@oxyhq/bloom 0.49.1 → 0.50.1
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/lib/commonjs/dialog/Dialog.js +6 -8
- package/lib/commonjs/dialog/Dialog.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.web.js +3 -4
- package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
- package/lib/commonjs/dialog/DialogHeader.js +271 -32
- package/lib/commonjs/dialog/DialogHeader.js.map +1 -1
- package/lib/module/dialog/Dialog.js +7 -9
- package/lib/module/dialog/Dialog.js.map +1 -1
- package/lib/module/dialog/Dialog.web.js +4 -5
- package/lib/module/dialog/Dialog.web.js.map +1 -1
- package/lib/module/dialog/DialogHeader.js +267 -28
- package/lib/module/dialog/DialogHeader.js.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/DialogHeader.d.ts +19 -0
- package/lib/typescript/commonjs/dialog/DialogHeader.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/types.d.ts +67 -0
- package/lib/typescript/commonjs/dialog/types.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/DialogHeader.d.ts +19 -0
- package/lib/typescript/module/dialog/DialogHeader.d.ts.map +1 -1
- package/lib/typescript/module/dialog/types.d.ts +67 -0
- package/lib/typescript/module/dialog/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/Dialog.test.tsx +77 -0
- package/src/dialog/Dialog.tsx +3 -3
- package/src/dialog/Dialog.web.tsx +2 -1
- package/src/dialog/DialogHeader.tsx +322 -27
- package/src/dialog/types.ts +81 -0
|
@@ -50,6 +50,73 @@ export interface DialogHeaderConfig {
|
|
|
50
50
|
* affordance entirely (e.g. a blocking surface).
|
|
51
51
|
*/
|
|
52
52
|
showClose?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* The ONE trailing call-to-action (Upload / Use photo / Save / Done) — a
|
|
55
|
+
* proper Bloom `Button` rendered at the trailing edge of the nav row, AFTER
|
|
56
|
+
* any `actions`. Standardizes what screens used to cram into `right`; supports
|
|
57
|
+
* `disabled` and a `loading` spinner (async submit). When set (and no explicit
|
|
58
|
+
* `right`), the default close affordance moves to the leading edge if the
|
|
59
|
+
* screen has no `onBack`, so there is always exactly one dismiss control.
|
|
60
|
+
*/
|
|
61
|
+
primaryAction?: {
|
|
62
|
+
label: string;
|
|
63
|
+
onPress: () => void;
|
|
64
|
+
disabled?: boolean;
|
|
65
|
+
loading?: boolean;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Trailing icon buttons (share / more / sort), rendered as frosted circles
|
|
69
|
+
* BEFORE `primaryAction`. Past {@link DIALOG_HEADER_MAX_INLINE_ACTIONS} the
|
|
70
|
+
* surplus collapses into a "more" overflow menu (Material pattern) built on
|
|
71
|
+
* Bloom's `Menu` — never hand-rolled. Each item's `accessibilityLabel` is also
|
|
72
|
+
* its overflow-menu row text.
|
|
73
|
+
*/
|
|
74
|
+
actions?: Array<{
|
|
75
|
+
icon: ReactNode;
|
|
76
|
+
accessibilityLabel: string;
|
|
77
|
+
onPress: () => void;
|
|
78
|
+
disabled?: boolean;
|
|
79
|
+
}>;
|
|
80
|
+
/**
|
|
81
|
+
* A search field in the collapsing large-title zone (iOS `.searchable` style:
|
|
82
|
+
* sits under the title and scrolls away with it). Requires a scrolling surface
|
|
83
|
+
* (`scrollable !== false`) — it lives in the same in-content block as the large
|
|
84
|
+
* title. Built on Bloom's `Search`.
|
|
85
|
+
*/
|
|
86
|
+
search?: {
|
|
87
|
+
value: string;
|
|
88
|
+
onChangeText: (text: string) => void;
|
|
89
|
+
placeholder?: string;
|
|
90
|
+
onSubmit?: () => void;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* A segmented control row UNDER the title (Material secondary row) for view
|
|
94
|
+
* switching. Requires a scrolling surface (lives in the large-title zone).
|
|
95
|
+
* Built on Bloom's `SegmentedControl` (`type="tabs"`).
|
|
96
|
+
*/
|
|
97
|
+
segments?: {
|
|
98
|
+
items: Array<{
|
|
99
|
+
key: string;
|
|
100
|
+
label: string;
|
|
101
|
+
}>;
|
|
102
|
+
value: string;
|
|
103
|
+
onChange: (key: string) => void;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Over a banner / dark media canvas, `'onImage'` strengthens the gradient
|
|
107
|
+
* scrim and forces light-content title + default icon buttons so the chrome
|
|
108
|
+
* stays legible over the media. `'default'` (the default) is unchanged.
|
|
109
|
+
*/
|
|
110
|
+
tone?: 'default' | 'onImage';
|
|
111
|
+
/**
|
|
112
|
+
* A thin step/progress indicator for wizards, rendered in the large-title zone
|
|
113
|
+
* below any title/search/segments. `step` is 1-based; the bar fills
|
|
114
|
+
* `step / total`.
|
|
115
|
+
*/
|
|
116
|
+
progress?: {
|
|
117
|
+
step: number;
|
|
118
|
+
total: number;
|
|
119
|
+
};
|
|
53
120
|
}
|
|
54
121
|
/**
|
|
55
122
|
* Side-sheet inset (px) from the root overlay's edges. Lets a host place a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/dialog/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEhF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAE7D,YAAY,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gEAAgE;IAChE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,kEAAkE;IAClE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/dialog/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dialog.web.d.ts","sourceRoot":"","sources":["../../../../src/dialog/Dialog.web.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Dialog.web.d.ts","sourceRoot":"","sources":["../../../../src/dialog/Dialog.web.tsx"],"names":[],"mappings":"AAoCA,OAAO,EAOL,4BAA4B,EAM7B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,YAAY,EAGZ,WAAW,EACZ,MAAM,SAAS,CAAC;AAqCjB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,2CAazD;AAiaD,OAAO,EAAE,4BAA4B,EAAE,CAAC;AAsQxC;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EACL,WAAW,EACX,OAAO,EACP,SAAS,GACV,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB,2CAgBA;AA8BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,gBAAgB,mZAK5B,CAAC"}
|
|
@@ -12,6 +12,12 @@ export declare const DIALOG_HEADER_OVERLAY_HEIGHT: number;
|
|
|
12
12
|
* BELOW the whole gradient overlay (fully clear at rest, then scrolls under it).
|
|
13
13
|
*/
|
|
14
14
|
export declare const DIALOG_HEADER_CONTENT_TOP: number;
|
|
15
|
+
/**
|
|
16
|
+
* Trailing icon `actions` shown inline before they collapse into a "more"
|
|
17
|
+
* overflow menu (Material overflow pattern). Kept small so the nav row never
|
|
18
|
+
* crowds the title.
|
|
19
|
+
*/
|
|
20
|
+
export declare const DIALOG_HEADER_MAX_INLINE_ACTIONS = 3;
|
|
15
21
|
interface HeaderStore {
|
|
16
22
|
getSnapshot: () => DialogHeaderConfig | null;
|
|
17
23
|
setOverride: (next: DialogHeaderConfig | null) => void;
|
|
@@ -83,4 +89,17 @@ export declare const DialogLargeTitle: React.NamedExoticComponent<{
|
|
|
83
89
|
controller: DialogHeaderController;
|
|
84
90
|
header: DialogHeaderConfig;
|
|
85
91
|
}>;
|
|
92
|
+
/**
|
|
93
|
+
* The nav-bar-height content inset for a header-mode surface whose content owns
|
|
94
|
+
* its own scroll (`scrollable: false`) — the account dialog or an own-scroller
|
|
95
|
+
* like the media picker. Under `tone: 'onImage'` it COLLAPSES to nothing so the
|
|
96
|
+
* media (photo grid / banner) slides UP under the floating translucent nav bar,
|
|
97
|
+
* edge-to-edge (Apple/Material immersive photo grid); otherwise it insets the
|
|
98
|
+
* content below the bar. Reads the merged (base + runtime-override) tone, since
|
|
99
|
+
* `tone` is contributed by the mounted screen through the override store.
|
|
100
|
+
*/
|
|
101
|
+
export declare const DialogNavBarSpacer: React.NamedExoticComponent<{
|
|
102
|
+
controller: DialogHeaderController;
|
|
103
|
+
header: DialogHeaderConfig;
|
|
104
|
+
}>;
|
|
86
105
|
//# sourceMappingURL=DialogHeader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DialogHeader.d.ts","sourceRoot":"","sources":["../../../../src/dialog/DialogHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AACf,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAiB,EAKf,KAAK,WAAW,EACjB,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"DialogHeader.d.ts","sourceRoot":"","sources":["../../../../src/dialog/DialogHeader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AACf,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAiB,EAKf,KAAK,WAAW,EACjB,MAAM,yBAAyB,CAAC;AAoBjC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAiBlD,gFAAgF;AAChF,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAKxC,uDAAuD;AACvD,eAAO,MAAM,4BAA4B,QAAwC,CAAC;AAElF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,QAA+B,CAAC;AAQtE;;;;GAIG;AACH,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAgBlD,UAAU,WAAW;IACnB,WAAW,EAAE,MAAM,kBAAkB,GAAG,IAAI,CAAC;IAC7C,WAAW,EAAE,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAC;CACjD;AA0CD;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7B,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtC,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,iFAAiF;AACjF,wBAAgB,yBAAyB,IAAI,sBAAsB,CAQlE;AAID;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,UAAU,EACV,QAAQ,GACT,EAAE;IACD,UAAU,EAAE,sBAAsB,CAAC;IACnC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,GAAG,KAAK,CAAC,YAAY,CAMrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CA2BnF;AAoID;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe;gBAOd,sBAAsB;YAC1B,kBAAkB;eACf,MAAM,IAAI;IACrB;;;;;OAKG;eACQ,OAAO;YACV,SAAS,CAAC,SAAS,CAAC;EAmI5B,CAAC;AAIH;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB;gBAIf,sBAAsB;YAC1B,kBAAkB;EA0F1B,CAAC;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB;gBAIjB,sBAAsB;YAC1B,kBAAkB;EAK1B,CAAC"}
|
|
@@ -50,6 +50,73 @@ export interface DialogHeaderConfig {
|
|
|
50
50
|
* affordance entirely (e.g. a blocking surface).
|
|
51
51
|
*/
|
|
52
52
|
showClose?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* The ONE trailing call-to-action (Upload / Use photo / Save / Done) — a
|
|
55
|
+
* proper Bloom `Button` rendered at the trailing edge of the nav row, AFTER
|
|
56
|
+
* any `actions`. Standardizes what screens used to cram into `right`; supports
|
|
57
|
+
* `disabled` and a `loading` spinner (async submit). When set (and no explicit
|
|
58
|
+
* `right`), the default close affordance moves to the leading edge if the
|
|
59
|
+
* screen has no `onBack`, so there is always exactly one dismiss control.
|
|
60
|
+
*/
|
|
61
|
+
primaryAction?: {
|
|
62
|
+
label: string;
|
|
63
|
+
onPress: () => void;
|
|
64
|
+
disabled?: boolean;
|
|
65
|
+
loading?: boolean;
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Trailing icon buttons (share / more / sort), rendered as frosted circles
|
|
69
|
+
* BEFORE `primaryAction`. Past {@link DIALOG_HEADER_MAX_INLINE_ACTIONS} the
|
|
70
|
+
* surplus collapses into a "more" overflow menu (Material pattern) built on
|
|
71
|
+
* Bloom's `Menu` — never hand-rolled. Each item's `accessibilityLabel` is also
|
|
72
|
+
* its overflow-menu row text.
|
|
73
|
+
*/
|
|
74
|
+
actions?: Array<{
|
|
75
|
+
icon: ReactNode;
|
|
76
|
+
accessibilityLabel: string;
|
|
77
|
+
onPress: () => void;
|
|
78
|
+
disabled?: boolean;
|
|
79
|
+
}>;
|
|
80
|
+
/**
|
|
81
|
+
* A search field in the collapsing large-title zone (iOS `.searchable` style:
|
|
82
|
+
* sits under the title and scrolls away with it). Requires a scrolling surface
|
|
83
|
+
* (`scrollable !== false`) — it lives in the same in-content block as the large
|
|
84
|
+
* title. Built on Bloom's `Search`.
|
|
85
|
+
*/
|
|
86
|
+
search?: {
|
|
87
|
+
value: string;
|
|
88
|
+
onChangeText: (text: string) => void;
|
|
89
|
+
placeholder?: string;
|
|
90
|
+
onSubmit?: () => void;
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* A segmented control row UNDER the title (Material secondary row) for view
|
|
94
|
+
* switching. Requires a scrolling surface (lives in the large-title zone).
|
|
95
|
+
* Built on Bloom's `SegmentedControl` (`type="tabs"`).
|
|
96
|
+
*/
|
|
97
|
+
segments?: {
|
|
98
|
+
items: Array<{
|
|
99
|
+
key: string;
|
|
100
|
+
label: string;
|
|
101
|
+
}>;
|
|
102
|
+
value: string;
|
|
103
|
+
onChange: (key: string) => void;
|
|
104
|
+
};
|
|
105
|
+
/**
|
|
106
|
+
* Over a banner / dark media canvas, `'onImage'` strengthens the gradient
|
|
107
|
+
* scrim and forces light-content title + default icon buttons so the chrome
|
|
108
|
+
* stays legible over the media. `'default'` (the default) is unchanged.
|
|
109
|
+
*/
|
|
110
|
+
tone?: 'default' | 'onImage';
|
|
111
|
+
/**
|
|
112
|
+
* A thin step/progress indicator for wizards, rendered in the large-title zone
|
|
113
|
+
* below any title/search/segments. `step` is 1-based; the bar fills
|
|
114
|
+
* `step / total`.
|
|
115
|
+
*/
|
|
116
|
+
progress?: {
|
|
117
|
+
step: number;
|
|
118
|
+
total: number;
|
|
119
|
+
};
|
|
53
120
|
}
|
|
54
121
|
/**
|
|
55
122
|
* Side-sheet inset (px) from the root overlay's edges. Lets a host place a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/dialog/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEhF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAE7D,YAAY,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAE9E;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gEAAgE;IAChE,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,kEAAkE;IAClE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/dialog/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -175,3 +175,80 @@ describe('alert() helper', () => {
|
|
|
175
175
|
expect(onPress).toHaveBeenCalledTimes(1);
|
|
176
176
|
});
|
|
177
177
|
});
|
|
178
|
+
|
|
179
|
+
describe('Dialog nav header (rich fields)', () => {
|
|
180
|
+
function openHeader(header: React.ComponentProps<typeof Dialog>['header']) {
|
|
181
|
+
let control: ReturnType<typeof useDialogControl> | undefined;
|
|
182
|
+
const utils = renderWithTheme(
|
|
183
|
+
<Harness onControl={(c) => { control = c; }}>
|
|
184
|
+
{(c) => (
|
|
185
|
+
<Dialog control={c} header={header} scrollable>
|
|
186
|
+
<Text>Screen body</Text>
|
|
187
|
+
</Dialog>
|
|
188
|
+
)}
|
|
189
|
+
</Harness>,
|
|
190
|
+
);
|
|
191
|
+
act(() => { control?.open(); });
|
|
192
|
+
return utils;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
it('renders primaryAction, actions, search and segments', () => {
|
|
196
|
+
const { getByText, getByLabelText, getByPlaceholderText } = openHeader({
|
|
197
|
+
title: 'Rich title',
|
|
198
|
+
primaryAction: { label: 'Save', onPress: jest.fn() },
|
|
199
|
+
actions: [
|
|
200
|
+
{ icon: <Text>·</Text>, accessibilityLabel: 'Share', onPress: jest.fn() },
|
|
201
|
+
{ icon: <Text>·</Text>, accessibilityLabel: 'Star', onPress: jest.fn() },
|
|
202
|
+
],
|
|
203
|
+
search: { value: '', onChangeText: jest.fn(), placeholder: 'Find items' },
|
|
204
|
+
segments: {
|
|
205
|
+
items: [
|
|
206
|
+
{ key: 'all', label: 'All' },
|
|
207
|
+
{ key: 'photos', label: 'Photos' },
|
|
208
|
+
],
|
|
209
|
+
value: 'all',
|
|
210
|
+
onChange: jest.fn(),
|
|
211
|
+
},
|
|
212
|
+
progress: { step: 2, total: 5 },
|
|
213
|
+
});
|
|
214
|
+
expect(getByText('Save')).toBeTruthy();
|
|
215
|
+
expect(getByLabelText('Share')).toBeTruthy();
|
|
216
|
+
expect(getByLabelText('Star')).toBeTruthy();
|
|
217
|
+
expect(getByPlaceholderText('Find items')).toBeTruthy();
|
|
218
|
+
expect(getByText('All')).toBeTruthy();
|
|
219
|
+
expect(getByText('Photos')).toBeTruthy();
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('fires primaryAction.onPress when the CTA is pressed', () => {
|
|
223
|
+
const onSave = jest.fn();
|
|
224
|
+
const { getByText } = openHeader({
|
|
225
|
+
title: 'T',
|
|
226
|
+
primaryAction: { label: 'Save', onPress: onSave },
|
|
227
|
+
});
|
|
228
|
+
act(() => { fireEvent.press(getByText('Save')); });
|
|
229
|
+
expect(onSave).toHaveBeenCalledTimes(1);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
it('collapses surplus actions into a "More" overflow trigger', () => {
|
|
233
|
+
const { getByLabelText } = openHeader({
|
|
234
|
+
title: 'T',
|
|
235
|
+
actions: [
|
|
236
|
+
{ icon: <Text>a</Text>, accessibilityLabel: 'A1', onPress: jest.fn() },
|
|
237
|
+
{ icon: <Text>b</Text>, accessibilityLabel: 'A2', onPress: jest.fn() },
|
|
238
|
+
{ icon: <Text>c</Text>, accessibilityLabel: 'A3', onPress: jest.fn() },
|
|
239
|
+
{ icon: <Text>d</Text>, accessibilityLabel: 'A4', onPress: jest.fn() },
|
|
240
|
+
],
|
|
241
|
+
});
|
|
242
|
+
// 4 actions > the inline max (3): the first two stay inline + a "More" trigger.
|
|
243
|
+
expect(getByLabelText('A1')).toBeTruthy();
|
|
244
|
+
expect(getByLabelText('A2')).toBeTruthy();
|
|
245
|
+
expect(getByLabelText('More')).toBeTruthy();
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it('backward-compat: a title-only header still renders the default close', () => {
|
|
249
|
+
const { getAllByText, getByLabelText } = openHeader({ title: 'Just a title' });
|
|
250
|
+
// Title renders in both the large title and the (collapsed) bar title.
|
|
251
|
+
expect(getAllByText('Just a title').length).toBeGreaterThanOrEqual(1);
|
|
252
|
+
expect(getByLabelText('Close')).toBeTruthy();
|
|
253
|
+
});
|
|
254
|
+
});
|
package/src/dialog/Dialog.tsx
CHANGED
|
@@ -32,10 +32,10 @@ import { Context, useDialogControl } from './context';
|
|
|
32
32
|
import { DialogBody } from './DialogContent';
|
|
33
33
|
import { DialogBottomSheet } from './DialogBottomSheet';
|
|
34
34
|
import {
|
|
35
|
-
DIALOG_NAV_BAR_HEIGHT,
|
|
36
35
|
type DialogHeaderController,
|
|
37
36
|
DialogHeaderProvider,
|
|
38
37
|
DialogLargeTitle,
|
|
38
|
+
DialogNavBarSpacer,
|
|
39
39
|
DialogNavHeader,
|
|
40
40
|
useDialogHeaderController,
|
|
41
41
|
} from './DialogHeader';
|
|
@@ -284,7 +284,7 @@ function CenteredOrSideDialog({
|
|
|
284
284
|
</>
|
|
285
285
|
) : (
|
|
286
286
|
<>
|
|
287
|
-
<
|
|
287
|
+
<DialogNavBarSpacer controller={headerController} header={header} />
|
|
288
288
|
<DialogHeaderProvider controller={headerController}>{bodyNode}</DialogHeaderProvider>
|
|
289
289
|
</>
|
|
290
290
|
)
|
|
@@ -573,7 +573,7 @@ function SideSheet({
|
|
|
573
573
|
onDismiss={onHeaderDismiss}
|
|
574
574
|
collapse={false}
|
|
575
575
|
/>
|
|
576
|
-
<
|
|
576
|
+
<DialogNavBarSpacer controller={headerController} header={header} />
|
|
577
577
|
<DialogHeaderProvider controller={headerController}>{children}</DialogHeaderProvider>
|
|
578
578
|
</View>
|
|
579
579
|
) : (
|
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
DIALOG_NAV_BAR_HEIGHT,
|
|
30
30
|
DialogHeaderProvider,
|
|
31
31
|
DialogLargeTitle,
|
|
32
|
+
DialogNavBarSpacer,
|
|
32
33
|
DialogNavHeader,
|
|
33
34
|
useDialogHeaderController,
|
|
34
35
|
} from './DialogHeader';
|
|
@@ -497,7 +498,7 @@ function DialogPanel({
|
|
|
497
498
|
/>
|
|
498
499
|
{scrollable === false ? (
|
|
499
500
|
<DialogMorphContent morph={morphState} style={{ flex: 1, minHeight: 0 }}>
|
|
500
|
-
<
|
|
501
|
+
<DialogNavBarSpacer controller={headerController} header={header} />
|
|
501
502
|
<DialogHeaderProvider controller={headerController}>{body}</DialogHeaderProvider>
|
|
502
503
|
</DialogMorphContent>
|
|
503
504
|
) : (
|