FluentUI: osnovni katalog gradnikov
Nazaj: FluentUI (knjižnica oblikovalskega sistema)
Stanje: od celovite razširitve (2026-07-14) je jedrni
nabor kataloga dosledno Tier 1 — Button, Dropdown, SelectBox,
SplitView (primitiv CSS), ProgressBar, Hover/Tooltip, CountBadge,
DeclarativeTable in Card/Tile so uveljavljeni kot metode
helper_plugin_wkfluentui_widgets oz. pogodbe CSS/atributov (navedeno
po vrstici); zavezujoča pogodba metod je v
FluentUI: javni API pomočnika. Od razširitve Studia
(2026-07-14) so tudi štirje gradniki, ki jih vodi Studio, v odseku spodaj
(filter InputBox, vrstica zavihkov urejevalnika, paleta ukazov,
maksimiranje podokna) Tier 1 — prvi porabnik je SQLite Data Studio
(wksqliteds).
Viri: VS Code (https://github.com/microsoft/vscode, pot
src/vs/base/browser/ui/**, osnovni gradniki) in Azure Data Studio
(https://github.com/microsoft/azuredatastudio, pot
src/sql/**, razširitve obrazcev/pogovornih oken/mrež, ki jih v
osnovnem VS Code ni) — oba javna, odprtokodna repozitorija.
Tabela gradnikov
| Gradnik | Razred VS Code | Osnovni razred CSS | Besednjak stanj | ARIA | Izvedba | |
|---|---|---|---|---|---|---|
| Button | Button, ButtonWithDropdown | .monaco-button (+.secondary/.small) | disabled, hover, focus, checked | role=„button“, aria-pressed, aria-disabled | Tier 1: widgets::button() (različice primary/secondary/outline/danger/link, pogovorno okno za potrditev) + osnovni CSS .wk-btn — poglobitev: Polja obrazca: Button | |
| InputBox | InputBox, HistoryInputBox | .monaco-inputbox (+.idle/.info/.warning/.error) | idle/info/warning/error, disabled, empty | aria-label, aria-invalid | Tier 1: metrika polja .wk-field__input + pogodba stanja/ARIA osnovne pogodbe polja; prosto besedilo s seznamom prek comboBox(allowUserInput) — poglobitev: predstavitveni portal polj obrazca | |
| Dropdown | BaseDropdown, DropdownMenu | .monaco-dropdown | active (odprto), disabled | aria-haspopup, aria-expanded | Tier 1: widgets::dropdown() (osnova details/summary + preslojen JS) — poglobitev: Polja obrazca: Dropdown Editor | |
| SelectBox | SelectBox (nativno/po meri) | .monaco-select-box | disabled option, expanded | aria-label, role=„separator“ | Tier 1: widgets::comboBox() / widgets::listEditor() — poglobitev: Polja obrazca: Combo Box | |
| List/Tree | List<T>, ObjectTree/DataTree | .monaco-list, .monaco-list-row | focused, selected, hover, drop-target, dragging | role=„list“/„listbox“/„treeitem“, aria-activedescendant, aria-level | Tier 1: widgets::tree() — drevo <details>/<summary>, z izbiro (radijski gumb/potrditveno polje, nabor role=tree), preurejanjem (▲/▼ + plast vlečenja) in skrčitvijo na ikone; predstavitveni portal: treeview | |
| ActionBar/Toolbar | ActionBar, ToolBar | .monaco-action-bar, .monaco-toolbar | disabled, vertical/horizontal, responsive-overflow | role=„toolbar“, tipkovnični roving tabindex | Tier 1: widgets::toolbar() + scripts/toolbar.js — s skupinami ribbon (groupLabel/size) in izbirnim prelivom | demo portal: toolbar |
| SplitView/Sash | SplitView, Sash | .monaco-split-view2, .monaco-sash | disabled, hover, active (vlečenje), orthogonal | — | Tier 1 (primitiv CSS): .wk-splitview + __pane--fixed (nativni resize) / __pane--fill — namenoma brez motorja JS sash | |
| ProgressBar | ProgressBar | .monaco-progress-container | active, done, infinite, discrete | role=„progressbar“, aria-valuenow | Tier 1: widgets::progressBar() + wkProgressBar.setValue() — poglobitev: Polja obrazca: Progress Bar | |
| Menu/ContextMenu | Menu, ContextView | .monaco-menu, .context-view | focused, checked | role=„menuitem“/„menuitemcheckbox“ | Tier 1 (podnabor): widgets::rowActions() + scripts/contextmenu.js — postopno, sproži le že obstoječe elemente, brez nove poti pisanja | |
| Hover/Tooltip | HoverWidget | .monaco-hover | fade-in, hidden, disabled (dejanje) | role=„tooltip“ | Tier 1: pogodba atributa data-wk-tooltip + scripts/tooltip.js (lebdenje in fokus, sklopitev aria-describedby, escape) | |
| CountBadge | CountBadge | .monaco-count-badge (tabletka, radij 11px) | različica „long“ | — | Tier 1: widgets::countBadge() (tabletka + –long, obvezno besedilo za bralnik zaslona) — edini vir značk, navBar() prenese sem | |
| Modal/Dialog (ADS) | osnovni razred Modal | .modal.normal-dialog (640px) / .modal.flyout-dialog (500/800/1200px) | — | standardna ARIA za pogovorna okna | Tier 1 (različica 640px): widgets::drawer() (ob strani) + widgets::modal() (wk-modal–normal, na sredini) | |
| FormLayout (ADS ModelView) | formContainer/groupContainer | .form-table/.form-row/.form-cell-title (stolpec oznak 129px) | required (rdeča zvezdica), zložljiva skupina | podobno <fieldset> | Tier 1 (jedrna mreža): widgets::propertyGrid() — mreža CSS fit-content(22rem) minmax(0, 1fr), brez required-zvezdice/zložljive skupine | |
| DeclarativeTable (ADS) | declarativeTable | .declarative-table | urejljive celice | — | Tier 1: widgets::declarativeTable() — nativna polja obrazca po celici ({name}[{i}][{key}]), pošlje brez JavaScripta | |
| Card/Tile (ADS) | komponenta card | .model-card (radij 8px, edina bolj zaobljena izjema sicer v 2px-ploskem sistemu) | značka stanja/izbire (radij 50 %) | — | Tier 1: widgets::card() (.wk-card, radius-lg, značka stanja, vrstica noge) | |
| Table/Designer (ADS) | Table(SlickGrid) + designer.ts | .monaco-table, .components-grid | puščice razvrščanja, meni filtra stolpcev | najboljša najdba za „hibrid obrazca in podatkovne mreže„ | Tier 2 (koncept) — porabnik Table Designer wksqliteds gradi na propertyGrid() + tabs(); predstavitveni portali: property-grid, tabcontrol, treelist | |
| Filter InputBox (ADS/VS Code) | InputBox kot filter seznama | .wk-listfilter | empty, focused, no-match | aria-controls + živo območje | Tier 1: widgets::listFilter() + scripts/listfilter.js — pogodba spodaj: inputbox-filter | |
| Vrstica zavihkov urejevalnika (ADS/VS Code) | EditorTabsControl | .wk-editortabs | active, dirty, disabled | role=„tablist“ | Tier 1: widgets::editorTabs() + scripts/editortabs.js — pogodba spodaj: editor-tab-strip | |
| Paleta ukazov (VS Code) | QuickInput/QuickOpen | .wk-cmdpalette | empty, filtered, no-match | pogovorno okno + listbox | Tier 1: widgets::commandPalette() + scripts/cmdpalette.js — pogodba spodaj: command-palette | |
| Maksimiranje podokna (VS Code) | razred postavitve maximized | .wk-shell-panel--max | maksimirano/normalno | stikalni gumb | Tier 1: pogodba atributa data-wk-panelmax + scripts/panelmax.js — pogodba spodaj: panel-maximieren |
Gradniki, ki jih vodi Studio (Tier 1)
Štirje gradniki, na katere se sklicuje inventar dejanj SQLite Data Studio
(stran območja Studia (samo v nemščini)) — prvotno
opredeljeni kot pogodba [T2], uveljavljeni in vključeni v Studio
od razširitve Studia (2026-07-14). Imena razredov (wk-*), ki so bila
prej označena kot „predlog“, so z izvedbo postala zavezujoča. Odprta
specifikacijska vprašanja po posameznem gradniku so zdaj odločena in
dokumentirana v ustreznem odseku. Referenca mehanike: Azure Data
Studio (https://github.com/microsoft/azuredatastudio) / VS Code
(https://github.com/microsoft/vscode): navedeno kot
rekonstruirana mehanika, ne prevzem kode.
Filter InputBox
Tier 1 (widgets::listFilter($targetId, $opts) + scripts/listfilter.js) ·
Referenca: src/vs/base/browser/ui/tree/abstractTree.ts
(filter drevesa prek InputBox), src/vs/base/browser/ui/list/listWidget.ts.
Namen + razmejitev. Enovrstično filtrirno polje pod naslovno vrstico Object Explorerja, ki vidne vozle drevesa zoži na zadetke (podniz, neobčutljivo na velike/male črke). Ni pogovorno okno za iskanje (brez podokna rezultatov, brez celobesedilnega iskanja po vsebini) in ni nadomestilo za iskanje na strani strežnika — le prikazuje/skriva že naložene vozle drevesa.
Anatomija.
<div class="wk-listfilter"> <input type="search" class="wk-listfilter__input" aria-controls="objtree" placeholder="Filtriraj …"> <span class="wk-listfilter__count" role="status" aria-live="polite">7 od 20</span> </div> <ul id="objtree" class="wk-tree"> … filtrirano drevo … </ul>
Stanja. prazno (brez filtra, vsi vozli vidni) · fokusirano · aktivno filtrira (nezadetki skriti) · no-match (prazno drevo + zamolklo vrstica „ni zadetkov„).
Tipkovnica + ARIA. Polje kot <input type=„search“> z
aria-controls na id drevesa; število zadetkov je v območju
role=„status“ aria-live=„polite“, tako da je zmanjšanje napovedano.
Esc izprazni filter in vrne fokus na drevo, puščica dol skoči iz
polja na prvi zadetek. Drevo ohrani svojo semantiko treeitem — filter
spremeni le hidden.
Nadomestilo brez JS. Degradira na nič (brez JavaScripta se ne izriše oz. je brez učinka) — „najti vozel“ ostane dosegljivo prek razširitve drevesa. Filter ni nikoli edini način dostopa do vozla.
Odločeno. (a) Brez poudarjanja zadetkov v besedilu vozla v v1
(namenoma minimalistično; naknadno nadgradljivo brez kršitve pogodbe). (b)
Filter deluje na celotno drevo, povezano prek aria-controls; primerja
se lastna oznaka vsakega vozla (neposredna povezava oz. povzetek
skupine), ne besedilo poddrevesa — sicer bi vsak prednik štel kot zadetek.
© Porabniki, ki zamenjajo ciljni DOM (npr. ponovno nalaganje auxbarja),
sprožijo dogodek wk-listfilter-rescan na ovojnici; trenutni filter
se nato znova uveljavi.
Vrstica zavihkov urejevalnika
Tier 1 (widgets::editorTabs($tabs, $opts) + scripts/editortabs.js;
upravljanje medpomnilnikov Studia: wksqliteds/script.js) · Referenca: src/vs/workbench/browser/parts/editor/
(editorTabsControl.ts, tabsTitleControl.ts — vrstica zavihkov,
indikator umazanega stanja, zapiranje).
Namen + razmejitev. Več hkrati odprtih poizvedb v delovnem prostoru
kot zavihki urejevalnika s piko umazanega stanja (neshranjena
sprememba). Razmejiti od zavihkov pogleda Table Designerja
(stolpci/indeksi/tuji ključi/sprožilci — to je tabs()-role=tablist
za preklop pogleda, glej tabcontrol):
vrstica zavihkov urejevalnika preklaplja dokumente (vsak zavihek
lasten SQL medpomnilnik), ne poglede istega predmeta.
Anatomija.
<div class="wk-editortabs" role="tablist" aria-label="Odprte poizvedbe"> <div class="wk-editortabs__tab is-active" role="tab" aria-selected="true"> <span class="wk-editortabs__title">poizvedba1.sql</span> <span class="wk-editortabs__dirty" aria-hidden="true">•</span> <button class="wk-editortabs__close" aria-label="Zapri">×</button> </div> <div class="wk-editortabs__tab" role="tab" aria-selected="false"> … </div> </div>
Stanja. active (v ospredju) · dirty (neshranjeno — pika namesto/nad × zaprtja) · disabled (ni preklopljivo, npr. med potekajočo izvedbo).
Tipkovnica + ARIA. role=„tablist“ z otroki role=„tab“,
aria-selected; roving tabindex, puščica-levo/-desno preklopi,
Delete/srednji klik zapre. Namenoma razmejeno od tablist
zavihkov pogleda Designerja, da bralniki zaslona ne zamenjajo „zavihkov
dokumenta„ z „zavihki pogleda“ (drugačen aria-label).
Nadomestilo brez JS. Degradira na eno poizvedbo (vrstica izgine, delovni prostor prikaže en sam SQL medpomnilnik) — izvedba ene poizvedbe prek POST-vračanja ostane nespremenjeno dosegljiva.
Odločeno (obstojnost: odločitev uporabnika 2026-07-14). (a)
localStorage po prijavi pod wk-editortabs:<login>
(kanonični ključ prek wkEditorTabs.storageKey()): zgolj preferenca
prikaza — strežnik ostane brez stanja in še naprej vidi le en poslan
medpomnilnik; vsebino medpomnilnikov upravlja porabnik (knjižnica
upravlja vrstico in sproža dogodka wk-tabchange/wk-tabclose,
slednjega je mogoče preklicati prek preventDefault). (b) Brez trde
zgornje meje; vrstica se vodoravno drsi (overflow-x). © Po
povezavi (povezovanje Studia: pripona ključa :<conn>) — SQL
medpomnilniki so specifični za povezavo. Zadnjega preostalega zavihka ni
mogoče zapreti.
Paleta ukazov
Tier 1 (widgets::commandPalette($opts) + scripts/cmdpalette.js) ·
Referenca: src/vs/platform/quickinput/browser/
(quickInput.ts), src/vs/workbench/contrib/quickaccess/.
Namen + razmejitev. Splošen preklop dejanj/navigacije (vzorec Ctrl+Shift+P): osrednje vnosno polje filtrira seznam vseh dosegljivih dejanj/ciljev skoka. Ni nadomestilo za menije/ukazno vrstico (ti ostanejo primarno, vidno upravljanje) in ni iskanje podatkov — naslavlja dejanja, ne vsebino.
Anatomija.
<div class="wk-cmdpalette" role="dialog" aria-modal="true" aria-label="Ukazi"> <input class="wk-cmdpalette__input" role="combobox" aria-expanded="true" aria-controls="cmdlist" aria-activedescendant="cmd-3"> <ul id="cmdlist" class="wk-cmdpalette__list" role="listbox"> <li id="cmd-3" role="option" aria-selected="true">Izvozi tabelo …</li> <li role="option">Izberi povezavo …</li> </ul> </div>
Stanja. prazno (vsa dejanja) · filtrirano · no-match („Ni ustreznega dejanja„).
Tipkovnica + ARIA. Kombinacija pogovorno okno + listbox:
role=„dialog“ aria-modal=„true“ okoli polja role=„combobox“, ki
prek aria-activedescendant kaže na aktivno vrstico role=„option“
znotraj role=„listbox“. Puščica gor/dol se premika, Enter
sproži, Esc zapre in vrne fokus na sprožilec; fokus ostane ujet v
prekrivnem oknu. Predlagana tipka za odpiranje: Ctrl+Shift+P —
označeno kot predlog (možen spor z brskalnikom/razširitvijo, preveriti pri
izvedbi).
Nadomestilo brez JS. Degradira na nič — vsako dejanje palete je dodatno dosegljivo prek menija, ukazne vrstice ali raila modula (paleta je zgolj pospešek, nikoli edina pot).
Odločeno. (a) Tipka za odpiranje Ctrl+Shift+P kot predlagano —
dokumentiran spor (Firefox: zasebno okno) ostaja, zato je vidni sprožilec
(gumb data-wk-palette-trigger, ki ga script.js v Studiu
vstavi v ukazno vrstico) pot brez spora. (b) Register dejanj nastane
dinamično iz DOM-a ob vsakem odpiranju: vsak viden element z
data-wk-cmd postane možnost (vrednost atributa = oznaka, prazna
vrednost = besedilo elementa); Enter znova sproži izvirni element
prek .click() — brez druge kodne poti, strežniško filtriranje
ACL/samo-za-branje vidnega markupa ostaja merodajno. © Obseg = aktivni
pogled (le tam obstaja viden, označen markup) — dejanja med moduli so
zato namenoma izven obsega.
Maksimiranje podokna
Tier 1 (pogodba atributa data-wk-panelmax + scripts/panelmax.js
+ CSS-območje .wk-shell-panel) · Referenca: src/vs/workbench/browser/layout.ts (razred
postavitve maximized, stikalo podokna); razredi vidnosti glej
FluentUI: osnovna postavitev podrobno.
Namen + razmejitev. Začasno preklopiti podokno rezultatov delovnega
prostora na polno višino vsebine (več vrstic brez drsenja). Ni celozaslonski
način (brez fullscreen izven lupine) in ni novo okno — raste le
območje podokna, ukazna vrstica/vrstica stanja/rail ostanejo.
Anatomija.
<div class="wk-shell-panel wk-shell-panel--max"> <div class="wk-shell-panel__header"> <span>Rezultati</span> <button class="wk-shell-panel__maximize is-active" aria-pressed="true" aria-label="Maksimiraj podokno">⤢</button> </div> <div class="wk-shell-panel__body"> … mreža rezultatov … </div> </div>
Stanja. normalno · maksimirano (modifikator
.wk-shell-panel--max na območju podokna; stikalni gumb dobi
.is-active).
Tipkovnica + ARIA. Stikalni gumb z aria-pressed (vklop/izklop
ohranjenega stanja) — namenoma ne aria-expanded (to bi opisovalo
razširitev/skrčitev skrite vsebine; tu se le poveča vidna vsebina).
Enter/Presledek preklopi, fokus ostane na gumbu.
Nadomestilo brez JS. Ne velja — brez JavaScripta ni maksimiranja; podokno ostane v normalni velikosti (povsem funkcionalno, le brez povečave).
Odločeno. (a) aria-pressed potrjeno — stikalo hrani stanje
vklop/izklop vidne vsebine, aria-expanded bi opisoval razkrivanje
skrite vsebine. (b) Da, kot preferenca prikaza po kontekstu:
localStorage wk-panelmax:<context> (kontekst = vrednost
atributa gumba; prazna vrednost = brez obstojnosti) — enak vzorec kot
velikost pogovornega okna delovnega prostora. © Maksimirano podokno
zapolni svoj pozicijski kontekst (.wk-shell-content, ki ima za to
position:relative v CSS-ju knjižnice) in začasno prekrije notranjo
delitev drsenja; ukazna vrstica, vrstica stanja in raili ostanejo vidni —
smernica prilagoditve vidnemu polju
(FluentUI: skrbniško območje podrobno) velja nespremenjeno, brž
ko se stikalo povrne.
Besednjak stanj (dosledno)
disabled, hover, focus/focused, active, checked/selected,
error/warning/info, expanded/collapsed, dragging/drop-target.
Konvencija poimenovanja razredov: koren monaco-<widget> z
modifikatorskimi razredi (brez formalnega BEM –modifier). Za
wkfluentui analogno predlagano: koren wk-<widget> z istimi
imeni modifikatorjev, da se uveljavljeni besednjak stanj prevzame 1:1.
Mehanika tematiziranja (referenca za prihodnji modul registra tokenov)
Troslojni model: (1) osrednji register barv/velikosti s privzetimi
vrednostmi za svetlo/temno/visok kontrast
(registerColor()/registerSize()), (2) mehanska izpeljava imena
domain.property → –vscode-domain-property, (3) EN generiran
slogovni list, omejen na korenski vsebnik, ki materializira vrednosti
aktivne teme. Uporablja se bodisi neposredno prek CSS var() bodisi
prek tipiziranega „objekta slogov“, ki se posreduje konstruktorju
gradnika (uporabno, kadar mora isti gradnik izrisovati v različnih barvnih
prostorih). Glej FluentUI: oblikovalski tokeni za
preprostejšo različico, dejansko uveljavljeno v wkfluentui (statični
tokeni –wk-* brez ravni registra, Tier 1).