# Sistema de design Suomi.fi

## Prévia da interface sistema de design Suomi.fi

Teste um PDF, rejeite um arquivo não compatível e remova o documento selecionado. Os arquivos permanecem no navegador.

## Referência de design sistema de design Suomi.fi

Documentação oficial, repositório de tokens inspecionado e metadados da versão 18.0.0 de suomifi-ui-components. A prévia é uma interpretação original, não o runtime nativo de React.

### Tipografia

| Nome / Regra | Valor / Configuração | Uso |
| --- | --- | --- |
| Family | Source Sans 3 | Versão 18; a versão 17 e as anteriores usavam Source Sans Pro. Carregue as fontes separadamente. |
| Body text | 18px | Mesmo padrão em dispositivos móveis e computadores. |
| Small body | 16px | Tratamento smallScreen do texto, não uma regra automática de viewport. |
| Lead | 22px / 20px smallScreen | Uma introdução por visualização; não use lead em todos os parágrafos. |
| Weights | 300 / 400 / 600 | Arquivos de fonte necessários para o pacote de componentes. |
### Espaçamento e superfícies

| Nome / Regra | Valor / Configuração | Uso |
| --- | --- | --- |
| Space scale | 5, 10, 15, 20, 25, 30, 40, 60, 80px | De xxs a xxxxl no JSON do repositório inspecionado. |
| Inset scale | 2, 4, 6, 8, 10, 16, 20px | De insetXxs a insetXxl; não faz parte da escala de espaçamento externo. |
| Basic radius | 2px | repository radius.basic; não presuma um raio amplo para cartões. |
| Highlight base | hsl(212, 63%, 45%) | Azul interativo padrão. |
| Highlight dark 1 | hsl(212, 63%, 37%) | Função de interação mais escura. |
| Highlight light 2 | hsl(212, 63%, 90%) | Função de superfície clara; verifique o contraste com o texto escolhido. |
### Layout e idioma de FileInput

| Nome / Regra | Valor / Configuração | Uso |
| --- | --- | --- |
| Default maximum width | 600px | Largura específica do componente, não uma grade para o site inteiro. |
| fullWidth | Boolean layout option | Expanda até preencher o contêiner pai quando o formulário precisar. |
| smallScreen | Explicit compact presentation option | Não invente um breakpoint global automático com base nesta propriedade. |
| Single selection | Chosen file replaces picker and drop area | A seleção de vários arquivos é um padrão separado, com os arquivos listados abaixo. |
| Required copy roles | labelText, hintText, dragAreaText, removeFileText, addedFileAriaText | Localize cada função; anunciar apenas o nome do arquivo não é suficiente para acessibilidade. |
## Guia completo sistema de design Suomi.fi

Um guia prático para escolher, aplicar e avaliar este sistema em uma interface real.

Orientações completas, um ponto de partida para a implementação e links para o código-fonte.

## Limites da implementação sistema de design Suomi.fi

### Sistema de componentes React

> Suomi.fi oferece React componentes estilizados com styled-components e um pacote de tokens separado. Na versão 18, a fonte esperada passa a ser Source Sans 3. Páginas existentes na versão 17 ainda podem usar Source Sans Pro; comparar essas capturas de tela sem verificar a versão do pacote pode levar a uma correção tipográfica equivocada.

A prévia incorporada continua sendo uma interpretação de HTML/CSS, identificada explicitamente como tal, do padrão documentado para um único arquivo. Abaixo, também foi incluído um exemplo separado de FileInput nativo de React, com callback verificado, valor controlado, dependências e importações de fontes. São duas implementações da mesma tarefa de seleção local; o exemplo nativo não transforma retroativamente a prévia incorporada de HTML no componente React.

Consulte a especificação de apoio

## Tipografia e carregamento de fontes sistema de design Suomi.fi

### Mantenha o texto corrido legível

Use o tamanho de 18 px documentado para o corpo do texto tanto em dispositivos móveis quanto em computadores. Uma viewport estreita não justifica reduzir todas as explicações do formulário. O tratamento de texto pequeno usa 16 px e deve ficar restrito a informações secundárias. O texto de destaque usa 22 px, reduzidos para 20 px com o tratamento compacto; reserve-o para a introdução da página.

Carregue os pesos de fonte pretendidos antes de comparar as quebras de linha. O pacote de componentes espera arquivos da Source Sans 3, enquanto esta prévia independente usa Arial de propósito. Essa substituição está indicada na observação da prévia e não deve ser apresentada como uma reprodução exata do componente nativo.

Consulte a especificação de apoio

## Espaçamento e largura sistema de design Suomi.fi

### Duas escalas de espaçamento distintas

A fonte dos tokens separa o espaçamento comum do espaçamento interno. No JSON inspecionado, o valor de l no espaçamento comum é 25 px; não copie um exemplo antigo do README que descreve l como 32 px. Os espaçamentos internos começam em 2 px e seguem uma sequência diferente. Ao gerar estilos, use as exportações reais da versão instalada.

FileInput tem largura máxima documentada de 600 px e uma opção fullWidth. Essa é uma restrição do componente, não uma indicação de que todas as páginas devam usar um contêiner de 600 px. Um formulário de recebimento de documentos pode colocar o campo em um layout mais amplo, mantendo o texto explicativo próximo ao rótulo.

Consulte a especificação de apoio

## Estrutura do seletor de arquivos sistema de design Suomi.fi

### O texto faz parte do contrato do componente

O rótulo visível identifica o documento solicitado. A instrução informa os formatos aceitos, o tamanho e a quantidade de arquivos antes de a pessoa abrir o seletor. A área de soltar oferece um atalho com o ponteiro, mas não deve substituir o campo de arquivo. As orientações oficiais descrevem o controle de seleção como o rótulo de um campo de arquivo nativo oculto.

No modo de arquivo único, o documento selecionado substitui o seletor e a área de soltar. Mantenha uma ação clara para removê-lo ao lado do documento. O modo de vários arquivos usa uma disposição de lista diferente; não acrescente arquivos adicionais silenciosamente a uma solicitação de arquivo único.

- labelText: identifique a evidência ou o documento solicitado, não use apenas “Enviar”.

- removeFileText: torne a ação de remoção compreensível no contexto do arquivo.

- addedFileAriaText: forneça o contexto da seleção antes de anunciar o nome do arquivo.

Consulte a especificação de apoio

## Seleção e recuperação sistema de design Suomi.fi

### Uma máquina de estados local para anexos

O exemplo aceita um PDF de até 5.000.000 bytes. Essas regras da aplicação foram escolhidas para este cenário de oficina. Não são padrões do pacote nem uma política oficial de envio de arquivos do Suomi.fi. O filtro accept do navegador serve apenas como indicação para o seletor; o exemplo verifica de forma independente o nome e o tamanho do arquivo após a seleção ou o arraste.

Metadados inválidos mantêm o seletor disponível e explicam como corrigir o problema. Uma seleção válida exibe o nome usando textContent, informa o tamanho em bytes e move o foco para o controle de remoção. Ao remover o arquivo, o valor do campo subjacente é limpo, o seletor volta a aparecer e o foco retorna, permitindo selecionar novamente o mesmo arquivo.

1. Selecione ou arraste exatamente um arquivo; rejeite vários arquivos com uma mensagem específica.

2. Verifique as regras locais do exemplo e anuncie o erro ou o nome do arquivo selecionado.

3. Remova o anexo e restaure a opção original de seleção.

Consulte a especificação de apoio

## Integração nativa sistema de design Suomi.fi

### Instale um conjunto de dependências compatível

A implementação de FileInput 18.0.0 publicada chama onChange com um FileList, não com um evento change de React. O valor controlado é um array de objetos de item de arquivo; o exemplo converte cada File aceito em { file }. O mesmo callback é executado quando a ação de remoção integrada altera a lista; assim, um FileList vazio limpa o array controlado. Esses contratos foram verificados no módulo dist/esm/core/Form/FileInput/FileInput.js publicado.

Mantenha value controlado desde a primeira renderização, inicializando-o como um array vazio. Valide o FileList recebido antes de convertê-lo nesse array. Este exemplo rejeita arquivos cujos nomes não terminam em .pdf ou cujo tamanho excede 5.000.000 bytes, e limpa a seleção em caso de rejeição. Essas são regras locais do exemplo, não uma verificação de segurança nem uma política do Suomi.fi. A validação do conteúdo no servidor continua sendo necessária antes de aceitar um envio real.

O exemplo nativo abaixo carrega Source Sans 3 nos pesos 400 e 600, monta React em um elemento raiz explícito e usa styled-components por meio da biblioteca. Inclua tslib explicitamente: os módulos ESM da versão 18.0.0 importam seus auxiliares, e uma compilação limpa sem essa dependência falhou. A configuração fixada abaixo inclui o runtime ausente e os arquivos de fonte. Não é necessário adicionar um provedor de tema para este exemplo com o tema padrão.

Consulte a especificação de apoio

### Use exportações de tokens verificadas

O guia oficial de estilos demonstra suomifiDesignTokens.spacing e suomifiDesignTokens.colors. O exemplo abaixo usa esses caminhos exportados para um contêiner personalizado; ele não substitui a implementação interna de 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
};
```

Referência de código

Consulte a especificação de apoio

## Acessibilidade e uso responsivo sistema de design Suomi.fi

### Acesse o campo sem arrastar

Mantenha um campo de arquivo nativo operável pelo teclado, mesmo quando a área de soltar estiver em destaque. Associe a instrução e o erro por meio de aria-describedby. Anuncie as alterações da seleção e a remoção sem reler a página inteira. Se houver vários controles desse tipo no formulário, o botão de remoção deve identificar o arquivo selecionado.

A propriedade oficial smallScreen oferece uma apresentação compacta. Ela não define um breakpoint global. Esta prévia independente usa um ajuste de padding específico da aplicação em 480 px, mantendo o texto do corpo em 18 px. Teste nomes de arquivo longos, ampliação e rótulos traduzidos; permita que os nomes quebrem linha sem alargar a página inteira.

Consulte a especificação de apoio

## Responsabilidades em produção sistema de design Suomi.fi

### Um arquivo selecionado não é um arquivo enviado

A demonstração nunca lê o conteúdo dos documentos nem envia solicitações. O nome do arquivo selecionado e a quantidade de bytes não comprovam que o documento seja válido, esteja armazenado ou tenha sido aceito. Serviços reais precisam de validação no servidor, progresso do envio, recuperação de falhas, regras de retenção e uma confirmação vinculada a uma resposta real.

O código do componente é licenciado pelo MIT. Essa licença não autoriza um projeto independente a se apresentar como um serviço do governo finlandês nem a usar uma identidade institucional restrita. Para experimentos, use um nome de projeto neutro e, para uma implementação oficial, obtenha as orientações de marca adequadas.

Consulte a especificação de apoio

## Exemplos de componentes do sistema de design sistema de design Suomi.fi

### Use as exportações oficiais de tokens

Caminhos verificados para exportar espaçamentos e cores para um wrapper personalizado.

```
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
};
```

Referência de código

### Seleção e remoção de um único arquivo

Interpretação local completa. Os limites de PDF e tamanho são escolhas do cenário; não há envio.

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

Referência de código

- Não é o componente nativo React.

- Em um serviço de produção, valide o conteúdo dos arquivos no servidor.

### FileInput nativo com validação controlada

Salve como main.jsx. Em conjunto, estes três arquivos reproduzem o exemplo nativo React usando os comandos de configuração.

```
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 />);
```

Referência de código

- O aplicativo cuida da validação; o componente nativo oferece seleção, remoção e controles acessíveis para arquivos.

### Layout da página de exemplo nativo

Salve como app.css. Em conjunto, estes três arquivos reproduzem o exemplo nativo React usando os comandos de configuração.

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

Referência de código

- O aplicativo cuida da validação; o componente nativo oferece seleção, remoção e controles acessíveis para arquivos.

### Ponto de montagem do exemplo nativo e recursos gerados

Salve como index.html. Em conjunto, estes três arquivos reproduzem o exemplo nativo React usando os comandos de configuração.

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

Referência de código

- O aplicativo cuida da validação; o componente nativo oferece seleção, remoção e controles acessíveis para arquivos.

## Configuração do agente sistema de design Suomi.fi

### Ponto de partida para implementação

Este exemplo reproduz a implementação nativa React abaixo, incluindo os arquivos locais da fonte Source Sans 3. Testado com formato inválido, seleção válida, remoção integrada e um PDF grande, em telas de 390 px e 1440 px. O ZIP de pré-visualização já disponível para download é uma interpretação separada HTML/CSS; seu README continua correto.

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

### Um prompt para seu projeto

```
Use o exemplo nativo fornecido de FileInput 18.0.0 do Suomi.fi React, com Source Sans 3 e as dependências de execução fixadas, incluindo tslib. Controle o valor como um array de objetos { file } e receba FileList diretamente em onChange; não leia event.target nesse callback. Valide o formato e o tamanho antes de aceitar uma seleção local, trate a lista vazia emitida pela remoção e mantenha o texto de ajuda e o de erro visíveis. Apresente a pré-visualização incorporada HTML como uma interpretação identificada separadamente. Nenhuma das implementações envia arquivos; a validação no servidor, o progresso e a confirmação do armazenamento exigem um contrato real com o backend.
```

## Fontes e escopo de sistema de design Suomi.fi

A pré-visualização incorporada e o ZIP para download são uma interpretação HTML/CSS de OpenDesign. O exemplo completo React, disponível separadamente, usa suomifi-ui-components 18.0.0 e os contratos verificados de value e onChange do FileInput. Os dois exemplos permitem selecionar arquivos localmente; nenhum envia nem armazena documentos em um servidor.

- Orientações sobre o FileInput Anatomia, funções dos textos, larguras e comportamento de seleção única ou múltipla.

- Tipografia Source Sans 3 e transição entre versões.

- Componente de texto Tamanhos de texto para corpo, pequeno e destaque.

- Origem dos tokens Valores reais de espaçamento, cor e raio.

- Repositório do componente Implementação React, dependências e licença MIT.

- Baixar o exemplo completo funcional ZIP com HTML completo, dependências locais CSS/JavaScript, licenças incluídas e instruções exatas de inicialização. Não é necessário executar uma etapa de compilação.

- Implementação verificada do FileInput 18.0.0 Origem do pacote publicado: dist/esm/core/Form/FileInput/FileInput.js. O valor controlado e o callback FileList foram conferidos nesta versão e testados em uma compilação nativa separada.

## Recursos relacionados a sistema de design Suomi.fi

### UNDP sistema de design

Explore os tokens públicos de cor e espaçamento da UNDP, abas nativas operáveis pelo teclado e um exemplo completo de leitura de oficina com progresso de revisão local.

### USWDS

Combine os tokens de espaçamento de USWDS, os papéis do tema, tabelas semânticas e accordions nativos em uma comparação de oportunidades pesquisável.

### VA sistema de design

Crie jornadas de serviço claras com os tokens semânticos e a Process List nativa da VA: explicações visíveis das etapas, rótulos de status significativos e detalhes complementares que mantêm o fluxo principal legível.


- [Referência de implementação](https://designsystem.suomi.fi/components/fileinput/)
- [Fonte](https://designsystem.suomi.fi/components/text/)
- [Fonte](https://github.com/vrk-kpa/suomifi-design-tokens/blob/master/src/tokens.json)
- [Fonte](https://designsystem.suomi.fi/components/fileinput/)
- [Consulte a especificação de apoio](https://github.com/vrk-kpa/suomifi-ui-components)
- [Consulte a especificação de apoio](https://designsystem.suomi.fi/components/text/)
- [Consulte a especificação de apoio](https://github.com/vrk-kpa/suomifi-design-tokens/blob/master/src/tokens.json)
- [Consulte a especificação de apoio](https://designsystem.suomi.fi/components/fileinput/)
- [Consulte a especificação de apoio](https://www.npmjs.com/package/suomifi-ui-components/v/18.0.0)
- [Referência de código](https://designsystem.suomi.fi/styles)
- [Consulte a especificação de apoio](https://designsystem.suomi.fi/styles)
- [Referência de código](https://designsystem.suomi.fi/components/fileinput/)
- [Referência de código](https://www.npmjs.com/package/suomifi-ui-components/v/18.0.0)
- [Orientações sobre o FileInput Anatomia, funções dos textos, larguras e comportamento de seleção única ou múltipla.](https://designsystem.suomi.fi/components/fileinput/)
- [Tipografia Source Sans 3 e transição entre versões.](https://designsystem.suomi.fi/styles/typography/)
- [Componente de texto Tamanhos de texto para corpo, pequeno e destaque.](https://designsystem.suomi.fi/components/text/)
- [Origem dos tokens Valores reais de espaçamento, cor e raio.](https://github.com/vrk-kpa/suomifi-design-tokens/blob/master/src/tokens.json)
- [Repositório do componente Implementação React, dependências e licença MIT.](https://github.com/vrk-kpa/suomifi-ui-components)
- [Implementação verificada do FileInput 18.0.0 Origem do pacote publicado: dist/esm/core/Form/FileInput/FileInput.js. O valor controlado e o callback FileList foram conferidos nesta versão e testados em uma compilação nativa separada.](https://www.npmjs.com/package/suomifi-ui-components/v/18.0.0)
