@mk-kit/ui 0.36.0 → 0.37.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.
@@ -83,8 +83,24 @@ declare class MkFormField implements MkFieldContext {
83
83
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
84
84
  /** Control size; nested controls inherit it. */
85
85
  readonly size: _angular_core.InputSignal<MkSize>;
86
+ /**
87
+ * Where the label sits: above the control (default), or `float` — inside
88
+ * the control, sliding up once it is focused or has a value. Floating works
89
+ * with `mkInput` / textarea and any control bound with `ngModel` or a
90
+ * `formControl`; the placeholder stays hidden until the label has moved.
91
+ */
92
+ readonly labelPosition: _angular_core.InputSignal<"top" | "float">;
93
+ private readonly host;
86
94
  /** The projected control's form binding, when it has one. */
87
95
  private readonly ngControl;
96
+ /** A control inside the field has focus. */
97
+ protected readonly focused: _angular_core.WritableSignal<boolean>;
98
+ /** Last value read straight from a native control (fallback when no NgControl). */
99
+ private readonly domValue;
100
+ /** The field holds a non-empty value (drives the floating label). */
101
+ protected readonly hasValue: _angular_core.Signal<boolean>;
102
+ /** Track a native control's value for the floating label when nothing else reports it. */
103
+ protected readDomValue(target: EventTarget | null): void;
88
104
  /**
89
105
  * Bumped on every change of the bound control so the computed state below
90
106
  * re-reads it. `AbstractControl` is not signal-based, so this bridges its
@@ -120,7 +136,7 @@ declare class MkFormField implements MkFieldContext {
120
136
  */
121
137
  readonly describedBy: _angular_core.Signal<string | null>;
122
138
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkFormField, never>;
123
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkFormField, "mk-form-field", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "errorMessages": { "alias": "errorMessages"; "required": false; "isSignal": true; }; "errorOn": { "alias": "errorOn"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, ["ngControl"], ["*"], true, never>;
139
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkFormField, "mk-form-field", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "errorMessages": { "alias": "errorMessages"; "required": false; "isSignal": true; }; "errorOn": { "alias": "errorOn"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "labelPosition": { "alias": "labelPosition"; "required": false; "isSignal": true; }; }, {}, ["ngControl"], ["*"], true, never>;
124
140
  }
125
141
 
126
142
  /** One field-level error to surface in {@link MkFormErrorSummary}. */
@@ -602,6 +618,251 @@ declare class MkSelect implements ControlValueAccessor, OnDestroy {
602
618
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkSelect, "mk-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
603
619
  }
604
620
 
621
+ /** One row of an `mk-listbox`. */
622
+ interface MkListboxOption {
623
+ /** Text shown (and matched by typeahead / the filter). */
624
+ label: string;
625
+ /** Value committed to the model when selected. */
626
+ value: unknown;
627
+ /** Secondary line under the label. */
628
+ description?: string;
629
+ /** Skipped by keyboard, not selectable. */
630
+ disabled?: boolean;
631
+ /** Options sharing a `group` render under one heading (keep them adjacent). */
632
+ group?: string;
633
+ }
634
+ /** A rendered row: either a group heading or an option with its index in the visible list. */
635
+ type Row = {
636
+ kind: 'group';
637
+ label: string;
638
+ id: string;
639
+ } | {
640
+ kind: 'option';
641
+ option: MkListboxOption;
642
+ index: number;
643
+ };
644
+ /**
645
+ * Listbox — a standalone, always-visible selection list (the ARIA `listbox`
646
+ * pattern) for one or many values: settings panes, "choose a template"
647
+ * pickers, side-by-side assignments, any place a dropdown would hide choices
648
+ * the user should see at once.
649
+ *
650
+ * Keyboard: Up / Down move, Home / End jump, PageUp / PageDown skip ten,
651
+ * type to jump to a label, Enter / Space select (toggle when `multiple`),
652
+ * Shift+Arrow / Shift+click extend a range, Ctrl/Cmd+A selects all. Focus
653
+ * stays on the list (`aria-activedescendant`). With `filterable`, a search
654
+ * box above the list narrows it by label or description.
655
+ *
656
+ * Implements `ControlValueAccessor` and a two-way `value` model — a single
657
+ * value, or an array when `multiple`.
658
+ *
659
+ * ```html
660
+ * <mk-listbox [options]="plans" [(value)]="plan" ariaLabel="Plan" />
661
+ * <mk-listbox multiple filterable [options]="people" [(ngModel)]="reviewers" />
662
+ * ```
663
+ */
664
+ declare class MkListbox implements ControlValueAccessor, OnDestroy {
665
+ private readonly field;
666
+ protected readonly i18n: _mk_kit_ui_core.MkI18nStrings;
667
+ private readonly listRef;
668
+ /** The rows to choose from. */
669
+ readonly options: _angular_core.InputSignal<readonly MkListboxOption[]>;
670
+ /** Allow several values; the model becomes an array. */
671
+ readonly multiple: _angular_core.InputSignalWithTransform<boolean, unknown>;
672
+ /** Show a search box that narrows the list by label / description. */
673
+ readonly filterable: _angular_core.InputSignalWithTransform<boolean, unknown>;
674
+ readonly filterPlaceholder: _angular_core.InputSignal<string | undefined>;
675
+ /**
676
+ * Single-select only: moving with the arrow keys selects immediately
677
+ * (default `true`); `false` requires Enter / Space to commit.
678
+ */
679
+ readonly selectionFollowsFocus: _angular_core.InputSignalWithTransform<boolean, unknown>;
680
+ /** Control size. Ignored when nested in an `mk-form-field`. */
681
+ readonly size: _angular_core.InputSignal<MkSize>;
682
+ readonly invalid: _angular_core.InputSignalWithTransform<boolean, unknown>;
683
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
684
+ /** Accessible name when there is no visible label / form field. */
685
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
686
+ readonly ariaLabelledby: _angular_core.InputSignal<string | undefined>;
687
+ /** Text shown when no option matches the filter. */
688
+ readonly emptyText: _angular_core.InputSignal<string | undefined>;
689
+ /** Two-way value: one value, or an array when `multiple`. */
690
+ readonly value: _angular_core.ModelSignal<unknown>;
691
+ /** Emitted after the user changes the selection (not on programmatic writes). */
692
+ readonly change: _angular_core.OutputEmitterRef<unknown>;
693
+ readonly listId: string;
694
+ protected readonly filterId: string;
695
+ protected readonly query: _angular_core.WritableSignal<string>;
696
+ protected readonly activeIndex: _angular_core.WritableSignal<number>;
697
+ private readonly cvaDisabled;
698
+ private onChange;
699
+ private onTouched;
700
+ private typeahead;
701
+ private typeaheadTimer?;
702
+ /** Range anchor for Shift selection (index in the visible list). */
703
+ private anchor;
704
+ protected readonly effectiveSize: _angular_core.Signal<MkSize>;
705
+ protected readonly isDisabled: _angular_core.Signal<boolean>;
706
+ protected readonly isInvalid: _angular_core.Signal<boolean>;
707
+ protected readonly labelledBy: _angular_core.Signal<string | null>;
708
+ protected readonly describedBy: _angular_core.Signal<string | null>;
709
+ /** Options that match the filter, in source order. */
710
+ protected readonly visible: _angular_core.Signal<MkListboxOption[]>;
711
+ /** Visible options with group headings interleaved. */
712
+ protected readonly rows: _angular_core.Signal<Row[]>;
713
+ protected readonly selectedValues: _angular_core.Signal<unknown[]>;
714
+ protected readonly activeId: _angular_core.Signal<string | null>;
715
+ constructor();
716
+ protected optionId(index: number): string;
717
+ protected isSelected(option: MkListboxOption): boolean;
718
+ /** Focus the list. */
719
+ focus(): void;
720
+ protected onOptionClick(index: number, event: MouseEvent): void;
721
+ protected onFilterInput(event: Event): void;
722
+ protected onFilterKeydown(event: KeyboardEvent): void;
723
+ protected onKeydown(event: KeyboardEvent): void;
724
+ protected onBlur(): void;
725
+ /** Move the active row by `delta` (wrapping for ±1), extending the selection with Shift. */
726
+ private step;
727
+ private jump;
728
+ private firstEnabled;
729
+ private lastEnabled;
730
+ private typeaheadSearch;
731
+ private commit;
732
+ /** Select every enabled option between two visible indexes (replacing, or adding to, the selection). */
733
+ private selectRange;
734
+ private selectAll;
735
+ private emit;
736
+ ngOnDestroy(): void;
737
+ writeValue(value: unknown): void;
738
+ registerOnChange(fn: (value: unknown) => void): void;
739
+ registerOnTouched(fn: () => void): void;
740
+ setDisabledState(isDisabled: boolean): void;
741
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkListbox, never>;
742
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkListbox, "mk-listbox", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "filterable": { "alias": "filterable"; "required": false; "isSignal": true; }; "filterPlaceholder": { "alias": "filterPlaceholder"; "required": false; "isSignal": true; }; "selectionFollowsFocus": { "alias": "selectionFollowsFocus"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "ariaLabelledby"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "change": "change"; }, never, never, true, never>;
743
+ }
744
+
745
+ /** One node of a cascader: a leaf, or a parent with `children`. */
746
+ interface MkCascaderOption {
747
+ label: string;
748
+ value: unknown;
749
+ children?: readonly MkCascaderOption[];
750
+ disabled?: boolean;
751
+ }
752
+ /**
753
+ * Cascader — a select whose choices are a hierarchy shown as side-by-side
754
+ * columns (region → country → city, category → subcategory, org unit → team).
755
+ * Each pick opens the next column; picking a leaf commits the whole path.
756
+ *
757
+ * The value is the **path** of option values (`['eu', 'pl', 'krk']`) by
758
+ * default, or just the leaf's value with `valueMode="leaf"`. Parents are only
759
+ * selectable with `selectParents` (a click on one then commits, and its
760
+ * children stay reachable).
761
+ *
762
+ * Keyboard: Up / Down move within a column, Right opens the children, Left
763
+ * goes back, Enter / Space selects, typing jumps to a label, Escape closes.
764
+ * `expandTrigger="hover"` opens columns on pointer hover as well as click.
765
+ *
766
+ * Implements `ControlValueAccessor` and a two-way `value` model.
767
+ *
768
+ * ```html
769
+ * <mk-cascader [options]="regions" [(value)]="location" placeholder="Where?" clearable />
770
+ * ```
771
+ */
772
+ declare class MkCascader implements ControlValueAccessor, OnDestroy {
773
+ private readonly field;
774
+ protected readonly i18n: _mk_kit_ui_core.MkI18nStrings;
775
+ private readonly host;
776
+ private readonly injector;
777
+ private readonly triggerRef;
778
+ private readonly panelRef;
779
+ /** The hierarchy to choose from. */
780
+ readonly options: _angular_core.InputSignal<readonly MkCascaderOption[]>;
781
+ /** Two-way value: the path of values (default) or the leaf value (`valueMode="leaf"`). */
782
+ readonly value: _angular_core.ModelSignal<unknown>;
783
+ /** Bind the full path of values (default) or only the chosen option's value. */
784
+ readonly valueMode: _angular_core.InputSignal<"path" | "leaf">;
785
+ /** Allow committing a parent option (click / Enter on it) instead of leaves only. */
786
+ readonly selectParents: _angular_core.InputSignalWithTransform<boolean, unknown>;
787
+ /** Open the next column on click (default) or also on pointer hover. */
788
+ readonly expandTrigger: _angular_core.InputSignal<"click" | "hover">;
789
+ readonly placeholder: _angular_core.InputSignal<string>;
790
+ /** Text between the labels of the chosen path. */
791
+ readonly separator: _angular_core.InputSignal<string>;
792
+ readonly clearable: _angular_core.InputSignalWithTransform<boolean, unknown>;
793
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
794
+ readonly invalid: _angular_core.InputSignalWithTransform<boolean, unknown>;
795
+ /** Control size. Ignored when nested in an `mk-form-field`. */
796
+ readonly size: _angular_core.InputSignal<MkSize>;
797
+ /** Emitted after the user commits or clears a value. */
798
+ readonly change: _angular_core.OutputEmitterRef<unknown>;
799
+ readonly triggerId: string;
800
+ readonly panelId: string;
801
+ readonly valueId: string;
802
+ protected readonly open: _angular_core.WritableSignal<boolean>;
803
+ /** Row index highlighted in each open column, left to right. */
804
+ protected readonly activePath: _angular_core.WritableSignal<number[]>;
805
+ private readonly cvaDisabled;
806
+ private onChange;
807
+ private onTouched;
808
+ private typeahead;
809
+ private typeaheadTimer?;
810
+ protected readonly effectiveSize: _angular_core.Signal<MkSize>;
811
+ protected readonly isDisabled: _angular_core.Signal<boolean>;
812
+ protected readonly isInvalid: _angular_core.Signal<boolean>;
813
+ protected readonly isRequired: _angular_core.Signal<boolean>;
814
+ protected readonly labelledBy: _angular_core.Signal<string | null>;
815
+ protected readonly describedBy: _angular_core.Signal<string | null>;
816
+ /** The options along the committed value, or `[]`. */
817
+ protected readonly selectedPath: _angular_core.Signal<MkCascaderOption[]>;
818
+ protected readonly displayLabel: _angular_core.Signal<string>;
819
+ /**
820
+ * Columns rendered in the panel: the root list, then the children of every
821
+ * opened parent along the active path. The last entry of the path is the
822
+ * cursor — resting on a parent does not open it (click, hover or → does).
823
+ */
824
+ protected readonly columns: _angular_core.Signal<readonly MkCascaderOption[][]>;
825
+ /** The column the keyboard cursor is in. */
826
+ private readonly cursorColumn;
827
+ protected readonly activeId: _angular_core.Signal<string | null>;
828
+ constructor();
829
+ protected optionId(column: number, row: number): string;
830
+ protected isOnPath(column: number, row: number): boolean;
831
+ protected isSelected(column: number, option: MkCascaderOption): boolean;
832
+ protected isCursor(column: number, row: number): boolean;
833
+ protected toggle(): void;
834
+ protected openPanel(): void;
835
+ protected close(restoreFocus?: boolean): void;
836
+ protected onTriggerKeydown(event: KeyboardEvent): void;
837
+ protected onFocusOut(event: FocusEvent): void;
838
+ protected onPanelFocusout(event: FocusEvent): void;
839
+ protected onOptionClick(column: number, row: number): void;
840
+ protected onOptionHover(column: number, row: number): void;
841
+ protected clear(event: Event): void;
842
+ protected onPanelKeydown(event: KeyboardEvent): void;
843
+ /** Point the cursor at `(column, row)`, trimming any deeper columns. */
844
+ private setCursor;
845
+ /** Open the children of `(column, row)` and move the cursor onto the first enabled one. */
846
+ private expand;
847
+ private stepRow;
848
+ private firstEnabled;
849
+ private lastEnabled;
850
+ private typeaheadSearch;
851
+ private commit;
852
+ private emit;
853
+ /** Row indexes of a path of options. */
854
+ private indexPath;
855
+ /** Depth-first search for the option whose value is `value` (leaf mode). */
856
+ private findPath;
857
+ ngOnDestroy(): void;
858
+ writeValue(value: unknown): void;
859
+ registerOnChange(fn: (value: unknown) => void): void;
860
+ registerOnTouched(fn: () => void): void;
861
+ setDisabledState(isDisabled: boolean): void;
862
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkCascader, never>;
863
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkCascader, "mk-cascader", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "valueMode": { "alias": "valueMode"; "required": false; "isSignal": true; }; "selectParents": { "alias": "selectParents"; "required": false; "isSignal": true; }; "expandTrigger": { "alias": "expandTrigger"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "separator": { "alias": "separator"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "change": "change"; }, never, never, true, never>;
864
+ }
865
+
605
866
  /** A single suggestion for {@link MkAutocomplete}. */
606
867
  interface MkAutocompleteOption {
607
868
  /** Text shown to the user and used as the input display value when chosen. */
@@ -3582,5 +3843,5 @@ declare class MkRangeSlider implements ControlValueAccessor, Validator, OnDestro
3582
3843
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkRangeSlider, "mk-range-slider", never, { "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "minLabel": { "alias": "minLabel"; "required": false; "isSignal": true; }; "maxLabel": { "alias": "maxLabel"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
3583
3844
  }
3584
3845
 
3585
- export { MK_CARD_BRAND_NAMES, MK_IBAN_LENGTHS, MK_KEYBOARD_LAYOUT_QWERTY_PL, MK_PHONE_COUNTRIES, MK_POSTAL_FORMATS, MK_TAX_ID_FORMATS, MkAutocomplete, MkButtonToggle, MkButtonToggleGroup, MkCardNumberInput, MkCodeEditor, MkColorPicker, MkCurrencyInput, MkFileUpload, MkFormErrorSummary, MkFormField, MkI18nInput, MkIbanInput, MkInput, MkInputGroup, MkMention, MkMentionPanel, MkMultiSelect, MkNumberInput, MkNumericKeypad, MkOnScreenKeyboard, MkOnScreenKeyboardTrigger, MkOtp, MkPasswordInput, MkPhoneInput, MkPostalCodeInput, MkRadio, MkRadioGroup, MkRangeSlider, MkRating, MkRepeater, MkRepeaterEmpty, MkRepeaterRow, MkSelect, MkSignaturePad, MkSlider, MkSubmitInput, MkSwitch, MkTagInput, MkTaxIdInput, MkTransferList, MkTreeSelect, mkCountryFlag, mkDetectCardBrand, mkIbanChecksum, mkIbanIsValid, mkIbanValidator, mkLuhnCheck, mkNipChecksum, mkPostalCodeValidator, mkPostalFormat, mkTaxIdFormat, mkTaxIdIsValid, mkTaxIdValidator };
3586
- export type { MkAutocompleteFilterMode, MkAutocompleteOption, MkCardBrand, MkCodeValidity, MkFormError, MkI18nLocale, MkI18nValue, MkKeyboardActionKey, MkKeyboardKey, MkKeyboardLayout, MkMentionFilterMode, MkMentionOption, MkMentionSearchEvent, MkMentionSelectEvent, MkMultiSelectFilterMode, MkMultiSelectOption, MkNumericKeypadMode, MkOnScreenKeyboardTarget, MkPasswordRule, MkPhoneCountry, MkPhoneValue, MkPostalFormat, MkRange, MkRepeaterRowContext, MkSelectOption, MkTaxIdFormat, MkTransferItem, MkUploadFile, MkUploadFn, MkUploadRejection, MkUploadStatus, MkUploadValueFormat };
3846
+ export { MK_CARD_BRAND_NAMES, MK_IBAN_LENGTHS, MK_KEYBOARD_LAYOUT_QWERTY_PL, MK_PHONE_COUNTRIES, MK_POSTAL_FORMATS, MK_TAX_ID_FORMATS, MkAutocomplete, MkButtonToggle, MkButtonToggleGroup, MkCardNumberInput, MkCascader, MkCodeEditor, MkColorPicker, MkCurrencyInput, MkFileUpload, MkFormErrorSummary, MkFormField, MkI18nInput, MkIbanInput, MkInput, MkInputGroup, MkListbox, MkMention, MkMentionPanel, MkMultiSelect, MkNumberInput, MkNumericKeypad, MkOnScreenKeyboard, MkOnScreenKeyboardTrigger, MkOtp, MkPasswordInput, MkPhoneInput, MkPostalCodeInput, MkRadio, MkRadioGroup, MkRangeSlider, MkRating, MkRepeater, MkRepeaterEmpty, MkRepeaterRow, MkSelect, MkSignaturePad, MkSlider, MkSubmitInput, MkSwitch, MkTagInput, MkTaxIdInput, MkTransferList, MkTreeSelect, mkCountryFlag, mkDetectCardBrand, mkIbanChecksum, mkIbanIsValid, mkIbanValidator, mkLuhnCheck, mkNipChecksum, mkPostalCodeValidator, mkPostalFormat, mkTaxIdFormat, mkTaxIdIsValid, mkTaxIdValidator };
3847
+ export type { MkAutocompleteFilterMode, MkAutocompleteOption, MkCardBrand, MkCascaderOption, MkCodeValidity, MkFormError, MkI18nLocale, MkI18nValue, MkKeyboardActionKey, MkKeyboardKey, MkKeyboardLayout, MkListboxOption, MkMentionFilterMode, MkMentionOption, MkMentionSearchEvent, MkMentionSelectEvent, MkMultiSelectFilterMode, MkMultiSelectOption, MkNumericKeypadMode, MkOnScreenKeyboardTarget, MkPasswordRule, MkPhoneCountry, MkPhoneValue, MkPostalFormat, MkRange, MkRepeaterRowContext, MkSelectOption, MkTaxIdFormat, MkTransferItem, MkUploadFile, MkUploadFn, MkUploadRejection, MkUploadStatus, MkUploadValueFormat };
@@ -0,0 +1,98 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import * as _mk_kit_ui_core from '@mk-kit/ui/core';
3
+ import { MkQueryField, MkQueryGroup, MkSize, mkIsQueryGroup, MkQueryRule, MkQueryCombinator, MkQueryNode } from '@mk-kit/ui/core';
4
+ import { MkSelectOption } from '@mk-kit/ui/forms';
5
+
6
+ /**
7
+ * QueryBuilder — a rule / group tree the user assembles from your `fields`,
8
+ * held as plain JSON (`MkQueryGroup`) in the two-way `query` model. Pair it
9
+ * with `mkQueryToPredicate()` to filter rows in the browser, with
10
+ * `MkTableDataSource.setQuery()` to send it to the server, or with
11
+ * `mkQueryToText()` for a readable summary.
12
+ *
13
+ * ```html
14
+ * <mk-query-builder [fields]="fields" [(query)]="query" allowNot />
15
+ *
16
+ * fields: MkQueryField[] = [
17
+ * { key: 'name', label: 'Name' },
18
+ * { key: 'orders', label: 'Orders', type: 'number' },
19
+ * { key: 'status', label: 'Status', type: 'select', options: [{ label: 'Active', value: 'active' }, …] },
20
+ * { key: 'since', label: 'Customer since', type: 'date' },
21
+ * { key: 'vip', label: 'VIP', type: 'boolean' },
22
+ * ];
23
+ * rows = computed(() => this.all.filter(mkQueryToPredicate(this.query(), this.fields)));
24
+ * ```
25
+ */
26
+ declare class MkQueryBuilder {
27
+ protected readonly i18n: _mk_kit_ui_core.MkI18nStrings;
28
+ /** The filterable fields, in picker order. */
29
+ readonly fields: _angular_core.InputSignal<readonly MkQueryField[]>;
30
+ /** The query tree (two-way). Starts as an empty `and` group. */
31
+ readonly query: _angular_core.ModelSignal<MkQueryGroup>;
32
+ /** How deep groups may nest (0 = rules only). */
33
+ readonly maxDepth: _angular_core.InputSignalWithTransform<number, unknown>;
34
+ /** Offer a *Not* toggle on every group. */
35
+ readonly allowNot: _angular_core.InputSignalWithTransform<boolean, unknown>;
36
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
37
+ /** Control size (default `sm`). */
38
+ readonly size: _angular_core.InputSignal<MkSize>;
39
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
40
+ /** Reset to an empty group. */
41
+ clear(): void;
42
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkQueryBuilder, never>;
43
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkQueryBuilder, "mk-query-builder", never, { "fields": { "alias": "fields"; "required": true; "isSignal": true; }; "query": { "alias": "query"; "required": false; "isSignal": true; }; "maxDepth": { "alias": "maxDepth"; "required": false; "isSignal": true; }; "allowNot": { "alias": "allowNot"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "query": "queryChange"; }, never, never, true, never>;
44
+ }
45
+
46
+ /**
47
+ * One group of the builder — its combinator toggle, rules, nested groups and
48
+ * the add / remove actions. Used by `mk-query-builder`; every edit emits a
49
+ * new immutable group upward.
50
+ */
51
+ declare class MkQueryGroupComponent {
52
+ protected readonly i18n: _mk_kit_ui_core.MkI18nStrings;
53
+ readonly group: _angular_core.InputSignal<MkQueryGroup>;
54
+ readonly fields: _angular_core.InputSignal<readonly MkQueryField[]>;
55
+ readonly depth: _angular_core.InputSignalWithTransform<number, unknown>;
56
+ readonly maxDepth: _angular_core.InputSignalWithTransform<number, unknown>;
57
+ readonly allowNot: _angular_core.InputSignalWithTransform<boolean, unknown>;
58
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
59
+ readonly root: _angular_core.InputSignalWithTransform<boolean, unknown>;
60
+ readonly size: _angular_core.InputSignal<MkSize>;
61
+ /** A new version of this group after an edit. */
62
+ readonly groupChange: _angular_core.OutputEmitterRef<MkQueryGroup>;
63
+ /** The user removed this (non-root) group. */
64
+ readonly remove: _angular_core.OutputEmitterRef<void>;
65
+ protected readonly fieldOptions: _angular_core.Signal<MkSelectOption[]>;
66
+ protected readonly canNest: _angular_core.Signal<boolean>;
67
+ protected readonly booleanOptions: _angular_core.Signal<MkSelectOption[]>;
68
+ protected isGroup: typeof mkIsQueryGroup;
69
+ protected fieldOf(rule: MkQueryRule): MkQueryField | undefined;
70
+ protected typeOf(rule: MkQueryRule): string;
71
+ protected operatorOptions(rule: MkQueryRule): MkSelectOption[];
72
+ protected needsValue(rule: MkQueryRule): boolean;
73
+ protected selectOptions(rule: MkQueryRule): MkSelectOption[];
74
+ protected isList(rule: MkQueryRule): boolean;
75
+ protected isRange(rule: MkQueryRule): boolean;
76
+ protected asArray(value: unknown): unknown[];
77
+ protected rangePart(rule: MkQueryRule, index: 0 | 1): unknown;
78
+ protected dateValue(v: unknown): Date | null;
79
+ protected numberValue(v: unknown): number | null;
80
+ protected textValue(v: unknown): string;
81
+ protected setCombinator(combinator: MkQueryCombinator): void;
82
+ protected toggleNot(): void;
83
+ protected addRule(): void;
84
+ protected addGroup(): void;
85
+ protected removeAt(index: number): void;
86
+ protected replaceAt(index: number, node: MkQueryNode): void;
87
+ protected setField(index: number, rule: MkQueryRule, key: unknown): void;
88
+ protected setOperator(index: number, rule: MkQueryRule, op: unknown): void;
89
+ protected setValue(index: number, rule: MkQueryRule, value: unknown): void;
90
+ protected setRangePart(index: number, rule: MkQueryRule, part: 0 | 1, value: unknown): void;
91
+ protected setDate(index: number, rule: MkQueryRule, d: Date | null): void;
92
+ protected setDateRange(index: number, rule: MkQueryRule, part: 0 | 1, d: Date | null): void;
93
+ protected onTextInput(index: number, rule: MkQueryRule, event: Event): void;
94
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkQueryGroupComponent, never>;
95
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkQueryGroupComponent, "mk-query-group", never, { "group": { "alias": "group"; "required": true; "isSignal": true; }; "fields": { "alias": "fields"; "required": true; "isSignal": true; }; "depth": { "alias": "depth"; "required": false; "isSignal": true; }; "maxDepth": { "alias": "maxDepth"; "required": false; "isSignal": true; }; "allowNot": { "alias": "allowNot"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "root": { "alias": "root"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "groupChange": "groupChange"; "remove": "remove"; }, never, never, true, never>;
96
+ }
97
+
98
+ export { MkQueryBuilder, MkQueryGroupComponent };
@@ -2,6 +2,7 @@ import * as _mk_kit_ui_table from '@mk-kit/ui/table';
2
2
  import * as _angular_core from '@angular/core';
3
3
  import { TemplateRef, Signal } from '@angular/core';
4
4
  import * as _mk_kit_ui_core from '@mk-kit/ui/core';
5
+ import { MkQueryGroup } from '@mk-kit/ui/core';
5
6
  import { Observable } from 'rxjs';
6
7
 
7
8
  /**
@@ -677,6 +678,8 @@ interface MkDataRequest {
677
678
  sort: MkSortState | null;
678
679
  /** Free-text filter query (`''` = none). */
679
680
  filter: string;
681
+ /** Structured filter from `mk-query-builder` (`null` = none). Compacted: no empty groups or unfinished rules. */
682
+ query: MkQueryGroup | null;
680
683
  }
681
684
  /** One page of server data returned by a {@link MkDataFetcher}. */
682
685
  interface MkDataPage<T> {
@@ -789,6 +792,7 @@ declare class MkTableDataSource<T> {
789
792
  private readonly _pageSize;
790
793
  private readonly _sort;
791
794
  private readonly _filter;
795
+ private readonly _query;
792
796
  /** Rows of the current page (`[]` until the first load lands). */
793
797
  readonly rows: Signal<T[]>;
794
798
  /** Total row count across all pages (feed to `mk-pagination`'s `total`). */
@@ -805,6 +809,8 @@ declare class MkTableDataSource<T> {
805
809
  readonly sort: Signal<MkSortState | null>;
806
810
  /** Current filter query (updates immediately, even while debouncing). */
807
811
  readonly filter: Signal<string>;
812
+ /** Current structured query, or `null`. */
813
+ readonly query: Signal<MkQueryGroup | null>;
808
814
  /** True when a settled load reported no rows at all. */
809
815
  readonly empty: Signal<boolean>;
810
816
  /** Monotonic request id — settles from older epochs are discarded. */
@@ -834,6 +840,12 @@ declare class MkTableDataSource<T> {
834
840
  * flushes it early. A no-op when the query is unchanged.
835
841
  */
836
842
  setFilter(query: string): void;
843
+ /**
844
+ * Set (or clear with `null`) the structured query from `mk-query-builder`.
845
+ * Empty groups and unfinished rules are dropped before the request; a query
846
+ * with nothing left is sent as `null`. Resets to page 1 and loads at once.
847
+ */
848
+ setQuery(query: MkQueryGroup | null): void;
837
849
  /**
838
850
  * Re-run the current request immediately (e.g. after a mutation). Flushes a
839
851
  * pending debounced filter, since the request reads the live filter value.
@@ -15,4 +15,6 @@ export * from '@mk-kit/ui/rich-text';
15
15
  export * from '@mk-kit/ui/block-editor';
16
16
  export * from '@mk-kit/ui/context-menu';
17
17
  export * from '@mk-kit/ui/layout';
18
+ export * from '@mk-kit/ui/chat';
19
+ export * from '@mk-kit/ui/query-builder';
18
20
  export * from '@mk-kit/ui/media';