From 0787525134b3a0780f87fa4217d52c05fef96926 Mon Sep 17 00:00:00 2001 From: Enciphered Date: Wed, 6 May 2026 00:21:13 +0500 Subject: [PATCH] Added issues that are going to be tracked and will be deeply considering changes based on DX. Co-authored-by: Copilot --- docs/06-component-reference.md | 6 + docs/Issues/Component-API-Smells.md | 525 ++++++++++++++++++ .../Issues/Component-by-Component-Concerns.md | 329 +++++++++++ .../Components/00-API-Design-Guidelines.md | 51 ++ .../00-API-Limitations-and-Workarounds.md | 128 +++++ docs/Issues/Improvement-Options-and-Costs.md | 68 +++ docs/Issues/README.md | 30 + docs/Issues/Roadmap.md | 81 +++ 8 files changed, 1218 insertions(+) create mode 100644 docs/Issues/Component-API-Smells.md create mode 100644 docs/Issues/Component-by-Component-Concerns.md create mode 100644 docs/Issues/Components/00-API-Design-Guidelines.md create mode 100644 docs/Issues/Components/00-API-Limitations-and-Workarounds.md create mode 100644 docs/Issues/Improvement-Options-and-Costs.md create mode 100644 docs/Issues/README.md create mode 100644 docs/Issues/Roadmap.md diff --git a/docs/06-component-reference.md b/docs/06-component-reference.md index 77bcabc..67365e2 100644 --- a/docs/06-component-reference.md +++ b/docs/06-component-reference.md @@ -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 diff --git a/docs/Issues/Component-API-Smells.md b/docs/Issues/Component-API-Smells.md new file mode 100644 index 0000000..2865456 --- /dev/null +++ b/docs/Issues/Component-API-Smells.md @@ -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`). +- 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 diff --git a/docs/Issues/Component-by-Component-Concerns.md b/docs/Issues/Component-by-Component-Concerns.md new file mode 100644 index 0000000..682a21b --- /dev/null +++ b/docs/Issues/Component-by-Component-Concerns.md @@ -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. diff --git a/docs/Issues/Components/00-API-Design-Guidelines.md b/docs/Issues/Components/00-API-Design-Guidelines.md new file mode 100644 index 0000000..0f1f5ae --- /dev/null +++ b/docs/Issues/Components/00-API-Design-Guidelines.md @@ -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? diff --git a/docs/Issues/Components/00-API-Limitations-and-Workarounds.md b/docs/Issues/Components/00-API-Limitations-and-Workarounds.md new file mode 100644 index 0000000..47d6b1e --- /dev/null +++ b/docs/Issues/Components/00-API-Limitations-and-Workarounds.md @@ -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 +
$$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. diff --git a/docs/Issues/Improvement-Options-and-Costs.md b/docs/Issues/Improvement-Options-and-Costs.md new file mode 100644 index 0000000..e6859f8 --- /dev/null +++ b/docs/Issues/Improvement-Options-and-Costs.md @@ -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 diff --git a/docs/Issues/README.md b/docs/Issues/README.md new file mode 100644 index 0000000..ad044c2 --- /dev/null +++ b/docs/Issues/README.md @@ -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. diff --git a/docs/Issues/Roadmap.md b/docs/Issues/Roadmap.md new file mode 100644 index 0000000..ee4df20 --- /dev/null +++ b/docs/Issues/Roadmap.md @@ -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.