Commit Graph
4 Commits
Author SHA1 Message Date
shadowdaoandClaude Opus 4.8 e1b4ab735c feat(builder): text+button package -- typography depth, button target/hover, box-model+anim/vis rollout
- 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>
2026-07-14 06:41:53 -07:00
shadowdaoandClaude Opus 4.8 591a51dcc2 fix(builder): escape/allowlist all attribute-value sinks incl. numeric/enum props (XSS)
An adversarial pass found 5 Critical XSS sinks where props declared number/enum
in TypeScript were interpolated raw into exported HTML attribute values,
trusting the type — but nothing enforces it at runtime (AI update_props only
validates node_id; deserialized saved state is untyped JSON). Fixed all 5
(NumberCounter data-target, StarRating aria-label, FormContainer method,
ContactForm/InputField input type) plus 6 sibling sinks found by an exhaustive
audit of every attribute-value interpolation across src/components: a
JS-source injection into ContentSlider's inline setInterval script, a
prototype-pollution-adjacent allowlist gap in Section's divider-shape lookup,
TextareaField rows, Testimonials rating aria-label, HeroSimple textAlign, and
MapEmbed zoom. Adds shared sanitizeFormMethod/sanitizeInputType allowlist
helpers to utils/escape.ts alongside the existing escapeAttr/safeUrl/cssValue
primitives. Every fix is TDD'd: a malicious-value test reproduces the raw
injection against the pre-fix code, then passes after the fix.

502 tests green (npx vitest run), tsc + vite build green (npm run build).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 18:03:44 -07:00
shadowdaoandClaude Opus 4.8 65a10a1ef9 refactor(builder): remove dead component settings UI
Each component defined a .craft.related.settings panel that was never
rendered -- the right panel renders only GuidedStyles (per-type
*StylePanel components), never .related.settings. Removed all dead
settings components across every component, their settings-only helpers
(including the dead uploadToWhp/showBrowser/handleBrowse asset-browse
blocks in Logo/Navbar/VideoBlock/FeaturesGrid, and CtasEditor in
_cta-helpers), and dropped the now-empty related keys. Render output,
.craft props/rules, and toHtml statics are unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-12 13:16:53 -07:00
shadowdaoandClaude Opus 4.6 91a6b6f34b Add Craft.js site builder (v2) - complete rebuild from GrapesJS
Rebuilt the visual site builder from scratch using Craft.js, React 18,
and TypeScript. The new editor renders directly in the DOM (no iframe),
supports 40+ components, multi-page with shared header/footer, 16
templates, full-spectrum color/gradient controls, custom head code
injection, save/publish workflow, and auto-save.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 18:31:16 -07:00