phil / ux-kit
PHIL UX kit for the Symfony UX Toolkit: the same recipes as the Shadcn kit, styled with phil-ux, installed with ux:install --kit; with the Twig functions its image recipes call, image_origin() and image_sources()
Package info
github.com/parler-haut-interagir-librement/ux-kit
Type:symfony-bundle
pkg:composer/phil/ux-kit
Requires
- php: >=8.5
- ext-mbstring: *
- phil/url: ^0.1.3@dev
- psr/log: ^3.0
- symfony/config: ^8.2
- symfony/dependency-injection: ^8.2
- symfony/http-foundation: ^8.2
- symfony/http-kernel: ^8.2
- twig/twig: ^3.21
Requires (Dev)
- phil/qr-code-bundle: ^0.1@dev
- php-webdriver/webdriver: ^1.16
- phpunit/phpunit: ^13.4
- psr/container: ^2.0
- psr/link: ^2.0
- symfony/asset: ^8.2
- symfony/asset-mapper: ^8.2
- symfony/framework-bundle: ^8.2
- symfony/panther: ^2.4
- symfony/twig-bundle: ^8.2
- symfony/ux-twig-component: ^3.7
- symfony/web-link: ^8.2
- twig/extra-bundle: ^3.24
- twig/html-extra: ^3.24
Suggests
- php-webdriver/webdriver: To extend the browser test case of src/Test/
- phpunit/phpunit: To extend the browser test case of src/Test/
- symfony/asset-mapper: For image_sources(), the props of a picture from the files of an image among the assets
- symfony/panther: To extend the browser test case of src/Test/
- symfony/web-link: For the preload of the main image of a page, which the image recipe requires
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-12 03:08:47 UTC
README
PHIL UX kit for the Symfony UX Toolkit: the same recipes as the Shadcn kit, styled with phil-ux, installed with
ux:install --kit.
The kit is a directory of recipes laid out as the Symfony UX Toolkit expects, its manifest.json at the root. Each
recipe is a Twig component — and its Stimulus controller when it moves —, which ux:install copies into the
application, where it becomes the application's own code. The look comes from phil-ux, the stylesheet of
phil/ux-css, on which every recipe depends; the recipes
bring only their Twig and their Stimulus.
The kit takes the recipe names, props, blocks and Stimulus controllers of the Shadcn kit, so that a bundle works with
either kit, and adds recipes of its own. Their Tailwind versions, under the same names and props, are the kit
phil/ux-kit-shadcn.
Status
| Recipe | Type | What it is | Status |
|---|---|---|---|
| Logo | component | A Picture with its AVIF and WebP sources and its densities, its variants for forced colours, dark systems and reduced motion, swapped by theme or locale, linked home; alt required |
Implemented and tested |
| AnimatedHeadline | component | A headline whose words are revealed through a clip, played through once, or cycled with a pause button; still under reduced motion; read whole by screen readers | Implemented and tested |
| Illustration | component | A figure showing one picture chosen among candidates on the server, by a seedable random | Implemented and tested |
| Image | component | An image of the content, Image or Picture with its AVIF and WebP sources, by density or by width, under the prop names of Symfony UX Image: the main image preloaded through WebLink, fetchpriority="low" for one far below, a placeholder colour of the tokens, an optional blurred preview, variants for forced colours, dark systems and reduced motion, a long description, credit, license and creation, the images of other hosts refused unless listed, image_sources() on AssetMapper, warnings in development for a text alternative left wrong; no inline style |
Implemented and tested |
| Gallery | component | A list of figures in a grid that follows its container, each image opened in a Lightbox when asked; a long gallery rendered as it comes near, with content-visibility |
Implemented and tested |
| Lightbox | component | An image enlarged in a native modal dialog, opened by the invokers of HTML, the lightbox controller standing in where the browser does not run them |
Implemented and tested |
| AutosaveStatus | component | The live region and the notice of a form's draft, for the autosave controller of phil/forms-autosave |
Implemented and tested |
| ReactionButton | component | One reaction of phil/reactions-bundle: a button that says it is pressed, or plain text; a target wide and tall enough for a finger |
Implemented and tested |
| ReactionPicker | component | The other reactions of phil/reactions-bundle: a disclosure of plain buttons, for the picker controller of the bundle |
Implemented and tested |
| ComingSoon | block | A full-height split page: logo, eyebrow, animated headline, paragraphs, illustration; stacked on small screens | Implemented and tested |
| Badge | component | A short label: a tag, a status, a count. | Implemented and tested |
| Button | component | A button, or a link that looks like one with as="a". |
Implemented and tested |
| ButtonGroup | component | Buttons that belong together, joined: a view switcher, the previous and next periods. | Implemented and tested |
| Card | component | A card: its picture, a header, its content and a footer. | Implemented and tested |
| Empty | component | What a list shows when it has nothing: a picture, a title, a sentence, and what to do. | Implemented and tested |
| Popover | component | A panel opened by a button, on the HTML popover API: it opens and closes, Escape and a click outside close it, without JavaScript; the controller places it next to its button. | Implemented and tested |
| QrCode | component | A QR code in a figure, with what it holds written beside it, a link for a web address, drawn on the server by phil/qr-code-bundle. |
Implemented and tested |
| Tabs | component | Tabs over panels. Without JavaScript every panel shows; with it, one at a time, the arrows, Home and End moving between the tabs. | Implemented and tested |
| Accordion | component | Sections that open and close, on details and summary: they work without JavaScript, the browser keeping one open at a time; the controller adds the arrows, Home and End. |
Implemented and tested |
| Dialog | component | A modal window, on the native dialog element and its invokers: the browser makes the page inert, keeps the focus inside, closes it on Escape and gives the focus back. |
Implemented and tested |
| Sheet | component | A panel sliding from an edge of the screen: a Dialog that keeps to one side, with the same controller. |
Implemented and tested |
| Switch | component | An on and off control: a checkbox with the role switch, which the browser checks and submits without JavaScript. |
Implemented and tested |
| Tooltip | component | A short description of a control, shown on hover and focus: it can be hovered, stays until left, and Escape dismisses it (WCAG 1.4.13). | Implemented and tested |
| Pagination | component | The links between the pages of a list. | Implemented and tested |
| Carousel | component | Slides in a row, on native scroll snapping: they scroll by touch, trackpad and keyboard without JavaScript; the controller adds the buttons, the arrows and, on request, the automatic play. ::scroll-button() being in one engine alone, the buttons do not rely on it. |
Implemented and tested |
| Spinner | component | What shows while something loads; phil-ux stills it under prefers-reduced-motion. |
Implemented and tested |
| Skeleton | component | A placeholder for content on its way, hidden from screen readers; phil-ux stills it under prefers-reduced-motion. |
Implemented and tested |
| Alert | component | A message that stands out: an error, a confirmation. | Implemented and tested |
| Avatar | component | The picture of a person, over the initials that show when it is missing or broken, without script. | Implemented and tested |
| Input | component | A text field; any attribute reaches the element. | Implemented and tested |
| Label | component | The name of a form control. | Implemented and tested |
| Select | component | A list of options to choose one from, submitted as a field of the form when it has a name. For a page without JavaScript, the select element is styled by phil-ux on its own. |
Implemented and tested |
| Separator | component | A line between two parts of a page. | Implemented and tested |
| Textarea | component | A field of several lines. | Implemented and tested |
| Checkbox | component | A checkbox, drawn by phil-ux. | Implemented and tested |
| Breadcrumb | component | Where the page sits in the site. | Implemented and tested |
| DropdownMenu | component | A menu of actions opened by a button, on the popover API: Escape and a click outside close it and the focus goes back to the button. | Implemented and tested |
| Table | component | A table of data, which scrolls sideways inside its own box on a small screen. | Implemented and tested |
| AlertDialog | component | A question in a modal window: Escape dismisses it, a click outside does not, the focus starts on the harmless answer. | Implemented and tested |
| AspectRatio | component | A box kept to a ratio, its picture or video covering it. | Implemented and tested |
| Collapsible | component | A part of the page that opens and closes, on details and summary, without JavaScript. |
Implemented and tested |
| Field | component | A form field — label, control, help, errors — and sets of fields under a legend. | Implemented and tested |
| Item | component | One entry of a list: its media, its title and description, its actions. | Implemented and tested |
| Kbd | component | A key of the keyboard, or the keys of a shortcut, on kbd. |
Implemented and tested |
| NativeSelect | component | The select element of the browser, dressed by phil-ux. |
Implemented and tested |
| Progress | component | The progress of a task, on the native progress element. |
Implemented and tested |
| RadioGroup | component | Radio buttons sharing a name, which the browser moves between with the arrows. | Implemented and tested |
| ScrollArea | component | A box whose content scrolls inside it, a region the keyboard reaches when named. | Implemented and tested |
| Toggle | component | A button that stays pressed, on a checkbox inside its label, without JavaScript. | Implemented and tested |
| ToggleGroup | component | Toggles that belong together, on radio buttons or checkboxes, without JavaScript. | Implemented and tested |
| LoginForm | block | A sign-in form in a card, for the form login of Symfony Security. | Implemented and tested |
| SignupForm | block | A sign-up form in a card, each field naming its errors, a password never written back. | Implemented and tested |
| ColorPicker | component | The colour well of the browser, its hexadecimal value and swatches to choose from. The well is the field: it works alone without a script. | Implemented and tested |
| DatePicker | component | The date field of the browser, which works alone, and a button opening a month on a grid, in a popover. | Implemented and tested |
| CopyButton | component | A button that copies a text, given or read from another element, and says so. | Implemented and tested |
| AnimatedButton | component | A button, or a link when it has an address, that moves under the pointer and the focus: a light sweeping across it, a lift or its arrow pushed forward. Pure CSS. | Implemented and tested |
| Stepper | component | The steps of a process, the finished ones marked, the current one announced, reading downwards on a phone. | Implemented and tested |
| ActivityCalendar | component | Activity over time: a cell per day, each read through its label, the colour never standing alone. Wider than the screen, it scrolls by itself and takes the focus to do so. | Implemented and tested |
| Tree | component | A tree of items, on the WAI-ARIA pattern. | Implemented and tested |
| Rating | component | A note out of a number of stars: radio buttons with a name, a single image without one, in half stars. | Implemented and tested |
| NumberInput | component | A number field with a button on each side. | Implemented and tested |
| FileInput | component | A file field that also takes a drop, listing what it holds with the size of each. | Implemented and tested |
| Tag | component | A short label, which a button can take away. | Implemented and tested |
| RelativeTime | component | A moment written by the server as a date, then by a script as the time from now, which it keeps right. | Implemented and tested |
| ProgressRing | component | Progress as a ring, with the percentage in its centre. Pure CSS and SVG. | Implemented and tested |
| Sparkline | component | A small line of values, drawn by the server. | Implemented and tested |
| BeforeAfter | component | Two pictures one above the other, the first cut where a slider says. | Implemented and tested |
| Chart | component | A chart drawn by the server in SVG, bars or lines, with the table of its values. | Implemented and tested |
| ChartJs | component | A chart of Symfony UX Chart.js in a figure, with its caption and the table of its values. | Implemented and tested |
Documentation
| Document | What it covers |
|---|---|
| Installation | ux:install from the public repository, the files to copy until then, the stylesheet. |
| Recipes | Each recipe, its props, blocks and controller. |
| A coming soon page | A whole page built from the ComingSoon block. |
| Extension points | What an application changes, and how. |
| Testing | How the kit is tested. |
| Reference | Every file of the kit. |
Quick start
php bin/console ux:install coming-soon --kit=github.com/parler-haut-interagir-librement/ux-kit
<twig:ComingSoon logoSrc="{{ asset('images/logo.svg') }}" logoAlt="Studio" eyebrow="{{ 'coming_soon'|trans }}" words="Studio" :paragraphs="['site.info'|trans]" :illustrations="[asset('images/main.png')]" illustrationAlt="" />
Requirements
Symfony UX Twig Component 3.7 or later; Symfony UX Toolkit 3.7 or later to install the recipes; the StimulusBundle for
the recipes that move and the blurred preview of Image; twig/extra-bundle, twig/html-extra, symfony/web-link
and the bundle of this package for Image, which lists the hosts whose images a page may show; phil/qr-code-bundle
for QrCode; Symfony UX Chart.js for ChartJs; the phil-ux stylesheet of phil/ux-css.
Contributing
Contributions are welcome on the PHIL monorepo: read the contribution guide and the code of conduct. Report a vulnerability privately, as the security policy explains, never in a public issue.
License
MIT, © Philippe Gamache, doing business as Le Gnome Archiviste; a Parler Haut Interagir Librement project. See LICENSE.