@koobiq/components 20.0.0 → 20.1.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 (192) hide show
  1. package/accordion/accordion-trigger.component.scss +0 -18
  2. package/accordion/accordion.component.scss +9 -2
  3. package/actions-panel/index.d.ts +1 -0
  4. package/alert/_alert-theme.scss +0 -4
  5. package/alert/alert-tokens.scss +4 -4
  6. package/app-switcher/app-switcher-dropdown-app.scss +2 -0
  7. package/breadcrumbs/breadcrumbs.scss +4 -0
  8. package/breadcrumbs/index.d.ts +2 -1
  9. package/button/button-group.scss +42 -2
  10. package/button-toggle/button-toggle.scss +23 -0
  11. package/button-toggle/index.d.ts +3 -1
  12. package/checkbox/checkbox.scss +5 -4
  13. package/clamped-text/index.d.ts +1 -0
  14. package/core/index.d.ts +402 -13
  15. package/core/styles/common/_animation.scss +4 -0
  16. package/core/styles/theming/_components-theming.scss +1 -1
  17. package/core/styles/theming/_scrollbar-theme.scss +4 -0
  18. package/datepicker/_datepicker-theme.scss +1 -1
  19. package/datepicker/datepicker-toggle.scss +3 -3
  20. package/dl/index.d.ts +1 -0
  21. package/dropdown/dropdown.scss +2 -2
  22. package/fesm2022/koobiq-components-accordion.mjs +4 -4
  23. package/fesm2022/koobiq-components-accordion.mjs.map +1 -1
  24. package/fesm2022/koobiq-components-actions-panel.mjs +14 -5
  25. package/fesm2022/koobiq-components-actions-panel.mjs.map +1 -1
  26. package/fesm2022/koobiq-components-alert.mjs +2 -2
  27. package/fesm2022/koobiq-components-alert.mjs.map +1 -1
  28. package/fesm2022/koobiq-components-app-switcher.mjs +6 -6
  29. package/fesm2022/koobiq-components-app-switcher.mjs.map +1 -1
  30. package/fesm2022/koobiq-components-breadcrumbs.mjs +6 -4
  31. package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
  32. package/fesm2022/koobiq-components-button-toggle.mjs +9 -6
  33. package/fesm2022/koobiq-components-button-toggle.mjs.map +1 -1
  34. package/fesm2022/koobiq-components-button.mjs +4 -4
  35. package/fesm2022/koobiq-components-button.mjs.map +1 -1
  36. package/fesm2022/koobiq-components-checkbox.mjs +2 -2
  37. package/fesm2022/koobiq-components-checkbox.mjs.map +1 -1
  38. package/fesm2022/koobiq-components-clamped-text.mjs +4 -0
  39. package/fesm2022/koobiq-components-clamped-text.mjs.map +1 -1
  40. package/fesm2022/koobiq-components-code-block.mjs +4 -0
  41. package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
  42. package/fesm2022/koobiq-components-core.mjs +449 -112
  43. package/fesm2022/koobiq-components-core.mjs.map +1 -1
  44. package/fesm2022/koobiq-components-datepicker.mjs +5 -5
  45. package/fesm2022/koobiq-components-datepicker.mjs.map +1 -1
  46. package/fesm2022/koobiq-components-dl.mjs +3 -2
  47. package/fesm2022/koobiq-components-dl.mjs.map +1 -1
  48. package/fesm2022/koobiq-components-dropdown.mjs +8 -13
  49. package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
  50. package/fesm2022/koobiq-components-file-upload.mjs +33 -22
  51. package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
  52. package/fesm2022/koobiq-components-filter-bar.mjs +974 -758
  53. package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
  54. package/fesm2022/koobiq-components-flag.mjs +66 -0
  55. package/fesm2022/koobiq-components-flag.mjs.map +1 -0
  56. package/fesm2022/koobiq-components-form-field.mjs +2 -2
  57. package/fesm2022/koobiq-components-form-field.mjs.map +1 -1
  58. package/fesm2022/koobiq-components-icon.mjs +2 -2
  59. package/fesm2022/koobiq-components-icon.mjs.map +1 -1
  60. package/fesm2022/koobiq-components-inline-edit.mjs +27 -6
  61. package/fesm2022/koobiq-components-inline-edit.mjs.map +1 -1
  62. package/fesm2022/koobiq-components-list.mjs +39 -20
  63. package/fesm2022/koobiq-components-list.mjs.map +1 -1
  64. package/fesm2022/koobiq-components-loader-overlay.mjs +2 -2
  65. package/fesm2022/koobiq-components-loader-overlay.mjs.map +1 -1
  66. package/fesm2022/koobiq-components-modal.mjs +9 -5
  67. package/fesm2022/koobiq-components-modal.mjs.map +1 -1
  68. package/fesm2022/koobiq-components-navbar.mjs +10 -9
  69. package/fesm2022/koobiq-components-navbar.mjs.map +1 -1
  70. package/fesm2022/koobiq-components-notification-center.mjs +178 -19
  71. package/fesm2022/koobiq-components-notification-center.mjs.map +1 -1
  72. package/fesm2022/koobiq-components-overflow-items.mjs +12 -4
  73. package/fesm2022/koobiq-components-overflow-items.mjs.map +1 -1
  74. package/fesm2022/koobiq-components-popover.mjs +4 -4
  75. package/fesm2022/koobiq-components-popover.mjs.map +1 -1
  76. package/fesm2022/koobiq-components-progress-bar.mjs +2 -2
  77. package/fesm2022/koobiq-components-progress-bar.mjs.map +1 -1
  78. package/fesm2022/koobiq-components-progress-spinner.mjs +2 -2
  79. package/fesm2022/koobiq-components-progress-spinner.mjs.map +1 -1
  80. package/fesm2022/koobiq-components-radio.mjs +3 -7
  81. package/fesm2022/koobiq-components-radio.mjs.map +1 -1
  82. package/fesm2022/koobiq-components-select.mjs +38 -16
  83. package/fesm2022/koobiq-components-select.mjs.map +1 -1
  84. package/fesm2022/koobiq-components-sidebar.mjs +4 -0
  85. package/fesm2022/koobiq-components-sidebar.mjs.map +1 -1
  86. package/fesm2022/koobiq-components-sidepanel.mjs +3 -3
  87. package/fesm2022/koobiq-components-sidepanel.mjs.map +1 -1
  88. package/fesm2022/koobiq-components-skeleton.mjs +2 -2
  89. package/fesm2022/koobiq-components-skeleton.mjs.map +1 -1
  90. package/fesm2022/koobiq-components-split-button.mjs +2 -2
  91. package/fesm2022/koobiq-components-split-button.mjs.map +1 -1
  92. package/fesm2022/koobiq-components-splitter.mjs +6 -2
  93. package/fesm2022/koobiq-components-splitter.mjs.map +1 -1
  94. package/fesm2022/koobiq-components-table.mjs +8 -6
  95. package/fesm2022/koobiq-components-table.mjs.map +1 -1
  96. package/fesm2022/koobiq-components-tabs.mjs +19 -7
  97. package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
  98. package/fesm2022/koobiq-components-tags.mjs +7 -0
  99. package/fesm2022/koobiq-components-tags.mjs.map +1 -1
  100. package/fesm2022/koobiq-components-textarea.mjs +7 -14
  101. package/fesm2022/koobiq-components-textarea.mjs.map +1 -1
  102. package/fesm2022/koobiq-components-time-range.mjs +4 -4
  103. package/fesm2022/koobiq-components-time-range.mjs.map +1 -1
  104. package/fesm2022/koobiq-components-timezone.mjs +6 -0
  105. package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
  106. package/fesm2022/koobiq-components-title.mjs +132 -14
  107. package/fesm2022/koobiq-components-title.mjs.map +1 -1
  108. package/fesm2022/koobiq-components-toast.mjs +1 -1
  109. package/fesm2022/koobiq-components-toast.mjs.map +1 -1
  110. package/fesm2022/koobiq-components-toggle.mjs +2 -2
  111. package/fesm2022/koobiq-components-toggle.mjs.map +1 -1
  112. package/fesm2022/koobiq-components-tooltip.mjs +50 -2
  113. package/fesm2022/koobiq-components-tooltip.mjs.map +1 -1
  114. package/fesm2022/koobiq-components-tree-select.mjs +44 -11
  115. package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
  116. package/fesm2022/koobiq-components-tree.mjs +67 -41
  117. package/fesm2022/koobiq-components-tree.mjs.map +1 -1
  118. package/fesm2022/koobiq-components-username.mjs +16 -3
  119. package/fesm2022/koobiq-components-username.mjs.map +1 -1
  120. package/file-upload/file-upload-tokens.scss +1 -0
  121. package/file-upload/index.d.ts +10 -7
  122. package/filter-bar/_filter-bar-theme.scss +86 -0
  123. package/filter-bar/filter-bar-tokens.scss +6 -0
  124. package/filter-bar/filter-bar.scss +10 -4
  125. package/filter-bar/filter-refresher.scss +1 -1
  126. package/filter-bar/filters.scss +23 -19
  127. package/filter-bar/index.d.ts +707 -338
  128. package/filter-bar/pipes/base-pipe.scss +14 -35
  129. package/filter-bar/pipes/pipe-date.scss +20 -14
  130. package/filter-bar/pipes/pipe-multi-tree-select.scss +5 -3
  131. package/filter-bar/pipes/pipe-multiselect.scss +5 -3
  132. package/filter-bar/pipes/pipe-readonly.scss +4 -13
  133. package/filter-bar/pipes/pipe-select.scss +3 -1
  134. package/filter-bar/pipes/pipe-tree-select.scss +3 -1
  135. package/flag/flag.scss +53 -0
  136. package/flag/index.d.ts +44 -0
  137. package/icon/icon-item-tokens.scss +1 -1
  138. package/inline-edit/index.d.ts +5 -0
  139. package/inline-edit/inline-edit.scss +7 -7
  140. package/link/link-tokens.scss +2 -2
  141. package/list/index.d.ts +11 -2
  142. package/loader-overlay/loader-overlay-tokens.scss +1 -1
  143. package/modal/_modal-animation.scss +6 -6
  144. package/modal/_modal-theme.scss +5 -0
  145. package/modal/index.d.ts +3 -1
  146. package/modal/modal.scss +15 -0
  147. package/navbar/index.d.ts +1 -0
  148. package/navbar/navbar-item.scss +9 -0
  149. package/notification-center/_notification-center-theme.scss +2 -1
  150. package/notification-center/index.d.ts +88 -3
  151. package/notification-center/notification-center.scss +42 -4
  152. package/notification-center/notification-item.scss +3 -2
  153. package/overflow-items/index.d.ts +1 -0
  154. package/package.json +7 -3
  155. package/prebuilt-themes/dark-theme.css +1 -1
  156. package/prebuilt-themes/light-theme.css +1 -1
  157. package/prebuilt-themes/theme.css +1 -1
  158. package/progress-bar/progress-bar.scss +4 -0
  159. package/progress-spinner/progress-spinner.scss +5 -1
  160. package/radio/index.d.ts +1 -5
  161. package/radio/radio.scss +18 -4
  162. package/schematics/collection.json +5 -0
  163. package/schematics/migrations/filter-bar-signals/README.md +66 -0
  164. package/schematics/migrations/filter-bar-signals/data.js +72 -0
  165. package/schematics/migrations/filter-bar-signals/index.js +316 -0
  166. package/schematics/migrations/filter-bar-signals/schema.json +20 -0
  167. package/schematics/migrations.json +5 -0
  168. package/schematics/ng-add/index.js +1 -1
  169. package/select/index.d.ts +10 -2
  170. package/sidebar/index.d.ts +1 -0
  171. package/skeleton/skeleton.scss +4 -0
  172. package/split-button/_split-button-theme.scss +2 -2
  173. package/splitter/_splitter-theme.scss +2 -2
  174. package/splitter/index.d.ts +1 -0
  175. package/table/_table-theme.scss +4 -0
  176. package/table/index.d.ts +3 -2
  177. package/tabs/index.d.ts +2 -0
  178. package/tabs/tab-header.scss +1 -0
  179. package/tabs/tabs-tokens.scss +1 -1
  180. package/textarea/index.d.ts +0 -1
  181. package/time-range/time-range.scss +0 -8
  182. package/timepicker/timepicker.scss +2 -2
  183. package/timezone/index.d.ts +1 -0
  184. package/title/index.d.ts +92 -2
  185. package/tooltip/index.d.ts +51 -3
  186. package/tree/_tree-theme.scss +2 -7
  187. package/tree/index.d.ts +19 -4
  188. package/tree/toggle.scss +5 -0
  189. package/tree/tree-option.scss +0 -4
  190. package/tree-select/_tree-select-theme.scss +1 -1
  191. package/tree-select/index.d.ts +9 -2
  192. package/username/index.d.ts +20 -2
@@ -41,6 +41,11 @@
41
41
  "description": "Migrates deprecated API removed in @koobiq/components v20.0.0",
42
42
  "factory": "./migrations/v20-upgrade/index",
43
43
  "schema": "./migrations/v20-upgrade/schema.json"
44
+ },
45
+ "filter-bar-signals": {
46
+ "description": "Migrates KbqFilterBar consumers to the signal-based API (filter/pipeTemplates/isChanged/... reads become calls)",
47
+ "factory": "./migrations/filter-bar-signals/index",
48
+ "schema": "./migrations/filter-bar-signals/schema.json"
44
49
  }
45
50
  }
46
51
  }
@@ -0,0 +1,66 @@
1
+ # filter-bar-signals
2
+
3
+ Migration schematic invoked automatically by `ng update @koobiq/components@21`.
4
+ Migrates consumers of `KbqFilterBar` to its signal-based public API.
5
+
6
+ ## Why
7
+
8
+ `KbqFilterBar` moved several members from accessors/getters to signals. Reading
9
+ them programmatically now requires a call, and assigning `filter` now goes
10
+ through `.set(...)`. Template _bindings_ (`[filter]`, `[(filter)]`,
11
+ `[pipeTemplates]`) keep working — only reads break.
12
+
13
+ | Member | Before | After |
14
+ | --------------------------------------------------------------------------- | -------- | ----------------- |
15
+ | `filter` | accessor | `ModelSignal` |
16
+ | `pipeTemplates` | accessor | `InputSignal` |
17
+ | `isChanged` / `isDisabled` / `isReadOnly` / `isSaved` / `isSavedAndChanged` | getter | `Signal<boolean>` |
18
+
19
+ ## What it does
20
+
21
+ The schematic walks every `.ts` and `.html` file in the project (skipping
22
+ `node_modules` and `dist`) and, for files that reference the filter bar:
23
+
24
+ - **TypeScript reads/writes.** For a receiver whose static type is annotated
25
+ `KbqFilterBar` / `KbqFilterBarHost` (method/function params, class fields —
26
+ including `@ViewChild(KbqFilterBar) x: KbqFilterBar` and constructor
27
+ parameter-properties — and typed locals), a read of a signal member becomes a
28
+ call and a `filter` write becomes `.set(...)`:
29
+ - `filterBar.filter` → `filterBar.filter()` (incl. optional chain `filterBar.filter?.name` → `filterBar.filter()?.name`)
30
+ - `filterBar.filter = next` → `filterBar.filter.set(next)`
31
+ - `this.filterBar.isChanged` → `this.filterBar.isChanged()`
32
+ - **Template reference reads.** For a `#ref` bound to `<kbq-filter-bar>`, reads
33
+ of signal members through that ref are rewritten in the same template
34
+ (external `.html` and inline `template:` strings): `ref.isChanged` →
35
+ `ref.isChanged()`.
36
+ - **Rename.** `KbqFilterBarRefresher` → `KbqFilterRefresher` (the old name is
37
+ still re-exported as an alias, so this is optional cleanup).
38
+
39
+ All rewrites are idempotent — running twice does not double the call.
40
+
41
+ ## What it does _not_ do (warn-only)
42
+
43
+ Some changes require code restructuring and are surfaced as warnings without
44
+ auto-fixing:
45
+
46
+ | Pattern | Manual migration |
47
+ | -------------------------------- | -------------------------------------------------------------------------------------------------- |
48
+ | `.changes` (KbqFilterBar) | Deprecated no-op; read `filterBar.filter()` inside an `effect(...)`, or listen to `(filterChange)` |
49
+ | `.preparePopover()` (KbqFilters) | Removed; use `openSaveAsNewFilterPopover()` / `openChangeFilterNamePopover()` |
50
+ | `viewChild(KbqFilterBar)` query | Returns the instance, so reads are a double call: `this.filterBar().filter()` — verify manually |
51
+ | `KBQ_FILTER_BAR_PIPES` | Now typed `Map<KbqPipeType, Type<KbqBasePipe>>`; wrap direct providers in `new Map([...])` |
52
+
53
+ ## Running it manually
54
+
55
+ ```
56
+ ng generate @koobiq/components:filter-bar-signals --project my-app
57
+ ```
58
+
59
+ Pass `--fix=false` to see what would change without writing files.
60
+
61
+ ## Limitations
62
+
63
+ Receivers are matched by explicit `KbqFilterBar` type annotation only (no
64
+ cross-package type inference), so aliased/inferred receivers
65
+ (`const fb = this.filterBar; fb.filter`) are left untouched and covered by the
66
+ warnings above. After running, **always inspect the diff** before committing.
@@ -0,0 +1,72 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Data for the `filter-bar-signals` migration.
5
+ *
6
+ * `KbqFilterBar` moved several members from accessors/getters to signals. Reading them programmatically
7
+ * (in `.ts` code or via a template reference variable) now requires a call:
8
+ *
9
+ * - `filterBar.filter` → `filterBar.filter()` (write `= v` → `.set(v)`)
10
+ * - `filterBar.pipeTemplates` → `filterBar.pipeTemplates()`
11
+ * - `filterBar.isChanged` → `filterBar.isChanged()` (also isDisabled/isReadOnly/isSaved/isSavedAndChanged)
12
+ *
13
+ * Template *bindings* (`[filter]`, `[(filter)]`, `[pipeTemplates]`) keep working — only reads break.
14
+ */
15
+ /** Members of `KbqFilterBar` that became signals; a read of any of them must become a call. */
16
+ const SIGNAL_MEMBERS = [
17
+ 'filter',
18
+ 'pipeTemplates',
19
+ 'isChanged',
20
+ 'isDisabled',
21
+ 'isReadOnly',
22
+ 'isSaved',
23
+ 'isSavedAndChanged'
24
+ ];
25
+ /** Signal members that are writable (`model()`); `x.filter = v` migrates to `x.filter.set(v)`. */
26
+ const WRITABLE_MEMBERS = new Set(['filter']);
27
+ /** TypeScript type annotations that mark a receiver as a filter bar. */
28
+ const FILTER_BAR_TYPE = 'KbqFilterBar';
29
+ const FILTER_BAR_HOST_TYPE = 'KbqFilterBarHost';
30
+ /** Element selector whose template reference variables (`#ref`) point at a filter bar. */
31
+ const FILTER_BAR_ELEMENT = 'kbq-filter-bar';
32
+ /**
33
+ * Safe, idempotent identifier renames applied to `.ts` files. The `\b…\b` boundaries make each rule
34
+ * idempotent. `KbqFilterBarRefresher` is still re-exported as an alias of `KbqFilterRefresher`, so this
35
+ * is optional cleanup that can never break a consumer build.
36
+ */
37
+ const tsRenameReplacements = [{ from: '\\bKbqFilterBarRefresher\\b', to: 'KbqFilterRefresher' }];
38
+ /**
39
+ * Patterns that can't be auto-fixed reliably — surfaced with file locations (in both `fix` and dry-run
40
+ * mode). Only evaluated for files that reference the filter bar, so the broad `.changes` pattern stays scoped.
41
+ */
42
+ const warnPatterns = [
43
+ {
44
+ pattern: '\\.changes\\b',
45
+ message: 'KbqFilterBar.changes is deprecated and no longer emits. Reactivity is driven by the `filter` ' +
46
+ 'signal now — read it with `filterBar.filter()` inside an `effect(...)`, or listen to the ' +
47
+ '`(filterChange)` output. (Best-effort match — ignore if this `.changes` is unrelated.)'
48
+ },
49
+ {
50
+ pattern: '\\.preparePopover\\(',
51
+ message: 'KbqFilters.preparePopover() was removed. Use openSaveAsNewFilterPopover() / ' +
52
+ 'openChangeFilterNamePopover() instead.'
53
+ },
54
+ {
55
+ pattern: '(?:viewChild|ViewChild)[^\\n;]*\\bKbqFilterBar\\b',
56
+ message: 'A KbqFilterBar view/signal query returns the component instance, whose filter is now a signal — ' +
57
+ 'reading it is a double call, e.g. `this.filterBar().filter()`. Verify query reads manually.'
58
+ },
59
+ {
60
+ pattern: '\\bKBQ_FILTER_BAR_PIPES\\b',
61
+ message: 'KBQ_FILTER_BAR_PIPES is now typed as Map<KbqPipeType, Type<KbqBasePipe>> (was an array of tuples). ' +
62
+ 'If you provide it directly, wrap the entries in `new Map([...])`.'
63
+ }
64
+ ];
65
+
66
+ exports.FILTER_BAR_ELEMENT = FILTER_BAR_ELEMENT;
67
+ exports.FILTER_BAR_HOST_TYPE = FILTER_BAR_HOST_TYPE;
68
+ exports.FILTER_BAR_TYPE = FILTER_BAR_TYPE;
69
+ exports.SIGNAL_MEMBERS = SIGNAL_MEMBERS;
70
+ exports.WRITABLE_MEMBERS = WRITABLE_MEMBERS;
71
+ exports.tsRenameReplacements = tsRenameReplacements;
72
+ exports.warnPatterns = warnPatterns;
@@ -0,0 +1,316 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var ts = require('typescript');
6
+ var utils_ast = require('../../utils/ast.js');
7
+ var utils_messages = require('../../utils/messages.js');
8
+ var utils_packageConfig = require('../../utils/package-config.js');
9
+ var utils_typescript = require('../../utils/typescript.js');
10
+ var migrations_filterBarSignals_data = require('./data.js');
11
+ require('@angular-devkit/schematics');
12
+ require('@schematics/angular/utility');
13
+
14
+ const TS_EXT = '.ts';
15
+ const HTML_EXT = '.html';
16
+ function escapeRegExp(value) {
17
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
18
+ }
19
+ /** Applies text-span edits to `content`, right-to-left, so earlier edits don't shift later offsets. */
20
+ function applyEdits(content, edits) {
21
+ const sorted = [...edits].sort((a, b) => b.start - a.start || b.end - a.end);
22
+ let result = content;
23
+ for (const { start, end, text } of sorted) {
24
+ result = result.slice(0, start) + text + result.slice(end);
25
+ }
26
+ return result;
27
+ }
28
+ const isFunctionLike = (node) => ts.isFunctionDeclaration(node) ||
29
+ ts.isMethodDeclaration(node) ||
30
+ ts.isConstructorDeclaration(node) ||
31
+ ts.isArrowFunction(node) ||
32
+ ts.isFunctionExpression(node) ||
33
+ ts.isGetAccessorDeclaration(node) ||
34
+ ts.isSetAccessorDeclaration(node);
35
+ /** Walks up from `node` to the nearest ancestor matching `predicate`. */
36
+ function findAncestor(node, predicate) {
37
+ let current = node.parent;
38
+ while (current) {
39
+ if (predicate(current))
40
+ return current;
41
+ current = current.parent;
42
+ }
43
+ return undefined;
44
+ }
45
+ /** Whether a type annotation refers to the filter bar (`KbqFilterBar` / `KbqFilterBarHost`). */
46
+ function isFilterBarType(type) {
47
+ return (!!type &&
48
+ ts.isTypeReferenceNode(type) &&
49
+ ts.isIdentifier(type.typeName) &&
50
+ (type.typeName.text === migrations_filterBarSignals_data.FILTER_BAR_TYPE || type.typeName.text === migrations_filterBarSignals_data.FILTER_BAR_HOST_TYPE));
51
+ }
52
+ const FIELD_MODIFIERS = new Set([
53
+ ts.SyntaxKind.PrivateKeyword,
54
+ ts.SyntaxKind.PublicKeyword,
55
+ ts.SyntaxKind.ProtectedKeyword,
56
+ ts.SyntaxKind.ReadonlyKeyword
57
+ ]);
58
+ /**
59
+ * Collects the receivers whose static type is a filter bar, by explicit annotation only (no cross-package
60
+ * type resolution): method/function params, class fields (incl. `@ViewChild(KbqFilterBar) x: KbqFilterBar`
61
+ * and constructor parameter-properties) and typed locals.
62
+ */
63
+ function collectReceivers(sourceFile) {
64
+ const receivers = [];
65
+ const add = (text, scope) => receivers.push({ text, start: scope.getStart(sourceFile), end: scope.getEnd() });
66
+ const visit = (node) => {
67
+ if (ts.isParameter(node) && ts.isIdentifier(node.name) && isFilterBarType(node.type)) {
68
+ add(node.name.text, findAncestor(node, isFunctionLike) ?? sourceFile);
69
+ // A constructor parameter-property is also a class field, reachable as `this.<name>`.
70
+ if (node.modifiers?.some((modifier) => FIELD_MODIFIERS.has(modifier.kind))) {
71
+ const owner = findAncestor(node, ts.isClassDeclaration);
72
+ if (owner)
73
+ add(`this.${node.name.text}`, owner);
74
+ }
75
+ }
76
+ else if (ts.isPropertyDeclaration(node) && ts.isIdentifier(node.name) && isFilterBarType(node.type)) {
77
+ const owner = findAncestor(node, ts.isClassDeclaration);
78
+ if (owner)
79
+ add(`this.${node.name.text}`, owner);
80
+ }
81
+ else if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && isFilterBarType(node.type)) {
82
+ add(node.name.text, findAncestor(node, isFunctionLike) ?? sourceFile);
83
+ }
84
+ node.forEachChild(visit);
85
+ };
86
+ visit(sourceFile);
87
+ return receivers;
88
+ }
89
+ /** Classifies a matched property access and appends the resulting edit(s). */
90
+ function classifyAccess(node, sourceFile, edits) {
91
+ const parent = node.parent;
92
+ // Already migrated: `x.filter()` (call) or `x.filter.set(...)` — leave alone (idempotent).
93
+ if (ts.isCallExpression(parent) && parent.expression === node)
94
+ return;
95
+ if (ts.isPropertyAccessExpression(parent) && parent.expression === node && parent.name.text === 'set')
96
+ return;
97
+ // Write target: `x.filter = RHS` → `x.filter.set(RHS)` (writable members only).
98
+ if (ts.isBinaryExpression(parent) &&
99
+ parent.left === node &&
100
+ parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) {
101
+ if (migrations_filterBarSignals_data.WRITABLE_MEMBERS.has(node.name.text)) {
102
+ const rhs = parent.right;
103
+ // Replace ` = ` with `.set(` and close after the right-hand side; keeping the RHS span intact
104
+ // lets any nested read edits inside it still apply.
105
+ edits.push({ start: node.getEnd(), end: rhs.getStart(sourceFile), text: '.set(' });
106
+ edits.push({ start: rhs.getEnd(), end: rhs.getEnd(), text: ')' });
107
+ }
108
+ return;
109
+ }
110
+ // Read (incl. optional chain `x?.filter`): append `()`.
111
+ edits.push({ start: node.getEnd(), end: node.getEnd(), text: '()' });
112
+ }
113
+ /** Collects edits for every read/write of a signal member on a known filter-bar receiver. */
114
+ function collectAccessEdits(sourceFile, receivers) {
115
+ const edits = [];
116
+ const visit = (node) => {
117
+ if (ts.isPropertyAccessExpression(node) &&
118
+ ts.isIdentifier(node.name) &&
119
+ migrations_filterBarSignals_data.SIGNAL_MEMBERS.includes(node.name.text)) {
120
+ const receiverText = node.expression.getText(sourceFile);
121
+ const start = node.getStart(sourceFile);
122
+ const end = node.getEnd();
123
+ const inScope = receivers.some((r) => r.text === receiverText && start >= r.start && end <= r.end);
124
+ if (inScope)
125
+ classifyAccess(node, sourceFile, edits);
126
+ }
127
+ node.forEachChild(visit);
128
+ };
129
+ visit(sourceFile);
130
+ return edits;
131
+ }
132
+ /** Pass A — rewrite programmatic reads/writes of filter-bar signal members in TypeScript code. */
133
+ function migrateTsExpressions(content, fileName) {
134
+ const sourceFile = ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
135
+ const receivers = collectReceivers(sourceFile);
136
+ if (receivers.length === 0)
137
+ return content;
138
+ const edits = collectAccessEdits(sourceFile, receivers);
139
+ return edits.length > 0 ? applyEdits(content, edits) : content;
140
+ }
141
+ /** Collects template reference variable names bound to a `<kbq-filter-bar>` element. */
142
+ class FilterBarRefCollector {
143
+ constructor() {
144
+ this.refs = new Set();
145
+ }
146
+ visitElement(element) {
147
+ if (element.name === migrations_filterBarSignals_data.FILTER_BAR_ELEMENT) {
148
+ for (const attr of element.attrs ?? []) {
149
+ if (typeof attr.name !== 'string')
150
+ continue;
151
+ if (attr.name.startsWith('#'))
152
+ this.refs.add(attr.name.slice(1));
153
+ else if (attr.name.startsWith('ref-'))
154
+ this.refs.add(attr.name.slice(4));
155
+ }
156
+ }
157
+ this.visitChildren(element);
158
+ }
159
+ visitBlock(block) {
160
+ this.visitChildren(block);
161
+ }
162
+ visitChildren(node) {
163
+ for (const child of node.children ?? []) {
164
+ child.visit(this);
165
+ }
166
+ }
167
+ visitAttribute() { }
168
+ visitText() { }
169
+ visitComment() { }
170
+ visitExpansion() { }
171
+ visitExpansionCase() { }
172
+ visitBlockParameter() { }
173
+ visitLetDeclaration() { }
174
+ }
175
+ /** Rewrites `ref.member` reads to `ref.member()` for the given refs, scoped to those exact identifiers. */
176
+ function rewriteRefReads(template, refs) {
177
+ const members = migrations_filterBarSignals_data.SIGNAL_MEMBERS.join('|');
178
+ let content = template;
179
+ let changed = false;
180
+ for (const ref of refs) {
181
+ // `\bref\.(member)\b(?!\s*\()` — skip anything already invoked, so the rewrite is idempotent.
182
+ const pattern = new RegExp(`\\b(${escapeRegExp(ref)})\\.(${members})\\b(?!\\s*\\()`, 'g');
183
+ const next = content.replace(pattern, '$1.$2()');
184
+ if (next !== content) {
185
+ content = next;
186
+ changed = true;
187
+ }
188
+ }
189
+ return { content, changed };
190
+ }
191
+ /** Pass B (core) — parse a template, discover filter-bar refs, rewrite their signal reads. */
192
+ async function migrateTemplate(template) {
193
+ if (!template.includes(migrations_filterBarSignals_data.FILTER_BAR_ELEMENT))
194
+ return { content: template, changed: false };
195
+ const parsed = await utils_typescript.parseTemplate(template);
196
+ if (!parsed.tree)
197
+ return { content: template, changed: false };
198
+ const collector = new FilterBarRefCollector();
199
+ utils_ast.visitAll(collector, parsed.tree.rootNodes);
200
+ if (collector.refs.size === 0)
201
+ return { content: template, changed: false };
202
+ return rewriteRefReads(template, [...collector.refs]);
203
+ }
204
+ /** Interior `[start, end]` ranges of inline `@Component({ template: '…' })` string literals. */
205
+ function collectInlineTemplateRanges(sourceFile) {
206
+ const ranges = [];
207
+ utils_typescript.forEachClass(sourceFile, (node) => {
208
+ const decorator = ts
209
+ .getDecorators(node)
210
+ ?.find((dec) => ts.isCallExpression(dec.expression) &&
211
+ ts.isIdentifier(dec.expression.expression) &&
212
+ dec.expression.expression.text === 'Component');
213
+ if (!decorator || !ts.isCallExpression(decorator.expression))
214
+ return;
215
+ const [arg] = decorator.expression.arguments;
216
+ if (!arg || !ts.isObjectLiteralExpression(arg))
217
+ return;
218
+ for (const prop of arg.properties) {
219
+ if (ts.isPropertyAssignment(prop) &&
220
+ (ts.isIdentifier(prop.name) || ts.isStringLiteralLike(prop.name)) &&
221
+ prop.name.text === 'template' &&
222
+ ts.isStringLiteralLike(prop.initializer) &&
223
+ prop.initializer.text) {
224
+ // +1 / -1 to exclude the opening/closing quote characters.
225
+ ranges.push({ start: prop.initializer.getStart(sourceFile) + 1, end: prop.initializer.getEnd() - 1 });
226
+ }
227
+ }
228
+ });
229
+ return ranges;
230
+ }
231
+ /** Pass B (inline) — rewrite filter-bar ref reads inside inline component templates. */
232
+ async function migrateInlineTemplates(content, fileName) {
233
+ const sourceFile = ts.createSourceFile(fileName, content, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
234
+ const ranges = collectInlineTemplateRanges(sourceFile).sort((a, b) => b.start - a.start);
235
+ let result = content;
236
+ for (const { start, end } of ranges) {
237
+ const { content: rewritten, changed } = await migrateTemplate(result.slice(start, end));
238
+ if (changed) {
239
+ result = result.slice(0, start) + rewritten + result.slice(end);
240
+ }
241
+ }
242
+ return result;
243
+ }
244
+ /** Pass C — safe identifier renames. */
245
+ function applyRenames(content) {
246
+ let result = content;
247
+ for (const { from, to } of migrations_filterBarSignals_data.tsRenameReplacements) {
248
+ result = result.replace(new RegExp(from, 'g'), to);
249
+ }
250
+ return result;
251
+ }
252
+ function logWarnings(context, filePath, content) {
253
+ for (const { pattern, message } of migrations_filterBarSignals_data.warnPatterns) {
254
+ if (new RegExp(pattern).test(content)) {
255
+ utils_messages.logMessage(context.logger, [`[filter-bar-signals] ${filePath}`, ` ${message}`]);
256
+ }
257
+ }
258
+ }
259
+ /** A `.ts` file is a filter-bar consumer if it names the type or imports the package. */
260
+ function referencesFilterBar(content) {
261
+ return /\bKbqFilterBar\b/.test(content) || content.includes('@koobiq/components/filter-bar');
262
+ }
263
+ function filterBarSignals(options) {
264
+ return async (tree, context) => {
265
+ const { project, fix } = options;
266
+ const projectDefinition = await utils_packageConfig.setupOptions(project, tree);
267
+ const root = projectDefinition?.root ?? '';
268
+ const rootDir = root ? tree.getDir(root) : tree.root;
269
+ const tsPaths = [];
270
+ const htmlPaths = [];
271
+ rootDir.visit((filePath) => {
272
+ if (filePath.includes('node_modules') || filePath.includes('/dist/'))
273
+ return;
274
+ if (filePath.endsWith(TS_EXT))
275
+ tsPaths.push(filePath);
276
+ else if (filePath.endsWith(HTML_EXT))
277
+ htmlPaths.push(filePath);
278
+ });
279
+ let touched = 0;
280
+ const commit = (filePath, original, updated) => {
281
+ if (updated === original)
282
+ return;
283
+ touched++;
284
+ if (fix) {
285
+ tree.overwrite(filePath, updated);
286
+ }
287
+ else {
288
+ utils_messages.logMessage(context.logger, [`[filter-bar-signals] would update ${filePath} (run with --fix to apply)`]);
289
+ }
290
+ };
291
+ for (const filePath of tsPaths) {
292
+ const original = tree.read(filePath)?.toString();
293
+ if (!original || !referencesFilterBar(original))
294
+ continue;
295
+ logWarnings(context, filePath, original);
296
+ let content = migrateTsExpressions(original, filePath);
297
+ content = await migrateInlineTemplates(content, filePath);
298
+ content = applyRenames(content);
299
+ commit(filePath, original, content);
300
+ }
301
+ for (const filePath of htmlPaths) {
302
+ const original = tree.read(filePath)?.toString();
303
+ if (!original)
304
+ continue;
305
+ const { content, changed } = await migrateTemplate(original);
306
+ if (changed)
307
+ commit(filePath, original, content);
308
+ }
309
+ utils_messages.logMessage(context.logger, [
310
+ `[filter-bar-signals] processed tree under "${root || '<workspace root>'}", ` +
311
+ `${fix ? 'updated' : 'would update'} ${touched} file(s).`
312
+ ]);
313
+ };
314
+ }
315
+
316
+ exports.default = filterBarSignals;
@@ -0,0 +1,20 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "$id": "koobiq-components-filter-bar-signals",
4
+ "title": "Koobiq components filter-bar signals migration",
5
+ "type": "object",
6
+ "properties": {
7
+ "project": {
8
+ "type": "string",
9
+ "description": "Name of the project to migrate. If omitted, the migration runs over the whole tree.",
10
+ "$default": {
11
+ "$source": "projectName"
12
+ }
13
+ },
14
+ "fix": {
15
+ "type": "boolean",
16
+ "default": true,
17
+ "description": "When true, applies all auto-fix replacements. When false, prints what would change without writing."
18
+ }
19
+ }
20
+ }
@@ -5,6 +5,11 @@
5
5
  "version": "20.0.0-0",
6
6
  "description": "Migrates code from deprecated APIs removed in @koobiq/components v20.0.0. Handles package moves (@koobiq/cdk/{a11y,keycodes,testing} → @koobiq/components/core, navbar-ic, risk-level, experimental form-field), TypeScript identifier renames, template selector renames (e.g. <kbq-filter-search> → <kbq-search-expandable>, <kbq-datepicker-toggle> → <kbq-datepicker-toggle-icon>), attribute renames (kbqFormFieldWithoutBorders → noBorders), tooltip modifier inputs, and emits warnings for structural changes that need manual migration (onSaveAsNew, file-upload customValidation/errors, app-switcher apps).",
7
7
  "factory": "./migrations/v20-upgrade/index"
8
+ },
9
+ "filter-bar-signals": {
10
+ "version": "21.0.0-0",
11
+ "description": "Migrates KbqFilterBar consumers to the signal-based API. Rewrites programmatic reads of the now-signal members (filter, pipeTemplates, isChanged, isDisabled, isReadOnly, isSaved, isSavedAndChanged) to calls and `filter = v` writes to `filter.set(v)` on receivers typed KbqFilterBar, including reads via template reference variables on <kbq-filter-bar>. Renames KbqFilterBarRefresher → KbqFilterRefresher and warns on changes/preparePopover/view-query cases that need manual migration.",
12
+ "factory": "./migrations/filter-bar-signals/index"
8
13
  }
9
14
  }
10
15
  }
@@ -27,7 +27,7 @@ function ngAdd(options) {
27
27
  }
28
28
  // Installing dependencies
29
29
  utils_packageConfig.addPackageToPackageJson(tree, '@angular/cdk', "^20.2.14");
30
- utils_packageConfig.addPackageToPackageJson(tree, '@koobiq/angular-luxon-adapter', "^20.0.0");
30
+ utils_packageConfig.addPackageToPackageJson(tree, '@koobiq/angular-luxon-adapter', "^20.1.0");
31
31
  utils_packageConfig.addPackageToPackageJson(tree, '@koobiq/date-formatter', "^3.5.1");
32
32
  utils_packageConfig.addPackageToPackageJson(tree, '@koobiq/date-adapter', "^3.5.1");
33
33
  utils_packageConfig.addPackageToPackageJson(tree, '@koobiq/icons', "^11.7.1");
package/select/index.d.ts CHANGED
@@ -9,7 +9,7 @@ import { ConnectedPosition, CdkConnectedOverlay, CdkOverlayOrigin } from '@angul
9
9
  import { CdkVirtualForOf, CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
10
10
  import { ControlValueAccessor, NgForm, FormGroupDirective, NgControl } from '@angular/forms';
11
11
  import * as i2 from '@koobiq/components/core';
12
- import { KbqAbstractSelect, CanUpdateErrorState, ErrorStateMatcher, KbqLocaleService, KbqOptionBase, ActiveDescendantKeyManager, KbqOption, KbqSelectTrigger, KbqSelectMatcher, KbqOptgroup, KbqSelectSearch, KbqSelectSearchEmptyResult, KbqOptionSelectionChange, KbqVirtualOption, KbqComponentColors } from '@koobiq/components/core';
12
+ import { KbqAbstractSelect, CanUpdateErrorState, ErrorStateMatcher, KbqLocaleService, KbqOptionBase, ActiveDescendantKeyManager, KbqOption, KbqSelectTrigger, KbqSelectMatcher, KbqOptgroup, KbqSelectSearch, KbqSelectSearchEmptyResult, KbqOptionSelectionChange, KbqSelectAllEvent, KbqVirtualOption, KbqComponentColors } from '@koobiq/components/core';
13
13
  import * as i11 from '@koobiq/components/form-field';
14
14
  import { KbqFormFieldControl, KbqCleaner } from '@koobiq/components/form-field';
15
15
  import * as i4 from '@koobiq/components/tags';
@@ -53,6 +53,7 @@ declare class KbqOptionTooltip extends KbqTooltipTrigger implements AfterViewIni
53
53
  private readonly option;
54
54
  private readonly resizeObserver;
55
55
  private readonly contentObserver;
56
+ private readonly isBrowser;
56
57
  private readonly debounceInterval;
57
58
  private resizeSubscription;
58
59
  private contentObserverSubscription;
@@ -283,6 +284,11 @@ declare class KbqSelect extends KbqAbstractSelect implements AfterContentInit, O
283
284
  readonly closedStream: Observable<void>;
284
285
  /** Event emitted when the selected value has been changed by the user. */
285
286
  readonly selectionChange: _angular_core.OutputEmitterRef<KbqSelectChange>;
287
+ /**
288
+ * Event emitted when all options are selected or deselected via the Ctrl/Cmd + A shortcut.
289
+ * Not emitted when a custom `selectAllHandler` is supplied — the handler owns the behaviour then.
290
+ */
291
+ readonly onSelectAll: _angular_core.OutputEmitterRef<KbqSelectAllEvent<KbqOption, KbqSelect>>;
286
292
  /**
287
293
  * Event that emits whenever the raw value of the select changes. This is here primarily
288
294
  * to facilitate the two-way binding for the `value` input.
@@ -346,6 +352,8 @@ declare class KbqSelect extends KbqAbstractSelect implements AfterContentInit, O
346
352
  * for primitive values where `value` itself is the display label.
347
353
  */
348
354
  readonly virtualOptionFactory: _angular_core.InputSignal<((value: any) => KbqVirtualOption) | undefined>;
355
+ /** When `true`, a repeated Ctrl/Cmd+A deselects all options. Off by default (Ctrl+A only selects). */
356
+ readonly selectAllToggle: _angular_core.InputSignalWithTransform<boolean, unknown>;
349
357
  /**
350
358
  * Function for handling the Ctrl + A (select all) keyboard combination.
351
359
  * By default, the internal handler selects all options.
@@ -676,7 +684,7 @@ declare class KbqSelect extends KbqAbstractSelect implements AfterContentInit, O
676
684
  /** Removes the dropdown class from the overlay container when select closes. */
677
685
  private removeClassFromOverlayContainer;
678
686
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<KbqSelect, never>;
679
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<KbqSelect, "kbq-select", ["kbqSelect"], { "hiddenItemsText": { "alias": "hiddenItemsText"; "required": false; }; "showPreselectedValues": { "alias": "showPreselectedValues"; "required": false; "isSignal": true; }; "triggerValuesLimit": { "alias": "triggerValuesLimit"; "required": false; "isSignal": true; }; "panelClass": { "alias": "panelClass"; "required": false; "isSignal": true; }; "backdropClass": { "alias": "backdropClass"; "required": false; "isSignal": true; }; "errorStateMatcher": { "alias": "errorStateMatcher"; "required": false; }; "sortComparator": { "alias": "sortComparator"; "required": false; "isSignal": true; }; "multiline": { "alias": "multiline"; "required": false; "isSignal": true; }; "searchMinOptionsThreshold": { "alias": "searchMinOptionsThreshold"; "required": false; }; "scrolledToBottomOffset": { "alias": "scrolledToBottomOffset"; "required": false; "isSignal": true; }; "hasBackdrop": { "alias": "hasBackdrop"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "required": { "alias": "required"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "compareWith": { "alias": "compareWith"; "required": false; }; "virtualOptionFactory": { "alias": "virtualOptionFactory"; "required": false; "isSignal": true; }; "selectAllHandler": { "alias": "selectAllHandler"; "required": false; }; "panelWidth": { "alias": "panelWidth"; "required": false; }; "panelMinWidth": { "alias": "panelMinWidth"; "required": false; }; "value": { "alias": "value"; "required": false; }; "id": { "alias": "id"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "hiddenItemsTextFormatter": { "alias": "hiddenItemsTextFormatter"; "required": false; }; }, { "openedChange": "openedChange"; "beforeOpened": "beforeOpened"; "openedStream": "opened"; "closedStream": "closed"; "selectionChange": "selectionChange"; "valueChange": "valueChange"; "scrolledToBottom": "scrolledToBottom"; }, ["footer", "cdkVirtualForOf", "virtualScrollViewport", "customTrigger", "customMatcher", "customTagTemplateRef", "cleaner", "optionGroups", "search", "searchEmpty", "options"], ["kbq-select-matcher, [kbq-select-matcher]", "kbq-select-trigger, [kbq-select-trigger]", "kbq-cleaner", "[kbqSelectSearch]", "[kbq-select-search-empty-result]", "*", "kbq-select-footer,[kbq-select-footer]"], true, never>;
687
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<KbqSelect, "kbq-select", ["kbqSelect"], { "hiddenItemsText": { "alias": "hiddenItemsText"; "required": false; }; "showPreselectedValues": { "alias": "showPreselectedValues"; "required": false; "isSignal": true; }; "triggerValuesLimit": { "alias": "triggerValuesLimit"; "required": false; "isSignal": true; }; "panelClass": { "alias": "panelClass"; "required": false; "isSignal": true; }; "backdropClass": { "alias": "backdropClass"; "required": false; "isSignal": true; }; "errorStateMatcher": { "alias": "errorStateMatcher"; "required": false; }; "sortComparator": { "alias": "sortComparator"; "required": false; "isSignal": true; }; "multiline": { "alias": "multiline"; "required": false; "isSignal": true; }; "searchMinOptionsThreshold": { "alias": "searchMinOptionsThreshold"; "required": false; }; "scrolledToBottomOffset": { "alias": "scrolledToBottomOffset"; "required": false; "isSignal": true; }; "hasBackdrop": { "alias": "hasBackdrop"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "required": { "alias": "required"; "required": false; }; "multiple": { "alias": "multiple"; "required": false; }; "compareWith": { "alias": "compareWith"; "required": false; }; "virtualOptionFactory": { "alias": "virtualOptionFactory"; "required": false; "isSignal": true; }; "selectAllToggle": { "alias": "selectAllToggle"; "required": false; "isSignal": true; }; "selectAllHandler": { "alias": "selectAllHandler"; "required": false; }; "panelWidth": { "alias": "panelWidth"; "required": false; }; "panelMinWidth": { "alias": "panelMinWidth"; "required": false; }; "value": { "alias": "value"; "required": false; }; "id": { "alias": "id"; "required": false; }; "tabIndex": { "alias": "tabIndex"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "hiddenItemsTextFormatter": { "alias": "hiddenItemsTextFormatter"; "required": false; }; }, { "openedChange": "openedChange"; "beforeOpened": "beforeOpened"; "openedStream": "opened"; "closedStream": "closed"; "selectionChange": "selectionChange"; "onSelectAll": "onSelectAll"; "valueChange": "valueChange"; "scrolledToBottom": "scrolledToBottom"; }, ["footer", "cdkVirtualForOf", "virtualScrollViewport", "customTrigger", "customMatcher", "customTagTemplateRef", "cleaner", "optionGroups", "search", "searchEmpty", "options"], ["kbq-select-matcher, [kbq-select-matcher]", "kbq-select-trigger, [kbq-select-trigger]", "kbq-cleaner", "[kbqSelectSearch]", "[kbq-select-search-empty-result]", "*", "kbq-select-footer,[kbq-select-footer]"], true, never>;
680
688
  static ngAcceptInputType_multiple: unknown;
681
689
  static ngAcceptInputType_panelMinWidth: unknown;
682
690
  static ngAcceptInputType_tabIndex: unknown;
@@ -37,6 +37,7 @@ declare class KbqSidebar implements OnDestroy, AfterContentInit {
37
37
  protected readonly document: Document;
38
38
  private readonly renderer;
39
39
  private readonly changeDetectorRef;
40
+ private readonly isBrowser;
40
41
  get opened(): boolean;
41
42
  set opened(value: boolean);
42
43
  private _opened;
@@ -52,5 +52,9 @@
52
52
  var(--kbq-skeleton-animation-wave-end) 100%
53
53
  );
54
54
  animation: wave var(--kbq-skeleton-animation-duration) ease-in var(--kbq-skeleton-animation-delay) infinite;
55
+
56
+ @media (prefers-reduced-motion: reduce) {
57
+ animation: none;
58
+ }
55
59
  }
56
60
  }
@@ -1,7 +1,7 @@
1
1
  @mixin kbq-split-button-theme() {
2
2
  .kbq-split-button {
3
3
  &:hover:has(.kbq-button_transparent) {
4
- background: var(--kbq-states-background-transparent-hover, rgba(108, 115, 147, 0.08));
4
+ background: var(--kbq-states-background-transparent-hover);
5
5
  }
6
6
 
7
7
  & .kbq-split-button_item {
@@ -102,7 +102,7 @@
102
102
  }
103
103
 
104
104
  & .kbq-split-button_second:before {
105
- background: rgba(138, 143, 168, 0.6);
105
+ background: var(--kbq-states-line-disabled);
106
106
  }
107
107
  }
108
108
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  &:hover,
8
8
  &.kbq-gutter_dragged {
9
- background-color: rgba(106, 115, 150, 0.08);
9
+ background-color: var(--kbq-states-background-transparent-hover);
10
10
  }
11
11
 
12
12
  &.kbq-gutter_vertical {
@@ -21,6 +21,6 @@
21
21
  }
22
22
 
23
23
  .kbq-gutter-ghost {
24
- background: rgba(106, 115, 150, 0.16);
24
+ background: var(--kbq-states-background-transparent-active);
25
25
  }
26
26
  }
@@ -112,6 +112,7 @@ declare class KbqSplitterAreaDirective implements AfterViewInit, OnDestroy {
112
112
  private splitter;
113
113
  readonly sizeChange: i0.OutputEmitterRef<number>;
114
114
  private readonly window;
115
+ private readonly platform;
115
116
  isResizing(): boolean;
116
117
  disableFlex(): void;
117
118
  ngAfterViewInit(): void;
@@ -16,7 +16,11 @@
16
16
  & > td {
17
17
  color: var(--kbq-foreground-contrast);
18
18
  }
19
+ }
20
+ }
19
21
 
22
+ &:not(.kbq-table_disable-hover) > tbody {
23
+ & > tr {
20
24
  &.kbq-hovered td,
21
25
  &:hover td {
22
26
  background-color: var(--kbq-states-background-transparent-hover);