alveole 0.0.1 → 1.0.0.pre.alpha.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +21 -26
  4. data/Rakefile +6 -8
  5. data/app/assets/config/alveole_manifest.js +5 -0
  6. data/app/assets/images/alveole/icons/favicon-150.png +0 -0
  7. data/app/assets/javascripts/alveole/application.js +10 -0
  8. data/app/assets/stylesheets/alveole/application.css +15 -0
  9. data/app/assets/stylesheets/application.tailwind.css +13 -0
  10. data/app/components/alveole/button_component.html.erb +10 -0
  11. data/app/components/alveole/button_component.rb +46 -0
  12. data/app/components/alveole/chip_component.html.erb +3 -0
  13. data/app/components/alveole/chip_component.rb +23 -0
  14. data/app/components/alveole/dropdown/menu_item_component.html.erb +2 -0
  15. data/app/components/alveole/dropdown/menu_item_component.rb +5 -0
  16. data/app/components/alveole/dropdown_component.html.erb +27 -0
  17. data/app/components/alveole/dropdown_component.rb +21 -0
  18. data/app/components/alveole/footer/link_component.html.erb +6 -0
  19. data/app/components/alveole/footer/link_component.rb +8 -0
  20. data/app/components/alveole/footer_component.html.erb +14 -0
  21. data/app/components/alveole/footer_component.rb +9 -0
  22. data/app/components/alveole/form_layout_component.html.erb +32 -0
  23. data/app/components/alveole/form_layout_component.rb +43 -0
  24. data/app/components/alveole/icon_component.html.erb +1 -0
  25. data/app/components/alveole/icon_component.rb +20 -0
  26. data/app/components/alveole/input/avatar_component.html.erb +16 -0
  27. data/app/components/alveole/input/avatar_component.rb +4 -0
  28. data/app/components/alveole/input/base_component.rb +16 -0
  29. data/app/components/alveole/input/comment_component.html.erb +153 -0
  30. data/app/components/alveole/input/comment_component.rb +5 -0
  31. data/app/components/alveole/input/counter_component.html.erb +16 -0
  32. data/app/components/alveole/input/counter_component.rb +4 -0
  33. data/app/components/alveole/input/email_component.html.erb +17 -0
  34. data/app/components/alveole/input/email_component.rb +4 -0
  35. data/app/components/alveole/input/file_component.html.erb +4 -0
  36. data/app/components/alveole/input/file_component.rb +4 -0
  37. data/app/components/alveole/input/search_component.html.erb +7 -0
  38. data/app/components/alveole/input/search_component.rb +5 -0
  39. data/app/components/alveole/input/select_component.html.erb +4 -0
  40. data/app/components/alveole/input/select_component.rb +12 -0
  41. data/app/components/alveole/input/text_component.html.erb +17 -0
  42. data/app/components/alveole/input/text_component.rb +4 -0
  43. data/app/components/alveole/input/textarea_component.html.erb +16 -0
  44. data/app/components/alveole/input/textarea_component.rb +4 -0
  45. data/app/components/alveole/mega_menu_component.html.erb +107 -0
  46. data/app/components/alveole/mega_menu_component.rb +6 -0
  47. data/app/components/alveole/sidebar/divider_component.html.erb +5 -0
  48. data/app/components/alveole/sidebar/divider_component.rb +5 -0
  49. data/app/components/alveole/sidebar/group_component.html.erb +7 -0
  50. data/app/components/alveole/sidebar/group_component.rb +37 -0
  51. data/app/components/alveole/sidebar/heading_component.html.erb +3 -0
  52. data/app/components/alveole/sidebar/heading_component.rb +8 -0
  53. data/app/components/alveole/sidebar/item_component.html.erb +14 -0
  54. data/app/components/alveole/sidebar/item_component.rb +17 -0
  55. data/app/components/alveole/sidebar_component.html.erb +13 -0
  56. data/app/components/alveole/sidebar_component.rb +40 -0
  57. data/app/controllers/alveole/application_controller.rb +4 -0
  58. data/app/helpers/alveole/application_helper.rb +4 -0
  59. data/app/jobs/alveole/application_job.rb +4 -0
  60. data/app/mailers/alveole/application_mailer.rb +6 -0
  61. data/app/models/alveole/application_record.rb +5 -0
  62. data/app/views/layouts/alveole/application.html.erb +28 -0
  63. data/config/importmap.rb +7 -0
  64. data/config/routes.rb +2 -0
  65. data/config/tailwind.config.js +42 -0
  66. data/lib/alveole/engine.rb +18 -21
  67. data/lib/alveole/version.rb +1 -1
  68. data/lib/alveole.rb +2 -12
  69. data/lib/tasks/alveole_tasks.rake +14 -0
  70. metadata +110 -110
  71. data/.gitignore +0 -8
  72. data/.gitlab-ci.yml +0 -55
  73. data/.rubocop.yml +0 -63
  74. data/.rubocop_todo.yml +0 -12
  75. data/.travis.yml +0 -6
  76. data/CODE_OF_CONDUCT.md +0 -74
  77. data/Gemfile +0 -7
  78. data/Gemfile.lock +0 -171
  79. data/LICENSE.txt +0 -21
  80. data/alveole.gemspec +0 -35
  81. data/bin/console +0 -14
  82. data/bin/setup +0 -8
  83. data/lib/alveole/components/avatar_component/avatar_component.html.slim +0 -6
  84. data/lib/alveole/components/avatar_component.rb +0 -9
  85. data/lib/alveole/components/badge_component/badge_component.html.slim +0 -2
  86. data/lib/alveole/components/badge_component.rb +0 -8
  87. data/lib/alveole/components/breadcrumb_component/breadcrumb_component.html.slim +0 -2
  88. data/lib/alveole/components/breadcrumb_component.rb +0 -8
  89. data/lib/alveole/components/breadcrumbs_component.rb +0 -7
  90. data/lib/alveole/components/button_component/button_component.html.slim +0 -5
  91. data/lib/alveole/components/button_component.rb +0 -15
  92. data/lib/alveole/components/definition_component/definition_component.html.slim +0 -4
  93. data/lib/alveole/components/definition_component.rb +0 -13
  94. data/lib/alveole/components/form_component/form_component.html.slim +0 -3
  95. data/lib/alveole/components/form_component.rb +0 -3
  96. data/lib/alveole/components/form_submit_component/form_submit_component.html.slim +0 -1
  97. data/lib/alveole/components/form_submit_component.rb +0 -7
  98. data/lib/alveole/components/heading_component/heading_component.html.slim +0 -4
  99. data/lib/alveole/components/heading_component.rb +0 -8
  100. data/lib/alveole/components/input_component/input_component.html.slim +0 -17
  101. data/lib/alveole/components/input_component.rb +0 -42
  102. data/lib/alveole/components/notice_component/notice_component.html.slim +0 -5
  103. data/lib/alveole/components/notice_component.rb +0 -15
  104. data/lib/alveole/components/page_component/page_component.html.slim +0 -10
  105. data/lib/alveole/components/page_component.rb +0 -4
  106. data/lib/alveole/components/sidebar_component/sidebar_component.html.slim +0 -7
  107. data/lib/alveole/components/sidebar_component.rb +0 -4
  108. data/lib/alveole/components/table_column_component/table_column_component.html.slim +0 -3
  109. data/lib/alveole/components/table_column_component.rb +0 -12
  110. data/lib/alveole/components/table_component/table_component.html.slim +0 -7
  111. data/lib/alveole/components/table_component.rb +0 -3
  112. data/lib/alveole/components/table_header_component/table_header_component.html.slim +0 -2
  113. data/lib/alveole/components/table_header_component.rb +0 -8
  114. data/lib/alveole/components/table_row_component/table_row_component.html.slim +0 -4
  115. data/lib/alveole/components/table_row_component.rb +0 -3
  116. data/lib/alveole/components/toolbar_component/toolbar_component.html.slim +0 -7
  117. data/lib/alveole/components/toolbar_component.rb +0 -4
  118. data/lib/alveole/concerns/bem.rb +0 -21
  119. data/lib/alveole/helpers/method_helper.rb +0 -31
  120. data/lib/alveole/javascript/components.js +0 -5
  121. data/lib/alveole/previews/avatar_component_preview.rb +0 -11
  122. data/lib/alveole/previews/badge_component_preview.rb +0 -11
  123. data/lib/alveole/previews/breadcrumb_component_preview.rb +0 -15
  124. data/lib/alveole/previews/button_component_preview.rb +0 -7
  125. data/lib/alveole/previews/definition_component_preview.rb +0 -33
  126. data/lib/alveole/previews/form_component_preview.rb +0 -18
  127. data/lib/alveole/previews/form_submit_component_preview.rb +0 -7
  128. data/lib/alveole/previews/heading_component_preview.rb +0 -11
  129. data/lib/alveole/previews/input_component_preview.rb +0 -32
  130. data/lib/alveole/previews/notice_component_preview.rb +0 -15
  131. data/lib/alveole/previews/page_component_preview.rb +0 -33
  132. data/lib/alveole/previews/sidebar_component_preview.rb +0 -33
  133. data/lib/alveole/previews/table_column_component_preview.rb +0 -36
  134. data/lib/alveole/previews/table_component_preview.rb +0 -12
  135. data/lib/alveole/previews/table_header_component_preview.rb +0 -27
  136. data/lib/alveole/previews/table_row_component_preview.rb +0 -18
  137. data/lib/alveole/previews/toolbar_component_preview.rb +0 -33
  138. data/lib/generators/alveole/config_generator.rb +0 -17
  139. data/lib/generators/alveole/templates/alveole_config.rb +0 -1
@@ -0,0 +1,153 @@
1
+ <alv-input-comment class="block mt-6 flex gap-x-3">
2
+ <%= render(AvatarComponent.new(src: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80", size: :xs, class: "flex-none")) %>
3
+ <form action="#" class="relative flex-auto">
4
+ <div class="overflow-hidden rounded-lg pb-12 shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-primary-600">
5
+ <label for="comment" class="sr-only">Add your comment</label>
6
+ <textarea rows="2" name="comment" id="comment" class="block w-full resize-none border-0 bg-transparent py-1.5 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm sm:leading-6" placeholder="Add your comment..."></textarea>
7
+ </div>
8
+
9
+ <div class="absolute inset-x-0 bottom-0 flex justify-between py-2 pl-3 pr-2">
10
+ <div class="flex items-center space-x-5">
11
+ <div class="flex items-center">
12
+ <button type="button" class="-m-2.5 flex h-10 w-10 items-center justify-center rounded-full text-gray-400 hover:text-gray-500">
13
+ <svg class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
14
+ <path fill-rule="evenodd" d="M15.621 4.379a3 3 0 00-4.242 0l-7 7a3 3 0 004.241 4.243h.001l.497-.5a.75.75 0 011.064 1.057l-.498.501-.002.002a4.5 4.5 0 01-6.364-6.364l7-7a4.5 4.5 0 016.368 6.36l-3.455 3.553A2.625 2.625 0 119.52 9.52l3.45-3.451a.75.75 0 111.061 1.06l-3.45 3.451a1.125 1.125 0 001.587 1.595l3.454-3.553a3 3 0 000-4.242z" clip-rule="evenodd" />
15
+ </svg>
16
+ <span class="sr-only">Attach a file</span>
17
+ </button>
18
+ </div>
19
+ <div class="flex items-center">
20
+ <div>
21
+ <label id="listbox-label" class="sr-only">Your mood</label>
22
+ <div class="relative">
23
+ <button type="button" class="relative -m-2.5 flex h-10 w-10 items-center justify-center rounded-full text-gray-400 hover:text-gray-500" aria-haspopup="listbox" aria-expanded="true" aria-labelledby="listbox-label">
24
+ <span class="flex items-center justify-center">
25
+ <!-- Placeholder label, show/hide based on listbox state. -->
26
+ <span>
27
+ <svg class="h-5 w-5 flex-shrink-0" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
28
+ <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.536-4.464a.75.75 0 10-1.061-1.061 3.5 3.5 0 01-4.95 0 .75.75 0 00-1.06 1.06 5 5 0 007.07 0zM9 8.5c0 .828-.448 1.5-1 1.5s-1-.672-1-1.5S7.448 7 8 7s1 .672 1 1.5zm3 1.5c.552 0 1-.672 1-1.5S12.552 7 12 7s-1 .672-1 1.5.448 1.5 1 1.5z" clip-rule="evenodd" />
29
+ </svg>
30
+ <span class="sr-only">Add your mood</span>
31
+ </span>
32
+ <!-- Selected item label, show/hide based on listbox state. -->
33
+ <span>
34
+ <span class="flex h-8 w-8 items-center justify-center rounded-full bg-red-500">
35
+ <svg class="h-5 w-5 flex-shrink-0 text-white" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
36
+ <path fill-rule="evenodd" d="M13.5 4.938a7 7 0 11-9.006 1.737c.202-.257.59-.218.793.039.278.352.594.672.943.954.332.269.786-.049.773-.476a5.977 5.977 0 01.572-2.759 6.026 6.026 0 012.486-2.665c.247-.14.55-.016.677.238A6.967 6.967 0 0013.5 4.938zM14 12a4 4 0 01-4 4c-1.913 0-3.52-1.398-3.91-3.182-.093-.429.44-.643.814-.413a4.043 4.043 0 001.601.564c.303.038.531-.24.51-.544a5.975 5.975 0 011.315-4.192.447.447 0 01.431-.16A4.001 4.001 0 0114 12z" clip-rule="evenodd" />
37
+ </svg>
38
+ </span>
39
+ <span class="sr-only">Excited</span>
40
+ </span>
41
+ </span>
42
+ </button>
43
+
44
+ <!--
45
+ Select popover, show/hide based on select state.
46
+
47
+ Entering: ""
48
+ From: ""
49
+ To: ""
50
+ Leaving: "transition ease-in duration-100"
51
+ From: "opacity-100"
52
+ To: "opacity-0"
53
+ -->
54
+ <ul class="absolute z-10 -ml-6 mt-1 w-60 rounded-lg bg-white py-3 text-base shadow ring-1 ring-black ring-opacity-5 focus:outline-none sm:ml-auto sm:w-64 sm:text-sm" tabindex="-1" role="listbox" aria-labelledby="listbox-label" aria-activedescendant="listbox-option-5">
55
+ <!--
56
+ Select option, manage highlight styles based on mouseenter/mouseleave and keyboard navigation.
57
+
58
+ Highlighted: "bg-gray-100", Not Highlighted: "bg-white"
59
+ -->
60
+ <li class="bg-white relative cursor-default select-none px-3 py-2" id="listbox-option-0" role="option">
61
+ <div class="flex items-center">
62
+ <div class="bg-red-500 flex h-8 w-8 items-center justify-center rounded-full">
63
+ <svg class="text-white h-5 w-5 flex-shrink-0" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
64
+ <path fill-rule="evenodd" d="M13.5 4.938a7 7 0 11-9.006 1.737c.202-.257.59-.218.793.039.278.352.594.672.943.954.332.269.786-.049.773-.476a5.977 5.977 0 01.572-2.759 6.026 6.026 0 012.486-2.665c.247-.14.55-.016.677.238A6.967 6.967 0 0013.5 4.938zM14 12a4 4 0 01-4 4c-1.913 0-3.52-1.398-3.91-3.182-.093-.429.44-.643.814-.413a4.043 4.043 0 001.601.564c.303.038.531-.24.51-.544a5.975 5.975 0 011.315-4.192.447.447 0 01.431-.16A4.001 4.001 0 0114 12z" clip-rule="evenodd" />
65
+ </svg>
66
+ </div>
67
+ <span class="ml-3 block truncate font-medium">Excited</span>
68
+ </div>
69
+ </li>
70
+ <!--
71
+ Select option, manage highlight styles based on mouseenter/mouseleave and keyboard navigation.
72
+
73
+ Highlighted: "bg-gray-100", Not Highlighted: "bg-white"
74
+ -->
75
+ <li class="bg-white relative cursor-default select-none px-3 py-2" id="listbox-option-1" role="option">
76
+ <div class="flex items-center">
77
+ <div class="bg-pink-400 flex h-8 w-8 items-center justify-center rounded-full">
78
+ <svg class="text-white h-5 w-5 flex-shrink-0" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
79
+ <path d="M9.653 16.915l-.005-.003-.019-.01a20.759 20.759 0 01-1.162-.682 22.045 22.045 0 01-2.582-1.9C4.045 12.733 2 10.352 2 7.5a4.5 4.5 0 018-2.828A4.5 4.5 0 0118 7.5c0 2.852-2.044 5.233-3.885 6.82a22.049 22.049 0 01-3.744 2.582l-.019.01-.005.003h-.002a.739.739 0 01-.69.001l-.002-.001z" />
80
+ </svg>
81
+ </div>
82
+ <span class="ml-3 block truncate font-medium">Loved</span>
83
+ </div>
84
+ </li>
85
+ <!--
86
+ Select option, manage highlight styles based on mouseenter/mouseleave and keyboard navigation.
87
+
88
+ Highlighted: "bg-gray-100", Not Highlighted: "bg-white"
89
+ -->
90
+ <li class="bg-white relative cursor-default select-none px-3 py-2" id="listbox-option-2" role="option">
91
+ <div class="flex items-center">
92
+ <div class="bg-green-400 flex h-8 w-8 items-center justify-center rounded-full">
93
+ <svg class="text-white h-5 w-5 flex-shrink-0" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
94
+ <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.536-4.464a.75.75 0 10-1.061-1.061 3.5 3.5 0 01-4.95 0 .75.75 0 00-1.06 1.06 5 5 0 007.07 0zM9 8.5c0 .828-.448 1.5-1 1.5s-1-.672-1-1.5S7.448 7 8 7s1 .672 1 1.5zm3 1.5c.552 0 1-.672 1-1.5S12.552 7 12 7s-1 .672-1 1.5.448 1.5 1 1.5z" clip-rule="evenodd" />
95
+ </svg>
96
+ </div>
97
+ <span class="ml-3 block truncate font-medium">Happy</span>
98
+ </div>
99
+ </li>
100
+ <!--
101
+ Select option, manage highlight styles based on mouseenter/mouseleave and keyboard navigation.
102
+
103
+ Highlighted: "bg-gray-100", Not Highlighted: "bg-white"
104
+ -->
105
+ <li class="bg-white relative cursor-default select-none px-3 py-2" id="listbox-option-3" role="option">
106
+ <div class="flex items-center">
107
+ <div class="bg-yellow-400 flex h-8 w-8 items-center justify-center rounded-full">
108
+ <svg class="text-white h-5 w-5 flex-shrink-0" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
109
+ <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm-3.536-3.475a.75.75 0 001.061 0 3.5 3.5 0 014.95 0 .75.75 0 101.06-1.06 5 5 0 00-7.07 0 .75.75 0 000 1.06zM9 8.5c0 .828-.448 1.5-1 1.5s-1-.672-1-1.5S7.448 7 8 7s1 .672 1 1.5zm3 1.5c.552 0 1-.672 1-1.5S12.552 7 12 7s-1 .672-1 1.5.448 1.5 1 1.5z" clip-rule="evenodd" />
110
+ </svg>
111
+ </div>
112
+ <span class="ml-3 block truncate font-medium">Sad</span>
113
+ </div>
114
+ </li>
115
+ <!--
116
+ Select option, manage highlight styles based on mouseenter/mouseleave and keyboard navigation.
117
+
118
+ Highlighted: "bg-gray-100", Not Highlighted: "bg-white"
119
+ -->
120
+ <li class="bg-white relative cursor-default select-none px-3 py-2" id="listbox-option-4" role="option">
121
+ <div class="flex items-center">
122
+ <div class="bg-blue-500 flex h-8 w-8 items-center justify-center rounded-full">
123
+ <svg class="text-white h-5 w-5 flex-shrink-0" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
124
+ <path d="M1 8.25a1.25 1.25 0 112.5 0v7.5a1.25 1.25 0 11-2.5 0v-7.5zM11 3V1.7c0-.268.14-.526.395-.607A2 2 0 0114 3c0 .995-.182 1.948-.514 2.826-.204.54.166 1.174.744 1.174h2.52c1.243 0 2.261 1.01 2.146 2.247a23.864 23.864 0 01-1.341 5.974C17.153 16.323 16.072 17 14.9 17h-3.192a3 3 0 01-1.341-.317l-2.734-1.366A3 3 0 006.292 15H5V8h.963c.685 0 1.258-.483 1.612-1.068a4.011 4.011 0 012.166-1.73c.432-.143.853-.386 1.011-.814.16-.432.248-.9.248-1.388z" />
125
+ </svg>
126
+ </div>
127
+ <span class="ml-3 block truncate font-medium">Thumbsy</span>
128
+ </div>
129
+ </li>
130
+ <!--
131
+ Select option, manage highlight styles based on mouseenter/mouseleave and keyboard navigation.
132
+
133
+ Highlighted: "bg-gray-100", Not Highlighted: "bg-white"
134
+ -->
135
+ <li class="bg-white relative cursor-default select-none px-3 py-2" id="listbox-option-5" role="option">
136
+ <div class="flex items-center">
137
+ <div class="bg-transparent flex h-8 w-8 items-center justify-center rounded-full">
138
+ <svg class="text-gray-400 h-5 w-5 flex-shrink-0" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
139
+ <path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" />
140
+ </svg>
141
+ </div>
142
+ <span class="ml-3 block truncate font-medium">I feel nothing</span>
143
+ </div>
144
+ </li>
145
+ </ul>
146
+ </div>
147
+ </div>
148
+ </div>
149
+ </div>
150
+ <button type="submit" class="rounded-md bg-white px-2.5 py-1.5 text-sm font-semibold text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50">Comment</button>
151
+ </div>
152
+ </form>
153
+ </alv-input-comment>
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::Input::CommentComponent < ViewComponent::Base
4
+
5
+ end
@@ -0,0 +1,16 @@
1
+ <alv-input-counter class="block max-w-xs mx-auto">
2
+ <%= f.label @attribute, class: "block mb-2 text-sm font-medium text-gray-900 dark:text-white" %>
3
+ <div class="relative flex items-center max-w-[8rem]">
4
+ <button type="button" id="decrement-button" data-input-counter-decrement="<%= @id %>" class="bg-gray-100 dark:bg-gray-700 dark:hover:bg-gray-600 dark:border-gray-600 hover:bg-gray-200 border border-gray-300 rounded-s-lg p-3 h-11 focus:ring-gray-100 dark:focus:ring-gray-700 focus:ring-2 focus:outline-none">
5
+ <svg class="w-3 h-3 text-gray-900 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 2">
6
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 1h16"/>
7
+ </svg>
8
+ </button>
9
+ <%= f.input_field @attribute, as: :string, id: @id, "data-input-counter": true, "aria-describedby": "helper-text-explanation", placeholder: "999", required: @required, class: "bg-white border-x-0 border-gray-300 h-11 text-center text-gray-900 text-sm focus:ring-blue-500 focus:border-blue-500 block w-full py-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" %>
10
+ <button type="button" id="increment-button" data-input-counter-increment="<%= @id %>" class="bg-gray-100 dark:bg-gray-700 dark:hover:bg-gray-600 dark:border-gray-600 hover:bg-gray-200 border border-gray-300 rounded-e-lg p-3 h-11 focus:ring-gray-100 dark:focus:ring-gray-700 focus:ring-2 focus:outline-none">
11
+ <svg class="w-3 h-3 text-gray-900 dark:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 18">
12
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 1v16M1 9h16"/>
13
+ </svg>
14
+ </button>
15
+ </div>
16
+ </alv-input-counter>
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::Input::CounterComponent < Alveole::Input::BaseComponent
4
+ end
@@ -0,0 +1,17 @@
1
+ <alv-input-email>
2
+ <%= f.label @attribute, class: "block text-sm font-medium leading-6 text-gray-900" %>
3
+ <div class="relative mt-2 rounded-md shadow-sm">
4
+ <% input_color_class = errors? ? "text-red-900 ring-red-300 placeholder:text-red-300 focus:ring-red-500" : "text-gray-900 ring-gray-300 placeholder:text-gray-400 focus:ring-primary-600" %>
5
+ <%= f.input_field @attribute, class: "block w-full rounded-md border-0 py-1.5 shadow-sm ring-1 ring-inset focus:ring-2 focus:ring-inset sm:text-sm sm:leading-6 #{input_color_class}" %>
6
+
7
+ <% if f.object.errors[@attribute].present? %>
8
+ <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
9
+ <%= render(IconComponent.new(:exclamation, class: "h-5 w-5 text-red-500")) %>
10
+ </div>
11
+ <% end %>
12
+ </div>
13
+ <% if @args[:hint] %>
14
+ <p class="mt-2 text-sm text-gray-500" id="email-description"><%= @args[:hint] %></p>
15
+ <% end %>
16
+ <%= f.error @attribute, id: "#{@attribute}_error", class: "mt-2 text-sm text-red-600" %>
17
+ </alv-input-email>
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::Input::EmailComponent < Alveole::Input::BaseComponent
4
+ end
@@ -0,0 +1,4 @@
1
+ <alv-input-file class="block">
2
+ <%= f.label @attribute, class: "block mb-2 text-sm font-medium text-gray-900 dark:text-white" %>
3
+ <%= f.input_field @attribute, as: :file, class: "block w-full text-sm text-gray-900 border border-gray-300 rounded-lg cursor-pointer dark:text-gray-400 focus:outline-none dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400" %>
4
+ </alv-input-file>
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::Input::FileComponent < Alveole::Input::BaseComponent
4
+ end
@@ -0,0 +1,7 @@
1
+ <alv-input-search class="relative flex items-center mt-4 md:mt-0">
2
+ <span class="absolute">
3
+ <%= render(IconComponent.new(:magnifying_glass, class: "w-5 h-5 mx-3 text-gray-400 dark:text-gray-600")) %>
4
+ </span>
5
+
6
+ <input type="text" placeholder="Search" class="block w-full py-1.5 pr-5 text-gray-700 bg-white border border-gray-200 rounded-lg md:w-80 placeholder-gray-400/70 pl-11 rtl:pr-11 rtl:pl-5 dark:bg-gray-900 dark:text-gray-300 dark:border-gray-600 focus:border-blue-400 dark:focus:border-blue-300 focus:ring-blue-300 focus:outline-none focus:ring focus:ring-opacity-40">
7
+ </alv-input-search>
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::Input::SearchComponent < ViewComponent::Base
4
+
5
+ end
@@ -0,0 +1,4 @@
1
+ <alv-input-select>
2
+ <%= f.label @attribute, class: "block mb-2 text-sm font-medium text-gray-900 dark:text-white" %>
3
+ <%= f.input_field @attribute, as: :select, id: @id, required: @required, collection: collection, class: "bg-white border border-gray-300 text-gray-900 text-sm rounded-md focus:ring-primary-500 focus:border-primary-500 block w-full p-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-primary-500 dark:focus:border-primary-500" %>
4
+ </alv-input-select>
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::Input::SelectComponent < Alveole::Input::BaseComponent
4
+ def collection
5
+ [
6
+ ["US", "United States"],
7
+ ["CA", "Canada"],
8
+ ["FR", "France"],
9
+ ["DE", "Germany"]
10
+ ]
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ <alv-input-text>
2
+ <%= f.label @attribute, class: "block text-sm font-medium leading-6 text-gray-900" %>
3
+ <div class="relative mt-2 rounded-md shadow-sm">
4
+ <% input_color_class = errors? ? "text-red-900 ring-red-300 placeholder:text-red-300 focus:ring-red-500" : "text-gray-900 ring-gray-300 placeholder:text-gray-400 focus:ring-primary-600" %>
5
+ <%= f.input_field @attribute, class: "block w-full rounded-md border-0 py-1.5 shadow-sm ring-1 ring-inset focus:ring-2 focus:ring-inset sm:text-sm sm:leading-6 #{input_color_class}" %>
6
+
7
+ <% if errors? %>
8
+ <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
9
+ <%= render(IconComponent.new(:exclamation, class: "h-5 w-5 text-red-500")) %>
10
+ </div>
11
+ <% end %>
12
+ </div>
13
+ <% if @args[:hint] %>
14
+ <p class="mt-2 text-sm text-gray-500" id="email-description"><%= @args[:hint] %></p>
15
+ <% end %>
16
+ <%= f.error @attribute, id: "#{@attribute}_error", class: "mt-2 text-sm text-red-600" %>
17
+ </alv-input-text>
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::Input::TextComponent < Alveole::Input::BaseComponent
4
+ end
@@ -0,0 +1,16 @@
1
+ <alv-input-textarea>
2
+ <%= f.label @attribute, class: "block text-sm font-medium leading-6 text-gray-900" %>
3
+ <div class="relative mt-2">
4
+ <%= f.input_field @attribute, as: :text, rows: 3, class: "block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-primary-600 sm:text-sm sm:leading-6" %>
5
+
6
+ <% if f.object.errors[@attribute].present? %>
7
+ <div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
8
+ <%= render(IconComponent.new(:exclamation, class: "h-5 w-5 text-red-500")) %>
9
+ </div>
10
+ <% end %>
11
+ </div>
12
+ <% if @args[:hint] %>
13
+ <p class="mt-2 text-sm text-gray-500" id="email-description"><%= @args[:hint] %></p>
14
+ <% end %>
15
+ <%= f.error @attribute, id: "#{@attribute}_error", class: "mt-2 text-sm text-red-600" %>
16
+ </alv-input-textarea>
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::Input::TextareaComponent < Alveole::Input::BaseComponent
4
+ end
@@ -0,0 +1,107 @@
1
+ <alv-mega-menu class="bg-white border-gray-200 dark:bg-gray-900">
2
+ <div class="flex flex-wrap items-center justify-between max-w-screen-xl mx-auto p-4">
3
+ <a href="https://flowbite.com" class="flex items-center space-x-3 rtl:space-x-reverse">
4
+ <%= logo %>
5
+ </a>
6
+ <div class="flex items-center md:order-2 space-x-1 md:space-x-2 rtl:space-x-reverse">
7
+ <% actions.each do |a| %>
8
+ <%= a %>
9
+ <% end %>
10
+ <button data-collapse-toggle="mega-menu" type="button" class="inline-flex items-center p-2 w-10 h-10 justify-center text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600" aria-controls="mega-menu" aria-expanded="false">
11
+ <span class="sr-only">Open main menu</span>
12
+ <svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 17 14">
13
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M1 1h15M1 7h15M1 13h15"/>
14
+ </svg>
15
+ </button>
16
+ </div>
17
+ <div id="mega-menu" class="items-center justify-between hidden w-full md:flex md:w-auto md:order-1">
18
+ <ul class="flex flex-col mt-4 font-medium md:flex-row md:mt-0 md:space-x-8 rtl:space-x-reverse">
19
+ <li>
20
+ <a href="#" class="block py-2 px-3 text-primary-600 border-b border-gray-100 hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-primary-600 md:p-0 dark:text-primary-500 md:dark:hover:text-primary-500 dark:hover:bg-gray-700 dark:hover:text-primary-500 md:dark:hover:bg-transparent dark:border-gray-700" aria-current="page">Home</a>
21
+ </li>
22
+ <li>
23
+ <button id="mega-menu-dropdown-button" data-dropdown-toggle="mega-menu-dropdown" class="flex items-center justify-between w-full py-2 px-3 font-medium text-gray-900 border-b border-gray-100 md:w-auto hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-primary-600 md:p-0 dark:text-white md:dark:hover:text-primary-500 dark:hover:bg-gray-700 dark:hover:text-primary-500 md:dark:hover:bg-transparent dark:border-gray-700">
24
+ Company <svg class="w-2.5 h-2.5 ms-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
25
+ <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4"/>
26
+ </svg>
27
+ </button>
28
+ <div id="mega-menu-dropdown" class="absolute z-10 grid hidden w-auto grid-cols-2 text-sm bg-white border border-gray-100 rounded-lg shadow-md dark:border-gray-700 md:grid-cols-3 dark:bg-gray-700">
29
+ <div class="p-4 pb-0 text-gray-900 md:pb-4 dark:text-white">
30
+ <ul class="space-y-4" aria-labelledby="mega-menu-dropdown-button">
31
+ <li>
32
+ <a href="#" class="text-gray-500 dark:text-gray-400 hover:text-primary-600 dark:hover:text-primary-500">
33
+ About Us
34
+ </a>
35
+ </li>
36
+ <li>
37
+ <a href="#" class="text-gray-500 dark:text-gray-400 hover:text-primary-600 dark:hover:text-primary-500">
38
+ Library
39
+ </a>
40
+ </li>
41
+ <li>
42
+ <a href="#" class="text-gray-500 dark:text-gray-400 hover:text-primary-600 dark:hover:text-primary-500">
43
+ Resources
44
+ </a>
45
+ </li>
46
+ <li>
47
+ <a href="#" class="text-gray-500 dark:text-gray-400 hover:text-primary-600 dark:hover:text-primary-500">
48
+ Pro Version
49
+ </a>
50
+ </li>
51
+ </ul>
52
+ </div>
53
+ <div class="p-4 pb-0 text-gray-900 md:pb-4 dark:text-white">
54
+ <ul class="space-y-4">
55
+ <li>
56
+ <a href="#" class="text-gray-500 dark:text-gray-400 hover:text-primary-600 dark:hover:text-primary-500">
57
+ Blog
58
+ </a>
59
+ </li>
60
+ <li>
61
+ <a href="#" class="text-gray-500 dark:text-gray-400 hover:text-primary-600 dark:hover:text-primary-500">
62
+ Newsletter
63
+ </a>
64
+ </li>
65
+ <li>
66
+ <a href="#" class="text-gray-500 dark:text-gray-400 hover:text-primary-600 dark:hover:text-primary-500">
67
+ Playground
68
+ </a>
69
+ </li>
70
+ <li>
71
+ <a href="#" class="text-gray-500 dark:text-gray-400 hover:text-primary-600 dark:hover:text-primary-500">
72
+ License
73
+ </a>
74
+ </li>
75
+ </ul>
76
+ </div>
77
+ <div class="p-4">
78
+ <ul class="space-y-4">
79
+ <li>
80
+ <a href="#" class="text-gray-500 dark:text-gray-400 hover:text-primary-600 dark:hover:text-primary-500">
81
+ Contact Us
82
+ </a>
83
+ </li>
84
+ <li>
85
+ <a href="#" class="text-gray-500 dark:text-gray-400 hover:text-primary-600 dark:hover:text-primary-500">
86
+ Support Center
87
+ </a>
88
+ </li>
89
+ <li>
90
+ <a href="#" class="text-gray-500 dark:text-gray-400 hover:text-primary-600 dark:hover:text-primary-500">
91
+ Terms
92
+ </a>
93
+ </li>
94
+ </ul>
95
+ </div>
96
+ </div>
97
+ </li>
98
+ <li>
99
+ <a href="#" class="block py-2 px-3 text-gray-900 border-b border-gray-100 hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-primary-600 md:p-0 dark:text-white md:dark:hover:text-primary-500 dark:hover:bg-gray-700 dark:hover:text-primary-500 md:dark:hover:bg-transparent dark:border-gray-700">Team</a>
100
+ </li>
101
+ <li>
102
+ <a href="#" class="block py-2 px-3 text-gray-900 border-b border-gray-100 hover:bg-gray-50 md:hover:bg-transparent md:border-0 md:hover:text-primary-600 md:p-0 dark:text-white md:dark:hover:text-primary-500 dark:hover:bg-gray-700 dark:hover:text-primary-500 md:dark:hover:bg-transparent dark:border-gray-700">Contact</a>
103
+ </li>
104
+ </ul>
105
+ </div>
106
+ </div>
107
+ </alv-mega-menu>
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::MegaMenuComponent < ViewComponent::Base
4
+ renders_one :logo
5
+ renders_many :actions
6
+ end
@@ -0,0 +1,5 @@
1
+ <alv-sidebar-divider class="relative">
2
+ <div class="absolute inset-0 flex items-center" aria-hidden="true">
3
+ <div class="w-full border-t border-gray-300"></div>
4
+ </div>
5
+ </alv-sidebar-divider>
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::Sidebar::DividerComponent < ViewComponent::Base
4
+
5
+ end
@@ -0,0 +1,7 @@
1
+ <alv-sidebar-group class="block space-y-3 ">
2
+ <label class="px-3 text-xs text-gray-500 uppercase dark:text-gray-400"><%= @title%></label>
3
+
4
+ <% items.each do |item| %>
5
+ <%= item %>
6
+ <% end %>
7
+ </alv-sidebar-group>
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::Sidebar::GroupComponent < ViewComponent::Base
4
+
5
+ renders_many :items, types: {
6
+ item: {
7
+ renders: lambda { |**system_arguments, &block|
8
+ Alveole::Sidebar::ItemComponent.new(
9
+ **system_arguments,
10
+ &block
11
+ )
12
+ },
13
+
14
+ as: :item
15
+ },
16
+
17
+ divider: {
18
+ renders: Alveole::Sidebar::DividerComponent,
19
+ as: :divider
20
+ },
21
+
22
+ group: {
23
+ renders: lambda { |**system_arguments, &block|
24
+ Alveole::Sidebar::GroupComponent.new(
25
+ **system_arguments,
26
+ &block
27
+ )
28
+ },
29
+
30
+ as: :group
31
+ }
32
+ }
33
+
34
+ def initialize(title:)
35
+ @title = title
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ <alv-sidebar-heading class="flex h-16 shrink-0 items-center mb-6">
2
+ <%= content %>
3
+ </alv-sidebar-heading>
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::Sidebar::HeadingComponent < ViewComponent::Base
4
+ def initialize(title: nil, image: nil)
5
+ @title = title
6
+ @image = image
7
+ end
8
+ end
@@ -0,0 +1,14 @@
1
+ <alv-sidebar-item class="block">
2
+ <% class_if_active = @current ? "bg-gray-50 text-primary-600" : "text-gray-600 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-800 dark:hover:text-gray-200 hover:text-gray-700" %>
3
+ <%= link_to @href, class: "#{class_if_active} flex items-center px-3 py-2 transition-colors duration-300 transform rounded-lg" do %>
4
+ <% if content.present? %>
5
+ <%= content %>
6
+ <% else %>
7
+ <% if @icon %>
8
+ <%= render(IconComponent.new(@icon, class: "w-5 h-5")) %>
9
+ <% end %>
10
+
11
+ <span class="mx-2 text-sm font-medium"><%= @title %></span>
12
+ <% end %>
13
+ <% end %>
14
+ </alv-sidebar-item>
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::Sidebar::ItemComponent < ViewComponent::Base
4
+ def initialize(title:, icon: nil, href:, active: false)
5
+ @title = title
6
+ @icon = icon
7
+ @href = href
8
+ @active = active
9
+ @current = @active
10
+ end
11
+
12
+ def before_render
13
+ if @active == false
14
+ @current = request.path == @href
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ <alv-sidebar class="flex flex-col w-64 h-screen px-5 py-8 overflow-y-auto bg-white border-r rtl:border-r-0 rtl:border-l dark:bg-gray-900 dark:border-gray-700">
2
+ <%= heading %>
3
+
4
+ <div class="flex flex-col justify-between flex-1">
5
+ <nav class="-mx-3 space-y-6 ">
6
+ <div class="space-y-3 ">
7
+ <% items.each do |item| %>
8
+ <%= item %>
9
+ <% end %>
10
+ </div>
11
+ </nav>
12
+ </div>
13
+ </alv-sidebar>
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Alveole::SidebarComponent < ViewComponent::Base
4
+ renders_one :heading, Alveole::Sidebar::HeadingComponent
5
+
6
+ renders_many :items, types: {
7
+ item: {
8
+ renders: lambda { |**system_arguments, &block|
9
+ Alveole::Sidebar::ItemComponent.new(
10
+ **system_arguments,
11
+ &block
12
+ )
13
+ },
14
+
15
+ as: :item
16
+ },
17
+
18
+ divider: {
19
+ renders: Alveole::Sidebar::DividerComponent,
20
+ as: :divider
21
+ },
22
+
23
+ group: {
24
+ renders: lambda { |**system_arguments, &block|
25
+ Alveole::Sidebar::GroupComponent.new(
26
+ **system_arguments,
27
+ &block
28
+ )
29
+ },
30
+
31
+ as: :group
32
+ }
33
+ }
34
+
35
+
36
+ def initialize(logo: nil, logo_url: nil)
37
+ @logo = logo
38
+ @logo_url = logo_url
39
+ end
40
+ end
@@ -0,0 +1,4 @@
1
+ module Alveole
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Alveole
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Alveole
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module Alveole
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: "from@example.com"
4
+ layout "mailer"
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Alveole
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end