()
| 160 | readonly activeDescendant: Signal<string | undefined>; |
| 161 | |
| 162 | constructor() { |
| 163 | const inputs = { |
| 164 | ...this, |
| 165 | id: this.id, |
| 166 | items: computed(() => this._collection.orderedItems().map(item => item._pattern)), |
| 167 | activeItem: signal<TreeItemPattern<V> | undefined>(undefined), |
| 168 | element: () => this.element, |
| 169 | }; |
| 170 | |
| 171 | this._pattern = new TreePattern<V>(inputs); |
| 172 | |
| 173 | this.activeDescendant = computed(() => this._pattern.activeDescendant()); |
| 174 | |
| 175 | afterNextRender(() => { |
| 176 | this._collection.startObserving(this.element); |
| 177 | }); |
| 178 | |
| 179 | // Check for any violations after the DOM has been updated. |
| 180 | if (typeof ngDevMode === 'undefined' || ngDevMode) { |
| 181 | afterRenderEffect({ |
| 182 | read: () => { |
| 183 | reportViolations(this._pattern.validate(), this.element); |
| 184 | }, |
| 185 | }); |
| 186 | } |
| 187 | |
| 188 | // Resets default focus based on selection state until interacted. |
| 189 | afterRenderEffect({write: () => this._pattern.setDefaultStateEffect()}); |
| 190 | |
| 191 | afterRenderEffect({ |
| 192 | write: () => { |
| 193 | const items = inputs.items(); |
| 194 | const activeItem = untracked(() => inputs.activeItem()); |
| 195 | |
| 196 | if (activeItem && !items.some(i => i === activeItem)) { |
| 197 | this._pattern.treeBehavior.unfocus(); |
| 198 | this._pattern.setDefaultState(); |
| 199 | } |
| 200 | }, |
| 201 | }); |
| 202 | } |
| 203 | |
| 204 | ngOnDestroy() { |
| 205 | this._collection.stopObserving(); |
nothing calls this directly
no test coverage detected