diff --git a/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheet.native.tsx b/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheet.native.tsx
index d698e555c..ea910b4ea 100644
--- a/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheet.native.tsx
+++ b/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheet.native.tsx
@@ -21,6 +21,7 @@ import { ContainedButton } from '../ContainedButton';
import { GhostButton } from '../GhostButton';
import { HStack } from '../HStack';
import { IconButton } from '../IconButton';
+import { Stack } from '../Stack';
import { Title } from '../Title';
import { VStack } from '../VStack';
import { withModalBottomSheetVariation } from './ModalBottomSheetProps';
@@ -45,6 +46,7 @@ export const ModalBottomSheet = withModalBottomSheetVariation(
transitionDuration = 300,
native_swipeToCloseThreshold = 0.4,
native_swipeToCloseVelocity = 200,
+ buttonDirection = 'vertical',
}) => {
const { getResponsiveValue } = useResponsiveValue();
const { generateStyle } = useSafeArea();
@@ -202,6 +204,23 @@ export const ModalBottomSheet = withModalBottomSheetVariation(
[isOpen, renderOpener, setIsOpen]
);
+ const subButton = useMemo(
+ () =>
+ subButtonOptions ? (
+
+ subButtonOptions.onClick?.({ close: closeModal })}
+ disabled={subButtonOptions.disabled}
+ IconComponent={subButtonOptions.IconComponent}
+ >
+ {subButtonOptions.text}
+
+
+ ) : null,
+ [closeModal, subButtonOptions]
+ );
+
return (
<>
{opener}
@@ -286,27 +305,49 @@ export const ModalBottomSheet = withModalBottomSheetVariation(
)}
- {isDefined(primaryButtonOptions) &&
- !isDefined(secondaryButtonOptions) &&
- !isDefined(subButtonOptions) && (
-
- primaryButtonOptions.onClick?.({ close: closeModal })}
- full={true}
- disabled={primaryButtonOptions.disabled}
- loading={primaryButtonOptions.loading}
- IconComponent={primaryButtonOptions.IconComponent}
- >
- {primaryButtonOptions.text}
-
-
- )}
- {isDefined(primaryButtonOptions) &&
- isDefined(secondaryButtonOptions) &&
- !isDefined(subButtonOptions) && (
-
+ {isDefined(primaryButtonOptions) && !isDefined(secondaryButtonOptions) && (
+
+ primaryButtonOptions.onClick?.({ close: closeModal })}
+ full={true}
+ disabled={primaryButtonOptions.disabled}
+ loading={primaryButtonOptions.loading}
+ IconComponent={primaryButtonOptions.IconComponent}
+ >
+ {primaryButtonOptions.text}
+
+ {isDefined(subButtonOptions) && subButton}
+
+ )}
+ {!isDefined(primaryButtonOptions) && isDefined(secondaryButtonOptions) && (
+
+ secondaryButtonOptions.onClick?.({ close: closeModal })}
+ full={true}
+ disabled={secondaryButtonOptions.disabled}
+ loading={secondaryButtonOptions.loading}
+ IconComponent={secondaryButtonOptions.IconComponent}
+ >
+ {secondaryButtonOptions.text}
+
+ {isDefined(subButtonOptions) && subButton}
+
+ )}
+ {isDefined(primaryButtonOptions) && isDefined(secondaryButtonOptions) && (
+
+
{secondaryButtonOptions.text}
-
- )}
- {isDefined(primaryButtonOptions) &&
- !isDefined(secondaryButtonOptions) &&
- isDefined(subButtonOptions) && (
-
- primaryButtonOptions.onClick?.({ close: closeModal })}
- full={true}
- disabled={primaryButtonOptions.disabled}
- loading={primaryButtonOptions.loading}
- IconComponent={primaryButtonOptions.IconComponent}
- >
- {primaryButtonOptions.text}
-
-
- subButtonOptions.onClick?.({ close: closeModal })}
- disabled={subButtonOptions.disabled}
- IconComponent={subButtonOptions.IconComponent}
- >
- {subButtonOptions.text}
-
-
-
- )}
+
+ {isDefined(subButtonOptions) && subButton}
+
+ )}
diff --git a/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheet.stories.tsx b/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheet.stories.tsx
index 5e14291a9..d481c2cb2 100644
--- a/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheet.stories.tsx
+++ b/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheet.stories.tsx
@@ -145,7 +145,7 @@ export const MultipleModal: ComponentStory = () => {
);
};
-export const withButtonOptions: ComponentStory = () => (
+export const withButtonOptions: ComponentStory = props => (
= () =>
)}
primaryButtonOptions={{ text: 'primary', disabled: false }}
secondaryButtonOptions={{ text: 'secondary', disabled: false }}
+ buttonDirection={props.buttonDirection}
/>
= () =>
primaryButtonOptions={{ text: 'primary', disabled: false }}
subButtonOptions={{ text: 'sub', disabled: false }}
/>
+ (
+
+ Primary + Secondary + Sub
+
+ )}
+ primaryButtonOptions={{ text: 'primary', disabled: false }}
+ secondaryButtonOptions={{ text: 'secondary', disabled: false }}
+ subButtonOptions={{ text: 'sub', disabled: false }}
+ buttonDirection={props.buttonDirection}
+ />
);
diff --git a/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheet.tsx b/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheet.tsx
index e5fb8c852..aebc97921 100644
--- a/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheet.tsx
+++ b/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheet.tsx
@@ -21,6 +21,7 @@ import { ContainedButton } from '../ContainedButton';
import { GhostButton } from '../GhostButton';
import { HStack } from '../HStack';
import { IconButton } from '../IconButton';
+import { Stack } from '../Stack';
import { Title } from '../Title';
import { VStack } from '../VStack';
import { withModalBottomSheetVariation } from './ModalBottomSheetProps';
@@ -37,6 +38,7 @@ export const ModalBottomSheet = withModalBottomSheetVariation(
primaryButtonOptions,
secondaryButtonOptions,
subButtonOptions,
+ buttonDirection = 'vertical',
onClose,
showCloseButton = true,
dimClosable = true,
@@ -132,6 +134,23 @@ export const ModalBottomSheet = withModalBottomSheetVariation(
return () => window.removeEventListener('keydown', onKeydown);
}, [closeModal, isOpen, dimClosable, showCloseButton]);
+ const subButton = useMemo(
+ () =>
+ subButtonOptions ? (
+
+ subButtonOptions.onClick?.({ close: closeModal })}
+ disabled={subButtonOptions.disabled}
+ IconComponent={subButtonOptions.IconComponent}
+ >
+ {subButtonOptions.text}
+
+
+ ) : null,
+ [closeModal, subButtonOptions]
+ );
+
return (
<>
{opener}
@@ -196,7 +215,15 @@ export const ModalBottomSheet = withModalBottomSheetVariation(
)}
{subtitle ? (
-
+
{subtitle}
) : null}
@@ -207,7 +234,7 @@ export const ModalBottomSheet = withModalBottomSheetVariation(
)}
- {isDefined(primaryButtonOptions) && !isDefined(secondaryButtonOptions) && !isDefined(subButtonOptions) && (
+ {isDefined(primaryButtonOptions) && !isDefined(secondaryButtonOptions) && (
{primaryButtonOptions.text}
+ {isDefined(subButtonOptions) && subButton}
)}
- {isDefined(primaryButtonOptions) && isDefined(secondaryButtonOptions) && !isDefined(subButtonOptions) && (
-
- primaryButtonOptions.onClick?.({ close: closeModal })}
- full={true}
- disabled={primaryButtonOptions.disabled}
- loading={primaryButtonOptions.loading}
- IconComponent={primaryButtonOptions.IconComponent}
- >
- {primaryButtonOptions.text}
-
+
+ {!isDefined(primaryButtonOptions) && isDefined(secondaryButtonOptions) && (
+
{secondaryButtonOptions.text}
+ {isDefined(subButtonOptions) && subButton}
)}
- {isDefined(primaryButtonOptions) && !isDefined(secondaryButtonOptions) && isDefined(subButtonOptions) && (
-
- primaryButtonOptions.onClick?.({ close: closeModal })}
- full={true}
- disabled={primaryButtonOptions.disabled}
- loading={primaryButtonOptions.loading}
- IconComponent={primaryButtonOptions.IconComponent}
+
+ {isDefined(primaryButtonOptions) && isDefined(secondaryButtonOptions) && (
+
+
- {primaryButtonOptions.text}
-
-
- subButtonOptions.onClick?.({ close: closeModal })}
- disabled={subButtonOptions.disabled}
- IconComponent={subButtonOptions.IconComponent}
+ primaryButtonOptions.onClick?.({ close: closeModal })}
+ full={true}
+ disabled={primaryButtonOptions.disabled}
+ loading={primaryButtonOptions.loading}
+ IconComponent={primaryButtonOptions.IconComponent}
+ >
+ {primaryButtonOptions.text}
+
+ secondaryButtonOptions.onClick?.({ close: closeModal })}
+ full={true}
+ disabled={secondaryButtonOptions.disabled}
+ loading={secondaryButtonOptions.loading}
+ IconComponent={secondaryButtonOptions.IconComponent}
>
- {subButtonOptions.text}
-
-
+ {secondaryButtonOptions.text}
+
+
+ {isDefined(subButtonOptions) && subButton}
)}
diff --git a/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheetProps.ts b/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheetProps.ts
index 4b8f39f83..f3ad31d70 100644
--- a/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheetProps.ts
+++ b/packages/vibrant-components/src/lib/ModalBottomSheet/ModalBottomSheetProps.ts
@@ -35,23 +35,35 @@ export type ModalBottomSheetProps = Either<
* @default 200
*/
native_swipeToCloseVelocity?: number;
-} & (
- | {
- primaryButtonOptions: ButtonOptions;
- secondaryButtonOptions?: ButtonOptions;
- subButtonOptions?: never;
- }
- | {
- primaryButtonOptions: ButtonOptions;
- secondaryButtonOptions?: never;
- subButtonOptions?: Omit;
- }
- | {
- primaryButtonOptions?: never;
- secondaryButtonOptions?: never;
- subButtonOptions?: never;
- }
- );
+} & (NoButtons | PrimaryButtonOnly | PrimarySecondaryButtons | SecondaryButtonOnly);
+
+type PrimaryButtonOnly = {
+ primaryButtonOptions: ButtonOptions;
+ secondaryButtonOptions?: never;
+ subButtonOptions?: Omit;
+ buttonDirection?: never;
+};
+
+type SecondaryButtonOnly = {
+ primaryButtonOptions?: never;
+ secondaryButtonOptions: ButtonOptions;
+ subButtonOptions?: Omit;
+ buttonDirection?: never;
+};
+
+type PrimarySecondaryButtons = {
+ primaryButtonOptions: ButtonOptions;
+ secondaryButtonOptions: ButtonOptions;
+ subButtonOptions?: Omit;
+ buttonDirection?: 'horizontal' | 'vertical';
+};
+
+type NoButtons = {
+ primaryButtonOptions?: never;
+ secondaryButtonOptions?: never;
+ subButtonOptions?: never;
+ buttonDirection?: never;
+};
export type ButtonOptions = {
kind?: 'primary' | 'secondary' | 'tertiary';