Перейти к содержимому
Плотность
Тема

Ввод

Вставки

JS Вставка в поле по нажатию — делает кит

Ряд подстановок для поля рядом: переменные шаблона, ключи события, поля записи. Нажатие кладёт значение на место каретки.

Компонент
Разметка
<div class="inst-field" style="max-inline-size:30rem">
  <label class="inst-label" for="ins-tpl">Шаблон уведомления</label>
  <textarea class="inst-textarea inst-u-mono" id="ins-tpl" rows="3">Упал {{name}}
</textarea>
  <div class="inst-inserts">
    <button class="inst-insert" type="button" data-insert-into="#ins-tpl" title="Имя монитора">{{name}}</button>
    <button class="inst-insert" type="button" data-insert-into="#ins-tpl" title="Адрес проверки">{{target}}</button>
    <button class="inst-insert" type="button" data-insert-into="#ins-tpl" title="Состояние">{{status}}</button>
    <button class="inst-insert" type="button" data-insert-into="#ins-tpl" title="Текст ошибки">{{error}}</button>
    <button class="inst-insert" type="button" data-insert-into="#ins-tpl" title="Время события">{{time}}</button>
  </div>
</div>

Пример живой: поставьте курсор в поле и нажмите подстановку — она встанет туда, где стоял курсор, а не в конец.

Использование

<div class="inst-field">
  <label class="inst-label" for="tpl">Шаблон</label>
  <textarea class="inst-textarea" id="tpl"></textarea>
  <div class="inst-inserts">
    <button class="inst-insert" type="button" data-insert-into="#tpl">{{name}}</button>
  </div>
</div>
Что Обязательно Почему
Настоящая <button type="button"> да Это действие. <span> не получит фокус, не сработает по Enter и не назовётся кнопкой
data-insert-into нет Без него берётся поле того же inst-field. Указывать нужно, когда поле лежит в другом месте разметки
Все подстановки видны разом да Пара рядов читается взглядом. То, что не поместилось и требует поиска, — уже справочник формата, и ему место в документации, а не под полем

Когда использовать

Используйте Возьмите другое
Подстановка в текст, который человек пишет сам Выбор одного значенияселект: у подстановок нет выбранного состояния
Ключи шаблона, поля записи, переменные события Метка, которую снимаюттег
Палитра под полем ввода Состояние объектабейдж: он сообщает, а не действует

Варианты

Вариантов нет намеренно. Подстановка тише действия: их бывает по десятку и больше на одно поле, и в полный голос палитра кричала бы громче того, ради чего страница открыта. Если подстановка важнее текста под ней — это не подстановка.

JS

Подключите модуль один раз на страницу.

<script type="module" src="src/kit.js"></script>

Что делает кит

Кладёт значение в поле на место каретки, а не в конец: курсор ставят туда, где нужна подстановка, и ждут её там. Выделенное заменяется. После вставки фокус возвращается в поле — иначе следующую букву некуда набрать.

Значение берётся из data-insert, а без него — из текста кнопки.

События

inst:insert всплывает с кнопки, detail{ text, field }. Отмена оставляет поле нетронутым: приложению может понадобиться своя логика вставки, например с проверкой позиции.

form.addEventListener('inst:insert', (e) => {
  if (!allowed.has(e.detail.text)) e.preventDefault();
});

Само поле после вставки шлёт нативный input — рамки видят изменение без единой строки клея.

Опции

Атрибут Что делает
data-insert-into Селектор поля. Без него берётся первое textarea/input того же .inst-field
data-insert Что вставить, если это не текст самой кнопки: короткая подпись, длинное значение

Правила

Так Настоящая кнопка

<button type="button"> внутри формы. Без type она отправит форму при первом же нажатии.

Не так Подстановка тегом

Тег снимают, и у него есть крестик. Подстановку не снимают — её вставляют.

Так Подпись = то, что вставится

На кнопке написано {{name}}, в поле попадает {{name}}. Расхождение между надписью и результатом — обман в чистом виде.

Не так Палитра, в которой надо искать

Пока подстановки читаются взглядом, ряд работает. Когда в нём приходится искать глазами — оставьте частые, остальные унесите в документацию формата.

Доступность

Имя Текст кнопки и есть значение — отдельная подпись не нужна. Пояснение кладётся в title, но оно дополняет, а не заменяет имя
Клавиатура Обычная кнопка: Tab, Enter, Space. Ряд из десяти кнопок проходится табом, и это правильно — каждая делает своё
Фокус после вставки Возвращается в поле. Оставленный на кнопке фокус означает, что человеку придётся искать поле руками
Контраст Подпись держит 4.5:1 на утопленной поверхности во всех шести темах
Моноширинный Подстановка — идентификатор, а не слово: {{name}} и {{node}} различаются посимвольно

API

ИмяЗначениеЧто делает
класс
inst-insertsРяд подстановок
inst-insertОдна подстановка. Настоящая <button>
атрибут
data-insert-intoСелектор поля, куда класть значение. Без него берётся поле того же inst-field
data-insertЧто вставить, если это не текст самой кнопки
событие
inst:insertНажата вставка. detail{ text, field }. Отмена оставляет поле нетронутым
токен
--control-h-sm26px
--surface-sunkenlight-dark(var(--n-2), var(--n-14))
--border-subtlelight-dark(oklch(0 0 0 / 0.07), oklch(1 0 0 / 0.06))
--font-monoui-monospace, "Cascadia Code", "JetBrains Mono", "SF Mono", Consolas, "Liberation Mono", monospace
--text-xs0.75rem
--space-24px
--space-36px
--radius-sm5px

Почему кит устроен именно так — конституция · Открытый код под MIT, github.com/keshon/instrument