@roy-ui/ui 0.0.3 → 0.0.5
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 +34 -16
- package/dist/TreeNav-22DY7TP5.css +135 -0
- package/dist/index.d.ts +28 -2
- package/dist/index.js +95 -3
- package/dist/index.js.map +1 -1
- package/package.json +91 -2
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# @roy-ui/ui
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Animated React components. Drop in, ship.
|
|
4
|
+
> TypeScript · RSC-safe · tree-shakable · under 12 KB.
|
|
4
5
|
|
|
5
6
|
[](https://www.npmjs.com/package/@roy-ui/ui)
|
|
6
7
|
[](https://www.npmjs.com/package/@roy-ui/ui)
|
|
@@ -8,19 +9,28 @@
|
|
|
8
9
|
[](https://www.npmjs.com/package/@roy-ui/ui)
|
|
9
10
|
[](https://github.com/DibbayajyotiRoy/RoyUI/blob/main/LICENSE)
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
<a href="https://github.com/DibbayajyotiRoy/RoyUI/blob/main/apps/docs/lib/demo/linkedin2.mp4">
|
|
13
|
+
<img
|
|
14
|
+
src="https://raw.githubusercontent.com/DibbayajyotiRoy/RoyUI/main/apps/docs/lib/demo/demo.gif"
|
|
15
|
+
alt="Roy UI components demo — gradient button, popover, text morph, made-by badge"
|
|
16
|
+
width="720" />
|
|
17
|
+
</a>
|
|
18
|
+
|
|
19
|
+
<sub>Click the GIF for the full-quality video.</sub>
|
|
12
20
|
|
|
13
21
|
---
|
|
14
22
|
|
|
15
23
|
## What is it?
|
|
16
24
|
|
|
17
|
-
`@roy-ui/ui` is an open-source React component library focused on animated, micro-interactive UI
|
|
25
|
+
`@roy-ui/ui` is an **open-source React component library** focused on **animated, micro-interactive UI components** — animated gradient buttons, accessible popovers, text-morph typing effects, tree navigation, and attribution badges — written in **TypeScript**, shipped as **tree-shakable ESM**, and fully compatible with **React Server Components**, **Next.js 15 App Router**, **Vite**, **Remix**, **Astro**, **TanStack Start**, and any modern React 18+ runtime.
|
|
18
26
|
|
|
19
|
-
- **Zero runtime config** — install, import, render.
|
|
20
|
-
- **
|
|
21
|
-
- **Self-contained CSS** — no Tailwind plugin, no PostCSS, no theme provider.
|
|
22
|
-
- **RSC-safe** — components are correctly marked `"use client"` inside the bundle.
|
|
23
|
-
- **Tiny** — the whole library is under 12 KB minified + gzipped.
|
|
27
|
+
- **Zero runtime config** — install, import, render. No CLI, no copy-paste, no Tailwind plugin.
|
|
28
|
+
- **TypeScript-first** — tree-shakable ESM with first-class `.d.ts` types and source maps.
|
|
29
|
+
- **Self-contained CSS** — no Tailwind plugin, no PostCSS, no theme provider, no design tokens to wire up.
|
|
30
|
+
- **RSC-safe (React Server Components-safe)** — components are correctly marked `"use client"` inside the bundle, so you can import directly from a Next.js App Router server component.
|
|
31
|
+
- **Tiny** — the whole library is under **12 KB** minified + gzipped, smaller than most single-component installs.
|
|
32
|
+
- **Animation built in** — no Framer Motion / motion-react setup required.
|
|
33
|
+
- **Framework-agnostic** — Next.js, Vite, Remix, Astro, TanStack Start, CRA, any ESM bundler.
|
|
24
34
|
|
|
25
35
|
## Install
|
|
26
36
|
|
|
@@ -80,15 +90,19 @@ Using the **Next.js App Router**? Import directly from a Server Component — th
|
|
|
80
90
|
| **`TextMorph`** | Character-by-character text diff animation. Great for live counters, currency tickers, and status text. |
|
|
81
91
|
| **`MadeBy`** | Floating "Made by ___" attribution badge with corner positioning. |
|
|
82
92
|
|
|
83
|
-
## Why use this?
|
|
93
|
+
## Why use this? (shadcn / Aceternity / Magic UI / MUI / Radix comparison)
|
|
94
|
+
|
|
95
|
+
| | `@roy-ui/ui` | shadcn/ui | Aceternity UI / Magic UI | Radix / Headless UI | MUI |
|
|
96
|
+
| --- | --- | --- | --- | --- | --- |
|
|
97
|
+
| Single `npm install` (no CLI, no copy) | Yes | No | No | Yes | Yes |
|
|
98
|
+
| Ships visual styles | Yes | Yes | Yes | No | Yes |
|
|
99
|
+
| RSC-safe out of the box | Yes | Yes | Manual | Manual | Manual |
|
|
100
|
+
| Tailwind required | No | Yes | Yes | No | No |
|
|
101
|
+
| Framer Motion required | No | No | Yes | No | No |
|
|
102
|
+
| Animation built in | Yes | Sometimes | Yes | No | Sometimes |
|
|
103
|
+
| Sub-12 KB total bundle | Yes | n/a | Per-component | Varies | No |
|
|
84
104
|
|
|
85
|
-
|
|
86
|
-
| --- | --- | --- | --- |
|
|
87
|
-
| Ships visual styles | Yes | No | Yes (copy-paste) |
|
|
88
|
-
| One install (no CLI, no copy) | Yes | Yes | No |
|
|
89
|
-
| RSC-safe out of the box | Yes | Manual | Yes |
|
|
90
|
-
| Tailwind required | No | No | Yes |
|
|
91
|
-
| Animation built in | Yes | No | Sometimes |
|
|
105
|
+
If you want unstyled accessibility primitives, use **Radix** or **React Aria**. If you want Tailwind components you copy-paste, use **shadcn/ui**. If you want marketing-page hero effects, use **Aceternity UI** or **Magic UI**. If you want a **small, drop-in set of animated React components with zero setup**, use **`@roy-ui/ui`**.
|
|
92
106
|
|
|
93
107
|
## Links
|
|
94
108
|
|
|
@@ -100,3 +114,7 @@ Using the **Next.js App Router**? Import directly from a Server Component — th
|
|
|
100
114
|
## License
|
|
101
115
|
|
|
102
116
|
[MIT](https://github.com/DibbayajyotiRoy/RoyUI/blob/main/LICENSE) © [Dibbayajyoti Roy](https://github.com/DibbayajyotiRoy)
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
<sub>**Topics:** React component library · React UI library · React UI kit · TypeScript React components · Next.js 15 components · Next.js App Router · React Server Components · RSC-safe · animated React components · React animation library · micro-interactions · tree-shakable ESM · zero-config React UI · tiny React UI · sub-12 KB · gradient button · animated gradient button · React popover · text morph · typing animation · React tree navigation · React sidebar nav · made by attribution badge · headless UI · accessible · WAI-ARIA · a11y · shadcn alternative · shadcn/ui alternative · Aceternity UI alternative · Magic UI alternative · MUI alternative · Material UI alternative · Radix alternative · HeroUI alternative · Mantine alternative · Chakra UI alternative · DaisyUI alternative · Tailwind-friendly · Vite · Remix · Astro · TanStack Start · React 18 · React 19 · MIT · open source · free.</sub>
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
.royui-treenav {
|
|
2
|
+
/* Theme tokens — override on .royui-treenav or :root for global retheme. */
|
|
3
|
+
--royui-treenav-branch: rgba(0, 0, 0, 0.28);
|
|
4
|
+
--royui-treenav-branch-active: rgba(0, 0, 0, 0.65);
|
|
5
|
+
|
|
6
|
+
--royui-treenav-label: rgba(0, 0, 0, 0.6);
|
|
7
|
+
--royui-treenav-label-hover: rgba(0, 0, 0, 0.92);
|
|
8
|
+
--royui-treenav-label-active: rgba(0, 0, 0, 1);
|
|
9
|
+
--royui-treenav-hover-bg: rgba(0, 0, 0, 0.04);
|
|
10
|
+
--royui-treenav-active-bg: rgba(0, 0, 0, 0.06);
|
|
11
|
+
|
|
12
|
+
--royui-treenav-font:
|
|
13
|
+
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial,
|
|
14
|
+
sans-serif;
|
|
15
|
+
--royui-treenav-font-size: 13px;
|
|
16
|
+
--royui-treenav-font-weight: 500;
|
|
17
|
+
--royui-treenav-font-weight-active: 600;
|
|
18
|
+
--royui-treenav-ease: cubic-bezier(0.22, 0.61, 0.36, 1);
|
|
19
|
+
|
|
20
|
+
position: relative;
|
|
21
|
+
margin: 0;
|
|
22
|
+
padding: 0;
|
|
23
|
+
padding-top: 4px;
|
|
24
|
+
margin-left: var(--royui-treenav-indent, 24px);
|
|
25
|
+
list-style: none;
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-direction: column;
|
|
28
|
+
gap: var(--royui-treenav-gap, 2px);
|
|
29
|
+
font-family: var(--royui-treenav-font);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@media (prefers-color-scheme: dark) {
|
|
33
|
+
.royui-treenav {
|
|
34
|
+
--royui-treenav-branch: rgba(255, 255, 255, 0.3);
|
|
35
|
+
--royui-treenav-branch-active: rgba(255, 255, 255, 0.65);
|
|
36
|
+
--royui-treenav-label: rgba(255, 255, 255, 0.6);
|
|
37
|
+
--royui-treenav-label-hover: rgba(255, 255, 255, 0.92);
|
|
38
|
+
--royui-treenav-label-active: rgba(255, 255, 255, 1);
|
|
39
|
+
--royui-treenav-hover-bg: rgba(255, 255, 255, 0.05);
|
|
40
|
+
--royui-treenav-active-bg: rgba(255, 255, 255, 0.07);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.royui-treenav__item {
|
|
45
|
+
position: relative;
|
|
46
|
+
list-style: none;
|
|
47
|
+
margin: 0;
|
|
48
|
+
padding: 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/* Bent-arrow connector — single SVG, single filled path. The L line and the
|
|
52
|
+
arrowhead share one closed outline, so they can never read as two shapes. */
|
|
53
|
+
.royui-treenav__connector {
|
|
54
|
+
position: absolute;
|
|
55
|
+
left: -2px;
|
|
56
|
+
top: 0;
|
|
57
|
+
width: 20px;
|
|
58
|
+
height: 100%;
|
|
59
|
+
color: var(--royui-treenav-branch);
|
|
60
|
+
transition: color 0.2s var(--royui-treenav-ease);
|
|
61
|
+
pointer-events: none;
|
|
62
|
+
z-index: 1;
|
|
63
|
+
overflow: visible;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* Active state — :has() on the LI keeps the rule order-independent and
|
|
67
|
+
works with any router that sets aria-current="page" on the inner link. */
|
|
68
|
+
.royui-treenav__item:has(.royui-treenav__link[aria-current='page'])
|
|
69
|
+
.royui-treenav__connector {
|
|
70
|
+
color: var(--royui-treenav-branch-active);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/* Link / anchor row */
|
|
74
|
+
.royui-treenav__link {
|
|
75
|
+
position: relative;
|
|
76
|
+
display: flex;
|
|
77
|
+
align-items: center;
|
|
78
|
+
gap: 10px;
|
|
79
|
+
margin-left: 18px;
|
|
80
|
+
padding: 6px 10px 6px 8px;
|
|
81
|
+
border-radius: 6px;
|
|
82
|
+
color: var(--royui-treenav-label);
|
|
83
|
+
font-size: var(--royui-treenav-font-size);
|
|
84
|
+
font-weight: var(--royui-treenav-font-weight);
|
|
85
|
+
line-height: 1.3;
|
|
86
|
+
text-decoration: none;
|
|
87
|
+
transition:
|
|
88
|
+
background-color 0.2s var(--royui-treenav-ease),
|
|
89
|
+
color 0.2s var(--royui-treenav-ease),
|
|
90
|
+
transform 0.18s var(--royui-treenav-ease);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.royui-treenav__link:hover {
|
|
94
|
+
background-color: var(--royui-treenav-hover-bg);
|
|
95
|
+
color: var(--royui-treenav-label-hover);
|
|
96
|
+
transform: translateX(4px);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.royui-treenav__link:focus-visible {
|
|
100
|
+
outline: 2px solid var(--royui-treenav-branch-active);
|
|
101
|
+
outline-offset: 2px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.royui-treenav__link[aria-current='page'] {
|
|
105
|
+
background-color: var(--royui-treenav-active-bg);
|
|
106
|
+
color: var(--royui-treenav-label-active);
|
|
107
|
+
font-weight: var(--royui-treenav-font-weight-active);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.royui-treenav__icon {
|
|
111
|
+
display: inline-flex;
|
|
112
|
+
align-items: center;
|
|
113
|
+
justify-content: center;
|
|
114
|
+
flex-shrink: 0;
|
|
115
|
+
line-height: 0;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.royui-treenav__label {
|
|
119
|
+
display: inline-block;
|
|
120
|
+
min-width: 0;
|
|
121
|
+
flex: 1;
|
|
122
|
+
overflow: hidden;
|
|
123
|
+
text-overflow: ellipsis;
|
|
124
|
+
white-space: nowrap;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@media (prefers-reduced-motion: reduce) {
|
|
128
|
+
.royui-treenav__connector,
|
|
129
|
+
.royui-treenav__link {
|
|
130
|
+
transition: none;
|
|
131
|
+
}
|
|
132
|
+
.royui-treenav__link:hover {
|
|
133
|
+
transform: none;
|
|
134
|
+
}
|
|
135
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ButtonHTMLAttributes, ReactNode, AnchorHTMLAttributes, CSSProperties, HTMLAttributes } from 'react';
|
|
2
|
+
import { ButtonHTMLAttributes, ReactNode, AnchorHTMLAttributes, CSSProperties, HTMLAttributes, LiHTMLAttributes } from 'react';
|
|
3
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
4
|
|
|
5
5
|
interface GradientButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
@@ -67,4 +67,30 @@ interface TextMorphProps extends Omit<HTMLAttributes<HTMLSpanElement>, 'children
|
|
|
67
67
|
}
|
|
68
68
|
declare const TextMorph: react.ForwardRefExoticComponent<TextMorphProps & react.RefAttributes<HTMLSpanElement>>;
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
interface TreeNavProps extends HTMLAttributes<HTMLUListElement> {
|
|
71
|
+
/** Left indent of the branched group, in pixels. Default 24. */
|
|
72
|
+
indent?: number;
|
|
73
|
+
/** Vertical gap between items, in pixels. Default 2. */
|
|
74
|
+
gap?: number;
|
|
75
|
+
}
|
|
76
|
+
declare const TreeNav: react.ForwardRefExoticComponent<TreeNavProps & react.RefAttributes<HTMLUListElement>>;
|
|
77
|
+
|
|
78
|
+
interface TreeNavItemProps extends Omit<LiHTMLAttributes<HTMLLIElement>, 'children'> {
|
|
79
|
+
/** Link target. Used when asChild is false (default <a> render). */
|
|
80
|
+
href?: string;
|
|
81
|
+
/** Mark this item active. Adds aria-current="page" to the rendered link. */
|
|
82
|
+
active?: boolean;
|
|
83
|
+
/** Render the consumer's element (e.g. next/link, TanStack Link) instead of an <a>. */
|
|
84
|
+
asChild?: boolean;
|
|
85
|
+
/** Hide the triangle tip at the end of the branch. Default false (tip shown). */
|
|
86
|
+
hideTip?: boolean;
|
|
87
|
+
/** Leading icon slot. */
|
|
88
|
+
icon?: ReactNode;
|
|
89
|
+
/** Anchor / link contents. */
|
|
90
|
+
children?: ReactNode;
|
|
91
|
+
/** Forwarded to the inner link element (className, onClick, etc.). */
|
|
92
|
+
linkProps?: Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href' | 'children'>;
|
|
93
|
+
}
|
|
94
|
+
declare const TreeNavItem: react.ForwardRefExoticComponent<TreeNavItemProps & react.RefAttributes<HTMLLIElement>>;
|
|
95
|
+
|
|
96
|
+
export { GradientButton, type GradientButtonProps, MadeBy, type MadeByPosition, type MadeByProps, Popover, type PopoverProps, TextMorph, type TextMorphProps, TreeNav, TreeNavItem, type TreeNavItemProps, type TreeNavProps };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { forwardRef, useState, useRef, useEffect } from 'react';
|
|
2
|
+
import { forwardRef, useState, useRef, useEffect, Children, isValidElement, cloneElement } from 'react';
|
|
3
3
|
import './GradientButton-TX2GJRIQ.css';
|
|
4
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
import './Popover-LSYVKT4M.css';
|
|
6
6
|
import './MadeBy-JCYGHWSD.css';
|
|
7
7
|
import './TextMorph-RX2BX25F.css';
|
|
8
|
+
import './TreeNav-22DY7TP5.css';
|
|
8
9
|
|
|
9
10
|
// src/components/gradient-button/GradientButton.tsx
|
|
10
11
|
var DefaultSpinner = () => /* @__PURE__ */ jsx("span", { className: "gradient-btn__spinner", "aria-hidden": "true", children: /* @__PURE__ */ jsxs("svg", { viewBox: "0 0 24 24", width: "18", height: "18", fill: "none", children: [
|
|
@@ -283,7 +284,98 @@ var TextMorph = forwardRef(
|
|
|
283
284
|
);
|
|
284
285
|
}
|
|
285
286
|
);
|
|
287
|
+
var TreeNav = forwardRef(
|
|
288
|
+
({ indent = 24, gap = 2, className = "", style, children, ...rest }, ref) => {
|
|
289
|
+
const mergedStyle = {
|
|
290
|
+
...style,
|
|
291
|
+
["--royui-treenav-indent"]: `${indent}px`,
|
|
292
|
+
["--royui-treenav-gap"]: `${gap}px`
|
|
293
|
+
};
|
|
294
|
+
const classes = ["royui-treenav", className].filter(Boolean).join(" ");
|
|
295
|
+
return /* @__PURE__ */ jsx("ul", { ref, className: classes, style: mergedStyle, ...rest, children });
|
|
296
|
+
}
|
|
297
|
+
);
|
|
298
|
+
TreeNav.displayName = "TreeNav";
|
|
299
|
+
var TreeNavItem = forwardRef(
|
|
300
|
+
({
|
|
301
|
+
href,
|
|
302
|
+
active = false,
|
|
303
|
+
asChild = false,
|
|
304
|
+
hideTip = false,
|
|
305
|
+
icon,
|
|
306
|
+
children,
|
|
307
|
+
linkProps,
|
|
308
|
+
className = "",
|
|
309
|
+
...rest
|
|
310
|
+
}, ref) => {
|
|
311
|
+
const itemClasses = [
|
|
312
|
+
"royui-treenav__item",
|
|
313
|
+
hideTip && "royui-treenav__item--no-tip",
|
|
314
|
+
className
|
|
315
|
+
].filter(Boolean).join(" ");
|
|
316
|
+
const linkContent = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
317
|
+
icon && /* @__PURE__ */ jsx("span", { className: "royui-treenav__icon", "aria-hidden": true, children: icon }),
|
|
318
|
+
/* @__PURE__ */ jsx("span", { className: "royui-treenav__label", children })
|
|
319
|
+
] });
|
|
320
|
+
let renderedLink;
|
|
321
|
+
if (asChild) {
|
|
322
|
+
const onlyChild = Children.only(children);
|
|
323
|
+
if (!isValidElement(onlyChild)) {
|
|
324
|
+
throw new Error(
|
|
325
|
+
"TreeNavItem: asChild requires a single React element child."
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
const childClassName = [
|
|
329
|
+
"royui-treenav__link",
|
|
330
|
+
onlyChild.props.className
|
|
331
|
+
].filter(Boolean).join(" ");
|
|
332
|
+
renderedLink = cloneElement(onlyChild, {
|
|
333
|
+
className: childClassName,
|
|
334
|
+
...active ? { "aria-current": "page" } : {}
|
|
335
|
+
});
|
|
336
|
+
} else {
|
|
337
|
+
const { className: linkClassName, ...linkRest } = linkProps ?? {};
|
|
338
|
+
const mergedLinkClass = ["royui-treenav__link", linkClassName].filter(Boolean).join(" ");
|
|
339
|
+
renderedLink = /* @__PURE__ */ jsx(
|
|
340
|
+
"a",
|
|
341
|
+
{
|
|
342
|
+
href,
|
|
343
|
+
className: mergedLinkClass,
|
|
344
|
+
...active ? { "aria-current": "page" } : {},
|
|
345
|
+
...linkRest,
|
|
346
|
+
children: linkContent
|
|
347
|
+
}
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
return /* @__PURE__ */ jsxs("li", { ref, className: itemClasses, ...rest, children: [
|
|
351
|
+
/* @__PURE__ */ jsx(
|
|
352
|
+
"svg",
|
|
353
|
+
{
|
|
354
|
+
className: "royui-treenav__connector",
|
|
355
|
+
viewBox: "0 0 20 30",
|
|
356
|
+
preserveAspectRatio: "xMinYMid meet",
|
|
357
|
+
"aria-hidden": true,
|
|
358
|
+
children: hideTip ? /* @__PURE__ */ jsx(
|
|
359
|
+
"path",
|
|
360
|
+
{
|
|
361
|
+
d: "M1.25 0 L1.25 7 Q1.25 15.75 11 15.75 L11 14.25 Q2.75 14.25 2.75 7 L2.75 0 Z",
|
|
362
|
+
fill: "currentColor"
|
|
363
|
+
}
|
|
364
|
+
) : /* @__PURE__ */ jsx(
|
|
365
|
+
"path",
|
|
366
|
+
{
|
|
367
|
+
d: "M1.25 0 L1.25 7 Q1.25 15.75 10.33 15.75 L10.33 16.94 L14.22 15 L10.33 13.06 L10.33 14.25 Q2.75 14.25 2.75 7 L2.75 0 Z",
|
|
368
|
+
fill: "currentColor"
|
|
369
|
+
}
|
|
370
|
+
)
|
|
371
|
+
}
|
|
372
|
+
),
|
|
373
|
+
renderedLink
|
|
374
|
+
] });
|
|
375
|
+
}
|
|
376
|
+
);
|
|
377
|
+
TreeNavItem.displayName = "TreeNavItem";
|
|
286
378
|
|
|
287
|
-
export { GradientButton, MadeBy, Popover, TextMorph };
|
|
379
|
+
export { GradientButton, MadeBy, Popover, TextMorph, TreeNav, TreeNavItem };
|
|
288
380
|
//# sourceMappingURL=index.js.map
|
|
289
381
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/gradient-button/GradientButton.tsx","../src/components/popover/Popover.tsx","../src/components/made-by/MadeBy.tsx","../src/components/text-morph/TextMorph.tsx"],"names":["jsxs","jsx","forwardRef","TextMorph","useState","useRef","useEffect"],"mappings":";;;;;;;;AAYA,IAAM,iBAAiB,sBACrB,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yBAAwB,aAAA,EAAY,MAAA,EAClD,QAAA,kBAAA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAQ,WAAA,EAAY,KAAA,EAAM,MAAK,MAAA,EAAO,IAAA,EAAK,MAAK,MAAA,EACnD,QAAA,EAAA;AAAA,kBAAA,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,EAAA,EAAG,IAAA;AAAA,MACH,EAAA,EAAG,IAAA;AAAA,MACH,CAAA,EAAE,GAAA;AAAA,MACF,MAAA,EAAO,cAAA;AAAA,MACP,aAAA,EAAc,KAAA;AAAA,MACd,WAAA,EAAY;AAAA;AAAA,GACd;AAAA,kBACA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,CAAA,EAAE,sBAAA;AAAA,MACF,MAAA,EAAO,cAAA;AAAA,MACP,WAAA,EAAY,KAAA;AAAA,MACZ,aAAA,EAAc;AAAA;AAAA;AAChB,CAAA,EACF,CAAA,EACF,CAAA;AAGK,IAAM,cAAA,GAAiB,UAAA;AAAA,EAC5B,CACE;AAAA,IACE,OAAA,GAAU,KAAA;AAAA,IACV,YAAA;AAAA,IACA,SAAA,GAAY,IAAA;AAAA,IACZ,QAAA;AAAA,IACA,SAAA,GAAY,EAAA;AAAA,IACZ,QAAA;AAAA,IACA,IAAA,GAAO,QAAA;AAAA,IACP,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,cAAA;AAAA,MACA,YAAY,oBAAA,GAAuB,EAAA;AAAA,MACnC,UAAU,uBAAA,GAA0B,EAAA;AAAA,MACpC;AAAA,KACF,CACG,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAEX,IAAA,uBACE,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,IAAA;AAAA,QACA,UAAU,QAAA,IAAY,OAAA;AAAA,QACtB,SAAA,EAAW,OAAA;AAAA,QACX,aAAW,OAAA,IAAW,MAAA;AAAA,QACrB,GAAG,IAAA;AAAA,QAEH,QAAA,EAAA,OAAA,GAAW,YAAA,oBAAgB,GAAA,CAAC,cAAA,EAAA,EAAe,CAAA,GAAM;AAAA;AAAA,KACpD;AAAA,EAEJ;AACF;AAEA,cAAA,CAAe,WAAA,GAAc,gBAAA;ACnD7B,IAAM,QAAA,GAAW,sBACfA,IAAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,KAAA,EAAM,IAAA;AAAA,IACN,MAAA,EAAO,IAAA;AAAA,IACP,OAAA,EAAQ,WAAA;AAAA,IACR,IAAA,EAAK,MAAA;AAAA,IACL,MAAA,EAAO,cAAA;AAAA,IACP,WAAA,EAAY,KAAA;AAAA,IACZ,aAAA,EAAc,OAAA;AAAA,IACd,cAAA,EAAe,OAAA;AAAA,IACf,aAAA,EAAW,IAAA;AAAA,IAEX,QAAA,EAAA;AAAA,sBAAAC,IAAC,QAAA,EAAA,EAAO,EAAA,EAAG,MAAK,EAAA,EAAG,IAAA,EAAK,GAAE,GAAA,EAAI,CAAA;AAAA,sBAC9BA,GAAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,oBAAA,EAAqB;AAAA;AAAA;AAC/B,CAAA;AAGK,SAAS,OAAA,CAAQ;AAAA,EACtB,QAAA;AAAA,EACA,KAAA;AAAA,EACA,KAAA,GAAQ,OAAA;AAAA,EACR,KAAA,GAAQ,IAAA;AAAA,EACR,KAAA,GAAQ,WAAA;AAAA,EACR,WAAA,GAAc,KAAA;AAAA,EACd;AACF,CAAA,EAAiB;AACf,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAAS,WAAW,CAAA;AAC5C,EAAA,MAAM,IAAA,GAAO,OAAuB,IAAI,CAAA;AACxC,EAAA,MAAM,SAAS,MAAM,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAEtC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,IAAA,EAAM;AACX,IAAA,SAAS,OAAO,CAAA,EAAe;AAC7B,MAAA,IAAI,IAAA,CAAK,WAAW,CAAC,IAAA,CAAK,QAAQ,QAAA,CAAS,CAAA,CAAE,MAAc,CAAA,EAAG;AAC5D,QAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,MACf;AAAA,IACF;AACA,IAAA,SAAS,MAAM,CAAA,EAAkB;AAC/B,MAAA,IAAI,CAAA,CAAE,GAAA,KAAQ,QAAA,EAAU,OAAA,CAAQ,KAAK,CAAA;AAAA,IACvC;AACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,aAAa,MAAM,CAAA;AAC7C,IAAA,QAAA,CAAS,gBAAA,CAAiB,WAAW,KAAK,CAAA;AAC1C,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,mBAAA,CAAoB,aAAa,MAAM,CAAA;AAChD,MAAA,QAAA,CAAS,mBAAA,CAAoB,WAAW,KAAK,CAAA;AAAA,IAC/C,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,MAAM,OAAA,GAAU,gBACd,aAAA,CAAc,EAAE,QAAQ,IAAA,EAAM,MAAA,EAAQ,CAAA,mBAEtCA,GAAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,IAAA,EAAK,QAAA;AAAA,MACL,OAAA,EAAS,MAAA;AAAA,MACT,YAAA,EAAY,KAAA;AAAA,MACZ,eAAA,EAAe,IAAA;AAAA,MACf,SAAA,EAAW,CAAA,uBAAA,EAA0B,IAAA,GAAO,4BAAA,GAA+B,EAAE,CAAA,CAAA;AAAA,MAE7E,QAAA,kBAAAA,IAAC,QAAA,EAAA,EAAS;AAAA;AAAA,GACZ;AAGF,EAAA,MAAM,aACJ,OAAO,KAAA,KAAU,QAAA,GAAW,CAAA,sBAAA,EAAyB,KAAK,CAAA,CAAA,GAAK,EAAA;AACjE,EAAA,MAAM,WAAA,GACJ,OAAO,KAAA,KAAU,QAAA,GAAW,EAAE,KAAA,EAAO,CAAA,EAAG,KAAK,CAAA,EAAA,CAAA,EAAK,GAAI,MAAA;AACxD,EAAA,MAAM,UAAA,GAAa,yBAAyB,KAAK,CAAA,CAAA;AAEjD,EAAA,uBACED,IAAAA,CAAC,KAAA,EAAA,EAAI,GAAA,EAAK,IAAA,EAAM,WAAU,eAAA,EACvB,QAAA,EAAA;AAAA,IAAA,OAAA;AAAA,IACA,wBACCA,IAAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,CAAA,qBAAA,EAAwB,UAAU,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA;AAAA,QAC3D,KAAA,EAAO,WAAA;AAAA,QACP,IAAA,EAAK,QAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,UAAA,KAAA,oBAASC,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,wBAAwB,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,0BACvDA,GAAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uBAAuB,QAAA,EAAS;AAAA;AAAA;AAAA;AACjD,GAAA,EAEJ,CAAA;AAEJ;ACrEO,IAAM,MAAA,GAASC,UAAAA;AAAA,EACpB,CACE;AAAA,IACE,IAAA;AAAA,IACA,IAAA;AAAA,IACA,MAAA,GAAS,SAAA;AAAA,IACT,QAAA,GAAW,cAAA;AAAA,IACX,IAAA;AAAA,IACA,QAAA;AAAA,IACA,SAAA;AAAA,IACA,SAAA,GAAY,EAAA;AAAA,IACZ,MAAA,GAAS,QAAA;AAAA,IACT,GAAA,GAAM,qBAAA;AAAA,IACN,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,MAAM,OAAA,GAAU;AAAA,MACd,cAAA;AAAA,MACA,iBAAiB,QAAQ,CAAA,CAAA;AAAA,MACzB;AAAA,KACF,CACG,MAAA,CAAO,OAAO,CAAA,CACd,KAAK,GAAG,CAAA;AAEX,IAAA,MAAM,aAA4B,EAAC;AACnC,IAAA,IAAI,QAAA,aAAqB,UAAA,GAAa,QAAA;AACtC,IAAA,IAAI,SAAA,aAAsB,SAAA,GAAY,SAAA;AAEtC,IAAA,uBACEF,IAAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,IAAA;AAAA,QACA,MAAA;AAAA,QACA,GAAA;AAAA,QACA,SAAA,EAAW,OAAA;AAAA,QACV,GAAG,IAAA;AAAA,QAEH,QAAA,EAAA;AAAA,UAAA,IAAA,oBACCC,GAAAA,CAAC,MAAA,EAAA,EAAK,WAAU,oBAAA,EAAqB,aAAA,EAAW,MAC7C,QAAA,EAAA,IAAA,EACH,CAAA;AAAA,0BAEFA,GAAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,wBAAwB,QAAA,EAAA,MAAA,EAAO,CAAA;AAAA,0BAC/CA,GAAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAU,oBAAA;AAAA,cACV,OAAO,MAAA,CAAO,IAAA,CAAK,UAAU,CAAA,CAAE,SAAS,UAAA,GAAa,MAAA;AAAA,cAEpD,QAAA,EAAA;AAAA;AAAA;AACH;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AAEA,MAAA,CAAO,WAAA,GAAc,QAAA;ACrDrB,SAAS,MAAM,EAAA,EAAY;AACzB,EAAA,OAAO,IAAI,OAAA,CAAc,CAAC,YAAY,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA;AAC/D;AAEA,SAAS,QAAA,CAAS,MAAc,EAAA,EAAY;AAC1C,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAA,EAAQ,GAAG,MAAM,CAAA;AAC5C,EAAA,OAAO,IAAI,IAAA,IAAQ,IAAA,CAAK,CAAC,CAAA,KAAM,EAAA,CAAG,CAAC,CAAA,EAAG,CAAA,EAAA;AACtC,EAAA,IAAI,CAAA,GAAI,CAAA;AACR,EAAA,OACE,IAAI,IAAA,CAAK,MAAA,GAAS,KAClB,CAAA,GAAI,EAAA,CAAG,SAAS,CAAA,IAChB,IAAA,CAAK,KAAK,MAAA,GAAS,CAAA,GAAI,CAAC,CAAA,KAAM,EAAA,CAAG,GAAG,MAAA,GAAS,CAAA,GAAI,CAAC,CAAA,EAClD;AACA,IAAA,CAAA,EAAA;AAAA,EACF;AACA,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,CAAC,CAAA;AAAA,IACvB,MAAA,EAAQ,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAS,CAAC,CAAA;AAAA,IAClC,QAAQ,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,IAAA,CAAK,SAAS,CAAC,CAAA;AAAA,IACrC,QAAQ,EAAA,CAAG,KAAA,CAAM,CAAA,EAAG,EAAA,CAAG,SAAS,CAAC;AAAA,GACnC;AACF;AAEA,SAAS,IAAA,CAAK,KAAa,GAAA,EAAa;AACtC,EAAA,OAAO,GAAA,GAAM,IAAA,CAAK,MAAA,EAAO,IAAK,GAAA,GAAM,GAAA,CAAA;AACtC;AAEO,IAAM,SAAA,GAAYC,UAAAA;AAAA,EACvB,SAASC,UAAAA,CACP;AAAA,IACE,KAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA,GAAY,CAAC,EAAA,EAAI,EAAE,CAAA;AAAA,IACnB,cAAA,GAAiB,CAAC,EAAA,EAAI,EAAE,CAAA;AAAA,IACxB,SAAA,GAAY,YAAA;AAAA,IACZ,kBAAA,GAAqB,CAAC,EAAA,EAAI,EAAE,CAAA;AAAA,IAC5B,OAAA,GAAU,EAAA;AAAA,IACV,QAAA,GAAW,KAAA;AAAA,IACX,SAAA,GAAY,EAAA;AAAA,IACZ,GAAG;AAAA,KAEL,GAAA,EACA;AACA,IAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIC,SAAS,KAAK,CAAA;AAChD,IAAA,MAAM,QAAA,GAAWC,OAAO,CAAC,CAAA;AACzB,IAAA,MAAM,UAAA,GAAaA,OAAO,KAAK,CAAA;AAC/B,IAAA,MAAM,YAAA,GAAeA,OAAO,KAAK,CAAA;AACjC,IAAA,MAAM,YAAA,GAAeA,OAAO,KAAK,CAAA;AAEjC,IAAAC,UAAU,MAAM;AACd,MAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,QAAA,UAAA,CAAW,UAAU,MAAA,CAAO,UAAA;AAAA,UAC1B;AAAA,SACF,CAAE,OAAA;AAAA,MACJ;AAAA,IACF,CAAA,EAAG,EAAE,CAAA;AAIL,IAAAA,UAAU,MAAM;AACd,MAAA,YAAA,CAAa,OAAA,GAAU,SAAA;AAAA,IACzB,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,IAAAA,UAAU,MAAM;AACd,MAAA,IAAI,KAAA,KAAU,aAAa,OAAA,EAAS;AACpC,MAAA,MAAM,SAAS,YAAA,CAAa,OAAA;AAC5B,MAAA,YAAA,CAAa,OAAA,GAAU,KAAA;AAEvB,MAAA,IAAI,QAAA,IAAY,WAAW,OAAA,EAAS;AAClC,QAAA,YAAA,CAAa,KAAK,CAAA;AAClB,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,OAAA,GAAU,EAAE,QAAA,CAAS,OAAA;AAE3B,MAAA,CAAC,YAAY;AACX,QAAA,MAAM,EAAE,QAAQ,MAAA,EAAQ,MAAA,EAAQ,QAAO,GAAI,QAAA,CAAS,QAAQ,KAAK,CAAA;AAEjE,QAAA,KAAA,IAAS,IAAI,MAAA,CAAO,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC3C,UAAA,IAAI,OAAA,KAAY,SAAS,OAAA,EAAS;AAClC,UAAA,YAAA,CAAa,SAAS,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,CAAC,IAAI,MAAM,CAAA;AACjD,UAAA,MAAM,KAAA,CAAM,KAAK,cAAA,CAAe,CAAC,GAAG,cAAA,CAAe,CAAC,CAAC,CAAC,CAAA;AAAA,QACxD;AAEA,QAAA,IAAI,OAAA,KAAY,SAAS,OAAA,EAAS;AAClC,QAAA,MAAM,MAAM,OAAO,CAAA;AAEnB,QAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,IAAK,MAAA,CAAO,QAAQ,CAAA,EAAA,EAAK;AACvC,UAAA,IAAI,OAAA,KAAY,SAAS,OAAA,EAAS;AAClC,UAAA,YAAA,CAAa,SAAS,MAAA,CAAO,KAAA,CAAM,CAAA,EAAG,CAAC,IAAI,MAAM,CAAA;AACjD,UAAA,MAAM,EAAA,GAAK,MAAA,CAAO,MAAA,CAAO,CAAA,GAAI,CAAC,CAAA;AAC9B,UAAA,MAAM,OAAO,IAAA,CAAK,SAAA,CAAU,CAAC,CAAA,EAAG,SAAA,CAAU,CAAC,CAAC,CAAA;AAC5C,UAAA,MAAM,KAAA,GAAQ,SAAA,CAAU,IAAA,CAAK,EAAE,CAAA,GAC3B,IAAA,CAAK,kBAAA,CAAmB,CAAC,CAAA,EAAG,kBAAA,CAAmB,CAAC,CAAC,CAAA,GACjD,CAAA;AACJ,UAAA,MAAM,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,QAC1B;AAAA,MACF,CAAA,GAAG;AAAA,IACL,CAAA,EAAG;AAAA,MACD,KAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA;AAAA,MACA,cAAA;AAAA,MACA,SAAA;AAAA,MACA,kBAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,uBACEL,GAAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,CAAA,gBAAA,EAAmB,SAAS,CAAA,CAAA,CAAG,IAAA,EAAK;AAAA,QAC/C,WAAA,EAAU,QAAA;AAAA,QACT,GAAG,IAAA;AAAA,QAEH,QAAA,EAAA,UAAA,GAAa,UAAA,CAAW,SAAS,CAAA,GAAI;AAAA;AAAA,KACxC;AAAA,EAEJ;AACF","file":"index.js","sourcesContent":["'use client';\n\nimport { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react';\nimport './GradientButton.css';\n\nexport interface GradientButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n loading?: boolean;\n loadingLabel?: ReactNode;\n fullWidth?: boolean;\n children: ReactNode;\n}\n\nconst DefaultSpinner = () => (\n <span className=\"gradient-btn__spinner\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"9\"\n stroke=\"currentColor\"\n strokeOpacity=\"0.3\"\n strokeWidth=\"2.5\"\n />\n <path\n d=\"M21 12a9 9 0 0 0-9-9\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n </span>\n);\n\nexport const GradientButton = forwardRef<HTMLButtonElement, GradientButtonProps>(\n (\n {\n loading = false,\n loadingLabel,\n fullWidth = true,\n disabled,\n className = '',\n children,\n type = 'button',\n ...rest\n },\n ref,\n ) => {\n const classes = [\n 'gradient-btn',\n fullWidth ? 'gradient-btn--full' : '',\n loading ? 'gradient-btn--loading' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n ref={ref}\n type={type}\n disabled={disabled || loading}\n className={classes}\n aria-busy={loading || undefined}\n {...rest}\n >\n {loading ? (loadingLabel ?? <DefaultSpinner />) : children}\n </button>\n );\n },\n);\n\nGradientButton.displayName = 'GradientButton';\n","'use client';\n\nimport {\n useEffect,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport './Popover.css';\n\nexport interface PopoverProps {\n children: ReactNode;\n title?: string;\n align?: 'left' | 'right';\n width?: 'sm' | 'md' | 'lg' | number;\n label?: string;\n defaultOpen?: boolean;\n renderTrigger?: (api: { isOpen: boolean; toggle: () => void }) => ReactNode;\n}\n\nconst InfoIcon = () => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n >\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 16v-5M12 8h.01\" />\n </svg>\n);\n\nexport function Popover({\n children,\n title,\n align = 'right',\n width = 'md',\n label = 'Open menu',\n defaultOpen = false,\n renderTrigger,\n}: PopoverProps) {\n const [open, setOpen] = useState(defaultOpen);\n const wrap = useRef<HTMLDivElement>(null);\n const toggle = () => setOpen((o) => !o);\n\n useEffect(() => {\n if (!open) return;\n function onDown(e: MouseEvent) {\n if (wrap.current && !wrap.current.contains(e.target as Node)) {\n setOpen(false);\n }\n }\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') setOpen(false);\n }\n document.addEventListener('mousedown', onDown);\n document.addEventListener('keydown', onKey);\n return () => {\n document.removeEventListener('mousedown', onDown);\n document.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n const trigger = renderTrigger ? (\n renderTrigger({ isOpen: open, toggle })\n ) : (\n <button\n type=\"button\"\n onClick={toggle}\n aria-label={label}\n aria-expanded={open}\n className={`royui-popover__trigger ${open ? 'royui-popover__trigger--on' : ''}`}\n >\n <InfoIcon />\n </button>\n );\n\n const widthClass =\n typeof width === 'string' ? `royui-popover__panel--${width}` : '';\n const customWidth =\n typeof width === 'number' ? { width: `${width}px` } : undefined;\n const alignClass = `royui-popover__panel--${align}`;\n\n return (\n <div ref={wrap} className=\"royui-popover\">\n {trigger}\n {open && (\n <div\n className={`royui-popover__panel ${widthClass} ${alignClass}`}\n style={customWidth}\n role=\"dialog\"\n >\n {title && <div className=\"royui-popover__title\">{title}</div>}\n <div className=\"royui-popover__body\">{children}</div>\n </div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport {\n forwardRef,\n type AnchorHTMLAttributes,\n type CSSProperties,\n type ReactNode,\n} from 'react';\nimport './MadeBy.css';\n\nexport type MadeByPosition =\n | 'bottom-right'\n | 'bottom-left'\n | 'top-right'\n | 'top-left';\n\nexport interface MadeByProps\n extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href' | 'prefix'> {\n /** Display name shown after the prefix. */\n name: string;\n /** URL opened when the badge is clicked. */\n href: string;\n /** Prefix copy. Defaults to \"Made by\". */\n prefix?: ReactNode;\n /** Viewport anchor. Defaults to \"bottom-right\". */\n position?: MadeByPosition;\n /** Optional leading slot — avatar, mark, emoji, dot. */\n icon?: ReactNode;\n /** Custom font-family for the author name. */\n nameFont?: string;\n /** Font style for the author name. Defaults to \"italic\". */\n nameStyle?: CSSProperties['fontStyle'];\n}\n\nexport const MadeBy = forwardRef<HTMLAnchorElement, MadeByProps>(\n (\n {\n name,\n href,\n prefix = 'Made by',\n position = 'bottom-right',\n icon,\n nameFont,\n nameStyle,\n className = '',\n target = '_blank',\n rel = 'noopener noreferrer',\n ...rest\n },\n ref,\n ) => {\n const classes = [\n 'royui-madeby',\n `royui-madeby--${position}`,\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const nameStyles: CSSProperties = {};\n if (nameFont) nameStyles.fontFamily = nameFont;\n if (nameStyle) nameStyles.fontStyle = nameStyle;\n\n return (\n <a\n ref={ref}\n href={href}\n target={target}\n rel={rel}\n className={classes}\n {...rest}\n >\n {icon && (\n <span className=\"royui-madeby__icon\" aria-hidden>\n {icon}\n </span>\n )}\n <span className=\"royui-madeby__prefix\">{prefix}</span>\n <span\n className=\"royui-madeby__name\"\n style={Object.keys(nameStyles).length ? nameStyles : undefined}\n >\n {name}\n </span>\n </a>\n );\n },\n);\n\nMadeBy.displayName = 'MadeBy';\n","'use client';\n\nimport {\n forwardRef,\n useEffect,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport './TextMorph.css';\n\nexport interface TextMorphProps\n extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {\n /** The current text. When this prop changes, the component diff-types\n from the previously displayed text to the new value. */\n value: string;\n /** Optional renderer for the current intermediate text — handy for\n syntax highlighting, gradient spans, or wrapping each word. Receives\n the partial string at every keystroke during the animation. */\n renderText?: (current: string) => ReactNode;\n /** Per-character typing delay range in ms. Default [30, 60]. */\n typeDelay?: [min: number, max: number];\n /** Per-character backspace delay range in ms. Default [18, 30]. */\n backspaceDelay?: [min: number, max: number];\n /** Characters that get an additional delay (harder to type on a real\n keyboard — punctuation, brackets, symbols). Default /[\\/{}\\-_@]/. */\n hardChars?: RegExp;\n /** Extra delay range for hard chars in ms. Default [30, 65]. */\n hardCharExtraDelay?: [min: number, max: number];\n /** Pause between backspace phase and typing phase, in ms. Default 70. */\n pauseMs?: number;\n /** Skip animation entirely and just swap text. */\n disabled?: boolean;\n}\n\nfunction sleep(ms: number) {\n return new Promise<void>((resolve) => setTimeout(resolve, ms));\n}\n\nfunction findDiff(from: string, to: string) {\n let p = 0;\n const maxP = Math.min(from.length, to.length);\n while (p < maxP && from[p] === to[p]) p++;\n let s = 0;\n while (\n s < from.length - p &&\n s < to.length - p &&\n from[from.length - 1 - s] === to[to.length - 1 - s]\n ) {\n s++;\n }\n return {\n prefix: from.slice(0, p),\n suffix: from.slice(from.length - s),\n oldMid: from.slice(p, from.length - s),\n newMid: to.slice(p, to.length - s),\n };\n}\n\nfunction rand(min: number, max: number) {\n return min + Math.random() * (max - min);\n}\n\nexport const TextMorph = forwardRef<HTMLSpanElement, TextMorphProps>(\n function TextMorph(\n {\n value,\n renderText,\n typeDelay = [30, 60],\n backspaceDelay = [18, 30],\n hardChars = /[\\/{}\\-_@]/,\n hardCharExtraDelay = [30, 65],\n pauseMs = 70,\n disabled = false,\n className = '',\n ...rest\n },\n ref,\n ) {\n const [displayed, setDisplayed] = useState(value);\n const tokenRef = useRef(0);\n const reducedRef = useRef(false);\n const prevValueRef = useRef(value);\n const displayedRef = useRef(value);\n\n useEffect(() => {\n if (typeof window !== 'undefined') {\n reducedRef.current = window.matchMedia(\n '(prefers-reduced-motion: reduce)',\n ).matches;\n }\n }, []);\n\n // Keep a ref of the currently shown text so the animation always\n // starts from the latest frame (even if interrupted mid-typing).\n useEffect(() => {\n displayedRef.current = displayed;\n }, [displayed]);\n\n useEffect(() => {\n if (value === prevValueRef.current) return;\n const source = displayedRef.current;\n prevValueRef.current = value;\n\n if (disabled || reducedRef.current) {\n setDisplayed(value);\n return;\n }\n\n const myToken = ++tokenRef.current;\n\n (async () => {\n const { prefix, suffix, oldMid, newMid } = findDiff(source, value);\n\n for (let i = oldMid.length - 1; i >= 0; i--) {\n if (myToken !== tokenRef.current) return;\n setDisplayed(prefix + oldMid.slice(0, i) + suffix);\n await sleep(rand(backspaceDelay[0], backspaceDelay[1]));\n }\n\n if (myToken !== tokenRef.current) return;\n await sleep(pauseMs);\n\n for (let i = 1; i <= newMid.length; i++) {\n if (myToken !== tokenRef.current) return;\n setDisplayed(prefix + newMid.slice(0, i) + suffix);\n const ch = newMid.charAt(i - 1);\n const base = rand(typeDelay[0], typeDelay[1]);\n const extra = hardChars.test(ch)\n ? rand(hardCharExtraDelay[0], hardCharExtraDelay[1])\n : 0;\n await sleep(base + extra);\n }\n })();\n }, [\n value,\n disabled,\n typeDelay,\n backspaceDelay,\n hardChars,\n hardCharExtraDelay,\n pauseMs,\n ]);\n\n return (\n <span\n ref={ref}\n className={`royui-textmorph ${className}`.trim()}\n aria-live=\"polite\"\n {...rest}\n >\n {renderText ? renderText(displayed) : displayed}\n </span>\n );\n },\n);\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/gradient-button/GradientButton.tsx","../src/components/popover/Popover.tsx","../src/components/made-by/MadeBy.tsx","../src/components/text-morph/TextMorph.tsx","../src/components/tree-nav/TreeNav.tsx","../src/components/tree-nav/TreeNavItem.tsx"],"names":["jsxs","jsx","forwardRef","TextMorph","useState","useRef","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["'use client';\n\nimport { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react';\nimport './GradientButton.css';\n\nexport interface GradientButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n loading?: boolean;\n loadingLabel?: ReactNode;\n fullWidth?: boolean;\n children: ReactNode;\n}\n\nconst DefaultSpinner = () => (\n <span className=\"gradient-btn__spinner\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" width=\"18\" height=\"18\" fill=\"none\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"9\"\n stroke=\"currentColor\"\n strokeOpacity=\"0.3\"\n strokeWidth=\"2.5\"\n />\n <path\n d=\"M21 12a9 9 0 0 0-9-9\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n </span>\n);\n\nexport const GradientButton = forwardRef<HTMLButtonElement, GradientButtonProps>(\n (\n {\n loading = false,\n loadingLabel,\n fullWidth = true,\n disabled,\n className = '',\n children,\n type = 'button',\n ...rest\n },\n ref,\n ) => {\n const classes = [\n 'gradient-btn',\n fullWidth ? 'gradient-btn--full' : '',\n loading ? 'gradient-btn--loading' : '',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <button\n ref={ref}\n type={type}\n disabled={disabled || loading}\n className={classes}\n aria-busy={loading || undefined}\n {...rest}\n >\n {loading ? (loadingLabel ?? <DefaultSpinner />) : children}\n </button>\n );\n },\n);\n\nGradientButton.displayName = 'GradientButton';\n","'use client';\n\nimport {\n useEffect,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport './Popover.css';\n\nexport interface PopoverProps {\n children: ReactNode;\n title?: string;\n align?: 'left' | 'right';\n width?: 'sm' | 'md' | 'lg' | number;\n label?: string;\n defaultOpen?: boolean;\n renderTrigger?: (api: { isOpen: boolean; toggle: () => void }) => ReactNode;\n}\n\nconst InfoIcon = () => (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n >\n <circle cx=\"12\" cy=\"12\" r=\"9\" />\n <path d=\"M12 16v-5M12 8h.01\" />\n </svg>\n);\n\nexport function Popover({\n children,\n title,\n align = 'right',\n width = 'md',\n label = 'Open menu',\n defaultOpen = false,\n renderTrigger,\n}: PopoverProps) {\n const [open, setOpen] = useState(defaultOpen);\n const wrap = useRef<HTMLDivElement>(null);\n const toggle = () => setOpen((o) => !o);\n\n useEffect(() => {\n if (!open) return;\n function onDown(e: MouseEvent) {\n if (wrap.current && !wrap.current.contains(e.target as Node)) {\n setOpen(false);\n }\n }\n function onKey(e: KeyboardEvent) {\n if (e.key === 'Escape') setOpen(false);\n }\n document.addEventListener('mousedown', onDown);\n document.addEventListener('keydown', onKey);\n return () => {\n document.removeEventListener('mousedown', onDown);\n document.removeEventListener('keydown', onKey);\n };\n }, [open]);\n\n const trigger = renderTrigger ? (\n renderTrigger({ isOpen: open, toggle })\n ) : (\n <button\n type=\"button\"\n onClick={toggle}\n aria-label={label}\n aria-expanded={open}\n className={`royui-popover__trigger ${open ? 'royui-popover__trigger--on' : ''}`}\n >\n <InfoIcon />\n </button>\n );\n\n const widthClass =\n typeof width === 'string' ? `royui-popover__panel--${width}` : '';\n const customWidth =\n typeof width === 'number' ? { width: `${width}px` } : undefined;\n const alignClass = `royui-popover__panel--${align}`;\n\n return (\n <div ref={wrap} className=\"royui-popover\">\n {trigger}\n {open && (\n <div\n className={`royui-popover__panel ${widthClass} ${alignClass}`}\n style={customWidth}\n role=\"dialog\"\n >\n {title && <div className=\"royui-popover__title\">{title}</div>}\n <div className=\"royui-popover__body\">{children}</div>\n </div>\n )}\n </div>\n );\n}\n","'use client';\n\nimport {\n forwardRef,\n type AnchorHTMLAttributes,\n type CSSProperties,\n type ReactNode,\n} from 'react';\nimport './MadeBy.css';\n\nexport type MadeByPosition =\n | 'bottom-right'\n | 'bottom-left'\n | 'top-right'\n | 'top-left';\n\nexport interface MadeByProps\n extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href' | 'prefix'> {\n /** Display name shown after the prefix. */\n name: string;\n /** URL opened when the badge is clicked. */\n href: string;\n /** Prefix copy. Defaults to \"Made by\". */\n prefix?: ReactNode;\n /** Viewport anchor. Defaults to \"bottom-right\". */\n position?: MadeByPosition;\n /** Optional leading slot — avatar, mark, emoji, dot. */\n icon?: ReactNode;\n /** Custom font-family for the author name. */\n nameFont?: string;\n /** Font style for the author name. Defaults to \"italic\". */\n nameStyle?: CSSProperties['fontStyle'];\n}\n\nexport const MadeBy = forwardRef<HTMLAnchorElement, MadeByProps>(\n (\n {\n name,\n href,\n prefix = 'Made by',\n position = 'bottom-right',\n icon,\n nameFont,\n nameStyle,\n className = '',\n target = '_blank',\n rel = 'noopener noreferrer',\n ...rest\n },\n ref,\n ) => {\n const classes = [\n 'royui-madeby',\n `royui-madeby--${position}`,\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const nameStyles: CSSProperties = {};\n if (nameFont) nameStyles.fontFamily = nameFont;\n if (nameStyle) nameStyles.fontStyle = nameStyle;\n\n return (\n <a\n ref={ref}\n href={href}\n target={target}\n rel={rel}\n className={classes}\n {...rest}\n >\n {icon && (\n <span className=\"royui-madeby__icon\" aria-hidden>\n {icon}\n </span>\n )}\n <span className=\"royui-madeby__prefix\">{prefix}</span>\n <span\n className=\"royui-madeby__name\"\n style={Object.keys(nameStyles).length ? nameStyles : undefined}\n >\n {name}\n </span>\n </a>\n );\n },\n);\n\nMadeBy.displayName = 'MadeBy';\n","'use client';\n\nimport {\n forwardRef,\n useEffect,\n useRef,\n useState,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport './TextMorph.css';\n\nexport interface TextMorphProps\n extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'> {\n /** The current text. When this prop changes, the component diff-types\n from the previously displayed text to the new value. */\n value: string;\n /** Optional renderer for the current intermediate text — handy for\n syntax highlighting, gradient spans, or wrapping each word. Receives\n the partial string at every keystroke during the animation. */\n renderText?: (current: string) => ReactNode;\n /** Per-character typing delay range in ms. Default [30, 60]. */\n typeDelay?: [min: number, max: number];\n /** Per-character backspace delay range in ms. Default [18, 30]. */\n backspaceDelay?: [min: number, max: number];\n /** Characters that get an additional delay (harder to type on a real\n keyboard — punctuation, brackets, symbols). Default /[\\/{}\\-_@]/. */\n hardChars?: RegExp;\n /** Extra delay range for hard chars in ms. Default [30, 65]. */\n hardCharExtraDelay?: [min: number, max: number];\n /** Pause between backspace phase and typing phase, in ms. Default 70. */\n pauseMs?: number;\n /** Skip animation entirely and just swap text. */\n disabled?: boolean;\n}\n\nfunction sleep(ms: number) {\n return new Promise<void>((resolve) => setTimeout(resolve, ms));\n}\n\nfunction findDiff(from: string, to: string) {\n let p = 0;\n const maxP = Math.min(from.length, to.length);\n while (p < maxP && from[p] === to[p]) p++;\n let s = 0;\n while (\n s < from.length - p &&\n s < to.length - p &&\n from[from.length - 1 - s] === to[to.length - 1 - s]\n ) {\n s++;\n }\n return {\n prefix: from.slice(0, p),\n suffix: from.slice(from.length - s),\n oldMid: from.slice(p, from.length - s),\n newMid: to.slice(p, to.length - s),\n };\n}\n\nfunction rand(min: number, max: number) {\n return min + Math.random() * (max - min);\n}\n\nexport const TextMorph = forwardRef<HTMLSpanElement, TextMorphProps>(\n function TextMorph(\n {\n value,\n renderText,\n typeDelay = [30, 60],\n backspaceDelay = [18, 30],\n hardChars = /[\\/{}\\-_@]/,\n hardCharExtraDelay = [30, 65],\n pauseMs = 70,\n disabled = false,\n className = '',\n ...rest\n },\n ref,\n ) {\n const [displayed, setDisplayed] = useState(value);\n const tokenRef = useRef(0);\n const reducedRef = useRef(false);\n const prevValueRef = useRef(value);\n const displayedRef = useRef(value);\n\n useEffect(() => {\n if (typeof window !== 'undefined') {\n reducedRef.current = window.matchMedia(\n '(prefers-reduced-motion: reduce)',\n ).matches;\n }\n }, []);\n\n // Keep a ref of the currently shown text so the animation always\n // starts from the latest frame (even if interrupted mid-typing).\n useEffect(() => {\n displayedRef.current = displayed;\n }, [displayed]);\n\n useEffect(() => {\n if (value === prevValueRef.current) return;\n const source = displayedRef.current;\n prevValueRef.current = value;\n\n if (disabled || reducedRef.current) {\n setDisplayed(value);\n return;\n }\n\n const myToken = ++tokenRef.current;\n\n (async () => {\n const { prefix, suffix, oldMid, newMid } = findDiff(source, value);\n\n for (let i = oldMid.length - 1; i >= 0; i--) {\n if (myToken !== tokenRef.current) return;\n setDisplayed(prefix + oldMid.slice(0, i) + suffix);\n await sleep(rand(backspaceDelay[0], backspaceDelay[1]));\n }\n\n if (myToken !== tokenRef.current) return;\n await sleep(pauseMs);\n\n for (let i = 1; i <= newMid.length; i++) {\n if (myToken !== tokenRef.current) return;\n setDisplayed(prefix + newMid.slice(0, i) + suffix);\n const ch = newMid.charAt(i - 1);\n const base = rand(typeDelay[0], typeDelay[1]);\n const extra = hardChars.test(ch)\n ? rand(hardCharExtraDelay[0], hardCharExtraDelay[1])\n : 0;\n await sleep(base + extra);\n }\n })();\n }, [\n value,\n disabled,\n typeDelay,\n backspaceDelay,\n hardChars,\n hardCharExtraDelay,\n pauseMs,\n ]);\n\n return (\n <span\n ref={ref}\n className={`royui-textmorph ${className}`.trim()}\n aria-live=\"polite\"\n {...rest}\n >\n {renderText ? renderText(displayed) : displayed}\n </span>\n );\n },\n);\n","'use client';\n\nimport {\n forwardRef,\n type CSSProperties,\n type HTMLAttributes,\n} from 'react';\nimport './TreeNav.css';\n\nexport interface TreeNavProps extends HTMLAttributes<HTMLUListElement> {\n /** Left indent of the branched group, in pixels. Default 24. */\n indent?: number;\n /** Vertical gap between items, in pixels. Default 2. */\n gap?: number;\n}\n\nexport const TreeNav = forwardRef<HTMLUListElement, TreeNavProps>(\n ({ indent = 24, gap = 2, className = '', style, children, ...rest }, ref) => {\n const mergedStyle: CSSProperties = {\n ...style,\n ['--royui-treenav-indent' as string]: `${indent}px`,\n ['--royui-treenav-gap' as string]: `${gap}px`,\n };\n\n const classes = ['royui-treenav', className].filter(Boolean).join(' ');\n\n return (\n <ul ref={ref} className={classes} style={mergedStyle} {...rest}>\n {children}\n </ul>\n );\n },\n);\n\nTreeNav.displayName = 'TreeNav';\n","'use client';\n\nimport {\n Children,\n cloneElement,\n forwardRef,\n isValidElement,\n type AnchorHTMLAttributes,\n type LiHTMLAttributes,\n type ReactElement,\n type ReactNode,\n} from 'react';\n\nexport interface TreeNavItemProps\n extends Omit<LiHTMLAttributes<HTMLLIElement>, 'children'> {\n /** Link target. Used when asChild is false (default <a> render). */\n href?: string;\n /** Mark this item active. Adds aria-current=\"page\" to the rendered link. */\n active?: boolean;\n /** Render the consumer's element (e.g. next/link, TanStack Link) instead of an <a>. */\n asChild?: boolean;\n /** Hide the triangle tip at the end of the branch. Default false (tip shown). */\n hideTip?: boolean;\n /** Leading icon slot. */\n icon?: ReactNode;\n /** Anchor / link contents. */\n children?: ReactNode;\n /** Forwarded to the inner link element (className, onClick, etc.). */\n linkProps?: Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href' | 'children'>;\n}\n\ntype ChildLinkElement = ReactElement<{\n className?: string;\n 'aria-current'?: AnchorHTMLAttributes<HTMLAnchorElement>['aria-current'];\n children?: ReactNode;\n}>;\n\nexport const TreeNavItem = forwardRef<HTMLLIElement, TreeNavItemProps>(\n (\n {\n href,\n active = false,\n asChild = false,\n hideTip = false,\n icon,\n children,\n linkProps,\n className = '',\n ...rest\n },\n ref,\n ) => {\n const itemClasses = [\n 'royui-treenav__item',\n hideTip && 'royui-treenav__item--no-tip',\n className,\n ]\n .filter(Boolean)\n .join(' ');\n\n const linkContent = (\n <>\n {icon && (\n <span className=\"royui-treenav__icon\" aria-hidden>\n {icon}\n </span>\n )}\n <span className=\"royui-treenav__label\">{children}</span>\n </>\n );\n\n let renderedLink: ReactNode;\n\n if (asChild) {\n const onlyChild = Children.only(children) as ChildLinkElement;\n if (!isValidElement(onlyChild)) {\n throw new Error(\n 'TreeNavItem: asChild requires a single React element child.',\n );\n }\n const childClassName = [\n 'royui-treenav__link',\n onlyChild.props.className,\n ]\n .filter(Boolean)\n .join(' ');\n\n renderedLink = cloneElement(onlyChild, {\n className: childClassName,\n ...(active ? { 'aria-current': 'page' as const } : {}),\n });\n } else {\n const { className: linkClassName, ...linkRest } = linkProps ?? {};\n const mergedLinkClass = ['royui-treenav__link', linkClassName]\n .filter(Boolean)\n .join(' ');\n\n renderedLink = (\n <a\n href={href}\n className={mergedLinkClass}\n {...(active ? { 'aria-current': 'page' as const } : {})}\n {...linkRest}\n >\n {linkContent}\n </a>\n );\n }\n\n return (\n <li ref={ref} className={itemClasses} {...rest}>\n <svg\n className=\"royui-treenav__connector\"\n viewBox=\"0 0 20 30\"\n preserveAspectRatio=\"xMinYMid meet\"\n aria-hidden\n >\n {hideTip ? (\n <path\n d=\"M1.25 0 L1.25 7 Q1.25 15.75 11 15.75 L11 14.25 Q2.75 14.25 2.75 7 L2.75 0 Z\"\n fill=\"currentColor\"\n />\n ) : (\n <path\n d=\"M1.25 0 L1.25 7 Q1.25 15.75 10.33 15.75 L10.33 16.94 L14.22 15 L10.33 13.06 L10.33 14.25 Q2.75 14.25 2.75 7 L2.75 0 Z\"\n fill=\"currentColor\"\n />\n )}\n </svg>\n {renderedLink}\n </li>\n );\n },\n);\n\nTreeNavItem.displayName = 'TreeNavItem';\n"]}
|
package/package.json
CHANGED
|
@@ -1,44 +1,133 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@roy-ui/ui",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "Free, animated React components built with TypeScript. Zero config, RSC-safe, sub-12 KB. Gradient button, popover, text morph and more.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
7
|
+
"reactjs",
|
|
8
|
+
"react-18",
|
|
9
|
+
"react-19",
|
|
7
10
|
"react-components",
|
|
8
11
|
"react-component-library",
|
|
9
12
|
"react-ui",
|
|
10
13
|
"react-ui-library",
|
|
14
|
+
"react-ui-kit",
|
|
15
|
+
"react-ui-framework",
|
|
11
16
|
"ui",
|
|
12
17
|
"ui-library",
|
|
13
18
|
"ui-kit",
|
|
19
|
+
"ui-components",
|
|
20
|
+
"ui-framework",
|
|
14
21
|
"component-library",
|
|
15
22
|
"components",
|
|
23
|
+
"components-library",
|
|
16
24
|
"design-system",
|
|
17
25
|
"typescript",
|
|
26
|
+
"typescript-react",
|
|
18
27
|
"esm",
|
|
28
|
+
"esm-only",
|
|
19
29
|
"tree-shakable",
|
|
30
|
+
"tree-shaking",
|
|
31
|
+
"side-effect-free",
|
|
32
|
+
"tiny",
|
|
33
|
+
"lightweight",
|
|
34
|
+
"zero-config",
|
|
20
35
|
"nextjs",
|
|
21
36
|
"next",
|
|
37
|
+
"next-js",
|
|
38
|
+
"next15",
|
|
39
|
+
"nextjs-15",
|
|
40
|
+
"app-router",
|
|
22
41
|
"react-server-components",
|
|
23
42
|
"rsc",
|
|
43
|
+
"rsc-safe",
|
|
24
44
|
"use-client",
|
|
45
|
+
"server-components",
|
|
46
|
+
"vite",
|
|
47
|
+
"remix",
|
|
48
|
+
"astro",
|
|
49
|
+
"tanstack",
|
|
50
|
+
"tanstack-start",
|
|
25
51
|
"animation",
|
|
26
52
|
"animated",
|
|
53
|
+
"animated-components",
|
|
54
|
+
"animated-ui",
|
|
55
|
+
"react-animation",
|
|
56
|
+
"react-animation-library",
|
|
27
57
|
"micro-interactions",
|
|
58
|
+
"motion",
|
|
59
|
+
"transitions",
|
|
28
60
|
"gradient",
|
|
29
61
|
"gradient-button",
|
|
62
|
+
"animated-gradient",
|
|
30
63
|
"button",
|
|
64
|
+
"cta-button",
|
|
65
|
+
"loading-button",
|
|
31
66
|
"popover",
|
|
67
|
+
"animated-popover",
|
|
32
68
|
"tooltip",
|
|
69
|
+
"overlay",
|
|
70
|
+
"modal",
|
|
71
|
+
"dialog",
|
|
33
72
|
"text-animation",
|
|
34
73
|
"text-morph",
|
|
35
74
|
"text-effect",
|
|
75
|
+
"typing-animation",
|
|
76
|
+
"tree-nav",
|
|
77
|
+
"tree-navigation",
|
|
78
|
+
"sidebar",
|
|
79
|
+
"sidebar-nav",
|
|
80
|
+
"navigation",
|
|
81
|
+
"menu",
|
|
36
82
|
"made-by",
|
|
37
83
|
"attribution-badge",
|
|
84
|
+
"badge",
|
|
85
|
+
"credit-badge",
|
|
86
|
+
"floating-badge",
|
|
87
|
+
"headless-ui",
|
|
88
|
+
"accessible",
|
|
89
|
+
"accessibility",
|
|
90
|
+
"wai-aria",
|
|
91
|
+
"aria",
|
|
92
|
+
"a11y",
|
|
38
93
|
"frontend",
|
|
94
|
+
"front-end",
|
|
95
|
+
"web-development",
|
|
39
96
|
"open-source",
|
|
40
97
|
"free",
|
|
41
|
-
"
|
|
98
|
+
"mit",
|
|
99
|
+
"mit-license",
|
|
100
|
+
"tailwind",
|
|
101
|
+
"tailwind-css",
|
|
102
|
+
"tailwind-friendly",
|
|
103
|
+
"shadcn",
|
|
104
|
+
"shadcn-ui",
|
|
105
|
+
"shadcn-alternative",
|
|
106
|
+
"shadcn-ui-alternative",
|
|
107
|
+
"aceternity",
|
|
108
|
+
"aceternity-ui",
|
|
109
|
+
"aceternity-alternative",
|
|
110
|
+
"magic-ui",
|
|
111
|
+
"magic-ui-alternative",
|
|
112
|
+
"mui",
|
|
113
|
+
"mui-alternative",
|
|
114
|
+
"material-ui",
|
|
115
|
+
"material-ui-alternative",
|
|
116
|
+
"radix",
|
|
117
|
+
"radix-ui",
|
|
118
|
+
"radix-alternative",
|
|
119
|
+
"hero-ui",
|
|
120
|
+
"heroui",
|
|
121
|
+
"heroui-alternative",
|
|
122
|
+
"mantine",
|
|
123
|
+
"mantine-alternative",
|
|
124
|
+
"chakra",
|
|
125
|
+
"chakra-ui",
|
|
126
|
+
"chakra-alternative",
|
|
127
|
+
"daisyui",
|
|
128
|
+
"daisyui-alternative",
|
|
129
|
+
"roy-ui",
|
|
130
|
+
"royui"
|
|
42
131
|
],
|
|
43
132
|
"author": {
|
|
44
133
|
"name": "Dibbayajyoti Roy",
|