diff --git a/example/.rnstorybook/stories/Organisms/Toaster/Toaster.stories.tsx b/example/.rnstorybook/stories/Organisms/Toaster/Toaster.stories.tsx
index e95bf80..083a327 100644
--- a/example/.rnstorybook/stories/Organisms/Toaster/Toaster.stories.tsx
+++ b/example/.rnstorybook/stories/Organisms/Toaster/Toaster.stories.tsx
@@ -116,6 +116,35 @@ const InsideModalDemo = () => (
);
+const LoadingDemo = () => (
+
+
+ ToasterApi.show({
+ type: 'info',
+ title: 'Loading...',
+ loading: true,
+ })
+ }
+ />
+
+ ToasterApi.show({
+ type: 'success',
+ title: 'Done!',
+ description: 'Action completed.',
+ })
+ }
+ />
+ ToasterApi.hide()}
+ />
+
+);
+
const meta = {
title: 'Organisms/Toaster',
component: View,
@@ -136,3 +165,7 @@ export const Interactive: Story = {
export const InsideModal: Story = {
render: () => ,
};
+
+export const Loading: Story = {
+ render: () => ,
+};
diff --git a/src/components/Atoms/Icon/index.tsx b/src/components/Atoms/Icon/index.tsx
index 72d1797..2373455 100644
--- a/src/components/Atoms/Icon/index.tsx
+++ b/src/components/Atoms/Icon/index.tsx
@@ -6,11 +6,19 @@ import { useRubberDuckStore } from '../../../store';
import { buildSize } from './library';
export const Icon: React.FC = (props) => {
- const { icon, size, color = "textPrimary" } = props;
+ const {
+ icon,
+ size,
+ color = "textPrimary",
+ hexColor,
+ } = props;
const colors = useRubberDuckStore((s) => s.colors);
const iconSize = buildSize(size);
const IconComponent = Icons[icon] as LucideIcon;
+ const resolvedColor = hexColor ?? colors[color];
- return ;
+ return ;
};
+
+export type { IconName } from './types';
diff --git a/src/components/Atoms/Icon/types/IIconProps.ts b/src/components/Atoms/Icon/types/IIconProps.ts
index 0e91def..2e586c8 100644
--- a/src/components/Atoms/Icon/types/IIconProps.ts
+++ b/src/components/Atoms/Icon/types/IIconProps.ts
@@ -6,4 +6,5 @@ export type IIconProps = {
icon: IconName;
size?: IconSize;
color?: keyof IColors;
+ hexColor?: string;
};
diff --git a/src/components/Atoms/Switch/index.tsx b/src/components/Atoms/Switch/index.tsx
index 69a665d..d4ae04a 100644
--- a/src/components/Atoms/Switch/index.tsx
+++ b/src/components/Atoms/Switch/index.tsx
@@ -11,7 +11,7 @@ export const Switch: React.FC = (props) => {
const { isOn, disabled } = props;
const colors = useRubberDuckStore((s) => s.colors);
- const styles = useStyles();
+ const styles = useStyles(!!disabled);
const reanimatedStyles = useReanimatedStyles({
isOn: !!isOn,
accentColor: colors.accent,
diff --git a/src/components/Atoms/Switch/styles.ts b/src/components/Atoms/Switch/styles.ts
index a09d9e9..aa755c4 100644
--- a/src/components/Atoms/Switch/styles.ts
+++ b/src/components/Atoms/Switch/styles.ts
@@ -3,7 +3,7 @@ import { useRubberDuckStore } from '../../../store';
import { Tokens } from '../../../tokens/Tokens.class';
import { SWITCH_TRACK_WIDTH, SWITCH_TRACK_HEIGHT, SWITCH_THUMB_SIZE, SWITCH_PADDING } from './constants';
-export const useStyles = () => {
+export const useStyles = (disabled: boolean) => {
const colors = useRubberDuckStore((s) => s.colors);
return StyleSheet.create({
@@ -13,6 +13,7 @@ export const useStyles = () => {
borderRadius: Tokens.radii({ key: 'full' }),
padding: SWITCH_PADDING,
justifyContent: 'center',
+ opacity: disabled ? 0.8 : 1,
},
thumb: {
diff --git a/src/components/Molecules/Inputs/MoneyField/index.tsx b/src/components/Molecules/Inputs/MoneyField/index.tsx
index 6136fb6..1f5e5a9 100644
--- a/src/components/Molecules/Inputs/MoneyField/index.tsx
+++ b/src/components/Molecules/Inputs/MoneyField/index.tsx
@@ -33,7 +33,7 @@ export const MoneyField: React.FC = (props) => {
const reanimatedStyles = useReanimatedStyles({
isFocused,
accentColor: colors.accent,
- borderDefaultColor: colors.borderDefault,
+ borderDefaultColor: colors.borderSubtle,
});
return (
diff --git a/src/components/Molecules/Inputs/MoneyField/styles.ts b/src/components/Molecules/Inputs/MoneyField/styles.ts
index 76eab75..922d3ad 100644
--- a/src/components/Molecules/Inputs/MoneyField/styles.ts
+++ b/src/components/Molecules/Inputs/MoneyField/styles.ts
@@ -22,7 +22,7 @@ export const useStyles = (props: IMoneyFieldProps) => {
inputWrapper: {
borderWidth: 2,
- borderColor: colors.borderDefault,
+ borderColor: colors.borderSubtle,
borderRadius: Tokens.radii({ key: 'lg' }),
backgroundColor: colors.background,
},
diff --git a/src/components/Molecules/Inputs/MultilineText/index.tsx b/src/components/Molecules/Inputs/MultilineText/index.tsx
index 0fed200..875a076 100644
--- a/src/components/Molecules/Inputs/MultilineText/index.tsx
+++ b/src/components/Molecules/Inputs/MultilineText/index.tsx
@@ -32,7 +32,7 @@ export const MultilineText: React.FC = (props) => {
const reanimatedStyles = useReanimatedStyles({
isFocused,
accentColor: colors.accent,
- borderDefaultColor: colors.borderDefault,
+ borderDefaultColor: colors.borderSubtle,
});
return (
diff --git a/src/components/Molecules/Inputs/MultilineText/styles.ts b/src/components/Molecules/Inputs/MultilineText/styles.ts
index e8d3cb1..d938a63 100644
--- a/src/components/Molecules/Inputs/MultilineText/styles.ts
+++ b/src/components/Molecules/Inputs/MultilineText/styles.ts
@@ -22,7 +22,7 @@ export const useStyles = (props: IMultilineTextProps) => {
inputWrapper: {
borderWidth: 2,
- borderColor: colors.borderDefault,
+ borderColor: colors.borderSubtle,
borderRadius: Tokens.radii({ key: 'lg' }),
backgroundColor: colors.background,
minHeight: 24 * numberOfLines,
diff --git a/src/components/Molecules/Inputs/NumberField/index.tsx b/src/components/Molecules/Inputs/NumberField/index.tsx
index 898d536..a91b586 100644
--- a/src/components/Molecules/Inputs/NumberField/index.tsx
+++ b/src/components/Molecules/Inputs/NumberField/index.tsx
@@ -32,7 +32,7 @@ export const NumberField: React.FC = (props) => {
const reanimatedStyles = useReanimatedStyles({
isFocused,
accentColor: colors.accent,
- borderDefaultColor: colors.borderDefault,
+ borderDefaultColor: colors.borderSubtle,
});
return (
diff --git a/src/components/Molecules/Inputs/NumberField/styles.ts b/src/components/Molecules/Inputs/NumberField/styles.ts
index 7f95f5d..4312fd3 100644
--- a/src/components/Molecules/Inputs/NumberField/styles.ts
+++ b/src/components/Molecules/Inputs/NumberField/styles.ts
@@ -24,7 +24,7 @@ export const useStyles = (props: INumberFieldProps) => {
flexDirection: 'row',
alignItems: 'center',
borderWidth: 2,
- borderColor: colors.borderDefault,
+ borderColor: colors.borderSubtle,
borderRadius: Tokens.radii({ key: 'lg' }),
backgroundColor: colors.background,
},
diff --git a/src/components/Molecules/Inputs/SimpleText/index.tsx b/src/components/Molecules/Inputs/SimpleText/index.tsx
index 6635242..5d33c2e 100644
--- a/src/components/Molecules/Inputs/SimpleText/index.tsx
+++ b/src/components/Molecules/Inputs/SimpleText/index.tsx
@@ -23,18 +23,18 @@ export const SimpleText: React.FC = (props) => {
const colors = useRubberDuckStore((s) => s.colors);
const styles = useStyles(props);
-
+
const {
isFocused,
onFocus,
onBlur,
onChangeText,
} = useSimpleTextViewModel(props);
-
+
const reanimatedStyles = useReanimatedStyles({
isFocused,
accentColor: colors.accent,
- borderDefaultColor: colors.borderDefault,
+ borderDefaultColor: colors.borderSubtle,
});
return (
diff --git a/src/components/Molecules/Inputs/SimpleText/styles.ts b/src/components/Molecules/Inputs/SimpleText/styles.ts
index bb7a2bf..18b2ae6 100644
--- a/src/components/Molecules/Inputs/SimpleText/styles.ts
+++ b/src/components/Molecules/Inputs/SimpleText/styles.ts
@@ -24,7 +24,7 @@ export const useStyles = (props: ISimpleTextProps) => {
flexDirection: 'row',
alignItems: 'center',
borderWidth: 2,
- borderColor: colors.borderDefault,
+ borderColor: colors.borderSubtle,
borderRadius: Tokens.radii({ key: 'lg' }),
backgroundColor: colors.background,
},
diff --git a/src/components/Organisms/BottomListModal/components/ModalList/library/mountRenderItem.tsx b/src/components/Organisms/BottomListModal/components/ModalList/library/mountRenderItem.tsx
index 451ff2c..cd0790b 100644
--- a/src/components/Organisms/BottomListModal/components/ModalList/library/mountRenderItem.tsx
+++ b/src/components/Organisms/BottomListModal/components/ModalList/library/mountRenderItem.tsx
@@ -31,26 +31,32 @@ export const mountRenderItem = (params: IMountRenderItemParams): ListRenderItem<
switch (item.type) {
case 'checkbox':
return (
-
+
-
+
);
case 'radio':
return (
-
+
-
+
);
case 'avatar':
diff --git a/src/components/Organisms/BottomModal/components/ModalBackground/index.tsx b/src/components/Organisms/BottomModal/components/ModalBackground/index.tsx
new file mode 100644
index 0000000..186cfb4
--- /dev/null
+++ b/src/components/Organisms/BottomModal/components/ModalBackground/index.tsx
@@ -0,0 +1,13 @@
+import type { BottomSheetBackgroundProps } from '@gorhom/bottom-sheet';
+import React from 'react';
+import Animated from 'react-native-reanimated';
+import { useStyles } from './styles';
+
+export const ModalBackground: React.FC = (props) => {
+ const { style } = props;
+ const styles = useStyles();
+
+ return (
+
+ );
+};
diff --git a/src/components/Organisms/BottomModal/components/ModalBackground/styles.ts b/src/components/Organisms/BottomModal/components/ModalBackground/styles.ts
new file mode 100644
index 0000000..4097754
--- /dev/null
+++ b/src/components/Organisms/BottomModal/components/ModalBackground/styles.ts
@@ -0,0 +1,15 @@
+import { StyleSheet } from 'react-native';
+import { useRubberDuckStore } from '../../../../../store';
+import { Tokens } from '../../../../../tokens/Tokens.class';
+
+export const useStyles = () => {
+ const colors = useRubberDuckStore((s) => s.colors);
+
+ return StyleSheet.create({
+ background: {
+ borderTopRightRadius: Tokens.radii({ key: 'lg' }),
+ borderTopLeftRadius: Tokens.radii({ key: 'lg' }),
+ backgroundColor: colors.surface,
+ },
+ });
+};
diff --git a/src/components/Organisms/BottomModal/components/index.ts b/src/components/Organisms/BottomModal/components/index.ts
new file mode 100644
index 0000000..fb9ea79
--- /dev/null
+++ b/src/components/Organisms/BottomModal/components/index.ts
@@ -0,0 +1 @@
+export * from './ModalBackground';
diff --git a/src/components/Organisms/BottomModal/index.tsx b/src/components/Organisms/BottomModal/index.tsx
index 01e6779..e432cb7 100644
--- a/src/components/Organisms/BottomModal/index.tsx
+++ b/src/components/Organisms/BottomModal/index.tsx
@@ -8,6 +8,7 @@ import {
} from '@gorhom/bottom-sheet';
import { useStyles } from './styles';
import { useBottomModalViewModel } from './hooks';
+import { ModalBackground } from './components';
export const BottomModal: React.FC = () => {
const { height: screenHeight } = useWindowDimensions();
@@ -33,8 +34,8 @@ export const BottomModal: React.FC = () => {
enableDynamicSizing
maxDynamicContentSize={screenHeight * 0.85}
backdropComponent={renderBackdrop}
+ backgroundComponent={ModalBackground}
handleIndicatorStyle={styles.handleIndicator}
- backgroundStyle={styles.background}
enablePanDownToClose>
{bottomModalProps?.content ?? null}
diff --git a/src/components/Organisms/BottomModal/styles.ts b/src/components/Organisms/BottomModal/styles.ts
index 5375534..6368db9 100644
--- a/src/components/Organisms/BottomModal/styles.ts
+++ b/src/components/Organisms/BottomModal/styles.ts
@@ -12,9 +12,5 @@ export const useStyles = () => {
height: 4,
borderRadius: Tokens.radii({ key: 'full' }),
},
-
- background: {
- backgroundColor: colors.surface,
- },
});
};
diff --git a/src/components/Organisms/Toaster/hooks/useToasterViewModel/index.ts b/src/components/Organisms/Toaster/hooks/useToasterViewModel/index.ts
index 5e9931c..f234e0a 100644
--- a/src/components/Organisms/Toaster/hooks/useToasterViewModel/index.ts
+++ b/src/components/Organisms/Toaster/hooks/useToasterViewModel/index.ts
@@ -24,7 +24,9 @@ export const useToasterViewModel = (ref: Ref | null) => {
clearTimer();
setToasterPropsState(props);
setIsVisible(true);
- timeoutRef.current = setTimeout(() => setIsVisible(false), props.duration ?? DEFAULT_TOAST_DURATION_MS);
+ if (!props.loading) {
+ timeoutRef.current = setTimeout(() => setIsVisible(false), props.duration ?? DEFAULT_TOAST_DURATION_MS);
+ }
};
const hide = () => {
diff --git a/src/components/Organisms/Toaster/index.tsx b/src/components/Organisms/Toaster/index.tsx
index 57c1d65..26faca2 100644
--- a/src/components/Organisms/Toaster/index.tsx
+++ b/src/components/Organisms/Toaster/index.tsx
@@ -8,45 +8,62 @@ import { useToasterViewModel, useReanimatedStyles } from './hooks';
import { TYPE_ICON_MAP } from './constants';
import { Text } from '../../Atoms/Text';
import { Icon } from '../../Atoms/Icon';
+import { Loading } from '../../Atoms/Loading';
export const Toaster: React.FC = ({ ref }) => {
const { toasterProps, isVisible, hide } = useToasterViewModel(ref ?? null);
const styles = useStyles(toasterProps?.type);
const reanimatedStyles = useReanimatedStyles(isVisible, hide);
+ const isLoading = toasterProps?.loading ?? false;
+
return (
+ style={[isLoading ? styles.wrapperLoading : styles.wrapper, reanimatedStyles.wrapper]}>
{toasterProps
?
<>
-
-
-
- {toasterProps.title}
-
- {toasterProps.description
- ?
-
- {toasterProps.description}
+ {isLoading
+ ?
+ <>
+
+
+
+ {toasterProps.title}
- : null
- }
-
+ >
+ :
+ <>
+
+
+
+ {toasterProps.title}
+
+
+ {toasterProps.description
+ ?
+
+ {toasterProps.description}
+
+ : null
+ }
+
-
-
-
+
+
+
+ >
+ }
>
: null
}
diff --git a/src/components/Organisms/Toaster/styles.ts b/src/components/Organisms/Toaster/styles.ts
index 7d18a3e..bf36a75 100644
--- a/src/components/Organisms/Toaster/styles.ts
+++ b/src/components/Organisms/Toaster/styles.ts
@@ -30,6 +30,20 @@ export const useStyles = (type: ToasterType | undefined) => {
zIndex: 999,
},
+ wrapperLoading: {
+ position: 'absolute',
+ bottom: Tokens.spacer({ key: 'lg' }),
+ alignSelf: 'center',
+ paddingVertical: Tokens.spacer({ key: 'sm' }),
+ paddingHorizontal: Tokens.spacer({ key: 'md' }),
+ borderRadius: Tokens.radii({ key: 'full' }),
+ flexDirection: 'row',
+ alignItems: 'center',
+ gap: Tokens.spacer({ key: 'xs' }),
+ backgroundColor,
+ zIndex: 999,
+ },
+
textWrapper: {
flex: 1,
},
diff --git a/src/components/Organisms/Toaster/types/IToasterRefProps.ts b/src/components/Organisms/Toaster/types/IToasterRefProps.ts
index 85f5bed..ccbfda1 100644
--- a/src/components/Organisms/Toaster/types/IToasterRefProps.ts
+++ b/src/components/Organisms/Toaster/types/IToasterRefProps.ts
@@ -5,4 +5,5 @@ export interface IToasterRefProps {
title: string;
description?: string;
duration?: number;
+ loading?: boolean;
}
diff --git a/src/index.ts b/src/index.ts
index e5db9e2..8c075cc 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -2,3 +2,4 @@ export * from './RubberDuckUI.class';
export * from './components';
export * from './hooks';
export * from './provider';
+export * from './tokens';
diff --git a/src/tokens/colors/dark.ts b/src/tokens/colors/dark.ts
index 3c8ca17..1c00339 100644
--- a/src/tokens/colors/dark.ts
+++ b/src/tokens/colors/dark.ts
@@ -5,17 +5,17 @@ export const dark: IColors = {
accentLight: '#FFE033',
accentDark: '#CCB000',
accentMuted: '#FFD60021',
- background: '#0A0A0A',
- surface: '#111111',
- surfaceRaised: '#1A1A1A',
- surfaceOverlay: '#222222',
+ background: '#080808',
+ surface: '#1C1C1E',
+ surfaceRaised: '#2C2C2E',
+ surfaceOverlay: '#3A3A3C',
textPrimary: '#F5F5F5',
textSecondary: '#A0A0A0',
textDisabled: '#555555',
textInverse: '#0A0A0A',
- borderSubtle: '#2A2A2A',
- borderDefault: '#3A3A3A',
- borderStrong: '#555555',
+ borderSubtle: '#3A3A3C',
+ borderDefault: '#505052',
+ borderStrong: '#6E6E70',
success: '#22C55E',
error: '#EF4444',
warning: '#F97316',
diff --git a/src/tokens/colors/light.ts b/src/tokens/colors/light.ts
index 7194af1..abf2735 100644
--- a/src/tokens/colors/light.ts
+++ b/src/tokens/colors/light.ts
@@ -5,10 +5,10 @@ export const light: IColors = {
accentLight: '#FFE033',
accentDark: '#CCB000',
accentMuted: '#FFD60026',
- background: '#FFFFFF',
- surface: '#F5F5F5',
- surfaceRaised: '#EFEFEF',
- surfaceOverlay: '#E5E5E5',
+ background: '#F5F5F5',
+ surface: '#FFFFFF',
+ surfaceRaised: '#E5E5EA',
+ surfaceOverlay: '#EBEBEB',
textPrimary: '#0A0A0A',
textSecondary: '#555555',
textDisabled: '#AAAAAA',
diff --git a/src/tokens/index.ts b/src/tokens/index.ts
new file mode 100644
index 0000000..84a8c07
--- /dev/null
+++ b/src/tokens/index.ts
@@ -0,0 +1 @@
+export type { IColors } from './colors/types';