Skip to content

Commit

Permalink
feat: add support for nested components
Browse files Browse the repository at this point in the history
  • Loading branch information
mychidarko committed Feb 11, 2023
1 parent 2b19524 commit 215751f
Showing 1 changed file with 52 additions and 14 deletions.
66 changes: 52 additions & 14 deletions src/UI/Core.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,28 @@ public static function init(): string
/**
* Render a Leaf UI
*
* @param Component|callable $component The Leaf UI component to render
* @param Component $component The Leaf UI component to render
*/
public static function render($component)
{
$componentData = static::buildComponent($component);

if ($componentData['responseType'] === 'json') {
unset($componentData['responseType']);
(new \Leaf\Http\Response)->json($componentData);
} else {
(new \Leaf\Http\Response)->markup($componentData['html']);
}
}

/**
* Process a Leaf UI component and return the HTML
*
* @param Component $name The name of the component
* @param bool $withoutScripts Whether to return the HTML without scripts
* @param callable $callback The callback to run when the component is rendered
*/
protected static function buildComponent(Component $component, bool $withoutScripts = false)
{
$data = json_decode((new \Leaf\Http\Request())->get('_leaf_ui_config', false) ?? '', true);

Expand All @@ -53,14 +72,16 @@ public static function render($component)
$state[$key] = $component->{$key};
}

return (new \Leaf\Http\Response)->json([
'html' => str_replace('</body>', Core::init() . '</body>', static::compileTemplate($component->render(), $state)),
return [
'responseType' => 'json',
'html' => $withoutScripts ? static::compileTemplate($component->render(), $state) : str_replace('</body>', Core::init() . '</body>', static::compileTemplate($component->render(), $state)),
'state' => $state,
]);
];
}

(new \Leaf\Http\Response)
->markup(str_replace('</body>', Core::createElement('script', [], ['
return [
'responseType' => 'html',
'html' => $withoutScripts ? static::compileTemplate($component->render(), get_class_vars($component::class)) : str_replace('</body>', Core::createElement('script', [], ['
window._leafUIConfig = {
el: document.querySelector("body"),
component: "' . $component::class . '",
Expand All @@ -69,7 +90,9 @@ public static function render($component)
path: "' . $_SERVER['REQUEST_URI'] . '",
requestMethod: "' . $_SERVER['REQUEST_METHOD'] . '",
};
']) . Core::init() . '</body>', static::compileTemplate($component->render(), get_class_vars($component::class))));
']) . Core::init() . '</body>', static::compileTemplate($component->render(), get_class_vars($component::class))),
'state' => json_encode(array_merge(static::$state, get_class_vars($component::class))),
];
}

/**
Expand Down Expand Up @@ -173,7 +196,7 @@ public static function compileTemplate(string $rawText, array $state = []): stri
}, $compiled);

$compiled = preg_replace_callback('/@component\((.*?)\)/', function ($matches) {
return Core::component($matches[1])['html'];
return Core::component($matches[1]);
}, $compiled);

return $compiled;
Expand All @@ -183,20 +206,35 @@ public static function compileTemplate(string $rawText, array $state = []): stri
* Embed a component into a view
*
* @param string $component The component to embed
* @return array
* @return string
*/
public static function component(string $component)
public static function component(string $component, $state = []): string
{
$component = trim($component, '"\'\`');

if (!class_exists($component)) {
trigger_error($component . ' does not exist', E_USER_ERROR);
}

return [
'html' => 'This is a component',
'state' => [],
];
$componentPayload = json_encode([
'type' => 'component',
'payload' => [
'params' => [],
'method' => null,
'methodArgs' => [],
'component' => $component,
'data' => $state ?? static::$state ?? [],
],
]);

$originalURI = $_SERVER['REQUEST_URI'];
$_SERVER['REQUEST_URI'] = "$originalURI?_leaf_ui_config=$componentPayload";

$componentData = static::buildComponent(new $component, true);

$_SERVER['REQUEST_URI'] = $originalURI;

return $componentData['html'];
}

/**
Expand Down

0 comments on commit 215751f

Please sign in to comment.