A Mix Task for generating a JSON file from a directory of components
This Mix Task helps you generate a JSON file from the files in a directory,
enabling you to use it with mix mishka.ui.add or share it in the community version.
Keep in mind that for each component, you must have both .eex and .exs files according to the
documentation of the Mishka Chelekom library.
Otherwise, you will need to create the necessary files manually.
It’s recommended to review the Core components and follow their structure as a guide.
If you prefer to perform the process manually, simply add the relevant option to your command to generate a template file. You can then customize it based on your specific requirements.
Note:
Use
--base64option to convert the file content to Base64 if you're using special Erlang characters that do not retain their original form when converted back to the original file.
Note:
It is important to note that to place each file in its designated section and specify its type, you must use the following naming convention:
For example, if your file is a component, you need to have two files:
component_something.exscomponent_something.eex
Similarly, for other file types like preset and template, you should follow the same
naming pattern as above. For instance:
template_something.exstemplate_something.eex
All files within the directory do not need to have the same name. However,
they must start with the section name where they are intended to be placed, such as
component, preset, or template. Additionally, each file must have both the
exs and eex formats.
Note: Since JavaScript files do not require configuration, you only need to place the file in the directory. For example:
something.js
What Should the Configuration of Each Component Look Like?
If you take a look at the example configuration below, you'll notice that the component file name matches the key name in the list, which also matches the configuration name. This ensures consistency and makes it easier to work with the component configuration.
File name: component_accordion.eex and component_accordion.exs
[
component_accordion: [
name: "component_accordion",
args: [...]
...
]
]Note: you can name this like preset_accordion or template_accordion too.
Example
mix mishka.ui.export --example arg
Export the built-in styled components as a MishkaCMS UI-kit bundle:
mix mishka.ui.export priv/components --cms --name chelekom --bundle-name chelekom --bundle-version 0.0.9
Export the headless Kit components as a MishkaCMS UI-kit bundle:
mix mishka.ui.export priv/headless --cms --name chelekom_headless --bundle-name chelekom_headless --bundle-version 0.0.9
Options
--base64or-b- Converts component content to Base64--nameor-n- Defines a name for JSON file, if it is not set default is template.json--orgor-o- It is only for structuring the file and has no effect on your export.--templateor-t- Creates a default JSON file for manual processing steps.--cms- Exports a MishkaCMS UI-kit bundle (mishka.ui_kit.bundle.v3) instead of the default JSON.--bundle-name- Sets the bundle name in--cmsoutput (defaults to the--namevalue).--bundle-version- Sets the bundle version in--cmsoutput (defaults to0.0.1).
What a component's .exs can say to the consuming CMS
Beside necessary — which names the OTHER components this one draws through — three keys describe
what the CMS must do with this component itself. All are optional and all default to false, so a
.exs written before they existed keeps its meaning exactly.
required: true # the CMS cannot run without it; its installer may not let it be deselected
precompile: true # build its CSS whether or not a page names it
stateful: true # install it as a Phoenix.LiveComponent, not a function componentprecompile exists because a consuming CMS builds a site's stylesheet from the components its
pages REFERENCE, and a component reached through helper code or the host's own markup is invisible
to that walk. Saying so here is the only way it can be known.
priv/components/icon.exs is the example: 49 of this kit's components declare it necessary, so
deselecting it would leave a third of the kit unable to draw.
What a component's .exs says to its docs page
Every .exs in priv/components, priv/headless and priv/mob ends with a docs: block: the
facts its page on mishka.tools shows as badges. They are declared by hand, not read from the code,
so a new component fills in all four, each true or false:
docs: [stateful: false, js_module: true, js: false, accessible: false]stateful— it is aPhoenix.LiveComponent("Stateful";falseshows "Stateless")js_module— it uses LiveView'sPhoenix.LiveView.JSat least once ("JS-module")js— it uses a JS hook: it draws aphx-hookor shipsscripts("JS")accessible— it has been reviewed accessible ("Accessible"); every headless one is
Neither export carries the block and no generator reads it, so it changes nothing in a bundle or
a generated file. Its stateful describes the component; the top-level stateful: true above is
what makes the CMS install it as a live component.
Shipping a live component
A stateful component gets an id, assigns of its own that survive the hosting page's re-renders,
and handle_event/3 aimed at itself rather than at the page. Write its .eex as a
Phoenix.LiveComponent module — one render/1 carrying the ~H, with mount/1, update/2 and
handle_event/3 beside it — and the exporter names the row after the .exs's own name instead
of after render, which every one of them would otherwise be called.
Three shapes the exporter refuses, because the consuming CMS refuses them too:
- more than one public component in the file — a live component IS its module
- a dispatching
defwith several clauses — each clause has its own root element, and a live component may have exactly one - an
attrnameduploads,streams,socketormyself— LiveView assigns those itself
Say it in the .exs. use Phoenix.LiveComponent in the .eex on its own is a warning and not a
declaration: the bundle carries what the config says.