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:
@@ -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.
|
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
|
## How to read the component docs
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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.
|
||||||
@@ -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.
|
||||||
Reference in New Issue
Block a user