uikit_rails 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +301 -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/form/USAGE +51 -0
  73. data/lib/uikit_rails/templates/components/form/builder.rb +233 -0
  74. data/lib/uikit_rails/templates/components/form/form.css +48 -0
  75. data/lib/uikit_rails/templates/components/form/preview.yml +95 -0
  76. data/lib/uikit_rails/templates/components/input/USAGE +21 -0
  77. data/lib/uikit_rails/templates/components/input/component.rb +25 -0
  78. data/lib/uikit_rails/templates/components/input/input.css +43 -0
  79. data/lib/uikit_rails/templates/components/input/preview.yml +58 -0
  80. data/lib/uikit_rails/templates/components/label/USAGE +16 -0
  81. data/lib/uikit_rails/templates/components/label/component.rb +25 -0
  82. data/lib/uikit_rails/templates/components/label/label.css +25 -0
  83. data/lib/uikit_rails/templates/components/label/preview.yml +34 -0
  84. data/lib/uikit_rails/templates/components/pagination/USAGE +45 -0
  85. data/lib/uikit_rails/templates/components/pagination/component.html.erb +7 -0
  86. data/lib/uikit_rails/templates/components/pagination/component.rb +90 -0
  87. data/lib/uikit_rails/templates/components/pagination/pagination.css +89 -0
  88. data/lib/uikit_rails/templates/components/pagination/preview.yml +61 -0
  89. data/lib/uikit_rails/templates/components/popover/USAGE +44 -0
  90. data/lib/uikit_rails/templates/components/popover/component.html.erb +8 -0
  91. data/lib/uikit_rails/templates/components/popover/component.rb +19 -0
  92. data/lib/uikit_rails/templates/components/popover/popover.css +94 -0
  93. data/lib/uikit_rails/templates/components/popover/preview.yml +102 -0
  94. data/lib/uikit_rails/templates/components/progress/USAGE +15 -0
  95. data/lib/uikit_rails/templates/components/progress/component.html.erb +3 -0
  96. data/lib/uikit_rails/templates/components/progress/component.rb +38 -0
  97. data/lib/uikit_rails/templates/components/progress/preview.yml +44 -0
  98. data/lib/uikit_rails/templates/components/progress/progress.css +20 -0
  99. data/lib/uikit_rails/templates/components/select/USAGE +19 -0
  100. data/lib/uikit_rails/templates/components/select/component.rb +38 -0
  101. data/lib/uikit_rails/templates/components/select/preview.yml +61 -0
  102. data/lib/uikit_rails/templates/components/select/select.css +46 -0
  103. data/lib/uikit_rails/templates/components/separator/USAGE +15 -0
  104. data/lib/uikit_rails/templates/components/separator/component.rb +34 -0
  105. data/lib/uikit_rails/templates/components/separator/preview.yml +32 -0
  106. data/lib/uikit_rails/templates/components/separator/separator.css +21 -0
  107. data/lib/uikit_rails/templates/components/sheet/USAGE +44 -0
  108. data/lib/uikit_rails/templates/components/sheet/component.html.erb +23 -0
  109. data/lib/uikit_rails/templates/components/sheet/component.rb +23 -0
  110. data/lib/uikit_rails/templates/components/sheet/preview.yml +105 -0
  111. data/lib/uikit_rails/templates/components/sheet/sheet.css +193 -0
  112. data/lib/uikit_rails/templates/components/skeleton/USAGE +19 -0
  113. data/lib/uikit_rails/templates/components/skeleton/component.rb +38 -0
  114. data/lib/uikit_rails/templates/components/skeleton/preview.yml +44 -0
  115. data/lib/uikit_rails/templates/components/skeleton/skeleton.css +25 -0
  116. data/lib/uikit_rails/templates/components/switch/USAGE +19 -0
  117. data/lib/uikit_rails/templates/components/switch/component.html.erb +19 -0
  118. data/lib/uikit_rails/templates/components/switch/component.rb +23 -0
  119. data/lib/uikit_rails/templates/components/switch/preview.yml +43 -0
  120. data/lib/uikit_rails/templates/components/switch/switch.css +81 -0
  121. data/lib/uikit_rails/templates/components/table/USAGE +40 -0
  122. data/lib/uikit_rails/templates/components/table/component.html.erb +14 -0
  123. data/lib/uikit_rails/templates/components/table/component.rb +25 -0
  124. data/lib/uikit_rails/templates/components/table/preview.yml +109 -0
  125. data/lib/uikit_rails/templates/components/table/table.css +86 -0
  126. data/lib/uikit_rails/templates/components/tabs/USAGE +24 -0
  127. data/lib/uikit_rails/templates/components/tabs/component.html.erb +10 -0
  128. data/lib/uikit_rails/templates/components/tabs/component.rb +35 -0
  129. data/lib/uikit_rails/templates/components/tabs/preview.yml +60 -0
  130. data/lib/uikit_rails/templates/components/tabs/tabs.css +72 -0
  131. data/lib/uikit_rails/templates/components/textarea/USAGE +19 -0
  132. data/lib/uikit_rails/templates/components/textarea/component.rb +25 -0
  133. data/lib/uikit_rails/templates/components/textarea/preview.yml +47 -0
  134. data/lib/uikit_rails/templates/components/textarea/textarea.css +39 -0
  135. data/lib/uikit_rails/templates/components/toggle/USAGE +25 -0
  136. data/lib/uikit_rails/templates/components/toggle/component.rb +39 -0
  137. data/lib/uikit_rails/templates/components/toggle/preview.yml +81 -0
  138. data/lib/uikit_rails/templates/components/toggle/toggle.css +89 -0
  139. data/lib/uikit_rails/templates/components/tooltip/USAGE +23 -0
  140. data/lib/uikit_rails/templates/components/tooltip/component.html.erb +8 -0
  141. data/lib/uikit_rails/templates/components/tooltip/component.rb +19 -0
  142. data/lib/uikit_rails/templates/components/tooltip/preview.yml +52 -0
  143. data/lib/uikit_rails/templates/components/tooltip/tooltip.css +78 -0
  144. data/lib/uikit_rails/templates/stimulus/accordion_controller.js +19 -0
  145. data/lib/uikit_rails/templates/stimulus/alert_dialog_controller.js +25 -0
  146. data/lib/uikit_rails/templates/stimulus/collapsible_controller.js +9 -0
  147. data/lib/uikit_rails/templates/stimulus/dialog_controller.js +19 -0
  148. data/lib/uikit_rails/templates/stimulus/dropdown_controller.js +47 -0
  149. data/lib/uikit_rails/templates/stimulus/popover_controller.js +47 -0
  150. data/lib/uikit_rails/templates/stimulus/sheet_controller.js +19 -0
  151. data/lib/uikit_rails/templates/stimulus/tabs_controller.js +24 -0
  152. data/lib/uikit_rails/templates/stimulus/tooltip_controller.js +13 -0
  153. data/lib/uikit_rails/version.rb +5 -0
  154. data/lib/uikit_rails.rb +59 -0
  155. data/sig/uikit_rails.rbs +4 -0
  156. data/test_app/.dockerignore +51 -0
  157. data/test_app/.gitattributes +9 -0
  158. data/test_app/.github/dependabot.yml +12 -0
  159. data/test_app/.github/workflows/ci.yml +124 -0
  160. data/test_app/.gitignore +35 -0
  161. data/test_app/.kamal/hooks/docker-setup.sample +3 -0
  162. data/test_app/.kamal/hooks/post-app-boot.sample +3 -0
  163. data/test_app/.kamal/hooks/post-deploy.sample +14 -0
  164. data/test_app/.kamal/hooks/post-proxy-reboot.sample +3 -0
  165. data/test_app/.kamal/hooks/pre-app-boot.sample +3 -0
  166. data/test_app/.kamal/hooks/pre-build.sample +51 -0
  167. data/test_app/.kamal/hooks/pre-connect.sample +47 -0
  168. data/test_app/.kamal/hooks/pre-deploy.sample +122 -0
  169. data/test_app/.kamal/hooks/pre-proxy-reboot.sample +3 -0
  170. data/test_app/.kamal/secrets +20 -0
  171. data/test_app/.rubocop.yml +8 -0
  172. data/test_app/.ruby-version +1 -0
  173. data/test_app/Dockerfile +77 -0
  174. data/test_app/Gemfile +68 -0
  175. data/test_app/Gemfile.lock +587 -0
  176. data/test_app/README.md +24 -0
  177. data/test_app/Rakefile +6 -0
  178. data/test_app/app/assets/images/.keep +0 -0
  179. data/test_app/app/assets/stylesheets/application.css +10 -0
  180. data/test_app/app/assets/stylesheets/ui/accordion.css +74 -0
  181. data/test_app/app/assets/stylesheets/ui/alert.css +60 -0
  182. data/test_app/app/assets/stylesheets/ui/alert_dialog.css +108 -0
  183. data/test_app/app/assets/stylesheets/ui/avatar.css +53 -0
  184. data/test_app/app/assets/stylesheets/ui/badge.css +61 -0
  185. data/test_app/app/assets/stylesheets/ui/breadcrumb.css +55 -0
  186. data/test_app/app/assets/stylesheets/ui/button.css +125 -0
  187. data/test_app/app/assets/stylesheets/ui/card.css +63 -0
  188. data/test_app/app/assets/stylesheets/ui/checkbox.css +67 -0
  189. data/test_app/app/assets/stylesheets/ui/collapsible.css +55 -0
  190. data/test_app/app/assets/stylesheets/ui/dialog.css +133 -0
  191. data/test_app/app/assets/stylesheets/ui/dropdown.css +104 -0
  192. data/test_app/app/assets/stylesheets/ui/form.css +48 -0
  193. data/test_app/app/assets/stylesheets/ui/input.css +43 -0
  194. data/test_app/app/assets/stylesheets/ui/label.css +25 -0
  195. data/test_app/app/assets/stylesheets/ui/pagination.css +89 -0
  196. data/test_app/app/assets/stylesheets/ui/popover.css +94 -0
  197. data/test_app/app/assets/stylesheets/ui/progress.css +20 -0
  198. data/test_app/app/assets/stylesheets/ui/select.css +46 -0
  199. data/test_app/app/assets/stylesheets/ui/separator.css +21 -0
  200. data/test_app/app/assets/stylesheets/ui/sheet.css +193 -0
  201. data/test_app/app/assets/stylesheets/ui/skeleton.css +25 -0
  202. data/test_app/app/assets/stylesheets/ui/switch.css +81 -0
  203. data/test_app/app/assets/stylesheets/ui/table.css +86 -0
  204. data/test_app/app/assets/stylesheets/ui/tabs.css +72 -0
  205. data/test_app/app/assets/stylesheets/ui/textarea.css +39 -0
  206. data/test_app/app/assets/stylesheets/ui/toggle.css +89 -0
  207. data/test_app/app/assets/stylesheets/ui/tooltip.css +78 -0
  208. data/test_app/app/assets/stylesheets/uikit_rails.css +69 -0
  209. data/test_app/app/components/ui/accordion/component.html.erb +13 -0
  210. data/test_app/app/components/ui/accordion/component.rb +35 -0
  211. data/test_app/app/components/ui/accordion/preview.yml +81 -0
  212. data/test_app/app/components/ui/alert/component.html.erb +9 -0
  213. data/test_app/app/components/ui/alert/component.rb +27 -0
  214. data/test_app/app/components/ui/alert/preview.yml +53 -0
  215. data/test_app/app/components/ui/alert_dialog/component.html.erb +27 -0
  216. data/test_app/app/components/ui/alert_dialog/component.rb +23 -0
  217. data/test_app/app/components/ui/alert_dialog/preview.yml +94 -0
  218. data/test_app/app/components/ui/avatar/component.html.erb +7 -0
  219. data/test_app/app/components/ui/avatar/component.rb +31 -0
  220. data/test_app/app/components/ui/avatar/preview.yml +42 -0
  221. data/test_app/app/components/ui/badge/component.rb +28 -0
  222. data/test_app/app/components/ui/badge/preview.yml +38 -0
  223. data/test_app/app/components/ui/base_component.rb +32 -0
  224. data/test_app/app/components/ui/breadcrumb/component.html.erb +14 -0
  225. data/test_app/app/components/ui/breadcrumb/component.rb +40 -0
  226. data/test_app/app/components/ui/breadcrumb/preview.yml +42 -0
  227. data/test_app/app/components/ui/button/component.rb +44 -0
  228. data/test_app/app/components/ui/button/preview.yml +106 -0
  229. data/test_app/app/components/ui/card/component.html.erb +16 -0
  230. data/test_app/app/components/ui/card/component.rb +26 -0
  231. data/test_app/app/components/ui/card/preview.yml +57 -0
  232. data/test_app/app/components/ui/checkbox/component.html.erb +6 -0
  233. data/test_app/app/components/ui/checkbox/component.rb +26 -0
  234. data/test_app/app/components/ui/checkbox/preview.yml +43 -0
  235. data/test_app/app/components/ui/collapsible/component.html.erb +8 -0
  236. data/test_app/app/components/ui/collapsible/component.rb +18 -0
  237. data/test_app/app/components/ui/collapsible/preview.yml +65 -0
  238. data/test_app/app/components/ui/dialog/component.html.erb +23 -0
  239. data/test_app/app/components/ui/dialog/component.rb +20 -0
  240. data/test_app/app/components/ui/dialog/preview.yml +77 -0
  241. data/test_app/app/components/ui/dropdown/component.html.erb +14 -0
  242. data/test_app/app/components/ui/dropdown/component.rb +62 -0
  243. data/test_app/app/components/ui/dropdown/preview.yml +75 -0
  244. data/test_app/app/components/ui/form/USAGE +51 -0
  245. data/test_app/app/components/ui/form/builder.rb +233 -0
  246. data/test_app/app/components/ui/form/component.rb +258 -0
  247. data/test_app/app/components/ui/form/form.css +48 -0
  248. data/test_app/app/components/ui/form/preview.yml +95 -0
  249. data/test_app/app/components/ui/input/component.rb +25 -0
  250. data/test_app/app/components/ui/input/preview.yml +58 -0
  251. data/test_app/app/components/ui/label/component.rb +25 -0
  252. data/test_app/app/components/ui/label/preview.yml +34 -0
  253. data/test_app/app/components/ui/pagination/component.html.erb +7 -0
  254. data/test_app/app/components/ui/pagination/component.rb +90 -0
  255. data/test_app/app/components/ui/pagination/preview.yml +61 -0
  256. data/test_app/app/components/ui/popover/component.html.erb +8 -0
  257. data/test_app/app/components/ui/popover/component.rb +19 -0
  258. data/test_app/app/components/ui/popover/preview.yml +102 -0
  259. data/test_app/app/components/ui/progress/component.html.erb +3 -0
  260. data/test_app/app/components/ui/progress/component.rb +38 -0
  261. data/test_app/app/components/ui/progress/preview.yml +44 -0
  262. data/test_app/app/components/ui/select/component.rb +38 -0
  263. data/test_app/app/components/ui/select/preview.yml +61 -0
  264. data/test_app/app/components/ui/separator/component.rb +34 -0
  265. data/test_app/app/components/ui/separator/preview.yml +32 -0
  266. data/test_app/app/components/ui/sheet/component.html.erb +23 -0
  267. data/test_app/app/components/ui/sheet/component.rb +23 -0
  268. data/test_app/app/components/ui/sheet/preview.yml +105 -0
  269. data/test_app/app/components/ui/skeleton/component.rb +38 -0
  270. data/test_app/app/components/ui/skeleton/preview.yml +44 -0
  271. data/test_app/app/components/ui/switch/component.html.erb +19 -0
  272. data/test_app/app/components/ui/switch/component.rb +23 -0
  273. data/test_app/app/components/ui/switch/preview.yml +43 -0
  274. data/test_app/app/components/ui/table/component.html.erb +14 -0
  275. data/test_app/app/components/ui/table/component.rb +25 -0
  276. data/test_app/app/components/ui/table/preview.yml +109 -0
  277. data/test_app/app/components/ui/tabs/component.html.erb +10 -0
  278. data/test_app/app/components/ui/tabs/component.rb +35 -0
  279. data/test_app/app/components/ui/tabs/preview.yml +60 -0
  280. data/test_app/app/components/ui/textarea/component.rb +25 -0
  281. data/test_app/app/components/ui/textarea/preview.yml +47 -0
  282. data/test_app/app/components/ui/toggle/component.rb +39 -0
  283. data/test_app/app/components/ui/toggle/preview.yml +81 -0
  284. data/test_app/app/components/ui/tooltip/component.html.erb +8 -0
  285. data/test_app/app/components/ui/tooltip/component.rb +19 -0
  286. data/test_app/app/components/ui/tooltip/preview.yml +52 -0
  287. data/test_app/app/controllers/application_controller.rb +7 -0
  288. data/test_app/app/controllers/concerns/.keep +0 -0
  289. data/test_app/app/helpers/application_helper.rb +2 -0
  290. data/test_app/app/javascript/application.js +3 -0
  291. data/test_app/app/javascript/controllers/application.js +9 -0
  292. data/test_app/app/javascript/controllers/hello_controller.js +7 -0
  293. data/test_app/app/javascript/controllers/index.js +4 -0
  294. data/test_app/app/javascript/controllers/ui/accordion_controller.js +19 -0
  295. data/test_app/app/javascript/controllers/ui/alert_dialog_controller.js +25 -0
  296. data/test_app/app/javascript/controllers/ui/collapsible_controller.js +9 -0
  297. data/test_app/app/javascript/controllers/ui/dialog_controller.js +19 -0
  298. data/test_app/app/javascript/controllers/ui/dropdown_controller.js +47 -0
  299. data/test_app/app/javascript/controllers/ui/popover_controller.js +47 -0
  300. data/test_app/app/javascript/controllers/ui/sheet_controller.js +19 -0
  301. data/test_app/app/javascript/controllers/ui/tabs_controller.js +24 -0
  302. data/test_app/app/javascript/controllers/ui/tooltip_controller.js +13 -0
  303. data/test_app/app/jobs/application_job.rb +7 -0
  304. data/test_app/app/mailers/application_mailer.rb +4 -0
  305. data/test_app/app/models/application_record.rb +3 -0
  306. data/test_app/app/models/concerns/.keep +0 -0
  307. data/test_app/app/views/layouts/application.html.erb +29 -0
  308. data/test_app/app/views/layouts/mailer.html.erb +13 -0
  309. data/test_app/app/views/layouts/mailer.text.erb +1 -0
  310. data/test_app/app/views/pwa/manifest.json.erb +22 -0
  311. data/test_app/app/views/pwa/service-worker.js +26 -0
  312. data/test_app/bin/brakeman +7 -0
  313. data/test_app/bin/bundler-audit +6 -0
  314. data/test_app/bin/ci +6 -0
  315. data/test_app/bin/dev +2 -0
  316. data/test_app/bin/docker-entrypoint +8 -0
  317. data/test_app/bin/importmap +4 -0
  318. data/test_app/bin/jobs +6 -0
  319. data/test_app/bin/kamal +16 -0
  320. data/test_app/bin/rails +4 -0
  321. data/test_app/bin/rake +4 -0
  322. data/test_app/bin/rubocop +8 -0
  323. data/test_app/bin/setup +35 -0
  324. data/test_app/bin/thrust +5 -0
  325. data/test_app/config/application.rb +27 -0
  326. data/test_app/config/boot.rb +4 -0
  327. data/test_app/config/bundler-audit.yml +5 -0
  328. data/test_app/config/cable.yml +17 -0
  329. data/test_app/config/cache.yml +16 -0
  330. data/test_app/config/ci.rb +24 -0
  331. data/test_app/config/credentials.yml.enc +1 -0
  332. data/test_app/config/database.yml +40 -0
  333. data/test_app/config/deploy.yml +119 -0
  334. data/test_app/config/environment.rb +5 -0
  335. data/test_app/config/environments/development.rb +78 -0
  336. data/test_app/config/environments/production.rb +90 -0
  337. data/test_app/config/environments/test.rb +53 -0
  338. data/test_app/config/importmap.rb +7 -0
  339. data/test_app/config/initializers/assets.rb +7 -0
  340. data/test_app/config/initializers/content_security_policy.rb +29 -0
  341. data/test_app/config/initializers/filter_parameter_logging.rb +8 -0
  342. data/test_app/config/initializers/inflections.rb +16 -0
  343. data/test_app/config/locales/en.yml +31 -0
  344. data/test_app/config/puma.rb +42 -0
  345. data/test_app/config/queue.yml +18 -0
  346. data/test_app/config/recurring.yml +15 -0
  347. data/test_app/config/routes.rb +13 -0
  348. data/test_app/config/storage.yml +27 -0
  349. data/test_app/config.ru +6 -0
  350. data/test_app/db/cable_schema.rb +11 -0
  351. data/test_app/db/cache_schema.rb +12 -0
  352. data/test_app/db/queue_schema.rb +129 -0
  353. data/test_app/db/seeds.rb +9 -0
  354. data/test_app/lib/tasks/.keep +0 -0
  355. data/test_app/log/.keep +0 -0
  356. data/test_app/public/400.html +135 -0
  357. data/test_app/public/404.html +135 -0
  358. data/test_app/public/406-unsupported-browser.html +135 -0
  359. data/test_app/public/422.html +135 -0
  360. data/test_app/public/500.html +135 -0
  361. data/test_app/public/icon.png +0 -0
  362. data/test_app/public/icon.svg +3 -0
  363. data/test_app/public/robots.txt +1 -0
  364. data/test_app/script/.keep +0 -0
  365. data/test_app/storage/.keep +0 -0
  366. data/test_app/test/controllers/.keep +0 -0
  367. data/test_app/test/fixtures/files/.keep +0 -0
  368. data/test_app/test/helpers/.keep +0 -0
  369. data/test_app/test/integration/.keep +0 -0
  370. data/test_app/test/mailers/.keep +0 -0
  371. data/test_app/test/models/.keep +0 -0
  372. data/test_app/test/test_helper.rb +15 -0
  373. data/test_app/tmp/.keep +0 -0
  374. data/test_app/tmp/pids/.keep +0 -0
  375. data/test_app/tmp/storage/.keep +0 -0
  376. data/test_app/vendor/.keep +0 -0
  377. data/test_app/vendor/javascript/.keep +0 -0
  378. metadata +448 -0
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ui
4
+ module Select
5
+ # Styled native select dropdown.
6
+ class Component < Ui::BaseComponent
7
+ attr_reader :options, :prompt, :selected, :html_attrs
8
+
9
+ def initialize(options: [], prompt: nil, selected: nil, **html_attrs)
10
+ @options = options
11
+ @prompt = prompt
12
+ @selected = selected
13
+ @html_attrs = html_attrs
14
+ super()
15
+ end
16
+
17
+ def call
18
+ content_tag(:select, options_html, **computed_attrs)
19
+ end
20
+
21
+ private
22
+
23
+ def computed_attrs
24
+ merge_attrs({ class: "ui-select" }, html_attrs)
25
+ end
26
+
27
+ def options_html
28
+ html = "".html_safe
29
+ html += content_tag(:option, prompt, value: "", disabled: true, selected: selected.nil?) if prompt
30
+ options.each do |opt|
31
+ label, value = opt.is_a?(Array) ? opt : [opt, opt]
32
+ html += content_tag(:option, label, value: value, selected: value.to_s == selected.to_s)
33
+ end
34
+ html
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,61 @@
1
+ description: A styled native select dropdown. Accepts an array of options (strings or [label, value] pairs), an optional prompt placeholder, and all standard HTML select attributes.
2
+
3
+ sections:
4
+ - title: Basic Usage
5
+ examples:
6
+ - title: With string options
7
+ code: |
8
+ <%= render Ui::Select::Component.new(
9
+ options: ["Apple", "Banana", "Cherry"],
10
+ prompt: "Select a fruit",
11
+ name: "fruit"
12
+ ) %>
13
+
14
+ - title: With label-value pairs
15
+ code: |
16
+ <%= render Ui::Select::Component.new(
17
+ options: [["United States", "us"], ["Canada", "ca"], ["Mexico", "mx"]],
18
+ prompt: "Select a country",
19
+ name: "country"
20
+ ) %>
21
+
22
+ - title: Pre-selected Value
23
+ examples:
24
+ - title: Selected option
25
+ code: |
26
+ <%= render Ui::Select::Component.new(
27
+ options: [["Small", "sm"], ["Medium", "md"], ["Large", "lg"]],
28
+ selected: "md",
29
+ name: "size"
30
+ ) %>
31
+
32
+ - title: States
33
+ examples:
34
+ - title: Disabled
35
+ code: |
36
+ <%= render Ui::Select::Component.new(
37
+ options: ["Option A", "Option B"],
38
+ prompt: "Disabled select",
39
+ disabled: true,
40
+ name: "disabled_select"
41
+ ) %>
42
+
43
+ - title: Required
44
+ code: |
45
+ <%= render Ui::Select::Component.new(
46
+ options: ["Draft", "Published", "Archived"],
47
+ prompt: "Select status",
48
+ required: true,
49
+ name: "status"
50
+ ) %>
51
+
52
+ - title: With Custom Attributes
53
+ examples:
54
+ - title: Custom data attributes
55
+ code: |
56
+ <%= render Ui::Select::Component.new(
57
+ options: ["Red", "Green", "Blue"],
58
+ prompt: "Pick a color",
59
+ name: "color",
60
+ data: { controller: "color-picker", action: "change->color-picker#update" }
61
+ ) %>
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ui
4
+ module Separator
5
+ # Visual divider between content sections.
6
+ class Component < Ui::BaseComponent
7
+ attr_reader :orientation, :decorative, :html_attrs
8
+
9
+ def initialize(orientation: :horizontal, decorative: false, **html_attrs)
10
+ @orientation = orientation.to_sym
11
+ @decorative = decorative
12
+ @html_attrs = html_attrs
13
+ super()
14
+ end
15
+
16
+ def call
17
+ tag.div(**computed_attrs)
18
+ end
19
+
20
+ private
21
+
22
+ def computed_attrs
23
+ merge_attrs(
24
+ {
25
+ class: class_names("ui-separator", "ui-separator--#{orientation}"),
26
+ role: decorative ? "none" : "separator",
27
+ "aria-orientation": orientation == :vertical ? "vertical" : nil
28
+ }.compact,
29
+ html_attrs
30
+ )
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,32 @@
1
+ description: A visual divider used to separate content sections. Supports horizontal and vertical orientations, with an optional decorative mode that hides the element from assistive technology.
2
+
3
+ sections:
4
+ - title: Orientation
5
+ examples:
6
+ - title: Horizontal (default)
7
+ code: |
8
+ <p>Above</p>
9
+ <%= render Ui::Separator::Component.new %>
10
+ <p>Below</p>
11
+
12
+ - title: Vertical
13
+ code: |
14
+ <div style="display: flex; align-items: center; height: 1.5rem; gap: 0.75rem;">
15
+ <span>Left</span>
16
+ <%= render Ui::Separator::Component.new(orientation: :vertical) %>
17
+ <span>Right</span>
18
+ </div>
19
+
20
+ - title: Decorative
21
+ examples:
22
+ - title: Decorative separator (hidden from screen readers)
23
+ code: |
24
+ <p>Section A</p>
25
+ <%= render Ui::Separator::Component.new(decorative: true) %>
26
+ <p>Section B</p>
27
+
28
+ - title: With Custom Attributes
29
+ examples:
30
+ - title: Custom class and margin
31
+ code: |
32
+ <%= render Ui::Separator::Component.new(class: "my-divider", style: "margin: 1.5rem 0;") %>
@@ -0,0 +1,23 @@
1
+ <div data-controller="ui--sheet" <%= tag.attributes(html_attrs) %>>
2
+ <% if trigger? %>
3
+ <div data-action="click->ui--sheet#open"><%= trigger %></div>
4
+ <% end %>
5
+ <dialog class="ui-sheet" data-ui--sheet-target="dialog">
6
+ <div class="ui-sheet__overlay" data-action="click->ui--sheet#close"></div>
7
+ <div class="ui-sheet__content ui-sheet__content--<%= side %>">
8
+ <% if title? || description? %>
9
+ <div class="ui-sheet__header">
10
+ <% if title? %><h2 class="ui-sheet__title"><%= title %></h2><% end %>
11
+ <% if description? %><p class="ui-sheet__description"><%= description %></p><% end %>
12
+ </div>
13
+ <% end %>
14
+ <div class="ui-sheet__body"><%= content %></div>
15
+ <% if footer? %>
16
+ <div class="ui-sheet__footer"><%= footer %></div>
17
+ <% end %>
18
+ <button class="ui-sheet__close" data-action="click->ui--sheet#close" aria-label="Close">
19
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>
20
+ </button>
21
+ </div>
22
+ </dialog>
23
+ </div>
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ui
4
+ module Sheet
5
+ # Slide-over panel from any side of the screen.
6
+ class Component < Ui::BaseComponent
7
+ SIDES = %i[top right bottom left].freeze
8
+
9
+ renders_one :trigger
10
+ renders_one :title
11
+ renders_one :description
12
+ renders_one :footer
13
+
14
+ attr_reader :side, :html_attrs
15
+
16
+ def initialize(side: :right, **html_attrs)
17
+ @side = side.to_sym
18
+ @html_attrs = html_attrs
19
+ super()
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,105 @@
1
+ description: A slide-over panel that enters from any side of the screen. Uses the native HTML <dialog> element for accessibility and supports title, description, body content, and footer slots.
2
+
3
+ sections:
4
+ - title: Basic Sheet
5
+ examples:
6
+ - title: Right side (default)
7
+ code: |
8
+ <%= render Ui::Sheet::Component.new do |sheet| %>
9
+ <% sheet.with_trigger do %>
10
+ <%= render Ui::Button::Component.new do %>Open Sheet<% end %>
11
+ <% end %>
12
+ <% sheet.with_title do %>Sheet Title<% end %>
13
+ <% sheet.with_description do %>This is a slide-over panel from the right.<% end %>
14
+ <p>Main content goes here. You can place forms, lists, or any other content inside the sheet body.</p>
15
+ <% sheet.with_footer do %>
16
+ <%= render Ui::Button::Component.new(variant: :outline, data: { action: "click->ui--sheet#close" }) do %>Cancel<% end %>
17
+ <%= render Ui::Button::Component.new do %>Save<% end %>
18
+ <% end %>
19
+ <% end %>
20
+
21
+ - title: Side Variants
22
+ examples:
23
+ - title: Left side
24
+ code: |
25
+ <%= render Ui::Sheet::Component.new(side: :left) do |sheet| %>
26
+ <% sheet.with_trigger do %>
27
+ <%= render Ui::Button::Component.new(variant: :outline) do %>Open Left<% end %>
28
+ <% end %>
29
+ <% sheet.with_title do %>Navigation<% end %>
30
+ <% sheet.with_description do %>Browse the site sections.<% end %>
31
+ <ul style="list-style:none;padding:0;margin:0;">
32
+ <li style="padding:0.5rem 0;border-bottom:1px solid var(--ui-border);">Dashboard</li>
33
+ <li style="padding:0.5rem 0;border-bottom:1px solid var(--ui-border);">Settings</li>
34
+ <li style="padding:0.5rem 0;">Profile</li>
35
+ </ul>
36
+ <% end %>
37
+
38
+ - title: Top side
39
+ code: |
40
+ <%= render Ui::Sheet::Component.new(side: :top) do |sheet| %>
41
+ <% sheet.with_trigger do %>
42
+ <%= render Ui::Button::Component.new(variant: :outline) do %>Open Top<% end %>
43
+ <% end %>
44
+ <% sheet.with_title do %>Notifications<% end %>
45
+ <% sheet.with_description do %>You have 3 unread notifications.<% end %>
46
+ <p>Notification content slides down from the top of the screen.</p>
47
+ <% end %>
48
+
49
+ - title: Bottom side
50
+ code: |
51
+ <%= render Ui::Sheet::Component.new(side: :bottom) do |sheet| %>
52
+ <% sheet.with_trigger do %>
53
+ <%= render Ui::Button::Component.new(variant: :outline) do %>Open Bottom<% end %>
54
+ <% end %>
55
+ <% sheet.with_title do %>Quick Actions<% end %>
56
+ <p>Action panel that slides up from the bottom.</p>
57
+ <% sheet.with_footer do %>
58
+ <%= render Ui::Button::Component.new(variant: :outline, data: { action: "click->ui--sheet#close" }) do %>Dismiss<% end %>
59
+ <% end %>
60
+ <% end %>
61
+
62
+ - title: Sheet with Form
63
+ examples:
64
+ - title: Edit profile sheet
65
+ code: |
66
+ <%= render Ui::Sheet::Component.new do |sheet| %>
67
+ <% sheet.with_trigger do %>
68
+ <%= render Ui::Button::Component.new do %>Edit Profile<% end %>
69
+ <% end %>
70
+ <% sheet.with_title do %>Edit Profile<% end %>
71
+ <% sheet.with_description do %>Make changes to your profile. Click save when you're done.<% end %>
72
+ <div style="display:flex;flex-direction:column;gap:1rem;">
73
+ <div>
74
+ <label style="font-size:var(--ui-font-size-sm);font-weight:500;">Name</label>
75
+ <input type="text" value="Jane Doe" style="width:100%;padding:0.5rem;border:1px solid var(--ui-border);border-radius:var(--ui-radius);margin-top:0.25rem;" />
76
+ </div>
77
+ <div>
78
+ <label style="font-size:var(--ui-font-size-sm);font-weight:500;">Email</label>
79
+ <input type="email" value="jane@example.com" style="width:100%;padding:0.5rem;border:1px solid var(--ui-border);border-radius:var(--ui-radius);margin-top:0.25rem;" />
80
+ </div>
81
+ <div>
82
+ <label style="font-size:var(--ui-font-size-sm);font-weight:500;">Bio</label>
83
+ <textarea rows="3" style="width:100%;padding:0.5rem;border:1px solid var(--ui-border);border-radius:var(--ui-radius);margin-top:0.25rem;resize:vertical;">Developer and designer.</textarea>
84
+ </div>
85
+ </div>
86
+ <% sheet.with_footer do %>
87
+ <%= render Ui::Button::Component.new(variant: :outline, data: { action: "click->ui--sheet#close" }) do %>Cancel<% end %>
88
+ <%= render Ui::Button::Component.new do %>Save changes<% end %>
89
+ <% end %>
90
+ <% end %>
91
+
92
+ - title: Custom Attributes
93
+ examples:
94
+ - title: Sheet with custom class
95
+ code: |
96
+ <%= render Ui::Sheet::Component.new(side: :right, class: "my-custom-sheet", data: { turbo_frame: "panel" }) do |sheet| %>
97
+ <% sheet.with_trigger do %>
98
+ <%= render Ui::Button::Component.new(variant: :secondary) do %>Open<% end %>
99
+ <% end %>
100
+ <% sheet.with_title do %>Custom Sheet<% end %>
101
+ <p>This sheet has custom attributes applied to the wrapper.</p>
102
+ <% sheet.with_footer do %>
103
+ <%= render Ui::Button::Component.new(variant: :outline, data: { action: "click->ui--sheet#close" }) do %>Close<% end %>
104
+ <% end %>
105
+ <% end %>
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ui
4
+ module Skeleton
5
+ # Animated placeholder for loading states.
6
+ class Component < Ui::BaseComponent
7
+ attr_reader :width, :height, :rounded, :html_attrs
8
+
9
+ def initialize(width: nil, height: nil, rounded: true, **html_attrs)
10
+ @width = width
11
+ @height = height
12
+ @rounded = rounded
13
+ @html_attrs = html_attrs
14
+ super()
15
+ end
16
+
17
+ def call
18
+ tag.div(**computed_attrs)
19
+ end
20
+
21
+ private
22
+
23
+ def computed_attrs
24
+ styles = []
25
+ styles << "width: #{width}" if width
26
+ styles << "height: #{height}" if height
27
+
28
+ merge_attrs(
29
+ {
30
+ class: class_names("ui-skeleton", "ui-skeleton--rounded": rounded),
31
+ style: styles.any? ? styles.join("; ") : nil
32
+ }.compact,
33
+ html_attrs
34
+ )
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,44 @@
1
+ description: An animated placeholder block used to indicate loading states. Supports custom dimensions and optional rounded corners.
2
+
3
+ sections:
4
+ - title: Basic
5
+ examples:
6
+ - title: Default skeleton line
7
+ code: |
8
+ <%= render Ui::Skeleton::Component.new(width: "100%", height: "1rem") %>
9
+
10
+ - title: Paragraph placeholder
11
+ code: |
12
+ <div style="display: flex; flex-direction: column; gap: 0.5rem;">
13
+ <%= render Ui::Skeleton::Component.new(width: "100%", height: "1rem") %>
14
+ <%= render Ui::Skeleton::Component.new(width: "80%", height: "1rem") %>
15
+ <%= render Ui::Skeleton::Component.new(width: "60%", height: "1rem") %>
16
+ </div>
17
+
18
+ - title: Shapes
19
+ examples:
20
+ - title: Circle (avatar placeholder)
21
+ code: |
22
+ <%= render Ui::Skeleton::Component.new(width: "2.5rem", height: "2.5rem", style: "border-radius: 9999px;") %>
23
+
24
+ - title: Square (no rounding)
25
+ code: |
26
+ <%= render Ui::Skeleton::Component.new(width: "4rem", height: "4rem", rounded: false) %>
27
+
28
+ - title: Card Placeholder
29
+ examples:
30
+ - title: Card skeleton layout
31
+ code: |
32
+ <div style="display: flex; align-items: center; gap: 1rem;">
33
+ <%= render Ui::Skeleton::Component.new(width: "2.5rem", height: "2.5rem", style: "border-radius: 9999px;") %>
34
+ <div style="display: flex; flex-direction: column; gap: 0.5rem; flex: 1;">
35
+ <%= render Ui::Skeleton::Component.new(width: "50%", height: "1rem") %>
36
+ <%= render Ui::Skeleton::Component.new(width: "80%", height: "0.75rem") %>
37
+ </div>
38
+ </div>
39
+
40
+ - title: With Custom Attributes
41
+ examples:
42
+ - title: Custom class
43
+ code: |
44
+ <%= render Ui::Skeleton::Component.new(width: "100%", height: "1rem", class: "my-skeleton") %>
@@ -0,0 +1,19 @@
1
+ <div class="ui-switch__wrapper">
2
+ <input
3
+ type="checkbox"
4
+ class="ui-switch__input"
5
+ id="<%= input_id %>"
6
+ <% if checked %>checked<% end %>
7
+ <% if html_attrs[:disabled] %>disabled<% end %>
8
+ <% if html_attrs[:name] %>name="<%= html_attrs[:name] %>"<% end %>
9
+ <% if html_attrs[:value] %>value="<%= html_attrs[:value] %>"<% end %>
10
+ role="switch"
11
+ aria-checked="<%= checked %>"
12
+ />
13
+ <label class="ui-switch" for="<%= input_id %>">
14
+ <span class="ui-switch__thumb"></span>
15
+ </label>
16
+ <% if label %>
17
+ <label class="ui-switch__label" for="<%= input_id %>"><%= label %></label>
18
+ <% end %>
19
+ </div>
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ui
4
+ module Switch
5
+ # Toggle switch for boolean settings.
6
+ class Component < Ui::BaseComponent
7
+ attr_reader :label, :checked, :html_attrs
8
+
9
+ def initialize(label: nil, checked: false, **html_attrs)
10
+ @label = label
11
+ @checked = checked
12
+ @html_attrs = html_attrs
13
+ super()
14
+ end
15
+
16
+ private
17
+
18
+ def input_id
19
+ html_attrs[:id] || "switch_#{object_id}"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,43 @@
1
+ description: A toggle switch for boolean settings. Pure CSS implementation using a hidden checkbox and styled label. No JavaScript required.
2
+
3
+ sections:
4
+ - title: Basic Usage
5
+ examples:
6
+ - title: Default (off)
7
+ code: |
8
+ <%= render Ui::Switch::Component.new(name: "notifications", id: "notifications") %>
9
+
10
+ - title: With label
11
+ code: |
12
+ <%= render Ui::Switch::Component.new(label: "Enable notifications", name: "notifications", id: "notif_label") %>
13
+
14
+ - title: States
15
+ examples:
16
+ - title: Checked (on)
17
+ code: |
18
+ <%= render Ui::Switch::Component.new(label: "Dark mode", checked: true, name: "dark_mode", id: "dark_mode") %>
19
+
20
+ - title: Disabled (off)
21
+ code: |
22
+ <%= render Ui::Switch::Component.new(label: "Unavailable feature", disabled: true, name: "unavailable", id: "unavailable") %>
23
+
24
+ - title: Disabled (on)
25
+ code: |
26
+ <%= render Ui::Switch::Component.new(label: "Always on", checked: true, disabled: true, name: "always_on", id: "always_on") %>
27
+
28
+ - title: Form Integration
29
+ examples:
30
+ - title: With value
31
+ code: |
32
+ <%= render Ui::Switch::Component.new(label: "Accept terms", name: "terms", value: "1", id: "terms_switch") %>
33
+
34
+ - title: With Custom Attributes
35
+ examples:
36
+ - title: Custom data attributes
37
+ code: |
38
+ <%= render Ui::Switch::Component.new(
39
+ label: "Auto-save",
40
+ name: "auto_save",
41
+ id: "auto_save",
42
+ data: { controller: "settings", action: "change->settings#toggle" }
43
+ ) %>
@@ -0,0 +1,14 @@
1
+ <div class="ui-table__wrapper">
2
+ <table class="ui-table" <%= tag.attributes(html_attrs) %>>
3
+ <% if caption? %>
4
+ <caption class="ui-table__caption"><%= caption %></caption>
5
+ <% end %>
6
+ <% if header? %>
7
+ <thead class="ui-table__head"><%= header %></thead>
8
+ <% end %>
9
+ <tbody class="ui-table__body"><%= content %></tbody>
10
+ <% if footer? %>
11
+ <tfoot class="ui-table__foot"><%= footer %></tfoot>
12
+ <% end %>
13
+ </table>
14
+ </div>
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ui
4
+ module Table
5
+ # Styled data table with header, body, and footer slots.
6
+ class Component < Ui::BaseComponent
7
+ renders_one :caption
8
+ renders_one :header
9
+ renders_one :footer
10
+
11
+ attr_reader :html_attrs
12
+
13
+ def initialize(**html_attrs)
14
+ @html_attrs = html_attrs
15
+ super()
16
+ end
17
+
18
+ private
19
+
20
+ def computed_attrs
21
+ merge_attrs({ class: "ui-table__wrapper" }, html_attrs)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,109 @@
1
+ description: A styled data table with optional caption, header, body, and footer slots. Supports responsive horizontal scrolling.
2
+
3
+ sections:
4
+ - title: Basic Table
5
+ examples:
6
+ - title: With header and rows
7
+ code: |
8
+ <%= render Ui::Table::Component.new do |table| %>
9
+ <% table.with_header do %>
10
+ <tr>
11
+ <th>Invoice</th>
12
+ <th>Status</th>
13
+ <th>Method</th>
14
+ <th class="text-right">Amount</th>
15
+ </tr>
16
+ <% end %>
17
+ <tr>
18
+ <td>INV-001</td>
19
+ <td>Paid</td>
20
+ <td>Credit Card</td>
21
+ <td class="text-right">$250.00</td>
22
+ </tr>
23
+ <tr>
24
+ <td>INV-002</td>
25
+ <td>Pending</td>
26
+ <td>PayPal</td>
27
+ <td class="text-right">$150.00</td>
28
+ </tr>
29
+ <tr>
30
+ <td>INV-003</td>
31
+ <td>Unpaid</td>
32
+ <td>Bank Transfer</td>
33
+ <td class="text-right">$350.00</td>
34
+ </tr>
35
+ <tr>
36
+ <td>INV-004</td>
37
+ <td>Paid</td>
38
+ <td>Credit Card</td>
39
+ <td class="text-right">$450.00</td>
40
+ </tr>
41
+ <tr>
42
+ <td>INV-005</td>
43
+ <td>Paid</td>
44
+ <td>PayPal</td>
45
+ <td class="text-right">$550.00</td>
46
+ </tr>
47
+ <% end %>
48
+
49
+ - title: With Caption
50
+ examples:
51
+ - title: Table with caption
52
+ code: |
53
+ <%= render Ui::Table::Component.new do |table| %>
54
+ <% table.with_caption do %>
55
+ A list of recent invoices.
56
+ <% end %>
57
+ <% table.with_header do %>
58
+ <tr>
59
+ <th>Invoice</th>
60
+ <th>Status</th>
61
+ <th class="text-right">Amount</th>
62
+ </tr>
63
+ <% end %>
64
+ <tr>
65
+ <td>INV-001</td>
66
+ <td>Paid</td>
67
+ <td class="text-right">$250.00</td>
68
+ </tr>
69
+ <tr>
70
+ <td>INV-002</td>
71
+ <td>Pending</td>
72
+ <td class="text-right">$150.00</td>
73
+ </tr>
74
+ <% end %>
75
+
76
+ - title: With Footer
77
+ examples:
78
+ - title: Table with footer totals
79
+ code: |
80
+ <%= render Ui::Table::Component.new do |table| %>
81
+ <% table.with_header do %>
82
+ <tr>
83
+ <th>Invoice</th>
84
+ <th>Status</th>
85
+ <th class="text-right">Amount</th>
86
+ </tr>
87
+ <% end %>
88
+ <tr>
89
+ <td>INV-001</td>
90
+ <td>Paid</td>
91
+ <td class="text-right">$250.00</td>
92
+ </tr>
93
+ <tr>
94
+ <td>INV-002</td>
95
+ <td>Pending</td>
96
+ <td class="text-right">$150.00</td>
97
+ </tr>
98
+ <tr>
99
+ <td>INV-003</td>
100
+ <td>Unpaid</td>
101
+ <td class="text-right">$350.00</td>
102
+ </tr>
103
+ <% table.with_footer do %>
104
+ <tr>
105
+ <td colspan="2"><strong>Total</strong></td>
106
+ <td class="text-right"><strong>$750.00</strong></td>
107
+ </tr>
108
+ <% end %>
109
+ <% end %>
@@ -0,0 +1,10 @@
1
+ <div data-controller="ui--tabs" data-ui--tabs-default-value="<%= default_tab || tabs.first&.id %>" class="ui-tabs" <%= tag.attributes(html_attrs) %>>
2
+ <div class="ui-tabs__list" role="tablist">
3
+ <% tabs.each do |tab| %>
4
+ <button class="ui-tabs__trigger" role="tab" data-action="click->ui--tabs#select" data-ui--tabs-id-param="<%= tab.id %>" data-ui--tabs-target="trigger" id="tab-<%= tab.id %>" aria-controls="panel-<%= tab.id %>"><%= tab.label %></button>
5
+ <% end %>
6
+ </div>
7
+ <% tabs.each do |tab| %>
8
+ <div class="ui-tabs__panel" role="tabpanel" data-ui--tabs-target="panel" data-tab-id="<%= tab.id %>" id="panel-<%= tab.id %>" aria-labelledby="tab-<%= tab.id %>" hidden><%= tab.to_s %></div>
9
+ <% end %>
10
+ </div>