uikit_rails 0.1.0

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.

Potentially problematic release.


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

Files changed (368) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +259 -0
  3. data/Rakefile +12 -0
  4. data/app/controllers/uikit_rails/styleguide_controller.rb +72 -0
  5. data/app/views/layouts/uikit_rails/application.html.erb +412 -0
  6. data/app/views/uikit_rails/styleguide/index.html.erb +27 -0
  7. data/app/views/uikit_rails/styleguide/show.html.erb +56 -0
  8. data/config/routes.rb +6 -0
  9. data/lib/uikit_rails/engine.rb +13 -0
  10. data/lib/uikit_rails/generators/add_generator.rb +110 -0
  11. data/lib/uikit_rails/generators/install_generator.rb +62 -0
  12. data/lib/uikit_rails/generators/templates/base_component.rb.tt +32 -0
  13. data/lib/uikit_rails/generators/templates/uikit_rails.css.tt +69 -0
  14. data/lib/uikit_rails/templates/components/accordion/USAGE +30 -0
  15. data/lib/uikit_rails/templates/components/accordion/accordion.css +74 -0
  16. data/lib/uikit_rails/templates/components/accordion/component.html.erb +13 -0
  17. data/lib/uikit_rails/templates/components/accordion/component.rb +35 -0
  18. data/lib/uikit_rails/templates/components/accordion/preview.yml +81 -0
  19. data/lib/uikit_rails/templates/components/alert/USAGE +25 -0
  20. data/lib/uikit_rails/templates/components/alert/alert.css +60 -0
  21. data/lib/uikit_rails/templates/components/alert/component.html.erb +9 -0
  22. data/lib/uikit_rails/templates/components/alert/component.rb +27 -0
  23. data/lib/uikit_rails/templates/components/alert/preview.yml +53 -0
  24. data/lib/uikit_rails/templates/components/alert_dialog/USAGE +38 -0
  25. data/lib/uikit_rails/templates/components/alert_dialog/alert_dialog.css +108 -0
  26. data/lib/uikit_rails/templates/components/alert_dialog/component.html.erb +27 -0
  27. data/lib/uikit_rails/templates/components/alert_dialog/component.rb +23 -0
  28. data/lib/uikit_rails/templates/components/alert_dialog/preview.yml +94 -0
  29. data/lib/uikit_rails/templates/components/avatar/USAGE +20 -0
  30. data/lib/uikit_rails/templates/components/avatar/avatar.css +53 -0
  31. data/lib/uikit_rails/templates/components/avatar/component.html.erb +7 -0
  32. data/lib/uikit_rails/templates/components/avatar/component.rb +31 -0
  33. data/lib/uikit_rails/templates/components/avatar/preview.yml +42 -0
  34. data/lib/uikit_rails/templates/components/badge/USAGE +13 -0
  35. data/lib/uikit_rails/templates/components/badge/badge.css +61 -0
  36. data/lib/uikit_rails/templates/components/badge/component.rb +28 -0
  37. data/lib/uikit_rails/templates/components/badge/preview.yml +38 -0
  38. data/lib/uikit_rails/templates/components/breadcrumb/USAGE +23 -0
  39. data/lib/uikit_rails/templates/components/breadcrumb/breadcrumb.css +55 -0
  40. data/lib/uikit_rails/templates/components/breadcrumb/component.html.erb +14 -0
  41. data/lib/uikit_rails/templates/components/breadcrumb/component.rb +40 -0
  42. data/lib/uikit_rails/templates/components/breadcrumb/preview.yml +42 -0
  43. data/lib/uikit_rails/templates/components/button/USAGE +21 -0
  44. data/lib/uikit_rails/templates/components/button/button.css +125 -0
  45. data/lib/uikit_rails/templates/components/button/component.rb +44 -0
  46. data/lib/uikit_rails/templates/components/button/preview.yml +106 -0
  47. data/lib/uikit_rails/templates/components/card/USAGE +33 -0
  48. data/lib/uikit_rails/templates/components/card/card.css +63 -0
  49. data/lib/uikit_rails/templates/components/card/component.html.erb +16 -0
  50. data/lib/uikit_rails/templates/components/card/component.rb +26 -0
  51. data/lib/uikit_rails/templates/components/card/preview.yml +57 -0
  52. data/lib/uikit_rails/templates/components/checkbox/USAGE +19 -0
  53. data/lib/uikit_rails/templates/components/checkbox/checkbox.css +67 -0
  54. data/lib/uikit_rails/templates/components/checkbox/component.html.erb +6 -0
  55. data/lib/uikit_rails/templates/components/checkbox/component.rb +26 -0
  56. data/lib/uikit_rails/templates/components/checkbox/preview.yml +43 -0
  57. data/lib/uikit_rails/templates/components/collapsible/USAGE +31 -0
  58. data/lib/uikit_rails/templates/components/collapsible/collapsible.css +55 -0
  59. data/lib/uikit_rails/templates/components/collapsible/component.html.erb +8 -0
  60. data/lib/uikit_rails/templates/components/collapsible/component.rb +18 -0
  61. data/lib/uikit_rails/templates/components/collapsible/preview.yml +65 -0
  62. data/lib/uikit_rails/templates/components/dialog/USAGE +41 -0
  63. data/lib/uikit_rails/templates/components/dialog/component.html.erb +23 -0
  64. data/lib/uikit_rails/templates/components/dialog/component.rb +20 -0
  65. data/lib/uikit_rails/templates/components/dialog/dialog.css +133 -0
  66. data/lib/uikit_rails/templates/components/dialog/preview.yml +77 -0
  67. data/lib/uikit_rails/templates/components/dropdown/USAGE +40 -0
  68. data/lib/uikit_rails/templates/components/dropdown/component.html.erb +14 -0
  69. data/lib/uikit_rails/templates/components/dropdown/component.rb +62 -0
  70. data/lib/uikit_rails/templates/components/dropdown/dropdown.css +104 -0
  71. data/lib/uikit_rails/templates/components/dropdown/preview.yml +75 -0
  72. data/lib/uikit_rails/templates/components/input/USAGE +21 -0
  73. data/lib/uikit_rails/templates/components/input/component.rb +25 -0
  74. data/lib/uikit_rails/templates/components/input/input.css +43 -0
  75. data/lib/uikit_rails/templates/components/input/preview.yml +58 -0
  76. data/lib/uikit_rails/templates/components/label/USAGE +16 -0
  77. data/lib/uikit_rails/templates/components/label/component.rb +25 -0
  78. data/lib/uikit_rails/templates/components/label/label.css +25 -0
  79. data/lib/uikit_rails/templates/components/label/preview.yml +34 -0
  80. data/lib/uikit_rails/templates/components/pagination/USAGE +45 -0
  81. data/lib/uikit_rails/templates/components/pagination/component.html.erb +7 -0
  82. data/lib/uikit_rails/templates/components/pagination/component.rb +90 -0
  83. data/lib/uikit_rails/templates/components/pagination/pagination.css +89 -0
  84. data/lib/uikit_rails/templates/components/pagination/preview.yml +61 -0
  85. data/lib/uikit_rails/templates/components/popover/USAGE +44 -0
  86. data/lib/uikit_rails/templates/components/popover/component.html.erb +8 -0
  87. data/lib/uikit_rails/templates/components/popover/component.rb +19 -0
  88. data/lib/uikit_rails/templates/components/popover/popover.css +94 -0
  89. data/lib/uikit_rails/templates/components/popover/preview.yml +102 -0
  90. data/lib/uikit_rails/templates/components/progress/USAGE +15 -0
  91. data/lib/uikit_rails/templates/components/progress/component.html.erb +3 -0
  92. data/lib/uikit_rails/templates/components/progress/component.rb +38 -0
  93. data/lib/uikit_rails/templates/components/progress/preview.yml +44 -0
  94. data/lib/uikit_rails/templates/components/progress/progress.css +20 -0
  95. data/lib/uikit_rails/templates/components/select/USAGE +19 -0
  96. data/lib/uikit_rails/templates/components/select/component.rb +38 -0
  97. data/lib/uikit_rails/templates/components/select/preview.yml +61 -0
  98. data/lib/uikit_rails/templates/components/select/select.css +46 -0
  99. data/lib/uikit_rails/templates/components/separator/USAGE +15 -0
  100. data/lib/uikit_rails/templates/components/separator/component.rb +34 -0
  101. data/lib/uikit_rails/templates/components/separator/preview.yml +32 -0
  102. data/lib/uikit_rails/templates/components/separator/separator.css +21 -0
  103. data/lib/uikit_rails/templates/components/sheet/USAGE +44 -0
  104. data/lib/uikit_rails/templates/components/sheet/component.html.erb +23 -0
  105. data/lib/uikit_rails/templates/components/sheet/component.rb +23 -0
  106. data/lib/uikit_rails/templates/components/sheet/preview.yml +105 -0
  107. data/lib/uikit_rails/templates/components/sheet/sheet.css +193 -0
  108. data/lib/uikit_rails/templates/components/skeleton/USAGE +19 -0
  109. data/lib/uikit_rails/templates/components/skeleton/component.rb +38 -0
  110. data/lib/uikit_rails/templates/components/skeleton/preview.yml +44 -0
  111. data/lib/uikit_rails/templates/components/skeleton/skeleton.css +25 -0
  112. data/lib/uikit_rails/templates/components/switch/USAGE +19 -0
  113. data/lib/uikit_rails/templates/components/switch/component.html.erb +19 -0
  114. data/lib/uikit_rails/templates/components/switch/component.rb +23 -0
  115. data/lib/uikit_rails/templates/components/switch/preview.yml +43 -0
  116. data/lib/uikit_rails/templates/components/switch/switch.css +81 -0
  117. data/lib/uikit_rails/templates/components/table/USAGE +40 -0
  118. data/lib/uikit_rails/templates/components/table/component.html.erb +14 -0
  119. data/lib/uikit_rails/templates/components/table/component.rb +25 -0
  120. data/lib/uikit_rails/templates/components/table/preview.yml +109 -0
  121. data/lib/uikit_rails/templates/components/table/table.css +86 -0
  122. data/lib/uikit_rails/templates/components/tabs/USAGE +24 -0
  123. data/lib/uikit_rails/templates/components/tabs/component.html.erb +10 -0
  124. data/lib/uikit_rails/templates/components/tabs/component.rb +35 -0
  125. data/lib/uikit_rails/templates/components/tabs/preview.yml +60 -0
  126. data/lib/uikit_rails/templates/components/tabs/tabs.css +72 -0
  127. data/lib/uikit_rails/templates/components/textarea/USAGE +19 -0
  128. data/lib/uikit_rails/templates/components/textarea/component.rb +25 -0
  129. data/lib/uikit_rails/templates/components/textarea/preview.yml +47 -0
  130. data/lib/uikit_rails/templates/components/textarea/textarea.css +39 -0
  131. data/lib/uikit_rails/templates/components/toggle/USAGE +25 -0
  132. data/lib/uikit_rails/templates/components/toggle/component.rb +39 -0
  133. data/lib/uikit_rails/templates/components/toggle/preview.yml +81 -0
  134. data/lib/uikit_rails/templates/components/toggle/toggle.css +89 -0
  135. data/lib/uikit_rails/templates/components/tooltip/USAGE +23 -0
  136. data/lib/uikit_rails/templates/components/tooltip/component.html.erb +8 -0
  137. data/lib/uikit_rails/templates/components/tooltip/component.rb +19 -0
  138. data/lib/uikit_rails/templates/components/tooltip/preview.yml +52 -0
  139. data/lib/uikit_rails/templates/components/tooltip/tooltip.css +78 -0
  140. data/lib/uikit_rails/templates/stimulus/accordion_controller.js +19 -0
  141. data/lib/uikit_rails/templates/stimulus/alert_dialog_controller.js +25 -0
  142. data/lib/uikit_rails/templates/stimulus/collapsible_controller.js +9 -0
  143. data/lib/uikit_rails/templates/stimulus/dialog_controller.js +19 -0
  144. data/lib/uikit_rails/templates/stimulus/dropdown_controller.js +47 -0
  145. data/lib/uikit_rails/templates/stimulus/popover_controller.js +47 -0
  146. data/lib/uikit_rails/templates/stimulus/sheet_controller.js +19 -0
  147. data/lib/uikit_rails/templates/stimulus/tabs_controller.js +24 -0
  148. data/lib/uikit_rails/templates/stimulus/tooltip_controller.js +13 -0
  149. data/lib/uikit_rails/version.rb +5 -0
  150. data/lib/uikit_rails.rb +58 -0
  151. data/sig/uikit_rails.rbs +4 -0
  152. data/test_app/.dockerignore +51 -0
  153. data/test_app/.gitattributes +9 -0
  154. data/test_app/.github/dependabot.yml +12 -0
  155. data/test_app/.github/workflows/ci.yml +124 -0
  156. data/test_app/.gitignore +35 -0
  157. data/test_app/.kamal/hooks/docker-setup.sample +3 -0
  158. data/test_app/.kamal/hooks/post-app-boot.sample +3 -0
  159. data/test_app/.kamal/hooks/post-deploy.sample +14 -0
  160. data/test_app/.kamal/hooks/post-proxy-reboot.sample +3 -0
  161. data/test_app/.kamal/hooks/pre-app-boot.sample +3 -0
  162. data/test_app/.kamal/hooks/pre-build.sample +51 -0
  163. data/test_app/.kamal/hooks/pre-connect.sample +47 -0
  164. data/test_app/.kamal/hooks/pre-deploy.sample +122 -0
  165. data/test_app/.kamal/hooks/pre-proxy-reboot.sample +3 -0
  166. data/test_app/.kamal/secrets +20 -0
  167. data/test_app/.rubocop.yml +8 -0
  168. data/test_app/.ruby-version +1 -0
  169. data/test_app/Dockerfile +77 -0
  170. data/test_app/Gemfile +68 -0
  171. data/test_app/Gemfile.lock +587 -0
  172. data/test_app/README.md +24 -0
  173. data/test_app/Rakefile +6 -0
  174. data/test_app/app/assets/images/.keep +0 -0
  175. data/test_app/app/assets/stylesheets/application.css +10 -0
  176. data/test_app/app/assets/stylesheets/ui/accordion.css +74 -0
  177. data/test_app/app/assets/stylesheets/ui/alert.css +60 -0
  178. data/test_app/app/assets/stylesheets/ui/alert_dialog.css +108 -0
  179. data/test_app/app/assets/stylesheets/ui/avatar.css +53 -0
  180. data/test_app/app/assets/stylesheets/ui/badge.css +61 -0
  181. data/test_app/app/assets/stylesheets/ui/breadcrumb.css +55 -0
  182. data/test_app/app/assets/stylesheets/ui/button.css +125 -0
  183. data/test_app/app/assets/stylesheets/ui/card.css +63 -0
  184. data/test_app/app/assets/stylesheets/ui/checkbox.css +67 -0
  185. data/test_app/app/assets/stylesheets/ui/collapsible.css +55 -0
  186. data/test_app/app/assets/stylesheets/ui/dialog.css +133 -0
  187. data/test_app/app/assets/stylesheets/ui/dropdown.css +104 -0
  188. data/test_app/app/assets/stylesheets/ui/input.css +43 -0
  189. data/test_app/app/assets/stylesheets/ui/label.css +25 -0
  190. data/test_app/app/assets/stylesheets/ui/pagination.css +89 -0
  191. data/test_app/app/assets/stylesheets/ui/popover.css +94 -0
  192. data/test_app/app/assets/stylesheets/ui/progress.css +20 -0
  193. data/test_app/app/assets/stylesheets/ui/select.css +46 -0
  194. data/test_app/app/assets/stylesheets/ui/separator.css +21 -0
  195. data/test_app/app/assets/stylesheets/ui/sheet.css +193 -0
  196. data/test_app/app/assets/stylesheets/ui/skeleton.css +25 -0
  197. data/test_app/app/assets/stylesheets/ui/switch.css +81 -0
  198. data/test_app/app/assets/stylesheets/ui/table.css +86 -0
  199. data/test_app/app/assets/stylesheets/ui/tabs.css +72 -0
  200. data/test_app/app/assets/stylesheets/ui/textarea.css +39 -0
  201. data/test_app/app/assets/stylesheets/ui/toggle.css +89 -0
  202. data/test_app/app/assets/stylesheets/ui/tooltip.css +78 -0
  203. data/test_app/app/assets/stylesheets/uikit_rails.css +69 -0
  204. data/test_app/app/components/ui/accordion/component.html.erb +13 -0
  205. data/test_app/app/components/ui/accordion/component.rb +35 -0
  206. data/test_app/app/components/ui/accordion/preview.yml +81 -0
  207. data/test_app/app/components/ui/alert/component.html.erb +9 -0
  208. data/test_app/app/components/ui/alert/component.rb +27 -0
  209. data/test_app/app/components/ui/alert/preview.yml +53 -0
  210. data/test_app/app/components/ui/alert_dialog/component.html.erb +27 -0
  211. data/test_app/app/components/ui/alert_dialog/component.rb +23 -0
  212. data/test_app/app/components/ui/alert_dialog/preview.yml +94 -0
  213. data/test_app/app/components/ui/avatar/component.html.erb +7 -0
  214. data/test_app/app/components/ui/avatar/component.rb +31 -0
  215. data/test_app/app/components/ui/avatar/preview.yml +42 -0
  216. data/test_app/app/components/ui/badge/component.rb +28 -0
  217. data/test_app/app/components/ui/badge/preview.yml +38 -0
  218. data/test_app/app/components/ui/base_component.rb +32 -0
  219. data/test_app/app/components/ui/breadcrumb/component.html.erb +14 -0
  220. data/test_app/app/components/ui/breadcrumb/component.rb +40 -0
  221. data/test_app/app/components/ui/breadcrumb/preview.yml +42 -0
  222. data/test_app/app/components/ui/button/component.rb +44 -0
  223. data/test_app/app/components/ui/button/preview.yml +106 -0
  224. data/test_app/app/components/ui/card/component.html.erb +16 -0
  225. data/test_app/app/components/ui/card/component.rb +26 -0
  226. data/test_app/app/components/ui/card/preview.yml +57 -0
  227. data/test_app/app/components/ui/checkbox/component.html.erb +6 -0
  228. data/test_app/app/components/ui/checkbox/component.rb +26 -0
  229. data/test_app/app/components/ui/checkbox/preview.yml +43 -0
  230. data/test_app/app/components/ui/collapsible/component.html.erb +8 -0
  231. data/test_app/app/components/ui/collapsible/component.rb +18 -0
  232. data/test_app/app/components/ui/collapsible/preview.yml +65 -0
  233. data/test_app/app/components/ui/dialog/component.html.erb +23 -0
  234. data/test_app/app/components/ui/dialog/component.rb +20 -0
  235. data/test_app/app/components/ui/dialog/preview.yml +77 -0
  236. data/test_app/app/components/ui/dropdown/component.html.erb +14 -0
  237. data/test_app/app/components/ui/dropdown/component.rb +62 -0
  238. data/test_app/app/components/ui/dropdown/preview.yml +75 -0
  239. data/test_app/app/components/ui/input/component.rb +25 -0
  240. data/test_app/app/components/ui/input/preview.yml +58 -0
  241. data/test_app/app/components/ui/label/component.rb +25 -0
  242. data/test_app/app/components/ui/label/preview.yml +34 -0
  243. data/test_app/app/components/ui/pagination/component.html.erb +7 -0
  244. data/test_app/app/components/ui/pagination/component.rb +90 -0
  245. data/test_app/app/components/ui/pagination/preview.yml +61 -0
  246. data/test_app/app/components/ui/popover/component.html.erb +8 -0
  247. data/test_app/app/components/ui/popover/component.rb +19 -0
  248. data/test_app/app/components/ui/popover/preview.yml +102 -0
  249. data/test_app/app/components/ui/progress/component.html.erb +3 -0
  250. data/test_app/app/components/ui/progress/component.rb +38 -0
  251. data/test_app/app/components/ui/progress/preview.yml +44 -0
  252. data/test_app/app/components/ui/select/component.rb +38 -0
  253. data/test_app/app/components/ui/select/preview.yml +61 -0
  254. data/test_app/app/components/ui/separator/component.rb +34 -0
  255. data/test_app/app/components/ui/separator/preview.yml +32 -0
  256. data/test_app/app/components/ui/sheet/component.html.erb +23 -0
  257. data/test_app/app/components/ui/sheet/component.rb +23 -0
  258. data/test_app/app/components/ui/sheet/preview.yml +105 -0
  259. data/test_app/app/components/ui/skeleton/component.rb +38 -0
  260. data/test_app/app/components/ui/skeleton/preview.yml +44 -0
  261. data/test_app/app/components/ui/switch/component.html.erb +19 -0
  262. data/test_app/app/components/ui/switch/component.rb +23 -0
  263. data/test_app/app/components/ui/switch/preview.yml +43 -0
  264. data/test_app/app/components/ui/table/component.html.erb +14 -0
  265. data/test_app/app/components/ui/table/component.rb +25 -0
  266. data/test_app/app/components/ui/table/preview.yml +109 -0
  267. data/test_app/app/components/ui/tabs/component.html.erb +10 -0
  268. data/test_app/app/components/ui/tabs/component.rb +35 -0
  269. data/test_app/app/components/ui/tabs/preview.yml +60 -0
  270. data/test_app/app/components/ui/textarea/component.rb +25 -0
  271. data/test_app/app/components/ui/textarea/preview.yml +47 -0
  272. data/test_app/app/components/ui/toggle/component.rb +39 -0
  273. data/test_app/app/components/ui/toggle/preview.yml +81 -0
  274. data/test_app/app/components/ui/tooltip/component.html.erb +8 -0
  275. data/test_app/app/components/ui/tooltip/component.rb +19 -0
  276. data/test_app/app/components/ui/tooltip/preview.yml +52 -0
  277. data/test_app/app/controllers/application_controller.rb +7 -0
  278. data/test_app/app/controllers/concerns/.keep +0 -0
  279. data/test_app/app/helpers/application_helper.rb +2 -0
  280. data/test_app/app/javascript/application.js +3 -0
  281. data/test_app/app/javascript/controllers/application.js +9 -0
  282. data/test_app/app/javascript/controllers/hello_controller.js +7 -0
  283. data/test_app/app/javascript/controllers/index.js +4 -0
  284. data/test_app/app/javascript/controllers/ui/accordion_controller.js +19 -0
  285. data/test_app/app/javascript/controllers/ui/alert_dialog_controller.js +25 -0
  286. data/test_app/app/javascript/controllers/ui/collapsible_controller.js +9 -0
  287. data/test_app/app/javascript/controllers/ui/dialog_controller.js +19 -0
  288. data/test_app/app/javascript/controllers/ui/dropdown_controller.js +47 -0
  289. data/test_app/app/javascript/controllers/ui/popover_controller.js +47 -0
  290. data/test_app/app/javascript/controllers/ui/sheet_controller.js +19 -0
  291. data/test_app/app/javascript/controllers/ui/tabs_controller.js +24 -0
  292. data/test_app/app/javascript/controllers/ui/tooltip_controller.js +13 -0
  293. data/test_app/app/jobs/application_job.rb +7 -0
  294. data/test_app/app/mailers/application_mailer.rb +4 -0
  295. data/test_app/app/models/application_record.rb +3 -0
  296. data/test_app/app/models/concerns/.keep +0 -0
  297. data/test_app/app/views/layouts/application.html.erb +29 -0
  298. data/test_app/app/views/layouts/mailer.html.erb +13 -0
  299. data/test_app/app/views/layouts/mailer.text.erb +1 -0
  300. data/test_app/app/views/pwa/manifest.json.erb +22 -0
  301. data/test_app/app/views/pwa/service-worker.js +26 -0
  302. data/test_app/bin/brakeman +7 -0
  303. data/test_app/bin/bundler-audit +6 -0
  304. data/test_app/bin/ci +6 -0
  305. data/test_app/bin/dev +2 -0
  306. data/test_app/bin/docker-entrypoint +8 -0
  307. data/test_app/bin/importmap +4 -0
  308. data/test_app/bin/jobs +6 -0
  309. data/test_app/bin/kamal +16 -0
  310. data/test_app/bin/rails +4 -0
  311. data/test_app/bin/rake +4 -0
  312. data/test_app/bin/rubocop +8 -0
  313. data/test_app/bin/setup +35 -0
  314. data/test_app/bin/thrust +5 -0
  315. data/test_app/config/application.rb +27 -0
  316. data/test_app/config/boot.rb +4 -0
  317. data/test_app/config/bundler-audit.yml +5 -0
  318. data/test_app/config/cable.yml +17 -0
  319. data/test_app/config/cache.yml +16 -0
  320. data/test_app/config/ci.rb +24 -0
  321. data/test_app/config/credentials.yml.enc +1 -0
  322. data/test_app/config/database.yml +40 -0
  323. data/test_app/config/deploy.yml +119 -0
  324. data/test_app/config/environment.rb +5 -0
  325. data/test_app/config/environments/development.rb +78 -0
  326. data/test_app/config/environments/production.rb +90 -0
  327. data/test_app/config/environments/test.rb +53 -0
  328. data/test_app/config/importmap.rb +7 -0
  329. data/test_app/config/initializers/assets.rb +7 -0
  330. data/test_app/config/initializers/content_security_policy.rb +29 -0
  331. data/test_app/config/initializers/filter_parameter_logging.rb +8 -0
  332. data/test_app/config/initializers/inflections.rb +16 -0
  333. data/test_app/config/locales/en.yml +31 -0
  334. data/test_app/config/puma.rb +42 -0
  335. data/test_app/config/queue.yml +18 -0
  336. data/test_app/config/recurring.yml +15 -0
  337. data/test_app/config/routes.rb +13 -0
  338. data/test_app/config/storage.yml +27 -0
  339. data/test_app/config.ru +6 -0
  340. data/test_app/db/cable_schema.rb +11 -0
  341. data/test_app/db/cache_schema.rb +12 -0
  342. data/test_app/db/queue_schema.rb +129 -0
  343. data/test_app/db/seeds.rb +9 -0
  344. data/test_app/lib/tasks/.keep +0 -0
  345. data/test_app/log/.keep +0 -0
  346. data/test_app/public/400.html +135 -0
  347. data/test_app/public/404.html +135 -0
  348. data/test_app/public/406-unsupported-browser.html +135 -0
  349. data/test_app/public/422.html +135 -0
  350. data/test_app/public/500.html +135 -0
  351. data/test_app/public/icon.png +0 -0
  352. data/test_app/public/icon.svg +3 -0
  353. data/test_app/public/robots.txt +1 -0
  354. data/test_app/script/.keep +0 -0
  355. data/test_app/storage/.keep +0 -0
  356. data/test_app/test/controllers/.keep +0 -0
  357. data/test_app/test/fixtures/files/.keep +0 -0
  358. data/test_app/test/helpers/.keep +0 -0
  359. data/test_app/test/integration/.keep +0 -0
  360. data/test_app/test/mailers/.keep +0 -0
  361. data/test_app/test/models/.keep +0 -0
  362. data/test_app/test/test_helper.rb +15 -0
  363. data/test_app/tmp/.keep +0 -0
  364. data/test_app/tmp/pids/.keep +0 -0
  365. data/test_app/tmp/storage/.keep +0 -0
  366. data/test_app/vendor/.keep +0 -0
  367. data/test_app/vendor/javascript/.keep +0 -0
  368. metadata +438 -0
@@ -0,0 +1,75 @@
1
+ description: A dropdown menu triggered by a button. Supports items, separators, and labels. Uses Stimulus for toggling with outside-click and escape-key dismissal.
2
+
3
+ sections:
4
+ - title: Basic Dropdown
5
+ examples:
6
+ - title: Simple menu
7
+ code: |
8
+ <%= render Ui::Dropdown::Component.new do |dropdown| %>
9
+ <% dropdown.with_trigger do %>
10
+ <%= render Ui::Button::Component.new(variant: :outline) do %>Options<% end %>
11
+ <% end %>
12
+ <% dropdown.with_item do %>Profile<% end %>
13
+ <% dropdown.with_item do %>Settings<% end %>
14
+ <% dropdown.with_separator %>
15
+ <% dropdown.with_item do %>Log out<% end %>
16
+ <% end %>
17
+
18
+ - title: With Labels and Links
19
+ examples:
20
+ - title: Grouped items with label
21
+ code: |
22
+ <%= render Ui::Dropdown::Component.new do |dropdown| %>
23
+ <% dropdown.with_trigger do %>
24
+ <%= render Ui::Button::Component.new(variant: :outline) do %>My Account<% end %>
25
+ <% end %>
26
+ <% dropdown.with_label do %>Account<% end %>
27
+ <% dropdown.with_item(href: "/profile") do %>Profile<% end %>
28
+ <% dropdown.with_item(href: "/billing") do %>Billing<% end %>
29
+ <% dropdown.with_separator %>
30
+ <% dropdown.with_label do %>Team<% end %>
31
+ <% dropdown.with_item(href: "/team") do %>Members<% end %>
32
+ <% dropdown.with_item(href: "/team/settings") do %>Team Settings<% end %>
33
+ <% dropdown.with_separator %>
34
+ <% dropdown.with_item do %>Log out<% end %>
35
+ <% end %>
36
+
37
+ - title: Alignment
38
+ examples:
39
+ - title: Right-aligned menu
40
+ code: |
41
+ <div style="display:flex;justify-content:flex-end;">
42
+ <%= render Ui::Dropdown::Component.new(align: :end) do |dropdown| %>
43
+ <% dropdown.with_trigger do %>
44
+ <%= render Ui::Button::Component.new(variant: :secondary) do %>Actions &#9662;<% end %>
45
+ <% end %>
46
+ <% dropdown.with_item do %>Edit<% end %>
47
+ <% dropdown.with_item do %>Duplicate<% end %>
48
+ <% dropdown.with_separator %>
49
+ <% dropdown.with_item do %>Archive<% end %>
50
+ <% dropdown.with_item do %>Delete<% end %>
51
+ <% end %>
52
+ </div>
53
+
54
+ - title: Left-aligned menu (default)
55
+ code: |
56
+ <%= render Ui::Dropdown::Component.new(align: :start) do |dropdown| %>
57
+ <% dropdown.with_trigger do %>
58
+ <%= render Ui::Button::Component.new(variant: :ghost) do %>Menu &#9662;<% end %>
59
+ <% end %>
60
+ <% dropdown.with_item do %>New File<% end %>
61
+ <% dropdown.with_item do %>Open<% end %>
62
+ <% dropdown.with_item do %>Save<% end %>
63
+ <% end %>
64
+
65
+ - title: Custom Attributes
66
+ examples:
67
+ - title: Dropdown with custom data attributes
68
+ code: |
69
+ <%= render Ui::Dropdown::Component.new(class: "my-dropdown", data: { turbo: false }) do |dropdown| %>
70
+ <% dropdown.with_trigger do %>
71
+ <%= render Ui::Button::Component.new do %>More<% end %>
72
+ <% end %>
73
+ <% dropdown.with_item(data: { action: "click->my-controller#export" }) do %>Export<% end %>
74
+ <% dropdown.with_item(data: { action: "click->my-controller#print" }) do %>Print<% end %>
75
+ <% end %>
@@ -0,0 +1,21 @@
1
+ Basic text input:
2
+
3
+ <%= render Ui::Input::Component.new(placeholder: "Enter text") %>
4
+
5
+ With type:
6
+
7
+ <%= render Ui::Input::Component.new(type: "email", placeholder: "you@example.com") %>
8
+ <%= render Ui::Input::Component.new(type: "password", placeholder: "••••••••") %>
9
+ <%= render Ui::Input::Component.new(type: "number", min: 0, max: 100) %>
10
+
11
+ With name and value:
12
+
13
+ <%= render Ui::Input::Component.new(name: "username", value: "john") %>
14
+
15
+ Disabled:
16
+
17
+ <%= render Ui::Input::Component.new(placeholder: "Disabled", disabled: true) %>
18
+
19
+ With custom attributes:
20
+
21
+ <%= render Ui::Input::Component.new(class: "extra", data: { turbo: false }) %>
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ui
4
+ module Input
5
+ # Text input field with consistent styling.
6
+ class Component < Ui::BaseComponent
7
+ attr_reader :html_attrs
8
+
9
+ def initialize(**html_attrs)
10
+ @html_attrs = html_attrs
11
+ super()
12
+ end
13
+
14
+ def call
15
+ tag.input(**computed_attrs)
16
+ end
17
+
18
+ private
19
+
20
+ def computed_attrs
21
+ merge_attrs({ class: "ui-input", type: "text" }, html_attrs)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,43 @@
1
+ /* ============================================
2
+ * UikitRails — Input
3
+ *
4
+ * Standard text input field.
5
+ * ============================================ */
6
+
7
+ .ui-input {
8
+ display: flex;
9
+ width: 100%;
10
+ height: 2.5rem;
11
+ padding: 0.5rem 0.75rem;
12
+ font-family: var(--ui-font-family);
13
+ font-size: var(--ui-font-size-sm);
14
+ line-height: 1.5;
15
+ color: var(--ui-foreground);
16
+ background-color: var(--ui-background);
17
+ border: 1px solid var(--ui-input);
18
+ border-radius: var(--ui-radius);
19
+ transition:
20
+ border-color var(--ui-transition-speed) ease,
21
+ box-shadow var(--ui-transition-speed) ease;
22
+ }
23
+
24
+ .ui-input::placeholder {
25
+ color: var(--ui-muted-foreground);
26
+ }
27
+
28
+ .ui-input:focus {
29
+ outline: none;
30
+ border-color: var(--ui-ring);
31
+ box-shadow: 0 0 0 1px var(--ui-ring);
32
+ }
33
+
34
+ .ui-input:disabled {
35
+ opacity: 0.5;
36
+ cursor: not-allowed;
37
+ background-color: var(--ui-muted);
38
+ }
39
+
40
+ .ui-input[type="file"] {
41
+ padding-top: 0.375rem;
42
+ font-size: var(--ui-font-size-xs);
43
+ }
@@ -0,0 +1,58 @@
1
+ description: A styled text input field. Supports all standard HTML input attributes including type, placeholder, disabled, and name.
2
+
3
+ sections:
4
+ - title: Basic Usage
5
+ examples:
6
+ - title: Default text input
7
+ code: |
8
+ <%= render Ui::Input::Component.new(placeholder: "Enter your name") %>
9
+
10
+ - title: With name attribute
11
+ code: |
12
+ <%= render Ui::Input::Component.new(name: "email", placeholder: "you@example.com") %>
13
+
14
+ - title: Input Types
15
+ examples:
16
+ - title: Email
17
+ code: |
18
+ <%= render Ui::Input::Component.new(type: "email", placeholder: "you@example.com") %>
19
+
20
+ - title: Password
21
+ code: |
22
+ <%= render Ui::Input::Component.new(type: "password", placeholder: "••••••••") %>
23
+
24
+ - title: Number
25
+ code: |
26
+ <%= render Ui::Input::Component.new(type: "number", placeholder: "0", min: 0, max: 100) %>
27
+
28
+ - title: Search
29
+ code: |
30
+ <%= render Ui::Input::Component.new(type: "search", placeholder: "Search...") %>
31
+
32
+ - title: File
33
+ code: |
34
+ <%= render Ui::Input::Component.new(type: "file") %>
35
+
36
+ - title: States
37
+ examples:
38
+ - title: Disabled
39
+ code: |
40
+ <%= render Ui::Input::Component.new(placeholder: "Disabled input", disabled: true) %>
41
+
42
+ - title: With value
43
+ code: |
44
+ <%= render Ui::Input::Component.new(value: "Pre-filled value") %>
45
+
46
+ - title: Required
47
+ code: |
48
+ <%= render Ui::Input::Component.new(placeholder: "Required field", required: true) %>
49
+
50
+ - title: With Custom Attributes
51
+ examples:
52
+ - title: Custom class and data attributes
53
+ code: |
54
+ <%= render Ui::Input::Component.new(
55
+ placeholder: "Custom",
56
+ class: "my-custom-class",
57
+ data: { controller: "input-validator" }
58
+ ) %>
@@ -0,0 +1,16 @@
1
+ Basic label:
2
+
3
+ <%= render Ui::Label::Component.new do %>Email<% end %>
4
+
5
+ With for attribute:
6
+
7
+ <%= render Ui::Label::Component.new(for: "email") do %>Email address<% end %>
8
+
9
+ With form input:
10
+
11
+ <%= render Ui::Label::Component.new(for: "username") do %>Username<% end %>
12
+ <input type="text" id="username" name="username" />
13
+
14
+ With custom attributes:
15
+
16
+ <%= render Ui::Label::Component.new(class: "extra", data: { required: true }) do %>Name<% end %>
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ui
4
+ module Label
5
+ # Form label with consistent styling.
6
+ class Component < Ui::BaseComponent
7
+ attr_reader :html_attrs
8
+
9
+ def initialize(**html_attrs)
10
+ @html_attrs = html_attrs
11
+ super()
12
+ end
13
+
14
+ def call
15
+ content_tag(:label, content, **computed_attrs)
16
+ end
17
+
18
+ private
19
+
20
+ def computed_attrs
21
+ merge_attrs({ class: "ui-label" }, html_attrs)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ /* ============================================
2
+ * UikitRails — Label
3
+ *
4
+ * Form label with consistent styling.
5
+ * ============================================ */
6
+
7
+ .ui-label {
8
+ display: inline-block;
9
+ font-family: var(--ui-font-family);
10
+ font-size: var(--ui-font-size-sm);
11
+ font-weight: 500;
12
+ line-height: 1;
13
+ color: var(--ui-foreground);
14
+ cursor: default;
15
+ }
16
+
17
+ .ui-label[for] {
18
+ cursor: pointer;
19
+ }
20
+
21
+ .ui-label--disabled,
22
+ .ui-label[aria-disabled="true"] {
23
+ opacity: 0.7;
24
+ pointer-events: none;
25
+ }
@@ -0,0 +1,34 @@
1
+ description: A form label element with consistent styling. Accepts a `for` attribute to associate with an input.
2
+
3
+ sections:
4
+ - title: Basic Label
5
+ examples:
6
+ - title: Default
7
+ code: |
8
+ <%= render Ui::Label::Component.new do %>Email<% end %>
9
+
10
+ - title: With for attribute
11
+ code: |
12
+ <%= render Ui::Label::Component.new(for: "email") do %>Email address<% end %>
13
+
14
+ - title: Usage with Form Inputs
15
+ examples:
16
+ - title: Label with text input
17
+ code: |
18
+ <%= render Ui::Label::Component.new(for: "username") do %>Username<% end %>
19
+ <input type="text" id="username" name="username" />
20
+
21
+ - title: Label with required field
22
+ code: |
23
+ <%= render Ui::Label::Component.new(for: "password") do %>Password <span aria-hidden="true">*</span><% end %>
24
+ <input type="password" id="password" name="password" required />
25
+
26
+ - title: With Custom Attributes
27
+ examples:
28
+ - title: Custom class and data attributes
29
+ code: |
30
+ <%= render Ui::Label::Component.new(
31
+ for: "name",
32
+ class: "my-custom-label",
33
+ data: { required: true }
34
+ ) do %>Full Name<% end %>
@@ -0,0 +1,45 @@
1
+ Basic pagination:
2
+
3
+ <%= render Ui::Pagination::Component.new do |pg| %>
4
+ <% pg.with_prev_page(href: "/page/1") %>
5
+ <% pg.with_page(href: "/page/1") do %>1<% end %>
6
+ <% pg.with_page(href: "/page/2", active: true) do %>2<% end %>
7
+ <% pg.with_page(href: "/page/3") do %>3<% end %>
8
+ <% pg.with_next_page(href: "/page/3") %>
9
+ <% end %>
10
+
11
+ With ellipsis for many pages:
12
+
13
+ <%= render Ui::Pagination::Component.new do |pg| %>
14
+ <% pg.with_prev_page(href: "/page/3") %>
15
+ <% pg.with_page(href: "/page/1") do %>1<% end %>
16
+ <% pg.with_ellipsis %>
17
+ <% pg.with_page(href: "/page/4", active: true) do %>4<% end %>
18
+ <% pg.with_ellipsis %>
19
+ <% pg.with_page(href: "/page/10") do %>10<% end %>
20
+ <% pg.with_next_page(href: "/page/5") %>
21
+ <% end %>
22
+
23
+ Disabled prev/next (first or last page):
24
+
25
+ <%= render Ui::Pagination::Component.new do |pg| %>
26
+ <% pg.with_prev_page(disabled: true) %>
27
+ <% pg.with_page(href: "/page/1", active: true) do %>1<% end %>
28
+ <% pg.with_page(href: "/page/2") do %>2<% end %>
29
+ <% pg.with_next_page(href: "/page/2") %>
30
+ <% end %>
31
+
32
+ Custom prev/next labels:
33
+
34
+ <%= render Ui::Pagination::Component.new do |pg| %>
35
+ <% pg.with_prev_page(href: "/page/2") do %>← Older<% end %>
36
+ <% pg.with_next_page(href: "/page/4") do %>Newer →<% end %>
37
+ <% end %>
38
+
39
+ With custom attributes:
40
+
41
+ <%= render Ui::Pagination::Component.new(data: { controller: "pagination" }) do |pg| %>
42
+ <% pg.with_prev_page(href: "/page/1") %>
43
+ <% pg.with_page(href: "/page/2", active: true) do %>2<% end %>
44
+ <% pg.with_next_page(href: "/page/3") %>
45
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <nav class="ui-pagination" aria-label="Pagination" <%= tag.attributes(html_attrs) %>>
2
+ <ul class="ui-pagination__list">
3
+ <% items.each do |item| %>
4
+ <li><%= item %></li>
5
+ <% end %>
6
+ </ul>
7
+ </nav>
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ui
4
+ module Pagination
5
+ # Page navigation with previous, next, and page links.
6
+ class Component < Ui::BaseComponent
7
+ renders_many :items, types: {
8
+ page: { renders: lambda { |href: "#", active: false, **attrs|
9
+ PageItem.new(href: href, active: active, **attrs)
10
+ }, as: :page },
11
+ prev_page: { renders: lambda { |href: "#", disabled: false, **attrs|
12
+ PrevItem.new(href: href, disabled: disabled, **attrs)
13
+ }, as: :prev_page },
14
+ next_page: { renders: lambda { |href: "#", disabled: false, **attrs|
15
+ NextItem.new(href: href, disabled: disabled, **attrs)
16
+ }, as: :next_page },
17
+ ellipsis: { renders: -> { EllipsisItem.new }, as: :ellipsis }
18
+ }
19
+
20
+ attr_reader :html_attrs
21
+
22
+ def initialize(**html_attrs)
23
+ @html_attrs = html_attrs
24
+ super()
25
+ end
26
+
27
+ class PageItem < Ui::BaseComponent
28
+ attr_reader :href, :active, :html_attrs
29
+
30
+ def initialize(href: "#", active: false, **html_attrs)
31
+ @href = href
32
+ @active = active
33
+ @html_attrs = html_attrs
34
+ super()
35
+ end
36
+
37
+ def call
38
+ content_tag(:a, content, class: class_names("ui-pagination__item", "ui-pagination__item--active": active),
39
+ href: href, "aria-current": ("page" if active), **html_attrs)
40
+ end
41
+ end
42
+
43
+ class PrevItem < Ui::BaseComponent
44
+ attr_reader :href, :disabled, :html_attrs
45
+
46
+ def initialize(href: "#", disabled: false, **html_attrs)
47
+ @href = href
48
+ @disabled = disabled
49
+ @html_attrs = html_attrs
50
+ super()
51
+ end
52
+
53
+ def call
54
+ classes = class_names("ui-pagination__item ui-pagination__prev", "ui-pagination__item--disabled": disabled)
55
+ if disabled
56
+ content_tag(:span, content.presence || "Previous", class: classes, "aria-disabled": "true", **html_attrs)
57
+ else
58
+ content_tag(:a, content.presence || "Previous", class: classes, href: href, **html_attrs)
59
+ end
60
+ end
61
+ end
62
+
63
+ class NextItem < Ui::BaseComponent
64
+ attr_reader :href, :disabled, :html_attrs
65
+
66
+ def initialize(href: "#", disabled: false, **html_attrs)
67
+ @href = href
68
+ @disabled = disabled
69
+ @html_attrs = html_attrs
70
+ super()
71
+ end
72
+
73
+ def call
74
+ classes = class_names("ui-pagination__item ui-pagination__next", "ui-pagination__item--disabled": disabled)
75
+ if disabled
76
+ content_tag(:span, content.presence || "Next", class: classes, "aria-disabled": "true", **html_attrs)
77
+ else
78
+ content_tag(:a, content.presence || "Next", class: classes, href: href, **html_attrs)
79
+ end
80
+ end
81
+ end
82
+
83
+ class EllipsisItem < Ui::BaseComponent
84
+ def call
85
+ content_tag(:span, "…", class: "ui-pagination__ellipsis")
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,89 @@
1
+ /* ============================================
2
+ * UikitRails — Pagination
3
+ *
4
+ * Items: page, prev_page, next_page, ellipsis
5
+ * ============================================ */
6
+
7
+ .ui-pagination {
8
+ font-family: var(--ui-font-family);
9
+ font-size: var(--ui-font-size-sm);
10
+ }
11
+
12
+ .ui-pagination__list {
13
+ display: flex;
14
+ align-items: center;
15
+ gap: 0.25rem;
16
+ list-style: none;
17
+ margin: 0;
18
+ padding: 0;
19
+ flex-wrap: wrap;
20
+ }
21
+
22
+ .ui-pagination__item {
23
+ display: inline-flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ min-width: 2.25rem;
27
+ height: 2.25rem;
28
+ padding: 0 0.625rem;
29
+ border: 1px solid var(--ui-border);
30
+ border-radius: var(--ui-radius);
31
+ background-color: var(--ui-background);
32
+ color: var(--ui-foreground);
33
+ text-decoration: none;
34
+ font-weight: 500;
35
+ line-height: 1;
36
+ cursor: pointer;
37
+ transition:
38
+ background-color var(--ui-transition-speed) ease,
39
+ color var(--ui-transition-speed) ease,
40
+ border-color var(--ui-transition-speed) ease;
41
+ }
42
+
43
+ .ui-pagination__item:hover {
44
+ background-color: var(--ui-accent);
45
+ color: var(--ui-accent-foreground);
46
+ }
47
+
48
+ .ui-pagination__item:focus-visible {
49
+ outline: 2px solid var(--ui-ring);
50
+ outline-offset: 2px;
51
+ }
52
+
53
+ /* --- Active page --- */
54
+
55
+ .ui-pagination__item--active {
56
+ background-color: var(--ui-primary);
57
+ color: var(--ui-primary-foreground);
58
+ border-color: var(--ui-primary);
59
+ pointer-events: none;
60
+ }
61
+
62
+ /* --- Disabled (prev/next) --- */
63
+
64
+ .ui-pagination__item--disabled {
65
+ opacity: 0.5;
66
+ pointer-events: none;
67
+ cursor: default;
68
+ }
69
+
70
+ /* --- Previous / Next --- */
71
+
72
+ .ui-pagination__prev,
73
+ .ui-pagination__next {
74
+ padding: 0 0.75rem;
75
+ }
76
+
77
+ /* --- Ellipsis --- */
78
+
79
+ .ui-pagination__ellipsis {
80
+ display: inline-flex;
81
+ align-items: center;
82
+ justify-content: center;
83
+ min-width: 2.25rem;
84
+ height: 2.25rem;
85
+ color: var(--ui-muted-foreground);
86
+ font-weight: 500;
87
+ letter-spacing: 0.1em;
88
+ cursor: default;
89
+ }
@@ -0,0 +1,61 @@
1
+ description: Page navigation with previous/next buttons, page numbers, and ellipsis indicators. Compose the pagination using slot items for full flexibility.
2
+
3
+ sections:
4
+ - title: Basic Pagination
5
+ examples:
6
+ - title: Simple page navigation
7
+ code: |
8
+ <%= render Ui::Pagination::Component.new do |pg| %>
9
+ <% pg.with_prev_page(href: "/page/1") %>
10
+ <% pg.with_page(href: "/page/1") do %>1<% end %>
11
+ <% pg.with_page(href: "/page/2", active: true) do %>2<% end %>
12
+ <% pg.with_page(href: "/page/3") do %>3<% end %>
13
+ <% pg.with_next_page(href: "/page/3") %>
14
+ <% end %>
15
+
16
+ - title: With Ellipsis
17
+ examples:
18
+ - title: Many pages with ellipsis
19
+ code: |
20
+ <%= render Ui::Pagination::Component.new do |pg| %>
21
+ <% pg.with_prev_page(href: "/page/3") %>
22
+ <% pg.with_page(href: "/page/1") do %>1<% end %>
23
+ <% pg.with_ellipsis %>
24
+ <% pg.with_page(href: "/page/3") do %>3<% end %>
25
+ <% pg.with_page(href: "/page/4", active: true) do %>4<% end %>
26
+ <% pg.with_page(href: "/page/5") do %>5<% end %>
27
+ <% pg.with_ellipsis %>
28
+ <% pg.with_page(href: "/page/10") do %>10<% end %>
29
+ <% pg.with_next_page(href: "/page/5") %>
30
+ <% end %>
31
+
32
+ - title: Disabled States
33
+ examples:
34
+ - title: First page (previous disabled)
35
+ code: |
36
+ <%= render Ui::Pagination::Component.new do |pg| %>
37
+ <% pg.with_prev_page(disabled: true) %>
38
+ <% pg.with_page(href: "/page/1", active: true) do %>1<% end %>
39
+ <% pg.with_page(href: "/page/2") do %>2<% end %>
40
+ <% pg.with_page(href: "/page/3") do %>3<% end %>
41
+ <% pg.with_next_page(href: "/page/2") %>
42
+ <% end %>
43
+
44
+ - title: Last page (next disabled)
45
+ code: |
46
+ <%= render Ui::Pagination::Component.new do |pg| %>
47
+ <% pg.with_prev_page(href: "/page/4") %>
48
+ <% pg.with_page(href: "/page/3") do %>3<% end %>
49
+ <% pg.with_page(href: "/page/4") do %>4<% end %>
50
+ <% pg.with_page(href: "/page/5", active: true) do %>5<% end %>
51
+ <% pg.with_next_page(disabled: true) %>
52
+ <% end %>
53
+
54
+ - title: Prev/Next Only
55
+ examples:
56
+ - title: Without page numbers
57
+ code: |
58
+ <%= render Ui::Pagination::Component.new do |pg| %>
59
+ <% pg.with_prev_page(href: "/page/2") do %>← Older<% end %>
60
+ <% pg.with_next_page(href: "/page/4") do %>Newer →<% end %>
61
+ <% end %>
@@ -0,0 +1,44 @@
1
+ Basic popover (bottom center):
2
+
3
+ <%= render Ui::Popover::Component.new do |popover| %>
4
+ <% popover.with_trigger do %>
5
+ <%= render Ui::Button::Component.new do %>Open<% end %>
6
+ <% end %>
7
+ <p>Popover content here.</p>
8
+ <% end %>
9
+
10
+ Side variants (top, bottom):
11
+
12
+ <%= render Ui::Popover::Component.new(side: :top) do |popover| %>
13
+ <% popover.with_trigger do %>Open Top<% end %>
14
+ <p>Content above trigger.</p>
15
+ <% end %>
16
+
17
+ Alignment (start, center, end):
18
+
19
+ <%= render Ui::Popover::Component.new(align: :start) do |popover| %>
20
+ <% popover.with_trigger do %>Open<% end %>
21
+ <p>Aligned to left edge.</p>
22
+ <% end %>
23
+
24
+ <%= render Ui::Popover::Component.new(align: :end, side: :top) do |popover| %>
25
+ <% popover.with_trigger do %>Open<% end %>
26
+ <p>Above, aligned to right edge.</p>
27
+ <% end %>
28
+
29
+ Slots:
30
+ trigger — Element that toggles the popover on click
31
+ content — Main body (default slot)
32
+
33
+ Props:
34
+ align (start/center/end, default: center) — Horizontal alignment relative to trigger
35
+ side (top/bottom, default: bottom) — Which side the popover appears on
36
+
37
+ Closes on outside click and Escape key.
38
+
39
+ With custom attributes:
40
+
41
+ <%= render Ui::Popover::Component.new(class: "extra", data: { turbo: false }) do |popover| %>
42
+ <% popover.with_trigger do %>Open<% end %>
43
+ <p>Content</p>
44
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <div data-controller="ui--popover" class="ui-popover" <%= tag.attributes(html_attrs) %>>
2
+ <% if trigger? %>
3
+ <div data-action="click->ui--popover#toggle" class="ui-popover__trigger"><%= trigger %></div>
4
+ <% end %>
5
+ <div data-ui--popover-target="content" class="ui-popover__content ui-popover__content--<%= side %> ui-popover__content--<%= align %>">
6
+ <%= content %>
7
+ </div>
8
+ </div>