Corex Design
View SourcePackage: corex_design. This guide is published on corex Hexdocs (full app wiring). The design package docs cover install, config, and build.
Corex components work without any bundled CSS. You style them with your own rules, usually by targeting data-scope and data-part on the rendered markup (each component’s Hexdocs page lists those selectors).
Corex Design is optional: token-based CSS, ready-made themes, and modifier classes such as ui-accent or ui-size-lg. Generated apps with --design (the default) add the corex_design Hex package and build CSS into assets/corex/.
Commands
| What you want | Command |
|---|---|
| New app with design (default) | mix corex.new my_app |
| New app without design | mix corex.new my_app --no-design |
| Regenerate design assets | mix corex.design.build |
List valid config values (components, semantics, themes, …) | mix corex.design.options |
| Build app assets (includes design) | mix assets.build |
mix corex.new adds {:corex_design, ...}, config :corex_design in config/config.exs, patches assets.build / assets.deploy to run corex.design.build, and adds /assets/corex/ to .gitignore. Output lands in assets/corex/ (generated; do not commit it).
Related installer flags (all imply design): --mode (light/dark), --theme (neo, uno, duo, leo). See Dark mode and Theming.
Setup in an existing app
- Add the dependency and config (see Manual installation).
- Add
/assets/corex/to.gitignore(generated output; rebuild withmix corex.design.build). - Import Corex Design in
assets/css/app.css. Prefer the single umbrella entry:
@import "../corex/corex.css";Layered imports still work when you need finer control:
@import "../corex/main.css";
@import "../corex/theme/neo.css";
@import "../corex/components.css";components.css is generated by mix corex.design.build from the components: list in config :corex_design. Adjust that list to trim the bundle; do not @import individual components/<name>.css files in app CSS.
Bundle filtering
In config/config.exs, keys under config :corex_design control the build-time CSS tree (not the runtime picker):
| Key | Default | Effect |
|---|---|---|
components | nil (all) | Emit only listed component recipe files |
semantics | nil (all) | Emit only listed palette roles (roles filtered by semantics); trims unused ui-{role} utilities |
themes | nil (all presets) | Emit only listed theme CSS (neo, uno, duo, leo) |
default_theme | :uno if omitted | Theme id used when CSS loads with no data-theme. New apps from mix corex.new set default_theme: :neo (and themes: [:neo]). Pass --theme to scaffold every preset. |
default_mode | :light | Build default mode (:light / :dark) |
accessibility | false | Preference CSS: false, true (all six axes), or [:text, :contrast, …] |
Run mix corex.design.options to print allowed values and your current resolved config.
components: ~w(button dialog accordion typo layout-heading)a,
semantics: ~w(accent brand alert)a,
themes: ~w(neo uno)a,
default_theme: :neo,
default_mode: :lightUse top-level semantics: to filter palette roles. scales: is only for numeric step overrides.
Runtime pickers use config :my_app, :themes (and cookies / localStorage). Keep that list a subset of what you emit here. See Theming, Dark mode, Accessibility, and Configuration.
- Point Tailwind at the generated tree (Phoenix 1.8+ example):
@source "../corex";- Set theme and mode on
<html>and base classes on<body>:
<html lang="en" data-theme="neo" data-mode="light">
<body class="typo">
{@inner_content}
</body>
</html>Use a data-theme value that matches a theme file you imported (neo, uno, duo, leo). See Theming and Dark mode for pickers and persistence.
Fonts (optional)
Corex Design does not ship @font-face files. Theme CSS sets stacks (--font-*) under [data-theme]; @theme registration makes them available to .typo and components.
- neo uses system fonts; no web font import is required.
- For uno, duo, leo, or a picker that switches among all four themes, load web fonts in
app.cssbefore Tailwind / Corex:
@import url('https://fonts.googleapis.com/css2?family=DM+Sans:ital,wght@0,300..900;1,300..900&family=IBM+Plex+Mono:ital,wght@0,400;0,500;0,600;0,700;1,400&family=IBM+Plex+Sans:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400&family=JetBrains+Mono:ital,wght@0,400..800;1,400..800&family=Playfair+Display:ital,wght@0,400..900;1,400..900&family=Work+Sans:ital,wght@0,300..900;1,300..900&display=swap');
@import "../corex/corex.css";That import covers DM Sans and JetBrains Mono (uno), Work Sans and Playfair Display (duo), and IBM Plex Sans/Mono (leo). Self-hosting the same families is fine.
If app.css still loads daisyUI from stock phx.new, remove it when using Corex Design—the two token systems conflict.
For Esbuild, hooks, and use Corex, follow Manual installation.
Modifier classes
Each styled component has a root class with the same name as the component (accordion, button, dialog, …). Stack shared modifier classes on the host:
<root> ui-<role> ui-solid ui-size-<step> ui-rounded-<step>Example:
<.accordion
id="faq"
class="accordion ui-accent ui-size-lg ui-rounded-lg"
items={Corex.Content.new([
[value: "lorem", label: "Lorem", content: "Lorem panel content."],
[value: "duis", label: "Duis", content: "Duis panel content."],
[value: "donec", label: "Donec", content: "Donec panel content."]
])}
/>Common modifier axes (not every component has every axis—check that component’s Hexdocs Style section):
| Axis | Examples | Effect |
|---|---|---|
| Semantic | ui-accent, ui-success | Palette CSS variables on the host |
| Variant | ui-solid (subtle is default) | Surface treatment |
| Size | ui-size-sm, ui-size-lg | Spacing, control height, and font size |
| Radius | ui-rounded-xl | Corner radius |
Semantic and variant axes combine: button ui-accent ui-solid. Semantic sets palette variables; ui-solid applies filled surface treatment.
See the modifier guide for the full axis system. Stack modifiers on the root class attribute. Do not invent new class names; use only shared ui-* modifiers and component-specific layout classes documented for that component.
Tokens and themes
After mix corex.design.build, CSS and tokens live under assets/corex/. Theme files switch palettes when both data-theme and data-mode are set on <html>.
Prefer modifier classes on Corex components and Tailwind utilities that map to the same tokens (text-ink, bg-surface, gap-space-lg, rounded-xl) in layout markup. Avoid overriding CSS variables in templates.
Icons
Inside Corex components (or their slots), use bare heroicons—parent CSS sizes them:
<.heroicon name="hero-chevron-down" />Avoid extra class on <.heroicon> when it sits inside another Corex component.
Without Corex Design
Use mix corex.new my_app --no-design, or skip the corex_design dependency in manual installs. Generated apps copy a static neo/light Design export into assets/corex/ (same layout as a live build: corex.css, tokens, components) and import it from app.css (or Tableau site.css). Edit or delete that folder to bring your own CSS. Component behavior and the LiveView/JS API are unchanged.
--mode, --theme, and --a11y require Design (corex_design); they cannot combine with --no-design. --lang is allowed with --no-design.
For a manual install without Design, either use mix corex.new --no-design or add corex_design and run mix corex.design.build with a neo/light config, then import ../corex/corex.css. The static snapshot is installer-only (not shipped in the :corex Hex package).
See also
- Manual installation — Esbuild, hooks, optional toast layout
- Theming —
data-themeand theme picker - Dark mode —
data-modeand mode toggle - Accessibility: optional preference axes and panel wiring
- Component Hexdocs — anatomy, API, and per-component Design examples