@kouji-ui/components 0.8.0 → 0.9.1
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.
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { ChangeDetectionStrategy, ViewEncapsulation, Component, input, inject, Injectable, booleanAttribute, computed, TemplateRef, viewChild, ElementRef, contentChildren, contentChild, model, ViewChild, PLATFORM_ID, DestroyRef, afterNextRender, effect, signal, Injector, untracked, output, EventEmitter, Output, makeEnvironmentProviders, provideEnvironmentInitializer, forwardRef, EnvironmentInjector, Directive, InjectionToken, ViewContainerRef, numberAttribute } from '@angular/core';
|
|
2
|
+
import { ChangeDetectionStrategy, ViewEncapsulation, Component, input, inject, Injectable, booleanAttribute, computed, TemplateRef, viewChild, ElementRef, contentChildren, contentChild, model, ViewChild, PLATFORM_ID, DestroyRef, afterNextRender, effect, signal, SecurityContext, Injector, untracked, output, EventEmitter, Output, makeEnvironmentProviders, provideEnvironmentInitializer, forwardRef, EnvironmentInjector, Directive, InjectionToken, ViewContainerRef, numberAttribute } from '@angular/core';
|
|
3
3
|
import * as i1 from '@kouji-ui/core';
|
|
4
|
-
import { KjAccordion, KjAccordionTrigger, KjAccordionItem, KjAccordionContent, SHEET_DATA, KjSheetRef, KjSheet, KjIconDirective, KjSheetService, KjAlert, KjAlertIcon, KjAlertTitle, KjAlertDescription, KjAlertActions, KjAlertDismiss, KJ_AVATAR_GROUP, KjAvatarImage, KjAvatarFallback, KjAvatar, KjPopoverTrigger, KjPopoverContent, KjPopoverArrow, KjPopoverClose, KjPopoverTitle, KjTranslateService, KjOverflowContent, KjAvatarGroup, KjBadge, KjBreadcrumb, KjSize, KjBreadcrumbList, KjBreadcrumbItem, KJ_BREADCRUMB_CONFIG, 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, KjConfirmPopupContent, KjConfirmPopupMessage, KjConfirmPopupAction, KjConfirmPopupCancel, KjDatePicker, KjDatePickerTrigger, KjDatePickerCalendar, defaultDateRangePresets, KjDateRangePresets, KjDateRangePresetOption, KjLocale, KjDropdownMenuTrigger, KjDropdownMenuContent, KjDropdownMenuItem, KjDropdownMenuSeparator, KjDropdownMenuLabel, KjDropdownMenuGroup, KjSpinner, KjVariant, KjEditorLoader, KjEditor, KJ_SIZE_PRESET, 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, 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, bindPresets, KJ_TABS_CONFIG, 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';
|
|
4
|
+
import { KjAccordion, KjAccordionTrigger, KjAccordionItem, KjAccordionContent, SHEET_DATA, KjSheetRef, KjSheet, KjIconDirective, KjSheetService, KjAlert, KjAlertIcon, KjAlertTitle, KjAlertDescription, KjAlertActions, KjAlertDismiss, KJ_AVATAR_GROUP, KjAvatarImage, KjAvatarFallback, KjAvatar, KjPopoverTrigger, KjPopoverContent, KjPopoverArrow, KjPopoverClose, KjPopoverTitle, KjTranslateService, KjOverflowContent, KjAvatarGroup, KjBadge, KjBreadcrumb, KjSize, KjBreadcrumbList, KjBreadcrumbItem, KJ_BREADCRUMB_CONFIG, 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, KJ_CHAT_CONFIG, parseSlash, matchSlashCommands, KjCheckbox, KjColorPicker, KjColorPickerTrigger, KjColorPickerPanel, KjColorPickerArea, KjColorPickerHueSlider, KjColorPickerAlphaSlider, KjColorPickerInput, KjComboboxInput, KjComboboxListbox, KjCombobox, KjComboboxOption, KjConfirmPopup, KjConfirmPopupTrigger, KjConfirmPopupContent, KjConfirmPopupMessage, KjConfirmPopupAction, KjConfirmPopupCancel, KjDatePicker, KjDatePickerTrigger, KjDatePickerCalendar, defaultDateRangePresets, KjDateRangePresets, KjDateRangePresetOption, KjLocale, KjDropdownMenuTrigger, KjDropdownMenuContent, KjDropdownMenuItem, KjDropdownMenuSeparator, KjDropdownMenuLabel, KjDropdownMenuGroup, KjSpinner, KjVariant, KjEditorLoader, KjEditor, KJ_SIZE_PRESET, 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, 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, bindPresets, KJ_TABS_CONFIG, 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
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
6
|
import { NgTemplateOutlet, isPlatformBrowser, NgComponentOutlet } from '@angular/common';
|
|
7
7
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
8
|
+
import { marked } from 'marked';
|
|
8
9
|
import * as i1$1 from '@angular/forms';
|
|
9
10
|
import { NG_VALUE_ACCESSOR, FormsModule, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
10
11
|
import * as lucideIcons from 'lucide-static';
|
|
@@ -1781,7 +1782,7 @@ class KjButtonComponent {
|
|
|
1781
1782
|
<ng-content />
|
|
1782
1783
|
}
|
|
1783
1784
|
</button>
|
|
1784
|
-
`, isInline: true, styles: ["@layer kj.component{.kj-button{display:inline-flex;align-items:center;justify-content:var(--kj-button-justify, center);gap:var(--kj-button-gap, var(--kj-space-sm));min-width:var(--kj-button-min-width, auto);height:var(--kj-button-height, auto);align-self:center;background:var(--kj-button-bg, var(--kj-bg-primary));color:var(--kj-button-fg, var(--kj-fg-on-primary));border:var(--kj-button-border-width, var(--kj-border)) var(--kj-button-border-style, solid) var(--kj-button-border-color, transparent);border-radius:var(--kj-button-radius, var(--kj-radius-field));padding:var(--kj-button-padding-y, var(--kj-space-sm)) var(--kj-button-padding-x, var(--kj-space-md));font:var(--kj-button-font-weight, 600) var(--kj-button-font-size, var(--kj-text-sm)) / 1.2 var(--kj-button-font, var(--kj-font-sans));letter-spacing:var(--kj-button-letter-spacing, -.01em);transition:color var(--kj-transition),border-color var(--kj-transition),box-shadow var(--kj-transition),transform var(--kj-transition),opacity var(--kj-transition);cursor:pointer;text-decoration:none}.kj-button[data-variant=destructive]{--kj-button-bg: var(--kj-bg-danger);--kj-button-fg: var(--kj-fg-on-danger)}.kj-button[data-variant=destructive]:hover{--kj-button-bg: color-mix(in oklch, var(--kj-bg-danger), black 8%)}.kj-button[data-variant=ghost]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-default);--kj-button-border-color: transparent}.kj-button[data-variant=ghost]:hover{--kj-button-bg: color-mix(in oklab, var(--kj-fg-default) 10%, transparent)}.kj-button[data-variant=outline]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-default);--kj-button-border-color: var(--kj-border-default)}.kj-button[data-variant=outline]:hover{--kj-button-bg: var(--kj-bg-surface)}.kj-button[data-variant=link]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-primary);--kj-button-padding-x: 0;--kj-button-padding-y: 0;--kj-button-shadow: none;--kj-button-shadow-hover: none;--kj-button-shadow-active: none;text-decoration:underline;text-underline-offset:4px}.kj-button[data-variant=link]:hover{--kj-button-bg: transparent;--kj-button-fg: color-mix(in oklch, var(--kj-fg-primary), black 8%)}.kj-button[data-size=xs]{--kj-button-padding-x: var(--kj-space-sm);--kj-button-padding-y: 0;--kj-button-font-size: .75rem;--kj-button-height: var(--kj-ctl-h-xs)}.kj-button[data-size=sm]{--kj-button-padding-x: var(--kj-space-sm);--kj-button-padding-y: .25rem;--kj-button-font-size: .8125rem;--kj-button-height: var(--kj-ctl-h-sm)}.kj-button[data-size=md]{--kj-button-height: var(--kj-ctl-h-md)}.kj-button[data-size=lg]{--kj-button-padding-x: var(--kj-space-lg);--kj-button-padding-y: .625rem;--kj-button-font-size: 1rem;--kj-button-height: var(--kj-ctl-h-lg)}.kj-button[data-size=xl]{--kj-button-padding-x: var(--kj-space-2xl);--kj-button-padding-y: .875rem;--kj-button-font-size: 1.0625rem;--kj-button-gap: var(--kj-space-md);--kj-button-height: var(--kj-ctl-h-xl)}.kj-button[data-size=icon]{--kj-button-padding-x: var(--kj-space-sm);--kj-button-padding-y: var(--kj-space-sm);--kj-button-height: var(--kj-ctl-h-md);aspect-ratio:1}.kj-button[data-full=true]{width:100%}.kj-button:hover{--kj-button-bg: var(--kj-button-bg-hover, color-mix(in oklch, var(--kj-bg-primary), black 8%));transform:translateY(var(--kj-button-hover-translate, var(--kj-hover-translate, -2px)))}.kj-button[data-variant=default]:hover{--kj-button-fg: var(--kj-button-fg-hover, var(--kj-fg-on-primary))}.kj-button[data-variant=default]{box-shadow:var(--kj-button-shadow, none)}.kj-button[data-variant=default]:hover{box-shadow:var(--kj-button-shadow-hover, var(--kj-button-shadow, none))}.kj-button[data-variant=default]:active{box-shadow:var(--kj-button-shadow-active, var(--kj-button-shadow, none))}.kj-button:active{transform:var(--kj-button-translate-active, none)}.kj-button:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-button[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-button[data-size=icon]{min-width:2.75rem;min-height:2.75rem}.kj-button[aria-busy=true]{opacity:.7;cursor:progress}.kj-button[aria-pressed=true]{--kj-button-bg: var(--kj-bg-field);box-shadow:inset 0 1px 2px #0000001f}.kj-button__spinner{display:inline-block;width:1em;height:1em;vertical-align:-.125em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:kj-button-spinner-rotate .6s linear infinite}}@keyframes kj-button-spinner-rotate{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: KjButton, selector: "[kjButton]", inputs: ["kjDisabled", "kjLoading", "kjFullWidth", "kjPressed"], outputs: ["kjPressedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1785
|
+
`, isInline: true, styles: ["@layer kj.component{.kj-button{display:inline-flex;align-items:center;justify-content:var(--kj-button-justify, center);gap:var(--kj-button-gap, var(--kj-space-sm));min-width:var(--kj-button-min-width, auto);height:var(--kj-button-height, auto);align-self:center;background:var(--kj-button-bg, var(--kj-bg-primary));color:var(--kj-button-fg, var(--kj-fg-on-primary));border:var(--kj-button-border-width, var(--kj-border)) var(--kj-button-border-style, solid) var(--kj-button-border-color, transparent);border-radius:var(--kj-button-radius, var(--kj-radius-field));padding:var(--kj-button-padding-y, var(--kj-space-sm)) var(--kj-button-padding-x, var(--kj-space-md));font:var(--kj-button-font-weight, 600) var(--kj-button-font-size, var(--kj-text-sm)) / 1.2 var(--kj-button-font, var(--kj-font-sans));letter-spacing:var(--kj-button-letter-spacing, -.01em);text-transform:var(--kj-button-text-transform, none);transition:color var(--kj-transition),border-color var(--kj-transition),box-shadow var(--kj-transition),transform var(--kj-transition),opacity var(--kj-transition);cursor:pointer;text-decoration:none}.kj-button[data-variant=destructive]{--kj-button-bg: var(--kj-bg-danger);--kj-button-fg: var(--kj-fg-on-danger)}.kj-button[data-variant=destructive]:hover{--kj-button-bg: color-mix(in oklch, var(--kj-bg-danger), black 8%)}.kj-button[data-variant=ghost]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-default);--kj-button-border-color: transparent}.kj-button[data-variant=ghost]:hover{--kj-button-bg: color-mix(in oklab, var(--kj-fg-default) 10%, transparent)}.kj-button[data-variant=outline]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-default);--kj-button-border-color: var(--kj-border-default)}.kj-button[data-variant=outline]:hover{--kj-button-bg: var(--kj-bg-surface)}.kj-button[data-variant=segmented]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-muted, var(--kj-fg-default));--kj-button-border-color: transparent;--kj-button-border-width: 0;--kj-button-radius: 0;--kj-button-hover-translate: none}.kj-button[data-variant=segmented]:hover{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-default)}.kj-button[data-variant=segmented][aria-pressed=true]{--kj-button-bg: var(--kj-segmented-bg-on, var(--kj-bg-surface));--kj-button-fg: var(--kj-segmented-fg-on, var(--kj-fg-default));cursor:default}.kj-button[data-variant=segmented][aria-pressed=true]:hover{--kj-button-bg: var(--kj-segmented-bg-on, var(--kj-bg-surface));--kj-button-fg: var(--kj-segmented-fg-on, var(--kj-fg-default))}.kj-button[data-variant=link]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-primary);--kj-button-padding-x: 0;--kj-button-padding-y: 0;--kj-button-shadow: none;--kj-button-shadow-hover: none;--kj-button-shadow-active: none;text-decoration:underline;text-underline-offset:4px}.kj-button[data-variant=link]:hover{--kj-button-bg: transparent;--kj-button-fg: color-mix(in oklch, var(--kj-fg-primary), black 8%)}.kj-button[data-size=xs]{--kj-button-padding-x: var(--kj-space-sm);--kj-button-padding-y: 0;--kj-button-font-size: .75rem;--kj-button-height: var(--kj-ctl-h-xs)}.kj-button[data-size=sm]{--kj-button-padding-x: var(--kj-space-sm);--kj-button-padding-y: .25rem;--kj-button-font-size: .8125rem;--kj-button-height: var(--kj-ctl-h-sm)}.kj-button[data-size=md]{--kj-button-height: var(--kj-ctl-h-md)}.kj-button[data-size=lg]{--kj-button-padding-x: var(--kj-space-lg);--kj-button-padding-y: .625rem;--kj-button-font-size: 1rem;--kj-button-height: var(--kj-ctl-h-lg)}.kj-button[data-size=xl]{--kj-button-padding-x: var(--kj-space-2xl);--kj-button-padding-y: .875rem;--kj-button-font-size: 1.0625rem;--kj-button-gap: var(--kj-space-md);--kj-button-height: var(--kj-ctl-h-xl)}.kj-button[data-size=icon]{--kj-button-padding-x: var(--kj-space-sm);--kj-button-padding-y: var(--kj-space-sm);--kj-button-height: var(--kj-ctl-h-md);aspect-ratio:1}.kj-button[data-full=true]{width:100%}.kj-button:hover{--kj-button-bg: var(--kj-button-bg-hover, color-mix(in oklch, var(--kj-bg-primary), black 8%));transform:translateY(var(--kj-button-hover-translate, var(--kj-hover-translate, -2px)))}.kj-button[data-variant=default]:hover{--kj-button-fg: var(--kj-button-fg-hover, var(--kj-fg-on-primary))}.kj-button[data-variant=default]{box-shadow:var(--kj-button-shadow, none)}.kj-button[data-variant=default]:hover{box-shadow:var(--kj-button-shadow-hover, var(--kj-button-shadow, none))}.kj-button[data-variant=default]:active{box-shadow:var(--kj-button-shadow-active, var(--kj-button-shadow, none))}.kj-button:active{transform:var(--kj-button-translate-active, none)}.kj-button:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-button[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-button[data-size=icon]{min-width:2.75rem;min-height:2.75rem}.kj-button[aria-busy=true]{opacity:.7;cursor:progress}.kj-button[aria-pressed=true]{--kj-button-bg: var(--kj-bg-field);box-shadow:inset 0 1px 2px #0000001f}.kj-button__spinner{display:inline-block;width:1em;height:1em;vertical-align:-.125em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:kj-button-spinner-rotate .6s linear infinite}}@keyframes kj-button-spinner-rotate{to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: KjButton, selector: "[kjButton]", inputs: ["kjDisabled", "kjLoading", "kjFullWidth", "kjPressed"], outputs: ["kjPressedChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1785
1786
|
}
|
|
1786
1787
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjButtonComponent, decorators: [{
|
|
1787
1788
|
type: Component,
|
|
@@ -1804,7 +1805,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
1804
1805
|
<ng-content />
|
|
1805
1806
|
}
|
|
1806
1807
|
</button>
|
|
1807
|
-
`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-button{display:inline-flex;align-items:center;justify-content:var(--kj-button-justify, center);gap:var(--kj-button-gap, var(--kj-space-sm));min-width:var(--kj-button-min-width, auto);height:var(--kj-button-height, auto);align-self:center;background:var(--kj-button-bg, var(--kj-bg-primary));color:var(--kj-button-fg, var(--kj-fg-on-primary));border:var(--kj-button-border-width, var(--kj-border)) var(--kj-button-border-style, solid) var(--kj-button-border-color, transparent);border-radius:var(--kj-button-radius, var(--kj-radius-field));padding:var(--kj-button-padding-y, var(--kj-space-sm)) var(--kj-button-padding-x, var(--kj-space-md));font:var(--kj-button-font-weight, 600) var(--kj-button-font-size, var(--kj-text-sm)) / 1.2 var(--kj-button-font, var(--kj-font-sans));letter-spacing:var(--kj-button-letter-spacing, -.01em);transition:color var(--kj-transition),border-color var(--kj-transition),box-shadow var(--kj-transition),transform var(--kj-transition),opacity var(--kj-transition);cursor:pointer;text-decoration:none}.kj-button[data-variant=destructive]{--kj-button-bg: var(--kj-bg-danger);--kj-button-fg: var(--kj-fg-on-danger)}.kj-button[data-variant=destructive]:hover{--kj-button-bg: color-mix(in oklch, var(--kj-bg-danger), black 8%)}.kj-button[data-variant=ghost]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-default);--kj-button-border-color: transparent}.kj-button[data-variant=ghost]:hover{--kj-button-bg: color-mix(in oklab, var(--kj-fg-default) 10%, transparent)}.kj-button[data-variant=outline]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-default);--kj-button-border-color: var(--kj-border-default)}.kj-button[data-variant=outline]:hover{--kj-button-bg: var(--kj-bg-surface)}.kj-button[data-variant=link]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-primary);--kj-button-padding-x: 0;--kj-button-padding-y: 0;--kj-button-shadow: none;--kj-button-shadow-hover: none;--kj-button-shadow-active: none;text-decoration:underline;text-underline-offset:4px}.kj-button[data-variant=link]:hover{--kj-button-bg: transparent;--kj-button-fg: color-mix(in oklch, var(--kj-fg-primary), black 8%)}.kj-button[data-size=xs]{--kj-button-padding-x: var(--kj-space-sm);--kj-button-padding-y: 0;--kj-button-font-size: .75rem;--kj-button-height: var(--kj-ctl-h-xs)}.kj-button[data-size=sm]{--kj-button-padding-x: var(--kj-space-sm);--kj-button-padding-y: .25rem;--kj-button-font-size: .8125rem;--kj-button-height: var(--kj-ctl-h-sm)}.kj-button[data-size=md]{--kj-button-height: var(--kj-ctl-h-md)}.kj-button[data-size=lg]{--kj-button-padding-x: var(--kj-space-lg);--kj-button-padding-y: .625rem;--kj-button-font-size: 1rem;--kj-button-height: var(--kj-ctl-h-lg)}.kj-button[data-size=xl]{--kj-button-padding-x: var(--kj-space-2xl);--kj-button-padding-y: .875rem;--kj-button-font-size: 1.0625rem;--kj-button-gap: var(--kj-space-md);--kj-button-height: var(--kj-ctl-h-xl)}.kj-button[data-size=icon]{--kj-button-padding-x: var(--kj-space-sm);--kj-button-padding-y: var(--kj-space-sm);--kj-button-height: var(--kj-ctl-h-md);aspect-ratio:1}.kj-button[data-full=true]{width:100%}.kj-button:hover{--kj-button-bg: var(--kj-button-bg-hover, color-mix(in oklch, var(--kj-bg-primary), black 8%));transform:translateY(var(--kj-button-hover-translate, var(--kj-hover-translate, -2px)))}.kj-button[data-variant=default]:hover{--kj-button-fg: var(--kj-button-fg-hover, var(--kj-fg-on-primary))}.kj-button[data-variant=default]{box-shadow:var(--kj-button-shadow, none)}.kj-button[data-variant=default]:hover{box-shadow:var(--kj-button-shadow-hover, var(--kj-button-shadow, none))}.kj-button[data-variant=default]:active{box-shadow:var(--kj-button-shadow-active, var(--kj-button-shadow, none))}.kj-button:active{transform:var(--kj-button-translate-active, none)}.kj-button:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-button[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-button[data-size=icon]{min-width:2.75rem;min-height:2.75rem}.kj-button[aria-busy=true]{opacity:.7;cursor:progress}.kj-button[aria-pressed=true]{--kj-button-bg: var(--kj-bg-field);box-shadow:inset 0 1px 2px #0000001f}.kj-button__spinner{display:inline-block;width:1em;height:1em;vertical-align:-.125em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:kj-button-spinner-rotate .6s linear infinite}}@keyframes kj-button-spinner-rotate{to{transform:rotate(360deg)}}\n"] }]
|
|
1808
|
+
`, encapsulation: ViewEncapsulation.None, host: { style: 'display: contents;' }, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-button{display:inline-flex;align-items:center;justify-content:var(--kj-button-justify, center);gap:var(--kj-button-gap, var(--kj-space-sm));min-width:var(--kj-button-min-width, auto);height:var(--kj-button-height, auto);align-self:center;background:var(--kj-button-bg, var(--kj-bg-primary));color:var(--kj-button-fg, var(--kj-fg-on-primary));border:var(--kj-button-border-width, var(--kj-border)) var(--kj-button-border-style, solid) var(--kj-button-border-color, transparent);border-radius:var(--kj-button-radius, var(--kj-radius-field));padding:var(--kj-button-padding-y, var(--kj-space-sm)) var(--kj-button-padding-x, var(--kj-space-md));font:var(--kj-button-font-weight, 600) var(--kj-button-font-size, var(--kj-text-sm)) / 1.2 var(--kj-button-font, var(--kj-font-sans));letter-spacing:var(--kj-button-letter-spacing, -.01em);text-transform:var(--kj-button-text-transform, none);transition:color var(--kj-transition),border-color var(--kj-transition),box-shadow var(--kj-transition),transform var(--kj-transition),opacity var(--kj-transition);cursor:pointer;text-decoration:none}.kj-button[data-variant=destructive]{--kj-button-bg: var(--kj-bg-danger);--kj-button-fg: var(--kj-fg-on-danger)}.kj-button[data-variant=destructive]:hover{--kj-button-bg: color-mix(in oklch, var(--kj-bg-danger), black 8%)}.kj-button[data-variant=ghost]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-default);--kj-button-border-color: transparent}.kj-button[data-variant=ghost]:hover{--kj-button-bg: color-mix(in oklab, var(--kj-fg-default) 10%, transparent)}.kj-button[data-variant=outline]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-default);--kj-button-border-color: var(--kj-border-default)}.kj-button[data-variant=outline]:hover{--kj-button-bg: var(--kj-bg-surface)}.kj-button[data-variant=segmented]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-muted, var(--kj-fg-default));--kj-button-border-color: transparent;--kj-button-border-width: 0;--kj-button-radius: 0;--kj-button-hover-translate: none}.kj-button[data-variant=segmented]:hover{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-default)}.kj-button[data-variant=segmented][aria-pressed=true]{--kj-button-bg: var(--kj-segmented-bg-on, var(--kj-bg-surface));--kj-button-fg: var(--kj-segmented-fg-on, var(--kj-fg-default));cursor:default}.kj-button[data-variant=segmented][aria-pressed=true]:hover{--kj-button-bg: var(--kj-segmented-bg-on, var(--kj-bg-surface));--kj-button-fg: var(--kj-segmented-fg-on, var(--kj-fg-default))}.kj-button[data-variant=link]{--kj-button-bg: transparent;--kj-button-fg: var(--kj-fg-primary);--kj-button-padding-x: 0;--kj-button-padding-y: 0;--kj-button-shadow: none;--kj-button-shadow-hover: none;--kj-button-shadow-active: none;text-decoration:underline;text-underline-offset:4px}.kj-button[data-variant=link]:hover{--kj-button-bg: transparent;--kj-button-fg: color-mix(in oklch, var(--kj-fg-primary), black 8%)}.kj-button[data-size=xs]{--kj-button-padding-x: var(--kj-space-sm);--kj-button-padding-y: 0;--kj-button-font-size: .75rem;--kj-button-height: var(--kj-ctl-h-xs)}.kj-button[data-size=sm]{--kj-button-padding-x: var(--kj-space-sm);--kj-button-padding-y: .25rem;--kj-button-font-size: .8125rem;--kj-button-height: var(--kj-ctl-h-sm)}.kj-button[data-size=md]{--kj-button-height: var(--kj-ctl-h-md)}.kj-button[data-size=lg]{--kj-button-padding-x: var(--kj-space-lg);--kj-button-padding-y: .625rem;--kj-button-font-size: 1rem;--kj-button-height: var(--kj-ctl-h-lg)}.kj-button[data-size=xl]{--kj-button-padding-x: var(--kj-space-2xl);--kj-button-padding-y: .875rem;--kj-button-font-size: 1.0625rem;--kj-button-gap: var(--kj-space-md);--kj-button-height: var(--kj-ctl-h-xl)}.kj-button[data-size=icon]{--kj-button-padding-x: var(--kj-space-sm);--kj-button-padding-y: var(--kj-space-sm);--kj-button-height: var(--kj-ctl-h-md);aspect-ratio:1}.kj-button[data-full=true]{width:100%}.kj-button:hover{--kj-button-bg: var(--kj-button-bg-hover, color-mix(in oklch, var(--kj-bg-primary), black 8%));transform:translateY(var(--kj-button-hover-translate, var(--kj-hover-translate, -2px)))}.kj-button[data-variant=default]:hover{--kj-button-fg: var(--kj-button-fg-hover, var(--kj-fg-on-primary))}.kj-button[data-variant=default]{box-shadow:var(--kj-button-shadow, none)}.kj-button[data-variant=default]:hover{box-shadow:var(--kj-button-shadow-hover, var(--kj-button-shadow, none))}.kj-button[data-variant=default]:active{box-shadow:var(--kj-button-shadow-active, var(--kj-button-shadow, none))}.kj-button:active{transform:var(--kj-button-translate-active, none)}.kj-button:focus-visible{outline:2px solid var(--kj-border-focus);outline-offset:2px}.kj-button[aria-disabled=true]{opacity:.45;cursor:not-allowed;pointer-events:none}.kj-button[data-size=icon]{min-width:2.75rem;min-height:2.75rem}.kj-button[aria-busy=true]{opacity:.7;cursor:progress}.kj-button[aria-pressed=true]{--kj-button-bg: var(--kj-bg-field);box-shadow:inset 0 1px 2px #0000001f}.kj-button__spinner{display:inline-block;width:1em;height:1em;vertical-align:-.125em;border:2px solid currentColor;border-right-color:transparent;border-radius:50%;animation:kj-button-spinner-rotate .6s linear infinite}}@keyframes kj-button-spinner-rotate{to{transform:rotate(360deg)}}\n"] }]
|
|
1808
1809
|
}], 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 }] }], kjLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjLoading", required: false }] }], kjFullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjFullWidth", required: false }] }], kjPressed: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjPressed", required: false }] }, { type: i0.Output, args: ["kjPressedChange"] }], kjType: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjType", required: false }] }], kjAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjAriaLabel", required: false }] }] } });
|
|
1809
1810
|
|
|
1810
1811
|
/**
|
|
@@ -1839,6 +1840,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
1839
1840
|
* @doc-example Variants
|
|
1840
1841
|
* Set `kjVariant` on the group to cascade onto every child button.
|
|
1841
1842
|
* @doc-file button-group.variants.example.ts
|
|
1843
|
+
* @doc-example Segmented
|
|
1844
|
+
* `kjVariant="segmented"` moves the border onto the group and fills only
|
|
1845
|
+
* the pressed child — a mode switcher rather than a toolbar.
|
|
1846
|
+
* @doc-file button-group.segmented.example.ts
|
|
1842
1847
|
* @doc-example Toggle
|
|
1843
1848
|
* Pair with `[kjPressed]` on each child to build a segmented control.
|
|
1844
1849
|
* @doc-file button-group.toggle.example.ts
|
|
@@ -1870,7 +1875,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
1870
1875
|
* @doc-related button,toggle,tabs
|
|
1871
1876
|
*
|
|
1872
1877
|
* @doc-css-var
|
|
1873
|
-
* --kj-button-group-gap
|
|
1878
|
+
* --kj-button-group-gap — Gap between adjacent buttons. Defaults to 0 (segmented look); raise for a spaced cluster.
|
|
1879
|
+
* --kj-segmented-border — Shell and divider colour, `kjVariant="segmented"` only. Defaults to `--kj-border-default`.
|
|
1880
|
+
* --kj-segmented-bg-on — Fill behind the pressed segment. Defaults to `--kj-bg-surface`.
|
|
1881
|
+
* --kj-segmented-fg-on — Ink on the pressed segment. Defaults to `--kj-fg-default`.
|
|
1882
|
+
*
|
|
1883
|
+
* Typography needs no dedicated hook: set the ordinary `--kj-button-font`,
|
|
1884
|
+
* `--kj-button-font-size`, `--kj-button-letter-spacing` and
|
|
1885
|
+
* `--kj-button-text-transform` on this host and they reach each child,
|
|
1886
|
+
* since every knob is read as `var(name, default)`. The on-state colours
|
|
1887
|
+
* are the exception — variant rules declare those knobs on the element,
|
|
1888
|
+
* so they get their own `--kj-segmented-*` indirection.
|
|
1874
1889
|
*
|
|
1875
1890
|
* @doc-category Library/Actions
|
|
1876
1891
|
* @doc
|
|
@@ -1888,7 +1903,9 @@ class KjButtonGroupComponent {
|
|
|
1888
1903
|
...(ngDevMode ? [{ debugName: "kjOrientation" }] : /* istanbul ignore next */ []));
|
|
1889
1904
|
/**
|
|
1890
1905
|
* Default variant forwarded to children via `KJ_BUTTON_GROUP`. Children
|
|
1891
|
-
* that set their own `kjVariant` override this fallback.
|
|
1906
|
+
* that set their own `kjVariant` override this fallback. Also mirrored to
|
|
1907
|
+
* `data-variant` on the host, which is how `segmented` draws its shared
|
|
1908
|
+
* shell and dividers.
|
|
1892
1909
|
*/
|
|
1893
1910
|
kjVariant = input(undefined, /* @ts-ignore */
|
|
1894
1911
|
...(ngDevMode ? [{ debugName: "kjVariant" }] : /* istanbul ignore next */ []));
|
|
@@ -1910,7 +1927,7 @@ class KjButtonGroupComponent {
|
|
|
1910
1927
|
kjAriaLabel = input(undefined, /* @ts-ignore */
|
|
1911
1928
|
...(ngDevMode ? [{ debugName: "kjAriaLabel" }] : /* istanbul ignore next */ []));
|
|
1912
1929
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjButtonGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1913
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.5", type: KjButtonGroupComponent, isStandalone: true, selector: "kj-button-group", inputs: { kjOrientation: { classPropertyName: "kjOrientation", publicName: "kjOrientation", isSignal: true, isRequired: false, transformFunction: null }, kjVariant: { classPropertyName: "kjVariant", publicName: "kjVariant", isSignal: true, isRequired: false, transformFunction: null }, kjSize: { classPropertyName: "kjSize", publicName: "kjSize", isSignal: true, isRequired: false, transformFunction: null }, kjDisabled: { classPropertyName: "kjDisabled", publicName: "kjDisabled", isSignal: true, isRequired: false, transformFunction: null }, kjAriaLabel: { classPropertyName: "kjAriaLabel", publicName: "kjAriaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-label": "kjAriaLabel()" }, classAttribute: "kj-button-group" }, hostDirectives: [{ directive: i1.KjButtonGroup, inputs: ["kjOrientation", "kjOrientation", "kjVariant", "kjVariant", "kjSize", "kjSize", "kjDisabled", "kjDisabled"] }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: ["@layer kj.component{.kj-button-group{--kj-button-group-gap: 0;display:inline-flex;flex-direction:row;align-items:stretch;gap:var(--kj-button-group-gap);border-radius:var(--kj-radius-field);isolation:isolate}.kj-button-group[data-orientation=vertical]{flex-direction:column}.kj-button-group:not([data-orientation=vertical])>kj-button>.kj-button{border-radius:0;margin-left:calc(-1 * var(--kj-border))}.kj-button-group:not([data-orientation=vertical])>kj-button:first-child>.kj-button{border-top-left-radius:var(--kj-radius-field);border-bottom-left-radius:var(--kj-radius-field);margin-left:0}.kj-button-group:not([data-orientation=vertical])>kj-button:last-child>.kj-button{border-top-right-radius:var(--kj-radius-field);border-bottom-right-radius:var(--kj-radius-field)}.kj-button-group[data-orientation=vertical]>kj-button>.kj-button{border-radius:0;margin-top:calc(-1 * var(--kj-border));width:100%}.kj-button-group[data-orientation=vertical]>kj-button:first-child>.kj-button{border-top-left-radius:var(--kj-radius-field);border-top-right-radius:var(--kj-radius-field);margin-top:0}.kj-button-group[data-orientation=vertical]>kj-button:last-child>.kj-button{border-bottom-left-radius:var(--kj-radius-field);border-bottom-right-radius:var(--kj-radius-field)}.kj-button-group>kj-button>.kj-button:hover,.kj-button-group>kj-button>.kj-button:focus-visible,.kj-button-group>kj-button>.kj-button[aria-pressed=true]{z-index:1}.kj-button-group[data-disabled]{opacity:.7}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1930
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.5", type: KjButtonGroupComponent, isStandalone: true, selector: "kj-button-group", inputs: { kjOrientation: { classPropertyName: "kjOrientation", publicName: "kjOrientation", isSignal: true, isRequired: false, transformFunction: null }, kjVariant: { classPropertyName: "kjVariant", publicName: "kjVariant", isSignal: true, isRequired: false, transformFunction: null }, kjSize: { classPropertyName: "kjSize", publicName: "kjSize", isSignal: true, isRequired: false, transformFunction: null }, kjDisabled: { classPropertyName: "kjDisabled", publicName: "kjDisabled", isSignal: true, isRequired: false, transformFunction: null }, kjAriaLabel: { classPropertyName: "kjAriaLabel", publicName: "kjAriaLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-label": "kjAriaLabel()" }, classAttribute: "kj-button-group" }, hostDirectives: [{ directive: i1.KjButtonGroup, inputs: ["kjOrientation", "kjOrientation", "kjVariant", "kjVariant", "kjSize", "kjSize", "kjDisabled", "kjDisabled"] }], ngImport: i0, template: `<ng-content />`, isInline: true, styles: ["@layer kj.component{.kj-button-group{--kj-button-group-gap: 0;display:inline-flex;flex-direction:row;align-items:stretch;gap:var(--kj-button-group-gap);border-radius:var(--kj-radius-field);isolation:isolate}.kj-button-group[data-orientation=vertical]{flex-direction:column}.kj-button-group:not([data-orientation=vertical])>kj-button>.kj-button{border-radius:0;margin-left:calc(-1 * var(--kj-border))}.kj-button-group:not([data-orientation=vertical])>kj-button:first-child>.kj-button{border-top-left-radius:var(--kj-radius-field);border-bottom-left-radius:var(--kj-radius-field);margin-left:0}.kj-button-group:not([data-orientation=vertical])>kj-button:last-child>.kj-button{border-top-right-radius:var(--kj-radius-field);border-bottom-right-radius:var(--kj-radius-field)}.kj-button-group[data-orientation=vertical]>kj-button>.kj-button{border-radius:0;margin-top:calc(-1 * var(--kj-border));width:100%}.kj-button-group[data-orientation=vertical]>kj-button:first-child>.kj-button{border-top-left-radius:var(--kj-radius-field);border-top-right-radius:var(--kj-radius-field);margin-top:0}.kj-button-group[data-orientation=vertical]>kj-button:last-child>.kj-button{border-bottom-left-radius:var(--kj-radius-field);border-bottom-right-radius:var(--kj-radius-field)}.kj-button-group>kj-button>.kj-button:hover,.kj-button-group>kj-button>.kj-button:focus-visible,.kj-button-group>kj-button>.kj-button[aria-pressed=true]{z-index:1}.kj-button-group[data-variant=segmented]{border:var(--kj-border) solid var(--kj-segmented-border, var(--kj-border-default));border-radius:var(--kj-radius-field);overflow:hidden}.kj-button-group[data-variant=segmented]>kj-button>.kj-button{margin-left:0;margin-top:0;border-radius:0}.kj-button-group[data-variant=segmented]:not([data-orientation=vertical])>kj-button+kj-button>.kj-button{border-left:var(--kj-border) solid var(--kj-segmented-border, var(--kj-border-default))}.kj-button-group[data-variant=segmented][data-orientation=vertical]>kj-button+kj-button>.kj-button{border-top:var(--kj-border) solid var(--kj-segmented-border, var(--kj-border-default))}.kj-button-group[data-disabled]{opacity:.7}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1914
1931
|
}
|
|
1915
1932
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjButtonGroupComponent, decorators: [{
|
|
1916
1933
|
type: Component,
|
|
@@ -1922,7 +1939,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
1922
1939
|
], template: `<ng-content />`, encapsulation: ViewEncapsulation.None, host: {
|
|
1923
1940
|
class: 'kj-button-group',
|
|
1924
1941
|
'[attr.aria-label]': 'kjAriaLabel()',
|
|
1925
|
-
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-button-group{--kj-button-group-gap: 0;display:inline-flex;flex-direction:row;align-items:stretch;gap:var(--kj-button-group-gap);border-radius:var(--kj-radius-field);isolation:isolate}.kj-button-group[data-orientation=vertical]{flex-direction:column}.kj-button-group:not([data-orientation=vertical])>kj-button>.kj-button{border-radius:0;margin-left:calc(-1 * var(--kj-border))}.kj-button-group:not([data-orientation=vertical])>kj-button:first-child>.kj-button{border-top-left-radius:var(--kj-radius-field);border-bottom-left-radius:var(--kj-radius-field);margin-left:0}.kj-button-group:not([data-orientation=vertical])>kj-button:last-child>.kj-button{border-top-right-radius:var(--kj-radius-field);border-bottom-right-radius:var(--kj-radius-field)}.kj-button-group[data-orientation=vertical]>kj-button>.kj-button{border-radius:0;margin-top:calc(-1 * var(--kj-border));width:100%}.kj-button-group[data-orientation=vertical]>kj-button:first-child>.kj-button{border-top-left-radius:var(--kj-radius-field);border-top-right-radius:var(--kj-radius-field);margin-top:0}.kj-button-group[data-orientation=vertical]>kj-button:last-child>.kj-button{border-bottom-left-radius:var(--kj-radius-field);border-bottom-right-radius:var(--kj-radius-field)}.kj-button-group>kj-button>.kj-button:hover,.kj-button-group>kj-button>.kj-button:focus-visible,.kj-button-group>kj-button>.kj-button[aria-pressed=true]{z-index:1}.kj-button-group[data-disabled]{opacity:.7}}\n"] }]
|
|
1942
|
+
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["@layer kj.component{.kj-button-group{--kj-button-group-gap: 0;display:inline-flex;flex-direction:row;align-items:stretch;gap:var(--kj-button-group-gap);border-radius:var(--kj-radius-field);isolation:isolate}.kj-button-group[data-orientation=vertical]{flex-direction:column}.kj-button-group:not([data-orientation=vertical])>kj-button>.kj-button{border-radius:0;margin-left:calc(-1 * var(--kj-border))}.kj-button-group:not([data-orientation=vertical])>kj-button:first-child>.kj-button{border-top-left-radius:var(--kj-radius-field);border-bottom-left-radius:var(--kj-radius-field);margin-left:0}.kj-button-group:not([data-orientation=vertical])>kj-button:last-child>.kj-button{border-top-right-radius:var(--kj-radius-field);border-bottom-right-radius:var(--kj-radius-field)}.kj-button-group[data-orientation=vertical]>kj-button>.kj-button{border-radius:0;margin-top:calc(-1 * var(--kj-border));width:100%}.kj-button-group[data-orientation=vertical]>kj-button:first-child>.kj-button{border-top-left-radius:var(--kj-radius-field);border-top-right-radius:var(--kj-radius-field);margin-top:0}.kj-button-group[data-orientation=vertical]>kj-button:last-child>.kj-button{border-bottom-left-radius:var(--kj-radius-field);border-bottom-right-radius:var(--kj-radius-field)}.kj-button-group>kj-button>.kj-button:hover,.kj-button-group>kj-button>.kj-button:focus-visible,.kj-button-group>kj-button>.kj-button[aria-pressed=true]{z-index:1}.kj-button-group[data-variant=segmented]{border:var(--kj-border) solid var(--kj-segmented-border, var(--kj-border-default));border-radius:var(--kj-radius-field);overflow:hidden}.kj-button-group[data-variant=segmented]>kj-button>.kj-button{margin-left:0;margin-top:0;border-radius:0}.kj-button-group[data-variant=segmented]:not([data-orientation=vertical])>kj-button+kj-button>.kj-button{border-left:var(--kj-border) solid var(--kj-segmented-border, var(--kj-border-default))}.kj-button-group[data-variant=segmented][data-orientation=vertical]>kj-button+kj-button>.kj-button{border-top:var(--kj-border) solid var(--kj-segmented-border, var(--kj-border-default))}.kj-button-group[data-disabled]{opacity:.7}}\n"] }]
|
|
1926
1943
|
}], propDecorators: { kjOrientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjOrientation", required: false }] }], 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 }] }], kjAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "kjAriaLabel", required: false }] }] } });
|
|
1927
1944
|
|
|
1928
1945
|
/**
|
|
@@ -3209,77 +3226,74 @@ function escapeHtml(s) {
|
|
|
3209
3226
|
.replace(/"/g, '"')
|
|
3210
3227
|
.replace(/'/g, ''');
|
|
3211
3228
|
}
|
|
3212
|
-
/** Only allow safe URL schemes for links. */
|
|
3213
|
-
function safeUrl(url) {
|
|
3214
|
-
const trimmed = url.trim();
|
|
3215
|
-
if (/^(https?:\/\/|\/|#|mailto:)/i.test(trimmed))
|
|
3216
|
-
return trimmed;
|
|
3217
|
-
return null;
|
|
3218
|
-
}
|
|
3219
|
-
/** Apply link / bold / italic to a non-code segment. */
|
|
3220
|
-
function formatSegment(seg) {
|
|
3221
|
-
let s = seg.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, (_m, text, url) => {
|
|
3222
|
-
const href = safeUrl(url);
|
|
3223
|
-
if (!href)
|
|
3224
|
-
return text;
|
|
3225
|
-
return `<a class="kj-md-link" href="${escapeHtml(href)}" rel="noopener noreferrer" target="_blank">${text}</a>`;
|
|
3226
|
-
});
|
|
3227
|
-
s = s.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
|
|
3228
|
-
s = s.replace(/(^|[^*])\*([^*]+)\*/g, '$1<em>$2</em>');
|
|
3229
|
-
return s;
|
|
3230
|
-
}
|
|
3231
3229
|
/**
|
|
3232
|
-
*
|
|
3233
|
-
*
|
|
3234
|
-
*
|
|
3230
|
+
* GFM, with `breaks` on: a chat turn treats a single newline as a line break,
|
|
3231
|
+
* which is what people type. `pedantic` off so the parser stays forgiving of
|
|
3232
|
+
* the half-formed markdown a model emits mid-stream.
|
|
3233
|
+
*
|
|
3234
|
+
* `marked` dropped its sanitizer in v5 and passes source HTML through
|
|
3235
|
+
* verbatim, so both HTML token kinds are overridden to escape instead. A chat
|
|
3236
|
+
* turn is model or user output: it may *describe* markup, never inject it.
|
|
3235
3237
|
*/
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
}
|
|
3245
|
-
|
|
3246
|
-
}
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
.
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
}
|
|
3238
|
+
marked.use({
|
|
3239
|
+
gfm: true,
|
|
3240
|
+
breaks: true,
|
|
3241
|
+
pedantic: false,
|
|
3242
|
+
renderer: {
|
|
3243
|
+
html(token) {
|
|
3244
|
+
return escapeHtml(typeof token === 'string' ? token : token.raw);
|
|
3245
|
+
},
|
|
3246
|
+
},
|
|
3247
|
+
tokenizer: {},
|
|
3248
|
+
});
|
|
3249
|
+
marked.use({
|
|
3250
|
+
renderer: {
|
|
3251
|
+
// Inline HTML (`<img …>` mid-sentence) travels a different path than a
|
|
3252
|
+
// block-level HTML token, and needs the same treatment.
|
|
3253
|
+
text(token) {
|
|
3254
|
+
const anyToken = token;
|
|
3255
|
+
if (Array.isArray(anyToken.tokens) && anyToken.tokens.length > 0) {
|
|
3256
|
+
return this.parser.parseInline(anyToken.tokens);
|
|
3257
|
+
}
|
|
3258
|
+
return escapeHtml(String(anyToken.text ?? anyToken.raw ?? ''));
|
|
3259
|
+
},
|
|
3260
|
+
},
|
|
3261
|
+
});
|
|
3260
3262
|
/**
|
|
3261
|
-
* Parse
|
|
3262
|
-
*
|
|
3263
|
-
* blocks with sanitised inline HTML.
|
|
3263
|
+
* Parse markdown into blocks: fenced code becomes a structural `code` block,
|
|
3264
|
+
* everything else is rendered to HTML as a `prose` block.
|
|
3264
3265
|
*
|
|
3265
|
-
*
|
|
3266
|
-
*
|
|
3267
|
-
*
|
|
3266
|
+
* Code is split out at the TOKEN level rather than by regex so an indented
|
|
3267
|
+
* block, a `~~~` fence, or a fence inside a list is still recognised — and so
|
|
3268
|
+
* a stray fence in a partial stream cannot swallow the rest of the message.
|
|
3268
3269
|
*/
|
|
3269
3270
|
function renderMarkdown(src) {
|
|
3271
|
+
const tokens = marked.lexer(src);
|
|
3270
3272
|
const blocks = [];
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3273
|
+
let prose = [];
|
|
3274
|
+
const flushProse = () => {
|
|
3275
|
+
if (prose.length === 0)
|
|
3276
|
+
return;
|
|
3277
|
+
// `marked.parser` reads `links` off the token list for reference-style
|
|
3278
|
+
// links; a plain slice would drop them and render `[a][b]` verbatim.
|
|
3279
|
+
const list = prose;
|
|
3280
|
+
list.links = tokens.links;
|
|
3281
|
+
blocks.push({ kind: 'prose', html: marked.parser(list) });
|
|
3282
|
+
prose = [];
|
|
3283
|
+
};
|
|
3284
|
+
for (const token of tokens) {
|
|
3285
|
+
if (token.type === 'code') {
|
|
3286
|
+
flushProse();
|
|
3287
|
+
blocks.push({
|
|
3288
|
+
kind: 'code',
|
|
3289
|
+
lang: typeof token.lang === 'string' ? token.lang.split(/\s+/)[0] : '',
|
|
3290
|
+
code: String(token.text ?? ''),
|
|
3291
|
+
});
|
|
3292
|
+
continue;
|
|
3293
|
+
}
|
|
3294
|
+
prose.push(token);
|
|
3279
3295
|
}
|
|
3280
|
-
|
|
3281
|
-
if (rest.trim())
|
|
3282
|
-
blocks.push({ kind: 'prose', html: renderProse(rest) });
|
|
3296
|
+
flushProse();
|
|
3283
3297
|
return blocks;
|
|
3284
3298
|
}
|
|
3285
3299
|
|
|
@@ -3325,8 +3339,15 @@ class KjChatMessage {
|
|
|
3325
3339
|
_copied = signal(null, /* @ts-ignore */
|
|
3326
3340
|
...(ngDevMode ? [{ debugName: "_copied" }] : /* istanbul ignore next */ []));
|
|
3327
3341
|
copiedIndex = this._copied.asReadonly();
|
|
3342
|
+
/**
|
|
3343
|
+
* Sanitise rather than bypass. `renderMarkdown` already escapes raw HTML at
|
|
3344
|
+
* the parse layer, but a chat body is model or user output — the one place
|
|
3345
|
+
* in a UI kit where trusting a single layer is a bad bet. `sanitize` strips
|
|
3346
|
+
* anything the parser somehow let through instead of waving it past
|
|
3347
|
+
* Angular's checks.
|
|
3348
|
+
*/
|
|
3328
3349
|
safe(html) {
|
|
3329
|
-
return this.sanitizer.
|
|
3350
|
+
return this.sanitizer.sanitize(SecurityContext.HTML, html) ?? '';
|
|
3330
3351
|
}
|
|
3331
3352
|
async copy(code, index) {
|
|
3332
3353
|
try {
|
|
@@ -3546,6 +3567,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImpor
|
|
|
3546
3567
|
* Provider-agnostic: pair with `KjPromptInput` and drive `KjChatStore` from any
|
|
3547
3568
|
* model / stream — the kit ships **no** LLM SDK or backend.
|
|
3548
3569
|
*
|
|
3570
|
+
* @doc-example Custom thread items
|
|
3571
|
+
* `provideKjChat` maps an item `type` to a component, so a thread can render
|
|
3572
|
+
* turns the kit knows nothing about. Ordinary messages are untouched.
|
|
3573
|
+
* @doc-file ai-chat.custom-items.example.ts
|
|
3549
3574
|
* @doc-example Streaming (simulated)
|
|
3550
3575
|
* A full send → simulated-stream → reply loop with slash commands, a Stop
|
|
3551
3576
|
* button, tool-call cards and citations. No backend — a fake token generator
|
|
@@ -3587,6 +3612,30 @@ class KjChatThread {
|
|
|
3587
3612
|
...(ngDevMode ? [{ debugName: "kjLabel" }] : /* istanbul ignore next */ []));
|
|
3588
3613
|
/** @internal — the coalescing announcer for the polite live region. */
|
|
3589
3614
|
announcer = inject(KjChatAnnouncer);
|
|
3615
|
+
config = inject(KJ_CHAT_CONFIG);
|
|
3616
|
+
/**
|
|
3617
|
+
* The registered component for a message's `type`, or `null` to let the
|
|
3618
|
+
* built-in renderer draw it. A message with no `type` never consults the
|
|
3619
|
+
* registry — that is the overwhelmingly common case and must stay free.
|
|
3620
|
+
*
|
|
3621
|
+
* An unknown `type` falls back to the configured `fallback`, and failing
|
|
3622
|
+
* that to the built-in renderer: a transcript that silently drops a turn is
|
|
3623
|
+
* worse than one that renders it plainly.
|
|
3624
|
+
*/
|
|
3625
|
+
rendererFor(message) {
|
|
3626
|
+
if (!message.type)
|
|
3627
|
+
return null;
|
|
3628
|
+
return this.config.renderers[message.type] ?? this.config.fallback ?? null;
|
|
3629
|
+
}
|
|
3630
|
+
/** The neutral shape handed to a registered renderer's `item` input. */
|
|
3631
|
+
itemFor(message) {
|
|
3632
|
+
return {
|
|
3633
|
+
id: message.id,
|
|
3634
|
+
type: message.type,
|
|
3635
|
+
role: message.role,
|
|
3636
|
+
data: message.data ?? message.content,
|
|
3637
|
+
};
|
|
3638
|
+
}
|
|
3590
3639
|
injector = inject(Injector);
|
|
3591
3640
|
logEl = viewChild.required('log');
|
|
3592
3641
|
lastId = null;
|
|
@@ -3636,7 +3685,13 @@ class KjChatThread {
|
|
|
3636
3685
|
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: `
|
|
3637
3686
|
<div #log kjChatLog kjChatLogLive="off" class="kj-chat-thread" [kjChatLogLabel]="kjLabel()">
|
|
3638
3687
|
@for (m of store().messages(); track m.id) {
|
|
3639
|
-
|
|
3688
|
+
@if (rendererFor(m); as renderer) {
|
|
3689
|
+
<ng-container
|
|
3690
|
+
*ngComponentOutlet="renderer; inputs: { item: itemFor(m), message: m }"
|
|
3691
|
+
></ng-container>
|
|
3692
|
+
} @else {
|
|
3693
|
+
<kj-chat-message [message]="m" />
|
|
3694
|
+
}
|
|
3640
3695
|
}
|
|
3641
3696
|
</div>
|
|
3642
3697
|
|
|
@@ -3644,14 +3699,20 @@ class KjChatThread {
|
|
|
3644
3699
|
<div class="kj-visually-hidden" aria-live="polite" aria-atomic="false">
|
|
3645
3700
|
{{ announcer.message() }}
|
|
3646
3701
|
</div>
|
|
3647
|
-
`, 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 });
|
|
3702
|
+
`, 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"] }, { kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletEnvironmentInjector", "ngComponentOutletContent", "ngComponentOutletNgModule"], exportAs: ["ngComponentOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
3648
3703
|
}
|
|
3649
3704
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.5", ngImport: i0, type: KjChatThread, decorators: [{
|
|
3650
3705
|
type: Component,
|
|
3651
|
-
args: [{ selector: 'kj-chat-thread', standalone: true, imports: [KjChatLog, KjChatMessage], providers: [KjChatAnnouncer], template: `
|
|
3706
|
+
args: [{ selector: 'kj-chat-thread', standalone: true, imports: [KjChatLog, KjChatMessage, NgComponentOutlet], providers: [KjChatAnnouncer], template: `
|
|
3652
3707
|
<div #log kjChatLog kjChatLogLive="off" class="kj-chat-thread" [kjChatLogLabel]="kjLabel()">
|
|
3653
3708
|
@for (m of store().messages(); track m.id) {
|
|
3654
|
-
|
|
3709
|
+
@if (rendererFor(m); as renderer) {
|
|
3710
|
+
<ng-container
|
|
3711
|
+
*ngComponentOutlet="renderer; inputs: { item: itemFor(m), message: m }"
|
|
3712
|
+
></ng-container>
|
|
3713
|
+
} @else {
|
|
3714
|
+
<kj-chat-message [message]="m" />
|
|
3715
|
+
}
|
|
3655
3716
|
}
|
|
3656
3717
|
</div>
|
|
3657
3718
|
|