I have created a simple Tailwind used code in Svelte:
<div class="w-full px-16 py-10"><div class="heading-1"><h1 class="text-[2.25rem] font-bold border-none mb-2.5"> The Sydney Sprinter: when lighting design meets technology</h1><div class="flex items-end"><div class="w-2/3"><img class="w-full" src="https://loremflickr.com/200/200?random=1" alt="reference" /></div><div class="w-1/3 px-6"><p class="text-xl">Sample text</p></div></div></div></div>
and script
contains a JSON object which contains Blocks
. It's an array of objects that I want to use to generate dynamic component blocks. I have created heading-1
style as a sample.
<script lang="ts"> const SAMPLE_JSON = { Blocks: [ { Type: 'Text', Style: 'Heading-1', Content: 'Hello, World!' }, { Type: 'Text', Style: 'Heading-2', Content: 'Short description' }, { Type: 'Text', Style: 'Paragraph', Content: 'This is a simple JSON file.' }, { Type: 'Text', Style: 'Heading-2', Content: 'Image' } ] };</script>
However, I want to generate different types of component blocks dynamically depending on my JSON object. For instance, for Text
type and heading-1
Style, it will be one block and same with others.
I have thought of creating a Block
component and generating multiple blocks, but it will be too many if/else
conditions. Something like:
{#if type === 'Text'} {#if style === 'Heading-1'}<h1 class="text-[2.25rem] font-bold mb-2.5">{content}</h1> {:else if style === 'Heading-2'}<h2 class="text-[1.5rem] font-bold mb-2">{content}</h2> {:else if style === 'Paragraph'}<p class="text-lg mb-4">{content}</p> {/if}{:else if type === 'Image'}<img src={content} alt="reference" class="w-full" />{/if}
Thus, Is there any better and optimal way of creating dynamic content blocks in Svelte?
Edit:
I have modified my code a bit to achieve desired result, where:
- Modified
script
to handle TypeScript with types:
<script lang="ts"> export type BlockType = { Type: string; Style: string; ImageUrl: string; Title: string; Content: string; TextSize: string; TextAlign: 'end' | 'start'; TextColor: 'white' | 'black'; BackgroundColor: 'white' | 'black'; }; type SampleJsonType = { Blocks: BlockType[]; }; const SAMPLE_JSON: SampleJsonType = { Blocks: [ { Type: 'Text', Style: 'Heading-1', ImageUrl: '/images/references/WE-EF_Schloss_Neuschwanstein_Seite_09 2.png', Title: 'Sample Title', Content: 'Sample Text', TextSize: '2.25rem', TextAlign: 'end', TextColor: 'black', BackgroundColor: 'white' } ] };</script>
- Added a loop to loop through the blocks:
<div class="w-full h-full px-16 py-10"> {#each SAMPLE_JSON.Blocks as block}<div class="heading-1 mb-10"><h1 class="text-[{block.TextSize}] font-bold border-none mb-2.5"> {block.Title}</h1><div class="flex w-full items-{block.TextAlign} bg-{block.BackgroundColor} text-{block.TextColor}"><div class="w-2/3"><img class="w-full" src={block.ImageUrl} alt="reference" /></div><div class="w-1/3 px-6"><p class="text-xl">{block.Content}</p></div></div></div> {/each}</div>
However, I'm still not quite sure if this is a good approach, especially to handle the Style: 'Heading-1'
. I'm open to suggestions on this case.