ngwr 9.1.0 → 10.0.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 (106) hide show
  1. package/README.md +14 -0
  2. package/badge/styles/_index.scss +16 -6
  3. package/badge/styles/_tag.scss +10 -1
  4. package/button/styles/_index.scss +48 -1
  5. package/dialog/styles/_index.scss +65 -0
  6. package/drawer/styles/_index.scss +61 -1
  7. package/fesm2022/ngwr-action-sheet.mjs +1 -1
  8. package/fesm2022/ngwr-action-sheet.mjs.map +1 -1
  9. package/fesm2022/ngwr-breadcrumbs.mjs +2 -2
  10. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  11. package/fesm2022/ngwr-card.mjs +2 -2
  12. package/fesm2022/ngwr-card.mjs.map +1 -1
  13. package/fesm2022/ngwr-cascader.mjs +6 -5
  14. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  15. package/fesm2022/ngwr-color-picker.mjs +6 -5
  16. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  17. package/fesm2022/ngwr-context-menu.mjs +7 -7
  18. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  19. package/fesm2022/ngwr-date-picker.mjs +14 -9
  20. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  21. package/fesm2022/ngwr-density.mjs +10 -2
  22. package/fesm2022/ngwr-density.mjs.map +1 -1
  23. package/fesm2022/ngwr-dialog.mjs +10 -1
  24. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  25. package/fesm2022/ngwr-drag-drop.mjs +2 -2
  26. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  27. package/fesm2022/ngwr-drawer.mjs +37 -16
  28. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  29. package/fesm2022/ngwr-dropdown.mjs +4 -3
  30. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  31. package/fesm2022/ngwr-i18n-en.mjs +16 -0
  32. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  33. package/fesm2022/ngwr-i18n-ru.mjs +17 -0
  34. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  35. package/fesm2022/ngwr-i18n.mjs +74 -1
  36. package/fesm2022/ngwr-i18n.mjs.map +1 -1
  37. package/fesm2022/ngwr-icon.mjs +74 -35
  38. package/fesm2022/ngwr-icon.mjs.map +1 -1
  39. package/fesm2022/ngwr-lightbox.mjs +2 -2
  40. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  41. package/fesm2022/ngwr-list.mjs +2 -2
  42. package/fesm2022/ngwr-list.mjs.map +1 -1
  43. package/fesm2022/ngwr-mention.mjs +166 -10
  44. package/fesm2022/ngwr-mention.mjs.map +1 -1
  45. package/fesm2022/ngwr-overlay.mjs +173 -3
  46. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  47. package/fesm2022/ngwr-pagination.mjs +17 -4
  48. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  49. package/fesm2022/ngwr-popconfirm.mjs +4 -3
  50. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  51. package/fesm2022/ngwr-popover.mjs +10 -3
  52. package/fesm2022/ngwr-popover.mjs.map +1 -1
  53. package/fesm2022/ngwr-select.mjs +12 -5
  54. package/fesm2022/ngwr-select.mjs.map +1 -1
  55. package/fesm2022/ngwr-table.mjs +1 -1
  56. package/fesm2022/ngwr-table.mjs.map +1 -1
  57. package/fesm2022/ngwr-theme.mjs +13 -3
  58. package/fesm2022/ngwr-theme.mjs.map +1 -1
  59. package/fesm2022/ngwr-tree.mjs +4 -3
  60. package/fesm2022/ngwr-tree.mjs.map +1 -1
  61. package/fesm2022/ngwr-version.mjs +1 -1
  62. package/fesm2022/ngwr-version.mjs.map +1 -1
  63. package/fesm2022/ngwr-waves.mjs +25 -3
  64. package/fesm2022/ngwr-waves.mjs.map +1 -1
  65. package/i18n/en.json +165 -0
  66. package/i18n/ru.json +165 -0
  67. package/icon/styles/_index.scss +10 -1
  68. package/input/styles/_index.scss +16 -0
  69. package/input-number/styles/_index.scss +8 -1
  70. package/keyboard/styles/_index.scss +10 -3
  71. package/llms-full.txt +3 -3
  72. package/mention/styles/_index.scss +23 -0
  73. package/package.json +3 -1
  74. package/pagination/styles/_index.scss +12 -0
  75. package/popover/styles/_index.scss +129 -45
  76. package/schematics/ng-add/index.js +18 -4
  77. package/schematics/package.json +3 -0
  78. package/schematics/use/symbol-map.json +2 -0
  79. package/select/styles/_index.scss +13 -0
  80. package/splitter/styles/_index.scss +7 -1
  81. package/table/styles/_index.scss +28 -10
  82. package/theme/styles/_box-model.scss +29 -0
  83. package/theme/styles/_colors.scss +74 -15
  84. package/theme/styles/_dark.scss +52 -6
  85. package/theme/styles/_index.scss +1 -0
  86. package/types/ngwr-cascader.d.ts +1 -0
  87. package/types/ngwr-color-picker.d.ts +1 -0
  88. package/types/ngwr-context-menu.d.ts +1 -0
  89. package/types/ngwr-date-picker.d.ts +5 -3
  90. package/types/ngwr-density.d.ts +8 -1
  91. package/types/ngwr-dialog.d.ts +9 -0
  92. package/types/ngwr-drawer.d.ts +20 -4
  93. package/types/ngwr-dropdown.d.ts +1 -0
  94. package/types/ngwr-i18n.d.ts +65 -2
  95. package/types/ngwr-icon.d.ts +11 -19
  96. package/types/ngwr-mention.d.ts +45 -1
  97. package/types/ngwr-overlay.d.ts +80 -2
  98. package/types/ngwr-pagination.d.ts +14 -1
  99. package/types/ngwr-popconfirm.d.ts +1 -0
  100. package/types/ngwr-popover.d.ts +1 -0
  101. package/types/ngwr-select.d.ts +6 -0
  102. package/types/ngwr-theme.d.ts +8 -1
  103. package/types/ngwr-tree.d.ts +1 -0
  104. package/types/ngwr-version.d.ts +1 -1
  105. package/types/ngwr-waves.d.ts +10 -0
  106. package/waves/styles/_index.scss +21 -0
@@ -1,5 +1,7 @@
1
1
  @use 'sass:color';
2
2
 
3
+ @use 'colors';
4
+
3
5
  // Dark theme overrides — opt-in via `[data-theme="dark"]` on <html>.
4
6
  // Drive the toggle from `WrTheme` (provided automatically with
5
7
  // `provideWrTheme(...)`).
@@ -17,6 +19,15 @@ $dark-intents: (
17
19
  danger: #ff5c5c,
18
20
  );
19
21
 
22
+ // The surface / ink bases below are re-tuned for the dark canvas too, but they
23
+ // live in hand-written blocks (each one documents a judgement call the loop
24
+ // can't express). Holding the values in variables lets the `-rgb` triplets and
25
+ // the shade derivations read from the value that actually ships, instead of
26
+ // being re-typed next to it.
27
+ $_light: #262f44;
28
+ $_medium: #9aa6b8;
29
+ $_dark: #e6ebf3;
30
+
20
31
  [data-theme='dark'] {
21
32
  // Canvas (was `--wr-color-white` in light mode)
22
33
  // Deeper than slate-900 so an elevated surface in slate-800 reads
@@ -26,8 +37,8 @@ $dark-intents: (
26
37
 
27
38
  // Text
28
39
  // Softer than pure-white — easier on the eyes for long reading.
29
- --wr-color-dark: #e6ebf3;
30
- --wr-color-dark-rgb: 230, 235, 243;
40
+ --wr-color-dark: #{$_dark};
41
+ --wr-color-dark-rgb: #{color.channel($_dark, 'red')}, #{color.channel($_dark, 'green')}, #{color.channel($_dark, 'blue')};
31
42
  // `*-contrast` values are baked at SCSS compile time from the light
32
43
  // palette, so they don't auto-flip when `--wr-color-dark` /
33
44
  // `--wr-color-white` are reassigned for dark mode. Tooltip-style
@@ -35,6 +46,14 @@ $dark-intents: (
35
46
  // white-on-white without this override; re-pair them by hand here.
36
47
  --wr-color-dark-contrast: #0b1120;
37
48
  --wr-color-white-contrast: #e6ebf3;
49
+ // Same story as the contrast pair: the shades were baked from the light
50
+ // palette's near-black ink, so `.wr-btn--dark:hover` painted itself almost
51
+ // black while keeping the near-black `-contrast` text. `dark` is an INK token,
52
+ // so unlike `light` below its shades mean exactly what they say.
53
+ --wr-color-dark-light: #{color.adjust($_dark, $lightness: 5%)};
54
+ --wr-color-dark-lighter: #{color.adjust($_dark, $lightness: 10%)};
55
+ --wr-color-dark-dark: #{color.adjust($_dark, $lightness: -5%)};
56
+ --wr-color-dark-darker: #{color.adjust($_dark, $lightness: -10%)};
38
57
 
39
58
  // Borders / tints (was `--wr-color-light`)
40
59
  // Used for two jobs at once: 1-px borders and translucent surface
@@ -43,8 +62,8 @@ $dark-intents: (
43
62
  // looks like glowing pencil lines). This value reads as a real
44
63
  // divider on cards / inputs without shouting — matches what Vercel
45
64
  // and shadcn ship for the same job.
46
- --wr-color-light: #262f44;
47
- --wr-color-light-rgb: 38, 47, 68;
65
+ --wr-color-light: #{$_light};
66
+ --wr-color-light-rgb: #{color.channel($_light, 'red')}, #{color.channel($_light, 'green')}, #{color.channel($_light, 'blue')};
48
67
  // The baked contrast pairs with the LIGHT value (#cbd5e1 → dark text);
49
68
  // the dark surface above needs light text instead.
50
69
  --wr-color-light-contrast: #e6ebf3;
@@ -57,18 +76,42 @@ $dark-intents: (
57
76
  // means "stronger divider" (further from canvas, so lighter).
58
77
  --wr-color-light-lighter: #1a2236;
59
78
  --wr-color-light-darker: #3a4661;
79
+ // `-light` / `-dark` were the two the hand block forgot, and they are what
80
+ // `.wr-btn--light` uses for hover / active. Left inherited, hover swapped in
81
+ // the LIGHT palette's slate-300 — a near-white fill under the near-white
82
+ // `-contrast` text above, so the button simply disappeared under the cursor.
83
+ // Half-steps of the tuned pair, same inverted reading: toward the canvas for
84
+ // `-light`, away from it for `-dark`, which also makes hover read as a lift.
85
+ --wr-color-light-light: #{color.adjust($_light, $lightness: -2.5%)};
86
+ --wr-color-light-dark: #{color.adjust($_light, $lightness: 5%)};
60
87
 
61
88
  // Secondary text (was `--wr-color-medium`)
62
89
  // Lifted from slate-400 → slate-300-ish for better legibility on
63
90
  // the deeper canvas.
64
- --wr-color-medium: #9aa6b8;
65
- --wr-color-medium-rgb: 154, 166, 184;
91
+ --wr-color-medium: #{$_medium};
92
+ --wr-color-medium-rgb: #{color.channel($_medium, 'red')}, #{color.channel($_medium, 'green')}, #{color.channel($_medium, 'blue')};
93
+ // This block shipped base + rgb only, so contrast and all four shades still
94
+ // came from the light palette's slate. Ink token, plain shades.
95
+ --wr-color-medium-contrast: #{colors.contrast($_medium)};
96
+ --wr-color-medium-light: #{color.adjust($_medium, $lightness: 5%)};
97
+ --wr-color-medium-lighter: #{color.adjust($_medium, $lightness: 10%)};
98
+ --wr-color-medium-dark: #{color.adjust($_medium, $lightness: -5%)};
99
+ --wr-color-medium-darker: #{color.adjust($_medium, $lightness: -10%)};
100
+
101
+ // Muted TEXT is its own token now (the light theme could not serve both text
102
+ // and fill from one value), so the dark canvas needs its own version too —
103
+ // otherwise it would inherit the light theme's dark ink. 7.64:1 here.
104
+ --wr-color-muted-text: #9aa6b8;
105
+ --wr-color-muted-text-rgb: 154, 166, 184;
66
106
 
67
107
  // Brand-color retune
68
108
  // The default primary (#3969e2) reads a touch dim on the deep
69
109
  // canvas. Bump the base + shade derivations so hover / focus rings
70
110
  // stay visible against slate-900.
71
111
  --wr-color-primary: #5b85ff;
112
+ // Same reason as the loop above — the light primary pairs with white, but the
113
+ // lightened dark-theme primary only reaches 3.36:1 against it.
114
+ --wr-color-primary-contrast: #{colors.contrast(#5b85ff)};
72
115
  --wr-color-primary-rgb: 91, 133, 255;
73
116
  --wr-color-primary-light: #7a9eff;
74
117
  --wr-color-primary-dark: #2f56c9;
@@ -79,6 +122,9 @@ $dark-intents: (
79
122
  // shade set in dark too (generated, so no intent can silently drift).
80
123
  @each $name, $base in $dark-intents {
81
124
  --wr-color-#{$name}: #{$base};
125
+ // Re-derived, not inherited: the light-palette token would pair the wrong
126
+ // foreground with a re-tuned base.
127
+ --wr-color-#{$name}-contrast: #{colors.contrast($base)};
82
128
  --wr-color-#{$name}-rgb: #{color.channel($base, 'red')}, #{color.channel($base, 'green')}, #{color.channel($base, 'blue')};
83
129
  --wr-color-#{$name}-light: #{color.adjust($base, $lightness: 5%)};
84
130
  --wr-color-#{$name}-lighter: #{color.adjust($base, $lightness: 10%)};
@@ -1,3 +1,4 @@
1
+ @forward 'box-model';
1
2
  @forward 'colors';
2
3
  @forward 'variables';
3
4
  @forward 'dark';
@@ -101,6 +101,7 @@ declare class WrCascader<T = string> implements FormValueControl<unknown> {
101
101
  protected readonly panelTpl: _angular_core.Signal<TemplateRef<any>>;
102
102
  private readonly host;
103
103
  private readonly overlay;
104
+ private readonly outsideClick;
104
105
  private readonly vcr;
105
106
  private readonly scrollStrategies;
106
107
  private readonly destroyRef;
@@ -286,6 +286,7 @@ declare class WrColorPickerTrigger {
286
286
  readonly closed: _angular_core.OutputEmitterRef<void>;
287
287
  private readonly host;
288
288
  private readonly overlay;
289
+ private readonly outsideClick;
289
290
  private readonly vcr;
290
291
  private readonly scrollStrategies;
291
292
  private readonly destroyRef;
@@ -44,6 +44,7 @@ declare class WrContextMenu {
44
44
  readonly menu: i0.InputSignal<WrContextMenuPanel>;
45
45
  private readonly host;
46
46
  private readonly overlay;
47
+ private readonly outsideClick;
47
48
  private readonly vcr;
48
49
  private readonly scrollStrategies;
49
50
  private readonly destroyRef;
@@ -25,7 +25,7 @@ import { WrDateFormat } from 'ngwr/date-adapter';
25
25
  * accepts both named keys (`'shortDate'`, `'mediumDateTime'`, …) and raw
26
26
  * token strings (`'dd.MM.yyyy'`, `'HH:mm'`). When `format` is left at the
27
27
  * default (`null`), the picker derives the right named key from `mode`:
28
- * `'date'` → `'shortDate'`, `'time'` → `'shortTime'`, `'datetime'` →
28
+ * `'date'` gives `'shortDate'`, `'time'` gives `'time'`, `'datetime'` gives
29
29
  * `'shortDateTime'`.
30
30
  *
31
31
  * @example
@@ -50,8 +50,8 @@ declare class WrDatePicker implements FormValueControl<Date | null> {
50
50
  readonly mode: _angular_core.InputSignal<"time" | "date" | "datetime">;
51
51
  /**
52
52
  * Format used for both display and parsing. When `null` (default), the
53
- * format is derived from `mode` (`shortDate` / `shortTime` /
54
- * `shortDateTime`). Pass a named key or raw token string to override.
53
+ * format is derived from `mode` (`shortDate` / `time` / `shortDateTime`).
54
+ * Pass a named key or raw token string to override.
55
55
  */
56
56
  readonly format: _angular_core.InputSignal<WrDateFormat | (string & {}) | null>;
57
57
  /** Placeholder shown when the input is empty. */
@@ -79,6 +79,7 @@ declare class WrDatePicker implements FormValueControl<Date | null> {
79
79
  readonly readonly: _angular_core.InputSignalWithTransform<boolean, any>;
80
80
  private readonly adapter;
81
81
  private readonly overlay;
82
+ private readonly outsideClick;
82
83
  private readonly scrollStrategies;
83
84
  private readonly host;
84
85
  private readonly destroyRef;
@@ -219,6 +220,7 @@ declare class WrDateRangePicker implements FormValueControl<WrDateRange | null>
219
220
  readonly readonly: _angular_core.InputSignalWithTransform<boolean, any>;
220
221
  private readonly adapter;
221
222
  private readonly overlay;
223
+ private readonly outsideClick;
222
224
  private readonly scrollStrategies;
223
225
  private readonly host;
224
226
  private readonly destroyRef;
@@ -90,7 +90,14 @@ declare class WrDensityDirective {
90
90
  * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
91
91
  */
92
92
 
93
- /** Configure {@link WrDensity}. All fields optional — merged with defaults. */
93
+ /**
94
+ * Configure and activate {@link WrDensity}. All fields optional — merged with
95
+ * defaults.
96
+ *
97
+ * The initializer instantiates {@link WrDensity} so its constructor effect can
98
+ * write `[data-wr-density]` onto `<html>`. Without it the tree-shakable service
99
+ * was never created and `defaultDensity` had no effect at all.
100
+ */
94
101
  declare function provideWrDensity(config?: Partial<WrDensityConfig>): EnvironmentProviders;
95
102
 
96
103
  export { DEFAULT_WR_DENSITY_CONFIG, WR_DENSITY_CONFIG, WrDensity, WrDensityDirective, provideWrDensity };
@@ -87,6 +87,14 @@ interface WrDialogOptions<D = unknown> {
87
87
  readonly closeOnBackdropClick?: boolean;
88
88
  /** When `true`, the Escape key closes the dialog. @default true */
89
89
  readonly closeOnEscape?: boolean;
90
+ /**
91
+ * Render a dismiss (×) button in the panel's top-right corner. Set `false`
92
+ * when the content supplies its own close affordance, or when the dialog must
93
+ * be resolved through its own actions. @default true
94
+ */
95
+ readonly closable?: boolean;
96
+ /** Accessible name for the dismiss button. Falls back to the `dialog.close` catalog key. */
97
+ readonly closeLabel?: string;
90
98
  /** Width applied to the panel — any valid CSS length. */
91
99
  readonly width?: string;
92
100
  /** Maximum width applied to the panel. */
@@ -130,6 +138,7 @@ declare class WrDialog {
130
138
  private readonly focusTrapFactory;
131
139
  private readonly isBrowser;
132
140
  private readonly responsiveConfig;
141
+ private readonly i18n;
133
142
  open<C, R = unknown, D = unknown>(component: ComponentType<C>, options?: WrDialogOptions<D>): WrDialogRef<C, R>;
134
143
  static ɵfac: i0.ɵɵFactoryDeclaration<WrDialog, never>;
135
144
  static ɵprov: i0.ɵɵInjectableDeclaration<WrDialog>;
@@ -48,6 +48,13 @@ interface WrDrawerOptions<D = unknown> {
48
48
  readonly closeOnBackdropClick?: boolean;
49
49
  /** When `true`, the Escape key closes the drawer. @default true */
50
50
  readonly closeOnEscape?: boolean;
51
+ /**
52
+ * Render a dismiss (×) button in the panel's top-right corner. Set `false`
53
+ * when the content supplies its own close affordance. @default true
54
+ */
55
+ readonly closable?: boolean;
56
+ /** Accessible name for the dismiss button. Falls back to the `drawer.close` catalog key. */
57
+ readonly closeLabel?: string;
51
58
  /** Extra CSS class(es) added to the panel. */
52
59
  readonly panelClass?: string | readonly string[];
53
60
  }
@@ -109,14 +116,22 @@ declare class WrDrawer {
109
116
  readonly closeOnBackdropClick: _angular_core.InputSignalWithTransform<boolean, any>;
110
117
  /** Close on Escape. @default true */
111
118
  readonly closeOnEscape: _angular_core.InputSignalWithTransform<boolean, any>;
119
+ /**
120
+ * Show a dismiss (×) button in the panel's top-right corner. Set `false` when
121
+ * the projected content supplies its own close affordance. @default true
122
+ */
123
+ readonly closable: _angular_core.InputSignalWithTransform<boolean, any>;
124
+ /** Accessible name for the dismiss button. Falls back to `drawer.close`. */
125
+ readonly closeLabel: _angular_core.InputSignal<string | null>;
126
+ protected readonly resolvedCloseLabel: _angular_core.Signal<string>;
112
127
  protected readonly panelTpl: _angular_core.Signal<TemplateRef<any>>;
113
128
  protected panelClass(): string;
114
129
  private swipeStartX;
115
130
  private swipeStartY;
116
131
  private swiping;
117
- protected onSwipeStart(event: TouchEvent): void;
118
- protected onSwipeMove(event: TouchEvent, panel: HTMLElement): void;
119
- protected onSwipeEnd(event: TouchEvent, panel: HTMLElement): void;
132
+ protected onSwipeStart(event: PointerEvent): void;
133
+ protected onSwipeMove(event: PointerEvent, panel: HTMLElement): void;
134
+ protected onSwipeEnd(event: PointerEvent, panel: HTMLElement): void;
120
135
  /** Axis + sign of the closing direction for the current position. */
121
136
  private closeAxis;
122
137
  private readonly overlay;
@@ -131,7 +146,7 @@ declare class WrDrawer {
131
146
  private openOverlay;
132
147
  private closeOverlay;
133
148
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrDrawer, never>;
134
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrDrawer, "wr-drawer", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "position": { "alias": "position"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "showHandle": { "alias": "showHandle"; "required": false; "isSignal": true; }; "safeArea": { "alias": "safeArea"; "required": false; "isSignal": true; }; "hasBackdrop": { "alias": "hasBackdrop"; "required": false; "isSignal": true; }; "closeOnBackdropClick": { "alias": "closeOnBackdropClick"; "required": false; "isSignal": true; }; "closeOnEscape": { "alias": "closeOnEscape"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["*"], true, never>;
149
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrDrawer, "wr-drawer", never, { "open": { "alias": "open"; "required": false; "isSignal": true; }; "position": { "alias": "position"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "maxHeight": { "alias": "maxHeight"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "showHandle": { "alias": "showHandle"; "required": false; "isSignal": true; }; "safeArea": { "alias": "safeArea"; "required": false; "isSignal": true; }; "hasBackdrop": { "alias": "hasBackdrop"; "required": false; "isSignal": true; }; "closeOnBackdropClick": { "alias": "closeOnBackdropClick"; "required": false; "isSignal": true; }; "closeOnEscape": { "alias": "closeOnEscape"; "required": false; "isSignal": true; }; "closable": { "alias": "closable"; "required": false; "isSignal": true; }; "closeLabel": { "alias": "closeLabel"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["*"], true, never>;
135
150
  }
136
151
 
137
152
  /**
@@ -237,6 +252,7 @@ declare class WrDrawerManager {
237
252
  private readonly parentInjector;
238
253
  private readonly focusTrapFactory;
239
254
  private readonly isBrowser;
255
+ private readonly i18n;
240
256
  open<C, R = unknown, D = unknown>(component: ComponentType<C>, options?: WrDrawerOptions<D>): WrDrawerRef<C, R>;
241
257
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrDrawerManager, never>;
242
258
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<WrDrawerManager>;
@@ -73,6 +73,7 @@ declare class WrDropdown {
73
73
  readonly closed: _angular_core.OutputEmitterRef<void>;
74
74
  private readonly host;
75
75
  private readonly overlay;
76
+ private readonly outsideClick;
76
77
  private readonly responsiveConfig;
77
78
  private readonly vcr;
78
79
  private readonly scrollStrategies;
@@ -76,6 +76,12 @@ declare class WrI18n {
76
76
  private readonly config;
77
77
  private readonly loader;
78
78
  private readonly storage;
79
+ /**
80
+ * Catalogs registered via `provideWrI18nBaseCatalogs()` — the floor under the
81
+ * loader's own catalogs, so ngwr's built-in strings survive an app that only
82
+ * ships its own keys. @internal
83
+ */
84
+ private readonly baseCatalogs;
79
85
  /** Per-(locale,scope) catalogs, populated by `loadCatalog`. @internal */
80
86
  private readonly catalogs;
81
87
  /** Bumped after each catalog write so reactive translates recompute. @internal */
@@ -106,6 +112,11 @@ declare class WrI18n {
106
112
  t(key: string, params?: WrI18nParams, scope?: string): string;
107
113
  /** Reactive translate — re-evaluates on locale or catalog updates. */
108
114
  translate(key: string, params?: WrI18nParams, scope?: string): Signal<string>;
115
+ /**
116
+ * Look a key up in the registered base catalogs, later contributions first so
117
+ * a feature can shadow an earlier one.
118
+ */
119
+ private walkBase;
109
120
  private initialLocale;
110
121
  private loadCatalog;
111
122
  static ɵfac: i0.ɵɵFactoryDeclaration<WrI18n, never>;
@@ -181,6 +192,35 @@ interface WrI18nLoader {
181
192
  }
182
193
  declare const WR_I18N_LOADER: InjectionToken<WrI18nLoader>;
183
194
 
195
+ /**
196
+ * @license
197
+ *
198
+ * Use of this source code is governed by an MIT-style license that can be
199
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
200
+ */
201
+
202
+ /** Base catalogs keyed by locale, contributed by {@link provideWrI18nBaseCatalogs}. */
203
+ type WrI18nBaseCatalogs = Readonly<Record<string, WrI18nCatalog>>;
204
+ /**
205
+ * Catalogs consulted *underneath* whatever the loader returned — the place for
206
+ * ngwr's own built-in strings.
207
+ *
208
+ * A loader **replaces** the catalog for a locale rather than extending it, so an
209
+ * app whose JSON holds only its own keys used to lose every built-in label to
210
+ * its hardcoded English fallback, silently. Registering `wrRu` / `wrEn` here
211
+ * puts them back without the app having to merge anything itself.
212
+ *
213
+ * `multi`, so several features can each contribute; later contributions win on
214
+ * a key collision, and anything the loader returned still wins over all of them.
215
+ *
216
+ * It has to be handed in by the consumer rather than wired up inside
217
+ * `provideWrI18n()`: the catalogs are their own entry points (`ngwr/i18n/ru`)
218
+ * and they already import from `ngwr/i18n`, so importing them back here is a
219
+ * circular entry-point dependency that ng-packagr rejects outright. Passing
220
+ * them in also keeps the locales you don't ship out of your bundle.
221
+ */
222
+ declare const WR_I18N_BASE_CATALOGS: InjectionToken<readonly Readonly<Record<string, WrI18nCatalog>>[]>;
223
+
184
224
  /**
185
225
  * @license
186
226
  *
@@ -270,6 +310,29 @@ declare function provideWrI18n(options?: ProvideWrI18nOptions): EnvironmentProvi
270
310
  * @param scopes Optional per-scope catalogs served to `registerScope(name)`.
271
311
  */
272
312
  declare function provideWrI18nStaticLoader(catalogs: WrI18nStaticCatalogs, scopes?: WrI18nStaticScopedCatalogs): Provider;
313
+ /**
314
+ * Register catalogs consulted *underneath* the loader — this is how ngwr's own
315
+ * built-in strings survive when you supply your own catalogs.
316
+ *
317
+ * A loader replaces the catalog for a locale instead of extending it, so a JSON
318
+ * file holding only your keys leaves every built-in label on its hardcoded
319
+ * English fallback, with nothing logged. One line fixes it, on either loader:
320
+ *
321
+ * @example
322
+ * ```ts
323
+ * import { wrRu } from 'ngwr/i18n/ru';
324
+ *
325
+ * providers: [
326
+ * provideWrI18n({ defaultLocale: 'ru', availableLocales: ['ru'] }),
327
+ * provideWrI18nBaseCatalogs({ ru: wrRu }),
328
+ * provideWrI18nHttpLoader({ path: '/assets/i18n/{locale}.json' }),
329
+ * ]
330
+ * ```
331
+ *
332
+ * Pass only the locales you ship — the ones you leave out stay out of the
333
+ * bundle. Your own keys always win; this is a floor, not an override.
334
+ */
335
+ declare function provideWrI18nBaseCatalogs(catalogs: WrI18nBaseCatalogs): Provider;
273
336
  /** Provide an HTTP loader — catalogs fetched from URLs. Requires `provideHttpClient`. */
274
337
  declare function provideWrI18nHttpLoader(config: WrI18nHttpLoaderConfig): Provider;
275
338
 
@@ -332,5 +395,5 @@ declare function readI18nText(key: string, fallback: string): string;
332
395
  */
333
396
  declare function useI18nFormatter(key: string, fallback: string): (params?: WrI18nParams) => string;
334
397
 
335
- export { DEFAULT_WR_I18N_CONFIG, WR_I18N_CONFIG, WR_I18N_LOADER, WrI18n, WrI18nHttpLoader, WrI18nStaticLoader, WrTDirective, WrTPipe, provideWrI18n, provideWrI18nHttpLoader, provideWrI18nStaticLoader, readI18nText, useI18nFormatter, useI18nText };
336
- export type { ProvideWrI18nOptions, WrI18nCatalog, WrI18nConfig, WrI18nConfigResolved, WrI18nHttpLoaderConfig, WrI18nLoader, WrI18nMissingHandler, WrI18nParams, WrI18nStaticCatalogs, WrI18nStaticScopedCatalogs };
398
+ export { DEFAULT_WR_I18N_CONFIG, WR_I18N_BASE_CATALOGS, WR_I18N_CONFIG, WR_I18N_LOADER, WrI18n, WrI18nHttpLoader, WrI18nStaticLoader, WrTDirective, WrTPipe, provideWrI18n, provideWrI18nBaseCatalogs, provideWrI18nHttpLoader, provideWrI18nStaticLoader, readI18nText, useI18nFormatter, useI18nText };
399
+ export type { ProvideWrI18nOptions, WrI18nBaseCatalogs, WrI18nCatalog, WrI18nConfig, WrI18nConfigResolved, WrI18nHttpLoaderConfig, WrI18nLoader, WrI18nMissingHandler, WrI18nParams, WrI18nStaticCatalogs, WrI18nStaticScopedCatalogs };
@@ -18,28 +18,20 @@ declare class WrIcon {
18
18
  readonly name: i0.InputSignal<string>;
19
19
  private readonly host;
20
20
  /**
21
- * Merged view of every `WR_ICONS` multi-provider visible from this
22
- * injector position — element-level first overlay, environment-level
23
- * (app/lazy-route bootstrap) as the base.
21
+ * Every icon visible from this position, walked up the whole chain of
22
+ * registering injector levels.
24
23
  *
25
- * Angular's default `inject(WR_ICONS)` only returns the **closest**
26
- * injector's contribution; if a component declares its own
27
- * `provideWrIcons(...)`, the root registration is **shadowed**, not
28
- * appended. That contradicts the docstring's "each call adds to the
29
- * registry" promise and silently breaks any page that overrides while
30
- * still relying on root-registered icons.
24
+ * Angular's `inject(WR_ICONS)` returns only the **closest** injector's
25
+ * contribution — `multi` providers are not merged across levels — so a
26
+ * component that registers its own icons used to shadow, not extend, what an
27
+ * ancestor registered. {@link WrIconRegistry} is provided once per
28
+ * registering level and links to its parent, so nesting any number of levels
29
+ * now adds up, with the nearest registration winning a name collision.
31
30
  *
32
- * We work around it by also asking the environment injector directly
33
- * (`envInjector.get(WR_ICONS, null, …)`). When no element-level
34
- * provider exists both calls return the same array reference and we
35
- * skip the redundant pass. Otherwise we lay element on top of env so
36
- * a page's local icons can override a root-registered name.
37
- *
38
- * One known limitation: multiple element-injector levels in between
39
- * still shadow each other — but the showcase doesn't nest providers
40
- * that deep, and the env+local merge fixes the dominant case.
31
+ * Optional: with no `provideWrIcons()` anywhere the map is simply empty and
32
+ * every name reports as unregistered.
41
33
  */
42
- private readonly iconSets;
34
+ private readonly iconRegistry;
43
35
  private readonly registry;
44
36
  private readonly icon;
45
37
  constructor();
@@ -62,12 +62,43 @@ declare class WrMention<T extends WrMentionItem = WrMentionItem> {
62
62
  private readonly overlay;
63
63
  private readonly scrollStrategies;
64
64
  private readonly destroyRef;
65
+ private readonly isBrowser;
65
66
  private overlayRef;
66
67
  private panelRef;
67
68
  private state;
68
69
  private readonly activeIndex;
69
70
  private readonly filteredItems;
71
+ private readonly isOpen;
72
+ /** @internal — read by the `aria-controls` host binding. */
73
+ protected readonly listboxId: string;
74
+ private readonly listLabel;
75
+ private readonly availableText;
76
+ private readonly insertedText;
77
+ /**
78
+ * `aria-activedescendant`, or `null`.
79
+ *
80
+ * Gated hard on `isOpen()`, which is only set once the panel's options are
81
+ * actually in the DOM. An id that resolves to nothing is an author error, and
82
+ * the failure mode is silent: the browser does not complain, it simply stops
83
+ * firing the event that makes a screen reader speak the option. Same
84
+ * discipline `tree.ts` uses for its virtualized rows.
85
+ */
86
+ protected readonly activeOptionId: _angular_core.Signal<string | null>;
87
+ /**
88
+ * Polite live region, parked on `<body>`.
89
+ *
90
+ * Not inside the panel: `close()` disposes the overlay on every keystroke that
91
+ * leaves a mention, so a region living there would be recreated constantly —
92
+ * and a live region has to be in the DOM *before* its text changes to be
93
+ * announced at all. It also could not announce the two cases that matter most,
94
+ * since in both the panel is already gone: "nothing matched" and "inserted X".
95
+ *
96
+ * Not a sibling of the host either — that would land inside the consumer's
97
+ * markup and start matching their `+`, `~` and `:nth-child()` selectors.
98
+ */
99
+ private liveRegion;
70
100
  constructor();
101
+ private announce;
71
102
  /** @internal */
72
103
  protected onInput(): void;
73
104
  /** @internal */
@@ -97,13 +128,26 @@ declare class WrMentionPanel {
97
128
  readonly items: _angular_core.InputSignal<readonly WrMentionItem[]>;
98
129
  readonly activeIndex: _angular_core.InputSignal<number>;
99
130
  readonly displayWith: _angular_core.InputSignal<(item: WrMentionItem) => string>;
131
+ /**
132
+ * Id of the `<ul role="listbox">`, minted by the directive and pointed at by
133
+ * its `aria-controls`. Owned there rather than here because the panel is
134
+ * disposed and rebuilt whenever the caret leaves a mention, while the
135
+ * attribute on the host has to stay put.
136
+ *
137
+ * Plain `input('')`, never `input.required` — a ComponentPortal-created
138
+ * component throws on the first change detection if a required input is unset.
139
+ */
140
+ readonly listboxId: _angular_core.InputSignal<string>;
141
+ /** Accessible name for the listbox. ARIA requires one; the directive supplies it from the catalog. */
142
+ readonly listLabel: _angular_core.InputSignal<string>;
143
+ protected optionId(index: number): string;
100
144
  /** Emitted when the user picks an item (click). */
101
145
  readonly picked: _angular_core.OutputEmitterRef<WrMentionItem>;
102
146
  /** Emitted on mouseenter — used by the directive to track hover. */
103
147
  readonly hovered: _angular_core.OutputEmitterRef<number>;
104
148
  protected onPick(item: WrMentionItem, event: MouseEvent): void;
105
149
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrMentionPanel, never>;
106
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrMentionPanel, "wr-mention-panel", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "activeIndex": { "alias": "activeIndex"; "required": false; "isSignal": true; }; "displayWith": { "alias": "displayWith"; "required": false; "isSignal": true; }; }, { "picked": "picked"; "hovered": "hovered"; }, never, never, true, never>;
150
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrMentionPanel, "wr-mention-panel", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "activeIndex": { "alias": "activeIndex"; "required": false; "isSignal": true; }; "displayWith": { "alias": "displayWith"; "required": false; "isSignal": true; }; "listboxId": { "alias": "listboxId"; "required": false; "isSignal": true; }; "listLabel": { "alias": "listLabel"; "required": false; "isSignal": true; }; }, { "picked": "picked"; "hovered": "hovered"; }, never, never, true, never>;
107
151
  }
108
152
 
109
153
  export { WrMention, WrMentionPanel };
@@ -1,7 +1,85 @@
1
- import { OverlayContainer, Overlay } from '@angular/cdk/overlay';
1
+ import { OverlayRef, OverlayContainer, Overlay } from '@angular/cdk/overlay';
2
+ import { Observable } from 'rxjs';
2
3
  import * as i0 from '@angular/core';
3
4
  import { EnvironmentProviders, InjectionToken } from '@angular/core';
4
5
 
6
+ /**
7
+ * @license
8
+ *
9
+ * Use of this source code is governed by an MIT-style license that can be
10
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
11
+ */
12
+ /**
13
+ * Appends a dismiss (✕) button to a service-opened overlay panel.
14
+ *
15
+ * `WrDialog` and `WrDrawerManager` build their panel around a component the
16
+ * consumer supplies, so there is no template of their own to put a corner button
17
+ * in — they call this instead. Component-driven overlays (`<wr-drawer>`) render
18
+ * the same markup in their template.
19
+ *
20
+ * Uses `host.ownerDocument` rather than the global `document`, so it carries no
21
+ * hidden browser-only assumption; callers still gate on the platform because
22
+ * they have nothing to append to on the server.
23
+ *
24
+ * @param host Panel element the button is appended to (and positioned against).
25
+ * @param className BEM class for the button, e.g. `wr-dialog__close`.
26
+ * @param label Accessible name — already localized by the caller.
27
+ * @param onClose Invoked on click.
28
+ */
29
+ declare function wrAppendOverlayClose(host: HTMLElement, className: string, label: string, onClose: () => void): HTMLButtonElement;
30
+
31
+ /**
32
+ * @license
33
+ *
34
+ * Use of this source code is governed by an MIT-style license that can be
35
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
36
+ */
37
+
38
+ /**
39
+ * Outside-click source for overlays — a drop-in replacement for
40
+ * `OverlayRef.outsidePointerEvents()`.
41
+ *
42
+ * **Why this exists.** CDK's `OverlayOutsideClickDispatcher` binds its
43
+ * listeners to `document.body`. When page content is shorter than the viewport,
44
+ * a click in the empty space below it targets `<html>` — and `<html>` is
45
+ * `body`'s *parent*, so the event bubbles straight to the document and `body`
46
+ * never sees it. The overlay silently stays open. Listening on the document
47
+ * itself catches both cases, and costs nothing else.
48
+ *
49
+ * Semantics are otherwise identical to the CDK's, deliberately:
50
+ *
51
+ * - Emits on `click` / `auxclick` / `contextmenu`, in the capture phase, and
52
+ * tracks `pointerdown` so a `click` is judged by where the press *started*
53
+ * (a drag that ends outside the pane doesn't count as an outside click).
54
+ * - Walks watchers top-most first and stops at the first one that contains the
55
+ * event, so clicking inside a stacked overlay can't close the ones beneath
56
+ * it (a `wr-select` opened inside a `wr-popover`, say).
57
+ * - Fires for the very click that opened the overlay, which is why every caller
58
+ * also ignores events landing on its own trigger.
59
+ *
60
+ * Registration is per subscription: the document listeners go up with the first
61
+ * watcher and come down with the last, so an app with no open overlay has none.
62
+ */
63
+ declare class WrOutsideClick {
64
+ private readonly doc;
65
+ private readonly isBrowser;
66
+ /** In attach order — last is top-most. */
67
+ private readonly watchers;
68
+ private cleanup;
69
+ private pressOrigin;
70
+ /**
71
+ * Emits every `click` / `auxclick` / `contextmenu` that lands outside the
72
+ * given overlay's pane, for as long as the returned observable is subscribed.
73
+ */
74
+ outsidePointerEvents(overlayRef: OverlayRef): Observable<MouseEvent>;
75
+ private readonly onPointerDown;
76
+ private readonly onClick;
77
+ private listen;
78
+ private unlisten;
79
+ static ɵfac: i0.ɵɵFactoryDeclaration<WrOutsideClick, never>;
80
+ static ɵprov: i0.ɵɵInjectableDeclaration<WrOutsideClick>;
81
+ }
82
+
5
83
  /**
6
84
  * @license
7
85
  *
@@ -175,4 +253,4 @@ declare const WR_OVERLAY: InjectionToken<Overlay>;
175
253
  */
176
254
  declare const WR_OVERLAY_CONTAINER: InjectionToken<OverlayContainer>;
177
255
 
178
- export { WR_OVERLAY, WR_OVERLAY_CONTAINER, WR_RESPONSIVE_OVERLAYS, WrOverlayContainer, provideWrOverlay, provideWrResponsiveOverlays, wrPresentAsSheet };
256
+ export { WR_OVERLAY, WR_OVERLAY_CONTAINER, WR_RESPONSIVE_OVERLAYS, WrOutsideClick, WrOverlayContainer, provideWrOverlay, provideWrResponsiveOverlays, wrAppendOverlayClose, wrPresentAsSheet };
@@ -1,3 +1,4 @@
1
+ import * as ngwr_i18n from 'ngwr/i18n';
1
2
  import * as _angular_core from '@angular/core';
2
3
 
3
4
  /**
@@ -91,11 +92,23 @@ declare class WrPagination {
91
92
  readonly nextLabel: _angular_core.InputSignal<string | null>;
92
93
  /** "Items per page" label. Falls back to `pagination.itemsPerPage`. */
93
94
  readonly itemsPerPageLabel: _angular_core.InputSignal<string | null>;
95
+ /** Accessible name for the `role="navigation"` host. Falls back to `pagination.label`. */
96
+ readonly label: _angular_core.InputSignal<string | null>;
94
97
  /** Resolved labels. */
95
98
  protected readonly resolvedOf: _angular_core.Signal<string>;
96
99
  protected readonly resolvedPrev: _angular_core.Signal<string>;
97
100
  protected readonly resolvedNext: _angular_core.Signal<string>;
98
101
  protected readonly resolvedItemsPerPage: _angular_core.Signal<string>;
102
+ /**
103
+ * Page-size option text — interpolates `{{size}}`. Was the template literal
104
+ * `{{ option }} / page`, which no catalog could reach, so a Russian UI read
105
+ * "25 / page".
106
+ */
107
+ protected readonly perPage: (params?: ngwr_i18n.WrI18nParams) => string;
108
+ /** Per-page-button aria-label — interpolates `{{page}}`. */
109
+ protected readonly goToPage: (params?: ngwr_i18n.WrI18nParams) => string;
110
+ /** The nav landmark's own accessible name — was a hardcoded English literal. */
111
+ protected readonly navLabel: _angular_core.Signal<string>;
99
112
  /** Internal: total page count. */
100
113
  protected readonly totalPages: _angular_core.Signal<number>;
101
114
  /** Internal: "X–Y of Z" string. */
@@ -112,7 +125,7 @@ declare class WrPagination {
112
125
  protected goTo(page: number | typeof ELLIPSIS): void;
113
126
  protected onSizeChange(size: number): void;
114
127
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<WrPagination, never>;
115
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrPagination, "wr-pagination", never, { "currentPage": { "alias": "currentPage"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "total": { "alias": "total"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "showSizeChanger": { "alias": "showSizeChanger"; "required": false; "isSignal": true; }; "showTotal": { "alias": "showTotal"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "responsive": { "alias": "responsive"; "required": false; "isSignal": true; }; "ofLabel": { "alias": "ofLabel"; "required": false; "isSignal": true; }; "prevLabel": { "alias": "prevLabel"; "required": false; "isSignal": true; }; "nextLabel": { "alias": "nextLabel"; "required": false; "isSignal": true; }; "itemsPerPageLabel": { "alias": "itemsPerPageLabel"; "required": false; "isSignal": true; }; }, { "currentPage": "currentPageChange"; "pageSize": "pageSizeChange"; }, never, never, true, never>;
128
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<WrPagination, "wr-pagination", never, { "currentPage": { "alias": "currentPage"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "total": { "alias": "total"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "showSizeChanger": { "alias": "showSizeChanger"; "required": false; "isSignal": true; }; "showTotal": { "alias": "showTotal"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "responsive": { "alias": "responsive"; "required": false; "isSignal": true; }; "ofLabel": { "alias": "ofLabel"; "required": false; "isSignal": true; }; "prevLabel": { "alias": "prevLabel"; "required": false; "isSignal": true; }; "nextLabel": { "alias": "nextLabel"; "required": false; "isSignal": true; }; "itemsPerPageLabel": { "alias": "itemsPerPageLabel"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, { "currentPage": "currentPageChange"; "pageSize": "pageSizeChange"; }, never, never, true, never>;
116
129
  }
117
130
 
118
131
  export { WrPagination };