@tolle_/tolle-ui 0.0.1-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.
Files changed (77) hide show
  1. package/README.md +35 -0
  2. package/esm2022/lib/accordion-item.component.mjs +78 -0
  3. package/esm2022/lib/accordion.component.mjs +60 -0
  4. package/esm2022/lib/badge.component.mjs +76 -0
  5. package/esm2022/lib/button-group.component.mjs +25 -0
  6. package/esm2022/lib/button.component.mjs +70 -0
  7. package/esm2022/lib/calendar.component.mjs +315 -0
  8. package/esm2022/lib/card.component.mjs +94 -0
  9. package/esm2022/lib/checkbox.component.mjs +100 -0
  10. package/esm2022/lib/data-table.component.mjs +332 -0
  11. package/esm2022/lib/date-picker.component.mjs +232 -0
  12. package/esm2022/lib/date-range-picker.component.mjs +208 -0
  13. package/esm2022/lib/input.component.mjs +134 -0
  14. package/esm2022/lib/masked-input.component.mjs +179 -0
  15. package/esm2022/lib/modal-ref.mjs +31 -0
  16. package/esm2022/lib/modal-stack.service.mjs +26 -0
  17. package/esm2022/lib/modal.component.mjs +98 -0
  18. package/esm2022/lib/modal.mjs +27 -0
  19. package/esm2022/lib/modal.service.mjs +65 -0
  20. package/esm2022/lib/multi-select.component.mjs +231 -0
  21. package/esm2022/lib/pagination.component.mjs +279 -0
  22. package/esm2022/lib/range-calendar.component.mjs +285 -0
  23. package/esm2022/lib/select-group.component.mjs +28 -0
  24. package/esm2022/lib/select-item.component.mjs +84 -0
  25. package/esm2022/lib/select-separator.component.mjs +24 -0
  26. package/esm2022/lib/select.component.mjs +261 -0
  27. package/esm2022/lib/select.service.mjs +21 -0
  28. package/esm2022/lib/skeleton.component.mjs +34 -0
  29. package/esm2022/lib/switch.component.mjs +133 -0
  30. package/esm2022/lib/toast.service.mjs +59 -0
  31. package/esm2022/lib/tolle-cell.directive.mjs +22 -0
  32. package/esm2022/lib/tolle-config.mjs +11 -0
  33. package/esm2022/lib/tooltip.directive.mjs +71 -0
  34. package/esm2022/lib/types/date-range.mjs +2 -0
  35. package/esm2022/lib/utils/cn.mjs +6 -0
  36. package/esm2022/public-api.mjs +36 -0
  37. package/esm2022/tolle_-tolle-ui.mjs +5 -0
  38. package/fesm2022/tolle_-tolle-ui.mjs +3553 -0
  39. package/fesm2022/tolle_-tolle-ui.mjs.map +1 -0
  40. package/index.d.ts +5 -0
  41. package/lib/accordion-item.component.d.ts +13 -0
  42. package/lib/accordion.component.d.ts +14 -0
  43. package/lib/badge.component.d.ts +14 -0
  44. package/lib/button-group.component.d.ts +8 -0
  45. package/lib/button.component.d.ts +16 -0
  46. package/lib/calendar.component.d.ts +35 -0
  47. package/lib/card.component.d.ts +32 -0
  48. package/lib/checkbox.component.d.ts +23 -0
  49. package/lib/data-table.component.d.ts +45 -0
  50. package/lib/date-picker.component.d.ts +35 -0
  51. package/lib/date-range-picker.component.d.ts +36 -0
  52. package/lib/input.component.d.ts +27 -0
  53. package/lib/masked-input.component.d.ts +36 -0
  54. package/lib/modal-ref.d.ts +16 -0
  55. package/lib/modal-stack.service.d.ts +12 -0
  56. package/lib/modal.component.d.ts +19 -0
  57. package/lib/modal.d.ts +29 -0
  58. package/lib/modal.service.d.ts +18 -0
  59. package/lib/multi-select.component.d.ts +47 -0
  60. package/lib/pagination.component.d.ts +36 -0
  61. package/lib/range-calendar.component.d.ts +37 -0
  62. package/lib/select-group.component.d.ts +8 -0
  63. package/lib/select-item.component.d.ts +18 -0
  64. package/lib/select-separator.component.d.ts +8 -0
  65. package/lib/select.component.d.ts +45 -0
  66. package/lib/select.service.d.ts +10 -0
  67. package/lib/skeleton.component.d.ts +10 -0
  68. package/lib/switch.component.d.ts +39 -0
  69. package/lib/toast.service.d.ts +24 -0
  70. package/lib/tolle-cell.directive.d.ts +9 -0
  71. package/lib/tolle-config.d.ts +9 -0
  72. package/lib/tooltip.directive.d.ts +15 -0
  73. package/lib/types/date-range.d.ts +4 -0
  74. package/lib/utils/cn.d.ts +2 -0
  75. package/package.json +32 -0
  76. package/public-api.d.ts +32 -0
  77. package/theme.css +211 -0
package/README.md ADDED
@@ -0,0 +1,35 @@
1
+ ## 🛡️ License & Attribution
2
+
3
+ This library is **Open Source** and free to use for both personal and commercial projects.
4
+
5
+ However, you **cannot** replicate this library and claim it as your own work.
6
+ If you redistribute the source code or use it in a public project, the original
7
+ copyright notice and author attribution must remain intact.
8
+
9
+ **Built with ❤️ by Bernard Kojo Ossei-Agyei**
10
+
11
+ # @tolle/ui
12
+
13
+ A premium, high-performance Angular UI library meticulously crafted with a **Google Dark Mode** aesthetic. Built for speed, accessibility, and a modern "charcoal" look.
14
+
15
+
16
+
17
+ ## ✨ Features
18
+
19
+ - 🌑 **Google Dark Mode First:** Optimized for `#121212` backgrounds using `color-mix` CSS technology.
20
+ - ⚡ **Zero-Animation Base:** Clean, instant state changes for a "snappy" enterprise feel.
21
+ - 🧩 **Angular Native:** Built with Reactive Forms and `ControlValueAccessor` integration.
22
+ - 📏 **Unified Sizing:** Every component scales perfectly from `xs` to `lg`.
23
+ - 🔍 **Searchable Comboboxes:** Select components with built-in real-time filtering.
24
+ - 🍞 **Advanced Toast System:** Stackable notifications with "Pause-on-Hover" and progress timers.
25
+
26
+ ---
27
+
28
+ ## 🚀 Installation
29
+
30
+ Install the library and its peer dependency (Floating UI):
31
+
32
+ ```bash
33
+ npm install @tolle/ui @floating-ui/dom
34
+
35
+ @import "@tolle/ui/styles/theme.css";
@@ -0,0 +1,78 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { cn } from './utils/cn';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ export class AccordionItemComponent {
7
+ title = '';
8
+ class = '';
9
+ id;
10
+ isOpen = false;
11
+ // This will be set by the parent Accordion component
12
+ onToggle;
13
+ toggle() {
14
+ if (this.onToggle) {
15
+ this.onToggle(this.id);
16
+ }
17
+ else {
18
+ this.isOpen = !this.isOpen;
19
+ }
20
+ }
21
+ cn = cn;
22
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AccordionItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
23
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AccordionItemComponent, isStandalone: true, selector: "tolle-accordion-item", inputs: { title: "title", class: "class", id: "id" }, ngImport: i0, template: `
24
+ <div [class]="cn('flex flex-col border-b border-border', class)">
25
+ <button
26
+ type="button"
27
+ (click)="toggle()"
28
+ class="flex flex-1 items-center justify-between py-4 font-medium transition-all [&[data-state=open]>i]:rotate-180"
29
+ [attr.data-state]="isOpen ? 'open' : 'closed'"
30
+ >
31
+ <span class="text-left">{{ title }}</span>
32
+ <i class="ri-arrow-down-s-line text-muted-foreground transition-transform"></i>
33
+ </button>
34
+
35
+ <div
36
+ *ngIf="isOpen"
37
+ class="pb-4 text-sm text-muted-foreground overflow-hidden"
38
+ >
39
+ <ng-content></ng-content>
40
+ </div>
41
+ </div>
42
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
43
+ }
44
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AccordionItemComponent, decorators: [{
45
+ type: Component,
46
+ args: [{
47
+ selector: 'tolle-accordion-item',
48
+ standalone: true,
49
+ imports: [CommonModule],
50
+ template: `
51
+ <div [class]="cn('flex flex-col border-b border-border', class)">
52
+ <button
53
+ type="button"
54
+ (click)="toggle()"
55
+ class="flex flex-1 items-center justify-between py-4 font-medium transition-all [&[data-state=open]>i]:rotate-180"
56
+ [attr.data-state]="isOpen ? 'open' : 'closed'"
57
+ >
58
+ <span class="text-left">{{ title }}</span>
59
+ <i class="ri-arrow-down-s-line text-muted-foreground transition-transform"></i>
60
+ </button>
61
+
62
+ <div
63
+ *ngIf="isOpen"
64
+ class="pb-4 text-sm text-muted-foreground overflow-hidden"
65
+ >
66
+ <ng-content></ng-content>
67
+ </div>
68
+ </div>
69
+ `
70
+ }]
71
+ }], propDecorators: { title: [{
72
+ type: Input
73
+ }], class: [{
74
+ type: Input
75
+ }], id: [{
76
+ type: Input
77
+ }] } });
78
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjb3JkaW9uLWl0ZW0uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdG9sbGUvc3JjL2xpYi9hY2NvcmRpb24taXRlbS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQTZCLE1BQU0sZUFBZSxDQUFDO0FBQzVFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sWUFBWSxDQUFDOzs7QUEyQmhDLE1BQU0sT0FBTyxzQkFBc0I7SUFDeEIsS0FBSyxHQUFXLEVBQUUsQ0FBQztJQUNuQixLQUFLLEdBQVcsRUFBRSxDQUFDO0lBQ25CLEVBQUUsQ0FBbUI7SUFFOUIsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUVmLHFEQUFxRDtJQUNyRCxRQUFRLENBQWlDO0lBRXpDLE1BQU07UUFDSixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN6QixDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzdCLENBQUM7SUFDSCxDQUFDO0lBRWtCLEVBQUUsR0FBRyxFQUFFLENBQUM7d0dBbEJoQixzQkFBc0I7NEZBQXRCLHNCQUFzQixzSUFyQnZCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJULDJEQXBCUyxZQUFZOzs0RkFzQlgsc0JBQXNCO2tCQXpCbEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsc0JBQXNCO29CQUNoQyxVQUFVLEVBQUUsSUFBSTtvQkFDaEIsT0FBTyxFQUFFLENBQUMsWUFBWSxDQUFDO29CQUN2QixRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FtQlQ7aUJBQ0Y7OEJBRVUsS0FBSztzQkFBYixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxFQUFFO3NCQUFWLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBDb250ZW50Q2hpbGQsIFRlbXBsYXRlUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgY24gfSBmcm9tICcuL3V0aWxzL2NuJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtYWNjb3JkaW9uLWl0ZW0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IFtjbGFzc109XCJjbignZmxleCBmbGV4LWNvbCBib3JkZXItYiBib3JkZXItYm9yZGVyJywgY2xhc3MpXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAoY2xpY2spPVwidG9nZ2xlKClcIlxuICAgICAgICBjbGFzcz1cImZsZXggZmxleC0xIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWJldHdlZW4gcHktNCBmb250LW1lZGl1bSB0cmFuc2l0aW9uLWFsbCBbJltkYXRhLXN0YXRlPW9wZW5dPmldOnJvdGF0ZS0xODBcIlxuICAgICAgICBbYXR0ci5kYXRhLXN0YXRlXT1cImlzT3BlbiA/ICdvcGVuJyA6ICdjbG9zZWQnXCJcbiAgICAgID5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWxlZnRcIj57eyB0aXRsZSB9fTwvc3Bhbj5cbiAgICAgICAgPGkgY2xhc3M9XCJyaS1hcnJvdy1kb3duLXMtbGluZSB0ZXh0LW11dGVkLWZvcmVncm91bmQgdHJhbnNpdGlvbi10cmFuc2Zvcm1cIj48L2k+XG4gICAgICA8L2J1dHRvbj5cblxuICAgICAgPGRpdlxuICAgICAgICAqbmdJZj1cImlzT3BlblwiXG4gICAgICAgIGNsYXNzPVwicGItNCB0ZXh0LXNtIHRleHQtbXV0ZWQtZm9yZWdyb3VuZCBvdmVyZmxvdy1oaWRkZW5cIlxuICAgICAgPlxuICAgICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYFxufSlcbmV4cG9ydCBjbGFzcyBBY2NvcmRpb25JdGVtQ29tcG9uZW50IHtcbiAgQElucHV0KCkgdGl0bGU6IHN0cmluZyA9ICcnO1xuICBASW5wdXQoKSBjbGFzczogc3RyaW5nID0gJyc7XG4gIEBJbnB1dCgpIGlkITogc3RyaW5nIHwgbnVtYmVyO1xuXG4gIGlzT3BlbiA9IGZhbHNlO1xuXG4gIC8vIFRoaXMgd2lsbCBiZSBzZXQgYnkgdGhlIHBhcmVudCBBY2NvcmRpb24gY29tcG9uZW50XG4gIG9uVG9nZ2xlPzogKGlkOiBzdHJpbmcgfCBudW1iZXIpID0+IHZvaWQ7XG5cbiAgdG9nZ2xlKCkge1xuICAgIGlmICh0aGlzLm9uVG9nZ2xlKSB7XG4gICAgICB0aGlzLm9uVG9nZ2xlKHRoaXMuaWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmlzT3BlbiA9ICF0aGlzLmlzT3BlbjtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY24gPSBjbjtcbn1cbiJdfQ==
@@ -0,0 +1,60 @@
1
+ import { Component, Input, ContentChildren } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { AccordionItemComponent } from './accordion-item.component';
4
+ import { cn } from './utils/cn';
5
+ import * as i0 from "@angular/core";
6
+ export class AccordionComponent {
7
+ type = 'single';
8
+ class = '';
9
+ items;
10
+ ngAfterContentInit() {
11
+ this.items.forEach((item, index) => {
12
+ // Assign unique ID if none provided
13
+ if (item.id === undefined)
14
+ item.id = index;
15
+ // Hook into the item's toggle event
16
+ item.onToggle = (id) => this.handleToggle(id);
17
+ });
18
+ }
19
+ handleToggle(selectedId) {
20
+ this.items.forEach(item => {
21
+ if (item.id === selectedId) {
22
+ item.isOpen = !item.isOpen;
23
+ }
24
+ else {
25
+ // If type is 'single', close all other items
26
+ if (this.type === 'single') {
27
+ item.isOpen = false;
28
+ }
29
+ }
30
+ });
31
+ }
32
+ cn = cn;
33
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AccordionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
34
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: AccordionComponent, isStandalone: true, selector: "tolle-accordion", inputs: { type: "type", class: "class" }, queries: [{ propertyName: "items", predicate: AccordionItemComponent }], ngImport: i0, template: `
35
+ <div [class]="cn('w-full border-t border-border', class)">
36
+ <ng-content></ng-content>
37
+ </div>
38
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }] });
39
+ }
40
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AccordionComponent, decorators: [{
41
+ type: Component,
42
+ args: [{
43
+ selector: 'tolle-accordion',
44
+ standalone: true,
45
+ imports: [CommonModule],
46
+ template: `
47
+ <div [class]="cn('w-full border-t border-border', class)">
48
+ <ng-content></ng-content>
49
+ </div>
50
+ `
51
+ }]
52
+ }], propDecorators: { type: [{
53
+ type: Input
54
+ }], class: [{
55
+ type: Input
56
+ }], items: [{
57
+ type: ContentChildren,
58
+ args: [AccordionItemComponent]
59
+ }] } });
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjb3JkaW9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RvbGxlL3NyYy9saWIvYWNjb3JkaW9uLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQStCLE1BQU0sZUFBZSxDQUFDO0FBQy9GLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sWUFBWSxDQUFDOztBQVloQyxNQUFNLE9BQU8sa0JBQWtCO0lBQ3BCLElBQUksR0FBMEIsUUFBUSxDQUFDO0lBQ3ZDLEtBQUssR0FBVyxFQUFFLENBQUM7SUFFYSxLQUFLLENBQXFDO0lBRW5GLGtCQUFrQjtRQUNoQixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUNqQyxvQ0FBb0M7WUFDcEMsSUFBSSxJQUFJLENBQUMsRUFBRSxLQUFLLFNBQVM7Z0JBQUUsSUFBSSxDQUFDLEVBQUUsR0FBRyxLQUFLLENBQUM7WUFFM0Msb0NBQW9DO1lBQ3BDLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDaEQsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sWUFBWSxDQUFDLFVBQTJCO1FBQzlDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3hCLElBQUksSUFBSSxDQUFDLEVBQUUsS0FBSyxVQUFVLEVBQUUsQ0FBQztnQkFDM0IsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDN0IsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLDZDQUE2QztnQkFDN0MsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO29CQUMzQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztnQkFDdEIsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFa0IsRUFBRSxHQUFHLEVBQUUsQ0FBQzt3R0E3QmhCLGtCQUFrQjs0RkFBbEIsa0JBQWtCLDJJQUlaLHNCQUFzQiw2QkFWN0I7Ozs7R0FJVCwyREFMUyxZQUFZOzs0RkFPWCxrQkFBa0I7a0JBVjlCLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGlCQUFpQjtvQkFDM0IsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQztvQkFDdkIsUUFBUSxFQUFFOzs7O0dBSVQ7aUJBQ0Y7OEJBRVUsSUFBSTtzQkFBWixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFFbUMsS0FBSztzQkFBN0MsZUFBZTt1QkFBQyxzQkFBc0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBDb250ZW50Q2hpbGRyZW4sIFF1ZXJ5TGlzdCwgQWZ0ZXJDb250ZW50SW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEFjY29yZGlvbkl0ZW1Db21wb25lbnQgfSBmcm9tICcuL2FjY29yZGlvbi1pdGVtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBjbiB9IGZyb20gJy4vdXRpbHMvY24nO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0b2xsZS1hY2NvcmRpb24nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IFtjbGFzc109XCJjbigndy1mdWxsIGJvcmRlci10IGJvcmRlci1ib3JkZXInLCBjbGFzcylcIj5cbiAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICA8L2Rpdj5cbiAgYFxufSlcbmV4cG9ydCBjbGFzcyBBY2NvcmRpb25Db21wb25lbnQgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0IHtcbiAgQElucHV0KCkgdHlwZTogJ3NpbmdsZScgfCAnbXVsdGlwbGUnID0gJ3NpbmdsZSc7XG4gIEBJbnB1dCgpIGNsYXNzOiBzdHJpbmcgPSAnJztcblxuICBAQ29udGVudENoaWxkcmVuKEFjY29yZGlvbkl0ZW1Db21wb25lbnQpIGl0ZW1zITogUXVlcnlMaXN0PEFjY29yZGlvbkl0ZW1Db21wb25lbnQ+O1xuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICB0aGlzLml0ZW1zLmZvckVhY2goKGl0ZW0sIGluZGV4KSA9PiB7XG4gICAgICAvLyBBc3NpZ24gdW5pcXVlIElEIGlmIG5vbmUgcHJvdmlkZWRcbiAgICAgIGlmIChpdGVtLmlkID09PSB1bmRlZmluZWQpIGl0ZW0uaWQgPSBpbmRleDtcblxuICAgICAgLy8gSG9vayBpbnRvIHRoZSBpdGVtJ3MgdG9nZ2xlIGV2ZW50XG4gICAgICBpdGVtLm9uVG9nZ2xlID0gKGlkKSA9PiB0aGlzLmhhbmRsZVRvZ2dsZShpZCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVRvZ2dsZShzZWxlY3RlZElkOiBzdHJpbmcgfCBudW1iZXIpIHtcbiAgICB0aGlzLml0ZW1zLmZvckVhY2goaXRlbSA9PiB7XG4gICAgICBpZiAoaXRlbS5pZCA9PT0gc2VsZWN0ZWRJZCkge1xuICAgICAgICBpdGVtLmlzT3BlbiA9ICFpdGVtLmlzT3BlbjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIElmIHR5cGUgaXMgJ3NpbmdsZScsIGNsb3NlIGFsbCBvdGhlciBpdGVtc1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnc2luZ2xlJykge1xuICAgICAgICAgIGl0ZW0uaXNPcGVuID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCByZWFkb25seSBjbiA9IGNuO1xufVxuIl19
@@ -0,0 +1,76 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { cn } from './utils/cn';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "@angular/common";
6
+ export class BadgeComponent {
7
+ variant = 'default';
8
+ size = 'default';
9
+ removable = false; // Toggle the "Pill" remove icon
10
+ class = '';
11
+ onRemove = new EventEmitter();
12
+ cn = cn;
13
+ get computedClass() {
14
+ return cn(
15
+ // Base styles - Pills are always rounded-full
16
+ 'inline-flex items-center justify-center rounded-full border px-2 py-0.5 font-medium transition-colors gap-1',
17
+ // Variants (Google Dark Mode theme)
18
+ this.variant === 'default' && 'border-transparent bg-primary text-primary-foreground', this.variant === 'secondary' && 'border-transparent bg-secondary text-secondary-foreground', this.variant === 'outline' && 'text-foreground border-border bg-transparent', this.variant === 'destructive' && 'border-transparent bg-destructive text-destructive-foreground',
19
+ // Sizing
20
+ this.size === 'xs' && 'px-1.5 py-0 text-[10px]', this.size === 'sm' && 'px-2 py-0 text-[11px]', this.size === 'default' && 'text-xs', this.class);
21
+ }
22
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
23
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: BadgeComponent, isStandalone: true, selector: "tolle-badge", inputs: { variant: "variant", size: "size", removable: "removable", class: "class" }, outputs: { onRemove: "onRemove" }, ngImport: i0, template: `
24
+ <div [class]="computedClass">
25
+ <ng-content select="[prefix]"></ng-content>
26
+
27
+ <span class="truncate">
28
+ <ng-content></ng-content>
29
+ </span>
30
+
31
+ <button
32
+ *ngIf="removable"
33
+ (click)="onRemove.emit($event)"
34
+ class="ml-1 -mr-1 rounded-full p-0.5 hover:bg-foreground/20 transition-colors outline-none focus:ring-1 focus:ring-ring"
35
+ >
36
+ <i class="ri-close-line text-[1.1em]"></i>
37
+ </button>
38
+ </div>
39
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
40
+ }
41
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: BadgeComponent, decorators: [{
42
+ type: Component,
43
+ args: [{
44
+ selector: 'tolle-badge',
45
+ standalone: true,
46
+ imports: [CommonModule],
47
+ template: `
48
+ <div [class]="computedClass">
49
+ <ng-content select="[prefix]"></ng-content>
50
+
51
+ <span class="truncate">
52
+ <ng-content></ng-content>
53
+ </span>
54
+
55
+ <button
56
+ *ngIf="removable"
57
+ (click)="onRemove.emit($event)"
58
+ class="ml-1 -mr-1 rounded-full p-0.5 hover:bg-foreground/20 transition-colors outline-none focus:ring-1 focus:ring-ring"
59
+ >
60
+ <i class="ri-close-line text-[1.1em]"></i>
61
+ </button>
62
+ </div>
63
+ `,
64
+ }]
65
+ }], propDecorators: { variant: [{
66
+ type: Input
67
+ }], size: [{
68
+ type: Input
69
+ }], removable: [{
70
+ type: Input
71
+ }], class: [{
72
+ type: Input
73
+ }], onRemove: [{
74
+ type: Output
75
+ }] } });
76
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFkZ2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdG9sbGUvc3JjL2xpYi9iYWRnZS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLFlBQVksQ0FBQzs7O0FBd0JoQyxNQUFNLE9BQU8sY0FBYztJQUNoQixPQUFPLEdBQXdELFNBQVMsQ0FBQztJQUN6RSxJQUFJLEdBQTRCLFNBQVMsQ0FBQztJQUMxQyxTQUFTLEdBQUcsS0FBSyxDQUFDLENBQUMsZ0NBQWdDO0lBQ25ELEtBQUssR0FBRyxFQUFFLENBQUM7SUFFVixRQUFRLEdBQUcsSUFBSSxZQUFZLEVBQWMsQ0FBQztJQUVqQyxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBRTNCLElBQUksYUFBYTtRQUNmLE9BQU8sRUFBRTtRQUNQLDhDQUE4QztRQUM5Qyw2R0FBNkc7UUFFN0csb0NBQW9DO1FBQ3BDLElBQUksQ0FBQyxPQUFPLEtBQUssU0FBUyxJQUFJLHVEQUF1RCxFQUNyRixJQUFJLENBQUMsT0FBTyxLQUFLLFdBQVcsSUFBSSwyREFBMkQsRUFDM0YsSUFBSSxDQUFDLE9BQU8sS0FBSyxTQUFTLElBQUksOENBQThDLEVBQzVFLElBQUksQ0FBQyxPQUFPLEtBQUssYUFBYSxJQUFJLCtEQUErRDtRQUVqRyxTQUFTO1FBQ1QsSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLElBQUkseUJBQXlCLEVBQy9DLElBQUksQ0FBQyxJQUFJLEtBQUssSUFBSSxJQUFJLHVCQUF1QixFQUM3QyxJQUFJLENBQUMsSUFBSSxLQUFLLFNBQVMsSUFBSSxTQUFTLEVBRXBDLElBQUksQ0FBQyxLQUFLLENBQ1gsQ0FBQztJQUNKLENBQUM7d0dBNUJVLGNBQWM7NEZBQWQsY0FBYyxnTUFsQmY7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQlQsMkRBakJTLFlBQVk7OzRGQW1CWCxjQUFjO2tCQXRCMUIsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsYUFBYTtvQkFDdkIsVUFBVSxFQUFFLElBQUk7b0JBQ2hCLE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQztvQkFDdkIsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JUO2lCQUNGOzhCQUVVLE9BQU87c0JBQWYsS0FBSztnQkFDRyxJQUFJO3NCQUFaLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBRUksUUFBUTtzQkFBakIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgY24gfSBmcm9tICcuL3V0aWxzL2NuJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndG9sbGUtYmFkZ2UnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IFtjbGFzc109XCJjb21wdXRlZENsYXNzXCI+XG4gICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJbcHJlZml4XVwiPjwvbmctY29udGVudD5cblxuICAgICAgPHNwYW4gY2xhc3M9XCJ0cnVuY2F0ZVwiPlxuICAgICAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gICAgICA8L3NwYW4+XG5cbiAgICAgIDxidXR0b25cbiAgICAgICAgKm5nSWY9XCJyZW1vdmFibGVcIlxuICAgICAgICAoY2xpY2spPVwib25SZW1vdmUuZW1pdCgkZXZlbnQpXCJcbiAgICAgICAgY2xhc3M9XCJtbC0xIC1tci0xIHJvdW5kZWQtZnVsbCBwLTAuNSBob3ZlcjpiZy1mb3JlZ3JvdW5kLzIwIHRyYW5zaXRpb24tY29sb3JzIG91dGxpbmUtbm9uZSBmb2N1czpyaW5nLTEgZm9jdXM6cmluZy1yaW5nXCJcbiAgICAgID5cbiAgICAgICAgPGkgY2xhc3M9XCJyaS1jbG9zZS1saW5lIHRleHQtWzEuMWVtXVwiPjwvaT5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBCYWRnZUNvbXBvbmVudCB7XG4gIEBJbnB1dCgpIHZhcmlhbnQ6ICdkZWZhdWx0JyB8ICdzZWNvbmRhcnknIHwgJ291dGxpbmUnIHwgJ2Rlc3RydWN0aXZlJyA9ICdkZWZhdWx0JztcbiAgQElucHV0KCkgc2l6ZTogJ3hzJyB8ICdzbScgfCAnZGVmYXVsdCcgPSAnZGVmYXVsdCc7XG4gIEBJbnB1dCgpIHJlbW92YWJsZSA9IGZhbHNlOyAvLyBUb2dnbGUgdGhlIFwiUGlsbFwiIHJlbW92ZSBpY29uXG4gIEBJbnB1dCgpIGNsYXNzID0gJyc7XG5cbiAgQE91dHB1dCgpIG9uUmVtb3ZlID0gbmV3IEV2ZW50RW1pdHRlcjxNb3VzZUV2ZW50PigpO1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBjbiA9IGNuO1xuXG4gIGdldCBjb21wdXRlZENsYXNzKCkge1xuICAgIHJldHVybiBjbihcbiAgICAgIC8vIEJhc2Ugc3R5bGVzIC0gUGlsbHMgYXJlIGFsd2F5cyByb3VuZGVkLWZ1bGxcbiAgICAgICdpbmxpbmUtZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcm91bmRlZC1mdWxsIGJvcmRlciBweC0yIHB5LTAuNSBmb250LW1lZGl1bSB0cmFuc2l0aW9uLWNvbG9ycyBnYXAtMScsXG5cbiAgICAgIC8vIFZhcmlhbnRzIChHb29nbGUgRGFyayBNb2RlIHRoZW1lKVxuICAgICAgdGhpcy52YXJpYW50ID09PSAnZGVmYXVsdCcgJiYgJ2JvcmRlci10cmFuc3BhcmVudCBiZy1wcmltYXJ5IHRleHQtcHJpbWFyeS1mb3JlZ3JvdW5kJyxcbiAgICAgIHRoaXMudmFyaWFudCA9PT0gJ3NlY29uZGFyeScgJiYgJ2JvcmRlci10cmFuc3BhcmVudCBiZy1zZWNvbmRhcnkgdGV4dC1zZWNvbmRhcnktZm9yZWdyb3VuZCcsXG4gICAgICB0aGlzLnZhcmlhbnQgPT09ICdvdXRsaW5lJyAmJiAndGV4dC1mb3JlZ3JvdW5kIGJvcmRlci1ib3JkZXIgYmctdHJhbnNwYXJlbnQnLFxuICAgICAgdGhpcy52YXJpYW50ID09PSAnZGVzdHJ1Y3RpdmUnICYmICdib3JkZXItdHJhbnNwYXJlbnQgYmctZGVzdHJ1Y3RpdmUgdGV4dC1kZXN0cnVjdGl2ZS1mb3JlZ3JvdW5kJyxcblxuICAgICAgLy8gU2l6aW5nXG4gICAgICB0aGlzLnNpemUgPT09ICd4cycgJiYgJ3B4LTEuNSBweS0wIHRleHQtWzEwcHhdJyxcbiAgICAgIHRoaXMuc2l6ZSA9PT0gJ3NtJyAmJiAncHgtMiBweS0wIHRleHQtWzExcHhdJyxcbiAgICAgIHRoaXMuc2l6ZSA9PT0gJ2RlZmF1bHQnICYmICd0ZXh0LXhzJyxcblxuICAgICAgdGhpcy5jbGFzc1xuICAgICk7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,25 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { cn } from './utils/cn';
4
+ import * as i0 from "@angular/core";
5
+ export class ButtonGroupComponent {
6
+ class = '';
7
+ cn = cn;
8
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ButtonGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
9
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ButtonGroupComponent, isStandalone: true, selector: "tolle-button-group", inputs: { class: "class" }, ngImport: i0, template: `
10
+ <div [class]="cn('inline-flex items-center -space-x-px rounded-md shadow-sm', class)">
11
+ <ng-content></ng-content>
12
+ </div>
13
+ `, isInline: true, styles: [":host{display:inline-block}:host ::ng-deep tolle-button:first-child button{@apply rounded-r-none;}:host ::ng-deep tolle-button:not(:first-child):not(:last-child) button{@apply rounded-none border-l-0;}:host ::ng-deep tolle-button:last-child:not(:first-child) button{@apply rounded-l-none border-l-0;}:host ::ng-deep tolle-button button:hover,:host ::ng-deep tolle-button button:focus{@apply z-10 relative;}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
14
+ }
15
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ButtonGroupComponent, decorators: [{
16
+ type: Component,
17
+ args: [{ selector: 'tolle-button-group', standalone: true, imports: [CommonModule], template: `
18
+ <div [class]="cn('inline-flex items-center -space-x-px rounded-md shadow-sm', class)">
19
+ <ng-content></ng-content>
20
+ </div>
21
+ `, styles: [":host{display:inline-block}:host ::ng-deep tolle-button:first-child button{@apply rounded-r-none;}:host ::ng-deep tolle-button:not(:first-child):not(:last-child) button{@apply rounded-none border-l-0;}:host ::ng-deep tolle-button:last-child:not(:first-child) button{@apply rounded-l-none border-l-0;}:host ::ng-deep tolle-button button:hover,:host ::ng-deep tolle-button button:focus{@apply z-10 relative;}\n"] }]
22
+ }], propDecorators: { class: [{
23
+ type: Input
24
+ }] } });
25
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnV0dG9uLWdyb3VwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RvbGxlL3NyYy9saWIvYnV0dG9uLWdyb3VwLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLFlBQVksQ0FBQzs7QUFzQ2hDLE1BQU0sT0FBTyxvQkFBb0I7SUFDdEIsS0FBSyxHQUFXLEVBQUUsQ0FBQztJQUNsQixFQUFFLEdBQUcsRUFBRSxDQUFDO3dHQUZQLG9CQUFvQjs0RkFBcEIsb0JBQW9CLDBHQWhDckI7Ozs7R0FJVCxpZUFMUyxZQUFZOzs0RkFpQ1gsb0JBQW9CO2tCQXBDaEMsU0FBUzsrQkFDRSxvQkFBb0IsY0FDbEIsSUFBSSxXQUNQLENBQUMsWUFBWSxDQUFDLFlBQ2I7Ozs7R0FJVDs4QkE2QlEsS0FBSztzQkFBYixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IGNuIH0gZnJvbSAnLi91dGlscy9jbic7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3RvbGxlLWJ1dHRvbi1ncm91cCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgW2NsYXNzXT1cImNuKCdpbmxpbmUtZmxleCBpdGVtcy1jZW50ZXIgLXNwYWNlLXgtcHggcm91bmRlZC1tZCBzaGFkb3ctc20nLCBjbGFzcylcIj5cbiAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVzOiBbYFxuICAgIDpob3N0IHtcbiAgICAgIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgICB9XG5cbiAgICAvKiAxLiBGaXJzdCBCdXR0b246IFJlbW92ZSByaWdodCByb3VuZGluZyBhbmQga2VlcCBib3JkZXIgKi9cbiAgICA6aG9zdCA6Om5nLWRlZXAgdG9sbGUtYnV0dG9uOmZpcnN0LWNoaWxkIGJ1dHRvbiB7XG4gICAgICBAYXBwbHkgcm91bmRlZC1yLW5vbmU7XG4gICAgfVxuXG4gICAgLyogMi4gTWlkZGxlIEJ1dHRvbnM6IFJlbW92ZSBhbGwgcm91bmRpbmcgYW5kIHRoZSBsZWZ0IGJvcmRlciB0byBhdm9pZCBkb3VibGUtdGhpY2tuZXNzICovXG4gICAgOmhvc3QgOjpuZy1kZWVwIHRvbGxlLWJ1dHRvbjpub3QoOmZpcnN0LWNoaWxkKTpub3QoOmxhc3QtY2hpbGQpIGJ1dHRvbiB7XG4gICAgICBAYXBwbHkgcm91bmRlZC1ub25lIGJvcmRlci1sLTA7XG4gICAgfVxuXG4gICAgLyogMy4gTGFzdCBCdXR0b246IFJlbW92ZSBsZWZ0IHJvdW5kaW5nIGFuZCBsZWZ0IGJvcmRlciAqL1xuICAgIDpob3N0IDo6bmctZGVlcCB0b2xsZS1idXR0b246bGFzdC1jaGlsZDpub3QoOmZpcnN0LWNoaWxkKSBidXR0b24ge1xuICAgICAgQGFwcGx5IHJvdW5kZWQtbC1ub25lIGJvcmRlci1sLTA7XG4gICAgfVxuXG4gICAgLyogNC4gSG92ZXIvRm9jdXMgU3RhdGU6IEJyaW5nIHRoZSBhY3RpdmUgYnV0dG9uIHRvIHRoZSBmcm9udCBzbyB0aGUgZm9jdXMgcmluZyBpc24ndCBjdXQgb2ZmICovXG4gICAgOmhvc3QgOjpuZy1kZWVwIHRvbGxlLWJ1dHRvbiBidXR0b246aG92ZXIsXG4gICAgOmhvc3QgOjpuZy1kZWVwIHRvbGxlLWJ1dHRvbiBidXR0b246Zm9jdXMge1xuICAgICAgQGFwcGx5IHotMTAgcmVsYXRpdmU7XG4gICAgfVxuICBgXVxufSlcbmV4cG9ydCBjbGFzcyBCdXR0b25Hcm91cENvbXBvbmVudCB7XG4gIEBJbnB1dCgpIGNsYXNzOiBzdHJpbmcgPSAnJztcbiAgcHJvdGVjdGVkIGNuID0gY247XG59XG4iXX0=
@@ -0,0 +1,70 @@
1
+ import { Component, Input } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { cva } from 'class-variance-authority';
4
+ import { cn } from './utils/cn'; // Importing the helper we made in Phase 2
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", {
10
+ variants: {
11
+ variant: {
12
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
13
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
14
+ outline: "border border-input hover:bg-accent hover:text-accent-foreground",
15
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
16
+ ghost: "hover:bg-accent hover:text-accent-foreground",
17
+ link: "underline-offset-4 hover:underline text-primary",
18
+ },
19
+ size: {
20
+ default: "h-10 px-4 py-2",
21
+ xs: "h-8 px-2 py-1 text-xs",
22
+ sm: "h-9 rounded-md px-3",
23
+ lg: "h-11 rounded-md px-8",
24
+ "icon-xs": "h-8 w-8",
25
+ "icon-sm": "h-9 w-9",
26
+ icon: "h-10 w-10",
27
+ "icon-lg": "h-11 w-11",
28
+ },
29
+ },
30
+ defaultVariants: {
31
+ variant: "default",
32
+ size: "default",
33
+ },
34
+ });
35
+ export class ButtonComponent {
36
+ // Allow consumers to pass a custom class to override styles
37
+ class = '';
38
+ // Expose the variants as Inputs
39
+ variant = 'default';
40
+ size = 'default';
41
+ // Calculate the final string of classes
42
+ get computedClass() {
43
+ return cn(buttonVariants({ variant: this.variant, size: this.size }), this.class);
44
+ }
45
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
46
+ 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" }, ngImport: i0, template: `
47
+ <button [class]="computedClass">
48
+ <span class="flex items-center justify-center gap-2 w-full h-full">
49
+ <ng-content></ng-content>
50
+ </span>
51
+ </button>
52
+ `, 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 }] });
53
+ }
54
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ButtonComponent, decorators: [{
55
+ type: Component,
56
+ args: [{ selector: 'tolle-button', standalone: true, imports: [CommonModule], template: `
57
+ <button [class]="computedClass">
58
+ <span class="flex items-center justify-center gap-2 w-full h-full">
59
+ <ng-content></ng-content>
60
+ </span>
61
+ </button>
62
+ `, 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"] }]
63
+ }], propDecorators: { class: [{
64
+ type: Input
65
+ }], variant: [{
66
+ type: Input
67
+ }], size: [{
68
+ type: Input
69
+ }] } });
70
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnV0dG9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RvbGxlL3NyYy9saWIvYnV0dG9uLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLEdBQUcsRUFBcUIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsRUFBRSxFQUFFLE1BQU0sWUFBWSxDQUFDLENBQUMsMENBQTBDOztBQUUzRSw4Q0FBOEM7QUFDOUMsTUFBTSxjQUFjLEdBQUcsR0FBRztBQUN4QixxQ0FBcUM7QUFDckMsc1FBQXNRLEVBQ3RRO0lBQ0UsUUFBUSxFQUFFO1FBQ1IsT0FBTyxFQUFFO1lBQ1AsT0FBTyxFQUFFLHdEQUF3RDtZQUNqRSxXQUFXLEVBQUUsb0VBQW9FO1lBQ2pGLE9BQU8sRUFBRSxrRUFBa0U7WUFDM0UsU0FBUyxFQUFFLDhEQUE4RDtZQUN6RSxLQUFLLEVBQUUsOENBQThDO1lBQ3JELElBQUksRUFBRSxpREFBaUQ7U0FDeEQ7UUFDRCxJQUFJLEVBQUU7WUFDSixPQUFPLEVBQUUsZ0JBQWdCO1lBQ3pCLEVBQUUsRUFBRSx1QkFBdUI7WUFDM0IsRUFBRSxFQUFFLHFCQUFxQjtZQUN6QixFQUFFLEVBQUUsc0JBQXNCO1lBQzFCLFNBQVMsRUFBRSxTQUFTO1lBQ3BCLFNBQVMsRUFBRSxTQUFTO1lBQ3BCLElBQUksRUFBRSxXQUFXO1lBQ2pCLFNBQVMsRUFBRSxXQUFXO1NBQ3ZCO0tBQ0Y7SUFDRCxlQUFlLEVBQUU7UUFDZixPQUFPLEVBQUUsU0FBUztRQUNsQixJQUFJLEVBQUUsU0FBUztLQUNoQjtDQUNGLENBQ0YsQ0FBQztBQStCRixNQUFNLE9BQU8sZUFBZTtJQUMxQiw0REFBNEQ7SUFDbkQsS0FBSyxHQUFXLEVBQUUsQ0FBQztJQUU1QixnQ0FBZ0M7SUFDdkIsT0FBTyxHQUEyQixTQUFTLENBQUM7SUFDNUMsSUFBSSxHQUF3QixTQUFTLENBQUM7SUFFL0Msd0NBQXdDO0lBQ3hDLElBQUksYUFBYTtRQUNmLE9BQU8sRUFBRSxDQUFDLGNBQWMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDcEYsQ0FBQzt3R0FYVSxlQUFlOzRGQUFmLGVBQWUsc0lBdEJoQjs7Ozs7O0dBTVQseU5BUFMsWUFBWTs7NEZBdUJYLGVBQWU7a0JBMUIzQixTQUFTOytCQUNFLGNBQWMsY0FDWixJQUFJLFdBQ1AsQ0FBQyxZQUFZLENBQUMsWUFDYjs7Ozs7O0dBTVQ7OEJBa0JRLEtBQUs7c0JBQWIsS0FBSztnQkFHRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csSUFBSTtzQkFBWixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IGN2YSwgdHlwZSBWYXJpYW50UHJvcHMgfSBmcm9tICdjbGFzcy12YXJpYW5jZS1hdXRob3JpdHknO1xuaW1wb3J0IHsgY24gfSBmcm9tICcuL3V0aWxzL2NuJzsgLy8gSW1wb3J0aW5nIHRoZSBoZWxwZXIgd2UgbWFkZSBpbiBQaGFzZSAyXG5cbi8vIDEuIERlZmluZSBDb21wb25lbnQgVmFyaWFudHMgKFRoZSBcIlJlY2lwZVwiKVxuY29uc3QgYnV0dG9uVmFyaWFudHMgPSBjdmEoXG4gIC8vIEJhc2Ugc3R5bGVzIGFwcGxpZWQgdG8gQUxMIGJ1dHRvbnNcbiAgXCJpbmxpbmUtZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcm91bmRlZC1tZCB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRyYW5zaXRpb24tY29sb3JzIGZvY3VzLXZpc2libGU6b3V0bGluZS1ub25lIGZvY3VzLXZpc2libGU6cmluZy0yIGZvY3VzLXZpc2libGU6cmluZy1yaW5nIGZvY3VzLXZpc2libGU6cmluZy1vZmZzZXQtMiBkaXNhYmxlZDpvcGFjaXR5LTUwIGRpc2FibGVkOnBvaW50ZXItZXZlbnRzLW5vbmUgcmluZy1vZmZzZXQtYmFja2dyb3VuZFwiLFxuICB7XG4gICAgdmFyaWFudHM6IHtcbiAgICAgIHZhcmlhbnQ6IHtcbiAgICAgICAgZGVmYXVsdDogXCJiZy1wcmltYXJ5IHRleHQtcHJpbWFyeS1mb3JlZ3JvdW5kIGhvdmVyOmJnLXByaW1hcnkvOTBcIixcbiAgICAgICAgZGVzdHJ1Y3RpdmU6IFwiYmctZGVzdHJ1Y3RpdmUgdGV4dC1kZXN0cnVjdGl2ZS1mb3JlZ3JvdW5kIGhvdmVyOmJnLWRlc3RydWN0aXZlLzkwXCIsXG4gICAgICAgIG91dGxpbmU6IFwiYm9yZGVyIGJvcmRlci1pbnB1dCBob3ZlcjpiZy1hY2NlbnQgaG92ZXI6dGV4dC1hY2NlbnQtZm9yZWdyb3VuZFwiLFxuICAgICAgICBzZWNvbmRhcnk6IFwiYmctc2Vjb25kYXJ5IHRleHQtc2Vjb25kYXJ5LWZvcmVncm91bmQgaG92ZXI6Ymctc2Vjb25kYXJ5LzgwXCIsXG4gICAgICAgIGdob3N0OiBcImhvdmVyOmJnLWFjY2VudCBob3Zlcjp0ZXh0LWFjY2VudC1mb3JlZ3JvdW5kXCIsXG4gICAgICAgIGxpbms6IFwidW5kZXJsaW5lLW9mZnNldC00IGhvdmVyOnVuZGVybGluZSB0ZXh0LXByaW1hcnlcIixcbiAgICAgIH0sXG4gICAgICBzaXplOiB7XG4gICAgICAgIGRlZmF1bHQ6IFwiaC0xMCBweC00IHB5LTJcIixcbiAgICAgICAgeHM6IFwiaC04IHB4LTIgcHktMSB0ZXh0LXhzXCIsXG4gICAgICAgIHNtOiBcImgtOSByb3VuZGVkLW1kIHB4LTNcIixcbiAgICAgICAgbGc6IFwiaC0xMSByb3VuZGVkLW1kIHB4LThcIixcbiAgICAgICAgXCJpY29uLXhzXCI6IFwiaC04IHctOFwiLFxuICAgICAgICBcImljb24tc21cIjogXCJoLTkgdy05XCIsXG4gICAgICAgIGljb246IFwiaC0xMCB3LTEwXCIsXG4gICAgICAgIFwiaWNvbi1sZ1wiOiBcImgtMTEgdy0xMVwiLFxuICAgICAgfSxcbiAgICB9LFxuICAgIGRlZmF1bHRWYXJpYW50czoge1xuICAgICAgdmFyaWFudDogXCJkZWZhdWx0XCIsXG4gICAgICBzaXplOiBcImRlZmF1bHRcIixcbiAgICB9LFxuICB9XG4pO1xuXG4vLyBIZWxwZXIgdHlwZSBmb3IgSW50ZWxsaXNlbnNlXG5leHBvcnQgdHlwZSBCdXR0b25Qcm9wcyA9IFZhcmlhbnRQcm9wczx0eXBlb2YgYnV0dG9uVmFyaWFudHM+O1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0b2xsZS1idXR0b24nLCAvLyBVc2FnZTogPHRvbGxlLWJ1dHRvbiB2YXJpYW50PVwiZGVzdHJ1Y3RpdmVcIj5cbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXG4gIHRlbXBsYXRlOiBgXG4gICAgPGJ1dHRvbiBbY2xhc3NdPVwiY29tcHV0ZWRDbGFzc1wiPlxuICAgICA8c3BhbiBjbGFzcz1cImZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIGdhcC0yIHctZnVsbCBoLWZ1bGxcIj5cbiAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgICAgPC9zcGFuPlxuICAgIDwvYnV0dG9uPlxuICBgLFxuICBzdHlsZXM6IFtgXG4gICAgLyogRW5zdXJlIFJlbWl4IEljb25zIGFsaWduIHZlcnRpY2FsbHkgd2l0aCB0ZXh0ICovXG4gICAgOmhvc3QgOjpuZy1kZWVwIGkge1xuICAgICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgbGluZS1oZWlnaHQ6IDE7XG4gICAgICBmb250LXNpemU6IDEuMjVlbTsgLyogU2NhbGVzIHJlbGF0aXZlIHRvIHRoZSBidXR0b24gdGV4dCBzaXplICovXG4gICAgfVxuXG4gICAgLyogU3BlY2lmaWMgc3BhY2luZyBpZiBpY29uIGlzIG5leHQgdG8gdGV4dCAqL1xuICAgIDpob3N0IDo6bmctZGVlcCBpOm5vdCg6b25seS1jaGlsZCkge1xuICAgICAgbWFyZ2luLXJpZ2h0OiAwLjVyZW07XG4gICAgfVxuICBgXVxufSlcbmV4cG9ydCBjbGFzcyBCdXR0b25Db21wb25lbnQge1xuICAvLyBBbGxvdyBjb25zdW1lcnMgdG8gcGFzcyBhIGN1c3RvbSBjbGFzcyB0byBvdmVycmlkZSBzdHlsZXNcbiAgQElucHV0KCkgY2xhc3M6IHN0cmluZyA9ICcnO1xuXG4gIC8vIEV4cG9zZSB0aGUgdmFyaWFudHMgYXMgSW5wdXRzXG4gIEBJbnB1dCgpIHZhcmlhbnQ6IEJ1dHRvblByb3BzWyd2YXJpYW50J10gPSAnZGVmYXVsdCc7XG4gIEBJbnB1dCgpIHNpemU6IEJ1dHRvblByb3BzWydzaXplJ10gPSAnZGVmYXVsdCc7XG5cbiAgLy8gQ2FsY3VsYXRlIHRoZSBmaW5hbCBzdHJpbmcgb2YgY2xhc3Nlc1xuICBnZXQgY29tcHV0ZWRDbGFzcygpIHtcbiAgICByZXR1cm4gY24oYnV0dG9uVmFyaWFudHMoeyB2YXJpYW50OiB0aGlzLnZhcmlhbnQsIHNpemU6IHRoaXMuc2l6ZSB9KSwgdGhpcy5jbGFzcyk7XG4gIH1cbn1cbiJdfQ==