luna-components-library 1.1.34 → 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 +280 -328
- package/dist/luna-components-library.js +2070 -471
- package/dist/luna-components-library.js.map +1 -1
- package/dist/src/components/Accordion.d.ts +9 -9
- package/dist/src/components/Anchor.d.ts +4 -6
- package/dist/src/components/Button.d.ts +8 -7
- package/dist/src/components/Card.d.ts +10 -7
- package/dist/src/components/DataTable.d.ts +40 -0
- package/dist/src/components/DropDown.d.ts +14 -12
- package/dist/src/components/Input.d.ts +20 -11
- package/dist/src/components/Modal.d.ts +1 -1
- package/dist/src/components/MultiSelect.d.ts +26 -0
- package/dist/src/components/Popconfirm.d.ts +20 -0
- package/dist/src/components/Preloader.d.ts +6 -3
- package/dist/src/components/ProgressBar.d.ts +21 -11
- package/dist/src/components/QRCode.d.ts +16 -0
- package/dist/src/components/ScrollTop.d.ts +5 -23
- package/dist/src/components/Spinner.d.ts +4 -5
- package/dist/src/components/Toast.d.ts +17 -0
- package/dist/src/components/Typed.d.ts +2 -4
- package/dist/src/components/WhatsApp.d.ts +9 -9
- package/dist/src/components/index.d.ts +5 -0
- package/dist/src/demo.d.ts +1 -2
- package/dist/src/styles.d.ts +259 -0
- package/dist/src/types.d.ts +23 -0
- package/dist/src/utilities/logger.util.d.ts +3 -0
- package/package.json +1 -1
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
|
-
- 🎯 **
|
|
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,126 +24,102 @@ yarn add luna-components-library
|
|
|
22
24
|
pnpm add luna-components-library
|
|
23
25
|
```
|
|
24
26
|
|
|
25
|
-
|
|
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,
|
|
52
|
-
|
|
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() {
|
|
40
|
+
const [showModal, setShowModal] = useState(false);
|
|
41
|
+
|
|
57
42
|
return (
|
|
58
|
-
<div
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
</Button>
|
|
67
|
-
|
|
68
|
-
<Card
|
|
69
|
-
title="Example Card"
|
|
70
|
-
padding="md"
|
|
71
|
-
shadow="lg"
|
|
72
|
-
className="max-w-md bg-white border border-gray-200 rounded-lg shadow-lg"
|
|
73
|
-
>
|
|
74
|
-
<p className="text-gray-700">This is a card component from Luna Components Library.</p>
|
|
75
|
-
<Button variant="outline" size="sm" className="mt-2 border border-gray-300 hover:border-gray-400">
|
|
76
|
-
Learn More
|
|
43
|
+
<div style={{ padding: '2rem', display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>
|
|
44
|
+
{/* 1. Basic Components */}
|
|
45
|
+
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '1rem' }}>
|
|
46
|
+
<Button
|
|
47
|
+
variant="primary"
|
|
48
|
+
onClick={() => setShowModal(true)}
|
|
49
|
+
>
|
|
50
|
+
Open Modal
|
|
77
51
|
</Button>
|
|
78
|
-
|
|
52
|
+
|
|
53
|
+
<Input
|
|
54
|
+
placeholder="Type something..."
|
|
55
|
+
/>
|
|
56
|
+
</div>
|
|
79
57
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
</
|
|
58
|
+
{/* 2. Content Display */}
|
|
59
|
+
<Card title="Luna Library" padding="md" shadow="sm">
|
|
60
|
+
<Typed
|
|
61
|
+
strings={['Modern React Components', 'TypeScript Ready', 'Zero Dependencies']}
|
|
62
|
+
/>
|
|
63
|
+
<p style={{ marginTop: '0.5rem' }}>Building fast and beautiful interfaces.</p>
|
|
64
|
+
</Card>
|
|
87
65
|
|
|
66
|
+
{/* 3. Interactive Elements */}
|
|
88
67
|
<Accordion
|
|
89
|
-
|
|
90
|
-
active={false}
|
|
91
|
-
onClick={() => console.log('Toggle')}
|
|
92
|
-
header={<h3 className="font-semibold text-gray-800">Click to expand</h3>}
|
|
93
|
-
content={<p className="text-gray-600">This is accordion content!</p>}
|
|
94
|
-
className="border border-gray-200 rounded-lg overflow-hidden"
|
|
95
|
-
/>
|
|
96
|
-
|
|
97
|
-
<Spinner
|
|
98
|
-
size="md"
|
|
99
|
-
type="circle"
|
|
100
|
-
className="text-blue-600"
|
|
101
|
-
/>
|
|
102
|
-
|
|
103
|
-
<DropDown
|
|
104
|
-
toggle={
|
|
105
|
-
<button className="bg-gray-100 hover:bg-gray-200 border border-gray-300 rounded px-3 py-2 text-sm">
|
|
106
|
-
Select Option
|
|
107
|
-
</button>
|
|
108
|
-
}
|
|
109
|
-
options={[
|
|
110
|
-
{ value: 'option1', label: 'Option 1' },
|
|
111
|
-
{ value: 'option2', label: 'Option 2' },
|
|
112
|
-
{ value: 'option3', label: 'Option 3' }
|
|
113
|
-
]}
|
|
114
|
-
selected="option1"
|
|
115
|
-
onChange={(value) => console.log('Selected:', value)}
|
|
116
|
-
/>
|
|
117
|
-
|
|
118
|
-
<Modal
|
|
119
|
-
show={true}
|
|
120
|
-
onHide={() => console.log('Modal closed')}
|
|
121
|
-
title="Modal Title"
|
|
122
|
-
className="bg-white rounded-lg shadow-xl"
|
|
68
|
+
title="Click to expand"
|
|
123
69
|
>
|
|
124
|
-
<p
|
|
70
|
+
<p>This is the accordion content!</p>
|
|
71
|
+
</Accordion>
|
|
72
|
+
|
|
73
|
+
{/* 4. Feedback & Progress */}
|
|
74
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
|
|
75
|
+
<p>Loading Progress:</p>
|
|
76
|
+
<ProgressBar progress={75} />
|
|
77
|
+
<Spinner size="sm" type="dots" />
|
|
78
|
+
</div>
|
|
79
|
+
|
|
80
|
+
{/* 5. Communication & Navigation */}
|
|
81
|
+
<div style={{ display: 'flex', gap: '1rem' }}>
|
|
82
|
+
<WhatsApp phone="123456789" message="Hello!" />
|
|
83
|
+
<Anchor href="https://github.com" variant="outline">GitHub Repo</Anchor>
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
{/* 6. Overlays (Modals & Preloaders) */}
|
|
87
|
+
<Modal isOpen={showModal} onClose={() => setShowModal(false)} title="Quick Start Modal">
|
|
88
|
+
<p>This is a modal from the library!</p>
|
|
125
89
|
</Modal>
|
|
126
90
|
|
|
127
|
-
<
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
size="md"
|
|
131
|
-
className="bg-blue-600 hover:bg-blue-700 text-white rounded-full shadow-lg"
|
|
132
|
-
/>
|
|
133
|
-
|
|
134
|
-
<Input
|
|
135
|
-
inputSize="md"
|
|
136
|
-
variant="primary"
|
|
137
|
-
placeholder="Enter your text here"
|
|
138
|
-
className="border border-gray-300 rounded-md shadow-sm focus:ring-blue-500 focus:border-blue-500"
|
|
139
|
-
/>
|
|
91
|
+
<Preloader isLoading={isLoading} duration={2000} onComplete={() => setIsLoading(false)} />
|
|
92
|
+
|
|
93
|
+
<ScrollTop />
|
|
140
94
|
</div>
|
|
141
95
|
);
|
|
142
96
|
}
|
|
143
97
|
```
|
|
144
98
|
|
|
99
|
+
### ⚓ Hooks & Utilities Quick Start
|
|
100
|
+
|
|
101
|
+
Luna Library also provides powerful hooks and utilities for common tasks:
|
|
102
|
+
|
|
103
|
+
```javascript
|
|
104
|
+
import { useFetch, useLocalStorage, httpClient, formatters, validators } from 'luna-components-library';
|
|
105
|
+
|
|
106
|
+
// 1. Data Fetching Hook
|
|
107
|
+
const { data, loading, error } = useFetch('https://api.example.com/data');
|
|
108
|
+
|
|
109
|
+
// 2. Direct HTTP Client
|
|
110
|
+
const postData = async () => {
|
|
111
|
+
const result = await httpClient.post('/api/users', { name: 'New User' });
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
// 3. Local Storage Management
|
|
115
|
+
const [theme, setTheme] = useLocalStorage('app-theme', 'light');
|
|
116
|
+
|
|
117
|
+
// 4. Practical Utilities
|
|
118
|
+
const price = formatters.currency(1200.50); // "$1,200.50"
|
|
119
|
+
const isValid = validators.isEmail('user@luna.com'); // true
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
|
|
145
123
|
## 🧩 Components
|
|
146
124
|
|
|
147
125
|
All components use TypeScript with specific types for better type safety and IntelliSense. The library follows a minimal documentation approach with descriptive type names instead of extensive JSDoc comments.
|
|
@@ -155,7 +133,6 @@ A versatile button component with multiple variants and sizes.
|
|
|
155
133
|
size="md"
|
|
156
134
|
onClick={handleClick}
|
|
157
135
|
disabled={false}
|
|
158
|
-
className="bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-lg transition-colors duration-200"
|
|
159
136
|
>
|
|
160
137
|
Button Text
|
|
161
138
|
</Button>
|
|
@@ -165,7 +142,7 @@ A versatile button component with multiple variants and sizes.
|
|
|
165
142
|
- `children`: React.ReactNode - Button content
|
|
166
143
|
- `variant?: ButtonVariant` - Button style (default: 'primary')
|
|
167
144
|
- `size?: ButtonSize` - Button size (default: 'md')
|
|
168
|
-
- `onClick?:
|
|
145
|
+
- `onClick?: React.MouseEventHandler<HTMLButtonElement>` - Click handler
|
|
169
146
|
- `disabled?: boolean` - Disable button (default: false)
|
|
170
147
|
- `className?: string` - Additional CSS classes
|
|
171
148
|
- `style?: React.CSSProperties` - Custom inline styles
|
|
@@ -248,35 +225,32 @@ type AnchorSize = 'sm' | 'md' | 'lg';
|
|
|
248
225
|
```
|
|
249
226
|
|
|
250
227
|
### Accordion
|
|
251
|
-
A collapsible content component with customizable header and
|
|
228
|
+
A collapsible content component with customizable header and animation.
|
|
252
229
|
|
|
253
230
|
```jsx
|
|
254
231
|
<Accordion
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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>
|
|
266
244
|
```
|
|
267
245
|
|
|
268
246
|
**Props:**
|
|
269
|
-
- `
|
|
270
|
-
- `
|
|
271
|
-
- `
|
|
272
|
-
- `
|
|
273
|
-
- `
|
|
274
|
-
- `
|
|
275
|
-
- `
|
|
276
|
-
- `headerClassName?: string` - CSS classes for accordion header element
|
|
277
|
-
- `contentClassName?: string` - CSS classes for accordion content element
|
|
278
|
-
- `style?: React.CSSProperties` - Custom inline styles
|
|
279
|
-
- `...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
|
|
280
254
|
|
|
281
255
|
### Spinner
|
|
282
256
|
A loading spinner component with customizable types and animations.
|
|
@@ -285,19 +259,17 @@ A loading spinner component with customizable types and animations.
|
|
|
285
259
|
<Spinner
|
|
286
260
|
size="md"
|
|
287
261
|
type="circle"
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
barClassName="w-1 h-4 bg-blue-600 rounded-full"
|
|
292
|
-
style={{ borderRadius: '50%' }}
|
|
262
|
+
color="#2563eb"
|
|
263
|
+
className="custom-class"
|
|
264
|
+
style={{ margin: '1rem' }}
|
|
293
265
|
/>
|
|
266
|
+
```
|
|
267
|
+
|
|
294
268
|
**Props:**
|
|
295
|
-
- `className?: string` - Additional CSS classes
|
|
296
|
-
- `containerClassName?: string` - CSS classes for container element
|
|
297
|
-
- `dotClassName?: string` - CSS classes for dot elements
|
|
298
|
-
- `barClassName?: string` - CSS classes for bar elements
|
|
299
269
|
- `size?: SpinnerSize` - Spinner size (default: 'md')
|
|
300
270
|
- `type?: SpinnerType` - Spinner animation type (default: 'circle')
|
|
271
|
+
- `color?: string` - Spinner color (default: '#2563eb')
|
|
272
|
+
- `className?: string` - Additional CSS classes
|
|
301
273
|
- `style?: React.CSSProperties` - Custom inline styles
|
|
302
274
|
|
|
303
275
|
**Types:**
|
|
@@ -311,36 +283,24 @@ A dropdown menu component with customizable toggle and options.
|
|
|
311
283
|
|
|
312
284
|
```jsx
|
|
313
285
|
<DropDown
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
options={[
|
|
320
|
-
{ value: 'option1', label: 'Option 1' },
|
|
321
|
-
{ value: 'option2', label: 'Option 2' },
|
|
322
|
-
{ value: 'option3', label: 'Option 3' }
|
|
323
|
-
]}
|
|
324
|
-
selected="option1"
|
|
325
|
-
onChange={(value) => console.log('Selected:', value)}
|
|
326
|
-
className="relative inline-block text-left"
|
|
327
|
-
dropdownClassName="absolute top-full left-0 mt-1 w-full bg-white border border-gray-300 rounded shadow-lg z-10"
|
|
328
|
-
optionsContainerClassName="py-1"
|
|
329
|
-
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"
|
|
330
291
|
/>
|
|
331
292
|
```
|
|
332
293
|
|
|
333
294
|
**Props:**
|
|
334
|
-
- `
|
|
335
|
-
- `
|
|
336
|
-
- `
|
|
337
|
-
- `
|
|
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)
|
|
338
303
|
- `className?: string` - Additional CSS classes for container
|
|
339
|
-
- `containerClassName?: string` - CSS classes for dropdown container element
|
|
340
|
-
- `dropdownClassName?: string` - CSS classes for dropdown menu element
|
|
341
|
-
- `optionsContainerClassName?: string` - CSS classes for options container element
|
|
342
|
-
- `optionClassName?: string` - CSS classes for individual option elements
|
|
343
|
-
- `style?: React.CSSProperties` - Custom inline styles
|
|
344
304
|
|
|
345
305
|
**DropDownOption Interface:**
|
|
346
306
|
```typescript
|
|
@@ -351,29 +311,26 @@ interface DropDownOption {
|
|
|
351
311
|
```
|
|
352
312
|
|
|
353
313
|
### ProgressBar
|
|
354
|
-
A progress bar component with customizable progress values and accessibility.
|
|
314
|
+
A progress bar component with customizable progress values, variants, and accessibility.
|
|
355
315
|
|
|
356
316
|
```jsx
|
|
357
317
|
<ProgressBar
|
|
358
318
|
progress={75}
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
className="bg-gray-200 rounded-full h-2"
|
|
363
|
-
barClassName="bg-blue-600 h-full rounded-full transition-all duration-300"
|
|
319
|
+
variant="primary"
|
|
320
|
+
showPercentage
|
|
321
|
+
className="custom-class"
|
|
364
322
|
/>
|
|
365
323
|
```
|
|
366
324
|
|
|
367
325
|
**Props:**
|
|
368
326
|
- `progress: number` - Current progress value
|
|
369
|
-
- `max
|
|
370
|
-
- `min
|
|
371
|
-
- `aria-label: string` - Accessibility label
|
|
372
|
-
- `className?: React.CSSProperties` - Custom CSS properties for styling
|
|
373
|
-
- `style?: React.CSSProperties` - Additional inline styles
|
|
374
|
-
- `containerClassName?: string` - CSS classes for the container element
|
|
375
|
-
- `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)
|
|
376
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
|
|
377
334
|
|
|
378
335
|
**Types:**
|
|
379
336
|
```typescript
|
|
@@ -391,15 +348,13 @@ A fullscreen overlay preloader component with customizable spinner and auto-hide
|
|
|
391
348
|
accentColor="#00ff88"
|
|
392
349
|
size={90}
|
|
393
350
|
borderWidth={6}
|
|
394
|
-
className="fixed inset-0 z-50"
|
|
395
|
-
spinnerClassName="border-4 border-gray-300 border-t-green-400"
|
|
396
351
|
onComplete={() => setIsLoading(false)}
|
|
397
352
|
/>
|
|
398
353
|
```
|
|
399
354
|
|
|
400
355
|
**Props:**
|
|
401
356
|
- `isLoading?: boolean` - Whether the preloader should be visible (if not provided, uses internal state)
|
|
402
|
-
- `duration?: number` - Duration in milliseconds before auto-hide (default:
|
|
357
|
+
- `duration?: number` - Duration in milliseconds before auto-hide (default: 2000)
|
|
403
358
|
- `backgroundColor?: string` - Background color of the overlay (default: CSS variable)
|
|
404
359
|
- `accentColor?: string` - Color of the spinner (default: CSS variable)
|
|
405
360
|
- `size?: number` - Size of the spinner in pixels (default: 60)
|
|
@@ -408,7 +363,7 @@ A fullscreen overlay preloader component with customizable spinner and auto-hide
|
|
|
408
363
|
- `spinnerClassName?: string` - Additional CSS classes for the spinner
|
|
409
364
|
- `zIndex?: number` - Z-index of the overlay (default: 999999)
|
|
410
365
|
- `onComplete?: () => void` - Callback when preloader finishes
|
|
411
|
-
- `
|
|
366
|
+
- `styles?: { overlay?: React.CSSProperties; spinner?: React.CSSProperties; }` - Custom inline styles
|
|
412
367
|
|
|
413
368
|
**Usage Modes:**
|
|
414
369
|
- **Controlled:** Use `isLoading` prop to control visibility externally
|
|
@@ -440,108 +395,24 @@ A floating scroll-to-top button that appears when the user scrolls down the page
|
|
|
440
395
|
<ScrollTop
|
|
441
396
|
threshold={200}
|
|
442
397
|
position="bottom-right"
|
|
443
|
-
|
|
444
|
-
className="bg-blue-600 hover:bg-blue-700 text-white rounded-full shadow-lg"
|
|
398
|
+
className="custom-class"
|
|
445
399
|
/>
|
|
446
400
|
```
|
|
447
401
|
|
|
448
|
-
**💡 Tip for Bootstrap / Existing CSS Frameworks:**
|
|
449
|
-
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:
|
|
450
|
-
|
|
451
|
-
```jsx
|
|
452
|
-
<ScrollTop
|
|
453
|
-
size="sm"
|
|
454
|
-
scrollPercentage={5}
|
|
455
|
-
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"
|
|
456
|
-
position="bottom-right"
|
|
457
|
-
>
|
|
458
|
-
<i className="bi bi-arrow-up"></i>
|
|
459
|
-
</ScrollTop>
|
|
460
|
-
```
|
|
461
|
-
|
|
462
402
|
**Props:**
|
|
463
|
-
- `threshold?: number` - Scroll position threshold
|
|
464
|
-
- `className?: string` - Additional CSS classes
|
|
465
|
-
- `children?: React.ReactNode` - Custom icon/content
|
|
466
|
-
- `position?:
|
|
467
|
-
- `size?:
|
|
468
|
-
- `shape?: 'circle' | 'square' | 'rounded'` - Button shape (default: 'circle')
|
|
469
|
-
- `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)
|
|
470
408
|
- `scrollBehavior?: 'auto' | 'smooth'` - Scroll behavior (default: 'smooth')
|
|
471
|
-
- `
|
|
472
|
-
- `onClick?: () => void` - Callback when button is clicked
|
|
473
|
-
- `onVisibilityChange?: (isVisible: boolean) => void` - Callback when visibility changes
|
|
474
|
-
- `targetElement?: string` - Element ID or selector to check visibility for showing the button
|
|
475
|
-
- `scrollPercentage?: number` - Percentage of page scroll to show the button (0-100)
|
|
476
|
-
- `buttonClassName?: string` - CSS classes for the button element
|
|
477
|
-
- `containerClassName?: string` - CSS classes for the container element
|
|
409
|
+
- `styles?: React.CSSProperties` - Custom inline styles
|
|
478
410
|
|
|
479
411
|
**Position Options:**
|
|
480
412
|
- `bottom-right` - Fixed bottom right
|
|
481
413
|
- `bottom-left` - Fixed bottom left
|
|
482
|
-
- `bottom-center` - Fixed bottom center
|
|
483
414
|
- `top-right` - Fixed top right
|
|
484
415
|
- `top-left` - Fixed top left
|
|
485
|
-
- `top-center` - Fixed top center
|
|
486
|
-
|
|
487
|
-
**Size Options:**
|
|
488
|
-
- `sm` - Small (32x32px)
|
|
489
|
-
- `md` - Medium (48x48px)
|
|
490
|
-
- `lg` - Large (64x64px)
|
|
491
|
-
|
|
492
|
-
**Shape Options:**
|
|
493
|
-
- `circle` - Fully rounded
|
|
494
|
-
- `square` - Square corners
|
|
495
|
-
- `rounded` - Slightly rounded
|
|
496
|
-
|
|
497
|
-
**Examples:**
|
|
498
|
-
```jsx
|
|
499
|
-
// Default usage with target element
|
|
500
|
-
<ScrollTop targetElement="#default-target" />
|
|
501
|
-
|
|
502
|
-
// Custom position and size
|
|
503
|
-
<ScrollTop
|
|
504
|
-
position="bottom-left"
|
|
505
|
-
size="lg"
|
|
506
|
-
targetElement="#custom-target"
|
|
507
|
-
className="bg-purple-600 hover:bg-purple-700"
|
|
508
|
-
/>
|
|
509
|
-
|
|
510
|
-
// Top position with small size
|
|
511
|
-
<ScrollTop
|
|
512
|
-
position="top-right"
|
|
513
|
-
size="sm"
|
|
514
|
-
targetElement="#top-target"
|
|
515
|
-
className="bg-green-600 hover:bg-green-700"
|
|
516
|
-
/>
|
|
517
|
-
|
|
518
|
-
// Center position with custom color
|
|
519
|
-
<ScrollTop
|
|
520
|
-
position="top-center"
|
|
521
|
-
size="sm"
|
|
522
|
-
targetElement="#center-target"
|
|
523
|
-
className="bg-blue-600 hover:bg-blue-700"
|
|
524
|
-
/>
|
|
525
|
-
|
|
526
|
-
// Percentage-based triggering
|
|
527
|
-
<ScrollTop
|
|
528
|
-
position="bottom-center"
|
|
529
|
-
size="lg"
|
|
530
|
-
scrollPercentage={99}
|
|
531
|
-
className="bg-indigo-600 hover:bg-indigo-700"
|
|
532
|
-
>
|
|
533
|
-
<span className="text-white font-bold">Top</span>
|
|
534
|
-
</ScrollTop>
|
|
535
|
-
|
|
536
|
-
// Custom icon with callbacks
|
|
537
|
-
<ScrollTop
|
|
538
|
-
targetElement="#footer"
|
|
539
|
-
onVisibilityChange={(visible) => console.log('Visible:', visible)}
|
|
540
|
-
onClick={() => console.log('Scrolled to top!')}
|
|
541
|
-
>
|
|
542
|
-
<span className="text-white font-bold">↑</span>
|
|
543
|
-
</ScrollTop>
|
|
544
|
-
```
|
|
545
416
|
|
|
546
417
|
### Typed
|
|
547
418
|
A typing animation component that types and deletes text in sequence.
|
|
@@ -552,33 +423,22 @@ A typing animation component that types and deletes text in sequence.
|
|
|
552
423
|
typeSpeed={50}
|
|
553
424
|
backSpeed={30}
|
|
554
425
|
loop={true}
|
|
555
|
-
className="
|
|
556
|
-
|
|
557
|
-
typedClassName="border-r-2 border-blue-600"
|
|
426
|
+
className="custom-class"
|
|
427
|
+
style={{ fontSize: '1.25rem' }}
|
|
558
428
|
/>
|
|
559
429
|
```
|
|
560
430
|
|
|
561
431
|
**Props:**
|
|
562
432
|
- `strings: string[]` - Array of strings to type in sequence
|
|
563
|
-
- `typeSpeed?: number` -
|
|
564
|
-
- `backSpeed?: number` -
|
|
565
|
-
- `backDelay?: number` - Delay before backspacing
|
|
566
|
-
- `startDelay?: number` - Delay before typing starts in
|
|
567
|
-
- `loop?: boolean` -
|
|
568
|
-
- `showCursor?: boolean` -
|
|
569
|
-
- `className?: string` - Additional CSS classes
|
|
570
|
-
- `
|
|
571
|
-
- `
|
|
572
|
-
- `cursorClassName?: string` - CSS classes for the cursor
|
|
573
|
-
- `style?: TypedStyle` - Custom CSS properties for styling
|
|
574
|
-
|
|
575
|
-
**Types:**
|
|
576
|
-
```typescript
|
|
577
|
-
type TypedStyle = CSSProperties & {
|
|
578
|
-
animation?: string;
|
|
579
|
-
animationDelay?: string;
|
|
580
|
-
};
|
|
581
|
-
```
|
|
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
|
|
582
442
|
|
|
583
443
|
### WhatsApp
|
|
584
444
|
A WhatsApp button component for quick contact integration.
|
|
@@ -589,28 +449,21 @@ A WhatsApp button component for quick contact integration.
|
|
|
589
449
|
message="Hello! I need help."
|
|
590
450
|
position="bottom-right"
|
|
591
451
|
size="md"
|
|
592
|
-
className="
|
|
452
|
+
className="custom-class"
|
|
593
453
|
/>
|
|
594
454
|
```
|
|
595
455
|
|
|
596
456
|
**Props:**
|
|
597
|
-
- `phone?: string` - Phone number
|
|
598
|
-
- `message?: string` - Default message
|
|
599
|
-
- `position?:
|
|
600
|
-
- `size?:
|
|
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')
|
|
601
461
|
- `showTooltip?: boolean` - Show tooltip on hover (default: true)
|
|
602
|
-
- `tooltipText?: string` - Tooltip text
|
|
603
|
-
- `className?: string` - Additional CSS classes
|
|
604
|
-
- `
|
|
605
|
-
- `onClick?: () => void` -
|
|
606
|
-
- `zIndex?: number` - Z-index
|
|
607
|
-
- `openInNewTab?: boolean` - Whether to open in new tab (default: true)
|
|
608
|
-
|
|
609
|
-
**Types:**
|
|
610
|
-
```typescript
|
|
611
|
-
type WhatsAppPosition = 'bottom-right' | 'bottom-left' | 'bottom-center' | 'top-right' | 'top-left' | 'top-center';
|
|
612
|
-
type WhatsAppSize = 'sm' | 'md' | 'lg';
|
|
613
|
-
```
|
|
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)
|
|
614
467
|
|
|
615
468
|
### Modal
|
|
616
469
|
A flexible modal component for displaying dialogs, forms, and overlays.
|
|
@@ -653,13 +506,14 @@ A flexible modal component for displaying dialogs, forms, and overlays.
|
|
|
653
506
|
- `footer?: React.ReactNode` - Custom footer content
|
|
654
507
|
- `closeButton?: boolean` - Whether to show close button (default: true)
|
|
655
508
|
- `className?: string` - Additional CSS classes for the modal
|
|
656
|
-
- `dialogClassName?: string` - CSS classes for the modal dialog
|
|
657
|
-
- `contentClassName?: string` - CSS classes for the modal content
|
|
658
|
-
- `headerClassName?: string` - CSS classes for the modal header
|
|
659
|
-
- `bodyClassName?: string` - CSS classes for the modal body
|
|
660
|
-
- `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')
|
|
661
514
|
- `style?: React.CSSProperties` - Custom inline styles
|
|
662
515
|
|
|
516
|
+
|
|
663
517
|
**Types:**
|
|
664
518
|
```typescript
|
|
665
519
|
type ModalSize = 'sm' | 'md' | 'lg' | 'xl';
|
|
@@ -772,7 +626,7 @@ const MyComponent = () => {
|
|
|
772
626
|
```
|
|
773
627
|
|
|
774
628
|
### Input
|
|
775
|
-
A versatile input component with multiple variants, sizes, and types.
|
|
629
|
+
A versatile input component with multiple variants, sizes, masks, currency formatting, and types.
|
|
776
630
|
|
|
777
631
|
```jsx
|
|
778
632
|
<Input
|
|
@@ -782,8 +636,11 @@ A versatile input component with multiple variants, sizes, and types.
|
|
|
782
636
|
placeholder="Enter your text here"
|
|
783
637
|
value={inputValue}
|
|
784
638
|
onChange={(value) => setInputValue(value)}
|
|
785
|
-
className="
|
|
786
|
-
|
|
639
|
+
className="custom-class"
|
|
640
|
+
id="my-input"
|
|
641
|
+
>
|
|
642
|
+
Input Label
|
|
643
|
+
</Input>
|
|
787
644
|
```
|
|
788
645
|
|
|
789
646
|
**Props:**
|
|
@@ -800,15 +657,21 @@ A versatile input component with multiple variants, sizes, and types.
|
|
|
800
657
|
- `required?: boolean` - Required field (default: false)
|
|
801
658
|
- `readOnly?: boolean` - Read-only input (default: false)
|
|
802
659
|
- `className?: string` - Additional CSS classes
|
|
803
|
-
- `containerClassName?: string` - CSS classes for container element
|
|
804
|
-
- `inputClassName?: string` - CSS classes for input element
|
|
805
|
-
- `variantClassName?: string` - CSS classes for variant styling
|
|
806
|
-
- `sizeClassName?: string` - CSS classes for size styling
|
|
807
660
|
- `style?: React.CSSProperties` - Custom inline styles
|
|
808
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)
|
|
809
672
|
- `aria-label?: string` - ARIA label for accessibility
|
|
810
|
-
- `aria-labelledby?: string` - ARIA labelledby
|
|
811
|
-
- `...props`: any - Additional HTML input attributes
|
|
673
|
+
- `aria-labelledby?: string` - ARIA labelledby
|
|
674
|
+
- `...props`: any - Additional HTML input attributes
|
|
812
675
|
|
|
813
676
|
**Types:**
|
|
814
677
|
```typescript
|
|
@@ -819,17 +682,85 @@ type InputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'sea
|
|
|
819
682
|
|
|
820
683
|
**Variants:**
|
|
821
684
|
- `none` - Default styling with border
|
|
822
|
-
- `primary` - Blue
|
|
823
|
-
- `secondary` - Gray
|
|
824
|
-
- `outline` - Border only
|
|
825
|
-
- `danger` - Red
|
|
826
|
-
- `success` - Green
|
|
685
|
+
- `primary` - Blue focus ring
|
|
686
|
+
- `secondary` - Gray focus ring
|
|
687
|
+
- `outline` - Border only
|
|
688
|
+
- `danger` - Red focus ring
|
|
689
|
+
- `success` - Green focus ring
|
|
827
690
|
|
|
828
691
|
**Size Options:**
|
|
829
692
|
- `sm` - Small padding and text
|
|
830
693
|
- `md` - Medium padding and text
|
|
831
694
|
- `lg` - Large padding and text
|
|
832
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
|
+
|
|
833
764
|
|
|
834
765
|
|
|
835
766
|
## 🛠️ Utilities & Hooks
|
|
@@ -837,7 +768,7 @@ type InputType = 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'sea
|
|
|
837
768
|
Luna Library now includes generic utilities and hooks to streamline API communication and state management.
|
|
838
769
|
|
|
839
770
|
### httpClient
|
|
840
|
-
A generic HTTP client wrapper for the Fetch API with support for standard HTTP methods. It automatically handles JSON stringification for POST/PUT requests and sets appropriate headers.
|
|
771
|
+
A generic HTTP client wrapper for the Fetch API with support for standard HTTP methods. It automatically handles JSON stringification for POST/PUT requests and sets appropriate headers. Calls apiFetch internally.
|
|
841
772
|
|
|
842
773
|
```javascript
|
|
843
774
|
import { httpClient } from 'luna-components-library';
|
|
@@ -854,6 +785,21 @@ const response = await httpClient.post('https://api.example.com/posts', {
|
|
|
854
785
|
// httpClient.delete(url, options)
|
|
855
786
|
```
|
|
856
787
|
|
|
788
|
+
### apiFetch
|
|
789
|
+
A low-level wrapper for the native `fetch` API that includes automatic response parsing and error handling for non-OK HTTP statuses.
|
|
790
|
+
|
|
791
|
+
```javascript
|
|
792
|
+
import { apiFetch } from 'luna-components-library';
|
|
793
|
+
|
|
794
|
+
try {
|
|
795
|
+
const data = await apiFetch('https://api.example.com/resource');
|
|
796
|
+
console.log(data);
|
|
797
|
+
} catch (error) {
|
|
798
|
+
console.error('Fetch failed:', error.message);
|
|
799
|
+
}
|
|
800
|
+
```
|
|
801
|
+
|
|
802
|
+
|
|
857
803
|
### storage
|
|
858
804
|
A wrapper for `localStorage` with safety checks and automatic JSON parsing.
|
|
859
805
|
|
|
@@ -900,7 +846,6 @@ logger.success('User logged in');
|
|
|
900
846
|
logger.warn('Low disk space');
|
|
901
847
|
logger.error('API failed', error);
|
|
902
848
|
```
|
|
903
|
-
```
|
|
904
849
|
|
|
905
850
|
### useFetch
|
|
906
851
|
A powerful custom hook for performing data fetching. It manages `data`, `error`, and `loading` states automatically and includes built-in `AbortController` support to prevent memory leaks and race conditions.
|
|
@@ -926,6 +871,7 @@ function UserList() {
|
|
|
926
871
|
</ul>
|
|
927
872
|
);
|
|
928
873
|
}
|
|
874
|
+
```
|
|
929
875
|
|
|
930
876
|
### useLocalStorage
|
|
931
877
|
Syncs state with `localStorage` automatically.
|
|
@@ -993,8 +939,12 @@ luna-library/
|
|
|
993
939
|
│ │ ├── utilExamples/ # Examples for hooks and extra utilities
|
|
994
940
|
│ │ ├── Button.tsx
|
|
995
941
|
│ │ ├── Card.tsx
|
|
942
|
+
│ │ ├── DataTable.tsx
|
|
996
943
|
│ │ ├── ... (Other UI Components)
|
|
944
|
+
|
|
997
945
|
│ │ └── index.ts
|
|
946
|
+
│ ├── styles.ts # Design tokens and shared style functions
|
|
947
|
+
│ ├── types.ts # Shared TypeScript types
|
|
998
948
|
│ ├── hooks/
|
|
999
949
|
│ │ ├── useFetch.hook.ts
|
|
1000
950
|
│ │ ├── useLocalStorage.hook.ts
|
|
@@ -1074,7 +1024,9 @@ The library is configured with:
|
|
|
1074
1024
|
- `rimraf` - Cross-platform file removal
|
|
1075
1025
|
|
|
1076
1026
|
### Styling
|
|
1077
|
-
This library
|
|
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.
|
|
1078
1030
|
|
|
1079
1031
|
## 🤝 Contributing
|
|
1080
1032
|
|