@aiquants/menu-bar 0.1.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/LICENSE +21 -0
- package/README.md +337 -0
- package/dist/MenuBar.d.ts +31 -0
- package/dist/components/SessionInfo.d.ts +37 -0
- package/dist/contents/MenuContent.d.ts +32 -0
- package/dist/contents/MenuList.d.ts +52 -0
- package/dist/contents/OverlayShadow.d.ts +25 -0
- package/dist/elements/MenuSwitch.d.ts +10 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.es.js +414 -0
- package/dist/index.umd.js +22 -0
- package/dist/menuBar.css +1 -0
- package/dist/types/user.d.ts +20 -0
- package/dist/types.d.ts +1 -0
- package/package.json +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 AIQuants
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
# @aiquants/menu-bar
|
|
2
|
+
|
|
3
|
+
A React menu bar component with authentication support and theming for modern web applications.
|
|
4
|
+
|
|
5
|
+
## Key Features
|
|
6
|
+
|
|
7
|
+
- **Menu Navigation**: Collapsible menu with smooth animations and hierarchical structure
|
|
8
|
+
- **Dark/Light Theme**: Comprehensive theming support with scoped CSS
|
|
9
|
+
- **Session Management**: Built-in session information display with user profiles
|
|
10
|
+
- **Responsive Design**: Mobile-friendly with overlay support
|
|
11
|
+
- **TypeScript Support**: Full TypeScript definitions included
|
|
12
|
+
- **React Router Integration**: Built for React Router with generic link component support
|
|
13
|
+
- **CSS Scoped**: All styles are scoped to prevent conflicts with host applications
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @aiquants/menu-bar
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Exports
|
|
22
|
+
|
|
23
|
+
This package exports the following components and types:
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
// Components
|
|
27
|
+
export { MenuBar } from '@aiquants/menu-bar';
|
|
28
|
+
export { SessionInfo, DefaultLink } from '@aiquants/menu-bar';
|
|
29
|
+
|
|
30
|
+
// Types
|
|
31
|
+
export type { IMenu, ISubmenu } from '@aiquants/menu-bar';
|
|
32
|
+
export type { Theme } from '@aiquants/menu-bar';
|
|
33
|
+
export type { SessionInfoProps, LinkProps } from '@aiquants/menu-bar';
|
|
34
|
+
export type { GoogleUserProfile, UserPhoto } from '@aiquants/menu-bar';
|
|
35
|
+
|
|
36
|
+
// CSS (import separately)
|
|
37
|
+
import '@aiquants/menu-bar/css';
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Basic Usage
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import React, { useState } from 'react';
|
|
44
|
+
import { MenuBar } from '@aiquants/menu-bar';
|
|
45
|
+
import '@aiquants/menu-bar/css';
|
|
46
|
+
|
|
47
|
+
function App() {
|
|
48
|
+
const [theme, setTheme] = useState('light');
|
|
49
|
+
|
|
50
|
+
const menuList = [
|
|
51
|
+
{
|
|
52
|
+
id: 1,
|
|
53
|
+
title: 'Dashboard',
|
|
54
|
+
href: '/dashboard',
|
|
55
|
+
submenu: []
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 2,
|
|
59
|
+
title: 'Data',
|
|
60
|
+
submenu: [
|
|
61
|
+
{ subid: 1, title: 'Reports', href: '/data/reports' },
|
|
62
|
+
{ subid: 2, title: 'Analytics', href: '/data/analytics' }
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
const toggleTheme = () => {
|
|
68
|
+
setTheme(prevTheme => prevTheme === 'light' ? 'dark' : 'light');
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const handleSignout = () => {
|
|
72
|
+
console.log('Signing out...');
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<div className="app">
|
|
77
|
+
<MenuBar
|
|
78
|
+
menuList={menuList}
|
|
79
|
+
theme={theme}
|
|
80
|
+
toggleTheme={toggleTheme}
|
|
81
|
+
onClickSignout={handleSignout}
|
|
82
|
+
menuHeader={<div>My App</div>}
|
|
83
|
+
/>
|
|
84
|
+
{/* Your app content */}
|
|
85
|
+
</div>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Props
|
|
91
|
+
|
|
92
|
+
### MenuBar Props
|
|
93
|
+
|
|
94
|
+
| Prop | Type | Required | Description |
|
|
95
|
+
|------|------|----------|-------------|
|
|
96
|
+
| `menuList` | `IMenu[]` | Yes | Array of menu items to display |
|
|
97
|
+
| `theme` | `'light' \| 'dark'` | Yes | Theme mode for the menu bar |
|
|
98
|
+
| `toggleTheme` | `() => void` | Yes | Function to toggle between light and dark themes |
|
|
99
|
+
| `onClickSignout` | `() => void` | Yes | Callback function for sign out action |
|
|
100
|
+
| `menuHeader` | `React.ReactNode` | No | Optional header content for the menu |
|
|
101
|
+
| `isMenuhide` | `boolean` | No | Whether to hide the menu bar entirely |
|
|
102
|
+
|
|
103
|
+
### IMenu Type
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
interface IMenu {
|
|
107
|
+
id: number;
|
|
108
|
+
title: string;
|
|
109
|
+
href?: string;
|
|
110
|
+
submenu: ISubmenu[];
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### ISubmenu Type
|
|
115
|
+
|
|
116
|
+
```tsx
|
|
117
|
+
interface ISubmenu {
|
|
118
|
+
subid: number;
|
|
119
|
+
title?: string;
|
|
120
|
+
href: string;
|
|
121
|
+
mark?: string;
|
|
122
|
+
new?: boolean;
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### GoogleUserProfile Type
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
interface GoogleUserProfile {
|
|
130
|
+
displayName: string;
|
|
131
|
+
photos: UserPhoto[];
|
|
132
|
+
id?: string;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
interface UserPhoto {
|
|
136
|
+
value: string;
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### SessionInfoProps Type
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
interface SessionInfoProps {
|
|
144
|
+
user: GoogleUserProfile | null;
|
|
145
|
+
onLogout?: () => void;
|
|
146
|
+
LinkComponent: React.ComponentType<LinkProps>;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
interface LinkProps {
|
|
150
|
+
to: string;
|
|
151
|
+
className?: string;
|
|
152
|
+
children: React.ReactNode;
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Theming
|
|
157
|
+
|
|
158
|
+
The menu bar supports both light and dark themes. All styles are scoped with the `.aiquants-menu-bar` class to prevent conflicts with your application's styles.
|
|
159
|
+
|
|
160
|
+
### Custom Styling
|
|
161
|
+
|
|
162
|
+
You can override the default styles by targeting the scoped classes:
|
|
163
|
+
|
|
164
|
+
```css
|
|
165
|
+
.aiquants-menu-bar {
|
|
166
|
+
/* Custom menu bar styles */
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.aiquants-menu-bar.theme-dark {
|
|
170
|
+
/* Dark theme overrides */
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.aiquants-menu-bar.theme-light {
|
|
174
|
+
/* Light theme overrides */
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Usage with React Router
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
import React, { useState } from 'react';
|
|
182
|
+
import { MenuBar } from '@aiquants/menu-bar';
|
|
183
|
+
|
|
184
|
+
function App() {
|
|
185
|
+
const [theme, setTheme] = useState('light');
|
|
186
|
+
|
|
187
|
+
const menuList = [
|
|
188
|
+
{
|
|
189
|
+
id: 1,
|
|
190
|
+
title: 'Home',
|
|
191
|
+
href: '/',
|
|
192
|
+
submenu: []
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
id: 2,
|
|
196
|
+
title: 'Products',
|
|
197
|
+
submenu: [
|
|
198
|
+
{ subid: 1, title: 'All Products', href: '/products' },
|
|
199
|
+
{ subid: 2, title: 'Categories', href: '/products/categories' }
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
];
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<MenuBar
|
|
206
|
+
menuList={menuList}
|
|
207
|
+
theme={theme}
|
|
208
|
+
toggleTheme={() => setTheme(theme === 'light' ? 'dark' : 'light')}
|
|
209
|
+
onClickSignout={() => console.log('Signout')}
|
|
210
|
+
/>
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Advanced Usage
|
|
216
|
+
|
|
217
|
+
### With Menu Header
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
import React from 'react';
|
|
221
|
+
|
|
222
|
+
const menuHeader = (
|
|
223
|
+
<div className="flex items-center gap-2 p-4">
|
|
224
|
+
<img src="/logo.png" alt="Logo" className="w-8 h-8" />
|
|
225
|
+
<span className="font-bold">My Application</span>
|
|
226
|
+
</div>
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
<MenuBar
|
|
230
|
+
menuList={menuList}
|
|
231
|
+
menuHeader={menuHeader}
|
|
232
|
+
theme={theme}
|
|
233
|
+
toggleTheme={toggleTheme}
|
|
234
|
+
onClickSignout={handleSignout}
|
|
235
|
+
/>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Hiding the Menu
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
import React from 'react';
|
|
242
|
+
|
|
243
|
+
<MenuBar
|
|
244
|
+
menuList={menuList}
|
|
245
|
+
theme={theme}
|
|
246
|
+
toggleTheme={toggleTheme}
|
|
247
|
+
onClickSignout={handleSignout}
|
|
248
|
+
isMenuhide={shouldHideMenu}
|
|
249
|
+
/>
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Components
|
|
253
|
+
|
|
254
|
+
### MenuBar
|
|
255
|
+
|
|
256
|
+
The main menu bar component that includes:
|
|
257
|
+
|
|
258
|
+
- Menu toggle button with hamburger icon
|
|
259
|
+
- Company logo and navigation menu
|
|
260
|
+
- Theme toggle functionality
|
|
261
|
+
- Responsive overlay for mobile devices
|
|
262
|
+
- Sign out functionality
|
|
263
|
+
|
|
264
|
+
### SessionInfo
|
|
265
|
+
|
|
266
|
+
A standalone session information component that displays:
|
|
267
|
+
|
|
268
|
+
- User avatar/profile picture
|
|
269
|
+
- User display name
|
|
270
|
+
- Logout functionality with customizable link component
|
|
271
|
+
|
|
272
|
+
```tsx
|
|
273
|
+
import { SessionInfo } from '@aiquants/menu-bar';
|
|
274
|
+
|
|
275
|
+
<SessionInfo
|
|
276
|
+
user={{
|
|
277
|
+
displayName: "John Doe",
|
|
278
|
+
photos: [{ value: "https://example.com/avatar.jpg" }]
|
|
279
|
+
}}
|
|
280
|
+
onLogout={() => console.log('Logout')}
|
|
281
|
+
LinkComponent={({ to, children, ...props }) => (
|
|
282
|
+
<a href={to} {...props}>{children}</a>
|
|
283
|
+
)}
|
|
284
|
+
/>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Menu Features
|
|
288
|
+
|
|
289
|
+
- **Hierarchical Menu Structure**: Support for main menu items with submenus
|
|
290
|
+
- **Dynamic Navigation**: Menu items can have direct links or submenu collections
|
|
291
|
+
- **Visual Indicators**: Support for special marks (lock icon, etc.) and "new" badges
|
|
292
|
+
- **External Links**: Option to open links in new tabs
|
|
293
|
+
|
|
294
|
+
## CSS Classes
|
|
295
|
+
|
|
296
|
+
All CSS classes are scoped with `.aiquants-` prefix:
|
|
297
|
+
|
|
298
|
+
- `.aiquants-menu-bar` - Main container
|
|
299
|
+
- `.aiquants-menu-switch` - Menu toggle button
|
|
300
|
+
- `.aiquants-menu-content` - Menu content area
|
|
301
|
+
- `.aiquants-session-info` - Session information
|
|
302
|
+
- `.aiquants-overlay-shadow` - Mobile overlay
|
|
303
|
+
|
|
304
|
+
## Browser Support
|
|
305
|
+
|
|
306
|
+
- Chrome/Edge 88+
|
|
307
|
+
- Firefox 78+
|
|
308
|
+
- Safari 14+
|
|
309
|
+
- Node.js 18+
|
|
310
|
+
|
|
311
|
+
## Development
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
# Install dependencies
|
|
315
|
+
npm install
|
|
316
|
+
|
|
317
|
+
# Build the package
|
|
318
|
+
npm run build
|
|
319
|
+
|
|
320
|
+
# Run type checking
|
|
321
|
+
npm run typecheck
|
|
322
|
+
|
|
323
|
+
# Clean build files
|
|
324
|
+
npm run clean
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
## License
|
|
328
|
+
|
|
329
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
330
|
+
|
|
331
|
+
## Contributing
|
|
332
|
+
|
|
333
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
334
|
+
|
|
335
|
+
## Author
|
|
336
|
+
|
|
337
|
+
fehde-k
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { IMenu } from './contents/MenuList';
|
|
2
|
+
import { Theme } from './types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @interface IMenuBarProps
|
|
6
|
+
* @description Props for the MenuBar component.
|
|
7
|
+
* @description MenuBar コンポーネントの Props。
|
|
8
|
+
* @property {IMenu[]} menuList - The list of menu items. メニュー項目のリスト。
|
|
9
|
+
* @property {React.ReactNode} [menuHeader] - The header content of the menu. メニューのヘッダーコンテンツ。
|
|
10
|
+
* @property {() => void} onClickSignout - Function to handle sign out. サインアウトを処理する関数。
|
|
11
|
+
* @property {boolean} [isMenuhide] - Whether to hide the menu. メニューを非表示にするかどうか。
|
|
12
|
+
* @property {Theme} theme - The current theme.
|
|
13
|
+
* @property {() => void} toggleTheme - Function to toggle the theme.
|
|
14
|
+
*/
|
|
15
|
+
interface IMenuBarProps {
|
|
16
|
+
menuList: IMenu[];
|
|
17
|
+
menuHeader?: React.ReactNode;
|
|
18
|
+
onClickSignout(): void;
|
|
19
|
+
isMenuhide?: boolean;
|
|
20
|
+
theme: Theme;
|
|
21
|
+
toggleTheme: () => void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @function MenuBar
|
|
25
|
+
* @description A component that renders the main menu bar.
|
|
26
|
+
* @description メインメニューバーを描画するコンポーネント。
|
|
27
|
+
* @param {IMenuBarProps} props - The props for the component.
|
|
28
|
+
* @returns {React.JSX.Element} The rendered menu bar.
|
|
29
|
+
*/
|
|
30
|
+
export declare const MenuBar: (props: IMenuBarProps) => React.JSX.Element;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { GoogleUserProfile } from '../types/user';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Link component props interface.
|
|
5
|
+
* リンクコンポーネントのプロパティ。
|
|
6
|
+
*/
|
|
7
|
+
export interface LinkProps {
|
|
8
|
+
/** Link destination URL */
|
|
9
|
+
to: string;
|
|
10
|
+
/** CSS class name */
|
|
11
|
+
className?: string;
|
|
12
|
+
/** Link content */
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Generic Link component that can be replaced with router-specific implementation.
|
|
17
|
+
* ルーター固有の実装で置き換え可能な汎用リンクコンポーネント。
|
|
18
|
+
*/
|
|
19
|
+
export declare const DefaultLink: ({ to, className, children }: LinkProps) => React.JSX.Element;
|
|
20
|
+
/**
|
|
21
|
+
* SessionInfo component props interface.
|
|
22
|
+
* ユーザーセッション情報を表示するコンポーネントのプロパティ。
|
|
23
|
+
*/
|
|
24
|
+
export interface SessionInfoProps {
|
|
25
|
+
/** User profile information from Google OAuth */
|
|
26
|
+
user: GoogleUserProfile | null;
|
|
27
|
+
/** Custom Link component (optional, defaults to DefaultLink) */
|
|
28
|
+
LinkComponent?: React.ComponentType<LinkProps>;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* SessionInfo component for displaying user session information.
|
|
32
|
+
* Displays user profile photo, navigation links, and user name when authenticated.
|
|
33
|
+
*
|
|
34
|
+
* ユーザーセッション情報を表示するコンポーネント。
|
|
35
|
+
* 認証時にプロフィール写真、ナビゲーションリンク、ユーザー名を表示する。
|
|
36
|
+
*/
|
|
37
|
+
export declare const SessionInfo: (props: SessionInfoProps) => React.JSX.Element;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { IMenu } from './MenuList';
|
|
2
|
+
import { Theme } from '../types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @interface IMenuContentProps
|
|
6
|
+
* @description Props for the MenuContent component.
|
|
7
|
+
* @description MenuContent コンポーネントの Props。
|
|
8
|
+
* @property {IMenu[]} menuList - The list of menu items. メニュー項目のリスト。
|
|
9
|
+
* @property {React.ReactNode} [menuHeader] - The header content of the menu. メニューのヘッダーコンテンツ。
|
|
10
|
+
* @property {boolean} open - Whether the menu is open. メニューが開いているかどうか。
|
|
11
|
+
* @property {() => void} onMenuSelected - Function to handle menu item selection. メニュー項目選択を処理する関数。
|
|
12
|
+
* @property {() => void} onClickSignout - Function to handle sign out. サインアウトを処理する関数。
|
|
13
|
+
* @property {Theme} theme - The current theme.
|
|
14
|
+
* @property {() => void} toggleTheme - Function to toggle the theme.
|
|
15
|
+
*/
|
|
16
|
+
interface IMenuContentProps {
|
|
17
|
+
menuList: IMenu[];
|
|
18
|
+
menuHeader?: React.ReactNode;
|
|
19
|
+
open: boolean;
|
|
20
|
+
onMenuSelected(): void;
|
|
21
|
+
onClickSignout(): void;
|
|
22
|
+
theme: Theme;
|
|
23
|
+
toggleTheme: () => void;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Renders the content of the menu bar.
|
|
27
|
+
* メニューバーのコンテンツを描画します。
|
|
28
|
+
* @param {IMenuContentProps} props - The properties for the MenuContent component.
|
|
29
|
+
* @returns {React.JSX.Element} The rendered menu content.
|
|
30
|
+
*/
|
|
31
|
+
export declare const MenuContent: (props: IMenuContentProps) => React.JSX.Element;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @interface ISubmenu
|
|
3
|
+
* @description Interface for a submenu item.
|
|
4
|
+
* @description サブメニュー項目のインターフェース。
|
|
5
|
+
* @property {number} subid - The unique ID of the submenu item. サブメニュー項目の一意の ID。
|
|
6
|
+
* @property {string} [title] - The title of the submenu item. サブメニュー項目のタイトル。
|
|
7
|
+
* @property {string} href - The URL for the submenu item. サブメニュー項目の URL。
|
|
8
|
+
* @property {string} [mark] - The type of mark to display next to the item. 項目の横に表示するマークの種類。
|
|
9
|
+
* @property {boolean} [new] - Whether the item is a new link. 新しいリンクかどうか。
|
|
10
|
+
*/
|
|
11
|
+
export interface ISubmenu {
|
|
12
|
+
subid: number;
|
|
13
|
+
title?: string;
|
|
14
|
+
href: string;
|
|
15
|
+
mark?: string;
|
|
16
|
+
new?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* @interface IMenu
|
|
20
|
+
* @description Interface for a menu item.
|
|
21
|
+
* @description メニュー項目のインターフェース。
|
|
22
|
+
* @property {number} id - The unique ID of the menu item. メニュー項目の一意の ID。
|
|
23
|
+
* @property {string} title - The title of the menu item. メニュー項目のタイトル。
|
|
24
|
+
* @property {string} [href] - The URL for the menu item. メニュー項目の URL。
|
|
25
|
+
* @property {ISubmenu[]} submenu - The list of submenu items. サブメニュー項目のリスト。
|
|
26
|
+
*/
|
|
27
|
+
export interface IMenu {
|
|
28
|
+
id: number;
|
|
29
|
+
title: string;
|
|
30
|
+
href?: string;
|
|
31
|
+
submenu: ISubmenu[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* @interface IMenuListProps
|
|
35
|
+
* @description Props for the MenuList component.
|
|
36
|
+
* @description MenuList コンポーネントの Props。
|
|
37
|
+
* @property {IMenu[]} menuList - The list of menu items. メニュー項目のリスト。
|
|
38
|
+
* @property {() => void} [onMenuSelected] - Function to handle menu item selection. メニュー項目選択を処理する関数。
|
|
39
|
+
*/
|
|
40
|
+
interface IMenuListProps {
|
|
41
|
+
menuList: IMenu[];
|
|
42
|
+
onMenuSelected?(): void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* @function MenuList
|
|
46
|
+
* @description A component that renders the list of menu items.
|
|
47
|
+
* @description メニュー項目のリストを描画するコンポーネント。
|
|
48
|
+
* @param {IMenuListProps} props - The props for the component.
|
|
49
|
+
* @returns {React.JSX.Element} The rendered menu list.
|
|
50
|
+
*/
|
|
51
|
+
export declare const MenuList: (props: IMenuListProps) => React.JSX.Element;
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module OverlayShadow
|
|
3
|
+
* @description This module provides an overlay shadow component.
|
|
4
|
+
* @description このモジュールは、オーバーレイシャドウコンポーネントを提供します。
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @interface IOverlayProps
|
|
8
|
+
* @description Props for the OverlayShadow component.
|
|
9
|
+
* @description OverlayShadow コンポーネントの Props。
|
|
10
|
+
* @property {boolean} isOverlay - Whether the overlay is visible. オーバーレイが表示されているかどうか。
|
|
11
|
+
* @property {() => void} [onOverlayClick] - Function to handle overlay click. オーバーレイのクリックを処理する関数。
|
|
12
|
+
*/
|
|
13
|
+
interface IOverlayProps {
|
|
14
|
+
isOverlay: boolean;
|
|
15
|
+
onOverlayClick?(): void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @function OverlayShadow
|
|
19
|
+
* @description A component that renders an overlay shadow.
|
|
20
|
+
* @description オーバーレイシャドウを描画するコンポーネント。
|
|
21
|
+
* @param {IOverlayProps} props - The props for the component.
|
|
22
|
+
* @returns {React.JSX.Element} The rendered overlay shadow.
|
|
23
|
+
*/
|
|
24
|
+
export declare const OverlayShadow: (props: IOverlayProps) => React.JSX.Element;
|
|
25
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { MenuBar } from './MenuBar';
|
|
2
|
+
export type { IMenu, ISubmenu } from './contents/MenuList';
|
|
3
|
+
export type { Theme } from './types';
|
|
4
|
+
export { SessionInfo, DefaultLink } from './components/SessionInfo';
|
|
5
|
+
export type { SessionInfoProps, LinkProps } from './components/SessionInfo';
|
|
6
|
+
export type { GoogleUserProfile, UserPhoto } from './types/user';
|
package/dist/index.es.js
ADDED
|
@@ -0,0 +1,414 @@
|
|
|
1
|
+
import ce, { useRef as N, useCallback as k, useEffect as V, useState as X, useMemo as ie } from "react";
|
|
2
|
+
import { Link as B } from "react-router-dom";
|
|
3
|
+
import { Link as ue, Lock as de, Download as fe, BarChart as me, Table as xe, FileText as z } from "lucide-react";
|
|
4
|
+
var O = { exports: {} }, _ = {};
|
|
5
|
+
/**
|
|
6
|
+
* @license React
|
|
7
|
+
* react-jsx-runtime.production.js
|
|
8
|
+
*
|
|
9
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
10
|
+
*
|
|
11
|
+
* This source code is licensed under the MIT license found in the
|
|
12
|
+
* LICENSE file in the root directory of this source tree.
|
|
13
|
+
*/
|
|
14
|
+
var U;
|
|
15
|
+
function he() {
|
|
16
|
+
if (U) return _;
|
|
17
|
+
U = 1;
|
|
18
|
+
var s = Symbol.for("react.transitional.element"), a = Symbol.for("react.fragment");
|
|
19
|
+
function o(f, m, l) {
|
|
20
|
+
var c = null;
|
|
21
|
+
if (l !== void 0 && (c = "" + l), m.key !== void 0 && (c = "" + m.key), "key" in m) {
|
|
22
|
+
l = {};
|
|
23
|
+
for (var t in m)
|
|
24
|
+
t !== "key" && (l[t] = m[t]);
|
|
25
|
+
} else l = m;
|
|
26
|
+
return m = l.ref, {
|
|
27
|
+
$$typeof: s,
|
|
28
|
+
type: f,
|
|
29
|
+
key: c,
|
|
30
|
+
ref: m !== void 0 ? m : null,
|
|
31
|
+
props: l
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return _.Fragment = a, _.jsx = o, _.jsxs = o, _;
|
|
35
|
+
}
|
|
36
|
+
var T = {};
|
|
37
|
+
/**
|
|
38
|
+
* @license React
|
|
39
|
+
* react-jsx-runtime.development.js
|
|
40
|
+
*
|
|
41
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
42
|
+
*
|
|
43
|
+
* This source code is licensed under the MIT license found in the
|
|
44
|
+
* LICENSE file in the root directory of this source tree.
|
|
45
|
+
*/
|
|
46
|
+
var J;
|
|
47
|
+
function pe() {
|
|
48
|
+
return J || (J = 1, process.env.NODE_ENV !== "production" && function() {
|
|
49
|
+
function s(e) {
|
|
50
|
+
if (e == null) return null;
|
|
51
|
+
if (typeof e == "function")
|
|
52
|
+
return e.$$typeof === oe ? null : e.displayName || e.name || null;
|
|
53
|
+
if (typeof e == "string") return e;
|
|
54
|
+
switch (e) {
|
|
55
|
+
case R:
|
|
56
|
+
return "Fragment";
|
|
57
|
+
case Z:
|
|
58
|
+
return "Profiler";
|
|
59
|
+
case E:
|
|
60
|
+
return "StrictMode";
|
|
61
|
+
case re:
|
|
62
|
+
return "Suspense";
|
|
63
|
+
case ne:
|
|
64
|
+
return "SuspenseList";
|
|
65
|
+
case se:
|
|
66
|
+
return "Activity";
|
|
67
|
+
}
|
|
68
|
+
if (typeof e == "object")
|
|
69
|
+
switch (typeof e.tag == "number" && console.error(
|
|
70
|
+
"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
|
|
71
|
+
), e.$$typeof) {
|
|
72
|
+
case S:
|
|
73
|
+
return "Portal";
|
|
74
|
+
case K:
|
|
75
|
+
return (e.displayName || "Context") + ".Provider";
|
|
76
|
+
case Q:
|
|
77
|
+
return (e._context.displayName || "Context") + ".Consumer";
|
|
78
|
+
case ee:
|
|
79
|
+
var n = e.render;
|
|
80
|
+
return e = e.displayName, e || (e = n.displayName || n.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e;
|
|
81
|
+
case te:
|
|
82
|
+
return n = e.displayName || null, n !== null ? n : s(e.type) || "Memo";
|
|
83
|
+
case q:
|
|
84
|
+
n = e._payload, e = e._init;
|
|
85
|
+
try {
|
|
86
|
+
return s(e(n));
|
|
87
|
+
} catch {
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
function a(e) {
|
|
93
|
+
return "" + e;
|
|
94
|
+
}
|
|
95
|
+
function o(e) {
|
|
96
|
+
try {
|
|
97
|
+
a(e);
|
|
98
|
+
var n = !1;
|
|
99
|
+
} catch {
|
|
100
|
+
n = !0;
|
|
101
|
+
}
|
|
102
|
+
if (n) {
|
|
103
|
+
n = console;
|
|
104
|
+
var u = n.error, x = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object";
|
|
105
|
+
return u.call(
|
|
106
|
+
n,
|
|
107
|
+
"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",
|
|
108
|
+
x
|
|
109
|
+
), a(e);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function f(e) {
|
|
113
|
+
if (e === R) return "<>";
|
|
114
|
+
if (typeof e == "object" && e !== null && e.$$typeof === q)
|
|
115
|
+
return "<...>";
|
|
116
|
+
try {
|
|
117
|
+
var n = s(e);
|
|
118
|
+
return n ? "<" + n + ">" : "<...>";
|
|
119
|
+
} catch {
|
|
120
|
+
return "<...>";
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function m() {
|
|
124
|
+
var e = C.A;
|
|
125
|
+
return e === null ? null : e.getOwner();
|
|
126
|
+
}
|
|
127
|
+
function l() {
|
|
128
|
+
return Error("react-stack-top-frame");
|
|
129
|
+
}
|
|
130
|
+
function c(e) {
|
|
131
|
+
if (I.call(e, "key")) {
|
|
132
|
+
var n = Object.getOwnPropertyDescriptor(e, "key").get;
|
|
133
|
+
if (n && n.isReactWarning) return !1;
|
|
134
|
+
}
|
|
135
|
+
return e.key !== void 0;
|
|
136
|
+
}
|
|
137
|
+
function t(e, n) {
|
|
138
|
+
function u() {
|
|
139
|
+
Y || (Y = !0, console.error(
|
|
140
|
+
"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
|
|
141
|
+
n
|
|
142
|
+
));
|
|
143
|
+
}
|
|
144
|
+
u.isReactWarning = !0, Object.defineProperty(e, "key", {
|
|
145
|
+
get: u,
|
|
146
|
+
configurable: !0
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
function i() {
|
|
150
|
+
var e = s(this.type);
|
|
151
|
+
return $[e] || ($[e] = !0, console.error(
|
|
152
|
+
"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release."
|
|
153
|
+
)), e = this.props.ref, e !== void 0 ? e : null;
|
|
154
|
+
}
|
|
155
|
+
function p(e, n, u, x, j, v, P, L) {
|
|
156
|
+
return u = v.ref, e = {
|
|
157
|
+
$$typeof: y,
|
|
158
|
+
type: e,
|
|
159
|
+
key: n,
|
|
160
|
+
props: v,
|
|
161
|
+
_owner: j
|
|
162
|
+
}, (u !== void 0 ? u : null) !== null ? Object.defineProperty(e, "ref", {
|
|
163
|
+
enumerable: !1,
|
|
164
|
+
get: i
|
|
165
|
+
}) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", {
|
|
166
|
+
configurable: !1,
|
|
167
|
+
enumerable: !1,
|
|
168
|
+
writable: !0,
|
|
169
|
+
value: 0
|
|
170
|
+
}), Object.defineProperty(e, "_debugInfo", {
|
|
171
|
+
configurable: !1,
|
|
172
|
+
enumerable: !1,
|
|
173
|
+
writable: !0,
|
|
174
|
+
value: null
|
|
175
|
+
}), Object.defineProperty(e, "_debugStack", {
|
|
176
|
+
configurable: !1,
|
|
177
|
+
enumerable: !1,
|
|
178
|
+
writable: !0,
|
|
179
|
+
value: P
|
|
180
|
+
}), Object.defineProperty(e, "_debugTask", {
|
|
181
|
+
configurable: !1,
|
|
182
|
+
enumerable: !1,
|
|
183
|
+
writable: !0,
|
|
184
|
+
value: L
|
|
185
|
+
}), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e;
|
|
186
|
+
}
|
|
187
|
+
function d(e, n, u, x, j, v, P, L) {
|
|
188
|
+
var h = n.children;
|
|
189
|
+
if (h !== void 0)
|
|
190
|
+
if (x)
|
|
191
|
+
if (ae(h)) {
|
|
192
|
+
for (x = 0; x < h.length; x++)
|
|
193
|
+
g(h[x]);
|
|
194
|
+
Object.freeze && Object.freeze(h);
|
|
195
|
+
} else
|
|
196
|
+
console.error(
|
|
197
|
+
"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."
|
|
198
|
+
);
|
|
199
|
+
else g(h);
|
|
200
|
+
if (I.call(n, "key")) {
|
|
201
|
+
h = s(e);
|
|
202
|
+
var w = Object.keys(n).filter(function(le) {
|
|
203
|
+
return le !== "key";
|
|
204
|
+
});
|
|
205
|
+
x = 0 < w.length ? "{key: someKey, " + w.join(": ..., ") + ": ...}" : "{key: someKey}", W[h + x] || (w = 0 < w.length ? "{" + w.join(": ..., ") + ": ...}" : "{}", console.error(
|
|
206
|
+
`A props object containing a "key" prop is being spread into JSX:
|
|
207
|
+
let props = %s;
|
|
208
|
+
<%s {...props} />
|
|
209
|
+
React keys must be passed directly to JSX without using spread:
|
|
210
|
+
let props = %s;
|
|
211
|
+
<%s key={someKey} {...props} />`,
|
|
212
|
+
x,
|
|
213
|
+
h,
|
|
214
|
+
w,
|
|
215
|
+
h
|
|
216
|
+
), W[h + x] = !0);
|
|
217
|
+
}
|
|
218
|
+
if (h = null, u !== void 0 && (o(u), h = "" + u), c(n) && (o(n.key), h = "" + n.key), "key" in n) {
|
|
219
|
+
u = {};
|
|
220
|
+
for (var M in n)
|
|
221
|
+
M !== "key" && (u[M] = n[M]);
|
|
222
|
+
} else u = n;
|
|
223
|
+
return h && t(
|
|
224
|
+
u,
|
|
225
|
+
typeof e == "function" ? e.displayName || e.name || "Unknown" : e
|
|
226
|
+
), p(
|
|
227
|
+
e,
|
|
228
|
+
h,
|
|
229
|
+
v,
|
|
230
|
+
j,
|
|
231
|
+
m(),
|
|
232
|
+
u,
|
|
233
|
+
P,
|
|
234
|
+
L
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
function g(e) {
|
|
238
|
+
typeof e == "object" && e !== null && e.$$typeof === y && e._store && (e._store.validated = 1);
|
|
239
|
+
}
|
|
240
|
+
var b = ce, y = Symbol.for("react.transitional.element"), S = Symbol.for("react.portal"), R = Symbol.for("react.fragment"), E = Symbol.for("react.strict_mode"), Z = Symbol.for("react.profiler"), Q = Symbol.for("react.consumer"), K = Symbol.for("react.context"), ee = Symbol.for("react.forward_ref"), re = Symbol.for("react.suspense"), ne = Symbol.for("react.suspense_list"), te = Symbol.for("react.memo"), q = Symbol.for("react.lazy"), se = Symbol.for("react.activity"), oe = Symbol.for("react.client.reference"), C = b.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, I = Object.prototype.hasOwnProperty, ae = Array.isArray, A = console.createTask ? console.createTask : function() {
|
|
241
|
+
return null;
|
|
242
|
+
};
|
|
243
|
+
b = {
|
|
244
|
+
react_stack_bottom_frame: function(e) {
|
|
245
|
+
return e();
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
var Y, $ = {}, D = b.react_stack_bottom_frame.bind(
|
|
249
|
+
b,
|
|
250
|
+
l
|
|
251
|
+
)(), F = A(f(l)), W = {};
|
|
252
|
+
T.Fragment = R, T.jsx = function(e, n, u, x, j) {
|
|
253
|
+
var v = 1e4 > C.recentlyCreatedOwnerStacks++;
|
|
254
|
+
return d(
|
|
255
|
+
e,
|
|
256
|
+
n,
|
|
257
|
+
u,
|
|
258
|
+
!1,
|
|
259
|
+
x,
|
|
260
|
+
j,
|
|
261
|
+
v ? Error("react-stack-top-frame") : D,
|
|
262
|
+
v ? A(f(e)) : F
|
|
263
|
+
);
|
|
264
|
+
}, T.jsxs = function(e, n, u, x, j) {
|
|
265
|
+
var v = 1e4 > C.recentlyCreatedOwnerStacks++;
|
|
266
|
+
return d(
|
|
267
|
+
e,
|
|
268
|
+
n,
|
|
269
|
+
u,
|
|
270
|
+
!0,
|
|
271
|
+
x,
|
|
272
|
+
j,
|
|
273
|
+
v ? Error("react-stack-top-frame") : D,
|
|
274
|
+
v ? A(f(e)) : F
|
|
275
|
+
);
|
|
276
|
+
};
|
|
277
|
+
}()), T;
|
|
278
|
+
}
|
|
279
|
+
var G;
|
|
280
|
+
function be() {
|
|
281
|
+
return G || (G = 1, process.env.NODE_ENV === "production" ? O.exports = he() : O.exports = pe()), O.exports;
|
|
282
|
+
}
|
|
283
|
+
var r = be();
|
|
284
|
+
const ve = (s) => {
|
|
285
|
+
const { open: a, onMenuOpen: o, onMenuClose: f, theme: m } = s, l = N(a), c = N(null), t = N(null), i = N(null), p = N(null), d = N(null), g = k(() => {
|
|
286
|
+
if (c.current && t.current && i.current && p.current && d.current) {
|
|
287
|
+
const E = m === "dark" ? "#fff" : "#000";
|
|
288
|
+
c.current.style.backgroundColor = E, c.current.style.width = "100%", c.current.style.height = "3px", c.current.style.transform = "", t.current.style.opacity = "1", t.current.style.backgroundColor = E, i.current.style.opacity = "1", i.current.style.backgroundColor = E, p.current.style.backgroundColor = E, p.current.style.width = "100%", p.current.style.height = "3px", p.current.style.transform = "", d.current.style.color = E, d.current.classList.remove("after:content-['close']"), d.current.classList.remove("after:ml-0.5"), d.current.classList.add("after:content-['menu']"), d.current.classList.add("after:-ml-0.5"), l.current = !0;
|
|
289
|
+
}
|
|
290
|
+
}, [m]), b = k(() => {
|
|
291
|
+
c.current && t.current && i.current && p.current && d.current && (c.current.style.backgroundColor = "#fff", c.current.style.width = "32px", c.current.style.height = "4px", c.current.style.transform = "translateY(9px) rotate(-45deg)", t.current.style.opacity = "0", i.current.style.opacity = "0", p.current.style.backgroundColor = "#fff", p.current.style.width = "32px", p.current.style.height = "4px", p.current.style.transform = "translateY(-9px) rotate(45deg)", d.current.style.color = "#fff", d.current.classList.remove("after:content-['menu']"), d.current.classList.remove("after:-ml-0.5"), d.current.classList.add("after:content-['close']"), d.current.classList.add("after:ml-0.5"), l.current = !1);
|
|
292
|
+
}, []), y = k(() => {
|
|
293
|
+
g(), f && f();
|
|
294
|
+
}, [g, f]), S = k(() => {
|
|
295
|
+
b(), o && o();
|
|
296
|
+
}, [b, o]), R = k(() => {
|
|
297
|
+
l.current ? S() : y();
|
|
298
|
+
}, [y, S]);
|
|
299
|
+
return V(() => {
|
|
300
|
+
a ? g() : b();
|
|
301
|
+
}, [a, g, b]), /* @__PURE__ */ r.jsxs("button", { type: "button", className: "fixed top-5 right-5 z-2147483648 inline-block h-[27px] w-[27px] cursor-pointer align-middle outline-hidden", onClick: R, children: [
|
|
302
|
+
/* @__PURE__ */ r.jsx("span", { className: "absolute top-0 left-0 box-border inline-block h-[3px] w-full select-none transition-all duration-500", ref: c }),
|
|
303
|
+
/* @__PURE__ */ r.jsx("span", { className: "absolute top-[6px] left-0 box-border inline-block h-[3px] w-full select-none transition-all duration-500", ref: t }),
|
|
304
|
+
/* @__PURE__ */ r.jsx("span", { className: "absolute top-[12px] left-0 box-border inline-block h-[3px] w-full select-none transition-all duration-500", ref: i }),
|
|
305
|
+
/* @__PURE__ */ r.jsx("span", { className: "absolute top-[18px] left-0 box-border inline-block h-[3px] w-full select-none transition-all duration-500", ref: p }),
|
|
306
|
+
/* @__PURE__ */ r.jsx("div", { className: "absolute w-full text-xs transition-all duration-500 after:mt-2 after:block", ref: d })
|
|
307
|
+
] });
|
|
308
|
+
}, H = new RegExp(/(^https?:\/\/)|(\.(html|htm)?$)/), ke = {
|
|
309
|
+
report: z,
|
|
310
|
+
slip: z,
|
|
311
|
+
table: xe,
|
|
312
|
+
chart: me,
|
|
313
|
+
download: fe,
|
|
314
|
+
lock: de,
|
|
315
|
+
href: ue
|
|
316
|
+
}, ge = ({ mark: s, children: a }) => {
|
|
317
|
+
const o = s ? ke[s] : void 0;
|
|
318
|
+
return o ? /* @__PURE__ */ r.jsxs("div", { className: "flex flex-nowrap items-center", children: [
|
|
319
|
+
/* @__PURE__ */ r.jsx(o, { className: "h-4 w-4" }),
|
|
320
|
+
/* @__PURE__ */ r.jsx("div", { className: "aiquants-menu-link mx-1 hover:underline", children: a })
|
|
321
|
+
] }) : /* @__PURE__ */ r.jsx("span", { className: "mx-1 text-sky-600 hover:underline dark:text-sky-400", children: a });
|
|
322
|
+
}, je = ({ item: s, onMenuSelected: a }) => {
|
|
323
|
+
if (s.href === "separator")
|
|
324
|
+
return /* @__PURE__ */ r.jsx("hr", { className: "aiquants-menu-separator mx-2 my-1 h-px" });
|
|
325
|
+
const o = /* @__PURE__ */ r.jsx(ge, { mark: s.mark, children: s.title }), f = {
|
|
326
|
+
onClick: a
|
|
327
|
+
};
|
|
328
|
+
return s.new ? /* @__PURE__ */ r.jsx("a", { href: s.href, rel: "noopener noreferrer", target: "_blank", ...f, children: o }) : H.test(s.href) ? /* @__PURE__ */ r.jsx("a", { href: s.href, ...f, children: o }) : /* @__PURE__ */ r.jsx(B, { to: s.href, ...f, children: o });
|
|
329
|
+
}, ye = (s) => {
|
|
330
|
+
const { menuList: a, onMenuSelected: o } = s, [f, m] = X(null), l = k((t) => {
|
|
331
|
+
m((i) => i === t ? null : t);
|
|
332
|
+
}, []), c = ie(() => /* @__PURE__ */ r.jsx(r.Fragment, { children: a.map((t) => /* @__PURE__ */ r.jsx("div", { children: t.href ? /* @__PURE__ */ r.jsx("div", { className: "aiquants-menu-list-item before:-mt-1 relative mb-1 ml-1 h-full rounded-l-2xl p-2 align-middle text-sm before:mr-2 before:inline-block before:h-4 before:w-4 before:rounded-full before:align-middle before:content-['']", children: H.test(t.href) ? /* @__PURE__ */ r.jsx("a", { href: t.href, onClick: o, children: /* @__PURE__ */ r.jsx("span", { className: "aiquants-menu-link hover:underline", children: t.title }) }) : /* @__PURE__ */ r.jsx(B, { to: t.href, onClick: o, children: /* @__PURE__ */ r.jsx("span", { className: "aiquants-menu-link hover:underline", children: t.title }) }) }) : /* @__PURE__ */ r.jsxs("details", { className: "menu-accordion-details", open: t.id === f, children: [
|
|
333
|
+
/* @__PURE__ */ r.jsx(
|
|
334
|
+
"summary",
|
|
335
|
+
{
|
|
336
|
+
className: "aiquants-menu-list-item menu-accordion-summary before:-mt-1 relative mb-1 ml-1 h-full list-none rounded-l-2xl p-2 align-middle text-sm outline-none before:mr-2 before:inline-block before:h-4 before:w-4 before:rounded-full before:align-middle before:content-['']",
|
|
337
|
+
onClick: (i) => {
|
|
338
|
+
i.preventDefault(), l(t.id);
|
|
339
|
+
},
|
|
340
|
+
onKeyDown: (i) => {
|
|
341
|
+
(i.key === "Enter" || i.key === " ") && (i.preventDefault(), l(t.id));
|
|
342
|
+
},
|
|
343
|
+
children: /* @__PURE__ */ r.jsx("span", { children: t.title })
|
|
344
|
+
}
|
|
345
|
+
),
|
|
346
|
+
/* @__PURE__ */ r.jsx("div", { className: "aiquants-menu-submenu pointer-events-auto my-1 mr-1 ml-4 rounded p-2 shadow-md", children: t.submenu.map((i) => /* @__PURE__ */ r.jsx("div", { className: "menu-accordion-container block w-full whitespace-nowrap text-sm", children: /* @__PURE__ */ r.jsx(je, { item: i, onMenuSelected: o }) }, i.subid)) })
|
|
347
|
+
] }) }, t.id)) }), [a, o, f, l]);
|
|
348
|
+
return /* @__PURE__ */ r.jsx("div", { className: "hidden-scrollbar h-0 grow overflow-y-scroll", children: c });
|
|
349
|
+
}, Ee = (s) => {
|
|
350
|
+
const { menuList: a, menuHeader: o, open: f, onMenuSelected: m, onClickSignout: l, theme: c, toggleTheme: t } = s;
|
|
351
|
+
return /* @__PURE__ */ r.jsxs("div", { className: `aiquants-menu-content fixed top-0 right-0 z-2147483642 flex min-h-screen w-[250px] select-none flex-col transition-transform duration-500 ${f ? "aiquants-menu-translate-x-0" : "aiquants-menu-translate-x-250"}`, children: [
|
|
352
|
+
/* @__PURE__ */ r.jsx("div", { className: "flex h-[100px] flex-col", children: o }),
|
|
353
|
+
/* @__PURE__ */ r.jsx("div", { className: "flex grow flex-col", children: /* @__PURE__ */ r.jsx(ye, { menuList: a, onMenuSelected: m }) }),
|
|
354
|
+
/* @__PURE__ */ r.jsx("div", { className: "p-4", children: /* @__PURE__ */ r.jsxs("label", { className: "aiquants-theme-toggle", children: [
|
|
355
|
+
/* @__PURE__ */ r.jsx("input", { type: "checkbox", value: "", checked: c === "dark", onChange: t }),
|
|
356
|
+
/* @__PURE__ */ r.jsx("div", { className: "aiquants-theme-toggle-track", children: /* @__PURE__ */ r.jsx("div", { className: "aiquants-theme-toggle-thumb" }) }),
|
|
357
|
+
/* @__PURE__ */ r.jsxs("span", { className: "aiquants-theme-text aiquants-theme-toggle-text", children: [
|
|
358
|
+
c === "light" ? "Light" : "Dark",
|
|
359
|
+
" Mode"
|
|
360
|
+
] })
|
|
361
|
+
] }) }),
|
|
362
|
+
/* @__PURE__ */ r.jsx("div", { children: /* @__PURE__ */ r.jsx(
|
|
363
|
+
"button",
|
|
364
|
+
{
|
|
365
|
+
type: "button",
|
|
366
|
+
className: "aiquants-signout-button mx-2 my-5.5 rounded-lg px-5 py-2.5 font-medium text-sm text-white focus:outline-hidden focus:ring-4 focus:ring-blue-300",
|
|
367
|
+
onClick: l,
|
|
368
|
+
children: "サインアウト"
|
|
369
|
+
}
|
|
370
|
+
) })
|
|
371
|
+
] });
|
|
372
|
+
}, we = (s) => {
|
|
373
|
+
const { isOverlay: a, onOverlayClick: o } = s;
|
|
374
|
+
return /* @__PURE__ */ r.jsx("button", { type: "button", className: `fixed inset-0 z-2147483640 cursor-default bg-black/50 transition-opacity duration-500 ${a ? "opacity-100" : "pointer-events-none opacity-0"}`, onClick: o });
|
|
375
|
+
}, Se = (s) => {
|
|
376
|
+
const { menuList: a, menuHeader: o, onClickSignout: f, isMenuhide: m, theme: l, toggleTheme: c } = s, [t, i] = X(!1), p = k(() => {
|
|
377
|
+
i(!0);
|
|
378
|
+
}, []), d = k(() => {
|
|
379
|
+
i(!1);
|
|
380
|
+
}, []), g = k(() => {
|
|
381
|
+
i(!1);
|
|
382
|
+
}, []), b = k(
|
|
383
|
+
(y) => {
|
|
384
|
+
if (y.key === "Escape")
|
|
385
|
+
return d(), !1;
|
|
386
|
+
},
|
|
387
|
+
[d]
|
|
388
|
+
);
|
|
389
|
+
return V(() => (t ? window.addEventListener("keydown", b, { passive: !0 }) : window.removeEventListener("keydown", b), () => {
|
|
390
|
+
window.removeEventListener("keydown", b);
|
|
391
|
+
}), [t, b]), m ? /* @__PURE__ */ r.jsx(r.Fragment, {}) : /* @__PURE__ */ r.jsxs("div", { className: `aiquants-menu-bar ${l}`, children: [
|
|
392
|
+
/* @__PURE__ */ r.jsx(ve, { onMenuClose: d, onMenuOpen: p, open: !t, theme: l }),
|
|
393
|
+
/* @__PURE__ */ r.jsx(Ee, { menuList: a, menuHeader: o, onClickSignout: f, onMenuSelected: g, open: t, theme: l, toggleTheme: c }),
|
|
394
|
+
/* @__PURE__ */ r.jsx(we, { isOverlay: t, onOverlayClick: d })
|
|
395
|
+
] });
|
|
396
|
+
}, Ne = ({ to: s, className: a, children: o }) => /* @__PURE__ */ r.jsx("a", { href: s, className: a, children: o }), Oe = (s) => {
|
|
397
|
+
const { user: a, LinkComponent: o = Ne } = s;
|
|
398
|
+
return /* @__PURE__ */ r.jsx("div", { className: "max-h-20 max-w-52", children: /* @__PURE__ */ r.jsx("div", { className: "flex grow flex-col", children: a ? /* @__PURE__ */ r.jsxs(r.Fragment, { children: [
|
|
399
|
+
/* @__PURE__ */ r.jsxs("div", { className: "flex flex-row", children: [
|
|
400
|
+
/* @__PURE__ */ r.jsx("div", { className: "aiquants-session-photo m-1 h-14 w-14 p-0.5", children: /* @__PURE__ */ r.jsx("img", { className: "object-contain", src: a.photos[0].value, "aria-label": "profile photo" }) }),
|
|
401
|
+
/* @__PURE__ */ r.jsxs("div", { className: "mx-1 flex flex-col", children: [
|
|
402
|
+
/* @__PURE__ */ r.jsx(o, { className: "aiquants-session-link my-1 rounded-lg px-2 text-center text-xs", to: "/", children: "プロフィールを編集" }),
|
|
403
|
+
/* @__PURE__ */ r.jsx(o, { className: "aiquants-session-link rounded-lg px-2 text-center text-xs", to: "/", children: "プロフィール" }),
|
|
404
|
+
/* @__PURE__ */ r.jsx(o, { className: "aiquants-session-link my-1 rounded-lg px-2 text-center text-xs", to: "https://myaccount.google.com/", children: "Google Account" })
|
|
405
|
+
] })
|
|
406
|
+
] }),
|
|
407
|
+
/* @__PURE__ */ r.jsx("div", { className: "aiquants-session-info mb-1 min-h-[1em] w-full rounded-r-lg px-2 py-0.5 text-xs", children: a.displayName })
|
|
408
|
+
] }) : /* @__PURE__ */ r.jsx(r.Fragment, { children: /* @__PURE__ */ r.jsx("div", { className: "aiquants-session-info mb-1 min-h-[1em] w-9/12 rounded-r-lg py-0.5 pl-1 text-xs", children: "ログインはこちら" }) }) }) });
|
|
409
|
+
};
|
|
410
|
+
export {
|
|
411
|
+
Ne as DefaultLink,
|
|
412
|
+
Se as MenuBar,
|
|
413
|
+
Oe as SessionInfo
|
|
414
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
(function(v,l){typeof exports=="object"&&typeof module<"u"?l(exports,require("react"),require("react-router-dom"),require("lucide-react")):typeof define=="function"&&define.amd?define(["exports","react","react-router-dom","lucide-react"],l):(v=typeof globalThis<"u"?globalThis:v||self,l(v["@aiquants/menu-bar"]={},v.React,v.ReactRouterDOM,v["lucide-react"]))})(this,function(v,l,Y,E){"use strict";var S={exports:{}},T={};/**
|
|
2
|
+
* @license React
|
|
3
|
+
* react-jsx-runtime.production.js
|
|
4
|
+
*
|
|
5
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
6
|
+
*
|
|
7
|
+
* This source code is licensed under the MIT license found in the
|
|
8
|
+
* LICENSE file in the root directory of this source tree.
|
|
9
|
+
*/var D;function Z(){if(D)return T;D=1;var s=Symbol.for("react.transitional.element"),o=Symbol.for("react.fragment");function a(m,x,c){var i=null;if(c!==void 0&&(i=""+c),x.key!==void 0&&(i=""+x.key),"key"in x){c={};for(var r in x)r!=="key"&&(c[r]=x[r])}else c=x;return x=c.ref,{$$typeof:s,type:m,key:i,ref:x!==void 0?x:null,props:c}}return T.Fragment=o,T.jsx=a,T.jsxs=a,T}var _={};/**
|
|
10
|
+
* @license React
|
|
11
|
+
* react-jsx-runtime.development.js
|
|
12
|
+
*
|
|
13
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
14
|
+
*
|
|
15
|
+
* This source code is licensed under the MIT license found in the
|
|
16
|
+
* LICENSE file in the root directory of this source tree.
|
|
17
|
+
*/var F;function Q(){return F||(F=1,process.env.NODE_ENV!=="production"&&function(){function s(e){if(e==null)return null;if(typeof e=="function")return e.$$typeof===pe?null:e.displayName||e.name||null;if(typeof e=="string")return e;switch(e){case C:return"Fragment";case ce:return"Profiler";case N:return"StrictMode";case de:return"Suspense";case me:return"SuspenseList";case he:return"Activity"}if(typeof e=="object")switch(typeof e.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),e.$$typeof){case O:return"Portal";case ue:return(e.displayName||"Context")+".Provider";case ie:return(e._context.displayName||"Context")+".Consumer";case fe:var t=e.render;return e=e.displayName,e||(e=t.displayName||t.name||"",e=e!==""?"ForwardRef("+e+")":"ForwardRef"),e;case xe:return t=e.displayName||null,t!==null?t:s(e.type)||"Memo";case U:t=e._payload,e=e._init;try{return s(e(t))}catch{}}return null}function o(e){return""+e}function a(e){try{o(e);var t=!1}catch{t=!0}if(t){t=console;var f=t.error,h=typeof Symbol=="function"&&Symbol.toStringTag&&e[Symbol.toStringTag]||e.constructor.name||"Object";return f.call(t,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",h),o(e)}}function m(e){if(e===C)return"<>";if(typeof e=="object"&&e!==null&&e.$$typeof===U)return"<...>";try{var t=s(e);return t?"<"+t+">":"<...>"}catch{return"<...>"}}function x(){var e=A.A;return e===null?null:e.getOwner()}function c(){return Error("react-stack-top-frame")}function i(e){if(J.call(e,"key")){var t=Object.getOwnPropertyDescriptor(e,"key").get;if(t&&t.isReactWarning)return!1}return e.key!==void 0}function r(e,t){function f(){G||(G=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",t))}f.isReactWarning=!0,Object.defineProperty(e,"key",{get:f,configurable:!0})}function u(){var e=s(this.type);return V[e]||(V[e]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),e=this.props.ref,e!==void 0?e:null}function b(e,t,f,h,g,y,M,L){return f=y.ref,e={$$typeof:w,type:e,key:t,props:y,_owner:g},(f!==void 0?f:null)!==null?Object.defineProperty(e,"ref",{enumerable:!1,get:u}):Object.defineProperty(e,"ref",{enumerable:!1,value:null}),e._store={},Object.defineProperty(e._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(e,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(e,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:M}),Object.defineProperty(e,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:L}),Object.freeze&&(Object.freeze(e.props),Object.freeze(e)),e}function d(e,t,f,h,g,y,M,L){var p=t.children;if(p!==void 0)if(h)if(be(p)){for(h=0;h<p.length;h++)j(p[h]);Object.freeze&&Object.freeze(p)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else j(p);if(J.call(t,"key")){p=s(e);var R=Object.keys(t).filter(function(ke){return ke!=="key"});h=0<R.length?"{key: someKey, "+R.join(": ..., ")+": ...}":"{key: someKey}",H[p+h]||(R=0<R.length?"{"+R.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
|
|
18
|
+
let props = %s;
|
|
19
|
+
<%s {...props} />
|
|
20
|
+
React keys must be passed directly to JSX without using spread:
|
|
21
|
+
let props = %s;
|
|
22
|
+
<%s key={someKey} {...props} />`,h,p,R,p),H[p+h]=!0)}if(p=null,f!==void 0&&(a(f),p=""+f),i(t)&&(a(t.key),p=""+t.key),"key"in t){f={};for(var I in t)I!=="key"&&(f[I]=t[I])}else f=t;return p&&r(f,typeof e=="function"?e.displayName||e.name||"Unknown":e),b(e,p,y,g,x(),f,M,L)}function j(e){typeof e=="object"&&e!==null&&e.$$typeof===w&&e._store&&(e._store.validated=1)}var k=l,w=Symbol.for("react.transitional.element"),O=Symbol.for("react.portal"),C=Symbol.for("react.fragment"),N=Symbol.for("react.strict_mode"),ce=Symbol.for("react.profiler"),ie=Symbol.for("react.consumer"),ue=Symbol.for("react.context"),fe=Symbol.for("react.forward_ref"),de=Symbol.for("react.suspense"),me=Symbol.for("react.suspense_list"),xe=Symbol.for("react.memo"),U=Symbol.for("react.lazy"),he=Symbol.for("react.activity"),pe=Symbol.for("react.client.reference"),A=k.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,J=Object.prototype.hasOwnProperty,be=Array.isArray,P=console.createTask?console.createTask:function(){return null};k={react_stack_bottom_frame:function(e){return e()}};var G,V={},B=k.react_stack_bottom_frame.bind(k,c)(),X=P(m(c)),H={};_.Fragment=C,_.jsx=function(e,t,f,h,g){var y=1e4>A.recentlyCreatedOwnerStacks++;return d(e,t,f,!1,h,g,y?Error("react-stack-top-frame"):B,y?P(m(e)):X)},_.jsxs=function(e,t,f,h,g){var y=1e4>A.recentlyCreatedOwnerStacks++;return d(e,t,f,!0,h,g,y?Error("react-stack-top-frame"):B,y?P(m(e)):X)}}()),_}var q;function K(){return q||(q=1,process.env.NODE_ENV==="production"?S.exports=Z():S.exports=Q()),S.exports}var n=K();const $=s=>{const{open:o,onMenuOpen:a,onMenuClose:m,theme:x}=s,c=l.useRef(o),i=l.useRef(null),r=l.useRef(null),u=l.useRef(null),b=l.useRef(null),d=l.useRef(null),j=l.useCallback(()=>{if(i.current&&r.current&&u.current&&b.current&&d.current){const N=x==="dark"?"#fff":"#000";i.current.style.backgroundColor=N,i.current.style.width="100%",i.current.style.height="3px",i.current.style.transform="",r.current.style.opacity="1",r.current.style.backgroundColor=N,u.current.style.opacity="1",u.current.style.backgroundColor=N,b.current.style.backgroundColor=N,b.current.style.width="100%",b.current.style.height="3px",b.current.style.transform="",d.current.style.color=N,d.current.classList.remove("after:content-['close']"),d.current.classList.remove("after:ml-0.5"),d.current.classList.add("after:content-['menu']"),d.current.classList.add("after:-ml-0.5"),c.current=!0}},[x]),k=l.useCallback(()=>{i.current&&r.current&&u.current&&b.current&&d.current&&(i.current.style.backgroundColor="#fff",i.current.style.width="32px",i.current.style.height="4px",i.current.style.transform="translateY(9px) rotate(-45deg)",r.current.style.opacity="0",u.current.style.opacity="0",b.current.style.backgroundColor="#fff",b.current.style.width="32px",b.current.style.height="4px",b.current.style.transform="translateY(-9px) rotate(45deg)",d.current.style.color="#fff",d.current.classList.remove("after:content-['menu']"),d.current.classList.remove("after:-ml-0.5"),d.current.classList.add("after:content-['close']"),d.current.classList.add("after:ml-0.5"),c.current=!1)},[]),w=l.useCallback(()=>{j(),m&&m()},[j,m]),O=l.useCallback(()=>{k(),a&&a()},[k,a]),C=l.useCallback(()=>{c.current?O():w()},[w,O]);return l.useEffect(()=>{o?j():k()},[o,j,k]),n.jsxs("button",{type:"button",className:"fixed top-5 right-5 z-2147483648 inline-block h-[27px] w-[27px] cursor-pointer align-middle outline-hidden",onClick:C,children:[n.jsx("span",{className:"absolute top-0 left-0 box-border inline-block h-[3px] w-full select-none transition-all duration-500",ref:i}),n.jsx("span",{className:"absolute top-[6px] left-0 box-border inline-block h-[3px] w-full select-none transition-all duration-500",ref:r}),n.jsx("span",{className:"absolute top-[12px] left-0 box-border inline-block h-[3px] w-full select-none transition-all duration-500",ref:u}),n.jsx("span",{className:"absolute top-[18px] left-0 box-border inline-block h-[3px] w-full select-none transition-all duration-500",ref:b}),n.jsx("div",{className:"absolute w-full text-xs transition-all duration-500 after:mt-2 after:block",ref:d})]})},W=new RegExp(/(^https?:\/\/)|(\.(html|htm)?$)/),ee={report:E.FileText,slip:E.FileText,table:E.Table,chart:E.BarChart,download:E.Download,lock:E.Lock,href:E.Link},ne=({mark:s,children:o})=>{const a=s?ee[s]:void 0;return a?n.jsxs("div",{className:"flex flex-nowrap items-center",children:[n.jsx(a,{className:"h-4 w-4"}),n.jsx("div",{className:"aiquants-menu-link mx-1 hover:underline",children:o})]}):n.jsx("span",{className:"mx-1 text-sky-600 hover:underline dark:text-sky-400",children:o})},te=({item:s,onMenuSelected:o})=>{if(s.href==="separator")return n.jsx("hr",{className:"aiquants-menu-separator mx-2 my-1 h-px"});const a=n.jsx(ne,{mark:s.mark,children:s.title}),m={onClick:o};return s.new?n.jsx("a",{href:s.href,rel:"noopener noreferrer",target:"_blank",...m,children:a}):W.test(s.href)?n.jsx("a",{href:s.href,...m,children:a}):n.jsx(Y.Link,{to:s.href,...m,children:a})},re=s=>{const{menuList:o,onMenuSelected:a}=s,[m,x]=l.useState(null),c=l.useCallback(r=>{x(u=>u===r?null:r)},[]),i=l.useMemo(()=>n.jsx(n.Fragment,{children:o.map(r=>n.jsx("div",{children:r.href?n.jsx("div",{className:"aiquants-menu-list-item before:-mt-1 relative mb-1 ml-1 h-full rounded-l-2xl p-2 align-middle text-sm before:mr-2 before:inline-block before:h-4 before:w-4 before:rounded-full before:align-middle before:content-['']",children:W.test(r.href)?n.jsx("a",{href:r.href,onClick:a,children:n.jsx("span",{className:"aiquants-menu-link hover:underline",children:r.title})}):n.jsx(Y.Link,{to:r.href,onClick:a,children:n.jsx("span",{className:"aiquants-menu-link hover:underline",children:r.title})})}):n.jsxs("details",{className:"menu-accordion-details",open:r.id===m,children:[n.jsx("summary",{className:"aiquants-menu-list-item menu-accordion-summary before:-mt-1 relative mb-1 ml-1 h-full list-none rounded-l-2xl p-2 align-middle text-sm outline-none before:mr-2 before:inline-block before:h-4 before:w-4 before:rounded-full before:align-middle before:content-['']",onClick:u=>{u.preventDefault(),c(r.id)},onKeyDown:u=>{(u.key==="Enter"||u.key===" ")&&(u.preventDefault(),c(r.id))},children:n.jsx("span",{children:r.title})}),n.jsx("div",{className:"aiquants-menu-submenu pointer-events-auto my-1 mr-1 ml-4 rounded p-2 shadow-md",children:r.submenu.map(u=>n.jsx("div",{className:"menu-accordion-container block w-full whitespace-nowrap text-sm",children:n.jsx(te,{item:u,onMenuSelected:a})},u.subid))})]})},r.id))}),[o,a,m,c]);return n.jsx("div",{className:"hidden-scrollbar h-0 grow overflow-y-scroll",children:i})},se=s=>{const{menuList:o,menuHeader:a,open:m,onMenuSelected:x,onClickSignout:c,theme:i,toggleTheme:r}=s;return n.jsxs("div",{className:`aiquants-menu-content fixed top-0 right-0 z-2147483642 flex min-h-screen w-[250px] select-none flex-col transition-transform duration-500 ${m?"aiquants-menu-translate-x-0":"aiquants-menu-translate-x-250"}`,children:[n.jsx("div",{className:"flex h-[100px] flex-col",children:a}),n.jsx("div",{className:"flex grow flex-col",children:n.jsx(re,{menuList:o,onMenuSelected:x})}),n.jsx("div",{className:"p-4",children:n.jsxs("label",{className:"aiquants-theme-toggle",children:[n.jsx("input",{type:"checkbox",value:"",checked:i==="dark",onChange:r}),n.jsx("div",{className:"aiquants-theme-toggle-track",children:n.jsx("div",{className:"aiquants-theme-toggle-thumb"})}),n.jsxs("span",{className:"aiquants-theme-text aiquants-theme-toggle-text",children:[i==="light"?"Light":"Dark"," Mode"]})]})}),n.jsx("div",{children:n.jsx("button",{type:"button",className:"aiquants-signout-button mx-2 my-5.5 rounded-lg px-5 py-2.5 font-medium text-sm text-white focus:outline-hidden focus:ring-4 focus:ring-blue-300",onClick:c,children:"サインアウト"})})]})},ae=s=>{const{isOverlay:o,onOverlayClick:a}=s;return n.jsx("button",{type:"button",className:`fixed inset-0 z-2147483640 cursor-default bg-black/50 transition-opacity duration-500 ${o?"opacity-100":"pointer-events-none opacity-0"}`,onClick:a})},oe=s=>{const{menuList:o,menuHeader:a,onClickSignout:m,isMenuhide:x,theme:c,toggleTheme:i}=s,[r,u]=l.useState(!1),b=l.useCallback(()=>{u(!0)},[]),d=l.useCallback(()=>{u(!1)},[]),j=l.useCallback(()=>{u(!1)},[]),k=l.useCallback(w=>{if(w.key==="Escape")return d(),!1},[d]);return l.useEffect(()=>(r?window.addEventListener("keydown",k,{passive:!0}):window.removeEventListener("keydown",k),()=>{window.removeEventListener("keydown",k)}),[r,k]),x?n.jsx(n.Fragment,{}):n.jsxs("div",{className:`aiquants-menu-bar ${c}`,children:[n.jsx($,{onMenuClose:d,onMenuOpen:b,open:!r,theme:c}),n.jsx(se,{menuList:o,menuHeader:a,onClickSignout:m,onMenuSelected:j,open:r,theme:c,toggleTheme:i}),n.jsx(ae,{isOverlay:r,onOverlayClick:d})]})},z=({to:s,className:o,children:a})=>n.jsx("a",{href:s,className:o,children:a}),le=s=>{const{user:o,LinkComponent:a=z}=s;return n.jsx("div",{className:"max-h-20 max-w-52",children:n.jsx("div",{className:"flex grow flex-col",children:o?n.jsxs(n.Fragment,{children:[n.jsxs("div",{className:"flex flex-row",children:[n.jsx("div",{className:"aiquants-session-photo m-1 h-14 w-14 p-0.5",children:n.jsx("img",{className:"object-contain",src:o.photos[0].value,"aria-label":"profile photo"})}),n.jsxs("div",{className:"mx-1 flex flex-col",children:[n.jsx(a,{className:"aiquants-session-link my-1 rounded-lg px-2 text-center text-xs",to:"/",children:"プロフィールを編集"}),n.jsx(a,{className:"aiquants-session-link rounded-lg px-2 text-center text-xs",to:"/",children:"プロフィール"}),n.jsx(a,{className:"aiquants-session-link my-1 rounded-lg px-2 text-center text-xs",to:"https://myaccount.google.com/",children:"Google Account"})]})]}),n.jsx("div",{className:"aiquants-session-info mb-1 min-h-[1em] w-full rounded-r-lg px-2 py-0.5 text-xs",children:o.displayName})]}):n.jsx(n.Fragment,{children:n.jsx("div",{className:"aiquants-session-info mb-1 min-h-[1em] w-9/12 rounded-r-lg py-0.5 pl-1 text-xs",children:"ログインはこちら"})})})})};v.DefaultLink=z,v.MenuBar=oe,v.SessionInfo=le,Object.defineProperty(v,Symbol.toStringTag,{value:"Module"})});
|
package/dist/menuBar.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.aiquants-menu-bar{font-size:1rem;line-height:1.5rem}.aiquants-menu-bar *{box-sizing:border-box}.aiquants-menu-bar a,.aiquants-menu-bar button{text-decoration:none;border:none;background:none;cursor:pointer}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .pointer-events-none{pointer-events:none}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .pointer-events-auto{pointer-events:auto}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .visible{visibility:visible}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .fixed{position:fixed}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .absolute{position:absolute}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .relative{position:relative}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .inset-0{inset:0}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .left-0{left:0}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .right-0{right:0}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .right-5{right:1.25rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .top-0{top:0}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .top-5{top:1.25rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .top-\[12px\]{top:12px}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .top-\[18px\]{top:18px}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .top-\[6px\]{top:6px}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .z-2147483640{z-index:2147483640}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .z-2147483642{z-index:2147483642}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .z-2147483648{z-index:2147483648}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .m-1{margin:.25rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .mx-1{margin-left:.25rem;margin-right:.25rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .mx-2{margin-left:.5rem;margin-right:.5rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .my-1{margin-top:.25rem;margin-bottom:.25rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .mb-1{margin-bottom:.25rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .ml-1{margin-left:.25rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .ml-4{margin-left:1rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .mr-1{margin-right:.25rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .box-border{box-sizing:border-box}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .block{display:block}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .inline-block{display:inline-block}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .flex{display:flex}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .table{display:table}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .h-0{height:0px}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .h-14{height:3.5rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .h-4{height:1rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .h-\[100px\]{height:100px}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .h-\[27px\]{height:27px}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .h-\[3px\]{height:3px}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .h-full{height:100%}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .h-px{height:1px}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .max-h-20{max-height:5rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .min-h-\[1em\]{min-height:1em}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .min-h-screen{min-height:100vh}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .w-14{width:3.5rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .w-4{width:1rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .w-9\/12{width:75%}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .w-\[250px\]{width:250px}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .w-\[27px\]{width:27px}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .w-full{width:100%}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .max-w-52{max-width:13rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .grow{flex-grow:1}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .cursor-default{cursor:default}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .cursor-pointer{cursor:pointer}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .list-none{list-style-type:none}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .flex-row{flex-direction:row}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .flex-col{flex-direction:column}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .flex-nowrap{flex-wrap:nowrap}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .items-center{align-items:center}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .overflow-y-scroll{overflow-y:scroll}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .whitespace-nowrap{white-space:nowrap}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .rounded{border-radius:.25rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .rounded-lg{border-radius:.5rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .rounded-l-2xl{border-top-left-radius:1rem;border-bottom-left-radius:1rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .rounded-r-lg{border-top-right-radius:.5rem;border-bottom-right-radius:.5rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .bg-black\/50{background-color:#00000080}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .object-contain{-o-object-fit:contain;object-fit:contain}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .p-0\.5{padding:.125rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .p-2{padding:.5rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .p-4{padding:1rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .px-2{padding-left:.5rem;padding-right:.5rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .px-5{padding-left:1.25rem;padding-right:1.25rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .py-0\.5{padding-top:.125rem;padding-bottom:.125rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .py-2\.5{padding-top:.625rem;padding-bottom:.625rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .pl-1{padding-left:.25rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .text-center{text-align:center}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .align-middle{vertical-align:middle}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .text-sm{font-size:.875rem;line-height:1.25rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .text-xs{font-size:.75rem;line-height:1rem}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .font-medium{font-weight:500}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .text-sky-600{--tw-text-opacity: 1;color:rgb(2 132 199 / var(--tw-text-opacity, 1))}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .opacity-0{opacity:0}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .opacity-100{opacity:1}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .outline-none{outline:2px solid transparent;outline-offset:2px}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}:is(.aiquants-menu-bar,.aiquants-menu-bar *) .duration-500{transition-duration:.5s}.aiquants-menu-bar.dark{color-scheme:dark}.aiquants-menu-bar.dark .aiquants-menu-content{background-color:#0f172a}.aiquants-menu-bar.light .aiquants-menu-content,.aiquants-menu-bar .aiquants-menu-content{background-color:#0369a1}.aiquants-menu-bar.dark .aiquants-signout-button{background-color:#334155}.aiquants-menu-bar.dark .aiquants-signout-button:hover{background-color:#475569}.aiquants-menu-bar.light .aiquants-signout-button,.aiquants-menu-bar .aiquants-signout-button{background-color:#2563eb}.aiquants-menu-bar.light .aiquants-signout-button:hover,.aiquants-menu-bar .aiquants-signout-button:hover{background-color:#1e40af}.aiquants-menu-bar.dark .aiquants-theme-text{color:#d1d5db}.aiquants-menu-bar.light .aiquants-theme-text,.aiquants-menu-bar .aiquants-theme-text{color:#fff}.aiquants-menu-bar.dark .aiquants-menu-list-item{background-color:#334155;color:#d1d5db}.aiquants-menu-bar.dark .aiquants-menu-list-item:before{background-color:#94a3b8}.aiquants-menu-bar.dark .aiquants-menu-submenu{background-color:#1e293b}.aiquants-menu-bar.dark .aiquants-menu-link{color:#38bdf8}.aiquants-menu-bar.dark .aiquants-menu-separator{border-color:#4b5563}.aiquants-menu-bar.light .aiquants-menu-list-item,.aiquants-menu-bar .aiquants-menu-list-item{background-color:#bae6fd;color:#4b5563}.aiquants-menu-bar.light .aiquants-menu-list-item:before,.aiquants-menu-bar .aiquants-menu-list-item:before{background-color:#fff}.aiquants-menu-bar.light .aiquants-menu-submenu,.aiquants-menu-bar .aiquants-menu-submenu{background-color:#fafafa}.aiquants-menu-bar.light .aiquants-menu-link,.aiquants-menu-bar .aiquants-menu-link{color:#0284c7}.aiquants-menu-bar.light .aiquants-menu-separator,.aiquants-menu-bar .aiquants-menu-separator{border-color:#4b5563}.aiquants-menu-bar.dark .aiquants-session-photo{background-color:#27272a}.aiquants-menu-bar.dark .aiquants-session-link,.aiquants-menu-bar.dark .aiquants-session-info{background-color:#334155;color:#e2e8f0}.aiquants-menu-bar.light .aiquants-session-photo,.aiquants-menu-bar .aiquants-session-photo{background-color:#fafafa}.aiquants-menu-bar.light .aiquants-session-link,.aiquants-menu-bar .aiquants-session-link,.aiquants-menu-bar.light .aiquants-session-info,.aiquants-menu-bar .aiquants-session-info{background-color:#dcfce7;color:#000}.aiquants-menu-accordion-summary{display:block;align-items:left;cursor:pointer}.aiquants-menu-accordion-summary::-webkit-details-marker{display:none}.aiquants-menu-accordion-container{transition:block-size .5s;contain:content}.aiquants-menu-translate-x-0{transform:translate(0)}.aiquants-menu-translate-x-250{transform:translate(250px)}.aiquants-theme-toggle{position:relative;display:inline-flex;cursor:pointer;align-items:center}.aiquants-theme-toggle input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.aiquants-theme-toggle-track{height:24px;width:44px;border-radius:9999px;background-color:#e5e7eb;position:relative;transition:background-color .2s ease}.aiquants-theme-toggle-thumb{position:absolute;top:2px;left:2px;height:20px;width:20px;border-radius:9999px;border:1px solid rgb(209 213 219);background-color:#fff;transition:all .2s ease}.aiquants-theme-toggle input:checked+.aiquants-theme-toggle-track{background-color:#2563eb}.aiquants-theme-toggle input:checked+.aiquants-theme-toggle-track .aiquants-theme-toggle-thumb{transform:translate(20px);border-color:#fff}.aiquants-theme-toggle input:focus+.aiquants-theme-toggle-track{outline:none;box-shadow:0 0 0 4px #93c5fd}.aiquants-menu-bar.dark .aiquants-theme-toggle-track{background-color:#374151;border-color:#4b5563}.aiquants-menu-bar.dark .aiquants-theme-toggle input:checked+.aiquants-theme-toggle-track{background-color:#2563eb}.aiquants-menu-bar.dark .aiquants-theme-toggle input:focus+.aiquants-theme-toggle-track{box-shadow:0 0 0 4px #1e3a8a}.aiquants-theme-toggle-text{margin-left:12px;font-size:14px;font-weight:500}.before\:-mt-1:before{content:var(--tw-content);margin-top:-.25rem}.before\:mr-2:before{content:var(--tw-content);margin-right:.5rem}.before\:inline-block:before{content:var(--tw-content);display:inline-block}.before\:h-4:before{content:var(--tw-content);height:1rem}.before\:w-4:before{content:var(--tw-content);width:1rem}.before\:rounded-full:before{content:var(--tw-content);border-radius:9999px}.before\:align-middle:before{content:var(--tw-content);vertical-align:middle}.before\:content-\[\'\'\]:before{--tw-content: "";content:var(--tw-content)}.after\:-ml-0\.5:after{content:var(--tw-content);margin-left:-.125rem}.after\:ml-0\.5:after{content:var(--tw-content);margin-left:.125rem}.after\:mt-2:after{content:var(--tw-content);margin-top:.5rem}.after\:block:after{content:var(--tw-content);display:block}.after\:content-\[\'close\'\]:after{--tw-content: "close";content:var(--tw-content)}.after\:content-\[\'menu\'\]:after{--tw-content: "menu";content:var(--tw-content)}.hover\:underline:hover{text-decoration-line:underline}.focus\:ring-4:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-blue-300:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(147 197 253 / var(--tw-ring-opacity, 1))}@media (prefers-color-scheme: dark){.dark\:text-sky-400{--tw-text-opacity: 1;color:rgb(56 189 248 / var(--tw-text-opacity, 1))}}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User profile photo information.
|
|
3
|
+
* ユーザープロフィール写真情報。
|
|
4
|
+
*/
|
|
5
|
+
export interface UserPhoto {
|
|
6
|
+
/** Photo URL */
|
|
7
|
+
value: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Google user profile information.
|
|
11
|
+
* Googleユーザープロフィール情報。
|
|
12
|
+
*/
|
|
13
|
+
export interface GoogleUserProfile {
|
|
14
|
+
/** User display name */
|
|
15
|
+
displayName: string;
|
|
16
|
+
/** Array of user photos */
|
|
17
|
+
photos: UserPhoto[];
|
|
18
|
+
/** User ID */
|
|
19
|
+
id?: string;
|
|
20
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type Theme = "light" | "dark";
|
package/package.json
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@aiquants/menu-bar",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "A React menu bar component with authentication support and theming",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"react",
|
|
8
|
+
"menu",
|
|
9
|
+
"navigation",
|
|
10
|
+
"authentication",
|
|
11
|
+
"theme",
|
|
12
|
+
"dark-mode",
|
|
13
|
+
"component",
|
|
14
|
+
"ui"
|
|
15
|
+
],
|
|
16
|
+
"author": {
|
|
17
|
+
"name": "fehde-k",
|
|
18
|
+
"url": "https://github.com/fehde-k"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"main": "dist/index.umd.js",
|
|
22
|
+
"module": "dist/index.es.js",
|
|
23
|
+
"types": "dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.es.js",
|
|
28
|
+
"require": "./dist/index.umd.js"
|
|
29
|
+
},
|
|
30
|
+
"./css": "./dist/menuBar.css"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"README.md",
|
|
35
|
+
"LICENSE"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"build": "vite build",
|
|
39
|
+
"dev": "vite build --watch",
|
|
40
|
+
"typecheck": "tsc --noEmit",
|
|
41
|
+
"clean": "rm -rf dist",
|
|
42
|
+
"prepublishOnly": "npm run clean && npm run typecheck && npm run build",
|
|
43
|
+
"publish:patch": "npm version patch && npm publish",
|
|
44
|
+
"publish:minor": "npm version minor && npm publish",
|
|
45
|
+
"publish:major": "npm version major && npm publish"
|
|
46
|
+
},
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18.0.0",
|
|
49
|
+
"npm": ">=8.0.0"
|
|
50
|
+
},
|
|
51
|
+
"peerDependencies": {
|
|
52
|
+
"react": "^19.1.0",
|
|
53
|
+
"react-dom": "^19.1.0",
|
|
54
|
+
"react-router-dom": "^7.7.1",
|
|
55
|
+
"lucide-react": "^0.473.0"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/react": "^19.1.9",
|
|
59
|
+
"@types/react-dom": "^19.1.7",
|
|
60
|
+
"@vitejs/plugin-react": "^4.2.1",
|
|
61
|
+
"react": "^19.1.0",
|
|
62
|
+
"react-dom": "^19.1.0",
|
|
63
|
+
"react-router-dom": "^7.7.1",
|
|
64
|
+
"typescript": "^5.3.3",
|
|
65
|
+
"vite": "^7.0.6",
|
|
66
|
+
"vite-plugin-dts": "^3.7.2",
|
|
67
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
68
|
+
"lucide-react": "^0.473.0",
|
|
69
|
+
"tailwindcss": "^3.4.0",
|
|
70
|
+
"autoprefixer": "^10.4.0",
|
|
71
|
+
"postcss": "^8.4.0"
|
|
72
|
+
},
|
|
73
|
+
"dependencies": {}
|
|
74
|
+
}
|