Crea un selector de secciones de informes con el componente Transfer controlado de Arco. Explora sus escalas reales de espaciado y tamaño, las convenciones de variables de CSS, las superficies semánticas y la diferencia entre seleccionar filas y moverlas.
Interpretación independiente HTML del comportamiento de Transfer de Arco y de los puntos de anclaje del tema verificados; el ejemplo nativo de React se proporciona por separado. · Referencia de implementación
02
Referencia de diseño del sistema de diseño de Arco Design
Fuente original de Arco React. Las constantes Less se muestran con @; las variables CSS en tiempo de ejecución usan --. El espaciado de la vista previa y la disposición de los paneles son decisiones originales de la aplicación, basadas en esas escalas.
Transfer del sistema de diseño de Arco Design representa la pertenencia, no solo una lista de casillas
Elige con criterio las secciones del informe
Arco Transfer es útil cuando un operador debe comparar dos conjuntos: las secciones disponibles y las incluidas en un informe. Marcar una fila la selecciona para una operación posterior; no mueve la sección de inmediato, salvo que esté activado el modo simple.
El ejemplo mantiene explícita la acción en dos pasos. El usuario selecciona «Canales de adquisición», activa «Incluir» y luego prepara un esquema. Ese esquema es una instantánea independiente, por lo que los cambios posteriores en el editor no modifican silenciosamente la versión preparada.
Sistema de diseño Arco Design: usa por separado la escala de tamaños y la de espaciado
Un mismo número puede representar dimensiones distintas
Las constantes de tamaño de Arco aumentan en incrementos de cuatro píxeles, mientras que la escala de espaciado empieza con 2, 4, 6, 8, 10 y 12 antes de dar saltos mayores. El tamaño predeterminado del componente corresponde a 32px. Suponer que todos los sufijos de tamaño o espaciado representan la misma cantidad produciría controles inconsistentes.
Los dos paneles de transferencia usan esquinas de radio medio y un margen de página de 24px en esta composición original. Las casillas pequeñas y los separadores de filas facilitan la selección de muchos elementos; las áreas más amplias de la página aportan separación sin sustituir el contenido útil por tarjetas demasiado grandes.
Sistema de diseño Arco Design: conserva los roles semánticos en los estilos de la aplicación
Las variables CSS tienen su propia convención de nombres
El tema predeterminado exporta variables como --color-text-1 y --color-fill-2, sin el prefijo arco. Las compilaciones personalizadas pueden cambiar ese prefijo, así que revisa el tema compilado al integrarlo en una aplicación con espacio de nombres propio. Las variables de la paleta principal contienen canales RGB; para usarlas se necesita rgb(var(--primary-6)), en lugar de tratarlas como si fueran un color hexadecimal completo.
La vista previa usa el tono azul de Arco verificado como referencia para la acción principal y las filas seleccionadas. En una sección restringida, se muestra una casilla deshabilitada y un texto explicativo, en vez de un color rojo que podría sugerir que el operador puede corregir un error.
Sistema de diseño Arco Design: admite etiquetas compactas y nombres de sección largos
Una escala práctica para el texto del cuerpo
El tamaño de texto predeterminado para el cuerpo es de 14px, con un multiplicador de interlineado de 1.5715. La familia tipográfica publicada empieza con Inter e incluye alternativas del sistema y para CJK. Se trata de una pila tipográfica CSS, no de una prueba de que se haya cargado un archivo de fuente Inter.
La etiqueta de una sección del informe puede ser más larga que la de ejemplo. La versión sin conexión ajusta el texto de las filas y apila los paneles en una ventana pequeña para que las etiquetas «Incluir» y «Quitar» sigan siendo legibles. No reduce todo el componente de transferencia hasta volver ilegible el texto.
Sistema de diseño Arco Design: dos matrices controladas evitan comportamientos ambiguos
La pertenencia y la selección tienen significados distintos
targetKeys indica qué elementos están en el informe. selectedKeys indica qué casillas están activas en ese momento en ambas listas. onSelectChange proporciona matrices para la izquierda y la derecha; concaténalas para controlar selectedKeys. onChange proporciona la nueva pertenencia, la dirección y las claves movidas.
Mantén estable la clave de cada elemento de origen, aunque cambie su etiqueta visible.
Combina las matrices de selección izquierda y derecha en onSelectChange.
Sustituye targetKeys por la nueva matriz de onChange.
Borra la selección temporal después de mover elementos e informa de su efecto inmediato.
Sistema de diseño Arco Design: la búsqueda debe acotar la vista sin eliminar elementos
Especifica claramente la regla de coincidencia
El filtro predeterminado de origen compara la consulta con el valor del elemento mediante una búsqueda de subcadena que distingue entre mayúsculas y minúsculas. El ejemplo proporcionado cambia ese comportamiento para que la búsqueda no distinga entre mayúsculas y minúsculas. Buscar una fila seleccionada que esté oculta no debe dar a entender que se ha eliminado de la lista de elementos del informe.
En esta lista pequeña, la paginación y la virtualización aportan poco. Arco ofrece esas opciones para conjuntos de datos mayores, pero la aplicación sigue siendo responsable de las claves estables, el conjunto completo de destinos y las reglas de selección en las vistas filtradas.
Las listas de elementos disponibles e incluidos tienen campos de búsqueda con etiquetas distintas.
El mensaje de que no hay coincidencias describe la vista filtrada, no un conjunto de datos vacío.
Para preparar un esquema se usa targetKeys, no solo las filas visibles en ese momento.
Sistema de diseño Arco Design: el modo oscuro cambia las superficies y el texto
Configura el selector publicado
Arco publica sus estilos para el modo oscuro bajo la etiqueta del tema con arco-theme="dark". En la compilación predeterminada, la etiqueta es body. Al quitar ese atributo se restablecen las reglas normales; añadir una clase no relacionada llamada dark no es lo mismo API.
Si añades una vista previa en modo oscuro, ajusta conjuntamente los roles del contenedor y del texto. El ejemplo sin conexión permanece intencionalmente en modo claro, mientras que el ejemplo nativo puede usar el tema CSS ya importado. No inviertas las miniaturas ni las ilustraciones de los informes aplicándoles un filtro general.
Sistema de diseño Arco Design: paquete, hoja de estilos y alcance real
Un esquema de informe no exporta los datos del informe
El paquete React es @arco-design/web-react y su entrada completa CSS es dist/css/arco.css. El ejemplo importa Transfer y Button desde la raíz del paquete y usa estado controlado, en lugar de inventar una API de creación de informes API.
La vista previa independiente reproduce el comportamiento de selección con casillas y botones nativos para funcionar sin conexión. Permite validar la lógica de interacción y la composición adaptable; no demuestra que el paquete nativo se haya compilado en un proyecto consumidor. Un exportador de producción necesitaría un backend y comprobaciones de permisos que van más allá de una fila de ejemplo deshabilitada.
Arco Design Ejemplos de componentes del Sistema de diseño
Muestra interactiva independiente completa
Guarda el documento completo como index.html y ábrelo en un navegador. Interpretación independiente HTML del comportamiento de Arco Transfer y de los colores de referencia del tema verificados; el ejemplo nativo React se proporciona por separado.
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 sección restringida del informe no se puede mover. Las filas seleccionadas y las secciones incluidas son estados distintos, de acuerdo con la diferencia explicada para Transfer nativo.
Transferencia controlada de secciones del informe
Transfer gestiona la pertenencia a los conjuntos de origen y destino, mientras que el estado de la aplicación almacena un esquema preparado por separado. Una fila restringida demuestra una opción deshabilitada sin pretender aplicar la autorización del servidor.
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 selección de casillas y la pertenencia al informe son matrices distintas.
El filtro personalizado no distingue entre mayúsculas y minúsculas.
Los datos de ejemplo son originales; no se cargan ni se exportan datos de análisis. La compilación nativa sigue siendo una comprobación de integración independiente.
04
Arco Design: configuración del agente para el sistema de diseño
Punto de partida para la implementación
Importa una vez la hoja de estilos completa arco.css y monta el ejemplo de React en un elemento raíz. No mezcles este paquete de React con las importaciones de Arco Vue.
Usa Arco React Transfer con claves estables en dataSource y controla por separado targetKeys y selectedKeys. Proporciona un filtro que no distinga entre mayúsculas y minúsculas, acciones explícitas de inclusión y eliminación, y una instantánea preparada del esquema. Conserva la sintaxis de variables de Arco CSS y describe con honestidad la interpretación sin conexión.
05
Fuentes y alcance del sistema de diseño Arco Design
Referencia independiente de OpenDesign. Datos originales del informe y vista previa solo local; las filas deshabilitadas no constituyen un límite de autorización.