Canvas Kit’in birleşik FormField bileşeni, denetimli TextInput bileşeni ve PrimaryButton bileşeniyle yerel bir öğrenme planı oluşturun. Güncel anlamsal belirteç kaynaklarıyla eski space.x4 geçiş örneklerinin farkını görün.
Canvas etkileşim kalıplarının ve ölçülü kurumsal hiyerarşinin HTML özgün çevrimdışı yorumudur. Renk paleti ve düzen uygulama tercihleridir; Sana kiracısının görünümünü yansıtmaz. · Uygulama başvurusu
02
Workday Canvas Tasarım Sistemi Tasarım Referansı
Güncel Canvas Kit kaynak kodu ve Canvas belirteçleri sys.json. Aşağıdaki ham JSON adları, kaynak yollarıdır; uydurulmuş, oluşturulmuş CSS değişken adları değildir. Temel belirteçlere eşlenen değerler takma ad olarak gösterilmiştir; tarihli geçiş referansı açıkça geçmişe ait olarak belirtilmiştir.
Workday Canvas Tasarım Sistemi Geçiş örneğini kopyalamadan önce güncel kaynak kodu inceleyin
Aralıklar artık kullanım amacına göre ayrılıyor
Canvas, canvas-kit-react/tokens içindeki tişört bedeni biçimindeki boşluk sabitlerinden system.space numaralı belirteçlerine, oradan da padding ve gap gibi kaynak kategorilerine evrildi. Güncel sys.json, bunların temelindeki değerleri temel belirteçlere yapılan başvurular olarak ifade eder. Bu referans, sözcükleri birleştirerek CSS değişkeni uydurmak yerine, kaynakta gerçekten bulunan yolları korur.
Geçiş tablosu, eski bir uygulamayı dönüştürürken hâlâ yararlıdır: önceki space.s değerinin neden bir rem değerine karşılık geldiğini açıklar. Bu, geçmişe ait bir kanıttır; her eski dışa aktarımın güncel arayüzde tercih edildiği anlamına gelmez. Önizlemede uygulama tercihi olarak açıkça 16 ve 24px aralıkları kullanılır; kitaplık belirteçlerinin adları konusunda yetkili kaynak, kaynak kod tablosudur.
Workday Canvas Tasarım Sistemi Renk, kiracıya ve bileşen durumuna bağlıdır
Bir birincil düğme, sabit bir mavi renk örneğinden fazlasıdır
PrimaryButton önce brand.action.base değerini okur; bu değer yoksa eski primary vurgusuna geri döner. Hover ve basılı tutma stilleri de durumları colorSpace yardımcılarıyla türetmeden önce brand eylem rollerine başvurur. Bu nedenle, sabit kodlanmış tek bir arka plan rengini değiştirmek bileşenin tema sözleşmesini yeniden oluşturamaz.
Özgün öğrenme önizlemesi, ölçülü bir mavi uygulama paleti kullanır ve kendisini HTML yorumu olarak tanımlar. Belirli bir müşterinin kiracısını veya daha yeni Sana Canvas temasını yansıtmaz. Eksiksiz yerel örnek, bileşen renklerini yüklü belirteç katmanlarının sağlamasına olanak tanır.
Workday Canvas Tasarım Sistemi Birleşik roller satır yüksekliğini ve kalınlığı korur
Boyut takma adı, stilin tamamı değildir
Güncel body.sm tipografi nesnesi; yazı tipi ailesini, normal kalınlığı, gövde metni boyutunu ve satır aralığını bir araya getirir. Başlık rolleri kalın ağırlığı kullanır. Eski bir ekran görüntüsünden yalnızca piksel boyutunu seçmek bu ilişkileri kaybettirir. Kaynak koddaki ad normal'dır; eski geçiş metinlerinde görülen regular anahtarı kullanılmaz.
Yazı tipleri Canvas Kit bileşen paketine dahil değildir. Yazı tipi yüklemeyi ayrı bir entegrasyon tercihi olarak ele alın; çevrimdışı örnek bir sistem yedeği kullanır ve Roboto veya Sana yazı tipini içerdiğini iddia etmez.
Workday Canvas Tasarım Sistemi FormField bileşik bir bileşendir
Etiket, giriş alanı ve ipucunu alanın bir araya getirmesine izin verin
Kaynak kod FormField.Label, FormField.Input ve FormField.Hint bileşenlerini sunar. TextInput öğesini Input'ın prop özelliği üzerinden geçirmek, modelin erişilebilir ilişkileri oluşturmasını sağlar. Bu yaklaşım, dış alana label özelliği ekleyip doğrudan içine sarmalanmamış bir giriş alanı yerleştiren eski örneklerden farklıdır.
Yatay formlarda geçerli yönlendirme değerleri horizontalStart ve horizontalEnd'dir. FormField.Field, giriş alanını ve ipucunu bu hizalama içinde gruplar. Açıklama doğrudan etiketin ve denetimin altında yer aldığından filtremiz dikey kalır.
FormField.Label içine görünür, gerçek bir etiket yerleştirin.
Workday Canvas Tasarım Sistemi Büyüyen bir giriş alanı da esnek bir üst kapsayıcıya ihtiyaç duyar
Asgari genişliği hesaba katın
TextInput, kaynak kodunda px2rem ile ifade edilen 280px'lik varsayılan bir asgari genişliğe sahiptir. grow tam genişlik ister; ancak dar bir görünüm alanına sığması için katı, iki sütunlu bir üst kapsayıcıyı kendiliğinden esnek hâle getirmez. Çevrimdışı katalog, mobilde plan kenar çubuğunu kurs kartlarının altına taşır ve her düzen sütununun küçülmesine izin verir.
Arama değeri sıradan bir React durum bilgisidir. Uygulama, üç kurs başlığında büyük-küçük harf duyarsız alt dize eşleşmesi yapar ve sonuç olmadığını açıkça gösterir. Filtre, seçilen kursları temizlemez; çünkü görünürlük ile plan üyeliği farklı durumlardır.
Workday Canvas Tasarım Sistemi Seçim, görünür sonuçlardan bağımsız olarak korunur
Kararlı kurs kimlikleri kullanın ve toplamları türetin
Her özgün kursun bir kimliği, başlığı ve süresi vardır. Seçilen liste kimlikleri saklar; görüntülenen toplam ise kurs kayıtlarından türetilir. Kataloğu filtrelemek, seçilmiş bir öğeyi kaldırmaz. Bir öğe kaldırıldığında Ekle eylemi hemen geri gelir ve toplam süre azalır.
Bu, yerel planlamaya yönelik özgün bir senaryodur. Workday API'lerini çağırmaz, bir çalışanı kaydetmez veya bir öğrenme kaydını değiştirmez. Bu sınırı görünür tutmak, prototipin gerçek bir iş işlemi izlenimi vermesini önler.
Yalnızca katalog görünümünü filtreleyin.
Bir kurs kimliğini yalnızca bir kez ekleyin.
Seçili kursları ve toplam dakikayı bu kimliklerden türetin.
Workday Canvas Tasarım Sistemi Temalı bileşenleri beklemeden önce belirteçleri yükleyin
Sağlayıcının ve CSS katmanlarının sorumlulukları farklıdır
Güncel başlangıç kılavuzu örneği; uygulama giriş noktasında temel, marka, bileşen ve sistem değişkeni stillerini içe aktarır, ardından arayüzü CanvasProvider ile sarar. Sağlayıcı tek başına bu CSS tanımlarının yerini tutmaz. Buradaki kod bu bileşimi izler ve eksiksiz bir React kökü sağlar.
Sana Canvas isteğe bağlıdır: değişkenleri sistem değişkenlerinden sonra yüklenir ve belgelenen html data-theme özelliği temayı seçer. Belge kökünü denetleyemeyen gömülü uygulamalar, açılır pencerelere tema aktarımı için özel bir sağlayıcı tema seçeneğine sahiptir. Paketleri yükseltirken bu temayı mevcut bir kiracıya yanlışlıkla eklemeyin.
Belgenin tamamını index.html adıyla kaydedip tarayıcıda açın. Canvas etkileşim kalıplarının ve ölçülü kurumsal hiyerarşinin HTML özgün çevrimdışı yorumudur. Renk paleti ve düzen uygulama tercihleridir; Sana kiracısının görünümünü yansıtmaz.
html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Canvas learning plan interpretation</title><style>*{box-sizing:border-box}body{margin:0;background:#f3f5f7;color:#20272f;font:16px/1.5 system-ui,sans-serif}button,input{font:inherit}header{background:white;border-bottom:1px solid #d5dbe0;padding:16px 24px;display:flex;gap:12px;align-items:center}.mark{width:32px;height:32px;border:4px solid #ed9b28;border-bottom:0;border-radius:50% 50% 0 0;height:16px;margin-right:8px}header span{font-size:14px;color:#59616b;margin-left:auto}main{max-width:1100px;margin:32px auto;padding:0 24px}h1{font-size:28px;line-height:36px;margin:0 0 8px}p{margin:0 0 24px}label{display:block;font-size:14px;font-weight:600;margin-bottom:8px}#search{width:100%;max-width:580px;height:40px;border:1px solid #89949f;border-radius:8px;padding:8px 12px;background:white}.hint{font-size:12px;color:#59616b;margin:8px 0 24px}.layout{display:grid;grid-template-columns:1fr 290px;gap:24px;align-items:start}.course{display:grid;grid-template-columns:96px 1fr;gap:24px;background:white;padding:24px;border-radius:8px;border:1px solid #d5dbe0;margin-bottom:16px;min-width:0}.art{height:96px;display:grid;place-items:center;border-radius:8px;font-size:40px;color:#005cb9;background:#e7f1fd}.art.orange{background:#fff0d6;color:#805200}.art.green{background:#e6f4ed;color:#236443}.category{font-size:12px;color:#59616b;text-transform:uppercase;letter-spacing:1px}h2{font-size:20px;line-height:28px;margin:4px 0 8px}.course p{font-size:14px;margin:0 0 16px;color:#59616b}.row{display:flex;justify-content:space-between;align-items:center;gap:16px}.row span{font-size:14px;color:#59616b}button{border:0;border-radius:999px;background:#005cb9;color:white;font-size:14px;font-weight:600;padding:8px 16px;cursor:pointer}button:disabled{opacity:.5;cursor:default}button:focus-visible,input:focus-visible{outline:3px solid #005cb9;outline-offset:3px}.plan{padding:24px;background:white;border:1px solid #d5dbe0;border-radius:8px}.plan h2{margin:0 0 16px}.number{font-size:36px;font-weight:700;line-height:1.2}.plan-total{padding-bottom:20px;border-bottom:1px solid #d5dbe0;margin-bottom:20px}.plan-total span{font-size:14px}.plan ul{padding:0;list-style:none;margin:0}.plan li{border-bottom:1px solid #e6e9ed;padding:0 0 16px;margin:0 0 16px;font-size:14px}.remove{background:transparent;color:#005cb9;padding:4px 0;display:block;border-radius:3px;text-decoration:underline;font-weight:400}.empty{font-size:14px;color:#59616b}.boundary{font-size:12px;color:#59616b;margin-top:24px}.no-results{background:white;border:1px solid #d5dbe0;padding:24px;border-radius:8px}@media(max-width:720px){main{padding:0 16px;margin:24px auto}.layout{grid-template-columns:1fr}.course{padding:16px;grid-template-columns:60px 1fr;gap:16px}.art{height:60px;font-size:28px}header span{display:none}.row{align-items:flex-start;flex-direction:column;gap:8px}.plan{padding:20px}}
</style><header><div class="mark" aria-hidden="true"></div><strong>Learning workspace</strong><span>Personal development · Local plan</span></header><main><h1>Make room to grow</h1><p>Choose a few focused lessons for your learning plan.</p><label for="search">Find a course</label><input id="search" type="search" placeholder="Search course titles" aria-describedby="hint"><p id="hint" class="hint">Search filters the catalog; your selected courses stay in the plan.</p><div class="layout"><section id="catalog" aria-label="Course catalog"></section><aside class="plan"><h2>Your local plan</h2><div class="plan-total" role="status"><div class="number" id="minutes">0</div><span>minutes · <span id="count">0</span> <span id="course-word">courses</span></span></div><ul id="selected"></ul><p class="empty" id="empty">Add a course to start your plan.</p><small>No enrollment is submitted.</small></aside></div><p class="boundary">Independent HTML interpretation of Canvas composition patterns. Original palette, course illustrations and content; no Workday account or enrollment service is connected.</p></main><script>const courses=[{id:'feedback',name:'Giving useful feedback',minutes:25,category:'Communication',description:'Practice clear observations and constructive next steps.',art:'◎',color:''},{id:'planning',name:'Planning a focused week',minutes:20,category:'Personal effectiveness',description:'Protect attention and organize a realistic working week.',art:'▤',color:'orange'},{id:'meetings',name:'Running inclusive meetings',minutes:30,category:'Teamwork',description:'Make space for different voices and useful decisions.',art:'◌',color:'green'}];let chosen=new Set;const catalog=document.querySelector('#catalog');function render(){let matches=courses.filter(c=>c.name.toLowerCase().includes(document.querySelector('#search').value.toLowerCase()));catalog.innerHTML=matches.length?matches.map(c=>`<article class="course"><div class="art ${c.color}" aria-hidden="true">${c.art}</div><div><div class="category">${c.category}</div><h2>${c.name}</h2><p>${c.description}</p><div class="row"><span>${c.minutes} minutes</span><button data-add="${c.id}" ${chosen.has(c.id)?'disabled':''}>${chosen.has(c.id)?'Added to plan':'Add to plan'}</button></div></div></article>`).join(''):'<div class="no-results">No matching courses. Try “feedback” or clear your search.</div>';let selected=courses.filter(c=>chosen.has(c.id));document.querySelector('#minutes').textContent=selected.reduce((sum,c)=>sum+c.minutes,0);document.querySelector('#count').textContent=selected.length;document.querySelector('#course-word').textContent=selected.length===1?'course':'courses';document.querySelector('#empty').hidden=selected.length>0;document.querySelector('#selected').innerHTML=selected.map(c=>`<li>${c.name}<button class="remove" data-remove="${c.id}" aria-label="Remove ${c.name}">Remove</button></li>`).join('');document.querySelectorAll('[data-add]').forEach(b=>b.onclick=()=>{let id=b.dataset.add;chosen.add(id);render();document.querySelector('[data-remove="'+id+'"]').focus()});document.querySelectorAll('[data-remove]').forEach(b=>b.onclick=()=>{let id=b.dataset.remove;chosen.delete(id);render();let add=document.querySelector('[data-add="'+id+'"]');(add||document.querySelector('#search')).focus()})}document.querySelector('#search').oninput=render;render();</script></html>
Bir kurs eklemek örnek öğrenme planını değiştirir. Yerel örnek ayrıca CanvasProvider'ı ve bileşik FormField API bileşenini gösterir; kayıt işlemi gönderilmez.
Bileşik alan ve seçilebilir öğrenme öğeleri
FormField giriş ilişkisini oluşturur, TextInput özgün kurs verilerini filtreler ve her PrimaryButton bir öğeyi bir kez ekler. Kaldırma işlemi seçilen toplamı yeniden hesaplar.
jsx
// In a React 18+ application with a bundler:
// npm install @workday/canvas-kit-react @workday/canvas-tokens-web @workday/canvas-kit-styling @emotion/react @emotion/styled
import React,{useState} from 'react';
import {createRoot} from 'react-dom/client';
import {CanvasProvider} from '@workday/canvas-kit-react/common';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {TextInput} from '@workday/canvas-kit-react/text-input';
import {PrimaryButton} from '@workday/canvas-kit-react/button';
import {system} from '@workday/canvas-tokens-web';
import {cssVar} from '@workday/canvas-kit-styling';
import '@workday/canvas-tokens-web/css/base/_variables.css';
import '@workday/canvas-tokens-web/css/brand/_variables.css';
import '@workday/canvas-tokens-web/css/component/_variables.css';
import '@workday/canvas-tokens-web/css/system/_variables.css';
// Default theme example; do not silently add a Sana theme to an existing tenant.
const courses=[{id:'feedback',name:'Giving useful feedback',minutes:25},{id:'planning',name:'Planning a focused week',minutes:20},{id:'meetings',name:'Running inclusive meetings',minutes:30}];
function LearningPlan(){
const [query,setQuery]=useState(''),[chosen,setChosen]=useState([]);
const visible=courses.filter(c=>c.name.toLowerCase().includes(query.toLowerCase()));
const selected=courses.filter(c=>chosen.includes(c.id));
return <main style={{fontFamily:cssVar(system.fontFamily.default),maxWidth:900,margin:'auto',padding:24}}>
<h1>Build a learning plan</h1>
<FormField><FormField.Label>Find a course</FormField.Label>
<FormField.Input as={TextInput} grow value={query} onChange={e=>setQuery(e.target.value)}/>
<FormField.Hint>Filter the three example course titles.</FormField.Hint>
</FormField>
<ul>{visible.map(c=><li key={c.id} style={{margin:'24px 0'}}><h2>{c.name}</h2><p>{c.minutes} minutes</p>
<PrimaryButton type="button" disabled={chosen.includes(c.id)} onClick={()=>setChosen(old=>[...old,c.id])}>
{chosen.includes(c.id)?'Added to plan':'Add to plan'}
</PrimaryButton></li>)}</ul>
{!visible.length&&<p>No matching courses.</p>}
<section aria-label="Learning plan"><h2>Your local plan</h2><p role="status">{selected.length} courses · {selected.reduce((sum,c)=>sum+c.minutes,0)} minutes</p>
<ul>{selected.map(c=><li key={c.id}>{c.name} <button type="button" onClick={()=>setChosen(old=>old.filter(id=>id!==c.id))}>Remove {c.name}</button></li>)}</ul>
<p>No enrollment is submitted.</p></section></main>;
}
createRoot(document.getElementById('root')).render(<CanvasProvider><LearningPlan/></CanvasProvider>);
PrimaryButton her bağımsız kurs öğesine aittir; planın tamamı yanıltıcı bir kayıt eylemi içermez.
Kaldırma işlemi, uygulamaya ait yerel bir düğme kullanır.
Devre dışı Added durumu yinelemeyi önler; canlı sayaç ise değişikliği doğrular.
04
Workday Canvas Tasarım Sistemi Yapay Zekâ Aracısı Kurulumu
Uygulamaya Başlangıç Noktası
Paketlenmiş bir uygulama için eksiksiz React bileşimi. Güncel CanvasProvider ve belirteç CSS kurulumu; özgün kurs verileri ve yerel kaldırma denetimleri. Uzak kayıt işlemi yoktur. Kaynak kod incelendi; bu çalışma alanında paket derlemesi yapılmadı.
jsx
// In a React 18+ application with a bundler:
// npm install @workday/canvas-kit-react @workday/canvas-tokens-web @workday/canvas-kit-styling @emotion/react @emotion/styled
import React,{useState} from 'react';
import {createRoot} from 'react-dom/client';
import {CanvasProvider} from '@workday/canvas-kit-react/common';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {TextInput} from '@workday/canvas-kit-react/text-input';
import {PrimaryButton} from '@workday/canvas-kit-react/button';
import {system} from '@workday/canvas-tokens-web';
import {cssVar} from '@workday/canvas-kit-styling';
import '@workday/canvas-tokens-web/css/base/_variables.css';
import '@workday/canvas-tokens-web/css/brand/_variables.css';
import '@workday/canvas-tokens-web/css/component/_variables.css';
import '@workday/canvas-tokens-web/css/system/_variables.css';
// Default theme example; do not silently add a Sana theme to an existing tenant.
const courses=[{id:'feedback',name:'Giving useful feedback',minutes:25},{id:'planning',name:'Planning a focused week',minutes:20},{id:'meetings',name:'Running inclusive meetings',minutes:30}];
function LearningPlan(){
const [query,setQuery]=useState(''),[chosen,setChosen]=useState([]);
const visible=courses.filter(c=>c.name.toLowerCase().includes(query.toLowerCase()));
const selected=courses.filter(c=>chosen.includes(c.id));
return <main style={{fontFamily:cssVar(system.fontFamily.default),maxWidth:900,margin:'auto',padding:24}}>
<h1>Build a learning plan</h1>
<FormField><FormField.Label>Find a course</FormField.Label>
<FormField.Input as={TextInput} grow value={query} onChange={e=>setQuery(e.target.value)}/>
<FormField.Hint>Filter the three example course titles.</FormField.Hint>
</FormField>
<ul>{visible.map(c=><li key={c.id} style={{margin:'24px 0'}}><h2>{c.name}</h2><p>{c.minutes} minutes</p>
<PrimaryButton type="button" disabled={chosen.includes(c.id)} onClick={()=>setChosen(old=>[...old,c.id])}>
{chosen.includes(c.id)?'Added to plan':'Add to plan'}
</PrimaryButton></li>)}</ul>
{!visible.length&&<p>No matching courses.</p>}
<section aria-label="Learning plan"><h2>Your local plan</h2><p role="status">{selected.length} courses · {selected.reduce((sum,c)=>sum+c.minutes,0)} minutes</p>
<ul>{selected.map(c=><li key={c.id}>{c.name} <button type="button" onClick={()=>setChosen(old=>old.filter(id=>id!==c.id))}>Remove {c.name}</button></li>)}</ul>
<p>No enrollment is submitted.</p></section></main>;
}
createRoot(document.getElementById('root')).render(<CanvasProvider><LearningPlan/></CanvasProvider>);
Projeniz İçin Bir İstem
Ajan İstemi
Mevcut Canvas FormField bileşimini ve token CSS katmanlarını kullanın. Kurs filtrelemesini seçim durumundan ayrı tutun, yinelenen seçimleri engelleyin ve toplam dakikayı hesaplayın. Anlamsal roller aracılığıyla kiracı temasını koruyun; geçmişteki numaralı aralık adlarını güncel tercih edilen kaynak kategorileriyle karıştırmayın.
05
Workday Canvas Tasarım Sistemi Kaynakları ve Kapsamı
Bağımsız OpenDesign referansı. Çalışan kaydı veya Workday API kullanılmaz. Güncel kaynak adları ile eski geçiş adları açıkça birbirinden ayrılmıştır.