Getting Started with Vue DockingLayout Component

Smart UI Vue examples target Vue 3 and Vite; enable TypeScript in create-vue when you want typed SFCs.

Demo source (Smart UI repo): vue/vue-3/src/docking-layout/overview/App.vue

Scaffold with Vite (Vue 3)

Run the official scaffolding tool:

npm create vue@latest

You will be prompted for TypeScript, Router, Pinia, and other options. When unsure, accept defaults and enable features later.

cd <your-project-name>
npm install
npm install smart-webcomponents
npm run dev
	

Vue + TypeScript

If you enabled TypeScript, use vite.config.ts with the same isCustomElement configuration as below so the compiler treats Smart UI tags as native custom elements.

Teach Vue about custom elements

Without this, Vue warns about unknown custom elements. Open vite.config.js or vite.config.ts and configure the Vue plugin so smart-* and legacy jqx-* tags are passed through to the DOM:

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          isCustomElement: tag => tag.startsWith('smart-') || tag.startsWith('jqx-')
        }
      }
    })
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})
	

App.vue example

Example from Smart UI Vue 3 demos for this widget:

<template>
  <div class="vue-root">
    <smart-docking-layout></smart-docking-layout>
  </div>
</template>

<script>
import { onMounted } from "vue";
import "smart-webcomponents/source/styles/smart.default.css";
import "smart-webcomponents/source/modules/smart.dockinglayout.js";
import "smart-webcomponents/source/modules/smart.textbox.js";
import "smart-webcomponents/source/modules/smart.slider.js";

export default {
  name: "app",
  setup() {
    onMounted(() => {
      const docking = document.querySelector("smart-docking-layout");
      docking.layout = [
        {
          type: "LayoutGroup",
          orientation: "horizontal",
          items: [
            {
              type: "LayoutGroup",
              items: [
                {
                  type: "LayoutPanel",
                  id: "tabPanel",
                  label: "Input",
                  items: [
                    {
                      label: "TextBox Tab",
                      content:
                        '<smart-multiline-text-box id="multiLine">Write more text here ...</smart-multiline-text-box>'
                    },
                    {
                      label: "Slider Tab",
                      content: '<smart-slider id="slider"></smart-slider>'
                    }
                  ]
                },
                {
                  type: "LayoutPanel",
                  label: "Output",
                  items: [
                    {
                      id: "outputTab",
                      label: "Output",
                      headerPosition: "none",
                      content: "Write more text here ..."
                    }
                  ]
                }
              ],
              orientation: "vertical"
            },
            {
              id: "item0",
              label: "Tabs 0",
              items: [
                {
                  label: "Tab A",
                  selected: true,
                  content:
                    "What is Lorem Ipsum?\n" +
                    "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of" +
                    "type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in " +
                    "the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.\n" +
                    "Why do we use it?\n" +
                    "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal " +
                    "distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their" +
                    "default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on " +
                    "purpose (injected humour and the like)."
                }
              ]
            }
          ]
        }
      ];

      docking.whenRendered(() => {
        document
          .getElementById("tabPanel")
          .addEventListener("change", function(event) {
            const target = event.target;
            if (target.tagName === "smart-slider") {
              document.getElementById("outputTab").innerHTML =
                event.detail.value;
            } else if (target.tagName === "smart-multiline-text-box") {
              document.getElementById("outputTab").innerHTML = target.value;
            } else if (target.tagName === "Smart-TABS") {
              const tabs = target;
              const selectedTabItem = tabs.getElementsByTagName(
                "smart-tab-item"
              )[tabs.selectedIndex];
              if (selectedTabItem === undefined) {
                return;
              }
              if (selectedTabItem.label.toLowerCase().indexOf("slider") > -1) {
                const slider = selectedTabItem.querySelector("smart-slider");
                document.getElementById("outputTab").innerHTML = slider.value;
              } else if (
                selectedTabItem.label.toLowerCase().indexOf("textbox") > -1
              ) {
                const textBoxValue = selectedTabItem.querySelector(
                  "smart-multiline-text-box"
                ).value;
                document.getElementById("outputTab").innerHTML = textBoxValue;
              }
            }
          });
      });
    });
  }
};
</script>

<style>
smart-docking-layout {
  width: 100%;
  height: 500px;
  background-color: #eeedf3;
}

smart-docking-layout .smart-items-container smart-splitter-item.smart-element,
smart-docking-layout
  .smart-items-container
  > .smart-container
  > smart-splitter-item.smart-element {
  width: 50%;
  height: 50%;
}

smart-docking-layout smart-tabs-window smart-slider.smart-element,
smart-docking-layout smart-tabs-window smart-multiline-text-box.smart-element {
  height: 100%;
  width: 100%;
}

smart-docking-layout smart-tabs-window smart-multiline-text-box.smart-element {
  display: block;
}
</style>
	

You can now use smart-docking-layout in templates; bindings and events follow Vue's normal syntax.

Run and build

Development server:

npm run dev

Then open http://localhost:5173/.

Production build:

npm run build

Output goes to ./dist.

Read more about using Smart UI for Vue.

Accessibility

The DockingLayout component follows WAI-ARIA best practices:

  • Keyboard navigation - Tab, Arrow keys, Enter, and Escape are supported
  • ARIA roles - Appropriate roles and labels are applied automatically
  • Focus management - Visible focus indicators for keyboard users
  • Screen readers - State changes are announced to assistive technology
  • High contrast - Supports Windows High Contrast Mode and forced colors

For custom labeling, set aria-label or aria-labelledby attributes on the component.

Live demos

Supported stacks: Smart UI targets Angular 17+, React 18+, Vue 3+, Node 18 LTS, and evergreen browsers; pin exact package versions to your org policy.