├── .nvmrc ├── src ├── loading │ ├── loading.type.ts │ └── loading.tsx ├── skeleton │ ├── skeleton.type.ts │ └── skeleton.tsx ├── types │ ├── common.js │ ├── common.d.ts │ └── common.ts ├── collapse │ ├── collapse.type.ts │ └── collapse.tsx ├── utils │ ├── index.d.ts │ ├── index.ts │ └── index.js ├── Navtabs │ ├── Navtabs.type.ts │ └── Navtabs.tsx ├── tabs │ ├── tabs.type.ts │ └── tabs.tsx ├── navigationbar │ ├── navigationbar.type.ts │ └── navigationbar.tsx ├── segmentedswitchios │ ├── segmentedswitchios.type.ts │ └── segmentedswitchios.tsx ├── dialog │ ├── dialog.type.ts │ └── dialog.tsx ├── Tile │ └── Tile.type.ts ├── emptystates │ ├── emptystates.type.ts │ └── emptystates.tsx ├── card │ ├── card.type.ts │ ├── card.tsx │ └── section.tsx ├── iosmodalsheets │ ├── iosmodalsheets.type.ts │ └── iosmodalsheets.tsx ├── statusbutton │ ├── statusbutton.type.ts │ └── statusbutton.tsx ├── bottomnav │ ├── bottomnav.type.ts │ └── bottomnav.tsx ├── androidmodalsheets │ ├── androidmodalsheets.type.ts │ └── androidmodalsheets.tsx ├── select │ ├── select.type.ts │ └── select.tsx ├── socialmediastack │ ├── socialmediastack.tsx │ ├── socialmediastack.type.ts │ ├── storyprogressbar.tsx │ ├── socialmediaengagement.tsx │ └── socialmediacontainer.tsx ├── Input │ ├── Input.type.ts │ ├── NormalInput.tsx │ ├── Input.tsx │ └── Autocomplete.tsx ├── bottomsheet │ ├── bottomsheet.type.ts │ └── bottomsheet.tsx ├── Button │ ├── Button.type.ts │ ├── rect.tsx │ ├── icon.tsx │ ├── Button.tsx │ └── typeDoc.tsx ├── index.tsx ├── grid │ ├── Grid.type.ts │ └── grid.tsx ├── alert │ ├── alert.type.ts │ └── alert.tsx ├── socialbuttons │ ├── socialbuttons.type.ts │ ├── socialbuttons.tsx │ └── sociallogin.tsx ├── iconography │ ├── iconography.type.ts │ └── iconography.tsx ├── sociallogin.tsx ├── index.ts ├── logo.svg └── styles │ └── global.css ├── postcss.config.cjs ├── nativewind-env.d.ts ├── babel.config.cjs ├── lefthook.yml ├── .github ├── ISSUE_TEMPLATE │ ├── config.yml │ ├── feature-request.yml │ └── bug-report.yml └── PULL_REQUEST_TEMPLATE.md ├── .editorconfig ├── .gitignore ├── tsconfig.json ├── LICENSE ├── SECURITY.md ├── tsconfig.build.json ├── CONTRIBUTING.md ├── package.json ├── CODE_OF_CONDUCT.md └── allprops.ts /.nvmrc: -------------------------------------------------------------------------------- 1 | v20 2 | -------------------------------------------------------------------------------- /src/loading/loading.type.ts: -------------------------------------------------------------------------------- 1 | export interface LoadingProps { 2 | description?: string; 3 | } 4 | -------------------------------------------------------------------------------- /src/skeleton/skeleton.type.ts: -------------------------------------------------------------------------------- 1 | export interface SkeletonProps { 2 | className?: string; 3 | } 4 | -------------------------------------------------------------------------------- /src/types/common.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /nativewind-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | // NOTE: This file should not be edited and should be committed with your source code. It is generated by NativeWind. -------------------------------------------------------------------------------- /src/collapse/collapse.type.ts: -------------------------------------------------------------------------------- 1 | export interface CollapsibleProps { 2 | title: string; 3 | text?: string; 4 | initialCollapsed?: boolean; 5 | children?: React.ReactNode; 6 | } 7 | -------------------------------------------------------------------------------- /src/utils/index.d.ts: -------------------------------------------------------------------------------- 1 | export { default as createStyle, useStyle, mergeStyles, isNativeWindAvailable } from './styleCompat'; 2 | export type { StyleCompatProps, RNStyle } from './styleCompat'; 3 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | // Main compatibility utilities 2 | export { default as createStyle, useStyle, mergeStyles, isNativeWindAvailable } from './styleCompat'; 3 | export type { StyleCompatProps, RNStyle } from './styleCompat'; 4 | -------------------------------------------------------------------------------- /babel.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | api.cache(true); 3 | return { 4 | presets: [ 5 | ["babel-preset-expo", { jsxImportSource: "nativewind" }], 6 | "nativewind/babel", 7 | ], 8 | }; 9 | }; -------------------------------------------------------------------------------- /src/Navtabs/Navtabs.type.ts: -------------------------------------------------------------------------------- 1 | import { ContainerComponentProps } from '../types/common'; 2 | 3 | export interface NavTabProps extends ContainerComponentProps { 4 | tabs: string[]; 5 | initialActiveIndex?: number; 6 | onTabChange?: (index: number) => void; 7 | } 8 | -------------------------------------------------------------------------------- /src/tabs/tabs.type.ts: -------------------------------------------------------------------------------- 1 | type MessageType = 'none' | 'help' | 'error'; 2 | 3 | export interface TabsProps { 4 | label: string; 5 | placeholder?: string; 6 | value?: string; 7 | messageType?: MessageType; 8 | message?: string; 9 | onPress?: () => void; 10 | } -------------------------------------------------------------------------------- /src/navigationbar/navigationbar.type.ts: -------------------------------------------------------------------------------- 1 | export interface NavigationBarProps { 2 | title: string; 3 | device?: 'ios' | 'android'; 4 | action?: 1 | 2 | 3; 5 | size?: 'compact' | 'expandable'; 6 | onClose?: () => void; 7 | onClipboard?: () => void; 8 | onForward?: () => void; 9 | } -------------------------------------------------------------------------------- /src/segmentedswitchios/segmentedswitchios.type.ts: -------------------------------------------------------------------------------- 1 | export interface SegmentedSwitchIOSProps { 2 | title: string; 3 | items: string[]; 4 | selectedIndex?: number | null; 5 | messageType?: 'none' | 'help' | 'error'; 6 | message?: string; 7 | onChange?: (index: number) => void; 8 | } -------------------------------------------------------------------------------- /src/dialog/dialog.type.ts: -------------------------------------------------------------------------------- 1 | import { ContainerComponentProps } from '../types/common'; 2 | 3 | export interface DialogProps extends ContainerComponentProps { 4 | title: string; 5 | description: string; 6 | buttonLabel: string; 7 | onButtonPress: () => void; 8 | children: React.ReactNode; 9 | } 10 | -------------------------------------------------------------------------------- /src/Tile/Tile.type.ts: -------------------------------------------------------------------------------- 1 | export type TileProps = { 2 | w?: number; 3 | h?: number; 4 | label: string; 5 | paragraph?: string; 6 | variant?: "variant-1" | "variant-2" | "variant-3" | "variant-4" | "variant-5" | "variant-6"; 7 | icon?: "sheart" | "heart" | "box" | "label"; 8 | enabled?: boolean; 9 | selected?: boolean; 10 | }; -------------------------------------------------------------------------------- /src/emptystates/emptystates.type.ts: -------------------------------------------------------------------------------- 1 | import { ReactNode } from "react"; 2 | 3 | type ActionType = "none" | "primary" | "secondary"; 4 | 5 | export interface EmptyStateProps { 6 | message: string; 7 | description?: string; 8 | label?: string; 9 | onPress?: () => void; 10 | action?: ActionType; 11 | children?: ReactNode; 12 | } -------------------------------------------------------------------------------- /lefthook.yml: -------------------------------------------------------------------------------- 1 | pre-commit: 2 | parallel: true 3 | commands: 4 | lint: 5 | glob: "*.{js,ts,jsx,tsx}" 6 | run: npx eslint {staged_files} 7 | types: 8 | glob: "*.{js,ts, jsx, tsx}" 9 | run: npx tsc 10 | commit-msg: 11 | parallel: true 12 | commands: 13 | commitlint: 14 | run: npx commitlint --edit 15 | -------------------------------------------------------------------------------- /src/card/card.type.ts: -------------------------------------------------------------------------------- 1 | import { ReactNode } from "react"; 2 | 3 | export interface CardProps { 4 | title?: string; 5 | label?: string; 6 | cardTitle?: boolean; 7 | button?: boolean; 8 | children?: ReactNode; 9 | } 10 | export interface CardSectionProps { 11 | title?: string; 12 | icon?: boolean; 13 | onPress?: () => void; 14 | } 15 | -------------------------------------------------------------------------------- /src/iosmodalsheets/iosmodalsheets.type.ts: -------------------------------------------------------------------------------- 1 | import { ReactNode } from 'react'; 2 | 3 | export interface IOSModalSheetProps { 4 | title: string; 5 | label: string; 6 | action?: 1 | 2 | 3; 7 | compact?: boolean; 8 | onClose?: () => void; 9 | onButtonPress?: () => void; 10 | onClipboard?: () => void; 11 | onForward?: () => void; 12 | children?: ReactNode; 13 | } -------------------------------------------------------------------------------- /src/statusbutton/statusbutton.type.ts: -------------------------------------------------------------------------------- 1 | type StatusType = 'information' | 'success' | 'warning' | 'error'; 2 | type ButtonType = 'primary' | 'subtle'; 3 | 4 | export interface StatusButtonProps { 5 | label?: string; 6 | type?: StatusType; 7 | buttonType?: ButtonType; 8 | iconLeft?: boolean; 9 | iconRight?: boolean; 10 | iconOnly?: boolean; 11 | onPress?: () => void; 12 | } -------------------------------------------------------------------------------- /src/bottomnav/bottomnav.type.ts: -------------------------------------------------------------------------------- 1 | export interface NavItemProps { 2 | icon: string; 3 | label: string; 4 | active: boolean; 5 | theme?: "light" | "dark"; 6 | onPress: () => void; 7 | } 8 | 9 | export interface BottomNavProps { 10 | items: Array<{ 11 | icon: string; 12 | label: string; 13 | }>; 14 | theme?: "light" | "dark"; 15 | initialActiveIndex?: number; 16 | onItemPress?: (index: number) => void; 17 | } 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: true 2 | contact_links: 3 | - name: ✨ Feature Request 4 | url: https://github.com/gaureshpai/reactnativeepictrailsds/discussions/new?category=ideas 5 | about: Suggest new features in the Ideas discussion category. 6 | 7 | - name: 💬 General Discussion & Help 8 | url: https://github.com/gaureshpai/reactnativeepictrailsds/discussions 9 | about: Ask questions or start general discussions here. -------------------------------------------------------------------------------- /src/androidmodalsheets/androidmodalsheets.type.ts: -------------------------------------------------------------------------------- 1 | import { ReactNode } from 'react'; 2 | import { ContainerComponentProps } from '../types/common'; 3 | 4 | export interface AndroidModalSheetProps extends ContainerComponentProps { 5 | title: string; 6 | label: string; 7 | action?: 1 | 2 | 3; 8 | compact?: boolean; 9 | onClose?: () => void; 10 | onButtonPress?: () => void; 11 | onClipboard?: () => void; 12 | onForward?: () => void; 13 | children?: ReactNode; 14 | } 15 | -------------------------------------------------------------------------------- /src/select/select.type.ts: -------------------------------------------------------------------------------- 1 | export type SelectValue = { 2 | value: string; 3 | label: string; 4 | flagCode?: string; 5 | }; 6 | 7 | type MessageType = 'none' | 'help' | 'error'; 8 | 9 | export interface SelectProps { 10 | label: string; 11 | values: SelectValue[]; 12 | placeholder?: string; 13 | prefix?: boolean; 14 | messageType?: MessageType; 15 | message?: string; 16 | onChange?: (value: SelectValue) => void; 17 | disabled?: boolean; 18 | containerStyle?: any; 19 | } -------------------------------------------------------------------------------- /src/socialmediastack/socialmediastack.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, StyleSheet } from 'react-native'; 3 | import { SocialMediaStackProps } from './socialmediastack.type'; 4 | 5 | const SocialMediaStack: React.FC = ({ children }) => { 6 | return ( 7 | 8 | {children} 9 | 10 | ); 11 | }; 12 | 13 | const styles = StyleSheet.create({ 14 | container: { 15 | flex: 1, 16 | width: '100%', 17 | height: '100%', 18 | position: 'relative', 19 | }, 20 | }); 21 | 22 | export default SocialMediaStack; -------------------------------------------------------------------------------- /src/Input/Input.type.ts: -------------------------------------------------------------------------------- 1 | import { TextInputProps } from "react-native"; 2 | 3 | export type NInputProp = TextInputProps & { 4 | Size?: "small" | "medium" | "large" | "full" | "fit"; 5 | Label?: string; 6 | Hint?: string; 7 | State?: "Default" | "Active" | "Correct" | "ViewOnly" | "Loading" | "Disabled" | "Incorrect"; 8 | curved?: boolean 9 | }; 10 | 11 | export type AInputProp = TextInputProps & { 12 | Size?: "small" | "medium" | "large" | "full" | "fit"; 13 | Label?: string; 14 | Hint?: string; 15 | State?: "Default" | "Error" | "Success" | "Loading"; 16 | input?: string[]; 17 | curved?: boolean 18 | }; -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent coding styles 2 | # across different editors and IDEs: editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | 14 | [*.{js,jsx,ts,tsx}] 15 | indent_style = space 16 | indent_size = 2 17 | 18 | [*.json] 19 | indent_style = space 20 | indent_size = 2 21 | quote_type = double 22 | 23 | [*.md] 24 | trim_trailing_whitespace = false 25 | 26 | [*.{yaml,yml}] 27 | indent_style = space 28 | indent_size = 2 29 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files 2 | 3 | # dependencies 4 | node_modules/ 5 | example/node_modules/ 6 | *.tgz 7 | .npmrc 8 | 9 | # Expo 10 | example/.expo/ 11 | example 12 | dist/ 13 | web-build/ 14 | expo-env.d.ts 15 | 16 | # Native 17 | *.orig.* 18 | *.jks 19 | *.p8 20 | *.p12 21 | *.key 22 | *.mobileprovision 23 | 24 | # Metro 25 | .metro-health-check* 26 | 27 | # debug 28 | npm-debug.* 29 | yarn-debug.* 30 | yarn-error.* 31 | 32 | # macOS 33 | .DS_Store 34 | *.pem 35 | 36 | # local env files 37 | .env*.local 38 | 39 | # TypeScript 40 | *.tsbuildinfo 41 | -------------------------------------------------------------------------------- /src/bottomsheet/bottomsheet.type.ts: -------------------------------------------------------------------------------- 1 | import { ReactNode } from "react"; 2 | 3 | export interface Comment { 4 | id?: string | number; 5 | userInitials?: string; 6 | userName?: string; 7 | likes?: number; 8 | time?: string; 9 | text?: string; 10 | } 11 | 12 | export interface BottomSheetProps { 13 | showKnob?: boolean; 14 | showButton?: boolean; 15 | buttonLabel?: string; 16 | onButtonPress?: () => void; 17 | showComments?: boolean; 18 | comments?: Comment[]; 19 | onAddComment?: (text: string) => void; 20 | onLikeComment?: (index: number) => void; 21 | onReplyComment?: (index: number) => void; 22 | children?: ReactNode; 23 | containerStyle?: object; 24 | } -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 🚀 Pull Request 3 | about: Submit a code change or improvement. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | ## 📌 Description 10 | 11 | 12 | 13 | Fixes: # 14 | 15 | ## 🔧 Changes 16 | 17 | 18 | - 19 | - 20 | - 21 | 22 | ## ✅ Checklist 23 | 24 | - [ ] Code follows project style 25 | - [ ] Tested and working 26 | - [ ] Docs updated (if needed) 27 | 28 | ## 🧪 Testing Steps 29 | 30 | 31 | 1. 32 | 2. 33 | 34 | ## 📝 Notes 35 | 36 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "expo/tsconfig.base", 3 | "compilerOptions": { 4 | "jsx": "react-native", 5 | "esModuleInterop": true, 6 | "allowSyntheticDefaultImports": true, 7 | "moduleResolution": "node", 8 | "resolveJsonModule": true, 9 | "strict": false, 10 | "skipLibCheck": true, 11 | "noEmitOnError": false, 12 | "ignoreDeprecations": "6.0", 13 | "target": "es2019", 14 | "lib": ["es2019", "dom"], 15 | "paths": { 16 | "@/*": [ 17 | "./*" 18 | ] 19 | } 20 | }, 21 | "include": [ 22 | "nativewind-env.d.ts", 23 | "./src/**/*" 24 | ], 25 | "exclude": [ 26 | "node_modules", 27 | "dist", 28 | "example" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /src/Button/Button.type.ts: -------------------------------------------------------------------------------- 1 | import { PressableProps } from "react-native"; 2 | import { PressableComponentProps, ComponentSize, ComponentState } from '../types/common'; 3 | 4 | export type ButtonProps = PressableProps & PressableComponentProps & { 5 | label: string; 6 | variant?: "primary" | "secondary"; 7 | size?: ComponentSize; 8 | icon?: "right" | "left"; 9 | state?: ComponentState; 10 | background?: string | null; 11 | }; 12 | 13 | export type TypeDocsProps = PressableProps & PressableComponentProps & { 14 | icon?: "left" | "right"; 15 | buttonLabel?: string; 16 | label?: string; 17 | size?: ComponentSize; 18 | state?: ComponentState; 19 | background?: string | null; 20 | onClick?: () => void; 21 | }; 22 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import "./styles/global.css"; 2 | 3 | export * from './alert'; 4 | export * from './androidmodalsheets'; 5 | export * from './bottomnav'; 6 | export * from './bottomsheet'; 7 | export * from './Button'; 8 | export * from './card'; 9 | export * from './collapse'; 10 | export * from './dialog'; 11 | export * from './emptystates'; 12 | export * from './grid'; 13 | export * from './iconography'; 14 | export * from './Input'; 15 | export * from './iosmodalsheets'; 16 | export * from './loading'; 17 | export * from './navigationbar'; 18 | export * from './Navtabs'; 19 | export * from './segmentedswitchios'; 20 | export * from './select'; 21 | export * from './skeleton'; 22 | export * from './socialbuttons'; 23 | export * from './socialmediastack'; 24 | export * from './statusbutton'; 25 | export * from './tabs'; 26 | export * from './Tile'; -------------------------------------------------------------------------------- /src/grid/Grid.type.ts: -------------------------------------------------------------------------------- 1 | import { ReactNode } from "react"; 2 | import { ContainerComponentProps } from '../types/common'; 3 | 4 | export type Breakpoint = "xs" | "sm" | "md" | "lg" | "xl"; 5 | export type ResponsiveValue = T | Partial>; 6 | 7 | export interface GridProps extends ContainerComponentProps { 8 | children: ReactNode; 9 | container?: boolean; 10 | spacing?: ResponsiveValue; 11 | rowSpacing?: ResponsiveValue; 12 | columnSpacing?: ResponsiveValue; 13 | columns?: ResponsiveValue; 14 | rows?: ResponsiveValue; 15 | direction?: ResponsiveValue<"row" | "column">; 16 | size?: ResponsiveValue; 17 | } 18 | 19 | export interface ItemProps extends ContainerComponentProps { 20 | children: ReactNode; 21 | xs?: number; 22 | sm?: number; 23 | md?: number; 24 | lg?: number; 25 | xl?: number; 26 | size?: number; 27 | } 28 | -------------------------------------------------------------------------------- /src/socialmediastack/socialmediastack.type.ts: -------------------------------------------------------------------------------- 1 | // Improved type for image content to handle both remote and local images 2 | export type ImageContent = { 3 | type: 'image'; 4 | imageUri: string; 5 | isLocal?: boolean; 6 | }; 7 | 8 | export type VideoContent = { 9 | type: 'video'; 10 | uri: string; 11 | }; 12 | 13 | export type TextContent = { 14 | type: 'text'; 15 | text: string; 16 | backgroundColor?: string; 17 | }; 18 | 19 | export type ContentItem = VideoContent | ImageContent | TextContent; 20 | 21 | export interface SocialMediaContainerProps { 22 | contentItems: ContentItem[]; 23 | duration?: number; 24 | onActiveIndexChange?: (index: number) => void; 25 | index?: number; 26 | } 27 | 28 | 29 | export interface SocialMediaStackProps { 30 | children: React.ReactNode; 31 | } 32 | export interface StoryProgressBarsProps { 33 | totalStories: number; 34 | activeStoryIndex: number; 35 | } 36 | -------------------------------------------------------------------------------- /src/utils/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __importDefault = (this && this.__importDefault) || function (mod) { 3 | return (mod && mod.__esModule) ? mod : { "default": mod }; 4 | }; 5 | Object.defineProperty(exports, "__esModule", { value: true }); 6 | exports.isNativeWindAvailable = exports.mergeStyles = exports.useStyle = exports.createStyle = void 0; 7 | // Main compatibility utilities 8 | var styleCompat_1 = require("./styleCompat"); 9 | Object.defineProperty(exports, "createStyle", { enumerable: true, get: function () { return __importDefault(styleCompat_1).default; } }); 10 | Object.defineProperty(exports, "useStyle", { enumerable: true, get: function () { return styleCompat_1.useStyle; } }); 11 | Object.defineProperty(exports, "mergeStyles", { enumerable: true, get: function () { return styleCompat_1.mergeStyles; } }); 12 | Object.defineProperty(exports, "isNativeWindAvailable", { enumerable: true, get: function () { return styleCompat_1.isNativeWindAvailable; } }); 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 paigauresh 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 | SOFTWARE. 21 | -------------------------------------------------------------------------------- /src/alert/alert.type.ts: -------------------------------------------------------------------------------- 1 | const alertStyles = { 2 | information: { 3 | backgroundColor: "#E8E8E8", 4 | color: "#1F1F1F", 5 | secondaryColor: "#DDDDDD", 6 | secondaryTextColor: "#1F1F1F", 7 | icon: "information-circle", 8 | }, 9 | success: { 10 | backgroundColor: "#D3EFDA", 11 | color: "#166C3B", 12 | secondaryColor: "#B1EAC2", 13 | secondaryTextColor: "#166C3B", 14 | icon: "checkmark-circle", 15 | }, 16 | warning: { 17 | backgroundColor: "#FEE2D4", 18 | color: "#C54600", 19 | secondaryColor: "#FFD3BC", 20 | secondaryTextColor: "#C54600", 21 | icon: "warning", 22 | }, 23 | error: { 24 | backgroundColor: "#FFE1DE", 25 | color: "#950F22", 26 | secondaryColor: "#FFD2CD", 27 | secondaryTextColor: "#950F22", 28 | icon: "alert-circle", 29 | }, 30 | }; 31 | 32 | type AlertType = "information" | "success" | "warning" | "error"; 33 | 34 | interface AlertProps { 35 | message: string; 36 | label?: string; 37 | description?: string; 38 | icon?: boolean; 39 | inline?: boolean; 40 | suppressed?: boolean; 41 | type?: AlertType; 42 | onPrimaryPress?: () => void; 43 | onSecondaryPress?: () => void; 44 | } 45 | 46 | export { alertStyles, AlertProps }; -------------------------------------------------------------------------------- /src/socialmediastack/storyprogressbar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, StyleSheet } from 'react-native'; 3 | import { StoryProgressBarsProps } from './socialmediastack.type'; 4 | 5 | const StoryProgressBar: React.FC = ({ totalStories, activeStoryIndex }) => { 6 | return ( 7 | 8 | {Array.from({ length: totalStories }).map((_, index) => ( 9 | 16 | ))} 17 | 18 | ); 19 | }; 20 | 21 | const styles = StyleSheet.create({ 22 | progressBarsContainer: { 23 | position: 'absolute', 24 | top: 10, 25 | left: 0, 26 | right: 0, 27 | flexDirection: 'row', 28 | paddingHorizontal: 20, 29 | zIndex: 10, 30 | }, 31 | progressBar: { 32 | flex: 1, 33 | height: 5, 34 | marginHorizontal: 2, 35 | }, 36 | activeProgressBar: { 37 | backgroundColor: '#FFFFFF', 38 | }, 39 | inactiveProgressBar: { 40 | backgroundColor: '#ffffff75', 41 | }, 42 | }); 43 | 44 | export default StoryProgressBar; -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | name: "🚀 Feature Request" 2 | description: Suggest an idea or enhancement for this project. 3 | labels: [enhancement] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | # 🚀 Feature Request 9 | 10 | Thanks for suggesting a feature! 11 | 12 | - type: textarea 13 | id: problem-statement 14 | attributes: 15 | label: Problem 16 | description: What problem are you trying to solve? 17 | placeholder: I'm always frustrated when... 18 | validations: 19 | required: true 20 | 21 | - type: textarea 22 | id: solution 23 | attributes: 24 | label: Proposed Solution 25 | description: Describe the solution you’d like. 26 | placeholder: A possible solution would be... 27 | validations: 28 | required: true 29 | 30 | - type: textarea 31 | id: alternatives 32 | attributes: 33 | label: Alternatives Considered 34 | description: Have you considered other solutions? 35 | placeholder: Another approach could be... 36 | validations: 37 | required: false 38 | 39 | - type: textarea 40 | id: context 41 | attributes: 42 | label: Additional Context 43 | description: Add any extra context or links. -------------------------------------------------------------------------------- /src/socialbuttons/socialbuttons.type.ts: -------------------------------------------------------------------------------- 1 | interface SocialButtonProps { 2 | provider: "email" | "google" | "facebook" | "apple"; 3 | onPress: () => void; 4 | } 5 | 6 | const providerConfig = { 7 | email: { 8 | text: "Sign in with E-mail", 9 | iconName: "mail", 10 | backgroundColor: "bg-gray-200", 11 | textColor: "text-black", 12 | iconColor: "black", 13 | }, 14 | google: { 15 | text: "Sign in with Google", 16 | iconName: "logo-google", 17 | backgroundColor: "bg-gray-200", 18 | textColor: "text-black", 19 | iconColor: "#4285F4", 20 | }, 21 | facebook: { 22 | text: "Sign in with Facebook", 23 | iconName: "logo-facebook", 24 | backgroundColor: "bg-gray-200", 25 | textColor: "text-black", 26 | iconColor: "#1877F2", 27 | }, 28 | apple: { 29 | text: "Sign in with Apple", 30 | iconName: "logo-apple", 31 | backgroundColor: "bg-black", 32 | textColor: "text-white", 33 | iconColor: "white", 34 | }, 35 | }; 36 | 37 | interface SocialLoginProps { 38 | email?: boolean; 39 | google?: boolean; 40 | facebook?: boolean; 41 | apple?: boolean; 42 | onEmailSignIn?: () => void; 43 | onGoogleSignIn?: () => void; 44 | onFacebookSignIn?: () => void; 45 | onAppleSignIn?: () => void; 46 | } 47 | 48 | export { SocialButtonProps, providerConfig, SocialLoginProps }; -------------------------------------------------------------------------------- /src/iconography/iconography.type.ts: -------------------------------------------------------------------------------- 1 | export const iconMap: Record = { 2 | bell: "notifications-outline", 3 | calendar: "calendar-outline", 4 | comment: "chatbubble-outline", 5 | email: "mail-outline", 6 | grid: "grid-outline", 7 | phone: "call-outline", 8 | plus: "add-outline", 9 | "chevron-left": "chevron-back-outline", 10 | check: "checkmark-outline", 11 | envelope: "mail-outline", 12 | link: "link-outline", 13 | "chevron-right": "chevron-forward-outline", 14 | x: "close-outline", 15 | "info-circle": "information-circle-outline", 16 | at: "at-outline", 17 | ellipsis: "ellipsis-horizontal-outline", 18 | search: "search-outline", 19 | "phone-handset": "call-outline", 20 | "check-small": "checkmark-outline", 21 | }; 22 | 23 | export type IconName = keyof typeof iconMap; 24 | 25 | export type PlaceholderSize = 26 | | "xl" 27 | | "large" 28 | | "medium" 29 | | "regular" 30 | | "small" 31 | | "xs" 32 | | "xxs" 33 | | "tiny"; 34 | 35 | export type AvatarSize = "xl" | "large" | "medium" | "small" | "xs" | "xxs"; 36 | 37 | export interface IconComponentProps { 38 | type: "icon" | "placeholder" | "avatar"; 39 | className?: string; 40 | iconName?: IconName; 41 | size?: number; 42 | theme?: "light" | "dark"; 43 | placeholderSize?: PlaceholderSize; 44 | filled?: boolean; 45 | avatarSize?: AvatarSize; 46 | initials?: string; 47 | } 48 | 49 | export const sizeMapping: Record = { 50 | xl: 48, 51 | large: 40, 52 | medium: 32, 53 | regular: 24, 54 | small: 20, 55 | xs: 16, 56 | xxs: 12, 57 | tiny: 8, 58 | }; -------------------------------------------------------------------------------- /src/socialbuttons/socialbuttons.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, TouchableOpacity } from 'react-native'; 3 | import Ionicons from '@expo/vector-icons/Ionicons'; 4 | import { SocialButtonProps, providerConfig, SocialLoginProps } from './socialbuttons.type'; 5 | 6 | const SocialButton: React.FC = ({ provider, onPress }) => { 7 | const config = providerConfig[provider]; 8 | 9 | return ( 10 | 14 | 15 | 16 | {config.text} 17 | 18 | 19 | 20 | ); 21 | }; 22 | 23 | const SocialLogin: React.FC = ({ 24 | email = true, 25 | google = false, 26 | facebook = false, 27 | apple = false, 28 | onEmailSignIn = () => { }, 29 | onGoogleSignIn = () => { }, 30 | onFacebookSignIn = () => { }, 31 | onAppleSignIn = () => { }, 32 | }) => { 33 | return ( 34 | 35 | {(email && )} 36 | {(google && )} 37 | {(facebook && )} 38 | {(apple && )} 39 | 40 | ); 41 | }; 42 | 43 | export default SocialLogin; -------------------------------------------------------------------------------- /src/socialmediastack/socialmediaengagement.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, TouchableOpacity, StyleSheet } from 'react-native'; 3 | import { Ionicons } from "@expo/vector-icons"; 4 | 5 | const SocialMediaEngagement = ({ 6 | icons = [ 7 | { name: 'heart-outline', onPress: () => console.log('Like pressed') }, 8 | { name: 'chatbox-outline', onPress: () => console.log('Comment pressed') }, 9 | { name: 'paper-plane-outline', onPress: () => console.log('Share pressed') }, 10 | ], 11 | iconColor = '#ffffff', 12 | }) => { 13 | return ( 14 | 15 | 16 | {icons.map((icon, index) => ( 17 | 22 | 23 | 24 | ))} 25 | 26 | 27 | ); 28 | }; 29 | 30 | const styles = StyleSheet.create({ 31 | container: { 32 | position: 'absolute', 33 | right: 15, 34 | bottom: 120, 35 | borderRadius: 8, 36 | padding: 8, 37 | width: 60, 38 | alignItems: 'center', 39 | zIndex: 999, 40 | }, 41 | title: { 42 | fontSize: 12, 43 | fontWeight: 'bold', 44 | textAlign: 'center', 45 | marginBottom: 10, 46 | width: '100%', 47 | }, 48 | iconsContainer: { 49 | width: '100%', 50 | }, 51 | iconButton: { 52 | width: '100%', 53 | backgroundColor: '#ffffff75', 54 | marginBottom: 18, 55 | alignItems: 'center', 56 | paddingVertical: 12, 57 | marginVertical: 2, 58 | } 59 | }); 60 | 61 | export default SocialMediaEngagement; -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # 🔒 Security Policy 2 | 3 | ## 🛠 Supported Versions 4 | 5 | We currently **maintain active support only for the latest stable release** of the design system. Versions prior to `1.0.0` have been **deprecated** and will not receive updates, including security patches. 6 | 7 | | Version | Status | 8 | | ---------- | ------------------------- | 9 | | `>= 1.0.0` | ✅ Supported (Active) | 10 | | `< 1.0.0` | ❌ Deprecated (No Support) | 11 | 12 | > The `1.x` release line marks the foundation for long-term support, stability, and forward compatibility. All critical fixes, patches, and features will be based on `v1.0.0` and above. 13 | 14 | ## 🛡 Reporting a Vulnerability 15 | 16 | If you discover a security vulnerability in **`reactnativeepictrailsds`**, please report it responsibly and privately so that we can address the issue promptly. 17 | 18 | ### 📩 How to Report 19 | 20 | Please send a detailed email to: 21 | 22 | 📧 **[paigauresh@gmail.com](mailto:paigauresh@gmail.com)** 23 | Subject: **Security Issue — reactnativeepictrailsds** 24 | 25 | Include the following information: 26 | 27 | * Clear steps to reproduce the issue 28 | * Affected package versions 29 | * Impact assessment (data leak, crash, etc.) 30 | * Optional: Any suggestions for remediation 31 | 32 | ### 🔄 What to Expect 33 | 34 | * **Acknowledgment**: You will receive a response within **2 business days** 35 | * **Assessment & Patch**: We aim to investigate and patch issues swiftly 36 | * **Disclosure**: If necessary, we will publish a public advisory in a responsible and transparent manner (with credit to reporters if desired) 37 | 38 | ## ⚠️ Responsible Disclosure Guidelines 39 | 40 | We **strongly encourage responsible disclosure**: 41 | 42 | * Please **do not** publicly disclose or discuss the vulnerability until a patch is released. 43 | * Avoid posting issues directly on GitHub if they contain sensitive security details. -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2019", 4 | "module": "commonjs", 5 | "lib": ["es2019"], 6 | "moduleResolution": "node", 7 | "esModuleInterop": true, 8 | "allowSyntheticDefaultImports": true, 9 | "resolveJsonModule": true, 10 | "strict": false, 11 | "skipLibCheck": true, 12 | "noEmitOnError": false, 13 | "declaration": true, 14 | "declarationMap": false, 15 | "jsx": "react-native", 16 | "outDir": "dist/commonjs" 17 | }, 18 | "include": [ 19 | "src/utils/styleCompat.ts", 20 | "src/utils/index.ts", 21 | "src/types/common.ts", 22 | "src/alert/alert.tsx", 23 | "src/alert/alert.type.ts", 24 | "src/androidmodalsheets/androidmodalsheets.tsx", 25 | "src/androidmodalsheets/androidmodalsheets.type.ts", 26 | "src/bottomnav/bottomnav.tsx", 27 | "src/bottomnav/bottomnav.type.ts", 28 | "src/Button/Button.tsx", 29 | "src/Button/Button.type.ts", 30 | "src/Button/icon.tsx", 31 | "src/Button/rect.tsx", 32 | "src/Button/typeDoc.tsx", 33 | "src/card/card.tsx", 34 | "src/card/card.type.ts", 35 | "src/card/section.tsx", 36 | "src/collapse/collapse.tsx", 37 | "src/collapse/collapse.type.ts", 38 | "src/dialog/dialog.tsx", 39 | "src/dialog/dialog.type.ts", 40 | "src/emptystates/emptystates.tsx", 41 | "src/emptystates/emptystates.type.ts", 42 | "src/grid/grid.tsx", 43 | "src/grid/Grid.type.ts", 44 | "src/Input/Input.tsx", 45 | "src/Input/Input.type.ts", 46 | "src/loading/loading.tsx", 47 | "src/loading/loading.type.ts", 48 | "src/Navtabs/Navtabs.tsx", 49 | "src/Navtabs/Navtabs.type.ts", 50 | "src/select/select.tsx", 51 | "src/select/select.type.ts", 52 | "src/skeleton/skeleton.tsx", 53 | "src/skeleton/skeleton.type.ts", 54 | "src/tabs/tabs.tsx", 55 | "src/tabs/tabs.type.ts", 56 | "src/sociallogin.tsx", 57 | "src/Tile/tile.tsx", 58 | "src/Tile/Tile.type.ts", 59 | "src/index.ts" 60 | ], 61 | "exclude": [ 62 | "node_modules", 63 | "dist" 64 | ] 65 | } 66 | -------------------------------------------------------------------------------- /src/loading/loading.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, ActivityIndicator } from 'react-native'; 3 | import { createStyle } from '../utils/styleCompat'; 4 | import { ContainerComponentProps } from '../types/common'; 5 | 6 | export interface LoadingProps extends ContainerComponentProps { 7 | description?: string; 8 | } 9 | 10 | const Loading: React.FC = ({ 11 | description = "Please wait, content of the page is loading...", 12 | className, 13 | style, 14 | ...props 15 | }) => { 16 | const containerStyle = createStyle({ 17 | className: `${className || ''} flex-1 items-center justify-center w-full h-full bg-white`, 18 | style: [ 19 | { 20 | flex: 1, 21 | alignItems: 'center', 22 | justifyContent: 'center', 23 | width: '100%', 24 | height: '100%', 25 | backgroundColor: 'white' 26 | }, 27 | style 28 | ].filter(Boolean) 29 | }); 30 | 31 | const indicatorContainerStyle = createStyle({ 32 | className: "w-20 h-20", 33 | style: { 34 | width: 80, 35 | height: 80 36 | } 37 | }); 38 | 39 | const indicatorWrapperStyle = createStyle({ 40 | className: "w-full h-full items-center justify-center", 41 | style: { 42 | width: '100%', 43 | height: '100%', 44 | alignItems: 'center', 45 | justifyContent: 'center' 46 | } 47 | }); 48 | 49 | const textStyle = createStyle({ 50 | className: "text-gray-500 text-center px-4", 51 | style: { 52 | color: '#6b7280', 53 | textAlign: 'center', 54 | paddingHorizontal: 16 55 | } 56 | }); 57 | 58 | return ( 59 | 60 | 61 | 62 | 66 | 67 | 68 | 69 | 70 | {description} 71 | 72 | 73 | ); 74 | }; 75 | 76 | export default Loading; 77 | 78 | -------------------------------------------------------------------------------- /src/card/card.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { View, Text } from "react-native"; 3 | import { createStyle } from '../utils/styleCompat'; 4 | import { ContainerComponentProps } from '../types/common'; 5 | 6 | export interface CardProps extends ContainerComponentProps { 7 | title?: string; 8 | subtitle?: string; 9 | cardTitle?: boolean; 10 | content?: React.ReactNode; 11 | backgroundColor?: string; 12 | } 13 | 14 | const Card: React.FC = ({ 15 | title, 16 | subtitle, 17 | cardTitle = true, 18 | children, 19 | content, 20 | backgroundColor = 'white', 21 | className, 22 | style, 23 | ...props 24 | }) => { 25 | const containerStyle = createStyle({ 26 | className: "px-4 bg-white overflow-hidden border border-gray-200 shadow-sm mb-4 w-[80vw]", 27 | style: [{ backgroundColor }, style].filter(Boolean) 28 | }); 29 | 30 | const headerStyle = createStyle({ 31 | className: `flex ${cardTitle ? "flex-row" : "flex-row-reverse"} justify-between px-0 py-2` 32 | }); 33 | 34 | const titleContainerStyle = createStyle({ 35 | className: "px-0 py-2" 36 | }); 37 | 38 | const titleTextStyle = createStyle({ 39 | className: "font-medium text-gray-800" 40 | }); 41 | 42 | const contentContainerStyle = createStyle({ 43 | className: "relative mb-4 p-4 bg-green-50 min-h-32 flex-grow" 44 | }); 45 | 46 | return ( 47 | 48 | 49 | {title && ( 50 | 51 | {title} 52 | 53 | )} 54 | 55 | {subtitle && ( 56 | 57 | 58 | {subtitle} 59 | 60 | 61 | )} 62 | 63 | 64 | 65 | {children} 66 | {content} 67 | 68 | 69 | ); 70 | }; 71 | 72 | export default Card; 73 | -------------------------------------------------------------------------------- /src/card/section.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, TouchableOpacity } from 'react-native'; 3 | import { Ionicons } from '@expo/vector-icons'; 4 | import { createStyle } from '../utils/styleCompat'; 5 | import { ContainerComponentProps } from '../types/common'; 6 | 7 | export interface CardSectionProps extends ContainerComponentProps { 8 | title?: string; 9 | icon?: boolean; 10 | onPress?: () => void; 11 | } 12 | 13 | const CardSection: React.FC = ({ 14 | title = "Section Title", 15 | icon = false, 16 | onPress = () => console.log('Section pressed'), 17 | className, 18 | style, 19 | ...props 20 | }) => { 21 | const containerStyle = createStyle({ 22 | className: `${className || ''} w-full bg-white`, 23 | style 24 | }); 25 | 26 | const touchableStyle = createStyle({ 27 | className: "flex flex-row items-center justify-between py-3 px-2 border-b border-gray-200" 28 | }); 29 | 30 | const leftContentStyle = createStyle({ 31 | className: "flex flex-row items-center" 32 | }); 33 | 34 | const iconContainerStyle = createStyle({ 35 | className: "mr-2 flex items-center justify-center" 36 | }); 37 | 38 | const titleTextStyle = createStyle({ 39 | className: "text-base font-medium text-gray-800", 40 | style: { 41 | fontSize: 16, 42 | fontWeight: "500", 43 | color: "#1f2937" 44 | } 45 | }); 46 | 47 | const rightIconStyle = createStyle({ 48 | className: "flex items-center justify-center" 49 | }); 50 | 51 | return ( 52 | 53 | 58 | 59 | {icon && ( 60 | 61 | 62 | 63 | )} 64 | {title} 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | ); 73 | }; 74 | 75 | export default CardSection; -------------------------------------------------------------------------------- /src/socialbuttons/sociallogin.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, TouchableOpacity } from 'react-native'; 3 | import { createStyle } from '../utils/styleCompat'; 4 | import { ContainerComponentProps } from '../types/common'; 5 | 6 | export interface SocialLoginProps extends ContainerComponentProps { 7 | email?: boolean; 8 | google?: boolean; 9 | facebook?: boolean; 10 | apple?: boolean; 11 | onEmailSignIn?: () => void; 12 | onGoogleSignIn?: () => void; 13 | onFacebookSignIn?: () => void; 14 | onAppleSignIn?: () => void; 15 | } 16 | 17 | const SocialLogin: React.FC = ({ 18 | email = true, 19 | google = true, 20 | facebook = true, 21 | apple = true, 22 | onEmailSignIn, 23 | onGoogleSignIn, 24 | onFacebookSignIn, 25 | onAppleSignIn, 26 | className, 27 | style, 28 | ...props 29 | }) => { 30 | const containerStyle = createStyle({ 31 | className: `${className || ''} w-full`, 32 | style 33 | }); 34 | 35 | const buttonStyle = createStyle({ 36 | className: 'flex-row items-center justify-center p-3 m-1 rounded-lg bg-blue-500' 37 | }); 38 | 39 | const buttonTextStyle = createStyle({ 40 | className: 'text-white font-medium', 41 | style: { color: 'white', fontWeight: '500' } 42 | }); 43 | 44 | return ( 45 | 46 | {google && ( 47 | 48 | Sign in with Google 49 | 50 | )} 51 | {apple && ( 52 | 53 | Sign in with Apple 54 | 55 | )} 56 | {facebook && ( 57 | 58 | Sign in with Facebook 59 | 60 | )} 61 | {email && ( 62 | 63 | Sign in with Email 64 | 65 | )} 66 | 67 | ); 68 | }; 69 | 70 | export default SocialLogin; 71 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.yml: -------------------------------------------------------------------------------- 1 | name: "🐛 Bug Report" 2 | description: Report a reproducible bug or regression in the library. 3 | labels: [bug] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | # 🐛 Bug Report 9 | 10 | Please fill out all required sections to help us fix the issue faster. 11 | 12 | - type: checkboxes 13 | attributes: 14 | label: Checklist 15 | description: Confirm the following before submitting: 16 | options: 17 | - label: I tested the latest version. 18 | required: true 19 | - label: I’m using a supported React Native version. 20 | required: true 21 | - label: I searched existing issues. 22 | required: true 23 | 24 | - type: textarea 25 | id: summary 26 | attributes: 27 | label: Bug Summary 28 | description: A clear and concise description of the bug. 29 | validations: 30 | required: true 31 | 32 | - type: input 33 | id: version 34 | attributes: 35 | label: Package Version 36 | placeholder: e.g., 1.0.2 37 | validations: 38 | required: true 39 | 40 | - type: textarea 41 | id: environment 42 | attributes: 43 | label: Environment Info 44 | description: Paste output from `npx react-native info` 45 | render: shell 46 | value: | 47 | ```sh 48 | npx react-native info 49 | ``` 50 | validations: 51 | required: true 52 | 53 | - type: textarea 54 | id: steps 55 | attributes: 56 | label: Steps to Reproduce 57 | description: Provide steps to reproduce the issue. 58 | placeholder: | 59 | 1. Install the package 60 | 2. Import a component 61 | 3. Run the app 62 | 4. Observe the issue 63 | validations: 64 | required: true 65 | 66 | - type: textarea 67 | id: expected 68 | attributes: 69 | label: Expected Behavior 70 | description: What should happen instead? 71 | validations: 72 | required: true 73 | 74 | - type: input 75 | id: repro 76 | attributes: 77 | label: Reproducible Example 78 | placeholder: e.g., https://github.com/user/repro-app 79 | validations: 80 | required: true 81 | 82 | - type: textarea 83 | id: context 84 | attributes: 85 | label: Additional Context 86 | description: Logs, device info, screenshots, or anything relevant. 87 | -------------------------------------------------------------------------------- /src/Input/NormalInput.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useRef, useEffect } from "react"; 2 | import { TextInput, View, ActivityIndicator } from "react-native"; 3 | import { Ionicons } from "@expo/vector-icons"; 4 | import { NInputProp } from "./Input.type"; 5 | const Sizes = { 6 | small: "w-[375px] h-[36px]", 7 | medium: "w-[375px] h-[48px]", 8 | large: "w-[375px] h-[56px]", 9 | full: "w-full h-full", 10 | fit : "w-fit h-full", 11 | }; 12 | 13 | export default function NormalText({ 14 | Size = "small", 15 | Label = "", 16 | Hint = "", 17 | State = "Default", 18 | value = "", 19 | curved = false, 20 | ...props 21 | }: NInputProp) { 22 | const inputRef = useRef(null); 23 | 24 | 25 | useEffect(() => { 26 | if (State === "Active" && inputRef.current) { 27 | inputRef.current.focus(); 28 | } 29 | }, [State]); 30 | 31 | 32 | const getOutlineClass = () => { 33 | if (["Loading", "Disabled", "ViewOnly"].includes(State)) { 34 | return "outline-none"; 35 | } 36 | }; 37 | 38 | 39 | const getIcon = () => { 40 | switch (State) { 41 | case "Correct": 42 | return ; 43 | case "Incorrect": 44 | return ; 45 | case "Loading": 46 | return ; 47 | default: 48 | return null; 49 | } 50 | }; 51 | 52 | return ( 53 | 54 | {Label ? ( 55 | 56 | {Label} 57 | 58 | ) : null} 59 | 60 | 66 | 67 | {["Correct", "Incorrect", "Loading"].includes(State) && ( 68 | 69 | {getIcon()} 70 | 71 | )} 72 | 73 | {Hint ? ( 74 | 75 | {Hint} 76 | 77 | ) : null} 78 | 79 | ); 80 | } 81 | -------------------------------------------------------------------------------- /src/iosmodalsheets/iosmodalsheets.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, TouchableOpacity, SafeAreaView } from 'react-native'; 3 | import { Ionicons } from '@expo/vector-icons'; 4 | import { RectButton } from "../Button"; 5 | import { IOSModalSheetProps } from './iosmodalsheets.type'; 6 | 7 | const IOSModalSheet: React.FC = ({ 8 | title, 9 | label, 10 | action = 1, 11 | compact = false, 12 | onClose, 13 | onButtonPress, 14 | onClipboard, 15 | onForward, 16 | children, 17 | }) => { 18 | 19 | return ( 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | {title} 29 | 30 | 31 | {action >= 3 && ( 32 | 33 | 34 | 35 | )} 36 | {action >= 2 && ( 37 | 38 | 39 | 40 | )} 41 | {action === 1 && } 42 | 43 | 44 | 45 | 46 | {!compact && ( 47 | {title} 48 | )} 49 | 50 | {children} 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | ); 65 | }; 66 | 67 | export default IOSModalSheet; -------------------------------------------------------------------------------- /src/navigationbar/navigationbar.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, TouchableOpacity, Platform } from 'react-native'; 3 | import { Ionicons } from '@expo/vector-icons'; 4 | import { NavigationBarProps } from './navigationbar.type'; 5 | 6 | const NavigationBar: React.FC = ({ 7 | title, 8 | device = Platform.OS as 'ios' | 'android', 9 | action = 1, 10 | size = 'compact', 11 | onClose, 12 | onClipboard, 13 | onForward, 14 | }) => { 15 | const isIOS = device === 'ios'; 16 | 17 | const renderActions = () => { 18 | if (action === 1) { 19 | return null; 20 | } else if (action === 2) { 21 | return ( 22 | 23 | 24 | 25 | ); 26 | } else if (action === 3) { 27 | return ( 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | ); 37 | } 38 | return null; 39 | }; 40 | 41 | return ( 42 | 43 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | {title} 53 | 54 | 55 | 56 | {renderActions()} 57 | 58 | 59 | 60 | 61 | {size === 'expandable' && ( 62 | 63 | 64 | {title} 65 | 66 | 67 | )} 68 | 69 | ); 70 | }; 71 | 72 | export default NavigationBar; -------------------------------------------------------------------------------- /src/sociallogin.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, TouchableOpacity } from 'react-native'; 3 | import { createStyle } from './utils/styleCompat'; 4 | import { ContainerComponentProps } from './types/common'; 5 | 6 | export interface SocialLoginProps extends ContainerComponentProps { 7 | email?: boolean; 8 | google?: boolean; 9 | facebook?: boolean; 10 | apple?: boolean; 11 | onEmailSignIn?: () => void; 12 | onGoogleSignIn?: () => void; 13 | onFacebookSignIn?: () => void; 14 | onAppleSignIn?: () => void; 15 | } 16 | 17 | const SocialLogin: React.FC = ({ 18 | email = true, 19 | google = true, 20 | facebook = true, 21 | apple = true, 22 | onEmailSignIn, 23 | onGoogleSignIn, 24 | onFacebookSignIn, 25 | onAppleSignIn, 26 | className, 27 | style, 28 | ...props 29 | }) => { 30 | const containerStyle = createStyle({ 31 | className: `${className || ''} w-full`, 32 | style 33 | }); 34 | 35 | const buttonStyle = createStyle({ 36 | className: 'flex-row items-center justify-center p-3 m-1 rounded-lg', 37 | style: { 38 | backgroundColor: '#3b82f6', 39 | padding: 12, 40 | margin: 4, 41 | borderRadius: 8, 42 | flexDirection: 'row', 43 | alignItems: 'center', 44 | justifyContent: 'center' 45 | } 46 | }); 47 | 48 | const buttonTextStyle = createStyle({ 49 | className: 'text-white font-medium', 50 | style: { 51 | color: 'white', 52 | fontWeight: '500', 53 | fontSize: 16 54 | } 55 | }); 56 | 57 | return ( 58 | 59 | {google && ( 60 | 61 | Sign in with Google 62 | 63 | )} 64 | {apple && ( 65 | 66 | Sign in with Apple 67 | 68 | )} 69 | {facebook && ( 70 | 71 | Sign in with Facebook 72 | 73 | )} 74 | {email && ( 75 | 76 | Sign in with Email 77 | 78 | )} 79 | 80 | ); 81 | }; 82 | 83 | export default SocialLogin; 84 | -------------------------------------------------------------------------------- /src/Navtabs/Navtabs.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { View, Text, TouchableOpacity } from 'react-native'; 3 | import { NavTabProps } from './Navtabs.type'; 4 | import { createStyle } from '../utils/styleCompat'; 5 | 6 | const NavTabs: React.FC = ({ 7 | tabs, 8 | initialActiveIndex = 0, 9 | onTabChange, 10 | className, 11 | style, 12 | ...props 13 | }) => { 14 | const [activeIndex, setActiveIndex] = useState(initialActiveIndex); 15 | 16 | const handleTabPress = (index: number) => { 17 | setActiveIndex(index); 18 | if (onTabChange) { 19 | onTabChange(index); 20 | } 21 | }; 22 | 23 | const containerStyle = createStyle({ 24 | className: `${className || ''} flex-row absolute top-0 w-full bg-gray-100 rounded-lg p-1`, 25 | style: [ 26 | { 27 | flexDirection: 'row', 28 | position: 'absolute', 29 | top: 0, 30 | width: '100%', 31 | backgroundColor: '#f3f4f6', 32 | borderRadius: 8, 33 | padding: 4 34 | }, 35 | style 36 | ].filter(Boolean) 37 | }); 38 | 39 | return ( 40 | 41 | {tabs.map((tab, index) => { 42 | const isActive = activeIndex === index; 43 | 44 | const tabStyle = createStyle({ 45 | className: `flex-1 py-2 px-4 items-center justify-center ${isActive ? 'bg-white rounded-md shadow' : 'bg-transparent'}`, 46 | style: { 47 | flex: 1, 48 | paddingVertical: 8, 49 | paddingHorizontal: 16, 50 | alignItems: 'center', 51 | justifyContent: 'center', 52 | backgroundColor: isActive ? '#ffffff' : 'transparent', 53 | borderRadius: isActive ? 6 : 0, 54 | shadowColor: isActive ? '#000' : 'transparent', 55 | shadowOffset: isActive ? { width: 0, height: 1 } : { width: 0, height: 0 }, 56 | shadowOpacity: isActive ? 0.1 : 0, 57 | shadowRadius: isActive ? 3 : 0, 58 | elevation: isActive ? 2 : 0 59 | } 60 | }); 61 | 62 | const textStyle = createStyle({ 63 | className: `text-sm font-medium ${isActive ? 'text-black' : 'text-gray-500'}`, 64 | style: { 65 | fontSize: 14, 66 | fontWeight: '500', 67 | color: isActive ? '#000000' : '#6b7280' 68 | } 69 | }); 70 | 71 | return ( 72 | handleTabPress(index)} 76 | > 77 | 78 | {tab} 79 | 80 | 81 | ); 82 | })} 83 | 84 | ); 85 | }; 86 | 87 | export default NavTabs; -------------------------------------------------------------------------------- /src/Button/rect.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import { Pressable, Text } from "react-native"; 3 | import { ActivityIndicator } from "react-native"; 4 | import { ButtonProps } from "./Button.type"; 5 | import { createStyle, mergeStyles } from '../utils/styleCompat'; 6 | 7 | const RectButton = ({ 8 | label = "Button", 9 | state = "default", 10 | size = "medium", 11 | disabled, 12 | background, 13 | variant = "primary", 14 | 15 | ...props 16 | }: ButtonProps) => { 17 | const buttonVariant = variant; 18 | 19 | const sizes = { 20 | small: "min-w-[80px] h-fit p-[10px]", 21 | medium: "min-w-[120px] h-fit p-[10px]", 22 | large: "min-w-[160px] h-fit p-[15px]", 23 | }; 24 | 25 | const primaryStates = { 26 | default: "bg-buttons-primary-default", 27 | pressed: "bg-buttons-primary-pressed", 28 | hover: "bg-buttons-primary-hover", 29 | disabled: "bg-buttons-primary-disabled", 30 | loading: "bg-buttons-primary-default", 31 | }; 32 | 33 | const secondaryStates = { 34 | default: 'btn-secondary-default', 35 | pressed: 'btn-secondary-pressed', 36 | hover: 'btn-secondary-hover', 37 | disabled: 'btn-secondary-disabled', 38 | loading: 'btn-secondary-loading', 39 | }; 40 | 41 | const states = buttonVariant === "primary" ? primaryStates : secondaryStates; 42 | 43 | background = disabled ? null : background; 44 | 45 | const [isHovered, setIsHovered] = useState(false); 46 | 47 | const isHoverEffectEnabled = !disabled && state !== "disabled" && state !== "loading"; 48 | 49 | // Create the style object combining className and style props 50 | const baseStyle = { 51 | backgroundColor: background ? background : undefined 52 | }; 53 | 54 | const containerStyle = createStyle({ 55 | className: `${sizes[size]} ${background 56 | ? '' 57 | : disabled 58 | ? states.disabled 59 | : isHovered && isHoverEffectEnabled 60 | ? states.hover 61 | : states[state] 62 | } flex items-center justify-center`, 63 | style: [baseStyle, props.style].filter(Boolean) 64 | }); 65 | 66 | return ( 67 | isHoverEffectEnabled && setIsHovered(true)} 70 | onHoverOut={() => isHoverEffectEnabled && setIsHovered(false)} 71 | style={containerStyle} 72 | {...props} 73 | > 74 | {state === "loading" ? ( 75 | 76 | ) : ( 77 | 80 | {label} 81 | 82 | )} 83 | 84 | ); 85 | }; 86 | 87 | export default RectButton; -------------------------------------------------------------------------------- /src/Input/Input.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text, TextInput, TextInputProps } from 'react-native'; 3 | import { createStyle } from '../utils/styleCompat'; 4 | import { BaseComponentProps, ComponentSize, ComponentState } from '../types/common'; 5 | 6 | export interface InputProps extends BaseComponentProps, Omit { 7 | label?: string; 8 | hint?: string; 9 | size?: ComponentSize; 10 | state?: 'default' | 'success' | 'error'; 11 | curved?: boolean; 12 | required?: boolean; 13 | } 14 | 15 | const Input: React.FC = ({ 16 | label, 17 | hint, 18 | size = 'medium', 19 | state = 'default', 20 | curved = false, 21 | required = false, 22 | className, 23 | style, 24 | disabled, 25 | ...textInputProps 26 | }) => { 27 | const sizes = { 28 | small: 'text-sm p-2', 29 | medium: 'text-base p-3', 30 | large: 'text-lg p-4' 31 | }; 32 | 33 | const getBorderColor = () => { 34 | switch (state) { 35 | case 'success': 36 | return 'border-green-500'; 37 | case 'error': 38 | return 'border-red-500'; 39 | default: 40 | return 'border-gray-300'; 41 | } 42 | }; 43 | 44 | const getHintColor = () => { 45 | switch (state) { 46 | case 'success': 47 | return 'text-green-600'; 48 | case 'error': 49 | return 'text-red-600'; 50 | default: 51 | return 'text-gray-600'; 52 | } 53 | }; 54 | 55 | const containerStyle = createStyle({ 56 | className: 'flex flex-col gap-2', 57 | style 58 | }); 59 | 60 | const labelStyle = createStyle({ 61 | className: 'text-sm font-medium text-gray-700' 62 | }); 63 | 64 | const inputStyle = createStyle({ 65 | className: `${sizes[size]} bg-white border-2 ${getBorderColor()} ${curved ? 'rounded-md' : ''} ${disabled ? 'bg-gray-100 text-gray-500' : 'text-gray-900'}`, 66 | style: { 67 | outlineWidth: 0, // Remove web outline 68 | } 69 | }); 70 | 71 | const hintStyle = createStyle({ 72 | className: `text-xs mt-1 ${getHintColor()}` 73 | }); 74 | 75 | return ( 76 | 77 | {label && ( 78 | 79 | 80 | {label} 81 | {required && *} 82 | 83 | 84 | )} 85 | 86 | 92 | 93 | {hint && ( 94 | 95 | {hint} 96 | 97 | )} 98 | 99 | ); 100 | }; 101 | 102 | export default Input; 103 | 104 | -------------------------------------------------------------------------------- /src/statusbutton/statusbutton.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { TouchableOpacity, Text, View } from 'react-native'; 3 | import { Ionicons } from '@expo/vector-icons'; 4 | import { StatusButtonProps } from './statusbutton.type'; 5 | 6 | const StatusButton: React.FC = ({ 7 | label = 'Label', 8 | type = 'information', 9 | buttonType = 'primary', 10 | iconLeft = false, 11 | iconRight = false, 12 | iconOnly = false, 13 | onPress = () => {}, 14 | }) => { 15 | const colorStyles = { 16 | information: { 17 | primary: { 18 | backgroundColor: '#1F1F1F', 19 | color: '#FFFFFF', 20 | }, 21 | subtle: { 22 | backgroundColor: '#DDDDDD', 23 | color: '#1F1F1F', 24 | }, 25 | }, 26 | success: { 27 | primary: { 28 | backgroundColor: '#0E8345', 29 | color: '#FFFFFF', 30 | }, 31 | subtle: { 32 | backgroundColor: '#B1EAC2', 33 | color: '#166C3B', 34 | }, 35 | }, 36 | warning: { 37 | primary: { 38 | backgroundColor: '#C54600', 39 | color: '#FFFFFF', 40 | }, 41 | subtle: { 42 | backgroundColor: '#FFD3BC', 43 | color: '#C54600', 44 | }, 45 | }, 46 | error: { 47 | primary: { 48 | backgroundColor: '#950F22', 49 | color: '#FFFFFF', 50 | }, 51 | subtle: { 52 | backgroundColor: '#FFD2CD', 53 | color: '#950F22', 54 | }, 55 | }, 56 | }; 57 | 58 | const currentStyle = colorStyles[type][buttonType]; 59 | const textColor = currentStyle.color; 60 | const backgroundColor = currentStyle.backgroundColor; 61 | 62 | const renderContent = () => { 63 | if (iconOnly) { 64 | return ( 65 | 70 | ); 71 | } 72 | 73 | return ( 74 | 75 | {iconLeft && ( 76 | 81 | )} 82 | 83 | {label} 84 | 85 | {iconRight && ( 86 | 91 | )} 92 | 93 | ); 94 | }; 95 | 96 | return ( 97 | 103 | {renderContent()} 104 | 105 | ); 106 | }; 107 | 108 | export default StatusButton; -------------------------------------------------------------------------------- /src/segmentedswitchios/segmentedswitchios.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { View, Text, TouchableOpacity, useWindowDimensions } from 'react-native'; 3 | import { Ionicons } from '@expo/vector-icons'; 4 | import { SegmentedSwitchIOSProps } from './segmentedswitchios.type'; 5 | 6 | const SegmentedSwitchIOS: React.FC = ({ 7 | title, 8 | items, 9 | selectedIndex = null, 10 | messageType = 'none', 11 | message = '', 12 | onChange 13 | }) => { 14 | const [selected, setSelected] = useState(selectedIndex); 15 | const { width } = useWindowDimensions(); 16 | const fontSize = width < 360 ? 'text-sm' : 'text-base'; 17 | const padding = width < 360 ? 'py-2' : 'py-3'; 18 | 19 | const handleSelect = (index: number) => { 20 | setSelected(index); 21 | if (onChange) { 22 | onChange(index); 23 | } 24 | }; 25 | 26 | const getIconName = () => { 27 | if (messageType === 'error') return 'alert-circle'; 28 | return 'information-circle'; 29 | }; 30 | 31 | return ( 32 | 33 | {title} 34 | 37 | {items.map((item, index) => ( 38 | 48 | handleSelect(index)}> 50 | 51 | {item} 52 | 53 | 54 | 55 | ))} 56 | 57 | 58 | {messageType !== 'none' && message && ( 59 | 60 | 61 | {message} 64 | 65 | )} 66 | 67 | ); 68 | }; 69 | 70 | export default SegmentedSwitchIOS; -------------------------------------------------------------------------------- /src/dialog/dialog.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, Text } from 'react-native'; 3 | import RectButton from "../Button/rect"; 4 | import { DialogProps } from "./dialog.type"; 5 | import { createStyle } from '../utils/styleCompat'; 6 | 7 | const Dialog: React.FC = ({ 8 | title, 9 | description, 10 | buttonLabel, 11 | onButtonPress, 12 | children, 13 | className, 14 | style, 15 | ...props 16 | }) => { 17 | return ( 18 | 35 | 49 | 60 | {children} 61 | 62 | 63 | 67 | 76 | {title} 77 | 78 | 79 | 87 | {description} 88 | 89 | 90 | 94 | 95 | 96 | 97 | 98 | 99 | ); 100 | }; 101 | 102 | export default Dialog; -------------------------------------------------------------------------------- /src/bottomnav/bottomnav.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import { View, Text, TouchableOpacity, StyleSheet } from 'react-native'; 3 | import { Ionicons } from "@expo/vector-icons"; 4 | import { BottomNavProps, NavItemProps } from './bottomnav.type'; 5 | 6 | const NavItem = ({ icon, label, active, theme, onPress }: NavItemProps) => { 7 | return ( 8 | 9 | 14 | 18 | {label} 19 | 20 | 21 | ); 22 | }; 23 | 24 | const BottomNav = ({ 25 | items, 26 | theme = 'light', 27 | initialActiveIndex = 0, 28 | onItemPress 29 | }: BottomNavProps) => { 30 | const [activeIndex, setActiveIndex] = useState(initialActiveIndex); 31 | 32 | const handlePress = (index: number) => { 33 | setActiveIndex(index); 34 | if (onItemPress) { 35 | onItemPress(index); 36 | } 37 | }; 38 | 39 | return ( 40 | 44 | 45 | {items.map((item, index) => ( 46 | handlePress(index)} 53 | /> 54 | ))} 55 | 56 | 60 | 64 | 65 | 66 | ); 67 | }; 68 | 69 | const styles = StyleSheet.create({ 70 | container: { 71 | position: 'absolute', 72 | bottom: 0, 73 | left: 0, 74 | right: 0, 75 | width: '100%', 76 | borderTopWidth: 1, 77 | borderTopColor: '#E5E5E5', 78 | paddingVertical: 8, 79 | elevation: 8, 80 | shadowColor: '#000000', 81 | shadowOffset: { width: 0, height: -2 }, 82 | shadowOpacity: 0.1, 83 | shadowRadius: 5, 84 | }, 85 | navContainer: { 86 | flexDirection: 'row', 87 | justifyContent: 'space-around', 88 | alignItems: 'center', 89 | }, 90 | navItem: { 91 | alignItems: 'center', 92 | justifyContent: 'center', 93 | paddingVertical: 8, 94 | }, 95 | label: { 96 | fontSize: 12, 97 | marginTop: 4, 98 | }, 99 | indicatorContainer: { 100 | width: '100%', 101 | paddingHorizontal: 40, 102 | flexDirection: 'row', 103 | marginTop: 8, 104 | }, 105 | indicator: { 106 | height: 3, 107 | width: 90, 108 | borderRadius: 1.5, 109 | } 110 | }); 111 | 112 | export default BottomNav; -------------------------------------------------------------------------------- /src/iconography/iconography.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { View, Text } from "react-native"; 3 | import { Ionicons } from "@expo/vector-icons"; 4 | import { createStyle } from '../utils/styleCompat'; 5 | import { iconMap, IconName, PlaceholderSize, AvatarSize, IconComponentProps, sizeMapping } from "./iconography.type"; 6 | 7 | const IconComponent: React.FC = ({ 8 | type, 9 | iconName, 10 | size = 24, 11 | theme = "light", 12 | placeholderSize = "medium", 13 | filled = false, 14 | avatarSize = "medium", 15 | initials = "AB", 16 | className = "", 17 | }) => { 18 | if (type === "icon") { 19 | return renderIcon(iconName, size, theme, className); 20 | } 21 | 22 | if (type === "placeholder") { 23 | return renderPlaceholder(placeholderSize, filled, className); 24 | } 25 | 26 | if (type === "avatar") { 27 | return renderAvatar(avatarSize, initials, className); 28 | } 29 | 30 | return null; 31 | }; 32 | 33 | 34 | const renderIcon = ( 35 | iconName?: IconName, 36 | size: number = 24, 37 | theme: "light" | "dark" = "light", 38 | className = "" 39 | ) => { 40 | if (!iconName) return null; 41 | 42 | const baseIconName = iconMap[iconName]; 43 | 44 | 45 | const ionIconName = 46 | theme === "dark" && baseIconName.endsWith("-outline") 47 | ? baseIconName.replace("-outline", "") 48 | : baseIconName; 49 | 50 | return ( 51 | 52 | 53 | 54 | ); 55 | }; 56 | 57 | 58 | const renderPlaceholder = ( 59 | size: PlaceholderSize = "medium", 60 | filled: boolean = false, 61 | className = "" 62 | ) => { 63 | const pixelSize = sizeMapping[size]; 64 | const bgClass = filled ? "bg-black" : "bg-transparent"; 65 | const borderClass = filled ? "" : "border border-black"; 66 | 67 | return ( 68 | 74 | ); 75 | }; 76 | 77 | 78 | const renderAvatar = ( 79 | size: AvatarSize = "medium", 80 | initials: string = "AB", 81 | className = "" 82 | ) => { 83 | const pixelSize = sizeMapping[size]; 84 | 85 | 86 | const fontSize = Math.max(Math.floor(pixelSize * 0.4), 8); 87 | 88 | 89 | const fontWeight = 90 | size === "xl" || size === "large" 91 | ? "900" 92 | : size === "medium" || size === "small" 93 | ? "700" 94 | : "500"; 95 | 96 | return ( 97 | 103 | 111 | {initials} 112 | 113 | 114 | ); 115 | }; 116 | 117 | export default IconComponent; -------------------------------------------------------------------------------- /src/emptystates/emptystates.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { View, Text } from "react-native"; 3 | import Button from "../Button/Button"; 4 | import { createStyle } from '../utils/styleCompat'; 5 | import { ContainerComponentProps } from '../types/common'; 6 | 7 | export interface EmptyStatesProps extends ContainerComponentProps { 8 | message: string; 9 | description?: string; 10 | label?: string; 11 | onPress?: () => void; 12 | action?: "none" | "primary" | "secondary"; 13 | children?: React.ReactNode; 14 | } 15 | 16 | const EmptyState: React.FC = ({ 17 | message, 18 | description, 19 | label = "Okay", 20 | onPress, 21 | action = "none", 22 | children, 23 | className, 24 | style, 25 | ...props 26 | }) => { 27 | const renderButton = () => { 28 | if (action === "none") return null; 29 | 30 | const buttontype = action === "primary" ? "primary" : "secondary"; 31 | 32 | return ( 33 |