view_component 2.33.0 → 2.37.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of view_component might be problematic. Click here for more details.

Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/assets/vendor/prism.css +196 -0
  4. data/app/assets/vendor/prism.min.js +12 -0
  5. data/app/controllers/view_components_controller.rb +1 -1
  6. data/app/helpers/preview_helper.rb +19 -0
  7. data/app/views/test_mailer/test_email.html.erb +1 -0
  8. data/app/views/view_components/_preview_source.html.erb +17 -0
  9. data/app/views/view_components/preview.html.erb +6 -2
  10. data/{CHANGELOG.md → docs/CHANGELOG.md} +151 -1
  11. data/lib/rails/generators/abstract_generator.rb +29 -0
  12. data/lib/rails/generators/component/component_generator.rb +5 -5
  13. data/lib/rails/generators/erb/component_generator.rb +7 -16
  14. data/lib/rails/generators/haml/component_generator.rb +6 -16
  15. data/lib/rails/generators/slim/component_generator.rb +6 -16
  16. data/lib/view_component.rb +2 -0
  17. data/lib/view_component/base.rb +144 -85
  18. data/lib/view_component/collection.rb +6 -2
  19. data/lib/view_component/compile_cache.rb +1 -0
  20. data/lib/view_component/compiler.rb +87 -53
  21. data/lib/view_component/content_areas.rb +57 -0
  22. data/lib/view_component/engine.rb +31 -3
  23. data/lib/view_component/instrumentation.rb +21 -0
  24. data/lib/view_component/preview.rb +19 -8
  25. data/lib/view_component/previewable.rb +16 -18
  26. data/lib/view_component/slot_v2.rb +34 -27
  27. data/lib/view_component/slotable.rb +2 -1
  28. data/lib/view_component/slotable_v2.rb +58 -24
  29. data/lib/view_component/test_helpers.rb +7 -1
  30. data/lib/view_component/translatable.rb +6 -5
  31. data/lib/view_component/version.rb +1 -1
  32. data/lib/view_component/with_content_helper.rb +5 -2
  33. data/lib/yard/mattr_accessor_handler.rb +19 -0
  34. metadata +76 -39
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e1d8f453f26f7d62a3549dcfb34a85a6fadfc05a7b38515ebe53bba7500acc9
4
- data.tar.gz: 39122c530de9fb557f7e66a0a3e6b94c20c492776edc45b193e2b3b60b834e39
3
+ metadata.gz: 5f97acb8cd2ac4c3c706207aa030cfb62af6d9066b9d05ed32b0946851132367
4
+ data.tar.gz: aeceea89a252646b358b5a67883fc926bffd56d321e0e3237fbc1471970c6745
5
5
  SHA512:
6
- metadata.gz: 6f016eb4da5b952a220971e0163853b8ca77dd5bc820b634d525316b4117654b78a279ffeb7bb8d66ce68401cc41a350861696152992923445a1c3d6c587b2ed
7
- data.tar.gz: 4203337d6188eea75e7d79ca246ca5309e5af7197256207e48c37b248958dbad49c07efff0a964d206d9c462ee5d1af3365f36f9f2d9e68661f7dbfe066e4a01
6
+ metadata.gz: 8bc5f98ac1fc8ca620d2add5b59d5c0505489229cd0d8a7dcc9858774399c4e82e3dae419b5016b23a1228bec1e9e2e5a3e9d6980376439e5fb0cf02153ac8f9
7
+ data.tar.gz: 4d7b0037a063825a777a94ca03e32e89abcadc04bb0c5ec2265f5eb8a1b62f7abb1e807ace75726365ab8baebdd774dd5fc757da2b0cd6ce51a5670b03309ff2
data/README.md CHANGED
@@ -8,7 +8,7 @@ See [viewcomponent.org](https://viewcomponent.org/) for documentation.
8
8
 
9
9
  ## Contributing
10
10
 
11
- This project is intended to be a safe, welcoming space for collaboration. Contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. We recommend reading the [contributing guide](./CONTRIBUTING.md) as well.
11
+ This project is intended to be a safe, welcoming space for collaboration. Contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. We recommend reading the [contributing guide](./docs/CONTRIBUTING.md) as well.
12
12
 
13
13
  ## License
14
14
 
@@ -0,0 +1,196 @@
1
+ /* PrismJS 1.23.0
2
+ https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+clike+erb+haml+markup-templating+ruby&plugins=line-highlight+highlight-keywords+normalize-whitespace */
3
+ /**
4
+ * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML
5
+ * Based on https://github.com/chriskempson/tomorrow-theme
6
+ * @author Rose Pritchard
7
+ */
8
+
9
+ code[class*="language-"],
10
+ pre[class*="language-"] {
11
+ color: #ccc;
12
+ background: none;
13
+ font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
14
+ font-size: 1em;
15
+ text-align: left;
16
+ white-space: pre;
17
+ word-spacing: normal;
18
+ word-break: normal;
19
+ word-wrap: normal;
20
+ line-height: 1.5;
21
+
22
+ -moz-tab-size: 4;
23
+ -o-tab-size: 4;
24
+ tab-size: 4;
25
+
26
+ -webkit-hyphens: none;
27
+ -moz-hyphens: none;
28
+ -ms-hyphens: none;
29
+ hyphens: none;
30
+
31
+ }
32
+
33
+ /* Code blocks */
34
+ pre[class*="language-"] {
35
+ padding: 1em;
36
+ margin: .5em 0;
37
+ overflow: auto;
38
+ }
39
+
40
+ :not(pre) > code[class*="language-"],
41
+ pre[class*="language-"] {
42
+ background: #2d2d2d;
43
+ }
44
+
45
+ /* Inline code */
46
+ :not(pre) > code[class*="language-"] {
47
+ padding: .1em;
48
+ border-radius: .3em;
49
+ white-space: normal;
50
+ }
51
+
52
+ .token.comment,
53
+ .token.block-comment,
54
+ .token.prolog,
55
+ .token.doctype,
56
+ .token.cdata {
57
+ color: #999;
58
+ }
59
+
60
+ .token.punctuation {
61
+ color: #ccc;
62
+ }
63
+
64
+ .token.tag,
65
+ .token.attr-name,
66
+ .token.namespace,
67
+ .token.deleted {
68
+ color: #e2777a;
69
+ }
70
+
71
+ .token.function-name {
72
+ color: #6196cc;
73
+ }
74
+
75
+ .token.boolean,
76
+ .token.number,
77
+ .token.function {
78
+ color: #f08d49;
79
+ }
80
+
81
+ .token.property,
82
+ .token.class-name,
83
+ .token.constant,
84
+ .token.symbol {
85
+ color: #f8c555;
86
+ }
87
+
88
+ .token.selector,
89
+ .token.important,
90
+ .token.atrule,
91
+ .token.keyword,
92
+ .token.builtin {
93
+ color: #cc99cd;
94
+ }
95
+
96
+ .token.string,
97
+ .token.char,
98
+ .token.attr-value,
99
+ .token.regex,
100
+ .token.variable {
101
+ color: #7ec699;
102
+ }
103
+
104
+ .token.operator,
105
+ .token.entity,
106
+ .token.url {
107
+ color: #67cdcc;
108
+ }
109
+
110
+ .token.important,
111
+ .token.bold {
112
+ font-weight: bold;
113
+ }
114
+ .token.italic {
115
+ font-style: italic;
116
+ }
117
+
118
+ .token.entity {
119
+ cursor: help;
120
+ }
121
+
122
+ .token.inserted {
123
+ color: green;
124
+ }
125
+
126
+ pre[data-line] {
127
+ position: relative;
128
+ padding: 1em 0 1em 3em;
129
+ }
130
+
131
+ .line-highlight {
132
+ position: absolute;
133
+ left: 0;
134
+ right: 0;
135
+ padding: inherit 0;
136
+ margin-top: 1em; /* Same as .prism’s padding-top */
137
+
138
+ background: hsla(24, 20%, 50%,.08);
139
+ background: linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
140
+
141
+ pointer-events: none;
142
+
143
+ line-height: inherit;
144
+ white-space: pre;
145
+ }
146
+
147
+ @media print {
148
+ .line-highlight {
149
+ /*
150
+ * This will prevent browsers from replacing the background color with white.
151
+ * It's necessary because the element is layered on top of the displayed code.
152
+ */
153
+ -webkit-print-color-adjust: exact;
154
+ color-adjust: exact;
155
+ }
156
+ }
157
+
158
+ .line-highlight:before,
159
+ .line-highlight[data-end]:after {
160
+ content: attr(data-start);
161
+ position: absolute;
162
+ top: .4em;
163
+ left: .6em;
164
+ min-width: 1em;
165
+ padding: 0 .5em;
166
+ background-color: hsla(24, 20%, 50%,.4);
167
+ color: hsl(24, 20%, 95%);
168
+ font: bold 65%/1.5 sans-serif;
169
+ text-align: center;
170
+ vertical-align: .3em;
171
+ border-radius: 999px;
172
+ text-shadow: none;
173
+ box-shadow: 0 1px white;
174
+ }
175
+
176
+ .line-highlight[data-end]:after {
177
+ content: attr(data-end);
178
+ top: auto;
179
+ bottom: .4em;
180
+ }
181
+
182
+ .line-numbers .line-highlight:before,
183
+ .line-numbers .line-highlight:after {
184
+ content: none;
185
+ }
186
+
187
+ pre[id].linkable-line-numbers span.line-numbers-rows {
188
+ pointer-events: all;
189
+ }
190
+ pre[id].linkable-line-numbers span.line-numbers-rows > span:before {
191
+ cursor: pointer;
192
+ }
193
+ pre[id].linkable-line-numbers span.line-numbers-rows > span:hover:before {
194
+ background-color: rgba(128, 128, 128, .2);
195
+ }
196
+
@@ -0,0 +1,12 @@
1
+ /* PrismJS 1.23.0
2
+ https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+clike+erb+haml+markup-templating+ruby&plugins=line-highlight+highlight-keywords+normalize-whitespace */
3
+ var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,n=0,e={},M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++n}),e.__id},clone:function t(e,r){var a,n;switch(r=r||{},M.util.type(e)){case"Object":if(n=M.util.objId(e),r[n])return r[n];for(var i in a={},r[n]=a,e)e.hasOwnProperty(i)&&(a[i]=t(e[i],r));return a;case"Array":return n=M.util.objId(e),r[n]?r[n]:(a=[],r[n]=a,e.forEach(function(e,n){a[n]=t(e,r)}),a);default:return e}},getLanguage:function(e){for(;e&&!c.test(e.className);)e=e.parentElement;return e?(e.className.match(c)||[,"none"])[1].toLowerCase():"none"},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(e){var n=(/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(e.stack)||[])[1];if(n){var t=document.getElementsByTagName("script");for(var r in t)if(t[r].src==n)return t[r]}return null}},isActive:function(e,n,t){for(var r="no-"+n;e;){var a=e.classList;if(a.contains(n))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!t}},languages:{plain:e,plaintext:e,text:e,txt:e,extend:function(e,n){var t=M.util.clone(M.languages[e]);for(var r in n)t[r]=n[r];return t},insertBefore:function(t,e,n,r){var a=(r=r||M.languages)[t],i={};for(var l in a)if(a.hasOwnProperty(l)){if(l==e)for(var o in n)n.hasOwnProperty(o)&&(i[o]=n[o]);n.hasOwnProperty(l)||(i[l]=a[l])}var s=r[t];return r[t]=i,M.languages.DFS(M.languages,function(e,n){n===s&&e!=t&&(this[e]=i)}),i},DFS:function e(n,t,r,a){a=a||{};var i=M.util.objId;for(var l in n)if(n.hasOwnProperty(l)){t.call(n,l,n[l],r||l);var o=n[l],s=M.util.type(o);"Object"!==s||a[i(o)]?"Array"!==s||a[i(o)]||(a[i(o)]=!0,e(o,t,l,a)):(a[i(o)]=!0,e(o,t,null,a))}}},plugins:{},highlightAll:function(e,n){M.highlightAllUnder(document,e,n)},highlightAllUnder:function(e,n,t){var r={callback:t,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};M.hooks.run("before-highlightall",r),r.elements=Array.prototype.slice.apply(r.container.querySelectorAll(r.selector)),M.hooks.run("before-all-elements-highlight",r);for(var a,i=0;a=r.elements[i++];)M.highlightElement(a,!0===n,r.callback)},highlightElement:function(e,n,t){var r=M.util.getLanguage(e),a=M.languages[r];e.className=e.className.replace(c,"").replace(/\s+/g," ")+" language-"+r;var i=e.parentElement;i&&"pre"===i.nodeName.toLowerCase()&&(i.className=i.className.replace(c,"").replace(/\s+/g," ")+" language-"+r);var l={element:e,language:r,grammar:a,code:e.textContent};function o(e){l.highlightedCode=e,M.hooks.run("before-insert",l),l.element.innerHTML=l.highlightedCode,M.hooks.run("after-highlight",l),M.hooks.run("complete",l),t&&t.call(l.element)}if(M.hooks.run("before-sanity-check",l),(i=l.element.parentElement)&&"pre"===i.nodeName.toLowerCase()&&!i.hasAttribute("tabindex")&&i.setAttribute("tabindex","0"),!l.code)return M.hooks.run("complete",l),void(t&&t.call(l.element));if(M.hooks.run("before-highlight",l),l.grammar)if(n&&u.Worker){var s=new Worker(M.filename);s.onmessage=function(e){o(e.data)},s.postMessage(JSON.stringify({language:l.language,code:l.code,immediateClose:!0}))}else o(M.highlight(l.code,l.grammar,l.language));else o(M.util.encode(l.code))},highlight:function(e,n,t){var r={code:e,grammar:n,language:t};return M.hooks.run("before-tokenize",r),r.tokens=M.tokenize(r.code,r.grammar),M.hooks.run("after-tokenize",r),W.stringify(M.util.encode(r.tokens),r.language)},tokenize:function(e,n){var t=n.rest;if(t){for(var r in t)n[r]=t[r];delete n.rest}var a=new i;return I(a,a.head,e),function e(n,t,r,a,i,l){for(var o in r)if(r.hasOwnProperty(o)&&r[o]){var s=r[o];s=Array.isArray(s)?s:[s];for(var u=0;u<s.length;++u){if(l&&l.cause==o+","+u)return;var c=s[u],g=c.inside,f=!!c.lookbehind,h=!!c.greedy,d=c.alias;if(h&&!c.pattern.global){var p=c.pattern.toString().match(/[imsuy]*$/)[0];c.pattern=RegExp(c.pattern.source,p+"g")}for(var v=c.pattern||c,m=a.next,y=i;m!==t.tail&&!(l&&y>=l.reach);y+=m.value.length,m=m.next){var b=m.value;if(t.length>n.length)return;if(!(b instanceof W)){var k,x=1;if(h){if(!(k=z(v,y,n,f)))break;var w=k.index,A=k.index+k[0].length,P=y;for(P+=m.value.length;P<=w;)m=m.next,P+=m.value.length;if(P-=m.value.length,y=P,m.value instanceof W)continue;for(var E=m;E!==t.tail&&(P<A||"string"==typeof E.value);E=E.next)x++,P+=E.value.length;x--,b=n.slice(y,P),k.index-=y}else if(!(k=z(v,0,b,f)))continue;var w=k.index,S=k[0],O=b.slice(0,w),L=b.slice(w+S.length),N=y+b.length;l&&N>l.reach&&(l.reach=N);var j=m.prev;O&&(j=I(t,j,O),y+=O.length),q(t,j,x);var C=new W(o,g?M.tokenize(S,g):S,d,S);if(m=I(t,j,C),L&&I(t,m,L),1<x){var _={cause:o+","+u,reach:N};e(n,t,r,m.prev,y,_),l&&_.reach>l.reach&&(l.reach=_.reach)}}}}}}(e,a,n,a.head,0),function(e){var n=[],t=e.head.next;for(;t!==e.tail;)n.push(t.value),t=t.next;return n}(a)},hooks:{all:{},add:function(e,n){var t=M.hooks.all;t[e]=t[e]||[],t[e].push(n)},run:function(e,n){var t=M.hooks.all[e];if(t&&t.length)for(var r,a=0;r=t[a++];)r(n)}},Token:W};function W(e,n,t,r){this.type=e,this.content=n,this.alias=t,this.length=0|(r||"").length}function z(e,n,t,r){e.lastIndex=n;var a=e.exec(t);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function i(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function I(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function q(e,n,t){for(var r=n.next,a=0;a<t&&r!==e.tail;a++)r=r.next;(n.next=r).prev=n,e.length-=a}if(u.Prism=M,W.stringify=function n(e,t){if("string"==typeof e)return e;if(Array.isArray(e)){var r="";return e.forEach(function(e){r+=n(e,t)}),r}var a={type:e.type,content:n(e.content,t),tag:"span",classes:["token",e.type],attributes:{},language:t},i=e.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(a.classes,i):a.classes.push(i)),M.hooks.run("wrap",a);var l="";for(var o in a.attributes)l+=" "+o+'="'+(a.attributes[o]||"").replace(/"/g,"&quot;")+'"';return"<"+a.tag+' class="'+a.classes.join(" ")+'"'+l+">"+a.content+"</"+a.tag+">"},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),t=n.language,r=n.code,a=n.immediateClose;u.postMessage(M.highlight(r,M.languages[t],t)),a&&u.close()},!1)),M;var t=M.util.currentScript();function r(){M.manual||M.highlightAll()}if(t&&(M.filename=t.src,t.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var a=document.readyState;"loading"===a||"interactive"===a&&t&&t.defer?document.addEventListener("DOMContentLoaded",r):window.requestAnimationFrame?window.requestAnimationFrame(r):window.setTimeout(r,16)}return M}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
4
+ Prism.languages.markup={comment:/<!--[\s\S]*?-->/,prolog:/<\?[\s\S]+?\?>/,doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/,name:/[^\s<>'"]+/}},cdata:/<!\[CDATA\[[\s\S]*?]]>/i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&amp;/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^<!\[CDATA\[|\]\]>$/i;var t={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:s}};t["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var n={};n[a]={pattern:RegExp("(<__[^>]*>)(?:<!\\[CDATA\\[(?:[^\\]]|\\](?!\\]>))*\\]\\]>|(?!<!\\[CDATA\\[)[^])*?(?=</__>)".replace(/__/g,function(){return a}),"i"),lookbehind:!0,greedy:!0,inside:t},Prism.languages.insertBefore("markup","cdata",n)}}),Object.defineProperty(Prism.languages.markup.tag,"addAttribute",{value:function(a,e){Prism.languages.markup.tag.inside["special-attr"].push({pattern:RegExp("(^|[\"'\\s])(?:"+a+")\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s'\">=]+(?=[\\s>]))","i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[e,"language-"+e],inside:Prism.languages[e]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml;
5
+ Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/};
6
+ !function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#.*/,{pattern:/^=begin\s[\s\S]*?^=end/m,greedy:!0}],"class-name":{pattern:/(\b(?:class)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.languages.ruby}};delete e.languages.ruby.function,e.languages.insertBefore("ruby","keyword",{regex:[{pattern:RegExp("%r(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^])*\\)","\\{(?:[^#{}\\\\]|#(?:\\{[^}]+\\})?|\\\\[^])*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\]","<(?:[^<>\\\\]|\\\\[^])*>"].join("|")+")[egimnosux]{0,6}"),greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[egimnosux]{0,6}(?=\s*(?:$|[\r\n,.;})#]))/,lookbehind:!0,greedy:!0,inside:{interpolation:n}}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:{pattern:/(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,lookbehind:!0},"method-definition":{pattern:/(\bdef\s+)[\w.]+/,lookbehind:!0,inside:{function:/\w+$/,rest:e.languages.ruby}}}),e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z]\w*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:RegExp("%[qQiIwWxs]?(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^])*\\)","\\{(?:[^#{}\\\\]|#(?:\\{[^}]+\\})?|\\\\[^])*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\]","<(?:[^<>\\\\]|\\\\[^])*>"].join("|")+")"),greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|#(?!\{)|\\(?:\r\n|[\s\S])|(?!\1)[^\\#\r\n])*\1/,greedy:!0,inside:{interpolation:n}}],e.languages.rb=e.languages.ruby}(Prism);
7
+ !function(h){function v(e,n){return"___"+e.toUpperCase()+n+"___"}Object.defineProperties(h.languages["markup-templating"]={},{buildPlaceholders:{value:function(a,r,e,o){if(a.language===r){var c=a.tokenStack=[];a.code=a.code.replace(e,function(e){if("function"==typeof o&&!o(e))return e;for(var n,t=c.length;-1!==a.code.indexOf(n=v(r,t));)++t;return c[t]=e,n}),a.grammar=h.languages.markup}}},tokenizePlaceholders:{value:function(p,k){if(p.language===k&&p.tokenStack){p.grammar=h.languages[k];var m=0,d=Object.keys(p.tokenStack);!function e(n){for(var t=0;t<n.length&&!(m>=d.length);t++){var a=n[t];if("string"==typeof a||a.content&&"string"==typeof a.content){var r=d[m],o=p.tokenStack[r],c="string"==typeof a?a:a.content,i=v(k,r),u=c.indexOf(i);if(-1<u){++m;var g=c.substring(0,u),l=new h.Token(k,h.tokenize(o,p.grammar),"language-"+k,o),s=c.substring(u+i.length),f=[];g&&f.push.apply(f,e([g])),f.push(l),s&&f.push.apply(f,e([s])),"string"==typeof a?n.splice.apply(n,[t,1].concat(f)):a.content=f}}else a.content&&e(a.content)}return n}(p.tokens)}}}})}(Prism);
8
+ !function(n){n.languages.erb=n.languages.extend("ruby",{}),n.languages.insertBefore("erb","comment",{delimiter:{pattern:/^<%=?|%>$/,alias:"punctuation"}}),n.hooks.add("before-tokenize",function(e){n.languages["markup-templating"].buildPlaceholders(e,"erb",/<%=?(?:[^\r\n]|[\r\n](?!=begin)|[\r\n]=begin\s[\s\S]*?^=end)+?%>/gm)}),n.hooks.add("after-tokenize",function(e){n.languages["markup-templating"].tokenizePlaceholders(e,"erb")})}(Prism);
9
+ !function(e){e.languages.haml={"multiline-comment":{pattern:/((?:^|\r?\n|\r)([\t ]*))(?:\/|-#).*(?:(?:\r?\n|\r)\2[\t ].+)*/,lookbehind:!0,alias:"comment"},"multiline-code":[{pattern:/((?:^|\r?\n|\r)([\t ]*)(?:[~-]|[&!]?=)).*,[\t ]*(?:(?:\r?\n|\r)\2[\t ].*,[\t ]*)*(?:(?:\r?\n|\r)\2[\t ].+)/,lookbehind:!0,inside:e.languages.ruby},{pattern:/((?:^|\r?\n|\r)([\t ]*)(?:[~-]|[&!]?=)).*\|[\t ]*(?:(?:\r?\n|\r)\2[\t ].*\|[\t ]*)*/,lookbehind:!0,inside:e.languages.ruby}],filter:{pattern:/((?:^|\r?\n|\r)([\t ]*)):[\w-]+(?:(?:\r?\n|\r)(?:\2[\t ].+|\s*?(?=\r?\n|\r)))+/,lookbehind:!0,inside:{"filter-name":{pattern:/^:[\w-]+/,alias:"variable"}}},markup:{pattern:/((?:^|\r?\n|\r)[\t ]*)<.+/,lookbehind:!0,inside:e.languages.markup},doctype:{pattern:/((?:^|\r?\n|\r)[\t ]*)!!!(?: .+)?/,lookbehind:!0},tag:{pattern:/((?:^|\r?\n|\r)[\t ]*)[%.#][\w\-#.]*[\w\-](?:\([^)]+\)|\{(?:\{[^}]+\}|[^{}])+\}|\[[^\]]+\])*[\/<>]*/,lookbehind:!0,inside:{attributes:[{pattern:/(^|[^#])\{(?:\{[^}]+\}|[^{}])+\}/,lookbehind:!0,inside:e.languages.ruby},{pattern:/\([^)]+\)/,inside:{"attr-value":{pattern:/(=\s*)(?:"(?:\\.|[^\\"\r\n])*"|[^)\s]+)/,lookbehind:!0},"attr-name":/[\w:-]+(?=\s*!?=|\s*[,)])/,punctuation:/[=(),]/}},{pattern:/\[[^\]]+\]/,inside:e.languages.ruby}],punctuation:/[<>]/}},code:{pattern:/((?:^|\r?\n|\r)[\t ]*(?:[~-]|[&!]?=)).+/,lookbehind:!0,inside:e.languages.ruby},interpolation:{pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"punctuation"},rest:e.languages.ruby}},punctuation:{pattern:/((?:^|\r?\n|\r)[\t ]*)[~=\-&!]+/,lookbehind:!0}};for(var t=["css",{filter:"coffee",language:"coffeescript"},"erb","javascript","less","markdown","ruby","scss","textile"],n={},r=0,a=t.length;r<a;r++){var i=t[r];i="string"==typeof i?{filter:i,language:i}:i,e.languages[i.language]&&(n["filter-"+i.filter]={pattern:RegExp("((?:^|\\r?\\n|\\r)([\\t ]*)):{{filter_name}}(?:(?:\\r?\\n|\\r)(?:\\2[\\t ].+|\\s*?(?=\\r?\\n|\\r)))+".replace("{{filter_name}}",function(){return i.filter})),lookbehind:!0,inside:{"filter-name":{pattern:/^:[\w-]+/,alias:"variable"},rest:e.languages[i.language]}})}e.languages.insertBefore("haml","filter",n)}(Prism);
10
+ !function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document&&document.querySelector){var t,o="line-numbers",s="linkable-line-numbers",a=function(){if(void 0===t){var e=document.createElement("div");e.style.fontSize="13px",e.style.lineHeight="1.5",e.style.padding="0",e.style.border="0",e.innerHTML="&nbsp;<br />&nbsp;",document.body.appendChild(e),t=38===e.offsetHeight,document.body.removeChild(e)}return t},l=!0,u=0;Prism.hooks.add("before-sanity-check",function(e){var t=e.element.parentElement;if(c(t)){var n=0;v(".line-highlight",t).forEach(function(e){n+=e.textContent.length,e.parentNode.removeChild(e)}),n&&/^( \n)+$/.test(e.code.slice(-n))&&(e.code=e.code.slice(0,-n))}}),Prism.hooks.add("complete",function e(t){var n=t.element.parentElement;if(c(n)){clearTimeout(u);var i=Prism.plugins.lineNumbers,r=t.plugins&&t.plugins.lineNumbers;if(b(n,o)&&i&&!r)Prism.hooks.add("line-numbers",e);else d(n)(),u=setTimeout(f,1)}}),window.addEventListener("hashchange",f),window.addEventListener("resize",function(){v("pre").filter(c).map(function(e){return d(e)}).forEach(y)})}function v(e,t){return Array.prototype.slice.call((t||document).querySelectorAll(e))}function b(e,t){return e.classList.contains(t)}function y(e){e()}function c(e){return!(!e||!/pre/i.test(e.nodeName))&&(!!e.hasAttribute("data-line")||!(!e.id||!Prism.util.isActive(e,s)))}function d(u,e,c){var t=(e="string"==typeof e?e:u.getAttribute("data-line")||"").replace(/\s+/g,"").split(",").filter(Boolean),d=+u.getAttribute("data-line-offset")||0,f=(a()?parseInt:parseFloat)(getComputedStyle(u).lineHeight),p=Prism.util.isActive(u,o),n=u.querySelector("code"),h=p?u:n||u,m=[],g=n&&h!=n?function(e,t){var n=getComputedStyle(e),i=getComputedStyle(t);function r(e){return+e.substr(0,e.length-2)}return t.offsetTop+r(i.borderTopWidth)+r(i.paddingTop)-r(n.paddingTop)}(u,n):0;t.forEach(function(e){var t=e.split("-"),n=+t[0],i=+t[1]||n,r=u.querySelector('.line-highlight[data-range="'+e+'"]')||document.createElement("div");if(m.push(function(){r.setAttribute("aria-hidden","true"),r.setAttribute("data-range",e),r.className=(c||"")+" line-highlight"}),p&&Prism.plugins.lineNumbers){var o=Prism.plugins.lineNumbers.getLine(u,n),s=Prism.plugins.lineNumbers.getLine(u,i);if(o){var a=o.offsetTop+g+"px";m.push(function(){r.style.top=a})}if(s){var l=s.offsetTop-o.offsetTop+s.offsetHeight+"px";m.push(function(){r.style.height=l})}}else m.push(function(){r.setAttribute("data-start",String(n)),n<i&&r.setAttribute("data-end",String(i)),r.style.top=(n-d-1)*f+g+"px",r.textContent=new Array(i-n+2).join(" \n")});m.push(function(){h.appendChild(r)})});var i=u.id;if(p&&Prism.util.isActive(u,s)&&i){b(u,s)||m.push(function(){u.classList.add(s)});var r=parseInt(u.getAttribute("data-start")||"1");v(".line-numbers-rows > span",u).forEach(function(e,t){var n=t+r;e.onclick=function(){var e=i+"."+n;l=!1,location.hash=e,setTimeout(function(){l=!0},1)}})}return function(){m.forEach(y)}}function f(){var e=location.hash.slice(1);v(".temporary.line-highlight").forEach(function(e){e.parentNode.removeChild(e)});var t=(e.match(/\.([\d,-]+)$/)||[,""])[1];if(t&&!document.getElementById(e)){var n=e.slice(0,e.lastIndexOf(".")),i=document.getElementById(n);if(i)i.hasAttribute("data-line")||i.setAttribute("data-line",""),d(i,t,"temporary ")(),l&&document.querySelector(".temporary.line-highlight").scrollIntoView()}}}();
11
+ "undefined"!=typeof Prism&&Prism.hooks.add("wrap",function(e){"keyword"===e.type&&e.classes.push("keyword-"+e.content)});
12
+ !function(){if("undefined"!=typeof Prism&&"undefined"!=typeof document){var i=Object.assign||function(e,n){for(var t in n)n.hasOwnProperty(t)&&(e[t]=n[t]);return e};e.prototype={setDefaults:function(e){this.defaults=i(this.defaults,e)},normalize:function(e,n){for(var t in n=i(this.defaults,n)){var r=t.replace(/-(\w)/g,function(e,n){return n.toUpperCase()});"normalize"!==t&&"setDefaults"!==r&&n[t]&&this[r]&&(e=this[r].call(this,e,n[t]))}return e},leftTrim:function(e){return e.replace(/^\s+/,"")},rightTrim:function(e){return e.replace(/\s+$/,"")},tabsToSpaces:function(e,n){return n=0|n||4,e.replace(/\t/g,new Array(++n).join(" "))},spacesToTabs:function(e,n){return n=0|n||4,e.replace(RegExp(" {"+n+"}","g"),"\t")},removeTrailing:function(e){return e.replace(/\s*?$/gm,"")},removeInitialLineFeed:function(e){return e.replace(/^(?:\r?\n|\r)/,"")},removeIndent:function(e){var n=e.match(/^[^\S\n\r]*(?=\S)/gm);return n&&n[0].length?(n.sort(function(e,n){return e.length-n.length}),n[0].length?e.replace(RegExp("^"+n[0],"gm"),""):e):e},indent:function(e,n){return e.replace(/^[^\S\n\r]*(?=\S)/gm,new Array(++n).join("\t")+"$&")},breakLines:function(e,n){n=!0===n?80:0|n||80;for(var t=e.split("\n"),r=0;r<t.length;++r)if(!(s(t[r])<=n)){for(var i=t[r].split(/(\s+)/g),o=0,a=0;a<i.length;++a){var l=s(i[a]);n<(o+=l)&&(i[a]="\n"+i[a],o=l)}t[r]=i.join("")}return t.join("\n")}},"undefined"!=typeof module&&module.exports&&(module.exports=e),"undefined"!=typeof Prism&&(Prism.plugins.NormalizeWhitespace=new e({"remove-trailing":!0,"remove-indent":!0,"left-trim":!0,"right-trim":!0}),Prism.hooks.add("before-sanity-check",function(e){var n=Prism.plugins.NormalizeWhitespace;if((!e.settings||!1!==e.settings["whitespace-normalization"])&&Prism.util.isActive(e.element,"whitespace-normalization",!0))if(e.element&&e.element.parentNode||!e.code){var t=e.element.parentNode;if(e.code&&t&&"pre"===t.nodeName.toLowerCase()){for(var r=t.childNodes,i="",o="",a=!1,l=0;l<r.length;++l){var s=r[l];s==e.element?a=!0:"#text"===s.nodeName&&(a?o+=s.nodeValue:i+=s.nodeValue,t.removeChild(s),--l)}if(e.element.children.length&&Prism.plugins.KeepMarkup){var c=i+e.element.innerHTML+o;e.element.innerHTML=n.normalize(c,e.settings),e.code=e.element.textContent}else e.code=i+e.code+o,e.code=n.normalize(e.code,e.settings)}}else e.code=n.normalize(e.code,e.settings)}))}function e(e){this.defaults=i({},e)}function s(e){for(var n=0,t=0;t<e.length;++t)e.charCodeAt(t)=="\t".charCodeAt(0)&&(n+=3);return e.length+n}}();
@@ -56,7 +56,7 @@ class ViewComponentsController < Rails::ApplicationController # :nodoc:
56
56
  if preview
57
57
  @preview = ViewComponent::Preview.find(preview)
58
58
  else
59
- raise AbstractController::ActionNotFound, "Component preview '#{params[:path]}' not found"
59
+ raise AbstractController::ActionNotFound, "Component preview '#{params[:path]}' not found."
60
60
  end
61
61
  end
62
62
 
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PreviewHelper
4
+ AVAILABLE_PRISM_LANGUAGES = ["ruby", "erb", "haml"]
5
+ FALLBACK_LANGUAGE = "ruby"
6
+
7
+ def prism_language_name(template:)
8
+ language = template.identifier.split(".").last
9
+ return FALLBACK_LANGUAGE unless AVAILABLE_PRISM_LANGUAGES.include? language
10
+
11
+ language
12
+ end
13
+
14
+ def preview_source
15
+ return if @render_args.nil?
16
+
17
+ render "preview_source" # rubocop:disable GitHub/RailsViewRenderPathsExist
18
+ end
19
+ end
@@ -0,0 +1 @@
1
+ <%= render MailerComponent.new %>
@@ -0,0 +1,17 @@
1
+ <link href="<%= asset_path('prism.css', skip_pipeline: true) %>" media="screen" rel="stylesheet" type="text/css">
2
+ <div class="view-component-source-example">
3
+ <h2>Source:</h2>
4
+ <pre class="source">
5
+ <% if @render_args[:component] %>
6
+ <code class="language-ruby">
7
+ <%= h @preview.preview_source(@example_name) %>
8
+ </code>
9
+ <% else %>
10
+ <% template = @view_renderer.lookup_context.find_template(@render_args[:template]) %>
11
+ <code class="language-<%= prism_language_name(template: template) %>">
12
+ <%= h template.source %>
13
+ </code>
14
+ <% end %>
15
+ </pre>
16
+ </div>
17
+ <script type="text/javascript" src="<%= asset_path('prism.min.js', skip_pipeline: true) %>"></script>
@@ -1,5 +1,9 @@
1
1
  <% if ViewComponent::Base.render_monkey_patch_enabled || Rails.version.to_f >= 6.1 %>
2
- <%= render(@render_args[:component], @render_args[:args], &@render_args[:block])%>
2
+ <%= render(@render_args[:component], @render_args[:args], &@render_args[:block]) %>
3
3
  <% else %>
4
- <%= render_component(@render_args[:component], &@render_args[:block])%>
4
+ <%= render_component(@render_args[:component], &@render_args[:block]) %>
5
+ <% end %>
6
+
7
+ <% if ViewComponent::Base.show_previews_source %>
8
+ <%= preview_source %>
5
9
  <% end %>
@@ -1,7 +1,157 @@
1
- # CHANGELOG
1
+ ---
2
+ layout: default
3
+ title: Changelog
4
+ ---
5
+
6
+ # Changelog
2
7
 
3
8
  ## main
4
9
 
10
+ ## 2.37.0
11
+
12
+ * Clarify slots example in docs to reduce naming confusion.
13
+
14
+ *Joel Hawksley*, *Blake Williams*
15
+
16
+ * Fix error in documentation for `render_many` passthrough slots.
17
+
18
+ *Ollie Nye*
19
+
20
+ * Add test case for conflict with internal `@variant` variable.
21
+
22
+ *David Backeus*
23
+
24
+ * Document decision to not change naming convention recommendation to remove `-Component` suffix.
25
+
26
+ *Joel Hawksley*
27
+
28
+ * Fix typo in documentation.
29
+
30
+ *Ryo.gift*
31
+
32
+ * Add inline template example to benchmark script.
33
+
34
+ *Andrew Tait*
35
+
36
+ * Fix benchmark scripts.
37
+
38
+ *Andrew Tait*
39
+
40
+ * Run benchmarks in CI.
41
+
42
+ *Joel Hawksley*
43
+
44
+ ## 2.36.0
45
+
46
+ * Add `slot_type` helper method.
47
+
48
+ *Jon Palmer*
49
+
50
+ * Add test case for rendering a ViewComponent with slots in a controller.
51
+
52
+ *Simon Fish*
53
+
54
+ * Add example ViewComponent to documentation landing page.
55
+
56
+ *Joel Hawksley*
57
+
58
+ * Set maximum line length to 120.
59
+
60
+ *Joel Hawksley*
61
+
62
+ * Setting a collection slot with the plural setter (`component.items(array)` for `renders_many :items`) returns the array of slots.
63
+
64
+ *Jon Palmer*
65
+
66
+ * Update error messages to be more descriptive and helpful.
67
+
68
+ *Joel Hawksley*
69
+
70
+ * Raise an error if the slot name for renders_many is :contents
71
+
72
+ *Simon Fish*
73
+
74
+ ## 2.35.0
75
+
76
+ * Only load assets for Preview source highlighting if previews are enabled.
77
+
78
+ *Joel Hawksley*
79
+
80
+ * Fix references to moved documentation files.
81
+
82
+ *Richard Macklin*
83
+
84
+ * Ensure consistent indentation with Rubocop.
85
+
86
+ *Joel Hawksley
87
+
88
+ * Bump `activesupport` upper bound from `< 7.0` to `< 8.0`.
89
+
90
+ *Richard Macklin*
91
+
92
+ * Add ERB Lint for a few basic rules.
93
+
94
+ *Joel Hawksley*
95
+
96
+ * Sort `gemspec` dependencies alphabetically.
97
+
98
+ *Joel Hawksley*
99
+
100
+ * Lock `method_source` at `1.0` to avoid open-ended dependency.
101
+
102
+ *Joel Hawksley*
103
+
104
+ * Require all PRs to include changelog entries.
105
+
106
+ *Joel Hawksley*
107
+
108
+ * Rename test app and move files under /test/sandbox.
109
+
110
+ *Matt-Yorkley*
111
+
112
+ * Make view_component_path config option available on ViewComponent::Base.
113
+
114
+ *Matt-Yorkley*
115
+
116
+ * Add @boardfish to Triage.
117
+
118
+ *Joel Hawksley*
119
+
120
+ * Adds support to change default components path (app/components) with `config.view_component.view_component_path`.
121
+
122
+ *lfalcao*
123
+
124
+ * Rename private instance variables (such as @variant) to reduce potential conflicts with subclasses.
125
+
126
+ *Joel Hawksley*
127
+
128
+ * Add documentation for configuration options.
129
+
130
+ *Joel Hawksley*
131
+
132
+ * Add view helper `preview_source` for rendering a source code preview below previews.
133
+ * Add config option `config.view_component.show_previews_source` for enabling the source preview.
134
+
135
+ *Johannes Engl*
136
+
137
+ * Add documentation for compatibility with ActionText.
138
+
139
+ *Jared Planter*
140
+
141
+ ## 2.34.0
142
+
143
+ * Add the ability to enable ActiveSupport notifications (`!render.view_component` event) with `config.view_component.instrumentation_enabled`.
144
+
145
+ *Svyatoslav Kryukov*
146
+
147
+ * Add [Generators](https://viewcomponent.org/guide/generators.html) page to documentation.
148
+
149
+ *Hans Lemuet*
150
+
151
+ * Fix bug where ViewComponents did not work in ActionMailers.
152
+
153
+ *dark-panda*
154
+
5
155
  ## 2.33.0
6
156
 
7
157
  * Add support for `_iteration` parameter when rendering in a collection