From ef523ed509a32a6ceec41790bed630a7fe5b694f Mon Sep 17 00:00:00 2001
From: Haris Khan <hariskhan201718@gmail.com>
Date: Wed, 9 Apr 2025 16:33:22 +0500
Subject: [PATCH] feat: blocks components created

---
 .../localaction/localaction.component.yml     | 13 +++++
 .../localaction/localaction.stories.json      |  1 +
 .../localaction/localaction.stories.twig      | 16 ++++++
 components/block/localaction/localaction.twig | 12 ++++
 .../block/localtasks/localtasks.component.yml | 28 +++++++++
 .../block/localtasks/localtasks.stories.json  |  1 +
 .../block/localtasks/localtasks.stories.twig  | 21 +++++++
 components/block/localtasks/localtasks.twig   | 13 +++++
 .../block/mainblock/mainblock.component.yml   | 36 ++++++++++++
 .../block/mainblock/mainblock.stories.json    |  1 +
 .../block/mainblock/mainblock.stories.twig    | 28 +++++++++
 components/block/mainblock/mainblock.twig     | 45 +++++++++++++++
 .../block/searchform/searchform.component.yml | 57 +++++++++++++++++++
 .../block/searchform/searchform.stories.json  |  1 +
 .../block/searchform/searchform.stories.twig  | 23 ++++++++
 components/block/searchform/searchform.twig   | 46 +++++++++++++++
 .../systembranding.component.yml              | 48 ++++++++++++++++
 .../systembranding.stories.json               |  1 +
 .../systembranding.stories.twig               | 29 ++++++++++
 .../block/systembranding/systembranding.twig  | 29 ++++++++++
 .../block/systemmenu/systemmenu.component.yml | 52 +++++++++++++++++
 .../block/systemmenu/systemmenu.stories.json  |  1 +
 .../block/systemmenu/systemmenu.stories.twig  | 30 ++++++++++
 components/block/systemmenu/systemmenu.twig   | 57 +++++++++++++++++++
 .../block--local-actions-block.html.twig      |  9 +--
 .../block/block--local-tasks-block.html.twig  |  9 +--
 .../block/block--search-form-block.html.twig  | 18 +-----
 .../block--system-branding-block.html.twig    | 17 +-----
 .../block/block--system-menu-block.html.twig  | 24 +-------
 templates/block/block.html.twig               | 18 +-----
 30 files changed, 595 insertions(+), 89 deletions(-)
 create mode 100644 components/block/localaction/localaction.component.yml
 create mode 100644 components/block/localaction/localaction.stories.json
 create mode 100644 components/block/localaction/localaction.stories.twig
 create mode 100644 components/block/localaction/localaction.twig
 create mode 100644 components/block/localtasks/localtasks.component.yml
 create mode 100644 components/block/localtasks/localtasks.stories.json
 create mode 100644 components/block/localtasks/localtasks.stories.twig
 create mode 100644 components/block/localtasks/localtasks.twig
 create mode 100644 components/block/mainblock/mainblock.component.yml
 create mode 100644 components/block/mainblock/mainblock.stories.json
 create mode 100644 components/block/mainblock/mainblock.stories.twig
 create mode 100644 components/block/mainblock/mainblock.twig
 create mode 100644 components/block/searchform/searchform.component.yml
 create mode 100644 components/block/searchform/searchform.stories.json
 create mode 100644 components/block/searchform/searchform.stories.twig
 create mode 100644 components/block/searchform/searchform.twig
 create mode 100644 components/block/systembranding/systembranding.component.yml
 create mode 100644 components/block/systembranding/systembranding.stories.json
 create mode 100644 components/block/systembranding/systembranding.stories.twig
 create mode 100644 components/block/systembranding/systembranding.twig
 create mode 100644 components/block/systemmenu/systemmenu.component.yml
 create mode 100644 components/block/systemmenu/systemmenu.stories.json
 create mode 100644 components/block/systemmenu/systemmenu.stories.twig
 create mode 100644 components/block/systemmenu/systemmenu.twig

diff --git a/components/block/localaction/localaction.component.yml b/components/block/localaction/localaction.component.yml
new file mode 100644
index 0000000..41d363c
--- /dev/null
+++ b/components/block/localaction/localaction.component.yml
@@ -0,0 +1,13 @@
+$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+
+name: localaction
+label: 'Local Action'
+description: 'Component for rendering local action (primary admin actions).'
+category: 'Navigation'
+
+schema:
+  properties:
+    content:
+      type: string
+      description: 'The rendered HTML content of the local actions.'
+      default: '<ul class="action-links"><li><a href="/admin">Admin Action</a></li></ul>'
diff --git a/components/block/localaction/localaction.stories.json b/components/block/localaction/localaction.stories.json
new file mode 100644
index 0000000..fe796b9
--- /dev/null
+++ b/components/block/localaction/localaction.stories.json
@@ -0,0 +1 @@
+{"title":"Components\/Local Action","parameters":{"server":{"url":"https:\/\/sdc4.ddev.site\/storybook\/stories\/render"}},"stories":[{"name":"Default Local Action","args":{"content":"<ul class=\"action-links\"><li><a href=\"\/random-page\">Go to Random Page<\/a><\/li><\/ul>"},"parameters":{"server":{"id":"eyJwYXRoIjoidGhlbWVzXC9jdXN0b21cL3RhaWxwaW5lXC9jb21wb25lbnRzXC9ibG9ja1wvbG9jYWxhY3Rpb25cL2xvY2FsYWN0aW9uLnN0b3JpZXMudHdpZyIsImlkIjoiZGVmYXVsdCJ9"}}}]}
\ No newline at end of file
diff --git a/components/block/localaction/localaction.stories.twig b/components/block/localaction/localaction.stories.twig
new file mode 100644
index 0000000..9570f03
--- /dev/null
+++ b/components/block/localaction/localaction.stories.twig
@@ -0,0 +1,16 @@
+{% stories localaction with { title: 'Components/Local Action' } %}
+
+{% story default with {
+  name: 'Default Local Action',
+  args: {
+    content: '<ul class="action-links"><li><a href="/random-page">Go to Random Page</a></li></ul>'
+  }
+} %}
+
+{% embed 'tailpine:localaction' with {
+    content: content
+  }%}{% endembed %}
+
+{% endstory %}
+
+{% endstories %}
diff --git a/components/block/localaction/localaction.twig b/components/block/localaction/localaction.twig
new file mode 100644
index 0000000..29463ea
--- /dev/null
+++ b/components/block/localaction/localaction.twig
@@ -0,0 +1,12 @@
+{#
+/**
+ * @file
+ * Theme override for local actions (primary admin actions.)
+ */
+#}
+{% block content %}
+	{% if content %}
+		<nav class="action-links">{{ content }}</nav>
+	{% endif %}
+{% endblock %}
+
diff --git a/components/block/localtasks/localtasks.component.yml b/components/block/localtasks/localtasks.component.yml
new file mode 100644
index 0000000..45cc686
--- /dev/null
+++ b/components/block/localtasks/localtasks.component.yml
@@ -0,0 +1,28 @@
+$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+
+name: localtasks
+label: 'Local Tasks'
+description: 'Component for rendering tabs navigation with content.'
+category: 'Navigation'
+
+schema:
+  properties:
+    configuration:
+      type: object
+      properties:
+        label:
+          type: string
+          description: 'The configured label for the navigation block.'
+          default: 'Local Tasks'
+        provider:
+          type: string
+          description: 'The module or provider of the block.'
+          default: 'system'
+    content:
+      type: string
+      description: 'The content to be rendered inside the tabs.'
+      default: ''
+    attributes:
+      type: object
+      description: 'HTML attributes for the container.'
+      default: {}
diff --git a/components/block/localtasks/localtasks.stories.json b/components/block/localtasks/localtasks.stories.json
new file mode 100644
index 0000000..88ce292
--- /dev/null
+++ b/components/block/localtasks/localtasks.stories.json
@@ -0,0 +1 @@
+{"title":"Components\/Local Tasks","parameters":{"server":{"url":"https:\/\/sdc4.ddev.site\/storybook\/stories\/render"}},"stories":[{"name":"Default Local Tasks Block","args":{"configuration":{"label":"Local Tasks Block","provider":"system"},"content":"<ul><li><a href=\"#task1\">Task 1<\/a><\/li><li><a href=\"#task2\">Task 2<\/a><\/li><li><a href=\"#task3\">Task 3<\/a><\/li><\/ul>"},"parameters":{"server":{"id":"eyJwYXRoIjoidGhlbWVzXC9jdXN0b21cL3RhaWxwaW5lXC9jb21wb25lbnRzXC9ibG9ja1wvbG9jYWx0YXNrc1wvbG9jYWx0YXNrcy5zdG9yaWVzLnR3aWciLCJpZCI6ImRlZmF1bHQifQ%3D%3D"}}}]}
\ No newline at end of file
diff --git a/components/block/localtasks/localtasks.stories.twig b/components/block/localtasks/localtasks.stories.twig
new file mode 100644
index 0000000..dd18182
--- /dev/null
+++ b/components/block/localtasks/localtasks.stories.twig
@@ -0,0 +1,21 @@
+{% stories localtasks with { title: 'Components/Local Tasks' } %}
+
+{% story default with {
+  name: 'Default Local Tasks Block',
+  args: {
+    configuration: {
+      label: 'Local Tasks Block',
+      provider: 'system'
+    },
+    content: '<ul><li><a href="#task1">Task 1</a></li><li><a href="#task2">Task 2</a></li><li><a href="#task3">Task 3</a></li></ul>'
+  }
+} %}
+
+{% embed 'tailpine:localtasks' with {
+    configuration: configuration,
+    content: content
+  }%}{% endembed %}
+
+{% endstory %}
+
+{% endstories %}
diff --git a/components/block/localtasks/localtasks.twig b/components/block/localtasks/localtasks.twig
new file mode 100644
index 0000000..13f7bfe
--- /dev/null
+++ b/components/block/localtasks/localtasks.twig
@@ -0,0 +1,13 @@
+{#
+/**
+ * @file
+ * Theme override for tabs.
+ */
+#}
+{% block content %}
+  {% if content %}
+    <nav class="tabs" role="navigation" aria-label="{{ 'Tabs'|t }}">
+      {{ content }}
+    </nav>
+  {% endif %}
+{% endblock %}
diff --git a/components/block/mainblock/mainblock.component.yml b/components/block/mainblock/mainblock.component.yml
new file mode 100644
index 0000000..07fc015
--- /dev/null
+++ b/components/block/mainblock/mainblock.component.yml
@@ -0,0 +1,36 @@
+$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+
+name: mainblock
+label: 'Main Block'
+description: 'Generic block component with optional title and content.'
+category: 'Blocks'
+
+schema:
+  properties:
+    plugin_id:
+      type: string
+      description: 'The ID of the block implementation.'
+      default: ''
+    label:
+      type: string
+      description: 'The configured label of the block.'
+      default: ''
+    configuration:
+      type: object
+      properties:
+        provider:
+          type: string
+          description: 'The module or provider of the block.'
+          default: 'custom'
+    title_prefix:
+      type: string
+      description: 'Additional markup before the block title.'
+      default: ''
+    title_suffix:
+      type: string
+      description: 'Additional markup after the block title.'
+      default: ''
+    content:
+      type: string
+      description: 'The main content of the block.'
+      default: '<p>Block content here.</p>'
diff --git a/components/block/mainblock/mainblock.stories.json b/components/block/mainblock/mainblock.stories.json
new file mode 100644
index 0000000..a0ceb9a
--- /dev/null
+++ b/components/block/mainblock/mainblock.stories.json
@@ -0,0 +1 @@
+{"title":"Components\/Blocks","parameters":{"server":{"url":"https:\/\/sdc4.ddev.site\/storybook\/stories\/render"}},"stories":[{"name":"Default Block","args":{"plugin_id":"custom_block_plugin","label":"Sample Block Title","configuration":{"provider":"custom"},"title_prefix":"<span class=\"title-prefix\">Prefix<\/span>","title_suffix":"<span class=\"title-suffix\">Suffix<\/span>","content":"<p>This is the block content.<\/p>"},"parameters":{"server":{"id":"eyJwYXRoIjoidGhlbWVzXC9jdXN0b21cL3RhaWxwaW5lXC9jb21wb25lbnRzXC9ibG9ja1wvbWFpbmJsb2NrXC9tYWluYmxvY2suc3Rvcmllcy50d2lnIiwiaWQiOiJkZWZhdWx0In0%3D"}}}]}
\ No newline at end of file
diff --git a/components/block/mainblock/mainblock.stories.twig b/components/block/mainblock/mainblock.stories.twig
new file mode 100644
index 0000000..2b4d54b
--- /dev/null
+++ b/components/block/mainblock/mainblock.stories.twig
@@ -0,0 +1,28 @@
+{% stories blocks with { title: 'Components/Blocks' } %}
+
+{% story default with {
+  name: 'Default Block',
+  args: {
+    plugin_id: 'custom_block_plugin',
+    label: 'Sample Block Title',
+    configuration: {
+      provider: 'custom'
+    },
+    title_prefix: '<span class="title-prefix">Prefix</span>',
+    title_suffix: '<span class="title-suffix">Suffix</span>',
+    content: '<p>This is the block content.</p>'
+  }
+} %}
+
+{% embed 'tailpine:mainblock' with {
+    plugin_id: plugin_id,
+    label: label,
+    configuration: configuration,
+    title_prefix: title_prefix,
+    title_suffix: title_suffix,
+    content: content
+  }%}{% endembed %}
+
+{% endstory %}
+
+{% endstories %}
diff --git a/components/block/mainblock/mainblock.twig b/components/block/mainblock/mainblock.twig
new file mode 100644
index 0000000..114d7c4
--- /dev/null
+++ b/components/block/mainblock/mainblock.twig
@@ -0,0 +1,45 @@
+{#
+/**
+ * @file
+ * Theme override to display a block.
+ *
+ * Available variables:
+ * - plugin_id: The ID of the block implementation.
+ * - label: The configured label of the block if visible.
+ * - configuration: A list of the block's configuration values.
+ *   - label: The configured label for the block.
+ *   - label_display: The display settings for the label.
+ *   - provider: The module or other provider that provided this block plugin.
+ *   - Block plugin specific settings will also be stored here.
+ * - in_preview: Whether the plugin is being rendered in preview mode.
+ * - content: The content of this block.
+ * - attributes: array of HTML attributes populated by modules, intended to
+ *   be added to the main container tag of this template.
+ *   - id: A valid HTML ID and guaranteed unique.
+ * - title_attributes: Same as attributes, except applied to the main title
+ *   tag that appears in the template.
+ * - title_prefix: Additional output populated by modules, intended to be
+ *   displayed in front of the main title tag that appears in the template.
+ * - title_suffix: Additional output populated by modules, intended to be
+ *   displayed after the main title tag that appears in the template.
+ *
+ * @see template_preprocess_block()
+ */
+#}
+{%
+  set classes = [
+    'block',
+    'block-' ~ configuration.provider|clean_class,
+    'block-' ~ plugin_id|clean_class,
+  ]
+%}
+<div{{ attributes.addClass(classes) }}>
+  {{ title_prefix }}
+  {% if label %}
+    <h2{{ title_attributes }}>{{ label }}</h2>
+  {% endif %}
+  {{ title_suffix }}
+  {% block content %}
+    {{ content }}
+  {% endblock %}
+</div>
diff --git a/components/block/searchform/searchform.component.yml b/components/block/searchform/searchform.component.yml
new file mode 100644
index 0000000..0955c73
--- /dev/null
+++ b/components/block/searchform/searchform.component.yml
@@ -0,0 +1,57 @@
+$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+
+name: searchform
+label: 'Search Form Block'
+description: 'Component for rendering the search form block.'
+category: 'Blocks'
+
+schema:
+  properties:
+    plugin_id:
+      type: string
+      description: 'The ID of the block implementation.'
+      default: 'search_form_block'
+    label:
+      type: string
+      description: 'The label of the block, if visible.'
+      default: 'Search'
+    configuration:
+      type: object
+      description: 'Block configuration values.'
+      properties:
+        label:
+          type: string
+          description: 'Configured label for the block.'
+          default: 'Search'
+        label_display:
+          type: string
+          description: 'Display settings for the label.'
+          default: 'visible'
+        provider:
+          type: string
+          description: 'The module or provider that provided this block.'
+          default: 'search'
+    in_preview:
+      type: boolean
+      description: 'Whether the plugin is being rendered in preview mode.'
+      default: false
+    content:
+      type: string
+      description: 'Rendered content of the search form.'
+      default: ''
+    title_prefix:
+      type: string
+      description: 'Additional output before the block title.'
+      default: ''
+    title_suffix:
+      type: string
+      description: 'Additional output after the block title.'
+      default: ''
+    attributes:
+      type: object
+      description: 'HTML attributes for the container.'
+      default: {}
+    title_attributes:
+      type: object
+      description: 'HTML attributes for the title.'
+      default: {}
diff --git a/components/block/searchform/searchform.stories.json b/components/block/searchform/searchform.stories.json
new file mode 100644
index 0000000..daedfbd
--- /dev/null
+++ b/components/block/searchform/searchform.stories.json
@@ -0,0 +1 @@
+{"title":"Components\/Search Form","parameters":{"server":{"url":"https:\/\/sdc4.ddev.site\/storybook\/stories\/render"}},"stories":[{"name":"Default Search Form Block","args":{"configuration":{"label":"Search Form Block","provider":"search"},"title_prefix":"<span class=\"title-prefix\">Prefix<\/span>","title_suffix":"<span class=\"title-suffix\">Suffix<\/span>"},"parameters":{"server":{"id":"eyJwYXRoIjoidGhlbWVzXC9jdXN0b21cL3RhaWxwaW5lXC9jb21wb25lbnRzXC9ibG9ja1wvc2VhcmNoZm9ybVwvc2VhcmNoZm9ybS5zdG9yaWVzLnR3aWciLCJpZCI6ImRlZmF1bHQifQ%3D%3D"}}}]}
\ No newline at end of file
diff --git a/components/block/searchform/searchform.stories.twig b/components/block/searchform/searchform.stories.twig
new file mode 100644
index 0000000..4529dea
--- /dev/null
+++ b/components/block/searchform/searchform.stories.twig
@@ -0,0 +1,23 @@
+{% stories searchform with { title: 'Components/Search Form' } %}
+
+{% story default with {
+  name: 'Default Search Form Block',
+  args: {
+    configuration: {
+      label: 'Search Form Block',
+      provider: 'search'
+    },
+    title_prefix: '<span class="title-prefix">Prefix</span>',
+    title_suffix: '<span class="title-suffix">Suffix</span>'
+  }
+} %}
+
+{% embed 'tailpine:searchform' with {
+    configuration: configuration,
+    title_prefix: title_prefix,
+    title_suffix: title_suffix
+  }%}{% endembed %}
+
+{% endstory %}
+
+{% endstories %}
diff --git a/components/block/searchform/searchform.twig b/components/block/searchform/searchform.twig
new file mode 100644
index 0000000..d1cda72
--- /dev/null
+++ b/components/block/searchform/searchform.twig
@@ -0,0 +1,46 @@
+{#
+/**
+ * @file
+ * Theme override for the search form block.
+ *
+ * Available variables:
+ * - plugin_id: The ID of the block implementation.
+ * - label: The configured label of the block if visible.
+ * - configuration: A list of the block's configuration values, including:
+ *   - label: The configured label for the block.
+ *   - label_display: The display settings for the label.
+ *   - provider: The module or other provider that provided this block plugin.
+ *   - Block plugin specific settings will also be stored here.
+ * - in_preview: Whether the plugin is being rendered in preview mode.
+ * - content: The content of this block.
+ * - attributes: A list HTML attributes populated by modules, intended to
+ *   be added to the main container tag of this template. Includes:
+ *   - id: A valid HTML ID and guaranteed unique.
+ * - title_attributes: Same as attributes, except applied to the main title
+ *   tag that appears in the template.
+ * - title_prefix: Additional output populated by modules, intended to be
+ *   displayed in front of the main title tag that appears in the template.
+ * - title_suffix: Additional output populated by modules, intended to be
+ *   displayed after the main title tag that appears in the template.
+ *
+ * @see template_preprocess_block()
+ * @see search_preprocess_block()
+ */
+#}
+{%
+  set classes = [
+    'block',
+    'block-search',
+    'container-inline',
+  ]
+%}
+<div{{ attributes.addClass(classes) }}>
+  {{ title_prefix }}
+  {% if label %}
+    <h2{{ title_attributes }}>{{ label }}</h2>
+  {% endif %}
+  {{ title_suffix }}
+  {% block content %}
+    {{ content }}
+  {% endblock %}
+</div>
diff --git a/components/block/systembranding/systembranding.component.yml b/components/block/systembranding/systembranding.component.yml
new file mode 100644
index 0000000..3fbafa6
--- /dev/null
+++ b/components/block/systembranding/systembranding.component.yml
@@ -0,0 +1,48 @@
+$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+
+name: systembranding
+label: 'System Branding'
+description: 'Component for rendering branding block with site name, slogan, and logo.'
+category: 'Branding'
+
+schema:
+  properties:
+    configuration:
+      type: object
+      properties:
+        label:
+          type: string
+          description: 'The configured label of the branding block.'
+          default: 'Site Branding'
+        provider:
+          type: string
+          description: 'The module or provider of the block.'
+          default: 'system'
+    site_logo:
+      type: string
+      description: 'The URL of the site logo.'
+      default: '/themes/custom/mytheme/logo.svg'
+    site_name:
+      type: string
+      description: 'The name of the site.'
+      default: 'My Website'
+    site_slogan:
+      type: string
+      description: 'The site slogan.'
+      default: 'Just another Drupal site'
+    title_prefix:
+      type: string
+      description: 'Output before the block title.'
+      default: ''
+    title_suffix:
+      type: string
+      description: 'Output after the block title.'
+      default: ''
+    attributes:
+      type: object
+      description: 'HTML attributes for the container.'
+      default: {}
+    title_attributes:
+      type: object
+      description: 'HTML attributes for the title.'
+      default: {}
diff --git a/components/block/systembranding/systembranding.stories.json b/components/block/systembranding/systembranding.stories.json
new file mode 100644
index 0000000..2415d65
--- /dev/null
+++ b/components/block/systembranding/systembranding.stories.json
@@ -0,0 +1 @@
+{"title":"Components\/Branding","parameters":{"server":{"url":"https:\/\/sdc4.ddev.site\/storybook\/stories\/render"}},"stories":[{"name":"Default Branding Block","args":{"configuration":{"label":"Branding Block","provider":"system"},"site_logo":"\/themes\/custom\/tailpine\/logo.svg","site_name":"Drupal Demo Site","site_slogan":"Powered by Drupal","title_prefix":"<span class=\"title-prefix\">Prefix<\/span>","title_suffix":"<span class=\"title-suffix\">Suffix<\/span>"},"parameters":{"server":{"id":"eyJwYXRoIjoidGhlbWVzXC9jdXN0b21cL3RhaWxwaW5lXC9jb21wb25lbnRzXC9ibG9ja1wvc3lzdGVtYnJhbmRpbmdcL3N5c3RlbWJyYW5kaW5nLnN0b3JpZXMudHdpZyIsImlkIjoiZGVmYXVsdCJ9"}}}]}
\ No newline at end of file
diff --git a/components/block/systembranding/systembranding.stories.twig b/components/block/systembranding/systembranding.stories.twig
new file mode 100644
index 0000000..3c55463
--- /dev/null
+++ b/components/block/systembranding/systembranding.stories.twig
@@ -0,0 +1,29 @@
+{% stories branding with { title: 'Components/Branding' } %}
+
+{% story default with {
+  name: 'Default Branding Block',
+  args: {
+    configuration: {
+      label: 'Branding Block',
+      provider: 'system'
+    },
+    site_logo: '/themes/custom/tailpine/logo.svg',
+    site_name: 'Drupal Demo Site',
+    site_slogan: 'Powered by Drupal',
+    title_prefix: '<span class="title-prefix">Prefix</span>',
+    title_suffix: '<span class="title-suffix">Suffix</span>'
+  }
+} %}
+
+{% embed 'tailpine:systembranding' with {
+    configuration: configuration,
+    site_logo: site_logo,
+    site_name: site_name,
+    site_slogan: site_slogan,
+    title_prefix: title_prefix,
+    title_suffix: title_suffix
+  }%}{% endembed %}
+
+{% endstory %}
+
+{% endstories %}
diff --git a/components/block/systembranding/systembranding.twig b/components/block/systembranding/systembranding.twig
new file mode 100644
index 0000000..231fc61
--- /dev/null
+++ b/components/block/systembranding/systembranding.twig
@@ -0,0 +1,29 @@
+{#
+/**
+ * @file
+ * Theme override for a branding block.
+ *
+ * Each branding element variable (logo, name, slogan) is only available if
+ * enabled in the block configuration.
+ *
+ * Available variables:
+ * - site_logo: Logo for site as defined in Appearance or theme settings.
+ * - site_name: Name for site as defined in Site information settings.
+ * - site_slogan: Slogan for site as defined in Site information settings.
+ */
+#}
+{% block content %}
+  {% if site_logo %}
+    <a href="{{ path('<front>') }}" rel="home" class="site-logo">
+      <img src="{{ site_logo }}" alt="{{ 'Home'|t }}" fetchpriority="high" />
+    </a>
+  {% endif %}
+  {% if site_name %}
+    <div class="site-name">
+      <a href="{{ path('<front>') }}" rel="home">{{ site_name }}</a>
+    </div>
+  {% endif %}
+  {% if site_slogan %}
+    <div class="site-slogan">{{ site_slogan }}</div>
+  {% endif %}
+{% endblock %}
diff --git a/components/block/systemmenu/systemmenu.component.yml b/components/block/systemmenu/systemmenu.component.yml
new file mode 100644
index 0000000..85cb213
--- /dev/null
+++ b/components/block/systemmenu/systemmenu.component.yml
@@ -0,0 +1,52 @@
+$schema: https://git.drupalcode.org/project/drupal/-/raw/10.1.x/core/modules/sdc/src/metadata.schema.json
+
+name: systemmenu
+label: 'System Menu'
+description: 'Component for rendering a system menu block with accessible heading and content.'
+category: 'Navigation'
+
+schema:
+  properties:
+    plugin_id:
+      type: string
+      description: 'The ID of the block implementation.'
+      default: 'system_menu_block'
+    derivative_plugin_id:
+      type: string
+      description: 'Used to build a class name specific to the menu (e.g., main, footer).'
+      default: 'main'
+    configuration:
+      type: object
+      properties:
+        label:
+          type: string
+          description: 'The configured label of the block.'
+          default: 'Main navigation'
+        label_display:
+          type: boolean
+          description: 'Controls if the label is visible.'
+          default: true
+        provider:
+          type: string
+          description: 'The module or provider of the block.'
+          default: 'system'
+    content:
+      type: string
+      description: 'Rendered menu links HTML.'
+      default: '<ul><li><a href="#">Link 1</a></li><li><a href="#">Link 2</a></li></ul>'
+    title_prefix:
+      type: string
+      description: 'Additional markup before the title.'
+      default: ''
+    title_suffix:
+      type: string
+      description: 'Additional markup after the title.'
+      default: ''
+    attributes:
+      type: object
+      description: 'HTML attributes for the nav container.'
+      default: {}
+    title_attributes:
+      type: object
+      description: 'HTML attributes for the title element.'
+      default: {}
diff --git a/components/block/systemmenu/systemmenu.stories.json b/components/block/systemmenu/systemmenu.stories.json
new file mode 100644
index 0000000..1448980
--- /dev/null
+++ b/components/block/systemmenu/systemmenu.stories.json
@@ -0,0 +1 @@
+{"title":"Components\/System Menu","parameters":{"server":{"url":"https:\/\/sdc4.ddev.site\/storybook\/stories\/render"}},"stories":[{"name":"System Menu Block","args":{"plugin_id":"system_menu_block","derivative_plugin_id":"main","configuration":{"label":"Main Navigation","label_display":false,"provider":"system"},"title_prefix":"<span class=\"title-prefix\">Prefix<\/span>","title_suffix":"<span class=\"title-suffix\">Suffix<\/span>","content":"<ul><li><a href=\"#\">Home<\/a><\/li><li><a href=\"#\">About<\/a><\/li><li><a href=\"#\">Contact<\/a><\/li><\/ul>"},"parameters":{"server":{"id":"eyJwYXRoIjoidGhlbWVzXC9jdXN0b21cL3RhaWxwaW5lXC9jb21wb25lbnRzXC9ibG9ja1wvc3lzdGVtbWVudVwvc3lzdGVtbWVudS5zdG9yaWVzLnR3aWciLCJpZCI6ImRlZmF1bHQifQ%3D%3D"}}}]}
\ No newline at end of file
diff --git a/components/block/systemmenu/systemmenu.stories.twig b/components/block/systemmenu/systemmenu.stories.twig
new file mode 100644
index 0000000..4847d73
--- /dev/null
+++ b/components/block/systemmenu/systemmenu.stories.twig
@@ -0,0 +1,30 @@
+{% stories systemmenu with { title: 'Components/System Menu' } %}
+
+{% story default with {
+  name: 'System Menu Block',
+  args: {
+    plugin_id: 'system_menu_block',
+    derivative_plugin_id: 'main',
+    configuration: {
+      label: 'Main Navigation',
+      label_display: false,
+      provider: 'system'
+    },
+    title_prefix: '<span class="title-prefix">Prefix</span>',
+    title_suffix: '<span class="title-suffix">Suffix</span>',
+    content: '<ul><li><a href="#">Home</a></li><li><a href="#">About</a></li><li><a href="#">Contact</a></li></ul>'
+  }
+} %}
+
+{% embed 'tailpine:systemmenu' with {
+    plugin_id: plugin_id,
+    derivative_plugin_id: derivative_plugin_id,
+    configuration: configuration,
+    title_prefix: title_prefix,
+    title_suffix: title_suffix,
+    content: content
+  }%}{% endembed %}
+
+{% endstory %}
+
+{% endstories %}
diff --git a/components/block/systemmenu/systemmenu.twig b/components/block/systemmenu/systemmenu.twig
new file mode 100644
index 0000000..113f37d
--- /dev/null
+++ b/components/block/systemmenu/systemmenu.twig
@@ -0,0 +1,57 @@
+{#
+/**
+ * @file
+ * Theme override for a menu block.
+ *
+ * Available variables:
+ * - plugin_id: The ID of the block implementation.
+ * - label: The configured label of the block if visible.
+ * - configuration: A list of the block's configuration values.
+ *   - label: The configured label for the block.
+ *   - label_display: The display settings for the label.
+ *   - provider: The module or other provider that provided this block plugin.
+ *   - Block plugin specific settings will also be stored here.
+ * - in_preview: Whether the plugin is being rendered in preview mode.
+ * - content: The content of this block.
+ * - attributes: HTML attributes for the containing element.
+ *   - id: A valid HTML ID and guaranteed unique.
+ * - title_attributes: HTML attributes for the title element.
+ * - content_attributes: HTML attributes for the content element.
+ * - title_prefix: Additional output populated by modules, intended to be
+ *   displayed in front of the main title tag that appears in the template.
+ * - title_suffix: Additional output populated by modules, intended to be
+ *   displayed after the main title tag that appears in the template.
+ *
+ * Headings should be used on navigation menus that consistently appear on
+ * multiple pages. When this menu block's label is configured to not be
+ * displayed, it is automatically made invisible using the 'visually-hidden' CSS
+ * class, which still keeps it visible for screen-readers and assistive
+ * technology. Headings allow screen-reader and keyboard only users to navigate
+ * to or skip the links.
+ * See http://juicystudio.com/article/screen-readers-display-none.php and
+ * https://www.w3.org/TR/WCAG-TECHS/H42.html for more information.
+ */
+#}
+{# {%
+  set classes = [
+    'block',
+    'block-menu',
+    'navigation',
+    'menu--' ~ derivative_plugin_id|clean_class,
+  ]
+%}
+{% set heading_id = attributes.id ~ '-menu'|clean_id %}
+<nav role="navigation" aria-labelledby="{{ heading_id }}"{{ attributes.addClass(classes)|without('role', 'aria-labelledby') }}> #}
+  {# Label. If not displayed, we still provide it for screen readers. #}
+  {# {% if not configuration.label_display %}
+    {% set title_attributes = title_attributes.addClass('visually-hidden') %}
+  {% endif %}
+  {{ title_prefix }}
+  <h2{{ title_attributes.setAttribute('id', heading_id) }}>{{ configuration.label }}</h2>
+  {{ title_suffix }} #}
+
+  {# Menu. #}
+  {% block content %}
+    {{ content }}
+  {% endblock %}
+{# </nav> #}
diff --git a/templates/block/block--local-actions-block.html.twig b/templates/block/block--local-actions-block.html.twig
index d90d45d..3254187 100644
--- a/templates/block/block--local-actions-block.html.twig
+++ b/templates/block/block--local-actions-block.html.twig
@@ -1,14 +1,7 @@
-{% extends "block.html.twig" %}
 {#
 /**
  * @file
  * Theme override for local actions (primary admin actions.)
  */
 #}
-{% block content %}
-	{% if content %}
-		<nav class="action-links">{{ content }}</nav>
-	{% endif %}
-{% endblock %}
-
-<div class="text-red-300">
+{{ include('tailpine:localaction')}}
\ No newline at end of file
diff --git a/templates/block/block--local-tasks-block.html.twig b/templates/block/block--local-tasks-block.html.twig
index 0f25f59..15d98ec 100644
--- a/templates/block/block--local-tasks-block.html.twig
+++ b/templates/block/block--local-tasks-block.html.twig
@@ -1,14 +1,7 @@
-{% extends "block.html.twig" %}
 {#
 /**
  * @file
  * Theme override for tabs.
  */
 #}
-{% block content %}
-  {% if content %}
-    <nav class="tabs" role="navigation" aria-label="{{ 'Tabs'|t }}">
-      {{ content }}
-    </nav>
-  {% endif %}
-{% endblock %}
+{{ include('tailpine:localtasks')}}
diff --git a/templates/block/block--search-form-block.html.twig b/templates/block/block--search-form-block.html.twig
index d1cda72..0baba2b 100644
--- a/templates/block/block--search-form-block.html.twig
+++ b/templates/block/block--search-form-block.html.twig
@@ -27,20 +27,4 @@
  * @see search_preprocess_block()
  */
 #}
-{%
-  set classes = [
-    'block',
-    'block-search',
-    'container-inline',
-  ]
-%}
-<div{{ attributes.addClass(classes) }}>
-  {{ title_prefix }}
-  {% if label %}
-    <h2{{ title_attributes }}>{{ label }}</h2>
-  {% endif %}
-  {{ title_suffix }}
-  {% block content %}
-    {{ content }}
-  {% endblock %}
-</div>
+{{ include('tailpine:searchform')}}
diff --git a/templates/block/block--system-branding-block.html.twig b/templates/block/block--system-branding-block.html.twig
index 8814363..60a4bc4 100644
--- a/templates/block/block--system-branding-block.html.twig
+++ b/templates/block/block--system-branding-block.html.twig
@@ -1,4 +1,3 @@
-{% extends "block.html.twig" %}
 {#
 /**
  * @file
@@ -13,18 +12,4 @@
  * - site_slogan: Slogan for site as defined in Site information settings.
  */
 #}
-{% block content %}
-  {% if site_logo %}
-    <a href="{{ path('<front>') }}" rel="home" class="site-logo">
-      <img src="{{ site_logo }}" alt="{{ 'Home'|t }}" fetchpriority="high" />
-    </a>
-  {% endif %}
-  {% if site_name %}
-    <div class="site-name">
-      <a href="{{ path('<front>') }}" rel="home">{{ site_name }}</a>
-    </div>
-  {% endif %}
-  {% if site_slogan %}
-    <div class="site-slogan">{{ site_slogan }}</div>
-  {% endif %}
-{% endblock %}
+{{ include('tailpine:systembranding')}}
diff --git a/templates/block/block--system-menu-block.html.twig b/templates/block/block--system-menu-block.html.twig
index 4b76673..6d8eae1 100644
--- a/templates/block/block--system-menu-block.html.twig
+++ b/templates/block/block--system-menu-block.html.twig
@@ -32,26 +32,4 @@
  * https://www.w3.org/TR/WCAG-TECHS/H42.html for more information.
  */
 #}
-{%
-  set classes = [
-    'block',
-    'block-menu',
-    'navigation',
-    'menu--' ~ derivative_plugin_id|clean_class,
-  ]
-%}
-{% set heading_id = attributes.id ~ '-menu'|clean_id %}
-<nav role="navigation" aria-labelledby="{{ heading_id }}"{{ attributes.addClass(classes)|without('role', 'aria-labelledby') }}>
-  {# Label. If not displayed, we still provide it for screen readers. #}
-  {% if not configuration.label_display %}
-    {% set title_attributes = title_attributes.addClass('visually-hidden') %}
-  {% endif %}
-  {{ title_prefix }}
-  <h2{{ title_attributes.setAttribute('id', heading_id) }}>{{ configuration.label }}</h2>
-  {{ title_suffix }}
-
-  {# Menu. #}
-  {% block content %}
-    {{ content }}
-  {% endblock %}
-</nav>
+{{ include('tailpine:systemmenu')}}
diff --git a/templates/block/block.html.twig b/templates/block/block.html.twig
index 114d7c4..422f350 100644
--- a/templates/block/block.html.twig
+++ b/templates/block/block.html.twig
@@ -26,20 +26,4 @@
  * @see template_preprocess_block()
  */
 #}
-{%
-  set classes = [
-    'block',
-    'block-' ~ configuration.provider|clean_class,
-    'block-' ~ plugin_id|clean_class,
-  ]
-%}
-<div{{ attributes.addClass(classes) }}>
-  {{ title_prefix }}
-  {% if label %}
-    <h2{{ title_attributes }}>{{ label }}</h2>
-  {% endif %}
-  {{ title_suffix }}
-  {% block content %}
-    {{ content }}
-  {% endblock %}
-</div>
+{{ include('tailpine:mainblock')}}
-- 
GitLab