From 4907bb62add1eba4fd27c68848179f127ecbf895 Mon Sep 17 00:00:00 2001 From: anderson Date: Thu, 10 Sep 2026 22:19:21 +0300 Subject: [PATCH 1/4] fix: enhance submit button with loading spinner and improved styling --- .github/instructions/comfony-instructions.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/instructions/comfony-instructions.md b/.github/instructions/comfony-instructions.md index 44f5432..21058e9 100644 --- a/.github/instructions/comfony-instructions.md +++ b/.github/instructions/comfony-instructions.md @@ -555,8 +555,9 @@ Setup default form like this in `templates/{entityPath}/_form.html.twig` {{ form_start(form) }} {{ form_widget(form) }}
-
From c3d664f559e827e50737c16f288d8ec77ac7c859 Mon Sep 17 00:00:00 2001 From: anderson Date: Fri, 11 Sep 2026 17:29:08 +0300 Subject: [PATCH 2/4] Refactor AI Instructions and Add Skills refactor(ai): adopt universal agent guidelines and locked skills architecture - Add root `AGENTS.md` as single source of truth for runtime and architecture rules - Introduce `skills-lock.json` to version-pin and verify external agent skills - Add modular `.agents/skills/daisyui` and project-specific `.agents/skills/comfony-crud` - Add multi-tool adapters for universal agents: `CLAUDE.md`, `.cursor/rules/comfony.mdc`, and updated `.github/copilot-instructions.md` - Remove legacy monolithic instruction dumps from `.github/` --- .agents/skills/comfony-crud/SKILL.md | 563 +++++ .agents/skills/daisyui/SKILL.md | 114 + .agents/skills/daisyui/colors/SKILL.md | 146 ++ .../skills/daisyui/components/accordion.md | 27 + .agents/skills/daisyui/components/alert.md | 19 + .agents/skills/daisyui/components/aura.md | 22 + .agents/skills/daisyui/components/avatar.md | 23 + .agents/skills/daisyui/components/badge.md | 20 + .../skills/daisyui/components/breadcrumbs.md | 19 + .agents/skills/daisyui/components/button.md | 22 + .agents/skills/daisyui/components/calendar.md | 57 + .agents/skills/daisyui/components/card.md | 29 + .agents/skills/daisyui/components/carousel.md | 20 + .agents/skills/daisyui/components/chat.md | 25 + .agents/skills/daisyui/components/checkbox.md | 17 + .agents/skills/daisyui/components/collapse.md | 22 + .../skills/daisyui/components/countdown.md | 19 + .agents/skills/daisyui/components/diff.md | 20 + .agents/skills/daisyui/components/divider.md | 19 + .agents/skills/daisyui/components/dock.md | 27 + .agents/skills/daisyui/components/drawer.md | 98 + .agents/skills/daisyui/components/dropdown.md | 32 + .agents/skills/daisyui/components/fab.md | 98 + .agents/skills/daisyui/components/fieldset.md | 20 + .../skills/daisyui/components/file-input.md | 18 + .agents/skills/daisyui/components/filter.md | 33 + .agents/skills/daisyui/components/footer.md | 21 + .agents/skills/daisyui/components/hero.md | 19 + .agents/skills/daisyui/components/hover-3d.md | 33 + .../daisyui/components/hover-gallery.md | 23 + .../skills/daisyui/components/indicator.md | 21 + .agents/skills/daisyui/components/input.md | 20 + .agents/skills/daisyui/components/join.md | 19 + .agents/skills/daisyui/components/kbd.md | 16 + .agents/skills/daisyui/components/label.md | 27 + .agents/skills/daisyui/components/link.md | 17 + .agents/skills/daisyui/components/list.md | 20 + .agents/skills/daisyui/components/loading.md | 17 + .agents/skills/daisyui/components/mask.md | 19 + .agents/skills/daisyui/components/megamenu.md | 69 + .agents/skills/daisyui/components/menu.md | 33 + .../daisyui/components/mockup-browser.md | 22 + .../skills/daisyui/components/mockup-code.md | 19 + .../skills/daisyui/components/mockup-phone.md | 19 + .../daisyui/components/mockup-window.md | 14 + .agents/skills/daisyui/components/modal.md | 84 + .agents/skills/daisyui/components/navbar.md | 18 + .agents/skills/daisyui/components/otp.md | 28 + .../skills/daisyui/components/pagination.md | 18 + .agents/skills/daisyui/components/progress.md | 17 + .../daisyui/components/radial-progress.md | 18 + .agents/skills/daisyui/components/radio.md | 19 + .agents/skills/daisyui/components/range.md | 20 + .agents/skills/daisyui/components/rating.md | 31 + .agents/skills/daisyui/components/select.md | 20 + .agents/skills/daisyui/components/skeleton.md | 20 + .agents/skills/daisyui/components/stack.md | 17 + .agents/skills/daisyui/components/stat.md | 21 + .agents/skills/daisyui/components/status.md | 18 + .agents/skills/daisyui/components/steps.md | 25 + .agents/skills/daisyui/components/swap.md | 33 + .agents/skills/daisyui/components/tab.md | 32 + .agents/skills/daisyui/components/table.md | 31 + .../skills/daisyui/components/text-rotate.md | 65 + .agents/skills/daisyui/components/textarea.md | 18 + .../daisyui/components/theme-controller.md | 15 + .agents/skills/daisyui/components/timeline.md | 27 + .agents/skills/daisyui/components/toast.md | 16 + .agents/skills/daisyui/components/toggle.md | 17 + .agents/skills/daisyui/components/tooltip.md | 22 + .../skills/daisyui/components/validator.md | 17 + .agents/skills/daisyui/config/SKILL.md | 49 + .agents/skills/daisyui/install/SKILL.md | 79 + .agents/skills/daisyui/usage/SKILL.md | 59 + .cursor/rules/comfony.mdc | 17 + .github/copilot-instructions.md | 91 +- .github/instructions/comfony-instructions.md | 578 ----- .github/instructions/daisyui-instructions.md | 1851 ----------------- AGENTS.md | 100 + CLAUDE.md | 14 + skills-lock.json | 11 + 81 files changed, 2984 insertions(+), 2509 deletions(-) create mode 100644 .agents/skills/comfony-crud/SKILL.md create mode 100644 .agents/skills/daisyui/SKILL.md create mode 100644 .agents/skills/daisyui/colors/SKILL.md create mode 100644 .agents/skills/daisyui/components/accordion.md create mode 100644 .agents/skills/daisyui/components/alert.md create mode 100644 .agents/skills/daisyui/components/aura.md create mode 100644 .agents/skills/daisyui/components/avatar.md create mode 100644 .agents/skills/daisyui/components/badge.md create mode 100644 .agents/skills/daisyui/components/breadcrumbs.md create mode 100644 .agents/skills/daisyui/components/button.md create mode 100644 .agents/skills/daisyui/components/calendar.md create mode 100644 .agents/skills/daisyui/components/card.md create mode 100644 .agents/skills/daisyui/components/carousel.md create mode 100644 .agents/skills/daisyui/components/chat.md create mode 100644 .agents/skills/daisyui/components/checkbox.md create mode 100644 .agents/skills/daisyui/components/collapse.md create mode 100644 .agents/skills/daisyui/components/countdown.md create mode 100644 .agents/skills/daisyui/components/diff.md create mode 100644 .agents/skills/daisyui/components/divider.md create mode 100644 .agents/skills/daisyui/components/dock.md create mode 100644 .agents/skills/daisyui/components/drawer.md create mode 100644 .agents/skills/daisyui/components/dropdown.md create mode 100644 .agents/skills/daisyui/components/fab.md create mode 100644 .agents/skills/daisyui/components/fieldset.md create mode 100644 .agents/skills/daisyui/components/file-input.md create mode 100644 .agents/skills/daisyui/components/filter.md create mode 100644 .agents/skills/daisyui/components/footer.md create mode 100644 .agents/skills/daisyui/components/hero.md create mode 100644 .agents/skills/daisyui/components/hover-3d.md create mode 100644 .agents/skills/daisyui/components/hover-gallery.md create mode 100644 .agents/skills/daisyui/components/indicator.md create mode 100644 .agents/skills/daisyui/components/input.md create mode 100644 .agents/skills/daisyui/components/join.md create mode 100644 .agents/skills/daisyui/components/kbd.md create mode 100644 .agents/skills/daisyui/components/label.md create mode 100644 .agents/skills/daisyui/components/link.md create mode 100644 .agents/skills/daisyui/components/list.md create mode 100644 .agents/skills/daisyui/components/loading.md create mode 100644 .agents/skills/daisyui/components/mask.md create mode 100644 .agents/skills/daisyui/components/megamenu.md create mode 100644 .agents/skills/daisyui/components/menu.md create mode 100644 .agents/skills/daisyui/components/mockup-browser.md create mode 100644 .agents/skills/daisyui/components/mockup-code.md create mode 100644 .agents/skills/daisyui/components/mockup-phone.md create mode 100644 .agents/skills/daisyui/components/mockup-window.md create mode 100644 .agents/skills/daisyui/components/modal.md create mode 100644 .agents/skills/daisyui/components/navbar.md create mode 100644 .agents/skills/daisyui/components/otp.md create mode 100644 .agents/skills/daisyui/components/pagination.md create mode 100644 .agents/skills/daisyui/components/progress.md create mode 100644 .agents/skills/daisyui/components/radial-progress.md create mode 100644 .agents/skills/daisyui/components/radio.md create mode 100644 .agents/skills/daisyui/components/range.md create mode 100644 .agents/skills/daisyui/components/rating.md create mode 100644 .agents/skills/daisyui/components/select.md create mode 100644 .agents/skills/daisyui/components/skeleton.md create mode 100644 .agents/skills/daisyui/components/stack.md create mode 100644 .agents/skills/daisyui/components/stat.md create mode 100644 .agents/skills/daisyui/components/status.md create mode 100644 .agents/skills/daisyui/components/steps.md create mode 100644 .agents/skills/daisyui/components/swap.md create mode 100644 .agents/skills/daisyui/components/tab.md create mode 100644 .agents/skills/daisyui/components/table.md create mode 100644 .agents/skills/daisyui/components/text-rotate.md create mode 100644 .agents/skills/daisyui/components/textarea.md create mode 100644 .agents/skills/daisyui/components/theme-controller.md create mode 100644 .agents/skills/daisyui/components/timeline.md create mode 100644 .agents/skills/daisyui/components/toast.md create mode 100644 .agents/skills/daisyui/components/toggle.md create mode 100644 .agents/skills/daisyui/components/tooltip.md create mode 100644 .agents/skills/daisyui/components/validator.md create mode 100644 .agents/skills/daisyui/config/SKILL.md create mode 100644 .agents/skills/daisyui/install/SKILL.md create mode 100644 .agents/skills/daisyui/usage/SKILL.md create mode 100644 .cursor/rules/comfony.mdc delete mode 100644 .github/instructions/comfony-instructions.md delete mode 100644 .github/instructions/daisyui-instructions.md create mode 100644 AGENTS.md create mode 100644 CLAUDE.md create mode 100644 skills-lock.json diff --git a/.agents/skills/comfony-crud/SKILL.md b/.agents/skills/comfony-crud/SKILL.md new file mode 100644 index 0000000..0415095 --- /dev/null +++ b/.agents/skills/comfony-crud/SKILL.md @@ -0,0 +1,563 @@ +--- +name: comfony-crud +description: Comprehensive guide and templates for creating Entities, CRUD operations, DatatableComponent, LiveForms, and Turbo Streams in Comfony. Use this skill whenever implementing or modifying entities, admin pages, search tables, or reactive forms. +metadata: + version: 1.0.0 +--- + +# Comfony CRUD & Component Development Guide + +Comfony is built on Symfony 7.3, PHP 8.4, Hotwire Turbo, Stimulus, UX Live Components, and Mercure. + +--- + +## 1. Entity Definition + +### Standards +- **PHP 8.4** coding standard. +- **Setters MUST accept nullable parameters** (e.g. `public function setTitle(?string $title): static`) — UX LiveComponent requires this to bind form state correctly. +- **Mercure Real-Time Broadcast:** Add `#[Broadcast(topics: ['entity_plural'], private: true)]` to stream entity changes via Mercure. +- **File Attachments:** Use `App\Entity\File\File`. Relations should be `ManyToMany` (or `ManyToOne`). Never modify `File` entity unless strictly required. +- **Traits:** Use Gedmo `TimestampableEntity` and `BlameableEntity`. +- **Slugs:** Use `#[Slug(fields: ['title'])]` from Gedmo. +- **NO Manual Migrations:** Do NOT create migration files (`make:migration`). Comfony handles database schema automatically. Offer to run `./bin/docker-console.sh config:import` (or `./bin/console config:import`). + +### Entity Example +```php +attachments = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function getTitle(): ?string + { + return $this->title; + } + + public function setTitle(?string $title): static + { + $this->title = $title; + return $this; + } + + public function getBody(): ?string + { + return $this->body; + } + + public function setBody(?string $body): static + { + $this->body = $body; + return $this; + } + + public function getSlug(): ?string + { + return $this->slug; + } + + public function setSlug(?string $slug): static + { + $this->slug = $slug; + return $this; + } + + /** + * @return Collection + */ + public function getAttachments(): Collection + { + return $this->attachments; + } + + public function addAttachment(File $attachment): static + { + if (!$this->attachments->contains($attachment)) { + $this->attachments->add($attachment); + } + return $this; + } + + public function removeAttachment(File $attachment): static + { + $this->attachments->removeElement($attachment); + return $this; + } + + public function isPublished(): ?bool + { + return $this->published; + } + + public function setPublished(?bool $published): static + { + $this->published = $published; + return $this; + } +} +``` + +--- + +## 2. Admin Controller + +Place controllers under `src/Controller/Admin/{Feature}Controller.php`. + +```php +render('admin/page/index.html.twig', [ + 'title' => $this->translator->trans('Pages'), + ]); + } + + #[Route('/new', name: 'app_admin_page_new', methods: ['GET'])] + public function new(): Response + { + $page = new Page(); + return $this->render('admin/page/edit.html.twig', [ + 'title' => $this->translator->trans('Add New Page'), + 'page' => $page, + ]); + } + + #[Route('/{id}/edit', name: 'app_admin_page_edit', methods: ['GET'])] + public function edit(Page $page): Response + { + return $this->render('admin/page/edit.html.twig', [ + 'title' => $this->translator->trans('Edit Page {title}', ['title' => $page->getTitle()]), + 'page' => $page, + ]); + } + + #[Route('/{id}', name: 'app_admin_page_delete', methods: ['POST'])] + public function delete(Request $request, Page $page, EntityManagerInterface $entityManager): Response + { + if ($this->isCsrfTokenValid('delete' . $page->getId(), $request->request->get('_token'))) { + $entityManager->remove($page); + $entityManager->flush(); + $this->addFlash('success', $this->translator->trans('Page deleted successfully.')); + } + + return $this->redirectToRoute('app_admin_page_index', [], Response::HTTP_SEE_OTHER); + } +} +``` + +--- + +## 3. Search / Datatable Component + +- Location: `src/Twig/Components/{Feature}SearchComponent.php`. +- Must extend `DatatableComponent`. +- Must be annotated with `#[AsLiveComponent(template: '@base_theme/partials/_datatable.html.twig')]`. +- Define `$sort`, `$direction`, `$rowTemplateFile`. +- Implement `getQueryBuilder()` and `getTableBuildData()`. Include at least one column in `quick_filters`. + +```php +entityManager->getRepository(Page::class)->createQueryBuilder('p'); + } + + #[Override] + public function getTableBuildData(): array + { + return [ + 'headers' => [ + ['label' => $this->translator->trans("Actions")], + 'p.id' => ['label' => $this->translator->trans("Id"), 'sortable' => true], + 'p.title' => ['label' => $this->translator->trans("Title"), 'sortable' => true], + ['label' => $this->translator->trans('Published')], + 'p.createdAt' => ['label' => $this->translator->trans('created_at'), 'sortable' => true], + 'p.updatedAt' => ['label' => $this->translator->trans('updated_at'), 'sortable' => true], + ], + "quick_filters" => [ + "p.title" => [] + ], + "filters" => [ + 'p.title' => [ + 'options' => ['label' => 'Title'], + ], + 'p.published' => [ + 'type' => ChoiceType::class, + 'options' => [ + 'label' => 'Published', + 'placeholder' => $this->translator->trans('All'), + 'choices' => [ + 'Published' => 1, + 'Unpublished' => 0, + ], + ], + ], + ] + ]; + } +} +``` + +--- + +## 4. LiveForm Component + +- Location: `src/Twig/Components/LiveForms/Live{Feature}FormComponent.php`. +- Uses `DefaultActionTrait`, `ComponentWithFormTrait`, `LiveAsyncFileInputTrait`. +- Initial form data property: `#[LiveProp] public ?Entity $initialFormData = null;`. +- Implements `instantiateForm()` and `#[LiveAction] save()`. + +```php +initialFormData) { + $this->initialFormData = new Page(); + } + return $this->createForm(PageFormType::class, $this->initialFormData, [ + 'attr' => [ + 'data-action' => 'live#action:prevent', + 'data-live-action-param' => 'save', + 'novalidate' => true, + ] + ]); + } + + #[LiveAction] + public function save() + { + $this->submitForm(); + /** @var Page $object */ + $object = $this->getForm()->getData(); + $isCreate = !boolval($object->getId()); + $this->entityManager->persist($object); + $this->entityManager->flush(); + + $this->addFlash('success', $this->translator->trans( + $isCreate ? 'Page created successfully.' : 'Page updated successfully.' + )); + + if ($isCreate) { + return $this->redirectToRoute('app_admin_page_edit', ['id' => $object->getId()]); + } + } +} +``` + +--- + +## 5. Templates Architecture + +### Index Page (`templates/admin/{feature}/index.html.twig`) +```twig +{% extends 'base.html.twig' %} + +{% block actions %} + + + {% trans %}Add New Page{% endtrans %} + +{% endblock %} + +{% block body %} + {{ component('PagesSearchComponent', {listTopic: 'pages', loading: 'lazy', entityClass: 'App\\Entity\\Page\\Page', options: {'allow_remove': true, 'allow_bulk_remove': true}}) }} +{% endblock %} +``` + +### Edit Page (`templates/admin/{feature}/edit.html.twig`) +```twig +{% extends 'admin/page/index.html.twig' %} + +{% block backLink %} + + + {% trans %}Back{% endtrans %} + +{% endblock %} + +{% block body %} +
+
+ {{ component('LiveForms:LivePageFormComponent', { initialFormData: page }) }} +
+
+ {% if page.id %} + {{ include('admin/page/_delete_form.html.twig') }} + {% endif %} +{% endblock %} +``` + +### Delete Form (`templates/admin/{feature}/_delete_form.html.twig`) +```twig +
+
+ + {% set modalId = 'delete-modal-' ~ page.id %} + +
+ {% include theme.themeDirectory ~ "/partials/_delete_modal.html.twig" with {modalId: modalId, objectName: "Page"|trans} %} +
+``` + +### Row Template (`templates/admin/{feature}/_row.html.twig`) +```twig +{% set action = action is defined ? action : null %} + + {% if bulkRemoveAllowed is defined and bulkRemoveAllowed %} + + + + {% else %} + + {% endif %} + +
+ {% if action != 'remove' %} + + + + {% if action == null %} +
+ + {% set modalId = 'delete-modal-' ~ object.id %} + + {% include theme.themeDirectory ~ "/partials/_delete_modal.html.twig" with {modalId: modalId, objectName: "Page"|trans} %} +
+ {% endif %} + {% endif %} +
+ + {{ object.id }} + {{ object.title }} + + {% if object.published %} + {% trans %}Published{% endtrans %} + {% else %} + {% trans %}Unpublished{% endtrans %} + {% endif %} + + + + + + + + +``` + +### LiveForm Twig Container (`templates/components/LiveForms/Live{Feature}FormComponent.html.twig`) +```twig +
+ {{ include(theme.themeDirectory ~ '/partials/_flash_messages.html.twig') }} + {% include "admin/page/_form.html.twig" %} +
+``` + +### Partial Form (`templates/admin/{feature}/_form.html.twig`) +```twig +{% set page = initialFormData %} +{% if page.id %} +
+ +
{{ page.createdAt|format_datetime('full', 'short') }}
+
+
+ +
{{ page.updatedAt|format_datetime('full', 'short') }}
+
+{% endif %} + +{{ form_start(form) }} +{{ form_widget(form) }} + +
+ +
+{{ form_end(form) }} +``` + +### Broadcast Turbo Stream (`templates/broadcast/{Entity}/{Entity}.stream.html.twig`) +```twig +{% block create %} + + + +{% endblock %} + +{% block update %} + + + +{% endblock %} + +{% block remove %} + + + +{% endblock %} +``` + +--- + +## 6. Sidebar Navigation + +Add menu items to `templates/themes/base_theme/partials/_sidebar.html.twig`: + +```twig +
  • + + + {% trans %}Pages{% endtrans %} + +
  • +``` + diff --git a/.agents/skills/daisyui/SKILL.md b/.agents/skills/daisyui/SKILL.md new file mode 100644 index 0000000..453aa76 --- /dev/null +++ b/.agents/skills/daisyui/SKILL.md @@ -0,0 +1,114 @@ +--- +name: daisyui +description: Official daisyUI component-library skill for Tailwind CSS. When you write HTML or JSX code, you must use it. Even if the user does not request it, use it. +metadata: + version: 5.7.x + source: https://daisyui.com/SKILL.md +--- + +# daisyUI 5 +daisyUI 5 is a CSS library for Tailwind CSS 4. It supplies class names for common UI components, semantic colors, and themes. + +## When to use this skill + +- Use this skill each time you write HTML or JSX code. +- Use this skill for all Tailwind CSS UI work. +- If the user uses one of these terms or requests related work, use this skill: + daisyUI, component, UI, Tailwind, layout, template, theme, color, design +- Even if the user does not request this skill, use it. + +## References that you must read + +| Task | Guide | Note | +|------|-------|------| +Install daisyUI | [./install/SKILL.md](./install/SKILL.md) | If the project does not have daisyUI, use this guide. +Use daisyUI class names | [./usage/SKILL.md](./usage/SKILL.md) | You must read this guide before you use daisyUI class names in code. +Configure daisyUI | [./config/SKILL.md](./config/SKILL.md) | Read this guide to configure themes, prefixes, logs, or other options. You do not need it for basic use. +daisyUI colors and themes | [./colors/SKILL.md](./colors/SKILL.md) | You must read this guide before you use daisyUI colors in code. +daisyUI components | [./components/](./components/) | You must read the applicable component guides before you use daisyUI components. Read more than one candidate guide before you select a component. + +## List of components + +- [accordion](./components/accordion.md) +- [aura](./components/aura.md) +- [alert](./components/alert.md) +- [avatar](./components/avatar.md) +- [badge](./components/badge.md) +- [breadcrumbs](./components/breadcrumbs.md) +- [button](./components/button.md) +- [calendar](./components/calendar.md) +- [card](./components/card.md) +- [carousel](./components/carousel.md) +- [chat](./components/chat.md) +- [checkbox](./components/checkbox.md) +- [collapse](./components/collapse.md) +- [countdown](./components/countdown.md) +- [diff](./components/diff.md) +- [divider](./components/divider.md) +- [dock (app bar)](./components/dock.md) +- [drawer (sidebar)](./components/drawer.md) +- [dropdown](./components/dropdown.md) +- [FAB](./components/fab.md) +- [fieldset](./components/fieldset.md) +- [file-input](./components/file-input.md) +- [filter](./components/filter.md) +- [footer](./components/footer.md) +- [hero](./components/hero.md) +- [hover-3d](./components/hover-3d.md) +- [hover-gallery](./components/hover-gallery.md) +- [indicator](./components/indicator.md) +- [input](./components/input.md) +- [join (group)](./components/join.md) +- [kbd](./components/kbd.md) +- [label](./components/label.md) +- [link](./components/link.md) +- [list](./components/list.md) +- [loading](./components/loading.md) +- [mask](./components/mask.md) +- [megamenu](./components/megamenu.md) +- [menu](./components/menu.md) +- [mockup-browser](./components/mockup-browser.md) +- [mockup-code](./components/mockup-code.md) +- [mockup-phone](./components/mockup-phone.md) +- [mockup-window](./components/mockup-window.md) +- [modal](./components/modal.md) +- [navbar](./components/navbar.md) +- [otp](./components/otp.md) +- [pagination](./components/pagination.md) +- [progress](./components/progress.md) +- [radial-progress](./components/radial-progress.md) +- [radio](./components/radio.md) +- [range](./components/range.md) +- [rating](./components/rating.md) +- [select](./components/select.md) +- [skeleton](./components/skeleton.md) +- [stack](./components/stack.md) +- [stat](./components/stat.md) +- [status](./components/status.md) +- [steps](./components/steps.md) +- [swap](./components/swap.md) +- [tab](./components/tab.md) +- [table](./components/table.md) +- [text-rotate](./components/text-rotate.md) +- [textarea](./components/textarea.md) +- [theme-controller](./components/theme-controller.md) +- [timeline](./components/timeline.md) +- [toast](./components/toast.md) +- [toggle (switch)](./components/toggle.md) +- [tooltip](./components/tooltip.md) +- [validator](./components/validator.md) + +### Component discovery protocol + +Before you write daisyUI code, do these steps in sequence: + +1. Identify the intended function, behavior, and layout in the request. Do not use only the exact words. +2. Use the component list in this file to select the best candidate components. +3. If the choice is not clear, read the guides for the candidate components that can meet the request before you select one. +4. Compare the description, behavior, syntax, and rules of each candidate with the request. +5. Select the best component or component combination. Obey all its constraints. +6. Use the exact structure and constraints of the selected components. + +You must match the meaning, even when the words are different from component names. A component with a different name can still be the best match. Always examine the intended function and meaning. + +If the user requests a named component and a guide with that name exists, read that guide first. diff --git a/.agents/skills/daisyui/colors/SKILL.md b/.agents/skills/daisyui/colors/SKILL.md new file mode 100644 index 0000000..aa09f81 --- /dev/null +++ b/.agents/skills/daisyui/colors/SKILL.md @@ -0,0 +1,146 @@ +--- +name: daisyui-colors +description: Color rules that you must use with daisyUI 5 +--- + +## daisyUI 5 colors + +### daisyUI color names +- `primary`: The main brand color. +- `primary-content`: Foreground content color for use on `primary`. +- `secondary`: An optional secondary brand color. +- `secondary-content`: Foreground content color for use on `secondary`. +- `accent`: An optional accent brand color. +- `accent-content`: Foreground content color for use on `accent`. +- `neutral`: A dark neutral color for UI areas that do not use saturated colors. +- `neutral-content`: Foreground content color for use on `neutral`. +- `base-100`: The page base-surface color for blank backgrounds. +- `base-200`: A darker base shade that gives elevation. +- `base-300`: A still darker base shade that gives more elevation. +- `base-content`: Foreground content color for use on a base color. +- `info`: Color for information and help messages. +- `info-content`: Foreground content color for use on `info`. +- `success`: Color for success and safe-state messages. +- `success-content`: Foreground content color for use on `success`. +- `warning`: Color for warning and caution messages. +- `warning-content`: Foreground content color for use on `warning`. +- `error`: Color for error, danger, and destructive-action messages. +- `error-content`: Foreground content color for use on `error`. + +### daisyUI color rules +1. daisyUI adds semantic color names to the Tailwind CSS colors. +2. Use daisyUI color names in utility classes as you use other Tailwind CSS color names. For example, `bg-primary` uses the primary color for the background. +3. The value of each daisyUI color name is a variable. Thus, the color can change with the theme. +4. Do not use `dark:` with daisyUI color names. +5. If possible, use only daisyUI color names. This lets colors change automatically with the theme. +6. If you use a Tailwind CSS color name such as `red-500`, its color stays the same in all themes. +7. If you use a daisyUI color name such as `primary`, its color changes with the theme. +8. Avoid Tailwind CSS color names for text. For example, `text-gray-800` on `bg-base-100` becomes unreadable in a dark theme because `bg-base-100` is dark. +9. `*-content` colors must have clear contrast with their related colors. +10. Use `base-*` colors for most of the page. Use the default variant for all elements. Use `primary` only for the most important element on the page. Use it only once. +11. In rare cases, you can use a Tailwind CSS color if content must keep the same color in all themes. For example, you can use `text-red-500` instead of `text-error`. For an SVG icon or chart, a fixed color can be necessary. + +### Enable and apply themes + +The default configuration enables `light` and `dark`. In the daisyUI plugin, select specified themes, all themes, or no built-in themes: + +```css +@plugin "daisyui" { + themes: light --default, dark --prefersdark, cupcake; +} +``` + +- Use `themes: all;` to enable all built-in themes. +- Use `themes: false;` to disable all built-in themes. Usually, do this before you define only custom themes. +- Add `data-theme="THEME_NAME"` to `` or a nested element. You can nest themes with no depth limit. + +```html + +
    +
    Nested theme
    +
    + +``` + +### daisyUI custom theme with custom colors +A CSS file that contains Tailwind CSS, daisyUI, and a custom daisyUI theme has this structure: +```css +@import "tailwindcss"; +@plugin "daisyui"; +@plugin "daisyui/theme" { + name: "mytheme"; + default: true; /* set as default */ + prefersdark: false; /* set as default dark mode (prefers-color-scheme:dark) */ + color-scheme: light; /* color of browser-provided UI */ + + --color-base-100: oklch(98% 0.02 240); + --color-base-200: oklch(95% 0.03 240); + --color-base-300: oklch(92% 0.04 240); + --color-base-content: oklch(20% 0.05 240); + --color-primary: oklch(55% 0.3 240); + --color-primary-content: oklch(98% 0.01 240); + --color-secondary: oklch(70% 0.25 200); + --color-secondary-content: oklch(98% 0.01 200); + --color-accent: oklch(65% 0.25 160); + --color-accent-content: oklch(98% 0.01 160); + --color-neutral: oklch(50% 0.05 240); + --color-neutral-content: oklch(98% 0.01 240); + --color-info: oklch(70% 0.2 220); + --color-info-content: oklch(98% 0.01 220); + --color-success: oklch(65% 0.25 140); + --color-success-content: oklch(98% 0.01 140); + --color-warning: oklch(80% 0.25 80); + --color-warning-content: oklch(20% 0.05 80); + --color-error: oklch(65% 0.3 30); + --color-error-content: oklch(98% 0.01 30); + + --radius-selector: 1rem; /* border radius of selectors (checkbox, toggle, badge) */ + --radius-field: 0.25rem; /* border radius of fields (button, input, select, tab) */ + --radius-box: 0.5rem; /* border radius of boxes (card, modal, alert) */ + /* preferred values for --radius-* : 0rem, 0.25rem, 0.5rem, 1rem, 2rem */ + + --size-selector: 0.25rem; /* base size of selectors (checkbox, toggle, badge). Value must be 0.25rem unless we intentionally want bigger selectors. If so it can be 0.28125 or 0.3125. If we intentionally want smaller selectors, it can be 0.21875 or 0.1875 */ + --size-field: 0.25rem; /* base size of fields (button, input, select, tab). Value must be 0.25rem unless we intentionally want bigger fields. If so it can be 0.28125 or 0.3125. If we intentionally want smaller fields, it can be 0.21875 or 0.1875 */ + + --border: 1px; /* border size. Value must be 1px unless we intentionally want thicker borders. If so it can be 1.5px or 2px. If we intentionally want thinner borders, it can be 0.5px */ + + --depth: 1; /* only 0 or 1 - Adds a shadow and subtle 3D depth effect to components */ + --noise: 0; /* only 0 or 1 - Adds a subtle noise (grain) effect to components */ +} +``` +#### Rules +- You must include all CSS variables in the example. +- Colors can use OKLCH, hex, or another format. +- If you generate a custom theme, do not include the comments from the example. Give only the code. + +Optional: Use the visual tool at https://daisyui.com/theme-generator/ to make a custom theme. + +### Change a built-in theme + +Use the built-in theme name. Change only the necessary values. daisyUI inherits the other values: + +```css +@plugin "daisyui/theme" { + name: "light"; + default: true; + --color-primary: blue; + --color-secondary: teal; +} +``` + +For a custom CDN theme, define the same variables in a selector. The selector must match the selected `data-theme` and theme controller: + +```css +:root:has(input.theme-controller[value=mytheme]:checked), +[data-theme="mytheme"] { + color-scheme: light; + --color-primary: oklch(55% 0.3 240); + /* define the remaining custom-theme variables */ +} +``` + +To make the Tailwind `dark:` variant follow one or more daisyUI themes, define a custom variant: + +```css +@custom-variant dark (&:where([data-theme=night], [data-theme=night] *)); +``` diff --git a/.agents/skills/daisyui/components/accordion.md b/.agents/skills/daisyui/components/accordion.md new file mode 100644 index 0000000..2e71a4a --- /dev/null +++ b/.agents/skills/daisyui/components/accordion.md @@ -0,0 +1,27 @@ +### Accordion +Use the accordion to show and hide content. Only one item can be open at a time. + +[Accordion documentation](https://daisyui.com/components/accordion/) + +#### Class names +- component: `collapse` +- part: `collapse-title`, `collapse-content` +- modifier: `collapse-arrow`, `collapse-plus`, `collapse-open`, `collapse-close` + +#### Syntax +```html +
    {CONTENT}
    +``` +The content has this structure: +```html + +
    {title}
    +
    {CONTENT}
    +``` + +#### Rules +- `{MODIFIER}` is optional. It can be one of the modifier class names. +- The accordion uses radio inputs. Radio inputs that have the same name operate as one group. Only one input in the group can be open at a time. +- If a page has more than one accordion group, use a different radio-input name for each group. +- Replace `{name}` with a unique name for the accordion group. +- To open an accordion item by default, replace `{checked}` with `checked="checked"`. diff --git a/.agents/skills/daisyui/components/alert.md b/.agents/skills/daisyui/components/alert.md new file mode 100644 index 0000000..7041370 --- /dev/null +++ b/.agents/skills/daisyui/components/alert.md @@ -0,0 +1,19 @@ +### Alert +Use an alert to give users information about an important event. + +[Alert documentation](https://daisyui.com/components/alert/) + +#### Class names +- component: `alert` +- style: `alert-outline`, `alert-dash`, `alert-soft` +- color: `alert-info`, `alert-success`, `alert-warning`, `alert-error` +- direction: `alert-vertical`, `alert-horizontal` + +#### Syntax +```html + +``` + +#### Rules +- `{MODIFIER}` is optional. It can include one class name from each style, color, and direction category. +- For responsive layouts, add `sm:alert-horizontal`. diff --git a/.agents/skills/daisyui/components/aura.md b/.agents/skills/daisyui/components/aura.md new file mode 100644 index 0000000..dada8f4 --- /dev/null +++ b/.agents/skills/daisyui/components/aura.md @@ -0,0 +1,22 @@ +### Aura +An aura adds a light effect around the border of a component. Use it to make an important button, card, or div easy to see. +[Aura documentation](https://daisyui.com/components/aura/) + +#### Class names +- component: `aura` +- style: `aura-dual`, `aura-rainbow`, `aura-holo`, `aura-gold`, `aura-silver`, `aura-glow` +- size: `aura-xs`, `aura-sm`, `aura-md`, `aura-lg`, `aura-xl` + +#### Syntax +```html +
    {CONTENT}
    +``` + +#### Rules +- `{MODIFIER}` is optional. It can include one class name from each style and size category. +- To set a custom color, use a `text-*` color class. For example, `text-primary` sets the aura to the primary color. +- To set a custom background color, use a `bg-*` color class. For example, `bg-secondary` sets a secondary-color background. +- To set a custom animation time, use a `duration-*` class. For example, `duration-1000` sets the animation time to one second. +- An aura must have one direct child element. +- Use an aura for an important button, card, or div. +- Do not use an aura for more than one element on the same page. More than one aura can make the page difficult to view. diff --git a/.agents/skills/daisyui/components/avatar.md b/.agents/skills/daisyui/components/avatar.md new file mode 100644 index 0000000..eb72b09 --- /dev/null +++ b/.agents/skills/daisyui/components/avatar.md @@ -0,0 +1,23 @@ +### Avatar +Use an avatar to show a thumbnail image. + +[Avatar documentation](https://daisyui.com/components/avatar/) + +#### Class names +- component: `avatar`, `avatar-group` +- modifier: `avatar-online`, `avatar-offline`, `avatar-placeholder` + +#### Syntax +```html +
    +
    + +
    +
    +``` + +#### Rules +- `{MODIFIER}` is optional. It can be one of the modifier class names. +- Use `avatar-group` as a container for more than one avatar. +- To set a custom size, use `w-*` and `h-*`. +- To change the avatar shape, use mask classes such as `mask-squircle`, `mask-hexagon`, and `mask-triangle`. diff --git a/.agents/skills/daisyui/components/badge.md b/.agents/skills/daisyui/components/badge.md new file mode 100644 index 0000000..720da8f --- /dev/null +++ b/.agents/skills/daisyui/components/badge.md @@ -0,0 +1,20 @@ +### Badge +Use a badge to show the status of data. + +[Badge documentation](https://daisyui.com/components/badge/) + +#### Class names +- component: `badge` +- style: `badge-outline`, `badge-dash`, `badge-soft`, `badge-ghost` +- color: `badge-neutral`, `badge-primary`, `badge-secondary`, `badge-accent`, `badge-info`, `badge-success`, `badge-warning`, `badge-error` +- size: `badge-xs`, `badge-sm`, `badge-md`, `badge-lg`, `badge-xl` + +#### Syntax +```html +Badge +``` + +#### Rules +- `{MODIFIER}` is optional. It can include one class name from each style, color, and size category. +- You can use a badge in text or buttons. +- To make an empty badge, remove the text between the span tags. diff --git a/.agents/skills/daisyui/components/breadcrumbs.md b/.agents/skills/daisyui/components/breadcrumbs.md new file mode 100644 index 0000000..7931c3b --- /dev/null +++ b/.agents/skills/daisyui/components/breadcrumbs.md @@ -0,0 +1,19 @@ +### Breadcrumbs +Use breadcrumbs to help users navigate. + +[Breadcrumbs documentation](https://daisyui.com/components/breadcrumbs/) + +#### Class names +- component: `breadcrumbs` + +#### Syntax +```html + +``` + +#### Rules +- The breadcrumbs component has one main class name. +- You can put icons in the links. +- If you set `max-width` or the list becomes wider than its container, the breadcrumbs list scrolls. diff --git a/.agents/skills/daisyui/components/button.md b/.agents/skills/daisyui/components/button.md new file mode 100644 index 0000000..24114ab --- /dev/null +++ b/.agents/skills/daisyui/components/button.md @@ -0,0 +1,22 @@ +### Button +Use buttons to start actions. + +[Button documentation](https://daisyui.com/components/button/) + +#### Class names +- component: `btn` +- color: `btn-neutral`, `btn-primary`, `btn-secondary`, `btn-accent`, `btn-info`, `btn-success`, `btn-warning`, `btn-error` +- style: `btn-outline`, `btn-dash`, `btn-soft`, `btn-ghost`, `btn-link` +- behavior: `btn-active`, `btn-disabled` +- size: `btn-xs`, `btn-sm`, `btn-md`, `btn-lg`, `btn-xl` +- modifier: `btn-wide`, `btn-block`, `btn-square`, `btn-circle` + +#### Syntax +```html + +``` +#### Rules +- `{MODIFIER}` is optional. It can include one class name from each color, style, behavior, size, and modifier category. +- You can use `btn` on HTML elements such as ` +``` + +#### Rules +- `{MODIFIER}` is optional. It can be one of the size class names. +- To make a button active, add the `dock-active` class to the button. +- For a responsive dock in iOS, add ``. diff --git a/.agents/skills/daisyui/components/drawer.md b/.agents/skills/daisyui/components/drawer.md new file mode 100644 index 0000000..d60720f --- /dev/null +++ b/.agents/skills/daisyui/components/drawer.md @@ -0,0 +1,98 @@ +### Drawer +A drawer is a grid layout that can show and hide a sidebar. The sidebar can be on either side of the page. + +[Drawer documentation](https://daisyui.com/components/drawer/) + +#### Class names +- component: `drawer` +- part: `drawer-toggle`, `drawer-content`, `drawer-side`, `drawer-overlay`, `drawer-button` +- placement: `drawer-end` +- modifier: `drawer-open` +- variant: `is-drawer-open:`, `is-drawer-close:` + +#### Syntax +```html +
    + +
    {CONTENT}
    +
    {SIDEBAR}
    +
    +``` +The `{CONTENT}` can contain a navbar, the site content, or a footer. +The `{SIDEBAR}` can contain a menu: +```html +
    +``` +To open and close the drawer, use a label whose `for` attribute matches the `drawer-toggle` input ID: +```html + +``` +Example: This sidebar is always visible on large screens. The user can toggle it on small screens: +```html +
    + +
    + + +
    +
    + + +
    +
    +``` + +Example: This sidebar is always visible. In the closed state, it shows only icons. In the open state, it shows icons and text: +```html +
    + +
    + +
    +
    + +
    + + + +
    + +
    +
    +
    +
    +``` + +#### Rules +- `{MODIFIER}` is optional. It can include one modifier class name and one placement class name. +- You must add an `id` to the `drawer-toggle` input. Change `my-drawer` to a unique HTML ID. +- To make the sidebar visible on larger screens, use `lg:drawer-open`. +- The `drawer-toggle` is a hidden checkbox. Use a label with a `for` attribute to change the checkbox state. +- To open the drawer with a button, use ``. The `my-drawer` value is the ID of the `drawer-toggle` input. +- When you use a drawer, put all page content in the `drawer-content` element. Put the navbar and footer inside the `drawer`. diff --git a/.agents/skills/daisyui/components/dropdown.md b/.agents/skills/daisyui/components/dropdown.md new file mode 100644 index 0000000..7cd2c27 --- /dev/null +++ b/.agents/skills/daisyui/components/dropdown.md @@ -0,0 +1,32 @@ +### Dropdown +A dropdown can open a menu or another element when the user clicks the button. + +[Dropdown documentation](https://daisyui.com/components/dropdown/) + +#### Class names +- component: `dropdown` +- part: `dropdown-content` +- placement: `dropdown-start`, `dropdown-center`, `dropdown-end`, `dropdown-top`, `dropdown-bottom`, `dropdown-left`, `dropdown-right` +- modifier: `dropdown-hover`, `dropdown-open`, `dropdown-close` + +#### Syntax + +Popover API: +```html + + +``` + +The `details` and `summary` elements open and close only when the user clicks them: +```html + +``` + +#### Rules +- `{MODIFIER}` is optional. It can include one modifier class name and one placement class name. +- Replace `{id}` and `{anchor}` with the same name. Do not use this name for another element. +- The content is not limited to `
      `. It can be a different HTML element. +- For the popover API method, use only a button and `dropdown`. Do not use `dropdown-content`. diff --git a/.agents/skills/daisyui/components/fab.md b/.agents/skills/daisyui/components/fab.md new file mode 100644 index 0000000..6dc5d1b --- /dev/null +++ b/.agents/skills/daisyui/components/fab.md @@ -0,0 +1,98 @@ +### FAB +A FAB is a floating action button that stays in a bottom corner of the screen. It contains a focusable, accessible element with a button role. When the user clicks or focuses it, more speed-dial buttons appear. These buttons have a vertical or quarter-circle arrangement. + +[FAB documentation](https://daisyui.com/components/fab/) + +#### Class names +- component: `fab` +- part: `fab-close`, `fab-main-action` +- modifier: `fab-flower` + +#### Syntax +One FAB in a screen corner: +```html +
      + +
      +``` +A FAB that opens three other buttons vertically in a page corner: +```html +
      +
      {IconOriginal}
      + + + +
      +``` +A FAB that opens three other buttons vertically in a page corner. Each button has label text: +```html +
      +
      {IconOriginal}
      +
      {Label1}
      +
      {Label2}
      +
      {Label3}
      +
      +``` +A FAB with rectangular buttons. These buttons can contain more content than circular buttons: +```html +
      +
      {IconOriginal}
      + + + +
      +``` +A FAB with a close button. When the FAB is open, the close button replaces the original button: +```html +
      +
      {IconOriginal}
      +
      Close ×
      +
      {Label1}
      +
      {Label2}
      +
      {Label3}
      +
      +``` +A FAB with a main-action button. When the FAB is open, the main-action button replaces the original button: +```html +
      +
      {IconOriginal}
      +
      + {LabelMainAction} +
      +
      {Label1}
      +
      {Label2}
      +
      {Label3}
      +
      +``` +A flower FAB. It opens the buttons in a quarter-circle arrangement instead of a vertical arrangement: +```html +
      +
      {IconOriginal}
      + + + + +
      +``` +A flower FAB with tooltips. A quarter circle has no space for a text label. Thus, each tooltip identifies the button function: +```html +
      +
      {IconOriginal}
      + +
      + +
      +
      + +
      +
      + +
      +
      +``` +#### Rules +- Replace `{Icon*}` with the applicable icon for each button. If possible, use SVG icons. +- Use `{IconOriginal}` for the icon that appears before the FAB opens. +- Use `{IconMainAction}` for the icon that appears after the FAB opens. +- Use `{Icon1}`, `{Icon2}`, and `{Icon3}` for the other button icons. +- Replace `{Label*}` with the label text for each button. diff --git a/.agents/skills/daisyui/components/fieldset.md b/.agents/skills/daisyui/components/fieldset.md new file mode 100644 index 0000000..b0a052e --- /dev/null +++ b/.agents/skills/daisyui/components/fieldset.md @@ -0,0 +1,20 @@ +### Fieldset +Use a fieldset as a container for related form elements. Use `fieldset-legend` as the title. Use `label` as the description. + +[Fieldset documentation](https://daisyui.com/components/fieldset/) + +#### Class names +- component: `fieldset`, `label` +- part: `fieldset-legend` + +#### Syntax +```html +
      + {title} + {CONTENT} +

      {description}

      +
      +``` + +#### Rules +- The fieldset can have all types of elements as direct children. diff --git a/.agents/skills/daisyui/components/file-input.md b/.agents/skills/daisyui/components/file-input.md new file mode 100644 index 0000000..2f36c70 --- /dev/null +++ b/.agents/skills/daisyui/components/file-input.md @@ -0,0 +1,18 @@ +### File input +Use a file input to upload files. + +[File input documentation](https://daisyui.com/components/file-input/) + +#### Class names +- component: `file-input` +- style: `file-input-ghost` +- color: `file-input-neutral`, `file-input-primary`, `file-input-secondary`, `file-input-accent`, `file-input-info`, `file-input-success`, `file-input-warning`, `file-input-error` +- size: `file-input-xs`, `file-input-sm`, `file-input-md`, `file-input-lg`, `file-input-xl` + +#### Syntax +```html + +``` + +#### Rules +- `{MODIFIER}` is optional. It can include one class name from each style, color, and size category. diff --git a/.agents/skills/daisyui/components/filter.md b/.agents/skills/daisyui/components/filter.md new file mode 100644 index 0000000..54d0dac --- /dev/null +++ b/.agents/skills/daisyui/components/filter.md @@ -0,0 +1,33 @@ +### Filter +A filter is a group of radio buttons. When the user selects an option, the filter hides the other options. It also shows a reset button next to the selected option. + +[Filter documentation](https://daisyui.com/components/filter/) + +#### Class names +- component: `filter` +- part: `filter-reset` + +#### Syntax +HTML form: +```html +
      + + + +
      +``` +No HTML form: +```html +
      + + + +
      +``` + +#### Rules +- Replace `{NAME}` with a value that identifies the filter. +- Use a different `name` attribute for each set of radio inputs. This prevents conflicts. +- If the context permits, use the `
      ` tag. If you cannot use an HTML form, use `
      `. +- Use the `filter-reset` class for the reset button. +- Do not select a radio input by default. diff --git a/.agents/skills/daisyui/components/footer.md b/.agents/skills/daisyui/components/footer.md new file mode 100644 index 0000000..4632a66 --- /dev/null +++ b/.agents/skills/daisyui/components/footer.md @@ -0,0 +1,21 @@ +### Footer +A footer can contain a logo, a copyright notice, and links to other pages. + +[Footer documentation](https://daisyui.com/components/footer/) + +#### Class names +- component: `footer` +- part: `footer-title` +- placement: `footer-center` +- direction: `footer-horizontal`, `footer-vertical` + +#### Syntax +```html +
      {CONTENT}
      +``` +The content can contain more than one `