Class: Plutonium::UI::Form::Theme

Inherits:
Phlexi::Form::Theme
  • Object
show all
Defined in:
lib/plutonium/ui/form/theme.rb

Class Method Summary collapse

Class Method Details

.themeObject



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/plutonium/ui/form/theme.rb', line 7

def self.theme
  super.merge({
    # Form structure
    # Width is NOT baked in here — it is configuration, not theme
    # (`page_width` / `form_width` on the definition, defaulting to
    # `Plutonium.configuration.default_page_width`), so Form::Resource
    # appends it. Overriding these keys therefore restyles the form
    # without silently pinning its width.
    base: "pu-card my-4 p-8 space-y-8",
    # :base for a form whose sections are cards — no card, no padding
    # of its own, since the section cards provide both.
    sectioned_base: "my-4 space-y-4",
    fields_wrapper: "grid grid-cols-1 md:grid-cols-2 2xl:grid-cols-4 gap-6 grid-flow-row-dense",

    # Sections are their OWN cards (see Component::Section), so this
    # only has to stack them.
    sections_wrapper: "space-y-4",

    # Section chrome (heading, accent, divider, collapsible caret).
    # Shared defaults with the show page so both read the same;
    # override any key here to restyle form sections alone.
    **Plutonium::UI::Component::Section::DEFAULT_THEME,
    actions_wrapper: "flex justify-end gap-3 pt-4 border-t border-[var(--pu-border-muted)]",
    wrapper: nil,
    inner_wrapper: "w-full",

    # Form errors
    form_errors_wrapper: "flex items-start gap-3 m-4 p-4 text-base text-danger-800 rounded-[var(--pu-radius-lg)] bg-danger-50 border border-danger-200 dark:bg-danger-950/30 dark:border-danger-800 dark:text-danger-300",
    form_errors_message: "font-semibold",
    form_errors_list: "mt-2 list-disc list-inside text-sm",

    # Label themes
    # The required marker is a `<abbr title="required">*</abbr>` which
    # picks up the browser's default dotted underline — strip it and
    # color the asterisk as a danger indicator instead.
    label: "mt-2 block mb-2 text-base font-semibold [&_abbr]:no-underline [&_abbr]:border-0 [&_abbr]:cursor-default [&_abbr]:text-danger-500",
    invalid_label: "text-danger-700 dark:text-danger-400",
    valid_label: "text-success-700 dark:text-success-400",
    neutral_label: "text-[var(--pu-text)]",

    # Input themes
    input: "pu-input",
    invalid_input: "pu-input pu-input-invalid",
    valid_input: "pu-input pu-input-valid",
    neutral_input: "",

    # Checkbox / Boolean
    checkbox: "pu-checkbox",
    boolean: "pu-checkbox",
    valid_boolean: "pu-checkbox",
    invalid_boolean: "pu-checkbox pu-input-invalid",

    # Toggle switch (opt-in boolean input: `as: :toggle`)
    toggle: "pu-toggle",
    valid_toggle: "pu-toggle",
    invalid_toggle: "pu-toggle pu-input-invalid",

    # Radio buttons
    radio_button: "pu-radio",
    collection_radio_buttons: "flex flex-col gap-2",

    # Color
    color: "pu-color-input appearance-none bg-transparent border-none cursor-pointer w-12 h-12 rounded-lg",
    invalid_color: nil,
    valid_color: nil,
    neutral_color: nil,

    # File input — keep pu-input's h-9 so the field matches the height
    # of text inputs and slim-selects. The native file-selector-button
    # fills the *full* height of the control and sits flush against the
    # left edge (px-0 on the wrapper, no vertical margin), reading as a
    # segmented button. A right border divides it from the filename text,
    # and only the left corners are rounded so it nests inside pu-input.
    # NOTE: pu-input ships its px-3/h-9 padding *unlayered*, so plain
    # pl-0/py-0 utilities (in @layer utilities) lose to it — the !
    # important variants are required to flatten the wrapper padding.
    file: "pu-input pl-0! py-0! [&::file-selector-button]:h-full [&::file-selector-button]:align-middle [&::file-selector-button]:m-0 [&::file-selector-button]:mr-4 [&::file-selector-button]:px-4 [&::file-selector-button]:leading-[1.1] [&::file-selector-button]:bg-[var(--pu-surface-alt)] [&::file-selector-button]:border-0 [&::file-selector-button]:border-r [&::file-selector-button]:border-[var(--pu-input-border)] [&::file-selector-button]:rounded-none [&::file-selector-button]:rounded-l-md [&::file-selector-button]:text-sm [&::file-selector-button]:font-semibold [&::file-selector-button]:text-[var(--pu-text-muted)] [&::file-selector-button]:hover:bg-[var(--pu-border)] [&::file-selector-button]:cursor-pointer [&::file-selector-button]:transition-colors",

    # Hint themes
    hint: "pu-hint whitespace-pre-wrap",

    # Error themes
    error: "text-xs text-danger-600 mt-1",

    # Button themes
    button: "pu-btn pu-btn-md pu-btn-primary",

    # Flatpickr
    flatpickr: :input,
    valid_flatpickr: :valid_input,
    invalid_flatpickr: :invalid_input,
    neutral_flatpickr: :neutral_input,

    # Currency (money input; the number field styles as a normal input,
    # the unit prefix is overlaid by the component)
    currency: :input,
    valid_currency: :valid_input,
    invalid_currency: :invalid_input,
    neutral_currency: :neutral_input,

    # Int tel input
    int_tel_input: :input,
    valid_int_tel_input: :valid_input,
    invalid_int_tel_input: :invalid_input,
    neutral_int_tel_input: :neutral_input,

    # JSON / JSONB textarea — without this the component falls back to
    # the neutral (classless) theme and loses pu-input's dark styling.
    json: :input,
    valid_json: :valid_input,
    invalid_json: :invalid_input,
    neutral_json: :neutral_input,

    # Uppy file upload
    uppy: :file,
    valid_uppy: :valid_file,
    invalid_uppy: :invalid_file,
    neutral_uppy: :neutral_file,

    # Association
    association: :select,
    valid_association: :valid_select,
    invalid_association: :invalid_select,
    neutral_association: :neutral_select,

    # Polymorphic association
    polymorpic_association: :association,
    valid_polymorpic_association: :valid_association,
    invalid_polymorpic_association: :invalid_association,
    neutral_polymorpic_association: :neutral_association
  })
end