Skip to content

fix(appkit-ui): remove stray focus ring on Command input and menu items - #494

Open
pkosiec wants to merge 2 commits into
mainfrom
pkosiec/fix-command-border
Open

fix(appkit-ui): remove stray focus ring on Command input and menu items#494
pkosiec wants to merge 2 commits into
mainfrom
pkosiec/fix-command-border

Conversation

@pkosiec

@pkosiec pkosiec commented Jul 28, 2026

Copy link
Copy Markdown
Member

Problem

Command's search input and the item slots in DropdownMenu, ContextMenu, and Menubar show an unexpected focus ring on keyboard focus — a double outline not present in upstream shadcn.

Reported by Ivan here: https://databricks.slack.com/archives/C079XV741BQ/p1785174428544209

Cause

A global :focus-visible rule in globals.css paints a box-shadow ring on every keyboard-focused element:

:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--background), 0 0 0 4px var(--ring);
}

It sits in @layer base. Components with their own focus-visible:ring-* (Input, Button, Select, …) are in @layer utilities and override it, so they look correct. The command input and menu items have no ring of their own, so they fall through to the global rule. Upstream shadcn gives these elements no ring.

Fix

Add focus-visible:shadow-none to those slots so they match shadcn. Menu items keep their focus:bg-accent highlight. The global rule is left untouched, so every other focusable keeps its ring.

shadow-none is required over ring-0: it emits a raw box-shadow that overrides the base rule, whereas ring-0 only sets --tw-ring-shadow and leaves the box-shadow in place.

Screenshots

image image

This pull request and its description were written by Isaac.

A global `:focus-visible` rule in globals.css paints a box-shadow ring on
every keyboard-focused element. It lives in @layer base, so components with
their own `focus-visible:ring-*` (Input, Button, Select, ...) override it via
@layer utilities and look correct. Bare focusables with no own ring —
CommandInput and dropdown/context/menubar item slots — fall through to the
global rule and show an unexpected double-line ring absent from upstream
shadcn (which deliberately gives these no ring).

Add `focus-visible:shadow-none` to those slots so they match shadcn.
`shadow-none` emits a raw box-shadow utility that overrides the base-layer
rule; `ring-0` would not, since it only sets --tw-ring-shadow. The global
rule is intentionally left intact for other bare focusables.

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

📦 Bundle size report

Compared against bundle-size-baseline.json (main).

@databricks/appkit

npm tarball (packed): 763 KB — gzipped download (dist + bin; excludes release-only docs/NOTICE).

dist raw gzip
JS (runtime) 791 KB 276 KB
Type declarations 285 KB 97 KB
Source maps 1.5 MB 515 KB
Other 11 KB 3.7 KB
Total 2.6 MB 892 KB
Per-entry composition (own code — deps external (as shipped))
Entry Initial (gz) Lazy (gz) Total (gz) node_modules (min) Own code (min)
. 86 KB 2.5 KB 89 KB external 281 KB
./beta 40 KB 231 B 40 KB external 119 KB
./type-generator 19 KB 0 B 19 KB external 54 KB

Chunks:

Entry Chunk Load Size (gz)
. index.js initial 82 KB
. utils.js initial 4.0 KB
. remote-tunnel-manager.js lazy 2.5 KB
./beta beta.js initial 30 KB
./beta databricks.js initial 5.8 KB
./beta service-context.js initial 3.2 KB
./beta client-options.js initial 220 B
./beta databricks.js lazy 128 B
./beta index.js lazy 103 B
./type-generator index.js initial 19 KB

@databricks/appkit-ui

npm tarball (packed): 305 KB (+101 B) — gzipped download (dist + bin; excludes release-only docs/NOTICE).

dist raw gzip
JS (runtime) 360 KB (+390 B) 119 KB (+60 B)
Type declarations 205 KB 74 KB
Source maps 686 KB (+390 B) 224 KB (+66 B)
CSS 16 KB 3.3 KB
Total 1.2 MB (+780 B) 422 KB (+126 B)
Per-entry composition (consumer bundle — deps bundled, peerDeps external)
Entry Initial (gz) Lazy (gz) Total (gz) node_modules (min) Own code (min)
./js 4.3 KB 49 KB 54 KB 208 KB 12 KB
./js/beta 20 B 0 B 20 B 0 B 0 B
./react 429 KB (+55 B) 49 KB 478 KB (+55 B) 1.3 MB 168 KB (+390 B)
./react/beta 20 B 0 B 20 B 0 B 0 B

Chunks:

Entry Chunk Load Size (gz)
./js index.js initial 4.2 KB
./js chunk initial 120 B
./js apache-arrow lazy 49 KB
./js/beta beta.js initial 20 B
./react index.js initial 427 KB
./react tslib initial 2.1 KB
./react apache-arrow lazy 49 KB
./react/beta beta.js initial 20 B

@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

🤖 AppKit PR bot

🔬 Run evals

Start an eval for this PR from the evals-monitor app: Go to Evals Monitor →

📦 Try this PR's app template

Scaffolds a new app from this PR's SDK build. Run it in any folder (requires the GitHub CLI — gh auth login — and the Databricks CLI):

gh run download 30355015433 -R databricks/appkit -n appkit-template-0.48.0-pr.9e5ef72-pkosiec-fix-command-border-494 -D appkit-pr-494 \
  && unzip -o "appkit-pr-494/appkit-template-0.48.0-pr.9e5ef72-pkosiec-fix-command-border-494.zip" -d "appkit-pr-494" \
  && databricks apps init --template "appkit-pr-494"

The template pins @databricks/appkit and @databricks/appkit-ui to tarballs built from this branch, so the scaffolded app runs against this PR's code.

@pkosiec
pkosiec marked this pull request as ready for review July 28, 2026 11:21
@pkosiec
pkosiec requested a review from a team as a code owner July 28, 2026 11:21
@pkosiec
pkosiec requested a review from MarioCadenas July 28, 2026 11:21
SelectItem used the same background-based focus pattern as the menu
components (focus:bg-accent + outline-hidden) without cancelling the
global :focus-visible box-shadow, leaving a stray ring on keyboard
navigation. Add focus-visible:shadow-none to match the menu fix.

Signed-off-by: Pawel Kosiec <pawel.kosiec@databricks.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant