fix(ui): make Pagination usable server-rendered, surface output errors

Pagination reported the requested page only through its change output, so on a
server-rendered page the controls did nothing: the parent had to own client
state to react, and the emitted page never became a URL. An optional
hrefTemplate now renders the steps and page numbers as anchors, which work
before hydration and without JavaScript and give each page a crawlable URL.
Buttons remain the default for client-owned lists. End steps are clamped and
marked disabled rather than linking past the first or last page.

Output handler errors are no longer swallowed. Nothing awaits invokeOutput, so
a handler that threw became an unhandled rejection that never reached the
console and presented as a control that silently does nothing. Handler errors
are now reported as WRN-DEV-OUTPUT-HANDLER-ERROR.

Regenerates the component reference and the UI visual contract.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-13 15:46:00 +05:30
co-authored by Claude Opus 5
parent 2e42be7b31
commit 5afb2d1875
6 changed files with 210 additions and 35 deletions
+2 -2
View File
@@ -63,7 +63,7 @@ Theme-aware, responsive toggle count component.
Accessible password field with optional show and hide controls.
- Mount: `data-component="TogglePassword"`
- Props: `size: string = "default"`, `color: string = "primary"`, `label: string = "Password"`, `name: string = "password"`, `value: string = ""`, `placeholder: string = "Enter your password"`, `autocomplete: string = "current-password"`, `minlength: string = ""`, `maxlength: string = ""`, `pattern: string = "(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}"`, `fields: unknown[] = []`, `visible: boolean = false`, `toggleable: boolean = true`, `toggleMode: string = "button"`, `checkboxLabel: string = "Show password"`, `showLabel: string = "Show password"`, `hideLabel: string = "Hide password"`, `disabled: boolean = false`, `readonly: boolean = false`, `required: boolean = false`, `invalid: boolean = false`, `helpText: string = ""`, `validationMessage: string = ""`, `class: string = ""`
- Props: `size: string = "default"`, `color: string = "primary"`, `label: string = "Password"`, `name: string = "password"`, `value: string = ""`, `placeholder: string = "Enter your password"`, `autocomplete: string = "current-password"`, `minlength: string = ""`, `maxlength: string = ""`, `pattern: string = "(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9]).{8,}"`, `fields: unknown[] = []`, `visible: boolean = false`, `toggleable: boolean = true`, `toggleMode: string = "button"`, `checkboxLabel: string = "Show password"`, `showLabel: string = "Show password"`, `hideLabel: string = "Hide password"`, `disabled: boolean = false`, `readonly: boolean = false`, `required: boolean = false`, `invalid: boolean = false`, `helpText: string = ""`, `validationMessage: string = ""`, `cornerHint: string = ""`, `cornerHref: string = ""`, `class: string = ""`
- Slots: None
- Outputs: `input({ name?: string; value: string | number | boolean | null | object; visible: boolean })`, `change({ name?: string; value: string | number | boolean | null | object; visible: boolean })`, `toggle({ visible: boolean })`
@@ -835,7 +835,7 @@ Theme-aware, responsive navbar component.
Theme-aware, responsive pagination component.
- Mount: `data-component="Pagination"`
- Props: `color: string = "primary"`, `size: string = "default"`, `page: number = 1`, `pageSize: number = 10`, `total: number = 0`, `variant: string = "compact"`, `siblingCount: number = 1`, `showSummary: boolean = true`, `label: string = "Pagination"`, `previousLabel: string = "Previous"`, `nextLabel: string = "Next"`, `class: string = ""`
- Props: `color: string = "primary"`, `size: string = "default"`, `page: number = 1`, `pageSize: number = 10`, `total: number = 0`, `variant: string = "compact"`, `siblingCount: number = 1`, `showSummary: boolean = true`, `label: string = "Pagination"`, `previousLabel: string = "Previous"`, `nextLabel: string = "Next"`, `hrefTemplate: string = ""`, `class: string = ""`
- Slots: `default`
- Outputs: `change({ page: number; pageSize: number })`, `previous({ page: number })`, `next({ page: number })`