# svar-vue - full bundle _Generated 2026-05-08T11:33:57.443Z_ ## Contents - [`SKILL.md`](#file-skill-md) - [`locales.md`](#file-locales-md) - [`themes.md`](#file-themes-md) - [`core/index.md`](#file-core-index-md) - [`core/avatar.md`](#file-core-avatar-md) - [`core/button.md`](#file-core-button-md) - [`core/calendar.md`](#file-core-calendar-md) - [`core/checkbox.md`](#file-core-checkbox-md) - [`core/colorboard.md`](#file-core-colorboard-md) - [`core/colorpicker.md`](#file-core-colorpicker-md) - [`core/colorselect.md`](#file-core-colorselect-md) - [`core/combo.md`](#file-core-combo-md) - [`core/counter.md`](#file-core-counter-md) - [`core/datepicker.md`](#file-core-datepicker-md) - [`core/daterangepicker.md`](#file-core-daterangepicker-md) - [`core/dropdown.md`](#file-core-dropdown-md) - [`core/field.md`](#file-core-field-md) - [`core/fullscreen.md`](#file-core-fullscreen-md) - [`core/globals.md`](#file-core-globals-md) - [`core/icon.md`](#file-core-icon-md) - [`core/locale.md`](#file-core-locale-md) - [`core/modal.md`](#file-core-modal-md) - [`core/modalarea.md`](#file-core-modalarea-md) - [`core/month.md`](#file-core-month-md) - [`core/multicombo.md`](#file-core-multicombo-md) - [`core/pager.md`](#file-core-pager-md) - [`core/popup.md`](#file-core-popup-md) - [`core/portal.md`](#file-core-portal-md) - [`core/radio.md`](#file-core-radio-md) - [`core/rangecalendar.md`](#file-core-rangecalendar-md) - [`core/richselect.md`](#file-core-richselect-md) - [`core/segmented.md`](#file-core-segmented-md) - [`core/select.md`](#file-core-select-md) - [`core/sidearea.md`](#file-core-sidearea-md) - [`core/slider.md`](#file-core-slider-md) - [`core/suggest-dropdown.md`](#file-core-suggest-dropdown-md) - [`core/switch.md`](#file-core-switch-md) - [`core/tabs.md`](#file-core-tabs-md) - [`core/text.md`](#file-core-text-md) - [`core/textarea.md`](#file-core-textarea-md) - [`core/themes.md`](#file-core-themes-md) - [`core/timepicker.md`](#file-core-timepicker-md) - [`core/twostate.md`](#file-core-twostate-md) - [`menu/index.md`](#file-menu-index-md) - [`toolbar/index.md`](#file-toolbar-index-md) - [`layout/index.md`](#file-layout-index-md) - [`grid/index.md`](#file-grid-index-md) - [`editor/index.md`](#file-editor-index-md) - [`filter/index.md`](#file-filter-index-md) - [`filter/FilterBar.md`](#file-filter-filterbar-md) - [`filter/FilterBuilder.md`](#file-filter-filterbuilder-md) - [`filter/FilterEditor.md`](#file-filter-filtereditor-md) - [`filter/FilterQuery.md`](#file-filter-filterquery-md) - [`gantt/index.md`](#file-gantt-index-md) - [`tasklist/index.md`](#file-tasklist-index-md) - [`comments/index.md`](#file-comments-index-md) - [`filemanager/index.md`](#file-filemanager-index-md) ## File: SKILL.md > Source: `SKILL.md` SVAR Vue ships as a family of `@svar-ui/vue-*` packages. This file routes to the per-package entry; each child file is standalone and contains the imports, public types, styling hooks, and recipes for its components. Open the matching file for the package you are using. If the component you need is not listed in the routing table below, default to `core/index.md` #### Component Routing | File | Package | Components | | ---------------------- | ------------------------ | ------------------------------------------------------------------------------------------- | | `core/index.md` | `@svar-ui/vue-core` | buttons, inputs, selectors, calendars, dropdowns, popups, modals, themes, locale (40+ widgets) | | `menu/index.md` | `@svar-ui/vue-menu` | `Menu`, `MenuBar`, `DropDownMenu`, `ContextMenu`, `ActionMenu` | | `toolbar/index.md` | `@svar-ui/vue-toolbar` | `Toolbar` | | `layout/index.md` | `@svar-ui/vue-layout` | `Layout`, `Cell`, `Panel` | | `grid/index.md` | `@svar-ui/vue-grid` | `Grid`, `HeaderMenu`, `Tooltip`, `ContextMenu`, `Toolbar` | | `editor/index.md` | `@svar-ui/vue-editor` | `Editor` | | `filter/index.md` | `@svar-ui/vue-filter` | `FilterBuilder`, `FilterEditor`, `FilterBar`, `FilterQuery` | | `gantt/index.md` | `@svar-ui/vue-gantt` | `Gantt`, `Toolbar`, `ContextMenu`, `Editor`, `Tooltip`, `HeaderMenu` | | `tasklist/index.md` | `@svar-ui/vue-tasklist` | `Tasklist` | | `comments/index.md` | `@svar-ui/vue-comments` | `Comments` | | `filemanager/index.md` | `@svar-ui/vue-filemanager` | `Filemanager` | #### Common Techniques These apply to every `@svar-ui/vue-*` package: - `themes.md` - theme wrappers, CSS variables, the `css` prop convention, class hooks - `locales.md` - locale context, bundled language packs, extending words and formats The widget hierarchy need to be wrapped in a theme component to ensure proper styling Some widgets (grid,gantt,filemanager, etc) exports their own theme components that delegate to core theme and add their own variables ## File: locales.md > Source: `locales.md` i18n patterns common to all SVAR Vue components - Locale wrapper, bundled language packs, extending words and formats ### Localizing SVAR Vue Components All `@svar-ui/vue-*` widgets read locale data from a single Vue inject key (`wx-i18n`). The mechanics live in `@svar-ui/vue-core`; every other package consumes them. #### Locale Wrapper Wrap the subtree you want to localize. With no wrapper, widgets fall back to English. ```vue ``` Wrap the smallest subtree that needs the alternative locale - nested `Locale` blocks let different parts of the app render in different languages. `Locale` does not render any DOM wrapper; it only mutates the injected context, so it never affects layout. #### Bundled Language Packs Core packs ship in `@svar-ui/core-locales`: ```js import { en, cn, de, es, fr, it, ja, pt, ru } from "@svar-ui/core-locales"; ``` Standalone widget packages ship their own dictionaries alongside the core pack - each exports locale objects keyed by language code (`cn`, `de`, `fr`, ...): - `@svar-ui/core-locales` - core widgets (always include) - `@svar-ui/editor-locales` - Editor - `@svar-ui/filter-locales` - Filter - `@svar-ui/gantt-locales` - Gantt - `@svar-ui/filemanager-locales` - File Manager - `@svar-ui/grid-locales` - Grid If you see English fallbacks in a localized UI, the missing terms come from the package's own locale module - merge them in via ``. To localize a standalone widget, merge the matching package locale with the core locale: ```vue ``` #### Extending Or Overriding Words `Locale words` accepts a partial pack and extends the current context. Spread an existing pack to keep its formats and override only what you need: ```vue ``` Pass `:optional="true"` to make merged terms additive fallbacks rather than overrides - useful for layering app-specific strings on top of a full pack. #### Affected Surfaces Locale changes calendar labels, date/time formats, modal buttons, pager strings, empty-list text, notice/modal helpers, color-board select text - any widget that displays static strings or formats values reads them through this context. #### Direct Helper For non-component code, use the `locale` helper to build a translator: ```js import { en, locale } from "@svar-ui/vue-core"; const i18n = locale(en).extend( { core: { "Rows per page": "Rows" } }, true ); const _ = i18n.getGroup("core"); _("Rows per page"); // "Rows" ``` ## File: themes.md > Source: `themes.md` ### Styling SVAR Vue Components All `@svar-ui/vue-*` widgets share the same theming pipeline. The mechanics live in `@svar-ui/vue-core`; every other package consumes them. #### Per widget css files Each package ships `style.css` (this component only) and `all.css` (this component plus all dependencies). ```css @import "@svar-ui/vue-gantt/style.css"; ``` #### Theme Wrapper Wrap the part of the app that uses SVAR widgets in a theme component from `@svar-ui/vue-core`: ```vue ``` Available themes: `Willow`, `WillowDark`. The wrapper: - provides the Vue inject key `wx-theme` - renders `.wx-theme.wx-{name}-theme` with `height:100%` - loads Open Sans + the `wxi` icon CSS by default; pass `:fonts="false"` to skip when the host app manages fonts itself Without a theme wrapper widgets still render but lose theme variables and font/icon CSS. #### Per-widget Willow / WillowDark themes Several widgets ship their **own** `Willow` / `WillowDark` components on top of the core base. The widget version wraps the core theme and layers in widget-specific CSS variables (bar colors, grid borders, timescale fonts, etc.). When using such a widget, import the theme from the widget package - not from core - so both layers apply. Widgets that expose custom `Willow` / `WillowDark` themes: - `@svar-ui/vue-core` - base - `@svar-ui/vue-gantt` - `@svar-ui/vue-grid` - `@svar-ui/vue-editor` - `@svar-ui/vue-filter` - `@svar-ui/vue-filemanager` - `@svar-ui/vue-comments` - `@svar-ui/vue-kanban` The widget theme delegates to core and adds extra rules scoped to `.wx-willow-theme` (or `.wx-willow-dark-theme`): ```vue ``` Mount the widget's own theme once at the app root. The wrapper internally renders the core `Willow`, so a separate core import is not needed: ```vue ``` #### CSS Variables Theme styling is variable-driven. Override variables on the theme wrapper or on any ancestor of the widgets you want to restyle - overrides cascade to every SVAR widget in the subtree. ```vue ``` Nest different wrapper blocks for per-section restyling without forking the theme. #### `css` Prop Convention Most widgets accept a `css` prop. The string is appended to the widget's root class, so it works as a parent styling hook: ```vue ``` Composite widgets often expose secondary css props for nested popups (`menuCss` on `Toolbar`/`MenuBar`, etc.). Check the per-component file for the exact set. #### Class Hooks The per-component file lists the exact selectors that widget exposes. #### Custom CSS class overrides When writing custom rules to override widget styles, always use **at least two selectors** (e.g. `.a .b {}`). Vue scopes its component styles by appending a hash attribute which has higher specificity than a plain `.b`. A two-selector rule (`.a .b`) matches or beats that specificity and wins. Convention: the first selector is a container/wrapper of the widget instance, the second is the inner class you want to alter: ```css .my-gantt-host .wx-bar-task { background: #ff8800; } ``` #### Override Order Prefer in this order: 1. **CSS variables on a wrapper** - propagates consistently to every widget in the subtree. 2. **`css` prop class** - a stable parent hook that survives internal markup changes. 3. **Direct `.wx-*` selectors** - targeted overrides; tightest coupling to widget internals, use sparingly. #### Core Vars ##### Base Colors | Variable | Default | Use for | |---|---|---| | `--wx-color-primary` | `#37a9ef` | Primary accent - active states, selected items, links | | `--wx-color-primary-selected` | `#d5eaf7` | Selected/highlighted row or item background | | `--wx-color-primary-font` | `#fff` | Text on primary-colored backgrounds | | `--wx-color-secondary` | `transparent` | Secondary/ghost element background | | `--wx-color-secondary-hover` | `rgba(55, 169, 239, 0.12)` | Secondary hover background | | `--wx-color-secondary-font` | `#37a9ef` | Secondary element text | | `--wx-color-secondary-border` | `#37a9ef` | Secondary element border | | `--wx-color-success` | `#77d257` | Success indicator | | `--wx-color-warning` | `#fcba2e` | Warning indicator | | `--wx-color-info` | `#37a9ef` | Info indicator | | `--wx-color-danger` | `#fe6158` | Error/destructive state, error borders | | `--wx-color-disabled` | `#f2f3f7` | Disabled element background | | `--wx-color-disabled-alt` | `#e9e9e9` | Alternate disabled background | | `--wx-color-font` | `#2c2f3c` | Primary text | | `--wx-color-font-alt` | `#9fa1ae` | Secondary/muted text, placeholders | | `--wx-color-font-disabled` | `#c0c3ce` | Disabled text | | `--wx-color-link` | `#37a9ef` | Link text | | `--wx-background` | `#ffffff` | Main surface | | `--wx-background-alt` | `#f2f3f7` | Alternate surface (cards, tags, odd/even areas) | | `--wx-background-hover` | `#eaedf5` | Hover state background | ##### Typography | Variable | Default | Use for | |---|---|---| | `--wx-font-family` | `"Open Sans", Arial, Helvetica, sans-serif` | All text | | `--wx-font-size` | `14px` | Body text | | `--wx-line-height` | `20px` | Body line height | | `--wx-font-size-md` | `14px` | Medium text | | `--wx-line-height-md` | `24px` | Medium line height | | `--wx-font-size-hd` | `16px` | Headings | | `--wx-line-height-hd` | `30px` | Heading line height | | `--wx-font-size-sm` | `12px` | Captions, small text | | `--wx-line-height-sm` | `16px` | Small line height | | `--wx-font-weight` | `400` | Normal weight | | `--wx-font-weight-md` | `600` | Semi-bold (labels, buttons) | | `--wx-font-weight-b` | `700` | Bold (modal headers) | ##### Icons | Variable | Default | Use for | |---|---|---| | `--wx-icon-color` | `#9fa1ae` | Default icon tint | | `--wx-icon-size` | `20px` | Icon dimensions | | `--wx-icon-border-radius` | `2px` | Icon hover-state rounding | ##### Borders, Shadows, Spacing | Variable | Default | Use for | |---|---|---| | `--wx-border` | `1px solid #e6e6e6` | Standard border | | `--wx-border-radius` | `3px` | Default corner radius | | `--wx-radius-major` | `6px` | Larger radius (cards, panels) | | `--wx-border-light` | `none` | Subtle divider | | `--wx-border-medium` | `1px solid #eaedf5` | Medium divider | | `--wx-shadow-light` | `0px 3px 10px ...` | Elevated panels (popups, dropdowns) | | `--wx-shadow-medium` | `0px 4px 20px ...` | High-elevation surfaces (modals) | | `--wx-padding` | `8px` | Base spacing unit | ##### Layout | Variable | Default | Use for | |---|---|---| | `--wx-field-gutter` | `16px` | Vertical gap between form rows | | `--wx-field-width` | `400px` | Max width of a form field row | ##### Z-index Scale | Layer | Value | |---|---| | Popups / dropdowns | `100` | | Modals | `1000` | | Notices / toasts | `1010` | ## File: core/index.md > Source: `core/index.md` Use when building, configuring, styling, or modifying SVAR Vue Core / @svar-ui/vue-core widgets, themes, locale, forms, popups, selectors, calendars, buttons, and display components This is an index file. Open the focused widget file that matches the component you are using. Each child file is standalone and contain all critical info needed for that widget. #### Package ```js import { TextArea, Button, Checkbox, CheckboxGroup, ColorSelect, ColorBoard, ColorPicker, Combo, DatePicker, DateRangePicker, Fullscreen, Avatar, Icon, MultiCombo, Popup, Dropdown, Pager, RadioButton, RadioButtonGroup, RichSelect, Segmented, Select, Slider, Switch, Tabs, Text, Counter, Globals, Field, Calendar, Month, RangeCalendar, TimePicker, TwoState, Modal, ModalArea, SideArea, Portal, Willow, WillowDark, Locale, locale, popupContainer, SuggestDropdown, en, } from "@svar-ui/vue-core"; import "@svar-ui/vue-core/all.css"; ``` #### Widget Index - `button.md` - `Button` - `twostate.md` - `TwoState` - `icon.md` - `Icon` - `checkbox.md` - `Checkbox`, `CheckboxGroup` - `radio.md` - `RadioButton`, `RadioButtonGroup` - `switch.md` - `Switch` - `segmented.md` - `Segmented` - `tabs.md` - `Tabs` - `field.md` - `Field` - `text.md` - `Text` - `textarea.md` - `TextArea` - `counter.md` - `Counter` - `slider.md` - `Slider` - `select.md` - `Select` - `combo.md` - `Combo` - `multicombo.md` - `MultiCombo` - `richselect.md` - `RichSelect` - `suggest-dropdown.md` - `SuggestDropdown` - `dropdown.md` - `Dropdown` - `popup.md` - `Popup` - `portal.md` - `Portal`, `popupContainer` - `colorselect.md` - `ColorSelect` - `colorboard.md` - `ColorBoard` - `colorpicker.md` - `ColorPicker` - `calendar.md` - `Calendar` - `month.md` - `Month` - `rangecalendar.md` - `RangeCalendar` - `datepicker.md` - `DatePicker` - `daterangepicker.md` - `DateRangePicker` - `timepicker.md` - `TimePicker` - `avatar.md` - `Avatar` - `pager.md` - `Pager` - `fullscreen.md` - `Fullscreen` - `modal.md` - `Modal` - `modalarea.md` - `ModalArea` - `sidearea.md` - `SideArea` - `globals.md` - `Globals`, `showNotice`, `showModal` - `themes.md` - `Willow`, `WillowDark`, theme CSS variables - `locale.md` - `Locale`, `locale`, `en`, bundled locale imports #### Shared Contracts - Most controls expose bindable `value` and an `onchange` callback. Event payloads differ by widget and are documented in each file. - Option-based widgets generally use `{ id, label }` options and emit selected ids as values. - Dropdown-backed widgets share `DropdownOptions` for position, align, width, inline mode, scroll tracking, and virtualization. ## File: core/avatar.md > Source: `core/avatar.md` ### SVAR Vue Core Avatar Package: `@svar-ui/vue-core` #### Package ```js import { Avatar } from "@svar-ui/vue-core"; ``` #### Supported Functionality - Displays one user or a stack of users. - User object fields are `id`, `name`, `avatar`, and `color`. - `size` controls circle size and computed font size; default is `32`. - `limit` caps visible users before responsive fitting is applied. - When users are hidden, the last visible avatar shows a `+N` overlay. - If `avatar` is present, it renders an image; otherwise initials are derived from `name`. #### Public Types ```ts import type { Component } from "vue"; export interface IUser { id: string | number; name?: string; avatar?: string; color?: string; } export declare const Avatar: Component<{ value: IUser | IUser[]; size?: number; limit?: number; }>; ``` #### Styling - Root: `.wx-avatar-root` - Stack: `.wx-avatar-stack` - Avatar item: `.wx-avatar`, `.wx-avatar-item` - Overflow state and badge: `.wx-avatar-overflow`, `.wx-avatar-overflow-badge` - Image selector: `.wx-avatar img` - Initial text selector: `.wx-avatar span` ```vue ``` #### Recipes ##### User Stack With Responsive Overflow ```vue ``` ##### Single Initial Avatar ```vue ``` ## File: core/button.md > Source: `core/button.md` ### SVAR Vue Core Button Package: `@svar-ui/vue-core` #### Package ```js import { Button } from "@svar-ui/vue-core"; ``` #### Supported Functionality - Renders a native `