@nanahoshi/mona-ui 0.18.5 → 0.19.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 (112) hide show
  1. package/README.md +71 -13
  2. package/fesm2022/nanahoshi-mona-ui-auto-complete.mjs +11 -3
  3. package/fesm2022/nanahoshi-mona-ui-breadcrumb.mjs +17 -9
  4. package/fesm2022/nanahoshi-mona-ui-button-group.mjs +16 -7
  5. package/fesm2022/nanahoshi-mona-ui-calendar.mjs +122 -48
  6. package/fesm2022/nanahoshi-mona-ui-card.mjs +22 -14
  7. package/fesm2022/nanahoshi-mona-ui-chart.mjs +78 -18
  8. package/fesm2022/nanahoshi-mona-ui-check-box.mjs +1 -1
  9. package/fesm2022/nanahoshi-mona-ui-chip.mjs +199 -77
  10. package/fesm2022/nanahoshi-mona-ui-circular-progress-bar.mjs +1 -2
  11. package/fesm2022/nanahoshi-mona-ui-color-gradient.mjs +23 -5
  12. package/fesm2022/nanahoshi-mona-ui-color-palette.mjs +49 -28
  13. package/fesm2022/nanahoshi-mona-ui-color-picker.mjs +42 -26
  14. package/fesm2022/nanahoshi-mona-ui-combo-box.mjs +11 -3
  15. package/fesm2022/nanahoshi-mona-ui-date-picker.mjs +28 -16
  16. package/fesm2022/nanahoshi-mona-ui-datetime-picker.mjs +74 -51
  17. package/fesm2022/nanahoshi-mona-ui-dialog.mjs +57 -25
  18. package/fesm2022/nanahoshi-mona-ui-dropdown-list.mjs +13 -5
  19. package/fesm2022/nanahoshi-mona-ui-dropdowns.mjs +17 -6
  20. package/fesm2022/nanahoshi-mona-ui-editor.mjs +178 -59
  21. package/fesm2022/nanahoshi-mona-ui-filter.mjs +137 -54
  22. package/fesm2022/{nanahoshi-mona-ui-grid-grid-footer-cell.component-WEDbZ5vy.mjs → nanahoshi-mona-ui-grid-grid-footer-cell.component-Bg7rckst.mjs} +2 -2
  23. package/fesm2022/{nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-ibH5osCg.mjs → nanahoshi-mona-ui-grid-grid-footer-table-cell.directive-BSSpaCLL.mjs} +2 -2
  24. package/fesm2022/nanahoshi-mona-ui-grid-grid-list.component-D9AwQFDV.mjs +145 -0
  25. package/fesm2022/{nanahoshi-mona-ui-grid-grid-toggle.component-hc-LeIb0.mjs → nanahoshi-mona-ui-grid-grid-toggle.component-Byb9iTes.mjs} +21 -17
  26. package/fesm2022/{nanahoshi-mona-ui-grid-grid-virtual-list.component-DYajpOb9.mjs → nanahoshi-mona-ui-grid-grid-virtual-list.component-CBmdtrXm.mjs} +5 -5
  27. package/fesm2022/{nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-Pm8Fbp6M.mjs → nanahoshi-mona-ui-grid-nanahoshi-mona-ui-grid-DPmJmCap.mjs} +90 -42
  28. package/fesm2022/nanahoshi-mona-ui-grid.mjs +1 -1
  29. package/fesm2022/nanahoshi-mona-ui-i18n.mjs +1168 -0
  30. package/fesm2022/nanahoshi-mona-ui-internal-list.mjs +12 -4
  31. package/fesm2022/nanahoshi-mona-ui-internal-tree.mjs +48 -21
  32. package/fesm2022/nanahoshi-mona-ui-list-box.mjs +33 -18
  33. package/fesm2022/nanahoshi-mona-ui-list-view.mjs +10 -10
  34. package/fesm2022/nanahoshi-mona-ui-list.mjs +2 -0
  35. package/fesm2022/nanahoshi-mona-ui-menubar.mjs +29 -16
  36. package/fesm2022/nanahoshi-mona-ui-multi-select.mjs +12 -3
  37. package/fesm2022/nanahoshi-mona-ui-notification.mjs +23 -18
  38. package/fesm2022/nanahoshi-mona-ui-numeric-text-box.mjs +211 -106
  39. package/fesm2022/nanahoshi-mona-ui-otp-input.mjs +14 -6
  40. package/fesm2022/nanahoshi-mona-ui-pager.mjs +46 -19
  41. package/fesm2022/nanahoshi-mona-ui-popup-menu.mjs +57 -46
  42. package/fesm2022/nanahoshi-mona-ui-popup.mjs +35 -15
  43. package/fesm2022/nanahoshi-mona-ui-progress-bar.mjs +38 -17
  44. package/fesm2022/nanahoshi-mona-ui-rating.mjs +25 -7
  45. package/fesm2022/nanahoshi-mona-ui-scroll-view.mjs +431 -101
  46. package/fesm2022/nanahoshi-mona-ui-segmented.mjs +1 -1
  47. package/fesm2022/nanahoshi-mona-ui-sheet.mjs +26 -8
  48. package/fesm2022/nanahoshi-mona-ui-sidebar.mjs +222 -28
  49. package/fesm2022/nanahoshi-mona-ui-slider.mjs +91 -36
  50. package/fesm2022/nanahoshi-mona-ui-spinner.mjs +34 -15
  51. package/fesm2022/nanahoshi-mona-ui-split-button.mjs +39 -23
  52. package/fesm2022/nanahoshi-mona-ui-splitter.mjs +50 -25
  53. package/fesm2022/nanahoshi-mona-ui-stepper.mjs +32 -14
  54. package/fesm2022/nanahoshi-mona-ui-switch.mjs +9 -9
  55. package/fesm2022/nanahoshi-mona-ui-tabs.mjs +74 -56
  56. package/fesm2022/nanahoshi-mona-ui-text-box.mjs +16 -8
  57. package/fesm2022/nanahoshi-mona-ui-time-picker.mjs +33 -19
  58. package/fesm2022/nanahoshi-mona-ui-time-selector.mjs +66 -27
  59. package/fesm2022/nanahoshi-mona-ui-tree-view.mjs +23 -15
  60. package/fesm2022/nanahoshi-mona-ui-window.mjs +71 -40
  61. package/i18n/package.json +4 -0
  62. package/package.json +5 -1
  63. package/types/nanahoshi-mona-ui-auto-complete.d.ts +6 -1
  64. package/types/nanahoshi-mona-ui-breadcrumb.d.ts +9 -3
  65. package/types/nanahoshi-mona-ui-button-group.d.ts +9 -3
  66. package/types/nanahoshi-mona-ui-calendar.d.ts +13 -3
  67. package/types/nanahoshi-mona-ui-card.d.ts +8 -2
  68. package/types/nanahoshi-mona-ui-chart.d.ts +10 -1
  69. package/types/nanahoshi-mona-ui-chip.d.ts +14 -5
  70. package/types/nanahoshi-mona-ui-color-gradient.d.ts +6 -1
  71. package/types/nanahoshi-mona-ui-color-palette.d.ts +21 -10
  72. package/types/nanahoshi-mona-ui-color-picker.d.ts +30 -20
  73. package/types/nanahoshi-mona-ui-combo-box.d.ts +6 -1
  74. package/types/nanahoshi-mona-ui-date-picker.d.ts +7 -2
  75. package/types/nanahoshi-mona-ui-datetime-picker.d.ts +33 -8
  76. package/types/nanahoshi-mona-ui-dialog.d.ts +16 -7
  77. package/types/nanahoshi-mona-ui-dropdown-list.d.ts +6 -1
  78. package/types/nanahoshi-mona-ui-dropdowns.d.ts +4 -1
  79. package/types/nanahoshi-mona-ui-editor.d.ts +6 -1
  80. package/types/nanahoshi-mona-ui-filter.d.ts +16 -10
  81. package/types/nanahoshi-mona-ui-grid.d.ts +38 -1
  82. package/types/nanahoshi-mona-ui-i18n.d.ts +633 -0
  83. package/types/nanahoshi-mona-ui-internal-list.d.ts +7 -2
  84. package/types/nanahoshi-mona-ui-internal-tree.d.ts +7 -3
  85. package/types/nanahoshi-mona-ui-list-box.d.ts +9 -4
  86. package/types/nanahoshi-mona-ui-list-view.d.ts +6 -6
  87. package/types/nanahoshi-mona-ui-list.d.ts +1 -1
  88. package/types/nanahoshi-mona-ui-menubar.d.ts +59 -58
  89. package/types/nanahoshi-mona-ui-multi-select.d.ts +6 -1
  90. package/types/nanahoshi-mona-ui-notification.d.ts +11 -5
  91. package/types/nanahoshi-mona-ui-numeric-text-box.d.ts +24 -15
  92. package/types/nanahoshi-mona-ui-otp-input.d.ts +9 -3
  93. package/types/nanahoshi-mona-ui-pager.d.ts +19 -6
  94. package/types/nanahoshi-mona-ui-popup.d.ts +2 -1
  95. package/types/nanahoshi-mona-ui-progress-bar.d.ts +9 -7
  96. package/types/nanahoshi-mona-ui-rating.d.ts +19 -12
  97. package/types/nanahoshi-mona-ui-scroll-view.d.ts +34 -28
  98. package/types/nanahoshi-mona-ui-sheet.d.ts +8 -2
  99. package/types/nanahoshi-mona-ui-sidebar.d.ts +3 -0
  100. package/types/nanahoshi-mona-ui-slider.d.ts +44 -26
  101. package/types/nanahoshi-mona-ui-spinner.d.ts +13 -4
  102. package/types/nanahoshi-mona-ui-split-button.d.ts +62 -56
  103. package/types/nanahoshi-mona-ui-splitter.d.ts +9 -6
  104. package/types/nanahoshi-mona-ui-stepper.d.ts +9 -3
  105. package/types/nanahoshi-mona-ui-switch.d.ts +1 -1
  106. package/types/nanahoshi-mona-ui-tabs.d.ts +96 -35
  107. package/types/nanahoshi-mona-ui-text-box.d.ts +11 -5
  108. package/types/nanahoshi-mona-ui-time-picker.d.ts +7 -2
  109. package/types/nanahoshi-mona-ui-time-selector.d.ts +16 -5
  110. package/types/nanahoshi-mona-ui-tree-view.d.ts +15 -10
  111. package/types/nanahoshi-mona-ui-window.d.ts +26 -20
  112. package/fesm2022/nanahoshi-mona-ui-grid-grid-list.component-ZM3CneJ0.mjs +0 -145
package/README.md CHANGED
@@ -1,25 +1,83 @@
1
- # MonaUi
1
+ # Mona UI
2
2
 
3
- This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 14.1.0.
3
+ A modern, high-performance, accessible UI component library built for Angular and styled with Tailwind CSS.
4
4
 
5
- ## Code scaffolding
5
+ ---
6
6
 
7
- Run `ng generate component component-name --project mona-ui` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project mona-ui`.
7
+ ## Features
8
8
 
9
- > Note: Don't forget to add `--project mona-ui` or else it will be added to the default project in your `angular.json` file.
9
+ - **Signal-Based State & Reactive Architecture:** First-class Angular Signals architecture for fine-grained reactivity.
10
+ - **Standalone Components:** Designed exclusively with modern Angular standalone components.
11
+ - **Comprehensive Internationalization (i18n):** Zero-config English defaults with full runtime locale switching, typed message namespaces, and message override precedence.
12
+ - **RTL-Ready:** Fully prepared for right-to-left layout direction with CSS Logical Properties and CDK-driven directionality.
13
+ - **High-Grade Accessibility (a11y):** Strict adherence to WCAG AA minimums, dynamic ARIA attributes, and zero AXE violations.
14
+ - **40+ Rich Components:** Data grids, interactive charts, calendar/pickers, rich text editor, scroll view, dialogs, dropdowns, and more.
10
15
 
11
- ## Build
16
+ ---
12
17
 
13
- Run `ng build mona-ui` to build the project. The build artifacts will be stored in the `dist/` directory.
18
+ ## Documentation
14
19
 
15
- ## Publishing
20
+ - [Internationalization (i18n) & RTL Guide](docs/i18n.md)
21
+ - [Component Migration Inventory](docs/internal/i18n-rtl-migration-inventory.md)
16
22
 
17
- After building your library with `ng build mona-ui`, go to the dist folder `cd dist/mona-ui` and run `npm publish`.
23
+ ---
18
24
 
19
- ## Running unit tests
25
+ ## Quick Start
20
26
 
21
- Run `ng test mona-ui` to execute the unit tests via [Karma](https://karma-runner.github.io).
27
+ ### Installation
22
28
 
23
- ## Further help
29
+ ```bash
30
+ npm install @nanahoshi/mona-ui
31
+ ```
24
32
 
25
- To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
33
+ ### Setup Internationalization
34
+
35
+ Mona UI works out-of-the-box in English without configuration. To provide a customized locale or configure runtime language switching, import `provideMonaI18n`:
36
+
37
+ ```typescript
38
+ import { ApplicationConfig } from '@angular/core';
39
+ import { provideMonaI18n } from '@nanahoshi/mona-ui/i18n';
40
+
41
+ export const appConfig: ApplicationConfig = {
42
+ providers: [
43
+ provideMonaI18n()
44
+ ]
45
+ };
46
+ ```
47
+
48
+ For complete details on localization, locale switching, and RTL support, refer to the [i18n & RTL Guide](docs/i18n.md).
49
+
50
+ ---
51
+
52
+ ## Development
53
+
54
+ ### Building the Library
55
+
56
+ ```bash
57
+ npm run build:metadata
58
+ npm run build:prod
59
+ ```
60
+
61
+ ### Running Tests
62
+
63
+ ```bash
64
+ # Run unit tests for the component library
65
+ npm run test:lib
66
+
67
+ # Run unit tests for the tester app
68
+ npm run test:app
69
+ ```
70
+
71
+ ### i18n & RTL Quality Audit
72
+
73
+ Mona UI includes an automated AST-based scanner to verify that no hard-coded English text, static ARIA labels, or physical CSS properties are introduced:
74
+
75
+ ```bash
76
+ npm run audit:i18n-rtl:strict
77
+ ```
78
+
79
+ ---
80
+
81
+ ## License
82
+
83
+ MIT
@@ -11,10 +11,15 @@ import { ListService, ListComponent, ListGroupHeaderTemplateDirective, ListFoote
11
11
  import * as i1 from '@nanahoshi/mona-ui/dropdowns';
12
12
  import { DropdownService, DropdownFooterTemplateDirective, DropdownGroupHeaderTemplateDirective, DropdownHeaderTemplateDirective, DropdownItemTemplateDirective, dropdownPopupThemeVariants, DropdownNoDataTemplateDirective, DropdownPrefixTemplateDirective, DropdownSuffixTemplateDirective, DropdownLiveRegionDirective, DropdownDataInputToken, DropdownPopupInputToken, DropdownDataHandlerDirective, DropdownListPopupHandlerDirective } from '@nanahoshi/mona-ui/dropdowns';
13
13
  import { TextBoxDirective } from '@nanahoshi/mona-ui/text-box';
14
+ import { MonaI18nService } from '@nanahoshi/mona-ui/i18n';
14
15
  import { Subject, filter, debounceTime, identity, take, tap } from 'rxjs';
15
16
  import { twMerge } from 'tailwind-merge';
16
17
  import { cva } from 'class-variance-authority';
17
18
 
19
+ const AUTO_COMPLETE_DEFAULT_MESSAGES = {
20
+ clear: "Clear"
21
+ };
22
+
18
23
  const autoCompleteBaseThemeVariants = cva(`
19
24
  flex
20
25
  ${themeControlSurfaceClasses} text-foreground
@@ -95,12 +100,14 @@ class AutoCompleteComponent {
95
100
  #destroyRef;
96
101
  #dropdownService;
97
102
  #hostElementRef;
103
+ #i18n;
98
104
  #listService;
99
105
  #popupRef;
100
106
  constructor() {
101
107
  this.#destroyRef = inject(DestroyRef);
102
108
  this.#dropdownService = inject(DropdownService);
103
109
  this.#hostElementRef = inject((ElementRef));
110
+ this.#i18n = inject(MonaI18nService);
104
111
  this.#listService = inject(ListService);
105
112
  this.#popupRef = this.#dropdownService.popupRef;
106
113
  this.activeDescendant = computed(() => {
@@ -161,6 +168,7 @@ class AutoCompleteComponent {
161
168
  return twMerge(variantClass, userClass);
162
169
  }, /* @ts-ignore */
163
170
  ...(ngDevMode ? [{ debugName: "listPopupClass" }] : /* istanbul ignore next */ []));
171
+ this.messages = this.#i18n.componentMessages("autoComplete", AUTO_COMPLETE_DEFAULT_MESSAGES);
164
172
  this.noDataTemplate = contentChild(DropdownNoDataTemplateDirective, { ...(ngDevMode ? { debugName: "noDataTemplate" } : /* istanbul ignore next */ {}), read: TemplateRef });
165
173
  this.popupTemplate = viewChild.required("popupTemplate", /* @ts-ignore */
166
174
  ...(ngDevMode ? [{ debugName: "popupTemplate" }] : /* istanbul ignore next */ []));
@@ -518,7 +526,7 @@ class AutoCompleteComponent {
518
526
  useExisting: forwardRef(() => AutoCompleteComponent),
519
527
  multi: false
520
528
  }
521
- ], queries: [{ propertyName: "footerTemplate", first: true, predicate: DropdownFooterTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "groupHeaderTemplate", first: true, predicate: DropdownGroupHeaderTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "headerTemplate", first: true, predicate: DropdownHeaderTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "itemTemplate", first: true, predicate: DropdownItemTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "noDataTemplate", first: true, predicate: DropdownNoDataTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "prefixTemplate", first: true, predicate: DropdownPrefixTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "suffixTemplate", first: true, predicate: DropdownSuffixTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "popupTemplate", first: true, predicate: ["popupTemplate"], descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.DropdownDataHandlerDirective }, { directive: i1.DropdownListPopupHandlerDirective }], ngImport: i0, template: "@if (prefixTemplate()) {\n <span [class]=\"affixClass()\">\n <ng-container [ngTemplateOutlet]=\"prefixTemplate()\"></ng-container>\n </span>\n}\n\n<input\n monaTextBox\n role=\"combobox\"\n [class]=\"inputClass()\"\n [disabled]=\"disabled()\"\n [id]=\"id\"\n [placeholder]=\"placeholder()\"\n [readonly]=\"readonly()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [ngModel]=\"autoCompleteValue()\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.aria-autocomplete]=\"'list'\"\n [attr.aria-busy]=\"loading()\"\n [attr.aria-controls]=\"listId\"\n [attr.aria-describedby]=\"ariaDescribedBy() || undefined\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-invalid]=\"invalidState() || undefined\"\n [attr.aria-label]=\"effectiveAriaLabel() || undefined\"\n [attr.aria-labelledby]=\"ariaLabelledBy() || undefined\"\n (ngModelChange)=\"autoCompleteValue$.next($event)\"\n (blur)=\"onInputBlur()\" />\n\n@if (showClearButton() && autoCompleteValue() && !loading()) {\n <mona-indicator-icon\n preset=\"clear\"\n [interactive]=\"true\"\n label=\"Clear\"\n (activate)=\"onValueClear($event)\"></mona-indicator-icon>\n}\n\n@if (loading()) {\n <mona-indicator-icon preset=\"loading\" [size]=\"12\"></mona-indicator-icon>\n}\n\n@if (suffixTemplate()) {\n <span [class]=\"affixClass()\">\n <ng-container [ngTemplateOutlet]=\"suffixTemplate()\"></ng-container>\n </span>\n}\n\n<span monaDropdownLiveRegion></span>\n\n<ng-template #popupTemplate>\n <div [class]=\"listPopupClass()\">\n <mona-list (itemSelect)=\"onItemSelect($event)\" [focusOnMount]=\"false\" [size]=\"size()\" [listId]=\"listId\">\n @if (footerTemplate()) {\n <ng-template monaListFooterTemplate>\n <ng-container [ngTemplateOutlet]=\"footerTemplate()\"></ng-container>\n </ng-template>\n }\n @if (groupHeaderTemplate()) {\n <ng-template monaListGroupHeaderTemplate let-group>\n <ng-container\n [ngTemplateOutlet]=\"groupHeaderTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: group }\"></ng-container>\n </ng-template>\n }\n @if (headerTemplate()) {\n <ng-template monaListHeaderTemplate>\n <ng-container [ngTemplateOutlet]=\"headerTemplate()\"></ng-container>\n </ng-template>\n }\n @if (itemTemplate()) {\n <ng-template monaListItemTemplate let-dataItem>\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: dataItem }\"></ng-container>\n </ng-template>\n }\n @if (noDataTemplate()) {\n <ng-template monaListNoDataTemplate>\n <ng-container [ngTemplateOutlet]=\"noDataTemplate()\"></ng-container>\n </ng-template>\n }\n </mona-list>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: TextBoxDirective, selector: "input[monaTextBox]", inputs: ["invalid", "rounded", "size", "touched", "class"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ListComponent, selector: "mona-list", inputs: ["ariaLabel", "data", "focusOnMount", "height", "listClass", "listId", "listItemClass", "listItemStyle", "listStyle", "maxHeight", "maxWidth", "size", "textField", "width"], outputs: ["itemSelect"] }, { kind: "directive", type: ListGroupHeaderTemplateDirective, selector: "ng-template[monaListGroupHeaderTemplate]" }, { kind: "directive", type: ListFooterTemplateDirective, selector: "ng-template[monaListFooterTemplate]" }, { kind: "directive", type: ListHeaderTemplateDirective, selector: "ng-template[monaListHeaderTemplate]" }, { kind: "directive", type: ListNoDataTemplateDirective, selector: "ng-template[monaListNoDataTemplate]" }, { kind: "directive", type: ListItemTemplateDirective, selector: "ng-template[monaListItemTemplate]" }, { kind: "directive", type: DropdownLiveRegionDirective, selector: "span[monaDropdownLiveRegion]" }, { kind: "component", type: IndicatorIconComponent, selector: "mona-indicator-icon", inputs: ["icon", "interactive", "label", "preset", "size", "class"], outputs: ["activate"] }] }); }
529
+ ], queries: [{ propertyName: "footerTemplate", first: true, predicate: DropdownFooterTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "groupHeaderTemplate", first: true, predicate: DropdownGroupHeaderTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "headerTemplate", first: true, predicate: DropdownHeaderTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "itemTemplate", first: true, predicate: DropdownItemTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "noDataTemplate", first: true, predicate: DropdownNoDataTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "prefixTemplate", first: true, predicate: DropdownPrefixTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }, { propertyName: "suffixTemplate", first: true, predicate: DropdownSuffixTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], viewQueries: [{ propertyName: "popupTemplate", first: true, predicate: ["popupTemplate"], descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.DropdownDataHandlerDirective }, { directive: i1.DropdownListPopupHandlerDirective }], ngImport: i0, template: "@if (prefixTemplate()) {\n <span [class]=\"affixClass()\">\n <ng-container [ngTemplateOutlet]=\"prefixTemplate()\"></ng-container>\n </span>\n}\n\n<input\n monaTextBox\n role=\"combobox\"\n [class]=\"inputClass()\"\n [disabled]=\"disabled()\"\n [id]=\"id\"\n [placeholder]=\"placeholder()\"\n [readonly]=\"readonly()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [ngModel]=\"autoCompleteValue()\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.aria-autocomplete]=\"'list'\"\n [attr.aria-busy]=\"loading()\"\n [attr.aria-controls]=\"listId\"\n [attr.aria-describedby]=\"ariaDescribedBy() || undefined\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-invalid]=\"invalidState() || undefined\"\n [attr.aria-label]=\"effectiveAriaLabel() || undefined\"\n [attr.aria-labelledby]=\"ariaLabelledBy() || undefined\"\n (ngModelChange)=\"autoCompleteValue$.next($event)\"\n (blur)=\"onInputBlur()\" />\n\n@if (showClearButton() && autoCompleteValue() && !loading()) {\n <mona-indicator-icon\n preset=\"clear\"\n [interactive]=\"true\"\n [label]=\"messages().clear\"\n (activate)=\"onValueClear($event)\"></mona-indicator-icon>\n}\n\n@if (loading()) {\n <mona-indicator-icon preset=\"loading\" [size]=\"12\"></mona-indicator-icon>\n}\n\n@if (suffixTemplate()) {\n <span [class]=\"affixClass()\">\n <ng-container [ngTemplateOutlet]=\"suffixTemplate()\"></ng-container>\n </span>\n}\n\n<span monaDropdownLiveRegion></span>\n\n<ng-template #popupTemplate>\n <div [class]=\"listPopupClass()\">\n <mona-list (itemSelect)=\"onItemSelect($event)\" [focusOnMount]=\"false\" [size]=\"size()\" [listId]=\"listId\">\n @if (footerTemplate()) {\n <ng-template monaListFooterTemplate>\n <ng-container [ngTemplateOutlet]=\"footerTemplate()\"></ng-container>\n </ng-template>\n }\n @if (groupHeaderTemplate()) {\n <ng-template monaListGroupHeaderTemplate let-group>\n <ng-container\n [ngTemplateOutlet]=\"groupHeaderTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: group }\"></ng-container>\n </ng-template>\n }\n @if (headerTemplate()) {\n <ng-template monaListHeaderTemplate>\n <ng-container [ngTemplateOutlet]=\"headerTemplate()\"></ng-container>\n </ng-template>\n }\n @if (itemTemplate()) {\n <ng-template monaListItemTemplate let-dataItem>\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: dataItem }\"></ng-container>\n </ng-template>\n }\n @if (noDataTemplate()) {\n <ng-template monaListNoDataTemplate>\n <ng-container [ngTemplateOutlet]=\"noDataTemplate()\"></ng-container>\n </ng-template>\n }\n </mona-list>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: TextBoxDirective, selector: "input[monaTextBox]", inputs: ["invalid", "rounded", "size", "touched", "class"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ListComponent, selector: "mona-list", inputs: ["ariaLabel", "data", "focusOnMount", "height", "listClass", "listId", "listItemClass", "listItemStyle", "listStyle", "maxHeight", "maxWidth", "size", "textField", "width"], outputs: ["itemSelect"] }, { kind: "directive", type: ListGroupHeaderTemplateDirective, selector: "ng-template[monaListGroupHeaderTemplate]" }, { kind: "directive", type: ListFooterTemplateDirective, selector: "ng-template[monaListFooterTemplate]" }, { kind: "directive", type: ListHeaderTemplateDirective, selector: "ng-template[monaListHeaderTemplate]" }, { kind: "directive", type: ListNoDataTemplateDirective, selector: "ng-template[monaListNoDataTemplate]" }, { kind: "directive", type: ListItemTemplateDirective, selector: "ng-template[monaListItemTemplate]" }, { kind: "directive", type: DropdownLiveRegionDirective, selector: "span[monaDropdownLiveRegion]" }, { kind: "component", type: IndicatorIconComponent, selector: "mona-indicator-icon", inputs: ["icon", "interactive", "label", "preset", "size", "class"], outputs: ["activate"] }] }); }
522
530
  }
523
531
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: AutoCompleteComponent, decorators: [{
524
532
  type: Component,
@@ -558,7 +566,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
558
566
  "[attr.data-readonly]": "readonly() || null",
559
567
  "[attr.tabindex]": "-1",
560
568
  "[class]": "baseClass()"
561
- }, template: "@if (prefixTemplate()) {\n <span [class]=\"affixClass()\">\n <ng-container [ngTemplateOutlet]=\"prefixTemplate()\"></ng-container>\n </span>\n}\n\n<input\n monaTextBox\n role=\"combobox\"\n [class]=\"inputClass()\"\n [disabled]=\"disabled()\"\n [id]=\"id\"\n [placeholder]=\"placeholder()\"\n [readonly]=\"readonly()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [ngModel]=\"autoCompleteValue()\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.aria-autocomplete]=\"'list'\"\n [attr.aria-busy]=\"loading()\"\n [attr.aria-controls]=\"listId\"\n [attr.aria-describedby]=\"ariaDescribedBy() || undefined\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-invalid]=\"invalidState() || undefined\"\n [attr.aria-label]=\"effectiveAriaLabel() || undefined\"\n [attr.aria-labelledby]=\"ariaLabelledBy() || undefined\"\n (ngModelChange)=\"autoCompleteValue$.next($event)\"\n (blur)=\"onInputBlur()\" />\n\n@if (showClearButton() && autoCompleteValue() && !loading()) {\n <mona-indicator-icon\n preset=\"clear\"\n [interactive]=\"true\"\n label=\"Clear\"\n (activate)=\"onValueClear($event)\"></mona-indicator-icon>\n}\n\n@if (loading()) {\n <mona-indicator-icon preset=\"loading\" [size]=\"12\"></mona-indicator-icon>\n}\n\n@if (suffixTemplate()) {\n <span [class]=\"affixClass()\">\n <ng-container [ngTemplateOutlet]=\"suffixTemplate()\"></ng-container>\n </span>\n}\n\n<span monaDropdownLiveRegion></span>\n\n<ng-template #popupTemplate>\n <div [class]=\"listPopupClass()\">\n <mona-list (itemSelect)=\"onItemSelect($event)\" [focusOnMount]=\"false\" [size]=\"size()\" [listId]=\"listId\">\n @if (footerTemplate()) {\n <ng-template monaListFooterTemplate>\n <ng-container [ngTemplateOutlet]=\"footerTemplate()\"></ng-container>\n </ng-template>\n }\n @if (groupHeaderTemplate()) {\n <ng-template monaListGroupHeaderTemplate let-group>\n <ng-container\n [ngTemplateOutlet]=\"groupHeaderTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: group }\"></ng-container>\n </ng-template>\n }\n @if (headerTemplate()) {\n <ng-template monaListHeaderTemplate>\n <ng-container [ngTemplateOutlet]=\"headerTemplate()\"></ng-container>\n </ng-template>\n }\n @if (itemTemplate()) {\n <ng-template monaListItemTemplate let-dataItem>\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: dataItem }\"></ng-container>\n </ng-template>\n }\n @if (noDataTemplate()) {\n <ng-template monaListNoDataTemplate>\n <ng-container [ngTemplateOutlet]=\"noDataTemplate()\"></ng-container>\n </ng-template>\n }\n </mona-list>\n </div>\n</ng-template>\n" }]
569
+ }, template: "@if (prefixTemplate()) {\n <span [class]=\"affixClass()\">\n <ng-container [ngTemplateOutlet]=\"prefixTemplate()\"></ng-container>\n </span>\n}\n\n<input\n monaTextBox\n role=\"combobox\"\n [class]=\"inputClass()\"\n [disabled]=\"disabled()\"\n [id]=\"id\"\n [placeholder]=\"placeholder()\"\n [readonly]=\"readonly()\"\n [rounded]=\"rounded()\"\n [size]=\"size()\"\n [ngModel]=\"autoCompleteValue()\"\n [attr.aria-activedescendant]=\"activeDescendant()\"\n [attr.aria-autocomplete]=\"'list'\"\n [attr.aria-busy]=\"loading()\"\n [attr.aria-controls]=\"listId\"\n [attr.aria-describedby]=\"ariaDescribedBy() || undefined\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-invalid]=\"invalidState() || undefined\"\n [attr.aria-label]=\"effectiveAriaLabel() || undefined\"\n [attr.aria-labelledby]=\"ariaLabelledBy() || undefined\"\n (ngModelChange)=\"autoCompleteValue$.next($event)\"\n (blur)=\"onInputBlur()\" />\n\n@if (showClearButton() && autoCompleteValue() && !loading()) {\n <mona-indicator-icon\n preset=\"clear\"\n [interactive]=\"true\"\n [label]=\"messages().clear\"\n (activate)=\"onValueClear($event)\"></mona-indicator-icon>\n}\n\n@if (loading()) {\n <mona-indicator-icon preset=\"loading\" [size]=\"12\"></mona-indicator-icon>\n}\n\n@if (suffixTemplate()) {\n <span [class]=\"affixClass()\">\n <ng-container [ngTemplateOutlet]=\"suffixTemplate()\"></ng-container>\n </span>\n}\n\n<span monaDropdownLiveRegion></span>\n\n<ng-template #popupTemplate>\n <div [class]=\"listPopupClass()\">\n <mona-list (itemSelect)=\"onItemSelect($event)\" [focusOnMount]=\"false\" [size]=\"size()\" [listId]=\"listId\">\n @if (footerTemplate()) {\n <ng-template monaListFooterTemplate>\n <ng-container [ngTemplateOutlet]=\"footerTemplate()\"></ng-container>\n </ng-template>\n }\n @if (groupHeaderTemplate()) {\n <ng-template monaListGroupHeaderTemplate let-group>\n <ng-container\n [ngTemplateOutlet]=\"groupHeaderTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: group }\"></ng-container>\n </ng-template>\n }\n @if (headerTemplate()) {\n <ng-template monaListHeaderTemplate>\n <ng-container [ngTemplateOutlet]=\"headerTemplate()\"></ng-container>\n </ng-template>\n }\n @if (itemTemplate()) {\n <ng-template monaListItemTemplate let-dataItem>\n <ng-container\n [ngTemplateOutlet]=\"itemTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: dataItem }\"></ng-container>\n </ng-template>\n }\n @if (noDataTemplate()) {\n <ng-template monaListNoDataTemplate>\n <ng-container [ngTemplateOutlet]=\"noDataTemplate()\"></ng-container>\n </ng-template>\n }\n </mona-list>\n </div>\n</ng-template>\n" }]
562
570
  }], ctorParameters: () => [], propDecorators: { footerTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DropdownFooterTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], groupHeaderTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DropdownGroupHeaderTemplateDirective), { ...{
563
571
  read: TemplateRef
564
572
  }, isSignal: true }] }], headerTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DropdownHeaderTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], itemTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DropdownItemTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], noDataTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DropdownNoDataTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], popupTemplate: [{ type: i0.ViewChild, args: ["popupTemplate", { isSignal: true }] }], prefixTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DropdownPrefixTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], suffixTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => DropdownSuffixTemplateDirective), { ...{ read: TemplateRef }, isSignal: true }] }], ariaDescribedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-describedby", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelledBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], close: [{ type: i0.Output, args: ["close"] }], closed: [{ type: i0.Output, args: ["closed"] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }, { type: i0.Output, args: ["disabledChange"] }], itemDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemDisabled", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], highlightFirst: [{ type: i0.Input, args: [{ isSignal: true, alias: "highlightFirst", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], open: [{ type: i0.Output, args: ["open"] }], opened: [{ type: i0.Output, args: ["opened"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], popupClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupClass", required: false }] }], popupHeight: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupHeight", required: false }] }], popupWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "popupWidth", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], rounded: [{ type: i0.Input, args: [{ isSignal: true, alias: "rounded", required: false }] }], showClearButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showClearButton", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], textField: [{ type: i0.Input, args: [{ isSignal: true, alias: "textField", required: false }] }], touch: [{ type: i0.Output, args: ["touch"] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }], valueField: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueField", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }] } });
@@ -571,5 +579,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
571
579
  * Generated bundle index. Do not edit.
572
580
  */
573
581
 
574
- export { AutoCompleteComponent };
582
+ export { AUTO_COMPLETE_DEFAULT_MESSAGES, AutoCompleteComponent };
575
583
  //# sourceMappingURL=nanahoshi-mona-ui-auto-complete.mjs.map
@@ -1,7 +1,8 @@
1
1
  import { NgTemplateOutlet } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { computed, input, Directive, output, viewChild, TemplateRef, Component, contentChildren, contentChild } from '@angular/core';
3
+ import { computed, input, Directive, output, viewChild, TemplateRef, Component, inject, contentChildren, contentChild } from '@angular/core';
4
4
  import { LucideChevronRight } from '@lucide/angular';
5
+ import { MonaI18nService } from '@nanahoshi/mona-ui/i18n';
5
6
  import { twMerge } from 'tailwind-merge';
6
7
  import { cva } from 'class-variance-authority';
7
8
 
@@ -96,6 +97,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
96
97
  }]
97
98
  }] });
98
99
 
100
+ const BREADCRUMB_DEFAULT_MESSAGES = {
101
+ breadcrumb: "Breadcrumb"
102
+ };
103
+
99
104
  class BreadcrumbItemComponent {
100
105
  constructor() {
101
106
  /**
@@ -123,12 +128,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
123
128
 
124
129
  class BreadcrumbComponent {
125
130
  constructor() {
126
- this.itemComponents = contentChildren(BreadcrumbItemComponent, /* @ts-ignore */
127
- ...(ngDevMode ? [{ debugName: "itemComponents" }] : /* istanbul ignore next */ []));
131
+ this.#i18n = inject(MonaI18nService);
128
132
  this.currentItemClass = computed(() => {
129
133
  return breadcrumbCurrentItemThemeVariants();
130
134
  }, /* @ts-ignore */
131
135
  ...(ngDevMode ? [{ debugName: "currentItemClass" }] : /* istanbul ignore next */ []));
136
+ this.itemComponents = contentChildren(BreadcrumbItemComponent, /* @ts-ignore */
137
+ ...(ngDevMode ? [{ debugName: "itemComponents" }] : /* istanbul ignore next */ []));
132
138
  this.listClass = computed(() => {
133
139
  const disabled = this.disabled();
134
140
  const userClass = this.userClass();
@@ -136,13 +142,14 @@ class BreadcrumbComponent {
136
142
  return twMerge(variantClass, userClass);
137
143
  }, /* @ts-ignore */
138
144
  ...(ngDevMode ? [{ debugName: "listClass" }] : /* istanbul ignore next */ []));
145
+ this.messages = this.#i18n.componentMessages("breadcrumb", BREADCRUMB_DEFAULT_MESSAGES);
139
146
  this.separatorTemplate = contentChild(BreadcrumbSeparatorTemplateDirective, { ...(ngDevMode ? { debugName: "separatorTemplate" } : /* istanbul ignore next */ {}), read: TemplateRef });
140
147
  /**
141
148
  * @description Accessible name for the breadcrumb navigation landmark.
142
149
  * Override when multiple breadcrumb components appear on the same page.
143
- * @default "Breadcrumb"
150
+ * @default ""
144
151
  */
145
- this.ariaLabel = input("Breadcrumb", { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: "aria-label" });
152
+ this.ariaLabel = input("", { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: "aria-label" });
146
153
  /**
147
154
  * @description Renders the entire breadcrumb with reduced visual emphasis and removes pointer interaction from all items.
148
155
  * @default false
@@ -155,6 +162,7 @@ class BreadcrumbComponent {
155
162
  */
156
163
  this.userClass = input("", { ...(ngDevMode ? { debugName: "userClass" } : /* istanbul ignore next */ {}), alias: "class" });
157
164
  }
165
+ #i18n;
158
166
  onItemClick(item) {
159
167
  if (this.disabled() || item.disabled()) {
160
168
  return;
@@ -162,14 +170,14 @@ class BreadcrumbComponent {
162
170
  item.itemClick.emit();
163
171
  }
164
172
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: BreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
165
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: BreadcrumbComponent, isStandalone: true, selector: "mona-breadcrumb", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "ariaLabel()" } }, queries: [{ propertyName: "itemComponents", predicate: BreadcrumbItemComponent, isSignal: true }, { propertyName: "separatorTemplate", first: true, predicate: BreadcrumbSeparatorTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "<ol role=\"list\" [class]=\"listClass()\">\n @for (item of itemComponents(); track item) {\n <li>\n @if ($last) {\n <span aria-current=\"page\" [class]=\"currentItemClass()\">\n <ng-container [ngTemplateOutlet]=\"item.templateRef()\"></ng-container>\n </span>\n } @else {\n <button\n type=\"button\"\n monaBreadcrumbItem\n [disabled]=\"disabled() || item.disabled()\"\n (click)=\"onItemClick(item)\">\n <ng-container [ngTemplateOutlet]=\"item.templateRef()\"></ng-container>\n </button>\n }\n </li>\n\n @if (!$last) {\n <li aria-hidden=\"true\" role=\"presentation\">\n @if (separatorTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"separatorTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: $index }\"></ng-container>\n } @else {\n <svg lucideChevronRight [size]=\"18\"></svg>\n }\n </li>\n }\n }\n</ol>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: BreadcrumbItemDirective, selector: "button[monaBreadcrumbItem]", inputs: ["disabled", "listDisabled", "class"] }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }] }); }
173
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: BreadcrumbComponent, isStandalone: true, selector: "mona-breadcrumb", inputs: { ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "navigation" }, properties: { "attr.aria-label": "ariaLabel() || messages().breadcrumb" } }, queries: [{ propertyName: "itemComponents", predicate: BreadcrumbItemComponent, isSignal: true }, { propertyName: "separatorTemplate", first: true, predicate: BreadcrumbSeparatorTemplateDirective, descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "<ol role=\"list\" [class]=\"listClass()\">\n @for (item of itemComponents(); track item) {\n <li>\n @if ($last) {\n <span aria-current=\"page\" [class]=\"currentItemClass()\">\n <ng-container [ngTemplateOutlet]=\"item.templateRef()\"></ng-container>\n </span>\n } @else {\n <button\n type=\"button\"\n monaBreadcrumbItem\n [disabled]=\"disabled() || item.disabled()\"\n (click)=\"onItemClick(item)\">\n <ng-container [ngTemplateOutlet]=\"item.templateRef()\"></ng-container>\n </button>\n }\n </li>\n\n @if (!$last) {\n <li aria-hidden=\"true\" role=\"presentation\">\n @if (separatorTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"separatorTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: $index }\"></ng-container>\n } @else {\n <svg lucideChevronRight [size]=\"18\" class=\"rtl:rotate-180\"></svg>\n }\n </li>\n }\n }\n</ol>\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: BreadcrumbItemDirective, selector: "button[monaBreadcrumbItem]", inputs: ["disabled", "listDisabled", "class"] }, { kind: "component", type: LucideChevronRight, selector: "svg[lucideChevronRight]" }] }); }
166
174
  }
167
175
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: BreadcrumbComponent, decorators: [{
168
176
  type: Component,
169
177
  args: [{ selector: "mona-breadcrumb", imports: [NgTemplateOutlet, BreadcrumbItemDirective, LucideChevronRight], host: {
170
178
  role: "navigation",
171
- "[attr.aria-label]": "ariaLabel()"
172
- }, template: "<ol role=\"list\" [class]=\"listClass()\">\n @for (item of itemComponents(); track item) {\n <li>\n @if ($last) {\n <span aria-current=\"page\" [class]=\"currentItemClass()\">\n <ng-container [ngTemplateOutlet]=\"item.templateRef()\"></ng-container>\n </span>\n } @else {\n <button\n type=\"button\"\n monaBreadcrumbItem\n [disabled]=\"disabled() || item.disabled()\"\n (click)=\"onItemClick(item)\">\n <ng-container [ngTemplateOutlet]=\"item.templateRef()\"></ng-container>\n </button>\n }\n </li>\n\n @if (!$last) {\n <li aria-hidden=\"true\" role=\"presentation\">\n @if (separatorTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"separatorTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: $index }\"></ng-container>\n } @else {\n <svg lucideChevronRight [size]=\"18\"></svg>\n }\n </li>\n }\n }\n</ol>\n" }]
179
+ "[attr.aria-label]": "ariaLabel() || messages().breadcrumb"
180
+ }, template: "<ol role=\"list\" [class]=\"listClass()\">\n @for (item of itemComponents(); track item) {\n <li>\n @if ($last) {\n <span aria-current=\"page\" [class]=\"currentItemClass()\">\n <ng-container [ngTemplateOutlet]=\"item.templateRef()\"></ng-container>\n </span>\n } @else {\n <button\n type=\"button\"\n monaBreadcrumbItem\n [disabled]=\"disabled() || item.disabled()\"\n (click)=\"onItemClick(item)\">\n <ng-container [ngTemplateOutlet]=\"item.templateRef()\"></ng-container>\n </button>\n }\n </li>\n\n @if (!$last) {\n <li aria-hidden=\"true\" role=\"presentation\">\n @if (separatorTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"separatorTemplate()\"\n [ngTemplateOutletContext]=\"{ $implicit: $index }\"></ng-container>\n } @else {\n <svg lucideChevronRight [size]=\"18\" class=\"rtl:rotate-180\"></svg>\n }\n </li>\n }\n }\n</ol>\n" }]
173
181
  }], propDecorators: { itemComponents: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => BreadcrumbItemComponent), { isSignal: true }] }], separatorTemplate: [{ type: i0.ContentChild, args: [i0.forwardRef(() => BreadcrumbSeparatorTemplateDirective), { ...{
174
182
  read: TemplateRef
175
183
  }, isSignal: true }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], userClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "class", required: false }] }] } });
@@ -182,5 +190,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
182
190
  * Generated bundle index. Do not edit.
183
191
  */
184
192
 
185
- export { BreadcrumbComponent, BreadcrumbItemComponent, BreadcrumbSeparatorTemplateDirective };
193
+ export { BREADCRUMB_DEFAULT_MESSAGES, BreadcrumbComponent, BreadcrumbItemComponent, BreadcrumbSeparatorTemplateDirective };
186
194
  //# sourceMappingURL=nanahoshi-mona-ui-breadcrumb.mjs.map
@@ -2,16 +2,21 @@ import * as i0 from '@angular/core';
2
2
  import { inject, DestroyRef, computed, contentChildren, input, model, effect, untracked, afterNextRender, Component } from '@angular/core';
3
3
  import { outputFromObservable, takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
4
4
  import { ButtonService, ButtonDirective } from '@nanahoshi/mona-ui/button';
5
+ import { MonaI18nService } from '@nanahoshi/mona-ui/i18n';
5
6
  import { map, pairwise } from 'rxjs';
6
7
  import { twMerge } from 'tailwind-merge';
7
8
  import { cva } from 'class-variance-authority';
8
9
 
10
+ const BUTTON_GROUP_DEFAULT_MESSAGES = {
11
+ buttonGroup: "Button group"
12
+ };
13
+
9
14
  const buttonGroupThemeVariants = cva(`
10
15
  inline-flex items-center justify-center
11
16
  border border-input-border
12
17
  [&>button]:border-0
13
18
  [&>button]:shadow-none
14
- [&>button:not(:last-child)]:border-r
19
+ [&>button:not(:last-child)]:border-e
15
20
  [&>button:not(:last-child)]:border-border-subtle
16
21
  [&>button]:rounded-none
17
22
  [&>button]:focus-visible:ring-2
@@ -21,7 +26,7 @@ const buttonGroupThemeVariants = cva(`
21
26
  look: {
22
27
  default: "",
23
28
  error: "border-transparent",
24
- ghost: "border-transparent [&>button:not(:last-child)]:border-r-0",
29
+ ghost: "border-transparent [&>button:not(:last-child)]:border-e-0",
25
30
  info: "border-transparent",
26
31
  outline: "",
27
32
  primary: "border-transparent",
@@ -69,9 +74,11 @@ const buttonGroupThemeVariants = cva(`
69
74
  class ButtonGroupComponent {
70
75
  #buttonService;
71
76
  #destroyRef;
77
+ #i18n;
72
78
  constructor() {
73
79
  this.#buttonService = inject(ButtonService, { self: true });
74
80
  this.#destroyRef = inject(DestroyRef);
81
+ this.#i18n = inject(MonaI18nService);
75
82
  this.baseClass = computed(() => {
76
83
  const look = this.look();
77
84
  const rounded = this.rounded();
@@ -83,6 +90,9 @@ class ButtonGroupComponent {
83
90
  ...(ngDevMode ? [{ debugName: "baseClass" }] : /* istanbul ignore next */ []));
84
91
  this.buttons = contentChildren(ButtonDirective, /* @ts-ignore */
85
92
  ...(ngDevMode ? [{ debugName: "buttons" }] : /* istanbul ignore next */ []));
93
+ this.messages = this.#i18n.componentMessages("buttonGroup", BUTTON_GROUP_DEFAULT_MESSAGES);
94
+ this.effectiveAriaLabel = computed(() => this.ariaLabel() ?? this.messages().buttonGroup, /* @ts-ignore */
95
+ ...(ngDevMode ? [{ debugName: "effectiveAriaLabel" }] : /* istanbul ignore next */ []));
86
96
  /**
87
97
  * @description When `false` and `selection` is `"single"`, at least one button must remain selected;
88
98
  * the active button cannot be deselected. Has no effect in `"multiple"` mode.
@@ -93,9 +103,8 @@ class ButtonGroupComponent {
93
103
  /**
94
104
  * @description Accessible name for the host element. Override when multiple button groups appear on the same page
95
105
  * so screen reader users can distinguish them.
96
- * @default "Button group"
97
106
  */
98
- this.ariaLabel = input("Button group", { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: "aria-label" });
107
+ this.ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: "aria-label" });
99
108
  /**
100
109
  * @description Emitted when any child button in the group is clicked.
101
110
  * Use `[(selected)]` on child buttons to observe the resulting selection state.
@@ -191,12 +200,12 @@ class ButtonGroupComponent {
191
200
  });
192
201
  }
193
202
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ButtonGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
194
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.6", type: ButtonGroupComponent, isStandalone: true, selector: "mona-button-group", inputs: { allowEmpty: { classPropertyName: "allowEmpty", publicName: "allowEmpty", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { buttonClick: "buttonClick", disabled: "disabledChange", selection: "selectionChange" }, host: { attributes: { "role": "group" }, properties: { "attr.aria-label": "ariaLabel()", "class": "baseClass()" } }, providers: [ButtonService], queries: [{ propertyName: "buttons", predicate: ButtonDirective, isSignal: true }], ngImport: i0, template: "<ng-content select=\"[monaButton]\"></ng-content>\n" }); }
203
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.0.6", type: ButtonGroupComponent, isStandalone: true, selector: "mona-button-group", inputs: { allowEmpty: { classPropertyName: "allowEmpty", publicName: "allowEmpty", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, look: { classPropertyName: "look", publicName: "look", isSignal: true, isRequired: false, transformFunction: null }, rounded: { classPropertyName: "rounded", publicName: "rounded", isSignal: true, isRequired: false, transformFunction: null }, selection: { classPropertyName: "selection", publicName: "selection", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, userClass: { classPropertyName: "userClass", publicName: "class", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { buttonClick: "buttonClick", disabled: "disabledChange", selection: "selectionChange" }, host: { attributes: { "role": "group" }, properties: { "attr.aria-label": "effectiveAriaLabel()", "class": "baseClass()" } }, providers: [ButtonService], queries: [{ propertyName: "buttons", predicate: ButtonDirective, isSignal: true }], ngImport: i0, template: "<ng-content select=\"[monaButton]\"></ng-content>\n" }); }
195
204
  }
196
205
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: ButtonGroupComponent, decorators: [{
197
206
  type: Component,
198
207
  args: [{ selector: "mona-button-group", providers: [ButtonService], host: {
199
- "[attr.aria-label]": "ariaLabel()",
208
+ "[attr.aria-label]": "effectiveAriaLabel()",
200
209
  "[class]": "baseClass()",
201
210
  role: "group"
202
211
  }, template: "<ng-content select=\"[monaButton]\"></ng-content>\n" }]
@@ -210,5 +219,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
210
219
  * Generated bundle index. Do not edit.
211
220
  */
212
221
 
213
- export { ButtonGroupComponent };
222
+ export { BUTTON_GROUP_DEFAULT_MESSAGES, ButtonGroupComponent };
214
223
  //# sourceMappingURL=nanahoshi-mona-ui-button-group.mjs.map