Commit Graph
79 Commits
Author SHA1 Message Date
Raunak Bhagat 0fe91853b1 feat(opal): stored-secret password tag, tab keyboard nav, tertiary actions (#16275)
## Description

**1. Stored secrets in `InputPasswordTypeIn`**
- New prop `existingValue`: a stored value from the backend, already
masked.
- While `value === existingValue`:
- the field shows the value as a medium blue `Tag` with the key icon,
and the input itself stays empty;
  - the reveal toggle is disabled;
  - Backspace or Delete clears the value;
  - typing or pasting replaces the value with the new text.
- After the first edit, the field is a normal password field again.
- To keep the stored secret on submit, the caller compares the submitted
value with `existingValue`.
- The tag has no tooltip.
- An unchanged existing value does not block submission: the native
`required` check is off while the tag shows. A `readOnly` field keeps
its existing value, and the caller's `onKeyDown` runs first and can
cancel the deletion.
- The `mask` prop and its ✱ overlay are removed. Password fields always
use the browser's own dots.

**Callers that edit a stored secret now pass `existingValue`**
- LLM provider modals (`APIKeyField`, Bedrock, Ollama), SSO provider
modal, index settings, web search, voice, tracing, image generation
(OpenAI, Azure), OpenAPI OAuth client secret, MCP API token and OAuth
secret, MCP user credentials, Craft app user credentials, Slack bot
tokens.
- In each one, the stored masked string is the field's initial value. So
the untouched field keeps Formik's `dirty` false, and a Save gated on
`dirty` stays blocked. Submit logic does not change: an unchanged value
still counts as unchanged.
- SSO used `isNonRevealable` on edit only to protect the stored value.
It uses `existingValue` now.
- No change where the form starts empty for a stored secret: the hooks
modal (only a placeholder holds the masked key), the Discord bot config
and the custom-analytics key.

**Raw password inputs move to `InputPasswordTypeIn`**
- Slack bot tokens, reset password, impersonate (API key,
`autoComplete="new-password"`), custom analytics secret key, plugin
connection dialog.

**2. Keyboard and tab navigation (from the closed #16238)**
These are the Opal parts of the closed Plugins PR. The plugins-specific
parts are left out.
- `Tabs`:
- new `activationMode`. In `"manual"`, the default, arrows move focus
and Enter or Space selects.
  - a focus ring shows while the keyboard moves focus;
- Tab enters the list on the selected tab and the next Tab leaves it, as
the ARIA tabs pattern says;
- Escape leaves the tabs, but only from a tab: a control in
`rightChildren` keeps focus;
  - only a left click focuses a tab.
- `orientation` is omitted from the props: Opal tabs are horizontal
only.
- `Interactive` (stateless): keyboard focus shows the hover state in
place of the browser's ring.
- `useGridNavigation`: keyboard focus on a control inside a grid item
shows again.
- `InputTypeIn` clear button: it keeps focus in the field after it
clears the value, it has an `aria-label`, and it sends `onChange` a real
change event.

- Escape on a control beside a text field (the clear button, the reveal
toggle, a chevron, a chip) returns focus to the field, also when a
tooltip consumed the key. This covers `InputTypeIn` and every input
built on it, plus `TagField`. On `InputTime` and `InputDatePicker`,
which have no single input, it focuses the first segment.

**3. Input action buttons**
- The right-side icon buttons use `tertiary` prominence: the clear
buttons of `InputTypeIn`, `TagField`, `InputTime` and `InputDatePicker`,
and the date picker's calendar button.
- The `InputTypeIn` and `UploadControl` clear buttons have tooltips.
- The tooltip-only clear and calendar buttons of `TagField`, `InputTime`
and `InputDatePicker` get an `aria-label`, so they have an accessible
name.
- The clear button is always an input's last control. `InputDatePicker`
drew it before the calendar button, and `TagField` (`InputTypeInTag`,
the multi-select) drew it before the dropdown chevron.

- `TagField` (`InputTypeInTag`, the multi-select) uses `size="sm"` for
its clear button, as the other inputs do. It used `xs`.

## Additional Options

- [ ] [Optional] Please cherry-pick this PR to the latest release
version.
- [x] [Optional] Override Linear Check

<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Adds an `existingValue` prop to `InputPasswordTypeIn` so forms that edit
backend secrets show the saved value as a key tag instead of editable
masked text, and polishes Opal tab keyboard navigation, focus handling,
and input action buttons.

**Stored secrets**
- `existingValue` marks a stored backend value: while the field's value
equals it, the value renders as a key tag, the input stays empty, and
the reveal toggle is disabled.
- Backspace or Delete clears it; typing or pasting replaces it whole. A
read-only field keeps the value, the caller's `onKeyDown` can cancel the
deletion, and an unchanged tag doesn't fail a native required check.
- Secret-editing forms (Slack tokens, SSO, MCP, language-model and
image-gen modals, tracing, voice, web search, and more) now pass
`existingValue`; a few raw password inputs move to
`InputPasswordTypeIn`. The `mask` prop and idle asterisk overlay are
removed.
- E2E specs for OpenAPI OAuth, index settings, and web search now verify
the stored value appears as a tag with an empty input.

**Keyboard and input actions**
- `Tabs` defaults to manual activation: arrows move focus, Enter or
Space selects, a focus ring tracks keyboard movement, and Escape leaves
the tabs. Only a plain left click focuses a tab; a caller's `onKeyDown`
can cancel the Escape.
- Keyboard focus on `Interactive` surfaces replaces the browser ring
with the hover state; `useGridNavigation` now shows focus on controls
inside grid items.
- `InputTypeIn`'s clear button sends a real change event, keeps focus in
the field after clearing, and gains an `aria-label`.
- Escape on an input's side controls (clear, reveal toggle, chevron,
chip) returns focus to the field, even when a tooltip consumed the key;
on `InputTime` and `InputDatePicker` it focuses the first segment.
- Input action buttons use `tertiary` prominence, the clear button is
always an input's last control, and `TagField`'s clear button is `sm`
like the other inputs'.

<sup>Written for commit 66ab5fd5b3.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/onyx-dot-app/onyx/pull/16275?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="View guided diff"
src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a>
<a
href="https://www.cubic.dev/action/auto-fix/pr/onyx-dot-app/onyx/16275?returnTo=https%3A%2F%2Fgithub.com%2Fonyx-dot-app%2Fonyx%2Fpull%2F16275&source=description"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"><img
alt="Turn on auto-fix"
src="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->

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

* **New Features**
* Password fields display saved credentials as masked, non-revealable
tags. Clear them with Backspace or Delete, or replace them by typing or
pasting.
* Tabs use manual activation: arrow keys move focus, while Enter or
Space selects.

* **Improvements**
* Credential fields preserve saved values while editing across
administrative and configuration forms.
* Clear controls provide localized labels and tooltips, and return focus
to the field.
  * Escape restores focus from date, time, tag, and input controls.
* Keyboard focus styling is more consistent across interactive controls
and grid navigation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-10-20 01:32:59 +00:00
4fcd7350d5 feat(web): Opal foundations, status icons, copy and formats for the indexing mock (#16165)
Co-authored-by: Nik <nikolas.garza5@gmail.com>
Co-authored-by: nik <nik@onyx.app>
2026-10-17 22:27:56 +00:00
roshan 2347a7beed refactor(opal): support consistent plugin dialogs with shared primitives (#16187) 2026-10-17 19:32:03 +00:00
Raunak Bhagat c9df4da344 feat(admin-sidebar): one pointer-following tooltip over locked pages; logical tooltip sides (#15926) 2026-10-12 23:25:32 +00:00
Raunak BhagatandClaude Opus 5.5 a5bb9dad6f feat(connectors): check a credential before a connector is created (#15007)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 04:48:36 +00:00
Raunak Bhagat 812c6ebb5b fix: brand-cased connector and logo names; Disabled scroll fix (#15662) 2026-10-07 19:48:18 +00:00
Raunak Bhagat 512e19bf24 refactor(connectors): clean up the Connector Content section (#15617) 2026-10-07 00:56:52 +00:00
Raunak Bhagat 820ce86e9a feat(connectors): keyboard navigation for the catalog, on two Opal hooks (#15390) 2026-10-01 23:37:04 +00:00
Raunak Bhagat efab755437 feat(opal): clickable SelectCards are keyboard-operable (#14997) 2026-09-22 19:44:32 +00:00
Raunak Bhagat da15c93ffc refactor(web): converge attachment rows on AttachmentItemButton (#14639) 2026-09-11 03:24:43 +00:00
Raunak Bhagat 4ad6cfbc27 feat(opal): add @opal/AttachmentItemButton (#14629) 2026-09-11 02:16:53 +00:00
Raunak Bhagat f9e3de36c8 refactor(opal): Move the remaining raw inputs into Opal (#14618) 2026-09-10 01:44:35 +00:00
Raunak Bhagat 6bd66b856a refactor(opal): give rounding a numeric scale (#14259) 2026-08-25 23:01:56 +00:00
Raunak Bhagat 9ed2b6255f refactor(web): move the IconButton call sites to Opal Button (#14163) 2026-08-24 16:49:51 +00:00
Raunak Bhagat 603efe6fd2 refactor(web): clean up how the active agent is resolved (#13960) 2026-08-21 17:29:08 +00:00
Raunak Bhagat 12c3c6a182 refactor(opal): move the card padding scale onto Spacing (#13916) 2026-08-12 20:14:56 +00:00
Jamison LahmanandClaude Fable 5 e99908ee7c fix(web): always show hover-revealed buttons on touch devices (#13680)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 22:36:00 +00:00
Nikolas Garza 1816f15cf8 refactor(opal): rename action-link-* tokens to action-selection-* (#13529) 2026-07-28 23:58:41 +00:00
claude[bot]andClaude 4669938b1f fix(storybook): align @storybook/* addon versions with storybook 10.5.0 (#13482)
Co-authored-by: Claude <noreply@anthropic.com>
2026-07-27 21:00:13 +00:00
Wenxi e11c382efd fix(web): apply oxfmt 0.59 formatting (#13481) 2026-07-27 20:46:24 +00:00
Jamison LahmanandClaude Opus 4.8 e15dd5903e fix(fe): remove opal-disabled layout styling (#12407)
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 16:33:09 +00:00
SubashMohanandClaude Opus 4.8 d7fb9691a7 feat(mobile): port Opal Button to React Native (#12255)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 04:24:29 +00:00
Jamison Lahman 929bc23886 fix(fe): disallow Interactive.Container from flex shrinking (#12283) 2026-06-22 21:09:57 +00:00
Raunak Bhagat e9a893d68f refactor(opal): migrate InputTypein into Opal (#11342) 2026-05-28 17:20:04 +00:00
Jamison Lahman 48dff20bae chore(fmt): fix oxfmt at HEAD (#11102) 2026-05-14 18:31:24 +00:00
Jamison LahmanandClaude Opus 4.7 e356243d43 chore(deps): upgrade tailwindcss v3 → v4 (#11035)
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-13 19:44:53 +00:00
Raunak Bhagat 634cb0b07a refactor(opal): Hoverable variant rename + new variants (#10674) 2026-04-28 13:59:13 -07:00
Raunak Bhagat 8ab892948f refactor(opal): rewrite @opal/core.Disabled from Radix Slot to div wrapper (#10501) 2026-04-27 09:14:06 -07:00
Raunak Bhagat e89c30cad1 fix(storybook): add global TooltipProvider decorator to Storybook for Opal (#10603) 2026-04-24 20:43:47 +00:00
Raunak Bhagat df332adbf4 fix(opal): separate Opal from @web/src shared utilities (#10598) 2026-04-24 20:04:43 +00:00
Raunak Bhagat 75ef2b014d refactor(opal): remove -Variant suffix from component props (#10348) 2026-04-18 00:16:51 +00:00
Nikolas Garza 32ba393b32 fix(chat): keep model selector popover open until max models reached (#10203) 2026-04-15 06:09:24 +00:00
Raunak Bhagat fc0e8560bc feat: opalify Tooltip component, migrate all consumers (#10210) 2026-04-15 03:42:15 +00:00
Raunak Bhagat 112edf41c5 refactor: replace Radix Slot with div wrapper in @opal/core.Disabled (#10119) 2026-04-14 17:40:32 +00:00
Raunak Bhagat 1c32a83dc2 fix: replace React context hover tracking with pure CSS (#9961) 2026-04-06 20:57:36 -07:00
Raunak Bhagat f77128d929 refactor: move SidebarTab to Opal with disabled prop and variant/state API (v2) (#9866) 2026-04-02 19:07:52 +00:00
Raunak Bhagat e002f6c195 Revert "refactor: move SidebarTab to opal" (#9865) 2026-04-02 11:38:03 -07:00
Raunak Bhagat 10d696262f refactor: move SidebarTab to opal (#9863) 2026-04-02 18:22:19 +00:00
Raunak Bhagat 41d1a33093 refactor: simplify opal/Disabled by removing its context (#9852) 2026-04-02 17:12:01 +00:00
Raunak Bhagat 67c8df002e refactor: update Button to define its own internal disabled styling (#9851) 2026-04-02 16:42:35 +00:00
Raunak Bhagat 11835a0268 fix(opal): guard opal/interactive's onClick handlers against React portal event bubbling (#9850) 2026-04-02 05:37:00 +00:00
Jamison Lahman 183e3b5ec3 fix(fe): foldable buttons unfold on tab (#9828) 2026-04-01 16:30:27 +00:00
Raunak Bhagat 7ecefdc90f refactor(opal): split Card sizeVariant into padding + rounding (#9823) 2026-04-01 03:32:08 +00:00
Raunak Bhagat 3f9e208759 feat(opal): SelectCard + CardHeaderLayout (#9760) 2026-03-30 19:54:54 +00:00
Raunak Bhagat a3dfe6aa1b refactor(opal): unify Interactive color system (#9717) 2026-03-28 00:40:23 +00:00
Raunak Bhagat 849385b756 refactor: migrate legacy components/Text (#9628) 2026-03-26 16:14:03 +00:00
Raunak Bhagat 41ae039bfa refactor(opal): cleanup button types in Opal (#9598) 2026-03-24 20:06:39 +00:00
Raunak Bhagat f187165077 refactor(opal): opalify FilterButton + migrate all instances away from old one (#9597) 2026-03-24 19:12:00 +00:00
Jamison Lahman aead6ab9a5 fix(fe): properly style "Sign In" button (#9480) 2026-03-24 10:02:02 -07:00
Jamison Lahman 84b134e226 fix(a11y): hidden buttons appear on tabbing (#9518) 2026-03-24 16:18:11 +00:00