defmodule Corex do @moduledoc false @components %{ accordion: {Corex.Accordion, [accordion: 1, accordion_skeleton: 1]}, action: {Corex.Action, [action: 1]}, angle_slider: {Corex.AngleSlider, [angle_slider: 1]}, avatar: {Corex.Avatar, [avatar: 1]}, carousel: {Corex.Carousel, [carousel: 1]}, checkbox: {Corex.Checkbox, [checkbox: 1]}, clipboard: {Corex.Clipboard, [clipboard: 1]}, code: {Corex.Code, [code: 1]}, collapsible: {Corex.Collapsible, [collapsible: 1]}, combobox: {Corex.Combobox, [combobox: 1]}, color_picker: {Corex.ColorPicker, [color_picker: 1]}, date_picker: {Corex.DatePicker, [date_picker: 1]}, dialog: {Corex.Dialog, [dialog: 1, dialog_title: 1, dialog_description: 1, dialog_close_trigger: 1]}, editable: {Corex.Editable, [editable: 1]}, email_input: {Corex.EmailInput, [email_input: 1]}, floating_panel: {Corex.FloatingPanel, [floating_panel: 1]}, form: {Corex.Form, [get_form_id: 1]}, hidden_input: {Corex.HiddenInput, [hidden_input: 1]}, listbox: {Corex.Listbox, [listbox: 1]}, marquee: {Corex.Marquee, [marquee: 1]}, menu: {Corex.Menu, [menu: 1]}, navigate: {Corex.Navigate, [navigate: 1]}, number_input: {Corex.NumberInput, [number_input: 1]}, password_input: {Corex.PasswordInput, [password_input: 1]}, pin_input: {Corex.PinInput, [pin_input: 1]}, radio_group: {Corex.RadioGroup, [radio_group: 1]}, select: {Corex.Select, [select: 1]}, signature_pad: {Corex.SignaturePad, [signature_pad: 1]}, switch: {Corex.Switch, [switch: 1]}, tabs: {Corex.Tabs, [tabs: 1, tabs_trigger: 1, tabs_content: 1]}, text_area_input: {Corex.TextAreaInput, [text_area_input: 1]}, text_input: {Corex.TextInput, [text_input: 1]}, timer: {Corex.Timer, [timer: 1]}, url_input: {Corex.UrlInput, [url_input: 1]}, toast: {Corex.Toast, [ toast_group: 1, toast_client_error: 1, toast_server_error: 1, toast_connected: 1, toast_disconnected: 1 ]}, toggle_group: {Corex.ToggleGroup, [toggle_group: 1]}, tree_view: {Corex.TreeView, [tree_view: 1, tree_item: 1, tree_branch: 1]} } defmacro __using__(opts \\ []) do only = Keyword.get(opts, :only, :all) except = Keyword.get(opts, :except, []) prefix = Keyword.get(opts, :prefix) # Filter components based on only/except selected_components = @components |> Enum.filter(fn {component_name, _} -> include?(component_name, only, except) end) if prefix do # Generate wrapper functions with prefix wrappers = for {_component_name, {mod, functions}} <- selected_components, {func_name, arity} <- functions do prefixed_name = :"#{prefix}_#{func_name}" # Generate the appropriate number of arguments args = Macro.generate_arguments(arity, __MODULE__) quote do defdelegate unquote(prefixed_name)(unquote_splicing(args)), to: unquote(mod), as: unquote(func_name) end end # Generate aliases aliases = for {_component_name, {mod, _functions}} <- selected_components do quote do alias unquote(mod) end end quote do unquote_splicing(wrappers) unquote_splicing(aliases) end else # Normal import without prefix imports = for {_component_name, {mod, functions}} <- selected_components do quote do import unquote(mod), only: unquote(functions) end end aliases = for {_component_name, {mod, _functions}} <- selected_components do quote do alias unquote(mod) end end quote do unquote_splicing(imports) unquote_splicing(aliases) end end end defp include?(_name, :all, []), do: true defp include?(name, :all, except), do: name not in except defp include?(name, only, _except) when is_list(only), do: name in only end