fluxbit_view_components 0.1.0
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 +7 -0
- data/LICENSE.txt +20 -0
- data/README.md +86 -0
- data/app/components/fluxbit/alert_component.rb +126 -0
- data/app/components/fluxbit/avatar_component.rb +113 -0
- data/app/components/fluxbit/avatar_group_component.rb +23 -0
- data/app/components/fluxbit/badge_component.rb +79 -0
- data/app/components/fluxbit/button_component.rb +97 -0
- data/app/components/fluxbit/button_group_component.rb +43 -0
- data/app/components/fluxbit/card_component.rb +135 -0
- data/app/components/fluxbit/component.rb +86 -0
- data/app/components/fluxbit/flex_component.rb +93 -0
- data/app/components/fluxbit/form/checkbox_input_component.rb +61 -0
- data/app/components/fluxbit/form/component.rb +71 -0
- data/app/components/fluxbit/form/datepicker_component.rb +7 -0
- data/app/components/fluxbit/form/form_builder_component.rb +117 -0
- data/app/components/fluxbit/form/helper_text_component.rb +29 -0
- data/app/components/fluxbit/form/label_component.rb +65 -0
- data/app/components/fluxbit/form/radio_input_component.rb +21 -0
- data/app/components/fluxbit/form/range_input_component.rb +51 -0
- data/app/components/fluxbit/form/select_free_input_component.rb +77 -0
- data/app/components/fluxbit/form/select_input_component.rb +21 -0
- data/app/components/fluxbit/form/spacer_input_component.rb +12 -0
- data/app/components/fluxbit/form/text_input_component.rb +225 -0
- data/app/components/fluxbit/form/textarea_input_component.rb +57 -0
- data/app/components/fluxbit/form/toggle_input_component.rb +166 -0
- data/app/components/fluxbit/form/upload_image_input_component.html.erb +48 -0
- data/app/components/fluxbit/form/upload_image_input_component.rb +66 -0
- data/app/components/fluxbit/form/upload_input_component.html.erb +12 -0
- data/app/components/fluxbit/form/upload_input_component.rb +47 -0
- data/app/components/fluxbit/gravatar_component.rb +99 -0
- data/app/components/fluxbit/heading_component.rb +47 -0
- data/app/components/fluxbit/modal_component.rb +141 -0
- data/app/components/fluxbit/popover_component.rb +71 -0
- data/app/components/fluxbit/tab_component.rb +142 -0
- data/app/components/fluxbit/text_component.rb +36 -0
- data/app/components/fluxbit/tooltip_component.rb +38 -0
- data/app/helpers/fluxbit/classes_helper.rb +21 -0
- data/app/helpers/fluxbit/components_helper.rb +75 -0
- data/config/deploy.yml +37 -0
- data/config/locales/en.yml +6 -0
- data/lib/fluxbit/config/alert_component.rb +59 -0
- data/lib/fluxbit/config/avatar_component.rb +79 -0
- data/lib/fluxbit/config/badge_component.rb +77 -0
- data/lib/fluxbit/config/button_component.rb +86 -0
- data/lib/fluxbit/config/card_component.rb +32 -0
- data/lib/fluxbit/config/flex_component.rb +63 -0
- data/lib/fluxbit/config/form/helper_text_component.rb +20 -0
- data/lib/fluxbit/config/gravatar_component.rb +19 -0
- data/lib/fluxbit/config/heading_component.rb +39 -0
- data/lib/fluxbit/config/modal_component.rb +71 -0
- data/lib/fluxbit/config/paragraph_component.rb +11 -0
- data/lib/fluxbit/config/popover_component.rb +33 -0
- data/lib/fluxbit/config/tab_component.rb +131 -0
- data/lib/fluxbit/config/text_component.rb +110 -0
- data/lib/fluxbit/config/tooltip_component.rb +11 -0
- data/lib/fluxbit/view_components/codemods/v3_slot_setters.rb +222 -0
- data/lib/fluxbit/view_components/engine.rb +36 -0
- data/lib/fluxbit/view_components/version.rb +7 -0
- data/lib/fluxbit/view_components.rb +30 -0
- data/lib/fluxbit_view_components.rb +3 -0
- data/lib/install/install.rb +64 -0
- data/lib/tasks/fluxbit_view_components_tasks.rake +22 -0
- metadata +238 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fluxbit::Config::HeadingComponent
|
4
|
+
mattr_accessor :size, default: 1
|
5
|
+
mattr_accessor :spacing, default: :tight
|
6
|
+
mattr_accessor :line_height, default: :none
|
7
|
+
|
8
|
+
# rubocop: disable Layout/LineLength, Metrics/BlockLength
|
9
|
+
mattr_accessor :styles do
|
10
|
+
{
|
11
|
+
base: "mb-4 text-gray-900 dark:text-white",
|
12
|
+
sizes: {
|
13
|
+
h1: "text-5xl font-extrabold md:text-6xl lg:text-7xl",
|
14
|
+
h2: "text-4xl font-bold md:text-5xl lg:text-6xl",
|
15
|
+
h3: "text-3xl font-bold md:text-4xl lg:text-5xl",
|
16
|
+
h4: "text-2xl font-bold md:text-3xl lg:text-4xl",
|
17
|
+
h5: "text-xl font-bold md:text-2xl lg:text-3xl",
|
18
|
+
h6: "text-lg font-bold md:text-xl lg:text-2xl"
|
19
|
+
},
|
20
|
+
spacings: {
|
21
|
+
tighter: "tracking-tighter",
|
22
|
+
tight: "tracking-tight",
|
23
|
+
normal: "tracking-normal",
|
24
|
+
wide: "tracking-wide",
|
25
|
+
wider: "tracking-wider",
|
26
|
+
widest: "tracking-widest"
|
27
|
+
},
|
28
|
+
line_heights: {
|
29
|
+
none: "leading-none",
|
30
|
+
tight: "leading-tight",
|
31
|
+
snug: "leading-snug",
|
32
|
+
normal: "leading-normal",
|
33
|
+
relaxed: "leading-relaxed",
|
34
|
+
loose: "leading-loose"
|
35
|
+
}
|
36
|
+
}
|
37
|
+
end
|
38
|
+
# rubocop: enable Layout/LineLength, Metrics/BlockLength
|
39
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fluxbit::Config::ModalComponent
|
4
|
+
mattr_accessor :opened, default: false
|
5
|
+
mattr_accessor :close_button, default: true
|
6
|
+
mattr_accessor :flat, default: false
|
7
|
+
mattr_accessor :size, default: 1
|
8
|
+
mattr_accessor :only_css, default: false
|
9
|
+
mattr_accessor :static, default: false
|
10
|
+
mattr_accessor :placement, default: nil
|
11
|
+
|
12
|
+
# rubocop: disable Layout/LineLength, Metrics/BlockLength
|
13
|
+
mattr_accessor :styles do
|
14
|
+
{
|
15
|
+
root: {
|
16
|
+
base: "fixed inset-x-0 top-0 z-50 h-screen overflow-y-auto overflow-x-hidden md:inset-0 md:h-full flex",
|
17
|
+
backdrop: "bg-gray-900/50 dark:bg-gray-900/80",
|
18
|
+
show: {
|
19
|
+
on: "",
|
20
|
+
off: "hidden"
|
21
|
+
},
|
22
|
+
size: [
|
23
|
+
"max-w-sm",
|
24
|
+
"max-w-md",
|
25
|
+
"max-w-lg",
|
26
|
+
"max-w-xl",
|
27
|
+
"max-w-2xl",
|
28
|
+
"max-w-3xl",
|
29
|
+
"max-w-4xl",
|
30
|
+
"max-w-5xl",
|
31
|
+
"max-w-6xl",
|
32
|
+
"max-w-7xl"
|
33
|
+
],
|
34
|
+
placements: {
|
35
|
+
"top-left": "items-start justify-start",
|
36
|
+
"top-center": "items-start justify-center",
|
37
|
+
"top-right": "items-start justify-end",
|
38
|
+
"center-left": "items-center justify-start",
|
39
|
+
"center": "items-center justify-center",
|
40
|
+
"center-right": "items-center justify-end",
|
41
|
+
"bottom-right": "items-end justify-end",
|
42
|
+
"bottom-center": "items-end justify-center",
|
43
|
+
"bottom-left": "items-end justify-start"
|
44
|
+
}
|
45
|
+
},
|
46
|
+
content: {
|
47
|
+
base: "relative h-full w-full p-4 md:h-auto",
|
48
|
+
inner: "relative flex max-h-[90dvh] flex-col rounded-lg bg-white shadow-sm dark:bg-gray-700"
|
49
|
+
},
|
50
|
+
body: {
|
51
|
+
base: "flex-1 overflow-auto p-6",
|
52
|
+
flat: "pt-0",
|
53
|
+
no_title: "-mt-4"
|
54
|
+
},
|
55
|
+
header: {
|
56
|
+
base: "flex items-start justify-between rounded-t border-b p-5 dark:border-gray-600",
|
57
|
+
flat: "border-b-0 p-2",
|
58
|
+
title: "text-xl font-medium text-gray-900 dark:text-white",
|
59
|
+
close: {
|
60
|
+
base: "close-button ml-auto inline-flex items-center rounded-lg bg-transparent p-1.5 text-sm text-gray-400 hover:bg-gray-200 hover:text-gray-900 dark:hover:bg-gray-600 dark:hover:text-white",
|
61
|
+
icon: "h-5 w-5"
|
62
|
+
}
|
63
|
+
},
|
64
|
+
footer: {
|
65
|
+
base: "flex items-center space-x-2 rounded-b border-t border-gray-200 p-6 dark:border-gray-600",
|
66
|
+
flat: "border-t-0"
|
67
|
+
}
|
68
|
+
}
|
69
|
+
end
|
70
|
+
# rubocop: enable Layout/LineLength, Metrics/BlockLength
|
71
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fluxbit::Config::ParagraphComponent
|
4
|
+
# rubocop: disable Layout/LineLength, Metrics/BlockLength
|
5
|
+
mattr_accessor :styles do
|
6
|
+
{
|
7
|
+
base: "mb-3 text-gray-500 dark:text-gray-400"
|
8
|
+
}
|
9
|
+
end
|
10
|
+
# rubocop: enable Layout/LineLength, Metrics/BlockLength
|
11
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fluxbit::Config::PopoverComponent
|
4
|
+
mattr_accessor :has_arrow, default: true
|
5
|
+
mattr_accessor :image_position, default: :right
|
6
|
+
mattr_accessor :image_props, default: {}
|
7
|
+
mattr_accessor :size, default: 2
|
8
|
+
|
9
|
+
# rubocop: disable Layout/LineLength, Metrics/BlockLength
|
10
|
+
mattr_accessor :styles do
|
11
|
+
{
|
12
|
+
base: "absolute z-10 invisible inline-block text-sm text-gray-500 transition-opacity duration-300 bg-white border border-gray-200 rounded-lg shadow-xs opacity-0 dark:text-gray-400 dark:border-gray-600 dark:bg-gray-800",
|
13
|
+
size: [
|
14
|
+
"w-24",
|
15
|
+
"w-32",
|
16
|
+
"w-48",
|
17
|
+
"w-64",
|
18
|
+
"w-96"
|
19
|
+
],
|
20
|
+
title: {
|
21
|
+
div: "px-3 py-2 bg-gray-100 border-b border-gray-200 rounded-t-lg dark:border-gray-600 dark:bg-gray-700",
|
22
|
+
h3: "font-semibold text-gray-900 dark:text-white"
|
23
|
+
},
|
24
|
+
content: "px-3 py-2",
|
25
|
+
image_base: "grid grid-cols-5",
|
26
|
+
image_content: {
|
27
|
+
text: "col-span-3 p-3 space-y-2",
|
28
|
+
image: "h-full col-span-2"
|
29
|
+
}
|
30
|
+
}
|
31
|
+
end
|
32
|
+
# rubocop: enable Layout/LineLength, Metrics/BlockLength
|
33
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fluxbit::Config::TabComponent
|
4
|
+
mattr_accessor :variant, default: :default
|
5
|
+
mattr_accessor :color, default: :blue
|
6
|
+
mattr_accessor :vertical, default: false
|
7
|
+
mattr_accessor :tab_panel, default: :default
|
8
|
+
|
9
|
+
# rubocop: disable Layout/LineLength, Metrics/BlockLength
|
10
|
+
mattr_accessor :styles do
|
11
|
+
{
|
12
|
+
div: {
|
13
|
+
horizontal: "",
|
14
|
+
vertical: "md:flex"
|
15
|
+
},
|
16
|
+
tab_list: {
|
17
|
+
ul: {
|
18
|
+
horizontal: "flex text-center",
|
19
|
+
vertical: "flex-column space-y space-y-4 text-sm font-medium text-gray-500 dark:text-gray-400 md:me-4 mb-4 md:mb-0"
|
20
|
+
},
|
21
|
+
li: "",
|
22
|
+
variant: {
|
23
|
+
default: "flex-wrap text-sm font-medium text-gray-500 border-b border-gray-200 dark:border-gray-700 dark:text-gray-400",
|
24
|
+
underline: "-mb-px flex-wrap border-b border-gray-200 dark:border-gray-700",
|
25
|
+
pills: "flex-wrap space-x-2 text-sm font-medium text-gray-500 dark:text-gray-400",
|
26
|
+
full_width: "grid w-full grid-flow-col divide-x divide-gray-200 rounded-none text-sm font-medium shadow dark:divide-gray-700 dark:text-gray-400"
|
27
|
+
},
|
28
|
+
tab_item: {
|
29
|
+
base: "inline-flex w-full",
|
30
|
+
variant: {
|
31
|
+
default: {
|
32
|
+
base: "inline-block p-4 rounded-t-lg",
|
33
|
+
active: {
|
34
|
+
blue: "text-blue-600 bg-gray-100 active dark:bg-gray-800 dark:text-blue-500",
|
35
|
+
cyan: "text-cyan-600 bg-gray-100 active dark:bg-gray-800 dark:text-cyan-500",
|
36
|
+
green: "text-green-600 bg-gray-100 active dark:bg-gray-800 dark:text-green-500",
|
37
|
+
indigo: "text-indigo-600 bg-gray-100 active dark:bg-gray-800 dark:text-indigo-500",
|
38
|
+
pink: "text-pink-600 bg-gray-100 active dark:bg-gray-800 dark:text-pink-500",
|
39
|
+
purple: "text-purple-600 bg-gray-100 active dark:bg-gray-800 dark:text-purple-500",
|
40
|
+
red: "text-red-600 bg-gray-100 active dark:bg-gray-800 dark:text-red-500",
|
41
|
+
yellow: "text-yellow-600 bg-gray-100 active dark:bg-gray-800 dark:text-yellow-500",
|
42
|
+
gray: "text-gray-600 bg-gray-100 active dark:bg-gray-700 dark:text-white"
|
43
|
+
},
|
44
|
+
inactive: "hover:text-gray-600 hover:bg-gray-50 dark:hover:bg-gray-800 dark:hover:text-gray-300",
|
45
|
+
disabled: "text-gray-400 cursor-not-allowed dark:text-gray-500"
|
46
|
+
},
|
47
|
+
underline: {
|
48
|
+
base: "inline-block p-4 rounded-t-lg border-b-2 ",
|
49
|
+
active: {
|
50
|
+
blue: "active text-blue-600 border-blue-600 dark:text-blue-500 dark:border-blue-500",
|
51
|
+
cyan: "active text-cyan-600 border-cyan-600 dark:text-cyan-500 dark:border-cyan-500",
|
52
|
+
green: "active text-green-600 border-green-600 dark:text-green-500 dark:border-green-500",
|
53
|
+
indigo: "active text-indigo-600 border-indigo-600 dark:text-indigo-500 dark:border-indigo-500",
|
54
|
+
pink: "active text-pink-600 border-pink-600 dark:text-pink-500 dark:border-pink-500",
|
55
|
+
purple: "active text-purple-600 border-purple-600 dark:text-purple-500 dark:border-purple-500",
|
56
|
+
red: "active text-red-600 border-red-600 dark:text-red-500 dark:border-red-500",
|
57
|
+
yellow: "active text-yellow-600 border-yellow-600 dark:text-yellow-500 dark:border-yellow-500",
|
58
|
+
gray: "active text-gray-600 border-gray-600 dark:text-gray-500 dark:border-gray-500"
|
59
|
+
},
|
60
|
+
inactive: "border-transparent hover:text-gray-600 hover:border-gray-300 dark:hover:text-gray-300",
|
61
|
+
disabled: "text-gray-400 border-transparent cursor-not-allowed dark:text-gray-500"
|
62
|
+
},
|
63
|
+
pills: {
|
64
|
+
base: "inline-block px-4 py-3 rounded-lg",
|
65
|
+
active: {
|
66
|
+
blue: "active text-white bg-blue-600",
|
67
|
+
cyan: "active text-white bg-cyan-600",
|
68
|
+
green: "active text-white bg-green-600",
|
69
|
+
indigo: "active text-white bg-indigo-600",
|
70
|
+
pink: "active text-white bg-pink-600",
|
71
|
+
purple: "active text-white bg-purple-600",
|
72
|
+
red: "active text-white bg-red-600",
|
73
|
+
yellow: "active text-white bg-yellow-600",
|
74
|
+
gray: "active text-white bg-gray-600"
|
75
|
+
},
|
76
|
+
inactive: "hover:text-gray-900 hover:bg-gray-100 dark:hover:bg-gray-800 dark:hover:text-white",
|
77
|
+
disabled: "text-gray-400 dark:text-gray-500 cursor-not-allowed"
|
78
|
+
},
|
79
|
+
full_width: {
|
80
|
+
base: "inline-block w-full p-4 border-r border-gray-200 dark:border-gray-700 focus:ring-2 focus:ring-blue-300 focus:outline-none",
|
81
|
+
active: {
|
82
|
+
blue: "text-blue-600 bg-gray-100 active dark:text-blue-500 dark:bg-gray-800",
|
83
|
+
cyan: "text-cyan-600 bg-gray-100 active dark:text-cyan-500 dark:bg-gray-800",
|
84
|
+
green: "text-green-600 bg-gray-100 active dark:text-green-500 dark:bg-gray-800",
|
85
|
+
indigo: "text-indigo-600 bg-gray-100 active dark:text-indigo-500 dark:bg-gray-800",
|
86
|
+
pink: "text-pink-600 bg-gray-100 active dark:text-pink-500 dark:bg-gray-800",
|
87
|
+
purple: "text-purple-600 bg-gray-100 active dark:text-purple-500 dark:bg-gray-800",
|
88
|
+
red: "text-red-600 bg-gray-100 active dark:text-red-500 dark:bg-gray-800",
|
89
|
+
yellow: "text-yellow-600 bg-gray-100 active dark:text-yellow-500 dark:bg-gray-800",
|
90
|
+
gray: "active text-gray-900 bg-gray-100 dark:bg-gray-700 dark:text-white"
|
91
|
+
},
|
92
|
+
inactive: "bg-white hover:text-gray-700 hover:bg-gray-50 dark:hover:text-white dark:bg-gray-800 dark:hover:bg-gray-700",
|
93
|
+
disabled: "cursor-not-allowed",
|
94
|
+
first: "rounded-s-lg",
|
95
|
+
last: "rounded-e-lg",
|
96
|
+
middle: ""
|
97
|
+
}
|
98
|
+
},
|
99
|
+
icon: "mr-2 h-5 w-5"
|
100
|
+
}
|
101
|
+
},
|
102
|
+
tabpanel_container: {
|
103
|
+
horizontal: "",
|
104
|
+
vertical: "w-full"
|
105
|
+
},
|
106
|
+
tabpanel: {
|
107
|
+
horizontal: {
|
108
|
+
none: {
|
109
|
+
active: "",
|
110
|
+
inactive: "hidden"
|
111
|
+
},
|
112
|
+
default: {
|
113
|
+
active: "p-4 rounded-b-lg bg-gray-50 dark:bg-gray-800",
|
114
|
+
inactive: "p-4 rounded-b-lg bg-gray-50 dark:bg-gray-800 hidden"
|
115
|
+
}
|
116
|
+
},
|
117
|
+
vertical: {
|
118
|
+
none: {
|
119
|
+
active: "",
|
120
|
+
inactive: "hidden"
|
121
|
+
},
|
122
|
+
default: {
|
123
|
+
active: "p-6 bg-gray-50 text-medium text-gray-500 dark:text-gray-400 dark:bg-gray-800 rounded-lg h-full",
|
124
|
+
inactive: "p-6 bg-gray-50 text-medium text-gray-500 dark:text-gray-400 dark:bg-gray-800 rounded-lg h-full hidden"
|
125
|
+
}
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
end
|
130
|
+
# rubocop: enable Layout/LineLength, Metrics/BlockLength
|
131
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fluxbit::Config::TextComponent
|
4
|
+
# rubocop: disable Layout/LineLength, Metrics/BlockLength
|
5
|
+
mattr_accessor :styles do
|
6
|
+
{
|
7
|
+
color: {
|
8
|
+
blue: "text-blue-600 dark:text-blue-500",
|
9
|
+
red: "text-red-600 dark:text-red-500",
|
10
|
+
green: "text-green-600 dark:text-green-500",
|
11
|
+
yellow: "text-yellow-600 dark:text-yellow-500",
|
12
|
+
purple: "text-purple-600 dark:text-purple-500",
|
13
|
+
pink: "text-pink-600 dark:text-pink-500",
|
14
|
+
orange: "text-orange-600 dark:text-orange-500",
|
15
|
+
teal: "text-teal-600 dark:text-teal-500",
|
16
|
+
cyan: "text-cyan-600 dark:text-cyan-500",
|
17
|
+
indigo: "text-indigo-600 dark:text-indigo-500",
|
18
|
+
blue_to_green: "text-transparent bg-clip-text bg-gradient-to-r to-emerald-600 from-sky-400",
|
19
|
+
blue_to_purple: "text-transparent bg-clip-text bg-gradient-to-r from-blue-500 to-purple-500",
|
20
|
+
red_to_yellow: "text-transparent bg-clip-text bg-gradient-to-r from-red-500 to-yellow-500",
|
21
|
+
green_to_blue: "text-transparent bg-clip-text bg-gradient-to-r from-green-500 to-blue-500",
|
22
|
+
purple_to_pink: "text-transparent bg-clip-text bg-gradient-to-r from-purple-500 to-pink-500",
|
23
|
+
orange_to_red: "text-transparent bg-clip-text bg-gradient-to-r from-orange-500 to-red-500"
|
24
|
+
},
|
25
|
+
bg_color: {
|
26
|
+
blue: "px-2 bg-blue-600 rounded-sm dark:bg-blue-500",
|
27
|
+
red: "px-2 bg-red-600 rounded-sm dark:bg-red-500",
|
28
|
+
green: "px-2 text-white bg-green-600 rounded-sm dark:bg-green-500",
|
29
|
+
yellow: "px-2 text-white bg-yellow-600 rounded-sm dark:bg-yellow-500",
|
30
|
+
purple: "px-2 text-white bg-purple-600 rounded-sm dark:bg-purple-500",
|
31
|
+
pink: "px-2 text-white bg-pink-600 rounded-sm dark:bg-pink-500",
|
32
|
+
orange: "px-2 text-white bg-orange-600 rounded-sm dark:bg-orange-500",
|
33
|
+
teal: "px-2 text-white bg-teal-600 rounded-sm dark:bg-teal-500",
|
34
|
+
cyan: "px-2 text-white bg-cyan-600 rounded-sm dark:bg-cyan-500",
|
35
|
+
indigo: "px-2 text-white bg-indigo-600 rounded-sm dark:bg-indigo-500",
|
36
|
+
blue_to_purple: "px-2 text-white bg-gradient-to-r from-blue-500 to-purple-500 rounded-sm",
|
37
|
+
red_to_yellow: "px-2 text-white bg-gradient-to-r from-red-500 to-yellow-500 rounded-sm",
|
38
|
+
green_to_blue: "px-2 text-white bg-gradient-to-r from-green-500 to-blue-500 rounded-sm",
|
39
|
+
purple_to_pink: "px-2 text-white bg-gradient-to-r from-purple-500 to-pink-500 rounded-sm",
|
40
|
+
orange_to_red: "px-2 text-white bg-gradient-to-r from-orange-500 to-red-500 rounded-sm"
|
41
|
+
},
|
42
|
+
size: {
|
43
|
+
xs: "text-xs",
|
44
|
+
sm: "text-sm",
|
45
|
+
base: "text-base",
|
46
|
+
lg: "text-lg",
|
47
|
+
xl: "text-xl",
|
48
|
+
"2xl": "text-2xl",
|
49
|
+
"3xl": "text-3xl",
|
50
|
+
"4xl": "text-4xl",
|
51
|
+
"5xl": "text-5xl",
|
52
|
+
"6xl": "text-6xl"
|
53
|
+
},
|
54
|
+
weight: {
|
55
|
+
thin: "font-thin",
|
56
|
+
extralight: "font-extralight",
|
57
|
+
light: "font-light",
|
58
|
+
normal: "font-normal",
|
59
|
+
medium: "font-medium",
|
60
|
+
semibold: "font-semibold",
|
61
|
+
bold: "font-bold",
|
62
|
+
extrabold: "font-extrabold",
|
63
|
+
black: "font-black"
|
64
|
+
},
|
65
|
+
transform: {
|
66
|
+
uppercase: "uppercase",
|
67
|
+
lowercase: "lowercase",
|
68
|
+
capitalize: "capitalize"
|
69
|
+
},
|
70
|
+
decoration_line: {
|
71
|
+
underline: "underline",
|
72
|
+
overline: "overline",
|
73
|
+
line_through: "line-through"
|
74
|
+
},
|
75
|
+
decoration_type: {
|
76
|
+
double: "decoration-double",
|
77
|
+
dotted: "decoration-dotted",
|
78
|
+
dashed: "decoration-dashed",
|
79
|
+
wavy: "decoration-wavy"
|
80
|
+
},
|
81
|
+
decoration_color: {
|
82
|
+
blue: "decoration-blue-400 dark:decoration-blue-600",
|
83
|
+
red: "decoration-red-400 dark:decoration-red-600",
|
84
|
+
green: "decoration-green-400 dark:decoration-green-600",
|
85
|
+
yellow: "decoration-yellow-400 dark:decoration-yellow-600",
|
86
|
+
purple: "decoration-purple-400 dark:decoration-purple-600",
|
87
|
+
pink: "decoration-pink-400 dark:decoration-pink-600",
|
88
|
+
orange: "decoration-orange-400 dark:decoration-orange-600",
|
89
|
+
teal: "decoration-teal-400 dark:decoration-teal-600",
|
90
|
+
cyan: "decoration-cyan-400 dark:decoration-cyan-600",
|
91
|
+
indigo: "decoration-indigo-400 dark:decoration-indigo-600"
|
92
|
+
},
|
93
|
+
decoration_tickness: [
|
94
|
+
"decoration-0",
|
95
|
+
"decoration-1",
|
96
|
+
"decoration-2",
|
97
|
+
"decoration-4",
|
98
|
+
"decoration-8"
|
99
|
+
],
|
100
|
+
underline_offset: [
|
101
|
+
"underline-offset-0",
|
102
|
+
"underline-offset-1",
|
103
|
+
"underline-offset-2",
|
104
|
+
"underline-offset-4",
|
105
|
+
"underline-offset-8"
|
106
|
+
]
|
107
|
+
}
|
108
|
+
end
|
109
|
+
# rubocop: enable Layout/LineLength, Metrics/BlockLength
|
110
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fluxbit::Config::TooltipComponent
|
4
|
+
# rubocop: disable Layout/LineLength, Metrics/BlockLength
|
5
|
+
mattr_accessor :styles do
|
6
|
+
{
|
7
|
+
base: "absolute z-10 invisible inline-block px-3 py-2 text-sm font-medium text-white transition-opacity duration-300 bg-gray-900 rounded-lg shadow-xs opacity-0 tooltip dark:bg-gray-700"
|
8
|
+
}
|
9
|
+
end
|
10
|
+
# rubocop: enable Layout/LineLength, Metrics/BlockLength
|
11
|
+
end
|
@@ -0,0 +1,222 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Fluxbit
|
4
|
+
module ViewComponents
|
5
|
+
# Usage:
|
6
|
+
#
|
7
|
+
# Run via rake task:
|
8
|
+
#
|
9
|
+
# bin/rails fluxbit_view_components:detect_legacy_slots
|
10
|
+
# bin/rails fluxbit_view_components:migrate_legacy_slots
|
11
|
+
# bin/rails fluxbit_view_components:migrate_legacy_slots app/views
|
12
|
+
#
|
13
|
+
# Or run via rails console if you need to pass custom paths:
|
14
|
+
#
|
15
|
+
# Fluxbit::ViewComponents::Codemods::V3SlotSetters.new(
|
16
|
+
# view_path: Rails.root.join("app/views"),
|
17
|
+
# ).call
|
18
|
+
module Codemods
|
19
|
+
class V3SlotSetters
|
20
|
+
TEMPLATE_LANGUAGES = %w[erb slim haml].join(",").freeze
|
21
|
+
RENDER_REGEX = /render[( ](?<component>\w+(?:::\w+)*)\.new[) ]+(do|\{) \|(?<arg>\w+)\b/ # standard:disable Lint/MixedRegexpCaptureTypes
|
22
|
+
|
23
|
+
Suggestion = Struct.new(:file, :line, :message)
|
24
|
+
|
25
|
+
def initialize(view_component_path: [], view_path: [], migrate: false)
|
26
|
+
Rails.application.eager_load!
|
27
|
+
|
28
|
+
@view_component_path = view_component_path
|
29
|
+
@view_path = view_path
|
30
|
+
@migrate = migrate
|
31
|
+
end
|
32
|
+
|
33
|
+
def call
|
34
|
+
puts "Using ViewComponent path: #{view_component_paths.join(", ")}"
|
35
|
+
puts "Using Views path: #{view_paths.join(", ")}"
|
36
|
+
puts "#{view_components.size} ViewComponents found"
|
37
|
+
puts "#{slottable_components.size} ViewComponents using Slots found"
|
38
|
+
puts "#{view_component_files.size} ViewComponent templates found"
|
39
|
+
puts "#{view_files.size} view files found"
|
40
|
+
process_all_files
|
41
|
+
end
|
42
|
+
|
43
|
+
def process_all_files
|
44
|
+
all_files.each do |file|
|
45
|
+
process_file(file)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def process_file(file)
|
50
|
+
@suggestions = []
|
51
|
+
@suggestions += scan_exact_matches(file)
|
52
|
+
@suggestions += scan_uncertain_matches(file)
|
53
|
+
|
54
|
+
return unless @suggestions.any?
|
55
|
+
|
56
|
+
puts
|
57
|
+
puts "File: #{file}"
|
58
|
+
@suggestions.each do |s|
|
59
|
+
puts "=> line #{s.line}: #{s.message}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def scan_exact_matches(file)
|
66
|
+
[].tap do |suggestions|
|
67
|
+
rendered_components = []
|
68
|
+
content = File.read(file)
|
69
|
+
|
70
|
+
if (render_match = content.match(RENDER_REGEX))
|
71
|
+
component = render_match[:component]
|
72
|
+
arg = render_match[:arg]
|
73
|
+
|
74
|
+
if registered_slots.key?(component.constantize)
|
75
|
+
used_slots_names = registered_slots[component.constantize]
|
76
|
+
rendered_components << { component: component, arg: arg, slots: used_slots_names }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
File.open(file, "r+") do |f|
|
81
|
+
lines = []
|
82
|
+
f.each_line do |line|
|
83
|
+
rendered_components.each do |rendered_component|
|
84
|
+
arg = rendered_component[:arg]
|
85
|
+
slots = rendered_component[:slots]
|
86
|
+
|
87
|
+
if (matches = line.scan(/#{arg}\.#{Regexp.union(slots)}/))
|
88
|
+
matches.each do |match|
|
89
|
+
new_value = match.gsub("#{arg}.", "#{arg}.with_")
|
90
|
+
message = if @migrate
|
91
|
+
"replaced `#{match}` with `#{new_value}`"
|
92
|
+
else
|
93
|
+
"probably replace `#{match}` with `#{new_value}`"
|
94
|
+
end
|
95
|
+
suggestions << Suggestion.new(file, f.lineno, message)
|
96
|
+
if @migrate
|
97
|
+
line.gsub!("#{arg}.", "#{arg}.with_")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
lines << line
|
103
|
+
end
|
104
|
+
|
105
|
+
if @migrate
|
106
|
+
f.rewind
|
107
|
+
f.write(lines.join)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def scan_uncertain_matches(file)
|
114
|
+
[].tap do |suggestions|
|
115
|
+
File.open(file, "r+") do |f|
|
116
|
+
lines = []
|
117
|
+
f.each_line do |line|
|
118
|
+
if (matches = line.scan(/(?<!\s)\.(?<slot>#{Regexp.union(all_registered_slot_names)})\b/))
|
119
|
+
matches.flatten.each do |match|
|
120
|
+
next if @suggestions.find { |s| s.file == file && s.line == f.lineno }
|
121
|
+
|
122
|
+
message = if @migrate
|
123
|
+
"replaced `#{match}` with `with_#{match}`"
|
124
|
+
else
|
125
|
+
"maybe replace `#{match}` with `with_#{match}`"
|
126
|
+
end
|
127
|
+
suggestions << Suggestion.new(file, f.lineno, message)
|
128
|
+
if @migrate
|
129
|
+
line.gsub!(/(?<!\s)\.(#{match})\b/, ".with_\\1")
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
lines << line
|
134
|
+
end
|
135
|
+
|
136
|
+
if @migrate
|
137
|
+
f.rewind
|
138
|
+
f.write(lines.join)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def view_components
|
145
|
+
ViewComponent::Base.descendants
|
146
|
+
end
|
147
|
+
|
148
|
+
def slottable_components
|
149
|
+
view_components.select do |comp|
|
150
|
+
comp.registered_slots.any?
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def registered_slots
|
155
|
+
@registered_slots ||= {}.tap do |slots|
|
156
|
+
puts
|
157
|
+
puts "Detected slots:"
|
158
|
+
slottable_components.each do |comp|
|
159
|
+
puts "- `#{comp}` has slots: #{comp.registered_slots.keys.join(", ")}"
|
160
|
+
slots[comp] = comp.registered_slots.map do |slot_name, slot|
|
161
|
+
normalized_slot_name(slot_name, slot)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def all_registered_slot_names
|
168
|
+
@all_registered_slot_names ||= registered_slots.values.flatten.uniq
|
169
|
+
end
|
170
|
+
|
171
|
+
def view_component_files
|
172
|
+
Dir.glob(Pathname.new(File.join(view_component_path_glob, "**", "*.{rb,#{TEMPLATE_LANGUAGES}}")))
|
173
|
+
end
|
174
|
+
|
175
|
+
def view_files
|
176
|
+
Dir.glob(Pathname.new(File.join(view_path_glob, "**", "*.{#{TEMPLATE_LANGUAGES}}")))
|
177
|
+
end
|
178
|
+
|
179
|
+
def all_files
|
180
|
+
view_component_files + view_files
|
181
|
+
end
|
182
|
+
|
183
|
+
def view_component_paths
|
184
|
+
@view_component_paths ||= [
|
185
|
+
Rails.application.config.view_component.view_component_path,
|
186
|
+
@view_component_path
|
187
|
+
].flatten.compact.uniq
|
188
|
+
end
|
189
|
+
|
190
|
+
def view_component_path_glob
|
191
|
+
return view_component_paths.first if view_component_paths.size == 1
|
192
|
+
|
193
|
+
"{#{view_component_paths.join(",")}}"
|
194
|
+
end
|
195
|
+
|
196
|
+
def rails_view_paths
|
197
|
+
ActionController::Base.view_paths.select do |path|
|
198
|
+
path.to_s.include?(Rails.root.to_s)
|
199
|
+
end.map(&:to_s)
|
200
|
+
end
|
201
|
+
|
202
|
+
def view_paths
|
203
|
+
@view_paths ||= [
|
204
|
+
rails_view_paths,
|
205
|
+
Rails.application.config.view_component.preview_paths,
|
206
|
+
@view_path
|
207
|
+
].flatten.compact.uniq
|
208
|
+
end
|
209
|
+
|
210
|
+
def view_path_glob
|
211
|
+
return view_paths.first if view_paths.size == 1
|
212
|
+
|
213
|
+
"{#{view_paths.join(",")}}"
|
214
|
+
end
|
215
|
+
|
216
|
+
def normalized_slot_name(slot_name, slot)
|
217
|
+
slot[:collection] ? ActiveSupport::Inflector.singularize(slot_name) : slot_name.to_s
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/engine"
|
4
|
+
require "view_component"
|
5
|
+
require "view_component/version"
|
6
|
+
|
7
|
+
module Fluxbit
|
8
|
+
module ViewComponents
|
9
|
+
class Engine < ::Rails::Engine
|
10
|
+
isolate_namespace Fluxbit::ViewComponents
|
11
|
+
|
12
|
+
config.autoload_paths = %W[
|
13
|
+
#{root}/app/components
|
14
|
+
#{root}/app/helpers
|
15
|
+
]
|
16
|
+
|
17
|
+
# Remove default wrapping .field_with_errors for proper Shopify form validations
|
18
|
+
config.to_prepare do
|
19
|
+
ActionView::Base.field_error_proc = ->(html_tag, _instance) { html_tag.html_safe }
|
20
|
+
end
|
21
|
+
|
22
|
+
initializer "fluxbit_view_components.importmap", before: "importmap" do |app|
|
23
|
+
if app.config.respond_to?(:importmap) && app.config.importmap.has_key?(:cache_sweepers)
|
24
|
+
app.config.importmap.cache_sweepers << Engine.root.join("app/assets/javascripts")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
initializer "fluxbit_view_components.helpers" do
|
29
|
+
ActiveSupport.on_load(:action_controller_base) do
|
30
|
+
helper Fluxbit::ClassesHelper
|
31
|
+
helper Fluxbit::ComponentsHelper
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|