@mk-kit/ui 0.36.0 → 0.38.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.
- package/README.md +11 -6
- package/fesm2022/mk-kit-ui-chat.mjs +490 -0
- package/fesm2022/mk-kit-ui-chat.mjs.map +1 -0
- package/fesm2022/mk-kit-ui-core.mjs +310 -1
- package/fesm2022/mk-kit-ui-core.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-dynamic-form.mjs +578 -0
- package/fesm2022/mk-kit-ui-dynamic-form.mjs.map +1 -0
- package/fesm2022/mk-kit-ui-feedback.mjs +400 -8
- package/fesm2022/mk-kit-ui-feedback.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-forms.mjs +816 -6
- package/fesm2022/mk-kit-ui-forms.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-query-builder.mjs +276 -0
- package/fesm2022/mk-kit-ui-query-builder.mjs.map +1 -0
- package/fesm2022/mk-kit-ui-table.mjs +20 -1
- package/fesm2022/mk-kit-ui-table.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-testing.mjs +834 -0
- package/fesm2022/mk-kit-ui-testing.mjs.map +1 -0
- package/fesm2022/mk-kit-ui.mjs +3 -0
- package/fesm2022/mk-kit-ui.mjs.map +1 -1
- package/package.json +17 -1
- package/types/mk-kit-ui-chat.d.ts +288 -0
- package/types/mk-kit-ui-core.d.ts +167 -2
- package/types/mk-kit-ui-dynamic-form.d.ts +305 -0
- package/types/mk-kit-ui-feedback.d.ts +111 -2
- package/types/mk-kit-ui-forms.d.ts +264 -3
- package/types/mk-kit-ui-query-builder.d.ts +98 -0
- package/types/mk-kit-ui-table.d.ts +12 -0
- package/types/mk-kit-ui-testing.d.ts +344 -0
- package/types/mk-kit-ui.d.ts +3 -0
|
@@ -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.
|