Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"permissions": {
"allow": [
"Bash(npm run test:*)",
"Bash(npm install)",
"Bash(npm audit:*)",
"Bash(npm outdated)",
"Bash(npm run typecheck:*)",
"Bash(npm run lint)",
"Bash(npm run coverage:*)",
"Bash(npm run build:production:*)",
"Bash(npm update:*)",
"Bash(npm view:*)",
"Bash(npm install:*)",
"Bash(npm run build:*)",
"Bash(npm run lint:*)",
"Bash(git checkout:*)",
"Bash(git add:*)",
"Bash(node:*)"
],
"deny": [],
"ask": []
}
}
53 changes: 53 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
version: 2
updates:
# Enable version updates for npm
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:00"
open-pull-requests-limit: 10
reviewers:
- "audit-brands/maintainers"
assignees:
- "audit-brands/maintainers"
commit-message:
prefix: "chore(deps):"
include: "scope"
labels:
- "dependencies"
- "javascript"
# Group minor and patch updates
groups:
development-dependencies:
patterns:
- "@types/*"
- "@vue/*"
- "@vitejs/*"
- "eslint*"
- "vitest*"
- "typescript"
- "vite"
update-types:
- "minor"
- "patch"
production-dependencies:
patterns:
- "@vueuse/*"
- "vue"
- "tailwindcss"
- "@tailwindcss/*"
Comment on lines +11 to +40
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix Dependabot reviewer/assignee settings.

Dependabot rejects configs where assignees contain team slugs (org/team) and it can only request reviews from teams that belong to the repo owner. As written, the workflow will fail to parse and no update PRs will be created. Please replace these entries with valid GitHub usernames or with a team slug that exists under themesberg, or simply drop them.

-    reviewers:
-      - "audit-brands/maintainers"
-    assignees:
-      - "audit-brands/maintainers"
+    # reviewers: []
+    # assignees: []
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
reviewers:
- "audit-brands/maintainers"
assignees:
- "audit-brands/maintainers"
commit-message:
prefix: "chore(deps):"
include: "scope"
labels:
- "dependencies"
- "javascript"
# Group minor and patch updates
groups:
development-dependencies:
patterns:
- "@types/*"
- "@vue/*"
- "@vitejs/*"
- "eslint*"
- "vitest*"
- "typescript"
- "vite"
update-types:
- "minor"
- "patch"
production-dependencies:
patterns:
- "@vueuse/*"
- "vue"
- "tailwindcss"
- "@tailwindcss/*"
# reviewers: []
# assignees: []
commit-message:
prefix: "chore(deps):"
include: "scope"
labels:
- "dependencies"
- "javascript"
# Group minor and patch updates
groups:
development-dependencies:
patterns:
- "@types/*"
- "@vue/*"
- "@vitejs/*"
- "eslint*"
- "vitest*"
- "typescript"
- "vite"
update-types:
- "minor"
- "patch"
production-dependencies:
patterns:
- "@vueuse/*"
- "vue"
- "tailwindcss"
- "@tailwindcss/*"
🤖 Prompt for AI Agents
.github/dependabot.yml around lines 11 to 40: the reviewers and assignees
entries use an external team slug ("audit-brands/maintainers") which Dependabot
rejects and reviewers must belong to the repository owner; replace those team
slugs with valid GitHub usernames or with a team slug that exists under the repo
owner (e.g., themesberg/<team>) or remove the reviewers/assignees keys entirely;
ensure assignees are individual usernames (not teams) and reviewers reference
only teams that actually belong to the repo owner so the Dependabot config
parses and PRs can be created.

update-types:
- "patch"

# Enable version updates for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"
commit-message:
prefix: "chore(ci):"
labels:
- "github-actions"
- "ci"
114 changes: 114 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
name: CI

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
test:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [20.x, 22.x]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run linting
run: npm run lint

- name: Run type checking
run: npm run typecheck

- name: Run tests
run: npm run test

- name: Run test coverage
run: npm run coverage

- name: Upload coverage to Codecov
if: matrix.node-version == '20.x'
uses: codecov/codecov-action@v4
with:
fail_ci_if_error: false
verbose: true

- name: Build package
run: npm run build:production

- name: Build documentation
run: npm run build

security:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Run security audit
run: npm audit --audit-level=moderate

- name: Check for outdated dependencies
run: npm outdated || true

publish:
runs-on: ubuntu-latest
needs: [test, security]
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
cache: 'npm'
registry-url: 'https://registry.npmjs.org'

- name: Install dependencies
run: npm ci

- name: Build package
run: npm run build:production

- name: Publish to NPM (if version changed)
run: |
# Only publish if package.json version is different from published version
CURRENT_VERSION=$(node -p "require('./package.json').version")
PUBLISHED_VERSION=$(npm view flowbite-vue version 2>/dev/null || echo "0.0.0")

if [ "$CURRENT_VERSION" != "$PUBLISHED_VERSION" ]; then
echo "Publishing version $CURRENT_VERSION (was $PUBLISHED_VERSION)"
npm publish
else
echo "Version $CURRENT_VERSION already published, skipping"
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
92 changes: 92 additions & 0 deletions .github/workflows/dependency-updates.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Dependency Updates

on:
schedule:
# Run weekly on Mondays at 9 AM UTC
- cron: '0 9 * * 1'
workflow_dispatch: # Allow manual triggering

jobs:
update-dependencies:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
cache: 'npm'

- name: Check for updates
id: updates
run: |
npm outdated --json > outdated.json || true
if [ -s outdated.json ] && [ "$(cat outdated.json)" != "{}" ]; then
echo "has_updates=true" >> $GITHUB_OUTPUT
echo "Updates available:"
cat outdated.json
else
echo "has_updates=false" >> $GITHUB_OUTPUT
echo "No updates available"
fi

- name: Create dependency update issue
if: steps.updates.outputs.has_updates == 'true'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const outdated = JSON.parse(fs.readFileSync('outdated.json', 'utf8'));

let body = '# Dependency Updates Available\n\n';
body += 'The following dependencies have updates available:\n\n';
body += '| Package | Current | Wanted | Latest |\n';
body += '|---------|---------|--------|--------|\n';

for (const [name, info] of Object.entries(outdated)) {
body += `| ${name} | ${info.current} | ${info.wanted} | ${info.latest} |\n`;
}

body += '\n## Next Steps\n';
body += '1. Review the changes for each package\n';
body += '2. Test updates in a development environment\n';
body += '3. Update dependencies with `npm update`\n';
body += '4. Run tests to ensure compatibility\n';
body += '\n*This issue was automatically created by the dependency update workflow.*';

// Check if an issue already exists
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: ['dependencies']
});

const existingIssue = issues.data.find(issue =>
issue.title.includes('Dependency Updates Available')
);

if (existingIssue) {
// Update existing issue
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: existingIssue.number,
body: body
});
console.log(`Updated existing issue #${existingIssue.number}`);
} else {
// Create new issue
const issue = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: 'Dependency Updates Available',
body: body,
labels: ['dependencies', 'maintenance']
});
console.log(`Created new issue #${issue.data.number}`);
}
Comment on lines +9 to +92
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Grant issues: write to the workflow.

actions/github-script cannot create or update issues with the default token permissions (only contents: read), so the job will always fail at the GitHub API call. Add explicit permissions before the jobs block:

 on:
   schedule:
     - cron: '0 9 * * 1'
   workflow_dispatch:

+permissions:
+  contents: read
+  issues: write
+
 jobs:
   update-dependencies:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
jobs:
update-dependencies:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
cache: 'npm'
- name: Check for updates
id: updates
run: |
npm outdated --json > outdated.json || true
if [ -s outdated.json ] && [ "$(cat outdated.json)" != "{}" ]; then
echo "has_updates=true" >> $GITHUB_OUTPUT
echo "Updates available:"
cat outdated.json
else
echo "has_updates=false" >> $GITHUB_OUTPUT
echo "No updates available"
fi
- name: Create dependency update issue
if: steps.updates.outputs.has_updates == 'true'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const outdated = JSON.parse(fs.readFileSync('outdated.json', 'utf8'));
let body = '# Dependency Updates Available\n\n';
body += 'The following dependencies have updates available:\n\n';
body += '| Package | Current | Wanted | Latest |\n';
body += '|---------|---------|--------|--------|\n';
for (const [name, info] of Object.entries(outdated)) {
body += `| ${name} | ${info.current} | ${info.wanted} | ${info.latest} |\n`;
}
body += '\n## Next Steps\n';
body += '1. Review the changes for each package\n';
body += '2. Test updates in a development environment\n';
body += '3. Update dependencies with `npm update`\n';
body += '4. Run tests to ensure compatibility\n';
body += '\n*This issue was automatically created by the dependency update workflow.*';
// Check if an issue already exists
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: ['dependencies']
});
const existingIssue = issues.data.find(issue =>
issue.title.includes('Dependency Updates Available')
);
if (existingIssue) {
// Update existing issue
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: existingIssue.number,
body: body
});
console.log(`Updated existing issue #${existingIssue.number}`);
} else {
// Create new issue
const issue = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: 'Dependency Updates Available',
body: body,
labels: ['dependencies', 'maintenance']
});
console.log(`Created new issue #${issue.data.number}`);
}
on:
schedule:
- cron: '0 9 * * 1'
workflow_dispatch:
permissions:
contents: read
issues: write
jobs:
update-dependencies:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
cache: 'npm'
- name: Check for updates
id: updates
run: |
npm outdated --json > outdated.json || true
if [ -s outdated.json ] && [ "$(cat outdated.json)" != "{}" ]; then
echo "has_updates=true" >> $GITHUB_OUTPUT
echo "Updates available:"
cat outdated.json
else
echo "has_updates=false" >> $GITHUB_OUTPUT
echo "No updates available"
fi
- name: Create dependency update issue
if: steps.updates.outputs.has_updates == 'true'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const outdated = JSON.parse(fs.readFileSync('outdated.json', 'utf8'));
let body = '# Dependency Updates Available\n\n';
body += 'The following dependencies have updates available:\n\n';
body += '| Package | Current | Wanted | Latest |\n';
body += '|---------|---------|--------|--------|\n';
for (const [name, info] of Object.entries(outdated)) {
body += `| ${name} | ${info.current} | ${info.wanted} | ${info.latest} |\n`;
}
body += '\n## Next Steps\n';
body += '1. Review the changes for each package\n';
body += '2. Test updates in a development environment\n';
body += '3. Update dependencies with `npm update`\n';
body += '4. Run tests to ensure compatibility\n';
body += '\n*This issue was automatically created by the dependency update workflow.*';
// Check if an issue already exists
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: ['dependencies']
});
const existingIssue = issues.data.find(issue =>
issue.title.includes('Dependency Updates Available')
);
if (existingIssue) {
// Update existing issue
await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: existingIssue.number,
body: body
});
console.log(`Updated existing issue #${existingIssue.number}`);
} else {
// Create new issue
const issue = await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: 'Dependency Updates Available',
body: body,
labels: ['dependencies', 'maintenance']
});
console.log(`Created new issue #${issue.data.number}`);
}
🤖 Prompt for AI Agents
.github/workflows/dependency-updates.yml lines 9-92: the workflow uses
actions/github-script to create/update issues but lacks explicit permissions so
the default token won't allow issue writes; add a top-level permissions block
(placed before jobs:) that grants issues: write (e.g., permissions: issues:
write) so the workflow can create and update GitHub issues, keeping or
explicitly setting required other permissions like contents: read if needed.

83 changes: 83 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Commands

### Development
```bash
# Start development server (VitePress documentation site)
npm run dev

# Build documentation site
npm run build

# Build the Vue component library for production
npm run build:production
```

### Testing & Quality
```bash
# Run tests with Vitest
npm run test

# Run tests with coverage
npm run coverage

# Run linting
npm run lint

# Fix linting issues
npm run lint-fix

# Type checking
npm run typecheck
```

### Library Build
```bash
# Build the package for distribution
npm run build:package

# Build type declarations only
npm run build:types

# Full production build (package + types)
npm run build:production
```

## Architecture

### Component Structure
The project is a Vue 3 component library implementing Flowbite design system. Each component follows this structure:
- `src/components/FwbComponentName/` - Component directory
- `FwbComponentName.vue` - Main component implementation
- `types.ts` - TypeScript type definitions for props and types
- `composables/` - Vue composables for component logic (classes, state management)
- `tests/` - Vitest test files (when present)

### Key Patterns
- **Class Generation**: Components use composables (e.g., `useComponentClasses.ts`) to generate Tailwind CSS classes based on props
- **Type Safety**: All components have TypeScript definitions in separate `types.ts` files
- **Composition API**: All components use Vue 3 Composition API with `<script setup>`
- **Tailwind Integration**: Components use Tailwind CSS v4 with `tailwind-merge` for class management
- **Component Prefix**: All components use `Fwb` prefix (Flowbite Web)

### Import Aliases
- `@/` maps to `./src/` directory for clean imports

### Testing
Tests use Vitest with Vue Test Utils. Test files are located in component-specific `tests/` folders and use the `.spec.ts` extension.

### Documentation
The project includes a VitePress documentation site in the `docs/` directory. Component examples and documentation are maintained as Markdown files.

## Development Workflow

When creating or modifying components:
1. Component implementation goes in `src/components/FwbComponentName/`
2. Use existing component patterns for consistency
3. Create TypeScript types in a separate `types.ts` file
4. Use composables for class generation logic
5. Export the component from `src/index.ts` for library consumers
6. Add documentation in `docs/components/` if creating a new component
Loading