poetry-ui 0.0.2

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 (442) hide show
  1. checksums.yaml +7 -0
  2. data/.gitattributes +6 -0
  3. data/CHANGELOG.md +3 -0
  4. data/LICENSE.txt +21 -0
  5. data/README.md +87 -0
  6. data/THIRD_PARTY_NOTICES.md +201 -0
  7. data/app/components/poetry/ui/accordion/component.html.erb +3 -0
  8. data/app/components/poetry/ui/accordion/component.rb +197 -0
  9. data/app/components/poetry/ui/accordion/preview.rb +39 -0
  10. data/app/components/poetry/ui/accordion/style.rb +37 -0
  11. data/app/components/poetry/ui/alert/component.html.erb +6 -0
  12. data/app/components/poetry/ui/alert/component.rb +61 -0
  13. data/app/components/poetry/ui/alert/preview.rb +35 -0
  14. data/app/components/poetry/ui/alert/style.rb +24 -0
  15. data/app/components/poetry/ui/alert_dialog/component.html.erb +17 -0
  16. data/app/components/poetry/ui/alert_dialog/component.rb +208 -0
  17. data/app/components/poetry/ui/alert_dialog/preview.rb +48 -0
  18. data/app/components/poetry/ui/alert_dialog/style.rb +46 -0
  19. data/app/components/poetry/ui/aspect_ratio/component.rb +63 -0
  20. data/app/components/poetry/ui/aspect_ratio/preview.rb +29 -0
  21. data/app/components/poetry/ui/aspect_ratio/style.rb +13 -0
  22. data/app/components/poetry/ui/attachment/component.html.erb +13 -0
  23. data/app/components/poetry/ui/attachment/component.rb +139 -0
  24. data/app/components/poetry/ui/attachment/preview.rb +83 -0
  25. data/app/components/poetry/ui/attachment/style.rb +59 -0
  26. data/app/components/poetry/ui/autocomplete/component.html.erb +16 -0
  27. data/app/components/poetry/ui/autocomplete/component.rb +193 -0
  28. data/app/components/poetry/ui/autocomplete/preview.rb +39 -0
  29. data/app/components/poetry/ui/autocomplete/style.rb +18 -0
  30. data/app/components/poetry/ui/avatar/component.rb +103 -0
  31. data/app/components/poetry/ui/avatar/group_preview.html.erb +11 -0
  32. data/app/components/poetry/ui/avatar/preview.rb +50 -0
  33. data/app/components/poetry/ui/avatar/style.rb +34 -0
  34. data/app/components/poetry/ui/badge/component.rb +73 -0
  35. data/app/components/poetry/ui/badge/preview.rb +54 -0
  36. data/app/components/poetry/ui/badge/style.rb +35 -0
  37. data/app/components/poetry/ui/breadcrumb/component.html.erb +32 -0
  38. data/app/components/poetry/ui/breadcrumb/component.rb +102 -0
  39. data/app/components/poetry/ui/breadcrumb/dropdown_crumb_preview.html.erb +21 -0
  40. data/app/components/poetry/ui/breadcrumb/preview.rb +45 -0
  41. data/app/components/poetry/ui/breadcrumb/style.rb +25 -0
  42. data/app/components/poetry/ui/bubble/component.html.erb +4 -0
  43. data/app/components/poetry/ui/bubble/component.rb +106 -0
  44. data/app/components/poetry/ui/bubble/preview.rb +62 -0
  45. data/app/components/poetry/ui/bubble/style.rb +47 -0
  46. data/app/components/poetry/ui/button/component.html.erb +14 -0
  47. data/app/components/poetry/ui/button/component.rb +168 -0
  48. data/app/components/poetry/ui/button/preview.rb +94 -0
  49. data/app/components/poetry/ui/button/style.rb +41 -0
  50. data/app/components/poetry/ui/button_group/component.rb +70 -0
  51. data/app/components/poetry/ui/button_group/popup_triggers_preview.html.erb +21 -0
  52. data/app/components/poetry/ui/button_group/preview.rb +46 -0
  53. data/app/components/poetry/ui/button_group/style.rb +27 -0
  54. data/app/components/poetry/ui/button_group/text_prefix_preview.html.erb +7 -0
  55. data/app/components/poetry/ui/calendar/component.html.erb +72 -0
  56. data/app/components/poetry/ui/calendar/component.rb +366 -0
  57. data/app/components/poetry/ui/calendar/preview.rb +55 -0
  58. data/app/components/poetry/ui/calendar/style.rb +55 -0
  59. data/app/components/poetry/ui/card/component.html.erb +11 -0
  60. data/app/components/poetry/ui/card/component.rb +90 -0
  61. data/app/components/poetry/ui/card/preview.rb +29 -0
  62. data/app/components/poetry/ui/card/style.rb +23 -0
  63. data/app/components/poetry/ui/carousel/component.html.erb +17 -0
  64. data/app/components/poetry/ui/carousel/component.rb +179 -0
  65. data/app/components/poetry/ui/carousel/preview.rb +67 -0
  66. data/app/components/poetry/ui/carousel/style.rb +39 -0
  67. data/app/components/poetry/ui/checkbox/component.html.erb +22 -0
  68. data/app/components/poetry/ui/checkbox/component.rb +179 -0
  69. data/app/components/poetry/ui/checkbox/preview.rb +68 -0
  70. data/app/components/poetry/ui/checkbox/style.rb +28 -0
  71. data/app/components/poetry/ui/clipboard_text/component.html.erb +15 -0
  72. data/app/components/poetry/ui/clipboard_text/component.rb +154 -0
  73. data/app/components/poetry/ui/clipboard_text/preview.rb +24 -0
  74. data/app/components/poetry/ui/clipboard_text/style.rb +23 -0
  75. data/app/components/poetry/ui/code_block/component.html.erb +13 -0
  76. data/app/components/poetry/ui/code_block/component.rb +141 -0
  77. data/app/components/poetry/ui/code_block/preview.rb +40 -0
  78. data/app/components/poetry/ui/code_block/style.rb +38 -0
  79. data/app/components/poetry/ui/collapsible/component.html.erb +4 -0
  80. data/app/components/poetry/ui/collapsible/component.rb +134 -0
  81. data/app/components/poetry/ui/collapsible/preview.rb +24 -0
  82. data/app/components/poetry/ui/combobox/component.html.erb +49 -0
  83. data/app/components/poetry/ui/combobox/component.rb +1086 -0
  84. data/app/components/poetry/ui/combobox/preview.rb +164 -0
  85. data/app/components/poetry/ui/combobox/style.rb +148 -0
  86. data/app/components/poetry/ui/command/component.html.erb +20 -0
  87. data/app/components/poetry/ui/command/component.rb +526 -0
  88. data/app/components/poetry/ui/command/dialog_component.html.erb +14 -0
  89. data/app/components/poetry/ui/command/dialog_component.rb +206 -0
  90. data/app/components/poetry/ui/command/dialog_preview.rb +39 -0
  91. data/app/components/poetry/ui/command/preview.rb +121 -0
  92. data/app/components/poetry/ui/command/style.rb +78 -0
  93. data/app/components/poetry/ui/composable_trigger.rb +63 -0
  94. data/app/components/poetry/ui/context_menu/component.html.erb +6 -0
  95. data/app/components/poetry/ui/context_menu/component.rb +358 -0
  96. data/app/components/poetry/ui/context_menu/preview.rb +111 -0
  97. data/app/components/poetry/ui/context_menu/style.rb +59 -0
  98. data/app/components/poetry/ui/data_table/component.html.erb +78 -0
  99. data/app/components/poetry/ui/data_table/component.rb +277 -0
  100. data/app/components/poetry/ui/data_table/preview.rb +68 -0
  101. data/app/components/poetry/ui/data_table/state.rb +115 -0
  102. data/app/components/poetry/ui/data_table/style.rb +42 -0
  103. data/app/components/poetry/ui/date_field/component.html.erb +7 -0
  104. data/app/components/poetry/ui/date_field/component.rb +209 -0
  105. data/app/components/poetry/ui/date_field/preview.rb +42 -0
  106. data/app/components/poetry/ui/date_field/style.rb +35 -0
  107. data/app/components/poetry/ui/date_picker/component.html.erb +23 -0
  108. data/app/components/poetry/ui/date_picker/component.rb +242 -0
  109. data/app/components/poetry/ui/date_picker/preview.rb +31 -0
  110. data/app/components/poetry/ui/date_picker/style.rb +25 -0
  111. data/app/components/poetry/ui/deferred/component.html.erb +16 -0
  112. data/app/components/poetry/ui/deferred/component.rb +90 -0
  113. data/app/components/poetry/ui/deferred/preview.rb +24 -0
  114. data/app/components/poetry/ui/dialog/component.html.erb +21 -0
  115. data/app/components/poetry/ui/dialog/component.rb +194 -0
  116. data/app/components/poetry/ui/dialog/preview.rb +33 -0
  117. data/app/components/poetry/ui/dialog/style.rb +30 -0
  118. data/app/components/poetry/ui/drawer/component.html.erb +16 -0
  119. data/app/components/poetry/ui/drawer/component.rb +207 -0
  120. data/app/components/poetry/ui/drawer/preview.rb +69 -0
  121. data/app/components/poetry/ui/drawer/style.rb +105 -0
  122. data/app/components/poetry/ui/dropdown_menu/component.html.erb +6 -0
  123. data/app/components/poetry/ui/dropdown_menu/component.rb +350 -0
  124. data/app/components/poetry/ui/dropdown_menu/preview.rb +101 -0
  125. data/app/components/poetry/ui/dropdown_menu/style.rb +60 -0
  126. data/app/components/poetry/ui/empty/component.html.erb +10 -0
  127. data/app/components/poetry/ui/empty/component.rb +79 -0
  128. data/app/components/poetry/ui/empty/preview.rb +27 -0
  129. data/app/components/poetry/ui/empty/style.rb +27 -0
  130. data/app/components/poetry/ui/family_identity.rb +52 -0
  131. data/app/components/poetry/ui/field/component.html.erb +19 -0
  132. data/app/components/poetry/ui/field/component.rb +183 -0
  133. data/app/components/poetry/ui/field/preview.html.erb +30 -0
  134. data/app/components/poetry/ui/field/preview.rb +72 -0
  135. data/app/components/poetry/ui/field/style.rb +68 -0
  136. data/app/components/poetry/ui/field_group/component.rb +61 -0
  137. data/app/components/poetry/ui/field_group/preview.html.erb +30 -0
  138. data/app/components/poetry/ui/field_group/preview.rb +20 -0
  139. data/app/components/poetry/ui/field_group/style.rb +25 -0
  140. data/app/components/poetry/ui/field_separator/component.rb +70 -0
  141. data/app/components/poetry/ui/field_separator/preview.rb +18 -0
  142. data/app/components/poetry/ui/field_separator/style.rb +20 -0
  143. data/app/components/poetry/ui/fieldset/component.rb +90 -0
  144. data/app/components/poetry/ui/fieldset/preview.html.erb +22 -0
  145. data/app/components/poetry/ui/fieldset/preview.rb +25 -0
  146. data/app/components/poetry/ui/fieldset/style.rb +18 -0
  147. data/app/components/poetry/ui/file_input/component.html.erb +14 -0
  148. data/app/components/poetry/ui/file_input/component.rb +188 -0
  149. data/app/components/poetry/ui/file_input/preview.rb +30 -0
  150. data/app/components/poetry/ui/file_input/style.rb +35 -0
  151. data/app/components/poetry/ui/hover_card/component.html.erb +6 -0
  152. data/app/components/poetry/ui/hover_card/component.rb +201 -0
  153. data/app/components/poetry/ui/hover_card/preview.rb +60 -0
  154. data/app/components/poetry/ui/hover_card/style.rb +17 -0
  155. data/app/components/poetry/ui/icon/component.rb +127 -0
  156. data/app/components/poetry/ui/icon/preview.rb +21 -0
  157. data/app/components/poetry/ui/input/component.rb +80 -0
  158. data/app/components/poetry/ui/input/preview.rb +35 -0
  159. data/app/components/poetry/ui/input/style.rb +18 -0
  160. data/app/components/poetry/ui/input_group/button_preview.html.erb +12 -0
  161. data/app/components/poetry/ui/input_group/component.rb +69 -0
  162. data/app/components/poetry/ui/input_group/preview.rb +23 -0
  163. data/app/components/poetry/ui/input_group/search_preview.html.erb +13 -0
  164. data/app/components/poetry/ui/input_group/style.rb +40 -0
  165. data/app/components/poetry/ui/input_group/textarea_preview.html.erb +10 -0
  166. data/app/components/poetry/ui/input_group_field.rb +61 -0
  167. data/app/components/poetry/ui/input_otp/component.html.erb +25 -0
  168. data/app/components/poetry/ui/input_otp/component.rb +250 -0
  169. data/app/components/poetry/ui/input_otp/preview.rb +91 -0
  170. data/app/components/poetry/ui/input_otp/style.rb +36 -0
  171. data/app/components/poetry/ui/item/component.html.erb +13 -0
  172. data/app/components/poetry/ui/item/component.rb +99 -0
  173. data/app/components/poetry/ui/item/group_preview.html.erb +15 -0
  174. data/app/components/poetry/ui/item/preview.rb +52 -0
  175. data/app/components/poetry/ui/item/style.rb +45 -0
  176. data/app/components/poetry/ui/kbd/component.rb +47 -0
  177. data/app/components/poetry/ui/kbd/group_preview.html.erb +4 -0
  178. data/app/components/poetry/ui/kbd/preview.rb +23 -0
  179. data/app/components/poetry/ui/kbd/style.rb +13 -0
  180. data/app/components/poetry/ui/label/component.rb +46 -0
  181. data/app/components/poetry/ui/label/preview.html.erb +5 -0
  182. data/app/components/poetry/ui/label/preview.rb +16 -0
  183. data/app/components/poetry/ui/label/style.rb +13 -0
  184. data/app/components/poetry/ui/link/component.rb +62 -0
  185. data/app/components/poetry/ui/link/preview.rb +31 -0
  186. data/app/components/poetry/ui/link/style.rb +20 -0
  187. data/app/components/poetry/ui/marker/component.html.erb +4 -0
  188. data/app/components/poetry/ui/marker/component.rb +81 -0
  189. data/app/components/poetry/ui/marker/preview.rb +43 -0
  190. data/app/components/poetry/ui/marker/style.rb +24 -0
  191. data/app/components/poetry/ui/menubar/component.html.erb +3 -0
  192. data/app/components/poetry/ui/menubar/component.rb +493 -0
  193. data/app/components/poetry/ui/menubar/preview.rb +164 -0
  194. data/app/components/poetry/ui/menubar/style.rb +71 -0
  195. data/app/components/poetry/ui/menus.rb +386 -0
  196. data/app/components/poetry/ui/message/component.html.erb +8 -0
  197. data/app/components/poetry/ui/message/component.rb +64 -0
  198. data/app/components/poetry/ui/message/preview.rb +33 -0
  199. data/app/components/poetry/ui/message/style.rb +29 -0
  200. data/app/components/poetry/ui/message_scroller/component.html.erb +15 -0
  201. data/app/components/poetry/ui/message_scroller/component.rb +163 -0
  202. data/app/components/poetry/ui/message_scroller/preview.rb +33 -0
  203. data/app/components/poetry/ui/message_scroller/style.rb +39 -0
  204. data/app/components/poetry/ui/metadata_list/component.rb +88 -0
  205. data/app/components/poetry/ui/metadata_list/preview.rb +55 -0
  206. data/app/components/poetry/ui/metadata_list/style.rb +35 -0
  207. data/app/components/poetry/ui/meter/component.rb +117 -0
  208. data/app/components/poetry/ui/meter/preview.rb +28 -0
  209. data/app/components/poetry/ui/meter/style.rb +16 -0
  210. data/app/components/poetry/ui/native_select/component.rb +124 -0
  211. data/app/components/poetry/ui/native_select/labelled_preview.html.erb +7 -0
  212. data/app/components/poetry/ui/native_select/preview.rb +20 -0
  213. data/app/components/poetry/ui/native_select/style.rb +22 -0
  214. data/app/components/poetry/ui/navigation_menu/bar_preview.html.erb +14 -0
  215. data/app/components/poetry/ui/navigation_menu/component.html.erb +25 -0
  216. data/app/components/poetry/ui/navigation_menu/component.rb +254 -0
  217. data/app/components/poetry/ui/navigation_menu/preview.rb +20 -0
  218. data/app/components/poetry/ui/navigation_menu/style.rb +73 -0
  219. data/app/components/poetry/ui/navigation_menu/viewport_preview.html.erb +23 -0
  220. data/app/components/poetry/ui/number_field/component.html.erb +19 -0
  221. data/app/components/poetry/ui/number_field/component.rb +263 -0
  222. data/app/components/poetry/ui/number_field/preview.rb +66 -0
  223. data/app/components/poetry/ui/number_field/style.rb +14 -0
  224. data/app/components/poetry/ui/pagination/component.html.erb +40 -0
  225. data/app/components/poetry/ui/pagination/component.rb +182 -0
  226. data/app/components/poetry/ui/pagination/preview.rb +47 -0
  227. data/app/components/poetry/ui/pagination/style.rb +27 -0
  228. data/app/components/poetry/ui/popover/component.html.erb +17 -0
  229. data/app/components/poetry/ui/popover/component.rb +203 -0
  230. data/app/components/poetry/ui/popover/preview.html.erb +29 -0
  231. data/app/components/poetry/ui/popover/preview.rb +66 -0
  232. data/app/components/poetry/ui/popover/style.rb +26 -0
  233. data/app/components/poetry/ui/popper_consumer.rb +69 -0
  234. data/app/components/poetry/ui/progress/component.rb +95 -0
  235. data/app/components/poetry/ui/progress/preview.rb +22 -0
  236. data/app/components/poetry/ui/progress/style.rb +19 -0
  237. data/app/components/poetry/ui/questionnaire/component.html.erb +80 -0
  238. data/app/components/poetry/ui/questionnaire/component.rb +396 -0
  239. data/app/components/poetry/ui/questionnaire/preview.rb +99 -0
  240. data/app/components/poetry/ui/questionnaire/style.rb +53 -0
  241. data/app/components/poetry/ui/radio_group/component.html.erb +4 -0
  242. data/app/components/poetry/ui/radio_group/component.rb +323 -0
  243. data/app/components/poetry/ui/radio_group/preview.rb +109 -0
  244. data/app/components/poetry/ui/radio_group/style.rb +53 -0
  245. data/app/components/poetry/ui/resizable/component.html.erb +10 -0
  246. data/app/components/poetry/ui/resizable/component.rb +178 -0
  247. data/app/components/poetry/ui/resizable/preview.rb +42 -0
  248. data/app/components/poetry/ui/resizable/style.rb +30 -0
  249. data/app/components/poetry/ui/scroll_area/component.rb +76 -0
  250. data/app/components/poetry/ui/scroll_area/preview.rb +35 -0
  251. data/app/components/poetry/ui/scroll_area/style.rb +19 -0
  252. data/app/components/poetry/ui/search_field/component.html.erb +15 -0
  253. data/app/components/poetry/ui/search_field/component.rb +137 -0
  254. data/app/components/poetry/ui/search_field/preview.rb +23 -0
  255. data/app/components/poetry/ui/search_field/style.rb +18 -0
  256. data/app/components/poetry/ui/select/component.html.erb +15 -0
  257. data/app/components/poetry/ui/select/component.rb +639 -0
  258. data/app/components/poetry/ui/select/preview.rb +113 -0
  259. data/app/components/poetry/ui/select/style.rb +58 -0
  260. data/app/components/poetry/ui/sensitive_input/component.html.erb +29 -0
  261. data/app/components/poetry/ui/sensitive_input/component.rb +274 -0
  262. data/app/components/poetry/ui/sensitive_input/preview.rb +40 -0
  263. data/app/components/poetry/ui/sensitive_input/style.rb +49 -0
  264. data/app/components/poetry/ui/separator/component.rb +57 -0
  265. data/app/components/poetry/ui/separator/preview.rb +19 -0
  266. data/app/components/poetry/ui/separator/style.rb +15 -0
  267. data/app/components/poetry/ui/sheet/component.html.erb +21 -0
  268. data/app/components/poetry/ui/sheet/component.rb +97 -0
  269. data/app/components/poetry/ui/sheet/preview.rb +57 -0
  270. data/app/components/poetry/ui/sheet/style.rb +47 -0
  271. data/app/components/poetry/ui/sidebar/component.html.erb +20 -0
  272. data/app/components/poetry/ui/sidebar/component.rb +249 -0
  273. data/app/components/poetry/ui/sidebar/preview.rb +21 -0
  274. data/app/components/poetry/ui/sidebar/shell_preview.html.erb +47 -0
  275. data/app/components/poetry/ui/sidebar/style.rb +139 -0
  276. data/app/components/poetry/ui/skeleton/component.rb +39 -0
  277. data/app/components/poetry/ui/skeleton/preview.rb +22 -0
  278. data/app/components/poetry/ui/skeleton/style.rb +13 -0
  279. data/app/components/poetry/ui/slider/component.html.erb +13 -0
  280. data/app/components/poetry/ui/slider/component.rb +360 -0
  281. data/app/components/poetry/ui/slider/preview.rb +73 -0
  282. data/app/components/poetry/ui/slider/style.rb +55 -0
  283. data/app/components/poetry/ui/spinner/component.rb +58 -0
  284. data/app/components/poetry/ui/spinner/preview.rb +22 -0
  285. data/app/components/poetry/ui/spinner/style.rb +12 -0
  286. data/app/components/poetry/ui/stat/component.html.erb +13 -0
  287. data/app/components/poetry/ui/stat/component.rb +102 -0
  288. data/app/components/poetry/ui/stat/preview.rb +47 -0
  289. data/app/components/poetry/ui/stat/style.rb +29 -0
  290. data/app/components/poetry/ui/switch/component.html.erb +15 -0
  291. data/app/components/poetry/ui/switch/component.rb +136 -0
  292. data/app/components/poetry/ui/switch/preview.rb +66 -0
  293. data/app/components/poetry/ui/switch/style.rb +22 -0
  294. data/app/components/poetry/ui/table/component.html.erb +3 -0
  295. data/app/components/poetry/ui/table/component.rb +93 -0
  296. data/app/components/poetry/ui/table/preview.rb +96 -0
  297. data/app/components/poetry/ui/table/style.rb +26 -0
  298. data/app/components/poetry/ui/tabs/component.html.erb +10 -0
  299. data/app/components/poetry/ui/tabs/component.rb +253 -0
  300. data/app/components/poetry/ui/tabs/preview.rb +43 -0
  301. data/app/components/poetry/ui/tabs/style.rb +49 -0
  302. data/app/components/poetry/ui/tag_group/component.html.erb +8 -0
  303. data/app/components/poetry/ui/tag_group/component.rb +203 -0
  304. data/app/components/poetry/ui/tag_group/preview.rb +43 -0
  305. data/app/components/poetry/ui/tag_group/style.rb +29 -0
  306. data/app/components/poetry/ui/textarea/component.rb +64 -0
  307. data/app/components/poetry/ui/textarea/preview.rb +75 -0
  308. data/app/components/poetry/ui/textarea/style.rb +18 -0
  309. data/app/components/poetry/ui/time_field/component.html.erb +6 -0
  310. data/app/components/poetry/ui/time_field/component.rb +85 -0
  311. data/app/components/poetry/ui/time_field/preview.rb +40 -0
  312. data/app/components/poetry/ui/time_field/style.rb +30 -0
  313. data/app/components/poetry/ui/timeline/component.rb +134 -0
  314. data/app/components/poetry/ui/timeline/preview.rb +61 -0
  315. data/app/components/poetry/ui/timeline/style.rb +54 -0
  316. data/app/components/poetry/ui/toast/component.html.erb +24 -0
  317. data/app/components/poetry/ui/toast/component.rb +178 -0
  318. data/app/components/poetry/ui/toast/preview.rb +69 -0
  319. data/app/components/poetry/ui/toast/style.rb +33 -0
  320. data/app/components/poetry/ui/toast_trigger/addressed_preview.html.erb +12 -0
  321. data/app/components/poetry/ui/toast_trigger/component.html.erb +3 -0
  322. data/app/components/poetry/ui/toast_trigger/component.rb +82 -0
  323. data/app/components/poetry/ui/toast_trigger/default_preview.html.erb +11 -0
  324. data/app/components/poetry/ui/toast_trigger/preview.rb +19 -0
  325. data/app/components/poetry/ui/toaster/component.html.erb +1 -0
  326. data/app/components/poetry/ui/toaster/component.rb +99 -0
  327. data/app/components/poetry/ui/toaster/positions_preview.html.erb +24 -0
  328. data/app/components/poetry/ui/toaster/preview.rb +46 -0
  329. data/app/components/poetry/ui/toaster/stamp_preview.html.erb +15 -0
  330. data/app/components/poetry/ui/toaster/style.rb +26 -0
  331. data/app/components/poetry/ui/toggle/component.rb +120 -0
  332. data/app/components/poetry/ui/toggle/preview.rb +79 -0
  333. data/app/components/poetry/ui/toggle/style.rb +33 -0
  334. data/app/components/poetry/ui/toggle_group/component.html.erb +4 -0
  335. data/app/components/poetry/ui/toggle_group/component.rb +252 -0
  336. data/app/components/poetry/ui/toggle_group/preview.rb +143 -0
  337. data/app/components/poetry/ui/toggle_group/style.rb +33 -0
  338. data/app/components/poetry/ui/toolbar/component.rb +125 -0
  339. data/app/components/poetry/ui/toolbar/preview.rb +41 -0
  340. data/app/components/poetry/ui/toolbar/style.rb +20 -0
  341. data/app/components/poetry/ui/tooltip/component.html.erb +20 -0
  342. data/app/components/poetry/ui/tooltip/component.rb +185 -0
  343. data/app/components/poetry/ui/tooltip/preview.rb +74 -0
  344. data/app/components/poetry/ui/tooltip/previews/provider_row.html.erb +25 -0
  345. data/app/components/poetry/ui/tooltip/style.rb +24 -0
  346. data/app/components/poetry/ui/tree/component.html.erb +32 -0
  347. data/app/components/poetry/ui/tree/component.rb +233 -0
  348. data/app/components/poetry/ui/tree/preview.rb +55 -0
  349. data/app/components/poetry/ui/tree/style.rb +29 -0
  350. data/app/components/poetry/ui/typeset/component.rb +73 -0
  351. data/app/components/poetry/ui/typeset/preview.rb +45 -0
  352. data/app/components/poetry/ui/typeset/style.rb +15 -0
  353. data/app/controllers/poetry/ui/llms_controller.rb +28 -0
  354. data/app/helpers/poetry/ui/components_helper.rb +1794 -0
  355. data/app/helpers/poetry/ui/form_builder/type_inference.rb +117 -0
  356. data/app/helpers/poetry/ui/form_builder.rb +916 -0
  357. data/app/helpers/poetry/ui/optimistic_form_builder.rb +55 -0
  358. data/app/helpers/poetry/ui/toast_stream_actions.rb +27 -0
  359. data/config/component_descriptions.yml +96 -0
  360. data/config/component_registry.yml +12257 -0
  361. data/config/locales/en.yml +93 -0
  362. data/config/routes.rb +8 -0
  363. data/config/template_classes.txt +113 -0
  364. data/lib/generators/poetry/add/add_generator.rb +218 -0
  365. data/lib/generators/poetry/agent_rules/agent_rules_generator.rb +91 -0
  366. data/lib/generators/poetry/agents/agents_generator.rb +24 -0
  367. data/lib/generators/poetry/agents_section.rb +148 -0
  368. data/lib/generators/poetry/block/block_generator.rb +67 -0
  369. data/lib/generators/poetry/block/templates/action_bar.html.erb +45 -0
  370. data/lib/generators/poetry/block/templates/app_shell.html.erb +139 -0
  371. data/lib/generators/poetry/block/templates/data_index.html.erb +85 -0
  372. data/lib/generators/poetry/block/templates/destructive_panel.html.erb +26 -0
  373. data/lib/generators/poetry/block/templates/page_header.html.erb +25 -0
  374. data/lib/generators/poetry/block/templates/section_card.html.erb +42 -0
  375. data/lib/generators/poetry/block/templates/stepper.html.erb +79 -0
  376. data/lib/generators/poetry/block/templates/top_nav.html.erb +44 -0
  377. data/lib/generators/poetry/diff/diff_generator.rb +135 -0
  378. data/lib/generators/poetry/editor/editor_generator.rb +344 -0
  379. data/lib/generators/poetry/editor/templates/poetry-check-hook +81 -0
  380. data/lib/generators/poetry/install/install_generator.rb +364 -0
  381. data/lib/generators/poetry/pagination/pagination_generator.rb +76 -0
  382. data/lib/generators/poetry/pagination/templates/kaminari_paginator.html.erb +29 -0
  383. data/lib/generators/poetry/pagination/templates/poetry_link_renderer.rb +34 -0
  384. data/lib/generators/poetry/pagination/templates/poetry_pagy_helper.rb +28 -0
  385. data/lib/generators/poetry/recipes/agent_embed/app/javascript/controllers/agent_demo_controller.js +131 -0
  386. data/lib/generators/poetry/recipes/screen_data_index/app/controllers/orders_controller.rb +15 -0
  387. data/lib/generators/poetry/recipes/screen_data_index/app/views/orders/index.html.erb +7 -0
  388. data/lib/generators/poetry/recipes/screen_data_index/test/system/orders_index_test.rb +16 -0
  389. data/lib/generators/poetry/recipes/screen_settings/app/controllers/settings_controller.rb +14 -0
  390. data/lib/generators/poetry/recipes/screen_settings/app/views/settings/show.html.erb +9 -0
  391. data/lib/generators/poetry/recipes/screen_settings/test/system/settings_show_test.rb +16 -0
  392. data/lib/generators/poetry/scaffold_templates/scaffold_templates_generator.rb +60 -0
  393. data/lib/generators/poetry/scaffold_templates/templates/_form.html.erb.tt +77 -0
  394. data/lib/generators/poetry/scaffold_templates/templates/controller.rb.tt +78 -0
  395. data/lib/generators/poetry/scaffold_templates/templates/edit.html.erb.tt +14 -0
  396. data/lib/generators/poetry/scaffold_templates/templates/index.html.erb.tt +24 -0
  397. data/lib/generators/poetry/scaffold_templates/templates/new.html.erb.tt +11 -0
  398. data/lib/generators/poetry/scaffold_templates/templates/partial.html.erb.tt +13 -0
  399. data/lib/generators/poetry/scaffold_templates/templates/show.html.erb.tt +18 -0
  400. data/lib/generators/poetry/skill/skill_generator.rb +34 -0
  401. data/lib/generators/poetry/skill/templates/poetry-component/SKILL.md +58 -0
  402. data/lib/generators/poetry/skill/templates/poetry-component/references/anatomy.md +152 -0
  403. data/lib/generators/poetry/skill/templates/poetry-component/references/checklist.md +67 -0
  404. data/lib/generators/poetry/skill/templates/poetry-component/references/documentation.md +137 -0
  405. data/lib/generators/poetry/skill/templates/poetry-design/SKILL.md +56 -0
  406. data/lib/generators/poetry/skill/templates/poetry-design/references/audit.md +123 -0
  407. data/lib/generators/poetry/skill/templates/poetry-design/references/compose.md +73 -0
  408. data/lib/generators/poetry/skill/templates/poetry-design/references/figma.md +68 -0
  409. data/lib/generators/poetry/skill/templates/poetry-design/references/paper.md +56 -0
  410. data/lib/generators/poetry/skill/templates/poetry-design/references/study.md +47 -0
  411. data/lib/generators/poetry/skill/templates/poetry-design/references/theme.md +70 -0
  412. data/lib/generators/poetry/skills_section.rb +58 -0
  413. data/lib/poetry/ui/chat.rb +283 -0
  414. data/lib/poetry/ui/code_block_highlighter.rb +60 -0
  415. data/lib/poetry/ui/engine.rb +55 -0
  416. data/lib/poetry/ui/recipes.rb +157 -0
  417. data/lib/poetry/ui/testing/combobox.rb +167 -0
  418. data/lib/poetry/ui/testing/dialog.rb +73 -0
  419. data/lib/poetry/ui/testing/menu.rb +127 -0
  420. data/lib/poetry/ui/testing/registration.rb +58 -0
  421. data/lib/poetry/ui/testing/select.rb +147 -0
  422. data/lib/poetry/ui/testing/tester.rb +130 -0
  423. data/lib/poetry/ui/testing.rb +130 -0
  424. data/lib/poetry/ui/themes.rb +109 -0
  425. data/lib/poetry/ui/version.rb +8 -0
  426. data/lib/poetry/ui/webmcp.rb +91 -0
  427. data/lib/poetry/ui.rb +285 -0
  428. data/lib/poetry-ui.rb +5 -0
  429. data/lib/tasks/poetry/check.rake +73 -0
  430. data/lib/tasks/poetry/design.rake +293 -0
  431. data/lib/tasks/poetry/verify.rake +36 -0
  432. data/themes/default.css +1793 -0
  433. data/themes/luma.css +1764 -0
  434. data/themes/lyra.css +1768 -0
  435. data/themes/maia.css +1768 -0
  436. data/themes/mira.css +1760 -0
  437. data/themes/nova.css +1755 -0
  438. data/themes/rhea.css +1771 -0
  439. data/themes/sera.css +1757 -0
  440. data/themes/vega.css +1775 -0
  441. data/typeset/typeset.css +499 -0
  442. metadata +502 -0
@@ -0,0 +1,11 @@
1
+ <div class="p-4">
2
+ <%= render Poetry::Ui::ToastTrigger::Component.new(template: "trigger-preview-toast") do %>
3
+ Show toast
4
+ <% end %>
5
+ </div>
6
+ <template id="trigger-preview-toast">
7
+ <%= poetry_toast(variant: :success, duration: 4000) do |toast| %>
8
+ <% toast.with_title { "Stamped into the region" } %>
9
+ <% end %>
10
+ </template>
11
+ <%= poetry_toaster %>
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Poetry
4
+ module Ui
5
+ module ToastTrigger
6
+ # The stamp pattern end-to-end: trigger + <template> toast + region.
7
+ class Preview < Poetry::Core::Preview::Base
8
+ def default
9
+ render_with_template(template: "poetry/ui/toast_trigger/default_preview")
10
+ end
11
+
12
+ # toaster: addressing - the stamp scoped to one region id.
13
+ def addressed
14
+ render_with_template(template: "poetry/ui/toast_trigger/addressed_preview")
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1 @@
1
+ <%= content_tag(:ol, content, **root_attributes.to_attributes) %>
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Poetry
4
+ module Ui
5
+ # The toast viewport.
6
+ module Toaster
7
+ # The closed vocabulary for the corner axis.
8
+ POSITIONS = %i[top-left top-center top-right bottom-left bottom-center bottom-right].freeze
9
+
10
+ # The toast viewport: a labeled role=region list rendered once in
11
+ # the layout, and the append target for streamed toasts
12
+ # (id=poetry-toaster). It is data-turbo-permanent - toasts survive
13
+ # Drive visits, so flash-after-redirect stays visible. The region
14
+ # owns the hotkey (F8 by default: focus the most recent toast, with
15
+ # prior focus restored after dismiss), enforces the visible limit
16
+ # (overflow queues hidden with timers held), and keeps the stack's
17
+ # positions as toasts come and go.
18
+ #
19
+ # Server code appends toasts with turbo_stream.poetry_toast(title:
20
+ # "Saved", variant: :success) - from controller responses, form
21
+ # streams, and broadcasts. To surface Rails flash as toasts, render
22
+ # the mapping next to the toaster in the layout (see the example).
23
+ #
24
+ # @example The flash -> toast mapping in the layout
25
+ # <%= poetry_toaster do %>
26
+ # <% flash.each do |kind, message| %>
27
+ # <%= poetry_toast(variant: kind.to_s == "alert" ? :destructive : :default) do |toast| %>
28
+ # <% toast.with_title { message } %>
29
+ # <% end %>
30
+ # <% end %>
31
+ # <% end %>
32
+ class Component < Poetry::Core::Component
33
+ # The stream append target (the turbo_stream.poetry_toast default).
34
+ DEFAULT_ID = "poetry-toaster"
35
+
36
+ # Projected into the registry, llms.txt, and the agent surface.
37
+ AGENT_RULES = [
38
+ "Exactly ONE poetry_toaster per layout; it is data-turbo-permanent.",
39
+ "Server-side toasts go through turbo_stream.poetry_toast / the flash recipe - never " \
40
+ "hand-append into #poetry-toaster.",
41
+ "Client-side (no round-trip) toasts go through poetry_toast_trigger(template:) + a " \
42
+ "<template> holding the rendered poetry_toast - the trigger stamps it into the region.",
43
+ "Do not announce() toast content yourself - the toast controller already does; " \
44
+ "double-announcing is a regression."
45
+ ].freeze
46
+
47
+ # Values only, zero actions: the controller wires its own
48
+ # window-keydown (hotkey) and dismiss listeners in connect.
49
+ use_stimulus do
50
+ on :root do
51
+ controller :toaster do
52
+ register
53
+ value :hotkey
54
+ value :limit
55
+ value :position
56
+ end
57
+ end
58
+ end
59
+
60
+ style :position, default: :"bottom-right", required: true, variants: POSITIONS,
61
+ doc: "The stack's corner - set here, not per toast; each toast's slide direction follows it."
62
+
63
+ option :hotkey, :string, default: "F8", doc: "The keyboard shortcut that focuses the most recent toast."
64
+ option :limit, :integer, default: 3, doc: "The maximum visible toasts; overflow queues hidden with timers held."
65
+
66
+ part "toaster", "The toast viewport itself (<ol>, role=region, data-turbo-permanent) - " \
67
+ "the corner geometry and the Turbo Stream append target ride here",
68
+ states: {
69
+ "data-position" => { condition: "always - the corner; each toast's slide " \
70
+ "direction keys off it via group/toaster",
71
+ values: POSITIONS.map(&:to_s) },
72
+ "data-poetry-top-layer" => { condition: "always - the dismissal layer exempts " \
73
+ "presses here, so clicking a toast never " \
74
+ "dismisses the overlay under it" }
75
+ }
76
+
77
+ # @api private
78
+ def root_attributes
79
+ html_attributes.merge_if_not_set(
80
+ {
81
+ "id" => DEFAULT_ID, "data-slot" => "toaster",
82
+ "role" => "region", "aria-label" => t("poetry.toast.region_label", hotkey: hotkey),
83
+ "tabindex" => "-1", "data-turbo-permanent" => "",
84
+ # The dismissal layer's top-layer exemption: presses inside
85
+ # the toaster are never "outside" an open overlay.
86
+ "data-poetry-top-layer" => "",
87
+ # The toast items key their slide direction on this via the
88
+ # group-data selector (items render independently of the
89
+ # region - a streamed toast cannot know the corner).
90
+ "data-position" => position
91
+ }.merge(stimulus_attributes_for(:root)).merge(component_data_attributes)
92
+ )
93
+ end
94
+
95
+ private :root_attributes
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,24 @@
1
+ <%# The four placements no other example renders, on one canvas - a
2
+ coverage fixture: real layouts run ONE toaster per page, and
3
+ default/top_center own bottom-right and top-center. This page exists so
4
+ every declared position renders in the golden and axe walks. %>
5
+ <%= poetry_toaster(position: :"top-left", id: "toaster-top-left") do %>
6
+ <%= poetry_toast(variant: :default) do |toast| %>
7
+ <% toast.with_title { "Top left" } %>
8
+ <% end %>
9
+ <% end %>
10
+ <%= poetry_toaster(position: :"top-right", id: "toaster-top-right") do %>
11
+ <%= poetry_toast(variant: :default) do |toast| %>
12
+ <% toast.with_title { "Top right" } %>
13
+ <% end %>
14
+ <% end %>
15
+ <%= poetry_toaster(position: :"bottom-left", id: "toaster-bottom-left") do %>
16
+ <%= poetry_toast(variant: :default) do |toast| %>
17
+ <% toast.with_title { "Bottom left" } %>
18
+ <% end %>
19
+ <% end %>
20
+ <%= poetry_toaster(position: :"bottom-center", id: "toaster-bottom-center") do %>
21
+ <%= poetry_toast(variant: :default) do |toast| %>
22
+ <% toast.with_title { "Bottom center" } %>
23
+ <% end %>
24
+ <% end %>
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Poetry
4
+ module Ui
5
+ module Toaster
6
+ # The Toaster preview: the labeled region with a server-rendered
7
+ # stack (the no-JS baseline: flash toasts appear as a static list),
8
+ # plus a top-center corner sample. One toaster per page in real
9
+ # layouts - previews render in isolation.
10
+ class Preview < Poetry::Core::Preview::Base
11
+ def default
12
+ render_component do
13
+ embed(stack_toast(:success, "Changes saved")) +
14
+ embed(stack_toast(:default, "Event scheduled"))
15
+ end
16
+ end
17
+
18
+ def top_center
19
+ render_component(position: :"top-center") do
20
+ embed(stack_toast(:info, "A new version is available"))
21
+ end
22
+ end
23
+
24
+ # The stamp path: trigger button + <template> toast + region (the
25
+ # no-round-trip delivery poetry_toast_trigger drives).
26
+ def stamp_trigger
27
+ render_with_template(template: "poetry/ui/toaster/stamp_preview")
28
+ end
29
+
30
+ def positions
31
+ # The four placements the examples above don't render, one canvas
32
+ # (axis coverage) - see the template's fixture note.
33
+ render_with_template(template: "poetry/ui/toaster/positions_preview")
34
+ end
35
+
36
+ private
37
+
38
+ def stack_toast(variant, title)
39
+ Toast::Component.new(variant: variant).tap do |toast|
40
+ toast.with_title { title }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,15 @@
1
+ <%# The stamp delivery path end-to-end: a poetry_toast_trigger button, the
2
+ <template> holding a real rendered toast, and the toaster region the
3
+ stamp lands in. What the template holds is byte-for-byte what a Turbo
4
+ Stream would append. %>
5
+ <div class="p-4">
6
+ <%= poetry_toast_trigger(template: "preview-stamp-toast", variant: :outline) do %>
7
+ Show toast
8
+ <% end %>
9
+ </div>
10
+ <template id="preview-stamp-toast">
11
+ <%= poetry_toast(variant: :success, duration: 4000) do |toast| %>
12
+ <% toast.with_title { "Stamped into the region" } %>
13
+ <% end %>
14
+ </template>
15
+ <%= poetry_toaster %>
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Poetry
4
+ module Ui
5
+ module Toaster
6
+ # Re-expressed through the cn-* theme layer. The position
7
+ # variants stay INLINE, unnamed: corner placement is pure positioning
8
+ # mechanism (fixed-corner geometry the slide selectors key on), with
9
+ # zero conflicts against the themed spacing/width.
10
+ class Style < Poetry::Core::Style
11
+ # max-w-full rides the theme WITH its sm: cap (split-side rule for
12
+ # responsive pairs - inline it would beat the themed cap always).
13
+ base "cn-toaster group/toaster pointer-events-none fixed z-50 flex w-full flex-col"
14
+
15
+ variant :position, {
16
+ "top-left": "top-0 left-0",
17
+ "top-center": "top-0 left-1/2 -translate-x-1/2",
18
+ "top-right": "top-0 right-0",
19
+ "bottom-left": "bottom-0 left-0",
20
+ "bottom-center": "bottom-0 left-1/2 -translate-x-1/2",
21
+ "bottom-right": "bottom-0 right-0"
22
+ }
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Poetry
4
+ module Ui
5
+ # Pressed-state buttons.
6
+ module Toggle
7
+ # A pressed-state button: aria-pressed plus a bare data-pressed
8
+ # presence attribute on a plain <button> - the standard ARIA
9
+ # toggle-button pattern. Pressed state is UI state
10
+ # (bold-in-a-toolbar, bookmark-on), so a Toggle carries no form
11
+ # machinery: state that must submit with a form is a Checkbox, an
12
+ # instant on/off setting is a Switch, and exclusive or grouped sets
13
+ # are a ToggleGroup.
14
+ #
15
+ # Icon-only toggles require label:, and the label must not change
16
+ # with state ("Bookmark", never "Remove bookmark") - aria-pressed
17
+ # already carries the state.
18
+ #
19
+ # @example An icon-only bookmark toggle
20
+ # render Poetry::Ui::Toggle::Component.new(label: "Bookmark", pressed: bookmarked?) do
21
+ # poetry_icon(name: :bookmark)
22
+ # end
23
+ class Component < Poetry::Core::Component
24
+ # The closed vocabulary for the variant axis.
25
+ VARIANTS = %i[default outline].freeze
26
+ # The closed vocabulary for the size axis.
27
+ SIZES = %i[default sm lg].freeze
28
+
29
+ # Projected into the registry, llms.txt, and the agent surface.
30
+ AGENT_RULES = [
31
+ "Use poetry_toggle - never a Button with hand-managed aria-pressed.",
32
+ "Toggle is UI state, NOT form data: never try to submit it. Form value -> Checkbox; instant " \
33
+ "setting -> Switch; exclusive/grouped -> ToggleGroup.",
34
+ "Icon-only toggles MUST pass label:, and the label must NOT change with state ('Bookmark', " \
35
+ "never 'Remove bookmark').",
36
+ "aria-pressed is the vocabulary - never aria-checked or aria-expanded on a Toggle.",
37
+ "Wire the EFFECT to poetry:toggle:change (or click) and revert via set(false) on failure - " \
38
+ "a pressed toggle whose effect failed is a lie.",
39
+ "Pressed visual is accent - don't override data-pressed colors per-instance (theme-level only)."
40
+ ].freeze
41
+
42
+ # Click flips aria-pressed and data-pressed together; the DOM is
43
+ # the store (no Values). No keydown wiring - Space and Enter
44
+ # already activate a native button.
45
+ use_stimulus do
46
+ on :root do
47
+ controller :pressed do
48
+ register
49
+ action :toggle, on: :click
50
+ end
51
+ end
52
+ end
53
+
54
+ style :variant, default: :default, required: true, variants: VARIANTS,
55
+ doc: "The visual treatment; :outline adds a border for standalone use."
56
+ style :size, default: :default, required: true, variants: SIZES, doc: "The control's size axis."
57
+
58
+ option :pressed, :boolean, default: false, doc: "The server-rendered pressed state."
59
+ option :disabled, :boolean, default: false, doc: "Disables the control and forwards to the native button."
60
+ option :label, :string,
61
+ doc: "REQUIRED when icon-only; must be state-INVARIANT (APG: aria-pressed carries the state - a " \
62
+ "flipping name makes SRs announce nonsense)."
63
+
64
+ part "toggle", "The pressed-state <button> - the whole component; aria-pressed carries the " \
65
+ "state and the controller flips both together",
66
+ states: {
67
+ "data-pressed" => "pressed (bare presence boolean - absent when unpressed, never " \
68
+ "data-pressed=false)",
69
+ "data-disabled" => "disabled (rendered alongside native disabled for styling-hook parity)",
70
+ "data-variant" => { condition: "the visual variant", values: VARIANTS.map(&:to_s) },
71
+ "data-size" => { condition: "the size", values: SIZES.map(&:to_s) }
72
+ }
73
+
74
+ # An icon-only (or empty) toggle without an accessible name never
75
+ # ships.
76
+ # @api private
77
+ def before_render
78
+ return if label.present? || visible_text?
79
+
80
+ raise ArgumentError,
81
+ "icon-only Toggle requires label: (the accessible name, state-invariant - " \
82
+ "'Bookmark', never 'Remove bookmark')"
83
+ end
84
+
85
+ # @api private
86
+ def call
87
+ content_tag(:button, content, **root_attributes.to_attributes)
88
+ end
89
+
90
+ # @api private
91
+ def root_attributes
92
+ attrs = {
93
+ "type" => "button", "data-slot" => "toggle",
94
+ "aria-pressed" => pressed.to_s,
95
+ "data-variant" => variant, "data-size" => size,
96
+ "disabled" => disabled
97
+ }
98
+ # Pressed is a bare presence attribute: data-pressed when on,
99
+ # absent when off (never data-pressed=false).
100
+ attrs["data-pressed"] = "" if pressed
101
+ # data-disabled renders alongside native disabled - kept for
102
+ # styling-hook parity (and the group-context roving filter).
103
+ attrs["data-disabled"] = "" if disabled
104
+ attrs["aria-label"] = label if label.present?
105
+ html_attributes.merge_if_not_set(
106
+ attrs.merge(stimulus_attributes_for(:root)).merge(component_data_attributes)
107
+ )
108
+ end
109
+
110
+ private
111
+
112
+ def visible_text?
113
+ content? && content.to_s.gsub(/<[^>]+>/, " ").strip.present?
114
+ end
115
+
116
+ private :root_attributes
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Poetry
4
+ module Ui
5
+ module Toggle
6
+ # The Toggle preview matrix: 2 variants x 3 sizes x pressed states,
7
+ # icon-only (label enforced) and icon+text - the toggle-demo corpus.
8
+ class Preview < Poetry::Core::Preview::Base
9
+ # @!group Variants
10
+
11
+ # The toggle-demo port: icon-only bookmark with a state-invariant
12
+ # accessible name.
13
+ def default
14
+ render_component(label: "Bookmark") do |_component|
15
+ embed(Icon::Component.new(name: :bookmark))
16
+ end
17
+ end
18
+
19
+ def outline
20
+ render_component(variant: :outline, label: "Italic") do |_component|
21
+ embed(Icon::Component.new(name: :italic))
22
+ end
23
+ end
24
+
25
+ # @!endgroup
26
+
27
+ # @!group States
28
+
29
+ def pressed
30
+ render_component(pressed: true, label: "Bold") do |_component|
31
+ embed(Icon::Component.new(name: :bold))
32
+ end
33
+ end
34
+
35
+ def disabled
36
+ render_component(disabled: true, variant: :outline, label: "Underline") do |_component|
37
+ embed(Icon::Component.new(name: :underline))
38
+ end
39
+ end
40
+
41
+ def disabled_pressed
42
+ render_component(disabled: true, pressed: true, label: "Bold") do |_component|
43
+ embed(Icon::Component.new(name: :bold))
44
+ end
45
+ end
46
+
47
+ # @!endgroup
48
+
49
+ # @!group Sizes
50
+
51
+ def small
52
+ render_component(size: :sm, variant: :outline, label: "Italic") do |_component|
53
+ embed(Icon::Component.new(name: :italic))
54
+ end
55
+ end
56
+
57
+ def large
58
+ render_component(size: :lg, label: "Bold") do |_component|
59
+ embed(Icon::Component.new(name: :bold))
60
+ end
61
+ end
62
+
63
+ # @!endgroup
64
+
65
+ # @!group Composition
66
+
67
+ # toggle-with-text: the visible text IS the accessible name - no
68
+ # label: needed.
69
+ def with_text
70
+ render_component(variant: :outline) do |_component|
71
+ embed(Icon::Component.new(name: :italic)).concat("Italic")
72
+ end
73
+ end
74
+
75
+ # @!endgroup
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Poetry
4
+ module Ui
5
+ module Toggle
6
+ # Re-expressed through the cn-* theme layer. Still the family's
7
+ # shared dictionary: ToggleGroup items consume it through
8
+ # Toggle::Style.css (shared, never copied). The muted-not-accent
9
+ # hover note now reads off the theme rules: .cn-toggle hovers MUTED
10
+ # (pressed owns accent), .cn-toggle-variant-outline hovers accent -
11
+ # both source-exact, in themes/default.css. hover:bg-muted deviates
12
+ # from upstream's inline split DELIBERATELY: outline's themed accent
13
+ # hover can only beat it from the same layer (the split-side conflict
14
+ # rule - an inline utility would win the cascade unconditionally).
15
+ class Style < Poetry::Core::Style
16
+ base "cn-toggle group/toggle inline-flex items-center justify-center whitespace-nowrap " \
17
+ "outline-none focus-visible:ring-[3px] disabled:pointer-events-none " \
18
+ "disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0"
19
+
20
+ variant :variant, {
21
+ default: "cn-toggle-variant-default",
22
+ outline: "cn-toggle-variant-outline"
23
+ }
24
+
25
+ variant :size, {
26
+ default: "cn-toggle-size-default",
27
+ sm: "cn-toggle-size-sm",
28
+ lg: "cn-toggle-size-lg"
29
+ }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,4 @@
1
+ <%# Items render as DIRECT children - the segmented data-[spacing=0]
2
+ first:/last:/border-l-0 chain depends on DOM order with no stray
3
+ wrappers between items (stream-appends must land inside this root). %>
4
+ <%= content_tag(:div, safe_join(items.map(&:to_s)), **root_attributes.to_attributes) %>