Added issues that are going to be tracked and will be deeply considering changes based on DX.

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-05-06 00:21:13 +05:00
parent b530bb8c97
commit 3059c6cc77
8 changed files with 1218 additions and 0 deletions
+6
View File
@@ -4,6 +4,12 @@ All components live in `Htmx.ApiDemo/Templates/Components/`. Each is a `.htmx` t
If you have not read [03-creating-a-component.md](03-creating-a-component.md) yet, start there — it explains how components work under the hood.
For known API limitations and improvement tracking, also see:
- [Issues/Components/00-API-Limitations-and-Workarounds.md](Issues/Components/00-API-Limitations-and-Workarounds.md)
- [Issues/Components/00-API-Design-Guidelines.md](Issues/Components/00-API-Design-Guidelines.md)
- [Issues/README.md](Issues/README.md)
---
## How to read the component docs
+525
View File
@@ -0,0 +1,525 @@
# Component API Smells
This document catalogs potential complaints about the current component/template API.
Each item includes:
- Problem
- Why it hurts
- Potential solutions
- Consequences/costs
## 1) Magic Strings for Variants, Sizes, Types, Directions
Problem:
- Many components use raw strings for semantic options (`variant`, `size`, `type`, `direction`, `align`, etc.).
- Invalid values often silently fall back to defaults.
Why it hurts:
- No compile-time safety.
- Typos are easy to miss.
- Weak IntelliSense discoverability.
Potential solutions:
- Replace string options with enums for common semantic domains.
- Generate constants classes per component for non-breaking intermediate step.
- Add analyzers that validate allowed literals where strings are retained.
Consequences/costs:
- Enums can be breaking if public signatures change.
- Constants are low cost but do not fully prevent invalid values.
- Analyzer route adds tooling complexity.
## 2) Inconsistent Styling Extensibility (`extraClasses` and wrappers)
Problem:
- Some components have `extraClasses`; others do not.
- Developers often wrap components in outer `div` just to apply layout/styling.
Why it hurts:
- No consistent mental model.
- Extra wrapper markup increases noise and nesting depth.
Potential solutions:
- Add a standard `className` (or `extraClasses`) parameter to every component.
- Support class merging utility behavior in a shared helper.
Consequences/costs:
- Public constructor expansion across many components.
- Need policy for precedence (base classes first vs custom classes first).
## 3) Missing Uniform Attribute Pass-Through
Problem:
- Attribute extensibility is fragmented (`hxAttrs` in some places, none in others).
- No first-class support for arbitrary `aria-*`, `data-*`, test IDs, analytics attributes.
Why it hurts:
- Manual string composition is error-prone.
- Difficult accessibility and testing instrumentation.
Potential solutions:
- Add a shared attributes bag type (`IReadOnlyDictionary<string, string?>`).
- Keep `hxAttrs` temporarily as compatibility shim.
Consequences/costs:
- Larger refactor surface.
- Slight allocation/processing overhead.
- Requires HTML attribute encoding rules in one central place.
## 4) `hxAttrs` Raw String Footgun
Problem:
- Raw attribute strings allow malformed markup or accidental injection.
Why it hurts:
- Hard-to-debug render bugs.
- Security posture depends on each caller doing manual encoding correctly.
Potential solutions:
- Deprecate raw `hxAttrs` in favor of typed/structured attrs.
- Provide safe helper methods to construct HTMX attribute sets.
Consequences/costs:
- Migration needed for existing call sites.
- Potentially breaking unless a gradual fallback is kept.
## 5) Unsafe-by-Default Raw HTML Content Paths
Problem:
- Several components accept string content that is rendered as raw HTML.
- Caller must remember to encode user-provided values.
Why it hurts:
- XSS risk in real application code.
- Easy to misuse when moving quickly.
Potential solutions:
- Safe-by-default encoding for plain string inputs.
- Separate APIs for encoded text vs trusted HTML (explicit escape hatch).
- Introduce a `SafeHtml` wrapper type for intentional raw HTML.
Consequences/costs:
- Safe-by-default may break current behavior for callers relying on raw HTML.
- Trusted-HTML API adds conceptual complexity, but clearer intent.
## 6) Inconsistent Security Guidance in Component Docs
Problem:
- Some docs mention encoding; others do not provide clear warnings.
Why it hurts:
- Security correctness relies on tribal knowledge.
Potential solutions:
- Add a standardized "Security" section to every component doc.
- Include explicit examples: safe input, unsafe input, and fix.
Consequences/costs:
- Documentation maintenance overhead.
- Strong DX/security benefit for low implementation cost.
## 7) No Explicit "Component Props" Model in Markup
Problem:
- Slots replace placeholders, but there is no direct concept of passing typed props in `.htmx` markup itself.
- Dynamic behavior is mostly constructor-centric in `.htmx.cs`.
Why it hurts:
- Feels unlike modern component systems where props are explicit and local.
- New users may expect inline component parameterization and be surprised.
Potential solutions:
- Document this limitation clearly as a design constraint.
- Add a generated props record convention per component/page.
- Explore optional parameterized slot syntax in generator (long-term).
Consequences/costs:
- Props model requires generator design changes.
- Parameterized slot syntax is high complexity and may conflict with AOT simplicity.
## 8) Constructor Bloat and Low Readability
Problem:
- Some components expose many optional parameters, often multiple strings.
Why it hurts:
- Ambiguous calls and poor self-documentation.
- Easy to mis-order arguments.
Potential solutions:
- Favor required args + options record pattern.
- Add fluent builders for complex components.
Consequences/costs:
- Options records improve readability but introduce extra types.
- Builders can increase allocations and complexity.
## 9) Tuple-Based APIs for Complex Components
Problem:
- Components like tabs/accordion/dropdown/table rely on tuple collections.
Why it hurts:
- Tuples are easy to misuse and harder to read than named objects.
- Harder to evolve APIs without breaking all call sites.
Potential solutions:
- Replace tuple parameters with named records (`TabItem`, `AccordionItem`, etc.).
Consequences/costs:
- Migration churn across existing usage.
- Clear long-term maintainability win.
## 10) Missing Validation Feedback for Invalid Inputs
Problem:
- Invalid option values often degrade silently rather than failing fast.
Why it hurts:
- Bugs are hidden and discovered late.
Potential solutions:
- Add debug-time validation with clear exceptions/messages.
- Optionally emit logs/diagnostics in production with safe defaults.
Consequences/costs:
- Strict runtime validation can be breaking for existing invalid usages.
- Diagnostics-only mode is safer for migration.
## 11) Inconsistent Boolean Option Naming
Problem:
- Different components use varying naming styles for booleans and toggles.
Why it hurts:
- Low API predictability.
Potential solutions:
- Define naming conventions (`isX`, `hasX`, `enableX`) and enforce globally.
Consequences/costs:
- Rename churn if normalized retroactively.
## 12) CSS Contract Coupled to JS via Hidden Class Names
Problem:
- Interactive behavior relies on specific class/data selectors that are effectively API contracts.
Why it hurts:
- Refactoring classes can break behavior.
- Coupling is not obvious from constructor APIs.
Potential solutions:
- Document required selectors/events in each interactive component doc.
- Prefer stable `data-component`/`data-role` markers over purely visual class names.
Consequences/costs:
- Markup updates across components and JS.
- Better long-term resilience to style refactors.
## 13) Runtime Behavior Dependencies Not Surfaced in API
Problem:
- Components requiring JS initialization do not expose that requirement in code signatures.
Why it hurts:
- Silent "renders but does not work" failures.
Potential solutions:
- Add `Requires JavaScript` section in docs and XML comments.
- Add lightweight marker interface or metadata attribute for interactive components.
Consequences/costs:
- Minimal runtime cost; mostly documentation/tooling work.
## 14) Accessibility Ergonomics Gaps
Problem:
- No consistent way to pass `aria-*`, `id`, `for`, `describedby` across all components.
Why it hurts:
- Accessibility quality depends on manual wrapper hacks.
Potential solutions:
- Introduce shared accessible options type.
- Provide defaults and enforce required labels where relevant.
Consequences/costs:
- Constructor changes and additional validation logic.
## 15) Testability Friction (No Standard Test IDs)
Problem:
- No consistent `data-testid` or attribute pass-through strategy.
Why it hurts:
- E2E selectors become brittle (class/text-based selectors).
Potential solutions:
- Add standard attributes bag and testing guidance.
- Add `testId` convenience parameter in interactive/form primitives.
Consequences/costs:
- Minor API surface increase.
- Significant test stability benefit.
## 16) Documentation Discoverability Gaps
Problem:
- Component docs focus on usage but under-emphasize known limitations and smell areas.
Why it hurts:
- New contributors re-learn the same constraints repeatedly.
Potential solutions:
- Add dedicated docs for limitations, anti-patterns, and migration strategy.
- Add an index from component reference into Issues docs.
Consequences/costs:
- Ongoing documentation upkeep.
## 17) Inconsistent Naming (`extraClasses` vs alternatives)
Problem:
- Similar concepts have inconsistent parameter names.
Why it hurts:
- Context switching overhead.
Potential solutions:
- Standardize naming dictionary and enforce in reviews.
- Offer temporary backward-compatible aliases.
Consequences/costs:
- Alias support increases short-term complexity.
## 18) Lack of Strongly-Typed Domain Primitives
Problem:
- IDs, route paths, CSS classes, and labels are all plain strings.
Why it hurts:
- Accidental parameter swaps and weak intent signaling.
Potential solutions:
- Introduce lightweight value objects or records for high-value domains (`DialogId`, `CssClassList`, etc.).
Consequences/costs:
- Added type count and conversion code.
- Better readability and safer APIs.
## 19) Missing Centralized Class Composition Policy
Problem:
- Tailwind class strings are composed ad-hoc in constructors.
Why it hurts:
- Risk of duplicate/conflicting classes.
- Hard to audit variant behavior consistency.
Potential solutions:
- Add shared class composition helper utilities.
- Optionally adopt a deterministic merge utility pattern.
Consequences/costs:
- New utility dependency or internal helper maintenance.
## 20) Limited Error Reporting for Misconfigured Interactive Components
Problem:
- Missing/incorrect JS hooks often fail quietly.
Why it hurts:
- Time-consuming debugging.
Potential solutions:
- Development-only console warnings/assertions from `components.js` when expected markers are missing.
Consequences/costs:
- Slight JS complexity increase.
- Better troubleshooting experience.
## 21) Form Component API Inconsistency
Problem:
- Form primitives vary in how they accept value/default/checked/attrs/labels.
Why it hurts:
- Hard to predict usage patterns across components.
Potential solutions:
- Define a shared form control contract:
- `name`, `id`, `label`, `value`, `disabled`, `required`, `className`, `attributes`
Consequences/costs:
- Widespread API harmonization work.
- Major usability win once stabilized.
## 22) No First-Class Validation/Error State Patterns
Problem:
- Error display, invalid styling, and message linkage are largely ad-hoc.
Why it hurts:
- Inconsistent UX and accessibility for validation states.
Potential solutions:
- Add canonical form-field wrapper component and error semantics.
- Add helper patterns in docs for mapping server validation to components.
Consequences/costs:
- Additional abstractions and migration.
## 23) Table API Lacks Strong Cell/Column Models
Problem:
- Table inputs as nested strings are simplistic and rigid.
Why it hurts:
- Hard to represent links, badges, actions, and per-cell semantics safely.
Potential solutions:
- Introduce column and row models with typed cell renderers.
- Support text cell vs trusted HTML cell explicit APIs.
Consequences/costs:
- Significant redesign effort for table API.
- High payoff for real-world usage.
## 24) Potential Over-Eager Precomputation in Constructors
Problem:
- Some components precompute heavy HTML payloads in constructor.
Why it hurts:
- Allocation spikes for large datasets.
- Can surprise developers expecting render-time streaming.
Potential solutions:
- Lazy compute/cache expensive sections.
- Document performance profile and guardrails per component.
Consequences/costs:
- Possible complexity in caching invalidation.
- Better performance transparency.
## 25) No Compatibility Policy for API Evolution
Problem:
- No explicit deprecation policy for parameter renames or behavior changes.
Why it hurts:
- Contributors hesitate to improve APIs due to break risk.
Potential solutions:
- Define semver/deprecation policy in docs.
- Use staged migration with obsolete annotations.
Consequences/costs:
- Process overhead, but critical for long-term maintainability.
## 26) No Unified Component Design Principles Doc
Problem:
- Patterns are documented, but not as enforceable design principles.
Why it hurts:
- New components may diverge in API style.
Potential solutions:
- Publish a component API style guide with mandatory rules and preferred patterns.
Consequences/costs:
- Requires reviewer discipline.
## 27) Internationalization (i18n) Boundaries Not Explicit
Problem:
- Many labels/content are plain strings without explicit localization guidance.
Why it hurts:
- Inconsistent localization strategy across pages/components.
Potential solutions:
- Add docs for localizable boundaries and resource integration patterns.
Consequences/costs:
- Documentation and integration work.
## 28) Missing "Known Limitations" Section in Component Reference Entry Point
Problem:
- The main component reference does not prominently call out systemic limitations.
Why it hurts:
- Developers discover constraints by trial and error.
Potential solutions:
- Add up-front limitations and issue tracker links in component reference.
Consequences/costs:
- Low cost; immediate discoverability gains.
## 29) API Surface Differs Across Similar Components
Problem:
- Similar categories (display/form/interactive) do not expose comparable extension points.
Why it hurts:
- Surprising differences force re-learning per component.
Potential solutions:
- Define a baseline component contract by category:
- Display: `className`, `attributes`
- Form: baseline form control props + attrs
- Interactive: baseline + JS contract notes
Consequences/costs:
- Requires systematic API audit and staged rollout.
## 30) Missing Tooling Support for API Misuse
Problem:
- No analyzers/code fixes for common mistakes (invalid variant, unsafe content, missing encoding).
Why it hurts:
- Review burden remains manual.
Potential solutions:
- Introduce Roslyn analyzers for:
- magic string validation
- unsafe raw HTML from untrusted sources
- missing serialization registration patterns
Consequences/costs:
- Initial tooling investment is medium-high.
- Scales quality across the codebase after adoption.
---
## Cross-Cutting Improvement Patterns
1. Standardized base options record:
- `className`
- `attributes`
- `testId`
- `ariaLabel`
2. Strong typing for semantic options:
- enums/constants/analyzers
3. Safe content model:
- text-safe by default, explicit trusted-html escape hatch
4. Better docs contract:
- every component doc should include:
- security notes
- accessibility notes
- JS dependency notes (if interactive)
- extension points
5. Migration strategy:
- additive changes first
- obsolete old params
- remove deprecated paths in major version bump
@@ -0,0 +1,329 @@
# Component-by-Component Concerns
This matrix captures likely API/DX complaints per component area, including potential improvement directions.
## Display Components
### Alert
Concerns:
- Variant as magic string.
- Content/title may be used as raw HTML without explicit safety boundary.
- Custom classes/attributes may be inconsistent.
Potential improvements:
- Enum for variant.
- Safe text API + explicit trusted HTML path.
- Standard `className` and `attributes`.
### Avatar
Concerns:
- Fallback/shape/size options can become string-heavy.
- Accessibility attributes may be awkward without attr bag.
Potential improvements:
- Typed size/shape options.
- Uniform attributes model.
### Badge
Concerns:
- Variant string typing and typo risk.
- Inconsistent extension points compared with Button/Input.
Potential improvements:
- Variant enum/constants.
- Standardized extensibility surface.
### Breadcrumb
Concerns:
- Item model may be primitive/string-only.
- Accessibility hooks and custom attrs may be limited.
Potential improvements:
- Named item record model.
- Attr bag and aria convenience options.
### Card
Concerns:
- Raw HTML sections can be misused.
- Optional sections create many constructor parameters.
Potential improvements:
- Options record.
- Safe content model.
### Progress
Concerns:
- Value bounds validation may be implicit or absent.
- Class extension inconsistencies.
Potential improvements:
- Explicit min/max validation.
- Standard class and attr extension.
### Separator
Concerns:
- Orientation/type as magic string.
- Thin API extensibility for accessibility semantics.
Potential improvements:
- Enum for orientation.
- Attr bag support.
### Skeleton
Concerns:
- Shape/sizing patterns vary by caller wrappers.
- Lacks compositional guidance for complex placeholders.
Potential improvements:
- Preset variants + className override.
- Pattern docs for loading states.
### Table
Concerns:
- Primitive row/cell string model limits rich content.
- Possible heavy constructor precomputation for large data.
- Safety boundary unclear when rendering rich cell content.
Potential improvements:
- Typed column/cell models.
- Lazy render/cache strategy for large tables.
- Explicit text-vs-html cell APIs.
### Tooltip
Concerns:
- Trigger/content composition can rely on string/slot conventions.
- Accessibility and focus behavior may need clearer guidance.
Potential improvements:
- Better keyboard and aria documentation.
- Attr/class pass-through consistency.
## Form Components
### Button
Concerns:
- Variant/size/type magic strings.
- `hxAttrs` raw string ergonomics/security risk.
- Need for wrapper to add layout classes in some contexts.
Potential improvements:
- Enums/constants.
- Structured attributes.
- Standard `className`.
### Checkbox
Concerns:
- Label/id/checked model may not match other form controls.
- Limited pass-through attributes.
Potential improvements:
- Shared form-control options contract.
- Attr bag and validation state support.
### FileInput
Concerns:
- Accepted file types and attrs may be cumbersome.
- Inconsistent API vs Input/Textarea.
Potential improvements:
- Shared form-control options.
- Better file-specific typed options.
### Input
Concerns:
- Input type as string.
- Validation/aria hooks likely manual.
Potential improvements:
- Input type enum/constants.
- Baseline form options and attr bag.
### RadioGroup
Concerns:
- Tuple options reduce readability.
- Direction/layout often string-based.
- Attr pass-through likely limited.
Potential improvements:
- Named option record.
- Typed direction values.
- Standard form/attr contract.
### Select
Concerns:
- Option model and selected/default semantics may be inconsistent.
- Styling/attrs may differ from Input/Textarea.
Potential improvements:
- Named option record.
- Unified form control API.
### Slider
Concerns:
- Value/min/max/step validation and formatting ergonomics.
- Limited attr/class extensibility in some usages.
Potential improvements:
- Stronger numeric validation and docs.
- Standard extension points.
### Switch
Concerns:
- Checked/value semantics may differ from checkbox.
- JS and accessibility contracts may not be obvious.
Potential improvements:
- Form contract alignment.
- Explicit a11y + JS requirements docs.
### Textarea
Concerns:
- Similar concerns to Input: attrs, validation, and consistency.
Potential improvements:
- Shared baseline form options.
## Interactive Components
### Accordion
Concerns:
- Tuple-based item model.
- JS selector coupling via markup classes/data attributes.
- Rich content safety boundary if strings are HTML.
Potential improvements:
- Named `AccordionItem` model.
- Stable data-role contracts.
- Explicit safe/trusted content APIs.
### Calendar
Concerns:
- JS dependency and date contract coupling.
- Limited custom attributes for instrumentation/a11y.
Potential improvements:
- Explicit JS contract docs in API comments.
- Standard attrs support.
### CalendarRange
Concerns:
- Similar to Calendar plus complexity around range state.
- Validation/error state API may be weak.
Potential improvements:
- Strong state model and docs.
- Better attr/validation contract.
### Dialog
Concerns:
- Open/close semantics rely on data attributes and JS wiring.
- Content sections may use raw HTML strings.
Potential improvements:
- Named trigger/actions patterns in docs.
- Safe content APIs and structured attrs.
### DropdownMenu
Concerns:
- Item model can be tuple-heavy.
- Keyboard and accessibility behavior depends on JS contract.
Potential improvements:
- Named item/action records.
- Explicit interaction/accessibility contract docs.
### Tabs
Concerns:
- Tuple-based tab definitions.
- ID/active state handling as plain strings.
- JS contract may be implicit.
Potential improvements:
- `TabItem` record + typed active key model.
- Explicit JS and accessibility notes.
### TimePicker
Concerns:
- Value format/string handling may be error-prone.
- JS coupling and validation ergonomics.
Potential improvements:
- Typed time value helpers.
- Clear formatting and validation rules.
## Notification Components
### Toast
Concerns:
- Trigger lifecycle and JS coupling may not be obvious.
- Variant/style options likely string-based.
Potential improvements:
- Typed options and JS contract docs.
- Standard attrs/class extension points.
### ToastViewport
Concerns:
- Placement/config likely string-heavy.
- Global singleton usage constraints may be under-documented.
Potential improvements:
- Typed placement/options.
- Clear singleton/layout guidance.
## Navigation Components
### Pagination
Concerns:
- Data model may be primitive and hard to customize.
- Accessibility state semantics need consistency.
Potential improvements:
- Named model for page items and actions.
- Strong accessibility defaults and hooks.
## Cross-Component Cost Notes
Low-cost improvements:
- Better docs for limitations/security/js contracts.
- Add design guidelines and migration policy.
- Constants for common string literals.
Medium-cost improvements:
- Standard `className` and `attributes` options.
- Options records for complex constructors.
- Named item models replacing tuples.
High-cost improvements:
- Safe-by-default content model transition.
- Full enum migration for all semantic options.
- Analyzer suite for API misuse detection.
@@ -0,0 +1,51 @@
# Component API Design Guidelines
Use this when creating or evolving components so the API remains predictable.
## Goals
- Consistency across all components
- Safe defaults for user content
- Low ceremony for common use cases
- Explicit escape hatches for advanced scenarios
## Baseline API Conventions
For every new component, prefer:
- `className` for caller-supplied Tailwind/CSS classes
- `attributes` for arbitrary HTML attributes (`aria-*`, `data-*`, test IDs)
- Strongly typed semantic options where practical (enums or constants)
- Named item records instead of tuples for complex lists
## Safety Rules
1. Plain text input should be encoded by default.
2. Raw HTML should require an explicit trusted path.
3. Never require callers to manually concatenate unsafe attribute strings for normal usage.
## Documentation Rules
Every component doc should include:
1. Quick example
2. All options
3. Security notes
4. Accessibility notes
5. JS dependency notes (if interactive)
6. Extension points (`className`, `attributes`)
## Evolution Rules
1. Prefer additive changes first.
2. Mark old APIs as deprecated with migration examples.
3. Remove deprecated paths only in major release.
## Review Checklist
- Is the API consistent with sibling components?
- Can callers add classes without wrapper divs?
- Can callers pass `aria-*` and `data-*` safely?
- Are semantic options type-safe?
- Are user-provided strings encoded by default?
- Are interactive JS requirements documented?
@@ -0,0 +1,128 @@
# 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
<div class="md:max-w-sm w-full">$$SaveButton$$</div>
```
## 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.
@@ -0,0 +1,68 @@
# Improvement Options and Costs
This matrix helps prioritize API improvements by DX value, risk, and migration cost.
Legend:
- Effort: S (small), M (medium), L (large), XL (very large)
- Break Risk: Low, Medium, High
- Runtime Impact: Positive, Neutral, Slight Negative
| Proposal | Solves | Effort | Break Risk | Runtime Impact | Notes |
|---|---|---|---|---|---|
| Add standardized `className` to all components | wrapper-div workaround, styling consistency | M | Low | Neutral | Additive change if optional |
| Add standardized attributes bag (`attributes`) | missing `aria-*`, `data-*`, test IDs | L | Medium | Slight Negative | Best long-term extensibility |
| Keep `hxAttrs` as compatibility fallback | migration safety | S | Low | Neutral | Mark as legacy in docs |
| Enums for variant/size/type | magic strings | M | Medium | Neutral | Better compile-time safety |
| Constants classes for allowed string values | magic strings (partial) | S | Low | Neutral | Good transitional step |
| Replace tuple APIs with named records | readability, future extensibility | M | Medium | Neutral | `TabItem`, `AccordionItem`, etc. |
| Add options-record constructors for complex components | constructor bloat | M | Low | Neutral | Improves call-site clarity |
| Safe-by-default text encoding APIs | XSS risk | M | High | Neutral | Breaking if current raw HTML behavior is relied on |
| Explicit trusted HTML wrapper API | intentional raw HTML path | M | Medium | Neutral | Clear security intent |
| Add standardized Security section in every component doc | security docs inconsistency | M | Low | Neutral | High ROI docs work |
| Add standardized Accessibility section in every component doc | a11y gaps | M | Low | Neutral | High ROI docs work |
| Add JS contract metadata/docs for interactive components | hidden JS dependencies | S | Low | Neutral | Immediate debugging benefit |
| Add development-time JS diagnostics in components.js | silent interactive failures | M | Low | Slight Negative | Dev-only checks recommended |
| Add analyzer: invalid variant literals | magic string typos | L | Low | Neutral | Tooling investment pays off |
| Add analyzer: unsafe unencoded user input usage | XSS prevention | L | Medium | Neutral | Requires careful heuristics |
| Add API evolution policy and deprecation plan | change management | S | Low | Neutral | Needed before major refactors |
| Introduce per-category baseline contracts | inconsistency across components | L | Medium | Neutral | Strategic but broad |
| Introduce table column/cell model | table API limitations | L | Medium | Neutral | High payoff for real apps |
| Add form control baseline contract | form component inconsistency | L | Medium | Neutral | Improves predictability |
| Introduce lazy compute in heavy components | precompute allocation concerns | M | Low | Positive | Benchmark before and after |
## Recommended Sequencing
1. Documentation-first, no-break improvements:
- known limitations docs
- security/a11y/js contract sections
- issue tracker links and migration guidance
2. Additive API upgrades:
- `className`
- `attributes`
- options records
- constants for allowed values
3. Strong typing and validation:
- enums
- analyzers
- debug validations
4. Breaking/security-hardening updates:
- safe-by-default content model
- deprecate raw string HTML entry points
## Consequence Summary
Positive consequences:
- More predictable and discoverable API
- Lower bug rate from string typos and attr mistakes
- Better security baseline
- Less wrapper-div boilerplate
Negative/neutral consequences:
- Larger API surface
- Migration overhead in existing usages
- Potentially more allocations for flexible attribute models
- Need for contributor discipline to maintain consistency
+30
View File
@@ -0,0 +1,30 @@
# Issues and API Improvement Tracker
This folder tracks known design/API smells in the current template stack, with proposed fixes and their trade-offs.
Use this section for:
- Capturing developer pain points before they are forgotten
- Aligning on possible API improvements
- Comparing implementation cost vs DX benefit
- Planning staged, low-risk migrations
## Files
- `Component-API-Smells.md` - exhaustive problem catalog and solution options
- `Improvement-Options-and-Costs.md` - decision matrix with cost/consequence analysis
- `Roadmap.md` - phased adoption plan
- `Component-by-Component-Concerns.md` - component-level complaint inventory and improvements
- `Components/00-API-Limitations-and-Workarounds.md` - component API limitations and practical workarounds
- `Components/00-API-Design-Guidelines.md` - component API design principles for future changes
## Scope
This is intentionally broader than bug tracking. Many entries are not defects; they are DX and API design weaknesses (inconsistency, discoverability, ergonomics, safety defaults, and maintainability concerns).
## Ground Rules
1. Keep issues concrete and reproducible.
2. Include at least one realistic solution.
3. Always state consequences (breaking change risk, complexity, perf, AOT constraints).
4. Prefer incremental migration paths over large rewrites.
+81
View File
@@ -0,0 +1,81 @@
# API Improvement Roadmap
This roadmap is designed to improve DX without destabilizing the current template.
## Phase 0: Track and Communicate (Now)
Goals:
- Make limitations explicit.
- Prevent repeated confusion.
Actions:
- Publish issues catalog and cost matrix.
- Link issues from the main component reference.
- Add "Known Limitations" + "Security" notes in component docs.
Success criteria:
- New contributors can find limitations before implementation.
## Phase 1: Low-Risk Additive API Improvements
Goals:
- Improve ergonomics with minimal break risk.
Actions:
- Add optional `className` to all components.
- Add optional `attributes` bag to all components.
- Keep `hxAttrs` as legacy fallback.
- Introduce constants classes for common string domains.
Success criteria:
- Most wrapper-div style workarounds disappear.
- Most custom attribute hacks disappear.
## Phase 2: Standardization and Strong Typing
Goals:
- Reduce error-prone string APIs.
Actions:
- Move high-value components to enums for semantic options.
- Introduce options records where constructors are overloaded.
- Replace tuple-based list inputs with named records.
Success criteria:
- IntelliSense can guide common component usage.
- Fewer runtime surprises from typos.
## Phase 3: Security and Validation Hardening
Goals:
- Safer defaults and clearer intent.
Actions:
- Introduce safe-by-default text paths.
- Keep explicit trusted HTML APIs for advanced usage.
- Add analyzers (or debug validators) for invalid options and unsafe patterns.
Success criteria:
- XSS risk materially reduced.
- Unsafe usage becomes explicit and reviewable.
## Phase 4: Deep API Evolution
Goals:
- Improve advanced composition and maintainability.
Actions:
- Formalize per-category component contracts.
- Improve table/form models for richer data and validation scenarios.
- Consider generator-level support for richer parameter/props models.
Success criteria:
- New component additions follow one predictable design style.
- Complex UIs require less custom glue code.
## Migration Strategy
1. Add new APIs first.
2. Mark old parameters/patterns as deprecated.
3. Provide codemod or migration examples.
4. Remove deprecated surface only in major release.