prisma-php 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/01-getting-started/authentication.md +280 -0
- package/dist/docs/01-getting-started/caching.md +346 -0
- package/dist/docs/01-getting-started/components.md +589 -0
- package/dist/docs/01-getting-started/error-handling.md +359 -0
- package/dist/docs/01-getting-started/fetching-data.md +637 -0
- package/dist/docs/01-getting-started/file-manager.md +307 -0
- package/dist/docs/01-getting-started/index.md +142 -0
- package/dist/docs/01-getting-started/installation.md +18 -0
- package/dist/docs/01-getting-started/layouts-and-pages.md +289 -0
- package/dist/docs/01-getting-started/metadata-and-og-images.md +228 -0
- package/dist/docs/01-getting-started/prisma-php-orm.md +374 -0
- package/dist/docs/01-getting-started/project-structure.md +328 -0
- package/dist/docs/01-getting-started/pulsepoint.md +434 -0
- package/dist/docs/01-getting-started/route-handlers.md +344 -0
- package/dist/docs/01-getting-started/upgrading.md +172 -0
- package/dist/docs/index.md +243 -0
- package/package.json +16 -0
|
@@ -0,0 +1,589 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Prisma PHP Components for AI Awareness
|
|
3
|
+
description: Learn how AI agents should understand, locate, import, and generate Prisma PHP components using the official PHPX and ImportComponent patterns.
|
|
4
|
+
related:
|
|
5
|
+
title: Related docs
|
|
6
|
+
description: Read the official Prisma PHP component docs before generating or editing components.
|
|
7
|
+
links:
|
|
8
|
+
- /docs/get-started-phpx
|
|
9
|
+
- /docs/import-component
|
|
10
|
+
- /docs/fragment
|
|
11
|
+
- /docs/icon-component
|
|
12
|
+
- /docs/button-component
|
|
13
|
+
- /docs/accordion-component
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
Prisma PHP components should be generated using the official **PHPX** and **ImportComponent** models, not assumptions from React, Vue, Blade components, or generic PHP templating.
|
|
17
|
+
|
|
18
|
+
If a task involves component creation, component editing, component composition, PHPX rendering rules, or importing PHP partials as PulsePoint-ready islands, AI agents should read the relevant local Prisma PHP docs first and use the installed framework conventions before generating code.
|
|
19
|
+
|
|
20
|
+
## AI rule: read the component docs first
|
|
21
|
+
|
|
22
|
+
Before generating, editing, or reviewing components, use this order:
|
|
23
|
+
|
|
24
|
+
1. Read `./prisma-php.json`.
|
|
25
|
+
2. Read the installed local docs in `node_modules/prisma-php/dist/docs`.
|
|
26
|
+
3. Inspect the existing local component structure.
|
|
27
|
+
4. Inspect Prisma PHP core internals only when the docs do not answer the task.
|
|
28
|
+
|
|
29
|
+
Do not assume JSX, TSX, Blade, Vue SFC, React, or generic PHP partial behavior applies directly.
|
|
30
|
+
|
|
31
|
+
## Read this doc when you need
|
|
32
|
+
|
|
33
|
+
- **PHPX component basics, naming, file placement, props, children, or reactive props** → `get-started-phpx`
|
|
34
|
+
- **importing a PHP partial as a component, component islands, `ImportComponent::render(...)`, or server-first PulsePoint boundaries** → `import-component`
|
|
35
|
+
- **multiple sibling nodes, wrapperless output, or `<>...</>` usage** → `fragment`
|
|
36
|
+
- **custom SVG icon components** → `icon-component`
|
|
37
|
+
- **button component structure, variants, sizes, or theme-aware classes** → `button-component`
|
|
38
|
+
- **accordion components, grouped sub-components, `StateManager`, or injected JS lifecycle rules** → `accordion-component`
|
|
39
|
+
|
|
40
|
+
## Two component models AI must not confuse
|
|
41
|
+
|
|
42
|
+
Prisma PHP has **two related but different component models**.
|
|
43
|
+
|
|
44
|
+
### 1. PHPX class-based components
|
|
45
|
+
|
|
46
|
+
Use this model when building reusable PHP component classes such as:
|
|
47
|
+
|
|
48
|
+
- `Button`
|
|
49
|
+
- `Accordion`
|
|
50
|
+
- `Search`
|
|
51
|
+
- `Card`
|
|
52
|
+
- `Icon`
|
|
53
|
+
|
|
54
|
+
These components:
|
|
55
|
+
|
|
56
|
+
- extend the PHPX base class
|
|
57
|
+
- usually live in a component namespace such as `src/app/Lib/Components`
|
|
58
|
+
- render HTML from `render(): string`
|
|
59
|
+
- use class-based props and helpers such as `$this->children`, `$this->class`, and `$this->getAttributes(...)`
|
|
60
|
+
|
|
61
|
+
### 2. `ImportComponent` partial-based components
|
|
62
|
+
|
|
63
|
+
Use this model when a plain PHP file or partial should become a **real PulsePoint component boundary**.
|
|
64
|
+
|
|
65
|
+
This is the right mental model for:
|
|
66
|
+
|
|
67
|
+
- server-first pages with small reactive islands
|
|
68
|
+
- imported PHP partials that must receive props as HTML attributes
|
|
69
|
+
- componentized partials that PulsePoint should hydrate later
|
|
70
|
+
- keeping PHP templating ergonomics while still producing component-aware markup
|
|
71
|
+
|
|
72
|
+
AI must not collapse these two models into one.
|
|
73
|
+
|
|
74
|
+
- **PHPX** is for class-based component authoring.
|
|
75
|
+
- **`ImportComponent`** is for importing PHP partial files as single-root component islands.
|
|
76
|
+
|
|
77
|
+
## Important AI rules for Prisma PHP components
|
|
78
|
+
|
|
79
|
+
- treat the official Prisma PHP component docs as the source of truth
|
|
80
|
+
- use **PHPX** for class-based reusable components
|
|
81
|
+
- use **`ImportComponent`** when a PHP partial should become a PulsePoint-ready component boundary
|
|
82
|
+
- keep file names and class names aligned for PHPX class components
|
|
83
|
+
- prefer the documented component directories and naming patterns
|
|
84
|
+
- do not invent undocumented lifecycle hooks, props APIs, or import behavior
|
|
85
|
+
- preserve Prisma PHP XML-style markup rules when returning component markup
|
|
86
|
+
- use `$this->children`, `$this->props`, `$this->class`, and `$this->getAttributes(...)` following the documented PHPX pattern
|
|
87
|
+
- when a component needs reactivity, distinguish between static PHP props and reactive PulsePoint props
|
|
88
|
+
- when a component requires grouped sub-components, follow the documented same-file naming pattern like `Accordion`, `AccordionItem`, `AccordionTrigger`, and `AccordionContent`
|
|
89
|
+
- when using `ImportComponent`, always ensure the imported file renders **exactly one root element**
|
|
90
|
+
|
|
91
|
+
## Component file placement and naming
|
|
92
|
+
|
|
93
|
+
The official PHPX docs describe a file and naming convention centered on class-based components.
|
|
94
|
+
|
|
95
|
+
A standard component should usually live in a component-oriented path such as:
|
|
96
|
+
|
|
97
|
+
```txt
|
|
98
|
+
src/app/Lib/Components/Button.php
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The class name should match the file name.
|
|
102
|
+
|
|
103
|
+
Examples:
|
|
104
|
+
|
|
105
|
+
- `Button.php` → `class Button`
|
|
106
|
+
- `Search.php` → `class Search`
|
|
107
|
+
- `Accordion.php` → `class Accordion`
|
|
108
|
+
|
|
109
|
+
### Related component naming
|
|
110
|
+
|
|
111
|
+
When a component is made of multiple related sub-components, the official docs recommend keeping them grouped under the same naming family.
|
|
112
|
+
|
|
113
|
+
Example naming group:
|
|
114
|
+
|
|
115
|
+
- `Accordion`
|
|
116
|
+
- `AccordionItem`
|
|
117
|
+
- `AccordionTrigger`
|
|
118
|
+
- `AccordionContent`
|
|
119
|
+
|
|
120
|
+
These related classes can live in the same file, and each class name should begin with the shared main component prefix.
|
|
121
|
+
|
|
122
|
+
Example path:
|
|
123
|
+
|
|
124
|
+
```txt
|
|
125
|
+
src/app/Lib/PHPX/Components/Accordion.php
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Imported partial component paths
|
|
129
|
+
|
|
130
|
+
For `ImportComponent`, the input is a **PHP file path**, not a PHPX class reference.
|
|
131
|
+
|
|
132
|
+
Common examples:
|
|
133
|
+
|
|
134
|
+
```txt
|
|
135
|
+
APP_PATH . '/inc/Hero.php'
|
|
136
|
+
APP_PATH . '/inc/SearchBox.php'
|
|
137
|
+
APP_PATH . '/components/UserCard.php'
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
AI should preserve the project's actual partial locations instead of inventing a new component folder structure when the task is specifically about imported partials.
|
|
141
|
+
|
|
142
|
+
## Base PHPX component shape
|
|
143
|
+
|
|
144
|
+
A Prisma PHPX component should generally:
|
|
145
|
+
|
|
146
|
+
1. extend the PHPX base class
|
|
147
|
+
2. accept `array $props = []` in the constructor
|
|
148
|
+
3. call `parent::__construct($props)`
|
|
149
|
+
4. render a string from `render(): string`
|
|
150
|
+
5. use helper methods such as `getMergeClasses(...)` and `getAttributes(...)` when appropriate
|
|
151
|
+
|
|
152
|
+
Typical shape:
|
|
153
|
+
|
|
154
|
+
```php
|
|
155
|
+
<?php
|
|
156
|
+
|
|
157
|
+
namespace Lib\Components;
|
|
158
|
+
|
|
159
|
+
use Lib\PHPX\PHPX;
|
|
160
|
+
|
|
161
|
+
class ClassName extends PHPX
|
|
162
|
+
{
|
|
163
|
+
public ?string $class = '';
|
|
164
|
+
public mixed $children = null;
|
|
165
|
+
|
|
166
|
+
public function __construct(array $props = [])
|
|
167
|
+
{
|
|
168
|
+
parent::__construct($props);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
public function render(): string
|
|
172
|
+
{
|
|
173
|
+
$class = $this->getMergeClasses($this->class);
|
|
174
|
+
$attributes = $this->getAttributes([
|
|
175
|
+
'class' => $class,
|
|
176
|
+
]);
|
|
177
|
+
|
|
178
|
+
return <<<HTML
|
|
179
|
+
<div {$attributes}>
|
|
180
|
+
{$this->children}
|
|
181
|
+
</div>
|
|
182
|
+
HTML;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Core PHPX props model
|
|
188
|
+
|
|
189
|
+
The official PHPX docs describe these important component properties:
|
|
190
|
+
|
|
191
|
+
- `$props` → all incoming props and attributes
|
|
192
|
+
- `$children` → inner rendered content
|
|
193
|
+
- `$class` → CSS class input for styling
|
|
194
|
+
- `$attributesArray` → HTML attributes prepared for rendering
|
|
195
|
+
|
|
196
|
+
AI should not invent alternative prop containers when the PHPX base model already provides these.
|
|
197
|
+
|
|
198
|
+
## Static props vs reactive props
|
|
199
|
+
|
|
200
|
+
Prisma PHP components separate normal server-side props from reactive PulsePoint props.
|
|
201
|
+
|
|
202
|
+
### Static props
|
|
203
|
+
|
|
204
|
+
Static props are plain PHP values and should be treated as normal typed component inputs.
|
|
205
|
+
|
|
206
|
+
Examples:
|
|
207
|
+
|
|
208
|
+
```xml
|
|
209
|
+
<Button type="submit" class="w-full" />
|
|
210
|
+
<TestComponent isChildren="true" />
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Reactive props
|
|
214
|
+
|
|
215
|
+
Reactive PulsePoint props must use mustache syntax.
|
|
216
|
+
|
|
217
|
+
Examples:
|
|
218
|
+
|
|
219
|
+
```xml
|
|
220
|
+
<TestComponent counter="{count}" setCounter="{setCount}" />
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### AI rule for reactive props
|
|
224
|
+
|
|
225
|
+
- use normal quoted props for static PHP values
|
|
226
|
+
- use mustache syntax for PulsePoint signals and client-reactive values
|
|
227
|
+
- do not mix the two models casually
|
|
228
|
+
- when a child component must receive browser-side state, pass it in mustache form
|
|
229
|
+
|
|
230
|
+
## `ImportComponent` rules
|
|
231
|
+
|
|
232
|
+
The official `ImportComponent` docs describe it as the utility that turns a PHP partial into a real PulsePoint component boundary.
|
|
233
|
+
|
|
234
|
+
### What `ImportComponent` does
|
|
235
|
+
|
|
236
|
+
When you call:
|
|
237
|
+
|
|
238
|
+
```php
|
|
239
|
+
ImportComponent::render($filePath, $props);
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Prisma PHP:
|
|
243
|
+
|
|
244
|
+
1. executes the component file in an isolated namespace
|
|
245
|
+
2. captures the produced HTML output
|
|
246
|
+
3. parses it as an XML fragment
|
|
247
|
+
4. enforces exactly one root element
|
|
248
|
+
5. injects a stable `pp-component` attribute
|
|
249
|
+
6. serializes props into HTML attributes on the root element
|
|
250
|
+
7. stores a snapshot accessible through `ImportComponent::sections()`
|
|
251
|
+
|
|
252
|
+
### AI rules for `ImportComponent`
|
|
253
|
+
|
|
254
|
+
- use `ImportComponent` for PHP partials, not for PHPX class components
|
|
255
|
+
- require exactly one root element in the imported file
|
|
256
|
+
- treat the imported output as a PulsePoint-ready island boundary
|
|
257
|
+
- pass server data as props and let Prisma PHP serialize them into attributes
|
|
258
|
+
- use mustache-valued props when passing reactive PulsePoint bindings into imported partials
|
|
259
|
+
- do not assume multiple top-level siblings are allowed
|
|
260
|
+
- do not manually inject `pp-component`; let `ImportComponent` do it
|
|
261
|
+
|
|
262
|
+
### Basic usage
|
|
263
|
+
|
|
264
|
+
```php
|
|
265
|
+
<?php
|
|
266
|
+
|
|
267
|
+
use PP\ImportComponent;
|
|
268
|
+
|
|
269
|
+
ImportComponent::render(APP_PATH . '/inc/Hero.php');
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Passing props
|
|
273
|
+
|
|
274
|
+
```php
|
|
275
|
+
<?php
|
|
276
|
+
|
|
277
|
+
use PP\ImportComponent;
|
|
278
|
+
|
|
279
|
+
$user = ['id' => 7, 'name' => 'Jefferson'];
|
|
280
|
+
|
|
281
|
+
ImportComponent::render(APP_PATH . '/inc/UserCard.php', [
|
|
282
|
+
'user' => $user,
|
|
283
|
+
'variant' => 'compact',
|
|
284
|
+
'isOnline' => true,
|
|
285
|
+
]);
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Reactive PulsePoint bindings
|
|
289
|
+
|
|
290
|
+
```php
|
|
291
|
+
<?php
|
|
292
|
+
|
|
293
|
+
use PP\ImportComponent;
|
|
294
|
+
?>
|
|
295
|
+
|
|
296
|
+
<div class="space-y-4">
|
|
297
|
+
<?php ImportComponent::render(APP_PATH . '/inc/SearchBox.php', [
|
|
298
|
+
'query' => '{query}',
|
|
299
|
+
'setQuery' => '{setQuery}',
|
|
300
|
+
]); ?>
|
|
301
|
+
|
|
302
|
+
<script type="text/pp">
|
|
303
|
+
const [query, setQuery] = pp.state('');
|
|
304
|
+
</script>
|
|
305
|
+
</div>
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Imported file requirements
|
|
309
|
+
|
|
310
|
+
The imported PHP file must output **exactly one root element**.
|
|
311
|
+
|
|
312
|
+
Correct:
|
|
313
|
+
|
|
314
|
+
```php
|
|
315
|
+
<div class="rounded-lg border bg-card p-4">
|
|
316
|
+
<h2 class="font-medium">Search</h2>
|
|
317
|
+
<input value="{query}" oninput="{(e) => setQuery(e.target.value)}" />
|
|
318
|
+
</div>
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
Incorrect:
|
|
322
|
+
|
|
323
|
+
```php
|
|
324
|
+
<h2 class="font-medium">Search</h2>
|
|
325
|
+
<input value="{query}" oninput="{(e) => setQuery(e.target.value)}" />
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
## `ImportComponent` prop serialization rules
|
|
329
|
+
|
|
330
|
+
The official docs define these serialization rules:
|
|
331
|
+
|
|
332
|
+
- `null` props are skipped
|
|
333
|
+
- booleans become `"true"` or `"false"`
|
|
334
|
+
- scalar values become strings
|
|
335
|
+
- arrays and objects become JSON
|
|
336
|
+
- when a prop value contains PulsePoint mustache syntax like `{count}`, Prisma PHP converts camelCase prop keys to kebab-case attribute names when needed for HTML-safe output
|
|
337
|
+
|
|
338
|
+
### AI implications
|
|
339
|
+
|
|
340
|
+
- pass normal PHP arrays and objects directly; do not pre-JSON-encode them manually unless the project already does that intentionally
|
|
341
|
+
- expect reactive props like `setCount` to become an HTML attribute such as `set-count` when the value contains mustache syntax
|
|
342
|
+
- do not rely on camelCase HTML attributes surviving unchanged in mustache-driven import cases
|
|
343
|
+
|
|
344
|
+
## Exposed functions inside imported components
|
|
345
|
+
|
|
346
|
+
The official `ImportComponent` docs also note an automatic exposed-function registry behavior during isolated execution.
|
|
347
|
+
|
|
348
|
+
That means an imported component file can define an exposed PHP function, and Prisma PHP can register it for later use through the exposed-function tooling.
|
|
349
|
+
|
|
350
|
+
Example:
|
|
351
|
+
|
|
352
|
+
```php
|
|
353
|
+
<?php
|
|
354
|
+
|
|
355
|
+
use PP\Attributes\Exposed;
|
|
356
|
+
|
|
357
|
+
#[Exposed]
|
|
358
|
+
function saveDraft(array $payload): array
|
|
359
|
+
{
|
|
360
|
+
return ['ok' => true];
|
|
361
|
+
}
|
|
362
|
+
?>
|
|
363
|
+
|
|
364
|
+
<div class="rounded-md border p-4">
|
|
365
|
+
Draft editor
|
|
366
|
+
</div>
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### AI rule
|
|
370
|
+
|
|
371
|
+
If a component file imported via `ImportComponent` defines `#[Exposed]` functions, do not move them out just because they are inside the imported file. Preserve the documented pattern unless the user explicitly wants a different structure.
|
|
372
|
+
|
|
373
|
+
## Fragment rules
|
|
374
|
+
|
|
375
|
+
The official `Fragment` component exists so PHPX components can return multiple sibling elements in heredoc output without forcing an unnecessary wrapper element.
|
|
376
|
+
|
|
377
|
+
Use `<Fragment>` or the shorthand fragment syntax:
|
|
378
|
+
|
|
379
|
+
```php
|
|
380
|
+
return <<<HTML
|
|
381
|
+
<>
|
|
382
|
+
<h1 class="text-2xl font-bold">Heading</h1>
|
|
383
|
+
<p class="text-muted-foreground">Paragraph</p>
|
|
384
|
+
</>
|
|
385
|
+
HTML;
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### When to use `Fragment`
|
|
389
|
+
|
|
390
|
+
Use it when:
|
|
391
|
+
|
|
392
|
+
- a PHPX component must return multiple siblings
|
|
393
|
+
- you want to avoid an unnecessary wrapper `div`
|
|
394
|
+
- semantic HTML would be harmed by adding an extra wrapper
|
|
395
|
+
- you are using heredoc output and PHPX still needs a single parseable root structure
|
|
396
|
+
|
|
397
|
+
### Important distinction
|
|
398
|
+
|
|
399
|
+
`Fragment` is a **PHPX rendering tool**.
|
|
400
|
+
|
|
401
|
+
It is **not** the same as `ImportComponent`'s single-root partial rule.
|
|
402
|
+
|
|
403
|
+
- in **PHPX**, `Fragment` is how multiple siblings can be represented
|
|
404
|
+
- in **`ImportComponent`**, the imported partial itself must still resolve to exactly one root element
|
|
405
|
+
|
|
406
|
+
AI should not misuse fragment concepts to bypass the `ImportComponent` single-root requirement.
|
|
407
|
+
|
|
408
|
+
## Icon component rules
|
|
409
|
+
|
|
410
|
+
The official icon component docs recommend SVG as the preferred format for custom icon components because SVG is lightweight, vector-based, and easy to style with utility classes.
|
|
411
|
+
|
|
412
|
+
A manual icon component follows the normal PHPX class pattern.
|
|
413
|
+
|
|
414
|
+
Typical structure:
|
|
415
|
+
|
|
416
|
+
```php
|
|
417
|
+
<?php
|
|
418
|
+
|
|
419
|
+
namespace Lib\GoogleIcons;
|
|
420
|
+
|
|
421
|
+
use PP\PHPX\PHPX;
|
|
422
|
+
|
|
423
|
+
class Search extends PHPX
|
|
424
|
+
{
|
|
425
|
+
public ?string $class = '';
|
|
426
|
+
|
|
427
|
+
public function __construct(array $props = [])
|
|
428
|
+
{
|
|
429
|
+
parent::__construct($props);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
public function render(): string
|
|
433
|
+
{
|
|
434
|
+
$class = $this->getMergeClasses($this->class);
|
|
435
|
+
$attributes = $this->getAttributes([
|
|
436
|
+
'class' => $class,
|
|
437
|
+
]);
|
|
438
|
+
|
|
439
|
+
return <<<HTML
|
|
440
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" {$attributes}>
|
|
441
|
+
<path d="..." />
|
|
442
|
+
</svg>
|
|
443
|
+
HTML;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### AI rules for icon components
|
|
449
|
+
|
|
450
|
+
- prefer SVG over raster formats when creating reusable icons
|
|
451
|
+
- expose `class` so the icon can be styled from the caller
|
|
452
|
+
- use `fill="currentColor"` when the icon should follow text color
|
|
453
|
+
- keep the component small and focused on rendering the SVG
|
|
454
|
+
- do not hardcode visual styling when utility classes can control it
|
|
455
|
+
|
|
456
|
+
## Button component rules
|
|
457
|
+
|
|
458
|
+
The official Button component docs present Button as a reusable PHPX component with:
|
|
459
|
+
|
|
460
|
+
- variants
|
|
461
|
+
- sizes
|
|
462
|
+
- theme-aware utility classes
|
|
463
|
+
- support for normal button rendering and anchor-style rendering
|
|
464
|
+
|
|
465
|
+
### AI rules for button components
|
|
466
|
+
|
|
467
|
+
- place button components in a standard component path such as `src/app/Lib/Components/Button.php`
|
|
468
|
+
- extend the PHPX base class
|
|
469
|
+
- use props like `variant` and `size` from `$this->props`
|
|
470
|
+
- compute classes centrally in a helper such as `getComputedClasses()`
|
|
471
|
+
- prefer theme token utilities like `bg-primary`, `text-primary-foreground`, `bg-destructive`, and `border-input` instead of hardcoded colors
|
|
472
|
+
- preserve accessibility-related states such as focus rings and disabled styles
|
|
473
|
+
|
|
474
|
+
### Common button structure
|
|
475
|
+
|
|
476
|
+
A documented button pattern typically includes:
|
|
477
|
+
|
|
478
|
+
- base classes for layout, typography, focus, and disabled state
|
|
479
|
+
- a variant map
|
|
480
|
+
- a size map
|
|
481
|
+
- merged user classes from `$class`
|
|
482
|
+
- optional rendering differences when the component should behave like a link
|
|
483
|
+
|
|
484
|
+
## Accordion component rules
|
|
485
|
+
|
|
486
|
+
The official Accordion docs define Accordion as a grouped PHPX component system with multiple classes working together.
|
|
487
|
+
|
|
488
|
+
### Related classes
|
|
489
|
+
|
|
490
|
+
- `Accordion`
|
|
491
|
+
- `AccordionItem`
|
|
492
|
+
- `AccordionTrigger`
|
|
493
|
+
- `AccordionContent`
|
|
494
|
+
|
|
495
|
+
### Important lifecycle rule
|
|
496
|
+
|
|
497
|
+
The docs explicitly note that Prisma PHPX execution starts from the innermost child to the outermost parent. Because of that, the parent `Accordion` constructs last, and that is why the JavaScript is injected there after child IDs are ready.
|
|
498
|
+
|
|
499
|
+
### AI rules for accordions
|
|
500
|
+
|
|
501
|
+
- keep related accordion classes in the same naming family
|
|
502
|
+
- use `StateManager` when following the documented ID-sharing pattern between trigger and content
|
|
503
|
+
- inject shared accordion JavaScript from the parent component when using the documented lifecycle pattern
|
|
504
|
+
- preserve WAI-ARIA attributes such as `aria-controls`, `aria-expanded`, `aria-labelledby`, and `role="region"`
|
|
505
|
+
- keep default visibility and animation classes in the content container unless the design intentionally changes them
|
|
506
|
+
|
|
507
|
+
### Sub-component responsibilities
|
|
508
|
+
|
|
509
|
+
- `AccordionItem` wraps a single item pair
|
|
510
|
+
- `AccordionTrigger` renders the clickable control and manages toggle-related IDs
|
|
511
|
+
- `AccordionContent` renders the hidden content region using the shared item ID state
|
|
512
|
+
|
|
513
|
+
## XML-style syntax rule for component output
|
|
514
|
+
|
|
515
|
+
When AI generates Prisma PHP components, returned markup should follow strict XML-style rules used across Prisma PHP templates.
|
|
516
|
+
|
|
517
|
+
Correct:
|
|
518
|
+
|
|
519
|
+
```xml
|
|
520
|
+
<hr />
|
|
521
|
+
<input type="text" />
|
|
522
|
+
<Search class="size-4" />
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
Incorrect:
|
|
526
|
+
|
|
527
|
+
```xml
|
|
528
|
+
<hr>
|
|
529
|
+
<input type="text">
|
|
530
|
+
<Search class=size-4>
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
Also:
|
|
534
|
+
|
|
535
|
+
- close all tags properly
|
|
536
|
+
- use double quotes for attributes
|
|
537
|
+
- avoid shorthand boolean attributes
|
|
538
|
+
|
|
539
|
+
## When AI should inspect framework internals
|
|
540
|
+
|
|
541
|
+
If the installed docs and local project code are not enough, AI may inspect Prisma PHP core internals in:
|
|
542
|
+
|
|
543
|
+
```txt
|
|
544
|
+
vendor/tsnc/prisma-php/src
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
Important component-related files may include:
|
|
548
|
+
|
|
549
|
+
- `vendor/tsnc/prisma-php/src/PHPX/PHPX.php`
|
|
550
|
+
- `vendor/tsnc/prisma-php/src/PHPX/Fragment.php`
|
|
551
|
+
- `vendor/tsnc/prisma-php/src/PHPX/TemplateCompiler.php`
|
|
552
|
+
- `vendor/tsnc/prisma-php/src/PHPX/TwMerge.php`
|
|
553
|
+
- `vendor/tsnc/prisma-php/src/PHPX/TypeCoercer.php`
|
|
554
|
+
- `vendor/tsnc/prisma-php/src/ImportComponent.php`
|
|
555
|
+
- `vendor/tsnc/prisma-php/src/StateManager.php`
|
|
556
|
+
- `vendor/tsnc/prisma-php/src/Attributes/Exposed.php`
|
|
557
|
+
|
|
558
|
+
Use these files to verify internals only when necessary. Do not treat vendor internals as the first stop when the installed docs already answer the task.
|
|
559
|
+
|
|
560
|
+
## Recommended AI workflow for component tasks
|
|
561
|
+
|
|
562
|
+
When asked to create or edit a Prisma PHP component, AI should follow this workflow:
|
|
563
|
+
|
|
564
|
+
1. Read `prisma-php.json`.
|
|
565
|
+
2. Read the relevant installed component docs.
|
|
566
|
+
3. Decide whether the task is **PHPX class-based** or **`ImportComponent` partial-based**.
|
|
567
|
+
4. Inspect the local component namespace and folder conventions.
|
|
568
|
+
5. Match file name and class name for PHPX class components.
|
|
569
|
+
6. Use XML-style markup in `render(): string` or in imported partial output.
|
|
570
|
+
7. Use static props and reactive props correctly.
|
|
571
|
+
8. Enforce the single-root rule for `ImportComponent` partials.
|
|
572
|
+
9. Only inspect `vendor/tsnc/prisma-php/src` when the docs or local usage are not enough.
|
|
573
|
+
|
|
574
|
+
## Quick component lookup table
|
|
575
|
+
|
|
576
|
+
| Task | Read first | Typical location |
|
|
577
|
+
| ----------------------------------------- | --------------------- | ---------------------------------------------- |
|
|
578
|
+
| create a reusable PHPX component | `get-started-phpx` | `src/app/Lib/Components/ClassName.php` |
|
|
579
|
+
| import a PHP partial as a reactive island | `import-component` | `APP_PATH . '/inc/ComponentName.php'` |
|
|
580
|
+
| return multiple siblings in PHPX | `fragment` | `vendor/tsnc/prisma-php/src/PHPX/Fragment.php` |
|
|
581
|
+
| create an SVG icon component | `icon-component` | `src/app/Lib/GoogleIcons/Search.php` |
|
|
582
|
+
| create a theme-aware button | `button-component` | `src/app/Lib/Components/Button.php` |
|
|
583
|
+
| create a grouped accordion | `accordion-component` | `src/app/Lib/Components/Accordion.php` |
|
|
584
|
+
|
|
585
|
+
## Final AI reminder
|
|
586
|
+
|
|
587
|
+
For Prisma PHP components, do not guess.
|
|
588
|
+
|
|
589
|
+
Read the official component docs first, decide whether the task belongs to **PHPX** or **`ImportComponent`**, preserve strict XML-style output, and only inspect Prisma PHP core internals when you truly need framework-level implementation details.
|