@kouji-ui/components 0.4.3 → 0.5.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/fesm2022/kouji-ui-components.mjs +2771 -265
- package/fesm2022/kouji-ui-components.mjs.map +1 -1
- package/package.json +41 -3
- package/types/kouji-ui-components.d.ts +947 -31
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { ChangeDetectionStrategy, ViewEncapsulation, Component, input,
|
|
2
|
+
import { ChangeDetectionStrategy, ViewEncapsulation, Component, input, inject, Injectable, booleanAttribute, computed, TemplateRef, model, ViewChild, contentChildren, ElementRef, PLATFORM_ID, DestroyRef, afterNextRender, effect, signal, Injector, viewChild, untracked, output, EventEmitter, Output, makeEnvironmentProviders, provideEnvironmentInitializer, forwardRef, EnvironmentInjector, Directive, InjectionToken, ViewContainerRef, contentChild, numberAttribute } from '@angular/core';
|
|
3
3
|
import * as i1 from '@kouji-ui/core';
|
|
4
|
-
import { KjAccordion, KjAccordionTrigger, KjAccordionItem, KjAccordionContent, KjAlert, KjAlertIcon, KjAlertTitle, KjAlertDescription, KjAlertActions, KjAlertDismiss,
|
|
5
|
-
export { KJ_DROPDOWN_MENU, KjBlockquote, KjCode, KjDialog, KjDialogRef, KjDialogService, KjDrawer, KjDrawerRef, KjDrawerService, KjDropdownMenuContent, KjDropdownMenuGroup, KjDropdownMenuItem, KjDropdownMenuLabel, KjDropdownMenuSeparator, KjDropdownMenuTrigger, KjLead, KjMuted, KjPopoverArrow, KjPopoverClose, KjPopoverContent, KjPopoverTitle, KjPopoverTrigger, KjTooltipArrow, KjTooltipContent, KjTooltipGroup, KjTooltipTrigger, KjTruncate } from '@kouji-ui/core';
|
|
6
|
-
import { NgTemplateOutlet, isPlatformBrowser } from '@angular/common';
|
|
4
|
+
import { KjAccordion, KjAccordionTrigger, KjAccordionItem, KjAccordionContent, SHEET_DATA, KjSheetRef, KjSheet, KjIconDirective, KjSheetService, KjAlert, KjAlertIcon, KjAlertTitle, KjAlertDescription, KjAlertActions, KjAlertDismiss, KJ_AVATAR_GROUP, KjAvatarImage, KjAvatarFallback, KjAvatar, KjAvatarGroup, KjBadge, KjBreadcrumb, KjBreadcrumbList, KjBreadcrumbItem, KjLink, KjBreadcrumbCurrent, KjBreadcrumbSeparator, KjBreadcrumbEllipsis, KjButton, KjButtonGroup, KjCalendar, KjCalendarHeader, KjCalendarGrid, KjCalendarDay, KjCarousel, KjLiveRegion, KjVisuallyHidden, KjCarouselViewport, KjCarouselSlide, KjCarouselPrevious, KjCarouselNext, KJ_CAROUSEL, KjCarouselIndicator, KjCarouselIndicators, KjCarouselAutoplay, KjCarouselPauseToggle, KjChatLog, KjChat, KjChatAvatar, KjChatHeader, KjChatBubble, KjChatFooter, KjChatAnnouncer, parseSlash, matchSlashCommands, KjCheckbox, KjColorPicker, KjColorPickerTrigger, KjColorPickerPanel, KjColorPickerArea, KjColorPickerHueSlider, KjColorPickerAlphaSlider, KjColorPickerInput, KjComboboxInput, KjComboboxListbox, KjCombobox, KjComboboxOption, KjConfirmPopup, KjConfirmPopupTrigger, KjPopoverContent, KjConfirmPopupContent, KjConfirmPopupMessage, KjConfirmPopupAction, KjConfirmPopupCancel, KjDatePicker, KjDatePickerTrigger, KjDatePickerCalendar, defaultDateRangePresets, KjDateRangePresets, KjDateRangePresetOption, KjLocale, KjDropdownMenuTrigger, KjDropdownMenuContent, KjDropdownMenuItem, KjDropdownMenuSeparator, KjDropdownMenuLabel, KjDropdownMenuGroup, KjSpinner, KjEditorLoader, KjEditor, KJ_SIZE_PRESET, KjSize, KjField, KjFieldLabel, KjFieldHelp, KjFieldError, KjFieldGroup, KjFileUpload, KjFileUploadTrigger, KjFileUploadDropzone, KjFileUploadList, KjFileUploadItem, KjProgressBar, KjProgressBarFill, KjForm, KjFormErrorSummary, KJ_ICON_REGISTRY, KjInput, KjInputGroup, KjInputGroupAddon, KjInputMask, KJ_INPUT_MASK_PRESETS, KjInputOtp, KjInputOtpCell, KjKbd, KJ_KBD_SIZE_PRESET, KjDivider, KJ_VARIANT_PRESET, KjList, KjListRow, KjMenubar, KjMenubarItem, KjNumberInput, KjNumberInputGroup, KjNumberStepper, KJ_OVERLAY_BADGE, KjOverlayBadgeContent, KjOverlayBadge, KjPagination, KjPaginationItem, KjPaginationPrevious, KjPaginationNext, KjPaginationFirst, KjPaginationLast, KjPaginationEllipsis, KjPaginationInfo, KJ_PASSWORD_INPUT, KjPasswordInput, KjPasswordInputScope, KjPasswordToggle, KjPasswordStrength, KjPasswordCapsLockWarning, KjPopoverTrigger, KjPopoverArrow, KjPopoverClose, KjPopoverTitle, KjRadioGroup, KjRadio, injectRteOverlayData, createKjImageNode, KJ_RTE_OVERLAY_DATA, KjRichTextEditor, KjRovingTabindex, KjRovingTabindexItemDirective, KjSelect, KjSelectTrigger, KjSelectContent, KjOption, KjSkeleton, KjSkipLink, KjSlider, KjSliderTrack, KjSliderRange, KjSliderThumb, KjSpeedDial, KjSpeedDialTrigger, KjSpeedDialActions, KjSpeedDialAction, KjStepper, KjStep, KjStepLabel, KjStepContent, KjStepperNext, KjStepperPrevious, KjStepperReset, KjToggle, KJ_TABLE, provideKjFilterParams, KjTable, KJ_TABLE_STORAGE, KjTableHeader, KjTableRow, KjTableCell, KjTableKeyboardNav, DRAWER_DATA, KjDrawer, KjDrawerService, KjTabs, KjTabList, KjTab, KjTabPanel, KjTag, KjTagRemove, KjTagList, KjTextarea, KjTimePicker, KjTimePickerHours, KjTimePickerMinutes, KjTimePickerSeconds, KjTimePickerMeridiem, KjToastViewport, KjToast, KjToastClose, KjTooltipTrigger, KjTooltipContent, KjTooltipArrow, KjTooltipGroup, KjCascadeSelect, KjCascadeSelectTrigger, KjCascadeSelectPanel, KjCascadeSelectOption, KjCascadeSelectSubPanel, KjCommandPalette, KjCommandInput, KjCommandList, KjCommandEmpty, injectListItem, KjListItem, KjCommandGroup, KjCommandSeparator, KjTreeSelectNode, KjTreeSelectToggle, KjTreeSelect, KjTreeSelectTrigger, KjTreeSelectContent } from '@kouji-ui/core';
|
|
5
|
+
export { KJ_DROPDOWN_MENU, KjBlockquote, KjCarousel, KjCarouselSlide, KjCascadeSelectOption, KjChatAnnouncer, KjChatStore, KjCode, KjColorPicker, KjCombobox, KjDatePicker, KjDialog, KjDialogRef, KjDialogService, KjDrawer, KjDrawerRef, KjDrawerService, KjDropdownMenuContent, KjDropdownMenuGroup, KjDropdownMenuItem, KjDropdownMenuLabel, KjDropdownMenuSeparator, KjDropdownMenuTrigger, KjFileUpload, KjInput, KjLead, KjLiveRegion, KjMuted, KjOverlayPanel, KjPopoverArrow, KjPopoverClose, KjPopoverContent, KjPopoverTitle, KjPopoverTrigger, KjRichTextEditor, KjSheet, KjSheetRef, KjSheetService, KjTabPanel, KjTable, KjTooltipArrow, KjTooltipContent, KjTooltipGroup, KjTooltipTrigger, KjTreeSelect, KjTruncate, SHEET_ARIA_LABEL, SHEET_DATA, SHEET_DETENT, SHEET_DISMISSIBLE } from '@kouji-ui/core';
|
|
6
|
+
import { NgTemplateOutlet, isPlatformBrowser, NgComponentOutlet } from '@angular/common';
|
|
7
|
+
import { DomSanitizer } from '@angular/platform-browser';
|
|
7
8
|
import * as i1$1 from '@angular/forms';
|
|
8
9
|
import { NG_VALUE_ACCESSOR, FormsModule, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
9
10
|
import * as lucideIcons from 'lucide-static';
|
|
@@ -180,6 +181,218 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
180
181
|
}]
|
|
181
182
|
}] });
|
|
182
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Render body for an action sheet. Rendered programmatically by
|
|
186
|
+
* {@link import('./action-sheet.service').KjActionSheetService} inside the
|
|
187
|
+
* bottom-sheet primitive; reads its config from `SHEET_DATA` and resolves the
|
|
188
|
+
* chosen action's `value` through the {@link KjSheetRef}.
|
|
189
|
+
*
|
|
190
|
+
* The action list is `role="menu"` with `role="menuitem"` rows; each row is a
|
|
191
|
+
* ≥ 44px touch target.
|
|
192
|
+
*
|
|
193
|
+
* @internal
|
|
194
|
+
*/
|
|
195
|
+
class KjActionSheet {
|
|
196
|
+
/** Config injected via `SHEET_DATA` by the action-sheet service. */
|
|
197
|
+
config = inject(SHEET_DATA);
|
|
198
|
+
ref = inject(KjSheetRef);
|
|
199
|
+
get cancelLabel() {
|
|
200
|
+
return this.config.cancelLabel === undefined ? 'Cancel' : this.config.cancelLabel;
|
|
201
|
+
}
|
|
202
|
+
/** Resolve the chosen action's value and close. */
|
|
203
|
+
select(action) {
|
|
204
|
+
if (action.disabled)
|
|
205
|
+
return;
|
|
206
|
+
this.ref.close(action.value);
|
|
207
|
+
}
|
|
208
|
+
/** Dismiss with `undefined`. */
|
|
209
|
+
cancel() {
|
|
210
|
+
this.ref.close(undefined);
|
|
211
|
+
}
|
|
212
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjActionSheet, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
213
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: KjActionSheet, isStandalone: true, selector: "kj-action-sheet", ngImport: i0, template: `
|
|
214
|
+
<kj-sheet class="kj-action-sheet">
|
|
215
|
+
@if (config.title) {
|
|
216
|
+
<h2 class="kj-action-sheet__title">{{ config.title }}</h2>
|
|
217
|
+
}
|
|
218
|
+
@if (config.description) {
|
|
219
|
+
<p class="kj-action-sheet__description">{{ config.description }}</p>
|
|
220
|
+
}
|
|
221
|
+
<div class="kj-action-sheet__list" role="menu" [attr.aria-label]="config.title ?? 'Actions'">
|
|
222
|
+
@for (action of config.actions; track action.value) {
|
|
223
|
+
<button
|
|
224
|
+
type="button"
|
|
225
|
+
role="menuitem"
|
|
226
|
+
class="kj-action-sheet__item"
|
|
227
|
+
[class.is-destructive]="action.role === 'destructive'"
|
|
228
|
+
[disabled]="action.disabled ? true : null"
|
|
229
|
+
(click)="select(action)"
|
|
230
|
+
>
|
|
231
|
+
@if (action.icon) {
|
|
232
|
+
<i class="kj-action-sheet__icon" [kjIcon]="action.icon" aria-hidden="true"></i>
|
|
233
|
+
}
|
|
234
|
+
<span class="kj-action-sheet__label">{{ action.label }}</span>
|
|
235
|
+
</button>
|
|
236
|
+
}
|
|
237
|
+
</div>
|
|
238
|
+
@if (cancelLabel !== null) {
|
|
239
|
+
<button
|
|
240
|
+
type="button"
|
|
241
|
+
class="kj-action-sheet__cancel"
|
|
242
|
+
(click)="cancel()"
|
|
243
|
+
>{{ cancelLabel }}</button>
|
|
244
|
+
}
|
|
245
|
+
</kj-sheet>
|
|
246
|
+
`, isInline: true, dependencies: [{ kind: "component", type: KjSheet, selector: "kj-sheet" }, { kind: "directive", type: KjIconDirective, selector: "span[kjIcon], i[kjIcon]", inputs: ["kjIcon", "kjIconLabel", "kjIconColor", "kjIconSize"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
247
|
+
}
|
|
248
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjActionSheet, decorators: [{
|
|
249
|
+
type: Component,
|
|
250
|
+
args: [{
|
|
251
|
+
selector: 'kj-action-sheet',
|
|
252
|
+
standalone: true,
|
|
253
|
+
imports: [KjSheet, KjIconDirective],
|
|
254
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
255
|
+
encapsulation: ViewEncapsulation.None,
|
|
256
|
+
template: `
|
|
257
|
+
<kj-sheet class="kj-action-sheet">
|
|
258
|
+
@if (config.title) {
|
|
259
|
+
<h2 class="kj-action-sheet__title">{{ config.title }}</h2>
|
|
260
|
+
}
|
|
261
|
+
@if (config.description) {
|
|
262
|
+
<p class="kj-action-sheet__description">{{ config.description }}</p>
|
|
263
|
+
}
|
|
264
|
+
<div class="kj-action-sheet__list" role="menu" [attr.aria-label]="config.title ?? 'Actions'">
|
|
265
|
+
@for (action of config.actions; track action.value) {
|
|
266
|
+
<button
|
|
267
|
+
type="button"
|
|
268
|
+
role="menuitem"
|
|
269
|
+
class="kj-action-sheet__item"
|
|
270
|
+
[class.is-destructive]="action.role === 'destructive'"
|
|
271
|
+
[disabled]="action.disabled ? true : null"
|
|
272
|
+
(click)="select(action)"
|
|
273
|
+
>
|
|
274
|
+
@if (action.icon) {
|
|
275
|
+
<i class="kj-action-sheet__icon" [kjIcon]="action.icon" aria-hidden="true"></i>
|
|
276
|
+
}
|
|
277
|
+
<span class="kj-action-sheet__label">{{ action.label }}</span>
|
|
278
|
+
</button>
|
|
279
|
+
}
|
|
280
|
+
</div>
|
|
281
|
+
@if (cancelLabel !== null) {
|
|
282
|
+
<button
|
|
283
|
+
type="button"
|
|
284
|
+
class="kj-action-sheet__cancel"
|
|
285
|
+
(click)="cancel()"
|
|
286
|
+
>{{ cancelLabel }}</button>
|
|
287
|
+
}
|
|
288
|
+
</kj-sheet>
|
|
289
|
+
`,
|
|
290
|
+
}]
|
|
291
|
+
}] });
|
|
292
|
+
/**
|
|
293
|
+
* Service-launched **action sheet** — a data-driven, iOS-style list of actions
|
|
294
|
+
* presented in a bottom sheet. Inject `KjActionSheetService` and call `open()`
|
|
295
|
+
* with a list of actions; selecting one resolves its `value`. Built entirely
|
|
296
|
+
* on the bottom-sheet primitive, so it inherits the same focus trap, scroll
|
|
297
|
+
* lock, drag-to-dismiss, and Escape handling. The wrapper component exists to
|
|
298
|
+
* host this documentation page.
|
|
299
|
+
*
|
|
300
|
+
* @doc
|
|
301
|
+
* @doc-name action-sheet
|
|
302
|
+
* @doc-is-main
|
|
303
|
+
* @doc-example Default
|
|
304
|
+
* A titled action sheet with a destructive action and a cancel row.
|
|
305
|
+
* @doc-file action-sheet.example.ts
|
|
306
|
+
* @doc-example With icons
|
|
307
|
+
* Actions with leading icons; the selected value resolves through the ref.
|
|
308
|
+
* @doc-file action-sheet.icons.example.ts
|
|
309
|
+
*
|
|
310
|
+
* @doc-keyboard
|
|
311
|
+
* Escape — Dismisses the sheet (resolves undefined)
|
|
312
|
+
* Tab / Shift+Tab — Cycles focus across the action rows (focus trap)
|
|
313
|
+
* Enter / Space — Activates the focused action row
|
|
314
|
+
*
|
|
315
|
+
* @doc-aria
|
|
316
|
+
* role — Panel is "dialog"; the action list is "menu" with "menuitem" rows
|
|
317
|
+
* aria-label — The sheet is named by its title (or "Actions" fallback)
|
|
318
|
+
*
|
|
319
|
+
* @doc-touch
|
|
320
|
+
* Every action row and the cancel row is a ≥ 44px touch target (WCAG 2.5.5).
|
|
321
|
+
* The bottom sheet's grab handle dismisses via drag.
|
|
322
|
+
*
|
|
323
|
+
* @doc-a11y
|
|
324
|
+
* Inherits the bottom sheet's a11y contract: focus trapped and restored to
|
|
325
|
+
* the trigger on close, siblings inert while open, only the topmost overlay
|
|
326
|
+
* receives Escape and outside-click. Destructive rows use `--kj-danger-*`
|
|
327
|
+
* tokens which meet AAA contrast in both themes.
|
|
328
|
+
*
|
|
329
|
+
* @doc-related sheet,dialog,dropdown-menu
|
|
330
|
+
*
|
|
331
|
+
* @doc-category Library/Overlay
|
|
332
|
+
*/
|
|
333
|
+
class KjActionSheetComponent {
|
|
334
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjActionSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
335
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: KjActionSheetComponent, isStandalone: true, selector: "kj-action-sheet-shell", host: { styleAttribute: "display: contents;" }, ngImport: i0, template: `<ng-content />`, isInline: true, styles: ["@layer kj.component{.kj-action-sheet__title{margin:0 0 var(--kj-space-xs);font:600 1.0625rem / 1.3 var(--kj-font-sans);color:var(--kj-fg-default);text-align:center}.kj-action-sheet__description{margin:0 0 var(--kj-space-md);font:.875rem / 1.4 var(--kj-font-sans);color:var(--kj-fg-muted);text-align:center}.kj-action-sheet__list{display:flex;flex-direction:column;gap:var(--kj-space-2xs, .25rem)}.kj-action-sheet__item,.kj-action-sheet__cancel{appearance:none;display:flex;align-items:center;gap:var(--kj-space-sm);width:100%;min-height:44px;padding:var(--kj-space-sm) var(--kj-space-md);border:0;border-radius:var(--kj-radius-md, .5rem);background:var(--kj-bg-subtle, transparent);color:var(--kj-fg-default);font:500 .9375rem / 1.4 var(--kj-font-sans);text-align:left;cursor:pointer}.kj-action-sheet__item:hover:not(:disabled),.kj-action-sheet__cancel:hover{background:var(--kj-bg-muted, var(--kj-border-muted))}.kj-action-sheet__item:focus-visible,.kj-action-sheet__cancel:focus-visible{outline:var(--kj-focus-ring-width, 2px) solid var(--kj-focus-ring-color, var(--kj-primary));outline-offset:2px}.kj-action-sheet__item:disabled{opacity:.5;cursor:not-allowed}.kj-action-sheet__item.is-destructive{color:var(--kj-danger-fg, var(--kj-danger, #d92d20))}.kj-action-sheet__item.is-destructive:hover:not(:disabled){background:var(--kj-danger-bg-subtle, color-mix(in srgb, var(--kj-danger, #d92d20) 12%, transparent))}.kj-action-sheet__icon{flex-shrink:0;width:1.25rem;height:1.25rem}.kj-action-sheet__label{flex:1}.kj-action-sheet__cancel{justify-content:center;margin-top:var(--kj-space-sm);font-weight:600;background:var(--kj-bg-muted, var(--kj-border-muted))}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
336
|
+
}
|
|
337
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjActionSheetComponent, decorators: [{
|
|
338
|
+
type: Component,
|
|
339
|
+
args: [{ selector: 'kj-action-sheet-shell', standalone: true, template: `<ng-content />`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-action-sheet__title{margin:0 0 var(--kj-space-xs);font:600 1.0625rem / 1.3 var(--kj-font-sans);color:var(--kj-fg-default);text-align:center}.kj-action-sheet__description{margin:0 0 var(--kj-space-md);font:.875rem / 1.4 var(--kj-font-sans);color:var(--kj-fg-muted);text-align:center}.kj-action-sheet__list{display:flex;flex-direction:column;gap:var(--kj-space-2xs, .25rem)}.kj-action-sheet__item,.kj-action-sheet__cancel{appearance:none;display:flex;align-items:center;gap:var(--kj-space-sm);width:100%;min-height:44px;padding:var(--kj-space-sm) var(--kj-space-md);border:0;border-radius:var(--kj-radius-md, .5rem);background:var(--kj-bg-subtle, transparent);color:var(--kj-fg-default);font:500 .9375rem / 1.4 var(--kj-font-sans);text-align:left;cursor:pointer}.kj-action-sheet__item:hover:not(:disabled),.kj-action-sheet__cancel:hover{background:var(--kj-bg-muted, var(--kj-border-muted))}.kj-action-sheet__item:focus-visible,.kj-action-sheet__cancel:focus-visible{outline:var(--kj-focus-ring-width, 2px) solid var(--kj-focus-ring-color, var(--kj-primary));outline-offset:2px}.kj-action-sheet__item:disabled{opacity:.5;cursor:not-allowed}.kj-action-sheet__item.is-destructive{color:var(--kj-danger-fg, var(--kj-danger, #d92d20))}.kj-action-sheet__item.is-destructive:hover:not(:disabled){background:var(--kj-danger-bg-subtle, color-mix(in srgb, var(--kj-danger, #d92d20) 12%, transparent))}.kj-action-sheet__icon{flex-shrink:0;width:1.25rem;height:1.25rem}.kj-action-sheet__label{flex:1}.kj-action-sheet__cancel{justify-content:center;margin-top:var(--kj-space-sm);font-weight:600;background:var(--kj-bg-muted, var(--kj-border-muted))}}\n"] }]
|
|
340
|
+
}] });
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Reference returned by {@link KjActionSheetService.open}. Resolves the chosen
|
|
344
|
+
* action's `value`, or `undefined` when dismissed (Escape / backdrop / cancel).
|
|
345
|
+
*
|
|
346
|
+
* @doc-category Library/Overlay
|
|
347
|
+
*/
|
|
348
|
+
class KjActionSheetRef {
|
|
349
|
+
sheetRef;
|
|
350
|
+
/** Emits the selected value (or `undefined`) once the sheet has closed. */
|
|
351
|
+
afterClosed$;
|
|
352
|
+
/** Promise resolving with the selected value (or `undefined`). */
|
|
353
|
+
result;
|
|
354
|
+
constructor(sheetRef) {
|
|
355
|
+
this.sheetRef = sheetRef;
|
|
356
|
+
this.afterClosed$ = sheetRef.afterClosed$;
|
|
357
|
+
this.result = sheetRef.result;
|
|
358
|
+
}
|
|
359
|
+
/** Dismiss the action sheet programmatically. */
|
|
360
|
+
close(result) {
|
|
361
|
+
this.sheetRef.close(result);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Programmatic service for opening an **action sheet** — a data-driven,
|
|
366
|
+
* iOS-style list of actions presented in a bottom sheet. Built on
|
|
367
|
+
* {@link KjSheetService}; it adds no new overlay surface, only a styled
|
|
368
|
+
* `role="menu"` action list on top of the bottom-sheet primitive.
|
|
369
|
+
*
|
|
370
|
+
* @doc-category Library/Overlay
|
|
371
|
+
*/
|
|
372
|
+
class KjActionSheetService {
|
|
373
|
+
sheet = inject(KjSheetService);
|
|
374
|
+
/**
|
|
375
|
+
* Open an action sheet.
|
|
376
|
+
*
|
|
377
|
+
* @param opts - Title, description, actions, and cancel label.
|
|
378
|
+
* @returns A {@link KjActionSheetRef} resolving the selected value.
|
|
379
|
+
*/
|
|
380
|
+
open(opts) {
|
|
381
|
+
const sheetRef = this.sheet.open(KjActionSheet, {
|
|
382
|
+
data: opts,
|
|
383
|
+
detent: 'auto',
|
|
384
|
+
ariaLabel: opts.title ?? 'Actions',
|
|
385
|
+
});
|
|
386
|
+
return new KjActionSheetRef(sheetRef);
|
|
387
|
+
}
|
|
388
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjActionSheetService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
389
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjActionSheetService, providedIn: 'root' });
|
|
390
|
+
}
|
|
391
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjActionSheetService, decorators: [{
|
|
392
|
+
type: Injectable,
|
|
393
|
+
args: [{ providedIn: 'root' }]
|
|
394
|
+
}] });
|
|
395
|
+
|
|
183
396
|
/**
|
|
184
397
|
* Styled wrapper around the `KjAlert` directive family. Provides the
|
|
185
398
|
* persistent in-flow notification surface (severity-aware chrome, severity
|
|
@@ -910,7 +1123,7 @@ class KjBreadcrumbComponent {
|
|
|
910
1123
|
kjSize = input('md', /* @ts-ignore */
|
|
911
1124
|
...(ngDevMode ? [{ debugName: "kjSize" }] : /* istanbul ignore next */ []));
|
|
912
1125
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
913
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.5", type: KjBreadcrumbComponent, isStandalone: true, selector: "nav[kj-breadcrumb], kj-breadcrumb", inputs: { kjSize: { classPropertyName: "kjSize", publicName: "kjSize", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, properties: { "attr.data-size": "kjSize()" }, classAttribute: "kj-breadcrumb" }, hostDirectives: [{ directive: i1.KjBreadcrumb, inputs: ["kjAriaLabel", "kjAriaLabel", "kjSeparator", "kjSeparator", "kjMaxItems", "kjMaxItems", "kjOverflow", "kjOverflow"] }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: ["@layer kj.component{.kj-breadcrumb{--kj-breadcrumb-gap: var(--kj-space-sm, .5rem);--kj-breadcrumb-separator-content: \"/\";--kj-breadcrumb-overflow-pad: .25rem;--kj-color-breadcrumb-muted: var(--kj-fg-muted);--kj-color-breadcrumb-current: var(--kj-fg-default);display:block;color:var(--kj-color-breadcrumb-muted);font-size:.875rem}.kj-breadcrumb[data-size=sm]{font-size:.8125rem}.kj-breadcrumb[data-size=md]{font-size:.875rem}.kj-breadcrumb[data-size=lg]{font-size:1rem}.kj-breadcrumb-list{display:flex;align-items:center;flex-wrap:nowrap;gap:var(--kj-breadcrumb-gap);margin:0;padding:0;list-style:none;min-width:0}.kj-breadcrumb-list[data-wrap=wrap]{flex-wrap:wrap}.kj-breadcrumb-list[data-wrap=no-wrap],.kj-breadcrumb-list[data-wrap=truncate]{flex-wrap:nowrap}.kj-breadcrumb-item{display:inline-flex;align-items:center;gap:var(--kj-breadcrumb-gap);min-width:0}.kj-breadcrumb-item[data-hidden]{display:none}.kj-breadcrumb-list:not([data-explicit-separators])>.kj-breadcrumb-item:not(:first-child):before{content:var(--kj-breadcrumb-separator-content, \"/\");color:var(--kj-color-breadcrumb-muted);opacity:.65;-webkit-user-select:none;user-select:none;margin-inline-end:var(--kj-breadcrumb-gap)}[dir=rtl] .kj-breadcrumb[data-mirror-separator] .kj-breadcrumb-list:not([data-explicit-separators])>.kj-breadcrumb-item:not(:first-child):before{display:inline-block;transform:scaleX(-1)}.kj-breadcrumb-separator{display:inline-flex;align-items:center;color:var(--kj-color-breadcrumb-muted);opacity:.65;-webkit-user-select:none;user-select:none}.kj-breadcrumb-link{text-decoration:none;padding-block:.5rem}.kj-breadcrumb-current{color:var(--kj-color-breadcrumb-current);font-weight:500}.kj-breadcrumb-ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:1.5rem;padding-inline:var(--kj-breadcrumb-overflow-pad);color:var(--kj-color-breadcrumb-muted);background:transparent;border:0;cursor:default;-webkit-user-select:none;user-select:none}.kj-breadcrumb-ellipsis[data-overflow=menu]{cursor:pointer;border-radius:var(--kj-radius-field, .25rem)}.kj-breadcrumb-ellipsis[data-overflow=menu]:hover{background:var(--kj-bg-surface, transparent)}@media print{.kj-breadcrumb-item[data-hidden]{display:revert}.kj-breadcrumb-ellipsis{display:none}}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1126
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.5", type: KjBreadcrumbComponent, isStandalone: true, selector: "nav[kj-breadcrumb], kj-breadcrumb", inputs: { kjSize: { classPropertyName: "kjSize", publicName: "kjSize", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, properties: { "attr.data-size": "kjSize()" }, classAttribute: "kj-breadcrumb" }, hostDirectives: [{ directive: i1.KjBreadcrumb, inputs: ["kjAriaLabel", "kjAriaLabel", "kjSeparator", "kjSeparator", "kjMaxItems", "kjMaxItems", "kjOverflow", "kjOverflow"] }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: ["@layer kj.component{.kj-breadcrumb{--kj-breadcrumb-gap: var(--kj-space-sm, .5rem);--kj-breadcrumb-separator-content: \"/\";--kj-breadcrumb-overflow-pad: .25rem;--kj-color-breadcrumb-muted: var(--kj-fg-muted);--kj-color-breadcrumb-current: var(--kj-fg-default);display:block;color:var(--kj-color-breadcrumb-muted);font-size:.875rem}.kj-breadcrumb[data-size=sm]{font-size:.8125rem}.kj-breadcrumb[data-size=md]{font-size:.875rem}.kj-breadcrumb[data-size=lg]{font-size:1rem}.kj-breadcrumb-list{display:flex;align-items:center;flex-wrap:nowrap;gap:var(--kj-breadcrumb-gap);margin:0;padding:0;list-style:none;min-width:0}.kj-breadcrumb-list[data-wrap=wrap]{flex-wrap:wrap}.kj-breadcrumb-list[data-wrap=no-wrap],.kj-breadcrumb-list[data-wrap=truncate]{flex-wrap:nowrap}.kj-breadcrumb-item{display:inline-flex;align-items:center;gap:var(--kj-breadcrumb-gap);min-width:0}.kj-breadcrumb-item[data-hidden]{display:none}.kj-breadcrumb-list:not([data-explicit-separators])>.kj-breadcrumb-item:not(:first-child):before{content:var(--kj-breadcrumb-separator-content, \"/\");color:var(--kj-color-breadcrumb-muted);opacity:.65;-webkit-user-select:none;user-select:none;margin-inline-end:var(--kj-breadcrumb-gap)}[dir=rtl] .kj-breadcrumb[data-mirror-separator] .kj-breadcrumb-list:not([data-explicit-separators])>.kj-breadcrumb-item:not(:first-child):before{display:inline-block;transform:scaleX(-1)}.kj-breadcrumb-separator{display:inline-flex;align-items:center;color:var(--kj-color-breadcrumb-muted);opacity:.65;-webkit-user-select:none;user-select:none}.kj-breadcrumb-link{--kj-link-fg: var(--kj-color-breadcrumb-muted);--kj-link-hover-fg: var(--kj-color-breadcrumb-current);color:var(--kj-link-fg);text-decoration:none;padding-block:.5rem;transition:color var(--kj-transition, .15s ease)}.kj-breadcrumb-link:hover{color:var(--kj-link-hover-fg);text-decoration:underline;text-underline-offset:3px}.kj-breadcrumb-link:focus-visible{outline:2px solid var(--kj-fg-primary);outline-offset:2px;border-radius:var(--kj-radius-field, .25rem)}.kj-breadcrumb-current{color:var(--kj-color-breadcrumb-current);font-weight:500}.kj-breadcrumb-ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:1.5rem;padding-inline:var(--kj-breadcrumb-overflow-pad);color:var(--kj-color-breadcrumb-muted);background:transparent;border:0;cursor:default;-webkit-user-select:none;user-select:none}.kj-breadcrumb-ellipsis[data-overflow=menu]{cursor:pointer;border-radius:var(--kj-radius-field, .25rem)}.kj-breadcrumb-ellipsis[data-overflow=menu]:hover{background:var(--kj-bg-surface, transparent)}@media print{.kj-breadcrumb-item[data-hidden]{display:revert}.kj-breadcrumb-ellipsis{display:none}}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
914
1127
|
}
|
|
915
1128
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjBreadcrumbComponent, decorators: [{
|
|
916
1129
|
type: Component,
|
|
@@ -923,7 +1136,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
923
1136
|
'class': 'kj-breadcrumb',
|
|
924
1137
|
'role': 'navigation',
|
|
925
1138
|
'[attr.data-size]': 'kjSize()',
|
|
926
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-breadcrumb{--kj-breadcrumb-gap: var(--kj-space-sm, .5rem);--kj-breadcrumb-separator-content: \"/\";--kj-breadcrumb-overflow-pad: .25rem;--kj-color-breadcrumb-muted: var(--kj-fg-muted);--kj-color-breadcrumb-current: var(--kj-fg-default);display:block;color:var(--kj-color-breadcrumb-muted);font-size:.875rem}.kj-breadcrumb[data-size=sm]{font-size:.8125rem}.kj-breadcrumb[data-size=md]{font-size:.875rem}.kj-breadcrumb[data-size=lg]{font-size:1rem}.kj-breadcrumb-list{display:flex;align-items:center;flex-wrap:nowrap;gap:var(--kj-breadcrumb-gap);margin:0;padding:0;list-style:none;min-width:0}.kj-breadcrumb-list[data-wrap=wrap]{flex-wrap:wrap}.kj-breadcrumb-list[data-wrap=no-wrap],.kj-breadcrumb-list[data-wrap=truncate]{flex-wrap:nowrap}.kj-breadcrumb-item{display:inline-flex;align-items:center;gap:var(--kj-breadcrumb-gap);min-width:0}.kj-breadcrumb-item[data-hidden]{display:none}.kj-breadcrumb-list:not([data-explicit-separators])>.kj-breadcrumb-item:not(:first-child):before{content:var(--kj-breadcrumb-separator-content, \"/\");color:var(--kj-color-breadcrumb-muted);opacity:.65;-webkit-user-select:none;user-select:none;margin-inline-end:var(--kj-breadcrumb-gap)}[dir=rtl] .kj-breadcrumb[data-mirror-separator] .kj-breadcrumb-list:not([data-explicit-separators])>.kj-breadcrumb-item:not(:first-child):before{display:inline-block;transform:scaleX(-1)}.kj-breadcrumb-separator{display:inline-flex;align-items:center;color:var(--kj-color-breadcrumb-muted);opacity:.65;-webkit-user-select:none;user-select:none}.kj-breadcrumb-link{text-decoration:none;padding-block:.5rem}.kj-breadcrumb-current{color:var(--kj-color-breadcrumb-current);font-weight:500}.kj-breadcrumb-ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:1.5rem;padding-inline:var(--kj-breadcrumb-overflow-pad);color:var(--kj-color-breadcrumb-muted);background:transparent;border:0;cursor:default;-webkit-user-select:none;user-select:none}.kj-breadcrumb-ellipsis[data-overflow=menu]{cursor:pointer;border-radius:var(--kj-radius-field, .25rem)}.kj-breadcrumb-ellipsis[data-overflow=menu]:hover{background:var(--kj-bg-surface, transparent)}@media print{.kj-breadcrumb-item[data-hidden]{display:revert}.kj-breadcrumb-ellipsis{display:none}}}\n"] }]
|
|
1139
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-breadcrumb{--kj-breadcrumb-gap: var(--kj-space-sm, .5rem);--kj-breadcrumb-separator-content: \"/\";--kj-breadcrumb-overflow-pad: .25rem;--kj-color-breadcrumb-muted: var(--kj-fg-muted);--kj-color-breadcrumb-current: var(--kj-fg-default);display:block;color:var(--kj-color-breadcrumb-muted);font-size:.875rem}.kj-breadcrumb[data-size=sm]{font-size:.8125rem}.kj-breadcrumb[data-size=md]{font-size:.875rem}.kj-breadcrumb[data-size=lg]{font-size:1rem}.kj-breadcrumb-list{display:flex;align-items:center;flex-wrap:nowrap;gap:var(--kj-breadcrumb-gap);margin:0;padding:0;list-style:none;min-width:0}.kj-breadcrumb-list[data-wrap=wrap]{flex-wrap:wrap}.kj-breadcrumb-list[data-wrap=no-wrap],.kj-breadcrumb-list[data-wrap=truncate]{flex-wrap:nowrap}.kj-breadcrumb-item{display:inline-flex;align-items:center;gap:var(--kj-breadcrumb-gap);min-width:0}.kj-breadcrumb-item[data-hidden]{display:none}.kj-breadcrumb-list:not([data-explicit-separators])>.kj-breadcrumb-item:not(:first-child):before{content:var(--kj-breadcrumb-separator-content, \"/\");color:var(--kj-color-breadcrumb-muted);opacity:.65;-webkit-user-select:none;user-select:none;margin-inline-end:var(--kj-breadcrumb-gap)}[dir=rtl] .kj-breadcrumb[data-mirror-separator] .kj-breadcrumb-list:not([data-explicit-separators])>.kj-breadcrumb-item:not(:first-child):before{display:inline-block;transform:scaleX(-1)}.kj-breadcrumb-separator{display:inline-flex;align-items:center;color:var(--kj-color-breadcrumb-muted);opacity:.65;-webkit-user-select:none;user-select:none}.kj-breadcrumb-link{--kj-link-fg: var(--kj-color-breadcrumb-muted);--kj-link-hover-fg: var(--kj-color-breadcrumb-current);color:var(--kj-link-fg);text-decoration:none;padding-block:.5rem;transition:color var(--kj-transition, .15s ease)}.kj-breadcrumb-link:hover{color:var(--kj-link-hover-fg);text-decoration:underline;text-underline-offset:3px}.kj-breadcrumb-link:focus-visible{outline:2px solid var(--kj-fg-primary);outline-offset:2px;border-radius:var(--kj-radius-field, .25rem)}.kj-breadcrumb-current{color:var(--kj-color-breadcrumb-current);font-weight:500}.kj-breadcrumb-ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:1.5rem;padding-inline:var(--kj-breadcrumb-overflow-pad);color:var(--kj-color-breadcrumb-muted);background:transparent;border:0;cursor:default;-webkit-user-select:none;user-select:none}.kj-breadcrumb-ellipsis[data-overflow=menu]{cursor:pointer;border-radius:var(--kj-radius-field, .25rem)}.kj-breadcrumb-ellipsis[data-overflow=menu]:hover{background:var(--kj-bg-surface, transparent)}@media print{.kj-breadcrumb-item[data-hidden]{display:revert}.kj-breadcrumb-ellipsis{display:none}}}\n"] }]
|
|
927
1140
|
}], propDecorators: { kjSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjSize", required: false }] }] } });
|
|
928
1141
|
/**
|
|
929
1142
|
* Wraps `KjBreadcrumbList`. Renders an `<ol>` host inside the breadcrumb
|
|
@@ -2285,6 +2498,150 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
2285
2498
|
}]
|
|
2286
2499
|
}], propDecorators: { ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }] } });
|
|
2287
2500
|
|
|
2501
|
+
/** Monotonic id source for wiring `aria-describedby` to the caption span. */
|
|
2502
|
+
let kjChartUid = 0;
|
|
2503
|
+
/**
|
|
2504
|
+
* Reusable charting surface wrapping Apache ECharts.
|
|
2505
|
+
*
|
|
2506
|
+
* SSR-safe: the ECharts instance is created lazily in the browser only, after
|
|
2507
|
+
* the host element has rendered. `option` changes are pushed through
|
|
2508
|
+
* `setOption`, and a `ResizeObserver` keeps the chart sized to its container.
|
|
2509
|
+
*
|
|
2510
|
+
* ECharts paints into an opaque `<canvas>` that assistive technology cannot
|
|
2511
|
+
* read. The host therefore carries `role="img"` plus a required-in-practice
|
|
2512
|
+
* `ariaLabel`, giving screen readers a one-line description. Pass `caption`
|
|
2513
|
+
* for a longer summary — it renders in a visually-hidden `<span>` wired to the
|
|
2514
|
+
* host via `aria-describedby`, so it is announced even though the host is an
|
|
2515
|
+
* image (a leaf) to AT.
|
|
2516
|
+
*
|
|
2517
|
+
* @example
|
|
2518
|
+
* ```html
|
|
2519
|
+
* <kj-chart [option]="chartOption" height="320px" ariaLabel="Revenue by month" />
|
|
2520
|
+
* ```
|
|
2521
|
+
*
|
|
2522
|
+
* @doc-example Default
|
|
2523
|
+
* The default playground — a labelled bar chart with auto-resize.
|
|
2524
|
+
* @doc-file chart.example.ts
|
|
2525
|
+
* @doc-example Usage
|
|
2526
|
+
* A bar chart and a donut, side by side, each with an accessible name and
|
|
2527
|
+
* summary. Use this as the copy-paste starting point.
|
|
2528
|
+
* @doc-file chart.usage.example.ts
|
|
2529
|
+
* @doc-example Donut
|
|
2530
|
+
* A pie series with an inner radius for part-to-whole breakdowns.
|
|
2531
|
+
* @doc-file chart.donut.example.ts
|
|
2532
|
+
*
|
|
2533
|
+
* @doc-aria
|
|
2534
|
+
* role — Always `img`; the canvas is decorative-with-label
|
|
2535
|
+
* aria-label — Bound from `ariaLabel`; the chart's accessible name
|
|
2536
|
+
* aria-describedby — Present only when `caption` is set; points at the sr-only summary
|
|
2537
|
+
*
|
|
2538
|
+
* @doc-a11y
|
|
2539
|
+
* Screen readers get the `ariaLabel` as the accessible name and, when set,
|
|
2540
|
+
* the `caption` as the accessible description. The host is never focusable
|
|
2541
|
+
* and the canvas takes no tab stop, so keyboard users are not trapped. For
|
|
2542
|
+
* dense data, mirror the series in an adjacent `<table>` or export link.
|
|
2543
|
+
*
|
|
2544
|
+
* @doc-related card,table
|
|
2545
|
+
*
|
|
2546
|
+
* @doc-css-var
|
|
2547
|
+
* --kj-chart-height — Container height. Bound from the `height` input.
|
|
2548
|
+
*
|
|
2549
|
+
* @doc-category Library/Data display
|
|
2550
|
+
* @doc
|
|
2551
|
+
* @doc-name chart
|
|
2552
|
+
* @doc-description Accessible Apache ECharts wrapper with reactive options, auto-resize, and SSR-safe lazy init.
|
|
2553
|
+
* @doc-is-main
|
|
2554
|
+
*/
|
|
2555
|
+
class KjChartComponent {
|
|
2556
|
+
/** The ECharts option object driving the chart. */
|
|
2557
|
+
option = input(/* @ts-ignore */
|
|
2558
|
+
...(ngDevMode ? [undefined, { debugName: "option" }] : /* istanbul ignore next */ []));
|
|
2559
|
+
/** Container height — number is treated as pixels. Default `'280px'`. */
|
|
2560
|
+
height = input('280px', /* @ts-ignore */
|
|
2561
|
+
...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
|
|
2562
|
+
/** Optional registered ECharts theme name. */
|
|
2563
|
+
theme = input(/* @ts-ignore */
|
|
2564
|
+
...(ngDevMode ? [undefined, { debugName: "theme" }] : /* istanbul ignore next */ []));
|
|
2565
|
+
/**
|
|
2566
|
+
* Accessible name for the chart — required in practice. Surfaced via
|
|
2567
|
+
* `role="img"` + `aria-label` so screen readers describe the opaque canvas.
|
|
2568
|
+
* Keep it to a short phrase, e.g. `"Revenue by month"`.
|
|
2569
|
+
*/
|
|
2570
|
+
ariaLabel = input('', /* @ts-ignore */
|
|
2571
|
+
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
2572
|
+
/**
|
|
2573
|
+
* Optional longer summary read to screen readers. Rendered in a
|
|
2574
|
+
* visually-hidden `<span>` and linked via `aria-describedby`. Use it to
|
|
2575
|
+
* spell out the takeaway a sighted user gets from the shape of the data.
|
|
2576
|
+
*/
|
|
2577
|
+
caption = input('', /* @ts-ignore */
|
|
2578
|
+
...(ngDevMode ? [{ debugName: "caption" }] : /* istanbul ignore next */ []));
|
|
2579
|
+
/** Stable id linking the sr-only caption span to `aria-describedby`. */
|
|
2580
|
+
captionId = `kj-chart-caption-${kjChartUid++}`;
|
|
2581
|
+
host = inject((ElementRef)).nativeElement;
|
|
2582
|
+
platformId = inject(PLATFORM_ID);
|
|
2583
|
+
destroyRef = inject(DestroyRef);
|
|
2584
|
+
chart = null;
|
|
2585
|
+
observer = null;
|
|
2586
|
+
resolvedHeight = () => {
|
|
2587
|
+
const h = this.height();
|
|
2588
|
+
return typeof h === 'number' ? `${h}px` : h;
|
|
2589
|
+
};
|
|
2590
|
+
constructor() {
|
|
2591
|
+
// Create the instance only in the browser, after the host is in the DOM.
|
|
2592
|
+
afterNextRender(() => {
|
|
2593
|
+
if (!isPlatformBrowser(this.platformId))
|
|
2594
|
+
return;
|
|
2595
|
+
void this.init();
|
|
2596
|
+
});
|
|
2597
|
+
// Push option changes to the live instance.
|
|
2598
|
+
effect(() => {
|
|
2599
|
+
const option = this.option();
|
|
2600
|
+
if (this.chart && option) {
|
|
2601
|
+
this.chart.setOption(option, { notMerge: true });
|
|
2602
|
+
}
|
|
2603
|
+
});
|
|
2604
|
+
this.destroyRef.onDestroy(() => this.dispose());
|
|
2605
|
+
}
|
|
2606
|
+
async init() {
|
|
2607
|
+
const echarts = await import('echarts');
|
|
2608
|
+
if (this.chart)
|
|
2609
|
+
return; // guard against double-init / destroyed race
|
|
2610
|
+
this.chart = echarts.init(this.host, this.theme());
|
|
2611
|
+
const option = this.option();
|
|
2612
|
+
if (option)
|
|
2613
|
+
this.chart.setOption(option, { notMerge: true });
|
|
2614
|
+
this.observer = new ResizeObserver(() => this.chart?.resize());
|
|
2615
|
+
this.observer.observe(this.host);
|
|
2616
|
+
}
|
|
2617
|
+
dispose() {
|
|
2618
|
+
this.observer?.disconnect();
|
|
2619
|
+
this.observer = null;
|
|
2620
|
+
this.chart?.dispose();
|
|
2621
|
+
this.chart = null;
|
|
2622
|
+
}
|
|
2623
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjChartComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2624
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: KjChartComponent, isStandalone: true, selector: "kj-chart", inputs: { option: { classPropertyName: "option", publicName: "option", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, caption: { classPropertyName: "caption", publicName: "caption", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "img" }, properties: { "attr.aria-label": "ariaLabel() || null", "attr.aria-describedby": "caption() ? captionId : null", "style.height": "resolvedHeight()" }, classAttribute: "kj-chart" }, ngImport: i0, template: `
|
|
2625
|
+
@if (caption(); as text) {
|
|
2626
|
+
<span [id]="captionId" class="kj-chart__caption">{{ text }}</span>
|
|
2627
|
+
}
|
|
2628
|
+
`, isInline: true, styles: ["@layer kj.component{.kj-chart{display:block;width:100%}.kj-chart__caption{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2629
|
+
}
|
|
2630
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjChartComponent, decorators: [{
|
|
2631
|
+
type: Component,
|
|
2632
|
+
args: [{ selector: 'kj-chart', standalone: true, template: `
|
|
2633
|
+
@if (caption(); as text) {
|
|
2634
|
+
<span [id]="captionId" class="kj-chart__caption">{{ text }}</span>
|
|
2635
|
+
}
|
|
2636
|
+
`, encapsulation: ViewEncapsulation.None, host: {
|
|
2637
|
+
'class': 'kj-chart',
|
|
2638
|
+
'role': 'img',
|
|
2639
|
+
'[attr.aria-label]': 'ariaLabel() || null',
|
|
2640
|
+
'[attr.aria-describedby]': 'caption() ? captionId : null',
|
|
2641
|
+
'[style.height]': 'resolvedHeight()',
|
|
2642
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-chart{display:block;width:100%}.kj-chart__caption{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}}\n"] }]
|
|
2643
|
+
}], ctorParameters: () => [], propDecorators: { option: [{ type: i0.Input, args: [{ isSignal: true, alias: "option", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], caption: [{ type: i0.Input, args: [{ isSignal: true, alias: "caption", required: false }] }] } });
|
|
2644
|
+
|
|
2288
2645
|
/**
|
|
2289
2646
|
* Chat log container. Composes `KjChatLog` via `hostDirectives` so the
|
|
2290
2647
|
* `role="log"` / `aria-live` / `aria-relevant` host bindings land on the
|
|
@@ -2548,47 +2905,797 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
2548
2905
|
}]
|
|
2549
2906
|
}] });
|
|
2550
2907
|
|
|
2551
|
-
|
|
2908
|
+
/** HTML-escape a raw string. */
|
|
2909
|
+
function escapeHtml(s) {
|
|
2910
|
+
return s
|
|
2911
|
+
.replace(/&/g, '&')
|
|
2912
|
+
.replace(/</g, '<')
|
|
2913
|
+
.replace(/>/g, '>')
|
|
2914
|
+
.replace(/"/g, '"')
|
|
2915
|
+
.replace(/'/g, ''');
|
|
2916
|
+
}
|
|
2917
|
+
/** Only allow safe URL schemes for links. */
|
|
2918
|
+
function safeUrl(url) {
|
|
2919
|
+
const trimmed = url.trim();
|
|
2920
|
+
if (/^(https?:\/\/|\/|#|mailto:)/i.test(trimmed))
|
|
2921
|
+
return trimmed;
|
|
2922
|
+
return null;
|
|
2923
|
+
}
|
|
2924
|
+
/** Apply link / bold / italic to a non-code segment. */
|
|
2925
|
+
function formatSegment(seg) {
|
|
2926
|
+
let s = seg.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, (_m, text, url) => {
|
|
2927
|
+
const href = safeUrl(url);
|
|
2928
|
+
if (!href)
|
|
2929
|
+
return text;
|
|
2930
|
+
return `<a class="kj-md-link" href="${escapeHtml(href)}" rel="noopener noreferrer" target="_blank">${text}</a>`;
|
|
2931
|
+
});
|
|
2932
|
+
s = s.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
|
|
2933
|
+
s = s.replace(/(^|[^*])\*([^*]+)\*/g, '$1<em>$2</em>');
|
|
2934
|
+
return s;
|
|
2935
|
+
}
|
|
2552
2936
|
/**
|
|
2553
|
-
*
|
|
2937
|
+
* Render inline markdown on an **already HTML-escaped** string. Splits on
|
|
2938
|
+
* backtick code spans first so their contents are never re-formatted, then
|
|
2939
|
+
* applies link / bold / italic to the remaining prose segments.
|
|
2940
|
+
*/
|
|
2941
|
+
function renderInline(escaped) {
|
|
2942
|
+
return escaped
|
|
2943
|
+
.split(/(`[^`]+`)/g)
|
|
2944
|
+
.map((seg) => {
|
|
2945
|
+
if (seg.length >= 2 && seg.startsWith('`') && seg.endsWith('`')) {
|
|
2946
|
+
return `<code class="kj-md-code">${seg.slice(1, -1)}</code>`;
|
|
2947
|
+
}
|
|
2948
|
+
return formatSegment(seg);
|
|
2949
|
+
})
|
|
2950
|
+
.join('');
|
|
2951
|
+
}
|
|
2952
|
+
/** Render a prose block (paragraphs + single-newline `<br>`) to safe HTML. */
|
|
2953
|
+
function renderProse(block) {
|
|
2954
|
+
const paragraphs = block
|
|
2955
|
+
.split(/\n{2,}/)
|
|
2956
|
+
.map((p) => p.trim())
|
|
2957
|
+
.filter(Boolean);
|
|
2958
|
+
return paragraphs
|
|
2959
|
+
.map((p) => {
|
|
2960
|
+
const lines = p.split('\n').map((line) => renderInline(escapeHtml(line)));
|
|
2961
|
+
return `<p>${lines.join('<br>')}</p>`;
|
|
2962
|
+
})
|
|
2963
|
+
.join('');
|
|
2964
|
+
}
|
|
2965
|
+
/**
|
|
2966
|
+
* Parse a lightweight markdown subset into blocks: fenced code blocks
|
|
2967
|
+
* (```lang) become structural `code` blocks; everything else becomes `prose`
|
|
2968
|
+
* blocks with sanitised inline HTML.
|
|
2554
2969
|
*
|
|
2555
|
-
*
|
|
2556
|
-
*
|
|
2557
|
-
*
|
|
2558
|
-
|
|
2970
|
+
* Deliberately minimal (no tables / nested lists) and **self-contained** — the
|
|
2971
|
+
* repo ships no markdown engine on `main`. Swap in a full parser later without
|
|
2972
|
+
* touching the view.
|
|
2973
|
+
*/
|
|
2974
|
+
function renderMarkdown(src) {
|
|
2975
|
+
const blocks = [];
|
|
2976
|
+
const fence = /```([\w-]*)\n?([\s\S]*?)```/g;
|
|
2977
|
+
let last = 0;
|
|
2978
|
+
for (let m = fence.exec(src); m; m = fence.exec(src)) {
|
|
2979
|
+
const before = src.slice(last, m.index);
|
|
2980
|
+
if (before.trim())
|
|
2981
|
+
blocks.push({ kind: 'prose', html: renderProse(before) });
|
|
2982
|
+
blocks.push({ kind: 'code', lang: m[1] || '', code: m[2].replace(/\n$/, '') });
|
|
2983
|
+
last = fence.lastIndex;
|
|
2984
|
+
}
|
|
2985
|
+
const rest = src.slice(last);
|
|
2986
|
+
if (rest.trim())
|
|
2987
|
+
blocks.push({ kind: 'prose', html: renderProse(rest) });
|
|
2988
|
+
return blocks;
|
|
2989
|
+
}
|
|
2990
|
+
|
|
2991
|
+
/** Human-readable accessible name per role. */
|
|
2992
|
+
const ROLE_LABEL = {
|
|
2993
|
+
user: 'You',
|
|
2994
|
+
assistant: 'Assistant',
|
|
2995
|
+
system: 'System',
|
|
2996
|
+
tool: 'Tool',
|
|
2997
|
+
};
|
|
2998
|
+
/**
|
|
2999
|
+
* Renders a single AI-thread message. Reuses the core `KjChat` row directive
|
|
3000
|
+
* for `role="article"` + side semantics, and renders the body per role:
|
|
3001
|
+
* user/assistant get a bubble with **safe markdown** (code blocks carry a copy
|
|
3002
|
+
* button), system gets a centered note, tool gets a tool-call card. Assistant
|
|
3003
|
+
* turns also surface tool-call cards, citations, and a reduced-motion typing
|
|
3004
|
+
* indicator while streaming.
|
|
2559
3005
|
*
|
|
2560
|
-
*
|
|
2561
|
-
*
|
|
2562
|
-
*
|
|
2563
|
-
*
|
|
2564
|
-
*
|
|
2565
|
-
*
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
3006
|
+
* The message is given an `aria-label` (its role name) so AT announces
|
|
3007
|
+
* "Assistant, article" rather than an anonymous region — the visible content is
|
|
3008
|
+
* the message text itself.
|
|
3009
|
+
*
|
|
3010
|
+
* @doc
|
|
3011
|
+
* @doc-name ai-chat
|
|
3012
|
+
*/
|
|
3013
|
+
class KjChatMessage {
|
|
3014
|
+
sanitizer = inject(DomSanitizer);
|
|
3015
|
+
/** The message to render. */
|
|
3016
|
+
message = input.required(/* @ts-ignore */
|
|
3017
|
+
...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
3018
|
+
/** User messages sit on the `end` side; everyone else on `start`. */
|
|
3019
|
+
side = computed(() => (this.message().role === 'user' ? 'end' : 'start'), /* @ts-ignore */
|
|
3020
|
+
...(ngDevMode ? [{ debugName: "side" }] : /* istanbul ignore next */ []));
|
|
3021
|
+
roleLabel = computed(() => ROLE_LABEL[this.message().role], /* @ts-ignore */
|
|
3022
|
+
...(ngDevMode ? [{ debugName: "roleLabel" }] : /* istanbul ignore next */ []));
|
|
3023
|
+
avatarGlyph = computed(() => this.roleLabel().charAt(0), /* @ts-ignore */
|
|
3024
|
+
...(ngDevMode ? [{ debugName: "avatarGlyph" }] : /* istanbul ignore next */ []));
|
|
3025
|
+
showAvatar = computed(() => this.message().role !== 'system', /* @ts-ignore */
|
|
3026
|
+
...(ngDevMode ? [{ debugName: "showAvatar" }] : /* istanbul ignore next */ []));
|
|
3027
|
+
/** Parsed markdown blocks for the body. */
|
|
3028
|
+
blocks = computed(() => renderMarkdown(this.message().content), /* @ts-ignore */
|
|
3029
|
+
...(ngDevMode ? [{ debugName: "blocks" }] : /* istanbul ignore next */ []));
|
|
3030
|
+
_copied = signal(null, /* @ts-ignore */
|
|
3031
|
+
...(ngDevMode ? [{ debugName: "_copied" }] : /* istanbul ignore next */ []));
|
|
3032
|
+
copiedIndex = this._copied.asReadonly();
|
|
3033
|
+
safe(html) {
|
|
3034
|
+
return this.sanitizer.bypassSecurityTrustHtml(html);
|
|
3035
|
+
}
|
|
3036
|
+
async copy(code, index) {
|
|
3037
|
+
try {
|
|
3038
|
+
await navigator.clipboard?.writeText(code);
|
|
3039
|
+
this._copied.set(index);
|
|
3040
|
+
setTimeout(() => this._copied.set(null), 2000);
|
|
3041
|
+
}
|
|
3042
|
+
catch {
|
|
3043
|
+
/* clipboard unavailable — no-op */
|
|
3044
|
+
}
|
|
3045
|
+
}
|
|
3046
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjChatMessage, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3047
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: KjChatMessage, isStandalone: true, selector: "kj-chat-message", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null } }, host: { classAttribute: "kj-chat-msg-host" }, ngImport: i0, template: `
|
|
3048
|
+
<div
|
|
3049
|
+
kjChat
|
|
3050
|
+
class="kj-chat-msg"
|
|
3051
|
+
[kjSide]="side()"
|
|
3052
|
+
[attr.data-role]="message().role"
|
|
3053
|
+
[attr.aria-label]="roleLabel()"
|
|
3054
|
+
>
|
|
3055
|
+
@if (showAvatar()) {
|
|
3056
|
+
<div class="kj-chat-msg__avatar" aria-hidden="true">{{ avatarGlyph() }}</div>
|
|
3057
|
+
}
|
|
3058
|
+
|
|
3059
|
+
<div class="kj-chat-msg__bubble">
|
|
3060
|
+
<!-- Tool-call cards (assistant turns) -->
|
|
3061
|
+
@for (tc of message().toolCalls ?? []; track tc.id) {
|
|
3062
|
+
<div
|
|
3063
|
+
class="kj-chat-tool"
|
|
3064
|
+
[attr.data-status]="tc.status"
|
|
3065
|
+
role="group"
|
|
3066
|
+
[attr.aria-label]="'Tool call: ' + tc.name"
|
|
3067
|
+
>
|
|
3068
|
+
<span class="kj-chat-tool__icon" aria-hidden="true">⚙</span>
|
|
3069
|
+
<span class="kj-chat-tool__name">{{ tc.name }}</span>
|
|
3070
|
+
<span class="kj-chat-tool__status">{{ tc.status }}</span>
|
|
3071
|
+
@if (tc.error) {
|
|
3072
|
+
<span class="kj-chat-tool__error">{{ tc.error }}</span>
|
|
3073
|
+
}
|
|
3074
|
+
</div>
|
|
3075
|
+
}
|
|
3076
|
+
|
|
3077
|
+
<!-- Body -->
|
|
3078
|
+
<div class="kj-chat-msg__body">
|
|
3079
|
+
@for (block of blocks(); track $index) {
|
|
3080
|
+
@if (block.kind === 'code') {
|
|
3081
|
+
<div class="kj-chat-code">
|
|
3082
|
+
<div class="kj-chat-code__bar">
|
|
3083
|
+
<span class="kj-chat-code__lang">{{ block.lang || 'code' }}</span>
|
|
3084
|
+
<button
|
|
3085
|
+
type="button"
|
|
3086
|
+
class="kj-chat-code__copy"
|
|
3087
|
+
[attr.aria-label]="copiedIndex() === $index ? 'Copied' : 'Copy code'"
|
|
3088
|
+
(click)="copy(block.code, $index)"
|
|
3089
|
+
>
|
|
3090
|
+
{{ copiedIndex() === $index ? 'Copied' : 'Copy' }}
|
|
3091
|
+
</button>
|
|
3092
|
+
</div>
|
|
3093
|
+
<pre class="kj-chat-code__pre"><code>{{ block.code }}</code></pre>
|
|
3094
|
+
</div>
|
|
3095
|
+
} @else {
|
|
3096
|
+
<div class="kj-chat-md" [innerHTML]="safe(block.html)"></div>
|
|
3097
|
+
}
|
|
3098
|
+
}
|
|
3099
|
+
|
|
3100
|
+
<!-- Typing indicator while streaming with no content yet -->
|
|
3101
|
+
@if (message().streaming && message().content.length === 0) {
|
|
3102
|
+
<div class="kj-chat-typing" role="status" aria-label="Assistant is typing">
|
|
3103
|
+
<span class="kj-chat-typing__dot"></span>
|
|
3104
|
+
<span class="kj-chat-typing__dot"></span>
|
|
3105
|
+
<span class="kj-chat-typing__dot"></span>
|
|
3106
|
+
</div>
|
|
3107
|
+
}
|
|
3108
|
+
</div>
|
|
3109
|
+
|
|
3110
|
+
<!-- Error -->
|
|
3111
|
+
@if (message().error) {
|
|
3112
|
+
<p class="kj-chat-msg__error" role="alert">{{ message().error }}</p>
|
|
3113
|
+
}
|
|
3114
|
+
|
|
3115
|
+
<!-- Citations -->
|
|
3116
|
+
@if ((message().citations ?? []).length > 0) {
|
|
3117
|
+
<ul class="kj-chat-cites" aria-label="Sources">
|
|
3118
|
+
@for (c of message().citations ?? []; track c.id) {
|
|
3119
|
+
<li class="kj-chat-cite">
|
|
3120
|
+
@if (c.url) {
|
|
3121
|
+
<a
|
|
3122
|
+
class="kj-chat-cite__link"
|
|
3123
|
+
[href]="c.url"
|
|
3124
|
+
rel="noopener noreferrer"
|
|
3125
|
+
target="_blank"
|
|
3126
|
+
>{{ c.title }}</a
|
|
3127
|
+
>
|
|
3128
|
+
} @else {
|
|
3129
|
+
<span class="kj-chat-cite__link">{{ c.title }}</span>
|
|
3130
|
+
}
|
|
3131
|
+
@if (c.snippet) {
|
|
3132
|
+
<span class="kj-chat-cite__snippet">{{ c.snippet }}</span>
|
|
3133
|
+
}
|
|
3134
|
+
</li>
|
|
3135
|
+
}
|
|
3136
|
+
</ul>
|
|
3137
|
+
}
|
|
3138
|
+
</div>
|
|
3139
|
+
</div>
|
|
3140
|
+
`, isInline: true, styles: ["@layer kj.component{.kj-visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.kj-chat-thread{display:flex;flex-direction:column;gap:var(--kj-space-md);padding:var(--kj-space-md);background:var(--kj-bg-body);color:var(--kj-fg-default);border-radius:var(--kj-radius-box);overflow-y:auto;font-family:var(--kj-font-sans)}.kj-chat-msg{display:flex;gap:var(--kj-space-sm);align-items:flex-start;max-width:100%}.kj-chat-msg[data-side=end]{flex-direction:row-reverse;margin-inline-start:auto}.kj-chat-msg[data-role=system]{justify-content:center}.kj-chat-msg__avatar{flex:0 0 auto;width:2rem;height:2rem;border-radius:50%;display:grid;place-items:center;font-size:var(--kj-text-sm);font-weight:600;background:var(--kj-bg-surface);color:var(--kj-fg-default);border:1px solid var(--kj-border-default)}.kj-chat-msg__bubble{display:flex;flex-direction:column;gap:var(--kj-space-xs);padding:var(--kj-space-sm) var(--kj-space-md);border-radius:var(--kj-radius-box);background:var(--kj-bg-surface);color:var(--kj-fg-default);max-width:min(48rem,100%);overflow-wrap:anywhere}.kj-chat-msg[data-role=user] .kj-chat-msg__bubble{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-chat-msg[data-role=system] .kj-chat-msg__bubble{background:transparent;color:var(--kj-fg-muted);font-size:var(--kj-text-sm);text-align:center;padding-block:var(--kj-space-xs)}.kj-chat-msg__body :is(p){margin:0 0 var(--kj-space-xs)}.kj-chat-msg__body :is(p):last-child{margin-bottom:0}.kj-chat-msg__error{margin:0;color:var(--kj-fg-danger);font-size:var(--kj-text-sm)}.kj-md-link{color:inherit;text-decoration:underline}.kj-md-code{font-family:ui-monospace,monospace;background:color-mix(in srgb,currentColor 12%,transparent);padding:.1em .35em;border-radius:var(--kj-radius-field);font-size:.9em}.kj-chat-code{border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);overflow:hidden;margin:var(--kj-space-xs) 0;background:var(--kj-bg-body)}.kj-chat-code__bar{display:flex;align-items:center;justify-content:space-between;padding:.25rem var(--kj-space-sm);background:var(--kj-bg-surface);border-bottom:1px solid var(--kj-border-default);font-size:var(--kj-text-sm);color:var(--kj-fg-muted)}.kj-chat-code__copy{min-height:1.75rem;padding:.25rem .6rem;border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);background:var(--kj-bg-body);color:var(--kj-fg-default);font-size:var(--kj-text-sm);cursor:pointer}.kj-chat-code__copy:hover{background:var(--kj-bg-surface)}.kj-chat-code__copy:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-chat-code__pre{margin:0;padding:var(--kj-space-sm);overflow-x:auto;font-family:ui-monospace,monospace;font-size:.9em;color:var(--kj-fg-default)}.kj-chat-tool{display:flex;align-items:center;gap:var(--kj-space-xs);padding:.35rem var(--kj-space-sm);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);background:var(--kj-bg-body);font-size:var(--kj-text-sm)}.kj-chat-tool__name{font-weight:600;font-family:ui-monospace,monospace}.kj-chat-tool__status{margin-inline-start:auto;color:var(--kj-fg-muted);text-transform:capitalize}.kj-chat-tool[data-status=error]{border-color:var(--kj-border-danger)}.kj-chat-tool[data-status=error] .kj-chat-tool__status,.kj-chat-tool__error{color:var(--kj-fg-danger)}.kj-chat-cites{list-style:none;margin:var(--kj-space-xs) 0 0;padding:0;display:flex;flex-wrap:wrap;gap:var(--kj-space-xs)}.kj-chat-cite{display:inline-flex;align-items:baseline;gap:.35rem;padding:.15rem .5rem;border:1px solid var(--kj-border-default);border-radius:999px;font-size:var(--kj-text-sm);background:var(--kj-bg-body)}.kj-chat-cite__link{color:var(--kj-fg-info);text-decoration:none}.kj-chat-cite__link:hover{text-decoration:underline}.kj-chat-cite__snippet{color:var(--kj-fg-muted)}.kj-chat-typing{display:inline-flex;gap:.25rem;align-items:center;padding:.25rem 0}.kj-chat-typing__dot{width:.5rem;height:.5rem;border-radius:50%;background:var(--kj-fg-muted);animation:kj-chat-bounce 1.2s infinite ease-in-out both}.kj-chat-typing__dot:nth-child(2){animation-delay:.15s}.kj-chat-typing__dot:nth-child(3){animation-delay:.3s}@keyframes kj-chat-bounce{0%,80%,to{transform:scale(.5);opacity:.4}40%{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.kj-chat-typing__dot{animation:none;opacity:.6}}.kj-prompt{position:relative;display:flex;align-items:flex-end;gap:var(--kj-space-sm);padding:var(--kj-space-sm);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-box);background:var(--kj-bg-field, var(--kj-input-bg))}.kj-prompt:focus-within{border-color:var(--kj-border-focus)}.kj-prompt__textarea{flex:1 1 auto;resize:none;border:none;outline:none;background:transparent;color:var(--kj-input-fg, var(--kj-fg-default));font-family:var(--kj-font-sans);font-size:var(--kj-input-font-size, 1rem);line-height:1.5;max-height:200px;overflow-y:auto}.kj-prompt__textarea::placeholder{color:var(--kj-input-placeholder-fg, var(--kj-fg-muted))}.kj-prompt__actions{display:flex;align-items:center;gap:var(--kj-space-xs);flex:0 0 auto}.kj-prompt__btn{display:grid;place-items:center;width:2.75rem;height:2.75rem;border-radius:50%;border:none;cursor:pointer;font-size:1.1rem}.kj-prompt__btn:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-prompt__btn--send{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-prompt__btn--send:disabled{opacity:.5;cursor:not-allowed}.kj-prompt__btn--stop{background:var(--kj-bg-danger);color:var(--kj-fg-on-danger)}.kj-prompt__slash{position:absolute;bottom:calc(100% + .25rem);left:0;right:0;margin:0;padding:.25rem;list-style:none;background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);box-shadow:0 4px 16px #00000026;max-height:14rem;overflow-y:auto;z-index:10}.kj-prompt__slash-item{display:flex;flex-direction:column;gap:.1rem;padding:var(--kj-space-xs) var(--kj-space-sm);border-radius:var(--kj-radius-field);cursor:pointer}.kj-prompt__slash-item.is-active,.kj-prompt__slash-item:hover{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-prompt__slash-name{font-family:ui-monospace,monospace;font-weight:600}.kj-prompt__slash-desc{font-size:var(--kj-text-sm);color:var(--kj-fg-muted)}.kj-prompt__slash-item.is-active .kj-prompt__slash-desc,.kj-prompt__slash-item:hover .kj-prompt__slash-desc{color:inherit}}\n"], dependencies: [{ kind: "directive", type: KjChat, selector: "[kjChat]", inputs: ["kjSide", "kjChatAuthor", "kjChatGrouped", "kjRole"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
3141
|
+
}
|
|
3142
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjChatMessage, decorators: [{
|
|
3143
|
+
type: Component,
|
|
3144
|
+
args: [{ selector: 'kj-chat-message', standalone: true, imports: [KjChat], template: `
|
|
3145
|
+
<div
|
|
3146
|
+
kjChat
|
|
3147
|
+
class="kj-chat-msg"
|
|
3148
|
+
[kjSide]="side()"
|
|
3149
|
+
[attr.data-role]="message().role"
|
|
3150
|
+
[attr.aria-label]="roleLabel()"
|
|
3151
|
+
>
|
|
3152
|
+
@if (showAvatar()) {
|
|
3153
|
+
<div class="kj-chat-msg__avatar" aria-hidden="true">{{ avatarGlyph() }}</div>
|
|
3154
|
+
}
|
|
3155
|
+
|
|
3156
|
+
<div class="kj-chat-msg__bubble">
|
|
3157
|
+
<!-- Tool-call cards (assistant turns) -->
|
|
3158
|
+
@for (tc of message().toolCalls ?? []; track tc.id) {
|
|
3159
|
+
<div
|
|
3160
|
+
class="kj-chat-tool"
|
|
3161
|
+
[attr.data-status]="tc.status"
|
|
3162
|
+
role="group"
|
|
3163
|
+
[attr.aria-label]="'Tool call: ' + tc.name"
|
|
3164
|
+
>
|
|
3165
|
+
<span class="kj-chat-tool__icon" aria-hidden="true">⚙</span>
|
|
3166
|
+
<span class="kj-chat-tool__name">{{ tc.name }}</span>
|
|
3167
|
+
<span class="kj-chat-tool__status">{{ tc.status }}</span>
|
|
3168
|
+
@if (tc.error) {
|
|
3169
|
+
<span class="kj-chat-tool__error">{{ tc.error }}</span>
|
|
3170
|
+
}
|
|
3171
|
+
</div>
|
|
3172
|
+
}
|
|
3173
|
+
|
|
3174
|
+
<!-- Body -->
|
|
3175
|
+
<div class="kj-chat-msg__body">
|
|
3176
|
+
@for (block of blocks(); track $index) {
|
|
3177
|
+
@if (block.kind === 'code') {
|
|
3178
|
+
<div class="kj-chat-code">
|
|
3179
|
+
<div class="kj-chat-code__bar">
|
|
3180
|
+
<span class="kj-chat-code__lang">{{ block.lang || 'code' }}</span>
|
|
3181
|
+
<button
|
|
3182
|
+
type="button"
|
|
3183
|
+
class="kj-chat-code__copy"
|
|
3184
|
+
[attr.aria-label]="copiedIndex() === $index ? 'Copied' : 'Copy code'"
|
|
3185
|
+
(click)="copy(block.code, $index)"
|
|
3186
|
+
>
|
|
3187
|
+
{{ copiedIndex() === $index ? 'Copied' : 'Copy' }}
|
|
3188
|
+
</button>
|
|
3189
|
+
</div>
|
|
3190
|
+
<pre class="kj-chat-code__pre"><code>{{ block.code }}</code></pre>
|
|
3191
|
+
</div>
|
|
3192
|
+
} @else {
|
|
3193
|
+
<div class="kj-chat-md" [innerHTML]="safe(block.html)"></div>
|
|
3194
|
+
}
|
|
3195
|
+
}
|
|
3196
|
+
|
|
3197
|
+
<!-- Typing indicator while streaming with no content yet -->
|
|
3198
|
+
@if (message().streaming && message().content.length === 0) {
|
|
3199
|
+
<div class="kj-chat-typing" role="status" aria-label="Assistant is typing">
|
|
3200
|
+
<span class="kj-chat-typing__dot"></span>
|
|
3201
|
+
<span class="kj-chat-typing__dot"></span>
|
|
3202
|
+
<span class="kj-chat-typing__dot"></span>
|
|
3203
|
+
</div>
|
|
3204
|
+
}
|
|
3205
|
+
</div>
|
|
3206
|
+
|
|
3207
|
+
<!-- Error -->
|
|
3208
|
+
@if (message().error) {
|
|
3209
|
+
<p class="kj-chat-msg__error" role="alert">{{ message().error }}</p>
|
|
3210
|
+
}
|
|
3211
|
+
|
|
3212
|
+
<!-- Citations -->
|
|
3213
|
+
@if ((message().citations ?? []).length > 0) {
|
|
3214
|
+
<ul class="kj-chat-cites" aria-label="Sources">
|
|
3215
|
+
@for (c of message().citations ?? []; track c.id) {
|
|
3216
|
+
<li class="kj-chat-cite">
|
|
3217
|
+
@if (c.url) {
|
|
3218
|
+
<a
|
|
3219
|
+
class="kj-chat-cite__link"
|
|
3220
|
+
[href]="c.url"
|
|
3221
|
+
rel="noopener noreferrer"
|
|
3222
|
+
target="_blank"
|
|
3223
|
+
>{{ c.title }}</a
|
|
3224
|
+
>
|
|
3225
|
+
} @else {
|
|
3226
|
+
<span class="kj-chat-cite__link">{{ c.title }}</span>
|
|
3227
|
+
}
|
|
3228
|
+
@if (c.snippet) {
|
|
3229
|
+
<span class="kj-chat-cite__snippet">{{ c.snippet }}</span>
|
|
3230
|
+
}
|
|
3231
|
+
</li>
|
|
3232
|
+
}
|
|
3233
|
+
</ul>
|
|
3234
|
+
}
|
|
3235
|
+
</div>
|
|
3236
|
+
</div>
|
|
3237
|
+
`, encapsulation: ViewEncapsulation.None, host: { class: 'kj-chat-msg-host' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.kj-chat-thread{display:flex;flex-direction:column;gap:var(--kj-space-md);padding:var(--kj-space-md);background:var(--kj-bg-body);color:var(--kj-fg-default);border-radius:var(--kj-radius-box);overflow-y:auto;font-family:var(--kj-font-sans)}.kj-chat-msg{display:flex;gap:var(--kj-space-sm);align-items:flex-start;max-width:100%}.kj-chat-msg[data-side=end]{flex-direction:row-reverse;margin-inline-start:auto}.kj-chat-msg[data-role=system]{justify-content:center}.kj-chat-msg__avatar{flex:0 0 auto;width:2rem;height:2rem;border-radius:50%;display:grid;place-items:center;font-size:var(--kj-text-sm);font-weight:600;background:var(--kj-bg-surface);color:var(--kj-fg-default);border:1px solid var(--kj-border-default)}.kj-chat-msg__bubble{display:flex;flex-direction:column;gap:var(--kj-space-xs);padding:var(--kj-space-sm) var(--kj-space-md);border-radius:var(--kj-radius-box);background:var(--kj-bg-surface);color:var(--kj-fg-default);max-width:min(48rem,100%);overflow-wrap:anywhere}.kj-chat-msg[data-role=user] .kj-chat-msg__bubble{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-chat-msg[data-role=system] .kj-chat-msg__bubble{background:transparent;color:var(--kj-fg-muted);font-size:var(--kj-text-sm);text-align:center;padding-block:var(--kj-space-xs)}.kj-chat-msg__body :is(p){margin:0 0 var(--kj-space-xs)}.kj-chat-msg__body :is(p):last-child{margin-bottom:0}.kj-chat-msg__error{margin:0;color:var(--kj-fg-danger);font-size:var(--kj-text-sm)}.kj-md-link{color:inherit;text-decoration:underline}.kj-md-code{font-family:ui-monospace,monospace;background:color-mix(in srgb,currentColor 12%,transparent);padding:.1em .35em;border-radius:var(--kj-radius-field);font-size:.9em}.kj-chat-code{border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);overflow:hidden;margin:var(--kj-space-xs) 0;background:var(--kj-bg-body)}.kj-chat-code__bar{display:flex;align-items:center;justify-content:space-between;padding:.25rem var(--kj-space-sm);background:var(--kj-bg-surface);border-bottom:1px solid var(--kj-border-default);font-size:var(--kj-text-sm);color:var(--kj-fg-muted)}.kj-chat-code__copy{min-height:1.75rem;padding:.25rem .6rem;border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);background:var(--kj-bg-body);color:var(--kj-fg-default);font-size:var(--kj-text-sm);cursor:pointer}.kj-chat-code__copy:hover{background:var(--kj-bg-surface)}.kj-chat-code__copy:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-chat-code__pre{margin:0;padding:var(--kj-space-sm);overflow-x:auto;font-family:ui-monospace,monospace;font-size:.9em;color:var(--kj-fg-default)}.kj-chat-tool{display:flex;align-items:center;gap:var(--kj-space-xs);padding:.35rem var(--kj-space-sm);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);background:var(--kj-bg-body);font-size:var(--kj-text-sm)}.kj-chat-tool__name{font-weight:600;font-family:ui-monospace,monospace}.kj-chat-tool__status{margin-inline-start:auto;color:var(--kj-fg-muted);text-transform:capitalize}.kj-chat-tool[data-status=error]{border-color:var(--kj-border-danger)}.kj-chat-tool[data-status=error] .kj-chat-tool__status,.kj-chat-tool__error{color:var(--kj-fg-danger)}.kj-chat-cites{list-style:none;margin:var(--kj-space-xs) 0 0;padding:0;display:flex;flex-wrap:wrap;gap:var(--kj-space-xs)}.kj-chat-cite{display:inline-flex;align-items:baseline;gap:.35rem;padding:.15rem .5rem;border:1px solid var(--kj-border-default);border-radius:999px;font-size:var(--kj-text-sm);background:var(--kj-bg-body)}.kj-chat-cite__link{color:var(--kj-fg-info);text-decoration:none}.kj-chat-cite__link:hover{text-decoration:underline}.kj-chat-cite__snippet{color:var(--kj-fg-muted)}.kj-chat-typing{display:inline-flex;gap:.25rem;align-items:center;padding:.25rem 0}.kj-chat-typing__dot{width:.5rem;height:.5rem;border-radius:50%;background:var(--kj-fg-muted);animation:kj-chat-bounce 1.2s infinite ease-in-out both}.kj-chat-typing__dot:nth-child(2){animation-delay:.15s}.kj-chat-typing__dot:nth-child(3){animation-delay:.3s}@keyframes kj-chat-bounce{0%,80%,to{transform:scale(.5);opacity:.4}40%{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.kj-chat-typing__dot{animation:none;opacity:.6}}.kj-prompt{position:relative;display:flex;align-items:flex-end;gap:var(--kj-space-sm);padding:var(--kj-space-sm);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-box);background:var(--kj-bg-field, var(--kj-input-bg))}.kj-prompt:focus-within{border-color:var(--kj-border-focus)}.kj-prompt__textarea{flex:1 1 auto;resize:none;border:none;outline:none;background:transparent;color:var(--kj-input-fg, var(--kj-fg-default));font-family:var(--kj-font-sans);font-size:var(--kj-input-font-size, 1rem);line-height:1.5;max-height:200px;overflow-y:auto}.kj-prompt__textarea::placeholder{color:var(--kj-input-placeholder-fg, var(--kj-fg-muted))}.kj-prompt__actions{display:flex;align-items:center;gap:var(--kj-space-xs);flex:0 0 auto}.kj-prompt__btn{display:grid;place-items:center;width:2.75rem;height:2.75rem;border-radius:50%;border:none;cursor:pointer;font-size:1.1rem}.kj-prompt__btn:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-prompt__btn--send{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-prompt__btn--send:disabled{opacity:.5;cursor:not-allowed}.kj-prompt__btn--stop{background:var(--kj-bg-danger);color:var(--kj-fg-on-danger)}.kj-prompt__slash{position:absolute;bottom:calc(100% + .25rem);left:0;right:0;margin:0;padding:.25rem;list-style:none;background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);box-shadow:0 4px 16px #00000026;max-height:14rem;overflow-y:auto;z-index:10}.kj-prompt__slash-item{display:flex;flex-direction:column;gap:.1rem;padding:var(--kj-space-xs) var(--kj-space-sm);border-radius:var(--kj-radius-field);cursor:pointer}.kj-prompt__slash-item.is-active,.kj-prompt__slash-item:hover{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-prompt__slash-name{font-family:ui-monospace,monospace;font-weight:600}.kj-prompt__slash-desc{font-size:var(--kj-text-sm);color:var(--kj-fg-muted)}.kj-prompt__slash-item.is-active .kj-prompt__slash-desc,.kj-prompt__slash-item:hover .kj-prompt__slash-desc{color:inherit}}\n"] }]
|
|
3238
|
+
}], propDecorators: { message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: true }] }] } });
|
|
3239
|
+
|
|
3240
|
+
/**
|
|
3241
|
+
* The AI thread surface: a scrollable message log driven by a {@link KjChatStore}.
|
|
3242
|
+
*
|
|
3243
|
+
* **Reuses `KjChatLog`** (core) for the `role="log"` message-log container, but
|
|
3244
|
+
* sets `kjChatLogLive="off"` because streamed tokens mutate an *existing*
|
|
3245
|
+
* message node — announcing every mutation would spam AT. Instead a single
|
|
3246
|
+
* dedicated **visually-hidden `aria-live="polite"` region** carries
|
|
3247
|
+
* announcements, fed by {@link KjChatAnnouncer}'s **coalescer** so the reply is
|
|
3248
|
+
* announced as whole sentences (never char-by-char, never duplicated). This is
|
|
3249
|
+
* the kit's accessibility differentiator.
|
|
3250
|
+
*
|
|
3251
|
+
* Provider-agnostic: pair with `KjPromptInput` and drive `KjChatStore` from any
|
|
3252
|
+
* model / stream — the kit ships **no** LLM SDK or backend.
|
|
3253
|
+
*
|
|
3254
|
+
* @doc-example Streaming (simulated)
|
|
3255
|
+
* A full send → simulated-stream → reply loop with slash commands, a Stop
|
|
3256
|
+
* button, tool-call cards and citations. No backend — a fake token generator
|
|
3257
|
+
* feeds the store on a timer.
|
|
3258
|
+
* @doc-file ai-chat.example.ts
|
|
2576
3259
|
*
|
|
2577
3260
|
* @doc-keyboard
|
|
2578
|
-
*
|
|
2579
|
-
*
|
|
3261
|
+
* Enter — Send the message
|
|
3262
|
+
* Shift+Enter — Insert a newline
|
|
3263
|
+
* Esc — Stop generating (while streaming) / close the slash menu
|
|
3264
|
+
* ArrowUp/Down — Move the slash-command selection
|
|
2580
3265
|
*
|
|
2581
3266
|
* @doc-aria
|
|
2582
|
-
* role
|
|
2583
|
-
* aria-
|
|
2584
|
-
*
|
|
2585
|
-
*
|
|
2586
|
-
* data-disabled — Mirrors the disabled posture for theme/scope hooks
|
|
2587
|
-
* data-indeterminate — Reflects the indeterminate posture for the dash glyph
|
|
3267
|
+
* role — `log` on the thread container (reuses `KjChatLog`)
|
|
3268
|
+
* aria-live — `off` on the visible log; a dedicated visually-hidden
|
|
3269
|
+
* `polite` region carries coalesced sentence announcements
|
|
3270
|
+
* article — each message is an `article` (via `KjChat`) named by its role
|
|
2588
3271
|
*
|
|
2589
|
-
* @doc-
|
|
2590
|
-
*
|
|
2591
|
-
*
|
|
3272
|
+
* @doc-a11y
|
|
3273
|
+
* Streaming replies are announced by a coalesced polite live region on
|
|
3274
|
+
* sentence boundaries — never char-by-char — so screen-reader users hear
|
|
3275
|
+
* whole sentences once each. Keyboard send/stop, reduced-motion typing dots,
|
|
3276
|
+
* and ≥44px controls complete the AAA story.
|
|
3277
|
+
*
|
|
3278
|
+
* @doc-related chat,command-palette,textarea
|
|
3279
|
+
*
|
|
3280
|
+
* @doc-category Library/AI
|
|
3281
|
+
* @doc
|
|
3282
|
+
* @doc-name ai-chat
|
|
3283
|
+
* @doc-is-main
|
|
3284
|
+
* @doc-description Provider-agnostic AI chat thread with streaming append, coalesced live-region announcements, slash commands, tool-call cards, and citations.
|
|
3285
|
+
*/
|
|
3286
|
+
class KjChatThread {
|
|
3287
|
+
/** The store driving this thread. */
|
|
3288
|
+
store = input.required(/* @ts-ignore */
|
|
3289
|
+
...(ngDevMode ? [{ debugName: "store" }] : /* istanbul ignore next */ []));
|
|
3290
|
+
/** Accessible label for the log landmark. */
|
|
3291
|
+
kjLabel = input('Conversation', /* @ts-ignore */
|
|
3292
|
+
...(ngDevMode ? [{ debugName: "kjLabel" }] : /* istanbul ignore next */ []));
|
|
3293
|
+
/** @internal — the coalescing announcer for the polite live region. */
|
|
3294
|
+
announcer = inject(KjChatAnnouncer);
|
|
3295
|
+
injector = inject(Injector);
|
|
3296
|
+
logEl = viewChild.required('log');
|
|
3297
|
+
lastId = null;
|
|
3298
|
+
lastLen = 0;
|
|
3299
|
+
prevStatus = null;
|
|
3300
|
+
constructor() {
|
|
3301
|
+
// Feed streamed deltas into the coalescer and manage flush/error/scroll.
|
|
3302
|
+
effect(() => {
|
|
3303
|
+
const store = this.store();
|
|
3304
|
+
const msgs = store.messages();
|
|
3305
|
+
const sid = store.streamingId();
|
|
3306
|
+
const status = store.status();
|
|
3307
|
+
untracked(() => {
|
|
3308
|
+
// New stream started — reset the delta cursor.
|
|
3309
|
+
if (sid !== this.lastId) {
|
|
3310
|
+
this.lastId = sid;
|
|
3311
|
+
this.lastLen = 0;
|
|
3312
|
+
}
|
|
3313
|
+
// Push the newly-arrived text delta to the coalescer.
|
|
3314
|
+
if (sid) {
|
|
3315
|
+
const m = msgs.find((x) => x.id === sid);
|
|
3316
|
+
if (m) {
|
|
3317
|
+
const delta = m.content.slice(this.lastLen);
|
|
3318
|
+
this.lastLen = m.content.length;
|
|
3319
|
+
if (delta)
|
|
3320
|
+
this.announcer.push(delta);
|
|
3321
|
+
}
|
|
3322
|
+
}
|
|
3323
|
+
// Status transitions: flush remainder on completion, announce errors.
|
|
3324
|
+
if (this.prevStatus === 'streaming' && status !== 'streaming') {
|
|
3325
|
+
this.announcer.flush();
|
|
3326
|
+
if (status === 'error')
|
|
3327
|
+
this.announcer.announce('Response failed.');
|
|
3328
|
+
}
|
|
3329
|
+
this.prevStatus = status;
|
|
3330
|
+
this.scrollToBottom();
|
|
3331
|
+
});
|
|
3332
|
+
});
|
|
3333
|
+
}
|
|
3334
|
+
scrollToBottom() {
|
|
3335
|
+
afterNextRender(() => {
|
|
3336
|
+
const el = this.logEl().nativeElement;
|
|
3337
|
+
el.scrollTop = el.scrollHeight;
|
|
3338
|
+
}, { injector: this.injector });
|
|
3339
|
+
}
|
|
3340
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjChatThread, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3341
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: KjChatThread, isStandalone: true, selector: "kj-chat-thread", inputs: { store: { classPropertyName: "store", publicName: "store", isSignal: true, isRequired: true, transformFunction: null }, kjLabel: { classPropertyName: "kjLabel", publicName: "kjLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "kj-chat-thread-host" }, providers: [KjChatAnnouncer], viewQueries: [{ propertyName: "logEl", first: true, predicate: ["log"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
3342
|
+
<div #log kjChatLog kjChatLogLive="off" class="kj-chat-thread" [kjChatLogLabel]="kjLabel()">
|
|
3343
|
+
@for (m of store().messages(); track m.id) {
|
|
3344
|
+
<kj-chat-message [message]="m" />
|
|
3345
|
+
}
|
|
3346
|
+
</div>
|
|
3347
|
+
|
|
3348
|
+
<!-- Coalesced polite announcer: whole sentences, debounced by boundary. -->
|
|
3349
|
+
<div class="kj-visually-hidden" aria-live="polite" aria-atomic="false">
|
|
3350
|
+
{{ announcer.message() }}
|
|
3351
|
+
</div>
|
|
3352
|
+
`, isInline: true, styles: ["@layer kj.component{.kj-visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.kj-chat-thread{display:flex;flex-direction:column;gap:var(--kj-space-md);padding:var(--kj-space-md);background:var(--kj-bg-body);color:var(--kj-fg-default);border-radius:var(--kj-radius-box);overflow-y:auto;font-family:var(--kj-font-sans)}.kj-chat-msg{display:flex;gap:var(--kj-space-sm);align-items:flex-start;max-width:100%}.kj-chat-msg[data-side=end]{flex-direction:row-reverse;margin-inline-start:auto}.kj-chat-msg[data-role=system]{justify-content:center}.kj-chat-msg__avatar{flex:0 0 auto;width:2rem;height:2rem;border-radius:50%;display:grid;place-items:center;font-size:var(--kj-text-sm);font-weight:600;background:var(--kj-bg-surface);color:var(--kj-fg-default);border:1px solid var(--kj-border-default)}.kj-chat-msg__bubble{display:flex;flex-direction:column;gap:var(--kj-space-xs);padding:var(--kj-space-sm) var(--kj-space-md);border-radius:var(--kj-radius-box);background:var(--kj-bg-surface);color:var(--kj-fg-default);max-width:min(48rem,100%);overflow-wrap:anywhere}.kj-chat-msg[data-role=user] .kj-chat-msg__bubble{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-chat-msg[data-role=system] .kj-chat-msg__bubble{background:transparent;color:var(--kj-fg-muted);font-size:var(--kj-text-sm);text-align:center;padding-block:var(--kj-space-xs)}.kj-chat-msg__body :is(p){margin:0 0 var(--kj-space-xs)}.kj-chat-msg__body :is(p):last-child{margin-bottom:0}.kj-chat-msg__error{margin:0;color:var(--kj-fg-danger);font-size:var(--kj-text-sm)}.kj-md-link{color:inherit;text-decoration:underline}.kj-md-code{font-family:ui-monospace,monospace;background:color-mix(in srgb,currentColor 12%,transparent);padding:.1em .35em;border-radius:var(--kj-radius-field);font-size:.9em}.kj-chat-code{border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);overflow:hidden;margin:var(--kj-space-xs) 0;background:var(--kj-bg-body)}.kj-chat-code__bar{display:flex;align-items:center;justify-content:space-between;padding:.25rem var(--kj-space-sm);background:var(--kj-bg-surface);border-bottom:1px solid var(--kj-border-default);font-size:var(--kj-text-sm);color:var(--kj-fg-muted)}.kj-chat-code__copy{min-height:1.75rem;padding:.25rem .6rem;border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);background:var(--kj-bg-body);color:var(--kj-fg-default);font-size:var(--kj-text-sm);cursor:pointer}.kj-chat-code__copy:hover{background:var(--kj-bg-surface)}.kj-chat-code__copy:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-chat-code__pre{margin:0;padding:var(--kj-space-sm);overflow-x:auto;font-family:ui-monospace,monospace;font-size:.9em;color:var(--kj-fg-default)}.kj-chat-tool{display:flex;align-items:center;gap:var(--kj-space-xs);padding:.35rem var(--kj-space-sm);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);background:var(--kj-bg-body);font-size:var(--kj-text-sm)}.kj-chat-tool__name{font-weight:600;font-family:ui-monospace,monospace}.kj-chat-tool__status{margin-inline-start:auto;color:var(--kj-fg-muted);text-transform:capitalize}.kj-chat-tool[data-status=error]{border-color:var(--kj-border-danger)}.kj-chat-tool[data-status=error] .kj-chat-tool__status,.kj-chat-tool__error{color:var(--kj-fg-danger)}.kj-chat-cites{list-style:none;margin:var(--kj-space-xs) 0 0;padding:0;display:flex;flex-wrap:wrap;gap:var(--kj-space-xs)}.kj-chat-cite{display:inline-flex;align-items:baseline;gap:.35rem;padding:.15rem .5rem;border:1px solid var(--kj-border-default);border-radius:999px;font-size:var(--kj-text-sm);background:var(--kj-bg-body)}.kj-chat-cite__link{color:var(--kj-fg-info);text-decoration:none}.kj-chat-cite__link:hover{text-decoration:underline}.kj-chat-cite__snippet{color:var(--kj-fg-muted)}.kj-chat-typing{display:inline-flex;gap:.25rem;align-items:center;padding:.25rem 0}.kj-chat-typing__dot{width:.5rem;height:.5rem;border-radius:50%;background:var(--kj-fg-muted);animation:kj-chat-bounce 1.2s infinite ease-in-out both}.kj-chat-typing__dot:nth-child(2){animation-delay:.15s}.kj-chat-typing__dot:nth-child(3){animation-delay:.3s}@keyframes kj-chat-bounce{0%,80%,to{transform:scale(.5);opacity:.4}40%{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.kj-chat-typing__dot{animation:none;opacity:.6}}.kj-prompt{position:relative;display:flex;align-items:flex-end;gap:var(--kj-space-sm);padding:var(--kj-space-sm);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-box);background:var(--kj-bg-field, var(--kj-input-bg))}.kj-prompt:focus-within{border-color:var(--kj-border-focus)}.kj-prompt__textarea{flex:1 1 auto;resize:none;border:none;outline:none;background:transparent;color:var(--kj-input-fg, var(--kj-fg-default));font-family:var(--kj-font-sans);font-size:var(--kj-input-font-size, 1rem);line-height:1.5;max-height:200px;overflow-y:auto}.kj-prompt__textarea::placeholder{color:var(--kj-input-placeholder-fg, var(--kj-fg-muted))}.kj-prompt__actions{display:flex;align-items:center;gap:var(--kj-space-xs);flex:0 0 auto}.kj-prompt__btn{display:grid;place-items:center;width:2.75rem;height:2.75rem;border-radius:50%;border:none;cursor:pointer;font-size:1.1rem}.kj-prompt__btn:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-prompt__btn--send{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-prompt__btn--send:disabled{opacity:.5;cursor:not-allowed}.kj-prompt__btn--stop{background:var(--kj-bg-danger);color:var(--kj-fg-on-danger)}.kj-prompt__slash{position:absolute;bottom:calc(100% + .25rem);left:0;right:0;margin:0;padding:.25rem;list-style:none;background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);box-shadow:0 4px 16px #00000026;max-height:14rem;overflow-y:auto;z-index:10}.kj-prompt__slash-item{display:flex;flex-direction:column;gap:.1rem;padding:var(--kj-space-xs) var(--kj-space-sm);border-radius:var(--kj-radius-field);cursor:pointer}.kj-prompt__slash-item.is-active,.kj-prompt__slash-item:hover{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-prompt__slash-name{font-family:ui-monospace,monospace;font-weight:600}.kj-prompt__slash-desc{font-size:var(--kj-text-sm);color:var(--kj-fg-muted)}.kj-prompt__slash-item.is-active .kj-prompt__slash-desc,.kj-prompt__slash-item:hover .kj-prompt__slash-desc{color:inherit}}\n"], dependencies: [{ kind: "directive", type: KjChatLog, selector: "[kjChatLog]", inputs: ["kjChatLogLive", "kjChatLogLabel"] }, { kind: "component", type: KjChatMessage, selector: "kj-chat-message", inputs: ["message"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
3353
|
+
}
|
|
3354
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjChatThread, decorators: [{
|
|
3355
|
+
type: Component,
|
|
3356
|
+
args: [{ selector: 'kj-chat-thread', standalone: true, imports: [KjChatLog, KjChatMessage], providers: [KjChatAnnouncer], template: `
|
|
3357
|
+
<div #log kjChatLog kjChatLogLive="off" class="kj-chat-thread" [kjChatLogLabel]="kjLabel()">
|
|
3358
|
+
@for (m of store().messages(); track m.id) {
|
|
3359
|
+
<kj-chat-message [message]="m" />
|
|
3360
|
+
}
|
|
3361
|
+
</div>
|
|
3362
|
+
|
|
3363
|
+
<!-- Coalesced polite announcer: whole sentences, debounced by boundary. -->
|
|
3364
|
+
<div class="kj-visually-hidden" aria-live="polite" aria-atomic="false">
|
|
3365
|
+
{{ announcer.message() }}
|
|
3366
|
+
</div>
|
|
3367
|
+
`, encapsulation: ViewEncapsulation.None, host: { class: 'kj-chat-thread-host' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.kj-chat-thread{display:flex;flex-direction:column;gap:var(--kj-space-md);padding:var(--kj-space-md);background:var(--kj-bg-body);color:var(--kj-fg-default);border-radius:var(--kj-radius-box);overflow-y:auto;font-family:var(--kj-font-sans)}.kj-chat-msg{display:flex;gap:var(--kj-space-sm);align-items:flex-start;max-width:100%}.kj-chat-msg[data-side=end]{flex-direction:row-reverse;margin-inline-start:auto}.kj-chat-msg[data-role=system]{justify-content:center}.kj-chat-msg__avatar{flex:0 0 auto;width:2rem;height:2rem;border-radius:50%;display:grid;place-items:center;font-size:var(--kj-text-sm);font-weight:600;background:var(--kj-bg-surface);color:var(--kj-fg-default);border:1px solid var(--kj-border-default)}.kj-chat-msg__bubble{display:flex;flex-direction:column;gap:var(--kj-space-xs);padding:var(--kj-space-sm) var(--kj-space-md);border-radius:var(--kj-radius-box);background:var(--kj-bg-surface);color:var(--kj-fg-default);max-width:min(48rem,100%);overflow-wrap:anywhere}.kj-chat-msg[data-role=user] .kj-chat-msg__bubble{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-chat-msg[data-role=system] .kj-chat-msg__bubble{background:transparent;color:var(--kj-fg-muted);font-size:var(--kj-text-sm);text-align:center;padding-block:var(--kj-space-xs)}.kj-chat-msg__body :is(p){margin:0 0 var(--kj-space-xs)}.kj-chat-msg__body :is(p):last-child{margin-bottom:0}.kj-chat-msg__error{margin:0;color:var(--kj-fg-danger);font-size:var(--kj-text-sm)}.kj-md-link{color:inherit;text-decoration:underline}.kj-md-code{font-family:ui-monospace,monospace;background:color-mix(in srgb,currentColor 12%,transparent);padding:.1em .35em;border-radius:var(--kj-radius-field);font-size:.9em}.kj-chat-code{border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);overflow:hidden;margin:var(--kj-space-xs) 0;background:var(--kj-bg-body)}.kj-chat-code__bar{display:flex;align-items:center;justify-content:space-between;padding:.25rem var(--kj-space-sm);background:var(--kj-bg-surface);border-bottom:1px solid var(--kj-border-default);font-size:var(--kj-text-sm);color:var(--kj-fg-muted)}.kj-chat-code__copy{min-height:1.75rem;padding:.25rem .6rem;border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);background:var(--kj-bg-body);color:var(--kj-fg-default);font-size:var(--kj-text-sm);cursor:pointer}.kj-chat-code__copy:hover{background:var(--kj-bg-surface)}.kj-chat-code__copy:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-chat-code__pre{margin:0;padding:var(--kj-space-sm);overflow-x:auto;font-family:ui-monospace,monospace;font-size:.9em;color:var(--kj-fg-default)}.kj-chat-tool{display:flex;align-items:center;gap:var(--kj-space-xs);padding:.35rem var(--kj-space-sm);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);background:var(--kj-bg-body);font-size:var(--kj-text-sm)}.kj-chat-tool__name{font-weight:600;font-family:ui-monospace,monospace}.kj-chat-tool__status{margin-inline-start:auto;color:var(--kj-fg-muted);text-transform:capitalize}.kj-chat-tool[data-status=error]{border-color:var(--kj-border-danger)}.kj-chat-tool[data-status=error] .kj-chat-tool__status,.kj-chat-tool__error{color:var(--kj-fg-danger)}.kj-chat-cites{list-style:none;margin:var(--kj-space-xs) 0 0;padding:0;display:flex;flex-wrap:wrap;gap:var(--kj-space-xs)}.kj-chat-cite{display:inline-flex;align-items:baseline;gap:.35rem;padding:.15rem .5rem;border:1px solid var(--kj-border-default);border-radius:999px;font-size:var(--kj-text-sm);background:var(--kj-bg-body)}.kj-chat-cite__link{color:var(--kj-fg-info);text-decoration:none}.kj-chat-cite__link:hover{text-decoration:underline}.kj-chat-cite__snippet{color:var(--kj-fg-muted)}.kj-chat-typing{display:inline-flex;gap:.25rem;align-items:center;padding:.25rem 0}.kj-chat-typing__dot{width:.5rem;height:.5rem;border-radius:50%;background:var(--kj-fg-muted);animation:kj-chat-bounce 1.2s infinite ease-in-out both}.kj-chat-typing__dot:nth-child(2){animation-delay:.15s}.kj-chat-typing__dot:nth-child(3){animation-delay:.3s}@keyframes kj-chat-bounce{0%,80%,to{transform:scale(.5);opacity:.4}40%{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.kj-chat-typing__dot{animation:none;opacity:.6}}.kj-prompt{position:relative;display:flex;align-items:flex-end;gap:var(--kj-space-sm);padding:var(--kj-space-sm);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-box);background:var(--kj-bg-field, var(--kj-input-bg))}.kj-prompt:focus-within{border-color:var(--kj-border-focus)}.kj-prompt__textarea{flex:1 1 auto;resize:none;border:none;outline:none;background:transparent;color:var(--kj-input-fg, var(--kj-fg-default));font-family:var(--kj-font-sans);font-size:var(--kj-input-font-size, 1rem);line-height:1.5;max-height:200px;overflow-y:auto}.kj-prompt__textarea::placeholder{color:var(--kj-input-placeholder-fg, var(--kj-fg-muted))}.kj-prompt__actions{display:flex;align-items:center;gap:var(--kj-space-xs);flex:0 0 auto}.kj-prompt__btn{display:grid;place-items:center;width:2.75rem;height:2.75rem;border-radius:50%;border:none;cursor:pointer;font-size:1.1rem}.kj-prompt__btn:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-prompt__btn--send{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-prompt__btn--send:disabled{opacity:.5;cursor:not-allowed}.kj-prompt__btn--stop{background:var(--kj-bg-danger);color:var(--kj-fg-on-danger)}.kj-prompt__slash{position:absolute;bottom:calc(100% + .25rem);left:0;right:0;margin:0;padding:.25rem;list-style:none;background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);box-shadow:0 4px 16px #00000026;max-height:14rem;overflow-y:auto;z-index:10}.kj-prompt__slash-item{display:flex;flex-direction:column;gap:.1rem;padding:var(--kj-space-xs) var(--kj-space-sm);border-radius:var(--kj-radius-field);cursor:pointer}.kj-prompt__slash-item.is-active,.kj-prompt__slash-item:hover{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-prompt__slash-name{font-family:ui-monospace,monospace;font-weight:600}.kj-prompt__slash-desc{font-size:var(--kj-text-sm);color:var(--kj-fg-muted)}.kj-prompt__slash-item.is-active .kj-prompt__slash-desc,.kj-prompt__slash-item:hover .kj-prompt__slash-desc{color:inherit}}\n"] }]
|
|
3368
|
+
}], ctorParameters: () => [], propDecorators: { store: [{ type: i0.Input, args: [{ isSignal: true, alias: "store", required: true }] }], kjLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjLabel", required: false }] }], logEl: [{ type: i0.ViewChild, args: ['log', { isSignal: true }] }] } });
|
|
3369
|
+
|
|
3370
|
+
let _promptId = 0;
|
|
3371
|
+
/**
|
|
3372
|
+
* Prompt composer for an AI thread: an auto-growing textarea with send / stop
|
|
3373
|
+
* controls, an optional attachment slot (`[kjPromptAttachments]`), and a
|
|
3374
|
+
* slash-command menu.
|
|
3375
|
+
*
|
|
3376
|
+
* **Keyboard:** `Enter` sends, `Shift+Enter` inserts a newline, `Esc` stops the
|
|
3377
|
+
* stream (when streaming) or closes the slash menu; `↑/↓` move the slash
|
|
3378
|
+
* selection and `Enter` picks it. The menu is a `role="listbox"`; the textarea
|
|
3379
|
+
* keeps DOM focus and points `aria-activedescendant` at the active option.
|
|
3380
|
+
*
|
|
3381
|
+
* **Slash matching reuses the command-palette engine** via
|
|
3382
|
+
* `matchSlashCommands` (backed by the palette's `kjSubstringFilter`).
|
|
3383
|
+
*
|
|
3384
|
+
* @doc
|
|
3385
|
+
* @doc-name ai-chat
|
|
3386
|
+
*/
|
|
3387
|
+
class KjPromptInput {
|
|
3388
|
+
uid = ++_promptId;
|
|
3389
|
+
textareaId = `kj-prompt-${this.uid}`;
|
|
3390
|
+
listboxId = `kj-prompt-slash-${this.uid}`;
|
|
3391
|
+
/** Two-way bound draft text. */
|
|
3392
|
+
kjValue = model('', /* @ts-ignore */
|
|
3393
|
+
...(ngDevMode ? [{ debugName: "kjValue" }] : /* istanbul ignore next */ []));
|
|
3394
|
+
/** Placeholder text. */
|
|
3395
|
+
kjPlaceholder = input('Message the assistant…', /* @ts-ignore */
|
|
3396
|
+
...(ngDevMode ? [{ debugName: "kjPlaceholder" }] : /* istanbul ignore next */ []));
|
|
3397
|
+
/** Accessible label for the textarea. */
|
|
3398
|
+
kjLabel = input('Message', /* @ts-ignore */
|
|
3399
|
+
...(ngDevMode ? [{ debugName: "kjLabel" }] : /* istanbul ignore next */ []));
|
|
3400
|
+
/** When true, show the Stop button instead of Send. */
|
|
3401
|
+
kjStreaming = input(false, /* @ts-ignore */
|
|
3402
|
+
...(ngDevMode ? [{ debugName: "kjStreaming" }] : /* istanbul ignore next */ []));
|
|
3403
|
+
/** Disable the composer entirely. */
|
|
3404
|
+
kjDisabled = input(false, /* @ts-ignore */
|
|
3405
|
+
...(ngDevMode ? [{ debugName: "kjDisabled" }] : /* istanbul ignore next */ []));
|
|
3406
|
+
/** Available slash commands. */
|
|
3407
|
+
kjSlashCommands = input([], /* @ts-ignore */
|
|
3408
|
+
...(ngDevMode ? [{ debugName: "kjSlashCommands" }] : /* istanbul ignore next */ []));
|
|
3409
|
+
/** Emits the trimmed message text on send. */
|
|
3410
|
+
kjSend = output();
|
|
3411
|
+
/** Emits when the user requests a stop. */
|
|
3412
|
+
kjStop = output();
|
|
3413
|
+
/** Emits the picked slash command. */
|
|
3414
|
+
kjSlashSelect = output();
|
|
3415
|
+
ta = viewChild.required('ta');
|
|
3416
|
+
_active = signal(0, /* @ts-ignore */
|
|
3417
|
+
...(ngDevMode ? [{ debugName: "_active" }] : /* istanbul ignore next */ []));
|
|
3418
|
+
activeIndex = this._active.asReadonly();
|
|
3419
|
+
slash = computed(() => parseSlash(this.kjValue()), /* @ts-ignore */
|
|
3420
|
+
...(ngDevMode ? [{ debugName: "slash" }] : /* istanbul ignore next */ []));
|
|
3421
|
+
slashMatches = computed(() => {
|
|
3422
|
+
const s = this.slash();
|
|
3423
|
+
if (!s.active)
|
|
3424
|
+
return [];
|
|
3425
|
+
return matchSlashCommands(s.query, this.kjSlashCommands());
|
|
3426
|
+
}, /* @ts-ignore */
|
|
3427
|
+
...(ngDevMode ? [{ debugName: "slashMatches" }] : /* istanbul ignore next */ []));
|
|
3428
|
+
slashOpen = computed(() => this.slashMatches().length > 0, /* @ts-ignore */
|
|
3429
|
+
...(ngDevMode ? [{ debugName: "slashOpen" }] : /* istanbul ignore next */ []));
|
|
3430
|
+
constructor() {
|
|
3431
|
+
// Keep the active index in range as matches change.
|
|
3432
|
+
effect(() => {
|
|
3433
|
+
const n = this.slashMatches().length;
|
|
3434
|
+
if (this._active() >= n)
|
|
3435
|
+
this._active.set(0);
|
|
3436
|
+
});
|
|
3437
|
+
// Auto-grow whenever the value changes (incl. programmatic resets).
|
|
3438
|
+
effect(() => {
|
|
3439
|
+
this.kjValue();
|
|
3440
|
+
queueMicrotask(() => this.autogrow());
|
|
3441
|
+
});
|
|
3442
|
+
}
|
|
3443
|
+
optionId(i) {
|
|
3444
|
+
return `${this.listboxId}-opt-${i}`;
|
|
3445
|
+
}
|
|
3446
|
+
onInput(ev) {
|
|
3447
|
+
this.kjValue.set(ev.target.value);
|
|
3448
|
+
this.autogrow();
|
|
3449
|
+
}
|
|
3450
|
+
onKeydown(ev) {
|
|
3451
|
+
if (this.slashOpen()) {
|
|
3452
|
+
if (ev.key === 'ArrowDown') {
|
|
3453
|
+
ev.preventDefault();
|
|
3454
|
+
this._active.update((i) => (i + 1) % this.slashMatches().length);
|
|
3455
|
+
return;
|
|
3456
|
+
}
|
|
3457
|
+
if (ev.key === 'ArrowUp') {
|
|
3458
|
+
ev.preventDefault();
|
|
3459
|
+
const n = this.slashMatches().length;
|
|
3460
|
+
this._active.update((i) => (i - 1 + n) % n);
|
|
3461
|
+
return;
|
|
3462
|
+
}
|
|
3463
|
+
if (ev.key === 'Enter') {
|
|
3464
|
+
ev.preventDefault();
|
|
3465
|
+
const cmd = this.slashMatches()[this._active()];
|
|
3466
|
+
if (cmd)
|
|
3467
|
+
this.commitSlash(cmd);
|
|
3468
|
+
return;
|
|
3469
|
+
}
|
|
3470
|
+
if (ev.key === 'Escape') {
|
|
3471
|
+
ev.preventDefault();
|
|
3472
|
+
// Close the menu by clearing the in-progress slash token.
|
|
3473
|
+
this.kjValue.set('');
|
|
3474
|
+
return;
|
|
3475
|
+
}
|
|
3476
|
+
}
|
|
3477
|
+
if (ev.key === 'Enter' && !ev.shiftKey) {
|
|
3478
|
+
ev.preventDefault();
|
|
3479
|
+
this.send();
|
|
3480
|
+
return;
|
|
3481
|
+
}
|
|
3482
|
+
if (ev.key === 'Escape' && this.kjStreaming()) {
|
|
3483
|
+
ev.preventDefault();
|
|
3484
|
+
this.onStop();
|
|
3485
|
+
}
|
|
3486
|
+
}
|
|
3487
|
+
onSubmit(ev) {
|
|
3488
|
+
ev.preventDefault();
|
|
3489
|
+
this.send();
|
|
3490
|
+
}
|
|
3491
|
+
onStop() {
|
|
3492
|
+
this.kjStop.emit();
|
|
3493
|
+
}
|
|
3494
|
+
pickSlash(ev, cmd) {
|
|
3495
|
+
ev.preventDefault(); // keep textarea focus
|
|
3496
|
+
this.commitSlash(cmd);
|
|
3497
|
+
}
|
|
3498
|
+
commitSlash(cmd) {
|
|
3499
|
+
this.kjSlashSelect.emit(cmd);
|
|
3500
|
+
this.kjValue.set(cmd.name + ' ');
|
|
3501
|
+
this.ta().nativeElement.focus();
|
|
3502
|
+
}
|
|
3503
|
+
send() {
|
|
3504
|
+
const text = this.kjValue().trim();
|
|
3505
|
+
if (!text || this.kjDisabled() || this.kjStreaming())
|
|
3506
|
+
return;
|
|
3507
|
+
this.kjSend.emit(text);
|
|
3508
|
+
this.kjValue.set('');
|
|
3509
|
+
this.autogrow();
|
|
3510
|
+
}
|
|
3511
|
+
autogrow() {
|
|
3512
|
+
const el = this.ta().nativeElement;
|
|
3513
|
+
el.style.height = 'auto';
|
|
3514
|
+
el.style.height = `${Math.min(el.scrollHeight, 200)}px`;
|
|
3515
|
+
}
|
|
3516
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjPromptInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3517
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: KjPromptInput, isStandalone: true, selector: "kj-prompt-input", inputs: { kjValue: { classPropertyName: "kjValue", publicName: "kjValue", isSignal: true, isRequired: false, transformFunction: null }, kjPlaceholder: { classPropertyName: "kjPlaceholder", publicName: "kjPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, kjLabel: { classPropertyName: "kjLabel", publicName: "kjLabel", isSignal: true, isRequired: false, transformFunction: null }, kjStreaming: { classPropertyName: "kjStreaming", publicName: "kjStreaming", isSignal: true, isRequired: false, transformFunction: null }, kjDisabled: { classPropertyName: "kjDisabled", publicName: "kjDisabled", isSignal: true, isRequired: false, transformFunction: null }, kjSlashCommands: { classPropertyName: "kjSlashCommands", publicName: "kjSlashCommands", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { kjValue: "kjValueChange", kjSend: "kjSend", kjStop: "kjStop", kjSlashSelect: "kjSlashSelect" }, host: { classAttribute: "kj-prompt-host" }, viewQueries: [{ propertyName: "ta", first: true, predicate: ["ta"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
3518
|
+
<form class="kj-prompt" (submit)="onSubmit($event)">
|
|
3519
|
+
@if (slashOpen()) {
|
|
3520
|
+
<ul class="kj-prompt__slash" role="listbox" [id]="listboxId" aria-label="Slash commands">
|
|
3521
|
+
@for (cmd of slashMatches(); track cmd.name; let i = $index) {
|
|
3522
|
+
<li
|
|
3523
|
+
class="kj-prompt__slash-item"
|
|
3524
|
+
role="option"
|
|
3525
|
+
[id]="optionId(i)"
|
|
3526
|
+
[attr.aria-selected]="i === activeIndex()"
|
|
3527
|
+
[class.is-active]="i === activeIndex()"
|
|
3528
|
+
(mousedown)="pickSlash($event, cmd)"
|
|
3529
|
+
>
|
|
3530
|
+
<span class="kj-prompt__slash-name">{{ cmd.name }}</span>
|
|
3531
|
+
@if (cmd.description) {
|
|
3532
|
+
<span class="kj-prompt__slash-desc">{{ cmd.description }}</span>
|
|
3533
|
+
}
|
|
3534
|
+
</li>
|
|
3535
|
+
}
|
|
3536
|
+
</ul>
|
|
3537
|
+
}
|
|
3538
|
+
|
|
3539
|
+
<label class="kj-visually-hidden" [attr.for]="textareaId">{{ kjLabel() }}</label>
|
|
3540
|
+
<textarea
|
|
3541
|
+
#ta
|
|
3542
|
+
class="kj-prompt__textarea"
|
|
3543
|
+
[id]="textareaId"
|
|
3544
|
+
[attr.placeholder]="kjPlaceholder()"
|
|
3545
|
+
[attr.aria-label]="kjLabel()"
|
|
3546
|
+
[attr.role]="slashOpen() ? 'combobox' : null"
|
|
3547
|
+
[attr.aria-expanded]="slashOpen() ? 'true' : null"
|
|
3548
|
+
[attr.aria-controls]="slashOpen() ? listboxId : null"
|
|
3549
|
+
[attr.aria-activedescendant]="slashOpen() ? optionId(activeIndex()) : null"
|
|
3550
|
+
[attr.aria-haspopup]="slashOpen() ? 'listbox' : null"
|
|
3551
|
+
[attr.aria-autocomplete]="slashOpen() ? 'list' : null"
|
|
3552
|
+
[disabled]="kjDisabled()"
|
|
3553
|
+
[value]="kjValue()"
|
|
3554
|
+
rows="1"
|
|
3555
|
+
(input)="onInput($event)"
|
|
3556
|
+
(keydown)="onKeydown($event)"
|
|
3557
|
+
></textarea>
|
|
3558
|
+
|
|
3559
|
+
<div class="kj-prompt__actions">
|
|
3560
|
+
<span class="kj-prompt__attachments">
|
|
3561
|
+
<ng-content select="[kjPromptAttachments]" />
|
|
3562
|
+
</span>
|
|
3563
|
+
@if (kjStreaming()) {
|
|
3564
|
+
<button
|
|
3565
|
+
type="button"
|
|
3566
|
+
class="kj-prompt__btn kj-prompt__btn--stop"
|
|
3567
|
+
aria-label="Stop generating"
|
|
3568
|
+
(click)="onStop()"
|
|
3569
|
+
>
|
|
3570
|
+
<span aria-hidden="true">■</span>
|
|
3571
|
+
</button>
|
|
3572
|
+
} @else {
|
|
3573
|
+
<button
|
|
3574
|
+
type="submit"
|
|
3575
|
+
class="kj-prompt__btn kj-prompt__btn--send"
|
|
3576
|
+
aria-label="Send message"
|
|
3577
|
+
[disabled]="kjDisabled() || kjValue().trim().length === 0"
|
|
3578
|
+
>
|
|
3579
|
+
<span aria-hidden="true">↥</span>
|
|
3580
|
+
</button>
|
|
3581
|
+
}
|
|
3582
|
+
</div>
|
|
3583
|
+
</form>
|
|
3584
|
+
`, isInline: true, styles: ["@layer kj.component{.kj-visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.kj-chat-thread{display:flex;flex-direction:column;gap:var(--kj-space-md);padding:var(--kj-space-md);background:var(--kj-bg-body);color:var(--kj-fg-default);border-radius:var(--kj-radius-box);overflow-y:auto;font-family:var(--kj-font-sans)}.kj-chat-msg{display:flex;gap:var(--kj-space-sm);align-items:flex-start;max-width:100%}.kj-chat-msg[data-side=end]{flex-direction:row-reverse;margin-inline-start:auto}.kj-chat-msg[data-role=system]{justify-content:center}.kj-chat-msg__avatar{flex:0 0 auto;width:2rem;height:2rem;border-radius:50%;display:grid;place-items:center;font-size:var(--kj-text-sm);font-weight:600;background:var(--kj-bg-surface);color:var(--kj-fg-default);border:1px solid var(--kj-border-default)}.kj-chat-msg__bubble{display:flex;flex-direction:column;gap:var(--kj-space-xs);padding:var(--kj-space-sm) var(--kj-space-md);border-radius:var(--kj-radius-box);background:var(--kj-bg-surface);color:var(--kj-fg-default);max-width:min(48rem,100%);overflow-wrap:anywhere}.kj-chat-msg[data-role=user] .kj-chat-msg__bubble{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-chat-msg[data-role=system] .kj-chat-msg__bubble{background:transparent;color:var(--kj-fg-muted);font-size:var(--kj-text-sm);text-align:center;padding-block:var(--kj-space-xs)}.kj-chat-msg__body :is(p){margin:0 0 var(--kj-space-xs)}.kj-chat-msg__body :is(p):last-child{margin-bottom:0}.kj-chat-msg__error{margin:0;color:var(--kj-fg-danger);font-size:var(--kj-text-sm)}.kj-md-link{color:inherit;text-decoration:underline}.kj-md-code{font-family:ui-monospace,monospace;background:color-mix(in srgb,currentColor 12%,transparent);padding:.1em .35em;border-radius:var(--kj-radius-field);font-size:.9em}.kj-chat-code{border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);overflow:hidden;margin:var(--kj-space-xs) 0;background:var(--kj-bg-body)}.kj-chat-code__bar{display:flex;align-items:center;justify-content:space-between;padding:.25rem var(--kj-space-sm);background:var(--kj-bg-surface);border-bottom:1px solid var(--kj-border-default);font-size:var(--kj-text-sm);color:var(--kj-fg-muted)}.kj-chat-code__copy{min-height:1.75rem;padding:.25rem .6rem;border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);background:var(--kj-bg-body);color:var(--kj-fg-default);font-size:var(--kj-text-sm);cursor:pointer}.kj-chat-code__copy:hover{background:var(--kj-bg-surface)}.kj-chat-code__copy:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-chat-code__pre{margin:0;padding:var(--kj-space-sm);overflow-x:auto;font-family:ui-monospace,monospace;font-size:.9em;color:var(--kj-fg-default)}.kj-chat-tool{display:flex;align-items:center;gap:var(--kj-space-xs);padding:.35rem var(--kj-space-sm);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);background:var(--kj-bg-body);font-size:var(--kj-text-sm)}.kj-chat-tool__name{font-weight:600;font-family:ui-monospace,monospace}.kj-chat-tool__status{margin-inline-start:auto;color:var(--kj-fg-muted);text-transform:capitalize}.kj-chat-tool[data-status=error]{border-color:var(--kj-border-danger)}.kj-chat-tool[data-status=error] .kj-chat-tool__status,.kj-chat-tool__error{color:var(--kj-fg-danger)}.kj-chat-cites{list-style:none;margin:var(--kj-space-xs) 0 0;padding:0;display:flex;flex-wrap:wrap;gap:var(--kj-space-xs)}.kj-chat-cite{display:inline-flex;align-items:baseline;gap:.35rem;padding:.15rem .5rem;border:1px solid var(--kj-border-default);border-radius:999px;font-size:var(--kj-text-sm);background:var(--kj-bg-body)}.kj-chat-cite__link{color:var(--kj-fg-info);text-decoration:none}.kj-chat-cite__link:hover{text-decoration:underline}.kj-chat-cite__snippet{color:var(--kj-fg-muted)}.kj-chat-typing{display:inline-flex;gap:.25rem;align-items:center;padding:.25rem 0}.kj-chat-typing__dot{width:.5rem;height:.5rem;border-radius:50%;background:var(--kj-fg-muted);animation:kj-chat-bounce 1.2s infinite ease-in-out both}.kj-chat-typing__dot:nth-child(2){animation-delay:.15s}.kj-chat-typing__dot:nth-child(3){animation-delay:.3s}@keyframes kj-chat-bounce{0%,80%,to{transform:scale(.5);opacity:.4}40%{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.kj-chat-typing__dot{animation:none;opacity:.6}}.kj-prompt{position:relative;display:flex;align-items:flex-end;gap:var(--kj-space-sm);padding:var(--kj-space-sm);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-box);background:var(--kj-bg-field, var(--kj-input-bg))}.kj-prompt:focus-within{border-color:var(--kj-border-focus)}.kj-prompt__textarea{flex:1 1 auto;resize:none;border:none;outline:none;background:transparent;color:var(--kj-input-fg, var(--kj-fg-default));font-family:var(--kj-font-sans);font-size:var(--kj-input-font-size, 1rem);line-height:1.5;max-height:200px;overflow-y:auto}.kj-prompt__textarea::placeholder{color:var(--kj-input-placeholder-fg, var(--kj-fg-muted))}.kj-prompt__actions{display:flex;align-items:center;gap:var(--kj-space-xs);flex:0 0 auto}.kj-prompt__btn{display:grid;place-items:center;width:2.75rem;height:2.75rem;border-radius:50%;border:none;cursor:pointer;font-size:1.1rem}.kj-prompt__btn:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-prompt__btn--send{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-prompt__btn--send:disabled{opacity:.5;cursor:not-allowed}.kj-prompt__btn--stop{background:var(--kj-bg-danger);color:var(--kj-fg-on-danger)}.kj-prompt__slash{position:absolute;bottom:calc(100% + .25rem);left:0;right:0;margin:0;padding:.25rem;list-style:none;background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);box-shadow:0 4px 16px #00000026;max-height:14rem;overflow-y:auto;z-index:10}.kj-prompt__slash-item{display:flex;flex-direction:column;gap:.1rem;padding:var(--kj-space-xs) var(--kj-space-sm);border-radius:var(--kj-radius-field);cursor:pointer}.kj-prompt__slash-item.is-active,.kj-prompt__slash-item:hover{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-prompt__slash-name{font-family:ui-monospace,monospace;font-weight:600}.kj-prompt__slash-desc{font-size:var(--kj-text-sm);color:var(--kj-fg-muted)}.kj-prompt__slash-item.is-active .kj-prompt__slash-desc,.kj-prompt__slash-item:hover .kj-prompt__slash-desc{color:inherit}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
3585
|
+
}
|
|
3586
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjPromptInput, decorators: [{
|
|
3587
|
+
type: Component,
|
|
3588
|
+
args: [{ selector: 'kj-prompt-input', standalone: true, template: `
|
|
3589
|
+
<form class="kj-prompt" (submit)="onSubmit($event)">
|
|
3590
|
+
@if (slashOpen()) {
|
|
3591
|
+
<ul class="kj-prompt__slash" role="listbox" [id]="listboxId" aria-label="Slash commands">
|
|
3592
|
+
@for (cmd of slashMatches(); track cmd.name; let i = $index) {
|
|
3593
|
+
<li
|
|
3594
|
+
class="kj-prompt__slash-item"
|
|
3595
|
+
role="option"
|
|
3596
|
+
[id]="optionId(i)"
|
|
3597
|
+
[attr.aria-selected]="i === activeIndex()"
|
|
3598
|
+
[class.is-active]="i === activeIndex()"
|
|
3599
|
+
(mousedown)="pickSlash($event, cmd)"
|
|
3600
|
+
>
|
|
3601
|
+
<span class="kj-prompt__slash-name">{{ cmd.name }}</span>
|
|
3602
|
+
@if (cmd.description) {
|
|
3603
|
+
<span class="kj-prompt__slash-desc">{{ cmd.description }}</span>
|
|
3604
|
+
}
|
|
3605
|
+
</li>
|
|
3606
|
+
}
|
|
3607
|
+
</ul>
|
|
3608
|
+
}
|
|
3609
|
+
|
|
3610
|
+
<label class="kj-visually-hidden" [attr.for]="textareaId">{{ kjLabel() }}</label>
|
|
3611
|
+
<textarea
|
|
3612
|
+
#ta
|
|
3613
|
+
class="kj-prompt__textarea"
|
|
3614
|
+
[id]="textareaId"
|
|
3615
|
+
[attr.placeholder]="kjPlaceholder()"
|
|
3616
|
+
[attr.aria-label]="kjLabel()"
|
|
3617
|
+
[attr.role]="slashOpen() ? 'combobox' : null"
|
|
3618
|
+
[attr.aria-expanded]="slashOpen() ? 'true' : null"
|
|
3619
|
+
[attr.aria-controls]="slashOpen() ? listboxId : null"
|
|
3620
|
+
[attr.aria-activedescendant]="slashOpen() ? optionId(activeIndex()) : null"
|
|
3621
|
+
[attr.aria-haspopup]="slashOpen() ? 'listbox' : null"
|
|
3622
|
+
[attr.aria-autocomplete]="slashOpen() ? 'list' : null"
|
|
3623
|
+
[disabled]="kjDisabled()"
|
|
3624
|
+
[value]="kjValue()"
|
|
3625
|
+
rows="1"
|
|
3626
|
+
(input)="onInput($event)"
|
|
3627
|
+
(keydown)="onKeydown($event)"
|
|
3628
|
+
></textarea>
|
|
3629
|
+
|
|
3630
|
+
<div class="kj-prompt__actions">
|
|
3631
|
+
<span class="kj-prompt__attachments">
|
|
3632
|
+
<ng-content select="[kjPromptAttachments]" />
|
|
3633
|
+
</span>
|
|
3634
|
+
@if (kjStreaming()) {
|
|
3635
|
+
<button
|
|
3636
|
+
type="button"
|
|
3637
|
+
class="kj-prompt__btn kj-prompt__btn--stop"
|
|
3638
|
+
aria-label="Stop generating"
|
|
3639
|
+
(click)="onStop()"
|
|
3640
|
+
>
|
|
3641
|
+
<span aria-hidden="true">■</span>
|
|
3642
|
+
</button>
|
|
3643
|
+
} @else {
|
|
3644
|
+
<button
|
|
3645
|
+
type="submit"
|
|
3646
|
+
class="kj-prompt__btn kj-prompt__btn--send"
|
|
3647
|
+
aria-label="Send message"
|
|
3648
|
+
[disabled]="kjDisabled() || kjValue().trim().length === 0"
|
|
3649
|
+
>
|
|
3650
|
+
<span aria-hidden="true">↥</span>
|
|
3651
|
+
</button>
|
|
3652
|
+
}
|
|
3653
|
+
</div>
|
|
3654
|
+
</form>
|
|
3655
|
+
`, encapsulation: ViewEncapsulation.None, host: { class: 'kj-prompt-host' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.kj-chat-thread{display:flex;flex-direction:column;gap:var(--kj-space-md);padding:var(--kj-space-md);background:var(--kj-bg-body);color:var(--kj-fg-default);border-radius:var(--kj-radius-box);overflow-y:auto;font-family:var(--kj-font-sans)}.kj-chat-msg{display:flex;gap:var(--kj-space-sm);align-items:flex-start;max-width:100%}.kj-chat-msg[data-side=end]{flex-direction:row-reverse;margin-inline-start:auto}.kj-chat-msg[data-role=system]{justify-content:center}.kj-chat-msg__avatar{flex:0 0 auto;width:2rem;height:2rem;border-radius:50%;display:grid;place-items:center;font-size:var(--kj-text-sm);font-weight:600;background:var(--kj-bg-surface);color:var(--kj-fg-default);border:1px solid var(--kj-border-default)}.kj-chat-msg__bubble{display:flex;flex-direction:column;gap:var(--kj-space-xs);padding:var(--kj-space-sm) var(--kj-space-md);border-radius:var(--kj-radius-box);background:var(--kj-bg-surface);color:var(--kj-fg-default);max-width:min(48rem,100%);overflow-wrap:anywhere}.kj-chat-msg[data-role=user] .kj-chat-msg__bubble{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-chat-msg[data-role=system] .kj-chat-msg__bubble{background:transparent;color:var(--kj-fg-muted);font-size:var(--kj-text-sm);text-align:center;padding-block:var(--kj-space-xs)}.kj-chat-msg__body :is(p){margin:0 0 var(--kj-space-xs)}.kj-chat-msg__body :is(p):last-child{margin-bottom:0}.kj-chat-msg__error{margin:0;color:var(--kj-fg-danger);font-size:var(--kj-text-sm)}.kj-md-link{color:inherit;text-decoration:underline}.kj-md-code{font-family:ui-monospace,monospace;background:color-mix(in srgb,currentColor 12%,transparent);padding:.1em .35em;border-radius:var(--kj-radius-field);font-size:.9em}.kj-chat-code{border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);overflow:hidden;margin:var(--kj-space-xs) 0;background:var(--kj-bg-body)}.kj-chat-code__bar{display:flex;align-items:center;justify-content:space-between;padding:.25rem var(--kj-space-sm);background:var(--kj-bg-surface);border-bottom:1px solid var(--kj-border-default);font-size:var(--kj-text-sm);color:var(--kj-fg-muted)}.kj-chat-code__copy{min-height:1.75rem;padding:.25rem .6rem;border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);background:var(--kj-bg-body);color:var(--kj-fg-default);font-size:var(--kj-text-sm);cursor:pointer}.kj-chat-code__copy:hover{background:var(--kj-bg-surface)}.kj-chat-code__copy:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-chat-code__pre{margin:0;padding:var(--kj-space-sm);overflow-x:auto;font-family:ui-monospace,monospace;font-size:.9em;color:var(--kj-fg-default)}.kj-chat-tool{display:flex;align-items:center;gap:var(--kj-space-xs);padding:.35rem var(--kj-space-sm);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);background:var(--kj-bg-body);font-size:var(--kj-text-sm)}.kj-chat-tool__name{font-weight:600;font-family:ui-monospace,monospace}.kj-chat-tool__status{margin-inline-start:auto;color:var(--kj-fg-muted);text-transform:capitalize}.kj-chat-tool[data-status=error]{border-color:var(--kj-border-danger)}.kj-chat-tool[data-status=error] .kj-chat-tool__status,.kj-chat-tool__error{color:var(--kj-fg-danger)}.kj-chat-cites{list-style:none;margin:var(--kj-space-xs) 0 0;padding:0;display:flex;flex-wrap:wrap;gap:var(--kj-space-xs)}.kj-chat-cite{display:inline-flex;align-items:baseline;gap:.35rem;padding:.15rem .5rem;border:1px solid var(--kj-border-default);border-radius:999px;font-size:var(--kj-text-sm);background:var(--kj-bg-body)}.kj-chat-cite__link{color:var(--kj-fg-info);text-decoration:none}.kj-chat-cite__link:hover{text-decoration:underline}.kj-chat-cite__snippet{color:var(--kj-fg-muted)}.kj-chat-typing{display:inline-flex;gap:.25rem;align-items:center;padding:.25rem 0}.kj-chat-typing__dot{width:.5rem;height:.5rem;border-radius:50%;background:var(--kj-fg-muted);animation:kj-chat-bounce 1.2s infinite ease-in-out both}.kj-chat-typing__dot:nth-child(2){animation-delay:.15s}.kj-chat-typing__dot:nth-child(3){animation-delay:.3s}@keyframes kj-chat-bounce{0%,80%,to{transform:scale(.5);opacity:.4}40%{transform:scale(1);opacity:1}}@media(prefers-reduced-motion:reduce){.kj-chat-typing__dot{animation:none;opacity:.6}}.kj-prompt{position:relative;display:flex;align-items:flex-end;gap:var(--kj-space-sm);padding:var(--kj-space-sm);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-box);background:var(--kj-bg-field, var(--kj-input-bg))}.kj-prompt:focus-within{border-color:var(--kj-border-focus)}.kj-prompt__textarea{flex:1 1 auto;resize:none;border:none;outline:none;background:transparent;color:var(--kj-input-fg, var(--kj-fg-default));font-family:var(--kj-font-sans);font-size:var(--kj-input-font-size, 1rem);line-height:1.5;max-height:200px;overflow-y:auto}.kj-prompt__textarea::placeholder{color:var(--kj-input-placeholder-fg, var(--kj-fg-muted))}.kj-prompt__actions{display:flex;align-items:center;gap:var(--kj-space-xs);flex:0 0 auto}.kj-prompt__btn{display:grid;place-items:center;width:2.75rem;height:2.75rem;border-radius:50%;border:none;cursor:pointer;font-size:1.1rem}.kj-prompt__btn:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-prompt__btn--send{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-prompt__btn--send:disabled{opacity:.5;cursor:not-allowed}.kj-prompt__btn--stop{background:var(--kj-bg-danger);color:var(--kj-fg-on-danger)}.kj-prompt__slash{position:absolute;bottom:calc(100% + .25rem);left:0;right:0;margin:0;padding:.25rem;list-style:none;background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-field);box-shadow:0 4px 16px #00000026;max-height:14rem;overflow-y:auto;z-index:10}.kj-prompt__slash-item{display:flex;flex-direction:column;gap:.1rem;padding:var(--kj-space-xs) var(--kj-space-sm);border-radius:var(--kj-radius-field);cursor:pointer}.kj-prompt__slash-item.is-active,.kj-prompt__slash-item:hover{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary)}.kj-prompt__slash-name{font-family:ui-monospace,monospace;font-weight:600}.kj-prompt__slash-desc{font-size:var(--kj-text-sm);color:var(--kj-fg-muted)}.kj-prompt__slash-item.is-active .kj-prompt__slash-desc,.kj-prompt__slash-item:hover .kj-prompt__slash-desc{color:inherit}}\n"] }]
|
|
3656
|
+
}], ctorParameters: () => [], propDecorators: { kjValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjValue", required: false }] }, { type: i0.Output, args: ["kjValueChange"] }], kjPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjPlaceholder", required: false }] }], kjLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjLabel", required: false }] }], kjStreaming: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjStreaming", required: false }] }], kjDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjDisabled", required: false }] }], kjSlashCommands: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjSlashCommands", required: false }] }], kjSend: [{ type: i0.Output, args: ["kjSend"] }], kjStop: [{ type: i0.Output, args: ["kjStop"] }], kjSlashSelect: [{ type: i0.Output, args: ["kjSlashSelect"] }], ta: [{ type: i0.ViewChild, args: ['ta', { isSignal: true }] }] } });
|
|
3657
|
+
|
|
3658
|
+
let checkboxIdCounter = 0;
|
|
3659
|
+
/**
|
|
3660
|
+
* Styled wrapper around the headless `KjCheckbox` directive.
|
|
3661
|
+
*
|
|
3662
|
+
* The host renders a `<label>` wrapping the checkbox box and any projected
|
|
3663
|
+
* content (label text). Clicking anywhere on the label checks/unchecks the
|
|
3664
|
+
* box. When `disabled` is set, both the box and label text dim via
|
|
3665
|
+
* `[data-disabled]` on the host.
|
|
3666
|
+
*
|
|
3667
|
+
* @doc-example Default
|
|
3668
|
+
* The default checkbox bound to a `signal<boolean>` via `[(checked)]`.
|
|
3669
|
+
* @doc-file checkbox.default.example.ts
|
|
3670
|
+
* @doc-example Usage
|
|
3671
|
+
* A walkthrough of the most common checkbox usages — checked binding,
|
|
3672
|
+
* indeterminate parent, size variants, and disabled.
|
|
3673
|
+
* @doc-file checkbox.usage.example.ts
|
|
3674
|
+
* @doc-example Checked
|
|
3675
|
+
* Pre-selected on first render. Two-way bind to persist user changes.
|
|
3676
|
+
* @doc-file checkbox.checked.example.ts
|
|
3677
|
+
* @doc-example Indeterminate
|
|
3678
|
+
* Tri-state "some-of-many" parent for a select-all row.
|
|
3679
|
+
* @doc-file checkbox.indeterminate.example.ts
|
|
3680
|
+
* @doc-example Disabled
|
|
3681
|
+
* `[disabled]="true"` dims the box + label and removes pointer events.
|
|
3682
|
+
* @doc-file checkbox.disabled.example.ts
|
|
3683
|
+
*
|
|
3684
|
+
* @doc-keyboard
|
|
3685
|
+
* Space — Toggles the checked state
|
|
3686
|
+
* Tab — Moves focus to the next focusable element
|
|
3687
|
+
*
|
|
3688
|
+
* @doc-aria
|
|
3689
|
+
* role="checkbox" — Applied to the inner focusable box by the headless directive
|
|
3690
|
+
* aria-checked — Reflects `true`, `false`, or `"mixed"` for indeterminate
|
|
3691
|
+
* aria-disabled — Reflected when `[disabled]` is true
|
|
3692
|
+
* aria-labelledby — Auto-wired to the projected label span
|
|
3693
|
+
* data-disabled — Mirrors the disabled posture for theme/scope hooks
|
|
3694
|
+
* data-indeterminate — Reflects the indeterminate posture for the dash glyph
|
|
3695
|
+
*
|
|
3696
|
+
* @doc-css-var
|
|
3697
|
+
* --kj-checkbox-size — Box edge length. `data-size="sm|lg"` overrides; default 1rem.
|
|
3698
|
+
* --kj-checkbox-bg — Unchecked background fill. Defaults to --kj-bg-body.
|
|
2592
3699
|
* --kj-checkbox-bg-checked — Background when checked or indeterminate. Defaults to --kj-bg-primary.
|
|
2593
3700
|
* --kj-checkbox-fg-checked — Checkmark/dash color. Defaults to --kj-fg-on-primary.
|
|
2594
3701
|
* --kj-checkbox-border — Border color when unchecked. Defaults to --kj-border-default.
|
|
@@ -3618,6 +4725,124 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
3618
4725
|
`, encapsulation: ViewEncapsulation.None, host: { class: 'kj-date-picker-host', style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-date-picker{display:inline-flex;align-items:center;gap:var(--kj-space-xs);position:relative}.kj-date-picker__input{--kj-date-picker-input-height: 2.25rem;appearance:none;border:var(--kj-border) solid var(--kj-border-default);border-radius:var(--kj-radius-field);padding:0 var(--kj-space-md);height:var(--kj-date-picker-input-height);font:inherit;background:var(--kj-bg-field);color:var(--kj-fg-default);min-width:12ch}.kj-date-picker[data-size=xs] .kj-date-picker__input{--kj-date-picker-input-height: 1.75rem;font-size:.75rem;padding-inline:var(--kj-space-sm);min-width:0}.kj-date-picker[data-size=sm] .kj-date-picker__input{--kj-date-picker-input-height: 2rem;font-size:.8125rem}.kj-date-picker[data-size=lg] .kj-date-picker__input{--kj-date-picker-input-height: 2.75rem;font-size:1rem}.kj-date-picker__input:focus{outline:2px solid var(--kj-border-focus);outline-offset:2px;border-color:var(--kj-border-focus)}.kj-date-picker__input[disabled]{opacity:.55;cursor:not-allowed}.kj-date-picker__panel{box-sizing:border-box;z-index:50;display:inline-block;background:var(--kj-bg-elevated);color:var(--kj-fg-default);border:var(--kj-border) solid var(--kj-border-default);border-radius:var(--kj-radius-box);box-shadow:var(--kj-shadow-md);padding:var(--kj-space-sm)}.kj-date-picker__panel .kj-calendar{padding:0}.kj-date-picker__panel[hidden]{display:none}\n"] }]
|
|
3619
4726
|
}], propDecorators: { kjValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjValue", required: false }] }, { type: i0.Output, args: ["kjValueChange"] }], kjOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjOpen", required: false }] }, { type: i0.Output, args: ["kjOpenChange"] }], kjMin: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjMin", required: false }] }], kjMax: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjMax", required: false }] }], kjDisabledDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjDisabledDates", required: false }] }], kjLocale: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjLocale", required: false }] }], kjFirstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjFirstDayOfWeek", required: false }] }], kjPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjPlaceholder", required: false }] }], kjReadonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjReadonly", required: false }] }], kjDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjDisabled", required: false }] }], kjSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjSize", required: false }] }] } });
|
|
3620
4727
|
|
|
4728
|
+
/**
|
|
4729
|
+
* Styled Date Range Presets — a compact, keyboard-navigable list of named
|
|
4730
|
+
* quick-selects ("Today", "Last 7 days", "This quarter", …). Picking one
|
|
4731
|
+
* resolves its inclusive `{ start, end }` range and commits the two-way
|
|
4732
|
+
* `kjValue`.
|
|
4733
|
+
*
|
|
4734
|
+
* Built as the reusable presets primitive from the date/time roadmap slice:
|
|
4735
|
+
* it slots beside a range calendar, but works standalone against any
|
|
4736
|
+
* `signal<KjDateRange | null>`.
|
|
4737
|
+
*
|
|
4738
|
+
* **Accessibility (WCAG 2.1 AAA):**
|
|
4739
|
+
* - the list is `role="listbox"` with an accessible name; each preset is a
|
|
4740
|
+
* `role="option"` `<button>` carrying `aria-selected`.
|
|
4741
|
+
* - roving tabindex — one tab stop; Up/Down (and Home/End) move between
|
|
4742
|
+
* options; Enter / Space select (native button activation).
|
|
4743
|
+
* - the selected preset is conveyed by `aria-selected`, not color alone.
|
|
4744
|
+
*
|
|
4745
|
+
* @doc-example Default
|
|
4746
|
+
* The ten built-in presets bound to a `signal<KjDateRange | null>`.
|
|
4747
|
+
* @doc-file date-range-presets.example.ts
|
|
4748
|
+
* @doc-example Custom presets
|
|
4749
|
+
* Spread `defaultDateRangePresets()` and append your own `getRange`.
|
|
4750
|
+
* @doc-file date-range-presets.custom.example.ts
|
|
4751
|
+
*
|
|
4752
|
+
* @doc-keyboard
|
|
4753
|
+
* ArrowDown|ArrowUp — Moves between presets
|
|
4754
|
+
* Home|End — Jumps to the first / last preset
|
|
4755
|
+
* Enter|Space — Selects the focused preset
|
|
4756
|
+
*
|
|
4757
|
+
* @doc-aria
|
|
4758
|
+
* role="listbox" — On the container; `aria-orientation="vertical"`
|
|
4759
|
+
* aria-label — Names the list ("Date range presets" by default)
|
|
4760
|
+
* role="option" — On each preset button
|
|
4761
|
+
* aria-selected — Reflects the chosen preset
|
|
4762
|
+
*
|
|
4763
|
+
* @doc-css-var
|
|
4764
|
+
* --kj-date-range-presets-min-width — Min width of the list. Default 12rem.
|
|
4765
|
+
*
|
|
4766
|
+
* @doc-touch
|
|
4767
|
+
* Preset rows are 44px tall to meet the WCAG 2.5.5 target size.
|
|
4768
|
+
*
|
|
4769
|
+
* @doc-related date-picker,calendar
|
|
4770
|
+
*
|
|
4771
|
+
* @doc-category Library/Data input
|
|
4772
|
+
* @doc
|
|
4773
|
+
* @doc-name date-range-presets
|
|
4774
|
+
* @doc-description Themed listbox of date-range quick-selects that resolve to an inclusive start/end range.
|
|
4775
|
+
* @doc-is-main
|
|
4776
|
+
*/
|
|
4777
|
+
class KjDateRangePresetsComponent {
|
|
4778
|
+
/** Selected range. Two-way bindable — `[(kjValue)]`. `null` clears. */
|
|
4779
|
+
kjValue = model(null, /* @ts-ignore */
|
|
4780
|
+
...(ngDevMode ? [{ debugName: "kjValue" }] : /* istanbul ignore next */ []));
|
|
4781
|
+
/** Presets to render. Defaults to the ten built-ins. */
|
|
4782
|
+
kjPresets = input(defaultDateRangePresets(), /* @ts-ignore */
|
|
4783
|
+
...(ngDevMode ? [{ debugName: "kjPresets" }] : /* istanbul ignore next */ []));
|
|
4784
|
+
/** Accessible name for the list. */
|
|
4785
|
+
kjLabel = input('Date range presets', /* @ts-ignore */
|
|
4786
|
+
...(ngDevMode ? [{ debugName: "kjLabel" }] : /* istanbul ignore next */ []));
|
|
4787
|
+
/** Injectable "now" for the preset math. Defaults to the current instant. */
|
|
4788
|
+
kjNow = input(null, /* @ts-ignore */
|
|
4789
|
+
...(ngDevMode ? [{ debugName: "kjNow" }] : /* istanbul ignore next */ []));
|
|
4790
|
+
/** Disable the whole list. */
|
|
4791
|
+
kjDisabled = input(false, { ...(ngDevMode ? { debugName: "kjDisabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
4792
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjDateRangePresetsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4793
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: KjDateRangePresetsComponent, isStandalone: true, selector: "kj-date-range-presets", inputs: { kjValue: { classPropertyName: "kjValue", publicName: "kjValue", isSignal: true, isRequired: false, transformFunction: null }, kjPresets: { classPropertyName: "kjPresets", publicName: "kjPresets", isSignal: true, isRequired: false, transformFunction: null }, kjLabel: { classPropertyName: "kjLabel", publicName: "kjLabel", isSignal: true, isRequired: false, transformFunction: null }, kjNow: { classPropertyName: "kjNow", publicName: "kjNow", isSignal: true, isRequired: false, transformFunction: null }, kjDisabled: { classPropertyName: "kjDisabled", publicName: "kjDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { kjValue: "kjValueChange" }, host: { styleAttribute: "display: contents;", classAttribute: "kj-date-range-presets-host" }, ngImport: i0, template: `
|
|
4794
|
+
<div
|
|
4795
|
+
kjDateRangePresets
|
|
4796
|
+
class="kj-date-range-presets"
|
|
4797
|
+
[kjValue]="kjValue() ?? null!"
|
|
4798
|
+
(kjValueChange)="kjValue.set($event)"
|
|
4799
|
+
[kjPresets]="kjPresets()"
|
|
4800
|
+
[kjLabel]="kjLabel()"
|
|
4801
|
+
[kjNow]="kjNow() ?? null!"
|
|
4802
|
+
[kjDisabled]="kjDisabled()"
|
|
4803
|
+
>
|
|
4804
|
+
@for (preset of kjPresets(); track preset.id) {
|
|
4805
|
+
<button
|
|
4806
|
+
kjDateRangePresetOption
|
|
4807
|
+
#opt="kjDateRangePresetOption"
|
|
4808
|
+
class="kj-date-range-presets__option"
|
|
4809
|
+
[kjPreset]="preset"
|
|
4810
|
+
[attr.data-selected]="opt.selected() ? '' : null"
|
|
4811
|
+
>
|
|
4812
|
+
{{ preset.label }}
|
|
4813
|
+
</button>
|
|
4814
|
+
}
|
|
4815
|
+
</div>
|
|
4816
|
+
`, isInline: true, styles: [".kj-date-range-presets{display:flex;flex-direction:column;gap:2px;min-width:var(--kj-date-range-presets-min-width, 12rem);padding:var(--kj-space-xs, .25rem);background:var(--kj-bg-elevated, transparent);border:var(--kj-border) solid var(--kj-border-subtle, transparent);border-radius:var(--kj-radius-field, .375rem);font-family:inherit;font-size:.8125rem;color:var(--kj-fg-default)}.kj-date-range-presets__option{appearance:none;display:flex;align-items:center;min-height:44px;padding:0 var(--kj-space-md, .75rem);background:transparent;border:var(--kj-border) solid transparent;border-radius:var(--kj-radius-field, .375rem);color:inherit;font:inherit;text-align:start;cursor:pointer}.kj-date-range-presets__option:hover:not([disabled]){background:var(--kj-bg-field)}.kj-date-range-presets__option:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:-2px}.kj-date-range-presets__option[data-selected]{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary);font-weight:600}.kj-date-range-presets__option[disabled]{opacity:.4;cursor:not-allowed}\n"], dependencies: [{ kind: "directive", type: KjDateRangePresets, selector: "[kjDateRangePresets]", inputs: ["kjValue", "kjPresets", "kjLabel", "kjNow", "kjReadonly"], outputs: ["kjValueChange"], exportAs: ["kjDateRangePresets"] }, { kind: "directive", type: KjDateRangePresetOption, selector: "button[kjDateRangePresetOption]", inputs: ["kjPreset"], exportAs: ["kjDateRangePresetOption"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
4817
|
+
}
|
|
4818
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjDateRangePresetsComponent, decorators: [{
|
|
4819
|
+
type: Component,
|
|
4820
|
+
args: [{ selector: 'kj-date-range-presets', standalone: true, imports: [KjDateRangePresets, KjDateRangePresetOption], template: `
|
|
4821
|
+
<div
|
|
4822
|
+
kjDateRangePresets
|
|
4823
|
+
class="kj-date-range-presets"
|
|
4824
|
+
[kjValue]="kjValue() ?? null!"
|
|
4825
|
+
(kjValueChange)="kjValue.set($event)"
|
|
4826
|
+
[kjPresets]="kjPresets()"
|
|
4827
|
+
[kjLabel]="kjLabel()"
|
|
4828
|
+
[kjNow]="kjNow() ?? null!"
|
|
4829
|
+
[kjDisabled]="kjDisabled()"
|
|
4830
|
+
>
|
|
4831
|
+
@for (preset of kjPresets(); track preset.id) {
|
|
4832
|
+
<button
|
|
4833
|
+
kjDateRangePresetOption
|
|
4834
|
+
#opt="kjDateRangePresetOption"
|
|
4835
|
+
class="kj-date-range-presets__option"
|
|
4836
|
+
[kjPreset]="preset"
|
|
4837
|
+
[attr.data-selected]="opt.selected() ? '' : null"
|
|
4838
|
+
>
|
|
4839
|
+
{{ preset.label }}
|
|
4840
|
+
</button>
|
|
4841
|
+
}
|
|
4842
|
+
</div>
|
|
4843
|
+
`, encapsulation: ViewEncapsulation.None, host: { class: 'kj-date-range-presets-host', style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-date-range-presets{display:flex;flex-direction:column;gap:2px;min-width:var(--kj-date-range-presets-min-width, 12rem);padding:var(--kj-space-xs, .25rem);background:var(--kj-bg-elevated, transparent);border:var(--kj-border) solid var(--kj-border-subtle, transparent);border-radius:var(--kj-radius-field, .375rem);font-family:inherit;font-size:.8125rem;color:var(--kj-fg-default)}.kj-date-range-presets__option{appearance:none;display:flex;align-items:center;min-height:44px;padding:0 var(--kj-space-md, .75rem);background:transparent;border:var(--kj-border) solid transparent;border-radius:var(--kj-radius-field, .375rem);color:inherit;font:inherit;text-align:start;cursor:pointer}.kj-date-range-presets__option:hover:not([disabled]){background:var(--kj-bg-field)}.kj-date-range-presets__option:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:-2px}.kj-date-range-presets__option[data-selected]{background:var(--kj-bg-primary);color:var(--kj-fg-on-primary);font-weight:600}.kj-date-range-presets__option[disabled]{opacity:.4;cursor:not-allowed}\n"] }]
|
|
4844
|
+
}], propDecorators: { kjValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjValue", required: false }] }, { type: i0.Output, args: ["kjValueChange"] }], kjPresets: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjPresets", required: false }] }], kjLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjLabel", required: false }] }], kjNow: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjNow", required: false }] }], kjDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjDisabled", required: false }] }] } });
|
|
4845
|
+
|
|
3621
4846
|
/** Format a Date as a locale short date + HH:mm time. */
|
|
3622
4847
|
function formatDateTime(d, locale) {
|
|
3623
4848
|
const date = new Intl.DateTimeFormat(locale || undefined, { dateStyle: 'short' }).format(d);
|
|
@@ -3893,6 +5118,108 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
3893
5118
|
args: [{ selector: 'kj-dialog-shell', standalone: true, template: `<ng-content />`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-dialog-overlay{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:1000}.kj-dialog{display:flex;flex-direction:column;background:var(--kj-bg-elevated);color:var(--kj-fg-default);border-radius:var(--kj-radius-box);box-shadow:var(--kj-shadow-lg);min-width:24rem;max-width:min(40rem,calc(100vw - 2rem));max-height:calc(100vh - 4rem);overflow:hidden;padding:var(--kj-space-xl)}.kj-dialog-header{display:flex;align-items:center;justify-content:flex-start;padding:var(--kj-space-lg) var(--kj-space-xl);border-bottom:var(--kj-border) solid var(--kj-border-muted)}.kj-dialog-header[data-align=center]{justify-content:center}.kj-dialog-title{display:block;margin:0;font:600 1.125rem / 1.3 var(--kj-font-sans);color:var(--kj-fg-default)}.kj-dialog-body{flex:1;color:var(--kj-fg-default);font:.9375rem / 1.5 var(--kj-font-sans)}.kj-dialog-body[data-padded]{padding:var(--kj-space-lg) var(--kj-space-xl)}.kj-dialog-body[data-scroll]{overflow-y:auto}.kj-dialog-footer{display:flex;align-items:center;gap:var(--kj-space-sm);padding:var(--kj-space-lg) var(--kj-space-xl);border-top:var(--kj-border) solid var(--kj-border-muted)}.kj-dialog-footer[data-align=start]{justify-content:flex-start}.kj-dialog-footer[data-align=center]{justify-content:center}.kj-dialog-footer[data-align=end]{justify-content:flex-end}.kj-dialog-footer[data-align=between]{justify-content:space-between}}\n"] }]
|
|
3894
5119
|
}] });
|
|
3895
5120
|
|
|
5121
|
+
/**
|
|
5122
|
+
* A visible, keyboard-native control that flips the application's logical text
|
|
5123
|
+
* direction between `ltr` and `rtl`.
|
|
5124
|
+
*
|
|
5125
|
+
* It is the concrete UI the locale provider pointed at: it reads
|
|
5126
|
+
* `KjLocale.isRtl()` and calls `KjLocale.setDirection(...)`. Paired with
|
|
5127
|
+
* `provideKjDocumentDirection()`, one click mirrors the whole page —
|
|
5128
|
+
* `<html dir>` flips and every logical-property layout follows.
|
|
5129
|
+
*
|
|
5130
|
+
* Renders a real `<button type="button">` so it is reachable by Tab and
|
|
5131
|
+
* operable with Enter / Space for free. `aria-pressed` reflects the RTL state
|
|
5132
|
+
* (pressed = RTL), and an accessible name is always present via
|
|
5133
|
+
* `[kjAriaLabel]`. Project custom content to replace the default `LTR` / `RTL`
|
|
5134
|
+
* text label.
|
|
5135
|
+
*
|
|
5136
|
+
* @example
|
|
5137
|
+
* ```html
|
|
5138
|
+
* <kj-direction-toggle />
|
|
5139
|
+
* <kj-direction-toggle kjAriaLabel="Toggle Arabic layout">اتجاه</kj-direction-toggle>
|
|
5140
|
+
* ```
|
|
5141
|
+
*
|
|
5142
|
+
* @doc-example Default
|
|
5143
|
+
* The toggle wired to `KjLocale` — click to flip `<html dir>` and mirror the page.
|
|
5144
|
+
* @doc-file direction-toggle.example.ts
|
|
5145
|
+
*
|
|
5146
|
+
* @doc-keyboard
|
|
5147
|
+
* Enter — Toggles the direction (native button activation)
|
|
5148
|
+
* Space — Toggles the direction (native button activation)
|
|
5149
|
+
* Tab — Moves focus to / from the toggle
|
|
5150
|
+
*
|
|
5151
|
+
* @doc-aria
|
|
5152
|
+
* aria-pressed — Reflects the RTL state (true when direction is rtl)
|
|
5153
|
+
* aria-label — Accessible name; defaults to "Toggle right-to-left layout"
|
|
5154
|
+
* data-direction — Mirrors the resolved direction (ltr | rtl) for theme CSS
|
|
5155
|
+
*
|
|
5156
|
+
* @doc-touch
|
|
5157
|
+
* The button reserves a 44×44px hit area (WCAG 2.5.5) regardless of label size.
|
|
5158
|
+
*
|
|
5159
|
+
* @doc-a11y
|
|
5160
|
+
* A native `<button>` with `aria-pressed` — AT announces "toggle button,
|
|
5161
|
+
* pressed/not pressed". Because mirroring is CSS-logical only, DOM and tab
|
|
5162
|
+
* order are unchanged in both directions (WCAG 1.3.2).
|
|
5163
|
+
*
|
|
5164
|
+
* @doc-related locale
|
|
5165
|
+
*
|
|
5166
|
+
* @doc-css-var
|
|
5167
|
+
* --kj-direction-toggle-bg — Background at rest.
|
|
5168
|
+
* --kj-direction-toggle-fg — Text color.
|
|
5169
|
+
* --kj-direction-toggle-border-color — Border color.
|
|
5170
|
+
* --kj-direction-toggle-radius — Corner radius.
|
|
5171
|
+
* --kj-direction-toggle-padding-x — Inline padding.
|
|
5172
|
+
* --kj-direction-toggle-padding-y — Block padding.
|
|
5173
|
+
*
|
|
5174
|
+
* @doc-category Library/Navigation
|
|
5175
|
+
* @doc
|
|
5176
|
+
* @doc-name direction-toggle
|
|
5177
|
+
* @doc-description Accessible LTR/RTL toggle button that drives KjLocale.direction and mirrors the page.
|
|
5178
|
+
* @doc-is-main
|
|
5179
|
+
*/
|
|
5180
|
+
class KjDirectionToggle {
|
|
5181
|
+
locale = inject(KjLocale);
|
|
5182
|
+
/** Resolved logical direction from the shared `KjLocale`. */
|
|
5183
|
+
direction = this.locale.direction;
|
|
5184
|
+
/** `true` when the resolved direction is `rtl`. Drives `aria-pressed`. */
|
|
5185
|
+
isRtl = this.locale.isRtl;
|
|
5186
|
+
/** Accessible name for the toggle button. */
|
|
5187
|
+
kjAriaLabel = input('Toggle right-to-left layout', /* @ts-ignore */
|
|
5188
|
+
...(ngDevMode ? [{ debugName: "kjAriaLabel" }] : /* istanbul ignore next */ []));
|
|
5189
|
+
/** Flip the direction: `ltr` ⇄ `rtl`. */
|
|
5190
|
+
toggle() {
|
|
5191
|
+
this.locale.setDirection(this.locale.isRtl() ? 'ltr' : 'rtl');
|
|
5192
|
+
}
|
|
5193
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjDirectionToggle, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5194
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.5", type: KjDirectionToggle, isStandalone: true, selector: "kj-direction-toggle", inputs: { kjAriaLabel: { classPropertyName: "kjAriaLabel", publicName: "kjAriaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { styleAttribute: "display: contents;" }, ngImport: i0, template: `
|
|
5195
|
+
<button
|
|
5196
|
+
type="button"
|
|
5197
|
+
class="kj-direction-toggle"
|
|
5198
|
+
[attr.aria-pressed]="isRtl()"
|
|
5199
|
+
[attr.aria-label]="kjAriaLabel()"
|
|
5200
|
+
[attr.data-direction]="direction()"
|
|
5201
|
+
(click)="toggle()"
|
|
5202
|
+
>
|
|
5203
|
+
<ng-content>{{ isRtl() ? 'RTL' : 'LTR' }}</ng-content>
|
|
5204
|
+
</button>
|
|
5205
|
+
`, isInline: true, styles: ["@layer kj.component{.kj-direction-toggle{--kj-direction-toggle-bg: var(--kj-bg-subtle, transparent);--kj-direction-toggle-fg: var(--kj-fg, currentColor);--kj-direction-toggle-border-color: var(--kj-border-color, currentColor);--kj-direction-toggle-radius: var(--kj-radius-field, .5rem);--kj-direction-toggle-padding-x: var(--kj-space-md, .75rem);--kj-direction-toggle-padding-y: var(--kj-space-sm, .5rem);display:inline-flex;align-items:center;justify-content:center;gap:var(--kj-space-xs, .25rem);min-width:44px;min-height:44px;padding-block:var(--kj-direction-toggle-padding-y);padding-inline:var(--kj-direction-toggle-padding-x);background:var(--kj-direction-toggle-bg);color:var(--kj-direction-toggle-fg);border:var(--kj-border, 1px) solid var(--kj-direction-toggle-border-color);border-radius:var(--kj-direction-toggle-radius);font:inherit;font-size:var(--kj-text-sm, .875rem);line-height:1;cursor:pointer;-webkit-user-select:none;user-select:none}.kj-direction-toggle:hover{background:var(--kj-bg-subtle-hover, var(--kj-direction-toggle-bg))}.kj-direction-toggle:focus-visible{outline:var(--kj-focus-ring-width, 2px) solid var(--kj-focus-ring-color, currentColor);outline-offset:2px}.kj-direction-toggle[aria-pressed=true]{background:var(--kj-bg-primary, var(--kj-direction-toggle-bg));color:var(--kj-fg-on-primary, var(--kj-direction-toggle-fg));border-color:var(--kj-bg-primary, var(--kj-direction-toggle-border-color))}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5206
|
+
}
|
|
5207
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjDirectionToggle, decorators: [{
|
|
5208
|
+
type: Component,
|
|
5209
|
+
args: [{ selector: 'kj-direction-toggle', standalone: true, template: `
|
|
5210
|
+
<button
|
|
5211
|
+
type="button"
|
|
5212
|
+
class="kj-direction-toggle"
|
|
5213
|
+
[attr.aria-pressed]="isRtl()"
|
|
5214
|
+
[attr.aria-label]="kjAriaLabel()"
|
|
5215
|
+
[attr.data-direction]="direction()"
|
|
5216
|
+
(click)="toggle()"
|
|
5217
|
+
>
|
|
5218
|
+
<ng-content>{{ isRtl() ? 'RTL' : 'LTR' }}</ng-content>
|
|
5219
|
+
</button>
|
|
5220
|
+
`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-direction-toggle{--kj-direction-toggle-bg: var(--kj-bg-subtle, transparent);--kj-direction-toggle-fg: var(--kj-fg, currentColor);--kj-direction-toggle-border-color: var(--kj-border-color, currentColor);--kj-direction-toggle-radius: var(--kj-radius-field, .5rem);--kj-direction-toggle-padding-x: var(--kj-space-md, .75rem);--kj-direction-toggle-padding-y: var(--kj-space-sm, .5rem);display:inline-flex;align-items:center;justify-content:center;gap:var(--kj-space-xs, .25rem);min-width:44px;min-height:44px;padding-block:var(--kj-direction-toggle-padding-y);padding-inline:var(--kj-direction-toggle-padding-x);background:var(--kj-direction-toggle-bg);color:var(--kj-direction-toggle-fg);border:var(--kj-border, 1px) solid var(--kj-direction-toggle-border-color);border-radius:var(--kj-direction-toggle-radius);font:inherit;font-size:var(--kj-text-sm, .875rem);line-height:1;cursor:pointer;-webkit-user-select:none;user-select:none}.kj-direction-toggle:hover{background:var(--kj-bg-subtle-hover, var(--kj-direction-toggle-bg))}.kj-direction-toggle:focus-visible{outline:var(--kj-focus-ring-width, 2px) solid var(--kj-focus-ring-color, currentColor);outline-offset:2px}.kj-direction-toggle[aria-pressed=true]{background:var(--kj-bg-primary, var(--kj-direction-toggle-bg));color:var(--kj-fg-on-primary, var(--kj-direction-toggle-fg));border-color:var(--kj-bg-primary, var(--kj-direction-toggle-border-color))}}\n"] }]
|
|
5221
|
+
}], propDecorators: { kjAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjAriaLabel", required: false }] }] } });
|
|
5222
|
+
|
|
3896
5223
|
/**
|
|
3897
5224
|
* Service-launched drawer (edge-anchored panel). Inject `KjDrawerService` and
|
|
3898
5225
|
* call `open()` with a template; the drawer absorbs the bottom-sheet pattern
|
|
@@ -4048,23 +5375,412 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
4048
5375
|
* `[kjDisabled]="true"` keeps the item focusable but blocks activation.
|
|
4049
5376
|
* @doc-file dropdown-menu.disabled.example.ts
|
|
4050
5377
|
*
|
|
4051
|
-
* @doc-category Library/Overlay
|
|
5378
|
+
* @doc-category Library/Overlay
|
|
5379
|
+
*/
|
|
5380
|
+
class KjDropdownMenuComponent {
|
|
5381
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjDropdownMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5382
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: KjDropdownMenuComponent, isStandalone: true, selector: "kj-dropdown-menu", host: { styleAttribute: "display: contents;" }, ngImport: i0, template: `<ng-content />`, isInline: true, styles: ["@layer kj.component{.kj-dropdown-menu{--kj-dropdown-menu-bg: var(--kj-bg-elevated);--kj-dropdown-menu-fg: var(--kj-fg-default);--kj-dropdown-menu-border-color: var(--kj-border-default);--kj-dropdown-menu-radius: var(--kj-radius-box);--kj-dropdown-menu-padding: var(--kj-space-xs);--kj-dropdown-menu-shadow: var(--kj-shadow-md);display:flex;flex-direction:column;box-sizing:border-box;min-width:12rem;max-width:min(20rem,calc(100vw - 2rem));background:var(--kj-dropdown-menu-bg);color:var(--kj-dropdown-menu-fg);border:var(--kj-border) solid var(--kj-dropdown-menu-border-color);border-radius:var(--kj-dropdown-menu-radius);padding:var(--kj-dropdown-menu-padding);font:.875rem / 1.5 var(--kj-font-sans);box-shadow:var(--kj-dropdown-menu-shadow);pointer-events:auto;z-index:1000}.kj-dropdown-menu[hidden]{display:none}.kj-dropdown-menu-item{--kj-dropdown-menu-item-padding-x: var(--kj-space-md);--kj-dropdown-menu-item-padding-y: var(--kj-space-sm);--kj-dropdown-menu-item-min-height: 2.75rem;--kj-dropdown-menu-item-radius: var(--kj-radius-field);--kj-dropdown-menu-item-hover-bg: var(--kj-bg-surface);--kj-dropdown-menu-item-active-bg: var(--kj-bg-field);display:flex;align-items:center;justify-content:flex-start;gap:var(--kj-space-sm);width:100%;min-height:var(--kj-dropdown-menu-item-min-height);box-sizing:border-box;padding:var(--kj-dropdown-menu-item-padding-y) var(--kj-dropdown-menu-item-padding-x);margin:0;background:transparent;color:inherit;border:none;border-radius:var(--kj-dropdown-menu-item-radius);font:inherit;text-align:start;cursor:pointer;-webkit-user-select:none;user-select:none}.kj-dropdown-menu-item:hover:not([data-disabled]){background:var(--kj-dropdown-menu-item-hover-bg)}.kj-dropdown-menu-item:focus-visible{outline:2px solid var(--kj-bg-primary);outline-offset:-2px}.kj-dropdown-menu-item[aria-current=true]{background:var(--kj-dropdown-menu-item-current-bg, var(--kj-bg-field));color:var(--kj-dropdown-menu-item-current-fg, var(--kj-fg-primary));font-weight:500}.kj-dropdown-menu-item[data-disabled]{cursor:not-allowed;opacity:.5}.kj-dropdown-menu-separator{display:block;height:1px;margin:var(--kj-space-xs) calc(var(--kj-space-xs) * -1);background:color-mix(in oklab,var(--kj-fg-default) 12%,transparent);border:0}.kj-dropdown-menu-label{display:block;padding:var(--kj-space-xs) var(--kj-space-md);font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--kj-fg-default);opacity:.65}.kj-dropdown-menu-group{display:flex;flex-direction:column}@media(prefers-reduced-motion:no-preference){.kj-dropdown-menu{transition:opacity .12s ease-out,transform .12s ease-out}.kj-dropdown-menu[data-state=closed]{opacity:0;transform:scale(.98)}.kj-dropdown-menu[data-state=open]{opacity:1;transform:scale(1)}}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5383
|
+
}
|
|
5384
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjDropdownMenuComponent, decorators: [{
|
|
5385
|
+
type: Component,
|
|
5386
|
+
args: [{ selector: 'kj-dropdown-menu', standalone: true, imports: [
|
|
5387
|
+
KjDropdownMenuTrigger,
|
|
5388
|
+
KjDropdownMenuContent,
|
|
5389
|
+
KjDropdownMenuItem,
|
|
5390
|
+
KjDropdownMenuSeparator,
|
|
5391
|
+
KjDropdownMenuLabel,
|
|
5392
|
+
KjDropdownMenuGroup,
|
|
5393
|
+
], template: `<ng-content />`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-dropdown-menu{--kj-dropdown-menu-bg: var(--kj-bg-elevated);--kj-dropdown-menu-fg: var(--kj-fg-default);--kj-dropdown-menu-border-color: var(--kj-border-default);--kj-dropdown-menu-radius: var(--kj-radius-box);--kj-dropdown-menu-padding: var(--kj-space-xs);--kj-dropdown-menu-shadow: var(--kj-shadow-md);display:flex;flex-direction:column;box-sizing:border-box;min-width:12rem;max-width:min(20rem,calc(100vw - 2rem));background:var(--kj-dropdown-menu-bg);color:var(--kj-dropdown-menu-fg);border:var(--kj-border) solid var(--kj-dropdown-menu-border-color);border-radius:var(--kj-dropdown-menu-radius);padding:var(--kj-dropdown-menu-padding);font:.875rem / 1.5 var(--kj-font-sans);box-shadow:var(--kj-dropdown-menu-shadow);pointer-events:auto;z-index:1000}.kj-dropdown-menu[hidden]{display:none}.kj-dropdown-menu-item{--kj-dropdown-menu-item-padding-x: var(--kj-space-md);--kj-dropdown-menu-item-padding-y: var(--kj-space-sm);--kj-dropdown-menu-item-min-height: 2.75rem;--kj-dropdown-menu-item-radius: var(--kj-radius-field);--kj-dropdown-menu-item-hover-bg: var(--kj-bg-surface);--kj-dropdown-menu-item-active-bg: var(--kj-bg-field);display:flex;align-items:center;justify-content:flex-start;gap:var(--kj-space-sm);width:100%;min-height:var(--kj-dropdown-menu-item-min-height);box-sizing:border-box;padding:var(--kj-dropdown-menu-item-padding-y) var(--kj-dropdown-menu-item-padding-x);margin:0;background:transparent;color:inherit;border:none;border-radius:var(--kj-dropdown-menu-item-radius);font:inherit;text-align:start;cursor:pointer;-webkit-user-select:none;user-select:none}.kj-dropdown-menu-item:hover:not([data-disabled]){background:var(--kj-dropdown-menu-item-hover-bg)}.kj-dropdown-menu-item:focus-visible{outline:2px solid var(--kj-bg-primary);outline-offset:-2px}.kj-dropdown-menu-item[aria-current=true]{background:var(--kj-dropdown-menu-item-current-bg, var(--kj-bg-field));color:var(--kj-dropdown-menu-item-current-fg, var(--kj-fg-primary));font-weight:500}.kj-dropdown-menu-item[data-disabled]{cursor:not-allowed;opacity:.5}.kj-dropdown-menu-separator{display:block;height:1px;margin:var(--kj-space-xs) calc(var(--kj-space-xs) * -1);background:color-mix(in oklab,var(--kj-fg-default) 12%,transparent);border:0}.kj-dropdown-menu-label{display:block;padding:var(--kj-space-xs) var(--kj-space-md);font-size:.75rem;font-weight:600;text-transform:uppercase;letter-spacing:.04em;color:var(--kj-fg-default);opacity:.65}.kj-dropdown-menu-group{display:flex;flex-direction:column}@media(prefers-reduced-motion:no-preference){.kj-dropdown-menu{transition:opacity .12s ease-out,transform .12s ease-out}.kj-dropdown-menu[data-state=closed]{opacity:0;transform:scale(.98)}.kj-dropdown-menu[data-state=open]{opacity:1;transform:scale(1)}}}\n"] }]
|
|
5394
|
+
}] });
|
|
5395
|
+
|
|
5396
|
+
/**
|
|
5397
|
+
* Styled wrapper around the headless `KjSpinner` directive.
|
|
5398
|
+
*
|
|
5399
|
+
* Composes `KjSpinner` via `hostDirectives` so the wrapper's host element is
|
|
5400
|
+
* *the* spinner — `role="status"`, `aria-live="polite"`, `aria-atomic="true"`,
|
|
5401
|
+
* the `aria-label` default ("Loading"), `data-animation`, and
|
|
5402
|
+
* `data-reduced-motion` all land on `<kj-spinner>` itself. `kjVariant` and
|
|
5403
|
+
* `kjSize` are wrapper-level inputs that the host mirrors to `data-variant` /
|
|
5404
|
+
* `data-size` (the directive's own nested `KjVariant` / `KjSize` host
|
|
5405
|
+
* directives are not transitively exposed through outer composition, so the
|
|
5406
|
+
* wrapper takes over the data-attribute reflection at this layer).
|
|
5407
|
+
*
|
|
5408
|
+
* The template renders an `aria-hidden` glyph element (the visual shape that
|
|
5409
|
+
* theme CSS keyframes drive per `data-animation`) and, when no
|
|
5410
|
+
* `aria-labelledby` was authored on the host, a `kjVisuallyHidden` label so
|
|
5411
|
+
* AT always finds an accessible name.
|
|
5412
|
+
*
|
|
5413
|
+
* **Indeterminate-only.** The spinner answers "something is happening" — it
|
|
5414
|
+
* has no value model. For "x of y" use Progress Bar; for missing-content
|
|
5415
|
+
* placeholders use Skeleton.
|
|
5416
|
+
*
|
|
5417
|
+
* @example
|
|
5418
|
+
* ```html
|
|
5419
|
+
* <kj-spinner />
|
|
5420
|
+
* <kj-spinner kjVariant="primary" kjSize="lg" kjAnimation="dots" kjAriaLabel="Sending" />
|
|
5421
|
+
* ```
|
|
5422
|
+
* @doc-example Default
|
|
5423
|
+
* The default playground — `spin` animation, `md` size, neutral variant,
|
|
5424
|
+
* default `aria-label="Loading"`.
|
|
5425
|
+
* @doc-file spinner.example.ts
|
|
5426
|
+
* @doc-example Usage
|
|
5427
|
+
* A walkthrough of the most common spinner usages — size, variant,
|
|
5428
|
+
* animation glyph, and inline placement next to copy.
|
|
5429
|
+
* @doc-file spinner.usage.example.ts
|
|
5430
|
+
* @doc-example Sizes
|
|
5431
|
+
* `xs` / `sm` / `md` / `lg` presets. There is intentionally no `xl` — that
|
|
5432
|
+
* size almost always wants a determinate Progress Bar instead.
|
|
5433
|
+
* @doc-file spinner.sizes.example.ts
|
|
5434
|
+
* @doc-example Variants
|
|
5435
|
+
* `neutral` (inherits `currentColor`), `primary`, `success`, `warning`,
|
|
5436
|
+
* `error`, `info`.
|
|
5437
|
+
* @doc-file spinner.variants.example.ts
|
|
5438
|
+
* @doc-example Animations
|
|
5439
|
+
* Animation shape preset — `spin`, `dots`, `bars`, etc. Themes own the
|
|
5440
|
+
* keyframes per value.
|
|
5441
|
+
* @doc-file spinner.animations.example.ts
|
|
5442
|
+
* @doc-example Inside a button
|
|
5443
|
+
* Embed the spinner inline next to a label to communicate in-flight work.
|
|
5444
|
+
* @doc-file spinner.in-button.example.ts
|
|
5445
|
+
*
|
|
5446
|
+
* @doc-keyboard
|
|
5447
|
+
* — — Non-interactive. The spinner is purely a status indicator.
|
|
5448
|
+
*
|
|
5449
|
+
* @doc-aria
|
|
5450
|
+
* role="status" — set on the host so AT announces it as a live status region
|
|
5451
|
+
* aria-live — "polite" so the label is read without interrupting the user
|
|
5452
|
+
* aria-atomic — "true" so the full label is announced on change
|
|
5453
|
+
* aria-label — Defaults to "Loading"; override per context (e.g. "Sending")
|
|
5454
|
+
* data-animation — Mirrors the resolved animation for theme hooks
|
|
5455
|
+
* data-variant — Mirrors the resolved variant for theme hooks
|
|
5456
|
+
* data-size — Mirrors the resolved size for theme hooks
|
|
5457
|
+
*
|
|
5458
|
+
* @doc-touch
|
|
5459
|
+
* — — Non-interactive; no touch target required.
|
|
5460
|
+
*
|
|
5461
|
+
* @doc-a11y
|
|
5462
|
+
* Indeterminate-only — answers "something is happening", with no value model.
|
|
5463
|
+
* Honours `prefers-reduced-motion` via `data-reduced-motion` on the host, so
|
|
5464
|
+
* themes can swap a calmer animation. When the consumer authors
|
|
5465
|
+
* `aria-labelledby` on the host the wrapper skips the visually-hidden label
|
|
5466
|
+
* to avoid double-naming.
|
|
5467
|
+
*
|
|
5468
|
+
* @doc-related progress-bar,skeleton,toast
|
|
5469
|
+
*
|
|
5470
|
+
* @doc-css-var
|
|
5471
|
+
* --kj-spinner-size — Glyph diameter. Sizes (xs/sm/md/lg) override.
|
|
5472
|
+
* --kj-spinner-color — Foreground color of the glyph. Variants set this; neutral inherits currentColor.
|
|
5473
|
+
* --kj-spinner-track — Track/background color for the spin arc.
|
|
5474
|
+
* --kj-spinner-duration — Base animation duration. Other animations scale off this.
|
|
5475
|
+
*
|
|
5476
|
+
* @doc-category Library/Feedback
|
|
5477
|
+
* @doc
|
|
5478
|
+
* @doc-name spinner
|
|
5479
|
+
* @doc-description Themed indeterminate loading spinner with variant, size, and animation glyph options.
|
|
5480
|
+
* @doc-is-main
|
|
5481
|
+
*/
|
|
5482
|
+
class KjSpinnerComponent {
|
|
5483
|
+
/**
|
|
5484
|
+
* Color preset reflected to `data-variant` on the host. Defaults to
|
|
5485
|
+
* `'neutral'`, which resolves to `currentColor` in shipped themes — so a
|
|
5486
|
+
* spinner inside a coloured surface inherits its parent's text colour.
|
|
5487
|
+
*/
|
|
5488
|
+
kjVariant = input('neutral', /* @ts-ignore */
|
|
5489
|
+
...(ngDevMode ? [{ debugName: "kjVariant" }] : /* istanbul ignore next */ []));
|
|
5490
|
+
/**
|
|
5491
|
+
* Size preset reflected to `data-size` on the host. Defaults to `'md'`.
|
|
5492
|
+
* Sizes ship as `xs | sm | md | lg`; an `xl` is intentionally absent — a
|
|
5493
|
+
* spinner that big almost always wants a determinate Progress Bar instead.
|
|
5494
|
+
*/
|
|
5495
|
+
kjSize = input('md', /* @ts-ignore */
|
|
5496
|
+
...(ngDevMode ? [{ debugName: "kjSize" }] : /* istanbul ignore next */ []));
|
|
5497
|
+
/**
|
|
5498
|
+
* Animation shape preset forwarded to `KjSpinner.kjAnimation` via the
|
|
5499
|
+
* composed host directive. Reflects on the host as `data-animation`.
|
|
5500
|
+
* Themes own the keyframes per value.
|
|
5501
|
+
*/
|
|
5502
|
+
kjAnimation = input('spin', /* @ts-ignore */
|
|
5503
|
+
...(ngDevMode ? [{ debugName: "kjAnimation" }] : /* istanbul ignore next */ []));
|
|
5504
|
+
/**
|
|
5505
|
+
* Accessible name forwarded to `KjSpinner.kjAriaLabel` via the composed
|
|
5506
|
+
* host directive. Default `'Loading'`. Used both as the host's
|
|
5507
|
+
* `aria-label` and as the visually-hidden text rendered inside the
|
|
5508
|
+
* wrapper when no consumer-authored `aria-labelledby` is on the element.
|
|
5509
|
+
*/
|
|
5510
|
+
kjAriaLabel = input('Loading', /* @ts-ignore */
|
|
5511
|
+
...(ngDevMode ? [{ debugName: "kjAriaLabel" }] : /* istanbul ignore next */ []));
|
|
5512
|
+
el = inject(ElementRef);
|
|
5513
|
+
/**
|
|
5514
|
+
* Snapshotted at construction: did the consumer author `aria-labelledby`
|
|
5515
|
+
* directly on `<kj-spinner>`? If so the accessible name is the referenced
|
|
5516
|
+
* element and we must not project a hidden duplicate. Read in the
|
|
5517
|
+
* constructor — by the time the template renders the directive may have
|
|
5518
|
+
* stamped its own attributes on the host.
|
|
5519
|
+
*/
|
|
5520
|
+
hasAuthoredLabelledBy;
|
|
5521
|
+
/**
|
|
5522
|
+
* `true` when the consumer did **not** author `aria-labelledby` on the
|
|
5523
|
+
* wrapper — i.e. the spinner's accessible name is its `aria-label`. The
|
|
5524
|
+
* wrapper renders a `kjVisuallyHidden` copy of the label as inner text so
|
|
5525
|
+
* AT that prefers content over `aria-label` (or that announces a
|
|
5526
|
+
* `role="status"` region's body on insertion) still has a name to read.
|
|
5527
|
+
* A consumer-authored `aria-labelledby` opts out of that hidden copy to
|
|
5528
|
+
* avoid double-naming the host.
|
|
5529
|
+
*/
|
|
5530
|
+
shouldRenderHiddenLabel = computed(() => !this.hasAuthoredLabelledBy, /* @ts-ignore */
|
|
5531
|
+
...(ngDevMode ? [{ debugName: "shouldRenderHiddenLabel" }] : /* istanbul ignore next */ []));
|
|
5532
|
+
constructor() {
|
|
5533
|
+
this.hasAuthoredLabelledBy =
|
|
5534
|
+
this.el.nativeElement.hasAttribute('aria-labelledby');
|
|
5535
|
+
}
|
|
5536
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjSpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5537
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: KjSpinnerComponent, isStandalone: true, selector: "kj-spinner", inputs: { kjVariant: { classPropertyName: "kjVariant", publicName: "kjVariant", isSignal: true, isRequired: false, transformFunction: null }, kjSize: { classPropertyName: "kjSize", publicName: "kjSize", isSignal: true, isRequired: false, transformFunction: null }, kjAnimation: { classPropertyName: "kjAnimation", publicName: "kjAnimation", isSignal: true, isRequired: false, transformFunction: null }, kjAriaLabel: { classPropertyName: "kjAriaLabel", publicName: "kjAriaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-variant": "kjVariant()", "attr.data-size": "kjSize()" }, classAttribute: "kj-spinner" }, hostDirectives: [{ directive: i1.KjSpinner, inputs: ["kjAnimation", "kjAnimation", "kjAriaLabel", "kjAriaLabel"] }], ngImport: i0, template: `
|
|
5538
|
+
<span class="kj-spinner__glyph" aria-hidden="true"></span>
|
|
5539
|
+
@if (shouldRenderHiddenLabel()) {
|
|
5540
|
+
<span kjVisuallyHidden>{{ kjAriaLabel() }}</span>
|
|
5541
|
+
}
|
|
5542
|
+
`, isInline: true, styles: ["@layer kj.component{.kj-spinner{--kj-spinner-size: 1.25rem;--kj-spinner-color: currentColor;--kj-spinner-track: color-mix(in srgb, currentColor 20%, transparent);--kj-spinner-duration: .7s;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--kj-spinner-size);block-size:var(--kj-spinner-size);color:var(--kj-spinner-color);pointer-events:none}.kj-spinner[data-size=xs]{--kj-spinner-size: .75rem}.kj-spinner[data-size=sm]{--kj-spinner-size: 1rem}.kj-spinner[data-size=md]{--kj-spinner-size: 1.25rem}.kj-spinner[data-size=lg]{--kj-spinner-size: 1.75rem}.kj-spinner[data-variant=neutral]{--kj-spinner-color: currentColor}.kj-spinner[data-variant=primary]{--kj-spinner-color: var(--kj-fg-primary)}.kj-spinner[data-variant=secondary]{--kj-spinner-color: var(--kj-fg-default)}.kj-spinner[data-variant=success]{--kj-spinner-color: var(--kj-fg-success, #16a34a)}.kj-spinner[data-variant=warning]{--kj-spinner-color: var(--kj-fg-warning, #d97706)}.kj-spinner[data-variant=error]{--kj-spinner-color: var(--kj-fg-danger, #dc2626)}.kj-spinner[data-variant=info]{--kj-spinner-color: var(--kj-fg-info, #2563eb)}.kj-spinner__glyph{display:inline-block;inline-size:100%;block-size:100%}.kj-spinner[data-animation=spin] .kj-spinner__glyph{border:2px solid var(--kj-spinner-track);border-block-start-color:var(--kj-spinner-color);border-radius:50%;animation:kj-spinner-spin var(--kj-spinner-duration) linear infinite}.kj-spinner[data-animation=pulse] .kj-spinner__glyph{background:var(--kj-spinner-color);border-radius:50%;animation:kj-spinner-pulse calc(var(--kj-spinner-duration) * 2) ease-in-out infinite}.kj-spinner[data-animation=dots]{inline-size:auto}.kj-spinner[data-animation=dots] .kj-spinner__glyph{display:inline-flex;gap:calc(var(--kj-spinner-size) * .25);inline-size:auto;block-size:100%}.kj-spinner[data-animation=dots] .kj-spinner__glyph:before,.kj-spinner[data-animation=dots] .kj-spinner__glyph:after{content:\"\";inline-size:calc(var(--kj-spinner-size) * .3);block-size:calc(var(--kj-spinner-size) * .3);background:var(--kj-spinner-color);border-radius:50%;animation:kj-spinner-dots calc(var(--kj-spinner-duration) * 2) ease-in-out infinite}.kj-spinner[data-animation=dots] .kj-spinner__glyph{background:transparent}.kj-spinner[data-animation=dots] .kj-spinner__glyph:after{animation-delay:calc(var(--kj-spinner-duration) * .4)}.kj-spinner[data-animation=bars]{inline-size:auto}.kj-spinner[data-animation=bars] .kj-spinner__glyph{display:inline-flex;align-items:stretch;gap:calc(var(--kj-spinner-size) * .15);inline-size:auto;block-size:100%}.kj-spinner[data-animation=bars] .kj-spinner__glyph:before,.kj-spinner[data-animation=bars] .kj-spinner__glyph:after{content:\"\";inline-size:calc(var(--kj-spinner-size) * .2);background:var(--kj-spinner-color);border-radius:calc(var(--kj-spinner-size) * .05);animation:kj-spinner-bars calc(var(--kj-spinner-duration) * 1.6) ease-in-out infinite;transform-origin:center}.kj-spinner[data-animation=bars] .kj-spinner__glyph:after{animation-delay:calc(var(--kj-spinner-duration) * .4)}.kj-spinner[data-reduced-motion=true] .kj-spinner__glyph,.kj-spinner[data-reduced-motion=true] .kj-spinner__glyph:before,.kj-spinner[data-reduced-motion=true] .kj-spinner__glyph:after{animation:kj-spinner-reduced-motion 1.6s ease-in-out infinite!important}}@keyframes kj-spinner-spin{to{transform:rotate(360deg)}}@keyframes kj-spinner-pulse{0%,to{opacity:.35;transform:scale(.85)}50%{opacity:1;transform:scale(1)}}@keyframes kj-spinner-dots{0%,80%,to{transform:scale(.4);opacity:.4}40%{transform:scale(1);opacity:1}}@keyframes kj-spinner-bars{0%,40%,to{transform:scaleY(.4)}20%{transform:scaleY(1)}}@keyframes kj-spinner-reduced-motion{0%,to{opacity:.45}50%{opacity:1}}\n"], dependencies: [{ kind: "directive", type: KjVisuallyHidden, selector: "[kjVisuallyHidden]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5543
|
+
}
|
|
5544
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjSpinnerComponent, decorators: [{
|
|
5545
|
+
type: Component,
|
|
5546
|
+
args: [{ selector: 'kj-spinner', standalone: true, imports: [KjVisuallyHidden], hostDirectives: [
|
|
5547
|
+
{
|
|
5548
|
+
directive: KjSpinner,
|
|
5549
|
+
// KjSpinner's own surface — kjVariant + kjSize live on its nested
|
|
5550
|
+
// KjVariant / KjSize and are not surfaced through this outer
|
|
5551
|
+
// composition; they are re-exposed as wrapper inputs below and wired
|
|
5552
|
+
// straight to the host's data-variant / data-size attributes.
|
|
5553
|
+
inputs: ['kjAnimation', 'kjAriaLabel'],
|
|
5554
|
+
},
|
|
5555
|
+
], template: `
|
|
5556
|
+
<span class="kj-spinner__glyph" aria-hidden="true"></span>
|
|
5557
|
+
@if (shouldRenderHiddenLabel()) {
|
|
5558
|
+
<span kjVisuallyHidden>{{ kjAriaLabel() }}</span>
|
|
5559
|
+
}
|
|
5560
|
+
`, encapsulation: ViewEncapsulation.None, host: {
|
|
5561
|
+
'class': 'kj-spinner',
|
|
5562
|
+
'[attr.data-variant]': 'kjVariant()',
|
|
5563
|
+
'[attr.data-size]': 'kjSize()',
|
|
5564
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-spinner{--kj-spinner-size: 1.25rem;--kj-spinner-color: currentColor;--kj-spinner-track: color-mix(in srgb, currentColor 20%, transparent);--kj-spinner-duration: .7s;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--kj-spinner-size);block-size:var(--kj-spinner-size);color:var(--kj-spinner-color);pointer-events:none}.kj-spinner[data-size=xs]{--kj-spinner-size: .75rem}.kj-spinner[data-size=sm]{--kj-spinner-size: 1rem}.kj-spinner[data-size=md]{--kj-spinner-size: 1.25rem}.kj-spinner[data-size=lg]{--kj-spinner-size: 1.75rem}.kj-spinner[data-variant=neutral]{--kj-spinner-color: currentColor}.kj-spinner[data-variant=primary]{--kj-spinner-color: var(--kj-fg-primary)}.kj-spinner[data-variant=secondary]{--kj-spinner-color: var(--kj-fg-default)}.kj-spinner[data-variant=success]{--kj-spinner-color: var(--kj-fg-success, #16a34a)}.kj-spinner[data-variant=warning]{--kj-spinner-color: var(--kj-fg-warning, #d97706)}.kj-spinner[data-variant=error]{--kj-spinner-color: var(--kj-fg-danger, #dc2626)}.kj-spinner[data-variant=info]{--kj-spinner-color: var(--kj-fg-info, #2563eb)}.kj-spinner__glyph{display:inline-block;inline-size:100%;block-size:100%}.kj-spinner[data-animation=spin] .kj-spinner__glyph{border:2px solid var(--kj-spinner-track);border-block-start-color:var(--kj-spinner-color);border-radius:50%;animation:kj-spinner-spin var(--kj-spinner-duration) linear infinite}.kj-spinner[data-animation=pulse] .kj-spinner__glyph{background:var(--kj-spinner-color);border-radius:50%;animation:kj-spinner-pulse calc(var(--kj-spinner-duration) * 2) ease-in-out infinite}.kj-spinner[data-animation=dots]{inline-size:auto}.kj-spinner[data-animation=dots] .kj-spinner__glyph{display:inline-flex;gap:calc(var(--kj-spinner-size) * .25);inline-size:auto;block-size:100%}.kj-spinner[data-animation=dots] .kj-spinner__glyph:before,.kj-spinner[data-animation=dots] .kj-spinner__glyph:after{content:\"\";inline-size:calc(var(--kj-spinner-size) * .3);block-size:calc(var(--kj-spinner-size) * .3);background:var(--kj-spinner-color);border-radius:50%;animation:kj-spinner-dots calc(var(--kj-spinner-duration) * 2) ease-in-out infinite}.kj-spinner[data-animation=dots] .kj-spinner__glyph{background:transparent}.kj-spinner[data-animation=dots] .kj-spinner__glyph:after{animation-delay:calc(var(--kj-spinner-duration) * .4)}.kj-spinner[data-animation=bars]{inline-size:auto}.kj-spinner[data-animation=bars] .kj-spinner__glyph{display:inline-flex;align-items:stretch;gap:calc(var(--kj-spinner-size) * .15);inline-size:auto;block-size:100%}.kj-spinner[data-animation=bars] .kj-spinner__glyph:before,.kj-spinner[data-animation=bars] .kj-spinner__glyph:after{content:\"\";inline-size:calc(var(--kj-spinner-size) * .2);background:var(--kj-spinner-color);border-radius:calc(var(--kj-spinner-size) * .05);animation:kj-spinner-bars calc(var(--kj-spinner-duration) * 1.6) ease-in-out infinite;transform-origin:center}.kj-spinner[data-animation=bars] .kj-spinner__glyph:after{animation-delay:calc(var(--kj-spinner-duration) * .4)}.kj-spinner[data-reduced-motion=true] .kj-spinner__glyph,.kj-spinner[data-reduced-motion=true] .kj-spinner__glyph:before,.kj-spinner[data-reduced-motion=true] .kj-spinner__glyph:after{animation:kj-spinner-reduced-motion 1.6s ease-in-out infinite!important}}@keyframes kj-spinner-spin{to{transform:rotate(360deg)}}@keyframes kj-spinner-pulse{0%,to{opacity:.35;transform:scale(.85)}50%{opacity:1;transform:scale(1)}}@keyframes kj-spinner-dots{0%,80%,to{transform:scale(.4);opacity:.4}40%{transform:scale(1);opacity:1}}@keyframes kj-spinner-bars{0%,40%,to{transform:scaleY(.4)}20%{transform:scaleY(1)}}@keyframes kj-spinner-reduced-motion{0%,to{opacity:.45}50%{opacity:1}}\n"] }]
|
|
5565
|
+
}], ctorParameters: () => [], propDecorators: { kjVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjVariant", required: false }] }], kjSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjSize", required: false }] }], kjAnimation: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjAnimation", required: false }] }], kjAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjAriaLabel", required: false }] }] } });
|
|
5566
|
+
|
|
5567
|
+
/**
|
|
5568
|
+
* Styled code editor — a themed `<kj-editor>` wrapping the headless `KjEditor`
|
|
5569
|
+
* directive (which wraps Monaco). Adds a kj-token-synced Monaco theme that
|
|
5570
|
+
* re-applies on theme switch, an optional toolbar (language badge + copy) and
|
|
5571
|
+
* status bar (cursor position + a keyboard-escape hint), reduced-motion, and a
|
|
5572
|
+
* loading region.
|
|
5573
|
+
*
|
|
5574
|
+
* Monaco is browser-only and heavy; it loads lazily after first render via
|
|
5575
|
+
* `KjEditorLoader`. Configure the source app-wide with `provideMonaco()`
|
|
5576
|
+
* (defaults to a CDN loader so the base bundle stays lean).
|
|
5577
|
+
*
|
|
5578
|
+
* @example
|
|
5579
|
+
* ```html
|
|
5580
|
+
* <kj-editor [(kjValue)]="code" kjLanguage="typescript" style="height:340px" />
|
|
5581
|
+
* ```
|
|
5582
|
+
* @doc-category Components/Data
|
|
5583
|
+
* @doc
|
|
5584
|
+
* @doc-name editor
|
|
5585
|
+
* @doc-is-main
|
|
5586
|
+
* @doc-description Themed Monaco code editor — syntax highlighting, two-way value, kj-theme sync, and AAA keyboard access.
|
|
5587
|
+
* @doc-example Default [full]
|
|
5588
|
+
* A TypeScript editor with the toolbar and status bar, two-way bound to a signal.
|
|
5589
|
+
* @doc-file editor.example.ts
|
|
5590
|
+
* @doc-example Languages [full]
|
|
5591
|
+
* Switch the `kjLanguage` to re-tokenise the same buffer across TS / HTML / CSS / JSON.
|
|
5592
|
+
* @doc-file editor.languages.example.ts
|
|
5593
|
+
* @doc-example Read-only [full]
|
|
5594
|
+
* A read-only viewer with the minimap enabled and line numbers on.
|
|
5595
|
+
* @doc-file editor.readonly.example.ts
|
|
5596
|
+
* @doc-example Options [full]
|
|
5597
|
+
* Toggle readonly, minimap, word wrap, line numbers and font size live.
|
|
5598
|
+
* @doc-file editor.options.example.ts
|
|
5599
|
+
*
|
|
5600
|
+
* @doc-keyboard
|
|
5601
|
+
* Tab Inserts a tab / indents (Monaco default)
|
|
5602
|
+
* Ctrl+M Toggles Tab-trapping — flips Tab to move focus in/out (no keyboard trap)
|
|
5603
|
+
* Alt+F1 Opens Monaco's accessibility help
|
|
5604
|
+
* Standard editing keys Arrow / Home / End / PageUp-Down / selection / undo-redo
|
|
5605
|
+
*
|
|
5606
|
+
* @doc-aria
|
|
5607
|
+
* aria-label Monaco's textarea is labelled from kjAriaLabel (defaults to "Code editor")
|
|
5608
|
+
* role=status The loading region announces the editor is loading
|
|
4052
5609
|
*/
|
|
4053
|
-
class
|
|
4054
|
-
|
|
4055
|
-
|
|
5610
|
+
class KjEditorComponent {
|
|
5611
|
+
hostRef = inject(ElementRef);
|
|
5612
|
+
destroyRef = inject(DestroyRef);
|
|
5613
|
+
loader = inject(KjEditorLoader);
|
|
5614
|
+
editorHost = viewChild.required('editorHost');
|
|
5615
|
+
/** Two-way editor text. */
|
|
5616
|
+
kjValue = model('', /* @ts-ignore */
|
|
5617
|
+
...(ngDevMode ? [{ debugName: "kjValue" }] : /* istanbul ignore next */ []));
|
|
5618
|
+
/** Code language — friendly name or Monaco id; short aliases (`ts`, `md`) normalised. */
|
|
5619
|
+
kjLanguage = input('plaintext', /* @ts-ignore */
|
|
5620
|
+
...(ngDevMode ? [{ debugName: "kjLanguage" }] : /* istanbul ignore next */ []));
|
|
5621
|
+
/** Read-only mode. */
|
|
5622
|
+
kjReadonly = input(false, /* @ts-ignore */
|
|
5623
|
+
...(ngDevMode ? [{ debugName: "kjReadonly" }] : /* istanbul ignore next */ []));
|
|
5624
|
+
/** Show the minimap. */
|
|
5625
|
+
kjMinimap = input(false, /* @ts-ignore */
|
|
5626
|
+
...(ngDevMode ? [{ debugName: "kjMinimap" }] : /* istanbul ignore next */ []));
|
|
5627
|
+
/** Gutter line-number mode. */
|
|
5628
|
+
kjLineNumbers = input('on', /* @ts-ignore */
|
|
5629
|
+
...(ngDevMode ? [{ debugName: "kjLineNumbers" }] : /* istanbul ignore next */ []));
|
|
5630
|
+
/** Soft wrap. */
|
|
5631
|
+
kjWordWrap = input('off', /* @ts-ignore */
|
|
5632
|
+
...(ngDevMode ? [{ debugName: "kjWordWrap" }] : /* istanbul ignore next */ []));
|
|
5633
|
+
/** Font size in px. */
|
|
5634
|
+
kjFontSize = input(13, /* @ts-ignore */
|
|
5635
|
+
...(ngDevMode ? [{ debugName: "kjFontSize" }] : /* istanbul ignore next */ []));
|
|
5636
|
+
/** Grow to fit content instead of filling the container (great for code snippets). */
|
|
5637
|
+
kjAutoHeight = input(false, /* @ts-ignore */
|
|
5638
|
+
...(ngDevMode ? [{ debugName: "kjAutoHeight" }] : /* istanbul ignore next */ []));
|
|
5639
|
+
/** Cap for `kjAutoHeight` in px (content scrolls past it). Uncapped when unset. */
|
|
5640
|
+
kjMaxHeight = input(undefined, /* @ts-ignore */
|
|
5641
|
+
...(ngDevMode ? [{ debugName: "kjMaxHeight" }] : /* istanbul ignore next */ []));
|
|
5642
|
+
/** Accessible name for the editor. */
|
|
5643
|
+
kjAriaLabel = input('Code editor', /* @ts-ignore */
|
|
5644
|
+
...(ngDevMode ? [{ debugName: "kjAriaLabel" }] : /* istanbul ignore next */ []));
|
|
5645
|
+
/** Start with Tab moving focus out instead of indenting. */
|
|
5646
|
+
kjTabFocusMode = input(false, /* @ts-ignore */
|
|
5647
|
+
...(ngDevMode ? [{ debugName: "kjTabFocusMode" }] : /* istanbul ignore next */ []));
|
|
5648
|
+
/** Escape hatch — merged last into Monaco's construction options. */
|
|
5649
|
+
kjOptions = input({}, /* @ts-ignore */
|
|
5650
|
+
...(ngDevMode ? [{ debugName: "kjOptions" }] : /* istanbul ignore next */ []));
|
|
5651
|
+
/** Show the toolbar (language badge + copy button). */
|
|
5652
|
+
kjShowToolbar = input(true, /* @ts-ignore */
|
|
5653
|
+
...(ngDevMode ? [{ debugName: "kjShowToolbar" }] : /* istanbul ignore next */ []));
|
|
5654
|
+
/** Show the status bar (cursor position + keyboard hint). */
|
|
5655
|
+
kjShowStatusBar = input(true, /* @ts-ignore */
|
|
5656
|
+
...(ngDevMode ? [{ debugName: "kjShowStatusBar" }] : /* istanbul ignore next */ []));
|
|
5657
|
+
/** True until Monaco has mounted. */
|
|
5658
|
+
loading = signal(true, /* @ts-ignore */
|
|
5659
|
+
...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
5660
|
+
/** Cursor position for the status bar. */
|
|
5661
|
+
line = signal(1, /* @ts-ignore */
|
|
5662
|
+
...(ngDevMode ? [{ debugName: "line" }] : /* istanbul ignore next */ []));
|
|
5663
|
+
column = signal(1, /* @ts-ignore */
|
|
5664
|
+
...(ngDevMode ? [{ debugName: "column" }] : /* istanbul ignore next */ []));
|
|
5665
|
+
copied = signal(false, /* @ts-ignore */
|
|
5666
|
+
...(ngDevMode ? [{ debugName: "copied" }] : /* istanbul ignore next */ []));
|
|
5667
|
+
/** Current kj-derived Monaco theme id, bound onto the directive. */
|
|
5668
|
+
themeId = signal('vs', /* @ts-ignore */
|
|
5669
|
+
...(ngDevMode ? [{ debugName: "themeId" }] : /* istanbul ignore next */ []));
|
|
5670
|
+
/** Human label for the platform-appropriate tab-escape shortcut. */
|
|
5671
|
+
escapeHint = computed(() => 'Press Ctrl+M to toggle Tab trapping', /* @ts-ignore */
|
|
5672
|
+
...(ngDevMode ? [{ debugName: "escapeHint" }] : /* istanbul ignore next */ []));
|
|
5673
|
+
monaco = null;
|
|
5674
|
+
constructor() {
|
|
5675
|
+
afterNextRender(() => {
|
|
5676
|
+
void this.syncTheme();
|
|
5677
|
+
// Re-apply the kj Monaco theme when the app theme switches.
|
|
5678
|
+
if (typeof MutationObserver !== 'undefined') {
|
|
5679
|
+
const obs = new MutationObserver(() => void this.syncTheme());
|
|
5680
|
+
obs.observe(document.documentElement, {
|
|
5681
|
+
attributes: true,
|
|
5682
|
+
attributeFilter: ['data-theme', 'class'],
|
|
5683
|
+
});
|
|
5684
|
+
this.destroyRef.onDestroy(() => obs.disconnect());
|
|
5685
|
+
}
|
|
5686
|
+
});
|
|
5687
|
+
}
|
|
5688
|
+
/** Wired from the directive's `kjReady` output. */
|
|
5689
|
+
onReady(editor) {
|
|
5690
|
+
this.loading.set(false);
|
|
5691
|
+
editor.onDidChangeCursorPosition((e) => {
|
|
5692
|
+
this.line.set(e.position.lineNumber);
|
|
5693
|
+
this.column.set(e.position.column);
|
|
5694
|
+
});
|
|
5695
|
+
void this.syncTheme();
|
|
5696
|
+
}
|
|
5697
|
+
async copy() {
|
|
5698
|
+
try {
|
|
5699
|
+
await navigator.clipboard.writeText(this.kjValue());
|
|
5700
|
+
this.copied.set(true);
|
|
5701
|
+
setTimeout(() => this.copied.set(false), 1500);
|
|
5702
|
+
}
|
|
5703
|
+
catch {
|
|
5704
|
+
// Clipboard unavailable (insecure context / denied) — no-op.
|
|
5705
|
+
}
|
|
5706
|
+
}
|
|
5707
|
+
/**
|
|
5708
|
+
* Read the resolved `--kj-*` surface tokens off the host, derive the scheme
|
|
5709
|
+
* from background luminance (theme-agnostic — works for any kj theme), define
|
|
5710
|
+
* a Monaco theme tinted with those tokens, and apply it globally.
|
|
5711
|
+
*/
|
|
5712
|
+
async syncTheme() {
|
|
5713
|
+
if (!this.monaco) {
|
|
5714
|
+
try {
|
|
5715
|
+
this.monaco = await this.loader.load();
|
|
5716
|
+
}
|
|
5717
|
+
catch {
|
|
5718
|
+
return;
|
|
5719
|
+
}
|
|
5720
|
+
}
|
|
5721
|
+
const monaco = this.monaco;
|
|
5722
|
+
if (!monaco || typeof getComputedStyle === 'undefined')
|
|
5723
|
+
return;
|
|
5724
|
+
const bg = this.resolveColor('--kj-bg-surface') ?? [255, 255, 255];
|
|
5725
|
+
const fg = this.resolveColor('--kj-fg-default') ?? [30, 30, 30];
|
|
5726
|
+
const muted = this.resolveColor('--kj-fg-muted') ?? [130, 130, 130];
|
|
5727
|
+
const accent = this.resolveColor('--kj-bg-primary') ?? [90, 120, 255];
|
|
5728
|
+
const dark = luminance(bg) < 0.5;
|
|
5729
|
+
const id = dark ? 'kj-editor-dark' : 'kj-editor-light';
|
|
5730
|
+
monaco.editor.defineTheme(id, {
|
|
5731
|
+
base: dark ? 'vs-dark' : 'vs',
|
|
5732
|
+
inherit: true,
|
|
5733
|
+
rules: [],
|
|
5734
|
+
colors: {
|
|
5735
|
+
'editor.background': hex(bg),
|
|
5736
|
+
'editor.foreground': hex(fg),
|
|
5737
|
+
'editorLineNumber.foreground': hex(muted),
|
|
5738
|
+
'editorLineNumber.activeForeground': hex(fg),
|
|
5739
|
+
'editorCursor.foreground': hex(accent),
|
|
5740
|
+
'editor.selectionBackground': hex(accent) + '55',
|
|
5741
|
+
'editorGutter.background': hex(bg),
|
|
5742
|
+
},
|
|
5743
|
+
});
|
|
5744
|
+
monaco.editor.setTheme(id);
|
|
5745
|
+
this.themeId.set(id);
|
|
5746
|
+
}
|
|
5747
|
+
/** Resolve a CSS custom property to [r,g,b] via a probe element. */
|
|
5748
|
+
resolveColor(varName) {
|
|
5749
|
+
const host = this.hostRef.nativeElement;
|
|
5750
|
+
const probe = document.createElement('span');
|
|
5751
|
+
probe.style.color = `var(${varName})`;
|
|
5752
|
+
probe.style.display = 'none';
|
|
5753
|
+
host.appendChild(probe);
|
|
5754
|
+
const rgb = getComputedStyle(probe).color;
|
|
5755
|
+
host.removeChild(probe);
|
|
5756
|
+
const m = rgb.match(/rgba?\(([^)]+)\)/);
|
|
5757
|
+
if (!m)
|
|
5758
|
+
return null;
|
|
5759
|
+
const parts = m[1].split(',').map((p) => parseFloat(p.trim()));
|
|
5760
|
+
if (parts.length < 3 || parts.some(Number.isNaN))
|
|
5761
|
+
return null;
|
|
5762
|
+
return [parts[0], parts[1], parts[2]];
|
|
5763
|
+
}
|
|
5764
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5765
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: KjEditorComponent, isStandalone: true, selector: "kj-editor", inputs: { kjValue: { classPropertyName: "kjValue", publicName: "kjValue", isSignal: true, isRequired: false, transformFunction: null }, kjLanguage: { classPropertyName: "kjLanguage", publicName: "kjLanguage", isSignal: true, isRequired: false, transformFunction: null }, kjReadonly: { classPropertyName: "kjReadonly", publicName: "kjReadonly", isSignal: true, isRequired: false, transformFunction: null }, kjMinimap: { classPropertyName: "kjMinimap", publicName: "kjMinimap", isSignal: true, isRequired: false, transformFunction: null }, kjLineNumbers: { classPropertyName: "kjLineNumbers", publicName: "kjLineNumbers", isSignal: true, isRequired: false, transformFunction: null }, kjWordWrap: { classPropertyName: "kjWordWrap", publicName: "kjWordWrap", isSignal: true, isRequired: false, transformFunction: null }, kjFontSize: { classPropertyName: "kjFontSize", publicName: "kjFontSize", isSignal: true, isRequired: false, transformFunction: null }, kjAutoHeight: { classPropertyName: "kjAutoHeight", publicName: "kjAutoHeight", isSignal: true, isRequired: false, transformFunction: null }, kjMaxHeight: { classPropertyName: "kjMaxHeight", publicName: "kjMaxHeight", isSignal: true, isRequired: false, transformFunction: null }, kjAriaLabel: { classPropertyName: "kjAriaLabel", publicName: "kjAriaLabel", isSignal: true, isRequired: false, transformFunction: null }, kjTabFocusMode: { classPropertyName: "kjTabFocusMode", publicName: "kjTabFocusMode", isSignal: true, isRequired: false, transformFunction: null }, kjOptions: { classPropertyName: "kjOptions", publicName: "kjOptions", isSignal: true, isRequired: false, transformFunction: null }, kjShowToolbar: { classPropertyName: "kjShowToolbar", publicName: "kjShowToolbar", isSignal: true, isRequired: false, transformFunction: null }, kjShowStatusBar: { classPropertyName: "kjShowStatusBar", publicName: "kjShowStatusBar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { kjValue: "kjValueChange" }, host: { properties: { "attr.data-auto-height": "kjAutoHeight() ? '' : null" } }, viewQueries: [{ propertyName: "editorHost", first: true, predicate: ["editorHost"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"kj-editor-wrap\">\n @if (kjShowToolbar()) {\n <div class=\"kj-editor-toolbar\">\n <span class=\"kj-editor-lang\">{{ kjLanguage() }}</span>\n <span class=\"kj-editor-spacer\"></span>\n <button\n type=\"button\"\n class=\"kj-editor-copy\"\n (click)=\"copy()\"\n [attr.aria-label]=\"copied() ? 'Copied' : 'Copy code'\"\n >\n {{ copied() ? 'Copied' : 'Copy' }}\n </button>\n </div>\n }\n\n <div class=\"kj-editor-body\">\n <div\n #editorHost\n class=\"kj-editor-host\"\n kjEditor\n [(kjValue)]=\"kjValue\"\n [kjLanguage]=\"kjLanguage()\"\n [kjReadonly]=\"kjReadonly()\"\n [kjMinimap]=\"kjMinimap()\"\n [kjLineNumbers]=\"kjLineNumbers()\"\n [kjWordWrap]=\"kjWordWrap()\"\n [kjFontSize]=\"kjFontSize()\"\n [kjAutoHeight]=\"kjAutoHeight()\"\n [kjMaxHeight]=\"kjMaxHeight()\"\n [kjAriaLabel]=\"kjAriaLabel()\"\n [kjTabFocusMode]=\"kjTabFocusMode()\"\n [kjTheme]=\"themeId()\"\n [kjOptions]=\"kjOptions()\"\n (kjReady)=\"onReady($event)\"\n ></div>\n\n @if (loading()) {\n <div class=\"kj-editor-loading\" role=\"status\" aria-live=\"polite\">\n <kj-spinner kjAriaLabel=\"Loading editor\" />\n </div>\n }\n </div>\n\n @if (kjShowStatusBar()) {\n <div class=\"kj-editor-status\">\n <span class=\"kj-editor-pos\">Ln {{ line() }}, Col {{ column() }}</span>\n <span class=\"kj-editor-spacer\"></span>\n <span class=\"kj-editor-hint\">{{ escapeHint() }}</span>\n </div>\n }\n</div>\n", styles: [":host{display:block;border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-md, 0);overflow:hidden;background:var(--kj-bg-surface)}.kj-editor-wrap{display:flex;flex-direction:column;height:100%;min-height:12rem}:host([data-auto-height]){height:auto}:host([data-auto-height]) .kj-editor-wrap{height:auto;min-height:0}:host([data-auto-height]) .kj-editor-body{position:static;flex:none;min-height:3rem}:host([data-auto-height]) .kj-editor-host{position:relative;inset:auto}.kj-editor-toolbar,.kj-editor-status{display:flex;align-items:center;gap:var(--kj-space-sm);padding:var(--kj-space-sm) var(--kj-space-lg);background:var(--kj-bg-body);flex-shrink:0}.kj-editor-toolbar{border-bottom:1px solid var(--kj-border-default)}.kj-editor-status{border-top:1px solid var(--kj-border-default)}.kj-editor-spacer{flex:1}.kj-editor-lang{font-family:var(--kj-font-mono);font-size:.65rem;letter-spacing:.12em;text-transform:uppercase;color:var(--kj-fg-primary);background:color-mix(in oklab,var(--kj-bg-primary) 8%,transparent);padding:.15rem var(--kj-space-sm);border:1px solid color-mix(in oklab,var(--kj-bg-primary) 22%,transparent)}.kj-editor-copy{background:none;border:none;color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.7rem;letter-spacing:.06em;cursor:pointer;min-height:44px;min-width:44px;padding:0 var(--kj-space-sm);transition:color .15s}.kj-editor-copy:hover{color:var(--kj-fg-default)}.kj-editor-copy:focus-visible{outline:2px solid var(--kj-border-focus, var(--kj-bg-primary));outline-offset:2px}.kj-editor-pos{font-family:var(--kj-font-mono);font-size:.7rem;color:var(--kj-fg-muted)}.kj-editor-hint{font-size:.7rem;color:var(--kj-fg-muted)}.kj-editor-body{position:relative;flex:1;min-height:8rem}.kj-editor-host{position:absolute;inset:0;overflow:hidden}.kj-editor-loading{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:var(--kj-bg-surface);z-index:1}.kj-editor-host ::ng-deep .monaco-editor,.kj-editor-host ::ng-deep .monaco-editor-background,.kj-editor-host ::ng-deep .monaco-editor .margin{background-color:var(--kj-bg-surface)!important}.kj-editor-host ::ng-deep .monaco-editor .scrollbar .slider{background:var(--kj-bg-field, var(--kj-bg-elevated))!important}@media(prefers-reduced-motion:reduce){.kj-editor-copy{transition:none}}\n"], dependencies: [{ kind: "directive", type: KjEditor, selector: "[kjEditor]", inputs: ["kjValue", "kjLanguage", "kjReadonly", "kjMinimap", "kjLineNumbers", "kjWordWrap", "kjFontSize", "kjAutoHeight", "kjMaxHeight", "kjTheme", "kjAriaLabel", "kjTabFocusMode", "kjOptions"], outputs: ["kjValueChange", "kjReady"], exportAs: ["kjEditor"] }, { kind: "component", type: KjSpinnerComponent, selector: "kj-spinner", inputs: ["kjVariant", "kjSize", "kjAnimation", "kjAriaLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4056
5766
|
}
|
|
4057
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type:
|
|
5767
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjEditorComponent, decorators: [{
|
|
4058
5768
|
type: Component,
|
|
4059
|
-
args: [{ selector: 'kj-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
5769
|
+
args: [{ selector: 'kj-editor', standalone: true, imports: [KjEditor, KjSpinnerComponent], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
5770
|
+
'[attr.data-auto-height]': "kjAutoHeight() ? '' : null",
|
|
5771
|
+
}, template: "<div class=\"kj-editor-wrap\">\n @if (kjShowToolbar()) {\n <div class=\"kj-editor-toolbar\">\n <span class=\"kj-editor-lang\">{{ kjLanguage() }}</span>\n <span class=\"kj-editor-spacer\"></span>\n <button\n type=\"button\"\n class=\"kj-editor-copy\"\n (click)=\"copy()\"\n [attr.aria-label]=\"copied() ? 'Copied' : 'Copy code'\"\n >\n {{ copied() ? 'Copied' : 'Copy' }}\n </button>\n </div>\n }\n\n <div class=\"kj-editor-body\">\n <div\n #editorHost\n class=\"kj-editor-host\"\n kjEditor\n [(kjValue)]=\"kjValue\"\n [kjLanguage]=\"kjLanguage()\"\n [kjReadonly]=\"kjReadonly()\"\n [kjMinimap]=\"kjMinimap()\"\n [kjLineNumbers]=\"kjLineNumbers()\"\n [kjWordWrap]=\"kjWordWrap()\"\n [kjFontSize]=\"kjFontSize()\"\n [kjAutoHeight]=\"kjAutoHeight()\"\n [kjMaxHeight]=\"kjMaxHeight()\"\n [kjAriaLabel]=\"kjAriaLabel()\"\n [kjTabFocusMode]=\"kjTabFocusMode()\"\n [kjTheme]=\"themeId()\"\n [kjOptions]=\"kjOptions()\"\n (kjReady)=\"onReady($event)\"\n ></div>\n\n @if (loading()) {\n <div class=\"kj-editor-loading\" role=\"status\" aria-live=\"polite\">\n <kj-spinner kjAriaLabel=\"Loading editor\" />\n </div>\n }\n </div>\n\n @if (kjShowStatusBar()) {\n <div class=\"kj-editor-status\">\n <span class=\"kj-editor-pos\">Ln {{ line() }}, Col {{ column() }}</span>\n <span class=\"kj-editor-spacer\"></span>\n <span class=\"kj-editor-hint\">{{ escapeHint() }}</span>\n </div>\n }\n</div>\n", styles: [":host{display:block;border:1px solid var(--kj-border-default);border-radius:var(--kj-radius-md, 0);overflow:hidden;background:var(--kj-bg-surface)}.kj-editor-wrap{display:flex;flex-direction:column;height:100%;min-height:12rem}:host([data-auto-height]){height:auto}:host([data-auto-height]) .kj-editor-wrap{height:auto;min-height:0}:host([data-auto-height]) .kj-editor-body{position:static;flex:none;min-height:3rem}:host([data-auto-height]) .kj-editor-host{position:relative;inset:auto}.kj-editor-toolbar,.kj-editor-status{display:flex;align-items:center;gap:var(--kj-space-sm);padding:var(--kj-space-sm) var(--kj-space-lg);background:var(--kj-bg-body);flex-shrink:0}.kj-editor-toolbar{border-bottom:1px solid var(--kj-border-default)}.kj-editor-status{border-top:1px solid var(--kj-border-default)}.kj-editor-spacer{flex:1}.kj-editor-lang{font-family:var(--kj-font-mono);font-size:.65rem;letter-spacing:.12em;text-transform:uppercase;color:var(--kj-fg-primary);background:color-mix(in oklab,var(--kj-bg-primary) 8%,transparent);padding:.15rem var(--kj-space-sm);border:1px solid color-mix(in oklab,var(--kj-bg-primary) 22%,transparent)}.kj-editor-copy{background:none;border:none;color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.7rem;letter-spacing:.06em;cursor:pointer;min-height:44px;min-width:44px;padding:0 var(--kj-space-sm);transition:color .15s}.kj-editor-copy:hover{color:var(--kj-fg-default)}.kj-editor-copy:focus-visible{outline:2px solid var(--kj-border-focus, var(--kj-bg-primary));outline-offset:2px}.kj-editor-pos{font-family:var(--kj-font-mono);font-size:.7rem;color:var(--kj-fg-muted)}.kj-editor-hint{font-size:.7rem;color:var(--kj-fg-muted)}.kj-editor-body{position:relative;flex:1;min-height:8rem}.kj-editor-host{position:absolute;inset:0;overflow:hidden}.kj-editor-loading{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:var(--kj-bg-surface);z-index:1}.kj-editor-host ::ng-deep .monaco-editor,.kj-editor-host ::ng-deep .monaco-editor-background,.kj-editor-host ::ng-deep .monaco-editor .margin{background-color:var(--kj-bg-surface)!important}.kj-editor-host ::ng-deep .monaco-editor .scrollbar .slider{background:var(--kj-bg-field, var(--kj-bg-elevated))!important}@media(prefers-reduced-motion:reduce){.kj-editor-copy{transition:none}}\n"] }]
|
|
5772
|
+
}], ctorParameters: () => [], propDecorators: { editorHost: [{ type: i0.ViewChild, args: ['editorHost', { isSignal: true }] }], kjValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjValue", required: false }] }, { type: i0.Output, args: ["kjValueChange"] }], kjLanguage: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjLanguage", required: false }] }], kjReadonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjReadonly", required: false }] }], kjMinimap: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjMinimap", required: false }] }], kjLineNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjLineNumbers", required: false }] }], kjWordWrap: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjWordWrap", required: false }] }], kjFontSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjFontSize", required: false }] }], kjAutoHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjAutoHeight", required: false }] }], kjMaxHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjMaxHeight", required: false }] }], kjAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjAriaLabel", required: false }] }], kjTabFocusMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjTabFocusMode", required: false }] }], kjOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjOptions", required: false }] }], kjShowToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjShowToolbar", required: false }] }], kjShowStatusBar: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjShowStatusBar", required: false }] }] } });
|
|
5773
|
+
/** Relative luminance (0 dark – 1 light) of an [r,g,b] triple. */
|
|
5774
|
+
function luminance([r, g, b]) {
|
|
5775
|
+
return (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
|
|
5776
|
+
}
|
|
5777
|
+
/** [r,g,b] → `#rrggbb`. */
|
|
5778
|
+
function hex([r, g, b]) {
|
|
5779
|
+
const h = (n) => Math.max(0, Math.min(255, Math.round(n)))
|
|
5780
|
+
.toString(16)
|
|
5781
|
+
.padStart(2, '0');
|
|
5782
|
+
return `#${h(r)}${h(g)}${h(b)}`;
|
|
5783
|
+
}
|
|
4068
5784
|
|
|
4069
5785
|
const KJ_EMPTY_STATE_SIZE_PRESET = {
|
|
4070
5786
|
values: ['sm', 'md', 'lg'],
|
|
@@ -5163,11 +6879,20 @@ function encodeSvgDataUrl(svg) {
|
|
|
5163
6879
|
.replace(/>/g, '%3E');
|
|
5164
6880
|
return `url("data:image/svg+xml;utf8,${encoded}")`;
|
|
5165
6881
|
}
|
|
5166
|
-
/**
|
|
6882
|
+
/**
|
|
6883
|
+
* Convert PascalCase ("AArrowDown") → kebab-case ("a-arrow-down").
|
|
6884
|
+
*
|
|
6885
|
+
* Lucide separates a trailing number from its word with a hyphen and keeps the
|
|
6886
|
+
* digits grouped ("Heading1" → "heading-1", "Clock10" → "clock-10"), so a
|
|
6887
|
+
* letter→digit boundary also gets a hyphen. Without this, digit-bearing icons
|
|
6888
|
+
* (headings, clock-1…12, columns-2, …) resolve to a key that never matches the
|
|
6889
|
+
* requested name and render blank.
|
|
6890
|
+
*/
|
|
5167
6891
|
function pascalToKebab(name) {
|
|
5168
6892
|
return name
|
|
5169
6893
|
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
5170
6894
|
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2')
|
|
6895
|
+
.replace(/([a-zA-Z])([0-9])/g, '$1-$2')
|
|
5171
6896
|
.toLowerCase();
|
|
5172
6897
|
}
|
|
5173
6898
|
/** Lazily build the kebab-name → encoded-data-url map once per app. */
|
|
@@ -5205,7 +6930,7 @@ function buildLucideRegistry() {
|
|
|
5205
6930
|
* ```
|
|
5206
6931
|
*
|
|
5207
6932
|
* @doc-example Gallery
|
|
5208
|
-
* @doc-file ../icon.gallery.example.ts
|
|
6933
|
+
* @doc-file ../_examples/icon.gallery.example.ts
|
|
5209
6934
|
*
|
|
5210
6935
|
* @doc-css-var
|
|
5211
6936
|
* --kj-icon — Resolved icon value (url("...") or "glyph"). Set by the directive — read by the rendered .kj-icon.
|
|
@@ -10715,6 +12440,800 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
10715
12440
|
}]
|
|
10716
12441
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], dot: [{ type: i0.ViewChild, args: ['dot', { isSignal: true }] }] } });
|
|
10717
12442
|
|
|
12443
|
+
/**
|
|
12444
|
+
* Build an inline-format toggle feature. These need no package loading — inline
|
|
12445
|
+
* formatting uses the core `FORMAT_TEXT_COMMAND` — so the whole feature is a
|
|
12446
|
+
* toolbar toggle plus an optional keyboard shortcut.
|
|
12447
|
+
*/
|
|
12448
|
+
function inlineFormat(format, icon, label, order, shortcut, ariaKeyshortcuts) {
|
|
12449
|
+
return {
|
|
12450
|
+
name: format,
|
|
12451
|
+
setup: shortcut
|
|
12452
|
+
? (ctx) => ctx.registerShortcut(shortcut, () => ctx.toggleInlineFormat(format))
|
|
12453
|
+
: undefined,
|
|
12454
|
+
toolbar: [
|
|
12455
|
+
{
|
|
12456
|
+
id: format,
|
|
12457
|
+
group: 'format',
|
|
12458
|
+
order,
|
|
12459
|
+
icon,
|
|
12460
|
+
label,
|
|
12461
|
+
ariaKeyshortcuts,
|
|
12462
|
+
kind: 'toggle',
|
|
12463
|
+
isActive: (state) => state.activeFormats.has(format),
|
|
12464
|
+
run: (ctx) => ctx.toggleInlineFormat(format),
|
|
12465
|
+
},
|
|
12466
|
+
],
|
|
12467
|
+
};
|
|
12468
|
+
}
|
|
12469
|
+
/** Bold (Ctrl/Cmd+B). */
|
|
12470
|
+
function bold() {
|
|
12471
|
+
return inlineFormat('bold', 'bold', 'Bold', 10, 'mod+b', 'Control+B');
|
|
12472
|
+
}
|
|
12473
|
+
/** Italic (Ctrl/Cmd+I). */
|
|
12474
|
+
function italic() {
|
|
12475
|
+
return inlineFormat('italic', 'italic', 'Italic', 20, 'mod+i', 'Control+I');
|
|
12476
|
+
}
|
|
12477
|
+
/** Underline (Ctrl/Cmd+U). */
|
|
12478
|
+
function underline() {
|
|
12479
|
+
return inlineFormat('underline', 'underline', 'Underline', 30, 'mod+u', 'Control+U');
|
|
12480
|
+
}
|
|
12481
|
+
/** Strikethrough. */
|
|
12482
|
+
function strike() {
|
|
12483
|
+
return inlineFormat('strikethrough', 'strikethrough', 'Strikethrough', 40);
|
|
12484
|
+
}
|
|
12485
|
+
/** Inline code. */
|
|
12486
|
+
function inlineCode() {
|
|
12487
|
+
return inlineFormat('code', 'code', 'Inline code', 50);
|
|
12488
|
+
}
|
|
12489
|
+
|
|
12490
|
+
/**
|
|
12491
|
+
* Heading feature. Lazily loads `@lexical/rich-text` for the heading node +
|
|
12492
|
+
* creator, and contributes one toolbar toggle per configured level.
|
|
12493
|
+
*/
|
|
12494
|
+
function heading(options) {
|
|
12495
|
+
const levels = options?.levels ?? [1, 2, 3];
|
|
12496
|
+
let mod;
|
|
12497
|
+
return {
|
|
12498
|
+
name: 'heading',
|
|
12499
|
+
async load() {
|
|
12500
|
+
mod = await import('@lexical/rich-text');
|
|
12501
|
+
},
|
|
12502
|
+
nodes: () => [mod.HeadingNode],
|
|
12503
|
+
toolbar: levels.map((level, index) => {
|
|
12504
|
+
const tag = `h${level}`;
|
|
12505
|
+
return {
|
|
12506
|
+
id: `heading-${level}`,
|
|
12507
|
+
group: 'block',
|
|
12508
|
+
order: index,
|
|
12509
|
+
icon: `heading-${level}`,
|
|
12510
|
+
label: `Heading ${level}`,
|
|
12511
|
+
kind: 'toggle',
|
|
12512
|
+
isActive: (state) => state.blockType === tag,
|
|
12513
|
+
run: (ctx) => {
|
|
12514
|
+
if (ctx.state.blockType === tag)
|
|
12515
|
+
ctx.setParagraph();
|
|
12516
|
+
else
|
|
12517
|
+
ctx.setBlock(() => mod.$createHeadingNode(tag));
|
|
12518
|
+
},
|
|
12519
|
+
};
|
|
12520
|
+
}),
|
|
12521
|
+
};
|
|
12522
|
+
}
|
|
12523
|
+
|
|
12524
|
+
// `registerList` sets up transforms + commands editor-wide; run it once even if
|
|
12525
|
+
// both bullet and ordered list features are enabled.
|
|
12526
|
+
const listRegistered = new WeakSet();
|
|
12527
|
+
function ensureList(editor, mod) {
|
|
12528
|
+
if (listRegistered.has(editor))
|
|
12529
|
+
return () => { };
|
|
12530
|
+
listRegistered.add(editor);
|
|
12531
|
+
const unregister = mod.registerList(editor);
|
|
12532
|
+
return () => {
|
|
12533
|
+
listRegistered.delete(editor);
|
|
12534
|
+
unregister();
|
|
12535
|
+
};
|
|
12536
|
+
}
|
|
12537
|
+
/** Bullet (unordered) list. Lazily loads `@lexical/list`. */
|
|
12538
|
+
function bulletList() {
|
|
12539
|
+
let mod;
|
|
12540
|
+
return {
|
|
12541
|
+
name: 'bullet-list',
|
|
12542
|
+
async load() {
|
|
12543
|
+
mod = await import('@lexical/list');
|
|
12544
|
+
},
|
|
12545
|
+
nodes: () => [mod.ListNode, mod.ListItemNode],
|
|
12546
|
+
setup: (ctx) => ensureList(ctx.editor, mod),
|
|
12547
|
+
toolbar: [
|
|
12548
|
+
{
|
|
12549
|
+
id: 'bullet-list',
|
|
12550
|
+
group: 'list',
|
|
12551
|
+
order: 0,
|
|
12552
|
+
icon: 'list',
|
|
12553
|
+
label: 'Bullet list',
|
|
12554
|
+
kind: 'toggle',
|
|
12555
|
+
isActive: (state) => state.blockType === 'bullet',
|
|
12556
|
+
run: (ctx) => ctx.state.blockType === 'bullet'
|
|
12557
|
+
? ctx.dispatch(mod.REMOVE_LIST_COMMAND, undefined)
|
|
12558
|
+
: ctx.dispatch(mod.INSERT_UNORDERED_LIST_COMMAND, undefined),
|
|
12559
|
+
},
|
|
12560
|
+
],
|
|
12561
|
+
};
|
|
12562
|
+
}
|
|
12563
|
+
/** Ordered (numbered) list. Lazily loads `@lexical/list`. */
|
|
12564
|
+
function orderedList() {
|
|
12565
|
+
let mod;
|
|
12566
|
+
return {
|
|
12567
|
+
name: 'ordered-list',
|
|
12568
|
+
async load() {
|
|
12569
|
+
mod = await import('@lexical/list');
|
|
12570
|
+
},
|
|
12571
|
+
nodes: () => [mod.ListNode, mod.ListItemNode],
|
|
12572
|
+
setup: (ctx) => ensureList(ctx.editor, mod),
|
|
12573
|
+
toolbar: [
|
|
12574
|
+
{
|
|
12575
|
+
id: 'ordered-list',
|
|
12576
|
+
group: 'list',
|
|
12577
|
+
order: 1,
|
|
12578
|
+
icon: 'list-ordered',
|
|
12579
|
+
label: 'Numbered list',
|
|
12580
|
+
kind: 'toggle',
|
|
12581
|
+
isActive: (state) => state.blockType === 'number',
|
|
12582
|
+
run: (ctx) => ctx.state.blockType === 'number'
|
|
12583
|
+
? ctx.dispatch(mod.REMOVE_LIST_COMMAND, undefined)
|
|
12584
|
+
: ctx.dispatch(mod.INSERT_ORDERED_LIST_COMMAND, undefined),
|
|
12585
|
+
},
|
|
12586
|
+
],
|
|
12587
|
+
};
|
|
12588
|
+
}
|
|
12589
|
+
|
|
12590
|
+
/** Blockquote feature. Lazily loads `@lexical/rich-text` for the quote node. */
|
|
12591
|
+
function quote() {
|
|
12592
|
+
let mod;
|
|
12593
|
+
return {
|
|
12594
|
+
name: 'quote',
|
|
12595
|
+
async load() {
|
|
12596
|
+
mod = await import('@lexical/rich-text');
|
|
12597
|
+
},
|
|
12598
|
+
nodes: () => [mod.QuoteNode],
|
|
12599
|
+
toolbar: [
|
|
12600
|
+
{
|
|
12601
|
+
id: 'quote',
|
|
12602
|
+
group: 'block',
|
|
12603
|
+
order: 10,
|
|
12604
|
+
icon: 'quote',
|
|
12605
|
+
label: 'Quote',
|
|
12606
|
+
kind: 'toggle',
|
|
12607
|
+
isActive: (state) => state.blockType === 'quote',
|
|
12608
|
+
run: (ctx) => ctx.state.blockType === 'quote'
|
|
12609
|
+
? ctx.setParagraph()
|
|
12610
|
+
: ctx.setBlock(() => mod.$createQuoteNode()),
|
|
12611
|
+
},
|
|
12612
|
+
],
|
|
12613
|
+
};
|
|
12614
|
+
}
|
|
12615
|
+
|
|
12616
|
+
/** Code block feature. Lazily loads `@lexical/code` (and its Prism grammars). */
|
|
12617
|
+
function codeBlock() {
|
|
12618
|
+
let mod;
|
|
12619
|
+
return {
|
|
12620
|
+
name: 'code-block',
|
|
12621
|
+
async load() {
|
|
12622
|
+
mod = await import('@lexical/code');
|
|
12623
|
+
},
|
|
12624
|
+
nodes: () => [mod.CodeNode, mod.CodeHighlightNode],
|
|
12625
|
+
toolbar: [
|
|
12626
|
+
{
|
|
12627
|
+
id: 'code-block',
|
|
12628
|
+
group: 'block',
|
|
12629
|
+
order: 20,
|
|
12630
|
+
icon: 'square-code',
|
|
12631
|
+
label: 'Code block',
|
|
12632
|
+
kind: 'toggle',
|
|
12633
|
+
isActive: (state) => state.blockType === 'code',
|
|
12634
|
+
run: (ctx) => ctx.state.blockType === 'code'
|
|
12635
|
+
? ctx.setParagraph()
|
|
12636
|
+
: ctx.setBlock(() => mod.$createCodeNode()),
|
|
12637
|
+
},
|
|
12638
|
+
],
|
|
12639
|
+
};
|
|
12640
|
+
}
|
|
12641
|
+
|
|
12642
|
+
/**
|
|
12643
|
+
* Link editor overlay contributed by the `link` feature. Rendered by the RTE
|
|
12644
|
+
* component inside a `role="dialog"` popover; it edits/removes the link at the
|
|
12645
|
+
* caret. Not part of the public API — surfaced via the feature's `overlay`.
|
|
12646
|
+
*/
|
|
12647
|
+
class LinkEditor {
|
|
12648
|
+
data = injectRteOverlayData();
|
|
12649
|
+
url = signal(this.data.url ?? '', /* @ts-ignore */
|
|
12650
|
+
...(ngDevMode ? [{ debugName: "url" }] : /* istanbul ignore next */ []));
|
|
12651
|
+
input = viewChild('input', /* @ts-ignore */
|
|
12652
|
+
...(ngDevMode ? [{ debugName: "input" }] : /* istanbul ignore next */ []));
|
|
12653
|
+
constructor() {
|
|
12654
|
+
afterNextRender(() => this.input()?.nativeElement.focus());
|
|
12655
|
+
}
|
|
12656
|
+
onApply(event) {
|
|
12657
|
+
event.preventDefault();
|
|
12658
|
+
this.data.apply(this.url().trim());
|
|
12659
|
+
}
|
|
12660
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: LinkEditor, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
12661
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: LinkEditor, isStandalone: true, selector: "kj-rte-link-editor", viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
12662
|
+
<form class="kj-rte__overlay-form" (submit)="onApply($event)">
|
|
12663
|
+
<label class="kj-rte__overlay-label" for="kj-rte-link-url">URL</label>
|
|
12664
|
+
<input
|
|
12665
|
+
#input
|
|
12666
|
+
id="kj-rte-link-url"
|
|
12667
|
+
class="kj-rte__overlay-input"
|
|
12668
|
+
type="url"
|
|
12669
|
+
placeholder="https://example.com"
|
|
12670
|
+
[value]="url()"
|
|
12671
|
+
(input)="url.set($any($event.target).value)"
|
|
12672
|
+
(keydown.escape)="data.close()"
|
|
12673
|
+
/>
|
|
12674
|
+
<div class="kj-rte__overlay-actions">
|
|
12675
|
+
<button type="submit" class="kj-rte__overlay-btn">Apply</button>
|
|
12676
|
+
@if (url()) {
|
|
12677
|
+
<button type="button" class="kj-rte__overlay-btn" (click)="data.remove()">Remove</button>
|
|
12678
|
+
}
|
|
12679
|
+
<button type="button" class="kj-rte__overlay-btn" (click)="data.close()">Cancel</button>
|
|
12680
|
+
</div>
|
|
12681
|
+
</form>
|
|
12682
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
12683
|
+
}
|
|
12684
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: LinkEditor, decorators: [{
|
|
12685
|
+
type: Component,
|
|
12686
|
+
args: [{
|
|
12687
|
+
selector: 'kj-rte-link-editor',
|
|
12688
|
+
standalone: true,
|
|
12689
|
+
template: `
|
|
12690
|
+
<form class="kj-rte__overlay-form" (submit)="onApply($event)">
|
|
12691
|
+
<label class="kj-rte__overlay-label" for="kj-rte-link-url">URL</label>
|
|
12692
|
+
<input
|
|
12693
|
+
#input
|
|
12694
|
+
id="kj-rte-link-url"
|
|
12695
|
+
class="kj-rte__overlay-input"
|
|
12696
|
+
type="url"
|
|
12697
|
+
placeholder="https://example.com"
|
|
12698
|
+
[value]="url()"
|
|
12699
|
+
(input)="url.set($any($event.target).value)"
|
|
12700
|
+
(keydown.escape)="data.close()"
|
|
12701
|
+
/>
|
|
12702
|
+
<div class="kj-rte__overlay-actions">
|
|
12703
|
+
<button type="submit" class="kj-rte__overlay-btn">Apply</button>
|
|
12704
|
+
@if (url()) {
|
|
12705
|
+
<button type="button" class="kj-rte__overlay-btn" (click)="data.remove()">Remove</button>
|
|
12706
|
+
}
|
|
12707
|
+
<button type="button" class="kj-rte__overlay-btn" (click)="data.close()">Cancel</button>
|
|
12708
|
+
</div>
|
|
12709
|
+
</form>
|
|
12710
|
+
`,
|
|
12711
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
12712
|
+
}]
|
|
12713
|
+
}], ctorParameters: () => [], propDecorators: { input: [{ type: i0.ViewChild, args: ['input', { isSignal: true }] }] } });
|
|
12714
|
+
|
|
12715
|
+
/**
|
|
12716
|
+
* Link feature. Lazily loads core `lexical` (for selection reads) and
|
|
12717
|
+
* `@lexical/link`. Contributes the link node, a Ctrl/Cmd+K shortcut, a toolbar
|
|
12718
|
+
* toggle, and the link-editor overlay.
|
|
12719
|
+
*/
|
|
12720
|
+
function link() {
|
|
12721
|
+
let lex;
|
|
12722
|
+
let mod;
|
|
12723
|
+
function selectedUrl(ctx) {
|
|
12724
|
+
return ctx.read(() => {
|
|
12725
|
+
const selection = lex.$getSelection();
|
|
12726
|
+
if (!lex.$isRangeSelection(selection))
|
|
12727
|
+
return '';
|
|
12728
|
+
for (const node of selection.getNodes()) {
|
|
12729
|
+
const link = mod.$isLinkNode(node)
|
|
12730
|
+
? node
|
|
12731
|
+
: mod.$isLinkNode(node.getParent())
|
|
12732
|
+
? node.getParent()
|
|
12733
|
+
: null;
|
|
12734
|
+
if (link && mod.$isLinkNode(link))
|
|
12735
|
+
return link.getURL();
|
|
12736
|
+
}
|
|
12737
|
+
return '';
|
|
12738
|
+
});
|
|
12739
|
+
}
|
|
12740
|
+
function open(ctx) {
|
|
12741
|
+
ctx.openOverlay('link', {
|
|
12742
|
+
url: selectedUrl(ctx),
|
|
12743
|
+
apply: (url) => {
|
|
12744
|
+
ctx.update(() => mod.$toggleLink(url ? url : null));
|
|
12745
|
+
ctx.closeOverlay();
|
|
12746
|
+
ctx.focus();
|
|
12747
|
+
ctx.announce(url ? 'Link added' : 'Link removed');
|
|
12748
|
+
},
|
|
12749
|
+
remove: () => {
|
|
12750
|
+
ctx.update(() => mod.$toggleLink(null));
|
|
12751
|
+
ctx.closeOverlay();
|
|
12752
|
+
ctx.focus();
|
|
12753
|
+
ctx.announce('Link removed');
|
|
12754
|
+
},
|
|
12755
|
+
close: () => {
|
|
12756
|
+
ctx.closeOverlay();
|
|
12757
|
+
ctx.focus();
|
|
12758
|
+
},
|
|
12759
|
+
});
|
|
12760
|
+
}
|
|
12761
|
+
return {
|
|
12762
|
+
name: 'link',
|
|
12763
|
+
async load() {
|
|
12764
|
+
[lex, mod] = await Promise.all([import('lexical'), import('@lexical/link')]);
|
|
12765
|
+
},
|
|
12766
|
+
nodes: () => [mod.LinkNode],
|
|
12767
|
+
setup: (ctx) => ctx.registerShortcut('mod+k', () => open(ctx)),
|
|
12768
|
+
toolbar: [
|
|
12769
|
+
{
|
|
12770
|
+
id: 'link',
|
|
12771
|
+
group: 'insert',
|
|
12772
|
+
order: 0,
|
|
12773
|
+
icon: 'link',
|
|
12774
|
+
label: 'Link',
|
|
12775
|
+
ariaKeyshortcuts: 'Control+K',
|
|
12776
|
+
kind: 'toggle',
|
|
12777
|
+
isActive: (state) => state.isLink,
|
|
12778
|
+
run: (ctx) => open(ctx),
|
|
12779
|
+
},
|
|
12780
|
+
],
|
|
12781
|
+
overlay: [{ id: 'link', label: 'Edit link', component: LinkEditor }],
|
|
12782
|
+
};
|
|
12783
|
+
}
|
|
12784
|
+
|
|
12785
|
+
/**
|
|
12786
|
+
* Image editor overlay contributed by the `image` feature. Collects a URL + alt
|
|
12787
|
+
* text (always require alt for WCAG 1.1.1) and inserts an image node.
|
|
12788
|
+
*/
|
|
12789
|
+
class ImageEditor {
|
|
12790
|
+
data = injectRteOverlayData();
|
|
12791
|
+
src = signal('', /* @ts-ignore */
|
|
12792
|
+
...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
|
|
12793
|
+
alt = signal('', /* @ts-ignore */
|
|
12794
|
+
...(ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []));
|
|
12795
|
+
input = viewChild('input', /* @ts-ignore */
|
|
12796
|
+
...(ngDevMode ? [{ debugName: "input" }] : /* istanbul ignore next */ []));
|
|
12797
|
+
constructor() {
|
|
12798
|
+
afterNextRender(() => this.input()?.nativeElement.focus());
|
|
12799
|
+
}
|
|
12800
|
+
onInsert(event) {
|
|
12801
|
+
event.preventDefault();
|
|
12802
|
+
const src = this.src().trim();
|
|
12803
|
+
if (src)
|
|
12804
|
+
this.data.insert(src, this.alt().trim());
|
|
12805
|
+
}
|
|
12806
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ImageEditor, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
12807
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.5", type: ImageEditor, isStandalone: true, selector: "kj-rte-image-editor", viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
12808
|
+
<form class="kj-rte__overlay-form" (submit)="onInsert($event)">
|
|
12809
|
+
<label class="kj-rte__overlay-label" for="kj-rte-image-src">Image URL</label>
|
|
12810
|
+
<input
|
|
12811
|
+
#input
|
|
12812
|
+
id="kj-rte-image-src"
|
|
12813
|
+
class="kj-rte__overlay-input"
|
|
12814
|
+
type="url"
|
|
12815
|
+
placeholder="https://example.com/photo.jpg"
|
|
12816
|
+
[value]="src()"
|
|
12817
|
+
(input)="src.set($any($event.target).value)"
|
|
12818
|
+
(keydown.escape)="data.close()"
|
|
12819
|
+
/>
|
|
12820
|
+
<label class="kj-rte__overlay-label" for="kj-rte-image-alt">Alt text</label>
|
|
12821
|
+
<input
|
|
12822
|
+
id="kj-rte-image-alt"
|
|
12823
|
+
class="kj-rte__overlay-input"
|
|
12824
|
+
type="text"
|
|
12825
|
+
placeholder="Describe the image"
|
|
12826
|
+
[value]="alt()"
|
|
12827
|
+
(input)="alt.set($any($event.target).value)"
|
|
12828
|
+
(keydown.escape)="data.close()"
|
|
12829
|
+
/>
|
|
12830
|
+
<div class="kj-rte__overlay-actions">
|
|
12831
|
+
<button type="submit" class="kj-rte__overlay-btn" [disabled]="!src().trim()">Insert</button>
|
|
12832
|
+
<button type="button" class="kj-rte__overlay-btn" (click)="data.close()">Cancel</button>
|
|
12833
|
+
</div>
|
|
12834
|
+
</form>
|
|
12835
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
12836
|
+
}
|
|
12837
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: ImageEditor, decorators: [{
|
|
12838
|
+
type: Component,
|
|
12839
|
+
args: [{
|
|
12840
|
+
selector: 'kj-rte-image-editor',
|
|
12841
|
+
standalone: true,
|
|
12842
|
+
template: `
|
|
12843
|
+
<form class="kj-rte__overlay-form" (submit)="onInsert($event)">
|
|
12844
|
+
<label class="kj-rte__overlay-label" for="kj-rte-image-src">Image URL</label>
|
|
12845
|
+
<input
|
|
12846
|
+
#input
|
|
12847
|
+
id="kj-rte-image-src"
|
|
12848
|
+
class="kj-rte__overlay-input"
|
|
12849
|
+
type="url"
|
|
12850
|
+
placeholder="https://example.com/photo.jpg"
|
|
12851
|
+
[value]="src()"
|
|
12852
|
+
(input)="src.set($any($event.target).value)"
|
|
12853
|
+
(keydown.escape)="data.close()"
|
|
12854
|
+
/>
|
|
12855
|
+
<label class="kj-rte__overlay-label" for="kj-rte-image-alt">Alt text</label>
|
|
12856
|
+
<input
|
|
12857
|
+
id="kj-rte-image-alt"
|
|
12858
|
+
class="kj-rte__overlay-input"
|
|
12859
|
+
type="text"
|
|
12860
|
+
placeholder="Describe the image"
|
|
12861
|
+
[value]="alt()"
|
|
12862
|
+
(input)="alt.set($any($event.target).value)"
|
|
12863
|
+
(keydown.escape)="data.close()"
|
|
12864
|
+
/>
|
|
12865
|
+
<div class="kj-rte__overlay-actions">
|
|
12866
|
+
<button type="submit" class="kj-rte__overlay-btn" [disabled]="!src().trim()">Insert</button>
|
|
12867
|
+
<button type="button" class="kj-rte__overlay-btn" (click)="data.close()">Cancel</button>
|
|
12868
|
+
</div>
|
|
12869
|
+
</form>
|
|
12870
|
+
`,
|
|
12871
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
12872
|
+
}]
|
|
12873
|
+
}], ctorParameters: () => [], propDecorators: { input: [{ type: i0.ViewChild, args: ['input', { isSignal: true }] }] } });
|
|
12874
|
+
|
|
12875
|
+
/**
|
|
12876
|
+
* Image feature. Lazily loads core `lexical` and builds a self-rendering image
|
|
12877
|
+
* node via `createKjImageNode`. Contributes a toolbar button + the image-editor
|
|
12878
|
+
* overlay (which collects URL + alt text).
|
|
12879
|
+
*/
|
|
12880
|
+
function image() {
|
|
12881
|
+
let api;
|
|
12882
|
+
return {
|
|
12883
|
+
name: 'image',
|
|
12884
|
+
async load() {
|
|
12885
|
+
const lex = await import('lexical');
|
|
12886
|
+
api = createKjImageNode(lex);
|
|
12887
|
+
},
|
|
12888
|
+
nodes: () => [api.Node],
|
|
12889
|
+
toolbar: [
|
|
12890
|
+
{
|
|
12891
|
+
id: 'image',
|
|
12892
|
+
group: 'insert',
|
|
12893
|
+
order: 10,
|
|
12894
|
+
icon: 'image',
|
|
12895
|
+
label: 'Image',
|
|
12896
|
+
kind: 'button',
|
|
12897
|
+
run: (ctx) => ctx.openOverlay('image', {
|
|
12898
|
+
insert: (src, alt) => {
|
|
12899
|
+
ctx.insertNodes(() => [api.$create({ src, alt })]);
|
|
12900
|
+
ctx.closeOverlay();
|
|
12901
|
+
ctx.focus();
|
|
12902
|
+
ctx.announce('Image inserted');
|
|
12903
|
+
},
|
|
12904
|
+
close: () => {
|
|
12905
|
+
ctx.closeOverlay();
|
|
12906
|
+
ctx.focus();
|
|
12907
|
+
},
|
|
12908
|
+
}),
|
|
12909
|
+
},
|
|
12910
|
+
],
|
|
12911
|
+
overlay: [{ id: 'image', label: 'Insert image', component: ImageEditor }],
|
|
12912
|
+
};
|
|
12913
|
+
}
|
|
12914
|
+
|
|
12915
|
+
/**
|
|
12916
|
+
* Markdown shortcuts (`# `, `- `, `1. `, `> `, `` ``` ``, `**bold**`, …). Lazily
|
|
12917
|
+
* loads `@lexical/markdown`. No toolbar UI — it's a typing behaviour.
|
|
12918
|
+
*/
|
|
12919
|
+
function markdownShortcuts() {
|
|
12920
|
+
let mod;
|
|
12921
|
+
return {
|
|
12922
|
+
name: 'markdown-shortcuts',
|
|
12923
|
+
async load() {
|
|
12924
|
+
mod = await import('@lexical/markdown');
|
|
12925
|
+
},
|
|
12926
|
+
setup: (ctx) => mod.registerMarkdownShortcuts(ctx.editor, mod.TRANSFORMERS),
|
|
12927
|
+
};
|
|
12928
|
+
}
|
|
12929
|
+
|
|
12930
|
+
/**
|
|
12931
|
+
* Undo/redo history. Lazily loads `@lexical/history` and contributes undo/redo
|
|
12932
|
+
* toolbar buttons (disabled until the respective action is available).
|
|
12933
|
+
*/
|
|
12934
|
+
function history() {
|
|
12935
|
+
let mod;
|
|
12936
|
+
return {
|
|
12937
|
+
name: 'history',
|
|
12938
|
+
async load() {
|
|
12939
|
+
mod = await import('@lexical/history');
|
|
12940
|
+
},
|
|
12941
|
+
setup: (ctx) => mod.registerHistory(ctx.editor, mod.createEmptyHistoryState(), 300),
|
|
12942
|
+
toolbar: [
|
|
12943
|
+
{
|
|
12944
|
+
id: 'undo',
|
|
12945
|
+
group: 'history',
|
|
12946
|
+
order: 0,
|
|
12947
|
+
icon: 'undo',
|
|
12948
|
+
label: 'Undo',
|
|
12949
|
+
ariaKeyshortcuts: 'Control+Z',
|
|
12950
|
+
kind: 'button',
|
|
12951
|
+
isDisabled: (state) => !state.canUndo,
|
|
12952
|
+
run: (ctx) => ctx.undo(),
|
|
12953
|
+
},
|
|
12954
|
+
{
|
|
12955
|
+
id: 'redo',
|
|
12956
|
+
group: 'history',
|
|
12957
|
+
order: 1,
|
|
12958
|
+
icon: 'redo',
|
|
12959
|
+
label: 'Redo',
|
|
12960
|
+
ariaKeyshortcuts: 'Control+Shift+Z',
|
|
12961
|
+
kind: 'button',
|
|
12962
|
+
isDisabled: (state) => !state.canRedo,
|
|
12963
|
+
run: (ctx) => ctx.redo(),
|
|
12964
|
+
},
|
|
12965
|
+
],
|
|
12966
|
+
};
|
|
12967
|
+
}
|
|
12968
|
+
|
|
12969
|
+
/**
|
|
12970
|
+
* The full default feature bundle, so a zero-config `<kj-rich-text-editor>`
|
|
12971
|
+
* still gives a complete editor. Compose your own subset with the individual
|
|
12972
|
+
* factories to load only the packages you need.
|
|
12973
|
+
*/
|
|
12974
|
+
function defaultFeatures() {
|
|
12975
|
+
return [
|
|
12976
|
+
bold(),
|
|
12977
|
+
italic(),
|
|
12978
|
+
underline(),
|
|
12979
|
+
strike(),
|
|
12980
|
+
inlineCode(),
|
|
12981
|
+
heading(),
|
|
12982
|
+
bulletList(),
|
|
12983
|
+
orderedList(),
|
|
12984
|
+
quote(),
|
|
12985
|
+
codeBlock(),
|
|
12986
|
+
link(),
|
|
12987
|
+
image(),
|
|
12988
|
+
markdownShortcuts(),
|
|
12989
|
+
history(),
|
|
12990
|
+
];
|
|
12991
|
+
}
|
|
12992
|
+
|
|
12993
|
+
let kjRteUid = 0;
|
|
12994
|
+
/**
|
|
12995
|
+
* Styled, accessible rich-text editor composing the headless
|
|
12996
|
+
* {@link KjRichTextEditor} core directive with a **dynamic** `role="toolbar"`
|
|
12997
|
+
* that renders whatever the active features contribute (sorted by group then
|
|
12998
|
+
* order) — no hardcoded buttons. Feature overlays (link/image editors) render in
|
|
12999
|
+
* an accessible `role="dialog"` popover.
|
|
13000
|
+
*
|
|
13001
|
+
* Zero-config gives the full editor via {@link defaultFeatures}; pass a subset to
|
|
13002
|
+
* `kjFeatures` (or `provideKjRichText(...)`) to load only the packages you need.
|
|
13003
|
+
*
|
|
13004
|
+
* @example
|
|
13005
|
+
* ```html
|
|
13006
|
+
* <kj-rich-text-editor kjLabel="Message" [(kjValue)]="html" />
|
|
13007
|
+
* <kj-rich-text-editor [kjFeatures]="[bold(), italic(), link()]" />
|
|
13008
|
+
* ```
|
|
13009
|
+
* @doc-category Library/Forms
|
|
13010
|
+
* @doc
|
|
13011
|
+
* @doc-name rich-text-editor
|
|
13012
|
+
* @doc-is-main
|
|
13013
|
+
* @doc-description Accessible, feature-composed rich-text editor wrapping Lexical with a dynamic toolbar.
|
|
13014
|
+
* @doc-example Default [full]
|
|
13015
|
+
* The full editor: the toolbar renders every default feature's contribution.
|
|
13016
|
+
* @doc-file rich-text-editor.example.ts
|
|
13017
|
+
* @doc-example Minimal (subset of features) [full]
|
|
13018
|
+
* Only bold, italic and link — the toolbar and loaded packages shrink to match.
|
|
13019
|
+
* @doc-file rich-text-editor.minimal.example.ts
|
|
13020
|
+
* @doc-example Custom feature [full]
|
|
13021
|
+
* A feature contributing its own toolbar button + node in a few lines.
|
|
13022
|
+
* @doc-file rich-text-editor.custom-node.example.ts
|
|
13023
|
+
* @doc-example Readonly [full]
|
|
13024
|
+
* Renders existing content without editing affordances.
|
|
13025
|
+
* @doc-file rich-text-editor.readonly.example.ts
|
|
13026
|
+
* @doc-aria role="textbox" — the editable surface, with aria-multiline="true".
|
|
13027
|
+
* @doc-aria role="toolbar" — the formatting controls, arrow-key navigable.
|
|
13028
|
+
* @doc-a11y Toggle items expose aria-pressed; feature actions announce via an aria-live region.
|
|
13029
|
+
* @doc-css-var --kj-rte-bg — Editor background.
|
|
13030
|
+
* @doc-css-var --kj-rte-border-color — Border colour.
|
|
13031
|
+
* @doc-css-var --kj-rte-radius — Corner radius.
|
|
13032
|
+
* @doc-css-var --kj-rte-min-height — Minimum height of the editable area.
|
|
13033
|
+
* @doc-related input,form,field
|
|
13034
|
+
*/
|
|
13035
|
+
class KjRichTextEditorComponent {
|
|
13036
|
+
env = inject(EnvironmentInjector);
|
|
13037
|
+
/** Active features. Defaults to the full {@link defaultFeatures} bundle. */
|
|
13038
|
+
kjFeatures = input(defaultFeatures(), /* @ts-ignore */
|
|
13039
|
+
...(ngDevMode ? [{ debugName: "kjFeatures" }] : /* istanbul ignore next */ []));
|
|
13040
|
+
/** Initial HTML content. */
|
|
13041
|
+
kjValue = input('', /* @ts-ignore */
|
|
13042
|
+
...(ngDevMode ? [{ debugName: "kjValue" }] : /* istanbul ignore next */ []));
|
|
13043
|
+
/** Accessible label for the editable region (ignored when `kjLabelledBy` is set). */
|
|
13044
|
+
kjLabel = input('Rich text editor', /* @ts-ignore */
|
|
13045
|
+
...(ngDevMode ? [{ debugName: "kjLabel" }] : /* istanbul ignore next */ []));
|
|
13046
|
+
/** ID of an external element that labels the editable region. */
|
|
13047
|
+
kjLabelledBy = input('', /* @ts-ignore */
|
|
13048
|
+
...(ngDevMode ? [{ debugName: "kjLabelledBy" }] : /* istanbul ignore next */ []));
|
|
13049
|
+
/** Placeholder shown while the editor is empty. */
|
|
13050
|
+
kjPlaceholder = input('', /* @ts-ignore */
|
|
13051
|
+
...(ngDevMode ? [{ debugName: "kjPlaceholder" }] : /* istanbul ignore next */ []));
|
|
13052
|
+
/** Render read-only (non-editable) content. */
|
|
13053
|
+
kjReadonly = input(false, /* @ts-ignore */
|
|
13054
|
+
...(ngDevMode ? [{ debugName: "kjReadonly" }] : /* istanbul ignore next */ []));
|
|
13055
|
+
/** Accessible label for the toolbar. */
|
|
13056
|
+
kjToolbarLabel = input('Formatting', /* @ts-ignore */
|
|
13057
|
+
...(ngDevMode ? [{ debugName: "kjToolbarLabel" }] : /* istanbul ignore next */ []));
|
|
13058
|
+
/** Whether the formatting toolbar is shown. */
|
|
13059
|
+
kjShowToolbar = input(true, /* @ts-ignore */
|
|
13060
|
+
...(ngDevMode ? [{ debugName: "kjShowToolbar" }] : /* istanbul ignore next */ []));
|
|
13061
|
+
/** Emits the serialized HTML whenever the content changes. */
|
|
13062
|
+
valueChange = output();
|
|
13063
|
+
/** Emits the plain text whenever the content changes. */
|
|
13064
|
+
textChange = output();
|
|
13065
|
+
/** Emits the Lexical serialized state whenever the content changes. */
|
|
13066
|
+
jsonChange = output();
|
|
13067
|
+
/** @internal Stable id used for aria-controls / labelledby wiring. */
|
|
13068
|
+
contentId = `kj-rte-${kjRteUid++}`;
|
|
13069
|
+
live = viewChild(KjLiveRegion, /* @ts-ignore */
|
|
13070
|
+
...(ngDevMode ? [{ debugName: "live" }] : /* istanbul ignore next */ []));
|
|
13071
|
+
overlayInjectors = new WeakMap();
|
|
13072
|
+
/** Run a toolbar item and announce toggle state changes to AT. */
|
|
13073
|
+
onRun(ed, item) {
|
|
13074
|
+
ed.runItem(item);
|
|
13075
|
+
if (item.kind === 'toggle') {
|
|
13076
|
+
this.announce(`${item.label} ${ed.itemActive(item) ? 'on' : 'off'}`);
|
|
13077
|
+
}
|
|
13078
|
+
}
|
|
13079
|
+
/** Announce a message via the live region (also handles feature announcements). */
|
|
13080
|
+
announce(message) {
|
|
13081
|
+
this.live()?.announce(message);
|
|
13082
|
+
}
|
|
13083
|
+
/** Injector that exposes the overlay's data via KJ_RTE_OVERLAY_DATA. */
|
|
13084
|
+
overlayInjector(active) {
|
|
13085
|
+
const key = (active.data ?? active);
|
|
13086
|
+
let injector = this.overlayInjectors.get(key);
|
|
13087
|
+
if (!injector) {
|
|
13088
|
+
injector = Injector.create({
|
|
13089
|
+
parent: this.env,
|
|
13090
|
+
providers: [{ provide: KJ_RTE_OVERLAY_DATA, useValue: active.data }],
|
|
13091
|
+
});
|
|
13092
|
+
this.overlayInjectors.set(key, injector);
|
|
13093
|
+
}
|
|
13094
|
+
return injector;
|
|
13095
|
+
}
|
|
13096
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjRichTextEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13097
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: KjRichTextEditorComponent, isStandalone: true, selector: "kj-rich-text-editor", inputs: { kjFeatures: { classPropertyName: "kjFeatures", publicName: "kjFeatures", isSignal: true, isRequired: false, transformFunction: null }, kjValue: { classPropertyName: "kjValue", publicName: "kjValue", isSignal: true, isRequired: false, transformFunction: null }, kjLabel: { classPropertyName: "kjLabel", publicName: "kjLabel", isSignal: true, isRequired: false, transformFunction: null }, kjLabelledBy: { classPropertyName: "kjLabelledBy", publicName: "kjLabelledBy", isSignal: true, isRequired: false, transformFunction: null }, kjPlaceholder: { classPropertyName: "kjPlaceholder", publicName: "kjPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, kjReadonly: { classPropertyName: "kjReadonly", publicName: "kjReadonly", isSignal: true, isRequired: false, transformFunction: null }, kjToolbarLabel: { classPropertyName: "kjToolbarLabel", publicName: "kjToolbarLabel", isSignal: true, isRequired: false, transformFunction: null }, kjShowToolbar: { classPropertyName: "kjShowToolbar", publicName: "kjShowToolbar", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", textChange: "textChange", jsonChange: "jsonChange" }, host: { classAttribute: "kj-rte" }, viewQueries: [{ propertyName: "live", first: true, predicate: KjLiveRegion, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
13098
|
+
@if (kjShowToolbar()) {
|
|
13099
|
+
<div
|
|
13100
|
+
class="kj-rte__toolbar"
|
|
13101
|
+
role="toolbar"
|
|
13102
|
+
[attr.aria-label]="kjToolbarLabel()"
|
|
13103
|
+
[attr.aria-controls]="contentId"
|
|
13104
|
+
kjRovingTabindex
|
|
13105
|
+
kjRovingOrientation="horizontal"
|
|
13106
|
+
>
|
|
13107
|
+
@for (grp of ed.toolbarGroups(); track grp.group; let firstGroup = $first) {
|
|
13108
|
+
@if (!firstGroup) {
|
|
13109
|
+
<span class="kj-rte__sep" role="separator" aria-orientation="vertical"></span>
|
|
13110
|
+
}
|
|
13111
|
+
<div class="kj-rte__group" role="group" [attr.aria-label]="grp.group">
|
|
13112
|
+
@for (item of grp.items; track item.id) {
|
|
13113
|
+
<button
|
|
13114
|
+
type="button"
|
|
13115
|
+
class="kj-rte__btn"
|
|
13116
|
+
kjRovingTabindexItem
|
|
13117
|
+
[attr.aria-label]="item.label"
|
|
13118
|
+
[title]="item.label"
|
|
13119
|
+
[attr.aria-keyshortcuts]="item.ariaKeyshortcuts || null"
|
|
13120
|
+
[class.kj-rte__btn--active]="ed.itemActive(item)"
|
|
13121
|
+
[attr.aria-pressed]="item.kind === 'toggle' ? ed.itemActive(item) : null"
|
|
13122
|
+
[disabled]="ed.itemDisabled(item)"
|
|
13123
|
+
(mousedown)="$event.preventDefault()"
|
|
13124
|
+
(click)="onRun(ed, item)"
|
|
13125
|
+
>
|
|
13126
|
+
<i [kjIcon]="item.icon" aria-hidden="true"></i>
|
|
13127
|
+
</button>
|
|
13128
|
+
}
|
|
13129
|
+
</div>
|
|
13130
|
+
}
|
|
13131
|
+
</div>
|
|
13132
|
+
|
|
13133
|
+
@if (ed.activeOverlay(); as ov) {
|
|
13134
|
+
<div class="kj-rte__overlay" role="dialog" [attr.aria-label]="ov.overlay.label">
|
|
13135
|
+
<ng-container
|
|
13136
|
+
*ngComponentOutlet="ov.overlay.component; injector: overlayInjector(ov)"
|
|
13137
|
+
/>
|
|
13138
|
+
</div>
|
|
13139
|
+
}
|
|
13140
|
+
}
|
|
13141
|
+
|
|
13142
|
+
<div
|
|
13143
|
+
#ed="kjRichTextEditor"
|
|
13144
|
+
[id]="contentId"
|
|
13145
|
+
class="kj-rte__content"
|
|
13146
|
+
kjRichTextEditor
|
|
13147
|
+
[kjFeatures]="kjFeatures()"
|
|
13148
|
+
[kjValue]="kjValue()"
|
|
13149
|
+
[kjReadonly]="kjReadonly()"
|
|
13150
|
+
[attr.aria-label]="kjLabelledBy() ? null : kjLabel()"
|
|
13151
|
+
[attr.aria-labelledby]="kjLabelledBy() || null"
|
|
13152
|
+
[attr.data-placeholder]="kjPlaceholder() || null"
|
|
13153
|
+
(valueChange)="valueChange.emit($event)"
|
|
13154
|
+
(textChange)="textChange.emit($event)"
|
|
13155
|
+
(jsonChange)="jsonChange.emit($event)"
|
|
13156
|
+
(announce)="announce($event)"
|
|
13157
|
+
></div>
|
|
13158
|
+
|
|
13159
|
+
<div class="kj-rte__sr" kjLiveRegion aria-live="polite"></div>
|
|
13160
|
+
`, isInline: true, styles: ["@layer kj.component{.kj-rte{--kj-rte-bg: var(--kj-bg-field);--kj-rte-fg: var(--kj-fg-default);--kj-rte-muted-fg: var(--kj-fg-muted);--kj-rte-border-color: var(--kj-border-default);--kj-rte-radius: var(--kj-radius-field);--kj-rte-toolbar-bg: var(--kj-bg-surface, var(--kj-bg-body));--kj-rte-btn-size: 2.75rem;--kj-rte-accent: var(--kj-bg-primary);--kj-rte-accent-fg: var(--kj-fg-on-primary);--kj-rte-min-height: 12rem;--kj-rte-pad: var(--kj-space-md);--kj-rte-font: var(--kj-font-sans);--kj-rte-mono: var(--kj-font-mono, ui-monospace, monospace);display:flex;flex-direction:column;width:100%;max-width:100%;min-width:0;box-sizing:border-box;background:var(--kj-rte-bg);color:var(--kj-rte-fg);border:var(--kj-border) solid var(--kj-rte-border-color);border-radius:var(--kj-rte-radius);font-family:var(--kj-rte-font);overflow:hidden}.kj-rte:focus-within{outline:2px solid var(--kj-rte-accent);outline-offset:1px;border-color:var(--kj-border-focus, var(--kj-rte-accent))}.kj-rte__toolbar{display:flex;flex-wrap:nowrap;align-items:center;gap:var(--kj-space-xs, .25rem);padding:var(--kj-space-sm);background:var(--kj-rte-toolbar-bg);border-bottom:var(--kj-border) solid var(--kj-rte-border-color);overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;scrollbar-color:var(--kj-rte-border-color) transparent}.kj-rte__toolbar::-webkit-scrollbar{height:.5rem}.kj-rte__toolbar::-webkit-scrollbar-thumb{background:var(--kj-rte-border-color);border-radius:.25rem}.kj-rte__toolbar::-webkit-scrollbar-track{background:transparent}.kj-rte__group{display:flex;align-items:center;gap:var(--kj-space-xs, .25rem)}.kj-rte__group,.kj-rte__sep,.kj-rte__btn{flex:0 0 auto}.kj-rte__sep{width:1px;align-self:stretch;min-height:1.5rem;margin:0 var(--kj-space-xs, .25rem);background:var(--kj-rte-border-color)}.kj-rte__btn{display:inline-flex;align-items:center;justify-content:center;min-width:var(--kj-rte-btn-size);min-height:var(--kj-rte-btn-size);padding:0 var(--kj-space-sm);color:var(--kj-rte-fg);background:transparent;border:var(--kj-border) solid transparent;border-radius:var(--kj-radius-field);cursor:pointer;transition:var(--kj-transition, background-color .15s ease, color .15s ease)}.kj-rte__btn:hover:not(:disabled){background:var(--kj-bg-subtle, var(--kj-bg-body))}.kj-rte__btn:focus-visible{outline:2px solid var(--kj-rte-accent);outline-offset:2px}.kj-rte__btn--active{background:color-mix(in srgb,var(--kj-rte-accent) 16%,transparent);border-color:color-mix(in srgb,var(--kj-rte-accent) 40%,transparent);color:var(--kj-rte-accent)}.kj-rte__btn:disabled{opacity:.45;cursor:not-allowed}.kj-rte__overlay{position:relative;z-index:1;padding:var(--kj-space-sm) var(--kj-rte-pad);background:var(--kj-rte-toolbar-bg);border-bottom:var(--kj-border) solid var(--kj-rte-border-color);box-shadow:0 6px 16px #0000001f}.kj-rte__overlay-form{display:flex;flex-wrap:wrap;align-items:center;gap:var(--kj-space-sm)}.kj-rte__overlay-label{font-size:var(--kj-text-sm);color:var(--kj-rte-muted-fg)}.kj-rte__overlay-input{flex:1 1 12rem;min-height:2.25rem;padding:var(--kj-space-sm) var(--kj-space-md);color:var(--kj-rte-fg);background:var(--kj-bg-field);border:var(--kj-border) solid var(--kj-rte-border-color);border-radius:var(--kj-radius-field);font:var(--kj-text-sm) / 1.4 var(--kj-rte-font)}.kj-rte__overlay-input:focus-visible{outline:2px solid var(--kj-rte-accent);outline-offset:1px}.kj-rte__overlay-actions{display:flex;gap:var(--kj-space-sm)}.kj-rte__overlay-btn{min-height:2.25rem;padding:0 var(--kj-space-md);color:var(--kj-rte-fg);background:transparent;border:var(--kj-border) solid var(--kj-rte-border-color);border-radius:var(--kj-radius-field);cursor:pointer}.kj-rte__overlay-btn:hover:not(:disabled){background:var(--kj-bg-subtle, var(--kj-bg-body))}.kj-rte__overlay-btn:focus-visible{outline:2px solid var(--kj-rte-accent);outline-offset:2px}.kj-rte__overlay-btn:disabled{opacity:.45;cursor:not-allowed}.kj-rte__content{flex:1 1 auto;min-width:0;min-height:var(--kj-rte-min-height);padding:var(--kj-rte-pad);outline:none;overflow-y:auto;overflow-wrap:anywhere;line-height:1.6;color:var(--kj-rte-fg)}.kj-rte__content[data-empty][data-placeholder]:before{content:attr(data-placeholder);color:var(--kj-rte-muted-fg);pointer-events:none}.kj-rte__sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.kj-rte .kj-rte-paragraph{margin:0 0 var(--kj-space-sm)}.kj-rte .kj-rte-h1{margin:0 0 var(--kj-space-sm);font-size:var(--kj-text-2xl, 1.75rem);font-weight:700;line-height:1.25}.kj-rte .kj-rte-h2{margin:0 0 var(--kj-space-sm);font-size:var(--kj-text-xl, 1.4rem);font-weight:700;line-height:1.3}.kj-rte .kj-rte-h3{margin:0 0 var(--kj-space-sm);font-size:var(--kj-text-lg, 1.2rem);font-weight:600;line-height:1.35}.kj-rte .kj-rte-ul,.kj-rte .kj-rte-ol{margin:0 0 var(--kj-space-sm);padding-left:1.5rem}.kj-rte .kj-rte-ul{list-style:disc}.kj-rte .kj-rte-ol{list-style:decimal}.kj-rte .kj-rte-li{margin-bottom:.25rem}.kj-rte .kj-rte-quote{margin:0 0 var(--kj-space-sm);padding-left:var(--kj-space-md);border-left:3px solid var(--kj-rte-border-color);color:var(--kj-rte-muted-fg);font-style:italic}.kj-rte .kj-rte-link{color:var(--kj-rte-accent);text-decoration:underline;text-underline-offset:2px}.kj-rte .kj-rte-bold{font-weight:700}.kj-rte .kj-rte-italic{font-style:italic}.kj-rte .kj-rte-underline{text-decoration:underline}.kj-rte .kj-rte-strikethrough{text-decoration:line-through}.kj-rte .kj-rte-code{padding:.1em .35em;background:var(--kj-bg-subtle, var(--kj-bg-body));border-radius:.25rem;font-family:var(--kj-rte-mono);font-size:.9em}.kj-rte .kj-rte-code-block{display:block;margin:0 0 var(--kj-space-sm);padding:var(--kj-space-md);background:var(--kj-bg-subtle, var(--kj-bg-body));border-radius:var(--kj-radius-field);font-family:var(--kj-rte-mono);font-size:.9em;white-space:pre-wrap;overflow-x:auto}.kj-rte .kj-rte-image{margin:var(--kj-space-sm) 0}.kj-rte .kj-rte-image img{max-width:100%;height:auto;border-radius:var(--kj-radius-field)}@media(prefers-reduced-motion:reduce){.kj-rte__btn,.kj-rte{transition:none}}}\n"], dependencies: [{ kind: "directive", type: KjRichTextEditor, selector: "[kjRichTextEditor]", inputs: ["kjValue", "kjFeatures", "kjExtensions", "kjPlugins", "kjReadonly", "kjSpellcheck", "kjNamespace"], outputs: ["valueChange", "textChange", "jsonChange", "announce"], exportAs: ["kjRichTextEditor"] }, { kind: "directive", type: KjRovingTabindex, selector: "[kjRovingTabindex]", inputs: ["kjRovingOrientation"] }, { kind: "directive", type: KjRovingTabindexItemDirective, selector: "[kjRovingTabindexItem]" }, { kind: "directive", type: KjLiveRegion, selector: "[kjLiveRegion]", inputs: ["kjPoliteness"], exportAs: ["kjLiveRegion"] }, { kind: "directive", type: KjIconDirective, selector: "span[kjIcon], i[kjIcon]", inputs: ["kjIcon", "kjIconLabel", "kjIconColor", "kjIconSize"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
13161
|
+
}
|
|
13162
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjRichTextEditorComponent, decorators: [{
|
|
13163
|
+
type: Component,
|
|
13164
|
+
args: [{ selector: 'kj-rich-text-editor', standalone: true, imports: [
|
|
13165
|
+
KjRichTextEditor,
|
|
13166
|
+
KjRovingTabindex,
|
|
13167
|
+
KjRovingTabindexItemDirective,
|
|
13168
|
+
KjLiveRegion,
|
|
13169
|
+
KjIconDirective,
|
|
13170
|
+
NgComponentOutlet,
|
|
13171
|
+
], host: { class: 'kj-rte' }, template: `
|
|
13172
|
+
@if (kjShowToolbar()) {
|
|
13173
|
+
<div
|
|
13174
|
+
class="kj-rte__toolbar"
|
|
13175
|
+
role="toolbar"
|
|
13176
|
+
[attr.aria-label]="kjToolbarLabel()"
|
|
13177
|
+
[attr.aria-controls]="contentId"
|
|
13178
|
+
kjRovingTabindex
|
|
13179
|
+
kjRovingOrientation="horizontal"
|
|
13180
|
+
>
|
|
13181
|
+
@for (grp of ed.toolbarGroups(); track grp.group; let firstGroup = $first) {
|
|
13182
|
+
@if (!firstGroup) {
|
|
13183
|
+
<span class="kj-rte__sep" role="separator" aria-orientation="vertical"></span>
|
|
13184
|
+
}
|
|
13185
|
+
<div class="kj-rte__group" role="group" [attr.aria-label]="grp.group">
|
|
13186
|
+
@for (item of grp.items; track item.id) {
|
|
13187
|
+
<button
|
|
13188
|
+
type="button"
|
|
13189
|
+
class="kj-rte__btn"
|
|
13190
|
+
kjRovingTabindexItem
|
|
13191
|
+
[attr.aria-label]="item.label"
|
|
13192
|
+
[title]="item.label"
|
|
13193
|
+
[attr.aria-keyshortcuts]="item.ariaKeyshortcuts || null"
|
|
13194
|
+
[class.kj-rte__btn--active]="ed.itemActive(item)"
|
|
13195
|
+
[attr.aria-pressed]="item.kind === 'toggle' ? ed.itemActive(item) : null"
|
|
13196
|
+
[disabled]="ed.itemDisabled(item)"
|
|
13197
|
+
(mousedown)="$event.preventDefault()"
|
|
13198
|
+
(click)="onRun(ed, item)"
|
|
13199
|
+
>
|
|
13200
|
+
<i [kjIcon]="item.icon" aria-hidden="true"></i>
|
|
13201
|
+
</button>
|
|
13202
|
+
}
|
|
13203
|
+
</div>
|
|
13204
|
+
}
|
|
13205
|
+
</div>
|
|
13206
|
+
|
|
13207
|
+
@if (ed.activeOverlay(); as ov) {
|
|
13208
|
+
<div class="kj-rte__overlay" role="dialog" [attr.aria-label]="ov.overlay.label">
|
|
13209
|
+
<ng-container
|
|
13210
|
+
*ngComponentOutlet="ov.overlay.component; injector: overlayInjector(ov)"
|
|
13211
|
+
/>
|
|
13212
|
+
</div>
|
|
13213
|
+
}
|
|
13214
|
+
}
|
|
13215
|
+
|
|
13216
|
+
<div
|
|
13217
|
+
#ed="kjRichTextEditor"
|
|
13218
|
+
[id]="contentId"
|
|
13219
|
+
class="kj-rte__content"
|
|
13220
|
+
kjRichTextEditor
|
|
13221
|
+
[kjFeatures]="kjFeatures()"
|
|
13222
|
+
[kjValue]="kjValue()"
|
|
13223
|
+
[kjReadonly]="kjReadonly()"
|
|
13224
|
+
[attr.aria-label]="kjLabelledBy() ? null : kjLabel()"
|
|
13225
|
+
[attr.aria-labelledby]="kjLabelledBy() || null"
|
|
13226
|
+
[attr.data-placeholder]="kjPlaceholder() || null"
|
|
13227
|
+
(valueChange)="valueChange.emit($event)"
|
|
13228
|
+
(textChange)="textChange.emit($event)"
|
|
13229
|
+
(jsonChange)="jsonChange.emit($event)"
|
|
13230
|
+
(announce)="announce($event)"
|
|
13231
|
+
></div>
|
|
13232
|
+
|
|
13233
|
+
<div class="kj-rte__sr" kjLiveRegion aria-live="polite"></div>
|
|
13234
|
+
`, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-rte{--kj-rte-bg: var(--kj-bg-field);--kj-rte-fg: var(--kj-fg-default);--kj-rte-muted-fg: var(--kj-fg-muted);--kj-rte-border-color: var(--kj-border-default);--kj-rte-radius: var(--kj-radius-field);--kj-rte-toolbar-bg: var(--kj-bg-surface, var(--kj-bg-body));--kj-rte-btn-size: 2.75rem;--kj-rte-accent: var(--kj-bg-primary);--kj-rte-accent-fg: var(--kj-fg-on-primary);--kj-rte-min-height: 12rem;--kj-rte-pad: var(--kj-space-md);--kj-rte-font: var(--kj-font-sans);--kj-rte-mono: var(--kj-font-mono, ui-monospace, monospace);display:flex;flex-direction:column;width:100%;max-width:100%;min-width:0;box-sizing:border-box;background:var(--kj-rte-bg);color:var(--kj-rte-fg);border:var(--kj-border) solid var(--kj-rte-border-color);border-radius:var(--kj-rte-radius);font-family:var(--kj-rte-font);overflow:hidden}.kj-rte:focus-within{outline:2px solid var(--kj-rte-accent);outline-offset:1px;border-color:var(--kj-border-focus, var(--kj-rte-accent))}.kj-rte__toolbar{display:flex;flex-wrap:nowrap;align-items:center;gap:var(--kj-space-xs, .25rem);padding:var(--kj-space-sm);background:var(--kj-rte-toolbar-bg);border-bottom:var(--kj-border) solid var(--kj-rte-border-color);overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;scrollbar-color:var(--kj-rte-border-color) transparent}.kj-rte__toolbar::-webkit-scrollbar{height:.5rem}.kj-rte__toolbar::-webkit-scrollbar-thumb{background:var(--kj-rte-border-color);border-radius:.25rem}.kj-rte__toolbar::-webkit-scrollbar-track{background:transparent}.kj-rte__group{display:flex;align-items:center;gap:var(--kj-space-xs, .25rem)}.kj-rte__group,.kj-rte__sep,.kj-rte__btn{flex:0 0 auto}.kj-rte__sep{width:1px;align-self:stretch;min-height:1.5rem;margin:0 var(--kj-space-xs, .25rem);background:var(--kj-rte-border-color)}.kj-rte__btn{display:inline-flex;align-items:center;justify-content:center;min-width:var(--kj-rte-btn-size);min-height:var(--kj-rte-btn-size);padding:0 var(--kj-space-sm);color:var(--kj-rte-fg);background:transparent;border:var(--kj-border) solid transparent;border-radius:var(--kj-radius-field);cursor:pointer;transition:var(--kj-transition, background-color .15s ease, color .15s ease)}.kj-rte__btn:hover:not(:disabled){background:var(--kj-bg-subtle, var(--kj-bg-body))}.kj-rte__btn:focus-visible{outline:2px solid var(--kj-rte-accent);outline-offset:2px}.kj-rte__btn--active{background:color-mix(in srgb,var(--kj-rte-accent) 16%,transparent);border-color:color-mix(in srgb,var(--kj-rte-accent) 40%,transparent);color:var(--kj-rte-accent)}.kj-rte__btn:disabled{opacity:.45;cursor:not-allowed}.kj-rte__overlay{position:relative;z-index:1;padding:var(--kj-space-sm) var(--kj-rte-pad);background:var(--kj-rte-toolbar-bg);border-bottom:var(--kj-border) solid var(--kj-rte-border-color);box-shadow:0 6px 16px #0000001f}.kj-rte__overlay-form{display:flex;flex-wrap:wrap;align-items:center;gap:var(--kj-space-sm)}.kj-rte__overlay-label{font-size:var(--kj-text-sm);color:var(--kj-rte-muted-fg)}.kj-rte__overlay-input{flex:1 1 12rem;min-height:2.25rem;padding:var(--kj-space-sm) var(--kj-space-md);color:var(--kj-rte-fg);background:var(--kj-bg-field);border:var(--kj-border) solid var(--kj-rte-border-color);border-radius:var(--kj-radius-field);font:var(--kj-text-sm) / 1.4 var(--kj-rte-font)}.kj-rte__overlay-input:focus-visible{outline:2px solid var(--kj-rte-accent);outline-offset:1px}.kj-rte__overlay-actions{display:flex;gap:var(--kj-space-sm)}.kj-rte__overlay-btn{min-height:2.25rem;padding:0 var(--kj-space-md);color:var(--kj-rte-fg);background:transparent;border:var(--kj-border) solid var(--kj-rte-border-color);border-radius:var(--kj-radius-field);cursor:pointer}.kj-rte__overlay-btn:hover:not(:disabled){background:var(--kj-bg-subtle, var(--kj-bg-body))}.kj-rte__overlay-btn:focus-visible{outline:2px solid var(--kj-rte-accent);outline-offset:2px}.kj-rte__overlay-btn:disabled{opacity:.45;cursor:not-allowed}.kj-rte__content{flex:1 1 auto;min-width:0;min-height:var(--kj-rte-min-height);padding:var(--kj-rte-pad);outline:none;overflow-y:auto;overflow-wrap:anywhere;line-height:1.6;color:var(--kj-rte-fg)}.kj-rte__content[data-empty][data-placeholder]:before{content:attr(data-placeholder);color:var(--kj-rte-muted-fg);pointer-events:none}.kj-rte__sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.kj-rte .kj-rte-paragraph{margin:0 0 var(--kj-space-sm)}.kj-rte .kj-rte-h1{margin:0 0 var(--kj-space-sm);font-size:var(--kj-text-2xl, 1.75rem);font-weight:700;line-height:1.25}.kj-rte .kj-rte-h2{margin:0 0 var(--kj-space-sm);font-size:var(--kj-text-xl, 1.4rem);font-weight:700;line-height:1.3}.kj-rte .kj-rte-h3{margin:0 0 var(--kj-space-sm);font-size:var(--kj-text-lg, 1.2rem);font-weight:600;line-height:1.35}.kj-rte .kj-rte-ul,.kj-rte .kj-rte-ol{margin:0 0 var(--kj-space-sm);padding-left:1.5rem}.kj-rte .kj-rte-ul{list-style:disc}.kj-rte .kj-rte-ol{list-style:decimal}.kj-rte .kj-rte-li{margin-bottom:.25rem}.kj-rte .kj-rte-quote{margin:0 0 var(--kj-space-sm);padding-left:var(--kj-space-md);border-left:3px solid var(--kj-rte-border-color);color:var(--kj-rte-muted-fg);font-style:italic}.kj-rte .kj-rte-link{color:var(--kj-rte-accent);text-decoration:underline;text-underline-offset:2px}.kj-rte .kj-rte-bold{font-weight:700}.kj-rte .kj-rte-italic{font-style:italic}.kj-rte .kj-rte-underline{text-decoration:underline}.kj-rte .kj-rte-strikethrough{text-decoration:line-through}.kj-rte .kj-rte-code{padding:.1em .35em;background:var(--kj-bg-subtle, var(--kj-bg-body));border-radius:.25rem;font-family:var(--kj-rte-mono);font-size:.9em}.kj-rte .kj-rte-code-block{display:block;margin:0 0 var(--kj-space-sm);padding:var(--kj-space-md);background:var(--kj-bg-subtle, var(--kj-bg-body));border-radius:var(--kj-radius-field);font-family:var(--kj-rte-mono);font-size:.9em;white-space:pre-wrap;overflow-x:auto}.kj-rte .kj-rte-image{margin:var(--kj-space-sm) 0}.kj-rte .kj-rte-image img{max-width:100%;height:auto;border-radius:var(--kj-radius-field)}@media(prefers-reduced-motion:reduce){.kj-rte__btn,.kj-rte{transition:none}}}\n"] }]
|
|
13235
|
+
}], propDecorators: { kjFeatures: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjFeatures", required: false }] }], kjValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjValue", required: false }] }], kjLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjLabel", required: false }] }], kjLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjLabelledBy", required: false }] }], kjPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjPlaceholder", required: false }] }], kjReadonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjReadonly", required: false }] }], kjToolbarLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjToolbarLabel", required: false }] }], kjShowToolbar: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjShowToolbar", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], textChange: [{ type: i0.Output, args: ["textChange"] }], jsonChange: [{ type: i0.Output, args: ["jsonChange"] }], live: [{ type: i0.ViewChild, args: [i0.forwardRef(() => KjLiveRegion), { isSignal: true }] }] } });
|
|
13236
|
+
|
|
10718
13237
|
/**
|
|
10719
13238
|
* Select root. Two-way bind via `[(value)]`.
|
|
10720
13239
|
*
|
|
@@ -10896,6 +13415,77 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
10896
13415
|
}]
|
|
10897
13416
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], kjLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjLabel", required: false }] }] } });
|
|
10898
13417
|
|
|
13418
|
+
/**
|
|
13419
|
+
* Service-launched **bottom sheet** — a mobile-first, bottom-anchored modal
|
|
13420
|
+
* surface with a grab handle and drag-to-dismiss. Inject `KjSheetService` and
|
|
13421
|
+
* call `open()` with a body component; the sheet slides up from the bottom
|
|
13422
|
+
* edge, traps focus, and locks background scroll. It reuses the same overlay
|
|
13423
|
+
* primitive stack as the drawer and dialog — bottom sheet is the mobile
|
|
13424
|
+
* composition of that engine, not a new one. The wrapper component exists to
|
|
13425
|
+
* host this documentation page.
|
|
13426
|
+
*
|
|
13427
|
+
* @doc
|
|
13428
|
+
* @doc-name sheet
|
|
13429
|
+
* @doc-is-main
|
|
13430
|
+
* @doc-example Default
|
|
13431
|
+
* A service-launched bottom sheet with a grab handle and drag-to-dismiss.
|
|
13432
|
+
* @doc-file sheet.example.ts
|
|
13433
|
+
* @doc-example Detents
|
|
13434
|
+
* `detent` sets the initial resting height — auto / half / full.
|
|
13435
|
+
* @doc-file sheet.detents.example.ts
|
|
13436
|
+
* @doc-example Scrollable
|
|
13437
|
+
* A tall body scrolls inside the sheet while the grab handle stays pinned.
|
|
13438
|
+
* @doc-file sheet.scrollable.example.ts
|
|
13439
|
+
*
|
|
13440
|
+
* @doc-keyboard
|
|
13441
|
+
* Escape — Closes the sheet (only the topmost overlay when stacked)
|
|
13442
|
+
* Enter / Space — Dismisses when the grab handle is focused
|
|
13443
|
+
* Tab — Cycles focus within the sheet (focus trap via `tabCycle({ returnFocus: true })`)
|
|
13444
|
+
* Shift+Tab — Cycles backward
|
|
13445
|
+
*
|
|
13446
|
+
* @doc-aria
|
|
13447
|
+
* role — "dialog"; `aria-modal="true"` while the backdrop is active
|
|
13448
|
+
* aria-label — Set via the `ariaLabel` option when no heading is projected
|
|
13449
|
+
* aria-labelledby — Wire to the id of your sheet heading for the accessible name
|
|
13450
|
+
* data-state — "open" / "closed" — drives the slide-up transform
|
|
13451
|
+
* data-kj-detent — Mirrors the resolved initial height for theming hooks
|
|
13452
|
+
*
|
|
13453
|
+
* @doc-css-var
|
|
13454
|
+
* --kj-sheet-bg — Panel background fill. Defaults to --kj-bg-elevated.
|
|
13455
|
+
* --kj-sheet-fg — Foreground text color. Defaults to --kj-fg-default.
|
|
13456
|
+
* --kj-sheet-shadow — Box shadow off the panel. Defaults to --kj-shadow-lg.
|
|
13457
|
+
* --kj-sheet-radius — Top corner radius. Defaults to --kj-radius-box.
|
|
13458
|
+
* --kj-sheet-max-height — Cap on the sheet height. Defaults to 92vh.
|
|
13459
|
+
* --kj-sheet-grip-color — Grab-handle pill color. Defaults to --kj-border-strong.
|
|
13460
|
+
*
|
|
13461
|
+
* @doc-touch
|
|
13462
|
+
* The grab handle is a ≥ 44px-tall touch target (WCAG 2.5.5) even though the
|
|
13463
|
+
* visible grip pill is small. Downward drag past 40% of the sheet height (or
|
|
13464
|
+
* 600 px/s) dismisses. Footer action buttons should use `kj-button`
|
|
13465
|
+
* `size="lg"` (≥ 44px).
|
|
13466
|
+
*
|
|
13467
|
+
* @doc-a11y
|
|
13468
|
+
* Focus is trapped inside the sheet while open and returned to the triggering
|
|
13469
|
+
* element on close (`returnFocus: true`). Siblings outside the sheet are
|
|
13470
|
+
* marked `inert` while it is open. Stacking is safe — only the topmost overlay
|
|
13471
|
+
* receives Escape and outside-click. The wrapper does not generate an
|
|
13472
|
+
* accessible name; provide one via `aria-labelledby` (a visible heading) or
|
|
13473
|
+
* the `ariaLabel` option. Slide transitions respect
|
|
13474
|
+
* `prefers-reduced-motion`, falling back to an opacity fade.
|
|
13475
|
+
*
|
|
13476
|
+
* @doc-related drawer,dialog,action-sheet
|
|
13477
|
+
*
|
|
13478
|
+
* @doc-category Library/Overlay
|
|
13479
|
+
*/
|
|
13480
|
+
class KjSheetComponent {
|
|
13481
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13482
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: KjSheetComponent, isStandalone: true, selector: "kj-sheet-shell", host: { styleAttribute: "display: contents;" }, ngImport: i0, template: `<ng-content />`, isInline: true, styles: ["@layer kj.component{.kj-sheet{--kj-sheet-bg: var(--kj-bg-elevated);--kj-sheet-fg: var(--kj-fg-default);--kj-sheet-shadow: var(--kj-shadow-lg);--kj-sheet-radius: var(--kj-radius-box);--kj-sheet-max-height: 92vh;--kj-sheet-grip-color: var(--kj-border-strong);position:fixed;left:0;right:0;bottom:0;display:flex;flex-direction:column;box-sizing:border-box;width:100%;max-height:var(--kj-sheet-max-height);margin-inline:auto;background:var(--kj-sheet-bg);color:var(--kj-sheet-fg);box-shadow:var(--kj-sheet-shadow);border-top-left-radius:var(--kj-sheet-radius);border-top-right-radius:var(--kj-sheet-radius);overflow:hidden;z-index:1000;transform:translate3d(0,var(--kj-sheet-drag-offset, 0),0);padding-bottom:env(safe-area-inset-bottom,0)}@media(min-width:40rem){.kj-sheet{max-width:32rem;border-bottom-left-radius:var(--kj-sheet-radius);border-bottom-right-radius:var(--kj-sheet-radius);bottom:var(--kj-space-lg)}}.kj-sheet[data-kj-detent=half]{height:50vh}.kj-sheet[data-kj-detent=full]{height:var(--kj-sheet-max-height)}.kj-sheet__handle{appearance:none;display:flex;align-items:center;justify-content:center;width:100%;min-height:44px;padding:0;border:0;background:transparent;cursor:grab;flex-shrink:0;touch-action:none}.kj-sheet[data-kj-dragging] .kj-sheet__handle{cursor:grabbing}.kj-sheet__grip{display:block;width:2.25rem;height:.3125rem;border-radius:999px;background:var(--kj-sheet-grip-color)}.kj-sheet__handle:focus-visible{outline:var(--kj-focus-ring-width, 2px) solid var(--kj-focus-ring-color, var(--kj-primary));outline-offset:-4px;border-radius:var(--kj-radius-sm)}.kj-sheet__content{flex:1;min-height:0;overflow-y:auto;padding:0 var(--kj-space-xl) var(--kj-space-xl);color:var(--kj-sheet-fg);font:.9375rem / 1.5 var(--kj-font-sans)}@media(prefers-reduced-motion:no-preference){.kj-sheet:not([data-kj-dragging]){transition:transform .26s cubic-bezier(.32,.72,0,1)}.kj-sheet[data-state=open]{transform:translate3d(0,var(--kj-sheet-drag-offset, 0),0)}.kj-sheet[data-state=closed]{transform:translate3d(0,100%,0)}}@media(prefers-reduced-motion:reduce){.kj-sheet:not([data-kj-dragging]){transition:opacity .12s linear}.kj-sheet[data-state=open]{opacity:1}.kj-sheet[data-state=closed]{opacity:0}}.kj-sheet__title{display:block;margin:0 0 var(--kj-space-xs);font:600 1.125rem / 1.3 var(--kj-font-sans);color:var(--kj-fg-default)}.kj-sheet__description{display:block;margin:0 0 var(--kj-space-md);color:var(--kj-fg-muted);font:.875rem / 1.4 var(--kj-font-sans)}.kj-sheet__footer{display:flex;gap:var(--kj-space-sm);padding-top:var(--kj-space-md)}.kj-sheet__footer[data-align=end]{justify-content:flex-end}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
13483
|
+
}
|
|
13484
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjSheetComponent, decorators: [{
|
|
13485
|
+
type: Component,
|
|
13486
|
+
args: [{ selector: 'kj-sheet-shell', standalone: true, template: `<ng-content />`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-sheet{--kj-sheet-bg: var(--kj-bg-elevated);--kj-sheet-fg: var(--kj-fg-default);--kj-sheet-shadow: var(--kj-shadow-lg);--kj-sheet-radius: var(--kj-radius-box);--kj-sheet-max-height: 92vh;--kj-sheet-grip-color: var(--kj-border-strong);position:fixed;left:0;right:0;bottom:0;display:flex;flex-direction:column;box-sizing:border-box;width:100%;max-height:var(--kj-sheet-max-height);margin-inline:auto;background:var(--kj-sheet-bg);color:var(--kj-sheet-fg);box-shadow:var(--kj-sheet-shadow);border-top-left-radius:var(--kj-sheet-radius);border-top-right-radius:var(--kj-sheet-radius);overflow:hidden;z-index:1000;transform:translate3d(0,var(--kj-sheet-drag-offset, 0),0);padding-bottom:env(safe-area-inset-bottom,0)}@media(min-width:40rem){.kj-sheet{max-width:32rem;border-bottom-left-radius:var(--kj-sheet-radius);border-bottom-right-radius:var(--kj-sheet-radius);bottom:var(--kj-space-lg)}}.kj-sheet[data-kj-detent=half]{height:50vh}.kj-sheet[data-kj-detent=full]{height:var(--kj-sheet-max-height)}.kj-sheet__handle{appearance:none;display:flex;align-items:center;justify-content:center;width:100%;min-height:44px;padding:0;border:0;background:transparent;cursor:grab;flex-shrink:0;touch-action:none}.kj-sheet[data-kj-dragging] .kj-sheet__handle{cursor:grabbing}.kj-sheet__grip{display:block;width:2.25rem;height:.3125rem;border-radius:999px;background:var(--kj-sheet-grip-color)}.kj-sheet__handle:focus-visible{outline:var(--kj-focus-ring-width, 2px) solid var(--kj-focus-ring-color, var(--kj-primary));outline-offset:-4px;border-radius:var(--kj-radius-sm)}.kj-sheet__content{flex:1;min-height:0;overflow-y:auto;padding:0 var(--kj-space-xl) var(--kj-space-xl);color:var(--kj-sheet-fg);font:.9375rem / 1.5 var(--kj-font-sans)}@media(prefers-reduced-motion:no-preference){.kj-sheet:not([data-kj-dragging]){transition:transform .26s cubic-bezier(.32,.72,0,1)}.kj-sheet[data-state=open]{transform:translate3d(0,var(--kj-sheet-drag-offset, 0),0)}.kj-sheet[data-state=closed]{transform:translate3d(0,100%,0)}}@media(prefers-reduced-motion:reduce){.kj-sheet:not([data-kj-dragging]){transition:opacity .12s linear}.kj-sheet[data-state=open]{opacity:1}.kj-sheet[data-state=closed]{opacity:0}}.kj-sheet__title{display:block;margin:0 0 var(--kj-space-xs);font:600 1.125rem / 1.3 var(--kj-font-sans);color:var(--kj-fg-default)}.kj-sheet__description{display:block;margin:0 0 var(--kj-space-md);color:var(--kj-fg-muted);font:.875rem / 1.4 var(--kj-font-sans)}.kj-sheet__footer{display:flex;gap:var(--kj-space-sm);padding-top:var(--kj-space-md)}.kj-sheet__footer[data-align=end]{justify-content:flex-end}}\n"] }]
|
|
13487
|
+
}] });
|
|
13488
|
+
|
|
10899
13489
|
/**
|
|
10900
13490
|
* Styled wrapper around the headless `KjSkeleton` directive.
|
|
10901
13491
|
*
|
|
@@ -11057,6 +13647,87 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
11057
13647
|
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-skeleton{--kj-skeleton-bg: var(--kj-bg-elevated, color-mix(in oklab, var(--kj-fg-default, #000) 12%, transparent));--kj-skeleton-highlight: var(--kj-bg-surface, color-mix(in oklab, var(--kj-fg-default, #000) 5%, transparent));--kj-skeleton-radius: var(--kj-radius-field, .375rem);--kj-skeleton-line-height: 1em;--kj-skeleton-line-radius: .25rem;--kj-skeleton-shimmer-duration: 1.4s;--kj-skeleton-pulse-duration: 1.6s;display:block;background-color:var(--kj-skeleton-bg);border-radius:var(--kj-skeleton-radius);inline-size:100%;block-size:1rem;overflow:hidden;position:relative}.kj-skeleton[data-shape=circle]{border-radius:50%;aspect-ratio:1 / 1}.kj-skeleton[data-shape=text],.kj-skeleton.kj-skeleton--line{block-size:var(--kj-skeleton-line-height);border-radius:var(--kj-skeleton-line-radius)}.kj-skeleton[data-shape=text-block]{display:flex;flex-direction:column;gap:var(--kj-space-sm, .5rem);background-color:transparent;border-radius:0;inline-size:100%;block-size:auto;overflow:visible}.kj-skeleton[data-animation=shimmer]:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 0%,var(--kj-skeleton-highlight) 50%,transparent 100%);transform:translate(-100%);animation:kj-skeleton-shimmer var(--kj-skeleton-shimmer-duration) linear infinite}.kj-skeleton[data-shape=text-block][data-animation=shimmer]:after{content:none}.kj-skeleton[data-animation=pulse]{animation:kj-skeleton-pulse var(--kj-skeleton-pulse-duration) ease-in-out infinite}.kj-skeleton[data-animation=none]:after{content:none}@keyframes kj-skeleton-shimmer{0%{transform:translate(-100%)}to{transform:translate(100%)}}@keyframes kj-skeleton-pulse{0%,to{opacity:1}50%{opacity:.55}}@media(prefers-reduced-motion:reduce){.kj-skeleton,.kj-skeleton:after{animation:none!important}}}\n"] }]
|
|
11058
13648
|
}], propDecorators: { kjSkeletonShape: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjSkeletonShape", required: false }] }], kjSkeletonAnimation: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjSkeletonAnimation", required: false }] }], kjWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjWidth", required: false }] }], kjHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjHeight", required: false }] }], kjLines: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjLines", required: false }] }] } });
|
|
11059
13649
|
|
|
13650
|
+
/**
|
|
13651
|
+
* Themed "skip to content" link — the styled wrapper around the headless
|
|
13652
|
+
* `KjSkipLink` directive. Implements [WCAG 2.4.1 Bypass
|
|
13653
|
+
* Blocks](https://www.w3.org/TR/WCAG21/#bypass-blocks): a keyboard user's first
|
|
13654
|
+
* Tab reveals it, and Enter jumps focus past the navbar / sidebar to the main
|
|
13655
|
+
* content landmark.
|
|
13656
|
+
*
|
|
13657
|
+
* Place it as the **first focusable element** of the app shell and give the main
|
|
13658
|
+
* landmark a matching `id` (default `main-content`):
|
|
13659
|
+
*
|
|
13660
|
+
* ```html
|
|
13661
|
+
* <kj-skip-link />
|
|
13662
|
+
* <kj-navbar />
|
|
13663
|
+
* <main id="main-content" tabindex="-1"><router-outlet /></main>
|
|
13664
|
+
* ```
|
|
13665
|
+
*
|
|
13666
|
+
* The visible label is projected content and defaults to "Skip to main content".
|
|
13667
|
+
* The link is visually hidden (parked above the viewport) until focused, then
|
|
13668
|
+
* slides into view with a solid high-contrast background so it is legible over
|
|
13669
|
+
* any page chrome.
|
|
13670
|
+
*
|
|
13671
|
+
* @example
|
|
13672
|
+
* ```html
|
|
13673
|
+
* <kj-skip-link />
|
|
13674
|
+
* <kj-skip-link kjTarget="page-body">Skip to article</kj-skip-link>
|
|
13675
|
+
* ```
|
|
13676
|
+
*
|
|
13677
|
+
* @doc-example Default
|
|
13678
|
+
* The shell-level skip link. Tab into the demo frame to reveal it, then
|
|
13679
|
+
* activate it to move focus to the demo's main region.
|
|
13680
|
+
* @doc-file skip-link.example.ts
|
|
13681
|
+
*
|
|
13682
|
+
* @doc-keyboard
|
|
13683
|
+
* Tab — Reveals the link when it receives focus (it is the first focusable element)
|
|
13684
|
+
* Enter — Activates it; keyboard focus moves to the target landmark
|
|
13685
|
+
*
|
|
13686
|
+
* @doc-aria
|
|
13687
|
+
* role=link — Native `<a>` semantics; accessible name from the projected label
|
|
13688
|
+
* href — Reflects `#<target>` so it works before hydration and is bookmarkable
|
|
13689
|
+
* tabindex=-1 — Applied to the target on activation so `focus()` lands and the
|
|
13690
|
+
* next Tab continues from the content, not the navigation
|
|
13691
|
+
*
|
|
13692
|
+
* @doc-a11y
|
|
13693
|
+
* Satisfies WCAG 2.4.1 Bypass Blocks. Hidden-until-focused (not
|
|
13694
|
+
* `display:none`, so it stays in the tab order), fully on-screen and
|
|
13695
|
+
* high-contrast when focused, and moves real keyboard focus — not just scroll.
|
|
13696
|
+
*
|
|
13697
|
+
* @doc-css-var
|
|
13698
|
+
* --kj-skip-link-bg — Background when focused. Defaults to the theme's primary surface.
|
|
13699
|
+
* --kj-skip-link-fg — Text color when focused. Pairs with the background for AAA contrast.
|
|
13700
|
+
* --kj-skip-link-radius — Corner radius of the focused pill.
|
|
13701
|
+
* --kj-skip-link-shadow — Elevation shadow when focused.
|
|
13702
|
+
* --kj-skip-link-offset — Inset from the top-left corner when focused.
|
|
13703
|
+
* --kj-skip-link-z — Stacking order. Must sit above the navbar and overlays.
|
|
13704
|
+
*
|
|
13705
|
+
* @doc-category Library/Navigation
|
|
13706
|
+
* @doc
|
|
13707
|
+
* @doc-name skip-link
|
|
13708
|
+
* @doc-description Themed, focus-moving "skip to main content" link for the app shell (WCAG 2.4.1).
|
|
13709
|
+
* @doc-is-main
|
|
13710
|
+
*/
|
|
13711
|
+
class KjSkipLinkComponent {
|
|
13712
|
+
/** `id` of the main-content landmark to move focus to. Defaults to `'main-content'`. */
|
|
13713
|
+
kjTarget = input('main-content', /* @ts-ignore */
|
|
13714
|
+
...(ngDevMode ? [{ debugName: "kjTarget" }] : /* istanbul ignore next */ []));
|
|
13715
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjSkipLinkComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
13716
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.5", type: KjSkipLinkComponent, isStandalone: true, selector: "kj-skip-link", inputs: { kjTarget: { classPropertyName: "kjTarget", publicName: "kjTarget", isSignal: true, isRequired: false, transformFunction: null } }, host: { styleAttribute: "display: contents;" }, ngImport: i0, template: `
|
|
13717
|
+
<a kjSkipLink class="kj-skip-link" [kjSkipLink]="kjTarget()">
|
|
13718
|
+
<ng-content>Skip to main content</ng-content>
|
|
13719
|
+
</a>
|
|
13720
|
+
`, isInline: true, styles: ["@layer kj.component{.kj-skip-link{--kj-skip-link-bg: var(--kj-bg-primary);--kj-skip-link-fg: var(--kj-fg-on-primary);--kj-skip-link-radius: var(--kj-radius-field, .25rem);--kj-skip-link-shadow: var(--kj-shadow-lg);--kj-skip-link-offset: var(--kj-space-sm, .5rem);--kj-skip-link-z: 1000;position:fixed;top:0;left:var(--kj-skip-link-offset);z-index:var(--kj-skip-link-z);transform:translateY(-150%);transition:transform var(--kj-transition, .15s ease);display:inline-block;padding:.625rem 1rem;min-height:44px;box-sizing:border-box;background:var(--kj-skip-link-bg);color:var(--kj-skip-link-fg);border-radius:var(--kj-skip-link-radius);box-shadow:var(--kj-skip-link-shadow);font:inherit;font-weight:600;line-height:1.4;text-decoration:none;white-space:nowrap}.kj-skip-link:focus,.kj-skip-link:focus-visible{transform:translateY(var(--kj-skip-link-offset));outline:3px solid var(--kj-fg-primary);outline-offset:2px}@media(prefers-reduced-motion:reduce){.kj-skip-link{transition:none}}}\n"], dependencies: [{ kind: "directive", type: KjSkipLink, selector: "a[kjSkipLink]", inputs: ["kjSkipLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
13721
|
+
}
|
|
13722
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjSkipLinkComponent, decorators: [{
|
|
13723
|
+
type: Component,
|
|
13724
|
+
args: [{ selector: 'kj-skip-link', standalone: true, imports: [KjSkipLink], template: `
|
|
13725
|
+
<a kjSkipLink class="kj-skip-link" [kjSkipLink]="kjTarget()">
|
|
13726
|
+
<ng-content>Skip to main content</ng-content>
|
|
13727
|
+
</a>
|
|
13728
|
+
`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-skip-link{--kj-skip-link-bg: var(--kj-bg-primary);--kj-skip-link-fg: var(--kj-fg-on-primary);--kj-skip-link-radius: var(--kj-radius-field, .25rem);--kj-skip-link-shadow: var(--kj-shadow-lg);--kj-skip-link-offset: var(--kj-space-sm, .5rem);--kj-skip-link-z: 1000;position:fixed;top:0;left:var(--kj-skip-link-offset);z-index:var(--kj-skip-link-z);transform:translateY(-150%);transition:transform var(--kj-transition, .15s ease);display:inline-block;padding:.625rem 1rem;min-height:44px;box-sizing:border-box;background:var(--kj-skip-link-bg);color:var(--kj-skip-link-fg);border-radius:var(--kj-skip-link-radius);box-shadow:var(--kj-skip-link-shadow);font:inherit;font-weight:600;line-height:1.4;text-decoration:none;white-space:nowrap}.kj-skip-link:focus,.kj-skip-link:focus-visible{transform:translateY(var(--kj-skip-link-offset));outline:3px solid var(--kj-fg-primary);outline-offset:2px}@media(prefers-reduced-motion:reduce){.kj-skip-link{transition:none}}}\n"] }]
|
|
13729
|
+
}], propDecorators: { kjTarget: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjTarget", required: false }] }] } });
|
|
13730
|
+
|
|
11060
13731
|
/**
|
|
11061
13732
|
* Styled wrapper around the headless `KjSlider` directive family.
|
|
11062
13733
|
*
|
|
@@ -11618,177 +14289,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
11618
14289
|
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-speed-dial{--kj-speed-dial-gap: var(--kj-space-md);--kj-speed-dial-edge: var(--kj-space-2xl);--kj-speed-dial-trigger-size: 3.5rem;--kj-speed-dial-action-size: 2.75rem;--kj-speed-dial-shadow: 0 6px 16px rgb(0 0 0 / .18);--kj-speed-dial-stagger: 30ms;--kj-speed-dial-duration: .18s;position:relative;display:inline-flex;flex-direction:column;align-items:center;gap:var(--kj-speed-dial-gap);z-index:100}.kj-speed-dial[data-direction=up]{flex-direction:column-reverse}.kj-speed-dial[data-direction=down]{flex-direction:column}.kj-speed-dial[data-direction=left]{flex-direction:row-reverse}.kj-speed-dial[data-direction=right]{flex-direction:row}.kj-speed-dial[data-position=bottom-right]{position:fixed;right:var(--kj-speed-dial-edge);bottom:var(--kj-speed-dial-edge)}.kj-speed-dial[data-position=bottom-left]{position:fixed;left:var(--kj-speed-dial-edge);bottom:var(--kj-speed-dial-edge)}.kj-speed-dial[data-position=top-right]{position:fixed;right:var(--kj-speed-dial-edge);top:var(--kj-speed-dial-edge)}.kj-speed-dial[data-position=top-left]{position:fixed;left:var(--kj-speed-dial-edge);top:var(--kj-speed-dial-edge)}.kj-speed-dial-trigger{--kj-button-radius: 9999px;--kj-button-padding-x: 0;--kj-button-padding-y: 0;--kj-button-shadow: var(--kj-speed-dial-shadow);width:var(--kj-speed-dial-trigger-size);height:var(--kj-speed-dial-trigger-size);min-width:var(--kj-speed-dial-trigger-size);flex:0 0 auto}.kj-speed-dial-trigger[data-state=open]>*{transform:rotate(45deg);transition:transform var(--kj-speed-dial-duration) ease}.kj-speed-dial-trigger>*{display:inline-flex;transition:transform var(--kj-speed-dial-duration) ease}.kj-speed-dial-actions{display:inline-flex;gap:var(--kj-speed-dial-gap);align-items:center;justify-content:center;pointer-events:none;opacity:0;transition:opacity var(--kj-speed-dial-duration) ease}.kj-speed-dial-actions[data-direction=up]{flex-direction:column-reverse}.kj-speed-dial-actions[data-direction=down]{flex-direction:column}.kj-speed-dial-actions[data-direction=left]{flex-direction:row-reverse}.kj-speed-dial-actions[data-direction=right]{flex-direction:row}.kj-speed-dial-actions[aria-hidden=true]{visibility:hidden;pointer-events:none}.kj-speed-dial-actions[data-expanded]{opacity:1;visibility:visible;pointer-events:auto}.kj-speed-dial-actions[data-direction=up]>*{transform:translateY(8px)}.kj-speed-dial-actions[data-direction=down]>*{transform:translateY(-8px)}.kj-speed-dial-actions[data-direction=left]>*{transform:translate(8px)}.kj-speed-dial-actions[data-direction=right]>*{transform:translate(-8px)}.kj-speed-dial-actions[data-expanded]>*{transform:translateZ(0);transition:transform var(--kj-speed-dial-duration) ease,opacity var(--kj-speed-dial-duration) ease;transition-delay:calc(var(--kj-speed-dial-stagger) * var(--kj-speed-dial-i, 0))}.kj-speed-dial-actions>*:nth-child(1){--kj-speed-dial-i: 0}.kj-speed-dial-actions>*:nth-child(2){--kj-speed-dial-i: 1}.kj-speed-dial-actions>*:nth-child(3){--kj-speed-dial-i: 2}.kj-speed-dial-actions>*:nth-child(4){--kj-speed-dial-i: 3}.kj-speed-dial-actions>*:nth-child(5){--kj-speed-dial-i: 4}.kj-speed-dial-actions>*:nth-child(6){--kj-speed-dial-i: 5}.kj-speed-dial-action{--kj-button-radius: 9999px;--kj-button-padding-x: 0;--kj-button-padding-y: 0;--kj-button-shadow: var(--kj-speed-dial-shadow);width:var(--kj-speed-dial-action-size);height:var(--kj-speed-dial-action-size);min-width:var(--kj-speed-dial-action-size);flex:0 0 auto}@media(prefers-reduced-motion:reduce){.kj-speed-dial-trigger>*,.kj-speed-dial-actions,.kj-speed-dial-actions>*{transition:none}.kj-speed-dial-actions>*{transform:none}}}\n"] }]
|
|
11619
14290
|
}], propDecorators: { kjVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjVariant", required: false }] }], kjSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjSize", required: false }] }], kjDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjDisabled", required: false }] }], kjCloseOnActivate: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjCloseOnActivate", required: false }] }], kjAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjAriaLabel", required: false }] }] } });
|
|
11620
14291
|
|
|
11621
|
-
/**
|
|
11622
|
-
* Styled wrapper around the headless `KjSpinner` directive.
|
|
11623
|
-
*
|
|
11624
|
-
* Composes `KjSpinner` via `hostDirectives` so the wrapper's host element is
|
|
11625
|
-
* *the* spinner — `role="status"`, `aria-live="polite"`, `aria-atomic="true"`,
|
|
11626
|
-
* the `aria-label` default ("Loading"), `data-animation`, and
|
|
11627
|
-
* `data-reduced-motion` all land on `<kj-spinner>` itself. `kjVariant` and
|
|
11628
|
-
* `kjSize` are wrapper-level inputs that the host mirrors to `data-variant` /
|
|
11629
|
-
* `data-size` (the directive's own nested `KjVariant` / `KjSize` host
|
|
11630
|
-
* directives are not transitively exposed through outer composition, so the
|
|
11631
|
-
* wrapper takes over the data-attribute reflection at this layer).
|
|
11632
|
-
*
|
|
11633
|
-
* The template renders an `aria-hidden` glyph element (the visual shape that
|
|
11634
|
-
* theme CSS keyframes drive per `data-animation`) and, when no
|
|
11635
|
-
* `aria-labelledby` was authored on the host, a `kjVisuallyHidden` label so
|
|
11636
|
-
* AT always finds an accessible name.
|
|
11637
|
-
*
|
|
11638
|
-
* **Indeterminate-only.** The spinner answers "something is happening" — it
|
|
11639
|
-
* has no value model. For "x of y" use Progress Bar; for missing-content
|
|
11640
|
-
* placeholders use Skeleton.
|
|
11641
|
-
*
|
|
11642
|
-
* @example
|
|
11643
|
-
* ```html
|
|
11644
|
-
* <kj-spinner />
|
|
11645
|
-
* <kj-spinner kjVariant="primary" kjSize="lg" kjAnimation="dots" kjAriaLabel="Sending" />
|
|
11646
|
-
* ```
|
|
11647
|
-
* @doc-example Default
|
|
11648
|
-
* The default playground — `spin` animation, `md` size, neutral variant,
|
|
11649
|
-
* default `aria-label="Loading"`.
|
|
11650
|
-
* @doc-file spinner.example.ts
|
|
11651
|
-
* @doc-example Usage
|
|
11652
|
-
* A walkthrough of the most common spinner usages — size, variant,
|
|
11653
|
-
* animation glyph, and inline placement next to copy.
|
|
11654
|
-
* @doc-file spinner.usage.example.ts
|
|
11655
|
-
* @doc-example Sizes
|
|
11656
|
-
* `xs` / `sm` / `md` / `lg` presets. There is intentionally no `xl` — that
|
|
11657
|
-
* size almost always wants a determinate Progress Bar instead.
|
|
11658
|
-
* @doc-file spinner.sizes.example.ts
|
|
11659
|
-
* @doc-example Variants
|
|
11660
|
-
* `neutral` (inherits `currentColor`), `primary`, `success`, `warning`,
|
|
11661
|
-
* `error`, `info`.
|
|
11662
|
-
* @doc-file spinner.variants.example.ts
|
|
11663
|
-
* @doc-example Animations
|
|
11664
|
-
* Animation shape preset — `spin`, `dots`, `bars`, etc. Themes own the
|
|
11665
|
-
* keyframes per value.
|
|
11666
|
-
* @doc-file spinner.animations.example.ts
|
|
11667
|
-
* @doc-example Inside a button
|
|
11668
|
-
* Embed the spinner inline next to a label to communicate in-flight work.
|
|
11669
|
-
* @doc-file spinner.in-button.example.ts
|
|
11670
|
-
*
|
|
11671
|
-
* @doc-keyboard
|
|
11672
|
-
* — — Non-interactive. The spinner is purely a status indicator.
|
|
11673
|
-
*
|
|
11674
|
-
* @doc-aria
|
|
11675
|
-
* role="status" — set on the host so AT announces it as a live status region
|
|
11676
|
-
* aria-live — "polite" so the label is read without interrupting the user
|
|
11677
|
-
* aria-atomic — "true" so the full label is announced on change
|
|
11678
|
-
* aria-label — Defaults to "Loading"; override per context (e.g. "Sending")
|
|
11679
|
-
* data-animation — Mirrors the resolved animation for theme hooks
|
|
11680
|
-
* data-variant — Mirrors the resolved variant for theme hooks
|
|
11681
|
-
* data-size — Mirrors the resolved size for theme hooks
|
|
11682
|
-
*
|
|
11683
|
-
* @doc-touch
|
|
11684
|
-
* — — Non-interactive; no touch target required.
|
|
11685
|
-
*
|
|
11686
|
-
* @doc-a11y
|
|
11687
|
-
* Indeterminate-only — answers "something is happening", with no value model.
|
|
11688
|
-
* Honours `prefers-reduced-motion` via `data-reduced-motion` on the host, so
|
|
11689
|
-
* themes can swap a calmer animation. When the consumer authors
|
|
11690
|
-
* `aria-labelledby` on the host the wrapper skips the visually-hidden label
|
|
11691
|
-
* to avoid double-naming.
|
|
11692
|
-
*
|
|
11693
|
-
* @doc-related progress-bar,skeleton,toast
|
|
11694
|
-
*
|
|
11695
|
-
* @doc-css-var
|
|
11696
|
-
* --kj-spinner-size — Glyph diameter. Sizes (xs/sm/md/lg) override.
|
|
11697
|
-
* --kj-spinner-color — Foreground color of the glyph. Variants set this; neutral inherits currentColor.
|
|
11698
|
-
* --kj-spinner-track — Track/background color for the spin arc.
|
|
11699
|
-
* --kj-spinner-duration — Base animation duration. Other animations scale off this.
|
|
11700
|
-
*
|
|
11701
|
-
* @doc-category Library/Feedback
|
|
11702
|
-
* @doc
|
|
11703
|
-
* @doc-name spinner
|
|
11704
|
-
* @doc-description Themed indeterminate loading spinner with variant, size, and animation glyph options.
|
|
11705
|
-
* @doc-is-main
|
|
11706
|
-
*/
|
|
11707
|
-
class KjSpinnerComponent {
|
|
11708
|
-
/**
|
|
11709
|
-
* Color preset reflected to `data-variant` on the host. Defaults to
|
|
11710
|
-
* `'neutral'`, which resolves to `currentColor` in shipped themes — so a
|
|
11711
|
-
* spinner inside a coloured surface inherits its parent's text colour.
|
|
11712
|
-
*/
|
|
11713
|
-
kjVariant = input('neutral', /* @ts-ignore */
|
|
11714
|
-
...(ngDevMode ? [{ debugName: "kjVariant" }] : /* istanbul ignore next */ []));
|
|
11715
|
-
/**
|
|
11716
|
-
* Size preset reflected to `data-size` on the host. Defaults to `'md'`.
|
|
11717
|
-
* Sizes ship as `xs | sm | md | lg`; an `xl` is intentionally absent — a
|
|
11718
|
-
* spinner that big almost always wants a determinate Progress Bar instead.
|
|
11719
|
-
*/
|
|
11720
|
-
kjSize = input('md', /* @ts-ignore */
|
|
11721
|
-
...(ngDevMode ? [{ debugName: "kjSize" }] : /* istanbul ignore next */ []));
|
|
11722
|
-
/**
|
|
11723
|
-
* Animation shape preset forwarded to `KjSpinner.kjAnimation` via the
|
|
11724
|
-
* composed host directive. Reflects on the host as `data-animation`.
|
|
11725
|
-
* Themes own the keyframes per value.
|
|
11726
|
-
*/
|
|
11727
|
-
kjAnimation = input('spin', /* @ts-ignore */
|
|
11728
|
-
...(ngDevMode ? [{ debugName: "kjAnimation" }] : /* istanbul ignore next */ []));
|
|
11729
|
-
/**
|
|
11730
|
-
* Accessible name forwarded to `KjSpinner.kjAriaLabel` via the composed
|
|
11731
|
-
* host directive. Default `'Loading'`. Used both as the host's
|
|
11732
|
-
* `aria-label` and as the visually-hidden text rendered inside the
|
|
11733
|
-
* wrapper when no consumer-authored `aria-labelledby` is on the element.
|
|
11734
|
-
*/
|
|
11735
|
-
kjAriaLabel = input('Loading', /* @ts-ignore */
|
|
11736
|
-
...(ngDevMode ? [{ debugName: "kjAriaLabel" }] : /* istanbul ignore next */ []));
|
|
11737
|
-
el = inject(ElementRef);
|
|
11738
|
-
/**
|
|
11739
|
-
* Snapshotted at construction: did the consumer author `aria-labelledby`
|
|
11740
|
-
* directly on `<kj-spinner>`? If so the accessible name is the referenced
|
|
11741
|
-
* element and we must not project a hidden duplicate. Read in the
|
|
11742
|
-
* constructor — by the time the template renders the directive may have
|
|
11743
|
-
* stamped its own attributes on the host.
|
|
11744
|
-
*/
|
|
11745
|
-
hasAuthoredLabelledBy;
|
|
11746
|
-
/**
|
|
11747
|
-
* `true` when the consumer did **not** author `aria-labelledby` on the
|
|
11748
|
-
* wrapper — i.e. the spinner's accessible name is its `aria-label`. The
|
|
11749
|
-
* wrapper renders a `kjVisuallyHidden` copy of the label as inner text so
|
|
11750
|
-
* AT that prefers content over `aria-label` (or that announces a
|
|
11751
|
-
* `role="status"` region's body on insertion) still has a name to read.
|
|
11752
|
-
* A consumer-authored `aria-labelledby` opts out of that hidden copy to
|
|
11753
|
-
* avoid double-naming the host.
|
|
11754
|
-
*/
|
|
11755
|
-
shouldRenderHiddenLabel = computed(() => !this.hasAuthoredLabelledBy, /* @ts-ignore */
|
|
11756
|
-
...(ngDevMode ? [{ debugName: "shouldRenderHiddenLabel" }] : /* istanbul ignore next */ []));
|
|
11757
|
-
constructor() {
|
|
11758
|
-
this.hasAuthoredLabelledBy =
|
|
11759
|
-
this.el.nativeElement.hasAttribute('aria-labelledby');
|
|
11760
|
-
}
|
|
11761
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjSpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
11762
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.5", type: KjSpinnerComponent, isStandalone: true, selector: "kj-spinner", inputs: { kjVariant: { classPropertyName: "kjVariant", publicName: "kjVariant", isSignal: true, isRequired: false, transformFunction: null }, kjSize: { classPropertyName: "kjSize", publicName: "kjSize", isSignal: true, isRequired: false, transformFunction: null }, kjAnimation: { classPropertyName: "kjAnimation", publicName: "kjAnimation", isSignal: true, isRequired: false, transformFunction: null }, kjAriaLabel: { classPropertyName: "kjAriaLabel", publicName: "kjAriaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-variant": "kjVariant()", "attr.data-size": "kjSize()" }, classAttribute: "kj-spinner" }, hostDirectives: [{ directive: i1.KjSpinner, inputs: ["kjAnimation", "kjAnimation", "kjAriaLabel", "kjAriaLabel"] }], ngImport: i0, template: `
|
|
11763
|
-
<span class="kj-spinner__glyph" aria-hidden="true"></span>
|
|
11764
|
-
@if (shouldRenderHiddenLabel()) {
|
|
11765
|
-
<span kjVisuallyHidden>{{ kjAriaLabel() }}</span>
|
|
11766
|
-
}
|
|
11767
|
-
`, isInline: true, styles: ["@layer kj.component{.kj-spinner{--kj-spinner-size: 1.25rem;--kj-spinner-color: currentColor;--kj-spinner-track: color-mix(in srgb, currentColor 20%, transparent);--kj-spinner-duration: .7s;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--kj-spinner-size);block-size:var(--kj-spinner-size);color:var(--kj-spinner-color);pointer-events:none}.kj-spinner[data-size=xs]{--kj-spinner-size: .75rem}.kj-spinner[data-size=sm]{--kj-spinner-size: 1rem}.kj-spinner[data-size=md]{--kj-spinner-size: 1.25rem}.kj-spinner[data-size=lg]{--kj-spinner-size: 1.75rem}.kj-spinner[data-variant=neutral]{--kj-spinner-color: currentColor}.kj-spinner[data-variant=primary]{--kj-spinner-color: var(--kj-fg-primary)}.kj-spinner[data-variant=secondary]{--kj-spinner-color: var(--kj-fg-default)}.kj-spinner[data-variant=success]{--kj-spinner-color: var(--kj-fg-success, #16a34a)}.kj-spinner[data-variant=warning]{--kj-spinner-color: var(--kj-fg-warning, #d97706)}.kj-spinner[data-variant=error]{--kj-spinner-color: var(--kj-fg-danger, #dc2626)}.kj-spinner[data-variant=info]{--kj-spinner-color: var(--kj-fg-info, #2563eb)}.kj-spinner__glyph{display:inline-block;inline-size:100%;block-size:100%}.kj-spinner[data-animation=spin] .kj-spinner__glyph{border:2px solid var(--kj-spinner-track);border-block-start-color:var(--kj-spinner-color);border-radius:50%;animation:kj-spinner-spin var(--kj-spinner-duration) linear infinite}.kj-spinner[data-animation=pulse] .kj-spinner__glyph{background:var(--kj-spinner-color);border-radius:50%;animation:kj-spinner-pulse calc(var(--kj-spinner-duration) * 2) ease-in-out infinite}.kj-spinner[data-animation=dots]{inline-size:auto}.kj-spinner[data-animation=dots] .kj-spinner__glyph{display:inline-flex;gap:calc(var(--kj-spinner-size) * .25);inline-size:auto;block-size:100%}.kj-spinner[data-animation=dots] .kj-spinner__glyph:before,.kj-spinner[data-animation=dots] .kj-spinner__glyph:after{content:\"\";inline-size:calc(var(--kj-spinner-size) * .3);block-size:calc(var(--kj-spinner-size) * .3);background:var(--kj-spinner-color);border-radius:50%;animation:kj-spinner-dots calc(var(--kj-spinner-duration) * 2) ease-in-out infinite}.kj-spinner[data-animation=dots] .kj-spinner__glyph{background:transparent}.kj-spinner[data-animation=dots] .kj-spinner__glyph:after{animation-delay:calc(var(--kj-spinner-duration) * .4)}.kj-spinner[data-animation=bars]{inline-size:auto}.kj-spinner[data-animation=bars] .kj-spinner__glyph{display:inline-flex;align-items:stretch;gap:calc(var(--kj-spinner-size) * .15);inline-size:auto;block-size:100%}.kj-spinner[data-animation=bars] .kj-spinner__glyph:before,.kj-spinner[data-animation=bars] .kj-spinner__glyph:after{content:\"\";inline-size:calc(var(--kj-spinner-size) * .2);background:var(--kj-spinner-color);border-radius:calc(var(--kj-spinner-size) * .05);animation:kj-spinner-bars calc(var(--kj-spinner-duration) * 1.6) ease-in-out infinite;transform-origin:center}.kj-spinner[data-animation=bars] .kj-spinner__glyph:after{animation-delay:calc(var(--kj-spinner-duration) * .4)}.kj-spinner[data-reduced-motion=true] .kj-spinner__glyph,.kj-spinner[data-reduced-motion=true] .kj-spinner__glyph:before,.kj-spinner[data-reduced-motion=true] .kj-spinner__glyph:after{animation:kj-spinner-reduced-motion 1.6s ease-in-out infinite!important}}@keyframes kj-spinner-spin{to{transform:rotate(360deg)}}@keyframes kj-spinner-pulse{0%,to{opacity:.35;transform:scale(.85)}50%{opacity:1;transform:scale(1)}}@keyframes kj-spinner-dots{0%,80%,to{transform:scale(.4);opacity:.4}40%{transform:scale(1);opacity:1}}@keyframes kj-spinner-bars{0%,40%,to{transform:scaleY(.4)}20%{transform:scaleY(1)}}@keyframes kj-spinner-reduced-motion{0%,to{opacity:.45}50%{opacity:1}}\n"], dependencies: [{ kind: "directive", type: KjVisuallyHidden, selector: "[kjVisuallyHidden]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
11768
|
-
}
|
|
11769
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjSpinnerComponent, decorators: [{
|
|
11770
|
-
type: Component,
|
|
11771
|
-
args: [{ selector: 'kj-spinner', standalone: true, imports: [KjVisuallyHidden], hostDirectives: [
|
|
11772
|
-
{
|
|
11773
|
-
directive: KjSpinner,
|
|
11774
|
-
// KjSpinner's own surface — kjVariant + kjSize live on its nested
|
|
11775
|
-
// KjVariant / KjSize and are not surfaced through this outer
|
|
11776
|
-
// composition; they are re-exposed as wrapper inputs below and wired
|
|
11777
|
-
// straight to the host's data-variant / data-size attributes.
|
|
11778
|
-
inputs: ['kjAnimation', 'kjAriaLabel'],
|
|
11779
|
-
},
|
|
11780
|
-
], template: `
|
|
11781
|
-
<span class="kj-spinner__glyph" aria-hidden="true"></span>
|
|
11782
|
-
@if (shouldRenderHiddenLabel()) {
|
|
11783
|
-
<span kjVisuallyHidden>{{ kjAriaLabel() }}</span>
|
|
11784
|
-
}
|
|
11785
|
-
`, encapsulation: ViewEncapsulation.None, host: {
|
|
11786
|
-
'class': 'kj-spinner',
|
|
11787
|
-
'[attr.data-variant]': 'kjVariant()',
|
|
11788
|
-
'[attr.data-size]': 'kjSize()',
|
|
11789
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-spinner{--kj-spinner-size: 1.25rem;--kj-spinner-color: currentColor;--kj-spinner-track: color-mix(in srgb, currentColor 20%, transparent);--kj-spinner-duration: .7s;display:inline-flex;align-items:center;justify-content:center;inline-size:var(--kj-spinner-size);block-size:var(--kj-spinner-size);color:var(--kj-spinner-color);pointer-events:none}.kj-spinner[data-size=xs]{--kj-spinner-size: .75rem}.kj-spinner[data-size=sm]{--kj-spinner-size: 1rem}.kj-spinner[data-size=md]{--kj-spinner-size: 1.25rem}.kj-spinner[data-size=lg]{--kj-spinner-size: 1.75rem}.kj-spinner[data-variant=neutral]{--kj-spinner-color: currentColor}.kj-spinner[data-variant=primary]{--kj-spinner-color: var(--kj-fg-primary)}.kj-spinner[data-variant=secondary]{--kj-spinner-color: var(--kj-fg-default)}.kj-spinner[data-variant=success]{--kj-spinner-color: var(--kj-fg-success, #16a34a)}.kj-spinner[data-variant=warning]{--kj-spinner-color: var(--kj-fg-warning, #d97706)}.kj-spinner[data-variant=error]{--kj-spinner-color: var(--kj-fg-danger, #dc2626)}.kj-spinner[data-variant=info]{--kj-spinner-color: var(--kj-fg-info, #2563eb)}.kj-spinner__glyph{display:inline-block;inline-size:100%;block-size:100%}.kj-spinner[data-animation=spin] .kj-spinner__glyph{border:2px solid var(--kj-spinner-track);border-block-start-color:var(--kj-spinner-color);border-radius:50%;animation:kj-spinner-spin var(--kj-spinner-duration) linear infinite}.kj-spinner[data-animation=pulse] .kj-spinner__glyph{background:var(--kj-spinner-color);border-radius:50%;animation:kj-spinner-pulse calc(var(--kj-spinner-duration) * 2) ease-in-out infinite}.kj-spinner[data-animation=dots]{inline-size:auto}.kj-spinner[data-animation=dots] .kj-spinner__glyph{display:inline-flex;gap:calc(var(--kj-spinner-size) * .25);inline-size:auto;block-size:100%}.kj-spinner[data-animation=dots] .kj-spinner__glyph:before,.kj-spinner[data-animation=dots] .kj-spinner__glyph:after{content:\"\";inline-size:calc(var(--kj-spinner-size) * .3);block-size:calc(var(--kj-spinner-size) * .3);background:var(--kj-spinner-color);border-radius:50%;animation:kj-spinner-dots calc(var(--kj-spinner-duration) * 2) ease-in-out infinite}.kj-spinner[data-animation=dots] .kj-spinner__glyph{background:transparent}.kj-spinner[data-animation=dots] .kj-spinner__glyph:after{animation-delay:calc(var(--kj-spinner-duration) * .4)}.kj-spinner[data-animation=bars]{inline-size:auto}.kj-spinner[data-animation=bars] .kj-spinner__glyph{display:inline-flex;align-items:stretch;gap:calc(var(--kj-spinner-size) * .15);inline-size:auto;block-size:100%}.kj-spinner[data-animation=bars] .kj-spinner__glyph:before,.kj-spinner[data-animation=bars] .kj-spinner__glyph:after{content:\"\";inline-size:calc(var(--kj-spinner-size) * .2);background:var(--kj-spinner-color);border-radius:calc(var(--kj-spinner-size) * .05);animation:kj-spinner-bars calc(var(--kj-spinner-duration) * 1.6) ease-in-out infinite;transform-origin:center}.kj-spinner[data-animation=bars] .kj-spinner__glyph:after{animation-delay:calc(var(--kj-spinner-duration) * .4)}.kj-spinner[data-reduced-motion=true] .kj-spinner__glyph,.kj-spinner[data-reduced-motion=true] .kj-spinner__glyph:before,.kj-spinner[data-reduced-motion=true] .kj-spinner__glyph:after{animation:kj-spinner-reduced-motion 1.6s ease-in-out infinite!important}}@keyframes kj-spinner-spin{to{transform:rotate(360deg)}}@keyframes kj-spinner-pulse{0%,to{opacity:.35;transform:scale(.85)}50%{opacity:1;transform:scale(1)}}@keyframes kj-spinner-dots{0%,80%,to{transform:scale(.4);opacity:.4}40%{transform:scale(1);opacity:1}}@keyframes kj-spinner-bars{0%,40%,to{transform:scaleY(.4)}20%{transform:scaleY(1)}}@keyframes kj-spinner-reduced-motion{0%,to{opacity:.45}50%{opacity:1}}\n"] }]
|
|
11790
|
-
}], ctorParameters: () => [], propDecorators: { kjVariant: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjVariant", required: false }] }], kjSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjSize", required: false }] }], kjAnimation: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjAnimation", required: false }] }], kjAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjAriaLabel", required: false }] }] } });
|
|
11791
|
-
|
|
11792
14292
|
/**
|
|
11793
14293
|
* Styled root wrapper around the headless `KjStepper` directive.
|
|
11794
14294
|
*
|
|
@@ -12083,10 +14583,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
12083
14583
|
* </div>
|
|
12084
14584
|
* ```
|
|
12085
14585
|
*
|
|
12086
|
-
*
|
|
12087
|
-
*
|
|
12088
|
-
* @doc-name table-virtual
|
|
12089
|
-
* @doc-description Row virtualization adapter on @tanstack/virtual-core. Exposes virtualRows / paddingTop / paddingBottom / totalSize signals for the styled data table.
|
|
14586
|
+
* Documented as part of the data table on the `table` page — not a standalone
|
|
14587
|
+
* docs entry.
|
|
12090
14588
|
*/
|
|
12091
14589
|
class KjTableVirtual {
|
|
12092
14590
|
/** Total number of rows in the underlying dataset. */
|
|
@@ -14965,10 +17463,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
14965
17463
|
* The toolbar must sit inside a `<kj-table>` (or any element hosting
|
|
14966
17464
|
* the `KJ_TABLE` token) so it can resolve the table instance via DI.
|
|
14967
17465
|
*
|
|
14968
|
-
*
|
|
14969
|
-
*
|
|
14970
|
-
* @doc-name table-toolbar
|
|
14971
|
-
* @doc-description Toolbar chrome above the data table — quick filter, density, column visibility, export, and bulk-action slot.
|
|
17466
|
+
* Documented as part of the data table on the `table` page — not a standalone
|
|
17467
|
+
* docs entry.
|
|
14972
17468
|
*/
|
|
14973
17469
|
class KjTableToolbarComponent {
|
|
14974
17470
|
/** The host table — resolved through `KJ_TABLE` injected from any ancestor. */
|
|
@@ -15207,10 +17703,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
15207
17703
|
* </kj-table>
|
|
15208
17704
|
* ```
|
|
15209
17705
|
*
|
|
15210
|
-
*
|
|
15211
|
-
*
|
|
15212
|
-
* @doc-name table-pagination
|
|
15213
|
-
* @doc-description Page-size selector, First/Prev/Next/Last nav, and "Showing N–M of total" summary bound to the parent table.
|
|
17706
|
+
* Documented as part of the data table on the `table` page — not a standalone
|
|
17707
|
+
* docs entry.
|
|
15214
17708
|
*/
|
|
15215
17709
|
class KjTablePaginationComponent {
|
|
15216
17710
|
/** Available page sizes for the selector. */
|
|
@@ -15533,10 +18027,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
15533
18027
|
* </kj-table>
|
|
15534
18028
|
* ```
|
|
15535
18029
|
*
|
|
15536
|
-
*
|
|
15537
|
-
*
|
|
15538
|
-
* @doc-name table-side-panel
|
|
15539
|
-
* @doc-description Service-launched drawer listing every column with visibility, pin, and group controls.
|
|
18030
|
+
* Documented as part of the data table on the `table` page — not a standalone
|
|
18031
|
+
* docs entry.
|
|
15540
18032
|
*/
|
|
15541
18033
|
class KjTableSidePanelComponent {
|
|
15542
18034
|
/** Whether the side panel is visible. Two-way bindable. */
|
|
@@ -15616,10 +18108,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
15616
18108
|
* </table>
|
|
15617
18109
|
* ```
|
|
15618
18110
|
*
|
|
15619
|
-
*
|
|
15620
|
-
*
|
|
15621
|
-
* @doc-name table-status-bar
|
|
15622
|
-
* @doc-description Counts strip showing row count, selected count, and filtered indicator.
|
|
18111
|
+
* Documented as part of the data table on the `table` page — not a standalone
|
|
18112
|
+
* docs entry.
|
|
15623
18113
|
*/
|
|
15624
18114
|
class KjTableStatusBarComponent {
|
|
15625
18115
|
table = inject(KJ_TABLE);
|
|
@@ -16741,11 +19231,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
16741
19231
|
*/
|
|
16742
19232
|
class KjToastWrapperComponent {
|
|
16743
19233
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjToastWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
16744
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: KjToastWrapperComponent, isStandalone: true, selector: "kj-toast-wrapper", host: { styleAttribute: "display: contents;" }, ngImport: i0, template: `<ng-content />`, isInline: true, styles: ["@layer kj.component{.kj-toast-viewport{position:fixed;list-style:none;padding:0;margin:0;z-index:var(--kj-toast-z-index, 1000);bottom:1rem;right:1rem;width:22rem;max-width:calc(100vw - 2rem)}.kj-toast-viewport[data-position-y=bottom]{bottom:1rem;top:auto}.kj-toast-viewport[data-position-y=top]{top:1rem;bottom:auto}.kj-toast-viewport[data-position-x=end]{right:1rem;left:auto}.kj-toast-viewport[data-position-x=start]{left:1rem;right:auto}.kj-toast-viewport[data-position-x=center]{left:50%;right:auto;transform:translate(-50%)}.kj-toast-viewport li{position:absolute;left:0;right:0;transition:transform .4s cubic-bezier(.21,.61,.35,1),opacity .3s ease}.kj-toast-viewport[data-position-y=bottom] li{bottom:0}.kj-toast-viewport[data-position-y=top] li{top:0}.kj-toast-viewport[data-expanded=false] .kj-toast:not([data-front=true]){height:var(--kj-toast-front-height);overflow:hidden;transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px) * -1)) scale(calc(1 - (var(--kj-toast-index) - 1) * .06));opacity:calc(1 - (var(--kj-toast-index) - 1) * .25)}.kj-toast-viewport[data-position-y=top][data-expanded=false] .kj-toast:not([data-front=true]){transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px))) scale(calc(1 - (var(--kj-toast-index) - 1) * .06))}.kj-toast-viewport[data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px)) * -1))}.kj-toast-viewport[data-position-y=top][data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px))))}.kj-toast{display:flex;align-items:center;gap:var(--kj-space-md, .75rem);padding:var(--kj-space-md, .75rem) var(--kj-space-lg, 1rem);min-width:18rem;font:.875rem / 1.4 var(--kj-font-sans, sans-serif);border-radius:var(--kj-radius-box, .5rem);box-shadow:0 4px 16px #0000002e,0 1px #ffffff0a inset;border:var(--kj-border, 1px) solid var(--kj-border-default, #e2e8f0);background:var(--kj-bg-elevated, #fff);color:var(--kj-fg-default, #1a202c);animation:kj-toast-enter .35s cubic-bezier(.21,.61,.35,1)}@keyframes kj-toast-enter{0%{opacity:0;transform:translateY(100%) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.kj-toast[data-variant=success]{background:var(--kj-bg-success, #16a34a);color:var(--kj-fg-on-success, #fff);border-color:transparent}.kj-toast[data-variant=warning]{background:var(--kj-bg-warning, #d97706);color:var(--kj-fg-on-warning, #fff);border-color:transparent}.kj-toast[data-variant=destructive]{background:var(--kj-bg-danger, #dc2626);color:var(--kj-fg-on-danger, #fff);border-color:transparent}.kj-toast-close{background:transparent;border:0;color:inherit;cursor:pointer;padding:4px 6px;border-radius:4px;line-height:1;font-size:1.1rem;opacity:.7;margin-
|
|
19234
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: KjToastWrapperComponent, isStandalone: true, selector: "kj-toast-wrapper", host: { styleAttribute: "display: contents;" }, ngImport: i0, template: `<ng-content />`, isInline: true, styles: ["@layer kj.component{.kj-toast-viewport{position:fixed;list-style:none;padding:0;margin:0;z-index:var(--kj-toast-z-index, 1000);bottom:1rem;right:1rem;width:22rem;max-width:calc(100vw - 2rem)}.kj-toast-viewport[data-position-y=bottom]{bottom:1rem;top:auto}.kj-toast-viewport[data-position-y=top]{top:1rem;bottom:auto}.kj-toast-viewport[data-position-x=end]{right:1rem;left:auto}.kj-toast-viewport[data-position-x=start]{left:1rem;right:auto}.kj-toast-viewport[data-position-x=center]{left:50%;right:auto;transform:translate(-50%)}.kj-toast-viewport li{position:absolute;left:0;right:0;transition:transform .4s cubic-bezier(.21,.61,.35,1),opacity .3s ease}.kj-toast-viewport[data-position-y=bottom] li{bottom:0}.kj-toast-viewport[data-position-y=top] li{top:0}.kj-toast-viewport[data-expanded=false] .kj-toast:not([data-front=true]){height:var(--kj-toast-front-height);overflow:hidden;transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px) * -1)) scale(calc(1 - (var(--kj-toast-index) - 1) * .06));opacity:calc(1 - (var(--kj-toast-index) - 1) * .25)}.kj-toast-viewport[data-position-y=top][data-expanded=false] .kj-toast:not([data-front=true]){transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px))) scale(calc(1 - (var(--kj-toast-index) - 1) * .06))}.kj-toast-viewport[data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px)) * -1))}.kj-toast-viewport[data-position-y=top][data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px))))}.kj-toast{display:flex;align-items:center;gap:var(--kj-space-md, .75rem);padding:var(--kj-space-md, .75rem) var(--kj-space-lg, 1rem);min-width:18rem;font:.875rem / 1.4 var(--kj-font-sans, sans-serif);border-radius:var(--kj-radius-box, .5rem);box-shadow:0 4px 16px #0000002e,0 1px #ffffff0a inset;border:var(--kj-border, 1px) solid var(--kj-border-default, #e2e8f0);background:var(--kj-bg-elevated, #fff);color:var(--kj-fg-default, #1a202c);animation:kj-toast-enter .35s cubic-bezier(.21,.61,.35,1)}@keyframes kj-toast-enter{0%{opacity:0;transform:translateY(100%) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.kj-toast[data-variant=success]{background:var(--kj-bg-success, #16a34a);color:var(--kj-fg-on-success, #fff);border-color:transparent}.kj-toast[data-variant=warning]{background:var(--kj-bg-warning, #d97706);color:var(--kj-fg-on-warning, #fff);border-color:transparent}.kj-toast[data-variant=destructive]{background:var(--kj-bg-danger, #dc2626);color:var(--kj-fg-on-danger, #fff);border-color:transparent}.kj-toast-close{background:transparent;border:0;color:inherit;cursor:pointer;padding:4px 6px;border-radius:4px;line-height:1;font-size:1.1rem;opacity:.7;margin-inline-start:auto;flex-shrink:0}.kj-toast-close:hover{opacity:1;background:#00000014}.kj-toast-close:focus-visible{outline:2px solid currentColor;outline-offset:2px}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
16745
19235
|
}
|
|
16746
19236
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjToastWrapperComponent, decorators: [{
|
|
16747
19237
|
type: Component,
|
|
16748
|
-
args: [{ selector: 'kj-toast-wrapper', standalone: true, template: `<ng-content />`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-toast-viewport{position:fixed;list-style:none;padding:0;margin:0;z-index:var(--kj-toast-z-index, 1000);bottom:1rem;right:1rem;width:22rem;max-width:calc(100vw - 2rem)}.kj-toast-viewport[data-position-y=bottom]{bottom:1rem;top:auto}.kj-toast-viewport[data-position-y=top]{top:1rem;bottom:auto}.kj-toast-viewport[data-position-x=end]{right:1rem;left:auto}.kj-toast-viewport[data-position-x=start]{left:1rem;right:auto}.kj-toast-viewport[data-position-x=center]{left:50%;right:auto;transform:translate(-50%)}.kj-toast-viewport li{position:absolute;left:0;right:0;transition:transform .4s cubic-bezier(.21,.61,.35,1),opacity .3s ease}.kj-toast-viewport[data-position-y=bottom] li{bottom:0}.kj-toast-viewport[data-position-y=top] li{top:0}.kj-toast-viewport[data-expanded=false] .kj-toast:not([data-front=true]){height:var(--kj-toast-front-height);overflow:hidden;transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px) * -1)) scale(calc(1 - (var(--kj-toast-index) - 1) * .06));opacity:calc(1 - (var(--kj-toast-index) - 1) * .25)}.kj-toast-viewport[data-position-y=top][data-expanded=false] .kj-toast:not([data-front=true]){transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px))) scale(calc(1 - (var(--kj-toast-index) - 1) * .06))}.kj-toast-viewport[data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px)) * -1))}.kj-toast-viewport[data-position-y=top][data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px))))}.kj-toast{display:flex;align-items:center;gap:var(--kj-space-md, .75rem);padding:var(--kj-space-md, .75rem) var(--kj-space-lg, 1rem);min-width:18rem;font:.875rem / 1.4 var(--kj-font-sans, sans-serif);border-radius:var(--kj-radius-box, .5rem);box-shadow:0 4px 16px #0000002e,0 1px #ffffff0a inset;border:var(--kj-border, 1px) solid var(--kj-border-default, #e2e8f0);background:var(--kj-bg-elevated, #fff);color:var(--kj-fg-default, #1a202c);animation:kj-toast-enter .35s cubic-bezier(.21,.61,.35,1)}@keyframes kj-toast-enter{0%{opacity:0;transform:translateY(100%) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.kj-toast[data-variant=success]{background:var(--kj-bg-success, #16a34a);color:var(--kj-fg-on-success, #fff);border-color:transparent}.kj-toast[data-variant=warning]{background:var(--kj-bg-warning, #d97706);color:var(--kj-fg-on-warning, #fff);border-color:transparent}.kj-toast[data-variant=destructive]{background:var(--kj-bg-danger, #dc2626);color:var(--kj-fg-on-danger, #fff);border-color:transparent}.kj-toast-close{background:transparent;border:0;color:inherit;cursor:pointer;padding:4px 6px;border-radius:4px;line-height:1;font-size:1.1rem;opacity:.7;margin-
|
|
19238
|
+
args: [{ selector: 'kj-toast-wrapper', standalone: true, template: `<ng-content />`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-toast-viewport{position:fixed;list-style:none;padding:0;margin:0;z-index:var(--kj-toast-z-index, 1000);bottom:1rem;right:1rem;width:22rem;max-width:calc(100vw - 2rem)}.kj-toast-viewport[data-position-y=bottom]{bottom:1rem;top:auto}.kj-toast-viewport[data-position-y=top]{top:1rem;bottom:auto}.kj-toast-viewport[data-position-x=end]{right:1rem;left:auto}.kj-toast-viewport[data-position-x=start]{left:1rem;right:auto}.kj-toast-viewport[data-position-x=center]{left:50%;right:auto;transform:translate(-50%)}.kj-toast-viewport li{position:absolute;left:0;right:0;transition:transform .4s cubic-bezier(.21,.61,.35,1),opacity .3s ease}.kj-toast-viewport[data-position-y=bottom] li{bottom:0}.kj-toast-viewport[data-position-y=top] li{top:0}.kj-toast-viewport[data-expanded=false] .kj-toast:not([data-front=true]){height:var(--kj-toast-front-height);overflow:hidden;transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px) * -1)) scale(calc(1 - (var(--kj-toast-index) - 1) * .06));opacity:calc(1 - (var(--kj-toast-index) - 1) * .25)}.kj-toast-viewport[data-position-y=top][data-expanded=false] .kj-toast:not([data-front=true]){transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px))) scale(calc(1 - (var(--kj-toast-index) - 1) * .06))}.kj-toast-viewport[data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px)) * -1))}.kj-toast-viewport[data-position-y=top][data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px))))}.kj-toast{display:flex;align-items:center;gap:var(--kj-space-md, .75rem);padding:var(--kj-space-md, .75rem) var(--kj-space-lg, 1rem);min-width:18rem;font:.875rem / 1.4 var(--kj-font-sans, sans-serif);border-radius:var(--kj-radius-box, .5rem);box-shadow:0 4px 16px #0000002e,0 1px #ffffff0a inset;border:var(--kj-border, 1px) solid var(--kj-border-default, #e2e8f0);background:var(--kj-bg-elevated, #fff);color:var(--kj-fg-default, #1a202c);animation:kj-toast-enter .35s cubic-bezier(.21,.61,.35,1)}@keyframes kj-toast-enter{0%{opacity:0;transform:translateY(100%) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.kj-toast[data-variant=success]{background:var(--kj-bg-success, #16a34a);color:var(--kj-fg-on-success, #fff);border-color:transparent}.kj-toast[data-variant=warning]{background:var(--kj-bg-warning, #d97706);color:var(--kj-fg-on-warning, #fff);border-color:transparent}.kj-toast[data-variant=destructive]{background:var(--kj-bg-danger, #dc2626);color:var(--kj-fg-on-danger, #fff);border-color:transparent}.kj-toast-close{background:transparent;border:0;color:inherit;cursor:pointer;padding:4px 6px;border-radius:4px;line-height:1;font-size:1.1rem;opacity:.7;margin-inline-start:auto;flex-shrink:0}.kj-toast-close:hover{opacity:1;background:#00000014}.kj-toast-close:focus-visible{outline:2px solid currentColor;outline-offset:2px}}\n"] }]
|
|
16749
19239
|
}] });
|
|
16750
19240
|
/**
|
|
16751
19241
|
* Toast viewport. Mount once near your trigger button (or in your app shell).
|
|
@@ -16767,7 +19257,7 @@ class KjToastViewportComponent {
|
|
|
16767
19257
|
</li>
|
|
16768
19258
|
}
|
|
16769
19259
|
</ol>
|
|
16770
|
-
`, isInline: true, styles: ["@layer kj.component{.kj-toast-viewport{position:fixed;list-style:none;padding:0;margin:0;z-index:var(--kj-toast-z-index, 1000);bottom:1rem;right:1rem;width:22rem;max-width:calc(100vw - 2rem)}.kj-toast-viewport[data-position-y=bottom]{bottom:1rem;top:auto}.kj-toast-viewport[data-position-y=top]{top:1rem;bottom:auto}.kj-toast-viewport[data-position-x=end]{right:1rem;left:auto}.kj-toast-viewport[data-position-x=start]{left:1rem;right:auto}.kj-toast-viewport[data-position-x=center]{left:50%;right:auto;transform:translate(-50%)}.kj-toast-viewport li{position:absolute;left:0;right:0;transition:transform .4s cubic-bezier(.21,.61,.35,1),opacity .3s ease}.kj-toast-viewport[data-position-y=bottom] li{bottom:0}.kj-toast-viewport[data-position-y=top] li{top:0}.kj-toast-viewport[data-expanded=false] .kj-toast:not([data-front=true]){height:var(--kj-toast-front-height);overflow:hidden;transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px) * -1)) scale(calc(1 - (var(--kj-toast-index) - 1) * .06));opacity:calc(1 - (var(--kj-toast-index) - 1) * .25)}.kj-toast-viewport[data-position-y=top][data-expanded=false] .kj-toast:not([data-front=true]){transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px))) scale(calc(1 - (var(--kj-toast-index) - 1) * .06))}.kj-toast-viewport[data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px)) * -1))}.kj-toast-viewport[data-position-y=top][data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px))))}.kj-toast{display:flex;align-items:center;gap:var(--kj-space-md, .75rem);padding:var(--kj-space-md, .75rem) var(--kj-space-lg, 1rem);min-width:18rem;font:.875rem / 1.4 var(--kj-font-sans, sans-serif);border-radius:var(--kj-radius-box, .5rem);box-shadow:0 4px 16px #0000002e,0 1px #ffffff0a inset;border:var(--kj-border, 1px) solid var(--kj-border-default, #e2e8f0);background:var(--kj-bg-elevated, #fff);color:var(--kj-fg-default, #1a202c);animation:kj-toast-enter .35s cubic-bezier(.21,.61,.35,1)}@keyframes kj-toast-enter{0%{opacity:0;transform:translateY(100%) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.kj-toast[data-variant=success]{background:var(--kj-bg-success, #16a34a);color:var(--kj-fg-on-success, #fff);border-color:transparent}.kj-toast[data-variant=warning]{background:var(--kj-bg-warning, #d97706);color:var(--kj-fg-on-warning, #fff);border-color:transparent}.kj-toast[data-variant=destructive]{background:var(--kj-bg-danger, #dc2626);color:var(--kj-fg-on-danger, #fff);border-color:transparent}.kj-toast-close{background:transparent;border:0;color:inherit;cursor:pointer;padding:4px 6px;border-radius:4px;line-height:1;font-size:1.1rem;opacity:.7;margin-
|
|
19260
|
+
`, isInline: true, styles: ["@layer kj.component{.kj-toast-viewport{position:fixed;list-style:none;padding:0;margin:0;z-index:var(--kj-toast-z-index, 1000);bottom:1rem;right:1rem;width:22rem;max-width:calc(100vw - 2rem)}.kj-toast-viewport[data-position-y=bottom]{bottom:1rem;top:auto}.kj-toast-viewport[data-position-y=top]{top:1rem;bottom:auto}.kj-toast-viewport[data-position-x=end]{right:1rem;left:auto}.kj-toast-viewport[data-position-x=start]{left:1rem;right:auto}.kj-toast-viewport[data-position-x=center]{left:50%;right:auto;transform:translate(-50%)}.kj-toast-viewport li{position:absolute;left:0;right:0;transition:transform .4s cubic-bezier(.21,.61,.35,1),opacity .3s ease}.kj-toast-viewport[data-position-y=bottom] li{bottom:0}.kj-toast-viewport[data-position-y=top] li{top:0}.kj-toast-viewport[data-expanded=false] .kj-toast:not([data-front=true]){height:var(--kj-toast-front-height);overflow:hidden;transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px) * -1)) scale(calc(1 - (var(--kj-toast-index) - 1) * .06));opacity:calc(1 - (var(--kj-toast-index) - 1) * .25)}.kj-toast-viewport[data-position-y=top][data-expanded=false] .kj-toast:not([data-front=true]){transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px))) scale(calc(1 - (var(--kj-toast-index) - 1) * .06))}.kj-toast-viewport[data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px)) * -1))}.kj-toast-viewport[data-position-y=top][data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px))))}.kj-toast{display:flex;align-items:center;gap:var(--kj-space-md, .75rem);padding:var(--kj-space-md, .75rem) var(--kj-space-lg, 1rem);min-width:18rem;font:.875rem / 1.4 var(--kj-font-sans, sans-serif);border-radius:var(--kj-radius-box, .5rem);box-shadow:0 4px 16px #0000002e,0 1px #ffffff0a inset;border:var(--kj-border, 1px) solid var(--kj-border-default, #e2e8f0);background:var(--kj-bg-elevated, #fff);color:var(--kj-fg-default, #1a202c);animation:kj-toast-enter .35s cubic-bezier(.21,.61,.35,1)}@keyframes kj-toast-enter{0%{opacity:0;transform:translateY(100%) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.kj-toast[data-variant=success]{background:var(--kj-bg-success, #16a34a);color:var(--kj-fg-on-success, #fff);border-color:transparent}.kj-toast[data-variant=warning]{background:var(--kj-bg-warning, #d97706);color:var(--kj-fg-on-warning, #fff);border-color:transparent}.kj-toast[data-variant=destructive]{background:var(--kj-bg-danger, #dc2626);color:var(--kj-fg-on-danger, #fff);border-color:transparent}.kj-toast-close{background:transparent;border:0;color:inherit;cursor:pointer;padding:4px 6px;border-radius:4px;line-height:1;font-size:1.1rem;opacity:.7;margin-inline-start:auto;flex-shrink:0}.kj-toast-close:hover{opacity:1;background:#00000014}.kj-toast-close:focus-visible{outline:2px solid currentColor;outline-offset:2px}}\n"], dependencies: [{ kind: "directive", type: KjToastViewport, selector: "[kjToastViewport]", inputs: ["kjToastDefaultTemplate", "kjToastMaxVisible", "kjToastGap", "kjToastBaseZIndex", "kjToastPositionX", "kjToastPositionY", "kjToastExpand", "kjToastPauseOnHover"], exportAs: ["kjToastViewport"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
16771
19261
|
}
|
|
16772
19262
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjToastViewportComponent, decorators: [{
|
|
16773
19263
|
type: Component,
|
|
@@ -16784,7 +19274,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
16784
19274
|
</li>
|
|
16785
19275
|
}
|
|
16786
19276
|
</ol>
|
|
16787
|
-
`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-toast-viewport{position:fixed;list-style:none;padding:0;margin:0;z-index:var(--kj-toast-z-index, 1000);bottom:1rem;right:1rem;width:22rem;max-width:calc(100vw - 2rem)}.kj-toast-viewport[data-position-y=bottom]{bottom:1rem;top:auto}.kj-toast-viewport[data-position-y=top]{top:1rem;bottom:auto}.kj-toast-viewport[data-position-x=end]{right:1rem;left:auto}.kj-toast-viewport[data-position-x=start]{left:1rem;right:auto}.kj-toast-viewport[data-position-x=center]{left:50%;right:auto;transform:translate(-50%)}.kj-toast-viewport li{position:absolute;left:0;right:0;transition:transform .4s cubic-bezier(.21,.61,.35,1),opacity .3s ease}.kj-toast-viewport[data-position-y=bottom] li{bottom:0}.kj-toast-viewport[data-position-y=top] li{top:0}.kj-toast-viewport[data-expanded=false] .kj-toast:not([data-front=true]){height:var(--kj-toast-front-height);overflow:hidden;transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px) * -1)) scale(calc(1 - (var(--kj-toast-index) - 1) * .06));opacity:calc(1 - (var(--kj-toast-index) - 1) * .25)}.kj-toast-viewport[data-position-y=top][data-expanded=false] .kj-toast:not([data-front=true]){transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px))) scale(calc(1 - (var(--kj-toast-index) - 1) * .06))}.kj-toast-viewport[data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px)) * -1))}.kj-toast-viewport[data-position-y=top][data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px))))}.kj-toast{display:flex;align-items:center;gap:var(--kj-space-md, .75rem);padding:var(--kj-space-md, .75rem) var(--kj-space-lg, 1rem);min-width:18rem;font:.875rem / 1.4 var(--kj-font-sans, sans-serif);border-radius:var(--kj-radius-box, .5rem);box-shadow:0 4px 16px #0000002e,0 1px #ffffff0a inset;border:var(--kj-border, 1px) solid var(--kj-border-default, #e2e8f0);background:var(--kj-bg-elevated, #fff);color:var(--kj-fg-default, #1a202c);animation:kj-toast-enter .35s cubic-bezier(.21,.61,.35,1)}@keyframes kj-toast-enter{0%{opacity:0;transform:translateY(100%) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.kj-toast[data-variant=success]{background:var(--kj-bg-success, #16a34a);color:var(--kj-fg-on-success, #fff);border-color:transparent}.kj-toast[data-variant=warning]{background:var(--kj-bg-warning, #d97706);color:var(--kj-fg-on-warning, #fff);border-color:transparent}.kj-toast[data-variant=destructive]{background:var(--kj-bg-danger, #dc2626);color:var(--kj-fg-on-danger, #fff);border-color:transparent}.kj-toast-close{background:transparent;border:0;color:inherit;cursor:pointer;padding:4px 6px;border-radius:4px;line-height:1;font-size:1.1rem;opacity:.7;margin-
|
|
19277
|
+
`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-toast-viewport{position:fixed;list-style:none;padding:0;margin:0;z-index:var(--kj-toast-z-index, 1000);bottom:1rem;right:1rem;width:22rem;max-width:calc(100vw - 2rem)}.kj-toast-viewport[data-position-y=bottom]{bottom:1rem;top:auto}.kj-toast-viewport[data-position-y=top]{top:1rem;bottom:auto}.kj-toast-viewport[data-position-x=end]{right:1rem;left:auto}.kj-toast-viewport[data-position-x=start]{left:1rem;right:auto}.kj-toast-viewport[data-position-x=center]{left:50%;right:auto;transform:translate(-50%)}.kj-toast-viewport li{position:absolute;left:0;right:0;transition:transform .4s cubic-bezier(.21,.61,.35,1),opacity .3s ease}.kj-toast-viewport[data-position-y=bottom] li{bottom:0}.kj-toast-viewport[data-position-y=top] li{top:0}.kj-toast-viewport[data-expanded=false] .kj-toast:not([data-front=true]){height:var(--kj-toast-front-height);overflow:hidden;transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px) * -1)) scale(calc(1 - (var(--kj-toast-index) - 1) * .06));opacity:calc(1 - (var(--kj-toast-index) - 1) * .25)}.kj-toast-viewport[data-position-y=top][data-expanded=false] .kj-toast:not([data-front=true]){transform:translateY(calc((var(--kj-toast-index) - 1) * var(--kj-toast-gap, 14px))) scale(calc(1 - (var(--kj-toast-index) - 1) * .06))}.kj-toast-viewport[data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px)) * -1))}.kj-toast-viewport[data-position-y=top][data-expanded=true] .kj-toast{transform:translateY(calc((var(--kj-toast-index) - 1) * (var(--kj-toast-height, 0px) + var(--kj-toast-gap, 14px))))}.kj-toast{display:flex;align-items:center;gap:var(--kj-space-md, .75rem);padding:var(--kj-space-md, .75rem) var(--kj-space-lg, 1rem);min-width:18rem;font:.875rem / 1.4 var(--kj-font-sans, sans-serif);border-radius:var(--kj-radius-box, .5rem);box-shadow:0 4px 16px #0000002e,0 1px #ffffff0a inset;border:var(--kj-border, 1px) solid var(--kj-border-default, #e2e8f0);background:var(--kj-bg-elevated, #fff);color:var(--kj-fg-default, #1a202c);animation:kj-toast-enter .35s cubic-bezier(.21,.61,.35,1)}@keyframes kj-toast-enter{0%{opacity:0;transform:translateY(100%) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.kj-toast[data-variant=success]{background:var(--kj-bg-success, #16a34a);color:var(--kj-fg-on-success, #fff);border-color:transparent}.kj-toast[data-variant=warning]{background:var(--kj-bg-warning, #d97706);color:var(--kj-fg-on-warning, #fff);border-color:transparent}.kj-toast[data-variant=destructive]{background:var(--kj-bg-danger, #dc2626);color:var(--kj-fg-on-danger, #fff);border-color:transparent}.kj-toast-close{background:transparent;border:0;color:inherit;cursor:pointer;padding:4px 6px;border-radius:4px;line-height:1;font-size:1.1rem;opacity:.7;margin-inline-start:auto;flex-shrink:0}.kj-toast-close:hover{opacity:1;background:#00000014}.kj-toast-close:focus-visible{outline:2px solid currentColor;outline-offset:2px}}\n"] }]
|
|
16788
19278
|
}] });
|
|
16789
19279
|
/**
|
|
16790
19280
|
* Single toast item. Bind `[variant]` from `ctx.variant` and `[id]` from `ctx.id`.
|
|
@@ -16850,7 +19340,7 @@ class KjToastCloseComponent {
|
|
|
16850
19340
|
[kjToastClose]="toastId()"
|
|
16851
19341
|
[attr.aria-label]="ariaLabel()"
|
|
16852
19342
|
class="kj-toast-close"
|
|
16853
|
-
><ng-content /></button>`, isInline: true, dependencies: [{ kind: "directive", type: KjToastClose, selector: "[kjToastClose]", inputs: ["kjToastClose"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
19343
|
+
><ng-content /></button>`, isInline: true, dependencies: [{ kind: "directive", type: KjToastClose, selector: "[kjToastClose]", inputs: ["kjToastClose", "kjToastCloseLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
16854
19344
|
}
|
|
16855
19345
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjToastCloseComponent, decorators: [{
|
|
16856
19346
|
type: Component,
|
|
@@ -17176,10 +19666,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
17176
19666
|
* --kj-command-item-align — Cross-axis alignment of row contents. Defaults to `center`.
|
|
17177
19667
|
* --kj-command-item-gap — Gap between icon and label inside a row. Defaults to --kj-space-md.
|
|
17178
19668
|
*
|
|
19669
|
+
* @doc-category Library/Actions
|
|
17179
19670
|
* @doc
|
|
17180
19671
|
* @doc-name command-palette
|
|
17181
19672
|
* @doc-description Themed Cmd-K modal command palette with fuzzy filtering, grouped results, and keyboard navigation.
|
|
17182
|
-
* @doc-is-main
|
|
17183
19673
|
*/
|
|
17184
19674
|
class KjCommandPaletteFooter {
|
|
17185
19675
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjCommandPaletteFooter, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
@@ -17281,6 +19771,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
17281
19771
|
* @doc-category Library/Actions
|
|
17282
19772
|
* @doc
|
|
17283
19773
|
* @doc-name command-palette
|
|
19774
|
+
* @doc-is-main
|
|
17284
19775
|
*/
|
|
17285
19776
|
class KjCommandPaletteComponent {
|
|
17286
19777
|
/** Input placeholder text. */
|
|
@@ -17312,7 +19803,22 @@ class KjCommandPaletteComponent {
|
|
|
17312
19803
|
...(ngDevMode ? [{ debugName: "customFooter" }] : /* istanbul ignore next */ []));
|
|
17313
19804
|
destroyRef = inject(DestroyRef);
|
|
17314
19805
|
platformId = inject(PLATFORM_ID);
|
|
19806
|
+
/** The composed headless palette (host directive) — owns query + active state. */
|
|
19807
|
+
palette = inject(KjCommandPalette);
|
|
17315
19808
|
constructor() {
|
|
19809
|
+
// Reset the search query + active item when the palette closes, so the
|
|
19810
|
+
// next open starts fresh instead of restoring the previous search. Paired
|
|
19811
|
+
// with KjCommandInput reflecting the query signal back to the DOM input,
|
|
19812
|
+
// this also clears the visible text.
|
|
19813
|
+
let wasOpen = false;
|
|
19814
|
+
effect(() => {
|
|
19815
|
+
const open = this.kjOpen();
|
|
19816
|
+
if (wasOpen && !open) {
|
|
19817
|
+
this.palette.kjQuery.set('');
|
|
19818
|
+
this.palette.kjValue.set(null);
|
|
19819
|
+
}
|
|
19820
|
+
wasOpen = open;
|
|
19821
|
+
});
|
|
17316
19822
|
afterNextRender(() => {
|
|
17317
19823
|
if (!isPlatformBrowser(this.platformId))
|
|
17318
19824
|
return;
|
|
@@ -17416,7 +19922,7 @@ class KjCommandPaletteComponent {
|
|
|
17416
19922
|
}
|
|
17417
19923
|
</div>
|
|
17418
19924
|
</div>
|
|
17419
|
-
`, isInline: true, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-
|
|
19925
|
+
`, isInline: true, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-inline-start:2px solid transparent;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);text-align:start;cursor:pointer;transition:background .1s}.kj-command-item:hover,.kj-command-item[data-active]{background:var(--kj-bg-surface);border-inline-start-color:var(--kj-bg-primary)}.kj-command-item[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-command-group{padding-block:.25rem}.kj-command-group__label{padding:.375rem var(--kj-space-lg, 1.25rem) .125rem;font-family:var(--kj-font-mono);font-size:.6rem;font-weight:600;color:var(--kj-fg-muted);letter-spacing:.1em;text-transform:uppercase}.kj-command-separator{height:1px;background:var(--kj-border-default);margin-block:.25rem}.kj-command-palette__footer{display:flex;gap:var(--kj-space-xl, 1.5rem);padding:var(--kj-space-sm, .375rem) var(--kj-space-lg, 1.25rem);border-top:1px solid var(--kj-border-default);background:var(--kj-bg-surface)}.kj-command-palette__footer span{display:flex;align-items:center;gap:.4rem;font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted)}.kj-command-palette__footer kbd{background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.6rem;padding:.1rem .35rem}@media(prefers-reduced-motion:reduce){.kj-command-item{transition:none}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: KjCommandInput, selector: "input[kjCommandInput]", exportAs: ["kjCommandInput"] }, { kind: "directive", type: KjCommandList, selector: "[kjCommandList]" }, { kind: "directive", type: KjCommandEmpty, selector: "[kjCommandEmpty]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
17420
19926
|
}
|
|
17421
19927
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjCommandPaletteComponent, decorators: [{
|
|
17422
19928
|
type: Component,
|
|
@@ -17475,7 +19981,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
17475
19981
|
class: 'kj-command-palette',
|
|
17476
19982
|
style: 'display: contents;',
|
|
17477
19983
|
'(kjActivate)': 'onActivate()',
|
|
17478
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-
|
|
19984
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-inline-start:2px solid transparent;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);text-align:start;cursor:pointer;transition:background .1s}.kj-command-item:hover,.kj-command-item[data-active]{background:var(--kj-bg-surface);border-inline-start-color:var(--kj-bg-primary)}.kj-command-item[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-command-group{padding-block:.25rem}.kj-command-group__label{padding:.375rem var(--kj-space-lg, 1.25rem) .125rem;font-family:var(--kj-font-mono);font-size:.6rem;font-weight:600;color:var(--kj-fg-muted);letter-spacing:.1em;text-transform:uppercase}.kj-command-separator{height:1px;background:var(--kj-border-default);margin-block:.25rem}.kj-command-palette__footer{display:flex;gap:var(--kj-space-xl, 1.5rem);padding:var(--kj-space-sm, .375rem) var(--kj-space-lg, 1.25rem);border-top:1px solid var(--kj-border-default);background:var(--kj-bg-surface)}.kj-command-palette__footer span{display:flex;align-items:center;gap:.4rem;font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted)}.kj-command-palette__footer kbd{background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.6rem;padding:.1rem .35rem}@media(prefers-reduced-motion:reduce){.kj-command-item{transition:none}}\n"] }]
|
|
17479
19985
|
}], ctorParameters: () => [], propDecorators: { kjPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjPlaceholder", required: false }] }], kjEscBadge: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjEscBadge", required: false }] }], kjAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjAriaLabel", required: false }] }], kjOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjOpen", required: false }] }, { type: i0.Output, args: ["kjOpenChange"] }], kjHotkey: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjHotkey", required: false }] }], kjItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjItems", required: false }] }], kjAutoCloseOnActivate: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjAutoCloseOnActivate", required: false }] }], itemTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KjCommandPaletteItemTemplate), { isSignal: true }] }], customFooter: [{ type: i0.ContentChild, args: [i0.forwardRef(() => KjCommandPaletteFooter), { isSignal: true }] }] } });
|
|
17480
19986
|
/**
|
|
17481
19987
|
* Styled command item. Renders a `<button>` with `[kjCommandItem]` applied.
|
|
@@ -17502,7 +20008,7 @@ class KjCommandItemComponent {
|
|
|
17502
20008
|
isActive = computed(() => this._palette.activeId() !== null && this._palette.activeId() === this._item.id, /* @ts-ignore */
|
|
17503
20009
|
...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []));
|
|
17504
20010
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjCommandItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
17505
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.5", type: KjCommandItemComponent, isStandalone: true, selector: "kj-command-item", inputs: { kjValue: { classPropertyName: "kjValue", publicName: "kjValue", isSignal: true, isRequired: false, transformFunction: null }, kjKeywords: { classPropertyName: "kjKeywords", publicName: "kjKeywords", isSignal: true, isRequired: false, transformFunction: null }, kjShortcut: { classPropertyName: "kjShortcut", publicName: "kjShortcut", isSignal: true, isRequired: false, transformFunction: null }, kjDisabled: { classPropertyName: "kjDisabled", publicName: "kjDisabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "option" }, properties: { "attr.aria-selected": "isActive() ? \"true\" : \"false\"", "attr.data-active": "isActive() ? \"\" : null" }, classAttribute: "kj-command-item" }, hostDirectives: [{ directive: i1.KjListItem, inputs: ["kjItemValue", "kjValue", "kjItemKeywords", "kjKeywords", "kjShortcut", "kjShortcut", "kjDisabled", "kjDisabled"] }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-
|
|
20011
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.5", type: KjCommandItemComponent, isStandalone: true, selector: "kj-command-item", inputs: { kjValue: { classPropertyName: "kjValue", publicName: "kjValue", isSignal: true, isRequired: false, transformFunction: null }, kjKeywords: { classPropertyName: "kjKeywords", publicName: "kjKeywords", isSignal: true, isRequired: false, transformFunction: null }, kjShortcut: { classPropertyName: "kjShortcut", publicName: "kjShortcut", isSignal: true, isRequired: false, transformFunction: null }, kjDisabled: { classPropertyName: "kjDisabled", publicName: "kjDisabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "option" }, properties: { "attr.aria-selected": "isActive() ? \"true\" : \"false\"", "attr.data-active": "isActive() ? \"\" : null" }, classAttribute: "kj-command-item" }, hostDirectives: [{ directive: i1.KjListItem, inputs: ["kjItemValue", "kjValue", "kjItemKeywords", "kjKeywords", "kjShortcut", "kjShortcut", "kjDisabled", "kjDisabled"] }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-inline-start:2px solid transparent;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);text-align:start;cursor:pointer;transition:background .1s}.kj-command-item:hover,.kj-command-item[data-active]{background:var(--kj-bg-surface);border-inline-start-color:var(--kj-bg-primary)}.kj-command-item[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-command-group{padding-block:.25rem}.kj-command-group__label{padding:.375rem var(--kj-space-lg, 1.25rem) .125rem;font-family:var(--kj-font-mono);font-size:.6rem;font-weight:600;color:var(--kj-fg-muted);letter-spacing:.1em;text-transform:uppercase}.kj-command-separator{height:1px;background:var(--kj-border-default);margin-block:.25rem}.kj-command-palette__footer{display:flex;gap:var(--kj-space-xl, 1.5rem);padding:var(--kj-space-sm, .375rem) var(--kj-space-lg, 1.25rem);border-top:1px solid var(--kj-border-default);background:var(--kj-bg-surface)}.kj-command-palette__footer span{display:flex;align-items:center;gap:.4rem;font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted)}.kj-command-palette__footer kbd{background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.6rem;padding:.1rem .35rem}@media(prefers-reduced-motion:reduce){.kj-command-item{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
17506
20012
|
}
|
|
17507
20013
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjCommandItemComponent, decorators: [{
|
|
17508
20014
|
type: Component,
|
|
@@ -17519,7 +20025,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
17519
20025
|
'role': 'option',
|
|
17520
20026
|
'[attr.aria-selected]': 'isActive() ? "true" : "false"',
|
|
17521
20027
|
'[attr.data-active]': 'isActive() ? "" : null',
|
|
17522
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-
|
|
20028
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-inline-start:2px solid transparent;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);text-align:start;cursor:pointer;transition:background .1s}.kj-command-item:hover,.kj-command-item[data-active]{background:var(--kj-bg-surface);border-inline-start-color:var(--kj-bg-primary)}.kj-command-item[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-command-group{padding-block:.25rem}.kj-command-group__label{padding:.375rem var(--kj-space-lg, 1.25rem) .125rem;font-family:var(--kj-font-mono);font-size:.6rem;font-weight:600;color:var(--kj-fg-muted);letter-spacing:.1em;text-transform:uppercase}.kj-command-separator{height:1px;background:var(--kj-border-default);margin-block:.25rem}.kj-command-palette__footer{display:flex;gap:var(--kj-space-xl, 1.5rem);padding:var(--kj-space-sm, .375rem) var(--kj-space-lg, 1.25rem);border-top:1px solid var(--kj-border-default);background:var(--kj-bg-surface)}.kj-command-palette__footer span{display:flex;align-items:center;gap:.4rem;font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted)}.kj-command-palette__footer kbd{background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.6rem;padding:.1rem .35rem}@media(prefers-reduced-motion:reduce){.kj-command-item{transition:none}}\n"] }]
|
|
17523
20029
|
}], propDecorators: { kjValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjValue", required: false }] }], kjKeywords: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjKeywords", required: false }] }], kjShortcut: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjShortcut", required: false }] }], kjDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjDisabled", required: false }] }] } });
|
|
17524
20030
|
/**
|
|
17525
20031
|
* Styled command group. Auto-hides when all child items are filtered out.
|
|
@@ -17538,7 +20044,7 @@ class KjCommandGroupComponent {
|
|
|
17538
20044
|
<div class="kj-command-group__label">{{ kjLabel() }}</div>
|
|
17539
20045
|
}
|
|
17540
20046
|
<ng-content />
|
|
17541
|
-
`, isInline: true, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-
|
|
20047
|
+
`, isInline: true, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-inline-start:2px solid transparent;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);text-align:start;cursor:pointer;transition:background .1s}.kj-command-item:hover,.kj-command-item[data-active]{background:var(--kj-bg-surface);border-inline-start-color:var(--kj-bg-primary)}.kj-command-item[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-command-group{padding-block:.25rem}.kj-command-group__label{padding:.375rem var(--kj-space-lg, 1.25rem) .125rem;font-family:var(--kj-font-mono);font-size:.6rem;font-weight:600;color:var(--kj-fg-muted);letter-spacing:.1em;text-transform:uppercase}.kj-command-separator{height:1px;background:var(--kj-border-default);margin-block:.25rem}.kj-command-palette__footer{display:flex;gap:var(--kj-space-xl, 1.5rem);padding:var(--kj-space-sm, .375rem) var(--kj-space-lg, 1.25rem);border-top:1px solid var(--kj-border-default);background:var(--kj-bg-surface)}.kj-command-palette__footer span{display:flex;align-items:center;gap:.4rem;font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted)}.kj-command-palette__footer kbd{background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.6rem;padding:.1rem .35rem}@media(prefers-reduced-motion:reduce){.kj-command-item{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
17542
20048
|
}
|
|
17543
20049
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjCommandGroupComponent, decorators: [{
|
|
17544
20050
|
type: Component,
|
|
@@ -17547,7 +20053,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
17547
20053
|
<div class="kj-command-group__label">{{ kjLabel() }}</div>
|
|
17548
20054
|
}
|
|
17549
20055
|
<ng-content />
|
|
17550
|
-
`, encapsulation: ViewEncapsulation.None, host: { class: 'kj-command-group' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-
|
|
20056
|
+
`, encapsulation: ViewEncapsulation.None, host: { class: 'kj-command-group' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-inline-start:2px solid transparent;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);text-align:start;cursor:pointer;transition:background .1s}.kj-command-item:hover,.kj-command-item[data-active]{background:var(--kj-bg-surface);border-inline-start-color:var(--kj-bg-primary)}.kj-command-item[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-command-group{padding-block:.25rem}.kj-command-group__label{padding:.375rem var(--kj-space-lg, 1.25rem) .125rem;font-family:var(--kj-font-mono);font-size:.6rem;font-weight:600;color:var(--kj-fg-muted);letter-spacing:.1em;text-transform:uppercase}.kj-command-separator{height:1px;background:var(--kj-border-default);margin-block:.25rem}.kj-command-palette__footer{display:flex;gap:var(--kj-space-xl, 1.5rem);padding:var(--kj-space-sm, .375rem) var(--kj-space-lg, 1.25rem);border-top:1px solid var(--kj-border-default);background:var(--kj-bg-surface)}.kj-command-palette__footer span{display:flex;align-items:center;gap:.4rem;font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted)}.kj-command-palette__footer kbd{background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.6rem;padding:.1rem .35rem}@media(prefers-reduced-motion:reduce){.kj-command-item{transition:none}}\n"] }]
|
|
17551
20057
|
}], propDecorators: { kjLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjLabel", required: false }] }] } });
|
|
17552
20058
|
/**
|
|
17553
20059
|
* Styled command input wrapper. Renders an `<input type="search">` with
|
|
@@ -17570,7 +20076,7 @@ class KjCommandInputComponent {
|
|
|
17570
20076
|
class="kj-command-input"
|
|
17571
20077
|
[placeholder]="kjPlaceholder()"
|
|
17572
20078
|
/>
|
|
17573
|
-
`, isInline: true, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-
|
|
20079
|
+
`, isInline: true, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-inline-start:2px solid transparent;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);text-align:start;cursor:pointer;transition:background .1s}.kj-command-item:hover,.kj-command-item[data-active]{background:var(--kj-bg-surface);border-inline-start-color:var(--kj-bg-primary)}.kj-command-item[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-command-group{padding-block:.25rem}.kj-command-group__label{padding:.375rem var(--kj-space-lg, 1.25rem) .125rem;font-family:var(--kj-font-mono);font-size:.6rem;font-weight:600;color:var(--kj-fg-muted);letter-spacing:.1em;text-transform:uppercase}.kj-command-separator{height:1px;background:var(--kj-border-default);margin-block:.25rem}.kj-command-palette__footer{display:flex;gap:var(--kj-space-xl, 1.5rem);padding:var(--kj-space-sm, .375rem) var(--kj-space-lg, 1.25rem);border-top:1px solid var(--kj-border-default);background:var(--kj-bg-surface)}.kj-command-palette__footer span{display:flex;align-items:center;gap:.4rem;font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted)}.kj-command-palette__footer kbd{background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.6rem;padding:.1rem .35rem}@media(prefers-reduced-motion:reduce){.kj-command-item{transition:none}}\n"], dependencies: [{ kind: "directive", type: KjCommandInput, selector: "input[kjCommandInput]", exportAs: ["kjCommandInput"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
17574
20080
|
}
|
|
17575
20081
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjCommandInputComponent, decorators: [{
|
|
17576
20082
|
type: Component,
|
|
@@ -17581,7 +20087,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
17581
20087
|
class="kj-command-input"
|
|
17582
20088
|
[placeholder]="kjPlaceholder()"
|
|
17583
20089
|
/>
|
|
17584
|
-
`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-
|
|
20090
|
+
`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-inline-start:2px solid transparent;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);text-align:start;cursor:pointer;transition:background .1s}.kj-command-item:hover,.kj-command-item[data-active]{background:var(--kj-bg-surface);border-inline-start-color:var(--kj-bg-primary)}.kj-command-item[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-command-group{padding-block:.25rem}.kj-command-group__label{padding:.375rem var(--kj-space-lg, 1.25rem) .125rem;font-family:var(--kj-font-mono);font-size:.6rem;font-weight:600;color:var(--kj-fg-muted);letter-spacing:.1em;text-transform:uppercase}.kj-command-separator{height:1px;background:var(--kj-border-default);margin-block:.25rem}.kj-command-palette__footer{display:flex;gap:var(--kj-space-xl, 1.5rem);padding:var(--kj-space-sm, .375rem) var(--kj-space-lg, 1.25rem);border-top:1px solid var(--kj-border-default);background:var(--kj-bg-surface)}.kj-command-palette__footer span{display:flex;align-items:center;gap:.4rem;font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted)}.kj-command-palette__footer kbd{background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.6rem;padding:.1rem .35rem}@media(prefers-reduced-motion:reduce){.kj-command-item{transition:none}}\n"] }]
|
|
17585
20091
|
}], propDecorators: { kjPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjPlaceholder", required: false }] }] } });
|
|
17586
20092
|
/**
|
|
17587
20093
|
* Styled separator between command groups.
|
|
@@ -17592,11 +20098,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
17592
20098
|
*/
|
|
17593
20099
|
class KjCommandSeparatorComponent {
|
|
17594
20100
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjCommandSeparatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
17595
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: KjCommandSeparatorComponent, isStandalone: true, selector: "kj-command-separator", host: { classAttribute: "kj-command-separator" }, hostDirectives: [{ directive: i1.KjCommandSeparator }], ngImport: i0, template: ``, isInline: true, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-
|
|
20101
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: KjCommandSeparatorComponent, isStandalone: true, selector: "kj-command-separator", host: { classAttribute: "kj-command-separator" }, hostDirectives: [{ directive: i1.KjCommandSeparator }], ngImport: i0, template: ``, isInline: true, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-inline-start:2px solid transparent;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);text-align:start;cursor:pointer;transition:background .1s}.kj-command-item:hover,.kj-command-item[data-active]{background:var(--kj-bg-surface);border-inline-start-color:var(--kj-bg-primary)}.kj-command-item[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-command-group{padding-block:.25rem}.kj-command-group__label{padding:.375rem var(--kj-space-lg, 1.25rem) .125rem;font-family:var(--kj-font-mono);font-size:.6rem;font-weight:600;color:var(--kj-fg-muted);letter-spacing:.1em;text-transform:uppercase}.kj-command-separator{height:1px;background:var(--kj-border-default);margin-block:.25rem}.kj-command-palette__footer{display:flex;gap:var(--kj-space-xl, 1.5rem);padding:var(--kj-space-sm, .375rem) var(--kj-space-lg, 1.25rem);border-top:1px solid var(--kj-border-default);background:var(--kj-bg-surface)}.kj-command-palette__footer span{display:flex;align-items:center;gap:.4rem;font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted)}.kj-command-palette__footer kbd{background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.6rem;padding:.1rem .35rem}@media(prefers-reduced-motion:reduce){.kj-command-item{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
17596
20102
|
}
|
|
17597
20103
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjCommandSeparatorComponent, decorators: [{
|
|
17598
20104
|
type: Component,
|
|
17599
|
-
args: [{ selector: 'kj-command-separator', standalone: true, hostDirectives: [KjCommandSeparator], template: ``, encapsulation: ViewEncapsulation.None, host: { class: 'kj-command-separator' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-
|
|
20105
|
+
args: [{ selector: 'kj-command-separator', standalone: true, hostDirectives: [KjCommandSeparator], template: ``, encapsulation: ViewEncapsulation.None, host: { class: 'kj-command-separator' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-inline-start:2px solid transparent;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);text-align:start;cursor:pointer;transition:background .1s}.kj-command-item:hover,.kj-command-item[data-active]{background:var(--kj-bg-surface);border-inline-start-color:var(--kj-bg-primary)}.kj-command-item[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-command-group{padding-block:.25rem}.kj-command-group__label{padding:.375rem var(--kj-space-lg, 1.25rem) .125rem;font-family:var(--kj-font-mono);font-size:.6rem;font-weight:600;color:var(--kj-fg-muted);letter-spacing:.1em;text-transform:uppercase}.kj-command-separator{height:1px;background:var(--kj-border-default);margin-block:.25rem}.kj-command-palette__footer{display:flex;gap:var(--kj-space-xl, 1.5rem);padding:var(--kj-space-sm, .375rem) var(--kj-space-lg, 1.25rem);border-top:1px solid var(--kj-border-default);background:var(--kj-bg-surface)}.kj-command-palette__footer span{display:flex;align-items:center;gap:.4rem;font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted)}.kj-command-palette__footer kbd{background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.6rem;padding:.1rem .35rem}@media(prefers-reduced-motion:reduce){.kj-command-item{transition:none}}\n"] }]
|
|
17600
20106
|
}] });
|
|
17601
20107
|
/**
|
|
17602
20108
|
* Styled empty state slot. Shown when no items match the current query.
|
|
@@ -17607,11 +20113,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
17607
20113
|
*/
|
|
17608
20114
|
class KjCommandEmptyComponent {
|
|
17609
20115
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjCommandEmptyComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
17610
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: KjCommandEmptyComponent, isStandalone: true, selector: "kj-command-empty", host: { classAttribute: "kj-command-empty" }, hostDirectives: [{ directive: i1.KjCommandEmpty }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-
|
|
20116
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.5", type: KjCommandEmptyComponent, isStandalone: true, selector: "kj-command-empty", host: { classAttribute: "kj-command-empty" }, hostDirectives: [{ directive: i1.KjCommandEmpty }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-inline-start:2px solid transparent;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);text-align:start;cursor:pointer;transition:background .1s}.kj-command-item:hover,.kj-command-item[data-active]{background:var(--kj-bg-surface);border-inline-start-color:var(--kj-bg-primary)}.kj-command-item[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-command-group{padding-block:.25rem}.kj-command-group__label{padding:.375rem var(--kj-space-lg, 1.25rem) .125rem;font-family:var(--kj-font-mono);font-size:.6rem;font-weight:600;color:var(--kj-fg-muted);letter-spacing:.1em;text-transform:uppercase}.kj-command-separator{height:1px;background:var(--kj-border-default);margin-block:.25rem}.kj-command-palette__footer{display:flex;gap:var(--kj-space-xl, 1.5rem);padding:var(--kj-space-sm, .375rem) var(--kj-space-lg, 1.25rem);border-top:1px solid var(--kj-border-default);background:var(--kj-bg-surface)}.kj-command-palette__footer span{display:flex;align-items:center;gap:.4rem;font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted)}.kj-command-palette__footer kbd{background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.6rem;padding:.1rem .35rem}@media(prefers-reduced-motion:reduce){.kj-command-item{transition:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
17611
20117
|
}
|
|
17612
20118
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjCommandEmptyComponent, decorators: [{
|
|
17613
20119
|
type: Component,
|
|
17614
|
-
args: [{ selector: 'kj-command-empty', standalone: true, hostDirectives: [KjCommandEmpty], template: `<ng-content />`, encapsulation: ViewEncapsulation.None, host: { class: 'kj-command-empty' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-
|
|
20120
|
+
args: [{ selector: 'kj-command-empty', standalone: true, hostDirectives: [KjCommandEmpty], template: `<ng-content />`, encapsulation: ViewEncapsulation.None, host: { class: 'kj-command-empty' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".kj-command-palette__shell{display:none}.kj-command-palette__shell.is-open{display:contents}.kj-command-palette__backdrop{position:fixed;inset:0;background:#000000b3;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:1000;animation:kj-command-palette-fade .1s ease-out}.kj-command-palette__dialog{position:fixed;top:15vh;left:50%;transform:translate(-50%);width:min(640px,92vw);display:flex;flex-direction:column;background:var(--kj-bg-elevated);border:1px solid var(--kj-border-default);z-index:1001;overflow:hidden;animation:kj-command-palette-slide .15s ease-out}@keyframes kj-command-palette-fade{0%{opacity:0}to{opacity:1}}@keyframes kj-command-palette-slide{0%{opacity:0;transform:translate(-50%) translateY(-8px)}to{opacity:1;transform:translate(-50%) translateY(0)}}@media(prefers-reduced-motion:reduce){.kj-command-palette__backdrop,.kj-command-palette__dialog{animation:none}}.kj-command-palette__input-wrapper{display:flex;align-items:center;padding:.875rem var(--kj-space-lg, 1.25rem);border-bottom:1px solid var(--kj-border-default);gap:var(--kj-space-md, .75rem)}.kj-command-palette__search-icon{flex-shrink:0;width:1rem;height:1rem;color:var(--kj-fg-muted)}.kj-command-palette__input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none}.kj-command-palette__input::placeholder{color:var(--kj-fg-muted)}.kj-command-palette__input::-webkit-search-cancel-button{display:none}.kj-command-input{flex:1;border:none;outline:none;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);appearance:none;-webkit-appearance:none;width:100%;padding:.875rem var(--kj-space-lg, 1.25rem)}.kj-command-palette__esc-kbd{font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted);background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);padding:.15rem .4rem;flex-shrink:0;cursor:pointer}.kj-command-palette__esc-kbd:hover{color:var(--kj-fg-default)}.kj-command-palette__list{overflow-y:auto;max-height:22rem;padding:var(--kj-space-sm, .375rem) 0}.kj-command-palette__empty,.kj-command-empty{padding:var(--kj-space-xl, 1.5rem) var(--kj-space-lg, 1.25rem);text-align:center;font-family:var(--kj-font-mono);font-size:.8rem;color:var(--kj-fg-muted)}.kj-command-item{display:flex;flex-direction:var(--kj-command-item-direction, row);align-items:var(--kj-command-item-align, center);gap:var(--kj-command-item-gap, var(--kj-space-md, .75rem));width:100%;min-height:2.75rem;padding:.625rem var(--kj-space-lg, 1.25rem);border:none;border-inline-start:2px solid transparent;background:transparent;font-family:var(--kj-font-mono);font-size:.875rem;color:var(--kj-fg-default);text-align:start;cursor:pointer;transition:background .1s}.kj-command-item:hover,.kj-command-item[data-active]{background:var(--kj-bg-surface);border-inline-start-color:var(--kj-bg-primary)}.kj-command-item[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-command-group{padding-block:.25rem}.kj-command-group__label{padding:.375rem var(--kj-space-lg, 1.25rem) .125rem;font-family:var(--kj-font-mono);font-size:.6rem;font-weight:600;color:var(--kj-fg-muted);letter-spacing:.1em;text-transform:uppercase}.kj-command-separator{height:1px;background:var(--kj-border-default);margin-block:.25rem}.kj-command-palette__footer{display:flex;gap:var(--kj-space-xl, 1.5rem);padding:var(--kj-space-sm, .375rem) var(--kj-space-lg, 1.25rem);border-top:1px solid var(--kj-border-default);background:var(--kj-bg-surface)}.kj-command-palette__footer span{display:flex;align-items:center;gap:.4rem;font-family:var(--kj-font-mono);font-size:.65rem;color:var(--kj-fg-muted)}.kj-command-palette__footer kbd{background:var(--kj-bg-surface);border:1px solid var(--kj-border-default);color:var(--kj-fg-muted);font-family:var(--kj-font-mono);font-size:.6rem;padding:.1rem .35rem}@media(prefers-reduced-motion:reduce){.kj-command-item{transition:none}}\n"] }]
|
|
17615
20121
|
}] });
|
|
17616
20122
|
|
|
17617
20123
|
/** Walk the tree into a flat array. All nodes are included; visibility is
|
|
@@ -18000,5 +20506,5 @@ const KJ_COMPONENTS_VERSION = '0.0.1';
|
|
|
18000
20506
|
* Generated bundle index. Do not edit.
|
|
18001
20507
|
*/
|
|
18002
20508
|
|
|
18003
|
-
export { KJ_COMPONENTS_VERSION, KJ_EDITOR_CONTRACT, KJ_FILTER_CONTEXT, KjAccordionComponent, KjAccordionContentComponent, KjAccordionItemComponent, KjAccordionTriggerComponent, KjAlertActionsComponent, KjAlertComponent, KjAlertDescriptionComponent, KjAlertDismissComponent, KjAlertIconComponent, KjAlertTitleComponent, KjAvatarComponent, KjAvatarGroupComponent, KjBadgeComponent, KjBooleanEditor, KjBreadcrumbComponent, KjBreadcrumbCurrentComponent, KjBreadcrumbEllipsisComponent, KjBreadcrumbItemComponent, KjBreadcrumbLinkComponent, KjBreadcrumbListComponent, KjBreadcrumbSeparatorComponent, KjBulkAction, KjButtonComponent, KjButtonGroupComponent, KjCalendarComponent, KjCardComponent, KjCardContentComponent, KjCardCoverComponent, KjCardFooterComponent, KjCardHeaderComponent, KjCardSubtitleComponent, KjCardTitleComponent, KjCarouselAutoplayComponent, KjCarouselComponent, KjCarouselIndicatorsComponent, KjCarouselNextComponent, KjCarouselPauseComponent, KjCarouselPreviousComponent, KjCarouselSlideComponent, KjCarouselViewportComponent, KjCascadeOptionComponent, KjCascadeSelectComponent, KjCascadeSubPanelComponent, KjCellEditorOutlet, KjCellTemplateDirective, KjChatAvatarComponent, KjChatBubbleComponent, KjChatComponent, KjChatFooterComponent, KjChatHeaderComponent, KjChatLogComponent, KjCheckboxComponent, KjColorPickerComponent, KjComboboxComponent, KjComboboxEmptyComponent, KjComboboxLoadingComponent, KjComboboxOptionComponent, KjCommandEmptyComponent, KjCommandGroupComponent, KjCommandInputComponent, KjCommandItemComponent, KjCommandPaletteComponent, KjCommandPaletteFooter, KjCommandPaletteItemTemplate, KjCommandSeparatorComponent, KjConfirmPopupActionComponent, KjConfirmPopupActionsComponent, KjConfirmPopupCancelComponent, KjConfirmPopupComponent, KjConfirmPopupContentComponent, KjConfirmPopupMessageComponent, KjConfirmPopupTriggerComponent, KjDateEditor, KjDateFilter, KjDatePickerComponent, KjDatetimePickerComponent, KjDialogComponent, KjDividerComponent, KjDrawerComponent, KjDropdownMenuComponent, KjEmptyStateActionsComponent, KjEmptyStateComponent, KjEmptyStateDescriptionComponent, KjEmptyStateIconComponent, KjEmptyStateTitleComponent, KjFieldComponent, KjFieldErrorComponent, KjFieldGroupComponent, KjFieldHelpComponent, KjFieldLabelComponent, KjFileUploadComponent, KjFilterCellOutlet, KjFormActionsComponent, KjFormComponent, KjFormSummaryComponent, KjIconGalleryExample, KjIconUsageExample, KjInputComponent, KjInputGroupAddonComponent, KjInputGroupComponent, KjInputMaskComponent, KjInputMaskCreditCardExample, KjInputMaskCustomTokensExample, KjInputMaskDateExample, KjInputMaskExample, KjInputMaskUsageExample, KjInputMaskValidationExample, KjInputOtpComponent, KjKbdComponent, KjLinkComponent, KjListComponent, KjListItemComponent, KjMenubarComponent, KjMenubarItemComponent, KjNumberEditor, KjNumberFilter, KjNumberInputComponent, KjOptionComponent, KjOverlayBadgeComponent, KjOverlayBadgeContentComponent, KjPaginationComponent, KjPaginationDefaultComponent, KjPaginationEllipsisComponent, KjPaginationFirstComponent, KjPaginationInfoComponent, KjPaginationItemComponent, KjPaginationLastComponent, KjPaginationNextComponent, KjPaginationPreviousComponent, KjPasswordInputComponent, KjPopoverComponent, KjProgressBarComponent, KjRadioComponent, KjRadioGroupComponent, KjSelectComponent, KjSelectEditor, KjSelectFilter, KjSkeletonComponent, KjSliderComponent, KjSpeedDialActionComponent, KjSpeedDialActionsComponent, KjSpeedDialComponent, KjSpeedDialTriggerComponent, KjSpinnerComponent, KjStepComponent, KjStepContentComponent, KjStepLabelComponent, KjStepperComponent, KjStepperNextComponent, KjStepperPreviousComponent, KjStepperResetComponent, KjTabComponent, KjTabListComponent, KjTabPanelComponent, KjTableComponent, KjTablePaginationComponent, KjTableSidePanelComponent, KjTableSidePanelContent, KjTableStatusBarComponent, KjTableToolbarComponent, KjTableVirtual, KjTabsComponent, KjTagComponent, KjTagListComponent, KjTagRemoveComponent, KjTextEditor, KjTextFilter, KjTextareaComponent, KjTimePickerComponent, KjToastCloseComponent, KjToastComponent, KjToastViewportComponent, KjToastWrapperComponent, KjToggleComponent, KjTooltipComponent, KjTreeSelectComponent, KjTreeSelectNodeComponent, LUCIDE_ICON_NAMES, copyToClipboard, downloadString, exportCsv, exportJson, provideLucideIcons, toTsv };
|
|
20509
|
+
export { KJ_COMPONENTS_VERSION, KJ_EDITOR_CONTRACT, KJ_FILTER_CONTEXT, KjAccordionComponent, KjAccordionContentComponent, KjAccordionItemComponent, KjAccordionTriggerComponent, KjActionSheet, KjActionSheetComponent, KjActionSheetRef, KjActionSheetService, KjAlertActionsComponent, KjAlertComponent, KjAlertDescriptionComponent, KjAlertDismissComponent, KjAlertIconComponent, KjAlertTitleComponent, KjAvatarComponent, KjAvatarGroupComponent, KjBadgeComponent, KjBooleanEditor, KjBreadcrumbComponent, KjBreadcrumbCurrentComponent, KjBreadcrumbEllipsisComponent, KjBreadcrumbItemComponent, KjBreadcrumbLinkComponent, KjBreadcrumbListComponent, KjBreadcrumbSeparatorComponent, KjBulkAction, KjButtonComponent, KjButtonGroupComponent, KjCalendarComponent, KjCardComponent, KjCardContentComponent, KjCardCoverComponent, KjCardFooterComponent, KjCardHeaderComponent, KjCardSubtitleComponent, KjCardTitleComponent, KjCarouselAutoplayComponent, KjCarouselComponent, KjCarouselIndicatorsComponent, KjCarouselNextComponent, KjCarouselPauseComponent, KjCarouselPreviousComponent, KjCarouselSlideComponent, KjCarouselViewportComponent, KjCascadeOptionComponent, KjCascadeSelectComponent, KjCascadeSubPanelComponent, KjCellEditorOutlet, KjCellTemplateDirective, KjChartComponent, KjChatAvatarComponent, KjChatBubbleComponent, KjChatComponent, KjChatFooterComponent, KjChatHeaderComponent, KjChatLogComponent, KjChatMessage, KjChatThread, KjCheckboxComponent, KjColorPickerComponent, KjComboboxComponent, KjComboboxEmptyComponent, KjComboboxLoadingComponent, KjComboboxOptionComponent, KjCommandEmptyComponent, KjCommandGroupComponent, KjCommandInputComponent, KjCommandItemComponent, KjCommandPaletteComponent, KjCommandPaletteFooter, KjCommandPaletteItemTemplate, KjCommandSeparatorComponent, KjConfirmPopupActionComponent, KjConfirmPopupActionsComponent, KjConfirmPopupCancelComponent, KjConfirmPopupComponent, KjConfirmPopupContentComponent, KjConfirmPopupMessageComponent, KjConfirmPopupTriggerComponent, KjDateEditor, KjDateFilter, KjDatePickerComponent, KjDateRangePresetsComponent, KjDatetimePickerComponent, KjDialogComponent, KjDirectionToggle, KjDividerComponent, KjDrawerComponent, KjDropdownMenuComponent, KjEditorComponent, KjEmptyStateActionsComponent, KjEmptyStateComponent, KjEmptyStateDescriptionComponent, KjEmptyStateIconComponent, KjEmptyStateTitleComponent, KjFieldComponent, KjFieldErrorComponent, KjFieldGroupComponent, KjFieldHelpComponent, KjFieldLabelComponent, KjFileUploadComponent, KjFilterCellOutlet, KjFormActionsComponent, KjFormComponent, KjFormSummaryComponent, KjIconGalleryExample, KjIconUsageExample, KjInputComponent, KjInputGroupAddonComponent, KjInputGroupComponent, KjInputMaskComponent, KjInputMaskCreditCardExample, KjInputMaskCustomTokensExample, KjInputMaskDateExample, KjInputMaskExample, KjInputMaskUsageExample, KjInputMaskValidationExample, KjInputOtpComponent, KjKbdComponent, KjLinkComponent, KjListComponent, KjListItemComponent, KjMenubarComponent, KjMenubarItemComponent, KjNumberEditor, KjNumberFilter, KjNumberInputComponent, KjOptionComponent, KjOverlayBadgeComponent, KjOverlayBadgeContentComponent, KjPaginationComponent, KjPaginationDefaultComponent, KjPaginationEllipsisComponent, KjPaginationFirstComponent, KjPaginationInfoComponent, KjPaginationItemComponent, KjPaginationLastComponent, KjPaginationNextComponent, KjPaginationPreviousComponent, KjPasswordInputComponent, KjPopoverComponent, KjProgressBarComponent, KjPromptInput, KjRadioComponent, KjRadioGroupComponent, KjRichTextEditorComponent, KjSelectComponent, KjSelectEditor, KjSelectFilter, KjSheetComponent, KjSkeletonComponent, KjSkipLinkComponent, KjSliderComponent, KjSpeedDialActionComponent, KjSpeedDialActionsComponent, KjSpeedDialComponent, KjSpeedDialTriggerComponent, KjSpinnerComponent, KjStepComponent, KjStepContentComponent, KjStepLabelComponent, KjStepperComponent, KjStepperNextComponent, KjStepperPreviousComponent, KjStepperResetComponent, KjTabComponent, KjTabListComponent, KjTabPanelComponent, KjTableComponent, KjTablePaginationComponent, KjTableSidePanelComponent, KjTableSidePanelContent, KjTableStatusBarComponent, KjTableToolbarComponent, KjTableVirtual, KjTabsComponent, KjTagComponent, KjTagListComponent, KjTagRemoveComponent, KjTextEditor, KjTextFilter, KjTextareaComponent, KjTimePickerComponent, KjToastCloseComponent, KjToastComponent, KjToastViewportComponent, KjToastWrapperComponent, KjToggleComponent, KjTooltipComponent, KjTreeSelectComponent, KjTreeSelectNodeComponent, LUCIDE_ICON_NAMES, bold, bulletList, codeBlock, copyToClipboard, defaultFeatures, downloadString, exportCsv, exportJson, heading, history, image, inlineCode, italic, link, markdownShortcuts, orderedList, provideLucideIcons, quote, renderMarkdown, strike, toTsv, underline };
|
|
18004
20510
|
//# sourceMappingURL=kouji-ui-components.mjs.map
|