@tolle_/tolle-ui 0.0.17-beta → 0.0.18-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,10 @@
1
1
  import { Component, Input } from '@angular/core';
2
2
  import { CommonModule } from '@angular/common';
3
3
  import { cva } from 'class-variance-authority';
4
- import { cn } from './utils/cn'; // Importing the helper we made in Phase 2
4
+ import { cn } from './utils/cn';
5
5
  import * as i0 from "@angular/core";
6
- // 1. Define Component Variants (The "Recipe")
7
- const buttonVariants = cva(
8
- // Base styles applied to ALL buttons
9
- "inline-flex items-center justify-center 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 disabled:opacity-50 disabled:pointer-events-none ring-offset-background", {
6
+ import * as i1 from "@angular/common";
7
+ const buttonVariants = cva("inline-flex items-center justify-center rounded-md text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background active:scale-[0.98]", {
10
8
  variants: {
11
9
  variant: {
12
10
  default: "bg-primary text-primary-foreground hover:bg-primary/90",
@@ -21,62 +19,79 @@ const buttonVariants = cva(
21
19
  xs: "h-8 px-2 py-1 text-xs",
22
20
  sm: "h-9 rounded-md px-3",
23
21
  lg: "h-11 rounded-md px-8",
22
+ // RESTORED: Square icon button variants
24
23
  "icon-xs": "h-8 w-8",
25
24
  "icon-sm": "h-9 w-9",
26
25
  icon: "h-10 w-10",
27
26
  "icon-lg": "h-11 w-11",
28
27
  },
29
- // Added block variant
30
- block: {
31
- true: "w-full flex",
32
- },
33
- // Added readonly variant
34
- readonly: {
35
- true: "pointer-events-none opacity-80",
36
- },
37
- disabled: {
38
- true: "pointer-events-none",
39
- }
28
+ block: { true: "w-full flex" },
29
+ busy: { true: "relative !cursor-wait !pointer-events-none" }
40
30
  },
41
31
  defaultVariants: {
42
32
  variant: "default",
43
33
  size: "default",
44
34
  block: false,
45
- readonly: false,
46
35
  },
47
36
  });
48
37
  export class ButtonComponent {
49
- // Allow consumers to pass a custom class to override styles
50
38
  class = '';
51
- // Expose the variants as Inputs
52
39
  variant = 'default';
53
40
  size = 'default';
54
- // Added new inputs
55
41
  block = false;
56
- readonly = false;
57
42
  disabled = false;
58
- // Calculate the final string of classes
43
+ busy = false;
44
+ readonly = false;
59
45
  get computedClass() {
60
- return cn(buttonVariants({ variant: this.variant, size: this.size, block: this.block, disabled: this.disabled }), this.class);
46
+ return cn(buttonVariants({
47
+ variant: this.variant,
48
+ size: this.size,
49
+ block: this.block,
50
+ busy: this.busy
51
+ }),
52
+ // Adds 'size-icon-sm', 'size-xs', etc. for the CSS selectors to work
53
+ 'size-' + this.size, this.class);
61
54
  }
62
55
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
63
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ButtonComponent, isStandalone: true, selector: "tolle-button", inputs: { class: "class", variant: "variant", size: "size", block: "block", readonly: "readonly", disabled: "disabled" }, ngImport: i0, template: `
64
- <button [class]="computedClass" [disabled]="disabled" [attr.aria-readonly]="readonly">
65
- <span class="flex items-center justify-center gap-2 w-full h-full">
56
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ButtonComponent, isStandalone: true, selector: "tolle-button", inputs: { class: "class", variant: "variant", size: "size", block: "block", disabled: "disabled", busy: "busy", readonly: "readonly" }, ngImport: i0, template: `
57
+ <button
58
+ [class]="computedClass"
59
+ [disabled]="disabled || busy"
60
+ [attr.aria-busy]="busy"
61
+ >
62
+ <div *ngIf="busy" class="absolute inset-0 flex items-center justify-center">
63
+ <svg class="animate-spin h-5 w-5 text-current" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
64
+ <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
65
+ <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
66
+ </svg>
67
+ </div>
68
+
69
+ <span class="flex items-center justify-center w-full h-full" [class.invisible]="busy">
66
70
  <ng-content></ng-content>
67
71
  </span>
68
72
  </button>
69
- `, isInline: true, styles: [":host ::ng-deep i{display:inline-flex;align-items:center;line-height:1;font-size:1.25em}:host ::ng-deep i:not(:only-child){margin-right:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
73
+ `, isInline: true, styles: [":host{display:inline-block}:host(.w-full){display:block}:host ::ng-deep i{display:inline-flex;align-items:center;justify-content:center;line-height:1}:host-context(.size-xs) ::ng-deep i,:host-context(.size-icon-xs) ::ng-deep i,:host-context(.size-sm) ::ng-deep i,:host-context(.size-icon-sm) ::ng-deep i{font-size:1rem}:host-context(.size-default) ::ng-deep i,:host-context(.size-icon) ::ng-deep i,:host-context(.size-lg) ::ng-deep i,:host-context(.size-icon-lg) ::ng-deep i{font-size:1.2rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
70
74
  }
71
75
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ButtonComponent, decorators: [{
72
76
  type: Component,
73
77
  args: [{ selector: 'tolle-button', standalone: true, imports: [CommonModule], template: `
74
- <button [class]="computedClass" [disabled]="disabled" [attr.aria-readonly]="readonly">
75
- <span class="flex items-center justify-center gap-2 w-full h-full">
78
+ <button
79
+ [class]="computedClass"
80
+ [disabled]="disabled || busy"
81
+ [attr.aria-busy]="busy"
82
+ >
83
+ <div *ngIf="busy" class="absolute inset-0 flex items-center justify-center">
84
+ <svg class="animate-spin h-5 w-5 text-current" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
85
+ <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
86
+ <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
87
+ </svg>
88
+ </div>
89
+
90
+ <span class="flex items-center justify-center w-full h-full" [class.invisible]="busy">
76
91
  <ng-content></ng-content>
77
92
  </span>
78
93
  </button>
79
- `, styles: [":host ::ng-deep i{display:inline-flex;align-items:center;line-height:1;font-size:1.25em}:host ::ng-deep i:not(:only-child){margin-right:.5rem}\n"] }]
94
+ `, styles: [":host{display:inline-block}:host(.w-full){display:block}:host ::ng-deep i{display:inline-flex;align-items:center;justify-content:center;line-height:1}:host-context(.size-xs) ::ng-deep i,:host-context(.size-icon-xs) ::ng-deep i,:host-context(.size-sm) ::ng-deep i,:host-context(.size-icon-sm) ::ng-deep i{font-size:1rem}:host-context(.size-default) ::ng-deep i,:host-context(.size-icon) ::ng-deep i,:host-context(.size-lg) ::ng-deep i,:host-context(.size-icon-lg) ::ng-deep i{font-size:1.2rem}\n"] }]
80
95
  }], propDecorators: { class: [{
81
96
  type: Input
82
97
  }], variant: [{
@@ -85,9 +100,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
85
100
  type: Input
86
101
  }], block: [{
87
102
  type: Input
88
- }], readonly: [{
89
- type: Input
90
103
  }], disabled: [{
91
104
  type: Input
105
+ }], busy: [{
106
+ type: Input
107
+ }], readonly: [{
108
+ type: Input
92
109
  }] } });
93
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnV0dG9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RvbGxlL3NyYy9saWIvYnV0dG9uLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLEdBQUcsRUFBcUIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sWUFBWSxDQUFDLENBQUMsMENBQTBDOztBQUUzRSw4Q0FBOEM7QUFDOUMsTUFBTSxjQUFjLEdBQUcsR0FBRztBQUN4QixxQ0FBcUM7QUFDckMsc1FBQXNRLEVBQ3RRO0lBQ0UsUUFBUSxFQUFFO1FBQ1IsT0FBTyxFQUFFO1lBQ1AsT0FBTyxFQUFFLHdEQUF3RDtZQUNqRSxXQUFXLEVBQUUsb0VBQW9FO1lBQ2pGLE9BQU8sRUFBRSxrRUFBa0U7WUFDM0UsU0FBUyxFQUFFLDhEQUE4RDtZQUN6RSxLQUFLLEVBQUUsOENBQThDO1lBQ3JELElBQUksRUFBRSxpREFBaUQ7U0FDeEQ7UUFDRCxJQUFJLEVBQUU7WUFDSixPQUFPLEVBQUUsZ0JBQWdCO1lBQ3pCLEVBQUUsRUFBRSx1QkFBdUI7WUFDM0IsRUFBRSxFQUFFLHFCQUFxQjtZQUN6QixFQUFFLEVBQUUsc0JBQXNCO1lBQzFCLFNBQVMsRUFBRSxTQUFTO1lBQ3BCLFNBQVMsRUFBRSxTQUFTO1lBQ3BCLElBQUksRUFBRSxXQUFXO1lBQ2pCLFNBQVMsRUFBRSxXQUFXO1NBQ3ZCO1FBQ0Qsc0JBQXNCO1FBQ3RCLEtBQUssRUFBRTtZQUNMLElBQUksRUFBRSxhQUFhO1NBQ3BCO1FBQ0QseUJBQXlCO1FBQ3pCLFFBQVEsRUFBRTtZQUNSLElBQUksRUFBRSxnQ0FBZ0M7U0FDdkM7UUFDRCxRQUFRLEVBQUU7WUFDUixJQUFJLEVBQUUscUJBQXFCO1NBQzVCO0tBQ0Y7SUFDRCxlQUFlLEVBQUU7UUFDZixPQUFPLEVBQUUsU0FBUztRQUNsQixJQUFJLEVBQUUsU0FBUztRQUNmLEtBQUssRUFBRSxLQUFLO1FBQ1osUUFBUSxFQUFFLEtBQUs7S0FDaEI7Q0FDRixDQUNGLENBQUM7QUErQkYsTUFBTSxPQUFPLGVBQWU7SUFDMUIsNERBQTREO0lBQ25ELEtBQUssR0FBVyxFQUFFLENBQUM7SUFFNUIsZ0NBQWdDO0lBQ3ZCLE9BQU8sR0FBMkIsU0FBUyxDQUFDO0lBQzVDLElBQUksR0FBd0IsU0FBUyxDQUFDO0lBRS9DLG1CQUFtQjtJQUNWLEtBQUssR0FBWSxLQUFLLENBQUM7SUFDdkIsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUMxQixRQUFRLEdBQVksS0FBSyxDQUFDO0lBRW5DLHdDQUF3QztJQUN4QyxJQUFJLGFBQWE7UUFDZixPQUFPLEVBQUUsQ0FBQyxjQUFjLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hJLENBQUM7d0dBaEJVLGVBQWU7NEZBQWYsZUFBZSxrTUF0QmhCOzs7Ozs7R0FNVCx5TkFQUyxZQUFZOzs0RkF1QlgsZUFBZTtrQkExQjNCLFNBQVM7K0JBQ0UsY0FBYyxjQUNaLElBQUksV0FDUCxDQUFDLFlBQVksQ0FBQyxZQUNiOzs7Ozs7R0FNVDs4QkFrQlEsS0FBSztzQkFBYixLQUFLO2dCQUdHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBR0csS0FBSztzQkFBYixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBjdmEsIHR5cGUgVmFyaWFudFByb3BzIH0gZnJvbSAnY2xhc3MtdmFyaWFuY2UtYXV0aG9yaXR5JztcbmltcG9ydCB7IGNuIH0gZnJvbSAnLi91dGlscy9jbic7IC8vIEltcG9ydGluZyB0aGUgaGVscGVyIHdlIG1hZGUgaW4gUGhhc2UgMlxuXG4vLyAxLiBEZWZpbmUgQ29tcG9uZW50IFZhcmlhbnRzIChUaGUgXCJSZWNpcGVcIilcbmNvbnN0IGJ1dHRvblZhcmlhbnRzID0gY3ZhKFxuICAvLyBCYXNlIHN0eWxlcyBhcHBsaWVkIHRvIEFMTCBidXR0b25zXG4gIFwiaW5saW5lLWZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHJvdW5kZWQtbWQgdGV4dC1zbSBmb250LW1lZGl1bSB0cmFuc2l0aW9uLWNvbG9ycyBmb2N1cy12aXNpYmxlOm91dGxpbmUtbm9uZSBmb2N1cy12aXNpYmxlOnJpbmctMiBmb2N1cy12aXNpYmxlOnJpbmctcmluZyBmb2N1cy12aXNpYmxlOnJpbmctb2Zmc2V0LTIgZGlzYWJsZWQ6b3BhY2l0eS01MCBkaXNhYmxlZDpwb2ludGVyLWV2ZW50cy1ub25lIHJpbmctb2Zmc2V0LWJhY2tncm91bmRcIixcbiAge1xuICAgIHZhcmlhbnRzOiB7XG4gICAgICB2YXJpYW50OiB7XG4gICAgICAgIGRlZmF1bHQ6IFwiYmctcHJpbWFyeSB0ZXh0LXByaW1hcnktZm9yZWdyb3VuZCBob3ZlcjpiZy1wcmltYXJ5LzkwXCIsXG4gICAgICAgIGRlc3RydWN0aXZlOiBcImJnLWRlc3RydWN0aXZlIHRleHQtZGVzdHJ1Y3RpdmUtZm9yZWdyb3VuZCBob3ZlcjpiZy1kZXN0cnVjdGl2ZS85MFwiLFxuICAgICAgICBvdXRsaW5lOiBcImJvcmRlciBib3JkZXItaW5wdXQgaG92ZXI6YmctYWNjZW50IGhvdmVyOnRleHQtYWNjZW50LWZvcmVncm91bmRcIixcbiAgICAgICAgc2Vjb25kYXJ5OiBcImJnLXNlY29uZGFyeSB0ZXh0LXNlY29uZGFyeS1mb3JlZ3JvdW5kIGhvdmVyOmJnLXNlY29uZGFyeS84MFwiLFxuICAgICAgICBnaG9zdDogXCJob3ZlcjpiZy1hY2NlbnQgaG92ZXI6dGV4dC1hY2NlbnQtZm9yZWdyb3VuZFwiLFxuICAgICAgICBsaW5rOiBcInVuZGVybGluZS1vZmZzZXQtNCBob3Zlcjp1bmRlcmxpbmUgdGV4dC1wcmltYXJ5XCIsXG4gICAgICB9LFxuICAgICAgc2l6ZToge1xuICAgICAgICBkZWZhdWx0OiBcImgtMTAgcHgtNCBweS0yXCIsXG4gICAgICAgIHhzOiBcImgtOCBweC0yIHB5LTEgdGV4dC14c1wiLFxuICAgICAgICBzbTogXCJoLTkgcm91bmRlZC1tZCBweC0zXCIsXG4gICAgICAgIGxnOiBcImgtMTEgcm91bmRlZC1tZCBweC04XCIsXG4gICAgICAgIFwiaWNvbi14c1wiOiBcImgtOCB3LThcIixcbiAgICAgICAgXCJpY29uLXNtXCI6IFwiaC05IHctOVwiLFxuICAgICAgICBpY29uOiBcImgtMTAgdy0xMFwiLFxuICAgICAgICBcImljb24tbGdcIjogXCJoLTExIHctMTFcIixcbiAgICAgIH0sXG4gICAgICAvLyBBZGRlZCBibG9jayB2YXJpYW50XG4gICAgICBibG9jazoge1xuICAgICAgICB0cnVlOiBcInctZnVsbCBmbGV4XCIsXG4gICAgICB9LFxuICAgICAgLy8gQWRkZWQgcmVhZG9ubHkgdmFyaWFudFxuICAgICAgcmVhZG9ubHk6IHtcbiAgICAgICAgdHJ1ZTogXCJwb2ludGVyLWV2ZW50cy1ub25lIG9wYWNpdHktODBcIixcbiAgICAgIH0sXG4gICAgICBkaXNhYmxlZDoge1xuICAgICAgICB0cnVlOiBcInBvaW50ZXItZXZlbnRzLW5vbmVcIixcbiAgICAgIH1cbiAgICB9LFxuICAgIGRlZmF1bHRWYXJpYW50czoge1xuICAgICAgdmFyaWFudDogXCJkZWZhdWx0XCIsXG4gICAgICBzaXplOiBcImRlZmF1bHRcIixcbiAgICAgIGJsb2NrOiBmYWxzZSxcbiAgICAgIHJlYWRvbmx5OiBmYWxzZSxcbiAgICB9LFxuICB9XG4pO1xuXG4vLyBIZWxwZXIgdHlwZSBmb3IgSW50ZWxsaXNlbnNlXG5leHBvcnQgdHlwZSBCdXR0b25Qcm9wcyA9IFZhcmlhbnRQcm9wczx0eXBlb2YgYnV0dG9uVmFyaWFudHM+O1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0b2xsZS1idXR0b24nLCAvLyBVc2FnZTogPHRvbGxlLWJ1dHRvbiB2YXJpYW50PVwiZGVzdHJ1Y3RpdmVcIj5cbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGJ1dHRvbiBbY2xhc3NdPVwiY29tcHV0ZWRDbGFzc1wiIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiIFthdHRyLmFyaWEtcmVhZG9ubHldPVwicmVhZG9ubHlcIj5cbiAgICAgPHNwYW4gY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBnYXAtMiB3LWZ1bGwgaC1mdWxsXCI+XG4gICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICAgIDwvc3Bhbj5cbiAgICA8L2J1dHRvbj5cbiAgYCxcbiAgc3R5bGVzOiBbYFxuICAgIC8qIEVuc3VyZSBSZW1peCBJY29ucyBhbGlnbiB2ZXJ0aWNhbGx5IHdpdGggdGV4dCAqL1xuICAgIDpob3N0IDo6bmctZGVlcCBpIHtcbiAgICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGxpbmUtaGVpZ2h0OiAxO1xuICAgICAgZm9udC1zaXplOiAxLjI1ZW07IC8qIFNjYWxlcyByZWxhdGl2ZSB0byB0aGUgYnV0dG9uIHRleHQgc2l6ZSAqL1xuICAgIH1cblxuICAgIC8qIFNwZWNpZmljIHNwYWNpbmcgaWYgaWNvbiBpcyBuZXh0IHRvIHRleHQgKi9cbiAgICA6aG9zdCA6Om5nLWRlZXAgaTpub3QoOm9ubHktY2hpbGQpIHtcbiAgICAgIG1hcmdpbi1yaWdodDogMC41cmVtO1xuICAgIH1cbiAgYF1cbn0pXG5leHBvcnQgY2xhc3MgQnV0dG9uQ29tcG9uZW50IHtcbiAgLy8gQWxsb3cgY29uc3VtZXJzIHRvIHBhc3MgYSBjdXN0b20gY2xhc3MgdG8gb3ZlcnJpZGUgc3R5bGVzXG4gIEBJbnB1dCgpIGNsYXNzOiBzdHJpbmcgPSAnJztcblxuICAvLyBFeHBvc2UgdGhlIHZhcmlhbnRzIGFzIElucHV0c1xuICBASW5wdXQoKSB2YXJpYW50OiBCdXR0b25Qcm9wc1sndmFyaWFudCddID0gJ2RlZmF1bHQnO1xuICBASW5wdXQoKSBzaXplOiBCdXR0b25Qcm9wc1snc2l6ZSddID0gJ2RlZmF1bHQnO1xuXG4gIC8vIEFkZGVkIG5ldyBpbnB1dHNcbiAgQElucHV0KCkgYmxvY2s6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgcmVhZG9ubHk6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAvLyBDYWxjdWxhdGUgdGhlIGZpbmFsIHN0cmluZyBvZiBjbGFzc2VzXG4gIGdldCBjb21wdXRlZENsYXNzKCkge1xuICAgIHJldHVybiBjbihidXR0b25WYXJpYW50cyh7IHZhcmlhbnQ6IHRoaXMudmFyaWFudCwgc2l6ZTogdGhpcy5zaXplLCBibG9jazogdGhpcy5ibG9jaywgZGlzYWJsZWQ6IHRoaXMuZGlzYWJsZWQgfSksIHRoaXMuY2xhc3MpO1xuICB9XG59XG4iXX0=
110
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnV0dG9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RvbGxlL3NyYy9saWIvYnV0dG9uLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLEdBQUcsRUFBcUIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sWUFBWSxDQUFDOzs7QUFFaEMsTUFBTSxjQUFjLEdBQUcsR0FBRyxDQUN4Qix1UkFBdVIsRUFDdlI7SUFDRSxRQUFRLEVBQUU7UUFDUixPQUFPLEVBQUU7WUFDUCxPQUFPLEVBQUUsd0RBQXdEO1lBQ2pFLFdBQVcsRUFBRSxvRUFBb0U7WUFDakYsT0FBTyxFQUFFLGtFQUFrRTtZQUMzRSxTQUFTLEVBQUUsOERBQThEO1lBQ3pFLEtBQUssRUFBRSw4Q0FBOEM7WUFDckQsSUFBSSxFQUFFLGlEQUFpRDtTQUN4RDtRQUNELElBQUksRUFBRTtZQUNKLE9BQU8sRUFBRSxnQkFBZ0I7WUFDekIsRUFBRSxFQUFFLHVCQUF1QjtZQUMzQixFQUFFLEVBQUUscUJBQXFCO1lBQ3pCLEVBQUUsRUFBRSxzQkFBc0I7WUFDMUIsd0NBQXdDO1lBQ3hDLFNBQVMsRUFBRSxTQUFTO1lBQ3BCLFNBQVMsRUFBRSxTQUFTO1lBQ3BCLElBQUksRUFBRSxXQUFXO1lBQ2pCLFNBQVMsRUFBRSxXQUFXO1NBQ3ZCO1FBQ0QsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRTtRQUM5QixJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsNENBQTRDLEVBQUU7S0FDN0Q7SUFDRCxlQUFlLEVBQUU7UUFDZixPQUFPLEVBQUUsU0FBUztRQUNsQixJQUFJLEVBQUUsU0FBUztRQUNmLEtBQUssRUFBRSxLQUFLO0tBQ2I7Q0FDRixDQUNGLENBQUM7QUFzREYsTUFBTSxPQUFPLGVBQWU7SUFDakIsS0FBSyxHQUFXLEVBQUUsQ0FBQztJQUNuQixPQUFPLEdBQTJCLFNBQVMsQ0FBQztJQUM1QyxJQUFJLEdBQXdCLFNBQVMsQ0FBQztJQUN0QyxLQUFLLEdBQVksS0FBSyxDQUFDO0lBQ3ZCLFFBQVEsR0FBWSxLQUFLLENBQUM7SUFDMUIsSUFBSSxHQUFZLEtBQUssQ0FBQztJQUN0QixRQUFRLEdBQVksS0FBSyxDQUFDO0lBRW5DLElBQUksYUFBYTtRQUNmLE9BQU8sRUFBRSxDQUNQLGNBQWMsQ0FBQztZQUNiLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztZQUNyQixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7WUFDakIsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO1NBQ2hCLENBQUM7UUFDRixxRUFBcUU7UUFDckUsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQ25CLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztJQUNKLENBQUM7d0dBckJVLGVBQWU7NEZBQWYsZUFBZSxnTkE5Q2hCOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCVCx1akJBbEJTLFlBQVk7OzRGQStDWCxlQUFlO2tCQWxEM0IsU0FBUzsrQkFDRSxjQUFjLGNBQ1osSUFBSSxXQUNQLENBQUMsWUFBWSxDQUFDLFlBQ2I7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJUOzhCQThCUSxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLElBQUk7c0JBQVosS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBjdmEsIHR5cGUgVmFyaWFudFByb3BzIH0gZnJvbSAnY2xhc3MtdmFyaWFuY2UtYXV0aG9yaXR5JztcbmltcG9ydCB7IGNuIH0gZnJvbSAnLi91dGlscy9jbic7XG5cbmNvbnN0IGJ1dHRvblZhcmlhbnRzID0gY3ZhKFxuICBcImlubGluZS1mbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciByb3VuZGVkLW1kIHRleHQtc20gZm9udC1tZWRpdW0gdHJhbnNpdGlvbi1hbGwgZm9jdXMtdmlzaWJsZTpvdXRsaW5lLW5vbmUgZm9jdXMtdmlzaWJsZTpyaW5nLTIgZm9jdXMtdmlzaWJsZTpyaW5nLXJpbmcgZm9jdXMtdmlzaWJsZTpyaW5nLW9mZnNldC0yIGRpc2FibGVkOm9wYWNpdHktNTAgZGlzYWJsZWQ6cG9pbnRlci1ldmVudHMtbm9uZSByaW5nLW9mZnNldC1iYWNrZ3JvdW5kIGFjdGl2ZTpzY2FsZS1bMC45OF1cIixcbiAge1xuICAgIHZhcmlhbnRzOiB7XG4gICAgICB2YXJpYW50OiB7XG4gICAgICAgIGRlZmF1bHQ6IFwiYmctcHJpbWFyeSB0ZXh0LXByaW1hcnktZm9yZWdyb3VuZCBob3ZlcjpiZy1wcmltYXJ5LzkwXCIsXG4gICAgICAgIGRlc3RydWN0aXZlOiBcImJnLWRlc3RydWN0aXZlIHRleHQtZGVzdHJ1Y3RpdmUtZm9yZWdyb3VuZCBob3ZlcjpiZy1kZXN0cnVjdGl2ZS85MFwiLFxuICAgICAgICBvdXRsaW5lOiBcImJvcmRlciBib3JkZXItaW5wdXQgaG92ZXI6YmctYWNjZW50IGhvdmVyOnRleHQtYWNjZW50LWZvcmVncm91bmRcIixcbiAgICAgICAgc2Vjb25kYXJ5OiBcImJnLXNlY29uZGFyeSB0ZXh0LXNlY29uZGFyeS1mb3JlZ3JvdW5kIGhvdmVyOmJnLXNlY29uZGFyeS84MFwiLFxuICAgICAgICBnaG9zdDogXCJob3ZlcjpiZy1hY2NlbnQgaG92ZXI6dGV4dC1hY2NlbnQtZm9yZWdyb3VuZFwiLFxuICAgICAgICBsaW5rOiBcInVuZGVybGluZS1vZmZzZXQtNCBob3Zlcjp1bmRlcmxpbmUgdGV4dC1wcmltYXJ5XCIsXG4gICAgICB9LFxuICAgICAgc2l6ZToge1xuICAgICAgICBkZWZhdWx0OiBcImgtMTAgcHgtNCBweS0yXCIsXG4gICAgICAgIHhzOiBcImgtOCBweC0yIHB5LTEgdGV4dC14c1wiLFxuICAgICAgICBzbTogXCJoLTkgcm91bmRlZC1tZCBweC0zXCIsXG4gICAgICAgIGxnOiBcImgtMTEgcm91bmRlZC1tZCBweC04XCIsXG4gICAgICAgIC8vIFJFU1RPUkVEOiBTcXVhcmUgaWNvbiBidXR0b24gdmFyaWFudHNcbiAgICAgICAgXCJpY29uLXhzXCI6IFwiaC04IHctOFwiLFxuICAgICAgICBcImljb24tc21cIjogXCJoLTkgdy05XCIsXG4gICAgICAgIGljb246IFwiaC0xMCB3LTEwXCIsXG4gICAgICAgIFwiaWNvbi1sZ1wiOiBcImgtMTEgdy0xMVwiLFxuICAgICAgfSxcbiAgICAgIGJsb2NrOiB7IHRydWU6IFwidy1mdWxsIGZsZXhcIiB9LFxuICAgICAgYnVzeTogeyB0cnVlOiBcInJlbGF0aXZlICFjdXJzb3Itd2FpdCAhcG9pbnRlci1ldmVudHMtbm9uZVwiIH1cbiAgICB9LFxuICAgIGRlZmF1bHRWYXJpYW50czoge1xuICAgICAgdmFyaWFudDogXCJkZWZhdWx0XCIsXG4gICAgICBzaXplOiBcImRlZmF1bHRcIixcbiAgICAgIGJsb2NrOiBmYWxzZSxcbiAgICB9LFxuICB9XG4pO1xuXG5leHBvcnQgdHlwZSBCdXR0b25Qcm9wcyA9IFZhcmlhbnRQcm9wczx0eXBlb2YgYnV0dG9uVmFyaWFudHM+O1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0b2xsZS1idXR0b24nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8YnV0dG9uXG4gICAgICBbY2xhc3NdPVwiY29tcHV0ZWRDbGFzc1wiXG4gICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWQgfHwgYnVzeVwiXG4gICAgICBbYXR0ci5hcmlhLWJ1c3ldPVwiYnVzeVwiXG4gICAgPlxuICAgICAgPGRpdiAqbmdJZj1cImJ1c3lcIiBjbGFzcz1cImFic29sdXRlIGluc2V0LTAgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJcIj5cbiAgICAgICAgPHN2ZyBjbGFzcz1cImFuaW1hdGUtc3BpbiBoLTUgdy01IHRleHQtY3VycmVudFwiIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiBmaWxsPVwibm9uZVwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIj5cbiAgICAgICAgICA8Y2lyY2xlIGNsYXNzPVwib3BhY2l0eS0yNVwiIGN4PVwiMTJcIiBjeT1cIjEyXCIgcj1cIjEwXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiNFwiPjwvY2lyY2xlPlxuICAgICAgICAgIDxwYXRoIGNsYXNzPVwib3BhY2l0eS03NVwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiTTQgMTJhOCA4IDAgMDE4LThWMEM1LjM3MyAwIDAgNS4zNzMgMCAxMmg0em0yIDUuMjkxQTcuOTYyIDcuOTYyIDAgMDE0IDEySDBjMCAzLjA0MiAxLjEzNSA1LjgyNCAzIDcuOTM4bDMtMi42NDd6XCI+PC9wYXRoPlxuICAgICAgICA8L3N2Zz5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8c3BhbiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHctZnVsbCBoLWZ1bGxcIiBbY2xhc3MuaW52aXNpYmxlXT1cImJ1c3lcIj5cbiAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgICAgPC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICBgLFxuICBzdHlsZXM6IFtgXG4gICAgOmhvc3QgeyBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IH1cbiAgICA6aG9zdCgudy1mdWxsKSB7IGRpc3BsYXk6IGJsb2NrOyB9XG5cbiAgICAvKiBDZW50ZXJpbmcgYW5kIFJlc2V0dGluZyBmb3IgaWNvbnMgKi9cbiAgICA6aG9zdCA6Om5nLWRlZXAgaSB7XG4gICAgICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgIGxpbmUtaGVpZ2h0OiAxO1xuICAgIH1cblxuICAgIC8qIE1BVENISU5HIFlPVVIgdGhlbWUuY3NzIExPR0lDOiBSZXNwb25zaXZlIGljb24gc2l6aW5nICovXG4gICAgOmhvc3QtY29udGV4dCguc2l6ZS14cykgOjpuZy1kZWVwIGksXG4gICAgOmhvc3QtY29udGV4dCguc2l6ZS1pY29uLXhzKSA6Om5nLWRlZXAgaSxcbiAgICA6aG9zdC1jb250ZXh0KC5zaXplLXNtKSA6Om5nLWRlZXAgaSxcbiAgICA6aG9zdC1jb250ZXh0KC5zaXplLWljb24tc20pIDo6bmctZGVlcCBpIHtcbiAgICAgIGZvbnQtc2l6ZTogMXJlbTsgLyogMTZweCAqL1xuICAgIH1cblxuICAgIDpob3N0LWNvbnRleHQoLnNpemUtZGVmYXVsdCkgOjpuZy1kZWVwIGksXG4gICAgOmhvc3QtY29udGV4dCguc2l6ZS1pY29uKSA6Om5nLWRlZXAgaSxcbiAgICA6aG9zdC1jb250ZXh0KC5zaXplLWxnKSA6Om5nLWRlZXAgaSxcbiAgICA6aG9zdC1jb250ZXh0KC5zaXplLWljb24tbGcpIDo6bmctZGVlcCBpIHtcbiAgICAgIGZvbnQtc2l6ZTogMS4ycmVtOyAvKiB+MTktMjBweCAqL1xuICAgIH1cbiAgYF1cbn0pXG5leHBvcnQgY2xhc3MgQnV0dG9uQ29tcG9uZW50IHtcbiAgQElucHV0KCkgY2xhc3M6IHN0cmluZyA9ICcnO1xuICBASW5wdXQoKSB2YXJpYW50OiBCdXR0b25Qcm9wc1sndmFyaWFudCddID0gJ2RlZmF1bHQnO1xuICBASW5wdXQoKSBzaXplOiBCdXR0b25Qcm9wc1snc2l6ZSddID0gJ2RlZmF1bHQnO1xuICBASW5wdXQoKSBibG9jazogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBkaXNhYmxlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBidXN5OiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIHJlYWRvbmx5OiBib29sZWFuID0gZmFsc2U7XG5cbiAgZ2V0IGNvbXB1dGVkQ2xhc3MoKSB7XG4gICAgcmV0dXJuIGNuKFxuICAgICAgYnV0dG9uVmFyaWFudHMoe1xuICAgICAgICB2YXJpYW50OiB0aGlzLnZhcmlhbnQsXG4gICAgICAgIHNpemU6IHRoaXMuc2l6ZSxcbiAgICAgICAgYmxvY2s6IHRoaXMuYmxvY2ssXG4gICAgICAgIGJ1c3k6IHRoaXMuYnVzeVxuICAgICAgfSksXG4gICAgICAvLyBBZGRzICdzaXplLWljb24tc20nLCAnc2l6ZS14cycsIGV0Yy4gZm9yIHRoZSBDU1Mgc2VsZWN0b3JzIHRvIHdvcmtcbiAgICAgICdzaXplLScgKyB0aGlzLnNpemUsXG4gICAgICB0aGlzLmNsYXNzXG4gICAgKTtcbiAgfVxufVxuIl19
@@ -18,10 +18,7 @@ function cn(...inputs) {
18
18
  return twMerge(clsx(inputs));
19
19
  }
20
20
 
21
- // 1. Define Component Variants (The "Recipe")
22
- const buttonVariants = cva(
23
- // Base styles applied to ALL buttons
24
- "inline-flex items-center justify-center 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 disabled:opacity-50 disabled:pointer-events-none ring-offset-background", {
21
+ const buttonVariants = cva("inline-flex items-center justify-center rounded-md text-sm font-medium transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background active:scale-[0.98]", {
25
22
  variants: {
26
23
  variant: {
27
24
  default: "bg-primary text-primary-foreground hover:bg-primary/90",
@@ -36,62 +33,79 @@ const buttonVariants = cva(
36
33
  xs: "h-8 px-2 py-1 text-xs",
37
34
  sm: "h-9 rounded-md px-3",
38
35
  lg: "h-11 rounded-md px-8",
36
+ // RESTORED: Square icon button variants
39
37
  "icon-xs": "h-8 w-8",
40
38
  "icon-sm": "h-9 w-9",
41
39
  icon: "h-10 w-10",
42
40
  "icon-lg": "h-11 w-11",
43
41
  },
44
- // Added block variant
45
- block: {
46
- true: "w-full flex",
47
- },
48
- // Added readonly variant
49
- readonly: {
50
- true: "pointer-events-none opacity-80",
51
- },
52
- disabled: {
53
- true: "pointer-events-none",
54
- }
42
+ block: { true: "w-full flex" },
43
+ busy: { true: "relative !cursor-wait !pointer-events-none" }
55
44
  },
56
45
  defaultVariants: {
57
46
  variant: "default",
58
47
  size: "default",
59
48
  block: false,
60
- readonly: false,
61
49
  },
62
50
  });
63
51
  class ButtonComponent {
64
- // Allow consumers to pass a custom class to override styles
65
52
  class = '';
66
- // Expose the variants as Inputs
67
53
  variant = 'default';
68
54
  size = 'default';
69
- // Added new inputs
70
55
  block = false;
71
- readonly = false;
72
56
  disabled = false;
73
- // Calculate the final string of classes
57
+ busy = false;
58
+ readonly = false;
74
59
  get computedClass() {
75
- return cn(buttonVariants({ variant: this.variant, size: this.size, block: this.block, disabled: this.disabled }), this.class);
60
+ return cn(buttonVariants({
61
+ variant: this.variant,
62
+ size: this.size,
63
+ block: this.block,
64
+ busy: this.busy
65
+ }),
66
+ // Adds 'size-icon-sm', 'size-xs', etc. for the CSS selectors to work
67
+ 'size-' + this.size, this.class);
76
68
  }
77
69
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
78
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ButtonComponent, isStandalone: true, selector: "tolle-button", inputs: { class: "class", variant: "variant", size: "size", block: "block", readonly: "readonly", disabled: "disabled" }, ngImport: i0, template: `
79
- <button [class]="computedClass" [disabled]="disabled" [attr.aria-readonly]="readonly">
80
- <span class="flex items-center justify-center gap-2 w-full h-full">
70
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ButtonComponent, isStandalone: true, selector: "tolle-button", inputs: { class: "class", variant: "variant", size: "size", block: "block", disabled: "disabled", busy: "busy", readonly: "readonly" }, ngImport: i0, template: `
71
+ <button
72
+ [class]="computedClass"
73
+ [disabled]="disabled || busy"
74
+ [attr.aria-busy]="busy"
75
+ >
76
+ <div *ngIf="busy" class="absolute inset-0 flex items-center justify-center">
77
+ <svg class="animate-spin h-5 w-5 text-current" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
78
+ <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
79
+ <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
80
+ </svg>
81
+ </div>
82
+
83
+ <span class="flex items-center justify-center w-full h-full" [class.invisible]="busy">
81
84
  <ng-content></ng-content>
82
85
  </span>
83
86
  </button>
84
- `, isInline: true, styles: [":host ::ng-deep i{display:inline-flex;align-items:center;line-height:1;font-size:1.25em}:host ::ng-deep i:not(:only-child){margin-right:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
87
+ `, isInline: true, styles: [":host{display:inline-block}:host(.w-full){display:block}:host ::ng-deep i{display:inline-flex;align-items:center;justify-content:center;line-height:1}:host-context(.size-xs) ::ng-deep i,:host-context(.size-icon-xs) ::ng-deep i,:host-context(.size-sm) ::ng-deep i,:host-context(.size-icon-sm) ::ng-deep i{font-size:1rem}:host-context(.size-default) ::ng-deep i,:host-context(.size-icon) ::ng-deep i,:host-context(.size-lg) ::ng-deep i,:host-context(.size-icon-lg) ::ng-deep i{font-size:1.2rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
85
88
  }
86
89
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ButtonComponent, decorators: [{
87
90
  type: Component,
88
91
  args: [{ selector: 'tolle-button', standalone: true, imports: [CommonModule], template: `
89
- <button [class]="computedClass" [disabled]="disabled" [attr.aria-readonly]="readonly">
90
- <span class="flex items-center justify-center gap-2 w-full h-full">
92
+ <button
93
+ [class]="computedClass"
94
+ [disabled]="disabled || busy"
95
+ [attr.aria-busy]="busy"
96
+ >
97
+ <div *ngIf="busy" class="absolute inset-0 flex items-center justify-center">
98
+ <svg class="animate-spin h-5 w-5 text-current" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
99
+ <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
100
+ <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
101
+ </svg>
102
+ </div>
103
+
104
+ <span class="flex items-center justify-center w-full h-full" [class.invisible]="busy">
91
105
  <ng-content></ng-content>
92
106
  </span>
93
107
  </button>
94
- `, styles: [":host ::ng-deep i{display:inline-flex;align-items:center;line-height:1;font-size:1.25em}:host ::ng-deep i:not(:only-child){margin-right:.5rem}\n"] }]
108
+ `, styles: [":host{display:inline-block}:host(.w-full){display:block}:host ::ng-deep i{display:inline-flex;align-items:center;justify-content:center;line-height:1}:host-context(.size-xs) ::ng-deep i,:host-context(.size-icon-xs) ::ng-deep i,:host-context(.size-sm) ::ng-deep i,:host-context(.size-icon-sm) ::ng-deep i{font-size:1rem}:host-context(.size-default) ::ng-deep i,:host-context(.size-icon) ::ng-deep i,:host-context(.size-lg) ::ng-deep i,:host-context(.size-icon-lg) ::ng-deep i{font-size:1.2rem}\n"] }]
95
109
  }], propDecorators: { class: [{
96
110
  type: Input
97
111
  }], variant: [{
@@ -100,10 +114,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
100
114
  type: Input
101
115
  }], block: [{
102
116
  type: Input
103
- }], readonly: [{
104
- type: Input
105
117
  }], disabled: [{
106
118
  type: Input
119
+ }], busy: [{
120
+ type: Input
121
+ }], readonly: [{
122
+ type: Input
107
123
  }] } });
108
124
 
109
125
  class InputComponent {