@goliafrs/control
v1.5.2
Published
Vue 3 control library with typed exports, standalone styles, and reusable menu primitives.
Readme
@goliafrs/control
Vue 3 control library with typed exports, standalone styles, and reusable menu primitives.
Install
pnpm add @goliafrs/control vueUsage
Import styles once in the host application:
import '@goliafrs/control/styles.css'Import from the root entry:
import { Button, Input, type ButtonVariant } from '@goliafrs/control'Import from subpaths:
import { Select, type SelectOption } from '@goliafrs/control/select'
import { Menu, type MenuEntry, type MenuItem } from '@goliafrs/control/menu'
import { Tooltip } from '@goliafrs/control/tooltip'Use Vue-native modelValue contracts:
<Input
ariaLabel="Search"
label="Search"
modelValue={searchQuery.value}
type="text"
onUpdate:modelValue={nextValue => {
searchQuery.value = nextValue
}}
/><Select
ariaLabel="Sort order"
label="Sort order"
modelValue={sortOrder.value}
options={sortOptions.value}
onUpdate:modelValue={nextValue => {
sortOrder.value = nextValue
}}
/>Use the standalone menu directly:
<Menu
anchorElement={triggerReference.value}
ariaLabel="Sort menu"
items={menuItems.value}
menuPosition={menuPosition.value}
onClose={() => {
menuPosition.value = null
}}
onSelect={itemId => {
selectedItemId.value = itemId
}}
/>Menu entries can be items or separators. Items accept color and backgroundColor
(any CSS color, applied through the --control-menu-item-color and
--control-menu-item-background custom properties, so hover and active states stay
visible), an extra className, and custom content: slot names a Menu slot for that
item, and the shared scoped item slot renders every other item. Both slots receive
{ item }. The menu height is limited by --control-menu-max-height (240px by default).
select receives the item id and the item click MouseEvent, so modifier keys such as
ctrlKey work anywhere on the item, slot content included:
onSelect={(itemId, event) => openPage(itemId, event.ctrlKey)}.
const menuItems: MenuEntry[] = [
{ id: 'launch', label: 'Launch', color: 'var(--app-accent-success)' },
{ id: 'launch-separator', type: 'separator' },
{ id: 'details', label: 'Details', color: 'var(--app-accent-primary)' },
{ id: 'details-separator', type: 'separator' },
{ id: 'uninstall', label: 'Uninstall', variant: 'danger' }
]Tooltip
Mount one Tooltip near the application root. It shows the data-tooltip text of any
hovered element, or of an element focused from the keyboard, so plain HTML elements and
components need nothing but the attribute:
import { Tooltip } from '@goliafrs/control/tooltip'
<button data-tooltip="Opens the install folder" type="button">Folder</button>
<Tooltip />MenuItem.tooltip and SelectOption.tooltip put the hint on the whole item button, padding
included, disabled items too. The hint centers above the element, flips below it near the
top edge, stays inside the viewport, follows window resizes and picks up a changed
data-tooltip while shown. An emptied attribute hides it. The element gets
aria-describedby pointing to the hint while it is shown. Pointer down, Escape, scroll,
focus loss and window blur hide it. With the Popover API the hint opens in the top layer
above menus and dialogs. Without it (jsdom) it stays a fixed element with z-index: 1001.
Colors and size come from --control-tooltip-background, --control-tooltip-text,
--control-tooltip-shadow and --control-tooltip-font-size.
Styles and themes
The package ships:
@goliafrs/control/styles.css@goliafrs/control/styles/tokens.scss@goliafrs/control/styles/mixins.scss
Override CSS variables in the host application:
:root {
--control-font-family: 'Rubik', sans-serif;
--control-button-primary-background: rgb(59 130 246 / 100%);
}Reuse raw Sass mixins and tokens:
@use '@goliafrs/control/styles/tokens.scss' as controlTokens;
@use '@goliafrs/control/styles/mixins.scss' as controlMixins;
:root[data-theme='light'] {
@include controlTokens.light-theme-tokens;
}
.custom-toolbar {
@include controlMixins.section-inline-padding;
}