Skip to content

Commit 80bc7fa

Browse files
committed
refactor(cdk-experimental/ui-patterns): remove uses of Signal and WritableSignal
* Introduces the SignalLike and WritableSignalLike types to avoid direct uses of Signal and WritableSignal refactor(cdk-experimental/ui-patterns): remove uses of Signal and WritableSignal * Introduces the SignalLike and WritableSignalLike types to avoid direct uses of Signal and WritableSignal Revert "refactor(cdk-experimental/ui-patterns): remove uses of signal" This reverts commit 8539158.
1 parent 11599f8 commit 80bc7fa

19 files changed

+114
-57
lines changed

Diff for: src/cdk-experimental/ui-patterns/behaviors/event-manager/BUILD.bazel

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ ts_library(
88
["**/*.ts"],
99
exclude = ["**/*.spec.ts"],
1010
),
11-
deps = ["@npm//@angular/core"],
11+
deps = [
12+
"//src/cdk-experimental/ui-patterns/behaviors/signal-like",
13+
],
1214
)

Diff for: src/cdk-experimental/ui-patterns/behaviors/event-manager/keyboard-event-manager.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {Signal} from '@angular/core';
9+
import {SignalLike} from '../signal-like/signal-like';
1010
import {
1111
EventHandler,
1212
EventHandlerOptions,
@@ -20,9 +20,9 @@ import {
2020
* Used to represent a keycode.
2121
*
2222
* This is used to match whether an events keycode should be handled. The ability to match using a
23-
* string, Signal, or Regexp gives us more flexibility when authoring event handlers.
23+
* string, SignalLike, or Regexp gives us more flexibility when authoring event handlers.
2424
*/
25-
type KeyCode = string | Signal<string> | RegExp;
25+
type KeyCode = string | SignalLike<string> | RegExp;
2626

2727
/**
2828
* An event manager that is specialized for handling keyboard events. By default this manager stops

Diff for: src/cdk-experimental/ui-patterns/behaviors/list-focus/BUILD.bazel

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ ts_library(
1010
),
1111
deps = [
1212
"//src/cdk-experimental/ui-patterns/behaviors/list-navigation",
13-
"@npm//@angular/core",
13+
"//src/cdk-experimental/ui-patterns/behaviors/signal-like",
1414
],
1515
)
1616

@@ -20,6 +20,7 @@ ng_test_library(
2020
deps = [
2121
":list-focus",
2222
"//src/cdk-experimental/ui-patterns/behaviors/list-navigation",
23+
"//src/cdk-experimental/ui-patterns/behaviors/signal-like",
2324
],
2425
)
2526

Diff for: src/cdk-experimental/ui-patterns/behaviors/list-focus/list-focus.spec.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {computed, Signal, signal} from '@angular/core';
9+
import {computed, signal} from '@angular/core';
10+
import {SignalLike} from '../signal-like/signal-like';
1011
import {ListNavigation, ListNavigationInputs} from '../list-navigation/list-navigation';
1112
import {ListFocus, ListFocusInputs, ListFocusItem} from './list-focus';
1213

1314
describe('List Focus', () => {
1415
interface TestItem extends ListFocusItem {
15-
tabindex: Signal<-1 | 0>;
16+
tabindex: SignalLike<-1 | 0>;
1617
}
1718

18-
function getItems(length: number): Signal<TestItem[]> {
19+
function getItems(length: number): SignalLike<TestItem[]> {
1920
return signal(
2021
Array.from({length}).map((_, i) => ({
2122
index: signal(i),
@@ -28,7 +29,7 @@ describe('List Focus', () => {
2829
}
2930

3031
function getNavigation<T extends TestItem>(
31-
items: Signal<T[]>,
32+
items: SignalLike<T[]>,
3233
args: Partial<ListNavigationInputs<T>> = {},
3334
): ListNavigation<T> {
3435
return new ListNavigation({

Diff for: src/cdk-experimental/ui-patterns/behaviors/list-focus/list-focus.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,22 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {Signal} from '@angular/core';
9+
import {SignalLike} from '../signal-like/signal-like';
1010
import {ListNavigation, ListNavigationItem} from '../list-navigation/list-navigation';
1111

1212
/** Represents an item in a collection, such as a listbox option, than may receive focus. */
1313
export interface ListFocusItem extends ListNavigationItem {
1414
/** A unique identifier for the item. */
15-
id: Signal<string>;
15+
id: SignalLike<string>;
1616

1717
/** The html element that should receive focus. */
18-
element: Signal<HTMLElement>;
18+
element: SignalLike<HTMLElement>;
1919
}
2020

2121
/** Represents the required inputs for a collection that contains focusable items. */
2222
export interface ListFocusInputs<T extends ListFocusItem> {
2323
/** The focus strategy used by the list. */
24-
focusMode: Signal<'roving' | 'activedescendant'>;
24+
focusMode: SignalLike<'roving' | 'activedescendant'>;
2525
}
2626

2727
/** Controls focus for a list of items. */

Diff for: src/cdk-experimental/ui-patterns/behaviors/list-navigation/BUILD.bazel

+8-2
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,19 @@ ts_library(
88
["**/*.ts"],
99
exclude = ["**/*.spec.ts"],
1010
),
11-
deps = ["@npm//@angular/core"],
11+
deps = [
12+
"//src/cdk-experimental/ui-patterns/behaviors/signal-like",
13+
"@npm//@angular/core",
14+
],
1215
)
1316

1417
ng_test_library(
1518
name = "unit_test_sources",
1619
srcs = glob(["**/*.spec.ts"]),
17-
deps = [":list-navigation"],
20+
deps = [
21+
":list-navigation",
22+
"//src/cdk-experimental/ui-patterns/behaviors/signal-like",
23+
],
1824
)
1925

2026
ng_web_test_suite(

Diff for: src/cdk-experimental/ui-patterns/behaviors/list-navigation/list-navigation.spec.ts

+5-4
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {Signal, signal, WritableSignal} from '@angular/core';
9+
import {signal} from '@angular/core';
10+
import {SignalLike, WritableSignalLike} from '../signal-like/signal-like';
1011
import {ListNavigationItem, ListNavigation, ListNavigationInputs} from './list-navigation';
1112

1213
describe('List Navigation', () => {
1314
interface TestItem extends ListNavigationItem {
14-
disabled: WritableSignal<boolean>;
15+
disabled: WritableSignalLike<boolean>;
1516
}
1617

17-
function getItems(length: number): Signal<TestItem[]> {
18+
function getItems(length: number): SignalLike<TestItem[]> {
1819
return signal(
1920
Array.from({length}).map((_, i) => ({
2021
index: signal(i),
@@ -24,7 +25,7 @@ describe('List Navigation', () => {
2425
}
2526

2627
function getNavigation<T extends TestItem>(
27-
items: Signal<T[]>,
28+
items: SignalLike<T[]>,
2829
args: Partial<ListNavigationInputs<T>> = {},
2930
): ListNavigation<T> {
3031
return new ListNavigation({

Diff for: src/cdk-experimental/ui-patterns/behaviors/list-navigation/list-navigation.ts

+9-8
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,34 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {signal, Signal, WritableSignal} from '@angular/core';
9+
import {signal} from '@angular/core';
10+
import {SignalLike, WritableSignalLike} from '../signal-like/signal-like';
1011

1112
/** Represents an item in a collection, such as a listbox option, than can be navigated to. */
1213
export interface ListNavigationItem {
1314
/** Whether an item is disabled. */
14-
disabled: Signal<boolean>;
15+
disabled: SignalLike<boolean>;
1516
}
1617

1718
/** Represents the required inputs for a collection that has navigable items. */
1819
export interface ListNavigationInputs<T extends ListNavigationItem> {
1920
/** Whether focus should wrap when navigating. */
20-
wrap: Signal<boolean>;
21+
wrap: SignalLike<boolean>;
2122

2223
/** The items in the list. */
23-
items: Signal<T[]>;
24+
items: SignalLike<T[]>;
2425

2526
/** Whether disabled items in the list should be skipped when navigating. */
26-
skipDisabled: Signal<boolean>;
27+
skipDisabled: SignalLike<boolean>;
2728

2829
/** The current index that has been navigated to. */
29-
activeIndex: WritableSignal<number>;
30+
activeIndex: WritableSignalLike<number>;
3031

3132
/** Whether the list is vertically or horizontally oriented. */
32-
orientation: Signal<'vertical' | 'horizontal'>;
33+
orientation: SignalLike<'vertical' | 'horizontal'>;
3334

3435
/** The direction that text is read based on the users locale. */
35-
textDirection: Signal<'rtl' | 'ltr'>;
36+
textDirection: SignalLike<'rtl' | 'ltr'>;
3637
}
3738

3839
/** Controls navigation for a list of items. */

Diff for: src/cdk-experimental/ui-patterns/behaviors/list-selection/BUILD.bazel

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ ts_library(
1010
),
1111
deps = [
1212
"//src/cdk-experimental/ui-patterns/behaviors/list-navigation",
13+
"//src/cdk-experimental/ui-patterns/behaviors/signal-like",
1314
"@npm//@angular/core",
1415
],
1516
)
@@ -20,6 +21,7 @@ ng_test_library(
2021
deps = [
2122
":list-selection",
2223
"//src/cdk-experimental/ui-patterns/behaviors/list-navigation",
24+
"//src/cdk-experimental/ui-patterns/behaviors/signal-like",
2325
],
2426
)
2527

Diff for: src/cdk-experimental/ui-patterns/behaviors/list-selection/list-selection.spec.ts

+6-5
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {Signal, signal, WritableSignal} from '@angular/core';
9+
import {signal} from '@angular/core';
10+
import {SignalLike, WritableSignalLike} from '../signal-like/signal-like';
1011
import {ListSelectionItem, ListSelection, ListSelectionInputs} from './list-selection';
1112
import {ListNavigation, ListNavigationInputs} from '../list-navigation/list-navigation';
1213

1314
describe('List Selection', () => {
1415
interface TestItem extends ListSelectionItem {
15-
disabled: WritableSignal<boolean>;
16+
disabled: WritableSignalLike<boolean>;
1617
}
1718

18-
function getItems(length: number): Signal<TestItem[]> {
19+
function getItems(length: number): SignalLike<TestItem[]> {
1920
return signal(
2021
Array.from({length}).map((_, i) => ({
2122
index: signal(i),
@@ -27,7 +28,7 @@ describe('List Selection', () => {
2728
}
2829

2930
function getNavigation<T extends TestItem>(
30-
items: Signal<T[]>,
31+
items: SignalLike<T[]>,
3132
args: Partial<ListNavigationInputs<T>> = {},
3233
): ListNavigation<T> {
3334
return new ListNavigation({
@@ -42,7 +43,7 @@ describe('List Selection', () => {
4243
}
4344

4445
function getSelection<T extends TestItem>(
45-
items: Signal<T[]>,
46+
items: SignalLike<T[]>,
4647
navigation: ListNavigation<T>,
4748
args: Partial<ListSelectionInputs<T>> = {},
4849
): ListSelection<T> {

Diff for: src/cdk-experimental/ui-patterns/behaviors/list-selection/list-selection.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,32 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {signal, Signal, WritableSignal} from '@angular/core';
9+
import {signal} from '@angular/core';
10+
import {SignalLike, WritableSignalLike} from '../signal-like/signal-like';
1011
import {ListNavigation, ListNavigationItem} from '../list-navigation/list-navigation';
1112

1213
/** Represents an item in a collection, such as a listbox option, than can be selected. */
1314
export interface ListSelectionItem extends ListNavigationItem {
1415
/** A unique identifier for the item. */
15-
id: Signal<string>;
16+
id: SignalLike<string>;
1617

1718
/** Whether an item is disabled. */
18-
disabled: Signal<boolean>;
19+
disabled: SignalLike<boolean>;
1920
}
2021

2122
/** Represents the required inputs for a collection that contains selectable items. */
2223
export interface ListSelectionInputs<T extends ListSelectionItem> {
2324
/** The items in the list. */
24-
items: Signal<T[]>;
25+
items: SignalLike<T[]>;
2526

2627
/** Whether multiple items in the list can be selected at once. */
27-
multiselectable: Signal<boolean>;
28+
multiselectable: SignalLike<boolean>;
2829

2930
/** The ids of the current selected items. */
30-
selectedIds: WritableSignal<string[]>;
31+
selectedIds: WritableSignalLike<string[]>;
3132

3233
/** The selection strategy used by the list. */
33-
selectionMode: Signal<'follow' | 'explicit'>;
34+
selectionMode: SignalLike<'follow' | 'explicit'>;
3435
}
3536

3637
/** Controls selection for a list of items. */

Diff for: src/cdk-experimental/ui-patterns/behaviors/list-typeahead/BUILD.bazel

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ ts_library(
1010
),
1111
deps = [
1212
"//src/cdk-experimental/ui-patterns/behaviors/list-navigation",
13+
"//src/cdk-experimental/ui-patterns/behaviors/signal-like",
1314
"@npm//@angular/core",
1415
],
1516
)
@@ -20,6 +21,7 @@ ng_test_library(
2021
deps = [
2122
":list-typeahead",
2223
"//src/cdk-experimental/ui-patterns/behaviors/list-navigation",
24+
"//src/cdk-experimental/ui-patterns/behaviors/signal-like",
2325
],
2426
)
2527

Diff for: src/cdk-experimental/ui-patterns/behaviors/list-typeahead/list-typeahead.spec.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {Signal, signal, WritableSignal} from '@angular/core';
9+
import {signal} from '@angular/core';
10+
import {SignalLike, WritableSignalLike} from '../signal-like/signal-like';
1011
import {ListTypeaheadItem, ListTypeahead} from './list-typeahead';
1112
import {fakeAsync, tick} from '@angular/core/testing';
1213
import {ListNavigation} from '../list-navigation/list-navigation';
1314

1415
describe('List Typeahead', () => {
1516
interface TestItem extends ListTypeaheadItem {
16-
disabled: WritableSignal<boolean>;
17+
disabled: WritableSignalLike<boolean>;
1718
}
1819

19-
function getItems(length: number): Signal<TestItem[]> {
20+
function getItems(length: number): SignalLike<TestItem[]> {
2021
return signal(
2122
Array.from({length}).map((_, i) => ({
2223
index: signal(i),

Diff for: src/cdk-experimental/ui-patterns/behaviors/list-typeahead/list-typeahead.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {signal, Signal} from '@angular/core';
9+
import {signal} from '@angular/core';
10+
import {SignalLike} from '../signal-like/signal-like';
1011
import {ListNavigationItem, ListNavigation} from '../list-navigation/list-navigation';
1112

1213
/**
@@ -15,7 +16,7 @@ import {ListNavigationItem, ListNavigation} from '../list-navigation/list-naviga
1516
*/
1617
export interface ListTypeaheadItem extends ListNavigationItem {
1718
/** The text used by the typeahead search. */
18-
searchTerm: Signal<string>;
19+
searchTerm: SignalLike<string>;
1920
}
2021

2122
/**
@@ -24,7 +25,7 @@ export interface ListTypeaheadItem extends ListNavigationItem {
2425
*/
2526
export interface ListTypeaheadInputs {
2627
/** The amount of time before the typeahead search is reset. */
27-
typeaheadDelay: Signal<number>;
28+
typeaheadDelay: SignalLike<number>;
2829
}
2930

3031
/** Controls typeahead for a list of items. */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
load("//tools:defaults.bzl", "ts_library")
2+
3+
package(default_visibility = ["//visibility:public"])
4+
5+
ts_library(
6+
name = "signal-like",
7+
srcs = ["signal-like.ts"],
8+
deps = [],
9+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
export type SignalLike<T> = () => T;
10+
11+
export interface WritableSignalLike<T> extends SignalLike<T> {
12+
set(value: T): void;
13+
update(updateFn: (value: T) => T): void;
14+
}
15+
16+
/** Converts a getter setter style signal to a WritableSignalLike. */
17+
export function convertGetterSetterToWritableSignalLike<T>(
18+
getter: () => T,
19+
setter: (v: T) => void,
20+
): WritableSignalLike<T> {
21+
return Object.assign(getter, {
22+
set: setter,
23+
update: (updateCallback: (v: T) => T) => setter(updateCallback(getter())),
24+
});
25+
}

0 commit comments

Comments
 (0)