Skip to content

Commit

Permalink
Merge pull request #18 from hotwired-laravel/strada
Browse files Browse the repository at this point in the history
Support Strada
  • Loading branch information
tonysm authored Nov 24, 2023
2 parents 4db4287 + 1f8092e commit eac587f
Show file tree
Hide file tree
Showing 14 changed files with 149 additions and 31 deletions.
4 changes: 3 additions & 1 deletion src/Commands/Concerns/InstallsForImportmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ protected function registerImportmapPins()
{
$this->components->task('pinning JS dependency (importmap)', function () {
$this->callSilently('importmap:pin', [
'packages' => ['@hotwired/stimulus'],
'packages' => collect($this->jsPackages())
->map(fn ($package, $version) => "{$package}@{$version}")
->all(),
]);

// Publishes the `@hotwired/stimulus-loading` package to public/
Expand Down
9 changes: 4 additions & 5 deletions src/Commands/Concerns/InstallsForNode.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,12 @@ protected function updateNpmPackagesForNode()
{
$this->components->task('registering NPM dependency', function () {
$this->updateNodePackages(function ($packages) {
return [
'@hotwired/stimulus' => '^3.1.0',
] + $packages;
return array_merge(
$packages,
$this->jsPackages(),
);
});

$this->afterMessages[] = '<fg=white>Run: `<fg=yellow>npm install && npm run dev</>`</>';

return true;
});
}
Expand Down
51 changes: 43 additions & 8 deletions src/Commands/InstallCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@

use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use RuntimeException;
use Symfony\Component\Process\Process;

class InstallCommand extends Command
{
use Concerns\InstallsForImportmap;
use Concerns\InstallsForNode;

public $signature = 'stimulus:install';
public $signature = 'stimulus:install {--strada : Sets up Strada as well.}';

public $description = 'Installs the Stimulus Laravel package.';

Expand All @@ -24,21 +26,54 @@ public function handle(): int
$this->installsForImportmaps();
} else {
$this->installsForNode();
}

if (! empty($this->afterMessages)) {
$this->newLine();
$this->components->info('After Notes and Next Steps');
$this->components->bulletList($this->afterMessages);
} else {
$this->components->info('Done');
if (file_exists(base_path('pnpm-lock.yaml'))) {
$this->runCommands(['pnpm install', 'pnpm run build']);
} elseif (file_exists(base_path('yarn.lock'))) {
$this->runCommands(['yarn install', 'yarn run build']);
} else {
$this->runCommands(['npm install', 'npm run build']);
}
}

$this->newLine();
$this->components->info('Done');
$this->newLine();

return self::SUCCESS;
}

protected function jsPackages(): array
{
return array_merge(
['@hotwired/stimulus' => '^3.1.0'],
$this->hasOption('strada') ? ['@hotwired/strada' => '^1.0.0-beta1'] : [],
);
}

/**
* Run the given commands.
*
* @param array $commands
* @return void
*/
protected function runCommands($commands)
{
$process = Process::fromShellCommandline(implode(' && ', $commands), null, null, null, null);

if ('\\' !== DIRECTORY_SEPARATOR && file_exists('/dev/tty') && is_readable('/dev/tty')) {
try {
$process->setTty(true);
} catch (RuntimeException $e) {
$this->output->writeln(' <bg=yellow;fg=black> WARN </> '.$e->getMessage().PHP_EOL);
}
}

$process->run(function ($type, $line) {
$this->output->write(' '.$line);
});
}

protected function usingImportmaps(): bool
{
return File::exists($this->importmapsFile());
Expand Down
9 changes: 9 additions & 0 deletions src/Commands/MakeCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use HotwiredLaravel\StimulusLaravel\StimulusGenerator;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Process;

class MakeCommand extends Command
{
Expand All @@ -26,6 +27,14 @@ public function handle(StimulusGenerator $generator): int
$this->components->task('regenerating manifest', function () {
return $this->callSilently(ManifestCommand::class);
});

if (file_exists(base_path('pnpm-lock.yaml'))) {
Process::forever()->path(base_path())->run(['pnpm', 'run', 'build']);
} elseif (file_exists(base_path('yarn.lock'))) {
Process::forever()->path(base_path())->run(['yarn', 'run', 'build']);
} else {
Process::forever()->path(base_path())->run(['npm', 'run', 'build']);
}
}

$this->newLine();
Expand Down
2 changes: 1 addition & 1 deletion src/Commands/ManifestCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public function handle(Manifest $generator)
// Run that command whenever you add a new controller or create them with
// `php artisan stimulus:make controllerName`
import { application } from '../libs/stimulus'
import { Stimulus } from '../libs/stimulus'
{$manifest}
JS);
Expand Down
48 changes: 48 additions & 0 deletions src/Commands/StradaMakeCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace HotwiredLaravel\StimulusLaravel\Commands;

use HotwiredLaravel\StimulusLaravel\StimulusGenerator;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Process;

class StradaMakeCommand extends Command
{
public $signature = 'strada:make
{name : The Strada Component name (without bridge prefix.}
{--prefix=bridge : The component prefix.}
{--bridge-name= : The name of the native component.}';

public $description = 'Makes a new Strada Component.';

public function handle(StimulusGenerator $generator): int
{
$this->components->info('Making Strada Component');

$this->components->task('creating strada component', function () use ($generator) {
$generator->createStrada($this->option('prefix'), $this->argument('name'), $this->option('bridge-name'));

return true;
});

if (! File::exists(base_path('routes/importmap.php'))) {
$this->components->task('regenerating manifest', function () {
return $this->callSilently(ManifestCommand::class);
});

if (file_exists(base_path('pnpm-lock.yaml'))) {
Process::forever()->path(base_path())->run(['pnpm', 'run', 'build']);
} elseif (file_exists(base_path('yarn.lock'))) {
Process::forever()->path(base_path())->run(['yarn', 'run', 'build']);
} else {
Process::forever()->path(base_path())->run(['npm', 'run', 'build']);
}
}

$this->newLine();
$this->components->info('Done');

return self::SUCCESS;
}
}
2 changes: 1 addition & 1 deletion src/Manifest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function generateFrom(string $controllersPath): Collection
return <<<JS
import {$controllerClassName} from '{$join(['.', $modulePath])}'
application.register('{$tagName}', {$controllerClassName})
Stimulus.register('{$tagName}', {$controllerClassName})
JS;
});
}
Expand Down
19 changes: 17 additions & 2 deletions src/StimulusGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,21 @@ public function __construct(private ?string $targetFolder = null)
$this->targetFolder ??= rtrim(resource_path('js/controllers'), '/');
}

public function create(string $name): array
public function create(string $name, string $stub = null, callable $replacementsCallback = null): array
{
$replacementsCallback ??= fn ($replacements) => $replacements;
$controllerName = $this->controllerName($name);
$targetFile = $this->targetFolder.'/'.$controllerName.'_controller.js';

File::ensureDirectoryExists(dirname($targetFile));

$replacements = $replacementsCallback([
'[attribute]' => $attributeName = $this->attributeName($name),
]);

File::put(
$targetFile,
str_replace('[attribute]', $attributeName = $this->attributeName($name), File::get(__DIR__.'/../stubs/controller.stub')),
str_replace(array_keys($replacements), array_values($replacements), File::get($stub ?: __DIR__.'/../stubs/controller.stub')),
);

return [
Expand All @@ -31,6 +36,16 @@ public function create(string $name): array
];
}

public function createStrada(string $prefix, string $name, string $bridgeName = null): array
{
return $this->create("$prefix/$name", stub: __DIR__.'/../stubs/strada.stub', replacementsCallback: function (array $replacements) use ($bridgeName) {
return array_merge(
$replacements,
['[bridge-name]' => $bridgeName ?? (string) Str::of($replacements['[attribute]'])->afterLast('--')],
);
});
}

private function controllerName(string $name): string
{
return Str::of($name)->replace('_controller', '')->snake('_');
Expand Down
1 change: 1 addition & 0 deletions src/StimulusLaravelServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function configurePackage(Package $package): void
->hasCommands([
Commands\InstallCommand::class,
Commands\MakeCommand::class,
Commands\StradaMakeCommand::class,
Commands\CoreMakeCommand::class,
Commands\PublishCommand::class,
Commands\ManifestCommand::class,
Expand Down
4 changes: 2 additions & 2 deletions stubs/resources/js/controllers/index-importmap.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { application } from 'libs/stimulus'
import { Stimulus } from 'libs/stimulus'

// Eager load all controllers defined in the import map under controllers/**/*_controller
import { eagerLoadControllersFrom } from '@hotwired/stimulus-loading'
eagerLoadControllersFrom('controllers', application)
eagerLoadControllersFrom('controllers', Stimulus)
4 changes: 2 additions & 2 deletions stubs/resources/js/controllers/index-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Run that command whenever you add a new controller or create them with
// `php artisan stimulus:make controllerName`

import { application } from '../libs/stimulus'
import { Stimulus } from '../libs/stimulus'

import HelloController from './hello_controller'
application.register('hello', HelloController)
Stimulus.register('hello', HelloController)
9 changes: 5 additions & 4 deletions stubs/resources/js/libs/stimulus.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { Application } from '@hotwired/stimulus'

const application = Application.start()
const Stimulus = Application.start()

// Configure Stimulus development experience
application.debug = false
window.Stimulus = application
Stimulus.debug = false

export { application }
window.Stimulus = Stimulus

export { Stimulus }
8 changes: 8 additions & 0 deletions stubs/strada.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { BridgeComponent, BridgeElement } from "@hotwired/strada"

// Connects to data-controller="[attribute]"
export default class extends BridgeComponent {
static component = "[bridge-name]"

//
}
10 changes: 5 additions & 5 deletions tests/ManifestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function generates_controllers_imports_given_a_path()
<<<'JS'
import HelloController from './hello_controller'
application.register('hello', HelloController)
Stimulus.register('hello', HelloController)
JS,
$manifest,
);
Expand All @@ -28,7 +28,7 @@ public function generates_controllers_imports_given_a_path()
<<<'JS'
import Nested__DeepController from './nested/deep_controller'
application.register('nested--deep', Nested__DeepController)
Stimulus.register('nested--deep', Nested__DeepController)
JS,
$manifest,
);
Expand All @@ -37,7 +37,7 @@ public function generates_controllers_imports_given_a_path()
<<<'JS'
import CoffeeController from './coffee_controller'
application.register('coffee', CoffeeController)
Stimulus.register('coffee', CoffeeController)
JS,
$manifest,
);
Expand All @@ -46,7 +46,7 @@ public function generates_controllers_imports_given_a_path()
<<<'JS'
import TypeScriptController from './type_script_controller'
application.register('type-script', TypeScriptController)
Stimulus.register('type-script', TypeScriptController)
JS,
$manifest,
);
Expand All @@ -55,7 +55,7 @@ public function generates_controllers_imports_given_a_path()
<<<'JS'
import Index from './index'
application.register('index', Index)
Stimulus.register('index', Index)
JS,
$manifest,
);
Expand Down

0 comments on commit eac587f

Please sign in to comment.