The StatamicBlock component is used to render the blocks from the Statamic API response.
It will handle the fields from the default "Helper: blok opties" fieldset and pass them as data- attributes to the component. With the exception of the "anchor" field, which is passed as the id attribute.
In order for this component to work, we need to update the nuxt.config.ts and main.css files to include the following:
export default defineNuxtConfig({
components: [
{ path: "~/components/blocks", global: true },
"~/components",
],
});
@import "tailwindcss";
@import "@nobears-front-end/nuxt-statamic";This ensures that the StatamicBlock can find the correct component based on the type field in the block.
<script setup lang="ts">
import { useChangeCase } from '@vueuse/integrations/useChangeCase';
const { data, error } = await useStatamicPage();
useStatamicPageErrorHandler(error);
</script>
<template>
<component
:is="resolveComponent(useChangeCase(block.type, 'pascalCase'))"
v-for="block in data?.blocks"
:key="block.id"
:block="block"
/>
</template>
<script lang="ts">
import type { TextField, StatamicBlockProps } from "@nobears-front-end/nuxt-statamic";
export type TextImageProps = StatamicBlockProps<{
title: TextField;
}>;
</script>
<script setup lang="ts">
defineProps<TextImageProps>();
</script>
<template>
<StatamicBlock :block>
<!-- Content here -->
</StatamicBlock>
</template>
You can build your own custom block by creating a new component in the app/components/blocks directory.
<script lang="ts">
import type { TextField, StatamicBlockProps } from "@nobears-front-end/nuxt-statamic";
export type TextImageProps = StatamicBlockProps<{
title: TextField;
}>;
</script>
<script setup lang="ts">
defineProps<TextImageProps>();
</script>
<template>
<StatamicBlock :block>
<!-- Content here -->
</StatamicBlock>
</template>
You can also add fields to the StatamicBlockOptions type
<script lang="ts">
import type { AssetField, TextField, StatamicBlockProps } from "@nobears-front-end/nuxt-statamic";
export type TextImageOptions = StatamicBlockOptions<
{ title: TextField },
{ background_image: AssetField } // Any additional fields included in the "Helper: blok opties" fieldset
>;
</script>
By default, the StatamicBlock component provides the none, small, medium and large spacing options.
When you need to add more spacing options, you can do so by adding the following to your main.css file:
@import "tailwindcss";
@import "@nobears-front-end/nuxt-statamic";
@theme default inline {
--spacing-statamic-block-extra-large: --spacing(48);
--spacing-statamic-block-extra-large--sm: --spacing(64);
--spacing-statamic-block-extra-large--md: --spacing(80);
}
@layer components {
[data-spacing-top="extra-large"] {
@apply pt-statamic-block-extra-large
sm:pt-statamic-block-extra-large--sm
md:pt-statamic-block-extra-large--md;
}
[data-spacing-bottom="extra-large"] {
/* ... */
}
}
@import "tailwindcss";
@import "@nobears-front-end/nuxt-statamic";
@layer components {
[data-background-color="primary"] {
@apply bg-primary;
}
}
The StatamicBlock exposes the StatamicBlockProps and StatamicBlockOptions types so you can build your own custom block in a unified way.
It includes all the fields that are by default included in the "Helper: blok opties" fieldset when you create a new Statamic project using our template.
Have a look the Building your own custom block example for more information.
/**
* The default fields that are provided by the "Helper: blok opties" fieldset in Statamic, when using our starter-kit.
*/
type StatamicBlockOptions = {
/**
* The background color for the block.
*
* This is added as a `data-background-color` attribute on the root element.
*/
background_color: SelectFieldSingle<string>;
/**
* The padding/spacing at the bottom of the block.
*
* This is added as a `data-spacing-bottom` attribute on the root element.
*/
padding_bottom: ButtonGroupField<"none" | "small" | "medium" | "large" | (string & {})>;
/**
* The padding/spacing at the top of the block.
*
* This is added as a `data-spacing-top` attribute on the root element.
*/
padding_top: ButtonGroupField<"none" | "small" | "medium" | "large" | (string & {})>;
/**
* An anchor ID for the block, used for navigation and linking.
*
* _If provided, this will be used as the `id` attribute instead of the block's Statamic ID._
*/
anchor: TextField;
};
/**
* The props for the StatamicBlock component
* @template T - The type of the block data
* @template O - The type of the options
*/
type StatamicBlockProps<
T extends Record<string, any> = Record<string, any>,
O extends Record<string, any> = StatamicBlockOptions,
> = {
/**
* The block data from Statamic
*
* _When using a {@link https://statamic.dev/fieldtypes/replicator|replicator} field, the `id` and `type` properties will be provided by Statamic._
*/
block: {
/**
* The ID of the block.
*
* _Will always be provided by Statamic when using a {@link https://statamic.dev/fieldtypes/replicator|replicator} field._
*/
id: TextField;
/**
* The type of the block in snake_case.
*
* This is added as a `data-type` attribute on the root element.
*
* _Will always be provided by Statamic when using a {@link https://statamic.dev/fieldtypes/replicator|replicator} field._
*/
type: NonNullable<TextField>;
} & O & T;
/**
* The element or component this component should render as.
*
* Will prioritize components over elements when the name for both is the same.
* @defaultValue "section"
* @example
* The following example will render the `Header` component if it exists in the project, otherwise it will render a `header` element.
* ```vue
* <template>
* <StatamicBlock :block as="header" />
* </template>
* ```
*/
as?: AsTag | Component;
} & Pick<PrimitiveProps, "asChild">;
| Prop | Default | Type |
|---|---|---|
block* | StatamicBlockPropsThe block data from Statamic. | |
as | 'section' | string | ComponentThe element or component that should be rendered. Prioritizes components over elements when both share the same name. |
asChild | booleanChange the default rendered element for the one passed as a child, merging their props and behavior. |
| Attribute | Value | Type |
|---|---|---|
id | props.block.anchor || props.block.id | stringThe value of the anchor field or the block ID. |
data-background-color | props.block.background_color.value | stringThe value of the background color field. |
data-spacing-bottom | props.block.padding_bottom.value | stringThe value of the padding bottom field. |
data-spacing-top | props.block.padding_top.value | stringThe value of the padding top field. |
data-type | props.block.type | stringThe type of the block. |
The spacing for the StatamicBlock component is controlled by the [data-spacing-{side}] attribute. The {side} can be top or bottom. We use a tailwindcss @layer components definition to then apply the spacing to the block. (Take a look at the Adding custom spacings section for more information.)
The CSS variables for controling the spacing for the StatamicBlock component follow the format:
--spacing-statamic-block-{spacing}-{breakpoint}
{spacing} - The spacing value (e.g., none, small, medium, large).{breakpoint} - Optional breakpoint modifier (e.g., sm, md, lg). When omitted, the variable applies globally.| CSS Variable | Value |
|---|---|
--spacing-statamic-block-none | --spacing(0) |
--spacing-statamic-block-small | --spacing(6) |
--spacing-statamic-block-small--sm | --spacing(10) |
--spacing-statamic-block-small--md | --spacing(12) |
--spacing-statamic-block-medium | --spacing(12) |
--spacing-statamic-block-medium--sm | --spacing(20) |
--spacing-statamic-block-medium--md | --spacing(24) |
--spacing-statamic-block-large | --spacing(24) |
--spacing-statamic-block-large--sm | --spacing(40) |
--spacing-statamic-block-large--md | --spacing(48) |