Software di assistenza clienti · Nuova risorsa

Sistema di design Zendesk Garden.

Una guida Garden per l’assistenza, con alias reali del tema, scale tipografiche e dei raggi, un compositore di risposte completo, bozze locali gestite in base alla visibilità e recupero dei campi.

Guida OpenDesign8 capitoli42 voci di riferimentoGuida applicativa originale
01

Anteprima dell’interfaccia del sistema di design Zendesk Garden

Modifica la visibilità della risposta, convalida una breve bozza, salva un’istantanea locale e prepara la bozza successiva.

Prepara una risposta mantenendo visibile il contesto del clienteApri l’esempio completo
ThemeProvider, Buttons e Forms nativi di Garden 9.16.1 React; flusso originale di composizione locale. · Riferimento per l’implementazione
02

Riferimento di progettazione del sistema di design Zendesk Garden

ThemeProvider, Buttons e Forms nativi di Garden 9.16.1 React; flusso originale di composizione locale.

Raggio degli angoli

Fonte
Nome / regolaValore / configurazioneUtilizzo
borderRadii.sm2pxScegli la forma in base al ruolo del componente; l’angolo medio predefinito non è a pillola.
borderRadii.md4pxScegli la forma in base al ruolo del componente; l’angolo medio predefinito non è a pillola.
borderRadii.lg8pxScegli la forma in base al ruolo del componente; l’angolo medio predefinito non è a pillola.

Breakpoint responsive

Fonte
Nome / regolaValore / configurazioneUtilizzo
breakpoints.xs0pxBreakpoint del tema; non garantiscono che l’applicazione cambi ogni area a ciascun passaggio.
breakpoints.sm576pxBreakpoint del tema; non garantiscono che l’applicazione cambi ogni area a ciascun passaggio.
breakpoints.md768pxBreakpoint del tema; non garantiscono che l’applicazione cambi ogni area a ciascun passaggio.
breakpoints.lg992pxBreakpoint del tema; non garantiscono che l’applicazione cambi ogni area a ciascun passaggio.
breakpoints.xl1200pxBreakpoint del tema; non garantiscono che l’applicazione cambi ogni area a ciascun passaggio.

Dimensioni del testo

Fonte
Nome / regolaValore / configurazioneUtilizzo
fontSizes.xs10pxMantieni distinti i ruoli del testo del corpo, delle etichette, dei metadati e dei titoli.
fontSizes.sm12pxMantieni distinti i ruoli del testo del corpo, delle etichette, dei metadati e dei titoli.
fontSizes.md14pxMantieni distinti i ruoli del testo del corpo, delle etichette, dei metadati e dei titoli.
fontSizes.lg18pxMantieni distinti i ruoli del testo del corpo, delle etichette, dei metadati e dei titoli.
fontSizes.xl22pxMantieni distinti i ruoli del testo del corpo, delle etichette, dei metadati e dei titoli.
fontSizes.xxl26pxMantieni distinti i ruoli del testo del corpo, delle etichette, dei metadati e dei titoli.
fontSizes.xxxl36pxMantieni distinti i ruoli del testo del corpo, delle etichette, dei metadati e dei titoli.

Altezze di riga

Fonte
Nome / regolaValore / configurazioneUtilizzo
lineHeights.sm16pxUsalo insieme al ruolo tipografico; non ricavare tutte le altezze di riga dalla dimensione del carattere.
lineHeights.md20pxUsalo insieme al ruolo tipografico; non ricavare tutte le altezze di riga dalla dimensione del carattere.
lineHeights.lg24pxUsalo insieme al ruolo tipografico; non ricavare tutte le altezze di riga dalla dimensione del carattere.
lineHeights.xl28pxUsalo insieme al ruolo tipografico; non ricavare tutte le altezze di riga dalla dimensione del carattere.
lineHeights.xxl32pxUsalo insieme al ruolo tipografico; non ricavare tutte le altezze di riga dalla dimensione del carattere.
lineHeights.xxxl44pxUsalo insieme al ruolo tipografico; non ricavare tutte le altezze di riga dalla dimensione del carattere.

Livelli di spaziatura

Fonte
Nome / regolaValore / configurazioneUtilizzo
space.base4Valori di spaziatura del tema per un ritmo prevedibile.
space.xxs4pxValori di spaziatura del tema per un ritmo prevedibile.
space.xs8pxValori di spaziatura del tema per un ritmo prevedibile.
space.sm12pxValori di spaziatura del tema per un ritmo prevedibile.
space.md20pxValori di spaziatura del tema per un ritmo prevedibile.
space.lg32pxValori di spaziatura del tema per un ritmo prevedibile.
space.xl40pxValori di spaziatura del tema per un ritmo prevedibile.
space.xxl48pxValori di spaziatura del tema per un ritmo prevedibile.

Mappatura dei ruoli semantici chiari

Fonte
Nome / regolaValore / configurazioneUtilizzo
colors.variables.light.background.defaultpalette.whiteAlias di un ruolo del tema; risolvilo tramite la tonalità e la palette selezionate, invece di trattare l’alias come un colore CSS.
colors.variables.light.background.subtleneutralHue.100Alias di un ruolo del tema; risolvilo tramite la tonalità e la palette selezionate, invece di trattare l’alias come un colore CSS.
colors.variables.light.background.dangerdangerHue.100Alias di un ruolo del tema; risolvilo tramite la tonalità e la palette selezionate, invece di trattare l’alias come un colore CSS.
colors.variables.light.background.primaryEmphasisprimaryHue.700Alias di un ruolo del tema; risolvilo tramite la tonalità e la palette selezionate, invece di trattare l’alias come un colore CSS.
colors.variables.light.foreground.defaultneutralHue.900Alias di un ruolo del tema; risolvilo tramite la tonalità e la palette selezionate, invece di trattare l’alias come un colore CSS.
colors.variables.light.foreground.subtleneutralHue.700Alias di un ruolo del tema; risolvilo tramite la tonalità e la palette selezionate, invece di trattare l’alias come un colore CSS.
colors.variables.light.foreground.onEmphasispalette.whiteAlias di un ruolo del tema; risolvilo tramite la tonalità e la palette selezionate, invece di trattare l’alias come un colore CSS.
colors.variables.light.foreground.primaryprimaryHue.700Alias di un ruolo del tema; risolvilo tramite la tonalità e la palette selezionate, invece di trattare l’alias come un colore CSS.
colors.variables.light.foreground.dangerdangerHue.700Alias di un ruolo del tema; risolvilo tramite la tonalità e la palette selezionate, invece di trattare l’alias come un colore CSS.
colors.variables.light.border.defaultneutralHue.300Alias di un ruolo del tema; risolvilo tramite la tonalità e la palette selezionate, invece di trattare l’alias come un colore CSS.
colors.variables.light.border.subtleneutralHue.200Alias di un ruolo del tema; risolvilo tramite la tonalità e la palette selezionate, invece di trattare l’alias come un colore CSS.
colors.variables.light.border.dangerdangerHue.300Alias di un ruolo del tema; risolvilo tramite la tonalità e la palette selezionate, invece di trattare l’alias come un colore CSS.
colors.variables.light.border.primaryEmphasisprimaryHue.700Alias di un ruolo del tema; risolvilo tramite la tonalità e la palette selezionate, invece di trattare l’alias come un colore CSS.
03

Guida completa al sistema di design Zendesk Garden

Una guida pratica per scegliere, applicare e valutare questo sistema in un’interfaccia reale.

DESIGN-zendesk-garden.md

Indicazioni complete, un punto di partenza per l’implementazione e link alle fonti.

Scarica la guida

Struttura dello spazio di assistenza del sistema di design Zendesk Garden

Mantieni visibile la richiesta del cliente

Per evitare una risposta ben formulata ma fuori tema, chi redige un messaggio di assistenza deve avere abbastanza contesto. L’esempio mostra la richiesta del cliente sopra la bozza e, accanto, il richiedente, l’organizzazione e l’argomento. L’interfaccia è abbastanza densa da consentire di confrontare il nuovo testo con la domanda originale senza cambiare schermata.

Da questa guida su OpenDesign

Tieni separati lo storico e la bozza attiva

Le voci salvate localmente compaiono sopra l’editor con un’indicazione esplicita della visibilità. La bozza attiva resta nel componente Textarea nativo. Il salvataggio aggiunge un’istantanea e svuota il campo, così le modifiche successive non possono alterare silenziosamente una nota già salvata.

Ruoli e palette del tema del sistema di design Zendesk Garden

Esamina gli alias prima di copiare i colori

In Garden 9, DEFAULT_THEME associa i ruoli semantici a famiglie di tonalità e valori numerati della palette. Un ruolo come background.primaryEmphasis non è un valore esadecimale letterale. La tabella di riferimento mantiene questi alias, così un tema personalizzato può cambiare la tonalità primaria senza lasciare frammenti blu codificati direttamente nei controlli nativi.

Mantieni le aree personalizzate compatibili con il provider

ThemeProvider fornisce lo stile dei componenti nativi. Questo esempio usa DEFAULT_THEME e uno spazio di lavoro personalizzato chiaro, coerente con il tema; non aggiunge un falso interruttore per la modalità scura che modifica solo lo sfondo circostante. Se aggiungi il supporto per gli schemi di colore, aggiorna i colori personalizzati dei messaggi e della barra laterale insieme a quelli del provider.

Tipografia e densità del sistema di design Zendesk Garden

Mantieni leggibile il testo di lavoro a 14px

Il tema predefinito espone un ruolo medio da 14px con un’altezza di riga media di 20px, oltre a ruoli distinti da 12px per i contenuti di supporto e da 18px per i titoli. L’esempio usa un titolo del ticket da 26px e metadati di contesto più piccoli. Il messaggio originale del cliente e le note salvate restano in testo normale, non compresso in etichette.

Lascia che le risposte lunghe vadano a capo naturalmente

Il testo salvato mantiene le interruzioni di riga e manda a capo le parole lunghe. Anche su uno schermo mobile stretto, quindi, la nota resta interamente visibile senza richiedere lo scorrimento orizzontale. L’area di composizione si espande in verticale tramite il campo di testo, invece di trasformare tutto lo storico dei messaggi in un riquadro a scorrimento interno.

Composizione di campi e pulsanti del sistema di design Zendesk Garden

Collega etichetta, suggerimento ed errore

Il componente Field nativo raggruppa Label, Hint, Textarea e Message condizionale. La proprietà di convalida modifica l’aspetto del campo di testo quando non viene rispettata la regola definita dall’applicazione sulla lunghezza minima. In questo modo si segue la composizione del componente, anziché applicare il colore di errore a un paragrafo non correlato all’esterno del campo.

Dedica alla visibilità un controllo specifico

Stato delle bozze e storico locale del sistema di design Zendesk Garden

Convalida prima di aggiungere un messaggio

L’applicazione richiede almeno dodici caratteri dopo aver rimosso gli spazi iniziali e finali. Se l’invio non supera il controllo, la bozza resta intatta, viene mostrato un messaggio nel campo e il focus passa al campo di testo. La modifica del testo rimuove l’errore non più attuale; un invio successivo verifica di nuovo il testo corrente. Questa regola è un comportamento dell’applicazione, non un’impostazione predefinita di Garden non documentata.

Distingui visivamente le note interne

Le voci interne hanno uno sfondo caldo, creato appositamente, e l’etichetta «Bozza di nota interna». Le voci pubbliche usano la superficie normale. Entrambe riportano esplicitamente che non sono state inviate. La distinzione mostra il contesto di visibilità senza imitare una conversazione Zendesk attiva né suggerire che qualcun altro abbia ricevuto qualcosa.

Aree di lavoro responsive del sistema di design Zendesk Garden

Sposta il contesto sotto l’attività principale

Al breakpoint dell’applicazione, il contesto del ticket si sposta sotto la conversazione e l’area di composizione. L’ordine del documento sottostante resta invariato. Su uno smartphone, il controllo della visibilità occupa tutta la larghezza disponibile e la riga delle azioni va a capo, così le etichette dei pulsanti non vengono compresse.

Usa raggi moderati e divisori sottili

I controlli nativi usano la scala dei raggi di 2px, 4px e 8px. I pannelli dei messaggi originali hanno angoli da 4px e bordi discreti. L’enfasi visiva maggiore va riservata all’azione attiva e allo stato di convalida, non alle ombre attorno a ogni messaggio.

Convalida e ripristino da tastiera del sistema di design Zendesk Garden

Verifica l’intero flusso delle bozze

Una verifica utile parte da un tentativo non valido e controlla poi che digitazione, cambio di visibilità, salvataggio e cancellazione lascino l’interfaccia comprensibile. Il codice usa un ref React per ripristinare il focus dopo un errore o un’azione di cancellazione. Il conteggio dei risultati viene annunciato in un’area di stato.

  1. Invia una bozza breve e segui l’errore del campo.
  2. Seleziona Nota interna, inserisci una nota utile e salvala.
  3. Cancella una bozza successiva e verifica che l’istantanea locale salvata resti disponibile.

Mantieni stabile l’ordine di lettura

La richiesta precede la bozza e le nuove istantanee locali salvate restano in ordine cronologico. I pulsanti nativi espongono le proprie azioni come testo. Nell’area di composizione non si nascondono scorciatoie da tastiera né comportamenti di invio automatico; la scelta della visibilità resta un menu Select con etichetta.

Integrazione React del sistema di design Zendesk Garden

Installa versioni compatibili dei pacchetti

L’esempio fissa i pacchetti per temi, pulsanti e moduli alla versione 9.16.1 e usa React 18 con styled-components. Mescolare versioni meno recenti dei pacchetti Garden può creare aspettative incoerenti sul tema. La voce JSX completa include il provider, la composizione del campo e lo stato locale, mentre il file CSS contiene solo il layout personalizzato.

  • @zendeskgarden/react-theming 9.16.1
  • @zendeskgarden/react-buttons 9.16.1
  • @zendeskgarden/react-forms 9.16.1

Estendi solo il livello di servizio mancante

Esempi di componenti del sistema di design Zendesk Garden

main.jsx — esempio completo funzionante

Prepara una risposta mantenendo visibile il contesto del cliente. Il codice riportato sotto è la voce React completa, comprensiva di tutto lo stato e della convalida.

jsx
import React, { useState, useRef } from "react";
import { createRoot } from "react-dom/client";
import { ThemeProvider, DEFAULT_THEME } from "@zendeskgarden/react-theming";
import { Button } from "@zendeskgarden/react-buttons";
import {
  Field,
  Label,
  Textarea,
  Hint,
  Message,
  Select,
} from "@zendeskgarden/react-forms";
import "./garden.css";
function App() {
  const [mode, setMode] = useState("public"),
    [text, setText] = useState(""),
    [error, setError] = useState(false),
    [items, setItems] = useState([]);
  const ref = useRef();
  function submit(e) {
    e.preventDefault();
    if (text.trim().length < 12) {
      setError(true);
      ref.current.focus();
      return;
    }
    setItems([...items, { mode, text: text.trim() }]);
    setText("");
    setError(false);
  }
  return (
    <ThemeProvider theme={DEFAULT_THEME}>
      <main className="garden-workspace">
        <header>
          <span>SUPPORT WORKSPACE / FICTIONAL TICKET</span>
          <h1>Help with an invoice address</h1>
          <p>Ticket #1028 · Nadia Walker · Email channel</p>
        </header>
        <div className="garden-grid">
          <section>
            <div className="message customer">
              <strong>Nadia Walker</strong>
              <small>Customer · example message</small>
              <p>
                Could you update the company address on our next invoice? The
                billing contact has changed.
              </p>
            </div>
            {items.map((i, n) => (
              <article className={"message " + i.mode} key={n}>
                <strong>
                  {i.mode === "public"
                    ? "Public reply draft"
                    : "Internal note draft"}
                </strong>
                <small>Saved locally · not sent</small>
                <p>{i.text}</p>
              </article>
            ))}
            <form onSubmit={submit} noValidate>
              <div className="composer-head">
                <h2>Compose a draft</h2>
                <Field>
                  <Label>Visibility</Label>
                  <Select
                    value={mode}
                    onChange={(e) => setMode(e.target.value)}
                  >
                    <option value="public">Public reply</option>
                    <option value="internal">Internal note</option>
                  </Select>
                </Field>
              </div>
              <Field>
                <Label>
                  {mode === "public" ? "Reply text" : "Internal note"}
                </Label>
                <Hint>
                  {mode === "public"
                    ? "Prepared for the customer; this demo will not send it."
                    : "Internal context for the support team; saved only in this page."}
                </Hint>
                <Textarea
                  ref={ref}
                  value={text}
                  rows={5}
                  validation={error ? "error" : undefined}
                  onChange={(e) => {
                    setText(e.target.value);
                    setError(false);
                  }}
                />
                {error && (
                  <Message validation="error">
                    Write at least 12 characters.
                  </Message>
                )}
              </Field>
              <div className="composer-actions">
                <span>{text.length} characters</span>
                <Button
                  type="button"
                  onClick={() => {
                    setText("");
                    setError(false);
                    ref.current.focus();
                  }}
                >
                  Clear draft
                </Button>
                <Button isPrimary type="submit">
                  Save local draft
                </Button>
              </div>
            </form>
            <p role="status">
              {items.length > 0
                ? `${items.length} draft${items.length === 1 ? "" : "s"} saved locally. No message sent.`
                : ""}
            </p>
          </section>
          <aside>
            <h2>Ticket context</h2>
            <dl>
              <dt>Requester</dt>
              <dd>Nadia Walker</dd>
              <dt>Organization</dt>
              <dd>Northstar Studio</dd>
              <dt>Priority</dt>
              <dd>Normal</dd>
              <dt>Topic</dt>
              <dd>Billing details</dd>
            </dl>
            <div className="context-note">
              <h3>Before replying</h3>
              <ul>
                <li>Confirm the billing contact.</li>
                <li>Keep invoice identifiers out of public examples.</li>
                <li>State whether the change affects future invoices.</li>
              </ul>
            </div>
          </aside>
        </div>
        <footer>
          Native Garden 9.16.1 React components. Original local drafting
          workflow; no Zendesk connection.
        </footer>
      </main>
    </ThemeProvider>
  );
}
createRoot(document.getElementById("root")).render(<App />);

Riferimento del codice

  • Crea un progetto React con Vite, mantieni <div id="root"></div> e salva questo codice come src/main.jsx.

garden.css — composizione responsive originale

Impaginazione dell’applicazione costruita intorno ai componenti nativi.

css
* {
  box-sizing: border-box;
}
body {
  margin: 0;
  font:
    14px/1.5 system-ui,
    sans-serif;
  color: #293239;
  background: #f8f9f9;
}
.garden-workspace header {
  padding: 24px 32px;
  background: white;
  border-bottom: 1px solid #d8dcde;
}
.garden-workspace header span {
  font-size: 10px;
  letter-spacing: 0.08em;
  color: #5c6970;
}
.garden-workspace h1 {
  font-size: 26px;
  line-height: 1.3;
  margin: 8px 0;
}
.garden-workspace header p {
  color: #5c6970;
  margin: 0;
}
.garden-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  gap: 24px;
  padding: 24px 32px;
}
.message {
  padding: 20px;
  background: white;
  border: 1px solid #d8dcde;
  border-radius: 4px;
  margin-bottom: 16px;
}
.message p {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  margin: 12px 0 0;
}
.message small {
  display: block;
  color: #5c6970;
  margin-top: 4px;
}
.message.internal {
  background: #fff8ed;
  border-color: #e7ce99;
}
form {
  padding: 24px;
  background: white;
  border: 1px solid #d8dcde;
  border-radius: 4px;
}
.composer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin-bottom: 24px;
}
.composer-head > div {
  max-width: 220px;
}
.garden-workspace h2 {
  font-size: 18px;
  margin: 0 0 12px;
}
.composer-actions {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  margin-top: 20px;
}
.composer-actions span {
  font-size: 12px;
  color: #5c6970;
  margin-right: auto;
}
.garden-grid aside {
  background: white;
  border: 1px solid #d8dcde;
  border-radius: 4px;
  padding: 20px;
  align-self: start;
}
dl {
  margin: 0;
}
dt {
  font-size: 12px;
  color: #5c6970;
  margin-top: 16px;
}
dd {
  margin: 4px 0 0;
  font-weight: 600;
}
.context-note {
  margin-top: 24px;
  border-top: 1px solid #e8eaec;
  padding-top: 16px;
}
.context-note h3 {
  font-size: 14px;
}
.context-note ul {
  padding-left: 18px;
  font-size: 12px;
}
.context-note li {
  margin: 8px 0;
}
footer {
  padding: 16px 32px;
  font-size: 12px;
  color: #5c6970;
  border-top: 1px solid #d8dcde;
  background: white;
}
@media (max-width: 850px) {
  .garden-grid {
    grid-template-columns: 1fr;
  }
}
@media (max-width: 550px) {
  .garden-grid {
    padding: 16px;
  }
  .garden-workspace header {
    padding: 20px 16px;
  }
  .composer-head {
    display: block;
  }
  .composer-head > div {
    max-width: none;
  }
  .composer-actions {
    flex-wrap: wrap;
    justify-content: flex-start;
  }
  .composer-actions span {
    width: 100%;
  }
  form {
    padding: 16px;
  }
}

Riferimento del codice

  • Salva il file accanto a main.jsx. Queste regole di composizione personalizzate sono distinte dal riferimento ai token della libreria.
04

Configurazione dell’agent del sistema di design Zendesk Garden

Punto di partenza per l’implementazione

L’esempio nativo bloccato è stato incluso nel bundle e verificato localmente nel browser. L’esempio usa solo lo stato locale dell’applicazione.

sh
npm create vite@latest garden-draft -- --template react
cd garden-draft
npm install
npm install [email protected] [email protected] styled-components @zendeskgarden/[email protected] @zendeskgarden/[email protected] @zendeskgarden/[email protected]
# Replace src/main.jsx and add src/garden.css.
npm run dev

Un prompt per il tuo progetto

Prompt per l’agente
Crea un modulo per comporre risposte di supporto Garden usando la composizione nativa di Field/Label/Hint/Textarea/Message. Mantieni la visibilità in ogni snapshot di bozza salvato, convalida prima di aggiungere contenuti, conserva il contesto del cliente e distingui il salvataggio locale dall’invio. Usa esattamente i ruoli del tema e consulta qui il codice sorgente completo.
05

Zendesk Garden Fonti e ambito del sistema di design

OpenDesign guida dell’applicazione. I componenti nativi di Garden mostrano l’esempio; il contenuto fittizio dei ticket e le bozze locali non si collegano a Zendesk e non inviano messaggi.