stimulus_plumbers_tailwind 0.4.0 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +40 -0
- data/README.md +27 -9
- data/lib/generators/stimulus_plumbers_tailwind/install/install_generator.rb +78 -0
- data/lib/stimulus_plumbers/themes/tailwind/avatar.rb +12 -12
- data/lib/stimulus_plumbers/themes/tailwind/button.rb +26 -22
- data/lib/stimulus_plumbers/themes/tailwind/calendar.rb +23 -20
- data/lib/stimulus_plumbers/themes/tailwind/card.rb +4 -5
- data/lib/stimulus_plumbers/themes/tailwind/combobox.rb +27 -17
- data/lib/stimulus_plumbers/themes/tailwind/form/field.rb +44 -57
- data/lib/stimulus_plumbers/themes/tailwind/form/input.rb +140 -54
- data/lib/stimulus_plumbers/themes/tailwind/form.rb +1 -10
- data/lib/stimulus_plumbers/themes/tailwind/icon.rb +7 -2
- data/lib/stimulus_plumbers/themes/tailwind/layout.rb +6 -3
- data/lib/stimulus_plumbers/themes/tailwind/link.rb +31 -29
- data/lib/stimulus_plumbers/themes/tailwind/list.rb +15 -13
- data/lib/stimulus_plumbers/themes/tailwind/timeline/group.rb +28 -0
- data/lib/stimulus_plumbers/themes/tailwind/timeline.rb +104 -0
- data/lib/stimulus_plumbers/themes/tailwind_theme.rb +3 -0
- data/lib/stimulus_plumbers_tailwind/engine.rb +4 -0
- data/lib/stimulus_plumbers_tailwind/version.rb +1 -1
- data/lib/tasks/stimulus_plumbers_tailwind.rake +15 -0
- metadata +5 -1
|
@@ -10,27 +10,6 @@ module StimulusPlumbers
|
|
|
10
10
|
HINT = %w[text-(length:--sp-text-xs) text-(--sp-color-muted-fg)].freeze
|
|
11
11
|
ERROR_TEXT = %w[text-(length:--sp-text-xs) text-(--sp-color-error)].freeze
|
|
12
12
|
|
|
13
|
-
FLOATING_INPUT_BASE = %w[
|
|
14
|
-
peer w-full text-(length:--sp-text-sm) text-(--sp-color-fg) appearance-none
|
|
15
|
-
focus:outline-none focus:ring-0
|
|
16
|
-
].freeze
|
|
17
|
-
FLOATING_INPUT_TYPES = {
|
|
18
|
-
filled: %w[
|
|
19
|
-
rounded-t-(--sp-radius-md) px-(--sp-space-2-5) pb-(--sp-space-2-5) pt-(--sp-space-5)
|
|
20
|
-
bg-(--sp-color-bg-muted) border-0 border-b-2
|
|
21
|
-
].freeze,
|
|
22
|
-
outlined: %w[
|
|
23
|
-
px-(--sp-space-2-5) pb-(--sp-space-2-5) pt-(--sp-space-4)
|
|
24
|
-
bg-transparent rounded-(--sp-radius-md) border
|
|
25
|
-
].freeze,
|
|
26
|
-
standard: %w[
|
|
27
|
-
py-(--sp-space-2-5) px-0
|
|
28
|
-
bg-transparent border-0 border-b-2
|
|
29
|
-
].freeze
|
|
30
|
-
}.freeze
|
|
31
|
-
FLOATING_INPUT_ERROR = %w[border-(--sp-color-error)].freeze
|
|
32
|
-
FLOATING_INPUT_DEFAULT = %w[border-(--sp-color-muted-fg) focus:border-(--sp-color-primary)].freeze
|
|
33
|
-
|
|
34
13
|
FLOATING_GROUP_TYPES = {
|
|
35
14
|
filled: %w[relative].freeze,
|
|
36
15
|
outlined: %w[relative].freeze,
|
|
@@ -41,28 +20,42 @@ module StimulusPlumbers
|
|
|
41
20
|
absolute text-(length:--sp-text-sm) text-(--sp-color-muted-fg)
|
|
42
21
|
duration-300 transform origin-[0]
|
|
43
22
|
].freeze
|
|
44
|
-
FLOATING_LABEL_FOCUS = %w[peer-focus:text-(--sp-color-primary)].freeze
|
|
23
|
+
FLOATING_LABEL_FOCUS = %w[peer-focus-within:text-(--sp-color-primary)].freeze
|
|
45
24
|
FLOATING_LABEL_ERROR = %w[text-(--sp-color-error)].freeze
|
|
46
25
|
FLOATING_LABEL_TYPES = {
|
|
47
26
|
filled: %w[
|
|
48
27
|
-translate-y-(--sp-space-4) scale-75 top-(--sp-space-4) z-10 start-(--sp-space-2-5)
|
|
49
|
-
peer-placeholder-shown:scale-100
|
|
50
|
-
peer-
|
|
51
|
-
|
|
28
|
+
peer-placeholder-shown:scale-100
|
|
29
|
+
peer-placeholder-shown:translate-y-0
|
|
30
|
+
peer-has-[input:not(:focus):placeholder-shown]:scale-100
|
|
31
|
+
peer-has-[input:not(:focus):placeholder-shown]:translate-y-0
|
|
32
|
+
peer-focus-within:scale-75
|
|
33
|
+
peer-focus-within:-translate-y-(--sp-space-4)
|
|
34
|
+
rtl:peer-focus-within:translate-x-1/4 rtl:peer-focus-within:left-auto
|
|
52
35
|
].freeze,
|
|
53
36
|
outlined: %w[
|
|
54
37
|
-translate-y-(--sp-space-4) scale-75 top-(--sp-space-2) z-10 start-1
|
|
55
|
-
bg-(--sp-color-bg) px-(--sp-space-2) peer-focus:px-(--sp-space-2)
|
|
56
|
-
peer-placeholder-shown:scale-100
|
|
57
|
-
peer-
|
|
58
|
-
|
|
38
|
+
bg-(--sp-color-bg) px-(--sp-space-2) peer-focus-within:px-(--sp-space-2)
|
|
39
|
+
peer-placeholder-shown:scale-100
|
|
40
|
+
peer-placeholder-shown:-translate-y-1/2
|
|
41
|
+
peer-placeholder-shown:top-1/2
|
|
42
|
+
peer-has-[input:not(:focus):placeholder-shown]:scale-100
|
|
43
|
+
peer-has-[input:not(:focus):placeholder-shown]:-translate-y-1/2
|
|
44
|
+
peer-has-[input:not(:focus):placeholder-shown]:top-1/2
|
|
45
|
+
peer-focus-within:top-(--sp-space-2) peer-focus-within:scale-75
|
|
46
|
+
peer-focus-within:-translate-y-(--sp-space-4)
|
|
47
|
+
rtl:peer-focus-within:translate-x-1/4 rtl:peer-focus-within:left-auto
|
|
59
48
|
].freeze,
|
|
60
49
|
standard: %w[
|
|
61
50
|
-translate-y-(--sp-space-6) scale-75 top-(--sp-space-3) -z-10 start-0
|
|
62
|
-
peer-focus:start-0
|
|
63
|
-
peer-placeholder-shown:scale-100
|
|
64
|
-
peer-
|
|
65
|
-
|
|
51
|
+
peer-focus-within:start-0
|
|
52
|
+
peer-placeholder-shown:scale-100
|
|
53
|
+
peer-placeholder-shown:translate-y-0
|
|
54
|
+
peer-has-[input:not(:focus):placeholder-shown]:scale-100
|
|
55
|
+
peer-has-[input:not(:focus):placeholder-shown]:translate-y-0
|
|
56
|
+
peer-focus-within:scale-75
|
|
57
|
+
peer-focus-within:-translate-y-(--sp-space-6)
|
|
58
|
+
rtl:peer-focus-within:translate-x-1/4 rtl:peer-focus-within:left-auto
|
|
66
59
|
].freeze
|
|
67
60
|
}.freeze
|
|
68
61
|
|
|
@@ -78,7 +71,7 @@ module StimulusPlumbers
|
|
|
78
71
|
hover:bg-(--sp-color-muted)
|
|
79
72
|
].freeze,
|
|
80
73
|
card: %w[
|
|
81
|
-
flex justify-between items-
|
|
74
|
+
flex justify-between items-center gap-(--sp-space-3) flex-1 p-(--sp-space-4) cursor-pointer select-none
|
|
82
75
|
text-(length:--sp-text-sm) text-(--sp-color-muted-fg)
|
|
83
76
|
bg-(--sp-color-bg) border border-(--sp-color-border) rounded-(--sp-radius-md) shadow-(--sp-shadow-xs)
|
|
84
77
|
hover:bg-(--sp-color-muted) hover:border-(--sp-color-border-strong) hover:text-(--sp-color-fg)
|
|
@@ -97,16 +90,16 @@ module StimulusPlumbers
|
|
|
97
90
|
text-(length:--sp-text-sm) text-(--sp-color-muted-fg)
|
|
98
91
|
bg-(--sp-color-bg) border border-(--sp-color-border) rounded-(--sp-radius-md)
|
|
99
92
|
hover:bg-(--sp-color-muted)
|
|
100
|
-
|
|
101
|
-
|
|
93
|
+
group-has-[:checked]:border-(--card-ring) group-has-[:checked]:bg-(--card-ring)/10
|
|
94
|
+
group-has-[:checked]:text-(--sp-color-fg) group-has-[:checked]:hover:bg-(--card-ring)/15
|
|
102
95
|
].freeze,
|
|
103
96
|
card: %w[
|
|
104
97
|
flex items-start flex-1 p-(--sp-space-4) cursor-pointer select-none
|
|
105
98
|
text-(length:--sp-text-sm) text-(--sp-color-muted-fg)
|
|
106
99
|
bg-(--sp-color-bg) border border-(--sp-color-border) rounded-(--sp-radius-md) shadow-(--sp-shadow-xs)
|
|
107
100
|
hover:bg-(--sp-color-muted) hover:border-(--sp-color-border-strong) hover:text-(--sp-color-fg)
|
|
108
|
-
|
|
109
|
-
|
|
101
|
+
group-has-[:checked]:border-(--card-ring) group-has-[:checked]:bg-(--card-ring)/10
|
|
102
|
+
group-has-[:checked]:text-(--sp-color-fg) group-has-[:checked]:hover:bg-(--card-ring)/15
|
|
110
103
|
].freeze
|
|
111
104
|
}.freeze
|
|
112
105
|
|
|
@@ -117,27 +110,17 @@ module StimulusPlumbers
|
|
|
117
110
|
|
|
118
111
|
private
|
|
119
112
|
|
|
120
|
-
def
|
|
121
|
-
{
|
|
122
|
-
classes: klasses(
|
|
123
|
-
*FLOATING_INPUT_BASE,
|
|
124
|
-
*FLOATING_INPUT_TYPES.fetch(type, []),
|
|
125
|
-
*(error ? FLOATING_INPUT_ERROR : FLOATING_INPUT_DEFAULT)
|
|
126
|
-
)
|
|
127
|
-
}
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def form_field_floating_group_classes(type: nil)
|
|
131
|
-
{ classes: klasses(*FLOATING_GROUP_TYPES.fetch(type, [])) }
|
|
113
|
+
def form_field_input_group_classes(floating: nil)
|
|
114
|
+
{ classes: klasses(*FLOATING_GROUP_TYPES.fetch(floating, [])) }
|
|
132
115
|
end
|
|
133
116
|
|
|
134
|
-
def
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
117
|
+
def form_field_label_classes(floating: nil, hidden: false, error: false, **)
|
|
118
|
+
if floating
|
|
119
|
+
color = error ? FLOATING_LABEL_ERROR : FLOATING_LABEL_FOCUS
|
|
120
|
+
{ classes: klasses(*FLOATING_LABEL_BASE, *FLOATING_LABEL_TYPES.fetch(floating, []), *color) }
|
|
121
|
+
else
|
|
122
|
+
{ classes: klasses(*LABEL, hidden ? "sr-only" : nil) }
|
|
123
|
+
end
|
|
141
124
|
end
|
|
142
125
|
|
|
143
126
|
def form_field_required_mark_classes
|
|
@@ -165,6 +148,10 @@ module StimulusPlumbers
|
|
|
165
148
|
card_color = %i[button card].include?(type) ? Card::VARIANTS.fetch(variant, Card::VARIANTS[:tertiary]) : []
|
|
166
149
|
{ classes: klasses(*RADIO_LABEL_TYPES.fetch(type), *card_color) }
|
|
167
150
|
end
|
|
151
|
+
|
|
152
|
+
def form_field_radio_item_group_classes
|
|
153
|
+
{ classes: "contents group" }
|
|
154
|
+
end
|
|
168
155
|
end
|
|
169
156
|
end
|
|
170
157
|
end
|
|
@@ -5,31 +5,98 @@ module StimulusPlumbers
|
|
|
5
5
|
module Tailwind
|
|
6
6
|
module Form
|
|
7
7
|
module Input
|
|
8
|
+
# ── Standalone input ──────────────────────────────────────────────────
|
|
8
9
|
INPUT_BASE = %w[
|
|
9
|
-
w-full rounded-(--sp-radius-md) border px-(--sp-space-3) py-(--sp-space-2)
|
|
10
|
-
text-(--sp-color-fg) bg-(--sp-color-bg)
|
|
10
|
+
w-full rounded-(--sp-radius-md) border px-(--sp-space-3) py-(--sp-space-2)
|
|
11
|
+
text-(length:--sp-text-sm) text-(--sp-color-fg) bg-(--sp-color-bg)
|
|
12
|
+
focus:outline-none focus:ring-(length:--sp-focus-ring-width) focus:ring-offset-0
|
|
13
|
+
].freeze
|
|
14
|
+
INPUT_DEFAULT = %w[
|
|
15
|
+
border-(--sp-color-muted-fg) hover:border-(--sp-color-fg)
|
|
16
|
+
focus:ring-(--sp-focus-ring-color)
|
|
17
|
+
].freeze
|
|
18
|
+
INPUT_ERROR = %w[border-(--sp-color-error) focus:ring-(--sp-color-error)].freeze
|
|
19
|
+
|
|
20
|
+
# ── Floating input ────────────────────────────────────────────────────
|
|
21
|
+
FLOATING_INPUT_BASE = %w[
|
|
22
|
+
peer w-full text-(length:--sp-text-sm) text-(--sp-color-fg) appearance-none
|
|
23
|
+
focus:outline-none focus:ring-0
|
|
24
|
+
focus-visible:outline-none focus-visible:ring-0
|
|
25
|
+
].freeze
|
|
26
|
+
FLOATING_INPUT_TYPES = {
|
|
27
|
+
filled: %w[
|
|
28
|
+
rounded-t-(--sp-radius-md) px-(--sp-space-2-5) pb-(--sp-space-2-5) pt-(--sp-space-5)
|
|
29
|
+
bg-(--sp-color-bg-muted) border-0 border-b-2
|
|
30
|
+
].freeze,
|
|
31
|
+
outlined: %w[
|
|
32
|
+
px-(--sp-space-2-5) pb-(--sp-space-2-5) pt-(--sp-space-4)
|
|
33
|
+
bg-transparent rounded-(--sp-radius-md) border
|
|
34
|
+
].freeze,
|
|
35
|
+
standard: %w[
|
|
36
|
+
py-(--sp-space-2-5) px-0
|
|
37
|
+
bg-transparent border-0 border-b-2
|
|
38
|
+
].freeze
|
|
39
|
+
}.freeze
|
|
40
|
+
FLOATING_INPUT_DEFAULT = %w[
|
|
41
|
+
border-(--sp-color-muted-fg) hover:border-(--sp-color-fg)
|
|
42
|
+
focus:border-(--sp-color-primary)
|
|
43
|
+
].freeze
|
|
44
|
+
FLOATING_INPUT_ERROR = %w[border-(--sp-color-error)].freeze
|
|
45
|
+
|
|
46
|
+
# ── Input group ───────────────────────────────────────────────────────
|
|
47
|
+
INPUT_GROUP_BASE = %w[flex items-center overflow-hidden rounded-(--sp-radius-md) border].freeze
|
|
48
|
+
INPUT_GROUP_BORDER = { error: "border-(--sp-color-error)", default: "border-(--sp-color-muted-fg)" }.freeze
|
|
49
|
+
|
|
50
|
+
# ── Floating input group ──────────────────────────────────────────────
|
|
51
|
+
FLOATING_INPUT_GROUP_BASE = %w[flex items-center overflow-hidden peer].freeze
|
|
52
|
+
FLOATING_INPUT_GROUP_TYPES = {
|
|
53
|
+
filled: %w[rounded-t-(--sp-radius-md) bg-(--sp-color-bg-muted) border-0 border-b-2].freeze,
|
|
54
|
+
outlined: %w[rounded-(--sp-radius-md) border].freeze,
|
|
55
|
+
standard: %w[rounded-none bg-transparent border-0 border-b-2].freeze
|
|
56
|
+
}.freeze
|
|
57
|
+
FLOATING_INPUT_GROUP_DEFAULT = %w[
|
|
58
|
+
border-(--sp-color-muted-fg) hover:border-(--sp-color-fg)
|
|
59
|
+
focus-within:border-(--sp-color-primary)
|
|
60
|
+
].freeze
|
|
61
|
+
FLOATING_INPUT_GROUP_ERROR = %w[border-(--sp-color-error)].freeze
|
|
62
|
+
|
|
63
|
+
# ── Combobox wrappers ─────────────────────────────────────────────────
|
|
64
|
+
COMBOBOX_INPUT = %w[
|
|
65
|
+
[&>input:not([type=hidden])]:border-0
|
|
66
|
+
[&>input:not([type=hidden])]:rounded-none
|
|
67
|
+
[&>input:not([type=hidden])]:px-0
|
|
68
|
+
[&>input:not([type=hidden])]:py-0
|
|
69
|
+
[&>input:not([type=hidden])]:bg-transparent
|
|
70
|
+
[&>input:not([type=hidden])]:shadow-none
|
|
71
|
+
[&>input:not([type=hidden])]:focus:ring-0
|
|
72
|
+
].freeze
|
|
73
|
+
COMBOBOX_TRIGGER_GROUP = %w[
|
|
74
|
+
[&>div:first-child]:border-0
|
|
75
|
+
[&>div:first-child]:rounded-none
|
|
76
|
+
[&>div:first-child]:px-0
|
|
77
|
+
[&>div:first-child]:py-0
|
|
78
|
+
[&>div:first-child]:focus-within:ring-0
|
|
11
79
|
].freeze
|
|
12
|
-
INPUT_ERROR = %w[border-(--sp-color-error) focus:ring-(--sp-color-error)].freeze
|
|
13
|
-
INPUT_DEFAULT = %w[border-(--sp-color-muted-fg) focus:ring-(--sp-focus-ring-color)].freeze
|
|
14
80
|
|
|
81
|
+
# ── Choice inputs ─────────────────────────────────────────────────────
|
|
15
82
|
CHECKBOX_TYPES = {
|
|
16
83
|
default: %w[
|
|
17
84
|
size-(--sp-control-size) rounded-(--sp-radius-sm) shrink-0
|
|
18
85
|
border border-(--sp-color-border) bg-(--sp-color-muted)
|
|
19
|
-
focus:ring-
|
|
86
|
+
focus:ring-(length:--sp-focus-ring-width) focus:ring-(--sp-focus-ring-color) focus:outline-none
|
|
20
87
|
disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer
|
|
21
88
|
].freeze,
|
|
22
89
|
button: %w[
|
|
23
90
|
size-(--sp-control-size) rounded-(--sp-radius-sm) shrink-0
|
|
24
91
|
border border-(--sp-color-border) bg-(--sp-color-muted)
|
|
25
|
-
focus:ring-
|
|
92
|
+
focus:ring-(length:--sp-focus-ring-width) focus:ring-(--sp-focus-ring-color) focus:outline-none
|
|
26
93
|
disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer
|
|
27
94
|
].freeze,
|
|
28
95
|
card: %w[
|
|
29
96
|
size-(--sp-control-size) rounded-(--sp-radius-sm) shrink-0
|
|
30
97
|
border border-(--sp-color-border) bg-(--sp-color-muted)
|
|
31
98
|
checked:border-(--card-ring)
|
|
32
|
-
focus:ring-
|
|
99
|
+
focus:ring-(length:--sp-focus-ring-width) focus:ring-(--card-ring) focus:outline-none
|
|
33
100
|
disabled:opacity-50 disabled:cursor-not-allowed cursor-pointer
|
|
34
101
|
].freeze
|
|
35
102
|
}.freeze
|
|
@@ -38,58 +105,54 @@ module StimulusPlumbers
|
|
|
38
105
|
default: %w[
|
|
39
106
|
size-(--sp-control-size) rounded-full shrink-0
|
|
40
107
|
[accent-color:var(--sp-color-primary)] cursor-pointer
|
|
41
|
-
focus:ring-
|
|
108
|
+
focus:ring-(length:--sp-focus-ring-width) focus:ring-(--sp-focus-ring-color) focus:outline-none
|
|
42
109
|
disabled:opacity-50 disabled:cursor-not-allowed
|
|
43
110
|
].freeze,
|
|
44
|
-
button: %w[hidden
|
|
45
|
-
card: %w[hidden
|
|
111
|
+
button: %w[hidden].freeze,
|
|
112
|
+
card: %w[hidden].freeze
|
|
46
113
|
}.freeze
|
|
47
114
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
[&>input:not([type=hidden])]:py-0
|
|
56
|
-
[&>input:not([type=hidden])]:bg-transparent
|
|
57
|
-
[&>input:not([type=hidden])]:shadow-none
|
|
58
|
-
[&>input:not([type=hidden])]:focus:ring-0
|
|
59
|
-
].freeze
|
|
60
|
-
COMBOBOX_TRIGGER_GROUP = %w[
|
|
61
|
-
[&>div:first-child]:border-0
|
|
62
|
-
[&>div:first-child]:rounded-none
|
|
63
|
-
[&>div:first-child]:px-0
|
|
64
|
-
[&>div:first-child]:py-0
|
|
65
|
-
[&>div:first-child]:focus-within:ring-0
|
|
66
|
-
].freeze
|
|
67
|
-
|
|
68
|
-
BUTTON_REVEAL = %w[
|
|
69
|
-
self-stretch border-0 bg-transparent px-(--sp-space-3) cursor-pointer text-(--sp-color-muted-fg)
|
|
70
|
-
hover:text-(--sp-color-fg) text-(length:--sp-text-sm)
|
|
115
|
+
# ── Utility buttons ───────────────────────────────────────────────────
|
|
116
|
+
BUTTON_REVEAL = [
|
|
117
|
+
*Control::BASE,
|
|
118
|
+
"inline-flex items-center justify-center",
|
|
119
|
+
"focus-visible:ring-(--sp-focus-ring-color)",
|
|
120
|
+
"self-stretch px-(--sp-space-2) border-0 bg-transparent cursor-pointer text-(--sp-color-muted-fg)",
|
|
121
|
+
"rounded-(--sp-radius-sm) hover:bg-(--sp-color-muted) hover:text-(--sp-color-fg)"
|
|
71
122
|
].freeze
|
|
72
|
-
BUTTON_CLEAR =
|
|
73
|
-
|
|
74
|
-
|
|
123
|
+
BUTTON_CLEAR = [
|
|
124
|
+
*Control::BASE,
|
|
125
|
+
"inline-flex items-center justify-center",
|
|
126
|
+
"focus-visible:ring-(--sp-focus-ring-color)",
|
|
127
|
+
"self-stretch px-(--sp-space-2) border-0 bg-transparent cursor-pointer text-(--sp-color-muted-fg)",
|
|
128
|
+
"rounded-(--sp-radius-sm) hover:bg-(--sp-color-muted) hover:text-(--sp-color-fg)"
|
|
75
129
|
].freeze
|
|
76
130
|
|
|
77
131
|
private
|
|
78
132
|
|
|
79
|
-
def form_field_input_classes(error: false)
|
|
80
|
-
|
|
133
|
+
def form_field_input_classes(floating: nil, error: false)
|
|
134
|
+
if floating
|
|
135
|
+
{ classes: klasses(
|
|
136
|
+
*FLOATING_INPUT_BASE,
|
|
137
|
+
*FLOATING_INPUT_TYPES.fetch(floating, []),
|
|
138
|
+
*(error ? FLOATING_INPUT_ERROR : FLOATING_INPUT_DEFAULT)
|
|
139
|
+
)
|
|
140
|
+
}
|
|
141
|
+
else
|
|
142
|
+
{ classes: klasses(*INPUT_BASE, *(error ? INPUT_ERROR : INPUT_DEFAULT)) }
|
|
143
|
+
end
|
|
81
144
|
end
|
|
82
145
|
|
|
83
|
-
def form_field_input_textarea_classes(error: false)
|
|
84
|
-
form_field_input_classes(error: error)
|
|
146
|
+
def form_field_input_textarea_classes(floating: nil, error: false)
|
|
147
|
+
form_field_input_classes(floating: floating, error: error)
|
|
85
148
|
end
|
|
86
149
|
|
|
87
|
-
def form_field_input_file_classes(error: false)
|
|
88
|
-
form_field_input_classes(error: error)
|
|
150
|
+
def form_field_input_file_classes(floating: nil, error: false)
|
|
151
|
+
form_field_input_classes(floating: floating, error: error)
|
|
89
152
|
end
|
|
90
153
|
|
|
91
|
-
def form_field_input_select_classes(error: false)
|
|
92
|
-
form_field_input_classes(error: error)
|
|
154
|
+
def form_field_input_select_classes(floating: nil, error: false)
|
|
155
|
+
form_field_input_classes(floating: floating, error: error)
|
|
93
156
|
end
|
|
94
157
|
|
|
95
158
|
def form_field_input_checkbox_classes(type: :default, variant: :default, **)
|
|
@@ -102,23 +165,46 @@ module StimulusPlumbers
|
|
|
102
165
|
{ classes: klasses(*RADIO_TYPES.fetch(type), *card_color) }
|
|
103
166
|
end
|
|
104
167
|
|
|
105
|
-
def input_group_classes(error: false)
|
|
106
|
-
|
|
168
|
+
def input_group_classes(error: false, floating: nil)
|
|
169
|
+
if floating
|
|
170
|
+
color = error ? FLOATING_INPUT_GROUP_ERROR : FLOATING_INPUT_GROUP_DEFAULT
|
|
171
|
+
{ classes: klasses(*FLOATING_INPUT_GROUP_BASE, *FLOATING_INPUT_GROUP_TYPES.fetch(floating, []), *color) }
|
|
172
|
+
else
|
|
173
|
+
{ classes: klasses(*INPUT_GROUP_BASE, INPUT_GROUP_BORDER[error ? :error : :default]) }
|
|
174
|
+
end
|
|
107
175
|
end
|
|
108
176
|
|
|
109
|
-
def form_field_input_combobox_classes(error: false)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
177
|
+
def form_field_input_combobox_classes(floating: nil, error: false)
|
|
178
|
+
if floating
|
|
179
|
+
form_field_input_combobox_floating_classes(floating: floating, error: error)
|
|
180
|
+
else
|
|
181
|
+
{
|
|
182
|
+
classes: klasses(
|
|
183
|
+
*INPUT_BASE,
|
|
184
|
+
*(error ? INPUT_ERROR : INPUT_DEFAULT),
|
|
185
|
+
*COMBOBOX_INPUT,
|
|
186
|
+
*COMBOBOX_TRIGGER_GROUP
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def form_field_input_combobox_floating_classes(floating: :standard, error: false)
|
|
193
|
+
{
|
|
194
|
+
classes: klasses(
|
|
195
|
+
*FLOATING_INPUT_BASE,
|
|
196
|
+
*FLOATING_INPUT_TYPES.fetch(floating, []),
|
|
197
|
+
*(error ? FLOATING_INPUT_ERROR : FLOATING_INPUT_DEFAULT),
|
|
198
|
+
*COMBOBOX_INPUT,
|
|
199
|
+
*COMBOBOX_TRIGGER_GROUP
|
|
200
|
+
)
|
|
201
|
+
}
|
|
117
202
|
end
|
|
118
203
|
|
|
119
204
|
def form_field_input_reveal_classes(**)
|
|
120
205
|
{
|
|
121
206
|
classes: klasses(
|
|
207
|
+
"peer",
|
|
122
208
|
"[&>input]:border-0",
|
|
123
209
|
"[&>input]:rounded-none",
|
|
124
210
|
"[&>input]:bg-transparent",
|
|
@@ -13,16 +13,7 @@ module StimulusPlumbers
|
|
|
13
13
|
{ classes: klasses(*GROUP_BASE, layout == :inline ? GROUP_INLINE : "flex-col") }
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def form_submit_classes(
|
|
17
|
-
{ classes: klasses(
|
|
18
|
-
*Button::BASE,
|
|
19
|
-
*Button::LAYOUT,
|
|
20
|
-
*Button::VARIANTS.fetch(variant, Button::VARIANTS[:primary]),
|
|
21
|
-
*Button::TYPES.fetch(type, Button::TYPES[:default]),
|
|
22
|
-
*(type == :card ? [] : Button::SIZES[:md])
|
|
23
|
-
)
|
|
24
|
-
}
|
|
25
|
-
end
|
|
16
|
+
def form_submit_classes(**) = {}
|
|
26
17
|
end
|
|
27
18
|
end
|
|
28
19
|
end
|
|
@@ -10,8 +10,13 @@ module StimulusPlumbers
|
|
|
10
10
|
module Icon
|
|
11
11
|
ALIASES = {
|
|
12
12
|
"close" => "x-mark",
|
|
13
|
+
"download" => "arrow-down-tray",
|
|
14
|
+
"book" => "book-open",
|
|
15
|
+
"edit" => "pencil",
|
|
16
|
+
"email" => "envelope",
|
|
13
17
|
"calendar" => "calendar-days",
|
|
14
|
-
"external-link" => "arrow-top-right-on-square"
|
|
18
|
+
"external-link" => "arrow-top-right-on-square",
|
|
19
|
+
"reveal" => "eye"
|
|
15
20
|
}.freeze
|
|
16
21
|
|
|
17
22
|
ICONS = StimulusPlumbers::Themes::Icons::Registry.new(
|
|
@@ -26,7 +31,7 @@ module StimulusPlumbers
|
|
|
26
31
|
private
|
|
27
32
|
|
|
28
33
|
def icon_classes
|
|
29
|
-
{ classes: "size-(--sp-icon-
|
|
34
|
+
{ classes: "size-(--sp-icon-size-lg)" }
|
|
30
35
|
end
|
|
31
36
|
end
|
|
32
37
|
end
|
|
@@ -4,9 +4,12 @@ module StimulusPlumbers
|
|
|
4
4
|
module Themes
|
|
5
5
|
module Tailwind
|
|
6
6
|
module Layout
|
|
7
|
-
|
|
8
|
-
DIVIDER = %w[flex items-center gap-(--sp-space-3)].freeze
|
|
9
|
-
|
|
7
|
+
# ── Divider ───────────────────────────────────────────────────────────
|
|
8
|
+
DIVIDER = %w[w-full flex items-center gap-(--sp-space-3)].freeze
|
|
9
|
+
DIVIDER_SEPARATOR = %w[flex-1 h-px bg-(--sp-color-border) border-0].freeze
|
|
10
|
+
DIVIDER_LABEL = %w[text-(length:--sp-text-sm) text-(--sp-color-muted-fg) whitespace-nowrap font-medium].freeze
|
|
11
|
+
|
|
12
|
+
# ── Popover ───────────────────────────────────────────────────────────
|
|
10
13
|
POPOVER_WRAPPER = %w[relative inline-block].freeze
|
|
11
14
|
POPOVER_TRIGGER = [
|
|
12
15
|
*Control::BASE,
|
|
@@ -4,34 +4,7 @@ module StimulusPlumbers
|
|
|
4
4
|
module Themes
|
|
5
5
|
module Tailwind
|
|
6
6
|
module Link
|
|
7
|
-
|
|
8
|
-
default: %w[
|
|
9
|
-
[--link-color:var(--sp-color-primary)]
|
|
10
|
-
[--link-ring:var(--sp-color-primary)]
|
|
11
|
-
[--link-bg:var(--sp-color-primary)]
|
|
12
|
-
].freeze,
|
|
13
|
-
success: %w[
|
|
14
|
-
[--link-color:var(--sp-color-success)]
|
|
15
|
-
[--link-ring:var(--sp-color-success-ring)]
|
|
16
|
-
[--link-bg:var(--sp-color-success)]
|
|
17
|
-
].freeze,
|
|
18
|
-
destructive: %w[
|
|
19
|
-
[--link-color:var(--sp-color-destructive)]
|
|
20
|
-
[--link-ring:var(--sp-color-destructive)]
|
|
21
|
-
[--link-bg:var(--sp-color-destructive)]
|
|
22
|
-
].freeze,
|
|
23
|
-
warning: %w[
|
|
24
|
-
[--link-color:var(--sp-color-warning)]
|
|
25
|
-
[--link-ring:var(--sp-color-warning-ring)]
|
|
26
|
-
[--link-bg:var(--sp-color-warning)]
|
|
27
|
-
].freeze,
|
|
28
|
-
info: %w[
|
|
29
|
-
[--link-color:var(--sp-color-info)]
|
|
30
|
-
[--link-ring:var(--sp-color-info-ring)]
|
|
31
|
-
[--link-bg:var(--sp-color-info)]
|
|
32
|
-
].freeze
|
|
33
|
-
}.freeze
|
|
34
|
-
|
|
7
|
+
# ── Type styles ───────────────────────────────────────────────────────
|
|
35
8
|
BASE = [
|
|
36
9
|
*Control::BASE,
|
|
37
10
|
"inline-flex items-center gap-(--sp-space-1)",
|
|
@@ -65,6 +38,35 @@ module StimulusPlumbers
|
|
|
65
38
|
"focus-visible:ring-(--link-ring)"
|
|
66
39
|
].freeze
|
|
67
40
|
|
|
41
|
+
# ── Color tokens ──────────────────────────────────────────────────────
|
|
42
|
+
VARIANTS = {
|
|
43
|
+
default: %w[
|
|
44
|
+
[--link-color:var(--sp-color-primary)]
|
|
45
|
+
[--link-ring:var(--sp-color-primary)]
|
|
46
|
+
[--link-bg:var(--sp-color-primary)]
|
|
47
|
+
].freeze,
|
|
48
|
+
success: %w[
|
|
49
|
+
[--link-color:var(--sp-color-success)]
|
|
50
|
+
[--link-ring:var(--sp-color-success-ring)]
|
|
51
|
+
[--link-bg:var(--sp-color-success)]
|
|
52
|
+
].freeze,
|
|
53
|
+
destructive: %w[
|
|
54
|
+
[--link-color:var(--sp-color-destructive)]
|
|
55
|
+
[--link-ring:var(--sp-color-destructive)]
|
|
56
|
+
[--link-bg:var(--sp-color-destructive)]
|
|
57
|
+
].freeze,
|
|
58
|
+
warning: %w[
|
|
59
|
+
[--link-color:var(--sp-color-warning)]
|
|
60
|
+
[--link-ring:var(--sp-color-warning-ring)]
|
|
61
|
+
[--link-bg:var(--sp-color-warning)]
|
|
62
|
+
].freeze,
|
|
63
|
+
info: %w[
|
|
64
|
+
[--link-color:var(--sp-color-info)]
|
|
65
|
+
[--link-ring:var(--sp-color-info-ring)]
|
|
66
|
+
[--link-bg:var(--sp-color-info)]
|
|
67
|
+
].freeze
|
|
68
|
+
}.freeze
|
|
69
|
+
|
|
68
70
|
private
|
|
69
71
|
|
|
70
72
|
def link_classes(type: :default, variant: :default)
|
|
@@ -77,7 +79,7 @@ module StimulusPlumbers
|
|
|
77
79
|
end
|
|
78
80
|
|
|
79
81
|
def link_icon_classes
|
|
80
|
-
{ classes: klasses("size-(--sp-
|
|
82
|
+
{ classes: klasses("size-(--sp-icon-size-sm)", "stroke-current") }
|
|
81
83
|
end
|
|
82
84
|
end
|
|
83
85
|
end
|
|
@@ -4,6 +4,19 @@ module StimulusPlumbers
|
|
|
4
4
|
module Themes
|
|
5
5
|
module Tailwind
|
|
6
6
|
module List
|
|
7
|
+
# ── Section ───────────────────────────────────────────────────────────
|
|
8
|
+
SECTION_TITLE_BASE = %w[
|
|
9
|
+
block px-(--sp-space-2) pb-(--sp-space-1)
|
|
10
|
+
text-(length:--sp-text-xs) font-semibold uppercase tracking-wider
|
|
11
|
+
text-(--sp-color-muted-fg)
|
|
12
|
+
].freeze
|
|
13
|
+
|
|
14
|
+
SECTION_DESCRIPTION_BASE = %w[
|
|
15
|
+
block px-(--sp-space-2) pb-(--sp-space-1)
|
|
16
|
+
text-(length:--sp-text-xs) text-(--sp-color-muted-fg)
|
|
17
|
+
].freeze
|
|
18
|
+
|
|
19
|
+
# ── Item ──────────────────────────────────────────────────────────────
|
|
7
20
|
ITEM_BASE = [
|
|
8
21
|
*Control::BASE,
|
|
9
22
|
"flex items-center gap-(--sp-space-2) w-full",
|
|
@@ -28,21 +41,10 @@ module StimulusPlumbers
|
|
|
28
41
|
text-(length:--sp-text-xs) text-(--sp-color-muted-fg)
|
|
29
42
|
].freeze
|
|
30
43
|
|
|
31
|
-
SECTION_TITLE_BASE = %w[
|
|
32
|
-
block px-(--sp-space-2) pb-(--sp-space-1)
|
|
33
|
-
text-(length:--sp-text-xs) font-semibold uppercase tracking-wider
|
|
34
|
-
text-(--sp-color-muted-fg)
|
|
35
|
-
].freeze
|
|
36
|
-
|
|
37
|
-
SECTION_DESCRIPTION_BASE = %w[
|
|
38
|
-
block px-(--sp-space-2) pb-(--sp-space-1)
|
|
39
|
-
text-(length:--sp-text-xs) text-(--sp-color-muted-fg)
|
|
40
|
-
].freeze
|
|
41
|
-
|
|
42
44
|
private
|
|
43
45
|
|
|
44
46
|
def list_classes
|
|
45
|
-
{ classes: klasses("py-(--sp-space-1)
|
|
47
|
+
{ classes: klasses("py-(--sp-space-1)") }
|
|
46
48
|
end
|
|
47
49
|
|
|
48
50
|
def list_section_classes
|
|
@@ -62,7 +64,7 @@ module StimulusPlumbers
|
|
|
62
64
|
end
|
|
63
65
|
|
|
64
66
|
def list_item_icon_classes
|
|
65
|
-
{ classes: klasses("size-(--sp-
|
|
67
|
+
{ classes: klasses("size-(--sp-icon-size-sm)", "stroke-current") }
|
|
66
68
|
end
|
|
67
69
|
|
|
68
70
|
def list_item_content_classes
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module StimulusPlumbers
|
|
4
|
+
module Themes
|
|
5
|
+
module Tailwind
|
|
6
|
+
module Timeline
|
|
7
|
+
module Group
|
|
8
|
+
WRAPPER = %w[space-y-4].freeze
|
|
9
|
+
SECTION = %w[
|
|
10
|
+
p-4
|
|
11
|
+
bg-(--sp-color-bg-muted)
|
|
12
|
+
border border-(--sp-color-border)
|
|
13
|
+
rounded-lg
|
|
14
|
+
].freeze
|
|
15
|
+
DATE = %w[text-base font-semibold text-(--sp-color-fg)].freeze
|
|
16
|
+
LIST = %w[mt-3 divide-y divide-(--sp-color-border)].freeze
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def timeline_group_classes = { classes: klasses(WRAPPER) }
|
|
21
|
+
def timeline_group_section_classes = { classes: klasses(SECTION) }
|
|
22
|
+
def timeline_group_section_date_classes = { classes: klasses(DATE) }
|
|
23
|
+
def timeline_group_section_list_classes = { classes: klasses(LIST) }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|