ngwr 14.7.0 → 14.8.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 (152) hide show
  1. package/bar-chart/styles/_index.scss +1 -0
  2. package/calendar-heatmap/styles/_index.scss +1 -0
  3. package/cascader/styles/_rules.scss +86 -14
  4. package/date-picker/styles/_index.scss +30 -0
  5. package/density/styles/_index.scss +4 -2
  6. package/donut-chart/styles/_index.scss +10 -0
  7. package/dropdown/styles/_index.scss +67 -5
  8. package/event-calendar/styles/_index.scss +209 -35
  9. package/fesm2022/ngwr-bar-chart.mjs +29 -4
  10. package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
  11. package/fesm2022/ngwr-calendar-heatmap.mjs +59 -4
  12. package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
  13. package/fesm2022/ngwr-cascader.mjs +2 -2
  14. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  15. package/fesm2022/ngwr-checkbox.mjs +12 -2
  16. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  17. package/fesm2022/ngwr-date-picker.mjs +705 -46
  18. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  19. package/fesm2022/ngwr-donut-chart.mjs +46 -4
  20. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  21. package/fesm2022/ngwr-dropdown.mjs +166 -17
  22. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  23. package/fesm2022/ngwr-event-calendar.mjs +9 -2
  24. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  25. package/fesm2022/ngwr-form.mjs +52 -1
  26. package/fesm2022/ngwr-form.mjs.map +1 -1
  27. package/fesm2022/ngwr-gauge.mjs +33 -4
  28. package/fesm2022/ngwr-gauge.mjs.map +1 -1
  29. package/fesm2022/ngwr-i18n-ar.mjs +2 -0
  30. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  31. package/fesm2022/ngwr-i18n-cs.mjs +2 -0
  32. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  33. package/fesm2022/ngwr-i18n-de.mjs +2 -0
  34. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  35. package/fesm2022/ngwr-i18n-en.mjs +5 -0
  36. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  37. package/fesm2022/ngwr-i18n-es.mjs +2 -0
  38. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  39. package/fesm2022/ngwr-i18n-fr.mjs +2 -0
  40. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  41. package/fesm2022/ngwr-i18n-he.mjs +2 -0
  42. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  43. package/fesm2022/ngwr-i18n-hi.mjs +2 -0
  44. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  45. package/fesm2022/ngwr-i18n-id.mjs +2 -0
  46. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  47. package/fesm2022/ngwr-i18n-it.mjs +2 -0
  48. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  49. package/fesm2022/ngwr-i18n-ja.mjs +2 -0
  50. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  51. package/fesm2022/ngwr-i18n-ko.mjs +2 -0
  52. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  53. package/fesm2022/ngwr-i18n-nl.mjs +2 -0
  54. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  55. package/fesm2022/ngwr-i18n-pl.mjs +2 -0
  56. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  57. package/fesm2022/ngwr-i18n-pt.mjs +2 -0
  58. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  59. package/fesm2022/ngwr-i18n-ru.mjs +2 -0
  60. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  61. package/fesm2022/ngwr-i18n-sv.mjs +2 -0
  62. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  63. package/fesm2022/ngwr-i18n-tr.mjs +2 -0
  64. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  65. package/fesm2022/ngwr-i18n-uk.mjs +2 -0
  66. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  67. package/fesm2022/ngwr-i18n-vi.mjs +2 -0
  68. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  69. package/fesm2022/ngwr-i18n-zh-TW.mjs +2 -0
  70. package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
  71. package/fesm2022/ngwr-i18n-zh.mjs +2 -0
  72. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  73. package/fesm2022/ngwr-input-number.mjs +12 -0
  74. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  75. package/fesm2022/ngwr-line-chart.mjs +16 -5
  76. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  77. package/fesm2022/ngwr-meter-group-testing.mjs +7 -3
  78. package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -1
  79. package/fesm2022/ngwr-meter-group.mjs +24 -4
  80. package/fesm2022/ngwr-meter-group.mjs.map +1 -1
  81. package/fesm2022/ngwr-page-header.mjs +10 -2
  82. package/fesm2022/ngwr-page-header.mjs.map +1 -1
  83. package/fesm2022/ngwr-popover.mjs +569 -7
  84. package/fesm2022/ngwr-popover.mjs.map +1 -1
  85. package/fesm2022/ngwr-sidebar.mjs +7 -0
  86. package/fesm2022/ngwr-sidebar.mjs.map +1 -1
  87. package/fesm2022/ngwr-sparkline.mjs +82 -8
  88. package/fesm2022/ngwr-sparkline.mjs.map +1 -1
  89. package/fesm2022/ngwr-table.mjs +1 -1
  90. package/fesm2022/ngwr-table.mjs.map +1 -1
  91. package/fesm2022/ngwr-toolbar.mjs +7 -0
  92. package/fesm2022/ngwr-toolbar.mjs.map +1 -1
  93. package/fesm2022/ngwr-version.mjs +1 -1
  94. package/fesm2022/ngwr-version.mjs.map +1 -1
  95. package/form/styles/_index.scss +11 -1
  96. package/gauge/styles/_index.scss +1 -0
  97. package/i18n/ar.json +3 -1
  98. package/i18n/cs.json +3 -1
  99. package/i18n/de.json +3 -1
  100. package/i18n/en.json +3 -1
  101. package/i18n/es.json +3 -1
  102. package/i18n/fr.json +3 -1
  103. package/i18n/he.json +3 -1
  104. package/i18n/hi.json +3 -1
  105. package/i18n/id.json +3 -1
  106. package/i18n/it.json +3 -1
  107. package/i18n/ja.json +3 -1
  108. package/i18n/ko.json +3 -1
  109. package/i18n/nl.json +3 -1
  110. package/i18n/pl.json +3 -1
  111. package/i18n/pt.json +3 -1
  112. package/i18n/ru.json +3 -1
  113. package/i18n/sv.json +3 -1
  114. package/i18n/tr.json +3 -1
  115. package/i18n/uk.json +3 -1
  116. package/i18n/vi.json +3 -1
  117. package/i18n/zh-TW.json +3 -1
  118. package/i18n/zh.json +3 -1
  119. package/input/styles/_index.scss +19 -0
  120. package/input-number/styles/_index.scss +69 -0
  121. package/line-chart/styles/_index.scss +30 -2
  122. package/llms-full.txt +3 -3
  123. package/meter-group/styles/_index.scss +1 -0
  124. package/overlay/styles/_arrow.scss +27 -2
  125. package/package.json +1 -1
  126. package/page-header/styles/_index.scss +37 -1
  127. package/pagination/styles/_index.scss +9 -5
  128. package/popover/styles/_index.scss +73 -5
  129. package/select/styles/_index.scss +48 -9
  130. package/sidebar/styles/_index.scss +34 -2
  131. package/sparkline/styles/_index.scss +19 -0
  132. package/toolbar/styles/_index.scss +35 -1
  133. package/tree/styles/_index.scss +45 -6
  134. package/types/ngwr-bar-chart.d.ts +19 -1
  135. package/types/ngwr-calendar-heatmap.d.ts +29 -1
  136. package/types/ngwr-checkbox.d.ts +2 -0
  137. package/types/ngwr-date-picker.d.ts +308 -43
  138. package/types/ngwr-donut-chart.d.ts +24 -1
  139. package/types/ngwr-dropdown.d.ts +22 -2
  140. package/types/ngwr-event-calendar.d.ts +8 -0
  141. package/types/ngwr-form.d.ts +35 -5
  142. package/types/ngwr-gauge.d.ts +20 -1
  143. package/types/ngwr-input-number.d.ts +7 -0
  144. package/types/ngwr-line-chart.d.ts +9 -1
  145. package/types/ngwr-meter-group-testing.d.ts +3 -2
  146. package/types/ngwr-meter-group.d.ts +14 -1
  147. package/types/ngwr-page-header.d.ts +10 -2
  148. package/types/ngwr-popover.d.ts +154 -3
  149. package/types/ngwr-sidebar.d.ts +7 -0
  150. package/types/ngwr-sparkline.d.ts +43 -1
  151. package/types/ngwr-toolbar.d.ts +7 -0
  152. package/types/ngwr-version.d.ts +1 -1
@@ -12,6 +12,13 @@ import { input, ViewEncapsulation, Component } from '@angular/core';
12
12
  * Action bar with three named zones — `[wrToolbarStart]`,
13
13
  * `[wrToolbarCenter]`, `[wrToolbarEnd]`. Use any one or all three.
14
14
  *
15
+ * A bare `<div>` wrapper in a zone, one with no `class` and no `style`, is laid
16
+ * out as a wrapping row with the zone's own gap, so the controls inside it are
17
+ * spaced exactly like controls projected one by one. The gap follows
18
+ * `--wr-density-gap`. Give the wrapper a class or a style and its layout is
19
+ * yours: the toolbar sets nothing on it. Put running text in a `<span>` or a
20
+ * `<p>`, which stay in inline flow.
21
+ *
15
22
  * @example
16
23
  * ```html
17
24
  * <wr-toolbar>
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-toolbar.mjs","sources":["../../../projects/lib/toolbar/toolbar.ts","../../../projects/lib/toolbar/toolbar.html","../../../projects/lib/toolbar/ngwr-toolbar.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, input } from '@angular/core';\n\n/**\n * Action bar with three named zones — `[wrToolbarStart]`,\n * `[wrToolbarCenter]`, `[wrToolbarEnd]`. Use any one or all three.\n *\n * @example\n * ```html\n * <wr-toolbar>\n * <div wrToolbarStart>\n * <button wr-btn>Back</button>\n * <strong>Items</strong>\n * </div>\n * <div wrToolbarCenter>\n * <wr-segmented [(value)]=\"view\" [options]=\"['grid', 'list']\" />\n * </div>\n * <div wrToolbarEnd>\n * <button wr-btn color=\"primary\">New</button>\n * </div>\n * </wr-toolbar>\n * ```\n *\n * @see https://ngwr.dev/reference/components/toolbar\n */\n@Component({\n selector: 'wr-toolbar',\n templateUrl: './toolbar.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-toolbar', role: 'toolbar', '[class.wr-toolbar--responsive]': 'responsive()' },\n})\nexport class WrToolbar {\n /**\n * Stack the zones vertically when the toolbar's own box is too narrow to fit\n * them in a row (a container query on its own width, not the viewport — so it\n * adapts inside a narrow column or split pane). @default false\n */\n readonly responsive = input(false, { transform: coerceBooleanProperty });\n}\n","<div class=\"wr-toolbar__zone wr-toolbar__zone--start\">\n <ng-content select=\"[wrToolbarStart]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--center\">\n <ng-content select=\"[wrToolbarCenter]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--end\">\n <ng-content select=\"[wrToolbarEnd]\" />\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;AAAA;;;;;AAKG;AAKH;;;;;;;;;;;;;;;;;;;;;AAqBG;MAOU,SAAS,CAAA;AACpB;;;;AAIG;IACM,UAAU,GAAG,KAAK,CAAC,KAAK,kFAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;uGAN7D,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAT,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,SAAS,oWCtCtB,gVASA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FD6Ba,SAAS,EAAA,UAAA,EAAA,CAAA;kBANrB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,YAAY,iBAEP,iBAAiB,CAAC,IAAI,EAAA,IAAA,EAC/B,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,gCAAgC,EAAE,cAAc,EAAE,EAAA,QAAA,EAAA,gVAAA,EAAA;;;AEpClG;;AAEG;;;;"}
1
+ {"version":3,"file":"ngwr-toolbar.mjs","sources":["../../../projects/lib/toolbar/toolbar.ts","../../../projects/lib/toolbar/toolbar.html","../../../projects/lib/toolbar/ngwr-toolbar.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { Component, ViewEncapsulation, input } from '@angular/core';\n\n/**\n * Action bar with three named zones — `[wrToolbarStart]`,\n * `[wrToolbarCenter]`, `[wrToolbarEnd]`. Use any one or all three.\n *\n * A bare `<div>` wrapper in a zone, one with no `class` and no `style`, is laid\n * out as a wrapping row with the zone's own gap, so the controls inside it are\n * spaced exactly like controls projected one by one. The gap follows\n * `--wr-density-gap`. Give the wrapper a class or a style and its layout is\n * yours: the toolbar sets nothing on it. Put running text in a `<span>` or a\n * `<p>`, which stay in inline flow.\n *\n * @example\n * ```html\n * <wr-toolbar>\n * <div wrToolbarStart>\n * <button wr-btn>Back</button>\n * <strong>Items</strong>\n * </div>\n * <div wrToolbarCenter>\n * <wr-segmented [(value)]=\"view\" [options]=\"['grid', 'list']\" />\n * </div>\n * <div wrToolbarEnd>\n * <button wr-btn color=\"primary\">New</button>\n * </div>\n * </wr-toolbar>\n * ```\n *\n * @see https://ngwr.dev/reference/components/toolbar\n */\n@Component({\n selector: 'wr-toolbar',\n templateUrl: './toolbar.html',\n encapsulation: ViewEncapsulation.None,\n host: { class: 'wr-toolbar', role: 'toolbar', '[class.wr-toolbar--responsive]': 'responsive()' },\n})\nexport class WrToolbar {\n /**\n * Stack the zones vertically when the toolbar's own box is too narrow to fit\n * them in a row (a container query on its own width, not the viewport — so it\n * adapts inside a narrow column or split pane). @default false\n */\n readonly responsive = input(false, { transform: coerceBooleanProperty });\n}\n","<div class=\"wr-toolbar__zone wr-toolbar__zone--start\">\n <ng-content select=\"[wrToolbarStart]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--center\">\n <ng-content select=\"[wrToolbarCenter]\" />\n</div>\n<div class=\"wr-toolbar__zone wr-toolbar__zone--end\">\n <ng-content select=\"[wrToolbarEnd]\" />\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;AAAA;;;;;AAKG;AAKH;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BG;MAOU,SAAS,CAAA;AACpB;;;;AAIG;IACM,UAAU,GAAG,KAAK,CAAC,KAAK,kFAAI,SAAS,EAAE,qBAAqB,EAAA,CAAG;uGAN7D,SAAS,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;AAAT,IAAA,OAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,SAAS,oWC7CtB,gVASA,EAAA,aAAA,EAAA,EAAA,CAAA,iBAAA,CAAA,IAAA,EAAA,CAAA;;2FDoCa,SAAS,EAAA,UAAA,EAAA,CAAA;kBANrB,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,YAAY,iBAEP,iBAAiB,CAAC,IAAI,EAAA,IAAA,EAC/B,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,gCAAgC,EAAE,cAAc,EAAE,EAAA,QAAA,EAAA,gVAAA,EAAA;;;AE3ClG;;AAEG;;;;"}
@@ -16,7 +16,7 @@ import { InjectionToken } from '@angular/core';
16
16
  * Distinct from `Version` exported by `@angular/core`, which reports the
17
17
  * loaded Angular runtime version (e.g. `'22.0.0'`), not ngwr's.
18
18
  */
19
- const NGWR_VERSION = '14.7.0';
19
+ const NGWR_VERSION = '14.8.0';
20
20
 
21
21
  /**
22
22
  * @license
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-version.mjs","sources":["../../../projects/lib/version/version.ts","../../../projects/lib/version/version.token.ts","../../../projects/lib/version/ngwr-version.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\n/**\n * The ngwr library version string, kept in sync with\n * `projects/lib/package.json` by `scripts/release-prepare.ts`.\n *\n * Prefer this over reading `package.json` at runtime — that requires a JSON\n * import or `require`, neither of which tree-shakes well in Angular builds.\n *\n * Distinct from `Version` exported by `@angular/core`, which reports the\n * loaded Angular runtime version (e.g. `'22.0.0'`), not ngwr's.\n */\nexport const NGWR_VERSION = '14.7.0';\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport { NGWR_VERSION } from './version';\n\n/**\n * Injection token holding the ngwr library version string.\n *\n * Default factory returns {@link NGWR_VERSION}. Override it in tests or in\n * apps that want to surface a custom build identifier.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class FooterComponent {\n * readonly version = inject(NGWR_VERSION_TOKEN);\n * }\n * ```\n */\nexport const NGWR_VERSION_TOKEN = new InjectionToken<string>('NGWR_VERSION_TOKEN', {\n providedIn: 'root',\n factory: () => NGWR_VERSION,\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAAA;;;;;AAKG;AAEH;;;;;;;;;AASG;AACI,MAAM,YAAY,GAAG;;ACjB5B;;;;;AAKG;AAMH;;;;;;;;;;;;;AAaG;MACU,kBAAkB,GAAG,IAAI,cAAc,CAAS,oBAAoB,EAAE;AACjF,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,YAAY;AAC5B,CAAA;;AC5BD;;AAEG;;;;"}
1
+ {"version":3,"file":"ngwr-version.mjs","sources":["../../../projects/lib/version/version.ts","../../../projects/lib/version/version.token.ts","../../../projects/lib/version/ngwr-version.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\n/**\n * The ngwr library version string, kept in sync with\n * `projects/lib/package.json` by `scripts/release-prepare.ts`.\n *\n * Prefer this over reading `package.json` at runtime — that requires a JSON\n * import or `require`, neither of which tree-shakes well in Angular builds.\n *\n * Distinct from `Version` exported by `@angular/core`, which reports the\n * loaded Angular runtime version (e.g. `'22.0.0'`), not ngwr's.\n */\nexport const NGWR_VERSION = '14.8.0';\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport { NGWR_VERSION } from './version';\n\n/**\n * Injection token holding the ngwr library version string.\n *\n * Default factory returns {@link NGWR_VERSION}. Override it in tests or in\n * apps that want to surface a custom build identifier.\n *\n * @example\n * ```ts\n * @Component({...})\n * export class FooterComponent {\n * readonly version = inject(NGWR_VERSION_TOKEN);\n * }\n * ```\n */\nexport const NGWR_VERSION_TOKEN = new InjectionToken<string>('NGWR_VERSION_TOKEN', {\n providedIn: 'root',\n factory: () => NGWR_VERSION,\n});\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;AAAA;;;;;AAKG;AAEH;;;;;;;;;AASG;AACI,MAAM,YAAY,GAAG;;ACjB5B;;;;;AAKG;AAMH;;;;;;;;;;;;;AAaG;MACU,kBAAkB,GAAG,IAAI,cAAc,CAAS,oBAAoB,EAAE;AACjF,IAAA,UAAU,EAAE,MAAM;AAClB,IAAA,OAAO,EAAE,MAAM,YAAY;AAC5B,CAAA;;AC5BD;;AAEG;;;;"}
@@ -88,6 +88,14 @@
88
88
  }
89
89
 
90
90
  // Visual states — invalid stripes the projected control too.
91
+ //
92
+ // The three combobox triggers are named one by one because each is a
93
+ // `<button>`, which the native selectors never reach. Only `wr-select`'s was
94
+ // listed, so a `wr-cascader` or an `openOn="overlay"` `wr-tree` in an invalid
95
+ // field announced `aria-invalid="true"` and kept its grey border. The property
96
+ // is set here rather than the component's border hook, the way the select's
97
+ // is, so the error edge holds while the trigger is focused or open — both of
98
+ // those set `border-color` directly and would otherwise paint it primary.
91
99
  // color-ok: `danger` against the default `--wr-color-outline` separates in
92
100
  // LIGHTNESS, not only in hue — 3.11:1 in light — so unlike two intents
93
101
  // compared with each other this survives greyscale, and the error MESSAGE
@@ -97,7 +105,9 @@
97
105
  &--invalid &__control select,
98
106
  &--invalid &__control .wr-input,
99
107
  &--invalid &__control .wr-textarea,
100
- &--invalid &__control .wr-select__trigger {
108
+ &--invalid &__control .wr-select__trigger,
109
+ &--invalid &__control .wr-cascader__trigger,
110
+ &--invalid &__control .wr-tree__trigger {
101
111
  border-color: var(--wr-color-danger);
102
112
  }
103
113
 
@@ -1,4 +1,5 @@
1
1
  @use '../../theme/styles' as theme;
2
+ @use '../../popover/styles'; // the `.wr-tooltip` chip the hover tooltip renders into
2
3
 
3
4
  .wr-gauge {
4
5
  display: inline-block;
package/i18n/ar.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "الحقول غير متطابقة.",
111
111
  "oneOf": "اختر إحدى القيم المسموح بها.",
112
112
  "minDate": "اختر تاريخًا لاحقًا.",
113
- "maxDate": "اختر تاريخًا سابقًا."
113
+ "maxDate": "اختر تاريخًا سابقًا.",
114
+ "dateFormat": "التنسيق المتوقع: {{example}}",
115
+ "dateFilter": "هذا التاريخ غير متاح."
114
116
  },
115
117
  "select": {
116
118
  "label": "اختيار",
package/i18n/cs.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "Tato pole se neshodují.",
111
111
  "oneOf": "Vyberte jednu z povolených hodnot.",
112
112
  "minDate": "Vyberte pozdější datum.",
113
- "maxDate": "Vyberte dřívější datum."
113
+ "maxDate": "Vyberte dřívější datum.",
114
+ "dateFormat": "Očekávaný formát: {{example}}",
115
+ "dateFilter": "Toto datum není k dispozici."
114
116
  },
115
117
  "select": {
116
118
  "label": "Vybrat",
package/i18n/de.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "Diese Felder stimmen nicht überein.",
111
111
  "oneOf": "Wählen Sie einen der zulässigen Werte.",
112
112
  "minDate": "Wählen Sie ein späteres Datum.",
113
- "maxDate": "Wählen Sie ein früheres Datum."
113
+ "maxDate": "Wählen Sie ein früheres Datum.",
114
+ "dateFormat": "Erwartetes Format: {{example}}",
115
+ "dateFilter": "Dieses Datum ist nicht verfügbar."
114
116
  },
115
117
  "select": {
116
118
  "label": "Auswahl",
package/i18n/en.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "These fields do not match.",
111
111
  "oneOf": "Choose one of the allowed values.",
112
112
  "minDate": "Choose a later date.",
113
- "maxDate": "Choose an earlier date."
113
+ "maxDate": "Choose an earlier date.",
114
+ "dateFormat": "Expected format: {{example}}",
115
+ "dateFilter": "This date is not available."
114
116
  },
115
117
  "select": {
116
118
  "label": "Select",
package/i18n/es.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "Los campos no coinciden.",
111
111
  "oneOf": "Debe ser uno de los valores permitidos.",
112
112
  "minDate": "La fecha debe ser posterior.",
113
- "maxDate": "La fecha debe ser anterior."
113
+ "maxDate": "La fecha debe ser anterior.",
114
+ "dateFormat": "Formato esperado: {{example}}",
115
+ "dateFilter": "Esta fecha no está disponible."
114
116
  },
115
117
  "select": {
116
118
  "label": "Seleccionar",
package/i18n/fr.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "Ces champs ne correspondent pas.",
111
111
  "oneOf": "Choisissez l'une des valeurs autorisées.",
112
112
  "minDate": "Choisissez une date ultérieure.",
113
- "maxDate": "Choisissez une date antérieure."
113
+ "maxDate": "Choisissez une date antérieure.",
114
+ "dateFormat": "Format attendu : {{example}}",
115
+ "dateFilter": "Cette date n'est pas disponible."
114
116
  },
115
117
  "select": {
116
118
  "label": "Sélectionner",
package/i18n/he.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "הערכים בשדות אינם זהים.",
111
111
  "oneOf": "יש לבחור אחד מהערכים המותרים.",
112
112
  "minDate": "יש לבחור תאריך מאוחר יותר.",
113
- "maxDate": "יש לבחור תאריך מוקדם יותר."
113
+ "maxDate": "יש לבחור תאריך מוקדם יותר.",
114
+ "dateFormat": "התבנית הנדרשת: {{example}}",
115
+ "dateFilter": "תאריך זה אינו זמין."
114
116
  },
115
117
  "select": {
116
118
  "label": "בחירה",
package/i18n/hi.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "ये फ़ील्ड मेल नहीं खाते।",
111
111
  "oneOf": "अनुमत मानों में से कोई एक चुनें।",
112
112
  "minDate": "इसके बाद की तारीख़ चुनें।",
113
- "maxDate": "इससे पहले की तारीख़ चुनें।"
113
+ "maxDate": "इससे पहले की तारीख़ चुनें।",
114
+ "dateFormat": "अपेक्षित फ़ॉर्मैट: {{example}}",
115
+ "dateFilter": "यह तारीख़ उपलब्ध नहीं है।"
114
116
  },
115
117
  "select": {
116
118
  "label": "चुनें",
package/i18n/id.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "Kolom-kolom ini tidak cocok.",
111
111
  "oneOf": "Pilih salah satu nilai yang diizinkan.",
112
112
  "minDate": "Pilih tanggal yang lebih baru.",
113
- "maxDate": "Pilih tanggal yang lebih awal."
113
+ "maxDate": "Pilih tanggal yang lebih awal.",
114
+ "dateFormat": "Format yang diharapkan: {{example}}",
115
+ "dateFilter": "Tanggal ini tidak tersedia."
114
116
  },
115
117
  "select": {
116
118
  "label": "Pilih",
package/i18n/it.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "I campi non coincidono.",
111
111
  "oneOf": "Scegli uno dei valori consentiti.",
112
112
  "minDate": "Scegli una data successiva.",
113
- "maxDate": "Scegli una data precedente."
113
+ "maxDate": "Scegli una data precedente.",
114
+ "dateFormat": "Formato previsto: {{example}}",
115
+ "dateFilter": "Questa data non è disponibile."
114
116
  },
115
117
  "select": {
116
118
  "label": "Seleziona",
package/i18n/ja.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "入力内容が一致しません。",
111
111
  "oneOf": "許可された値から選択してください。",
112
112
  "minDate": "これより後の日付を選択してください。",
113
- "maxDate": "これより前の日付を選択してください。"
113
+ "maxDate": "これより前の日付を選択してください。",
114
+ "dateFormat": "入力例:{{example}}",
115
+ "dateFilter": "この日付は選択できません。"
114
116
  },
115
117
  "select": {
116
118
  "label": "選択",
package/i18n/ko.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "입력한 항목이 서로 일치하지 않습니다.",
111
111
  "oneOf": "허용된 값 중 하나를 선택하세요.",
112
112
  "minDate": "더 늦은 날짜를 선택하세요.",
113
- "maxDate": "더 빠른 날짜를 선택하세요."
113
+ "maxDate": "더 빠른 날짜를 선택하세요.",
114
+ "dateFormat": "입력 형식: {{example}}",
115
+ "dateFilter": "이 날짜는 선택할 수 없습니다."
114
116
  },
115
117
  "select": {
116
118
  "label": "선택",
package/i18n/nl.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "Deze velden komen niet overeen.",
111
111
  "oneOf": "Kies een van de toegestane waarden.",
112
112
  "minDate": "Kies een latere datum.",
113
- "maxDate": "Kies een eerdere datum."
113
+ "maxDate": "Kies een eerdere datum.",
114
+ "dateFormat": "Verwachte notatie: {{example}}",
115
+ "dateFilter": "Deze datum is niet beschikbaar."
114
116
  },
115
117
  "select": {
116
118
  "label": "Selecteren",
package/i18n/pl.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "Pola nie są zgodne.",
111
111
  "oneOf": "Wybierz jedną z dozwolonych wartości.",
112
112
  "minDate": "Wybierz późniejszą datę.",
113
- "maxDate": "Wybierz wcześniejszą datę."
113
+ "maxDate": "Wybierz wcześniejszą datę.",
114
+ "dateFormat": "Oczekiwany format: {{example}}",
115
+ "dateFilter": "Ta data jest niedostępna."
114
116
  },
115
117
  "select": {
116
118
  "label": "Wybór",
package/i18n/pt.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "Estes campos não coincidem.",
111
111
  "oneOf": "Escolha um dos valores permitidos.",
112
112
  "minDate": "Escolha uma data posterior.",
113
- "maxDate": "Escolha uma data anterior."
113
+ "maxDate": "Escolha uma data anterior.",
114
+ "dateFormat": "Formato esperado: {{example}}",
115
+ "dateFilter": "Esta data não está disponível."
114
116
  },
115
117
  "select": {
116
118
  "label": "Selecionar",
package/i18n/ru.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "Значения полей не совпадают.",
111
111
  "oneOf": "Выберите одно из допустимых значений.",
112
112
  "minDate": "Выберите более позднюю дату.",
113
- "maxDate": "Выберите более раннюю дату."
113
+ "maxDate": "Выберите более раннюю дату.",
114
+ "dateFormat": "Ожидаемый формат: {{example}}",
115
+ "dateFilter": "Эта дата недоступна."
114
116
  },
115
117
  "select": {
116
118
  "label": "Выбрать",
package/i18n/sv.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "Fälten stämmer inte överens.",
111
111
  "oneOf": "Välj ett av de tillåtna värdena.",
112
112
  "minDate": "Välj ett senare datum.",
113
- "maxDate": "Välj ett tidigare datum."
113
+ "maxDate": "Välj ett tidigare datum.",
114
+ "dateFormat": "Förväntat format: {{example}}",
115
+ "dateFilter": "Det här datumet är inte tillgängligt."
114
116
  },
115
117
  "select": {
116
118
  "label": "Välj",
package/i18n/tr.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "Bu alanlar eşleşmiyor.",
111
111
  "oneOf": "İzin verilen değerlerden birini seçin.",
112
112
  "minDate": "Daha ileri bir tarih seçin.",
113
- "maxDate": "Daha erken bir tarih seçin."
113
+ "maxDate": "Daha erken bir tarih seçin.",
114
+ "dateFormat": "Beklenen biçim: {{example}}",
115
+ "dateFilter": "Bu tarih seçilemez."
114
116
  },
115
117
  "select": {
116
118
  "label": "Seçim",
package/i18n/uk.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "Значення полів не збігаються.",
111
111
  "oneOf": "Виберіть одне з допустимих значень.",
112
112
  "minDate": "Виберіть пізнішу дату.",
113
- "maxDate": "Виберіть ранішу дату."
113
+ "maxDate": "Виберіть ранішу дату.",
114
+ "dateFormat": "Очікуваний формат: {{example}}",
115
+ "dateFilter": "Ця дата недоступна."
114
116
  },
115
117
  "select": {
116
118
  "label": "Вибрати",
package/i18n/vi.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "Các trường này không khớp nhau.",
111
111
  "oneOf": "Chọn một trong các giá trị cho phép.",
112
112
  "minDate": "Chọn ngày muộn hơn.",
113
- "maxDate": "Chọn ngày sớm hơn."
113
+ "maxDate": "Chọn ngày sớm hơn.",
114
+ "dateFormat": "Định dạng cần nhập: {{example}}",
115
+ "dateFilter": "Không thể chọn ngày này."
114
116
  },
115
117
  "select": {
116
118
  "label": "Chọn",
package/i18n/zh-TW.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "這些欄位不相符。",
111
111
  "oneOf": "請從允許的值中選擇。",
112
112
  "minDate": "請選擇較晚的日期。",
113
- "maxDate": "請選擇較早的日期。"
113
+ "maxDate": "請選擇較早的日期。",
114
+ "dateFormat": "格式應為:{{example}}",
115
+ "dateFilter": "此日期無法選擇。"
114
116
  },
115
117
  "select": {
116
118
  "label": "選擇",
package/i18n/zh.json CHANGED
@@ -110,7 +110,9 @@
110
110
  "matchFields": "这些字段的值不一致。",
111
111
  "oneOf": "请从允许的值中选择。",
112
112
  "minDate": "请选择更晚的日期。",
113
- "maxDate": "请选择更早的日期。"
113
+ "maxDate": "请选择更早的日期。",
114
+ "dateFormat": "格式应为:{{example}}",
115
+ "dateFilter": "此日期不可选。"
114
116
  },
115
117
  "select": {
116
118
  "label": "选择",
@@ -188,7 +188,26 @@
188
188
  padding-inline-end: 0.25rem;
189
189
  }
190
190
 
191
+ // The toggle's flex item is its HOST, not the `<button>`. The group stretches
192
+ // the host to the field's height, but a blockified host lays the inline-flex
193
+ // button on a line box, at the top. That line box is a strut of the INHERITED
194
+ // line-height, so how far off it was depends on the page: on the showcase
195
+ // (15px text, 22.5px line-height) the eye sat 5.5px above the field's centre
196
+ // at md, 8.5px at lg and 12px at lg under `touch`, and an `sm` field was 24.5px
197
+ // instead of 22px; under a 32px line-height even an md field grew to 34px. A
198
+ // flex host has no line box, and its button stretches.
199
+ //
200
+ // `:not([hidden])`, because this is an author rule and the UA's
201
+ // `[hidden] { display: none }` is not: without it, `<wr-password-toggle
202
+ // [hidden]="…">` would stay on screen.
203
+ > wr-password-toggle:not([hidden]) {
204
+ display: flex;
205
+ }
206
+
191
207
  &__toggle {
208
+ // Stretched by the host above, so `align-items: center` below centres the
209
+ // glyph on the whole field rather than on the glyph's own height.
210
+ align-self: stretch;
192
211
  display: inline-flex;
193
212
  align-items: center;
194
213
  justify-content: center;
@@ -1,8 +1,23 @@
1
1
  @use '../../theme/styles' as theme;
2
2
 
3
3
  .wr-input-number {
4
+ // Width of the ▲ / ▼ glyph; its height is 0.6 of it, the proportion the
5
+ // markup's `10x6` always drew. It follows the control's size the way
6
+ // `--wr-btn-icon-size` does, because the column is one fixed-width strip
7
+ // whose height does not: at `sm` each half-button is 10px tall, and a
8
+ // chevron sized for `md` filled all but 2px of it.
9
+ --wr-input-number-step-icon-size: 0.625rem; // 10px
10
+
4
11
  display: inline-block;
5
12
 
13
+ &--sm {
14
+ --wr-input-number-step-icon-size: 0.5rem; // 8px
15
+ }
16
+
17
+ &--lg {
18
+ --wr-input-number-step-icon-size: 0.75rem; // 12px
19
+ }
20
+
6
21
  // Steppers live as a compact vertical column inside the suffix slot.
7
22
  // `<wr-input-group>` sets `pointer-events: none` on non-button affixes
8
23
  // (selector specificity 0,1,1 — class + `:not(element)`). We chain
@@ -79,6 +94,60 @@
79
94
  cursor: not-allowed;
80
95
  opacity: var(--wr-disabled-opacity);
81
96
  }
97
+
98
+ // CSS size, so it beats the markup's `width` / `height` attributes — which
99
+ // stay, as what an unstyled page draws instead of a 300x150 default.
100
+ svg {
101
+ width: var(--wr-input-number-step-icon-size);
102
+ height: calc(var(--wr-input-number-step-icon-size) * 0.6);
103
+ }
104
+ }
105
+
106
+ // A pill's end is a half-disc as tall as the field. The column itself fitted
107
+ // it — its start border sits 26px from the outer end, on the straight run
108
+ // before a curve 11–21.5px long, and its own end radius followed the arc — but
109
+ // the divider between ▲ and ▼ ran to the very tip of the curve, and the start
110
+ // border plus that divider cut the end cap into a separate square segment with
111
+ // the chevrons 7px from the end, inside the bend. Keeping the dividers and
112
+ // clearing the curve means insetting the column by the whole radius (18px at
113
+ // `lg`), which leaves an empty D-shaped cap after it. So the pill drops the
114
+ // dividers instead, and the pair sits inside the end the way the text sits
115
+ // inside the start.
116
+ &--rounded {
117
+ .wr-input-number__steppers.wr-input-group__affix {
118
+ border-inline-start: 0;
119
+ border-radius: 0;
120
+ overflow: visible;
121
+ // Half the pill's affix inset: added to the half-button's own slack around
122
+ // the glyph (7px at `md`), the chevrons end 14–16px from the border, where
123
+ // the field's text begins on the other side. It costs a pill 7px of
124
+ // minimum width (8px of margin, less the 1px border above). Padding the
125
+ // steps instead keeps the old width and leaves the chevrons 10–12px from
126
+ // the border.
127
+ margin-inline-end: calc(var(--wr-input-group-padding-x) / 2);
128
+ }
129
+
130
+ // With the column no longer clipping them, the hover and pressed tints need
131
+ // a shape of their own: a small-radius tint box reaches past the curved
132
+ // border at `lg` (measured with 5px corners: about 1px, 2px under `touch`).
133
+ // An oversized end radius is scaled down to the half-button's own height, so
134
+ // each tint ends in a quarter-disc that stays inside the curve and the pair
135
+ // reads as the pill's end cap.
136
+ .wr-input-number__step {
137
+ border-radius: 0;
138
+
139
+ &:first-child {
140
+ border-start-end-radius: 999px;
141
+ }
142
+
143
+ &:last-child {
144
+ border-end-end-radius: 999px;
145
+ }
146
+
147
+ & + .wr-input-number__step {
148
+ border-top: 0;
149
+ }
150
+ }
82
151
  }
83
152
 
84
153
  &--disabled {
@@ -34,15 +34,43 @@
34
34
  position: relative;
35
35
  }
36
36
 
37
- svg {
37
+ // The plot's drawing by its class, never a bare `svg`: the legend swatch is an
38
+ // `<svg>` too, and `.wr-line-chart svg` (0,1,1) outranks `&__swatch` (0,1,0), so
39
+ // the 1rem × 0.125rem dash stretched to the legend row — measured in Chromium at
40
+ // 337 × 44px, a solid bar across the series names it was meant to mark.
41
+ &__svg {
38
42
  display: block;
39
43
  width: 100%;
40
44
  height: 100%;
41
45
  }
42
46
 
47
+ // What the tooltip's `cqw` resolves against: the plot's width, which the drawing
48
+ // stretches to. On the plot itself the containment would take the SVG out of the
49
+ // chart's intrinsic width — measured in Chromium, a `width: max-content` chart went
50
+ // from 480px to 0 — while this layer is out of flow and contributes nothing either
51
+ // way. Never hittable: it covers the plot, and taking the `pointermove` would close
52
+ // the tooltip it holds.
53
+ &__tooltip-layer {
54
+ position: absolute;
55
+ inset: 0;
56
+ container-type: inline-size;
57
+ pointer-events: none;
58
+ }
59
+
43
60
  &__tooltip {
44
61
  position: absolute;
45
- transform: translate(-50%, 0.5rem);
62
+ // Centred on its point, but never past either end of the plot — the x labels' clamp:
63
+ // the shift is the smaller of half the box and the room actually left on that side,
64
+ // so a tooltip that fits sits exactly over its crosshair and only the ones near an
65
+ // end move inwards. Centred with nothing bounding it, the tooltip at the last point
66
+ // hung half its width past the chart — measured at 52px over the right edge in
67
+ // Chromium, cut off by any container that clips and a sideways scroll on a phone for
68
+ // any that does not.
69
+ // rtl-ok: the SVG's own x, and SVG coordinates do not flip with `direction`
70
+ transform: translate(
71
+ clamp(calc(var(--wr-line-chart-x, 50) * -1cqw), -50%, calc((100 - var(--wr-line-chart-x, 50)) * 1cqw - 100%)),
72
+ 0.5rem
73
+ );
46
74
  background: var(--wr-color-surface);
47
75
  border: 1px solid var(--wr-color-outline);
48
76
  border-radius: var(--wr-border-radius-base);
package/llms-full.txt CHANGED
@@ -261,8 +261,8 @@
261
261
  ## ngwr/date-picker
262
262
  - import: `import { WrDatePicker } from 'ngwr/date-picker'`
263
263
  - selector: `wr-date-picker`, `wr-date-range-picker`
264
- - exports: WrDatePicker, WrDateRangePicker, WrDateRange
265
- - Unified date / time / date-time picker. `<input>` + popover for every mode — overlay content swaps based on `[mode]`. Parses on every keystroke (silently — only emits when valid), reformats canonical on blur. Format driven by `WrDateAdapter`. A signal-forms native control — it implements `FormValueControl`, so `[formField]` binds straight to its `value` model. `[(value)]` works standalone, and `[(ngModel)]` / reactive forms keep working through [Angular 22's forms bridge](/guides/forms).
264
+ - exports: WrDatePicker, WrDateRangePicker, WrDateInputError, WrDateRange, WrDateRangeInputError
265
+ - Unified date / time / date-time picker. `<input>` + popover for every mode — overlay content swaps based on `[mode]`. Parses on every keystroke and emits only a date it can read and would accept; anything else is refused and shown as invalid, never guessed. Reformats canonical on blur. Format driven by `WrDateAdapter`. A signal-forms native control — it implements `FormValueControl`, so `[formField]` binds straight to its `value` model. `[(value)]` works standalone, and `[(ngModel)]` / reactive forms keep working through [Angular 22's forms bridge](/guides/forms).
266
266
 
267
267
  ## ngwr/date-picker/testing
268
268
  - import: `import { WrDatePickerDayHarness } from 'ngwr/date-picker/testing'`
@@ -756,7 +756,7 @@
756
756
  ## ngwr/popover
757
757
  - import: `import { WrPopover } from 'ngwr/popover'`
758
758
  - selector: `[wrPopover]`
759
- - exports: WrPopover, WrPopoverPosition
759
+ - exports: useChartTooltip, WrPopover, WrChartTooltip, WrChartTooltipDatum, WrChartTooltipTarget, WrPopoverPosition
760
760
  - Anchored content panel. Project a template (popover) or pass a plain string (tooltip — use `mode="tooltip"`). Click or hover to open; a tooltip also answers a keyboard focus. Built on CDK Overlay.
761
761
 
762
762
  ## ngwr/popover/testing
@@ -1,4 +1,5 @@
1
1
  @use '../../theme/styles' as theme;
2
+ @use '../../popover/styles'; // the `.wr-tooltip` chip the hover tooltip renders into
2
3
 
3
4
  .wr-meter-group {
4
5
  display: flex;
@@ -139,8 +139,15 @@ $placements: (
139
139
  /// turns the right border into the down-right face and the bottom one into the
140
140
  /// down-left face, so `right + bottom` is what outlines a tip pointing DOWN.
141
141
  /// Swapping only the inline half would paint two faces that are tucked under
142
- /// the panel. A mirrored arrow needs the rotation mirrored as well — more than
143
- /// a property rewrite, so it is left for the RTL pass that owns the TS side.
142
+ /// the panel.
143
+ ///
144
+ /// That is also why a side edge needs its own RTL rule, which `anchored-arrow`
145
+ /// emits. `at()` hangs the arrow off the panel's inline start or end, so under
146
+ /// `dir="rtl"` a `right`-placed panel carries it on its PHYSICAL right while
147
+ /// these faces still outline a tip pointing left — the two faces painted are
148
+ /// the ones inside the panel, drawn over its content as a chevron, and the tip
149
+ /// that does stick out has no outline. The top and bottom edges are symmetric
150
+ /// about the vertical axis and need nothing.
144
151
  @mixin faces($edge, $color) {
145
152
  @if $edge == bottom {
146
153
  // rtl-ok: down-right face of a 45°-rotated square — fixed by the rotation
@@ -239,5 +246,23 @@ $placements: (
239
246
  @include faces($edge, $border);
240
247
  }
241
248
  }
249
+
250
+ // A side edge under RTL: the arrow already sits on the mirrored side (`at()`
251
+ // is logical), so the outline moves to the mirrored faces — see `faces()`.
252
+ // Keyed on the `dir` the CDK writes on the pane's own host, as a CHILD
253
+ // combinator, rather than on any RTL ancestor: an overlay created `ltr` inside
254
+ // an `rtl` page lays out `ltr`, and a descendant match would outline it wrong.
255
+ @if $border != null and ($edge == left or $edge == right) {
256
+ $mirrored: left;
257
+
258
+ @if $edge == left {
259
+ $mirrored: right;
260
+ }
261
+
262
+ [dir='rtl'] > #{$pane}--#{$placement} #{$panel}::after {
263
+ border: 0;
264
+ @include faces($mirrored, $border);
265
+ }
266
+ }
242
267
  }
243
268
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ngwr",
3
- "version": "14.7.0",
3
+ "version": "14.8.0",
4
4
  "bin": {
5
5
  "ngwr-mcp": "mcp/server.js"
6
6
  },