Skip to content

[6.x] Documentation pass - #19506

Draft
brianjhanson wants to merge 15 commits into
6.xfrom
feature/documentation-pass
Draft

[6.x] Documentation pass#19506
brianjhanson wants to merge 15 commits into
6.xfrom
feature/documentation-pass

Conversation

@brianjhanson

Copy link
Copy Markdown
Contributor

Description

Related issues

brianjhanson and others added 7 commits August 27, 2026 15:30
`.storybook/preview.ts` imports `dist/custom-elements.json` statically, so a
running Storybook keeps whatever manifest it booted with. Editing a component's
JSDoc then had no effect until the server was restarted — and because the
helpers turn any arg without a matching argType into a literal attribute, a
newly documented slot would render as an escaped `*-slot="<p>…"` string
instead of slotted content.

Run the analyzer's watch mode alongside the dev server so the manifest, the
controls, and the generated API tables follow the source.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
`selectable` rendered a bare `<input type="checkbox">`, which axe flags as
"Form elements must have labels" and which blocked any story exercising it
from passing the a11y gate.

Name it with the new `select-label` attribute, falling back to a translated
"Select". A list of chips should set it to the entity each chip stands for,
so the checkboxes do not all read alike.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
Callout had three undescribed attributes, no documented slots despite having
four, placeholder descriptions on the rest, and a `@TODO` sitting inside a
public JSDoc block. Rewrite the annotations so the manifest carries the whole
surface, convert the stories to derive their args and argTypes from it, and
add a docs page.

Fixes found while writing it: the `variant` control was populated with
appearance values, the default args set a `variant` that does not exist, a
dead `flash` arg had a control, and `craft-button` was never imported so the
action button never upgraded.

The `padding` attribute no longer accepts unitless numbers or arbitrary CSS
lengths — only the `sm`/`md`/`lg`/`xl` steps and `0`/`none`. An off-scale
value now writes nothing and leaves the component's own default standing;
consumers who need one set the padding custom properties instead. This lands
in the shared `Paddable` mixin, so craft-pane behaves the same way.

Without a title, the callout grid is now a single row, rather than a two-row
template with the body borrowing the title's area.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
The `thumbnail` slot was undocumented despite being rendered, and
`thumb-alignment` had no description, so neither reached the manifest. Add
both, and move the CP-specific note about spreading an element's card
attributes out of the public summary into a comment beside the code.

Convert the stories to derive their args and argTypes from the manifest, so
the controls drive every story rather than only the ones with a matching
custom render, and add a docs page.

Two fixes found while writing it: the header action buttons set
`appearance="plain"`, which craft-button has no such attribute for — the
property is `variant`. And `craft-button`'s `accessible-name` reports the
name it computed for its own error check rather than setting one, so an
icon-only button still needs an `aria-label`.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
`accessible-name` looked like a way to name an icon-only button, but it only
recorded the name the component computed for its own nameless-button warning.
Setting it never put anything in the DOM — it just silenced the warning, so
the Matrix "Remove" buttons that used it were nameless and unflagged.

Make it `_accessibleName` state, and point the callers that were naming
buttons with it at `aria-label`: the PHP Button builder (so the existing
`accessibleName()` API keeps working and now emits a real name), the Matrix
Vue control, and the matrix-input custom element.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
Twelve of its thirteen attributes had no description, and none of its four
slots or its `action:change-state` event were documented. Annotate the whole
surface, convert the stories to derive their args and argTypes from the
manifest, and add a docs page.

Three fixes along the way. The `confirm` attribute was never read — the CP
already passes confirmation inside the action descriptor, which `runAction`
handles — so it is gone. `active` styled itself from `:host([active])` but did
not reflect, so setting the property did nothing; it reflects now. And the
component rendered `craft-icon` and `craft-spinner` without importing either,
leaving them unupgraded anywhere the stories did not happen to pull them in.

The stories had disabled the a11y gate wholesale (`a11y: {test: 'todo'}` on
the meta). It is on now, scoped off for the two stories whose violations are
inherent: an interactive `suffix` nests a control inside the item's button,
and the full-palette grid necessarily includes low-contrast colors. The
nested-interactive finding is a real structural issue, called out in the docs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown

brianjhanson and others added 8 commits August 28, 2026 15:30
None of its nineteen attributes had a description, its slot was undocumented,
and it had no stories at all. Annotate the whole surface, add stories driven
from the manifest, and add a docs page.

The submission contract is the part worth writing down: a `name` posts
`name[date]`, `name[time]`, `name[timezone]`, and `name[locale]`, so the
server receives one coherent value. The locale always travels with it, and the
timezone rides along in a hidden input whenever it is not shown as a control.
So is the asymmetry between the visibility flags: `show-date` and `show-time`
are default-on and only the exact string "false" turns them off, while
`show-timezone` is an ordinary boolean attribute.

Also fixes `disabled-time-ranges`, whose converter guarded `null` but not an
empty attribute, so `disabled-time-ranges=""` threw "Unexpected end of JSON
input" before the element could render.

The a11y gate is surfaced rather than enforced for these stories: the date and
time inputs have no accessible name of their own, since each is a field with
an empty label slot and a wrapping craft-field names the pair instead of the
parts. That needs a labelling decision, and is called out on the docs page.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
Story-level decorators are additive rather than overriding, so the story's
own `(story) => story()` did not opt out of the shared field wrapper — it
added a pass-through and the meta decorator still wrapped the result, giving
two nested `craft-field`s with the inner one outside the outer's `input` slot.

Make opting out a parameter the shared decorator checks instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
`show-date` and `show-time` are default-on string flags, and the storybook
helpers map a `"false"` arg onto boolean `false`, which removes the attribute
— an absent attribute then reads as on, so both stories rendered both inputs.

Write the attribute directly in those two stories, and disable the controls
for the pair rather than offering a knob that cannot express the value. Spell
out on the docs page that a boolean binding cannot turn these off either.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
A patch in the previous commit truncated the story off the end of the file,
leaving the docs page pointing at it with `of={undefined}` and failing to
render at all.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
`<Canvas of={ChipStories.Icon}>` resolving to `undefined` does not fail the
build — Storybook renders the entire page as an error instead, so a renamed
or dropped story silently costs a component its documentation until someone
opens the page. That has now happened twice.

Cross-check every MDX page's story references against its story file's
exports.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
None of the three had a class summary, neither date nor time had any stories,
and craft-input-time's three own attributes were undescribed. Annotate all
three, add stories driven from the manifest, and add docs pages. This also
gives craft-input-date-time's docs page the two links it was already making
to pages that did not exist.

craft-input is the base the other `craft-input-*` controls extend, so its page
carries the shared surface — labelling, the width inference around `maxlength`,
and Lion's eight slots — and the others link back to it rather than restating
it.

Two things worth recording while writing them. `min` and `max` are declared
`attribute: false` on the base, so they are properties rather than attributes
and have to be bound as such. And `disabled-time-ranges` takes `[start, end]`
tuples, not `{start, end}` objects as craft-input-date-time's page claimed;
that page is corrected, and the ranges are enforced by validation after a time
is chosen rather than by the picker.

Also applies the empty-attribute fix from craft-input-date-time to
craft-input-time's identical converter, where `disabled-time-ranges=""` threw
before the element could render.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
Adds docs pages for money, handle, color, copy, password, and file, which
completes the family: all ten `craft-input*` elements now carry a summary,
described attributes, stories, and a page.

craft-input-money had seven undescribed attributes, and craft-input-handle
had two plus no summary and no stories at all. Password and file had neither
summary nor slots recorded, because both extend Lion directly rather than
craft-input — which is worth knowing, since it means the base control's
`maxlength`, `size`, `width`, `monospace`, `center`, and `hidden-input` are
not available on them. craft-input-color does the same. Each page says so
rather than leaving a reader to find out.

Two behaviours worth recording. craft-input-money's `show-currency` and
`clearable` are default-on string flags — the same shape as
craft-input-date-time's `show-date`, where only the literal "false" turns
them off and a boolean binding cannot. And craft-input-handle's `autocorrect`
serialises as `on`/`off` rather than as a bare boolean attribute.

Also renames the file input's story title from `Controls/InputFile` to
`Controls/Input File`, so it sorts and reads with the rest of the family and
its docs id matches the pattern.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
Both extended Lion's input directly, so neither picked up the base control's
`maxlength`, `size`, `small`, `width`, `center`, `monospace`, or
`hidden-input` — and the PHP builders stripped all seven back out of the host
attributes to match, with a comment naming that limitation as the reason.

Extending craft-input closes the gap in both directions: the elements gain the
base surface, and the builders can stop deleting attributes their parent had
already prepared. `type` is still kept off the host for both, since the
password field toggles it and the colour field pairs its own text input with a
native swatch.

The reveal button, the colour swatch, the presets datalist, and the model
values are unchanged, and the help text renders identically — the styles the
two already imported were the ones doing that work.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HY6JVxWjJjmZUMuSiBUW9p
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant