Plataforma de datos · Nuevo recurso

Sistema de diseño de Segment Evergreen.

Una referencia de Evergreen con valores de tema reales, entrada controlada de etiquetas, coincidencia de reglas en tiempo real, una vía para recuperarse de un estado vacío y un diálogo de revisión nativo.

Guía de OpenDesign8 capítulos36 entradas de referenciaGuía de aplicación original
01

Vista previa de la interfaz del sistema de diseño de Segment Evergreen

Combina un plan y las etiquetas obligatorias, revisa los registros coincidentes, resuelve los casos sin coincidencias y consulta una instantánea local.

Crea y revisa una audiencia localAbrir ejemplo completo
Componentes nativos de Evergreen 7.1.9 para React y defaultTheme; reglas originales para audiencias locales. · Referencia de implementación
02

Referencia de diseño del sistema de diseño de Segment Evergreen

Componentes nativos de Evergreen 7.1.9 para React y defaultTheme; reglas originales para audiencias locales.

Radios de esquina

Fuente
Nombre / ReglaValor / ConfiguraciónUso
radii.00pxRadio indexado del tema; elige una función en lugar de redondear progresivamente cada cuadro anidado.
radii.14pxRadio indexado del tema; elige una función en lugar de redondear progresivamente cada cuadro anidado.
radii.28pxRadio indexado del tema; elige una función en lugar de redondear progresivamente cada cuadro anidado.

Tamaños de texto

Fuente
Nombre / ReglaValor / ConfiguraciónUso
fontSizes.010pxValores indexados de font-size en el tema predeterminado publicado.
fontSizes.112pxValores indexados de font-size en el tema predeterminado publicado.
fontSizes.214pxValores indexados de font-size en el tema predeterminado publicado.
fontSizes.316pxValores indexados de font-size en el tema predeterminado publicado.
fontSizes.418pxValores indexados de font-size en el tema predeterminado publicado.
fontSizes.520pxValores indexados de font-size en el tema predeterminado publicado.
fontSizes.624pxValores indexados de font-size en el tema predeterminado publicado.
fontSizes.732pxValores indexados de font-size en el tema predeterminado publicado.

Alturas de línea

Fuente
Nombre / ReglaValor / ConfiguraciónUso
lineHeights.016pxCombínalas con la función de texto prevista en lugar de aplicar a todos los párrafos el ritmo de los encabezados.
lineHeights.118pxCombínalas con la función de texto prevista en lugar de aplicar a todos los párrafos el ritmo de los encabezados.
lineHeights.220pxCombínalas con la función de texto prevista en lugar de aplicar a todos los párrafos el ritmo de los encabezados.
lineHeights.324pxCombínalas con la función de texto prevista en lugar de aplicar a todos los párrafos el ritmo de los encabezados.
lineHeights.428pxCombínalas con la función de texto prevista en lugar de aplicar a todos los párrafos el ritmo de los encabezados.
lineHeights.532pxCombínalas con la función de texto prevista en lugar de aplicar a todos los párrafos el ritmo de los encabezados.
lineHeights.640pxCombínalas con la función de texto prevista en lugar de aplicar a todos los párrafos el ritmo de los encabezados.

Pesos de fuente

Fuente
Nombre / ReglaValor / ConfiguraciónUso
fontWeights.light300En este tema, Evergreen asigna 500 a semibold y 600 a bold; no los sustituyas sin más por los valores predeterminados de las palabras clave del navegador.
fontWeights.normal400En este tema, Evergreen asigna 500 a semibold y 600 a bold; no los sustituyas sin más por los valores predeterminados de las palabras clave del navegador.
fontWeights.semibold500En este tema, Evergreen asigna 500 a semibold y 600 a bold; no los sustituyas sin más por los valores predeterminados de las palabras clave del navegador.
fontWeights.bold600En este tema, Evergreen asigna 500 a semibold y 600 a bold; no los sustituyas sin más por los valores predeterminados de las palabras clave del navegador.

Referencias de la paleta predeterminada

Fuente
Nombre / ReglaValor / ConfiguraciónUso
colors.gray900#101840 Texto oscuro principal.
colors.gray700#696f8c Texto complementario.
colors.gray400#d8dae5 Límite definido.
colors.gray200#edeff5 Separador sutil.
colors.gray100#F4F5F9 Fondo discreto.
colors.blue500#3366FF Referencia de azul principal.
colors.blue600#2952CC Referencia de interacción en azul más intenso.
colors.red500#D14343 Referencia de error crítico.
colors.green500#52BD95 Referencia de éxito.

Funciones de diseño y API para entradas controladas

Fuente
Nombre / ReglaValor / ConfiguraciónUso
majorScale(3)24pxEscala principal de ocho píxeles para el espaciado entre secciones.
minorScale(3)12pxEscala secundaria de cuatro píxeles para relaciones de menor tamaño.
TagInput.valuescontrolled arrayLa aplicación controla las etiquetas aceptadas.
TagInput.onChangenew array; return false to retain inputValida las nuevas etiquetas antes de aceptarlas.
TagInput.separatorcomma and new line by defaultPermite varias etiquetas sin un analizador personalizado.
03

Guía completa del sistema de diseño de Segment Evergreen

Una guía práctica para elegir, aplicar y revisar este sistema en una interfaz real.

DESIGN-segment-evergreen.md

Orientación completa, un punto de partida para la implementación y enlaces al código fuente.

Descargar la guía

Estructura del creador de audiencias del sistema de diseño de Segment Evergreen

Mantén las reglas junto a sus consecuencias

El ejemplo combina un panel de reglas con registros ficticios que coinciden. El selector de planes y las etiquetas obligatorias aparecen junto al recuento de resultados, de modo que el efecto de cambiar una regla es fácil de entender. El usuario no tiene que guardar ni abrir un cuadro de diálogo para descubrir si la combinación actual coincide con algún registro.

De esta guía de OpenDesign

Utiliza un conjunto de datos finito y transparente

Cinco registros de muestra identificados por nombre muestran su plan y sus etiquetas. La página no pretende consultar un almacén de datos de clientes ni estimar el tamaño de una audiencia real. Un resultado nulo es una parte útil del ejemplo e incluye una acción para restaurar el conjunto completo de datos.

Valores y semántica del tema del sistema de diseño de Segment Evergreen

Consulta el tema predeterminado real

Evergreen 7.1.9 proporciona radios, tamaños de fuente y alturas de línea indexados, además de colores con nombre y estilos de componentes. La tabla conserva intactos esos valores exportados. Conviene prestar especial atención a los nombres de los pesos de fuente: semibold y bold corresponden a 500 y 600, respectivamente, valores distintos de los que se suelen presuponer.

Mantén la composición personalizada en consonancia

ThemeProvider proporciona las entradas, etiquetas, insignias, botones y el cuadro de diálogo nativos. Los paneles creados para el ejemplo usan la misma combinación sobria de grises fríos y azul. El ejemplo no sobrescribe los estilos internos de los componentes nativos con selectores generales de CSS, por lo que se conservan los estilos de interacción proporcionados.

Tipografía del sistema de diseño de Segment Evergreen para editar reglas

Establece una jerarquía clara para la tarea

Las funciones de encabezado distinguen el título de la audiencia de los títulos de los paneles y de los nombres de cada resultado. El texto complementario explica cómo introducir etiquetas y aclara que los datos son ficticios. La insignia con el recuento aparece junto al encabezado de resultados, en lugar de sustituirlo, para que el usuario pueda identificar la sección antes de interpretar el número.

Mantén legibles los metadatos

La información sobre planes y etiquetas ayuda a explicar las coincidencias y no es meramente decorativa. El diseño permite que las etiquetas ocupen varias líneas y apila el texto y las insignias de cada registro en pantallas de teléfono estrechas. Reducir todas las etiquetas a un tamaño diminuto ocultaría las pruebas que el usuario necesita para entender las reglas.

Escalas principal y secundaria del sistema de diseño de Segment Evergreen

Usa funciones para repetir el espaciado

majorScale y minorScale representan incrementos de ocho y cuatro píxeles. En el ejemplo de componente se usa majorScale(3) para separar 24px el encabezado del panel, mientras que la hoja de estilos personalizada se ocupa de la composición adaptable. Mantén clara esta distinción: un punto de ruptura de cuadrícula es una decisión de la aplicación, no el resultado de una función de espaciado.

Mantén las relaciones entre campos en móviles

Etiquetas controladas y coincidencias en el sistema de diseño Segment Evergreen

Normaliza los valores antes de aceptarlos

El controlador onChange recorta los espacios y convierte las cadenas a minúsculas, elimina duplicados y rechaza más de cuatro etiquetas distintas. Al devolver false, el campo conserva el valor cuando se rechaza una etiqueta. Esta política corresponde a la aplicación de audiencias; TagInput proporciona la interacción controlada, pero no elige un límite de negocio.

Aplica deliberadamente la coincidencia con todas las etiquetas

Un registro debe coincidir con el plan seleccionado y con todas las etiquetas requeridas. Al borrar las etiquetas, se elimina esa restricción; al elegir Cualquiera, se elimina la restricción del plan. El recuento actual de resultados se obtiene de la misma lista filtrada que se muestra en pantalla, para evitar que el recuento no coincida con las tarjetas visibles.

Diálogo de revisión y vista local del sistema de diseño Segment Evergreen

Revisa las reglas actuales antes de guardar

Se requiere un nombre de audiencia no vacío para abrir el diálogo. El diálogo vuelve a mostrar el nombre, el recuento, el plan y las etiquetas, y luego ofrece la opción Guardar localmente. Este paso adicional muestra una superposición nativa en torno a una vista concreta, en lugar de una confirmación vacía que solo diga «¿Seguro que quieres continuar?».

Invalida el éxito anterior cuando cambian las reglas

Si cambia el nombre, el plan o las etiquetas, se borra el indicador de vista guardada. Así, un éxito local anterior no puede confundirse con la confirmación de reglas recién editadas. La aplicación nunca describe la vista como una audiencia de Segment ni envía solicitudes a una plataforma de clientes.

Entrada por teclado y recuperación del diálogo en el sistema de diseño Segment Evergreen

Prueba las etiquetas, los resultados y la revisión como un solo flujo

Es posible añadir etiquetas con las teclas de entrada documentadas, y el campo recibe una etiqueta visible mediante su id. Si se rechaza una etiqueta por superar el límite, se muestra una alerta de peligro nativa. La revisión usa el comportamiento nativo del foco de Dialog, en lugar de una superposición creada manualmente con el foco sin gestionar.

  1. Añade newsletter a la etiqueta activa inicial y compara el recuento.
  2. Añade una etiqueta que no coincida y luego borra las reglas para volver a mostrar cinco registros.
  3. Revisa y guarda localmente; luego cambia una regla y comprueba que desaparezca el éxito anterior.

Mantén la recuperación del estado vacío dentro de la tarea actual

Al borrar las reglas, se eliminan las restricciones de plan y etiquetas, y se descarta el estado guardado obsoleto. La región de resultados vuelve a incluir los cinco registros. El usuario puede seguir editando de inmediato; no se requiere navegación oculta ni recargar la página.

Integración de Segment Evergreen con el sistema de diseño React

Usa un ejemplo controlado completo

La implementación nativa importa ThemeProvider, defaultTheme y los componentes que representa. El estado contiene las reglas, los errores, la visibilidad del diálogo y la vista guardada local. El JSX completo y CSS que aparecen a continuación incluyen los datos ficticios, de modo que el cálculo de resultados puede reproducirse sin un API externo.

  • ThemeProvider utiliza defaultTheme fijado.
  • La aplicación controla los valores de TagInput.
  • Dialog revisa las mismas reglas que se usan en la lista de resultados.

Añade el acceso a datos como una capa independiente de la aplicación

Ejemplos de componentes del sistema de diseño Segment Evergreen

main.jsx — ejemplo completo y funcional

Crea y revisa una audiencia local. El código fuente a continuación es la implementación completa de React, con todo el estado y la validación incluidos.

jsx
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import {
  ThemeProvider,
  defaultTheme,
  Heading,
  Text,
  Paragraph,
  Button,
  TagInput,
  TextInputField,
  SelectField,
  Alert,
  Dialog,
  Badge,
  majorScale,
} from "evergreen-ui";
import "./evergreen.css";
const people = [
  { name: "Avery Stone", plan: "Pro", tags: ["active", "newsletter"] },
  { name: "Taylor Reed", plan: "Free", tags: ["newsletter"] },
  { name: "Jordan Park", plan: "Pro", tags: ["active"] },
  { name: "Morgan Lee", plan: "Team", tags: ["active", "newsletter"] },
  { name: "Casey Chen", plan: "Free", tags: ["trial"] },
];
function App() {
  const [tags, setTags] = useState(["active"]),
    [plan, setPlan] = useState("Any"),
    [name, setName] = useState("Active customers"),
    [error, setError] = useState(""),
    [open, setOpen] = useState(false),
    [saved, setSaved] = useState(null);
  const matches = people.filter(
    (p) =>
      (plan === "Any" || p.plan === plan) &&
      tags.every((t) => p.tags.includes(t)),
  );
  function changeTags(values) {
    const unique = [
      ...new Set(values.map((v) => v.trim().toLowerCase()).filter(Boolean)),
    ];
    if (unique.length > 4) {
      setError("Use at most four tags.");
      return false;
    }
    setTags(unique);
    setError("");
    setSaved(null);
  }
  return (
    <ThemeProvider value={defaultTheme}>
      <main className="audience">
        <header>
          <Text size={300}>WORKSPACE / AUDIENCES</Text>
          <Heading size={700} marginTop={8}>
            Build a focused audience
          </Heading>
          <Paragraph marginTop={8}>
            Combine a plan and tags against five fictional records. No customer
            data is loaded.
          </Paragraph>
        </header>
        <div className="audience-grid">
          <section className="rule-panel">
            <Heading size={500} marginBottom={majorScale(3)}>
              Audience rules
            </Heading>
            <TextInputField
              label="Audience name"
              value={name}
              onChange={(e) => {
                setName(e.target.value);
                setSaved(null);
              }}
            />
            <SelectField
              label="Plan"
              value={plan}
              onChange={(e) => {
                setPlan(e.target.value);
                setSaved(null);
              }}
            >
              <option>Any</option>
              <option>Free</option>
              <option>Pro</option>
              <option>Team</option>
            </SelectField>
            <label htmlFor="audience-tags">Required tags</label>
            <Paragraph size={300} marginBottom={8}>
              Press Enter or comma to add a tag. Every tag must match.
            </Paragraph>
            <TagInput
              values={tags}
              onChange={changeTags}
              width="100%"
              inputProps={{ id: "audience-tags", placeholder: "Add tag…" }}
            />
            <Paragraph size={300} marginTop={8}>
              Available sample tags: active, newsletter, trial.
            </Paragraph>
            {error && <Alert intent="danger" title={error} marginTop={16} />}
            <Button
              appearance="primary"
              marginTop={24}
              onClick={() => {
                if (!name.trim()) {
                  setError("Name the audience before reviewing.");
                  return;
                }
                setError("");
                setOpen(true);
              }}
            >
              Review audience
            </Button>
          </section>
          <section className="results-panel">
            <div className="results-title">
              <Heading size={500}>Matching sample records</Heading>
              <Badge color="blue">
                {matches.length} of {people.length}
              </Badge>
            </div>
            {matches.length ? (
              <div className="record-list">
                {matches.map((p) => (
                  <article key={p.name}>
                    <div>
                      <Heading size={400}>{p.name}</Heading>
                      <Text size={300}>{p.plan} plan</Text>
                    </div>
                    <div className="tag-list">
                      {p.tags.map((t) => (
                        <Badge key={t} color="neutral">
                          {t}
                        </Badge>
                      ))}
                    </div>
                  </article>
                ))}
              </div>
            ) : (
              <div className="empty">
                <Heading size={500}>No matching sample records</Heading>
                <Paragraph marginTop={8}>
                  Remove a tag or change the plan to broaden the selection.
                </Paragraph>
                <Button
                  marginTop={16}
                  onClick={() => {
                    setTags([]);
                    setPlan("Any");
                    setSaved(null);
                  }}
                >
                  Clear rules
                </Button>
              </div>
            )}
            {saved && (
              <Alert
                intent="success"
                title="Local audience saved"
                marginTop={20}
              >
                {saved.name} · {saved.count} sample records. Nothing was sent to
                Segment.
              </Alert>
            )}
          </section>
        </div>
        <Dialog
          isShown={open}
          title="Review local audience"
          onCloseComplete={() => setOpen(false)}
          confirmLabel="Save locally"
          onConfirm={() => {
            setSaved({ name: name.trim(), count: matches.length });
            setOpen(false);
          }}
          width={560}
        >
          <Paragraph>
            <strong>{name}</strong> matches {matches.length} of {people.length}{" "}
            fictional records.
          </Paragraph>
          <Paragraph marginTop={12}>
            Plan: {plan}. Required tags: {tags.join(", ") || "none"}.
          </Paragraph>
          <Paragraph marginTop={12}>
            This saves only a local snapshot; it does not create a Segment
            audience.
          </Paragraph>
        </Dialog>
        <footer>
          Native Evergreen 7.1.9 React components. Original audience logic; no
          analytics or customer service connection.
        </footer>
      </main>
    </ThemeProvider>
  );
}
createRoot(document.getElementById("root")).render(<App />);

Referencia de código

  • Crea un proyecto Vite React, conserva <div id="root"></div> y cárgalo como src/main.jsx.

evergreen.css — composición adaptable original

Diseño de la aplicación con capas alrededor de los componentes nativos.

css
* {
  box-sizing: border-box;
}
body {
  margin: 0;
  background: #f4f5f9;
  color: #101840;
  font:
    14px/1.5 system-ui,
    sans-serif;
}
.audience {
  padding: 32px;
}
.audience header {
  max-width: 800px;
  margin-bottom: 28px;
}
.audience-grid {
  display: grid;
  grid-template-columns: minmax(260px, 0.85fr) minmax(0, 1.5fr);
  gap: 24px;
}
.rule-panel,
.results-panel {
  padding: 24px;
  background: white;
  border: 1px solid #d8dae5;
  border-radius: 8px;
  min-width: 0;
}
.rule-panel > label {
  font-weight: 600;
  display: block;
  margin-bottom: 8px;
}
.results-title {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin-bottom: 24px;
}
.record-list article {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 20px 0;
  border-bottom: 1px solid #edeff5;
}
.record-list article:first-child {
  padding-top: 0;
}
.record-list article:last-child {
  border: 0;
}
.tag-list {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.empty {
  padding: 36px 12px;
  text-align: center;
  background: #f4f5f9;
  border-radius: 4px;
}
.audience footer {
  margin-top: 24px;
  font-size: 12px;
  color: #696f8c;
}
.audience input {
  max-width: 100%;
}
[role="dialog"] {
  max-width: calc(100vw - 32px);
}
@media (max-width: 850px) {
  .audience-grid {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 550px) {
  .audience {
    padding: 16px;
  }
  .rule-panel,
  .results-panel {
    padding: 20px;
  }
  .record-list article {
    align-items: flex-start;
    flex-direction: column;
  }
  .results-title {
    align-items: flex-start;
  }
}

Referencia de código

  • Guárdalo junto a main.jsx. Estas reglas de composición personalizadas se distinguen de la referencia de tokens de la biblioteca.
04

Configuración del agente para el sistema de diseño Segment Evergreen

Punto de partida para la implementación

El ejemplo nativo fijado se empaquetó y se comprobó localmente en el navegador. El ejemplo utiliza únicamente el estado local de la aplicación.

sh
npm create vite@latest evergreen-audience -- --template react
cd evergreen-audience
npm install
npm install [email protected] [email protected] [email protected]
# Replace src/main.jsx and add src/evergreen.css.
npm run dev

Una instrucción para tu proyecto

Instrucción para el agente
Crea un editor de audiencias de Evergreen con el tema real y TagInput controlado. Normaliza y elimina los duplicados de las etiquetas, especifica la coincidencia con todas ellas, mantén coherentes los resultados y los recuentos, permite revisarlos en un Dialog nativo y borra el estado de éxito obsoleto cuando cambien las reglas. No afirmes que existe una conexión con un servicio de Segment.
05

Fuentes y alcance del sistema de diseño Segment Evergreen

Guía de implementación de OpenDesign para Evergreen 7.1.9. Cinco registros ficticios muestran el filtrado local y la revisión de una vista. No hay datos de clientes de Segment ni una audiencia de API conectados.