Here’s the code for our Tabs component (Tabs.svelte
):
<script>
import * as BuilderSDK from "@builder.io/sdk-svelte";
export let tabList;
export let builderBlock;
export let builderContext;
let activeTab = 0;
function selectTab(tab) {
activeTab = tab;
}
$: {
console.log("Active Tab", tabList[activeTab], builderBlock, builderContext);
}
</script>
<style>
.section-header {
margin-left: 130px; /* lg:mx-[130px] */
overflow: hidden;
}
.section-header h2 {
margin-left: 4px; /* mx-4 */
margin-bottom: 5px; /* mb-5 */
font-size: 1.875rem; /* text-3xl */
font-weight: bold; /* bold */
}
.tabs-wrap {
display: flex;
flex-wrap: wrap;
}
.tabs button {
padding-top: .5rem; /* py-6 */
padding-right: 1rem; /* px-4 */
padding-bottom: .5rem; /* py-6 */
padding-left: 1rem; /* px-4 */
border: 0.25rem; /* border-b-4 */
border-style: solid; /* border-solid */
cursor: pointer;
font-weight: bold;
font-size: 1rem; /* text-xl */
line-height: 1; /* leading-normal */
white-space: nowrap; /* whitespace-nowrap */
color: #333; /* text-[#333] */
border-color: #fff; /* border-[#fff] */
}
.tabs button.active {
border-color: #00c853; /* border-green-500 */
}
</style>
<div class="section-header">
<h2>Svelte Tabs Component</h2>
<div class="tabs-wrap">
<div class="tabs flex">
{#if tabList}
{#each tabList as tab, index}
<button
class:active="{activeTab === index}"
on:click={() => selectTab(index)}
>
{tab.tabName}
</button>
{/each}
{/if}
</div>
{#if tabList && tabList?.length != 0}
<slot />
{/if}
</div>
{#if tabList && tabList?.length != 0}
<BuilderSDK.Blocks
parent={builderBlock?.id}
path={`component?.options?.tabList?.${activeTab}.children`}
blocks={tabList[activeTab]?.children}
/>
{/if}
</div>
Here is the code for +page.svelte
<script>
import Tabs from "../Tabs.svelte";
import { isPreviewing, Content } from "@builder.io/sdk-svelte";
import { BUILDER_PUBLIC_API_KEY } from "../../apiKey";
// Create an array of your custom components and their properties
const CUSTOM_COMPONENTS = [
{
component: Tabs,
name: "TabFields",
canHaveChildren: true,
inputs: [
{
name: "tabList",
type: "list",
subFields: [
{
name: "tabName",
type: "string",
},
{
name: "children",
type: "blocks",
defaultValue: [
{
"@type": "@builder.io/sdk:Element",
component: {
name: "Text",
options: {
text: "This is editable block within the builder editor",
},
},
responsiveStyles: {
large: {
display: "flex",
flexDirection: "column",
position: "relative",
flexShrink: "0",
boxSizing: "border-box",
marginTop: "8px",
lineHeight: "normal",
height: "200px",
textAlign: "left",
minHeight: "200px",
},
small: {
height: "200px",
},
},
},
],
},
],
},
],
},
];
// this data comes from the function in `+page.server.js`, which runs on the server only
export let data;
// we want to show unpublished content when in preview mode.
const canShowContent = data.content || isPreviewing();
</script>
<svelte:head>
<title>Home</title>
</svelte:head>
<main>
<h1>Welcome to SvelteKit</h1>
<div>Below is your Builder Content:</div>
{#if canShowContent}
<div>page Title: {data.content?.data?.title || "Unpublished"}</div>
<Content
model="page"
content={data.content}
apiKey={BUILDER_PUBLIC_API_KEY}
customComponents={CUSTOM_COMPONENTS}
enrich={true}
/>
{:else}
Content Not Found
{/if}
</main>
<footer>
<p>
Visit <a href="https://www.builder.io/c/docs/custom-components-children">Builder.io</a> to read the documentation
</p>
</footer>
<style>
h1 {
width: 100%;
font-size: 2rem;
text-align: center;
}
footer {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 40px;
}
@media (min-width: 480px) {
footer {
padding: 40px 0;
}
}
</style>