Skip to content

Commit dee1e9a

Browse files
jmscheweaverryan
authored andcommitted
Add docs about creating UX bundles
1 parent c982784 commit dee1e9a

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed

frontend/create_ux_bundle.rst

+139
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
.. index::
2+
single: Create a UX bundle
3+
4+
Create a UX bundle
5+
==================
6+
7+
.. tip::
8+
9+
Before reading this, you may want to have a look at
10+
:doc:`Best Practices for Reusable Bundles </bundles/best_practices>`.
11+
12+
Here are a few tricks to make your bundle install as a UX bundle.
13+
14+
composer.json file
15+
------------------
16+
17+
Your ``composer.json`` file must have the ``symfony-ux`` keyword:
18+
19+
.. code-block:: json
20+
21+
{
22+
"keywords": ["symfony-ux"]
23+
}
24+
25+
Assets location
26+
---------------
27+
28+
Your assets must be located in one of the following directories, with a ``package.json`` file so Flex can handle it
29+
during install/update:
30+
31+
* ``/assets`` (recommended)
32+
* ``/Resources/assets``
33+
* ``/src/Resources/assets``
34+
35+
package.json file
36+
-----------------
37+
38+
Your ``package.json`` file must contain a ``symfony`` config with controllers defined, and also add required packages
39+
to the ``peerDependencies``:
40+
41+
.. code-block:: json
42+
43+
{
44+
"name": "@acme/feature",
45+
"version": "1.0.0",
46+
"symfony": {
47+
"controllers": {
48+
"slug": {
49+
"main": "dist/controller.js",
50+
"fetch": "eager",
51+
"enabled": true,
52+
"autoimport": {
53+
"dist/bootstrap4-theme.css": false,
54+
"dist/bootstrap5-theme.css": true
55+
}
56+
}
57+
}
58+
},
59+
"peerDependencies": {
60+
"@hotwired/stimulus": "^3.0.0",
61+
"slugify": "^1.6.5"
62+
}
63+
}
64+
65+
In this case, the file located at ``[assets directory]/dist/controller.js`` will be exposed.
66+
67+
.. tip::
68+
69+
You can either write raw JS in this ``dist/controller.js`` file, or you can e.g. write your controller with
70+
TypeScript and transpile it to JavaScript.
71+
72+
Here is an example to do so:
73+
74+
1. Add the following to your ``package.json`` file:
75+
76+
.. code-block:: json
77+
78+
{
79+
"scripts": {
80+
"build": "babel src --extensions .ts -d dist"
81+
},
82+
"devDependencies": {
83+
"@babel/cli": "^7.20.7",
84+
"@babel/core": "^7.20.12",
85+
"@babel/plugin-proposal-class-properties": "^7.18.6",
86+
"@babel/preset-env": "^7.20.2",
87+
"@babel/preset-typescript": "^7.18.6",
88+
"@hotwired/stimulus": "^3.2.1",
89+
"typescript": "^4.9.5"
90+
}
91+
}
92+
93+
2. Run either ``npm install`` or ``yarn install`` to install the new dependencies.
94+
95+
3. Write your Stimulus controller with TypeScript in ``src/controller.ts``.
96+
97+
4. Run ``npm run build`` or ``yarn run build`` to transpile your TypeScript controller into JavaScript.
98+
99+
To use your controller in a template (e.g. one defined in your bundle) you can use it like this:
100+
101+
.. code-block:: html+twig
102+
103+
<div
104+
{{ stimulus_controller('acme/feature/slug', { modal: 'my-value' }) }}
105+
{#
106+
will render:
107+
data-controller="acme--feature--slug"
108+
data-acme--feature--slug-modal-value="my-value"
109+
#}
110+
>
111+
...
112+
</div>
113+
114+
Don't forget to add ``symfony/webpack-encore-bundle:^1.12`` as a composer dependency to use
115+
Twig ``stimulus_*`` functions.
116+
117+
.. tip::
118+
119+
Controller Naming: In this example, the ``name`` of the PHP package is ``acme/feature`` and the name
120+
of the controller in ``package.json`` is ``slug``. So, the full controller name for Stimulus will be
121+
``acme--feature--slug``, though with the ``stimulus_controller()`` function, you can use ``acme/feature/slug``.
122+
123+
Each controller has a number of options in ``package.json`` file:
124+
125+
================== ====================================================================================================
126+
Option Description
127+
================== ====================================================================================================
128+
enabled Whether the controller should be enabled by default.
129+
main Path to the controller file.
130+
fetch How controller & dependencies are included when the page loads.
131+
Use ``eager`` (default) to make controller & dependencies included in the JavaScript that's
132+
downloaded when the page is loaded.
133+
Use ``lazy`` to make controller & dependencies isolated into a separate file and only downloaded
134+
asynchronously if (and when) the data-controller HTML appears on the page.
135+
autoimport List of files to be imported with the controller. Useful e.g. when there are several CSS styles
136+
depending on the frontend framework used (like Bootstrap 4 or 5, Tailwind CSS...).
137+
The value must be an object with files as keys, and a boolean as value for each file to set
138+
whether the file should be imported.
139+
================== ====================================================================================================

0 commit comments

Comments
 (0)