Desenvolver
Com shadcn-vue
Como usar Sinapse + shadcn-vue em Vue 3 / Nuxt. Tokens semantic compatíveis — componentes shadcn-vue ficam Sinapse-coral automático.
Por que funciona
shadcn-vue usa
os mesmos semantic tokens que a Sinapse @itps/styles:
--primary, --background,
--card, etc. Carregando nossa CSS entry, os componentes shadcn-vue
viram coral Sinapse automaticamente — sem fork, sem patch.
1 · Setup
Instalar tudo
Terminal
# 1. Tailwind v4 (se ainda não tem)
pnpm add tailwindcss
# 2. shadcn-vue init (cria components.json, alias, etc)
pnpm dlx shadcn-vue@latest init
# 3. Sinapse tokens — workspace OU copy
# workspace: pnpm add @itps/styles --workspace
# copy: cp <repo-sinapse>/packages/styles/*.css ./assets/styles/ 2 · CSS entry
Importar Sinapse no main.css
shadcn-vue cria por default um app/assets/index.css com
os semantic vars. Substitua por @itps/styles:
app/assets/index.css
@import "tailwindcss";
@import "@itps/styles"; /* nossa CSS — sobrescreve defaults shadcn-vue */ 3 · Adicionar componentes
CLI shadcn-vue
pnpm dlx shadcn-vue@latest add button
pnpm dlx shadcn-vue@latest add card
pnpm dlx shadcn-vue@latest add dialog # Modal
pnpm dlx shadcn-vue@latest add tabs
pnpm dlx shadcn-vue@latest add select
# ... etc — veja shadcn-vue.com/docs/components
Componentes Vue ficam em app/components/ui/. Use direto:
<script setup>
import { Button } from '@/components/ui/button'
</script>
<template>
<Button>Salvar</Button> <!-- coral Sinapse -->
<Button variant="outline">Cancelar</Button>
</template> 4 · Componentes Sinapse drop-in
Substitua os gerados pra ficar 1:1 com o DS
O Button.vue que a CLI shadcn-vue gera tem styling próprio (radius, altura, hover) — coral mas não idêntico ao Sinapse.
Substitua o conteúdo de cada arquivo em app/components/ui/ pelos snippets abaixo. Wrappers finos que usam .itps-* — um source of truth (components.css).
Button.vue
app/components/ui/button/Button.vue
<script setup lang="ts">
defineProps<{
variant?: 'primary' | 'secondary' | 'ghost' | 'outline'
size?: 'sm' | 'md' | 'lg'
}>()
</script>
<template>
<button
:class="[
'itps-btn',
`itps-btn--${$props.variant ?? 'primary'}`,
$props.size && $props.size !== 'md' && `itps-btn--${$props.size}`,
]"
>
<slot />
</button>
</template> Card.vue
app/components/ui/card/Card.vue
<script setup lang="ts">
defineProps<{ elevated?: boolean }>()
</script>
<template>
<div :class="['itps-card', $props.elevated && 'itps-card--elevated']">
<slot />
</div>
</template> Chip.vue
app/components/ui/chip/Chip.vue
<script setup lang="ts">
defineProps<{
variant?: 'default' | 'primary' | 'success' | 'warning' | 'danger'
}>()
</script>
<template>
<span
:class="[
'itps-chip',
$props.variant && $props.variant !== 'default' && `itps-chip--${$props.variant}`,
]"
>
<slot />
</span>
</template> Callout.vue
app/components/ui/callout/Callout.vue
<script setup lang="ts">
defineProps<{
variant?: 'default' | 'info' | 'success' | 'warning' | 'danger'
}>()
</script>
<template>
<div
:class="[
'itps-callout',
$props.variant && $props.variant !== 'default' && `itps-callout--${$props.variant}`,
]"
>
<slot />
</div>
</template> Input.vue
app/components/ui/input/Input.vue
<script setup lang="ts">
defineProps<{ error?: boolean }>()
const model = defineModel<string>()
</script>
<template>
<input
v-model="model"
:class="['itps-input', $props.error && 'itps-input--error']"
/>
</template> Field.vue
app/components/ui/field/Field.vue
<script setup lang="ts">
defineProps<{
label?: string
hint?: string
error?: string
id?: string
}>()
</script>
<template>
<div class="itps-field">
<label v-if="label" :for="id" class="itps-field__label">{{ label }}</label>
<slot :id="id" />
<p v-if="error" class="itps-field__error">{{ error }}</p>
<p v-else-if="hint" class="itps-field__hint">{{ hint }}</p>
</div>
</template> 5 · Componentes Sinapse-only
RiskClassification, DataOverlay, FeedbackIcon
Estes 3 componentes não existem em shadcn-vue (são domain-specific de saúde pública). Pegue o HTML+classes da página de cada um em /componentes e converta pra Vue SFC manualmente.
Próximos passos