diff --git a/packages/unified-ui/lib/unified_ui/reference.ex b/packages/unified-ui/lib/unified_ui/reference.ex index 9a6ba59e..d41b4e9f 100644 --- a/packages/unified-ui/lib/unified_ui/reference.ex +++ b/packages/unified-ui/lib/unified_ui/reference.ex @@ -80,11 +80,6 @@ defmodule UnifiedUi.Reference do WidgetComponents.catalog() end - @spec widget_component_source_mapping() :: %{pos_integer() => map()} - def widget_component_source_mapping do - WidgetComponents.source_mapping() - end - @spec widget_component_aliases() :: %{atom() => atom()} def widget_component_aliases do WidgetComponents.aliases() diff --git a/packages/unified-ui/lib/unified_ui/tooling.ex b/packages/unified-ui/lib/unified_ui/tooling.ex index 8b36072b..76a4329b 100644 --- a/packages/unified-ui/lib/unified_ui/tooling.ex +++ b/packages/unified-ui/lib/unified_ui/tooling.ex @@ -117,8 +117,7 @@ defmodule UnifiedUi.Tooling do %{ families: WidgetComponents.component_families(), components: WidgetComponents.catalog(), - aliases: WidgetComponents.aliases(), - source_mapping: WidgetComponents.source_mapping() + aliases: WidgetComponents.aliases() } end diff --git a/packages/unified-ui/lib/unified_ui/widget_components.ex b/packages/unified-ui/lib/unified_ui/widget_components.ex index 5df729df..b349c710 100644 --- a/packages/unified-ui/lib/unified_ui/widget_components.ex +++ b/packages/unified-ui/lib/unified_ui/widget_components.ex @@ -2,9 +2,12 @@ defmodule UnifiedUi.WidgetComponents do @moduledoc """ Reference catalog for the canonical widget-component expansion. - The catalog records the AshUi PR 79-98 source mapping, portable canonical - names, semantic families, and compatibility aliases before the DSL entities - are implemented. + The catalog records portable canonical names, semantic families, and + compatibility aliases for widget kinds available in UnifiedUi. + + Schema is intentionally loose: a catalog entry needs only kind, family, + summary, and aliases. Provenance and PR tracking live in git history, + not in the runtime catalog (per Pascal Discord 2026-05-16). """ @type family :: @@ -19,17 +22,10 @@ defmodule UnifiedUi.WidgetComponents do @type component :: %{ required(:kind) => atom(), required(:family) => family(), - required(:source) => source(), required(:summary) => String.t(), required(:aliases) => [atom()] } - @type source :: %{ - required(:system) => :ash_ui, - required(:pr) => pos_integer(), - required(:name) => atom() - } - @type name_diagnostic :: %{ required(:status) => :canonical | :alias | :unknown, required(:name) => atom() | String.t(), @@ -52,119 +48,102 @@ defmodule UnifiedUi.WidgetComponents do %{ kind: :inline_rich_text_heading, family: :content_identity_and_disclosure, - source: %{system: :ash_ui, pr: 79, name: :inline_rich_text_heading}, summary: "Semantic heading with inline text and emphasis segments.", aliases: [] }, %{ kind: :disclosure, family: :content_identity_and_disclosure, - source: %{system: :ash_ui, pr: 80, name: :disclosure}, summary: "Progressive disclosure region with summary, open state, and body children.", aliases: [] }, %{ kind: :runtime_form_shell, family: :form_control_and_composer, - source: %{system: :ash_ui, pr: 81, name: :phoenix_form}, summary: "Portable form shell whose runtime-owned form state is supplied by the host.", aliases: [:phoenix_form] }, %{ kind: :kicker, family: :content_identity_and_disclosure, - source: %{system: :ash_ui, pr: 82, name: :kicker}, summary: "Eyebrow label cluster with ordered items and separator behavior.", aliases: [] }, %{ kind: :avatar, family: :content_identity_and_disclosure, - source: %{system: :ash_ui, pr: 83, name: :avatar}, summary: "Identity display using initials or image source with size, shape, and variant.", aliases: [] }, %{ kind: :presence_dot, family: :content_identity_and_disclosure, - source: %{system: :ash_ui, pr: 84, name: :presence_dot}, summary: "Small state-driven status indicator with size and accessibility metadata.", aliases: [] }, %{ kind: :segmented_button_group, family: :form_control_and_composer, - source: %{system: :ash_ui, pr: 85, name: :segmented_button_group}, summary: "Single-selection segmented control with option values and labels.", aliases: [] }, %{ kind: :list_item_multi_column, family: :row_and_artifact, - source: %{system: :ash_ui, pr: 86, name: :list_item_multi_column}, summary: "Selectable or linkable multi-column row with child cell content.", aliases: [] }, %{ kind: :artifact_row, family: :row_and_artifact, - source: %{system: :ash_ui, pr: 87, name: :artifact_row}, summary: "Artifact row with title, meta text, row identity, and trailing content.", aliases: [] }, %{ kind: :sticky_frosted_header, family: :layer_shell_and_callout, - source: %{system: :ash_ui, pr: 88, name: :sticky_frosted_header}, summary: "Sticky shell header with leading, title, and trailing child positions.", aliases: [] }, %{ kind: :pipeline_stepper_horizontal, family: :workflow_progress_and_status, - source: %{system: :ash_ui, pr: 89, name: :pipeline_stepper_horizontal}, summary: "Horizontal workflow stepper with done, active, and pending step state.", aliases: [] }, %{ kind: :segmented_progress_bar, family: :workflow_progress_and_status, - source: %{system: :ash_ui, pr: 90, name: :segmented_progress_bar}, summary: "Weighted multi-segment progress bar with per-segment state.", aliases: [] }, %{ kind: :workflow_stage_list_vertical, family: :workflow_progress_and_status, - source: %{system: :ash_ui, pr: 91, name: :workflow_stage_list_vertical}, summary: "Vertical numbered workflow stage list with connector state.", aliases: [] }, %{ kind: :meter_thin, family: :workflow_progress_and_status, - source: %{system: :ash_ui, pr: 92, name: :meter_thin}, summary: "Compact progress meter with normalized value and optional label.", aliases: [] }, %{ kind: :slide_over_panel, family: :layer_shell_and_callout, - source: %{system: :ash_ui, pr: 93, name: :slide_over_panel}, summary: "Non-modal contextual side panel with open state, size, and children.", aliases: [] }, %{ kind: :event_callout, family: :layer_shell_and_callout, - source: %{system: :ash_ui, pr: 94, name: :event_callout}, summary: "Inline stream or status callout with tone, eyebrow, body, and action content.", aliases: [] }, %{ kind: :redline_inline, family: :redline_and_code, - source: %{system: :ash_ui, pr: 95, name: :redline_inline}, summary: "Inline redline text display with keep, insert, delete, accepted, and rejected state.", aliases: [] @@ -172,21 +151,18 @@ defmodule UnifiedUi.WidgetComponents do %{ kind: :code_block_syntax_highlighted, family: :redline_and_code, - source: %{system: :ash_ui, pr: 96, name: :code_block_syntax_highlighted}, summary: "Pre-tokenized code block display with language and semantic token types.", aliases: [] }, %{ kind: :chat_composer, family: :form_control_and_composer, - source: %{system: :ash_ui, pr: 97, name: :chat_composer}, summary: "Multi-line composer with tool area, send intent, and change intent.", aliases: [] }, %{ kind: :list_repeat, family: :composition_behavior, - source: %{system: :ash_ui, pr: 98, name: :ui_relationship_repeat}, summary: "Composition behavior that repeats a child template over rows from a list binding.", aliases: [:ui_relationship_repeat, :repeat] @@ -329,21 +305,6 @@ defmodule UnifiedUi.WidgetComponents do Enum.filter(@components, &(&1.family == family)) end - @spec source_mapping() :: %{pos_integer() => map()} - def source_mapping do - Map.new(@components, fn component -> - source = component.source - - {source.pr, - %{ - source_name: source.name, - canonical_kind: component.kind, - family: component.family, - aliases: component.aliases - }} - end) - end - defp normalize_name(name) when is_atom(name), do: name defp normalize_name(name) when is_binary(name) do diff --git a/packages/unified-ui/test/unified_ui/widget_components_catalog_test.exs b/packages/unified-ui/test/unified_ui/widget_components_catalog_test.exs index 6d225937..31f96ee1 100644 --- a/packages/unified-ui/test/unified_ui/widget_components_catalog_test.exs +++ b/packages/unified-ui/test/unified_ui/widget_components_catalog_test.exs @@ -44,17 +44,6 @@ defmodule UnifiedUi.WidgetComponentsCatalogTest do } end - test "source mapping records every AshUi PR in order" do - source_mapping = WidgetComponents.source_mapping() - - assert Map.keys(source_mapping) == Enum.to_list(79..98) - assert source_mapping[79].canonical_kind == :inline_rich_text_heading - assert source_mapping[81].source_name == :phoenix_form - assert source_mapping[81].canonical_kind == :runtime_form_shell - assert source_mapping[98].source_name == :ui_relationship_repeat - assert source_mapping[98].canonical_kind == :list_repeat - end - test "canonical name lookup accepts AshUi aliases with diagnostics" do assert WidgetComponents.canonical_kind(:runtime_form_shell) == {:ok, :runtime_form_shell} assert WidgetComponents.canonical_kind("runtime_form_shell") == {:ok, :runtime_form_shell} @@ -94,13 +83,9 @@ defmodule UnifiedUi.WidgetComponentsCatalogTest do assert UnifiedUi.Reference.widget_component_families() == WidgetComponents.component_families() - assert UnifiedUi.Reference.widget_component_source_mapping()[98].canonical_kind == - :list_repeat - tooling_catalog = UnifiedUi.Tooling.widget_component_catalog() assert tooling_catalog.families == WidgetComponents.component_families() assert tooling_catalog.aliases == WidgetComponents.aliases() - assert tooling_catalog.source_mapping[81].canonical_kind == :runtime_form_shell end end