trying to port web app starter from PHP

This commit is contained in:
udo
2026-04-19 09:38:23 +00:00
parent 46d98a092f
commit be514d63d6
546 changed files with 76910 additions and 2807 deletions
@@ -0,0 +1,25 @@
<?php return [
'render' => function($prop) {
include_css('themes/common/css/workspace.css');
include_js('js/u-workspace-shell.js');
$id = trim((string)($prop['id'] ?? ''));
$class = trim((string)($prop['class'] ?? ''));
$sidebar = (string)($prop['sidebar_html'] ?? '');
$main = (string)($prop['main_html'] ?? '');
$overlayId = trim((string)($prop['overlay_id'] ?? ''));
ob_start();
?>
<div<?= $id !== '' ? ' id="' . asafe($id) . '"' : '' ?> class="ws-app<?= $class !== '' ? ' ' . asafe($class) : '' ?>">
<?= $sidebar ?>
<div<?= $overlayId !== '' ? ' id="' . asafe($overlayId) . '"' : '' ?> class="ws-sidebar-overlay"></div>
<main class="ws-main">
<?= $main ?>
</main>
</div>
<?php
return ob_get_clean();
},
'about' => 'Generic workspace app shell with sidebar, overlay, and main content area',
];
@@ -0,0 +1,22 @@
<?php return [
'render' => function($prop) {
$id = trim((string)($prop['id'] ?? ''));
$class = trim((string)($prop['class'] ?? ''));
$icon = trim((string)($prop['icon_class'] ?? 'fas fa-layer-group'));
$title = (string)($prop['title'] ?? '');
$text = (string)($prop['text'] ?? '');
$actionHtml = (string)($prop['action_html'] ?? '');
ob_start();
?>
<div<?= $id !== '' ? ' id="' . asafe($id) . '"' : '' ?> class="ws-empty-state<?= $class !== '' ? ' ' . asafe($class) : '' ?>">
<div class="ws-empty-icon"><i class="<?= asafe($icon) ?>"></i></div>
<h2><?= safe($title) ?></h2>
<p><?= safe($text) ?></p>
<?= $actionHtml ?>
</div>
<?php
return ob_get_clean();
},
'about' => 'Centered empty-state block for shell panels and placeholder screens',
];
@@ -0,0 +1,21 @@
<?php return [
'render' => function($prop) {
$tag = trim((string)($prop['tag'] ?? 'button'));
if (!in_array($tag, ['button', 'span', 'a'], true)) $tag = 'button';
$id = trim((string)($prop['id'] ?? ''));
$class = trim((string)($prop['class'] ?? ''));
$title = trim((string)($prop['title'] ?? ''));
$icon = trim((string)($prop['icon_class'] ?? ''));
$text = (string)($prop['text'] ?? '');
$attrs = trim((string)($prop['attrs'] ?? ''));
$href = trim((string)($prop['href'] ?? ''));
$type = trim((string)($prop['type'] ?? 'button'));
ob_start();
?>
<<?= $tag ?><?= $id !== '' ? ' id="' . asafe($id) . '"' : '' ?> class="ws-icon-btn<?= $class !== '' ? ' ' . asafe($class) : '' ?>"<?= $title !== '' ? ' title="' . asafe($title) . '"' : '' ?><?= $tag === 'button' ? ' type="' . asafe($type) . '"' : '' ?><?= $tag === 'a' && $href !== '' ? ' href="' . asafe($href) . '"' : '' ?><?= $attrs !== '' ? ' ' . $attrs : '' ?>><?php if ($icon !== ''): ?><i class="<?= asafe($icon) ?>"></i><?php endif; ?><?php if ($text !== ''): ?><span><?= safe($text) ?></span><?php endif; ?></<?= $tag ?>>
<?php
return ob_get_clean();
},
'about' => 'Small utility icon button for shell toolbars and compact actions',
];
@@ -0,0 +1,15 @@
<?php return [
'render' => function($prop) {
$id = trim((string)($prop['id'] ?? ''));
$class = trim((string)($prop['class'] ?? ''));
$icon = trim((string)($prop['icon_class'] ?? ''));
$text = (string)($prop['text'] ?? '');
ob_start();
?>
<div<?= $id !== '' ? ' id="' . asafe($id) . '"' : '' ?> class="ws-list-state<?= $class !== '' ? ' ' . asafe($class) : '' ?>"><?php if ($icon !== ''): ?><i class="<?= asafe($icon) ?>"></i><?php endif; ?><span><?= safe($text) ?></span></div>
<?php
return ob_get_clean();
},
'about' => 'Compact sidebar/list placeholder state with optional icon',
];
@@ -0,0 +1,24 @@
<?php return [
'render' => function($prop) {
$id = trim((string)($prop['id'] ?? ''));
$class = trim((string)($prop['class'] ?? ''));
$buttonId = trim((string)($prop['button_id'] ?? ''));
$buttonClass = trim((string)($prop['button_class'] ?? ''));
$titleId = trim((string)($prop['title_id'] ?? ''));
$titleClass = trim((string)($prop['title_class'] ?? ''));
$title = (string)($prop['title'] ?? '');
$icon = trim((string)($prop['icon_class'] ?? 'fas fa-bars'));
ob_start();
?>
<div<?= $id !== '' ? ' id="' . asafe($id) . '"' : '' ?> class="ws-mobile-bar<?= $class !== '' ? ' ' . asafe($class) : '' ?>">
<button<?= $buttonId !== '' ? ' id="' . asafe($buttonId) . '"' : '' ?> class="ws-mobile-toggle<?= $buttonClass !== '' ? ' ' . asafe($buttonClass) : '' ?>" title="Toggle sidebar" type="button">
<i class="<?= asafe($icon) ?>"></i>
</button>
<span<?= $titleId !== '' ? ' id="' . asafe($titleId) . '"' : '' ?> class="ws-mobile-title<?= $titleClass !== '' ? ' ' . asafe($titleClass) : '' ?>"><?= safe($title) ?></span>
</div>
<?php
return ob_get_clean();
},
'about' => 'Compact mobile header bar for workspace layouts with a sidebar toggle',
];
@@ -0,0 +1,25 @@
<?php return [
'render' => function($prop) {
$class = trim((string)($prop['class'] ?? ''));
$title = (string)($prop['title'] ?? '');
$subtitle = (string)($prop['subtitle'] ?? '');
$titleId = trim((string)($prop['title_id'] ?? ''));
$subtitleId = trim((string)($prop['subtitle_id'] ?? ''));
$actionsHtml = (string)($prop['actions_html'] ?? '');
ob_start();
?>
<div class="ws-panel-header<?= $class !== '' ? ' ' . asafe($class) : '' ?>">
<div class="ws-panel-title-group">
<h2<?= $titleId !== '' ? ' id="' . asafe($titleId) . '"' : '' ?>><?= safe($title) ?></h2>
<?php if ($subtitle !== ''): ?>
<p<?= $subtitleId !== '' ? ' id="' . asafe($subtitleId) . '"' : '' ?> class="ws-subtitle"><?= safe($subtitle) ?></p>
<?php endif; ?>
</div>
<?php if ($actionsHtml !== ''): ?><div class="ws-header-actions"><?= $actionsHtml ?></div><?php endif; ?>
</div>
<?php
return ob_get_clean();
},
'about' => 'Panel heading with title, optional subtitle, and actions slot',
];
@@ -0,0 +1,19 @@
<?php return [
'render' => function($prop) {
$id = trim((string)($prop['id'] ?? ''));
$class = trim((string)($prop['class'] ?? ''));
$attrs = trim((string)($prop['attrs'] ?? ''));
$header = (string)($prop['header_html'] ?? '');
$body = (string)($prop['body_html'] ?? '');
ob_start();
?>
<section<?= $id !== '' ? ' id="' . asafe($id) . '"' : '' ?> class="ws-panel<?= $class !== '' ? ' ' . asafe($class) : '' ?>"<?= $attrs !== '' ? ' ' . $attrs : '' ?>>
<?= $header ?>
<?= $body ?>
</section>
<?php
return ob_get_clean();
},
'about' => 'Flexible workspace panel container with separate header and body slots',
];
@@ -0,0 +1,17 @@
<?php return [
'render' => function($prop) {
$class = trim((string)($prop['class'] ?? ''));
$title = (string)($prop['title'] ?? '');
$actionsHtml = (string)($prop['actions_html'] ?? '');
ob_start();
?>
<div class="ws-section-head<?= $class !== '' ? ' ' . asafe($class) : '' ?>">
<h3><?= safe($title) ?></h3>
<?php if ($actionsHtml !== ''): ?><div class="ws-header-actions"><?= $actionsHtml ?></div><?php endif; ?>
</div>
<?php
return ob_get_clean();
},
'about' => 'Compact section heading for grouped workspace content',
];
@@ -0,0 +1,19 @@
<?php return [
'render' => function($prop) {
$id = trim((string)($prop['id'] ?? ''));
$class = trim((string)($prop['class'] ?? ''));
$attrs = trim((string)($prop['attrs'] ?? ''));
$header = (string)($prop['header_html'] ?? '');
$body = (string)($prop['body_html'] ?? '');
ob_start();
?>
<section<?= $id !== '' ? ' id="' . asafe($id) . '"' : '' ?> class="ws-section<?= $class !== '' ? ' ' . asafe($class) : '' ?>"<?= $attrs !== '' ? ' ' . $attrs : '' ?>>
<?= $header ?>
<?= $body ?>
</section>
<?php
return ob_get_clean();
},
'about' => 'Stacked workspace section wrapper for grouped content blocks',
];
@@ -0,0 +1,18 @@
<?php return [
'render' => function($prop) {
$id = trim((string)($prop['id'] ?? ''));
$class = trim((string)($prop['class'] ?? ''));
$top = (string)($prop['top_html'] ?? '');
$body = (string)($prop['body_html'] ?? '');
ob_start();
?>
<aside<?= $id !== '' ? ' id="' . asafe($id) . '"' : '' ?> class="ws-sidebar<?= $class !== '' ? ' ' . asafe($class) : '' ?>">
<?= $top ?>
<?= $body ?>
</aside>
<?php
return ob_get_clean();
},
'about' => 'Generic workspace sidebar wrapper with separate top and body slots',
];
@@ -0,0 +1,26 @@
<?php return [
'render' => function($prop) {
$id = trim((string)($prop['id'] ?? ''));
$class = trim((string)($prop['class'] ?? ''));
$actionHtml = (string)($prop['action_html'] ?? '');
$searchId = trim((string)($prop['search_id'] ?? ''));
$searchClass = trim((string)($prop['search_class'] ?? ''));
$searchInputId = trim((string)($prop['search_input_id'] ?? ''));
$searchInputName = trim((string)($prop['search_input_name'] ?? 'search'));
$searchInputClass = trim((string)($prop['search_input_class'] ?? ''));
$searchPlaceholder = (string)($prop['search_placeholder'] ?? 'Search...');
ob_start();
?>
<div<?= $id !== '' ? ' id="' . asafe($id) . '"' : '' ?> class="ws-sidebar-top<?= $class !== '' ? ' ' . asafe($class) : '' ?>">
<?= $actionHtml ?>
<div<?= $searchId !== '' ? ' id="' . asafe($searchId) . '"' : '' ?> class="ws-search-wrap<?= $searchClass !== '' ? ' ' . asafe($searchClass) : '' ?>">
<i class="fas fa-search ws-search-icon"></i>
<input type="search"<?= $searchInputId !== '' ? ' id="' . asafe($searchInputId) . '"' : '' ?> name="<?= asafe($searchInputName) ?>" class="ws-search-input<?= $searchInputClass !== '' ? ' ' . asafe($searchInputClass) : '' ?>" placeholder="<?= asafe($searchPlaceholder) ?>" autocomplete="off">
</div>
</div>
<?php
return ob_get_clean();
},
'about' => 'Sidebar toolbar with optional action area and compact search field',
];
@@ -0,0 +1,17 @@
<?php return [
'render' => function($prop) {
$id = trim((string)($prop['id'] ?? ''));
$class = trim((string)($prop['class'] ?? ''));
$label = trim((string)($prop['label'] ?? $prop['text'] ?? ''));
$variant = preg_replace('/[^a-z0-9_-]/i', '', strtolower(trim((string)($prop['variant'] ?? 'neutral'))));
if ($variant === '') $variant = 'neutral';
$title = trim((string)($prop['title'] ?? ''));
ob_start();
?>
<span<?= $id !== '' ? ' id="' . asafe($id) . '"' : '' ?> class="ws-status-pill ws-status-pill-<?= asafe($variant) ?><?= $class !== '' ? ' ' . asafe($class) : '' ?>"<?= $title !== '' ? ' title="' . asafe($title) . '"' : '' ?>><?= safe($label) ?></span>
<?php
return ob_get_clean();
},
'about' => 'Compact semantic status badge for neutral, info, success, warning, and danger states',
];