You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
Bastian Masanek 6e50ec7034 Init 2 months ago
..
ExperimentaButton.vue Init 2 months ago
ExperimentaCard.vue Init 2 months ago
ExperimentaLogo.vue Init 2 months ago
ExperimentaStatusMessage.vue Init 2 months ago
README.md Init 2 months ago

README.md

experimenta Vue Komponenten-Beispiele

Dieser Ordner enthält Referenz-Implementierungen der experimenta Design System Komponenten als Vue 3 Single File Components (SFC).

Diese Komponenten dienen als Vorlagen und Beispiele für die Entwicklung eigener Komponenten oder können direkt in das Projekt kopiert werden.


Verfügbare Komponenten

1. ExperimentaButton.vue

Animierter Button mit Gradient-Hintergrund nach experimenta Design System.

Features:

  • Primary & Secondary Variants
  • Responsive Größen (Small, Medium, Large)
  • Link-Verhalten (kann als <a> oder <button> gerendert werden)
  • Hover-Animation mit Gradient-Shift
  • Accessibility-Ready (Focus States, ARIA Labels)

Verwendung:

<script setup>
import ExperimentaButton from './ExperimentaButton.vue'
</script>

<template>
  <!-- Primary Button (default) -->
  <ExperimentaButton @click="handleClick"> Zur Startseite </ExperimentaButton>

  <!-- Secondary Button -->
  <ExperimentaButton variant="secondary"> Abbrechen </ExperimentaButton>

  <!-- As Link -->
  <ExperimentaButton href="https://www.experimenta.science" target="_blank">
    Zur experimenta Website
  </ExperimentaButton>

  <!-- Small Size -->
  <ExperimentaButton size="small"> Small Button </ExperimentaButton>

  <!-- Disabled -->
  <ExperimentaButton disabled> Disabled Button </ExperimentaButton>
</template>

2. ExperimentaCard.vue

Glass-morphism Card-Komponente mit verschiedenen Variants.

Features:

  • Glass-morphism Styling (Backdrop Blur)
  • Info, Contact, Progress Variants
  • Optional: Akzent-Border (links)
  • Slot-basiertes Design (flexibel)

Verwendung:

<script setup>
import ExperimentaCard from './ExperimentaCard.vue'
</script>

<template>
  <!-- Glass Card (Main) -->
  <ExperimentaCard>
    <h1>Willkommen!</h1>
    <p>Dies ist eine Glass-morphism Card.</p>
  </ExperimentaCard>

  <!-- Info Card mit Titel -->
  <ExperimentaCard variant="info" title="Ihre Vorteile">
    <p>Mit der Jahreskarte erhalten Sie...</p>
  </ExperimentaCard>

  <!-- Card mit Custom Title Slot -->
  <ExperimentaCard variant="contact">
    <template #title>
      <span>Kontakt</span>
    </template>
    <p>E-Mail: info@experimenta.science</p>
  </ExperimentaCard>

  <!-- Progress Card -->
  <ExperimentaCard variant="progress">
    <!-- Progress Bar Content -->
  </ExperimentaCard>
</template>

3. ExperimentaStatusMessage.vue

Status-Nachrichten mit animierten Icons (Success, Error, Warning, Info).

Features:

  • 4 Status-Typen mit passenden Farben
  • Animiertes Icon (Pulse Animation)
  • Responsive Icon-Größe
  • Slot-basierte Inhalte

Verwendung:

<script setup>
import ExperimentaStatusMessage from './ExperimentaStatusMessage.vue'
</script>

<template>
  <!-- Success Message -->
  <ExperimentaStatusMessage type="success" title="Verlängerung erfolgreich!">
    <p>Ihre Jahreskarte wurde erfolgreich verlängert.</p>
  </ExperimentaStatusMessage>

  <!-- Error Message -->
  <ExperimentaStatusMessage type="error" title="Ein Fehler ist aufgetreten">
    <p>Bitte versuchen Sie es erneut.</p>
  </ExperimentaStatusMessage>

  <!-- Custom Icon -->
  <ExperimentaStatusMessage type="warning" title="Achtung" icon="⚠">
    <p>Dies ist eine Warnung.</p>
  </ExperimentaStatusMessage>

  <!-- Custom Title Slot -->
  <ExperimentaStatusMessage type="info">
    <template #title>
      <span>Information</span>
    </template>
    <p>Hier ist eine Info.</p>
  </ExperimentaStatusMessage>
</template>

4. ExperimentaLogo.vue

Offizielles experimenta X-Logo mit Farbverläufen.

Features:

  • SVG-basiert (skalierbar, scharf)
  • 3 Größen (Small, Medium, Large)
  • Responsive (passt sich automatisch an)
  • Optional als Link verwendbar
  • Hover-Animation

Verwendung:

<script setup>
import ExperimentaLogo from './ExperimentaLogo.vue'
</script>

<template>
  <!-- Logo (default: large) -->
  <ExperimentaLogo />

  <!-- Logo als Link -->
  <ExperimentaLogo href="https://www.experimenta.science" target="_blank" />

  <!-- Small Logo -->
  <ExperimentaLogo size="small" />

  <!-- Medium Logo -->
  <ExperimentaLogo size="medium" />
</template>

Integration in Nuxt 4

Option 1: Komponenten in components/ verschieben

Kopiere die gewünschten Komponenten nach components/:

cp docs/design-examples/components/ExperimentaButton.vue components/

Nuxt erkennt sie automatisch (Auto-Imports):

<template>
  <div>
    <ExperimentaButton>Click me</ExperimentaButton>
  </div>
</template>

Option 2: Als Composable verwenden

Erstelle eine Composable-Funktion in composables/useExperimenta.ts:

export function useExperimenta() {
  return {
    // Export component references
    ExperimentaButton: () => import('@/docs/design-examples/components/ExperimentaButton.vue'),
    ExperimentaCard: () => import('@/docs/design-examples/components/ExperimentaCard.vue'),
    // ...
  }
}

Anpassungen & Erweiterungen

shadcn-nuxt Integration

Diese Komponenten können shadcn-nuxt Komponenten ersetzen oder ergänzen:

<!-- Statt shadcn Button: -->
<Button>Click me</Button>

<!-- Verwende experimenta Button: -->
<ExperimentaButton>Click me</ExperimentaButton>

Tailwind Klassen verwenden

Alle Komponenten verwenden Tailwind CSS Utilities. Du kannst sie anpassen:

<ExperimentaButton class="mt-8">
  Custom Margin
</ExperimentaButton>

Custom Variants hinzufügen

Beispiel: Eine neue Button-Variant hinzufügen:

<!-- In ExperimentaButton.vue -->
<script setup lang="ts">
interface Props {
  variant?: 'primary' | 'secondary' | 'tertiary' // Neu: tertiary
}
</script>

<style scoped>
/* Neue Variant definieren */
.btn-tertiary {
  @apply bg-info text-white;
}

.btn-tertiary:hover {
  @apply bg-info-dark;
}
</style>

TypeScript Support

Alle Komponenten sind TypeScript-ready mit vollständigen Prop-Definitionen.

Beispiel für Type-Safe Usage:

<script setup lang="ts">
import ExperimentaButton from './ExperimentaButton.vue'

function handleClick(event: MouseEvent) {
  console.log('Button clicked', event)
}
</script>

<template>
  <ExperimentaButton variant="primary" size="large" :disabled="false" @click="handleClick">
    Click me
  </ExperimentaButton>
</template>

Accessibility (A11y)

Alle Komponenten folgen WCAG 2.1 AA Standards:

  • Keyboard Navigation (Tab, Enter, Space)
  • Focus Indicators (sichtbarer Focus-Ring)
  • ARIA Labels (Screen Reader Support)
  • Color Contrast (mindestens 4.5:1 Ratio)

Testing

Beispiel für Vitest Unit Tests:

// ExperimentaButton.spec.ts
import { mount } from '@vue/test-utils'
import ExperimentaButton from './ExperimentaButton.vue'

describe('ExperimentaButton', () => {
  it('renders primary button by default', () => {
    const wrapper = mount(ExperimentaButton, {
      slots: { default: 'Click me' },
    })

    expect(wrapper.find('.btn-primary').exists()).toBe(true)
    expect(wrapper.text()).toBe('Click me')
  })

  it('emits click event', async () => {
    const wrapper = mount(ExperimentaButton)
    await wrapper.trigger('click')

    expect(wrapper.emitted('click')).toBeTruthy()
  })

  it('renders as link when href is provided', () => {
    const wrapper = mount(ExperimentaButton, {
      props: { href: 'https://example.com' },
    })

    expect(wrapper.element.tagName).toBe('A')
    expect(wrapper.attributes('href')).toBe('https://example.com')
  })
})

Storybook Integration (Optional)

Erstelle Stories für visuelle Dokumentation:

// ExperimentaButton.stories.ts
import type { Meta, StoryObj } from '@storybook/vue3'
import ExperimentaButton from './ExperimentaButton.vue'

const meta: Meta<typeof ExperimentaButton> = {
  title: 'Components/ExperimentaButton',
  component: ExperimentaButton,
  tags: ['autodocs'],
}

export default meta
type Story = StoryObj<typeof ExperimentaButton>

export const Primary: Story = {
  args: {
    variant: 'primary',
  },
  render: (args) => ({
    components: { ExperimentaButton },
    setup() {
      return { args }
    },
    template: '<ExperimentaButton v-bind="args">Click me</ExperimentaButton>',
  }),
}

export const Secondary: Story = {
  args: {
    variant: 'secondary',
  },
  render: (args) => ({
    components: { ExperimentaButton },
    setup() {
      return { args }
    },
    template: '<ExperimentaButton v-bind="args">Cancel</ExperimentaButton>',
  }),
}

Weitere Ressourcen

  • Design System Dokumentation: docs/DESIGN_SYSTEM.md
  • Tailwind Config: tailwind.config.ts
  • CSS Custom Properties: assets/css/tailwind.css
  • Design-Vorlagen: design-examples/*.html

Fragen oder Feedback?docs@experimenta.science