@hoddy-ui/core 1.0.100 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,331 +1,914 @@
1
1
  # @hoddy-ui/core
2
2
 
3
- Hoddy UI is a versatile UI component and theming library for React Native and Expo. It follows the Hoddy UI design guidelines, which are a tweak of Material Design. The library provides a collection of reusable components and a customizable theming system to simplify and accelerate the development of mobile applications.
3
+ **The complete UI component library for React Native and Expo applications**
4
4
 
5
- ## Installation
5
+ A comprehensive, production-ready UI component library that follows Material Design principles with a modern twist. Built with TypeScript and optimized for React Native and Expo applications.
6
6
 
7
- To install Hoddy UI, use npm or yarn:
7
+ ## Features
8
8
 
9
- **npm:**
9
+ - 🎨 **20+ Production-Ready Components** - From basic buttons to complex forms
10
+ - 🌗 **Dark Mode Support** - Automatic theme switching with system preference detection
11
+ - 🔧 **TypeScript First** - Full type safety and IntelliSense support
12
+ - ⚡ **Performance Optimized** - Minimal bundle size with tree shaking
13
+ - 🎯 **Accessibility Ready** - WCAG compliant components
14
+ - 🔌 **Highly Customizable** - Extensive theming and configuration options
15
+ - 📱 **Cross Platform** - Works seamlessly on iOS and Android
10
16
 
11
- ```sh
17
+ ## 📦 Installation
18
+
19
+ ```bash
12
20
  npm install @hoddy-ui/core
21
+ # or
22
+ yarn add @hoddy-ui/core
13
23
  ```
14
24
 
15
- **yarn:**
25
+ ### Peer Dependencies
16
26
 
17
- ```sh
18
- yarn add @hoddy-ui/core
27
+ Install the required peer dependencies:
28
+
29
+ ```bash
30
+ npm install @expo/vector-icons @react-native-async-storage/async-storage @react-navigation/native expo-navigation-bar expo-system-ui react-native-safe-area-context react-native-size-matters
19
31
  ```
20
32
 
21
- Hoddy UI has the following peer dependencies, make sure to install them as well:
33
+ Or with yarn:
22
34
 
23
- ```json
24
- "@expo/vector-icons": "^13.0.0",
25
- "@react-native-async-storage/async-storage": "^1.18.1",
26
- "@react-navigation/native": "^6.1.6",
27
- "expo-navigation-bar": "^2.1.1",
28
- "expo-system-ui": "^2.2.1",
29
- "react": "^18.2.0",
30
- "react-native": "^0.71.8",
31
- "react-native-safe-area-context": "^4.5.3",
32
- "react-native-size-matters": "^0.4.0"
35
+ ```bash
36
+ yarn add @expo/vector-icons @react-native-async-storage/async-storage @react-navigation/native expo-navigation-bar expo-system-ui react-native-safe-area-context react-native-size-matters
33
37
  ```
34
38
 
35
- ## Enabling dark mode
39
+ ## 🚀 Quick Start
36
40
 
37
- To take advantage of the dark mode feature, add the UIProvider component to the root of your app
41
+ ### Basic Setup
38
42
 
39
- ```javascript
40
- import { UIThemeProvider } from "hoddy-ui/core";
43
+ 1. **Initialize the library** (optional but recommended):
41
44
 
42
- function App() {
45
+ ```tsx
46
+ import { initialize } from "@hoddy-ui/core";
47
+
48
+ initialize({
49
+ // Custom font family
50
+ fontFamily: "Inter-Regular",
51
+
52
+ // Google Maps API key for Locator component
53
+ googleMapApiKey: "your-google-maps-api-key",
54
+
55
+ // Edge-to-edge display (affects Android navigation bar styling)
56
+ edgeToEdge: false,
57
+
58
+ // Custom colors
59
+ colors: {
60
+ primary: {
61
+ main: "#6366f1",
62
+ light: "#818cf8",
63
+ dark: "#4f46e5",
64
+ },
65
+ },
66
+ });
67
+ ```
68
+
69
+ 2. **Wrap your app with the theme provider**:
70
+
71
+ ```tsx
72
+ import React from "react";
73
+ import { UIThemeProvider } from "@hoddy-ui/core";
74
+ import App from "./App";
75
+
76
+ export default function Root() {
43
77
  return (
44
78
  <UIThemeProvider>
45
- <Component />
79
+ <App />
46
80
  </UIThemeProvider>
47
81
  );
48
82
  }
49
83
  ```
50
84
 
51
- ## Usage
85
+ 3. **Start using components**:
52
86
 
53
- Here's a quick example of how to use Hoddy UI in your React Native or Expo project:
54
-
55
- ```javascript
87
+ ```tsx
56
88
  import React from "react";
57
89
  import { View } from "react-native";
58
- import { Button, Typography } from "@hoddy-ui/core";
90
+ import { Typography, Button, TextField, useColors } from "@hoddy-ui/core";
91
+
92
+ export default function HomeScreen() {
93
+ const colors = useColors();
59
94
 
60
- const HomeScreen = () => {
61
95
  return (
62
- <View>
63
- <Typography>Welcome to Hoddy UI!</Typography>
64
- <Button title="Click me" onPress={() => console.log("Button pressed!")} />
96
+ <View style={{ padding: 20, backgroundColor: colors.white[1] }}>
97
+ <Typography variant="h4" color="primary" gutterBottom={20}>
98
+ Welcome to Hoddy UI!
99
+ </Typography>
100
+
101
+ <TextField
102
+ label="Email Address"
103
+ variant="outlined"
104
+ keyboardType="email-address"
105
+ gutterBottom={16}
106
+ />
107
+
108
+ <Button
109
+ title="Get Started"
110
+ variant="contained"
111
+ color="primary"
112
+ onPress={() => console.log("Button pressed!")}
113
+ />
65
114
  </View>
66
115
  );
67
- };
116
+ }
117
+ ```
118
+
119
+ ## ⚙️ Configuration
120
+
121
+ ### Global Configuration
68
122
 
69
- export default HomeScreen;
123
+ Use the `initialize` function to configure the library globally:
124
+
125
+ ```tsx
126
+ import { initialize } from "@hoddy-ui/core";
127
+
128
+ initialize({
129
+ // Font family for all typography components
130
+ fontFamily?: string;
131
+
132
+ // Google Maps API key for Locator component
133
+ googleMapApiKey?: string;
134
+
135
+ // Edge-to-edge display (skips Android navigation bar styling)
136
+ edgeToEdge?: boolean;
137
+
138
+ // Custom color overrides
139
+ colors?: {
140
+ primary?: { main: string; light?: string; dark?: string };
141
+ secondary?: { main: string; light?: string; dark?: string };
142
+ // ... and more
143
+ };
144
+ });
70
145
  ```
71
146
 
72
- ## Components
147
+ ### Theme Configuration
73
148
 
74
- Hoddy UI provides the following components for building your UI:
149
+ The theme system automatically detects system preferences and can be controlled programmatically:
75
150
 
76
- - [AdaptiveStatusBar](#adaptivestatusbar)
77
- - [Avatar](#avatar)
78
- - [AlertX](#alertx)
79
- - [Button](#button)
80
- - [FlashMessage](#flashmessage)
81
- - [FormWrapper](#formwrapper)
82
- - [Grid](#grid)
83
- - [GridItem](#griditem)
84
- - [IconButton](#iconbutton)
85
- - [LinkButton](#linkbutton)
86
- - [List](#list)
87
- - [ListItem](#listitem)
88
- - [ListItemText](#listitemtext)
89
- - [Locator](#locator)
90
- - [Popup](#popup)
91
- - [SafeAreaView](#safeareaview)
92
- - [Spinner](#spinner)
93
- - [TextField](#textfield)
94
- - [TextField2](#textfield2)
95
- - [Typography](#typography)
151
+ ```tsx
152
+ import { useTheme } from "@hoddy-ui/core";
96
153
 
97
- ## Component API Reference
154
+ function ThemeToggle() {
155
+ const { themeState, themeDispatch } = useTheme();
98
156
 
99
- ### AdaptiveStatusBar
157
+ const toggleTheme = () => {
158
+ themeDispatch({
159
+ type: themeState.mode === "dark" ? "light" : "dark",
160
+ });
161
+ };
162
+
163
+ return (
164
+ <Button
165
+ title={`Switch to ${themeState.mode === "dark" ? "Light" : "Dark"} Mode`}
166
+ onPress={toggleTheme}
167
+ />
168
+ );
169
+ }
170
+ ```
100
171
 
101
- A component that adapts the status bar color based on the theme.
172
+ ## 🎨 Theming System
102
173
 
103
- **Props:**
174
+ ### Using Hooks
104
175
 
105
- | Prop | Type | Default | Description |
106
- | --------------- | ------ | --------------- | ----------------------------------------------------------------------------------------- |
107
- | barStyle | string | "light-content" | The style of the status bar. Possible values: "default", "light-content", "dark-content". |
108
- | backgroundColor | string | Theme-dependent | The background color of the status bar. |
176
+ Access theme colors and state throughout your app:
109
177
 
110
- Example usage:
178
+ ```tsx
179
+ import { useColors, useTheme } from "@hoddy-ui/core";
111
180
 
112
- ```jsx
113
- import { AdaptiveStatusBar } from "@hoddy-ui/core";
181
+ function MyComponent() {
182
+ const colors = useColors();
183
+ const theme = useTheme();
114
184
 
115
- const App = () => {
116
185
  return (
117
- <>
118
- <AdaptiveStatusBar />
119
- {/* Rest of the app */}
120
- </>
186
+ <View
187
+ style={{
188
+ backgroundColor: colors.white[1],
189
+ borderColor: colors.primary.main,
190
+ }}
191
+ >
192
+ <Typography color={theme === "dark" ? "white" : "dark"}>
193
+ Current theme: {theme}
194
+ </Typography>
195
+ </View>
121
196
  );
197
+ }
198
+ ```
199
+
200
+ ### Color Palette
201
+
202
+ The library includes a comprehensive color system:
203
+
204
+ ```tsx
205
+ const colors = {
206
+ // Primary colors
207
+ primary: { main: "#007AFF", light: "#5AC8FA", dark: "#0051D5" },
208
+ secondary: { main: "#FF3B30", light: "#FF6B6B", dark: "#D70015" },
209
+
210
+ // Neutral colors
211
+ white: ["#FFFFFF", "#F8F9FA", "#E9ECEF"],
212
+ black: ["#000000", "#212529", "#495057"],
213
+
214
+ // Semantic colors
215
+ success: { main: "#28A745", light: "#34CE57", dark: "#1E7E34" },
216
+ error: { main: "#DC3545", light: "#E74C3C", dark: "#C82333" },
217
+ warning: { main: "#FFC107", light: "#FFD54F", dark: "#FF8F00" },
218
+
219
+ // Utility colors
220
+ textPrimary: { main: "#212529" },
221
+ textSecondary: { main: "#6C757D" },
222
+ divider: { main: "#DEE2E6" },
122
223
  };
123
224
  ```
124
225
 
125
- ### Avatar
226
+ ## 🧩 Components
126
227
 
127
- A component for displaying user avatars.
228
+ ### Layout & Structure
128
229
 
129
- **Props:**
230
+ - **`SafeAreaView`** - Safe area wrapper for different devices
231
+ - **`Grid`** & **`GridItem`** - Flexible grid layout system
232
+ - **`FormWrapper`** - Form container with validation support
130
233
 
131
- | Prop | Type | Default | Description |
132
- | ------- | ------- | ------- | ------------------------------------- |
133
- | image | number | - | The source of the avatar image. |
134
- | size | number | 40 | The size of the avatar in pixels. |
135
- | rounded | boolean | false | Whether the avatar should be rounded. |
234
+ ### Navigation & Status
136
235
 
137
- ### AlertX
236
+ - **`AdaptiveStatusBar`** - Theme-aware status bar
237
+ - Navigation utilities via hooks
138
238
 
139
- A customizable alert component.
239
+ ### Typography
140
240
 
141
- **Props:**
241
+ - **`Typography`** - Comprehensive text component with variants (h1-h6, body1-body2, caption)
142
242
 
143
- | Prop | Type | Default | Description |
144
- | ------- | ------ | --------- | --------------------------------------------------------------------------------- |
145
- | title | string | - | The title of the alert. |
146
- | message | string | - | The message/content of the alert. |
147
- | type | string | "default" | The type of the alert. Possible values: "default", "success", "error", "warning". |
243
+ ### Form Components
148
244
 
149
- ### Button
245
+ - **`TextField`** - Material Design text input with variants
246
+ - **`TextField2`** - Alternative text field design
247
+ - **`Locator`** - Location picker with Google Maps integration
150
248
 
151
- A customizable button component.
249
+ ### Interactive Elements
152
250
 
153
- **Props:**
251
+ - **`Button`** - Primary action buttons with variants
252
+ - **`IconButton`** - Icon-only buttons
253
+ - **`LinkButton`** - Text-based link buttons
154
254
 
155
- | Prop | Type | Default | Description |
156
- | ------- | -------- | ------- | ------------------------------------------ |
157
- | title | string | - | The text to display on the button. |
158
- | onPress | function | - | The function to be called on button press. |
255
+ ### Feedback & Communication
159
256
 
160
- ### FlashMessage
257
+ - **`FlashMessage`** - Toast notifications and alerts
258
+ - **`AlertX`** - Customizable alert dialogs
259
+ - **`Spinner`** - Loading indicators
161
260
 
162
- A component for displaying flash messages.
261
+ ### Data Display
163
262
 
164
- **Props:**
263
+ - **`Avatar`** - User profile images and placeholders
264
+ - **`List`**, **`ListItem`**, **`ListItemText`** - List components
165
265
 
166
- | Prop | Type | Default | Description |
167
- | -------- | ------- | --------- | ----------------------------------------------------------------------------------------- |
168
- | message | string | - | The message/content of the flash message. |
169
- | type | string | "default" | The type of the flash message. Possible values: "default", "success", "error", "warning". |
170
- | duration | number | 3000 | The duration in milliseconds that the flash message should be displayed. |
171
- | autoHide | boolean | true | Whether the flash message should auto-hide after the specified duration. |
266
+ ### Overlays & Modals
172
267
 
173
- ### FormWrapper
268
+ - **`Popup`** - Modal dialogs and bottom sheets
174
269
 
175
- A wrapper component for form fields.
270
+ ### Animation
176
271
 
177
- **Props:**
272
+ - **`Animator`** - Layout animations and transitions
178
273
 
179
- | Prop | Type | Default | Description |
180
- | -------- | ---- | ------- | ----------------------------------------- |
181
- | children | node | - | The form fields/components to be wrapped. |
274
+ ## 📖 Component API Reference
182
275
 
183
- ### Grid
276
+ ### Typography
184
277
 
185
- A flexible grid component for arranging child elements.
278
+ A versatile text component supporting multiple variants and styling options.
186
279
 
187
280
  **Props:**
188
281
 
189
- | Prop | Type | Default | Description |
190
- | ---------- | ------ | ------- | ---------------------------------------------- |
191
- | children | node | - | The child elements to be rendered in the grid. |
192
- | numColumns | number | 2 | The number of columns in the grid. |
193
- | spacing | number | 10 | The spacing between grid items in pixels. |
282
+ | Prop | Type | Default | Description |
283
+ | -------------- | --------------------------------------------------------------------------------- | --------- | ----------------------------- |
284
+ | `variant` | `"h1" \| "h2" \| "h3" \| "h4" \| "h5" \| "h6" \| "body1" \| "body2" \| "caption"` | `"body1"` | Text style variant |
285
+ | `color` | `string` | `"dark"` | Text color from theme palette |
286
+ | `align` | `"left" \| "center" \| "right"` | `"left"` | Text alignment |
287
+ | `gutterBottom` | `number` | `0` | Bottom margin in pixels |
288
+ | `fontWeight` | `number` | `400` | Font weight |
289
+ | `textCase` | `"uppercase" \| "lowercase" \| "capitalize"` | `null` | Text transformation |
290
+
291
+ **Example:**
292
+
293
+ ```tsx
294
+ <Typography variant="h4" color="primary" gutterBottom={20}>
295
+ Welcome to Hoddy UI
296
+ </Typography>
297
+ ```
194
298
 
195
- ### GridItem
299
+ ### Button
196
300
 
197
- A component representing an item in the Grid component.
301
+ A comprehensive button component with multiple variants and states.
198
302
 
199
303
  **Props:**
200
304
 
201
- | Prop | Type | Default | Description |
202
- | -------- | ---- | ------- | ----------------------------- |
203
- | children | node | - | The content of the grid item. |
305
+ | Prop | Type | Default | Description |
306
+ | ---------- | ------------------------------------- | ------------- | -------------------------- |
307
+ | `title` | `string` | - | Button text |
308
+ | `variant` | `"contained" \| "outlined" \| "text"` | `"contained"` | Button variant |
309
+ | `color` | `string` | `"primary"` | Button color from theme |
310
+ | `size` | `"small" \| "medium" \| "large"` | `"medium"` | Button size |
311
+ | `disabled` | `boolean` | `false` | Disabled state |
312
+ | `loading` | `boolean` | `false` | Loading state with spinner |
313
+ | `onPress` | `() => void` | - | Press handler |
314
+ | `start` | `ReactNode` | - | Leading icon/element |
315
+ | `end` | `ReactNode` | - | Trailing icon/element |
316
+
317
+ **Example:**
318
+
319
+ ```tsx
320
+ <Button
321
+ title="Submit"
322
+ variant="contained"
323
+ color="primary"
324
+ loading={isLoading}
325
+ onPress={handleSubmit}
326
+ />
327
+ ```
204
328
 
205
329
  ### IconButton
206
330
 
207
- A button component with an icon.
331
+ A button component that displays only an icon.
208
332
 
209
333
  **Props:**
210
334
 
211
- | Prop | Type | Default | Description |
212
- | ------- | -------- | ------- | ------------------------------------------ |
213
- | icon | string | - | The name of the icon to display. |
214
- | onPress | function | - | The function to be called on button press. |
335
+ | Prop | Type | Default | Description |
336
+ | ----------------- | --------------------- | ------------ | ------------------------- |
337
+ | `icon` | `string` | - | Icon name |
338
+ | `iconType` | `"material" \| "ion"` | `"material"` | Icon library to use |
339
+ | `size` | `number` | `24` | Icon size in pixels |
340
+ | `color` | `string` | `"dark"` | Icon color from theme |
341
+ | `bg` | `boolean` | `false` | Show background circle |
342
+ | `elevation` | `number` | `0` | Shadow elevation |
343
+ | `disabled` | `boolean` | `false` | Disabled state |
344
+ | `onPress` | `() => void` | - | Press handler |
345
+ | `style` | `ViewStyle` | `{}` | Icon style overrides |
346
+ | `containerStyles` | `ViewStyle` | `{}` | Container style overrides |
347
+
348
+ **Example:**
349
+
350
+ ```tsx
351
+ <IconButton
352
+ icon="star"
353
+ iconType="ion"
354
+ size={28}
355
+ color="primary"
356
+ bg={true}
357
+ elevation={2}
358
+ onPress={() => console.log("Starred!")}
359
+ />
360
+ ```
215
361
 
216
362
  ### LinkButton
217
363
 
218
- A button component that navigates to a specified URL.
364
+ A text-based button component for navigation or secondary actions.
219
365
 
220
366
  **Props:**
221
367
 
222
- | Prop | Type | Default | Description |
223
- | ----- | ------ | ------- | --------------------------------------- |
224
- | title | string | - | The text to display on the button. |
225
- | url | string | - | The URL to navigate to on button press. |
368
+ | Prop | Type | Default | Description |
369
+ | ------------ | ------------ | -------- | --------------------- |
370
+ | `title` | `string` | - | Button text |
371
+ | `color` | `string` | `"blue"` | Text color from theme |
372
+ | `fontSize` | `number` | `12` | Font size |
373
+ | `fontWeight` | `string` | `"400"` | Font weight |
374
+ | `disabled` | `boolean` | `false` | Disabled state |
375
+ | `onPress` | `() => void` | - | Press handler |
376
+ | `style` | `TextStyle` | `{}` | Text style overrides |
377
+
378
+ **Example:**
379
+
380
+ ```tsx
381
+ <LinkButton
382
+ title="Forgot Password?"
383
+ color="primary"
384
+ fontSize={14}
385
+ onPress={() => navigation.navigate("ForgotPassword")}
386
+ />
387
+ ```
226
388
 
227
- ### List
389
+ ### TextField
228
390
 
229
- A component for rendering lists.
391
+ A Material Design text input component with comprehensive features.
230
392
 
231
393
  **Props:**
232
394
 
233
- | Prop | Type | Default | Description |
234
- | -------- | ---- | ------- | ------------------------------ |
235
- | children | node | - | The list items to be rendered. |
395
+ | Prop | Type | Default | Description |
396
+ | -------------- | -------------------------------------- | ------------ | --------------------- |
397
+ | `label` | `string` | - | Input label |
398
+ | `variant` | `"outlined" \| "filled" \| "standard"` | `"outlined"` | Input variant |
399
+ | `value` | `string` | - | Input value |
400
+ | `onChangeText` | `(text: string) => void` | - | Change handler |
401
+ | `placeholder` | `string` | - | Placeholder text |
402
+ | `error` | `boolean` | `false` | Error state |
403
+ | `helperText` | `string` | - | Helper/error text |
404
+ | `disabled` | `boolean` | `false` | Disabled state |
405
+ | `multiline` | `boolean` | `false` | Multiline input |
406
+ | `start` | `ReactNode` | - | Leading icon/element |
407
+ | `end` | `ReactNode` | - | Trailing icon/element |
408
+
409
+ **Example:**
410
+
411
+ ```tsx
412
+ <TextField
413
+ label="Email Address"
414
+ variant="outlined"
415
+ value={email}
416
+ onChangeText={setEmail}
417
+ keyboardType="email-address"
418
+ error={!!emailError}
419
+ helperText={emailError}
420
+ />
421
+ ```
236
422
 
237
- ### ListItem
423
+ ### Locator
238
424
 
239
- A component representing an item in the List component.
425
+ A location picker component with Google Maps integration.
240
426
 
241
427
  **Props:**
242
428
 
243
- | Prop | Type | Default | Description |
244
- | -------- | ---- | ------- | ----------------------------- |
245
- | children | node | - | The content of the list item. |
429
+ | Prop | Type | Default | Description |
430
+ | -------------------- | ---------------------------------- | ------------- | -------------------------- |
431
+ | `onLocationSelected` | `(location: LocationType) => void` | - | Location selection handler |
432
+ | `label` | `string` | - | Input label |
433
+ | `variant` | `"contained" \| "outlined"` | `"contained"` | Input variant |
434
+ | `location` | `LocationType` | - | Current location |
435
+ | `country` | `string` | `"ng"` | Country code for search |
436
+ | `error` | `boolean` | `false` | Error state |
437
+
438
+ **Example:**
439
+
440
+ ```tsx
441
+ <Locator
442
+ label="Select Location"
443
+ onLocationSelected={(location) => setSelectedLocation(location)}
444
+ country="us"
445
+ />
446
+ ```
246
447
 
247
- ### ListItemText
448
+ ### SafeAreaView
248
449
 
249
- A component representing the text content of a ListItem.
450
+ A safe area wrapper component that handles device-specific safe areas.
250
451
 
251
452
  **Props:**
252
453
 
253
- | Prop | Type | Default | Description |
254
- | -------- | ---- | ------- | ------------------------ |
255
- | children | node | - | The text to be rendered. |
454
+ | Prop | Type | Default | Description |
455
+ | ---------- | ----------- | ------- | ------------------------- |
456
+ | `children` | `ReactNode` | - | Child components |
457
+ | `style` | `ViewStyle` | `{}` | Container style overrides |
256
458
 
257
- ### Locator
459
+ **Example:**
460
+
461
+ ```tsx
462
+ <SafeAreaView style={{ backgroundColor: "white" }}>
463
+ <YourContent />
464
+ </SafeAreaView>
465
+ ```
258
466
 
259
- A component for displaying a location marker on a map.
467
+ ### AdaptiveStatusBar
468
+
469
+ A status bar component that automatically adapts to the current theme.
260
470
 
261
471
  **Props:**
262
472
 
263
- | Prop | Type | Default | Description |
264
- | --------- | ------ | ------- | ------------------------------ |
265
- | latitude | number | - | The latitude of the location. |
266
- | longitude | number | - | The longitude of the location. |
473
+ | Prop | Type | Default | Description |
474
+ | ------------- | --------- | ------- | ------------------------------------- |
475
+ | `translucent` | `boolean` | `false` | Whether the status bar is translucent |
267
476
 
268
- ### Popup
477
+ **Example:**
478
+
479
+ ```tsx
480
+ <AdaptiveStatusBar translucent={true} />
481
+ ```
269
482
 
270
- A customizable popup component.
483
+ ### AlertX
484
+
485
+ A customizable alert component for displaying important messages.
271
486
 
272
487
  **Props:**
273
488
 
274
- | Prop | Type | Default | Description |
275
- | ------- | -------- | ------- | --------------------------------------------------- |
276
- | title | string | - | The title of the popup. |
277
- | onClose | function | - | The function to be called when the popup is closed. |
489
+ | Prop | Type | Default | Description |
490
+ | -------------- | --------------------------------------------- | ------------- | ------------------------- |
491
+ | `type` | `"info" \| "warning" \| "success" \| "error"` | `"info"` | Alert type |
492
+ | `variant` | `"contained" \| "outlined"` | `"contained"` | Alert variant |
493
+ | `title` | `string` | - | Alert title |
494
+ | `body` | `string` | - | Alert message |
495
+ | `gutterBottom` | `number` | `0` | Bottom margin in pixels |
496
+ | `style` | `ViewStyle` | `{}` | Container style overrides |
497
+
498
+ **Example:**
499
+
500
+ ```tsx
501
+ <AlertX
502
+ type="success"
503
+ title="Success!"
504
+ body="Your profile has been updated successfully."
505
+ gutterBottom={20}
506
+ />
507
+ ```
278
508
 
279
- ### SafeAreaView
509
+ ### Avatar
280
510
 
281
- A component that renders content within the safe area boundaries of the device.
511
+ A component for displaying user avatars with support for images, labels, or default icons.
282
512
 
283
513
  **Props:**
284
514
 
285
- | Prop | Type | Default | Description |
286
- | -------- | ---- | ------- | --------------------------- |
287
- | children | node | - | The content to be rendered. |
515
+ | Prop | Type | Default | Description |
516
+ | --------- | --------------------------- | ------------- | --------------------------- |
517
+ | `source` | `ImageSourcePropType` | - | Image source |
518
+ | `label` | `string` | - | Text label (first letter) |
519
+ | `size` | `number` | `48` | Avatar size in pixels |
520
+ | `color` | `string` | `"dark"` | Background color from theme |
521
+ | `variant` | `"contained" \| "outlined"` | `"contained"` | Avatar variant |
522
+ | `style` | `ViewStyle` | `{}` | Container style overrides |
523
+
524
+ **Example:**
525
+
526
+ ```tsx
527
+ <Avatar
528
+ source={{ uri: 'https://example.com/avatar.jpg' }}
529
+ size={64}
530
+ />
531
+
532
+ <Avatar
533
+ label="John Doe"
534
+ color="primary"
535
+ size={48}
536
+ />
537
+ ```
288
538
 
289
- ### Spinner
539
+ ### Grid & GridItem
540
+
541
+ Flexible grid layout components for organizing content.
542
+
543
+ **Grid Props:**
544
+
545
+ | Prop | Type | Default | Description |
546
+ | ---------- | ----------- | ------- | ------------------------- |
547
+ | `children` | `ReactNode` | - | GridItem components |
548
+ | `spacing` | `number` | `1` | Spacing between items |
549
+ | `style` | `ViewStyle` | `{}` | Container style overrides |
550
+
551
+ **GridItem Props:**
552
+
553
+ | Prop | Type | Default | Description |
554
+ | ------------ | ---------------------------------------- | ------- | ------------------------- |
555
+ | `children` | `ReactNode` | - | Item content |
556
+ | `col` | `number` | `2` | Number of columns to span |
557
+ | `alignItems` | `"center" \| "flex-start" \| "flex-end"` | - | Item alignment |
558
+ | `spacing` | `number` | `1` | Item spacing |
559
+ | `style` | `ViewStyle` | `{}` | Item style overrides |
560
+
561
+ **Example:**
562
+
563
+ ```tsx
564
+ <Grid spacing={2}>
565
+ <GridItem col={2}>
566
+ <Typography>Full width item</Typography>
567
+ </GridItem>
568
+ <GridItem col={4} alignItems="center">
569
+ <Typography>Quarter width item</Typography>
570
+ </GridItem>
571
+ <GridItem col={4}>
572
+ <Typography>Another quarter width</Typography>
573
+ </GridItem>
574
+ </Grid>
575
+ ```
576
+
577
+ ### FormWrapper
290
578
 
291
- A component for displaying a loading spinner.
579
+ A wrapper component that provides keyboard handling and scrolling for forms.
292
580
 
293
581
  **Props:**
294
582
 
295
- | Prop | Type | Default | Description |
296
- | ----- | ------ | --------------- | ----------------------------------------------------------- |
297
- | size | string | "small" | The size of the spinner. Possible values: "small", "large". |
298
- | color | string | Theme-dependent | The color of the spinner. |
583
+ | Prop | Type | Default | Description |
584
+ | ------------------------ | ------------------------------- | ------------------ | --------------------------- |
585
+ | `children` | `ReactNode` | - | Form content |
586
+ | `mode` | `"scroll" \| "static"` | `"scroll"` | Wrapper mode |
587
+ | `behavior` | `KeyboardAvoidingView` behavior | Platform-dependent | Keyboard avoidance behavior |
588
+ | `keyboardVerticalOffset` | `number` | `10` | Keyboard offset |
589
+ | `contentContainerStyle` | `ViewStyle` | `{}` | ScrollView content style |
590
+ | `style` | `ViewStyle` | `{}` | Container style |
591
+ | `onScroll` | `(event) => void` | - | Scroll event handler |
592
+
593
+ **Example:**
594
+
595
+ ```tsx
596
+ <FormWrapper mode="scroll" keyboardVerticalOffset={20}>
597
+ <TextField label="Name" />
598
+ <TextField label="Email" />
599
+ <Button title="Submit" />
600
+ </FormWrapper>
601
+ ```
299
602
 
300
- ### TextField
603
+ ### List, ListItem & ListItemText
604
+
605
+ Components for displaying structured lists of data.
606
+
607
+ **List Props:**
608
+
609
+ | Prop | Type | Default | Description |
610
+ | ---------- | ----------- | ------- | ------------------------- |
611
+ | `children` | `ReactNode` | - | ListItem components |
612
+ | `style` | `ViewStyle` | `{}` | Container style overrides |
613
+
614
+ **ListItem Props:**
615
+
616
+ | Prop | Type | Default | Description |
617
+ | ---------- | ------------ | ------- | ------------------------- |
618
+ | `children` | `ReactNode` | - | Item content |
619
+ | `link` | `boolean` | `false` | Show arrow indicator |
620
+ | `divider` | `boolean` | `false` | Show bottom border |
621
+ | `onPress` | `() => void` | - | Press handler |
622
+ | `index` | `number` | `1` | Item index for animations |
623
+ | `style` | `ViewStyle` | `{}` | Item style overrides |
624
+
625
+ **ListItemText Props:**
626
+
627
+ | Prop | Type | Default | Description |
628
+ | ---------------- | ----------------- | ------- | ------------------------- |
629
+ | `primary` | `string` | - | Primary text |
630
+ | `secondary` | `string` | - | Secondary text |
631
+ | `divider` | `boolean` | `false` | Show bottom border |
632
+ | `primaryProps` | `TypographyProps` | `{}` | Primary text props |
633
+ | `secondaryProps` | `TypographyProps` | `{}` | Secondary text props |
634
+ | `style` | `ViewStyle` | `{}` | Container style overrides |
635
+
636
+ **Example:**
637
+
638
+ ```tsx
639
+ <List>
640
+ <ListItem link onPress={() => navigate("Profile")}>
641
+ <ListItemText primary="Profile Settings" secondary="Manage your account" />
642
+ </ListItem>
643
+ <ListItem divider>
644
+ <ListItemText primary="Notifications" />
645
+ </ListItem>
646
+ </List>
647
+ ```
301
648
 
302
- A component for text input.
649
+ ### Popup
650
+
651
+ A modal component for overlays, dialogs, and bottom sheets.
303
652
 
304
653
  **Props:**
305
654
 
306
- | Prop | Type | Default | Description |
307
- | ----------- | ------ | ------- | ----------------------------------- |
308
- | label | string | - | The label for the text input. |
309
- | placeholder | string | - | The placeholder text for the input. |
655
+ | Prop | Type | Default | Description |
656
+ | ------------------------ | ------------------- | ------- | ------------------------- |
657
+ | `open` | `boolean` | - | Whether popup is visible |
658
+ | `onClose` | `() => void` | - | Close handler |
659
+ | `title` | `string` | - | Popup title |
660
+ | `children` | `ReactNode` | - | Popup content |
661
+ | `sheet` | `boolean \| number` | `false` | Bottom sheet mode/height |
662
+ | `bare` | `boolean` | `false` | Hide header and padding |
663
+ | `keyboardVerticalOffset` | `number` | - | Keyboard avoidance offset |
664
+ | `style` | `ViewStyle` | `{}` | Container style overrides |
665
+
666
+ **Example:**
667
+
668
+ ```tsx
669
+ <Popup
670
+ open={isOpen}
671
+ onClose={() => setIsOpen(false)}
672
+ title="Confirm Action"
673
+ sheet={400}
674
+ >
675
+ <Typography>Are you sure you want to delete this item?</Typography>
676
+ <Button title="Delete" color="error" />
677
+ <Button title="Cancel" variant="outlined" />
678
+ </Popup>
679
+ ```
310
680
 
311
- ### TextField2
681
+ ### Spinner
312
682
 
313
- Another component for text input.
683
+ A loading indicator component with customizable appearance.
314
684
 
315
685
  **Props:**
316
686
 
317
- | Prop | Type | Default | Description |
318
- | ----------- | ------ | ------- | ----------------------------------- |
319
- | label | string | - | The label for the text input. |
320
- | placeholder | string | - | The placeholder text for the input. |
687
+ | Prop | Type | Default | Description |
688
+ | ------------ | -------------------- | ----------- | ------------------------- |
689
+ | `size` | `"small" \| "large"` | `"large"` | Spinner size |
690
+ | `color` | `string` | `"primary"` | Spinner color from theme |
691
+ | `label` | `string` | - | Loading text |
692
+ | `fullscreen` | `boolean` | `false` | Cover entire screen |
693
+ | `style` | `ViewStyle` | `{}` | Container style overrides |
321
694
 
322
- ### Typography
695
+ **Example:**
696
+
697
+ ```tsx
698
+ <Spinner size="large" color="primary" label="Loading..." fullscreen={true} />
699
+ ```
700
+
701
+ ### Animator
323
702
 
324
- A component for displaying text with different styles.
703
+ A component for adding layout animations and transitions.
325
704
 
326
705
  **Props:**
327
706
 
328
- | Prop | Type | Default | Description |
329
- | -------- | ------ | ------- | ---------------------------------------------------------------------------------------------------- |
330
- | variant | string | "body" | The style variant of the text. Possible values: "heading", "title", "subheading", "body", "caption". |
331
- | children | node | - | The text content to be rendered. |
707
+ | Prop | Type | Default | Description |
708
+ | --------------- | --------------------------------------------------------------------------- | ----------------- | ------------------------- |
709
+ | `children` | `ReactNode` | - | Content to animate |
710
+ | `type` | `"fade" \| "slideInLeft" \| "slideInRight" \| "slideInUp" \| "slideInDown"` | `"fade"` | Animation type |
711
+ | `duration` | `number` | `500` | Animation duration (ms) |
712
+ | `delay` | `number` | `100` | Animation delay (ms) |
713
+ | `animationType` | `"easeInEaseOut" \| "linear" \| "spring"` | `"easeInEaseOut"` | Animation timing function |
714
+ | `style` | `ViewStyle` | `{}` | Container style overrides |
715
+
716
+ **Example:**
717
+
718
+ ```tsx
719
+ <Animator type="slideInUp" duration={600} delay={200} animationType="spring">
720
+ <Typography>This content will slide up</Typography>
721
+ </Animator>
722
+ ```
723
+
724
+ ### FlashMessage
725
+
726
+ Display toast notifications and alerts.
727
+
728
+ **Props:**
729
+
730
+ | Prop | Type | Default | Description |
731
+ | ---------- | --------------------------------------------- | -------- | ---------------------- |
732
+ | `message` | `string` | - | Message text |
733
+ | `type` | `"success" \| "error" \| "warning" \| "info"` | `"info"` | Message type |
734
+ | `duration` | `number` | `3000` | Display duration in ms |
735
+ | `position` | `"top" \| "bottom"` | `"top"` | Message position |
736
+
737
+ **Usage:**
738
+
739
+ ```tsx
740
+ import { showMessage } from "@hoddy-ui/core";
741
+
742
+ // Show a success message
743
+ showMessage({
744
+ message: "Profile updated successfully!",
745
+ type: "success",
746
+ });
747
+ ```
748
+
749
+ ## 🔧 Hooks
750
+
751
+ ### useColors
752
+
753
+ Access the current theme's color palette:
754
+
755
+ ```tsx
756
+ import { useColors } from "@hoddy-ui/core";
757
+
758
+ function MyComponent() {
759
+ const colors = useColors();
760
+
761
+ return (
762
+ <View style={{ backgroundColor: colors.primary.main }}>
763
+ {/* Component content */}
764
+ </View>
765
+ );
766
+ }
767
+ ```
768
+
769
+ ### useTheme
770
+
771
+ Access and control the current theme:
772
+
773
+ ```tsx
774
+ import { useTheme } from "@hoddy-ui/core";
775
+
776
+ function ThemeAwareComponent() {
777
+ const { themeState, themeDispatch } = useTheme();
778
+
779
+ const toggleTheme = () => {
780
+ themeDispatch({
781
+ type: themeState.mode === "dark" ? "light" : "dark",
782
+ });
783
+ };
784
+
785
+ return <Button title="Toggle Theme" onPress={toggleTheme} />;
786
+ }
787
+ ```
788
+
789
+ ### useNavScreenOptions
790
+
791
+ Get theme-aware navigation screen options:
792
+
793
+ ```tsx
794
+ import { useNavScreenOptions } from "@hoddy-ui/core";
795
+
796
+ function MyScreen() {
797
+ const screenOptions = useNavScreenOptions("stack");
798
+
799
+ // Use with React Navigation
800
+ return (
801
+ <Stack.Screen name="Home" component={HomeScreen} options={screenOptions} />
802
+ );
803
+ }
804
+ ```
805
+
806
+ ## 🎯 Advanced Usage
807
+
808
+ ### Custom Theme Provider
809
+
810
+ Create your own theme provider with custom configurations:
811
+
812
+ ```tsx
813
+ import { UIThemeProvider, initialize } from "@hoddy-ui/core";
814
+
815
+ // Initialize with custom configuration
816
+ initialize({
817
+ fontFamily: "CustomFont-Regular",
818
+ colors: {
819
+ primary: { main: "#FF6B6B" },
820
+ secondary: { main: "#4ECDC4" },
821
+ },
822
+ });
823
+
824
+ function App() {
825
+ return (
826
+ <UIThemeProvider>
827
+ <YourAppContent />
828
+ </UIThemeProvider>
829
+ );
830
+ }
831
+ ```
832
+
833
+ ### Form Validation Example
834
+
835
+ ```tsx
836
+ import React, { useState } from "react";
837
+ import { View } from "react-native";
838
+ import { TextField, Button, FormWrapper } from "@hoddy-ui/core";
839
+
840
+ function LoginForm() {
841
+ const [email, setEmail] = useState("");
842
+ const [password, setPassword] = useState("");
843
+ const [errors, setErrors] = useState({});
844
+
845
+ const validate = () => {
846
+ const newErrors = {};
847
+ if (!email) newErrors.email = "Email is required";
848
+ if (!password) newErrors.password = "Password is required";
849
+ setErrors(newErrors);
850
+ return Object.keys(newErrors).length === 0;
851
+ };
852
+
853
+ const handleSubmit = () => {
854
+ if (validate()) {
855
+ // Handle form submission
856
+ }
857
+ };
858
+
859
+ return (
860
+ <FormWrapper>
861
+ <TextField
862
+ label="Email"
863
+ value={email}
864
+ onChangeText={setEmail}
865
+ error={!!errors.email}
866
+ helperText={errors.email}
867
+ keyboardType="email-address"
868
+ />
869
+
870
+ <TextField
871
+ label="Password"
872
+ value={password}
873
+ onChangeText={setPassword}
874
+ error={!!errors.password}
875
+ helperText={errors.password}
876
+ secureTextEntry
877
+ />
878
+
879
+ <Button
880
+ title="Login"
881
+ onPress={handleSubmit}
882
+ variant="contained"
883
+ color="primary"
884
+ />
885
+ </FormWrapper>
886
+ );
887
+ }
888
+ ```
889
+
890
+ ## 📱 Platform Compatibility
891
+
892
+ - **React Native**: ≥ 0.71.8
893
+ - **Expo**: SDK 48+
894
+ - **iOS**: 11.0+
895
+ - **Android**: API 21+ (Android 5.0)
896
+ - **TypeScript**: ≥ 5.0.4
897
+
898
+ ## 🤝 Contributing
899
+
900
+ We welcome contributions! Please see our [Contributing Guide](../../CONTRIBUTING.md) for details.
901
+
902
+ ## 📄 License
903
+
904
+ MIT © [Hoddy Inc](https://github.com/kinghoddy)
905
+
906
+ ## 🔗 Links
907
+
908
+ - [GitHub Repository](https://github.com/kinghoddy/hoddy-ui)
909
+ - [npm Package](https://www.npmjs.com/package/@hoddy-ui/core)
910
+ - [Issues & Support](https://github.com/kinghoddy/hoddy-ui/issues)
911
+
912
+ ---
913
+
914
+ **Need help?** [Open an issue](https://github.com/kinghoddy/hoddy-ui/issues) or check out our [examples](../../test/hoddyui).