Components
Components in Sibyl are reusable pieces of code that can be used to structure your web pages more effectively. Components encapsulate functionality and allow for modularity, which makes your code easier to maintain and scale.
Structure of a Component
A component consists of four parts:
-
HTML (
template
tag) : This is the structure or layout of your component. It includes HTML tags and special directives provided by Sibyl, such asrender-if
for conditional rendering,for-each
for iterating over arrays, and more. -
Python (
python
tag) : This is where you can include Python code to handle logic in your component. This Python code runs when the component is rendered. It can have an optional phase of execution, defaulting to run when entering the component and "cleanup" to run when leaving the component. -
CSS (
style
tag) : This is where you style your component. The CSS is scoped to the component, which means it only applies to the HTML within this component. -
JavaScript (
script
tag) : This is where you can include JavaScript code that is executed on the client side. This can be useful for adding interactivity to your components.
Here's an example of a component:
<template>
<!-- Your HTML goes here -->
</template>
<python>
# Your Python code goes here
</python>
<style>
/* Your CSS goes here */
</style>
<script>
// Your JavaScript goes here
</script>
Using a Component
To use a component in your layouts or pages, use the
Component
tag with the
name
attribute set to the component's name.
For example, here's how you can include the
DrawerItem
component in another component or layout:
<Component render-if="drawerItems" name="Drawer">
<Component
name="DrawerItem"
for-each="drawerItem in drawerItems"
item="{{ drawerItem }}"
/>
</Component>
In this example, DrawerItem is the name of the component, for-each is a directive that loops over the drawerItems array, and item is a prop that passes the current drawerItem to the DrawerItem component.
You can also pass variables to a component using attributes. In the example above, the drawerItem variable is passed to the DrawerItem component using the item attribute.
Variable Naming Conventions
In Sibyl, variables (props) are passed to components using kebab-case (e.g., drawer-item) and accessed within the component using camelCase (e.g., drawerItem). This naming convention keeps the code clean and consistent, while also avoiding naming conflicts with HTML attributes, which are case-insensitive.
Slots
Slots in Sibyl provide a way to pass content from a parent component to its child component. They allow for greater flexibility and customization by enabling dynamic content injection.
Defining a Slot
To define a slot in a component, use the
Slot
tag with a specified name. This name serves as a placeholder for the content that will be passed into the slot. Here's an example:
<template>
<div>
<h1>Welcome to My Website</h1>
<Slot name="Content"></Slot>
</div>
</template>
In this example, the
Slot
tag with the name attribute set to "content" acts as a placeholder for the content that will be injected into the slot.
Using a Slot
To inject content into a slot, use a tag with the specified name within the parent component. Here's an example of using the slot defined above:
<Component name="MyComponent">
<p>This is some custom content.</p>
<p>More content can be added here.</p>
<Content> <!-- This is the slot -->
<p>This content will be injected into the slot.</p>
</Content>
</Component>
Default Slot Content
You can also provide default content for a slot by placing it between the opening and closing
Slot
tags in the child component. This default content will be used if no content is provided from the parent component. Here's an example:
<template>
<div>
<h1>Welcome to My Website</h1>
<Slot name="content">
<p>This is the default content for the slot.</p>
</Slot>
</div>
</template>
The Default Slot
You can also use the default slot to pass content to a component. This is useful when you want to pass content to a component without having to define a slot in the component. To define the default slot, simply create an unnamed slot. Here's an example:
<Component name="MyComponent">
<p>This is some custom content.</p>
<p>More content can be added here.</p>
<!-- This is the default slot -->
<p>This content will be injected into the default slot.</p>
</Component>
And the component:
<template>
<div>
<h1>Welcome to My Website</h1>
<Slot> <!-- This is the default slot, since it has no name -->
<p>This is the default content for the slot.</p>
</Slot>
</div>
</template>
Benefits of Using Components
Components provide several benefits:
- Reusability: Once you've defined a component, you can reuse it in multiple places, reducing code duplication.
- Modularity: Components allow you to split your code into smaller, more manageable pieces.
- Flexibility: By passing props to components, you can create flexible components that can be customized for each use case.
- Interactivity: By including JavaScript in your components, you can add interactivity and enhance the user experience.
Scoped styles
Styles aren't scoped to a component. This means you should be careful with your CSS selectors to avoid conflicts with other components. For example, if you have a component with a class of
button
, you should use a more specific selector like
button.my-component-button
instead of just
.button
to avoid conflicts with other components that may also have a class of
button
.