Inventura nativních <button> v apps/web/src — matice A/B/C
Zdroj: node /root/.claude/jobs/d1322dc8/tmp/raw-buttons-full.mjs — 480 <button>, 192 unikátních klíčů tříd, 539 souborů. Referenční kanon pro posouzení vizuální změny (vše apps/web/src/):
.acrm-btn(ds.css:1136): výška--control-h=30px, padding0 var(--sp-4)=12px, border 1px transparent, radius--radius-sm=8px, font 500 13px sans. Varianty primary/default/ghost/danger (ds.css:1157-1201)..icon(ds.css:1202): width=30px, padding 0..acrm-btn.compact(ds/button.css:13): výška--control-h-sm=24px, padding0 var(--sp-3)=8px, gap--sp-2=6px, font--small=500 12px. Ikona 14px (--ico-xs)..compact.icon: width--sp-6=24px, padding 0..acrm-icobtn(ds.css:205): 30×30 (--control-h), radius 8px, bg transparent, barva--fg-secondary(--ink-500), hover--hover-surface, active/open--active-surface, disabled opacity .5..sm(ds.css:241): 24×24 (--control-h-sm)..acrm-icobtn.framed(ds.css:249): 32px šířka (pevná,sizese neuplatní), border 1px--border-strong, bg--surface-100, shadow-xs, barva--ink-700, hover bg--surface-75.- Tokeny:
--radius-md=11px,--sp-2=6px,--sp-3=8px,--sp-4=12px,--sp-6=24px,--field-h=32px,--ico-xs=14px,--ico-sm=16px,--surface-75#fbfbfb/#161719,--surface-100#fff/#1b1c1f,--ink-700#303135/#cccdd1 (packages/ui/src/tokens/tokens.css).
Klasifikace: A — samostatné akční tlačítko re-implementované vlastním stylem (cíl <Button>/ <IconButton>); B — součást kanonického primitivu (menu/popover item, chip, tab, řádek, disclosure, kalendářní buňka, rich-text toggle…), žádná akce potřebná; C — nejasné, patří na stůl Art Directora.
Metodická poznámka: inventura je regex nad literálním textem <button, takže občas zachytí i citaci <button> uvnitř českého JSDoc komentáře (viz sekce „(bez třídy)" níže) a u dynamických className={...} výrazů vytáhne jen první token výrazu, ne skutečnou třídu — u těch je nutné přečíst JSX a dohledat reálnou třídu (např. klíč chip je ve skutečnosti tk-chip/fl-in, klíč entity/dedup je segmentovaný přepínač .acrm-segmented).
A — samostatné akční tlačítko re-implementované (45 tříd)
| Třída | Počet | Umístění (file:line) | CSS pravidlo | Navrhovaný cíl | Vizuální změna |
|---|---|---|---|---|---|
| pdr-ico | 9 | drawer/RecordDrawer.tsx:242,275,310,313,340; pages/BankaPage.tsx:323; DochazkaPage.tsx:539; DokumentyPage.tsx:107; RozpoctyPage.tsx:273 | ds/record-drawer.css:55-72 | <IconButton icon="…"> | ano — barva --fg-muted místo --fg-secondary, disabled opacity .35 místo .5 |
| aichat-act | 5 | components/assistant/AssistantChat.tsx:388,398,408,421; mail/compose/AiThreadPane.tsx:221 | ds/ai-chat.css:205-224 | <IconButton size="sm"> | malá — barva --fg-muted v klidu místo --fg-secondary (rozměr 24×24 sedí) |
| gsp-cancel | 2 | GlobalSearch.tsx:1638; deal/DealSubjectStep.tsx:221 | ds/global-search.css:551-559 | <Button variant="ghost" compact> | ano — žádná fixní výška (jen padding) vs. compact 24px |
| gsp-back | 2 | GlobalSearch.tsx:1664; search/AnswerPane.tsx:107 | ds/global-search.css:570-584 | <Button variant="ghost"> s ikonou | ano — má vlastní border-bottom (hlavičkový řádek), Button ho nemá |
| toast-x | 2 | GoogleConnectBanner.tsx:54; notifications/ToastProvider.tsx:177 | ds/toast.css:108-124 | <IconButton icon="x" size="sm"> | ano — 22×22 neodpovídá žádné DS velikosti (24/30) |
| aichat-prompt-act | 2 | assistant/AssistantPrompts.tsx:498,507 | ds/ai-chat.css:814-826 | <IconButton> | ano — 28px není ani sm(24) ani default(30) |
| acrm-bulkbar-act | 2 | bulk/BulkActionBar.tsx:119,132 | components/bulk/bulk-bar.css:83-112 | <Button variant="ghost"> / variant="danger" | ano — výška 34px (Button 30/24), font-weight 550 vlastní |
| gsp-act | 2 | global-search/PaletteResultsColumn.tsx:381,384 | ds/global-search.css:236-246 | <Button variant="default"> | ne — hodnoty 1:1 s .acrm-btn.default |
| wf-parbtn | 2 | products/PricingSections.tsx:376,435 | ds/orders.css:198-217 | <Button variant="default"> (chybí „pressed/on" tón) | ne pro klid; ano pro .on (žlutý accent, Button pressed nemá) |
| tbar-mark | 2 | CompanyRecordPage.tsx:2579; PersonRecordPage.tsx:1359 | ds.css:2582-2596 | <IconButton icon="star" size="sm"> | ano — hit-box ~26px, focus box-shadow místo outline |
| pr-ico | 2 | DocumentDetailPage.tsx:325; PortfolioBuilderPage.tsx:687 | ds/person-record.css:40-55 | <IconButton icon="…"> | malá — barva --fg-muted vs --fg-secondary |
| fin-cash-doc | 2 | PokladnaDetailPage.tsx:416,441 | ds/finance.css:218-230 | <IconButton icon="receipt" variant="framed"> | ano — 26×26 s borderem vs framed pevných 32px |
| col-new | 1 | components/Board.tsx:215 | ds/board.css:98 | <Button variant="ghost" className="w-full"> | ano — výška 34 vs 30, radius-md vs radius-sm, font display 600/12 vs sans 500/13 |
| fb-add | 1 | components/FilterBar.tsx:504 | ds/filter-bar.css:146 | <Button variant="ghost"> | ano — radius-md vs radius-sm, padding 10px vs 12px, font 12 vs 13 |
| fb-reset | 1 | components/FilterBar.tsx:517 | ds/filter-bar.css:147 | <Button variant="ghost"> | ano — stejně jako fb-add (sdílené pravidlo) |
| sigpad-clear | 1 | components/SignaturePad.tsx:89 | ds/signature-pad.css:35 | <Button variant="ghost" compact> | ano — bez pevné výšky, font-weight 600/12, hover mění barvu textu místo pozadí |
| file-menu | 1 | components/SubjectFilesTab.tsx:185 | ds/person-record.css:617 | <IconButton icon="dots-vertical" size="sm"> | ano, drobně — 26×26 vs 24×24 |
| aichat-slash | 1 | assistant/AssistantChat.tsx:740 | ds/ai-chat.css:609 | <IconButton icon="slash" variant="framed"> | ano — 24px vs framed pevných 32px (framed nemá size) |
| aichat-send | 1 | assistant/AssistantChat.tsx:757 | ds/ai-chat.css:474 | <Button variant="primary" className="icon"> | ano jen v disabled stavu — vlastní surface-75/border-strong/fg-muted vs pouhé opacity .5; klidový/hover stav sedí 1:1 |
| aichat-thread-more | 1 | assistant/AssistantThreads.tsx:144 | ds/ai-chat.css:537 | <IconButton icon="dots-vertical" size="sm"> | ano — 26×26 vs 24×24 |
| acrm-bulkbar-link | 1 | bulk/BulkActionBar.tsx:113 | components/bulk/bulk-bar.css:61 | <Button variant="ghost" compact> | ano — bez pevné výšky, barva accent vs fg |
| acrm-bulkbar-close | 1 | bulk/BulkActionBar.tsx:165 | components/bulk/bulk-bar.css:116 | <IconButton icon="x"> | ne/minimálně — 30×30 = --control-h sedí; hover color-mix(fg 7%) vs token --hover-surface, vizuálně blízké |
| fl-copy | 1 | calendar/EditMeetingForm.tsx:713 | ds/dialog-formless.css:224 | <IconButton icon="copy" size="sm"> | ano — radius-xs vs radius-sm, barva fg-muted vs fg-secondary |
| cell-add | 1 | calendar/MonthGrid.tsx:214 | ds/calendar.css:356 | <IconButton icon="plus" variant="framed" size="sm"> | ano — 20px neodpovídá framed (32px) ani žádné jiné DS velikosti |
| itm-add | 1 | deal/deal-parts.tsx:129 | ds/person-record.css:1316 | <Button variant="ghost"> | ano — výška 32 vs 30, barva fg-secondary vs fg |
| mc-fundx | 1 | mail/compose/PortfolioFields.tsx:204 | components/mail/mail.css:626 | <IconButton icon="x" size="sm"> | ano, drobně — 26 vs 24 (komentář: „1:1 z .rowx") |
| dismiss | 1 | meetings/CrmChangesBlock.tsx:142 | ds/task-list.css:421,441 | <IconButton icon="x" variant="framed" size="sm"> | ano — framed pevných 32px vs 24px, vlastní bordered vzhled |
| approve | 1 | meetings/CrmChangesBlock.tsx:150 | ds/task-list.css:421,445 | <Button variant="primary" compact className="icon"> | minimální — 24px = compact shoda, jen padding/font-weight drobně jiné |
| npanel-link | 1 | notifications/NotifBell.tsx:312 | ds/notifications.css:84 | <Button variant="ghost" compact> | ano — bez pevné výšky, barva accent vs fg |
| npanel-ico | 1 | notifications/NotifBell.tsx:315 | ds/notifications.css:97 | <IconButton icon="x" size="sm"> | ano — 28×28 vs 24×24 |
| all | 1 | notifications/NotifBell.tsx:367 | ds/notifications.css:295 | <Button variant="ghost" className="w-full"> | ano — výška 34 vs 30, radius-md vs radius-sm, barva accent vs fg |
| icobtn | 1 | notifications/NotifBell.tsx:456 | ds/app-shell.css:227 | <IconButton icon="bell"> | ano — šířka --field-h=32px vs 30/24, radius-md vs radius-sm |
| ac-clear | 1 | segment/SegmentBuilder.tsx:210 | ds/segment-screen.css:909 | <IconButton icon="x" size="sm"> | ano — 28px šířka vs 24, bez pevné výšky |
| sgb-clearall | 1 | segment/SegmentBuilder.tsx:1044 | ds/segment-screen.css:1069 | <Button variant="ghost" compact> | ano — žádný border/výška/hover nyní |
| sgb-th-kebab | 1 | segment/SegmentScreen.tsx:905 | ds/segment-screen.css:486 | <IconButton icon="dots-vertical"> | ano — 20×20 vs 24/30, navíc vlastní hover-reveal (opacity 0→1) |
| sgb-ctl | 1 | segment/SegmentScreen.tsx:1592 | ds/segment-screen.css:244 | <Button variant="default"> | ano — radius-md vs radius-sm, font 12 vs 13, padding 8 vs 12 |
| cd-ai-send | 1 | pages/CrmDashboardPage.tsx:125 | ds/crm-dashboard.css:98 | <IconButton icon="arrow-up"> | ano — klidové pozadí accent-tint a plný accent na hover (IconButton má transparent/hover-surface) |
| cd-ctl | 1 | pages/CrmDashboardPage.tsx:477 | ds/crm-dashboard.css:157 | <IconButton icon="dots-vertical" size="sm"> | ne — 24×24, radius-sm, hover-surface sedí |
| fx | 1 | pages/ImportPage.tsx:623 | ds/import.css:258 | <IconButton icon="x" variant="framed"> | ano, drobně — 30px vs framed pevných 32px |
| rowx | 1 | pages/ObchodDetailPage.tsx:555 | ds/person-record.css:1291 | <IconButton icon="x" size="sm"> | ano, drobně — 26×26 vs 24×24 |
| set-back | 1 | pages/settings/SettingsLayout.tsx:227 | ds/settings.css:113 | <IconButton icon="arrow-left" size="sm"> | ano — 26×26 vs 24×24, hover --active-surface místo --hover-surface |
| set-help | 1 | pages/settings/SettingsLayout.tsx:310 | ds/settings.css:208 | <Button variant="ghost" compact> | ano — bez pevné výšky, padding sp-1/sp-2 vs sp-3, barva fg-secondary vs fg |
| as-navtoggle | 1 | components/AppShell.tsx:292 | ds/responsive.css:22-36 | <IconButton icon="menu-2"> | ano — 32×32/radius-md vs 30(24 sm)/radius-sm; záměrně zarovnáno na --field-h k vyhledávání |
| as-icobtn | 1 | components/AppShell.tsx:359 | ds/app-shell.css:184-202 | <IconButton icon="…"> | ano — stejný důvod jako as-navtoggle (--field-h/radius-md) |
Dvě položky navíc potřebují variantu, kterou <Button> dnes nenabízí: dlr-dial (zelený „positive" tón, viz sekci C) a wf-parbtn (pressed/„on" tón) — wf-parbtn je zařazen sem do A, protože klidový stav sedí a jen .on chybí.
B — součást kanonického primitivu (128 tříd)
Popover/menu/option řádek (kanon .acrm-popover-item, ds.css:1963, a příbuzné option-row rodiny): acrm-popover-item (93), acrm-optchip (12, inputs.css:790), acrm-recordselect-opt (9, inputs.css:538), acrm-recordselect-trigger (1, inputs.css:437 — vzhled inputu/kombobox, ne tlačítka), fb-opt (9, filter-bar.css:260), fb-clear (1, filter-bar.css:338 — „kanon dropdownu, řádek 32px jako .acrm-popover-item"), rcpt-opt (2, option řádek příjemce v mail menu), phe-ccrow (2, multi-value.css:178, „1:1 z DS Multi-value editor"), phe-cc (1, multi-value.css:145, spouštěč DialCodePicker), segpick-trigger/segpick-tone/segpick-ic (3, .segpick popover primitiv), o (1) / seg (1) / seg2 (1) / speakerFilter (2) / unreadOnly (2) / dedup (2) — volby v .acrm-segmented skupině (dedup má lokální pill-segmented, ale bucket B jako option).
Chip primitivy (kanonická rodina .tk-chip/.acrm-pill): tk-chip (7, task-dialog.css:158), tchip (6, „kanon Section top bar chip", ds.css:2632), acrm-tag-x (5, inputs.css:940, odstraňovací glyf uvnitř tagu), add-ref (3, dialog-formless.css:392), fb-chip (3, filter-bar.css:39), acrm-fchip-x (3, inputs.css:1001), acrm-rmchip-x (1) / acrm-rmchip-add (1) — demo kanonu na /ds/inputs, pipe-btn (1, kanonický pipeline selector), dlr-chip (2, dialer.css:290, option chip produktů — stejná rodina jako acrm-optchip), chip (1, dynamický klíč → skutečná třída tk-chip, meetings/reminder-select.tsx:50), chip-morph-hit (1, chip-morph.css:36, klikací plocha uvnitř ChipMorph řady), x (2, remove-× v .acrm-pill/.chip), tk-id (1) / wf-id (2) — kopírovací mono-chip afordance, acrm-pill (1, přímé použití kanonické třídy .acrm-pill, ds.css:962), ord-tier (1, orders.css:78 — výběrová dlaždice cenové úrovně, radio-card vzor, ne akce).
Tabs/segmenty/toggly: npanel-tab (2, notifications.css:124, pill tab), sgb-tab (1), eml-tab (2, tablist e-mailového listu), ctype-sw (2) / ctype-main (1, calendar.css:1578-1592, barevný radio přepínač / řádek typu se sourozencem kebab), cal-row (2, checkbox řádek filtru), mgt-cell (2, „button musí vypadat jako obsah tabulky, ne jako tlačítko", merge-table.css:132), sgb-grade (2, „bonita rating ladder — clickable tag toggles"), on (2) / b (1) / i (1) / s (1) — rich-text toolbar toggle v .nt-bub (note-dialog.css:255-285), re-tb (1, mail.css:1126, rich-text toolbar toggle composeru), tl-state (1, task-list.css:220, stavový glyf-přepínač bez rámečku uvnitř řádku úkolu).
Řádky výpisů/karet (row-as-whole nebo title-in-row): cls (2, jádro ItemList.Row), rr-row (1), pr-seg (1, nav-item vzor), sr-hl-row (1, „klikatelný řádek je skutečné <button>"), acc-cls-row (1), jrn-account (1), rooms-room (1, rooms.css:24, „hairline list, žádný box per řádek"), acrm-row (1, přímo kanonická třída), atl-txt (1, DuplicatesPanel.tsx:154, inline-reset — celý název/podnadpis řádku je proklik), mt-sum (1) / mt-hd-main (1) / mt-older (1) — thread.css:92, 180, 260, celé řádky karty zprávy, aichat-mail-row (1) / aichat-mail-foot (1), tl-meeting (1, settings.css:971, translucentní blok schůzky na timeline docházky — vizualizace, ne tlačítko), ptsk-state (1) / ptsk-name (1) — ItemList.Row reset uvnitř ProjectTaskRow, pl-name (1) / pl-val (1) / pl-more (2) — key-value row procesu, stat-stage (1) / cd-ai-model (1) / sgb-sum (2) — PickerMenu-trigger stejné rodiny, hs-drill (1, dialer.css:775, „afordance, ne odkaz pryč" manažerský drill-down), vat-sub-sha (1, accounting.css:814, „kánon kopírovatelné hodnoty, ne tlačítko"), nitem-t (1) / nitem-link (1) — notifications.css:205-244, textová část/odkaz uvnitř položky zvonečku, set-item (1, settings.css:181, položka postranního menu Nastavení — vzor Attio), tmore (1, timeline.css:634, textový odkaz „další" v agregované buňce, stejná rodina jako mr-reclink/hs-drill), prj-msblk-date (1, project-milestones.css:183, tichý spouštěč inline DateField uvnitř řádku milníku).
Kalendář: cwk-allday-ev (2) / cwk-allday-more (2) — kanonický pár celodenních čipů, dp-day (1) / dp-clear (2) / dp-addtime (1) / dp-open (1) — kanonický DatePicker, cell-tasks (1, calendar.css:883, „stejný vzor jako .cwk-allday-more/.more") / more (1, calendar.css:862, kanonický pár s .cwk-allday-more), mb-sd (1, mobilní týdenní pruh), prev (1) / today (1) — AD-schválená výjimka z rodiny Button (ACRM-91/97/103, 27. 9. 2026).
Grafy/vizualizace: sr-ch-mark-btn (1, sales-reports.css:268, značka události pod osou grafu — chart marker, ne UI akce).
AppShell/topbar (nav rail): as-row (1) / as-grp (1) / as-row-chev (1) / as-sub-chev (1) — app-shell.css:311-663, řádky/skupiny navigačního stromu.
FilterBar: fb-conj (1, filter-bar.css:97, logická spojka and/or mezi filtr-chipy, ACRM-50 — bespoke primitiv, ne Button).
**Formless dialog (.fl-*):** fl-in (10) / fl-when (2) — hodnotové řádky, fl-conflict (1, dialog-formless.css:813, značka konfliktu uvnitř .fl-in řádku).
Multi-value editor: rr-ev-tx (2, multi-value.css, telefonní hodnota jako link v RecordRail).
AI chat/asistent: aichat-fup (2, řádek návrhu navazující otázky), aichat-tools-t (1, ai-chat.css:55, boxless textový toggle „ukázat stopu nástrojů"), aichat-ctx-add (1, assistant.css:128, „1:1 .sb-h .a"), aichat-prompt-ico (1, ai-chat.css:724, výběrová dlaždice v mřížce ikon presetů, ne akce).
Sdílený „tichý odkaz" (JEDNA definice sb-h .a, section-block.css:99): a (10), tl-showall (1), dup-link (4, duplicate-panel.css:27), itm-mk (2, person-record.css:1425), mr-reclink (9, meeting-record.css:44), mr-speaker-suggest (1, „týž tvar jako mr-reclink"), ts (1, kombinace ts mr-reclink), chf-errlink (1, record-rail.css:949, „sdílený jazyk odkazů railu").
Record rail: eref-x (1, ds.css:525, „kanonický remove-×, sdílený se .pill .x"), rooms-slot-x (1, rooms.css:208, stejná rodina remove-× jako eref-x), t (1, record-rail.css:89, disclosure toggle titulku sekce railu — stejný vzor jako sb-toggle).
SectionBlock disclosure: sb-toggle (1, section-block.css:61) / sb-peek (1, section-block.css:44) — přesný příklad výjimky „disclosure toggle uvnitř SectionBlock".
Ostatní kanonické/dokumentované vzory: stop (3) / retry (2) — sdílená definice .aichat-err .retry, .aichat-run .stop (ai-chat.css:307-321), nc-composer (1, note-dialog.css:163, note composer v record draweru), note-card (1, note-card.css:68, „port _ds/note-card.css" — kanonická karta poznámky), entity (2, dynamický klíč → segmentovaný přepínač kroku importu), slotClass → pv-val (1) / pv-opt (1) — mail.css:745-761, „1:1 z DS karty Mail compose", chip vyplněného/prázdného slotu v šabloně, pdr-ico (9, drawer/record-drawer.css — POZOR: tato třída je klasifikovaná v A výše jako standalone icon action, zde není duplicitně počítána).
C — nejasné, patří na stůl AD (18 tříd)
| Třída | Počet | Umístění | Proč nejasné |
|---|---|---|---|
| dlr-dial | 2 | pages/DialerPage.tsx:1644,1669 | Reimplementuje tvar .acrm-btn (výška/border/radius shodné), ale barva je vlastní „positive" zelená — Button variantu primary/default/ghost/danger takovou nemá; AD musí rozhodnout nový variant vs. bespoke (ds/dialer.css:463). |
| cside-toggle | 2 | pages/KalendarPage.tsx:1703,1823 | Asymetrický tvar (border-left:0, radius jen na jedné straně), splývá s hranou panelu kalendáře — IconButton takový tvar nemá (ds/calendar.css:202-214). |
| as-modebtn | 1 | components/AppShell.tsx:319 | Spouštěč přepínače modulů + menu (workspace-style trigger, ikona+text+výška --field-h) — kandidát na kanonický MenuButton (!3890), ale rozměr/vzhled se liší; potřeba AD (ds/app-shell.css:81-100). |
| as-search | 1 | components/AppShell.tsx:337 | Vypadá jako vstupní pole (cursor: text, border-strong, bg surface-100), ne tlačítko — nejasné, zda cílem je Button/IconButton, nebo DS Input trigger (ds/app-shell.css:147-160). |
| className | 3 | AppShell.tsx:568; contact-actions/PhoneActionsMenu.tsx:129; meetings/speaker-assign.tsx:68 | Třída je prop předávaná voláním (generický trigger/nav-row) — skutečný vzhled závisí na volajícím, nedohledatelné bez trasování všech callerů v rámci tohoto auditu. |
| as-acctbtn | 1 | components/AppShell.tsx:386 | Account/workspace switcher trigger, pill tvar, výška --field-h=32px — stejná nejistota jako as-modebtn (MenuButton vs. bespoke header trigger), ds/app-shell.css:311. |
| fb-save | 1 | components/FilterBar.tsx:523 | Jediná zvýrazněná akce lišty s podkladem --accent-tint — žádná ze čtyř Button variant takový tón nekreslí (ds/filter-bar.css:172); rozhodnutí je nová varianta, nebo bespoke zůstává. |
| gsp-foot | 1 | components/GlobalSearch.tsx:1702 | 44px CTA patka palety „Zeptat se asistenta", ale NENÍ mobilní touch (ten platí jen ≤720px, tahle patka vždy) a nese vlastní border-top/pozadí „ze schváleného návrhu, 1:1" — nejasné, zda cíl je bespoke řádek, nebo rozšíření touch (ds/global-search.css:252). |
| mc-tplsel | 1 | components/mail/ComposeForm.tsx:3690 | Komentář přímo v CSS říká, že srovnání výšek (32px anatomie Field v railu vs. 30px Button) „je otázka na AD, ne na tenhle MR" (mail.css:511-512). |
| phe-x | 1 | components/multivalue/MvRow.tsx:46 | 20px ikonová afordance je explicitně „1:1 z DS Multi-value editor" (schválená karta, multi-value.css:81-88) — záměna za IconButton size="sm" (24px) by kartu porušila; nutné ověřit u AD, zda karta byla mezitím revidována. |
| phe-copy | 1 | components/multivalue/MvValue.tsx:40 | Totéž: 16px kopírovací afordance „1:1 z DS Multi-value editor" (multi-value.css:289-300), rozměr neodpovídá žádné IconButton velikosti, ale je to záměrná shoda s kartou. |
| prj-msblk-add | 1 | components/projects/ProjectMilestonesSection.tsx:360 | „Tichý řádek jako v Linearu" bez border/bg/výšky (project-milestones.css:205), stejný vzor jako .tl-addrow — nejasné, zda cíl je Button ghost compact, nebo samostatný „quiet add row" primitiv. |
| triggerClass | 1 | components/record/RecordActionsMenu.tsx:340 | Proměnná — komponenta už nabízí kanonickou cestu <IconButton icon="dots-vertical"> o řádek výš; fallback nese cizí třídu (pdr-ico, řešeno zvlášť v A). Rozhodnutí je, zda volající přejít na kanonickou větev. |
| dlg-gen | 1 | components/segment/SegmentBuilder.tsx:786 | AI „Vygenerovat" (fialová, sparkles-2), bez border/bg/výšky (segment-screen.css:1267) — nejasné, zda cíl Button ghost compact, nebo záměrný „AI text action" vzor. |
| shd-empty | 1 | components/segment/ShareDialog.tsx:492 | Přerušovaný rámeček přes celou šířku (segment-screen.css:1861) — vlastní „empty-state add" vzor; nejasné, zda cíl Button ghost/w-full, nebo zůstat u dashed vzoru. |
| dlr-lock-ext | 1 | pages/DialerPage.tsx:1162 | Text akce „Prodloužit" uvnitř útlé pilulky odpočtu zámku (dialer.css:217), bez border/bg/výšky — nejasné, zda tam Button chrome vůbec patří. |
| dlr-lock-cancel | 1 | pages/DialerPage.tsx:1170 | Totéž pro „Zrušit" (barva na hover → critical, dialer.css:231) — stejná nejistota. |
| drop | 1 | pages/ImportPage.tsx:591 | Celá drop-zone (ikona+text+hint, přerušovaný rámeček, drag&drop, import.css:183) — není akční tlačítko ani položka primitivu, spíš samostatný DS vzor „upload dropzone" bez kanonu. |
Speciální bucket „(bez třídy)" / dynamický klíč (62 výskytů)
Vzorkováno ~35 z 62 lokací napříč dvěma nezávislými prověrkami. Zjištění:
- Naprostá většina jsou FALSE POSITIVES regexu, ne skutečná netříděná tlačítka: skript hledá literální text
<buttona tento kodebase hojně cituje<button>v českých JSDoc/inline komentářích vysvětlujících, proč komponenta používá<span role="button">nebo naopak proč NEpoužívá<button>(např.components/AppShell.tsx:534,components/Board.tsx:249,components/ItemList.tsx:184/187/192/263/274/369,components/GlobalSearch.tsx:20/262,components/deal/DealRail.tsx:464,components/dialog/MetaChip.tsx:9/37,components/mail/EmailRow.tsx:148,components/notes/ChipMorph.tsx:15,components/notifications/NotifBell.tsx:194,components/relations/RelationRow.tsx:63,components/company/CompanyMergeTable.tsx:335) — na daném řádku není žádný skutečný JSX<button>. Odhad ze vzorku: cca 70–75 % bucketu jsou takové artefakty. - Několik je skutečných tlačítek, ale s třídou, kterou jednoduchý regex nezachytil kvůli složitějšímu atributu před
className(např.ref={...}nebo více atributů na řádku):components/FilterBar.tsx:447je ve skutečnostifb-chip(kanonický, B);components/company/CompanyMergeTable.tsx:319jemgt-cell(B);components/drawer/RecordDrawer.tsx:310/313jepdr-ico(A, jen jiný řádek téhož souboru);components/record/RecordActionsMenu.tsx:339jetriggerClass(C, řešeno výše). - Několik je skutečně bez CSS třídy, stylováno inline
style={}— legitimní B (volba/option, ne akce): barevný výběr týmu (pages/TeamDetailPage.tsx:456,pages/TymyPage.tsx:114— swatch barev týmu,aria-pressed), disclosure toggle oprávnění (pages/settings/ModuleRights.tsx:122), výběr osoby v řádku (pages/settings/OpravneniLide.tsx:75). - Jediný nalezený nezpochybnitelný „bez třídy" A-kandidát:
pages/KalendarPage.tsx:677a:685(.czoom button— kolečka zoomu +/− v týdenním pohledu kalendáře,ds/calendar.css:1327: 24×24, radius-pill, bordered, shadow-sm). Komentář u nich (ACRM-89) říká, že jsou ZÁMĚRNĚ menší/jiné než ghost tlačítka navigace vedle nich, ale bez explicitního AD razítka jako u výjimkyprev/today→ zařazeno raději do C než A: „vlastní zoom-kolečka, dokumentované inženýrské zdůvodnění, ale bez AD podpisu." pages/KalendarPage.tsx:1586(„next" šipka) — bez třídy, ale sdílí selektor.nav button:not(.today)se sourozenciprev/today(schválená výjimka rodiny Button, ACRM-91/97/103) → B.
Závěr k „bez": nebyl nalezen žádný nezpochybnitelný A-kandidát mimo dvojici .czoom button (klasifikováno jako C kvůli chybějícímu AD razítku). Doporučení pro budoucí inventury: opravit regex skriptu, ať vylučuje řádky uvnitř /* ... */ a // ... komentářů — sníží to šum v tomto bucketu z ~62 na odhadem ~15-18 skutečných výskytů.
Totals
| Bucket | Počet tříd |
|---|---|
| A | 45 |
| B | 128 |
| C | 18 |
| „bez" (speciální, viz výše) | 1 (62 výskytů, ~70-75 % false positives regexu) |
| Celkem tříd | 192 |
Source: docs/button/INVENTURA-nativni-button-2026-09-28.md · GitLab