material_view_components 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +17 -0
- data/app/assets/builds/material_view_components/application.css +218048 -0
- data/app/assets/builds/material_view_components/application.js +1958 -0
- data/app/assets/config/material_view_components_manifest.js +1 -0
- data/app/assets/stylesheets/material_view_components/application.tailwind.css +182 -0
- data/app/components/application_component.rb +19 -0
- data/app/components/material/button_component.html.erb +10 -0
- data/app/components/material/button_component.rb +190 -0
- data/app/components/material/button_component_controller.js +8 -0
- data/app/components/material/fab_component.html.erb +8 -0
- data/app/components/material/fab_component.rb +41 -0
- data/app/controllers/material_view_components/application_controller.rb +4 -0
- data/app/helpers/material_view_components/application_helper.rb +4 -0
- data/app/javascript/application.js +2 -0
- data/app/javascript/controllers/application.js +15 -0
- data/app/javascript/controllers/hello_controller.js +7 -0
- data/app/javascript/controllers/helpers.js +30 -0
- data/app/javascript/controllers/index.js +7 -0
- data/app/jobs/material_view_components/application_job.rb +4 -0
- data/app/mailers/material_view_components/application_mailer.rb +6 -0
- data/app/models/material_view_components/application_record.rb +5 -0
- data/app/views/layouts/material_view_components/application.html.erb +19 -0
- data/config/initializers/assets.rb +3 -0
- data/config/routes.rb +2 -0
- data/lib/material_view_components/engine.rb +7 -0
- data/lib/material_view_components/version.rb +3 -0
- data/lib/material_view_components.rb +6 -0
- data/lib/tasks/material_view_components_tasks.rake +4 -0
- metadata +146 -0
@@ -0,0 +1 @@
|
|
1
|
+
//= link_tree ../builds
|
@@ -0,0 +1,182 @@
|
|
1
|
+
:root {
|
2
|
+
/* Material Design 3 colors */
|
3
|
+
--material-color-primary: #6750A4;
|
4
|
+
--material-color-primary-on-dark: #D0BCFF;
|
5
|
+
--material-color-primary-container: #EADDFF;
|
6
|
+
--material-color-primary-container-on-dark: #4F378B;
|
7
|
+
--material-color-secondary: #625B71;
|
8
|
+
--material-color-secondary-on-dark: #CCC2DC;
|
9
|
+
--material-color-secondary-container: #E8DEF8;
|
10
|
+
--material-color-secondary-container-on-dark: #4A4458;
|
11
|
+
--material-color-tertiary: #7D5260;
|
12
|
+
--material-color-tertiary-on-dark: #EFB8C8;
|
13
|
+
--material-color-tertiary-container: #FFD8E4;
|
14
|
+
--material-color-tertiary-container-on-dark: #633B48;
|
15
|
+
--material-color-surface: #FFFBFE;
|
16
|
+
--material-color-surface-on-dark: #1C1B1F;
|
17
|
+
--material-color-surface-variant: #E7E0EC;
|
18
|
+
--material-color-surface-variant-on-dark: #49454F;
|
19
|
+
--material-color-background: #FFFBFE;
|
20
|
+
--material-color-background-on-dark: #1C1B1F;
|
21
|
+
--material-color-error: #B3261E;
|
22
|
+
--material-color-error-on-dark: #F2B8B5;
|
23
|
+
--material-color-error-container: #F9DEDC;
|
24
|
+
--material-color-error-container-on-dark: #8C1D18;
|
25
|
+
--material-color-disabled-container: rgb(28 27 31 / 12%);
|
26
|
+
--material-color-disabled-container-on-dark: rgb(230 225 229 / 12%);
|
27
|
+
--material-color-on-primary: #FFFFFF;
|
28
|
+
--material-color-on-primary-on-dark: #371E73;
|
29
|
+
--material-color-on-primary-container: #21005E;
|
30
|
+
--material-color-on-primary-container-on-dark: #EADDFF;
|
31
|
+
--material-color-on-secondary: #FFFFFF;
|
32
|
+
--material-color-on-secondary-on-dark: #332D41;
|
33
|
+
--material-color-on-secondary-container: #1E192B;
|
34
|
+
--material-color-on-secondary-container-on-dark: #E8DEF8;
|
35
|
+
--material-color-on-tertiary: #FFFFFF;
|
36
|
+
--material-color-on-tertiary-on-dark: #492532;
|
37
|
+
--material-color-on-tertiary-container: #370B1E;
|
38
|
+
--material-color-on-tertiary-container-on-dark: #FFD8E4;
|
39
|
+
--material-color-on-surface: #1C1B1F;
|
40
|
+
--material-color-on-surface-on-dark: #E6E1E5;
|
41
|
+
--material-color-on-surface-variant: #49454E;
|
42
|
+
--material-color-on-surface-variant-on-dark: #CAC4D0;
|
43
|
+
--material-color-on-background: #1C1B1F;
|
44
|
+
--material-color-on-background-on-dark: #E6E1E5;
|
45
|
+
--material-color-on-error: #FFFFFF;
|
46
|
+
--material-color-on-error-on-dark: #601410;
|
47
|
+
--material-color-on-error-container: #370B1E;
|
48
|
+
--material-color-on-error-container-on-dark: #F9DEDC;
|
49
|
+
--material-color-outline: #79747E;
|
50
|
+
--material-color-outline-on-dark: #938F99;
|
51
|
+
--material-color-outline-disabled: rgb(121 116 126 / 12%);
|
52
|
+
--material-color-outline-disabled-on-dark: rgb(147 143 153 / 12%);
|
53
|
+
--material-color-shadow: #000000;
|
54
|
+
--material-color-inverse-surface: #313033;
|
55
|
+
--material-color-inverse-surface-on-dark: #E6E1E5;
|
56
|
+
--material-color-inverse-on-surface: #F4EFF4;
|
57
|
+
--material-color-inverse-on-surface-on-dark: #313033;
|
58
|
+
--material-color-inverse-primary: #D0BCFF;
|
59
|
+
--material-color-inverse-primary-on-dark: #6750A4;
|
60
|
+
|
61
|
+
/* Material Design 3 typography */
|
62
|
+
--material-typeface-brand-regular: "Roboto";
|
63
|
+
--material-typeface-weight-regular: 400;
|
64
|
+
--material-typeface-plain-medium: "Roboto";
|
65
|
+
--material-typeface-weight-medium: 500;
|
66
|
+
|
67
|
+
/* Display large */
|
68
|
+
--material-typescale-display-large-font: var(--material-typeface-brand-regular);
|
69
|
+
--material-typescale-display-large-line-height: 4rem;
|
70
|
+
--material-typescale-display-large-size: 3.5625rem;
|
71
|
+
--material-typescale-display-large-tracking: 0rem;
|
72
|
+
--material-typescale-display-large-weight: var(--material-typeface-weight-regular);
|
73
|
+
|
74
|
+
/* Display medium */
|
75
|
+
--material-typescale-display-medium-font: var(--material-typeface-brand-regular);
|
76
|
+
--material-typescale-display-medium-line-height: 3.25rem;
|
77
|
+
--material-typescale-display-medium-size: 2.8125rem;
|
78
|
+
--material-typescale-display-medium-tracking: 0rem;
|
79
|
+
--material-typescale-display-medium-weight: var(--material-typeface-weight-regular);
|
80
|
+
|
81
|
+
/* Display small */
|
82
|
+
--material-typescale-display-small-font: var(--material-typeface-brand-regular);
|
83
|
+
--material-typescale-display-small-line-height: 2.75rem;
|
84
|
+
--material-typescale-display-small-size: 2rem;
|
85
|
+
--material-typescale-display-small-tracking: 0rem;
|
86
|
+
--material-typescale-display-small-weight: var(--material-typeface-weight-regular);
|
87
|
+
|
88
|
+
/* Headline large */
|
89
|
+
--material-typescale-headline-large-font: var(--material-typeface-brand-regular);
|
90
|
+
--material-typescale-headline-large-line-height: 2.5rem;
|
91
|
+
--material-typescale-headline-large-size: 2rem;
|
92
|
+
--material-typescale-headline-large-tracking: 0rem;
|
93
|
+
--material-typescale-headline-large-weight: var(--material-typeface-weight-regular);
|
94
|
+
|
95
|
+
/* Headline medium */
|
96
|
+
--material-typescale-headline-medium-font: var(--material-typeface-brand-regular);
|
97
|
+
--material-typescale-headline-medium-line-height: 2.25rem;
|
98
|
+
--material-typescale-headline-medium-size: 1.75rem;
|
99
|
+
--material-typescale-headline-medium-tracking: 0rem;
|
100
|
+
--material-typescale-headline-medium-weight: var(--material-typeface-weight-regular);
|
101
|
+
|
102
|
+
/* Headline small */
|
103
|
+
--material-typescale-headline-small-font: var(--material-typeface-brand-regular);
|
104
|
+
--material-typescale-headline-small-line-height: 2rem;
|
105
|
+
--material-typescale-headline-small-size: 1.5rem;
|
106
|
+
--material-typescale-headline-small-tracking: 0rem;
|
107
|
+
--material-typescale-headline-small-weight: var(--material-typeface-weight-regular);
|
108
|
+
|
109
|
+
/* Title large */
|
110
|
+
--material-typescale-title-large-font: var(--material-typeface-brand-regular);
|
111
|
+
--material-typescale-title-large-line-height: 1.75rem;
|
112
|
+
--material-typescale-title-large-size: 1.375rem;
|
113
|
+
--material-typescale-title-large-tracking: 0rem;
|
114
|
+
--material-typescale-title-large-weight: var(--material-typeface-weight-regular);
|
115
|
+
|
116
|
+
/* Title medium */
|
117
|
+
--material-typescale-title-medium-font: var(--material-typeface-plain-medium);
|
118
|
+
--material-typescale-title-medium-line-height: 1.5rem;
|
119
|
+
--material-typescale-title-medium-size: 1rem;
|
120
|
+
--material-typescale-title-medium-tracking: 0.0094rem;
|
121
|
+
--material-typescale-title-medium-weight: var(--material-typeface-weight-medium);
|
122
|
+
|
123
|
+
/* Title small */
|
124
|
+
--material-typescale-title-small-font: var(--material-typeface-brand-regular);
|
125
|
+
--material-typescale-title-small-line-height: 1.75rem;
|
126
|
+
--material-typescale-title-small-size: 1.375rem;
|
127
|
+
--material-typescale-title-small-tracking: 0rem;
|
128
|
+
--material-typescale-title-small-weight: var(--material-typeface-weight-regular);
|
129
|
+
|
130
|
+
/* Label large */
|
131
|
+
--material-typescale-label-large-font: var(--material-typeface-plain-medium);
|
132
|
+
--material-typescale-label-large-line-height: 1.25rem;
|
133
|
+
--material-typescale-label-large-size: 0.875rem;
|
134
|
+
--material-typescale-label-large-tracking: 0.0063rem;
|
135
|
+
--material-typescale-label-large-weight: var(--material-typeface-weight-medium);
|
136
|
+
|
137
|
+
/* Label medium */
|
138
|
+
--material-typescale-label-medium-font: var(--material-typeface-plain-medium);
|
139
|
+
--material-typescale-label-medium-line-height: 1rem;
|
140
|
+
--material-typescale-label-medium-size: 0.75rem;
|
141
|
+
--material-typescale-label-medium-tracking: 0.0063rem;
|
142
|
+
--material-typescale-label-medium-weight: var(--material-typeface-weight-medium);
|
143
|
+
|
144
|
+
/* Label small */
|
145
|
+
--material-typescale-label-small-font: var(--material-typeface-plain-medium);
|
146
|
+
--material-typescale-label-small-line-height: 0.375rem;
|
147
|
+
--material-typescale-label-small-size: 0.6875rem;
|
148
|
+
--material-typescale-label-small-tracking: 0.0313rem;
|
149
|
+
--material-typescale-label-small-weight: var(--material-typeface-weight-medium);
|
150
|
+
|
151
|
+
/* Body large */
|
152
|
+
--material-typescale-body-large-font: var(--material-typeface-plain-medium);
|
153
|
+
--material-typescale-body-large-line-height: 1.5rem;
|
154
|
+
--material-typescale-body-large-size: 1rem;
|
155
|
+
--material-typescale-body-large-tracking: 0.0094rem;
|
156
|
+
--material-typescale-body-large-weight: var(--material-typeface-weight-regular);
|
157
|
+
|
158
|
+
/* Body medium */
|
159
|
+
--material-typescale-body-medium-font: var(--material-typeface-plain-medium);
|
160
|
+
--material-typescale-body-medium-line-height: 1.25rem;
|
161
|
+
--material-typescale-body-medium-size: 0.875rem;
|
162
|
+
--material-typescale-body-medium-tracking: 0.0156rem;
|
163
|
+
--material-typescale-body-medium-weight: var(--material-typeface-weight-regular);
|
164
|
+
|
165
|
+
/* Body small */
|
166
|
+
--material-typescale-body-small-font: var(--material-typeface-plain-medium);
|
167
|
+
--material-typescale-body-small-line-height: 1rem;
|
168
|
+
--material-typescale-body-small-size: 0.75rem;
|
169
|
+
--material-typescale-body-small-tracking: 0.025rem;
|
170
|
+
--material-typescale-body-small-weight: var(--material-typeface-weight-regular);
|
171
|
+
|
172
|
+
/* Material Design overlay opacity values */
|
173
|
+
--material-state-hover-overlay-opacity: 8%;
|
174
|
+
--material-state-focus-overlay-opacity: 12%;
|
175
|
+
--material-state-pressed-overlay-opacity: 12%;
|
176
|
+
--material-state-dragged-overlay-opacity: 16%;
|
177
|
+
--material-state-disabled-content-overlay-opacity: 38%;
|
178
|
+
--material-state-disabled-container-overlay-opacity: 12%;
|
179
|
+
}
|
180
|
+
|
181
|
+
@tailwind base;
|
182
|
+
@tailwind utilities;
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class ApplicationComponent < ViewComponent::Base
|
4
|
+
def identifier
|
5
|
+
klass = self.class
|
6
|
+
|
7
|
+
klass.name
|
8
|
+
.tableize
|
9
|
+
.singularize
|
10
|
+
.gsub("/", "--")
|
11
|
+
.gsub("_", "-")
|
12
|
+
end
|
13
|
+
|
14
|
+
def sanitize(string)
|
15
|
+
string
|
16
|
+
.strip
|
17
|
+
.gsub(/\s{2,}|\n/, " ")
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= button_to @name, @html_options.merge(form_class: "", class: container_classes, data: { controller: identifier }) do %>
|
2
|
+
<div class="<%= content_classes %>">
|
3
|
+
<%= icon %>
|
4
|
+
<%= text %>
|
5
|
+
</div>
|
6
|
+
<% unless disabled %>
|
7
|
+
<div class="<%= overlay_classes %>">
|
8
|
+
</div>
|
9
|
+
<% end %>
|
10
|
+
<% end %>
|
@@ -0,0 +1,190 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Material::ButtonComponent < ApplicationComponent
|
4
|
+
renders_one :text, -> (text) do
|
5
|
+
content_tag :span do
|
6
|
+
text
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
renders_one :icon, -> (name = nil, &block) do
|
11
|
+
if block
|
12
|
+
content_tag :span, class: "material-pr-2" do
|
13
|
+
block.call
|
14
|
+
end
|
15
|
+
else
|
16
|
+
content_tag :span, class: "material-icons material-pr-2" do
|
17
|
+
name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :disabled
|
23
|
+
attr_reader :button_type
|
24
|
+
|
25
|
+
def initialize(name = "", html_options = {}, disabled: false, button_type: :filled)
|
26
|
+
@name = name
|
27
|
+
@html_options = disabled ? html_options.merge(disabled: "disabled") : html_options
|
28
|
+
@disabled = disabled
|
29
|
+
@button_type = button_type
|
30
|
+
end
|
31
|
+
|
32
|
+
def container_classes
|
33
|
+
send :"#{button_type}_button_container_classes"
|
34
|
+
end
|
35
|
+
|
36
|
+
def content_classes
|
37
|
+
send :"#{button_type}_button_content_classes"
|
38
|
+
end
|
39
|
+
|
40
|
+
def overlay_classes
|
41
|
+
send :"#{button_type}_button_overlay_classes"
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def filled_button_container_classes
|
47
|
+
sanitize <<-CLASSES
|
48
|
+
material-relative #{icon ? "material-pl-4 material-pr-6" : "material-px-6"}
|
49
|
+
material-h-10 material-rounded-full #{disabled ?
|
50
|
+
"material-bg-disabled-container dark:material-bg-disabled-container-on-dark
|
51
|
+
material-cursor-default" : "material-bg-primary
|
52
|
+
dark:material-bg-primary-on-dark hover:material-shadow"}
|
53
|
+
CLASSES
|
54
|
+
end
|
55
|
+
|
56
|
+
def filled_button_content_classes
|
57
|
+
sanitize <<-CLASSES
|
58
|
+
material-flex material-items-center #{disabled ? "material-text-on-surface
|
59
|
+
dark:material-text-on-surface-on-dark material-opacity-disabled-content" :
|
60
|
+
"material-text-on-primary dark:material-text-on-primary-on-dark"}
|
61
|
+
material-text-label-large material-font-medium material-font-label
|
62
|
+
material-leading-label-large material-tracking-label-large
|
63
|
+
CLASSES
|
64
|
+
end
|
65
|
+
|
66
|
+
def filled_button_overlay_classes
|
67
|
+
sanitize <<-CLASSES
|
68
|
+
material-absolute material-w-full material-inset-0 material-rounded-full
|
69
|
+
material-bg-on-primary dark:material-bg-on-primary-on-dark
|
70
|
+
material-opacity-0 hover:material-opacity-hover focus:material-opacity-focus
|
71
|
+
active:material-opacity-pressed
|
72
|
+
CLASSES
|
73
|
+
end
|
74
|
+
|
75
|
+
def tonal_button_container_classes
|
76
|
+
sanitize <<-CLASSES
|
77
|
+
material-relative #{icon ? "material-pl-4 material-pr-6" : "material-px-6"}
|
78
|
+
material-h-10 material-rounded-full #{disabled ?
|
79
|
+
"material-bg-disabled-container dark:material-bg-disabled-container-on-dark
|
80
|
+
material-cursor-default" : "material-bg-secondary-container
|
81
|
+
dark:material-bg-secondary-container-on-dark hover:material-shadow"}
|
82
|
+
CLASSES
|
83
|
+
end
|
84
|
+
|
85
|
+
def tonal_button_content_classes
|
86
|
+
sanitize <<-CLASSES
|
87
|
+
material-flex material-items-center #{disabled ? "material-text-on-surface
|
88
|
+
dark:material-text-on-surface-on-dark material-opacity-disabled-content" :
|
89
|
+
"material-text-on-secondary-container dark:material-text-on-secondary-container-on-dark"}
|
90
|
+
material-text-label-large material-font-medium material-font-label
|
91
|
+
material-leading-label-large material-tracking-label-large
|
92
|
+
CLASSES
|
93
|
+
end
|
94
|
+
|
95
|
+
def tonal_button_overlay_classes
|
96
|
+
sanitize <<-CLASSES
|
97
|
+
material-absolute material-w-full material-inset-0 material-rounded-full
|
98
|
+
material-bg-on-surface dark:material-bg-on-surface-on-dark
|
99
|
+
material-opacity-0 hover:material-opacity-hover focus:material-opacity-focus
|
100
|
+
active:material-opacity-pressed
|
101
|
+
CLASSES
|
102
|
+
end
|
103
|
+
|
104
|
+
def outlined_button_container_classes
|
105
|
+
sanitize <<-CLASSES
|
106
|
+
material-relative #{icon ? "material-pl-4 material-pr-6" : "material-px-6"}
|
107
|
+
material-h-10 dark:material-outline-on-dark material-rounded-full
|
108
|
+
#{disabled ? "material-outline-disabled material-cursor-default
|
109
|
+
dark:material-outline-disabled-on-dark" : "material-bg-surface
|
110
|
+
dark:material-bg-surface-on-dark material-outline-default
|
111
|
+
hover:material-shadow"}
|
112
|
+
CLASSES
|
113
|
+
end
|
114
|
+
|
115
|
+
def outlined_button_content_classes
|
116
|
+
sanitize <<-CLASSES
|
117
|
+
material-flex material-items-center #{disabled ? "material-text-on-surface
|
118
|
+
dark:material-text-on-surface-on-dark material-opacity-disabled-content" :
|
119
|
+
"material-text-primary dark:material-text-primary-on-dark"}
|
120
|
+
material-text-label-large material-font-medium material-font-label
|
121
|
+
material-leading-label-large material-tracking-label-large
|
122
|
+
CLASSES
|
123
|
+
end
|
124
|
+
|
125
|
+
def outlined_button_overlay_classes
|
126
|
+
sanitize <<-CLASSES
|
127
|
+
material-absolute material-w-full material-inset-0 material-rounded-full
|
128
|
+
material-bg-primary dark:material-bg-primary-on-dark material-opacity-0
|
129
|
+
hover:material-opacity-hover focus:material-opacity-focus
|
130
|
+
active:material-opacity-pressed
|
131
|
+
CLASSES
|
132
|
+
end
|
133
|
+
|
134
|
+
def elevated_button_container_classes
|
135
|
+
sanitize <<-CLASSES
|
136
|
+
material-relative #{icon ? "material-pl-4 material-pr-6" : "material-px-6"}
|
137
|
+
material-h-10 material-rounded-full
|
138
|
+
#{disabled ? "material-bg-disabled-container
|
139
|
+
dark:material-bg-disabled-container-on-dark material-cursor-default" :
|
140
|
+
"material-bg-surface dark:material-bg-surface-on-dark material-shadow
|
141
|
+
hover:material-shadow-md"}
|
142
|
+
CLASSES
|
143
|
+
end
|
144
|
+
|
145
|
+
def elevated_button_content_classes
|
146
|
+
sanitize <<-CLASSES
|
147
|
+
material-flex material-items-center #{disabled ? "material-text-on-surface
|
148
|
+
dark:material-text-on-surface-on-dark material-opacity-disabled-content" :
|
149
|
+
"material-text-primary dark:material-text-primary-on-dark"}
|
150
|
+
material-text-label-large material-font-medium material-font-label
|
151
|
+
material-leading-label-large material-tracking-label-large
|
152
|
+
CLASSES
|
153
|
+
end
|
154
|
+
|
155
|
+
def elevated_button_overlay_classes
|
156
|
+
sanitize <<-CLASSES
|
157
|
+
material-absolute material-w-full material-inset-0 material-rounded-full
|
158
|
+
material-bg-primary dark:material-bg-primary-on-dark material-opacity-0
|
159
|
+
hover:material-opacity-hover focus:material-opacity-focus
|
160
|
+
active:material-opacity-pressed
|
161
|
+
CLASSES
|
162
|
+
end
|
163
|
+
|
164
|
+
def text_button_container_classes
|
165
|
+
sanitize <<-CLASSES
|
166
|
+
material-relative #{icon ? "material-pl-3 material-pr-4" : "material-px-3"}
|
167
|
+
material-h-10 material-rounded-full #{disabled ? "material-cursor-default" :
|
168
|
+
"hover:material-shadow"}
|
169
|
+
CLASSES
|
170
|
+
end
|
171
|
+
|
172
|
+
def text_button_content_classes
|
173
|
+
sanitize <<-CLASSES
|
174
|
+
material-flex material-items-center #{disabled ? "material-text-on-surface
|
175
|
+
dark:material-text-on-surface-on-dark material-opacity-disabled-content" :
|
176
|
+
"material-text-primary dark:material-text-primary-on-dark"}
|
177
|
+
material-text-label-large material-font-medium material-font-label
|
178
|
+
material-leading-label-large material-tracking-label-large
|
179
|
+
CLASSES
|
180
|
+
end
|
181
|
+
|
182
|
+
def text_button_overlay_classes
|
183
|
+
sanitize <<-CLASSES
|
184
|
+
material-absolute material-w-full material-inset-0 material-rounded-full
|
185
|
+
material-bg-primary dark:material-bg-primary-on-dark material-opacity-0
|
186
|
+
hover:material-opacity-hover focus:material-opacity-focus
|
187
|
+
active:material-opacity-pressed
|
188
|
+
CLASSES
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Material::FABComponent < ApplicationComponent
|
4
|
+
renders_one :icon, -> (name) do
|
5
|
+
content_tag :span, class: "material-icons" do
|
6
|
+
name
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(name = "", html_options = {})
|
11
|
+
@name = name
|
12
|
+
@html_options = html_options
|
13
|
+
end
|
14
|
+
|
15
|
+
def container_classes
|
16
|
+
sanitize <<-CLASSES
|
17
|
+
material-relative material-flex material-items-center
|
18
|
+
material-justify-center material-h-56px material-w-56px
|
19
|
+
material-bg-primary-container dark:material-bg-primary-container-on-dark
|
20
|
+
material-rounded-xl material-elevation-3
|
21
|
+
CLASSES
|
22
|
+
end
|
23
|
+
|
24
|
+
def content_classes
|
25
|
+
sanitize <<-CLASSES
|
26
|
+
material-flex material-items-center material-justify-center
|
27
|
+
material-text-on-primary-container
|
28
|
+
dark:material-text-on-primary-container-on-dark
|
29
|
+
CLASSES
|
30
|
+
end
|
31
|
+
|
32
|
+
def overlay_classes
|
33
|
+
sanitize <<-CLASSES
|
34
|
+
material-absolute material-inset-0 material-w-full
|
35
|
+
material-bg-on-primary-container dark:material-bg-on-primary-on-dark
|
36
|
+
material-rounded-xl material-opacity-0 hover:material-opacity-hover
|
37
|
+
focus:material-opacity-focus active:material-opacity-pressed
|
38
|
+
hover:material-elevation-4 focus:material-elevation-3 active:material-elevation-3
|
39
|
+
CLASSES
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { Application } from "@hotwired/stimulus"
|
2
|
+
|
3
|
+
const application = Application.start()
|
4
|
+
|
5
|
+
// Configure Stimulus development experience
|
6
|
+
application.warnings = true
|
7
|
+
application.debug = false
|
8
|
+
window.Stimulus = application
|
9
|
+
|
10
|
+
// Register components controllers
|
11
|
+
import registerControllersFrom from "./helpers.js"
|
12
|
+
|
13
|
+
registerControllersFrom(require("../../components/**/*_controller.js"))
|
14
|
+
|
15
|
+
export { application }
|
@@ -0,0 +1,30 @@
|
|
1
|
+
export const controllerNameFrom = (filename) => {
|
2
|
+
const pattern = /.*\/components\/((?:\w+\/)*)(\w+)_controller.js$/
|
3
|
+
|
4
|
+
const controllerName = filename
|
5
|
+
.replace(pattern, (_match, $1, $2) => {
|
6
|
+
const scope = $1
|
7
|
+
.replaceAll('/', '--')
|
8
|
+
.replaceAll('_', '-')
|
9
|
+
|
10
|
+
const name = $2
|
11
|
+
.replaceAll('_', '-')
|
12
|
+
|
13
|
+
return scope + name
|
14
|
+
})
|
15
|
+
|
16
|
+
return controllerName
|
17
|
+
}
|
18
|
+
|
19
|
+
export default registerControllersFrom = (context) => {
|
20
|
+
const { default: componentControllers, filenames } = context
|
21
|
+
|
22
|
+
for (let i = 0, len = componentControllers.length; i < len; i++) {
|
23
|
+
let componentController = componentControllers[i].default
|
24
|
+
let filename = filenames[i]
|
25
|
+
let name = controllerNameFrom(filename)
|
26
|
+
|
27
|
+
Stimulus.register(name, componentController)
|
28
|
+
console.log(name);
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
// This file is auto-generated by ./bin/rails stimulus:manifest:update
|
2
|
+
// Run that command whenever you add a new controller
|
3
|
+
|
4
|
+
import { application } from "./application"
|
5
|
+
|
6
|
+
import HelloController from "./hello_controller"
|
7
|
+
application.register("hello", HelloController)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Material view components</title>
|
5
|
+
<%= csrf_meta_tags %>
|
6
|
+
<%= csp_meta_tag %>
|
7
|
+
|
8
|
+
<%= stylesheet_link_tag "material_view_components/application", media: "all" %>
|
9
|
+
<%= javascript_include_tag "application", defer: true %>
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
|
13
|
+
<%= yield %>
|
14
|
+
|
15
|
+
=======
|
16
|
+
<body class="p-8">
|
17
|
+
<%= yield %>
|
18
|
+
</body>
|
19
|
+
</html>
|
data/config/routes.rb
ADDED