@mesgflow/ui-kit 0.6.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/LICENSE +21 -0
- package/README.md +200 -0
- package/fesm2022/mesgflow-ui-kit-accordion.mjs +75 -0
- package/fesm2022/mesgflow-ui-kit-accordion.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-alert.mjs +165 -0
- package/fesm2022/mesgflow-ui-kit-alert.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-avatar-group.mjs +88 -0
- package/fesm2022/mesgflow-ui-kit-avatar-group.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-avatar.mjs +123 -0
- package/fesm2022/mesgflow-ui-kit-avatar.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-badge.mjs +68 -0
- package/fesm2022/mesgflow-ui-kit-badge.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-banner.mjs +111 -0
- package/fesm2022/mesgflow-ui-kit-banner.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-box-input.mjs +78 -0
- package/fesm2022/mesgflow-ui-kit-box-input.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-brand.mjs +120 -0
- package/fesm2022/mesgflow-ui-kit-brand.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-breadcrumb.mjs +84 -0
- package/fesm2022/mesgflow-ui-kit-breadcrumb.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-button-group.mjs +37 -0
- package/fesm2022/mesgflow-ui-kit-button-group.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-button.mjs +359 -0
- package/fesm2022/mesgflow-ui-kit-button.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-card.mjs +128 -0
- package/fesm2022/mesgflow-ui-kit-card.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-chart.mjs +538 -0
- package/fesm2022/mesgflow-ui-kit-chart.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-checkbox.mjs +45 -0
- package/fesm2022/mesgflow-ui-kit-checkbox.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-chip.mjs +123 -0
- package/fesm2022/mesgflow-ui-kit-chip.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-code-block.mjs +71 -0
- package/fesm2022/mesgflow-ui-kit-code-block.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-collapsible.mjs +89 -0
- package/fesm2022/mesgflow-ui-kit-collapsible.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-color-picker.mjs +210 -0
- package/fesm2022/mesgflow-ui-kit-color-picker.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-combobox.mjs +181 -0
- package/fesm2022/mesgflow-ui-kit-combobox.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-command.mjs +491 -0
- package/fesm2022/mesgflow-ui-kit-command.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-context-menu.mjs +92 -0
- package/fesm2022/mesgflow-ui-kit-context-menu.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-copy-button.mjs +167 -0
- package/fesm2022/mesgflow-ui-kit-copy-button.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-core.mjs +624 -0
- package/fesm2022/mesgflow-ui-kit-core.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-date-picker.mjs +643 -0
- package/fesm2022/mesgflow-ui-kit-date-picker.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-description-list.mjs +76 -0
- package/fesm2022/mesgflow-ui-kit-description-list.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-dialog.mjs +700 -0
- package/fesm2022/mesgflow-ui-kit-dialog.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-divider.mjs +62 -0
- package/fesm2022/mesgflow-ui-kit-divider.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-dropzone.mjs +126 -0
- package/fesm2022/mesgflow-ui-kit-dropzone.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-empty-state.mjs +70 -0
- package/fesm2022/mesgflow-ui-kit-empty-state.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-field.mjs +42 -0
- package/fesm2022/mesgflow-ui-kit-field.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-hover-card.mjs +171 -0
- package/fesm2022/mesgflow-ui-kit-hover-card.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-i18n-tr.mjs +258 -0
- package/fesm2022/mesgflow-ui-kit-i18n-tr.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-icon.mjs +174 -0
- package/fesm2022/mesgflow-ui-kit-icon.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-input.mjs +448 -0
- package/fesm2022/mesgflow-ui-kit-input.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-kbd.mjs +24 -0
- package/fesm2022/mesgflow-ui-kit-kbd.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-link.mjs +48 -0
- package/fesm2022/mesgflow-ui-kit-link.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-menu.mjs +105 -0
- package/fesm2022/mesgflow-ui-kit-menu.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-number-input.mjs +153 -0
- package/fesm2022/mesgflow-ui-kit-number-input.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-otp-input.mjs +164 -0
- package/fesm2022/mesgflow-ui-kit-otp-input.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-page-header.mjs +83 -0
- package/fesm2022/mesgflow-ui-kit-page-header.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-pagination.mjs +99 -0
- package/fesm2022/mesgflow-ui-kit-pagination.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-password-input.mjs +120 -0
- package/fesm2022/mesgflow-ui-kit-password-input.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-popover.mjs +213 -0
- package/fesm2022/mesgflow-ui-kit-popover.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-progress.mjs +82 -0
- package/fesm2022/mesgflow-ui-kit-progress.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-radio.mjs +123 -0
- package/fesm2022/mesgflow-ui-kit-radio.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-rating.mjs +116 -0
- package/fesm2022/mesgflow-ui-kit-rating.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-scroll-area.mjs +84 -0
- package/fesm2022/mesgflow-ui-kit-scroll-area.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-search-input.mjs +154 -0
- package/fesm2022/mesgflow-ui-kit-search-input.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-segmented-control.mjs +95 -0
- package/fesm2022/mesgflow-ui-kit-segmented-control.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-select.mjs +227 -0
- package/fesm2022/mesgflow-ui-kit-select.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-sidebar.mjs +449 -0
- package/fesm2022/mesgflow-ui-kit-sidebar.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-skeleton.mjs +74 -0
- package/fesm2022/mesgflow-ui-kit-skeleton.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-slider.mjs +179 -0
- package/fesm2022/mesgflow-ui-kit-slider.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-spinner.mjs +67 -0
- package/fesm2022/mesgflow-ui-kit-spinner.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-splitter.mjs +97 -0
- package/fesm2022/mesgflow-ui-kit-splitter.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-stat-tile.mjs +98 -0
- package/fesm2022/mesgflow-ui-kit-stat-tile.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-stepper.mjs +133 -0
- package/fesm2022/mesgflow-ui-kit-stepper.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-switch.mjs +73 -0
- package/fesm2022/mesgflow-ui-kit-switch.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-table.mjs +1783 -0
- package/fesm2022/mesgflow-ui-kit-table.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-tabs.mjs +569 -0
- package/fesm2022/mesgflow-ui-kit-tabs.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-tag-input.mjs +138 -0
- package/fesm2022/mesgflow-ui-kit-tag-input.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-theme-switcher.mjs +53 -0
- package/fesm2022/mesgflow-ui-kit-theme-switcher.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-theming.mjs +1016 -0
- package/fesm2022/mesgflow-ui-kit-theming.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-time-picker.mjs +138 -0
- package/fesm2022/mesgflow-ui-kit-time-picker.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-timeline.mjs +91 -0
- package/fesm2022/mesgflow-ui-kit-timeline.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-toast.mjs +202 -0
- package/fesm2022/mesgflow-ui-kit-toast.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-toggle.mjs +243 -0
- package/fesm2022/mesgflow-ui-kit-toggle.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-toolbar.mjs +99 -0
- package/fesm2022/mesgflow-ui-kit-toolbar.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-tooltip.mjs +160 -0
- package/fesm2022/mesgflow-ui-kit-tooltip.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-tour.mjs +272 -0
- package/fesm2022/mesgflow-ui-kit-tour.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-tree-select.mjs +177 -0
- package/fesm2022/mesgflow-ui-kit-tree-select.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit-tree.mjs +82 -0
- package/fesm2022/mesgflow-ui-kit-tree.mjs.map +1 -0
- package/fesm2022/mesgflow-ui-kit.mjs +12851 -0
- package/fesm2022/mesgflow-ui-kit.mjs.map +1 -0
- package/package.json +374 -0
- package/preset.css +20 -0
- package/tokens/color.css +693 -0
- package/tokens/contrast.css +68 -0
- package/tokens/elevation.css +68 -0
- package/tokens/motion.css +277 -0
- package/tokens/radius.css +69 -0
- package/tokens/typography.css +127 -0
- package/tokens.css +41 -0
- package/types/mesgflow-ui-kit-accordion.d.ts +42 -0
- package/types/mesgflow-ui-kit-alert.d.ts +60 -0
- package/types/mesgflow-ui-kit-avatar-group.d.ts +28 -0
- package/types/mesgflow-ui-kit-avatar.d.ts +23 -0
- package/types/mesgflow-ui-kit-badge.d.ts +39 -0
- package/types/mesgflow-ui-kit-banner.d.ts +42 -0
- package/types/mesgflow-ui-kit-box-input.d.ts +45 -0
- package/types/mesgflow-ui-kit-brand.d.ts +48 -0
- package/types/mesgflow-ui-kit-breadcrumb.d.ts +26 -0
- package/types/mesgflow-ui-kit-button-group.d.ts +17 -0
- package/types/mesgflow-ui-kit-button.d.ts +75 -0
- package/types/mesgflow-ui-kit-card.d.ts +71 -0
- package/types/mesgflow-ui-kit-chart.d.ts +242 -0
- package/types/mesgflow-ui-kit-checkbox.d.ts +17 -0
- package/types/mesgflow-ui-kit-chip.d.ts +46 -0
- package/types/mesgflow-ui-kit-code-block.d.ts +56 -0
- package/types/mesgflow-ui-kit-collapsible.d.ts +39 -0
- package/types/mesgflow-ui-kit-color-picker.d.ts +78 -0
- package/types/mesgflow-ui-kit-combobox.d.ts +74 -0
- package/types/mesgflow-ui-kit-command.d.ts +185 -0
- package/types/mesgflow-ui-kit-context-menu.d.ts +40 -0
- package/types/mesgflow-ui-kit-copy-button.d.ts +47 -0
- package/types/mesgflow-ui-kit-core.d.ts +508 -0
- package/types/mesgflow-ui-kit-date-picker.d.ts +215 -0
- package/types/mesgflow-ui-kit-description-list.d.ts +23 -0
- package/types/mesgflow-ui-kit-dialog.d.ts +342 -0
- package/types/mesgflow-ui-kit-divider.d.ts +23 -0
- package/types/mesgflow-ui-kit-dropzone.d.ts +47 -0
- package/types/mesgflow-ui-kit-empty-state.d.ts +18 -0
- package/types/mesgflow-ui-kit-field.d.ts +26 -0
- package/types/mesgflow-ui-kit-hover-card.d.ts +52 -0
- package/types/mesgflow-ui-kit-i18n-tr.d.ts +14 -0
- package/types/mesgflow-ui-kit-icon.d.ts +76 -0
- package/types/mesgflow-ui-kit-input.d.ts +186 -0
- package/types/mesgflow-ui-kit-kbd.d.ts +9 -0
- package/types/mesgflow-ui-kit-link.d.ts +20 -0
- package/types/mesgflow-ui-kit-menu.d.ts +53 -0
- package/types/mesgflow-ui-kit-number-input.d.ts +55 -0
- package/types/mesgflow-ui-kit-otp-input.d.ts +44 -0
- package/types/mesgflow-ui-kit-page-header.d.ts +31 -0
- package/types/mesgflow-ui-kit-pagination.d.ts +50 -0
- package/types/mesgflow-ui-kit-password-input.d.ts +33 -0
- package/types/mesgflow-ui-kit-popover.d.ts +62 -0
- package/types/mesgflow-ui-kit-progress.d.ts +32 -0
- package/types/mesgflow-ui-kit-radio.d.ts +59 -0
- package/types/mesgflow-ui-kit-rating.d.ts +56 -0
- package/types/mesgflow-ui-kit-scroll-area.d.ts +27 -0
- package/types/mesgflow-ui-kit-search-input.d.ts +72 -0
- package/types/mesgflow-ui-kit-segmented-control.d.ts +54 -0
- package/types/mesgflow-ui-kit-select.d.ts +89 -0
- package/types/mesgflow-ui-kit-sidebar.d.ts +224 -0
- package/types/mesgflow-ui-kit-skeleton.d.ts +29 -0
- package/types/mesgflow-ui-kit-slider.d.ts +40 -0
- package/types/mesgflow-ui-kit-spinner.d.ts +31 -0
- package/types/mesgflow-ui-kit-splitter.d.ts +40 -0
- package/types/mesgflow-ui-kit-stat-tile.d.ts +54 -0
- package/types/mesgflow-ui-kit-stepper.d.ts +48 -0
- package/types/mesgflow-ui-kit-switch.d.ts +34 -0
- package/types/mesgflow-ui-kit-table.d.ts +805 -0
- package/types/mesgflow-ui-kit-tabs.d.ts +269 -0
- package/types/mesgflow-ui-kit-tag-input.d.ts +33 -0
- package/types/mesgflow-ui-kit-theme-switcher.d.ts +27 -0
- package/types/mesgflow-ui-kit-theming.d.ts +745 -0
- package/types/mesgflow-ui-kit-time-picker.d.ts +54 -0
- package/types/mesgflow-ui-kit-timeline.d.ts +27 -0
- package/types/mesgflow-ui-kit-toast.d.ts +94 -0
- package/types/mesgflow-ui-kit-toggle.d.ts +110 -0
- package/types/mesgflow-ui-kit-toolbar.d.ts +52 -0
- package/types/mesgflow-ui-kit-tooltip.d.ts +55 -0
- package/types/mesgflow-ui-kit-tour.d.ts +66 -0
- package/types/mesgflow-ui-kit-tree-select.d.ts +65 -0
- package/types/mesgflow-ui-kit-tree.d.ts +44 -0
- package/types/mesgflow-ui-kit.d.ts +5444 -0
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, model, booleanAttribute, output, inject, ElementRef, viewChild, computed, linkedSignal, afterRenderEffect, Component, Service, Directive } from '@angular/core';
|
|
3
|
+
import { MF_COMMAND_LABELS, MF_DATE_LOCALE } from '@mesgflow/ui-kit/core';
|
|
4
|
+
import { Icon } from '@mesgflow/ui-kit/icon';
|
|
5
|
+
import { Kbd } from '@mesgflow/ui-kit/kbd';
|
|
6
|
+
import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog';
|
|
7
|
+
import { DialogSurface, DialogService } from '@mesgflow/ui-kit/dialog';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Tek karakteri karşılaştırma biçimine indirger — 1:1 uzunluk KORUNUR (vurgu aralıkları orijinal
|
|
11
|
+
* etiket üzerinde doğrudan kullanılabilsin diye): küçük harf + aksan atma ("Ö"→"o", "ç"→"c") +
|
|
12
|
+
* noktasız ı→i. Böylece "ozel" "Özel"i, "ISIK" "ışık"ı bulur — Türkçe klavyesiz yazan kullanıcı
|
|
13
|
+
* için premium paletlerin (Linear, Raycast) beklenen davranışı.
|
|
14
|
+
*/
|
|
15
|
+
function foldChar(char, locale) {
|
|
16
|
+
const lower = char.toLocaleLowerCase(locale);
|
|
17
|
+
const stripped = lower.normalize('NFD').replace(/\p{M}/gu, '');
|
|
18
|
+
// Kod noktası bazında — `charAt` bir emoji'nin yarısını (UTF-16 vekil çifti) döndürürdü.
|
|
19
|
+
const first = Array.from(stripped)[0] ?? Array.from(lower)[0] ?? char;
|
|
20
|
+
return first === 'ı' ? 'i' : first;
|
|
21
|
+
}
|
|
22
|
+
function foldText(text, locale) {
|
|
23
|
+
let out = '';
|
|
24
|
+
for (const char of text)
|
|
25
|
+
out += foldChar(char, locale);
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
const WORD_BOUNDARY = /[\s\-_/.:]/;
|
|
29
|
+
function isWordStart(text, index) {
|
|
30
|
+
return index === 0 || WORD_BOUNDARY.test(text.charAt(index - 1));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Alt-dizi (subsequence) eşleşmesi — her sorgu karakteri SIRAYLA bulunmalı. Kelime başına düşen
|
|
34
|
+
* ve ardışık gelen karakterler ödüllendirilir ("gs" → "**G**enel **S**ayfa").
|
|
35
|
+
* Eşleşme yoksa `null`.
|
|
36
|
+
*/
|
|
37
|
+
function fuzzyMatch(text, query) {
|
|
38
|
+
const indices = [];
|
|
39
|
+
let score = 0;
|
|
40
|
+
let from = 0;
|
|
41
|
+
for (const char of query) {
|
|
42
|
+
// Önce bir kelime başında aranır; yoksa ilk görünen konuma düşülür.
|
|
43
|
+
let index = -1;
|
|
44
|
+
for (let i = from; i < text.length; i++) {
|
|
45
|
+
if (text.charAt(i) === char && isWordStart(text, i)) {
|
|
46
|
+
index = i;
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (index === -1)
|
|
51
|
+
index = text.indexOf(char, from);
|
|
52
|
+
if (index === -1)
|
|
53
|
+
return null;
|
|
54
|
+
const previous = indices.at(-1);
|
|
55
|
+
if (previous !== undefined && index === previous + 1)
|
|
56
|
+
score += 3;
|
|
57
|
+
if (isWordStart(text, index))
|
|
58
|
+
score += 2;
|
|
59
|
+
indices.push(index);
|
|
60
|
+
from = index + 1;
|
|
61
|
+
}
|
|
62
|
+
return { score, indices };
|
|
63
|
+
}
|
|
64
|
+
function toSegments(label, indices) {
|
|
65
|
+
const chars = Array.from(label);
|
|
66
|
+
const hit = new Set(indices);
|
|
67
|
+
const segments = [];
|
|
68
|
+
chars.forEach((char, i) => {
|
|
69
|
+
const match = hit.has(i);
|
|
70
|
+
const last = segments.at(-1);
|
|
71
|
+
if (last && last.match === match)
|
|
72
|
+
last.text += char;
|
|
73
|
+
else
|
|
74
|
+
segments.push({ text: char, match });
|
|
75
|
+
});
|
|
76
|
+
return segments;
|
|
77
|
+
}
|
|
78
|
+
function range(start, length) {
|
|
79
|
+
return Array.from({ length }, (_, i) => start + i);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Puan basamakları (yüksek → düşük): tam etiket 1000 · etiket başı 800 · kelime başı 600 ·
|
|
83
|
+
* etiket içi 400 · anahtar kelime / ipucu 200–300 · bulanık alt-dizi 100+. Aynı basamakta kısa
|
|
84
|
+
* etiket öne geçer (daha "tam" eşleşme). Etiketi eşleşmeyen öğenin segmentleri vurgusuzdur.
|
|
85
|
+
*/
|
|
86
|
+
function scoreCommand(item, foldedQuery, locale) {
|
|
87
|
+
const plain = [{ text: item.label, match: false }];
|
|
88
|
+
if (!foldedQuery)
|
|
89
|
+
return { item, score: 0, segments: plain };
|
|
90
|
+
const label = foldText(item.label, locale);
|
|
91
|
+
const brevity = Math.max(0, 50 - label.length);
|
|
92
|
+
const queryLength = Array.from(foldedQuery).length;
|
|
93
|
+
const at = label.indexOf(foldedQuery);
|
|
94
|
+
if (at !== -1) {
|
|
95
|
+
// `foldText` 1:1 olduğu için UTF-16 indeksi yerine kod noktası indeksine çevrilir.
|
|
96
|
+
const start = Array.from(label.slice(0, at)).length;
|
|
97
|
+
const base = label === foldedQuery ? 1000 : at === 0 ? 800 : isWordStart(label, at) ? 600 : 400;
|
|
98
|
+
return {
|
|
99
|
+
item,
|
|
100
|
+
score: base + brevity,
|
|
101
|
+
segments: toSegments(item.label, range(start, queryLength)),
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const extras = [...(item.keywords ?? []), item.hint ?? ''].map((text) => foldText(text, locale));
|
|
105
|
+
if (extras.some((text) => text.startsWith(foldedQuery)))
|
|
106
|
+
return { item, score: 300, segments: plain };
|
|
107
|
+
if (extras.some((text) => text.includes(foldedQuery)))
|
|
108
|
+
return { item, score: 200, segments: plain };
|
|
109
|
+
const fuzzy = fuzzyMatch(label, foldedQuery);
|
|
110
|
+
if (!fuzzy)
|
|
111
|
+
return null;
|
|
112
|
+
const chars = Array.from(label);
|
|
113
|
+
const indices = fuzzy.indices.map((i) => Array.from(label.slice(0, i)).length);
|
|
114
|
+
return {
|
|
115
|
+
item,
|
|
116
|
+
score: 100 + fuzzy.score + Math.max(0, 50 - chars.length) / 10,
|
|
117
|
+
segments: toSegments(item.label, indices),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Boş sorguda öğeler verildiği sırada döner; doluyken puana göre (eşitlikte verilen sıra —
|
|
122
|
+
* `Array.prototype.sort` kararlı) sıralanır ve ilk `limit` tutulur.
|
|
123
|
+
*/
|
|
124
|
+
function filterCommands(items, query, options = {}) {
|
|
125
|
+
const { limit = Infinity, locale } = options;
|
|
126
|
+
const folded = foldText(query.trim(), locale);
|
|
127
|
+
const results = [];
|
|
128
|
+
for (const item of items) {
|
|
129
|
+
const result = scoreCommand(item, folded, locale);
|
|
130
|
+
if (result)
|
|
131
|
+
results.push(result);
|
|
132
|
+
}
|
|
133
|
+
if (folded)
|
|
134
|
+
results.sort((a, b) => b.score - a.score);
|
|
135
|
+
return results.slice(0, limit);
|
|
136
|
+
}
|
|
137
|
+
/** Sonuçları `group`'a göre toplar — grup sırası, o gruptaki EN İYİ sonucun sırasıdır. */
|
|
138
|
+
function groupCommands(results) {
|
|
139
|
+
const groups = new Map();
|
|
140
|
+
for (const result of results) {
|
|
141
|
+
const key = result.item.group ?? '';
|
|
142
|
+
let group = groups.get(key);
|
|
143
|
+
if (!group) {
|
|
144
|
+
group = { label: key, results: [] };
|
|
145
|
+
groups.set(key, group);
|
|
146
|
+
}
|
|
147
|
+
group.results.push(result);
|
|
148
|
+
}
|
|
149
|
+
return [...groups.values()];
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
let commandIdSeq = 0;
|
|
153
|
+
/**
|
|
154
|
+
* `<mf-command [items]="commands" (run)="onRun($event)" />`
|
|
155
|
+
*
|
|
156
|
+
* Komut paleti gövdesi — arama kutusu + gruplu sonuç listesi. Tek başına (sayfa içi, ör. bir
|
|
157
|
+
* ayarlar arama alanı) kullanılabilir; ⌘K deneyimi için `CommandPaletteService.open()` bunu bir
|
|
158
|
+
* dialog içinde açar (bkz. `command-palette.service.ts`).
|
|
159
|
+
*
|
|
160
|
+
* ARIA 1.2 combobox deseni: odak HER ZAMAN input'ta kalır, etkin satır `aria-activedescendant`
|
|
161
|
+
* ile duyurulur (satırlar odaklanamaz — `mousedown` engellenir, aksi halde input odağı kaybederdi).
|
|
162
|
+
* Arama aksan/büyük-küçük harf duyarsız, alt-dizi (fuzzy) eşleşmeli ve eşleşen harfleri vurgular
|
|
163
|
+
* (bkz. `command-search.ts`). Esc: sorgu doluysa ÖNCE sorguyu temizler (Raycast/Linear davranışı),
|
|
164
|
+
* boşsa olayı yukarı bırakır — dialog'un kendi Esc kapanışı çalışır.
|
|
165
|
+
*/
|
|
166
|
+
class Command {
|
|
167
|
+
items = input.required(/* @ts-ignore */
|
|
168
|
+
...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
169
|
+
query = model('', /* @ts-ignore */
|
|
170
|
+
...(ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []));
|
|
171
|
+
placeholder = input(/* @ts-ignore */
|
|
172
|
+
...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
173
|
+
ariaLabel = input(/* @ts-ignore */
|
|
174
|
+
...(ngDevMode ? [undefined, { debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
175
|
+
/** Dolu sorguda gösterilecek en fazla sonuç — boş sorguda tüm liste (tüketici sıralaması) gösterilir. */
|
|
176
|
+
limit = input(50, /* @ts-ignore */
|
|
177
|
+
...(ngDevMode ? [{ debugName: "limit" }] : /* istanbul ignore next */ []));
|
|
178
|
+
/** Alt bilgi şeridi: ↑↓ / ↵ / Esc ipuçları (dialog içinde anlamlı; sayfa içi kullanımda genelde kapalı). */
|
|
179
|
+
hints = input(false, { ...(ngDevMode ? { debugName: "hints" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
180
|
+
/** Açılışta input'a odaklan — dialog zaten ilk odaklanabilir öğeye odaklanır, sayfa içinde istenirse. */
|
|
181
|
+
autofocus = input(false, { ...(ngDevMode ? { debugName: "autofocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
182
|
+
run = output();
|
|
183
|
+
labels = inject(MF_COMMAND_LABELS);
|
|
184
|
+
locale = inject(MF_DATE_LOCALE);
|
|
185
|
+
host = inject(ElementRef);
|
|
186
|
+
inputRef = viewChild.required('input', /* @ts-ignore */
|
|
187
|
+
...(ngDevMode ? [{ debugName: "inputRef" }] : /* istanbul ignore next */ []));
|
|
188
|
+
idPrefix = `mf-command-${++commandIdSeq}`;
|
|
189
|
+
listboxId = `${this.idPrefix}-listbox`;
|
|
190
|
+
effectivePlaceholder = computed(() => this.placeholder() ?? this.labels().placeholder, /* @ts-ignore */
|
|
191
|
+
...(ngDevMode ? [{ debugName: "effectivePlaceholder" }] : /* istanbul ignore next */ []));
|
|
192
|
+
effectiveAriaLabel = computed(() => this.ariaLabel() ?? this.labels().ariaLabel, /* @ts-ignore */
|
|
193
|
+
...(ngDevMode ? [{ debugName: "effectiveAriaLabel" }] : /* istanbul ignore next */ []));
|
|
194
|
+
results = computed(() => filterCommands(this.items(), this.query(), {
|
|
195
|
+
limit: this.query().trim() ? this.limit() : Infinity,
|
|
196
|
+
locale: this.locale().code,
|
|
197
|
+
}), /* @ts-ignore */
|
|
198
|
+
...(ngDevMode ? [{ debugName: "results" }] : /* istanbul ignore next */ []));
|
|
199
|
+
groups = computed(() => groupCommands(this.results()), /* @ts-ignore */
|
|
200
|
+
...(ngDevMode ? [{ debugName: "groups" }] : /* istanbul ignore next */ []));
|
|
201
|
+
/** Görüntülenme sırasıyla düz liste — klavye gezinmesi bunun üzerinde yürür. */
|
|
202
|
+
flat = computed(() => this.groups().flatMap((group) => group.results), /* @ts-ignore */
|
|
203
|
+
...(ngDevMode ? [{ debugName: "flat" }] : /* istanbul ignore next */ []));
|
|
204
|
+
/** Sonuç kümesi her değiştiğinde ilk etkin satıra sıfırlanır; kullanıcı gezinince elle güncellenir. */
|
|
205
|
+
activeId = linkedSignal(() => this.flat().find((result) => !result.item.disabled)?.item.id ?? null, /* @ts-ignore */
|
|
206
|
+
...(ngDevMode ? [{ debugName: "activeId" }] : /* istanbul ignore next */ []));
|
|
207
|
+
activeDomId = computed(() => {
|
|
208
|
+
const id = this.activeId();
|
|
209
|
+
return id === null ? null : this.optionId(id);
|
|
210
|
+
}, /* @ts-ignore */
|
|
211
|
+
...(ngDevMode ? [{ debugName: "activeDomId" }] : /* istanbul ignore next */ []));
|
|
212
|
+
liveText = computed(() => {
|
|
213
|
+
if (!this.query().trim())
|
|
214
|
+
return '';
|
|
215
|
+
const count = this.results().length;
|
|
216
|
+
return count ? `${count} ${this.labels().resultsCount}` : this.labels().empty;
|
|
217
|
+
}, /* @ts-ignore */
|
|
218
|
+
...(ngDevMode ? [{ debugName: "liveText" }] : /* istanbul ignore next */ []));
|
|
219
|
+
constructor() {
|
|
220
|
+
afterRenderEffect(() => {
|
|
221
|
+
const domId = this.activeDomId();
|
|
222
|
+
if (!domId)
|
|
223
|
+
return;
|
|
224
|
+
const option = this.host.nativeElement.querySelector(`#${domId}`);
|
|
225
|
+
option?.scrollIntoView?.({ block: 'nearest' });
|
|
226
|
+
});
|
|
227
|
+
afterRenderEffect({
|
|
228
|
+
write: () => {
|
|
229
|
+
if (this.autofocus())
|
|
230
|
+
this.inputRef().nativeElement.focus();
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
/** DOM kimliği sıra numarasından türer — `item.id` boşluk/`/` içerebilir, geçerli bir `id` olmayabilir. */
|
|
235
|
+
indexById = computed(() => new Map(this.flat().map((result, index) => [result.item.id, index])), /* @ts-ignore */
|
|
236
|
+
...(ngDevMode ? [{ debugName: "indexById" }] : /* istanbul ignore next */ []));
|
|
237
|
+
optionId(itemId) {
|
|
238
|
+
return `${this.idPrefix}-option-${this.indexById().get(itemId) ?? -1}`;
|
|
239
|
+
}
|
|
240
|
+
groupId(index) {
|
|
241
|
+
return `${this.idPrefix}-group-${index}`;
|
|
242
|
+
}
|
|
243
|
+
onInput(value) {
|
|
244
|
+
this.query.set(value);
|
|
245
|
+
}
|
|
246
|
+
onKeydown(event) {
|
|
247
|
+
switch (event.key) {
|
|
248
|
+
case 'ArrowDown':
|
|
249
|
+
event.preventDefault();
|
|
250
|
+
this.move(1);
|
|
251
|
+
break;
|
|
252
|
+
case 'ArrowUp':
|
|
253
|
+
event.preventDefault();
|
|
254
|
+
this.move(-1);
|
|
255
|
+
break;
|
|
256
|
+
case 'Home':
|
|
257
|
+
case 'End':
|
|
258
|
+
// Ctrl ile — düz Home/End input içindeki imleci taşımaya devam etsin.
|
|
259
|
+
if (!event.ctrlKey && !event.metaKey)
|
|
260
|
+
return;
|
|
261
|
+
event.preventDefault();
|
|
262
|
+
this.edge(event.key === 'Home' ? 'first' : 'last');
|
|
263
|
+
break;
|
|
264
|
+
case 'Enter': {
|
|
265
|
+
if (event.isComposing)
|
|
266
|
+
return;
|
|
267
|
+
event.preventDefault();
|
|
268
|
+
const active = this.flat().find((result) => result.item.id === this.activeId());
|
|
269
|
+
if (active)
|
|
270
|
+
this.select(active);
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
case 'Escape':
|
|
274
|
+
if (!this.query())
|
|
275
|
+
return;
|
|
276
|
+
event.preventDefault();
|
|
277
|
+
event.stopPropagation();
|
|
278
|
+
this.query.set('');
|
|
279
|
+
break;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
setActive(result) {
|
|
283
|
+
if (!result.item.disabled)
|
|
284
|
+
this.activeId.set(result.item.id);
|
|
285
|
+
}
|
|
286
|
+
select(result) {
|
|
287
|
+
if (result.item.disabled)
|
|
288
|
+
return;
|
|
289
|
+
this.run.emit(result.item);
|
|
290
|
+
}
|
|
291
|
+
/** Programatik odak — ör. sayfa içi kullanımda bir kısayolla aramaya atlamak için. */
|
|
292
|
+
focus() {
|
|
293
|
+
this.inputRef().nativeElement.focus();
|
|
294
|
+
}
|
|
295
|
+
enabled() {
|
|
296
|
+
return this.flat().filter((result) => !result.item.disabled);
|
|
297
|
+
}
|
|
298
|
+
move(delta) {
|
|
299
|
+
const enabled = this.enabled();
|
|
300
|
+
if (enabled.length === 0)
|
|
301
|
+
return;
|
|
302
|
+
const current = enabled.findIndex((result) => result.item.id === this.activeId());
|
|
303
|
+
const next = (current + delta + enabled.length) % enabled.length;
|
|
304
|
+
this.activeId.set(enabled[current === -1 ? 0 : next].item.id);
|
|
305
|
+
}
|
|
306
|
+
edge(which) {
|
|
307
|
+
const enabled = this.enabled();
|
|
308
|
+
const target = which === 'first' ? enabled[0] : enabled.at(-1);
|
|
309
|
+
if (target)
|
|
310
|
+
this.activeId.set(target.item.id);
|
|
311
|
+
}
|
|
312
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Command, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
313
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.6", type: Command, isStandalone: true, selector: "mf-command", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: true, transformFunction: null }, query: { classPropertyName: "query", publicName: "query", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, limit: { classPropertyName: "limit", publicName: "limit", isSignal: true, isRequired: false, transformFunction: null }, hints: { classPropertyName: "hints", publicName: "hints", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { query: "queryChange", run: "run" }, host: { classAttribute: "flex min-h-0 flex-col" }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, isSignal: true }], exportAs: ["mfCommand"], ngImport: i0, template: "<div class=\"flex shrink-0 items-center gap-2.5 border-b border-hairline px-4\">\r\n <span mfIcon [size]=\"18\" class=\"shrink-0 text-fg-subtle\">search</span>\r\n <input\r\n #input\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n autocapitalize=\"off\"\r\n spellcheck=\"false\"\r\n aria-autocomplete=\"list\"\r\n [attr.aria-expanded]=\"groups().length > 0\"\r\n [attr.aria-controls]=\"groups().length > 0 ? listboxId : null\"\r\n [attr.aria-activedescendant]=\"activeDomId()\"\r\n [attr.aria-label]=\"effectiveAriaLabel()\"\r\n [placeholder]=\"effectivePlaceholder()\"\r\n [value]=\"query()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (keydown)=\"onKeydown($event)\"\r\n class=\"h-12 w-full min-w-0 appearance-none border-0 bg-transparent text-sm text-fg outline-none placeholder:text-fg-subtle\"\r\n />\r\n <ng-content select=\"[mfCommandInputEnd]\" />\r\n</div>\r\n\r\n@if (groups().length > 0) {\r\n <div\r\n [id]=\"listboxId\"\r\n role=\"listbox\"\r\n [attr.aria-label]=\"effectiveAriaLabel()\"\r\n class=\"max-h-[min(24rem,60dvh)] min-h-0 scroll-py-2 overflow-y-auto overscroll-contain p-2\"\r\n >\r\n @for (group of groups(); track group.label; let g = $index) {\r\n <div role=\"group\" [attr.aria-labelledby]=\"group.label ? groupId(g) : null\">\r\n @if (group.label) {\r\n <div\r\n [id]=\"groupId(g)\"\r\n aria-hidden=\"true\"\r\n class=\"px-2.5 pt-2 pb-1 font-mono text-eyebrow text-fg-subtle uppercase\"\r\n >\r\n {{ group.label }}\r\n </div>\r\n }\r\n @for (result of group.results; track result.item.id) {\r\n <!-- Klavye input'ta (aria-activedescendant) \u2014 sat\u0131r bilerek odaklanamaz, bkz. command.ts. -->\r\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\r\n <div\r\n role=\"option\"\r\n [id]=\"optionId(result.item.id)\"\r\n [attr.aria-selected]=\"result.item.id === activeId()\"\r\n [attr.aria-disabled]=\"result.item.disabled || null\"\r\n class=\"flex cursor-pointer items-center gap-3 rounded-md px-2.5 py-2 text-sm text-fg-muted transition-colors duration-fast ease-emphasis aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-selected:bg-surface-alt aria-selected:text-fg\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n (pointermove)=\"setActive(result)\"\r\n (click)=\"select(result)\"\r\n >\r\n @if (result.item.icon) {\r\n <span mfIcon [size]=\"18\" class=\"shrink-0 text-fg-subtle\">{{ result.item.icon }}</span>\r\n }\r\n <span class=\"min-w-0 flex-1 truncate\">\r\n @for (segment of result.segments; track $index) {\r\n @if (segment.match) {\r\n <mark class=\"bg-transparent font-semibold text-fg\">{{ segment.text }}</mark>\r\n } @else {\r\n <!-- \u00C7\u0131plak metin d\u00FC\u011F\u00FCm\u00FC OLMAMALI: etraf\u0131ndaki bo\u015Fluk \" \" olarak kal\u0131p kelimeyi b\u00F6ler (\"Dia log\"). -->\r\n <span>{{ segment.text }}</span>\r\n }\r\n }\r\n @if (result.item.hint) {\r\n <span class=\"ms-2 text-xs text-fg-subtle\">{{ result.item.hint }}</span>\r\n }\r\n </span>\r\n @if (result.item.shortcut?.length) {\r\n <span class=\"flex shrink-0 items-center gap-0.5\" aria-hidden=\"true\">\r\n @for (key of result.item.shortcut; track $index) {\r\n <kbd mfKbd>{{ key }}</kbd>\r\n }\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n} @else if (query().trim()) {\r\n <p class=\"px-4 py-10 text-center text-sm text-fg-subtle\">{{ labels().empty }}</p>\r\n}\r\n\r\n<div class=\"sr-only\" aria-live=\"polite\">{{ liveText() }}</div>\r\n\r\n@if (hints()) {\r\n <div\r\n class=\"flex shrink-0 items-center gap-4 border-t border-hairline px-4 py-2 text-xs text-fg-subtle\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"flex items-center gap-1\">\r\n <kbd mfKbd>\u2191</kbd><kbd mfKbd>\u2193</kbd> {{ labels().navigate }}\r\n </span>\r\n <span class=\"flex items-center gap-1\"><kbd mfKbd>\u21B5</kbd> {{ labels().select }}</span>\r\n <span class=\"flex items-center gap-1\"><kbd mfKbd>Esc</kbd> {{ labels().close }}</span>\r\n </div>\r\n}\r\n", dependencies: [{ kind: "directive", type: Icon, selector: "span[mfIcon]", inputs: ["size", "filled"] }, { kind: "directive", type: Kbd, selector: "kbd[mfKbd]" }] });
|
|
314
|
+
}
|
|
315
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: Command, decorators: [{
|
|
316
|
+
type: Component,
|
|
317
|
+
args: [{ selector: 'mf-command', exportAs: 'mfCommand', imports: [Icon, Kbd], host: { class: 'flex min-h-0 flex-col' }, template: "<div class=\"flex shrink-0 items-center gap-2.5 border-b border-hairline px-4\">\r\n <span mfIcon [size]=\"18\" class=\"shrink-0 text-fg-subtle\">search</span>\r\n <input\r\n #input\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n autocapitalize=\"off\"\r\n spellcheck=\"false\"\r\n aria-autocomplete=\"list\"\r\n [attr.aria-expanded]=\"groups().length > 0\"\r\n [attr.aria-controls]=\"groups().length > 0 ? listboxId : null\"\r\n [attr.aria-activedescendant]=\"activeDomId()\"\r\n [attr.aria-label]=\"effectiveAriaLabel()\"\r\n [placeholder]=\"effectivePlaceholder()\"\r\n [value]=\"query()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (keydown)=\"onKeydown($event)\"\r\n class=\"h-12 w-full min-w-0 appearance-none border-0 bg-transparent text-sm text-fg outline-none placeholder:text-fg-subtle\"\r\n />\r\n <ng-content select=\"[mfCommandInputEnd]\" />\r\n</div>\r\n\r\n@if (groups().length > 0) {\r\n <div\r\n [id]=\"listboxId\"\r\n role=\"listbox\"\r\n [attr.aria-label]=\"effectiveAriaLabel()\"\r\n class=\"max-h-[min(24rem,60dvh)] min-h-0 scroll-py-2 overflow-y-auto overscroll-contain p-2\"\r\n >\r\n @for (group of groups(); track group.label; let g = $index) {\r\n <div role=\"group\" [attr.aria-labelledby]=\"group.label ? groupId(g) : null\">\r\n @if (group.label) {\r\n <div\r\n [id]=\"groupId(g)\"\r\n aria-hidden=\"true\"\r\n class=\"px-2.5 pt-2 pb-1 font-mono text-eyebrow text-fg-subtle uppercase\"\r\n >\r\n {{ group.label }}\r\n </div>\r\n }\r\n @for (result of group.results; track result.item.id) {\r\n <!-- Klavye input'ta (aria-activedescendant) \u2014 sat\u0131r bilerek odaklanamaz, bkz. command.ts. -->\r\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\r\n <div\r\n role=\"option\"\r\n [id]=\"optionId(result.item.id)\"\r\n [attr.aria-selected]=\"result.item.id === activeId()\"\r\n [attr.aria-disabled]=\"result.item.disabled || null\"\r\n class=\"flex cursor-pointer items-center gap-3 rounded-md px-2.5 py-2 text-sm text-fg-muted transition-colors duration-fast ease-emphasis aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-selected:bg-surface-alt aria-selected:text-fg\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n (pointermove)=\"setActive(result)\"\r\n (click)=\"select(result)\"\r\n >\r\n @if (result.item.icon) {\r\n <span mfIcon [size]=\"18\" class=\"shrink-0 text-fg-subtle\">{{ result.item.icon }}</span>\r\n }\r\n <span class=\"min-w-0 flex-1 truncate\">\r\n @for (segment of result.segments; track $index) {\r\n @if (segment.match) {\r\n <mark class=\"bg-transparent font-semibold text-fg\">{{ segment.text }}</mark>\r\n } @else {\r\n <!-- \u00C7\u0131plak metin d\u00FC\u011F\u00FCm\u00FC OLMAMALI: etraf\u0131ndaki bo\u015Fluk \" \" olarak kal\u0131p kelimeyi b\u00F6ler (\"Dia log\"). -->\r\n <span>{{ segment.text }}</span>\r\n }\r\n }\r\n @if (result.item.hint) {\r\n <span class=\"ms-2 text-xs text-fg-subtle\">{{ result.item.hint }}</span>\r\n }\r\n </span>\r\n @if (result.item.shortcut?.length) {\r\n <span class=\"flex shrink-0 items-center gap-0.5\" aria-hidden=\"true\">\r\n @for (key of result.item.shortcut; track $index) {\r\n <kbd mfKbd>{{ key }}</kbd>\r\n }\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n} @else if (query().trim()) {\r\n <p class=\"px-4 py-10 text-center text-sm text-fg-subtle\">{{ labels().empty }}</p>\r\n}\r\n\r\n<div class=\"sr-only\" aria-live=\"polite\">{{ liveText() }}</div>\r\n\r\n@if (hints()) {\r\n <div\r\n class=\"flex shrink-0 items-center gap-4 border-t border-hairline px-4 py-2 text-xs text-fg-subtle\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"flex items-center gap-1\">\r\n <kbd mfKbd>\u2191</kbd><kbd mfKbd>\u2193</kbd> {{ labels().navigate }}\r\n </span>\r\n <span class=\"flex items-center gap-1\"><kbd mfKbd>\u21B5</kbd> {{ labels().select }}</span>\r\n <span class=\"flex items-center gap-1\"><kbd mfKbd>Esc</kbd> {{ labels().close }}</span>\r\n </div>\r\n}\r\n" }]
|
|
318
|
+
}], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], query: [{ type: i0.Input, args: [{ isSignal: true, alias: "query", required: false }] }, { type: i0.Output, args: ["queryChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], limit: [{ type: i0.Input, args: [{ isSignal: true, alias: "limit", required: false }] }], hints: [{ type: i0.Input, args: [{ isSignal: true, alias: "hints", required: false }] }], autofocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autofocus", required: false }] }], run: [{ type: i0.Output, args: ["run"] }], inputRef: [{ type: i0.ViewChild, args: ['input', { isSignal: true }] }] } });
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* `CommandPaletteService.open()`'ın dialog içeriği — `<mf-dialog>` KULLANMAZ: Dialog'un her zaman
|
|
322
|
+
* çizdiği başlık/kapat şeridi bir komut paletine uymuyor; yüzey `overlaySurface` reçetesinin cam
|
|
323
|
+
* olmayan, daha yüksek gölgeli hâli (palet içeriğin ÜSTÜNDE yüzen tek odak — Linear/Raycast).
|
|
324
|
+
* Dialog kabı kendi `aria-label`'ını servisten alır; odak/Esc/backdrop CDK'dan gelir.
|
|
325
|
+
*/
|
|
326
|
+
class CommandPalette {
|
|
327
|
+
data = inject(DIALOG_DATA);
|
|
328
|
+
ref = inject(DialogRef);
|
|
329
|
+
/** `DialogService` çıkış animasyonu turu — `Dialog`'un aynı reaktif sınıfı (bkz. dialog.service.ts). */
|
|
330
|
+
surface = inject(DialogSurface, { optional: true });
|
|
331
|
+
closing = computed(() => this.surface?.closing() ?? false, /* @ts-ignore */
|
|
332
|
+
...(ngDevMode ? [{ debugName: "closing" }] : /* istanbul ignore next */ []));
|
|
333
|
+
sheet = computed(() => this.surface?.sheet() ?? false, /* @ts-ignore */
|
|
334
|
+
...(ngDevMode ? [{ debugName: "sheet" }] : /* istanbul ignore next */ []));
|
|
335
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: CommandPalette, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
336
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.6", type: CommandPalette, isStandalone: true, selector: "mf-command-palette", host: { properties: { "class.animate-dialog-in": "!closing()", "class.animate-dialog-out": "closing()", "class.rounded-b-none": "sheet()", "class.border-b-0": "sheet()" }, classAttribute: "flex max-h-[min(34rem,80dvh)] w-[min(40rem,calc(100vw-2rem))] flex-col overflow-hidden rounded-xl border border-hairline bg-overlay shadow-3" }, ngImport: i0, template: `
|
|
337
|
+
<mf-command
|
|
338
|
+
class="min-h-0 flex-1"
|
|
339
|
+
hints
|
|
340
|
+
[items]="data.items"
|
|
341
|
+
[placeholder]="data.placeholder"
|
|
342
|
+
[limit]="data.limit ?? 50"
|
|
343
|
+
[query]="data.query ?? ''"
|
|
344
|
+
(run)="ref.close($event)"
|
|
345
|
+
/>
|
|
346
|
+
`, isInline: true, dependencies: [{ kind: "component", type: Command, selector: "mf-command", inputs: ["items", "query", "placeholder", "ariaLabel", "limit", "hints", "autofocus"], outputs: ["queryChange", "run"], exportAs: ["mfCommand"] }] });
|
|
347
|
+
}
|
|
348
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: CommandPalette, decorators: [{
|
|
349
|
+
type: Component,
|
|
350
|
+
args: [{
|
|
351
|
+
selector: 'mf-command-palette',
|
|
352
|
+
imports: [Command],
|
|
353
|
+
host: {
|
|
354
|
+
class: 'flex max-h-[min(34rem,80dvh)] w-[min(40rem,calc(100vw-2rem))] flex-col overflow-hidden rounded-xl border border-hairline bg-overlay shadow-3',
|
|
355
|
+
'[class.animate-dialog-in]': '!closing()',
|
|
356
|
+
'[class.animate-dialog-out]': 'closing()',
|
|
357
|
+
// Mobil sheet (`DialogService` 640px altında alta yaslar) — alt kenar ekrana oturur.
|
|
358
|
+
'[class.rounded-b-none]': 'sheet()',
|
|
359
|
+
'[class.border-b-0]': 'sheet()',
|
|
360
|
+
},
|
|
361
|
+
template: `
|
|
362
|
+
<mf-command
|
|
363
|
+
class="min-h-0 flex-1"
|
|
364
|
+
hints
|
|
365
|
+
[items]="data.items"
|
|
366
|
+
[placeholder]="data.placeholder"
|
|
367
|
+
[limit]="data.limit ?? 50"
|
|
368
|
+
[query]="data.query ?? ''"
|
|
369
|
+
(run)="ref.close($event)"
|
|
370
|
+
/>
|
|
371
|
+
`,
|
|
372
|
+
}]
|
|
373
|
+
}] });
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* ⌘K paletinin tek açılış noktası — `DialogService` üzerine ince katman (odak tuzağı, Esc,
|
|
377
|
+
* backdrop, odak iadesi, çıkış animasyonu, mobil sheet HEPSİ oradan):
|
|
378
|
+
*
|
|
379
|
+
* ```ts
|
|
380
|
+
* const item = await palette.open(commands);
|
|
381
|
+
* if (item) void router.navigateByUrl(item.data.url);
|
|
382
|
+
* ```
|
|
383
|
+
*
|
|
384
|
+
* Aynı anda tek palet: açıkken yeniden `open()` yeni bir dialog yığmaz, açık olanın sonucunu
|
|
385
|
+
* bekleyen aynı `Promise`'i döner (kısayola iki kez basmak iki palet açmasın).
|
|
386
|
+
*/
|
|
387
|
+
class CommandPaletteService {
|
|
388
|
+
dialog = inject(DialogService);
|
|
389
|
+
labels = inject(MF_COMMAND_LABELS);
|
|
390
|
+
active = null;
|
|
391
|
+
get isOpen() {
|
|
392
|
+
return this.active !== null;
|
|
393
|
+
}
|
|
394
|
+
open(items, options = {}) {
|
|
395
|
+
if (this.active)
|
|
396
|
+
return this.active.result;
|
|
397
|
+
const ref = this.dialog.open(CommandPalette, {
|
|
398
|
+
data: { ...options, items },
|
|
399
|
+
size: 'sm',
|
|
400
|
+
ariaLabel: this.labels().ariaLabel,
|
|
401
|
+
});
|
|
402
|
+
const result = new Promise((resolve) => ref.closed.subscribe((item) => {
|
|
403
|
+
this.active = null;
|
|
404
|
+
resolve(item);
|
|
405
|
+
}));
|
|
406
|
+
this.active = {
|
|
407
|
+
ref: ref,
|
|
408
|
+
result: result,
|
|
409
|
+
};
|
|
410
|
+
return result;
|
|
411
|
+
}
|
|
412
|
+
close() {
|
|
413
|
+
this.active?.ref.close();
|
|
414
|
+
}
|
|
415
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: CommandPaletteService, deps: [], target: i0.ɵɵFactoryTarget.Service });
|
|
416
|
+
static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.1.6", ngImport: i0, type: CommandPaletteService });
|
|
417
|
+
}
|
|
418
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: CommandPaletteService, decorators: [{
|
|
419
|
+
type: Service
|
|
420
|
+
}] });
|
|
421
|
+
|
|
422
|
+
/** `Ctrl/⌘ + <hotkey>` mi? Düzenlenebilir bir metin alanındayken (`contenteditable`) kısayol yutulmaz. */
|
|
423
|
+
function isCommandHotkey(event, hotkey = 'k') {
|
|
424
|
+
if (event.key.toLowerCase() !== hotkey.toLowerCase())
|
|
425
|
+
return false;
|
|
426
|
+
if (!(event.ctrlKey || event.metaKey) || event.altKey || event.shiftKey)
|
|
427
|
+
return false;
|
|
428
|
+
const target = event.target;
|
|
429
|
+
return !target?.closest?.('[contenteditable]:not([contenteditable="false"])');
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* `<button mfButton [mfCommandPaletteTrigger]="commands" (commandRun)="go($event)">Ara</button>`
|
|
433
|
+
*
|
|
434
|
+
* Tıklamada VE global `Ctrl/⌘+K` kısayolunda paleti açar; seçilen öğeyi `commandRun` ile verir.
|
|
435
|
+
* `aria-keyshortcuts` kısayolu yardımcı teknolojiye duyurur. Kısayol dinleyicisi belgeye bağlı —
|
|
436
|
+
* sayfada TEK tetikleyici `hotkey` taşımalı (diğerleri `[hotkeyDisabled]="true"`).
|
|
437
|
+
*/
|
|
438
|
+
class CommandPaletteTrigger {
|
|
439
|
+
items = input.required({ ...(ngDevMode ? { debugName: "items" } : /* istanbul ignore next */ {}), alias: 'mfCommandPaletteTrigger' });
|
|
440
|
+
placeholder = input(/* @ts-ignore */
|
|
441
|
+
...(ngDevMode ? [undefined, { debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
442
|
+
hotkey = input('k', /* @ts-ignore */
|
|
443
|
+
...(ngDevMode ? [{ debugName: "hotkey" }] : /* istanbul ignore next */ []));
|
|
444
|
+
hotkeyDisabled = input(false, { ...(ngDevMode ? { debugName: "hotkeyDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
445
|
+
commandRun = output();
|
|
446
|
+
palette = inject(CommandPaletteService);
|
|
447
|
+
keyshortcuts = computed(() => {
|
|
448
|
+
if (this.hotkeyDisabled())
|
|
449
|
+
return null;
|
|
450
|
+
const key = this.hotkey().toUpperCase();
|
|
451
|
+
return `Control+${key} Meta+${key}`;
|
|
452
|
+
}, /* @ts-ignore */
|
|
453
|
+
...(ngDevMode ? [{ debugName: "keyshortcuts" }] : /* istanbul ignore next */ []));
|
|
454
|
+
onDocumentKeydown(event) {
|
|
455
|
+
if (this.hotkeyDisabled() || !isCommandHotkey(event, this.hotkey()))
|
|
456
|
+
return;
|
|
457
|
+
event.preventDefault();
|
|
458
|
+
// Açıkken tekrar basmak paleti kapatır (Linear/Raycast'ın aç-kapa davranışı).
|
|
459
|
+
if (this.palette.isOpen)
|
|
460
|
+
this.palette.close();
|
|
461
|
+
else
|
|
462
|
+
void this.open();
|
|
463
|
+
}
|
|
464
|
+
async open() {
|
|
465
|
+
const item = await this.palette.open(this.items(), { placeholder: this.placeholder() });
|
|
466
|
+
if (item)
|
|
467
|
+
this.commandRun.emit(item);
|
|
468
|
+
}
|
|
469
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: CommandPaletteTrigger, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
470
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.6", type: CommandPaletteTrigger, isStandalone: true, selector: "[mfCommandPaletteTrigger]", inputs: { items: { classPropertyName: "items", publicName: "mfCommandPaletteTrigger", isSignal: true, isRequired: true, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hotkey: { classPropertyName: "hotkey", publicName: "hotkey", isSignal: true, isRequired: false, transformFunction: null }, hotkeyDisabled: { classPropertyName: "hotkeyDisabled", publicName: "hotkeyDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { commandRun: "commandRun" }, host: { attributes: { "aria-haspopup": "dialog" }, listeners: { "click": "open()", "document:keydown": "onDocumentKeydown($event)" }, properties: { "attr.aria-keyshortcuts": "keyshortcuts()" } }, exportAs: ["mfCommandPaletteTrigger"], ngImport: i0 });
|
|
471
|
+
}
|
|
472
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.6", ngImport: i0, type: CommandPaletteTrigger, decorators: [{
|
|
473
|
+
type: Directive,
|
|
474
|
+
args: [{
|
|
475
|
+
selector: '[mfCommandPaletteTrigger]',
|
|
476
|
+
exportAs: 'mfCommandPaletteTrigger',
|
|
477
|
+
host: {
|
|
478
|
+
'aria-haspopup': 'dialog',
|
|
479
|
+
'[attr.aria-keyshortcuts]': 'keyshortcuts()',
|
|
480
|
+
'(click)': 'open()',
|
|
481
|
+
'(document:keydown)': 'onDocumentKeydown($event)',
|
|
482
|
+
},
|
|
483
|
+
}]
|
|
484
|
+
}], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "mfCommandPaletteTrigger", required: true }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hotkey: [{ type: i0.Input, args: [{ isSignal: true, alias: "hotkey", required: false }] }], hotkeyDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "hotkeyDisabled", required: false }] }], commandRun: [{ type: i0.Output, args: ["commandRun"] }] } });
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Generated bundle index. Do not edit.
|
|
488
|
+
*/
|
|
489
|
+
|
|
490
|
+
export { Command, CommandPalette, CommandPaletteService, CommandPaletteTrigger, filterCommands, foldText, groupCommands, isCommandHotkey, scoreCommand };
|
|
491
|
+
//# sourceMappingURL=mesgflow-ui-kit-command.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mesgflow-ui-kit-command.mjs","sources":["../../../projects/ui-kit/command/command-search.ts","../../../projects/ui-kit/command/command.ts","../../../projects/ui-kit/command/command.html","../../../projects/ui-kit/command/command-palette.ts","../../../projects/ui-kit/command/command-palette.service.ts","../../../projects/ui-kit/command/command-palette-trigger.ts","../../../projects/ui-kit/command/mesgflow-ui-kit-command.ts"],"sourcesContent":["/** `mf-command`'ın tek öğesi — `data` tüketicinin kendi yükü (rota, eylem kimliği vb.). */\r\nexport interface MfCommandItem<T = unknown> {\r\n /** Benzersiz — `@for` track anahtarı ve DOM kimliği buradan türer. */\r\n id: string;\r\n label: string;\r\n /** Aynı `group`'taki öğeler başlık altında toplanır; grup sırası = ilk görünme sırası. */\r\n group?: string;\r\n icon?: string;\r\n /** Etiketin yanında sönük ikincil metin (ör. yol, açıklama). Aranır ama vurgulanmaz. */\r\n hint?: string;\r\n /** Etikette geçmeyen eş anlamlılar (\"theme\" → \"Görünüm\"). */\r\n keywords?: readonly string[];\r\n /** Görsel kısayol yongaları (`['Ctrl', 'S']`) — kısayolu DİNLEMEZ, yalnızca gösterir. */\r\n shortcut?: readonly string[];\r\n disabled?: boolean;\r\n data?: T;\r\n}\r\n\r\n/** Etiketin görüntülenen parçaları — `match: true` olanlar vurgulanır. */\r\nexport interface MfCommandSegment {\r\n text: string;\r\n match: boolean;\r\n}\r\n\r\nexport interface MfCommandResult<T = unknown> {\r\n item: MfCommandItem<T>;\r\n score: number;\r\n segments: MfCommandSegment[];\r\n}\r\n\r\n/**\r\n * Tek karakteri karşılaştırma biçimine indirger — 1:1 uzunluk KORUNUR (vurgu aralıkları orijinal\r\n * etiket üzerinde doğrudan kullanılabilsin diye): küçük harf + aksan atma (\"Ö\"→\"o\", \"ç\"→\"c\") +\r\n * noktasız ı→i. Böylece \"ozel\" \"Özel\"i, \"ISIK\" \"ışık\"ı bulur — Türkçe klavyesiz yazan kullanıcı\r\n * için premium paletlerin (Linear, Raycast) beklenen davranışı.\r\n */\r\nfunction foldChar(char: string, locale: string | undefined): string {\r\n const lower = char.toLocaleLowerCase(locale);\r\n const stripped = lower.normalize('NFD').replace(/\\p{M}/gu, '');\r\n // Kod noktası bazında — `charAt` bir emoji'nin yarısını (UTF-16 vekil çifti) döndürürdü.\r\n const first = Array.from(stripped)[0] ?? Array.from(lower)[0] ?? char;\r\n return first === 'ı' ? 'i' : first;\r\n}\r\n\r\nexport function foldText(text: string, locale?: string): string {\r\n let out = '';\r\n for (const char of text) out += foldChar(char, locale);\r\n return out;\r\n}\r\n\r\nconst WORD_BOUNDARY = /[\\s\\-_/.:]/;\r\n\r\nfunction isWordStart(text: string, index: number): boolean {\r\n return index === 0 || WORD_BOUNDARY.test(text.charAt(index - 1));\r\n}\r\n\r\n/**\r\n * Alt-dizi (subsequence) eşleşmesi — her sorgu karakteri SIRAYLA bulunmalı. Kelime başına düşen\r\n * ve ardışık gelen karakterler ödüllendirilir (\"gs\" → \"**G**enel **S**ayfa\").\r\n * Eşleşme yoksa `null`.\r\n */\r\nfunction fuzzyMatch(text: string, query: string): { score: number; indices: number[] } | null {\r\n const indices: number[] = [];\r\n let score = 0;\r\n let from = 0;\r\n for (const char of query) {\r\n // Önce bir kelime başında aranır; yoksa ilk görünen konuma düşülür.\r\n let index = -1;\r\n for (let i = from; i < text.length; i++) {\r\n if (text.charAt(i) === char && isWordStart(text, i)) {\r\n index = i;\r\n break;\r\n }\r\n }\r\n if (index === -1) index = text.indexOf(char, from);\r\n if (index === -1) return null;\r\n const previous = indices.at(-1);\r\n if (previous !== undefined && index === previous + 1) score += 3;\r\n if (isWordStart(text, index)) score += 2;\r\n indices.push(index);\r\n from = index + 1;\r\n }\r\n return { score, indices };\r\n}\r\n\r\nfunction toSegments(label: string, indices: readonly number[]): MfCommandSegment[] {\r\n const chars = Array.from(label);\r\n const hit = new Set(indices);\r\n const segments: MfCommandSegment[] = [];\r\n chars.forEach((char, i) => {\r\n const match = hit.has(i);\r\n const last = segments.at(-1);\r\n if (last && last.match === match) last.text += char;\r\n else segments.push({ text: char, match });\r\n });\r\n return segments;\r\n}\r\n\r\nfunction range(start: number, length: number): number[] {\r\n return Array.from({ length }, (_, i) => start + i);\r\n}\r\n\r\n/**\r\n * Puan basamakları (yüksek → düşük): tam etiket 1000 · etiket başı 800 · kelime başı 600 ·\r\n * etiket içi 400 · anahtar kelime / ipucu 200–300 · bulanık alt-dizi 100+. Aynı basamakta kısa\r\n * etiket öne geçer (daha \"tam\" eşleşme). Etiketi eşleşmeyen öğenin segmentleri vurgusuzdur.\r\n */\r\nexport function scoreCommand<T>(\r\n item: MfCommandItem<T>,\r\n foldedQuery: string,\r\n locale?: string,\r\n): MfCommandResult<T> | null {\r\n const plain: MfCommandSegment[] = [{ text: item.label, match: false }];\r\n if (!foldedQuery) return { item, score: 0, segments: plain };\r\n\r\n const label = foldText(item.label, locale);\r\n const brevity = Math.max(0, 50 - label.length);\r\n const queryLength = Array.from(foldedQuery).length;\r\n const at = label.indexOf(foldedQuery);\r\n if (at !== -1) {\r\n // `foldText` 1:1 olduğu için UTF-16 indeksi yerine kod noktası indeksine çevrilir.\r\n const start = Array.from(label.slice(0, at)).length;\r\n const base = label === foldedQuery ? 1000 : at === 0 ? 800 : isWordStart(label, at) ? 600 : 400;\r\n return {\r\n item,\r\n score: base + brevity,\r\n segments: toSegments(item.label, range(start, queryLength)),\r\n };\r\n }\r\n\r\n const extras = [...(item.keywords ?? []), item.hint ?? ''].map((text) => foldText(text, locale));\r\n if (extras.some((text) => text.startsWith(foldedQuery)))\r\n return { item, score: 300, segments: plain };\r\n if (extras.some((text) => text.includes(foldedQuery)))\r\n return { item, score: 200, segments: plain };\r\n\r\n const fuzzy = fuzzyMatch(label, foldedQuery);\r\n if (!fuzzy) return null;\r\n const chars = Array.from(label);\r\n const indices = fuzzy.indices.map((i) => Array.from(label.slice(0, i)).length);\r\n return {\r\n item,\r\n score: 100 + fuzzy.score + Math.max(0, 50 - chars.length) / 10,\r\n segments: toSegments(item.label, indices),\r\n };\r\n}\r\n\r\n/**\r\n * Boş sorguda öğeler verildiği sırada döner; doluyken puana göre (eşitlikte verilen sıra —\r\n * `Array.prototype.sort` kararlı) sıralanır ve ilk `limit` tutulur.\r\n */\r\nexport function filterCommands<T>(\r\n items: readonly MfCommandItem<T>[],\r\n query: string,\r\n options: { limit?: number; locale?: string } = {},\r\n): MfCommandResult<T>[] {\r\n const { limit = Infinity, locale } = options;\r\n const folded = foldText(query.trim(), locale);\r\n const results: MfCommandResult<T>[] = [];\r\n for (const item of items) {\r\n const result = scoreCommand(item, folded, locale);\r\n if (result) results.push(result);\r\n }\r\n if (folded) results.sort((a, b) => b.score - a.score);\r\n return results.slice(0, limit);\r\n}\r\n\r\nexport interface MfCommandGroup<T = unknown> {\r\n label: string;\r\n results: MfCommandResult<T>[];\r\n}\r\n\r\n/** Sonuçları `group`'a göre toplar — grup sırası, o gruptaki EN İYİ sonucun sırasıdır. */\r\nexport function groupCommands<T>(results: readonly MfCommandResult<T>[]): MfCommandGroup<T>[] {\r\n const groups = new Map<string, MfCommandGroup<T>>();\r\n for (const result of results) {\r\n const key = result.item.group ?? '';\r\n let group = groups.get(key);\r\n if (!group) {\r\n group = { label: key, results: [] };\r\n groups.set(key, group);\r\n }\r\n group.results.push(result);\r\n }\r\n return [...groups.values()];\r\n}\r\n","import {\r\n Component,\r\n ElementRef,\r\n afterRenderEffect,\r\n booleanAttribute,\r\n computed,\r\n inject,\r\n input,\r\n linkedSignal,\r\n model,\r\n output,\r\n viewChild,\r\n} from '@angular/core';\r\nimport { MF_COMMAND_LABELS, MF_DATE_LOCALE } from '@mesgflow/ui-kit/core';\r\nimport { Icon } from '@mesgflow/ui-kit/icon';\r\nimport { Kbd } from '@mesgflow/ui-kit/kbd';\r\nimport {\r\n filterCommands,\r\n groupCommands,\r\n type MfCommandItem,\r\n type MfCommandResult,\r\n} from './command-search';\r\n\r\nlet commandIdSeq = 0;\r\n\r\n/**\r\n * `<mf-command [items]=\"commands\" (run)=\"onRun($event)\" />`\r\n *\r\n * Komut paleti gövdesi — arama kutusu + gruplu sonuç listesi. Tek başına (sayfa içi, ör. bir\r\n * ayarlar arama alanı) kullanılabilir; ⌘K deneyimi için `CommandPaletteService.open()` bunu bir\r\n * dialog içinde açar (bkz. `command-palette.service.ts`).\r\n *\r\n * ARIA 1.2 combobox deseni: odak HER ZAMAN input'ta kalır, etkin satır `aria-activedescendant`\r\n * ile duyurulur (satırlar odaklanamaz — `mousedown` engellenir, aksi halde input odağı kaybederdi).\r\n * Arama aksan/büyük-küçük harf duyarsız, alt-dizi (fuzzy) eşleşmeli ve eşleşen harfleri vurgular\r\n * (bkz. `command-search.ts`). Esc: sorgu doluysa ÖNCE sorguyu temizler (Raycast/Linear davranışı),\r\n * boşsa olayı yukarı bırakır — dialog'un kendi Esc kapanışı çalışır.\r\n */\r\n@Component({\r\n selector: 'mf-command',\r\n exportAs: 'mfCommand',\r\n imports: [Icon, Kbd],\r\n host: { class: 'flex min-h-0 flex-col' },\r\n templateUrl: './command.html',\r\n})\r\nexport class Command<T = unknown> {\r\n readonly items = input.required<readonly MfCommandItem<T>[]>();\r\n readonly query = model('');\r\n readonly placeholder = input<string>();\r\n readonly ariaLabel = input<string>();\r\n /** Dolu sorguda gösterilecek en fazla sonuç — boş sorguda tüm liste (tüketici sıralaması) gösterilir. */\r\n readonly limit = input(50);\r\n /** Alt bilgi şeridi: ↑↓ / ↵ / Esc ipuçları (dialog içinde anlamlı; sayfa içi kullanımda genelde kapalı). */\r\n readonly hints = input(false, { transform: booleanAttribute });\r\n /** Açılışta input'a odaklan — dialog zaten ilk odaklanabilir öğeye odaklanır, sayfa içinde istenirse. */\r\n readonly autofocus = input(false, { transform: booleanAttribute });\r\n\r\n readonly run = output<MfCommandItem<T>>();\r\n\r\n protected readonly labels = inject(MF_COMMAND_LABELS);\r\n private readonly locale = inject(MF_DATE_LOCALE);\r\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\r\n private readonly inputRef = viewChild.required<ElementRef<HTMLInputElement>>('input');\r\n\r\n private readonly idPrefix = `mf-command-${++commandIdSeq}`;\r\n protected readonly listboxId = `${this.idPrefix}-listbox`;\r\n\r\n protected readonly effectivePlaceholder = computed(\r\n () => this.placeholder() ?? this.labels().placeholder,\r\n );\r\n protected readonly effectiveAriaLabel = computed(\r\n () => this.ariaLabel() ?? this.labels().ariaLabel,\r\n );\r\n\r\n private readonly results = computed(() =>\r\n filterCommands(this.items(), this.query(), {\r\n limit: this.query().trim() ? this.limit() : Infinity,\r\n locale: this.locale().code,\r\n }),\r\n );\r\n protected readonly groups = computed(() => groupCommands(this.results()));\r\n /** Görüntülenme sırasıyla düz liste — klavye gezinmesi bunun üzerinde yürür. */\r\n private readonly flat = computed(() => this.groups().flatMap((group) => group.results));\r\n\r\n /** Sonuç kümesi her değiştiğinde ilk etkin satıra sıfırlanır; kullanıcı gezinince elle güncellenir. */\r\n protected readonly activeId = linkedSignal(\r\n () => this.flat().find((result) => !result.item.disabled)?.item.id ?? null,\r\n );\r\n protected readonly activeDomId = computed(() => {\r\n const id = this.activeId();\r\n return id === null ? null : this.optionId(id);\r\n });\r\n\r\n protected readonly liveText = computed(() => {\r\n if (!this.query().trim()) return '';\r\n const count = this.results().length;\r\n return count ? `${count} ${this.labels().resultsCount}` : this.labels().empty;\r\n });\r\n\r\n constructor() {\r\n afterRenderEffect(() => {\r\n const domId = this.activeDomId();\r\n if (!domId) return;\r\n const option = this.host.nativeElement.querySelector<HTMLElement>(`#${domId}`);\r\n option?.scrollIntoView?.({ block: 'nearest' });\r\n });\r\n afterRenderEffect({\r\n write: () => {\r\n if (this.autofocus()) this.inputRef().nativeElement.focus();\r\n },\r\n });\r\n }\r\n\r\n /** DOM kimliği sıra numarasından türer — `item.id` boşluk/`/` içerebilir, geçerli bir `id` olmayabilir. */\r\n private readonly indexById = computed(\r\n () => new Map(this.flat().map((result, index) => [result.item.id, index])),\r\n );\r\n\r\n protected optionId(itemId: string): string {\r\n return `${this.idPrefix}-option-${this.indexById().get(itemId) ?? -1}`;\r\n }\r\n\r\n protected groupId(index: number): string {\r\n return `${this.idPrefix}-group-${index}`;\r\n }\r\n\r\n protected onInput(value: string): void {\r\n this.query.set(value);\r\n }\r\n\r\n protected onKeydown(event: KeyboardEvent): void {\r\n switch (event.key) {\r\n case 'ArrowDown':\r\n event.preventDefault();\r\n this.move(1);\r\n break;\r\n case 'ArrowUp':\r\n event.preventDefault();\r\n this.move(-1);\r\n break;\r\n case 'Home':\r\n case 'End':\r\n // Ctrl ile — düz Home/End input içindeki imleci taşımaya devam etsin.\r\n if (!event.ctrlKey && !event.metaKey) return;\r\n event.preventDefault();\r\n this.edge(event.key === 'Home' ? 'first' : 'last');\r\n break;\r\n case 'Enter': {\r\n if (event.isComposing) return;\r\n event.preventDefault();\r\n const active = this.flat().find((result) => result.item.id === this.activeId());\r\n if (active) this.select(active);\r\n break;\r\n }\r\n case 'Escape':\r\n if (!this.query()) return;\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.query.set('');\r\n break;\r\n }\r\n }\r\n\r\n protected setActive(result: MfCommandResult<T>): void {\r\n if (!result.item.disabled) this.activeId.set(result.item.id);\r\n }\r\n\r\n protected select(result: MfCommandResult<T>): void {\r\n if (result.item.disabled) return;\r\n this.run.emit(result.item);\r\n }\r\n\r\n /** Programatik odak — ör. sayfa içi kullanımda bir kısayolla aramaya atlamak için. */\r\n focus(): void {\r\n this.inputRef().nativeElement.focus();\r\n }\r\n\r\n private enabled(): MfCommandResult<T>[] {\r\n return this.flat().filter((result) => !result.item.disabled);\r\n }\r\n\r\n private move(delta: number): void {\r\n const enabled = this.enabled();\r\n if (enabled.length === 0) return;\r\n const current = enabled.findIndex((result) => result.item.id === this.activeId());\r\n const next = (current + delta + enabled.length) % enabled.length;\r\n this.activeId.set(enabled[current === -1 ? 0 : next].item.id);\r\n }\r\n\r\n private edge(which: 'first' | 'last'): void {\r\n const enabled = this.enabled();\r\n const target = which === 'first' ? enabled[0] : enabled.at(-1);\r\n if (target) this.activeId.set(target.item.id);\r\n }\r\n}\r\n","<div class=\"flex shrink-0 items-center gap-2.5 border-b border-hairline px-4\">\r\n <span mfIcon [size]=\"18\" class=\"shrink-0 text-fg-subtle\">search</span>\r\n <input\r\n #input\r\n type=\"text\"\r\n role=\"combobox\"\r\n autocomplete=\"off\"\r\n autocapitalize=\"off\"\r\n spellcheck=\"false\"\r\n aria-autocomplete=\"list\"\r\n [attr.aria-expanded]=\"groups().length > 0\"\r\n [attr.aria-controls]=\"groups().length > 0 ? listboxId : null\"\r\n [attr.aria-activedescendant]=\"activeDomId()\"\r\n [attr.aria-label]=\"effectiveAriaLabel()\"\r\n [placeholder]=\"effectivePlaceholder()\"\r\n [value]=\"query()\"\r\n (input)=\"onInput($any($event.target).value)\"\r\n (keydown)=\"onKeydown($event)\"\r\n class=\"h-12 w-full min-w-0 appearance-none border-0 bg-transparent text-sm text-fg outline-none placeholder:text-fg-subtle\"\r\n />\r\n <ng-content select=\"[mfCommandInputEnd]\" />\r\n</div>\r\n\r\n@if (groups().length > 0) {\r\n <div\r\n [id]=\"listboxId\"\r\n role=\"listbox\"\r\n [attr.aria-label]=\"effectiveAriaLabel()\"\r\n class=\"max-h-[min(24rem,60dvh)] min-h-0 scroll-py-2 overflow-y-auto overscroll-contain p-2\"\r\n >\r\n @for (group of groups(); track group.label; let g = $index) {\r\n <div role=\"group\" [attr.aria-labelledby]=\"group.label ? groupId(g) : null\">\r\n @if (group.label) {\r\n <div\r\n [id]=\"groupId(g)\"\r\n aria-hidden=\"true\"\r\n class=\"px-2.5 pt-2 pb-1 font-mono text-eyebrow text-fg-subtle uppercase\"\r\n >\r\n {{ group.label }}\r\n </div>\r\n }\r\n @for (result of group.results; track result.item.id) {\r\n <!-- Klavye input'ta (aria-activedescendant) — satır bilerek odaklanamaz, bkz. command.ts. -->\r\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\r\n <div\r\n role=\"option\"\r\n [id]=\"optionId(result.item.id)\"\r\n [attr.aria-selected]=\"result.item.id === activeId()\"\r\n [attr.aria-disabled]=\"result.item.disabled || null\"\r\n class=\"flex cursor-pointer items-center gap-3 rounded-md px-2.5 py-2 text-sm text-fg-muted transition-colors duration-fast ease-emphasis aria-disabled:cursor-not-allowed aria-disabled:opacity-50 aria-selected:bg-surface-alt aria-selected:text-fg\"\r\n (mousedown)=\"$event.preventDefault()\"\r\n (pointermove)=\"setActive(result)\"\r\n (click)=\"select(result)\"\r\n >\r\n @if (result.item.icon) {\r\n <span mfIcon [size]=\"18\" class=\"shrink-0 text-fg-subtle\">{{ result.item.icon }}</span>\r\n }\r\n <span class=\"min-w-0 flex-1 truncate\">\r\n @for (segment of result.segments; track $index) {\r\n @if (segment.match) {\r\n <mark class=\"bg-transparent font-semibold text-fg\">{{ segment.text }}</mark>\r\n } @else {\r\n <!-- Çıplak metin düğümü OLMAMALI: etrafındaki boşluk \" \" olarak kalıp kelimeyi böler (\"Dia log\"). -->\r\n <span>{{ segment.text }}</span>\r\n }\r\n }\r\n @if (result.item.hint) {\r\n <span class=\"ms-2 text-xs text-fg-subtle\">{{ result.item.hint }}</span>\r\n }\r\n </span>\r\n @if (result.item.shortcut?.length) {\r\n <span class=\"flex shrink-0 items-center gap-0.5\" aria-hidden=\"true\">\r\n @for (key of result.item.shortcut; track $index) {\r\n <kbd mfKbd>{{ key }}</kbd>\r\n }\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n} @else if (query().trim()) {\r\n <p class=\"px-4 py-10 text-center text-sm text-fg-subtle\">{{ labels().empty }}</p>\r\n}\r\n\r\n<div class=\"sr-only\" aria-live=\"polite\">{{ liveText() }}</div>\r\n\r\n@if (hints()) {\r\n <div\r\n class=\"flex shrink-0 items-center gap-4 border-t border-hairline px-4 py-2 text-xs text-fg-subtle\"\r\n aria-hidden=\"true\"\r\n >\r\n <span class=\"flex items-center gap-1\">\r\n <kbd mfKbd>↑</kbd><kbd mfKbd>↓</kbd> {{ labels().navigate }}\r\n </span>\r\n <span class=\"flex items-center gap-1\"><kbd mfKbd>↵</kbd> {{ labels().select }}</span>\r\n <span class=\"flex items-center gap-1\"><kbd mfKbd>Esc</kbd> {{ labels().close }}</span>\r\n </div>\r\n}\r\n","import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog';\r\nimport { Component, computed, inject } from '@angular/core';\r\nimport { DialogSurface } from '@mesgflow/ui-kit/dialog';\r\nimport { Command } from './command';\r\nimport type { MfCommandItem } from './command-search';\r\n\r\nexport interface CommandPaletteData<T = unknown> {\r\n items: readonly MfCommandItem<T>[];\r\n placeholder?: string;\r\n query?: string;\r\n limit?: number;\r\n}\r\n\r\n/**\r\n * `CommandPaletteService.open()`'ın dialog içeriği — `<mf-dialog>` KULLANMAZ: Dialog'un her zaman\r\n * çizdiği başlık/kapat şeridi bir komut paletine uymuyor; yüzey `overlaySurface` reçetesinin cam\r\n * olmayan, daha yüksek gölgeli hâli (palet içeriğin ÜSTÜNDE yüzen tek odak — Linear/Raycast).\r\n * Dialog kabı kendi `aria-label`'ını servisten alır; odak/Esc/backdrop CDK'dan gelir.\r\n */\r\n@Component({\r\n selector: 'mf-command-palette',\r\n imports: [Command],\r\n host: {\r\n class:\r\n 'flex max-h-[min(34rem,80dvh)] w-[min(40rem,calc(100vw-2rem))] flex-col overflow-hidden rounded-xl border border-hairline bg-overlay shadow-3',\r\n '[class.animate-dialog-in]': '!closing()',\r\n '[class.animate-dialog-out]': 'closing()',\r\n // Mobil sheet (`DialogService` 640px altında alta yaslar) — alt kenar ekrana oturur.\r\n '[class.rounded-b-none]': 'sheet()',\r\n '[class.border-b-0]': 'sheet()',\r\n },\r\n template: `\r\n <mf-command\r\n class=\"min-h-0 flex-1\"\r\n hints\r\n [items]=\"data.items\"\r\n [placeholder]=\"data.placeholder\"\r\n [limit]=\"data.limit ?? 50\"\r\n [query]=\"data.query ?? ''\"\r\n (run)=\"ref.close($event)\"\r\n />\r\n `,\r\n})\r\nexport class CommandPalette<T = unknown> {\r\n protected readonly data = inject<CommandPaletteData<T>>(DIALOG_DATA);\r\n protected readonly ref = inject<DialogRef<MfCommandItem<T>, CommandPalette<T>>>(DialogRef);\r\n /** `DialogService` çıkış animasyonu turu — `Dialog`'un aynı reaktif sınıfı (bkz. dialog.service.ts). */\r\n private readonly surface = inject(DialogSurface, { optional: true });\r\n protected readonly closing = computed(() => this.surface?.closing() ?? false);\r\n protected readonly sheet = computed(() => this.surface?.sheet() ?? false);\r\n}\r\n","import type { DialogRef } from '@angular/cdk/dialog';\r\nimport { Service, inject } from '@angular/core';\r\nimport { MF_COMMAND_LABELS } from '@mesgflow/ui-kit/core';\r\nimport { DialogService } from '@mesgflow/ui-kit/dialog';\r\nimport { CommandPalette, type CommandPaletteData } from './command-palette';\r\nimport type { MfCommandItem } from './command-search';\r\n\r\nexport type CommandPaletteOptions = Omit<CommandPaletteData, 'items'>;\r\n\r\n/**\r\n * ⌘K paletinin tek açılış noktası — `DialogService` üzerine ince katman (odak tuzağı, Esc,\r\n * backdrop, odak iadesi, çıkış animasyonu, mobil sheet HEPSİ oradan):\r\n *\r\n * ```ts\r\n * const item = await palette.open(commands);\r\n * if (item) void router.navigateByUrl(item.data.url);\r\n * ```\r\n *\r\n * Aynı anda tek palet: açıkken yeniden `open()` yeni bir dialog yığmaz, açık olanın sonucunu\r\n * bekleyen aynı `Promise`'i döner (kısayola iki kez basmak iki palet açmasın).\r\n */\r\n@Service()\r\nexport class CommandPaletteService {\r\n private readonly dialog = inject(DialogService);\r\n private readonly labels = inject(MF_COMMAND_LABELS);\r\n private active: {\r\n ref: DialogRef<MfCommandItem, CommandPalette>;\r\n result: Promise<MfCommandItem | undefined>;\r\n } | null = null;\r\n\r\n get isOpen(): boolean {\r\n return this.active !== null;\r\n }\r\n\r\n open<T>(\r\n items: readonly MfCommandItem<T>[],\r\n options: CommandPaletteOptions = {},\r\n ): Promise<MfCommandItem<T> | undefined> {\r\n if (this.active) return this.active.result as Promise<MfCommandItem<T> | undefined>;\r\n\r\n const ref = this.dialog.open<MfCommandItem<T>, CommandPaletteData<T>, CommandPalette<T>>(\r\n CommandPalette,\r\n {\r\n data: { ...options, items },\r\n size: 'sm',\r\n ariaLabel: this.labels().ariaLabel,\r\n },\r\n );\r\n const result = new Promise<MfCommandItem<T> | undefined>((resolve) =>\r\n ref.closed.subscribe((item) => {\r\n this.active = null;\r\n resolve(item);\r\n }),\r\n );\r\n this.active = {\r\n ref: ref as unknown as DialogRef<MfCommandItem, CommandPalette>,\r\n result: result as Promise<MfCommandItem | undefined>,\r\n };\r\n return result;\r\n }\r\n\r\n close(): void {\r\n this.active?.ref.close();\r\n }\r\n}\r\n","import { Directive, booleanAttribute, computed, inject, input, output } from '@angular/core';\r\nimport { CommandPaletteService } from './command-palette.service';\r\nimport type { MfCommandItem } from './command-search';\r\n\r\n/** `Ctrl/⌘ + <hotkey>` mi? Düzenlenebilir bir metin alanındayken (`contenteditable`) kısayol yutulmaz. */\r\nexport function isCommandHotkey(event: KeyboardEvent, hotkey = 'k'): boolean {\r\n if (event.key.toLowerCase() !== hotkey.toLowerCase()) return false;\r\n if (!(event.ctrlKey || event.metaKey) || event.altKey || event.shiftKey) return false;\r\n const target = event.target as HTMLElement | null;\r\n return !target?.closest?.('[contenteditable]:not([contenteditable=\"false\"])');\r\n}\r\n\r\n/**\r\n * `<button mfButton [mfCommandPaletteTrigger]=\"commands\" (commandRun)=\"go($event)\">Ara</button>`\r\n *\r\n * Tıklamada VE global `Ctrl/⌘+K` kısayolunda paleti açar; seçilen öğeyi `commandRun` ile verir.\r\n * `aria-keyshortcuts` kısayolu yardımcı teknolojiye duyurur. Kısayol dinleyicisi belgeye bağlı —\r\n * sayfada TEK tetikleyici `hotkey` taşımalı (diğerleri `[hotkeyDisabled]=\"true\"`).\r\n */\r\n@Directive({\r\n selector: '[mfCommandPaletteTrigger]',\r\n exportAs: 'mfCommandPaletteTrigger',\r\n host: {\r\n 'aria-haspopup': 'dialog',\r\n '[attr.aria-keyshortcuts]': 'keyshortcuts()',\r\n '(click)': 'open()',\r\n '(document:keydown)': 'onDocumentKeydown($event)',\r\n },\r\n})\r\nexport class CommandPaletteTrigger<T = unknown> {\r\n readonly items = input.required<readonly MfCommandItem<T>[]>({\r\n alias: 'mfCommandPaletteTrigger',\r\n });\r\n readonly placeholder = input<string>();\r\n readonly hotkey = input('k');\r\n readonly hotkeyDisabled = input(false, { transform: booleanAttribute });\r\n\r\n readonly commandRun = output<MfCommandItem<T>>();\r\n\r\n private readonly palette = inject(CommandPaletteService);\r\n\r\n protected readonly keyshortcuts = computed(() => {\r\n if (this.hotkeyDisabled()) return null;\r\n const key = this.hotkey().toUpperCase();\r\n return `Control+${key} Meta+${key}`;\r\n });\r\n\r\n protected onDocumentKeydown(event: KeyboardEvent): void {\r\n if (this.hotkeyDisabled() || !isCommandHotkey(event, this.hotkey())) return;\r\n event.preventDefault();\r\n // Açıkken tekrar basmak paleti kapatır (Linear/Raycast'ın aç-kapa davranışı).\r\n if (this.palette.isOpen) this.palette.close();\r\n else void this.open();\r\n }\r\n\r\n async open(): Promise<void> {\r\n const item = await this.palette.open(this.items(), { placeholder: this.placeholder() });\r\n if (item) this.commandRun.emit(item);\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|