@qalma/kit 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,15 +27,25 @@ npm install @qalma/editor @qalma/kit @ng-icons/core @ng-icons/lucide
27
27
 
28
28
  Peer dependencies:
29
29
 
30
- - `@angular/core` `>=21 <22`
31
- - `@angular/common` `>=21 <22`
30
+ - `@angular/core` `>=21 <23`
31
+ - `@angular/common` `>=21 <23`
32
32
  - `@qalma/editor`
33
33
  - `@ng-icons/core`
34
34
  - `@ng-icons/lucide`
35
35
 
36
- The kit expects your app to provide Tailwind utilities and the CSS token
37
- contract below. If you already use shadcn-style tokens, the defaults should feel
38
- familiar.
36
+ The kit does not ship a compiled stylesheet. It expects your app to provide
37
+ Tailwind utilities and the CSS token contract below. If you already use
38
+ shadcn-style tokens, the defaults should feel familiar.
39
+
40
+ With Tailwind v4, point Tailwind at the installed package so it generates the
41
+ utilities used inside kit components:
42
+
43
+ ```css
44
+ @import 'tailwindcss';
45
+
46
+ /* Adjust the path if your global stylesheet is not src/styles.css. */
47
+ @source '../node_modules/@qalma/kit';
48
+ ```
39
49
 
40
50
  ## Theming
41
51
 
@@ -43,10 +53,11 @@ The kit does not ship a fixed brand. Components read design tokens through
43
53
  Tailwind utility names such as `bg-popover`, `text-muted-foreground`,
44
54
  `border-border`, and `ring-ring`.
45
55
 
46
- With Tailwind v4, expose those tokens with `@theme`:
56
+ Then expose those tokens with `@theme`:
47
57
 
48
58
  ```css
49
59
  @import 'tailwindcss';
60
+ @source '../node_modules/@qalma/kit';
50
61
 
51
62
  @theme {
52
63
  --color-background: var(--background);
@@ -230,10 +230,10 @@ class QalmaSuggestionMenu {
230
230
  optionsScroller() {
231
231
  return this.elementRef.nativeElement.querySelector(`[${SUGGESTION_OPTIONS_SCROLLER_ATTR}]`);
232
232
  }
233
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaSuggestionMenu, deps: [], target: i0.ɵɵFactoryTarget.Directive });
234
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.17", type: QalmaSuggestionMenu, isStandalone: true, inputs: { placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activate: "activate", pick: "pick", dismiss: "dismiss" }, ngImport: i0 });
233
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaSuggestionMenu, deps: [], target: i0.ɵɵFactoryTarget.Directive });
234
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: QalmaSuggestionMenu, isStandalone: true, inputs: { placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, activeIndex: { classPropertyName: "activeIndex", publicName: "activeIndex", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activate: "activate", pick: "pick", dismiss: "dismiss" }, ngImport: i0 });
235
235
  }
236
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaSuggestionMenu, decorators: [{
236
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaSuggestionMenu, decorators: [{
237
237
  type: Directive
238
238
  }], propDecorators: { placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], activeIndex: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeIndex", required: false }] }], activate: [{ type: i0.Output, args: ["activate"] }], pick: [{ type: i0.Output, args: ["pick"] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }] } });
239
239
 
@@ -596,10 +596,10 @@ class QalmaDragHandleDirective {
596
596
  startDrag(event, handle) {
597
597
  this.controller.startDrag(event, handle);
598
598
  }
599
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaDragHandleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
600
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.17", type: QalmaDragHandleDirective, isStandalone: true, selector: "[qalmaDragHandle]", inputs: { editor: { classPropertyName: "editor", publicName: "qalmaDragHandle", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["qalmaDragHandle"], ngImport: i0 });
599
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaDragHandleDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
600
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: QalmaDragHandleDirective, isStandalone: true, selector: "[qalmaDragHandle]", inputs: { editor: { classPropertyName: "editor", publicName: "qalmaDragHandle", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["qalmaDragHandle"], ngImport: i0 });
601
601
  }
602
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaDragHandleDirective, decorators: [{
602
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaDragHandleDirective, decorators: [{
603
603
  type: Directive,
604
604
  args: [{
605
605
  exportAs: 'qalmaDragHandle',
@@ -763,10 +763,10 @@ class QalmaSelectionToolbarDirective {
763
763
  hide() {
764
764
  this.controller.hide();
765
765
  }
766
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaSelectionToolbarDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
767
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.17", type: QalmaSelectionToolbarDirective, isStandalone: true, selector: "[qalmaSelectionToolbar]", inputs: { editor: { classPropertyName: "editor", publicName: "qalmaSelectionToolbar", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["qalmaSelectionToolbar"], ngImport: i0 });
766
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaSelectionToolbarDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
767
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: QalmaSelectionToolbarDirective, isStandalone: true, selector: "[qalmaSelectionToolbar]", inputs: { editor: { classPropertyName: "editor", publicName: "qalmaSelectionToolbar", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["qalmaSelectionToolbar"], ngImport: i0 });
768
768
  }
769
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaSelectionToolbarDirective, decorators: [{
769
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaSelectionToolbarDirective, decorators: [{
770
770
  type: Directive,
771
771
  args: [{
772
772
  exportAs: 'qalmaSelectionToolbar',
@@ -13,11 +13,12 @@ import { twMerge } from 'tailwind-merge';
13
13
  /**
14
14
  * Default styling for a toolbar command button. Icon-only, square, and driven
15
15
  * entirely by the host's shadcn-style design tokens (`text-muted-foreground`,
16
- * `bg-secondary`, `bg-accent-subtle`…) so it themes with the surrounding app.
16
+ * `bg-card`, `bg-secondary`, `bg-accent-subtle`…) so it themes with the
17
+ * surrounding app.
17
18
  * The `qalma-command-active` class is toggled by the `QalmaCommand` directive
18
19
  * when the underlying command is active.
19
20
  */
20
- const TOOLBAR_BUTTON_CLASS = 'inline-flex h-[1.85rem] w-[1.85rem] cursor-pointer items-center justify-center rounded-[0.4rem] border border-transparent text-muted-foreground transition hover:bg-secondary hover:text-foreground disabled:cursor-not-allowed disabled:opacity-45 [&.qalma-command-active]:border-accent/40 [&.qalma-command-active]:bg-accent-subtle [&.qalma-command-active]:text-accent';
21
+ const TOOLBAR_BUTTON_CLASS = 'inline-flex h-[1.85rem] w-[1.85rem] cursor-pointer items-center justify-center rounded-[0.4rem] border border-border bg-card text-muted-foreground transition hover:border-accent/50 hover:bg-secondary hover:text-foreground disabled:cursor-not-allowed disabled:opacity-45 [&.qalma-command-active]:border-accent/40 [&.qalma-command-active]:bg-accent-subtle [&.qalma-command-active]:text-accent';
21
22
  /**
22
23
  * Generic, declarative toolbar button for a single editor command.
23
24
  *
@@ -43,8 +44,8 @@ class QalmaToolbarButton {
43
44
  /** Optional icon-size class override (default: `text-[0.9rem]`). */
44
45
  iconClass = input('text-[0.9rem]', ...(ngDevMode ? [{ debugName: "iconClass" }] : /* istanbul ignore next */ []));
45
46
  buttonClass = TOOLBAR_BUTTON_CLASS;
46
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaToolbarButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
47
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: QalmaToolbarButton, isStandalone: true, selector: "qalma-toolbar-button", inputs: { command: { classPropertyName: "command", publicName: "command", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, iconClass: { classPropertyName: "iconClass", publicName: "iconClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: `
47
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaToolbarButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
48
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.22", type: QalmaToolbarButton, isStandalone: true, selector: "qalma-toolbar-button", inputs: { command: { classPropertyName: "command", publicName: "command", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, iconClass: { classPropertyName: "iconClass", publicName: "iconClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: `
48
49
  <button
49
50
  type="button"
50
51
  [qalmaCommand]="command()"
@@ -57,7 +58,7 @@ class QalmaToolbarButton {
57
58
  </button>
58
59
  `, isInline: true, dependencies: [{ kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: QalmaCommand, selector: "button[qalmaCommand]", inputs: ["qalmaCommand", "qalmaCommandValue"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
59
60
  }
60
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaToolbarButton, decorators: [{
61
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaToolbarButton, decorators: [{
61
62
  type: Component,
62
63
  args: [{
63
64
  selector: 'qalma-toolbar-button',
@@ -218,8 +219,8 @@ class QalmaToolbarRegistry {
218
219
  asTemplate(item) {
219
220
  return item.template;
220
221
  }
221
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaToolbarRegistry, deps: [], target: i0.ɵɵFactoryTarget.Component });
222
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: QalmaToolbarRegistry, isStandalone: true, selector: "qalma-toolbar-registry", inputs: { groups: { classPropertyName: "groups", publicName: "groups", isSignal: true, isRequired: true, transformFunction: null }, separatorClass: { classPropertyName: "separatorClass", publicName: "separatorClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: `
222
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaToolbarRegistry, deps: [], target: i0.ɵɵFactoryTarget.Component });
223
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: QalmaToolbarRegistry, isStandalone: true, selector: "qalma-toolbar-registry", inputs: { groups: { classPropertyName: "groups", publicName: "groups", isSignal: true, isRequired: true, transformFunction: null }, separatorClass: { classPropertyName: "separatorClass", publicName: "separatorClass", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "contents" }, ngImport: i0, template: `
223
224
  @for (group of visibleGroups(); track $index; let first = $first) {
224
225
  @if (!first) {
225
226
  <span [class]="separatorClass()" aria-hidden="true"></span>
@@ -239,7 +240,7 @@ class QalmaToolbarRegistry {
239
240
  }
240
241
  `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: QalmaToolbarButton, selector: "qalma-toolbar-button", inputs: ["command", "value", "icon", "label", "iconClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
241
242
  }
242
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaToolbarRegistry, decorators: [{
243
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaToolbarRegistry, decorators: [{
243
244
  type: Component,
244
245
  args: [{
245
246
  selector: 'qalma-toolbar-registry',
@@ -357,10 +358,10 @@ class QalmaButton {
357
358
  variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
358
359
  size = input('default', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
359
360
  computedClass = computed(() => cn(buttonVariants({ variant: this.variant(), size: this.size() }), this.initialClass), ...(ngDevMode ? [{ debugName: "computedClass" }] : /* istanbul ignore next */ []));
360
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaButton, deps: [], target: i0.ɵɵFactoryTarget.Directive });
361
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.17", type: QalmaButton, isStandalone: true, selector: "button[qalmaBtn], a[qalmaBtn]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "computedClass()" } }, ngImport: i0 });
361
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaButton, deps: [], target: i0.ɵɵFactoryTarget.Directive });
362
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.22", type: QalmaButton, isStandalone: true, selector: "button[qalmaBtn], a[qalmaBtn]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "computedClass()" } }, ngImport: i0 });
362
363
  }
363
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaButton, decorators: [{
364
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaButton, decorators: [{
364
365
  type: Directive,
365
366
  args: [{
366
367
  selector: 'button[qalmaBtn], a[qalmaBtn]',
@@ -415,8 +416,8 @@ class QalmaDragHandle {
415
416
  this.menuOpen.set(false);
416
417
  this.dismiss.emit();
417
418
  }
418
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaDragHandle, deps: [], target: i0.ɵɵFactoryTarget.Component });
419
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: QalmaDragHandle, isStandalone: true, selector: "qalma-drag-handle", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, handle: { classPropertyName: "handle", publicName: "handle", isSignal: true, isRequired: false, transformFunction: null }, dropIndicator: { classPropertyName: "dropIndicator", publicName: "dropIndicator", isSignal: true, isRequired: false, transformFunction: null }, draggedBlockHighlight: { classPropertyName: "draggedBlockHighlight", publicName: "draggedBlockHighlight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismiss: "dismiss", dragStart: "dragStart" }, providers: [
419
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaDragHandle, deps: [], target: i0.ɵɵFactoryTarget.Component });
420
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: QalmaDragHandle, isStandalone: true, selector: "qalma-drag-handle", inputs: { editor: { classPropertyName: "editor", publicName: "editor", isSignal: true, isRequired: true, transformFunction: null }, handle: { classPropertyName: "handle", publicName: "handle", isSignal: true, isRequired: false, transformFunction: null }, dropIndicator: { classPropertyName: "dropIndicator", publicName: "dropIndicator", isSignal: true, isRequired: false, transformFunction: null }, draggedBlockHighlight: { classPropertyName: "draggedBlockHighlight", publicName: "draggedBlockHighlight", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismiss: "dismiss", dragStart: "dragStart" }, providers: [
420
421
  provideIcons({
421
422
  lucideArrowDown,
422
423
  lucideArrowUp,
@@ -542,7 +543,7 @@ class QalmaDragHandle {
542
543
  }
543
544
  `, isInline: true, dependencies: [{ kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: QalmaButton, selector: "button[qalmaBtn], a[qalmaBtn]", inputs: ["variant", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
544
545
  }
545
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaDragHandle, decorators: [{
546
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaDragHandle, decorators: [{
546
547
  type: Component,
547
548
  args: [{
548
549
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -687,8 +688,8 @@ class QalmaMentionMenu extends QalmaSuggestionMenu {
687
688
  suggestions = input([], ...(ngDevMode ? [{ debugName: "suggestions" }] : /* istanbul ignore next */ []));
688
689
  loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
689
690
  optionList = this.suggestions;
690
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaMentionMenu, deps: null, target: i0.ɵɵFactoryTarget.Component });
691
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: QalmaMentionMenu, isStandalone: true, selector: "qalma-mention-menu", inputs: { suggestions: { classPropertyName: "suggestions", publicName: "suggestions", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
691
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaMentionMenu, deps: null, target: i0.ɵɵFactoryTarget.Component });
692
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: QalmaMentionMenu, isStandalone: true, selector: "qalma-mention-menu", inputs: { suggestions: { classPropertyName: "suggestions", publicName: "suggestions", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
692
693
  @if (placement(); as placement) {
693
694
  <div
694
695
  role="listbox"
@@ -765,7 +766,7 @@ class QalmaMentionMenu extends QalmaSuggestionMenu {
765
766
  }
766
767
  `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
767
768
  }
768
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaMentionMenu, decorators: [{
769
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaMentionMenu, decorators: [{
769
770
  type: Component,
770
771
  args: [{
771
772
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -867,8 +868,8 @@ class QalmaSlashCommandMenu extends QalmaSuggestionMenu {
867
868
  queueMicrotask(() => this.scrollOptionIntoView(activeIndex));
868
869
  });
869
870
  }
870
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaSlashCommandMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
871
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: QalmaSlashCommandMenu, isStandalone: true, selector: "qalma-slash-command-menu", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
871
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaSlashCommandMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
872
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: QalmaSlashCommandMenu, isStandalone: true, selector: "qalma-slash-command-menu", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
872
873
  provideIcons({
873
874
  lucideCode,
874
875
  lucideHeading1,
@@ -965,7 +966,7 @@ class QalmaSlashCommandMenu extends QalmaSuggestionMenu {
965
966
  }
966
967
  `, isInline: true, dependencies: [{ kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
967
968
  }
968
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaSlashCommandMenu, decorators: [{
969
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaSlashCommandMenu, decorators: [{
969
970
  type: Component,
970
971
  args: [{
971
972
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -1087,8 +1088,8 @@ class QalmaLinkPopover {
1087
1088
  this.hrefChange.emit(target.value);
1088
1089
  }
1089
1090
  }
1090
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaLinkPopover, deps: [], target: i0.ɵɵFactoryTarget.Component });
1091
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: QalmaLinkPopover, isStandalone: true, selector: "qalma-link-popover", inputs: { popover: { classPropertyName: "popover", publicName: "popover", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { hrefChange: "hrefChange", edit: "edit", save: "save", remove: "remove", dismiss: "dismiss", keepOpen: "keepOpen", scheduleHide: "scheduleHide" }, providers: [
1091
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaLinkPopover, deps: [], target: i0.ɵɵFactoryTarget.Component });
1092
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: QalmaLinkPopover, isStandalone: true, selector: "qalma-link-popover", inputs: { popover: { classPropertyName: "popover", publicName: "popover", isSignal: true, isRequired: false, transformFunction: null }, href: { classPropertyName: "href", publicName: "href", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { hrefChange: "hrefChange", edit: "edit", save: "save", remove: "remove", dismiss: "dismiss", keepOpen: "keepOpen", scheduleHide: "scheduleHide" }, providers: [
1092
1093
  provideIcons({
1093
1094
  lucideCheck,
1094
1095
  lucideExternalLink,
@@ -1199,7 +1200,7 @@ class QalmaLinkPopover {
1199
1200
  }
1200
1201
  `, isInline: true, dependencies: [{ kind: "component", type: NgIcon, selector: "ng-icon", inputs: ["name", "svg", "size", "strokeWidth", "color"] }, { kind: "directive", type: QalmaButton, selector: "button[qalmaBtn], a[qalmaBtn]", inputs: ["variant", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1201
1202
  }
1202
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaLinkPopover, decorators: [{
1203
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaLinkPopover, decorators: [{
1203
1204
  type: Component,
1204
1205
  args: [{
1205
1206
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -1354,8 +1355,8 @@ class QalmaContextualToolbar {
1354
1355
  event.preventDefault();
1355
1356
  this.dismiss.emit();
1356
1357
  }
1357
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaContextualToolbar, deps: [], target: i0.ɵɵFactoryTarget.Component });
1358
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: QalmaContextualToolbar, isStandalone: true, selector: "qalma-contextual-toolbar", inputs: { placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismiss: "dismiss" }, ngImport: i0, template: `
1358
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaContextualToolbar, deps: [], target: i0.ɵɵFactoryTarget.Component });
1359
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.22", type: QalmaContextualToolbar, isStandalone: true, selector: "qalma-contextual-toolbar", inputs: { placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismiss: "dismiss" }, ngImport: i0, template: `
1359
1360
  @if (placement(); as placement) {
1360
1361
  <qalma-toolbar
1361
1362
  [label]="label()"
@@ -1369,7 +1370,7 @@ class QalmaContextualToolbar {
1369
1370
  }
1370
1371
  `, isInline: true, dependencies: [{ kind: "component", type: QalmaToolbar, selector: "qalma-toolbar", inputs: ["label"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1371
1372
  }
1372
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: QalmaContextualToolbar, decorators: [{
1373
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.22", ngImport: i0, type: QalmaContextualToolbar, decorators: [{
1373
1374
  type: Component,
1374
1375
  args: [{
1375
1376
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -1 +1 @@
1
- {"version":3,"file":"qalma-kit.mjs","sources":["../../../../libs/ui-kit/src/lib/toolbar-button.ts","../../../../libs/ui-kit/src/lib/toolbar-commands.ts","../../../../libs/ui-kit/src/lib/toolbar-registry.ts","../../../../libs/ui-kit/src/lib/toolbar-icons.ts","../../../../libs/ui-kit/src/lib/cn.ts","../../../../libs/ui-kit/src/lib/button.ts","../../../../libs/ui-kit/src/lib/drag-handle.ts","../../../../libs/ui-kit/src/lib/mention-menu.ts","../../../../libs/ui-kit/src/lib/slash-command-menu.ts","../../../../libs/ui-kit/src/lib/link-popover.ts","../../../../libs/ui-kit/src/lib/contextual-toolbar.ts","../../../../libs/ui-kit/src/index.ts","../../../../libs/ui-kit/src/qalma-kit.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { NgIcon } from '@ng-icons/core';\nimport { QalmaCommand } from '@qalma/editor';\n\n/**\n * Default styling for a toolbar command button. Icon-only, square, and driven\n * entirely by the host's shadcn-style design tokens (`text-muted-foreground`,\n * `bg-secondary`, `bg-accent-subtle`…) so it themes with the surrounding app.\n * The `qalma-command-active` class is toggled by the `QalmaCommand` directive\n * when the underlying command is active.\n */\nexport const TOOLBAR_BUTTON_CLASS =\n 'inline-flex h-[1.85rem] w-[1.85rem] cursor-pointer items-center justify-center rounded-[0.4rem] border border-transparent text-muted-foreground transition hover:bg-secondary hover:text-foreground disabled:cursor-not-allowed disabled:opacity-45 [&.qalma-command-active]:border-accent/40 [&.qalma-command-active]:bg-accent-subtle [&.qalma-command-active]:text-accent';\n\n/**\n * Generic, declarative toolbar button for a single editor command.\n *\n * Renders a native `<button>` wired to the `QalmaCommand` directive (execute /\n * active / disabled / aria) with an `<ng-icon>`, so a whole toolbar becomes a\n * list of `<qalma-toolbar-button command icon label />` instead of the\n * six-line `<button qalmaCommand><ng-icon></button>` block repeated per\n * command. The host uses `display: contents` so the inner button participates\n * directly in the surrounding toolbar's flex layout.\n *\n * Icons resolve from the `NgIcon` provider scope of the surrounding component\n * (register them with `provideIcons({ … })` as usual).\n */\n@Component({\n selector: 'qalma-toolbar-button',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgIcon, QalmaCommand],\n host: {\n class: 'contents',\n },\n template: `\n <button\n type=\"button\"\n [qalmaCommand]=\"command()\"\n [qalmaCommandValue]=\"value()\"\n [class]=\"buttonClass\"\n [title]=\"label()\"\n [attr.aria-label]=\"label()\"\n >\n <ng-icon [class]=\"iconClass()\" [name]=\"icon()\" aria-hidden=\"true\" />\n </button>\n `,\n})\nexport class QalmaToolbarButton {\n /** Command name to execute, e.g. `toggleBold`. */\n readonly command = input.required<string>();\n /** Optional command payload (forwarded to `qalmaCommandValue`). */\n readonly value = input<unknown>();\n /** Lucide (or any registered) icon name, e.g. `lucideBold`. */\n readonly icon = input.required<string>();\n /** Accessible name — used for both `title` and `aria-label`. */\n readonly label = input.required<string>();\n /** Optional icon-size class override (default: `text-[0.9rem]`). */\n readonly iconClass = input('text-[0.9rem]');\n\n protected readonly buttonClass = TOOLBAR_BUTTON_CLASS;\n}\n","import type { TemplateRef } from '@angular/core';\n\n/**\n * A single command button in a toolbar registry: which editor command to run,\n * which icon to show, and its accessible label. `value` is forwarded to the\n * command as its payload when present.\n */\nexport interface ToolbarCommandItem {\n readonly command: string;\n readonly icon: string;\n readonly label: string;\n readonly value?: unknown;\n}\n\n/**\n * An escape hatch for controls that are not a plain command button (color\n * pickers, upload buttons, a language `<select>`…). The consumer supplies an\n * `<ng-template>` and the toolbar renders it inline at this position.\n */\nexport interface ToolbarTemplateItem {\n readonly template: TemplateRef<unknown>;\n}\n\nexport type ToolbarItem = ToolbarCommandItem | ToolbarTemplateItem;\n\n/** One separator-delimited run of items. Empty groups render nothing. */\nexport type ToolbarGroup = readonly ToolbarItem[];\n\nexport function isToolbarCommandItem(\n item: ToolbarItem,\n): item is ToolbarCommandItem {\n return 'command' in item;\n}\n\n// ---------------------------------------------------------------------------\n// Default command fragments — the declarative source of truth for the standard\n// editor toolbar, reusable across consumers (playground, sandbox, downstream\n// apps). Compose them into `ToolbarGroup[]` and hand them to\n// `<qalma-toolbar-registry>`; interleave custom controls with `ToolbarTemplateItem`.\n// ---------------------------------------------------------------------------\n\nexport const QALMA_TOOLBAR_HEADINGS: readonly ToolbarCommandItem[] = [\n { command: 'setParagraph', icon: 'lucidePilcrow', label: 'Paragraph' },\n { command: 'toggleHeading1', icon: 'lucideHeading1', label: 'Heading 1' },\n { command: 'toggleHeading2', icon: 'lucideHeading2', label: 'Heading 2' },\n { command: 'toggleHeading3', icon: 'lucideHeading3', label: 'Heading 3' },\n];\n\nexport const QALMA_TOOLBAR_INLINE_MARKS: readonly ToolbarCommandItem[] = [\n { command: 'toggleBold', icon: 'lucideBold', label: 'Bold' },\n { command: 'toggleItalic', icon: 'lucideItalic', label: 'Italic' },\n { command: 'toggleUnderline', icon: 'lucideUnderline', label: 'Underline' },\n {\n command: 'toggleStrike',\n icon: 'lucideStrikethrough',\n label: 'Strikethrough',\n },\n { command: 'toggleInlineCode', icon: 'lucideCode', label: 'Inline code' },\n { command: 'toggleMonospace', icon: 'lucideLetterText', label: 'Monospace' },\n { command: 'toggleSubscript', icon: 'lucideSubscript', label: 'Subscript' },\n {\n command: 'toggleSuperscript',\n icon: 'lucideSuperscript',\n label: 'Superscript',\n },\n];\n\nexport const QALMA_TOOLBAR_ALIGN: readonly ToolbarCommandItem[] = [\n { command: 'setTextAlignLeft', icon: 'lucideAlignLeft', label: 'Align left' },\n {\n command: 'setTextAlignCenter',\n icon: 'lucideAlignCenter',\n label: 'Align center',\n },\n {\n command: 'setTextAlignRight',\n icon: 'lucideAlignRight',\n label: 'Align right',\n },\n {\n command: 'setTextAlignJustify',\n icon: 'lucideAlignJustify',\n label: 'Justify',\n },\n];\n\nexport const QALMA_TOOLBAR_LISTS: readonly ToolbarCommandItem[] = [\n { command: 'toggleBulletList', icon: 'lucideList', label: 'Bullet list' },\n {\n command: 'toggleOrderedList',\n icon: 'lucideListOrdered',\n label: 'Ordered list',\n },\n { command: 'toggleTaskList', icon: 'lucideListTodo', label: 'Task list' },\n { command: 'liftListItem', icon: 'lucideOutdent', label: 'Outdent' },\n { command: 'sinkListItem', icon: 'lucideIndent', label: 'Indent' },\n { command: 'toggleBlockquote', icon: 'lucideTextQuote', label: 'Blockquote' },\n { command: 'toggleCodeBlock', icon: 'lucideSquareCode', label: 'Code block' },\n];\n\n/** Always-available table entry point (inserting a new table). */\nexport const QALMA_TOOLBAR_TABLE_INSERT: ToolbarCommandItem = {\n command: 'insertTable',\n icon: 'lucideTable',\n label: 'Insert table',\n};\n\n/** Table editing commands — only meaningful while the selection is in a table. */\nexport const QALMA_TOOLBAR_TABLE_OPS: readonly ToolbarCommandItem[] = [\n {\n command: 'addRowAfter',\n icon: 'lucideBetweenHorizontalEnd',\n label: 'Add row',\n },\n {\n command: 'addColumnAfter',\n icon: 'lucideBetweenVerticalEnd',\n label: 'Add column',\n },\n { command: 'deleteRow', icon: 'lucideRows3', label: 'Delete row' },\n { command: 'deleteColumn', icon: 'lucideColumns3', label: 'Delete column' },\n {\n command: 'toggleHeaderRow',\n icon: 'lucideHeading',\n label: 'Toggle header row',\n },\n { command: 'deleteTable', icon: 'lucideTrash2', label: 'Delete table' },\n];\n\nexport const QALMA_TOOLBAR_HISTORY: readonly ToolbarCommandItem[] = [\n { command: 'undo', icon: 'lucideUndo2', label: 'Undo' },\n { command: 'redo', icon: 'lucideRedo2', label: 'Redo' },\n];\n\n/** Standalone command that usually sits alongside the color controls. */\nexport const QALMA_TOOLBAR_CLEAR_FORMATTING: ToolbarCommandItem = {\n command: 'clearFormatting',\n icon: 'lucideEraser',\n label: 'Clear formatting',\n};\n\n/** Standalone command that usually sits alongside the link/insert controls. */\nexport const QALMA_TOOLBAR_UNSET_LINK: ToolbarCommandItem = {\n command: 'unsetLink',\n icon: 'lucideUnlink',\n label: 'Unlink',\n};\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n TemplateRef,\n computed,\n input,\n} from '@angular/core';\n\nimport { QalmaToolbarButton } from './toolbar-button';\nimport {\n ToolbarCommandItem,\n ToolbarGroup,\n ToolbarItem,\n ToolbarTemplateItem,\n isToolbarCommandItem,\n} from './toolbar-commands';\n\n/** Vertical divider rendered between non-empty toolbar groups. */\nexport const TOOLBAR_SEPARATOR_CLASS =\n 'mx-0.5 h-5 w-px shrink-0 self-center bg-border';\n\n/**\n * Renders a declarative toolbar registry: an ordered list of groups, each a\n * list of command buttons and/or inline custom-control templates, with a\n * separator drawn between non-empty groups.\n *\n * Meant to sit inside the editor's `<qalma-toolbar>` (which owns the\n * `role=\"toolbar\"` semantics); the host uses `display: contents` so the\n * rendered buttons participate directly in that container's flex layout.\n *\n * ```html\n * <qalma-toolbar class=\"flex …\">\n * <ng-template #colors> … custom controls … </ng-template>\n * <qalma-toolbar-registry [groups]=\"[headings, marks, [{ template: colors }]]\" />\n * </qalma-toolbar>\n * ```\n */\n@Component({\n selector: 'qalma-toolbar-registry',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet, QalmaToolbarButton],\n host: {\n class: 'contents',\n },\n template: `\n @for (group of visibleGroups(); track $index; let first = $first) {\n @if (!first) {\n <span [class]=\"separatorClass()\" aria-hidden=\"true\"></span>\n }\n @for (item of group; track $index) {\n @if (asCommand(item); as command) {\n <qalma-toolbar-button\n [command]=\"command.command\"\n [value]=\"command.value\"\n [icon]=\"command.icon\"\n [label]=\"command.label\"\n />\n } @else {\n <ng-container [ngTemplateOutlet]=\"asTemplate(item)\" />\n }\n }\n }\n `,\n})\nexport class QalmaToolbarRegistry {\n readonly groups = input.required<readonly ToolbarGroup[]>();\n readonly separatorClass = input(TOOLBAR_SEPARATOR_CLASS);\n\n /** Drop empty groups so they neither render content nor a dangling separator. */\n protected readonly visibleGroups = computed(() =>\n this.groups().filter((group) => group.length > 0),\n );\n\n protected asCommand(item: ToolbarItem): ToolbarCommandItem | null {\n return isToolbarCommandItem(item) ? item : null;\n }\n\n protected asTemplate(item: ToolbarItem): TemplateRef<unknown> {\n return (item as ToolbarTemplateItem).template;\n }\n}\n","import { provideIcons } from '@ng-icons/core';\nimport {\n lucideAlignCenter,\n lucideAlignJustify,\n lucideAlignLeft,\n lucideAlignRight,\n lucideBetweenHorizontalEnd,\n lucideBetweenVerticalEnd,\n lucideBold,\n lucideCode,\n lucideColumns3,\n lucideEraser,\n lucideHeading,\n lucideHeading1,\n lucideHeading2,\n lucideHeading3,\n lucideIndent,\n lucideItalic,\n lucideLetterText,\n lucideList,\n lucideListOrdered,\n lucideListTodo,\n lucideOutdent,\n lucidePilcrow,\n lucideRedo2,\n lucideRows3,\n lucideSquareCode,\n lucideStrikethrough,\n lucideSubscript,\n lucideSuperscript,\n lucideTable,\n lucideTextQuote,\n lucideTrash2,\n lucideUnderline,\n lucideUndo2,\n lucideUnlink,\n} from '@ng-icons/lucide';\n\n/**\n * Registers the Lucide icons referenced by the default toolbar command\n * fragments (`QALMA_TOOLBAR_*`), so consumers can wire the standard toolbar\n * without re-declaring the icon set:\n *\n * ```ts\n * providers: [provideQalmaToolbarIcons()]\n * ```\n *\n * Add your own `provideIcons({ … })` alongside it for any custom controls\n * (color pickers, upload buttons…) that live outside the command registry.\n */\nexport function provideQalmaToolbarIcons() {\n return provideIcons({\n lucideAlignCenter,\n lucideAlignJustify,\n lucideAlignLeft,\n lucideAlignRight,\n lucideBetweenHorizontalEnd,\n lucideBetweenVerticalEnd,\n lucideBold,\n lucideCode,\n lucideColumns3,\n lucideEraser,\n lucideHeading,\n lucideHeading1,\n lucideHeading2,\n lucideHeading3,\n lucideIndent,\n lucideItalic,\n lucideLetterText,\n lucideList,\n lucideListOrdered,\n lucideListTodo,\n lucideOutdent,\n lucidePilcrow,\n lucideRedo2,\n lucideRows3,\n lucideSquareCode,\n lucideStrikethrough,\n lucideSubscript,\n lucideSuperscript,\n lucideTable,\n lucideTextQuote,\n lucideTrash2,\n lucideUnderline,\n lucideUndo2,\n lucideUnlink,\n });\n}\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import { Directive, ElementRef, computed, inject, input } from '@angular/core';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from './cn';\n\nexport const buttonVariants = cva(\n 'inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 [&_ng-icon]:shrink-0',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n outline:\n 'border border-border bg-card text-foreground hover:bg-secondary hover:text-secondary-foreground',\n ghost:\n 'text-foreground hover:bg-secondary hover:text-secondary-foreground',\n accent: 'bg-accent text-accent-foreground hover:bg-accent/90',\n link: 'text-accent underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-11 rounded-md px-6 text-base',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nexport type ButtonVariant = NonNullable<\n VariantProps<typeof buttonVariants>['variant']\n>;\nexport type ButtonSize = NonNullable<\n VariantProps<typeof buttonVariants>['size']\n>;\n\n/**\n * Headless-styled button directive so it composes onto native `<button>` and\n * `<a>` elements while reading from the host's Tailwind design tokens.\n */\n@Directive({\n selector: 'button[qalmaBtn], a[qalmaBtn]',\n host: {\n '[class]': 'computedClass()',\n },\n})\nexport class QalmaButton {\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly initialClass =\n this.host.nativeElement.getAttribute('class') ?? '';\n\n readonly variant = input<ButtonVariant>('default');\n readonly size = input<ButtonSize>('default');\n\n protected readonly computedClass = computed(() =>\n cn(\n buttonVariants({ variant: this.variant(), size: this.size() }),\n this.initialClass,\n ),\n );\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { QalmaEditorController } from '@qalma/editor';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport {\n lucideArrowDown,\n lucideArrowUp,\n lucideCopy,\n lucideGripVertical,\n lucideMousePointer2,\n lucideTrash2,\n} from '@ng-icons/lucide';\n\nimport {\n DismissibleOverlay,\n QalmaDragBlockHighlight,\n QalmaDragDropIndicator,\n QalmaDragHandleView,\n} from '@qalma/kit/headless';\n\nimport { QalmaButton } from './button';\n\nexport interface QalmaDragStart {\n event: PointerEvent;\n handle: QalmaDragHandleView;\n}\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgIcon, QalmaButton],\n providers: [\n provideIcons({\n lucideArrowDown,\n lucideArrowUp,\n lucideCopy,\n lucideGripVertical,\n lucideMousePointer2,\n lucideTrash2,\n }),\n ],\n selector: 'qalma-drag-handle',\n template: `\n @if (draggedBlockHighlight(); as highlight) {\n <div\n data-qalma-dragging-block-highlight\n class=\"pointer-events-none fixed left-0 top-0 z-20 rounded-md border border-accent bg-accent-subtle/80 opacity-70 shadow-md will-change-transform\"\n [style.transform]=\"highlight.transform\"\n [style.width.px]=\"highlight.width\"\n [style.height.px]=\"highlight.height\"\n ></div>\n }\n\n @if (dropIndicator(); as indicator) {\n <div\n data-qalma-drag-drop-line\n class=\"pointer-events-none fixed left-0 top-0 z-40 h-0.5 rounded-full bg-accent shadow-md will-change-transform\"\n [style.transform]=\"indicator.transform\"\n [style.width.px]=\"indicator.width\"\n ></div>\n }\n\n @if (handle(); as handle) {\n <div\n data-qalma-drag-handle\n class=\"fixed left-0 top-0 z-30 flex items-start gap-1 will-change-transform\"\n tabindex=\"-1\"\n [style.transform]=\"handle.transform\"\n (mousedown)=\"preserveSelection($event)\"\n (keydown.escape)=\"dismissFromKeyboard($event)\"\n >\n <button\n qalmaBtn\n variant=\"ghost\"\n size=\"icon\"\n type=\"button\"\n class=\"!h-[1.85rem] !w-[1.85rem] cursor-grab rounded-[0.4rem] border border-transparent bg-card/95 text-muted-foreground shadow-sm active:cursor-grabbing hover:border-border hover:bg-secondary hover:text-foreground\"\n [class.border-accent]=\"menuOpen()\"\n [class.text-accent]=\"menuOpen()\"\n (pointerdown)=\"startDrag($event, handle)\"\n (click)=\"toggleMenu()\"\n title=\"Block actions\"\n aria-label=\"Block actions\"\n [attr.aria-expanded]=\"menuOpen()\"\n >\n <ng-icon\n class=\"text-[0.9rem]\"\n name=\"lucideGripVertical\"\n aria-hidden=\"true\"\n />\n </button>\n\n @if (menuOpen()) {\n <div\n role=\"menu\"\n aria-label=\"Block actions\"\n class=\"w-44 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg\"\n >\n <button\n type=\"button\"\n class=\"flex h-8 w-full cursor-pointer items-center gap-2 rounded-sm px-2 text-left text-xs font-medium text-foreground transition hover:bg-secondary disabled:cursor-not-allowed disabled:opacity-45\"\n [disabled]=\"!canExecute('selectBlock', handle)\"\n (mousedown)=\"preserveSelection($event)\"\n (click)=\"execute('selectBlock', handle)\"\n role=\"menuitem\"\n >\n <ng-icon name=\"lucideMousePointer2\" aria-hidden=\"true\" />\n Select block\n </button>\n <button\n type=\"button\"\n class=\"flex h-8 w-full cursor-pointer items-center gap-2 rounded-sm px-2 text-left text-xs font-medium text-foreground transition hover:bg-secondary disabled:cursor-not-allowed disabled:opacity-45\"\n [disabled]=\"!handle.canMoveUp\"\n (mousedown)=\"preserveSelection($event)\"\n (click)=\"execute('moveBlockUp', handle)\"\n role=\"menuitem\"\n >\n <ng-icon name=\"lucideArrowUp\" aria-hidden=\"true\" />\n Move up\n </button>\n <button\n type=\"button\"\n class=\"flex h-8 w-full cursor-pointer items-center gap-2 rounded-sm px-2 text-left text-xs font-medium text-foreground transition hover:bg-secondary disabled:cursor-not-allowed disabled:opacity-45\"\n [disabled]=\"!handle.canMoveDown\"\n (mousedown)=\"preserveSelection($event)\"\n (click)=\"execute('moveBlockDown', handle)\"\n role=\"menuitem\"\n >\n <ng-icon name=\"lucideArrowDown\" aria-hidden=\"true\" />\n Move down\n </button>\n <button\n type=\"button\"\n class=\"flex h-8 w-full cursor-pointer items-center gap-2 rounded-sm px-2 text-left text-xs font-medium text-foreground transition hover:bg-secondary disabled:cursor-not-allowed disabled:opacity-45\"\n [disabled]=\"!canExecute('duplicateBlock', handle)\"\n (mousedown)=\"preserveSelection($event)\"\n (click)=\"execute('duplicateBlock', handle)\"\n role=\"menuitem\"\n >\n <ng-icon name=\"lucideCopy\" aria-hidden=\"true\" />\n Duplicate\n </button>\n <button\n type=\"button\"\n class=\"flex h-8 w-full cursor-pointer items-center gap-2 rounded-sm px-2 text-left text-xs font-medium text-destructive transition hover:bg-destructive/10 disabled:cursor-not-allowed disabled:opacity-45\"\n [disabled]=\"!canExecute('deleteBlock', handle)\"\n (mousedown)=\"preserveSelection($event)\"\n (click)=\"execute('deleteBlock', handle)\"\n role=\"menuitem\"\n >\n <ng-icon name=\"lucideTrash2\" aria-hidden=\"true\" />\n Delete\n </button>\n </div>\n }\n </div>\n }\n `,\n})\nexport class QalmaDragHandle {\n readonly editor = input.required<QalmaEditorController>();\n readonly handle = input<QalmaDragHandleView | null>(null);\n readonly dropIndicator = input<QalmaDragDropIndicator | null>(null);\n readonly draggedBlockHighlight = input<QalmaDragBlockHighlight | null>(\n null,\n );\n readonly dismiss = output<void>();\n readonly dragStart = output<QalmaDragStart>();\n\n protected readonly menuOpen = signal(false);\n\n constructor() {\n // Close the block-actions menu on an outside pointerdown or Escape. A click\n // on the handle button or the menu itself (both under `[data-qalma-drag-handle]`)\n // is treated as inside, so it doesn't self-dismiss. Connected for the\n // component's lifetime; the callback is a no-op while the menu is closed.\n new DismissibleOverlay({\n isInside: (target) =>\n target instanceof Element &&\n !!target.closest('[data-qalma-drag-handle]'),\n onDismiss: () => this.menuOpen.set(false),\n }).connect(inject(DestroyRef));\n }\n\n protected toggleMenu(): void {\n this.menuOpen.update((open) => !open);\n }\n\n protected startDrag(\n event: PointerEvent,\n handle: QalmaDragHandleView,\n ): void {\n this.menuOpen.set(false);\n this.dragStart.emit({ event, handle });\n }\n\n protected canExecute(\n command: string,\n handle: QalmaDragHandleView,\n ): boolean {\n return this.editor().canExecute(command, handle.target);\n }\n\n protected execute(command: string, handle: QalmaDragHandleView): void {\n if (this.editor().execute(command, handle.target)) {\n this.dismissHandle();\n }\n }\n\n protected preserveSelection(event: MouseEvent): void {\n event.preventDefault();\n }\n\n protected dismissFromKeyboard(event: Event): void {\n event.preventDefault();\n this.dismissHandle();\n }\n\n protected dismissHandle(): void {\n this.menuOpen.set(false);\n this.dismiss.emit();\n }\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\nimport { QalmaSuggestionMenu } from '@qalma/kit/headless';\n\nexport interface QalmaMentionOption {\n readonly id: string;\n readonly label: string;\n readonly description: string;\n}\n\n/**\n * Caret-anchored mention suggestion menu: an avatar-initial list with a loading\n * state. Positioning, keyboard handling and active highlighting come from\n * {@link QalmaSuggestionMenu}; feed it a `placement` (see `flipAbovePlacement`)\n * and the filtered `suggestions`.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'qalma-mention-menu',\n template: `\n @if (placement(); as placement) {\n <div\n role=\"listbox\"\n aria-label=\"Mention suggestions\"\n class=\"fixed z-20 w-[min(280px,calc(100vw-24px))] overflow-hidden rounded-md border border-border bg-popover p-1 text-sm text-popover-foreground shadow-lg outline-none\"\n [style.left.px]=\"placement.left\"\n [style.top.px]=\"placement.top\"\n [style.bottom.px]=\"placement.bottom\"\n [style.max-height.px]=\"placement.maxHeight\"\n >\n @if (loading()) {\n <div\n class=\"flex items-center gap-2 px-2 py-2 text-sm text-muted-foreground\"\n >\n <span\n class=\"size-7 animate-pulse rounded-sm border border-border bg-secondary\"\n aria-hidden=\"true\"\n ></span>\n <span>Loading…</span>\n </div>\n } @else {\n <div class=\"max-h-full overflow-y-auto\">\n @for (\n option of suggestions();\n track option.id;\n let index = $index\n ) {\n <button\n type=\"button\"\n role=\"option\"\n [attr.data-suggestion-index]=\"index\"\n class=\"group grid h-12 w-full min-w-0 cursor-pointer grid-cols-[1.75rem_minmax(0,1fr)] items-center gap-2 rounded-sm px-2 text-left transition-colors hover:bg-accent-subtle hover:text-foreground focus:bg-accent-subtle focus:text-foreground focus:outline-none\"\n [class.bg-accent-subtle]=\"index === activeIndex()\"\n [class.text-foreground]=\"index === activeIndex()\"\n [attr.aria-selected]=\"index === activeIndex()\"\n [attr.tabindex]=\"index === activeIndex() ? 0 : -1\"\n (mouseenter)=\"activate.emit(index)\"\n (mousedown)=\"preserveSelection($event)\"\n (keydown)=\"handleOptionKeydown($event, option, index)\"\n (click)=\"pick.emit(option)\"\n >\n <span\n class=\"flex size-7 items-center justify-center rounded-sm border border-border bg-card text-xs font-semibold text-foreground\"\n [class.border-accent]=\"index === activeIndex()\"\n [class.bg-background]=\"index === activeIndex()\"\n [class.text-accent]=\"index === activeIndex()\"\n aria-hidden=\"true\"\n >\n {{ option.label.slice(0, 1) }}\n </span>\n <span class=\"min-w-0\">\n <span class=\"block truncate font-medium leading-5\">{{\n option.label\n }}</span>\n @if (index === activeIndex()) {\n <span\n class=\"block truncate text-xs leading-4 text-foreground\"\n >\n {{ option.description }}\n </span>\n } @else {\n <span\n class=\"block truncate text-xs leading-4 text-muted-foreground group-hover:text-foreground group-focus:text-foreground\"\n >\n {{ option.description }}\n </span>\n }\n </span>\n </button>\n }\n </div>\n }\n </div>\n }\n `,\n})\nexport class QalmaMentionMenu extends QalmaSuggestionMenu<QalmaMentionOption> {\n readonly suggestions = input<readonly QalmaMentionOption[]>([]);\n readonly loading = input(false);\n\n protected readonly optionList = this.suggestions;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n effect,\n input,\n} from '@angular/core';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport {\n lucideCode,\n lucideHeading1,\n lucideHeading2,\n lucideHeading3,\n lucideList,\n lucideListOrdered,\n lucideListTodo,\n lucideMinus,\n lucidePilcrow,\n lucideSquareCode,\n lucideTable,\n lucideTextQuote,\n} from '@ng-icons/lucide';\nimport { QalmaCommandValue } from '@qalma/editor';\n\nimport { QalmaSuggestionMenu } from '@qalma/kit/headless';\n\nexport interface QalmaSlashCommandOption {\n readonly id: string;\n readonly label: string;\n readonly description: string;\n readonly icon: string;\n readonly shortcut: string;\n /** Editor command to run when the option is picked. */\n readonly command: string;\n readonly value?: QalmaCommandValue;\n readonly placement?: 'block' | 'inline';\n /** Extra terms the consumer can match against when filtering. */\n readonly keywords: readonly string[];\n}\n\n/**\n * Caret-anchored slash-command menu: an icon + shortcut list with a \"Commands\"\n * header and an Escape hint footer, scrolling the active option into view.\n * Positioning, keyboard handling and active highlighting come from\n * {@link QalmaSuggestionMenu}; feed it a `placement` (see `flipAbovePlacement`)\n * and the filtered `options`. Ships the default block-command icon set.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgIcon],\n providers: [\n provideIcons({\n lucideCode,\n lucideHeading1,\n lucideHeading2,\n lucideHeading3,\n lucideList,\n lucideListOrdered,\n lucideListTodo,\n lucideMinus,\n lucidePilcrow,\n lucideSquareCode,\n lucideTable,\n lucideTextQuote,\n }),\n ],\n selector: 'qalma-slash-command-menu',\n template: `\n @if (placement(); as placement) {\n <div\n role=\"listbox\"\n aria-label=\"Slash command suggestions\"\n class=\"fixed z-20 flex w-[min(320px,calc(100vw-24px))] flex-col overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg outline-none\"\n [style.left.px]=\"placement.left\"\n [style.top.px]=\"placement.top\"\n [style.bottom.px]=\"placement.bottom\"\n [style.max-height.px]=\"placement.maxHeight\"\n >\n <div\n class=\"shrink-0 px-2 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\"\n >\n Commands\n </div>\n <div data-suggestion-options class=\"min-h-0 flex-1 overflow-y-auto\">\n @for (option of options(); track option.id; let index = $index) {\n <button\n type=\"button\"\n role=\"option\"\n [attr.data-suggestion-index]=\"index\"\n class=\"group grid h-11 w-full min-w-0 cursor-pointer grid-cols-[1.75rem_minmax(0,1fr)_auto] items-center gap-2 rounded-sm px-2 text-left text-sm transition-colors hover:bg-accent-subtle hover:text-foreground focus:bg-accent-subtle focus:text-foreground focus:outline-none\"\n [class.bg-accent-subtle]=\"index === activeIndex()\"\n [class.text-foreground]=\"index === activeIndex()\"\n [attr.aria-selected]=\"index === activeIndex()\"\n [attr.tabindex]=\"index === activeIndex() ? 0 : -1\"\n (mouseenter)=\"activate.emit(index)\"\n (mousedown)=\"preserveSelection($event)\"\n (keydown)=\"handleOptionKeydown($event, option, index)\"\n (click)=\"pick.emit(option)\"\n >\n <span\n class=\"flex size-7 items-center justify-center rounded-sm border border-border bg-card text-[14px] text-foreground\"\n [class.border-accent]=\"index === activeIndex()\"\n [class.bg-background]=\"index === activeIndex()\"\n [class.text-accent]=\"index === activeIndex()\"\n >\n <ng-icon [name]=\"option.icon\" aria-hidden=\"true\" />\n </span>\n <span class=\"min-w-0\">\n <span class=\"block truncate font-medium leading-5\">{{\n option.label\n }}</span>\n @if (index === activeIndex()) {\n <span\n class=\"block truncate text-xs leading-4 text-foreground\"\n >\n {{ option.description }}\n </span>\n } @else {\n <span\n class=\"block truncate text-xs leading-4 text-muted-foreground group-hover:text-foreground group-focus:text-foreground\"\n >\n {{ option.description }}\n </span>\n }\n </span>\n <kbd\n class=\"rounded-sm border border-border bg-card px-1.5 py-0.5 font-mono text-[11px] text-muted-foreground\"\n [class.border-accent]=\"index === activeIndex()\"\n [class.bg-background]=\"index === activeIndex()\"\n [class.text-accent]=\"index === activeIndex()\"\n >\n {{ option.shortcut }}\n </kbd>\n </button>\n }\n </div>\n <div\n class=\"mt-1 flex h-8 shrink-0 items-center justify-between border-t border-border px-2 text-[11px] text-muted-foreground\"\n >\n <span>Close menu</span>\n <kbd\n class=\"rounded-sm border border-border bg-card px-1.5 py-0.5 font-mono\"\n >esc</kbd\n >\n </div>\n </div>\n }\n `,\n})\nexport class QalmaSlashCommandMenu extends QalmaSuggestionMenu<QalmaSlashCommandOption> {\n readonly options = input<readonly QalmaSlashCommandOption[]>([]);\n\n protected readonly optionList = this.options;\n\n constructor() {\n super();\n\n effect(() => {\n const activeIndex = this.activeIndex();\n\n this.options();\n queueMicrotask(() => this.scrollOptionIntoView(activeIndex));\n });\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n input,\n output,\n} from '@angular/core';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport {\n lucideCheck,\n lucideExternalLink,\n lucideLink,\n lucidePencil,\n lucideUnlink,\n lucideX,\n} from '@ng-icons/lucide';\n\nimport { LinkPopover } from '@qalma/kit/headless';\n\nimport { QalmaButton } from './button';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgIcon, QalmaButton],\n providers: [\n provideIcons({\n lucideCheck,\n lucideExternalLink,\n lucideLink,\n lucidePencil,\n lucideUnlink,\n lucideX,\n }),\n ],\n selector: 'qalma-link-popover',\n template: `\n @if (popover(); as popover) {\n <div\n data-qalma-link-popover\n role=\"dialog\"\n aria-label=\"Link preview\"\n class=\"fixed z-20 w-[min(360px,calc(100vw-32px))] rounded-md border border-border bg-popover p-1.5 text-sm text-popover-foreground shadow-lg outline-none\"\n [style.left.px]=\"popover.left\"\n [style.top.px]=\"popover.top\"\n (mouseenter)=\"keepOpen.emit()\"\n (mouseleave)=\"scheduleHide.emit()\"\n (focusin)=\"keepOpen.emit()\"\n (focusout)=\"scheduleHide.emit()\"\n >\n @if (popover.editing) {\n <div class=\"flex items-center gap-1.5\">\n <label\n class=\"flex h-9 min-w-0 flex-1 items-center gap-2 rounded-md border border-input bg-background px-2 text-sm transition focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/30\"\n >\n <ng-icon\n class=\"shrink-0 text-muted-foreground\"\n name=\"lucideLink\"\n aria-hidden=\"true\"\n />\n <input\n class=\"min-w-0 flex-1 bg-transparent text-foreground outline-none placeholder:text-muted-foreground\"\n type=\"url\"\n aria-label=\"Edit link URL\"\n [value]=\"href()\"\n (input)=\"updateHref($event)\"\n />\n </label>\n <button\n qalmaBtn\n size=\"icon\"\n type=\"button\"\n [disabled]=\"!href().trim()\"\n (click)=\"save.emit(popover)\"\n title=\"Save link\"\n aria-label=\"Save link\"\n >\n <ng-icon name=\"lucideCheck\" aria-hidden=\"true\" />\n </button>\n <button\n qalmaBtn\n variant=\"outline\"\n size=\"icon\"\n type=\"button\"\n (click)=\"dismiss.emit()\"\n title=\"Cancel\"\n aria-label=\"Cancel\"\n >\n <ng-icon name=\"lucideX\" aria-hidden=\"true\" />\n </button>\n </div>\n } @else {\n <div class=\"flex items-center gap-1.5\">\n <a\n class=\"inline-flex h-9 min-w-0 flex-1 items-center gap-1.5 rounded-md border border-border bg-card px-2.5 text-accent transition-colors hover:bg-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n [href]=\"popover.href\"\n [target]=\"popover.target ?? '_blank'\"\n [rel]=\"popover.rel ?? 'noopener noreferrer'\"\n title=\"Open link\"\n >\n <span class=\"min-w-0 truncate font-medium\">{{\n popover.href\n }}</span>\n <ng-icon\n class=\"shrink-0 text-base\"\n name=\"lucideExternalLink\"\n aria-hidden=\"true\"\n />\n </a>\n <button\n qalmaBtn\n variant=\"outline\"\n size=\"icon\"\n type=\"button\"\n (click)=\"edit.emit(popover)\"\n title=\"Edit link\"\n aria-label=\"Edit link\"\n >\n <ng-icon name=\"lucidePencil\" aria-hidden=\"true\" />\n </button>\n <button\n qalmaBtn\n variant=\"ghost\"\n size=\"icon\"\n type=\"button\"\n class=\"text-destructive hover:bg-destructive/10 hover:text-destructive\"\n (click)=\"remove.emit(popover)\"\n title=\"Unlink\"\n aria-label=\"Unlink\"\n >\n <ng-icon name=\"lucideUnlink\" aria-hidden=\"true\" />\n </button>\n </div>\n }\n </div>\n }\n `,\n})\nexport class QalmaLinkPopover {\n readonly popover = input<LinkPopover | null>(null);\n readonly href = input.required<string>();\n\n readonly hrefChange = output<string>();\n readonly edit = output<LinkPopover>();\n readonly save = output<LinkPopover>();\n readonly remove = output<LinkPopover>();\n readonly dismiss = output<void>();\n readonly keepOpen = output<void>();\n readonly scheduleHide = output<void>();\n\n protected updateHref(event: Event): void {\n const target = event.target;\n\n if (target instanceof HTMLInputElement) {\n this.hrefChange.emit(target.value);\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n input,\n output,\n} from '@angular/core';\nimport { QalmaToolbar } from '@qalma/editor';\n\nimport { QalmaContextualToolbarPlacement } from '@qalma/kit/headless';\n\n/**\n * Floating, selection-anchored toolbar container. It owns the hard parts — the\n * fixed-position `transform` from a {@link QalmaContextualToolbarPlacement}\n * (see `QalmaSelectionToolbarDirective`), preserving the editor selection on\n * pointer-down, and Escape-to-dismiss — and projects whatever controls you put\n * inside it. Nothing about the button set is baked in: compose\n * `<qalma-toolbar-button>` for commands and your own buttons for app actions\n * (opening a link editor, a color picker, an AI action…).\n *\n * The container's `mousedown` handler preserves the selection for every\n * projected control via event bubbling, so inner buttons don't each need to.\n *\n * ```html\n * <qalma-contextual-toolbar\n * [placement]=\"selection.placement()\"\n * (dismiss)=\"selection.hide()\"\n * >\n * <qalma-toolbar-button command=\"toggleBold\" icon=\"lucideBold\" label=\"Bold\" />\n * <qalma-toolbar-button command=\"toggleItalic\" icon=\"lucideItalic\" label=\"Italic\" />\n * <button type=\"button\" [class]=\"TOOLBAR_BUTTON_CLASS\" (click)=\"openLinkEditor()\">…</button>\n * </qalma-contextual-toolbar>\n * ```\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [QalmaToolbar],\n selector: 'qalma-contextual-toolbar',\n template: `\n @if (placement(); as placement) {\n <qalma-toolbar\n [label]=\"label()\"\n class=\"fixed left-0 top-0 z-30 flex items-center gap-0.5 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg will-change-transform\"\n [style.transform]=\"placement.transform\"\n (mousedown)=\"preserveSelection($event)\"\n (keydown.escape)=\"dismissFromKeyboard($event)\"\n >\n <ng-content />\n </qalma-toolbar>\n }\n `,\n})\nexport class QalmaContextualToolbar {\n readonly placement = input<QalmaContextualToolbarPlacement | null>(null);\n /** Accessible name for the toolbar region. */\n readonly label = input('Selection formatting');\n readonly dismiss = output<void>();\n\n protected preserveSelection(event: MouseEvent): void {\n event.preventDefault();\n }\n\n protected dismissFromKeyboard(event: Event): void {\n event.preventDefault();\n this.dismiss.emit();\n }\n}\n","// @qalma/kit — Tailwind/shadcn-flavored UI for the Qalma editor.\n//\n// This entry point is the styled tier: components that pull `cva` + `@ng-icons`\n// and read the host's design tokens. It re-exports the entire dependency-free\n// `@qalma/kit/headless` surface (controllers, geometry, keyboard nav) so it\n// stays a superset — bring-your-own-design-system consumers can import the\n// leaner `@qalma/kit/headless` directly instead.\n//\n// The internal `QalmaButton` directive and `cn()` helper are intentionally NOT\n// exported: a host already has a button and a class-merge utility in its design\n// system. They remain private implementation details of the styled components.\nexport * from '@qalma/kit/headless';\n\n// Toolbar\nexport * from './lib/toolbar-button';\nexport * from './lib/toolbar-commands';\nexport * from './lib/toolbar-registry';\nexport * from './lib/toolbar-icons';\n\n// Editor surface components\nexport * from './lib/drag-handle';\nexport * from './lib/mention-menu';\nexport * from './lib/slash-command-menu';\nexport * from './lib/link-popover';\nexport * from './lib/contextual-toolbar';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"qalma-kit.mjs","sources":["../../../../libs/ui-kit/src/lib/toolbar-button.ts","../../../../libs/ui-kit/src/lib/toolbar-commands.ts","../../../../libs/ui-kit/src/lib/toolbar-registry.ts","../../../../libs/ui-kit/src/lib/toolbar-icons.ts","../../../../libs/ui-kit/src/lib/cn.ts","../../../../libs/ui-kit/src/lib/button.ts","../../../../libs/ui-kit/src/lib/drag-handle.ts","../../../../libs/ui-kit/src/lib/mention-menu.ts","../../../../libs/ui-kit/src/lib/slash-command-menu.ts","../../../../libs/ui-kit/src/lib/link-popover.ts","../../../../libs/ui-kit/src/lib/contextual-toolbar.ts","../../../../libs/ui-kit/src/index.ts","../../../../libs/ui-kit/src/qalma-kit.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { NgIcon } from '@ng-icons/core';\nimport { QalmaCommand } from '@qalma/editor';\n\n/**\n * Default styling for a toolbar command button. Icon-only, square, and driven\n * entirely by the host's shadcn-style design tokens (`text-muted-foreground`,\n * `bg-card`, `bg-secondary`, `bg-accent-subtle`…) so it themes with the\n * surrounding app.\n * The `qalma-command-active` class is toggled by the `QalmaCommand` directive\n * when the underlying command is active.\n */\nexport const TOOLBAR_BUTTON_CLASS =\n 'inline-flex h-[1.85rem] w-[1.85rem] cursor-pointer items-center justify-center rounded-[0.4rem] border border-border bg-card text-muted-foreground transition hover:border-accent/50 hover:bg-secondary hover:text-foreground disabled:cursor-not-allowed disabled:opacity-45 [&.qalma-command-active]:border-accent/40 [&.qalma-command-active]:bg-accent-subtle [&.qalma-command-active]:text-accent';\n\n/**\n * Generic, declarative toolbar button for a single editor command.\n *\n * Renders a native `<button>` wired to the `QalmaCommand` directive (execute /\n * active / disabled / aria) with an `<ng-icon>`, so a whole toolbar becomes a\n * list of `<qalma-toolbar-button command icon label />` instead of the\n * six-line `<button qalmaCommand><ng-icon></button>` block repeated per\n * command. The host uses `display: contents` so the inner button participates\n * directly in the surrounding toolbar's flex layout.\n *\n * Icons resolve from the `NgIcon` provider scope of the surrounding component\n * (register them with `provideIcons({ … })` as usual).\n */\n@Component({\n selector: 'qalma-toolbar-button',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgIcon, QalmaCommand],\n host: {\n class: 'contents',\n },\n template: `\n <button\n type=\"button\"\n [qalmaCommand]=\"command()\"\n [qalmaCommandValue]=\"value()\"\n [class]=\"buttonClass\"\n [title]=\"label()\"\n [attr.aria-label]=\"label()\"\n >\n <ng-icon [class]=\"iconClass()\" [name]=\"icon()\" aria-hidden=\"true\" />\n </button>\n `,\n})\nexport class QalmaToolbarButton {\n /** Command name to execute, e.g. `toggleBold`. */\n readonly command = input.required<string>();\n /** Optional command payload (forwarded to `qalmaCommandValue`). */\n readonly value = input<unknown>();\n /** Lucide (or any registered) icon name, e.g. `lucideBold`. */\n readonly icon = input.required<string>();\n /** Accessible name — used for both `title` and `aria-label`. */\n readonly label = input.required<string>();\n /** Optional icon-size class override (default: `text-[0.9rem]`). */\n readonly iconClass = input('text-[0.9rem]');\n\n protected readonly buttonClass = TOOLBAR_BUTTON_CLASS;\n}\n","import type { TemplateRef } from '@angular/core';\n\n/**\n * A single command button in a toolbar registry: which editor command to run,\n * which icon to show, and its accessible label. `value` is forwarded to the\n * command as its payload when present.\n */\nexport interface ToolbarCommandItem {\n readonly command: string;\n readonly icon: string;\n readonly label: string;\n readonly value?: unknown;\n}\n\n/**\n * An escape hatch for controls that are not a plain command button (color\n * pickers, upload buttons, a language `<select>`…). The consumer supplies an\n * `<ng-template>` and the toolbar renders it inline at this position.\n */\nexport interface ToolbarTemplateItem {\n readonly template: TemplateRef<unknown>;\n}\n\nexport type ToolbarItem = ToolbarCommandItem | ToolbarTemplateItem;\n\n/** One separator-delimited run of items. Empty groups render nothing. */\nexport type ToolbarGroup = readonly ToolbarItem[];\n\nexport function isToolbarCommandItem(\n item: ToolbarItem,\n): item is ToolbarCommandItem {\n return 'command' in item;\n}\n\n// ---------------------------------------------------------------------------\n// Default command fragments — the declarative source of truth for the standard\n// editor toolbar, reusable across consumers (playground, sandbox, downstream\n// apps). Compose them into `ToolbarGroup[]` and hand them to\n// `<qalma-toolbar-registry>`; interleave custom controls with `ToolbarTemplateItem`.\n// ---------------------------------------------------------------------------\n\nexport const QALMA_TOOLBAR_HEADINGS: readonly ToolbarCommandItem[] = [\n { command: 'setParagraph', icon: 'lucidePilcrow', label: 'Paragraph' },\n { command: 'toggleHeading1', icon: 'lucideHeading1', label: 'Heading 1' },\n { command: 'toggleHeading2', icon: 'lucideHeading2', label: 'Heading 2' },\n { command: 'toggleHeading3', icon: 'lucideHeading3', label: 'Heading 3' },\n];\n\nexport const QALMA_TOOLBAR_INLINE_MARKS: readonly ToolbarCommandItem[] = [\n { command: 'toggleBold', icon: 'lucideBold', label: 'Bold' },\n { command: 'toggleItalic', icon: 'lucideItalic', label: 'Italic' },\n { command: 'toggleUnderline', icon: 'lucideUnderline', label: 'Underline' },\n {\n command: 'toggleStrike',\n icon: 'lucideStrikethrough',\n label: 'Strikethrough',\n },\n { command: 'toggleInlineCode', icon: 'lucideCode', label: 'Inline code' },\n { command: 'toggleMonospace', icon: 'lucideLetterText', label: 'Monospace' },\n { command: 'toggleSubscript', icon: 'lucideSubscript', label: 'Subscript' },\n {\n command: 'toggleSuperscript',\n icon: 'lucideSuperscript',\n label: 'Superscript',\n },\n];\n\nexport const QALMA_TOOLBAR_ALIGN: readonly ToolbarCommandItem[] = [\n { command: 'setTextAlignLeft', icon: 'lucideAlignLeft', label: 'Align left' },\n {\n command: 'setTextAlignCenter',\n icon: 'lucideAlignCenter',\n label: 'Align center',\n },\n {\n command: 'setTextAlignRight',\n icon: 'lucideAlignRight',\n label: 'Align right',\n },\n {\n command: 'setTextAlignJustify',\n icon: 'lucideAlignJustify',\n label: 'Justify',\n },\n];\n\nexport const QALMA_TOOLBAR_LISTS: readonly ToolbarCommandItem[] = [\n { command: 'toggleBulletList', icon: 'lucideList', label: 'Bullet list' },\n {\n command: 'toggleOrderedList',\n icon: 'lucideListOrdered',\n label: 'Ordered list',\n },\n { command: 'toggleTaskList', icon: 'lucideListTodo', label: 'Task list' },\n { command: 'liftListItem', icon: 'lucideOutdent', label: 'Outdent' },\n { command: 'sinkListItem', icon: 'lucideIndent', label: 'Indent' },\n { command: 'toggleBlockquote', icon: 'lucideTextQuote', label: 'Blockquote' },\n { command: 'toggleCodeBlock', icon: 'lucideSquareCode', label: 'Code block' },\n];\n\n/** Always-available table entry point (inserting a new table). */\nexport const QALMA_TOOLBAR_TABLE_INSERT: ToolbarCommandItem = {\n command: 'insertTable',\n icon: 'lucideTable',\n label: 'Insert table',\n};\n\n/** Table editing commands — only meaningful while the selection is in a table. */\nexport const QALMA_TOOLBAR_TABLE_OPS: readonly ToolbarCommandItem[] = [\n {\n command: 'addRowAfter',\n icon: 'lucideBetweenHorizontalEnd',\n label: 'Add row',\n },\n {\n command: 'addColumnAfter',\n icon: 'lucideBetweenVerticalEnd',\n label: 'Add column',\n },\n { command: 'deleteRow', icon: 'lucideRows3', label: 'Delete row' },\n { command: 'deleteColumn', icon: 'lucideColumns3', label: 'Delete column' },\n {\n command: 'toggleHeaderRow',\n icon: 'lucideHeading',\n label: 'Toggle header row',\n },\n { command: 'deleteTable', icon: 'lucideTrash2', label: 'Delete table' },\n];\n\nexport const QALMA_TOOLBAR_HISTORY: readonly ToolbarCommandItem[] = [\n { command: 'undo', icon: 'lucideUndo2', label: 'Undo' },\n { command: 'redo', icon: 'lucideRedo2', label: 'Redo' },\n];\n\n/** Standalone command that usually sits alongside the color controls. */\nexport const QALMA_TOOLBAR_CLEAR_FORMATTING: ToolbarCommandItem = {\n command: 'clearFormatting',\n icon: 'lucideEraser',\n label: 'Clear formatting',\n};\n\n/** Standalone command that usually sits alongside the link/insert controls. */\nexport const QALMA_TOOLBAR_UNSET_LINK: ToolbarCommandItem = {\n command: 'unsetLink',\n icon: 'lucideUnlink',\n label: 'Unlink',\n};\n","import { NgTemplateOutlet } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n TemplateRef,\n computed,\n input,\n} from '@angular/core';\n\nimport { QalmaToolbarButton } from './toolbar-button';\nimport {\n ToolbarCommandItem,\n ToolbarGroup,\n ToolbarItem,\n ToolbarTemplateItem,\n isToolbarCommandItem,\n} from './toolbar-commands';\n\n/** Vertical divider rendered between non-empty toolbar groups. */\nexport const TOOLBAR_SEPARATOR_CLASS =\n 'mx-0.5 h-5 w-px shrink-0 self-center bg-border';\n\n/**\n * Renders a declarative toolbar registry: an ordered list of groups, each a\n * list of command buttons and/or inline custom-control templates, with a\n * separator drawn between non-empty groups.\n *\n * Meant to sit inside the editor's `<qalma-toolbar>` (which owns the\n * `role=\"toolbar\"` semantics); the host uses `display: contents` so the\n * rendered buttons participate directly in that container's flex layout.\n *\n * ```html\n * <qalma-toolbar class=\"flex …\">\n * <ng-template #colors> … custom controls … </ng-template>\n * <qalma-toolbar-registry [groups]=\"[headings, marks, [{ template: colors }]]\" />\n * </qalma-toolbar>\n * ```\n */\n@Component({\n selector: 'qalma-toolbar-registry',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgTemplateOutlet, QalmaToolbarButton],\n host: {\n class: 'contents',\n },\n template: `\n @for (group of visibleGroups(); track $index; let first = $first) {\n @if (!first) {\n <span [class]=\"separatorClass()\" aria-hidden=\"true\"></span>\n }\n @for (item of group; track $index) {\n @if (asCommand(item); as command) {\n <qalma-toolbar-button\n [command]=\"command.command\"\n [value]=\"command.value\"\n [icon]=\"command.icon\"\n [label]=\"command.label\"\n />\n } @else {\n <ng-container [ngTemplateOutlet]=\"asTemplate(item)\" />\n }\n }\n }\n `,\n})\nexport class QalmaToolbarRegistry {\n readonly groups = input.required<readonly ToolbarGroup[]>();\n readonly separatorClass = input(TOOLBAR_SEPARATOR_CLASS);\n\n /** Drop empty groups so they neither render content nor a dangling separator. */\n protected readonly visibleGroups = computed(() =>\n this.groups().filter((group) => group.length > 0),\n );\n\n protected asCommand(item: ToolbarItem): ToolbarCommandItem | null {\n return isToolbarCommandItem(item) ? item : null;\n }\n\n protected asTemplate(item: ToolbarItem): TemplateRef<unknown> {\n return (item as ToolbarTemplateItem).template;\n }\n}\n","import { provideIcons } from '@ng-icons/core';\nimport {\n lucideAlignCenter,\n lucideAlignJustify,\n lucideAlignLeft,\n lucideAlignRight,\n lucideBetweenHorizontalEnd,\n lucideBetweenVerticalEnd,\n lucideBold,\n lucideCode,\n lucideColumns3,\n lucideEraser,\n lucideHeading,\n lucideHeading1,\n lucideHeading2,\n lucideHeading3,\n lucideIndent,\n lucideItalic,\n lucideLetterText,\n lucideList,\n lucideListOrdered,\n lucideListTodo,\n lucideOutdent,\n lucidePilcrow,\n lucideRedo2,\n lucideRows3,\n lucideSquareCode,\n lucideStrikethrough,\n lucideSubscript,\n lucideSuperscript,\n lucideTable,\n lucideTextQuote,\n lucideTrash2,\n lucideUnderline,\n lucideUndo2,\n lucideUnlink,\n} from '@ng-icons/lucide';\n\n/**\n * Registers the Lucide icons referenced by the default toolbar command\n * fragments (`QALMA_TOOLBAR_*`), so consumers can wire the standard toolbar\n * without re-declaring the icon set:\n *\n * ```ts\n * providers: [provideQalmaToolbarIcons()]\n * ```\n *\n * Add your own `provideIcons({ … })` alongside it for any custom controls\n * (color pickers, upload buttons…) that live outside the command registry.\n */\nexport function provideQalmaToolbarIcons() {\n return provideIcons({\n lucideAlignCenter,\n lucideAlignJustify,\n lucideAlignLeft,\n lucideAlignRight,\n lucideBetweenHorizontalEnd,\n lucideBetweenVerticalEnd,\n lucideBold,\n lucideCode,\n lucideColumns3,\n lucideEraser,\n lucideHeading,\n lucideHeading1,\n lucideHeading2,\n lucideHeading3,\n lucideIndent,\n lucideItalic,\n lucideLetterText,\n lucideList,\n lucideListOrdered,\n lucideListTodo,\n lucideOutdent,\n lucidePilcrow,\n lucideRedo2,\n lucideRows3,\n lucideSquareCode,\n lucideStrikethrough,\n lucideSubscript,\n lucideSuperscript,\n lucideTable,\n lucideTextQuote,\n lucideTrash2,\n lucideUnderline,\n lucideUndo2,\n lucideUnlink,\n });\n}\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","import { Directive, ElementRef, computed, inject, input } from '@angular/core';\nimport { cva, type VariantProps } from 'class-variance-authority';\n\nimport { cn } from './cn';\n\nexport const buttonVariants = cva(\n 'inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50 [&_ng-icon]:shrink-0',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n secondary:\n 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n outline:\n 'border border-border bg-card text-foreground hover:bg-secondary hover:text-secondary-foreground',\n ghost:\n 'text-foreground hover:bg-secondary hover:text-secondary-foreground',\n accent: 'bg-accent text-accent-foreground hover:bg-accent/90',\n link: 'text-accent underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-9 px-4 py-2',\n sm: 'h-8 rounded-md px-3 text-xs',\n lg: 'h-11 rounded-md px-6 text-base',\n icon: 'h-9 w-9',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nexport type ButtonVariant = NonNullable<\n VariantProps<typeof buttonVariants>['variant']\n>;\nexport type ButtonSize = NonNullable<\n VariantProps<typeof buttonVariants>['size']\n>;\n\n/**\n * Headless-styled button directive so it composes onto native `<button>` and\n * `<a>` elements while reading from the host's Tailwind design tokens.\n */\n@Directive({\n selector: 'button[qalmaBtn], a[qalmaBtn]',\n host: {\n '[class]': 'computedClass()',\n },\n})\nexport class QalmaButton {\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly initialClass =\n this.host.nativeElement.getAttribute('class') ?? '';\n\n readonly variant = input<ButtonVariant>('default');\n readonly size = input<ButtonSize>('default');\n\n protected readonly computedClass = computed(() =>\n cn(\n buttonVariants({ variant: this.variant(), size: this.size() }),\n this.initialClass,\n ),\n );\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n inject,\n input,\n output,\n signal,\n} from '@angular/core';\nimport { QalmaEditorController } from '@qalma/editor';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport {\n lucideArrowDown,\n lucideArrowUp,\n lucideCopy,\n lucideGripVertical,\n lucideMousePointer2,\n lucideTrash2,\n} from '@ng-icons/lucide';\n\nimport {\n DismissibleOverlay,\n QalmaDragBlockHighlight,\n QalmaDragDropIndicator,\n QalmaDragHandleView,\n} from '@qalma/kit/headless';\n\nimport { QalmaButton } from './button';\n\nexport interface QalmaDragStart {\n event: PointerEvent;\n handle: QalmaDragHandleView;\n}\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgIcon, QalmaButton],\n providers: [\n provideIcons({\n lucideArrowDown,\n lucideArrowUp,\n lucideCopy,\n lucideGripVertical,\n lucideMousePointer2,\n lucideTrash2,\n }),\n ],\n selector: 'qalma-drag-handle',\n template: `\n @if (draggedBlockHighlight(); as highlight) {\n <div\n data-qalma-dragging-block-highlight\n class=\"pointer-events-none fixed left-0 top-0 z-20 rounded-md border border-accent bg-accent-subtle/80 opacity-70 shadow-md will-change-transform\"\n [style.transform]=\"highlight.transform\"\n [style.width.px]=\"highlight.width\"\n [style.height.px]=\"highlight.height\"\n ></div>\n }\n\n @if (dropIndicator(); as indicator) {\n <div\n data-qalma-drag-drop-line\n class=\"pointer-events-none fixed left-0 top-0 z-40 h-0.5 rounded-full bg-accent shadow-md will-change-transform\"\n [style.transform]=\"indicator.transform\"\n [style.width.px]=\"indicator.width\"\n ></div>\n }\n\n @if (handle(); as handle) {\n <div\n data-qalma-drag-handle\n class=\"fixed left-0 top-0 z-30 flex items-start gap-1 will-change-transform\"\n tabindex=\"-1\"\n [style.transform]=\"handle.transform\"\n (mousedown)=\"preserveSelection($event)\"\n (keydown.escape)=\"dismissFromKeyboard($event)\"\n >\n <button\n qalmaBtn\n variant=\"ghost\"\n size=\"icon\"\n type=\"button\"\n class=\"!h-[1.85rem] !w-[1.85rem] cursor-grab rounded-[0.4rem] border border-transparent bg-card/95 text-muted-foreground shadow-sm active:cursor-grabbing hover:border-border hover:bg-secondary hover:text-foreground\"\n [class.border-accent]=\"menuOpen()\"\n [class.text-accent]=\"menuOpen()\"\n (pointerdown)=\"startDrag($event, handle)\"\n (click)=\"toggleMenu()\"\n title=\"Block actions\"\n aria-label=\"Block actions\"\n [attr.aria-expanded]=\"menuOpen()\"\n >\n <ng-icon\n class=\"text-[0.9rem]\"\n name=\"lucideGripVertical\"\n aria-hidden=\"true\"\n />\n </button>\n\n @if (menuOpen()) {\n <div\n role=\"menu\"\n aria-label=\"Block actions\"\n class=\"w-44 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg\"\n >\n <button\n type=\"button\"\n class=\"flex h-8 w-full cursor-pointer items-center gap-2 rounded-sm px-2 text-left text-xs font-medium text-foreground transition hover:bg-secondary disabled:cursor-not-allowed disabled:opacity-45\"\n [disabled]=\"!canExecute('selectBlock', handle)\"\n (mousedown)=\"preserveSelection($event)\"\n (click)=\"execute('selectBlock', handle)\"\n role=\"menuitem\"\n >\n <ng-icon name=\"lucideMousePointer2\" aria-hidden=\"true\" />\n Select block\n </button>\n <button\n type=\"button\"\n class=\"flex h-8 w-full cursor-pointer items-center gap-2 rounded-sm px-2 text-left text-xs font-medium text-foreground transition hover:bg-secondary disabled:cursor-not-allowed disabled:opacity-45\"\n [disabled]=\"!handle.canMoveUp\"\n (mousedown)=\"preserveSelection($event)\"\n (click)=\"execute('moveBlockUp', handle)\"\n role=\"menuitem\"\n >\n <ng-icon name=\"lucideArrowUp\" aria-hidden=\"true\" />\n Move up\n </button>\n <button\n type=\"button\"\n class=\"flex h-8 w-full cursor-pointer items-center gap-2 rounded-sm px-2 text-left text-xs font-medium text-foreground transition hover:bg-secondary disabled:cursor-not-allowed disabled:opacity-45\"\n [disabled]=\"!handle.canMoveDown\"\n (mousedown)=\"preserveSelection($event)\"\n (click)=\"execute('moveBlockDown', handle)\"\n role=\"menuitem\"\n >\n <ng-icon name=\"lucideArrowDown\" aria-hidden=\"true\" />\n Move down\n </button>\n <button\n type=\"button\"\n class=\"flex h-8 w-full cursor-pointer items-center gap-2 rounded-sm px-2 text-left text-xs font-medium text-foreground transition hover:bg-secondary disabled:cursor-not-allowed disabled:opacity-45\"\n [disabled]=\"!canExecute('duplicateBlock', handle)\"\n (mousedown)=\"preserveSelection($event)\"\n (click)=\"execute('duplicateBlock', handle)\"\n role=\"menuitem\"\n >\n <ng-icon name=\"lucideCopy\" aria-hidden=\"true\" />\n Duplicate\n </button>\n <button\n type=\"button\"\n class=\"flex h-8 w-full cursor-pointer items-center gap-2 rounded-sm px-2 text-left text-xs font-medium text-destructive transition hover:bg-destructive/10 disabled:cursor-not-allowed disabled:opacity-45\"\n [disabled]=\"!canExecute('deleteBlock', handle)\"\n (mousedown)=\"preserveSelection($event)\"\n (click)=\"execute('deleteBlock', handle)\"\n role=\"menuitem\"\n >\n <ng-icon name=\"lucideTrash2\" aria-hidden=\"true\" />\n Delete\n </button>\n </div>\n }\n </div>\n }\n `,\n})\nexport class QalmaDragHandle {\n readonly editor = input.required<QalmaEditorController>();\n readonly handle = input<QalmaDragHandleView | null>(null);\n readonly dropIndicator = input<QalmaDragDropIndicator | null>(null);\n readonly draggedBlockHighlight = input<QalmaDragBlockHighlight | null>(\n null,\n );\n readonly dismiss = output<void>();\n readonly dragStart = output<QalmaDragStart>();\n\n protected readonly menuOpen = signal(false);\n\n constructor() {\n // Close the block-actions menu on an outside pointerdown or Escape. A click\n // on the handle button or the menu itself (both under `[data-qalma-drag-handle]`)\n // is treated as inside, so it doesn't self-dismiss. Connected for the\n // component's lifetime; the callback is a no-op while the menu is closed.\n new DismissibleOverlay({\n isInside: (target) =>\n target instanceof Element &&\n !!target.closest('[data-qalma-drag-handle]'),\n onDismiss: () => this.menuOpen.set(false),\n }).connect(inject(DestroyRef));\n }\n\n protected toggleMenu(): void {\n this.menuOpen.update((open) => !open);\n }\n\n protected startDrag(\n event: PointerEvent,\n handle: QalmaDragHandleView,\n ): void {\n this.menuOpen.set(false);\n this.dragStart.emit({ event, handle });\n }\n\n protected canExecute(\n command: string,\n handle: QalmaDragHandleView,\n ): boolean {\n return this.editor().canExecute(command, handle.target);\n }\n\n protected execute(command: string, handle: QalmaDragHandleView): void {\n if (this.editor().execute(command, handle.target)) {\n this.dismissHandle();\n }\n }\n\n protected preserveSelection(event: MouseEvent): void {\n event.preventDefault();\n }\n\n protected dismissFromKeyboard(event: Event): void {\n event.preventDefault();\n this.dismissHandle();\n }\n\n protected dismissHandle(): void {\n this.menuOpen.set(false);\n this.dismiss.emit();\n }\n}\n","import { ChangeDetectionStrategy, Component, input } from '@angular/core';\n\nimport { QalmaSuggestionMenu } from '@qalma/kit/headless';\n\nexport interface QalmaMentionOption {\n readonly id: string;\n readonly label: string;\n readonly description: string;\n}\n\n/**\n * Caret-anchored mention suggestion menu: an avatar-initial list with a loading\n * state. Positioning, keyboard handling and active highlighting come from\n * {@link QalmaSuggestionMenu}; feed it a `placement` (see `flipAbovePlacement`)\n * and the filtered `suggestions`.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n selector: 'qalma-mention-menu',\n template: `\n @if (placement(); as placement) {\n <div\n role=\"listbox\"\n aria-label=\"Mention suggestions\"\n class=\"fixed z-20 w-[min(280px,calc(100vw-24px))] overflow-hidden rounded-md border border-border bg-popover p-1 text-sm text-popover-foreground shadow-lg outline-none\"\n [style.left.px]=\"placement.left\"\n [style.top.px]=\"placement.top\"\n [style.bottom.px]=\"placement.bottom\"\n [style.max-height.px]=\"placement.maxHeight\"\n >\n @if (loading()) {\n <div\n class=\"flex items-center gap-2 px-2 py-2 text-sm text-muted-foreground\"\n >\n <span\n class=\"size-7 animate-pulse rounded-sm border border-border bg-secondary\"\n aria-hidden=\"true\"\n ></span>\n <span>Loading…</span>\n </div>\n } @else {\n <div class=\"max-h-full overflow-y-auto\">\n @for (\n option of suggestions();\n track option.id;\n let index = $index\n ) {\n <button\n type=\"button\"\n role=\"option\"\n [attr.data-suggestion-index]=\"index\"\n class=\"group grid h-12 w-full min-w-0 cursor-pointer grid-cols-[1.75rem_minmax(0,1fr)] items-center gap-2 rounded-sm px-2 text-left transition-colors hover:bg-accent-subtle hover:text-foreground focus:bg-accent-subtle focus:text-foreground focus:outline-none\"\n [class.bg-accent-subtle]=\"index === activeIndex()\"\n [class.text-foreground]=\"index === activeIndex()\"\n [attr.aria-selected]=\"index === activeIndex()\"\n [attr.tabindex]=\"index === activeIndex() ? 0 : -1\"\n (mouseenter)=\"activate.emit(index)\"\n (mousedown)=\"preserveSelection($event)\"\n (keydown)=\"handleOptionKeydown($event, option, index)\"\n (click)=\"pick.emit(option)\"\n >\n <span\n class=\"flex size-7 items-center justify-center rounded-sm border border-border bg-card text-xs font-semibold text-foreground\"\n [class.border-accent]=\"index === activeIndex()\"\n [class.bg-background]=\"index === activeIndex()\"\n [class.text-accent]=\"index === activeIndex()\"\n aria-hidden=\"true\"\n >\n {{ option.label.slice(0, 1) }}\n </span>\n <span class=\"min-w-0\">\n <span class=\"block truncate font-medium leading-5\">{{\n option.label\n }}</span>\n @if (index === activeIndex()) {\n <span\n class=\"block truncate text-xs leading-4 text-foreground\"\n >\n {{ option.description }}\n </span>\n } @else {\n <span\n class=\"block truncate text-xs leading-4 text-muted-foreground group-hover:text-foreground group-focus:text-foreground\"\n >\n {{ option.description }}\n </span>\n }\n </span>\n </button>\n }\n </div>\n }\n </div>\n }\n `,\n})\nexport class QalmaMentionMenu extends QalmaSuggestionMenu<QalmaMentionOption> {\n readonly suggestions = input<readonly QalmaMentionOption[]>([]);\n readonly loading = input(false);\n\n protected readonly optionList = this.suggestions;\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n effect,\n input,\n} from '@angular/core';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport {\n lucideCode,\n lucideHeading1,\n lucideHeading2,\n lucideHeading3,\n lucideList,\n lucideListOrdered,\n lucideListTodo,\n lucideMinus,\n lucidePilcrow,\n lucideSquareCode,\n lucideTable,\n lucideTextQuote,\n} from '@ng-icons/lucide';\nimport { QalmaCommandValue } from '@qalma/editor';\n\nimport { QalmaSuggestionMenu } from '@qalma/kit/headless';\n\nexport interface QalmaSlashCommandOption {\n readonly id: string;\n readonly label: string;\n readonly description: string;\n readonly icon: string;\n readonly shortcut: string;\n /** Editor command to run when the option is picked. */\n readonly command: string;\n readonly value?: QalmaCommandValue;\n readonly placement?: 'block' | 'inline';\n /** Extra terms the consumer can match against when filtering. */\n readonly keywords: readonly string[];\n}\n\n/**\n * Caret-anchored slash-command menu: an icon + shortcut list with a \"Commands\"\n * header and an Escape hint footer, scrolling the active option into view.\n * Positioning, keyboard handling and active highlighting come from\n * {@link QalmaSuggestionMenu}; feed it a `placement` (see `flipAbovePlacement`)\n * and the filtered `options`. Ships the default block-command icon set.\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgIcon],\n providers: [\n provideIcons({\n lucideCode,\n lucideHeading1,\n lucideHeading2,\n lucideHeading3,\n lucideList,\n lucideListOrdered,\n lucideListTodo,\n lucideMinus,\n lucidePilcrow,\n lucideSquareCode,\n lucideTable,\n lucideTextQuote,\n }),\n ],\n selector: 'qalma-slash-command-menu',\n template: `\n @if (placement(); as placement) {\n <div\n role=\"listbox\"\n aria-label=\"Slash command suggestions\"\n class=\"fixed z-20 flex w-[min(320px,calc(100vw-24px))] flex-col overflow-hidden rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg outline-none\"\n [style.left.px]=\"placement.left\"\n [style.top.px]=\"placement.top\"\n [style.bottom.px]=\"placement.bottom\"\n [style.max-height.px]=\"placement.maxHeight\"\n >\n <div\n class=\"shrink-0 px-2 py-1.5 text-[11px] font-semibold uppercase tracking-wide text-muted-foreground\"\n >\n Commands\n </div>\n <div data-suggestion-options class=\"min-h-0 flex-1 overflow-y-auto\">\n @for (option of options(); track option.id; let index = $index) {\n <button\n type=\"button\"\n role=\"option\"\n [attr.data-suggestion-index]=\"index\"\n class=\"group grid h-11 w-full min-w-0 cursor-pointer grid-cols-[1.75rem_minmax(0,1fr)_auto] items-center gap-2 rounded-sm px-2 text-left text-sm transition-colors hover:bg-accent-subtle hover:text-foreground focus:bg-accent-subtle focus:text-foreground focus:outline-none\"\n [class.bg-accent-subtle]=\"index === activeIndex()\"\n [class.text-foreground]=\"index === activeIndex()\"\n [attr.aria-selected]=\"index === activeIndex()\"\n [attr.tabindex]=\"index === activeIndex() ? 0 : -1\"\n (mouseenter)=\"activate.emit(index)\"\n (mousedown)=\"preserveSelection($event)\"\n (keydown)=\"handleOptionKeydown($event, option, index)\"\n (click)=\"pick.emit(option)\"\n >\n <span\n class=\"flex size-7 items-center justify-center rounded-sm border border-border bg-card text-[14px] text-foreground\"\n [class.border-accent]=\"index === activeIndex()\"\n [class.bg-background]=\"index === activeIndex()\"\n [class.text-accent]=\"index === activeIndex()\"\n >\n <ng-icon [name]=\"option.icon\" aria-hidden=\"true\" />\n </span>\n <span class=\"min-w-0\">\n <span class=\"block truncate font-medium leading-5\">{{\n option.label\n }}</span>\n @if (index === activeIndex()) {\n <span\n class=\"block truncate text-xs leading-4 text-foreground\"\n >\n {{ option.description }}\n </span>\n } @else {\n <span\n class=\"block truncate text-xs leading-4 text-muted-foreground group-hover:text-foreground group-focus:text-foreground\"\n >\n {{ option.description }}\n </span>\n }\n </span>\n <kbd\n class=\"rounded-sm border border-border bg-card px-1.5 py-0.5 font-mono text-[11px] text-muted-foreground\"\n [class.border-accent]=\"index === activeIndex()\"\n [class.bg-background]=\"index === activeIndex()\"\n [class.text-accent]=\"index === activeIndex()\"\n >\n {{ option.shortcut }}\n </kbd>\n </button>\n }\n </div>\n <div\n class=\"mt-1 flex h-8 shrink-0 items-center justify-between border-t border-border px-2 text-[11px] text-muted-foreground\"\n >\n <span>Close menu</span>\n <kbd\n class=\"rounded-sm border border-border bg-card px-1.5 py-0.5 font-mono\"\n >esc</kbd\n >\n </div>\n </div>\n }\n `,\n})\nexport class QalmaSlashCommandMenu extends QalmaSuggestionMenu<QalmaSlashCommandOption> {\n readonly options = input<readonly QalmaSlashCommandOption[]>([]);\n\n protected readonly optionList = this.options;\n\n constructor() {\n super();\n\n effect(() => {\n const activeIndex = this.activeIndex();\n\n this.options();\n queueMicrotask(() => this.scrollOptionIntoView(activeIndex));\n });\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n input,\n output,\n} from '@angular/core';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport {\n lucideCheck,\n lucideExternalLink,\n lucideLink,\n lucidePencil,\n lucideUnlink,\n lucideX,\n} from '@ng-icons/lucide';\n\nimport { LinkPopover } from '@qalma/kit/headless';\n\nimport { QalmaButton } from './button';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgIcon, QalmaButton],\n providers: [\n provideIcons({\n lucideCheck,\n lucideExternalLink,\n lucideLink,\n lucidePencil,\n lucideUnlink,\n lucideX,\n }),\n ],\n selector: 'qalma-link-popover',\n template: `\n @if (popover(); as popover) {\n <div\n data-qalma-link-popover\n role=\"dialog\"\n aria-label=\"Link preview\"\n class=\"fixed z-20 w-[min(360px,calc(100vw-32px))] rounded-md border border-border bg-popover p-1.5 text-sm text-popover-foreground shadow-lg outline-none\"\n [style.left.px]=\"popover.left\"\n [style.top.px]=\"popover.top\"\n (mouseenter)=\"keepOpen.emit()\"\n (mouseleave)=\"scheduleHide.emit()\"\n (focusin)=\"keepOpen.emit()\"\n (focusout)=\"scheduleHide.emit()\"\n >\n @if (popover.editing) {\n <div class=\"flex items-center gap-1.5\">\n <label\n class=\"flex h-9 min-w-0 flex-1 items-center gap-2 rounded-md border border-input bg-background px-2 text-sm transition focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/30\"\n >\n <ng-icon\n class=\"shrink-0 text-muted-foreground\"\n name=\"lucideLink\"\n aria-hidden=\"true\"\n />\n <input\n class=\"min-w-0 flex-1 bg-transparent text-foreground outline-none placeholder:text-muted-foreground\"\n type=\"url\"\n aria-label=\"Edit link URL\"\n [value]=\"href()\"\n (input)=\"updateHref($event)\"\n />\n </label>\n <button\n qalmaBtn\n size=\"icon\"\n type=\"button\"\n [disabled]=\"!href().trim()\"\n (click)=\"save.emit(popover)\"\n title=\"Save link\"\n aria-label=\"Save link\"\n >\n <ng-icon name=\"lucideCheck\" aria-hidden=\"true\" />\n </button>\n <button\n qalmaBtn\n variant=\"outline\"\n size=\"icon\"\n type=\"button\"\n (click)=\"dismiss.emit()\"\n title=\"Cancel\"\n aria-label=\"Cancel\"\n >\n <ng-icon name=\"lucideX\" aria-hidden=\"true\" />\n </button>\n </div>\n } @else {\n <div class=\"flex items-center gap-1.5\">\n <a\n class=\"inline-flex h-9 min-w-0 flex-1 items-center gap-1.5 rounded-md border border-border bg-card px-2.5 text-accent transition-colors hover:bg-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n [href]=\"popover.href\"\n [target]=\"popover.target ?? '_blank'\"\n [rel]=\"popover.rel ?? 'noopener noreferrer'\"\n title=\"Open link\"\n >\n <span class=\"min-w-0 truncate font-medium\">{{\n popover.href\n }}</span>\n <ng-icon\n class=\"shrink-0 text-base\"\n name=\"lucideExternalLink\"\n aria-hidden=\"true\"\n />\n </a>\n <button\n qalmaBtn\n variant=\"outline\"\n size=\"icon\"\n type=\"button\"\n (click)=\"edit.emit(popover)\"\n title=\"Edit link\"\n aria-label=\"Edit link\"\n >\n <ng-icon name=\"lucidePencil\" aria-hidden=\"true\" />\n </button>\n <button\n qalmaBtn\n variant=\"ghost\"\n size=\"icon\"\n type=\"button\"\n class=\"text-destructive hover:bg-destructive/10 hover:text-destructive\"\n (click)=\"remove.emit(popover)\"\n title=\"Unlink\"\n aria-label=\"Unlink\"\n >\n <ng-icon name=\"lucideUnlink\" aria-hidden=\"true\" />\n </button>\n </div>\n }\n </div>\n }\n `,\n})\nexport class QalmaLinkPopover {\n readonly popover = input<LinkPopover | null>(null);\n readonly href = input.required<string>();\n\n readonly hrefChange = output<string>();\n readonly edit = output<LinkPopover>();\n readonly save = output<LinkPopover>();\n readonly remove = output<LinkPopover>();\n readonly dismiss = output<void>();\n readonly keepOpen = output<void>();\n readonly scheduleHide = output<void>();\n\n protected updateHref(event: Event): void {\n const target = event.target;\n\n if (target instanceof HTMLInputElement) {\n this.hrefChange.emit(target.value);\n }\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n input,\n output,\n} from '@angular/core';\nimport { QalmaToolbar } from '@qalma/editor';\n\nimport { QalmaContextualToolbarPlacement } from '@qalma/kit/headless';\n\n/**\n * Floating, selection-anchored toolbar container. It owns the hard parts — the\n * fixed-position `transform` from a {@link QalmaContextualToolbarPlacement}\n * (see `QalmaSelectionToolbarDirective`), preserving the editor selection on\n * pointer-down, and Escape-to-dismiss — and projects whatever controls you put\n * inside it. Nothing about the button set is baked in: compose\n * `<qalma-toolbar-button>` for commands and your own buttons for app actions\n * (opening a link editor, a color picker, an AI action…).\n *\n * The container's `mousedown` handler preserves the selection for every\n * projected control via event bubbling, so inner buttons don't each need to.\n *\n * ```html\n * <qalma-contextual-toolbar\n * [placement]=\"selection.placement()\"\n * (dismiss)=\"selection.hide()\"\n * >\n * <qalma-toolbar-button command=\"toggleBold\" icon=\"lucideBold\" label=\"Bold\" />\n * <qalma-toolbar-button command=\"toggleItalic\" icon=\"lucideItalic\" label=\"Italic\" />\n * <button type=\"button\" [class]=\"TOOLBAR_BUTTON_CLASS\" (click)=\"openLinkEditor()\">…</button>\n * </qalma-contextual-toolbar>\n * ```\n */\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [QalmaToolbar],\n selector: 'qalma-contextual-toolbar',\n template: `\n @if (placement(); as placement) {\n <qalma-toolbar\n [label]=\"label()\"\n class=\"fixed left-0 top-0 z-30 flex items-center gap-0.5 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-lg will-change-transform\"\n [style.transform]=\"placement.transform\"\n (mousedown)=\"preserveSelection($event)\"\n (keydown.escape)=\"dismissFromKeyboard($event)\"\n >\n <ng-content />\n </qalma-toolbar>\n }\n `,\n})\nexport class QalmaContextualToolbar {\n readonly placement = input<QalmaContextualToolbarPlacement | null>(null);\n /** Accessible name for the toolbar region. */\n readonly label = input('Selection formatting');\n readonly dismiss = output<void>();\n\n protected preserveSelection(event: MouseEvent): void {\n event.preventDefault();\n }\n\n protected dismissFromKeyboard(event: Event): void {\n event.preventDefault();\n this.dismiss.emit();\n }\n}\n","// @qalma/kit — Tailwind/shadcn-flavored UI for the Qalma editor.\n//\n// This entry point is the styled tier: components that pull `cva` + `@ng-icons`\n// and read the host's design tokens. It re-exports the entire dependency-free\n// `@qalma/kit/headless` surface (controllers, geometry, keyboard nav) so it\n// stays a superset — bring-your-own-design-system consumers can import the\n// leaner `@qalma/kit/headless` directly instead.\n//\n// The internal `QalmaButton` directive and `cn()` helper are intentionally NOT\n// exported: a host already has a button and a class-merge utility in its design\n// system. They remain private implementation details of the styled components.\nexport * from '@qalma/kit/headless';\n\n// Toolbar\nexport * from './lib/toolbar-button';\nexport * from './lib/toolbar-commands';\nexport * from './lib/toolbar-registry';\nexport * from './lib/toolbar-icons';\n\n// Editor surface components\nexport * from './lib/drag-handle';\nexport * from './lib/mention-menu';\nexport * from './lib/slash-command-menu';\nexport * from './lib/link-popover';\nexport * from './lib/contextual-toolbar';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qalma/kit",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Tailwind-first, themeable UI components for the Qalma editor.",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,
@@ -28,8 +28,8 @@
28
28
  "tag": "latest"
29
29
  },
30
30
  "peerDependencies": {
31
- "@angular/core": ">=21.0.0 <22.0.0",
32
- "@angular/common": ">=21.0.0 <22.0.0",
31
+ "@angular/core": ">=21.0.0 <23.0.0",
32
+ "@angular/common": ">=21.0.0 <23.0.0",
33
33
  "@ng-icons/core": ">=33.0.0",
34
34
  "@ng-icons/lucide": ">=33.0.0",
35
35
  "@qalma/editor": ">=0.1.0-beta.0"
@@ -7,11 +7,12 @@ import { QalmaEditorController, QalmaCommandValue } from '@qalma/editor';
7
7
  /**
8
8
  * Default styling for a toolbar command button. Icon-only, square, and driven
9
9
  * entirely by the host's shadcn-style design tokens (`text-muted-foreground`,
10
- * `bg-secondary`, `bg-accent-subtle`…) so it themes with the surrounding app.
10
+ * `bg-card`, `bg-secondary`, `bg-accent-subtle`…) so it themes with the
11
+ * surrounding app.
11
12
  * The `qalma-command-active` class is toggled by the `QalmaCommand` directive
12
13
  * when the underlying command is active.
13
14
  */
14
- declare const TOOLBAR_BUTTON_CLASS = "inline-flex h-[1.85rem] w-[1.85rem] cursor-pointer items-center justify-center rounded-[0.4rem] border border-transparent text-muted-foreground transition hover:bg-secondary hover:text-foreground disabled:cursor-not-allowed disabled:opacity-45 [&.qalma-command-active]:border-accent/40 [&.qalma-command-active]:bg-accent-subtle [&.qalma-command-active]:text-accent";
15
+ declare const TOOLBAR_BUTTON_CLASS = "inline-flex h-[1.85rem] w-[1.85rem] cursor-pointer items-center justify-center rounded-[0.4rem] border border-border bg-card text-muted-foreground transition hover:border-accent/50 hover:bg-secondary hover:text-foreground disabled:cursor-not-allowed disabled:opacity-45 [&.qalma-command-active]:border-accent/40 [&.qalma-command-active]:bg-accent-subtle [&.qalma-command-active]:text-accent";
15
16
  /**
16
17
  * Generic, declarative toolbar button for a single editor command.
17
18
  *
@@ -36,7 +37,7 @@ declare class QalmaToolbarButton {
36
37
  readonly label: _angular_core.InputSignal<string>;
37
38
  /** Optional icon-size class override (default: `text-[0.9rem]`). */
38
39
  readonly iconClass: _angular_core.InputSignal<string>;
39
- protected readonly buttonClass = "inline-flex h-[1.85rem] w-[1.85rem] cursor-pointer items-center justify-center rounded-[0.4rem] border border-transparent text-muted-foreground transition hover:bg-secondary hover:text-foreground disabled:cursor-not-allowed disabled:opacity-45 [&.qalma-command-active]:border-accent/40 [&.qalma-command-active]:bg-accent-subtle [&.qalma-command-active]:text-accent";
40
+ protected readonly buttonClass = "inline-flex h-[1.85rem] w-[1.85rem] cursor-pointer items-center justify-center rounded-[0.4rem] border border-border bg-card text-muted-foreground transition hover:border-accent/50 hover:bg-secondary hover:text-foreground disabled:cursor-not-allowed disabled:opacity-45 [&.qalma-command-active]:border-accent/40 [&.qalma-command-active]:bg-accent-subtle [&.qalma-command-active]:text-accent";
40
41
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<QalmaToolbarButton, never>;
41
42
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<QalmaToolbarButton, "qalma-toolbar-button", never, { "command": { "alias": "command"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "iconClass": { "alias": "iconClass"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
42
43
  }
@@ -1 +1 @@
1
- {"version":3,"file":"qalma-kit.d.ts","sources":["../../../../libs/ui-kit/src/lib/toolbar-button.ts","../../../../libs/ui-kit/src/lib/toolbar-commands.ts","../../../../libs/ui-kit/src/lib/toolbar-registry.ts","../../../../libs/ui-kit/src/lib/toolbar-icons.ts","../../../../libs/ui-kit/src/lib/drag-handle.ts","../../../../libs/ui-kit/src/lib/mention-menu.ts","../../../../libs/ui-kit/src/lib/slash-command-menu.ts","../../../../libs/ui-kit/src/lib/link-popover.ts","../../../../libs/ui-kit/src/lib/contextual-toolbar.ts"],"mappings":"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","names":[]}
1
+ {"version":3,"file":"qalma-kit.d.ts","sources":["../../../../libs/ui-kit/src/lib/toolbar-button.ts","../../../../libs/ui-kit/src/lib/toolbar-commands.ts","../../../../libs/ui-kit/src/lib/toolbar-registry.ts","../../../../libs/ui-kit/src/lib/toolbar-icons.ts","../../../../libs/ui-kit/src/lib/drag-handle.ts","../../../../libs/ui-kit/src/lib/mention-menu.ts","../../../../libs/ui-kit/src/lib/slash-command-menu.ts","../../../../libs/ui-kit/src/lib/link-popover.ts","../../../../libs/ui-kit/src/lib/contextual-toolbar.ts"],"mappings":"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","names":[]}