@mk-kit/ui 0.34.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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -0
  3. package/block-editor/README.md +254 -0
  4. package/fesm2022/mk-kit-ui-block-editor.mjs +2158 -0
  5. package/fesm2022/mk-kit-ui-block-editor.mjs.map +1 -0
  6. package/fesm2022/mk-kit-ui-button.mjs +81 -0
  7. package/fesm2022/mk-kit-ui-button.mjs.map +1 -0
  8. package/fesm2022/mk-kit-ui-checkbox.mjs +136 -0
  9. package/fesm2022/mk-kit-ui-checkbox.mjs.map +1 -0
  10. package/fesm2022/mk-kit-ui-chip.mjs +122 -0
  11. package/fesm2022/mk-kit-ui-chip.mjs.map +1 -0
  12. package/fesm2022/mk-kit-ui-context-menu.mjs +144 -0
  13. package/fesm2022/mk-kit-ui-context-menu.mjs.map +1 -0
  14. package/fesm2022/mk-kit-ui-core.mjs +1576 -0
  15. package/fesm2022/mk-kit-ui-core.mjs.map +1 -0
  16. package/fesm2022/mk-kit-ui-data.mjs +6055 -0
  17. package/fesm2022/mk-kit-ui-data.mjs.map +1 -0
  18. package/fesm2022/mk-kit-ui-datetime.mjs +3409 -0
  19. package/fesm2022/mk-kit-ui-datetime.mjs.map +1 -0
  20. package/fesm2022/mk-kit-ui-directives.mjs +1779 -0
  21. package/fesm2022/mk-kit-ui-directives.mjs.map +1 -0
  22. package/fesm2022/mk-kit-ui-dnd.mjs +1073 -0
  23. package/fesm2022/mk-kit-ui-dnd.mjs.map +1 -0
  24. package/fesm2022/mk-kit-ui-feedback.mjs +2426 -0
  25. package/fesm2022/mk-kit-ui-feedback.mjs.map +1 -0
  26. package/fesm2022/mk-kit-ui-forms.mjs +9208 -0
  27. package/fesm2022/mk-kit-ui-forms.mjs.map +1 -0
  28. package/fesm2022/mk-kit-ui-icon.mjs +470 -0
  29. package/fesm2022/mk-kit-ui-icon.mjs.map +1 -0
  30. package/fesm2022/mk-kit-ui-media.mjs +896 -0
  31. package/fesm2022/mk-kit-ui-media.mjs.map +1 -0
  32. package/fesm2022/mk-kit-ui-navigation.mjs +2542 -0
  33. package/fesm2022/mk-kit-ui-navigation.mjs.map +1 -0
  34. package/fesm2022/mk-kit-ui-rich-text.mjs +565 -0
  35. package/fesm2022/mk-kit-ui-rich-text.mjs.map +1 -0
  36. package/fesm2022/mk-kit-ui-table.mjs +1378 -0
  37. package/fesm2022/mk-kit-ui-table.mjs.map +1 -0
  38. package/fesm2022/mk-kit-ui.mjs +32 -0
  39. package/fesm2022/mk-kit-ui.mjs.map +1 -0
  40. package/package.json +130 -0
  41. package/schematics/collection.json +10 -0
  42. package/schematics/ng-add/index.js +113 -0
  43. package/schematics/ng-add/schema.json +22 -0
  44. package/schematics/package.json +3 -0
  45. package/styles/mk-kit.css +750 -0
  46. package/types/mk-kit-ui-block-editor.d.ts +292 -0
  47. package/types/mk-kit-ui-button.d.ts +40 -0
  48. package/types/mk-kit-ui-checkbox.d.ts +62 -0
  49. package/types/mk-kit-ui-chip.d.ts +59 -0
  50. package/types/mk-kit-ui-context-menu.d.ts +57 -0
  51. package/types/mk-kit-ui-core.d.ts +1105 -0
  52. package/types/mk-kit-ui-data.d.ts +2580 -0
  53. package/types/mk-kit-ui-datetime.d.ts +1171 -0
  54. package/types/mk-kit-ui-directives.d.ts +807 -0
  55. package/types/mk-kit-ui-dnd.d.ts +423 -0
  56. package/types/mk-kit-ui-feedback.d.ts +1270 -0
  57. package/types/mk-kit-ui-forms.d.ts +3586 -0
  58. package/types/mk-kit-ui-icon.d.ts +108 -0
  59. package/types/mk-kit-ui-media.d.ts +549 -0
  60. package/types/mk-kit-ui-navigation.d.ts +1169 -0
  61. package/types/mk-kit-ui-rich-text.d.ts +187 -0
  62. package/types/mk-kit-ui-table.d.ts +739 -0
  63. package/types/mk-kit-ui.d.ts +17 -0
@@ -0,0 +1,187 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { OnDestroy } from '@angular/core';
3
+ import { ControlValueAccessor } from '@angular/forms';
4
+ import * as _mk_kit_ui_core from '@mk-kit/ui/core';
5
+
6
+ /**
7
+ * Rich text — a small WYSIWYG form control over a sanitised HTML string, for
8
+ * single "description"-style fields where the full block editor is overkill.
9
+ * Renders a textarea-like surface with the floating inline formatting toolbar
10
+ * (Bold, Italic, Underline, Strikethrough, Inline code, Link, Clear) on text
11
+ * selection; Enter inserts a line break.
12
+ *
13
+ * Implements `ControlValueAccessor` with a two-way `value` model, so it works
14
+ * with `[(ngModel)]`, reactive forms and `[(value)]`. Every value — written or
15
+ * emitted — passes through {@link sanitizeInlineHtml}, and a visually empty
16
+ * surface (whitespace / lone `<br>`s) normalises to `''` so `required`
17
+ * validation behaves.
18
+ *
19
+ * ```html
20
+ * <mk-rich-text [(ngModel)]="description" placeholder="Describe it…" />
21
+ * <mk-rich-text [(value)]="html" minHeight="8rem" />
22
+ * ```
23
+ */
24
+ declare class MkRichText implements ControlValueAccessor {
25
+ private readonly field;
26
+ private readonly i18n;
27
+ /** Two-way HTML string value (sanitised; `''` when visually empty). */
28
+ readonly value: _angular_core.ModelSignal<string>;
29
+ /** Placeholder shown when empty. */
30
+ readonly placeholder: _angular_core.InputSignal<string>;
31
+ /** Disable the control. */
32
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
33
+ /** Force the invalid visual + `aria-invalid` when used standalone. */
34
+ readonly invalid: _angular_core.InputSignalWithTransform<boolean, unknown>;
35
+ /** Minimum height of the editable area (any CSS length). */
36
+ readonly minHeight: _angular_core.InputSignal<string>;
37
+ /** Accessible label when not labelled by an `mk-form-field`. */
38
+ readonly ariaLabel: _angular_core.InputSignal<string>;
39
+ private readonly cvaDisabled;
40
+ private onChange;
41
+ private onTouched;
42
+ protected readonly isDisabled: _angular_core.Signal<boolean>;
43
+ protected readonly isInvalid: _angular_core.Signal<boolean>;
44
+ protected readonly labelledBy: string | null;
45
+ protected readonly describedBy: _angular_core.Signal<string | null>;
46
+ protected readonly effectiveAriaLabel: _angular_core.Signal<string>;
47
+ /** Sanitised view of the model, rendered into the engine. */
48
+ protected readonly safeHtml: _angular_core.Signal<string>;
49
+ /** User edit: sanitise, normalise the empty state, propagate. */
50
+ protected onContentChange(html: string): void;
51
+ protected onFocusChange(focused: boolean): void;
52
+ writeValue(value: unknown): void;
53
+ registerOnChange(fn: (value: string) => void): void;
54
+ registerOnTouched(fn: () => void): void;
55
+ setDisabledState(isDisabled: boolean): void;
56
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkRichText, never>;
57
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkRichText, "mk-rich-text", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "minHeight": { "alias": "minHeight"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
58
+ }
59
+
60
+ /** Payload for a split (Enter) event: text before/after the caret. */
61
+ interface MkRichTextSplit {
62
+ before: string;
63
+ after: string;
64
+ }
65
+ /** A formatting command exposed by the floating toolbar. */
66
+ interface MkInlineTool {
67
+ id: string;
68
+ label: string;
69
+ icon: string;
70
+ shortcut?: string;
71
+ }
72
+ /**
73
+ * Rich-text engine — an accessible contenteditable surface with a floating
74
+ * inline formatting toolbar (Bold, Italic, Underline, Strikethrough, Inline
75
+ * code, Link, Clear). Built on the native Selection API +
76
+ * `document.execCommand` (deprecated but universally supported and
77
+ * dependency-free — the only practical way to do inline formatting without a
78
+ * heavyweight editor engine).
79
+ *
80
+ * This is the low-level building block: it emits HTML via `contentChange`, and
81
+ * structural intents (`splitAt`, `removeEmpty`, `arrowOut`) so a block-editor
82
+ * host can create, merge or navigate blocks. For a standalone form control use
83
+ * {@link MkRichText} (`<mk-rich-text>`), which wraps this engine in a CVA over
84
+ * a sanitised HTML string.
85
+ */
86
+ declare class MkRichTextEngine implements OnDestroy {
87
+ private readonly document;
88
+ private readonly host;
89
+ private readonly editableRef;
90
+ protected readonly i18n: _mk_kit_ui_core.MkI18nStrings;
91
+ /** Pending toolbar-hide delay from `onBlur`; cleared on destroy. */
92
+ private blurTimer;
93
+ /** Current HTML content. */
94
+ readonly html: _angular_core.InputSignal<string>;
95
+ /** Placeholder shown when empty. */
96
+ readonly placeholder: _angular_core.InputSignal<string>;
97
+ /** Disable editing. */
98
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
99
+ /** Allow soft line breaks (Shift+Enter). Plain Enter always splits. */
100
+ readonly multiline: _angular_core.InputSignalWithTransform<boolean, unknown>;
101
+ /**
102
+ * Emit `splitAt` on Enter (block-editor hosts). When `false` — standalone
103
+ * field usage — Enter inserts a line break inside this surface instead.
104
+ */
105
+ readonly splitOnEnter: _angular_core.InputSignalWithTransform<boolean, unknown>;
106
+ /** Minimum height of the editable surface (any CSS length). */
107
+ readonly minHeight: _angular_core.InputSignal<string | null>;
108
+ /** Accessible label for the editable region. */
109
+ readonly ariaLabel: _angular_core.InputSignal<string>;
110
+ /** Id of an external label element, for `aria-labelledby`. */
111
+ readonly labelledBy: _angular_core.InputSignal<string | null>;
112
+ /** Space-separated id list for `aria-describedby`. */
113
+ readonly describedBy: _angular_core.InputSignal<string | null>;
114
+ /** Reflect an invalid state via `aria-invalid`. */
115
+ readonly invalid: _angular_core.InputSignalWithTransform<boolean, unknown>;
116
+ /** Fired on every edit with the sanitised-by-construction HTML. */
117
+ readonly contentChange: _angular_core.OutputEmitterRef<string>;
118
+ /** Enter pressed: `before` stays in this block, `after` starts a new one. */
119
+ readonly splitAt: _angular_core.OutputEmitterRef<MkRichTextSplit>;
120
+ /** Backspace at the very start of an empty block. */
121
+ readonly removeEmpty: _angular_core.OutputEmitterRef<void>;
122
+ /** Caret tried to leave the top/bottom edge with an arrow key. */
123
+ readonly arrowOut: _angular_core.OutputEmitterRef<"up" | "down">;
124
+ /** Focus/blur bubbled so the wrapper can show selection chrome. */
125
+ readonly focusChange: _angular_core.OutputEmitterRef<boolean>;
126
+ protected readonly isEmpty: _angular_core.WritableSignal<boolean>;
127
+ protected readonly toolbar: _angular_core.WritableSignal<{
128
+ visible: boolean;
129
+ top: number;
130
+ left: number;
131
+ }>;
132
+ protected readonly activeFormats: _angular_core.WritableSignal<Set<string>>;
133
+ protected readonly tools: MkInlineTool[];
134
+ protected readonly showPlaceholder: _angular_core.Signal<boolean>;
135
+ constructor();
136
+ /** Places the caret and focuses (called by the host for navigation). */
137
+ focus(position?: 'start' | 'end'): void;
138
+ protected onInput(): void;
139
+ protected onFocus(): void;
140
+ ngOnDestroy(): void;
141
+ protected onBlur(): void;
142
+ protected onSelectionChange(): void;
143
+ protected onKeydown(event: KeyboardEvent): void;
144
+ /** Escape inside the toolbar returns focus to the text; arrows move tools. */
145
+ protected onToolbarKeydown(event: KeyboardEvent): void;
146
+ /** Runs a toolbar command, keeping the model + toolbar state in sync. */
147
+ protected runTool(id: string): void;
148
+ protected isActive(id: string): boolean;
149
+ private emitSplit;
150
+ /** Inserts a `<br>` at the caret (Enter in `splitOnEnter=false` mode). */
151
+ private insertLineBreak;
152
+ /** Extracts markup after the caret so the host can start a new block with it. */
153
+ private splitHtmlAtCaret;
154
+ private wrapInlineCode;
155
+ private applyLink;
156
+ private updateToolbar;
157
+ private computeEmpty;
158
+ private setCaret;
159
+ private isSelectionCollapsed;
160
+ private isCaretAtStart;
161
+ private isCaretAtEnd;
162
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkRichTextEngine, never>;
163
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkRichTextEngine, "mk-rich-text-engine", never, { "html": { "alias": "html"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "multiline": { "alias": "multiline"; "required": false; "isSignal": true; }; "splitOnEnter": { "alias": "splitOnEnter"; "required": false; "isSignal": true; }; "minHeight": { "alias": "minHeight"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "labelledBy": { "alias": "labelledBy"; "required": false; "isSignal": true; }; "describedBy": { "alias": "describedBy"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; }, { "contentChange": "contentChange"; "splitAt": "splitAt"; "removeEmpty": "removeEmpty"; "arrowOut": "arrowOut"; "focusChange": "focusChange"; }, never, never, true, never>;
164
+ }
165
+
166
+ /**
167
+ * Allow-list sanitiser for inline rich-text HTML — the security backbone of
168
+ * both `<mk-rich-text>` and the block editor's text blocks.
169
+ *
170
+ * SECURITY MODEL: rich-text surfaces store HTML authored through the editor's
171
+ * restricted formatting commands. Before that markup is emitted, persisted or
172
+ * re-rendered it is passed through {@link sanitizeInlineHtml}, an allow-list
173
+ * cleaner that strips scripts, event handlers and dangerous URLs. Angular's
174
+ * `DomSanitizer` re-sanitises at display time where applicable. This module is
175
+ * dependency-free so it can run on a server (SSG/SSR) — never feed its output
176
+ * back into `innerHTML` without sanitising again.
177
+ */
178
+ /**
179
+ * Allow-list cleaner for inline rich text. Keeps a small set of formatting
180
+ * tags, strips everything else's tags (preserving their text), removes event
181
+ * handler attributes and unsafe `href`s. Not a substitute for `DomSanitizer`,
182
+ * but makes the serialised string safe by construction.
183
+ */
184
+ declare function sanitizeInlineHtml(html: string): string;
185
+
186
+ export { MkRichText, MkRichTextEngine, sanitizeInlineHtml };
187
+ export type { MkRichTextSplit };