--- name: ui5-best-practices description: | UI5 development best practices and coding standards derived exclusively from official SAP UI5 guidelines. Use when writing UI5 applications to ensure modern, maintainable code following SAP standards. Covers: async module loading (sap.ui.define, ES6 imports, core:require), ComponentSupport initialization, data binding with OData types, i18n management, CSP compliance (no inline scripts), TypeScript event types (UI5 >= 1.115.0), MCP tooling (get_api_reference, run_ui5_linter), CAP integration patterns, and form creation rules (never SimpleForm, always Form with ColumnLayout). Keywords: ui5 coding standards, async loading, sap.ui.define, data binding, odata types, i18n translation, CSP no inline scripts, TypeScript event handlers, Button$PressEvent, ui5 linter, API reference, ComponentSupport, form layout, ColumnLayout, CAP integration, cds watch --- # UI5 Best Practices and Coding Standards ## Overview This skill enforces UI5 development standards derived from official SAP guidelines. It covers the four critical areas: coding guidelines, tooling integration, CAP integration, and form creation rules. --- ## 1. Module Loading - CRITICAL ### Never Use Global Access **NEVER** access UI5 framework objects globally (e.g., `sap.m.Button`). Always declare dependencies explicitly for asynchronous loading. #### JavaScript ```javascript // ❌ WRONG - Global access var oButton = new sap.m.Button(); // ✅ CORRECT - Explicit dependency sap.ui.define(["sap/m/Button"], function(Button) { var oButton = new Button(); }); // ✅ CORRECT - Dynamic loading with sap.ui.require sap.ui.require(["sap/m/MessageBox"], function(MessageBox) { MessageBox.show("Hello"); }); ``` #### TypeScript ```ts // ❌ WRONG - Global namespace const button: sap.m.Button; // ✅ CORRECT - Import module import Button from "sap/m/Button"; const button: Button; ``` #### XML Views ```xml ``` **Why**: Ensures proper async loading, improves performance in production builds. **Reference**: UI5 documentation page "Require Modules in XML View and Fragment" --- ## 2. Component Initialization Use `sap/ui/core/ComponentSupport` for declarative initialization of the **initial (root)** component: ```html
``` **Reference**: UI5 documentation page "Declarative API for Initial Components" **Note:** Nested components should be managed via component usages (declared in the manifest.json of the containing component) --- ## 3. Data Binding Best Practices ### Always Use Built-in Data Types **ALWAYS** use data binding in views to connect UI controls to data or i18n models. **Priority order**: 1. OData types (`sap/ui/model/odata/type/*`) - **Preferred** 2. Simple types (`sap/ui/model/type/*`) - Only when no OData equivalent 3. Custom types - For special two-way binding scenarios or complex validation 4. Custom formatters - Only for unique business logic (one-way binding) ```xml ``` **Common OData Types**: - `sap.ui.model.odata.type.Decimal` - Numbers with decimals - `sap.ui.model.odata.type.String` - Text with length constraints - `sap.ui.model.odata.type.DateTime` - Date and time **Common Simple Types** (use only when no OData equivalent): - `sap.ui.model.type.DateInterval` - Date ranges - `sap.ui.model.type.FileSize` - File size formatting **Example**: For number formatting with thousands separator, prefer `sap.ui.model.odata.type.Decimal` with `formatOptions: {groupingEnabled: true}` over `sap.ui.model.type.Integer` or a custom formatter. ### When to Use Custom Types Custom types are needed for **special two-way binding scenarios** where built-in types don't provide the required validation or conversion logic. **Example: Custom Type for Email Validation with Two-Way Binding** ```javascript // controller/EmailType.js sap.ui.define(["sap/ui/model/SimpleType"], function(SimpleType) { return SimpleType.extend("my.app.type.EmailType", { formatValue: function(oValue) { return oValue; }, parseValue: function(oValue) { return oValue; }, validateValue: function(oValue) { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (oValue && !emailRegex.test(oValue)) { throw new sap.ui.model.ValidateException("Invalid email format"); } } }); }); ``` **Usage in View**: ```xml ``` **Why Custom Types**: - ✅ Two-way binding support (formatValue + parseValue + validateValue) - ✅ Real-time validation as user types - ✅ Model updates immediately on valid input - ❌ Custom formatters only work for one-way (display) binding ### Data Binding in Views **ALWAYS** use data binding to connect controls to models: ```xml ``` --- ## 4. Internationalization (i18n) ### Translation Workflow Guidelines When modifying `.properties` files, follow the appropriate workflow based on your project type: **For development and testing**: - Update `i18n.properties` (base file) only - Changes will be reflected immediately for development **Production translation workflows**: - **SAP S/4HANA apps**: **NEVER** manually edit localized files (`i18n_de.properties`, `i18n_fr.properties`, etc.) - Translation is handled through SAP's internal translation process - **Apps using SAP Translation Hub or Translation Export/Import (TEW)**: **DO NOT** touch localized files - Translations are generated automatically from the base file - **Manually translated apps only**: Apply changes to all locale files to maintain consistency **Why**: Professional translation workflows generate localized files from the base `i18n.properties` file. Manual edits to localized files will be overwritten during the translation process. --- ## 5. Security - Content Security Policy ### Never Use Inline Scripts or Styles **NEVER** use inline scripts or inline styles in HTML. They violate the recommended CSP settings for UI5 applications. ```html
Styled text
Styled text
``` **Requirements**: - All application logic must reside in dedicated JS or TS files - All styling must reside in dedicated CSS files - Inline `