@makigamestudio/ui-core 0.2.0 → 0.3.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.
|
@@ -384,6 +384,10 @@ class ActionButtonListComponent {
|
|
|
384
384
|
* PopoverController.create() sets properties directly, bypassing signal inputs.
|
|
385
385
|
*/
|
|
386
386
|
_buttonsFromProps = signal([], ...(ngDevMode ? [{ debugName: "_buttonsFromProps" }] : []));
|
|
387
|
+
/**
|
|
388
|
+
* Internal signal to store the Set of currently loading child button IDs.
|
|
389
|
+
*/
|
|
390
|
+
_loadingChildIdsFromProps = signal(null, ...(ngDevMode ? [{ debugName: "_loadingChildIdsFromProps" }] : []));
|
|
387
391
|
/**
|
|
388
392
|
* The list of action buttons to display (when used via template binding).
|
|
389
393
|
*/
|
|
@@ -404,6 +408,20 @@ class ActionButtonListComponent {
|
|
|
404
408
|
set buttonsFromPopover(value) {
|
|
405
409
|
this._buttonsFromProps.set(value);
|
|
406
410
|
}
|
|
411
|
+
/**
|
|
412
|
+
* Setter to capture loading child IDs signal passed via PopoverController.create({ componentProps }).
|
|
413
|
+
*/
|
|
414
|
+
set loadingChildIds(value) {
|
|
415
|
+
this._loadingChildIdsFromProps.set(value);
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Checks if a specific button is currently loading.
|
|
419
|
+
*/
|
|
420
|
+
isButtonLoading(button) {
|
|
421
|
+
const loadingChildIdsSignal = this._loadingChildIdsFromProps();
|
|
422
|
+
const loadingChildIds = loadingChildIdsSignal ? loadingChildIdsSignal() : new Set();
|
|
423
|
+
return button.loading || loadingChildIds.has(button.id);
|
|
424
|
+
}
|
|
407
425
|
/**
|
|
408
426
|
* Emits when a button is selected from the list.
|
|
409
427
|
*/
|
|
@@ -419,7 +437,7 @@ class ActionButtonListComponent {
|
|
|
419
437
|
* @param button - The clicked action button
|
|
420
438
|
*/
|
|
421
439
|
onButtonClick(button) {
|
|
422
|
-
if (button
|
|
440
|
+
if (this.isButtonLoading(button) || button.config?.disabled) {
|
|
423
441
|
return;
|
|
424
442
|
}
|
|
425
443
|
this.buttonSelect.emit(button);
|
|
@@ -431,11 +449,11 @@ class ActionButtonListComponent {
|
|
|
431
449
|
@for (button of buttonList(); track button.id) {
|
|
432
450
|
<ion-item
|
|
433
451
|
[button]="true"
|
|
434
|
-
[disabled]="button
|
|
452
|
+
[disabled]="isButtonLoading(button) || button.config?.disabled"
|
|
435
453
|
[detail]="button.type === dropdownType"
|
|
436
454
|
(click)="onButtonClick(button)"
|
|
437
455
|
>
|
|
438
|
-
@if (button.
|
|
456
|
+
@if (isButtonLoading(button) && (button.showLoadingSpinner ?? true)) {
|
|
439
457
|
<ion-spinner slot="start" name="crescent" />
|
|
440
458
|
} @else if (button.icon) {
|
|
441
459
|
<ion-icon slot="start" [name]="button.icon" />
|
|
@@ -450,7 +468,7 @@ class ActionButtonListComponent {
|
|
|
450
468
|
</ion-item>
|
|
451
469
|
}
|
|
452
470
|
</ion-list>
|
|
453
|
-
`, isInline: true, styles: [":host{display:block}ion-list{padding:0}ion-item{--padding-start: var(--maki-action-button-list-padding, 16px);--padding-end: var(--maki-action-button-list-padding, 16px);--min-height: var(--maki-action-button-list-item-height, 44px);cursor:pointer;width:
|
|
471
|
+
`, isInline: true, styles: [":host{display:block}::ng-deep ion-popover::part(content){width:fit-content}ion-list{padding:0}ion-item{--padding-start: var(--maki-action-button-list-padding, 16px);--padding-end: var(--maki-action-button-list-padding, 16px);--min-height: var(--maki-action-button-list-item-height, 44px);cursor:pointer;width:100%}ion-item[disabled]{cursor:not-allowed}ion-label{white-space:nowrap}ion-icon{font-size:var(--maki-action-button-list-icon-size, 20px);margin-inline-end:var(--maki-action-button-list-icon-gap, 12px)}ion-spinner{width:var(--maki-action-button-list-icon-size, 20px);height:var(--maki-action-button-list-icon-size, 20px);margin-inline-end:var(--maki-action-button-list-icon-gap, 12px)}\n"], dependencies: [{ kind: "component", type: IonList, selector: "ion-list", inputs: ["inset", "lines", "mode"] }, { kind: "component", type: IonItem, selector: "ion-item", inputs: ["button", "color", "detail", "detailIcon", "disabled", "download", "href", "lines", "mode", "rel", "routerAnimation", "routerDirection", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
454
472
|
}
|
|
455
473
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ActionButtonListComponent, decorators: [{
|
|
456
474
|
type: Component,
|
|
@@ -459,11 +477,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
459
477
|
@for (button of buttonList(); track button.id) {
|
|
460
478
|
<ion-item
|
|
461
479
|
[button]="true"
|
|
462
|
-
[disabled]="button
|
|
480
|
+
[disabled]="isButtonLoading(button) || button.config?.disabled"
|
|
463
481
|
[detail]="button.type === dropdownType"
|
|
464
482
|
(click)="onButtonClick(button)"
|
|
465
483
|
>
|
|
466
|
-
@if (button.
|
|
484
|
+
@if (isButtonLoading(button) && (button.showLoadingSpinner ?? true)) {
|
|
467
485
|
<ion-spinner slot="start" name="crescent" />
|
|
468
486
|
} @else if (button.icon) {
|
|
469
487
|
<ion-icon slot="start" [name]="button.icon" />
|
|
@@ -478,7 +496,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
478
496
|
</ion-item>
|
|
479
497
|
}
|
|
480
498
|
</ion-list>
|
|
481
|
-
`, styles: [":host{display:block}ion-list{padding:0}ion-item{--padding-start: var(--maki-action-button-list-padding, 16px);--padding-end: var(--maki-action-button-list-padding, 16px);--min-height: var(--maki-action-button-list-item-height, 44px);cursor:pointer;width:
|
|
499
|
+
`, styles: [":host{display:block}::ng-deep ion-popover::part(content){width:fit-content}ion-list{padding:0}ion-item{--padding-start: var(--maki-action-button-list-padding, 16px);--padding-end: var(--maki-action-button-list-padding, 16px);--min-height: var(--maki-action-button-list-item-height, 44px);cursor:pointer;width:100%}ion-item[disabled]{cursor:not-allowed}ion-label{white-space:nowrap}ion-icon{font-size:var(--maki-action-button-list-icon-size, 20px);margin-inline-end:var(--maki-action-button-list-icon-gap, 12px)}ion-spinner{width:var(--maki-action-button-list-icon-size, 20px);height:var(--maki-action-button-list-icon-size, 20px);margin-inline-end:var(--maki-action-button-list-icon-gap, 12px)}\n"] }]
|
|
482
500
|
}], ctorParameters: () => [], propDecorators: { buttons: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttons", required: false }] }], buttonSelect: [{ type: i0.Output, args: ["buttonSelect"] }] } });
|
|
483
501
|
|
|
484
502
|
/**
|
|
@@ -561,6 +579,11 @@ class ButtonComponent {
|
|
|
561
579
|
* Internal loading state for async handler execution.
|
|
562
580
|
*/
|
|
563
581
|
_isLoading = signal(false, ...(ngDevMode ? [{ debugName: "_isLoading" }] : []));
|
|
582
|
+
/**
|
|
583
|
+
* Set of child button IDs that are currently loading (for dropdowns).
|
|
584
|
+
* Tracks multiple concurrent loading operations.
|
|
585
|
+
*/
|
|
586
|
+
_loadingChildIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "_loadingChildIds" }] : []));
|
|
564
587
|
/**
|
|
565
588
|
* The action button configuration.
|
|
566
589
|
*/
|
|
@@ -576,13 +599,58 @@ class ButtonComponent {
|
|
|
576
599
|
*/
|
|
577
600
|
childSelect = output();
|
|
578
601
|
/**
|
|
579
|
-
*
|
|
602
|
+
* Checks if any child button is in a loading state and has showLoadingSpinner enabled.
|
|
603
|
+
*/
|
|
604
|
+
hasLoadingChild = computed(() => {
|
|
605
|
+
const btn = this.button();
|
|
606
|
+
if (btn.type !== ActionButtonType.Dropdown || !btn.children) {
|
|
607
|
+
return false;
|
|
608
|
+
}
|
|
609
|
+
const loadingChildIds = this._loadingChildIds();
|
|
610
|
+
return btn.children.some((child) => {
|
|
611
|
+
const isLoadingFromProp = child.loading && (child.showLoadingSpinner ?? true);
|
|
612
|
+
const isLoadingFromExecution = loadingChildIds.has(child.id) && (child.showLoadingSpinner ?? true);
|
|
613
|
+
return isLoadingFromProp || isLoadingFromExecution;
|
|
614
|
+
});
|
|
615
|
+
}, ...(ngDevMode ? [{ debugName: "hasLoadingChild" }] : []));
|
|
616
|
+
/**
|
|
617
|
+
* Combined loading state from external prop, internal async state, and child loading.
|
|
618
|
+
* Returns true if:
|
|
619
|
+
* - Internal loading state is active, OR
|
|
620
|
+
* - External loading prop is true, OR
|
|
621
|
+
* - Any child is loading AND parent has showLoadingSpinner !== false
|
|
622
|
+
*/
|
|
623
|
+
isLoading = computed(() => {
|
|
624
|
+
const btn = this.button();
|
|
625
|
+
const parentLoading = this._isLoading() || (btn.loading ?? false);
|
|
626
|
+
const childLoading = this.hasLoadingChild() && (btn.showLoadingSpinner ?? true);
|
|
627
|
+
return parentLoading || childLoading;
|
|
628
|
+
}, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
|
|
629
|
+
/**
|
|
630
|
+
* Whether to display the loading spinner.
|
|
631
|
+
* Shows spinner only if button is loading AND showLoadingSpinner is not false.
|
|
580
632
|
*/
|
|
581
|
-
|
|
633
|
+
showLoadingSpinner = computed(() => {
|
|
634
|
+
return this.isLoading() && (this.button().showLoadingSpinner ?? true);
|
|
635
|
+
}, ...(ngDevMode ? [{ debugName: "showLoadingSpinner" }] : []));
|
|
582
636
|
/**
|
|
583
|
-
* Whether the button is disabled
|
|
637
|
+
* Whether the button is disabled.
|
|
638
|
+
* - Non-dropdown buttons: Disabled when loading or explicitly disabled in config
|
|
639
|
+
* - Dropdown buttons: Only disabled when explicitly disabled in config or when parent itself is loading
|
|
640
|
+
* (not disabled by inherited child loading - user can still open dropdown to see loading children)
|
|
584
641
|
*/
|
|
585
|
-
isDisabled = computed(() =>
|
|
642
|
+
isDisabled = computed(() => {
|
|
643
|
+
const btn = this.button();
|
|
644
|
+
const configDisabled = btn.config?.disabled ?? false;
|
|
645
|
+
// For dropdown buttons, only disable if config says so or if parent itself is loading
|
|
646
|
+
// Don't disable for inherited child loading (user should be able to open dropdown)
|
|
647
|
+
if (btn.type === ActionButtonType.Dropdown) {
|
|
648
|
+
const parentSelfLoading = this._isLoading() || (btn.loading ?? false);
|
|
649
|
+
return configDisabled || parentSelfLoading;
|
|
650
|
+
}
|
|
651
|
+
// For non-dropdown buttons, disable when loading
|
|
652
|
+
return this.isLoading() || configDisabled;
|
|
653
|
+
}, ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
|
|
586
654
|
/**
|
|
587
655
|
* Determines the slot for the icon based on button type and label presence.
|
|
588
656
|
*/
|
|
@@ -644,19 +712,35 @@ class ButtonComponent {
|
|
|
644
712
|
const popover = await this.popoverCtrl.create({
|
|
645
713
|
component: ActionButtonListComponent,
|
|
646
714
|
componentProps: {
|
|
647
|
-
buttonsFromPopover: children
|
|
715
|
+
buttonsFromPopover: children,
|
|
716
|
+
loadingChildIds: this._loadingChildIds,
|
|
648
717
|
},
|
|
649
718
|
event,
|
|
650
719
|
translucent: true,
|
|
651
720
|
dismissOnSelect: true,
|
|
652
721
|
side: 'bottom',
|
|
653
722
|
alignment: 'end',
|
|
654
|
-
arrow: false
|
|
723
|
+
arrow: false,
|
|
655
724
|
});
|
|
656
725
|
await popover.present();
|
|
657
726
|
const { data, role } = await popover.onDidDismiss();
|
|
658
727
|
if (role === 'select' && data) {
|
|
659
|
-
|
|
728
|
+
// Add child to loading set and execute its handler
|
|
729
|
+
this._loadingChildIds.update((ids) => new Set([...ids, data.id]));
|
|
730
|
+
try {
|
|
731
|
+
const result = data.handler();
|
|
732
|
+
if (result instanceof Promise) {
|
|
733
|
+
await result;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
finally {
|
|
737
|
+
// Remove child from loading set
|
|
738
|
+
this._loadingChildIds.update((ids) => {
|
|
739
|
+
const newIds = new Set(ids);
|
|
740
|
+
newIds.delete(data.id);
|
|
741
|
+
return newIds;
|
|
742
|
+
});
|
|
743
|
+
}
|
|
660
744
|
this.childSelect.emit(data);
|
|
661
745
|
}
|
|
662
746
|
}
|
|
@@ -691,21 +775,19 @@ class ButtonComponent {
|
|
|
691
775
|
[title]="button().tooltip ?? ''"
|
|
692
776
|
(click)="onClick($event)"
|
|
693
777
|
>
|
|
694
|
-
@if (
|
|
695
|
-
<ion-spinner name="crescent" />
|
|
696
|
-
} @else {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
<ion-icon name="chevron-down-outline" slot="end" class="dropdown-icon" />
|
|
705
|
-
}
|
|
778
|
+
@if (showLoadingSpinner()) {
|
|
779
|
+
<ion-spinner [slot]="iconSlot()" name="crescent" />
|
|
780
|
+
} @else if (button().icon) {
|
|
781
|
+
<ion-icon [name]="button().icon" [slot]="iconSlot()" class="button-icon" />
|
|
782
|
+
}
|
|
783
|
+
@if (showLabel()) {
|
|
784
|
+
{{ button().label }}
|
|
785
|
+
}
|
|
786
|
+
@if (showDropdownIcon()) {
|
|
787
|
+
<ion-icon name="chevron-down-outline" slot="end" class="dropdown-icon" />
|
|
706
788
|
}
|
|
707
789
|
</ion-button>
|
|
708
|
-
`, isInline: true, styles: [":host{display:inline-block}ion-button{--padding-start: var(--maki-button-padding-start);--padding-end: var(--maki-button-padding-end)}ion-spinner{width:var(--maki-button-spinner-size,
|
|
790
|
+
`, isInline: true, styles: [":host{display:inline-block}ion-button{--padding-start: var(--maki-button-padding-start);--padding-end: var(--maki-button-padding-end)}ion-spinner{width:var(--maki-button-spinner-size, 16px);height:var(--maki-button-spinner-size, 16px);margin:0 4px 0 0}.button-icon{font-size:var(--maki-button-icon-size, 16px);margin:0 4px 0 0}.dropdown-icon{font-size:var(--maki-button-dropdown-icon-size, 16px);margin-inline-start:var(--maki-button-dropdown-icon-gap, 4px)}\n"], dependencies: [{ kind: "component", type: IonButton, selector: "ion-button", inputs: ["buttonType", "color", "disabled", "download", "expand", "fill", "form", "href", "mode", "rel", "routerAnimation", "routerDirection", "shape", "size", "strong", "target", "type"] }, { kind: "component", type: IonIcon, selector: "ion-icon", inputs: ["color", "flipRtl", "icon", "ios", "lazy", "md", "mode", "name", "sanitize", "size", "src"] }, { kind: "component", type: IonSpinner, selector: "ion-spinner", inputs: ["color", "duration", "name", "paused"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
709
791
|
}
|
|
710
792
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
711
793
|
type: Component,
|
|
@@ -722,21 +804,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.0", ngImpor
|
|
|
722
804
|
[title]="button().tooltip ?? ''"
|
|
723
805
|
(click)="onClick($event)"
|
|
724
806
|
>
|
|
725
|
-
@if (
|
|
726
|
-
<ion-spinner name="crescent" />
|
|
727
|
-
} @else {
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
<ion-icon name="chevron-down-outline" slot="end" class="dropdown-icon" />
|
|
736
|
-
}
|
|
807
|
+
@if (showLoadingSpinner()) {
|
|
808
|
+
<ion-spinner [slot]="iconSlot()" name="crescent" />
|
|
809
|
+
} @else if (button().icon) {
|
|
810
|
+
<ion-icon [name]="button().icon" [slot]="iconSlot()" class="button-icon" />
|
|
811
|
+
}
|
|
812
|
+
@if (showLabel()) {
|
|
813
|
+
{{ button().label }}
|
|
814
|
+
}
|
|
815
|
+
@if (showDropdownIcon()) {
|
|
816
|
+
<ion-icon name="chevron-down-outline" slot="end" class="dropdown-icon" />
|
|
737
817
|
}
|
|
738
818
|
</ion-button>
|
|
739
|
-
`, styles: [":host{display:inline-block}ion-button{--padding-start: var(--maki-button-padding-start);--padding-end: var(--maki-button-padding-end)}ion-spinner{width:var(--maki-button-spinner-size,
|
|
819
|
+
`, styles: [":host{display:inline-block}ion-button{--padding-start: var(--maki-button-padding-start);--padding-end: var(--maki-button-padding-end)}ion-spinner{width:var(--maki-button-spinner-size, 16px);height:var(--maki-button-spinner-size, 16px);margin:0 4px 0 0}.button-icon{font-size:var(--maki-button-icon-size, 16px);margin:0 4px 0 0}.dropdown-icon{font-size:var(--maki-button-dropdown-icon-size, 16px);margin-inline-start:var(--maki-button-dropdown-icon-gap, 4px)}\n"] }]
|
|
740
820
|
}], ctorParameters: () => [], propDecorators: { button: [{ type: i0.Input, args: [{ isSignal: true, alias: "button", required: true }] }], buttonClick: [{ type: i0.Output, args: ["buttonClick"] }], childSelect: [{ type: i0.Output, args: ["childSelect"] }] } });
|
|
741
821
|
|
|
742
822
|
/*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"makigamestudio-ui-core.mjs","sources":["../../../projects/ui-core/src/lib/models/test.class.ts","../../../projects/ui-core/src/lib/models/action-button-type.enum.ts","../../../projects/ui-core/src/lib/services/test.service.ts","../../../projects/ui-core/src/lib/components/test-card/test-card.component.ts","../../../projects/ui-core/src/lib/components/action-button-list/action-button-list.component.ts","../../../projects/ui-core/src/lib/components/button/button.component.ts","../../../projects/ui-core/src/public-api.ts","../../../projects/ui-core/src/makigamestudio-ui-core.ts"],"sourcesContent":["import { TestInterface } from './test.interface';\n\n/**\n * TestClass - Example class implementing TestInterface.\n * Demonstrates the pattern for creating model classes with validation and factory methods.\n */\nexport class TestClass implements TestInterface {\n readonly id: string;\n readonly title: string;\n readonly description?: string;\n readonly createdAt: Date;\n readonly isActive: boolean;\n readonly metadata?: Record<string, unknown>;\n\n constructor(data: TestInterface) {\n this.id = data.id;\n this.title = data.title;\n this.description = data.description;\n this.createdAt = data.createdAt instanceof Date ? data.createdAt : new Date(data.createdAt);\n this.isActive = data.isActive;\n this.metadata = data.metadata;\n }\n\n /**\n * Factory method to create a new TestClass instance with a generated ID.\n */\n static create(title: string, description?: string): TestClass {\n return new TestClass({\n id: crypto.randomUUID(),\n title,\n description,\n createdAt: new Date(),\n isActive: true\n });\n }\n\n /**\n * Creates a new instance with updated properties (immutable pattern).\n */\n update(changes: Partial<Omit<TestInterface, 'id' | 'createdAt'>>): TestClass {\n return new TestClass({\n ...this,\n ...changes\n });\n }\n\n /**\n * Returns a deactivated copy of this instance.\n */\n deactivate(): TestClass {\n return this.update({ isActive: false });\n }\n\n /**\n * Converts the instance to a plain JSON object.\n */\n toJSON(): TestInterface {\n return {\n id: this.id,\n title: this.title,\n description: this.description,\n createdAt: this.createdAt,\n isActive: this.isActive,\n metadata: this.metadata\n };\n }\n}\n","/**\n * @file Action button type enumeration\n * @description Defines the display types for action buttons\n */\n\n/**\n * Enumeration of action button display types.\n *\n * @example\n * ```typescript\n * const button: ActionButton = {\n * id: 'save-btn',\n * label: 'Save',\n * type: ActionButtonType.Default,\n * handler: () => console.log('Saved!')\n * };\n * ```\n */\nexport enum ActionButtonType {\n /**\n * Standard button with label and optional icon.\n */\n Default = 'default',\n\n /**\n * Button displaying only an icon, no label.\n */\n IconOnly = 'icon-only',\n\n /**\n * Button that opens a dropdown popover with child actions.\n */\n Dropdown = 'dropdown'\n}\n","import { Injectable, computed, signal } from '@angular/core';\nimport { TestClass } from '../models/test.class';\nimport { TestInterface } from '../models/test.interface';\n\n/**\n * TestService - Example service using Angular Signals for reactive state management.\n * Provided in root, demonstrating singleton service pattern with signal-based state.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TestService {\n // Private writable signal for internal state\n private readonly _items = signal<readonly TestClass[]>([]);\n private readonly _loading = signal<boolean>(false);\n private readonly _error = signal<string | null>(null);\n\n // Public readonly computed signals for consumers\n /** All items in the store */\n readonly items = this._items.asReadonly();\n\n /** Loading state indicator */\n readonly loading = this._loading.asReadonly();\n\n /** Current error message, if any */\n readonly error = this._error.asReadonly();\n\n /** Count of all items */\n readonly count = computed(() => this._items().length);\n\n /** Only active items */\n readonly activeItems = computed(() => this._items().filter(item => item.isActive));\n\n /** Count of active items */\n readonly activeCount = computed(() => this.activeItems().length);\n\n /**\n * Adds a new item to the store.\n */\n addItem(title: string, description?: string): TestClass {\n const newItem = TestClass.create(title, description);\n this._items.update(items => [...items, newItem]);\n this._error.set(null);\n return newItem;\n }\n\n /**\n * Removes an item by ID.\n */\n removeItem(id: string): boolean {\n const currentItems = this._items();\n const filteredItems = currentItems.filter(item => item.id !== id);\n\n if (filteredItems.length === currentItems.length) {\n return false;\n }\n\n this._items.set(filteredItems);\n return true;\n }\n\n /**\n * Updates an existing item by ID.\n */\n updateItem(\n id: string,\n changes: Partial<Omit<TestInterface, 'id' | 'createdAt'>>\n ): TestClass | null {\n let updatedItem: TestClass | null = null;\n\n this._items.update(items =>\n items.map(item => {\n if (item.id === id) {\n updatedItem = item.update(changes);\n return updatedItem;\n }\n return item;\n })\n );\n\n return updatedItem;\n }\n\n /**\n * Deactivates an item by ID.\n */\n deactivateItem(id: string): TestClass | null {\n return this.updateItem(id, { isActive: false });\n }\n\n /**\n * Gets an item by ID using computed lookup.\n */\n getItemById(id: string): TestClass | undefined {\n return this._items().find(item => item.id === id);\n }\n\n /**\n * Clears all items from the store.\n */\n clearAll(): void {\n this._items.set([]);\n this._error.set(null);\n }\n\n /**\n * Sets the loading state.\n */\n setLoading(loading: boolean): void {\n this._loading.set(loading);\n }\n\n /**\n * Sets an error message.\n */\n setError(error: string | null): void {\n this._error.set(error);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n input,\n output,\n viewChild\n} from '@angular/core';\nimport {\n IonButton,\n IonCard,\n IonCardContent,\n IonCardHeader,\n IonCardSubtitle,\n IonCardTitle,\n IonIcon\n} from '@ionic/angular/standalone';\nimport { addIcons } from 'ionicons';\nimport { createOutline, trashOutline } from 'ionicons/icons';\nimport { TestInterface } from '../../models/test.interface';\n\n/**\n * TestCardComponent - Standalone Ionic Card component demonstrating\n * Angular 21 best practices: OnPush, Signal inputs/outputs/queries.\n *\n * @example\n * ```html\n * <maki-test-card\n * [item]=\"myItem\"\n * [showActions]=\"true\"\n * (itemClick)=\"onItemClick($event)\"\n * (deleteClick)=\"onDelete($event)\"\n * />\n * ```\n */\n@Component({\n selector: 'maki-test-card',\n standalone: true,\n imports: [\n IonCard,\n IonCardHeader,\n IonCardTitle,\n IonCardSubtitle,\n IonCardContent,\n IonButton,\n IonIcon\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <ion-card #cardElement [class.inactive]=\"!item().isActive\" (click)=\"onCardClick()\">\n <ion-card-header>\n <ion-card-title>{{ item().title }}</ion-card-title>\n @if (formattedDate()) {\n <ion-card-subtitle>\n {{ formattedDate() }}\n @if (!item().isActive) {\n <span class=\"status-badge inactive\">Inactive</span>\n }\n </ion-card-subtitle>\n }\n </ion-card-header>\n\n @if (item().description) {\n <ion-card-content>\n <p>{{ item().description }}</p>\n </ion-card-content>\n }\n\n @if (showActions()) {\n <ion-card-content class=\"card-actions\">\n <ion-button fill=\"outline\" size=\"small\" (click)=\"onEditClick($event)\">\n <ion-icon slot=\"start\" name=\"create-outline\"></ion-icon>\n Edit\n </ion-button>\n <ion-button fill=\"outline\" size=\"small\" color=\"danger\" (click)=\"onDeleteClick($event)\">\n <ion-icon slot=\"start\" name=\"trash-outline\"></ion-icon>\n Delete\n </ion-button>\n </ion-card-content>\n }\n </ion-card>\n `,\n styles: [\n `\n :host {\n display: block;\n }\n\n ion-card {\n --background: var(--maki-card-background, var(--ion-card-background, #fff));\n --color: var(--maki-card-color, var(--ion-text-color));\n margin: var(--maki-card-margin, 16px);\n border-radius: var(--maki-card-border-radius, 12px);\n transition:\n opacity 0.2s ease,\n transform 0.2s ease;\n cursor: pointer;\n\n &:hover {\n transform: translateY(-2px);\n }\n\n &.inactive {\n opacity: 0.6;\n }\n }\n\n ion-card-title {\n color: var(--maki-primary, var(--ion-color-primary));\n font-weight: 600;\n }\n\n ion-card-subtitle {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .status-badge {\n font-size: 0.75rem;\n padding: 2px 8px;\n border-radius: 4px;\n font-weight: 500;\n\n &.inactive {\n background-color: var(--ion-color-medium-tint);\n color: var(--ion-color-medium-contrast);\n }\n }\n\n .card-actions {\n display: flex;\n gap: 8px;\n padding-top: 0;\n\n ion-button {\n --border-color: var(--maki-primary, var(--ion-color-primary));\n --color: var(--maki-primary, var(--ion-color-primary));\n }\n }\n `\n ]\n})\nexport class TestCardComponent {\n // Signal inputs\n readonly item = input.required<TestInterface>();\n readonly showActions = input<boolean>(false);\n\n // Signal outputs\n readonly itemClick = output<TestInterface>();\n readonly editClick = output<TestInterface>();\n readonly deleteClick = output<TestInterface>();\n\n // Signal queries\n readonly cardElement = viewChild<ElementRef<HTMLIonCardElement>>('cardElement');\n\n // Computed signals\n readonly formattedDate = computed(() => {\n const date = this.item().createdAt;\n if (!date) return '';\n\n const dateObj = date instanceof Date ? date : new Date(date);\n return dateObj.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric'\n });\n });\n\n constructor() {\n addIcons({ createOutline, trashOutline });\n }\n\n protected onCardClick(): void {\n this.itemClick.emit(this.item());\n }\n\n protected onEditClick(event: Event): void {\n event.stopPropagation();\n this.editClick.emit(this.item());\n }\n\n protected onDeleteClick(event: Event): void {\n event.stopPropagation();\n this.deleteClick.emit(this.item());\n }\n\n /**\n * Public method to focus the card element programmatically.\n */\n focus(): void {\n this.cardElement()?.nativeElement?.focus();\n }\n}\n","/**\n * @file Action Button List Component\n * @description Component for rendering a list of action buttons inside a popover\n */\n\nimport { ChangeDetectionStrategy, Component, inject, input, output, signal } from '@angular/core';\nimport { IonIcon, IonItem, IonLabel, IonList, IonSpinner, PopoverController } from '@ionic/angular/standalone';\nimport { addIcons } from 'ionicons';\n\nimport { ActionButtonType } from '../../models/action-button-type.enum';\nimport { ActionButton } from '../../models/action-button.interface';\n\n/**\n * Component that renders a list of action buttons for use in popovers/dropdowns.\n *\n * This component is designed to be used as the content of an `ion-popover`\n * created via `PopoverController`. When a button is selected, it dismisses\n * the popover and returns the selected button.\n *\n * @example\n * ```typescript\n * // Used internally by maki-button for dropdowns\n * // Can also be used standalone:\n * const popover = await popoverCtrl.create({\n * component: ActionButtonListComponent,\n * componentProps: { buttons: myButtons },\n * event: clickEvent\n * });\n * await popover.present();\n *\n * const { data } = await popover.onDidDismiss();\n * if (data) {\n * data.handler();\n * }\n * ```\n *\n * @usageNotes\n * ### Inputs\n * - `buttons` (required): Array of `ActionButton` objects to display\n *\n * ### Outputs\n * - `buttonSelect`: Emits the selected `ActionButton` when clicked\n */\n@Component({\n selector: 'maki-action-button-list',\n standalone: true,\n imports: [IonList, IonItem, IonIcon, IonLabel, IonSpinner],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <ion-list lines=\"none\">\n @for (button of buttonList(); track button.id) {\n <ion-item\n [button]=\"true\"\n [disabled]=\"button.loading || button.config?.disabled\"\n [detail]=\"button.type === dropdownType\"\n (click)=\"onButtonClick(button)\"\n >\n @if (button.loading) {\n <ion-spinner slot=\"start\" name=\"crescent\" />\n } @else if (button.icon) {\n <ion-icon slot=\"start\" [name]=\"button.icon\" />\n }\n @if (button.label) {\n <ion-label>{{ button.label }}</ion-label>\n }\n </ion-item>\n } @empty {\n <ion-item>\n <ion-label color=\"medium\">No actions available</ion-label>\n </ion-item>\n }\n </ion-list>\n `,\n styles: [\n `\n :host {\n display: block;\n }\n\n ion-list {\n padding: 0;\n }\n\n ion-item {\n --padding-start: var(--maki-action-button-list-padding, 16px);\n --padding-end: var(--maki-action-button-list-padding, 16px);\n --min-height: var(--maki-action-button-list-item-height, 44px);\n cursor: pointer;\n width: fit-content;\n }\n\n ion-label {\n white-space: nowrap;\n }\n\n ion-icon {\n font-size: var(--maki-action-button-list-icon-size, 20px);\n margin-inline-end: var(--maki-action-button-list-icon-gap, 12px);\n }\n\n ion-spinner {\n width: var(--maki-action-button-list-icon-size, 20px);\n height: var(--maki-action-button-list-icon-size, 20px);\n margin-inline-end: var(--maki-action-button-list-icon-gap, 12px);\n }\n `,\n ],\n})\nexport class ActionButtonListComponent {\n /**\n * Reference to ActionButtonType.Dropdown for template comparison.\n * @internal\n */\n protected readonly dropdownType = ActionButtonType.Dropdown;\n\n /**\n * Popover controller for dismissing the popover when an item is selected.\n */\n private readonly popoverCtrl = inject(PopoverController, { optional: true });\n\n /**\n * Internal signal to store buttons passed via componentProps.\n * PopoverController.create() sets properties directly, bypassing signal inputs.\n */\n private readonly _buttonsFromProps = signal<readonly ActionButton[]>([]);\n\n /**\n * The list of action buttons to display (when used via template binding).\n */\n readonly buttons = input<readonly ActionButton[]>([]);\n\n /**\n * Computed button list that works with both signal input and componentProps.\n * PopoverController passes buttons as a direct property, not through Angular's input system.\n */\n protected readonly buttonList = (): readonly ActionButton[] => {\n const fromProps = this._buttonsFromProps();\n const fromInput = this.buttons();\n return fromProps.length > 0 ? fromProps : fromInput;\n };\n\n /**\n * Setter to capture buttons passed via PopoverController.create({ componentProps }).\n * This is called when Ionic sets the property directly on the component instance.\n */\n set buttonsFromPopover(value: readonly ActionButton[]) {\n this._buttonsFromProps.set(value);\n }\n\n /**\n * Emits when a button is selected from the list.\n */\n readonly buttonSelect = output<ActionButton>();\n\n constructor() {\n // Register any icons that might be used\n addIcons({});\n }\n\n /**\n * Handles click on a button item.\n * Emits the selected button and dismisses the popover.\n *\n * @param button - The clicked action button\n */\n protected onButtonClick(button: ActionButton): void {\n if (button.loading || button.config?.disabled) {\n return;\n }\n\n this.buttonSelect.emit(button);\n this.popoverCtrl?.dismiss(button, 'select');\n }\n}\n","/**\n * @file Button Component\n * @description Configurable button component that renders ion-button based on ActionButton configuration\n */\n\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n output,\n signal\n} from '@angular/core';\nimport { IonButton, IonIcon, IonSpinner, PopoverController } from '@ionic/angular/standalone';\nimport { addIcons } from 'ionicons';\nimport { chevronDownOutline } from 'ionicons/icons';\n\nimport { ActionButtonType } from '../../models/action-button-type.enum';\nimport { ActionButton } from '../../models/action-button.interface';\nimport { ActionButtonListComponent } from '../action-button-list/action-button-list.component';\n\n/**\n * A configurable button component that renders an `ion-button` based on\n * an `ActionButton` configuration object.\n *\n * Features:\n * - Three display types: Default (label + icon), IconOnly, and Dropdown\n * - Automatic loading state management for async handlers\n * - Dropdown support via PopoverController with child actions\n * - Full Ionic button styling configuration (fill, size, color, shape, expand)\n * - Automatic chevron icon for dropdown buttons\n *\n * @example\n * ```html\n * <!-- Simple button -->\n * <maki-button [button]=\"saveButton\" />\n *\n * <!-- Icon-only button -->\n * <maki-button [button]=\"iconButton\" />\n *\n * <!-- Dropdown button -->\n * <maki-button [button]=\"menuButton\" />\n * ```\n *\n * @example\n * ```typescript\n * // In your component\n * saveButton: ActionButton = {\n * id: 'save',\n * label: 'Save',\n * icon: 'saveOutline',\n * type: ActionButtonType.Default,\n * config: { fill: 'solid', color: 'primary' },\n * handler: async () => {\n * await this.saveData();\n * }\n * };\n *\n * menuButton: ActionButton = {\n * id: 'menu',\n * label: 'Actions',\n * type: ActionButtonType.Dropdown,\n * handler: () => {},\n * children: [\n * { id: 'edit', label: 'Edit', icon: 'createOutline', type: ActionButtonType.Default, handler: () => this.edit() },\n * { id: 'delete', label: 'Delete', icon: 'trashOutline', type: ActionButtonType.Default, handler: () => this.delete() }\n * ]\n * };\n * ```\n *\n * @usageNotes\n * ### Inputs\n * - `button` (required): The `ActionButton` configuration object\n *\n * ### Outputs\n * - `buttonClick`: Emits the button configuration when clicked (for non-dropdown buttons)\n * - `childSelect`: Emits the selected child button (for dropdown buttons)\n *\n * ### Loading State\n * The component automatically manages loading state for async handlers.\n * When a handler returns a Promise, the button shows a spinner until it resolves/rejects.\n * You can also manually control loading via the `button.loading` property.\n *\n * ### Dropdown Behavior\n * For `ActionButtonType.Dropdown`, clicking the button opens an `ion-popover`\n * containing an `ActionButtonListComponent` with the child buttons.\n * When a child is selected, its handler is executed and `childSelect` is emitted.\n */\n@Component({\n selector: 'maki-button',\n standalone: true,\n imports: [IonButton, IonIcon, IonSpinner],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <ion-button\n [fill]=\"button().config?.fill\"\n [size]=\"button().config?.size\"\n [color]=\"button().config?.color\"\n [shape]=\"button().config?.shape\"\n [expand]=\"button().config?.expand\"\n [strong]=\"button().config?.strong\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"button().ariaLabel\"\n [title]=\"button().tooltip ?? ''\"\n (click)=\"onClick($event)\"\n >\n @if (isLoading()) {\n <ion-spinner name=\"crescent\" />\n } @else {\n @if (button().icon) {\n <ion-icon [name]=\"button().icon\" [slot]=\"iconSlot()\" />\n }\n @if (showLabel()) {\n {{ button().label }}\n }\n @if (showDropdownIcon()) {\n <ion-icon name=\"chevron-down-outline\" slot=\"end\" class=\"dropdown-icon\" />\n }\n }\n </ion-button>\n `,\n styles: [\n `\n :host {\n display: inline-block;\n }\n\n ion-button {\n --padding-start: var(--maki-button-padding-start);\n --padding-end: var(--maki-button-padding-end);\n }\n\n ion-spinner {\n width: var(--maki-button-spinner-size, 20px);\n height: var(--maki-button-spinner-size, 20px);\n }\n\n .dropdown-icon {\n font-size: var(--maki-button-dropdown-icon-size, 16px);\n margin-inline-start: var(--maki-button-dropdown-icon-gap, 4px);\n }\n `\n ]\n})\nexport class ButtonComponent {\n /**\n * Popover controller for creating dropdown popovers.\n */\n private readonly popoverCtrl = inject(PopoverController);\n\n /**\n * Internal loading state for async handler execution.\n */\n private readonly _isLoading = signal<boolean>(false);\n\n /**\n * The action button configuration.\n */\n readonly button = input.required<ActionButton>();\n\n /**\n * Emits when the button is clicked (for non-dropdown buttons).\n * Emits the button configuration that was clicked.\n */\n readonly buttonClick = output<ActionButton>();\n\n /**\n * Emits when a child button is selected from a dropdown.\n * Only emits for `ActionButtonType.Dropdown` buttons.\n */\n readonly childSelect = output<ActionButton>();\n\n /**\n * Combined loading state from external prop and internal async state.\n */\n readonly isLoading = computed(() => this._isLoading() || (this.button().loading ?? false));\n\n /**\n * Whether the button is disabled (from config or loading state).\n */\n readonly isDisabled = computed(\n () => this.isLoading() || (this.button().config?.disabled ?? false)\n );\n\n /**\n * Determines the slot for the icon based on button type and label presence.\n */\n readonly iconSlot = computed(() => {\n const btn = this.button();\n if (btn.type === ActionButtonType.IconOnly) {\n return 'icon-only';\n }\n return btn.label ? 'start' : 'icon-only';\n });\n\n /**\n * Whether to show the label text.\n */\n readonly showLabel = computed(() => {\n const btn = this.button();\n return btn.type !== ActionButtonType.IconOnly && btn.label;\n });\n\n /**\n * Whether to show the dropdown chevron icon.\n */\n readonly showDropdownIcon = computed(() => {\n const btn = this.button();\n return btn.type === ActionButtonType.Dropdown && !btn.config?.hideDropdownIcon;\n });\n\n constructor() {\n addIcons({ chevronDownOutline });\n }\n\n /**\n * Handles button click events.\n * For dropdown buttons, opens a popover with child actions.\n * For other buttons, executes the handler with auto-loading management.\n *\n * @param event - The click event\n */\n protected async onClick(event: Event): Promise<void> {\n const btn = this.button();\n\n if (this.isDisabled()) {\n return;\n }\n\n if (btn.type === ActionButtonType.Dropdown) {\n await this.openDropdown(event);\n } else {\n await this.executeHandler(btn);\n this.buttonClick.emit(btn);\n }\n }\n\n /**\n * Opens a dropdown popover with child action buttons.\n *\n * @param event - The triggering click event for popover positioning\n */\n private async openDropdown(event: Event): Promise<void> {\n const btn = this.button();\n const children = btn.children ?? [];\n\n if (children.length === 0) {\n return;\n }\n\n const popover = await this.popoverCtrl.create({\n component: ActionButtonListComponent,\n componentProps: {\n buttonsFromPopover: children\n },\n event,\n translucent: true,\n dismissOnSelect: true,\n side: 'bottom',\n alignment: 'end',\n arrow: false\n });\n\n await popover.present();\n\n const { data, role } = await popover.onDidDismiss<ActionButton>();\n\n if (role === 'select' && data) {\n await this.executeHandler(data);\n this.childSelect.emit(data);\n }\n }\n\n /**\n * Executes a button's handler with automatic loading state management.\n *\n * @param btn - The button whose handler to execute\n */\n private async executeHandler(btn: ActionButton): Promise<void> {\n const result = btn.handler();\n\n if (result instanceof Promise) {\n this._isLoading.set(true);\n try {\n await result;\n } finally {\n this._isLoading.set(false);\n }\n }\n }\n}\n","/*\n * Public API Surface of @makigamestudio/ui-core\n */\n\n// Models\nexport { TestClass } from './lib/models/test.class';\nexport type { TestInterface } from './lib/models/test.interface';\n\n// Action Button Models\nexport type { ActionButtonConfig } from './lib/models/action-button-config.interface';\nexport { ActionButtonType } from './lib/models/action-button-type.enum';\nexport type { ActionButton } from './lib/models/action-button.interface';\n\n// Services\nexport { TestService } from './lib/services/test.service';\n\n// Components\nexport { TestCardComponent } from './lib/components/test-card/test-card.component';\n\n// Action Button Components\nexport { ActionButtonListComponent } from './lib/components/action-button-list/action-button-list.component';\nexport { ButtonComponent } from './lib/components/button/button.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"makigamestudio-ui-core.mjs","sources":["../../../projects/ui-core/src/lib/models/test.class.ts","../../../projects/ui-core/src/lib/models/action-button-type.enum.ts","../../../projects/ui-core/src/lib/services/test.service.ts","../../../projects/ui-core/src/lib/components/test-card/test-card.component.ts","../../../projects/ui-core/src/lib/components/action-button-list/action-button-list.component.ts","../../../projects/ui-core/src/lib/components/button/button.component.ts","../../../projects/ui-core/src/public-api.ts","../../../projects/ui-core/src/makigamestudio-ui-core.ts"],"sourcesContent":["import { TestInterface } from './test.interface';\n\n/**\n * TestClass - Example class implementing TestInterface.\n * Demonstrates the pattern for creating model classes with validation and factory methods.\n */\nexport class TestClass implements TestInterface {\n readonly id: string;\n readonly title: string;\n readonly description?: string;\n readonly createdAt: Date;\n readonly isActive: boolean;\n readonly metadata?: Record<string, unknown>;\n\n constructor(data: TestInterface) {\n this.id = data.id;\n this.title = data.title;\n this.description = data.description;\n this.createdAt = data.createdAt instanceof Date ? data.createdAt : new Date(data.createdAt);\n this.isActive = data.isActive;\n this.metadata = data.metadata;\n }\n\n /**\n * Factory method to create a new TestClass instance with a generated ID.\n */\n static create(title: string, description?: string): TestClass {\n return new TestClass({\n id: crypto.randomUUID(),\n title,\n description,\n createdAt: new Date(),\n isActive: true\n });\n }\n\n /**\n * Creates a new instance with updated properties (immutable pattern).\n */\n update(changes: Partial<Omit<TestInterface, 'id' | 'createdAt'>>): TestClass {\n return new TestClass({\n ...this,\n ...changes\n });\n }\n\n /**\n * Returns a deactivated copy of this instance.\n */\n deactivate(): TestClass {\n return this.update({ isActive: false });\n }\n\n /**\n * Converts the instance to a plain JSON object.\n */\n toJSON(): TestInterface {\n return {\n id: this.id,\n title: this.title,\n description: this.description,\n createdAt: this.createdAt,\n isActive: this.isActive,\n metadata: this.metadata\n };\n }\n}\n","/**\n * @file Action button type enumeration\n * @description Defines the display types for action buttons\n */\n\n/**\n * Enumeration of action button display types.\n *\n * @example\n * ```typescript\n * const button: ActionButton = {\n * id: 'save-btn',\n * label: 'Save',\n * type: ActionButtonType.Default,\n * handler: () => console.log('Saved!')\n * };\n * ```\n */\nexport enum ActionButtonType {\n /**\n * Standard button with label and optional icon.\n */\n Default = 'default',\n\n /**\n * Button displaying only an icon, no label.\n */\n IconOnly = 'icon-only',\n\n /**\n * Button that opens a dropdown popover with child actions.\n */\n Dropdown = 'dropdown'\n}\n","import { Injectable, computed, signal } from '@angular/core';\nimport { TestClass } from '../models/test.class';\nimport { TestInterface } from '../models/test.interface';\n\n/**\n * TestService - Example service using Angular Signals for reactive state management.\n * Provided in root, demonstrating singleton service pattern with signal-based state.\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class TestService {\n // Private writable signal for internal state\n private readonly _items = signal<readonly TestClass[]>([]);\n private readonly _loading = signal<boolean>(false);\n private readonly _error = signal<string | null>(null);\n\n // Public readonly computed signals for consumers\n /** All items in the store */\n readonly items = this._items.asReadonly();\n\n /** Loading state indicator */\n readonly loading = this._loading.asReadonly();\n\n /** Current error message, if any */\n readonly error = this._error.asReadonly();\n\n /** Count of all items */\n readonly count = computed(() => this._items().length);\n\n /** Only active items */\n readonly activeItems = computed(() => this._items().filter(item => item.isActive));\n\n /** Count of active items */\n readonly activeCount = computed(() => this.activeItems().length);\n\n /**\n * Adds a new item to the store.\n */\n addItem(title: string, description?: string): TestClass {\n const newItem = TestClass.create(title, description);\n this._items.update(items => [...items, newItem]);\n this._error.set(null);\n return newItem;\n }\n\n /**\n * Removes an item by ID.\n */\n removeItem(id: string): boolean {\n const currentItems = this._items();\n const filteredItems = currentItems.filter(item => item.id !== id);\n\n if (filteredItems.length === currentItems.length) {\n return false;\n }\n\n this._items.set(filteredItems);\n return true;\n }\n\n /**\n * Updates an existing item by ID.\n */\n updateItem(\n id: string,\n changes: Partial<Omit<TestInterface, 'id' | 'createdAt'>>\n ): TestClass | null {\n let updatedItem: TestClass | null = null;\n\n this._items.update(items =>\n items.map(item => {\n if (item.id === id) {\n updatedItem = item.update(changes);\n return updatedItem;\n }\n return item;\n })\n );\n\n return updatedItem;\n }\n\n /**\n * Deactivates an item by ID.\n */\n deactivateItem(id: string): TestClass | null {\n return this.updateItem(id, { isActive: false });\n }\n\n /**\n * Gets an item by ID using computed lookup.\n */\n getItemById(id: string): TestClass | undefined {\n return this._items().find(item => item.id === id);\n }\n\n /**\n * Clears all items from the store.\n */\n clearAll(): void {\n this._items.set([]);\n this._error.set(null);\n }\n\n /**\n * Sets the loading state.\n */\n setLoading(loading: boolean): void {\n this._loading.set(loading);\n }\n\n /**\n * Sets an error message.\n */\n setError(error: string | null): void {\n this._error.set(error);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n input,\n output,\n viewChild\n} from '@angular/core';\nimport {\n IonButton,\n IonCard,\n IonCardContent,\n IonCardHeader,\n IonCardSubtitle,\n IonCardTitle,\n IonIcon\n} from '@ionic/angular/standalone';\nimport { addIcons } from 'ionicons';\nimport { createOutline, trashOutline } from 'ionicons/icons';\nimport { TestInterface } from '../../models/test.interface';\n\n/**\n * TestCardComponent - Standalone Ionic Card component demonstrating\n * Angular 21 best practices: OnPush, Signal inputs/outputs/queries.\n *\n * @example\n * ```html\n * <maki-test-card\n * [item]=\"myItem\"\n * [showActions]=\"true\"\n * (itemClick)=\"onItemClick($event)\"\n * (deleteClick)=\"onDelete($event)\"\n * />\n * ```\n */\n@Component({\n selector: 'maki-test-card',\n standalone: true,\n imports: [\n IonCard,\n IonCardHeader,\n IonCardTitle,\n IonCardSubtitle,\n IonCardContent,\n IonButton,\n IonIcon\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <ion-card #cardElement [class.inactive]=\"!item().isActive\" (click)=\"onCardClick()\">\n <ion-card-header>\n <ion-card-title>{{ item().title }}</ion-card-title>\n @if (formattedDate()) {\n <ion-card-subtitle>\n {{ formattedDate() }}\n @if (!item().isActive) {\n <span class=\"status-badge inactive\">Inactive</span>\n }\n </ion-card-subtitle>\n }\n </ion-card-header>\n\n @if (item().description) {\n <ion-card-content>\n <p>{{ item().description }}</p>\n </ion-card-content>\n }\n\n @if (showActions()) {\n <ion-card-content class=\"card-actions\">\n <ion-button fill=\"outline\" size=\"small\" (click)=\"onEditClick($event)\">\n <ion-icon slot=\"start\" name=\"create-outline\"></ion-icon>\n Edit\n </ion-button>\n <ion-button fill=\"outline\" size=\"small\" color=\"danger\" (click)=\"onDeleteClick($event)\">\n <ion-icon slot=\"start\" name=\"trash-outline\"></ion-icon>\n Delete\n </ion-button>\n </ion-card-content>\n }\n </ion-card>\n `,\n styles: [\n `\n :host {\n display: block;\n }\n\n ion-card {\n --background: var(--maki-card-background, var(--ion-card-background, #fff));\n --color: var(--maki-card-color, var(--ion-text-color));\n margin: var(--maki-card-margin, 16px);\n border-radius: var(--maki-card-border-radius, 12px);\n transition:\n opacity 0.2s ease,\n transform 0.2s ease;\n cursor: pointer;\n\n &:hover {\n transform: translateY(-2px);\n }\n\n &.inactive {\n opacity: 0.6;\n }\n }\n\n ion-card-title {\n color: var(--maki-primary, var(--ion-color-primary));\n font-weight: 600;\n }\n\n ion-card-subtitle {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n .status-badge {\n font-size: 0.75rem;\n padding: 2px 8px;\n border-radius: 4px;\n font-weight: 500;\n\n &.inactive {\n background-color: var(--ion-color-medium-tint);\n color: var(--ion-color-medium-contrast);\n }\n }\n\n .card-actions {\n display: flex;\n gap: 8px;\n padding-top: 0;\n\n ion-button {\n --border-color: var(--maki-primary, var(--ion-color-primary));\n --color: var(--maki-primary, var(--ion-color-primary));\n }\n }\n `\n ]\n})\nexport class TestCardComponent {\n // Signal inputs\n readonly item = input.required<TestInterface>();\n readonly showActions = input<boolean>(false);\n\n // Signal outputs\n readonly itemClick = output<TestInterface>();\n readonly editClick = output<TestInterface>();\n readonly deleteClick = output<TestInterface>();\n\n // Signal queries\n readonly cardElement = viewChild<ElementRef<HTMLIonCardElement>>('cardElement');\n\n // Computed signals\n readonly formattedDate = computed(() => {\n const date = this.item().createdAt;\n if (!date) return '';\n\n const dateObj = date instanceof Date ? date : new Date(date);\n return dateObj.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric'\n });\n });\n\n constructor() {\n addIcons({ createOutline, trashOutline });\n }\n\n protected onCardClick(): void {\n this.itemClick.emit(this.item());\n }\n\n protected onEditClick(event: Event): void {\n event.stopPropagation();\n this.editClick.emit(this.item());\n }\n\n protected onDeleteClick(event: Event): void {\n event.stopPropagation();\n this.deleteClick.emit(this.item());\n }\n\n /**\n * Public method to focus the card element programmatically.\n */\n focus(): void {\n this.cardElement()?.nativeElement?.focus();\n }\n}\n","/**\n * @file Action Button List Component\n * @description Component for rendering a list of action buttons inside a popover\n */\n\nimport { ChangeDetectionStrategy, Component, inject, input, output, signal, Signal } from '@angular/core';\nimport { IonIcon, IonItem, IonLabel, IonList, IonSpinner, PopoverController } from '@ionic/angular/standalone';\nimport { addIcons } from 'ionicons';\n\nimport { ActionButtonType } from '../../models/action-button-type.enum';\nimport { ActionButton } from '../../models/action-button.interface';\n\n/**\n * Component that renders a list of action buttons for use in popovers/dropdowns.\n *\n * This component is designed to be used as the content of an `ion-popover`\n * created via `PopoverController`. When a button is selected, it dismisses\n * the popover and returns the selected button.\n *\n * @example\n * ```typescript\n * // Used internally by maki-button for dropdowns\n * // Can also be used standalone:\n * const popover = await popoverCtrl.create({\n * component: ActionButtonListComponent,\n * componentProps: { buttons: myButtons },\n * event: clickEvent\n * });\n * await popover.present();\n *\n * const { data } = await popover.onDidDismiss();\n * if (data) {\n * data.handler();\n * }\n * ```\n *\n * @usageNotes\n * ### Inputs\n * - `buttons` (required): Array of `ActionButton` objects to display\n *\n * ### Outputs\n * - `buttonSelect`: Emits the selected `ActionButton` when clicked\n */\n@Component({\n selector: 'maki-action-button-list',\n standalone: true,\n imports: [IonList, IonItem, IonIcon, IonLabel, IonSpinner],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <ion-list lines=\"none\">\n @for (button of buttonList(); track button.id) {\n <ion-item\n [button]=\"true\"\n [disabled]=\"isButtonLoading(button) || button.config?.disabled\"\n [detail]=\"button.type === dropdownType\"\n (click)=\"onButtonClick(button)\"\n >\n @if (isButtonLoading(button) && (button.showLoadingSpinner ?? true)) {\n <ion-spinner slot=\"start\" name=\"crescent\" />\n } @else if (button.icon) {\n <ion-icon slot=\"start\" [name]=\"button.icon\" />\n }\n @if (button.label) {\n <ion-label>{{ button.label }}</ion-label>\n }\n </ion-item>\n } @empty {\n <ion-item>\n <ion-label color=\"medium\">No actions available</ion-label>\n </ion-item>\n }\n </ion-list>\n `,\n styles: [\n `\n :host {\n display: block;\n }\n\n ::ng-deep ion-popover::part(content) {\n width: fit-content;\n }\n\n ion-list {\n padding: 0;\n }\n\n ion-item {\n --padding-start: var(--maki-action-button-list-padding, 16px);\n --padding-end: var(--maki-action-button-list-padding, 16px);\n\n --min-height: var(--maki-action-button-list-item-height, 44px);\n\n cursor: pointer;\n\n width: 100%;\n }\n\n ion-item[disabled] {\n cursor: not-allowed;\n }\n\n ion-label {\n white-space: nowrap;\n }\n\n ion-icon {\n font-size: var(--maki-action-button-list-icon-size, 20px);\n margin-inline-end: var(--maki-action-button-list-icon-gap, 12px);\n }\n\n ion-spinner {\n width: var(--maki-action-button-list-icon-size, 20px);\n height: var(--maki-action-button-list-icon-size, 20px);\n margin-inline-end: var(--maki-action-button-list-icon-gap, 12px);\n }\n `,\n ],\n})\nexport class ActionButtonListComponent {\n /**\n * Reference to ActionButtonType.Dropdown for template comparison.\n * @internal\n */\n protected readonly dropdownType = ActionButtonType.Dropdown;\n\n /**\n * Popover controller for dismissing the popover when an item is selected.\n */\n private readonly popoverCtrl = inject(PopoverController, { optional: true });\n\n /**\n * Internal signal to store buttons passed via componentProps.\n * PopoverController.create() sets properties directly, bypassing signal inputs.\n */\n private readonly _buttonsFromProps = signal<readonly ActionButton[]>([]);\n\n /**\n * Internal signal to store the Set of currently loading child button IDs.\n */\n private readonly _loadingChildIdsFromProps = signal<Signal<ReadonlySet<string>> | null>(null);\n\n /**\n * The list of action buttons to display (when used via template binding).\n */\n readonly buttons = input<readonly ActionButton[]>([]);\n\n /**\n * Computed button list that works with both signal input and componentProps.\n * PopoverController passes buttons as a direct property, not through Angular's input system.\n */\n protected readonly buttonList = (): readonly ActionButton[] => {\n const fromProps = this._buttonsFromProps();\n const fromInput = this.buttons();\n return fromProps.length > 0 ? fromProps : fromInput;\n };\n\n /**\n * Setter to capture buttons passed via PopoverController.create({ componentProps }).\n * This is called when Ionic sets the property directly on the component instance.\n */\n set buttonsFromPopover(value: readonly ActionButton[]) {\n this._buttonsFromProps.set(value);\n }\n\n /**\n * Setter to capture loading child IDs signal passed via PopoverController.create({ componentProps }).\n */\n set loadingChildIds(value: Signal<ReadonlySet<string>>) {\n this._loadingChildIdsFromProps.set(value);\n }\n\n /**\n * Checks if a specific button is currently loading.\n */\n protected isButtonLoading(button: ActionButton): boolean {\n const loadingChildIdsSignal = this._loadingChildIdsFromProps();\n const loadingChildIds = loadingChildIdsSignal ? loadingChildIdsSignal() : new Set<string>();\n return button.loading || loadingChildIds.has(button.id);\n }\n\n /**\n * Emits when a button is selected from the list.\n */\n readonly buttonSelect = output<ActionButton>();\n\n constructor() {\n // Register any icons that might be used\n addIcons({});\n }\n\n /**\n * Handles click on a button item.\n * Emits the selected button and dismisses the popover.\n *\n * @param button - The clicked action button\n */\n protected onButtonClick(button: ActionButton): void {\n if (this.isButtonLoading(button) || button.config?.disabled) {\n return;\n }\n\n this.buttonSelect.emit(button);\n this.popoverCtrl?.dismiss(button, 'select');\n }\n}\n","/**\n * @file Button Component\n * @description Configurable button component that renders ion-button based on ActionButton configuration\n */\n\nimport { ChangeDetectionStrategy, Component, computed, inject, input, output, signal } from '@angular/core';\nimport { IonButton, IonIcon, IonSpinner, PopoverController } from '@ionic/angular/standalone';\nimport { addIcons } from 'ionicons';\nimport { chevronDownOutline } from 'ionicons/icons';\n\nimport { ActionButtonType } from '../../models/action-button-type.enum';\nimport { ActionButton } from '../../models/action-button.interface';\nimport { ActionButtonListComponent } from '../action-button-list/action-button-list.component';\n\n/**\n * A configurable button component that renders an `ion-button` based on\n * an `ActionButton` configuration object.\n *\n * Features:\n * - Three display types: Default (label + icon), IconOnly, and Dropdown\n * - Automatic loading state management for async handlers\n * - Dropdown support via PopoverController with child actions\n * - Full Ionic button styling configuration (fill, size, color, shape, expand)\n * - Automatic chevron icon for dropdown buttons\n *\n * @example\n * ```html\n * <!-- Simple button -->\n * <maki-button [button]=\"saveButton\" />\n *\n * <!-- Icon-only button -->\n * <maki-button [button]=\"iconButton\" />\n *\n * <!-- Dropdown button -->\n * <maki-button [button]=\"menuButton\" />\n * ```\n *\n * @example\n * ```typescript\n * // In your component\n * saveButton: ActionButton = {\n * id: 'save',\n * label: 'Save',\n * icon: 'saveOutline',\n * type: ActionButtonType.Default,\n * config: { fill: 'solid', color: 'primary' },\n * handler: async () => {\n * await this.saveData();\n * }\n * };\n *\n * menuButton: ActionButton = {\n * id: 'menu',\n * label: 'Actions',\n * type: ActionButtonType.Dropdown,\n * handler: () => {},\n * children: [\n * { id: 'edit', label: 'Edit', icon: 'createOutline', type: ActionButtonType.Default, handler: () => this.edit() },\n * { id: 'delete', label: 'Delete', icon: 'trashOutline', type: ActionButtonType.Default, handler: () => this.delete() }\n * ]\n * };\n * ```\n *\n * @usageNotes\n * ### Inputs\n * - `button` (required): The `ActionButton` configuration object\n *\n * ### Outputs\n * - `buttonClick`: Emits the button configuration when clicked (for non-dropdown buttons)\n * - `childSelect`: Emits the selected child button (for dropdown buttons)\n *\n * ### Loading State\n * The component automatically manages loading state for async handlers.\n * When a handler returns a Promise, the button shows a spinner until it resolves/rejects.\n * You can also manually control loading via the `button.loading` property.\n *\n * ### Dropdown Behavior\n * For `ActionButtonType.Dropdown`, clicking the button opens an `ion-popover`\n * containing an `ActionButtonListComponent` with the child buttons.\n * When a child is selected, its handler is executed and `childSelect` is emitted.\n */\n@Component({\n selector: 'maki-button',\n standalone: true,\n imports: [IonButton, IonIcon, IonSpinner],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <ion-button\n [fill]=\"button().config?.fill\"\n [size]=\"button().config?.size\"\n [color]=\"button().config?.color\"\n [shape]=\"button().config?.shape\"\n [expand]=\"button().config?.expand\"\n [strong]=\"button().config?.strong\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"button().ariaLabel\"\n [title]=\"button().tooltip ?? ''\"\n (click)=\"onClick($event)\"\n >\n @if (showLoadingSpinner()) {\n <ion-spinner [slot]=\"iconSlot()\" name=\"crescent\" />\n } @else if (button().icon) {\n <ion-icon [name]=\"button().icon\" [slot]=\"iconSlot()\" class=\"button-icon\" />\n }\n @if (showLabel()) {\n {{ button().label }}\n }\n @if (showDropdownIcon()) {\n <ion-icon name=\"chevron-down-outline\" slot=\"end\" class=\"dropdown-icon\" />\n }\n </ion-button>\n `,\n styles: [\n `\n :host {\n display: inline-block;\n }\n\n ion-button {\n --padding-start: var(--maki-button-padding-start);\n --padding-end: var(--maki-button-padding-end);\n }\n\n ion-spinner {\n width: var(--maki-button-spinner-size, 16px);\n height: var(--maki-button-spinner-size, 16px);\n margin: 0 4px 0 0;\n }\n\n .button-icon {\n font-size: var(--maki-button-icon-size, 16px);\n margin: 0 4px 0 0;\n }\n\n .dropdown-icon {\n font-size: var(--maki-button-dropdown-icon-size, 16px);\n margin-inline-start: var(--maki-button-dropdown-icon-gap, 4px);\n }\n `,\n ],\n})\nexport class ButtonComponent {\n /**\n * Popover controller for creating dropdown popovers.\n */\n private readonly popoverCtrl = inject(PopoverController);\n\n /**\n * Internal loading state for async handler execution.\n */\n private readonly _isLoading = signal<boolean>(false);\n\n /**\n * Set of child button IDs that are currently loading (for dropdowns).\n * Tracks multiple concurrent loading operations.\n */\n private readonly _loadingChildIds = signal<ReadonlySet<string>>(new Set());\n\n /**\n * The action button configuration.\n */\n readonly button = input.required<ActionButton>();\n\n /**\n * Emits when the button is clicked (for non-dropdown buttons).\n * Emits the button configuration that was clicked.\n */\n readonly buttonClick = output<ActionButton>();\n\n /**\n * Emits when a child button is selected from a dropdown.\n * Only emits for `ActionButtonType.Dropdown` buttons.\n */\n readonly childSelect = output<ActionButton>();\n\n /**\n * Checks if any child button is in a loading state and has showLoadingSpinner enabled.\n */\n private readonly hasLoadingChild = computed(() => {\n const btn = this.button();\n if (btn.type !== ActionButtonType.Dropdown || !btn.children) {\n return false;\n }\n const loadingChildIds = this._loadingChildIds();\n return btn.children.some((child) => {\n const isLoadingFromProp = child.loading && (child.showLoadingSpinner ?? true);\n const isLoadingFromExecution = loadingChildIds.has(child.id) && (child.showLoadingSpinner ?? true);\n return isLoadingFromProp || isLoadingFromExecution;\n });\n });\n\n /**\n * Combined loading state from external prop, internal async state, and child loading.\n * Returns true if:\n * - Internal loading state is active, OR\n * - External loading prop is true, OR\n * - Any child is loading AND parent has showLoadingSpinner !== false\n */\n readonly isLoading = computed(() => {\n const btn = this.button();\n const parentLoading = this._isLoading() || (btn.loading ?? false);\n const childLoading = this.hasLoadingChild() && (btn.showLoadingSpinner ?? true);\n return parentLoading || childLoading;\n });\n\n /**\n * Whether to display the loading spinner.\n * Shows spinner only if button is loading AND showLoadingSpinner is not false.\n */\n readonly showLoadingSpinner = computed(() => {\n return this.isLoading() && (this.button().showLoadingSpinner ?? true);\n });\n\n /**\n * Whether the button is disabled.\n * - Non-dropdown buttons: Disabled when loading or explicitly disabled in config\n * - Dropdown buttons: Only disabled when explicitly disabled in config or when parent itself is loading\n * (not disabled by inherited child loading - user can still open dropdown to see loading children)\n */\n readonly isDisabled = computed(() => {\n const btn = this.button();\n const configDisabled = btn.config?.disabled ?? false;\n\n // For dropdown buttons, only disable if config says so or if parent itself is loading\n // Don't disable for inherited child loading (user should be able to open dropdown)\n if (btn.type === ActionButtonType.Dropdown) {\n const parentSelfLoading = this._isLoading() || (btn.loading ?? false);\n return configDisabled || parentSelfLoading;\n }\n\n // For non-dropdown buttons, disable when loading\n return this.isLoading() || configDisabled;\n });\n\n /**\n * Determines the slot for the icon based on button type and label presence.\n */\n readonly iconSlot = computed(() => {\n const btn = this.button();\n if (btn.type === ActionButtonType.IconOnly) {\n return 'icon-only';\n }\n return btn.label ? 'start' : 'icon-only';\n });\n\n /**\n * Whether to show the label text.\n */\n readonly showLabel = computed(() => {\n const btn = this.button();\n return btn.type !== ActionButtonType.IconOnly && btn.label;\n });\n\n /**\n * Whether to show the dropdown chevron icon.\n */\n readonly showDropdownIcon = computed(() => {\n const btn = this.button();\n return btn.type === ActionButtonType.Dropdown && !btn.config?.hideDropdownIcon;\n });\n\n constructor() {\n addIcons({ chevronDownOutline });\n }\n\n /**\n * Handles button click events.\n * For dropdown buttons, opens a popover with child actions.\n * For other buttons, executes the handler with auto-loading management.\n *\n * @param event - The click event\n */\n protected async onClick(event: Event): Promise<void> {\n const btn = this.button();\n\n if (this.isDisabled()) {\n return;\n }\n\n if (btn.type === ActionButtonType.Dropdown) {\n await this.openDropdown(event);\n } else {\n await this.executeHandler(btn);\n this.buttonClick.emit(btn);\n }\n }\n\n /**\n * Opens a dropdown popover with child action buttons.\n *\n * @param event - The triggering click event for popover positioning\n */\n private async openDropdown(event: Event): Promise<void> {\n const btn = this.button();\n const children = btn.children ?? [];\n\n if (children.length === 0) {\n return;\n }\n\n const popover = await this.popoverCtrl.create({\n component: ActionButtonListComponent,\n componentProps: {\n buttonsFromPopover: children,\n loadingChildIds: this._loadingChildIds,\n },\n event,\n translucent: true,\n dismissOnSelect: true,\n side: 'bottom',\n alignment: 'end',\n arrow: false,\n });\n\n await popover.present();\n\n const { data, role } = await popover.onDidDismiss<ActionButton>();\n\n if (role === 'select' && data) {\n // Add child to loading set and execute its handler\n this._loadingChildIds.update((ids) => new Set([...ids, data.id]));\n try {\n const result = data.handler();\n if (result instanceof Promise) {\n await result;\n }\n } finally {\n // Remove child from loading set\n this._loadingChildIds.update((ids) => {\n const newIds = new Set(ids);\n newIds.delete(data.id);\n return newIds;\n });\n }\n this.childSelect.emit(data);\n }\n }\n\n /**\n * Executes a button's handler with automatic loading state management.\n *\n * @param btn - The button whose handler to execute\n */\n private async executeHandler(btn: ActionButton): Promise<void> {\n const result = btn.handler();\n\n if (result instanceof Promise) {\n this._isLoading.set(true);\n try {\n await result;\n } finally {\n this._isLoading.set(false);\n }\n }\n }\n}\n","/*\n * Public API Surface of @makigamestudio/ui-core\n */\n\n// Models\nexport { TestClass } from './lib/models/test.class';\nexport type { TestInterface } from './lib/models/test.interface';\n\n// Action Button Models\nexport type { ActionButtonConfig } from './lib/models/action-button-config.interface';\nexport { ActionButtonType } from './lib/models/action-button-type.enum';\nexport type { ActionButton } from './lib/models/action-button.interface';\n\n// Services\nexport { TestService } from './lib/services/test.service';\n\n// Components\nexport { TestCardComponent } from './lib/components/test-card/test-card.component';\n\n// Action Button Components\nexport { ActionButtonListComponent } from './lib/components/action-button-list/action-button-list.component';\nexport { ButtonComponent } from './lib/components/button/button.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/theme.css
CHANGED
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
/* Button Component (maki-button) */
|
|
84
84
|
--maki-button-padding-start: 8px;
|
|
85
85
|
--maki-button-padding-end: 8px;
|
|
86
|
-
--maki-button-spinner-size:
|
|
86
|
+
--maki-button-spinner-size: 16px;
|
|
87
87
|
--maki-button-dropdown-icon-size: 16px;
|
|
88
88
|
--maki-button-dropdown-icon-gap: 4px;
|
|
89
89
|
|
package/theme.scss
CHANGED
|
@@ -105,7 +105,7 @@
|
|
|
105
105
|
// ==============================================
|
|
106
106
|
--maki-button-padding-start: 8px;
|
|
107
107
|
--maki-button-padding-end: 8px;
|
|
108
|
-
--maki-button-spinner-size:
|
|
108
|
+
--maki-button-spinner-size: 16px;
|
|
109
109
|
--maki-button-dropdown-icon-size: 16px;
|
|
110
110
|
--maki-button-dropdown-icon-gap: 4px;
|
|
111
111
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { ElementRef } from '@angular/core';
|
|
2
|
+
import { ElementRef, Signal } from '@angular/core';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* TestInterface - Example interface exported from ui-core library.
|
|
@@ -230,6 +230,20 @@ interface ActionButton<T = void> {
|
|
|
230
230
|
* The button shows loading if either this or the internal state is true.
|
|
231
231
|
*/
|
|
232
232
|
readonly loading?: boolean;
|
|
233
|
+
/**
|
|
234
|
+
* Controls whether to display the loading spinner when the button is in a loading state.
|
|
235
|
+
* Defaults to `true` if not specified.
|
|
236
|
+
*
|
|
237
|
+
* When `false`, the button will still be disabled during loading, but the spinner will not be shown.
|
|
238
|
+
* This is useful when you want to indicate loading state without replacing the button's visual content.
|
|
239
|
+
*
|
|
240
|
+
* For dropdown buttons, this also controls loading state propagation from children:
|
|
241
|
+
* - If both parent and child have `showLoadingSpinner !== false`, the parent will show a spinner when ANY child is loading.
|
|
242
|
+
* - The parent dropdown remains clickable even when showing inherited child loading state.
|
|
243
|
+
*
|
|
244
|
+
* @default true
|
|
245
|
+
*/
|
|
246
|
+
readonly showLoadingSpinner?: boolean;
|
|
233
247
|
/**
|
|
234
248
|
* Child action buttons for dropdown menus.
|
|
235
249
|
* Only used when `type` is `ActionButtonType.Dropdown`.
|
|
@@ -390,6 +404,10 @@ declare class ActionButtonListComponent {
|
|
|
390
404
|
* PopoverController.create() sets properties directly, bypassing signal inputs.
|
|
391
405
|
*/
|
|
392
406
|
private readonly _buttonsFromProps;
|
|
407
|
+
/**
|
|
408
|
+
* Internal signal to store the Set of currently loading child button IDs.
|
|
409
|
+
*/
|
|
410
|
+
private readonly _loadingChildIdsFromProps;
|
|
393
411
|
/**
|
|
394
412
|
* The list of action buttons to display (when used via template binding).
|
|
395
413
|
*/
|
|
@@ -404,6 +422,14 @@ declare class ActionButtonListComponent {
|
|
|
404
422
|
* This is called when Ionic sets the property directly on the component instance.
|
|
405
423
|
*/
|
|
406
424
|
set buttonsFromPopover(value: readonly ActionButton[]);
|
|
425
|
+
/**
|
|
426
|
+
* Setter to capture loading child IDs signal passed via PopoverController.create({ componentProps }).
|
|
427
|
+
*/
|
|
428
|
+
set loadingChildIds(value: Signal<ReadonlySet<string>>);
|
|
429
|
+
/**
|
|
430
|
+
* Checks if a specific button is currently loading.
|
|
431
|
+
*/
|
|
432
|
+
protected isButtonLoading(button: ActionButton): boolean;
|
|
407
433
|
/**
|
|
408
434
|
* Emits when a button is selected from the list.
|
|
409
435
|
*/
|
|
@@ -496,6 +522,11 @@ declare class ButtonComponent {
|
|
|
496
522
|
* Internal loading state for async handler execution.
|
|
497
523
|
*/
|
|
498
524
|
private readonly _isLoading;
|
|
525
|
+
/**
|
|
526
|
+
* Set of child button IDs that are currently loading (for dropdowns).
|
|
527
|
+
* Tracks multiple concurrent loading operations.
|
|
528
|
+
*/
|
|
529
|
+
private readonly _loadingChildIds;
|
|
499
530
|
/**
|
|
500
531
|
* The action button configuration.
|
|
501
532
|
*/
|
|
@@ -511,11 +542,27 @@ declare class ButtonComponent {
|
|
|
511
542
|
*/
|
|
512
543
|
readonly childSelect: _angular_core.OutputEmitterRef<ActionButton<void>>;
|
|
513
544
|
/**
|
|
514
|
-
*
|
|
545
|
+
* Checks if any child button is in a loading state and has showLoadingSpinner enabled.
|
|
546
|
+
*/
|
|
547
|
+
private readonly hasLoadingChild;
|
|
548
|
+
/**
|
|
549
|
+
* Combined loading state from external prop, internal async state, and child loading.
|
|
550
|
+
* Returns true if:
|
|
551
|
+
* - Internal loading state is active, OR
|
|
552
|
+
* - External loading prop is true, OR
|
|
553
|
+
* - Any child is loading AND parent has showLoadingSpinner !== false
|
|
515
554
|
*/
|
|
516
555
|
readonly isLoading: _angular_core.Signal<boolean>;
|
|
517
556
|
/**
|
|
518
|
-
* Whether
|
|
557
|
+
* Whether to display the loading spinner.
|
|
558
|
+
* Shows spinner only if button is loading AND showLoadingSpinner is not false.
|
|
559
|
+
*/
|
|
560
|
+
readonly showLoadingSpinner: _angular_core.Signal<boolean>;
|
|
561
|
+
/**
|
|
562
|
+
* Whether the button is disabled.
|
|
563
|
+
* - Non-dropdown buttons: Disabled when loading or explicitly disabled in config
|
|
564
|
+
* - Dropdown buttons: Only disabled when explicitly disabled in config or when parent itself is loading
|
|
565
|
+
* (not disabled by inherited child loading - user can still open dropdown to see loading children)
|
|
519
566
|
*/
|
|
520
567
|
readonly isDisabled: _angular_core.Signal<boolean>;
|
|
521
568
|
/**
|