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,125 @@
1
+ /* ============================================
2
+ * UikitRails — Button
3
+ *
4
+ * Variants: default, destructive, outline, secondary, ghost, link
5
+ * Sizes: sm, md, lg, icon
6
+ * ============================================ */
7
+
8
+ .ui-btn {
9
+ display: inline-flex;
10
+ align-items: center;
11
+ justify-content: center;
12
+ gap: 0.5rem;
13
+ white-space: nowrap;
14
+ font-family: var(--ui-font-family);
15
+ font-weight: 500;
16
+ border: 1px solid transparent;
17
+ border-radius: var(--ui-radius);
18
+ cursor: pointer;
19
+ transition:
20
+ background-color var(--ui-transition-speed) ease,
21
+ color var(--ui-transition-speed) ease,
22
+ border-color var(--ui-transition-speed) ease,
23
+ box-shadow var(--ui-transition-speed) ease;
24
+ text-decoration: none;
25
+ line-height: 1;
26
+ }
27
+
28
+ .ui-btn:focus-visible {
29
+ outline: 2px solid var(--ui-ring);
30
+ outline-offset: 2px;
31
+ }
32
+
33
+ .ui-btn:disabled,
34
+ .ui-btn[aria-disabled="true"] {
35
+ opacity: 0.5;
36
+ pointer-events: none;
37
+ }
38
+
39
+ /* --- Variants --- */
40
+
41
+ .ui-btn--default {
42
+ background-color: var(--ui-primary);
43
+ color: var(--ui-primary-foreground);
44
+ }
45
+
46
+ .ui-btn--default:hover {
47
+ background-color: color-mix(in srgb, var(--ui-primary) 90%, transparent);
48
+ }
49
+
50
+ .ui-btn--destructive {
51
+ background-color: var(--ui-destructive);
52
+ color: var(--ui-destructive-foreground);
53
+ }
54
+
55
+ .ui-btn--destructive:hover {
56
+ background-color: color-mix(in srgb, var(--ui-destructive) 90%, transparent);
57
+ }
58
+
59
+ .ui-btn--outline {
60
+ border-color: var(--ui-border);
61
+ background-color: var(--ui-background);
62
+ color: var(--ui-foreground);
63
+ }
64
+
65
+ .ui-btn--outline:hover {
66
+ background-color: var(--ui-accent);
67
+ color: var(--ui-accent-foreground);
68
+ }
69
+
70
+ .ui-btn--secondary {
71
+ background-color: var(--ui-secondary);
72
+ color: var(--ui-secondary-foreground);
73
+ }
74
+
75
+ .ui-btn--secondary:hover {
76
+ background-color: color-mix(in srgb, var(--ui-secondary) 80%, transparent);
77
+ }
78
+
79
+ .ui-btn--ghost {
80
+ background-color: transparent;
81
+ color: var(--ui-foreground);
82
+ }
83
+
84
+ .ui-btn--ghost:hover {
85
+ background-color: var(--ui-accent);
86
+ color: var(--ui-accent-foreground);
87
+ }
88
+
89
+ .ui-btn--link {
90
+ background-color: transparent;
91
+ color: var(--ui-primary);
92
+ text-underline-offset: 4px;
93
+ }
94
+
95
+ .ui-btn--link:hover {
96
+ text-decoration: underline;
97
+ }
98
+
99
+ /* --- Sizes --- */
100
+
101
+ .ui-btn--sm {
102
+ height: 2.25rem;
103
+ padding: 0 0.75rem;
104
+ font-size: var(--ui-font-size-xs);
105
+ border-radius: var(--ui-radius);
106
+ }
107
+
108
+ .ui-btn--md {
109
+ height: 2.5rem;
110
+ padding: 0.5rem 1rem;
111
+ font-size: var(--ui-font-size-sm);
112
+ }
113
+
114
+ .ui-btn--lg {
115
+ height: 2.75rem;
116
+ padding: 0 2rem;
117
+ font-size: var(--ui-font-size-base);
118
+ border-radius: var(--ui-radius);
119
+ }
120
+
121
+ .ui-btn--icon {
122
+ height: 2.5rem;
123
+ width: 2.5rem;
124
+ padding: 0;
125
+ }
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ui
4
+ module Button
5
+ # Button component with multiple variants and sizes.
6
+ class Component < Ui::BaseComponent
7
+ VARIANTS = %i[default destructive outline secondary ghost link].freeze
8
+ SIZES = %i[sm md lg icon].freeze
9
+
10
+ attr_reader :variant, :size, :tag, :html_attrs
11
+
12
+ def initialize(variant: :default, size: :md, tag: :button, **html_attrs)
13
+ @variant = variant.to_sym
14
+ @size = size.to_sym
15
+ @tag = tag
16
+ @html_attrs = html_attrs
17
+ super()
18
+ end
19
+
20
+ def call
21
+ content_tag(tag, content, **computed_attrs)
22
+ end
23
+
24
+ private
25
+
26
+ def computed_attrs
27
+ defaults = {
28
+ class: computed_classes,
29
+ type: (tag == :button ? "button" : nil)
30
+ }.compact
31
+
32
+ merge_attrs(defaults, html_attrs)
33
+ end
34
+
35
+ def computed_classes
36
+ class_names(
37
+ "ui-btn",
38
+ "ui-btn--#{variant}",
39
+ "ui-btn--#{size}"
40
+ )
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,106 @@
1
+ description: A clickable button with multiple variants and sizes. Renders as a <button> by default or as an <a> tag for links.
2
+
3
+ sections:
4
+ - title: Variants
5
+ examples:
6
+ - title: Default
7
+ code: |
8
+ <%= render Ui::Button::Component.new do %>
9
+ Click me
10
+ <% end %>
11
+
12
+ - title: Secondary
13
+ code: |
14
+ <%= render Ui::Button::Component.new(variant: :secondary) do %>
15
+ Secondary
16
+ <% end %>
17
+
18
+ - title: Destructive
19
+ code: |
20
+ <%= render Ui::Button::Component.new(variant: :destructive) do %>
21
+ Delete
22
+ <% end %>
23
+
24
+ - title: Outline
25
+ code: |
26
+ <%= render Ui::Button::Component.new(variant: :outline) do %>
27
+ Outline
28
+ <% end %>
29
+
30
+ - title: Ghost
31
+ code: |
32
+ <%= render Ui::Button::Component.new(variant: :ghost) do %>
33
+ Ghost
34
+ <% end %>
35
+
36
+ - title: Link
37
+ code: |
38
+ <%= render Ui::Button::Component.new(variant: :link) do %>
39
+ Link
40
+ <% end %>
41
+
42
+ - title: Sizes
43
+ examples:
44
+ - title: Small
45
+ code: |
46
+ <%= render Ui::Button::Component.new(size: :sm) do %>
47
+ Small
48
+ <% end %>
49
+
50
+ - title: Medium (default)
51
+ code: |
52
+ <%= render Ui::Button::Component.new(size: :md) do %>
53
+ Medium
54
+ <% end %>
55
+
56
+ - title: Large
57
+ code: |
58
+ <%= render Ui::Button::Component.new(size: :lg) do %>
59
+ Large
60
+ <% end %>
61
+
62
+ - title: Icon
63
+ code: |
64
+ <%= render Ui::Button::Component.new(size: :icon) do %>
65
+ &#9733;
66
+ <% end %>
67
+
68
+ - title: As a Link
69
+ examples:
70
+ - title: Link with default style
71
+ code: |
72
+ <%= render Ui::Button::Component.new(tag: :a, href: "/dashboard") do %>
73
+ Go to Dashboard
74
+ <% end %>
75
+
76
+ - title: Link with outline style
77
+ code: |
78
+ <%= render Ui::Button::Component.new(tag: :a, href: "#", variant: :outline) do %>
79
+ Learn more
80
+ <% end %>
81
+
82
+ - title: Disabled State
83
+ examples:
84
+ - title: Disabled default
85
+ code: |
86
+ <%= render Ui::Button::Component.new(disabled: true) do %>
87
+ Disabled
88
+ <% end %>
89
+
90
+ - title: Disabled destructive
91
+ code: |
92
+ <%= render Ui::Button::Component.new(variant: :destructive, disabled: true) do %>
93
+ Can't delete
94
+ <% end %>
95
+
96
+ - title: With Custom Attributes
97
+ examples:
98
+ - title: Custom class and data attributes
99
+ code: |
100
+ <%= render Ui::Button::Component.new(
101
+ variant: :secondary,
102
+ class: "my-custom-class",
103
+ data: { turbo: false, controller: "my-controller" }
104
+ ) do %>
105
+ Custom
106
+ <% end %>
@@ -0,0 +1,33 @@
1
+ Basic card:
2
+
3
+ <%= render Ui::Card::Component.new do |card| %>
4
+ <% card.with_title do %>Title<% end %>
5
+ <p>Body content</p>
6
+ <% end %>
7
+
8
+ With title and description:
9
+
10
+ <%= render Ui::Card::Component.new do |card| %>
11
+ <% card.with_title do %>Title<% end %>
12
+ <% card.with_description do %>Description text<% end %>
13
+ <p>Body</p>
14
+ <% end %>
15
+
16
+ With footer:
17
+
18
+ <%= render Ui::Card::Component.new do |card| %>
19
+ <% card.with_title do %>Title<% end %>
20
+ <p>Content</p>
21
+ <% card.with_footer do %>Footer content<% end %>
22
+ <% end %>
23
+
24
+ With custom header:
25
+
26
+ <%= render Ui::Card::Component.new do |card| %>
27
+ <% card.with_header do %><strong>Custom header</strong><% end %>
28
+ <p>Content</p>
29
+ <% end %>
30
+
31
+ With custom attributes:
32
+
33
+ <%= render Ui::Card::Component.new(class: "extra", data: { controller: "card" }) do %>Content<% end %>
@@ -0,0 +1,63 @@
1
+ /* ============================================
2
+ * UikitRails — Card
3
+ *
4
+ * Versatile container for grouping related content
5
+ * with optional header, title, description, and footer.
6
+ * ============================================ */
7
+
8
+ .ui-card {
9
+ display: flex;
10
+ flex-direction: column;
11
+ background-color: var(--ui-background);
12
+ color: var(--ui-foreground);
13
+ border: 1px solid var(--ui-border);
14
+ border-radius: var(--ui-radius);
15
+ box-shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
16
+ font-family: var(--ui-font-family);
17
+ overflow: hidden;
18
+ }
19
+
20
+ /* --- Header --- */
21
+
22
+ .ui-card__header {
23
+ display: flex;
24
+ flex-direction: column;
25
+ gap: 0.375rem;
26
+ padding: 1.5rem 1.5rem 0;
27
+ }
28
+
29
+ /* --- Title --- */
30
+
31
+ .ui-card__title {
32
+ margin: 0;
33
+ font-size: var(--ui-font-size-base);
34
+ font-weight: 600;
35
+ line-height: 1.25;
36
+ color: var(--ui-foreground);
37
+ }
38
+
39
+ /* --- Description --- */
40
+
41
+ .ui-card__description {
42
+ margin: 0;
43
+ font-size: var(--ui-font-size-sm);
44
+ color: var(--ui-muted-foreground);
45
+ line-height: 1.5;
46
+ }
47
+
48
+ /* --- Body --- */
49
+
50
+ .ui-card__body {
51
+ padding: 1.5rem;
52
+ font-size: var(--ui-font-size-sm);
53
+ flex: 1;
54
+ }
55
+
56
+ /* --- Footer --- */
57
+
58
+ .ui-card__footer {
59
+ display: flex;
60
+ align-items: center;
61
+ gap: 0.5rem;
62
+ padding: 0 1.5rem 1.5rem;
63
+ }
@@ -0,0 +1,16 @@
1
+ <%= content_tag :div, **computed_attrs do %>
2
+ <% if header? %>
3
+ <div class="ui-card__header"><%= header %></div>
4
+ <% elsif title? || description? %>
5
+ <div class="ui-card__header">
6
+ <% if title? %><h3 class="ui-card__title"><%= title %></h3><% end %>
7
+ <% if description? %><p class="ui-card__description"><%= description %></p><% end %>
8
+ </div>
9
+ <% end %>
10
+ <% if content? %>
11
+ <div class="ui-card__body"><%= content %></div>
12
+ <% end %>
13
+ <% if footer? %>
14
+ <div class="ui-card__footer"><%= footer %></div>
15
+ <% end %>
16
+ <% end %>
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ui
4
+ module Card
5
+ # Versatile container for grouping related content.
6
+ class Component < Ui::BaseComponent
7
+ renders_one :header
8
+ renders_one :title
9
+ renders_one :description
10
+ renders_one :footer
11
+
12
+ attr_reader :html_attrs
13
+
14
+ def initialize(**html_attrs)
15
+ @html_attrs = html_attrs
16
+ super()
17
+ end
18
+
19
+ private
20
+
21
+ def computed_attrs
22
+ merge_attrs({ class: "ui-card" }, html_attrs)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,57 @@
1
+ description: A versatile container for grouping related content with optional header, title, description, body, and footer sections.
2
+
3
+ sections:
4
+ - title: Basic Card
5
+ examples:
6
+ - title: Simple content
7
+ code: |
8
+ <%= render Ui::Card::Component.new do |card| %>
9
+ <% card.with_title do %>Card Title<% end %>
10
+ <% card.with_description do %>A short description of the card content.<% end %>
11
+ <p>This is the card body content.</p>
12
+ <% end %>
13
+
14
+ - title: Card with Header, Title, Description & Footer
15
+ examples:
16
+ - title: Full card
17
+ code: |
18
+ <%= render Ui::Card::Component.new do |card| %>
19
+ <% card.with_title do %>Notifications<% end %>
20
+ <% card.with_description do %>You have 3 unread messages.<% end %>
21
+ <p>Review your latest notifications and take action.</p>
22
+ <% card.with_footer do %>
23
+ <%= render Ui::Button::Component.new(size: :sm) do %>View all<% end %>
24
+ <% end %>
25
+ <% end %>
26
+
27
+ - title: Card with custom header
28
+ code: |
29
+ <%= render Ui::Card::Component.new do |card| %>
30
+ <% card.with_header do %>
31
+ <div style="display:flex;align-items:center;justify-content:space-between;">
32
+ <strong>Team Members</strong>
33
+ <span>3 online</span>
34
+ </div>
35
+ <% end %>
36
+ <p>Manage your team and their permissions.</p>
37
+ <% end %>
38
+
39
+ - title: Card with Custom Content
40
+ examples:
41
+ - title: Custom styled card
42
+ code: |
43
+ <%= render Ui::Card::Component.new(class: "my-custom-card") do |card| %>
44
+ <% card.with_title do %>Settings<% end %>
45
+ <% card.with_description do %>Manage your account preferences.<% end %>
46
+ <p>Content goes here.</p>
47
+ <% card.with_footer do %>
48
+ <%= render Ui::Button::Component.new(variant: :outline, size: :sm) do %>Cancel<% end %>
49
+ <%= render Ui::Button::Component.new(size: :sm) do %>Save<% end %>
50
+ <% end %>
51
+ <% end %>
52
+
53
+ - title: Minimal card
54
+ code: |
55
+ <%= render Ui::Card::Component.new do %>
56
+ <p>A simple card with just body content and no header or footer.</p>
57
+ <% end %>
@@ -0,0 +1,19 @@
1
+ Basic checkbox:
2
+
3
+ <%= render Ui::Checkbox::Component.new(name: "agree") %>
4
+
5
+ With label:
6
+
7
+ <%= render Ui::Checkbox::Component.new(label: "Accept terms", name: "terms", id: "terms") %>
8
+
9
+ Checked by default:
10
+
11
+ <%= render Ui::Checkbox::Component.new(label: "Enabled", checked: true, name: "enabled", id: "enabled") %>
12
+
13
+ Disabled:
14
+
15
+ <%= render Ui::Checkbox::Component.new(label: "Disabled", disabled: true, name: "off", id: "off") %>
16
+
17
+ With custom attributes:
18
+
19
+ <%= render Ui::Checkbox::Component.new(label: "Toggle", name: "flag", id: "flag", data: { action: "change->ctrl#run" }) %>
@@ -0,0 +1,67 @@
1
+ /* ============================================
2
+ * UikitRails — Checkbox
3
+ *
4
+ * Custom styled checkbox with optional label.
5
+ * ============================================ */
6
+
7
+ .ui-checkbox__wrapper {
8
+ display: inline-flex;
9
+ align-items: center;
10
+ gap: 0.5rem;
11
+ }
12
+
13
+ .ui-checkbox {
14
+ appearance: none;
15
+ -webkit-appearance: none;
16
+ width: 1rem;
17
+ height: 1rem;
18
+ border: 1px solid var(--ui-border);
19
+ border-radius: calc(var(--ui-radius) * 0.5);
20
+ background-color: var(--ui-background);
21
+ cursor: pointer;
22
+ flex-shrink: 0;
23
+ position: relative;
24
+ transition:
25
+ background-color var(--ui-transition-speed) ease,
26
+ border-color var(--ui-transition-speed) ease;
27
+ }
28
+
29
+ .ui-checkbox:checked {
30
+ background-color: var(--ui-primary);
31
+ border-color: var(--ui-primary);
32
+ }
33
+
34
+ .ui-checkbox:checked::after {
35
+ content: "";
36
+ position: absolute;
37
+ top: 1px;
38
+ left: 4px;
39
+ width: 5px;
40
+ height: 9px;
41
+ border: solid var(--ui-primary-foreground);
42
+ border-width: 0 2px 2px 0;
43
+ transform: rotate(45deg);
44
+ }
45
+
46
+ .ui-checkbox:focus-visible {
47
+ outline: 2px solid var(--ui-ring);
48
+ outline-offset: 2px;
49
+ }
50
+
51
+ .ui-checkbox:disabled {
52
+ opacity: 0.5;
53
+ cursor: not-allowed;
54
+ }
55
+
56
+ .ui-checkbox:disabled + .ui-checkbox__label {
57
+ opacity: 0.5;
58
+ cursor: not-allowed;
59
+ }
60
+
61
+ .ui-checkbox__label {
62
+ font-family: var(--ui-font-family);
63
+ font-size: var(--ui-font-size-sm);
64
+ color: var(--ui-foreground);
65
+ cursor: pointer;
66
+ user-select: none;
67
+ }
@@ -0,0 +1,6 @@
1
+ <div class="ui-checkbox__wrapper">
2
+ <input <%= tag.attributes(input_attrs) %> />
3
+ <% if label %>
4
+ <label class="ui-checkbox__label" for="<%= input_id %>"><%= label %></label>
5
+ <% end %>
6
+ </div>
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ui
4
+ module Checkbox
5
+ # Styled checkbox with optional label.
6
+ class Component < Ui::BaseComponent
7
+ attr_reader :label, :html_attrs
8
+
9
+ def initialize(label: nil, **html_attrs)
10
+ @label = label
11
+ @html_attrs = html_attrs
12
+ super()
13
+ end
14
+
15
+ private
16
+
17
+ def input_attrs
18
+ merge_attrs({ class: "ui-checkbox", type: "checkbox" }, html_attrs)
19
+ end
20
+
21
+ def input_id
22
+ html_attrs[:id] || html_attrs[:name]
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,43 @@
1
+ description: A styled checkbox with an optional label. Supports checked, disabled, and all standard HTML input attributes.
2
+
3
+ sections:
4
+ - title: Basic Usage
5
+ examples:
6
+ - title: Without label
7
+ code: |
8
+ <%= render Ui::Checkbox::Component.new(name: "terms") %>
9
+
10
+ - title: With label
11
+ code: |
12
+ <%= render Ui::Checkbox::Component.new(label: "Accept terms and conditions", name: "terms", id: "terms") %>
13
+
14
+ - title: States
15
+ examples:
16
+ - title: Checked
17
+ code: |
18
+ <%= render Ui::Checkbox::Component.new(label: "Checked by default", checked: true, name: "notify", id: "notify") %>
19
+
20
+ - title: Disabled
21
+ code: |
22
+ <%= render Ui::Checkbox::Component.new(label: "Disabled checkbox", disabled: true, name: "disabled_cb", id: "disabled_cb") %>
23
+
24
+ - title: Disabled and checked
25
+ code: |
26
+ <%= render Ui::Checkbox::Component.new(label: "Disabled checked", disabled: true, checked: true, name: "disabled_checked", id: "disabled_checked") %>
27
+
28
+ - title: Form Integration
29
+ examples:
30
+ - title: With value
31
+ code: |
32
+ <%= render Ui::Checkbox::Component.new(label: "Subscribe to newsletter", name: "subscribe", value: "1", id: "subscribe") %>
33
+
34
+ - title: With Custom Attributes
35
+ examples:
36
+ - title: Custom data attributes
37
+ code: |
38
+ <%= render Ui::Checkbox::Component.new(
39
+ label: "Enable feature",
40
+ name: "feature",
41
+ id: "feature",
42
+ data: { controller: "feature-toggle", action: "change->feature-toggle#toggle" }
43
+ ) %>
@@ -0,0 +1,31 @@
1
+ Basic collapsible:
2
+
3
+ <%= render Ui::Collapsible::Component.new do |collapsible| %>
4
+ <% collapsible.with_trigger do %>
5
+ <span>Toggle content</span>
6
+ <% end %>
7
+ <p>Hidden content revealed on click.</p>
8
+ <% end %>
9
+
10
+ Open by default:
11
+
12
+ <%= render Ui::Collapsible::Component.new(open: true) do |collapsible| %>
13
+ <% collapsible.with_trigger do %>
14
+ <span>Already open</span>
15
+ <% end %>
16
+ <p>This content is visible on load.</p>
17
+ <% end %>
18
+
19
+ Slots:
20
+ trigger — Clickable area that toggles visibility
21
+ content — Main body (default slot), shown/hidden on toggle
22
+
23
+ Props:
24
+ open (boolean, default: false) — Whether the content starts expanded
25
+
26
+ With custom attributes:
27
+
28
+ <%= render Ui::Collapsible::Component.new(class: "extra", data: { section: "faq" }) do |collapsible| %>
29
+ <% collapsible.with_trigger do %>Question?<% end %>
30
+ <p>Answer.</p>
31
+ <% end %>