Государственные услуги · Новый ресурс

Дизайн-система Suomi.fi.

Создавайте понятные формы для финских государственных услуг с Source Sans 3, явными токенами интервалов и восстанавливаемым сценарием выбора документов.

Руководство OpenDesign8 глав16 справочных материаловАвторское руководство по приложению
01

Дизайн-система Suomi.fi — предпросмотр интерфейса

Попробуйте выбрать PDF, отклоните файл неподдерживаемого формата и удалите выбранный документ. Файлы остаются в браузере.

Выберите и удалите вложениеОткрыть полный пример
Исходная интерпретация HTML/CSS документированного сценария с одним файлом; резервный шрифт Arial. · Справочник по реализации
02

Дизайн-система Suomi.fi — справочник по дизайн-системе

Официальная документация, изученный репозиторий токенов и метаданные suomifi-ui-components 18.0.0. Предпросмотр — оригинальная интерпретация, а не нативная среда выполнения React.

Типографика

Источник
Название / правилоЗначение / конфигурацияПрименение
FamilySource Sans 3В версии 18 используется Source Sans 3; в версии 17 и более ранних — Source Sans Pro. Загружайте шрифты отдельно.
Body text18pxОдинаковое значение по умолчанию для мобильных и настольных устройств.
Small body16pxТекстовый режим smallScreen, а не автоматическое правило для области просмотра.
Lead22px / 20px smallScreenНе более одного вводного блока на экран; не используйте lead для каждого абзаца.
Weights300 / 400 / 600Файлы шрифтов, необходимые пакету компонентов.

Отступы и поверхности

Источник
Название / правилоЗначение / конфигурацияПрименение
Space scale5, 10, 15, 20, 25, 30, 40, 60, 80pxОт xxs до xxxxl согласно JSON репозитория, изученного при подготовке.
Inset scale2, 4, 6, 8, 10, 16, 20pxОт insetXxs до insetXxl; это не внешняя шкала отступов.
Basic radius2pxrepository radius.basic; не делайте вывод о большом радиусе карточек.
Highlight basehsl(212, 63%, 45%)Стандартный синий цвет интерактивных элементов.
Highlight dark 1hsl(212, 63%, 37%)Более тёмный цвет для интерактивных элементов.
Highlight light 2hsl(212, 63%, 90%)Цвет светлой поверхности; проверьте контраст с выбранным цветом текста.

Расположение и язык FileInput

Источник
Название / правилоЗначение / конфигурацияПрименение
Default maximum width600pxШирина конкретного компонента, а не сетка всего сайта.
fullWidthBoolean layout optionРастягивайте на всю ширину родительского элемента, если этого требует форма.
smallScreenExplicit compact presentation optionНе выводите из этого свойства наличие глобальной автоматической контрольной точки.
Single selectionChosen file replaces picker and drop areaВыбор нескольких файлов — отдельный сценарий со списком файлов ниже.
Required copy roleslabelText, hintText, dragAreaText, removeFileText, addedFileAriaTextЛокализуйте описание каждой роли: одного имени файла недостаточно для полного объявления средствами специальных возможностей.
03

Дизайн-система Suomi.fi — полное руководство

Практическое руководство по выбору, применению и оценке этой системы для реального интерфейса.

DESIGN-suomi-fi.md

Подробные рекомендации, отправная точка для реализации и ссылки на источники.

Скачать руководство

Дизайн-система Suomi.fi — границы реализации

Система компонентов React

Suomi.fi предоставляет React компонентов со стилями на основе styled-components и отдельный пакет токенов. В версии 18 ожидаемым шрифтом стал Source Sans 3. На страницах более ранней версии 17 всё ещё может использоваться Source Sans Pro; сравнение таких снимков экрана без проверки версии пакета может привести к ошибочной корректировке типографики.

Из этого руководства OpenDesign

Встроенный предпросмотр по-прежнему явно обозначен как интерпретация HTML/CSS документированного сценария с одним файлом. Ниже также добавлен отдельный пример нативного FileInput из React с проверенными обратным вызовом, управляемым значением, зависимостями и импортами шрифтов. Это две реализации одной и той же локальной задачи выбора файла; нативный пример не превращает задним числом встроенный предпросмотр HTML в компонент React.

Прочитать вспомогательную спецификацию

Дизайн-система Suomi.fi — типографика и загрузка шрифтов

Сохраняйте читаемость основного текста

Используйте рекомендованный размер основного текста 18px на мобильных и настольных устройствах. Узкая область просмотра не является поводом уменьшать размер всех пояснений к форме. Малый текст — 16px, он предназначен для второстепенной информации. Размер вводного текста — 22px, а в компактном режиме — 20px; используйте его только во вступлении к странице.

Загрузите нужные начертания шрифта, прежде чем сравнивать переносы строк. Пакет компонентов ожидает файлы Source Sans 3, тогда как в этом независимом предпросмотре намеренно используется Arial. Эта замена отмечена в примечании к предпросмотру; его нельзя выдавать за точное отображение нативного компонента.

Прочитать вспомогательную спецификацию

Дизайн-система Suomi.fi — отступы и ширина

Две разные шкалы отступов

В источнике токенов обычные отступы отделены от внутренних. Обычный отступ l в изученном JSON равен 25px; не копируйте устаревший пример из README, где для l указано 32px. Внутренние отступы начинаются с 2px и далее идут по другой последовательности. При генерации стилей используйте фактические экспорты установленной версии.

Для FileInput документированы максимальная ширина 600px и свойство fullWidth. Это ограничение компонента, а не основание считать 600px универсальной шириной контейнера страницы. Форму для загрузки документов можно поместить в более широкую компоновку, сохранив поясняющий текст рядом с её меткой.

Прочитать вспомогательную спецификацию

Дизайн-система Suomi.fi — структура выбора файла

Текст — часть контракта компонента

Видимая метка называет нужный документ. Подсказка до открытия диалога выбора объясняет поддерживаемые форматы, размер и допустимое количество файлов. Область перетаскивания предлагает быстрый способ выбора, но не должна заменять поле ввода файла. В официальных рекомендациях элемент управления выбором описан как метка скрытого нативного поля ввода файла.

В режиме выбора одного файла выбранный документ заменяет область выбора и перетаскивания. Рядом с документом оставьте понятное действие для удаления. Режим выбора нескольких файлов использует другой формат списка; не добавляйте незаметно дополнительные файлы в запрос на выбор одного файла.

  • labelText: назовите требуемое подтверждение или документ, а не ограничивайтесь словом «Загрузить».
  • removeFileText: сформулируйте действие удаления так, чтобы оно было понятно в контексте файла.
  • addedFileAriaText: перед объявлением имени файла предоставьте контекст выбора.

Прочитать вспомогательную спецификацию

Дизайн-система Suomi.fi — выбор файла и восстановление после ошибки

Локальная машина состояний для вложения

Пример принимает один PDF размером не более 5 000 000 байт. Это правила приложения, выбранные для сценария данного практикума. Они не являются настройками пакета по умолчанию или официальной политикой Suomi.fi по загрузке файлов. Атрибут accept в браузере лишь помогает фильтровать файлы в диалоге выбора; в примере имя и размер файла дополнительно проверяются после выбора или перетаскивания.

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

  1. Выберите или перетащите ровно один файл; при выборе нескольких файлов покажите соответствующее сообщение.
  2. Проверьте локальные правила примера и объявите либо сообщение об ошибке, либо имя выбранного файла.
  3. Удалите вложение и восстановите исходный элемент выбора.

Прочитать вспомогательную спецификацию

Дизайн-система Suomi.fi Нативная интеграция

Установите согласованный набор зависимостей

В опубликованной версии 18.0.0 реализация FileInput вызывает onChange с FileList, а не с событием изменения React. Управляемое значение — это массив объектов файлов; в примере каждый принятый File преобразуется в { file }. Тот же обратный вызов выполняется при изменении списка встроенным действием удаления, поэтому пустой FileList очищает управляемый массив. Эти контракты проверены в опубликованном модуле dist/esm/core/Form/FileInput/FileInput.js.

Управляйте value с первого рендера, начав с пустого массива. Проверяйте входящий FileList, прежде чем преобразовывать его в этот массив. В примере отклоняются файлы, имена которых не оканчиваются на .pdf или размер которых превышает 5 000 000 байт; при отклонении выбор очищается. Это локальные правила примера, а не проверка безопасности и не политика Suomi.fi. Перед приёмом реальной загрузки необходимо проверять содержимое файлов на сервере.

Приведённый ниже нативный пример загружает Source Sans 3 начертаниями 400 и 600, монтирует React в явно заданный корневой элемент и использует styled-components через библиотеку. Явно укажите tslib: ESM-модули версии 18.0.0 импортируют её вспомогательные функции, и чистая сборка без этой зависимости завершилась ошибкой. В закреплённой ниже конфигурации указаны недостающая среда выполнения и файлы шрифтов. Для этого примера с темой по умолчанию дополнительный провайдер темы не нужен.

Прочитать вспомогательную спецификацию

Используйте проверенные экспорты токенов

В официальном руководстве по стилям показаны suomifiDesignTokens.spacing и suomifiDesignTokens.colors. В примере ниже эти экспортированные пути используются для пользовательской обёртки; это не альтернативная реализация внутренних механизмов FileInput.

tsx
import { suomifiDesignTokens } from 'suomifi-design-tokens';
// Real exported token paths. Use values instead of copying README example numbers.
const attachmentStyle = {
  maxWidth: 600,
  padding: suomifiDesignTokens.spacing.m,
  borderColor: suomifiDesignTokens.colors.highlightBase
};

Справочник по коду

Прочитать вспомогательную спецификацию

Дизайн-система Suomi.fi Доступность и адаптивное использование

Доступ к полю без перетаскивания

Сохраняйте возможность работы с нативным полем выбора файлов с клавиатуры, даже если область перетаскивания заметно выделена. Свяжите подсказку и сообщение об ошибке с помощью aria-describedby. Объявляйте изменения выбора и удаление, не зачитывая страницу заново. Если в форме может быть несколько таких элементов управления, кнопка удаления должна указывать, к какому выбранному файлу она относится.

Официальный проп smallScreen обеспечивает компактное отображение. Он не задаёт глобальную контрольную точку. В этом независимом примере для отступов используется специфичное для приложения изменение при ширине 480px, а размер основного текста остаётся равным 18px. Проверяйте длинные имена файлов, масштабирование и переведённые подписи; переносите имена файлов по строкам, не позволяя всей странице стать шире.

Прочитать вспомогательную спецификацию

Дизайн-система Suomi.fi Ответственность в производственной среде

Выбранный файл — ещё не загруженный файл

Демонстрационный пример не читает содержимое документов и не отправляет запросы. Имя выбранного файла и его размер в байтах не подтверждают, что документ действителен, сохранён или принят. Для реальных сервисов необходимы проверка на сервере, отображение хода загрузки, возможность восстановиться после ошибки, правила хранения и подтверждение, основанное на фактическом ответе.

Код компонента распространяется по лицензии MIT. Эта лицензия на код не даёт независимому проекту права представлять себя как финскую государственную службу или использовать защищённую институциональную айдентику. Для экспериментов используйте нейтральное название проекта, а для официальной реализации получите соответствующие рекомендации по брендингу.

Прочитать вспомогательную спецификацию

Дизайн-система Suomi.fi Примеры компонентов дизайн-системы

Используйте официальные экспорты токенов

Проверенные пути экспорта значений отступов и цветов для пользовательской обёртки.

tsx
import { suomifiDesignTokens } from 'suomifi-design-tokens';
// Real exported token paths. Use values instead of copying README example numbers.
const attachmentStyle = {
  maxWidth: 600,
  padding: suomifiDesignTokens.spacing.m,
  borderColor: suomifiDesignTokens.colors.highlightBase
};

Справочник по коду

Выбор и удаление одного файла

Полная самостоятельная реализация. Ограничения по формату PDF и размеру выбраны для примера; загрузка не выполняется.

html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Attachment example</title><style>*{box-sizing:border-box}body{margin:0;padding:30px 20px;font:18px/1.5 Arial,sans-serif;color:#202020;background:#fff}main{max-width:600px;margin:auto}h1{font-size:32px;line-height:1.2;font-weight:400;margin:0 0 20px}p{margin:0 0 20px}label{font-weight:600;display:block}small{display:block;font-size:16px}.drop{margin-top:15px;border:2px dashed hsl(212,63%,45%);padding:30px;text-align:center;background:hsl(212,63%,90%)}button,input::file-selector-button{font:600 18px Arial;padding:12px 20px;border:1px solid hsl(212,63%,37%);border-radius:2px;background:hsl(212,63%,45%);color:white;cursor:pointer}button:focus-visible,input:focus-visible{outline:3px solid #202020;outline-offset:3px}input{width:100%;font-size:16px;margin:15px 0}input::file-selector-button{margin-right:10px}.file{border:1px solid #777;padding:20px;margin:20px 0;overflow-wrap:anywhere}.file button{margin-top:15px;background:white;color:hsl(212,63%,37%)}#error{color:#a32020;font-weight:bold}footer{font-size:14px;margin-top:30px;border-top:1px solid #ccc;padding-top:15px}[hidden]{display:none!important}@media(max-width:480px){body{padding:20px 15px}.drop{padding:20px}h1{font-size:28px}}</style><main><small>COMMUNITY WORKSHOP · ATTACHMENT</small><h1>Add your project outline</h1><p>Choose one PDF up to 5 MB. This local example checks file metadata; it does not read or send the document.</p><div id="picker"><label for="file">Project outline</label><small id="hint">One PDF file. Maximum 5 MB (5,000,000 bytes).</small><input id="file" type="file" accept=".pdf,application/pdf" aria-describedby="hint error"><div class="drop" id="drop">Or drop one PDF here</div></div><p id="error" role="alert" hidden></p><section id="selected" class="file" hidden aria-label="Selected attachment"><strong id="name"></strong><small id="size"></small><button id="remove" type="button">Remove file</button></section><p id="status" role="status">No file selected.</p><footer>OpenDesign interpretation of the Suomi.fi attachment pattern. Arial fallback; no official identity or React component runtime. PDF and 5 MB are example rules.</footer></main><script>const input=document.querySelector('#file'),picker=document.querySelector('#picker'),selected=document.querySelector('#selected'),error=document.querySelector('#error'),status=document.querySelector('#status');function choose(files){error.hidden=true;if(files.length!==1){error.textContent='Choose exactly one file.';error.hidden=false;input.value='';return}const file=files[0];if(!/\.pdf$/i.test(file.name)||file.size>5000000){error.textContent='Choose a PDF no larger than 5 MB.';error.hidden=false;input.setAttribute('aria-invalid','true');input.value='';return}input.removeAttribute('aria-invalid');document.querySelector('#name').textContent=file.name;document.querySelector('#size').textContent=file.size.toLocaleString('en')+' bytes · selected locally';document.querySelector('#remove').setAttribute('aria-label','Remove '+file.name);picker.hidden=true;selected.hidden=false;status.textContent='Selected file: '+file.name;document.querySelector('#remove').focus()}input.addEventListener('change',()=>{if(input.files.length)choose(input.files)});document.querySelector('#drop').addEventListener('dragover',e=>e.preventDefault());document.querySelector('#drop').addEventListener('drop',e=>{e.preventDefault();choose(e.dataTransfer.files)});document.querySelector('#remove').onclick=()=>{input.value='';picker.hidden=false;selected.hidden=true;error.hidden=true;input.removeAttribute('aria-invalid');status.textContent='File removed. Choose another file.';input.focus()};</script></html>

Справочник по коду

  • Не нативный компонент React.
  • В производственной среде проверяйте содержимое файлов на сервере.

Нативный FileInput с управляемой проверкой

Сохраните как main.jsx. Вместе эти три файла воспроизводят нативный пример React с помощью команд настройки.

jsx
import React, { useState } from 'react';
import { createRoot } from 'react-dom/client';
import { FileInput } from 'suomifi-ui-components';
import '@fontsource/source-sans-3/400.css';
import '@fontsource/source-sans-3/600.css';
import './app.css';
function App() {
  const [value, setValue] = useState([]);
  const [error, setError] = useState('');
  function change(files) {
    const next = Array.from(files);
    const invalid = next.length > 1 || next.some(file => !/\.pdf$/i.test(file.name) || file.size > 5000000);
    if (invalid) {
      setValue([]);
      setError('Choose one PDF no larger than 5 MB.');
      return;
    }
    setValue(next.map(file => ({ file })));
    setError('');
  }
  return <main><h1>Select a workshop document</h1><p>This local example does not upload or read the document.</p>
    <FileInput id="document" labelText="Workshop document" hintText="One PDF, maximum 5 MB (5,000,000 bytes)."
      inputButtonText="Choose PDF" dragAreaText="or drop a PDF here" removeFileText="Remove file"
      addedFileAriaText="Selected file" accept=".pdf" value={value} onChange={change}
      status={error ? 'error' : 'default'} statusText={error} />
    <p role="status">{value.length ? `${value[0].file.name} selected locally.` : 'No file selected.'}</p>
  </main>;
}
createRoot(document.getElementById('root')).render(<App />);

Справочник по коду

  • Проверку выполняет приложение; нативный компонент обеспечивает выбор и удаление файлов, а также доступные элементы управления файлами.

Макет страницы нативного примера

Сохраните как app.css. Вместе эти три файла воспроизводят нативный пример React с помощью команд настройки.

css
body{margin:0;font:18px/1.5 'Source Sans 3',sans-serif;color:#292929;background:#fff}main{max-width:600px;margin:0 auto;padding:24px}h1{font-size:32px;line-height:1.2}*{box-sizing:border-box}

Справочник по коду

  • Проверку выполняет приложение; нативный компонент обеспечивает выбор и удаление файлов, а также доступные элементы управления файлами.

Точка монтирования нативного примера и сгенерированные ресурсы

Сохраните как index.html. Вместе эти три файла воспроизводят нативный пример React с помощью команд настройки.

html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Native Suomi.fi FileInput</title><link rel="stylesheet" href="./app.css"><div id="root"></div><script type="module" src="./app.js"></script></html>

Справочник по коду

  • Проверку выполняет приложение; нативный компонент обеспечивает выбор и удаление файлов, а также доступные элементы управления файлами.
04

Дизайн-система Suomi.fi Настройка ИИ-агента

Отправная точка для реализации

Эта настройка собирает приведённый ниже нативный пример React, включая локальные файлы шрифта Source Sans 3. Проверено с недопустимым форматом, корректным выбором, встроенным удалением и PDF-файлом слишком большого размера при ширине 390px и 1440px. Существующий архив ZIP со скачиваемым предпросмотром — это отдельная интерпретация HTML/CSS; его README остаётся актуальным.

bash
npm install --save-exact [email protected] [email protected] [email protected] [email protected] [email protected] @fontsource/[email protected]
npm install --save-dev --save-exact [email protected]
# Save main.jsx, app.css and index.html from the complete examples below.
npx esbuild main.jsx --bundle --outdir=dist --entry-names=app --loader:.woff=copy --loader:.woff2=copy
cp index.html dist/index.html
python3 -m http.server 8080 --directory dist
# Open http://localhost:8080

Запрос для вашего проекта

Промпт для AI-агента
Используйте предоставленный нативный пример Suomi.fi FileInput 18.0.0 React со шрифтом Source Sans 3 и закреплёнными зависимостями среды выполнения, включая tslib. Управляйте value как массивом объектов { file }; onChange получает FileList напрямую, поэтому не обращайтесь в этом обратном вызове к event.target. Проверяйте формат и размер до принятия локально выбранного файла, обрабатывайте пустой список, возвращаемый при удалении, и оставляйте подсказки и сообщения об ошибках видимыми. Встроенный предпросмотр HTML следует считать отдельно обозначенной интерпретацией. Ни одна из реализаций не загружает файл; проверка на сервере, отображение хода загрузки и подтверждение сохранения требуют фактического контракта с серверной частью.
05

Дизайн-система Suomi.fi Источники и область применения

Встроенный предпросмотр и скачиваемый ZIP — это интерпретация OpenDesign HTML/CSS. Отдельный полный пример React использует suomifi-ui-components 18.0.0 и проверенные контракты value и onChange компонента FileInput. В обоих примерах можно локально выбрать файл; ни один из них не загружает и не сохраняет документ на сервере.