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 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
+ ![React](https://img.shields.io/badge/React-20232A?style=for-the-badge&logo=react&logoColor=61DAFB)
8
+ ![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white)
9
+ ![Tailwind CSS](https://img.shields.io/badge/Tailwind_CSS-38B2AC?style=for-the-badge&logo=tailwind-css&logoColor=white)
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
@@ -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 };
@@ -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
+ }