Module: ComponentHelper
- Defined in:
- app/helpers/component_helper.rb
Overview
The Registry of Names
All components available to views are declared here. There is no method_missing sorcery, no dynamic resolution, no convention-based guessing. If a component is not in the registry, it does not exist.
To create a new component: add one line to COMPONENT_MAP and create the class.
See: specs/the-holy-view-spec.md, Article 3
Constant Summary collapse
- COMPONENT_MAP =
{ # Layout Primitives VStack: "VStackComponent", HStack: "HStackComponent", Column: "ColumnComponent", Row: "RowComponent", Pusher: "PusherComponent", Overlay: "OverlayComponent", LinkTo: "LinkToComponent", SubHeader: "SubHeaderComponent", # Globals Reset: "ResetComponent", Site: "SiteComponent", Wrapper: "WrapperComponent", Template: "TemplateComponent", BackButton: "BackButtonComponent", # Elements Button: "ButtonComponent", Paragraph: "ParagraphComponent", ButtonTo: "ButtonToComponent", Container: "ContainerComponent", Divider: "DividerComponent", Emoji: "EmojiComponent", Flag: "FlagComponent", Header: "HeaderComponent", Icon: "IconComponent", Image: "ImageComponent", Input: "InputComponent", Tag: "TagComponent", TagGroup: "TagGroupComponent", List: "ListComponent", ListItem: "ListItemComponent", ListContent: "ListContentComponent", ListHeader: "ListHeaderComponent", ListDescription: "ListDescriptionComponent", Loader: "LoaderComponent", Placeholder: "PlaceholderComponent", Rail: "RailComponent", Reveal: "RevealComponent", Segment: "SegmentComponent", SegmentGroup: "SegmentGroupComponent", Step: "StepComponent", StepGroup: "StepGroupComponent", Text: "TextComponent", ButtonGroup: "ButtonGroupComponent", # Collections Breadcrumb: "BreadcrumbComponent", Field: "FieldComponent", Form: "FormComponent", Grid: "GridComponent", Menu: "MenuComponent", MenuItem: "MenuItemComponent", SubMenu: "SubMenuComponent", Message: "MessageComponent", Table: "TableComponent", TableRow: "TableRowComponent", TableCell: "TableCellComponent", # Views Ad: "AdComponent", ItemGroup: "ItemGroupComponent", Card: "CardComponent", Comment: "CommentComponent", CommentGroup: "CommentGroupComponent", CommentReplyGroup: "CommentReplyGroupComponent", CommentReply: "CommentReplyComponent", Feed: "FeedComponent", FeedItem: "FeedItemComponent", Item: "ItemComponent", Statistic: "StatisticComponent", # Modules Accordion: "AccordionComponent", AccordionItem: "AccordionItemComponent", SubAccordion: "SubAccordionComponent", Calendar: "CalendarComponent", Dimmer: "DimmerComponent", Dropdown: "DropdownComponent", Embed: "EmbedComponent", Flyout: "FlyoutComponent", Modal: "ModalComponent", Nag: "NagComponent", Popup: "PopupComponent", Progress: "ProgressComponent", Slider: "SliderComponent", Rating: "RatingComponent", Search: "SearchComponent", Shape: "ShapeComponent", Sidebar: "SidebarComponent", Sticky: "StickyComponent", Tab: "TabComponent", TabGroup: "TabGroupComponent", Toast: "ToastComponent", Transition: "TransitionComponent", # Behaviors Api: "ApiComponent", State: "StateComponent", Visibility: "VisibilityComponent", # Blocks ResourceListBlock: "ResourceListBlock" }.freeze
Instance Method Summary collapse
- #ContentFor(*args, &block) ⇒ Object
- #CspMetaTag ⇒ Object
- #CsrfMetaTags ⇒ Object
- #DocType(type = :html) ⇒ Object
- #JavascriptImportmap ⇒ Object
-
#method_missing(method_name, *args, **kwargs, &block) ⇒ Object
PascalCase method calls that aren’t in COMPONENT_MAP are forwarded to the current form builder as underscored method names.
- #NbSpace ⇒ Object
- #Partial(*args, **kwargs, &block) ⇒ Object
- #respond_to_missing?(method_name, include_private = false) ⇒ Boolean
- #Style(css = nil, &block) ⇒ Object
- #StylesheetLink(*args) ⇒ Object
- #text(content) ⇒ Object
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, **kwargs, &block) ⇒ Object
PascalCase method calls that aren’t in COMPONENT_MAP are forwarded to the current form builder as underscored method names. e.g. TextField(:label, placeholder: “Name”) -> f.text_field(:label, placeholder: “Name”)
EmojiField(:icon) -> f.emoji_field(:icon)
Select(:role, [["Admin","admin"]]) -> f.select(:role, [["Admin","admin"]])
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 |
# File 'app/helpers/component_helper.rb', line 176 def method_missing(method_name, *args, **kwargs, &block) if method_name =~ /\A[A-Z]/ && @_form_builder underscored = method_name.to_s.gsub(/([a-z])([A-Z])/, '\1_\2').downcase if @_form_builder.respond_to?(underscored) output_buffer << @_form_builder.public_send(underscored, *args, **kwargs, &block) return end end if method_name =~ /\A[A-Z]/ tag_name = method_name.to_s.underscore.gsub("_", "-") output_buffer << tag.public_send(tag_name, *args, **kwargs, &block) return end super end |
Instance Method Details
#ContentFor(*args, &block) ⇒ Object
165 166 167 168 169 |
# File 'app/helpers/component_helper.rb', line 165 def ContentFor(*args, &block) value = content_for(*args, &block) output_buffer << value if value.present? value end |
#CspMetaTag ⇒ Object
161 162 163 |
# File 'app/helpers/component_helper.rb', line 161 def CspMetaTag output_buffer << end |
#CsrfMetaTags ⇒ Object
157 158 159 |
# File 'app/helpers/component_helper.rb', line 157 def CsrfMetaTags output_buffer << end |
#DocType(type = :html) ⇒ Object
145 146 147 |
# File 'app/helpers/component_helper.rb', line 145 def DocType(type = :html) output_buffer << "<!DOCTYPE #{type}>".html_safe end |
#JavascriptImportmap ⇒ Object
153 154 155 |
# File 'app/helpers/component_helper.rb', line 153 def JavascriptImportmap output_buffer << end |
#NbSpace ⇒ Object
137 138 139 |
# File 'app/helpers/component_helper.rb', line 137 def NbSpace output_buffer << " ".html_safe end |
#Partial(*args, **kwargs, &block) ⇒ Object
141 142 143 |
# File 'app/helpers/component_helper.rb', line 141 def Partial(*args, **kwargs, &block) output_buffer << render(*args, **kwargs, &block) end |
#respond_to_missing?(method_name, include_private = false) ⇒ Boolean
194 195 196 197 198 199 200 201 202 203 |
# File 'app/helpers/component_helper.rb', line 194 def respond_to_missing?(method_name, include_private = false) if method_name =~ /\A[A-Z]/ && @_form_builder underscored = method_name.to_s.gsub(/([a-z])([A-Z])/, '\1_\2').downcase return true if @_form_builder.respond_to?(underscored) end return true if method_name =~ /\A[A-Z]/ super end |
#Style(css = nil, &block) ⇒ Object
129 130 131 |
# File 'app/helpers/component_helper.rb', line 129 def Style(css = nil, &block) output_buffer << render("StyleComponent".constantize.new(css), &block) end |
#StylesheetLink(*args) ⇒ Object
149 150 151 |
# File 'app/helpers/component_helper.rb', line 149 def StylesheetLink(*args) output_buffer << stylesheet_link_tag(*args) end |
#text(content) ⇒ Object
133 134 135 |
# File 'app/helpers/component_helper.rb', line 133 def text(content) output_buffer << content.to_s end |