Skip to main content

defineComponent Plugin

The defineComponent plugin is Coralite's core built-in plugin that enables dynamic template functionality. It provides the wrapper for tokens, slots, and script execution in templates that need data processing and client-side interactivity.

What is defineComponent #

defineComponent is a built-in Coralite plugin enables data processing, computed values, or client-side Javascript. It's available as a core plugin from both coralite and coralite/plugins:

JavaScript
Code copied!

// Option 1: Import from coralite (core plugin)
import { defineComponent } from 'coralite'

// Option 2: Import from coralite/plugins (all plugins)
import { defineComponent } from 'coralite/plugins'

export default defineComponent({
  // Component configuration
})
      

When to Use defineComponent #

Use defineComponent When: #

Do NOT Use defineComponent When: #

Template Type Comparison #

Static Template (No defineComponent) #

HTML
Code copied!
<template id="simple-component">
  <div>
    <h1>{{ title }}</h1>
    <p>{{ description }}</p>
  </div>
</template>

No script tag needed - Coralite processes token replacements automatically.

Dynamic Template (With defineComponent) #

HTML
Code copied!
<template id="dynamic-component">
  <div>
    <h1>{{ greeting }}</h1>
    <button type="button" ref="actionBtn">Click me</button>
  </div>
</template>

<script type="module">
  import { defineComponent } from 'coralite'
  
  export default defineComponent({
    tokens: {
      greeting: ({ name }) => `Hello, ${name}!`
    },
    script: (context, helpers) => {
      const btn = helpers.refs('actionBtn')
      btn.addEventListener('click', () => {
        console.log('Button clicked!')
      })
    }
  })
</script>

Requires defineComponent as the default export.

Basic Usage #

Here's the minimal setup for a dynamic template:

HTML
Code copied!
<template id="my-component">
  <div>
    <h1>{{ title }}</h1>
  </div>
</template>

<script type="module">
  import { defineComponent } from 'coralite'
  
  export default defineComponent({
    tokens: {
      title: () => 'My Component Title'
    }
  })
</script>

Tokens #

Tokens are computed values that are processed at build time. They can be strings or functions that return values based on the template's context.

Token Structure #

JavaScript
Code copied!

export default defineComponent({
  tokens: {
    // Static token (string)
    staticValue: 'Hello World',
    
    // Computed token (function)
    fullName: ({ firstName, lastName }) => `${firstName} ${lastName}`,
    
    // Token with data processing
    formattedDate: ({ date }) => new Date(date).toLocaleDateString(),
    
    // Token with conditional logic
    status: ({ isActive }) => isActive ? 'Active' : 'Inactive'
  }
})
      

Token Context #

Token functions receive a values parameter containing:

HTML
Code copied!
<!-- Page: user.html -->

<head>
  <meta name="firstName" content="Alice"></meta>
  <meta name="lastName" content="Smith"></meta>
  <title>User Profile</title>
</head>
<body>
  <user-profile age="25"></user-profile>
</body>
JavaScript
Code copied!

// In defineComponent:
export default defineComponent({
  tokens: {
    // values = { $firstName: "Alice", $lastName: "Smith", $title: "User Profile", age: "25" }
    fullName: ({ $firstName, $lastName }) => `${$firstName} ${$lastName}`,
    greeting: ({ age }) => `You are ${age} years old`
  }
})
      

Slots #

Slots allow you to process and transform content that is passed between custom element tags.

Basic Slot Processing #

HTML
Code copied!
<template id="card-component">
  <div class="card">
    <div class="card-content">
      {{ content }}
    </div>
  </div>
</template>

<script type="module">
  import { defineComponent } from 'coralite'
  
  export default defineComponent({
    slots: {
      content: (slotNodes, values) => {
        // Transform slot content
        return slotNodes
      }
    }
  })
</script>

Slot Function Parameters #

Slot Example #

HTML
Code copied!
<!-- Using the component -->

<card-component>
  <h2>Card Title</h2>
  <p>Card content goes here</p>
</card-component>
JavaScript
Code copied!

// In defineComponent:
export default defineComponent({
  slots: {
    content: (slotNodes, values) => {
      // Add classes or transform content
      return slotNodes.map(node => {
        if (node.type === 'tag' && node.name === 'h2') {
          node.attribs.class = 'card-title'
        }
        return node
      })
    }
  }
})
      

Script #

The script function provides client-side JavaScript execution. It gets serialized and runs in the browser after the page loads.

Script Function Signature #

JavaScript
Code copied!

export default defineComponent({
  script: (context, helpers) => {
    // context: Contains processed token values
    // helpers: Contains client-side helpers like refs
    
    // Return JavaScript code as string OR
    return `
      const btn = refs('actionBtn');
      btn.addEventListener('click', () => {
        console.log('Clicked!');
      });
    `
    
    // OR execute directly (less common)
    // (code runs immediately)
  }
})
      

Script Context #

Script Helpers #

Script Example #

HTML
Code copied!
<template id="counter">
  <div>
    <h2>Count: {{ count }}</h2>
    <button type="button" ref="increment">+</button>
    <button type="button" ref="decrement">-</button>
  </div>
</template>

<script type="module">
  import { defineComponent } from 'coralite'
  
  export default defineComponent({
    tokens: {
      count: ({ initial }) => parseInt(initial) || 0
    },
    script: (context, helpers) => {
      const refs = helpers.refs
      const increment = refs('increment')
      const decrement = refs('decrement')
      
      let count = context.values.count
      
      increment.addEventListener('click', () => {
        count++
        document.querySelector('h2').textContent = `Count: ${count}`
      })
      
      decrement.addEventListener('click', () => {
        count--
        document.querySelector('h2').textContent = `Count: ${count}`
      })
    }
  })
</script>

Complete Example #

Here's a complete example showing all defineComponent features working together:

HTML
Code copied!
<!-- Page: product.html -->

<head>
  <meta name="name" content="Coralite Pro"></meta>
  <meta name="price" content="99.99"></meta>
  <meta name="inStock" content="true"></meta>
  <title>Product Details</title>
</head>
<body>
  <product-card discount="10" show-details="true"></product-card>
</body>
HTML
Code copied!
<!-- Template: product-card.html -->

<template id="product-card">
  <div class="product-card">
    <h2>{{ productName }}</h2>
    <p class="price">{{ displayPrice }}</p>
    <div class="status">{{ stockStatus }}</div>
    <div class="details">
      {{ details }}
    </div>
    <button type="button" ref="buyBtn">Buy Now</button>
  </div>
</template>

<script type="module">
  import { defineComponent } from 'coralite'
  
  export default defineComponent({
    tokens: {
      // Computed token from page metadata
      productName: ({ $name }) => $name,
      
      // Computed token with calculation
      displayPrice: ({ $price, discount }) => {
        const price = parseFloat($price)
        const discountPercent = parseFloat(discount) || 0
        const finalPrice = price * (1 - discountPercent / 100)
        return `$${finalPrice.toFixed(2)}`
      },
      
      // Conditional token
      stockStatus: ({ $inStock }) => 
        $inStock === 'true' ? 'In Stock' : 'Out of Stock'
    },
    
    slots: {
      details: (slotNodes, values) => {
        // Only show details if show-details attribute is true
        if (values.showDetails !== 'true') {
          return []
        }
        return slotNodes
      }
    },
    
    script: (context, helpers) => {
      const refs = helpers.refs
      const buyBtn = refs('buyBtn')
      
      if (buyBtn) {
        buyBtn.addEventListener('click', () => {
          alert(`Thank you for purchasing ${context.values.productName}!`)
        })
      }
    }
  })
</script>

Key Points #

Start Building with Coralite!

Use the scaffolding script to get jump started into your next project with Coralite

Copied commandline!