@@ -475,33 +480,42 @@ export function AppearanceMarketDialog({ isOpen, onClose }: AppearanceMarketDial
data-openbitfun-part="marketNav"
aria-label={t('package.market.views.label')}
>
-
+
{account.me && (
-
+
)}
{account.me?.isAdmin && (
-
+
)}
{view !== 'browse' ?
: detail ? renderDetail() : (
diff --git a/src/web-ui/src/infrastructure/config/components/AppearanceSettingsPage.scss b/src/web-ui/src/infrastructure/config/components/AppearanceSettingsPage.scss
index 9ba5fcf1b1..c35d4b4593 100644
--- a/src/web-ui/src/infrastructure/config/components/AppearanceSettingsPage.scss
+++ b/src/web-ui/src/infrastructure/config/components/AppearanceSettingsPage.scss
@@ -338,6 +338,10 @@
}
+.appearance-market__dialog-header {
+ align-items: center;
+}
+
/* Fixed height: every view scrolls internally so the dialog never resizes while loading. */
.appearance-market__modal {
min-height: min(720px, 78vh);
@@ -359,7 +363,20 @@
padding-bottom: var(--openbitfun-space-2);
border-bottom: 1px solid var(--openbitfun-color-border-default);
- button {
+ .appearance-market__nav-item {
+ inline-size: auto;
+ min-inline-size: min-content;
+ min-block-size: 0;
+ align-items: stretch;
+ padding: 0;
+ gap: 0;
+ border-radius: var(--openbitfun-radius-sm);
+ background: transparent;
+ box-shadow: none;
+ transition: none;
+ }
+
+ .appearance-market__nav-item > [data-openbitfun-part='trigger'] {
padding: var(--openbitfun-space-2) var(--openbitfun-space-3);
border: 0;
border-radius: var(--openbitfun-radius-sm);
@@ -367,8 +384,19 @@
color: var(--openbitfun-color-content-secondary);
font: inherit;
font-size: var(--openbitfun-type-label-md-font-size);
+ text-align: center;
+ white-space: normal;
cursor: pointer;
+ @layer openbitfun.components {
+ outline: revert-layer;
+ }
+
+ > [data-openbitfun-part='label'] {
+ font: inherit;
+ letter-spacing: inherit;
+ }
+
&:hover {
background: var(--openbitfun-color-surface-subtle);
color: var(--openbitfun-color-content-primary);
diff --git a/src/web-ui/src/shared/ui/OverflowText.test.tsx b/src/web-ui/src/shared/ui/OverflowText.test.tsx
index 6388037812..1e6d634492 100644
--- a/src/web-ui/src/shared/ui/OverflowText.test.tsx
+++ b/src/web-ui/src/shared/ui/OverflowText.test.tsx
@@ -75,6 +75,28 @@ describe('overflow text full-content access', () => {
expect(button.getAttribute('aria-describedby')).toBe('help');
});
+ it('keeps interaction-only ellipsis idle on virtual selection and reveals full text on focus', () => {
+ render(
);
+ const label = host.querySelector
('[data-overflow]')!;
+ expect(label.getAttribute('data-overflow')).toBe('true');
+ expect(label.getAttribute('data-marquee-active')).toBeNull();
+ reveal();
+ expect(tooltip()).toBeNull();
+ act(() => host.querySelector('button')!.focus());
+ reveal();
+ expect(tooltip()?.textContent).toBe(longLabel);
+ act(() => {
+ availableWidth = 1000;
+ resizeCallbacks.forEach(callback => callback());
+ });
+ expect(label.getAttribute('data-overflow')).toBe('false');
+ expect(tooltip()).toBeNull();
+ });
+
it('keeps the command tooltip open when portal enter precedes native trigger leave', () => {
render();
expect(host.querySelector('[title]')).toBeNull();