docs: add UI/UX component guidelines and improve breadcrumb/tab-panel styling
Add "Komponenten in Formularen" section to boundaries-ui.md with rules for core button classes, margin resets, checkbox sizing, sticky positioning, icon-only buttons, responsive grids, and CSS variables. Add matching quick-reference bullets to CLAUDE.md UI Patterns section. Fix breadcrumb wrapping: nowrap + overflow hidden + flex-shrink for single-line behavior. Add data-tab-panel-wide opt-out for full-width tab panels (default 70ch). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -58,3 +58,13 @@
|
||||
2. MUST NOT globale unscoped Overrides ohne klaren Scope einfuehren.
|
||||
3. MUST Vendor-Overrides nur in `web/css/vendor-overrides/**` pflegen.
|
||||
4. MUST bestehende CSS-Variablen bevorzugen statt neue Inline-Farbwerte zu verteilen.
|
||||
|
||||
## Komponenten in Formularen
|
||||
|
||||
1. MUST Core-Button-Klassen (`secondary outline small`, `danger outline small`) verwenden statt Custom-Button-CSS. Custom-CSS nur fuer Layout (z.B. `border-radius: 50%`).
|
||||
2. MUST `margin-bottom: 0` auf Buttons, Inputs, Selects und Labels innerhalb selbststaendiger Komponenten in Formularen resetten (Core setzt `margin-bottom: var(--app-spacing)` global).
|
||||
3. MUST Checkboxen in Flex-Containern mit expliziter Groesse (`width: 1.25em; height: 1.25em`) und `flex-shrink: 0` versehen (Core nutzt `appearance: none` mit Custom-Sizing).
|
||||
4. MUST `position: sticky` mit `top: calc(var(--app-topbar-height) + ...)` verwenden, nicht `top: 0` (Topbar ist sticky).
|
||||
5. MUST Icon-Only-Buttons mit `data-tooltip` und `aria-label` versehen.
|
||||
6. MUST bei `grid-template-columns` mit mehr als einer Spalte ein `@media`-Fallback auf Single-Column definieren.
|
||||
7. MUST bestehende `--app-*` CSS-Variablen fuer Farben verwenden, nie Farbwerte hardcoden.
|
||||
|
||||
@@ -159,6 +159,7 @@ docker/ # Dockerfiles, Nginx configs, PHP configs
|
||||
### UI Patterns
|
||||
|
||||
- Edit pages: tabs → `Master data` | `Visibility` | optional `Danger zone`
|
||||
- **Tab panel width**: `data-tab-panel` defaults to `max-width: 70ch` (optimal for form readability). Add `data-tab-panel-wide` for panels that need full width (e.g. split layouts, side-by-side editors, preview panels, tables). Use 70ch for standard form fields (text inputs, selects, textareas); use wide for multi-column layouts or content that benefits from horizontal space.
|
||||
- Titlebar partial for primary actions (Save, Save & close)
|
||||
- Secondary actions in Aside block via `app-details-aside-actions.phtml`
|
||||
- Lists use Grid.js via `initStandardListPage()` (GR-UI-LIST)
|
||||
@@ -166,6 +167,9 @@ docker/ # Dockerfiles, Nginx configs, PHP configs
|
||||
- New views must handle loading, empty, error, and success states (GR-UI-014)
|
||||
- All visible text wrapped in `t('...')`
|
||||
- Check existing JS/CSS components before adding new ones (GR-UI-REUSE)
|
||||
- **Buttons**: Always use core classes (`secondary outline small`, `danger outline small`) — custom CSS only for shape/position. Icon-only buttons must have `data-tooltip` + `aria-label`.
|
||||
- **Components inside forms**: Reset core `margin-bottom` on buttons/inputs/selects/labels at component scope. Checkboxes in flex need explicit `1.25em` sizing + `flex-shrink: 0`.
|
||||
- **Sticky elements**: Always use `top: calc(var(--app-topbar-height) + ...)` — never `top: 0`. Multi-column grids must have a responsive single-column `@media` fallback.
|
||||
- **File uploads** use `app-file-upload.phtml` partial (deliberate exception to plain-HTML inputs — the markup is too complex for inline use). See `templates/partials/app-file-upload.phtml` for the `$fileUpload` array contract. Never write file-upload markup inline; always use the partial.
|
||||
|
||||
### Never Do This
|
||||
|
||||
@@ -26,7 +26,7 @@ $handoverSchemaFields = is_array($handoverSchemaFields ?? null) ? $handoverSchem
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div data-tab-panel="handover-protocol">
|
||||
<div data-tab-panel="handover-protocol" data-tab-panel-wide>
|
||||
<div class="handover-schema-split">
|
||||
<div class="handover-schema-split-editor">
|
||||
<div
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
min-width: 0;
|
||||
font-size: var(--text-xs);
|
||||
line-height: var(--leading-tight);
|
||||
}
|
||||
@@ -16,11 +17,13 @@
|
||||
.app-breadcrumb ol {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
flex-wrap: nowrap;
|
||||
gap: 0.375rem;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.app-breadcrumb li {
|
||||
@@ -28,6 +31,13 @@
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
min-width: 0;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
.app-breadcrumb li:first-child,
|
||||
.app-breadcrumb li:last-child {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.app-breadcrumb li::before {
|
||||
@@ -40,12 +50,13 @@
|
||||
font-size: 0.75em; /* em-relative sizing — intentional */
|
||||
margin-inline-end: 0.375rem;
|
||||
pointer-events: none;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.app-breadcrumb a,
|
||||
.app-breadcrumb [aria-current="page"] {
|
||||
display: inline-block;
|
||||
max-width: 18ch;
|
||||
max-width: 14ch;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
max-width: 70ch;
|
||||
}
|
||||
|
||||
.app-details-container > section > form [data-tab-panel-wide] {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.app-details-aside-actions {
|
||||
display: grid;
|
||||
gap: calc(var(--app-spacing) * 0.5);
|
||||
|
||||
Reference in New Issue
Block a user