# Installation ## Quick Start with AI Paste this into your AI coding tool and let it handle the setup: ```text Install @shopware-ag/meteor-component-library in this project. Connect the Meteor MCP server at https://meteor.shopware.com/mcp (or read https://meteor.shopware.com/llms.txt) to learn the components and conventions. ``` ## Manual setup Meteor is a monorepo that publishes each part of the design system as a standalone npm package. You can adopt the full stack or pick only what your project needs: the component library, the token set, and the icon kit are all independently installable and versioned. ## Component library The component library builds upon the icon kit and design tokens, and requires Vue 3. ### Install ```sh npm install @shopware-ag/meteor-component-library ``` ### Import styles Add both imports to your application entry point. ```ts import "@shopware-ag/meteor-component-library/styles.css"; import "@shopware-ag/meteor-component-library/font.css"; ``` ### Configure i18n English and German translations are bundled. Register `vue-i18n` before mounting your app. ```ts import { createApp } from "vue"; import { createI18n } from "vue-i18n"; import App from "./App.vue"; const i18n = createI18n({ legacy: false }); createApp(App).use(i18n).mount("#app"); ``` ### Use components Components are tree-shakable. Import only what you use. ```vue ``` ### Future flags Some behavior that will become the default in upcoming major releases is available early behind future flags. Opt in through the [**Theme Provider**](https://meteor.shopware.com/utilities/components/theme-provider) `future` prop to align your application with the next major and reduce the work when you upgrade. ::note Future flags let established applications like the Shopware Admin stay visually stable while the library evolves, since new behavior stays opt-in. Because the flags also carry the behavior we intend to make default, we recommend turning them all on by passing `{ all: true }` to the [**Theme Provider**](https://meteor.shopware.com/utilities/components/theme-provider) `future` prop whenever your application can accept the risk of visual breaks on future updates. :: ## Tokens The token package is framework-agnostic. Install it independently whenever you need Meteor's design decisions without the component library. ### Install ```sh npm install @shopware-ag/meteor-tokens ``` ### Import The light theme defines design tokens via CSS variables on `:root` and the dark theme replaces the variable values when `data-theme="dark"` is set on elements as an HTML attribute. ```ts import "@shopware-ag/meteor-tokens/administration/light.css"; import "@shopware-ag/meteor-tokens/administration/dark.css"; ``` ### Use ```css .my-component { color: var(--color-text-primary-default); background: var(--color-elevation-surface-default); padding: var(--scale-size-16); } ``` ## Icons The icon kit can be used standalone in any framework as SVGs, or as Vue components via `mt-icon` in the component library. ### Install ```sh npm install @shopware-ag/meteor-icon-kit ``` ### Import as SVG ```ts import PlusIcon from "@shopware-ag/meteor-icon-kit/icons/regular/plus.svg"; ``` ### Use with mt-icon (Vue) `mt-icon` is included in the component library and renders any icon by name. ```html ``` ## Browser support Meteor targets all major evergreen browsers. Features used in the component library and token package are limited to those with [Baseline Newly available](https://developer.mozilla.org/en-US/docs/Glossary/Baseline/Compatibility){rel=""nofollow""} status, a web platform interoperability signal meaning the feature is supported in the latest stable releases of Chrome, Edge, Firefox, and Safari with no polyfills required. Legacy browsers and non-evergreen environments are not supported. # Agents There are two ways to give AI tools access to the Meteor documentation. The [MCP server](https://meteor.shopware.com/#mcp-server) provides a live, tool-driven connection that assistants such as Claude Code, Cursor, and VS Code can browse on their own. The [llms.txt and raw markdown](https://meteor.shopware.com/#llmstxt-and-raw-markdown) files expose the same content as static URLs you can paste straight into a prompt. ## MCP server The Model Context Protocol (MCP) is a standardized way for AI assistants to access external data and tools. Meteor ships an MCP server that lets assistants read the documentation directly and query structured data about components, examples, icons, and design tokens, so answers and generated code stay grounded in the current docs instead of model memory. The server uses HTTP transport and is available at: ```text https://meteor.shopware.com/mcp ``` ### Tools | Tool | Description | | ------------ | ---------------------------------------------------------------------------------------------------------------------------------- | | `list-pages` | List all documentation pages with their paths and descriptions. | | `get-page` | Retrieve the full content of a documentation page. Component pages include the API reference and example code inlined as markdown. | ### Resources Browsable catalogs the assistant can read in a single call: | Resource | Description | | --------------------- | ------------------------------------------------------------- | | `meteor://components` | Every component with its name, slug, and description. | | `meteor://examples` | Every documented example and its owning component. | | `meteor://icons` | The full icon kit (name, mode, tags). | | `meteor://tokens` | Design tokens grouped by category, each with its description. | ### Configuration Add the server to your AI assistant using the tab for your tool. ::code-group ```bash [Claude Code] claude mcp add --transport http meteor https://meteor.shopware.com/mcp ``` ```json [Cursor] { "mcpServers": { "meteor": { "type": "http", "url": "https://meteor.shopware.com/mcp" } } } ``` ```json [VS Code] { "servers": { "meteor": { "type": "http", "url": "https://meteor.shopware.com/mcp" } } } ``` ```json [Claude Desktop] { "mcpServers": { "meteor": { "command": "npx", "args": ["mcp-remote", "https://meteor.shopware.com/mcp"] } } } ``` :: ### Usage Once the server is connected, you can ask your assistant questions like: - "List the Meteor documentation pages" - "Show me the mt-button documentation from Meteor, including its props" - "Which Meteor component should I use for a confirmation dialog?" - "What does the Meteor migration guide say about replacing sw- components?" The assistant calls `list-pages` to discover what exists and `get-page` to read a page (component pages include the API reference and example code inlined as markdown). The `meteor://components`, `meteor://examples`, `meteor://icons`, and `meteor://tokens` resources let it browse the full catalogs directly. ::note Prefer structured docs over plain web access: the MCP server returns the same content that powers this site, so the assistant works from the exact, current documentation. :: ## llms.txt and raw markdown [llms.txt](https://llmstxt.org/){rel=""nofollow""} is a convention for exposing documentation in a format optimized for large language models. Instead of parsing rendered HTML, an AI tool can read a single structured text file that links to the full documentation as clean markdown. Meteor publishes two files: | File | Description | | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------- | | [`/llms.txt`](https://meteor.shopware.com/llms.txt){rel=""nofollow""} | A concise index of the documentation with links to each page. | | [`/llms-full.txt`](https://meteor.shopware.com/llms-full.txt){rel=""nofollow""} | The complete documentation inlined into a single file. | Start with `/llms.txt` for most cases. Use `/llms-full.txt` when the tool supports large context windows and you want the entire documentation set in one request. ### Raw markdown Every documentation page is also available as raw markdown by prefixing the path with `/raw` and adding a `.md` suffix. For example: ```text https://meteor.shopware.com/raw/documentation/getting-started/migration.md ``` Dynamic content such as component prop tables is rendered to plain markdown in these files, so the output stays useful to tools that cannot execute the site. ### Using it with AI tools Most assistants let you reference a URL directly in a prompt. Paste a link to `/llms.txt` or a specific `/raw/*.md` page and ask your question, for example: - "Using {rel=""nofollow""}, which component should I use for a confirmation dialog?" - "Summarize {rel=""nofollow""}" # Migration If you're using older `sw-` components, here's how to transition to Meteor. ## Component mapping - `sw-button` → `mt-button` - `sw-text-field` → `mt-text-field` - `sw-card` → `mt-card` - `sw-banner` → `mt-banner` - `sw-checkbox` → `mt-checkbox` - `sw-switch-field` → `mt-switch` - `sw-select` → `mt-select` - `sw-datepicker` → `mt-datepicker` ## Design tokens Replace custom CSS variables or hard-coded colors with [Meteor tokens](https://meteor.shopware.com/documentation/design/tokens): ```css /* Use Meteor tokens directly */ color: var(--color-icon-primary-default); ``` ## Icons The component name is the same. The tag just changes from `sw-icon` to `mt-icon`. See the [Icons](https://meteor.shopware.com/documentation/design/icons) page for the full icon set and usage guidance. ```html ``` ## From admin-extension-sdk to meteor-admin-sdk The `@shopware-ag/admin-extension-sdk` package was archived in March 2024 and replaced by `@shopware-ag/meteor-admin-sdk`. ```sh npm uninstall @shopware-ag/admin-extension-sdk npm install @shopware-ag/meteor-admin-sdk ``` Update your imports: ```js // Before import { notification } from "@shopware-ag/admin-extension-sdk"; // After import { notification } from "@shopware-ag/meteor-admin-sdk"; ``` For the full API and usage guidance, see the [Admin SDK documentation](https://developer.shopware.com/resources/admin-extension-sdk/){rel=""nofollow""}. ## Gradual migration Meteor works alongside existing components. Migrate page by page rather than all at once: 1. Install Meteor alongside your existing setup 2. Replace components one at a time 3. Update styling to use design tokens progressively 4. Test each step before continuing ## Between Meteor versions When upgrading between major versions of Meteor packages, check the [changelog](https://meteor.shopware.com/documentation/getting-started/whats-new) for breaking changes. Each release includes a changelog entry that lists renamed props, removed components, and token renames. For minor and patch releases, upgrades are safe without additional migration steps. # Contributing The contributing guide is maintained in [CONTRIBUTING.md](https://github.com/shopware/meteor/blob/main/CONTRIBUTING.md) in the repository. # What's new ## Component Library ### 5.6.2 #### Patch Changes - Updated dependencies \[[`71c0a2c`](https://github.com/shopware/meteor/commit/71c0a2c093950bc9fa661deaa836e8123c741684){rel=""nofollow""}]: - @shopware-ag/meteor-admin-sdk\@6.13.0 ### 5.6.1 #### Patch Changes - Updated dependencies \[[`4fdee56`](https://github.com/shopware/meteor/commit/4fdee561f0dd0121f0aa8fbc780a62141ab713ab){rel=""nofollow""}]: - @shopware-ag/meteor-icon-kit\@5.10.0 ### 5.6.0 #### Minor Changes - [#1139](https://github.com/shopware/meteor/pull/1139){rel=""nofollow""} [`26f46b6`](https://github.com/shopware/meteor/commit/26f46b611d5b1e72d28af816b50b2ee2a416017d){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Add an optional `hint` prop to all form fields for rendering a caption below the field. The existing `#hint` slot still works and takes precedence. Hint content now renders with a consistent info-icon style, which also applies to existing `#hint` slot usage. #### Patch Changes - Updated dependencies \[[`579d59a`](https://github.com/shopware/meteor/commit/579d59ad92b44e58d3a800b93489f6e15e5b7ae3){rel=""nofollow""}]: - @shopware-ag/meteor-admin-sdk\@6.12.0 ### 5.5.0 #### Minor Changes - [#1284](https://github.com/shopware/meteor/pull/1284){rel=""nofollow""} [`2875130`](https://github.com/shopware/meteor/commit/2875130e4b0f582daf95a05d2b33e64f68197e75){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Add the `mt-theme-select` component for choosing the application color theme (light, dark, or system) and the `useTheme` composable that resolves the system preference, applies the resolved theme to `data-theme`, and persists the choice. #### Patch Changes - [#1289](https://github.com/shopware/meteor/pull/1289){rel=""nofollow""} [`5377579`](https://github.com/shopware/meteor/commit/5377579ac8b450ea9a86557c91216cc69d29937b){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Move `inter-ui` to `devDependencies`. The Inter font files are copied into `dist/assets/fonts/` at build time, so the package stays self-contained — keep using the `font.css` export. If you imported `inter-ui` directly without declaring it, add it to your own `dependencies`. - [#1289](https://github.com/shopware/meteor/pull/1289){rel=""nofollow""} [`5377579`](https://github.com/shopware/meteor/commit/5377579ac8b450ea9a86557c91216cc69d29937b){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Stop publishing source maps. They were built with `sourcemap: "hidden"`, so no published file referenced them — removes 23.6 MB of unreachable files from the package. - [#1289](https://github.com/shopware/meteor/pull/1289){rel=""nofollow""} [`5377579`](https://github.com/shopware/meteor/commit/5377579ac8b450ea9a86557c91216cc69d29937b){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Stop publishing the `src` directory. The `exports` map only exposes `dist`, so `src` was never reachable through supported imports. If you reached into `src` via raw `node_modules` paths (e.g. SCSS imports), switch to the documented `dist` entry points. - Updated dependencies \[[`2875130`](https://github.com/shopware/meteor/commit/2875130e4b0f582daf95a05d2b33e64f68197e75){rel=""nofollow""}, [`5377579`](https://github.com/shopware/meteor/commit/5377579ac8b450ea9a86557c91216cc69d29937b){rel=""nofollow""}]: - @shopware-ag/meteor-admin-sdk\@6.11.0 - @shopware-ag/meteor-icon-kit\@5.9.1 ### 5.4.0 #### Minor Changes - [#1281](https://github.com/shopware/meteor/pull/1281){rel=""nofollow""} [`f091304`](https://github.com/shopware/meteor/commit/f09130459e371d65651446ece113a59868001cca){rel=""nofollow""} Thanks [@fabianhueske](https://github.com/fabianhueske){rel=""nofollow""}! - Add `MtStatusDot`, a small semantic status dot with variants (`neutral`, `info`, `attention`, `critical`, `positive`), sizes (`s`, `m`, `l`), an optional `pulse` animation for signaling live activity (disabled under reduced motion), and an optional accessible `label`. :br The internal color badge it replaces has been removed and its usages migrated: data table badge columns now render with `MtBadge`, and the tab badge and the `MtBadge` status indicator now use `MtStatusDot`. Existing badge column `variant` values keep working unchanged; those badges now use the standard Badge styling. #### Patch Changes - Updated dependencies \[[`0d8dde1`](https://github.com/shopware/meteor/commit/0d8dde13640bf8c703e779b5e7a7fa80458185fa){rel=""nofollow""}]: - @shopware-ag/meteor-admin-sdk\@6.10.0 ### 5.3.2 #### Patch Changes - [#1280](https://github.com/shopware/meteor/pull/1280){rel=""nofollow""} [`226f16a`](https://github.com/shopware/meteor/commit/226f16af4dc9e1fca419c7262d6f0d3ece89b516){rel=""nofollow""} Thanks [@fabianhueske](https://github.com/fabianhueske){rel=""nofollow""}! - Refined several prop types to their literal values so the API reference renders them accurately. The `size` prop of `mt-text-field`, `mt-number-field`, and `mt-unit-field` is now typed as `"small" | "default"`, and the `mt-popover` `width` prop is now typed as `"dynamic" | "large" | "medium" | "small"` to match the value it actually accepts (previously it listed the non-functional `"auto"` and omitted the `"dynamic"` default). These are type-only corrections; the runtime behaviour is unchanged. - [#1272](https://github.com/shopware/meteor/pull/1272){rel=""nofollow""} [`1cbcdb8`](https://github.com/shopware/meteor/commit/1cbcdb8ff0b7ef1040cf1ed21b94a6bf1f4caadc){rel=""nofollow""} Thanks [@keulinho](https://github.com/keulinho){rel=""nofollow""}! - Fix number field stepping for values with high fractional precision limits. - [#1279](https://github.com/shopware/meteor/pull/1279){rel=""nofollow""} [`de7628d`](https://github.com/shopware/meteor/commit/de7628de4b396ef5d749dcb53633cdeb02b6c222){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - The collapsible open and close animations now use `ease-in-out` timing for a smoother transition. - [#1275](https://github.com/shopware/meteor/pull/1275){rel=""nofollow""} [`d292012`](https://github.com/shopware/meteor/commit/d2920123a0f02f3436692b49eae2cdb6472cf009){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - The modal now focuses the dialog container when it opens instead of the first interactive element. This prevents unintended side effects like an accidentally focused link or a tooltip opening together with the modal, while still moving focus into the dialog for keyboard and screen reader users. ### 5.3.1 #### Patch Changes - [#1269](https://github.com/shopware/meteor/pull/1269){rel=""nofollow""} [`1e4749e`](https://github.com/shopware/meteor/commit/1e4749ed333f7497e9ccec1dfd3f102e4197a7de){rel=""nofollow""} Thanks [@keulinho](https://github.com/keulinho){rel=""nofollow""}! - Fix floating-point rounding after stepping a number field. - [#1267](https://github.com/shopware/meteor/pull/1267){rel=""nofollow""} [`63df47b`](https://github.com/shopware/meteor/commit/63df47b653ec0bc18f35c0c2dbd8eb2e3e772557){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Remove the global `html, body` height rule from `styles.css` entirely, restoring the pre-5.2.0 behavior where consumers own their document-level layout. :br The rule has caused problems in both of its variants: - `height: 100dvh` (introduced in 5.2.0) deadlocked apps rendered in the Administration's auto-sized iframes at the 150px browser fallback, because the admin-sdk reported the pinned viewport height back to `sw-iframe-renderer`. - `min-height: 100dvh` (5.3.0) fixed the deadlock but made iframe auto-resizing a one-way ratchet: `body` never shrinks below the iframe's current height, so `location.startAutoResizer()` never reports a smaller height when content shrinks, and small widgets stay floored at the 150px fallback. :brWith the rule removed, auto-sized iframe locations grow **and** shrink with their content again, exactly as on ≤5.1.x. :br If your app relied on the implicit full-viewport height for a percentage-based layout (introduced accidentally in 5.2.0), declare it yourself: ```css html, body { height: 100dvh; } ``` ### 5.3.0 #### Minor Changes - [#1242](https://github.com/shopware/meteor/pull/1242){rel=""nofollow""} [`db041ae`](https://github.com/shopware/meteor/commit/db041ae91891a272f8abd9da7e5bbf441a3713e1){rel=""nofollow""} Thanks [@fabianhueske](https://github.com/fabianhueske){rel=""nofollow""}! - Added a way to enable every future flag at once and introduced two new flags. The Theme Provider `future` prop now accepts `{ all: true }` to turn on all current and upcoming flags, so flags added in later releases are opted into automatically. Combine it with overrides to fine-tune, for example `{ all: true, removeCardWidth: false }` to enable everything except a single flag. :br New flags: - `removeSwitchMinHeight`: removes the minimum height from a non-bordered `mt-switch`. - `bannerFullWidth`: makes `mt-banner` span the full width of its container. :brAll flags remain `false` by default, so behavior is unchanged until you opt in. #### Patch Changes - [#1259](https://github.com/shopware/meteor/pull/1259){rel=""nofollow""} [`0b11681`](https://github.com/shopware/meteor/commit/0b116813d524f8d0c0f233a1db2b9982866c9cbc){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Removed `@shopware-ag/meteor-icon-kit` from `peerDependencies` to prevent unwanted major version bumps. Because Changesets treats any non-patch bump of a peer dependency as a breaking change for the dependent package, a minor release of the icon kit forced a major release of the component library. The icon kit remains a regular dependency, so resolution is unchanged. - [#1265](https://github.com/shopware/meteor/pull/1265){rel=""nofollow""} [`664d2d3`](https://github.com/shopware/meteor/commit/664d2d30cd91af5a7404fffa1719abf678977c0a){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Added the `license` field (`MIT`) to the package metadata, aligning it with the other Meteor packages and the repository's license. - [#1262](https://github.com/shopware/meteor/pull/1262){rel=""nofollow""} [`d902e2a`](https://github.com/shopware/meteor/commit/d902e2a35b30f021603b267dc4fd86e96e778e84){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Fixed the component library collapsing to a 150px iframe when embedded in the Shopware Administration: `html`/`body` now use `min-height: 100dvh` instead of a fixed `height`. :br Reverted the `body` background to its original hardcoded value. The background is now deprecated and will change in an upcoming major version (likely detecting the embedded context automatically so it can go transparent inside the Administration). - [#1261](https://github.com/shopware/meteor/pull/1261){rel=""nofollow""} [`e5c28e0`](https://github.com/shopware/meteor/commit/e5c28e006af9f4ed25e29f01558070f88745534c){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Fixed `mt-number-field` inconsistently parsing pasted values with mixed decimal and grouping separators. Values such as `333,33` and `1.333,33` could silently become wrong amounts. The parser now treats the rightmost `.` or `,` as the decimal separator and removes earlier separators as grouping separators, and `onInput` uses the same parser so editing and blur behavior agree. - [#1266](https://github.com/shopware/meteor/pull/1266){rel=""nofollow""} [`b82647f`](https://github.com/shopware/meteor/commit/b82647f8d73c4ecc7d65856345097bd93f483357){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Fixed `mt-select` not selecting the highlighted option with the Enter key. The keyboard listener registry was shadowed by an empty data property, so keyboard selections never reached the result items. - [#1266](https://github.com/shopware/meteor/pull/1266){rel=""nofollow""} [`b82647f`](https://github.com/shopware/meteor/commit/b82647f8d73c4ecc7d65856345097bd93f483357){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Fixed `mt-select` showing the selected value as a placeholder when reopened. The value now stays in the input field; the result list is only filtered once the user actually edits the text. - [#1255](https://github.com/shopware/meteor/pull/1255){rel=""nofollow""} [`7c9f669`](https://github.com/shopware/meteor/commit/7c9f669b60b33a62b68ca52652337e687eae5eaf){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Various visual and positioning fixes across components: - Fixed `mt-floating-ui` popovers landing in the wrong spot and drifting on scroll by pinning `position` to the computed strategy. - Fixed `mt-colorpicker` popover positioning being sensitive to stylesheet source order. - Fixed `mt-action-menu` z-index stacking order. - Adjusted `mt-banner` close icon and spacing. - Adjusted `mt-checkbox` and `mt-switch` icon, spacing, gap and line-height. - Adjusted `mt-select` and `mt-button` field icons, spacing and active state. - Used tokens for `mt-base-field` label font-size and line-height. - Updated dependencies \[[`ca51ea5`](https://github.com/shopware/meteor/commit/ca51ea5ec04da206f20e726c55ab1278d860965c){rel=""nofollow""}, [`9eb0c3d`](https://github.com/shopware/meteor/commit/9eb0c3d2fd496c704a63d87f73c370ade5084942){rel=""nofollow""}]: - @shopware-ag/meteor-icon-kit\@5.9.0 - @shopware-ag/meteor-admin-sdk\@6.9.1 ### 5.2.0 #### Minor Changes - [#1155](https://github.com/shopware/meteor/pull/1155){rel=""nofollow""} [`dac8771`](https://github.com/shopware/meteor/commit/dac877135b31fcedaf94365f2e16f1ce4e1bea9d){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Added global css adjustments, inter font handling and css preflight reset to the library #### Patch Changes - [#1155](https://github.com/shopware/meteor/pull/1155){rel=""nofollow""} [`dac8771`](https://github.com/shopware/meteor/commit/dac877135b31fcedaf94365f2e16f1ce4e1bea9d){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Scoped the text editor diff modal styles to avoid leaking Tailwind Preflight globally. - [#1179](https://github.com/shopware/meteor/pull/1179){rel=""nofollow""} [`f380305`](https://github.com/shopware/meteor/commit/f380305595b7b7abc7ede6088a6961b775fec787){rel=""nofollow""} Thanks [@fabianhueske](https://github.com/fabianhueske){rel=""nofollow""}! - Fixed `mt-card` letting full-bleed content overflow its rounded corners by clipping content with `overflow: hidden`. - [#1178](https://github.com/shopware/meteor/pull/1178){rel=""nofollow""} [`e21a76c`](https://github.com/shopware/meteor/commit/e21a76c571147a1b8f678d26999fe7b47198da3e){rel=""nofollow""} Thanks [@fabianhueske](https://github.com/fabianhueske){rel=""nofollow""}! - Fixed `mt-number-field` with `numberType="float"` rounding some values down due to binary floating-point errors (for example `1.035` normalized to `1.03` instead of `1.04`). Normalization now rounds on the decimal representation, so half-up rounding is consistent across values. - [#1178](https://github.com/shopware/meteor/pull/1178){rel=""nofollow""} [`e21a76c`](https://github.com/shopware/meteor/commit/e21a76c571147a1b8f678d26999fe7b47198da3e){rel=""nofollow""} Thanks [@fabianhueske](https://github.com/fabianhueske){rel=""nofollow""}! - Fixed `mt-number-field` with `numberType="int"` mangling decimal input on blur (for example `1.05` became `105` instead of `1`). Decimal and exponent input is now parsed as a float and rounded to the nearest integer. - [#1177](https://github.com/shopware/meteor/pull/1177){rel=""nofollow""} [`89e62b3`](https://github.com/shopware/meteor/commit/89e62b3e0f06b480e20ddd607945127c85d29f15){rel=""nofollow""} Thanks [@fabianhueske](https://github.com/fabianhueske){rel=""nofollow""}! - Fixed the `mt-password-field` showing the parent background behind the visibility-toggle button in dark mode. The field now paints a consistent `--color-background-primary-default` surface across the input and toggle button. - [#1172](https://github.com/shopware/meteor/pull/1172){rel=""nofollow""} [`db1cf75`](https://github.com/shopware/meteor/commit/db1cf75d2aa09b2039f7da587e8d2b7313af5164){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Adjusted font bundling to import the actual woff2 font files instead of vite bundling them in base64 due to library mode defaults ### 5.1.0 #### Minor Changes - [#1142](https://github.com/shopware/meteor/pull/1142){rel=""nofollow""} [`1ab72fb`](https://github.com/shopware/meteor/commit/1ab72fbfcdbcad989083da2cb9e620240df482de){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Add `anchorElement` and `detached` props to `mt-floating-ui` for external anchor positioning. #### Patch Changes - [#1161](https://github.com/shopware/meteor/pull/1161){rel=""nofollow""} [`10bb170`](https://github.com/shopware/meteor/commit/10bb1700651b1f8e9042936b63ac7ced808c9792){rel=""nofollow""} Thanks [@mstegmeyer](https://github.com/mstegmeyer){rel=""nofollow""}! - Fix datepicker locale loading for date-fns v4 locale module exports. - [#1151](https://github.com/shopware/meteor/pull/1151){rel=""nofollow""} [`a4a236c`](https://github.com/shopware/meteor/commit/a4a236c4ea378adbb015a699813023f72c2f1fb8){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Added optional headline and description props to the mt-loader component - [#1146](https://github.com/shopware/meteor/pull/1146){rel=""nofollow""} [`b358e2a`](https://github.com/shopware/meteor/commit/b358e2a38b7729289d37daa7c7fe475c8d0e9109){rel=""nofollow""} Thanks [@shyim](https://github.com/shyim){rel=""nofollow""}! - Fixed `mt-url-field` mangling IP address input. The native URL parser rewrote numeric hosts as IPv4 addresses (e.g. `192` → `0.0.0.192`), and IPv6 literals were normalized or rejected mid-typing. The field now preserves the raw host the user typed and keeps the input in sync while a partial address is still being entered. - [#1137](https://github.com/shopware/meteor/pull/1137){rel=""nofollow""} [`1d8ee80`](https://github.com/shopware/meteor/commit/1d8ee80c18011082c895f3222a19604985603c85){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - mt-field-error now resolves interpolation params from error.meta.parameters while continuing to support error.parameters. - [#1157](https://github.com/shopware/meteor/pull/1157){rel=""nofollow""} [`22a0d25`](https://github.com/shopware/meteor/commit/22a0d25d06d08d5a2560470a8d4745ba6663d56a){rel=""nofollow""} Thanks [@gweiermann](https://github.com/gweiermann){rel=""nofollow""}! - Prevent mt-number-field from normalizing the displayed decimal value while the user is editing. - Updated dependencies \[[`ed965bd`](https://github.com/shopware/meteor/commit/ed965bdd41fe9972ba15319ccf0077dd14026ec2){rel=""nofollow""}]: - @shopware-ag/meteor-icon-kit\@5.8.0 ### 5.0.0 #### Minor Changes - [#1094](https://github.com/shopware/meteor/pull/1094){rel=""nofollow""} [`5673f08`](https://github.com/shopware/meteor/commit/5673f0839d4c074a87d5f4b852419f5467f066a5){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Add `maxDate` prop to `mt-datepicker` - [#1141](https://github.com/shopware/meteor/pull/1141){rel=""nofollow""} [`703eccf`](https://github.com/shopware/meteor/commit/703eccf0fba2cbd2e2091bea32a60a8dc9730380){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Add `mt-collapsible` component to component-library - [#1141](https://github.com/shopware/meteor/pull/1141){rel=""nofollow""} [`703eccf`](https://github.com/shopware/meteor/commit/703eccf0fba2cbd2e2091bea32a60a8dc9730380){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Add `mt-collapsible` component to component-library - [#1094](https://github.com/shopware/meteor/pull/1094){rel=""nofollow""} [`5673f08`](https://github.com/shopware/meteor/commit/5673f0839d4c074a87d5f4b852419f5467f066a5){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - upgrade `@vuepic/vue-datepicker` from v10 to v12 and migrate `mt-datepicker` to the new vue-datepicker APIs #### Patch Changes - [#1061](https://github.com/shopware/meteor/pull/1061){rel=""nofollow""} [`d453e51`](https://github.com/shopware/meteor/commit/d453e51231ce1f3c487cfd95755d10330e9ef8e3){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Moved test and Storybook deps to devDependencies - [#1138](https://github.com/shopware/meteor/pull/1138){rel=""nofollow""} [`6e8cd79`](https://github.com/shopware/meteor/commit/6e8cd79e32ba63e601ad5c3e9e0575800860bcf5){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Fix `mt-entity-data-table` Storybook interaction tests by waiting on rendered table content - [#1134](https://github.com/shopware/meteor/pull/1134){rel=""nofollow""} [`ac54a03`](https://github.com/shopware/meteor/commit/ac54a03028e2733b1c99ec71475b3ae39890afaf){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - fixed failing interaction tests inside `mt-text-editor` - Updated dependencies \[[`d5fe2db`](https://github.com/shopware/meteor/commit/d5fe2dbb90ca5fa9513d9fc3626548e902a660c8){rel=""nofollow""}, [`d5fe2db`](https://github.com/shopware/meteor/commit/d5fe2dbb90ca5fa9513d9fc3626548e902a660c8){rel=""nofollow""}]: - @shopware-ag/meteor-icon-kit\@5.7.0 ### 4.28.6 #### Patch Changes - Updated dependencies \[[`8bf06e1`](https://github.com/shopware/meteor/commit/8bf06e1263674c7ac16eef307b3ce94568786772){rel=""nofollow""}]: - @shopware-ag/meteor-admin-sdk\@6.9.0 ### 4.28.5 #### Patch Changes - [#1102](https://github.com/shopware/meteor/pull/1102){rel=""nofollow""} [`924d5cb`](https://github.com/shopware/meteor/commit/924d5cbbf82be87cf3e6679c8d7a72efc5625286){rel=""nofollow""} Thanks [@taltholtmann](https://github.com/taltholtmann){rel=""nofollow""}! - Do not pass `disabled` to `mt-field-label` in `mt-switch`, so the inheritance toggle remains clickable when the field is disabled - Updated dependencies \[[`38dca02`](https://github.com/shopware/meteor/commit/38dca021430720533747c51a0755756f02ed0aa7){rel=""nofollow""}]: - @shopware-ag/meteor-admin-sdk\@6.8.0 ### 4.28.4 #### Patch Changes - Updated dependencies \[[`e5ed183`](https://github.com/shopware/meteor/commit/e5ed183fb28337aceee3addabd30b2cbc1e94309){rel=""nofollow""}]: - @shopware-ag/meteor-admin-sdk\@6.7.4 ### 4.28.3 #### Patch Changes - Updated dependencies \[[`3555da4`](https://github.com/shopware/meteor/commit/3555da49571e2374e1c822a79006f2b8c8c0097c){rel=""nofollow""}]: - @shopware-ag/meteor-admin-sdk\@6.7.3 ### 4.28.2 #### Patch Changes - Updated dependencies \[[`b88ded5`](https://github.com/shopware/meteor/commit/b88ded5bfe9791c442829fd1bae0d6220dba0887){rel=""nofollow""}]: - @shopware-ag/meteor-admin-sdk\@6.7.2 ### 4.28.1 #### Patch Changes - Updated dependencies \[[`e7003d3`](https://github.com/shopware/meteor/commit/e7003d3a7f908544888b67b453dee9e8e246a608){rel=""nofollow""}]: - @shopware-ag/meteor-admin-sdk\@6.7.1 ### 4.28.0 #### Minor Changes - [#1085](https://github.com/shopware/meteor/pull/1085){rel=""nofollow""} [`d6f96a2`](https://github.com/shopware/meteor/commit/d6f96a2fb68eefc91c00be79b47a8066b4b004af){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Add story for `mt-floating-ui` #### Patch Changes - Updated dependencies \[[`f24b5cb`](https://github.com/shopware/meteor/commit/f24b5cb2228d9f5974b7f34b1835e2a7986e4158){rel=""nofollow""}, [`99ccb68`](https://github.com/shopware/meteor/commit/99ccb6823ec970d7791988231df020443291bf3b){rel=""nofollow""}]: - @shopware-ag/meteor-admin-sdk\@6.7.0 ### 4.27.0 #### Minor Changes - [#1052](https://github.com/shopware/meteor/pull/1052){rel=""nofollow""} [`02baae0`](https://github.com/shopware/meteor/commit/02baae02835ba8323ef223a400c2a9b0d76a72c5){rel=""nofollow""} Thanks [@gweiermann](https://github.com/gweiermann){rel=""nofollow""}! - use \ for \ instead of manual DOM manipulation #### Patch Changes - [#1058](https://github.com/shopware/meteor/pull/1058){rel=""nofollow""} [`e237d93`](https://github.com/shopware/meteor/commit/e237d933469394e0fd2ad4e8823194fe962d2026){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Add null/undefined handling to `MtColorpicker` modelValue - Updated dependencies \[[`eb968bd`](https://github.com/shopware/meteor/commit/eb968bdb5df44844b600a263ece33fa689bac489){rel=""nofollow""}]: - @shopware-ag/meteor-admin-sdk\@6.6.0 ### 4.26.0 #### Minor Changes - [#1041](https://github.com/shopware/meteor/pull/1041){rel=""nofollow""} [`cdd8bca`](https://github.com/shopware/meteor/commit/cdd8bcaad06c1e60b3bf3298e3410e3feb5484bd){rel=""nofollow""} Thanks [@gweiermann](https://github.com/gweiermann){rel=""nofollow""}! - Order backdrop of modals to make them stackable #### Patch Changes - [#1040](https://github.com/shopware/meteor/pull/1040){rel=""nofollow""} [`196bfdc`](https://github.com/shopware/meteor/commit/196bfdcbd9b0a94e596dc62175d4a6aaffa926ca){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - fix size small in `mt-number-field` - Updated dependencies \[[`01879a1`](https://github.com/shopware/meteor/commit/01879a18a412afbaf96c070f7b5fa459a8a56b39){rel=""nofollow""}, [`8bcae42`](https://github.com/shopware/meteor/commit/8bcae42bd8337af2f74123b1cb8555ca82c3092a){rel=""nofollow""}]: - @shopware-ag/meteor-tokens\@1.4.0 - @shopware-ag/meteor-admin-sdk\@6.5.1 ### 4.25.0 #### Minor Changes - [#1032](https://github.com/shopware/meteor/pull/1032){rel=""nofollow""} [`869b2fc`](https://github.com/shopware/meteor/commit/869b2fc1c5cf05ad4911180093743c1fe5aa503d){rel=""nofollow""} Thanks [@gweiermann](https://github.com/gweiermann){rel=""nofollow""}! - Deprecate `mt-number-field`s property `allowEmpty` and make its default to `true` instead of `false`. - [#1002](https://github.com/shopware/meteor/pull/1002){rel=""nofollow""} [`ed55526`](https://github.com/shopware/meteor/commit/ed5552636ed84efed65274672ec5f7e3f7baaeeb){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - add `mt-radio-group` component - [#1037](https://github.com/shopware/meteor/pull/1037){rel=""nofollow""} [`72586a8`](https://github.com/shopware/meteor/commit/72586a81aac5544b4e8c733e0d88aa4be560793b){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Add `showControls` prop to `mt-number-field` - [#1033](https://github.com/shopware/meteor/pull/1033){rel=""nofollow""} [`69815ad`](https://github.com/shopware/meteor/commit/69815adc3af6badc5f4bad1fad331cca2c101124){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - fix size `small` for `mt-base-field` #### Patch Changes - [#1021](https://github.com/shopware/meteor/pull/1021){rel=""nofollow""} [`20ecb82`](https://github.com/shopware/meteor/commit/20ecb8238c11ff548ea5f8fa91d12195dd6d02fe){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Export `mt-help-text` from component library - Updated dependencies \[[`481e01d`](https://github.com/shopware/meteor/commit/481e01d2f55f66700139bda63c71071cc63078e9){rel=""nofollow""}]: - @shopware-ag/meteor-admin-sdk\@6.5.0 ### 4.24.0 #### Minor Changes - bca848a: Add header-left slot to `mt-modal` Add header-right slot to `mt-modal` Add headerHide prop to `mt-modal` Add closeable prop to `mt-modal-root` - b4909d0: add mt-avatar component #### Patch Changes - 9b3b208: fix: hide time hint in `mt-datepicker` - e14e664: fix border-top color on mt-card footer ### 4.23.0 #### Minor Changes - 43795ed: fix(mt-number-field): allow typing intermediate values below min/max during input - d209cdc: feat: add centered prop to `mt-empty-state` #### Patch Changes - bb08d97: revert default center `mt-empty-state` ### 4.22.0 #### Minor Changes - 9aa19e4: Add exports for `mt-snackbar` and `useSnackbar` - 6467a01: Add `tertiary` variant to `mt-button` Deprecated `action` variant on `mt-button`. Use `secondary` instead. - efce046: Add "matchReferenceWidth" prop to "mt-floating-ui" to match the width of the reference element #### Patch Changes - 3e475a8: Fix font size of `large` variant of `mt-button` ### 4.21.1 #### Patch Changes - 66de384: Add watcher on the `default-item` prop in `mt-tabs` - 3c80718: Fixed wrapper spacing in `mt-datepicker` ### 4.21.0 #### Minor Changes - 502e096: Added br-tag to mt-tooltip allowlist - a7d05e5: Fix timezone issue in `mt-datepicker` ### 4.20.1 #### Patch Changes - Updated dependencies [e14b1ea] - @shopware-ag/meteor-tokens\@1.3.1 ### 4.20.0 #### Minor Changes - 863d58e: Add diff-view to mt-text-editor when using unsupported markup #### Patch Changes - 0623c6b: Add v-model to mt-checkbox - 0623c6b: Refactor mt-password-field so that it uses mt-base-field and supports inheritance logic. Also fixes hint prop - 0623c6b: Use the mt-inheritance-switch inside the mt-field-label instead of a manual implementation - 8537be0: feat: add translation to promo badge - 0623c6b: Fix missing inheritance events in mt-colorpicker ### 4.19.0 #### Minor Changes - eadd0c4: Add ability to disable the selection of specific row in mt-data-table #### Patch Changes - 462f4db: fix: mt-select button alignment ### 4.18.0 #### Minor Changes - e50a2f8: feat: make center alignment default mt-empty-state - 864b75a: feat: implement mt-promo-badge component - a1a8ee8: implement snackbar component - 350639a: Add more support for different HTML elements for the mt-text-editor - 3360706: feat: implement badge component - a375c4c: Add ability to append more context button for each row of mt-data-table #### Patch Changes - 324a662: Add color for banner content - b183cb8: Pass `Event` to the `onLabelClick` handler - b8b71dd: Fix that overflowed elements like popovers aren't visible inside mt-card - 2846d01: Align colors of placeholders for all input fields - e7491e2: stop showing hover styles for disabled number field controls - Updated dependencies [9726930] - Updated dependencies [92c09da] - @shopware-ag/meteor-admin-sdk\@6.4.0 ### 4.17.0 #### Minor Changes - 70666f2: Fine tune mt-loader size scaling #### Patch Changes - faac8e2: add slot for customize the cell content - 8959aec: Added prop `linkType` to `mt-empty-state` to control the behaviour of the displayed link. - 3f8428c: fix error state unit field - Updated dependencies [2f985e4] - Updated dependencies [033631c] - @shopware-ag/meteor-admin-sdk\@6.3.0 ### 4.16.1 #### Patch Changes - 3f0a32c: fix dragdrop behaviour mt-popover - 9c4350b: change global color of headings and paragraphs - Updated dependencies [809847f] - @shopware-ag/meteor-icon-kit\@5.6.0 ### 4.16.0 #### Minor Changes - 67fa32b: - Add error handling for mt-datepicker component - Add minDate handling for mt-datepicker component #### Patch Changes - 6e30862: Moved ellipsis animation from mixins to global - Updated dependencies [9a63888] - Updated dependencies [4954036] - @shopware-ag/meteor-tokens\@1.3.0 - @shopware-ag/meteor-admin-sdk\@6.2.1 ### 4.15.0 #### Minor Changes - 06fe48f: Add is prop to `mt-button`:br Note: We've deprecated the `link` prop in favor of the `is` prop. :br Old: ```vue Link ``` :brNew: ```vue Link ``` ### Why? :brThe new API improves the user experience. :br The old API always used a standard HTML anchor tag. This caused the page to always do a full page reload. :br With this new API you can also use the `RouterLink` component of the Vue Router package. The router can intercept the page and do a typical SPA navigation. #### Patch Changes - 0f4c732: Properly announce mt-progress-bar to screen readers - 6cc0aab: Allow setting name for `mt-checkbox` for form submition - 87cf138: Allow setting `mt-checkbox` as required - 47c4e16: improve keyboard experience for `mt-number-field` - 27cf4bf: Add inset values for mt-card content - bc745ce: stop shrinking increment and decrement buttons of number field when it gets smaller - 0f4c732: Remove unnecessary vertical spacing for mt-progress-bar - 8e13247: Make clear button in mt-select bigger - 68c05cf: Update focus styles for form components - 50a3ab1: Fix: Updated CSS selector for preview images in `mt-data-table-text-renderer` to apply correct styles - 0f4c732: Correctly announce multiple mt-progress-bars - c0ec385: Update color tokens - ce4f3a2: Improve UX of http method toggle in mt-url-field - 2620d2c: Improve text-wrapping for empty state descriptions - 6b1a724: Set fixed dimensions for icon in mt-empty-state regardless which icon is used - 4092483: Update focus styles of mt-button - 0f4c732: Hide progress label if none is defined - 8aadd9d: Corrected datepicker alignment - Updated dependencies [19ca0a3] - @shopware-ag/meteor-tokens\@1.2.0 ### 4.14.0 #### Minor Changes - 333ac4c: Add mt-entity-select component #### Patch Changes - d09f56f: Do not show the timezone when displaying a date in mt-datepicker - 2dfd85a: Define emits on `mt-datepicker` - 2dfd85a: Update text colors in datepicker - cf0626a: Add reactivity to `min`/`max` changes in `mt-number-field` to prevent invalid values. - 2dfd85a: Allow clearing value of `mt-datepicker` - e78c40a: fix: validator errors mt-field-error - Updated dependencies [802233c] - Updated dependencies [e44cf07] - @shopware-ag/meteor-admin-sdk\@6.2.0 ### 4.13.0 #### Minor Changes - 794edcc: Add mt-entity-data-table component #### Patch Changes - Updated dependencies [5e34e6d] - @shopware-ag/meteor-admin-sdk\@6.1.0 ### 4.12.2 #### Patch Changes - de166a0: Add wrapper value to mt-data-table story - 0f57146: Reduced animation delay in mt-tool-tip ### 4.12.1 #### Patch Changes - 1147b22: Set default variant of `mt-button` to `secondary` ### 4.12.0 #### Minor Changes - 215eec6: Added button slot to mt-empty-state ### 4.11.2 #### Patch Changes - a85dee7: Add opacity to shadow token ### 4.11.1 #### Patch Changes - 611eb5d: Emit a blur event when blurring the `mt-text-field` - 0a04056: Style icons in mt-select to work in dark mode - 0257c30: allow setting icon size via style prop ```vue ``` ### 4.11.0 #### Minor Changes - 36bf822: Add mt-unit-field component #### Patch Changes - be9c623: fixed unnecessary whitespace select - 74772d6: fixed multiple select handling - bed29f0: Only emit change event when using `@change` on `mt-number-field` - 2cd3eff: Do not emit change event when pressing increment and decrement buttons on `mt-number-field` - e77fada: fixed hint class naming datepicker - 828c6dc: fixed popover width resizing ### 4.10.1 #### Patch Changes - 269bf4a: Add mt-switch--disabled class to mt-switch - c47c136: Update alignment of close icon in mt-label - Updated dependencies [f4ed7d0] - Updated dependencies [0f5575d] - Updated dependencies [a1c2414] - @shopware-ag/meteor-tokens\@1.1.0 - @shopware-ag/meteor-icon-kit\@5.5.0 ### 4.10.0 #### Minor Changes - 243ffd8: Changed z-index of mt-modal and mt-tooltip #### Patch Changes - 9b0cc45: \* Remove duplicated external link icon - Removed fixed 16px font-size for `mt-link` - Changed gap and icon size to be relative to current font size - adb59f8: Allow sanitized HTML values inside tooltip ### 4.9.1 #### Patch Changes - 466f306: Get rid of duplicate isInherited in mt-checkbox ### 4.9.0 #### Minor Changes - fd48763: Add custom format prop for mt-datepicker and add dateType "time" to mt-datepicker - 3ff2753: add catch to dynamic icon import in mt-icon.vue #### Patch Changes - 5c20ef8: Fix the `mt-email-field` showing the error message on its init instead after interacting with it. - 34d33d9: Add missing isInherited prop to mt-checkbox - 3a8e1d5: - Align form component heights - e440678: - Fix tooltip z-index position - 32b1d35: Added `type=button` to all buttons to prevent default `type=submit` behaviour - 371c286: Fix overflow of colorpicker in mt-text-editor ### 4.8.0 #### Minor Changes - c6017dd: Added label slot to mt-checkbox ### 4.7.1 #### Patch Changes - 55b219b: - Remove stop propagation for `mt-select-base` click handler ### 4.7.0 #### Minor Changes - 8d89449: Fix password flickering and add submit event for `mt-password-field.vue` component. ### 4.6.0 #### Minor Changes - 3af841b: Allow setting the max width of a tooltip ```html ``` - 7498dc5: Fix single select truncation #### Patch Changes - ba9a202: Allow setting the max width of helptexts - 611a1d9: Set default max-width of help texts to 240px - c0166e8: Change display mode of mt-button to inline-grid - b0d74e7: Teleport tooltips to body - b3d2b03: Set default max-width of tooltips to 240px - 67c1cf8: Wrap tooltip content for mt-tooltip component ### 4.5.1 #### Patch Changes - 6372237: Center content of mt-button when it's a link - 55832a9: Show icons when mt-button is a link ### 4.5.0 #### Minor Changes - 6de3f71: Allow setting an icon without specifing the mode like regular or solid :br You can now define an icon without explicitly defining the mode for it like this: ```vue ``` :brBy default we use regular icons, however you can use solid icons as follows: ```vue ``` #### Patch Changes - ee0a4ad: Allow setting a margin on an `mt-button` component - a57d22e: fix: update wrong position of mt-select popover - d988d78: Add auto-completion for color prop of mt-text component ### 4.4.1 #### Patch Changes - 1b0b620: Add missing placeholder to mt-colorpicker - 6cc3876: Focus colorpicker when clicking on its label - Updated dependencies [7abaa5a] - @shopware-ag/meteor-tokens\@1.0.0 ### 4.4.0 #### Minor Changes - c235676: Make mt-url-field public ### 4.3.1 #### Patch Changes - f251c89: Fix alignment of help-text in mt-textarea component - 489997c: Fix mt-popover-deprecated - Previously the `mt-popover-deprecated` component was configured to have the name `MtPopover`. This caused issues with some compiler setups. Change the name to `MtPopoverDeprecated`. ### 4.3.0 #### Minor Changes - 4893678: Add v-model support to mt-switch - ef58de6: chore: export type Toast #### Patch Changes - 4893678: Stop emitting inheritance-restore event twice on switch field - 2fbc665: Stop selecting text when double clicking on label - 4893678: Stop emitting inheritance-remove event twice for switch - 4893678: Mark mt-switch as required if required prop is true - 0d00f6f: Do not show bottom shadow in modal when content is not scrollable - 8d1820d: Announce error of mt-switch to screenreaders ### 4.2.0 #### Minor Changes - 4536d2a: Emit change event on password field - d6c07d0: Add types for event of mt-url-field component #### Patch Changes - a0c8266: Stop emitting onUpdate\:modelValue event when blurring the mt-url-field - 4536d2a: Add name property to mt-password-field - 48134cd: Add types for slots for mt-url-field - c5471b3: Announce tooltip content when focusing tooltip trigger - cc6075f: Announce email field as invalid to screen readers when input has error - d8a289e: Fix some small bugs in mt-text-field, mt-email-field and mt-tooltip - 43305d9: Stop announcing tooltip triangle to screen readers ### 4.1.0 #### Minor Changes - 64c04bd: Make mt-search public - ab6cba0: feat(mt-colorpicker): Add keyboard navigation support - 4e96d91: Add mt-url-field #### Patch Changes - 4e96d91: Allow toggling the http protocol in mt-url-field using the keyboard - 4e96d91: Disable mt-url-field when inheritance is linked - 8434c25: Fix huge error badge in mt-tabs - 362941d: mt-textarea can now be a required form field - cf34b59: Turn scrollbar dark for dark mode - ed02b43: Show label for single-option mt-select in full width - 4e96d91: Stop emitting update\:modelValue event when component gets created - 859c7f8: Open tooltip when focusing a loading link button with a tooltip - 4e96d91: Do not change the http protocol in mt-url-field when clicking the protocol button and the input field is inherited - a8d3340: hide data table toolbar when it has no header - 4e96d91: Allow mt-url-field to be required - 11b05f5: Disable number field when value is inherited - eee3ecf: Do not redirect when clicking on a disabled link button - 045b002: Show search icon when mt-select has not results - fbca9df: Add aria attributes to mt-switch - 4e96d91: emit update\:modelValue every time the user types into the mt-url-field - eee3ecf: Do not allow focusing a loading link button - f4e2d6b: Open the context menu when pressing space or enter - 95edac4: Add focus state to banner close button - 26c8e2b: Show a tooltip when focusing a disabled link button with a tooltip - 8405f12: Do not allow focusing a disabled link button - 3863b64: Announce mt-search as a real search input - fab1a1d: Remove link role from mt-link when using custom component ### 4.0.1 #### Patch Changes - f3b0e2f: Fixed the Type generation for components like mt-text-editor or mt-tabs ### 4.0.0 #### Major Changes - fc3c5a6: Reduce bundle size caused by font :br Previously you needed to only import one css file: ```js // Some JavaScript file: index.js import "@shopware-ag/meteor-component-library/dist/styles.css"; ``` :brYou now need to update that one import to the following two imports: ```js // Some JavaScript file: index.js import "@shopware-ag/meteor-component-library/styles.css"; // Note: this path is different from the old one import "@shopware-ag/meteor-component-library/font.css"; ``` :brIf you want to load the font by yourself, you can do that. Remove the second import and load the font the way you want. - eeb8c7f: Removed locale control from mt-theme-provider. :br Controlling the local will still happen via vue-i18n - b2ef241: Making vue a peer dependency :br This allows you to define the version of Vue you want to use. Before you needed to use the exact vue version Meteor used. Now you can define it by yourself, but it must meet the version requirements. - 50de30f: Require a minimum version of vue 3.5 - b3039c1: # Add new Text Editor component :br This change introduces a new Text Editor component to the Meteor Component Library. :br We change the 'legacy' mode of i18n to 'false' in the Meteor Component Library configuration to use the new i18n composable. #### Minor Changes - ba4fdbd: Adds a new slot for custom content within the button, enabling more flexible button customization. - d9c26a2: Export mt-tooltip component - 7593d00: remove hero variant from mt-card - 9175c17: replace flatpickr with vue3datepicker - b5ed517: Add mt-tooltip component - b7423bb: remove mt-url-field #### Patch Changes - ad10063: Hide inheritance toggle in card by default - 0dcb079: Improve reading order for card titles when using a screen reader - 54b5fa4: Add translation for mt-banner - a4b2203: Add focus styles for checkbox - 066da5c: Open tooltip when focusing disabled button - 51d6160: Migrate mt-select over to the custom built i18n composable - 85908bf: Migrate mt-data-table over to the custom built i18n composable - 824ee5a: Update focus style of inheritance toggle in card - d2480cf: Fixes a issue in the mt-modal that the toggling does not work when it is triggered outside the modal. Fixes a issue in the mt-modal that it does not work inside transformed elements. This was fixed by moving the modal to the body element using the native Teleport feature of Vue 3. - 0280b80: Add missing translation for data table filters - 069a2ad: Do not announce mt-avatar for screen readers - daa8824: Add landmarks to card component for screen readers - ed03f65: Improve accessibility of mt-field-error - 893fba8: Increase contrast ratio in mt-avatar - 3b50452: Update focus style of switch - 4f9e73d: Migrate mt-data-table-settings over to the composition api - 893fba8: Increase color contrast in mt-avatar component - 45e2dc7: Make size propert on mt-loader optional - 235546f: Migrate mt-label to custom built i18n composable - 850107e: Fix emit focus event for mt-text-field component ### 3.14.0 #### Minor Changes - 001adb3: Add external and internal variants for link component #### Patch Changes - cc754b9: Deprecated the mt-url-field component - 47063ae: Deprecated mt-external link component - 62be382: move mt-loader over to plain css - 28f5cb1: remove default margin of banner component, hidden by future flag - 6d32afa: Improve a11y of help text - 936ccf3: Allow disabling individual tab items - 2f0a666: Remove default margin from base field, hidden by future flag - 07e243a: Migrate mt-loader over to the composition api ### 3.13.0 #### Minor Changes - a438ea0: Add future flag for removing card max width - 3c1b5ad: Add mt-theme-provider component - 79f0b40: Remove default margin for tab component when using removeDefaultMargin future flag #### Patch Changes - ec2aba1: Do not announce icon of empty state - 340f7af: fix the issue in the sw-number-field component when pressing the up or down arrow keys if a new value was typed - 5a5e797: Replace mt-popover-deprecated in mt-colorpicker - 307439b: Updated flatpickr dependency to the latest version to fix mt-datepicker issue when date typed manually - d0185b6: Deprecate hero card - 3ddcd26: Make buttons in number field accessible - cb83cca: Deprecate small prop on tabs component - 17bca01: Remove default margin from checkbox, hidden by future flag - c43799c: remove default margin from card component, hidden by future flag ### 3.12.0 #### Minor Changes - ea49a5e: Disable next page and last page button in mt-pagination when data table is empty - ecf9d1a: Allow insetting of card footer - 627f2fb: Add mt-text component - ebf0a2a: Add mt-inset component #### Patch Changes - da43c4e: Use semantic border radius tokens in card component - c412dd0: Change styling of card footer - 36e0812: Fixed missing emit definition and console warning - 4a59fcc: Replaced border radius tokens with tokens - 0630e58: Adjust padding of card header - 9ea8e15: Allow null label for mt-textarea - dc6ad1a: allow x-small as valid variant for button - 1321454: Add semantic border radius token for checkbox - 6371d3a: Use rem values instead of px values in card - 11d870a: Make toggle password button accessible - 099ca2b: Fix styling of card title - 8045090: Hide label with CSS in base-field component when empty - ebe7a33: Use semantic border radius token for overlays - bebea2e: Use button border radius token for buttons and segmented control - Updated dependencies [e644cef] - @shopware-ag/meteor-tokens\@0.3.0 ### 3.11.0 #### Minor Changes - 1319ae3: Add mt-slider component ### 3.10.0 #### Minor Changes - 4c8d610: Add mt-modal component ### 3.9.0 #### Minor Changes - 8c74a37: Add mt-link component #### Patch Changes - 24e5d7a: Add token to select empty state - 573953b: Fix mt-select currentValue getter early return on null or undefined values - 0ee7820: Make difference between enabled and disabled paginations button more clear ### 3.8.2 #### Patch Changes - 4be837e: Add tokens for loader component - b6c52b7: Fix positioning of the toast notifications - b301a99: Fix placeholder in select components - 4f85b4f: Style required star for base field - cdb9eda: Add tokens to context button - 8182c77: Add tokens for data table component - 3eb91a0: Add tokens for skeleton bar ### 3.8.1 #### Patch Changes - def10ee: Add tokens to tooltip component - 81f8d4c: Fix tag deletion is not working on the Safari browser - d60aad5: # Fix number field events - Deprecated `change` event for `mt-number-field` - Added `update:modelValue` event to `mt-number-field` - Updated dependencies [0a0ac80] - Updated dependencies [0a0ac80] - Updated dependencies [0a0ac80] - Updated dependencies [0a0ac80] - Updated dependencies [0a0ac80] - Updated dependencies [0a0ac80] - Updated dependencies [0a0ac80] - Updated dependencies [0a0ac80] - Updated dependencies [0a0ac80] - Updated dependencies [0a0ac80] - @shopware-ag/meteor-tokens\@0.2.0 ### 3.8.0 #### Minor Changes - 19bba6e: Make mt-floating-ui component public available #### Patch Changes - 2946e98: Add tokens to switch component - 7798532: Remove unecessary pressed state for number field component - 1c90253: Add tokens to external link component - 23dc704: Add tokens for password field - 1574963: Set disabled attribute on disabled items in segmented control - 40641b6: Fix tooltip placement - 2d24896: Add tokens for textarea field - d935701: Adjust padding of card content - 5fc49f8: Add tokens for color picker - 16be216: Add tokens to segmented control component - 2b13b0b: Add tokens to number field ### 3.7.0 #### Minor Changes - cfff3b8: Update and build globally mt-empty-state - 50afd23: Add a prop to remove settings table button in the header - fbe8152: Allow add an image to cell table #### Patch Changes - c76ec92: Add tokens for search component - 15efa51: Add tokens for mt-base-field - 1b4e735: Add tokens for checkbox component - b9b4005: Change icon of inheritance switch - d9f7c3e: Adjust icon of copy button ### 3.6.1 #### Patch Changes - c58b80f: Fix data table open details event emitter in context menu item ### 3.6.0 #### Minor Changes - 22a5068: Exporting Filter and Option types - 321a830: Add filters to data table - 3b22c7a: Import overlay popover component to use. #### Patch Changes - b54d88c: Fix toast type to accept string|number for property id ### 3.5.2 #### Patch Changes - 84836ea: Fix correct wrapping of "mt-select-selection-list" ### 3.5.1 #### Patch Changes - b68fa55: fix createId not being compatible with webpack ### 3.5.0 #### Minor Changes - 95cdb1f: Allow attribute inheritance on every form field #### Patch Changes - 85942a2: Fix id generation for inputs when using SSR ### 3.4.0 #### Minor Changes - 97ba4d8: Implement toasts #### Patch Changes - 7ff2788: Remove unnecessary left border in data table - Updated dependencies [8443590] - @shopware-ag/meteor-tokens\@0.1.0 ### 3.3.0 #### Minor Changes - f0655bf: Add inheritance toggle to card component #### Patch Changes - a6fe140: resize checkmark in checkbox to correct dimensions - 0ba5c91: Change wrong Fragment import from React to Vue - 856489b: Only animate tabs slider after first render ### 3.2.0 #### Minor Changes - e0e1741: Add property "size" to "mt-icon" ### 3.1.0 #### Minor Changes - 6c6678d: - Renamed all "sw" prefixes to "mt" - Keep old sw prefixes for backwards compatibility ### 3.0.0 #### Minor Changes - bff12c5: - Added character count to sw-text-field and sw-textarea #### Patch Changes - 8a9066a: Fix prop type validation inside sw-select-result-list which fixes SSR All notable changes to this project will be documented in this file. ### [3.0.0] - 16.02.2024 - Updated Vue version from 2 to 3 - Updated Storybook build from Webpack to Vite - Changed Jest to Vitest ### [2.2.0] - 17.10.2023 - Added MtPagination and DeviceHelperPlugin to public API - Fix sw-tab emitting 'new-item-active' event ### [2.1.2] - 06.09.2023 - Fix indeterminate state of `sw-checkbox` ### [2.1.1] - 26.04.2023 - Fixed broken `sw-text-field` inheritance option - Fixed missing bannerIndex property in `sw-banner` - Fixed `sw-select` single select behaviour ### [2.1.0] - 21.03.2023 - Fixed wrong timezone handling in datepicker ### [2.0.1] - 25.01.2022 - Fixed wrong bundling of UUID utils which don't work in browser ### [2.0.0] - 09.01.2022 #### BREAKING CHANGES - Changed default font from Source-Sans-Pro to Inter ### [1.0.2] - 30.12.2022 #### Changed - Changed `visibleValues` computed property in `sw-select` to correctly display selected value for single select component. #### BREAKING CHANGES - Updated Vue version to 2.7 #### Changed - Updated Webpack in Storybook to version 5 - Changed drop-shadow to box-shadow in "sw-card" to improve performance in Safari ## Tokens ### 1.4.0 #### Minor Changes - [#1049](https://github.com/shopware/meteor/pull/1049){rel=""nofollow""} [`01879a1`](https://github.com/shopware/meteor/commit/01879a18a412afbaf96c070f7b5fa459a8a56b39){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - - Upgraded typescript-eslint from 8.24.1 to 8.35.0 - Migrated from eslint-plugin-vitest to @vitest/eslint-plugin - Upgraded @types/node from 22.13.4 to 25.0.0 ### 1.3.1 #### Patch Changes - e14b1ea: mark every dependency as a dev dependency ### 1.3.0 #### Minor Changes - 9a63888: Add description to all Design Tokens ### 1.2.0 #### Minor Changes - 19ca0a3: Update tokens - Added `color/interaction/secondary/pressed` - Added `color/elevation/backdrop/default` - Added `color/elevation/floating/default` - Added `color/background/secondary/default` - Added `color/background/tertiary/default` - Added `color/icon/primary/inverse` - Added `color/icon/secondary/default` - Added `color/icon/secondary/disabled` - Added `color/icon/secondary/inverse` - Added `color/icon/brand/pressed` - Added `color/text/primary/inverse` - Added `color/text/secondary/inverse` - Added `color/text/brand/pressed` - Added `color/text/critical/pressed` - Added `color/text/brand/inverse` - Added `color/static/white` - Added `color/static/black` - Changed `color/interaction/primary/hover` to map to `color/brand/600` instead of `color/brand/700` in light and dark mode - Changed `color/interaction/primary/pressed` to map to `color/brand/700` instead of `color/brand/600` in light and dark mode - Changed `color/interaction/primary/disabled` to map to `color/brand/800` instead of `color/brand/300` in dark mode - Changed `color/interaction/critical/hover` to map to `color/red/600` instead of `color/red/700` in light and dark mode - Changed `color/interaction/critical/pressed` to map to `color/red/700` instead of `color/red/600` in light and dark mode - Changed `color/interaction/critical/disabled` to map to `color/red/800` instead of `color/red/200` in dark mode - Changed `color/interaction/secondary/default` to map to `color/zinc/900` instead of `color/zinc/850` in dark mode - Changed `color/interaction/secondary/hover` to map to `color/zinc/850` instead of `color/zinc/800` in dark mode - Changed `color/interaction/secondary/pressed` to map to `color/zinc/800` instead of `color/zinc/900` in dark mode - Changed `color/elevation/surface/sunken` to map to `color/zinc/1000` instead of `color/zinc/975` in dark mode - Changed `color/elevation/surface/default` to map to `color/zinc/975` instead of `color/zinc/950` in dark mode - Changed `color/elevation/surface/raised` to map to `color/zinc/950` instead of `color/zinc/900` in dark mode - Changed `color/elevation/surface/floating` to map to `color/elevation/floating/default` - Changed `color/background/brand/default` to map to `color/brand/900` instead of `color/brand/800` in dark mode - Changed `color/background/critical/default` to map to `color/red/900` instead of `color/red/800` in dark mode - Changed `color/background/attention/default` to map to `color/orange/900` instead of `color/orange/800` in dark mode - Changed `color/background/positive/default` to map to `color/green/900` instead of `color/green/800` in dark mode - Changed `color/background/accent/default` to map to `color/purple/900` instead of `color/purple/800` in dark mode - Changed `color/background/primary/default` to map to `color/zinc/0` in light mode - Changed `color/background/primary/default` to map to `color/zinc/900` in dark mode - Changed `color/background/primary/disabled` to map to `color/background/tertiary/default` - Changed `color/background/critical/dark` to map to `color/background/critical/default` - Changed `color/icon/primary/default` to map to `color/zinc/900` instead of `color/zinc/700` in light mode - Changed `color/icon/primary/default` to map to `color/zinc/50` instead of `color/zinc/100` in dark mode - Changed `color/icon/primary/disabled` to map to `color/zinc/300` instead of `color/zinc/200` in light mode - Changed `color/icon/primary/disabled` to map to `color/zinc/600` instead of `color/zinc/500` in dark mode - Changed `color/icon/brand/hover` to map to `color/brand/600` instead of `color/brand/700` in light and dark mode - Changed `color/icon/brand/disabled` to map to `color/brand/700` instead of `color/brand/300` in dark mode - Changed `color/icon/critical/default` to map to `color/red/500` instead of `color/red/400` in dark mode - Changed `color/icon/critical/disabled` to map to `color/red/800` instead of `color/red/300` in dark mode - Changed `color/icon/static/default` to map to `color/static/white` in light and dark mode - Changed `color/icon/static/dark` to map to `color/static/black` in light and dark mode - Changed `color/icon/inverse/default` to map to `color/icon/primary/inverse` instead of `color/zinc/50` in light mode - Changed `color/icon/inverse/default` to map to `color/icon/primary/inverse` instead of `color/zinc/850` in dark mode - Changed `color/border/brand/selected` to map to `color/border/brand/default` - Changed `color/border/brand/default` to map to `color/brand/500` in dark and light mode - Changed `color/border/brand/disabled` to map to `color/brand/700` instead of `color/brand/300` in dark mode - Changed `color/border/critical/disabled` to map to `color/red/700` instead of `color/red/300` in dark mode - Changed `color/border/secondary/default` to map to `color/zinc/850` instead of `color/zinc/800` in dark mode - Changed `color/border/critical/default` to map to `color/red/500` instead of `color/red/400` in dark mode - Changed `color/border/attention/default` to map to `color/orange/600` instead of `color/orange/500` in dark mode - Changed `color/border/positive/default` to map to `color/green/600` instead of `color/green/500` in dark mode - Changed `color/border/accent/default` to map to `color/purple/600` instead of `color/purple/500` in dark mode - Changed `color/text/inverse/default` to map to `color/text/primary/inverse` instead of `color/zinc/50` in light mode - Changed `color/text/inverse/default` to map to `color/text/primary/inverse` instead of `color/zinc/850` in dark mode - Changed `color/text/static/default` to map to `color/static/white` in light and dark mode - Changed `color/text/static/dark` to map to `color/static/black` in light and dark mode - Changed `color/text/brand/hover` to map to `color/brand/600` instead of `color/brand/700` in light mode - Changed `color/text/brand/default` to map to `color/brand/400` instead of `color/brand/500` in dark mode - Changed `color/text/brand/hover` to map to `color/brand/500` instead of `color/brand/700` in dark mode - Changed `color/text/brand/disabled` to map to `color/brand/700` instead of `color/brand/300` in dark mode - Changed `color/text/critical/hover` to map to `color/red/600` instead of `color/red/700` in light mode - Changed `color/text/critical/hover` to map to `color/red/500` instead of `color/red/700` in dark mode - Changed `color/text/critical/disabled` to map to `color/red/700` instead of `color/red/300` in dark mode - Changed `color/text/primary/default` to map to `color/zinc/50` instead of `color/zinc/100` in dark mode - Changed `color/text/primary/default` to map to `color/zinc/900` instead of `color/zinc/800` in light mode - Changed `color/text/primary/disabled` to map to `color/zinc/600` instead of `color/zinc/500` in dark mode - Changed `color/text/secondary/disabled` to map to `color/zinc/600` instead of `color/zinc/500` in dark mode - Changed `color/text/critical/dark` to map to `color/text/critical/default` - Fixed `color/elevation/surface/floating` to map to `color/zinc/0` instead of `#FFFFFF` in dark mode - Deprecated `border radius/overlay`. Please use `border radius/xs` instead. - Deprecated `color/interaction/secondary/dark`. Please use `color/interaction/secondary/default` for interactive elements and `color/background/tertiary/default` for non-interactive elements instead. - Deprecated `color/elevation/surface/selected`. There is no direct replacement. - Deprecated `color/elevation/surface/hover`. There is no direct replacement. - Deprecated `color/elevation/surface/frame`. There is no direct replacement. - Deprecated `color/elevation/surface/overlay`. Please use `color/elevation/surface/raised` instead. - Deprecated `color/elevation/surface/backdrop`. Please use `color/elevation/backdrop/default` instead. - Deprecated `color/elevation/surface/floating`. Please use `color/elevation/floating/default` instead. - Deprecated `color/background/primary/disabled`. Please use `color/background/tertiary/default` instead. - Deprecated `color/background/critical/dark`. Please use `color/background/critical/default` instead. - Deprecated `color/icon/critical/hover`. There is no direct replacement. Icons in links should use the corresponding text color. - Deprecated `color/icon/static/default`. Please use `color/static/white` instead. - Deprecated `color/icon/static/dark`. Please use `color/static/black` instead. - Deprecated `color/icon/inverse/default`. Please use `color/icon/primary/inverse` instead. - Deprecated `color/border/brand/selected`. Please use `color/border/brand/default` instead. - Deprecated `color/border/critical/dark`. Please use `color/border/critical/default` instead. - Deprecated `color/text/inverse/default`. Please use `color/text/primary/inverse` instead. - Deprecated `color/text/static/default`. Please use `color/static/white` instead. - Deprecated `color/text/static/dark`. Please use `color/static/black` instead. - Deprecated `color/text/tertiary/default`. Please use `color/text/secondary/default` instead. - Deprecated `color/text/attention/default`. There is no direct replacement. - Deprecated `color/text/positive/default`. There is no direct replacement. - Deprecated `color/text/critical/dark`. Please use `color/text/critical/default` instead. ### 1.1.0 #### Minor Changes - f4ed7d0: Add `color-border-secondary-default` token ### 1.0.0 #### Major Changes - 7abaa5a: Mark tokens as stable ### 0.3.0 #### Minor Changes - e644cef: - Removed scale/size/3 - Removed scale/size/9 - Removed scale/size/11 - Removed scale/size/13 - Removed scale/size/15 - Removed scale/size/17 - Removed scale/size/19 - Removed scale/size/34 - Removed scale/size/38 - Removed scale/size/42 - Removed scale/size/44 - Removed scale/size/52 - Removed scale/size/60 - Removed scale/size/88 - Removed scale/size/112 - Removed scale/size/144 - Removed scale/size/176 - Removed scale/size/208 - Removed scale/size/240 - Added scale/size/0 - Added border/radius/none - Added spacing/radius/checkbox - Added border/radius/button - Added border/radius/overlay - Added border/radius/card - Removed color/border/tertiary/default - Removed color/border/secondary/default ### 0.2.0 #### Minor Changes - 0a0ac80: Add color/icon/inverse token - 0a0ac80: Add color/elevation/surface/floating token - 0a0ac80: Add color/text/inverse token - 0a0ac80: Add color/text/static/dark token - 0a0ac80: Add color/icon/static/dark token #### Patch Changes - 0a0ac80: Changed color/interactive/secondary/default to map to zinc/850 instead of zinc/800 in dark mode - 0a0ac80: Changed color/icon/inverted to color/icon/static/default - 0a0ac80: Changed color/interactive/secondary/hover to map to zinc/800 instead of zinc/700 in dark mode - 0a0ac80: Changed color/text/inverted to color/text/static/default - 0a0ac80: Changed color/interactive/secondary/hover to map to zinc/75 instead of zinc/100 in light mode ### 0.1.0 #### Minor Changes - 8443590: \* Added "color/elevation/surface/frame" - Changed "color/text/accent/default" to map to "purple/400" instead of "purple/050" in dark mode - Changed "color/elevation/surface/overlay" to map to "zinc/850" instead of "zinc/800" in dark mode - Changed "color/elevation/surface/sunken" to map to "zinc/975" instead of "zinc/900" in dark mode - Changed "color/interaction/secondary/hover" to map to "zinc/700" instead of "zinc/800" in dark mode - Changed "color/elevation/surface/overlay to map to "zinc/800" instead of "zinc/900" in dark mode - Changed "color/interactive/secondary/disabled to map to "zinc/700" instead of "zinc/600" in dark mode ### 0.0.1 #### Patch Changes - 9b6a418: Add token deliverables ## Icon Kit ### 5.10.0 #### Minor Changes - [#1312](https://github.com/shopware/meteor/pull/1312){rel=""nofollow""} [`4fdee56`](https://github.com/shopware/meteor/commit/4fdee561f0dd0121f0aa8fbc780a62141ab713ab){rel=""nofollow""} Thanks [@github-actions](https://github.com/apps/github-actions){rel=""nofollow""}! - Added icons: `regular-trust``solid-trust` ### 5.9.1 #### Patch Changes - [#1289](https://github.com/shopware/meteor/pull/1289){rel=""nofollow""} [`5377579`](https://github.com/shopware/meteor/commit/5377579ac8b450ea9a86557c91216cc69d29937b){rel=""nofollow""} Thanks [@arnoldstoba](https://github.com/arnoldstoba){rel=""nofollow""}! - Move the Figma sync tooling (`@t3-oss/env-core`, `dotenv`, `ora`, `winston`, `zod`) to `devDependencies`. It is only used by the unpublished icon sync script — installs get \~10 MB smaller. If you imported one of these packages without declaring it, add it to your own `dependencies`. ### 5.9.0 #### Minor Changes - [#1263](https://github.com/shopware/meteor/pull/1263){rel=""nofollow""} [`ca51ea5`](https://github.com/shopware/meteor/commit/ca51ea5ec04da206f20e726c55ab1278d860965c){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Added multiple icons: `regular-panel-bottom``regular-panel-left``regular-panel-right``regular-panel-top``regular-shopware-copilot``solid-panel-bottom``solid-panel-left``solid-panel-right``solid-panel-top``solid-shopware-copilot`:br Modified icons: `regular-cog``solid-cog` ### 5.8.0 #### Minor Changes - [#1162](https://github.com/shopware/meteor/pull/1162){rel=""nofollow""} [`ed965bd`](https://github.com/shopware/meteor/commit/ed965bdd41fe9972ba15319ccf0077dd14026ec2){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Modified icons: `shopware-intelligence``shopware-nexus``shopware-payments` ### 5.7.0 #### Minor Changes - [#1144](https://github.com/shopware/meteor/pull/1144){rel=""nofollow""} [`d5fe2db`](https://github.com/shopware/meteor/commit/d5fe2dbb90ca5fa9513d9fc3626548e902a660c8){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Added multiple icons: `regular-bitcoin``regular-british-pound``regular-filter-alt``regular-indian-rupee``regular-japanese-yen``regular-shopware-intelligence``regular-shopware-nexus``regular-shopware-payments``regular-swiss-franc``regular-us-dollar``solid-bitcoin``solid-british-pound``solid-filter-alt``solid-indian-rupee``solid-japanese-yen``solid-shopware-intelligence``solid-shopware-nexus``solid-shopware-payments``solid-swiss-franc``solid-us-dollar` - [#1144](https://github.com/shopware/meteor/pull/1144){rel=""nofollow""} [`d5fe2db`](https://github.com/shopware/meteor/commit/d5fe2dbb90ca5fa9513d9fc3626548e902a660c8){rel=""nofollow""} Thanks [@alastair-simon](https://github.com/alastair-simon){rel=""nofollow""}! - Modified icons: `regular-cog-s``solid-cog-s` ### 5.6.0 #### Minor Changes - 809847f: Add multiple icons: - `regular-bolt` - `solid-bolt` - `regular-database-alt` - `solid-database-alt` - `regular-flame` - `solid-flame` - `regular-snowflake` - `solid-snowflake` - `regular-upscale` - `solid-upscale` ### 5.5.0 #### Minor Changes - 0f5575d: Add icons - Add `face-confused` - Add `face-frown-slight` - Add `face-meh-blank` - Add `face-meh` - Add `face-smile-relaxed` - Add `face-smile-upside-down` - Add `face-smile` - Add `face-smirking` - Add `face-unamused` - a1c2414: Add crop icon ### 5.4.0 #### Minor Changes - ec91cce: Add solid and regular "plans" icon ### 5.3.0 #### Minor Changes - e15e23a: Add share icon ### 5.2.1 #### Patch Changes - 9b441e6: We've fixed and issue that prevented two icons from being available as solid variant. :br Fixed: - `solid/e-scooter` - `solid/balance-scale` ### 5.2.0 We've added *X* to the set of social network icons. Farewell Larry 🐦 Added: - `regular/x` - `solid/x` - `regular/tiktok` - `solid/tiktok` - `regular/stackoverflow` - `solid/stackoverflow` - `regular/slack` - `solid/slack` - `regular/3D` - `solid/3D` - `regular/AR` - `solid/AR` Updated: - Adjusted visual alignment of arrows and chevrons ### 5.1.0 Revelio ✨ Added: - `regular/wand-magic` - `solid/wand-magic` - `regular/wand-magic-sparkles` - `solid/wand-magic-sparkles` - `regular/sparkle` - `solid/sparkle` - `regular/sparkles` - `solid/sparkles` ### 5.0.0 Added: - `regular/artificial-intelligence` - `solid/artificial-intelligence` - `regular/cloud` - `solid/cloud` - `regular/line-column` - `solid/line-column` - `regular/line-column-xs` Updated: - `regular/filter` - `solid/filter` Breaking change: - Renamed `delete-coloumn` to `delete-column` - Renamed `insert-coloumn-after` to `insert-column-after` - Renamed `insert-coloumn-before` to `insert-column-before` - Removed `regular/wand-magic` (available in 5.1.0) - Removed `solid/wand-magic` (available in 5.1.0) - Removed `regular/wand-magic-sparkles` (available in 5.1.0) - Removed `solid/wand-magic-sparkles` (available in 5.1.0) - Removed `regular/sparkle` (available in 5.1.0) - Removed `solid/sparkle` (available in 5.1.0) - Removed `regular/sparkles` (available in 5.1.0) - Removed `solid/sparkles` (available in 5.1.0) ### 4.6.0 Revelio ✨ Added: - `regular/wand-magic` - `solid/wand-magic` - `regular/wand-magic-sparkles` - `solid/wand-magic-sparkles` - `regular/sparkle` - `solid/sparkle` - `regular/sparkles` - `solid/sparkles` ### 4.5.0 Added: - `regular/image-text` - `solid/image-text` ### 4.4.0 Changed: - `regular/microphone-slash` - `solid/microphone-slash` - `regular/video-slash` - `solid/video-slash` - `regular/phone-slash` - `solid/phone-slash` - `regular/eye-slash` - `solid/eye-slash` - `regular/volume-mute` - `solid/volume-mute` - `regular/bell-slash` - `solid/bell-slash` Added: - `regular/mobile-slash` - `solid/mobile-slash` - `regular/tablet-slash` - `solid/tablet-slash` - `regular/desktop-slash` - `solid/desktop-slash` ### 4.3.0 Added: - `regular/globe` and `solid/globe` ### 4.2.0 Added: - `regular/link-horizontal` and `solid/link-horizontal` - `regular/link-horizontal-slash` and `solid/link-horizontal-slash` - CSS is now generated along svgs files ### 2.1.0 Added: - `regular/party-horn` and `solid/party-horn` - `regular/google` and `solid/google` Fixed: - Fix size and path issues of `regular/shopware` and `solid/shopware` ### 2.0.0 Breaking change: - Updated names of icons: `solid/thumbs-up`, `regular/thumbs-up`, `regular/times-hexagon`, `regular/thumbs-down` ### 1.1.0 Fix: - Before creating the SVG icons all existing icons will be deleted. This will allow to delete icons Features: - Only include the `icons` folder in the NPM package ### 1.0.0 Features: - Initial release of the icon kit \ # Design Principles Our Product Design Principles reflect how we think about design: **Building the right thing; building the thing right.** These principles are the foundation of Shopware's products and services, whether you work at Shopware or develop apps for the Shopware ecosystem. They are not a checklist. They are a shared lens for making decisions when requirements are ambiguous, tradeoffs are real, and speed matters. ## Accessibility and inclusivity Design experiences that are accessible to users of all abilities and backgrounds, fostering inclusivity and equal opportunities for engagement. Accessibility is not a post-launch concern. It shapes interaction patterns, color contrast, keyboard behavior, and copy from the start. We follow WCAG 2.1 AA as a baseline and consider a broad range of users: those navigating by keyboard or screen reader, those on low-bandwidth connections, and those in high-pressure, task-dense work environments like a merchant's back office. See the [Accessibility](https://meteor.shopware.com/documentation/guidelines/accessibility) guidelines for practical implementation guidance. ## Data-informed decision making Leverage data, user research, analytics, and feedback to drive informed design decisions. Embrace the iterative nature of design and be open to evolving quickly with new learnings. Good intent is not enough. We validate assumptions with real usage data, usability sessions, and qualitative feedback. Decisions that cannot be tested should at least be clearly reasoned. When new evidence conflicts with a prior decision, the evidence wins. ## Sticky merchant and shopper experiences Create engaging experiences that foster long-term relationships with users. Focus on seamless onboarding, intuitive interfaces, and powerful tools that drive engagement and conversions. Shopware products are used under commercial pressure. Merchants need to act quickly and confidently; shoppers need a path to purchase that feels effortless. Design should reduce the gap between a user's goal and their ability to achieve it, and reward sustained use with increasing efficiency. ## Reduce friction, aim for simplicity Strive for simplicity and clarity, eliminating unnecessary complexity and reducing friction to create intuitive and efficient interfaces. Minimize distractions and provide empowering UX writing. Simplicity is not the absence of features. It is the absence of unnecessary obstacles. Every field, label, modal, and confirmation step has a cost. We earn complexity only when it serves an explicit user need. When in doubt, cut. ## Streamlined and consistent experiences Deliver streamlined and consistent experiences by utilizing our design system. Reduce cognitive load by maintaining consistency in layouts, design elements, typography, and interactions. Consistency lowers the cost of learning. When the same interaction pattern appears in different parts of the product, users only have to learn it once. When the same visual token is used across components, the interface feels unified without requiring explicit coordination. ## Ethical design practices Uphold ethical design principles: respect user privacy, promote transparency, and avoid manipulative techniques that compromise user trust. Build products that put people and the planet first. Trust is slow to build and fast to lose. We do not use dark patterns, deceptive defaults, or urgency mechanisms that exploit users. We are transparent about what data is collected, how it is used, and what actions are irreversible. We design for the long-term relationship, not the short-term conversion. The [Wording](https://meteor.shopware.com/documentation/content/wording) guidelines cover inclusive language and tone of voice that support these principles in copy. ## How these principles shape Meteor Meteor is not just a component library. It is a set of decisions encoded in code. Every API choice, every default value, every token name reflects at least one of these principles. When you use a Meteor component, you inherit those decisions. When you override them, you take on the responsibility of honoring the same principles in your own implementation. If a design decision ever feels hard to justify, returning to these principles is a reliable starting point. # Accessibility An accessible app means people of all abilities can interact with, understand, and navigate it. At Shopware, we are committed to creating inclusive and barrier-free experiences for our merchants and their customers. Meteor components ship with built-in accessibility features: keyboard support, sensible ARIA usage, and WCAG 2.1 AA compliance. However, you still need to review your patterns, content, and interactions so your app is accessible end-to-end. ## What Meteor provides out of the box - **Keyboard navigation**: All interactive components are fully operable via keyboard - **ARIA attributes**: Components include appropriate roles, states, and properties - **Focus management**: Focus is managed correctly in modals, dropdowns, and other overlays - **Color contrast**: [Design tokens](https://meteor.shopware.com/documentation/design/tokens) meet WCAG 2.1 AA contrast ratios for text and UI elements - **Dark mode**: Both light and dark themes maintain accessible contrast levels - **Screen reader support**: Components are tested with common assistive technologies ## What you still need to consider ### Keep experiences simple Respect people's time by making apps that are easy to use and navigate. - Avoid complex flows where simpler alternatives exist - Use consistent patterns across pages so users don't have to relearn interactions - Use concise, plain language. Aim for a reading level appropriate to your audience ### Be inclusive - Use inclusive language throughout your interface - Don't make assumptions about people's abilities - Avoid jargon, metaphors, and non-literal phrases ### Provide text alternatives Text can be seen, heard via text-to-speech, and touched with a braille reader. - Write clear and concise labels and alt text for all meaningful images and icons - Use the `decorative` prop on [`mt-icon`](https://meteor.shopware.com/components/icon) for purely visual icons so they stay out of the accessibility tree - Include transcripts or captions for any video content ### Never rely on color alone Some people cannot perceive color, and others perceive it differently. - Always pair color with a secondary indicator such as an icon, label, or pattern - Use semantic icon tokens (`critical`, `positive`, `attention`) to reinforce meaning alongside color ### Use semantic HTML Semantic HTML describes the meaning of elements to browsers and assistive technologies. - Use landmark elements (`header`, `nav`, `main`, `footer`) to structure your pages - Avoid using `div` or `span` as interactive elements - Make sure headings follow a logical hierarchy ### Give people control - Ensure your layouts reflow correctly across all screen sizes - Respect the user's reduced motion settings with `prefers-reduced-motion` - Allow sufficient time for time-sensitive interactions ### Test broadly - Test with keyboard-only navigation - Test with screen readers (VoiceOver, NVDA, or JAWS) - Test with real users with disabilities when possible ## Recommended tools - **[WAVE](https://wave.webaim.org/){rel=""nofollow""}**: Visual feedback tool that overlays accessibility information directly on the page. Useful for quickly spotting heading hierarchy and contrast issues. - **[Lighthouse](https://developer.chrome.com/docs/lighthouse/accessibility/){rel=""nofollow""}**: Built into Chrome DevTools. Useful for a quick overall accessibility score as part of a broader performance audit. ## Pre-ship checklist Run through these before shipping any new feature or page: - All interactive elements are reachable and operable by keyboard alone - No keyboard focus traps exist outside of intended modal or overlay patterns - All images and meaningful icons have descriptive labels or alt text - Color is never the only indicator of state or meaning - Text and UI elements meet WCAG 2.1 AA contrast ratios - Heading levels follow a logical hierarchy without skipping levels - Form fields have visible labels connected via `for`/`id` or `aria-labelledby` - Animations and transitions respect `prefers-reduced-motion` # Interactions Every interactive element should communicate clearly whether it can be used, what will happen if it is used, and whether the system has responded. Getting this right reduces hesitation and builds trust in the interface. | State | Token | Description | | -------- | -------------------------------------- | -------------------------------- | | Resting | `--color-interaction-primary-default` | The default, idle state. | | Hover | `--color-interaction-primary-hover` | The pointer is over the element. | | Focus | `--color-border-brand-default` | Keyboard focus outline. | | Pressed | `--color-interaction-primary-pressed` | The element is being activated. | | Disabled | `--color-interaction-primary-disabled` | The element is non-interactive. | ## Input methods Design and test with all four input methods in mind. - **Mouse:** Hover states must appear immediately. Hit areas should be comfortably large. Use `cursor: pointer` to signal interactivity. - **Keyboard:** Every element must be reachable by Tab and operable with Enter or Space. Focus order should follow reading order. Never suppress the focus ring. - **Touch:** Targets must be at least 40x40px. Hover states do not exist; never gate actions or labels behind hover. - **Voice:** Every control needs a meaningful visible label. Icon-only buttons must have an `aria-label` matching what a user would say to activate it. ## Communicating affordance Before a user commits to an action, they need enough information to feel confident doing so. Labels, icons, and placement do most of this work. Interaction states reinforce it. An element at rest should look clickable if it is clickable. Rely on shape, labeling, and context (not just color) to establish this. Hover and focus states then confirm the expectation once the user moves toward the element. Unavailable actions should remain visible but clearly inactive. A disabled state that is invisible or easy to overlook leaves users stuck without knowing why. Where possible, accompany a disabled element with an explanation nearby: a tooltip, helper text, or contextual message. ## Responding to input Once a user acts, the interface should respond immediately. Even if the operation takes time, the system should acknowledge the input right away. - For operations that take time, show a [Loader](https://meteor.shopware.com/components/loader) or [Progress Bar](https://meteor.shopware.com/components/progress-bar) so the user knows work is in progress. - For completed actions that do not require a new page or view, use a [Snackbar](https://meteor.shopware.com/components/snackbar) to confirm the outcome without interrupting the flow. - For failures, explain what went wrong and what the user can do to resolve it. Surface errors close to where the problem occurred rather than in a generic top-level message. ## Critical actions Actions that are destructive or irreversible must be marked clearly so users can make an informed decision before confirming. Use the `critical` variant on components and the corresponding critical color tokens for any action that deletes, removes, or permanently changes data. This applies to the trigger element as well as any confirmation dialog that follows. - Use `--color-interaction-critical-default` and its state variants for interactive controls. - Use `--color-text-critical-*` and `--color-icon-critical-*` tokens for supporting text, icons, and inline warnings. - Always pair a critical action with a confirmation step. Never trigger a destructive operation on a single click. ## Focus ring The focus ring is the primary visual signal for keyboard navigation. It must always be visible. Meteor's standard focus ring: ```css outline: 2px solid var(--color-border-brand-default); outline-offset: 2px; ``` The 2px outline is heavy enough to read against both light and dark surfaces. The 2px offset keeps it visually separate from the element's own border. ### Adjusting the offset The offset is the only thing that should change between contexts. The thickness and color stay the same. If the default 2px offset looks broken or visually wrong in a specific component, adjust it. Higher values give the ring more breathing room; lower values pull it in. Zero offset is acceptable when the element is inside an `overflow: hidden` container and there is no other way to show the ring. ## Tokens For interaction-specific color tokens, see the [Tokens](https://meteor.shopware.com/documentation/design/tokens) page. # Components Consistency is what lets a library of parts feel like one system. The conventions below apply whenever you add a new component or change an existing one. ## Naming and file structure Every component uses the `mt-` prefix and kebab-case. The component name, its folder, and its primary file all share the same name. ```text mt-button/ mt-button.vue mt-button.stories.ts mt-button.interactive.stories.ts mt-button.spec.ts ``` Add `sub-components/` only when the component uses the compound pattern. Add `composables/` when the component extracts logic into composables. Do not create either folder preemptively. ## Props - Props use camelCase. Plural nouns for arrays (`items`), singular for objects (`item`), `num` prefix or `Count`/`Index` suffix for numbers (`numColumns`, `activeIndex`). - Boolean props use plain adjectives with no prefix: `loading`, `open`, `disabled`. Avoid inverted booleans: `showIcon` not `hideIcon`. - Avoid native HTML attribute names. Use `heading` instead of `title`. `disabled`, `required`, and `readonly` are intentional exceptions. - Name props from the component's perspective, not the caller's: `hasSubmitButton` not `hasSubmitPermission`. - Never use `"default"` as a named prop value. Set the default via `defineProps`'s `default` option. - Prefer slots over props for content that may contain markup. Use the standard prop names below consistently. Never substitute alternatives like `type`, `kind`, or `style`. | Prop | Purpose | Values / Type | | ------------- | ------------------------------------------- | ---------------------------------------------------------- | | `variant` | Semantic intent / feedback tone | `neutral` `info` `attention` `critical` `positive` | | `appearance` | Visual hierarchy for interactive components | `primary` `secondary` `tertiary` | | `shape` | Geometric shape variant | `circle` `square` `pill` | | `size` | Dimension | `2xs` `xs` `s` `m` `l` `xl` `2xl` `3xl` | | `width` | Explicit width constraint | `2xs` `xs` `s` `m` `l` `xl` `2xl` `3xl` `full` | | `height` | Explicit height constraint | `2xs` `xs` `s` `m` `l` `xl` `2xl` `3xl` `full` | | `placement` | Floating element anchor position | `top` `bottom` `left` `right` + `-start` / `-end` variants | | `modelValue` | Primary bound value, enables `v-model` | any | | `label` | Visible label for a field or control | string | | `placeholder` | Input placeholder text | string | | `helpText` | Helper text below a field | string | | `name` | Form field name attribute | string | | `heading` | Heading of a card, modal, or section | string | | `subtitle` | Secondary heading below `heading` | string | | `error` | Validation error for a field | `{ code?: number; detail: string }` | | `disabled` | Prevents interaction | boolean | | `required` | Marks a field as required | boolean | | `readonly` | Allows reading but not editing | boolean | | `loading` | Shows a loading state | boolean | | `open` | Controls open/expanded state | boolean | | `closable` | Shows a dismiss / close control | boolean | | `as` | Polymorphic root element override | `string | Component` | ## Slots All slot names use kebab-case without exception. Use logical direction names that are RTL-safe rather than physical ones (`start`/`end` over `left`/`right`). Standard positional slot names: | Slot | Purpose | | -------------- | ------------------------------------------------------------------------------------------ | | `default` | Primary content area. Always provide unless the component has none | | `leading` | Icon or element flanking the component's primary content from the outside | | `trailing` | Icon or element flanking the component's primary content from the outside, on the end side | | `prefix` | Content rendered inside an input field boundary at the start (e.g. currency symbol) | | `suffix` | Content rendered inside an input field boundary at the end (e.g. unit label) | | `header-start` | Left region of a header row | | `header-end` | Right region of a header row | | `trigger` | Element that opens an overlay or compound component. Receives `{ open }` scoped state | | `footer` | Bottom region of a card, modal, or panel | Use scoped slots to expose internal state that consumers may need to react to: ```vue ``` Mark internal-only slots with `@private`: ```vue ``` ## Events Events use kebab-case. Two-way binding follows Vue's `update:propName` pattern. Custom events are verbs or verb-object phrases. Always declare every event in `defineEmits`. Undeclared `$emit` calls are a maintenance hazard and break TypeScript consumers. ```ts const emit = defineEmits<{ "update:modelValue": [value: string]; "update:open": [value: boolean]; "item-activate": [item: Item]; focus: [event: FocusEvent]; blur: [event: FocusEvent]; }>(); ``` Pair every two-way prop with a matching `update:propName` event. Never use a `change` event as a substitute for `update:modelValue`. Never re-emit raw DOM events directly. The one permitted exception is `focus` and `blur` on form field components: consumers need the `FocusEvent` object for custom validation timing and there is no semantic equivalent. ## CSS Classes follow BEM: `mt-{component}__element` for sub-parts and `mt-{component}--modifier` for variants and states. ```css .mt-button { } .mt-button__content { } .mt-button--primary { } .mt-button--disabled { } ``` Always use design tokens for colors, spacing, typography, and border radii. Never hardcode values that a token covers. This ensures components respond correctly to theme changes. ## Compound components Use the compound component pattern when a component requires coordinated sub-parts that consumers may want to compose independently. Sub-components are named `mt-{parent}-{role}`. Shared state lives in a composable under `composables/` and is distributed via `provide`/`inject`. ```text mt-modal/ mt-modal.vue sub-components/ mt-modal-trigger.vue mt-modal-close.vue mt-modal-action.vue composables/ useModalContext.ts ``` Export all public sub-components from the package index alongside the parent. **Do** mt-modal + mt-modal-trigger + mt-modal-action composed by the consumer **Don't** one mt-modal with props: showTrigger, triggerLabel, showCloseButton, footerButtonLabel, ... ## Accessibility Every interactive component must be keyboard-navigable and work with a screen reader out of the box. Use semantic HTML elements as the base. Apply ARIA attributes only when native semantics are insufficient. Form controls must always render a visible, associated label. Loading and disabled states must be communicated via the appropriate HTML attributes (`aria-busy`, `disabled`) so assistive technology can announce them without relying on visual cues alone. For detailed accessibility requirements and patterns, see the [Accessibility](https://meteor.shopware.com/documentation/guidelines/accessibility) page. ## Documentation A component is built and verified in Storybook first, then documented on this site. 1. Ship a `.stories.ts` file with the component and write its tests. Stories cover all significant variants and states, and at least one interactive story exercises the primary user flow. 2. Once the component and its stories are in place, document it on this docs site: add a page with live examples, an API reference, and usage guidance. Follow the [content standard](https://github.com/shopware/meteor/blob/main/apps/docs/DOCS_STANDARD.md){rel=""nofollow""} for the page structure and conventions. ## Component lifecycle Meteor components have one of three lifecycle states: Experimental, Stable, or Deprecated. The state tells consumers how much they can rely on the component's API and behavior. ### Experimental Experimental components are available for early use, but their API and behavior are not stable yet. Use them when they solve your problem, but expect that props, events, slots, visual behavior, or accessibility details may still change. During this stage, we test new ideas and gather feedback. If a component is not useful enough to become Stable, we may remove it in a future release. Breaking changes can happen without notice beforehand. ### Stable Stable components are ready for production use. A component can move to Stable when: - it is covered by automated tests - it uses Meteor Design Tokens - it meets WCAG 2.1 AA requirements - it has documentation and usage examples Breaking changes to Stable components are documented at least one patch version before a major release. ### Deprecated Deprecated components are still available, but should no longer be used for new work. When possible, we provide an alternative and migration guidance. Deprecated components are removed in the next major version. ## Adding new components Meteor does not cover every component every team will ever need. When you hit a gap, follow this process. **1. Build it locally first.** Build the component in your own app. Local implementations ship faster and let you validate the design and API in a real product context before committing to a shared interface. **2. Inform the Meteor team.** Once the component is stable and in use, let the Meteor team know via a GitHub issue or the dedicated Slack channel. Share what the component does, where it is used, and any design decisions you made along the way. **3. The Meteor team evaluates the fit.** The team will assess whether the component belongs in Meteor or should stay local. Not every component needs to be global. Some are too product-specific, too narrow in scope, or not yet stable enough to expose as a shared API. **4. Promotion from local to global.** If the same component surfaces independently across multiple products, that is a strong signal it belongs in Meteor. The team tracks these patterns and will take ownership of the migration when the time is right. Your local implementation becomes the foundation for the global version. # Tokens ## What are tokens A design token captures a single design decision (a color, a spacing step, a font size) as a named value that both design and code reference. Naming raw values this way keeps the UI consistent and maintainable across tools and platforms. ## Token names explained Each part of a token's name specifies one aspect of its use: - **Type**: the broad classification (`color`, `font`, `scale`, `border-radius`). - **Category**: a grouping within the type (`icon`, `text`, `background`, `elevation`). - **Instance**: a usage within the category (`primary`, `positive`, `critical`). - **Variant**: the state (`default`, `hover`, `pressed`, `disabled`). This four-part structure applies to semantic color tokens; others such as `--font-size-s` or `--scale-size-8` use fewer parts because they carry no state. ## Usage See [Installation](https://meteor.shopware.com/documentation/getting-started/installation#tokens) to install the token package and import the theme CSS. ## All tokens ### Interaction | Token | Description | | ---------------------------------------- | -------------------------------------------------------- | | `--color-interaction-primary-default` | Use for resting primary interactive elements. | | `--color-interaction-primary-hover` | Use for hovered primary interactive elements. | | `--color-interaction-primary-pressed` | Use for pressed (active) primary interactive elements. | | `--color-interaction-primary-disabled` | Use for disabled primary interactive elements. | | `--color-interaction-secondary-default` | Use for resting secondary interactive elements. | | `--color-interaction-secondary-hover` | Use for hovered secondary interactive elements. | | `--color-interaction-secondary-pressed` | Use for pressed (active) secondary interactive elements. | | `--color-interaction-secondary-disabled` | Use for disabled secondary interactive elements. | | `--color-interaction-critical-default` | Use for resting critical interactive elements. | | `--color-interaction-critical-hover` | Use for hovered critical interactive elements. | | `--color-interaction-critical-pressed` | Use for pressed (active) critical interactive elements. | | `--color-interaction-critical-disabled` | Use for disabled critical interactive elements. | ### Elevation | Token | Description | | ------------------------------------ | ------------------------------------------------------------------------------------------------------- | | `--color-elevation-surface-sunken` | Use for surfaces of visually sunken elements like highlighted or separated areas within other surfaces. | | `--color-elevation-surface-default` | Use for main application or page backgrounds. | | `--color-elevation-surface-raised` | Use for surfaces of visually raised elements like cards or similar. | | `--color-elevation-backdrop-default` | Use for elements that overlay large portions of the application while a modal or similar is open. | | `--color-elevation-floating-default` | Use for floating elements such as tooltips that require high emphasis against the application colors. | | `--color-elevation-shadow-default` | Use for shadow of elevated elements like modals, popovers or similar. | ### Background | Token | Description | | -------------------------------------- | --------------------------------------------------------------------------- | | `--color-background-primary-default` | Use for background of neutral elements. | | `--color-background-secondary-default` | Use for background of neutral elements. | | `--color-background-tertiary-default` | Use for background of neutral elements or for elements in a disabled state. | | `--color-background-brand-default` | Use for background of elements in an information state. | | `--color-background-critical-default` | Use for background of elements in critical or error states. | | `--color-background-attention-default` | Use for background of elements in attention or warning states. | | `--color-background-positive-default` | Use for background of elements in positive or success states. | | `--color-background-accent-default` | Use for background of elements indicating Shopware’s inheritance behavior. | ### Icon | Token | Description | | --------------------------------- | -------------------------------------------------------------- | | `--color-icon-primary-default` | Use for icons. | | `--color-icon-primary-disabled` | Use for disabled icons. | | `--color-icon-primary-inverse` | Use for icons on inverse backgrounds. | | `--color-icon-secondary-default` | Use for secondary icons. | | `--color-icon-secondary-disabled` | Use for disabled secondary icons. | | `--color-icon-secondary-inverse` | Use for secondary icons on inverse backgrounds. | | `--color-icon-brand-default` | Use for icons indicating an information state. | | `--color-icon-brand-hover` | Use for icons indicating a hovered information state. | | `--color-icon-brand-pressed` | Use for icons indicating a pressed (active) information state. | | `--color-icon-brand-disabled` | Use for icons indicating a disabled information state. | | `--color-icon-critical-default` | Use for icons indicating critical or error states. | | `--color-icon-critical-disabled` | Use for icons indicating disabled, critical or error states. | | `--color-icon-attention-default` | Use for icons indicating attention or warning states. | | `--color-icon-positive-default` | Use for icons indicating positive or success states. | | `--color-icon-accent-default` | Use for icons indicating Shopware’s inheritance behavior. | ### Border | Token | Description | | ---------------------------------- | ------------------------------------------------------------------------------------------------ | | `--color-border-primary-default` | Use for border of elements with high emphasis like secondary buttons, form fields or similar. | | `--color-border-secondary-default` | Use for border of elements with low emphasis like sections dividers, cards, sidebars or similar. | | `--color-border-brand-default` | Use for border of focused, selected or brand-highlighted elements. | | `--color-border-brand-disabled` | Use for border of disabled brand-highlighted elements. | | `--color-border-critical-default` | Use for border of elements in critical or error states. | | `--color-border-critical-disabled` | Use for border of elements in disabled, critical or error states. | | `--color-border-attention-default` | Use for border of elements in attention or warning states. | | `--color-border-positive-default` | Use for border of elements in positive or success states. | | `--color-border-accent-default` | Use for border of elements indicating Shopware’s inheritance behavior. | ### Text | Token | Description | | --------------------------------- | ------------------------------------------------------------------------------- | | `--color-text-primary-default` | Use for high-emphasis text like body copy and headlines. | | `--color-text-primary-disabled` | Use for text indicating disabled states of parent elements. | | `--color-text-primary-inverse` | Use for text on inverse backgrounds. | | `--color-text-secondary-default` | Use for supporting or secondary text content. | | `--color-text-secondary-disabled` | Use for supporting or secondary text content in disabled parent elements. | | `--color-text-secondary-inverse` | Use for secondary text on inverse backgrounds. | | `--color-text-brand-default` | Use for text indicating a link or action. | | `--color-text-brand-hover` | Use for hovered text indicating a link or action. | | `--color-text-brand-pressed` | Use for pressed (active) text indicating a link or action. | | `--color-text-brand-disabled` | Use for disabled text indicating a link or action. | | `--color-text-brand-inverse` | Use for text indicating a link or interaction on inverse backgrounds. | | `--color-text-critical-default` | Use for text indicating critical or error states or an action. | | `--color-text-critical-hover` | Use for hovered text indicating critical or error states or an action. | | `--color-text-critical-pressed` | Use for pressed (active) text indicating critical or error states or an action. | | `--color-text-critical-disabled` | Use for disabled text indicating critical or error states or an action. | | `--color-text-accent-default` | Use for text indicating Shopware’s inheritance behavior. | ### Static | Token | Description | | ---------------------- | --------------------------------------------------------------------- | | `--color-static-white` | Use for elements unaffected by theme changes with white color. | | `--color-static-black` | Use for elements unaffected by theme changes with almost black color. | ### Font Family | Token | Description | | ------------------------ | ------------------ | | `--font-family-headings` | Use for headings. | | `--font-family-body` | Use for body text. | ### Font Size | Token | Description | | ----------------- | ------------------------------------------------------------------------------------ | | `--font-size-2xs` | Use for supporting text content. | | `--font-size-xs` | Use for body copy. | | `--font-size-s` | Use for slightly larger body copy or small headlines. | | `--font-size-m` | Use for headlines separating content sections from each other like cards or similar. | | `--font-size-l` | Use for headlines introducing pages or larger groups of content. | | `--font-size-xl` | Use for headlines in larger marketing elements. | | `--font-size-2xl` | Use for headlines in larger marketing elements. | | `--font-size-3xl` | Use for headlines in larger marketing elements. | ### Font Weight | Token | Description | | ------------------------ | ------------------------------------------- | | `--font-weight-regular` | Use for text with default emphasis. | | `--font-weight-medium` | Use for text with slightly higher emphasis. | | `--font-weight-semibold` | Use for text with high emphasis. | | `--font-weight-bold` | Use for text with highest emphasis. | ### Line Height | Token | Description | | ------------------------ | ------------------------------------------ | | `--font-line-height-2xs` | Use for the line height for text size 2xs. | | `--font-line-height-xs` | Use for the line height for text size xs. | | `--font-line-height-s` | Use for the line height for text size s. | | `--font-line-height-m` | Use for the line height for text size m. | | `--font-line-height-l` | Use for the line height for text size l. | | `--font-line-height-xl` | Use for the line height for text size xl. | | `--font-line-height-2xl` | Use for the line height for text size 2xl. | | `--font-line-height-3xl` | Use for the line height for text size 3xl. | ### Border Radius | Token | Description | | -------------------------- | ---------------------------------------------------------------------- | | `--border-radius-card` | Use for border radius of cards or similar. | | `--border-radius-button` | Use for border radius of buttons or similar. | | `--border-radius-checkbox` | Use for border radius of checkboxes or similar. | | `--border-radius-none` | Use for elements that should not have a border radius applied. | | `--border-radius-2xs` | Use for border radius of extra small elements. | | `--border-radius-xs` | Use for border radius of small elements. | | `--border-radius-s` | Use for border radius of larger elements. | | `--border-radius-m` | Use for border radius of medium sized elements. | | `--border-radius-l` | Use for border radius of large elements. | | `--border-radius-xl` | Use for border radius of extra large elements. | | `--border-radius-2xl` | Use for border radius of extra large elements. | | `--border-radius-3xl` | Use for border radius of extra large elements. | | `--border-radius-4xl` | Use for border radius of extra large elements. | | `--border-radius-round` | Use for border radius of fully rounded elements like pills or similar. | ### Scale | Token | Description | | ------------------- | ----------- | | `--scale-size-0` | | | `--scale-size-1` | | | `--scale-size-2` | | | `--scale-size-4` | | | `--scale-size-6` | | | `--scale-size-8` | | | `--scale-size-10` | | | `--scale-size-12` | | | `--scale-size-14` | | | `--scale-size-16` | | | `--scale-size-18` | | | `--scale-size-20` | | | `--scale-size-22` | | | `--scale-size-24` | | | `--scale-size-26` | | | `--scale-size-28` | | | `--scale-size-30` | | | `--scale-size-32` | | | `--scale-size-36` | | | `--scale-size-40` | | | `--scale-size-48` | | | `--scale-size-56` | | | `--scale-size-64` | | | `--scale-size-72` | | | `--scale-size-80` | | | `--scale-size-96` | | | `--scale-size-128` | | | `--scale-size-160` | | | `--scale-size-192` | | | `--scale-size-224` | | | `--scale-size-256` | | | `--scale-size-9999` | | ## Adding a new token New tokens require sign-off from both design and engineering before they are added. The process is intentionally lightweight but ensures every new token has a clear purpose and fits the existing naming structure. ### Starting a proposal A new token can be initiated from either side. A designer might identify a gap while building a new component in Figma; an engineer might notice a hardcoded value that should be abstracted. Either way, the proposal should be shared with the other discipline before work begins. Use a [GitHub issue](https://github.com/shopware/meteor/issues){rel=""nofollow""}, a Figma comment on the library file, or the Meteor Slack channel to open the discussion. #### What a good proposal includes - What the token represents and where it will be used - The proposed name following the `type-category-instance-variant` structure - The intended value in all available themes - Whether an existing token could cover the need instead ### Review and sign-off Both the design team and the Meteor engineering team review the proposal. The review checks that the name is consistent with existing conventions, that the token is genuinely needed and not a duplicate, and that it works correctly across both themes. ### From Figma to code Once approved, the token is added to the Figma Variables library first. From there it is synced to the token package using the Figma Variables sync workflow. The Meteor team owns the PR that lands the token in the codebase and publishes it in the next release. ## Customizing tokens We recommend against overriding existing Meteor tokens. Overrides can cause unexpected visual divergence from the design system and break when token values change in future releases. If your project needs additional tokens, define new ones with a custom prefix instead. If you do need to override, do so after importing the Meteor token files and scope changes to `[data-theme="dark"]` for theme variants. ```css @import "@shopware-ag/meteor-tokens/administration/light.css"; @import "@shopware-ag/meteor-tokens/administration/dark.css"; /* Add new tokens with a custom prefix */ :root { --myapp-color-brand-default: #7c3aed; --myapp-color-brand-hover: #6d28d9; } [data-theme="dark"] { --myapp-color-brand-default: #8b5cf6; --myapp-color-brand-hover: #7c3aed; } ``` # Color Palette Every color in Meteor starts here. The palette is the raw material that [Tokens](https://meteor.shopware.com/documentation/design/tokens) draw from to apply usage and meaning in components and layouts. ## Naming convention Each palette color is identified by its hue name and a numeric shade. The number represents luminosity on a scale from 50 (lightest) to 950 (darkest). For example, `color-blue-500` is the mid-range blue, while `color-blue-50` is a near-white tint and `color-blue-950` is near-black. This naming convention makes the scale predictable: a higher number is always darker, a lower number is always lighter, regardless of hue. ## How to use Palette values have no semantic meaning on their own. They are the toolbox designers use to define semantic tokens and build themes. Tokens carry intent (such as "primary action" or "destructive state") and adapt correctly across different themes. Reaching for a raw palette value skips that layer of meaning and breaks theming. ::warning The primitive palette is not a stable API: the number of colors and their values can change at any time, outside the usual major-version, deprecation, and breaking-change process. Styling components or interfaces with palette values directly is at your own risk; use Meteor's semantic tokens in product code instead. :: ### Slate | Name | Token | Value | | ---- | ------------------- | --------- | | 50 | `--color-slate-50` | `#fafbfe` | | 100 | `--color-slate-100` | `#f0f3ff` | | 200 | `--color-slate-200` | `#e0e3f3` | | 300 | `--color-slate-300` | `#cbcede` | | 400 | `--color-slate-400` | `#b6b9c9` | | 500 | `--color-slate-500` | `#a3a6b5` | | 600 | `--color-slate-600` | `#808392` | | 700 | `--color-slate-700` | `#666977` | | 800 | `--color-slate-800` | `#474a57` | | 900 | `--color-slate-900` | `#2b2e3a` | | 950 | `--color-slate-950` | `#12141e` | ### Blue | Name | Token | Value | | ---- | ------------------ | --------- | | 50 | `--color-blue-50` | `#eef6ff` | | 100 | `--color-blue-100` | `#cce5ff` | | 200 | `--color-blue-200` | `#a8d4ff` | | 300 | `--color-blue-300` | `#83c3ff` | | 400 | `--color-blue-400` | `#59b1ff` | | 500 | `--color-blue-500` | `#189eff` | | 600 | `--color-blue-600` | `#0081d4` | | 700 | `--color-blue-700` | `#005b99` | | 800 | `--color-blue-800` | `#00375f` | | 900 | `--color-blue-900` | `#001931` | ### Yellow | Name | Token | Value | | ---- | -------------------- | --------- | | 50 | `--color-yellow-50` | `#fffef7` | | 100 | `--color-yellow-100` | `#fff7d6` | | 200 | `--color-yellow-200` | `#ffefb3` | | 300 | `--color-yellow-300` | `#ffe88e` | | 400 | `--color-yellow-400` | `#ffe061` | | 500 | `--color-yellow-500` | `#ffd702` | | 600 | `--color-yellow-600` | `#cdac00` | | 700 | `--color-yellow-700` | `#8d7600` | | 800 | `--color-yellow-800` | `#4f4100` | | 900 | `--color-yellow-900` | `#1e1800` | ### Pumpkin | Name | Token | Value | | ---- | --------------------- | --------- | | 50 | `--color-pumpkin-50` | `#fff2ec` | | 100 | `--color-pumpkin-100` | `#ffddcc` | | 200 | `--color-pumpkin-200` | `#ffc7aa` | | 300 | `--color-pumpkin-300` | `#ffb086` | | 400 | `--color-pumpkin-400` | `#ff985e` | | 500 | `--color-pumpkin-500` | `#f88138` | | 600 | `--color-pumpkin-600` | `#d46000` | | 700 | `--color-pumpkin-700` | `#974200` | | 800 | `--color-pumpkin-800` | `#5c2600` | | 900 | `--color-pumpkin-900` | `#2c0e00` | ### Pink | Name | Token | Value | | ---- | ------------------ | --------- | | 50 | `--color-pink-50` | `#fff1f5` | | 100 | `--color-pink-100` | `#ffd8e4` | | 200 | `--color-pink-200` | `#ffbed3` | | 300 | `--color-pink-300` | `#ffa2c2` | | 400 | `--color-pink-400` | `#ff83b1` | | 500 | `--color-pink-500` | `#ff5ea1` | | 600 | `--color-pink-600` | `#e42683` | | 700 | `--color-pink-700` | `#a8005c` | | 800 | `--color-pink-800` | `#670036` | | 900 | `--color-pink-900` | `#340018` | ### Purple | Name | Token | Value | | ---- | -------------------- | --------- | | 50 | `--color-purple-50` | `#f5f4ff` | | 100 | `--color-purple-100` | `#e4e1ff` | | 200 | `--color-purple-200` | `#d4ceff` | | 300 | `--color-purple-300` | `#c4bbff` | | 400 | `--color-purple-400` | `#b5a8ff` | | 500 | `--color-purple-500` | `#a694ff` | | 600 | `--color-purple-600` | `#886fe9` | | 700 | `--color-purple-700` | `#633bc6` | | 800 | `--color-purple-800` | `#3e0091` | | 900 | `--color-purple-900` | `#1c0049` | ### Emerald | Name | Token | Value | | ---- | --------------------- | --------- | | 50 | `--color-emerald-50` | `#ddffea` | | 100 | `--color-emerald-100` | `#aeffd0` | | 200 | `--color-emerald-200` | `#80fbba` | | 300 | `--color-emerald-300` | `#74f0af` | | 400 | `--color-emerald-400` | `#67e4a4` | | 500 | `--color-emerald-500` | `#57d998` | | 600 | `--color-emerald-600` | `#00b472` | | 700 | `--color-emerald-700` | `#007e4e` | | 800 | `--color-emerald-800` | `#00492b` | | 900 | `--color-emerald-900` | `#001f0f` | ### Zinc | Name | Token | Value | | ---- | ------------------- | --------- | | 0 | `--color-zinc-0` | `#ffffff` | | 50 | `--color-zinc-50` | `#fafbfe` | | 75 | `--color-zinc-75` | `#f2f3f8` | | 100 | `--color-zinc-100` | `#e2e3e9` | | 200 | `--color-zinc-200` | `#cdced4` | | 300 | `--color-zinc-300` | `#b9babf` | | 400 | `--color-zinc-400` | `#a5a6ab` | | 500 | `--color-zinc-500` | `#838489` | | 600 | `--color-zinc-600` | `#696a6e` | | 700 | `--color-zinc-700` | `#3d3e42` | | 800 | `--color-zinc-800` | `#2d2e32` | | 850 | `--color-zinc-850` | `#26262b` | | 900 | `--color-zinc-900` | `#1e1e24` | | 950 | `--color-zinc-950` | `#141418` | | 975 | `--color-zinc-975` | `#101013` | | 1000 | `--color-zinc-1000` | `#09090b` | ### Orange | Name | Token | Value | | ---- | -------------------- | --------- | | 50 | `--color-orange-50` | `#fff3e3` | | 100 | `--color-orange-100` | `#ffe6c4` | | 200 | `--color-orange-200` | `#ffd9a2` | | 300 | `--color-orange-300` | `#ffcb7e` | | 400 | `--color-orange-400` | `#ffbc51` | | 500 | `--color-orange-500` | `#fbaf18` | | 600 | `--color-orange-600` | `#cc8c00` | | 700 | `--color-orange-700` | `#8f6000` | | 800 | `--color-orange-800` | `#533600` | | 900 | `--color-orange-900` | `#241500` | ### Green | Name | Token | Value | | ---- | ------------------- | --------- | | 50 | `--color-green-50` | `#e1ffe0` | | 100 | `--color-green-100` | `#b0fbb0` | | 200 | `--color-green-200` | `#86f98c` | | 300 | `--color-green-300` | `#73f27a` | | 400 | `--color-green-400` | `#4dde58` | | 500 | `--color-green-500` | `#36d046` | | 600 | `--color-green-600` | `#00ab26` | | 700 | `--color-green-700` | `#007818` | | 800 | `--color-green-800` | `#00470a` | | 900 | `--color-green-900` | `#002002` | ### Red | Name | Token | Value | | ---- | ----------------- | --------- | | 50 | `--color-red-50` | `#fff2f0` | | 100 | `--color-red-100` | `#ffcfc9` | | 200 | `--color-red-200` | `#ffa9a0` | | 300 | `--color-red-300` | `#ff7f74` | | 400 | `--color-red-400` | `#fc4945` | | 500 | `--color-red-500` | `#e2262a` | | 600 | `--color-red-600` | `#c20017` | | 700 | `--color-red-700` | `#90000e` | | 800 | `--color-red-800` | `#5e0006` | | 900 | `--color-red-900` | `#360002` | ### Brand | Name | Token | Value | | ---- | ------------------- | --------- | | 50 | `--color-brand-50` | `#f0f6ff` | | 100 | `--color-brand-100` | `#c8ddff` | | 200 | `--color-brand-200` | `#9fc4ff` | | 300 | `--color-brand-300` | `#76aaff` | | 400 | `--color-brand-400` | `#4a8fff` | | 500 | `--color-brand-500` | `#0870ff` | | 600 | `--color-brand-600` | `#005cd7` | | 700 | `--color-brand-700` | `#0042a0` | | 800 | `--color-brand-800` | `#00296a` | | 900 | `--color-brand-900` | `#00153e` | | 950 | `--color-brand-950` | `#000c2b` | ### Cyan | Name | Token | Value | | ---- | ------------------ | --------- | | 50 | `--color-cyan-50` | `#e8f8ff` | | 100 | `--color-cyan-100` | `#c3eeff` | | 200 | `--color-cyan-200` | `#9ce4ff` | | 300 | `--color-cyan-300` | `#79dbff` | | 400 | `--color-cyan-400` | `#4ad0fc` | | 500 | `--color-cyan-500` | `#2fc3f0` | | 600 | `--color-cyan-600` | `#009ac0` | | 700 | `--color-cyan-700` | `#006c88` | | 800 | `--color-cyan-800` | `#004051` | | 900 | `--color-cyan-900` | `#001c26` | # Elevation | Surface | Token | Description | | ------- | ----------------------------------- | ------------------------------------------------------------------------------ | | Sunken | `--color-elevation-surface-sunken` | Recessed areas such as wells and inset panels that sit below the base surface. | | Default | `--color-elevation-surface-default` | The base surface for page and panel backgrounds. | | Raised | `--color-elevation-surface-raised` | Elements lifted above the base, such as cards, popovers, and dropdowns. | Surfaces that sit closer to the user should feel closer. Meteor handles this with elevation tokens that map directly to layers in the visual stack, rather than arbitrary background colors. Using them consistently keeps surfaces related correctly across both light and dark mode without any extra work. ## Surface tokens Three tokens cover the vast majority of UI surfaces: | Token | Description | | ----------------------------------- | ------------------------------------------------------------------------------------------------------- | | `--color-elevation-surface-sunken` | Use for surfaces of visually sunken elements like highlighted or separated areas within other surfaces. | | `--color-elevation-surface-default` | Use for main application or page backgrounds. | | `--color-elevation-surface-raised` | Use for surfaces of visually raised elements like cards or similar. | **Do** Use elevation surface tokens for large scale app surfaces to include the correct elevation system with theming. **Don't** Use background colors and hard coded values for large scale surfaces. ## Special-purpose tokens | Token | Description | | ------------------------------------ | ----------------------------------------------------------------------------------------------------- | | `--color-elevation-backdrop-default` | Use for elements that overlay large portions of the application while a modal or similar is open. | | `--color-elevation-floating-default` | Use for floating elements such as tooltips that require high emphasis against the application colors. | | `--color-elevation-shadow-default` | Use for shadow of elevated elements like modals, popovers or similar. | # Spacing Spacing decisions made ad hoc accumulate into visual inconsistency. When every component picks its own padding and gap values, the UI becomes uneven in ways that are hard to diagnose and fix systematically. A fixed scale solves this by constraining choices to a shared set of values. Components that use the same scale step naturally feel related. Layouts built from scale-aligned components align with each other without manual correction. And when spacing needs to change globally, updating a token propagates everywhere at once. Meteor's scale is numeric: every token name reflects its value in pixels, so `--scale-size-8` is 8px. There is no semantic indirection to memorize. ## Scale reference | Token | Description | | ------------------- | ----------- | | `--scale-size-0` | | | `--scale-size-1` | | | `--scale-size-2` | | | `--scale-size-4` | | | `--scale-size-6` | | | `--scale-size-8` | | | `--scale-size-10` | | | `--scale-size-12` | | | `--scale-size-14` | | | `--scale-size-16` | | | `--scale-size-18` | | | `--scale-size-20` | | | `--scale-size-22` | | | `--scale-size-24` | | | `--scale-size-26` | | | `--scale-size-28` | | | `--scale-size-30` | | | `--scale-size-32` | | | `--scale-size-36` | | | `--scale-size-40` | | | `--scale-size-48` | | | `--scale-size-56` | | | `--scale-size-64` | | | `--scale-size-72` | | | `--scale-size-80` | | | `--scale-size-96` | | | `--scale-size-128` | | | `--scale-size-160` | | | `--scale-size-192` | | | `--scale-size-224` | | | `--scale-size-256` | | | `--scale-size-9999` | | ## Choosing a step As a starting point: - **4-8px** for tight internal spacing within a component, such as an icon-to-label gap or badge padding - **12-16px** for standard component padding and item spacing - **24-40px** for spacing between form elements and section separation within a view - **48-64px** for separation between major layout regions Consistency matters more than the exact value. Prefer reusing an existing step over introducing a one-off intermediate value. **Do** - Use scale tokens for all spacing: padding, margin, and gap. - Reuse the closest scale step when the ideal value falls between two tokens. - Use calc(var(--scale-size-8) \* -1) to negate a token when a negative offset is needed. - Use border-radius tokens (--border-radius-\*) for corner radii. **Don't** - Use arbitrary px or rem values that fall outside the scale. - Introduce one-off spacing values to achieve pixel-perfect designs. - Hardcode a negative px value like margin-top: -8px. - Use scale tokens for border-radius. They serve different purposes and are separately maintained. # Border Radius Border radius decisions made ad hoc produce interfaces where similar elements have subtly different shapes, making the UI feel unpolished without an obvious cause. Meteor provides two layers of border radius tokens: semantic tokens for general use, and element-scoped tokens that encode the correct radius for specific component types. Always prefer an element-scoped token when one exists for your use case. Fall back to semantic tokens when no element-scoped token applies. ## Element-scoped tokens Element-scoped tokens encode the right radius for specific element types. Use these before reaching for a semantic token. | Token | Description | | -------------------------- | ----------------------------------------------- | | `--border-radius-card` | Use for border radius of cards or similar. | | `--border-radius-button` | Use for border radius of buttons or similar. | | `--border-radius-checkbox` | Use for border radius of checkboxes or similar. | ## Semantic tokens Use semantic tokens when no element-scoped token fits your element. | Token | Description | | ----------------------- | ---------------------------------------------------------------------- | | `--border-radius-none` | Use for elements that should not have a border radius applied. | | `--border-radius-2xs` | Use for border radius of extra small elements. | | `--border-radius-xs` | Use for border radius of small elements. | | `--border-radius-s` | Use for border radius of larger elements. | | `--border-radius-m` | Use for border radius of medium sized elements. | | `--border-radius-l` | Use for border radius of large elements. | | `--border-radius-xl` | Use for border radius of extra large elements. | | `--border-radius-2xl` | Use for border radius of extra large elements. | | `--border-radius-3xl` | Use for border radius of extra large elements. | | `--border-radius-4xl` | Use for border radius of extra large elements. | | `--border-radius-round` | Use for border radius of fully rounded elements like pills or similar. | ## Usage **Do** - Use --border-radius-round for pill badges, avatar circles, and fully rounded tags. - Use border-radius tokens for corner radii. **Don't** - Use a large arbitrary value like border-radius: 999px or 50%. - Use scale tokens (--scale-size-\*) for border-radius. Using scale directly removes the semantic layer and doesn't allow for theming or updates on border radius tokens. # Typography One typeface, applied consistently, carries a product's voice further than any single style choice. Everything here is available as CSS custom properties and via the [Text](https://meteor.shopware.com/components/text) component. ## Font family | Token | Description | | ------------------------ | ------------------ | | `--font-family-headings` | Use for headings. | | `--font-family-body` | Use for body text. | Inter is loaded via `@shopware-ag/meteor-component-library/font.css`. Import this stylesheet to ensure the font is available. If you manage fonts independently, make sure Inter is available under the name `Inter`. ## Size Meteor uses a named scale from `2xs` to `3xl`. Always pair a `--font-size-*` token with its matching `--font-line-height-*` token; the line heights are tuned to each step. | Token | Description | | ----------------- | ------------------------------------------------------------------------------------ | | `--font-size-2xs` | Use for supporting text content. | | `--font-size-xs` | Use for body copy. | | `--font-size-s` | Use for slightly larger body copy or small headlines. | | `--font-size-m` | Use for headlines separating content sections from each other like cards or similar. | | `--font-size-l` | Use for headlines introducing pages or larger groups of content. | | `--font-size-xl` | Use for headlines in larger marketing elements. | | `--font-size-2xl` | Use for headlines in larger marketing elements. | | `--font-size-3xl` | Use for headlines in larger marketing elements. | ## Weight Reserve `--font-weight-semibold` and `--font-weight-bold` for headings, labels, and key emphasis. Body copy should be `--font-weight-regular`. | Token | Description | | ------------------------ | ------------------------------------------- | | `--font-weight-regular` | Use for text with default emphasis. | | `--font-weight-medium` | Use for text with slightly higher emphasis. | | `--font-weight-semibold` | Use for text with high emphasis. | | `--font-weight-bold` | Use for text with highest emphasis. | ## Hierarchy Create hierarchy through size and weight, not decoration. A clear hierarchy guides the reader's eye without requiring color or additional visual treatments. - Use one prominent size per section. Combining multiple large sizes on a single screen competes for attention rather than directing it. - Increase weight before increasing size. Stepping up from `regular` to `semibold` at the same size creates sufficient contrast for labels, headings, and interactive elements. - Reserve `3xl` and `2xl` for page-level titles and major section headers. Use `xl` and `l` for subsections. Use `m` and `s` for card and section headlines. Use `xs` for body copy, supporting labels, and metadata. - Secondary information should use `--color-text-secondary-default`, not a smaller size. Reducing size too aggressively harms legibility. ## Line length Keep body copy between 60 and 80 characters per line. Use `max-width: 65ch` on the container to enforce this. This does not apply to labels or UI strings. ## Usage To render text, prefer the [Text](https://meteor.shopware.com/components/text) component over applying these tokens directly. It maps the size, weight, and color tokens to props and pairs each size with the correct line height automatically. See its page for the full API and examples. **Do** - Use font-size and line-height tokens together from the same scale step. - Use --font-weight-semibold or --font-weight-bold only for headings and labels. **Don't** - Mix a token font-size with a hardcoded line-height, or use raw px values. - Apply bold weight to long-form body text. It reduces readability. ## Accessibility - Ensure sufficient contrast between text and background. Use `--color-text-primary-default` on `--color-elevation-surface-default` as your baseline. - Do not set font sizes below `--font-size-2xs` (12px). Below this threshold legibility degrades significantly. - Avoid setting `line-height` below 1.4 for body copy. The token line heights already meet this. For broader accessibility guidance, including contrast requirements, see the [Accessibility](https://meteor.shopware.com/documentation/guidelines/accessibility) page. # Icons Meteor icons follow a minimal, expressive style aligned with Shopware's product language. For technical usage, see the [Icon component](https://meteor.shopware.com/components/icon) documentation. ## Philosophy Icons in Meteor are functional first. They exist to support actions, communicate state, and aid navigation. Not to decorate. Every icon in the kit serves a clear interface purpose. The style is intentionally restrained: consistent stroke weights, unified corner radii, and optical sizing that keeps icons readable at small sizes. This restraint makes the set cohesive and ensures icons never compete with the content they support. ## All icons Meteor ships a full set of UI icons in regular and solid styles, each available through the MtIcon component. Use the interactive browser on this page to search icons by name and copy their token. ## Common usages These examples demonstrate typical icon usage in the Shopware Administration and other Shopware products that use Meteor, where each icon has a clearly defined meaning. | Icon | Usage | | ----------------------- | ----------------------- | | `tachometer` | Dashboard | | `home` | Home | | `products` | Products | | `variants` | Product Variants | | `barcode` | SKU / Barcode | | `crossselling` | Cross-selling | | `shopping-bag` | Orders | | `users` | Customers | | `content` | Content | | `megaphone` | Marketing | | `plug` | Extensions | | `cog` | Settings | | `storefront` | Sales Channels | | `briefcase` | B2B Components | | `shopping-cart` | Shopping cart | | `heart` | Wishlist | | `search` | Search | | `filter` | Filter | | `sort` | Sort | | `bulk-edit` | Bulk edit | | `eye` | Preview | | `sign-in` | Login/Signup | | `sign-out` | Logout | | `database` | Import/Export | | `download` | Download / Export | | `upload` | Upload / Import | | `rule` | Rule Builder | | `flow` | Flow Builder | | `sitemap` | Categories | | `image` | Media | | `folder` | Folder | | `file-text` | Documents | | `tag` | Tags | | `archive` | Archive | | `calendar` | Date | | `clock` | Scheduled / Pending | | `history` | History | | `link` | Link | | `credit-card` | Payment methods | | `discount` | Promotions / Discounts | | `truck` | Shipping | | `inventory` | Stock / Inventory | | `warehouse` | Warehouse | | `analytics` | Analytics | | `user` | Users | | `key` | API Key / Credentials | | `tools-alt` | Maintenance | | `server` | Server / Infrastructure | | `plans` | Shopware Plans | | `shopware-nexus` | Shopware Nexus | | `shopware-payments` | Shopware Payments | | `shopware-intelligence` | Shopware Intelligence | | `check-circle` | Success | | `exclamation-circle` | Error | | `exclamation-triangle` | Warning | | `info-circle` | Info | | `bell` | Notifications | | `chevron-left` | Back / Previous | | `chevron-right` | Forward / Next | | `external-link` | Open in new tab | | `plus` | Add / Create | | `pencil-s` | Edit | | `minus` | Remove | | `trash` | Delete | | `duplicate` | Duplicate | | `copy` | Copy | | `times` | Close | ## Regular and solid variants Most icons come in two variants. Use them consistently within similar contexts. Mixing variants arbitrarily inside the same control group creates visual inconsistency. **Regular** is the default for standard interface actions and supporting UI. Use it for navigation, actions, and inline indicators. **Solid** works better for very small sizes and for larger decorative or prominent icon placements where a heavier fill reads better. ```vue ``` ## Sizing Meteor icons are designed for a small set of sizes. Staying within this set keeps the UI consistent across screens. - **24px**: Standalone icons, empty states, prominent surfaces - **20px**: Standard actions, headers, supporting icons in regular-density UI - **16px**: Inline controls, field affordances, compact supporting UI - **14px or smaller**: Dense UI only, where the icon is clearly secondary ```vue ``` **Do** Use 24px, 20px, and 16px for the vast majority of icons. Reserve smaller sizes for genuinely dense UI. **Don't** Use arbitrary sizes. The common size set keeps the interface visually consistent. ## Color Always use semantic icon tokens so they adapt correctly to light and dark themes and to interactive states. - `--color-icon-primary-default` for the standard icon color - `--color-icon-secondary-default` when the icon should attract less attention than surrounding content - Semantic variants such as `brand`, `attention`, `critical`, `positive`, or `accent` when the icon color carries a contextual meaning See the [Tokens](https://meteor.shopware.com/documentation/design/tokens) page for the full list of available icon color tokens. ```vue ``` **Do** Use icon color tokens so icons respond to theme changes and state transitions automatically. **Don't** Hardcode hex values for icon color. They will break in dark mode and won't reflect interactive states. ## Icons and meaning Icons rarely stand alone. Pair them with a visible label or place them inside a control that already communicates its purpose. When an icon does carry meaning on its own (a close button, a status indicator), make sure that meaning is also available through visible text or an accessible label on the parent control. **Do** Support icons with nearby text or an existing control label. **Don't** Rely on an icon alone to communicate a critical action or state. Color and shape alone are not sufficient. ## Adding icons to the kit New icons require sign-off from both design and engineering before they are added. The process ensures every new icon is genuinely needed, fits the visual style, and arrives in the codebase ready to use. ### Starting the work New icons always start in Figma. The designer draws the icon and adds it to the Meteor icon library file before any code is written. This keeps the source of truth in design and makes the review step natural: reviewers can see the icon in context alongside the rest of the set. Open the discussion early by sharing the Figma frame in the Meteor Slack channel, leaving a comment on the icon library file, or opening a GitHub issue. Early visibility prevents duplicate work and gives engineering a chance to flag any technical constraints before design is finalized. ### What to cover in the proposal - What the icon represents and the interface contexts where it will appear - Whether a regular variant, a solid variant, or both are needed - Whether an existing icon could cover the need with a different usage convention ### Naming Icons follow the `regular-name` and `solid-name` prefix convention. The name after the prefix should describe what the icon depicts, not where it is used. Keep names short, lowercase, and hyphenated. ### Review and sign-off Both the design team and the Meteor engineering team review the proposal. The review checks that the new icon is consistent with the existing visual style, that it is not a duplicate of something already in the kit, and that the name follows the naming convention. ### From Figma to code Once approved, the icon lives in the Figma library. From there a custom sync script exports the icon assets and packages them into the icon kit. The Meteor team owns the PR that lands the icon in the codebase and publishes it in the next release. # Wording At Shopware, tone of voice plays a central role in our brand identity. Through a consistent and authentic tone, we aim to resonate with our users, establish trust, and create memorable experiences that reflect our commitment to innovation, reliability, and customer-centricity. ## Writing goals **Empower**: Help people understand Shopware by using language that informs them and encourages them to make the most of our products. **Respect**: Treat readers with the respect they deserve. Put yourself in their shoes and don't patronize them. Be considerate and inclusive. **Educate**: Tell readers what they need to know, not just what we want to say. Give them the exact information they need, along with opportunities to learn more. **Engage**: Write to engage the reader, capturing their interest with relevant content and a conversational tone. ## Our approach **Clear**: Understand the topic you're writing about. Use simple words and sentences. **Useful**: Before you start writing, ask yourself: What purpose does this serve? Who is going to read it? What do they need to know? **Friendly**: Write like a human. All of our content, from website copy to system alerts, should be warm and human. **Appropriate**: Adapt your tone depending on who you're writing to and what you're writing about. ## Active voice You should (almost) always write in the active voice. In active voice, the subject does the action. In passive voice, the action is done to the subject. **Do** - Jennifer logged into the account - The customer placed the order **Don't** - The account was logged into by Jennifer - The order was placed by the customer > **Tip:** Words like "was" and "by" often indicate passive voice. Scan for these and rework sentences where they appear. When to use passive voice: - To avoid referring to yourself or Shopware, for example, "Invoices are created monthly and emailed to you" avoids an unnecessary Shopware subject - To make it clear you didn't personally take an action - When the object is more important than the subject ## Inclusive language We champion **people-first language**: keep the individual as the most important part of the sentiment and don't concentrate on characteristics like gender, sexual orientation, religion, or ability unless it's relevant. ### Race and ethnicity **Do** - "allowlist" and "blocklist" - "main", "primary" **Don't** - "whitelist" and "blacklist" - "master" ### Gender **Do** - "they" - "people", "folks", "teammates" - Neutral, straightforward titles - "workforce" **Don't** - "him" or "her", "he" or "she" - "guys" - "ninja", "rockstar", "wizard" - "manpower" ### Sexual orientation and gender identity **Do** "spouse" or "partner" **Don't** "wife/husband" or "girlfriend/boyfriend" ## Abbreviations and acronyms **Write in plain language.** If there's a chance your reader won't recognize an abbreviation or acronym, spell it out the first time you mention it. Then use the short version for all other references. > **Tip:** If the abbreviation is well known (like API or HTML), use it directly without spelling it out. **Do** Your store now supports cross-border payments through the Open Banking protocol. **Don't** Your store now supports cross-border payments through OBP. ## Capitalisation Shopware feature names are capitalised in every context. They need to stand out whenever they are mentioned. Examples: Rule Builder, Sales Channel, Flow Builder, B2B Components. Capital letters are used at the beginning of every sentence. Subsequent words within a sentence are generally not capitalised unless they are proper nouns or feature names. ## Buttons Button labels should be as short as possible. Use a verb that describes the action. **Do** Save **Don't** Click here to save If the context alone does not make the action clear, add a noun and, if necessary, a preposition. **Do** - Save product - Continue to checkout **Don't** - Save the product - Continue to the checkout Do not use articles. ## Addressing users In English, use "you" and "your" for all audiences. In German, use the informal address for users. In the Shopware Admin, Du, Dich, Dir, and Dein are capitalised as a sign of respect, even though standard German grammar does not require it. Example: Speichere das Produkt, bevor Du die Seite verlässt. ## Glossary For a full reference of approved English and German terms, see the [Glossary](https://meteor.shopware.com/documentation/content/glossary) page. # Messaging Good messages tell users what happened, why it matters, and what to do next. Every message in products using Meteor should be clear, honest, and respectful of the user's time. ## Error messages Error messages appear after something has gone wrong. Tell users what failed and how to recover, not to apologise or assign blame. Lead with the most likely fix. Avoid "sorry", "please", and softeners like "oops": they trivialise real problems and undermine trust. **Do** - Product could not be saved. Check your connection and try again. - Import failed. The file format is not supported. Use CSV or XLSX. **Don't** - Error: An error occurred while attempting to save the product. Please try again. - Something went wrong with your import. ## Form validation Validation messages appear inline, next to the field that failed. They are the most-read copy in any form, so precision matters. Write validation messages that tell the user what went wrong and what to do about it. Avoid blaming the user or restating what the label already says. **Do** - Enter a valid email address. - Password must be at least 8 characters. **Don't** - Invalid email. - Password is too short. For `helpText` (the supporting text shown below a field before any error), explain the constraint upfront so users do not encounter a validation error in the first place. **Do** Must be at least 8 characters and include a number. **Don't** Enter your password. ## Success messages Success messages confirm that an action completed. Confirm the outcome and get out of the way. Avoid exclamation marks and "Success!" as a label. Reserve stronger celebration for significant milestones, not routine actions. **Do** - Product saved. - Order cancelled. The customer will be refunded within 5 business days. **Don't** - Success! The product has been successfully saved. - Your order has been cancelled successfully. ## Warning messages Warning messages appear before a risky or irreversible action. They prepare users, not punish them. Be specific about what will happen and whether it can be undone. Stay calm: avoid exclamation marks and "Warning:" prefixes. **Do** - Unsaved changes will be lost if you leave this page. - This product will be removed from all associated Sales Channels and cannot be restored. **Don't** - Warning: You have unsaved changes! - Are you sure you want to delete this product? ## Info messages Info messages provide context that helps users understand the current state. They do not require action and should not interrupt the workflow. Get to the point and stop: do not pad with filler phrases. **Do** Prices are shown excluding VAT. Switch to gross display in your settings. **Don't** Please note that for your information, prices on this page are currently being displayed without VAT applied. ## Empty states Use the [Empty State](https://meteor.shopware.com/components/empty-state) component wherever possible. Empty states appear when a list, table, or section has no content yet. There are two distinct situations: - **Blank slate:** the user has not yet added anything. Introduce the feature and prompt the first action. - **Cleared state:** the user completed a task or filtered out all results. Acknowledge the outcome and suggest what to do next. Write the heading as a direct observation, not an apology. Tell users what they can do from here. **Do** - No products yet. Add your first product to start selling. - No results for 'blue shirt'. Try a different search term or clear your filters. **Don't** - Unfortunately, there are no products to display at this time. - Your search returned no results. ## Loading states Loading messages should be brief. The user already knows the app is working. Use a label only when it adds context about what is happening. For generic operations, no label is better than a vague one. **Do** - Loading products... - Importing orders... **Don't** - Please wait while we load your data. This may take a moment. - Loading... # Glossary Use these terms consistently across all English and German copy. When a term appears here, always use this spelling and capitalisation. Do not invent alternatives. ## Products and features | English | German | | ------------------------- | ------------------------- | | 3D & AR Commerce | 3D & AR Commerce | | AI | KI | | AI Copilot | AI Copilot | | B2B Components | B2B Components | | Community Edition | Community Edition | | Custom fields | Zusatzfelder | | Customer groups | Kundengruppen | | Digital Sales Rooms | Digital Sales Rooms | | Dynamic product groups | Dynamische Produktgruppen | | Email templates | E-Mail-Templates | | Essential characteristics | Wesentliche Merkmale | | Extensions | Erweiterungen | | Flow Builder | Flow Builder | | Import / Export | Import/Export | | Integrations | Integrationen | | Language pack | Sprachpaket | | Measurement system | Maßeinheitensystem | | Migration Assistant | Migrations-Assistent | | Number ranges | Nummernkreise | | Payment methods | Zahlungsarten | | Promotion | Rabattaktion | | Rule Builder | Rule Builder | | Sales Channel | Verkaufskanal | | Salutations | Anreden | | Scale units | Produkteinheiten | | Shipping methods | Versandarten | | Shopping Experiences | Erlebniswelten | | Shopware Account | Shopware Account | | Shopware Admin | Shopware Admin | | Shopware Administration | Shopware Administration | | Shopware Analytics | Shopware Analytics | | Shopware Beyond | Shopware Beyond | | Shopware Evolve | Shopware Evolve | | Shopware Intelligence | Shopware Intelligence | | Shopware Nexus | Shopware Nexus | | Shopware PaaS | Shopware PaaS | | Shopware Payments | Shopware Payments | | Shopware Plans | Shopware Pläne | | Shopware Rise | Shopware Rise | | Shopware Services | Shopware Services | | Snippets | Textbausteine | | Spatial Commerce | Spatial Commerce | | Subscriptions | Abonnements | | Tax | Steuern | | Users & permissions | Benutzer & Rechte | ## User interface | English | German | | ---------- | ---------------- | | Activate | Aktivieren | | Add | Hinzufügen | | Apply | Übernehmen | | Archive | Archivieren | | Back | Zurück | | Cancel | Abbrechen | | Close | Schließen | | Confirm | Bestätigen | | Continue | Fortfahren | | Create | Erstellen | | Deactivate | Deaktivieren | | Delete | Löschen | | Discard | Verwerfen | | Download | Herunterladen | | Duplicate | Duplizieren | | Edit | Bearbeiten | | Filter | Filtern | | Filters | Filter | | Learn more | Mehr erfahren | | Log in | Anmelden | | Login | Anmeldung | | Next | Weiter | | Open | Öffnen | | Overview | Übersicht | | Preview | Vorschau | | Publish | Veröffentlichen | | Remove | Entfernen | | Required | Pflichtfeld | | Reset | Zurücksetzen | | Restore | Wiederherstellen | | Save | Speichern | | Select all | Alle auswählen | | Settings | Einstellungen | | Sign up | Registrieren | | Signup | Registrierung | | Sort | Sortieren | | Upload | Hochladen | | View | Ansehen | # Artificial Intelligence An AI feature earns trust at every stage, from the first impression to the follow-up. The principles below walk through that lifecycle and what each moment asks of the design. ## Before the interaction Set expectations before a merchant engages. Explain what the feature does in terms of outcomes, not technology. Be upfront about what data it uses. **Do** Generate a product description from your title and attributes. **Don't** Uses a large language model to produce text based on your input. ## During the interaction Always acknowledge that input was received and processing is underway. Never leave a blank or frozen state. Merchants must be able to review output before it takes effect. Every suggestion should be previewable, editable, and dismissable. **Do** Show a preview of the generated content with Edit and Use actions before applying it. **Don't** Apply AI-generated content immediately without a review step. **AI-generated content should never replace human-generated content without review or approval.** ## When something goes wrong Acknowledge errors directly. Give the merchant a clear path to correct, dismiss, or retry from a clean state. **Do** I could not generate a description for this product. Check that the product has a title and at least one attribute. **Don't** Something went wrong. Please try again. ## Writing for AI Write in plain, conversational language. Avoid technical jargon about the underlying model or infrastructure. Speak to the merchant's goals, not the system's mechanics. Use active voice. It makes AI responses feel direct and accountable. **Do** I generated three product descriptions based on your input. **Don't** Three product descriptions were generated. Never oversell what a feature can do. Be honest about limitations upfront rather than letting the merchant discover them through failure. # Action Menu ```vue ``` ## Usage **Action Menu** reveals a short list of contextual actions for a specific record, card, row, or view. Use it for secondary actions like `Duplicate`, `Move`, `Export`, or `Delete` that should stay available without claiming permanent visual priority. ```ts import { MtActionMenu } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Without icons ```vue ``` ### Grouped items Use groups to separate related action sets and keep scanning easy. ```vue ``` ### Keyboard shortcuts ```vue ``` ### States ```vue ``` ### Nested submenu ```vue ``` ### External links An item with a `link` prop renders as an external anchor and opens in a new tab. ```vue ``` ### Match trigger width ```vue ``` ## Anatomy **Action Menu** is built from a small set of companion exports that work together: - `mt-dropdown-menu-root` manages the open and closed state for the menu. - `mt-dropdown-menu-trigger` defines the interactive element that opens the menu, usually a [**Button**](https://meteor.shopware.com/components/button). - `mt-dropdown-menu-portal` renders the menu content in an overlay layer outside the surrounding layout flow. - `mt-action-menu` renders the menu surface itself. - `mt-action-menu-item` renders individual actions, links, shortcuts, and submenu triggers. - `mt-action-menu-group` separates related actions and keeps mixed icon alignment consistent inside a group. - `mt-dropdown-menu-sub` creates nested submenu flows when a second level is truly needed. These parts are exported together so the pattern can be composed in one place. ## API reference ### Props | Prop | Type | Default | Description | | --------------------- | --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | `is-sub-menu` | `boolean` | `false` | | | `match-trigger-width` | `boolean` | `false` | When enabled, the menu content will match the trigger's width using Reka UI's CSS variables. Also constrains max-height to available viewport space. | ### Slots | Slot | Bindings | Description | | --------- | -------- | ----------- | | `default` | `{}` | | ## Best practices **Do** - Keep labels short, specific, and action-oriented. - Prioritize frequent actions and place destructive actions later in the menu. - Keep action ordering consistent across similar contexts. - Keep the menu focused on related actions for the same object or context. - Use `mt-action-menu-group` to separate action sets when grouping improves scanning. - Separate destructive actions into their own group when they appear alongside non-destructive actions. - Use the `critical` variant for destructive actions such as delete or remove. - Keep icon usage consistent within a visual group whenever possible. - Use `shortcut` only when the same action is also available from the keyboard elsewhere in the product. **Don't** - Do not use **Action Menu** for the main action on a screen or card. - Do not hide critical task-completion steps only inside an **Action Menu**. - Do not group unrelated actions or create groups without a clear purpose. - Do not create deep or complex hierarchies when a flatter structure would be easier to scan. - Do not overuse groups or create many single-item groups when a flatter list would scan better. - Do not use icons, groups, or separators unless they add clarity. - Do not rely on color, icons, or shortcut labels alone to explain what an action does. ## Behavior - **Action Menu** is a compound pattern, not a standalone trigger. It is always composed from the companion exports listed in Anatomy. - `shortcut` accepts a structured object with `modifiers` and `key`. - Supported modifier values are `mod`, `ctrl`, `alt`, `shift`, and `meta`. - Use `mod` for cross-platform shortcuts because it maps to `Command` on Mac and `Control` on Windows and Linux. Use `meta` only when you need the platform-specific meta key explicitly. - Supported special keys are `enter`, `esc`, `tab`, `space`, `backspace`, `delete`, `up`, `down`, `left`, and `right`. - Shortcut labels are formatted automatically for Mac and PC, and `aria-keyshortcuts` is added for assistive technology. - An `mt-action-menu-item` with a `link` prop renders as an external anchor and opens in a new tab. - `is-sub-menu` on `mt-action-menu` and `is-sub-trigger` on `mt-action-menu-item` are used together for nested submenu patterns. - `match-trigger-width` is useful when the menu should align visually with a wider trigger such as a row action or account switcher. - Keep nesting shallow. One submenu level is usually enough, and more than two levels should be avoided. ## Accessibility - The trigger should have a clear accessible name so users understand what actions the menu contains. - Menu item labels should stay understandable without depending only on icons, color, or shortcut labels. - If you provide `shortcut`, it supplements the action label rather than replacing it. - Destructive actions should remain clearly labeled in text, not only visually differentiated through the `critical` variant. - Use submenu patterns carefully, because deep menu hierarchies are harder to navigate with keyboard and assistive technology. ## Related components - [**Floating UI**](https://meteor.shopware.com/components/floating-ui): when you need a custom popover surface with richer content such as text, filters, form fields, or mixed layout content instead of a menu of actions. # Avatar ```vue ``` ## Usage **Avatar** represents a person or entity as a profile image or initials. Use it to identify users in lists, headers, menus, and chat threads, with an image when recognition matters and a profile picture is available, or initials as a lightweight fallback. ```ts import { MtAvatar } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Sizes ```vue ``` ### With image ```vue ``` ### Square ```vue ``` ### All background colors The background color is derived from the provided name, so repeated names get a stable color. ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ------------ | ------------------------------------ | ----------- | ----------- | | `size` | `"s" \| "m" \| "l" \| "2xs" \| "xs"` | `"m"` | | | `first-name` | `string` | `undefined` | | | `last-name` | `string` | `undefined` | | | `image-url` | `string` | `undefined` | | | `variant` | `"square" \| "circle"` | `"circle"` | | ### Slots | Slot | Bindings | Description | | --------- | -------- | ----------- | | `default` | `{}` | | ## Best practices **Do** - Provide an `imageUrl` when possible, photos improve recognition. - Rely on initials when no image is available, they are concise and readable. - Pick a size that fits the layout, for example `s` for dense lists or `l` for profile headers. - Use the `square` variant when the surrounding UI uses sharper corners. **Don't** - Do not treat **Avatar** as a clickable element, wrap it in a button or link if interaction is required. - Do not place long text inside **Avatar**, it should only contain initials or an image. - Do not oversize **Avatar** in dense layouts, this harms scanability. ## Behavior - If no `imageUrl` is provided, **Avatar** falls back to initials derived from `firstName` and `lastName`. - The background color is derived from the provided name, which gives repeated names a stable visual treatment. - **Avatar** is presentational. If the avatar should trigger an action, place it inside an interactive wrapper instead of making the avatar itself responsible for interaction. ## Accessibility - If the avatar is only decorative, keep it out of the interaction flow. - If the avatar represents an important person or entity, make sure the surrounding UI still exposes that identity in text. - When wrapping the avatar in an interactive control, ensure the control has a clear accessible name. # Badge ```vue ``` ## Usage **Badge** is a compact, non-interactive label for short, glanceable states. Use it inline in tables, cards, lists, or detail headers to help users scan status, category, or state, and reach for the `variant`, size, icon, or status indicator when an extra visual cue reinforces the meaning. ```ts import { MtBadge } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Variants ```vue ``` ### Sizes ```vue ``` ### Status indicator ```vue ``` ### Icon ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ------------------ | ---------------------------------------------------------------- | ----------- | ----------- | | `variant` | `"critical" \| "info" \| "neutral" \| "attention" \| "positive"` | `"neutral"` | | | `icon` | `string` | `undefined` | | | `size` | `"s" \| "m" \| "l"` | `"s"` | | | `status-indicator` | `boolean` | `false` | | ### Slots | Slot | Bindings | Description | | --------- | -------- | ----------- | | `default` | `any` | | | `icon` | `any` | | ## Best practices **Do** - Keep badge labels short and easy to scan. - Choose the `variant` that matches the semantic meaning of the label. - Use the smallest size that still fits the surrounding layout comfortably. - Add an icon or status indicator only when it meaningfully improves recognition. **Don't** - Do not use **Badge** for long messages or explanatory text. - Do not make **Badge** behave like buttons or links. - Do not overload a surface with too many badges, because they quickly lose emphasis. - Do not rely on color alone to communicate meaning. ## Behavior - **Badge** is presentational and non-interactive. If users need to click, open, or trigger something, use a more appropriate interactive component around it. - The component stays intentionally compact, so it works best with a short label and a single supporting visual treatment. - The status indicator and icon are optional enhancements, not a replacement for a clear text label. ## Accessibility - Keep the label understandable on its own so meaning does not depend only on color, the status dot, or the icon. - Because badges are non-interactive, avoid using them as the only way to expose important information or actions. - Use concise text so the badge remains readable in dense interfaces and small sizes. ## Related components - [**Promo Badge**](https://meteor.shopware.com/components/promo-badge): when the label is a predefined promotional label such as `New`, `Beta`, or `Shopware AI`. - [**Status Dot**](https://meteor.shopware.com/components/status-dot): when a small colored dot is enough and no text label is needed. # Banner ```vue ``` ## Usage **Banner** is a persistent, inline message that stays in the page layout. Use it for warnings, success confirmations, inherited-state hints, or inline guidance that should remain visible near the affected content until the user reads or dismisses it, rather than as a temporary overlay notification. ```ts import { MtBanner } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Closable ```vue ``` ### Variants ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | -------------- | ------------------------------------------------------------------------------- | ----------- | ----------- | | `variant` | `"critical" \| "info" \| "neutral" \| "attention" \| "positive" \| "inherited"` | `"neutral"` | | | `title` | `string` | | | | `hide-icon` | `boolean` | `false` | | | `closable` | `boolean` | `false` | | | `banner-index` | `string` | | | | `icon` | `string` | | | ### Events | Event | Payload | Description | | ------- | ------------------------------------- | ----------- | | `close` | `[bannerIndex?: string \| undefined]` | | ### Slots | Slot | Bindings | Description | | ------------ | -------- | ----------- | | `customIcon` | `{}` | | | `default` | `{}` | | ## Best practices **Do** - Keep the message concise and directly tied to the surrounding context. - Choose the `variant` that matches the meaning of the message. - Prefer **Banner** with the default icon enabled, using the icon that comes with the selected `variant`. - Use the `title` to help people scan the message quickly when the content is more than a short sentence. - Use `closable` only when dismissing the banner is a safe choice for the user. - If you add actions inside the banner content, choose components and variants with sufficient color contrast. [**Button**](https://meteor.shopware.com/components/button) in `primary` or `secondary` is a good starting point. **Don't** - Do not use **Banner** for transient confirmations that can disappear after a few seconds. - Do not stack many **Banner** components together, because they quickly compete with the main page content. - Do not hide blocking or decision-heavy flows in **Banner** when a modal or dedicated screen is more appropriate. - Do not replace the built-in variant icon unless you have a strong semantic reason to do so. - Do not rely on icon color alone to communicate meaning. The text should still be clear on its own. ## Accessibility - **Banner** content should remain understandable without depending on the icon alone. - Use clear text so the message still works for people using screen readers or high-contrast modes. - Only make a banner dismissible when removing it will not hide information the user still needs. - If the banner includes actions in the slot content, verify their contrast against the banner background instead of assuming every button style will remain readable. - Keep the message brief and structured so it can be scanned quickly inside a busy page. ## Related components - [**Snackbar**](https://meteor.shopware.com/components/snackbar): when you need lightweight temporary feedback that appears separately from the page content. # Button ```vue ``` ## Usage **Button** triggers a clear user action such as saving, creating, confirming, or moving to the next step. Use the `variant` to communicate action hierarchy and intent, and the size to fit the surrounding layout without changing what the action means. ```ts import { MtButton } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Variants Each variant signals a different level of emphasis and intent. ```vue ``` ### Sizes Match the button size to the surrounding layout without changing the meaning of the action. ```vue ``` ### With icon Add an icon in the front or back slot to reinforce the action. ```vue ``` ### Icon only Use `square` and an `aria-label` for a compact, icon-only control. ```vue ``` ### States ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ------------ | ------------------------------------------------------------------ | ------------- | ----------- | | `is` | `string \| Component` | `"button"` | | | `disabled` | `boolean` | | | | `variant` | `"secondary" \| "primary" \| "tertiary" \| "critical" \| "action"` | `"secondary"` | | | `ghost` | `boolean` | | | | `size` | `"small" \| "default" \| "large" \| "x-small"` | `"small"` | | | `square` | `boolean` | | | | `block` | `boolean` | | | | `link` | `string` | `undefined` | | | `is-loading` | `boolean` | | | ### Slots | Slot | Bindings | Description | | ----------- | -------- | ----------- | | `default` | `any` | | | `iconFront` | `any` | | | `iconBack` | `any` | | ## Best practices **Do** - Keep button labels short, specific, and action-oriented. - Use `primary` for the main action in a local context. - Use `secondary` or `tertiary` for supporting actions. - Use `critical` only for destructive or high-risk actions. - Use `square` when you render an icon-only button so the control stays visually balanced. **Don't** - Do not use multiple primary buttons in the same local action group. - Do not use vague labels such as `Submit` or `Continue` when a clearer verb would help. - Do not rely on color alone to explain what a button will do. - Do not use **Button** for purely navigational inline text links. ## Behavior - **Button** supports visual hierarchy through variants, but the label still carries the main meaning of the action. - Loading and disabled states should be used to prevent duplicate actions or indicate temporary unavailability. - The icon slots are optional enhancements. For icon-only buttons, use `square` and provide an accessible name. ## Accessibility - **Button** text should clearly describe the action without depending on surrounding context alone. - If you use only an icon visually, ensure the button still has an accessible name. - Icon-only buttons are valid, but they should use the `square` prop and a clear accessible label such as `aria-label`. - Disabled and loading buttons should be used intentionally so people understand why the action is unavailable. ## Related components - [**Link**](https://meteor.shopware.com/components/link): when the user is moving to another page, route, or destination. # Card ```vue ``` ## Usage **Card** is a bordered surface that groups related content, metadata, and local actions into one section that reads as a single surface. Use it for settings sections, dashboards, detail views, or other grouped content that needs a local header and should stay visually connected instead of being spread across loose page elements. Use it with tabs when users need to switch between closely related views inside the same section. ```ts import { MtCard } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Header content Use the header to add context, identity, and one related secondary action. ```vue ``` ### Tabs ```vue ``` ### Loading ```vue ``` ### Inheritance Show the link or unlink toggle when a card represents values that can be inherited or overridden. ```vue ``` ### Inset content ```vue ``` ### Inset footer ```vue ``` ## Anatomy **Card** is composed from a few structural regions and optional slots: - The header can contain an avatar, title, subtitle, and related header content on the right. - The tabs area sits below the header and can be used for closely related views of the same section. - The content area holds the main information, form fields, or other section content. **Card** also exposes [**Inset**](https://meteor.shopware.com/utilities/components/inset) as a companion layout utility for cases where content inside the card should visually break out to the card edges without hard-coding spacing values. - Use **Inset** inside the default card content when an inner block should align to the card's outer padding instead of the current content flow. - Use **Inset** in the `footer` slot when the footer needs its own full-width background or custom padding treatment while still staying aligned to the card spacing tokens. - **Inset** works by consuming the card's inset spacing variables, so it is most useful inside components such as **Card** that define those values for you. ## API reference ### Props | Prop | Type | Default | Description | | ------------- | --------- | ----------- | ----------- | | `title` | `string` | | | | `subtitle` | `string` | | | | `is-loading` | `boolean` | | | | `large` | `boolean` | | | | `inheritance` | `boolean` | `undefined` | | ### Events | Event | Payload | Description | | -------------------- | ------------------ | ----------- | | `update:inheritance` | `[value: boolean]` | | ### Slots | Slot | Bindings | Description | | ----------------- | -------- | ----------- | | `title` | `any` | | | `subtitle` | `any` | | | `avatar` | `any` | | | `grid` | `any` | | | `footer` | `any` | | | `default` | `any` | | | `toolbar` | `any` | | | `tabs` | `any` | | | `before-card` | `any` | | | `after-card` | `any` | | | `headerRight` | `any` | | | `context-actions` | `any` | | ## Best practices **Do** - Keep each **Card** focused on one topic, entity, or task. - Use `title` and `subtitle` when they help users scan the section quickly. - Use the header to add context, identity, or one closely related action for the section. - Use tabs only when the content stays part of the same overall section. - Keep the content inside a **Card** concise enough that the surface still feels like one grouped area. **Don't** - Do not overload one **Card** with unrelated content blocks or too many competing actions. - Do not nest many **Card** components inside each other when a simpler layout would be easier to scan. - Do not use **Card** as a generic wrapper for unrelated page content. - Do not add decorative header content if it does not help users understand the section. - Do not use tabs for unrelated destinations or views that should be separate sections. - Do not rely on a decorative card title alone when the contained actions need their own clear labels. ## Behavior - The card header is only rendered when `title`, `subtitle`, `avatar`, or their replacement slots are provided. - The `tabs` slot only renders the tab bar. The surrounding view is responsible for handling tab state and swapping the content. - The `title` and `subtitle` slots can replace the matching props when you need custom header content. - `isLoading` overlays the content area with a loader while the card keeps its layout. - **Inset** pairs naturally with **Card** because the card content and footer define the inset spacing variables that **Inset** consumes. - `inheritance` shows the link or unlink toggle and emits `update:inheritance` when the toggle is clicked. - The `before-card` and `after-card` slots are private and should not be used in application code. ## Accessibility - Prefer using the `title` prop when the card needs a programmatic label, because it is also used as the card's `aria-label`. - If you render custom controls in `headerRight`, make sure each control has a clear accessible name. - Keep card titles descriptive so users can understand the section before interacting with controls inside it. - If you add tabs inside a **Card**, those tabs still need their own keyboard support and clear labels. ## Related components - [**Inset**](https://meteor.shopware.com/utilities/components/inset): when you only need spacing or padded grouping inside an existing surface. # Chart ```vue ``` ## Usage **Chart** is a data visualization for showing how values change over time, used with `type="area"`. Use it when users should compare trends, peaks, and drops across one or more series, and when a visual trend is easier to understand than a table alone. ```ts import { MtChart } from "@shopware-ag/meteor-component-library"; ``` ## API reference ### Props | Prop | Type | Default | Description | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------- | ----------- | | `series` \* | `any[]` | | | | `options` | `ApexCharts.ApexOptions` | `{}` | | | `type` | `"area" \| "line" \| "bar" \| "pie" \| "donut" \| "radialBar" \| "scatter" \| "bubble" \| "heatmap" \| "candlestick" \| "boxPlot" \| "radar" \| "polarArea" \| "rangeBar" \| "rangeArea" \| "treemap"` | `"area"` | | | `width` | `string \| number` | `"100%"` | | | `height` | `string \| number` | `"300px"` | | ## Best practices **Do** - Keep the time scale or sequence clear by providing meaningful x-axis labels. - Use short series names so the legend and tooltip stay easy to scan. - Pair the chart with nearby summary text when the data drives a decision. **Don't** - Do not use an area chart when exact individual values are the primary goal. - Do not rely on color alone to explain the data series. - Do not use the chart as the only presentation of critical information. ## Behavior - **Chart** passes `series` and `options` through to ApexCharts and merges your `options` with Meteor's default chart options. - Changing `series`, `options`, `type`, `width`, or `height` updates the rendered chart. ## Accessibility - Provide the chart with nearby text that explains the main takeaway, because charts are not equally accessible for every user. - Do not use the chart alone for critical information without an accessible text or table alternative. - Keep labels and series names concise so tooltip and axis content stays readable. # Checkbox ```vue ``` ## Usage **Checkbox** is an independent on or off control for boolean values and multi-select lists. Use it when users can turn an option on or off without affecting other options, when multiple options in a group can be selected at the same time, or for form fields that should submit a boolean value. ```ts import { MtCheckbox } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### States ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ------------------------ | ---------------------------------------- | ----------- | ---------------------------------------------------- | | `name` | `string` | `undefined` | The name of the input field when submitting a form. | | `map-inheritance` | `Record` | `null` | | | `disabled` | `boolean` | `false` | Toggles the disabled state of the checkbox. | | `required` | `boolean` | `false` | Marks the field as required with an asterix. | | `model-value` | `boolean` | `undefined` | v-model binding for the checkbox value. | | `label` | `string` | `undefined` | A label for the checkbox. | | `error` | `Record` | `null` | Error object for this field. | | `help-text` | `string` | `null` | Help text with additional information for the field. | | `is-inherited` | `boolean` | `false` | Determines if the field is inherited. | | `checked` | `boolean` | `undefined` | Determines the checked state of the checkbox. | | `partial` | `boolean` | `false` | Determines if the field is partially checked. | | `inherited-value` | `boolean` | `null` | Inherited value from another SalesChannel. | | `bordered` | `boolean` | `false` | Determines if the field is surrounded by a border. | | `on-update:model-value` | `((...args: any[]) => any) \| undefined` | | | | `on-inheritance-restore` | `((...args: any[]) => any) \| undefined` | | | | `on-inheritance-remove` | `((...args: any[]) => any) \| undefined` | | | | `on-change` | `((...args: any[]) => any) \| undefined` | | | | `on-update:checked` | `((...args: any[]) => any) \| undefined` | | | ### Exposed | Name | Type | Description | | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | ----------- | | `checkboxClasses` | `{ "mt-checkbox--future-remove-default-margin": any; "mt-checkbox--future-consistent-label-line-height": any; }` | | | `id` | `string` | | | `currentValue` | `boolean` | | | `formFieldName` | `string` | | | `MtCheckboxFieldClasses` | `{ "has--error": boolean; "is--disabled": boolean; "is--inherited": boolean; "is--bordered": boolean; "is--partly-checked": boolean; }` | | | `identification` | `string` | | | `hasError` | `boolean` | | | `inputState` | `boolean` | | | `isInheritanceField` | `boolean` | | | `isInheritedComputed` | `boolean` | | | `isDisabled` | `boolean` | | | `isPartlyChecked` | `boolean` | | | `iconName` | `string` | | | `hasLabel` | `boolean` | | ## Best practices **Do** - Use short, clear labels that describe the checked state in plain language. - Use help text when the effect of the option is not obvious from the label alone. - Use the indeterminate state only when the checkbox represents a mixed selection. **Don't** - Do not use **Checkbox** for mutually exclusive options. - Do not use the indeterminate state as a permanent third value. - Do not rely on the checkmark alone without a visible label. ## Behavior - Prefer `v-model` with `modelValue` and `update:modelValue` for new code. The `checked` prop and `change` event are legacy APIs. - `partial` shows an indeterminate visual state. It is useful for parent selections with mixed child states. - `inheritedValue` and `isInherited` support inheritance fields. An inherited **Checkbox** is disabled until inheritance is removed. - `helpText`, `error`, `required`, and `bordered` integrate with the shared field wrapper. ## Accessibility - Always provide a visible label, either through the `label` prop or the `label` slot. - **Checkbox** uses a native checkbox input, so it supports standard keyboard interaction such as toggling with the Space key. - If the indeterminate state needs explanation, describe its meaning in nearby text instead of relying on the visual state alone. ## Related components - [**Radio Group**](https://meteor.shopware.com/components/radio-group): when users must choose exactly one option from a small set of visible choices. - [**Select**](https://meteor.shopware.com/components/select): when users need to choose from a longer list or when space is limited. # Collapsible ```vue ``` ## Usage **Collapsible** is an interactive container that expands and collapses related content behind a trigger. Use it when secondary content should stay out of the way until a user reveals it, composing `mt-collapsible` with `mt-collapsible-trigger` and `mt-collapsible-content`. ```ts import { MtCollapsible, MtCollapsibleTrigger, MtCollapsibleContent, } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Disabled ```vue ``` ## Anatomy **Collapsible** is built from three companion exports that work together: - `mt-collapsible` is the root container that owns the open and closed state. - `mt-collapsible-trigger` is the interactive element that toggles the open state. It renders as a `button` by default. - `mt-collapsible-content` is the region that is shown or hidden when the state changes. ## API reference ### Props | Prop | Type | Default | Description | | -------------- | ------------------ | ------- | ------------------------------------------------------------------------------------- | | `open` | `boolean` | | | | `default-open` | `boolean` | | | | `disabled` | `boolean` | | | | `as` | `string \| object` | `"div"` | | | `as-child` | `boolean` | `false` | | | `keep-mounted` | `boolean` | `true` | Whether the closed content stays mounted in the DOM when closed. Defaults to \`true\` | ### Events | Event | Payload | Description | | ------------- | ------------------ | ----------- | | `update:open` | `[value: boolean]` | | ### Slots | Slot | Bindings | Description | | --------- | -------------------- | ----------- | | `default` | `{ open: boolean; }` | | ## Behavior - **Collapsible** is a compound pattern. You always compose `mt-collapsible` with `mt-collapsible-trigger` and `mt-collapsible-content`. - The open state can be controlled externally with `v-model:open` or left uncontrolled with `default-open`. - When `disabled`, the trigger no longer toggles the content and the data attributes reflect the disabled state for styling. - The content slides open and closed over 300 ms by default, using the `--reka-collapsible-content-height` CSS variable that the component exposes on its content element. The animation respects `prefers-reduced-motion`. - `keep-mounted` defaults to `true` so the closed content stays in the DOM (it is hidden with `hidden="until-found"`, which keeps it discoverable to the browser's find-in-page feature) and the slide animation can play. Set `keep-mounted="false"` when the closed subtree is too expensive to leave mounted; the open and close animation will not play in that case. ## Accessibility - The trigger should always have a clear accessible name so users understand what content the toggle reveals. - The trigger and content are linked through `aria-controls` and `aria-expanded`, so assistive technology announces the state change automatically. - When using a custom element via `as-child`, make sure the rendered element is still focusable and supports keyboard activation. # Colorpicker ```vue ``` ## Usage **Colorpicker** is a form field for choosing and editing a color value. Use it when users need to define a custom brand, accent, or interface color and a text input alone would make color editing harder or more error-prone. Use the alpha option when transparency is part of the value users need to control. ```ts import { MtColorpicker } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Without alpha ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ---------------------------- | ---------------------------------------- | -------- | ------------------------------------------------------------------------------------------- | | `disabled` | `boolean` | `false` | Determines if the field is disabled. | | `required` | `boolean` | `false` | Determines if the field is required. | | `model-value` | `string \| null` | `""` | The value of the colorpicker field. | | `name` | `string` | `null` | | | `label` | `string` | `null` | A label for your text field. Usually used to guide the user what value this field controls. | | `error` | `Record` | `null` | An error in your business logic related to this field. | | `help-text` | `string` | `null` | A text that helps the user to understand what this field does. | | `is-inherited` | `boolean` | `false` | Toggles the inheritance visualization. | | `is-inheritance-field` | `boolean` | `false` | Determines if the field is inheritable. | | `hint` | `string \| null` | `null` | Optional caption below the field. The \`#hint\` slot takes precedence when provided. | | `disable-inheritance-toggle` | `boolean` | `false` | Determines the active state of the inheritance toggle. | | `z-index` | `number \| null` | `null` | | | `color-output` | `"auto" \| "hex" \| "hsl" \| "rgb"` | `"auto"` | Change the output value which gets emitted and shown in the field. | | `alpha` | `boolean` | `true` | If activated then the color value can contain alpha values | | `readonly` | `boolean` | `false` | Determines if the field can be edited | | `color-labels` | `boolean` | `true` | Toggle the labels above each field inside the colorpicker | | `compact` | `boolean` | `false` | Show the colorpicker in a compact mode | | `apply-mode` | `boolean` | `false` | Use apply-mode to apply the color value on button click | | `placeholder` | `string` | | | | `on-update:model-value` | `((...args: any[]) => any) \| undefined` | | | | `on-inheritance-restore` | `((...args: any[]) => any) \| undefined` | | | | `on-inheritance-remove` | `((...args: any[]) => any) \| undefined` | | | ### Exposed | Name | Type | Description | | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | | `t` | `ComposerTranslation<{ en: { "mt-colorpicker": { apply: string; }; }; de: { "mt-colorpicker": { apply: string; }; }; }, "de" \| "en", RemoveIndexSignature<{ [x: string]: LocaleMessageValue; }>, never, "mt-colorpicker" \| "mt-colorpicker.apply", "mt-colorpicker" \| "mt-colorpicker.apply">` | | | `localValue` | `string \| { string: string; red: string; green: string; blue: string; alpha?: string \| undefined; }` | | | `visible` | `boolean` | | | `isDragging` | `boolean` | | | `userInput` | `null` | | | `luminanceValue` | `number` | | | `saturationValue` | `number` | | | `hueValue` | `number` | | | `alphaValue` | `number` | | | `hasFocus` | `boolean` | | | `trap` | `{ active: boolean; paused: boolean; activate: (activateOptions?: ActivateOptions \| undefined) => FocusTrap; deactivate: (deactivateOptions?: DeactivateOptions \| undefined) => FocusTrap; pause: (pauseOptions?: PauseOptions \| undefined) => FocusTrap; unpause: (unpauseOptions?: UnpauseOptions \| undefined) => FocusTrap; updateContainerElements: (containerElements: string \| HTMLElement \| SVGElement \| (string \| HTMLElement \| SVGElement)[]) => FocusTrap; } \| null` | | | `hueStep` | `number` | | | `alphaStep` | `number` | | | `colorValue` | `string \| { string: string; red: string; green: string; blue: string; alpha?: string \| undefined; }` | | | `showFieldHint` | `boolean` | | | `integerAlpha` | `number` | | | `sliderBackground` | `string` | | | `isColorValid` | `boolean` | | | `previewColorValue` | `string` | | | `selectorBackground` | `string` | | | `redValue` | `number` | | | `greenValue` | `number` | | | `blueValue` | `number` | | | `rgbValue` | `string` | | | `hslValue` | `string` | | | `hexValue` | `string \| { string: string; red: string; green: string; blue: string; alpha?: string \| undefined; }` | | | `convertedValue` | `string \| { string: string; red: string; green: string; blue: string; alpha?: string \| undefined; }` | | | `selectorPositionX` | `string` | | | `selectorPositionY` | `string` | | | `selectorStyles` | `{ backgroundColor: string; top: string; left: string; }` | | | `componentClasses` | `{ "mt-colorpicker": boolean; "mt-colorpicker--compact": boolean; }` | | ## Best practices **Do** - Use a clear label so users understand what surface or token the color affects. - Keep the emitted format consistent with the value your feature expects. - Enable alpha only when transparency is actually supported by the consuming feature. **Don't** - Do not use **Colorpicker** when users only need to choose from a small fixed palette. - Do not enable alpha if the saved value ignores transparency. - Do not rely on color alone to explain what a setting changes. ## Behavior - **Colorpicker** supports different emitted output formats through `colorOutput`, such as `auto`, `hex`, `hsl`, and `rgb`. - When `alpha` is enabled, the picker also exposes transparency controls and can emit values with opacity. - `helpText`, `required`, `error`, and inheritance-related props integrate with the shared field wrapper. ## Accessibility - Always provide a visible label so users understand what the chosen color controls. - Do not rely only on the visual preview. The text value should remain understandable and editable. - If alpha is enabled, make sure nearby context explains how transparency affects the result. # Data Table ::warning **Experimental.** The API may still change in a future release. :: ```vue ``` ## Usage **Data Table** is a flexible table for presenting large, structured datasets in rows and columns. Define each column through a configuration object that sets its label, data property, renderer, and position, and drive the table entirely through props while reacting to its events, since it holds no internal data state. Use pagination, sorting, filtering, and search to help users work through large result sets, row selection and bulk actions when users need to act on several rows at once, and the `caption` prop to give screen readers a descriptive summary of the table. ```ts import { MtDataTable } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Full width The `full` layout lets the table span the available width instead of sitting in a centered card. ```vue ``` ### Empty state When the data source is empty, the table shows a built-in empty state. ```vue ``` ### Sticky header The column header stays in view while the rows scroll. ```vue ``` ## Basic usage A minimal table needs a `dataSource`, a `columns` definition, and handlers for the pagination events: ```html ``` ## Column configuration Each column is described by a configuration object that controls how the cell is rendered and how it behaves: ```typescript interface ColumnDefinition { label: string; // Column header label property: string; // Property path in the data source object renderer?: string; // How to render the cell ('text' | 'number' | 'price') position: number; // Column order (use increments of 100) sortable?: boolean; // Enable or disable sorting (default: true) width?: number; // Fixed column width allowResize?: boolean; // Allow column resizing visible?: boolean; // Show or hide the column } ``` ## Managing data Because **Data Table** holds no internal state, the parent owns all data and UI state and reacts to the table's events. A complete integration wires every interaction back to a single data-fetching function: ```html ``` ## Filtering Filters are declared through a `filters` array and applied through `appliedFilters`. Each filter follows this structure: ```typescript interface Filter { id: string; label: string; type: { id: string; options: Array<{ id: string; label: string; }>; }; } ``` ```html ``` ## Loading states Toggle `isLoading` around data fetching so the table shows skeleton placeholders while data is on the way: ```html ``` ## Creating a wrapper component When several tables share the same data-management logic, wrap the component once to reduce boilerplate, centralize API integration, and keep table implementations consistent: ```html ``` Consuming the wrapper then takes much less code: ```html ``` From here you can extend the wrapper with error handling and retry logic, caching, export, bulk actions, or persistent table state. ## API reference ### Props | Prop | Type | Default | Description | | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `current-page` \* | `number` | | Define the current page of the table. | | `columns` \* | `ColumnProperty` | | The defintions for the columns which should be displayed in the table. | | `data-source` \* | `DataSourcePropType` | | The data source which contains the data for the current state of the table. | | `pagination-limit` \* | `number` | | Define the limit of items per page. | | `pagination-total-items` \* | `number` | | Define the total amount of items. | | `title` | `string` | `""` | Define the title of the table. | | `subtitle` | `string` | `""` | Define the subtitle of the table. | | `is-loading` | `boolean` | `false` | If active then the table will be in loading state. | | `filters` | `Filter[]` | `[]` | All available filters | | `show-outlines` | `boolean` | `true` | Enable or disable outlines for the table. | | `show-stripes` | `boolean` | `true` | Enable or disable the stripe design for the table. | | `enable-outline-framing` | `boolean` | `false` | Enable or disable outline framing on hover | | `enable-row-numbering` | `boolean` | `false` | \* Enable numbered rows | | `column-changes` | `Record` | `reactive({})` | Optional property. When you want to override the current column information with the given changes, you can pass them here. The changes will be applied to the current column information. This is useful for saving and loading the current column configuration when the user customizes the table. | | `layout` | `"default" \| "full"` | `"default"` | The layout of the data table. | | `enable-reload` | `boolean` | `false` | Activate the reload button at the top right corner of the table. | | `pagination-options` | `number[]` | `[5, 10, 25, 50]` | Define the available pagination limits. | | `sort-by` | `string` | `""` | Define the current sort by property. | | `sort-direction` | `"ASC" \| "DESC"` | `"ASC"` | Define the current sort direction. | | `disable-search` | `boolean` | `false` | If active then the search input will be disabled. | | `search-value` | `string` | `""` | Define the current search value. | | `allow-row-selection` | `boolean` | `false` | If active user can select rows and can perform actions on them. | | `disable-row-select` | `string[]` | `[]` | | | `selected-rows` | `string[]` | `[]` | | | `allow-bulk-edit` | `boolean` | `false` | If active user can do bulk edit by selecting items | | `allow-bulk-delete` | `boolean` | `false` | If active user can do bulk delete by selecting items | | `bulk-edit-more-actions` | `{ id: string; label: string; onClick: () => void; icon?: string \| undefined; type?: MtPopoverItemType \| undefined; metaCopy?: string \| undefined; contextualDetail?: string \| undefined; }[] \| undefined` | `[]` | Add more custom bulk edit actions | | `disable-delete` | `boolean` | `false` | Disable the possibility to delete items | | `disable-edit` | `boolean` | `false` | Disable the possibility to edit items | | `disable-settings-table` | `boolean` | `false` | Disable the possibility to settings table | | `caption` | `string` | `"Data table"` | Caption for accessibility | | `applied-filters` | `Filter[]` | `[]` | Filters in use by the user | | `number-of-results` | `number` | `undefined` | Displays how many results are found | | `additional-context-buttons` | `{ type?: "default" \| "critical" \| "active" \| undefined; label: string; key: string; }[]` | `[]` | Additional context buttons to show in the context menu | | `on-change-show-outlines` | `((...args: any[]) => any) \| undefined` | | | | `on-change-show-stripes` | `((...args: any[]) => any) \| undefined` | | | | `on-change-outline-framing` | `((...args: any[]) => any) \| undefined` | | | | `on-change-enable-row-numbering` | `((...args: any[]) => any) \| undefined` | | | | `on-reload` | `((...args: any[]) => any) \| undefined` | | | | `on-pagination-limit-change` | `((...args: any[]) => any) \| undefined` | | | | `on-pagination-current-page-change` | `((...args: any[]) => any) \| undefined` | | | | `on-search-value-change` | `((...args: any[]) => any) \| undefined` | | | | `on-sort-change` | `((...args: any[]) => any) \| undefined` | | | | `on-open-details` | `((...args: any[]) => any) \| undefined` | | | | `on-selection-change` | `((...args: any[]) => any) \| undefined` | | | | `on-multiple-selection-change` | `((...args: any[]) => any) \| undefined` | | | | `on-bulk-edit` | `((...args: any[]) => any) \| undefined` | | | | `on-bulk-delete` | `((...args: any[]) => any) \| undefined` | | | | `on-item-delete` | `((...args: any[]) => any) \| undefined` | | | | `on-update:applied-filters` | `((...args: any[]) => any) \| undefined` | | | | `on-context-select` | `((...args: any[]) => any) \| undefined` | | | ### Exposed | Name | Type | Description | | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | | `t` | `ComposerTranslation<{ en: { itemsPerPage: string; filter: { numberOfResults: string; addFilter: string; fetchingFilteredResults: string; }; columnSettings: { sortAscending: string; sortDescending: string; hideColumn: string; }; addColumnIndicator: { popoverTitle: string; tooltipMessage: string; }; contextButtons: { edit: string; delete: string; }; emptyState: { headline: string; description: string; }; bulkEdit: { itemsSelected: string; edit: string; delete: string; more: string; }; reload: { tooltip: string; }; }; de: { itemsPerPage: string; filter: { numberOfResults: string; addFilter: string; fetchingFilteredResults: string; }; columnSettings: { sortAscending: string; sortDescending: string; hideColumn: string; }; addColumnIndicator: { popoverTitle: string; tooltipMessage: string; }; contextButtons: { edit: string; delete: string; }; emptyState: { headline: string; description: string; }; bulkEdit: { itemsSelected: string; edit: string; delete: string; more: string; }; reload: { tooltip: string; }; }; }, "de" \| "en", RemoveIndexSignature<{ [x: string]: LocaleMessageValue; }>, never, "filter" \| "reload" \| "itemsPerPage" \| "columnSettings" \| "addColumnIndicator" \| "contextButtons" \| "emptyState" \| "bulkEdit" \| "filter.numberOfResults" \| "filter.addFilter" \| "filter.fetchingFilteredResults" \| "reload.tooltip" \| "columnSettings.sortAscending" \| "columnSettings.sortDescending" \| "columnSettings.hideColumn" \| "addColumnIndicator.popoverTitle" \| "addColumnIndicator.tooltipMessage" \| "contextButtons.delete" \| "contextButtons.edit" \| "emptyState.description" \| "emptyState.headline" \| "bulkEdit.delete" \| "bulkEdit.edit" \| "bulkEdit.itemsSelected" \| "bulkEdit.more", "filter" \| "reload" \| "itemsPerPage" \| "columnSettings" \| "addColumnIndicator" \| "contextButtons" \| "emptyState" \| "bulkEdit" \| "filter.numberOfResults" \| "filter.addFilter" \| "filter.fetchingFilteredResults" \| "reload.tooltip" \| "columnSettings.sortAscending" \| "columnSettings.sortDescending" \| "columnSettings.hideColumn" \| "addColumnIndicator.popoverTitle" \| "addColumnIndicator.tooltipMessage" \| "contextButtons.delete" \| "contextButtons.edit" \| "emptyState.description" \| "emptyState.headline" \| "bulkEdit.delete" \| "bulkEdit.edit" \| "bulkEdit.itemsSelected" \| "bulkEdit.more">` | | | `sortedColumns` | `ColumnDefinition[]` | | | `isFirstVisibleColumn` | `(column: ColumnDefinition) => boolean` | | | `addColumnOptions` | `{ id: string; label: string; parentGroup: undefined; position: number; isVisible: boolean; isClickable: boolean; isSortable: boolean; isHidable: boolean; disabled: boolean; }[]` | | | `renderColumnDataCellStyle` | `(column: ColumnDefinition) => { width: string; "min-width": string; "max-width": string; "white-space": "nowrap" \| "normal"; }` | | | `renderColumnHeaderStyle` | `(column: ColumnDefinition) => { "max-width": string; width: string; "min-width": string; "white-space": "nowrap" \| "normal"; }` | | | `tableWrapper` | `any` | | | `emitReload` | `() => void` | | | `emitPaginationLimitChange` | `(limitValue: number) => void` | | | `emitPaginationCurrentPageChange` | `(currentPage: number) => void` | | | `emitSearchValueChange` | `(searchValue: string) => void` | | | `paginationOptionsConverted` | `{ id: number; label: string; value: number; }[]` | | | `startColumnResizing` | `(column: ColumnDefinition \| null) => void` | | | `columnHeaderRefs` | `Record` | | | `columnDataCellRefs` | `Record` | | | `setColumnDataCellRefs` | `({ el, column, index, }: { el?: HTMLElement \| undefined; column: ColumnDefinition; index: number; }) => void` | | | `dataTable` | `HTMLElement \| null` | | | `dragConfig` | `Partial>` | | | `dropConfig` | `Partial & { dropZone?: "before" \| "after" \| undefined; }>` | | | `resetAllChanges` | `() => void` | | | `changeColumnPosition` | `(columnId: string, targetColumnId: string, insertPosition?: "before" \| "after") => void` | | | `isColumnVisible` | `(column: ColumnDefinition) => boolean` | | | `changeColumnVisibility` | `(columnProperty: string, visibility: boolean) => void` | | | `emitSortChange` | `(property: string, direction: "ASC" \| "DESC") => void` | | | `onColumnSettingsSortChange` | `(property: string, direction: "ASC" \| "DESC", chainMethod?: (() => void) \| undefined) => void` | | | `MtDataTableClasses` | `{ "mt-data-table__layout-default": boolean; "mt-data-table__layout-full": boolean; "mt-data-table__first-column-fixed": boolean; "mt-data-table__last-column-fixed": boolean; "mt-data-table__stripes": boolean; "mt-data-table__outlines": boolean; "mt-data-table__column-outline-framing-active": boolean; }` | | | `tableStylingVariables` | `{ "--fixed-left-column-width": string; "--fixed-right-column-width": string; }` | | | `getSelectionValue` | `(dataId: string) => boolean` | | | `onRowSelect` | `(dataId: string) => void` | | | `somethingSelected` | `boolean` | | | `bulkEditSegmentedControlActions` | `SegmentedControlActionsProp` | | | `handleSelectAll` | `() => void` | | | `highlightedColumn` | `string \| null` | | | `setHighlightedColumn` | `(column: ColumnDefinition \| null) => void` | | | `getColumnDataCellClasses` | `(column: ColumnDefinition) => string[]` | | | `getColumnHeaderClasses` | `(column: ColumnDefinition) => string[]` | | | `getPreviousVisibleColumn` | `(column: ColumnDefinition) => ColumnDefinition \| null` | | | `getColumnDataRowClasses` | `(rowId: string) => string[]` | | | `getColumnHeaderInnerWrapperClasses` | `(column: ColumnDefinition) => string[]` | | | `forceHighlightedColumn` | `boolean` | | | `addColumnOptionsSearch` | `string` | | | `onAddColumnOptionClick` | `(columnProperty: string, previousColumnProperty: string) => void` | | | `onAddColumnSearch` | `(value: string) => void` | | | `currentHoveredColumn` | `string \| null` | | | `currentHoveredRow` | `string \| null` | | | `setCurrentHoveredCell` | `(columnProperty: string \| null, rowId: string) => void` | | | `isPrimaryColumn` | `(column: ColumnDefinition) => boolean` | | | `emptyData` | `{}[]` | | | `getRealIndex` | `(index: number) => number` | | | `isDragging` | `boolean` | | | `filterChildViews` | `{ name: string; title: string; }[]` | | | `removeFilter` | `(id: string) => void` | | | `addOption` | `(filterId: string, optionId: string) => void` | | | `removeOption` | `(filterId: string, optionId: string) => void` | | | `isOptionSelected` | `(filterId: string, optionId: string) => boolean` | | | `handleSearchUpdate` | `(value: string) => void` | | ## Best practices **Do** - Provide a unique `id` field for every row in the data source. - Use increments of 100 for column positions to leave room for inserting columns later. - Enable sorting only on columns where it is meaningful. - Use server-side pagination and keep the current page's data source small for large datasets. - Show the loading state while data is being fetched. - Set the `caption` prop to describe the table for screen readers. **Don't** - Do not expect the table to manage its own data, sorting, or pagination state. - Do not load an entire large dataset into the data source at once. - Do not offer long or irrelevant filter option lists. ## Behavior - **Data Table** is a dumb component: it renders data and emits events but keeps no internal state. - All data and UI state, including current page, page size, sort column and direction, applied filters, search term, and selected rows, must be provided through props. - User interactions such as sorting, filtering, pagination, search, and selection emit events that the parent must handle to update the data. - Set `isLoading` to true while fetching data so the table shows skeleton placeholders, then set it back to false when the data arrives. - When data management is repeated across several tables, wrap the component to centralize fetching, state, and event handling. ## Accessibility - Use the `caption` prop to provide a descriptive summary of the table for screen readers. - Keep column labels clear so the purpose of each column is understandable on its own. # Datepicker ```vue ``` ## Usage **Datepicker** is a calendar-style input for choosing a date, a time, or both together. Use it when a structured picker is safer and faster than freeform date input, and use range mode when users need to define a start and end date in one field. ```ts import { MtDatepicker } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Date only ```vue ``` ### Time only ```vue ``` ### Range ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ------------------ | -------------------------------------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | `label` | `string \| null` | `null` | A label for your date picker field. It helps the user understand what this field is for. | | `date-type` | `"datetime" \| "date" \| "time"` | `"datetime"` | Defines the type of the date picker. Options: "date" (for selecting a date), or "datetime" (for selecting both). | | `locale` | `string` | `"de"` | Sets the locale for the date picker. This affects things like the language used for month names and weekdays. | | `format` | `string \| ((date: Date) => string) \| ((dates: Date[]) => string) \| undefined` | `undefined` | The format of the date picker. You can use a string or a function to format the date. | | `time-zone` | `string` | `"UTC"` | Defines the time zone for the date picker. Useful for adjusting date and time according to a specific timezone. | | `model-value` | `string \| string[] \| Date \| Date[] \| null` | `null` | The value of the date picker. Can be a single string or an array of strings. This represents the currently selected date(s). | | `placeholder` | `string` | `"Y-m-d ..."` | Placeholder text to show in the date picker input field when no date is selected. | | `is24` | `boolean` | `true` | Determines if the timepicker is in 24 or 12 hour format | | `required` | `boolean` | `false` | Determines if the date picker field is required. If true, the user must select a value before submitting the form. | | `disabled` | `boolean` | `false` | Determines if the date picker field is disabled. If true, the user will not be able to interact with the field. | | `range` | `boolean` | `false` | Enables the date range selection feature. If true, the user can select a start and end date. | | `size` | `"small" \| "default"` | `"default"` | Sets the size of the datepicker. Options: "small" or "default". | | `error` | `{ code?: number \| undefined; detail?: string \| undefined; } \| null` | `null` | An error in your business logic related to this field. For example: {"code": 500, "detail": "Error while saving"} | | `help-text` | `string` | `undefined` | Help text for the date picker. | | `min-date` | `string \| Date` | `undefined` | The minimum selectable date. Can be a Date object or an ISO string. Any date before this will be disabled in the calendar. For example: "today" | | `hour-increment` | `number` | `1` | The increment for hours in the time picker grid. Controls how many hours are skipped when navigating through the hours overlay. | | `minute-increment` | `number` | `1` | The increment for minutes in the time picker grid. Controls how many minutes are skipped when navigating through the minutes overlay. | | `text-input` | `boolean` | `false` | Enables typing directly into the input field. | | `max-date` | `string \| Date` | `undefined` | The maximum selectable date. Can be a Date object or an ISO string | ### Events | Event | Payload | Description | | ------------------- | ----------------------------------------------------------- | ----------- | | `update:modelValue` | `[value: string \| string[] \| (string \| null)[] \| null]` | | ## Best practices **Do** - Match the `dateType` to the value users actually need, such as `date`, `time`, or `datetime`. - Use a clear label so users know what event, deadline, or schedule the value belongs to. - Set the timezone intentionally when the chosen value is shared across regions or systems. **Don't** - Do not use **Datepicker** when a plain text field is enough for a non-date value. - Do not expose time selection if the feature only needs a date. - Do not leave timezone behavior implicit when it affects saved values. ## Behavior - `dateType` controls whether the picker behaves as a date, time, or datetime input. - `range` lets one field hold a start and end value. - `timeZone` affects how values are interpreted and displayed. - `helpText`, `required`, `disabled`, `error`, and `size` integrate with the shared field styling. ## Accessibility - Always provide a visible label so users understand what date or time they are setting. - Use the simplest picker mode that fits the task, because extra controls increase interaction cost. - If timezone matters for the saved value, explain that nearby instead of relying only on the hint. # Email Field ```vue ``` ## Usage **Email Field** is a form input for entering a single email address. Use it when the value should be an email address and browser email keyboards, autofill, or native validation improve the input flow, such as account settings, contact forms, invitations, or other flows that store one address. ```ts import { MtEmailField } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Disabled ```vue ``` ### Error ```vue ``` ### Hint ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ---------------------- | --------------------- | ------- | ------------------------------------------------------------------------------------ | | `disabled` | `boolean` | | | | `required` | `boolean` | | | | `model-value` | `string` | | | | `name` | `string` | | | | `label` | `string` | | | | `error` | `{ detail: string; }` | | | | `help-text` | `string` | | | | `copyable` | `boolean` | | | | `copyable-tooltip` | `boolean` | | | | `placeholder` | `string` | | | | `small` | `boolean` | | | | `is-inherited` | `boolean` | | | | `is-inheritance-field` | `boolean` | | | | `hint` | `string \| null` | | Optional caption below the field. The \`#hint\` slot takes precedence when provided. | ### Events | Event | Payload | Description | | ------------------- | ------------------------------ | ----------- | | `update:modelValue` | `[value: string \| undefined]` | | ### Slots | Slot | Bindings | Description | | -------- | -------- | ----------- | | `prefix` | `{}` | | | `suffix` | `{}` | | | `hint` | `{}` | | ## Best practices **Do** - Use a clear label such as `Email address` or `Work email`. - Add help text when users need context about how the address will be used. - Use the shared field features such as `error`, `hint`, or inheritance only when they add real value. **Don't** - Do not use **Email Field** for general text input. - Do not rely on the placeholder as the only label. - Do not use it for multiple addresses in one field. ## Behavior - **Email Field** uses a native `type="email"` input and checks browser validity on blur. - `copyable` adds a copy button for read-only or reference-heavy flows where copying the address is useful. - The component supports shared field patterns such as `prefix`, `suffix`, `hint`, `helpText`, `error`, and inheritance handling. ## Accessibility - Always provide a visible label so users understand what address is expected. - Native email input behavior can improve keyboard and autofill support, especially on mobile devices. ## Related components - [**Text Field**](https://meteor.shopware.com/components/text-field): when the value is general text and should not be constrained to an email format. # Empty State ```vue ``` ## Usage **Empty State** is a placeholder surface for a list, page section, or feature that has no content to show yet. Use it when users need context about why the area is empty and what they can do next, such as first-time setup, filtered no-results moments, or empty collections. ```ts import { MtEmptyState } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### With action Add a link and a button so users can recover from the empty state. ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ---------------- | -------------------------- | ------------ | ----------- | | `headline` \* | `string` | | | | `description` \* | `string` | | | | `icon` \* | `string` | | | | `link-href` | `string` | | | | `link-text` | `string` | | | | `link-type` | `"external" \| "internal"` | `"internal"` | | | `button-text` | `string` | | | | `centered` | `boolean` | `false` | | ### Events | Event | Payload | Description | | -------------- | ------- | ----------- | | `button-click` | `any[]` | | ### Slots | Slot | Bindings | Description | | -------- | -------- | ----------- | | `button` | `{}` | | ## Best practices **Do** - Use a headline and description that explain the empty situation clearly. - Add one relevant next step, such as a [**Link**](https://meteor.shopware.com/components/link) or primary button, when users can recover from the empty state. - Choose an icon that supports the message without becoming the main focus. **Don't** - Do not use **Empty State** for critical warnings or error-heavy states. - Do not overload the component with multiple competing actions. - Do not leave users without context about why the area is empty. ## Behavior - **Empty State** combines an icon, headline, description, and optional recovery action in one surface. - A text link and a button can be shown when users should navigate or create something from the empty state. - The `button` slot can replace the default action button when a custom button is needed. ## Accessibility - Keep the headline and description clear enough to explain the empty situation without relying on the icon. - Use action text that describes the next step clearly, especially when the state blocks progress. - Make sure linked or button-based recovery actions are keyboard reachable and specific. # Entity Data Table ::warning **Experimental.** The API may still change in a future release. It builds on [**Data Table**](https://meteor.shopware.com/components/data-table) . :: ```vue ``` ## Usage **Entity Data Table** is a repository-backed [**Data Table**](https://meteor.shopware.com/components/data-table) for rows that come from an Admin SDK entity repository. Use it when you want searching, sorting, pagination, and filtering to refetch automatically, plus built-in row selection and bulk-action wiring. Define `availableFilters` only for the filters users actually need, and handle `open-details`, `bulk-delete`, and `bulk-edit` in the parent component. ```ts import { MtEntityDataTable } from "@shopware-ag/meteor-component-library"; ``` ## API reference ### Props | Prop | Type | Default | Description | | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ----------- | | `entity` \* | `keyof EntitySchema.Entities` | | | | `columns` \* | `ColumnDefinition[]` | | | | `repository` | `((entityName: EntityName) => { search: (criteria: default, context?: ApiContext \| undefined) => Promise \| null>; get: (id: string, context?: ApiContext \| undefined, criteria?: default \| undefined) => Promise \| null>; save: (entity: Entity, context?: ApiContext \| undefined) => Promise; clone: (entityId: string, contextOrBehavior?: any, behaviorOrContext?: any) => Promise; hasChanges: (entity: Entity) => Promise; saveAll: (entities: default, context?: ApiContext \| undefined) => Promise; delete: (entityId: string, context?: ApiContext \| undefined) => Promise; create: (context?: ApiContext \| undefined, entityId?: string \| undefined) => Promise \| null>; }) \| undefined` | | | | `force-real-modal` | `boolean` | | | | `column-changes` | `Record` | | | | `title` | `string` | | | | `subtitle` | `string` | | | | `layout` | `"default" \| "full"` | | | | `allow-bulk-delete` | `boolean` | | | | `allow-bulk-edit` | `boolean` | | | | `allow-row-selection` | `boolean` | | | | `bulk-edit-more-actions` | `{ id: string; label: string; onClick: () => void; icon?: string \| undefined; type?: any; metaCopy?: string \| undefined; contextualDetail?: string \| undefined; }[] \| undefined` | | | | `disable-delete` | `boolean` | | | | `disable-edit` | `boolean` | | | | `disable-search` | `boolean` | | | | `disable-settings-table` | `boolean` | | | | `additional-context-buttons` | `{ type?: "default" \| "critical" \| "active" \| undefined; label: string; key: string; }[]` | | | | `caption` | `string` | | | | `pagination-options` | `number[]` | | | | `available-filters` | `AvailableFilter[]` | | | ### Events | Event | Payload | Description | | -------------- | ------------------------ | ----------- | | `open-details` | `[row: { id: string; }]` | | | `bulk-delete` | `[rowIds: string[]]` | | | `bulk-edit` | `[rowIds: string[]]` | | ## Best practices **Do** - Let the wrapper own repository-backed table state. - Define `availableFilters` only for filters users actually need. - Handle `open-details`, `bulk-delete`, and `bulk-edit` in the parent component. **Don't** - Do not use it when the parent must fully own fetching and table state. - Do not duplicate repository search, sort, pagination, or filter handling in the parent component. - Do not use it for local-only datasets where plain [**Data Table**](https://meteor.shopware.com/components/data-table) is enough. ## Behavior - Data is fetched on mount. - The table refetches when page, limit, sort, search, or filters change. - `availableFilters` generates the filter UI for repository-backed filters. - Bulk actions emit the currently selected row ids. ## Accessibility - Give the table a meaningful `title` or surrounding heading. - Keep column labels and filter labels clear and specific. ## Related components - [**Data Table**](https://meteor.shopware.com/components/data-table): when the parent component should own fetching and state management. # Entity Select ```vue ``` ## Usage **Entity Select** is a repository-backed select that loads its options from an Admin SDK entity repository. Use it when options should come from a repository and you want built-in search and pagination for the results, or when an existing `modelValue` should be hydrated to a visible selected label. ```ts import { MtEntitySelect } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### With initial value ```vue ``` ### Multi-selection ```vue ``` ### Disabled ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ----------- | | `entity` \* | `keyof EntitySchema.Entities` | | | | `repository` | `((entityName: EntityName) => { search: (criteria: default, context?: ApiContext \| undefined) => Promise \| null>; get: (id: string, context?: ApiContext \| undefined, criteria?: default \| undefined) => Promise \| null>; save: (entity: Entity, context?: ApiContext \| undefined) => Promise; clone: (entityId: string, contextOrBehavior?: any, behaviorOrContext?: any) => Promise; hasChanges: (entity: Entity) => Promise; saveAll: (entities: default, context?: ApiContext \| undefined) => Promise; delete: (entityId: string, context?: ApiContext \| undefined) => Promise; create: (context?: ApiContext \| undefined, entityId?: string \| undefined) => Promise \| null>; }) \| undefined` | `undefined` | | | `model-value` | `any` | `null` | | | `label-property` | `string \| string[]` | `"name"` | | | `value-property` | `string` | `"id"` | | | `disabled` | `boolean` | `false` | | | `enable-multi-selection` | `boolean` | `false` | | ### Events | Event | Payload | Description | | ------------------- | -------------- | ----------- | | `update:modelValue` | `[value: any]` | | ## Best practices **Do** - Pass `entity` for the default repository lookup. - Use `repository` only when you need custom fetching behavior. - Keep `labelProperty` and `valueProperty` aligned with the entity shape you want to show and store. **Don't** - Do not use it when options are already available locally. - Do not duplicate search or pagination in the parent component. - Do not assume `modelValue` stores the whole entity by default. ## Behavior - The first page loads on mount. - Search is handled through repository term lookups. - `modelValue` stores the selected `valueProperty`, which defaults to `id`. ## Accessibility - Use a clear visible field label so users understand what entity they are selecting. - Keep result labels distinct so search results stay easy to understand. ## Related components - [**Select**](https://meteor.shopware.com/components/select): when options come from local or externally managed lists. # Floating UI ```vue ``` ## Usage **Floating UI** is a low-level primitive for building custom popover-style surfaces such as rich pickers, menus, inspectors, or inline tools, with automatic positioning relative to a trigger element. Use it when higher-level components such as [**Action Menu**](https://meteor.shopware.com/components/action-menu) do not fit the custom floating interaction you need. ```ts import { MtFloatingUi } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Multiple anchors Use `detached` mode together with `anchorElement` to share one floating surface across multiple triggers. The floating panel repositions itself to each anchor as the user hovers, and a short close delay keeps it reachable when the cursor travels from trigger to panel. ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------- | | `is-opened` \* | `boolean` | | | | `floating-ui-options` | `Partial<{ placement?: Placement \| undefined; strategy?: Strategy \| undefined; middleware?: (false \| { name: string; options?: any; fn: (state: { placement: Placement; platform: Platform; strategy: Strategy; x: number; y: number; initialPlacement: Placement; middlewareData: MiddlewareData; rects: ElementRects; elements: Elements; }) => Promisable; } \| null \| undefined)[] \| undefined; platform?: Platform \| undefined; }> \| undefined` | | | | `show-arrow` | `boolean` | | | | `offset` | `number` | | | | `auto-update-options` | `Partial` | | | | `match-reference-width` | `boolean` | | If true, the floating UI content will match the width of the reference element. | | `anchor-element` | `HTMLElement \| null` | | An external DOM element to anchor the floating content to, instead of the built-in trigger slot wrapper | | `detached` | `boolean` | | When true, the trigger slot is not rendered and the root wrapper is not displayed Use with \`anchorElement\`. | ### Events | Event | Payload | Description | | ------- | ------- | ----------- | | `close` | `[]` | | ### Slots | Slot | Bindings | Description | | --------- | -------------------------------------------------------------------- | ----------- | | `trigger` | `{}` | | | `default` | `{ referenceElementWidth: number; referenceElementHeight: number; }` | | ## Best practices **Do** - Manage the open state outside the component and update it through `isOpened` and the `close` event. - Provide a clear trigger element so users understand what opens the floating surface. - Style the slotted content as a complete surface, including background, border, spacing, and shadow. - Use `matchReferenceWidth` when the floating surface should align to the trigger width. **Don't** - Do not use **Floating UI** when a higher-level component such as [**Action Menu**](https://meteor.shopware.com/components/action-menu) already fits the use case. - Do not rely on it to provide a finished surface design. It only handles positioning and behavior. - Do not forget to handle keyboard and focus behavior for custom interactive content. ## Behavior - **Floating UI** teleports its content to `body`, so the floating surface can escape clipping and stacking issues in the local layout. - It uses Floating UI middleware to offset, flip, and measure the floating surface automatically. - `showArrow` adds an arrow element, but the slotted content still needs to provide the actual surface styling. - The default slot receives `referenceElementWidth` and `referenceElementHeight`, which help when the floating content needs to size itself relative to the trigger. - `matchReferenceWidth` sets the floating container width to the trigger width automatically. ## Accessibility - Make sure the trigger clearly communicates what it opens. - If the floating content contains interactive controls, manage focus and keyboard behavior intentionally. - Provide visible structure and labels inside the floating surface so the custom content stays understandable once opened. ## Related components - [**Popover**](https://meteor.shopware.com/components/popover): when the standard popover styling and interaction model already fit. - [**Action Menu**](https://meteor.shopware.com/components/action-menu): when you need a standard menu of actions or options. # Help Text ```vue ``` ## Usage **Help Text** is a small help trigger that reveals brief supporting guidance in a tooltip. Use it next to a label or control for short explanatory details that are helpful but not essential at first glance, keeping interfaces compact while still offering lightweight guidance. ```ts import { MtHelpText } from "@shopware-ag/meteor-component-library"; ``` ## API reference ### Props | Prop | Type | Default | Description | | ------------ | -------- | ------- | ----------- | | `text` \* | `string` | | | | `width` | `number` | | | | `show-delay` | `number` | `0` | | | `hide-delay` | `number` | `150` | | | `placement` | `any` | | | ## Best practices **Do** - Use **Help Text** for brief, supplementary explanations. - Place it near the element it describes, such as next to a label. - Keep the tooltip text short and specific so users can understand it quickly. **Don't** - Do not use **Help Text** for critical information users must always see. - Do not put lengthy content in the tooltip. - Do not use it as a substitute for a clear label or necessary inline guidance. ## Behavior - **Help Text** uses a [**Tooltip**](https://meteor.shopware.com/components/tooltip) internally and shows the provided text on hover or keyboard focus. - `placement`, `width`, `showDelay`, and `hideDelay` can adjust how the tooltip behaves. - The trigger is a small icon button, so the content should stay concise and contextual. ## Accessibility - Only use **Help Text** for optional supporting guidance, not for instructions users must read to complete a task. - Keep the tooltip text short enough to be understood quickly when focus moves to the trigger. - Make sure the nearby label or surrounding UI still makes sense without opening the tooltip. ## Related components - [**Tooltip**](https://meteor.shopware.com/components/tooltip): when you need more flexible tooltip behavior or a different trigger element. # Icon ```vue ``` ## Usage **Icon** renders an SVG glyph from the Meteor icon kit for compact visual cues that support a label, action, or state. Use it when an icon should be rendered consistently through the component library, with color and sizing following design tokens instead of ad-hoc inline SVG usage. To browse the full icon set, search by name, and review icon philosophy and common usage patterns, see the [Icons](https://meteor.shopware.com/documentation/design/icons) reference. ```ts import { MtIcon } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Mode ```vue ``` ### Sizes ```vue ``` ### Colors ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ------------ | ---------------------- | ----------- | ----------- | | `name` \* | `string` | | | | `color` | `string` | `undefined` | | | `decorative` | `boolean` | `false` | | | `size` | `string` | `undefined` | | | `mode` | `"regular" \| "solid"` | `"regular"` | | ## Behavior - `name` can include the icon mode directly, such as `regular-products` or `solid-pencil-s`. - `mode` is available when the name itself does not already include the `regular-` or `solid-` prefix, for example `name="calendar" mode="solid"`. - Prefer the explicit `mode` prop in docs and app code when it makes the chosen variant easier to read at a glance. - `solid` icons usually work better for very small sizes and for larger decorative icon use, while `regular` icons are often a better default for standard interface actions and supporting UI. - `size` accepts pixel strings and plain numeric values, which are normalized to pixel sizes. - Icons inherit `currentColor`, so using icon color tokens keeps them aligned with the theme and state tokens used elsewhere in the library. ## Accessibility - Use `decorative` for icons that are purely visual and already explained by surrounding text. - If an icon communicates meaning on its own, make sure that meaning is still available through visible text or accessible labeling on the parent control. - Do not depend on icon color alone to convey success, warning, or error states. ## Related - [Icons](https://meteor.shopware.com/documentation/design/icons): browse the full icon set, search by name, and review icon philosophy and common usage patterns. # Link ```vue ``` ## Usage **Link** is a text-level navigation control that moves users to another page, route, or destination. Use it for inline links, secondary navigation, and text-level actions where the destination should feel lightweight and text-like instead of button-like, and use the `type` prop when an internal or external destination should be signaled visually. ```ts import { MtLink } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Critical ```vue ``` ### Disabled ```vue ``` ### External ```vue ``` ### Internal ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ---------- | -------------------------- | --------------- | ----------- | | `to` | `string` | | | | `as` | `string` | `"router-link"` | | | `variant` | `"primary" \| "critical"` | `"primary"` | | | `disabled` | `boolean` | `false` | | | `type` | `"external" \| "internal"` | | | ### Events | Event | Payload | Description | | ------- | --------------------- | ----------- | | `click` | `[event: MouseEvent]` | | ### Slots | Slot | Bindings | Description | | --------- | -------- | ----------- | | `default` | `{}` | | ## Best practices **Do** - Use link text that clearly describes the destination or result. - Use the `type` prop when an internal or external destination should be signaled visually. - Keep **Link** close to the content or context it belongs to. **Don't** - Do not use **Link** for actions that stay on the current page. - Do not use vague text such as `Click here` when the destination matters. - Do not disable a link unless removing navigation is genuinely necessary. ## Behavior - **Link** can render different elements through the `as` prop and defaults to a `router-link`. - `variant` changes the visual emphasis, while `type` can add an internal or external direction cue. - `disabled` removes the active destination and click behavior. ## Accessibility - Link text should make sense out of context so screen reader users can understand the destination. - Use **Link** only when the control actually navigates somewhere. - Make sure disabled links are used sparingly, since unavailable navigation can be confusing. ## Related components - [**Button**](https://meteor.shopware.com/components/button): when the user should trigger an action on the current page. # Loader ```vue ``` ## Usage **Loader** is an indeterminate loading indicator shown while content, a card, or a control is waiting for async work to finish. Use it when the loading duration is uncertain and a simple busy indicator is enough, in places where users should stay in context instead of being redirected to a separate loading screen. ```ts import { MtLoader } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### With text ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ------------- | ------------------- | -------- | ----------- | | `size` | `` `${string}px` `` | `"50px"` | | | `title` | `string` | | | | `description` | `string` | | | | `backdrop` | `boolean` | `true` | | ## Best practices **Do** - Keep the loading state brief and replace it with real content as soon as possible. - Use a size that fits the surrounding surface, such as a compact loader inside controls and a larger loader in content areas. - Use `title` and `description` when users need short context for what is loading. - Pair **Loader** with disabled or blocked interactions when the underlying surface should not be used while loading. - Place it inside a bounded surface that provides the context for what is loading. **Don't** - Do not use **Loader** when you can show real progress with a percentage or completed amount. - Do not leave **Loader** visible for long-running tasks without additional context or feedback. - Do not use it as the only way to explain what is happening when the wait may take noticeable time. ## Behavior - **Loader** is an indeterminate indicator. It does not expose a value or completion state. - The component centers itself and renders as an absolute overlay with a semi-transparent background, so it works best inside the surface that is being loaded. - `size` accepts pixel values such as `16px`, `32px`, or `48px`, and the ring thickness adapts to the provided size. - `backdrop` controls whether **Loader** renders its backdrop background and defaults to `true`. - `title` and `description` render below the spinner as centered body text and can be used independently. ## Accessibility - **Loader** is visual only and does not announce loading state to assistive technologies on its own. - `title` and `description` provide visible context, but the surrounding region should still expose an appropriate busy state when the loading state matters for screen-reader users. - If loading blocks interaction, also disable or otherwise guard the affected controls so keyboard users are not left guessing what is available. ## Related components - [**Progress Bar**](https://meteor.shopware.com/components/progress-bar): when you can communicate meaningful progress such as processed items, uploaded bytes, or percentage complete. # Modal ```vue ``` ## Usage **Modal** is a dialog that sits above the current page to focus attention on a single task or decision. Use it for flows that need clear interruption, such as confirmations, forms, or important details, when users need to complete a focused task without leaving the current page and the content should sit above the rest of the interface instead of becoming part of the page layout. ```ts import { MtModal, MtModalRoot, MtModalTrigger, MtModalClose, MtModalAction, } from "@shopware-ag/meteor-component-library"; ``` ## Anatomy **Modal** is built from a small set of companion exports that work together: - `mt-modal-root` wraps all related modal components and controls whether the modal is visible. - `mt-modal` renders the modal surface and content container. - `mt-modal-trigger` defines the element that opens the modal when clicked, usually a [**Button**](https://meteor.shopware.com/components/button). - `mt-modal-action` performs an action before closing the modal, most often for confirm flows. - `mt-modal-close` closes the modal when clicked. These parts are exported together so the pattern can be composed in one place. ## Composition In most cases you open a modal through a trigger. Wrap the related parts in `mt-modal-root`: ```html ``` To run work before the modal closes, such as a network request, use `mt-modal-action`. Its click handler receives a `done` callback that closes the modal when you call it: ```html ``` ### Controlled state To open a modal from something other than a trigger, control the open state directly with the `isOpen` prop on `mt-modal-root`: ```html ``` ## API reference ### Props | Prop | Type | Default | Description | | ------------- | ------------------------------------- | ----------- | ----------- | | `width` | `"s" \| "m" \| "l" \| "xl" \| "full"` | `"m"` | | | `title` | `string` | `undefined` | | | `subtitle` | `string` | `undefined` | | | `inset` | `boolean` | `false` | | | `hide-header` | `boolean` | `false` | | ### Slots | Slot | Bindings | Description | | -------------- | -------- | ----------- | | `header-left` | `{}` | | | `title-after` | `{}` | | | `header-right` | `{}` | | | `default` | `{}` | | | `footer` | `{}` | | ## Best practices **Do** - Keep modal content focused on a single task or decision. - Use a clear title and footer actions so users understand how to continue or cancel. - Choose a modal width that matches the amount of content. **Don't** - Do not overload a modal with several unrelated tasks. - Do not use a modal when inline content or a dedicated page would be easier to understand. - Do not make closing behavior ambiguous. ## Behavior - `mt-modal-root` controls whether the modal is mounted and visible. - `mt-modal-trigger`, `mt-modal-action`, and `mt-modal-close` support common opening and closing flows. - `mt-modal-action` receives a `done` callback so you can run work, such as a network request, before the modal closes. - Use the `isOpen` prop on `mt-modal-root` to control the open state directly when something other than a trigger opens the modal. - Footer actions are usually the clearest place for confirmation and cancellation controls. ## Accessibility - Use a clear title so users immediately understand the purpose of the dialog. - Keep focus behavior predictable and ensure footer actions are reachable by keyboard. - Only use **Modal** when interrupting the current flow is justified by the task. # Number Field ```vue ``` ## Usage **Number Field** is a numeric input control for values that should be numeric, such as quantities, counts, percentages, or other values that benefit from step-based input. Use it when min and max limits should guide valid input. ```ts import { MtNumberField } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Disabled ```vue ``` ### Error ```vue ``` ### Hint ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ---------------------------- | ---------------------------------------- | ----------- | --------------------------------------------------------------------------------------------- | | `label` | `string` | `null` | A label for your text field. Usually used to guide the user what value this field controls. | | `placeholder` | `string` | `""` | A placeholder text being displayed if no value is set. | | `disabled` | `boolean` | `false` | Determines if the field is disabled. | | `error` | `Record` | `null` | An error in your business logic related to this field. | | `hint` | `string \| null` | `null` | Optional caption below the field. The \`#hint\` slot takes precedence when provided. | | `name` | `string` | `null` | | | `required` | `boolean` | `false` | Determines if the field is required. | | `help-text` | `string` | `null` | A text that helps the user to understand what this field does. | | `size` | `"default" \| "small"` | `"default"` | The size of the text field. The size of the number field. | | `is-inherited` | `boolean` | `false` | Toggles the inheritance visualization. | | `is-inheritance-field` | `boolean` | `false` | Determines if the field is inheritable. | | `disable-inheritance-toggle` | `boolean` | `false` | Determines the active state of the inheritance toggle. | | `id-suffix` | `string` | `""` | | | `model-value` | `number` | `null` | The value of the text field. The value of the number field. | | `copyable` | `boolean` | `false` | Toggles the copy function of the text field. | | `copyable-tooltip` | `boolean` | `false` | If set to true the tooltip will change on successful copy. | | `max-length` | `number` | `undefined` | If set to a value a character counter will be displayed. | | `number-type` | `"float" \| "int"` | `"float"` | Defines if the number should be a floating point number or integer. | | `step` | `number` | `null` | Defines the amount of which the number is increased or decreased per step. | | `min` | `number` | `null` | Defines the minimum value of the number. | | `max` | `number` | `null` | Defines the maximum value of the number. | | `digits` | `number` | `2` | Defines how many digits should be displayed after the decimal point. | | `fill-digits` | `boolean` | `false` | Defines if digits should be filled with zeros if the value is smaller than the minimum value. | | `allow-empty` | `boolean` | `undefined` | Defines if the field can be empty. | | `number-align-end` | `boolean` | `false` | Defines if the number should be aligned to the end of the input field. | | `show-controls` | `boolean` | `true` | Defines if the control arrows should be visible. | | `on-update:model-value` | `((...args: any[]) => any) \| undefined` | | | | `on-change` | `((...args: any[]) => any) \| undefined` | | | | `on-inheritance-restore` | `((...args: any[]) => any) \| undefined` | | | | `on-inheritance-remove` | `((...args: any[]) => any) \| undefined` | | | | `on-focus` | `((...args: any[]) => any) \| undefined` | | | | `on-blur` | `((...args: any[]) => any) \| undefined` | | | | `on-input-change` | `((...args: any[]) => any) \| undefined` | | | ### Exposed | Name | Type | Description | | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | | `t` | `ComposerTranslation<{ en: { increaseButton: string; decreaseButton: string; }; de: { increaseButton: string; decreaseButton: string; }; }, "en" \| "de", RemoveIndexSignature<{ [x: string]: LocaleMessageValue; }>, never, "increaseButton" \| "decreaseButton", "increaseButton" \| "decreaseButton">` | | | `currentValue` | `string \| number` | | | `hasFocus` | `boolean` | | | `rawUserInput` | `string \| null` | | | `showFieldHint` | `boolean` | | | `hasError` | `boolean` | | | `hasDisabledInput` | `boolean` | | | `realStep` | `number` | | | `realMinimum` | `number \| null` | | | `realMaximum` | `number \| null` | | | `stringRepresentation` | `string` | | | `controlClasses` | `{ "mt-field__controls--disabled": boolean; "mt-field__controls--has-error": boolean; "mt-field__controls--small": boolean; }` | | | `allowEmptyWithDefault` | `boolean` | | | `onInput` | `((event: Event) => void) & ((event: Event) => void)` | | ## Best practices **Do** - Use a clear label that explains what the number represents. - Configure `step`, `min`, and `max` when the range is known. - Choose the right `numberType` for integer or decimal input. **Don't** - Do not use **Number Field** for values that are identifiers but look numeric. - Do not use it when users need to pick both a number and a unit together. - Do not hide important limits from users if the field enforces them. ## Behavior - **Number Field** builds on the shared field base and adds numeric parsing, stepping, and optional arrow controls. - `numberType`, `digits`, `fillDigits`, and `numberAlignEnd` help tune how numeric values are entered and displayed. - `showControls` can show increase and decrease buttons for step-based adjustment. ## Accessibility - Always provide a visible label that explains the meaning of the number. - Use help text when users need context about valid ranges, units, or rounding. - Make sure any min, max, or step behavior matches the expectations shown in the UI. ## Related components - [**Text Field**](https://meteor.shopware.com/components/text-field): when numeric-looking content should stay as plain text. # Pagination ```vue ``` ## Usage **Pagination** is a control for moving through larger result sets one page at a time, letting users move forward, backward, or jump to a specific page. Use it alongside data tables, result lists, or overview pages with many items when a list or table is split into pages. ```ts import { MtPagination } from "@shopware-ag/meteor-component-library"; ``` ## API reference ### Props | Prop | Type | Default | Description | | ----------------- | -------- | ------- | ----------- | | `current-page` \* | `number` | | | | `limit` \* | `number` | | | | `total-items` \* | `number` | | | ### Events | Event | Payload | Description | | --------------------- | ----------------- | ----------- | | `change-current-page` | `[value: number]` | | ## Best practices **Do** - Keep `limit` and `totalItems` in sync with the actual dataset. - Reset back to the first page when the page size or result set changes significantly. - Place **Pagination** close to the content it controls. **Don't** - Do not use **Pagination** when all items comfortably fit in one view. - Do not use **Pagination** for exploratory browsing patterns where users are expected to keep discovering content continuously. Infinite scrolling may fit better there. - Do not leave the current page disconnected from the visible result range. - Do not mix pagination with infinite scrolling in the same content area. ## Behavior - **Pagination** displays the current visible range, for example `1-25 of 100`. - It emits `change-current-page` when users navigate with the buttons or by typing a page number. - Changing `limit` resets the current page back to `1`. ## Accessibility - Navigation buttons include accessible labels for first, previous, next, and last page. - Keep **Pagination** near the content it updates so the relationship stays clear. - Make sure page changes also update the visible content in a predictable way for keyboard and screen-reader users. # Password Field ```vue ``` ## Usage **Password Field** is a masked input for passwords, secrets, or other credential input that can optionally reveal its value when users need to confirm briefly what they typed. Use it in sign-in, account setup, or credential update flows. ```ts import { MtPasswordField } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Disabled ```vue ``` ### Error ```vue ``` ### Hint ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ---------------------------- | ------------------------------------------- | ----------- | ----------- | | `label` | `string \| null` | `null` | | | `placeholder` | `string` | `""` | | | `disabled` | `boolean` | | | | `error` | `{ code: number; detail: string; } \| null` | `null` | | | `hint` | `string \| null` | `null` | | | `toggable` | `boolean` | `true` | | | `name` | `string` | `undefined` | | | `required` | `boolean` | `false` | | | `help-text` | `string` | `""` | | | `size` | `"default" \| "small"` | `"default"` | | | `is-inherited` | `boolean` | `false` | | | `is-inheritance-field` | `boolean` | `false` | | | `disable-inheritance-toggle` | `boolean` | `false` | | | `id-suffix` | `string` | `""` | | | `model-value` | `string` | | | ### Events | Event | Payload | Description | | --------------------- | ------------------------------ | ----------- | | `update:modelValue` | `[value: string \| undefined]` | | | `submit` | `[]` | | | `change` | `[value: string \| undefined]` | | | `inheritance-restore` | `[value: unknown]` | | | `inheritance-remove` | `[value: unknown]` | | ### Slots | Slot | Bindings | Description | | -------- | -------- | ----------- | | `prefix` | `any` | | | `suffix` | `any` | | | `hint` | `any` | | ## Best practices **Do** - Use a clear label such as `Password` or `New password`. - Add help text or hint content when users need password rules. - Keep the visibility toggle enabled when it helps users avoid typing mistakes. **Don't** - Do not use **Password Field** for non-sensitive text. - Do not rely on placeholder text as the only instruction. - Do not hide password requirements if the field enforces them. ## Behavior - **Password Field** masks input by default and can reveal the value with the visibility toggle when `toggable` is enabled. - The component supports shared field patterns such as `hint`, `helpText`, `error`, and inheritance handling. - It emits `submit` on Enter, which can help in credential flows. ## Accessibility - Always provide a visible label so users know what credential is expected. - Make sure the show or hide password control has a clear accessible name, especially if the field appears more than once on a page. ## Related components - [**Text Field**](https://meteor.shopware.com/components/text-field): when the value is not sensitive and does not need reveal behavior. # Popover ::warning **Experimental.** The API may still change. Prefer [**Action Menu**](https://meteor.shopware.com/components/action-menu) or [**Floating UI**](https://meteor.shopware.com/components/floating-ui) when they fit your use case. :: ```vue ``` ## Usage **Popover** is an experimental floating surface that reveals contextual settings and nested option views from a trigger. Prefer [**Action Menu**](https://meteor.shopware.com/components/action-menu) when you need a standard menu of actions or options, or **Floating UI** when you need a custom floating surface with your own layout, content, or interaction behavior, and reach for **Popover** only when neither already fits the use case. ```ts import { MtPopover, MtPopoverItem, MtPopoverItemResult, } from "@shopware-ag/meteor-component-library"; ``` ## Anatomy **Popover** is built from a small set of companion exports that work together: - `mt-popover` renders the floating surface, its header, and the view transitions, and exposes the trigger and item slots. - `mt-popover-item` renders a single row inside a view, with optional icon, switch, checkbox, options affordance, or nested view trigger. - `mt-popover-item-result` renders a grouped, draggable list of options, such as a column visibility and ordering editor. These parts are exported together so the pattern can be composed in one place. ## API reference ### Props | Prop | Type | Default | Description | | --------------- | --------------------------------------------- | ----------- | ----------- | | `width` | `"small" \| "large" \| "dynamic" \| "medium"` | `"dynamic"` | | | `title` | `string` | `""` | | | `child-views` | `View[]` | `[]` | | | `disable-float` | `boolean` | `false` | | ### Events | Event | Payload | Description | | ----------------- | ------- | ----------- | | `update:isOpened` | `any[]` | | ### Exposed | Name | Type | Description | | ------------------ | ------------------------------------------------------------------------------------------------------ | ----------- | | `goViewBack` | `() => void` | | | `currentView` | `View` | | | `activeView` | `string` | | | `changeView` | `(view: string) => void` | | | `allViews` | `View[]` | | | `viewTransition` | `"slideIn" \| "slideOut"` | | | `MtPopover` | `HTMLElement \| null` | | | `closeFloatingUi` | `() => void` | | | `toggleFloatingUi` | `() => void` | | | `isOpened` | `boolean` | | | `mainComponentTag` | `"div" \| "mt-floating-ui"` | | | `componentClasses` | `{ [x: string]: boolean; "mt-popover--float": boolean; "is--open": boolean; "has--header": boolean; }` | | | `showHeader` | `boolean` | | ## Best practices **Do** - Reach for [**Action Menu**](https://meteor.shopware.com/components/action-menu) or **Floating UI** first, and use **Popover** only when neither fits. - Keep the trigger labelled clearly so users understand what the surface contains. - Use views and nested views to keep each step focused instead of overloading a single list. **Don't** - Do not use **Popover** for the main action on a screen. - Do not nest views more deeply than the task requires. - Do not rely on icons or color alone to explain what an item does. ## Behavior - The `#trigger` slot exposes `toggleFloatingUi`, which opens and closes the surface. Stop click propagation on the trigger so the open click does not immediately close it. - Items render inside named view slots such as `#popover-items__base`. Additional views are declared through `childViews` and rendered in matching `#popover-items__` slots. - The view slots expose `changeView`, which navigates to a named view. The header shows a back button automatically for any view other than `base`. - `disableFloat` renders the content inline as a plain container instead of a floating surface, which is useful for embedding the panel without a trigger. - `width` accepts `dynamic`, `small`, `medium`, or `large` to constrain the surface width. ## Accessibility - Provide a clear accessible name on the trigger so users understand what the surface contains. - Item labels should stay understandable without depending only on icons or color. - The surface uses a dialog role, so keep focus behavior predictable when it opens and closes. ## Related components - [**Action Menu**](https://meteor.shopware.com/components/action-menu): when you need a short, scannable list of actions or options. - [**Floating UI**](https://meteor.shopware.com/components/floating-ui): when you need a custom floating surface with your own layout, content, or interaction behavior. # Progress Bar ```vue ``` ## Usage **Progress Bar** is a determinate indicator for tasks such as uploads, imports, or processing steps where completion can be measured. Use it when you can communicate a meaningful current value and maximum value, placed in context close to the content or action the progress belongs to. ```ts import { MtProgressBar } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Custom units and error ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | --------------------- | ------------------------------------------- | ----------- | ----------- | | `label` \* | `string` | | | | `max-value` \* | `number` | | | | `error` | `{ detail: string; code: number; } \| null` | | | | `progress-label-type` | `string` | `"percent"` | | | `model-value` | `number` | | | ### Events | Event | Payload | Description | | ------------------- | ------------------------------ | ----------- | | `update:modelValue` | `[value: number \| undefined]` | | ## Best practices **Do** - Provide a clear label so users understand what the progress refers to. - Keep the value and maximum meaningful, stable, and easy to reason about. - Use the default percentage label when percent is the clearest way to communicate progress. - Use `progressLabelType` when a concrete unit such as `kb` or `items` is more useful than a percentage. - Show the `error` state when progress is blocked or the related process fails. **Don't** - Do not use **Progress Bar** when the task has no measurable completion state. - Do not rely on progress color alone to communicate success or failure. - Do not feed invalid values on purpose and rely on clamping as the primary behavior. - Do not hide the surrounding context for long-running tasks that may need more explanation. ## Behavior - **Progress Bar** uses the current value and `maxValue` to calculate the filled width. - The fill width is clamped between `0%` and `100%`, so values below `0` or above the maximum do not overflow the track. - By default the progress label is shown as a percentage. When `progressLabelType` is set to another value, the label is rendered as `current unit / max unit`. - When `error` is present, the fill changes to the critical color and the error message is rendered below the track. ## Accessibility - **Progress Bar** exposes `role="progressbar"` with `aria-valuenow`, `aria-valuemin`, and `aria-valuemax`. - Provide a visible `label`, because the progressbar is associated with that label via `aria-labelledby`. - The percentage or unit label is marked `aria-hidden`, so important status information should not depend on that text alone. - If the task is especially important or long-running, pair **Progress Bar** with additional explanatory text so screen-reader and keyboard users have enough context. ## Related components - [**Loader**](https://meteor.shopware.com/components/loader): when work is in progress but the exact completion amount is unknown. # Promo Badge ```vue ``` ## Usage **Promo Badge** highlights promotional elements across our products with predefined feature labels such as `New`, `Beta`, or `Shopware AI`. Use it when a promotional label should stand out consistently without inventing a new visual treatment. ```ts import { MtPromoBadge } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Variants ```vue ``` ### Sizes ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | --------- | ---------------------------------- | ------- | ----------- | | `variant` | `"new" \| "beta" \| "shopware-ai"` | `"new"` | | | `size` | `"s" \| "m" \| "l"` | `"s"` | | ## Best practices **Do** - Use **Promo Badge** to highlight promotional elements across our products. - Keep the meaning consistent with the defined variants such as `New`, `Beta`, and `Shopware AI`. - Use **Promo Badge** sparingly so it draws attention without cluttering the interface. **Don't** - Do not use **Promo Badge** for status indicators such as error or success. Use [**Badge**](https://meteor.shopware.com/components/badge) instead. - Do not create custom promotional variants. Stick to the predefined set for consistency. - Do not make **Promo Badge** clickable, because it is not a [**Button**](https://meteor.shopware.com/components/button) or [**Link**](https://meteor.shopware.com/components/link). Showing a [**Tooltip**](https://meteor.shopware.com/components/tooltip) on hover is fine. ## Behavior - **Promo Badge** wraps [**Badge**](https://meteor.shopware.com/components/badge) and maps each promotional variant to a predefined label, icon, and badge style. - The visible text is controlled by the selected `variant`, so it stays consistent across products and languages. - The component is intentionally limited to a small set of promotional meanings rather than being a general status label. ## Accessibility - Keep the promotional meaning understandable from the text label and not from the icon alone. - Because **Promo Badge** is non-interactive, avoid using it as the only way to expose an important action. - Use it sparingly so promotional emphasis remains meaningful in dense interfaces. ## Related components - [**Badge**](https://meteor.shopware.com/components/badge): when the label represents a general product state such as status, health, or workflow. # Radio Group ```vue ``` ## Usage **Radio Group** presents a set of mutually exclusive options where only one selection is allowed. Use it when the available choices should stay visible on the page instead of being hidden in a collapsed control, and when users benefit from scanning or comparing a small number of options before choosing one. ```ts import { MtRadioGroupRoot, MtRadioGroupList, MtRadioGroupItem, MtRadioGroupCustomItem, MtRadioGroupIndicator, } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Custom item Build fully custom option cards while keeping the shared radio-group state. ```vue ``` ## Anatomy **Radio Group** is a compound component made up of several public exports: - `MtRadioGroupRoot` provides the shared label, help text, hint, error handling, and selected-value state. - `MtRadioGroupList` lays out a standard vertical list of radio items with the expected spacing. - `MtRadioGroupItem` renders the default radio option with a label. - `MtRadioGroupCustomItem` lets you build fully custom option cards while still participating in the shared radio-group state. - `MtRadioGroupIndicator` renders the actual radio input and control, and is mainly useful inside custom-item compositions. ## API reference ### Props | Prop | Type | Default | Description | | ------------------- | ------------------------------------- | ----------- | ------------------------------------------------------------------------------------ | | `model-value` | `string \| number \| boolean \| null` | `null` | | | `disabled` | `boolean` | `false` | | | `aria-described-by` | `string` | `undefined` | | | `label` | `string` | `""` | | | `help-text` | `string` | `""` | | | `name` | `string` | `undefined` | | | `error` | `{ detail: string; }` | `undefined` | | | `hint` | `string \| null` | `null` | Optional caption below the field. The \`#hint\` slot takes precedence when provided. | ### Events | Event | Payload | Description | | ------------------- | ---------------------------------------------- | ----------- | | `update:modelValue` | `[value: string \| number \| boolean \| null]` | | ### Slots | Slot | Bindings | Description | | --------- | ------------------------------------------------ | ----------- | | `hint` | `{}` | | | `default` | `{ disabled: boolean; identification: string; }` | | ## Best practices **Do** - Use clear, concise labels for each option. - Use a descriptive group label that explains what the user is selecting. - Include help text or a hint when the selection needs additional context. - Use the `error` prop to display validation errors when needed. - Ensure each radio item has a unique `id` and `value`. - Use `MtRadioGroupList` to wrap multiple `MtRadioGroupItem` components for proper spacing. - Use `MtRadioGroupCustomItem` when you need custom-styled radio options such as pricing plans or feature cards. - Keep the number of options manageable. A small visible set is the sweet spot. **Don't** - Do not use **Radio Group** for multiple selections. Use [**Checkbox**](https://meteor.shopware.com/components/checkbox) instead. - Do not use a single radio button. Radio groups should present a real choice. - Do not omit labels. Always provide clear labels for accessibility and usability. - Do not use radio groups for long lists of options where a [**Select**](https://meteor.shopware.com/components/select) would be easier to scan. - Do not use the same `value` for multiple items within the same group. - Do not forget to handle the `v-model` binding so the selected value stays in sync. ## Behavior - **Radio Group** uses `v-model` on `MtRadioGroupRoot` to manage the selected value across all items in the group. - `MtRadioGroupItem` should always be used inside `MtRadioGroupRoot`, because it depends on the shared radio-group context. - `MtRadioGroupCustomItem` gives you layout freedom, but you still need to render `MtRadioGroupIndicator` so the custom option remains a real radio control. - `helpText`, `hint`, and `error` follow the shared field patterns used by other form components. ## Accessibility - Provide a clear group label or other nearby visible context so users understand what the choice controls. - `MtRadioGroupIndicator` uses native radio inputs, so the group benefits from standard browser keyboard behavior. - Keep option labels explicit so users do not need surrounding context to understand each choice. - If you build custom items, make sure the visible content still makes the selected state and choice meaning clear. ## Related components - [**Checkbox**](https://meteor.shopware.com/components/checkbox): when users can turn an option on or off independently or choose multiple items. - [**Select**](https://meteor.shopware.com/components/select): when there are more options or when space is limited. # Search ```vue ``` ## Usage **Search** is a lightweight input that narrows down visible content as users type or confirm a search term. Use it for list views, data tables, or page-level finding tools when a simple search input is enough and a full form field wrapper is not needed. ```ts import { MtSearch } from "@shopware-ag/meteor-component-library"; ``` ## API reference ### Props | Prop | Type | Default | Description | | ------------- | ---------------------- | ----------- | ----------- | | `model-value` | `string` | | | | `placeholder` | `string` | | | | `size` | `"default" \| "small"` | `"default"` | | | `disabled` | `boolean` | | | ### Events | Event | Payload | Description | | ------------------- | ----------------- | ----------- | | `update:modelValue` | `[value: string]` | | | `change` | `[value: string]` | | ## Best practices **Do** - Place **Search** close to the content it affects. - Use a placeholder or surrounding heading that makes the search scope clear. - Keep search behavior responsive so users quickly see what changed. **Don't** - Do not use **Search** for values that should be stored as form data. - Do not use it when a labeled form field is the better semantic choice. - Do not leave the search scope ambiguous. ## Behavior - **Search** uses a native `type="search"` input and emits both `update:modelValue` and `change`. - The component is intentionally lightweight and does not include the shared field wrapper used by the form field family. - `size` can make the control more compact in dense toolbars or filter areas. ## Accessibility - Make sure the purpose of **Search** is clear from nearby visible context if the placeholder alone is not enough. - Keep the filtering result predictable so users understand what content the search affects. - Ensure keyboard users can reach the input in the same order as the content it controls. ## Related components - [**Text Field**](https://meteor.shopware.com/components/text-field): when the value should be entered and stored as regular form data. # Select ```vue ``` ## Usage **Select** lets users pick one or more values from a list of predefined options instead of entering free-form text. Use it when the list may be longer than a simple inline choice group would comfortably show, or when searching, custom option labels, or multi selection would improve the picking experience. ```ts import { MtSelect } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Multiple selection Enable `enableMultiSelection` so users can choose several values at once. ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ---------------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `options` \* | `unknown[]` | | An array of objects with the labelProperty and valueProperty. | | `disabled` | `boolean` | `false` | Disables or enables the select field. | | `label` | `string` | `""` | The label for the select field itself. | | `placeholder` | `string` | `""` | The placeholder for the select field. | | `error` | `Record` | `null` | An error in your business logic related to this field. For example: {"code": 500, "detail": "Error while saving"} | | `is-inherited` | `boolean` | `false` | Toggles the inheritance visualization. | | `is-inheritance-field` | `boolean` | `false` | Determines if the field is inheritable. | | `hint` | `string \| null` | `null` | Optional caption below the field. The \`#hint\` slot takes precedence when provided. | | `model-value` | `string \| number \| boolean \| object \| unknown[] \| null` | `null` | Dependent on multiSelection, either a single value or an array of values. | | `small` | `boolean` | `false` | Render the select field in small without a search input | | `disable-inheritance-toggle` | `boolean` | `false` | Determines the active state of the inheritance toggle. | | `is-loading` | `boolean` | `false` | Toggles the loading state of the select field. | | `label-property` | `string \| string[]` | `"label"` | The object key of the label property. Can be a single string or an array of strings. If an array is provided, the first property that has a non-empty value will be used. | | `value-property` | `string` | `"value"` | The object key to use for the value. | | `always-show-placeholder` | `boolean` | `true` | Determines if the placeholder should be shown even when there are no selections. | | `enable-multi-selection` | `boolean` | `false` | Toggles if either one or more items can be selected. | | `value-limit` | `number` | `5` | The number of items that are expanded by default. | | `hide-clearable-button` | `boolean` | `false` | Toggles a button to clear all selections. | | `highlight-search-term` | `boolean` | `true` | Determines to highlight the searched term or not. | | `search-function` | `Function` | `({ options, labelProperty, searchTerm, }: { options: any; labelProperty: string \| string[]; searchTerm: string; }) => { return options.filter((option: any) => { // If labelProperty is an array, check each property if (Array.isArray(labelProperty)) { for (const property of labelProperty) { const label = getPropertyValue(option, property); if (label && typeof label === "string" && label.toLowerCase().includes(searchTerm.toLowerCase())) { return true; } } return false; } // Original behavior for string labelProperty const label = getPropertyValue(option, labelProperty); if (!label) { return false; } return label.toLowerCase().includes(searchTerm.toLowerCase()); }); }` | Used to implement a custom search function. Parameters passed: { options, labelProperty, valueProperty, searchTerm } | | `on-update:model-value` | `((...args: any[]) => any) \| undefined` | | | | `on-change` | `((...args: any[]) => any) \| undefined` | | | | `on-inheritance-remove` | `((...args: any[]) => any) \| undefined` | | | | `on-inheritance-restore` | `((...args: any[]) => any) \| undefined` | | | | `on-item-add` | `((...args: any[]) => any) \| undefined` | | | | `on-item-remove` | `((...args: any[]) => any) \| undefined` | | | | `on-display-values-expand` | `((...args: any[]) => any) \| undefined` | | | | `on-paginate` | `((...args: any[]) => any) \| undefined` | | | | `on-search-term-change` | `((...args: any[]) => any) \| undefined` | | | ### Exposed | Name | Type | Description | | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | | `t` | `ComposerTranslation<{ en: { messageNoResults: string; }; de: { messageNoResults: string; }; }, "en" \| "de", RemoveIndexSignature<{ [x: string]: LocaleMessageValue; }>, never, "messageNoResults", "messageNoResults">` | | | `getKey` | `any` | | | `searchTerm` | `string` | | | `limit` | `number` | | | `searchResults` | `never[]` | | | `isSearchResultsLoading` | `boolean` | | | `showFieldHint` | `boolean` | | | `visibleValues` | `any[]` | | | `totalValuesCount` | `number` | | | `invisibleValueCount` | `number` | | | `currentValue` | `string \| number \| boolean \| object \| unknown[] \| null` | | | `visibleResults` | `any[]` | | | `componentClasses` | `Record` | | ## Best practices **Do** - Use a clear field label so users understand what they are choosing. - Keep option labels concise and easy to scan. - Use `enableMultiSelection` only when selecting multiple values is a real user need. - Set `labelProperty` and `valueProperty` explicitly when your option shape differs from the defaults. - Add hint or help text when the selection rules need extra explanation. **Don't** - Do not use **Select** when users should enter arbitrary text instead of choosing from known values. - Do not use a long select list when a smaller visible choice group would be easier to compare directly. - Do not rely on placeholder text as the only instruction for the field. - Do not mix unclear or duplicated option labels, especially in searchable lists. - Do not enable multi selection when the form should store exactly one value. ## Behavior - **Select** supports both single and multiple selection. `modelValue` can be a single value, an option object, or an array depending on the selection mode and `valueProperty`. - The component searches within the provided options by default and supports a custom `searchFunction` when filtering needs to follow business-specific rules. - `labelProperty` can be a string or an array of property paths. When an array is used, the first non-empty value is used as the visible label. - Shared field features such as `hint`, `error`, prefix and suffix content, and inheritance handling work the same way as in other form fields. - `small` renders a compact variant without the inline search input, which is better suited to tighter layouts. - Use `selectionLabelProperty` to customize how selected items are rendered in the closed field. - Use the `result-item` slot or `resultLabelProperty` when result rows need richer formatting than a plain text label. - Use the `before-item-list` and `after-item-list` slots for supporting content around the result list, such as guidance or actions. ## Accessibility - Provide a clear field label or other nearby visible context so users understand what the selection controls. - Keep option labels distinct so users can tell similar choices apart while searching or navigating with the keyboard. - Use help text when multiple selection, custom option rendering, or inherited values might otherwise be unclear. ## Related components - [**Radio Group**](https://meteor.shopware.com/components/radio-group): when a small set of options should stay visible so users can compare them directly. - [**Checkbox**](https://meteor.shopware.com/components/checkbox): when users are toggling independent options on and off rather than choosing from a shared option set. # Skeleton Bar ```vue ``` ## Usage **Skeleton Bar** is a shimmering placeholder block for when the final content structure is known but the real content is still loading. Use it in cards, lists, tables, or detail views where preserving the final layout helps reduce visual jump, and combine multiple bars when the loading state should suggest lines of text or grouped placeholder content. ```ts import { MtSkeletonBar } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Form layout Combine several bars across a grid to mirror the structure of the content that will appear. ```vue ``` ## API reference ## Best practices **Do** - Match the placeholder size and grouping roughly to the final content shape. - Use **Skeleton Bar** close to the surface where the real content will appear. - Replace the skeleton as soon as the actual content is ready. - Combine several bars with different widths when that helps communicate the expected structure. **Don't** - Do not use **Skeleton Bar** when you can show real progress or completion state. - Do not leave skeleton placeholders visible for long-running tasks without additional context. - Do not use skeleton bars as a generic decoration when nothing is actually loading. - Do not make users interact with placeholder content that is not ready yet. ## Behavior - **Skeleton Bar** is purely visual. It renders a shimmer animation over a neutral placeholder surface. - The component takes the full available width of its container, so surrounding layout controls its final size. - Consecutive skeleton bars add vertical spacing automatically, which makes it easy to stack them into text-like placeholder groups. ## Accessibility - **Skeleton Bar** does not announce loading state or placeholder semantics on its own. - When the loading state matters for assistive technologies, expose that state on the surrounding region or pair it with additional loading text. - Keep the placeholder structure close to the final content so all users can understand what area is being loaded. ## Related components - [**Loader**](https://meteor.shopware.com/components/loader): when a simple indeterminate loading indicator is enough and a structural placeholder would not add value. # Slider ```vue ``` ## Usage **Slider** lets users adjust a numeric value within a known range by dragging along a scale. Use it for settings such as limits, thresholds, percentages, or price ranges, where seeing the relative position of a value is more helpful than typing alone. ```ts import { MtSlider } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Range ```vue ``` ## API reference ## Best practices **Do** - Use a clear label that explains what the scale controls. - Set sensible `min`, `max`, and `step` values for the use case. - Use a range slider when users need to set both a lower and upper bound together. **Don't** - Do not use **Slider** when precise text or number entry is the primary need. - Do not use a very large range with tiny steps if dragging would become frustrating. - Do not rely only on the visual bar to explain the meaning of the selected value. ## Behavior - **Slider** can represent either a single numeric value or a two-value range through `isRange`. - The component includes linked number inputs, so users can adjust values by dragging or by typing. - `markCount`, `step`, and `minDistance` help shape how the scale behaves and how dense the value guidance feels. ## Accessibility - Use a visible label that makes the meaning of the scale clear. - Make sure the chosen range and step size still allow keyboard users to reach useful values efficiently. - Avoid using **Slider** for critical settings if users need extremely precise control without an alternate input path. ## Related components - [**Number Field**](https://meteor.shopware.com/components/number-field): when precise numeric entry matters more than direct manipulation. # Snackbar ```vue ``` ## Usage **Snackbar** shows temporary, non-blocking feedback for short-lived messages, such as confirming that an action completed (saving, deleting, or updating), surfacing errors or warnings that people should notice without leaving their current flow, or reporting background progress that resolves into success or error feedback. Use it when you may need one non-critical follow-up action, such as `Undo`. `mt-snackbar` is the host that renders the stack; you publish notifications with the [**useSnackbar**](https://meteor.shopware.com/utilities/composables/use-snackbar) composable. ```ts import { MtSnackbar } from "@shopware-ag/meteor-component-library"; ``` ## Anatomy **Snackbar** is used together with the [**useSnackbar**](https://meteor.shopware.com/utilities/composables/use-snackbar) composable. Mount `mt-snackbar` once near your app shell to render the stack, then call `addSnackbar` from `useSnackbar` wherever an action happens. ```vue ``` See [**useSnackbar**](https://meteor.shopware.com/utilities/composables/use-snackbar) for the full publishing API (`addSnackbar`, `removeSnackbar`, `clearSnackbars`) and every `Snackbar` option. ## API reference `MtSnackbar` exposes no props, slots, or events. Mount it once as shown above and drive it entirely through the [**useSnackbar**](https://meteor.shopware.com/utilities/composables/use-snackbar) composable. ## Best practices **Do** - Keep the message short, specific, and easy to scan at a glance. - Mount `MtSnackbar` once and trigger messages through `useSnackbar()` where the action happens. - Use `progress` snackbars for background work that will resolve into a success or error state. - Keep optional actions short and directly related to the message. **Don't** - Do not use **Snackbar** for critical information that must stay visible until the user explicitly dismisses it. - Do not overload a snackbar with long text or multiple actions. - Do not rely on a snackbar as the only place a user can recover from a destructive action. - Do not fire many snackbars in rapid succession, because they quickly become noisy and easy to miss. ## Behavior - **Snackbar** uses a global store, so one mounted `MtSnackbar` host is usually the right setup for an application. - Standard snackbars close automatically after `5000ms` by default. - Setting `duration` to `0` disables the auto-dismiss timer, which means you should remove that snackbar through `removeSnackbar` or `clearSnackbars`. - Hovering the snackbar stack pauses dismissal timers until the pointer leaves. - `progress` snackbars stay visible until `uploadState` changes to `success` or `error`, then they close shortly after showing the final message. - The optional `link` supports one non-critical follow-up action, not a full decision flow. ## Accessibility - Error and warning snackbars use assertive live announcements, while default, success, and progress snackbars use polite announcements. - Snackbar notifications receive focus when they appear, so messages should remain concise and understandable out of context. - Do not use **Snackbar** for blocking confirmations, legal notices, or other information that must remain available until explicitly dismissed. - If you provide an action like `Undo`, make sure that recovery path also exists elsewhere in the interface and not only in the temporary snackbar. ## Related - [**useSnackbar**](https://meteor.shopware.com/utilities/composables/use-snackbar): the composable for publishing, updating, and removing snackbars. - [**Banner**](https://meteor.shopware.com/components/banner): when the message is persistent inline messaging that should remain visible while the user continues working. # Status Dot ```vue ``` ## Usage **Status Dot** is a small, non-interactive colored dot for signaling a single status at a glance, such as an item being active, needing attention, or in an error state. Use it next to a label in tabs, lists, or headers where a full [**Badge**](https://meteor.shopware.com/components/badge) would be too heavy, and always pair it with nearby text so the meaning never depends on color alone. ```ts import { MtStatusDot } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Variants ```vue ``` ### Sizes ```vue ``` ### Pulse Set `pulse` to add a pulsating ring that signals ongoing, live activity, such as a process that is currently running. ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | --------- | ---------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `variant` | `"critical" \| "info" \| "neutral" \| "attention" \| "positive"` | `"neutral"` | The semantic color of the status dot. | | `size` | `"s" \| "m" \| "l"` | `"m"` | The diameter of the dot. | | `pulse` | `boolean` | `false` | Adds a pulsating ring around the dot to signal an ongoing, live activity (e.g. something is currently active or processing). The animation is disabled for users who prefer reduced motion. | | `label` | `string` | `undefined` | An accessible label describing the status. When omitted the dot is treated as decorative and hidden from assistive technology. | ## Best practices **Do** - Pair the dot with a nearby text label so the status is never conveyed by color alone. - Choose the `variant` that matches the semantic meaning of the status. - Set the `label` prop when the dot is the only thing communicating a status, so assistive technology can announce it. - Keep it for single, glanceable states. **Don't** - Do not use **Status Dot** to convey text or counts; use [**Badge**](https://meteor.shopware.com/components/badge) instead. - Do not make **Status Dot** interactive or the only target for a click. - Do not place many dots together, because they become hard to tell apart. - Do not rely on color alone to communicate meaning. ## Behavior - **Status Dot** is presentational and non-interactive. If users need to click or trigger something, wrap it in an appropriate interactive component. - It renders a single fixed shape and has no text or slot content; use [**Badge**](https://meteor.shopware.com/components/badge) when a label is required. - With `pulse` the dot shows a repeating ring to signal live activity. Reserve it for states that are genuinely ongoing, and avoid pulsating several dots at once. ## Accessibility - The dot is decorative by default and hidden from assistive technology, on the assumption that a visible text label carries the meaning. - When the dot is the only carrier of a status, set the `label` prop. It then exposes an accessible name to assistive technology. - Do not communicate status through color alone; keep an adjacent text label for all users. - The `pulse` animation is automatically disabled for users who have enabled reduced motion, leaving the dot in its static state. ## Related components - [**Badge**](https://meteor.shopware.com/components/badge): when the status needs a text label, icon, or a larger visual treatment. # Switch ```vue ``` ## Usage **Switch** is a direct on or off control for a single binary setting that takes effect immediately. Use it in forms or settings screens where users expect a quick toggle interaction and the on or off state is easy to understand without extra confirmation. ```ts import { MtSwitch } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### States ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ---------------------- | --------------------- | ------- | ----------- | | `model-value` | `boolean` | | | | `label` | `string` | | | | `is-inherited` | `boolean` | | | | `is-inheritance-field` | `boolean` | | | | `inherited-value` | `boolean` | | | | `required` | `boolean` | | | | `disabled` | `boolean` | | | | `checked` | `boolean` | | | | `bordered` | `boolean` | | | | `help-text` | `string` | | | | `error` | `{ detail: string; }` | | | | `remove-top-margin` | `boolean` | | | | `name` | `string` | | | ### Events | Event | Payload | Description | | --------------------- | ------------------ | ----------- | | `update:modelValue` | `[value: boolean]` | | | `change` | `[value: boolean]` | | | `inheritance-remove` | `[]` | | | `inheritance-restore` | `[]` | | ## Best practices **Do** - Use a clear label that describes the setting, not just the current state. - Use **Switch** for immediate preferences or feature toggles. - Add help text when users need more context about the effect of changing the setting. **Don't** - Do not use **Switch** for multi-select choices. - Do not use it when turning something on or off requires additional explanation or confirmation. - Do not rely on the visual position of the thumb alone to communicate state. ## Behavior - **Switch** supports a binary on or off value through `modelValue`. - The component also supports shared field patterns such as `error`, `helpText`, inheritance handling, and bordered presentation. - Because **Switch** is meant for direct toggling, it works best when users can understand the outcome immediately. ## Accessibility - Use a visible label that clearly explains what the toggle controls. - Make sure the setting makes sense when announced with its checked or unchecked state by assistive technology. - Avoid using **Switch** for critical actions where accidental toggling would be risky. ## Related components - [**Checkbox**](https://meteor.shopware.com/components/checkbox): when users are selecting items or confirming a value as part of a broader form submission flow. # Tabs ```vue ``` ## Usage **Tabs** let users move between peer sections of content when only one panel or view should be active at a time. Use them for compact navigation inside a page, card, or workspace area. ```ts import { MtTabs } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Vertical Lay the tabs out as a vertical list for side navigation within a section. ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | -------------- | ----------- | ------- | ----------- | | `items` \* | `TabItem[]` | | | | `small` | `boolean` | `false` | | | `vertical` | `boolean` | `false` | | | `default-item` | `string` | `""` | | ### Events | Event | Payload | Description | | ----------------- | ------- | ----------- | | `new-item-active` | `any[]` | | ### Exposed | Name | Type | Description | | ------------------- | -------------------------------------------------------------------------------------------------------------------------- | ----------- | | `tabClasses` | `(string \| { "mt-tabs--vertical": boolean; "mt-tabs--small": boolean; "mt-tabs--future-remove-default-margin": any; })[]` | | | `refreshKey` | `boolean` | | | `activeItemName` | `string` | | | `showMoreItems` | `boolean` | | | `passedFirstRender` | `boolean` | | | `activeDomItem` | `any` | | | `sliderPosition` | `number` | | | `sliderLength` | `number` | | | `activeItem` | `TabItem` | | | `sliderClasses` | `Record` | | | `sliderStyle` | `string` | | ## Best practices **Do** - Use short, clear labels so users can scan the available sections quickly. - Keep the set of tabs related and at the same hierarchy level. - Use badges or error indicators only when the extra status helps users prioritize where to look. **Don't** - Do not use **Tabs** for unrelated actions or mixed controls. - Do not overload tabs with long labels that make scanning difficult. - Do not use tabs when a vertical navigation, segmented control, or button group would express the structure more clearly. ## Behavior - **Tabs** take their items from the `items` prop and emit `new-item-active` when the selection changes. - If there are too many horizontal tabs to fit, extra items move into a `More` menu automatically. - `vertical` changes the layout direction, and `small` provides a more compact presentation. - `small` is marked as deprecated in the component and should be treated as a legacy option. ## Accessibility - Use labels that make sense as standalone tab names. - Keep the order stable so keyboard and screen-reader users can build a reliable mental model. - Make sure the currently active tab corresponds to clearly updated content nearby. ## Related components - Segmented Control: when its current experimental grouped-action behavior is needed, not as a general replacement for tab navigation. - [**Button**](https://meteor.shopware.com/components/button): when the user should trigger an action instead of navigating between peer sections. # Text ```vue ``` ## Usage **Text** is the base typography component for body copy, labels, headings, and supporting descriptions. Use it when you need consistent typography across content and interface text, and when the semantic HTML element and the visual text style should be chosen separately. ```ts import { MtText } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Sizes ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | -------- | -------------------------------------------------------------- | ------------------------------ | ----------- | | `size` | `"s" \| "2xs" \| "xs" \| "m" \| "l" \| "xl" \| "2xl" \| "3xl"` | `"s"` | | | `weight` | `"regular" \| "bold" \| "semibold" \| "medium"` | `"regular"` | | | `color` | `string` | `"color-text-primary-default"` | | | `as` | `string \| Component` | `"p"` | | ### Slots | Slot | Bindings | Description | | --------- | -------- | ----------- | | `default` | `{}` | | ## Best practices **Do** - Choose the `as` prop based on the semantic meaning of the content. - Choose `size` and `weight` based on visual hierarchy. - Keep color choices aligned with the text token system. **Don't** - Do not use **Text** only for spacing or layout. - Do not use heading-sized text when the content is not actually a heading in the page structure. - Do not override the semantics of important content without a clear reason. ## Behavior - **Text** renders as a semantic element through the `as` prop and defaults to a paragraph. - `size`, `weight`, and `color` control the visual style while the content stays in the default slot. - Larger sizes use the heading font tokens, while smaller sizes use the body font tokens. ## Accessibility - Use the `as` prop to preserve the correct document structure, especially for headings. - Do not rely on visual styling alone to communicate hierarchy if semantic headings are required. - Keep color choices readable against the background and aligned with contrast requirements. # Text Editor ```vue ``` ## Usage **Text Editor** lets users author rich text content such as descriptions, notes, or formatted documents, binding the HTML string with `v-model`. Use the `customButtons` and `excludedButtons` props to tailor the toolbar (or set `show-toolbar` to `false` to hide it entirely), switch between WYSIWYG and raw HTML editing through `v-model:code-mode`, enable `is-inline-edit` for an inline experience with a floating toolbar, and extend the editor with custom Tiptap extensions through the `tipTapConfig` prop. ```ts import { MtTextEditor } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Inline editing Enables inline editing with a floating toolbar. ```vue ``` ### Hidden toolbar Hide the toolbar completely for a simpler editing experience or a custom toolbar. ```vue ``` ### Code mode Start the editor in raw HTML editing mode. ```vue ``` ### Two-way code mode binding Control the editor mode programmatically with `v-model:code-mode`. ```vue ``` ### Custom toolbar buttons Add custom buttons to the toolbar, backed by a custom Tiptap extension. ```vue ``` ### Security gate on initial load When the initial HTML would change after parsing, an overlay blocks WYSIWYG editing until the diff is reviewed and accepted. ```vue ``` ## Slots ### `button_` A dynamic slot is rendered for every toolbar button as `button_`. Use it to replace the automatically rendered button with your own component. For example, to customize the `text-color` button: ```html ``` ### `contextual-buttons` Custom buttons for the editor footer. These can change contextually based on the editor's current state. ### `footer-left` and `footer-right` Customize the left or right sections of the editor's footer. ## Toolbar buttons The editor includes these built-in buttons by default. Use the `excludedButtons` prop to remove buttons and `customButtons` to add your own. The position values are useful when inserting custom buttons (see [Positioning](https://meteor.shopware.com/#positioning)). | Button name | Description | Alignment | Position | | -------------- | -------------------------------------------------- | --------- | -------- | | format | Opens a popover with formatting options. | left | 1000 | | text-color | Allows the user to pick a text color. | left | 2000 | | bold | Toggles bold text. | left | 3000 | | italic | Toggles italic text. | left | 4000 | | underline | Toggles underlined text. | left | 5000 | | strikethrough | Toggles strikethrough text. | left | 6000 | | superscript | Toggles superscript text. | left | 7000 | | subscript | Toggles subscript text. | left | 8000 | | text-alignment | Opens a popover to set text alignment. | left | 9000 | | unordered-list | Toggles an unordered list. | left | 10000 | | numbered-list | Toggles a numbered list. | left | 11000 | | link | Opens a modal to insert or edit links. | left | 12000 | | table | Opens a modal to insert or modify tables. | left | 13000 | | undo | Undoes the last action. | right | 1000 | | redo | Redoes the last undone action. | right | 2000 | | toggle-code | Toggles between WYSIWYG mode and raw HTML editing. | right | 3000 | ## Custom buttons Add custom buttons to the toolbar by passing an array of `CustomButton` objects to the `customButtons` prop. Each button supports these properties: - **`name`** (required): A unique identifier for the button. - **`label`** (required): The visible label, as direct text or a translation key. - **`icon`**: An optional icon name from the Meteor icon set, shown instead of the label. - **`isActive`**: A function returning whether the button is currently active (for example, when bold is toggled on). - **`action`**: A function that runs when the button is clicked, where you apply an editor command. - **`children`**: An array of child buttons to build a dropdown or multi-level menu. - **`alignment`**: Whether the button appears on the `left` or `right` of the toolbar. - **`position`**: The button's order in the toolbar. Lower values appear first. - **`disabled`**: A function returning whether the button should be disabled. - **`contextualButtons`**: A function returning additional footer buttons based on the editor's state. ### Simple button A custom button that toggles bold formatting: ```html ``` ### Dropdown menu Use the `children` property to build a dropdown. Each child is another `CustomButton`: ```html ``` ### Contextual footer buttons Use the `contextualButtons` property to return footer buttons that appear based on the editor's state, such as a "Remove link" action that only shows when a link is selected: ```html ``` ### Disabling a button by state Provide a `disabled` function to disable a button dynamically, for example when the editor is empty: ```html ``` ### Positioning Buttons are sorted by their `position` value, lowest first. The default buttons use increments of `1000`, leaving room to insert custom buttons at specific positions. For example, `position: 3500` places a button between `bold` (3000) and `italic` (4000). See the [Toolbar buttons](https://meteor.shopware.com/#toolbar-buttons) table for the default positions. ## Customizing with Tiptap extensions The editor's features are built on [Tiptap extensions](https://tiptap.dev/docs/editor/core-concepts/extensions){rel=""nofollow""}. Pass custom extensions through the `tipTapConfig` prop, except the hardcoded `content`, `editorProps`, and `onUpdate` properties: ```html ``` ## Validating before save The component exposes a `validate()` method through a template ref. It checks the current code editor content against what Tiptap can represent and shows the diff modal if the HTML differs. It returns `true` when valid (no diff, or not in code mode) and `false` when the diff modal was shown. This is useful for validating content before closing a modal or saving: ```html ``` ## API reference ### Props | Prop | Type | Default | Description | | ------------------ | --------------------- | ------- | ------------------------------------------------------------------------------------------- | | `model-value` \* | `string` | `""` | | | `disabled` | `boolean` | `false` | Add disabled state to the editor | | `label` | `string` | `null` | A label for your text field. Usually used to guide the user what value this field controls. | | `placeholder` | `string` | `""` | Add placeholder text to the editor | | `error` | `Record` | `null` | An error in your business logic related to this field. | | `is-inline-edit` | `boolean` | `false` | Enable inline edit mode | | `tip-tap-config` | `Record` | `{}` | Add custom configuration for the tip tap editor | | `custom-buttons` | `CustomButton[]` | `[]` | Custom buttons to be added to the toolbar | | `excluded-buttons` | `string[]` | `[]` | Excluded buttons from the toolbar | | `show-toolbar` | `boolean` | `true` | Control toolbar visibility. Set to false to hide the toolbar completely. | | `code-mode` | `boolean` | `false` | Control code editor mode. Set to true to show the code editor instead of WYSIWYG. | ### Events | Event | Payload | Description | | ------------------- | ------- | ----------- | | `update:modelValue` | `any[]` | | | `update:codeMode` | `any[]` | | ### Slots | Slot | Bindings | Description | | -------------------- | -------------------------------------------------------- | ----------- | | `contextual-buttons` | `{ editor: Editor; buttons: Reactive; }` | | | `footer-left` | `{ editor: Editor; }` | | | `footer-right` | `{ editor: Editor; }` | | ### Exposed | Name | Type | Description | | ---------- | ------------------------ | ----------- | | `validate` | `() => Promise` | | ## Best practices **Do** - Use `v-model` to keep the HTML content in sync with your state. - Provide a `label` so users understand what the field is for. - Tailor the toolbar with `customButtons` and `excludedButtons` to match the editing needs of the context. - Use the code mode when users need to inspect or edit the raw HTML. **Don't** - Do not feed unsupported HTML markup without expecting the security gate to require a diff review first. - Do not rely on the editor for plain, unformatted text where a simpler input is enough. - Do not hide the toolbar unless you provide another way to apply formatting. ## Behavior - The editor is built on Tiptap and accepts custom extensions through `tipTapConfig`, except the hardcoded `content`, `editorProps`, and `onUpdate` properties. - When the editor mounts in WYSIWYG mode, it dry-runs a Tiptap parse and compares the result with the initial HTML. If the HTML differs, an overlay blocks editing until the user reviews a diff and accepts the parsed result. While the gate is active, `update:modelValue` emits are suppressed. - When switching from code mode to WYSIWYG, the editor compares the code with Tiptap's parsed output and shows a side-by-side diff modal if changes are detected. The user can accept the changes and switch, or stay in the code editor. - The component exposes a `validate()` method through a template ref. It checks the current code editor content against what Tiptap can represent and shows the diff modal if the HTML differs. It returns `true` when valid (no diff or not in code mode) and `false` when the diff modal was shown, which is useful before saving or closing a parent modal. - Custom buttons are ordered by their `position` value, with default buttons spaced in increments of `1000` so custom buttons can be inserted between them. - The footer shows a live character count, and `contextual-buttons` can change based on the current cursor position. ## Accessibility - Provide a `label` so the field has an accessible name. - When replacing default buttons with custom ones, ensure each button keeps a clear, descriptive label. # Text Field ```vue ``` ## Usage **Text Field** is a single-line input for short free-form text values such as names, titles, and identifiers. Use it when users should type one value in a single-line input and when shared field features such as `hint`, `helpText`, `error`, or inheritance are helpful. ```ts import { MtTextField } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Disabled ```vue ``` ### Error ```vue ``` ### Hint ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ---------------------------- | ---------------------------------------- | ----------- | ------------------------------------------------------------------------------------------- | | `required` | `boolean` | `false` | Determines if the field is required. | | `disabled` | `boolean` | `false` | Determines if the field is disabled. | | `name` | `string` | `null` | | | `label` | `string` | `null` | A label for your text field. Usually used to guide the user what value this field controls. | | `placeholder` | `string` | `""` | A placeholder text being displayed if no value is set. | | `error` | `Record` | `null` | An error in your business logic related to this field. | | `help-text` | `string` | `null` | A text that helps the user to understand what this field does. | | `max-length` | `number` | `undefined` | If set to a value a character counter will be displayed. | | `is-inherited` | `boolean` | `false` | Toggles the inheritance visualization. | | `is-inheritance-field` | `boolean` | `false` | Determines if the field is inheritable. | | `hint` | `string \| null` | `null` | Optional caption below the field. The \`#hint\` slot takes precedence when provided. | | `model-value` | `string \| number` | `""` | The value of the text field. | | `size` | `"default" \| "small"` | `"default"` | The size of the text field. | | `disable-inheritance-toggle` | `boolean` | `false` | Determines the active state of the inheritance toggle. | | `copyable` | `boolean` | `false` | Toggles the copy function of the text field. | | `copyable-tooltip` | `boolean` | `false` | If set to true the tooltip will change on successful copy. | | `id-suffix` | `string` | `""` | | | `on-update:model-value` | `((...args: any[]) => any) \| undefined` | | | | `on-change` | `((...args: any[]) => any) \| undefined` | | | | `on-inheritance-remove` | `((...args: any[]) => any) \| undefined` | | | | `on-inheritance-restore` | `((...args: any[]) => any) \| undefined` | | | | `on-focus` | `((...args: any[]) => any) \| undefined` | | | | `on-blur` | `((...args: any[]) => any) \| undefined` | | | ### Exposed | Name | Type | Description | | ------------------ | ------------------ | ----------- | | `currentValue` | `string \| number` | | | `hasFocus` | `boolean` | | | `showFieldHint` | `boolean` | | | `hasError` | `boolean` | | | `hasDisabledInput` | `boolean` | | ## Best practices **Do** - Use a clear visible label that describes the expected value. - Keep the content short enough for a single-line input. - Add help text or hint content when users need more context. **Don't** - Do not use **Text Field** for longer multi-line content. - Do not rely on the placeholder as the only instruction. - Do not use it when a more specific field type would guide input better. ## Behavior - **Text Field** supports shared field features such as `prefix`, `suffix`, `hint`, `helpText`, `error`, and inheritance handling. - `copyable` adds a copy button for reference-heavy values that users may need to copy out of the field. - `maxLength` can show a live character counter when the value length matters. ## Accessibility - Always provide a visible label so users understand what value is expected. - Use a more specific field type when browser input behavior or validation would improve accessibility. ## Related components - [**Email Field**](https://meteor.shopware.com/components/email-field): when the value must be an email address. - [**URL Field**](https://meteor.shopware.com/components/url-field): when the value should be a link and URL-specific behavior is helpful. - [**Number Field**](https://meteor.shopware.com/components/number-field): when the value should behave like a number with numeric constraints or stepping. - [**Unit Field**](https://meteor.shopware.com/components/unit-field): when users should enter a number together with a selectable unit. - [**Password Field**](https://meteor.shopware.com/components/password-field): when the value is sensitive and should be hidden by default. - [**Search**](https://meteor.shopware.com/components/search): when the value is meant to filter or find content in the interface. # Textarea ```vue ``` ## Usage **Textarea** is a multi-line input for notes, descriptions, comments, or other longer free-form text in a form. Use it when users need more space than a single-line field should provide, and when line breaks and longer written input are part of the value. ```ts import { MtTextarea } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Disabled ```vue ``` ### Error ```vue ``` ### Hint ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ---------------------- | --------------------- | ------- | ----------- | | `required` | `boolean` | | | | `disabled` | `boolean` | | | | `name` | `string` | | | | `label` | `string` | | | | `placeholder` | `string` | | | | `error` | `{ detail: string; }` | | | | `help-text` | `string` | | | | `max-length` | `number` | | | | `is-inherited` | `boolean` | | | | `is-inheritance-field` | `boolean` | | | | `hint` | `string \| null` | | | | `model-value` | `string` | | | ### Events | Event | Payload | Description | | --------------------- | ------------------------------ | ----------- | | `update:modelValue` | `[value: string \| undefined]` | | | `change` | `[string \| undefined]` | | | `inheritance-remove` | `[]` | | | `inheritance-restore` | `[]` | | | `focus` | `[]` | | | `blur` | `[]` | | ### Slots | Slot | Bindings | Description | | ------ | -------- | ----------- | | `hint` | `{}` | | ## Best practices **Do** - Use a clear visible label that explains what kind of content belongs in the field. - Add help text or hint content when users need guidance about tone, length, or formatting. - Use `maxLength` when the content length matters and should stay visible. **Don't** - Do not use **Textarea** for short single-line values. - Do not rely on the placeholder as the only instruction. - Do not use it when a more structured input would guide users better. ## Behavior - **Textarea** supports shared field patterns such as `hint`, `helpText`, `error`, and inheritance handling. - The field can grow vertically because resizing is enabled for the text area itself. - `maxLength` shows a live character counter when the content length matters. ## Accessibility - Always provide a visible label so users understand what longer text is expected. - Use clear length guidance when the field has a maximum character limit. ## Related components - [**Text Field**](https://meteor.shopware.com/components/text-field): when the value should stay short and single-line. # Theme Select ```vue ``` ## Usage **Theme Select** lets users choose the application color theme: light, dark, or following the operating system preference. Use it in settings screens, profile pages, or anywhere a theme preference belongs. It is a controlled component: it only reports the chosen theme through `v-model` and does not apply or persist the theme itself, which keeps the host application in charge of how the choice takes effect. ```ts import { MtThemeSelect } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Pairing with useTheme The [**useTheme**](https://meteor.shopware.com/utilities/composables/use-theme) composable resolves the `system` option against `prefers-color-scheme`, applies the resolved value as `data-theme`, and persists the choice. Binding its `theme` ref to the select is all a typical app needs. ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ------------- | --------- | ---------- | -------------------------------------- | | `label` | `string` | | The label for the select field itself. | | `disabled` | `boolean` | | Disables the select field. | | `model-value` | `any` | `"system"` | | ### Events | Event | Payload | Description | | ------------------- | ---------------- | ----------- | | `update:modelValue` | `[value: Theme]` | | ## Best practices **Do** - Default to `system` so the application respects the operating system preference. - Pair the select with [**useTheme**](https://meteor.shopware.com/utilities/composables/use-theme) so the choice is applied and persisted consistently. - Give the field a label that describes the setting, such as `Color theme` or `Appearance`. **Don't** - Do not use **Theme Select** for unrelated multi-option settings; it is purpose-built for color themes. - Do not apply the theme from multiple places at once. Keep one owner for the `data-theme` attribute. ## Behavior - **Theme Select** accepts and emits one of three values through `modelValue`: `"light"`, `"dark"`, or `"system"`, and defaults to `"system"`. - The component is purely presentational. Resolving `system`, writing `data-theme`, and persisting the choice is the host's responsibility, which [**useTheme**](https://meteor.shopware.com/utilities/composables/use-theme) handles out of the box. - Option labels are localized (English and German) through the library's i18n setup. - Additional [**Select**](https://meteor.shopware.com/components/select) props such as `small` or `error` fall through to the underlying select. ## Accessibility - Keyboard and screen reader behavior follow the underlying [**Select**](https://meteor.shopware.com/components/select) component. - Each option is labelled with text, so the choice never relies on color or iconography. - Provide a visible `label` so the setting is announced with its purpose. ## Related components - [**Select**](https://meteor.shopware.com/components/select): the general-purpose select this component builds on, for arbitrary option sets. - [**useTheme**](https://meteor.shopware.com/utilities/composables/use-theme): the composable that resolves, applies, and persists the theme this component selects. # Toast ::caution **Deprecated.** Use [**Snackbar**](https://meteor.shopware.com/components/snackbar) instead. :: ```vue ``` ## Usage **Toast** is short-lived, action-bound feedback for confirming a save or reporting that something failed. Use the `positive` and `informal` types for non-critical feedback that can disappear on its own, and the `critical` type for problems the user should not miss. Add `dismissible` or an `action` when the message needs a manual close control or a single follow-up such as `Undo`, and keep messages to a few words since toasts are brief and not persistent. ```ts import { MtToast } from "@shopware-ag/meteor-component-library"; ``` ## Anatomy **Toast** renders a host that you mount once, usually near the app shell. It does not own the toast state. You pass the current toasts through the `toasts` prop and remove a toast from your own list when the component emits `remove-toast`. ```vue ``` ### Toast The exported **Toast** type describes a single notification in the `toasts` list. Prepend new toasts so the most recent one appears first. | Field | Value | Default | Description | | ------------- | ----------------------------------------- | -------- | ---------------------------------------------------------------------------------------- | | `id` | `number | string` | Required | Unique identifier you assign when adding the toast. Used to remove it on `remove-toast`. | | `msg` | `string` | Required | Main toast text shown to the user. Keep it to a few words. | | `type` | `"positive" | "informal" | "critical"` | Required | Controls semantic styling, placement, and live-region behavior. | | `icon` | `string` | None | Optional icon name shown before the message. | | `action` | `{ label: string; callback: () => void }` | None | Optional single follow-up action rendered as a button. | | `dismissible` | `boolean` | `false` | When `true`, the toast shows a manual close control. | ## API reference ### Props | Prop | Type | Default | Description | | ----------- | --------- | ------- | ------------------------------------------------------------------- | | `toasts` \* | `Toast[]` | | A collection of toasts. The most current one needs to be prepended. | ### Events | Event | Payload | Description | | -------------- | ------- | ----------- | | `remove-toast` | `any[]` | | ## Best practices **Do** - Keep the message short, specific, and easy to scan at a glance. - Mount the toast host once and feed it from your own state where the action happens. - Use `positive` and `informal` for non-critical feedback that can auto-dismiss. - Use `critical` for failures the user needs to notice. - Remove each toast from your list when `remove-toast` fires. **Don't** - Do not use **Toast** for information that must stay visible until the user explicitly dismisses it. - Do not overload a toast with long text or more than one action. - Do not rely on a toast as the only recovery path for a destructive action. - Do not fire many toasts in rapid succession, because they quickly become noisy and easy to miss. ## Behavior - **Toast** places each message into one of two categories automatically based on its type, dismissibility, and action. - Quick toasts are non-dismissible, non-critical toasts of type `positive` or `informal` with no action. They appear bottom center and auto-close after about three seconds. - Regular toasts are critical, dismissible, or action-bearing toasts. They appear bottom right and auto-close after about ten seconds. - A `critical` toast that has an `action` does not auto-close and must be dismissed manually. - Hovering a toast pauses its auto-close timer until the pointer leaves. - The component never removes a toast from your data. It only emits `remove-toast` with the toast id, and you update your own list in response. ## Accessibility - `critical` toasts use assertive live announcements, while `positive` and `informal` toasts use polite announcements. - A `critical` toast with an action uses an `alertdialog` role, so it stays until the user acts on or dismisses it. - Toasts can be dismissed with the `Escape` key when they are focused. - Keep messages concise and understandable out of context, since toasts are short-lived. - Do not use **Toast** for blocking confirmations, legal notices, or other information that must remain available until explicitly dismissed. ## Related components - [**Snackbar**](https://meteor.shopware.com/components/snackbar): when you need overlay feedback driven through the `useSnackbar()` store, with built-in support for progress and link actions. # Tooltip ```vue ``` ## Usage **Tooltip** is a floating layer of brief supporting information shown when users hover or focus a trigger element. Use it for short contextual guidance when extra information is helpful but should stay hidden until requested, and when the trigger is already part of the interface, such as a button, icon, or inline control. ```ts import { MtTooltip } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Placement Use `placement` to position the tooltip relative to its trigger. ```vue ``` ### Rich content The `content` prop accepts sanitized HTML, so simple formatting can be shown when needed. ```vue ``` ## Anatomy - **Tooltip** uses the default slot as the trigger. - The slot provides trigger bindings such as focus, hover, and accessibility attributes that should be spread onto the trigger element. - The tooltip body itself is rendered in a floating layer and positioned relative to the trigger. ## API reference ### Props | Prop | Type | Default | Description | | --------------------------- | ----------- | ------- | ----------- | | `content` \* | `string` | | | | `delay-duration-in-ms` | `number` | `300` | | | `hide-delay-duration-in-ms` | `number` | `300` | | | `placement` | `Placement` | `"top"` | | | `max-width` | `number` | `240` | | ### Slots | Slot | Bindings | Description | | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | | `default` | `{ id: string; onFocus: () => void; onBlur: (event: FocusEvent) => void; onKeydown: (event: KeyboardEvent) => void; onMouseover: () => void; onMouseleave: () => void; onMousedown: () => void; onMouseup: () => void; 'aria-describedby': string; }` | | ## Best practices **Do** - Keep tooltip content brief and easy to scan. - Attach the tooltip to the element it explains. - Use `placement` and `maxWidth` when the surrounding layout needs a more predictable presentation. **Don't** - Do not use **Tooltip** for critical information users must always see. - Do not put long-form instructions or complex content in the tooltip. - Do not rely on **Tooltip** as the only way to explain a control that would otherwise be unclear. ## Behavior - **Tooltip** opens on hover and keyboard focus, and closes on blur, mouse leave, or common dismiss keys such as `Escape`. - The `content` prop accepts sanitized HTML, so simple formatting can be shown when needed. - `delayDurationInMs`, `hideDelayDurationInMs`, `placement`, and `maxWidth` help tune the tooltip behavior for the surrounding UI. ## Accessibility - Only use **Tooltip** for supporting information, not for instructions users must read to complete a task. - Make sure the trigger control still has a clear accessible name and purpose without opening the tooltip. - Keep the content short enough that it can be understood quickly when focus moves to the trigger. ## Related components - [**Help Text**](https://meteor.shopware.com/components/help-text): when you need the standard small help icon pattern next to a field or label. # Unit Field ```vue ``` ## Usage **Unit Field** is a numeric input combined with a unit selector for measurements such as lengths, weights, or other values that may switch between compatible units. Use it when users should enter a value together with a measurement unit, and when unit conversion should happen as part of the input flow. ```ts import { MtUnitField } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Disabled ```vue ``` ### Error ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ---------------------------- | ---------------------- | ----------- | ------------------------------------------------------------------------------------ | | `default-unit` \* | `convert.Unit` | `"mm"` | | | `measurement-type` | `"length" \| "mass"` | `"length"` | | | `model-value` | `number` | `undefined` | | | `placeholder` | `string` | | | | `number-type` | `"float" \| "int"` | | | | `step` | `number` | `1` | | | `min` | `number` | | | | `max` | `number` | | | | `digits` | `number` | | | | `fill-digits` | `boolean` | | | | `allow-empty` | `boolean` | | | | `number-align-end` | `boolean` | | | | `label` | `string` | | | | `error` | `object` | | | | `disabled` | `boolean` | | | | `required` | `boolean` | | | | `name` | `string` | | | | `size` | `"default" \| "small"` | | | | `help-text` | `string` | | | | `is-inherited` | `boolean` | | | | `is-inheritance-field` | `boolean` | | | | `disable-inheritance-toggle` | `boolean` | | | | `copyable` | `boolean` | | | | `copyable-tooltip` | `boolean` | | | | `z-index` | `number \| null` | `null` | | | `hint` | `string \| null` | `null` | Optional caption below the field. The \`#hint\` slot takes precedence when provided. | ### Events | Event | Payload | Description | | ------------------------ | ------------------------------ | ----------- | | `update:modelValue` | `[value: number \| undefined]` | | | `update:defaultUnit` | `[value: convert.Unit]` | | | `update:measurementType` | `[value: "length" \| "mass"]` | | | `inheritance-restore` | `[]` | | | `inheritance-remove` | `[]` | | ### Slots | Slot | Bindings | Description | | ------ | -------- | ----------- | | `hint` | `{}` | | ## Best practices **Do** - Use a clear label that explains what is being measured. - Set a sensible `defaultUnit` for the most common case. - Choose the right `measurementType` so the available units match the use case. **Don't** - Do not use **Unit Field** when the unit is fixed and never changes. - Do not use it for non-measurement values such as counts or identifiers. - Do not hide the meaning of the measurement behind a vague label. ## Behavior - **Unit Field** combines [**Number Field**](https://meteor.shopware.com/components/number-field) behavior with a unit selector. - Changing the selected unit can convert the current value to keep the measurement consistent. - `measurementType` controls which units are available, and `defaultUnit` controls the current selection. ## Accessibility - Always provide a visible label so users understand what the measurement refers to. - Make sure unit changes remain understandable, especially when the displayed numeric value updates after conversion. - Use help text when users need guidance about accepted ranges or preferred units. ## Related components - [**Number Field**](https://meteor.shopware.com/components/number-field): when the value is numeric and the unit is fixed or communicated elsewhere. # URL Field ```vue ``` ## Usage **URL Field** is a single-line input for entering and normalizing a web address such as external links, landing pages, or reference URLs stored in forms. Use it when the value should point to a website or route, and when protocol handling like `https://` and `http://` should stay visible and easy to change. ```ts import { MtUrlField } from "@shopware-ag/meteor-component-library"; ``` ## Examples ### Disabled ```vue ``` ### Error ```vue ``` ### Hint ```vue ``` ## API reference ### Props | Prop | Type | Default | Description | | ---------------------- | ---------------------- | ----------- | ------------------------------------------------------------------------------------ | | `omit-url-hash` | `boolean` | | | | `omit-url-search` | `boolean` | | | | `copyable` | `boolean` | | | | `error` | `{ detail: string; }` | | | | `label` | `string` | | | | `required` | `boolean` | | | | `is-inheritance-field` | `boolean` | | | | `is-inherited` | `boolean` | | | | `help-text` | `string` | | | | `disabled` | `boolean` | | | | `placeholder` | `string` | | | | `name` | `string` | | | | `size` | `"default" \| "small"` | `"default"` | | | `hint` | `string \| null` | | Optional caption below the field. The \`#hint\` slot takes precedence when provided. | | `model-value` | `string` | | | ### Events | Event | Payload | Description | | --------------------- | ------------------------------ | ----------- | | `update:modelValue` | `[value: string \| undefined]` | | | `change` | `[value: string]` | | | `inheritance-remove` | `[]` | | | `inheritance-restore` | `[]` | | ### Slots | Slot | Bindings | Description | | -------- | -------- | ----------- | | `suffix` | `any` | | | `hint` | `any` | | ## Best practices **Do** - Use a clear label such as `Website` or `Target URL`. - Add help text when users need rules about valid links or allowed domains. - Enable `copyable` when users often reuse the saved URL elsewhere. **Don't** - Do not use **URL Field** for general text input. - Do not ask users to type the full protocol if the field already helps manage it. - Do not use it for multiple links in one field. ## Behavior - **URL Field** uses a native `type="url"` input and keeps the protocol toggle visible beside the input. - The component normalizes entered URLs and can omit search parameters or hashes when configured. - `copyable` adds a quick way to copy the current URL from the field. ## Accessibility - Always provide a visible label so users know what kind of link is expected. - Keep help text specific when only certain URLs or domains are allowed. - Make sure the final saved URL is understandable if the protocol toggle changes the output value. ## Related components - [**Text Field**](https://meteor.shopware.com/components/text-field): when the value is general text and should not be normalized as a URL. # Inset ## Usage **Inset** lets content break out to the edges of a padded container by consuming that container's inset spacing variables. Use it inside a padded surface such as [**Card**](https://meteor.shopware.com/components/card), for example in a `footer` slot that needs its own full-width background, when an inner block should align to the container's outer edges instead of the content padding. Use it only inside components that define the inset spacing variables it consumes. ```ts import { MtInset } from "@shopware-ag/meteor-component-library"; ``` ## Example **Inset** has no visual style of its own. It reads the inset spacing variables from its container and applies matching negative margins so its content reaches the container edges: ```vue Regular padded content. Full-bleed block inside the card. ``` ## CSS variables **Inset** pulls each edge outward by the amount its container sets on these variables. A container that does not define them (the default) leaves the content in place. | Variable | Effect | | ------------------------- | ------------------------- | | `--mt-inset-block-start` | Pulls the top edge out | | `--mt-inset-inline-end` | Pulls the right edge out | | `--mt-inset-block-end` | Pulls the bottom edge out | | `--mt-inset-inline-start` | Pulls the left edge out | ## Related components - [**Card**](https://meteor.shopware.com/components/card): when you need the full bordered surface with a header, content, and footer that defines the inset spacing for you. # Theme Provider ## Usage **Theme Provider** wraps your application, or any subtree, and provides shared settings to the Meteor components inside it. Its main use today is opting into future flags: behavior that becomes the default in the next major release. Enabling them early keeps your application aligned with where the library is heading and reduces the work required when you upgrade. ```vue ``` The `future` prop takes an object. All flags default to `false`, so behavior is unchanged until you opt in. The optional `all` key sets the baseline, and any individual flag you list overrides it, so `{ all: true }` enables every current *and* upcoming flag automatically. | Goal | `future` value | | ------------------------------- | -------------------------------------------------- | | Opt out of everything (default) | Omit the prop, or don't mount a Theme Provider | | Opt into one flag | `{ removeCardWidth: true }` | | Opt into several flags | `{ removeCardWidth: true, bannerFullWidth: true }` | | Opt into everything | `{ all: true }` | | Opt into everything except one | `{ all: true, removeCardWidth: false }` | ## Future flags | Flag | Effect | | ----------------------- | ------------------------------------------------------------------------------------------------------------ | | `removeCardWidth` | Removes the maximum width constraint from `mt-card`. | | `removeDefaultMargin` | Removes the default outer margin from components such as cards, tabs, checkboxes, switches, and text fields. | | `removeSwitchMinHeight` | Removes the minimum height from a non-bordered `mt-switch`. | | `bannerFullWidth` | Makes `mt-banner` span the full width of its container. | # useFutureFlags ::note `useFutureFlags` is internal to the component library and is not exported from the package. It is documented for contributors building or extending Meteor components. Applications opt into flags through the [**Theme Provider**](https://meteor.shopware.com/utilities/components/theme-provider) `future` prop, not this composable. :: ## Usage `useFutureFlags` returns the future flags currently provided by the nearest [**Theme Provider**](https://meteor.shopware.com/utilities/components/theme-provider). Call it inside a component to adapt behavior when a flag is enabled, for example dropping a default margin once `removeDefaultMargin` is on. When no Theme Provider is mounted, every flag falls back to `false`. ```ts import { computed } from "vue"; import { useFutureFlags } from "../../composables/useFutureFlags"; const futureFlags = useFutureFlags(); const hasDefaultMargin = computed(() => !futureFlags.removeDefaultMargin); ``` ## API `useFutureFlags()` returns a `FutureFlags` object: | Flag | Type | Default | Description | | ----------------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------ | | `removeCardWidth` | `boolean` | `false` | Removes the maximum width constraint from `mt-card`. | | `removeDefaultMargin` | `boolean` | `false` | Removes the default outer margin from components such as cards, tabs, checkboxes, switches, and text fields. | | `removeSwitchMinHeight` | `boolean` | `false` | Removes the minimum height from a non-bordered `mt-switch`. | | `bannerFullWidth` | `boolean` | `false` | Makes `mt-banner` span the full width of its container. | ## Related - [**Theme Provider**](https://meteor.shopware.com/utilities/components/theme-provider): provides the flags this composable reads. # useSnackbar ```vue ``` ## Usage `useSnackbar` publishes [**Snackbar**](https://meteor.shopware.com/components/snackbar) notifications from anywhere in your application. It uses a global store, so mount a single `mt-snackbar` host near your app shell and then call `addSnackbar` wherever the action happens; the host renders the shared stack. ```ts import { useSnackbar } from "@shopware-ag/meteor-component-library"; const { addSnackbar } = useSnackbar(); addSnackbar({ message: "Changes saved", variant: "success" }); ``` ## API `useSnackbar()` returns: | Member | Type | Description | | ---------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------- | | `snackbars` | `Readonly>` | The reactive, read-only list of active snackbars that the `mt-snackbar` host renders. | | `addSnackbar` | `(snackbar: Omit) => Snackbar` | Adds a snackbar to the stack and returns it with a generated `id`. Defaults `duration` to `5000`. | | `removeSnackbar` | `(id: string) => void` | Removes the snackbar with the given `id`. | | `clearSnackbars` | `() => void` | Removes all snackbars. | ### Snackbar The shape passed to `addSnackbar` (without `id`): | Property | Type | Description | | -------------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | | `message` | `string` | The text shown in the snackbar. Required. | | `variant` | `"success" | "error" | "warning" | "progress"` | Visual style and semantics. | | `icon` | `string` | Optional leading icon name. | | `link` | `{ text: string; url: string }` | Optional single follow-up link. | | `duration` | `number` | Auto-dismiss delay in milliseconds. Defaults to `5000`. Set it to `0` to disable auto-dismiss and remove the snackbar yourself with `removeSnackbar`. | | `progressPercentage` | `number` | Current progress from `0` to `100`, for `progress` snackbars. | | `uploadState` | `"success" | "error"` | Terminal state that resolves a `progress` snackbar. | | `successMessage` | `string` | Message shown when a `progress` snackbar resolves successfully. | | `errorMessage` | `string` | Message shown when a `progress` snackbar resolves with an error. | ## Related components - [**Snackbar**](https://meteor.shopware.com/components/snackbar): the component that renders the notifications this composable publishes. # useTheme ```vue ``` ## Usage `useTheme` manages the application color theme. It tracks the user's preference (`light`, `dark`, or `system`), resolves `system` against the operating system via `prefers-color-scheme`, writes the resolved value to a target element's `data-theme` attribute (the document root by default), and persists the choice to `localStorage`. Bind the returned `theme` ref to [**Theme Select**](https://meteor.shopware.com/components/theme-select) with `v-model` to let users control it. ```ts import { useTheme } from "@shopware-ag/meteor-component-library"; const { theme, resolvedTheme, setTheme, stop } = useTheme(); ``` The preference is shared: instances using the same `storageKey` stay in sync within the document and across browser tabs. ## API ### Options `useTheme(options?)` accepts: | Option | Type | Description | | --------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `storageKey` | `string | null` | The `localStorage` key used to persist the preference. Defaults to `"mt-theme"`. Set it to `null` to disable persistence. | | `target` | `HTMLElement` | The element whose `data-theme` attribute is kept in sync with the resolved theme. Defaults to `document.documentElement`. | | `defaultTheme` | `"light" | "dark" | "system"` | The preference used when nothing has been persisted yet. Defaults to `"system"`. | | `applyToTarget` | `boolean` | Whether to write the resolved theme to the target's `data-theme` attribute. Defaults to `true`. Disable it when the host applies the theme itself. | ### Return value | Member | Type | Description | | --------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `theme` | `Ref` | The user's preference: `"light"`, `"dark"`, or `"system"`. Writable; bind it to [**Theme Select**](https://meteor.shopware.com/components/theme-select) with `v-model`. | | `resolvedTheme` | `ComputedRef` | The applied theme after resolving `"system"`: `"light"` or `"dark"`. | | `setTheme` | `(theme: Theme) => void` | Sets the preference programmatically. | | `stop` | `() => void` | Releases all listeners. Called automatically on scope disposal when used inside a component or `effectScope`; call it manually when using the composable outside of an active scope. | ### Types ```ts type Theme = "light" | "dark" | "system"; type ResolvedTheme = "light" | "dark"; ``` ## Behavior - While the preference is `system`, `resolvedTheme` updates live when the operating system preference changes. - Invalid persisted values are ignored and fall back to `defaultTheme`. - Meteor tokens are theme-aware through `data-theme`, so applying the resolved theme to the document root themes every Meteor component on the page. ## Related components - [**Theme Select**](https://meteor.shopware.com/components/theme-select): the select component built for choosing the theme this composable manages. # Tooltip ## Usage The `v-tooltip` directive attaches a tooltip to any element. Register it once on your app, then bind either a string or an options object. For interactive tooltips, HTML content, or focus support, use the [**Tooltip**](https://meteor.shopware.com/components/tooltip) component instead. ```ts import { TooltipDirective } from "@shopware-ag/meteor-component-library"; app.directive("tooltip", TooltipDirective); ``` ```vue ``` ## Options Bind a string (the message) or an object with: | Option | Type | Default | Description | | ------------------------ | ------------------------------------- | ----------- | ---------------------------------------------------------------------------- | | `message` | `string` | required | The tooltip text. | | `position` | `"top" | "right" | "bottom" | "left"` | `"top"` | Placement relative to the element. Takes priority over a placement modifier. | | `width` | `number | "auto"` | `200` | Tooltip width in pixels, or `"auto"`. | | `showDelay` | `number` | `100` | Delay in milliseconds before showing on hover. | | `hideDelay` | `number` | `showDelay` | Delay in milliseconds before hiding. | | `disabled` | `boolean` | `false` | Disables the tooltip so it never shows. | | `appearance` | `string` | `"dark"` | Adds a `mt-tooltip--` class for custom styling. | | `showOnDisabledElements` | `boolean` | `false` | Wraps the element so the tooltip still shows while it is disabled. | | `zIndex` | `number` | none | Explicit stacking order for the tooltip layer. | The placement can also be set with a modifier, such as `v-tooltip.bottom`. When both are present, `position` wins. ## Related components - [**Tooltip**](https://meteor.shopware.com/components/tooltip): when you need an interactive tooltip, formatted content, or keyboard focus support. # Device helper ## Usage **Device Helper** is a Vue plugin that adds a `$device` helper to every component for reading viewport, screen, and platform information, and for reacting to viewport resizes. ```ts import { DeviceHelperPlugin } from "@shopware-ag/meteor-component-library"; app.use(DeviceHelperPlugin); ``` Once installed, use `this.$device` in any component: ```ts const width = this.$device.getViewportWidth(); const platform = this.$device.getPlatform(); ``` ## API `$device` exposes: | Method | Returns | Description | | ------------------------------------------ | ------------------- | -------------------------------------------------------- | | `getViewportWidth()` | `number` | Current viewport width in pixels. | | `getViewportHeight()` | `number` | Current viewport height in pixels. | | `getScreenWidth()` | `number` | Screen width in pixels. | | `getScreenHeight()` | `number` | Screen height in pixels. | | `getDevicePixelRatio()` | `number` | The device pixel ratio. | | `getScreenOrientation()` | `ScreenOrientation` | The current screen orientation. | | `getUserAgent()` | `string` | The browser user agent string. | | `getBrowserLanguage()` | `string` | The browser language. | | `getPlatform()` | `string` | The operating system platform. | | `getSystemKey()` | `string` | The platform system modifier key (Control or Command). | | `onResize({ listener, scope, component })` | `number` | Registers a viewport resize listener and returns its id. | | `removeResizeListener(component)` | `boolean` | Removes the resize listeners registered for a component. |