Class: PhlexForms::Theme

Inherits:
Object
  • Object
show all
Defined in:
lib/phlex_forms/theme.rb

Overview

A theme maps component roles (:input, :select, :control, ...) to component classes. The binding contract — the leaf initializer signatures (*modifiers, name:, id:, value:, error:, required:, ...) — is the stable interface, so the same form class renders under any theme.

Built-ins:

Theme.daisy — the DaisyUI-delegating Forms::* leaves (default when the
            daisyui gem is loaded)
Theme.plain — bare semantic HTML (Forms::Plain::*): variants accepted and
            ignored, zero styling classes, aria/data hooks only

Select per form (Form(model:, theme: :plain)), per class (form_options theme: :plain), or globally (PhlexForms.configure { |c| c.theme = :plain }). Override single roles:

PhlexForms::Theme.resolve(:plain).with(input: MyInput)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(components) ⇒ Theme

Returns a new instance of Theme.



21
22
23
# File 'lib/phlex_forms/theme.rb', line 21

def initialize(components)
  @components = components.freeze
end

Class Method Details

.daisyObject



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/phlex_forms/theme.rb', line 47

def daisy
  unless defined?(DaisyUI)
    raise PhlexForms::FeatureUnavailable,
      "the daisy theme requires the daisyui gem. Add `gem \"daisyui\"` to your " \
      "Gemfile, or use the plain theme."
  end

  @daisy ||= new(
    input: Forms::Input, select: Forms::Select, choices_select: Forms::ChoicesSelect,
    textarea: Forms::Textarea, rich_textarea: Forms::RichTextarea,
    checkbox: Forms::Checkbox, toggle: Forms::Toggle, radio: Forms::Radio,
    file: Forms::FileInput, wrapped_input: Forms::WrappedInput,
    control: Forms::FormControl, label: Forms::Label,
    field_error: Forms::FieldError, field_hint: Forms::FieldHint,
    submit: Forms::Submit, row: Forms::Row, group: Forms::Group
  )
end

.plainObject

choices_select degrades to the native plain select (no choices.js) and rich_textarea to a plain textarea; toggle renders as a checkbox.



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/phlex_forms/theme.rb', line 67

def plain
  @plain ||= new(
    input: Forms::Plain::Input, select: Forms::Plain::Select, choices_select: Forms::Plain::Select,
    textarea: Forms::Plain::Textarea, rich_textarea: Forms::Plain::Textarea,
    checkbox: Forms::Plain::Checkbox, toggle: Forms::Plain::Checkbox, radio: Forms::Plain::Radio,
    file: Forms::Plain::FileInput, wrapped_input: Forms::Plain::WrappedInput,
    control: Forms::Plain::Control, label: Forms::Plain::Label,
    field_error: Forms::Plain::FieldError, field_hint: Forms::Plain::FieldHint,
    submit: Forms::Plain::Submit, row: Forms::Plain::Row, group: Forms::Plain::Group
  )
end

.resolve(value) ⇒ Object



36
37
38
39
40
41
42
43
44
45
# File 'lib/phlex_forms/theme.rb', line 36

def resolve(value)
  value = PhlexForms.config.theme if value.nil?
  case value
  when Theme then value
  when :daisy then daisy
  when :plain then plain
  else
    raise ArgumentError, "unknown theme #{value.inspect} (use :daisy, :plain, or a PhlexForms::Theme)"
  end
end

Instance Method Details

#[](role) ⇒ Object



25
26
27
28
29
# File 'lib/phlex_forms/theme.rb', line 25

def [](role)
  @components.fetch(role) do
    raise KeyError, "unknown theme role #{role.inspect} (roles: #{@components.keys.join(', ')})"
  end
end

#with(**overrides) ⇒ Object



31
32
33
# File 'lib/phlex_forms/theme.rb', line 31

def with(**overrides)
  self.class.new(@components.merge(overrides))
end