Files
roshan c6e437b018 refactor(web): migrate replaced refresh-components to Opal (#16242)
## Description

This is the third of four cleanup PRs on top of #16234, which is merged
(stack: #16240 icons, #16241 raw elements, #16242 refresh components,
#16243 Text). It migrates the refresh-components that
`opal/no-replaced-refresh-import` flags, except `Text`, which the next
PR migrates. These are `Card`, `Truncated`, `SelectButton`, `LineItem`
and `Divider`. 13 of 22 files are migrated, and the other 9 are kept for
the reasons below.

### Changes (under `web/src/`)

**`Card` to Opal `Card`** (9 sites in 4 files:
`app/admin/discord-bot/page.tsx`,
`app/admin/discord-bot/[guild-id]/page.tsx`,
`app/app/settings/usage/UsageSettings.tsx`,
`views/admin/GroupsPage/GroupPermissionsSection.tsx`)
- The refresh `Card` put an inner `Section` inside its box, but Opal
`Card` does not. So each site wraps its children in `<Section
alignItems="start" height="fit">` and passes `rounding={4}` for the same
16px corner. One discord-bot card has a single full-width `Section`
child, so it gets no wrapper.
- The variants map like this:
  - `primary` → `border="solid"`;
  - `secondary` → `color="transparent" border="solid"`;
  - the computed `"disabled"` variant → `border="solid" disabled={...}`.

**`Truncated` to `OverflowText`** (9 files:
`app/ee/admin/theme/Preview.tsx`, `lib/app/components.tsx`,
`refresh-components/messages/InfoBlock.tsx`,
`sections/onboarding/components/LLMProviderCard.tsx`,
`ee/sections/SearchCard.tsx`, `layouts/general-layouts.tsx`,
`sections/document-sidebar/ChatDocumentDisplay.tsx`,
`sections/knowledge/agent-knowledge/KnowledgeSearch.tsx`,
`sections/knowledge/SourceHierarchyBrowser.tsx`)
- Each site becomes `as="p" textPosition="text-start"`, with `font` and
`color` set explicitly.
- Sites with no color flag get `color="text-05"`, because the refresh
default is `text-05` and the Opal default is `text-04`.
- `className="line-clamp-2"` becomes `maxLines={2}`.
- `applicationName` can be null, so it renders `{applicationName ??
""}`.

**`SelectButton` to Opal `SelectButton`**
(`sections/knowledge/SourceHierarchyBrowser.tsx`)
- It uses `variant="select-light"`, and `transient` maps to
`interaction={sortDropdownOpen ? "hover" : "rest"}`.

### Visual differences reviewers should check

- **`ChatDocumentDisplay`:** the old tooltip opened with `side="start"`.
`OverflowText` has no side prop, so its tooltip always opens above the
text, aligned to the start.
- **`SourceHierarchyBrowser` sort button:** the label at rest changes
from `text-03` to `text-04`. The size is Opal's default `lg`, where the
old button used `px-2 py-2 rounded-12`.
- **All `OverflowText` sites:**
  - Opal `Text` always adds `px-[2px]`.
- The old `grow w-full` wrapper is gone. The parents are start-aligned,
so the layout should look the same.
- **Card borders:** Opal draws `border-border-01`. The old card used the
global default border color.

### Kept on purpose

- **`app/admin/billing/BillingDetailsView.tsx`, `PlansView.tsx`:** these
Cards pass a `className` (`billing-card-enter`, `billing-payment-card`,
`plan-card`), and Opal `Card` takes no `className`. The deprecation note
on refresh `Card` already says these need a decision.
- **`app/admin/billing/CheckoutView.tsx`:** one Card is clickable and
has `className` and `data-selected`, so it is probably a `SelectCard`.
That needs a design decision.
- **`refresh-components/buttons/LineItem.tsx`:** its title `Truncated`
gets per-variant `line-item-text-*` classes that `OverflowText` cannot
take.
- **`refresh-components/buttons/source-tag/SourceTag.tsx`:** its
`Truncated` shares a `TextStyleProps` object with the refresh `Text`
beside it.
- **`refresh-components/commandmenu/CommandMenu.tsx`:**
- Its `Divider`s use `icon` and highlight states that Opal `Divider`
does not support.
- Its `LineItem` rows depend on muted, action and emphasized colors and
on the keyboard-nav hover in `line-item.css`.
- **`views/admin/UsersPage/EditUserModal.tsx`,
`ServiceAccountsPage/EditServiceAccountModal.tsx`,
`ServiceAccountsPage/ApiKeyFormModal.tsx`:** each has `skeleton`
LineItems (dashed border, 12px text), and neither `LineItemButton` nor
`EmptyMessageCard` matches that look.

## How Has This Been Tested?

- oxlint: in the 13 migrated files, the only
`opal(no-replaced-refresh-import)` diagnostics left are refresh `Text`,
which the next PR migrates. The full run has 0 errors.
- `bun run types:check`: no type errors, and type coverage stays at
99.04%.
- pre-commit (oxfmt, oxlint) passes on the changed files.

## Additional Options

- [ ] [Optional] Please cherry-pick this PR to the latest release
version.



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Hovering over a suppressed tooltip no longer closes its enclosing
tooltip.

* **UI Improvements**
* Text exceeding available space now has consistent overflow handling
across navigation, search results, document lists, onboarding, and
informational messages.
* Admin, usage, permissions, and Discord settings cards now have
consistent borders, rounded corners, disabled states, and content
alignment.
* The knowledge source sort control now reflects its interaction state
while the dropdown is open.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-10-20 00:31:45 +00:00
..