Créez un sélecteur de sections de rapport avec le composant Transfer contrôlé d’Arco. Découvrez ses véritables échelles d’espacement et de taille, ses conventions de variables CSS, ses surfaces sémantiques et la différence entre sélectionner des lignes et les déplacer.
Interprétation autonome du comportement de Transfer HTML et des points d’ancrage du thème vérifiés ; exemple natif React fourni séparément. · Référence de mise en œuvre
02
Système de design Arco Design — référence de conception
Source amont d’Arco React. Les constantes Less sont préfixées par @ ; les variables CSS à l’exécution utilisent --. Les espacements de l’aperçu et la disposition des panneaux sont des choix originaux pour l’application, fondés sur ces échelles.
Arco Design Dans le système de design, Transfer représente l’appartenance, pas simplement une liste de cases à cocher
Choisissez soigneusement les sections du rapport
Arco Transfer est utile lorsqu’un opérateur doit comparer deux ensembles : les sections disponibles et celles incluses dans un rapport. Cocher une ligne la marque pour une opération ultérieure ; la section n’est pas déplacée immédiatement, sauf si le mode simple est activé.
L’exemple conserve l’action explicite en deux étapes. L’utilisateur sélectionne « Canaux d’acquisition », active « Inclure », puis prépare un plan. Ce plan constitue un instantané distinct : les modifications ultérieures dans l’éditeur ne modifient pas silencieusement la version préparée.
Arco Design Dans le système de design, utilisez séparément les échelles de tailles et d’espacements
Une même valeur peut désigner des dimensions différentes
Les constantes de taille d’Arco augmentent par incréments de quatre pixels, tandis que l’échelle d’espacement commence par 2, 4, 6, 8, 10 et 12, avant de passer à des incréments plus grands. La taille par défaut du composant correspond à 32 px. Supposer que chaque suffixe de taille ou d’espacement désigne la même valeur entraînerait des contrôles incohérents.
Dans cette composition d’origine, les deux panneaux de transfert ont des coins moyennement arrondis et la marge de page est de 24 px. Les petites cases à cocher et les séparateurs de ligne facilitent les sélections denses ; les grandes zones de la page assurent une séparation sans remplacer le contenu utile par des cartes surdimensionnées.
Système de design Arco Design Conservez les rôles sémantiques dans le style de l’application
Les variables CSS ont leurs propres conventions de nommage
Le thème par défaut expose des variables telles que --color-text-1 et --color-fill-2, sans préfixe arco. Les compilations personnalisées peuvent modifier ce préfixe ; vérifiez donc le thème compilé lors de son intégration dans une application utilisant son propre espace de noms. Les variables de la palette principale contiennent des canaux RVB : il faut utiliser rgb(var(--primary-6)) plutôt que de les traiter comme une couleur hexadécimale complète.
L’aperçu utilise le repère bleu Arco vérifié pour l’action principale et les lignes sélectionnées. Pour une section restreinte, une case à cocher désactivée et un texte explicatif sont préférables à une couleur rouge, qui pourrait laisser croire à une erreur que l’opérateur peut corriger.
Système de design Arco Design Prévoyez les libellés denses et les noms de section longs
Une échelle pratique pour le texte courant
La taille par défaut du texte courant est de 14 px, avec un interligne de 1.5715. La famille publiée commence par Inter et comprend des polices de remplacement système et CJK. Il s’agit d’une pile CSS, et non de la preuve qu’un fichier de police Inter a été chargé.
Le libellé d’une section de rapport peut être plus long que l’exemple. La version hors ligne répartit le texte des lignes sur plusieurs lignes et empile les panneaux sur les petits écrans, afin que les libellés « Inclure » et « Retirer » restent lisibles. Elle ne réduit pas l’ensemble du composant de transfert au point de rendre le texte illisible.
Système de design Arco Design Deux tableaux contrôlés évitent les comportements ambigus
L’appartenance et la sélection ont des sens différents
targetKeys indique quels éléments figurent dans le rapport. selectedKeys indique quelles cases à cocher sont actuellement activées dans les deux listes. onSelectChange fournit les tableaux de gauche et de droite ; concaténez-les pour contrôler selectedKeys. onChange fournit la nouvelle appartenance, la direction et les clés déplacées.
Conservez une clé stable pour chaque élément source, même si son libellé change.
Combinez les tableaux de sélection de gauche et de droite dans onSelectChange.
Remplacez targetKeys par le nouveau tableau fourni par onChange.
Effacez la sélection temporaire après un déplacement et indiquez son effet local.
Système de design Arco Design La recherche doit filtrer l’affichage sans modifier l’appartenance
Précisez la règle de correspondance
Par défaut, le filtre source compare la requête à la valeur de l’élément au moyen d’une recherche partielle sensible à la casse. L’exemple fourni remplace ce comportement par une recherche sans distinction de casse. La recherche d’une ligne sélectionnée masquée ne doit pas laisser croire qu’elle a été retirée du rapport.
Pour cette petite liste, la pagination et la virtualisation apportent peu. Arco propose ces options pour les grands volumes de données, mais l’application reste responsable des clés stables, de l’ensemble complet des éléments cibles et des règles de sélection dans les vues filtrées.
Les listes des éléments disponibles et inclus disposent chacune de leur propre champ de recherche.
Le message indiquant qu’aucun résultat ne correspond décrit la vue filtrée, pas un jeu de données vide.
La préparation d’un plan utilise targetKeys, et non les seules lignes actuellement visibles.
Système de design Arco Design Le mode sombre modifie les surfaces autant que le texte
Définissez le sélecteur publié
Arco publie ses règles de remplacement pour le mode sombre sous la balise du thème, avec arco-theme="dark". Dans la compilation par défaut, cette balise est body. Supprimer cet attribut rétablit les règles normales ; ajouter une classe sans rapport appelée dark ne revient pas au même API.
Pour ajouter un aperçu sombre, adaptez ensemble le conteneur et les rôles du texte. L’exemple hors ligne reste volontairement clair, tandis que l’exemple natif peut utiliser le thème CSS déjà importé. N’inversez pas les vignettes de rapport ni les illustrations au moyen d’un filtre global.
Système de design Arco Design Package, feuille de style et limites réelles
Un plan de rapport n’exporte pas les données du rapport
Le package React est @arco-design/web-react et sa feuille de style complète CSS est dist/css/arco.css. L’exemple importe Transfer et Button depuis la racine du package et utilise un état contrôlé, plutôt que d’inventer une API de création de rapports.
L’aperçu autonome interprète le comportement de sélection à l’aide de cases à cocher et de boutons natifs, afin de fonctionner hors ligne. Il valide la logique d’interaction et la composition adaptative ; il ne prouve pas que le package natif a été compilé dans un projet utilisateur. Un exportateur destiné à la production nécessiterait un backend et des vérifications des autorisations allant au-delà d’une ligne d’exemple désactivée.
Arco Design Exemples de composants du système de design
Exemple interactif autonome complet
Enregistrez le document complet sous le nom index.html, puis ouvrez-le dans un navigateur. Interprétation autonome HTML du comportement d’Arco Transfer et repères de thème vérifiés ; exemple natif React fourni séparément.
html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Arco report section transfer</title><style>
*{box-sizing:border-box}body{margin:0;color:#1d2129;background:#f7f8fa;font:14px/22px Arial,sans-serif}header{padding:20px 28px;background:white;border-bottom:1px solid #e5e6eb;display:flex;justify-content:space-between}.logo{font-size:18px;font-weight:bold;letter-spacing:-.02em}.logo i{font-style:normal;color:#165dff;margin-right:8px}header small{color:#4e5969}main{max-width:1050px;padding:28px;margin:auto}h1{font-size:24px;line-height:32px;margin:0 0 8px}.lead{color:#4e5969;margin:0 0 24px}.transfer{display:grid;grid-template-columns:minmax(0,1fr) 106px minmax(0,1fr);align-items:stretch}.list{border:1px solid #e5e6eb;background:white;border-radius:4px;min-width:0}.head{padding:16px;background:#f2f3f5;display:flex;gap:8px;justify-content:space-between}.head h2{font-size:14px;margin:0}.count{font-size:12px;color:#4e5969}.search{padding:12px;border-bottom:1px solid #e5e6eb}.search label{font-size:12px;display:block;margin-bottom:4px;color:#4e5969}.search input{height:32px;width:100%;border:1px solid transparent;background:#f2f3f5;padding:4px 12px;font:inherit;border-radius:2px}input:focus,button:focus-visible{outline:2px solid #165dff;outline-offset:2px}.items{min-height:290px;padding:8px}.item{display:flex;gap:10px;padding:12px 8px;border-radius:2px;align-items:start;cursor:pointer}.item:has(input:checked){background:#e8f3ff}.item input{width:16px;height:16px;accent-color:#165dff;margin-top:3px;flex-shrink:0}.item small{display:block;color:#4e5969;font-size:12px}.item:has(input:disabled){color:#86909c;cursor:not-allowed}.ops{padding:16px 12px;display:flex;flex-direction:column;gap:12px;justify-content:center}button{font:14px/22px Arial;border:1px solid #e5e6eb;background:white;color:#1d2129;border-radius:2px;padding:5px 12px;cursor:pointer}.ops button{padding:5px 4px}.primary{background:#165dff;border-color:#165dff;color:#fff}button:disabled{background:#f2f3f5;color:#86909c;border-color:#e5e6eb;cursor:not-allowed}.footer{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:20px 0}.footer p{font-size:12px;color:#4e5969;margin:0}.outline{background:white;border:1px solid #e5e6eb;border-radius:4px;padding:24px}.outline h2{font-size:16px;margin:0 0 12px}.outline ol{margin:0;padding-left:20px}.note{color:#4e5969;font-size:12px;margin-top:20px}.empty{padding:20px 8px;color:#4e5969}.selection{font-size:12px;color:#4e5969;padding:10px 16px;border-top:1px solid #e5e6eb}@media(max-width:650px){main{padding:24px 16px}.transfer{grid-template-columns:1fr}.ops{flex-direction:row;padding:12px}.ops button{padding:6px 16px}.items{min-height:160px}.footer{align-items:start;flex-direction:column}header{padding:16px}}
</style><header><span class="logo"><i>A /</i> Analytics workspace</span><small>Report studio</small></header><main><h1>Choose report sections</h1><p class="lead">Build an outline from the sections available to this workspace.</p><div class="transfer"><section class="list"><div class="head"><h2>Available sections</h2><span id="left-count" class="count"></span></div><div class="search"><label for="left-search">Find available section</label><input id="left-search" type="search" placeholder="Search by section name"></div><div class="items" id="left"></div><div class="selection" id="left-selected"></div></section><div class="ops"><button class="primary" id="include" disabled>Include →</button><button id="remove" disabled>← Remove</button></div><section class="list"><div class="head"><h2>Included in report</h2><span id="right-count" class="count"></span></div><div class="search"><label for="right-search">Find included section</label><input id="right-search" type="search" placeholder="Search included sections"></div><div class="items" id="right"></div><div class="selection" id="right-selected"></div></section></div><div class="footer"><p id="status" role="status">Select a section, then choose Include or Remove.</p><button id="prepare" class="primary">Prepare outline</button></div><section class="outline"><h2>Prepared outline</h2><div id="snapshot">No outline prepared yet.</div></section><p class="note">HTML interpretation of Arco Transfer · Original sample sections · Local outline only, no analytics data exported</p></main><script>
const data=[{key:'overview',value:'Executive overview',detail:'A concise summary of the reporting period'},{key:'traffic',value:'Acquisition channels',detail:'How people arrive at your product'},{key:'retention',value:'Retention cohorts',detail:'Returning usage by cohort'},{key:'revenue',value:'Revenue breakdown',detail:'Revenue categories and trends'},{key:'raw',value:'Raw event export',detail:'Restricted · unavailable in this specimen',disabled:true}];const $=id=>document.getElementById(id);let target=new Set(['overview']),selected=new Set();
function render(){for(const side of ['left','right']){const items=data.filter(x=>target.has(x.key)===(side==='right')),query=$(side+'-search').value.toLowerCase(),host=$(side);host.replaceChildren();$(side+'-count').textContent=items.length+' sections';const visible=items.filter(x=>x.value.toLowerCase().includes(query));if(!visible.length){const p=document.createElement('p');p.className='empty';p.textContent=query?'No matching sections.':'No sections in this column.';host.append(p)}for(const item of visible){const label=document.createElement('label');label.className='item';const input=document.createElement('input');input.type='checkbox';input.id='check-'+item.key;input.checked=selected.has(item.key);input.disabled=!!item.disabled;input.setAttribute('aria-label',item.value);input.onchange=()=>{input.checked?selected.add(item.key):selected.delete(item.key);render();$('check-'+item.key)?.focus()};const text=document.createElement('span'),small=document.createElement('small');text.textContent=item.value;small.textContent=item.detail;text.append(small);label.append(input,text);host.append(label)}$(side+'-selected').textContent=items.filter(x=>selected.has(x.key)).length+' selected'}$('include').disabled=!data.some(x=>selected.has(x.key)&&!target.has(x.key)&&!x.disabled);$('remove').disabled=!data.some(x=>selected.has(x.key)&&target.has(x.key)&&!x.disabled);$('prepare').disabled=!target.size}
function move(toTarget){const moved=data.filter(x=>selected.has(x.key)&&target.has(x.key)!==toTarget&&!x.disabled);for(const item of moved)toTarget?target.add(item.key):target.delete(item.key);selected.clear();render();$('status').textContent=moved.length+' section(s) '+(toTarget?'included in':'removed from')+' the local draft.';$(toTarget?'right-search':'left-search').focus()}
$('include').onclick=()=>move(true);$('remove').onclick=()=>move(false);for(const side of ['left','right'])$(side+'-search').oninput=render;$('prepare').onclick=()=>{const ol=document.createElement('ol');for(const item of data.filter(x=>target.has(x.key))){const li=document.createElement('li');li.textContent=item.value;ol.append(li)}$('snapshot').replaceChildren(ol);$('status').textContent='Local report outline prepared. No data exported.'};render();
</script></html>
La section restreinte du rapport ne peut pas être déplacée. Les lignes sélectionnées et les sections incluses correspondent à des états distincts, conformément à la distinction expliquée pour Transfer natif.
Transfert contrôlé des sections du rapport
Transfer gère les éléments présents dans les listes source et cible, tandis que l’état de l’application stocke un plan préparé séparément. Une ligne restreinte illustre une option désactivée sans prétendre imposer une autorisation côté serveur.
jsx
// npm install @arco-design/web-react react react-dom
import React,{useState} from 'react';
import {createRoot} from 'react-dom/client';
import {Transfer,Button} from '@arco-design/web-react';
import '@arco-design/web-react/dist/css/arco.css';
const data = [
{key:'overview',value:'Executive overview'},
{key:'traffic',value:'Acquisition channels'},
{key:'retention',value:'Retention cohorts'},
{key:'revenue',value:'Revenue breakdown'},
{key:'raw',value:'Raw event export (restricted)',disabled:true}
];
function ReportBuilder(){
const [target,setTarget]=useState(['overview']);
const [selected,setSelected]=useState([]);
const [snapshot,setSnapshot]=useState([]);
const [status,setStatus]=useState('Choose sections for a local report.');
return <main style={{padding:24,maxWidth:960,margin:'auto'}}>
<h1>Report sections</h1>
<Transfer dataSource={data} targetKeys={target} selectedKeys={selected}
titleTexts={['Available sections','Included in report']}
operationTexts={['Include','Remove']}
showSearch searchPlaceholder={['Find available section','Find included section']}
filterOption={(query,item)=>item.value.toLowerCase().includes(query.toLowerCase())}
onSelectChange={(left,right)=>setSelected([...left,...right])}
onChange={(keys,direction,moved)=>{
setTarget(keys);setSelected([]);
setStatus(`${moved.length} section(s) moved to ${direction}. Draft only.`);
}} />
<p role="status">{status}</p>
<Button type="primary" disabled={!target.length} onClick={()=>{
setSnapshot([...target]);setStatus('Local report outline prepared. No data exported.');
}}>Prepare outline</Button>
<h2>Prepared outline</h2>
{snapshot.length ? <ol>{snapshot.map(key=><li key={key}>{data.find(item=>item.key===key).value}</li>)}</ol> : <p>No outline prepared yet.</p>}
</main>;
}
createRoot(document.getElementById('root')).render(<ReportBuilder />);
La sélection des cases à cocher et l’appartenance au rapport sont gérées dans des tableaux distincts.
Le filtre personnalisé ne tient pas compte de la casse.
Les données d’exemple sont originales ; aucune donnée analytique n’est chargée ni exportée. La compilation native reste une vérification d’intégration distincte.
04
Arco Design Configuration de l’agent du système de design
Point de départ de l’implémentation
Importez une seule fois la feuille de style complète arco.css et montez l’exemple React dans un élément racine. Ne mélangez pas ce package React avec les imports d’Arco Vue.
Utilisez Arco React Transfer avec des clés stables dans dataSource, ainsi que targetKeys et selectedKeys contrôlés séparément. Fournissez un filtre insensible à la casse, des actions explicites Inclure/Retirer et un instantané du plan préparé. Respectez la syntaxe des variables CSS d’Arco et indiquez clairement qu’il s’agit d’une interprétation hors ligne.
05
Arco Design Sources et périmètre du système de design
Référence OpenDesign indépendante. Données de rapport originales et aperçu local uniquement ; les lignes désactivées ne constituent pas une limite d’autorisation.