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 Progress
5
+ # Progress bar showing completion percentage.
6
+ class Component < Ui::BaseComponent
7
+ attr_reader :value, :max, :html_attrs
8
+
9
+ def initialize(value: 0, max: 100, **html_attrs)
10
+ @value = value.to_i
11
+ @max = max.to_i
12
+ @html_attrs = html_attrs
13
+ super()
14
+ end
15
+
16
+ def percentage
17
+ return 0 if max.zero?
18
+
19
+ [(value.to_f / max * 100).round, 100].min
20
+ end
21
+
22
+ private
23
+
24
+ def computed_attrs
25
+ merge_attrs(
26
+ {
27
+ class: "ui-progress",
28
+ role: "progressbar",
29
+ "aria-valuenow": value,
30
+ "aria-valuemin": 0,
31
+ "aria-valuemax": max
32
+ },
33
+ html_attrs
34
+ )
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,44 @@
1
+ description: An accessible progress bar that visually indicates completion percentage. Includes ARIA attributes for screen readers and smooth width transitions.
2
+
3
+ sections:
4
+ - title: Basic Usage
5
+ examples:
6
+ - title: Empty (0%)
7
+ code: |
8
+ <%= render Ui::Progress::Component.new(value: 0) %>
9
+
10
+ - title: Partial (45%)
11
+ code: |
12
+ <%= render Ui::Progress::Component.new(value: 45) %>
13
+
14
+ - title: Complete (100%)
15
+ code: |
16
+ <%= render Ui::Progress::Component.new(value: 100) %>
17
+
18
+ - title: Custom Max
19
+ examples:
20
+ - title: 3 of 5 steps
21
+ code: |
22
+ <%= render Ui::Progress::Component.new(value: 3, max: 5) %>
23
+
24
+ - title: 7 of 10 items
25
+ code: |
26
+ <%= render Ui::Progress::Component.new(value: 7, max: 10) %>
27
+
28
+ - title: With Labels
29
+ examples:
30
+ - title: Progress with percentage label
31
+ code: |
32
+ <div style="display: flex; flex-direction: column; gap: 0.25rem;">
33
+ <div style="display: flex; justify-content: space-between; font-size: 0.875rem;">
34
+ <span>Uploading…</span>
35
+ <span>65%</span>
36
+ </div>
37
+ <%= render Ui::Progress::Component.new(value: 65) %>
38
+ </div>
39
+
40
+ - title: With Custom Attributes
41
+ examples:
42
+ - title: Custom class and data attributes
43
+ code: |
44
+ <%= render Ui::Progress::Component.new(value: 50, class: "my-progress", data: { controller: "upload" }) %>
@@ -0,0 +1,20 @@
1
+ /* ============================================
2
+ * UikitRails — Progress
3
+ *
4
+ * Accessible progress bar with smooth transitions
5
+ * ============================================ */
6
+
7
+ .ui-progress {
8
+ width: 100%;
9
+ height: 0.625rem;
10
+ overflow: hidden;
11
+ border-radius: 9999px;
12
+ background-color: var(--ui-muted);
13
+ }
14
+
15
+ .ui-progress__bar {
16
+ height: 100%;
17
+ background-color: var(--ui-primary);
18
+ border-radius: 9999px;
19
+ transition: width var(--ui-transition-speed) ease;
20
+ }
@@ -0,0 +1,19 @@
1
+ Basic select with string options:
2
+
3
+ <%= render Ui::Select::Component.new(options: ["Apple", "Banana", "Cherry"], prompt: "Select a fruit", name: "fruit") %>
4
+
5
+ With [label, value] pairs:
6
+
7
+ <%= render Ui::Select::Component.new(options: [["Small", "sm"], ["Large", "lg"]], name: "size") %>
8
+
9
+ Pre-selected value:
10
+
11
+ <%= render Ui::Select::Component.new(options: [["Draft", "draft"], ["Published", "published"]], selected: "published", name: "status") %>
12
+
13
+ Disabled:
14
+
15
+ <%= render Ui::Select::Component.new(options: ["A", "B"], prompt: "Disabled", disabled: true, name: "off") %>
16
+
17
+ With custom attributes:
18
+
19
+ <%= render Ui::Select::Component.new(options: ["Red", "Blue"], name: "color", data: { action: "change->ctrl#run" }) %>
@@ -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,46 @@
1
+ /* ============================================
2
+ * UikitRails — Select
3
+ *
4
+ * Styled native select dropdown.
5
+ * ============================================ */
6
+
7
+ .ui-select {
8
+ display: flex;
9
+ width: 100%;
10
+ height: 2.5rem;
11
+ padding: 0.5rem 2.5rem 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
+ appearance: none;
20
+ -webkit-appearance: none;
21
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
22
+ background-repeat: no-repeat;
23
+ background-position: right 0.75rem center;
24
+ background-size: 1rem;
25
+ cursor: pointer;
26
+ transition:
27
+ border-color var(--ui-transition-speed) ease,
28
+ box-shadow var(--ui-transition-speed) ease;
29
+ }
30
+
31
+ .ui-select:focus {
32
+ outline: none;
33
+ border-color: var(--ui-ring);
34
+ box-shadow: 0 0 0 1px var(--ui-ring);
35
+ }
36
+
37
+ .ui-select:disabled {
38
+ opacity: 0.5;
39
+ cursor: not-allowed;
40
+ background-color: var(--ui-muted);
41
+ }
42
+
43
+ .ui-select:invalid,
44
+ .ui-select option[disabled] {
45
+ color: var(--ui-muted-foreground);
46
+ }
@@ -0,0 +1,15 @@
1
+ Horizontal separator (default):
2
+
3
+ <%= render Ui::Separator::Component.new %>
4
+
5
+ Vertical separator (parent must define height):
6
+
7
+ <%= render Ui::Separator::Component.new(orientation: :vertical) %>
8
+
9
+ Decorative (hidden from screen readers):
10
+
11
+ <%= render Ui::Separator::Component.new(decorative: true) %>
12
+
13
+ With custom attributes:
14
+
15
+ <%= render Ui::Separator::Component.new(class: "extra", style: "margin: 2rem 0;") %>
@@ -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,21 @@
1
+ /* ============================================
2
+ * UikitRails — Separator
3
+ *
4
+ * Orientations: horizontal, vertical
5
+ * ============================================ */
6
+
7
+ .ui-separator {
8
+ flex-shrink: 0;
9
+ background-color: var(--ui-border);
10
+ }
11
+
12
+ .ui-separator--horizontal {
13
+ width: 100%;
14
+ height: 1px;
15
+ }
16
+
17
+ .ui-separator--vertical {
18
+ width: 1px;
19
+ height: 100%;
20
+ align-self: stretch;
21
+ }
@@ -0,0 +1,44 @@
1
+ Basic sheet (slides from right):
2
+
3
+ <%= render Ui::Sheet::Component.new do |sheet| %>
4
+ <% sheet.with_trigger do %>
5
+ <%= render Ui::Button::Component.new do %>Open<% end %>
6
+ <% end %>
7
+ <% sheet.with_title do %>Sheet Title<% end %>
8
+ <% sheet.with_description do %>A short description.<% end %>
9
+ <p>Body content goes here.</p>
10
+ <% sheet.with_footer do %>
11
+ <%= render Ui::Button::Component.new(variant: :outline, data: { action: "click->ui--sheet#close" }) do %>Cancel<% end %>
12
+ <%= render Ui::Button::Component.new do %>Confirm<% end %>
13
+ <% end %>
14
+ <% end %>
15
+
16
+ Side variants (top, right, bottom, left):
17
+
18
+ <%= render Ui::Sheet::Component.new(side: :left) do |sheet| %>
19
+ <% sheet.with_trigger do %>Open Left<% end %>
20
+ <% sheet.with_title do %>Navigation<% end %>
21
+ <p>Content</p>
22
+ <% end %>
23
+
24
+ <%= render Ui::Sheet::Component.new(side: :bottom) do |sheet| %>
25
+ <% sheet.with_trigger do %>Open Bottom<% end %>
26
+ <p>Content</p>
27
+ <% end %>
28
+
29
+ Slots:
30
+ trigger — Element that opens the sheet on click
31
+ title — Sheet heading (rendered as <h2>)
32
+ description — Subtitle text below the title
33
+ footer — Bottom area, typically for action buttons
34
+ content — Main body (default slot)
35
+
36
+ Close from inside the sheet:
37
+ Use data-action="click->ui--sheet#close" on any element inside.
38
+
39
+ With custom attributes:
40
+
41
+ <%= render Ui::Sheet::Component.new(side: :right, class: "extra", data: { turbo: false }) do |sheet| %>
42
+ <% sheet.with_title do %>Title<% end %>
43
+ <p>Content</p>
44
+ <% end %>
@@ -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 %>