@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.
- package/accordion/accordion-trigger.component.scss +0 -18
- package/accordion/accordion.component.scss +9 -2
- package/actions-panel/index.d.ts +1 -0
- package/alert/_alert-theme.scss +0 -4
- package/alert/alert-tokens.scss +4 -4
- package/app-switcher/app-switcher-dropdown-app.scss +2 -0
- package/breadcrumbs/breadcrumbs.scss +4 -0
- package/breadcrumbs/index.d.ts +2 -1
- package/button/button-group.scss +42 -2
- package/button-toggle/button-toggle.scss +23 -0
- package/button-toggle/index.d.ts +3 -1
- package/checkbox/checkbox.scss +5 -4
- package/clamped-text/index.d.ts +1 -0
- package/core/index.d.ts +402 -13
- package/core/styles/common/_animation.scss +4 -0
- package/core/styles/theming/_components-theming.scss +1 -1
- package/core/styles/theming/_scrollbar-theme.scss +4 -0
- package/datepicker/_datepicker-theme.scss +1 -1
- package/datepicker/datepicker-toggle.scss +3 -3
- package/dl/index.d.ts +1 -0
- package/dropdown/dropdown.scss +2 -2
- package/fesm2022/koobiq-components-accordion.mjs +4 -4
- package/fesm2022/koobiq-components-accordion.mjs.map +1 -1
- package/fesm2022/koobiq-components-actions-panel.mjs +14 -5
- package/fesm2022/koobiq-components-actions-panel.mjs.map +1 -1
- package/fesm2022/koobiq-components-alert.mjs +2 -2
- package/fesm2022/koobiq-components-alert.mjs.map +1 -1
- package/fesm2022/koobiq-components-app-switcher.mjs +6 -6
- package/fesm2022/koobiq-components-app-switcher.mjs.map +1 -1
- package/fesm2022/koobiq-components-breadcrumbs.mjs +6 -4
- package/fesm2022/koobiq-components-breadcrumbs.mjs.map +1 -1
- package/fesm2022/koobiq-components-button-toggle.mjs +9 -6
- package/fesm2022/koobiq-components-button-toggle.mjs.map +1 -1
- package/fesm2022/koobiq-components-button.mjs +4 -4
- package/fesm2022/koobiq-components-button.mjs.map +1 -1
- package/fesm2022/koobiq-components-checkbox.mjs +2 -2
- package/fesm2022/koobiq-components-checkbox.mjs.map +1 -1
- package/fesm2022/koobiq-components-clamped-text.mjs +4 -0
- package/fesm2022/koobiq-components-clamped-text.mjs.map +1 -1
- package/fesm2022/koobiq-components-code-block.mjs +4 -0
- package/fesm2022/koobiq-components-code-block.mjs.map +1 -1
- package/fesm2022/koobiq-components-core.mjs +449 -112
- package/fesm2022/koobiq-components-core.mjs.map +1 -1
- package/fesm2022/koobiq-components-datepicker.mjs +5 -5
- package/fesm2022/koobiq-components-datepicker.mjs.map +1 -1
- package/fesm2022/koobiq-components-dl.mjs +3 -2
- package/fesm2022/koobiq-components-dl.mjs.map +1 -1
- package/fesm2022/koobiq-components-dropdown.mjs +8 -13
- package/fesm2022/koobiq-components-dropdown.mjs.map +1 -1
- package/fesm2022/koobiq-components-file-upload.mjs +33 -22
- package/fesm2022/koobiq-components-file-upload.mjs.map +1 -1
- package/fesm2022/koobiq-components-filter-bar.mjs +974 -758
- package/fesm2022/koobiq-components-filter-bar.mjs.map +1 -1
- package/fesm2022/koobiq-components-flag.mjs +66 -0
- package/fesm2022/koobiq-components-flag.mjs.map +1 -0
- package/fesm2022/koobiq-components-form-field.mjs +2 -2
- package/fesm2022/koobiq-components-form-field.mjs.map +1 -1
- package/fesm2022/koobiq-components-icon.mjs +2 -2
- package/fesm2022/koobiq-components-icon.mjs.map +1 -1
- package/fesm2022/koobiq-components-inline-edit.mjs +27 -6
- package/fesm2022/koobiq-components-inline-edit.mjs.map +1 -1
- package/fesm2022/koobiq-components-list.mjs +39 -20
- package/fesm2022/koobiq-components-list.mjs.map +1 -1
- package/fesm2022/koobiq-components-loader-overlay.mjs +2 -2
- package/fesm2022/koobiq-components-loader-overlay.mjs.map +1 -1
- package/fesm2022/koobiq-components-modal.mjs +9 -5
- package/fesm2022/koobiq-components-modal.mjs.map +1 -1
- package/fesm2022/koobiq-components-navbar.mjs +10 -9
- package/fesm2022/koobiq-components-navbar.mjs.map +1 -1
- package/fesm2022/koobiq-components-notification-center.mjs +178 -19
- package/fesm2022/koobiq-components-notification-center.mjs.map +1 -1
- package/fesm2022/koobiq-components-overflow-items.mjs +12 -4
- package/fesm2022/koobiq-components-overflow-items.mjs.map +1 -1
- package/fesm2022/koobiq-components-popover.mjs +4 -4
- package/fesm2022/koobiq-components-popover.mjs.map +1 -1
- package/fesm2022/koobiq-components-progress-bar.mjs +2 -2
- package/fesm2022/koobiq-components-progress-bar.mjs.map +1 -1
- package/fesm2022/koobiq-components-progress-spinner.mjs +2 -2
- package/fesm2022/koobiq-components-progress-spinner.mjs.map +1 -1
- package/fesm2022/koobiq-components-radio.mjs +3 -7
- package/fesm2022/koobiq-components-radio.mjs.map +1 -1
- package/fesm2022/koobiq-components-select.mjs +38 -16
- package/fesm2022/koobiq-components-select.mjs.map +1 -1
- package/fesm2022/koobiq-components-sidebar.mjs +4 -0
- package/fesm2022/koobiq-components-sidebar.mjs.map +1 -1
- package/fesm2022/koobiq-components-sidepanel.mjs +3 -3
- package/fesm2022/koobiq-components-sidepanel.mjs.map +1 -1
- package/fesm2022/koobiq-components-skeleton.mjs +2 -2
- package/fesm2022/koobiq-components-skeleton.mjs.map +1 -1
- package/fesm2022/koobiq-components-split-button.mjs +2 -2
- package/fesm2022/koobiq-components-split-button.mjs.map +1 -1
- package/fesm2022/koobiq-components-splitter.mjs +6 -2
- package/fesm2022/koobiq-components-splitter.mjs.map +1 -1
- package/fesm2022/koobiq-components-table.mjs +8 -6
- package/fesm2022/koobiq-components-table.mjs.map +1 -1
- package/fesm2022/koobiq-components-tabs.mjs +19 -7
- package/fesm2022/koobiq-components-tabs.mjs.map +1 -1
- package/fesm2022/koobiq-components-tags.mjs +7 -0
- package/fesm2022/koobiq-components-tags.mjs.map +1 -1
- package/fesm2022/koobiq-components-textarea.mjs +7 -14
- package/fesm2022/koobiq-components-textarea.mjs.map +1 -1
- package/fesm2022/koobiq-components-time-range.mjs +4 -4
- package/fesm2022/koobiq-components-time-range.mjs.map +1 -1
- package/fesm2022/koobiq-components-timezone.mjs +6 -0
- package/fesm2022/koobiq-components-timezone.mjs.map +1 -1
- package/fesm2022/koobiq-components-title.mjs +132 -14
- package/fesm2022/koobiq-components-title.mjs.map +1 -1
- package/fesm2022/koobiq-components-toast.mjs +1 -1
- package/fesm2022/koobiq-components-toast.mjs.map +1 -1
- package/fesm2022/koobiq-components-toggle.mjs +2 -2
- package/fesm2022/koobiq-components-toggle.mjs.map +1 -1
- package/fesm2022/koobiq-components-tooltip.mjs +50 -2
- package/fesm2022/koobiq-components-tooltip.mjs.map +1 -1
- package/fesm2022/koobiq-components-tree-select.mjs +44 -11
- package/fesm2022/koobiq-components-tree-select.mjs.map +1 -1
- package/fesm2022/koobiq-components-tree.mjs +67 -41
- package/fesm2022/koobiq-components-tree.mjs.map +1 -1
- package/fesm2022/koobiq-components-username.mjs +16 -3
- package/fesm2022/koobiq-components-username.mjs.map +1 -1
- package/file-upload/file-upload-tokens.scss +1 -0
- package/file-upload/index.d.ts +10 -7
- package/filter-bar/_filter-bar-theme.scss +86 -0
- package/filter-bar/filter-bar-tokens.scss +6 -0
- package/filter-bar/filter-bar.scss +10 -4
- package/filter-bar/filter-refresher.scss +1 -1
- package/filter-bar/filters.scss +23 -19
- package/filter-bar/index.d.ts +707 -338
- package/filter-bar/pipes/base-pipe.scss +14 -35
- package/filter-bar/pipes/pipe-date.scss +20 -14
- package/filter-bar/pipes/pipe-multi-tree-select.scss +5 -3
- package/filter-bar/pipes/pipe-multiselect.scss +5 -3
- package/filter-bar/pipes/pipe-readonly.scss +4 -13
- package/filter-bar/pipes/pipe-select.scss +3 -1
- package/filter-bar/pipes/pipe-tree-select.scss +3 -1
- package/flag/flag.scss +53 -0
- package/flag/index.d.ts +44 -0
- package/icon/icon-item-tokens.scss +1 -1
- package/inline-edit/index.d.ts +5 -0
- package/inline-edit/inline-edit.scss +7 -7
- package/link/link-tokens.scss +2 -2
- package/list/index.d.ts +11 -2
- package/loader-overlay/loader-overlay-tokens.scss +1 -1
- package/modal/_modal-animation.scss +6 -6
- package/modal/_modal-theme.scss +5 -0
- package/modal/index.d.ts +3 -1
- package/modal/modal.scss +15 -0
- package/navbar/index.d.ts +1 -0
- package/navbar/navbar-item.scss +9 -0
- package/notification-center/_notification-center-theme.scss +2 -1
- package/notification-center/index.d.ts +88 -3
- package/notification-center/notification-center.scss +42 -4
- package/notification-center/notification-item.scss +3 -2
- package/overflow-items/index.d.ts +1 -0
- package/package.json +7 -3
- package/prebuilt-themes/dark-theme.css +1 -1
- package/prebuilt-themes/light-theme.css +1 -1
- package/prebuilt-themes/theme.css +1 -1
- package/progress-bar/progress-bar.scss +4 -0
- package/progress-spinner/progress-spinner.scss +5 -1
- package/radio/index.d.ts +1 -5
- package/radio/radio.scss +18 -4
- package/schematics/collection.json +5 -0
- package/schematics/migrations/filter-bar-signals/README.md +66 -0
- package/schematics/migrations/filter-bar-signals/data.js +72 -0
- package/schematics/migrations/filter-bar-signals/index.js +316 -0
- package/schematics/migrations/filter-bar-signals/schema.json +20 -0
- package/schematics/migrations.json +5 -0
- package/schematics/ng-add/index.js +1 -1
- package/select/index.d.ts +10 -2
- package/sidebar/index.d.ts +1 -0
- package/skeleton/skeleton.scss +4 -0
- package/split-button/_split-button-theme.scss +2 -2
- package/splitter/_splitter-theme.scss +2 -2
- package/splitter/index.d.ts +1 -0
- package/table/_table-theme.scss +4 -0
- package/table/index.d.ts +3 -2
- package/tabs/index.d.ts +2 -0
- package/tabs/tab-header.scss +1 -0
- package/tabs/tabs-tokens.scss +1 -1
- package/textarea/index.d.ts +0 -1
- package/time-range/time-range.scss +0 -8
- package/timepicker/timepicker.scss +2 -2
- package/timezone/index.d.ts +1 -0
- package/title/index.d.ts +92 -2
- package/tooltip/index.d.ts +51 -3
- package/tree/_tree-theme.scss +2 -7
- package/tree/index.d.ts +19 -4
- package/tree/toggle.scss +5 -0
- package/tree/tree-option.scss +0 -4
- package/tree-select/_tree-select-theme.scss +1 -1
- package/tree-select/index.d.ts +9 -2
- 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.
|
|
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;
|
package/sidebar/index.d.ts
CHANGED
|
@@ -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;
|
package/skeleton/skeleton.scss
CHANGED
|
@@ -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
|
|
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:
|
|
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:
|
|
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:
|
|
24
|
+
background: var(--kbq-states-background-transparent-active);
|
|
25
25
|
}
|
|
26
26
|
}
|
package/splitter/index.d.ts
CHANGED
|
@@ -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;
|
package/table/_table-theme.scss
CHANGED