fix(form): FK select стилизация — match TextInput/SingleSelect look

После перехода на native <select> в предыдущем коммите рендер
показывал OS default (двойная стрелка на macOS Safari, узкая высота,
native blue focus border). Не попадало в стиль формы — рядом
TextInput/DatePicker от @nstart/ui выглядели иначе.

Фикс:
- appearance-none убирает OS default
- Кастомный chevron как inline SVG в data-uri (color #687078 = carbon/40,
  same weight что у CaretDown в SingleSelect)
- pl-3 / pr-10 / py-2 = совпадает с TextInput высотой (~38px)
- focus:ring-1 ultramarain — same focus state как у TextInput

Native browser dropdown поведение сохраняется (auto-flip, scroll,
type-ahead) — просто внешне стало match'ить @nstart/ui дизайн систему.
This commit is contained in:
Zimin A.N.
2026-05-06 20:19:11 +03:00
parent 05af8e1520
commit 668f1b8b5b
@@ -747,6 +747,13 @@ const ReferenceSelectField = ({
// scroll и type-ahead search работают OOTB. SingleSelect popup
// через createPortal с position:fixed не делает auto-flip и уходит
// за нижний край когда триггер близко к низу modal'а.
// Caret chevron как inline SVG в data-uri — match'ит SingleSelect
// CaretDown иконку (color carbon/40, weight 'regular', size ~16).
// appearance-none убирает OS default стрелку, иначе на macOS Safari
// рендерится двойной chevron + native blue border.
const caretSvg =
"url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23687078' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='4 6 8 10 12 6'/></svg>\")"
return (
<Controller
control={control}
@@ -759,13 +766,18 @@ const ReferenceSelectField = ({
onChange={(e) => field.onChange(e.target.value || undefined)}
disabled={isLoading}
aria-invalid={Boolean(errorMsg)}
// appearance-none + custom caret = одинаковый look на всех
// платформах. py-2 (8px) match'ит TextInput высоту.
// pr-10 даёт место под chevron, остальной padding как у TextInput.
className={[
'w-full border rounded-sm px-3 py-2 text-sm font-secondary',
'w-full appearance-none border rounded-sm pl-3 pr-10 py-2 text-sm font-secondary',
'bg-white text-black transition-colors',
'bg-no-repeat bg-[right_0.75rem_center] bg-[length:1rem_1rem]',
'focus:outline-none focus:ring-1 focus:ring-ultramarain focus:border-ultramarain',
errorMsg ? 'border-mars' : 'border-regolith hover:border-carbon/40',
isLoading ? 'cursor-wait text-carbon/60' : 'cursor-pointer',
].join(' ')}
style={{ backgroundImage: caretSvg }}
>
<option value="">{isLoading ? '…' : '—'}</option>
{options.map((opt) => (