@alexandretav/aleui 1.0.0 → 1.1.2
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 +208 -105
- package/cli.js +142 -0
- package/package.json +10 -8
- package/src/components/accordion/accordion.tsx +103 -0
- package/src/components/accordion/index.ts +2 -0
- package/src/components/aero-bubble/aero-bubble.tsx +51 -0
- package/src/components/aero-bubble/index.ts +2 -0
- package/src/components/aero-button/aero-button.tsx +49 -0
- package/src/components/aero-button/index.ts +2 -0
- package/src/components/aero-button/shiny-button.tsx +83 -0
- package/src/components/aero-card/aero-card.tsx +43 -0
- package/src/components/aero-card/index.ts +2 -0
- package/src/components/aero-input/aero-input.tsx +41 -0
- package/src/components/aero-input/index.ts +2 -0
- package/src/components/button/button.tsx +50 -0
- package/src/components/button/index.ts +2 -0
- package/src/components/card/card.tsx +43 -0
- package/src/components/card/index.ts +2 -0
- package/src/components/index.ts +30 -0
- package/src/components/input/index.ts +2 -0
- package/src/components/input/input.tsx +49 -0
- package/src/components/modal/index.ts +2 -0
- package/src/components/modal/modal.tsx +82 -0
- package/src/theme/glass.ts +124 -0
- package/src/utils/index.ts +39 -0
- package/dist/index.d.mts +0 -137
- package/dist/index.d.ts +0 -137
- package/dist/index.js +0 -417
- package/dist/index.mjs +0 -371
package/README.md
CHANGED
|
@@ -1,122 +1,132 @@
|
|
|
1
|
-
# ✨ Glassmorphism
|
|
1
|
+
# ✨ AleUI - Glassmorphism Components
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Beautiful, modern React components with glassmorphism and Frutiger Aero design. Copy components directly to your project - no bloat, full control.
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|

|
|
7
7
|

|
|
8
8
|

|
|
9
9
|
|
|
10
10
|
## 🎨 Features
|
|
11
11
|
|
|
12
|
-
- ✨ **
|
|
13
|
-
- 🌊 **Frutiger Aero
|
|
14
|
-
- 📘 **TypeScript
|
|
15
|
-
- 🎨 **Tailwind CSS**: Utility-first
|
|
16
|
-
- 🎭 **
|
|
17
|
-
- 📱 **Responsive**: Mobile-first design
|
|
18
|
-
- 🔧 **
|
|
19
|
-
- ⚡ **Framer Motion**: Smooth animations
|
|
12
|
+
- ✨ **Copy, Don't Install**: Components are copied to your project, not bundled
|
|
13
|
+
- 🌊 **Glassmorphism & Frutiger Aero**: Modern glass effects + nostalgic 2000s aesthetic
|
|
14
|
+
- 📘 **TypeScript**: Full type safety and IntelliSense
|
|
15
|
+
- 🎨 **Tailwind CSS**: Utility-first styling
|
|
16
|
+
- 🎭 **4 Variants**: Light, Medium, Dark, and Colored for each component
|
|
17
|
+
- 📱 **Responsive**: Mobile-first design
|
|
18
|
+
- 🔧 **Full Control**: Edit components directly in your codebase
|
|
19
|
+
- ⚡ **Framer Motion**: Smooth animations
|
|
20
20
|
|
|
21
21
|
## 📦 Components
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
26
|
-
- **
|
|
27
|
-
- **
|
|
28
|
-
- **
|
|
23
|
+
### Glassmorphism Components
|
|
24
|
+
- **Button** - Interactive buttons with glass effects
|
|
25
|
+
- **Card** - Container components with blur
|
|
26
|
+
- **Input** - Form fields with labels
|
|
27
|
+
- **Modal** - Dialog with backdrop blur
|
|
28
|
+
- **Accordion** - Collapsible panels
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
### Frutiger Aero Components
|
|
31
|
+
- **AeroButton** - Aquatic gradient buttons
|
|
32
|
+
- **AeroCard** - Cards with aero styling
|
|
33
|
+
- **AeroInput** - Inputs with aero theme
|
|
34
|
+
- **AeroBubble** - Decorative bubble elements
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
npm install glassmorphism-ui
|
|
36
|
-
# or
|
|
37
|
-
yarn add glassmorphism-ui
|
|
38
|
-
# or
|
|
39
|
-
pnpm add glassmorphism-ui
|
|
40
|
-
```
|
|
36
|
+
## 🚀 Quick Start
|
|
41
37
|
|
|
42
|
-
### Setup Tailwind CSS
|
|
38
|
+
### 1. Setup Tailwind CSS
|
|
43
39
|
|
|
44
|
-
|
|
40
|
+
Add to your `tailwind.config.js`:
|
|
45
41
|
|
|
46
42
|
```js
|
|
47
43
|
module.exports = {
|
|
48
44
|
content: [
|
|
49
45
|
"./src/**/*.{js,ts,jsx,tsx}",
|
|
50
|
-
"./node_modules/glassmorphism-ui/**/*.{js,ts,jsx,tsx}", // Add this line
|
|
51
46
|
],
|
|
52
47
|
theme: {
|
|
53
48
|
extend: {
|
|
54
|
-
colors: {
|
|
55
|
-
aero: {
|
|
56
|
-
sky: '#87CEEB',
|
|
57
|
-
aqua: '#00CED1',
|
|
58
|
-
cyan: '#00E5FF',
|
|
59
|
-
mint: '#98FF98',
|
|
60
|
-
lime: '#BFFF00',
|
|
61
|
-
white: '#F0F8FF',
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
49
|
boxShadow: {
|
|
65
50
|
'aero': '0 8px 32px 0 rgba(31, 38, 135, 0.37)',
|
|
66
51
|
'aero-lg': '0 12px 48px 0 rgba(31, 38, 135, 0.5)',
|
|
67
52
|
},
|
|
68
53
|
},
|
|
69
54
|
},
|
|
70
|
-
plugins: [],
|
|
71
55
|
}
|
|
72
56
|
```
|
|
73
57
|
|
|
74
|
-
###
|
|
58
|
+
### 2. Add Components
|
|
75
59
|
|
|
76
|
-
|
|
60
|
+
Add all components (recommended):
|
|
77
61
|
|
|
78
62
|
```bash
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
cd glassmorphism-ui
|
|
63
|
+
npx @alexandretav/aleui
|
|
64
|
+
```
|
|
82
65
|
|
|
83
|
-
|
|
84
|
-
npm install
|
|
66
|
+
Or add a specific component:
|
|
85
67
|
|
|
86
|
-
|
|
87
|
-
|
|
68
|
+
```bash
|
|
69
|
+
npx @alexandretav/aleui add button
|
|
88
70
|
```
|
|
89
71
|
|
|
90
|
-
|
|
72
|
+
List available components:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npx @alexandretav/aleui list
|
|
76
|
+
```
|
|
91
77
|
|
|
92
|
-
|
|
78
|
+
### 3. Use Components
|
|
93
79
|
|
|
94
|
-
|
|
80
|
+
Components are copied to `src/components/ui/` in your project:
|
|
95
81
|
|
|
96
82
|
```tsx
|
|
97
|
-
import { Button
|
|
83
|
+
import { Button } from '@/components/ui/button';
|
|
84
|
+
import { Card } from '@/components/ui/card';
|
|
85
|
+
|
|
86
|
+
function App() {
|
|
87
|
+
return (
|
|
88
|
+
<Card variant="medium" padding="lg">
|
|
89
|
+
<h2>Hello World</h2>
|
|
90
|
+
<Button variant="light" size="md">
|
|
91
|
+
Click Me
|
|
92
|
+
</Button>
|
|
93
|
+
</Card>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
98
96
|
```
|
|
99
97
|
|
|
100
|
-
|
|
98
|
+
## 💻 Usage Examples
|
|
99
|
+
|
|
100
|
+
### Button
|
|
101
101
|
|
|
102
102
|
```tsx
|
|
103
|
-
|
|
103
|
+
import { Button } from '@/components/ui/button';
|
|
104
|
+
|
|
105
|
+
<Button variant="light" size="md" onClick={() => alert('Clicked!')}>
|
|
104
106
|
Click Me
|
|
105
107
|
</Button>
|
|
108
|
+
|
|
109
|
+
<Button variant="colored" size="lg" fullWidth>
|
|
110
|
+
Full Width Button
|
|
111
|
+
</Button>
|
|
106
112
|
```
|
|
107
113
|
|
|
108
|
-
### Card
|
|
114
|
+
### Card
|
|
109
115
|
|
|
110
116
|
```tsx
|
|
111
|
-
|
|
117
|
+
import { Card } from '@/components/ui/card';
|
|
118
|
+
|
|
119
|
+
<Card variant="medium" padding="lg" enableInteractions>
|
|
112
120
|
<h2>Card Title</h2>
|
|
113
|
-
<p>Card content
|
|
121
|
+
<p>Card content with hover effects</p>
|
|
114
122
|
</Card>
|
|
115
123
|
```
|
|
116
124
|
|
|
117
|
-
### Input
|
|
125
|
+
### Input
|
|
118
126
|
|
|
119
127
|
```tsx
|
|
128
|
+
import { Input } from '@/components/ui/input';
|
|
129
|
+
|
|
120
130
|
<Input
|
|
121
131
|
variant="light"
|
|
122
132
|
label="Email"
|
|
@@ -126,9 +136,12 @@ import { Button, Card, Input, Modal } from '@/components';
|
|
|
126
136
|
/>
|
|
127
137
|
```
|
|
128
138
|
|
|
129
|
-
### Modal
|
|
139
|
+
### Modal
|
|
130
140
|
|
|
131
141
|
```tsx
|
|
142
|
+
import { Modal } from '@/components/ui/modal';
|
|
143
|
+
import { useState } from 'react';
|
|
144
|
+
|
|
132
145
|
const [isOpen, setIsOpen] = useState(false);
|
|
133
146
|
|
|
134
147
|
<Modal
|
|
@@ -141,75 +154,165 @@ const [isOpen, setIsOpen] = useState(false);
|
|
|
141
154
|
</Modal>
|
|
142
155
|
```
|
|
143
156
|
|
|
157
|
+
### Accordion
|
|
158
|
+
|
|
159
|
+
```tsx
|
|
160
|
+
import { Accordion } from '@/components/ui/accordion';
|
|
161
|
+
|
|
162
|
+
<Accordion
|
|
163
|
+
variant="light"
|
|
164
|
+
items={[
|
|
165
|
+
{
|
|
166
|
+
id: '1',
|
|
167
|
+
title: 'Question 1',
|
|
168
|
+
content: 'Answer 1',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
id: '2',
|
|
172
|
+
title: 'Question 2',
|
|
173
|
+
content: 'Answer 2',
|
|
174
|
+
},
|
|
175
|
+
]}
|
|
176
|
+
/>
|
|
177
|
+
```
|
|
178
|
+
|
|
144
179
|
## 🎨 Customization
|
|
145
180
|
|
|
181
|
+
Since components are copied to your project, you have **full control** to customize them:
|
|
182
|
+
|
|
183
|
+
### Edit Components Directly
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
// src/components/ui/button/button.tsx
|
|
187
|
+
export const Button = ({ variant = 'light', ... }) => {
|
|
188
|
+
// Modify styles, add features, change behavior
|
|
189
|
+
return <button className={...}>...</button>
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
146
193
|
### Theme Configuration
|
|
147
194
|
|
|
148
|
-
The
|
|
195
|
+
The theme is in `src/theme/glass.ts`:
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
export const glassVariants = {
|
|
199
|
+
light: {
|
|
200
|
+
background: 'bg-white/5',
|
|
201
|
+
backdropBlur: 'backdrop-blur-[2px]',
|
|
202
|
+
border: 'border border-white/15',
|
|
203
|
+
shadow: 'shadow-lg',
|
|
204
|
+
hover: 'hover:bg-white/10',
|
|
205
|
+
focus: 'focus:ring-2 focus:ring-white/10',
|
|
206
|
+
},
|
|
207
|
+
// ... customize as needed
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Using Theme Utilities
|
|
149
212
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
213
|
+
```tsx
|
|
214
|
+
import { getGlassClasses, getAeroClasses } from '@/theme/glass';
|
|
215
|
+
|
|
216
|
+
const MyComponent = () => {
|
|
217
|
+
const glassStyle = getGlassClasses('medium');
|
|
218
|
+
const aeroStyle = getAeroClasses('colored');
|
|
219
|
+
|
|
220
|
+
return <div className={glassStyle}>Custom component</div>;
|
|
221
|
+
};
|
|
222
|
+
```
|
|
155
223
|
|
|
156
|
-
|
|
224
|
+
## 📁 Project Structure (After Installation)
|
|
157
225
|
|
|
158
|
-
|
|
226
|
+
```
|
|
227
|
+
your-project/
|
|
228
|
+
├── src/
|
|
229
|
+
│ ├── components/
|
|
230
|
+
│ │ └── ui/ # Components copied here
|
|
231
|
+
│ │ ├── button/
|
|
232
|
+
│ │ │ ├── button.tsx
|
|
233
|
+
│ │ │ └── index.ts
|
|
234
|
+
│ │ ├── card/
|
|
235
|
+
│ │ ├── input/
|
|
236
|
+
│ │ ├── modal/
|
|
237
|
+
│ │ ├── accordion/
|
|
238
|
+
│ │ └── aero-bubble/
|
|
239
|
+
│ └── theme/
|
|
240
|
+
│ └── glass.ts # Theme config copied here
|
|
241
|
+
```
|
|
159
242
|
|
|
160
|
-
|
|
243
|
+
## 🎯 CLI Commands
|
|
161
244
|
|
|
162
|
-
|
|
245
|
+
```bash
|
|
246
|
+
# Add all components (default)
|
|
247
|
+
npx @alexandretav/aleui
|
|
163
248
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
- `.glass-hover` - Hover animation
|
|
249
|
+
# Add a specific component
|
|
250
|
+
npx @alexandretav/aleui add button
|
|
251
|
+
npx @alexandretav/aleui add card
|
|
252
|
+
npx @alexandretav/aleui add modal
|
|
169
253
|
|
|
170
|
-
|
|
254
|
+
# List available components
|
|
255
|
+
npx @alexandretav/aleui list
|
|
171
256
|
|
|
257
|
+
# Show help
|
|
258
|
+
npx @alexandretav/aleui help
|
|
172
259
|
```
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
│ ├── Input/
|
|
186
|
-
│ │ ├── Input.tsx
|
|
187
|
-
│ │ └── index.ts
|
|
188
|
-
│ ├── Modal/
|
|
189
|
-
│ │ ├── Modal.tsx
|
|
190
|
-
│ │ └── index.ts
|
|
191
|
-
│ └── index.ts # Component exports
|
|
192
|
-
├── theme/
|
|
193
|
-
│ └── glass.ts # Glassmorphism theme config
|
|
194
|
-
└── utils/
|
|
195
|
-
└── index.ts # Utility functions
|
|
260
|
+
|
|
261
|
+
## 🌐 Demo
|
|
262
|
+
|
|
263
|
+
View live demo: [https://github.com/alexandrertav/alex-ui](https://github.com/alexandrertav/alex-ui)
|
|
264
|
+
|
|
265
|
+
Run demo locally:
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
git clone https://github.com/alexandrertav/alex-ui.git
|
|
269
|
+
cd alex-ui
|
|
270
|
+
npm install
|
|
271
|
+
npm run dev
|
|
196
272
|
```
|
|
197
273
|
|
|
274
|
+
Open [http://localhost:3000](http://localhost:3000)
|
|
275
|
+
|
|
198
276
|
## 🛠️ Tech Stack
|
|
199
277
|
|
|
200
|
-
- **
|
|
278
|
+
- **React 18** - UI library
|
|
201
279
|
- **TypeScript** - Type safety
|
|
202
280
|
- **Tailwind CSS** - Styling
|
|
203
|
-
- **
|
|
281
|
+
- **Framer Motion** - Animations
|
|
282
|
+
|
|
283
|
+
## ❓ FAQ
|
|
284
|
+
|
|
285
|
+
**Q: Why copy components instead of installing from npm?**
|
|
286
|
+
A: Full control. Edit, customize, and own the code. No black boxes.
|
|
287
|
+
|
|
288
|
+
**Q: Do I need to install the package?**
|
|
289
|
+
A: No! Just use `npx @alexandretav/aleui add <component>` to copy components.
|
|
290
|
+
|
|
291
|
+
**Q: Can I modify the components?**
|
|
292
|
+
A: Yes! They're in your codebase. Modify freely.
|
|
293
|
+
|
|
294
|
+
**Q: What about updates?**
|
|
295
|
+
A: Re-run the CLI command to get the latest version of a component.
|
|
296
|
+
|
|
297
|
+
**Q: Does it work with Next.js/Remix/Vite?**
|
|
298
|
+
A: Yes! Works with any React framework that supports Tailwind CSS.
|
|
204
299
|
|
|
205
300
|
## 📝 License
|
|
206
301
|
|
|
207
|
-
MIT
|
|
302
|
+
MIT License - feel free to use in personal and commercial projects.
|
|
208
303
|
|
|
209
304
|
## 🤝 Contributing
|
|
210
305
|
|
|
211
|
-
Contributions are welcome!
|
|
306
|
+
Contributions are welcome!
|
|
307
|
+
|
|
308
|
+
- Report bugs: [GitHub Issues](https://github.com/alexandrertav/alex-ui/issues)
|
|
309
|
+
- Submit PRs: [GitHub Pull Requests](https://github.com/alexandrertav/alex-ui/pulls)
|
|
310
|
+
|
|
311
|
+
## 🔗 Links
|
|
312
|
+
|
|
313
|
+
- **NPM Package**: [@alexandretav/aleui](https://www.npmjs.com/package/@alexandretav/aleui)
|
|
314
|
+
- **GitHub**: [alexandrertav/alex-ui](https://github.com/alexandrertav/alex-ui)
|
|
315
|
+
- **Author**: Alexandre R. Tavares
|
|
212
316
|
|
|
213
317
|
---
|
|
214
318
|
|
|
215
|
-
Built with ❤️ using Next.js and Tailwind CSS
|
package/cli.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { execSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const COMPONENTS_DIR = path.join(__dirname, 'src', 'components');
|
|
8
|
+
const TARGET_DIR = path.join(process.cwd(), 'src', 'components', 'ui');
|
|
9
|
+
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
const command = args[0];
|
|
12
|
+
const componentName = args[1];
|
|
13
|
+
|
|
14
|
+
const availableComponents = [
|
|
15
|
+
'button',
|
|
16
|
+
'card',
|
|
17
|
+
'input',
|
|
18
|
+
'modal',
|
|
19
|
+
'accordion',
|
|
20
|
+
'aero-bubble',
|
|
21
|
+
'aero-button',
|
|
22
|
+
'aero-card',
|
|
23
|
+
'aero-input'
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
function copyComponent(name) {
|
|
27
|
+
const sourcePath = path.join(COMPONENTS_DIR, name);
|
|
28
|
+
const targetPath = path.join(TARGET_DIR, name);
|
|
29
|
+
|
|
30
|
+
if (!fs.existsSync(sourcePath)) {
|
|
31
|
+
console.error(`❌ Componente "${name}" não encontrado!`);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Criar diretório de destino
|
|
36
|
+
if (!fs.existsSync(targetPath)) {
|
|
37
|
+
fs.mkdirSync(targetPath, { recursive: true });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Copiar arquivos
|
|
41
|
+
const files = fs.readdirSync(sourcePath);
|
|
42
|
+
files.forEach(file => {
|
|
43
|
+
const sourceFile = path.join(sourcePath, file);
|
|
44
|
+
const targetFile = path.join(targetPath, file);
|
|
45
|
+
fs.copyFileSync(sourceFile, targetFile);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
console.log(`✅ Componente "${name}" copiado para ${targetPath}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function copyTheme() {
|
|
52
|
+
const themePath = path.join(__dirname, 'src', 'theme');
|
|
53
|
+
const targetThemePath = path.join(process.cwd(), 'src', 'theme');
|
|
54
|
+
|
|
55
|
+
if (!fs.existsSync(targetThemePath)) {
|
|
56
|
+
fs.mkdirSync(targetThemePath, { recursive: true });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const files = fs.readdirSync(themePath);
|
|
60
|
+
files.forEach(file => {
|
|
61
|
+
const sourceFile = path.join(themePath, file);
|
|
62
|
+
const targetFile = path.join(targetThemePath, file);
|
|
63
|
+
fs.copyFileSync(sourceFile, targetFile);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
console.log(`✅ Tema copiado para ${targetThemePath}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function showHelp() {
|
|
70
|
+
console.log(`
|
|
71
|
+
🎨 AleUI - Glassmorphism Components
|
|
72
|
+
|
|
73
|
+
Uso:
|
|
74
|
+
npx @alexandretav/aleui # Adiciona todos os componentes
|
|
75
|
+
npx @alexandretav/aleui add <componente> # Adiciona um componente específico
|
|
76
|
+
npx @alexandretav/aleui list # Lista componentes disponíveis
|
|
77
|
+
|
|
78
|
+
Comandos:
|
|
79
|
+
(sem comando) Adiciona todos os componentes
|
|
80
|
+
add <componente> Adiciona um componente específico
|
|
81
|
+
add-all Adiciona todos os componentes
|
|
82
|
+
list Lista componentes disponíveis
|
|
83
|
+
help Mostra esta ajuda
|
|
84
|
+
|
|
85
|
+
Componentes disponíveis:
|
|
86
|
+
${availableComponents.map(c => ` - ${c}`).join('\n')}
|
|
87
|
+
|
|
88
|
+
Exemplos:
|
|
89
|
+
npx @alexandretav/aleui # Adiciona tudo
|
|
90
|
+
npx @alexandretav/aleui add button # Adiciona só o Button
|
|
91
|
+
npx @alexandretav/aleui add card # Adiciona só o Card
|
|
92
|
+
npx @alexandretav/aleui list # Lista componentes
|
|
93
|
+
`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function listComponents() {
|
|
97
|
+
console.log('\n📦 Componentes disponíveis:\n');
|
|
98
|
+
availableComponents.forEach(c => {
|
|
99
|
+
console.log(` ✨ ${c}`);
|
|
100
|
+
});
|
|
101
|
+
console.log('');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Main
|
|
105
|
+
if (!command) {
|
|
106
|
+
// Se não houver comando, adiciona todos os componentes
|
|
107
|
+
copyTheme();
|
|
108
|
+
availableComponents.forEach(comp => copyComponent(comp));
|
|
109
|
+
console.log('\n✅ Todos os componentes foram copiados!');
|
|
110
|
+
} else {
|
|
111
|
+
switch (command) {
|
|
112
|
+
case 'add':
|
|
113
|
+
if (!componentName) {
|
|
114
|
+
console.error('❌ Especifique o nome do componente!');
|
|
115
|
+
console.log('Uso: npx @alexandretav/aleui add <componente>');
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
copyTheme();
|
|
119
|
+
copyComponent(componentName);
|
|
120
|
+
break;
|
|
121
|
+
|
|
122
|
+
case 'add-all':
|
|
123
|
+
copyTheme();
|
|
124
|
+
availableComponents.forEach(comp => copyComponent(comp));
|
|
125
|
+
console.log('\n✅ Todos os componentes foram copiados!');
|
|
126
|
+
break;
|
|
127
|
+
|
|
128
|
+
case 'list':
|
|
129
|
+
listComponents();
|
|
130
|
+
break;
|
|
131
|
+
|
|
132
|
+
case 'help':
|
|
133
|
+
case '--help':
|
|
134
|
+
case '-h':
|
|
135
|
+
showHelp();
|
|
136
|
+
break;
|
|
137
|
+
|
|
138
|
+
default:
|
|
139
|
+
console.error(`❌ Comando desconhecido: "${command}"`);
|
|
140
|
+
showHelp();
|
|
141
|
+
}
|
|
142
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alexandretav/aleui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Glass UI components for React",
|
|
5
|
-
"main": "
|
|
6
|
-
"
|
|
7
|
-
"
|
|
5
|
+
"main": "src/components/index.ts",
|
|
6
|
+
"types": "src/components/index.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"aleui": "cli.js"
|
|
9
|
+
},
|
|
8
10
|
"files": [
|
|
9
|
-
"
|
|
11
|
+
"src/components",
|
|
12
|
+
"src/theme",
|
|
13
|
+
"src/utils",
|
|
10
14
|
"README.md",
|
|
11
15
|
"LICENSE"
|
|
12
16
|
],
|
|
@@ -33,10 +37,8 @@
|
|
|
33
37
|
"scripts": {
|
|
34
38
|
"dev": "next dev",
|
|
35
39
|
"build": "next build",
|
|
36
|
-
"build:lib": "tsup src/components/index.ts --format cjs,esm --dts --external react --external react-dom --external framer-motion",
|
|
37
40
|
"start": "next start",
|
|
38
|
-
"lint": "next lint"
|
|
39
|
-
"prepublishOnly": "npm run build:lib"
|
|
41
|
+
"lint": "next lint"
|
|
40
42
|
},
|
|
41
43
|
"peerDependencies": {
|
|
42
44
|
"framer-motion": "^11.0.0",
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React, { useState } from 'react';
|
|
4
|
+
import { getGlassClasses, GlassVariantType } from '@/theme/glass';
|
|
5
|
+
|
|
6
|
+
export interface AccordionItemProps {
|
|
7
|
+
id: string;
|
|
8
|
+
title: string;
|
|
9
|
+
content: React.ReactNode;
|
|
10
|
+
icon?: React.ReactNode;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface AccordionProps {
|
|
14
|
+
items: AccordionItemProps[];
|
|
15
|
+
variant?: GlassVariantType;
|
|
16
|
+
allowMultiple?: boolean;
|
|
17
|
+
defaultOpen?: string[];
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const Accordion: React.FC<AccordionProps> = ({
|
|
22
|
+
items,
|
|
23
|
+
variant = 'light',
|
|
24
|
+
allowMultiple = false,
|
|
25
|
+
defaultOpen = [],
|
|
26
|
+
className = '',
|
|
27
|
+
}) => {
|
|
28
|
+
const [openItems, setOpenItems] = useState<string[]>(defaultOpen);
|
|
29
|
+
|
|
30
|
+
const toggleItem = (id: string) => {
|
|
31
|
+
if (allowMultiple) {
|
|
32
|
+
setOpenItems((prev) =>
|
|
33
|
+
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id]
|
|
34
|
+
);
|
|
35
|
+
} else {
|
|
36
|
+
setOpenItems((prev) => (prev.includes(id) ? [] : [id]));
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const isOpen = (id: string) => openItems.includes(id);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div className={className}>
|
|
44
|
+
{items.map((item, index) => {
|
|
45
|
+
const open = isOpen(item.id);
|
|
46
|
+
const glassClasses = getGlassClasses(variant, 'rounded-none', false);
|
|
47
|
+
const isFirst = index === 0;
|
|
48
|
+
const isLast = index === items.length - 1;
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div
|
|
52
|
+
key={item.id}
|
|
53
|
+
className={`${glassClasses} ${
|
|
54
|
+
isFirst ? 'rounded-t-lg' : ''
|
|
55
|
+
} ${
|
|
56
|
+
isLast ? 'rounded-b-lg' : ''
|
|
57
|
+
} ${
|
|
58
|
+
!isLast ? 'border-b border-white/10' : ''
|
|
59
|
+
}`}
|
|
60
|
+
>
|
|
61
|
+
<button
|
|
62
|
+
onClick={() => toggleItem(item.id)}
|
|
63
|
+
className="w-full px-4 py-4 flex items-center justify-between text-left text-white font-medium hover:underline transition-all duration-200"
|
|
64
|
+
>
|
|
65
|
+
<div className="flex items-center gap-2">
|
|
66
|
+
{item.icon && <span className="flex items-center text-base">{item.icon}</span>}
|
|
67
|
+
<span className="text-sm font-medium">{item.title}</span>
|
|
68
|
+
</div>
|
|
69
|
+
<svg
|
|
70
|
+
className={`w-4 h-4 shrink-0 transition-transform duration-200 text-white/70 ${
|
|
71
|
+
open ? 'rotate-180' : ''
|
|
72
|
+
}`}
|
|
73
|
+
fill="none"
|
|
74
|
+
stroke="currentColor"
|
|
75
|
+
strokeWidth="2"
|
|
76
|
+
viewBox="0 0 24 24"
|
|
77
|
+
>
|
|
78
|
+
<path
|
|
79
|
+
strokeLinecap="round"
|
|
80
|
+
strokeLinejoin="round"
|
|
81
|
+
d="M19 9l-7 7-7-7"
|
|
82
|
+
/>
|
|
83
|
+
</svg>
|
|
84
|
+
</button>
|
|
85
|
+
<div
|
|
86
|
+
className={`grid transition-all duration-200 ease-in-out ${
|
|
87
|
+
open ? 'grid-rows-[1fr] opacity-100' : 'grid-rows-[0fr] opacity-0'
|
|
88
|
+
}`}
|
|
89
|
+
>
|
|
90
|
+
<div className="overflow-hidden">
|
|
91
|
+
<div className="px-4 pb-4 pt-0 text-sm text-white/80 leading-relaxed">
|
|
92
|
+
{item.content}
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
98
|
+
})}
|
|
99
|
+
</div>
|
|
100
|
+
);
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
export default Accordion;
|