Skip to content

Commit fedb4d4

Browse files
authored
refactor(cdk-experimental/ui-patterns): loosen the API to accept different types of signals (angular#30597)
* Introduces the SignalLike and WritableSignalLike types to avoid direct uses of Signal and WritableSignal
1 parent fcc3a63 commit fedb4d4

File tree

19 files changed

+115
-57
lines changed

19 files changed

+115
-57
lines changed

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

Lines changed: 3 additions & 1 deletion
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
)

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

Lines changed: 3 additions & 3 deletions
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

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

Lines changed: 2 additions & 1 deletion
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

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

Lines changed: 5 additions & 4 deletions
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({

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

Lines changed: 4 additions & 4 deletions
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. */

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

Lines changed: 8 additions & 2 deletions
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(

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

Lines changed: 5 additions & 4 deletions
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({

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

Lines changed: 9 additions & 8 deletions
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. */

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

Lines changed: 2 additions & 0 deletions
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

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

Lines changed: 6 additions & 5 deletions
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> {

0 commit comments

Comments
 (0)