loco_motion-rails 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
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