From ee62633584bd2584f671063813475559840c020a Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Wed, 6 May 2026 19:56:09 -0300 Subject: [PATCH 01/13] feat(Icon): export IconName type Co-Authored-By: Claude Sonnet 4.6 --- src/components/Atoms/Icon/index.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/Atoms/Icon/index.tsx b/src/components/Atoms/Icon/index.tsx index 72d1797..b89acb0 100644 --- a/src/components/Atoms/Icon/index.tsx +++ b/src/components/Atoms/Icon/index.tsx @@ -14,3 +14,5 @@ export const Icon: React.FC = (props) => { return ; }; + +export type { IconName } from './types'; From 956fbd68d53580880f84446a7ecb49483dd05b93 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Wed, 6 May 2026 20:03:16 -0300 Subject: [PATCH 02/13] feat: export IColors type Co-Authored-By: Claude Sonnet 4.6 --- src/index.ts | 1 + src/tokens/index.ts | 1 + 2 files changed, 2 insertions(+) create mode 100644 src/tokens/index.ts 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/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'; From bd0625c54aee16b45b2bea14a737a65179ecf33a Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Wed, 6 May 2026 20:11:16 -0300 Subject: [PATCH 03/13] feat(Icon): add hexColor prop Co-Authored-By: Claude Sonnet 4.6 --- src/components/Atoms/Icon/index.tsx | 10 ++++++++-- src/components/Atoms/Icon/types/IIconProps.ts | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/components/Atoms/Icon/index.tsx b/src/components/Atoms/Icon/index.tsx index b89acb0..2373455 100644 --- a/src/components/Atoms/Icon/index.tsx +++ b/src/components/Atoms/Icon/index.tsx @@ -6,13 +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; }; From d82ab7c4da5df97e12120667445b7b91f41d9411 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Wed, 6 May 2026 20:51:24 -0300 Subject: [PATCH 04/13] chore(colors): update dark theme values Co-Authored-By: Claude Sonnet 4.6 --- src/tokens/colors/dark.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/tokens/colors/dark.ts b/src/tokens/colors/dark.ts index 3c8ca17..5dad651 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: '#1C1C1E', + surface: '#000000', + 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', From 2b2f68ea3d3c6722d9f41c0182a5f28eee1e6398 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Thu, 7 May 2026 00:42:55 -0300 Subject: [PATCH 05/13] chore(colors): update dark and light theme values Co-Authored-By: Claude Sonnet 4.6 --- src/tokens/colors/dark.ts | 4 ++-- src/tokens/colors/light.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tokens/colors/dark.ts b/src/tokens/colors/dark.ts index 5dad651..1c00339 100644 --- a/src/tokens/colors/dark.ts +++ b/src/tokens/colors/dark.ts @@ -5,8 +5,8 @@ export const dark: IColors = { accentLight: '#FFE033', accentDark: '#CCB000', accentMuted: '#FFD60021', - background: '#1C1C1E', - surface: '#000000', + background: '#080808', + surface: '#1C1C1E', surfaceRaised: '#2C2C2E', surfaceOverlay: '#3A3A3C', textPrimary: '#F5F5F5', 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', From 945ea9238eb10aa87ff20a621911a0d8ff539301 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Thu, 7 May 2026 00:43:01 -0300 Subject: [PATCH 06/13] feat(Switch): apply opacity when disabled Co-Authored-By: Claude Sonnet 4.6 --- src/components/Atoms/Switch/index.tsx | 2 +- src/components/Atoms/Switch/styles.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) 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: { From cef3805b8dafcfd6823312a7a7d2bad24d9dece9 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Thu, 7 May 2026 00:43:07 -0300 Subject: [PATCH 07/13] fix(Inputs): use borderSubtle instead of borderDefault Co-Authored-By: Claude Sonnet 4.6 --- src/components/Molecules/Inputs/MoneyField/index.tsx | 2 +- src/components/Molecules/Inputs/MoneyField/styles.ts | 2 +- src/components/Molecules/Inputs/MultilineText/index.tsx | 2 +- src/components/Molecules/Inputs/MultilineText/styles.ts | 2 +- src/components/Molecules/Inputs/NumberField/index.tsx | 2 +- src/components/Molecules/Inputs/NumberField/styles.ts | 2 +- src/components/Molecules/Inputs/SimpleText/index.tsx | 6 +++--- src/components/Molecules/Inputs/SimpleText/styles.ts | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) 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, }, From 0e8571a3f34a7bc6df409c5dfdb69f855ae8ea5c Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Thu, 7 May 2026 04:20:36 -0300 Subject: [PATCH 08/13] refactor(BottomModal): extract background into component Move backgroundColor styling from main component into a dedicated ModalBackground component for better separation of concerns. Co-Authored-By: Claude Haiku 4.5 --- .../components/ModalBackground/index.tsx | 13 +++++++++++++ .../components/ModalBackground/styles.ts | 12 ++++++++++++ .../Organisms/BottomModal/components/index.ts | 1 + src/components/Organisms/BottomModal/index.tsx | 3 ++- src/components/Organisms/BottomModal/styles.ts | 4 ---- 5 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 src/components/Organisms/BottomModal/components/ModalBackground/index.tsx create mode 100644 src/components/Organisms/BottomModal/components/ModalBackground/styles.ts create mode 100644 src/components/Organisms/BottomModal/components/index.ts 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..0bef560 --- /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 { View } from 'react-native'; +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..ce34c9f --- /dev/null +++ b/src/components/Organisms/BottomModal/components/ModalBackground/styles.ts @@ -0,0 +1,12 @@ +import { StyleSheet } from 'react-native'; +import { useRubberDuckStore } from '../../../../../store'; + +export const useStyles = () => { + const colors = useRubberDuckStore((s) => s.colors); + + return StyleSheet.create({ + background: { + 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, - }, }); }; From 5ed0dacafce7ee0ed58c7cda5f9276d054f940b5 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Thu, 7 May 2026 04:23:50 -0300 Subject: [PATCH 09/13] refactor(BottomModal): use Animated.View for background Co-Authored-By: Claude Haiku 4.5 --- .../BottomModal/components/ModalBackground/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Organisms/BottomModal/components/ModalBackground/index.tsx b/src/components/Organisms/BottomModal/components/ModalBackground/index.tsx index 0bef560..186cfb4 100644 --- a/src/components/Organisms/BottomModal/components/ModalBackground/index.tsx +++ b/src/components/Organisms/BottomModal/components/ModalBackground/index.tsx @@ -1,6 +1,6 @@ import type { BottomSheetBackgroundProps } from '@gorhom/bottom-sheet'; import React from 'react'; -import { View } from 'react-native'; +import Animated from 'react-native-reanimated'; import { useStyles } from './styles'; export const ModalBackground: React.FC = (props) => { @@ -8,6 +8,6 @@ export const ModalBackground: React.FC = (props) => const styles = useStyles(); return ( - + ); }; From c6ac42d53798d70eb3a24b1462195e46ae1b8b9f Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Thu, 7 May 2026 04:28:18 -0300 Subject: [PATCH 10/13] style(ModalBackground): add border radius Co-Authored-By: Claude Haiku 4.5 --- .../Organisms/BottomModal/components/ModalBackground/styles.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/Organisms/BottomModal/components/ModalBackground/styles.ts b/src/components/Organisms/BottomModal/components/ModalBackground/styles.ts index ce34c9f..4097754 100644 --- a/src/components/Organisms/BottomModal/components/ModalBackground/styles.ts +++ b/src/components/Organisms/BottomModal/components/ModalBackground/styles.ts @@ -1,11 +1,14 @@ 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, }, }); From a610daa99a656daad82d7270aadbc948aa1684ba Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Thu, 7 May 2026 04:32:57 -0300 Subject: [PATCH 11/13] refactor(ModalList): use TouchableOpacity for item wrapping Replace View with TouchableOpacity for checkbox and radio items to enable visual feedback on interaction (0.8 activeOpacity) and move onPress handling to container level. Co-Authored-By: Claude Haiku 4.5 --- .../ModalList/library/mountRenderItem.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) 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': From 71c7a7e9045f8685ddc82e991de5c8f2691f82d1 Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Sat, 16 May 2026 14:40:10 -0300 Subject: [PATCH 12/13] feat(Toaster): add loading state support - Conditionally render Loading spinner in lieu of icon - Skip auto-dismiss when loading is enabled - Add wrapperLoading style variant for centered layout Co-Authored-By: Claude Haiku 4.5 --- .../hooks/useToasterViewModel/index.ts | 4 +- src/components/Organisms/Toaster/index.tsx | 65 ++++++++++++------- src/components/Organisms/Toaster/styles.ts | 14 ++++ .../Toaster/types/IToasterRefProps.ts | 1 + 4 files changed, 59 insertions(+), 25 deletions(-) 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; } From a0c6fcc55e3d7644d53847438e1894ba40429a2f Mon Sep 17 00:00:00 2001 From: eumaninho54 Date: Sat, 16 May 2026 14:40:13 -0300 Subject: [PATCH 13/13] test(Toaster): add Loading story Demonstrate loading and resolve flow with toggle buttons. Co-Authored-By: Claude Haiku 4.5 --- .../Organisms/Toaster/Toaster.stories.tsx | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) 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: () => , +};