Releases: phcdevworks/spectre-components
Release list
Phase 6 - Interaction Parity
Contract change type: additive
Added
-
sp-nav- thin wrapper backed bygetNavClasses. Supportsbordered,
sticky, andfull-width. -
sp-sidebar- off-canvas sidebar backed bygetSidebarClasses,
getSidebarBackdropClasses, andgetSidebarToggleClasses. Renders a toggle
button and backdrop, and managesopenstate as native Lit element
interactivity (click, backdrop click,Esc) instead of a ported script.
Reflects open/closed state viadata-sidebar-openon the host to match the
Spectre CSS selector contract. Dispatchessp-openandsp-close. -
sp-dropdown- trigger + menu backed bygetDropdownClassesand
getDropdownMenuClasses. Supportsplacement
(bottom-start/bottom-end/top-start/top-end, defaultbottom-start) and
full-width. Projectsslot="trigger"content into the trigger button and
all other children into the menu. Closes on outside click orEscand returns
focus to the trigger. Dispatchessp-openandsp-close. -
sp-modal- overlay + dialog backed bygetModalClassesand
getModalOverlayClasses. Supportsopenandfull-width. Implements
focus-trap (Tab/Shift+Tab),Esc-to-close, backdrop-click-to-close,
initial focus on open, and focus restoration on close. Dispatchessp-close. -
sp-toast- notification backed bygetToastClassesand
getToastIconClasses. Supportsvariant(info/success/warning/danger,
defaultinfo),dismissed,full-width, andauto-dismiss(ms). Exposes
imperativeshow()/dismiss()methods and dispatchessp-showand
sp-dismiss. Projectsslot="icon"content into an icon container only when
present. -
sp-tooltip- hover/focus-triggered tooltip backed bygetTooltipClasses.
Supportsplacement(top/bottom/left/right, defaulttop) andvisible.
Shows on triggermouseenter/focusinand hides onmouseleave/focusout.
Dispatchessp-showandsp-hide.These six close the remaining component-coverage gap against
@phcdevworks/spectre-ui-astro, using its.astroadapters as the reference
for recipe options and markup structure, with interactivity implemented as
native Lit element state rather than ported scripts.
Phase 6 - Layout and Recipe Alignment
Contract change type: additive
Added
-
sp-container- layout component backed bygetContainerClasses. Supports
max-width(prose). ExportsspectreContainerMaxWidthsand
SpectreContainerMaxWidth. -
sp-grid- layout component backed bygetGridClasses. Supportscolumns
(1/2/3/4/6/12, default1) andgap(sm/md/lg, defaultmd). Exports
spectreGridColumns,spectreGridGaps,SpectreGridColumns, and
SpectreGridGap. -
sp-section- layout wrapper backed bygetSectionClasses. Renders a
<section>with no additional variant props. -
sp-stack- layout component backed bygetStackClasses. Supports
direction(vertical/horizontal, defaultvertical),basis(sidebar),
andalign(center/stretch, defaultcenter). Exports
spectreStackAligns,spectreStackBases,spectreStackDirections,
SpectreStackAlign,SpectreStackBasis, andSpectreStackDirection.These four close part of the component-coverage gap against
@phcdevworks/spectre-ui-astro, using its.astroadapters as the
reference for recipe options and markup structure (interactivity, where
applicable in later additions, is implemented as native Lit element state
rather than ported scripts).
Fixed
-
sp-badge,sp-card,sp-icon-box,sp-testimonial,sp-avatar,
sp-pricing-card, andsp-tagnow renderrole="group"on their native
element whenever anaria-labeloraria-labelledbyis forwarded. These
components wrap a roleless<div>/<span>, and ARIA forbidsaria-label/
aria-labelledbyon an element with no role - axe-core's
aria-prohibited-attrrule flagged this as a violation. The role is
omitted when no label is forwarded, so unlabeled instances are unaffected.
Found while extendingtests/accessibility.test.tscoverage (Phase 5 P1). -
sp-checkboxandsp-radioindicator spans now callgetCheckboxClasses/
getRadioClassesfrom@phcdevworks/spectre-uiinstead of a hardcoded
literal class string. Previously the--checked/--disabledmodifier
classes were never applied, so the indicator's visual state never changed
on toggle or disable, regardless of the native<input>'s actual state. -
sp-fieldset's root<fieldset>element now callsgetFieldsetClasses
from@phcdevworks/spectre-ui. Previously it rendered with noclass
attribute at all, so@phcdevworks/spectre-ui's border/padding styling
for.sp-fieldsetnever applied.
Changed
-
sp-fieldset's legend now calls the purpose-builtgetFieldsetLegendClasses
(.sp-fieldset__legend, themed via--sp-fieldset-legend-text) instead of
the genericgetInputLabelClasses(.sp-label, themed via
--sp-component-input-role-text) it borrowed before
@phcdevworks/spectre-ui@2.6.0published a fieldset-specific recipe. -
sp-labelnow callsgetLabelClasses(.sp-form-label, themed via
--sp-label-*) instead ofgetInputLabelClasses(.sp-label, themed via
--sp-component-input-role-text) - the same kind of borrowed-recipe
situation assp-fieldset's legend, now that a label-specific recipe
exists. Added arequiredproperty, whichgetLabelClassessupports
(renderssp-form-label--required) but the previous recipe did not.Rendered class name change: any external CSS that happened to target
sp-fieldset's legend orsp-label's native<label>via the.sp-label
class will no longer match - neither was a supported public styling hook,
but this is called out explicitly since the class name itself is visible
in the DOM. -
sp-selectandsp-textareanow call the purpose-built
getSelectClasses/getTextareaClassesrecipes instead of borrowing
getInputClasses, now that@phcdevworks/spectre-tokens@3.3.1and
@phcdevworks/spectre-ui@2.7.0addedinvalid/success/loadingstate
support to those recipes.disabledandloadingare now forwarded as
independent options instead of being collapsed into onestatevalue, so
each now renders its own modifier class.Rendered class name change:
sp-select/sp-textareapreviously
renderedsp-input--*modifier classes (e.g.sp-input--lg,
sp-input--error); they now rendersp-select--*/sp-textarea--*(e.g.
sp-select--lg,sp-select--invalid).sp-input--*was never a supported
public styling hook on these elements, but this is called out explicitly
since the class names are visible in the DOM. -
Bumped
@phcdevworks/spectre-tokensto^3.3.1and
@phcdevworks/spectre-uito^2.7.0, closing dependency drift against the
current publishedproject-designversions.
Testing
- Phase 5 P1 hardening pass (no other source changes required):
- Keyboard interaction audit for
sp-select,sp-radio, andsp-checkbox
confirmed no customkeydownhandling exists anywhere in the package -
native browser keyboard semantics (space/enter activation, native radio
group navigation) pass through untouched. Added tests asserting native
keydown events are never intercepted orpreventDefault()-ed, and that
native input/change events correctly update host properties. - Form-association audit for
sp-input,sp-textarea,sp-select,
sp-checkbox, andsp-radioconfirmed native form participation
(FormData,checkValidity(), ancestorform.checkValidity()) works
correctly withoutElementInternals/formAssociated, since each
component renders a real native form control as a light-DOM descendant.
Added end-to-end tests submitting through an ancestor<form>. - Extended
tests/accessibility.test.tswith axe-core scenarios covering
populated, empty, and slot-projection states forsp-badge,sp-card,
sp-icon-box,sp-rating, andsp-testimonial- this surfaced the
role="group"fix above. - Audited
sp-cardandsp-testimonialfor slotted-content edge cases
(whitespace-only text, empty slotted elements, nested interactive
elements, long-text overflow). ConfirmedhasMeaningfulContent()and
SpectreProjectableElementalready handle all four correctly; added
regression tests locking in the behavior. - Added Playwright-based visual regression coverage
(visual-tests/components.visual.spec.ts) snapshotting all 21 components
via the existingverification_app.tspage. Run with
npm run test:visual; regenerate baselines with
npm run test:visual:update. Local opt-in only - not wired into
npm run checkor CI, since cross-runner font/rendering differences make
CI-gated pixel diffs a separate decision.
- Keyboard interaction audit for
Phase 5 - Display Surface Expansion
Contract change type: additive
Added
-
sp-alert- display component backed bygetAlertClasses. Supportsvariant
(info/success/warning/danger/neutral),size(sm/md/lg),dismissed,
disabled,loading, andfull-width. Renders withrole="alert"and
aria-busyreflecting the loading state. ExportsspectreAlertVariants,
spectreAlertSizes,SpectreAlertVariant,SpectreAlertSize, and
SpectreAlertProps. -
sp-avatar- display component backed bygetAvatarClasses. Supportssize
(xs/sm/md/lg/xl),shape(circle/square),interactive,disabled,
loading,full-width, andplaceholder. Reflects theloadingstate to
aria-busy. ExportsspectreAvatarShapes,spectreAvatarSizes,
SpectreAvatarShape,SpectreAvatarSize, andSpectreAvatarProps. -
sp-spinner- loading indicator backed bygetSpinnerClasses. Supports
variant(primary/secondary/success/warning/danger/info/neutral/accent/cta),
size(sm/md/lg),disabled, andloading(defaults totrue). Renders
withrole="status", reflects theloadingstate toaria-busy, and
defaultsaria-labeltoLoading. ExportsspectreSpinnerVariants,
spectreSpinnerSizes,SpectreSpinnerVariant,SpectreSpinnerSize, and
SpectreSpinnerProps. -
sp-tag- display component backed bygetTagClasses. Supportsvariant
(default/primary/secondary/success/warning/danger/info/neutral/accent/cta/outline/ghost),
size(sm/md/lg),interactive,selected,dismissible,disabled,
loading, andfull-width. Reflects theloadingstate toaria-busy.
ExportsspectreTagVariants,spectreTagSizes,SpectreTagVariant,
SpectreTagSize, andSpectreTagProps. -
sp-pricing-card- display container backed bygetPricingCardClasses.
Supportsfeatured,interactive,disabled,loading, and
full-height. Reflects theloadingstate toaria-busy. Exports
SpectrePricingCardProps.
Phase 4 - Display Component Expansion and Ecosystem Manifest Gate
Contract change type: additive
Added
- Added
@phcdevworks/spectre-manifestas a devDependency.
spectre.manifest.jsonat the repo root declares this package's ecosystem
role, layer, exports, and allowed dependency targets.check:ecosystem
validates it in the check pipeline. sp-badge- display component backed bygetBadgeClasses. Supportsvariant
(11 values),size(sm/md/lg),disabled,loading, andfull-width.
ExportsspectreBadgeVariants,spectreBadgeSizes,SpectreBadgeVariant,
SpectreBadgeSize, andSpectreBadgeProps.sp-card- display container backed bygetCardClasses. Supportsvariant
(elevated/flat/outline/ghost),padded,full-height,interactive,
disabled, andloading. ExportsspectreCardVariants,
SpectreCardVariant, andSpectreCardProps.sp-icon-box- display component backed bygetIconBoxClasses. Supports
variant(11 values),size(sm/md/lg),disabled,loading,
interactive,pill, andfull-width. ExportsspectreIconBoxVariants,
spectreIconBoxSizes,SpectreIconBoxVariant,SpectreIconBoxSize, and
SpectreIconBoxProps.sp-rating- display component backed bygetRatingClasses. Renders star
spans programmatically fromvalueandmaxwith arole="img"container
and a computed accessible label. Supportssize(sm/md/lg),disabled,
loading, and alabeltext property. ExportsspectreRatingSizes,
SpectreRatingSize, andSpectreRatingProps.sp-testimonial- display container backed bygetTestimonialClasses.
Supportsvariant(elevated/flat/outline/ghost),full-height,
interactive,disabled, andloading. Exports
spectreTestimonialVariants,SpectreTestimonialVariant, and
SpectreTestimonialProps.- Added subpath exports for all five new components in
package.jsonand
tsup.config.ts. - Extended
components.contract.jsonwith entries for all five new components. - Added new variant and type-guard helpers to
src/utils/form.ts:
spectreBadgeVariants,spectreCardVariants,spectreIconBoxVariants, and
spectreTestimonialVariants.
Changed
- Updated
@phcdevworks/spectre-tokensto^2.8.0and
@phcdevworks/spectre-uito^1.8.0. - Aligned
engines.noderequirement with upstream styling contract.
Phase 3 - Contract Validation and Accessibility Audit Gate
Contract change type: additive
Added
-
components.contract.json- machine-readable manifest anchoring the public
component surface: tags, element classes, entry points, exported value
symbols, exported types, and per-component rendering contracts (renderMode,
shadowDomApproved). -
scripts/check-contract.ts- export-snapshot validator that reads
components.contract.jsonand fails if actual dist exports drift from the
declared contract. Runs asnpm run check:contract. -
scripts/check-invariants.ts- thin-adapter invariant checker that fails on
hardcoded hex colors, hardcoded spacing values in template literals, local
Spectre CSS custom property redefinitions, and Shadow DOM usage without
explicit approval in the manifest. Runs asnpm run check:invariants. -
Both new checks are wired into
npm run checkafter the build step. -
axe-coredevDependency added to support runtime ARIA and accessibility
validation in tests. -
tests/accessibility.test.ts- axe-core audit tests for all eight components
(sp-button,sp-input,sp-textarea,sp-select,sp-checkbox,
sp-radio,sp-label,sp-fieldset). Covers default, invalid, loading, and
aria-label/legend scenarios. Runs as part ofnpm testand the full
npm run checkgate.
Phase 2 - Styling Contract Alignment and Export Validation
Contract change type: additive
Added
sp-button: addedicon-onlyproperty to align with updated styling contract
in@phcdevworks/spectre-ui.sp-label: addeddisabledproperty to align with updated styling contract
in@phcdevworks/spectre-ui.scripts/check-exports.ts- post-build export resolution check that imports
each subpath entry point and verifies the expected registration functions and
element classes are present.check:exportsnpm script wired intonpm run checkafter the build step, so
CI now validates exports on every push and PR.- README: "Why this package exists alongside spectre-ui" architectural
explanation covering the L1–L4 Spectre layer model. - README: per-component API reference tables covering all attributes, events,
content projection behavior, and internal CSS targeting hooks for all eight
components. - README: Accessibility section documenting ARIA forwarding, focus delegation,
state-to-ARIA mapping, and label association patterns. - README: Light DOM rendering explanation and CSS targeting guidance
(data-sp-*-nativeattribute selectors as stable hooks). - README: Framework integration notes for React 19+, React 18, Vue 3, and Astro
with minimal working examples. - AGENTS.md: AI Hard Limits section with explicit unconditional rules covering
scope, design system boundaries, architecture, and API stability. - CLAUDE.md: "What not to do" expanded with framework-specific examples and
explicit component scope and stability rules. - Added Codex companion operating and release review documentation.
- Added workspace GitHub Copilot instruction, scoped repository guidance, and a
reusable release-readiness prompt for standardized AI collaboration.
Changed
- Updated
@phcdevworks/spectre-tokensto^2.6.0and
@phcdevworks/spectre-uito^1.6.0. sp-button: updatedgetButtonClassescall to includeiconOnlystate.sp-inputandsp-textarea: expanded native attribute support and reinforced
coverage for standard form-control attributes.sp-label,sp-fieldset,sp-checkbox,sp-radio: updated internal labels
and legends to usegetInputLabelClassesrecipe from
@phcdevworks/spectre-ui, ensuring consistent typography and disabled states.- Bumped
litto^3.3.3. - Bumped dev dependency ranges and updated lockfile.
- Aligned AI guidance, PR checklist language, and package validation so
npm run checkconsistently covers lint, typecheck, tests, build, and export
validation. - Updated contributor-facing validation notes to match the full
npm run check
gate. - Fixed existing TypeScript test and CSS side-effect import typing drift exposed
by the restored typecheck gate. - Added root Copilot support guidance to match the Spectre AI instruction
structure used by@phcdevworks/spectre-tokens. - Corrected README automation wording so Jules' bounded maintenance commit
authority matchesJULES.md. - Updated shared agent guidance to reference the root Copilot support file.
- Migrated
scripts/check-exportsandscripts/propose-versionto TypeScript
and updated npm script invocations to run the.tsfiles directly.
Fixed
sp-button: added missingsp-labelclass to property-based label fallbacks
and loading labels for typography consistency with other form controls.sp-textarea: reflectrowsproperty to the host attribute so HTML
serialization stays consistent with the declared value.sp-fieldset: added missingaria-invalidattribute to the native
<fieldset>element.sp-fieldset: tightened legend rendering to avoid empty legend output.sp-radio: synchronized programmatic checked-state changes across radio
groups.- Refactored form utility normalization helpers for tighter property validation
acrossrows,maxlength, andminlengthinputs.
Phase 1 - Foundation API Tightening and Component Documentation
Contract change type: additive
Added
formassociation support forsp-input,sp-select, andsp-textarea.- Rich label content support for checkbox and radio controls while preserving
their native input behavior. - Shared light-DOM projection and attribute proxying utilities for foundation
components. - Focused coverage for attribute forwarding, projected content synchronization,
form association, and label rendering behavior. - Contributor, security, code of conduct, and expanded component usage
documentation.
Changed
- Bumped the package release version to
1.1.0. - Refactored foundation components around shared base/projectable behavior while
keeping their public custom element contracts explicit. - Standardized label rendering, property accessors, optional property typing,
and form-control implementation details across the current component set. - Tightened package exports and removed unnecessary public type re-exports from
the select entry point. - Updated Spectre, TypeScript, ESLint, Vitest, Prettier, and related dependency
ranges and lockfile entries.
Fixed
- Unified forwarding for
id,title, ARIA attributes, and native control
attributes across form components. - Improved projected light-DOM content synchronization so external content is
preserved more predictably during updates. - Improved checkbox, radio, select, label, and fieldset accessibility behavior
and DOM hygiene. - Fixed exact optional property type compliance across component classes.
Phase 1 - Foundation Stabilization and Package Release
Contract change type: N/A
Added
formassociation support forsp-input,sp-select, andsp-textarea.- Rich label content support for checkbox and radio controls.
- Shared base and projectable utilities for light-DOM component rendering and
content projection. - Contributor documentation and TypeScript-based ESLint configuration.
- Focused tests for select, label, fieldset, checkbox, radio, projected content,
and form-control behavior.
Changed
- Bumped the package release version to
1.0.0. - Updated Spectre dependency ranges to
@phcdevworks/spectre-tokens^2.4.0
and@phcdevworks/spectre-ui^1.4.0. - Standardized foundation component implementation patterns across the current
public component set. - Refactored components to use shared light-DOM projection and base behavior
instead of duplicating component plumbing. - Tightened label rendering, select sizing, fieldset behavior, and form
component APIs. - Updated TypeScript, ESLint, Vitest, Prettier, Rollup, and related lockfile
entries.
Fixed
- Improved projected content synchronization in light-DOM components.
- Improved checkbox, radio, select, label, and fieldset accessibility behavior.
- Improved DOM hygiene for checkbox and radio label rendering.
- Fixed linting and build issues around the tightened
sp-selectAPI.
Phase 0 - Initial Component Foundations
Contract change type: N/A
Added
- Initial package scaffold for
@phcdevworks/spectre-components. - Root package export plus explicit subpath exports for component-level
registration and consumption. defineSpectreComponents()helper for opt-in registration of the current
component set.- Initial public component set:
sp-buttonsp-inputsp-textareasp-selectsp-checkboxsp-radiosp-labelsp-fieldset
- Vitest coverage for the initial component surface.
- Repository and editor setup files for contributing and release readiness.
Changed
- Tightened component APIs to better align form control behavior across button,
input, textarea, and select patterns. - Consolidated package CSS import expectations for release packaging.
- Updated package metadata, exports, and dependency ranges for the first npm
release.
Fixed
- Improved ARIA reactivity and accessibility fallbacks across the early form
control components. - Improved slotted content handling, content persistence, and loading behavior
in foundational controls. - Tightened property validation and control consistency for early public APIs.