orbcafe-ui 1.0.0
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 +130 -0
- package/dist/index.d.mts +70 -0
- package/dist/index.d.ts +70 -0
- package/dist/index.js +2 -0
- package/dist/index.mjs +2 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# OrbCafe UI
|
|
2
|
+
|
|
3
|
+
A modern, glassmorphism-inspired UI component library for React and Next.js applications.
|
|
4
|
+
|
|
5
|
+
## Tech Stack
|
|
6
|
+
|
|
7
|
+

|
|
8
|
+

|
|
9
|
+

|
|
10
|
+
|
|
11
|
+
## Getting Started
|
|
12
|
+
|
|
13
|
+
### Prerequisites
|
|
14
|
+
|
|
15
|
+
- React 18+
|
|
16
|
+
- Next.js 13+ (App Router recommended)
|
|
17
|
+
- Tailwind CSS configured in your project
|
|
18
|
+
|
|
19
|
+
### Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install orbcafe-ui
|
|
23
|
+
# or
|
|
24
|
+
yarn add orbcafe-ui
|
|
25
|
+
# or
|
|
26
|
+
pnpm add orbcafe-ui
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Setup
|
|
30
|
+
|
|
31
|
+
Ensure your `tailwind.config.js` includes the path to the `orbcafe-ui` components to ensure styles are applied correctly:
|
|
32
|
+
|
|
33
|
+
```javascript
|
|
34
|
+
// tailwind.config.js
|
|
35
|
+
module.exports = {
|
|
36
|
+
content: [
|
|
37
|
+
// ... your other content paths
|
|
38
|
+
"./node_modules/orbcafe-ui/dist/**/*.{js,mjs}",
|
|
39
|
+
],
|
|
40
|
+
// ... rest of your config
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Key Features
|
|
45
|
+
|
|
46
|
+
- **Glassmorphism Design**: Beautiful, modern UI components with frosted glass effects.
|
|
47
|
+
- **Navigation Island**: A collapsible, responsive sidebar navigation component.
|
|
48
|
+
- **Tree Menu**: Hierarchical menu support with expandable/collapsible nodes.
|
|
49
|
+
- **Fully Typed**: Written in TypeScript with complete type definitions.
|
|
50
|
+
|
|
51
|
+
## Usage Examples
|
|
52
|
+
|
|
53
|
+
### Navigation Island
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
import { NavigationIsland, TreeMenuItem } from 'orbcafe-ui';
|
|
57
|
+
import { useState } from 'react';
|
|
58
|
+
|
|
59
|
+
const menuData: TreeMenuItem[] = [
|
|
60
|
+
{
|
|
61
|
+
id: 'dashboard',
|
|
62
|
+
title: 'Dashboard',
|
|
63
|
+
href: '/dashboard',
|
|
64
|
+
icon: <DashboardIcon /> // Replace with your icon
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: 'settings',
|
|
68
|
+
title: 'Settings',
|
|
69
|
+
children: [
|
|
70
|
+
{ id: 'profile', title: 'Profile', href: '/settings/profile' },
|
|
71
|
+
{ id: 'account', title: 'Account', href: '/settings/account' }
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
export default function Layout() {
|
|
77
|
+
const [collapsed, setCollapsed] = useState(false);
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<div className="flex h-screen">
|
|
81
|
+
<NavigationIsland
|
|
82
|
+
collapsed={collapsed}
|
|
83
|
+
onToggle={() => setCollapsed(!collapsed)}
|
|
84
|
+
menuData={menuData}
|
|
85
|
+
/>
|
|
86
|
+
<main className="flex-1">
|
|
87
|
+
{/* Your content */}
|
|
88
|
+
</main>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Button
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
import { Button } from 'orbcafe-ui';
|
|
98
|
+
|
|
99
|
+
export default function Page() {
|
|
100
|
+
return (
|
|
101
|
+
<div className="p-4 space-x-4">
|
|
102
|
+
<Button variant="default">Default Button</Button>
|
|
103
|
+
<Button variant="ghost">Ghost Button</Button>
|
|
104
|
+
<Button variant="outline">Outline Button</Button>
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Project Structure
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
orbcafe-ui/
|
|
114
|
+
├── dist/ # Built files (ESM & CJS)
|
|
115
|
+
├── src/
|
|
116
|
+
│ ├── components/ # UI Components
|
|
117
|
+
│ │ ├── button.tsx
|
|
118
|
+
│ │ ├── navigation-island.tsx
|
|
119
|
+
│ │ └── tree-menu.tsx
|
|
120
|
+
│ ├── config/ # Configuration constants
|
|
121
|
+
│ ├── lib/ # Utility functions
|
|
122
|
+
│ └── index.ts # Entry point
|
|
123
|
+
├── package.json
|
|
124
|
+
├── tsup.config.ts
|
|
125
|
+
└── tsconfig.json
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import React__default from 'react';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
5
|
+
import { VariantProps } from 'class-variance-authority';
|
|
6
|
+
|
|
7
|
+
interface TreeMenuItem {
|
|
8
|
+
id: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
label?: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
icon?: React__default.ReactNode;
|
|
13
|
+
href?: string;
|
|
14
|
+
appurl?: string;
|
|
15
|
+
children?: TreeMenuItem[];
|
|
16
|
+
isExpanded?: boolean;
|
|
17
|
+
data?: any;
|
|
18
|
+
}
|
|
19
|
+
interface TreeMenuProps {
|
|
20
|
+
items: TreeMenuItem[];
|
|
21
|
+
onItemClick?: (item: TreeMenuItem) => void;
|
|
22
|
+
className?: string;
|
|
23
|
+
level?: number;
|
|
24
|
+
expandedIds?: Set<string>;
|
|
25
|
+
onToggleExpand?: (id: string) => void;
|
|
26
|
+
}
|
|
27
|
+
declare function TreeMenu({ items, onItemClick, className, level, expandedIds, onToggleExpand }: TreeMenuProps): react_jsx_runtime.JSX.Element;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @file 10_Frontend/components/ui/molecules/navigation-island.tsx
|
|
31
|
+
*
|
|
32
|
+
* @summary Core frontend navigation-island module for the ORBAI Core project
|
|
33
|
+
* @author ORBAICODER
|
|
34
|
+
* @version 1.0.0
|
|
35
|
+
* @date 2025-01-19
|
|
36
|
+
*
|
|
37
|
+
* @description
|
|
38
|
+
* This file is responsible for:
|
|
39
|
+
* - Implementing navigation-island functionality within frontend workflows
|
|
40
|
+
* - Integrating with shared ORBAI Core application processes under frontend
|
|
41
|
+
*
|
|
42
|
+
* @logic
|
|
43
|
+
* 1. Import required dependencies and configuration
|
|
44
|
+
* 2. Execute the primary logic for navigation-island
|
|
45
|
+
* 3. Export the resulting APIs, hooks, or components for reuse
|
|
46
|
+
*
|
|
47
|
+
* @changelog
|
|
48
|
+
* V1.0.0 - 2025-01-19 - Initial creation
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
interface NavigationIslandProps {
|
|
52
|
+
collapsed: boolean;
|
|
53
|
+
onToggle: () => void;
|
|
54
|
+
className?: string;
|
|
55
|
+
maxHeight?: number;
|
|
56
|
+
menuData?: TreeMenuItem[];
|
|
57
|
+
}
|
|
58
|
+
declare const NavigationIsland: React__default.FC<NavigationIslandProps>;
|
|
59
|
+
|
|
60
|
+
declare const buttonVariants: (props?: ({
|
|
61
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "chat-tool" | "chat-send" | "chat-stop" | "chat-disabled" | null | undefined;
|
|
62
|
+
size?: "default" | "sm" | "lg" | "icon" | "chat-sm" | "chat-md" | "chat-lg" | null | undefined;
|
|
63
|
+
rounded?: "sm" | "none" | "md" | "full" | null | undefined;
|
|
64
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
65
|
+
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
66
|
+
asChild?: boolean;
|
|
67
|
+
}
|
|
68
|
+
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
69
|
+
|
|
70
|
+
export { Button, type ButtonProps, NavigationIsland, type NavigationIslandProps, TreeMenu, type TreeMenuItem, buttonVariants };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import React__default from 'react';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
5
|
+
import { VariantProps } from 'class-variance-authority';
|
|
6
|
+
|
|
7
|
+
interface TreeMenuItem {
|
|
8
|
+
id: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
label?: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
icon?: React__default.ReactNode;
|
|
13
|
+
href?: string;
|
|
14
|
+
appurl?: string;
|
|
15
|
+
children?: TreeMenuItem[];
|
|
16
|
+
isExpanded?: boolean;
|
|
17
|
+
data?: any;
|
|
18
|
+
}
|
|
19
|
+
interface TreeMenuProps {
|
|
20
|
+
items: TreeMenuItem[];
|
|
21
|
+
onItemClick?: (item: TreeMenuItem) => void;
|
|
22
|
+
className?: string;
|
|
23
|
+
level?: number;
|
|
24
|
+
expandedIds?: Set<string>;
|
|
25
|
+
onToggleExpand?: (id: string) => void;
|
|
26
|
+
}
|
|
27
|
+
declare function TreeMenu({ items, onItemClick, className, level, expandedIds, onToggleExpand }: TreeMenuProps): react_jsx_runtime.JSX.Element;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @file 10_Frontend/components/ui/molecules/navigation-island.tsx
|
|
31
|
+
*
|
|
32
|
+
* @summary Core frontend navigation-island module for the ORBAI Core project
|
|
33
|
+
* @author ORBAICODER
|
|
34
|
+
* @version 1.0.0
|
|
35
|
+
* @date 2025-01-19
|
|
36
|
+
*
|
|
37
|
+
* @description
|
|
38
|
+
* This file is responsible for:
|
|
39
|
+
* - Implementing navigation-island functionality within frontend workflows
|
|
40
|
+
* - Integrating with shared ORBAI Core application processes under frontend
|
|
41
|
+
*
|
|
42
|
+
* @logic
|
|
43
|
+
* 1. Import required dependencies and configuration
|
|
44
|
+
* 2. Execute the primary logic for navigation-island
|
|
45
|
+
* 3. Export the resulting APIs, hooks, or components for reuse
|
|
46
|
+
*
|
|
47
|
+
* @changelog
|
|
48
|
+
* V1.0.0 - 2025-01-19 - Initial creation
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
interface NavigationIslandProps {
|
|
52
|
+
collapsed: boolean;
|
|
53
|
+
onToggle: () => void;
|
|
54
|
+
className?: string;
|
|
55
|
+
maxHeight?: number;
|
|
56
|
+
menuData?: TreeMenuItem[];
|
|
57
|
+
}
|
|
58
|
+
declare const NavigationIsland: React__default.FC<NavigationIslandProps>;
|
|
59
|
+
|
|
60
|
+
declare const buttonVariants: (props?: ({
|
|
61
|
+
variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "chat-tool" | "chat-send" | "chat-stop" | "chat-disabled" | null | undefined;
|
|
62
|
+
size?: "default" | "sm" | "lg" | "icon" | "chat-sm" | "chat-md" | "chat-lg" | null | undefined;
|
|
63
|
+
rounded?: "sm" | "none" | "md" | "full" | null | undefined;
|
|
64
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
65
|
+
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
66
|
+
asChild?: boolean;
|
|
67
|
+
}
|
|
68
|
+
declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement>>;
|
|
69
|
+
|
|
70
|
+
export { Button, type ButtonProps, NavigationIsland, type NavigationIslandProps, TreeMenu, type TreeMenuItem, buttonVariants };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var A=require('react'),navigation=require('next/navigation'),lucideReact=require('lucide-react'),clsx=require('clsx'),tailwindMerge=require('tailwind-merge'),reactSlot=require('@radix-ui/react-slot'),classVarianceAuthority=require('class-variance-authority'),jsxRuntime=require('react/jsx-runtime');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var A__namespace=/*#__PURE__*/_interopNamespace(A);function u(...o){return tailwindMerge.twMerge(clsx.clsx(o))}var I={primary:"#000000",primaryHover:"#333333"},k={primary:"bg-primary text-primary-foreground hover:bg-primary/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",ghost:"hover:bg-accent hover:text-accent-foreground"},x={none:"rounded-none",sm:"rounded-sm",md:"rounded-md",full:"rounded-full"},S=()=>"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50";var j=classVarianceAuthority.cva(S(),{variants:{variant:{default:`${k.primary} shadow-sm`,destructive:"bg-red-500 text-white hover:bg-red-600 active:bg-red-700 dark:bg-red-600 dark:hover:bg-red-500 dark:active:bg-red-700 shadow-sm",outline:`${k.outline} shadow-sm`,secondary:"bg-gray-200 text-gray-700 hover:bg-gray-300 active:bg-gray-400 dark:bg-gray-700 dark:text-gray-200 dark:hover:bg-gray-600 dark:active:bg-gray-500 shadow-sm",ghost:k.ghost,link:"text-blue-600 dark:text-blue-400 underline-offset-4 hover:underline hover:text-blue-700 dark:hover:text-blue-300 active:text-blue-800 dark:active:text-blue-200","chat-tool":"bg-[var(--orbai-surface-2)] border border-[var(--orbai-border-soft)] text-[var(--orbai-text-2)] hover:bg-[var(--orbai-surface-3)] hover:border-[var(--orbai-border-strong)] hover:text-[var(--orbai-text-1)] active:scale-95 transition-all duration-200","chat-send":`bg-[${I.primary}] hover:bg-[${I.primaryHover}] text-white border border-[var(--orbai-border-strong)] shadow-[var(--orbai-shadow-soft-sm)] hover:shadow-[var(--orbai-shadow-soft-md)] active:scale-95 transition-all duration-200`,"chat-stop":"bg-red-500 hover:bg-red-600 border border-[var(--orbai-border-strong)] shadow-[var(--orbai-shadow-soft-sm)] hover:shadow-[var(--orbai-shadow-soft-md)] active:scale-95 text-white transition-all duration-200","chat-disabled":"cursor-not-allowed opacity-50 bg-[var(--orbai-surface-2)] border border-[var(--orbai-border-soft)] text-[var(--orbai-muted)]"},size:{default:"h-10 px-4 py-2",sm:"h-9 px-3",lg:"h-11 px-8",icon:"h-10 w-10","chat-sm":"h-8 w-8 rounded-full","chat-md":"h-10 w-10 rounded-full","chat-lg":"h-12 w-12 rounded-full"},rounded:{none:x.none,sm:x.sm,md:x.md,full:x.full}},defaultVariants:{variant:"default",size:"default",rounded:"md"}}),T=A__namespace.forwardRef(({className:o,variant:h,size:b,asChild:p=false,...i},c)=>jsxRuntime.jsx(p?reactSlot.Slot:"button",{className:u(j({variant:h,size:b,className:o})),ref:c,...i}));T.displayName="Button";function E({items:o,onItemClick:h,className:b="",level:p=0,expandedIds:i,onToggleExpand:c}){let d=navigation.usePathname(),[y,f]=A.useState(new Set),g=i!==void 0&&c!==void 0,w=g?i:y,m=t=>{if(g)c(t);else {let e=new Set(y);e.has(t)?e.delete(t):e.add(t),f(e);}},N=t=>{t.children&&t.children.length>0&&m(t.id),h&&h(t);};return !o||!Array.isArray(o)?jsxRuntime.jsx("div",{className:u("tree-menu",b),children:jsxRuntime.jsx("div",{className:"text-sm text-gray-500 p-2",children:"No items to display"})}):jsxRuntime.jsx("div",{className:u("tree-menu",b),children:o.map(t=>{let e=w.has(t.id)||t.isExpanded,r=t.children&&t.children.length>0,l=t.appurl||t.href,a=l?d===l:false;return jsxRuntime.jsxs("div",{className:"tree-menu-item relative",children:[a&&jsxRuntime.jsx("div",{className:"absolute left-0 top-2 bottom-2 w-1 bg-blue-500 rounded-r-full z-10"}),jsxRuntime.jsxs(T,{variant:"ghost",className:u("w-full justify-start gap-2 h-auto py-2 relative overflow-hidden group",`ml-${p*4}`,a?"bg-blue-50/80 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 hover:bg-blue-100/80 dark:hover:bg-blue-900/30":"hover:bg-gray-100/50 dark:hover:bg-gray-800/50 text-gray-700 dark:text-gray-300"),onClick:()=>N(t),children:[r&&jsxRuntime.jsx("div",{className:u("flex-shrink-0 transition-transform duration-200",e&&"rotate-90",a?"text-blue-500":"text-gray-400 group-hover:text-gray-600 dark:text-gray-500 dark:group-hover:text-gray-300"),children:jsxRuntime.jsx(lucideReact.ChevronRight,{className:"h-4 w-4"})}),!r&&jsxRuntime.jsx("div",{className:"w-4 h-4 flex-shrink-0"}),t.icon&&jsxRuntime.jsx("div",{className:u("flex-shrink-0 transition-colors duration-200",a?"text-blue-500":"text-gray-400 group-hover:text-gray-600 dark:text-gray-500 dark:group-hover:text-gray-300"),children:t.icon}),jsxRuntime.jsxs("div",{className:"flex-1 text-left overflow-hidden z-10",children:[jsxRuntime.jsx("div",{className:u("text-sm truncate transition-colors duration-200",a?"font-semibold":"font-medium"),children:t.title||t.label}),t.description&&jsxRuntime.jsx("div",{className:u("text-xs truncate transition-colors duration-200",a?"text-blue-400/80 dark:text-blue-300/60":"text-gray-500 dark:text-gray-400"),title:t.description,children:t.description})]})]}),r&&jsxRuntime.jsx("div",{className:u("grid transition-[grid-template-rows] duration-300 ease-in-out",e?"grid-rows-[1fr]":"grid-rows-[0fr]"),children:jsxRuntime.jsx("div",{className:"overflow-hidden",children:jsxRuntime.jsx(E,{items:t.children,onItemClick:h,level:p+1,expandedIds:i,onToggleExpand:c})})})]},t.id)})})}var ve=({collapsed:o,onToggle:h,className:b="",maxHeight:p,menuData:i=[]})=>{let c=navigation.useRouter(),[d,y]=A.useState(""),[f,g]=A.useState(new Set);A.useEffect(()=>{o&&g(new Set);},[o]);let w=A.useCallback(e=>{let r=[],l=a=>{a.forEach(v=>{r.push(v.id),v.children&&l(v.children);});};return l(e),r},[]),m=A.useMemo(()=>{if(!d.trim())return i;let e=r=>r.reduce((l,a)=>{let v=a.title?.toLowerCase().includes(d.toLowerCase())||a.description?.toLowerCase().includes(d.toLowerCase()),C=a.children?e(a.children):[];return (v||C.length>0)&&l.push({...a,children:C.length>0?C:a.children}),l},[]);return e(i)},[d,i]),N=A.useMemo(()=>d.trim()?new Set(w(i)):f,[d,i,f,w]),t=A.useCallback(async e=>{if(console.log("\u{1F5B1}\uFE0F \u5BFC\u822A\u83DC\u5355\u9879\u70B9\u51FB:",e),e.id==="chat"||e.appurl==="/chat"){console.log("\u{1F4AC} \u68C0\u6D4B\u5230chat\u83DC\u5355\u70B9\u51FB\uFF0C\u8DF3\u8F6C\u5230\u65B0\u7684\u804A\u5929\u89C6\u56FE");try{c.push("/chat?new=true");}catch(l){console.error("\u274C \u65E0\u6CD5\u8DF3\u8F6C\u5230\u65B0\u804A\u5929\u89C6\u56FE:",l),c.push("/chat");}return}let r=e.appurl||e.href;r&&(r.startsWith("http://")||r.startsWith("https://")?window.open(r,"_blank"):c.push(r));},[c]);return jsxRuntime.jsxs("div",{className:`flex flex-col bg-white/10 dark:bg-[#101928] backdrop-blur-xl border border-white/20 dark:border-white/10 shadow-[0_4px_8px_0_rgba(31,38,135,0.1)] ${o?"w-14 rounded-full":"w-[234px] rounded-2xl"} relative ${b}`,style:{backdropFilter:"blur(16px) saturate(180%)",WebkitBackdropFilter:"blur(16px) saturate(180%)",transition:"width 400ms cubic-bezier(0.4, 0.0, 0.2, 1), border-radius 0ms cubic-bezier(0.4, 0.0, 0.2, 1), box-shadow 400ms ease-out",maxHeight:p?`${p}px`:void 0},children:[jsxRuntime.jsx("div",{className:`pt-4 pb-2 transition-all duration-500 ease-in-out ${o?"px-1":"px-2"}`,children:o?jsxRuntime.jsx("div",{className:"flex justify-center",children:jsxRuntime.jsx("button",{onClick:h,className:"w-10 h-10 flex items-center justify-center rounded-lg text-gray-500 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors duration-200",title:"\u5C55\u5F00\u5BFC\u822A",children:jsxRuntime.jsx(lucideReact.Search,{className:"h-5 w-5"})})}):jsxRuntime.jsxs("div",{className:`relative transition-opacity duration-300 ${o?"opacity-0":"opacity-100 delay-200"}`,children:[jsxRuntime.jsx("input",{type:"text",placeholder:"\u641C\u7D22\u83DC\u5355...",value:d,onChange:e=>y(e.target.value),className:"w-full pl-10 pr-4 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"}),jsxRuntime.jsx("div",{className:"absolute left-3 top-1/2 transform -translate-y-1/2 pointer-events-none",children:jsxRuntime.jsx(lucideReact.Search,{className:"h-4 w-4 text-gray-400 dark:text-gray-500"})})]})}),jsxRuntime.jsx("nav",{className:`flex-1 pb-4 transition-all duration-500 ease-in-out overflow-y-auto min-h-0 ${o?"px-1":"px-2"}`,children:m.length===0?jsxRuntime.jsx("div",{className:"flex items-center justify-center py-8 text-gray-500 text-sm",children:o?"\u{1F4C2}":d?"\u672A\u627E\u5230\u5339\u914D\u7684\u83DC\u5355\u9879":"\u6682\u65E0\u53EF\u8BBF\u95EE\u7684\u5E94\u7528"}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[!o&&jsxRuntime.jsx("div",{className:`transition-opacity duration-300 ${o?"opacity-0":"opacity-100 delay-200"}`,children:jsxRuntime.jsx(E,{items:m,onItemClick:t,className:"space-y-1",expandedIds:N,onToggleExpand:e=>{let r=new Set(f);m.some(a=>a.id===e)?r.has(e)?r.delete(e):(m.forEach(a=>{a.id!==e&&r.has(a.id)&&r.delete(a.id);}),r.add(e)):r.has(e)?r.delete(e):r.add(e),g(r);}})}),o&&jsxRuntime.jsx("div",{className:"space-y-2",children:i.map(e=>jsxRuntime.jsx("div",{className:"space-y-1",children:jsxRuntime.jsx("button",{onClick:()=>{h();let r=new Set([e.id]);g(r);},className:"w-full flex items-center justify-center p-2 rounded-lg text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 cursor-pointer transition-colors duration-200",title:`\u5C55\u5F00\u67E5\u770B ${e.title}`,children:e.icon||jsxRuntime.jsx("div",{className:"w-6 h-6 bg-blue-100 dark:bg-blue-900/20 rounded text-xs flex items-center justify-center font-medium text-blue-600 dark:text-blue-400",children:e.title?.charAt(0)||"?"})})},e.id))})]})}),!o&&jsxRuntime.jsx("button",{onClick:h,className:"absolute -bottom-1 -right-1 w-6 h-6 bg-transparent hover:bg-white/20 dark:hover:bg-gray-800/50 rounded-full flex items-center justify-center transition-all duration-300 ease-in-out z-20",title:"\u6298\u53E0\u5BFC\u822A",children:jsxRuntime.jsx("div",{className:"absolute",style:{bottom:"0px",right:"0px",width:"16px",height:"16px",overflow:"hidden"},children:jsxRuntime.jsx("div",{className:"dark:border-yellow-400",style:{width:"32px",height:"32px",borderRadius:"16px",border:"3px solid #21BCFF",backgroundColor:"transparent",position:"absolute",top:"-16px",left:"-16px"}})})})]})};
|
|
2
|
+
exports.Button=T;exports.NavigationIsland=ve;exports.TreeMenu=E;exports.buttonVariants=j;
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import*as A from'react';import {useState,useEffect,useCallback,useMemo}from'react';import {usePathname,useRouter}from'next/navigation';import {ChevronRight,Search}from'lucide-react';import {clsx}from'clsx';import {twMerge}from'tailwind-merge';import {Slot}from'@radix-ui/react-slot';import {cva}from'class-variance-authority';import {jsx,jsxs,Fragment}from'react/jsx-runtime';function u(...o){return twMerge(clsx(o))}var I={primary:"#000000",primaryHover:"#333333"},k={primary:"bg-primary text-primary-foreground hover:bg-primary/90",outline:"border border-input bg-background hover:bg-accent hover:text-accent-foreground",ghost:"hover:bg-accent hover:text-accent-foreground"},x={none:"rounded-none",sm:"rounded-sm",md:"rounded-md",full:"rounded-full"},S=()=>"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50";var j=cva(S(),{variants:{variant:{default:`${k.primary} shadow-sm`,destructive:"bg-red-500 text-white hover:bg-red-600 active:bg-red-700 dark:bg-red-600 dark:hover:bg-red-500 dark:active:bg-red-700 shadow-sm",outline:`${k.outline} shadow-sm`,secondary:"bg-gray-200 text-gray-700 hover:bg-gray-300 active:bg-gray-400 dark:bg-gray-700 dark:text-gray-200 dark:hover:bg-gray-600 dark:active:bg-gray-500 shadow-sm",ghost:k.ghost,link:"text-blue-600 dark:text-blue-400 underline-offset-4 hover:underline hover:text-blue-700 dark:hover:text-blue-300 active:text-blue-800 dark:active:text-blue-200","chat-tool":"bg-[var(--orbai-surface-2)] border border-[var(--orbai-border-soft)] text-[var(--orbai-text-2)] hover:bg-[var(--orbai-surface-3)] hover:border-[var(--orbai-border-strong)] hover:text-[var(--orbai-text-1)] active:scale-95 transition-all duration-200","chat-send":`bg-[${I.primary}] hover:bg-[${I.primaryHover}] text-white border border-[var(--orbai-border-strong)] shadow-[var(--orbai-shadow-soft-sm)] hover:shadow-[var(--orbai-shadow-soft-md)] active:scale-95 transition-all duration-200`,"chat-stop":"bg-red-500 hover:bg-red-600 border border-[var(--orbai-border-strong)] shadow-[var(--orbai-shadow-soft-sm)] hover:shadow-[var(--orbai-shadow-soft-md)] active:scale-95 text-white transition-all duration-200","chat-disabled":"cursor-not-allowed opacity-50 bg-[var(--orbai-surface-2)] border border-[var(--orbai-border-soft)] text-[var(--orbai-muted)]"},size:{default:"h-10 px-4 py-2",sm:"h-9 px-3",lg:"h-11 px-8",icon:"h-10 w-10","chat-sm":"h-8 w-8 rounded-full","chat-md":"h-10 w-10 rounded-full","chat-lg":"h-12 w-12 rounded-full"},rounded:{none:x.none,sm:x.sm,md:x.md,full:x.full}},defaultVariants:{variant:"default",size:"default",rounded:"md"}}),T=A.forwardRef(({className:o,variant:h,size:b,asChild:p=false,...i},c)=>jsx(p?Slot:"button",{className:u(j({variant:h,size:b,className:o})),ref:c,...i}));T.displayName="Button";function E({items:o,onItemClick:h,className:b="",level:p=0,expandedIds:i,onToggleExpand:c}){let d=usePathname(),[y,f]=useState(new Set),g=i!==void 0&&c!==void 0,w=g?i:y,m=t=>{if(g)c(t);else {let e=new Set(y);e.has(t)?e.delete(t):e.add(t),f(e);}},N=t=>{t.children&&t.children.length>0&&m(t.id),h&&h(t);};return !o||!Array.isArray(o)?jsx("div",{className:u("tree-menu",b),children:jsx("div",{className:"text-sm text-gray-500 p-2",children:"No items to display"})}):jsx("div",{className:u("tree-menu",b),children:o.map(t=>{let e=w.has(t.id)||t.isExpanded,r=t.children&&t.children.length>0,l=t.appurl||t.href,a=l?d===l:false;return jsxs("div",{className:"tree-menu-item relative",children:[a&&jsx("div",{className:"absolute left-0 top-2 bottom-2 w-1 bg-blue-500 rounded-r-full z-10"}),jsxs(T,{variant:"ghost",className:u("w-full justify-start gap-2 h-auto py-2 relative overflow-hidden group",`ml-${p*4}`,a?"bg-blue-50/80 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 hover:bg-blue-100/80 dark:hover:bg-blue-900/30":"hover:bg-gray-100/50 dark:hover:bg-gray-800/50 text-gray-700 dark:text-gray-300"),onClick:()=>N(t),children:[r&&jsx("div",{className:u("flex-shrink-0 transition-transform duration-200",e&&"rotate-90",a?"text-blue-500":"text-gray-400 group-hover:text-gray-600 dark:text-gray-500 dark:group-hover:text-gray-300"),children:jsx(ChevronRight,{className:"h-4 w-4"})}),!r&&jsx("div",{className:"w-4 h-4 flex-shrink-0"}),t.icon&&jsx("div",{className:u("flex-shrink-0 transition-colors duration-200",a?"text-blue-500":"text-gray-400 group-hover:text-gray-600 dark:text-gray-500 dark:group-hover:text-gray-300"),children:t.icon}),jsxs("div",{className:"flex-1 text-left overflow-hidden z-10",children:[jsx("div",{className:u("text-sm truncate transition-colors duration-200",a?"font-semibold":"font-medium"),children:t.title||t.label}),t.description&&jsx("div",{className:u("text-xs truncate transition-colors duration-200",a?"text-blue-400/80 dark:text-blue-300/60":"text-gray-500 dark:text-gray-400"),title:t.description,children:t.description})]})]}),r&&jsx("div",{className:u("grid transition-[grid-template-rows] duration-300 ease-in-out",e?"grid-rows-[1fr]":"grid-rows-[0fr]"),children:jsx("div",{className:"overflow-hidden",children:jsx(E,{items:t.children,onItemClick:h,level:p+1,expandedIds:i,onToggleExpand:c})})})]},t.id)})})}var ve=({collapsed:o,onToggle:h,className:b="",maxHeight:p,menuData:i=[]})=>{let c=useRouter(),[d,y]=useState(""),[f,g]=useState(new Set);useEffect(()=>{o&&g(new Set);},[o]);let w=useCallback(e=>{let r=[],l=a=>{a.forEach(v=>{r.push(v.id),v.children&&l(v.children);});};return l(e),r},[]),m=useMemo(()=>{if(!d.trim())return i;let e=r=>r.reduce((l,a)=>{let v=a.title?.toLowerCase().includes(d.toLowerCase())||a.description?.toLowerCase().includes(d.toLowerCase()),C=a.children?e(a.children):[];return (v||C.length>0)&&l.push({...a,children:C.length>0?C:a.children}),l},[]);return e(i)},[d,i]),N=useMemo(()=>d.trim()?new Set(w(i)):f,[d,i,f,w]),t=useCallback(async e=>{if(console.log("\u{1F5B1}\uFE0F \u5BFC\u822A\u83DC\u5355\u9879\u70B9\u51FB:",e),e.id==="chat"||e.appurl==="/chat"){console.log("\u{1F4AC} \u68C0\u6D4B\u5230chat\u83DC\u5355\u70B9\u51FB\uFF0C\u8DF3\u8F6C\u5230\u65B0\u7684\u804A\u5929\u89C6\u56FE");try{c.push("/chat?new=true");}catch(l){console.error("\u274C \u65E0\u6CD5\u8DF3\u8F6C\u5230\u65B0\u804A\u5929\u89C6\u56FE:",l),c.push("/chat");}return}let r=e.appurl||e.href;r&&(r.startsWith("http://")||r.startsWith("https://")?window.open(r,"_blank"):c.push(r));},[c]);return jsxs("div",{className:`flex flex-col bg-white/10 dark:bg-[#101928] backdrop-blur-xl border border-white/20 dark:border-white/10 shadow-[0_4px_8px_0_rgba(31,38,135,0.1)] ${o?"w-14 rounded-full":"w-[234px] rounded-2xl"} relative ${b}`,style:{backdropFilter:"blur(16px) saturate(180%)",WebkitBackdropFilter:"blur(16px) saturate(180%)",transition:"width 400ms cubic-bezier(0.4, 0.0, 0.2, 1), border-radius 0ms cubic-bezier(0.4, 0.0, 0.2, 1), box-shadow 400ms ease-out",maxHeight:p?`${p}px`:void 0},children:[jsx("div",{className:`pt-4 pb-2 transition-all duration-500 ease-in-out ${o?"px-1":"px-2"}`,children:o?jsx("div",{className:"flex justify-center",children:jsx("button",{onClick:h,className:"w-10 h-10 flex items-center justify-center rounded-lg text-gray-500 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 transition-colors duration-200",title:"\u5C55\u5F00\u5BFC\u822A",children:jsx(Search,{className:"h-5 w-5"})})}):jsxs("div",{className:`relative transition-opacity duration-300 ${o?"opacity-0":"opacity-100 delay-200"}`,children:[jsx("input",{type:"text",placeholder:"\u641C\u7D22\u83DC\u5355...",value:d,onChange:e=>y(e.target.value),className:"w-full pl-10 pr-4 py-2 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent"}),jsx("div",{className:"absolute left-3 top-1/2 transform -translate-y-1/2 pointer-events-none",children:jsx(Search,{className:"h-4 w-4 text-gray-400 dark:text-gray-500"})})]})}),jsx("nav",{className:`flex-1 pb-4 transition-all duration-500 ease-in-out overflow-y-auto min-h-0 ${o?"px-1":"px-2"}`,children:m.length===0?jsx("div",{className:"flex items-center justify-center py-8 text-gray-500 text-sm",children:o?"\u{1F4C2}":d?"\u672A\u627E\u5230\u5339\u914D\u7684\u83DC\u5355\u9879":"\u6682\u65E0\u53EF\u8BBF\u95EE\u7684\u5E94\u7528"}):jsxs(Fragment,{children:[!o&&jsx("div",{className:`transition-opacity duration-300 ${o?"opacity-0":"opacity-100 delay-200"}`,children:jsx(E,{items:m,onItemClick:t,className:"space-y-1",expandedIds:N,onToggleExpand:e=>{let r=new Set(f);m.some(a=>a.id===e)?r.has(e)?r.delete(e):(m.forEach(a=>{a.id!==e&&r.has(a.id)&&r.delete(a.id);}),r.add(e)):r.has(e)?r.delete(e):r.add(e),g(r);}})}),o&&jsx("div",{className:"space-y-2",children:i.map(e=>jsx("div",{className:"space-y-1",children:jsx("button",{onClick:()=>{h();let r=new Set([e.id]);g(r);},className:"w-full flex items-center justify-center p-2 rounded-lg text-gray-600 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800 cursor-pointer transition-colors duration-200",title:`\u5C55\u5F00\u67E5\u770B ${e.title}`,children:e.icon||jsx("div",{className:"w-6 h-6 bg-blue-100 dark:bg-blue-900/20 rounded text-xs flex items-center justify-center font-medium text-blue-600 dark:text-blue-400",children:e.title?.charAt(0)||"?"})})},e.id))})]})}),!o&&jsx("button",{onClick:h,className:"absolute -bottom-1 -right-1 w-6 h-6 bg-transparent hover:bg-white/20 dark:hover:bg-gray-800/50 rounded-full flex items-center justify-center transition-all duration-300 ease-in-out z-20",title:"\u6298\u53E0\u5BFC\u822A",children:jsx("div",{className:"absolute",style:{bottom:"0px",right:"0px",width:"16px",height:"16px",overflow:"hidden"},children:jsx("div",{className:"dark:border-yellow-400",style:{width:"32px",height:"32px",borderRadius:"16px",border:"3px solid #21BCFF",backgroundColor:"transparent",position:"absolute",top:"-16px",left:"-16px"}})})})]})};
|
|
2
|
+
export{T as Button,ve as NavigationIsland,E as TreeMenu,j as buttonVariants};
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "orbcafe-ui",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Awesome UI components with Glassmorphism",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsup",
|
|
10
|
+
"prepublishOnly": "npm run build"
|
|
11
|
+
},
|
|
12
|
+
"keywords": ["react", "tailwind", "ui"],
|
|
13
|
+
"author": "ORBAI Team",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"sideEffects": false,
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
21
|
+
"react-dom": "^18.0.0 || ^19.0.0",
|
|
22
|
+
"next": "^13.0.0 || ^14.0.0 || ^15.0.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/node": "^20.0.0",
|
|
26
|
+
"@types/react": "^18.0.0",
|
|
27
|
+
"@types/react-dom": "^18.0.0",
|
|
28
|
+
"tsup": "^8.0.0",
|
|
29
|
+
"typescript": "^5.0.0",
|
|
30
|
+
"next": "^14.0.0"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"lucide-react": "^0.475.0",
|
|
34
|
+
"clsx": "^2.0.0",
|
|
35
|
+
"tailwind-merge": "^2.0.0",
|
|
36
|
+
"@radix-ui/react-slot": "^1.0.0",
|
|
37
|
+
"class-variance-authority": "^0.7.0"
|
|
38
|
+
}
|
|
39
|
+
}
|