@mk-kit/ui 0.38.0 → 0.40.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 +6 -1
- package/fesm2022/mk-kit-ui-data.mjs +48 -28
- package/fesm2022/mk-kit-ui-data.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-dnd.mjs +27 -2
- package/fesm2022/mk-kit-ui-dnd.mjs.map +1 -1
- package/fesm2022/mk-kit-ui-navigation.mjs +8 -4
- package/fesm2022/mk-kit-ui-navigation.mjs.map +1 -1
- package/package.json +1 -1
- package/schematics/collection.json +5 -0
- package/schematics/migrate-primeng/index.js +76 -0
- package/schematics/migrate-primeng/mapping.js +289 -0
- package/schematics/migrate-primeng/schema.json +25 -0
- package/schematics/migrate-primeng/transform.js +325 -0
- package/types/mk-kit-ui-data.d.ts +20 -12
- package/types/mk-kit-ui-dnd.d.ts +2 -0
- package/types/mk-kit-ui-navigation.d.ts +2 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MK_STYLE_PATH = void 0;
|
|
4
|
+
exports.transformTypeScript = transformTypeScript;
|
|
5
|
+
exports.transformTemplate = transformTemplate;
|
|
6
|
+
exports.transformAngularJson = transformAngularJson;
|
|
7
|
+
exports.transformPackageJson = transformPackageJson;
|
|
8
|
+
exports.renderReport = renderReport;
|
|
9
|
+
/**
|
|
10
|
+
* Pure string transforms behind the `migrate-primeng` schematic. No devkit
|
|
11
|
+
* types here so they can be unit-tested on fixtures and reused by other
|
|
12
|
+
* tooling. Every function returns the new text plus what it did.
|
|
13
|
+
*/
|
|
14
|
+
const mapping_1 = require("./mapping");
|
|
15
|
+
const MODULE_BY_PATH = new Map(mapping_1.MODULES.map((m) => [m.path, m]));
|
|
16
|
+
function escapeRe(s) {
|
|
17
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
18
|
+
}
|
|
19
|
+
function docsUrl(route) {
|
|
20
|
+
return route ? `${mapping_1.DOCS_BASE}${route}` : undefined;
|
|
21
|
+
}
|
|
22
|
+
/* ------------------------------------------------------------------------ */
|
|
23
|
+
/* TypeScript */
|
|
24
|
+
/* ------------------------------------------------------------------------ */
|
|
25
|
+
const IMPORT_RE = /import\s*(type\s+)?\{([^}]*)\}\s*from\s*['"]primeng\/([\w-]+)['"];?[ \t]*\r?\n?/g;
|
|
26
|
+
/**
|
|
27
|
+
* Rewrites `primeng/*` imports to `@mk-kit/ui`, renames the imported
|
|
28
|
+
* identifiers everywhere in the file, keeps unmapped symbols on their
|
|
29
|
+
* original import, and dedupes `imports: [...]` arrays.
|
|
30
|
+
*/
|
|
31
|
+
function transformTypeScript(source) {
|
|
32
|
+
const findings = [];
|
|
33
|
+
const mkNames = new Set();
|
|
34
|
+
const renames = new Map();
|
|
35
|
+
const keep = [];
|
|
36
|
+
let text = source;
|
|
37
|
+
let firstImportIndex = -1;
|
|
38
|
+
text = text.replace(IMPORT_RE, (whole, isType, names, path, offset) => {
|
|
39
|
+
const rule = MODULE_BY_PATH.get(path);
|
|
40
|
+
if (firstImportIndex === -1)
|
|
41
|
+
firstImportIndex = offset;
|
|
42
|
+
const symbols = names
|
|
43
|
+
.split(',')
|
|
44
|
+
.map((n) => n.trim())
|
|
45
|
+
.filter(Boolean);
|
|
46
|
+
const unmapped = [];
|
|
47
|
+
for (const raw of symbols) {
|
|
48
|
+
const [name, alias] = raw.split(/\s+as\s+/).map((s) => s.trim());
|
|
49
|
+
const target = rule?.symbols[name];
|
|
50
|
+
if (target) {
|
|
51
|
+
mkNames.add(target);
|
|
52
|
+
renames.set(alias ?? name, target);
|
|
53
|
+
add(findings, `import:primeng/${path}`, `${name} → ${target}`, 'rewrite', rule?.docs);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
unmapped.push(raw);
|
|
57
|
+
add(findings, `import:primeng/${path}`, `${name} (primeng/${path}) has no drop-in equivalent — kept`, rule ? 'manual' : 'unmapped', rule?.docs);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (unmapped.length)
|
|
61
|
+
keep.push(`import ${isType ?? ''}{ ${unmapped.join(', ')} } from 'primeng/${path}';\n`);
|
|
62
|
+
if (rule?.note && symbols.some((s) => rule.symbols[s.split(/\s+as\s+/)[0].trim()])) {
|
|
63
|
+
add(findings, `note:primeng/${path}`, rule.note, 'manual', rule.docs);
|
|
64
|
+
}
|
|
65
|
+
return '';
|
|
66
|
+
});
|
|
67
|
+
if (firstImportIndex === -1)
|
|
68
|
+
return { text: source, changed: false, findings };
|
|
69
|
+
// Rename identifiers (whole words) — includes `imports: [...]` entries and injected services.
|
|
70
|
+
for (const [from, to] of renames) {
|
|
71
|
+
if (from === to)
|
|
72
|
+
continue;
|
|
73
|
+
text = text.replace(new RegExp(`\\b${escapeRe(from)}\\b`, 'g'), to);
|
|
74
|
+
}
|
|
75
|
+
// Dedupe entries inside `imports: [ ... ]` arrays (several PrimeNG symbols map to one class).
|
|
76
|
+
text = text.replace(/imports:\s*\[([^\]]*)\]/g, (whole, inner) => {
|
|
77
|
+
const seen = new Set();
|
|
78
|
+
const items = inner
|
|
79
|
+
.split(',')
|
|
80
|
+
.map((s) => s.trim())
|
|
81
|
+
.filter((s) => s && !seen.has(s) && seen.add(s));
|
|
82
|
+
const multiline = inner.includes('\n');
|
|
83
|
+
return multiline ? `imports: [\n ${items.join(',\n ')},\n ]` : `imports: [${items.join(', ')}]`;
|
|
84
|
+
});
|
|
85
|
+
// Insert the mk-kit import where the first primeng import was, merging with an existing one.
|
|
86
|
+
const header = [...(keep.length ? keep : [])];
|
|
87
|
+
if (mkNames.size) {
|
|
88
|
+
const existing = /import\s*\{([^}]*)\}\s*from\s*['"]@mk-kit\/ui['"];?[ \t]*\r?\n?/;
|
|
89
|
+
const m = existing.exec(text);
|
|
90
|
+
if (m) {
|
|
91
|
+
const merged = new Set(m[1].split(',').map((s) => s.trim()).filter(Boolean));
|
|
92
|
+
for (const n of mkNames)
|
|
93
|
+
merged.add(n);
|
|
94
|
+
text = text.replace(existing, `import { ${[...merged].join(', ')} } from '@mk-kit/ui';\n`);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
header.unshift(`import { ${[...mkNames].join(', ')} } from '@mk-kit/ui';\n`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
text = text.slice(0, firstImportIndex) + header.join('') + text.slice(firstImportIndex);
|
|
101
|
+
// Service usage hints (MessageService / ConfirmationService bodies are not mechanical).
|
|
102
|
+
if (renames.has('MessageService')) {
|
|
103
|
+
text = text.replace(/(\n[ \t]*)([^\n]*\.add\(\s*\{[^\n]*severity[^\n]*)/g, '$1// mk-kit: MessageService.add({severity, summary, detail}) → toast.<severity>(detail, { title: summary })$1$2');
|
|
104
|
+
}
|
|
105
|
+
if (renames.has('ConfirmationService')) {
|
|
106
|
+
text = text.replace(/(\n[ \t]*)([^\n]*\.confirm\(\s*\{[^\n]*)/g, '$1// mk-kit: ConfirmationService.confirm({...}) → await dialog.confirm({ title, message, tone }) returns boolean$1$2');
|
|
107
|
+
}
|
|
108
|
+
// Inline templates get the template pass too.
|
|
109
|
+
const tpl = transformTemplate(text, true);
|
|
110
|
+
text = tpl.text;
|
|
111
|
+
findings.push(...tpl.findings);
|
|
112
|
+
return { text, changed: text !== source, findings };
|
|
113
|
+
}
|
|
114
|
+
/* ------------------------------------------------------------------------ */
|
|
115
|
+
/* Templates */
|
|
116
|
+
/* ------------------------------------------------------------------------ */
|
|
117
|
+
/** Longest selectors first so `p-inputgroupaddon` is not eaten by `p-inputgroup`. */
|
|
118
|
+
const ELEMENT_RULES = mapping_1.SELECTORS.filter((r) => r.kind === 'element').sort((a, b) => b.from.length - a.from.length);
|
|
119
|
+
const ATTRIBUTE_RULES = mapping_1.SELECTORS.filter((r) => r.kind === 'attribute').sort((a, b) => b.from.length - a.from.length);
|
|
120
|
+
function noteComment(rule, inline) {
|
|
121
|
+
const text = `mk-kit: ${rule.from} → ${rule.to ?? 'manual'} — ${rule.note ?? ''}`.trim();
|
|
122
|
+
// Inside a TS template literal `-->` is fine; keep one comment style everywhere.
|
|
123
|
+
return inline ? `<!-- ${text} -->` : `<!-- ${text} -->`;
|
|
124
|
+
}
|
|
125
|
+
function renameAttrs(openTag, attrs) {
|
|
126
|
+
if (!attrs)
|
|
127
|
+
return openTag;
|
|
128
|
+
let out = openTag;
|
|
129
|
+
for (const [from, to] of Object.entries(attrs)) {
|
|
130
|
+
const re = new RegExp(`(\\s)${escapeRe(from)}(?=[\\s=>/])`, 'g');
|
|
131
|
+
out = out.replace(re, (_m, ws) => (to === null ? ws.trimEnd() : `${ws}${to}`));
|
|
132
|
+
}
|
|
133
|
+
return out;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Rewrites PrimeNG selectors in a template (an .html file, or a whole .ts file
|
|
137
|
+
* when `inline` — only `<p-…` tags and known attribute tokens are touched).
|
|
138
|
+
*/
|
|
139
|
+
function transformTemplate(source, inline = false) {
|
|
140
|
+
const findings = [];
|
|
141
|
+
let text = source;
|
|
142
|
+
for (const rule of ELEMENT_RULES) {
|
|
143
|
+
const open = new RegExp(`<${escapeRe(rule.from)}(?=[\\s>/])`, 'g');
|
|
144
|
+
const close = new RegExp(`</${escapeRe(rule.from)}\\s*>`, 'g');
|
|
145
|
+
const matches = text.match(open);
|
|
146
|
+
if (!matches)
|
|
147
|
+
continue;
|
|
148
|
+
const n = matches.length;
|
|
149
|
+
if (rule.to) {
|
|
150
|
+
// Rename open/close tags, then attributes on each opening tag.
|
|
151
|
+
text = text.replace(open, `<${rule.to}`).replace(close, `</${rule.to}>`);
|
|
152
|
+
if (rule.attrs) {
|
|
153
|
+
const tagRe = new RegExp(`<${escapeRe(rule.to)}(\\s[^>]*)?>`, 'g');
|
|
154
|
+
text = text.replace(tagRe, (tag) => renameAttrs(tag, rule.attrs));
|
|
155
|
+
}
|
|
156
|
+
add(findings, `element:${rule.from}`, `<${rule.from}> → <${rule.to}>`, 'rewrite', rule.docs, n);
|
|
157
|
+
if (rule.manual && rule.note) {
|
|
158
|
+
text = insertNote(text, `<${rule.to}`, noteComment(rule, inline));
|
|
159
|
+
add(findings, `manual:${rule.from}`, rule.note, 'manual', rule.docs, n);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
text = insertNote(text, `<${rule.from}`, noteComment(rule, inline));
|
|
164
|
+
add(findings, `element:${rule.from}`, rule.note ?? 'no drop-in equivalent', 'unmapped', rule.docs, n);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
for (const rule of ATTRIBUTE_RULES) {
|
|
168
|
+
// Attribute token forms: `pButton`, `[pTooltip]="…"`, `pTooltip="…"`.
|
|
169
|
+
const token = new RegExp(`(?<=[\\s\\[])${escapeRe(rule.from)}(?=[\\s=\\]>/])`, 'g');
|
|
170
|
+
const matches = text.match(token);
|
|
171
|
+
if (!matches)
|
|
172
|
+
continue;
|
|
173
|
+
const n = matches.length;
|
|
174
|
+
if (rule.to) {
|
|
175
|
+
text = text.replace(token, rule.to);
|
|
176
|
+
if (rule.attrs) {
|
|
177
|
+
const tagRe = new RegExp(`<[a-zA-Z][^>]*\\b${escapeRe(rule.to)}\\b[^>]*>`, 'g');
|
|
178
|
+
text = text.replace(tagRe, (tag) => renameAttrs(tag, rule.attrs));
|
|
179
|
+
}
|
|
180
|
+
add(findings, `attr:${rule.from}`, `${rule.from} → ${rule.to}`, 'rewrite', rule.docs, n);
|
|
181
|
+
if (rule.manual && rule.note) {
|
|
182
|
+
text = insertNoteBeforeTagWith(text, rule.to, noteComment(rule, inline));
|
|
183
|
+
add(findings, `manual:${rule.from}`, rule.note, 'manual', rule.docs, n);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
text = insertNoteBeforeTagWith(text, rule.from, noteComment(rule, inline));
|
|
188
|
+
add(findings, `attr:${rule.from}`, rule.note ?? 'no drop-in equivalent', 'unmapped', rule.docs, n);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return { text, changed: text !== source, findings };
|
|
192
|
+
}
|
|
193
|
+
/** Insert `note` once, right before the first occurrence of `needle` (keeps indentation). */
|
|
194
|
+
function insertNote(text, needle, note) {
|
|
195
|
+
if (text.includes(note))
|
|
196
|
+
return text;
|
|
197
|
+
const i = text.indexOf(needle);
|
|
198
|
+
if (i === -1)
|
|
199
|
+
return text;
|
|
200
|
+
const lineStart = text.lastIndexOf('\n', i) + 1;
|
|
201
|
+
const indent = text.slice(lineStart, i).match(/^[ \t]*$/) ? text.slice(lineStart, i) : '';
|
|
202
|
+
return indent ? text.slice(0, lineStart) + indent + note + '\n' + text.slice(lineStart) : text.slice(0, i) + note + ' ' + text.slice(i);
|
|
203
|
+
}
|
|
204
|
+
/** Insert `note` once before the first tag that carries `attr`. */
|
|
205
|
+
function insertNoteBeforeTagWith(text, attr, note) {
|
|
206
|
+
if (text.includes(note))
|
|
207
|
+
return text;
|
|
208
|
+
const re = new RegExp(`<[a-zA-Z][^>]*(?<=[\\s\\[])${escapeRe(attr)}(?=[\\s=\\]>/])`);
|
|
209
|
+
const m = re.exec(text);
|
|
210
|
+
if (!m)
|
|
211
|
+
return text;
|
|
212
|
+
return insertNote(text, m[0], note);
|
|
213
|
+
}
|
|
214
|
+
/* ------------------------------------------------------------------------ */
|
|
215
|
+
/* Workspace files */
|
|
216
|
+
/* ------------------------------------------------------------------------ */
|
|
217
|
+
exports.MK_STYLE_PATH = 'node_modules/@mk-kit/ui/styles/mk-kit.css';
|
|
218
|
+
/** Remove PrimeNG / primeicons / primeflex style entries from every project's `styles`; add the mk-kit theme. */
|
|
219
|
+
function transformAngularJson(source) {
|
|
220
|
+
const findings = [];
|
|
221
|
+
let json;
|
|
222
|
+
try {
|
|
223
|
+
json = JSON.parse(source);
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
return { text: source, changed: false, findings };
|
|
227
|
+
}
|
|
228
|
+
let changed = false;
|
|
229
|
+
for (const project of Object.values(json.projects ?? {})) {
|
|
230
|
+
const options = project?.architect?.build?.options;
|
|
231
|
+
if (!options || !Array.isArray(options.styles))
|
|
232
|
+
continue;
|
|
233
|
+
const before = options.styles.length;
|
|
234
|
+
options.styles = options.styles.filter((s) => {
|
|
235
|
+
const p = typeof s === 'string' ? s : s?.input ?? '';
|
|
236
|
+
return !/prime(ng|icons|flex|uix)/i.test(p);
|
|
237
|
+
});
|
|
238
|
+
if (options.styles.length !== before) {
|
|
239
|
+
changed = true;
|
|
240
|
+
add(findings, 'styles:primeng', `removed ${before - options.styles.length} PrimeNG/primeicons style entries`, 'rewrite', '/theming', before - options.styles.length);
|
|
241
|
+
}
|
|
242
|
+
const has = options.styles.some((s) => (typeof s === 'string' ? s : s?.input ?? '').includes('@mk-kit/ui/styles'));
|
|
243
|
+
if (!has) {
|
|
244
|
+
options.styles.unshift(exports.MK_STYLE_PATH);
|
|
245
|
+
changed = true;
|
|
246
|
+
add(findings, 'styles:mk-kit', `added ${exports.MK_STYLE_PATH}`, 'rewrite', '/theming');
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return { text: changed ? JSON.stringify(json, null, 2) + '\n' : source, changed, findings };
|
|
250
|
+
}
|
|
251
|
+
/** Drop PrimeNG packages from dependencies and make sure @mk-kit/ui is present. */
|
|
252
|
+
function transformPackageJson(source, packages, mkVersion = '^0.38.0') {
|
|
253
|
+
const findings = [];
|
|
254
|
+
let json;
|
|
255
|
+
try {
|
|
256
|
+
json = JSON.parse(source);
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
return { text: source, changed: false, findings };
|
|
260
|
+
}
|
|
261
|
+
let changed = false;
|
|
262
|
+
for (const field of ['dependencies', 'devDependencies']) {
|
|
263
|
+
const deps = json[field];
|
|
264
|
+
if (!deps)
|
|
265
|
+
continue;
|
|
266
|
+
for (const p of packages) {
|
|
267
|
+
if (p in deps) {
|
|
268
|
+
delete deps[p];
|
|
269
|
+
changed = true;
|
|
270
|
+
add(findings, 'package:remove', `removed ${p} from ${field}`, 'rewrite');
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
json.dependencies ??= {};
|
|
275
|
+
if (!json.dependencies['@mk-kit/ui']) {
|
|
276
|
+
json.dependencies['@mk-kit/ui'] = mkVersion;
|
|
277
|
+
changed = true;
|
|
278
|
+
add(findings, 'package:add', `added @mk-kit/ui ${mkVersion}`, 'rewrite');
|
|
279
|
+
}
|
|
280
|
+
return { text: changed ? JSON.stringify(json, null, 2) + '\n' : source, changed, findings };
|
|
281
|
+
}
|
|
282
|
+
function add(findings, rule, message, kind, docs, count = 1) {
|
|
283
|
+
const existing = findings.find((f) => f.rule === rule && f.message === message);
|
|
284
|
+
if (existing)
|
|
285
|
+
existing.count += count;
|
|
286
|
+
else
|
|
287
|
+
findings.push({ rule, message, kind, docs: docsUrl(docs), count });
|
|
288
|
+
}
|
|
289
|
+
/** Markdown report of a whole run. */
|
|
290
|
+
function renderReport(files, options) {
|
|
291
|
+
const all = files.flatMap((f) => f.findings.map((x) => ({ ...x, file: f.path })));
|
|
292
|
+
const changed = files.filter((f) => f.changed);
|
|
293
|
+
const byKind = (kind) => all.filter((f) => f.kind === kind);
|
|
294
|
+
const sum = (list) => list.reduce((n, f) => n + f.count, 0);
|
|
295
|
+
const lines = [];
|
|
296
|
+
lines.push('# PrimeNG → mk-kit migration report', '');
|
|
297
|
+
lines.push(`${options.dryRun ? '**Dry run** — nothing was written. ' : ''}Scanned ${options.scanned} files, ${options.dryRun ? 'would change' : 'changed'} ${changed.length}.`, '');
|
|
298
|
+
lines.push(`- Automatic rewrites: **${sum(byKind('rewrite'))}**`);
|
|
299
|
+
lines.push(`- Needs a manual touch: **${sum(byKind('manual'))}**`);
|
|
300
|
+
lines.push(`- No mk-kit equivalent: **${sum(byKind('unmapped'))}**`, '');
|
|
301
|
+
lines.push('## Rewrites', '');
|
|
302
|
+
const rewrites = group(byKind('rewrite'));
|
|
303
|
+
lines.push(...(rewrites.length ? rewrites.map(([msg, n]) => `- ${msg} ×${n}`) : ['- (none)']), '');
|
|
304
|
+
lines.push('## Manual steps', '', 'Look for `<!-- mk-kit: … -->` and `// mk-kit:` comments in the changed files.', '');
|
|
305
|
+
const manual = group(byKind('manual'), true);
|
|
306
|
+
lines.push(...(manual.length ? manual.map(([msg, n, docs]) => `- ${msg} ×${n}${docs ? ` — [docs](${docs})` : ''}`) : ['- (none)']), '');
|
|
307
|
+
lines.push('## Not available in mk-kit', '');
|
|
308
|
+
const unmapped = group(byKind('unmapped'), true);
|
|
309
|
+
lines.push(...(unmapped.length ? unmapped.map(([msg, n, docs]) => `- ${msg} ×${n}${docs ? ` — closest: [docs](${docs})` : ''}`) : ['- (none)']), '');
|
|
310
|
+
lines.push('## Files', '');
|
|
311
|
+
lines.push(...(changed.length ? changed.map((f) => `- \`${f.path}\` — ${f.findings.map((x) => `${x.rule}×${x.count}`).join(', ')}`) : ['- (none)']), '');
|
|
312
|
+
lines.push('## Next', '');
|
|
313
|
+
lines.push('1. Run `ng build` and fix the remaining template errors — most are the `<!-- mk-kit -->` notes above.', '2. Replace `MessageService.add(...)` calls with `MkToastService` and `ConfirmationService.confirm(...)` with `await MkDialogService.confirm(...)`.', '3. Icons: `pi pi-*` classes → `<mk-icon name="…" />` (see https://mk-kit.dev/components/icon).', `4. Theme: \`--mk-*\` tokens replace the PrimeNG preset — https://mk-kit.dev/theming.`, '');
|
|
314
|
+
return lines.join('\n');
|
|
315
|
+
}
|
|
316
|
+
function group(list, withDocs = false) {
|
|
317
|
+
const map = new Map();
|
|
318
|
+
for (const f of list) {
|
|
319
|
+
const key = f.message;
|
|
320
|
+
const cur = map.get(key) ?? [0, f.docs];
|
|
321
|
+
cur[0] += f.count;
|
|
322
|
+
map.set(key, cur);
|
|
323
|
+
}
|
|
324
|
+
return [...map.entries()].map(([msg, [n, docs]]) => [msg, n, withDocs ? docs : undefined]);
|
|
325
|
+
}
|
|
@@ -1758,6 +1758,21 @@ declare class MkCountdown {
|
|
|
1758
1758
|
|
|
1759
1759
|
/** Layout for {@link MkDescriptionList}. */
|
|
1760
1760
|
type MkDescriptionLayout = 'grid' | 'stacked';
|
|
1761
|
+
/**
|
|
1762
|
+
* A single term/detail row of {@link MkDescriptionList}: `term` becomes the
|
|
1763
|
+
* `<dt>`, the projected content the `<dd>`. The row itself renders nothing —
|
|
1764
|
+
* the list reads its rows and writes `<dt>`/`<dd>` as direct children of the
|
|
1765
|
+
* `<dl>`, which is what HTML and assistive tech require (a wrapper element
|
|
1766
|
+
* between `<dl>` and `<dt>` fails axe `definition-list` / `dlitem`).
|
|
1767
|
+
*/
|
|
1768
|
+
declare class MkDescItem {
|
|
1769
|
+
/** The term (label) shown in the `<dt>`. */
|
|
1770
|
+
readonly term: _angular_core.InputSignal<string>;
|
|
1771
|
+
/** The row's detail content, rendered by the list inside its `<dd>`. @internal */
|
|
1772
|
+
readonly content: _angular_core.Signal<TemplateRef<unknown>>;
|
|
1773
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkDescItem, never>;
|
|
1774
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkDescItem, "mk-desc-item", never, { "term": { "alias": "term"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1775
|
+
}
|
|
1761
1776
|
/**
|
|
1762
1777
|
* DescriptionList — a semantic `<dl>` of term/detail pairs for entity-detail and
|
|
1763
1778
|
* metadata panels. Project {@link MkDescItem} rows; values may be rich content
|
|
@@ -1770,25 +1785,18 @@ type MkDescriptionLayout = 'grid' | 'stacked';
|
|
|
1770
1785
|
* <mk-desc-item term="Owner">Ada Lovelace</mk-desc-item>
|
|
1771
1786
|
* </mk-description-list>
|
|
1772
1787
|
* ```
|
|
1788
|
+
*
|
|
1789
|
+
* Only `mk-desc-item` children are rendered; the `<dl>` always contains plain
|
|
1790
|
+
* `<dt>`/`<dd>` pairs.
|
|
1773
1791
|
*/
|
|
1774
1792
|
declare class MkDescriptionList {
|
|
1775
1793
|
/** `grid` aligns terms in a column; `stacked` puts each term above its value. */
|
|
1776
1794
|
readonly layout: _angular_core.InputSignal<MkDescriptionLayout>;
|
|
1777
1795
|
/** Draw a divider between rows. */
|
|
1778
1796
|
readonly divided: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1797
|
+
protected readonly items: _angular_core.Signal<readonly MkDescItem[]>;
|
|
1779
1798
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkDescriptionList, never>;
|
|
1780
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkDescriptionList, "mk-description-list", never, { "layout": { "alias": "layout"; "required": false; "isSignal": true; }; "divided": { "alias": "divided"; "required": false; "isSignal": true; }; }, {},
|
|
1781
|
-
}
|
|
1782
|
-
/**
|
|
1783
|
-
* A single term/detail row inside {@link MkDescriptionList}. Renders a `<dt>`
|
|
1784
|
-
* (the `term`) and a `<dd>` (the projected value). The host is `display:contents`
|
|
1785
|
-
* so the `<dt>`/`<dd>` participate directly in the list's grid.
|
|
1786
|
-
*/
|
|
1787
|
-
declare class MkDescItem {
|
|
1788
|
-
/** The term (label) shown in the `<dt>`. */
|
|
1789
|
-
readonly term: _angular_core.InputSignal<string>;
|
|
1790
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkDescItem, never>;
|
|
1791
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkDescItem, "mk-desc-item", never, { "term": { "alias": "term"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1799
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkDescriptionList, "mk-description-list", never, { "layout": { "alias": "layout"; "required": false; "isSignal": true; }; "divided": { "alias": "divided"; "required": false; "isSignal": true; }; }, {}, ["items"], never, true, never>;
|
|
1792
1800
|
}
|
|
1793
1801
|
|
|
1794
1802
|
/**
|
package/types/mk-kit-ui-dnd.d.ts
CHANGED
|
@@ -210,6 +210,8 @@ declare class MkDrag<T = unknown> {
|
|
|
210
210
|
private cleanupDom;
|
|
211
211
|
private emit;
|
|
212
212
|
private isHandleTarget;
|
|
213
|
+
/** Whether `target` belongs to this item rather than to a nested `[mkDrag]`. */
|
|
214
|
+
private isOwnTarget;
|
|
213
215
|
private prefersReducedMotion;
|
|
214
216
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<MkDrag<any>, never>;
|
|
215
217
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<MkDrag<any>, "[mkDrag]", ["mkDrag"], { "mkDragData": { "alias": "mkDragData"; "required": false; "isSignal": true; }; "mkDragDisabled": { "alias": "mkDragDisabled"; "required": false; "isSignal": true; }; "mkDragTouchDelay": { "alias": "mkDragTouchDelay"; "required": false; "isSignal": true; }; }, {}, ["handles"], ["*"], true, never>;
|
|
@@ -643,6 +643,8 @@ declare class MkNavGroup {
|
|
|
643
643
|
readonly expanded: _angular_core.ModelSignal<boolean>;
|
|
644
644
|
/** Id of the items region (for `aria-controls`). */
|
|
645
645
|
readonly regionId: string;
|
|
646
|
+
/** Id of the header, used to name the nested item list. */
|
|
647
|
+
readonly headerId: string;
|
|
646
648
|
/** Whether the enclosing list is a collapsed icon rail. */
|
|
647
649
|
protected readonly railCollapsed: _angular_core.Signal<boolean>;
|
|
648
650
|
/** Items are visible unless collapsible-and-closed. */
|