Corex Design

View Source

Package: 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 wantCommand
New app with design (default)mix corex.new my_app
New app without designmix corex.new my_app --no-design
Regenerate design assetsmix 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

  1. Add the dependency and config (see Manual installation).
  2. Add /assets/corex/ to .gitignore (generated output; rebuild with mix corex.design.build).
  3. 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):

KeyDefaultEffect
componentsnil (all)Emit only listed component recipe files
semanticsnil (all)Emit only listed palette roles (roles filtered by semantics); trims unused ui-{role} utilities
themesnil (all presets)Emit only listed theme CSS (neo, uno, duo, leo)
default_theme:uno if omittedTheme 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:lightBuild default mode (:light / :dark)
accessibilityfalsePreference 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: :light

Use 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.

  1. Point Tailwind at the generated tree (Phoenix 1.8+ example):
@source "../corex";
  1. 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.css before 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):

AxisExamplesEffect
Semanticui-accent, ui-successPalette CSS variables on the host
Variantui-solid (subtle is default)Surface treatment
Sizeui-size-sm, ui-size-lgSpacing, control height, and font size
Radiusui-rounded-xlCorner 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
  • Themingdata-theme and theme picker
  • Dark modedata-mode and mode toggle
  • Accessibility: optional preference axes and panel wiring
  • Component Hexdocs — anatomy, API, and per-component Design examples