Skip to main content

component-composition

How to combine fundamental-styles components correctly - required wrappers, nesting rules, and common composition patterns

Informations de source

Dépôt
SAP/fundamental-styles
Dernière activité de la source
21 mai 2026 à 13:13
Langue détectée de SKILL.md
anglais
Étoiles
235
Forks
73

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
component-composition
description
How to combine fundamental-styles components correctly - required wrappers, nesting rules, and common composition patterns
metadata
{"tags":["composition","structure","nesting","wrappers","patterns"],"keywords":["composition","combine-components","nesting","wrapper-elements","form-item","input-group","popover","dialog-structure","required-wrappers","component-hierarchy","parent-child","structure"]}
# Component Composition This skill explains how to combine fundamental-styles components correctly, including required wrappers, nesting rules, and common composition patterns. ## When to Use This Skill Use this skill when: - The user asks "How do I combine [component A] with [component B]?" - The user needs to understand component structure and nesting - The user asks about required wrapper elements - The user's component isn't working due to incorrect composition - The user asks "Why do I need this wrapper element?" - The user wants to understand parent-child relationships between components --- ## Core Composition Principles ### 1. Always Include Required Wrappers Many components require specific wrapper elements to function correctly: ```html <!-- ❌ Wrong - missing wrapper --> <label class="fd-form-label">Name</label> <input class="fd-input" /> <!-- ✅ Correct - wrapped in form-item --> <div class="fd-form-item"> <label class="fd-form-label">Name</label> <input class="fd-input" /> </div> ``` --- ### 2. Follow the Component Hierarchy Each component has a specific structure - don't skip levels: ```html <!-- ❌ Wrong - missing table__row --> <table class="fd-table"> <tbody class="fd-table__body"> <td class="fd-table__cell">Data</td> </tbody> </table> <!-- ✅ Correct - proper hierarchy --> <table class="fd-table"> <tbody class="fd-table__body"> <tr class="fd-table__row"> <td class="fd-table__cell">Data</td> </tr> </tbody> </table> ``` --- ### 3. Understand Block Independence Each component (block) is independent. Nesting blocks doesn't create a hierarchy: ```html <!-- Both are independent blocks, not parent-child --> <button class="fd-button"> <i class="sap-icon--edit"></i> </button> ``` `.fd-button` and `.sap-icon--edit` are two separate blocks living together, not a parent-child BEM relationship. --- ## Common Composition Patterns ### Form Item Composition **Components:** Form Item + Form Label + Input + Form Message **Structure:** ```html <div class="fd-form-item"> <label class="fd-form-label" for="input-id">Label Text</label> <input class="fd-input" id="input-id" type="text" /> </div> ``` **With validation message:** ```html <div class="fd-form-item"> <label class="fd-form-label fd-form-label--required" for="email">Email</label> <input class="fd-input is-error" id="email" type="email" aria-describedby="email-error" /> <span class="fd-form-message fd-form-message--error" id="email-error"> Invalid email format </span> </div> ``` **Why these wrappers?** - `.fd-form-item` provides spacing and layout structure - Keeps label, input, and message grouped together - Enables proper responsive behavior --- ### Input Group Composition **Components:** Input Group + Input + Button **Basic input group:** ```html <div class="fd-input-group"> <input class="fd-input fd-input-group__input" type="text" placeholder="Search" /> <span class="fd-input-group__addon fd-input-group__addon--button"> <button class="fd-button fd-button--transparent" aria-label="Search"> <i class="sap-icon--search"></i> </button> </span> </div> ``` **With text addon:** ```html <div class="fd-input-group"> <span class="fd-input-group__addon fd-input-group__addon--before">$</span> <input class="fd-input fd-input-group__input" type="number" /> <span class="fd-input-group__addon fd-input-group__addon--after">.00</span> </div> ``` **Why these wrappers?** - `.fd-input-group` establishes flex layout - `.fd-input-group__input` modifier allows input to flex-grow - `.fd-input-group__addon` positions addons correctly - Ensures seamless visual connection between elements --- ### Popover + Menu (Contextual Menu) **Components:** Popover (container) + Button (control/trigger) + Menu (body content) **Structure:** ```html <div class="fd-popover"> <!-- Control/Trigger --> <div class="fd-popover__control"> <button class="fd-button fd-button--transparent" aria-label="More actions"> <i class="sap-icon--overflow"></i> </button> </div> <!-- Body with Menu --> <div class="fd-popover__body" aria-hidden="true"> <nav class="fd-menu"> <ul class="fd-menu__list"> <li class="fd-menu__item"> <a class="fd-menu__link" href="#"> <span class="fd-menu__title">Edit</span> </a> </li> <li class="fd-menu__item"> <a class="fd-menu__link" href="#"> <span class="fd-menu__title">Delete</span> </a> </li> </ul> </nav> </div> </div> ``` **Why this composition?** - `.fd-popover` manages positioning and visibility - `.fd-popover__control` wraps the trigger element - `.fd-popover__body` contains the content (menu, form, etc.) - Separates trigger from content for proper overlay behavior --- ### Dialog Composition **Components:** Dialog + Bar (header/footer) + Title + Button **Structure:** ```html <div class="fd-dialog fd-dialog--active"> <div class="fd-dialog__content"> <!-- Header --> <header class="fd-dialog__header fd-bar fd-bar--header"> <div class="fd-bar__left"> <div class="fd-bar__element"> <h3 class="fd-title fd-title--h5">Dialog Title</h3> </div> </div> <div class="fd-bar__right"> <div class="fd-bar__element"> <button class="fd-button fd-button--transparent" aria-label="Close"> <i class="sap-icon--decline"></i> </button> </div> </div> </header> <!-- Body --> <div class="fd-dialog__body"> <p>Dialog content goes here</p> </div> <!-- Footer --> <footer class="fd-dialog__footer fd-bar fd-bar--footer"> <div class="fd-bar__right"> <div class="fd-bar__element"> <button class="fd-button fd-button--emphasized">Save</button> </div> <div class="fd-bar__element"> <button class="fd-button fd-button--transparent">Cancel</button> </div> </div> </footer> </div> </div> ``` **Why this structure?** - `.fd-dialog` is the overlay container - `.fd-dialog__content` contains all dialog content - `.fd-dialog__header` uses `.fd-bar` for consistent header layout - `.fd-dialog__footer` uses `.fd-bar` for consistent footer layout - `.fd-bar__left` / `.fd-bar__right` position elements - `.fd-bar__element` wraps each item in the bar --- ### Button + Icon + Text **Components:** Button + Icon + Button Text **Icon-only button (no text):** ```html <button class="fd-button fd-button--transparent" aria-label="Edit"> <i class="sap-icon--edit"></i> </button> ``` **Button with icon and text:** ```html <button class="fd-button fd-button--emphasized"> <i class="sap-icon--save" role="presentation" aria-hidden="true"></i> <span class="fd-button__text">Save</span> </button> ``` **Why the difference?** - Icon-only: needs `aria-label` for accessibility (no visible text) - Icon + text: text provides label, icon is decorative (`aria-hidden="true"`) - `.fd-button__text` wrapper allows proper spacing between icon and text --- ### Table + Toolbar + Pagination **Components:** Toolbar + Table + Pagination **Structure:** ```html <!-- Toolbar above table --> <div class="fd-toolbar"> <div class="fd-toolbar__group"> <button class="fd-button fd-button--transparent fd-button--compact"> <i class="sap-icon--add" role="presentation" aria-hidden="true"></i> <span class="fd-button__text">Add</span> </button> </div> </div> <!-- Table --> <table class="fd-table"> <thead class="fd-table__header"> <tr class="fd-table__row"> <th class="fd-table__cell">Name</th> <th class="fd-table__cell">Status</th> </tr> </thead> <tbody class="fd-table__body"> <tr class="fd-table__row"> <td class="fd-table__cell">John Doe</td> <td class="fd-table__cell">Active</td> </tr> </tbody> </table> <!-- Pagination below table --> <div class="fd-pagination"> <nav class="fd-pagination__nav"> <a href="#" class="fd-button fd-button--transparent" aria-label="Previous"> <i class="sap-icon--navigation-left-arrow"></i> </a> <a href="#" class="fd-button fd-button--transparent">1</a> <a href="#" class="fd-button fd-button--transparent is-active" aria-current="page">2</a> <a href="#" class="fd-button fd-button--transparent">3</a> <a href="#" class="fd-button fd-button--transparent" aria-label="Next"> <i class="sap-icon--navigation-right-arrow"></i> </a> </nav> </div> ``` **Why separate components?** - Each is an independent block - Toolbar provides actions for the table
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub