diff --git a/OpenBitFun-Installer/src/assets/openbitfun-mark-dark.png b/OpenBitFun-Installer/src/assets/openbitfun-mark-dark.png index bac28ae23d..8cf2ee11b4 100644 Binary files a/OpenBitFun-Installer/src/assets/openbitfun-mark-dark.png and b/OpenBitFun-Installer/src/assets/openbitfun-mark-dark.png differ diff --git a/OpenBitFun-Installer/src/assets/openbitfun-mark-light.png b/OpenBitFun-Installer/src/assets/openbitfun-mark-light.png index 424fb3da81..2f9eb6c395 100644 Binary files a/OpenBitFun-Installer/src/assets/openbitfun-mark-light.png and b/OpenBitFun-Installer/src/assets/openbitfun-mark-light.png differ diff --git a/assets/brand/exports/openbitfun-mark-dark-1024.png b/assets/brand/exports/openbitfun-mark-dark-1024.png index 2f05bb8ad6..de297b3e84 100644 Binary files a/assets/brand/exports/openbitfun-mark-dark-1024.png and b/assets/brand/exports/openbitfun-mark-dark-1024.png differ diff --git a/assets/brand/exports/openbitfun-mark-dark-128.png b/assets/brand/exports/openbitfun-mark-dark-128.png index 2b1748c5d6..cd9395ab5a 100644 Binary files a/assets/brand/exports/openbitfun-mark-dark-128.png and b/assets/brand/exports/openbitfun-mark-dark-128.png differ diff --git a/assets/brand/exports/openbitfun-mark-dark-16.png b/assets/brand/exports/openbitfun-mark-dark-16.png index 5174241dbc..c0006ff775 100644 Binary files a/assets/brand/exports/openbitfun-mark-dark-16.png and b/assets/brand/exports/openbitfun-mark-dark-16.png differ diff --git a/assets/brand/exports/openbitfun-mark-dark-192.png b/assets/brand/exports/openbitfun-mark-dark-192.png index 7536aa81e4..8522512039 100644 Binary files a/assets/brand/exports/openbitfun-mark-dark-192.png and b/assets/brand/exports/openbitfun-mark-dark-192.png differ diff --git a/assets/brand/exports/openbitfun-mark-dark-2048.png b/assets/brand/exports/openbitfun-mark-dark-2048.png index 6baf9db7ad..ccb35c2754 100644 Binary files a/assets/brand/exports/openbitfun-mark-dark-2048.png and b/assets/brand/exports/openbitfun-mark-dark-2048.png differ diff --git a/assets/brand/exports/openbitfun-mark-dark-24.png b/assets/brand/exports/openbitfun-mark-dark-24.png index ecac76b4c4..569d89bf35 100644 Binary files a/assets/brand/exports/openbitfun-mark-dark-24.png and b/assets/brand/exports/openbitfun-mark-dark-24.png differ diff --git a/assets/brand/exports/openbitfun-mark-dark-256.png b/assets/brand/exports/openbitfun-mark-dark-256.png index 997989485b..a14b2966c7 100644 Binary files a/assets/brand/exports/openbitfun-mark-dark-256.png and b/assets/brand/exports/openbitfun-mark-dark-256.png differ diff --git a/assets/brand/exports/openbitfun-mark-dark-32.png b/assets/brand/exports/openbitfun-mark-dark-32.png index 07a239bd85..c89bb3c2ef 100644 Binary files a/assets/brand/exports/openbitfun-mark-dark-32.png and b/assets/brand/exports/openbitfun-mark-dark-32.png differ diff --git a/assets/brand/exports/openbitfun-mark-dark-48.png b/assets/brand/exports/openbitfun-mark-dark-48.png index 16e1e03bab..a8034f9f1c 100644 Binary files a/assets/brand/exports/openbitfun-mark-dark-48.png and b/assets/brand/exports/openbitfun-mark-dark-48.png differ diff --git a/assets/brand/exports/openbitfun-mark-dark-512.png b/assets/brand/exports/openbitfun-mark-dark-512.png index bac28ae23d..8cf2ee11b4 100644 Binary files a/assets/brand/exports/openbitfun-mark-dark-512.png and b/assets/brand/exports/openbitfun-mark-dark-512.png differ diff --git a/assets/brand/exports/openbitfun-mark-dark-64.png b/assets/brand/exports/openbitfun-mark-dark-64.png index 9ebc6ac820..98d0f9b7ac 100644 Binary files a/assets/brand/exports/openbitfun-mark-dark-64.png and b/assets/brand/exports/openbitfun-mark-dark-64.png differ diff --git a/assets/brand/exports/openbitfun-mark-dark-96.png b/assets/brand/exports/openbitfun-mark-dark-96.png index 5939dd2554..32d8bccddc 100644 Binary files a/assets/brand/exports/openbitfun-mark-dark-96.png and b/assets/brand/exports/openbitfun-mark-dark-96.png differ diff --git a/assets/brand/exports/openbitfun-mark-light-1024.png b/assets/brand/exports/openbitfun-mark-light-1024.png index e220e333c1..5a920a1d50 100644 Binary files a/assets/brand/exports/openbitfun-mark-light-1024.png and b/assets/brand/exports/openbitfun-mark-light-1024.png differ diff --git a/assets/brand/exports/openbitfun-mark-light-128.png b/assets/brand/exports/openbitfun-mark-light-128.png index cf2a3f8872..1332840376 100644 Binary files a/assets/brand/exports/openbitfun-mark-light-128.png and b/assets/brand/exports/openbitfun-mark-light-128.png differ diff --git a/assets/brand/exports/openbitfun-mark-light-16.png b/assets/brand/exports/openbitfun-mark-light-16.png index 6fb9dc2dfc..66399c736e 100644 Binary files a/assets/brand/exports/openbitfun-mark-light-16.png and b/assets/brand/exports/openbitfun-mark-light-16.png differ diff --git a/assets/brand/exports/openbitfun-mark-light-192.png b/assets/brand/exports/openbitfun-mark-light-192.png index e182fea980..843376c5bc 100644 Binary files a/assets/brand/exports/openbitfun-mark-light-192.png and b/assets/brand/exports/openbitfun-mark-light-192.png differ diff --git a/assets/brand/exports/openbitfun-mark-light-2048.png b/assets/brand/exports/openbitfun-mark-light-2048.png index d791098d08..f340b4f7b6 100644 Binary files a/assets/brand/exports/openbitfun-mark-light-2048.png and b/assets/brand/exports/openbitfun-mark-light-2048.png differ diff --git a/assets/brand/exports/openbitfun-mark-light-24.png b/assets/brand/exports/openbitfun-mark-light-24.png index 9b1ff0ee2a..720d0ae687 100644 Binary files a/assets/brand/exports/openbitfun-mark-light-24.png and b/assets/brand/exports/openbitfun-mark-light-24.png differ diff --git a/assets/brand/exports/openbitfun-mark-light-256.png b/assets/brand/exports/openbitfun-mark-light-256.png index cf855d1d65..0bf92c7847 100644 Binary files a/assets/brand/exports/openbitfun-mark-light-256.png and b/assets/brand/exports/openbitfun-mark-light-256.png differ diff --git a/assets/brand/exports/openbitfun-mark-light-32.png b/assets/brand/exports/openbitfun-mark-light-32.png index bf01046043..cfdcae0d5f 100644 Binary files a/assets/brand/exports/openbitfun-mark-light-32.png and b/assets/brand/exports/openbitfun-mark-light-32.png differ diff --git a/assets/brand/exports/openbitfun-mark-light-48.png b/assets/brand/exports/openbitfun-mark-light-48.png index a8a103f989..bf09bb8943 100644 Binary files a/assets/brand/exports/openbitfun-mark-light-48.png and b/assets/brand/exports/openbitfun-mark-light-48.png differ diff --git a/assets/brand/exports/openbitfun-mark-light-512.png b/assets/brand/exports/openbitfun-mark-light-512.png index 424fb3da81..2f9eb6c395 100644 Binary files a/assets/brand/exports/openbitfun-mark-light-512.png and b/assets/brand/exports/openbitfun-mark-light-512.png differ diff --git a/assets/brand/exports/openbitfun-mark-light-64.png b/assets/brand/exports/openbitfun-mark-light-64.png index 3682661d24..5b46ba3c3b 100644 Binary files a/assets/brand/exports/openbitfun-mark-light-64.png and b/assets/brand/exports/openbitfun-mark-light-64.png differ diff --git a/assets/brand/exports/openbitfun-mark-light-96.png b/assets/brand/exports/openbitfun-mark-light-96.png index 0412017e8b..1dc84b8bb0 100644 Binary files a/assets/brand/exports/openbitfun-mark-light-96.png and b/assets/brand/exports/openbitfun-mark-light-96.png differ diff --git a/assets/brand/exports/openbitfun-mark.svg b/assets/brand/exports/openbitfun-mark.svg index a62f9a7115..87e0152c06 100644 --- a/assets/brand/exports/openbitfun-mark.svg +++ b/assets/brand/exports/openbitfun-mark.svg @@ -1,19 +1,17 @@ - - OpenBitFun - Static fine-line mark. Fifteen rounded hexagonal contours, with a transparent background. - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/assets/brand/source/openbitfun-mark-dark.png b/assets/brand/source/openbitfun-mark-dark.png index bac28ae23d..8cf2ee11b4 100644 Binary files a/assets/brand/source/openbitfun-mark-dark.png and b/assets/brand/source/openbitfun-mark-dark.png differ diff --git a/assets/brand/source/openbitfun-mark-light.png b/assets/brand/source/openbitfun-mark-light.png index 424fb3da81..2f9eb6c395 100644 Binary files a/assets/brand/source/openbitfun-mark-light.png and b/assets/brand/source/openbitfun-mark-light.png differ diff --git a/assets/brand/source/openbitfun-mark.svg b/assets/brand/source/openbitfun-mark.svg index a62f9a7115..87e0152c06 100644 --- a/assets/brand/source/openbitfun-mark.svg +++ b/assets/brand/source/openbitfun-mark.svg @@ -1,19 +1,17 @@ - - OpenBitFun - Static fine-line mark. Fifteen rounded hexagonal contours, with a transparent background. - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + diff --git a/design-system/AGENTS.md b/design-system/AGENTS.md index a8fa5dc6a4..faa01ab5d9 100644 --- a/design-system/AGENTS.md +++ b/design-system/AGENTS.md @@ -10,6 +10,7 @@ This file applies to `design-system/**`. Repository-wide rules in the root `AGEN - `@openbitfun/ui` owns React anatomy, behavior, accessibility, and stable variants. It must remain independent from product routes, stores, locale catalogs, Tauri APIs, and concrete themes. - `@openbitfun/design-tokens` owns theme-independent names and system scales. `@openbitfun/theme-openbitfun` supplies replaceable reference and semantic values. - Components consume semantic or system CSS variables. Raw colors are forbidden in public component CSS. Component-private variables use the `--_` prefix. +- Single-line text slots use `OverflowText`: plain text defaults to fade-out truncation plus an interaction marquee; rich composition keeps its layout unless explicitly opted in. Keep icons/actions outside the text slot, mark the owning control with `data-overflow-trigger`, and preserve wrapping or native editing where appropriate. See the UI package README for the shared interaction contract. - Files under `dist/` are generated and must not be edited or committed. - Design Lab may alias `@openbitfun/ui` to source only during Vite development for HMR. Its production build must consume package exports. - `@openbitfun/ui/registry` is the source of truth for published components. Design Lab derives navigation, counts, token scopes, and detail routes from that registry; Lab-only previews or copy must never add, retain, or remove a package component. diff --git a/design-system/packages/design-tokens/src/system.tokens.json b/design-system/packages/design-tokens/src/system.tokens.json index 20c2b4cdd4..8a67d617a8 100644 --- a/design-system/packages/design-tokens/src/system.tokens.json +++ b/design-system/packages/design-tokens/src/system.tokens.json @@ -659,9 +659,9 @@ }, "confirmDialog": { "contentGap": { "$value": "{space.4}" }, - "messageGap": { "$value": "{space.3}" }, + "messageGap": { "$value": "{space.2}" }, "iconSize": { "$value": "32px" }, - "iconGlyphSize": { "$value": "18px" }, + "iconGlyphSize": { "$value": "{control.icon.sizeMd}" }, "previewMaxBlockSize": { "$value": "240px" }, "previewPaddingBlock": { "$value": "{space.3}" }, "previewPaddingInline": { "$value": "{space.4}" }, diff --git a/design-system/packages/design-tokens/tests/contract.test.mjs b/design-system/packages/design-tokens/tests/contract.test.mjs index fd33dd1cfa..67cf0a97cd 100644 --- a/design-system/packages/design-tokens/tests/contract.test.mjs +++ b/design-system/packages/design-tokens/tests/contract.test.mjs @@ -296,9 +296,9 @@ test("ConfirmDialog tokens preserve semantic content and preview composition", a const systemDocument = await readSource("system.tokens.json"); assert.equal(tokens["layout.confirmDialog.contentGap"], "16px"); - assert.equal(tokens["layout.confirmDialog.messageGap"], "12px"); + assert.equal(tokens["layout.confirmDialog.messageGap"], "8px"); assert.equal(tokens["layout.confirmDialog.iconSize"], "32px"); - assert.equal(tokens["layout.confirmDialog.iconGlyphSize"], "18px"); + assert.equal(tokens["layout.confirmDialog.iconGlyphSize"], "16px"); assert.equal(tokens["layout.confirmDialog.previewMaxBlockSize"], "240px"); assert.equal(tokens["layout.spinner.matrixCellXs"], "3px"); assert.equal(tokens["layout.spinner.matrixCellSm"], "4px"); diff --git a/design-system/packages/ui/README.md b/design-system/packages/ui/README.md index cb9a77bb70..6b838180ef 100644 --- a/design-system/packages/ui/README.md +++ b/design-system/packages/ui/README.md @@ -18,6 +18,61 @@ export function Example() { The package owns component anatomy, behavior, accessibility, and stable variants. It does not own theme selection persistence, product state, routes, locale resources, or platform APIs. +## Text overflow + +Use `OverflowText` for single-line, non-editable labels instead of local +`text-overflow: ellipsis` rules or shortening the underlying string. Plain text +defaults to **fade-out truncation with an interaction marquee**: a background-independent +gradient mask at the inline end, followed by scrolling on hover or keyboard focus. +Both effects apply only when the text actually overflows. Short labels remain untouched. +Standard button, menu, navigation, card, selection, and disclosure text slots +already use this primitive; consumers should not wrap those slots a second time. + +```tsx +import { OverflowText } from "@openbitfun/ui"; + +// The surrounding layout owns the available width. +{description} + +// Mark the owning control so its whole hit target and keyboard focus reveal text. + +``` + +String, number, and plain-text array children use marquee automatically. +Use `behavior="fade"` for a deliberate static label, and `behavior="marquee"` +for text-only rich markup such as search highlights. Standard interactive controls +already own the hover/focus trigger. Put +`data-overflow-trigger` on one control or row, never the entire list. Virtual +selection may use `marqueeActive` on the label or `data-overflow-active="true"` +on its owning trigger, without adding another tab stop. `ListboxOption` forwards +its virtual active state through this contract. Selected +tabs do not animate automatically. Motion respects `prefers-reduced-motion`; +reduced-motion users keep the static fade. Text and movement follow RTL direction. + +Rich children default to fade to preserve the label's existing inline composition. +Composite containers keep their icons/actions fixed and give each text slot its +own `OverflowText`. Marquee measures and +translates one inline text span; keep icons, badges, and action buttons outside +it. Complete text stays in the accessibility tree. Clipped string/number labels +get a native title unless the caller supplies one; rich content should use its +own full-text tooltip or detail view. Do not use marquee as the sole way to +access information on touch surfaces. + +Multi-line descriptions should normally wrap. Editable fields, source code, +structured paths that need to preserve their suffix, and native controls keep +their appropriate text treatment instead of receiving a blanket fade rule. +Mobile sheet/page titles and row descriptions wrap for touch access. Tooltips +also wrap: a full-text fallback must not truncate its own content. + +The Web UI uses this contract in shell/navigation and search, workspace/session +lists, model and context pickers, file/Git lists, settings, tool-card summaries, +usage reports, and the Canvas SDK's truncating text/file labels. Remaining local +ellipsis rules are intentional source-code excerpts, contenteditable reference +chips/placeholders, and multiline message previews. Diagnostic/payload size caps +and persisted Appearance `textOverflow` values are data contracts, not layout rules. + ## Mobile controls Touch-first controls use the isolated mobile entry so compact and foldable @@ -58,14 +113,6 @@ surface elevation, responsive inline sizing, composer geometry, transparent floating action layout, and sheet accessibility. Product state, localized copy, routing, and device or session operations stay in the consuming application. -Use `OverflowText` for single-line labels that need a treatment only when their -rendered content is actually clipped. Its default `fade` behavior softens the -inline end. `behavior="marquee"` keeps that resting cue, then reveals the full -label with a measured hover/focus marquee; reduced-motion users keep the static -fade. The primitive preserves the full text in the accessibility tree, supports -right-to-left direction, and leaves width constraints and tooltip content to -the consumer. - `Disclosure` is the shared expandable-content primitive. It owns controlled or uncontrolled open state, trigger/region accessibility wiring, focus exclusion while collapsed, reduced-motion behavior, and independent header actions. @@ -148,6 +195,17 @@ in the form. Search, typed values, and multiple selection remain component-owned compositions; its container must supply padding, height, and visible focus treatment. The default SearchField appearance is unchanged. +`SearchField variant="panel"` provides a joined frosted surface with a rounded +input row and an optional `footer` slot for result status and actions. It reuses +the same input node when switching from the default pill, preserves input-row +height, and provides a divider, metadata typography, and a single focus outline. +The surface uses semantic tint and blur tokens, with an opaque fallback for +unsupported blur or reduced transparency. Callers own the query, localized +counts, navigation callbacks, and disabled action states; use `IconButton` for +the actions. The panel stays in normal flow by default. A toolbar that needs +downward expansion without reflow should reserve the input height and position +the SearchField over that anchor. + `FieldGroup fieldSurface="ambient"` keeps text and picker field borders while letting their shells reuse the grouped surface. The default field surface stays theme-owned, and portalled menus remain on the opaque panel surface. diff --git a/design-system/packages/ui/src/components/ActionCard/ActionCard.module.css b/design-system/packages/ui/src/components/ActionCard/ActionCard.module.css index 98c39d588e..3116ae2589 100644 --- a/design-system/packages/ui/src/components/ActionCard/ActionCard.module.css +++ b/design-system/packages/ui/src/components/ActionCard/ActionCard.module.css @@ -110,7 +110,6 @@ .description { overflow: hidden; min-inline-size: 0; - text-overflow: ellipsis; white-space: nowrap; } diff --git a/design-system/packages/ui/src/components/ActionCard/ActionCard.tsx b/design-system/packages/ui/src/components/ActionCard/ActionCard.tsx index 190312a8f3..b2d202f3db 100644 --- a/design-system/packages/ui/src/components/ActionCard/ActionCard.tsx +++ b/design-system/packages/ui/src/components/ActionCard/ActionCard.tsx @@ -6,6 +6,7 @@ import { } from "react"; import { IconButton, type IconButtonProps } from "../IconButton"; import { classNames } from "../../internal/classNames"; +import { OverflowText } from "../../primitives/OverflowText"; import styles from "./ActionCard.module.css"; export interface ActionCardAction { @@ -52,7 +53,7 @@ export const ActionCard = forwardRef( data-selected={selected ? "true" : "false"} data-size={size} > - - {children} + {children} {description !== undefined && description !== null && ( - + {description} - + )} diff --git a/design-system/packages/ui/src/components/ActionItem/ActionItem.module.css b/design-system/packages/ui/src/components/ActionItem/ActionItem.module.css index 4d103ae6e7..edd67d012b 100644 --- a/design-system/packages/ui/src/components/ActionItem/ActionItem.module.css +++ b/design-system/packages/ui/src/components/ActionItem/ActionItem.module.css @@ -99,7 +99,6 @@ font-weight: var(--openbitfun-type-label-md-font-weight); line-height: var(--openbitfun-type-body-sm-line-height); letter-spacing: var(--openbitfun-type-label-md-letter-spacing); - text-overflow: ellipsis; white-space: nowrap; } diff --git a/design-system/packages/ui/src/components/ActionItem/ActionItem.tsx b/design-system/packages/ui/src/components/ActionItem/ActionItem.tsx index 933fec1935..c7593438b2 100644 --- a/design-system/packages/ui/src/components/ActionItem/ActionItem.tsx +++ b/design-system/packages/ui/src/components/ActionItem/ActionItem.tsx @@ -6,6 +6,7 @@ import { } from "react"; import { IconButton, type IconButtonProps } from "../IconButton"; import { classNames } from "../../internal/classNames"; +import { OverflowText } from "../../primitives/OverflowText"; import styles from "./ActionItem.module.css"; export interface ActionItemAction { @@ -57,7 +58,7 @@ export const ActionItem = forwardRef(functio data-openbitfun-tone={tone} data-disabled={disabled ? "true" : "false"} > - ); }); diff --git a/design-system/packages/ui/src/components/Listbox/Listbox.module.css b/design-system/packages/ui/src/components/Listbox/Listbox.module.css index 776c9e2e66..a41619d785 100644 --- a/design-system/packages/ui/src/components/Listbox/Listbox.module.css +++ b/design-system/packages/ui/src/components/Listbox/Listbox.module.css @@ -131,7 +131,6 @@ .metadata { overflow: hidden; font-family: var(--openbitfun-type-label-md-font-family); - text-overflow: ellipsis; } .label { diff --git a/design-system/packages/ui/src/components/Listbox/Listbox.tsx b/design-system/packages/ui/src/components/Listbox/Listbox.tsx index 3f59813ad7..5d404356a4 100644 --- a/design-system/packages/ui/src/components/Listbox/Listbox.tsx +++ b/design-system/packages/ui/src/components/Listbox/Listbox.tsx @@ -13,6 +13,7 @@ import { } from "react"; import { Icon } from "../Icon"; import { classNames } from "../../internal/classNames"; +import { OverflowText } from "../../primitives/OverflowText"; import { ScrollArea, type ScrollbarVisibility } from "../ScrollArea"; import styles from "./Listbox.module.css"; @@ -218,12 +219,13 @@ export const ListboxOption = forwardRef( ...props }, ref) { return ( - ); })} diff --git a/design-system/packages/ui/src/components/Select/Select.module.css b/design-system/packages/ui/src/components/Select/Select.module.css index a6fd60b183..83d75ef508 100644 --- a/design-system/packages/ui/src/components/Select/Select.module.css +++ b/design-system/packages/ui/src/components/Select/Select.module.css @@ -143,7 +143,6 @@ overflow: hidden; flex: 1 1 auto; min-inline-size: 0; - text-overflow: ellipsis; white-space: nowrap; } diff --git a/design-system/packages/ui/src/components/Select/Select.tsx b/design-system/packages/ui/src/components/Select/Select.tsx index f73d874367..5cbdc4f590 100644 --- a/design-system/packages/ui/src/components/Select/Select.tsx +++ b/design-system/packages/ui/src/components/Select/Select.tsx @@ -15,6 +15,7 @@ import { type SelectHTMLAttributes, } from "react"; import { classNames } from "../../internal/classNames"; +import { OverflowText } from "../../primitives/OverflowText"; import { useFieldSurface } from "../../internal/fieldSurface"; import { useAnchoredLayer, type LayerPlacement } from "../../internal/useAnchoredLayer"; import { Portal } from "../../overlay/Portal"; @@ -346,12 +347,12 @@ export const Select = forwardRef(function Select {leading} )} - {selectedOption?.label ?? placeholder} - + @@ -370,6 +371,7 @@ export const Select = forwardRef(function Select style={layout?.style ?? { position: "fixed", visibility: "hidden" }} > {hasEndAction && ( diff --git a/design-system/packages/ui/src/flow-chat/ask-user/AskUser.module.css b/design-system/packages/ui/src/flow-chat/ask-user/AskUser.module.css index 97dff15e44..75214f9dd6 100644 --- a/design-system/packages/ui/src/flow-chat/ask-user/AskUser.module.css +++ b/design-system/packages/ui/src/flow-chat/ask-user/AskUser.module.css @@ -117,7 +117,6 @@ overflow: hidden; flex: 1 1 auto; min-inline-size: 0; - text-overflow: ellipsis; white-space: nowrap; } @@ -272,7 +271,6 @@ font-weight: var(--openbitfun-type-body-md-font-weight); line-height: var(--openbitfun-type-body-sm-line-height); text-align: end; - text-overflow: ellipsis; white-space: nowrap; } diff --git a/design-system/packages/ui/src/flow-chat/ask-user/AskUser.tsx b/design-system/packages/ui/src/flow-chat/ask-user/AskUser.tsx index 36e8f39ca6..75e8886741 100644 --- a/design-system/packages/ui/src/flow-chat/ask-user/AskUser.tsx +++ b/design-system/packages/ui/src/flow-chat/ask-user/AskUser.tsx @@ -1,3 +1,4 @@ +import { OverflowText } from '../../primitives/OverflowText'; import { forwardRef, useId, @@ -220,7 +221,7 @@ export const AskUser = forwardRef(function AskUser ref={ref} > {hasSummary ? ( - - @@ -471,7 +471,7 @@ const MainNav: React.FC = ({
- @@ -514,7 +514,7 @@ const MainNav: React.FC = ({ data-testid="agent-skill-tabs" > - - -
))} diff --git a/src/web-ui/src/app/components/NavPanel/components/MiniAppEntry.tsx b/src/web-ui/src/app/components/NavPanel/components/MiniAppEntry.tsx index 4eb8e66c5d..023d787322 100644 --- a/src/web-ui/src/app/components/NavPanel/components/MiniAppEntry.tsx +++ b/src/web-ui/src/app/components/NavPanel/components/MiniAppEntry.tsx @@ -3,7 +3,7 @@ import { useI18n } from '@/infrastructure/i18n/hooks/useI18n'; import { useMiniAppStore } from '@/app/scenes/miniapps/miniAppStore'; import { useMiniAppActivity } from '@/app/scenes/miniapps/hooks/useMiniAppActivity'; import { renderMiniAppIcon, getMiniAppIconGradient } from '@/app/scenes/miniapps/utils/miniAppIcons'; -import { Icon, Tooltip } from '@openbitfun/ui'; +import { OverflowText, Icon, Tooltip } from '@openbitfun/ui'; const MAX_VISIBLE_ACTIVE_APPS = 3; @@ -45,7 +45,7 @@ const MiniAppEntry: React.FC = ({ return (
-
= ({ - {t('scenes.miniApps')} + {t('scenes.miniApps')} diff --git a/src/web-ui/src/app/components/NavPanel/components/NavItem.tsx b/src/web-ui/src/app/components/NavPanel/components/NavItem.tsx index b51f472640..951cd19383 100644 --- a/src/web-ui/src/app/components/NavPanel/components/NavItem.tsx +++ b/src/web-ui/src/app/components/NavPanel/components/NavItem.tsx @@ -10,7 +10,7 @@ import React, { useRef } from 'react'; import type { LucideIcon } from 'lucide-react'; import type { NavItem as NavItemConfig } from '../types'; -import { Icon, Tooltip } from '@openbitfun/ui'; +import { OverflowText, Icon, Tooltip } from '@openbitfun/ui'; interface NavItemProps { item: NavItemConfig; @@ -63,7 +63,7 @@ const NavItem: React.FC = ({ }; return ( - - @@ -1149,6 +1149,7 @@ const WorkspaceItem: React.FC = ({ ), diff --git a/src/web-ui/src/app/components/NavPanel/sections/workspaces/WorkspaceSessionBatchModal.tsx b/src/web-ui/src/app/components/NavPanel/sections/workspaces/WorkspaceSessionBatchModal.tsx index a932102d8d..82d7be6bb4 100644 --- a/src/web-ui/src/app/components/NavPanel/sections/workspaces/WorkspaceSessionBatchModal.tsx +++ b/src/web-ui/src/app/components/NavPanel/sections/workspaces/WorkspaceSessionBatchModal.tsx @@ -1,4 +1,4 @@ -import { +import { OverflowText, Button, Checkbox, Icon, @@ -330,9 +330,9 @@ const WorkspaceSessionBatchModal: React.FC = ({
- + {workspaceLabel} - +
@@ -423,9 +423,9 @@ const WorkspaceSessionBatchModal: React.FC = ({ : } - + {sessionName} - + {displayAsChild && ( {t('nav.sessions.batchChildSession')} diff --git a/src/web-ui/src/app/components/RemoteConnectDialog/AccountPanel.scss b/src/web-ui/src/app/components/RemoteConnectDialog/AccountPanel.scss index a1e0823303..3c12490699 100644 --- a/src/web-ui/src/app/components/RemoteConnectDialog/AccountPanel.scss +++ b/src/web-ui/src/app/components/RemoteConnectDialog/AccountPanel.scss @@ -151,7 +151,6 @@ font-family: var(--openbitfun-type-body-sm-font-family); font-size: var(--openbitfun-type-label-sm-font-size); color: var(--openbitfun-color-content-muted); - text-overflow: ellipsis; white-space: nowrap; } @@ -269,7 +268,6 @@ min-width: 0; flex: 1; overflow: hidden; - text-overflow: ellipsis; white-space: nowrap; } @@ -396,10 +394,9 @@ align-items: center; min-width: 0; - > span:first-child { + > span:not([data-overflow-content]):first-child { min-width: 0; overflow: hidden; - text-overflow: ellipsis; } > .account-panel__device-badge { @@ -410,7 +407,6 @@ color: var(--openbitfun-color-content-primary); font-size: var(--openbitfun-type-label-md-font-size); font-weight: var(--openbitfun-type-label-selected-font-weight); - text-overflow: ellipsis; white-space: nowrap; } diff --git a/src/web-ui/src/app/components/RemoteConnectDialog/AccountPanel.tsx b/src/web-ui/src/app/components/RemoteConnectDialog/AccountPanel.tsx index 38888229a7..28ca1cf9f5 100644 --- a/src/web-ui/src/app/components/RemoteConnectDialog/AccountPanel.tsx +++ b/src/web-ui/src/app/components/RemoteConnectDialog/AccountPanel.tsx @@ -15,7 +15,7 @@ * group), not an external README. See `src/features/relay-deploy/README.md`. */ -import { Alert, Button, Field, Icon, IconButton, Input, ScrollArea, StatusPill } from '@openbitfun/ui'; +import { OverflowText, Alert, Button, Field, Icon, IconButton, Input, ScrollArea, StatusPill } from '@openbitfun/ui'; import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react'; import { useI18n } from '@/infrastructure/i18n'; import { useCurrentWorkspace } from '@/infrastructure/contexts/WorkspaceContext'; @@ -1215,9 +1215,9 @@ export const AccountPanel: React.FC = ({
)} diff --git a/src/web-ui/src/app/layout/FloatingMiniChat.scss b/src/web-ui/src/app/layout/FloatingMiniChat.scss index 2bd7156aff..36007c535b 100644 --- a/src/web-ui/src/app/layout/FloatingMiniChat.scss +++ b/src/web-ui/src/app/layout/FloatingMiniChat.scss @@ -372,7 +372,7 @@ $panel-height: 680px; } 50% { box-shadow: 0 4px 12px color-mix(in srgb, var(--openbitfun-color-content-on-light) 30%, transparent), - 0 0 0 2px var(--openbitfun-color-status-warning-content); + 0 0 0 2px var(--openbitfun-color-status-warning-emphasis); } } @@ -438,7 +438,6 @@ $panel-height: 680px; flex: 1; min-width: 0; overflow: hidden; - text-overflow: ellipsis; white-space: nowrap; text-align: left; } @@ -573,10 +572,9 @@ $panel-height: 680px; color: var(--openbitfun-color-content-muted); font-size: var(--openbitfun-type-flow-support-font-size); - span { + span:not([data-overflow-content]) { min-width: 0; overflow: hidden; - text-overflow: ellipsis; white-space: nowrap; } } diff --git a/src/web-ui/src/app/layout/FloatingMiniChat.tsx b/src/web-ui/src/app/layout/FloatingMiniChat.tsx index 826ed8bad8..aebc5fc234 100644 --- a/src/web-ui/src/app/layout/FloatingMiniChat.tsx +++ b/src/web-ui/src/app/layout/FloatingMiniChat.tsx @@ -19,7 +19,7 @@ import type { ChatInputRegistration, ChatInputSubmission, } from '@/flow_chat/components/chatInputRegistration'; -import { Icon, IconButton, LauncherButton, Tooltip } from '@openbitfun/ui'; +import { OverflowText, Icon, IconButton, LauncherButton, Tooltip } from '@openbitfun/ui'; import { useCurrentWorkspace } from '@/infrastructure/contexts/WorkspaceContext'; import { SessionMenu, useFlowChatSessions } from '../../flow_chat/components/session-menu'; @@ -641,7 +641,7 @@ export const FloatingMiniChat: React.FC = () => {
- {popupTitle} + {popupTitle}
diff --git a/src/web-ui/src/app/layout/MiniAppBubbleWelcome.tsx b/src/web-ui/src/app/layout/MiniAppBubbleWelcome.tsx index 27da3dabcc..78cfdf38d4 100644 --- a/src/web-ui/src/app/layout/MiniAppBubbleWelcome.tsx +++ b/src/web-ui/src/app/layout/MiniAppBubbleWelcome.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Icon, ScrollArea } from '@openbitfun/ui'; +import { OverflowText, Icon, ScrollArea } from '@openbitfun/ui'; import { FolderOpen } from 'lucide-react'; import type { MiniAppBubbleCustomization } from '@/app/scenes/miniapps/miniAppStore'; import { renderMiniAppIcon } from '@/app/scenes/miniapps/utils/miniAppIcons'; @@ -71,7 +71,7 @@ export const MiniAppBubbleWelcome: React.FC = ({ data-workspace-path={workspacePath} >
)} diff --git a/src/web-ui/src/app/scenes/SceneViewport.scss b/src/web-ui/src/app/scenes/SceneViewport.scss index b49c8f5af4..8c98a6399a 100644 --- a/src/web-ui/src/app/scenes/SceneViewport.scss +++ b/src/web-ui/src/app/scenes/SceneViewport.scss @@ -12,6 +12,15 @@ background: var(--openbitfun-color-surface-scene); box-shadow: none; + // The ecosystem catalog owns its own content padding and starts at the scene edge. + .openbitfun-workspace-body__scene-surface > &:has( + > .openbitfun-scene-viewport__clip + > .openbitfun-scene-viewport__scene--visible[data-scene-id='ecosystem-compatibility'] + ) { + inline-size: calc(100% + var(--openbitfun-space-4)); + margin-inline-start: calc(0px - var(--openbitfun-space-4)); + } + &__clip { position: absolute; inset: 0; diff --git a/src/web-ui/src/app/scenes/agents/AgentsScene.tsx b/src/web-ui/src/app/scenes/agents/AgentsScene.tsx index 0f3176ae08..f6bdc1ef2f 100644 --- a/src/web-ui/src/app/scenes/agents/AgentsScene.tsx +++ b/src/web-ui/src/app/scenes/agents/AgentsScene.tsx @@ -1,4 +1,4 @@ -import { Button, Combobox, Icon, IconButton, SearchField, Select, StatusPill, Tooltip, ScrollArea, type IconSource } from '@openbitfun/ui'; +import { OverflowText, Button, Combobox, Icon, IconButton, SearchField, Select, StatusPill, Tooltip, ScrollArea, type IconSource } from '@openbitfun/ui'; import React, { useCallback, useEffect, useMemo, useState } from 'react'; import type { TFunction } from 'i18next'; import { Bot, Cpu, FileText, MessageSquareText, RotateCcw, Wrench } from 'lucide-react'; @@ -864,31 +864,31 @@ const AgentsHomeView: React.FC = () => { {selectedAgent ? (