Merge branch '3.x'

This commit is contained in:
Adam Weston
2023-11-28 10:31:46 -05:00
38 changed files with 757 additions and 347 deletions

View File

@@ -2,9 +2,9 @@ root = true
[*] [*]
charset = utf-8 charset = utf-8
end_of_line = lf
indent_size = 4 indent_size = 4
indent_style = space indent_style = space
end_of_line = lf
insert_final_newline = true insert_final_newline = true
trim_trailing_whitespace = true trim_trailing_whitespace = true

21
.gitattributes vendored
View File

@@ -5,15 +5,24 @@
/.github export-ignore /.github export-ignore
/.gitattributes export-ignore /.gitattributes export-ignore
/.gitignore export-ignore /.gitignore export-ignore
/phpunit.xml.dist export-ignore /.idea export-ignore
/art export-ignore /.prettierrc export-ignore
/docs export-ignore /.package-lock.json export-ignore
/tests export-ignore
/.editorconfig export-ignore /.editorconfig export-ignore
/.php_cs.dist.php export-ignore /.php_cs.dist.php export-ignore
/.vscode export-ignore
/art export-ignore
/docs export-ignore
/images export-ignore
/tests export-ignore
/package.json export-ignore
/phpstan-baseline.neon export-ignore
/phpstan.neon.dist export-ignore
/postcss.config.js export-ignore
/phpunit.xml.dist export-ignore
/pint.json export-ignore
/psalm.xml export-ignore /psalm.xml export-ignore
/psalm.xml.dist export-ignore /psalm.xml.dist export-ignore
/tailwind.config.js export-ignore
/testbench.yaml export-ignore /testbench.yaml export-ignore
/UPGRADING.md export-ignore /UPGRADING.md export-ignore
/phpstan.neon.dist export-ignore
/phpstan-baseline.neon export-ignore

View File

@@ -14,7 +14,7 @@ Please be considerate towards maintainers when raising issues or presenting pull
world that developers are civilized and selfless people. world that developers are civilized and selfless people.
It's the duty of the maintainer to ensure that all submissions to the project are of sufficient It's the duty of the maintainer to ensure that all submissions to the project are of sufficient
quality to benefit the project. Many developers have different skillsets, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used. quality to benefit the project. Many developers have different skills, strengths, and weaknesses. Respect the maintainer's decision, and do not be upset or abusive if your submission is not used.
## Viability ## Viability

66
.github/ISSUE_TEMPLATE/bug.yml vendored Normal file
View File

@@ -0,0 +1,66 @@
name: Bug Report
description: Report an Issue or Bug with the Package
title: "[Bug]: "
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
We're sorry to hear you have a problem. Can you help us solve it by providing the following details.
- type: textarea
id: what-happened
attributes:
label: What happened?
description: What did you expect to happen?
placeholder: I cannot currently do X thing because when I do, it breaks X thing.
validations:
required: true
- type: textarea
id: how-to-reproduce
attributes:
label: How to reproduce the bug
description: How did this occur, please add any config values used and provide a set of reliable steps if possible.
placeholder: When I do X I see Y.
validations:
required: true
- type: input
id: package-version
attributes:
label: Package Version
description: What version of our Package are you running? Please be as specific as possible
placeholder: 2.0.0
validations:
required: true
- type: input
id: php-version
attributes:
label: PHP Version
description: What version of PHP are you running? Please be as specific as possible
placeholder: 8.2.0
validations:
required: true
- type: input
id: laravel-version
attributes:
label: Laravel Version
description: What version of Laravel are you running? Please be as specific as possible
placeholder: 9.0.0
validations:
required: true
- type: dropdown
id: operating-systems
attributes:
label: Which operating systems does with happen with?
description: You may select more than one.
multiple: true
options:
- macOS
- Windows
- Linux
- type: textarea
id: notes
attributes:
label: Notes
description: Use this field to provide any other notes that you feel might be relevant to the issue.
validations:
required: false

View File

@@ -9,6 +9,3 @@ contact_links:
- name: Report a security issue - name: Report a security issue
url: https://github.com/:vendor_name/:package_name/security/policy url: https://github.com/:vendor_name/:package_name/security/policy
about: Learn how to notify us for sensitive bugs about: Learn how to notify us for sensitive bugs
- name: Report a bug
url: https://github.com/:vendor_name/:package_name/issues/new
about: Report a reproducable bug

View File

@@ -1,4 +1,5 @@
name: dependabot-auto-merge name: "Dependabot Auto-Merge"
on: pull_request_target on: pull_request_target
permissions: permissions:

View File

@@ -1,21 +0,0 @@
name: Fix PHP code style issues
on: [push]
jobs:
php-code-styling:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
ref: ${{ github.head_ref }}
- name: Fix PHP code style issues
uses: aglipanci/laravel-pint-action@1.0.0
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: Fix styling

View File

@@ -0,0 +1,27 @@
name: "Fix PHP Code Styling"
on:
push:
paths:
- '**.php'
permissions:
contents: write
jobs:
php-code-styling:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
- name: Fix PHP code style issues
uses: aglipanci/laravel-pint-action@2.3.0
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: Fix styling

View File

@@ -11,7 +11,7 @@ jobs:
name: phpstan name: phpstan
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
- name: Setup PHP - name: Setup PHP
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
@@ -20,7 +20,7 @@ jobs:
coverage: none coverage: none
- name: Install composer dependencies - name: Install composer dependencies
uses: ramsey/composer-install@v1 uses: ramsey/composer-install@v2
- name: Run PHPStan - name: Run PHPStan
run: ./vendor/bin/phpstan --error-format=github run: ./vendor/bin/phpstan --error-format=github

View File

@@ -13,18 +13,19 @@ jobs:
fail-fast: true fail-fast: true
matrix: matrix:
os: [ubuntu-latest, windows-latest] os: [ubuntu-latest, windows-latest]
php: [8.1] php: [8.2, 8.1]
laravel: [9.*] laravel: [10.*]
stability: [prefer-lowest, prefer-stable] stability: [prefer-lowest, prefer-stable]
include: include:
- laravel: 9.* - laravel: 10.*
testbench: 7.* testbench: 8.*
carbon: ^2.63
name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }} name: P${{ matrix.php }} - L${{ matrix.laravel }} - ${{ matrix.stability }} - ${{ matrix.os }}
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v4
- name: Setup PHP - name: Setup PHP
uses: shivammathur/setup-php@v2 uses: shivammathur/setup-php@v2
@@ -40,8 +41,11 @@ jobs:
- name: Install dependencies - name: Install dependencies
run: | run: |
composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" "nesbot/carbon:${{ matrix.carbon }}" --no-interaction --no-update
composer update --${{ matrix.stability }} --prefer-dist --no-interaction composer update --${{ matrix.stability }} --prefer-dist --no-interaction
- name: List Installed Dependencies
run: composer show -D
- name: Execute tests - name: Execute tests
run: vendor/bin/pest run: vendor/bin/pest --ci

View File

@@ -4,13 +4,16 @@ on:
release: release:
types: [released] types: [released]
permissions:
contents: write
jobs: jobs:
update: update:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v3 uses: actions/checkout@v4
with: with:
ref: main ref: main
@@ -21,7 +24,7 @@ jobs:
release-notes: ${{ github.event.release.body }} release-notes: ${{ github.event.release.body }}
- name: Commit updated CHANGELOG - name: Commit updated CHANGELOG
uses: stefanzweifel/git-auto-commit-action@v4 uses: stefanzweifel/git-auto-commit-action@v5
with: with:
branch: main branch: main
commit_message: Update CHANGELOG commit_message: Update CHANGELOG

7
.gitignore vendored
View File

@@ -1,14 +1,13 @@
.DS_Store
.idea .idea
.php_cs
.php_cs.cache
.phpunit.result.cache .phpunit.result.cache
.vscode
build build
composer.lock composer.lock
coverage coverage
docs docs
node_modules
phpunit.xml phpunit.xml
phpstan.neon phpstan.neon
testbench.yaml testbench.yaml
vendor vendor
node_modules
.php-cs-fixer.cache

5
.prettierrc Normal file
View File

@@ -0,0 +1,5 @@
{
"semi": false,
"singleQuote": true,
"trailingComma": "all"
}

View File

@@ -1,8 +1,8 @@
# :package_description # :package_description
[![Latest Version on Packagist](https://img.shields.io/packagist/v/:vendor_slug/:package_slug.svg?style=flat-square)](https://packagist.org/packages/:vendor_slug/:package_slug) [![Latest Version on Packagist](https://img.shields.io/packagist/v/:vendor_slug/:package_slug.svg?style=flat-square)](https://packagist.org/packages/:vendor_slug/:package_slug)
[![GitHub Tests Action Status](https://img.shields.io/github/workflow/status/:vendor_slug/:package_slug/run-tests?label=tests)](https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3Arun-tests+branch%3Amain) [![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/:vendor_slug/:package_slug/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3Arun-tests+branch%3Amain)
[![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/:vendor_slug/:package_slug/Check%20&%20fix%20styling?label=code%20style)](https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain) [![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/:vendor_slug/:package_slug/fix-php-code-style-issues.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/:vendor_slug/:package_slug/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
[![Total Downloads](https://img.shields.io/packagist/dt/:vendor_slug/:package_slug.svg?style=flat-square)](https://packagist.org/packages/:vendor_slug/:package_slug) [![Total Downloads](https://img.shields.io/packagist/dt/:vendor_slug/:package_slug.svg?style=flat-square)](https://packagist.org/packages/:vendor_slug/:package_slug)
<!--delete--> <!--delete-->
@@ -54,8 +54,8 @@ return [
## Usage ## Usage
```php ```php
$skeleton = new VendorName\Skeleton(); $variable = new VendorName\Skeleton();
echo $skeleton->echoPhrase('Hello, VendorName!'); echo $variable->echoPhrase('Hello, VendorName!');
``` ```
## Testing ## Testing

50
bin/build.js Normal file
View File

@@ -0,0 +1,50 @@
import esbuild from 'esbuild'
const isDev = process.argv.includes('--dev')
async function compile(options) {
const context = await esbuild.context(options)
if (isDev) {
await context.watch()
} else {
await context.rebuild()
await context.dispose()
}
}
const defaultOptions = {
define: {
'process.env.NODE_ENV': isDev ? `'development'` : `'production'`,
},
bundle: true,
mainFields: ['module', 'main'],
platform: 'neutral',
sourcemap: isDev ? 'inline' : false,
sourcesContent: isDev,
treeShaking: true,
target: ['es2020'],
minify: !isDev,
plugins: [{
name: 'watchPlugin',
setup: function (build) {
build.onStart(() => {
console.log(`Build started at ${new Date(Date.now()).toLocaleTimeString()}: ${build.initialOptions.outfile}`)
})
build.onEnd((result) => {
if (result.errors.length > 0) {
console.log(`Build failed at ${new Date(Date.now()).toLocaleTimeString()}: ${build.initialOptions.outfile}`, result.errors)
} else {
console.log(`Build finished at ${new Date(Date.now()).toLocaleTimeString()}: ${build.initialOptions.outfile}`)
}
})
}
}],
}
compile({
...defaultOptions,
entryPoints: ['./resources/js/index.js'],
outfile: './resources/dist/skeleton.js',
})

View File

@@ -7,6 +7,10 @@
":package_slug" ":package_slug"
], ],
"homepage": "https://github.com/:vendor_slug/:package_slug", "homepage": "https://github.com/:vendor_slug/:package_slug",
"support": {
"issues": "https://github.com/:vendor_slug/:package_slug/issues",
"source": "https://github.com/:vendor_slug/:package_slug"
},
"license": "MIT", "license": "MIT",
"authors": [ "authors": [
{ {
@@ -16,50 +20,47 @@
} }
], ],
"require": { "require": {
"php": "^8.0", "php": "^8.1",
"filament/filament": "^2.0", "filament/filament": "^3.0",
"spatie/laravel-package-tools": "^1.9.2", "filament/forms": "^3.0",
"illuminate/contracts": "^9.0" "filament/tables": "^3.0",
"spatie/laravel-package-tools": "^1.15.0",
"illuminate/contracts": "^10.0"
}, },
"require-dev": { "require-dev": {
"laravel/pint": "^1.0", "laravel/pint": "^1.0",
"nunomaduro/collision": "^6.0", "nunomaduro/collision": "^7.9",
"nunomaduro/larastan": "^2.0.1", "nunomaduro/larastan": "^2.0.1",
"orchestra/testbench": "^7.0", "orchestra/testbench": "^8.0",
"pestphp/pest": "^1.21", "pestphp/pest": "^2.0",
"pestphp/pest-plugin-laravel": "^1.1", "pestphp/pest-plugin-arch": "^2.0",
"pestphp/pest-plugin-livewire": "^1.0", "pestphp/pest-plugin-laravel": "^2.0",
"pestphp/pest-plugin-parallel": "^0.3",
"phpstan/extension-installer": "^1.1", "phpstan/extension-installer": "^1.1",
"phpstan/phpstan-deprecation-rules": "^1.0", "phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-phpunit": "^1.0", "phpstan/phpstan-phpunit": "^1.0",
"phpunit/phpunit": "^9.5",
"spatie/laravel-ray": "^1.26" "spatie/laravel-ray": "^1.26"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"VendorName\\Skeleton\\": "src", "VendorName\\Skeleton\\": "src/",
"VendorName\\Skeleton\\Database\\Factories\\": "database/factories" "VendorName\\Skeleton\\Database\\Factories\\": "database/factories/"
} }
}, },
"autoload-dev": { "autoload-dev": {
"psr-4": { "psr-4": {
"VendorName\\Skeleton\\Tests\\": "tests" "VendorName\\Skeleton\\Tests\\": "tests/"
} }
}, },
"scripts": { "scripts": {
"pint": "vendor/bin/pint", "post-autoload-dump": "@php ./vendor/bin/testbench package:discover --ansi",
"test:pest": "vendor/bin/pest --parallel", "analyse": "vendor/bin/phpstan analyse",
"test:phpstan": "vendor/bin/phpstan analyse", "test": "vendor/bin/pest",
"test": [ "test-coverage": "vendor/bin/pest --coverage",
"@test:pest", "format": "vendor/bin/pint"
"@test:phpstan"
]
}, },
"config": { "config": {
"sort-packages": true, "sort-packages": true,
"allow-plugins": { "allow-plugins": {
"composer/package-versions-deprecated": true,
"pestphp/pest-plugin": true, "pestphp/pest-plugin": true,
"phpstan/extension-installer": true "phpstan/extension-installer": true
} }

View File

@@ -7,14 +7,16 @@ $authorName = ask('Author name', $gitName);
$gitEmail = run('git config user.email'); $gitEmail = run('git config user.email');
$authorEmail = ask('Author email', $gitEmail); $authorEmail = ask('Author email', $gitEmail);
$usernameGuess = explode(':', run('git config remote.origin.url'))[1]; $usernameGuess = explode(':', run('git config remote.origin.url'))[1] ?? '';
if ($usernameGuess !== '') {
$usernameGuess = dirname($usernameGuess); $usernameGuess = dirname($usernameGuess);
$usernameGuess = basename($usernameGuess); $usernameGuess = basename($usernameGuess);
}
$authorUsername = ask('Author username', $usernameGuess); $authorUsername = ask('Author username', $usernameGuess);
$vendorName = ask('Vendor name', $authorUsername); $vendorName = ask('Vendor name', $authorUsername);
$vendorSlug = slugify($vendorName); $vendorSlug = slugify($vendorName);
$vendorNamespace = ucwords($vendorName); $vendorNamespace = str_replace('-', '', ucwords($vendorName));
$vendorNamespace = ask('Vendor namespace', $vendorNamespace); $vendorNamespace = ask('Vendor namespace', $vendorNamespace);
$currentDirectory = getcwd(); $currentDirectory = getcwd();
@@ -22,40 +24,101 @@ $folderName = basename($currentDirectory);
$packageName = ask('Package name', $folderName); $packageName = ask('Package name', $folderName);
$packageSlug = slugify($packageName); $packageSlug = slugify($packageName);
$packageSlugWithoutPrefix = remove_prefix('laravel-', $packageSlug); $packageSlugWithoutPrefix = removePrefix('filament-', $packageSlug);
$className = title_case($packageName); $className = titleCase($packageName);
$className = ask('Class name', $className); $className = ask('Class name', $className);
$description = ask('Package description', "This is my package {$packageSlug}"); $variableName = lcfirst($className);
$description = ask('Package description', "This is my package $packageSlug");
$usePhpStan = confirm('Enable PhpStan?', true); $usePhpStan = confirm('Enable PhpStan?', true);
$usePint = confirm('Enable Pint?', true); $usePint = confirm('Enable Pint?', true);
$useDependabot = confirm('Enable Dependabot?', true);
$useLaravelRay = confirm('Enable Ray?', true);
$useUpdateChangelogWorkflow = confirm('Use automatic changelog updater workflow?', true); $useUpdateChangelogWorkflow = confirm('Use automatic changelog updater workflow?', true);
writeln('------'); $isTheme = confirm('Is this a custom theme?');
writeln("Author : {$authorName} ({$authorUsername}, {$authorEmail})"); $formsOnly = ! $isTheme && confirm('Is this for Forms only?');
writeln("Vendor : {$vendorName} ({$vendorSlug})"); $tablesOnly = ! ($isTheme || $formsOnly) && confirm('Is this for Tables only?');
writeln("Package : {$packageSlug} <{$description}>");
writeln("Namespace : {$vendorNamespace}\\{$className}");
writeln("Class name : {$className}");
writeln('---');
writeln('Packages & Utilities');
writeln('Use PhpCsFixer : ' . ($usePhpCsFixer ? 'yes' : 'no'));
writeln('Use Larastan/PhpStan : ' . ($usePhpStan ? 'yes' : 'no'));
writeln('Use Pint : ' . ($usePint ? 'yes' : 'no'));
writeln('Use Auto-Changelog : ' . ($useUpdateChangelogWorkflow ? 'yes' : 'no'));
writeln('------');
writeln("\r");
writeln('------');
writeln("Author : \e[0;36m$authorName ($authorUsername, $authorEmail)\e[0m");
writeln("Vendor : \e[0;36m$vendorName ($vendorSlug)\e[0m");
writeln('Package : ' . "\e[0;36m" . $packageSlug . ($description ? " <{$description}>" : '') . "\e[0m");
writeln("Namespace : \e[0;36m$vendorNamespace\\$className\e[0m");
writeln("Class name : \e[0;36m$className\e[0m");
writeln('---');
writeln("\e[1;37mPackages & Utilities\e[0m");
writeln('Larastan/PhpStan : ' . ($usePhpStan ? "\e[0;32mYes" : "\e[0;31mNo") . "\e[0m");
writeln('Pint : ' . ($usePint ? "\e[0;32mYes" : "\e[0;31mNo") . "\e[0m");
writeln('Use Dependabot : ' . ($useDependabot ? "\e[0;32mYes" : "\e[0;31mNo") . "\e[0m");
writeln('Use Ray : ' . ($useLaravelRay ? "\e[0;32mYes" : "\e[0;31mNo") . "\e[0m");
writeln('Auto-Changelog : ' . ($useUpdateChangelogWorkflow ? "\e[0;32mYes" : "\e[0;31mNo") . "\e[0m");
if ($formsOnly) {
writeln("Filament/Forms : \e[0;32mYes\e[0m");
} elseif ($tablesOnly) {
writeln("Filament/Tables : \e[0;32mYes\e[0m");
} else {
writeln("Filament/Filament : \e[0;32mYes\e[0m");
}
writeln('------');
writeln("\r");
writeln('This script will replace the above values in all relevant files in the project directory.'); writeln('This script will replace the above values in all relevant files in the project directory.');
writeln("\r");
if (! confirm('Modify files?', true)) { if (! confirm('Modify files?', true)) {
exit(1); exit(1);
} }
if ($formsOnly) {
safeUnlink(__DIR__ . '/src/SkeletonTheme.php');
safeUnlink(__DIR__ . '/src/SkeletonPlugin.php');
removeComposerDeps([
'filament/filament',
'filament/tables',
], 'require');
} elseif ($tablesOnly) {
safeUnlink(__DIR__ . '/src/SkeletonTheme.php');
safeUnlink(__DIR__ . '/src/SkeletonPlugin.php');
removeComposerDeps([
'filament/filament',
'filament/forms',
], 'require');
} else {
if ($isTheme) {
safeUnlink(__DIR__ . '/src/SkeletonServiceProvider.php');
safeUnlink(__DIR__ . '/src/SkeletonPlugin.php');
safeUnlink(__DIR__ . '/src/Skeleton.php');
removeDirectory(__DIR__ . '/bin');
removeDirectory(__DIR__ . '/config');
removeDirectory(__DIR__ . '/database');
removeDirectory(__DIR__ . '/stubs');
removeDirectory(__DIR__ . '/resources/js');
removeDirectory(__DIR__ . '/resources/lang');
removeDirectory(__DIR__ . '/resources/views');
removeDirectory(__DIR__ . '/src/Commands');
removeDirectory(__DIR__ . '/src/Facades');
removeDirectory(__DIR__ . '/src/Testing');
setupPackageJsonForTheme();
} else {
safeUnlink(__DIR__ . '/src/SkeletonTheme.php');
}
removeComposerDeps([
'filament/forms',
'filament/tables',
], 'require');
}
$files = (str_starts_with(strtoupper(PHP_OS), 'WIN') ? replaceForWindows() : replaceForAllOtherOSes()); $files = (str_starts_with(strtoupper(PHP_OS), 'WIN') ? replaceForWindows() : replaceForAllOtherOSes());
foreach ($files as $file) { foreach ($files as $file) {
replace_in_file($file, [ replaceInFile($file, [
':author_name' => $authorName, ':author_name' => $authorName,
':author_username' => $authorUsername, ':author_username' => $authorUsername,
'author@domain.com' => $authorEmail, 'author@domain.com' => $authorEmail,
@@ -67,30 +130,34 @@ foreach ($files as $file) {
':package_slug_without_prefix' => $packageSlugWithoutPrefix, ':package_slug_without_prefix' => $packageSlugWithoutPrefix,
'Skeleton' => $className, 'Skeleton' => $className,
'skeleton' => $packageSlug, 'skeleton' => $packageSlug,
'migration_table_name' => titleSnake($packageSlug),
'variable' => $variableName,
':package_description' => $description, ':package_description' => $description,
]); ]);
match (true) { match (true) {
str_contains($file, determineSeparator('src/Skeleton.php')) => rename($file, determineSeparator('./src/' . $className . '.php')), str_contains($file, determineSeparator('src/Skeleton.php')) => rename($file, determineSeparator('./src/' . $className . '.php')),
str_contains($file, determineSeparator('src/SkeletonServiceProvider.php')) => rename($file, determineSeparator('./src/' . $className . 'ServiceProvider.php')), str_contains($file, determineSeparator('src/SkeletonServiceProvider.php')) => rename($file, determineSeparator('./src/' . $className . 'ServiceProvider.php')),
str_contains($file, determineSeparator('src/SkeletonTheme.php')) => rename($file, determineSeparator('./src/' . $className . 'Theme.php')),
str_contains($file, determineSeparator('src/SkeletonPlugin.php')) => rename($file, determineSeparator('./src/' . $className . 'Plugin.php')),
str_contains($file, determineSeparator('src/Facades/Skeleton.php')) => rename($file, determineSeparator('./src/Facades/' . $className . '.php')), str_contains($file, determineSeparator('src/Facades/Skeleton.php')) => rename($file, determineSeparator('./src/Facades/' . $className . '.php')),
str_contains($file, determineSeparator('src/Commands/SkeletonCommand.php')) => rename($file, determineSeparator('./src/Commands/' . $className . 'Command.php')), str_contains($file, determineSeparator('src/Commands/SkeletonCommand.php')) => rename($file, determineSeparator('./src/Commands/' . $className . 'Command.php')),
str_contains($file, determineSeparator('database/migrations/create_skeleton_table.php.stub')) => rename($file, determineSeparator('./database/migrations/create_' . $packageSlugWithoutPrefix . '_table.php.stub')), str_contains($file, determineSeparator('src/Testing/TestsSkeleton.php')) => rename($file, determineSeparator('./src/Testing/Tests' . $className . '.php')),
str_contains($file, determineSeparator('database/migrations/create_skeleton_table.php.stub')) => rename($file, determineSeparator('./database/migrations/create_' . titleSnake($packageSlugWithoutPrefix) . '_table.php.stub')),
str_contains($file, determineSeparator('config/skeleton.php')) => rename($file, determineSeparator('./config/' . $packageSlugWithoutPrefix . '.php')), str_contains($file, determineSeparator('config/skeleton.php')) => rename($file, determineSeparator('./config/' . $packageSlugWithoutPrefix . '.php')),
str_contains($file, 'README.md') => remove_readme_paragraphs($file), str_contains($file, determineSeparator('resources/lang/en/skeleton.php')) => rename($file, determineSeparator('./resources/lang/en/' . $packageSlugWithoutPrefix . '.php')),
str_contains($file, 'README.md') => removeTag($file, 'delete'),
default => [], default => [],
}; };
} }
if (! $usePint) { if (! $useDependabot) {
safeUnlink(__DIR__ . '/pint.json'); safeUnlink(__DIR__ . '/.github/dependabot.yml');
safeUnlink(__DIR__ . '/.github/workflows/pint.yml'); safeUnlink(__DIR__ . '/.github/workflows/dependabot-auto-merge.yml');
}
remove_composer_deps([ if (! $useLaravelRay) {
'laravel/pint', removeComposerDeps(['spatie/laravel-ray'], 'require-dev');
]);
remove_composer_script(['pint']);
} }
if (! $usePhpStan) { if (! $usePhpStan) {
@@ -98,32 +165,41 @@ if (! $usePhpStan) {
safeUnlink(__DIR__ . '/phpstan-baseline.neon'); safeUnlink(__DIR__ . '/phpstan-baseline.neon');
safeUnlink(__DIR__ . '/.github/workflows/phpstan.yml'); safeUnlink(__DIR__ . '/.github/workflows/phpstan.yml');
remove_composer_deps([ removeComposerDeps([
'phpstan/extension-installer', 'phpstan/extension-installer',
'phpstan/phpstan-deprecation-rules', 'phpstan/phpstan-deprecation-rules',
'phpstan/phpstan-phpunit', 'phpstan/phpstan-phpunit',
'nunomaduro/larastan', 'nunomaduro/larastan',
]); ], 'require-dev');
remove_composer_script([ removeComposerDeps(['analyse'], 'scripts');
'test:phpstan', }
'@test:phpstan',
]); if (! $usePint) {
safeUnlink(__DIR__ . '/.github/workflows/fix-php-code-style-issues.yml');
safeUnlink(__DIR__ . '/pint.json');
removeComposerDeps([
'laravel/pint',
], 'require-dev');
removeComposerDeps(['format'], 'scripts');
} }
if (! $useUpdateChangelogWorkflow) { if (! $useUpdateChangelogWorkflow) {
safeUnlink(__DIR__ . '/.github/workflows/update-changelog.yml'); safeUnlink(__DIR__ . '/.github/workflows/update-changelog.yml');
} }
confirm('Execute `composer install` and run tests?') && run('composer install && composer test'); confirm('Execute `composer install`?') && run('composer install');
confirm('Let this script delete itself?', true) && unlink(__FILE__); if (confirm('Let this script delete itself?', true)) {
unlink(__FILE__);
}
function ask(string $question, string $default = ''): string function ask(string $question, string $default = ''): string
{ {
$consoleColor = new ConsoleColor(); $def = $default ? "\e[0;33m ($default)" : '';
$def = $default ? $consoleColor->apply('yellow', " ({$default})") : null; $answer = readline("\e[0;32m" . $question . $def . ": \e[0m");
$answer = readline($consoleColor->apply('green', $question . $def . ': '));
if (! $answer) { if (! $answer) {
return $default; return $default;
@@ -134,11 +210,9 @@ function ask(string $question, string $default = ''): string
function confirm(string $question, bool $default = false): bool function confirm(string $question, bool $default = false): bool
{ {
$consoleColor = new ConsoleColor();
$answer = ask($question, ($default ? 'Y/n' : 'y/N')); $answer = ask($question, ($default ? 'Y/n' : 'y/N'));
if (! $answer) { if (strtolower($answer) === 'y/n') {
return $default; return $default;
} }
@@ -152,18 +226,7 @@ function writeln(string $line): void
function run(string $command): string function run(string $command): string
{ {
return trim(shell_exec($command)); return trim((string) shell_exec($command));
}
function str_after(string $subject, string $search): string
{
$pos = strrpos($subject, $search);
if ($pos === false) {
return $subject;
}
return substr($subject, $pos + strlen($search));
} }
function slugify(string $subject): string function slugify(string $subject): string
@@ -171,12 +234,17 @@ function slugify(string $subject): string
return strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $subject), '-')); return strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $subject), '-'));
} }
function title_case(string $subject): string function titleCase(string $subject): string
{ {
return str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $subject))); return str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $subject)));
} }
function replace_in_file(string $file, array $replacements): void function titleSnake(string $subject, string $replace = '_'): string
{
return str_replace(['-', '_'], $replace, $subject);
}
function replaceInFile(string $file, array $replacements): void
{ {
$contents = file_get_contents($file); $contents = file_get_contents($file);
@@ -190,7 +258,7 @@ function replace_in_file(string $file, array $replacements): void
); );
} }
function remove_prefix(string $prefix, string $content): string function removePrefix(string $prefix, string $content): string
{ {
if (str_starts_with($content, $prefix)) { if (str_starts_with($content, $prefix)) {
return substr($content, strlen($prefix)); return substr($content, strlen($prefix));
@@ -199,53 +267,68 @@ function remove_prefix(string $prefix, string $content): string
return $content; return $content;
} }
function remove_composer_deps(array $names) function removeComposerDeps(array $names, string $location): void
{ {
$data = json_decode(file_get_contents(__DIR__ . '/composer.json'), true); $data = json_decode(file_get_contents(__DIR__ . '/composer.json'), true);
foreach ($data['require-dev'] as $name => $version) { foreach ($data[$location] as $name => $version) {
if (in_array($name, $names, true)) { if (in_array($name, $names, true)) {
unset($data['require-dev'][$name]); unset($data[$location][$name]);
} }
} }
file_put_contents(__DIR__ . '/composer.json', json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); file_put_contents(__DIR__ . '/composer.json', json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
} }
function remove_composer_script(array $scriptNames) function removeNpmDeps(array $names, string $location): void
{ {
$data = json_decode(file_get_contents(__DIR__ . '/composer.json'), true); $data = json_decode(file_get_contents(__DIR__ . '/package.json'), true);
foreach ($data['scripts'] as $name => $script) { foreach ($data[$location] as $name => $version) {
if (is_array($script)) { if (in_array($name, $names, true)) {
foreach ($script as $k => $s) { unset($data[$location][$name]);
if (in_array($s, $scriptNames)) {
unset($data['scripts'][$name][$k]);
break;
}
}
} elseif (in_array($name, $scriptNames)) {
unset($data['scripts'][$name]);
break;
} }
} }
file_put_contents(__DIR__ . '/composer.json', json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)); file_put_contents(__DIR__ . '/package.json', json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES |
JSON_UNESCAPED_UNICODE));
} }
function remove_readme_paragraphs(string $file): void function removeTag(string $file, string $tag): void
{ {
$contents = file_get_contents($file); $contents = file_get_contents($file);
file_put_contents( file_put_contents(
$file, $file,
preg_replace('/<!--delete-->.*<!--\/delete-->/s', '', $contents) ?: $contents preg_replace('/<!--' . $tag . '-->.*<!--\/' . $tag . '-->/s', '', $contents) ?: $contents
); );
} }
function safeUnlink(string $filename) function setupPackageJsonForTheme(): void
{
removeNpmDeps([
'purge',
'dev',
'dev:scripts',
'build',
'build:scripts',
], 'scripts');
removeNpmDeps([
'@awcodes/filament-plugin-purge',
'esbuild',
'npm-run-all',
'prettier',
'prettier-plugin-tailwindcss',
], 'devDependencies');
replaceInFile(__DIR__ . '/package.json', [
'dev:styles' => 'dev',
'build:styles' => 'build',
]);
}
function safeUnlink(string $filename): void
{ {
if (file_exists($filename) && is_file($filename)) { if (file_exists($filename) && is_file($filename)) {
unlink($filename); unlink($filename);
@@ -259,118 +342,25 @@ function determineSeparator(string $path): string
function replaceForWindows(): array function replaceForWindows(): array
{ {
return preg_split('/\\r\\n|\\r|\\n/', run('dir /S /B * | findstr /v /i .git\ | findstr /v /i vendor | findstr /v /i ' . basename(__FILE__) . ' | findstr /r /i /M /F:/ ":author :vendor :package VendorName skeleton vendor_name vendor_slug author@domain.com"')); return preg_split('/\\r\\n|\\r|\\n/', run('dir /S /B * | findstr /v /i .git\ | findstr /v /i vendor | findstr /v /i ' . basename(__FILE__) . ' | findstr /r /i /M /F:/ ":author :vendor :package VendorName skeleton migration_table_name vendor_name vendor_slug author@domain.com"'));
} }
function replaceForAllOtherOSes(): array function replaceForAllOtherOSes(): array
{ {
return explode(PHP_EOL, run('grep -E -r -l -i ":author|:vendor|:package|VendorName|skeleton|vendor_name|vendor_slug|author@domain.com" --exclude-dir=vendor ./* ./.github/* | grep -v ' . basename(__FILE__))); return explode(PHP_EOL, run('grep -E -r -l -i ":author|:vendor|:package|VendorName|skeleton|migration_table_name|vendor_name|vendor_slug|author@domain.com" --exclude-dir=vendor ./* ./.github/* | grep -v ' . basename(__FILE__)));
} }
class ConsoleColor function removeDirectory($dir): void
{ {
const FOREGROUND = 38; if (is_dir($dir)) {
$objects = scandir($dir);
const BACKGROUND = 48; foreach ($objects as $object) {
if ($object != '.' && $object != '..') {
const COLOR256_REGEXP = '~^(bg_)?color_([0-9]{1,3})$~'; if (filetype($dir . '/' . $object) == 'dir') {
removeDirectory($dir . '/' . $object);
const RESET_STYLE = 0;
/** @var bool */
private $isSupported;
/** @var bool */
private $forceStyle = false;
/** @var array */
private $styles = [
'none' => null,
'bold' => '1',
'dark' => '2',
'italic' => '3',
'underline' => '4',
'blink' => '5',
'reverse' => '7',
'concealed' => '8',
'default' => '39',
'black' => '30',
'red' => '31',
'green' => '32',
'yellow' => '33',
'blue' => '34',
'magenta' => '35',
'cyan' => '36',
'light_gray' => '37',
'dark_gray' => '90',
'light_red' => '91',
'light_green' => '92',
'light_yellow' => '93',
'light_blue' => '94',
'light_magenta' => '95',
'light_cyan' => '96',
'white' => '97',
'bg_default' => '49',
'bg_black' => '40',
'bg_red' => '41',
'bg_green' => '42',
'bg_yellow' => '43',
'bg_blue' => '44',
'bg_magenta' => '45',
'bg_cyan' => '46',
'bg_light_gray' => '47',
'bg_dark_gray' => '100',
'bg_light_red' => '101',
'bg_light_green' => '102',
'bg_light_yellow' => '103',
'bg_light_blue' => '104',
'bg_light_magenta' => '105',
'bg_light_cyan' => '106',
'bg_white' => '107',
];
/** @var array */
private $themes = [];
public function __construct()
{
$this->isSupported = $this->isSupported();
}
/**
* @param string|array $style
* @param string $text
* @return string
*
* @throws InvalidStyleException
* @throws \InvalidArgumentException
*/
public function apply($style, $text)
{
if (! $this->isStyleForced() && ! $this->isSupported()) {
return $text;
}
if (is_string($style)) {
$style = [$style];
}
if (! is_array($style)) {
throw new \InvalidArgumentException('Style must be string or array.');
}
$sequences = [];
foreach ($style as $s) {
if (isset($this->themes[$s])) {
$sequences = array_merge($sequences, $this->themeSequence($s));
} elseif ($this->isValidStyle($s)) {
$sequences[] = $this->styleSequence($s);
} else { } else {
throw new InvalidStyleException($s); unlink($dir . '/' . $object);
}
} }
} }

View File

@@ -8,7 +8,7 @@ return new class extends Migration
{ {
public function up() public function up()
{ {
Schema::create('skeleton_table', function (Blueprint $table) { Schema::create('migration_table_name_table', function (Blueprint $table) {
$table->id(); $table->id();
// add fields // add fields

View File

@@ -1,20 +1,26 @@
{ {
"private": true, "private": true,
"type": "module",
"scripts": { "scripts": {
"dev:styles": "npx tailwindcss -i resources/css/plugin.css -o resources/dist/skeleton.css --postcss --watch", "dev:styles": "npx tailwindcss -i resources/css/index.css -o resources/dist/skeleton.css --postcss --watch",
"dev:scripts": "esbuild resources/js/plugin.js --bundle --sourcemap=inline --outfile=resources/dist/skeleton.js --watch", "dev:scripts": "node bin/build.js --dev",
"build:styles": "npx tailwindcss -i resources/css/plugin.css -o resources/dist/skeleton.css --postcss --minify && npm run purge", "build:styles": "npx tailwindcss -i resources/css/index.css -o resources/dist/skeleton.css --postcss --minify && npm run purge",
"build:scripts": "esbuild resources/js/plugin.js --bundle --minify --outfile=resources/dist/skeleton.js", "build:scripts": "node bin/build.js",
"purge": "filament-purge -i resources/dist/skeleton.css -o resources/dist/skeleton.css", "purge": "filament-purge -i resources/dist/skeleton.css -o resources/dist/skeleton.css -v 3.x",
"dev": "npm-run-all --parallel dev:*", "dev": "npm-run-all --parallel dev:*",
"build": "npm-run-all build:*" "build": "npm-run-all build:*"
}, },
"devDependencies": { "devDependencies": {
"@awcodes/filament-plugin-purge": "^1.0.2", "@awcodes/filament-plugin-purge": "^1.1.1",
"autoprefixer": "^10.4.7", "@tailwindcss/forms": "^0.5.4",
"esbuild": "^0.8.57", "@tailwindcss/typography": "^0.5.9",
"autoprefixer": "^10.4.14",
"esbuild": "^0.19.2",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"postcss": "^8.4.14", "postcss": "^8.4.26",
"tailwindcss": "^3.1.6" "postcss-import": "^15.1.0",
"prettier": "^2.7.1",
"prettier-plugin-tailwindcss": "^0.1.13",
"tailwindcss": "^3.3.3"
} }
} }

View File

@@ -1,14 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<phpunit <phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.2/phpunit.xsd"
backupGlobals="false" backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php" bootstrap="vendor/autoload.php"
colors="true" colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false" processIsolation="false"
stopOnFailure="false" stopOnFailure="false"
executionOrder="random" executionOrder="random"
@@ -16,7 +12,8 @@
failOnRisky="true" failOnRisky="true"
failOnEmptyTestSuite="true" failOnEmptyTestSuite="true"
beStrictAboutOutputDuringTests="true" beStrictAboutOutputDuringTests="true"
verbose="true" cacheDirectory=".phpunit.cache"
backupStaticProperties="false"
> >
<testsuites> <testsuites>
<testsuite name="VendorName Test Suite"> <testsuite name="VendorName Test Suite">
@@ -24,9 +21,6 @@
</testsuite> </testsuite>
</testsuites> </testsuites>
<coverage> <coverage>
<include>
<directory suffix=".php">./src</directory>
</include>
<report> <report>
<html outputDirectory="build/coverage"/> <html outputDirectory="build/coverage"/>
<text outputFile="build/coverage.txt"/> <text outputFile="build/coverage.txt"/>
@@ -36,4 +30,9 @@
<logging> <logging>
<junit outputFile="build/report.junit.xml"/> <junit outputFile="build/report.junit.xml"/>
</logging> </logging>
<source>
<include>
<directory suffix=".php">./src</directory>
</include>
</source>
</phpunit> </phpunit>

View File

@@ -6,6 +6,9 @@
"spacing": "one" "spacing": "one"
}, },
"method_argument_space": true, "method_argument_space": true,
"single_trait_insert_per_statement": true "single_trait_insert_per_statement": true,
"types_spaces": {
"space": "single"
}
} }
} }

8
postcss.config.cjs Normal file
View File

@@ -0,0 +1,8 @@
module.exports = {
plugins: {
"postcss-import": {},
"tailwindcss/nesting": {},
tailwindcss: {},
autoprefixer: {},
},
}

View File

@@ -1,6 +0,0 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};

1
resources/css/index.css Normal file
View File

@@ -0,0 +1 @@
@import '../../vendor/filament/filament/resources/css/theme.css';

View File

@@ -1 +0,0 @@
@tailwind utilities;

View File

@@ -0,0 +1,6 @@
<?php
// translations for VendorName/Skeleton
return [
//
];

View File

@@ -0,0 +1,19 @@
<?php
namespace VendorName\Skeleton\Commands;
use Illuminate\Console\Command;
class SkeletonCommand extends Command
{
public $signature = 'skeleton';
public $description = 'My command';
public function handle(): int
{
$this->comment('All done');
return self::SUCCESS;
}
}

16
src/Facades/Skeleton.php Normal file
View File

@@ -0,0 +1,16 @@
<?php
namespace VendorName\Skeleton\Facades;
use Illuminate\Support\Facades\Facade;
/**
* @see \VendorName\Skeleton\Skeleton
*/
class Skeleton extends Facade
{
protected static function getFacadeAccessor()
{
return \VendorName\Skeleton\Skeleton::class;
}
}

7
src/Skeleton.php Normal file
View File

@@ -0,0 +1,7 @@
<?php
namespace VendorName\Skeleton;
class Skeleton
{
}

37
src/SkeletonPlugin.php Normal file
View File

@@ -0,0 +1,37 @@
<?php
namespace VendorName\Skeleton;
use Filament\Contracts\Plugin;
use Filament\Panel;
class SkeletonPlugin implements Plugin
{
public function getId(): string
{
return 'skeleton';
}
public function register(Panel $panel): void
{
//
}
public function boot(Panel $panel): void
{
//
}
public static function make(): static
{
return app(static::class);
}
public static function get(): static
{
/** @var static $plugin */
$plugin = filament(app(static::class)->getId());
return $plugin;
}
}

View File

@@ -2,39 +2,153 @@
namespace VendorName\Skeleton; namespace VendorName\Skeleton;
use Filament\PluginServiceProvider; use Filament\Support\Assets\AlpineComponent;
use Filament\Support\Assets\Asset;
use Filament\Support\Assets\Css;
use Filament\Support\Assets\Js;
use Filament\Support\Facades\FilamentAsset;
use Filament\Support\Facades\FilamentIcon;
use Illuminate\Filesystem\Filesystem;
use Livewire\Features\SupportTesting\Testable;
use Spatie\LaravelPackageTools\Commands\InstallCommand;
use Spatie\LaravelPackageTools\Package; use Spatie\LaravelPackageTools\Package;
use Spatie\LaravelPackageTools\PackageServiceProvider;
use VendorName\Skeleton\Commands\SkeletonCommand;
use VendorName\Skeleton\Testing\TestsSkeleton;
class SkeletonServiceProvider extends PluginServiceProvider class SkeletonServiceProvider extends PackageServiceProvider
{ {
public static string $name = 'skeleton'; public static string $name = 'skeleton';
protected array $resources = [ public static string $viewNamespace = 'skeleton';
// CustomResource::class,
];
protected array $pages = [
// CustomPage::class,
];
protected array $widgets = [
// CustomWidget::class,
];
protected array $styles = [
'plugin-skeleton' => __DIR__ . '/../resources/dist/skeleton.css',
];
protected array $scripts = [
'plugin-skeleton' => __DIR__ . '/../resources/dist/skeleton.js',
];
// protected array $beforeCoreScripts = [
// 'plugin-skeleton' => __DIR__ . '/../resources/dist/skeleton.js',
// ];
public function configurePackage(Package $package): void public function configurePackage(Package $package): void
{ {
$package->name(static::$name); /*
* This class is a Package Service Provider
*
* More info: https://github.com/spatie/laravel-package-tools
*/
$package->name(static::$name)
->hasCommands($this->getCommands())
->hasInstallCommand(function (InstallCommand $command) {
$command
->publishConfigFile()
->publishMigrations()
->askToRunMigrations()
->askToStarRepoOnGitHub(':vendor_slug/:package_slug');
});
$configFileName = $package->shortName();
if (file_exists($package->basePath("/../config/{$configFileName}.php"))) {
$package->hasConfigFile();
}
if (file_exists($package->basePath('/../database/migrations'))) {
$package->hasMigrations($this->getMigrations());
}
if (file_exists($package->basePath('/../resources/lang'))) {
$package->hasTranslations();
}
if (file_exists($package->basePath('/../resources/views'))) {
$package->hasViews(static::$viewNamespace);
}
}
public function packageRegistered(): void
{
}
public function packageBooted(): void
{
// Asset Registration
FilamentAsset::register(
$this->getAssets(),
$this->getAssetPackageName()
);
FilamentAsset::registerScriptData(
$this->getScriptData(),
$this->getAssetPackageName()
);
// Icon Registration
FilamentIcon::register($this->getIcons());
// Handle Stubs
if (app()->runningInConsole()) {
foreach (app(Filesystem::class)->files(__DIR__ . '/../stubs/') as $file) {
$this->publishes([
$file->getRealPath() => base_path("stubs/skeleton/{$file->getFilename()}"),
], 'skeleton-stubs');
}
}
// Testing
Testable::mixin(new TestsSkeleton());
}
protected function getAssetPackageName(): ?string
{
return ':vendor_slug/:package_slug';
}
/**
* @return array<Asset>
*/
protected function getAssets(): array
{
return [
// AlpineComponent::make('skeleton', __DIR__ . '/../resources/dist/components/skeleton.js'),
Css::make('skeleton-styles', __DIR__ . '/../resources/dist/skeleton.css'),
Js::make('skeleton-scripts', __DIR__ . '/../resources/dist/skeleton.js'),
];
}
/**
* @return array<class-string>
*/
protected function getCommands(): array
{
return [
SkeletonCommand::class,
];
}
/**
* @return array<string>
*/
protected function getIcons(): array
{
return [];
}
/**
* @return array<string>
*/
protected function getRoutes(): array
{
return [];
}
/**
* @return array<string, mixed>
*/
protected function getScriptData(): array
{
return [];
}
/**
* @return array<string>
*/
protected function getMigrations(): array
{
return [
'create_skeleton_table',
];
} }
} }

39
src/SkeletonTheme.php Normal file
View File

@@ -0,0 +1,39 @@
<?php
namespace VendorName\Skeleton;
use Filament\Contracts\Plugin;
use Filament\Panel;
use Filament\Support\Assets\Theme;
use Filament\Support\Color;
use Filament\Support\Facades\FilamentAsset;
class Skeleton implements Plugin
{
public function getId(): string
{
return 'skeleton';
}
public function register(Panel $panel): void
{
FilamentAsset::register([
Theme::make('skeleton', __DIR__ . '/../resources/dist/skeleton.css'),
]);
$panel
->font('DM Sans')
->primaryColor(Color::Amber)
->secondaryColor(Color::Gray)
->warningColor(Color::Amber)
->dangerColor(Color::Rose)
->successColor(Color::Green)
->grayColor(Color::Gray)
->theme('skeleton');
}
public function boot(Panel $panel): void
{
//
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace VendorName\Skeleton\Testing;
use Livewire\Features\SupportTesting\Testable;
/**
* @mixin Testable
*/
class TestsSkeleton
{
//
}

View File

@@ -1,21 +1,10 @@
const colors = require("tailwindcss/colors"); const preset = require('./vendor/filament/filament/tailwind.config.preset')
/** @type {import('tailwindcss').Config} */
module.exports = { module.exports = {
content: ["./resources/views/**/*.blade.php", "./src/**/*.php"], presets: [preset],
darkMode: "class", content: [
theme: { './app/Filament/**/*.php',
extend: { './resources/views/filament/**/*.blade.php',
colors: { './vendor/filament/**/*.blade.php',
danger: colors.rose, ],
primary: colors.yellow, }
success: colors.green,
warning: colors.amber,
},
},
},
corePlugins: {
preflight: false,
},
plugins: [],
};

5
tests/ArchTest.php Normal file
View File

@@ -0,0 +1,5 @@
<?php
it('will not use debugging functions')
->expect(['dd', 'dump', 'ray'])
->each->not->toBeUsed();

View File

@@ -2,10 +2,22 @@
namespace VendorName\Skeleton\Tests; namespace VendorName\Skeleton\Tests;
use BladeUI\Heroicons\BladeHeroiconsServiceProvider;
use BladeUI\Icons\BladeIconsServiceProvider;
use Filament\Actions\ActionsServiceProvider;
use Filament\FilamentServiceProvider; use Filament\FilamentServiceProvider;
use Filament\Forms\FormsServiceProvider;
use Filament\Infolists\InfolistsServiceProvider;
use Filament\Notifications\NotificationsServiceProvider;
use Filament\SpatieLaravelSettingsPluginServiceProvider;
use Filament\SpatieLaravelTranslatablePluginServiceProvider;
use Filament\Support\SupportServiceProvider;
use Filament\Tables\TablesServiceProvider;
use Filament\Widgets\WidgetsServiceProvider;
use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Database\Eloquent\Factories\Factory;
use Livewire\LivewireServiceProvider; use Livewire\LivewireServiceProvider;
use Orchestra\Testbench\TestCase as Orchestra; use Orchestra\Testbench\TestCase as Orchestra;
use RyanChandler\BladeCaptureDirective\BladeCaptureDirectiveServiceProvider;
use VendorName\Skeleton\SkeletonServiceProvider; use VendorName\Skeleton\SkeletonServiceProvider;
class TestCase extends Orchestra class TestCase extends Orchestra
@@ -22,8 +34,20 @@ class TestCase extends Orchestra
protected function getPackageProviders($app) protected function getPackageProviders($app)
{ {
return [ return [
LivewireServiceProvider::class, ActionsServiceProvider::class,
BladeCaptureDirectiveServiceProvider::class,
BladeHeroiconsServiceProvider::class,
BladeIconsServiceProvider::class,
FilamentServiceProvider::class, FilamentServiceProvider::class,
FormsServiceProvider::class,
InfolistsServiceProvider::class,
LivewireServiceProvider::class,
NotificationsServiceProvider::class,
SpatieLaravelSettingsPluginServiceProvider::class,
SpatieLaravelTranslatablePluginServiceProvider::class,
SupportServiceProvider::class,
TablesServiceProvider::class,
WidgetsServiceProvider::class,
SkeletonServiceProvider::class, SkeletonServiceProvider::class,
]; ];
} }