Design de produits d’entreprise · Nouvelle ressource

Système de design Nord.

Examinez les tokens du thème Therapy de Nord et les contrats des Web Components au moyen d’un brouillon de demande de salle : rôles de couleur réels, dimensions adaptatives des champs, validation explicite et résultats préparés localement.

Guide OpenDesign8 chapitres38 entrées de référenceGuide de l’application d’origine
01

Aperçu de l’interface système de design Nord

Choisissez l’une des cinq capacités de salle, validez un titre et préparez un récapitulatif local de la demande.

Brouillon de demande de salleOuvrir l’exemple complet
Interprétation hors ligne des jetons Nord Therapy HTML/CSS ; l’intégration native du Web Component est présentée séparément. · Référence de mise en œuvre
02

Référence de conception système de design Nord

Jetons Nord 9.0.4 et documentation actuelle des composants. Les valeurs ci-dessous décrivent le thème Therapy par défaut, et non l’ensemble des marques Nordhealth. La documentation publique n’autorise pas l’utilisation de Nord en dehors du cadre prévu par Nordhealth.

Rôles du thème Therapy

Source
Nom / règleValeur / configurationUtilisation
--n-color-accent#3559c7 Action principale.
--n-color-text#0c1a3d Contenu principal.
--n-color-text-weak#36434a Texte d’accompagnement.
--n-color-background#fafbfb Page.
--n-color-surface#ffffff Panneau.
--n-color-border#d8dee4 Séparateur.
--n-color-border-strong#bcc5cc Contour du contrôle.
--n-color-text-error#d24023 Message d’erreur.

Espacement

Source
Nom / règleValeur / configurationUtilisation
--n-space-xs4pxTrès serré.
--n-space-s8pxAssocié.
--n-space-m16pxGroupe.
--n-space-l24pxSection.
--n-space-xl36pxGrand.
--n-space-xxl72pxMajeur.

Typographie et forme

Source
Nom / règleValeur / configurationUtilisation
--n-font-size-m0.875remCorps de texte.
--n-font-size-l1remTexte large.
--n-font-size-xl1.25remTitre de section.
--n-font-size-xxl1.5remTitre.
--n-line-height1.5Multiplicateur du corps de texte.
--n-line-height-form20pxInterligne du contrôle.
--n-font-weight-heading600Titre de section.
--n-border-radius-s3pxContrôle.
--n-border-radius5pxSurface.

Contrat d’Input

Source
Nom / règleValeur / configurationUtilisation
label / hint / errorBuilt-in field textInput autonome avec libellé intégré.
expandBoolean, default falseOccupe toute la largeur du parent.
sizes / m / lMoyen par défaut.
readonly versus disabledSubmitted versus excludedUn champ en lecture seule reste accessible au focus.
--n-input-inline-size240pxLargeur fixe par défaut ; préférez expand pour les formulaires adaptatifs.

Contrat de Select

Source
Nom / règleValeur / configurationUtilisation
Default slotNative option elementsN’inventez pas nord-option.
valueStringSélection contrôlée.
requiredBooleanUtilisez novalidate et gérez les erreurs dans l’application.
changeUser selection eventLisez component.value.
focus()Component methodAttendez la définition avant d’appeler le composant.

Contrat de Button

Source
Nom / règleValeur / configurationUtilisation
typesubmit by defaultPrécisez le type button pour les actions qui ne soumettent pas le formulaire.
variantdefault / primary / dashed / plain / dangerUne seule action principale par section.
hrefCreates anchor semanticsPour la navigation.
sizes / m / lMoyen par défaut.
loadingBusy presentationAssociez-le à un état annoncé.
03

Guide complet système de design Nord

Un guide pratique pour choisir, appliquer et évaluer ce système dans une interface réelle.

DESIGN-nordhealth.md

Des conseils complets, un point de départ pour la mise en œuvre et des liens vers les sources.

Télécharger le guide

Système de design Nord Nord est un système produit interne avec des références publiques

Rendez l’usage prévu explicite

La documentation de Nord décrit un système conçu pour les expériences Nordhealth. Ses composants accessibles au public constituent des références utiles, mais cet exemple ne prétend pas que la marque ou les conditions d’utilisation des composants autorisent une réutilisation commerciale sans restriction. Les noms de salles et le processus de demande présentés ici sont des données de démonstration originales.

Extrait de ce guide OpenDesign

Le tableau de jetons par défaut correspond à Therapy. Une application vétérinaire ou de santé doit sélectionner le thème prévu à cet effet, plutôt que de supposer qu’une touche de bleu définit tous les produits Nordhealth. La décision concernant le thème doit relever de l’application.

Consultez la spécification associée

Système de design Nord Les rôles Therapy préservent la sobriété de l’espace de travail

Distinguez les rôles du texte, des contours et des surfaces

L’exemple utilise le rôle de texte principal pour les détails de la demande et un rôle plus discret pour les explications. Des panneaux blancs se détachent sur la page blanc cassé ; une bordure plus marquée signale les champs modifiables. Le texte d’erreur apparaît à côté du titre invalide, plutôt que de teinter toute l’interface en rouge. L’aperçu ne contient aucune information clinique ni donnée de patient.

Consultez la spécification associée

Système de design Nord Le texte compact nécessite un interligne suffisant

Utilisez ensemble la taille et l’interligne documentés

Le jeton associe une taille de corps de 0.875rem à une hauteur de ligne de 1.5, tandis que le texte des formulaires dispose d’une boîte de ligne distincte de 20px. Il s’agit de deux règles différentes : appliquer la valeur des formulaires aux longs paragraphes les comprimerait inutilement. La référence en ligne utilise le jeton de famille Nordhealth Sans ; cette interprétation hors ligne recourt délibérément aux polices système disponibles, sans prétendre qu’une police sous licence est fournie.

Consultez la spécification associée

Système de design Nord Étendez les contrôles dans la grille de l’application

Le composant ne définit pas de point de rupture pour la page

Input utilise par défaut une variable inline-size de 240px. expand est la méthode documentée pour occuper toute la colonne de champ disponible. Dans notre exemple, la liste des salles se trouve à côté de l’éditeur sur ordinateur et passe au-dessus sur mobile ; ce point de rupture relève de l’application, pas d’un jeton Nord. Le nom de la salle, sa capacité et son libellé de disponibilité restent visibles lorsqu’une ligne est sélectionnée.

Dans l’interprétation hors ligne, la liste des salles sélectionnées est un groupe radio natif. L’exemple fourni séparément pour la bibliothèque utilise un Select à cinq options. Les deux permettent de choisir une salle, mais illustrent des mises en page différentes et ne sont pas présentés comme des implémentations identiques à l’exécution du composant.

Consultez la spécification associée

Système de design Nord Confiez les libellés et les messages d’erreur à une seule source

Les champs autonomes suffisent pour ce formulaire

Input ou Select peut gérer lui-même son libellé, son indication et son erreur. Lorsqu’elle est utilisée, la composition Field prend en charge ces responsabilités ; cumuler les deux séries produirait des indications redondantes. Cet exemple utilise la version autonome et associe une erreur concise au titre lorsque celui-ci est vide après suppression des espaces superflus.

Les champs désactivés sont exclus de l’envoi du formulaire, tandis que les champs en lecture seule conservent une valeur pertinente, accessible au focus et envoyée avec le formulaire. Ne désactivez pas l’identifiant d’une salle simplement pour empêcher sa modification s’il doit toujours accompagner la demande.

  • Laissez visible le libellé du titre de la demande.
  • Utilisez l’indication pour préciser le contenu attendu, et non à la place du libellé.
  • Associez le message de validation au contrôle invalide.

Consultez la spécification associée

Système de design Nord Select contient des éléments option ordinaires

Lisez la valeur depuis le composant hôte

Le slot par défaut accepte des éléments option natifs. Chaque salle possède une valeur stable et un libellé descriptif visible qui indique sa capacité. L’événement change informe l’application qu’elle doit recalculer le récapitulatif à partir de la valeur du composant hôte. Cette composition n’utilise aucune balise personnalisée nord-option.

Nord recommande Select pour les ensembles de choix plus importants et les boutons radio lorsqu’il est utile d’afficher directement quelques choix. L’exemple propose cinq salles ; la présentation hors ligne en boutons radio facilite la comparaison visuelle des capacités.

Consultez la spécification associée

Système de design Nord Les valeurs par défaut de Button influent sur la composition du formulaire

Définissez explicitement les sémantiques d’action, de lien et de chargement

Par défaut, Button utilise type="submit". Une action secondaire d’aperçu ou de réinitialisation placée dans un formulaire doit donc préciser son type si elle ne doit pas déclencher l’envoi. L’ajout d’un href au composant lui confère les sémantiques d’un lien ; utilisez cette option pour la navigation plutôt qu’un gestionnaire de clic qui imite une ancre.

L’état de chargement conserve le focus sur le bouton tout en empêchant les activations répétées. Son indicateur de chargement est masqué aux technologies d’assistance ; l’application doit donc communiquer la progression par des mots. N’utilisez pas systématiquement l’état désactivé : une action indisponible et une action en cours n’ont pas les mêmes besoins en matière de focus et de retour d’information.

L’exemple de demande de salle effectue un calcul synchrone du brouillon et n’a donc pas besoin d’un délai de chargement. Le bouton principal vérifie le titre et lit la salle choisie ; toute modification de l’un ou de l’autre supprime la phrase de brouillon devenue obsolète. Les sections Input et Select ci-dessus expliquent quelles API Nord gèrent ces champs.

Consultez la spécification associée

Système de design Nord Chargez le CSS requis avant d’appeler les méthodes des composants

Le prototypage du chargement et la création d’un bundle de production diffèrent

Le guide de démarrage rapide officiel associe le module de composants au framework CSS. Ce dernier fournit les jetons partagés et les styles de base. Pour une application intégrée à un bundle, installez @nordhealth/css et @nordhealth/components, importez une seule fois le CSS et importez uniquement les modules des composants utilisés. Les modules des packages enregistrent leurs éléments comme effets de bord.

React 19 peut utiliser directement ces éléments personnalisés. L’ancien wrapper @nordhealth/react est obsolète selon les recommandations actuelles. Le rendu côté serveur n’inclut pas le DOM shadow des composants ; les imports Next.js nécessitent une frontière client. Distinguez ces limites d’intégration de l’aperçu hors ligne HTML, dont les interactions fonctionnent sans la bibliothèque.

  1. Chargez le CSS du framework avant les modules des composants.
  2. Attendez customElements.whenDefined avant d’appeler focus pendant l’initialisation.
  3. Ajoutez les gestionnaires de validation et d’état local.
  4. Pour la production, regroupez les dépendances au lieu de vous fier à de nombreuses requêtes de modules CDN.

Consultez la spécification associée

Exemples de composants du système de design système de design Nord

Exemple interactif autonome complet

Enregistrez le document complet sous le nom index.html et ouvrez-le dans un navigateur. Interprétation hors ligne HTML/CSS des jetons Nord Therapy ; l’intégration native aux Web Components est présentée séparément.

html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Nord room request interpretation</title><style>*{box-sizing:border-box}body{margin:0;background:#fafbfb;color:#0c1a3d;font:14px/1.5 system-ui,sans-serif}button,input{font:inherit}header{height:52px;background:white;border-bottom:1px solid #d8dee4;padding:0 24px;display:flex;align-items:center;justify-content:space-between}header small{color:#36434a}main{max-width:960px;margin:36px auto;padding:0 24px}h1{font-size:24px;line-height:1.2;margin:0 0 8px}h2{font-size:20px;line-height:1.2;margin:0 0 16px}p{margin:0 0 24px}.muted{color:#36434a}.layout{display:grid;grid-template-columns:310px 1fr;gap:24px}.panel{background:white;border:1px solid #d8dee4;border-radius:5px;padding:24px}fieldset{margin:0;padding:0;border:0;min-width:0}legend{font-weight:600;margin-bottom:16px}.room{display:flex;gap:12px;padding:12px;border:1px solid #d8dee4;border-radius:3px;margin-bottom:8px;cursor:pointer;align-items:center}.room:has(:checked){border-color:#3559c7;background:#f0f4ff}.room input{accent-color:#3559c7}.room span{flex:1}.room small{display:block;color:#36434a}.room b{font-size:12px;font-weight:500}.diagram{height:120px;background:#f6f8f8;display:grid;place-items:center;margin:-24px -24px 24px;border-radius:5px 5px 0 0;border-bottom:1px solid #d8dee4}.table{height:50px;border:2px solid #bcc5cc;border-radius:5px;background:#fff;position:relative;transition:width .2s ease}.chair{position:absolute;width:12px;height:10px;border:1px solid #bcc5cc;background:white;border-radius:3px;top:-16px}.chair.bottom{top:auto;bottom:-16px}label.field{display:block;font-weight:600;margin:16px 0 8px}#title{width:100%;border:1px solid #bcc5cc;border-radius:3px;height:36px;padding:7px 12px;color:inherit;background:white}#title[aria-invalid=true]{border-color:#d24023}.error{color:#d24023;min-height:20px;font-size:12px;margin:4px 0 12px}button{background:#3559c7;color:white;border:1px solid transparent;box-shadow:0 1px 3px #0c0c0c17;border-radius:3px;padding:7px 16px;cursor:pointer}button:focus-visible,input:focus-visible{outline:2px solid #3559c7;outline-offset:3px}.summary{margin-top:24px;background:#f0f4ff;border:1px solid #c6d4f9;padding:16px;border-radius:5px;overflow-wrap:anywhere}.summary:empty{display:none}.boundary{font-size:12px;color:#36434a;margin-top:24px}#selected{font-weight:600}.facts{display:flex;gap:24px;margin-bottom:24px}.facts strong{font-size:20px;display:block}.facts span{font-size:12px;color:#36434a}@media(max-width:650px){main{margin:24px auto;padding:0 16px}.layout{grid-template-columns:1fr;gap:16px}.panel{padding:16px}.diagram{margin:-16px -16px 16px}.room{padding:8px 12px}header{padding:0 16px}header small{display:none}}</style><header><strong>◈ Workplace</strong><small>Room request workspace</small></header><main><h1>A room for your next conversation</h1><p class="muted">Choose a room and prepare a request draft.</p><div class="layout"><section class="panel"><fieldset><legend>Choose a room</legend><div id="rooms"></div></fieldset></section><section class="panel"><div class="diagram" aria-hidden="true"><div class="table" id="table"></div></div><h2 id="selected">Birch</h2><div class="facts"><div><strong id="capacity">4</strong><span>Seats</span></div><div><strong>Draft</strong><span>Request status</span></div></div><form novalidate><label class="field" for="title">Request title</label><input id="title" type="text" aria-describedby="hint error" placeholder="e.g. Design review"><div id="error" class="error" role="alert"></div><p id="hint" class="muted">Use a non-sensitive meeting title. Availability is not checked in this example.</p><button type="submit">Prepare request</button></form><div class="summary" id="result" role="status"></div></section></div><p class="boundary">Independent HTML interpretation of Nord Therapy tokens. Nord is intended for Nordhealth products. This example creates a local draft only; it does not reserve a room.</p></main><script>const rooms=[['Birch',4],['Cedar',6],['Elm',8],['Maple',10],['Pine',12]],field=document.querySelector('#title'),result=document.querySelector('#result');let selected=0;document.querySelector('#rooms').innerHTML=rooms.map(([name,n],i)=>`<label class="room"><input type="radio" name="room" value="${i}" ${i===0?'checked':''}><span>${name}<small>Meeting room</small></span><b>${n} seats</b></label>`).join('');function update(){let [name,n]=rooms[selected];document.querySelector('#selected').textContent=name;document.querySelector('#capacity').textContent=n;let table=document.querySelector('#table');table.style.width=(n*12+44)+'px';table.innerHTML=Array.from({length:n},(_,i)=>`<i class="chair ${i>=n/2?'bottom':''}" style="left:${12+(i%(n/2))*24}px"></i>`).join('');result.textContent=''}document.querySelectorAll('[name=room]').forEach(input=>input.onchange=()=>{selected=Number(input.value);update()});document.querySelector('form').onsubmit=e=>{e.preventDefault();if(!field.value.trim()){document.querySelector('#error').textContent='Enter a request title.';field.setAttribute('aria-invalid','true');field.focus();return}result.textContent='Draft prepared: '+field.value.trim()+' · '+rooms[selected][0]+' · '+rooms[selected][1]+' seats. No room is reserved.'};field.oninput=()=>{field.removeAttribute('aria-invalid');document.querySelector('#error').textContent='';result.textContent=''};update();</script></html>

Référence du code

  • Cet exemple présente les salles sous forme de boutons radio ; l’exemple natif Nord utilise Select avec des éléments option classiques. Aucun des deux ne réserve réellement de salle.

Une demande de salle avec libellé et validation explicite

Les éléments nord-input et nord-select autonomes fournissent des libellés sans la famille Field facultative. À la soumission, les valeurs des composants sont lues et la propriété d’erreur du champ de saisie est définie.

html
<!doctype html>
<html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Room request draft</title>
<link rel="stylesheet" href="https://nordcdn.net/ds/css/5.2.4/nord.min.css">
<script type="module" src="https://nordcdn.net/ds/components/5.3.0/index.js"></script>
<style>main{max-width:560px;margin:auto;padding:var(--n-space-l)}form{display:grid;gap:var(--n-space-l)}</style>
<main><h1>Prepare a room request</h1><p>For an authorized Nordhealth product. Local demonstration only.</p>
<form novalidate>
<nord-input id="request" name="request" label="Request title" hint="Use a non-sensitive meeting title." required expand></nord-input>
<nord-select id="room" name="room" label="Room" value="Birch" expand>
<option value="Birch">Birch · 4 seats</option><option value="Cedar">Cedar · 6 seats</option>
<option value="Elm">Elm · 8 seats</option><option value="Maple">Maple · 10 seats</option><option value="Pine">Pine · 12 seats</option>
</nord-select>
<nord-button type="submit" variant="primary">Prepare request</nord-button>
</form><p id="result" role="status"></p></main>
<script type="module">
await Promise.all(['nord-input','nord-select','nord-button'].map(name=>customElements.whenDefined(name)));
const form=document.querySelector('form'), title=document.querySelector('#request'),room=document.querySelector('#room'),result=document.querySelector('#result');
form.addEventListener('submit',event=>{
 event.preventDefault();title.error=title.value.trim()?'':'Enter a request title.';
 if(title.error){title.focus();return;}
 result.textContent=`Draft: ${title.value.trim()} in ${room.value}. No room is reserved.`;
});
form.addEventListener('input',()=>{result.textContent='';title.error='';});
form.addEventListener('change',()=>{result.textContent='';});
</script></html>

Référence du code

  • Avec cinq salles, Select constitue un choix compact pertinent.
  • Par défaut, Button a le type submit ; cet exemple précise explicitement ce type.
  • Les éléments personnalisés sont attendus avant l’utilisation de leurs méthodes. Aucun service de réservation n’est appelé.
04

Configuration de l’agent système de design Nord

Point de départ de l’implémentation

Prototype complet utilisant un CDN public pour un usage autorisé de Nordhealth. La documentation indique actuellement la version CSS 5.2.4 et la version 5.3.0 des composants. En production, créez un bundle avec les packages npm ; l’interprétation visuelle hors ligne ci-dessous ne charge pas ces packages distants.

html
<!doctype html>
<html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
<title>Room request draft</title>
<link rel="stylesheet" href="https://nordcdn.net/ds/css/5.2.4/nord.min.css">
<script type="module" src="https://nordcdn.net/ds/components/5.3.0/index.js"></script>
<style>main{max-width:560px;margin:auto;padding:var(--n-space-l)}form{display:grid;gap:var(--n-space-l)}</style>
<main><h1>Prepare a room request</h1><p>For an authorized Nordhealth product. Local demonstration only.</p>
<form novalidate>
<nord-input id="request" name="request" label="Request title" hint="Use a non-sensitive meeting title." required expand></nord-input>
<nord-select id="room" name="room" label="Room" value="Birch" expand>
<option value="Birch">Birch · 4 seats</option><option value="Cedar">Cedar · 6 seats</option>
<option value="Elm">Elm · 8 seats</option><option value="Maple">Maple · 10 seats</option><option value="Pine">Pine · 12 seats</option>
</nord-select>
<nord-button type="submit" variant="primary">Prepare request</nord-button>
</form><p id="result" role="status"></p></main>
<script type="module">
await Promise.all(['nord-input','nord-select','nord-button'].map(name=>customElements.whenDefined(name)));
const form=document.querySelector('form'), title=document.querySelector('#request'),room=document.querySelector('#room'),result=document.querySelector('#result');
form.addEventListener('submit',event=>{
 event.preventDefault();title.error=title.value.trim()?'':'Enter a request title.';
 if(title.error){title.focus();return;}
 result.textContent=`Draft: ${title.value.trim()} in ${room.value}. No room is reserved.`;
});
form.addEventListener('input',()=>{result.textContent='';title.error='';});
form.addEventListener('change',()=>{result.textContent='';});
</script></html>

Un prompt pour votre projet

Prompt pour l’agent IA
Utilisez les rôles sémantiques de Nord Therapy avec des contrôles munis de libellés. Intégrez les champs à une mise en page d’application adaptative. Validez le titre de la demande après suppression des espaces superflus, conservez une seule salle sélectionnée et affichez uniquement le résultat d’un brouillon local. Pour une véritable implémentation Nordhealth, respectez les autorisations documentées concernant les packages et les thèmes.
05

Système de design Nord Sources et périmètre

Référence OpenDesign indépendante. Nord indique que son usage prévu concerne les produits Nordhealth. Cette interprétation originale HTML ne réserve pas de salle et ne confère aucun droit d’utilisation de la marque ou des composants.