Compare commits

...

2 Commits

Author SHA1 Message Date
pigui
7bb40d32f1 Drop the gradient focus ring, which doubled every field's left edge
The doubled edge was not the textarea's alone -- it was on every field,
and the previous commit's explanation of why the inputs were exempt was
wrong. I asserted that at 999px the ring and the outline clamp to the
same curve without measuring it. They do not:

  ring     999px -> a 24px circle      (half the field's height)
  outline  999px -> a 12x24 ellipse    (leading piece width x half height)

The ring is one continuous rounded rectangle over the whole field; the
outline beneath it is split into three pieces and its leading piece is
12px wide. No radius makes a full-width curve agree with a 12px-wide
one, so there was nothing to tune -- the ring had to go. It was mine,
lifted from the library's `gradient` theme onto a shell that does not
use it, and `alternative` already expresses focus through the outline's
own colour.

The textarea's radius goes back to 1.25rem, since it was only lowered to
dodge the clamp.

Verified at 3x, one curve per field: valid+focus violet, error+focus
red, no ring anywhere.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 14:06:59 +02:00
pigui
4d2a8dd26b Fix the doubled edge down the left of the textarea
Focusing the textarea while it had an error drew two red curves down its
left side, a couple of pixels apart. Not a positioning problem -- the
ring and the outline share the same box to the pixel. It is clamping.

The outline's leading piece is 12px wide, so the 20px corner radius it
was given got clamped to 12, while the focus ring, drawn across the full
width, kept a true 20px curve. Same declared radius, two different
curves. At 10px nothing is clamped and they land on top of each other.

The single-line fields never showed this: at 999px both the outline and
the ring clamp to half the field's height, so they already agreed.

Verified at 2x: one continuous outline, ring and leading piece both
reporting 10px.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-31 13:31:58 +02:00
2 changed files with 11 additions and 30 deletions

View File

@@ -84,6 +84,9 @@
font-weight: var(--pi-theme-field-label-weight, inherit);
}
// A stadium is right for a 48px input and wrong for a 112px textarea, which
// is all this is now — with the focus ring gone there is no second shape to
// agree with.
.pi-field.pi-form-field__textarea {
--pi-theme-field-radius: 1.25rem;
}
@@ -127,20 +130,3 @@
font-size: var(--pi-font-size-x-small, 0.75rem);
}
}
// Focusing a field that already has an error drew it twice: the notched
// outline stays in the error colour, and the gradient focus ring is painted on
// top of it in the brand's violet-to-cyan. Two rings, two colours, one field —
// and on the textarea, at two different radii, which is what made it obvious.
//
// The ring is worth keeping: it is how focus reads on every other field. It
// just has to agree with the state it is decorating, so while the field is
// invalid the ring is built from the warn colour instead of the brand one. The
// field ends up with a single red indication that still brightens on focus.
:host ::ng-deep .pi-field .mat-form-field-invalid {
--pi-theme-field-focus-gradient: linear-gradient(
120deg,
var(--pi-color-warn),
var(--pi-color-warn-200, var(--pi-color-warn))
);
}

View File

@@ -92,19 +92,14 @@ html {
@include brand-ramp('highlighted', #6c2fb5, #ffffff);
}
// The `gradient` theme's signature — a gradient focus ring on fields — is a
// token, so it can be lifted onto the `alternative` shell without swapping
// themes. `_mat-form-field.scss` reads it; the flat border is turned off so it
// does not show through the ring.
.pi-shell__alternative {
--pi-theme-field-focus-gradient: linear-gradient(
120deg,
var(--pi-color-primary),
var(--pi-color-accent),
var(--pi-color-highlighted)
);
--pi-theme-field-border-color-focus: transparent;
}
// The `gradient` theme's focus ring is deliberately NOT lifted onto this shell.
//
// It is drawn as one continuous rounded rectangle over the whole field, while
// the outline underneath is split into three pieces. The leading piece is 12px
// wide, so a large radius clamps to a 12x24 ellipse there while the ring keeps
// a true 24px circle — two curves that cannot be made to agree at any radius,
// showing as a doubled edge down the left of every field. Focus is left to the
// outline's own colour, which is what `alternative` already defines.
html,
body {