@oxyhq/bloom 1.0.2 → 1.0.4
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/docs/button.mdx +19 -17
- package/docs/design-tokens.mdx +12 -10
- package/docs/dropdown-menu.mdx +26 -3
- package/lib/commonjs/context-menu/ContextMenu.js +2 -0
- package/lib/commonjs/context-menu/ContextMenu.js.map +1 -1
- package/lib/commonjs/context-menu/ContextMenu.web.js +2 -0
- package/lib/commonjs/context-menu/ContextMenu.web.js.map +1 -1
- package/lib/commonjs/design-tokens/tokens.json +11040 -0
- package/lib/commonjs/dialog/SheetShell.js +6 -1
- package/lib/commonjs/dialog/SheetShell.js.map +1 -1
- package/lib/commonjs/dropdown-menu/DropdownMenu.js +7 -1
- package/lib/commonjs/dropdown-menu/DropdownMenu.js.map +1 -1
- package/lib/commonjs/dropdown-menu/DropdownMenu.web.js +2 -0
- package/lib/commonjs/dropdown-menu/DropdownMenu.web.js.map +1 -1
- package/lib/commonjs/floating/TriggerSlot.js +3 -1
- package/lib/commonjs/floating/TriggerSlot.js.map +1 -1
- package/lib/commonjs/floating/constants.js +4 -1
- package/lib/commonjs/floating/constants.js.map +1 -1
- package/lib/commonjs/floating/menu-rows.js +28 -22
- package/lib/commonjs/floating/menu-rows.js.map +1 -1
- package/lib/commonjs/floating/menu-sub-flyout.js +18 -5
- package/lib/commonjs/floating/menu-sub-flyout.js.map +1 -1
- package/lib/commonjs/floating/menu-sub-inline.js +5 -1
- package/lib/commonjs/floating/menu-sub-inline.js.map +1 -1
- package/lib/commonjs/floating/shared.js +2 -2
- package/lib/commonjs/floating/shared.js.map +1 -1
- package/lib/commonjs/popover/Popover.js +2 -0
- package/lib/commonjs/popover/Popover.js.map +1 -1
- package/lib/commonjs/popover/Popover.web.js +2 -0
- package/lib/commonjs/popover/Popover.web.js.map +1 -1
- package/lib/commonjs/theme/color-policy.js +1 -1
- package/lib/commonjs/theme/color-presets.js +331 -1
- package/lib/commonjs/theme/color-presets.js.map +1 -1
- package/lib/commonjs/theme/glass-colors.js +22 -19
- package/lib/commonjs/theme/glass-colors.js.map +1 -1
- package/lib/module/context-menu/ContextMenu.js +2 -0
- package/lib/module/context-menu/ContextMenu.js.map +1 -1
- package/lib/module/context-menu/ContextMenu.web.js +2 -0
- package/lib/module/context-menu/ContextMenu.web.js.map +1 -1
- package/lib/module/design-tokens/tokens.json +11040 -0
- package/lib/module/dialog/SheetShell.js +6 -1
- package/lib/module/dialog/SheetShell.js.map +1 -1
- package/lib/module/dropdown-menu/DropdownMenu.js +7 -1
- package/lib/module/dropdown-menu/DropdownMenu.js.map +1 -1
- package/lib/module/dropdown-menu/DropdownMenu.web.js +2 -0
- package/lib/module/dropdown-menu/DropdownMenu.web.js.map +1 -1
- package/lib/module/floating/TriggerSlot.js +5 -3
- package/lib/module/floating/TriggerSlot.js.map +1 -1
- package/lib/module/floating/constants.js +3 -0
- package/lib/module/floating/constants.js.map +1 -1
- package/lib/module/floating/menu-rows.js +29 -23
- package/lib/module/floating/menu-rows.js.map +1 -1
- package/lib/module/floating/menu-sub-flyout.js +18 -5
- package/lib/module/floating/menu-sub-flyout.js.map +1 -1
- package/lib/module/floating/menu-sub-inline.js +5 -1
- package/lib/module/floating/menu-sub-inline.js.map +1 -1
- package/lib/module/floating/shared.js +3 -3
- package/lib/module/floating/shared.js.map +1 -1
- package/lib/module/popover/Popover.js +2 -0
- package/lib/module/popover/Popover.js.map +1 -1
- package/lib/module/popover/Popover.web.js +2 -0
- package/lib/module/popover/Popover.web.js.map +1 -1
- package/lib/module/theme/color-policy.js +1 -1
- package/lib/module/theme/color-presets.js +331 -1
- package/lib/module/theme/color-presets.js.map +1 -1
- package/lib/module/theme/glass-colors.js +22 -19
- package/lib/module/theme/glass-colors.js.map +1 -1
- package/lib/typescript/commonjs/context-menu/ContextMenu.d.ts +1 -1
- package/lib/typescript/commonjs/context-menu/ContextMenu.d.ts.map +1 -1
- package/lib/typescript/commonjs/context-menu/ContextMenu.web.d.ts +1 -1
- package/lib/typescript/commonjs/context-menu/ContextMenu.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/context-menu/types.d.ts +2 -0
- package/lib/typescript/commonjs/context-menu/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/SheetShell.d.ts +4 -1
- package/lib/typescript/commonjs/dialog/SheetShell.d.ts.map +1 -1
- package/lib/typescript/commonjs/dropdown-menu/DropdownMenu.d.ts +2 -2
- package/lib/typescript/commonjs/dropdown-menu/DropdownMenu.d.ts.map +1 -1
- package/lib/typescript/commonjs/dropdown-menu/DropdownMenu.web.d.ts +1 -1
- package/lib/typescript/commonjs/dropdown-menu/DropdownMenu.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/floating/TriggerSlot.d.ts +3 -1
- package/lib/typescript/commonjs/floating/TriggerSlot.d.ts.map +1 -1
- package/lib/typescript/commonjs/floating/constants.d.ts +2 -0
- package/lib/typescript/commonjs/floating/constants.d.ts.map +1 -1
- package/lib/typescript/commonjs/floating/menu-rows.d.ts.map +1 -1
- package/lib/typescript/commonjs/floating/menu-sub-flyout.d.ts.map +1 -1
- package/lib/typescript/commonjs/floating/menu-sub-inline.d.ts.map +1 -1
- package/lib/typescript/commonjs/floating/shared.d.ts +2 -2
- package/lib/typescript/commonjs/floating/shared.d.ts.map +1 -1
- package/lib/typescript/commonjs/floating/types.d.ts +29 -3
- package/lib/typescript/commonjs/floating/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/popover/Popover.d.ts +1 -1
- package/lib/typescript/commonjs/popover/Popover.d.ts.map +1 -1
- package/lib/typescript/commonjs/popover/Popover.web.d.ts +1 -1
- package/lib/typescript/commonjs/popover/Popover.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/color-presets.d.ts +331 -1
- package/lib/typescript/commonjs/theme/color-presets.d.ts.map +1 -1
- package/lib/typescript/commonjs/theme/glass-colors.d.ts +22 -19
- package/lib/typescript/commonjs/theme/glass-colors.d.ts.map +1 -1
- package/lib/typescript/module/context-menu/ContextMenu.d.ts +1 -1
- package/lib/typescript/module/context-menu/ContextMenu.d.ts.map +1 -1
- package/lib/typescript/module/context-menu/ContextMenu.web.d.ts +1 -1
- package/lib/typescript/module/context-menu/ContextMenu.web.d.ts.map +1 -1
- package/lib/typescript/module/context-menu/types.d.ts +2 -0
- package/lib/typescript/module/context-menu/types.d.ts.map +1 -1
- package/lib/typescript/module/dialog/SheetShell.d.ts +4 -1
- package/lib/typescript/module/dialog/SheetShell.d.ts.map +1 -1
- package/lib/typescript/module/dropdown-menu/DropdownMenu.d.ts +2 -2
- package/lib/typescript/module/dropdown-menu/DropdownMenu.d.ts.map +1 -1
- package/lib/typescript/module/dropdown-menu/DropdownMenu.web.d.ts +1 -1
- package/lib/typescript/module/dropdown-menu/DropdownMenu.web.d.ts.map +1 -1
- package/lib/typescript/module/floating/TriggerSlot.d.ts +3 -1
- package/lib/typescript/module/floating/TriggerSlot.d.ts.map +1 -1
- package/lib/typescript/module/floating/constants.d.ts +2 -0
- package/lib/typescript/module/floating/constants.d.ts.map +1 -1
- package/lib/typescript/module/floating/menu-rows.d.ts.map +1 -1
- package/lib/typescript/module/floating/menu-sub-flyout.d.ts.map +1 -1
- package/lib/typescript/module/floating/menu-sub-inline.d.ts.map +1 -1
- package/lib/typescript/module/floating/shared.d.ts +2 -2
- package/lib/typescript/module/floating/shared.d.ts.map +1 -1
- package/lib/typescript/module/floating/types.d.ts +29 -3
- package/lib/typescript/module/floating/types.d.ts.map +1 -1
- package/lib/typescript/module/popover/Popover.d.ts +1 -1
- package/lib/typescript/module/popover/Popover.d.ts.map +1 -1
- package/lib/typescript/module/popover/Popover.web.d.ts +1 -1
- package/lib/typescript/module/popover/Popover.web.d.ts.map +1 -1
- package/lib/typescript/module/theme/color-presets.d.ts +331 -1
- package/lib/typescript/module/theme/color-presets.d.ts.map +1 -1
- package/lib/typescript/module/theme/glass-colors.d.ts +22 -19
- package/lib/typescript/module/theme/glass-colors.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/context-menu/ContextMenu.tsx +2 -0
- package/src/context-menu/ContextMenu.web.tsx +2 -0
- package/src/context-menu/types.ts +2 -0
- package/src/design-tokens/tokens.json +11040 -0
- package/src/dialog/SheetShell.tsx +10 -2
- package/src/dropdown-menu/DropdownMenu.tsx +11 -1
- package/src/dropdown-menu/DropdownMenu.web.tsx +2 -0
- package/src/floating/TriggerSlot.tsx +7 -3
- package/src/floating/constants.ts +3 -1
- package/src/floating/menu-rows.tsx +36 -25
- package/src/floating/menu-sub-flyout.tsx +22 -5
- package/src/floating/menu-sub-inline.tsx +12 -2
- package/src/floating/shared.tsx +11 -4
- package/src/floating/types.ts +29 -3
- package/src/popover/Popover.tsx +2 -0
- package/src/popover/Popover.web.tsx +2 -0
- package/src/theme/__tests__/__fixtures__/golden-resolved-tokens.json +3600 -0
- package/src/theme/color-policy.ts +1 -1
- package/src/theme/color-presets.ts +361 -1
- package/src/theme/glass-colors.ts +22 -19
|
@@ -15,6 +15,7 @@ import { Pressable, StyleSheet, View, type StyleProp, type ViewStyle } from 'rea
|
|
|
15
15
|
|
|
16
16
|
import { BottomSheet, type BottomSheetRef } from '../bottom-sheet';
|
|
17
17
|
import { useAccessibilityFocus } from '../hooks/use-accessibility-focus';
|
|
18
|
+
import { StyledView } from '../styles/styled-primitives';
|
|
18
19
|
import { Z_INDEX } from '../styles/z-index';
|
|
19
20
|
import { useTheme } from '../theme/use-theme';
|
|
20
21
|
import { Context } from './context';
|
|
@@ -25,8 +26,11 @@ export interface SheetShellProps {
|
|
|
25
26
|
label?: string;
|
|
26
27
|
header?: React.ReactNode;
|
|
27
28
|
onClose?: () => void;
|
|
29
|
+
/** Classes applied to the inner padded content container. */
|
|
30
|
+
contentClassName?: string;
|
|
28
31
|
/** Style overrides applied to the inner padded content container. */
|
|
29
32
|
contentStyle?: StyleProp<ViewStyle>;
|
|
33
|
+
contentTestID?: string;
|
|
30
34
|
children?: React.ReactNode;
|
|
31
35
|
}
|
|
32
36
|
|
|
@@ -40,7 +44,9 @@ export function SheetShell({
|
|
|
40
44
|
label,
|
|
41
45
|
header,
|
|
42
46
|
onClose,
|
|
47
|
+
contentClassName,
|
|
43
48
|
contentStyle,
|
|
49
|
+
contentTestID,
|
|
44
50
|
children,
|
|
45
51
|
}: SheetShellProps) {
|
|
46
52
|
const theme = useTheme();
|
|
@@ -119,7 +125,7 @@ export function SheetShell({
|
|
|
119
125
|
<Context.Provider value={context}>
|
|
120
126
|
<SheetHandle onPress={() => close()} />
|
|
121
127
|
{header}
|
|
122
|
-
<
|
|
128
|
+
<StyledView
|
|
123
129
|
// Deliberately NOT `accessible`: collapsing the body into one
|
|
124
130
|
// accessibility element would make its rows unreachable, and the
|
|
125
131
|
// focus move below would land on the group instead of the first row.
|
|
@@ -131,10 +137,12 @@ export function SheetShell({
|
|
|
131
137
|
// sheet is an RN `<Modal>`, whose `onRequestClose` it fires.
|
|
132
138
|
onAccessibilityEscape={() => close()}
|
|
133
139
|
accessibilityLabel={label}
|
|
140
|
+
className={contentClassName}
|
|
141
|
+
testID={contentTestID}
|
|
134
142
|
style={[styles.body, { backgroundColor: theme.colors.background }, contentStyle]}
|
|
135
143
|
>
|
|
136
144
|
{children}
|
|
137
|
-
</
|
|
145
|
+
</StyledView>
|
|
138
146
|
</Context.Provider>
|
|
139
147
|
</BottomSheet>
|
|
140
148
|
);
|
|
@@ -52,6 +52,7 @@ export function DropdownMenuTrigger({
|
|
|
52
52
|
asChild,
|
|
53
53
|
disabled,
|
|
54
54
|
label,
|
|
55
|
+
className,
|
|
55
56
|
style,
|
|
56
57
|
testID,
|
|
57
58
|
}: DropdownMenuTriggerProps) {
|
|
@@ -61,6 +62,7 @@ export function DropdownMenuTrigger({
|
|
|
61
62
|
<TriggerSlot
|
|
62
63
|
asChild={asChild}
|
|
63
64
|
anchorRef={menu.anchorRef}
|
|
65
|
+
className={className}
|
|
64
66
|
style={style}
|
|
65
67
|
testID={testID}
|
|
66
68
|
handle={{
|
|
@@ -79,7 +81,9 @@ export function DropdownMenuTrigger({
|
|
|
79
81
|
export function DropdownMenuContent({
|
|
80
82
|
children,
|
|
81
83
|
label = 'Menu',
|
|
84
|
+
className,
|
|
82
85
|
style,
|
|
86
|
+
testID,
|
|
83
87
|
}: DropdownMenuContentProps) {
|
|
84
88
|
const menu = useDropdownMenu();
|
|
85
89
|
const { control, onSheetClose } = useSheetOpenBridge(menu.open, menu.setOpen);
|
|
@@ -89,7 +93,13 @@ export function DropdownMenuContent({
|
|
|
89
93
|
);
|
|
90
94
|
|
|
91
95
|
return (
|
|
92
|
-
<SheetShell
|
|
96
|
+
<SheetShell
|
|
97
|
+
control={control}
|
|
98
|
+
label={label}
|
|
99
|
+
onClose={onSheetClose}
|
|
100
|
+
contentClassName={className}
|
|
101
|
+
contentStyle={style}
|
|
102
|
+
contentTestID={testID}>
|
|
93
103
|
<MenuSurfaceProvider value={surface}>{children}</MenuSurfaceProvider>
|
|
94
104
|
</SheetShell>
|
|
95
105
|
);
|
|
@@ -47,6 +47,7 @@ export function DropdownMenuTrigger({
|
|
|
47
47
|
asChild,
|
|
48
48
|
disabled,
|
|
49
49
|
label,
|
|
50
|
+
className,
|
|
50
51
|
style,
|
|
51
52
|
testID,
|
|
52
53
|
}: DropdownMenuTriggerProps) {
|
|
@@ -56,6 +57,7 @@ export function DropdownMenuTrigger({
|
|
|
56
57
|
<TriggerSlot
|
|
57
58
|
asChild={asChild}
|
|
58
59
|
anchorRef={menu.anchorRef}
|
|
60
|
+
className={className}
|
|
59
61
|
style={style}
|
|
60
62
|
testID={testID}
|
|
61
63
|
handle={{
|
|
@@ -27,7 +27,7 @@ import { StyleSheet, View, type StyleProp, type ViewStyle } from 'react-native';
|
|
|
27
27
|
|
|
28
28
|
import { useRestoreAccessibilityFocus } from '../hooks/use-accessibility-focus';
|
|
29
29
|
import { mergeRefs } from '../hooks/merge-refs';
|
|
30
|
-
import { StyledPressable } from '../styles/styled-primitives';
|
|
30
|
+
import { StyledPressable, StyledView } from '../styles/styled-primitives';
|
|
31
31
|
import type { TriggerHandleProps } from './types';
|
|
32
32
|
|
|
33
33
|
export interface TriggerSlotProps {
|
|
@@ -38,6 +38,8 @@ export interface TriggerSlotProps {
|
|
|
38
38
|
handle: TriggerHandleProps;
|
|
39
39
|
/** Measured by the web forks to position the surface. Unused on native. */
|
|
40
40
|
anchorRef?: React.RefObject<View | null>;
|
|
41
|
+
/** Classes for the wrapper box — the node the parent lays out. */
|
|
42
|
+
className?: string;
|
|
41
43
|
/** Style for the wrapper box. The child styles itself. */
|
|
42
44
|
style?: StyleProp<ViewStyle>;
|
|
43
45
|
testID?: string;
|
|
@@ -95,6 +97,7 @@ export function TriggerSlot({
|
|
|
95
97
|
children,
|
|
96
98
|
handle,
|
|
97
99
|
anchorRef,
|
|
100
|
+
className,
|
|
98
101
|
style,
|
|
99
102
|
testID,
|
|
100
103
|
}: TriggerSlotProps) {
|
|
@@ -107,9 +110,10 @@ export function TriggerSlot({
|
|
|
107
110
|
useRestoreAccessibilityFocus(handle['aria-expanded'] === true, ownRef);
|
|
108
111
|
|
|
109
112
|
return (
|
|
110
|
-
<
|
|
113
|
+
<StyledView
|
|
111
114
|
ref={mergeRefs([ownRef, anchorRef])}
|
|
112
115
|
collapsable={false}
|
|
116
|
+
className={className}
|
|
113
117
|
style={[styles.wrap, style]}
|
|
114
118
|
testID={testID}>
|
|
115
119
|
{asChild ? (
|
|
@@ -117,7 +121,7 @@ export function TriggerSlot({
|
|
|
117
121
|
) : (
|
|
118
122
|
<StyledPressable {...handle}>{children}</StyledPressable>
|
|
119
123
|
)}
|
|
120
|
-
</
|
|
124
|
+
</StyledView>
|
|
121
125
|
);
|
|
122
126
|
}
|
|
123
127
|
|
|
@@ -225,6 +225,9 @@ export const ROW_INSET_CLASS = 'pl-space-32';
|
|
|
225
225
|
/** `pl-8 pr-2` on the two rows that carry an out-of-flow indicator. */
|
|
226
226
|
export const ROW_GUTTER_CLASS = 'pl-space-32 pr-space-8';
|
|
227
227
|
|
|
228
|
+
/** `pl-2 pr-8` when that out-of-flow indicator sits on the trailing edge. */
|
|
229
|
+
export const ROW_GUTTER_END_CLASS = 'pl-space-8 pr-space-32';
|
|
230
|
+
|
|
228
231
|
/**
|
|
229
232
|
* The row's own label: `text-sm`, no weight of its own.
|
|
230
233
|
*
|
|
@@ -340,4 +343,3 @@ export const SELECT_ITEM_CLASS =
|
|
|
340
343
|
|
|
341
344
|
/** `text-foreground select-none text-sm`. */
|
|
342
345
|
export const SELECT_ITEM_TEXT_CLASS = 'flex-1 min-w-0 text-sm text-foreground';
|
|
343
|
-
|
|
@@ -48,6 +48,7 @@ import { useTheme } from '../theme/use-theme';
|
|
|
48
48
|
import {
|
|
49
49
|
ROW_ICON_SIZE,
|
|
50
50
|
ROW_INDICATOR_CLASS,
|
|
51
|
+
ROW_INDICATOR_END_CLASS,
|
|
51
52
|
ROW_LABEL_CLASS,
|
|
52
53
|
ROW_LABEL_INSET_CLASS,
|
|
53
54
|
ROW_RADIO_DOT_CLASS,
|
|
@@ -69,13 +70,13 @@ import type {
|
|
|
69
70
|
} from './types';
|
|
70
71
|
|
|
71
72
|
/**
|
|
72
|
-
* The target's
|
|
73
|
+
* The target's 32px selection gutter with its out-of-flow 14px indicator.
|
|
73
74
|
*
|
|
74
75
|
* The indicator is OUT OF FLOW, which is the whole point: a checkbox row's text
|
|
75
|
-
* starts at a fixed
|
|
76
|
-
* up
|
|
77
|
-
*
|
|
78
|
-
* would
|
|
76
|
+
* starts at a fixed inset whether or not a check is drawn, so a menu's rows line
|
|
77
|
+
* up. `indicatorPosition="trailing"` mirrors that geometry for products whose
|
|
78
|
+
* menu vocabulary puts the check at the far edge. Passing the mark as a normal
|
|
79
|
+
* slot would put it back in flow and collapse the column on an unchecked row.
|
|
79
80
|
*
|
|
80
81
|
* `pointerEvents="none"` as a PROP, not a style entry: the box sits ON TOP of
|
|
81
82
|
* the row's own pressable, so without it the indicator swallows the press that
|
|
@@ -84,15 +85,19 @@ import type {
|
|
|
84
85
|
*/
|
|
85
86
|
function IndicatorGutter({
|
|
86
87
|
indicator,
|
|
88
|
+
position,
|
|
87
89
|
children,
|
|
88
90
|
}: {
|
|
89
91
|
indicator: React.ReactNode;
|
|
92
|
+
position: 'leading' | 'trailing';
|
|
90
93
|
children: React.ReactNode;
|
|
91
94
|
}) {
|
|
92
95
|
return (
|
|
93
96
|
<StyledView className="relative">
|
|
94
97
|
{children}
|
|
95
|
-
<StyledView
|
|
98
|
+
<StyledView
|
|
99
|
+
className={position === 'leading' ? ROW_INDICATOR_CLASS : ROW_INDICATOR_END_CLASS}
|
|
100
|
+
pointerEvents="none">
|
|
96
101
|
{indicator}
|
|
97
102
|
</StyledView>
|
|
98
103
|
</StyledView>
|
|
@@ -157,6 +162,8 @@ export function createMenuRows(prefix: string, createSub: MenuSubFactory): MenuR
|
|
|
157
162
|
children,
|
|
158
163
|
checked,
|
|
159
164
|
onCheckedChange,
|
|
165
|
+
indicator,
|
|
166
|
+
indicatorPosition = 'leading',
|
|
160
167
|
disabled = false,
|
|
161
168
|
trailing,
|
|
162
169
|
keepOpen = false,
|
|
@@ -168,23 +175,26 @@ export function createMenuRows(prefix: string, createSub: MenuSubFactory): MenuR
|
|
|
168
175
|
const theme = useTheme();
|
|
169
176
|
const surface = useMenuSurface();
|
|
170
177
|
const { title, body } = splitChildren(children);
|
|
178
|
+
const selectedIndicator =
|
|
179
|
+
indicator === undefined ? (
|
|
180
|
+
<CheckIcon
|
|
181
|
+
width={ROW_ICON_SIZE}
|
|
182
|
+
height={ROW_ICON_SIZE}
|
|
183
|
+
fill={theme.colors.text}
|
|
184
|
+
/>
|
|
185
|
+
) : (
|
|
186
|
+
indicator
|
|
187
|
+
);
|
|
171
188
|
|
|
172
189
|
return (
|
|
173
190
|
<IndicatorGutter
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
<CheckIcon
|
|
177
|
-
width={ROW_ICON_SIZE}
|
|
178
|
-
height={ROW_ICON_SIZE}
|
|
179
|
-
fill={theme.colors.text}
|
|
180
|
-
/>
|
|
181
|
-
) : null
|
|
182
|
-
}>
|
|
191
|
+
position={indicatorPosition}
|
|
192
|
+
indicator={checked ? selectedIndicator : null}>
|
|
183
193
|
<MenuRowShell
|
|
184
194
|
role="checkbox"
|
|
185
195
|
checked={checked}
|
|
186
196
|
disabled={disabled}
|
|
187
|
-
gutter
|
|
197
|
+
gutter={indicatorPosition}
|
|
188
198
|
trailing={trailing}
|
|
189
199
|
title={title}
|
|
190
200
|
onPress={() => {
|
|
@@ -215,6 +225,8 @@ export function createMenuRows(prefix: string, createSub: MenuSubFactory): MenuR
|
|
|
215
225
|
function MenuRadioItem({
|
|
216
226
|
children,
|
|
217
227
|
value,
|
|
228
|
+
indicator,
|
|
229
|
+
indicatorPosition = 'leading',
|
|
218
230
|
disabled = false,
|
|
219
231
|
trailing,
|
|
220
232
|
keepOpen = false,
|
|
@@ -227,22 +239,21 @@ export function createMenuRows(prefix: string, createSub: MenuSubFactory): MenuR
|
|
|
227
239
|
const group = useMenuRadioGroup();
|
|
228
240
|
const { title, body } = splitChildren(children);
|
|
229
241
|
const checked = group.value === value;
|
|
242
|
+
// `bg-foreground h-2 w-2 rounded-full`: the established default remains a
|
|
243
|
+
// filled dot. A caller-supplied node replaces only this selected mark; the
|
|
244
|
+
// shared gutter and ARIA state remain owned here.
|
|
245
|
+
const selectedIndicator =
|
|
246
|
+
indicator === undefined ? <StyledView className={ROW_RADIO_DOT_CLASS} /> : indicator;
|
|
230
247
|
|
|
231
248
|
return (
|
|
232
249
|
<IndicatorGutter
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
// FILLED DOT with no ring, which is what fits an 8px mark inside a
|
|
236
|
-
// 14px indicator box. `radio-indicator/` draws Bloom's ringed control,
|
|
237
|
-
// a different thing at a different size, and using it here is what made
|
|
238
|
-
// a menu radio row twice the width of its checkbox sibling.
|
|
239
|
-
checked ? <StyledView className={ROW_RADIO_DOT_CLASS} /> : null
|
|
240
|
-
}>
|
|
250
|
+
position={indicatorPosition}
|
|
251
|
+
indicator={checked ? selectedIndicator : null}>
|
|
241
252
|
<MenuRowShell
|
|
242
253
|
role="radio"
|
|
243
254
|
checked={checked}
|
|
244
255
|
disabled={disabled}
|
|
245
|
-
gutter
|
|
256
|
+
gutter={indicatorPosition}
|
|
246
257
|
trailing={trailing}
|
|
247
258
|
title={title}
|
|
248
259
|
onPress={() => {
|
|
@@ -388,7 +388,19 @@ export function createFlyoutMenuSub(prefix: string): MenuSubParts {
|
|
|
388
388
|
}
|
|
389
389
|
MenuSubTrigger.displayName = `${prefix}SubTrigger`;
|
|
390
390
|
|
|
391
|
-
function MenuSubContent({
|
|
391
|
+
function MenuSubContent({
|
|
392
|
+
children,
|
|
393
|
+
label = 'Submenu',
|
|
394
|
+
side = 'right',
|
|
395
|
+
align = 'start',
|
|
396
|
+
sideOffset = MENU_SUB_SIDE_OFFSET,
|
|
397
|
+
alignOffset,
|
|
398
|
+
minWidth,
|
|
399
|
+
maxWidth,
|
|
400
|
+
className,
|
|
401
|
+
style,
|
|
402
|
+
testID,
|
|
403
|
+
}: MenuSubContentProps) {
|
|
392
404
|
const sub = useSubFlyout();
|
|
393
405
|
const anchor = useFlyoutAnchor(sub.triggerRef, sub.open);
|
|
394
406
|
const [node, setNode] = useState<View | null>(null);
|
|
@@ -445,19 +457,24 @@ export function createFlyoutMenuSub(prefix: string): MenuSubParts {
|
|
|
445
457
|
open={sub.open}
|
|
446
458
|
anchor={anchor}
|
|
447
459
|
role="menu"
|
|
448
|
-
|
|
460
|
+
label={label}
|
|
461
|
+
side={side}
|
|
449
462
|
// The panel's first row lines up with the trigger row it flew out of.
|
|
450
|
-
align=
|
|
463
|
+
align={align}
|
|
451
464
|
// Measured from the PARENT PANEL's edge, not the trigger row's — see
|
|
452
465
|
// `useFlyoutAnchor`.
|
|
453
|
-
sideOffset={
|
|
466
|
+
sideOffset={sideOffset}
|
|
467
|
+
alignOffset={alignOffset}
|
|
454
468
|
dismissible={false}
|
|
455
469
|
modal={false}
|
|
456
470
|
onDismiss={sub.closeAndRefocus}
|
|
471
|
+
minWidth={minWidth}
|
|
472
|
+
maxWidth={maxWidth}
|
|
457
473
|
// `w-64` — a sub panel is a FIXED 256px, so a column of flyouts does not
|
|
458
474
|
// step in and out as their labels change length.
|
|
459
475
|
className={cx(MENU_SUB_PANEL_CLASS, className)}
|
|
460
|
-
style={style}
|
|
476
|
+
style={style}
|
|
477
|
+
testID={testID}>
|
|
461
478
|
{/* `-mx-1 px-1 max-h-96 overflow-y-auto`: the negative inset bleeds the
|
|
462
479
|
scroller to the panel edge and pads the content back, so the
|
|
463
480
|
scrollbar is not inset by the panel's own `p-1`. It doubles as the
|
|
@@ -93,13 +93,23 @@ export function createInlineMenuSub(prefix: string): MenuSubParts {
|
|
|
93
93
|
}
|
|
94
94
|
MenuSubTrigger.displayName = `${prefix}SubTrigger`;
|
|
95
95
|
|
|
96
|
-
function MenuSubContent({
|
|
96
|
+
function MenuSubContent({
|
|
97
|
+
children,
|
|
98
|
+
label,
|
|
99
|
+
className,
|
|
100
|
+
style,
|
|
101
|
+
testID,
|
|
102
|
+
}: MenuSubContentProps) {
|
|
97
103
|
const sub = useMenuSub();
|
|
98
104
|
if (!sub.open) return null;
|
|
99
105
|
// Indented under its trigger, which is the whole visual statement an inline
|
|
100
106
|
// disclosure makes.
|
|
101
107
|
return (
|
|
102
|
-
<StyledView
|
|
108
|
+
<StyledView
|
|
109
|
+
accessibilityLabel={label}
|
|
110
|
+
className={cx('pl-space-16', className)}
|
|
111
|
+
style={style}
|
|
112
|
+
testID={testID}>
|
|
103
113
|
{children}
|
|
104
114
|
</StyledView>
|
|
105
115
|
);
|
package/src/floating/shared.tsx
CHANGED
|
@@ -47,6 +47,7 @@ import {
|
|
|
47
47
|
ROW_DISABLED_CLASS,
|
|
48
48
|
ROW_ENABLED_CLASS,
|
|
49
49
|
ROW_GUTTER_CLASS,
|
|
50
|
+
ROW_GUTTER_END_CLASS,
|
|
50
51
|
ROW_HIGHLIGHT_CLASS,
|
|
51
52
|
ROW_INSET_CLASS,
|
|
52
53
|
ROW_LEADING_CLASS,
|
|
@@ -116,8 +117,8 @@ export interface MenuRowShellProps {
|
|
|
116
117
|
destructive?: boolean;
|
|
117
118
|
/** Indent to line up with the rows that carry an indicator. */
|
|
118
119
|
inset?: boolean;
|
|
119
|
-
/** This row carries an out-of-flow indicator
|
|
120
|
-
gutter?:
|
|
120
|
+
/** This row carries an out-of-flow indicator at the named edge. */
|
|
121
|
+
gutter?: 'leading' | 'trailing';
|
|
121
122
|
leading?: React.ReactNode;
|
|
122
123
|
trailing?: React.ReactNode;
|
|
123
124
|
/** A plain-string child, rendered as the row's own label. */
|
|
@@ -146,7 +147,7 @@ export function MenuRowShell({
|
|
|
146
147
|
disabled,
|
|
147
148
|
destructive = false,
|
|
148
149
|
inset = false,
|
|
149
|
-
gutter
|
|
150
|
+
gutter,
|
|
150
151
|
leading,
|
|
151
152
|
trailing,
|
|
152
153
|
title,
|
|
@@ -164,7 +165,13 @@ export function MenuRowShell({
|
|
|
164
165
|
const rowClass = cx(
|
|
165
166
|
ROW_CLASS,
|
|
166
167
|
disabled ? ROW_DISABLED_CLASS : ROW_ENABLED_CLASS,
|
|
167
|
-
gutter
|
|
168
|
+
gutter === 'leading'
|
|
169
|
+
? ROW_GUTTER_CLASS
|
|
170
|
+
: gutter === 'trailing'
|
|
171
|
+
? ROW_GUTTER_END_CLASS
|
|
172
|
+
: inset
|
|
173
|
+
? ROW_INSET_CLASS
|
|
174
|
+
: false,
|
|
168
175
|
highlighted && ROW_HIGHLIGHT_CLASS,
|
|
169
176
|
className,
|
|
170
177
|
);
|
package/src/floating/types.ts
CHANGED
|
@@ -189,9 +189,8 @@ export interface OverlayTriggerProps {
|
|
|
189
189
|
/** Accessible name. Ignored when the `asChild` child carries its own. */
|
|
190
190
|
label?: string;
|
|
191
191
|
/**
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* the class lands alone.
|
|
192
|
+
* Bare triggers apply this to the measured anchor wrapper; families whose
|
|
193
|
+
* trigger owns chrome append it to that chrome instead.
|
|
195
194
|
*/
|
|
196
195
|
className?: string;
|
|
197
196
|
style?: StyleProp<ViewStyle>;
|
|
@@ -274,6 +273,13 @@ export interface MenuCheckboxRowProps
|
|
|
274
273
|
extends Omit<MenuRowProps, 'onPress' | 'variant' | 'leading' | 'inset'> {
|
|
275
274
|
checked: boolean;
|
|
276
275
|
onCheckedChange: (checked: boolean) => void;
|
|
276
|
+
/**
|
|
277
|
+
* Mark rendered while checked. Omit for Bloom's default check; pass `null`
|
|
278
|
+
* to suppress it or a glyph to match a product-specific menu.
|
|
279
|
+
*/
|
|
280
|
+
indicator?: React.ReactNode;
|
|
281
|
+
/** Where the mark sits. Defaults to the established leading gutter. */
|
|
282
|
+
indicatorPosition?: 'leading' | 'trailing';
|
|
277
283
|
}
|
|
278
284
|
|
|
279
285
|
export interface MenuRadioGroupProps {
|
|
@@ -285,6 +291,13 @@ export interface MenuRadioGroupProps {
|
|
|
285
291
|
export interface MenuRadioRowProps
|
|
286
292
|
extends Omit<MenuRowProps, 'onPress' | 'variant' | 'leading' | 'inset'> {
|
|
287
293
|
value: string;
|
|
294
|
+
/**
|
|
295
|
+
* Mark rendered while this value is selected. Omit for Bloom's default dot;
|
|
296
|
+
* pass `null` to suppress it or a glyph to match a product-specific menu.
|
|
297
|
+
*/
|
|
298
|
+
indicator?: React.ReactNode;
|
|
299
|
+
/** Where the mark sits. Defaults to the established leading gutter. */
|
|
300
|
+
indicatorPosition?: 'leading' | 'trailing';
|
|
288
301
|
}
|
|
289
302
|
|
|
290
303
|
export interface MenuLabelProps {
|
|
@@ -325,9 +338,22 @@ export interface MenuSubTriggerProps {
|
|
|
325
338
|
|
|
326
339
|
export interface MenuSubContentProps {
|
|
327
340
|
children?: React.ReactNode;
|
|
341
|
+
/** Accessible name of the flyout panel on web. */
|
|
342
|
+
label?: string;
|
|
343
|
+
/** Preferred lateral side on web. Defaults to `'right'` and may flip to fit. */
|
|
344
|
+
side?: Extract<FloatingSide, 'left' | 'right'>;
|
|
345
|
+
/** Vertical alignment against the sub trigger on web. Defaults to `'start'`. */
|
|
346
|
+
align?: FloatingAlign;
|
|
347
|
+
/** Gap from the parent panel edge on web. Defaults to Bloom's submenu seam. */
|
|
348
|
+
sideOffset?: number;
|
|
349
|
+
/** Vertical shift applied before viewport clamping on web. */
|
|
350
|
+
alignOffset?: number;
|
|
351
|
+
minWidth?: number;
|
|
352
|
+
maxWidth?: number;
|
|
328
353
|
/** Appended to the sub panel's own classes — see {@link MenuRowProps.className}. */
|
|
329
354
|
className?: string;
|
|
330
355
|
style?: StyleProp<ViewStyle>;
|
|
356
|
+
testID?: string;
|
|
331
357
|
}
|
|
332
358
|
|
|
333
359
|
/**
|
package/src/popover/Popover.tsx
CHANGED
|
@@ -36,6 +36,7 @@ export function PopoverTrigger({
|
|
|
36
36
|
asChild,
|
|
37
37
|
disabled,
|
|
38
38
|
label,
|
|
39
|
+
className,
|
|
39
40
|
style,
|
|
40
41
|
testID,
|
|
41
42
|
}: PopoverTriggerProps) {
|
|
@@ -45,6 +46,7 @@ export function PopoverTrigger({
|
|
|
45
46
|
<TriggerSlot
|
|
46
47
|
asChild={asChild}
|
|
47
48
|
anchorRef={popover.anchorRef}
|
|
49
|
+
className={className}
|
|
48
50
|
style={style}
|
|
49
51
|
testID={testID}
|
|
50
52
|
handle={{
|
|
@@ -36,6 +36,7 @@ export function PopoverTrigger({
|
|
|
36
36
|
asChild,
|
|
37
37
|
disabled,
|
|
38
38
|
label,
|
|
39
|
+
className,
|
|
39
40
|
style,
|
|
40
41
|
testID,
|
|
41
42
|
}: PopoverTriggerProps) {
|
|
@@ -45,6 +46,7 @@ export function PopoverTrigger({
|
|
|
45
46
|
<TriggerSlot
|
|
46
47
|
asChild={asChild}
|
|
47
48
|
anchorRef={popover.anchorRef}
|
|
49
|
+
className={className}
|
|
48
50
|
style={style}
|
|
49
51
|
testID={testID}
|
|
50
52
|
handle={{
|