Open source component-level UI library for Vue.js.
npm i @codemonster-ru/vueforgePeer dependencies:
vue(v3)vue-router(v4)@codemonster-ru/vueiconify
import { createApp } from 'vue';
import {
VueForge,
DefaultTheme,
Button,
Input,
NumberInput,
FormField,
Textarea,
FileUpload,
Breadcrumbs,
Select,
Autocomplete,
MultiSelect,
DatePicker,
DateRangePicker,
TimePicker,
Pagination,
DataTable,
Checkbox,
Switch,
Alert,
Skeleton,
Progress,
Badge,
Chip,
Accordion,
AccordionItem,
Slider,
Stepper,
Rating,
Drawer,
Dropdown,
} from '@codemonster-ru/vueforge';
import '@codemonster-ru/vueforge/dist/index.css';
const app = createApp(App);
app.use(VueForge, {
theme: {
preset: DefaultTheme,
},
});<Button label="Hello" severity="primary" />
<FormField label="Name" hint="Required field">
<Input v-model="name" placeholder="Your name" />
</FormField>
<NumberInput v-model="age" :min="0" :max="120" :step="1" />
<Textarea v-model="bio" placeholder="Tell us about yourself" />
<FileUpload v-model="resume" accept=".pdf,.doc,.docx" />
<Breadcrumbs :items="breadcrumbItems" />
<Select v-model="role" :options="roles" placeholder="Choose role" />
<Autocomplete v-model="country" :options="countries" placeholder="Find country" />
<MultiSelect v-model="countries" :options="countryOptions" placeholder="Select countries" clearable />
<DatePicker v-model="birthday" placeholder="Pick birthday" />
<DateRangePicker v-model="range" placeholder="Pick range" />
<TimePicker v-model="meetingTime" placeholder="Pick time" />
<Pagination v-model="page" :total-items="240" :page-size="20" />
<DataTable :columns="columns" :rows="rows" sortable striped />
<Checkbox v-model="agreed" label="I agree" />
<Switch v-model="darkMode" label="Dark mode" />
<Alert severity="info" title="Heads up" message="Project settings were updated." />
<Skeleton height="12px" width="140px" />
<Progress :value="64" />
<Badge label="Beta" />
<Chip label="New" />
<Slider v-model="volume" :min="0" :max="100" :step="5" show-value />
<Stepper v-model="step" :steps="steps" clickable />
<Rating v-model="rating" allow-half />
<Accordion v-model="faq">
<AccordionItem value="shipping" title="Shipping">
Shipping details
</AccordionItem>
<AccordionItem value="returns" title="Returns">
Returns policy
</AccordionItem>
</Accordion>
<Drawer v-model="drawerOpen" title="Filters" position="right">
<template #body>
Drawer content
</template>
</Drawer>
<Dropdown :items="menuItems">
<template #trigger>
<Button label="Actions" />
</template>
</Dropdown>- Button
- Card
- Checkbox
- RadioGroup
- RadioButton
- Tabs
- Tab
- TabPanel
- Accordion
- AccordionItem
- Toast
- ToastContainer
- Alert
- Input
- NumberInput
- FormField
- Textarea
- FileUpload
- Link
- Breadcrumbs
- Menu
- Modal
- Drawer
- Dropdown
- Popover
- Select
- Autocomplete
- MultiSelect
- DatePicker
- DateRangePicker
- TimePicker
- Pagination
- DataTable
- Switch
- Tooltip
- Skeleton
- Progress
- Badge
- Chip
- Avatar
- Slider
- Stepper
- Rating
Input / Textarea (quick API):
Input: single-line control, supportsv-model,size,variant,disabled,readonly.NumberInput: numeric control, supportsv-model,min,max,step,precision,controls,size,variant.Textarea: multi-line control, same as Input plusrows.Checkbox,Select,Autocomplete,MultiSelect,DatePicker,DateRangePicker,Pagination, andDataTablealso supportvariant: 'filled' | 'outlined'.
Props:
id?: string(used inlabel forand slot props)label?: stringhint?: stringerror?: stringrequired?: booleandisabled?: booleansize?: 'small' | 'normal' | 'large'(defaultnormal)
Slots:
default- form control wrapper slot props:{ id, describedBy, invalid, required }label(optional)hint(optional)error(optional)
Example:
<FormField label="Email" hint="We never share it" :error="emailError">
<template #default="{ id, describedBy }">
<Input :id="id" v-model="email" :aria-describedby="describedBy" placeholder="name@example.com" />
</template>
</FormField>Note: default filled backgrounds for Input/Select/Textarea use controls.backgroundColor (defaults to bgSoftColor). Set it to bgColor to disable soft backgrounds.
Props:
modelValue?: string | number(v-model)options?: Array<{ label: string; value: string | number; disabled?: boolean }>optionLabel?: string(defaultlabel)optionValue?: string(defaultvalue)placeholder?: stringdisabled?: booleanreadonly?: booleanloading?: booleanloadingText?: string(defaultLoading...)emptyText?: string(defaultNo results)filter?: boolean(defaulttrue)size?: 'small' | 'normal' | 'large'(defaultnormal)variant?: 'filled' | 'outlined'(defaultfilled)
Events:
update:modelValuechangesearchfocusblur
Example:
<Autocomplete v-model="country" :options="countries" placeholder="Find country" />Props:
modelValue?: Array<string | number>(v-model)options?: Array<{ label: string; value: string | number; disabled?: boolean }>optionLabel?: string(defaultlabel)optionValue?: string(defaultvalue)placeholder?: stringsearchPlaceholder?: string(defaultSearch...)disabled?: booleanreadonly?: booleanloading?: booleanloadingText?: string(defaultLoading...)emptyText?: string(defaultNo results)filter?: boolean(defaulttrue)clearable?: boolean(defaultfalse)size?: 'small' | 'normal' | 'large'(defaultnormal)variant?: 'filled' | 'outlined'(defaultfilled)
Events:
update:modelValuechangesearchfocusblur
Example:
<MultiSelect v-model="countries" :options="countryOptions" placeholder="Select countries" clearable />Component tokens (override via theme.overrides.components.multiselect):
minWidth,fontSize,controlGap,chevronSizepadding,borderRadius,borderColorbackgroundColor,textColor,placeholderColorfocusBorderColor,focusRingShadow,hoverBorderColordisabledOpacitypanelBackgroundColor,panelBorderColor,panelPadding,panelMaxHeight,panelRadiusOffset,panelShadowsearchPadding,searchBorderColor,searchBorderRadiusoptionPadding,optionBorderRadiusoptionHoverBackgroundColor,optionActiveBackgroundColor,optionActiveTextColor,optionHighlightedBackgroundColoremptyPadding,emptyColorloadingPadding,loadingColorclearSize,clearRadius,clearHoverBackgroundColorsmall.fontSize,small.paddinglarge.fontSize,large.padding
Props:
modelValue?: string(v-model, ISO dateYYYY-MM-DD)placeholder?: stringdisabled?: booleanreadonly?: booleanmin?: string(ISO dateYYYY-MM-DD)max?: string(ISO dateYYYY-MM-DD)locale?: string(defaulten-US)firstDayOfWeek?: number(default0, Sunday)size?: 'small' | 'normal' | 'large'(defaultnormal)variant?: 'filled' | 'outlined'(defaultfilled)
Events:
update:modelValuechangefocusblur
Example:
<DatePicker v-model="startDate" placeholder="Pick date" min="2026-01-01" max="2026-12-31" />Props:
modelValue?: [string | null, string | null] | null(v-model, ISO dateYYYY-MM-DD)placeholder?: stringstartPlaceholder?: string(defaultStart)endPlaceholder?: string(defaultEnd)separator?: string(default-)disabled?: booleanreadonly?: booleanmin?: string(ISO dateYYYY-MM-DD)max?: string(ISO dateYYYY-MM-DD)locale?: string(defaulten-US)firstDayOfWeek?: number(default0, Sunday)size?: 'small' | 'normal' | 'large'(defaultnormal)variant?: 'filled' | 'outlined'(defaultfilled)
Events:
update:modelValuechangefocusblur
Example:
<DateRangePicker v-model="dateRange" placeholder="Pick date range" min="2026-01-01" max="2026-12-31" />Props:
modelValue?: string(v-model, timeHH:mm)placeholder?: stringdisabled?: booleanreadonly?: booleanmin?: string(timeHH:mm)max?: string(timeHH:mm)step?: number(minutes, default30)format?: '24h' | '12h'(default24h)size?: 'small' | 'normal' | 'large'(defaultnormal)variant?: 'filled' | 'outlined'(defaultfilled)
Events:
update:modelValuechangefocusblur
Example:
<TimePicker v-model="meetingTime" placeholder="Pick time" min="09:00" max="18:00" :step="15" />Component tokens (override via theme.overrides.components.timepicker):
minWidth,fontSize,controlGap,chevronSizepadding,borderRadius,borderColorbackgroundColor,textColor,placeholderColorfocusBorderColor,focusRingShadow,hoverBorderColordisabledOpacitypanelBackgroundColor,panelBorderColor,panelPadding,panelMaxHeight,panelRadiusOffset,panelShadowoptionPadding,optionBorderRadiusoptionHoverBackgroundColor,optionActiveBackgroundColor,optionActiveTextColorsmall.fontSize,small.paddinglarge.fontSize,large.padding
Props:
modelValue?: number(v-model, default1)totalItems?: number(default0)pageSize?: number(default10)totalPages?: number(optional override instead oftotalItems/pageSize)siblingCount?: number(default1)boundaryCount?: number(default1)disabled?: booleansize?: 'small' | 'normal' | 'large'(defaultnormal)variant?: 'filled' | 'outlined'(defaultfilled)prevLabel?: string(defaultPrev)nextLabel?: string(defaultNext)ellipsisLabel?: string(default...)
Events:
update:modelValuechange
Slots:
indicator- slot props:{ step, index, status, active, completed, upcoming, error }step- slot props:{ step, index, status, active, completed, upcoming, error }
Example:
<Pagination v-model="page" :total-items="240" :page-size="20" />Component tokens (override via theme.overrides.components.pagination):
gap,itemMinWidth,fontSize,paddingborderRadius,borderColorbackgroundColor,textColorhoverBackgroundColoractiveBorderColor,activeBackgroundColor,activeTextColorfocusBorderColor,focusRingShadowdisabledOpacity,ellipsisPaddingsmall.fontSize,small.paddinglarge.fontSize,large.padding
Props:
rows?: Array<Record<string, unknown>>columns?: Array<{ field: string; header?: string; sortable?: boolean; align?: 'left' | 'center' | 'right'; width?: string; minWidth?: string; formatter?: (row, value, column) => string | number }>rowKey?: string | ((row, index) => string | number)sortable?: booleansortField?: string | nullsortOrder?: 'asc' | 'desc' | nullloading?: booleanloadingText?: string(defaultLoading...)emptyText?: string(defaultNo data)striped?: boolean(defaultfalse)hover?: boolean(defaulttrue)size?: 'small' | 'normal' | 'large'(defaultnormal)variant?: 'filled' | 'outlined'(defaultfilled)showHeader?: boolean(defaulttrue)ariaLabel?: string(defaultData table)
Events:
update:sortFieldupdate:sortOrdersortrowClick
Slots:
header-{field}cell-{field}emptyloading
Example:
<DataTable
:columns="[
{ field: 'name', header: 'Name', sortable: true },
{ field: 'role', header: 'Role' },
{ field: 'age', header: 'Age', align: 'right', sortable: true },
]"
:rows="[
{ id: 1, name: 'Alice', role: 'Developer', age: 29 },
{ id: 2, name: 'Bob', role: 'Designer', age: 34 },
]"
row-key="id"
sortable
striped
/>Component tokens (override via theme.overrides.components.datatable):
borderColor,borderRadius,backgroundColorfontSize,textColorheaderBackgroundColor,headerTextColor,headerFontSize,headerFontWeight,headerBorderColor,headerGaprowBackgroundColor,rowTextColor,rowBorderColorcellPaddingstripedBackgroundColor,hoverBackgroundColorsortIconColor,sortIconActiveColor,sortIconSizestatePadding,stateTextColorsmall.fontSize,small.cellPaddinglarge.fontSize,large.cellPadding
Props:
modelValue?: string(v-model)placeholder?: stringdisabled?: booleanreadonly?: booleansize?: 'small' | 'normal' | 'large'(defaultnormal)variant?: 'filled' | 'outlined'(defaultfilled)rows?: number(default3)
Events:
update:modelValueinputchangefocusblur
Example:
<Textarea v-model="bio" placeholder="Tell us about yourself" rows="4" />Props:
modelValue?: File | File[] | null(v-model)multiple?: booleanaccept?: stringdisabled?: booleanreadonly?: booleanmaxSize?: number(bytes)maxFiles?: numberplaceholder?: stringbuttonLabel?: string(defaultBrowse)size?: 'small' | 'normal' | 'large'(defaultnormal)variant?: 'filled' | 'outlined'(defaultfilled)
Events:
update:modelValuechangereject(payload:Array<{ file: File; reason: 'maxSize' | 'maxFiles'; maxSize?: number; maxFiles?: number }>)focusblur
Example:
<FileUpload v-model="attachments" multiple :max-files="5" :max-size="10_000_000" />Component tokens (override via theme.overrides.components.fileUpload):
minHeight,fontSize,gap,paddingborderRadius,borderColorbackgroundColor,textColor,placeholderColorfocusBorderColor,focusRingShadow,hoverBorderColordisabledOpacity,dragBackgroundColorlistGap,itemPadding,itemBorderColor,itemBackgroundColor,itemRadius,itemTextColor,sizeTextColorbuttonPadding,buttonRadius,buttonBorderColor,buttonBackgroundColor,buttonTextColor,buttonHoverBackgroundColorremoveSize,removeRadius,removeHoverBackgroundColorsmall.fontSize,small.padding,small.buttonPaddinglarge.fontSize,large.padding,large.buttonPadding
Props:
modelValue?: number | null(v-model)min?: numbermax?: numberstep?: number(default1)precision?: numberplaceholder?: stringdisabled?: booleanreadonly?: booleancontrols?: boolean(defaulttrue)size?: 'small' | 'normal' | 'large'(defaultnormal)variant?: 'filled' | 'outlined'(defaultfilled)ariaLabel?: string(defaultNumber input)
Events:
update:modelValueinputchangefocusblur
Example:
<NumberInput v-model="quantity" :min="0" :max="10" :step="1" />Props (RadioGroup):
modelValue?: string | number | boolean(v-model)name?: stringdisabled?: booleanvariant?: 'filled' | 'outlined'(defaultfilled)direction?: 'vertical' | 'horizontal'(defaultvertical)
Props (RadioButton):
value?: string | number | booleanlabel?: stringdisabled?: booleanname?: stringvariant?: 'filled' | 'outlined'(defaultfilled)
Example:
<RadioGroup v-model="plan" direction="horizontal">
<RadioButton value="basic">Basic</RadioButton>
<RadioButton value="pro">Pro</RadioButton>
</RadioGroup>Props:
items?: Array<{ label?: string; to?: string; href?: string; url?: string; active?: boolean; disabled?: boolean }>separator?: string(default/)ariaLabel?: string(defaultBreadcrumbs)
Slots:
item- slot props:{ item, index, isLast, active }separator(optional) - slot props:{ separator }
Example:
<Breadcrumbs
:items="[
{ label: 'Home', to: '/' },
{ label: 'Settings', to: '/settings' },
{ label: 'Profile', active: true },
]"
/>Component tokens (override via theme.overrides.components.breadcrumbs):
gap,fontSize,textColor,hoverColor,activeColorseparatorColor,disabledOpacity
Props (Tabs):
modelValue?: string | number(v-model)disabled?: booleanorientation?: 'horizontal' | 'vertical'(defaulthorizontal)
Props (Tab):
value: string | numberlabel?: stringdisabled?: boolean
Props (TabPanel):
value: string | number
Example:
<Tabs v-model="tab">
<template #tabs>
<Tab value="overview">Overview</Tab>
<Tab value="settings">Settings</Tab>
</template>
<template #panels>
<TabPanel value="overview">Overview content</TabPanel>
<TabPanel value="settings">Settings content</TabPanel>
</template>
</Tabs>Component tokens (override via theme.overrides.components.tabs):
gap,listGap,listBorderWidth,listBorderColor,listVerticalPaddingtabPadding,tabFontSize,tabBorderRadiustabTextColor,tabBackgroundColor,tabHoverBackgroundColortabActiveTextColor,tabActiveBackgroundColor,tabActiveBorderColor,tabActiveBorderWidthpanelPadding,panelBorderRadius,panelBackgroundColor,panelTextColordisabledOpacity
Props (Accordion):
modelValue?: string | number | Array<string | number>(v-model)multiple?: boolean(defaultfalse)disabled?: booleanvariant?: 'filled' | 'outlined'(defaultfilled)size?: 'small' | 'normal' | 'large'(defaultnormal)ariaLabel?: stringariaLabelledby?: string
Props (AccordionItem):
value: string | numbertitle?: stringdisabled?: booleanunmount?: boolean(defaultfalse)
Events:
update:modelValuechange
Example:
<Accordion v-model="faq">
<AccordionItem value="shipping" title="Shipping">
Shipping details
</AccordionItem>
<AccordionItem value="returns" title="Returns">
Returns policy
</AccordionItem>
</Accordion>Component tokens (override via theme.overrides.components.accordion):
gap,borderRadius,borderColor,backgroundColorheaderGap,headerPadding,headerFontSize,headerFontWeightheaderTextColor,headerBackgroundColor,headerHoverBackgroundColor,headerActiveBackgroundColorcontentPadding,contentTextColor,contentBackgroundColoriconSize,iconColor,dividerColorfocusRingShadow,disabledOpacitysmall.headerPadding,small.headerFontSize,small.contentPaddinglarge.headerPadding,large.headerFontSize,large.contentPadding
Props (Toast):
modelValue?: boolean(v-model)title?: stringmessage?: stringseverity?: 'neutral' | 'info' | 'success' | 'warn' | 'danger'(defaultneutral)closable?: boolean(defaulttrue)duration?: number(ms, default0, no auto-close)
Props (ToastContainer):
position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'(defaulttop-right)
Example:
<ToastContainer position="top-right">
<Toast v-model="toastOpen" title="Saved" message="Changes are saved." severity="success" :duration="2500" />
</ToastContainer>Component tokens (override via theme.overrides.components.toast):
gap,padding,borderRadius,borderColorbackgroundColor,textColor,shadow,minWidthfontSize,lineHeight,bodyGaptitleFontSize,titleFontWeight,closeSizecontainerGap,containerPadding,containerMaxWidth,zIndexinfo.*,success.*,warn.*,danger.*(backgroundColor/borderColor/textColor)
Props:
modelValue?: boolean(optional v-model)title?: stringmessage?: stringseverity?: 'neutral' | 'info' | 'success' | 'warn' | 'danger'(defaultneutral)closable?: boolean(defaultfalse)icon?: string
Slots:
default- message content (fallbacks tomessage)title(optional)icon(optional)actions(optional)close(optional)
Events:
update:modelValueclose
Example:
<Alert v-model="alertOpen" severity="warn" title="Unsaved changes" closable>
You have unsaved form changes.
<template #actions>
<Button label="Save" size="small" />
</template>
</Alert>Component tokens (override via theme.overrides.components.alert):
gap,padding,borderRadius,borderColorbackgroundColor,textColor,iconColorfontSize,lineHeight,bodyGaptitleFontSize,titleFontWeightactionsGap,closeSize,closeRadius,closeFontSize,closeHoverBackgroundColorinfo.*,success.*,warn.*,danger.*(backgroundColor/borderColor/textColor)
Component tokens (override via theme.overrides.components.textarea):
gap,fontSize,paddingborderRadius,borderColorbackgroundColor,textColor,placeholderColorfocusBorderColor,focusRingShadow,hoverBorderColordisabledOpacityminHeight,resizesmall.fontSize,small.paddinglarge.fontSize,large.padding
Props:
modelValue?: boolean(v-model)title?: stringsize?: 'sm' | 'md' | 'lg'closeOnOverlay?: boolean(default true)closeOnEsc?: boolean(default true)showClose?: boolean(default true)lockScroll?: boolean(default true)
Slots:
header(optional) - replaces the title areabody(optional) - modal content (defaults to default slot if not provided)default(optional) - modal content ifbodyslot is not usedfooter(optional)close(optional) - custom close button; slot props:{ close }
Events:
update:modelValueopenclose
Example:
<Modal v-model="open" title="Confirm action" size="sm">
<template #body>
<p>Are you sure?</p>
</template>
<template #footer>
<Button label="Cancel" severity="secondary" @click="open = false" />
<Button label="Confirm" @click="open = false" />
</template>
</Modal>Component tokens (override via theme.overrides.components.modal):
width,maxWidth,maxHeightwidthSm,maxWidthSmwidthLg,maxWidthLgpadding,borderRadiusbackgroundColor,textColoroverlayBackgroundColorshadowzIndexheaderGap,bodyGap,footerGaptitleFontSize,titleLineHeight,titleFontWeightcloseSize,closeRadius,closeOffsetcloseColor,closeFontSize,closeHoverBackgroundColor
Props:
modelValue?: boolean(v-model)title?: stringposition?: 'left' | 'right' | 'top' | 'bottom'(defaultright)size?: 'sm' | 'md' | 'lg'overlay?: boolean(defaulttrue)closeOnOverlay?: boolean(defaulttrue)closeOnEsc?: boolean(defaulttrue)showClose?: boolean(defaulttrue)lockScroll?: boolean(defaulttrue)
Slots:
header(optional) - replaces the title areabody(optional) - drawer content (defaults to default slot if not provided)default(optional) - drawer content ifbodyslot is not usedfooter(optional)close(optional) - custom close button; slot props:{ close }
Events:
update:modelValueopenclose
Example:
<Drawer v-model="open" title="Filters" position="right">
<template #body>
<p>Drawer content</p>
</template>
<template #footer>
<Button label="Reset" severity="secondary" size="small" />
<Button label="Apply" size="small" @click="open = false" />
</template>
</Drawer>Component tokens (override via theme.overrides.components.drawer):
width,widthSm,widthLgheight,heightSm,heightLgpadding,borderRadiusbackgroundColor,textColoroverlayBackgroundColorshadowzIndexheaderGap,bodyGap,footerGaptitleFontSize,titleLineHeight,titleFontWeightcloseSize,closeRadius,closeOffsetcloseColor,closeFontSize,closeHoverBackgroundColor
Props:
modelValue?: boolean(v-model)items?: Array<{ label?: string; to?: string; href?: string; url?: string; icon?: string; disabled?: boolean; separator?: boolean; command?: () => void }>placement?: 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end' | 'bottom' | 'top'(defaultbottom-start)offset?: number(default6)disabled?: booleancloseOnSelect?: boolean(defaulttrue)closeOnEsc?: boolean(defaulttrue)matchTriggerWidth?: boolean(defaulttrue)
Slots:
triggerdefault(optional) - dropdown content (defaults toitemslist if provided)
Note: For custom dropdown content, add data-dropdown-close to clickable elements to auto-close on click.
Events:
update:modelValueopencloseselect
Example:
<Dropdown :items="menuItems">
<template #trigger>
<Button label="Actions" />
</template>
</Dropdown>Component tokens (override via theme.overrides.components.dropdown):
panelPadding,panelBorderRadius,panelBorderColorpanelBackgroundColor,panelShadow,zIndexdisabledOpacity,itemPadding
Props:
text?: stringplacement?: 'top' | 'bottom' | 'left' | 'right'(defaulttop)disabled?: booleanarrow?: boolean(defaultfalse)
Slots:
default- trigger contentcontent(optional) - tooltip content (fallbacks totext)
Example:
<Tooltip text="Helpful hint" arrow>
<Button label="Hover me" />
</Tooltip>Props:
width?: string | numberheight?: string | numbervariant?: 'text' | 'rect' | 'circle'(defaulttext)animated?: boolean(defaulttrue)
Example:
<Skeleton width="240px" height="14px" />
<Skeleton width="180px" height="14px" />
<Skeleton variant="circle" width="48" />Props:
label?: stringsize?: 'small' | 'normal' | 'large'(defaultnormal)variant?: 'solid' | 'soft' | 'outline'(defaultsoft)severity?: 'neutral' | 'info' | 'success' | 'warn' | 'danger'(defaultneutral)ariaLabel?: string
Slots:
default- badge content (fallbacks tolabel)
Example:
<Badge label="Beta" />
<Badge severity="success" variant="outline">Active</Badge>Component tokens (override via theme.overrides.components.badge):
fontSize,lineHeight,paddingX,paddingY,borderRadius,gapbackgroundColor,textColor,borderColorsoftBackgroundColor,softTextColor,softBorderColoroutlineTextColor,outlineBorderColorinfo.*,success.*,warn.*,danger.*(backgroundColor/textColor/borderColor/soft*/outline*)small.fontSize,small.paddingX,small.paddingYlarge.fontSize,large.paddingX,large.paddingY
Props:
label?: stringsize?: 'small' | 'normal' | 'large'(defaultnormal)variant?: 'solid' | 'soft' | 'outline'(defaultsoft)severity?: 'neutral' | 'info' | 'success' | 'warn' | 'danger'(defaultneutral)disabled?: booleanclosable?: boolean(defaultfalse)icon?: stringariaLabel?: stringcloseLabel?: string(defaultRemove)
Slots:
default- chip content (fallbacks tolabel)icon(optional)close(optional)
Events:
close
Example:
<Chip label="New" />
<Chip severity="info" closable>Info</Chip>Component tokens (override via theme.overrides.components.chip):
fontSize,lineHeight,paddingX,paddingY,borderRadius,gapbackgroundColor,textColor,borderColorsoftBackgroundColor,softTextColor,softBorderColoroutlineTextColor,outlineBorderColoriconSize,closeSize,closeFontSize,closeRadius,closeColor,closeHoverBackgroundColor,disabledOpacityinfo.*,success.*,warn.*,danger.*(backgroundColor/textColor/borderColor/soft*/outline*)small.fontSize,small.paddingX,small.paddingYlarge.fontSize,large.paddingX,large.paddingY
Props:
src?: stringalt?: stringname?: stringsize?: 'small' | 'normal' | 'large'(defaultnormal)shape?: 'circle' | 'rounded'(defaultcircle)status?: 'online' | 'offline' | 'busy' | 'away'
Slots:
default- custom avatar content
Example:
<Avatar name="Ada Lovelace" />
<Avatar src="/img/ada.png" alt="Ada Lovelace" size="large" />
<Avatar name="Ada Lovelace" status="online" />Component tokens (override via theme.overrides.components.avatar):
size,fontSize,fontWeightbackgroundColor,textColor,borderColor,borderWidth,borderRadiusstatusSize,statusBorderWidth,statusBorderColorstatusOnlineColor,statusOfflineColor,statusBusyColor,statusAwayColorsmall.size,small.fontSize,small.statusSizelarge.size,large.fontSize,large.statusSize
Props:
value?: number(0-100; omit for indeterminate)variant?: 'linear' | 'circular'(defaultlinear)size?: 'small' | 'normal' | 'large'(defaultnormal)label?: stringshowValue?: boolean(defaultfalse)severity?: 'neutral' | 'info' | 'success' | 'warn' | 'danger'(defaultneutral)ariaLabel?: string
Example:
<Progress :value="64" />
<Progress variant="circular" :value="42" size="small" />
<Progress variant="linear" severity="success" showValue :value="85" />
<Progress variant="linear" />Component tokens (override via theme.overrides.components.progress):
width,height,borderRadiusbackgroundColor,barColorlabelColor,labelFontSize,gapcircularSize,circularThicknessanimationDurationinfo.barColor,success.barColor,warn.barColor,danger.barColorsmall.height,small.labelFontSize,small.circularSize,small.circularThicknesslarge.height,large.labelFontSize,large.circularSize,large.circularThickness
Props:
modelValue?: number | [number, number](v-model)min?: number(default0)max?: number(default100)step?: number(default1)range?: boolean(defaultfalse)disabled?: booleansize?: 'small' | 'normal' | 'large'(defaultnormal)variant?: 'filled' | 'outlined'(defaultfilled)showValue?: boolean(defaultfalse)marks?: Array<{ value: number; label?: string }>
Events:
update:modelValueinputchangefocusblur
Example:
<Slider v-model="volume" :min="0" :max="100" :step="5" show-value />
<Slider v-model="priceRange" :min="0" :max="1000" :step="10" range />Component tokens (override via theme.overrides.components.slider):
width,gaptextColortrackHeight,trackBackgroundColor,trackRadius,fillBackgroundColorthumbSize,thumbColor,thumbBorderColor,thumbBorderWidth,thumbShadowfocusRingShadow,disabledOpacitymarkSize,markColor,markLabelFontSize,markLabelColor,marksHeightvalueFontSize,valueColorsmall.trackHeight,small.thumbSize,small.valueFontSizelarge.trackHeight,large.thumbSize,large.valueFontSize
Props:
modelValue?: string | number(v-model)steps?: Array<{ label?: string; description?: string; value?: string | number; disabled?: boolean; status?: 'completed' | 'active' | 'upcoming' | 'error' }>orientation?: 'horizontal' | 'vertical'(defaulthorizontal)size?: 'small' | 'normal' | 'large'(defaultnormal)clickable?: boolean(defaultfalse)ariaLabel?: stringariaLabelledby?: string
Events:
update:modelValuechange
Example:
<Stepper v-model="step" :steps="steps" clickable />
<Stepper v-model="step" :steps="steps" orientation="vertical" size="small" />Component tokens (override via theme.overrides.components.stepper):
gap,itemGap,lineThickness,lineLength,lineColorindicatorSize,indicatorBorderRadius,indicatorBorderWidth,indicatorFontSizeindicatorBackgroundColor,indicatorTextColor,indicatorBorderColoractiveIndicatorBackgroundColor,activeIndicatorTextColor,activeIndicatorBorderColorcompletedIndicatorBackgroundColor,completedIndicatorTextColor,completedIndicatorBorderColorerrorIndicatorBackgroundColor,errorIndicatorTextColor,errorIndicatorBorderColorlabelFontSize,labelColor,descriptionFontSize,descriptionColordisabledOpacitysmall.indicatorSize,small.indicatorFontSize,small.labelFontSize,small.descriptionFontSize,small.lineLength,small.itemGaplarge.indicatorSize,large.indicatorFontSize,large.labelFontSize,large.descriptionFontSize,large.lineLength,large.itemGap
Props:
modelValue?: number(v-model)max?: number(default5)allowHalf?: boolean(defaultfalse)readonly?: booleandisabled?: booleansize?: 'small' | 'normal' | 'large'(defaultnormal)ariaLabel?: string
Events:
update:modelValuechangefocusblur
Example:
<Rating v-model="score" />
<Rating v-model="score" allow-half size="large" />Component tokens (override via theme.overrides.components.rating):
gap,size,color,activeColor,hoverColorfocusRingShadow,focusRadius,disabledOpacitysmall.sizelarge.size
VueForge exposes design tokens as CSS variables generated from the theme preset. Core groups:
colors.*→--vf-{color}+ shades (--vf-{color}-100..900)radii.*→ corner radiitypography.*→ base font size & line heightstates.*→ focus ring, disabled opacitycontrols.*→ base control sizing (height, padding)sizes.sm/lg→ shared small/large sizing for Button/Input/Select
Typed tokens:
ThemeTokens/ThemeOptions/ThemePresetare exported for type-safe theming in TS.components.*accepts component-specific tokens (typed keys: button/card/checkbox/radio/tabs/accordion/toast/alert/input/numberInput/formField/textarea/link/breadcrumbs/menu/modal/drawer/popover/dropdown/select/autocomplete/multiselect/datepicker/daterangepicker/timepicker/pagination/switch/tooltip/skeleton/progress/badge/chip/avatar/datatable/slider/stepper/rating).
Default core values (from DefaultTheme):
| Token | Value |
|---|---|
borderWidth |
1px |
controls.height |
2rem |
controls.paddingY |
0.25rem |
controls.paddingX |
0.6rem |
radii.sm |
4px |
radii.md |
6px |
radii.lg |
10px |
typography.fontSize |
1rem |
typography.lineHeight |
1.4 |
states.disabledOpacity |
0.6 |
states.focusRingShadow |
0 0 0 3px rgba(var(--vf-blue-600-rgb), 0.12) |
sizes.sm.fontSize |
0.875rem |
sizes.sm.paddingY |
0.2rem |
sizes.sm.paddingX |
0.5rem |
sizes.lg.fontSize |
1.125rem |
sizes.lg.paddingY |
0.5rem |
sizes.lg.paddingX |
1rem |
Example override:
setTheme({
preset: DefaultTheme,
overrides: {
typography: {
fontSize: '0.9375rem',
lineHeight: '1.4',
},
controls: {
height: '2rem',
paddingY: '0.25rem',
paddingX: '0.6rem',
},
sizes: {
sm: { fontSize: '0.8125rem', paddingY: '0.2rem', paddingX: '0.45rem' },
lg: { fontSize: '1.125rem', paddingY: '0.5rem', paddingX: '1rem' },
},
},
});The example app lives in src/example and showcases all components.
npm run devVueForge maps the theme preset to CSS variables. You can override parts of the preset and it will recompute shades for color tokens.
app.use(VueForge, {
theme: {
preset: DefaultTheme,
strict: false,
overrides: {
colors: {
green: '#18a66a',
},
},
selector: ':root',
darkSelector: ':root[data-theme=dark]',
},
});You can also update the theme at runtime:
import { setTheme, updateTheme } from '@codemonster-ru/vueforge';
setTheme({ preset: DefaultTheme });
updateTheme({
overrides: {
colors: { blue: '#2b6cb0' },
},
});Notes:
- Non-hex colors (e.g.
rgb(...),hsl(...),var(--brand)) are allowed, but shade variables (--vf-*-100..900) will not be generated. - Set
theme.strict: trueto throw on invalid token values (non-string / non-plain object) during theme application.
Core methods:
setTheme(options)— apply a theme preset (with optional overrides).updateTheme(partial)— update only parts of the current theme.getTheme()— get the last applied theme options.
Key options:
preset: base theme object (e.g.DefaultTheme)overrides: partial overrides merged into presetselector: CSS selector for base variables (default:root)darkSelector: selector for dark scheme (default:root[data-theme=dark])strict: throw on invalid token values (otherwise warnings)
Example:
setTheme({
preset: DefaultTheme,
overrides: {
colors: { blue: '#2b6cb0' },
typography: { fontSize: '0.95rem' },
},
strict: true,
});