Skip to content
This repository has been archived by the owner on Feb 27, 2024. It is now read-only.

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
pascalbaljet committed Jan 22, 2024
1 parent 960841e commit f4f2772
Show file tree
Hide file tree
Showing 16 changed files with 146 additions and 34 deletions.
26 changes: 26 additions & 0 deletions app/app/View/Components/NestedChild.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\View\Components;

use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;

class NestedChild extends Component
{
/**
* Create a new component instance.
*/
public function __construct()
{
//
}

/**
* Get the view / contents that represent the component.
*/
public function render(): View|Closure|string
{
return view('components.nested-child');
}
}
26 changes: 26 additions & 0 deletions app/app/View/Components/NestedRoot.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\View\Components;

use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;

class NestedRoot extends Component
{
/**
* Create a new component instance.
*/
public function __construct()
{
//
}

/**
* Get the view / contents that represent the component.
*/
public function render(): View|Closure|string
{
return view('components.nested-root');
}
}
4 changes: 2 additions & 2 deletions app/resources/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import '../css/app.css'
import { createApp } from 'vue/dist/vue.esm-bundler.js'

// for dev
// import { SpladeCorePlugin } from '../../../dist/protone-media-laravel-splade-core'
import { SpladeCorePlugin } from '../../../dist/protone-media-laravel-splade-core'

// for build
import { SpladeCorePlugin } from '@protonemedia/laravel-splade-core'
// import { SpladeCorePlugin } from '@protonemedia/laravel-splade-core'

const app = createApp().use(SpladeCorePlugin, {
components: import.meta.glob('./splade/*.vue', { eager: true }),
Expand Down
7 changes: 6 additions & 1 deletion app/resources/views/components/emit.blade.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
<script setup>
const emit = defineEmits(['trigger'])
const count = ref(0)
const trigger = () => {
count.value++
emit('trigger')
}
</script>

<button @click="trigger">Trigger</button>
<button @click="trigger">Trigger</button>

<p>Times triggered: <span v-html="count"></span></p>
3 changes: 3 additions & 0 deletions app/resources/views/components/nested-child.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<script setup></script>

{{ $slot }}
3 changes: 3 additions & 0 deletions app/resources/views/components/nested-root.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<script setup></script>

{{ $slot }}
8 changes: 0 additions & 8 deletions app/resources/views/emit.blade.php
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
<x-layout>
<script setup>
const show = ref(false)
function toggle() {
show.value = !show.value
}
</script>

<x-emit @trigger="toggle" />

<h2 v-if="show">Triggered</h2>
Expand Down
21 changes: 21 additions & 0 deletions app/resources/views/nested.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<x-layout>
<script setup>
const toggled = ref(false)
const toggle = () => toggled.value = !toggled.value
</script>

<button @click="toggle">Toggle</button>

<p v-if="toggled">Parent - Blade Slot - toggled</p>
<p v-if="!toggled">Parent - Blade Slot - not toggled</p>

<x-nested-root>
<p v-if="toggled">Nested root - Blade Slot - toggled</p>
<p v-if="!toggled">Nested root - Blade Slot - not toggled</p>

<x-nested-child>
<p v-if="toggled">Nested child - Blade Slot - toggled</p>
<p v-if="!toggled">Nested child - Blade Slot - not toggled</p>
</x-nested-child>
</x-nested-root>
</x-layout>
1 change: 1 addition & 0 deletions app/routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
Route::view('/dynamic-component-import', 'dynamic-component-import');
Route::view('/emit', 'emit');
Route::view('/form', 'form');
Route::view('/nested', 'nested');
Route::view('/props-in-template', 'props-in-template');
Route::view('/refresh', 'refresh')->middleware(Refreshable::class);
Route::view('/refresh-state', 'refresh-state')->middleware(Refreshable::class);
Expand Down
11 changes: 2 additions & 9 deletions lib/GenericSpladeComponent.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup>
import { computed, inject, ref, onUnmounted } from "vue";
import { inject, ref, onUnmounted } from "vue";
const props = defineProps({
bridge: {
Expand All @@ -22,15 +22,8 @@ eventBus.on(`template:${templateId}`, updateTemplate);
onUnmounted(() => {
eventBus.off(`template:${templateId}`, updateTemplate);
});
const render = computed(() => {
return {
template: template.value,
name: "GenericSpladeComponentRender",
};
});
</script>

<template>
<render :splade-bridge="bridge" :splade-template-id="templateId"></render>
<slot />
</template>
32 changes: 27 additions & 5 deletions src/BladeViewExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,19 @@ protected function extractWrappedViewInRootLayout(): void
];
}

private function getDataObject(): Collection
{
$importedComponents = $this->getImportedComponents();

return Collection::make()
->merge($this->getBladeProperties())
->merge($this->scriptParser->getVariables()->reject(fn ($variable) => $variable === 'props'))
->merge($this->getBladeFunctions())
->when($this->isRefreshable(), fn (Collection $collection) => $collection->push('refreshComponent'))
->when($this->viewUsesElementRefs(), fn (Collection $collection) => $collection->push('setSpladeRef'))
->merge($importedComponents['dynamic']);
}

/**
* Handle the extraction of the Vue script. Returns the view without the <script setup> tag.
*/
Expand All @@ -123,7 +136,10 @@ public function handle(Filesystem $filesystem): string

// Adjust the current defineProps, or generate a new one if it didn't exist yet.
$defineVueProps = $this->extractDefinePropsFromScript();
$propsBag = $defineVueProps->toAttributeBag();

$propsBag = $defineVueProps->toAttributeBag(
$this->getDataObject()->all()
);

$vueComponent = implode(PHP_EOL, array_filter([
'<script setup>',
Expand All @@ -135,9 +151,9 @@ public function handle(Filesystem $filesystem): string
$this->renderJavascriptFunctionToRefreshComponent(),
$this->renderElementRefStoreAndSetter(),
$defineVueProps->getOriginalScript(),
$this->renderSpladeRenderFunction($defineVueProps),
// $this->renderSpladeRenderFunction($defineVueProps),
'</script>',
"<template><spladeRender {$propsBag->toHtml()} /></template>",
"<template><slot {$propsBag->toHtml()} /></template>",
]));

$directory = config('splade-core.compiled_scripts');
Expand All @@ -148,7 +164,13 @@ public function handle(Filesystem $filesystem): string
Process::path(base_path())->run("node_modules/.bin/eslint --fix {$vuePath}");
}

return $this->viewWithoutScriptTag;
$dataObject = $this->getDataObject()->implode(',');

return <<<HTML
<template #default="{{$dataObject}}">
{$this->viewWithoutScriptTag}
</template>
HTML;
}

/**
Expand Down Expand Up @@ -545,7 +567,7 @@ protected function renderSpladeRenderFunction(DefineVueProps $defineVueProps): s
{$inheritAttrs}
name: "{$this->getTag()}Render",
{$componentsObject}
template: spladeTemplates[props.spladeTemplateId],
template: '<slot />',
data: () => { return { {$dataObject} } },
props: {$definePropsObject},
};
Expand Down
4 changes: 2 additions & 2 deletions src/DefineVueProps.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,9 @@ public function toArray()
];
}

public function toAttributeBag(): ComponentAttributeBag
public function toAttributeBag(array $with = []): ComponentAttributeBag
{
$attrs = collect($this->getPropKeys())->mapWithKeys(function (string $prop) {
$attrs = collect($this->getPropKeys())->merge($with)->mapWithKeys(function (string $prop) {
$key = Str::kebab($prop);

return ['v-bind:'.$key => $prop];
Expand Down
6 changes: 3 additions & 3 deletions src/RenderViewAsVueComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ public function render(string $templateId): string
{
$tag = Str::kebab($this->tag);

$component = "<{$tag} splade-template-id=\"{$templateId}\"></{$tag}>";
$component = "<{$tag}></{$tag}>";

if (empty($this->rootLayoutTags)) {
return $component;
}

$rootLayout = Blade::render(<<<HTML
{$this->rootLayoutTags[0]}
###SPLADE-INJECT-HERE###
###SPLADE-INJECT-SLOT-HERE###
{$this->rootLayoutTags[1]}
HTML);

return str_replace('###SPLADE-INJECT-HERE###', $component, $rootLayout);
return str_replace('###SPLADE-INJECT-SLOT-HERE###', $component, $rootLayout);
}
}
11 changes: 10 additions & 1 deletion src/ScriptParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,23 @@ public function getVariables(Collection|array $additionalItems = []): Collection
$variables = Collection::make();
$nodes = Collection::make();

$add = fn (Identifier $node) => $variables->push($node->getName()) && $nodes->push($node);
$add = function (Identifier $node) use ($variables, $nodes) {
$variables->push($node->getName());
$nodes->push($node);
};

foreach ($this->rootNode->getBody() as $node) {
if ($node instanceof VariableDeclaration) {
foreach ($node->getDeclarations() as $declaration) {
$id = $declaration->getId();

if ($id instanceof Identifier) {
if ($id->getName() === 'emit') {
if ($declaration->getInit()->getCallee()->getName() === 'defineEmits') {
continue;
}
}

$add($id);
} elseif ($id instanceof ObjectPattern) {
foreach ($id->getProperties() as $property) {
Expand Down
2 changes: 1 addition & 1 deletion src/SpladeCoreServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ protected function registerBladeCompiler()
$app['files'],
$app['config']['view.compiled'],
$app['config']->get('view.relative_hash', false) ? $app->basePath() : '',
$app['config']->get('view.cache', true),
$app['config']->get('view.cache', false),
$app['config']->get('view.compiled_extension', 'php'),
), function (BladeCompiler $blade) {
$blade->component('dynamic-component', DynamicComponent::class);
Expand Down
15 changes: 13 additions & 2 deletions src/View/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ public function renderComponent()
// 'response',
]))->toHtml();

$tag = $spladeBridge['tag'];

collect($spladeBridge['props'])->each(function ($specs, $key) use ($attributes) {
if (! str_starts_with($key, 'v-bind:')) {
$key = 'v-bind:'.Str::kebab($key);
Expand All @@ -166,10 +168,19 @@ public function renderComponent()
: Js::from($specs->value)->toHtml();
});

$slotProps = collect($spladeBridge['props'])
->keys()
->map(fn ($key) => Str::camel($key))
->implode(',');

$attrs = $attributes->toHtml();

$tag = Str::kebab($tag);

// dd($spladeBridge);

return static::$trackSpladeComponents
? "<!--splade-template-id=\"{$templateId}\"--><generic-splade-component {$attrs} :bridge=\"{$spladeBridgeHtml}\"></generic-splade-component>"
: "<generic-splade-component {$attrs} :bridge=\"{$spladeBridgeHtml}\"></generic-splade-component>";
? "<generic-splade-component :bridge=\"{$spladeBridgeHtml}\"><{$tag} {$attrs}>{$output}</{$tag}></generic-splade-component>"
: "<generic-splade-component :bridge=\"{$spladeBridgeHtml}\"><{$tag} {$attrs}>{$output}</{$tag}></generic-splade-component>";
}
}

0 comments on commit f4f2772

Please sign in to comment.