# Component API Limitations and Workarounds This page documents known limitations in the current component API and practical ways to work effectively with them. ## 1) Magic String Parameters Limitation: - Semantic options like `variant`, `size`, and similar values are frequently string-based. What this means: - Typos may silently fall back to defaults. Workaround: - Centralize repeated literals in local constants in your feature code. - Prefer named arguments for readability. Example: ```csharp private const string VariantDestructive = "destructive"; var deleteButton = new Button( label: "Delete", variant: VariantDestructive, size: "sm"); ``` ## 2) Extra Styling Often Requires Wrappers Limitation: - Not every component exposes a class extension parameter. What this means: - You may need wrapper elements for layout spacing, sizing, or responsive behavior. Workaround: - Use a minimal wrapper pattern and keep wrapper intent obvious. Example: ```html
$$SaveButton$$
``` ## 3) No Universal Attribute Bag Limitation: - Some components expose `hxAttrs`, some do not, and no shared attributes model exists yet. What this means: - Passing `aria-*`, `data-*`, or test selectors is inconsistent. Workaround: - Prefer wrapper-level attributes where possible. - If using raw attr strings, keep them static and explicit. ## 4) No Direct "Props in .htmx Markup" Model Limitation: - Component/page parameterization is constructor-driven in `.htmx.cs`, not inline-props driven in `.htmx` markup. What this means: - Dynamic behavior is assembled in C# code-behind. Workaround: - Treat `.htmx` as shape and slot layout. - Treat `.htmx.cs` as the single source of component input logic. ## 5) Raw HTML Output Requires Discipline Limitation: - Several components render provided strings as HTML. What this means: - User input must be encoded before rendering. Workaround: - Always encode user-provided values before `ToUtf8Bytes()`. Example: ```csharp var safeName = System.Web.HttpUtility.HtmlEncode(userDisplayName); _nameData = safeName.ToUtf8Bytes(); ``` ## 6) Interactive Components Depend on JS Contracts Limitation: - Components like tabs, accordion, dialog, calendar, and toast depend on JavaScript hooks/selectors. What this means: - Markup can render but behave incorrectly if expected JS wiring is missing. Workaround: - Verify behavior after HTMX swaps. - Keep required data-role/class markers intact. ## 7) Tuple APIs for Complex Components Limitation: - Some components expect tuple arrays for items/options. What this means: - Call sites can become harder to read and evolve. Workaround: - Build small local records/variables first, then map to tuples. ## 8) Form API Inconsistency Limitation: - Form primitives do not all expose the same extension points. What this means: - You need per-component familiarity. Workaround: - Create feature-local helper methods to normalize usage patterns. ## 9) Recommendation for Teams If multiple developers are contributing: 1. Define local conventions for allowed variant strings. 2. Standardize wrapper patterns (`layout wrappers`, `a11y wrappers`, `test-id wrappers`). 3. Review for HTML encoding whenever user input is rendered. 4. Track repeated pain points in docs/Issues for future API upgrades.