@oxyhq/bloom 0.50.0 → 0.50.2
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/bottom-sheet/index.web.js +3 -2
- package/lib/commonjs/bottom-sheet/index.web.js.map +1 -1
- package/lib/commonjs/context-menu/index.web.js +3 -7
- package/lib/commonjs/context-menu/index.web.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.js +18 -15
- package/lib/commonjs/dialog/Dialog.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.web.js +17 -23
- package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
- package/lib/commonjs/dialog/DialogHeader.js +84 -13
- package/lib/commonjs/dialog/DialogHeader.js.map +1 -1
- package/lib/commonjs/menu/index.web.js +3 -7
- package/lib/commonjs/menu/index.web.js.map +1 -1
- package/lib/commonjs/popover/index.web.js +5 -7
- package/lib/commonjs/popover/index.web.js.map +1 -1
- package/lib/commonjs/select/index.web.js +3 -7
- package/lib/commonjs/select/index.web.js.map +1 -1
- package/lib/commonjs/slider/Slider.js +4 -9
- package/lib/commonjs/slider/Slider.js.map +1 -1
- package/lib/commonjs/switch/Switch.js +4 -8
- package/lib/commonjs/switch/Switch.js.map +1 -1
- package/lib/commonjs/tabs/Tabs.js +3 -8
- package/lib/commonjs/tabs/Tabs.js.map +1 -1
- package/lib/commonjs/toast/Toast.js +3 -8
- package/lib/commonjs/toast/Toast.js.map +1 -1
- package/lib/module/bottom-sheet/index.web.js +3 -2
- package/lib/module/bottom-sheet/index.web.js.map +1 -1
- package/lib/module/context-menu/index.web.js +3 -7
- package/lib/module/context-menu/index.web.js.map +1 -1
- package/lib/module/dialog/Dialog.js +19 -16
- package/lib/module/dialog/Dialog.js.map +1 -1
- package/lib/module/dialog/Dialog.web.js +18 -24
- package/lib/module/dialog/Dialog.web.js.map +1 -1
- package/lib/module/dialog/DialogHeader.js +83 -12
- package/lib/module/dialog/DialogHeader.js.map +1 -1
- package/lib/module/menu/index.web.js +3 -7
- package/lib/module/menu/index.web.js.map +1 -1
- package/lib/module/popover/index.web.js +5 -7
- package/lib/module/popover/index.web.js.map +1 -1
- package/lib/module/select/index.web.js +3 -7
- package/lib/module/select/index.web.js.map +1 -1
- package/lib/module/slider/Slider.js +4 -9
- package/lib/module/slider/Slider.js.map +1 -1
- package/lib/module/switch/Switch.js +4 -8
- package/lib/module/switch/Switch.js.map +1 -1
- package/lib/module/tabs/Tabs.js +3 -8
- package/lib/module/tabs/Tabs.js.map +1 -1
- package/lib/module/toast/Toast.js +3 -8
- package/lib/module/toast/Toast.js.map +1 -1
- package/lib/typescript/commonjs/context-menu/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/DialogHeader.d.ts +13 -0
- package/lib/typescript/commonjs/dialog/DialogHeader.d.ts.map +1 -1
- package/lib/typescript/commonjs/menu/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/popover/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/select/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/slider/Slider.d.ts.map +1 -1
- package/lib/typescript/commonjs/switch/Switch.d.ts.map +1 -1
- package/lib/typescript/commonjs/tabs/Tabs.d.ts.map +1 -1
- package/lib/typescript/commonjs/toast/Toast.d.ts.map +1 -1
- package/lib/typescript/module/context-menu/index.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.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 +13 -0
- package/lib/typescript/module/dialog/DialogHeader.d.ts.map +1 -1
- package/lib/typescript/module/menu/index.web.d.ts.map +1 -1
- package/lib/typescript/module/popover/index.web.d.ts.map +1 -1
- package/lib/typescript/module/select/index.web.d.ts.map +1 -1
- package/lib/typescript/module/slider/Slider.d.ts.map +1 -1
- package/lib/typescript/module/switch/Switch.d.ts.map +1 -1
- package/lib/typescript/module/tabs/Tabs.d.ts.map +1 -1
- package/lib/typescript/module/toast/Toast.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/bottom-sheet/index.web.tsx +1 -1
- package/src/context-menu/index.web.tsx +3 -4
- package/src/dialog/Dialog.tsx +10 -7
- package/src/dialog/Dialog.web.tsx +12 -12
- package/src/dialog/DialogHeader.tsx +93 -17
- package/src/menu/index.web.tsx +3 -4
- package/src/popover/index.web.tsx +5 -4
- package/src/select/index.web.tsx +3 -4
- package/src/slider/Slider.tsx +3 -5
- package/src/switch/Switch.tsx +4 -5
- package/src/tabs/Tabs.tsx +3 -5
- package/src/toast/Toast.tsx +3 -5
|
@@ -21,6 +21,7 @@ import { RemoveScrollBar } from 'react-remove-scroll-bar';
|
|
|
21
21
|
|
|
22
22
|
import { Portal } from '../portal/index.web';
|
|
23
23
|
import { createOverlayZIndex } from '../styles/z-index';
|
|
24
|
+
import { bloomShadowStyle } from '../design-tokens/shadows';
|
|
24
25
|
import { useTheme } from '../theme/use-theme';
|
|
25
26
|
import { Context, useDialogContext, useDialogControl } from './context';
|
|
26
27
|
import { DialogBody } from './DialogContent';
|
|
@@ -29,6 +30,7 @@ import {
|
|
|
29
30
|
DIALOG_NAV_BAR_HEIGHT,
|
|
30
31
|
DialogHeaderProvider,
|
|
31
32
|
DialogLargeTitle,
|
|
33
|
+
DialogNavBarSpacer,
|
|
32
34
|
DialogNavHeader,
|
|
33
35
|
useDialogHeaderController,
|
|
34
36
|
} from './DialogHeader';
|
|
@@ -467,10 +469,9 @@ function DialogPanel({
|
|
|
467
469
|
backgroundColor: theme.colors.background,
|
|
468
470
|
borderWidth: 1,
|
|
469
471
|
borderColor: theme.isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)',
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
shadowOffset: { width: 0, height: 4 },
|
|
472
|
+
// Design-system overlay elevation (`shadow-m`) as a `boxShadow` — RN-Web
|
|
473
|
+
// deprecated the `shadow*` style props.
|
|
474
|
+
...bloomShadowStyle('m'),
|
|
474
475
|
zIndex: surfaceZIndex,
|
|
475
476
|
},
|
|
476
477
|
isClosing
|
|
@@ -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
|
) : (
|
|
@@ -671,9 +672,8 @@ function SheetSurface({
|
|
|
671
672
|
|
|
672
673
|
return (
|
|
673
674
|
<View
|
|
674
|
-
style={[sheetStyles.root, { zIndex: backdropZIndex }, containerStyle]}
|
|
675
|
+
style={[sheetStyles.root, { zIndex: backdropZIndex }, containerStyle, { pointerEvents: 'box-none' }]}
|
|
675
676
|
{...(containerClassName ? ({ className: containerClassName } as Record<string, string>) : {})}
|
|
676
|
-
pointerEvents="box-none"
|
|
677
677
|
>
|
|
678
678
|
<Pressable
|
|
679
679
|
testID={testID ? `${testID}-backdrop` : DIALOG_SHEET_BACKDROP_TESTID}
|
|
@@ -703,15 +703,16 @@ function SheetSurface({
|
|
|
703
703
|
sheetStyles.panel,
|
|
704
704
|
{
|
|
705
705
|
backgroundColor: theme.colors.background,
|
|
706
|
-
shadowColor: theme.colors.shadow,
|
|
707
706
|
zIndex: surfaceZIndex,
|
|
707
|
+
pointerEvents: 'auto',
|
|
708
|
+
// Design-system overlay elevation (`shadow-m`) as a `boxShadow`.
|
|
709
|
+
...bloomShadowStyle('m'),
|
|
708
710
|
},
|
|
709
711
|
panelGeometry,
|
|
710
712
|
panelTransition,
|
|
711
713
|
panelStyle,
|
|
712
714
|
style,
|
|
713
715
|
]}
|
|
714
|
-
pointerEvents="auto"
|
|
715
716
|
>
|
|
716
717
|
{header ? (
|
|
717
718
|
// Nav-header mode on a side drawer: a static titled bar (the drawer
|
|
@@ -859,9 +860,8 @@ const sheetStyles = {
|
|
|
859
860
|
panel: {
|
|
860
861
|
position: 'absolute',
|
|
861
862
|
overflow: 'hidden',
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
shadowOffset: { width: 0, height: 8 },
|
|
863
|
+
// Elevation is applied at the usage site via `bloomShadowStyle('m')`
|
|
864
|
+
// (`boxShadow` on web); the deprecated `shadow*` props were removed.
|
|
865
865
|
} as ViewStyle,
|
|
866
866
|
};
|
|
867
867
|
|
|
@@ -106,6 +106,62 @@ interface HeaderStore {
|
|
|
106
106
|
subscribe: (listener: () => void) => () => void;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
type PrimaryAction = NonNullable<DialogHeaderConfig['primaryAction']>;
|
|
110
|
+
type HeaderAction = NonNullable<DialogHeaderConfig['actions']>[number];
|
|
111
|
+
type HeaderSearch = NonNullable<DialogHeaderConfig['search']>;
|
|
112
|
+
type HeaderSegments = NonNullable<DialogHeaderConfig['segments']>;
|
|
113
|
+
type HeaderProgress = NonNullable<DialogHeaderConfig['progress']>;
|
|
114
|
+
|
|
115
|
+
function primaryActionEqual(a: PrimaryAction | undefined, b: PrimaryAction | undefined): boolean {
|
|
116
|
+
if (a === b) return true;
|
|
117
|
+
if (!a || !b) return false;
|
|
118
|
+
// `onPress` is a fresh closure each render — its identity never changes what the
|
|
119
|
+
// button renders, so compare only the render-affecting scalars.
|
|
120
|
+
return a.label === b.label && !!a.disabled === !!b.disabled && !!a.loading === !!b.loading;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function actionsEqual(a: HeaderAction[] | undefined, b: HeaderAction[] | undefined): boolean {
|
|
124
|
+
if (a === b) return true;
|
|
125
|
+
if (!a || !b || a.length !== b.length) return false;
|
|
126
|
+
for (let i = 0; i < a.length; i += 1) {
|
|
127
|
+
const x = a[i];
|
|
128
|
+
const y = b[i];
|
|
129
|
+
if (!x || !y) return false;
|
|
130
|
+
// `icon` is a memoized node (compared by identity); `onPress` is ignored.
|
|
131
|
+
if (
|
|
132
|
+
x.accessibilityLabel !== y.accessibilityLabel ||
|
|
133
|
+
!!x.disabled !== !!y.disabled ||
|
|
134
|
+
x.icon !== y.icon
|
|
135
|
+
) {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function searchEqual(a: HeaderSearch | undefined, b: HeaderSearch | undefined): boolean {
|
|
143
|
+
if (a === b) return true;
|
|
144
|
+
if (!a || !b) return false;
|
|
145
|
+
return a.value === b.value && a.placeholder === b.placeholder;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function segmentsEqual(a: HeaderSegments | undefined, b: HeaderSegments | undefined): boolean {
|
|
149
|
+
if (a === b) return true;
|
|
150
|
+
if (!a || !b || a.value !== b.value || a.items.length !== b.items.length) return false;
|
|
151
|
+
for (let i = 0; i < a.items.length; i += 1) {
|
|
152
|
+
const ai = a.items[i];
|
|
153
|
+
const bi = b.items[i];
|
|
154
|
+
if (!ai || !bi || ai.key !== bi.key || ai.label !== bi.label) return false;
|
|
155
|
+
}
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function progressEqual(a: HeaderProgress | undefined, b: HeaderProgress | undefined): boolean {
|
|
160
|
+
if (a === b) return true;
|
|
161
|
+
if (!a || !b) return false;
|
|
162
|
+
return a.step === b.step && a.total === b.total;
|
|
163
|
+
}
|
|
164
|
+
|
|
109
165
|
function configsEqual(a: DialogHeaderConfig | null, b: DialogHeaderConfig | null): boolean {
|
|
110
166
|
if (a === b) return true;
|
|
111
167
|
if (!a || !b) return false;
|
|
@@ -116,16 +172,20 @@ function configsEqual(a: DialogHeaderConfig | null, b: DialogHeaderConfig | null
|
|
|
116
172
|
a.largeTitle === b.largeTitle &&
|
|
117
173
|
a.left === b.left &&
|
|
118
174
|
a.right === b.right &&
|
|
119
|
-
|
|
175
|
+
// `onBack` legitimately gets a fresh closure each render; its identity never
|
|
176
|
+
// changes what the header renders, so compare by PRESENCE, never identity —
|
|
177
|
+
// treating a new ref as "changed" is exactly what drives the update loop.
|
|
178
|
+
!!a.onBack === !!b.onBack &&
|
|
120
179
|
a.showClose === b.showClose &&
|
|
121
|
-
// Rich fields —
|
|
122
|
-
// `
|
|
123
|
-
a
|
|
124
|
-
a.actions === b.actions &&
|
|
125
|
-
a.search === b.search &&
|
|
126
|
-
a.segments === b.segments &&
|
|
180
|
+
// Rich fields — compared by VALUE (render-affecting scalars only). A caller
|
|
181
|
+
// passing an inline `primaryAction`/`actions`/… object (a fresh reference
|
|
182
|
+
// every render) must NOT force a store update: that is React error #185.
|
|
127
183
|
a.tone === b.tone &&
|
|
128
|
-
a.
|
|
184
|
+
primaryActionEqual(a.primaryAction, b.primaryAction) &&
|
|
185
|
+
actionsEqual(a.actions, b.actions) &&
|
|
186
|
+
searchEqual(a.search, b.search) &&
|
|
187
|
+
segmentsEqual(a.segments, b.segments) &&
|
|
188
|
+
progressEqual(a.progress, b.progress)
|
|
129
189
|
);
|
|
130
190
|
}
|
|
131
191
|
|
|
@@ -474,28 +534,23 @@ export const DialogNavHeader = memo(function DialogNavHeader({
|
|
|
474
534
|
) : null);
|
|
475
535
|
|
|
476
536
|
return (
|
|
477
|
-
<View
|
|
478
|
-
pointerEvents="box-none"
|
|
479
|
-
style={[styles.overlay, style]}
|
|
480
|
-
>
|
|
537
|
+
<View style={[styles.overlay, style, { pointerEvents: 'box-none' }]}>
|
|
481
538
|
{/* Opaque (surface bg) at the top → transparent at the bottom, so scrolled
|
|
482
539
|
content fades out under the bar. `onImage` swaps to a dark scrim so the
|
|
483
540
|
chrome reads over media. Pure NativeWind — no SVG dependency. */}
|
|
484
541
|
<View
|
|
485
|
-
pointerEvents="none"
|
|
486
542
|
className={
|
|
487
543
|
onImage
|
|
488
544
|
? 'bg-gradient-to-b from-black/60 to-transparent'
|
|
489
545
|
: 'bg-gradient-to-b from-bg to-transparent'
|
|
490
546
|
}
|
|
491
|
-
style={[StyleSheet.absoluteFill, { height: DIALOG_HEADER_OVERLAY_HEIGHT }]}
|
|
547
|
+
style={[StyleSheet.absoluteFill, { height: DIALOG_HEADER_OVERLAY_HEIGHT, pointerEvents: 'none' }]}
|
|
492
548
|
/>
|
|
493
|
-
<View
|
|
549
|
+
<View style={[styles.navRow, { pointerEvents: 'box-none' }]}>
|
|
494
550
|
<View style={styles.side}>{left}</View>
|
|
495
551
|
<Animated.View
|
|
496
|
-
pointerEvents="none"
|
|
497
552
|
testID="dialog-nav-title"
|
|
498
|
-
style={[styles.centerTitle, titleStyle]}
|
|
553
|
+
style={[styles.centerTitle, titleStyle, { pointerEvents: 'none' }]}
|
|
499
554
|
>
|
|
500
555
|
{config.titleContent ?? null}
|
|
501
556
|
{!config.titleContent && config.title ? (
|
|
@@ -624,6 +679,27 @@ export const DialogLargeTitle = memo(function DialogLargeTitle({
|
|
|
624
679
|
);
|
|
625
680
|
});
|
|
626
681
|
|
|
682
|
+
/**
|
|
683
|
+
* The nav-bar-height content inset for a header-mode surface whose content owns
|
|
684
|
+
* its own scroll (`scrollable: false`) — the account dialog or an own-scroller
|
|
685
|
+
* like the media picker. Under `tone: 'onImage'` it COLLAPSES to nothing so the
|
|
686
|
+
* media (photo grid / banner) slides UP under the floating translucent nav bar,
|
|
687
|
+
* edge-to-edge (Apple/Material immersive photo grid); otherwise it insets the
|
|
688
|
+
* content below the bar. Reads the merged (base + runtime-override) tone, since
|
|
689
|
+
* `tone` is contributed by the mounted screen through the override store.
|
|
690
|
+
*/
|
|
691
|
+
export const DialogNavBarSpacer = memo(function DialogNavBarSpacer({
|
|
692
|
+
controller,
|
|
693
|
+
header,
|
|
694
|
+
}: {
|
|
695
|
+
controller: DialogHeaderController;
|
|
696
|
+
header: DialogHeaderConfig;
|
|
697
|
+
}) {
|
|
698
|
+
const config = useMergedHeaderConfig(header, controller.store);
|
|
699
|
+
if (config.tone === 'onImage') return null;
|
|
700
|
+
return <View style={{ height: DIALOG_NAV_BAR_HEIGHT }} />;
|
|
701
|
+
});
|
|
702
|
+
|
|
627
703
|
const styles = StyleSheet.create({
|
|
628
704
|
overlay: {
|
|
629
705
|
position: 'absolute',
|
package/src/menu/index.web.tsx
CHANGED
|
@@ -17,6 +17,7 @@ import { Text } from '../typography';
|
|
|
17
17
|
import type { DialogControlProps } from '../dialog/types';
|
|
18
18
|
import { Portal } from '../portal/index.web';
|
|
19
19
|
import { createDropdownZIndex } from '../styles/z-index';
|
|
20
|
+
import { bloomShadowStyle } from '../design-tokens/shadows';
|
|
20
21
|
import {
|
|
21
22
|
MenuContext,
|
|
22
23
|
ItemContext,
|
|
@@ -255,7 +256,7 @@ export function MenuContent({
|
|
|
255
256
|
? theme.colors.backgroundSecondary
|
|
256
257
|
: theme.colors.background,
|
|
257
258
|
borderColor: theme.colors.borderLight,
|
|
258
|
-
|
|
259
|
+
...bloomShadowStyle('m'),
|
|
259
260
|
},
|
|
260
261
|
style,
|
|
261
262
|
styles.portaledDropdown,
|
|
@@ -393,9 +394,7 @@ const styles = StyleSheet.create({
|
|
|
393
394
|
borderWidth: 1,
|
|
394
395
|
overflow: 'hidden',
|
|
395
396
|
zIndex: menuZIndex.surface,
|
|
396
|
-
|
|
397
|
-
shadowRadius: 12,
|
|
398
|
-
shadowOffset: { width: 0, height: 4 },
|
|
397
|
+
// Overlay elevation applied at the usage site via `bloomShadowStyle('m')`.
|
|
399
398
|
minWidth: 180,
|
|
400
399
|
},
|
|
401
400
|
portaledDropdown: {
|
|
@@ -12,6 +12,7 @@ import { Pressable, StyleSheet, View } from 'react-native';
|
|
|
12
12
|
import { useTheme } from '../theme/use-theme';
|
|
13
13
|
import { Portal } from '../portal/index.web';
|
|
14
14
|
import { createOverlayZIndex } from '../styles/z-index';
|
|
15
|
+
import { bloomShadowStyle } from '../design-tokens/shadows';
|
|
15
16
|
import { PopoverContext, usePopoverContext } from './context';
|
|
16
17
|
import type {
|
|
17
18
|
PopoverContentProps,
|
|
@@ -288,7 +289,9 @@ export function PopoverContent({
|
|
|
288
289
|
? theme.colors.backgroundSecondary
|
|
289
290
|
: theme.colors.background,
|
|
290
291
|
borderColor: theme.colors.borderLight,
|
|
291
|
-
|
|
292
|
+
// Design-system overlay elevation (`shadow-m`) as a `boxShadow` —
|
|
293
|
+
// RN-Web deprecated the `shadow*` style props.
|
|
294
|
+
...bloomShadowStyle('m'),
|
|
292
295
|
// Hide until measured to avoid a one-frame jump.
|
|
293
296
|
opacity: panelSize ? 1 : 0,
|
|
294
297
|
},
|
|
@@ -320,9 +323,7 @@ const styles = StyleSheet.create({
|
|
|
320
323
|
borderWidth: 1,
|
|
321
324
|
paddingVertical: 4,
|
|
322
325
|
overflow: 'hidden',
|
|
323
|
-
|
|
324
|
-
shadowRadius: 12,
|
|
325
|
-
shadowOffset: { width: 0, height: 4 },
|
|
326
|
+
// Elevation applied at the usage site via `bloomShadowStyle('m')` (boxShadow).
|
|
326
327
|
pointerEvents: 'auto',
|
|
327
328
|
},
|
|
328
329
|
});
|
package/src/select/index.web.tsx
CHANGED
|
@@ -5,6 +5,7 @@ import { useTheme } from '../theme/use-theme';
|
|
|
5
5
|
import { Text } from '../typography';
|
|
6
6
|
import { Portal } from '../portal/index.web';
|
|
7
7
|
import { createOverlayZIndex } from '../styles/z-index';
|
|
8
|
+
import { bloomShadowStyle } from '../design-tokens/shadows';
|
|
8
9
|
import { RadioIndicator } from '../radio-indicator';
|
|
9
10
|
import { useInteractionState } from '../hooks/useInteractionState';
|
|
10
11
|
import {
|
|
@@ -201,7 +202,7 @@ export function SelectContent<T>({
|
|
|
201
202
|
? theme.colors.backgroundSecondary
|
|
202
203
|
: theme.colors.background,
|
|
203
204
|
borderColor: theme.colors.borderLight,
|
|
204
|
-
|
|
205
|
+
...bloomShadowStyle('m'),
|
|
205
206
|
},
|
|
206
207
|
]}
|
|
207
208
|
>
|
|
@@ -348,9 +349,7 @@ const styles = StyleSheet.create({
|
|
|
348
349
|
overflow: 'hidden',
|
|
349
350
|
padding: 4,
|
|
350
351
|
minWidth: 180,
|
|
351
|
-
|
|
352
|
-
shadowRadius: 12,
|
|
353
|
-
shadowOffset: { width: 0, height: 4 },
|
|
352
|
+
// Overlay elevation applied at the usage site via `bloomShadowStyle('m')`.
|
|
354
353
|
// Opt back in from the Portal root's `pointer-events: none`.
|
|
355
354
|
pointerEvents: 'auto',
|
|
356
355
|
},
|
package/src/slider/Slider.tsx
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
|
|
13
13
|
import { useTheme } from '../theme/use-theme';
|
|
14
14
|
import { animation } from '../styles/tokens';
|
|
15
|
+
import { bloomShadowStyle } from '../design-tokens/shadows';
|
|
15
16
|
import type { SliderProps } from './types';
|
|
16
17
|
|
|
17
18
|
function clamp(v: number, min: number, max: number): number {
|
|
@@ -236,7 +237,6 @@ const SliderComponent = function Slider({
|
|
|
236
237
|
backgroundColor: thumbColor,
|
|
237
238
|
left: thumbLeft,
|
|
238
239
|
transform: [{ scale: thumbScale }],
|
|
239
|
-
shadowColor: theme.colors.shadow,
|
|
240
240
|
},
|
|
241
241
|
]}
|
|
242
242
|
/>
|
|
@@ -261,10 +261,8 @@ const styles = StyleSheet.create({
|
|
|
261
261
|
thumb: {
|
|
262
262
|
position: 'absolute',
|
|
263
263
|
top: '50%',
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
shadowRadius: 2,
|
|
267
|
-
elevation: 2,
|
|
264
|
+
// Subtle raise (`shadow-s`) — `boxShadow` on web, RN shadow/elevation on native.
|
|
265
|
+
...bloomShadowStyle('s'),
|
|
268
266
|
},
|
|
269
267
|
disabled: {
|
|
270
268
|
opacity: 0.5,
|
package/src/switch/Switch.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import { Pressable, Animated, StyleSheet } from 'react-native';
|
|
|
3
3
|
|
|
4
4
|
import { useTheme } from '../theme/use-theme';
|
|
5
5
|
import { animation } from '../styles/tokens';
|
|
6
|
+
import { bloomShadowStyle } from '../design-tokens/shadows';
|
|
6
7
|
import type { SwitchProps } from './types';
|
|
7
8
|
|
|
8
9
|
const TRACK = { default: { w: 44, h: 26 }, sm: { w: 36, h: 22 } } as const;
|
|
@@ -128,10 +129,8 @@ const styles = StyleSheet.create({
|
|
|
128
129
|
},
|
|
129
130
|
thumb: {
|
|
130
131
|
backgroundColor: '#fff',
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
shadowRadius: 3,
|
|
135
|
-
elevation: 3,
|
|
132
|
+
// Subtle raise (`shadow-s`) — `boxShadow` on web (RN-Web deprecated `shadow*`),
|
|
133
|
+
// RN elevation/shadow on native.
|
|
134
|
+
...bloomShadowStyle('s'),
|
|
136
135
|
},
|
|
137
136
|
});
|
package/src/tabs/Tabs.tsx
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
import { useTheme } from '../theme/use-theme';
|
|
23
23
|
import { usePressAnimation } from '../hooks/usePressAnimation';
|
|
24
24
|
import { borderRadius, space } from '../styles/tokens';
|
|
25
|
+
import { bloomShadowStyle } from '../design-tokens/shadows';
|
|
25
26
|
import type { TabsProps, TabsTriggerProps, TabsContentProps, TabsVariant } from './types';
|
|
26
27
|
|
|
27
28
|
type TriggerLayout = Pick<LayoutRectangle, 'x' | 'width'>;
|
|
@@ -226,11 +227,8 @@ const TabComponent: React.FC<TabsTriggerProps> = ({
|
|
|
226
227
|
if (isSelected) {
|
|
227
228
|
base.backgroundColor = theme.colors.card;
|
|
228
229
|
base.borderRadius = borderRadius.xs + 2;
|
|
229
|
-
|
|
230
|
-
base
|
|
231
|
-
base.shadowOpacity = 0.1;
|
|
232
|
-
base.shadowRadius = 2;
|
|
233
|
-
base.elevation = 1;
|
|
230
|
+
// Subtle raise (`shadow-s`) — `boxShadow` on web, RN shadow/elevation on native.
|
|
231
|
+
Object.assign(base, bloomShadowStyle('s'));
|
|
234
232
|
}
|
|
235
233
|
break;
|
|
236
234
|
case 'outlined':
|
package/src/toast/Toast.tsx
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
|
|
10
10
|
import { useTheme } from '../theme/use-theme';
|
|
11
11
|
import { useInteractionState } from '../hooks/useInteractionState';
|
|
12
|
+
import { bloomShadowStyle } from '../design-tokens/shadows';
|
|
12
13
|
import type { ThemeColors } from '../theme/types';
|
|
13
14
|
import { dismiss } from './sonner';
|
|
14
15
|
import type { ToastType } from './types';
|
|
@@ -242,11 +243,8 @@ const styles = StyleSheet.create({
|
|
|
242
243
|
flexDirection: 'row',
|
|
243
244
|
gap: 8,
|
|
244
245
|
paddingVertical: 14,
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
shadowOpacity: 0.05,
|
|
248
|
-
shadowRadius: 2,
|
|
249
|
-
elevation: 2,
|
|
246
|
+
// Subtle raise (`shadow-s`) — `boxShadow` on web, RN shadow/elevation on native.
|
|
247
|
+
...bloomShadowStyle('s'),
|
|
250
248
|
},
|
|
251
249
|
textContainer: {
|
|
252
250
|
flex: 1,
|