@herongxhr/ui-react 0.1.2 → 0.1.3

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.
@@ -0,0 +1,10 @@
1
+ export interface AccountMenuProps {
2
+ name: string;
3
+ description?: string;
4
+ avatarUrl?: string;
5
+ loggingOut?: boolean;
6
+ logoutDisabled?: boolean;
7
+ onLogout: () => void;
8
+ className?: string;
9
+ }
10
+ export declare function AccountMenu({ name, description, avatarUrl, loggingOut, logoutDisabled, onLogout, className }: AccountMenuProps): import("react").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Menu } from '@base-ui/react/menu';
3
+ import { ChevronDown, LogOut } from 'lucide-react';
4
+ import { Avatar } from './avatar.js';
5
+ export function AccountMenu({ name, description, avatarUrl, loggingOut = false, logoutDisabled = false, onLogout, className }) {
6
+ const displayName = name.trim() || '已登录账号';
7
+ const detail = description?.trim();
8
+ return _jsx("div", { className: ['hrui-account-menu', className].filter(Boolean).join(' '), children: _jsxs(Menu.Root, { modal: false, children: [_jsxs(Menu.Trigger, { className: "hrui-account-trigger", "aria-label": `打开${displayName}的账号菜单`, children: [_jsx(Avatar, { src: avatarUrl, alt: "", size: "small" }), _jsx("span", { className: "hrui-account-trigger-name", children: displayName }), _jsx(ChevronDown, { className: "hrui-account-chevron", "aria-hidden": "true" })] }), _jsx(Menu.Portal, { children: _jsx(Menu.Positioner, { className: "hrui-account-positioner", side: "bottom", align: "end", sideOffset: 8, children: _jsxs(Menu.Popup, { className: "hrui-account-popup", "aria-label": `${displayName}的账号菜单`, children: [_jsxs("div", { className: "hrui-account-summary", children: [_jsx(Avatar, { src: avatarUrl, alt: "" }), _jsxs("div", { className: "hrui-account-identity", children: [_jsx("strong", { children: displayName }), detail && _jsx("span", { children: detail })] })] }), _jsx(Menu.Separator, { className: "hrui-account-separator" }), _jsxs(Menu.Item, { className: "hrui-account-logout", closeOnClick: false, disabled: loggingOut || logoutDisabled, "aria-busy": loggingOut || undefined, label: "\u9000\u51FA\u767B\u5F55", onClick: () => { if (!loggingOut && !logoutDisabled)
9
+ onLogout(); }, children: [_jsx(LogOut, { "aria-hidden": "true" }), _jsx("span", { children: loggingOut ? '正在退出…' : '退出登录' })] })] }) }) })] }) });
10
+ }
@@ -0,0 +1,7 @@
1
+ export interface AvatarProps {
2
+ src?: string;
3
+ alt?: string;
4
+ size?: 'small' | 'medium';
5
+ className?: string;
6
+ }
7
+ export declare function Avatar({ src, alt, size, className }: AvatarProps): import("react").JSX.Element;
package/dist/avatar.js ADDED
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Avatar as BaseAvatar } from '@base-ui/react/avatar';
3
+ import { UserRound } from 'lucide-react';
4
+ export function Avatar({ src, alt = '用户头像', size = 'medium', className }) {
5
+ return _jsxs(BaseAvatar.Root, { className: ['hrui-avatar', className].filter(Boolean).join(' '), "data-size": size, "aria-hidden": alt === '' || undefined, children: [src && _jsx(BaseAvatar.Image, { className: "hrui-avatar-image", src: src, alt: alt, referrerPolicy: "no-referrer" }), _jsx(BaseAvatar.Fallback, { className: "hrui-avatar-fallback", role: alt ? 'img' : undefined, "aria-label": alt || undefined, children: _jsx(UserRound, { "aria-hidden": "true" }) })] }, src || '');
6
+ }
package/dist/index.d.ts CHANGED
@@ -2,4 +2,6 @@ export * from './select.js';
2
2
  export * from './dialog.js';
3
3
  export * from './theme-select.js';
4
4
  export * from './theme-toggle.js';
5
+ export * from './avatar.js';
6
+ export * from './account-menu.js';
5
7
  export { CSPProvider } from '@base-ui/react/csp-provider';
package/dist/index.js CHANGED
@@ -2,4 +2,6 @@ export * from './select.js';
2
2
  export * from './dialog.js';
3
3
  export * from './theme-select.js';
4
4
  export * from './theme-toggle.js';
5
+ export * from './avatar.js';
6
+ export * from './account-menu.js';
5
7
  export { CSPProvider } from '@base-ui/react/csp-provider';
package/dist/styles.css CHANGED
@@ -158,6 +158,33 @@
158
158
  }
159
159
  .hrui-theme-toggle-system>svg { width: var(--hr-ui-icon-medium); height: var(--hr-ui-icon-medium); stroke-width: var(--hr-ui-icon-stroke); }
160
160
  .hrui-theme-toggle-system[aria-pressed="true"] { color: var(--hr-ui-color-accent); background: var(--hr-ui-color-accent-soft); }
161
+ .hrui-avatar { position: relative; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; width: var(--hr-ui-space-10); height: var(--hr-ui-space-10); overflow: hidden; border-radius: var(--hr-ui-radius-round); background: var(--hr-ui-color-surface-raised); color: var(--hr-ui-color-muted); }
162
+ .hrui-avatar[data-size="small"] { width: var(--hr-ui-space-8); height: var(--hr-ui-space-8); }
163
+ .hrui-avatar-image { position: absolute; inset: 0; display: block; width: 100%; height: 100%; object-fit: cover; }
164
+ .hrui-avatar-fallback { display: inline-flex; align-items: center; justify-content: center; width: 100%; height: 100%; }
165
+ .hrui-avatar-fallback svg { width: var(--hr-ui-icon-medium); height: var(--hr-ui-icon-medium); stroke-width: var(--hr-ui-icon-stroke); }
166
+ .hrui-account-menu { display: inline-flex; align-items: center; min-width: 0; }
167
+ .hrui-account-trigger { appearance: none; box-sizing: border-box; display: inline-flex; align-items: center; gap: var(--hr-ui-space-2); min-height: var(--hr-ui-control-height); min-width: var(--hr-ui-control-height); max-width: 100%; padding: var(--hr-ui-space-1) var(--hr-ui-space-2); border: 0; border-radius: var(--hr-ui-radius-medium); background: transparent; color: var(--hr-ui-color-text); font: var(--hr-ui-font-small)/var(--hr-ui-leading-heading) var(--hr-ui-font-sans); cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; transition: background-color var(--hr-ui-transition-fast), color var(--hr-ui-transition-fast); }
168
+ .hrui-account-trigger:hover,.hrui-account-trigger[data-popup-open] { background: var(--hr-ui-color-surface-raised); }
169
+ .hrui-account-trigger:focus-visible { outline: var(--hr-ui-focus-width-subtle) solid var(--hr-ui-color-focus); outline-offset: var(--hr-ui-focus-offset); }
170
+ .hrui-account-trigger-name { min-width: 0; max-width: var(--hr-ui-popover-width-small); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: var(--hr-ui-weight-medium); }
171
+ .hrui-account-chevron { width: var(--hr-ui-icon-small); height: var(--hr-ui-icon-small); flex-shrink: 0; color: var(--hr-ui-color-subtle); stroke-width: var(--hr-ui-icon-stroke); transition: transform var(--hr-ui-transition-fast) var(--hr-ui-motion-easing-standard); }
172
+ .hrui-account-trigger[data-popup-open] .hrui-account-chevron { transform: rotate(180deg); }
173
+ .hrui-account-positioner { z-index: var(--hr-ui-layer-popover); outline: none; }
174
+ .hrui-account-popup { box-sizing: border-box; width: calc(var(--hr-ui-popover-width-small) + var(--hr-ui-space-8)); max-width: var(--available-width); max-height: var(--available-height); overflow-y: auto; overscroll-behavior: contain; padding: var(--hr-ui-space-1); border: var(--hr-ui-border-width) solid var(--hr-ui-color-border); border-radius: var(--hr-ui-radius-medium); background: var(--hr-ui-color-surface); color: var(--hr-ui-color-text); box-shadow: var(--hr-ui-shadow-popover); font: var(--hr-ui-font-small)/var(--hr-ui-leading-body) var(--hr-ui-font-sans); outline: none; transform-origin: var(--transform-origin); opacity: 1; transform: translateY(0) scale(1); transition: opacity var(--hr-ui-transition-fast) var(--hr-ui-motion-easing-standard), transform var(--hr-ui-transition-normal) var(--hr-ui-motion-easing-standard); }
175
+ .hrui-account-popup[data-starting-style],.hrui-account-popup[data-ending-style] { opacity: 0; transform: translateY(calc(-1 * var(--hr-ui-space-1))) scale(var(--hr-ui-motion-scale-enter)); }
176
+ .hrui-account-popup[data-ending-style] { transition-duration: var(--hr-ui-transition-fast); }
177
+ .hrui-account-summary { display: flex; align-items: center; gap: var(--hr-ui-space-3); padding: var(--hr-ui-space-3); }
178
+ .hrui-account-identity { display: flex; flex-direction: column; min-width: 0; gap: var(--hr-ui-space-1); overflow-wrap: anywhere; }
179
+ .hrui-account-identity strong { font-size: var(--hr-ui-font-small); font-weight: var(--hr-ui-weight-semibold); line-height: var(--hr-ui-leading-heading); }
180
+ .hrui-account-identity>span { color: var(--hr-ui-color-subtle); font-size: var(--hr-ui-font-caption); }
181
+ .hrui-account-separator { height: var(--hr-ui-border-width); margin: var(--hr-ui-space-1) 0; background: var(--hr-ui-color-border); }
182
+ .hrui-account-logout { box-sizing: border-box; display: flex; align-items: center; gap: var(--hr-ui-space-3); min-height: var(--hr-ui-control-height); padding: var(--hr-ui-space-3); border-radius: var(--hr-ui-radius-small); outline: none; cursor: pointer; user-select: none; color: var(--hr-ui-color-text); transition: color var(--hr-ui-transition-fast), background-color var(--hr-ui-transition-fast); }
183
+ .hrui-account-logout[data-highlighted] { color: var(--hr-ui-color-highlight-text); background: var(--hr-ui-color-highlight); }
184
+ .hrui-account-logout:focus-visible { outline: var(--hr-ui-focus-width-subtle) solid var(--hr-ui-color-focus); outline-offset: calc(-1 * var(--hr-ui-focus-width-subtle)); }
185
+ .hrui-account-logout[data-disabled] { opacity: var(--hr-ui-opacity-disabled); cursor: not-allowed; }
186
+ .hrui-account-logout svg { width: var(--hr-ui-icon-medium); height: var(--hr-ui-icon-medium); stroke-width: var(--hr-ui-icon-stroke); flex-shrink: 0; }
187
+ @media (max-width: 760px) { .hrui-account-trigger-name { display: none; } }
161
188
  .hrui-dialog-backdrop { position: fixed; inset: 0; z-index: var(--hr-ui-layer-backdrop); background: var(--hr-ui-color-scrim); transition: opacity var(--hr-ui-transition-fast) var(--hr-ui-motion-easing-standard); }
162
189
  .hrui-dialog-backdrop[data-starting-style],
163
190
  .hrui-dialog-backdrop[data-ending-style] { opacity: 0; }
@@ -170,5 +197,6 @@
170
197
  @media (max-width: 760px) { .hrui-dialog-viewport { padding: var(--hr-ui-space-2); } }
171
198
  @media (prefers-reduced-motion: reduce) {
172
199
  .hrui-select-trigger, .hrui-select-icon, .hrui-select-popup, .hrui-select-item,
173
- .hrui-dialog-backdrop, .hrui-dialog-popup, .hrui-theme-toggle-button, .hrui-theme-toggle-icon { transition: none; }
200
+ .hrui-dialog-backdrop, .hrui-dialog-popup, .hrui-theme-toggle-button, .hrui-theme-toggle-icon,
201
+ .hrui-account-trigger, .hrui-account-chevron, .hrui-account-popup, .hrui-account-logout { transition: none; }
174
202
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@herongxhr/ui-react",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "license": "UNLICENSED",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/",