Behavior JavaScript and CSS
Register a plain-JavaScript component, read its props, style it and clean up.
Updated November 8, 2026
Register and mount
(function () { var SB = window.SBComponents; if (!SB || typeof SB.register !== "function") return; SB.register("circle-gallery", { // the component's saved type, exactly mount: function (el) { var images = []; try { images = JSON.parse(el.getAttribute("data-images") || "[]"); } catch (e) {} var speed = parseFloat(el.getAttribute("data-speed")) || 24; el.style.setProperty("--cc-accent", el.getAttribute("data-accent") || "#6366f1"); var ring = document.createElement("div"); ring.className = "cc-ring"; images.forEach(function (src) { var img = document.createElement("img"); img.className = "cc-item"; img.src = src; img.alt = ""; ring.appendChild(img); }); el.replaceChildren(ring); var ResizeObserver(function () { /* re-fit */ }); onResize.observe(el); return function cleanup() { onResize.disconnect(); }; } }); })();The name passed toregister()must equal the component's type, or nothing mounts.
mount(el)must return a cleanup function. The editor re-runsmounton every prop edit, so remove listeners, timers, observers and animation loops there.
Never read a prop you did not declare. Arrays arrive JSON-encoded.
CSS
Send a stylesheet for every class your JavaScript creates; a component whose classes are not styled is rejected. Put layout in CSS, not in JavaScript style strings: CSS paints with the first frame and is the only way to get :hover, media queries and grid. Drive CSS from props with custom properties:
Leave the root transparent; people set its background in the Style tab.
Site fonts and colours
The frame inherits the site's design tokens as CSS variables: --sb-font-family, --sb-heading-font-family, --sb-text, --sb-bg, --sb-surface, --sb-accent, --sb-muted, --sb-border. The root already uses the site font and text colour. Default colour props to a token with a fallback, such as var(--sb-accent, #6366f1). To draw such a value on a canvas or in WebGL, resolve it first with SBComponents.color(el, value, "#6366f1").
Good practice
Size your drawing toeland re-fit it with aResizeObserver.
UseIntersectionObserverfor reveal-on-scroll, never a scroll position.
Honourprefers-reduced-motionfor anything that loops or moves.
Dispose what you create:renderer.dispose()and textures for three,chart.destroy(),anim.destroy()for Lottie.
Questions about building on Praisma Hub? We're happy to help.
Contact us
