@mk-kit/ui 0.35.0 → 0.36.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 +7 -6
- package/THIRD_PARTY_NOTICES.md +28 -0
- package/fesm2022/mk-kit-ui-core.mjs +139 -1
- package/fesm2022/mk-kit-ui-core.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-icon.mjs +444 -117
- package/fesm2022/mk-kit-ui-icon.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-layout.mjs +401 -0
- package/fesm2022/mk-kit-ui-layout.mjs.map +1 -0
- package/fesm2022/mk-kit-ui-navigation.mjs +2 -2
- package/fesm2022/mk-kit-ui-navigation.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-table.mjs +271 -19
- package/fesm2022/mk-kit-ui-table.mjs.map +1 -1
- package/fesm2022/mk-kit-ui.mjs +1 -0
- package/fesm2022/mk-kit-ui.mjs.map +1 -1
- package/package.json +5 -1
- package/styles/mk-kit.css +16 -0
- package/types/mk-kit-ui-core.d.ts +67 -3
- package/types/mk-kit-ui-icon.d.ts +6 -2
- package/types/mk-kit-ui-layout.d.ts +236 -0
- package/types/mk-kit-ui-table.d.ts +133 -5
- package/types/mk-kit-ui.d.ts +1 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Themable, accessible Angular component library for admin dashboards, back-offices and internal tools.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
170+ standalone components, directives and services — data tables, charts,
|
|
6
6
|
date & time pickers, editors, kanban, overlays, an app shell — written for
|
|
7
7
|
Angular 22 with signals and `OnPush` from day one. Every visual value is a
|
|
8
8
|
`--mk-*` CSS custom property; light and dark ship out of the box; WCAG 2.1 AA
|
|
@@ -73,14 +73,14 @@ export class AppRoot {
|
|
|
73
73
|
|---|---|
|
|
74
74
|
| **Forms & inputs** (49) | text, number, password (strength meter), OTP, phone (country prefix), postal code, currency, card number, IBAN, tax id, masked input, tag input, select, autocomplete, multi-select, tree-select, transfer list, checkbox, radio, switch, slider, range slider, rating, colour picker, file upload (dropzone), signature pad, numeric keypad & on-screen keyboard, repeater (`FormArray`), form field with automatic validation messages, form error summary |
|
|
75
75
|
| **Date & time** | calendar, date picker, date-range picker, time picker, month/year picker, week picker, inline mini date, event calendar with editable week/day grid (drag to move / resize) |
|
|
76
|
-
| **Tables & grids** (6) | data table — sort, multi-select, expandable rows, grouping, sticky header, column resize / reorder / pin, inline cell edit, responsive stacking — plus `MkTableDataSource` for server-side sort/page/filter |
|
|
76
|
+
| **Tables & grids** (6) | data table — sort, multi-select, expandable rows, tree rows, grouping, sticky header, column resize / reorder / pin, inline cell edit, responsive stacking, CSV export, print styles — plus `MkTableDataSource` for server-side sort/page/filter |
|
|
77
77
|
| **Charts** (12) | line/area, bar (stacked, horizontal, label fitting), donut, gauge, progress ring, scatter/bubble, radar, funnel, treemap, heatmap, calendar heatmap, sparkline — SVG, themed, accessible |
|
|
78
78
|
| **Data display** (25) | cards, lists, stat cards, badges, tags, chips, avatars & groups, timeline, description list, tree, empty state, countdown, QR code, diff view, JSON viewer, code block, virtual scroll, carousel, kanban |
|
|
79
|
-
| **Navigation & layout** (
|
|
79
|
+
| **Navigation & layout** (21) | app shell (responsive sidebar), stack / flex / grid layout primitives, nav list & groups, tabs, stepper, breadcrumb, pagination, menu, context menu, command palette (⌘K), page header, toolbar, splitter, drawer, scroll area, FAB, back-to-top |
|
|
80
80
|
| **Feedback & overlays** (20) | dialogs (+ `confirm()` / `alert()` / `prompt()`), bottom sheet, drawer, popover, popconfirm, hovercard, tooltip, toast, snackbar, alert, banner, result page, notification center, product tour, progress bar, loading bar, spinner, skeletons |
|
|
81
81
|
| **Editors & interactions** (22) | block editor (Notion-style, HTML round-trip), rich text, markdown renderer, code editor, log viewer, drag & drop, sortable list, @mentions, hotkeys, undo/redo history, permissions (`*mkCan`), clipboard, intersect, infinite scroll, ripple, scrollspy |
|
|
82
82
|
| **Media** (6) | image with states, gallery, lightbox, cropper, media manager |
|
|
83
|
-
| **Core services** | theme (light/dark/system + density), overlay & anchored panels, focus trap, live announcer, icon registry, i18n |
|
|
83
|
+
| **Core services** | theme (light/dark/system + density), breakpoints, overlay & anchored panels, focus trap, live announcer, icon registry (426 built-in icons), i18n |
|
|
84
84
|
|
|
85
85
|
The full, searchable index lives in the docs (`/components-index`).
|
|
86
86
|
|
|
@@ -96,7 +96,7 @@ import { MkDatePicker } from '@mk-kit/ui/datetime';
|
|
|
96
96
|
|
|
97
97
|
Available: `core`, `forms`, `datetime`, `table`, `data`, `navigation`,
|
|
98
98
|
`feedback`, `directives`, `dnd`, `media`, `icon`, `button`, `checkbox`, `chip`,
|
|
99
|
-
`context-menu`, `rich-text`, `block-editor`. `sideEffects: false` throughout.
|
|
99
|
+
`context-menu`, `layout`, `rich-text`, `block-editor`. `sideEffects: false` throughout.
|
|
100
100
|
|
|
101
101
|
## Theming
|
|
102
102
|
|
|
@@ -196,4 +196,5 @@ for use of the name and logo.
|
|
|
196
196
|
|
|
197
197
|
## License
|
|
198
198
|
|
|
199
|
-
MIT © Mateusz
|
|
199
|
+
MIT © Mateusz Kornaś. Part of the built-in icon set is derived from
|
|
200
|
+
[Lucide](https://lucide.dev) (ISC) — see `THIRD_PARTY_NOTICES.md`.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
## Lucide Icons
|
|
4
|
+
|
|
5
|
+
Part of the built-in icon set (`MK_EXTENDED_ICONS`, generated by
|
|
6
|
+
`scripts/gen-icons.mjs`) is derived from [Lucide](https://lucide.dev),
|
|
7
|
+
distributed under the ISC licence:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
ISC License
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2026 Lucide Icons and Contributors
|
|
13
|
+
|
|
14
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
15
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
16
|
+
copyright notice and this permission notice appear in all copies.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
19
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
20
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
21
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
22
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
23
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
24
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Lucide itself is derived in part from [Feather](https://feathericons.com)
|
|
28
|
+
(MIT, Copyright (c) 2013-2023 Cole Bemis).
|
|
@@ -176,6 +176,142 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
176
176
|
args: [{ providedIn: 'root' }]
|
|
177
177
|
}], ctorParameters: () => [] });
|
|
178
178
|
|
|
179
|
+
/** The default scale (same numbers as Tailwind, so mental models transfer). */
|
|
180
|
+
const MK_DEFAULT_BREAKPOINTS = {
|
|
181
|
+
sm: 640,
|
|
182
|
+
md: 768,
|
|
183
|
+
lg: 1024,
|
|
184
|
+
xl: 1280,
|
|
185
|
+
'2xl': 1536,
|
|
186
|
+
};
|
|
187
|
+
/** Override the breakpoint scale app-wide: `{ provide: MK_BREAKPOINTS, useValue: { …, lg: 1100 } }`. */
|
|
188
|
+
const MK_BREAKPOINTS = new InjectionToken('MK_BREAKPOINTS', {
|
|
189
|
+
providedIn: 'root',
|
|
190
|
+
factory: () => MK_DEFAULT_BREAKPOINTS,
|
|
191
|
+
});
|
|
192
|
+
const ORDER = ['xs', 'sm', 'md', 'lg', 'xl', '2xl'];
|
|
193
|
+
/** True when `value` is a per-breakpoint map rather than a plain value. */
|
|
194
|
+
function mkIsResponsive(value) {
|
|
195
|
+
return (typeof value === 'object' &&
|
|
196
|
+
value !== null &&
|
|
197
|
+
!Array.isArray(value) &&
|
|
198
|
+
Object.keys(value).every((k) => ORDER.includes(k)));
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Reactive viewport breakpoints, one `matchMedia` listener per step.
|
|
202
|
+
*
|
|
203
|
+
* ```ts
|
|
204
|
+
* private readonly bp = inject(MkBreakpointService);
|
|
205
|
+
* readonly compact = this.bp.down('md'); // Signal<boolean>
|
|
206
|
+
* readonly columns = computed(() => this.bp.resolve({ xs: 1, md: 2, xl: 4 }));
|
|
207
|
+
* ```
|
|
208
|
+
*
|
|
209
|
+
* On the server (no `window`) everything reports `xs`.
|
|
210
|
+
*/
|
|
211
|
+
class MkBreakpointService {
|
|
212
|
+
/** The breakpoint scale in effect (see {@link MK_BREAKPOINTS}). */
|
|
213
|
+
breakpoints = inject(MK_BREAKPOINTS);
|
|
214
|
+
document = inject(DOCUMENT);
|
|
215
|
+
isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
216
|
+
/** `matches` per step, in scale order (`sm` first). */
|
|
217
|
+
steps = new Map();
|
|
218
|
+
cleanup = [];
|
|
219
|
+
queries = new Map();
|
|
220
|
+
ups = new Map();
|
|
221
|
+
downs = new Map();
|
|
222
|
+
/** The widest breakpoint the viewport currently satisfies. */
|
|
223
|
+
current;
|
|
224
|
+
constructor() {
|
|
225
|
+
for (const name of ORDER.slice(1)) {
|
|
226
|
+
const min = this.breakpoints[name];
|
|
227
|
+
this.steps.set(name, this.watch(`(min-width: ${min}px)`));
|
|
228
|
+
}
|
|
229
|
+
this.current = computed(() => {
|
|
230
|
+
let current = 'xs';
|
|
231
|
+
for (const name of ORDER.slice(1))
|
|
232
|
+
if (this.steps.get(name)())
|
|
233
|
+
current = name;
|
|
234
|
+
return current;
|
|
235
|
+
}, /* @ts-ignore */
|
|
236
|
+
...(ngDevMode ? [{ debugName: "current" }] : /* istanbul ignore next */ []));
|
|
237
|
+
}
|
|
238
|
+
/** True while the viewport is at least `bp` wide (`up('md')` = md, lg, xl, 2xl). */
|
|
239
|
+
up(bp) {
|
|
240
|
+
let s = this.ups.get(bp);
|
|
241
|
+
if (!s) {
|
|
242
|
+
s = bp === 'xs' ? signal(true).asReadonly() : this.steps.get(bp).asReadonly();
|
|
243
|
+
this.ups.set(bp, s);
|
|
244
|
+
}
|
|
245
|
+
return s;
|
|
246
|
+
}
|
|
247
|
+
/** True while the viewport is narrower than `bp` (`down('md')` = xs, sm). */
|
|
248
|
+
down(bp) {
|
|
249
|
+
let s = this.downs.get(bp);
|
|
250
|
+
if (!s) {
|
|
251
|
+
const up = this.up(bp);
|
|
252
|
+
s = computed(() => !up());
|
|
253
|
+
this.downs.set(bp, s);
|
|
254
|
+
}
|
|
255
|
+
return s;
|
|
256
|
+
}
|
|
257
|
+
/** True while the viewport is at least `from` and narrower than `to`. */
|
|
258
|
+
between(from, to) {
|
|
259
|
+
const lo = this.up(from);
|
|
260
|
+
const hi = this.down(to);
|
|
261
|
+
return computed(() => lo() && hi());
|
|
262
|
+
}
|
|
263
|
+
/** Any media query as a signal, e.g. `observe('(orientation: portrait)')`. */
|
|
264
|
+
observe(query) {
|
|
265
|
+
let s = this.queries.get(query);
|
|
266
|
+
if (!s) {
|
|
267
|
+
s = this.watch(query).asReadonly();
|
|
268
|
+
this.queries.set(query, s);
|
|
269
|
+
}
|
|
270
|
+
return s;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Pick the entry of a responsive value for the current viewport —
|
|
274
|
+
* mobile-first, so `{ xs: 1, md: 2 }` gives 1 on `sm` and 2 on `xl`.
|
|
275
|
+
* A plain value is returned as is. Read inside a `computed` to track it.
|
|
276
|
+
*/
|
|
277
|
+
resolve(value) {
|
|
278
|
+
if (!mkIsResponsive(value))
|
|
279
|
+
return value;
|
|
280
|
+
const idx = ORDER.indexOf(this.current());
|
|
281
|
+
for (let i = idx; i >= 0; i--) {
|
|
282
|
+
const v = value[ORDER[i]];
|
|
283
|
+
if (v !== undefined)
|
|
284
|
+
return v;
|
|
285
|
+
}
|
|
286
|
+
return undefined;
|
|
287
|
+
}
|
|
288
|
+
ngOnDestroy() {
|
|
289
|
+
for (const off of this.cleanup)
|
|
290
|
+
off();
|
|
291
|
+
this.cleanup.length = 0;
|
|
292
|
+
}
|
|
293
|
+
watch(query) {
|
|
294
|
+
const s = signal(false, /* @ts-ignore */
|
|
295
|
+
...(ngDevMode ? [{ debugName: "s" }] : /* istanbul ignore next */ []));
|
|
296
|
+
if (!this.isBrowser)
|
|
297
|
+
return s;
|
|
298
|
+
const mql = this.document.defaultView?.matchMedia?.(query);
|
|
299
|
+
if (!mql)
|
|
300
|
+
return s;
|
|
301
|
+
s.set(mql.matches);
|
|
302
|
+
const onChange = (e) => s.set(e.matches);
|
|
303
|
+
mql.addEventListener('change', onChange);
|
|
304
|
+
this.cleanup.push(() => mql.removeEventListener('change', onChange));
|
|
305
|
+
return s;
|
|
306
|
+
}
|
|
307
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkBreakpointService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
308
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkBreakpointService, providedIn: 'root' });
|
|
309
|
+
}
|
|
310
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: MkBreakpointService, decorators: [{
|
|
311
|
+
type: Injectable,
|
|
312
|
+
args: [{ providedIn: 'root' }]
|
|
313
|
+
}], ctorParameters: () => [] });
|
|
314
|
+
|
|
179
315
|
/**
|
|
180
316
|
* Announces messages to assistive technology via a visually-hidden
|
|
181
317
|
* `aria-live` region. Used by toasts, form validation, sort changes, etc.
|
|
@@ -1167,6 +1303,8 @@ const MK_DEFAULT_I18N = {
|
|
|
1167
1303
|
expandHeader: 'Expand',
|
|
1168
1304
|
expandRow: 'Expand row',
|
|
1169
1305
|
collapseRow: 'Collapse row',
|
|
1306
|
+
expandTreeRow: 'Show child rows',
|
|
1307
|
+
collapseTreeRow: 'Hide child rows',
|
|
1170
1308
|
expandGroup: 'Expand group',
|
|
1171
1309
|
collapseGroup: 'Collapse group',
|
|
1172
1310
|
groupCount: (count) => `${count} item${count === 1 ? '' : 's'}`,
|
|
@@ -1592,5 +1730,5 @@ function mkFirstErrorMessage(errors, strings, overrides) {
|
|
|
1592
1730
|
* Generated bundle index. Do not edit.
|
|
1593
1731
|
*/
|
|
1594
1732
|
|
|
1595
|
-
export { MK_DEFAULT_DATE_NAMES, MK_DEFAULT_I18N, MK_DEFAULT_VALIDATION, MK_I18N, MK_OVERLAY_DATA, MkAnchoredPanel, MkFieldContext, MkFocusTrap, MkLiveAnnouncer, MkOverlayRef, MkOverlayService, MkThemeService, mkComputeAnchoredPosition, mkFirstErrorMessage, mkGetFocusable, mkHighlight, mkHighlightJson, mkUniqueId, mkValidatorChange, provideMkI18n };
|
|
1733
|
+
export { MK_BREAKPOINTS, MK_DEFAULT_BREAKPOINTS, MK_DEFAULT_DATE_NAMES, MK_DEFAULT_I18N, MK_DEFAULT_VALIDATION, MK_I18N, MK_OVERLAY_DATA, MkAnchoredPanel, MkBreakpointService, MkFieldContext, MkFocusTrap, MkLiveAnnouncer, MkOverlayRef, MkOverlayService, MkThemeService, mkComputeAnchoredPosition, mkFirstErrorMessage, mkGetFocusable, mkHighlight, mkHighlightJson, mkIsResponsive, mkUniqueId, mkValidatorChange, provideMkI18n };
|
|
1596
1734
|
//# sourceMappingURL=mk-kit-ui-core.mjs.map
|