loco_motion-rails 0.0.6

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 (67) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +880 -0
  4. data/app/components/daisy/actions/button_component.html.haml +7 -0
  5. data/app/components/daisy/actions/button_component.rb +52 -0
  6. data/app/components/daisy/actions/dropdown_component.html.haml +13 -0
  7. data/app/components/daisy/actions/dropdown_component.rb +48 -0
  8. data/app/components/daisy/actions/modal_component.html.haml +31 -0
  9. data/app/components/daisy/actions/modal_component.rb +92 -0
  10. data/app/components/daisy/actions/swap_component.html.haml +17 -0
  11. data/app/components/daisy/actions/swap_component.rb +56 -0
  12. data/app/components/daisy/actions/theme_controller_component.html.haml +5 -0
  13. data/app/components/daisy/actions/theme_controller_component.rb +8 -0
  14. data/app/components/daisy/data_display/accordion_component.html.haml +4 -0
  15. data/app/components/daisy/data_display/accordion_component.rb +82 -0
  16. data/app/components/daisy/data_display/avatar_component.html.haml +9 -0
  17. data/app/components/daisy/data_display/avatar_component.rb +60 -0
  18. data/app/components/daisy/data_display/badge_component.html.haml +2 -0
  19. data/app/components/daisy/data_display/badge_component.rb +27 -0
  20. data/app/components/daisy/data_display/card_component.html.haml +17 -0
  21. data/app/components/daisy/data_display/card_component.rb +53 -0
  22. data/app/components/daisy/data_display/carousel_component.html.haml +3 -0
  23. data/app/components/daisy/data_display/carousel_component.rb +17 -0
  24. data/app/components/daisy/data_display/chat_component.html.haml +14 -0
  25. data/app/components/daisy/data_display/chat_component.rb +38 -0
  26. data/app/components/daisy/data_display/collapse_component.html.haml +13 -0
  27. data/app/components/daisy/data_display/collapse_component.rb +37 -0
  28. data/app/components/daisy/data_display/countdown_component.html.haml +24 -0
  29. data/app/components/daisy/data_display/countdown_component.rb +70 -0
  30. data/app/components/daisy/data_display/countdown_controller.js +78 -0
  31. data/app/components/daisy/data_display/diff_component.html.haml +6 -0
  32. data/app/components/daisy/data_display/diff_component.rb +25 -0
  33. data/app/components/daisy/data_display/kbd_component.html.haml +2 -0
  34. data/app/components/daisy/data_display/kbd_component.rb +21 -0
  35. data/app/components/daisy/data_display/stat_component.html.haml +27 -0
  36. data/app/components/daisy/data_display/stat_component.rb +41 -0
  37. data/app/components/daisy/data_display/table_component.html.haml +14 -0
  38. data/app/components/daisy/data_display/table_component.rb +148 -0
  39. data/app/components/daisy/data_display/timeline_component.html.haml +7 -0
  40. data/app/components/daisy/data_display/timeline_component.rb +8 -0
  41. data/app/components/daisy/data_display/timeline_event_component.html.haml +28 -0
  42. data/app/components/daisy/data_display/timeline_event_component.rb +47 -0
  43. data/app/components/daisy/feedback/alert_component.html.haml +8 -0
  44. data/app/components/daisy/feedback/alert_component.rb +19 -0
  45. data/app/components/daisy/layout/join_component.rb +15 -0
  46. data/app/components/daisy/navigation/bottom_nav_component.rb +59 -0
  47. data/app/components/daisy/navigation/breadcrumbs_component.html.haml +7 -0
  48. data/app/components/daisy/navigation/breadcrumbs_component.rb +15 -0
  49. data/app/components/daisy/navigation/link_component.html.haml +4 -0
  50. data/app/components/daisy/navigation/link_component.rb +34 -0
  51. data/app/components/daisy/navigation/menu_component.html.haml +3 -0
  52. data/app/components/daisy/navigation/menu_component.rb +49 -0
  53. data/app/components/daisy/navigation/navbar_component.html.haml +4 -0
  54. data/app/components/daisy/navigation/navbar_component.rb +12 -0
  55. data/app/components/daisy/navigation/steps_component.rb +40 -0
  56. data/app/components/daisy/navigation/tabs_component.html.haml +4 -0
  57. data/app/components/daisy/navigation/tabs_component.rb +107 -0
  58. data/app/components/hero/icon_component.rb +18 -0
  59. data/lib/daisy/helpers.rb +61 -0
  60. data/lib/daisy.rb +19 -0
  61. data/lib/loco_motion/base_component.rb +371 -0
  62. data/lib/loco_motion/basic_component.rb +18 -0
  63. data/lib/loco_motion/component_config.rb +165 -0
  64. data/lib/loco_motion/engine.rb +8 -0
  65. data/lib/loco_motion/errors.rb +33 -0
  66. data/lib/loco_motion.rb +48 -0
  67. metadata +408 -0
@@ -0,0 +1,59 @@
1
+ class Daisy::Navigation::BottomNavComponent < LocoMotion.configuration.base_component_class
2
+
3
+ class Daisy::Navigation::BottomNavSectionComponent < LocoMotion.configuration.base_component_class
4
+
5
+ define_parts :icon, :title
6
+
7
+ def initialize(*args, **kws, &block)
8
+ super
9
+
10
+ @icon = config_option(:icon)
11
+ @icon_variant = config_option(:icon_variant, :outline)
12
+ @title = config_option(:title)
13
+ @href = config_option(:href)
14
+ @active = config_option(:active, false)
15
+ end
16
+
17
+ def before_render
18
+ if @href
19
+ set_tag_name(:component, :a)
20
+ add_html(:component, href: @href)
21
+ else
22
+ set_tag_name(:component, :button)
23
+ end
24
+
25
+ add_css(:component, "active") if @active
26
+
27
+ add_css(:icon, "[:where(&)]:size-6")
28
+
29
+ set_tag_name(:title, :span)
30
+ add_css(:title, "btm-nav-label")
31
+ end
32
+
33
+ def call
34
+ part(:component) do
35
+ concat(hero_icon(@icon, variant: @icon_variant, html: rendered_html(:icon))) if @icon
36
+ concat(part(:title) { @title }) if @title
37
+ concat(content)
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ renders_many :sections, Daisy::Navigation::BottomNavSectionComponent
44
+
45
+ def before_render
46
+ add_css(:component, "btm-nav")
47
+ end
48
+
49
+ def call
50
+ part(:component) do
51
+ sections.each do |section|
52
+ concat(section)
53
+ end
54
+
55
+ concat(content)
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,7 @@
1
+ = part(:component) do
2
+ = part(:list_wrapper) do
3
+ - items.each do |item|
4
+ - item.set_loco_parent(component_ref)
5
+ = item
6
+
7
+ = content
@@ -0,0 +1,15 @@
1
+ class Daisy::Navigation::BreadcrumbsComponent < LocoMotion.configuration.base_component_class
2
+ define_parts :list_wrapper
3
+
4
+ renders_many :items, LocoMotion::BasicComponent.build(tag_name: :li)
5
+
6
+ def initialize(*args, **kws, &block)
7
+ super
8
+ end
9
+
10
+ def before_render
11
+ add_css(:component, "breadcrumbs")
12
+
13
+ set_tag_name(:list_wrapper, :ul)
14
+ end
15
+ end
@@ -0,0 +1,4 @@
1
+ = part(:component) do
2
+ = @text if @text
3
+
4
+ = content
@@ -0,0 +1,34 @@
1
+ #
2
+ # The Daisy::Navigation::LinkComponent is a simple component that renders an
3
+ # anchor tag.
4
+ #
5
+ class Daisy::Navigation::LinkComponent < LocoMotion.configuration.base_component_class
6
+
7
+ # Create a new instance of the LinkComponent.
8
+ #
9
+ # If passed **two** positional arguments, the first is considered the `text`
10
+ # and the second is considered the `href`. If passed only **one** positional
11
+ # argument, it is treated as the `href` and we assume the `text` will be
12
+ # provided in the block. `target` is always a keyword argument.
13
+ #
14
+ # @param text [String] The text to display in the link.
15
+ # @param href [String] The URL to visit when the link is clicked.
16
+ # @param target [String] The target attribute for the anchor tag.
17
+ def initialize(*args, **kws, &block)
18
+ super
19
+
20
+ @text = config_option(:text, args.size == 2 ? args[0] : nil)
21
+ @href = config_option(:href, args.size == 2 ? args[1] : args[0])
22
+ end
23
+
24
+ #
25
+ # Adds the relevant Daisy classes and applies the href and target attributes
26
+ # if provided.
27
+ #
28
+ def before_render
29
+ set_tag_name(:component, :a)
30
+ add_css(:component, "link")
31
+ add_html(:component, { href: @href }) if @href
32
+ add_html(:component, { target: @target }) if @target
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ = part(:component) do
2
+ - items.each do |item|
3
+ = item
@@ -0,0 +1,49 @@
1
+ class Daisy::Navigation::MenuComponent < LocoMotion.configuration.base_component_class
2
+
3
+ #
4
+ # The items for the MenuComponent.
5
+ #
6
+ #
7
+ class Daisy::Navigation::MenuItemComponent < LocoMotion.configuration.base_component_class
8
+ define_part :title
9
+
10
+ #
11
+ # Create a new instance of the MenuItemComponent.
12
+ #
13
+ # @param title [String] (Optional) Shows an additional title above the item.
14
+ # @param disabled [Boolean] (Optional) Sets the item in a disabled state.
15
+ #
16
+ def initialize(*args, **kws, &block)
17
+ super
18
+
19
+ @simple_title = config_option(:title)
20
+ @disabled = config_option(:disabled)
21
+ end
22
+
23
+ def before_render
24
+ set_tag_name(:component, :li)
25
+ add_css(:component, "disabled pointer-events-none") if @disabled
26
+
27
+ set_tag_name(:title, :h2)
28
+ add_css(:title, "menu-title")
29
+ end
30
+
31
+ def call
32
+ part(:component) do
33
+ concat(part(:title) { @simple_title }) if @simple_title
34
+ concat(content)
35
+ end
36
+ end
37
+ end
38
+
39
+ renders_many :items, Daisy::Navigation::MenuItemComponent
40
+
41
+ def initialize(*args, **kws, &block)
42
+ super
43
+ end
44
+
45
+ def before_render
46
+ set_tag_name(:component, :ul)
47
+ add_css(:component, "menu")
48
+ end
49
+ end
@@ -0,0 +1,4 @@
1
+ = part(:component) do
2
+ = start if start?
3
+ = center if center?
4
+ = tail if tail?
@@ -0,0 +1,12 @@
1
+ class Daisy::Navigation::NavbarComponent < LocoMotion.configuration.base_component_class
2
+ renders_one :start, LocoMotion::BasicComponent.build(css: "navbar-start")
3
+
4
+ renders_one :center, LocoMotion::BasicComponent.build(css: "navbar-center")
5
+
6
+ # End is a reserved word in Ruby
7
+ renders_one :tail, LocoMotion::BasicComponent.build(css: "navbar-end")
8
+
9
+ def before_render
10
+ add_css(:component, "navbar")
11
+ end
12
+ end
@@ -0,0 +1,40 @@
1
+ class Daisy::Navigation::StepsComponent < LocoMotion.configuration.base_component_class
2
+
3
+ class Daisy::Navigation::StepComponent < LocoMotion.configuration.base_component_class
4
+ attr_reader :simple
5
+ def initialize(*args, **kws, &block)
6
+ super
7
+
8
+ @simple_title = config_option(:title)
9
+ @number = config_option(:number)
10
+ end
11
+
12
+ def before_render
13
+ set_tag_name(:component, :li)
14
+ add_css(:component, "step")
15
+ add_html(:component, { data: { content: @number } }) if @number
16
+ end
17
+
18
+ def call
19
+ part(:component) do
20
+ concat(@simple_title) if @simple_title
21
+ concat(content) if content?
22
+ end
23
+ end
24
+ end
25
+
26
+ renders_many :steps, Daisy::Navigation::StepComponent
27
+
28
+ def before_render
29
+ set_tag_name(:component, :ul)
30
+ add_css(:component, "steps")
31
+ end
32
+
33
+ def call
34
+ part(:component) do
35
+ steps.each do |step|
36
+ concat(step)
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,4 @@
1
+ = part(:component) do
2
+ - tabs.each do |tab|
3
+ - tab.set_loco_parent(component_ref)
4
+ = tab
@@ -0,0 +1,107 @@
1
+ # This is the Tabs component.
2
+ class Daisy::Navigation::TabsComponent < LocoMotion.configuration.base_component_class
3
+
4
+ class TabComponent < LocoMotion::BasicComponent
5
+ define_parts :content_wrapper
6
+
7
+ renders_one :title
8
+ renders_one :custom_content
9
+
10
+ attr_reader :active
11
+
12
+ # @return [String] Accessor for the `title` string passed via the component
13
+ # config.
14
+ attr_reader :simple_title
15
+
16
+ def initialize(*args, **kws, &block)
17
+ super
18
+
19
+ @active = config_option(:active, false)
20
+ @checked = config_option(:checked, false)
21
+ @disabled = config_option(:disabled, false)
22
+ @href = config_option(:href)
23
+ @simple_title = config_option(:title)
24
+ @target = config_option(:target)
25
+ @value = config_option(:value)
26
+ end
27
+
28
+ def before_render
29
+ # Reset the name to the config option or the parent name if available
30
+ @name = config_option(:name, loco_parent&.name)
31
+
32
+ if loco_parent&.radio?
33
+ setup_radio_button
34
+ else
35
+ setup_component
36
+ end
37
+
38
+ setup_content_wrapper unless custom_content?
39
+ end
40
+
41
+ def setup_component
42
+ set_tag_name(:component, :a)
43
+ add_css(:component, "tab")
44
+ add_css(:component, "tab-active") if @active || @checked
45
+ add_html(:component, { role: "tab", href: @href, target: @target, "aria-label": @simple_title })
46
+ add_html(:component, { disabled: @disabled }) if @disabled
47
+ end
48
+
49
+ def setup_radio_button
50
+ set_tag_name(:component, :input)
51
+ add_css(:component, "tab")
52
+ add_html(:component, {
53
+ type: "radio",
54
+ role: "tab",
55
+ "aria-label": @simple_title,
56
+ name: @name,
57
+ value: @value,
58
+ checked: @active || @checked
59
+ })
60
+ add_html(:component, { disabled: @disabled }) if @disabled
61
+ end
62
+
63
+ def setup_content_wrapper
64
+ add_css(:content_wrapper, "tab-content")
65
+ add_html(:content_wrapper, { role: "tabpanel" })
66
+ end
67
+
68
+ def call
69
+ # Not sure why we need these, but this forces the rendering below to
70
+ # include the content blocks passed to each slot.
71
+ # title.to_s if title?
72
+ # custom_content.to_s if custom_content?
73
+
74
+ capture do
75
+ if loco_parent&.radio?
76
+ concat(part(:component))
77
+ else
78
+ concat(part(:component) { concat(title? ? title : @simple_title) })
79
+ end
80
+
81
+ concat(part(:content_wrapper) { content }) if content? && content
82
+ concat(custom_content) if custom_content?
83
+ end
84
+ end
85
+ end
86
+
87
+ renders_many :tabs, TabComponent
88
+
89
+ attr_reader :name, :radio
90
+
91
+ def initialize(*args, **kws, &block)
92
+ super
93
+
94
+ @name = config_option(:name, "tabs-#{SecureRandom.uuid}")
95
+ @radio = config_option(:radio, false)
96
+ end
97
+
98
+ def before_render
99
+ add_css(:component, "tabs")
100
+ add_html(:component, { role: "tablist" })
101
+ end
102
+
103
+ def radio?
104
+ radio
105
+ end
106
+
107
+ end
@@ -0,0 +1,18 @@
1
+ class Hero::IconComponent < LocoMotion.configuration.base_component_class
2
+ def initialize(*args, **kws, &block)
3
+ super
4
+
5
+ # Accept either the :icon keyword argument or the first positional argument
6
+ @icon = config_option(:icon, args[0])
7
+ @variant = config_option(:variant)
8
+ end
9
+
10
+ def before_render
11
+ add_html(:component, { variant: @variant }) if @variant
12
+ add_css(:component, "[:where(&)]:size-5")
13
+ end
14
+
15
+ def call
16
+ heroicon_tag(@icon, **rendered_html(:component))
17
+ end
18
+ end
@@ -0,0 +1,61 @@
1
+ module Daisy
2
+ COMPONENT_HELPERS = {
3
+ # TODO: The hero icons should be in a different helper? Or maybe this whole
4
+ # thing should be in a Loco module instead of Daisy?
5
+
6
+ ### Hero Icons
7
+ icon: "Hero::IconComponent",
8
+
9
+ ### Daisy Components
10
+
11
+ # Actions
12
+ button: "Daisy::Actions::ButtonComponent",
13
+ dropdown: "Daisy::Actions::DropdownComponent",
14
+ modal: "Daisy::Actions::ModalComponent",
15
+ swap: "Daisy::Actions::SwapComponent",
16
+ theme_controller: "Daisy::Actions::ThemeControllerComponent",
17
+
18
+ # Data
19
+ accordion: "Daisy::DataDisplay::AccordionComponent",
20
+ avatar: "Daisy::DataDisplay::AvatarComponent",
21
+ badge: "Daisy::DataDisplay::BadgeComponent",
22
+ card: "Daisy::DataDisplay::CardComponent",
23
+ carousel: "Daisy::DataDisplay::CarouselComponent",
24
+ chat: "Daisy::DataDisplay::ChatComponent",
25
+ collapse: "Daisy::DataDisplay::CollapseComponent",
26
+ countdown: "Daisy::DataDisplay::CountdownComponent",
27
+ diff: "Daisy::DataDisplay::DiffComponent",
28
+ kbd: "Daisy::DataDisplay::KbdComponent",
29
+ stat: "Daisy::DataDisplay::StatComponent",
30
+ table: "Daisy::DataDisplay::TableComponent",
31
+ timeline: "Daisy::DataDisplay::TimelineComponent",
32
+
33
+ # Navigation
34
+ breadcrumbs: "Daisy::Navigation::BreadcrumbsComponent",
35
+ bottom_nav: "Daisy::Navigation::BottomNavComponent",
36
+ link: "Daisy::Navigation::LinkComponent",
37
+ menu: "Daisy::Navigation::MenuComponent",
38
+ navbar: "Daisy::Navigation::NavbarComponent",
39
+ # TODO: This doesn't exist as a component, so it feels weird to have it
40
+ # here; but it makes the navigation work properly.
41
+ pagination: "Daisy::Navigation::PaginationComponent",
42
+ steps: "Daisy::Navigation::StepsComponent",
43
+ tabs: "Daisy::Navigation::TabsComponent",
44
+
45
+ # Feedback
46
+ alert: "Daisy::Feedback::AlertComponent",
47
+
48
+ # Layout
49
+ join: "Daisy::Layout::JoinComponent",
50
+ }
51
+
52
+ module Helpers
53
+ COMPONENT_HELPERS.each do |method_name, component_klass|
54
+ framework = component_klass.split("::").first.downcase
55
+
56
+ ActionView::Helpers.define_method("#{framework}_#{method_name}") do |*args, **kws, &block|
57
+ render(component_klass.constantize.new(*args, **kws), &block)
58
+ end
59
+ end
60
+ end
61
+ end
data/lib/daisy.rb ADDED
@@ -0,0 +1,19 @@
1
+ require "daisy/helpers"
2
+ require "heroicons-rails"
3
+
4
+ module Daisy
5
+ #
6
+ # Holds all Action-type components.
7
+ #
8
+ module Actions; end
9
+
10
+ #
11
+ # Holds all Data-type components.
12
+ #
13
+ module DataDisplay; end
14
+
15
+ #
16
+ # Holds all Navigation-type components.
17
+ #
18
+ module Navigation; end
19
+ end