phase 2 - step 1 - minimal project setup

remove build:types

fix types

update package-lock

fix types

updated packages

install missing dependency

fix typecheck

tests for plugin.ts

update projekt.md
This commit is contained in:
Ulf Gebhardt 2026-02-04 17:21:14 +01:00
parent b88e02ebee
commit bce5ba830c
Signed by: ulfgebhardt
GPG Key ID: DA6B843E748679C9
12 changed files with 4228 additions and 16 deletions

30
packages/ui/.gitignore vendored Normal file
View File

@ -0,0 +1,30 @@
# Dependencies
node_modules/
# Build output
dist/
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Test coverage
coverage/
# Histoire
.histoire/
# Logs
*.log
npm-debug.log*
# Temporary files
*.tmp
*.temp

View File

@ -71,7 +71,7 @@ Die Library bietet zwei Nutzungsmöglichkeiten:
@ocelot-social/ui
├── dist/
│ ├── index.js # Vue Komponenten
│ ├── styles.css # Vorkompilierte Styles (für Nicht-Tailwind)
│ ├── style.css # Vorkompilierte Styles (für Nicht-Tailwind)
│ └── tailwind.preset.js # Tailwind Preset (für Tailwind-Nutzer)
```
@ -91,7 +91,7 @@ import { OsButton } from '@ocelot-social/ui'
```js
// main.js
import { OsButton } from '@ocelot-social/ui'
import '@ocelot-social/ui/styles.css'
import '@ocelot-social/ui/style.css'
```
### Branding (funktioniert für beide)
@ -417,16 +417,17 @@ Bei der Migration werden:
- [x] Regressionstests (`yarn dev` und manuelle Prüfung) ✅
### Phase 2: Projekt-Setup
- [ ] Vite + Vue 3 Projekt initialisieren
- [ ] vue-demi einrichten für Vue 2 Kompatibilität
- [x] Vite + Vue 3 Projekt initialisieren
- [x] vue-demi einrichten für Vue 2 Kompatibilität
- [ ] Tailwind CSS einrichten
- [ ] Dual-Build konfigurieren (Tailwind Preset + vorkompilierte CSS)
- [ ] CSS Custom Properties Token-System aufsetzen
- [ ] Dark Mode Grundstruktur
- [ ] Histoire für Dokumentation einrichten
- [ ] Vitest konfigurieren (mit Vue 2/3 Matrix)
- [x] Vitest konfigurieren
- [ ] Vitest Vue 2/3 Matrix einrichten
- [ ] eslint-config-it4c einrichten (inkl. TypeScript, Vue, Prettier, JSDoc) ⚠️ **BLOCKED: siehe §18**
- [ ] npm Package-Struktur (@ocelot-social/ui) mit korrekten exports
- [x] npm Package-Struktur (@ocelot-social/ui) mit korrekten exports
- [ ] Build-Pipeline für Vue 2/3 Dual-Support
- [ ] GitHub Workflows einrichten (Lint, Test, Build)
- [ ] Visual Regression Tests einrichten (Playwright)
@ -439,7 +440,7 @@ Bei der Migration werden:
- [ ] npm Publish Workflow
- [ ] Histoire Deploy Workflow
- [ ] LICENSE Datei (Apache 2.0)
- [ ] README.md Grundgerüst (Installation, Quick Start, Struktur)
- [x] README.md Grundgerüst (Installation, Quick Start, Struktur)
- [ ] CONTRIBUTING.md
- [ ] Docs-Generierung einrichten (scripts/generate-docs.ts)
@ -476,12 +477,12 @@ Bei der Migration werden:
```
Phase 0: ██████████ 100% (6/6 Aufgaben) ✅
Phase 1: ██████████ 100% (6/6 Aufgaben) ✅
Phase 2: ░░░░░░░░░░ 0% (0/26 Aufgaben)
Phase 2: ██░░░░░░░░ 19% (5/27 Aufgaben)
Phase 3: ░░░░░░░░░░ 0% (0/7 Aufgaben)
Phase 4: ░░░░░░░░░░ 0% (0/18 Aufgaben)
Phase 5: ░░░░░░░░░░ 0% (0/7 Aufgaben)
───────────────────────────────────────
Gesamt: ██░░░░░░░░ ~15%
Gesamt: ██░░░░░░░░ ~18%
```
### Katalogisierung (Details in KATALOG.md)
@ -506,7 +507,7 @@ Integriert: 0
**Letzte Aktualisierung:** 2026-02-04
**Aktuelle Phase:** Phase 2 (Projekt-Setup) - Bereit zum Start
**Aktuelle Phase:** Phase 2 (Projekt-Setup) - In Arbeit (19%)
**Zuletzt abgeschlossen:**
- [x] Projektordner erstellt
@ -529,14 +530,25 @@ Integriert: 0
- Webpack-Regel für ESM .mjs Module
- **Unit-Tests: 157 Suites, 979 passed, 87 Snapshots**
- **Integrationstests: bestanden**
- [x] **Phase 2: Projekt-Setup** (in Arbeit)
- Vite + Vue 3 Projekt initialisiert
- vue-demi für Vue 2/3 Kompatibilität
- Vitest konfiguriert (integriert in vite.config.ts)
- npm Package-Struktur mit korrekten exports
- README.md Grundgerüst
- Plugin-Tests geschrieben
**Aktuell in Arbeit:**
- Nichts - Bereit für Phase 2
- Phase 2: Projekt-Setup (5/27 Aufgaben erledigt)
**Nächste Schritte:**
1. ~~Phase 0: Komponenten-Analyse~~
2. ~~Phase 1: Vue 2.7 Upgrade~~
3. **Phase 2: Projekt-Setup** (Vite + Vue 3 + Histoire)
3. **Phase 2: Projekt-Setup** - Fortsetzen mit:
- Tailwind CSS einrichten
- Histoire für Dokumentation
- GitHub Workflows
- LICENSE Datei
---
@ -636,6 +648,10 @@ Integriert: 0
| 2026-02-04 | **Phasen umbenannt** | 0.5→1, 1→2, 2→3, 3→4, 4→5 (nur ganzzahlige Phasen) |
| 2026-02-04 | **Dokument-Konsolidierung** | §13 Zahlen korrigiert, §14 Link entfernt, §16 Reihenfolge, Terminologie vereinheitlicht |
| 2026-02-04 | **Komplexitätsanalyse** | §20 hinzugefügt: Risikofaktoren, Parallelisierbarkeit, Aufwandstreiber pro Komponente |
| 2026-02-04 | **Phase 2 gestartet** | Vite + Vue 3 Projekt initialisiert, vue-demi, Vitest, Package-Struktur |
| 2026-02-04 | **Build-System** | vite.config.ts mit Library-Mode, vite-plugin-dts für Types, vite-tsconfig-paths |
| 2026-02-04 | **Testing** | Vitest in vite.config.ts integriert, Plugin-Tests geschrieben |
| 2026-02-04 | **Dokumentation** | README.md mit Installation und Usage (Tree-Shaking vs Plugin) |
---
@ -1272,17 +1288,17 @@ packages/ui/
│ │ ├── tailwind.config.js # Nutzt @ocelot-social/ui/tailwind.preset
│ │ └── src/App.vue # Importiert alle Komponenten
│ │
│ ├── vue3-css/ # Vite + Vue 3 + styles.css
│ ├── vue3-css/ # Vite + Vue 3 + style.css
│ │ ├── package.json
│ │ ├── vite.config.ts
│ │ └── src/
│ │ ├── main.ts # import '@ocelot-social/ui/styles.css'
│ │ ├── main.ts # import '@ocelot-social/ui/style.css'
│ │ └── App.vue
│ │
│ ├── vue2-tailwind/ # Vue CLI / Nuxt 2 + Tailwind
│ │ └── ...
│ │
│ └── vue2-css/ # Vue CLI / Nuxt 2 + styles.css
│ └── vue2-css/ # Vue CLI / Nuxt 2 + style.css
│ └── ...
```
@ -1360,7 +1376,7 @@ for (const example of examples) {
"require": "./dist/index.cjs",
"types": "./dist/index.d.ts"
},
"./styles.css": "./dist/styles.css",
"./style.css": "./dist/style.css",
"./tailwind.preset": {
"import": "./dist/tailwind.preset.mjs",
"require": "./dist/tailwind.preset.cjs",

64
packages/ui/README.md Normal file
View File

@ -0,0 +1,64 @@
# @ocelot-social/ui
Vue component library for ocelot.social - works with Vue 2.7+ and Vue 3.
## Installation
```bash
npm install @ocelot-social/ui
```
## Usage
### Option 1: Individual Imports (recommended)
Import only the components you need. This enables tree-shaking for smaller bundle sizes.
```ts
import { OsButton, OsCard } from '@ocelot-social/ui'
```
```vue
<template>
<OsButton variant="primary">Click me</OsButton>
</template>
<script setup>
import { OsButton } from '@ocelot-social/ui'
</script>
```
### Option 2: Global Registration
Register all components globally via the Vue plugin. No tree-shaking - all components are included in the bundle.
```ts
// main.ts
import { createApp } from 'vue'
import { OcelotUI } from '@ocelot-social/ui'
import App from './App.vue'
const app = createApp(App)
app.use(OcelotUI)
app.mount('#app')
```
Components are then available globally without imports:
```vue
<template>
<OsButton variant="primary">Click me</OsButton>
</template>
```
## Vue 2.7 Support
This library uses [vue-demi](https://github.com/vueuse/vue-demi) for Vue 2/3 compatibility.
```ts
// Vue 2.7
import Vue from 'vue'
import { OcelotUI } from '@ocelot-social/ui'
Vue.use(OcelotUI)
```

3853
packages/ui/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

74
packages/ui/package.json Normal file
View File

@ -0,0 +1,74 @@
{
"name": "@ocelot-social/ui",
"version": "0.0.1",
"description": "Vue component library for ocelot.social - works with Vue 2.7+ and Vue 3",
"license": "Apache-2.0",
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
},
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"test": "vitest run",
"test:watch": "vitest",
"test:coverage": "vitest run --coverage",
"typecheck": "vue-tsc --noEmit",
"prepublishOnly": "npm run build"
},
"peerDependencies": {
"vue": "^2.7.0 || ^3.0.0"
},
"dependencies": {
"vue-demi": "^0.14.10"
},
"devDependencies": {
"@types/node": "^25.2.0",
"@vitejs/plugin-vue": "^6.0.4",
"@vitest/coverage-v8": "^4.0.18",
"@vue/test-utils": "^2.4.6",
"jsdom": "^28.0.0",
"typescript": "^5.9.3",
"vite": "^7.3.1",
"vite-plugin-dts": "^4.5.4",
"vite-tsconfig-paths": "^6.0.5",
"vitest": "^4.0.18",
"vue": "^3.5.27",
"vue-tsc": "^3.2.4"
},
"engines": {
"node": ">=18.0.0"
},
"repository": {
"type": "git",
"url": "https://github.com/Ocelot-Social-Community/Ocelot-Social.git",
"directory": "packages/ui"
},
"bugs": {
"url": "https://github.com/Ocelot-Social-Community/Ocelot-Social/issues"
},
"homepage": "https://github.com/Ocelot-Social-Community/Ocelot-Social/tree/master/packages/ui#readme",
"keywords": [
"vue",
"vue3",
"vue2",
"components",
"ui",
"ocelot-social",
"design-system"
],
"publishConfig": {
"access": "public"
}
}

View File

@ -0,0 +1,10 @@
/**
* Component exports
*
* Single source of truth for all components.
* Add new components here - they will automatically be:
* - Available as named exports: import { OsButton } from '@ocelot-social/ui'
* - Registered globally when using the plugin: app.use(OcelotUI)
*/
// export { default as OsButton } from './OsButton/OsButton.vue'

12
packages/ui/src/index.ts Normal file
View File

@ -0,0 +1,12 @@
/**
* @ocelot-social/ui
*
* Vue component library for ocelot.social
* Works with Vue 2.7+ and Vue 3
*/
// Re-export all components
export * from './components'
// Export Vue plugin for global registration
export { default as OcelotUI } from './plugin'

View File

@ -0,0 +1,33 @@
import { describe, it, expect, vi } from 'vitest'
import OcelotUI from './plugin'
import * as components from './components'
describe('OcelotUI Plugin', () => {
it('has an install function', () => {
expect(OcelotUI.install).toBeTypeOf('function')
})
it('registers all exported components', () => {
const mockApp = {
component: vi.fn(),
}
OcelotUI.install!(mockApp as never)
const componentEntries = Object.entries(components)
expect(mockApp.component).toHaveBeenCalledTimes(componentEntries.length)
for (const [name, component] of componentEntries) {
expect(mockApp.component).toHaveBeenCalledWith(name, component)
}
})
it('works with empty components', () => {
const mockApp = {
component: vi.fn(),
}
expect(() => OcelotUI.install!(mockApp as never)).not.toThrow()
})
})

21
packages/ui/src/plugin.ts Normal file
View File

@ -0,0 +1,21 @@
import type { App, Component, Plugin } from 'vue-demi'
import * as components from './components'
/**
* Vue plugin for global component registration
*
* Usage:
* ```ts
* import { OcelotUI } from '@ocelot-social/ui'
* app.use(OcelotUI)
* ```
*/
const OcelotUI: Plugin = {
install(app: App) {
for (const [name, component] of Object.entries(components)) {
app.component(name, component as Component)
}
},
}
export default OcelotUI

7
packages/ui/src/vite-env.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
/// <reference types="vite/client" />
declare module '*.vue' {
import type { DefineComponent } from 'vue-demi'
const component: DefineComponent<object, object, unknown>
export default component
}

41
packages/ui/tsconfig.json Normal file
View File

@ -0,0 +1,41 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "preserve",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true,
/* Paths */
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
},
/* Types */
"types": ["vite/client", "vitest/globals"]
},
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"vite.config.ts"
],
"exclude": ["node_modules", "dist"]
}

View File

@ -0,0 +1,51 @@
import { defineConfig } from 'vitest/config'
import vue from '@vitejs/plugin-vue'
import dts from 'vite-plugin-dts'
import tsconfigPaths from 'vite-tsconfig-paths'
import { resolve } from 'path'
export default defineConfig({
plugins: [
vue(),
tsconfigPaths(),
dts({
include: ['src/**/*.ts', 'src/**/*.vue'],
outDir: 'dist',
rollupTypes: true,
}),
],
build: {
lib: {
entry: resolve(__dirname, 'src/index.ts'),
name: 'OcelotSocialUI',
formats: ['es', 'cjs'],
fileName: (format) => `index.${format === 'es' ? 'mjs' : 'cjs'}`,
},
rollupOptions: {
external: ['vue', 'vue-demi'],
output: {
globals: {
vue: 'Vue',
'vue-demi': 'VueDemi',
},
},
},
cssCodeSplit: false,
sourcemap: true,
},
test: {
globals: true,
environment: 'jsdom',
include: ['src/**/*.{test,spec}.{js,ts}'],
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
include: ['src/**/*.{ts,vue}'],
exclude: [
'src/**/*.d.ts',
'src/**/*.{test,spec}.ts',
'src/**/index.ts',
],
},
},
})