Como contribuir
Do que um componente é feito, e onde fica cada peça.
Um componente são cinco peças, cada uma no seu lugar. Nenhuma é opcional, e a ordem é a ordem em que são escritas.
packages/themes/src/presets/base/components/toggleswitch.ts # tokens
packages/styles/src/toggleswitch/{toggleswitch.css,index.ts} # CSS + class map
packages/vue/src/components/ToggleSwitch/
types.ts # the props interface, extending BaseProps
ToggleSwitch.vue # the component
ToggleSwitch.spec.ts# axe + keyboard + ARIA
index.ts
apps/docs/src/demos/ToggleSwitch.vue # the demo page1. Tokens
Uma árvore de tokens cujos valores apontam para a camada semântica ('{formField.borderColor}', '{control.minHeight}'), e não para uma cor. Tudo o que muda de um esquema de cores para o outro vai em colorScheme. Cada token vira uma variável --vt-toggleswitch-….
2. Estilo
- As classes são
vt-toggleswitch,vt-toggleswitch-<part>,vt-toggleswitch-<modifier>. - O CSS lê apenas
var(--vt-…). Uma cor, um raio ou uma duração fixos no código são um bug. - Construa sobre o visual compartilhado (
.vt-field,.vt-overlay,.vt-option,.vt-mask) em vez de reestilizá-lo. - O foco pelo teclado mostra o anel de foco; tudo o que é animado para sob
prefers-reduced-motion.
3. O componente
<script setup lang="ts">
defineOptions({ name: 'VtToggleSwitch' });
const props = withDefaults(defineProps<ToggleSwitchProps>(), {
unstyled: undefined // required: an absent boolean prop would be false,
}); // and false would override the global setting
const { part } = useComponent(toggleswitchStyle, props);
</script>
<template>
<!-- one call per element: theme classes, pass-through and state -->
<div v-bind="part('root', state)">
<span v-bind="part('thumb', state)" />
</div>
</template>v-bind="part(…)" em todo elemento é o que torna um componente tematizável, alcançável por pass-through e utilizável sem estilo. Um componente que envolve um controle nativo também usa useSplitAttrs() com inheritAttrs: false, para que class vista o wrapper enquanto name, aria-describedby e o resto chegam ao controle.
4. A demo
Uma página em apps/docs/src/demos/ que exporta meta: DemoMeta de um bloco <script> simples. Este site a encontra por glob e lê o mesmo arquivo de novo, como texto, para mostrar o código ao lado de cada exemplo, então um trecho não tem como se afastar do que documenta.
5. Barrels
pnpm gen escreve todas as listas de index.ts. Ninguém as edita à mão.
Convenções que vale conhecer
v-modelviadefineModel(); ids a partir douseId()do Vue.- O texto vem do locale, nunca de um literal no template.
- Popups usam
<Teleport to="body">, a transiçãovt-overlayeuseOverlay(); modais acrescentamuseFocusTrap()elockScroll(). - Comportamento sem DOM (navegação, parsing, seleção) vai para
@vitral/core, com um teste lá. - Prefira uma opção a um componente novo: duas coisas que só diferem no que recusam são uma coisa só, com uma prop.
Verificações
pnpm test # vitest + axe
pnpm typecheck # vue-tsc over every package and the site
node scripts/gen-index.mjs --check # barrels up to date
pnpm build # every package builds, with declarations