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

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

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

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

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

### Типографика

| Название / правило | Значение / конфигурация | Применение |
| --- | --- | --- |
| Family | Source Sans 3 | В версии 18 используется Source Sans 3; в версии 17 и более ранних — Source Sans Pro. Загружайте шрифты отдельно. |
| Body text | 18px | Одинаковое значение по умолчанию для мобильных и настольных устройств. |
| Small body | 16px | Текстовый режим smallScreen, а не автоматическое правило для области просмотра. |
| Lead | 22px / 20px smallScreen | Не более одного вводного блока на экран; не используйте lead для каждого абзаца. |
| Weights | 300 / 400 / 600 | Файлы шрифтов, необходимые пакету компонентов. |
### Отступы и поверхности

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

| Название / правило | Значение / конфигурация | Применение |
| --- | --- | --- |
| Default maximum width | 600px | Ширина конкретного компонента, а не сетка всего сайта. |
| fullWidth | Boolean layout option | Растягивайте на всю ширину родительского элемента, если этого требует форма. |
| smallScreen | Explicit compact presentation option | Не выводите из этого свойства наличие глобальной автоматической контрольной точки. |
| Single selection | Chosen file replaces picker and drop area | Выбор нескольких файлов — отдельный сценарий со списком файлов ниже. |
| Required copy roles | labelText, hintText, dragAreaText, removeFileText, addedFileAriaText | Локализуйте описание каждой роли: одного имени файла недостаточно для полного объявления средствами специальных возможностей. |
## Дизайн-система Suomi.fi — полное руководство

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

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

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

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

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

Встроенный предпросмотр по-прежнему явно обозначен как интерпретация 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.

```
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 Примеры компонентов дизайн-системы

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

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

```
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 и размеру выбраны для примера; загрузка не выполняется.

```
<!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 с помощью команд настройки.

```
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 с помощью команд настройки.

```
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 с помощью команд настройки.

```
<!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>
```

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

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

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

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

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

```
npm install --save-exact suomifi-ui-components@18.0.0 react@18.3.1 react-dom@18.3.1 styled-components@6.5.3 tslib@2.8.1 @fontsource/source-sans-3@5.3.0
npm install --save-dev --save-exact esbuild@0.28.2
# 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
```

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

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

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

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

- Руководство по FileInput Структура, назначение текстов, ширина и поведение при выборе одного или нескольких файлов.

- Типографика Source Sans 3 и переход между версиями.

- Текстовый компонент Размеры основного, мелкого и увеличенного текста.

- Источник токенов Фактические значения отступов, цветов и скруглений.

- Репозиторий компонентов Реализация React, зависимости и лицензия MIT.

- Скачать полный рабочий пример ZIP-архив с полным HTML, локальными зависимостями CSS/JavaScript, лицензиями и точными инструкциями по запуску. Сборка не требуется.

- Проверенная реализация FileInput 18.0.0 Исходный код опубликованного пакета: dist/esm/core/Form/FileInput/FileInput.js. Управляемое значение и обратный вызов с FileList проверены для этой версии и испытаны в отдельной нативной сборке.

## Дизайн-система Suomi.fi Связанные ресурсы

### UNDP дизайн-система

Изучите опубликованные токены цвета и интервалов UNDP, нативные вкладки с управлением клавиатурой и полноценный пример чтения материалов мастер-класса с локальным отслеживанием прогресса.

### USWDS

Объедините токены интервалов USWDS, роли тем, семантические таблицы и нативные аккордеоны в интерфейсе для поиска и сравнения возможностей.

### VA дизайн-система

Создавайте понятные сценарии получения услуг с семантическими токенами VA и нативным списком Process List: наглядными пояснениями к этапам, содержательными обозначениями статуса и дополнительными сведениями, не мешающими воспринимать основной маршрут.


- [Справочник по реализации](https://designsystem.suomi.fi/components/fileinput/)
- [Источник](https://designsystem.suomi.fi/components/text/)
- [Источник](https://github.com/vrk-kpa/suomifi-design-tokens/blob/master/src/tokens.json)
- [Источник](https://designsystem.suomi.fi/components/fileinput/)
- [Прочитать вспомогательную спецификацию](https://github.com/vrk-kpa/suomifi-ui-components)
- [Прочитать вспомогательную спецификацию](https://designsystem.suomi.fi/components/text/)
- [Прочитать вспомогательную спецификацию](https://github.com/vrk-kpa/suomifi-design-tokens/blob/master/src/tokens.json)
- [Прочитать вспомогательную спецификацию](https://designsystem.suomi.fi/components/fileinput/)
- [Прочитать вспомогательную спецификацию](https://www.npmjs.com/package/suomifi-ui-components/v/18.0.0)
- [Справочник по коду](https://designsystem.suomi.fi/styles)
- [Прочитать вспомогательную спецификацию](https://designsystem.suomi.fi/styles)
- [Справочник по коду](https://designsystem.suomi.fi/components/fileinput/)
- [Справочник по коду](https://www.npmjs.com/package/suomifi-ui-components/v/18.0.0)
- [Руководство по FileInput Структура, назначение текстов, ширина и поведение при выборе одного или нескольких файлов.](https://designsystem.suomi.fi/components/fileinput/)
- [Типографика Source Sans 3 и переход между версиями.](https://designsystem.suomi.fi/styles/typography/)
- [Текстовый компонент Размеры основного, мелкого и увеличенного текста.](https://designsystem.suomi.fi/components/text/)
- [Источник токенов Фактические значения отступов, цветов и скруглений.](https://github.com/vrk-kpa/suomifi-design-tokens/blob/master/src/tokens.json)
- [Репозиторий компонентов Реализация React, зависимости и лицензия MIT.](https://github.com/vrk-kpa/suomifi-ui-components)
- [Проверенная реализация FileInput 18.0.0 Исходный код опубликованного пакета: dist/esm/core/Form/FileInput/FileInput.js. Управляемое значение и обратный вызов с FileList проверены для этой версии и испытаны в отдельной нативной сборке.](https://www.npmjs.com/package/suomifi-ui-components/v/18.0.0)
