material_view_components 0.1.1

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.
Files changed (32) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +17 -0
  5. data/app/assets/builds/material_view_components/application.css +218048 -0
  6. data/app/assets/builds/material_view_components/application.js +1958 -0
  7. data/app/assets/config/material_view_components_manifest.js +1 -0
  8. data/app/assets/stylesheets/material_view_components/application.tailwind.css +182 -0
  9. data/app/components/application_component.rb +19 -0
  10. data/app/components/material/button_component.html.erb +10 -0
  11. data/app/components/material/button_component.rb +190 -0
  12. data/app/components/material/button_component_controller.js +8 -0
  13. data/app/components/material/fab_component.html.erb +8 -0
  14. data/app/components/material/fab_component.rb +41 -0
  15. data/app/controllers/material_view_components/application_controller.rb +4 -0
  16. data/app/helpers/material_view_components/application_helper.rb +4 -0
  17. data/app/javascript/application.js +2 -0
  18. data/app/javascript/controllers/application.js +15 -0
  19. data/app/javascript/controllers/hello_controller.js +7 -0
  20. data/app/javascript/controllers/helpers.js +30 -0
  21. data/app/javascript/controllers/index.js +7 -0
  22. data/app/jobs/material_view_components/application_job.rb +4 -0
  23. data/app/mailers/material_view_components/application_mailer.rb +6 -0
  24. data/app/models/material_view_components/application_record.rb +5 -0
  25. data/app/views/layouts/material_view_components/application.html.erb +19 -0
  26. data/config/initializers/assets.rb +3 -0
  27. data/config/routes.rb +2 -0
  28. data/lib/material_view_components/engine.rb +7 -0
  29. data/lib/material_view_components/version.rb +3 -0
  30. data/lib/material_view_components.rb +6 -0
  31. data/lib/tasks/material_view_components_tasks.rake +4 -0
  32. 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,8 @@
1
+ import { Controller } from "@hotwired/stimulus";
2
+
3
+ export default class extends Controller {
4
+ connect() {
5
+ console.log("Hello, Stimulus!", this.element);
6
+ }
7
+ }
8
+
@@ -0,0 +1,8 @@
1
+ <%= button_to @name, @html_options.merge(form_class: "", class: container_classes, data: { controller: identifier }) do %>
2
+ <div class="<%= content_classes %>">
3
+ <%= icon %>
4
+ </div>
5
+
6
+ <div class="<%= overlay_classes %>">
7
+ </div>
8
+ <% 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,4 @@
1
+ module MaterialViewComponents
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module MaterialViewComponents
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,2 @@
1
+ // Entry point for the build script in your package.json
2
+ import "./controllers"
@@ -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,7 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ export default class extends Controller {
4
+ connect() {
5
+ this.element.textContent = "Hello World!"
6
+ }
7
+ }
@@ -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,4 @@
1
+ module MaterialViewComponents
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module MaterialViewComponents
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: "from@example.com"
4
+ layout "mailer"
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module MaterialViewComponents
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -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>
@@ -0,0 +1,3 @@
1
+ Rails.application.configure do
2
+ config.assets.precompile << "material_view_components_manifest.js"
3
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ MaterialViewComponents::Engine.routes.draw do
2
+ end
@@ -0,0 +1,7 @@
1
+ require "view_component/engine"
2
+
3
+ module MaterialViewComponents
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace MaterialViewComponents
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module MaterialViewComponents
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,6 @@
1
+ require "material_view_components/version"
2
+ require "material_view_components/engine"
3
+
4
+ module MaterialViewComponents
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :material_view_components do
3
+ # # Task goes here
4
+ # end