@ngbase/adk 0.1.17 → 0.1.19

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 (205) hide show
  1. package/fesm2022/ngbase-adk-a11y.mjs +42 -42
  2. package/fesm2022/ngbase-adk-a11y.mjs.map +1 -1
  3. package/fesm2022/ngbase-adk-accordion.mjs +20 -26
  4. package/fesm2022/ngbase-adk-accordion.mjs.map +1 -1
  5. package/fesm2022/ngbase-adk-autocomplete.mjs +11 -11
  6. package/fesm2022/ngbase-adk-autocomplete.mjs.map +1 -1
  7. package/fesm2022/ngbase-adk-avatar.mjs +13 -13
  8. package/fesm2022/ngbase-adk-avatar.mjs.map +1 -1
  9. package/fesm2022/ngbase-adk-bidi.mjs +3 -3
  10. package/fesm2022/ngbase-adk-bidi.mjs.map +1 -1
  11. package/fesm2022/ngbase-adk-breadcrumb.mjs +14 -14
  12. package/fesm2022/ngbase-adk-breadcrumb.mjs.map +1 -1
  13. package/fesm2022/ngbase-adk-cache.mjs +3 -3
  14. package/fesm2022/ngbase-adk-cache.mjs.map +1 -1
  15. package/fesm2022/ngbase-adk-carousel.mjs +18 -18
  16. package/fesm2022/ngbase-adk-carousel.mjs.map +1 -1
  17. package/fesm2022/ngbase-adk-checkbox.mjs +15 -21
  18. package/fesm2022/ngbase-adk-checkbox.mjs.map +1 -1
  19. package/fesm2022/ngbase-adk-chip.mjs +12 -12
  20. package/fesm2022/ngbase-adk-chip.mjs.map +1 -1
  21. package/fesm2022/ngbase-adk-clipboard.mjs +7 -5
  22. package/fesm2022/ngbase-adk-clipboard.mjs.map +1 -1
  23. package/fesm2022/ngbase-adk-collections.mjs.map +1 -1
  24. package/fesm2022/ngbase-adk-color-picker.mjs +44 -53
  25. package/fesm2022/ngbase-adk-color-picker.mjs.map +1 -1
  26. package/fesm2022/ngbase-adk-cookies.mjs +3 -3
  27. package/fesm2022/ngbase-adk-cookies.mjs.map +1 -1
  28. package/fesm2022/ngbase-adk-datepicker.mjs +70 -89
  29. package/fesm2022/ngbase-adk-datepicker.mjs.map +1 -1
  30. package/fesm2022/ngbase-adk-dialog.mjs +17 -39
  31. package/fesm2022/ngbase-adk-dialog.mjs.map +1 -1
  32. package/fesm2022/ngbase-adk-drag.mjs +20 -20
  33. package/fesm2022/ngbase-adk-drag.mjs.map +1 -1
  34. package/fesm2022/ngbase-adk-form-field.mjs +65 -118
  35. package/fesm2022/ngbase-adk-form-field.mjs.map +1 -1
  36. package/fesm2022/ngbase-adk-hover-card.mjs +5 -5
  37. package/fesm2022/ngbase-adk-hover-card.mjs.map +1 -1
  38. package/fesm2022/ngbase-adk-icon.mjs +9 -11
  39. package/fesm2022/ngbase-adk-icon.mjs.map +1 -1
  40. package/fesm2022/ngbase-adk-inline-edit.mjs +27 -35
  41. package/fesm2022/ngbase-adk-inline-edit.mjs.map +1 -1
  42. package/fesm2022/ngbase-adk-jwt.mjs +6 -6
  43. package/fesm2022/ngbase-adk-jwt.mjs.map +1 -1
  44. package/fesm2022/ngbase-adk-keys.mjs +6 -6
  45. package/fesm2022/ngbase-adk-keys.mjs.map +1 -1
  46. package/fesm2022/ngbase-adk-layout.mjs.map +1 -1
  47. package/fesm2022/ngbase-adk-list.mjs +10 -10
  48. package/fesm2022/ngbase-adk-list.mjs.map +1 -1
  49. package/fesm2022/ngbase-adk-mask.mjs +8 -8
  50. package/fesm2022/ngbase-adk-mask.mjs.map +1 -1
  51. package/fesm2022/ngbase-adk-menu.mjs +69 -79
  52. package/fesm2022/ngbase-adk-menu.mjs.map +1 -1
  53. package/fesm2022/ngbase-adk-network.mjs +3 -3
  54. package/fesm2022/ngbase-adk-network.mjs.map +1 -1
  55. package/fesm2022/ngbase-adk-otp.mjs +24 -45
  56. package/fesm2022/ngbase-adk-otp.mjs.map +1 -1
  57. package/fesm2022/ngbase-adk-pagination.mjs +9 -9
  58. package/fesm2022/ngbase-adk-pagination.mjs.map +1 -1
  59. package/fesm2022/ngbase-adk-popover.mjs +120 -89
  60. package/fesm2022/ngbase-adk-popover.mjs.map +1 -1
  61. package/fesm2022/ngbase-adk-portal.mjs +139 -47
  62. package/fesm2022/ngbase-adk-portal.mjs.map +1 -1
  63. package/fesm2022/ngbase-adk-progress.mjs +7 -7
  64. package/fesm2022/ngbase-adk-progress.mjs.map +1 -1
  65. package/fesm2022/ngbase-adk-radio.mjs +20 -27
  66. package/fesm2022/ngbase-adk-radio.mjs.map +1 -1
  67. package/fesm2022/ngbase-adk-resizable.mjs +138 -48
  68. package/fesm2022/ngbase-adk-resizable.mjs.map +1 -1
  69. package/fesm2022/ngbase-adk-scroll-area.mjs +28 -20
  70. package/fesm2022/ngbase-adk-scroll-area.mjs.map +1 -1
  71. package/fesm2022/ngbase-adk-select.mjs +58 -80
  72. package/fesm2022/ngbase-adk-select.mjs.map +1 -1
  73. package/fesm2022/ngbase-adk-selectable.mjs +19 -30
  74. package/fesm2022/ngbase-adk-selectable.mjs.map +1 -1
  75. package/fesm2022/ngbase-adk-sheet.mjs +6 -20
  76. package/fesm2022/ngbase-adk-sheet.mjs.map +1 -1
  77. package/fesm2022/ngbase-adk-sidenav.mjs +65 -48
  78. package/fesm2022/ngbase-adk-sidenav.mjs.map +1 -1
  79. package/fesm2022/ngbase-adk-slider.mjs +40 -53
  80. package/fesm2022/ngbase-adk-slider.mjs.map +1 -1
  81. package/fesm2022/ngbase-adk-sonner.mjs +12 -19
  82. package/fesm2022/ngbase-adk-sonner.mjs.map +1 -1
  83. package/fesm2022/ngbase-adk-stepper.mjs +17 -25
  84. package/fesm2022/ngbase-adk-stepper.mjs.map +1 -1
  85. package/fesm2022/ngbase-adk-switch.mjs +25 -32
  86. package/fesm2022/ngbase-adk-switch.mjs.map +1 -1
  87. package/fesm2022/ngbase-adk-table.mjs +581 -83
  88. package/fesm2022/ngbase-adk-table.mjs.map +1 -1
  89. package/fesm2022/ngbase-adk-tabs.mjs +37 -35
  90. package/fesm2022/ngbase-adk-tabs.mjs.map +1 -1
  91. package/fesm2022/ngbase-adk-test.mjs.map +1 -1
  92. package/fesm2022/ngbase-adk-toggle-group.mjs +20 -34
  93. package/fesm2022/ngbase-adk-toggle-group.mjs.map +1 -1
  94. package/fesm2022/ngbase-adk-toggle.mjs +14 -19
  95. package/fesm2022/ngbase-adk-toggle.mjs.map +1 -1
  96. package/fesm2022/ngbase-adk-tooltip.mjs +12 -19
  97. package/fesm2022/ngbase-adk-tooltip.mjs.map +1 -1
  98. package/fesm2022/ngbase-adk-tour.mjs +47 -52
  99. package/fesm2022/ngbase-adk-tour.mjs.map +1 -1
  100. package/fesm2022/ngbase-adk-translate.mjs +8 -10
  101. package/fesm2022/ngbase-adk-translate.mjs.map +1 -1
  102. package/fesm2022/ngbase-adk-tree.mjs +20 -20
  103. package/fesm2022/ngbase-adk-tree.mjs.map +1 -1
  104. package/fesm2022/ngbase-adk-utils.mjs +30 -43
  105. package/fesm2022/ngbase-adk-utils.mjs.map +1 -1
  106. package/fesm2022/ngbase-adk-virtualizer.mjs +9 -9
  107. package/fesm2022/ngbase-adk-virtualizer.mjs.map +1 -1
  108. package/package.json +101 -101
  109. package/schematics/components/files/accordion/accordion.ts.template +10 -5
  110. package/schematics/components/files/audio/AudioPlayer.ts.template +245 -0
  111. package/schematics/components/files/audio/AudioRecorder.ts.template +377 -0
  112. package/schematics/components/files/audio/AudioVisualizer.ts.template +175 -0
  113. package/schematics/components/files/audio/index.ts.template +3 -0
  114. package/schematics/components/files/badge/badge-llm.md.template +2 -2
  115. package/schematics/components/files/badge/badge.ts.template +29 -9
  116. package/schematics/components/files/card/card.ts.template +1 -1
  117. package/schematics/components/files/charts/area-chart.component.ts.template +278 -0
  118. package/schematics/components/files/charts/bar-chart.component.ts.template +262 -0
  119. package/schematics/components/files/charts/chart-tooltip.component.ts.template +168 -0
  120. package/schematics/components/files/charts/index.ts.template +4 -0
  121. package/schematics/components/files/charts/line-chart.component.ts.template +238 -0
  122. package/schematics/components/files/charts/pie-chart.component.ts.template +283 -0
  123. package/schematics/components/files/checkbox/checkbox.ts.template +4 -7
  124. package/schematics/components/files/color-picker/color-picker.ts.template +2 -2
  125. package/schematics/components/files/dialog/dialog.ts.template +11 -14
  126. package/schematics/components/files/drawer/drawer.ts.template +25 -28
  127. package/schematics/components/files/form-field/form-field.ts.template +59 -23
  128. package/schematics/components/files/inline-edit/inline-edit.ts.template +3 -1
  129. package/schematics/components/files/pagination/pagination.ts.template +6 -6
  130. package/schematics/components/files/picasa/picasa-base.component.ts.template +9 -30
  131. package/schematics/components/files/popover/popover.ts.template +9 -4
  132. package/schematics/components/files/select/list-selection.ts.template +0 -2
  133. package/schematics/components/files/select/option.ts.template +1 -1
  134. package/schematics/components/files/selectable/selectable.ts.template +2 -2
  135. package/schematics/components/files/sheet/sheet.ts.template +20 -14
  136. package/schematics/components/files/sidenav/sidenav.ts.template +69 -6
  137. package/schematics/components/files/sonner/sonner.ts.template +1 -2
  138. package/schematics/components/files/stepper/stepper-llm.md.template +7 -0
  139. package/schematics/components/files/stepper/stepper.ts.template +2 -4
  140. package/schematics/components/files/switch/switch.ts.template +2 -2
  141. package/schematics/components/files/table/table-llm.md.template +14 -2
  142. package/schematics/components/files/table/table.ts.template +42 -3
  143. package/schematics/components/files/theme/theme.service.ts.template +3 -3
  144. package/schematics/components/files/toggle/toggle.ts.template +1 -1
  145. package/schematics/components/files/toggle-group/toggle-group.ts.template +1 -1
  146. package/schematics/components/files/tooltip/tooltip.ts.template +2 -3
  147. package/{accordion/index.d.ts → types/ngbase-adk-accordion.d.ts} +1 -3
  148. package/{autocomplete/index.d.ts → types/ngbase-adk-autocomplete.d.ts} +2 -7
  149. package/{checkbox/index.d.ts → types/ngbase-adk-checkbox.d.ts} +8 -14
  150. package/types/ngbase-adk-clipboard.d.ts +12 -0
  151. package/{color-picker/index.d.ts → types/ngbase-adk-color-picker.d.ts} +14 -26
  152. package/{datepicker/index.d.ts → types/ngbase-adk-datepicker.d.ts} +9 -18
  153. package/{dialog/index.d.ts → types/ngbase-adk-dialog.d.ts} +3 -8
  154. package/types/ngbase-adk-form-field.d.ts +88 -0
  155. package/{inline-edit/index.d.ts → types/ngbase-adk-inline-edit.d.ts} +8 -16
  156. package/{menu/index.d.ts → types/ngbase-adk-menu.d.ts} +6 -5
  157. package/{otp/index.d.ts → types/ngbase-adk-otp.d.ts} +8 -16
  158. package/{popover/index.d.ts → types/ngbase-adk-popover.d.ts} +14 -2
  159. package/{portal/index.d.ts → types/ngbase-adk-portal.d.ts} +30 -8
  160. package/{radio/index.d.ts → types/ngbase-adk-radio.d.ts} +9 -12
  161. package/{resizable/index.d.ts → types/ngbase-adk-resizable.d.ts} +4 -4
  162. package/{scroll-area/index.d.ts → types/ngbase-adk-scroll-area.d.ts} +2 -1
  163. package/{select/index.d.ts → types/ngbase-adk-select.d.ts} +8 -22
  164. package/{selectable/index.d.ts → types/ngbase-adk-selectable.d.ts} +6 -10
  165. package/{sheet/index.d.ts → types/ngbase-adk-sheet.d.ts} +4 -3
  166. package/{sidenav/index.d.ts → types/ngbase-adk-sidenav.d.ts} +7 -8
  167. package/{slider/index.d.ts → types/ngbase-adk-slider.d.ts} +8 -17
  168. package/{sonner/index.d.ts → types/ngbase-adk-sonner.d.ts} +1 -3
  169. package/{stepper/index.d.ts → types/ngbase-adk-stepper.d.ts} +1 -4
  170. package/{switch/index.d.ts → types/ngbase-adk-switch.d.ts} +7 -14
  171. package/{table/index.d.ts → types/ngbase-adk-table.d.ts} +126 -3
  172. package/{test/index.d.ts → types/ngbase-adk-test.d.ts} +1 -1
  173. package/{toggle-group/index.d.ts → types/ngbase-adk-toggle-group.d.ts} +5 -10
  174. package/types/ngbase-adk-toggle.d.ts +14 -0
  175. package/{tooltip/index.d.ts → types/ngbase-adk-tooltip.d.ts} +9 -11
  176. package/{tour/index.d.ts → types/ngbase-adk-tour.d.ts} +3 -6
  177. package/{utils/index.d.ts → types/ngbase-adk-utils.d.ts} +15 -11
  178. package/clipboard/index.d.ts +0 -11
  179. package/form-field/index.d.ts +0 -97
  180. package/toggle/index.d.ts +0 -16
  181. /package/{a11y/index.d.ts → types/ngbase-adk-a11y.d.ts} +0 -0
  182. /package/{avatar/index.d.ts → types/ngbase-adk-avatar.d.ts} +0 -0
  183. /package/{bidi/index.d.ts → types/ngbase-adk-bidi.d.ts} +0 -0
  184. /package/{breadcrumb/index.d.ts → types/ngbase-adk-breadcrumb.d.ts} +0 -0
  185. /package/{cache/index.d.ts → types/ngbase-adk-cache.d.ts} +0 -0
  186. /package/{carousel/index.d.ts → types/ngbase-adk-carousel.d.ts} +0 -0
  187. /package/{chip/index.d.ts → types/ngbase-adk-chip.d.ts} +0 -0
  188. /package/{collections/index.d.ts → types/ngbase-adk-collections.d.ts} +0 -0
  189. /package/{cookies/index.d.ts → types/ngbase-adk-cookies.d.ts} +0 -0
  190. /package/{drag/index.d.ts → types/ngbase-adk-drag.d.ts} +0 -0
  191. /package/{hover-card/index.d.ts → types/ngbase-adk-hover-card.d.ts} +0 -0
  192. /package/{icon/index.d.ts → types/ngbase-adk-icon.d.ts} +0 -0
  193. /package/{jwt/index.d.ts → types/ngbase-adk-jwt.d.ts} +0 -0
  194. /package/{keys/index.d.ts → types/ngbase-adk-keys.d.ts} +0 -0
  195. /package/{layout/index.d.ts → types/ngbase-adk-layout.d.ts} +0 -0
  196. /package/{list/index.d.ts → types/ngbase-adk-list.d.ts} +0 -0
  197. /package/{mask/index.d.ts → types/ngbase-adk-mask.d.ts} +0 -0
  198. /package/{network/index.d.ts → types/ngbase-adk-network.d.ts} +0 -0
  199. /package/{pagination/index.d.ts → types/ngbase-adk-pagination.d.ts} +0 -0
  200. /package/{progress/index.d.ts → types/ngbase-adk-progress.d.ts} +0 -0
  201. /package/{tabs/index.d.ts → types/ngbase-adk-tabs.d.ts} +0 -0
  202. /package/{translate/index.d.ts → types/ngbase-adk-translate.d.ts} +0 -0
  203. /package/{tree/index.d.ts → types/ngbase-adk-tree.d.ts} +0 -0
  204. /package/{virtualizer/index.d.ts → types/ngbase-adk-virtualizer.d.ts} +0 -0
  205. /package/{index.d.ts → types/ngbase-adk.d.ts} +0 -0
@@ -1,24 +1,25 @@
1
- import { animate, state, style, transition, trigger } from '@angular/animations';
2
1
  import {
3
2
  ChangeDetectionStrategy,
4
3
  Component,
5
4
  ViewContainerRef,
6
- afterNextRender,
5
+ computed,
7
6
  viewChild,
8
7
  } from '@angular/core';
9
8
  import { FocusTrap } from '@ngbase/adk/a11y';
10
9
  import { BaseDialog, basePortal, DialogInput, DialogOptions } from '@ngbase/adk/portal';
11
- import { createHostAnimation, fadeAnimation } from '@ngbase/adk/utils';
12
10
 
13
11
  @Component({
14
12
  selector: '<%= name %>-drawer',
15
13
  template: `
16
14
  <div class="pointer-events-none flex h-full flex-col justify-end">
17
15
  <div
18
- class="pointer-events-auto flex max-h-[90vh] flex-col overflow-hidden rounded-tl-2xl rounded-tr-2xl border-t bg-background p-4 shadow-2xl"
19
- [@bottomAnimation]
16
+ class="{{
17
+ 'bg-background pointer-events-auto flex max-h-[90vh] flex-col overflow-hidden rounded-tl-2xl rounded-tr-2xl border-t p-4 shadow-2xl' +
18
+ (closing() ? ' drawer-content-leave' : ' drawer-content')
19
+ }}"
20
+ (animationend)="onAnimationEnd($event)"
20
21
  >
21
- <button class="mx-auto h-2 w-20 rounded-full bg-muted-foreground"></button>
22
+ <button class="bg-muted-foreground mx-auto h-2 w-20 rounded-full"></button>
22
23
  @if (!isHideHeader) {
23
24
  <div class="flex h-8 items-center">
24
25
  <h2 class="flex-1 font-bold">{{ options.title }}</h2>
@@ -26,49 +27,45 @@ import { createHostAnimation, fadeAnimation } from '@ngbase/adk/utils';
26
27
  </div>
27
28
  }
28
29
  <div class="h-full overflow-auto">
29
- <ng-container #myDialog />
30
+ <ng-container #contentContainer />
30
31
  </div>
31
32
  </div>
32
33
  </div>
33
34
  @if (backdropColor) {
34
35
  <div
35
- class="absolute top-0 -z-10 h-full w-full bg-black/30"
36
- [@fadeAnimation]
37
36
  (click)="close()"
37
+ (animationend)="onAnimationEnd($event)"
38
+ class="{{
39
+ 'absolute top-0 -z-10 h-full w-full bg-black/30' +
40
+ (closing() ? ' dialog-backdrop-leave' : ' dialog-backdrop')
41
+ }}"
38
42
  ></div>
39
43
  }
40
44
  `,
41
45
  host: {
42
46
  class: 'fixed block top-0 bottom-0 left-0 right-0 overflow-hidden z-p',
43
- '[@parentAnimation]': '',
44
- '(@parentAnimation.done)': 'animationDone()',
45
47
  },
46
48
  hostDirectives: [FocusTrap],
47
49
  changeDetection: ChangeDetectionStrategy.OnPush,
48
- animations: [
49
- createHostAnimation(['@bottomAnimation', '@fadeAnimation']),
50
- trigger('bottomAnimation', [
51
- state('1', style({ transform: 'none' })),
52
- state('void', style({ transform: 'translate3d(0, 100%, 0)' })),
53
- state('0', style({ transform: 'translate3d(0, 100%, 0)' })),
54
- transition('* => *', animate('200ms ease')),
55
- ]),
56
- fadeAnimation('200ms'),
57
- ],
58
50
  })
59
51
  export class DrawerContainer extends BaseDialog {
60
- myDialog = viewChild('myDialog', { read: ViewContainerRef });
52
+ protected override readonly hasAnimations = true;
53
+ readonly contentContainer = viewChild('contentContainer', { read: ViewContainerRef });
61
54
  backdropColor = true;
62
55
  options!: DialogOptions;
63
56
  classNames = '';
64
57
  isHideHeader = false;
65
58
 
66
- constructor() {
67
- super();
68
- afterNextRender(() => {
69
- this._afterViewSource.next(this.myDialog()!);
70
- });
71
- }
59
+ readonly style = computed(() => {
60
+ return {
61
+ width: this.options.fullWindow ? '100vw' : this.options.width,
62
+ height: this.options.fullWindow ? '100vh' : this.options.height,
63
+ maxWidth: this.options.fullWindow ? '100vw' : this.options.maxWidth,
64
+ maxHeight: this.options.fullWindow ? '100vh' : this.options.maxHeight || '96vh',
65
+ minHeight: this.options.minHeight,
66
+ minWidth: this.options.minWidth,
67
+ };
68
+ });
72
69
 
73
70
  override setOptions(options: DialogOptions): void {
74
71
  this.options = options;
@@ -1,11 +1,11 @@
1
1
  import {
2
2
  ChangeDetectionStrategy,
3
3
  Component,
4
+ computed,
4
5
  Directive,
5
6
  effect,
6
7
  ElementRef,
7
8
  inject,
8
- OnDestroy,
9
9
  viewChild,
10
10
  } from '@angular/core';
11
11
  import {
@@ -13,7 +13,7 @@ import {
13
13
  NgbFormField,
14
14
  NgbInputError,
15
15
  NgbLabel,
16
- toggleDiv,
16
+ NumberFormat,
17
17
  } from '@ngbase/adk/form-field';
18
18
  import { InputStyle } from './input-style.directive';
19
19
  import { NgbSelectTarget } from '@ngbase/adk/select';
@@ -26,20 +26,44 @@ import { NgbSelectTarget } from '@ngbase/adk/select';
26
26
  template: `
27
27
  <ng-content select="[<%= name %>Label]" />
28
28
  <ng-content select="[<%= name %>Description]" />
29
- <div class="flex items-center" #target <%= name %>InputStyle>
29
+ <div
30
+ class="has-[[disabled]]:bg-input/30 flex items-center"
31
+ #target
32
+ <%= name %>InputStyle
33
+ [class]="
34
+ ngbFormField.hasErrors()
35
+ ? 'border-red-500 focus-within:border-red-500 focus-within:ring-red-500/30'
36
+ : ''
37
+ "
38
+ >
30
39
  <ng-content select="[<%= name %>Prefix]" />
31
40
  <ng-content />
32
41
  <ng-content select="[<%= name %>Suffix]" />
33
42
  </div>
34
- <ng-content select="[<%= name %>Error]" />
43
+ @for (error of errors(); track error.kind) {
44
+ <div class="overflow-hidden" animate.enter="height-enter" animate.leave="height-leave">
45
+ <div class="mx-0.5 min-h-0 text-sm text-red-500">
46
+ {{ error.message }}
47
+ </div>
48
+ </div>
49
+ }
35
50
  `,
36
51
  host: {
37
52
  class: 'inline-flex flex-col font-medium gap-1',
38
53
  },
39
54
  })
40
- export class FormField {
55
+ export class MeeFormField {
56
+ readonly ngbFormField = inject(NgbFormField);
41
57
  readonly selectTarget = inject(NgbSelectTarget);
42
58
  readonly target = viewChild.required<ElementRef<HTMLDivElement>>('target');
59
+ readonly errors = computed(() => {
60
+ const control = this.ngbFormField._control();
61
+ const state = control?.state();
62
+ if (state?.touched() && state?.errors()?.length) {
63
+ return state.errors();
64
+ }
65
+ return [];
66
+ });
43
67
  private _ = effect(() => {
44
68
  this.selectTarget.target.set(this.target().nativeElement);
45
69
  });
@@ -57,6 +81,16 @@ export class MeeInput {
57
81
  readonly formField = inject(NgbFormField, { optional: true });
58
82
  }
59
83
 
84
+ @Directive({
85
+ selector: '[<%= name %>NumberInput]',
86
+ // hostDirectives: [{ directive: InputBase, inputs: ['value'], outputs: ['valueChange'] }],
87
+ host: {
88
+ class: 'outline-none w-full bg-transparent placeholder:text-gray-400',
89
+ '[class.border-red-500]': 'formField?.hasErrors()',
90
+ },
91
+ })
92
+ export class MeeNumberInput extends NumberFormat {}
93
+
60
94
  @Component({
61
95
  selector: '[<%= name %>Label]',
62
96
  changeDetection: ChangeDetectionStrategy.OnPush,
@@ -76,10 +110,18 @@ export class Label {}
76
110
  })
77
111
  export class Description {}
78
112
 
113
+ @Directive({
114
+ selector: '[<%= name %>Hint]',
115
+ host: {
116
+ class: 'text-xs text-muted-foreground mt-1',
117
+ },
118
+ })
119
+ export class Hint {}
120
+
79
121
  @Directive({
80
122
  selector: '[<%= name %>Prefix]',
81
123
  host: {
82
- class: 'mr-2.5 text-muted-foreground',
124
+ class: 'mr-2.5 text-muted-foreground flex items-center',
83
125
  },
84
126
  })
85
127
  export class InputPrefix {}
@@ -87,7 +129,7 @@ export class InputPrefix {}
87
129
  @Directive({
88
130
  selector: '[<%= name %>Suffix]',
89
131
  host: {
90
- class: 'ml-2.5 text-muted-foreground',
132
+ class: 'ml-2.5 text-muted-foreground flex items-center',
91
133
  },
92
134
  })
93
135
  export class InputSuffix {}
@@ -95,26 +137,20 @@ export class InputSuffix {}
95
137
  @Component({
96
138
  selector: '[<%= name %>Error]',
97
139
  hostDirectives: [{ directive: NgbInputError, inputs: ['ngbError: <%= name %>Error'] }],
98
- template: `<ng-content />`,
140
+ template: `
141
+ @if (isInvalid()) {
142
+ <div class="overflow-hidden" animate.enter="height-enter" animate.leave="height-leave">
143
+ <div class="min-h-0">
144
+ <ng-content />
145
+ </div>
146
+ </div>
147
+ }
148
+ `,
99
149
  host: {
100
150
  class: 'text-red-500 mx-0.5',
101
- '[@toggleDiv]': 'isInvalid() ? "visible" : "hidden"',
102
151
  },
103
- animations: [toggleDiv],
104
152
  })
105
- export class InputError implements OnDestroy {
153
+ export class InputError {
106
154
  readonly error = inject(NgbInputError);
107
- readonly el = inject<ElementRef<HTMLDivElement>>(ElementRef);
108
-
109
155
  readonly isInvalid = this.error.isInvalid;
110
-
111
- constructor() {
112
- this.error.animate.set(true);
113
- }
114
-
115
- ngOnDestroy() {
116
- if (!this.isInvalid()) {
117
- this.el.nativeElement.classList.add('h-0', 'opacity-0');
118
- }
119
- }
120
156
  }
@@ -1,4 +1,4 @@
1
- import { Component } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component } from '@angular/core';
2
2
  import {
3
3
  NgbInlineEdit,
4
4
  NgbInlineInput,
@@ -8,6 +8,8 @@ import {
8
8
 
9
9
  @Component({
10
10
  selector: '<%= name %>-inline-edit',
11
+ exportAs: '<%= name %>InlineEdit',
12
+ changeDetection: ChangeDetectionStrategy.OnPush,
11
13
  providers: [aliasInlineEdit(InlineEdit)],
12
14
  imports: [NgbInlineInput, NgbInlineValue],
13
15
  template: `
@@ -10,7 +10,7 @@ import {
10
10
  lucideChevronsLeft,
11
11
  lucideChevronsRight,
12
12
  } from '@ng-icons/lucide';
13
- import { FormField } from '<%= basepath %>/form-field';
13
+ import { MeeFormField } from '<%= basepath %>/form-field';
14
14
 
15
15
  @Component({
16
16
  selector: '<%= name %>-pagination',
@@ -23,12 +23,12 @@ import { FormField } from '<%= basepath %>/form-field';
23
23
  lucideChevronsRight,
24
24
  }),
25
25
  ],
26
- imports: [Button, Icon, Select, Option, NgbPaginationBtn, FormField],
26
+ imports: [Button, Icon, Select, Option, NgbPaginationBtn, MeeFormField],
27
27
  template: `
28
- <div class="flex items-center gap-2">
29
- <div>Rows per page</div>
28
+ <div class="flex flex-1 items-center gap-2">
29
+ <div class="hidden md:block">Rows per page</div>
30
30
  <<%= name %>-form-field class="!w-auto [&>.mis]:min-h-8 [&>.mis]:py-0">
31
- <<%= name %>-select [value]="size()" (valueChange)="sizeChanged($event)">
31
+ <<%= name %>-select [value]="size()" (valueChange)="sizeChanged($any($event))">
32
32
  @for (size of sizeOptions(); track size) {
33
33
  <<%= name %>-option [value]="size">
34
34
  {{ size }}
@@ -51,7 +51,7 @@ import { FormField } from '<%= basepath %>/form-field';
51
51
  ngbPaginationBtn="page"
52
52
  [jump]="snap"
53
53
  <%= name %>Button="ghost"
54
- class="min-w-9 !p-2 ring-offset-foreground aria-[current=page]:bg-muted aria-[current=page]:text-primary"
54
+ class="ring-offset-foreground aria-[current=page]:bg-muted aria-[current=page]:text-primary min-w-9 !p-2"
55
55
  >
56
56
  {{ snap }}
57
57
  </button>
@@ -1,12 +1,5 @@
1
- import {
2
- afterNextRender,
3
- ChangeDetectionStrategy,
4
- Component,
5
- viewChild,
6
- ViewContainerRef,
7
- } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, viewChild, ViewContainerRef } from '@angular/core';
8
2
  import { BaseDialog, DialogOptions } from '@ngbase/adk/portal';
9
- import { createHostAnimation, fadeAnimation } from '@ngbase/adk/utils';
10
3
  import { Subject } from 'rxjs';
11
4
 
12
5
  @Component({
@@ -15,18 +8,20 @@ import { Subject } from 'rxjs';
15
8
  template: `
16
9
  <div class="pointer-events-none flex h-full items-center justify-center">
17
10
  <div class="pointer-events-auto">
18
- <ng-container #myDialog />
11
+ <ng-container #contentContainer />
19
12
  </div>
20
13
  <div
21
- class="backdropColor pointer-events-auto absolute top-0 -z-10 h-full w-full"
22
14
  (click)="!options.disableClose && close()"
23
- [@fadeAnimation]=""
15
+ (animationend)="onAnimationEnd($event)"
16
+ class="{{
17
+ 'backdropColor pointer-events-auto absolute top-0 -z-10 h-full w-full' +
18
+ (closing() ? ' dialog-backdrop-leave' : ' dialog-backdrop')
19
+ }}"
24
20
  ></div>
25
21
  </div>
26
22
  `,
27
23
  host: {
28
24
  class: 'fixed block top-0 bottom-0 left-0 right-0 overflow-auto pointer-events-none z-p',
29
- '[@parentAnimation]': '',
30
25
  },
31
26
  styles: `
32
27
  .backdropColor {
@@ -41,10 +36,10 @@ import { Subject } from 'rxjs';
41
36
  border-radius: 0;
42
37
  }
43
38
  `,
44
- animations: [createHostAnimation(['@fadeAnimation']), fadeAnimation('300ms')],
45
39
  })
46
40
  export class PicasaBase extends BaseDialog {
47
- myDialog = viewChild('myDialog', { read: ViewContainerRef });
41
+ protected override readonly hasAnimations = true;
42
+ readonly contentContainer = viewChild('contentContainer', { read: ViewContainerRef });
48
43
 
49
44
  backdropColor = true;
50
45
  isSidePopup = true;
@@ -54,22 +49,6 @@ export class PicasaBase extends BaseDialog {
54
49
  isHideHeader = false;
55
50
  onDone = new Subject<any>();
56
51
 
57
- constructor() {
58
- super();
59
- afterNextRender(() => {
60
- this._afterViewSource.next(this.myDialog()!);
61
-
62
- // setTimeout(() => {
63
- // this.show.set(false);
64
- // }, 2000);
65
- });
66
- // this.dialogRef.afterClosed.subscribe(() => {
67
- // setTimeout(() => {
68
- // this.animationDone();
69
- // }, 500);
70
- // });
71
- }
72
-
73
52
  override setOptions(options: DialogOptions) {
74
53
  this.options = options;
75
54
  this.classNames = this.options.classNames?.join(' ') || '';
@@ -18,11 +18,14 @@ import {
18
18
  imports: [NgbPopoverBackdrop, NgbPopoverMain, NgbPopoverArrow],
19
19
  template: ` <div
20
20
  ngbPopoverMain
21
- [@slideInOutAnimation]
22
- class="menu-container pointer-events-auto fixed z-10 flex flex-col rounded-lg border bg-popover text-popover-foreground shadow-md"
21
+ (animationend)="onAnimationEnd($event)"
22
+ class="{{
23
+ 'menu-container pointer-events-auto fixed z-10 flex flex-col rounded-lg border bg-popover text-popover-foreground shadow-md' +
24
+ (closing() ? ' popover-content-leave' : ' popover-content')
25
+ }}"
23
26
  >
24
27
  <div class="flex flex-1 flex-col overflow-auto" ngbPopoverArrow>
25
- <ng-container #myDialog />
28
+ <ng-container #contentContainer />
26
29
  </div>
27
30
  </div>
28
31
  @if (options().backdrop) {
@@ -33,7 +36,9 @@ import {
33
36
  'fixed top-0 left-0 w-full h-full pointer-events-none z-p flex items-center justify-center',
34
37
  },
35
38
  })
36
- class Popover extends NgbPopover {}
39
+ class Popover extends NgbPopover {
40
+ protected override readonly hasAnimations = true;
41
+ }
37
42
 
38
43
  export function registerPopover() {
39
44
  return registerNgbPopover(Popover);
@@ -1,12 +1,10 @@
1
1
  import { ChangeDetectionStrategy, Component } from '@angular/core';
2
- import { provideValueAccessor } from '@ngbase/adk/utils';
3
2
  import { SelectBase } from '@ngbase/adk/select';
4
3
 
5
4
  @Component({
6
5
  selector: '<%= name %>-list-selection',
7
6
  changeDetection: ChangeDetectionStrategy.OnPush,
8
7
  template: `<ng-content />`,
9
- providers: [provideValueAccessor(ListSelection)],
10
8
  })
11
9
  export class ListSelection<T> extends SelectBase<T> {
12
10
  constructor() {
@@ -24,7 +24,7 @@ export class Option<T> {
24
24
  @Component({
25
25
  selector: '<%= name %>-option-group, [<%= name %>OptionGroup]',
26
26
  changeDetection: ChangeDetectionStrategy.OnPush,
27
- template: `<div class="sticky -top-1 z-10 bg-popover px-2 py-1.5 text-sm text-muted-foreground">
27
+ template: `<div class="bg-popover text-muted-foreground sticky -top-1 z-10 px-2 py-1.5 text-sm">
28
28
  {{ label() }}
29
29
  </div>
30
30
  <ng-content />`,
@@ -23,8 +23,8 @@ export class SelectableItem<T> {
23
23
  hostDirectives: [
24
24
  {
25
25
  directive: NgbSelectable,
26
- inputs: ['activeIndex'],
27
- outputs: ['activeIndexChange', 'valueChanged'],
26
+ inputs: ['value'],
27
+ outputs: ['valueChange'],
28
28
  },
29
29
  ],
30
30
  template: `<ng-content />`,
@@ -4,10 +4,8 @@ import { Button } from '<%= basepath %>/button';
4
4
  import { Icon } from '<%= basepath %>/icon';
5
5
  import { provideIcons } from '@ng-icons/core';
6
6
  import { lucideX } from '@ng-icons/lucide';
7
- import { sideAnimation } from '@ngbase/adk/dialog';
8
7
  import { NgbSheet, NgbSheetContainer, ngbSheetPortal } from '@ngbase/adk/sheet';
9
8
  import { aliasSheet } from '@ngbase/adk/sheet';
10
- import { createHostAnimation, fadeAnimation } from '@ngbase/adk/utils';
11
9
 
12
10
  @Component({
13
11
  selector: '<%= name %>-sheet',
@@ -21,13 +19,22 @@ import { createHostAnimation, fadeAnimation } from '@ngbase/adk/utils';
21
19
  [class]="options.position === 'left' ? 'justify-start' : 'justify-end'"
22
20
  >
23
21
  <div
24
- class="pointer-events-auto m-2 flex flex-col overflow-hidden rounded-lg border-l bg-background shadow-2xl will-change-transform"
25
- [@sideAnimation]="position()"
22
+ class="{{
23
+ 'pointer-events-auto m-2 flex flex-col overflow-hidden rounded-lg border-l bg-background shadow-2xl will-change-transform' +
24
+ (closing()
25
+ ? options.position === 'left'
26
+ ? ' sheet-content-left-leave'
27
+ : ' sheet-content-right-leave'
28
+ : options.position === 'left'
29
+ ? ' sheet-content-left'
30
+ : ' sheet-content-right')
31
+ }}"
26
32
  [ngStyle]="{
27
33
  width: options.width,
28
34
  minWidth: options.minWidth,
29
35
  maxWidth: options.maxWidth,
30
36
  }"
37
+ (animationend)="onAnimationEnd($event)"
31
38
  >
32
39
  @if (!isHideHeader) {
33
40
  <div class="flex items-center border-b px-4 py-2">
@@ -38,29 +45,28 @@ import { createHostAnimation, fadeAnimation } from '@ngbase/adk/utils';
38
45
  </div>
39
46
  }
40
47
  <div class="h-full overflow-auto p-4">
41
- <ng-container #myDialog />
48
+ <ng-container #contentContainer />
42
49
  </div>
43
50
  </div>
44
51
  </div>
45
52
  @if (backdropColor) {
46
53
  <div
47
- class="absolute top-0 -z-10 h-full w-full bg-black/30"
48
- [@fadeAnimation]
49
54
  (click)="close()"
55
+ (animationend)="onAnimationEnd($event)"
56
+ class="{{
57
+ 'absolute top-0 -z-10 h-full w-full bg-black/30' +
58
+ (closing() ? ' dialog-backdrop-leave' : ' dialog-backdrop')
59
+ }}"
50
60
  ></div>
51
- <!-- [class]="status() ? 'pointer-events-auto' : 'pointer-events-none'" -->
52
61
  }
53
62
  `,
54
63
  host: {
55
64
  class: 'fixed block top-0 bottom-0 left-0 right-0 z-p',
56
65
  },
57
- animations: [
58
- createHostAnimation(['@fadeAnimation', '@sideAnimation']),
59
- fadeAnimation('300ms'),
60
- sideAnimation,
61
- ],
62
66
  })
63
- export class SheetContainer extends NgbSheetContainer {}
67
+ export class SheetContainer extends NgbSheetContainer {
68
+ protected override readonly hasAnimations = true;
69
+ }
64
70
 
65
71
  export function sheetPortal() {
66
72
  return ngbSheetPortal(SheetContainer);
@@ -1,4 +1,5 @@
1
- import { ChangeDetectionStrategy, Component } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, linkedSignal, Signal, signal } from '@angular/core';
2
+ import { breakpointObserver } from '@ngbase/adk/layout';
2
3
  import {
3
4
  NgbSidenav,
4
5
  NgbSidenavHeader,
@@ -7,7 +8,6 @@ import {
7
8
  NgbSidenavOverlay,
8
9
  SidenavType,
9
10
  aliasSidenav,
10
- slideAnimation,
11
11
  } from '@ngbase/adk/sidenav';
12
12
 
13
13
  export type { SidenavType };
@@ -19,9 +19,14 @@ export type { SidenavType };
19
19
  imports: [NgbSidenavOverlay, NgbSidenavHeaderTrack],
20
20
  template: `
21
21
  @if (showOverlay()) {
22
- <div ngbSidenavOverlay class="z-p bg-black/70"></div>
22
+ <div
23
+ ngbSidenavOverlay
24
+ class="z-p bg-black/70"
25
+ animate.enter="dialog-backdrop"
26
+ animate.leave="dialog-backdrop-leave"
27
+ ></div>
23
28
  }
24
- <div ngbSidenavHeaderTrack class="transition-[width] duration-500"></div>
29
+ <div ngbSidenavHeaderTrack class="sidenav-track"></div>
25
30
  <ng-content select="<%= name %>-sidenav-header" />
26
31
  <ng-content />
27
32
  `,
@@ -41,8 +46,66 @@ export class Sidenav extends NgbSidenav {}
41
46
  </div>
42
47
  `,
43
48
  host: {
44
- class: 'block h-full bg-background z-p transition-[width] duration-500',
49
+ class: 'block h-full bg-background z-p sidenav-header',
45
50
  },
46
- animations: [slideAnimation('500ms cubic-bezier(0.4, 0, 0.2, 1)')],
47
51
  })
48
52
  export class SidenavHeader extends NgbSidenavHeader {}
53
+
54
+ /**
55
+ * A record mapping breakpoint names to their media query and the SidenavType to use when matched.
56
+ * Breakpoints are evaluated in order; the first match wins.
57
+ *
58
+ * @example
59
+ * { md: { query: '(max-width: 768px)', mode: 'over' }, lg: { query: '(max-width: 1200px)', mode: 'push' } }
60
+ */
61
+ export type SidenavBreakpoints = Record<string, { query: string; mode: SidenavType }>;
62
+
63
+ const DEFAULT_BREAKPOINTS: SidenavBreakpoints = {
64
+ md: { query: '(max-width: 768px)', mode: 'over' },
65
+ };
66
+
67
+ export function sidenavResponsive(
68
+ sidenav: Signal<Sidenav>,
69
+ breakpointConfig: SidenavBreakpoints = DEFAULT_BREAKPOINTS,
70
+ defaultMode: SidenavType = 'side',
71
+ ) {
72
+ const breakpoints = breakpointObserver();
73
+
74
+ // Build the queries record: { md: '(max-width: 768px)', lg: '(max-width: 1200px)' }
75
+ const queries = Object.fromEntries(
76
+ Object.entries(breakpointConfig).map(([key, { query }]) => [key, query]),
77
+ ) as Record<string, string>;
78
+
79
+ const bp = breakpoints.observe(queries);
80
+
81
+ const mode = linkedSignal({
82
+ source: bp.state,
83
+ computation: state => {
84
+ // Return the mode of the first matching breakpoint
85
+ for (const key of Object.keys(breakpointConfig)) {
86
+ if (state[key]) {
87
+ return breakpointConfig[key].mode;
88
+ }
89
+ }
90
+ return defaultMode;
91
+ },
92
+ });
93
+
94
+ // Initially hidden if any breakpoint matches
95
+ const initialMatch = Object.values(breakpointConfig).some(({ query }) =>
96
+ breakpoints.matches(query),
97
+ );
98
+ const show = signal(!initialMatch);
99
+
100
+ function toggle() {
101
+ sidenav().toggle();
102
+ }
103
+
104
+ function toggleMode() {
105
+ mode.update(current =>
106
+ current === defaultMode ? Object.values(breakpointConfig)[0].mode : defaultMode,
107
+ );
108
+ }
109
+
110
+ return { show, mode, toggle, toggleMode };
111
+ }
@@ -1,5 +1,5 @@
1
1
  import { ChangeDetectionStrategy, Component } from '@angular/core';
2
- import { NgbSonner, ngbSonnerPortal, sonnerAnimation, SonnerBase } from '@ngbase/adk/sonner';
2
+ import { NgbSonner, ngbSonnerPortal, SonnerBase } from '@ngbase/adk/sonner';
3
3
  import { Icon } from '<%= basepath %>/icon';
4
4
  import { provideIcons } from '@ng-icons/core';
5
5
  import {
@@ -41,7 +41,6 @@ import {
41
41
  }
42
42
  </ul>
43
43
  `,
44
- animations: [sonnerAnimation],
45
44
  })
46
45
  export class Sonner extends NgbSonner {
47
46
  readonly icons = {
@@ -30,3 +30,10 @@ import { Stepper, Step, StepHeader } from '@/ui/stepper';
30
30
  <<%= name %>-step title="Step 3"> Step 3 </<%= name %>-step>
31
31
  </<%= name %>-stepper>
32
32
  ```
33
+
34
+ ```ts
35
+ class App {
36
+ readonly activeIndex = signal(0);
37
+ readonly direction = signal('horizontal');
38
+ }
39
+ ```
@@ -7,7 +7,6 @@ import {
7
7
  NgbStepper,
8
8
  NgbStepperStep,
9
9
  provideStep,
10
- stepperAnimation,
11
10
  } from '@ngbase/adk/stepper';
12
11
 
13
12
  @Component({
@@ -46,8 +45,8 @@ import {
46
45
  }
47
46
  </div>
48
47
  @if (step.verticalTemplate(); as template) {
49
- <div class="ml-12" [@slide]>
50
- <div class="pt-4">
48
+ <div class="stepper-content ml-12">
49
+ <div class="min-h-0 pt-4">
51
50
  <ng-container *ngTemplateOutlet="template" />
52
51
  </div>
53
52
  </div>
@@ -57,7 +56,6 @@ import {
57
56
  </div>
58
57
  <ng-content />
59
58
  `,
60
- animations: [stepperAnimation],
61
59
  })
62
60
  export class Stepper extends NgbStepper {}
63
61