react-tilt-button 0.0.6
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 +224 -0
- package/dist/react-tilt-button.css +1 -0
- package/dist/react-tilt-button.es.js +424 -0
- package/dist/react-tilt-button.umd.js +6 -0
- package/package.json +63 -0
package/README.md
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# React Tilt Button
|
|
2
|
+
|
|
3
|
+
> A physical, 3D tactile React button component with tilt, squish, and real depth.
|
|
4
|
+
|
|
5
|
+
đź”— **Live Demo:** https://react-tilt-button.vercel.app/
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+
|
|
9
|
+
Features:
|
|
10
|
+
|
|
11
|
+
- Tilts on hover (left / middle / right)
|
|
12
|
+
- Squishes on press
|
|
13
|
+
- Has a visible “side wall” (depth)
|
|
14
|
+
- Enforces physical constraints so it never breaks
|
|
15
|
+
- Supports **predefined style variants**
|
|
16
|
+
- Is fully configurable via props
|
|
17
|
+
|
|
18
|
+
Inspired by `react-awesome-button`, but implemented as a small, dependency-free component.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install react-tilt-button
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```jsx
|
|
29
|
+
import { TiltButton } from 'react-tilt-button';
|
|
30
|
+
import '/node_modules/react-tilt-button/dist/react-tilt-button.css';
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Basic Usage
|
|
36
|
+
|
|
37
|
+
```jsx
|
|
38
|
+
<TiltButton onClick={() => alert('Clicked!')}>Click me</TiltButton>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Using Variants
|
|
44
|
+
|
|
45
|
+
Variants are **predefined visual styles** (material / theme presets).
|
|
46
|
+
|
|
47
|
+
```jsx
|
|
48
|
+
<TiltButton variant="solid">Solid</TiltButton>
|
|
49
|
+
<TiltButton variant="outline">Outline</TiltButton>
|
|
50
|
+
<TiltButton variant="arcade">Arcade</TiltButton>
|
|
51
|
+
<TiltButton variant="carbon">Carbon</TiltButton>
|
|
52
|
+
<TiltButton variant="warning">Warning</TiltButton>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
You can still override any value manually:
|
|
56
|
+
|
|
57
|
+
```jsx
|
|
58
|
+
<TiltButton
|
|
59
|
+
variant='solid'
|
|
60
|
+
surfaceColor='#10b981'
|
|
61
|
+
>
|
|
62
|
+
Custom Green
|
|
63
|
+
</TiltButton>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Demo
|
|
69
|
+
|
|
70
|
+
Try it live here:
|
|
71
|
+
|
|
72
|
+
👉 **https://react-tilt-button.vercel.app/**
|
|
73
|
+
|
|
74
|
+
The demo lets you:
|
|
75
|
+
|
|
76
|
+
- Test all variants
|
|
77
|
+
- Change geometry (depth, radius, tilt, etc.)
|
|
78
|
+
- See physical constraints in action
|
|
79
|
+
- Copy settings for your own usage
|
|
80
|
+
|
|
81
|
+
## Full Example
|
|
82
|
+
|
|
83
|
+
```jsx
|
|
84
|
+
<TiltButton
|
|
85
|
+
variant='arcade'
|
|
86
|
+
width={400}
|
|
87
|
+
height={120}
|
|
88
|
+
elevation={20}
|
|
89
|
+
pressInset={10}
|
|
90
|
+
tilt={4}
|
|
91
|
+
radius={14}
|
|
92
|
+
motion={160}
|
|
93
|
+
>
|
|
94
|
+
My Button
|
|
95
|
+
</TiltButton>
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Physical Constraints (Important)
|
|
101
|
+
|
|
102
|
+
The component automatically clamps values:
|
|
103
|
+
|
|
104
|
+
- `elevation` ≤ `height * 0.3`
|
|
105
|
+
- `pressInset` ≤ `elevation`
|
|
106
|
+
- `tilt` ≤ `elevation / 9`
|
|
107
|
+
- `radius` ≤ `(height - elevation) / 4`
|
|
108
|
+
|
|
109
|
+
So the button:
|
|
110
|
+
|
|
111
|
+
- Never crashes
|
|
112
|
+
- Never inverts
|
|
113
|
+
- Never visually breaks
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Props
|
|
118
|
+
|
|
119
|
+
### Core
|
|
120
|
+
|
|
121
|
+
| Prop | Type | Default |
|
|
122
|
+
| ---------- | --------- | ------- |
|
|
123
|
+
| `children` | ReactNode | — |
|
|
124
|
+
| `onClick` | function | — |
|
|
125
|
+
| `disabled` | boolean | `false` |
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
### Variant
|
|
130
|
+
|
|
131
|
+
| Prop | Type | Default | Description |
|
|
132
|
+
| --------- | ------ | ------- | ------------------------------ |
|
|
133
|
+
| `variant` | string | `solid` | Predefined visual style preset |
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### Geometry
|
|
138
|
+
|
|
139
|
+
| Prop | Type | Default | Notes |
|
|
140
|
+
| ------------ | ---------------- | ------- | ------------------------------ |
|
|
141
|
+
| `width` | number \| string | `260` | No max |
|
|
142
|
+
| `height` | number \| string | `64` | No max |
|
|
143
|
+
| `elevation` | number | `14` | Clamped to `height * 0.3` |
|
|
144
|
+
| `pressInset` | number | `5` | Clamped to `<= elevation` |
|
|
145
|
+
| `tilt` | number | `2` | Clamped to `<= elevation / 9` |
|
|
146
|
+
| `radius` | number | `14` | Clamped to `<= faceHeight / 4` |
|
|
147
|
+
| `motion` | number (ms) | `160` | Animation speed |
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### Colors (Optional Overrides)
|
|
152
|
+
|
|
153
|
+
These override the selected variant.
|
|
154
|
+
|
|
155
|
+
| Prop |
|
|
156
|
+
| -------------- |
|
|
157
|
+
| `surfaceColor` |
|
|
158
|
+
| `sideColor` |
|
|
159
|
+
| `textColor` |
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### Border (Optional Overrides)
|
|
164
|
+
|
|
165
|
+
| Prop |
|
|
166
|
+
| ------------- |
|
|
167
|
+
| `bordered` |
|
|
168
|
+
| `borderColor` |
|
|
169
|
+
| `borderWidth` |
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
### Misc
|
|
174
|
+
|
|
175
|
+
| Prop | Description |
|
|
176
|
+
| ----------- | ------------------------- |
|
|
177
|
+
| `className` | Extra classes |
|
|
178
|
+
| `style` | Merged into inline styles |
|
|
179
|
+
| `...props` | Passed to `<button>` |
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Behavior
|
|
184
|
+
|
|
185
|
+
- Action fires on **mouse release**
|
|
186
|
+
- Hover is split into left / middle / right zones
|
|
187
|
+
- This is a **physical UI primitive**, not a flat semantic button
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
## Styling
|
|
192
|
+
|
|
193
|
+
All visuals are driven by CSS variables:
|
|
194
|
+
|
|
195
|
+
- `--button-raise-level`
|
|
196
|
+
- `--press-inset`
|
|
197
|
+
- `--button-hover-pressure`
|
|
198
|
+
- `--radius`
|
|
199
|
+
- `--surface-color`
|
|
200
|
+
- `--side-color`
|
|
201
|
+
- `--text-color`
|
|
202
|
+
- `--border-color`
|
|
203
|
+
- `--border-width`
|
|
204
|
+
|
|
205
|
+
So you can theme it externally if needed.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Philosophy
|
|
210
|
+
|
|
211
|
+
This is not a flat UI button.
|
|
212
|
+
|
|
213
|
+
It is a **physical, tactile UI primitive** that behaves like an object:
|
|
214
|
+
|
|
215
|
+
- It has depth
|
|
216
|
+
- It deforms
|
|
217
|
+
- It squishes
|
|
218
|
+
- It reacts to pressure
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
Use it. Ship it. Modify it.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.soft-btn{--button-raise-level: 14px;--press-inset: 5px;--button-hover-pressure: 2;--transform-speed: .16s;--radius: 14px;--surface-color: #f3f4f6;--side-color: #d1d5db;--text-color: #111827;--border-color: rgba(0, 0, 0, .35);--border-width: 2px;position:relative;border:none;background:transparent;padding:0;cursor:pointer;-webkit-user-select:none;user-select:none}.soft-btn__wrapper{position:relative;display:block;width:100%;height:100%;transform-style:preserve-3d}.soft-btn__wrapper:before{content:"";position:absolute;left:0;right:0;bottom:0;height:calc(100% - var(--button-raise-level));background:var(--side-color);border-bottom-left-radius:var(--radius);border-bottom-right-radius:var(--radius);border-radius:var(--radius)}.soft-btn__content{position:relative;width:100%;height:calc(100% - var(--button-raise-level));background:var(--surface-color);color:var(--text-color);border-radius:var(--radius);display:flex;align-items:center;justify-content:center;font-size:18px;font-weight:600;transform:translateY(0);transition:transform var(--transform-speed) ease-out;will-change:transform;backface-visibility:hidden;transform-origin:center}.soft-btn__inner{display:inline-flex;align-items:center;gap:10px}.soft-btn--bordered .soft-btn__content{box-shadow:inset 0 0 0 var(--border-width) var(--border-color)}.soft-btn--middle .soft-btn__content{transform:translateY(calc(1px * var(--button-hover-pressure)))}.soft-btn--left .soft-btn__content{transform:skewY(calc(-1deg * var(--button-hover-pressure)))}.soft-btn--right .soft-btn__content{transform:skewY(calc(1deg * var(--button-hover-pressure)))}.soft-btn--active .soft-btn__content{transform:translateY(var(--press-inset));transition:transform calc(var(--transform-speed) * .8) ease-out}.soft-btn--disabled{opacity:.6;pointer-events:none}
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
import me, { useRef as _e, useState as oe } from "react";
|
|
2
|
+
var U = { exports: {} }, S = {};
|
|
3
|
+
var ne;
|
|
4
|
+
function pe() {
|
|
5
|
+
if (ne) return S;
|
|
6
|
+
ne = 1;
|
|
7
|
+
var u = /* @__PURE__ */ Symbol.for("react.transitional.element"), f = /* @__PURE__ */ Symbol.for("react.fragment");
|
|
8
|
+
function a(i, s, c) {
|
|
9
|
+
var d = null;
|
|
10
|
+
if (c !== void 0 && (d = "" + c), s.key !== void 0 && (d = "" + s.key), "key" in s) {
|
|
11
|
+
c = {};
|
|
12
|
+
for (var b in s)
|
|
13
|
+
b !== "key" && (c[b] = s[b]);
|
|
14
|
+
} else c = s;
|
|
15
|
+
return s = c.ref, {
|
|
16
|
+
$$typeof: u,
|
|
17
|
+
type: i,
|
|
18
|
+
key: d,
|
|
19
|
+
ref: s !== void 0 ? s : null,
|
|
20
|
+
props: c
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return S.Fragment = f, S.jsx = a, S.jsxs = a, S;
|
|
24
|
+
}
|
|
25
|
+
var N = {};
|
|
26
|
+
var ae;
|
|
27
|
+
function Ee() {
|
|
28
|
+
return ae || (ae = 1, process.env.NODE_ENV !== "production" && (function() {
|
|
29
|
+
function u(e) {
|
|
30
|
+
if (e == null) return null;
|
|
31
|
+
if (typeof e == "function")
|
|
32
|
+
return e.$$typeof === Q ? null : e.displayName || e.name || null;
|
|
33
|
+
if (typeof e == "string") return e;
|
|
34
|
+
switch (e) {
|
|
35
|
+
case C:
|
|
36
|
+
return "Fragment";
|
|
37
|
+
case T:
|
|
38
|
+
return "Profiler";
|
|
39
|
+
case J:
|
|
40
|
+
return "StrictMode";
|
|
41
|
+
case h:
|
|
42
|
+
return "Suspense";
|
|
43
|
+
case W:
|
|
44
|
+
return "SuspenseList";
|
|
45
|
+
case G:
|
|
46
|
+
return "Activity";
|
|
47
|
+
}
|
|
48
|
+
if (typeof e == "object")
|
|
49
|
+
switch (typeof e.tag == "number" && console.error(
|
|
50
|
+
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
|
|
51
|
+
), e.$$typeof) {
|
|
52
|
+
case q:
|
|
53
|
+
return "Portal";
|
|
54
|
+
case $:
|
|
55
|
+
return e.displayName || "Context";
|
|
56
|
+
case X:
|
|
57
|
+
return (e._context.displayName || "Context") + ".Consumer";
|
|
58
|
+
case z:
|
|
59
|
+
var r = e.render;
|
|
60
|
+
return e = e.displayName, e || (e = r.displayName || r.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e;
|
|
61
|
+
case E:
|
|
62
|
+
return r = e.displayName || null, r !== null ? r : u(e.type) || "Memo";
|
|
63
|
+
case v:
|
|
64
|
+
r = e._payload, e = e._init;
|
|
65
|
+
try {
|
|
66
|
+
return u(e(r));
|
|
67
|
+
} catch {
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
function f(e) {
|
|
73
|
+
return "" + e;
|
|
74
|
+
}
|
|
75
|
+
function a(e) {
|
|
76
|
+
try {
|
|
77
|
+
f(e);
|
|
78
|
+
var r = !1;
|
|
79
|
+
} catch {
|
|
80
|
+
r = !0;
|
|
81
|
+
}
|
|
82
|
+
if (r) {
|
|
83
|
+
r = console;
|
|
84
|
+
var t = r.error, o = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object";
|
|
85
|
+
return t.call(
|
|
86
|
+
r,
|
|
87
|
+
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
|
|
88
|
+
o
|
|
89
|
+
), f(e);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function i(e) {
|
|
93
|
+
if (e === C) return "<>";
|
|
94
|
+
if (typeof e == "object" && e !== null && e.$$typeof === v)
|
|
95
|
+
return "<...>";
|
|
96
|
+
try {
|
|
97
|
+
var r = u(e);
|
|
98
|
+
return r ? "<" + r + ">" : "<...>";
|
|
99
|
+
} catch {
|
|
100
|
+
return "<...>";
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function s() {
|
|
104
|
+
var e = A.A;
|
|
105
|
+
return e === null ? null : e.getOwner();
|
|
106
|
+
}
|
|
107
|
+
function c() {
|
|
108
|
+
return Error("react-stack-top-frame");
|
|
109
|
+
}
|
|
110
|
+
function d(e) {
|
|
111
|
+
if (m.call(e, "key")) {
|
|
112
|
+
var r = Object.getOwnPropertyDescriptor(e, "key").get;
|
|
113
|
+
if (r && r.isReactWarning) return !1;
|
|
114
|
+
}
|
|
115
|
+
return e.key !== void 0;
|
|
116
|
+
}
|
|
117
|
+
function b(e, r) {
|
|
118
|
+
function t() {
|
|
119
|
+
I || (I = !0, console.error(
|
|
120
|
+
"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
|
|
121
|
+
r
|
|
122
|
+
));
|
|
123
|
+
}
|
|
124
|
+
t.isReactWarning = !0, Object.defineProperty(e, "key", {
|
|
125
|
+
get: t,
|
|
126
|
+
configurable: !0
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function x() {
|
|
130
|
+
var e = u(this.type);
|
|
131
|
+
return Y[e] || (Y[e] = !0, console.error(
|
|
132
|
+
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
|
|
133
|
+
)), e = this.props.ref, e !== void 0 ? e : null;
|
|
134
|
+
}
|
|
135
|
+
function _(e, r, t, o, R, w) {
|
|
136
|
+
var n = t.ref;
|
|
137
|
+
return e = {
|
|
138
|
+
$$typeof: M,
|
|
139
|
+
type: e,
|
|
140
|
+
key: r,
|
|
141
|
+
props: t,
|
|
142
|
+
_owner: o
|
|
143
|
+
}, (n !== void 0 ? n : null) !== null ? Object.defineProperty(e, "ref", {
|
|
144
|
+
enumerable: !1,
|
|
145
|
+
get: x
|
|
146
|
+
}) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", {
|
|
147
|
+
configurable: !1,
|
|
148
|
+
enumerable: !1,
|
|
149
|
+
writable: !0,
|
|
150
|
+
value: 0
|
|
151
|
+
}), Object.defineProperty(e, "_debugInfo", {
|
|
152
|
+
configurable: !1,
|
|
153
|
+
enumerable: !1,
|
|
154
|
+
writable: !0,
|
|
155
|
+
value: null
|
|
156
|
+
}), Object.defineProperty(e, "_debugStack", {
|
|
157
|
+
configurable: !1,
|
|
158
|
+
enumerable: !1,
|
|
159
|
+
writable: !0,
|
|
160
|
+
value: R
|
|
161
|
+
}), Object.defineProperty(e, "_debugTask", {
|
|
162
|
+
configurable: !1,
|
|
163
|
+
enumerable: !1,
|
|
164
|
+
writable: !0,
|
|
165
|
+
value: w
|
|
166
|
+
}), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e;
|
|
167
|
+
}
|
|
168
|
+
function P(e, r, t, o, R, w) {
|
|
169
|
+
var n = r.children;
|
|
170
|
+
if (n !== void 0)
|
|
171
|
+
if (o)
|
|
172
|
+
if (H(n)) {
|
|
173
|
+
for (o = 0; o < n.length; o++)
|
|
174
|
+
j(n[o]);
|
|
175
|
+
Object.freeze && Object.freeze(n);
|
|
176
|
+
} else
|
|
177
|
+
console.error(
|
|
178
|
+
"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
|
|
179
|
+
);
|
|
180
|
+
else j(n);
|
|
181
|
+
if (m.call(r, "key")) {
|
|
182
|
+
n = u(e);
|
|
183
|
+
var l = Object.keys(r).filter(function(Z) {
|
|
184
|
+
return Z !== "key";
|
|
185
|
+
});
|
|
186
|
+
o = 0 < l.length ? "{key: someKey, " + l.join(": ..., ") + ": ...}" : "{key: someKey}", L[n + o] || (l = 0 < l.length ? "{" + l.join(": ..., ") + ": ...}" : "{}", console.error(
|
|
187
|
+
`A props object containing a "key" prop is being spread into JSX:
|
|
188
|
+
let props = %s;
|
|
189
|
+
<%s {...props} />
|
|
190
|
+
React keys must be passed directly to JSX without using spread:
|
|
191
|
+
let props = %s;
|
|
192
|
+
<%s key={someKey} {...props} />`,
|
|
193
|
+
o,
|
|
194
|
+
n,
|
|
195
|
+
l,
|
|
196
|
+
n
|
|
197
|
+
), L[n + o] = !0);
|
|
198
|
+
}
|
|
199
|
+
if (n = null, t !== void 0 && (a(t), n = "" + t), d(r) && (a(r.key), n = "" + r.key), "key" in r) {
|
|
200
|
+
t = {};
|
|
201
|
+
for (var O in r)
|
|
202
|
+
O !== "key" && (t[O] = r[O]);
|
|
203
|
+
} else t = r;
|
|
204
|
+
return n && b(
|
|
205
|
+
t,
|
|
206
|
+
typeof e == "function" ? e.displayName || e.name || "Unknown" : e
|
|
207
|
+
), _(
|
|
208
|
+
e,
|
|
209
|
+
n,
|
|
210
|
+
t,
|
|
211
|
+
s(),
|
|
212
|
+
R,
|
|
213
|
+
w
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
function j(e) {
|
|
217
|
+
g(e) ? e._store && (e._store.validated = 1) : typeof e == "object" && e !== null && e.$$typeof === v && (e._payload.status === "fulfilled" ? g(e._payload.value) && e._payload.value._store && (e._payload.value._store.validated = 1) : e._store && (e._store.validated = 1));
|
|
218
|
+
}
|
|
219
|
+
function g(e) {
|
|
220
|
+
return typeof e == "object" && e !== null && e.$$typeof === M;
|
|
221
|
+
}
|
|
222
|
+
var p = me, M = /* @__PURE__ */ Symbol.for("react.transitional.element"), q = /* @__PURE__ */ Symbol.for("react.portal"), C = /* @__PURE__ */ Symbol.for("react.fragment"), J = /* @__PURE__ */ Symbol.for("react.strict_mode"), T = /* @__PURE__ */ Symbol.for("react.profiler"), X = /* @__PURE__ */ Symbol.for("react.consumer"), $ = /* @__PURE__ */ Symbol.for("react.context"), z = /* @__PURE__ */ Symbol.for("react.forward_ref"), h = /* @__PURE__ */ Symbol.for("react.suspense"), W = /* @__PURE__ */ Symbol.for("react.suspense_list"), E = /* @__PURE__ */ Symbol.for("react.memo"), v = /* @__PURE__ */ Symbol.for("react.lazy"), G = /* @__PURE__ */ Symbol.for("react.activity"), Q = /* @__PURE__ */ Symbol.for("react.client.reference"), A = p.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, m = Object.prototype.hasOwnProperty, H = Array.isArray, k = console.createTask ? console.createTask : function() {
|
|
223
|
+
return null;
|
|
224
|
+
};
|
|
225
|
+
p = {
|
|
226
|
+
react_stack_bottom_frame: function(e) {
|
|
227
|
+
return e();
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
var I, Y = {}, D = p.react_stack_bottom_frame.bind(
|
|
231
|
+
p,
|
|
232
|
+
c
|
|
233
|
+
)(), F = k(i(c)), L = {};
|
|
234
|
+
N.Fragment = C, N.jsx = function(e, r, t) {
|
|
235
|
+
var o = 1e4 > A.recentlyCreatedOwnerStacks++;
|
|
236
|
+
return P(
|
|
237
|
+
e,
|
|
238
|
+
r,
|
|
239
|
+
t,
|
|
240
|
+
!1,
|
|
241
|
+
o ? Error("react-stack-top-frame") : D,
|
|
242
|
+
o ? k(i(e)) : F
|
|
243
|
+
);
|
|
244
|
+
}, N.jsxs = function(e, r, t) {
|
|
245
|
+
var o = 1e4 > A.recentlyCreatedOwnerStacks++;
|
|
246
|
+
return P(
|
|
247
|
+
e,
|
|
248
|
+
r,
|
|
249
|
+
t,
|
|
250
|
+
!0,
|
|
251
|
+
o ? Error("react-stack-top-frame") : D,
|
|
252
|
+
o ? k(i(e)) : F
|
|
253
|
+
);
|
|
254
|
+
};
|
|
255
|
+
})()), N;
|
|
256
|
+
}
|
|
257
|
+
var se;
|
|
258
|
+
function ve() {
|
|
259
|
+
return se || (se = 1, process.env.NODE_ENV === "production" ? U.exports = pe() : U.exports = Ee()), U.exports;
|
|
260
|
+
}
|
|
261
|
+
var V = ve();
|
|
262
|
+
const le = {
|
|
263
|
+
solid: {
|
|
264
|
+
surfaceColor: "#3b82f6",
|
|
265
|
+
sideColor: "#1d4ed8",
|
|
266
|
+
textColor: "#ffffff",
|
|
267
|
+
bordered: !1,
|
|
268
|
+
borderColor: "transparent",
|
|
269
|
+
borderWidth: 0
|
|
270
|
+
},
|
|
271
|
+
outline: {
|
|
272
|
+
surfaceColor: "#ffffff",
|
|
273
|
+
sideColor: "#2563eb",
|
|
274
|
+
textColor: "#2563eb",
|
|
275
|
+
bordered: !0,
|
|
276
|
+
borderColor: "#2563eb",
|
|
277
|
+
borderWidth: 3
|
|
278
|
+
},
|
|
279
|
+
dark: {
|
|
280
|
+
surfaceColor: "#181818",
|
|
281
|
+
sideColor: "#494949",
|
|
282
|
+
textColor: "#e5e7eb",
|
|
283
|
+
bordered: !0,
|
|
284
|
+
borderColor: "#5e5e5e",
|
|
285
|
+
borderWidth: 3
|
|
286
|
+
},
|
|
287
|
+
arcade: {
|
|
288
|
+
surfaceColor: "#22b8c7",
|
|
289
|
+
sideColor: "#e5dd4a",
|
|
290
|
+
textColor: "#fef08a",
|
|
291
|
+
bordered: !0,
|
|
292
|
+
borderColor: "#fef08a",
|
|
293
|
+
borderWidth: 3
|
|
294
|
+
},
|
|
295
|
+
gum: {
|
|
296
|
+
surfaceColor: "#f472b6",
|
|
297
|
+
sideColor: "#db2777",
|
|
298
|
+
textColor: "#ffffff",
|
|
299
|
+
bordered: !1,
|
|
300
|
+
borderColor: "transparent",
|
|
301
|
+
borderWidth: 0
|
|
302
|
+
},
|
|
303
|
+
carbon: {
|
|
304
|
+
surfaceColor: "#2a2a37",
|
|
305
|
+
sideColor: "#8b5e3c",
|
|
306
|
+
textColor: "#c4a484",
|
|
307
|
+
bordered: !0,
|
|
308
|
+
borderColor: "#8b5f39",
|
|
309
|
+
borderWidth: 4
|
|
310
|
+
},
|
|
311
|
+
warning: {
|
|
312
|
+
surfaceColor: "#2c2c39",
|
|
313
|
+
sideColor: "#b22b3b",
|
|
314
|
+
textColor: "#fff7ed",
|
|
315
|
+
bordered: !0,
|
|
316
|
+
borderColor: "#d9445b",
|
|
317
|
+
borderWidth: 4
|
|
318
|
+
},
|
|
319
|
+
steel: {
|
|
320
|
+
surfaceColor: "#cbd5e1",
|
|
321
|
+
sideColor: "#64748b",
|
|
322
|
+
textColor: "#020617",
|
|
323
|
+
bordered: !0,
|
|
324
|
+
borderColor: "#475569",
|
|
325
|
+
borderWidth: 2
|
|
326
|
+
},
|
|
327
|
+
gold: {
|
|
328
|
+
surfaceColor: "#ffcf10",
|
|
329
|
+
sideColor: "#d29000",
|
|
330
|
+
textColor: "#422006",
|
|
331
|
+
bordered: !0,
|
|
332
|
+
borderColor: "#fff0a8",
|
|
333
|
+
borderWidth: 2
|
|
334
|
+
},
|
|
335
|
+
lavender: {
|
|
336
|
+
surfaceColor: "#cec3fd",
|
|
337
|
+
sideColor: "#b489ff",
|
|
338
|
+
textColor: "#2e1065",
|
|
339
|
+
bordered: !1,
|
|
340
|
+
borderColor: "#a36eff",
|
|
341
|
+
borderWidth: 4
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
function B(u, f, a) {
|
|
345
|
+
return Math.max(f, Math.min(a, u));
|
|
346
|
+
}
|
|
347
|
+
function Te({
|
|
348
|
+
children: u,
|
|
349
|
+
onClick: f,
|
|
350
|
+
disabled: a = !1,
|
|
351
|
+
variant: i = "solid",
|
|
352
|
+
elevation: s = 14,
|
|
353
|
+
pressInset: c = 5,
|
|
354
|
+
tilt: d = 2,
|
|
355
|
+
motion: b = 160,
|
|
356
|
+
width: x = 260,
|
|
357
|
+
height: _ = 64,
|
|
358
|
+
radius: P = 14,
|
|
359
|
+
surfaceColor: j,
|
|
360
|
+
sideColor: g,
|
|
361
|
+
textColor: p,
|
|
362
|
+
bordered: M,
|
|
363
|
+
borderColor: q,
|
|
364
|
+
borderWidth: C,
|
|
365
|
+
className: J = "",
|
|
366
|
+
style: T,
|
|
367
|
+
...X
|
|
368
|
+
}) {
|
|
369
|
+
const $ = _e(null), [z, h] = oe(!1), [W, E] = oe(null), v = Math.max(0, Number(_) || 0), G = Math.max(0, Number(s) || 0), A = v * 0.3, m = B(G, 0, A), H = Math.max(0, Number(c) || 0), k = B(H, 0, m), I = Math.max(0, Number(d) || 0), Y = Number((m / 9).toFixed(2)), D = B(I, 0, Y), F = v - m, L = Math.max(0, Math.floor(F / 4)), e = Math.max(0, Number(P) || 0), r = B(e, 0, L), t = Math.max(0, Number(b) || 0), o = (y) => {
|
|
370
|
+
if (a) return;
|
|
371
|
+
const K = $.current;
|
|
372
|
+
if (!K) return;
|
|
373
|
+
const ee = K.getBoundingClientRect(), re = y.clientX - ee.left, te = ee.width || 1;
|
|
374
|
+
re < te * 0.33 ? E("left") : re > te * 0.66 ? E("right") : E("middle");
|
|
375
|
+
}, R = () => {
|
|
376
|
+
E(null), h(!1);
|
|
377
|
+
}, w = (y) => {
|
|
378
|
+
a || y.button === 0 && h(!0);
|
|
379
|
+
}, n = (y) => {
|
|
380
|
+
a || (h(!1), f && f(y));
|
|
381
|
+
}, l = le[i] || le.solid, O = j ?? l.surfaceColor, Z = g ?? l.sideColor, ce = p ?? l.textColor, ue = M ?? l.bordered, fe = q ?? l.borderColor, ie = C ?? l.borderWidth, de = {
|
|
382
|
+
...{
|
|
383
|
+
"--button-raise-level": `${m}px`,
|
|
384
|
+
"--press-inset": `${k}px`,
|
|
385
|
+
"--button-hover-pressure": D,
|
|
386
|
+
"--transform-speed": `${t}ms`,
|
|
387
|
+
"--radius": `${r}px`,
|
|
388
|
+
"--surface-color": O,
|
|
389
|
+
"--side-color": Z,
|
|
390
|
+
"--text-color": ce,
|
|
391
|
+
"--border-color": fe,
|
|
392
|
+
"--border-width": `${ie}px`,
|
|
393
|
+
width: typeof x == "number" ? `${x}px` : x,
|
|
394
|
+
height: typeof _ == "number" ? `${_}px` : _
|
|
395
|
+
},
|
|
396
|
+
...T && typeof T == "object" ? T : {}
|
|
397
|
+
}, be = [
|
|
398
|
+
"soft-btn",
|
|
399
|
+
z && "soft-btn--active",
|
|
400
|
+
W && `soft-btn--${W}`,
|
|
401
|
+
a && "soft-btn--disabled",
|
|
402
|
+
ue && "soft-btn--bordered",
|
|
403
|
+
J
|
|
404
|
+
].filter(Boolean).join(" ");
|
|
405
|
+
return /* @__PURE__ */ V.jsx(
|
|
406
|
+
"button",
|
|
407
|
+
{
|
|
408
|
+
...X,
|
|
409
|
+
ref: $,
|
|
410
|
+
className: be,
|
|
411
|
+
style: de,
|
|
412
|
+
onMouseMove: o,
|
|
413
|
+
onMouseLeave: R,
|
|
414
|
+
onMouseDown: w,
|
|
415
|
+
onMouseUp: n,
|
|
416
|
+
disabled: a,
|
|
417
|
+
children: /* @__PURE__ */ V.jsx("span", { className: "soft-btn__wrapper", children: /* @__PURE__ */ V.jsx("span", { className: "soft-btn__content", children: /* @__PURE__ */ V.jsx("span", { className: "soft-btn__inner", children: u }) }) })
|
|
418
|
+
}
|
|
419
|
+
);
|
|
420
|
+
}
|
|
421
|
+
export {
|
|
422
|
+
Te as TiltButton,
|
|
423
|
+
le as TiltButtonVariants
|
|
424
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
(function(i,d){typeof exports=="object"&&typeof module<"u"?d(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],d):(i=typeof globalThis<"u"?globalThis:i||self,d(i["react-tilt-button"]={},i.React))})(this,(function(i,d){"use strict";var g={exports:{}},C={};var re;function ue(){if(re)return C;re=1;var u=Symbol.for("react.transitional.element"),f=Symbol.for("react.fragment");function a(b,s,c){var m=null;if(c!==void 0&&(m=""+c),s.key!==void 0&&(m=""+s.key),"key"in s){c={};for(var p in s)p!=="key"&&(c[p]=s[p])}else c=s;return s=c.ref,{$$typeof:u,type:b,key:m,ref:s!==void 0?s:null,props:c}}return C.Fragment=f,C.jsx=a,C.jsxs=a,C}var h={};var te;function fe(){return te||(te=1,process.env.NODE_ENV!=="production"&&(function(){function u(e){if(e==null)return null;if(typeof e=="function")return e.$$typeof===ne?null:e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case y:return"Fragment";case O:return"Profiler";case q:return"StrictMode";case S:return"Suspense";case L:return"SuspenseList";case Q:return"Activity"}if(typeof e=="object")switch(typeof e.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),e.$$typeof){case G:return"Portal";case F:return e.displayName||"Context";case H:return(e._context.displayName||"Context")+".Consumer";case Z:var r=e.render;return e=e.displayName,e||(e=r.displayName||r.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case R:return r=e.displayName||null,r!==null?r:u(e.type)||"Memo";case T:r=e._payload,e=e._init;try{return u(e(r))}catch{}}return null}function f(e){return""+e}function a(e){try{f(e);var r=!1}catch{r=!0}if(r){r=console;var t=r.error,o=typeof Symbol=="function"&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object";return t.call(r,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",o),f(e)}}function b(e){if(e===y)return"<>";if(typeof e=="object"&&e!==null&&e.$$typeof===T)return"<...>";try{var r=u(e);return r?"<"+r+">":"<...>"}catch{return"<...>"}}function s(){var e=k.A;return e===null?null:e.getOwner()}function c(){return Error("react-stack-top-frame")}function m(e){if(_.call(e,"key")){var r=Object.getOwnPropertyDescriptor(e,"key").get;if(r&&r.isReactWarning)return!1}return e.key!==void 0}function p(e,r){function t(){U||(U=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",r))}t.isReactWarning=!0,Object.defineProperty(e,"key",{get:t,configurable:!0})}function A(){var e=u(this.type);return V[e]||(V[e]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),e=this.props.ref,e!==void 0?e:null}function v(e,r,t,o,x,N){var n=t.ref;return e={$$typeof:D,type:e,key:r,props:t,_owner:o},(n!==void 0?n:null)!==null?Object.defineProperty(e,"ref",{enumerable:!1,get:A}):Object.defineProperty(e,"ref",{enumerable:!1,value:null}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:x}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:N}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function I(e,r,t,o,x,N){var n=r.children;if(n!==void 0)if(o)if(K(n)){for(o=0;o<n.length;o++)Y(n[o]);Object.freeze&&Object.freeze(n)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else Y(n);if(_.call(r,"key")){n=u(e);var l=Object.keys(r).filter(function(ee){return ee!=="key"});o=0<l.length?"{key: someKey, "+l.join(": ..., ")+": ...}":"{key: someKey}",X[n+o]||(l=0<l.length?"{"+l.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
|
|
2
|
+
let props = %s;
|
|
3
|
+
<%s {...props} />
|
|
4
|
+
React keys must be passed directly to JSX without using spread:
|
|
5
|
+
let props = %s;
|
|
6
|
+
<%s key={someKey} {...props} />`,o,n,l,n),X[n+o]=!0)}if(n=null,t!==void 0&&(a(t),n=""+t),m(r)&&(a(r.key),n=""+r.key),"key"in r){t={};for(var P in r)P!=="key"&&(t[P]=r[P])}else t=r;return n&&p(t,typeof e=="function"?e.displayName||e.name||"Unknown":e),v(e,n,t,s(),x,N)}function Y(e){$(e)?e._store&&(e._store.validated=1):typeof e=="object"&&e!==null&&e.$$typeof===T&&(e._payload.status==="fulfilled"?$(e._payload.value)&&e._payload.value._store&&(e._payload.value._store.validated=1):e._store&&(e._store.validated=1))}function $(e){return typeof e=="object"&&e!==null&&e.$$typeof===D}var E=d,D=Symbol.for("react.transitional.element"),G=Symbol.for("react.portal"),y=Symbol.for("react.fragment"),q=Symbol.for("react.strict_mode"),O=Symbol.for("react.profiler"),H=Symbol.for("react.consumer"),F=Symbol.for("react.context"),Z=Symbol.for("react.forward_ref"),S=Symbol.for("react.suspense"),L=Symbol.for("react.suspense_list"),R=Symbol.for("react.memo"),T=Symbol.for("react.lazy"),Q=Symbol.for("react.activity"),ne=Symbol.for("react.client.reference"),k=E.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,_=Object.prototype.hasOwnProperty,K=Array.isArray,w=console.createTask?console.createTask:function(){return null};E={react_stack_bottom_frame:function(e){return e()}};var U,V={},B=E.react_stack_bottom_frame.bind(E,c)(),J=w(b(c)),X={};h.Fragment=y,h.jsx=function(e,r,t){var o=1e4>k.recentlyCreatedOwnerStacks++;return I(e,r,t,!1,o?Error("react-stack-top-frame"):B,o?w(b(e)):J)},h.jsxs=function(e,r,t){var o=1e4>k.recentlyCreatedOwnerStacks++;return I(e,r,t,!0,o?Error("react-stack-top-frame"):B,o?w(b(e)):J)}})()),h}var oe;function ie(){return oe||(oe=1,process.env.NODE_ENV==="production"?g.exports=ue():g.exports=fe()),g.exports}var M=ie();const z={solid:{surfaceColor:"#3b82f6",sideColor:"#1d4ed8",textColor:"#ffffff",bordered:!1,borderColor:"transparent",borderWidth:0},outline:{surfaceColor:"#ffffff",sideColor:"#2563eb",textColor:"#2563eb",bordered:!0,borderColor:"#2563eb",borderWidth:3},dark:{surfaceColor:"#181818",sideColor:"#494949",textColor:"#e5e7eb",bordered:!0,borderColor:"#5e5e5e",borderWidth:3},arcade:{surfaceColor:"#22b8c7",sideColor:"#e5dd4a",textColor:"#fef08a",bordered:!0,borderColor:"#fef08a",borderWidth:3},gum:{surfaceColor:"#f472b6",sideColor:"#db2777",textColor:"#ffffff",bordered:!1,borderColor:"transparent",borderWidth:0},carbon:{surfaceColor:"#2a2a37",sideColor:"#8b5e3c",textColor:"#c4a484",bordered:!0,borderColor:"#8b5f39",borderWidth:4},warning:{surfaceColor:"#2c2c39",sideColor:"#b22b3b",textColor:"#fff7ed",bordered:!0,borderColor:"#d9445b",borderWidth:4},steel:{surfaceColor:"#cbd5e1",sideColor:"#64748b",textColor:"#020617",bordered:!0,borderColor:"#475569",borderWidth:2},gold:{surfaceColor:"#ffcf10",sideColor:"#d29000",textColor:"#422006",bordered:!0,borderColor:"#fff0a8",borderWidth:2},lavender:{surfaceColor:"#cec3fd",sideColor:"#b489ff",textColor:"#2e1065",bordered:!1,borderColor:"#a36eff",borderWidth:4}};function W(u,f,a){return Math.max(f,Math.min(a,u))}function de({children:u,onClick:f,disabled:a=!1,variant:b="solid",elevation:s=14,pressInset:c=5,tilt:m=2,motion:p=160,width:A=260,height:v=64,radius:I=14,surfaceColor:Y,sideColor:$,textColor:E,bordered:D,borderColor:G,borderWidth:y,className:q="",style:O,...H}){const F=d.useRef(null),[Z,S]=d.useState(!1),[L,R]=d.useState(null),T=Math.max(0,Number(v)||0),Q=Math.max(0,Number(s)||0),k=T*.3,_=W(Q,0,k),K=Math.max(0,Number(c)||0),w=W(K,0,_),U=Math.max(0,Number(m)||0),V=Number((_/9).toFixed(2)),B=W(U,0,V),J=T-_,X=Math.max(0,Math.floor(J/4)),e=Math.max(0,Number(I)||0),r=W(e,0,X),t=Math.max(0,Number(p)||0),o=j=>{if(a)return;const ae=F.current;if(!ae)return;const se=ae.getBoundingClientRect(),le=j.clientX-se.left,ce=se.width||1;le<ce*.33?R("left"):le>ce*.66?R("right"):R("middle")},x=()=>{R(null),S(!1)},N=j=>{a||j.button===0&&S(!0)},n=j=>{a||(S(!1),f&&f(j))},l=z[b]||z.solid,P=Y??l.surfaceColor,ee=$??l.sideColor,be=E??l.textColor,me=D??l.bordered,pe=G??l.borderColor,_e=y??l.borderWidth,ve={...{"--button-raise-level":`${_}px`,"--press-inset":`${w}px`,"--button-hover-pressure":B,"--transform-speed":`${t}ms`,"--radius":`${r}px`,"--surface-color":P,"--side-color":ee,"--text-color":be,"--border-color":pe,"--border-width":`${_e}px`,width:typeof A=="number"?`${A}px`:A,height:typeof v=="number"?`${v}px`:v},...O&&typeof O=="object"?O:{}},Ee=["soft-btn",Z&&"soft-btn--active",L&&`soft-btn--${L}`,a&&"soft-btn--disabled",me&&"soft-btn--bordered",q].filter(Boolean).join(" ");return M.jsx("button",{...H,ref:F,className:Ee,style:ve,onMouseMove:o,onMouseLeave:x,onMouseDown:N,onMouseUp:n,disabled:a,children:M.jsx("span",{className:"soft-btn__wrapper",children:M.jsx("span",{className:"soft-btn__content",children:M.jsx("span",{className:"soft-btn__inner",children:u})})})})}i.TiltButton=de,i.TiltButtonVariants=z,Object.defineProperty(i,Symbol.toStringTag,{value:"Module"})}));
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-tilt-button",
|
|
3
|
+
"version": "0.0.6",
|
|
4
|
+
"description": "",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "archisvaze",
|
|
7
|
+
"keywords": [],
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"main": "./dist/react-tilt-button.umd.js",
|
|
13
|
+
"module": "./dist/react-tilt-button.es.js",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": "./dist/react-tilt-button.es.js",
|
|
17
|
+
"require": "./dist/react-tilt-button.umd.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"dev": "vite",
|
|
22
|
+
"build": "vite build",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"watch": "vitest",
|
|
25
|
+
"coverage": "vitest run --coverage"
|
|
26
|
+
},
|
|
27
|
+
"browserslist": {
|
|
28
|
+
"production": [
|
|
29
|
+
">0.2%",
|
|
30
|
+
"not dead",
|
|
31
|
+
"not op_mini all"
|
|
32
|
+
],
|
|
33
|
+
"development": [
|
|
34
|
+
"last 1 chrome version",
|
|
35
|
+
"last 1 firefox version",
|
|
36
|
+
"last 1 safari version"
|
|
37
|
+
]
|
|
38
|
+
},
|
|
39
|
+
"eslintConfig": {
|
|
40
|
+
"env": {
|
|
41
|
+
"browser": true,
|
|
42
|
+
"node": true,
|
|
43
|
+
"es2020": true
|
|
44
|
+
},
|
|
45
|
+
"extends": [
|
|
46
|
+
"eslint:recommended",
|
|
47
|
+
"plugin:react/recommended"
|
|
48
|
+
],
|
|
49
|
+
"parserOptions": {
|
|
50
|
+
"sourceType": "module"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
55
|
+
"react": "^19.2.3",
|
|
56
|
+
"react-dom": "^19.2.3",
|
|
57
|
+
"vite": "^7.3.1"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"react": "^19.2.3",
|
|
61
|
+
"react-dom": "^19.2.3"
|
|
62
|
+
}
|
|
63
|
+
}
|