@nanahoshi/mona-ui 0.10.0 → 0.11.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.
Files changed (21) hide show
  1. package/fesm2022/nanahoshi-mona-ui-combo-box.mjs +53 -25
  2. package/fesm2022/nanahoshi-mona-ui-dropdown-list.mjs +53 -24
  3. package/fesm2022/nanahoshi-mona-ui-editor.mjs +3 -3
  4. package/fesm2022/nanahoshi-mona-ui-filter.mjs +1 -1
  5. package/fesm2022/{nanahoshi-mona-ui-grid-grid-footer-cell.component-CJmjLl7R.mjs → nanahoshi-mona-ui-grid-grid-footer-cell.component-C86jzKCU.mjs} +2 -2
  6. package/fesm2022/{nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-pGhsAcVA.mjs → nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-D_GxIU2u.mjs} +2 -2
  7. package/fesm2022/{nanahoshi-mona-ui-grid-grid-list.component-BhnFFIOl.mjs → nanahoshi-mona-ui-grid-grid-list.component-C9VBe6IU.mjs} +5 -5
  8. package/fesm2022/{nanahoshi-mona-ui-grid-grid-toggle.component-DE3ffsva.mjs → nanahoshi-mona-ui-grid-grid-toggle.component-BpgLVr6a.mjs} +2 -2
  9. package/fesm2022/{nanahoshi-mona-ui-grid-grid-virtual-list.component-7acNUovW.mjs → nanahoshi-mona-ui-grid-grid-virtual-list.component-9f5wNcOJ.mjs} +5 -5
  10. package/fesm2022/{nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-DaOemy_G.mjs → nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-CChyqXg7.mjs} +10 -10
  11. package/fesm2022/nanahoshi-mona-ui-grid.mjs +1 -1
  12. package/fesm2022/nanahoshi-mona-ui-internal-list.mjs +24 -21
  13. package/fesm2022/nanahoshi-mona-ui-multi-select.mjs +46 -12
  14. package/fesm2022/nanahoshi-mona-ui-pager.mjs +1 -1
  15. package/package.json +1 -1
  16. package/types/nanahoshi-mona-ui-auto-complete.d.ts +2 -2
  17. package/types/nanahoshi-mona-ui-combo-box.d.ts +26 -10
  18. package/types/nanahoshi-mona-ui-dropdown-list.d.ts +25 -9
  19. package/types/nanahoshi-mona-ui-dropdowns.d.ts +3 -3
  20. package/types/nanahoshi-mona-ui-internal-list.d.ts +13 -4
  21. package/types/nanahoshi-mona-ui-multi-select.d.ts +26 -10
@@ -700,7 +700,7 @@ class PagerComponent {
700
700
  }
701
701
  }
702
702
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PagerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
703
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: PagerComponent, isStandalone: true, selector: "mona-pager", inputs: { firstLast: { classPropertyName: "firstLast", publicName: "firstLast", isSignal: true, isRequired: false, transformFunction: null }, navigable: { classPropertyName: "navigable", publicName: "navigable", isSignal: true, isRequired: false, transformFunction: null }, pageInput: { classPropertyName: "pageInput", publicName: "pageInput", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeValues: { classPropertyName: "pageSizeValues", publicName: "pageSizeValues", isSignal: true, isRequired: false, transformFunction: null }, previousNext: { classPropertyName: "previousNext", publicName: "previousNext", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, showInfo: { classPropertyName: "showInfo", publicName: "showInfo", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, skip: { classPropertyName: "skip", publicName: "skip", isSignal: true, isRequired: false, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, userClasses: { classPropertyName: "userClasses", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, visiblePages: { classPropertyName: "visiblePages", publicName: "visiblePages", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange", pageSizeChange: "pageSizeChange" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "attr.tabindex": "navigable() ? 0 : null", "class": "baseClasses()" } }, queries: [{ propertyName: "navigationButtonsTemplateList", predicate: PagerNavigationButtonsTemplateDirective, isSignal: true }, { propertyName: "numericButtonsTemplate", first: true, predicate: PagerNumericButtonsTemplateDirective, descendants: true, isSignal: true }, { propertyName: "pageSizeTemplate", first: true, predicate: PagerPageSizeTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "pagerInfoTemplate", first: true, predicate: PagerInfoTemplateDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "pageSizeDropdownList", first: true, predicate: ["pageSizeDropdownList"], descendants: true, isSignal: true }], ngImport: i0, template: "@let numericButtonsTemplateRef = numericButtonsTemplate()?.templateRef;\n@let pageSizeTemplateRef = pageSizeTemplate();\n@let pagerInfoTemplateRef = pagerInfoTemplate()?.templateRef;\n\n@if (type() === \"numeric\") {\n @if (pageListVisible()) {\n <ol [class]=\"listClasses()\">\n @if (firstLast()) {\n <ng-container [ngTemplateOutlet]=\"firstPageButton\"></ng-container>\n }\n @if (previousNext()) {\n <ng-container [ngTemplateOutlet]=\"previousPageButton\"></ng-container>\n }\n\n @if (numericButtonsTemplateRef) {\n <ng-container\n [ngTemplateOutlet]=\"numericButtonsTemplateRef\"\n [ngTemplateOutletContext]=\"{ totalPages: pageCount() }\"></ng-container>\n } @else {\n @if (pages().length !== 0) {\n <li [class]=\"pageItemClasses(page() === 1)\">\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [selected]=\"page() === 1\"\n [attr.aria-label]=\"'Page 1'\"\n [attr.aria-current]=\"page() === 1 ? 'page' : null\"\n (click)=\"onPageClick(1)\">\n 1\n </button>\n </li>\n }\n @if (previousJumperVisible()) {\n <li>\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [attr.aria-label]=\"jumpPreviousLabel()\"\n (click)=\"onJumpPreviousClick()\">\n <svg lucideEllipsis [size]=\"iconSize()\"></svg>\n </button>\n </li>\n }\n\n @for (pageItem of pages() | monaSlice: 1 : pages().length - 1; track $index) {\n <li [attr.data-page]=\"pageItem.page\" [class]=\"pageItemClasses(page() === pageItem.page)\">\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [selected]=\"page() === pageItem.page\"\n [attr.aria-label]=\"'Page ' + pageItem.text\"\n [attr.aria-current]=\"page() === pageItem.page ? 'page' : null\"\n (click)=\"onPageClick(pageItem.page)\">\n {{ pageItem.text }}\n </button>\n </li>\n }\n\n @if (nextJumperVisible()) {\n <li>\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [attr.aria-label]=\"jumpNextLabel()\"\n (click)=\"onJumpNextClick()\">\n <svg lucideEllipsis [size]=\"iconSize()\"></svg>\n </button>\n </li>\n }\n\n @if (pages().length > 1) {\n <li [class]=\"pageItemClasses(page() === pageCount())\">\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [selected]=\"page() === pageCount()\"\n [attr.aria-label]=\"'Page ' + pageCount()\"\n [attr.aria-current]=\"page() === pageCount() ? 'page' : null\"\n (click)=\"onPageClick(pageCount())\">\n {{ pageCount() }}\n </button>\n </li>\n }\n }\n\n @if (previousNext()) {\n <ng-container [ngTemplateOutlet]=\"nextPageButton\"></ng-container>\n }\n\n @if (firstLast()) {\n <ng-container [ngTemplateOutlet]=\"lastPageButton\"></ng-container>\n }\n\n @if (pageInputVisible() && pageInput()) {\n <li>\n <mona-numeric-text-box\n monaPagerFocusable\n [spinners]=\"false\"\n [minValue]=\"1\"\n [maxValue]=\"pageCount()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [ngModel]=\"inputValue()\"\n (ngModelChange)=\"inputValue.set($event)\"\n (inputBlur)=\"onPageInputBlur()\"></mona-numeric-text-box>\n </li>\n }\n\n @if (pageInputVisible() && pageSizeDropdownData().length > 0) {\n <li>\n @if (pageSizeTemplateRef) {\n <ng-container\n [ngTemplateOutlet]=\"pageSizeTemplateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: pageSizeDropdownData() }\">\n </ng-container>\n } @else {\n <mona-dropdown-list\n monaPagerFocusable\n [data]=\"pageSizeDropdownData()\"\n [ngModel]=\"pageSize()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n (ngModelChange)=\"onPageSizeValueChange($event)\"\n #pageSizeDropdownList>\n <ng-template monaDropDownListValueTemplate let-item>\n <span>{{ item }} / page</span>\n </ng-template>\n </mona-dropdown-list>\n }\n </li>\n }\n </ol>\n }\n @if (infoVisible()) {\n @if (pagerInfoTemplateRef) {\n <ng-container\n [ngTemplateOutlet]=\"pagerInfoTemplateRef\"\n [ngTemplateOutletContext]=\"pagerInfoTemplateContext()\"></ng-container>\n } @else {\n <span [class]=\"infoClasses()\">{{ pagerInfo() }}</span>\n }\n }\n}\n@if (type() === \"input\") {\n <div [class]=\"inputClasses()\">\n @if (pageListVisible()) {\n <ol [class]=\"listClasses()\">\n @if (firstLast()) {\n <ng-container [ngTemplateOutlet]=\"firstPageButton\"></ng-container>\n }\n @if (previousNext()) {\n <ng-container [ngTemplateOutlet]=\"previousPageButton\"></ng-container>\n }\n <li class=\"flex items-center gap-2 mx-2\">\n <span>Page</span>\n <mona-numeric-text-box\n monaPagerFocusable\n [spinners]=\"false\"\n [minValue]=\"1\"\n [maxValue]=\"pageCount()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [ngModel]=\"inputValue()\"\n (ngModelChange)=\"inputValue.set($event)\"\n (inputBlur)=\"onPageInputBlur()\"></mona-numeric-text-box>\n <span>of</span>\n <span>{{ pageCount() }}</span>\n </li>\n @if (previousNext()) {\n <ng-container [ngTemplateOutlet]=\"nextPageButton\"></ng-container>\n }\n @if (firstLast()) {\n <ng-container [ngTemplateOutlet]=\"lastPageButton\"></ng-container>\n }\n </ol>\n }\n </div>\n @if (infoVisible()) {\n @if (pagerInfoTemplateRef) {\n <ng-container\n [ngTemplateOutlet]=\"pagerInfoTemplateRef\"\n [ngTemplateOutletContext]=\"pagerInfoTemplateContext()\"></ng-container>\n } @else {\n <span [class]=\"infoClasses()\">{{ pagerInfo() }}</span>\n }\n }\n}\n@if (!pageListVisible()) {\n <ol [class]=\"listClasses()\">\n @if (firstLast()) {\n <ng-container [ngTemplateOutlet]=\"firstPageButton\"></ng-container>\n }\n @if (previousNext()) {\n <ng-container [ngTemplateOutlet]=\"previousPageButton\"></ng-container>\n }\n @if (pageCount() !== 0) {\n <li>\n <mona-dropdown-list\n monaPagerFocusable\n [data]=\"pageList()\"\n [ngModel]=\"page()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n monaDropDownVirtualScroll\n (ngModelChange)=\"onPageClick($event)\"\n style=\"width: 75px\"></mona-dropdown-list>\n </li>\n }\n @if (previousNext()) {\n <ng-container [ngTemplateOutlet]=\"nextPageButton\"></ng-container>\n }\n @if (firstLast()) {\n <ng-container [ngTemplateOutlet]=\"lastPageButton\"></ng-container>\n }\n </ol>\n}\n\n<ng-template #firstPageButton>\n <li>\n @let firstPageTemplate = firstPageNavigationTemplate();\n @if (firstPageTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"firstPageTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{\n totalPages: pageCount(),\n pageSize: pagerPageSize(),\n disabled: page() === 1\n }\">\n </ng-container>\n } @else {\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [attr.aria-label]=\"firstPageLabel\"\n (click)=\"onPageClick(1)\"\n [disabled]=\"page() === 1\">\n <svg lucideChevronsLeft [size]=\"iconSize()\"></svg>\n </button>\n }\n </li>\n</ng-template>\n\n<ng-template #previousPageButton>\n <li>\n @let previousPageTemplate = previousPageNavigationTemplate();\n @if (previousPageTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"previousPageTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{\n totalPages: pageCount(),\n pageSize: pagerPageSize(),\n disabled: page() <= 1\n }\">\n </ng-container>\n } @else {\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [disabled]=\"page() <= 1\"\n [attr.aria-label]=\"previousPageLabel\"\n (click)=\"onPreviousPageClick()\">\n <svg lucideChevronLeft [size]=\"iconSize()\"></svg>\n </button>\n }\n </li>\n</ng-template>\n\n<ng-template #nextPageButton>\n <li>\n @let nextPageTemplate = nextPageNavigationTemplate();\n @if (nextPageTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"nextPageTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{\n totalPages: pageCount(),\n pageSize: pagerPageSize(),\n disabled: page() < 1 || page() === pageCount()\n }\">\n </ng-container>\n } @else {\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [disabled]=\"page() < 1 || page() === pageCount()\"\n [attr.aria-label]=\"nextPageLabel\"\n (click)=\"onNextPageClick()\">\n <svg lucideChevronRight [size]=\"iconSize()\"></svg>\n </button>\n }\n </li>\n</ng-template>\n\n<ng-template #lastPageButton>\n <li>\n @let lastPageTemplate = lastPageNavigationTemplate();\n @if (lastPageTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"lastPageTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{\n totalPages: pageCount(),\n pageSize: pagerPageSize(),\n disabled: page() === pageCount()\n }\">\n </ng-container>\n } @else {\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [attr.aria-label]=\"lastPageLabel\"\n (click)=\"onPageClick(pageCount())\"\n [disabled]=\"page() === pageCount()\">\n <svg lucideChevronsRight [size]=\"iconSize()\"></svg>\n </button>\n }\n </li>\n</ng-template>\n", dependencies: [{ kind: "directive", type: ButtonDirective, selector: "button[monaButton]", inputs: ["aria-haspopup", "disabled", "iconOnly", "loading", "look", "rounded", "selected", "size", "tabindex", "type", "toggleable", "class"], outputs: ["disabledChange", "loadingChange", "lookChange", "selectedChange"] }, { kind: "component", type: NumericTextBoxComponent, selector: "mona-numeric-text-box", inputs: ["aria-label", "decimals", "disabled", "formatter", "maxValue", "minValue", "nullable", "readonly", "required", "invalid", "rounded", "size", "spinners", "step", "tabindex", "touched", "class", "value"], outputs: ["inputBlur", "inputFocus", "inputFocusOut", "touch", "valueChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: DropdownListComponent, selector: "mona-dropdown-list", inputs: ["aria-label", "aria-labelledby", "data", "disabled", "itemDisabled", "invalid", "loading", "placeholder", "popupClass", "popupHeight", "popupWidth", "readonly", "required", "rounded", "showClearButton", "size", "textField", "touched", "class", "valueField", "value"], outputs: ["close", "closed", "disabledChange", "open", "opened", "touch", "valueChange"] }, { kind: "directive", type: PagerFocusableDirective, selector: "[monaPagerFocusable]" }, { kind: "directive", type: DropdownVirtualScrollDirective, selector: " mona-auto-complete[monaDropDownVirtualScroll], mona-dropdown-list[monaDropDownVirtualScroll], mona-combo-box[monaDropDownVirtualScroll], mona-multi-select[monaDropDownVirtualScroll] ", inputs: ["monaDropDownVirtualScroll"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: DropdownListValueTemplateDirective, selector: "ng-template[monaDropDownListValueTemplate]" }, { kind: "component", type: LucideEllipsis, selector: "svg[lucideEllipsis], svg[lucideMoreHorizontal]" }, { kind: "component", type: LucideChevronsLeft, selector: "svg[lucideChevronsLeft]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "component", type: LucideChevronsRight, selector: "svg[lucideChevronsRight]" }, { kind: "pipe", type: SlicePipe, name: "monaSlice" }] }); }
703
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: PagerComponent, isStandalone: true, selector: "mona-pager", inputs: { firstLast: { classPropertyName: "firstLast", publicName: "firstLast", isSignal: true, isRequired: false, transformFunction: null }, navigable: { classPropertyName: "navigable", publicName: "navigable", isSignal: true, isRequired: false, transformFunction: null }, pageInput: { classPropertyName: "pageInput", publicName: "pageInput", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null }, pageSizeValues: { classPropertyName: "pageSizeValues", publicName: "pageSizeValues", isSignal: true, isRequired: false, transformFunction: null }, previousNext: { classPropertyName: "previousNext", publicName: "previousNext", isSignal: true, isRequired: false, transformFunction: null }, responsive: { classPropertyName: "responsive", publicName: "responsive", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, showInfo: { classPropertyName: "showInfo", publicName: "showInfo", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, skip: { classPropertyName: "skip", publicName: "skip", isSignal: true, isRequired: false, transformFunction: null }, total: { classPropertyName: "total", publicName: "total", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, userClasses: { classPropertyName: "userClasses", publicName: "class", isSignal: true, isRequired: false, transformFunction: null }, visiblePages: { classPropertyName: "visiblePages", publicName: "visiblePages", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { pageChange: "pageChange", pageSizeChange: "pageSizeChange" }, host: { listeners: { "keydown": "onKeydown($event)" }, properties: { "attr.tabindex": "navigable() ? 0 : null", "class": "baseClasses()" } }, queries: [{ propertyName: "navigationButtonsTemplateList", predicate: PagerNavigationButtonsTemplateDirective, isSignal: true }, { propertyName: "numericButtonsTemplate", first: true, predicate: PagerNumericButtonsTemplateDirective, descendants: true, isSignal: true }, { propertyName: "pageSizeTemplate", first: true, predicate: PagerPageSizeTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "pagerInfoTemplate", first: true, predicate: PagerInfoTemplateDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "pageSizeDropdownList", first: true, predicate: ["pageSizeDropdownList"], descendants: true, isSignal: true }], ngImport: i0, template: "@let numericButtonsTemplateRef = numericButtonsTemplate()?.templateRef;\n@let pageSizeTemplateRef = pageSizeTemplate();\n@let pagerInfoTemplateRef = pagerInfoTemplate()?.templateRef;\n\n@if (type() === \"numeric\") {\n @if (pageListVisible()) {\n <ol [class]=\"listClasses()\">\n @if (firstLast()) {\n <ng-container [ngTemplateOutlet]=\"firstPageButton\"></ng-container>\n }\n @if (previousNext()) {\n <ng-container [ngTemplateOutlet]=\"previousPageButton\"></ng-container>\n }\n\n @if (numericButtonsTemplateRef) {\n <ng-container\n [ngTemplateOutlet]=\"numericButtonsTemplateRef\"\n [ngTemplateOutletContext]=\"{ totalPages: pageCount() }\"></ng-container>\n } @else {\n @if (pages().length !== 0) {\n <li [class]=\"pageItemClasses(page() === 1)\">\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [selected]=\"page() === 1\"\n [attr.aria-label]=\"'Page 1'\"\n [attr.aria-current]=\"page() === 1 ? 'page' : null\"\n (click)=\"onPageClick(1)\">\n 1\n </button>\n </li>\n }\n @if (previousJumperVisible()) {\n <li>\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [attr.aria-label]=\"jumpPreviousLabel()\"\n (click)=\"onJumpPreviousClick()\">\n <svg lucideEllipsis [size]=\"iconSize()\"></svg>\n </button>\n </li>\n }\n\n @for (pageItem of pages() | monaSlice: 1 : pages().length - 1; track $index) {\n <li [attr.data-page]=\"pageItem.page\" [class]=\"pageItemClasses(page() === pageItem.page)\">\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [selected]=\"page() === pageItem.page\"\n [attr.aria-label]=\"'Page ' + pageItem.text\"\n [attr.aria-current]=\"page() === pageItem.page ? 'page' : null\"\n (click)=\"onPageClick(pageItem.page)\">\n {{ pageItem.text }}\n </button>\n </li>\n }\n\n @if (nextJumperVisible()) {\n <li>\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [attr.aria-label]=\"jumpNextLabel()\"\n (click)=\"onJumpNextClick()\">\n <svg lucideEllipsis [size]=\"iconSize()\"></svg>\n </button>\n </li>\n }\n\n @if (pages().length > 1) {\n <li [class]=\"pageItemClasses(page() === pageCount())\">\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [selected]=\"page() === pageCount()\"\n [attr.aria-label]=\"'Page ' + pageCount()\"\n [attr.aria-current]=\"page() === pageCount() ? 'page' : null\"\n (click)=\"onPageClick(pageCount())\">\n {{ pageCount() }}\n </button>\n </li>\n }\n }\n\n @if (previousNext()) {\n <ng-container [ngTemplateOutlet]=\"nextPageButton\"></ng-container>\n }\n\n @if (firstLast()) {\n <ng-container [ngTemplateOutlet]=\"lastPageButton\"></ng-container>\n }\n\n @if (pageInputVisible() && pageInput()) {\n <li>\n <mona-numeric-text-box\n monaPagerFocusable\n [spinners]=\"false\"\n [minValue]=\"1\"\n [maxValue]=\"pageCount()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [ngModel]=\"inputValue()\"\n (ngModelChange)=\"inputValue.set($event)\"\n (inputBlur)=\"onPageInputBlur()\"></mona-numeric-text-box>\n </li>\n }\n\n @if (pageInputVisible() && pageSizeDropdownData().length > 0) {\n <li>\n @if (pageSizeTemplateRef) {\n <ng-container\n [ngTemplateOutlet]=\"pageSizeTemplateRef\"\n [ngTemplateOutletContext]=\"{ $implicit: pageSizeDropdownData() }\">\n </ng-container>\n } @else {\n <mona-dropdown-list\n monaPagerFocusable\n [data]=\"pageSizeDropdownData()\"\n [ngModel]=\"pageSize()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n (ngModelChange)=\"onPageSizeValueChange($event)\"\n #pageSizeDropdownList>\n <ng-template monaDropDownListValueTemplate let-item>\n <span>{{ item }} / page</span>\n </ng-template>\n </mona-dropdown-list>\n }\n </li>\n }\n </ol>\n }\n @if (infoVisible()) {\n @if (pagerInfoTemplateRef) {\n <ng-container\n [ngTemplateOutlet]=\"pagerInfoTemplateRef\"\n [ngTemplateOutletContext]=\"pagerInfoTemplateContext()\"></ng-container>\n } @else {\n <span [class]=\"infoClasses()\">{{ pagerInfo() }}</span>\n }\n }\n}\n@if (type() === \"input\") {\n <div [class]=\"inputClasses()\">\n @if (pageListVisible()) {\n <ol [class]=\"listClasses()\">\n @if (firstLast()) {\n <ng-container [ngTemplateOutlet]=\"firstPageButton\"></ng-container>\n }\n @if (previousNext()) {\n <ng-container [ngTemplateOutlet]=\"previousPageButton\"></ng-container>\n }\n <li class=\"flex items-center gap-2 mx-2\">\n <span>Page</span>\n <mona-numeric-text-box\n monaPagerFocusable\n [spinners]=\"false\"\n [minValue]=\"1\"\n [maxValue]=\"pageCount()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [ngModel]=\"inputValue()\"\n (ngModelChange)=\"inputValue.set($event)\"\n (inputBlur)=\"onPageInputBlur()\"></mona-numeric-text-box>\n <span>of</span>\n <span>{{ pageCount() }}</span>\n </li>\n @if (previousNext()) {\n <ng-container [ngTemplateOutlet]=\"nextPageButton\"></ng-container>\n }\n @if (firstLast()) {\n <ng-container [ngTemplateOutlet]=\"lastPageButton\"></ng-container>\n }\n </ol>\n }\n </div>\n @if (infoVisible()) {\n @if (pagerInfoTemplateRef) {\n <ng-container\n [ngTemplateOutlet]=\"pagerInfoTemplateRef\"\n [ngTemplateOutletContext]=\"pagerInfoTemplateContext()\"></ng-container>\n } @else {\n <span [class]=\"infoClasses()\">{{ pagerInfo() }}</span>\n }\n }\n}\n@if (!pageListVisible()) {\n <ol [class]=\"listClasses()\">\n @if (firstLast()) {\n <ng-container [ngTemplateOutlet]=\"firstPageButton\"></ng-container>\n }\n @if (previousNext()) {\n <ng-container [ngTemplateOutlet]=\"previousPageButton\"></ng-container>\n }\n @if (pageCount() !== 0) {\n <li>\n <mona-dropdown-list\n monaPagerFocusable\n [data]=\"pageList()\"\n [ngModel]=\"page()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n monaDropDownVirtualScroll\n (ngModelChange)=\"onPageClick($event)\"\n style=\"width: 75px\"></mona-dropdown-list>\n </li>\n }\n @if (previousNext()) {\n <ng-container [ngTemplateOutlet]=\"nextPageButton\"></ng-container>\n }\n @if (firstLast()) {\n <ng-container [ngTemplateOutlet]=\"lastPageButton\"></ng-container>\n }\n </ol>\n}\n\n<ng-template #firstPageButton>\n <li>\n @let firstPageTemplate = firstPageNavigationTemplate();\n @if (firstPageTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"firstPageTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{\n totalPages: pageCount(),\n pageSize: pagerPageSize(),\n disabled: page() === 1\n }\">\n </ng-container>\n } @else {\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [attr.aria-label]=\"firstPageLabel\"\n (click)=\"onPageClick(1)\"\n [disabled]=\"page() === 1\">\n <svg lucideChevronsLeft [size]=\"iconSize()\"></svg>\n </button>\n }\n </li>\n</ng-template>\n\n<ng-template #previousPageButton>\n <li>\n @let previousPageTemplate = previousPageNavigationTemplate();\n @if (previousPageTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"previousPageTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{\n totalPages: pageCount(),\n pageSize: pagerPageSize(),\n disabled: page() <= 1\n }\">\n </ng-container>\n } @else {\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [disabled]=\"page() <= 1\"\n [attr.aria-label]=\"previousPageLabel\"\n (click)=\"onPreviousPageClick()\">\n <svg lucideChevronLeft [size]=\"iconSize()\"></svg>\n </button>\n }\n </li>\n</ng-template>\n\n<ng-template #nextPageButton>\n <li>\n @let nextPageTemplate = nextPageNavigationTemplate();\n @if (nextPageTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"nextPageTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{\n totalPages: pageCount(),\n pageSize: pagerPageSize(),\n disabled: page() < 1 || page() === pageCount()\n }\">\n </ng-container>\n } @else {\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [disabled]=\"page() < 1 || page() === pageCount()\"\n [attr.aria-label]=\"nextPageLabel\"\n (click)=\"onNextPageClick()\">\n <svg lucideChevronRight [size]=\"iconSize()\"></svg>\n </button>\n }\n </li>\n</ng-template>\n\n<ng-template #lastPageButton>\n <li>\n @let lastPageTemplate = lastPageNavigationTemplate();\n @if (lastPageTemplate) {\n <ng-container\n [ngTemplateOutlet]=\"lastPageTemplate.templateRef\"\n [ngTemplateOutletContext]=\"{\n totalPages: pageCount(),\n pageSize: pagerPageSize(),\n disabled: page() === pageCount()\n }\">\n </ng-container>\n } @else {\n <button\n monaPagerFocusable\n monaButton\n look=\"ghost\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [attr.aria-label]=\"lastPageLabel\"\n (click)=\"onPageClick(pageCount())\"\n [disabled]=\"page() === pageCount()\">\n <svg lucideChevronsRight [size]=\"iconSize()\"></svg>\n </button>\n }\n </li>\n</ng-template>\n", dependencies: [{ kind: "directive", type: ButtonDirective, selector: "button[monaButton]", inputs: ["aria-haspopup", "disabled", "iconOnly", "loading", "look", "rounded", "selected", "size", "tabindex", "type", "toggleable", "class"], outputs: ["disabledChange", "loadingChange", "lookChange", "selectedChange"] }, { kind: "component", type: NumericTextBoxComponent, selector: "mona-numeric-text-box", inputs: ["aria-label", "decimals", "disabled", "formatter", "maxValue", "minValue", "nullable", "readonly", "required", "invalid", "rounded", "size", "spinners", "step", "tabindex", "touched", "class", "value"], outputs: ["inputBlur", "inputFocus", "inputFocusOut", "touch", "valueChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: DropdownListComponent, selector: "mona-dropdown-list", inputs: ["aria-label", "aria-labelledby", "data", "disabled", "itemDisabled", "invalid", "loading", "placeholder", "popupClass", "popupHeight", "popupWidth", "readonly", "required", "rounded", "showClearButton", "size", "textField", "touched", "class", "valueField", "valuePrimitive", "value"], outputs: ["close", "closed", "disabledChange", "open", "opened", "touch", "valueChange"] }, { kind: "directive", type: PagerFocusableDirective, selector: "[monaPagerFocusable]" }, { kind: "directive", type: DropdownVirtualScrollDirective, selector: " mona-auto-complete[monaDropDownVirtualScroll], mona-dropdown-list[monaDropDownVirtualScroll], mona-combo-box[monaDropDownVirtualScroll], mona-multi-select[monaDropDownVirtualScroll] ", inputs: ["monaDropDownVirtualScroll"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: DropdownListValueTemplateDirective, selector: "ng-template[monaDropDownListValueTemplate]" }, { kind: "component", type: LucideEllipsis, selector: "svg[lucideEllipsis], svg[lucideMoreHorizontal]" }, { kind: "component", type: LucideChevronsLeft, selector: "svg[lucideChevronsLeft]" }, { kind: "component", type: LucideChevronLeft, selector: "svg[lucideChevronLeft]" }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }, { kind: "component", type: LucideChevronsRight, selector: "svg[lucideChevronsRight]" }, { kind: "pipe", type: SlicePipe, name: "monaSlice" }] }); }
704
704
  }
705
705
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: PagerComponent, decorators: [{
706
706
  type: Component,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nanahoshi/mona-ui",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "A very light Angular UI framework",
5
5
  "author": "Nanahoshi",
6
6
  "repository": {
@@ -169,7 +169,7 @@ declare class AutoCompleteComponent<TData = unknown> implements FormValueControl
169
169
  * If null, the item itself is used as the display text.
170
170
  * @default null
171
171
  */
172
- readonly textField: _angular_core.InputSignal<DropdownFieldSelectorType<TData>>;
172
+ readonly textField: _angular_core.InputSignal<DropdownFieldSelectorType<TData, string>>;
173
173
  /**
174
174
  * @description Emitted when the autocomplete is interacted with on blur, selection, clear, or committed input.
175
175
  * The `FormField` directive listens to this to mark the field as touched.
@@ -191,7 +191,7 @@ declare class AutoCompleteComponent<TData = unknown> implements FormValueControl
191
191
  * If null, the item itself is used as the value.
192
192
  * @default null
193
193
  */
194
- readonly valueField: _angular_core.InputSignal<DropdownFieldSelectorType<TData>>;
194
+ readonly valueField: _angular_core.InputSignal<DropdownFieldSelectorType<TData, unknown>>;
195
195
  /**
196
196
  * @description Two-way bindable current autocomplete value. Implements `FormValueControl<string | null>`,
197
197
  * enabling signal forms `[formField]` binding.
@@ -31,7 +31,7 @@ type ComboBoxAffixContainerVariantInput = VariantInputs<ComboBoxAffixContainerVa
31
31
  type ComboBoxVariantProps = ComboBoxBaseVariantProps & ComboBoxTextInputVariantProps & ComboBoxAffixContainerVariantProps;
32
32
  type ComboBoxVariantInput = Omit<ComboBoxBaseVariantInput, "focused" | "invalid"> & ComboBoxTextInputVariantInput & ComboBoxAffixContainerVariantInput;
33
33
 
34
- declare class ComboBoxComponent<TData = unknown> implements FormValueControl<TData | null>, ComboBoxVariantInput, DropdownDataInput<TData>, DropdownPopupInput, DropdownPopupVariantInput {
34
+ declare class ComboBoxComponent<TData = unknown, TValue = TData> implements FormValueControl<TValue | null>, ComboBoxVariantInput, DropdownDataInput<TData>, DropdownPopupInput, DropdownPopupVariantInput {
35
35
  #private;
36
36
  protected readonly activeDescendant: _angular_core.Signal<string | null>;
37
37
  protected readonly affixClass: _angular_core.Signal<string>;
@@ -168,7 +168,7 @@ declare class ComboBoxComponent<TData = unknown> implements FormValueControl<TDa
168
168
  * If not set, the item itself is used as the text representation.
169
169
  * @default undefined
170
170
  */
171
- readonly textField: _angular_core.InputSignal<DropdownFieldSelectorType<TData>>;
171
+ readonly textField: _angular_core.InputSignal<DropdownFieldSelectorType<TData, string>>;
172
172
  /**
173
173
  * @description Emitted when the combo box is interacted with on blur, selection, clear, or committed input.
174
174
  * The `FormField` directive listens to this to mark the field as touched.
@@ -192,17 +192,31 @@ declare class ComboBoxComponent<TData = unknown> implements FormValueControl<TDa
192
192
  readonly valueAdd: _angular_core.OutputEmitterRef<string>;
193
193
  /**
194
194
  * @description Property name or accessor used to derive the value from a data item.
195
- * If not set, the item itself is used as the value representation.
195
+ * It is used for stable item identity, matching externally supplied values, and primitive
196
+ * value projection when {@link valuePrimitive} is enabled.
197
+ * When omitted, the item itself is used as the value representation.
198
+ * Should resolve to a stable, unique scalar.
196
199
  * @default undefined
197
200
  */
198
- readonly valueField: _angular_core.InputSignal<DropdownFieldSelectorType<TData>>;
201
+ readonly valueField: _angular_core.InputSignal<DropdownFieldSelectorType<TData, unknown>>;
199
202
  /**
200
- * @description Two-way bindable current selected value. Implements `FormValueControl<TData | null>`,
201
- * enabling signal forms `[formField]` binding. When `valueField` is set, primitive field values can be
202
- * written into this model to restore a matching selected item.
203
+ * @description Determines whether the bound value contains complete data items
204
+ * or values extracted through {@link valueField}.
205
+ *
206
+ * When `false`, selecting an item writes the complete data item.
207
+ * When `true`, selecting an item writes the value resolved through `valueField`.
208
+ *
209
+ * @default false
210
+ */
211
+ readonly valuePrimitive: _angular_core.InputSignal<boolean>;
212
+ /**
213
+ * @description Two-way bindable current selected value. Implements `FormValueControl<TValue | null>`,
214
+ * enabling signal forms `[formField]` binding.
215
+ * Object mode returns the selected data item; primitive mode (see {@link valuePrimitive}) returns the value
216
+ * resolved through {@link valueField}. `null` represents no selection.
203
217
  * @default null
204
218
  */
205
- readonly value: _angular_core.ModelSignal<TData | null>;
219
+ readonly value: _angular_core.ModelSignal<TValue | null>;
206
220
  constructor();
207
221
  protected onInputBlur(): void;
208
222
  protected onItemSelect(event: SelectionChangeEvent<TData>): void;
@@ -223,8 +237,10 @@ declare class ComboBoxComponent<TData = unknown> implements FormValueControl<TDa
223
237
  private setSpaceKeySubscription;
224
238
  private setSubscriptions;
225
239
  private updateValue;
226
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<ComboBoxComponent<any>, never>;
227
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<ComboBoxComponent<any>, "mona-combo-box", never, { "allowCustomValue": { "alias": "allowCustomValue"; "required": false; "isSignal": true; }; "ariaDescribedBy": { "alias": "aria-describedby"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "itemDisabled": { "alias": "itemDisabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "popupClass": { "alias": "popupClass"; "required": false; "isSignal": true; }; "popupHeight": { "alias": "popupHeight"; "required": false; "isSignal": true; }; "popupWidth": { "alias": "popupWidth"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "showClearButton": { "alias": "showClearButton"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "textField": { "alias": "textField"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "close": "close"; "closed": "closed"; "disabled": "disabledChange"; "open": "open"; "opened": "opened"; "touch": "touch"; "valueAdd": "valueAdd"; "value": "valueChange"; }, ["footerTemplate", "groupHeaderTemplate", "headerTemplate", "itemTemplate", "noDataTemplate", "prefixTemplate"], never, true, [{ directive: typeof i1.DropdownDataHandlerDirective; inputs: {}; outputs: {}; }, { directive: typeof i1.DropdownListPopupHandlerDirective; inputs: {}; outputs: {}; }]>;
240
+ private getControlValue;
241
+ private synchronizeSelection;
242
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<ComboBoxComponent<any, any>, never>;
243
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<ComboBoxComponent<any, any>, "mona-combo-box", never, { "allowCustomValue": { "alias": "allowCustomValue"; "required": false; "isSignal": true; }; "ariaDescribedBy": { "alias": "aria-describedby"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "itemDisabled": { "alias": "itemDisabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "popupClass": { "alias": "popupClass"; "required": false; "isSignal": true; }; "popupHeight": { "alias": "popupHeight"; "required": false; "isSignal": true; }; "popupWidth": { "alias": "popupWidth"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "showClearButton": { "alias": "showClearButton"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "textField": { "alias": "textField"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "valuePrimitive": { "alias": "valuePrimitive"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "close": "close"; "closed": "closed"; "disabled": "disabledChange"; "open": "open"; "opened": "opened"; "touch": "touch"; "valueAdd": "valueAdd"; "value": "valueChange"; }, ["footerTemplate", "groupHeaderTemplate", "headerTemplate", "itemTemplate", "noDataTemplate", "prefixTemplate"], never, true, [{ directive: typeof i1.DropdownDataHandlerDirective; inputs: {}; outputs: {}; }, { directive: typeof i1.DropdownListPopupHandlerDirective; inputs: {}; outputs: {}; }]>;
228
244
  }
229
245
 
230
246
  export { ComboBoxComponent };
@@ -32,7 +32,7 @@ type DropdownListValueContainerVariantInput = VariantInputs<DropdownListValueCon
32
32
  type DropDownListVariantProps = DropdownListInputVariantProps & DropdownListAffixContainerVariantProps & DropdownListValueContainerVariantProps;
33
33
  type DropDownListVariantInput = Omit<DropdownListInputVariantInput, "expanded" | "hasPrefix" | "invalid"> & DropdownListAffixContainerVariantInput & Omit<DropdownListValueContainerVariantInput, "hasTemplate">;
34
34
 
35
- declare class DropdownListComponent<TData = unknown> implements FormValueControl<TData | null>, DropDownListVariantInput, DropdownDataInput<TData>, DropdownPopupInput {
35
+ declare class DropdownListComponent<TData = unknown, TValue = TData> implements FormValueControl<TValue | null>, DropDownListVariantInput, DropdownDataInput<TData>, DropdownPopupInput {
36
36
  #private;
37
37
  protected readonly activeDescendant: _angular_core.Signal<string | null>;
38
38
  protected readonly affixClass: _angular_core.Signal<string>;
@@ -158,7 +158,7 @@ declare class DropdownListComponent<TData = unknown> implements FormValueControl
158
158
  * If omitted, the item itself is used as the display text.
159
159
  * @default undefined
160
160
  */
161
- readonly textField: _angular_core.InputSignal<DropdownFieldSelectorType<TData>>;
161
+ readonly textField: _angular_core.InputSignal<DropdownFieldSelectorType<TData, string>>;
162
162
  /**
163
163
  * @description Emitted when the control is interacted with via blur, selection, or clear.
164
164
  * The `FormField` directive listens to this to mark the field as touched.
@@ -176,24 +176,39 @@ declare class DropdownListComponent<TData = unknown> implements FormValueControl
176
176
  readonly userClass: _angular_core.InputSignal<string>;
177
177
  /**
178
178
  * @description Property name or accessor used to derive the value from a data item.
179
- * If omitted, the item itself is used as the value.
179
+ * It is used for stable item identity, matching externally supplied values, and primitive
180
+ * value projection when {@link valuePrimitive} is enabled.
181
+ * When omitted, the item itself is used as the value.
182
+ * Should resolve to a stable, unique scalar.
180
183
  * @default undefined
181
184
  */
182
- readonly valueField: _angular_core.InputSignal<DropdownFieldSelectorType<TData>>;
185
+ readonly valueField: _angular_core.InputSignal<DropdownFieldSelectorType<TData, unknown>>;
186
+ /**
187
+ * @description Determines whether the bound value contains complete data items
188
+ * or values extracted through {@link valueField}.
189
+ *
190
+ * When `false`, selecting an item writes the complete data item.
191
+ * When `true`, selecting an item writes the value resolved through `valueField`.
192
+ *
193
+ * @default false
194
+ */
195
+ readonly valuePrimitive: _angular_core.InputSignal<boolean>;
183
196
  /**
184
197
  * @description Currently selected value, two-way bindable and compatible with Signal Forms via `[formField]`.
185
- * When `valueField` is set, this may hold the primitive field value instead of the full data item.
198
+ * Object mode returns the selected data item; primitive mode (see {@link valuePrimitive}) returns the value
199
+ * resolved through {@link valueField}. `null` represents no selection.
186
200
  * @default null
187
201
  */
188
- readonly value: _angular_core.ModelSignal<TData | null>;
202
+ readonly value: _angular_core.ModelSignal<TValue | null>;
189
203
  constructor();
190
- setValue(value: TData): void;
204
+ setValue(value: TValue): void;
191
205
  protected onBlur(): void;
192
206
  protected onItemSelect(event: SelectionChangeEvent<TData>): void;
193
207
  protected onValueClear(event: MouseEvent | KeyboardEvent): void;
194
208
  private closePopup;
195
209
  private cycleThroughMatchedItems;
196
210
  focus(): void;
211
+ private getControlValue;
197
212
  private handleEnterKey;
198
213
  private handleHomeEndKeys;
199
214
  private initialize;
@@ -204,9 +219,10 @@ declare class DropdownListComponent<TData = unknown> implements FormValueControl
204
219
  private setPopupCloseSubscriptions;
205
220
  private setSubscriptions;
206
221
  private setTypeaheadSubscription;
222
+ private synchronizeSelection;
207
223
  private updateValue;
208
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<DropdownListComponent<any>, never>;
209
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<DropdownListComponent<any>, "mona-dropdown-list", never, { "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "itemDisabled": { "alias": "itemDisabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "popupClass": { "alias": "popupClass"; "required": false; "isSignal": true; }; "popupHeight": { "alias": "popupHeight"; "required": false; "isSignal": true; }; "popupWidth": { "alias": "popupWidth"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "showClearButton": { "alias": "showClearButton"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "textField": { "alias": "textField"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "close": "close"; "closed": "closed"; "disabled": "disabledChange"; "open": "open"; "opened": "opened"; "touch": "touch"; "value": "valueChange"; }, ["footerTemplate", "groupHeaderTemplate", "headerTemplate", "itemTemplate", "noDataTemplate", "prefixTemplate", "valueTemplate"], never, true, [{ directive: typeof i1.DropdownDataHandlerDirective; inputs: {}; outputs: {}; }, { directive: typeof i1.DropdownListPopupHandlerDirective; inputs: {}; outputs: {}; }]>;
224
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DropdownListComponent<any, any>, never>;
225
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DropdownListComponent<any, any>, "mona-dropdown-list", never, { "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "itemDisabled": { "alias": "itemDisabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "popupClass": { "alias": "popupClass"; "required": false; "isSignal": true; }; "popupHeight": { "alias": "popupHeight"; "required": false; "isSignal": true; }; "popupWidth": { "alias": "popupWidth"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "showClearButton": { "alias": "showClearButton"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "textField": { "alias": "textField"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "valuePrimitive": { "alias": "valuePrimitive"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "close": "close"; "closed": "closed"; "disabled": "disabledChange"; "open": "open"; "opened": "opened"; "touch": "touch"; "value": "valueChange"; }, ["footerTemplate", "groupHeaderTemplate", "headerTemplate", "itemTemplate", "noDataTemplate", "prefixTemplate", "valueTemplate"], never, true, [{ directive: typeof i1.DropdownDataHandlerDirective; inputs: {}; outputs: {}; }, { directive: typeof i1.DropdownListPopupHandlerDirective; inputs: {}; outputs: {}; }]>;
210
226
  }
211
227
 
212
228
  declare class DropdownListValueTemplateDirective {
@@ -10,14 +10,14 @@ import * as class_variance_authority_types from 'class-variance-authority/types'
10
10
  import { VariantInputs } from '@nanahoshi/mona-ui/internal';
11
11
  import { VariantProps } from 'class-variance-authority';
12
12
 
13
- type DropdownFieldSelectorType<TData> = string | Selector<TData, string> | null | undefined;
13
+ type DropdownFieldSelectorType<TData, TResult = unknown> = string | Selector<TData, TResult> | null | undefined;
14
14
  type DropdownFieldPredicateType<TData> = string | Predicate<TData> | null | undefined;
15
15
 
16
16
  interface DropdownDataInput<TData> {
17
17
  readonly data: InputSignal<Iterable<TData>>;
18
18
  readonly itemDisabled: InputSignal<DropdownFieldPredicateType<TData>>;
19
- readonly textField: InputSignal<DropdownFieldSelectorType<TData>>;
20
- readonly valueField: InputSignal<DropdownFieldSelectorType<TData>>;
19
+ readonly textField: InputSignal<DropdownFieldSelectorType<TData, string>>;
20
+ readonly valueField: InputSignal<DropdownFieldSelectorType<TData, unknown>>;
21
21
  }
22
22
  declare const DropdownDataInputToken: InjectionToken<DropdownDataInput<unknown>>;
23
23
 
@@ -122,7 +122,7 @@ declare class ListService<TData> {
122
122
  readonly selectedListItems: _angular_core.Signal<ImmutableSet<ListItem<TData>>>;
123
123
  readonly selectionChange$: Subject<ListItem<TData>>;
124
124
  readonly textField: _angular_core.WritableSignal<string | Selector<TData, string>>;
125
- readonly valueField: _angular_core.WritableSignal<string | Selector<TData, any>>;
125
+ readonly valueField: _angular_core.WritableSignal<string | Selector<TData, unknown>>;
126
126
  readonly viewItems: _angular_core.Signal<ImmutableSet<ListItem<TData>>>;
127
127
  readonly virtualScrollOptions: _angular_core.WritableSignal<VirtualScrollOptions>;
128
128
  readonly itemPositions: _angular_core.Signal<Map<string, {
@@ -133,6 +133,16 @@ declare class ListService<TData> {
133
133
  position: number;
134
134
  total: number;
135
135
  } | null;
136
+ /**
137
+ * Resolves the selection value of a data item through `valueField`.
138
+ *
139
+ * When no `valueField` is configured, the data item itself is the value.
140
+ * When `valueField` is a string, the item property is read with a nullish fallback to the item.
141
+ * When `valueField` is a function, its result is used as-is.
142
+ *
143
+ * Falsy results such as `0`, `false`, and `""` are valid values and do not fall back to the item.
144
+ */
145
+ getDataItemValue(dataItem: TData): unknown;
136
146
  clearFilter(): void;
137
147
  clearHighlightedItem(): void;
138
148
  clearSelections(): void;
@@ -161,12 +171,11 @@ declare class ListService<TData> {
161
171
  setPageableOptions(settings: PagerSettings): void;
162
172
  setSelectableOptions(options: Partial<SelectableOptions>): void;
163
173
  setSelectedDataItems(dataItems: Iterable<TData>): void;
164
- setSelectedKeys(selectedKeys: Iterable<any>): void;
174
+ setSelectedKeys(selectedKeys: Iterable<unknown>): void;
165
175
  setTextField(textField: string | Selector<TData, string>): void;
166
- setValueField(valueField: string | Selector<TData, any>): void;
176
+ setValueField(valueField: string | Selector<TData, unknown>): void;
167
177
  setVirtualScrollOptions(options: VirtualScrollOptions): void;
168
178
  private filterItem;
169
- private getDataItemSelectionKey;
170
179
  private getOrderKey;
171
180
  private getPreviousItemForNavigation;
172
181
  private getSelectionKey;
@@ -36,7 +36,7 @@ type MultiSelectIndicatorContainerVariantInput = VariantInputs<MultiSelectIndica
36
36
  type MultiSelectVariantProps = MultiSelectBaseVariantProps & MultiSelectItemContainerVariantProps & MultiSelectAffixContainerVariantProps & MultiSelectIndicatorContainerVariantProps;
37
37
  type MultiSelectVariantInput = Omit<MultiSelectBaseVariantInput, "focused" | "invalid"> & MultiSelectItemContainerVariantInput & MultiSelectAffixContainerVariantInput & MultiSelectIndicatorContainerVariantInput;
38
38
 
39
- declare class MultiSelectComponent<TData = unknown> implements FormValueControl<Iterable<TData>>, MultiSelectVariantInput, DropdownDataInput<TData>, DropdownPopupInput, DropdownPopupVariantInput {
39
+ declare class MultiSelectComponent<TData = unknown, TValue = TData> implements FormValueControl<Iterable<TValue>>, MultiSelectVariantInput, DropdownDataInput<TData>, DropdownPopupInput, DropdownPopupVariantInput {
40
40
  #private;
41
41
  protected readonly activeDescendant: _angular_core.Signal<string | null>;
42
42
  protected readonly affixClass: _angular_core.Signal<string>;
@@ -168,7 +168,7 @@ declare class MultiSelectComponent<TData = unknown> implements FormValueControl<
168
168
  * If null, the item itself will be used as the text representation.
169
169
  * @default null
170
170
  */
171
- readonly textField: _angular_core.InputSignal<DropdownFieldSelectorType<TData>>;
171
+ readonly textField: _angular_core.InputSignal<DropdownFieldSelectorType<TData, string>>;
172
172
  /**
173
173
  * @description Emitted when the multi select is interacted with on blur, selection, remove, or clear.
174
174
  * The `FormField` directive listens to this to mark the field as touched.
@@ -187,18 +187,32 @@ declare class MultiSelectComponent<TData = unknown> implements FormValueControl<
187
187
  readonly userClass: _angular_core.InputSignal<string>;
188
188
  /**
189
189
  * @description Sets the value field of the multi select component.
190
- * It can be null, string, or a function that takes an item and returns a string.
190
+ * It is used for stable item identity, matching externally supplied values, and primitive
191
+ * value projection when {@link valuePrimitive} is enabled.
192
+ * It can be null, string, or a function that takes an item and returns a value.
191
193
  * If null, the item itself will be used as the value representation.
194
+ * Should resolve to a stable, unique scalar.
192
195
  * @default null
193
196
  */
194
- readonly valueField: _angular_core.InputSignal<DropdownFieldSelectorType<TData>>;
197
+ readonly valueField: _angular_core.InputSignal<DropdownFieldSelectorType<TData, unknown>>;
198
+ /**
199
+ * @description Determines whether the bound value contains complete data items
200
+ * or values extracted through {@link valueField}.
201
+ *
202
+ * When `false`, selecting an item writes the complete data item.
203
+ * When `true`, selecting an item writes the value resolved through `valueField`.
204
+ *
205
+ * @default false
206
+ */
207
+ readonly valuePrimitive: _angular_core.InputSignal<boolean>;
195
208
  /**
196
- * @description Two-way bindable current selected values. Implements `FormValueControl<Iterable<TData>>`,
197
- * enabling signal forms `[formField]` binding. When `valueField` is set, primitive field values can be
198
- * written into this model to restore matching selected items.
209
+ * @description Two-way bindable current selected values. Implements `FormValueControl<Iterable<TValue>>`,
210
+ * enabling signal forms `[formField]` binding.
211
+ * Object mode contains selected data items; primitive mode (see {@link valuePrimitive}) contains values
212
+ * resolved through {@link valueField}. An empty selection is represented by an empty iterable/array.
199
213
  * @default []
200
214
  */
201
- readonly value: _angular_core.ModelSignal<Iterable<TData>>;
215
+ readonly value: _angular_core.ModelSignal<Iterable<TValue>>;
202
216
  constructor();
203
217
  focus(): void;
204
218
  protected onBlur(): void;
@@ -206,6 +220,7 @@ declare class MultiSelectComponent<TData = unknown> implements FormValueControl<
206
220
  protected onSelectedItemRemove(event: Event, listItem: ListItem<TData>): void;
207
221
  protected onSelectedItemGroupRemove(event: Event): void;
208
222
  protected onValueClear(event: Event): void;
223
+ private getSelectedControlValues;
209
224
  private handleEnterKey;
210
225
  private handlePopupPositionUpdate;
211
226
  private initialize;
@@ -213,9 +228,10 @@ declare class MultiSelectComponent<TData = unknown> implements FormValueControl<
213
228
  private setEnterKeySubscription;
214
229
  private setEventListeners;
215
230
  private setSubscriptions;
231
+ private synchronizeSelection;
216
232
  private updateValue;
217
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<MultiSelectComponent<any>, never>;
218
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<MultiSelectComponent<any>, "mona-multi-select", never, { "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "autoClose": { "alias": "autoClose"; "required": false; "isSignal": true; }; "checkboxes": { "alias": "checkboxes"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "itemDisabled": { "alias": "itemDisabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "popupClass": { "alias": "popupClass"; "required": false; "isSignal": true; }; "popupHeight": { "alias": "popupHeight"; "required": false; "isSignal": true; }; "popupWidth": { "alias": "popupWidth"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "showClearButton": { "alias": "showClearButton"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "textField": { "alias": "textField"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "close": "close"; "closed": "closed"; "disabled": "disabledChange"; "open": "open"; "opened": "opened"; "touch": "touch"; "value": "valueChange"; }, ["footerTemplate", "groupHeaderTemplate", "headerTemplate", "itemTemplate", "noDataTemplate", "prefixTemplate", "tagTemplate"], never, true, [{ directive: typeof i1.DropdownDataHandlerDirective; inputs: {}; outputs: {}; }, { directive: typeof i1.DropdownListPopupHandlerDirective; inputs: {}; outputs: {}; }]>;
233
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<MultiSelectComponent<any, any>, never>;
234
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<MultiSelectComponent<any, any>, "mona-multi-select", never, { "ariaLabel": { "alias": "aria-label"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "aria-labelledby"; "required": false; "isSignal": true; }; "autoClose": { "alias": "autoClose"; "required": false; "isSignal": true; }; "checkboxes": { "alias": "checkboxes"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "itemDisabled": { "alias": "itemDisabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "popupClass": { "alias": "popupClass"; "required": false; "isSignal": true; }; "popupHeight": { "alias": "popupHeight"; "required": false; "isSignal": true; }; "popupWidth": { "alias": "popupWidth"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "showClearButton": { "alias": "showClearButton"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "textField": { "alias": "textField"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "userClass": { "alias": "class"; "required": false; "isSignal": true; }; "valueField": { "alias": "valueField"; "required": false; "isSignal": true; }; "valuePrimitive": { "alias": "valuePrimitive"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "close": "close"; "closed": "closed"; "disabled": "disabledChange"; "open": "open"; "opened": "opened"; "touch": "touch"; "value": "valueChange"; }, ["footerTemplate", "groupHeaderTemplate", "headerTemplate", "itemTemplate", "noDataTemplate", "prefixTemplate", "tagTemplate"], never, true, [{ directive: typeof i1.DropdownDataHandlerDirective; inputs: {}; outputs: {}; }, { directive: typeof i1.DropdownListPopupHandlerDirective; inputs: {}; outputs: {}; }]>;
219
235
  }
220
236
 
221
237
  declare class MultiSelectSummaryTagDirective<TData> {