- TextStylePanel (Heading/TextBlock): line-height/letter-spacing presets,
text-transform (none/uppercase/lowercase/capitalize), italic + underline
toggles (fontStyle/textDecoration), and a custom NumericUnitInput
font-size alongside the existing preset row. All write to component
`style`; no toHtml changes needed (style already flows through
cssPropsToString for both components).
- ButtonStylePanel/ButtonLink: "Open in new tab" checkbox writes the
existing `target` prop ('_self'/'_blank' -- toHtml already emitted
rel="noopener noreferrer" for _blank). New Hover State section
(hoverBg/hoverColor via ColorPickerField) renders a scoped
`<style>.btn_<hash>:hover{...}</style>` block before the `<a>` in
toHtml, scoped per-node via scopeId (same pattern as Navbar/Menu) so
two buttons on one page don't collide; both values sanitized through
cssValue against <style>-element breakout. Editor canvas gets a live
hover preview via onMouseEnter/onMouseLeave local state (mirrors Menu's
approach), since there's no way to preview a CSS :hover rule directly
on an inline-styled React element.
- Heading/TextBlock/ButtonLink: added margin(per-side)/padding(per-side,
Text only)/border/box-shadow/opacity style defaults + AnimationControl/
VisibilityControl-backed animation/animationDelay/hideOnDesktop/
hideOnTablet/hideOnMobile props, each panel gaining collapsible
Spacing / Border & Effects / Animation & Visibility sections. Button
keeps its existing padding-shorthand preset row rather than adding a
redundant per-side padding control; only margin got the new
per-side SpacingControl.
- Tests: extended all three *.toHtml.test.ts files -- typography style
emission (line-height/letter-spacing/text-transform/font-style/
text-decoration/custom font-size), button target+rel, scoped hover
style emission + two adversarial style-breakout cases (</style><script>
and rule-injection via `;}selector{`), and craft.props assertions for
every new prop on all three components. 674 tests green, tsc + vite
build clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
jknapp
merged commit b03425ac39 into main2026-07-14 13:46:08 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Typography: line-height/letter-spacing/text-transform/italic/underline/custom size. Button: open-in-new-tab toggle + per-node scoped :hover style (XSS-safe via cssValue/scopeId). Box-model + animation/visibility on Heading/TextBlock/ButtonLink. Reviewed (no XSS, no regression). 674 tests.
🤖 Generated with Claude Code
- TextStylePanel (Heading/TextBlock): line-height/letter-spacing presets, text-transform (none/uppercase/lowercase/capitalize), italic + underline toggles (fontStyle/textDecoration), and a custom NumericUnitInput font-size alongside the existing preset row. All write to component `style`; no toHtml changes needed (style already flows through cssPropsToString for both components). - ButtonStylePanel/ButtonLink: "Open in new tab" checkbox writes the existing `target` prop ('_self'/'_blank' -- toHtml already emitted rel="noopener noreferrer" for _blank). New Hover State section (hoverBg/hoverColor via ColorPickerField) renders a scoped `<style>.btn_<hash>:hover{...}</style>` block before the `<a>` in toHtml, scoped per-node via scopeId (same pattern as Navbar/Menu) so two buttons on one page don't collide; both values sanitized through cssValue against <style>-element breakout. Editor canvas gets a live hover preview via onMouseEnter/onMouseLeave local state (mirrors Menu's approach), since there's no way to preview a CSS :hover rule directly on an inline-styled React element. - Heading/TextBlock/ButtonLink: added margin(per-side)/padding(per-side, Text only)/border/box-shadow/opacity style defaults + AnimationControl/ VisibilityControl-backed animation/animationDelay/hideOnDesktop/ hideOnTablet/hideOnMobile props, each panel gaining collapsible Spacing / Border & Effects / Animation & Visibility sections. Button keeps its existing padding-shorthand preset row rather than adding a redundant per-side padding control; only margin got the new per-side SpacingControl. - Tests: extended all three *.toHtml.test.ts files -- typography style emission (line-height/letter-spacing/text-transform/font-style/ text-decoration/custom font-size), button target+rel, scoped hover style emission + two adversarial style-breakout cases (</style><script> and rule-injection via `;}selector{`), and craft.props assertions for every new prop on all three components. 674 tests green, tsc + vite build clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>