Use o tema Horizon de SAP Fiori com UI5 Web Components: parâmetros reais do tema, densidade de conteúdo explícita, estados semânticos de valor e uma composição para solicitações de compra com validação local.
Interpretação offline HTML dos parâmetros Morning Horizon e da composição de formulário UI5. Um exemplo de pacote nativo é incluído separadamente. · Referência de implementação
02
Referência de design do sistema de design SAP Fiori
Parâmetros de origem Morning Horizon (sap_horizon) e documentação atual dos UI5 Web Components. Os nomes @sap menos abaixo são parâmetros de origem; os estilos do navegador usam as propriedades personalizadas --sap correspondentes. As dimensões protegidas são observações, não pontos de substituição recomendados.
O design do sistema de design SAP Fiori e a implementação com UI5 têm escopos diferentes
Um ponto de partida concreto
SAP Fiori descreve uma experiência de usuário empresarial. Esta referência escolhe UI5 Web Components para um exemplo implementável de solicitação de compra. Isso não significa que a instalação desses componentes crie um aplicativo SAPUI5, um plano de página do Fiori elements ou uma transação empresarial SAP autorizada.
O pacote principal de componentes fornece Input, Select e Button. Os componentes Fiori de nível mais alto estão em um pacote separado. Importar apenas os módulos usados neste exemplo deixa explícito o ponto de entrada e evita sugerir uma CDN não compatível com todos os componentes.
Sistema de design SAP Fiori: use parâmetros Horizon nomeados em vez de uma paleta azul genérica
Superfícies e papéis de estado
Morning Horizon define a página com uma superfície cinza-clara e usa uma superfície base branca. O azul da marca e a cor do texto são parâmetros distintos. Os papéis negativo, crítico, positivo e informativo descrevem significados, não uma lista de cores decorativas para alternar entre cartões.
A prévia usa uma faixa informativa para o resumo preparado porque a preparação local não equivale à aprovação de uma compra. O preço do item, os centros de custo e as anotações de aprovação são dados de exemplo originais. Eles nunca devem ser interpretados como regras de negócio fornecidas pela SAP.
Sistema de design SAP Fiori: Compacto é uma configuração de componente, não uma captura de tela menor
Aplique a densidade a uma região significativa
O UI5 permite usar um marcador de compactação na raiz, no body, em uma região ou em um componente. O atributo data-ui5-compact-size e a classe ui5-content-density-compact são mecanismos públicos. Alterar o marcador dinamicamente não exige um API de densidade separado.
Use controles compactos em uma tarefa densa de desktop somente quando a interação continuar adequada. A interpretação incorporada reduz o espaçamento entre controles e linhas, mas mantém as mesmas informações. No layout estreito, as regiões são empilhadas em vez de reduzir todos os rótulos e botões.
Sistema de design SAP Fiori: a família 72 e seu comportamento de carregamento
A disponibilidade das fontes faz parte da configuração
O tema Horizon especifica 72 e 72full antes das fontes alternativas. A documentação do UI5 explica como desativar o carregamento padrão de fontes e hospedá-las localmente. A entrada de conveniência FontFace.css está marcada como experimental; por isso, fixe e verifique novamente seu caminho se escolher essa opção.
A prévia independente usa Arial como alternativa explícita para uso offline. O exemplo nativo de UI5 usa a variável font-family publicada. Essa distinção evita afirmar que uma captura de tela visualmente semelhante, gerada com uma fonte alternativa, comprova que os recursos de fonte da SAP foram carregados.
Sistema de design SAP Fiori: um Select tem alterações confirmadas e provisórias
Escolha uma única estratégia de seleção controlada
O valor de Select corresponde ao valor ou ao texto de uma Option. Não é recomendado combinar um valor de Select com flags selected nas Options; um valor inexistente não seleciona nenhuma opção. O exemplo inicializa uma opção real de centro de custo e lê o valor de Select ao preparar o resultado.
O evento change contém a opção selecionada. O evento live-change também é disparado ao navegar pelas opções e ao voltar atrás com Escape. Use a seleção confirmada para dados de negócio e reserve as alterações provisórias para prévias.
Importe os registros de Select e Option antes de renderizar suas tags.
Associe o rótulo visível do centro de custo usando accessible-name-ref.
Mantenha value como a única estratégia de seleção neste exemplo.
Sistema de design SAP Fiori: a entrada numérica ainda requer validação do aplicativo
O estado e a mensagem do valor devem estar associados
O valor de Input é uma string, mesmo quando o tipo de entrada é Number. Converta-o e verifique se é um número inteiro finito dentro dos limites antes de multiplicá-lo pelo preço de exemplo. Um valor vazio não pode ser aceito como zero. O estado de erro semântico atual é Negative, não um enum Error inventado.
O slot valueStateMessage fornece um elemento raiz que contém uma explicação específica. O total em tempo real escuta o evento input; o resumo preparado só é atualizado quando o usuário aciona a ação.
Leia o título e a string numérica dos respectivos componentes.
Exija um título e uma quantidade inteira de 1 a 20 neste exemplo.
Marque os controles afetados como Negative e mantenha os valores digitados.
Prepare o resumo somente depois que ambas as condições forem atendidas.
Sistema de design SAP Fiori: mantenha o resultado descritivo e local
Use uma faixa para um resultado conciso
MessageStrip oferece designs semânticos e um controle para fechar. Uma explicação obrigatória pode ocultar o botão de fechar para que continue disponível. É melhor manter o slot padrão como texto, sem expandi-lo para um formulário ou painel.
O resumo inclui título, quantidade, total de exemplo e centro de custo. A frase final explica que nada foi enviado. Um serviço real substituiria esta etapa local por uma solicitação autorizada e uma resposta com o status real do backend.
Sistema de design SAP Fiori: recursos de tema e registro de módulos
A seleção de tema requer os recursos correspondentes
Morning Horizon é o padrão documentado e está incorporado aos componentes. Temas adicionais exigem o módulo Assets.js para cada biblioteca usada. Em seguida, setTheme pode selecionar Evening Horizon ou uma das variantes de alto contraste. Escolher um nome de tema escuro sem verificar os recursos carregados não constitui uma integração completa.
O ponto de entrada fornecido registra cada elemento personalizado antes de criar a marcação. O Vite processa importações ES dinâmicas e recursos JSON. Compile o projeto nativo e verifique fontes, carregamento do tema e comportamento do teclado separadamente do exemplo offline HTML.
Exemplos de componentes do sistema de design SAP Fiori
Exemplo interativo completo e independente
Salve o documento completo como index.html e abra-o em um navegador. Interpretação offline HTML dos parâmetros Morning Horizon e da composição de formulário UI5. Um exemplo de pacote nativo é incluído separadamente.
html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Fiori purchase request</title><style>
*{box-sizing:border-box}body{margin:0;color:#131e29;background:#f5f6f7;font:14px/1.5 Arial,sans-serif}header{background:white;padding:12px 24px;display:flex;gap:16px;align-items:center;border-bottom:1px solid #d5dadd}.symbol{width:32px;height:32px;display:grid;place-items:center;background:#0070f2;color:white;border-radius:8px;font-weight:bold}header strong{font-size:16px}header span:last-child{margin-left:auto;color:#556b82;font-size:12px}main{max-width:1100px;margin:auto;padding:24px}.objecthead{display:flex;justify-content:space-between;gap:20px;align-items:start;margin-bottom:24px}h1{font-size:28px;line-height:36px;margin:0 0 6px}h2{font-size:18px;margin:0 0 16px}.subtitle{color:#556b82;margin:0}.draft{background:#e1f4ff;color:#0032a5;padding:6px 12px;border-radius:6px}.layout{display:grid;grid-template-columns:minmax(0,1fr) 280px;gap:24px}.panel{background:white;border-radius:12px;padding:24px;border:1px solid #d5dadd}label{display:block;margin-bottom:6px;color:#556b82}input,select{width:100%;height:44px;border:1px solid #758ca4;border-radius:8px;padding:8px 12px;background:#fff;font:inherit;color:inherit}input:focus,select:focus,button:focus-visible{outline:2px solid #0032a5;outline-offset:3px}.fields{display:grid;grid-template-columns:1fr 1fr;gap:24px;margin-bottom:24px}.fields>div:first-child{grid-column:1/-1}.line{border-top:1px solid #d5dadd;padding-top:20px;display:grid;grid-template-columns:64px minmax(0,1fr) auto;gap:16px;align-items:center}.monitor{background:#e1f4ff;border:2px solid #556b82;height:42px;border-radius:4px;position:relative;margin-bottom:12px}.monitor:after{content:'';position:absolute;bottom:-12px;left:25%;width:50%;height:10px;border-bottom:3px solid #556b82;border-left:8px solid transparent;border-right:8px solid transparent}.line strong{display:block}.line small{color:#556b82}.money{font-size:24px;font-weight:600;white-space:nowrap}.unit{font-size:12px;color:#556b82}.total{display:flex;justify-content:space-between;padding-top:24px;font-weight:600}.controls{display:flex;gap:12px;flex-wrap:wrap;margin-top:24px}button{border:1px solid #0070f2;background:white;color:#0057b8;padding:10px 16px;border-radius:8px;font:600 14px/20px Arial;cursor:pointer}button.primary{background:#0070f2;color:white}button:hover{filter:brightness(.95)}.steps{list-style:none;padding:0;margin:0;counter-reset:step}.steps li{position:relative;padding:0 0 24px 36px;color:#556b82}.steps li:before{counter-increment:step;content:counter(step);position:absolute;left:0;top:0;border:1px solid #758ca4;border-radius:50%;width:24px;height:24px;text-align:center;background:white}.steps strong{display:block;color:#131e29}.steps li:first-child:before{background:#e1f4ff;color:#0057b8;border-color:#0070f2}.strip{margin-top:24px;background:#e1f4ff;border:1px solid #0070f2;padding:12px 16px;border-radius:8px}.strip.error{background:#ffeaf4;border-color:#aa0808;color:#aa0808}.foot{font-size:12px;color:#556b82;margin-top:24px}.compact input,.compact select{height:32px;padding:4px 8px}.compact .fields{gap:12px}.compact .panel{padding:16px}.compact .line{padding-top:12px}.compact button{padding:6px 12px}.hint{font-size:12px;color:#556b82;margin:6px 0 0}@media(max-width:700px){main{padding:20px 16px}.layout{grid-template-columns:1fr}.fields{grid-template-columns:1fr}.objecthead{display:block}.draft{display:inline-block;margin-top:12px}.line{grid-template-columns:48px minmax(0,1fr)}.line>.money{grid-column:2}.panel{padding:20px}header{padding:12px 16px}}
</style><header><span class="symbol">P</span><strong>Procurement workspace</strong><span>Sample environment</span></header><main><div class="objecthead"><div><h1>Purchase request</h1><p class="subtitle">PR-DRAFT · Workplace equipment</p></div><span class="draft">Draft · not submitted</span></div><div class="layout"><section class="panel"><h2>Request details</h2><form id="form" novalidate><div class="fields"><div><label for="title">Request title</label><input id="title" placeholder="e.g. Studio display upgrade" aria-describedby="notice"></div><div><label for="team">Cost center</label><select id="team"><option value="Design · CC-240">Design · CC-240</option><option value="Research · CC-360">Research · CC-360</option></select></div><div><label for="qty">Monitor quantity</label><input id="qty" type="number" min="1" max="20" step="1" value="2" aria-describedby="qty-help notice"><p id="qty-help" class="hint">Whole number from 1 to 20.</p></div></div><div class="line"><div class="monitor" aria-hidden="true"></div><div><strong>27-inch studio monitor</strong><small>Equipment · Item 100240</small></div><div class="money">€320 <span class="unit">/ unit</span></div></div><div class="total"><span>Estimated line total</span><output id="total">€640</output></div><div class="controls"><button class="primary">Prepare summary</button><button type="button" id="density" aria-pressed="false">Compact controls</button></div></form></section><aside class="panel"><h2>Request path</h2><ol class="steps"><li><strong>Prepare draft</strong>Check quantities and cost center.</li><li><strong>Review summary</strong>Confirm the local request details.</li><li><strong>Submit to service</strong>Not connected in this preview.</li></ol><p class="hint">The review path and price are illustrative application data.</p></aside></div><div class="strip" id="notice" role="status">Complete the draft before preparing the summary.</div><p class="foot">HTML interpretation of SAP Morning Horizon · UI5 native integration provided in guide · No SAP transaction created</p></main><script>
const $=id=>document.getElementById(id);function amount(){const n=Number($('qty').value);return Number.isInteger(n)&&n>=1&&n<=20?n:null}$('qty').oninput=()=>{$('total').textContent=amount()===null?'Invalid quantity':'€'+amount()*320};$('density').onclick=()=>{const active=document.body.classList.toggle('compact');$('density').setAttribute('aria-pressed',String(active));$('density').textContent=active?'Cozy controls':'Compact controls'};$('form').onsubmit=e=>{e.preventDefault();const title=$('title').value.trim(),n=amount();$('title').setAttribute('aria-invalid',String(!title));$('qty').setAttribute('aria-invalid',String(n===null));$('notice').classList.toggle('error',!title||n===null);if(!title||n===null){$('notice').textContent=!title?'Enter a title for this request.':'Use a whole quantity from 1 to 20.';(!title?$('title'):$('qty')).focus();return}$('notice').textContent='Local summary: '+title+' · '+n+' monitors · €'+n*320+' · '+$('team').value+'. Nothing submitted.'};
</script></html>
A chave de densidade deste documento HTML é uma interpretação. A entrada de UI5 demonstra o marcador compacto real, os elementos personalizados registrados e os recursos Horizon.
Solicitação de compra Horizon com quantidades validadas
Input, Select/Option, Button e MessageStrip compõem um resumo local da requisição. Os totais atualizados a cada tecla permanecem separados do resultado preparado.
javascript
// main.js in a Vite vanilla project. index.html contains <div id="app"></div>.
import '@ui5/webcomponents/dist/Button.js';
import '@ui5/webcomponents/dist/Input.js';
import '@ui5/webcomponents/dist/Select.js';
import '@ui5/webcomponents/dist/Option.js';
import '@ui5/webcomponents/dist/MessageStrip.js';
import '@ui5/webcomponents/dist/Assets.js';
import {setTheme} from '@ui5/webcomponents-base/dist/config/Theme.js';
setTheme('sap_horizon');
document.querySelector('#app').innerHTML = `
<main style="max-width:800px;margin:auto;padding:24px;font-family:var(--sapFontFamily)">
<h1>Purchase request</h1>
<p>Prepare a local requisition summary. No SAP transaction is created.</p>
<p id="request-label">Request title</p>
<ui5-input id="title" accessible-name-ref="request-label" required>
<span slot="valueStateMessage">Enter a title for this request.</span>
</ui5-input>
<p id="team-label">Cost center</p>
<ui5-select id="team" accessible-name-ref="team-label" value="design">
<ui5-option value="design">Design · CC-240</ui5-option>
<ui5-option value="research">Research · CC-360</ui5-option>
</ui5-select>
<p id="qty-label">Monitor quantity</p>
<ui5-input id="qty" type="Number" accessible-name-ref="qty-label" value="2">
<span slot="valueStateMessage">Use a whole number from 1 to 20.</span>
</ui5-input>
<p id="total">Estimated line total: €640</p>
<ui5-button id="prepare" design="Emphasized">Prepare summary</ui5-button>
<ui5-button id="density">Toggle compact controls</ui5-button>
<ui5-message-strip id="notice" design="Information" hide-close-button style="display:block;margin-top:24px">
Complete the draft before preparing the summary.
</ui5-message-strip>
</main>`;
const title=document.querySelector('#title'),qty=document.querySelector('#qty');
qty.addEventListener('input',()=>{
const n=Number(qty.value);
document.querySelector('#total').textContent=Number.isInteger(n)&&n>=1&&n<=20
? `Estimated line total: €${n*320}` : 'Enter a valid quantity to calculate the total.';
});
document.querySelector('#prepare').addEventListener('click',()=>{
const n=Number(qty.value), validTitle=!!title.value.trim(), validQty=Number.isInteger(n)&&n>=1&&n<=20;
title.valueState=validTitle?'None':'Negative';qty.valueState=validQty?'None':'Negative';
const notice=document.querySelector('#notice');
if(!validTitle||!validQty){notice.design='Negative';notice.textContent='Correct the request title or quantity before continuing.';return;}
notice.design='Information';
notice.textContent=`Local summary: ${title.value.trim()}, ${n} monitors, €${n*320}, ${document.querySelector('#team').value}. Nothing submitted.`;
});
document.querySelector('#density').addEventListener('click',()=>document.body.toggleAttribute('data-ui5-compact-size'));
A regra de quantidade, o preço de €320 por item e os centros de custo são dados de aplicativo inventados, não políticas da SAP.
UI5 Web Components são uma implementação dos padrões Fiori; isto não é um aplicativo SAPUI5 completo nem um plano de página do Fiori elements.
Nenhuma transação SAP é criada. A validação da prévia offline não implica a compilação das dependências nativas.
04
Configuração do agente do sistema de design SAP Fiori
Ponto de partida para implementação
Substitua o main.js do Vite pelo exemplo completo. A documentação do UI5 requer um empacotador de módulos ES; não oferece uma CDN oficial com todos os componentes.
bash
npm create vite@latest fiori-request -- --template vanilla
cd fiori-request
npm install
npm install @ui5/webcomponents @ui5/webcomponents-base
npm run dev
Um prompt para seu projeto
Prompt para agente de IA
Crie uma solicitação de compra Fiori usando os componentes Input, Select, Button e MessageStrip do UI5 Web Components com o tema Horizon. Preserve a validação numérica, o estado de valor negativo correto, a densidade compacta explícita e o comportamento transparente do resumo local.
05
SAP Fiori Fontes e escopo do sistema de design
Referência independente de OpenDesign. Exemplo com UI5 Web Components, não uma transação SAP implantada nem uma aplicação completa do Fiori elements.