cite-ui 0.1.0 → 0.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 +162 -0
- package/dist/cite-ui.es.js +212 -97
- package/dist/cite-ui.umd.js +9 -1
- package/package.json +1 -1
- package/src/components/Navbar/index.jsx +73 -14
- package/src/components/WhatsAppFloat/index.jsx +54 -0
- package/src/index.jsx +1 -0
- package/src/main.jsx +112 -0
package/Readme.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# cite-ui
|
|
2
|
+
|
|
3
|
+
A reusable React component library built for FrameStudio client projects. Prop-driven, Tailwind CSS styled, and published on npm.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install cite-ui
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
After installing, add cite-ui to your Tailwind `content` array so styles are picked up correctly:
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
// tailwind.config.js
|
|
17
|
+
export default {
|
|
18
|
+
content: [
|
|
19
|
+
"./index.html",
|
|
20
|
+
"./src/**/*.{js,jsx}",
|
|
21
|
+
"./node_modules/cite-ui/src/**/*.{js,jsx}"
|
|
22
|
+
],
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Components
|
|
29
|
+
|
|
30
|
+
### Button
|
|
31
|
+
|
|
32
|
+
A flexible button component with three variants.
|
|
33
|
+
|
|
34
|
+
**Props**
|
|
35
|
+
|
|
36
|
+
| Prop | Type | Default | Description |
|
|
37
|
+
|------|------|---------|-------------|
|
|
38
|
+
| `variant` | `"primary"` \| `"secondary"` \| `"whatsapp"` | `"primary"` | Button style |
|
|
39
|
+
| `label` | `string` | — | Button text |
|
|
40
|
+
| `onClick` | `function` | — | Click handler |
|
|
41
|
+
| `className` | `string` | `""` | Extra Tailwind classes |
|
|
42
|
+
|
|
43
|
+
**Usage**
|
|
44
|
+
|
|
45
|
+
```jsx
|
|
46
|
+
import { Button } from 'cite-ui'
|
|
47
|
+
|
|
48
|
+
<Button variant="primary" label="Get Started" onClick={() => {}} />
|
|
49
|
+
<Button variant="secondary" label="Learn More" onClick={() => {}} />
|
|
50
|
+
<Button variant="whatsapp" label="Chat with us" onClick={() => window.open('https://wa.me/254712345678')} />
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
### Navbar
|
|
56
|
+
|
|
57
|
+
A responsive sticky navbar with mobile hamburger menu.
|
|
58
|
+
|
|
59
|
+
**Props**
|
|
60
|
+
|
|
61
|
+
| Prop | Type | Default | Description |
|
|
62
|
+
|------|------|---------|-------------|
|
|
63
|
+
| `logo` | `string` | — | Brand name or logo text |
|
|
64
|
+
| `links` | `{ label: string, href: string }[]` | `[]` | Navigation links |
|
|
65
|
+
| `ctaLabel` | `string` | — | CTA button text (optional) |
|
|
66
|
+
| `ctaHref` | `string` | — | CTA button link (optional) |
|
|
67
|
+
|
|
68
|
+
**Usage**
|
|
69
|
+
|
|
70
|
+
```jsx
|
|
71
|
+
import { Navbar } from 'cite-ui'
|
|
72
|
+
|
|
73
|
+
const links = [
|
|
74
|
+
{ label: 'Home', href: '#' },
|
|
75
|
+
{ label: 'About', href: '#' },
|
|
76
|
+
{ label: 'Services', href: '#' },
|
|
77
|
+
]
|
|
78
|
+
|
|
79
|
+
<Navbar
|
|
80
|
+
logo="My Business"
|
|
81
|
+
links={links}
|
|
82
|
+
ctaLabel="Get Started"
|
|
83
|
+
ctaHref="#contact"
|
|
84
|
+
/>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### Gallery
|
|
90
|
+
|
|
91
|
+
A responsive image grid with lightbox on click.
|
|
92
|
+
|
|
93
|
+
**Props**
|
|
94
|
+
|
|
95
|
+
| Prop | Type | Default | Description |
|
|
96
|
+
|------|------|---------|-------------|
|
|
97
|
+
| `images` | `{ src: string, alt: string }[]` | `[]` | Array of image objects |
|
|
98
|
+
| `columns` | `number` | `3` | Number of columns on desktop (1–6) |
|
|
99
|
+
| `gap` | `number` | `4` | Gap between images (Tailwind spacing scale) |
|
|
100
|
+
|
|
101
|
+
**Usage**
|
|
102
|
+
|
|
103
|
+
```jsx
|
|
104
|
+
import { Gallery } from 'cite-ui'
|
|
105
|
+
|
|
106
|
+
const images = [
|
|
107
|
+
{ src: '/images/photo1.jpg', alt: 'Photo 1' },
|
|
108
|
+
{ src: '/images/photo2.jpg', alt: 'Photo 2' },
|
|
109
|
+
{ src: '/images/photo3.jpg', alt: 'Photo 3' },
|
|
110
|
+
]
|
|
111
|
+
|
|
112
|
+
<Gallery images={images} columns={3} gap={4} />
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Full Example
|
|
118
|
+
|
|
119
|
+
```jsx
|
|
120
|
+
import { Navbar, Button, Gallery } from 'cite-ui'
|
|
121
|
+
|
|
122
|
+
const links = [
|
|
123
|
+
{ label: 'Home', href: '#' },
|
|
124
|
+
{ label: 'About', href: '#' },
|
|
125
|
+
{ label: 'Services', href: '#' },
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
const images = [
|
|
129
|
+
{ src: '/images/photo1.jpg', alt: 'Photo 1' },
|
|
130
|
+
{ src: '/images/photo2.jpg', alt: 'Photo 2' },
|
|
131
|
+
{ src: '/images/photo3.jpg', alt: 'Photo 3' },
|
|
132
|
+
]
|
|
133
|
+
|
|
134
|
+
export default function App() {
|
|
135
|
+
return (
|
|
136
|
+
<div>
|
|
137
|
+
<Navbar logo="FrameStudio" links={links} ctaLabel="Get Started" ctaHref="#" />
|
|
138
|
+
<div className="p-8 space-y-6">
|
|
139
|
+
<Button variant="whatsapp" label="Chat with us" onClick={() => window.open('https://wa.me/254712345678')} />
|
|
140
|
+
<Gallery images={images} columns={3} />
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
)
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## Peer Dependencies
|
|
150
|
+
|
|
151
|
+
cite-ui requires React 18+ and Tailwind CSS v3 to be installed in your project.
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
npm install react react-dom
|
|
155
|
+
npm install -D tailwindcss
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT
|
package/dist/cite-ui.es.js
CHANGED
|
@@ -1,136 +1,198 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import { useState as
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
1
|
+
import { jsxs as l, jsx as e, Fragment as m } from "react/jsx-runtime";
|
|
2
|
+
import { useState as g } from "react";
|
|
3
|
+
const w = ({
|
|
4
|
+
logo: o,
|
|
5
|
+
links: s = [],
|
|
6
|
+
ctaLabel: r,
|
|
7
|
+
ctaHref: t,
|
|
8
|
+
variant: n = "default",
|
|
9
|
+
cartCount: a = 0,
|
|
10
|
+
onCartClick: d
|
|
11
|
+
}) => {
|
|
12
|
+
const [p, x] = g(!1), c = n === "glass";
|
|
13
|
+
return /* @__PURE__ */ l(
|
|
14
|
+
"nav",
|
|
15
|
+
{
|
|
16
|
+
className: `sticky top-0 z-50 ${c ? "" : "bg-white border-b border-gray-200"}`,
|
|
17
|
+
style: c ? {
|
|
18
|
+
background: "rgba(255,255,255,0.7)",
|
|
19
|
+
backdropFilter: "blur(12px)",
|
|
20
|
+
WebkitBackdropFilter: "blur(12px)",
|
|
21
|
+
borderBottom: "1px solid rgba(255,255,255,0.3)"
|
|
22
|
+
} : {},
|
|
23
|
+
children: [
|
|
24
|
+
/* @__PURE__ */ e("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ l("div", { className: "flex items-center justify-between h-16 relative", children: [
|
|
25
|
+
/* @__PURE__ */ e("div", { className: "flex-shrink-0 text-xl font-bold tracking-tight", children: o }),
|
|
26
|
+
/* @__PURE__ */ e(
|
|
27
|
+
"div",
|
|
28
|
+
{
|
|
29
|
+
className: `items-center gap-8 ${c ? "absolute left-1/2 -translate-x-1/2 hidden md:flex" : "hidden md:flex"}`,
|
|
30
|
+
children: s.map((i, h) => /* @__PURE__ */ e(
|
|
31
|
+
"a",
|
|
32
|
+
{
|
|
33
|
+
href: i.href,
|
|
34
|
+
className: "text-gray-600 hover:text-black transition-colors",
|
|
35
|
+
children: i.label
|
|
36
|
+
},
|
|
37
|
+
h
|
|
38
|
+
))
|
|
39
|
+
}
|
|
40
|
+
),
|
|
41
|
+
/* @__PURE__ */ l("div", { className: "flex items-center gap-4", children: [
|
|
42
|
+
c ? /* @__PURE__ */ l(
|
|
43
|
+
"button",
|
|
34
44
|
{
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
onClick: d,
|
|
46
|
+
className: "relative p-2 text-gray-600 hover:text-black transition-colors",
|
|
47
|
+
children: [
|
|
48
|
+
/* @__PURE__ */ e(
|
|
49
|
+
"svg",
|
|
50
|
+
{
|
|
51
|
+
className: "w-6 h-6",
|
|
52
|
+
fill: "none",
|
|
53
|
+
stroke: "currentColor",
|
|
54
|
+
viewBox: "0 0 24 24",
|
|
55
|
+
children: /* @__PURE__ */ e(
|
|
56
|
+
"path",
|
|
57
|
+
{
|
|
58
|
+
strokeLinecap: "round",
|
|
59
|
+
strokeLinejoin: "round",
|
|
60
|
+
strokeWidth: 2,
|
|
61
|
+
d: "M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 100 4 2 2 0 000-4z"
|
|
62
|
+
}
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
),
|
|
66
|
+
a > 0 && /* @__PURE__ */ e("span", { className: "absolute -top-1 -right-1 bg-red-500 text-white text-xs w-5 h-5 rounded-full flex items-center justify-center font-medium", children: a })
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
) : r && t && /* @__PURE__ */ e(
|
|
70
|
+
"a",
|
|
71
|
+
{
|
|
72
|
+
href: t,
|
|
73
|
+
className: "hidden md:inline-block bg-black text-white rounded-lg px-5 py-2 text-sm font-medium hover:bg-gray-800 transition-colors",
|
|
74
|
+
children: r
|
|
75
|
+
}
|
|
76
|
+
),
|
|
77
|
+
/* @__PURE__ */ e(
|
|
78
|
+
"button",
|
|
79
|
+
{
|
|
80
|
+
onClick: () => x((i) => !i),
|
|
81
|
+
className: "md:hidden p-2 rounded-md text-gray-600 hover:text-black transition-colors",
|
|
82
|
+
"aria-label": "Toggle menu",
|
|
83
|
+
children: /* @__PURE__ */ e(
|
|
84
|
+
"svg",
|
|
49
85
|
{
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
86
|
+
className: "w-6 h-6",
|
|
87
|
+
fill: "none",
|
|
88
|
+
stroke: "currentColor",
|
|
89
|
+
viewBox: "0 0 24 24",
|
|
90
|
+
children: p ? /* @__PURE__ */ e(
|
|
91
|
+
"path",
|
|
92
|
+
{
|
|
93
|
+
strokeLinecap: "round",
|
|
94
|
+
strokeLinejoin: "round",
|
|
95
|
+
strokeWidth: 2,
|
|
96
|
+
d: "M6 18L18 6M6 6l12 12"
|
|
97
|
+
}
|
|
98
|
+
) : /* @__PURE__ */ e(
|
|
99
|
+
"path",
|
|
100
|
+
{
|
|
101
|
+
strokeLinecap: "round",
|
|
102
|
+
strokeLinejoin: "round",
|
|
103
|
+
strokeWidth: 2,
|
|
104
|
+
d: "M4 6h16M4 12h16M4 18h16"
|
|
105
|
+
}
|
|
106
|
+
)
|
|
54
107
|
}
|
|
55
108
|
)
|
|
56
109
|
}
|
|
57
110
|
)
|
|
111
|
+
] })
|
|
112
|
+
] }) }),
|
|
113
|
+
p && /* @__PURE__ */ l(
|
|
114
|
+
"div",
|
|
115
|
+
{
|
|
116
|
+
className: "md:hidden border-t px-4 pb-4 pt-2 space-y-3",
|
|
117
|
+
style: {
|
|
118
|
+
borderColor: c ? "rgba(255,255,255,0.3)" : "#e5e7eb"
|
|
119
|
+
},
|
|
120
|
+
children: [
|
|
121
|
+
s.map((i, h) => /* @__PURE__ */ e(
|
|
122
|
+
"a",
|
|
123
|
+
{
|
|
124
|
+
href: i.href,
|
|
125
|
+
className: "block text-gray-600 hover:text-black transition-colors",
|
|
126
|
+
children: i.label
|
|
127
|
+
},
|
|
128
|
+
h
|
|
129
|
+
)),
|
|
130
|
+
!c && r && t && /* @__PURE__ */ e(
|
|
131
|
+
"a",
|
|
132
|
+
{
|
|
133
|
+
href: t,
|
|
134
|
+
className: "block text-center bg-black text-white rounded-lg px-5 py-2 text-sm font-medium hover:bg-gray-800 transition-colors",
|
|
135
|
+
children: r
|
|
136
|
+
}
|
|
137
|
+
)
|
|
138
|
+
]
|
|
58
139
|
}
|
|
59
140
|
)
|
|
60
|
-
]
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"a",
|
|
65
|
-
{
|
|
66
|
-
href: r.href,
|
|
67
|
-
className: "block text-gray-600 hover:text-black transition-colors",
|
|
68
|
-
children: r.label
|
|
69
|
-
},
|
|
70
|
-
i
|
|
71
|
-
)),
|
|
72
|
-
l && t && /* @__PURE__ */ e(
|
|
73
|
-
"a",
|
|
74
|
-
{
|
|
75
|
-
href: t,
|
|
76
|
-
className: "block text-center bg-black text-white rounded-lg px-5 py-2 text-sm font-medium hover:bg-gray-800 transition-colors",
|
|
77
|
-
children: l
|
|
78
|
-
}
|
|
79
|
-
)
|
|
80
|
-
] })
|
|
81
|
-
] });
|
|
82
|
-
}, m = {
|
|
141
|
+
]
|
|
142
|
+
}
|
|
143
|
+
);
|
|
144
|
+
}, b = {
|
|
83
145
|
primary: "bg-black text-white rounded-lg px-6 py-3",
|
|
84
146
|
secondary: "bg-transparent border border-black text-black rounded-lg px-6 py-3",
|
|
85
147
|
whatsapp: "bg-[#25D366] text-white rounded-lg px-6 py-3"
|
|
86
|
-
},
|
|
148
|
+
}, v = ({ variant: o = "primary", label: s, onClick: r, className: t = "" }) => /* @__PURE__ */ l(
|
|
87
149
|
"button",
|
|
88
150
|
{
|
|
89
|
-
onClick:
|
|
90
|
-
className: `${
|
|
151
|
+
onClick: r,
|
|
152
|
+
className: `${b[o]} ${t}`,
|
|
91
153
|
children: [
|
|
92
|
-
|
|
93
|
-
|
|
154
|
+
o === "whatsapp" && /* @__PURE__ */ e("span", { children: "💬 " }),
|
|
155
|
+
s
|
|
94
156
|
]
|
|
95
157
|
}
|
|
96
|
-
),
|
|
158
|
+
), u = {
|
|
97
159
|
1: "lg:grid-cols-1",
|
|
98
160
|
2: "lg:grid-cols-2",
|
|
99
161
|
3: "lg:grid-cols-3",
|
|
100
162
|
4: "lg:grid-cols-4",
|
|
101
163
|
5: "lg:grid-cols-5",
|
|
102
164
|
6: "lg:grid-cols-6"
|
|
103
|
-
},
|
|
104
|
-
const [t,
|
|
105
|
-
return /* @__PURE__ */
|
|
165
|
+
}, N = ({ images: o = [], columns: s = 3, gap: r = 4 }) => {
|
|
166
|
+
const [t, n] = g(null);
|
|
167
|
+
return /* @__PURE__ */ l(m, { children: [
|
|
106
168
|
/* @__PURE__ */ e(
|
|
107
169
|
"div",
|
|
108
170
|
{
|
|
109
|
-
className: `grid grid-cols-1 sm:grid-cols-2 ${
|
|
110
|
-
style: { gap: `${
|
|
111
|
-
children:
|
|
171
|
+
className: `grid grid-cols-1 sm:grid-cols-2 ${u[s] || ""}`,
|
|
172
|
+
style: { gap: `${r * 0.25}rem` },
|
|
173
|
+
children: o.map((a, d) => /* @__PURE__ */ e(
|
|
112
174
|
"img",
|
|
113
175
|
{
|
|
114
|
-
src:
|
|
115
|
-
alt:
|
|
176
|
+
src: a.src,
|
|
177
|
+
alt: a.alt,
|
|
116
178
|
className: "w-full h-64 object-cover rounded-lg cursor-pointer",
|
|
117
|
-
onClick: () =>
|
|
179
|
+
onClick: () => n(a)
|
|
118
180
|
},
|
|
119
|
-
|
|
181
|
+
d
|
|
120
182
|
))
|
|
121
183
|
}
|
|
122
184
|
),
|
|
123
|
-
t && /* @__PURE__ */
|
|
185
|
+
t && /* @__PURE__ */ l(
|
|
124
186
|
"div",
|
|
125
187
|
{
|
|
126
188
|
className: "fixed inset-0 z-50 bg-black/80 flex items-center justify-center",
|
|
127
|
-
onClick: () =>
|
|
189
|
+
onClick: () => n(null),
|
|
128
190
|
children: [
|
|
129
191
|
/* @__PURE__ */ e(
|
|
130
192
|
"button",
|
|
131
193
|
{
|
|
132
194
|
className: "absolute top-4 right-4 text-white text-4xl leading-none hover:opacity-70",
|
|
133
|
-
onClick: () =>
|
|
195
|
+
onClick: () => n(null),
|
|
134
196
|
children: "×"
|
|
135
197
|
}
|
|
136
198
|
),
|
|
@@ -140,16 +202,69 @@ const b = ({ logo: a, links: n = [], ctaLabel: l, ctaHref: t }) => {
|
|
|
140
202
|
src: t.src,
|
|
141
203
|
alt: t.alt,
|
|
142
204
|
className: "max-w-[90vw] max-h-[90vh] object-contain rounded-lg",
|
|
143
|
-
onClick: (
|
|
205
|
+
onClick: (a) => a.stopPropagation()
|
|
144
206
|
}
|
|
145
207
|
)
|
|
146
208
|
]
|
|
147
209
|
}
|
|
148
210
|
)
|
|
149
211
|
] });
|
|
212
|
+
}, C = ({
|
|
213
|
+
phoneNumber: o,
|
|
214
|
+
message: s = "Hello, I would like to inquire about your services.",
|
|
215
|
+
bottom: r = "24px",
|
|
216
|
+
right: t = "24px"
|
|
217
|
+
}) => {
|
|
218
|
+
const n = `https://wa.me/${o}?text=${encodeURIComponent(s)}`;
|
|
219
|
+
return /* @__PURE__ */ l(m, { children: [
|
|
220
|
+
/* @__PURE__ */ e("style", { children: `
|
|
221
|
+
@keyframes wa-pulse {
|
|
222
|
+
0%, 100% { box-shadow: 0 0 0 0 rgba(37, 211, 102, 0.5); }
|
|
223
|
+
50% { box-shadow: 0 0 0 12px rgba(37, 211, 102, 0); }
|
|
224
|
+
}
|
|
225
|
+
.wa-btn {
|
|
226
|
+
animation: wa-pulse 2s infinite;
|
|
227
|
+
}
|
|
228
|
+
` }),
|
|
229
|
+
/* @__PURE__ */ e(
|
|
230
|
+
"a",
|
|
231
|
+
{
|
|
232
|
+
href: n,
|
|
233
|
+
target: "_blank",
|
|
234
|
+
rel: "noopener noreferrer",
|
|
235
|
+
className: "wa-btn",
|
|
236
|
+
style: {
|
|
237
|
+
position: "fixed",
|
|
238
|
+
bottom: r,
|
|
239
|
+
right: t,
|
|
240
|
+
width: 56,
|
|
241
|
+
height: 56,
|
|
242
|
+
borderRadius: "50%",
|
|
243
|
+
backgroundColor: "#25D366",
|
|
244
|
+
display: "flex",
|
|
245
|
+
alignItems: "center",
|
|
246
|
+
justifyContent: "center",
|
|
247
|
+
zIndex: 9999,
|
|
248
|
+
cursor: "pointer",
|
|
249
|
+
textDecoration: "none"
|
|
250
|
+
},
|
|
251
|
+
children: /* @__PURE__ */ e(
|
|
252
|
+
"svg",
|
|
253
|
+
{
|
|
254
|
+
viewBox: "0 0 24 24",
|
|
255
|
+
fill: "white",
|
|
256
|
+
width: 28,
|
|
257
|
+
height: 28,
|
|
258
|
+
children: /* @__PURE__ */ e("path", { d: "M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z" })
|
|
259
|
+
}
|
|
260
|
+
)
|
|
261
|
+
}
|
|
262
|
+
)
|
|
263
|
+
] });
|
|
150
264
|
};
|
|
151
265
|
export {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
266
|
+
v as Button,
|
|
267
|
+
N as Gallery,
|
|
268
|
+
w as Navbar,
|
|
269
|
+
C as WhatsAppFloat
|
|
155
270
|
};
|
package/dist/cite-ui.umd.js
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(t,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],e):(t=typeof globalThis<"u"?globalThis:t||self,e(t.CiteUI={},t.ReactJsxRuntime,t.React))})(this,function(t,e,p){"use strict";const b=({logo:s,links:o=[],ctaLabel:l,ctaHref:r,variant:n="default",cartCount:a=0,onCartClick:i})=>{const[g,y]=p.useState(!1),d=n==="glass",v=d?{background:"rgba(255,255,255,0.7)",backdropFilter:"blur(12px)",WebkitBackdropFilter:"blur(12px)",borderBottom:"1px solid rgba(255,255,255,0.3)"}:{};return e.jsxs("nav",{className:`sticky top-0 z-50 ${d?"":"bg-white border-b border-gray-200"}`,style:v,children:[e.jsx("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",children:e.jsxs("div",{className:"flex items-center justify-between h-16 relative",children:[e.jsx("div",{className:"flex-shrink-0 text-xl font-bold tracking-tight",children:s}),e.jsx("div",{className:`items-center gap-8 ${d?"absolute left-1/2 -translate-x-1/2 hidden md:flex":"hidden md:flex"}`,children:o.map((c,h)=>e.jsx("a",{href:c.href,className:"text-gray-600 hover:text-black transition-colors",children:c.label},h))}),e.jsxs("div",{className:"flex items-center gap-4",children:[d?e.jsxs("button",{onClick:i,className:"relative p-2 text-gray-600 hover:text-black transition-colors",children:[e.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 100 4 2 2 0 000-4z"})}),a>0&&e.jsx("span",{className:"absolute -top-1 -right-1 bg-red-500 text-white text-xs w-5 h-5 rounded-full flex items-center justify-center font-medium",children:a})]}):l&&r&&e.jsx("a",{href:r,className:"hidden md:inline-block bg-black text-white rounded-lg px-5 py-2 text-sm font-medium hover:bg-gray-800 transition-colors",children:l}),e.jsx("button",{onClick:()=>y(c=>!c),className:"md:hidden p-2 rounded-md text-gray-600 hover:text-black transition-colors","aria-label":"Toggle menu",children:e.jsx("svg",{className:"w-6 h-6",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:g?e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M6 18L18 6M6 6l12 12"}):e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M4 6h16M4 12h16M4 18h16"})})})]})]})}),g&&e.jsxs("div",{className:"md:hidden border-t px-4 pb-4 pt-2 space-y-3",style:{borderColor:d?"rgba(255,255,255,0.3)":"#e5e7eb"},children:[o.map((c,h)=>e.jsx("a",{href:c.href,className:"block text-gray-600 hover:text-black transition-colors",children:c.label},h)),!d&&l&&r&&e.jsx("a",{href:r,className:"block text-center bg-black text-white rounded-lg px-5 py-2 text-sm font-medium hover:bg-gray-800 transition-colors",children:l})]})]})},x={primary:"bg-black text-white rounded-lg px-6 py-3",secondary:"bg-transparent border border-black text-black rounded-lg px-6 py-3",whatsapp:"bg-[#25D366] text-white rounded-lg px-6 py-3"},f=({variant:s="primary",label:o,onClick:l,className:r=""})=>e.jsxs("button",{onClick:l,className:`${x[s]} ${r}`,children:[s==="whatsapp"&&e.jsx("span",{children:"💬 "}),o]}),m={1:"lg:grid-cols-1",2:"lg:grid-cols-2",3:"lg:grid-cols-3",4:"lg:grid-cols-4",5:"lg:grid-cols-5",6:"lg:grid-cols-6"},u=({images:s=[],columns:o=3,gap:l=4})=>{const[r,n]=p.useState(null);return e.jsxs(e.Fragment,{children:[e.jsx("div",{className:`grid grid-cols-1 sm:grid-cols-2 ${m[o]||""}`,style:{gap:`${l*.25}rem`},children:s.map((a,i)=>e.jsx("img",{src:a.src,alt:a.alt,className:"w-full h-64 object-cover rounded-lg cursor-pointer",onClick:()=>n(a)},i))}),r&&e.jsxs("div",{className:"fixed inset-0 z-50 bg-black/80 flex items-center justify-center",onClick:()=>n(null),children:[e.jsx("button",{className:"absolute top-4 right-4 text-white text-4xl leading-none hover:opacity-70",onClick:()=>n(null),children:"×"}),e.jsx("img",{src:r.src,alt:r.alt,className:"max-w-[90vw] max-h-[90vh] object-contain rounded-lg",onClick:a=>a.stopPropagation()})]})]})},k=({phoneNumber:s,message:o="Hello, I would like to inquire about your services.",bottom:l="24px",right:r="24px"})=>{const n=`https://wa.me/${s}?text=${encodeURIComponent(o)}`;return e.jsxs(e.Fragment,{children:[e.jsx("style",{children:`
|
|
2
|
+
@keyframes wa-pulse {
|
|
3
|
+
0%, 100% { box-shadow: 0 0 0 0 rgba(37, 211, 102, 0.5); }
|
|
4
|
+
50% { box-shadow: 0 0 0 12px rgba(37, 211, 102, 0); }
|
|
5
|
+
}
|
|
6
|
+
.wa-btn {
|
|
7
|
+
animation: wa-pulse 2s infinite;
|
|
8
|
+
}
|
|
9
|
+
`}),e.jsx("a",{href:n,target:"_blank",rel:"noopener noreferrer",className:"wa-btn",style:{position:"fixed",bottom:l,right:r,width:56,height:56,borderRadius:"50%",backgroundColor:"#25D366",display:"flex",alignItems:"center",justifyContent:"center",zIndex:9999,cursor:"pointer",textDecoration:"none"},children:e.jsx("svg",{viewBox:"0 0 24 24",fill:"white",width:28,height:28,children:e.jsx("path",{d:"M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z"})})})]})};t.Button=f,t.Gallery=u,t.Navbar=b,t.WhatsAppFloat=k,Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -1,15 +1,42 @@
|
|
|
1
1
|
import { useState } from 'react'
|
|
2
2
|
|
|
3
|
-
const Navbar = ({
|
|
3
|
+
const Navbar = ({
|
|
4
|
+
logo,
|
|
5
|
+
links = [],
|
|
6
|
+
ctaLabel,
|
|
7
|
+
ctaHref,
|
|
8
|
+
variant = 'default',
|
|
9
|
+
cartCount = 0,
|
|
10
|
+
onCartClick,
|
|
11
|
+
}) => {
|
|
4
12
|
const [open, setOpen] = useState(false)
|
|
13
|
+
const isGlass = variant === 'glass'
|
|
14
|
+
|
|
15
|
+
const glassStyles = isGlass
|
|
16
|
+
? {
|
|
17
|
+
background: 'rgba(255,255,255,0.7)',
|
|
18
|
+
backdropFilter: 'blur(12px)',
|
|
19
|
+
WebkitBackdropFilter: 'blur(12px)',
|
|
20
|
+
borderBottom: '1px solid rgba(255,255,255,0.3)',
|
|
21
|
+
}
|
|
22
|
+
: {}
|
|
5
23
|
|
|
6
24
|
return (
|
|
7
|
-
<nav
|
|
25
|
+
<nav
|
|
26
|
+
className={`sticky top-0 z-50 ${isGlass ? '' : 'bg-white border-b border-gray-200'}`}
|
|
27
|
+
style={glassStyles}
|
|
28
|
+
>
|
|
8
29
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
9
|
-
<div className="flex items-center justify-between h-16">
|
|
10
|
-
<div className="text-xl font-bold tracking-tight">{logo}</div>
|
|
30
|
+
<div className="flex items-center justify-between h-16 relative">
|
|
31
|
+
<div className="flex-shrink-0 text-xl font-bold tracking-tight">{logo}</div>
|
|
11
32
|
|
|
12
|
-
<div
|
|
33
|
+
<div
|
|
34
|
+
className={`items-center gap-8 ${
|
|
35
|
+
isGlass
|
|
36
|
+
? 'absolute left-1/2 -translate-x-1/2 hidden md:flex'
|
|
37
|
+
: 'hidden md:flex'
|
|
38
|
+
}`}
|
|
39
|
+
>
|
|
13
40
|
{links.map((link, i) => (
|
|
14
41
|
<a
|
|
15
42
|
key={i}
|
|
@@ -22,18 +49,45 @@ const Navbar = ({ logo, links = [], ctaLabel, ctaHref }) => {
|
|
|
22
49
|
</div>
|
|
23
50
|
|
|
24
51
|
<div className="flex items-center gap-4">
|
|
25
|
-
{
|
|
26
|
-
<
|
|
27
|
-
|
|
28
|
-
className="
|
|
52
|
+
{isGlass ? (
|
|
53
|
+
<button
|
|
54
|
+
onClick={onCartClick}
|
|
55
|
+
className="relative p-2 text-gray-600 hover:text-black transition-colors"
|
|
29
56
|
>
|
|
30
|
-
|
|
31
|
-
|
|
57
|
+
<svg
|
|
58
|
+
className="w-6 h-6"
|
|
59
|
+
fill="none"
|
|
60
|
+
stroke="currentColor"
|
|
61
|
+
viewBox="0 0 24 24"
|
|
62
|
+
>
|
|
63
|
+
<path
|
|
64
|
+
strokeLinecap="round"
|
|
65
|
+
strokeLinejoin="round"
|
|
66
|
+
strokeWidth={2}
|
|
67
|
+
d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 100 4 2 2 0 000-4z"
|
|
68
|
+
/>
|
|
69
|
+
</svg>
|
|
70
|
+
{cartCount > 0 && (
|
|
71
|
+
<span className="absolute -top-1 -right-1 bg-red-500 text-white text-xs w-5 h-5 rounded-full flex items-center justify-center font-medium">
|
|
72
|
+
{cartCount}
|
|
73
|
+
</span>
|
|
74
|
+
)}
|
|
75
|
+
</button>
|
|
76
|
+
) : (
|
|
77
|
+
ctaLabel &&
|
|
78
|
+
ctaHref && (
|
|
79
|
+
<a
|
|
80
|
+
href={ctaHref}
|
|
81
|
+
className="hidden md:inline-block bg-black text-white rounded-lg px-5 py-2 text-sm font-medium hover:bg-gray-800 transition-colors"
|
|
82
|
+
>
|
|
83
|
+
{ctaLabel}
|
|
84
|
+
</a>
|
|
85
|
+
)
|
|
32
86
|
)}
|
|
33
87
|
|
|
34
88
|
<button
|
|
35
89
|
onClick={() => setOpen((v) => !v)}
|
|
36
|
-
className="md:hidden p-2 rounded-md text-gray-600 hover:text-black"
|
|
90
|
+
className="md:hidden p-2 rounded-md text-gray-600 hover:text-black transition-colors"
|
|
37
91
|
aria-label="Toggle menu"
|
|
38
92
|
>
|
|
39
93
|
<svg
|
|
@@ -64,7 +118,12 @@ const Navbar = ({ logo, links = [], ctaLabel, ctaHref }) => {
|
|
|
64
118
|
</div>
|
|
65
119
|
|
|
66
120
|
{open && (
|
|
67
|
-
<div
|
|
121
|
+
<div
|
|
122
|
+
className="md:hidden border-t px-4 pb-4 pt-2 space-y-3"
|
|
123
|
+
style={{
|
|
124
|
+
borderColor: isGlass ? 'rgba(255,255,255,0.3)' : '#e5e7eb',
|
|
125
|
+
}}
|
|
126
|
+
>
|
|
68
127
|
{links.map((link, i) => (
|
|
69
128
|
<a
|
|
70
129
|
key={i}
|
|
@@ -74,7 +133,7 @@ const Navbar = ({ logo, links = [], ctaLabel, ctaHref }) => {
|
|
|
74
133
|
{link.label}
|
|
75
134
|
</a>
|
|
76
135
|
))}
|
|
77
|
-
{ctaLabel && ctaHref && (
|
|
136
|
+
{!isGlass && ctaLabel && ctaHref && (
|
|
78
137
|
<a
|
|
79
138
|
href={ctaHref}
|
|
80
139
|
className="block text-center bg-black text-white rounded-lg px-5 py-2 text-sm font-medium hover:bg-gray-800 transition-colors"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
const WhatsAppFloat = ({
|
|
2
|
+
phoneNumber,
|
|
3
|
+
message = 'Hello, I would like to inquire about your services.',
|
|
4
|
+
bottom = '24px',
|
|
5
|
+
right = '24px',
|
|
6
|
+
}) => {
|
|
7
|
+
const href = `https://wa.me/${phoneNumber}?text=${encodeURIComponent(message)}`
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<>
|
|
11
|
+
<style>{`
|
|
12
|
+
@keyframes wa-pulse {
|
|
13
|
+
0%, 100% { box-shadow: 0 0 0 0 rgba(37, 211, 102, 0.5); }
|
|
14
|
+
50% { box-shadow: 0 0 0 12px rgba(37, 211, 102, 0); }
|
|
15
|
+
}
|
|
16
|
+
.wa-btn {
|
|
17
|
+
animation: wa-pulse 2s infinite;
|
|
18
|
+
}
|
|
19
|
+
`}</style>
|
|
20
|
+
<a
|
|
21
|
+
href={href}
|
|
22
|
+
target="_blank"
|
|
23
|
+
rel="noopener noreferrer"
|
|
24
|
+
className="wa-btn"
|
|
25
|
+
style={{
|
|
26
|
+
position: 'fixed',
|
|
27
|
+
bottom,
|
|
28
|
+
right,
|
|
29
|
+
width: 56,
|
|
30
|
+
height: 56,
|
|
31
|
+
borderRadius: '50%',
|
|
32
|
+
backgroundColor: '#25D366',
|
|
33
|
+
display: 'flex',
|
|
34
|
+
alignItems: 'center',
|
|
35
|
+
justifyContent: 'center',
|
|
36
|
+
zIndex: 9999,
|
|
37
|
+
cursor: 'pointer',
|
|
38
|
+
textDecoration: 'none',
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
<svg
|
|
42
|
+
viewBox="0 0 24 24"
|
|
43
|
+
fill="white"
|
|
44
|
+
width={28}
|
|
45
|
+
height={28}
|
|
46
|
+
>
|
|
47
|
+
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z" />
|
|
48
|
+
</svg>
|
|
49
|
+
</a>
|
|
50
|
+
</>
|
|
51
|
+
)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default WhatsAppFloat
|
package/src/index.jsx
CHANGED
package/src/main.jsx
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ReactDOM from "react-dom/client";
|
|
3
|
+
import "./styles.css";
|
|
4
|
+
import { Navbar, Button, Gallery, WhatsAppFloat } from "./index";
|
|
5
|
+
|
|
6
|
+
const links = [
|
|
7
|
+
{ label: "Home", href: "#" },
|
|
8
|
+
{ label: "About", href: "#" },
|
|
9
|
+
{ label: "Services", href: "#" },
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
const images = [
|
|
13
|
+
{ src: "https://picsum.photos/seed/a/400/300", alt: "Image 1" },
|
|
14
|
+
{ src: "https://picsum.photos/seed/b/400/300", alt: "Image 2" },
|
|
15
|
+
{ src: "https://picsum.photos/seed/c/400/300", alt: "Image 3" },
|
|
16
|
+
{ src: "https://picsum.photos/seed/d/400/300", alt: "Image 4" },
|
|
17
|
+
{ src: "https://picsum.photos/seed/e/400/300", alt: "Image 5" },
|
|
18
|
+
{ src: "https://picsum.photos/seed/f/400/300", alt: "Image 6" },
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
const Section = ({ title, description, children }) => (
|
|
22
|
+
<div className="px-8 py-16 border-b border-gray-200">
|
|
23
|
+
<div className="max-w-5xl mx-auto">
|
|
24
|
+
<p className="mb-1 text-xs font-semibold tracking-widest text-gray-400 uppercase">
|
|
25
|
+
Component
|
|
26
|
+
</p>
|
|
27
|
+
<h2 className="mb-1 text-2xl font-bold text-gray-900">{title}</h2>
|
|
28
|
+
<p className="mb-10 text-gray-500">{description}</p>
|
|
29
|
+
<div className="p-8 border border-gray-200 bg-gray-50 rounded-xl">
|
|
30
|
+
{children}
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
ReactDOM.createRoot(document.getElementById("root")).render(
|
|
37
|
+
<div className="min-h-screen bg-white">
|
|
38
|
+
{/* Header */}
|
|
39
|
+
<div className="px-8 py-12 text-center border-b border-gray-200">
|
|
40
|
+
<h1 className="text-4xl font-bold tracking-tight text-gray-900">
|
|
41
|
+
cite-ui
|
|
42
|
+
</h1>
|
|
43
|
+
<p className="mt-2 text-gray-500">
|
|
44
|
+
FrameStudio component library — v0.1.2
|
|
45
|
+
</p>
|
|
46
|
+
</div>
|
|
47
|
+
|
|
48
|
+
{/* Navbar */}
|
|
49
|
+
<Section
|
|
50
|
+
title="Navbar"
|
|
51
|
+
description="Two variants — default and glass. Glass includes centered links and cart icon."
|
|
52
|
+
>
|
|
53
|
+
<div className="mb-6 overflow-hidden border border-gray-200 rounded-lg">
|
|
54
|
+
<Navbar
|
|
55
|
+
logo="FrameStudio"
|
|
56
|
+
links={links}
|
|
57
|
+
ctaLabel="Get Started"
|
|
58
|
+
ctaHref="#"
|
|
59
|
+
/>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div
|
|
63
|
+
className="relative overflow-hidden border border-gray-200 rounded-lg"
|
|
64
|
+
style={{
|
|
65
|
+
background: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)",
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
<Navbar
|
|
69
|
+
variant="glass"
|
|
70
|
+
logo="FrameStudio"
|
|
71
|
+
links={links}
|
|
72
|
+
cartCount={3}
|
|
73
|
+
onCartClick={() => alert("Cart clicked")}
|
|
74
|
+
/>
|
|
75
|
+
</div>
|
|
76
|
+
</Section>
|
|
77
|
+
|
|
78
|
+
{/* Button */}
|
|
79
|
+
<Section
|
|
80
|
+
title="Button"
|
|
81
|
+
description="Three variants — primary, secondary, and WhatsApp — all prop-driven."
|
|
82
|
+
>
|
|
83
|
+
<div className="flex flex-wrap gap-4">
|
|
84
|
+
<Button variant="primary" label="Primary" onClick={() => {}} />
|
|
85
|
+
<Button variant="secondary" label="Secondary" onClick={() => {}} />
|
|
86
|
+
<Button variant="whatsapp" label="WhatsApp" onClick={() => {}} />
|
|
87
|
+
</div>
|
|
88
|
+
</Section>
|
|
89
|
+
|
|
90
|
+
{/* Gallery */}
|
|
91
|
+
<Section
|
|
92
|
+
title="Gallery"
|
|
93
|
+
description="Responsive image grid with lightbox on click. Control columns and gap via props."
|
|
94
|
+
>
|
|
95
|
+
<Gallery images={images} columns={3} gap={4} />
|
|
96
|
+
</Section>
|
|
97
|
+
|
|
98
|
+
{/* WhatsAppFloat */}
|
|
99
|
+
<Section
|
|
100
|
+
title="WhatsApp Float"
|
|
101
|
+
description="Fixed floating WhatsApp button with pulse animation. Opens a pre-filled chat."
|
|
102
|
+
>
|
|
103
|
+
<div className="relative h-32 bg-gray-100 rounded-lg">
|
|
104
|
+
<p className="pt-6 text-sm text-center text-gray-400">
|
|
105
|
+
Floating button preview — visible bottom right of screen
|
|
106
|
+
</p>
|
|
107
|
+
</div>
|
|
108
|
+
</Section>
|
|
109
|
+
|
|
110
|
+
<WhatsAppFloat phoneNumber="254712345678" />
|
|
111
|
+
</div>,
|
|
112
|
+
);
|