luna-components-library 1.1.36 → 1.1.37

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
@@ -7,10 +7,12 @@ A modern React component library built with TypeScript and Vite, designed for re
7
7
  - 🚀 **Built with Vite** - Fast development and optimized builds
8
8
  - 📝 **TypeScript Support** - Full type safety and IntelliSense
9
9
  - 🎨 **Modern Components** - Clean, accessible, and customizable UI components
10
- - 🎯 **Tailwind CSS Styled** - Components use Tailwind CSS utility classes for styling
10
+ - 🎯 **Zero Dependencies** - Components use a pure inline-style architecture for maximum portability
11
11
  - 📦 **Tree-shakable** - Only bundle what you use
12
12
  - 🔧 **Multiple Formats** - ES modules and UMD bundles
13
13
  - 📚 **Type Declarations** - Complete TypeScript definitions included
14
+ - 🧩 **Centralized Design System** - All design tokens, variants, and shared styles live in `src/styles.ts` for consistency
15
+ - 🎭 **className Passthrough** - Every component accepts a `className` prop applied to the outermost element
14
16
 
15
17
  ## 📦 Installation
16
18
 
@@ -22,96 +24,73 @@ yarn add luna-components-library
22
24
  pnpm add luna-components-library
23
25
  ```
24
26
 
25
- **⚠️ Important:** This library uses **Tailwind CSS** for styling. Make sure you have Tailwind CSS configured in your project:
26
-
27
- ```bash
28
- npm install tailwindcss
29
- npx tailwindcss init -p
30
- ```
31
-
32
- Then add the library's components to your `tailwind.config.js`:
33
-
34
- ```js
35
- module.exports = {
36
- content: [
37
- "./src/**/*.{js,jsx,ts,tsx}",
38
- "./node_modules/luna-components-library/dist/**/*.{js,ts,jsx,tsx}"
39
- ],
40
- // ... rest of your config
41
- }
42
- ```
43
-
44
- **💡 Tailwind CSS Best Practices with Luna Library:**
45
- To ensure Tailwind CSS successfully generates and includes the necessary utility classes in your target project's build, it is highly recommended to explicitly provide all necessary styling and positioning classes via the `className` prop for each component you use. By manually specifying these classes (e.g., `className="bg-blue-600 text-white p-4"`), you guarantee that Tailwind's scanner in your main project detects them and includes them in your final CSS file without relying exclusively on the node_modules parser.
27
+ **💡 No Setup Required:**
28
+ Luna Library is fully standalone. All styles are encapsulated within the components using inline styles and dynamic CSS injection, meaning you do not need to install Tailwind CSS, PostCSS, Bootstrap, or any other styling framework to use it. Just install and import!
46
29
 
47
30
  ## 🚀 Quick Start
48
31
 
49
32
  ```jsx
33
+ import { useState } from 'react';
50
34
  import {
51
- Button, Card, Anchor, Accordion, Spinner, DropDown,
52
- ProgressBar, Preloader, ScrollTop, Modal, Input,
53
- WhatsApp, Typed
35
+ Button, Input, Card, Typed, Accordion, ProgressBar, Spinner,
36
+ Preloader, ScrollTop, Modal, WhatsApp, DataTable
54
37
  } from 'luna-components-library';
55
38
 
56
39
  function App() {
57
40
  const [showModal, setShowModal] = useState(false);
58
- const [isLoading, setIsLoading] = useState(false);
59
41
 
60
42
  return (
61
- <div className="p-4 space-y-6">
43
+ <div style={{ padding: '2rem', display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
62
44
  {/* 1. Basic Components */}
63
- <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
45
+ <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
64
46
  <Button
65
47
  variant="primary"
66
48
  onClick={() => setShowModal(true)}
67
- className="bg-blue-600 hover:bg-blue-700 text-white p-2 rounded"
68
49
  >
69
50
  Open Modal
70
51
  </Button>
71
52
 
72
53
  <Input
73
54
  placeholder="Type something..."
74
- className="border p-2 rounded"
75
55
  />
76
56
  </div>
77
57
 
78
58
  {/* 2. Content Display */}
79
- <Card title="Luna Library" className="shadow-md p-4">
59
+ <Card title="Luna Library" padding="md" shadow="sm">
80
60
  <Typed
81
- strings={['Modern React Components', 'TypeScript Ready', 'Tailwind Styled']}
82
- className="text-blue-600 font-bold"
61
+ strings={['Modern React Components', 'TypeScript Ready', 'Zero Dependencies']}
83
62
  />
84
- <p className="mt-2">Building fast and beautiful interfaces.</p>
63
+ <p style={{ marginTop: '0.5rem' }}>Building fast and beautiful interfaces.</p>
85
64
  </Card>
86
65
 
87
66
  {/* 3. Interactive Elements */}
88
67
  <Accordion
89
- header="Click to expand"
90
- content="This is the accordion content!"
91
- className="border rounded"
92
- />
68
+ title="Click to expand"
69
+ >
70
+ <p>This is the accordion content!</p>
71
+ </Accordion>
93
72
 
94
73
  {/* 4. Feedback & Progress */}
95
- <div className="space-y-2">
74
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
96
75
  <p>Loading Progress:</p>
97
- <ProgressBar progress={75} variant="success" className="h-2 bg-gray-200" />
98
- <Spinner size="sm" type="dots" className="text-blue-500" />
76
+ <ProgressBar progress={75} />
77
+ <Spinner size="sm" type="dots" />
99
78
  </div>
100
79
 
101
80
  {/* 5. Communication & Navigation */}
102
- <div className="flex gap-4">
81
+ <div style={{ display: 'flex', gap: '1rem' }}>
103
82
  <WhatsApp phone="123456789" message="Hello!" />
104
83
  <Anchor href="https://github.com" variant="outline">GitHub Repo</Anchor>
105
84
  </div>
106
85
 
107
86
  {/* 6. Overlays (Modals & Preloaders) */}
108
- <Modal show={showModal} onHide={() => setShowModal(false)} title="Quick Start Modal">
87
+ <Modal isOpen={showModal} onClose={() => setShowModal(false)} title="Quick Start Modal">
109
88
  <p>This is a modal from the library!</p>
110
89
  </Modal>
111
90
 
112
- {isLoading && <Preloader duration={2000} onComplete={() => setIsLoading(false)} />}
91
+ <Preloader isLoading={isLoading} duration={2000} onComplete={() => setIsLoading(false)} />
113
92
 
114
- <ScrollTop threshold={100} className="bg-blue-600 text-white p-2 rounded-full" />
93
+ <ScrollTop />
115
94
  </div>
116
95
  );
117
96
  }
@@ -154,7 +133,6 @@ A versatile button component with multiple variants and sizes.
154
133
  size="md"
155
134
  onClick={handleClick}
156
135
  disabled={false}
157
- className="bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-lg transition-colors duration-200"
158
136
  >
159
137
  Button Text
160
138
  </Button>
@@ -164,7 +142,7 @@ A versatile button component with multiple variants and sizes.
164
142
  - `children`: React.ReactNode - Button content
165
143
  - `variant?: ButtonVariant` - Button style (default: 'primary')
166
144
  - `size?: ButtonSize` - Button size (default: 'md')
167
- - `onClick?: () => void` - Click handler
145
+ - `onClick?: React.MouseEventHandler<HTMLButtonElement>` - Click handler
168
146
  - `disabled?: boolean` - Disable button (default: false)
169
147
  - `className?: string` - Additional CSS classes
170
148
  - `style?: React.CSSProperties` - Custom inline styles
@@ -247,35 +225,32 @@ type AnchorSize = 'sm' | 'md' | 'lg';
247
225
  ```
248
226
 
249
227
  ### Accordion
250
- A collapsible content component with customizable header and content sections.
228
+ A collapsible content component with customizable header and animation.
251
229
 
252
230
  ```jsx
253
231
  <Accordion
254
- key="accordion-1"
255
- active={isActive}
256
- onClick={() => setIsActive(!isActive)}
257
- header={<h3 className="font-semibold text-gray-800">Accordion Title</h3>}
258
- content={<p className="text-gray-600">Accordion content goes here</p>}
259
- className="border border-gray-200 rounded-lg overflow-hidden"
260
- containerClassName="border border-gray-200 rounded-lg overflow-hidden"
261
- headerClassName="w-full px-4 py-3 text-left bg-gray-50 hover:bg-gray-100 focus:bg-gray-100 focus:outline-none transition-colors duration-200 flex justify-between items-center"
262
- contentClassName="transition-all duration-300 ease-in-out"
263
- {...React.ComponentPropsWithoutRef<'div'>}
264
- />
232
+ title="Click to expand"
233
+ className="custom-class"
234
+ styles={{
235
+ header: { backgroundColor: '#f3f4f6' },
236
+ content: { padding: '1rem' },
237
+ arrow: { color: '#6b7280' },
238
+ container: { marginBottom: '0.5rem' },
239
+ innerContent: { fontSize: '0.875rem' },
240
+ }}
241
+ >
242
+ <p>Accordion content goes here.</p>
243
+ </Accordion>
265
244
  ```
266
245
 
267
246
  **Props:**
268
- - `key: string` - Unique identifier for the accordion
269
- - `active: boolean` - Whether the accordion is expanded
270
- - `onClick: () => void` - Toggle function
271
- - `header: React.ReactNode` - Header content
272
- - `content: React.ReactNode` - Content to show when expanded
273
- - `className?: string` - Additional CSS classes for accordion
274
- - `containerClassName?: string` - CSS classes for accordion container element
275
- - `headerClassName?: string` - CSS classes for accordion header element
276
- - `contentClassName?: string` - CSS classes for accordion content element
277
- - `style?: React.CSSProperties` - Custom inline styles
278
- - `...props`: any - Additional HTML div attributes (spreads all native div props)
247
+ - `title: React.ReactNode` - Header title content
248
+ - `children: React.ReactNode` - Content to show when expanded
249
+ - `defaultActive?: boolean` - Whether expanded by default (default: false)
250
+ - `active?: boolean` - Controlled active state
251
+ - `onClick?: () => void` - Toggle click handler
252
+ - `styles?: Styles<'container' | 'header' | 'content' | 'arrow' | 'innerContent'>` - Custom inline styles per element
253
+ - `className?: string` - Additional CSS classes
279
254
 
280
255
  ### Spinner
281
256
  A loading spinner component with customizable types and animations.
@@ -284,19 +259,17 @@ A loading spinner component with customizable types and animations.
284
259
  <Spinner
285
260
  size="md"
286
261
  type="circle"
287
- className="text-blue-600"
288
- containerClassName="flex justify-center"
289
- dotClassName="w-2 h-2 bg-blue-600 rounded-full"
290
- barClassName="w-1 h-4 bg-blue-600 rounded-full"
291
- style={{ borderRadius: '50%' }}
262
+ color="#2563eb"
263
+ className="custom-class"
264
+ style={{ margin: '1rem' }}
292
265
  />
266
+ ```
267
+
293
268
  **Props:**
294
- - `className?: string` - Additional CSS classes
295
- - `containerClassName?: string` - CSS classes for container element
296
- - `dotClassName?: string` - CSS classes for dot elements
297
- - `barClassName?: string` - CSS classes for bar elements
298
269
  - `size?: SpinnerSize` - Spinner size (default: 'md')
299
270
  - `type?: SpinnerType` - Spinner animation type (default: 'circle')
271
+ - `color?: string` - Spinner color (default: '#2563eb')
272
+ - `className?: string` - Additional CSS classes
300
273
  - `style?: React.CSSProperties` - Custom inline styles
301
274
 
302
275
  **Types:**
@@ -310,36 +283,24 @@ A dropdown menu component with customizable toggle and options.
310
283
 
311
284
  ```jsx
312
285
  <DropDown
313
- toggle={
314
- <button className="bg-gray-100 hover:bg-gray-200 border border-gray-300 rounded px-3 py-2 text-sm">
315
- Menu
316
- </button>
317
- }
318
- options={[
319
- { value: 'option1', label: 'Option 1' },
320
- { value: 'option2', label: 'Option 2' },
321
- { value: 'option3', label: 'Option 3' }
322
- ]}
323
- selected="option1"
324
- onChange={(value) => console.log('Selected:', value)}
325
- className="relative inline-block text-left"
326
- dropdownClassName="absolute top-full left-0 mt-1 w-full bg-white border border-gray-300 rounded shadow-lg z-10"
327
- optionsContainerClassName="py-1"
328
- optionClassName="block px-3 py-2 hover:bg-gray-100 cursor-pointer text-sm"
286
+ options={['Option 1', 'Option 2', 'Option 3']}
287
+ value={selectedOption}
288
+ onChange={setSelectedOption}
289
+ placeholder="Select an option"
290
+ className="custom-dropdown"
329
291
  />
330
292
  ```
331
293
 
332
294
  **Props:**
333
- - `toggle: React.ReactNode` - Toggle button/element
334
- - `options: DropDownOption[]` - Array of option objects with `value` and `label` properties
335
- - `selected: string | number` - Currently selected option value
336
- - `onChange: (value: string | number) => void` - Selection change handler
295
+ - `options: (string | number | DropDownOption)[]` - Array of options
296
+ - `value?: string | number | React.ReactNode` - Currently selected value
297
+ - `onChange: (value: any) => void` - Selection change handler
298
+ - `placeholder?: string` - Placeholder text (default: 'Select an option')
299
+ - `toggle?: React.ReactNode` - Custom toggle element
300
+ - `classNames?: DropDownClassNames` - Custom class names for sub-elements
301
+ - `styles?: DropDownStyles` - Custom inline styles per element
302
+ - `disabled?: boolean` - Disable the dropdown (default: false)
337
303
  - `className?: string` - Additional CSS classes for container
338
- - `containerClassName?: string` - CSS classes for dropdown container element
339
- - `dropdownClassName?: string` - CSS classes for dropdown menu element
340
- - `optionsContainerClassName?: string` - CSS classes for options container element
341
- - `optionClassName?: string` - CSS classes for individual option elements
342
- - `style?: React.CSSProperties` - Custom inline styles
343
304
 
344
305
  **DropDownOption Interface:**
345
306
  ```typescript
@@ -350,29 +311,26 @@ interface DropDownOption {
350
311
  ```
351
312
 
352
313
  ### ProgressBar
353
- A progress bar component with customizable progress values and accessibility.
314
+ A progress bar component with customizable progress values, variants, and accessibility.
354
315
 
355
316
  ```jsx
356
317
  <ProgressBar
357
318
  progress={75}
358
- max={100}
359
- min={0}
360
- aria-label="Loading progress"
361
- className="bg-gray-200 rounded-full h-2"
362
- barClassName="bg-blue-600 h-full rounded-full transition-all duration-300"
319
+ variant="primary"
320
+ showPercentage
321
+ className="custom-class"
363
322
  />
364
323
  ```
365
324
 
366
325
  **Props:**
367
326
  - `progress: number` - Current progress value
368
- - `max: number` - Maximum progress value
369
- - `min: number` - Minimum progress value
370
- - `aria-label: string` - Accessibility label
371
- - `className?: React.CSSProperties` - Custom CSS properties for styling
372
- - `style?: React.CSSProperties` - Additional inline styles
373
- - `containerClassName?: string` - CSS classes for the container element
374
- - `barClassName?: string` - CSS classes for the progress bar element
327
+ - `max?: number` - Maximum progress value (default: 100)
328
+ - `min?: number` - Minimum progress value (default: 0)
375
329
  - `variant?: ProgressBarVariant` - Color variant (default: 'primary')
330
+ - `showPercentage?: boolean` - Show percentage text (default: true)
331
+ - `className?: string` - Additional CSS classes
332
+ - `styles?: { container?: React.CSSProperties; bar?: React.CSSProperties; text?: React.CSSProperties }` - Custom inline styles
333
+ - `aria-label?: string` - Accessibility label
376
334
 
377
335
  **Types:**
378
336
  ```typescript
@@ -390,15 +348,13 @@ A fullscreen overlay preloader component with customizable spinner and auto-hide
390
348
  accentColor="#00ff88"
391
349
  size={90}
392
350
  borderWidth={6}
393
- className="fixed inset-0 z-50"
394
- spinnerClassName="border-4 border-gray-300 border-t-green-400"
395
351
  onComplete={() => setIsLoading(false)}
396
352
  />
397
353
  ```
398
354
 
399
355
  **Props:**
400
356
  - `isLoading?: boolean` - Whether the preloader should be visible (if not provided, uses internal state)
401
- - `duration?: number` - Duration in milliseconds before auto-hide (default: 1000)
357
+ - `duration?: number` - Duration in milliseconds before auto-hide (default: 2000)
402
358
  - `backgroundColor?: string` - Background color of the overlay (default: CSS variable)
403
359
  - `accentColor?: string` - Color of the spinner (default: CSS variable)
404
360
  - `size?: number` - Size of the spinner in pixels (default: 60)
@@ -407,7 +363,7 @@ A fullscreen overlay preloader component with customizable spinner and auto-hide
407
363
  - `spinnerClassName?: string` - Additional CSS classes for the spinner
408
364
  - `zIndex?: number` - Z-index of the overlay (default: 999999)
409
365
  - `onComplete?: () => void` - Callback when preloader finishes
410
- - `style?: React.CSSProperties` - Custom inline styles
366
+ - `styles?: { overlay?: React.CSSProperties; spinner?: React.CSSProperties; }` - Custom inline styles
411
367
 
412
368
  **Usage Modes:**
413
369
  - **Controlled:** Use `isLoading` prop to control visibility externally
@@ -439,108 +395,24 @@ A floating scroll-to-top button that appears when the user scrolls down the page
439
395
  <ScrollTop
440
396
  threshold={200}
441
397
  position="bottom-right"
442
- size="md"
443
- className="bg-blue-600 hover:bg-blue-700 text-white rounded-full shadow-lg"
398
+ className="custom-class"
444
399
  />
445
400
  ```
446
401
 
447
- **💡 Tip for Bootstrap / Existing CSS Frameworks:**
448
- If you are using this library in a project that also uses Bootstrap (or another framework), you may need to explicitly declare all Tailwind positioning and styling classes and mark them with `!` (important) to ensure they have priority over Bootstrap's default styles (which can override border-radius or positioning). For example:
449
-
450
- ```jsx
451
- <ScrollTop
452
- size="sm"
453
- scrollPercentage={5}
454
- className="!bg-indigo-600 hover:!bg-indigo-700 !text-white !rounded-full !z-[9999] !w-10 !h-10 flex items-center justify-center !right-8 !bottom-8 !fixed"
455
- position="bottom-right"
456
- >
457
- <i className="bi bi-arrow-up"></i>
458
- </ScrollTop>
459
- ```
460
-
461
402
  **Props:**
462
- - `threshold?: number` - Scroll position threshold to show the button in pixels (default: 100)
463
- - `className?: string` - Additional CSS classes for the button
464
- - `children?: React.ReactNode` - Custom icon/content for the button (default: arrow up)
465
- - `position?: 'bottom-right' | 'bottom-left' | 'bottom-center' | 'top-right' | 'top-left' | 'top-center'` - Button position (default: 'bottom-right')
466
- - `size?: 'sm' | 'md' | 'lg'` - Button size (default: 'md')
467
- - `shape?: 'circle' | 'square' | 'rounded'` - Button shape (default: 'circle')
468
- - `showInitially?: boolean` - Whether to show the button initially (default: false)
403
+ - `threshold?: number` - Scroll position threshold in pixels (default: 100)
404
+ - `className?: string` - Additional CSS classes
405
+ - `children?: React.ReactNode` - Custom icon/content (default: arrow up SVG)
406
+ - `position?: CornerPosition` - Button position (default: 'bottom-right')
407
+ - `size?: number` - Button size in pixels (default: 48)
469
408
  - `scrollBehavior?: 'auto' | 'smooth'` - Scroll behavior (default: 'smooth')
470
- - `style?: React.CSSProperties` - Custom styles
471
- - `onClick?: () => void` - Callback when button is clicked
472
- - `onVisibilityChange?: (isVisible: boolean) => void` - Callback when visibility changes
473
- - `targetElement?: string` - Element ID or selector to check visibility for showing the button
474
- - `scrollPercentage?: number` - Percentage of page scroll to show the button (0-100)
475
- - `buttonClassName?: string` - CSS classes for the button element
476
- - `containerClassName?: string` - CSS classes for the container element
409
+ - `styles?: React.CSSProperties` - Custom inline styles
477
410
 
478
411
  **Position Options:**
479
412
  - `bottom-right` - Fixed bottom right
480
413
  - `bottom-left` - Fixed bottom left
481
- - `bottom-center` - Fixed bottom center
482
414
  - `top-right` - Fixed top right
483
415
  - `top-left` - Fixed top left
484
- - `top-center` - Fixed top center
485
-
486
- **Size Options:**
487
- - `sm` - Small (32x32px)
488
- - `md` - Medium (48x48px)
489
- - `lg` - Large (64x64px)
490
-
491
- **Shape Options:**
492
- - `circle` - Fully rounded
493
- - `square` - Square corners
494
- - `rounded` - Slightly rounded
495
-
496
- **Examples:**
497
- ```jsx
498
- // Default usage with target element
499
- <ScrollTop targetElement="#default-target" />
500
-
501
- // Custom position and size
502
- <ScrollTop
503
- position="bottom-left"
504
- size="lg"
505
- targetElement="#custom-target"
506
- className="bg-purple-600 hover:bg-purple-700"
507
- />
508
-
509
- // Top position with small size
510
- <ScrollTop
511
- position="top-right"
512
- size="sm"
513
- targetElement="#top-target"
514
- className="bg-green-600 hover:bg-green-700"
515
- />
516
-
517
- // Center position with custom color
518
- <ScrollTop
519
- position="top-center"
520
- size="sm"
521
- targetElement="#center-target"
522
- className="bg-blue-600 hover:bg-blue-700"
523
- />
524
-
525
- // Percentage-based triggering
526
- <ScrollTop
527
- position="bottom-center"
528
- size="lg"
529
- scrollPercentage={99}
530
- className="bg-indigo-600 hover:bg-indigo-700"
531
- >
532
- <span className="text-white font-bold">Top</span>
533
- </ScrollTop>
534
-
535
- // Custom icon with callbacks
536
- <ScrollTop
537
- targetElement="#footer"
538
- onVisibilityChange={(visible) => console.log('Visible:', visible)}
539
- onClick={() => console.log('Scrolled to top!')}
540
- >
541
- <span className="text-white font-bold">↑</span>
542
- </ScrollTop>
543
- ```
544
416
 
545
417
  ### Typed
546
418
  A typing animation component that types and deletes text in sequence.
@@ -551,33 +423,22 @@ A typing animation component that types and deletes text in sequence.
551
423
  typeSpeed={50}
552
424
  backSpeed={30}
553
425
  loop={true}
554
- className="text-blue-600 font-mono text-lg"
555
- containerClassName="inline-block"
556
- typedClassName="border-r-2 border-blue-600"
426
+ className="custom-class"
427
+ style={{ fontSize: '1.25rem' }}
557
428
  />
558
429
  ```
559
430
 
560
431
  **Props:**
561
432
  - `strings: string[]` - Array of strings to type in sequence
562
- - `typeSpeed?: number` - Speed of typing in milliseconds per character (default: 50)
563
- - `backSpeed?: number` - Speed of backspacing in milliseconds per character (default: 30)
564
- - `backDelay?: number` - Delay before backspacing starts in milliseconds (default: 500)
565
- - `startDelay?: number` - Delay before typing starts in milliseconds (default: 0)
566
- - `loop?: boolean` - Whether to loop through strings indefinitely (default: true)
567
- - `showCursor?: boolean` - Whether to show a blinking cursor (default: true)
568
- - `className?: string` - Additional CSS classes for the component
569
- - `containerClassName?: string` - CSS classes for the container element
570
- - `typedClassName?: string` - CSS classes for the typed text
571
- - `cursorClassName?: string` - CSS classes for the cursor
572
- - `style?: TypedStyle` - Custom CSS properties for styling
573
-
574
- **Types:**
575
- ```typescript
576
- type TypedStyle = CSSProperties & {
577
- animation?: string;
578
- animationDelay?: string;
579
- };
580
- ```
433
+ - `typeSpeed?: number` - Typing speed in ms per character (default: 50)
434
+ - `backSpeed?: number` - Backspacing speed in ms per character (default: 30)
435
+ - `backDelay?: number` - Delay before backspacing in ms (default: 500)
436
+ - `startDelay?: number` - Delay before typing starts in ms (default: 0)
437
+ - `loop?: boolean` - Loop through strings (default: true)
438
+ - `showCursor?: boolean` - Show blinking cursor (default: true)
439
+ - `className?: string` - Additional CSS classes
440
+ - `style?: CSSProperties & { animation?: string; animationDelay?: string }` - Custom inline styles
441
+ - `cursorStyle?: React.CSSProperties` - Custom styles for cursor element
581
442
 
582
443
  ### WhatsApp
583
444
  A WhatsApp button component for quick contact integration.
@@ -588,28 +449,21 @@ A WhatsApp button component for quick contact integration.
588
449
  message="Hello! I need help."
589
450
  position="bottom-right"
590
451
  size="md"
591
- className="bg-green-500 hover:bg-green-600 text-white rounded-full shadow-lg"
452
+ className="custom-class"
592
453
  />
593
454
  ```
594
455
 
595
456
  **Props:**
596
- - `phone?: string` - Phone number for WhatsApp (with country code, without + or spaces)
597
- - `message?: string` - Default message to send (default: "¡Hola! Me gustaría obtener más información.")
598
- - `position?: WhatsAppPosition` - Position of the button (default: 'bottom-right')
599
- - `size?: WhatsAppSize` - Size of the button (default: 'md')
457
+ - `phone?: string` - Phone number (with country code, without + or spaces)
458
+ - `message?: string` - Default message (default: 'Hi!')
459
+ - `position?: CornerPosition` - Button position (default: 'bottom-right')
460
+ - `size?: Size` - Button size (default: 'md')
600
461
  - `showTooltip?: boolean` - Show tooltip on hover (default: true)
601
- - `tooltipText?: string` - Tooltip text
602
- - `className?: string` - Additional CSS classes for the button
603
- - `style?: React.CSSProperties` - Custom styles
604
- - `onClick?: () => void` - Callback when button is clicked
605
- - `zIndex?: number` - Z-index for the button
606
- - `openInNewTab?: boolean` - Whether to open in new tab (default: true)
607
-
608
- **Types:**
609
- ```typescript
610
- type WhatsAppPosition = 'bottom-right' | 'bottom-left' | 'bottom-center' | 'top-right' | 'top-left' | 'top-center';
611
- type WhatsAppSize = 'sm' | 'md' | 'lg';
612
- ```
462
+ - `tooltipText?: string` - Tooltip text (default: 'Need help?')
463
+ - `className?: string` - Additional CSS classes
464
+ - `styles?: { button?: React.CSSProperties; tooltip?: React.CSSProperties }` - Custom inline styles
465
+ - `onClick?: () => void` - Click callback
466
+ - `zIndex?: number` - Z-index (default: 1000)
613
467
 
614
468
  ### Modal
615
469
  A flexible modal component for displaying dialogs, forms, and overlays.
@@ -652,13 +506,14 @@ A flexible modal component for displaying dialogs, forms, and overlays.
652
506
  - `footer?: React.ReactNode` - Custom footer content
653
507
  - `closeButton?: boolean` - Whether to show close button (default: true)
654
508
  - `className?: string` - Additional CSS classes for the modal
655
- - `dialogClassName?: string` - CSS classes for the modal dialog
656
- - `contentClassName?: string` - CSS classes for the modal content
657
- - `headerClassName?: string` - CSS classes for the modal header
658
- - `bodyClassName?: string` - CSS classes for the modal body
659
- - `footerClassName?: string` - CSS classes for the modal footer
509
+ - `dialogClassName?: string` - CSS classes for the modal dialog (default: 'luna-modal-dialog')
510
+ - `contentClassName?: string` - CSS classes for the modal content (default: 'luna-modal-content')
511
+ - `headerClassName?: string` - CSS classes for the modal header (default: 'luna-modal-header')
512
+ - `bodyClassName?: string` - CSS classes for the modal body (default: 'luna-modal-body')
513
+ - `footerClassName?: string` - CSS classes for the modal footer (default: 'luna-modal-footer')
660
514
  - `style?: React.CSSProperties` - Custom inline styles
661
515
 
516
+
662
517
  **Types:**
663
518
  ```typescript
664
519
  type ModalSize = 'sm' | 'md' | 'lg' | 'xl';
@@ -771,7 +626,7 @@ const MyComponent = () => {
771
626
  ```
772
627
 
773
628
  ### Input
774
- A versatile input component with multiple variants, sizes, and types.
629
+ A versatile input component with multiple variants, sizes, masks, currency formatting, and types.
775
630
 
776
631
  ```jsx
777
632
  <Input
@@ -781,8 +636,11 @@ A versatile input component with multiple variants, sizes, and types.
781
636
  placeholder="Enter your text here"
782
637
  value={inputValue}
783
638
  onChange={(value) => setInputValue(value)}
784
- className="border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500"
785
- />
639
+ className="custom-class"
640
+ id="my-input"
641
+ >
642
+ Input Label
643
+ </Input>
786
644
  ```
787
645
 
788
646
  **Props:**
@@ -799,15 +657,21 @@ A versatile input component with multiple variants, sizes, and types.
799
657
  - `required?: boolean` - Required field (default: false)
800
658
  - `readOnly?: boolean` - Read-only input (default: false)
801
659
  - `className?: string` - Additional CSS classes
802
- - `containerClassName?: string` - CSS classes for container element
803
- - `inputClassName?: string` - CSS classes for input element
804
- - `variantClassName?: string` - CSS classes for variant styling
805
- - `sizeClassName?: string` - CSS classes for size styling
806
660
  - `style?: React.CSSProperties` - Custom inline styles
807
661
  - `id?: string` - HTML id attribute for label association
662
+ - `name?: string` - HTML name attribute
663
+ - `classNames?: InputClassNames` - Custom class names for sub-elements
664
+ - `styles?: InputStyles` - Custom inline styles per element
665
+ - `mask?: string` - Input mask pattern (e.g. "(999) 999-9999")
666
+ - `maskChar?: string` - Mask placeholder character (default: '_')
667
+ - `useCurrency?: boolean` - Enable currency formatting
668
+ - `currency?: string` - Currency code (e.g. "USD", "CRC")
669
+ - `locale?: string` - Locale for formatting (e.g. "en-US", "es-CR")
670
+ - `minFractionDigits?: number` - Minimum fraction digits (default: 0)
671
+ - `maxFractionDigits?: number` - Maximum fraction digits (default: 2)
808
672
  - `aria-label?: string` - ARIA label for accessibility
809
- - `aria-labelledby?: string` - ARIA labelledby for accessibility
810
- - `...props`: any - Additional HTML input attributes (spreads all native input props)
673
+ - `aria-labelledby?: string` - ARIA labelledby
674
+ - `...props`: any - Additional HTML input attributes
811
675
 
812
676
  **Types:**
813
677
  ```typescript
@@ -818,17 +682,85 @@ type InputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'sea
818
682
 
819
683
  **Variants:**
820
684
  - `none` - Default styling with border
821
- - `primary` - Blue background with white text
822
- - `secondary` - Gray background with white text
823
- - `outline` - Border only with gray text
824
- - `danger` - Red background with white text
825
- - `success` - Green background with white text
685
+ - `primary` - Blue focus ring
686
+ - `secondary` - Gray focus ring
687
+ - `outline` - Border only
688
+ - `danger` - Red focus ring
689
+ - `success` - Green focus ring
826
690
 
827
691
  **Size Options:**
828
692
  - `sm` - Small padding and text
829
693
  - `md` - Medium padding and text
830
694
  - `lg` - Large padding and text
831
695
  - `xl` - Extra large padding and text
696
+ ### DataTable
697
+ A powerful and customizable data grid with support for filtering, sorting, pagination, selection, and search.
698
+
699
+ ```jsx
700
+ <DataTable
701
+ columns={[
702
+ { key: 'name', label: 'Name', sortable: true, filterable: true },
703
+ { key: 'email', label: 'Email' },
704
+ {
705
+ key: 'status',
706
+ label: 'Status',
707
+ filterable: true,
708
+ filterOptions: [
709
+ { label: 'Active', value: 'Active' },
710
+ { label: 'Inactive', value: 'Inactive' }
711
+ ],
712
+ render: (val) => <span className={val === 'Active' ? 'text-green-600' : 'text-red-600'}>{val}</span>
713
+ },
714
+ {
715
+ key: 'actions',
716
+ label: 'Actions',
717
+ render: (_, row) => (
718
+ <Button size="sm" variant="outline" onClick={() => handleEdit(row)}>
719
+ Edit
720
+ </Button>
721
+ )
722
+ }
723
+ ]}
724
+ data={myData}
725
+ pagination
726
+ pageSize={5}
727
+ selectable
728
+ searchable
729
+ onRowClick={(row) => console.log('Clicked:', row)}
730
+ onSelectionChange={(selectedRows) => console.log('Selected:', selectedRows)}
731
+ className="custom-datatable"
732
+ />
733
+ ```
734
+
735
+ **Props:**
736
+ - `columns: DataTableColumn[]` - Array of column definitions
737
+ - `data: any[]` - Array of data objects
738
+ - `pagination?: boolean` - Enable pagination (default: false)
739
+ - `pageSize?: number` - Rows per page (default: 10)
740
+ - `selectable?: boolean` - Show selection checkboxes (default: false)
741
+ - `searchable?: boolean` - Show search filter (default: false)
742
+ - `onSelectionChange?: (selectedRows: any[]) => void` - Selection change handler
743
+ - `onRowClick?: (row: any) => void` - Row click handler
744
+ - `onRowDoubleClick?: (row: any) => void` - Row double click handler
745
+ - `texts?: DataTableTexts` - Custom text labels for i18n
746
+ - `classNames?: DataTableClassNames` - Custom class names per element
747
+ - `styles?: DataTableStyles` - Custom inline styles per element
748
+ - `className?: string` - Additional CSS classes
749
+
750
+ **Column Interface:**
751
+ ```typescript
752
+ interface DataTableColumn {
753
+ key: string;
754
+ label: React.ReactNode;
755
+ sortable?: boolean;
756
+ filterable?: boolean;
757
+ filterOptions?: { label: string; value: any }[];
758
+ render?: (value: any, row: any) => React.ReactNode;
759
+ }
760
+ ```
761
+
762
+
763
+
832
764
 
833
765
 
834
766
  ## 🛠️ Utilities & Hooks
@@ -1007,8 +939,12 @@ luna-library/
1007
939
  │ │ ├── utilExamples/ # Examples for hooks and extra utilities
1008
940
  │ │ ├── Button.tsx
1009
941
  │ │ ├── Card.tsx
942
+ │ │ ├── DataTable.tsx
1010
943
  │ │ ├── ... (Other UI Components)
944
+
1011
945
  │ │ └── index.ts
946
+ │ ├── styles.ts # Design tokens and shared style functions
947
+ │ ├── types.ts # Shared TypeScript types
1012
948
  │ ├── hooks/
1013
949
  │ │ ├── useFetch.hook.ts
1014
950
  │ │ ├── useLocalStorage.hook.ts
@@ -1088,7 +1024,9 @@ The library is configured with:
1088
1024
  - `rimraf` - Cross-platform file removal
1089
1025
 
1090
1026
  ### Styling
1091
- This library is built with **Tailwind CSS** utility classes. Components use predefined Tailwind classes for consistent styling and are fully customizable through the `className` prop.
1027
+ This library uses a **pure inline-style architecture** with a centralized design system. All design tokens (`colors`, `radii`, `fontSizes`, `shadows`, `transitions`, etc.) and shared style objects (`commonStyles`, `variantStyles`, `sizeStyles`) are defined in `src/styles.ts`. Components consume these tokens and generate inline styles, class name strings, or both depending on the component.
1028
+
1029
+ **No CSS framework required** - you don't need Tailwind CSS, PostCSS, or any other styling tool to use this library. Each component accepts `className` (for CSS classes) and `style` (for inline style overrides) props for customization.
1092
1030
 
1093
1031
  ## 🤝 Contributing
1094
1032