Перейти к содержимому
Меню
Язык, сейчас Русский
EnglishGaeilge简体中文Españolहिन्दीPortuguêsবাংলাРусский日本語廣東話Tiếng Việtالعربية

дизайн-система rastrillo

Обзор всего, что даёт дизайн-система. Тема: day. Язык: Русский.

Форма

Каждый элемент управления в тех состояниях, в которые его ставит настоящая форма. Все они лежат в rst-box с отступами, потому что именно это предполагают эти партиалы.

Готовые и согласованные между собой элементы интерфейса, отрисованные на сервере.

В словаре самого фреймворка это partials: ui.Templates() возвращает partials, и docs/site/templates.md описывает их под этим именем. Слово на этой странице изменилось, слово в коде — нет.

Ссылки здесь неактивны

Ссылки неактивны, исходник примера приложен.

Каждый пример ниже — в своей рамке.

Содержимое примеров на английском. Каркасы примеров переведены.

field

Подпись, поле, необязательная подсказка, пояснение и ошибка. Обычный текстовый элемент с явным ID.

Без ничего

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field><label rst-field-label for="f_bare">Title</label>
<input rst-input type="text" id="f_bare" name="f_bare">
</div></form></section>

С подсказкой

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field><label rst-field-label for="f_hint">Slug <span rst-field-hint>(lowercase, no spaces)</span></label>
<input rst-input type="text" id="f_hint" name="f_hint">
</div></form></section>

Со справкой под элементом управления

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field><label rst-field-label for="f_help">Email</label>
<input rst-input type="email" id="f_help" name="f_help" autocomplete="email" aria-describedby="f_help-help">
<p rst-field-help id="f_help-help">We only use this to send you replies.</p>
</div></form></section>

Обязательное

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field><label rst-field-label for="f_required">Full name</label>
<input rst-input type="text" id="f_required" name="f_required" required>
</div></form></section>

С ошибкой

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field><label rst-field-label for="f_error">Email</label>
<input rst-input type="email" id="f_error" name="f_error" value="grace@" aria-invalid="true" aria-describedby="f_error-error">
<p rst-field-error id="f_error-error" role="alert">That does not look like an email address.</p>
</div></form></section>

Короткое

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field><label rst-field-label for="f_short">Postcode</label>
<input rst-input="short" type="text" id="f_short" name="f_short" value="D02 XY45">
</div></form></section>

Главное поле

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field><label rst-field-label for="f_primary">Title</label>
<input rst-input="primary" type="text" id="f_primary" name="f_primary" value="Quarterly board meeting">
</div></form></section>

field-text

Одно текстовое поле с подписью, идентификаторы выводятся из Name. Звёздочка обязательности помечена aria-hidden: программный сигнал — атрибут required у поля.

Без ничего

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field>
  <label rst-field-label for="ft_bare">Title</label>
  <input rst-input id="ft_bare" name="ft_bare" type="text">
</div></form></section>

С подсказкой

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field>
  <label rst-field-label for="ft_hint">Headline</label>
  <input rst-input id="ft_hint" name="ft_hint" type="text" aria-describedby="ft_hint-hint">
  <small rst-field-hint id="ft_hint-hint">Shown in the list.</small>
</div></form></section>

Обязательное

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field>
  <label rst-field-label for="ft_required">Display name <span rst-field-required aria-hidden="true">*</span></label>
  <input rst-input id="ft_required" name="ft_required" type="text" autocomplete="nickname" required>
</div></form></section>

С ошибкой

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field>
  <label rst-field-label for="ft_error">Title</label>
  <input rst-input id="ft_error" name="ft_error" type="text" value="Release notes" aria-invalid="true" aria-describedby="ft_error-error">
  <small rst-field-error id="ft_error-error">A post with that title already exists.</small>
</div></form></section>

Главное поле

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field>
  <label rst-field-label for="ft_primary">What is it?</label>
  <input rst-input="primary" id="ft_primary" name="ft_primary" type="text" value="Quarterly board meeting">
</div></form></section>

Добавьте Primary к главному полю формы — например, к заголовку или имени, — чтобы поле стало заметнее.

field-textarea

Обёртка field-text вокруг textarea.

Без ничего

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field>
  <label rst-field-label for="ta_bare">Notes</label>
  <textarea rst-textarea id="ta_bare" name="ta_bare" rows="3"></textarea>
</div></form></section>

С подсказкой

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field>
  <label rst-field-label for="ta_hint">Bio</label>
  <textarea rst-textarea id="ta_hint" name="ta_hint" rows="3" aria-describedby="ta_hint-hint"></textarea>
  <small rst-field-hint id="ta_hint-hint">Shown on your profile.</small>
</div></form></section>

С ошибкой

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field>
  <label rst-field-label for="ta_error">Summary</label>
  <textarea rst-textarea id="ta_error" name="ta_error" rows="3" aria-invalid="true" aria-describedby="ta_error-error">…</textarea>
  <small rst-field-error id="ta_error-error">A summary needs at least twenty characters.</small>
</div></form></section>

Обязательное

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field>
  <label rst-field-label for="ta_required">Reason for refund <span rst-field-required aria-hidden="true">*</span></label>
  <textarea rst-textarea id="ta_required" name="ta_required" rows="3" required></textarea>
</div></form></section>

field-select

Обёртка field вокруг родного select. Больше десяти вариантов — и select включает комбобокс с фильтром из select.js; отправляет форма всё равно родной select.

Три варианта: обычный select

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field><label rst-field-label for="sel_few">Role</label>
<select rst-input id="sel_few" name="sel_few"><option value="Admin" selected>Admin</option><option value="Editor">Editor</option><option value="Member">Member</option></select>
</div></form></section>

Двенадцать вариантов: комбобокс с фильтром

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field><label rst-field-label for="sel_many">City</label>
<select rst-input id="sel_many" name="sel_many" data-rst-select data-rst-select-filter="Введите текст для фильтра" data-rst-select-results="Результатов: {n}" data-rst-select-result-one="1 результат" aria-describedby="sel_many-help"><option value="Dublin" selected>Dublin</option><option value="Lisbon">Lisbon</option><option value="Madrid">Madrid</option><option value="Berlin">Berlin</option><option value="Rome">Rome</option><option value="Athens">Athens</option><option value="Helsinki">Helsinki</option><option value="Reykjavík">Reykjavík</option><option value="Warsaw">Warsaw</option><option value="Zagreb">Zagreb</option><option value="Tallinn">Tallinn</option><option value="Valletta">Valletta</option></select>
<p rst-field-help id="sel_many-help">Start typing to filter.</p>
</div></form></section>

Больше десяти вариантов — и партиал включает select.js. Меньше десяти — нет: поиск по горстке пунктов это мебель, а не помощь.

Двенадцать вариантов, Plain — от улучшения отказались

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field><label rst-field-label for="sel_plain">City</label>
<select rst-input id="sel_plain" name="sel_plain"><option value="Dublin" selected>Dublin</option><option value="Lisbon">Lisbon</option><option value="Madrid">Madrid</option><option value="Berlin">Berlin</option><option value="Rome">Rome</option><option value="Athens">Athens</option><option value="Helsinki">Helsinki</option><option value="Reykjavík">Reykjavík</option><option value="Warsaw">Warsaw</option><option value="Zagreb">Zagreb</option><option value="Tallinn">Tallinn</option><option value="Valletta">Valletta</option></select>
</div></form></section>

Обязательное, с ошибкой

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field><label rst-field-label for="sel_error">Role</label>
<select rst-input id="sel_error" name="sel_error" required aria-invalid="true" aria-describedby="sel_error-error"><option value="Admin" selected>Admin</option><option value="Editor">Editor</option><option value="Member">Member</option></select>
<p rst-field-error id="sel_error-error" role="alert">Pick a role for this person.</p>
</div></form></section>

Написан вручную, с optgroup

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-field><label rst-field-label for="sel_grouped">Region</label>
<select rst-input id="sel_grouped" name="sel_grouped" data-rst-select data-rst-select-filter="Введите текст для фильтра" data-rst-select-results="Результатов: {n}" data-rst-select-result-one="1 результат">
<optgroup label="Europe"><option value="dublin" selected>Dublin</option><option value="lisbon">Lisbon</option><option value="warsaw">Warsaw</option></optgroup>
<optgroup label="Americas"><option value="montreal">Montréal</option><option value="lima">Lima</option><option value="austin">Austin</option></optgroup>
<optgroup label="Asia"><option value="osaka">Osaka</option><option value="hanoi">Hanoi</option><option value="dhaka">Dhaka</option></optgroup>
<optgroup label="Africa"><option value="accra">Accra</option><option value="nairobi">Nairobi</option><option value="tunis">Tunis</option></optgroup>
</select>
</div></form></section>

Options здесь — плоский список, поэтому сгруппированные варианты пишет разметкой само приложение. select.js отрисовывает группы, а не выбрасывает их; написанный вручную select может и вовсе отказаться от улучшения через data-rst-select="false".

field-check

Единственный механизм переключения: настоящий флажок с видом тумблера, клавиатура и экранный диктор не страдают.

Включено

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><label rst-switch><input type="checkbox" name="notify_on" checked><span rst-switch-track aria-hidden="true"></span> Email me about replies</label></form></section>

Выключено

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><label rst-switch><input type="checkbox" name="notify_off"><span rst-switch-track aria-hidden="true"></span> Email me about mentions</label></form></section>

Отключено

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><label rst-switch><input type="checkbox" name="notify_disabled" disabled><span rst-switch-track aria-hidden="true"></span> Email me a weekly digest</label></form></section>

choice-field

Карточки вариантов — предпочтительная группа радиокнопок или флажков. Title остаётся коротким, объясняет Desc.

Выберите одно

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><fieldset rst-choice><legend>Plan</legend><div rst-choice-cards><label><input type="radio" name="plan" value="free"><span><span rst-choice-title>Free</span><span rst-choice-desc>One project, community support.</span></span></label><label><input type="radio" name="plan" value="pro" checked><span><span rst-choice-title>Pro</span><span rst-choice-desc>Unlimited projects and a support inbox.</span></span></label></div></fieldset></form></section>

Выберите любые

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><fieldset rst-choice><legend>Send me</legend><div rst-choice-cards><label><input type="checkbox" name="digest" value="replies" checked><span><span rst-choice-title>Replies</span><span rst-choice-desc>As they happen.</span></span></label><label><input type="checkbox" name="digest" value="weekly"><span><span rst-choice-title>Weekly digest</span><span rst-choice-desc>Monday mornings.</span></span></label></div></fieldset></form></section>

form-foot

Завершающая строка формы: одна главная кнопка отправки и необязательная ссылка отмены. Отмена — ссылка, потому что уйти с формы значит перейти на другую страницу.

Сохранить и отменить

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-form-foot>
  <button rst-btn="primary" type="submit">Save post</button>
  <a rst-btn href="/posts">Back to posts</a>
</div></form></section>

Только отправка

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-form-foot>
  <button rst-btn="primary" type="submit">Send invitation</button>
</div></form></section>

В покое — кнопка до того, как что-либо произошло

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-form-foot>
  <button rst-btn="primary" type="submit">Publish</button>
  <a rst-btn href="/posts">Back to posts</a>
</div></form></section>

Кнопка, которая ЧТО-ТО МЕНЯЕТ, получает состояние загрузки; кнопка, которая лишь что-то раскрывает — раскрывающийся блок, выпадающее меню, вкладка, — нет. rastrillo.js применяет это правило к каждой кнопке отправки в каждой форме, включать ничего не нужно.

В работе — то, что rastrillo.js пишет на выходе

Предпросмотр
<section rst-box><form rst-form method="post" action="#"><div rst-form-foot>
<button rst-btn="primary" type="submit" aria-busy="true" data-idle-label="Publish" disabled><span rst-spin aria-hidden="true"></span>Publishing…</button>
<a rst-btn href="/posts">Back to posts</a>
</div></form></section>

Только та кнопка, по которой нажали: все остальные кнопки отправки в форме сохраняют своё name и value, а сама форма защищена от повторной отправки. data-busy="false" отключает правило — на форме или на одной кнопке; data-busy-label заменяет текст. Без скриптов ничего этого не происходит и форма отправляется ровно так же, как всегда, так что идемпотентность по-прежнему забота сервера.

confirm-form

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

Необратимое действие

Предпросмотр
<section rst-box><form rst-form-actions method="post" action="/posts/1/delete"><input type="hidden" name="csrf" value="tok-123"><input type="hidden" name="id" value="1"><a rst-btn="ghost" href="/posts/1">Отмена</a><button type="submit" rst-btn="danger">Delete this post</button></form></section>

Обычный случай, текст отмены по умолчанию

Предпросмотр
<section rst-box><form rst-form-actions method="post" action="/posts/1/publish"><a rst-btn="ghost" href="/posts/1">Отмена</a><button type="submit" rst-btn="primary">Publish</button></form></section>

CancelLabel не задан, поэтому текст ссылки отмены берётся из каталога.