Commit graph

5 commits

Author SHA1 Message Date
ryan-crabbe-berri
89d2d34453 fix(ui): lint z-index utilities behind arbitrary Tailwind variants
The variant prefix pattern only understood word variants, so
data-[side=top]:z-50 or [&>*]:z-[5] slipped past the rule. Parse the
utility as everything after the last top-level colon (brackets and
parens nest) and also strip the important marker. Formats the two files
prettier flagged in CI
2026-08-25 17:34:45 -07:00
ryan-crabbe-berri
6385b6d801 refactor(ui): replace hand-picked z-index values with one named scale and lint it
Regression LIT-6143 (the policy Flow Builder painting its guardrail dropdown
underneath a position: fixed shell at z-index 1000) was one instance of a
class of bug: pages picking their own z-index numbers above the portalled
popup layer. This removes the class.

- globals.css defines the only z-index values in the dashboard as Tailwind
  utilities: z-raised, z-chrome, z-sticky, z-sticky-pinned, z-floating,
  z-overlay, z-popup; every numeric, arbitrary and inline z-index across
  src is migrated onto them and tailwind-merge learns the tokens
- new local/no-ad-hoc-z-index ESLint rule bans z-<n>, z-[...], z-(...) and
  inline zIndex everywhere, and reserves z-popup for the portalled
  primitives in components/ui (and the DataTable menus)
- the Flow Builder renders in the dashboard content area instead of as a
  fixed full-screen overlay, so it has no stacking level at all
- the guardrail content-filter Add keyword / Add pattern / Custom pattern
  dialogs drop the leftover z-[1100] (renamed from ABOVE_ANTD_MODAL when
  antd was removed) that hid their own Action select and pattern combobox
  behind the dialog, the same bug as LIT-6143
2026-08-25 17:02:35 -07:00
yuneng-jiang
93c1461074
fix(ui): restore hover feedback and dark-mode variants lost in the token migration (#37579)
* fix(ui): restore hover feedback and dark-mode variants lost in the token migration

PR #37576 mapped hardcoded Tailwind palette classes onto semantic tokens. Two-tone
hover pairs collapsed onto a single token, so 116 hover utilities across 49 files
became identical to their base class and produced no visible feedback, and in seven
files a dark: variant was dropped while its hardcoded light partner survived, leaving
those elements stuck light in dark mode.

Hover states now follow the alpha-step idiom the shadcn primitives already use
(hover:bg-primary/80, hover:bg-success/20): a duplicated hover:text-X or hover:bg-X
becomes /80, hover:border-border becomes hover:border-ring, and a duplicate is
dropped where another hover utility on the element already carries the change. One
transition-colors that no longer animated anything is removed.

For the dark-mode gaps, indigo maps onto info and amber onto warning. There is no
purple token in globals.css, so the purple sites keep their palette classes and get
their dark: partner back.

* fix(ui): add an eslint rule that fails a hover: utility identical to its base

The token migration collapsed two-tone hover pairs by hand, so nothing catches
the next one. `local/no-noop-hover-variant` reads every string literal and
template chunk and errors when a `hover:X` sits alongside a bare `X`, which is
exactly the shape that renders no hover feedback. It ships at error with no
suppression baseline, so the eleven sites that already carried a dead hover
before the migration are fixed here too.

The rule reads one class string at a time, so a base class supplied by a
different ternary branch than its hover partner is left alone: a selected row
whose resting colour already matches its hover colour is deliberate, not a bug.
2026-08-19 22:52:36 -07:00
ryan-crabbe-berri
67fce87b16
chore(ui): add filename, size, JSX-handler, prefer-const, and antd lint rules (#34341)
* chore(ui): add filename, size, JSX-handler, prefer-const, and antd lint rules

Wires up five error-level ESLint rules on the dashboard, grandfathering every
current offender into eslint-suppressions.json so the gate only bites new code
and ratchets down as files are fixed

- local/filename-pascal-case: new local rule requiring PascalCase .tsx names,
  exempting Next.js reserved files (page, layout, route, ...) and test/spec files
  (239 grandfathered)
- max-lines: 800 lines over src/**, excluding tests, src/data, and generated
  schema.d.ts (20 grandfathered)
- local/no-complex-jsx-arrow: new local rule flagging inline JSX arrow handlers
  with block bodies over two statements; each failure is a small extract-to-named
  -handler refactor (65 grandfathered)
- prefer-const: flipped from off to error (103 grandfathered)
- no-restricted-imports: added antd to the phase-out ban alongside tremor, and
  pointed both messages at shadcn/ui primitives (405 antd import sites grandfathered)

Both new local rules ship with RuleTester coverage

* fix(ui): preserve secondary extensions in filename-pascal-case suggestion

The suggestion text built the rename from only the head segment, so a
multi-dot file like my-component.utils.tsx was told to become
MyComponent.tsx instead of MyComponent.utils.tsx. Rebuild it from the
PascalCased head plus the untouched remaining segments, and add tests
covering multi-dot filenames and the hyphenated Next.js reserved names
(global-error, apple-icon, opengraph-image, twitter-image)
2026-07-22 19:34:35 -07:00
ryan-crabbe-berri
5973d9fd2b
feat(ui): add eslint rules for nested ternaries, large inline object args, and long condition chains (#32415)
* feat(ui): add eslint rules for nested ternaries, large inline object args, and long condition chains

Adds three dashboard lint rules to keep new code readable. Nested ternaries
are banned outright via the built-in no-nested-ternary, with the 265 existing
occurrences grandfathered in eslint-suppressions.json so only new ones fail.

Two custom rules ship as a small local plugin under scripts/eslint-rules:
no-large-inline-object-arg flags object literals with 4+ properties passed
straight into a call, nudging toward a named variable, and no-long-condition-chain
flags boolean expressions that combine 4+ conditions, nudging toward a named
boolean. Both are warnings tracked on the existing budget ratchet
(eslint-budgets.json + eslint-metrics.json) with headroom above the current
counts, so they ratchet down over time rather than freezing a baseline. Both
thresholds are configurable rule options and covered by RuleTester unit tests.

* fix(ui): scope no-long-condition-chain to boolean operators, not nullish

Greptile flagged that the rule counted nullish-coalescing chains the same as
&&/|| chains, so a 4-part `a ?? b ?? c ?? d` fallback surfaced "Boolean
expression combines 4 conditions", which is inaccurate since a `??` fallback
is value defaulting, not a condition. Restrict the visitor to && / || nodes so
`??` chains are treated as leaves, while a boolean chain nested inside a `??`
is still caught. Drops 6 miscounted occurrences (240 -> 234).

* chore(ui): sync lint metrics and suppressions with staging

Merge advanced the base branch, adding one no-large-inline-object-arg
occurrence (508 -> 509) and making one grandfathered react-hooks suppression
stale. Regenerate eslint-metrics.json and prune the suppression so the
budget/drift gate passes.

* chore(ui): sync lint metrics with staging

Merge advanced the base, adding four no-large-inline-object-arg occurrences
(509 -> 513). Regenerate eslint-metrics.json so the drift gate passes.
2026-07-08 21:32:16 +00:00