From 14bc697f5e1bfb82c194872775293f3d2e53d5cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tao=20Bojl=C3=A9n?= Date: Sat, 20 Jun 2026 00:58:46 +0100 Subject: [PATCH] feat(button): colocated nova/vega styles (pilot vertical slice) - button.ex: marker + data-slot/variant/size; styling moved to colocated CSS. - priv/styles/{nova,vega}/button.css: verbatim ports (adds xs/icon-xs/sm/lg sizes). - gen.registry: reject components with >1 marker (guards moduledoc mentions). - Update registry/add tests + doctest to button's colocated_css dep + injection. Co-Authored-By: Claude Opus 4.8 (1M context) --- lib/mix/tasks/shadix.gen.registry.ex | 25 +++++++-- lib/shadix/components/button.ex | 49 +++++------------ lib/shadix/registry.ex | 4 +- priv/registry/button.json | 11 +++- priv/styles/nova/button.css | 61 +++++++++++++++++++++ priv/styles/vega/button.css | 61 +++++++++++++++++++++ test/mix/tasks/shadix_add_test.exs | 38 ++++++++++--- test/mix/tasks/shadix_gen_registry_test.exs | 6 +- test/shadix/components/button_test.exs | 27 +++++---- test/shadix/registry_test.exs | 4 +- 10 files changed, 215 insertions(+), 71 deletions(-) create mode 100644 priv/styles/nova/button.css create mode 100644 priv/styles/vega/button.css diff --git a/lib/mix/tasks/shadix.gen.registry.ex b/lib/mix/tasks/shadix.gen.registry.ex index 7bc1b8a..0c6bb25 100644 --- a/lib/mix/tasks/shadix.gen.registry.ex +++ b/lib/mix/tasks/shadix.gen.registry.ex @@ -88,15 +88,28 @@ defmodule Mix.Tasks.Shadix.Gen.Registry do "hooks" => hooks } - if String.contains?(content, @marker) do - base - |> Map.put("default_style", "nova") - |> Map.put("styles", styles_for(name)) - else - base + case marker_count(content) do + 0 -> + base + + 1 -> + base + |> Map.put("default_style", "nova") + |> Map.put("styles", styles_for(name)) + + n -> + Mix.raise( + "Component #{name} contains the colocated-css marker #{n} times; it must appear " <> + "exactly once (the first node of the template). Remove other occurrences " <> + "(e.g. from the @moduledoc)." + ) end end + defp marker_count(content) do + content |> String.split(@marker) |> length() |> Kernel.-(1) + end + # Reads `priv/styles/