phlex_kit 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (405) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README.md +135 -0
  4. data/app/assets/stylesheets/phlex_kit/_tokens.css +91 -0
  5. data/app/assets/stylesheets/phlex_kit/phlex_kit.css +82 -0
  6. data/app/components/phlex_kit/accordion/accordion.css +14 -0
  7. data/app/components/phlex_kit/accordion/accordion.rb +10 -0
  8. data/app/components/phlex_kit/accordion/accordion_content.rb +8 -0
  9. data/app/components/phlex_kit/accordion/accordion_default_content.rb +6 -0
  10. data/app/components/phlex_kit/accordion/accordion_default_trigger.rb +12 -0
  11. data/app/components/phlex_kit/accordion/accordion_icon.rb +16 -0
  12. data/app/components/phlex_kit/accordion/accordion_item.rb +12 -0
  13. data/app/components/phlex_kit/accordion/accordion_trigger.rb +8 -0
  14. data/app/components/phlex_kit/alert/alert.css +32 -0
  15. data/app/components/phlex_kit/alert/alert.rb +37 -0
  16. data/app/components/phlex_kit/alert/alert_description.rb +12 -0
  17. data/app/components/phlex_kit/alert/alert_title.rb +12 -0
  18. data/app/components/phlex_kit/alert_dialog/alert_dialog.css +37 -0
  19. data/app/components/phlex_kit/alert_dialog/alert_dialog.rb +20 -0
  20. data/app/components/phlex_kit/alert_dialog/alert_dialog_action.rb +14 -0
  21. data/app/components/phlex_kit/alert_dialog/alert_dialog_cancel.rb +13 -0
  22. data/app/components/phlex_kit/alert_dialog/alert_dialog_content.rb +19 -0
  23. data/app/components/phlex_kit/alert_dialog/alert_dialog_description.rb +12 -0
  24. data/app/components/phlex_kit/alert_dialog/alert_dialog_footer.rb +12 -0
  25. data/app/components/phlex_kit/alert_dialog/alert_dialog_header.rb +12 -0
  26. data/app/components/phlex_kit/alert_dialog/alert_dialog_title.rb +12 -0
  27. data/app/components/phlex_kit/alert_dialog/alert_dialog_trigger.rb +12 -0
  28. data/app/components/phlex_kit/aspect_ratio/aspect_ratio.css +12 -0
  29. data/app/components/phlex_kit/aspect_ratio/aspect_ratio.rb +27 -0
  30. data/app/components/phlex_kit/attachment/attachment.css +62 -0
  31. data/app/components/phlex_kit/attachment/attachment.rb +16 -0
  32. data/app/components/phlex_kit/attachment/attachment_action.rb +24 -0
  33. data/app/components/phlex_kit/attachment/attachment_actions.rb +7 -0
  34. data/app/components/phlex_kit/attachment/attachment_content.rb +7 -0
  35. data/app/components/phlex_kit/attachment/attachment_description.rb +7 -0
  36. data/app/components/phlex_kit/attachment/attachment_media.rb +8 -0
  37. data/app/components/phlex_kit/attachment/attachment_title.rb +7 -0
  38. data/app/components/phlex_kit/avatar/avatar.css +35 -0
  39. data/app/components/phlex_kit/avatar/avatar.rb +25 -0
  40. data/app/components/phlex_kit/avatar/avatar_fallback.rb +13 -0
  41. data/app/components/phlex_kit/avatar/avatar_group.rb +7 -0
  42. data/app/components/phlex_kit/avatar/avatar_image.rb +24 -0
  43. data/app/components/phlex_kit/badge/badge.css +50 -0
  44. data/app/components/phlex_kit/badge/badge.rb +39 -0
  45. data/app/components/phlex_kit/breadcrumb/breadcrumb.css +18 -0
  46. data/app/components/phlex_kit/breadcrumb/breadcrumb.rb +8 -0
  47. data/app/components/phlex_kit/breadcrumb/breadcrumb_ellipsis.rb +15 -0
  48. data/app/components/phlex_kit/breadcrumb/breadcrumb_item.rb +6 -0
  49. data/app/components/phlex_kit/breadcrumb/breadcrumb_link.rb +9 -0
  50. data/app/components/phlex_kit/breadcrumb/breadcrumb_list.rb +6 -0
  51. data/app/components/phlex_kit/breadcrumb/breadcrumb_page.rb +8 -0
  52. data/app/components/phlex_kit/breadcrumb/breadcrumb_separator.rb +10 -0
  53. data/app/components/phlex_kit/bubble/bubble.css +32 -0
  54. data/app/components/phlex_kit/bubble/bubble.rb +17 -0
  55. data/app/components/phlex_kit/bubble/bubble_content.rb +11 -0
  56. data/app/components/phlex_kit/bubble/bubble_group.rb +6 -0
  57. data/app/components/phlex_kit/bubble/bubble_reactions.rb +12 -0
  58. data/app/components/phlex_kit/button/button.css +72 -0
  59. data/app/components/phlex_kit/button/button.rb +51 -0
  60. data/app/components/phlex_kit/button_group/button_group.css +8 -0
  61. data/app/components/phlex_kit/button_group/button_group.rb +14 -0
  62. data/app/components/phlex_kit/calendar/calendar.css +109 -0
  63. data/app/components/phlex_kit/calendar/calendar.rb +47 -0
  64. data/app/components/phlex_kit/calendar/calendar_body.rb +13 -0
  65. data/app/components/phlex_kit/calendar/calendar_days.rb +98 -0
  66. data/app/components/phlex_kit/calendar/calendar_header.rb +13 -0
  67. data/app/components/phlex_kit/calendar/calendar_next.rb +40 -0
  68. data/app/components/phlex_kit/calendar/calendar_prev.rb +40 -0
  69. data/app/components/phlex_kit/calendar/calendar_title.rb +19 -0
  70. data/app/components/phlex_kit/calendar/calendar_weekdays.rb +27 -0
  71. data/app/components/phlex_kit/card/card.css +15 -0
  72. data/app/components/phlex_kit/card/card.rb +29 -0
  73. data/app/components/phlex_kit/card/card_content.rb +12 -0
  74. data/app/components/phlex_kit/card/card_description.rb +12 -0
  75. data/app/components/phlex_kit/card/card_footer.rb +12 -0
  76. data/app/components/phlex_kit/card/card_header.rb +12 -0
  77. data/app/components/phlex_kit/card/card_title.rb +12 -0
  78. data/app/components/phlex_kit/carousel/carousel.css +41 -0
  79. data/app/components/phlex_kit/carousel/carousel.rb +37 -0
  80. data/app/components/phlex_kit/carousel/carousel_content.rb +16 -0
  81. data/app/components/phlex_kit/carousel/carousel_item.rb +17 -0
  82. data/app/components/phlex_kit/carousel/carousel_next.rb +39 -0
  83. data/app/components/phlex_kit/carousel/carousel_previous.rb +40 -0
  84. data/app/components/phlex_kit/chart/chart.css +9 -0
  85. data/app/components/phlex_kit/chart/chart.rb +31 -0
  86. data/app/components/phlex_kit/checkbox/checkbox.css +27 -0
  87. data/app/components/phlex_kit/checkbox/checkbox.rb +26 -0
  88. data/app/components/phlex_kit/clipboard/clipboard.css +8 -0
  89. data/app/components/phlex_kit/clipboard/clipboard.rb +19 -0
  90. data/app/components/phlex_kit/clipboard/clipboard_popover.rb +14 -0
  91. data/app/components/phlex_kit/clipboard/clipboard_source.rb +6 -0
  92. data/app/components/phlex_kit/clipboard/clipboard_trigger.rb +6 -0
  93. data/app/components/phlex_kit/codeblock/codeblock.css +7 -0
  94. data/app/components/phlex_kit/codeblock/codeblock.rb +23 -0
  95. data/app/components/phlex_kit/collapsible/collapsible.css +3 -0
  96. data/app/components/phlex_kit/collapsible/collapsible.rb +13 -0
  97. data/app/components/phlex_kit/collapsible/collapsible_content.rb +8 -0
  98. data/app/components/phlex_kit/collapsible/collapsible_trigger.rb +8 -0
  99. data/app/components/phlex_kit/combobox/combobox.css +310 -0
  100. data/app/components/phlex_kit/combobox/combobox.rb +33 -0
  101. data/app/components/phlex_kit/combobox/combobox_badge.rb +15 -0
  102. data/app/components/phlex_kit/combobox/combobox_badge_trigger.rb +55 -0
  103. data/app/components/phlex_kit/combobox/combobox_checkbox.rb +21 -0
  104. data/app/components/phlex_kit/combobox/combobox_clear_button.rb +39 -0
  105. data/app/components/phlex_kit/combobox/combobox_empty_state.rb +17 -0
  106. data/app/components/phlex_kit/combobox/combobox_input_trigger.rb +69 -0
  107. data/app/components/phlex_kit/combobox/combobox_item.rb +19 -0
  108. data/app/components/phlex_kit/combobox/combobox_item_indicator.rb +27 -0
  109. data/app/components/phlex_kit/combobox/combobox_list.rb +12 -0
  110. data/app/components/phlex_kit/combobox/combobox_list_group.rb +14 -0
  111. data/app/components/phlex_kit/combobox/combobox_popover.rb +27 -0
  112. data/app/components/phlex_kit/combobox/combobox_radio.rb +26 -0
  113. data/app/components/phlex_kit/combobox/combobox_search_input.rb +49 -0
  114. data/app/components/phlex_kit/combobox/combobox_toggle_all_checkbox.rb +21 -0
  115. data/app/components/phlex_kit/combobox/combobox_trigger.rb +48 -0
  116. data/app/components/phlex_kit/command/command.css +104 -0
  117. data/app/components/phlex_kit/command/command.rb +18 -0
  118. data/app/components/phlex_kit/command/command_dialog.rb +19 -0
  119. data/app/components/phlex_kit/command/command_dialog_content.rb +37 -0
  120. data/app/components/phlex_kit/command/command_dialog_trigger.rb +22 -0
  121. data/app/components/phlex_kit/command/command_empty.rb +17 -0
  122. data/app/components/phlex_kit/command/command_group.rb +32 -0
  123. data/app/components/phlex_kit/command/command_input.rb +56 -0
  124. data/app/components/phlex_kit/command/command_item.rb +22 -0
  125. data/app/components/phlex_kit/command/command_list.rb +12 -0
  126. data/app/components/phlex_kit/context_menu/context_menu.css +19 -0
  127. data/app/components/phlex_kit/context_menu/context_menu.rb +11 -0
  128. data/app/components/phlex_kit/context_menu/context_menu_content.rb +8 -0
  129. data/app/components/phlex_kit/context_menu/context_menu_item.rb +25 -0
  130. data/app/components/phlex_kit/context_menu/context_menu_label.rb +11 -0
  131. data/app/components/phlex_kit/context_menu/context_menu_separator.rb +8 -0
  132. data/app/components/phlex_kit/context_menu/context_menu_trigger.rb +8 -0
  133. data/app/components/phlex_kit/data_table/data_table.css +110 -0
  134. data/app/components/phlex_kit/data_table/data_table.rb +25 -0
  135. data/app/components/phlex_kit/data_table/data_table_bulk_actions.rb +15 -0
  136. data/app/components/phlex_kit/data_table/data_table_column_toggle.rb +61 -0
  137. data/app/components/phlex_kit/data_table/data_table_expand_toggle.rb +40 -0
  138. data/app/components/phlex_kit/data_table/data_table_form.rb +36 -0
  139. data/app/components/phlex_kit/data_table/data_table_kaminari_adapter.rb +17 -0
  140. data/app/components/phlex_kit/data_table/data_table_manual_adapter.rb +18 -0
  141. data/app/components/phlex_kit/data_table/data_table_pagination.rb +98 -0
  142. data/app/components/phlex_kit/data_table/data_table_pagination_bar.rb +13 -0
  143. data/app/components/phlex_kit/data_table/data_table_pagy_adapter.rb +17 -0
  144. data/app/components/phlex_kit/data_table/data_table_per_page_select.rb +29 -0
  145. data/app/components/phlex_kit/data_table/data_table_row_checkbox.rb +24 -0
  146. data/app/components/phlex_kit/data_table/data_table_search.rb +51 -0
  147. data/app/components/phlex_kit/data_table/data_table_select_all_checkbox.rb +19 -0
  148. data/app/components/phlex_kit/data_table/data_table_selection_summary.rb +19 -0
  149. data/app/components/phlex_kit/data_table/data_table_sort_head.rb +82 -0
  150. data/app/components/phlex_kit/data_table/data_table_toolbar.rb +13 -0
  151. data/app/components/phlex_kit/date_picker/date_picker.css +28 -0
  152. data/app/components/phlex_kit/date_picker/date_picker.rb +71 -0
  153. data/app/components/phlex_kit/dialog/dialog.css +32 -0
  154. data/app/components/phlex_kit/dialog/dialog.rb +14 -0
  155. data/app/components/phlex_kit/dialog/dialog_content.rb +21 -0
  156. data/app/components/phlex_kit/dialog/dialog_description.rb +6 -0
  157. data/app/components/phlex_kit/dialog/dialog_footer.rb +6 -0
  158. data/app/components/phlex_kit/dialog/dialog_header.rb +6 -0
  159. data/app/components/phlex_kit/dialog/dialog_middle.rb +6 -0
  160. data/app/components/phlex_kit/dialog/dialog_title.rb +6 -0
  161. data/app/components/phlex_kit/dialog/dialog_trigger.rb +8 -0
  162. data/app/components/phlex_kit/drawer/drawer.css +54 -0
  163. data/app/components/phlex_kit/drawer/drawer.rb +18 -0
  164. data/app/components/phlex_kit/drawer/drawer_close.rb +9 -0
  165. data/app/components/phlex_kit/drawer/drawer_content.rb +21 -0
  166. data/app/components/phlex_kit/drawer/drawer_description.rb +7 -0
  167. data/app/components/phlex_kit/drawer/drawer_footer.rb +7 -0
  168. data/app/components/phlex_kit/drawer/drawer_header.rb +7 -0
  169. data/app/components/phlex_kit/drawer/drawer_title.rb +7 -0
  170. data/app/components/phlex_kit/drawer/drawer_trigger.rb +9 -0
  171. data/app/components/phlex_kit/dropdown_menu/dropdown_menu.css +38 -0
  172. data/app/components/phlex_kit/dropdown_menu/dropdown_menu.rb +22 -0
  173. data/app/components/phlex_kit/dropdown_menu/dropdown_menu_content.rb +23 -0
  174. data/app/components/phlex_kit/dropdown_menu/dropdown_menu_item.rb +22 -0
  175. data/app/components/phlex_kit/dropdown_menu/dropdown_menu_label.rb +12 -0
  176. data/app/components/phlex_kit/dropdown_menu/dropdown_menu_separator.rb +12 -0
  177. data/app/components/phlex_kit/dropdown_menu/dropdown_menu_trigger.rb +15 -0
  178. data/app/components/phlex_kit/empty/empty.css +25 -0
  179. data/app/components/phlex_kit/empty/empty.rb +6 -0
  180. data/app/components/phlex_kit/empty/empty_content.rb +6 -0
  181. data/app/components/phlex_kit/empty/empty_description.rb +6 -0
  182. data/app/components/phlex_kit/empty/empty_header.rb +6 -0
  183. data/app/components/phlex_kit/empty/empty_media.rb +14 -0
  184. data/app/components/phlex_kit/empty/empty_title.rb +6 -0
  185. data/app/components/phlex_kit/form/form.css +15 -0
  186. data/app/components/phlex_kit/form/form.rb +27 -0
  187. data/app/components/phlex_kit/form_field/form_field.css +31 -0
  188. data/app/components/phlex_kit/form_field/form_field.rb +31 -0
  189. data/app/components/phlex_kit/form_field/form_field_error.rb +19 -0
  190. data/app/components/phlex_kit/form_field/form_field_hint.rb +13 -0
  191. data/app/components/phlex_kit/form_field/form_field_label.rb +13 -0
  192. data/app/components/phlex_kit/hover_card/hover_card.css +8 -0
  193. data/app/components/phlex_kit/hover_card/hover_card.rb +10 -0
  194. data/app/components/phlex_kit/hover_card/hover_card_content.rb +8 -0
  195. data/app/components/phlex_kit/hover_card/hover_card_trigger.rb +6 -0
  196. data/app/components/phlex_kit/input/input.css +29 -0
  197. data/app/components/phlex_kit/input/input.rb +34 -0
  198. data/app/components/phlex_kit/input_group/input_group.css +35 -0
  199. data/app/components/phlex_kit/input_group/input_group.rb +15 -0
  200. data/app/components/phlex_kit/input_group/input_group_addon.rb +16 -0
  201. data/app/components/phlex_kit/input_group/input_group_text.rb +7 -0
  202. data/app/components/phlex_kit/input_otp/input_otp.css +32 -0
  203. data/app/components/phlex_kit/input_otp/input_otp.rb +29 -0
  204. data/app/components/phlex_kit/input_otp/input_otp_group.rb +7 -0
  205. data/app/components/phlex_kit/input_otp/input_otp_separator.rb +7 -0
  206. data/app/components/phlex_kit/input_otp/input_otp_slot.rb +27 -0
  207. data/app/components/phlex_kit/item/item.css +32 -0
  208. data/app/components/phlex_kit/item/item.rb +18 -0
  209. data/app/components/phlex_kit/item/item_actions.rb +7 -0
  210. data/app/components/phlex_kit/item/item_content.rb +7 -0
  211. data/app/components/phlex_kit/item/item_description.rb +7 -0
  212. data/app/components/phlex_kit/item/item_group.rb +7 -0
  213. data/app/components/phlex_kit/item/item_media.rb +7 -0
  214. data/app/components/phlex_kit/item/item_title.rb +7 -0
  215. data/app/components/phlex_kit/kbd/kbd.css +17 -0
  216. data/app/components/phlex_kit/kbd/kbd.rb +14 -0
  217. data/app/components/phlex_kit/kbd/kbd_group.rb +12 -0
  218. data/app/components/phlex_kit/label/label.css +12 -0
  219. data/app/components/phlex_kit/label/label.rb +14 -0
  220. data/app/components/phlex_kit/link/link.css +6 -0
  221. data/app/components/phlex_kit/link/link.rb +47 -0
  222. data/app/components/phlex_kit/masked_input/masked_input.rb +12 -0
  223. data/app/components/phlex_kit/menubar/menubar.css +66 -0
  224. data/app/components/phlex_kit/menubar/menubar.rb +24 -0
  225. data/app/components/phlex_kit/menubar/menubar_content.rb +9 -0
  226. data/app/components/phlex_kit/menubar/menubar_item.rb +26 -0
  227. data/app/components/phlex_kit/menubar/menubar_menu.rb +9 -0
  228. data/app/components/phlex_kit/menubar/menubar_separator.rb +7 -0
  229. data/app/components/phlex_kit/menubar/menubar_trigger.rb +14 -0
  230. data/app/components/phlex_kit/message/message.css +20 -0
  231. data/app/components/phlex_kit/message/message.rb +14 -0
  232. data/app/components/phlex_kit/message/message_avatar.rb +6 -0
  233. data/app/components/phlex_kit/message/message_content.rb +6 -0
  234. data/app/components/phlex_kit/message/message_footer.rb +6 -0
  235. data/app/components/phlex_kit/message/message_group.rb +6 -0
  236. data/app/components/phlex_kit/message/message_header.rb +6 -0
  237. data/app/components/phlex_kit/message_scroller/message_scroller.css +2 -0
  238. data/app/components/phlex_kit/message_scroller/message_scroller.rb +11 -0
  239. data/app/components/phlex_kit/native_select/native_select.css +51 -0
  240. data/app/components/phlex_kit/native_select/native_select.rb +48 -0
  241. data/app/components/phlex_kit/native_select/native_select_group.rb +13 -0
  242. data/app/components/phlex_kit/native_select/native_select_icon.rb +32 -0
  243. data/app/components/phlex_kit/native_select/native_select_option.rb +14 -0
  244. data/app/components/phlex_kit/navigation_menu/navigation_menu.css +67 -0
  245. data/app/components/phlex_kit/navigation_menu/navigation_menu.rb +23 -0
  246. data/app/components/phlex_kit/navigation_menu/navigation_menu_content.rb +9 -0
  247. data/app/components/phlex_kit/navigation_menu/navigation_menu_item.rb +9 -0
  248. data/app/components/phlex_kit/navigation_menu/navigation_menu_link.rb +13 -0
  249. data/app/components/phlex_kit/navigation_menu/navigation_menu_list.rb +7 -0
  250. data/app/components/phlex_kit/navigation_menu/navigation_menu_trigger.rb +27 -0
  251. data/app/components/phlex_kit/pagination/pagination.css +5 -0
  252. data/app/components/phlex_kit/pagination/pagination.rb +10 -0
  253. data/app/components/phlex_kit/pagination/pagination_content.rb +6 -0
  254. data/app/components/phlex_kit/pagination/pagination_ellipsis.rb +17 -0
  255. data/app/components/phlex_kit/pagination/pagination_item.rb +14 -0
  256. data/app/components/phlex_kit/popover/popover.css +9 -0
  257. data/app/components/phlex_kit/popover/popover.rb +11 -0
  258. data/app/components/phlex_kit/popover/popover_content.rb +8 -0
  259. data/app/components/phlex_kit/popover/popover_trigger.rb +8 -0
  260. data/app/components/phlex_kit/progress/progress.css +17 -0
  261. data/app/components/phlex_kit/progress/progress.rb +25 -0
  262. data/app/components/phlex_kit/radio_button/radio_button.css +9 -0
  263. data/app/components/phlex_kit/radio_button/radio_button.rb +19 -0
  264. data/app/components/phlex_kit/radio_group/radio_group.css +3 -0
  265. data/app/components/phlex_kit/radio_group/radio_group.rb +14 -0
  266. data/app/components/phlex_kit/resizable/resizable.css +23 -0
  267. data/app/components/phlex_kit/resizable/resizable_handle.rb +21 -0
  268. data/app/components/phlex_kit/resizable/resizable_panel.rb +19 -0
  269. data/app/components/phlex_kit/resizable/resizable_panel_group.rb +26 -0
  270. data/app/components/phlex_kit/scroll_area/scroll_area.css +21 -0
  271. data/app/components/phlex_kit/scroll_area/scroll_area.rb +15 -0
  272. data/app/components/phlex_kit/select/select.css +80 -0
  273. data/app/components/phlex_kit/select/select.rb +43 -0
  274. data/app/components/phlex_kit/select/select_content.rb +24 -0
  275. data/app/components/phlex_kit/select/select_group.rb +13 -0
  276. data/app/components/phlex_kit/select/select_input.rb +23 -0
  277. data/app/components/phlex_kit/select/select_item.rb +52 -0
  278. data/app/components/phlex_kit/select/select_label.rb +13 -0
  279. data/app/components/phlex_kit/select/select_trigger.rb +42 -0
  280. data/app/components/phlex_kit/select/select_value.rb +21 -0
  281. data/app/components/phlex_kit/separator/separator.css +6 -0
  282. data/app/components/phlex_kit/separator/separator.rb +30 -0
  283. data/app/components/phlex_kit/sheet/sheet.css +17 -0
  284. data/app/components/phlex_kit/sheet/sheet.rb +14 -0
  285. data/app/components/phlex_kit/sheet/sheet_content.rb +25 -0
  286. data/app/components/phlex_kit/sheet/sheet_description.rb +6 -0
  287. data/app/components/phlex_kit/sheet/sheet_footer.rb +6 -0
  288. data/app/components/phlex_kit/sheet/sheet_header.rb +6 -0
  289. data/app/components/phlex_kit/sheet/sheet_middle.rb +6 -0
  290. data/app/components/phlex_kit/sheet/sheet_title.rb +6 -0
  291. data/app/components/phlex_kit/sheet/sheet_trigger.rb +6 -0
  292. data/app/components/phlex_kit/shortcut_key/shortcut_key.css +17 -0
  293. data/app/components/phlex_kit/shortcut_key/shortcut_key.rb +9 -0
  294. data/app/components/phlex_kit/sidebar/sidebar.css +42 -0
  295. data/app/components/phlex_kit/sidebar/sidebar.rb +19 -0
  296. data/app/components/phlex_kit/sidebar/sidebar_content.rb +12 -0
  297. data/app/components/phlex_kit/sidebar/sidebar_footer.rb +12 -0
  298. data/app/components/phlex_kit/sidebar/sidebar_group.rb +12 -0
  299. data/app/components/phlex_kit/sidebar/sidebar_header.rb +12 -0
  300. data/app/components/phlex_kit/sidebar/sidebar_inset.rb +14 -0
  301. data/app/components/phlex_kit/sidebar/sidebar_menu.rb +12 -0
  302. data/app/components/phlex_kit/sidebar/sidebar_menu_button.rb +17 -0
  303. data/app/components/phlex_kit/sidebar/sidebar_menu_item.rb +12 -0
  304. data/app/components/phlex_kit/sidebar/sidebar_wrapper.rb +13 -0
  305. data/app/components/phlex_kit/skeleton/skeleton.css +7 -0
  306. data/app/components/phlex_kit/skeleton/skeleton.rb +9 -0
  307. data/app/components/phlex_kit/slider/slider.css +52 -0
  308. data/app/components/phlex_kit/slider/slider.rb +39 -0
  309. data/app/components/phlex_kit/spinner/spinner.css +5 -0
  310. data/app/components/phlex_kit/spinner/spinner.rb +27 -0
  311. data/app/components/phlex_kit/stars/stars.css +4 -0
  312. data/app/components/phlex_kit/stars/stars.rb +19 -0
  313. data/app/components/phlex_kit/switch/switch.css +28 -0
  314. data/app/components/phlex_kit/switch/switch.rb +21 -0
  315. data/app/components/phlex_kit/table/table.css +24 -0
  316. data/app/components/phlex_kit/table/table.rb +35 -0
  317. data/app/components/phlex_kit/table/table_body.rb +12 -0
  318. data/app/components/phlex_kit/table/table_caption.rb +12 -0
  319. data/app/components/phlex_kit/table/table_cell.rb +12 -0
  320. data/app/components/phlex_kit/table/table_footer.rb +12 -0
  321. data/app/components/phlex_kit/table/table_head.rb +12 -0
  322. data/app/components/phlex_kit/table/table_header.rb +12 -0
  323. data/app/components/phlex_kit/table/table_row.rb +12 -0
  324. data/app/components/phlex_kit/tabs/tabs.css +13 -0
  325. data/app/components/phlex_kit/tabs/tabs.rb +13 -0
  326. data/app/components/phlex_kit/tabs/tabs_content.rb +11 -0
  327. data/app/components/phlex_kit/tabs/tabs_list.rb +6 -0
  328. data/app/components/phlex_kit/tabs/tabs_trigger.rb +17 -0
  329. data/app/components/phlex_kit/textarea/textarea.css +27 -0
  330. data/app/components/phlex_kit/textarea/textarea.rb +24 -0
  331. data/app/components/phlex_kit/theme_toggle/theme_toggle.rb +15 -0
  332. data/app/components/phlex_kit/toast/toast.css +163 -0
  333. data/app/components/phlex_kit/toast/toast.rb +21 -0
  334. data/app/components/phlex_kit/toast/toast_action.rb +19 -0
  335. data/app/components/phlex_kit/toast/toast_cancel.rb +18 -0
  336. data/app/components/phlex_kit/toast/toast_close.rb +35 -0
  337. data/app/components/phlex_kit/toast/toast_description.rb +13 -0
  338. data/app/components/phlex_kit/toast/toast_icon.rb +63 -0
  339. data/app/components/phlex_kit/toast/toast_item.rb +70 -0
  340. data/app/components/phlex_kit/toast/toast_region.rb +121 -0
  341. data/app/components/phlex_kit/toast/toast_title.rb +13 -0
  342. data/app/components/phlex_kit/toggle/toggle.css +16 -0
  343. data/app/components/phlex_kit/toggle/toggle.rb +59 -0
  344. data/app/components/phlex_kit/toggle_group/toggle_group.css +10 -0
  345. data/app/components/phlex_kit/toggle_group/toggle_group.rb +65 -0
  346. data/app/components/phlex_kit/toggle_group/toggle_group_item.rb +37 -0
  347. data/app/components/phlex_kit/tooltip/tooltip.css +28 -0
  348. data/app/components/phlex_kit/tooltip/tooltip.rb +15 -0
  349. data/app/components/phlex_kit/tooltip/tooltip_content.rb +12 -0
  350. data/app/components/phlex_kit/tooltip/tooltip_trigger.rb +13 -0
  351. data/app/components/phlex_kit/typography/blockquote.rb +12 -0
  352. data/app/components/phlex_kit/typography/heading.rb +38 -0
  353. data/app/components/phlex_kit/typography/inline_code.rb +13 -0
  354. data/app/components/phlex_kit/typography/inline_link.rb +15 -0
  355. data/app/components/phlex_kit/typography/text.rb +48 -0
  356. data/app/components/phlex_kit/typography/typography.css +50 -0
  357. data/app/javascript/phlex_kit/controllers/accordion_controller.js +59 -0
  358. data/app/javascript/phlex_kit/controllers/alert_dialog_controller.js +24 -0
  359. data/app/javascript/phlex_kit/controllers/avatar_controller.js +30 -0
  360. data/app/javascript/phlex_kit/controllers/calendar_controller.js +316 -0
  361. data/app/javascript/phlex_kit/controllers/calendar_input_controller.js +10 -0
  362. data/app/javascript/phlex_kit/controllers/carousel_controller.js +189 -0
  363. data/app/javascript/phlex_kit/controllers/chart_controller.js +135 -0
  364. data/app/javascript/phlex_kit/controllers/clipboard_controller.js +30 -0
  365. data/app/javascript/phlex_kit/controllers/collapsible_controller.js +14 -0
  366. data/app/javascript/phlex_kit/controllers/combobox_controller.js +303 -0
  367. data/app/javascript/phlex_kit/controllers/command_controller.js +161 -0
  368. data/app/javascript/phlex_kit/controllers/command_dialog_controller.js +37 -0
  369. data/app/javascript/phlex_kit/controllers/context_menu_controller.js +28 -0
  370. data/app/javascript/phlex_kit/controllers/data_table_column_visibility_controller.js +18 -0
  371. data/app/javascript/phlex_kit/controllers/data_table_controller.js +61 -0
  372. data/app/javascript/phlex_kit/controllers/data_table_search_controller.js +67 -0
  373. data/app/javascript/phlex_kit/controllers/dialog_controller.js +20 -0
  374. data/app/javascript/phlex_kit/controllers/dropdown_menu_controller.js +106 -0
  375. data/app/javascript/phlex_kit/controllers/form_field_controller.js +69 -0
  376. data/app/javascript/phlex_kit/controllers/hover_card_controller.js +11 -0
  377. data/app/javascript/phlex_kit/controllers/index.js +87 -0
  378. data/app/javascript/phlex_kit/controllers/input_otp_controller.js +66 -0
  379. data/app/javascript/phlex_kit/controllers/masked_input_controller.js +26 -0
  380. data/app/javascript/phlex_kit/controllers/menubar_controller.js +43 -0
  381. data/app/javascript/phlex_kit/controllers/message_scroller_controller.js +335 -0
  382. data/app/javascript/phlex_kit/controllers/popover_controller.js +12 -0
  383. data/app/javascript/phlex_kit/controllers/resizable_controller.js +42 -0
  384. data/app/javascript/phlex_kit/controllers/select_controller.js +141 -0
  385. data/app/javascript/phlex_kit/controllers/select_item_controller.js +14 -0
  386. data/app/javascript/phlex_kit/controllers/sheet_content_controller.js +6 -0
  387. data/app/javascript/phlex_kit/controllers/sheet_controller.js +10 -0
  388. data/app/javascript/phlex_kit/controllers/slider_controller.js +19 -0
  389. data/app/javascript/phlex_kit/controllers/tabs_controller.js +28 -0
  390. data/app/javascript/phlex_kit/controllers/theme_toggle_controller.js +22 -0
  391. data/app/javascript/phlex_kit/controllers/toast_controller.js +153 -0
  392. data/app/javascript/phlex_kit/controllers/toaster_controller.js +321 -0
  393. data/app/javascript/phlex_kit/controllers/toggle_controller.js +25 -0
  394. data/app/javascript/phlex_kit/controllers/toggle_group_controller.js +91 -0
  395. data/config/importmap.rb +7 -0
  396. data/lib/generators/phlex_kit/component/component_generator.rb +41 -0
  397. data/lib/generators/phlex_kit/install/install_generator.rb +51 -0
  398. data/lib/generators/phlex_kit/install/templates/phlex_kit.rb +11 -0
  399. data/lib/phlex_kit/base_component.rb +22 -0
  400. data/lib/phlex_kit/configuration.rb +46 -0
  401. data/lib/phlex_kit/engine.rb +50 -0
  402. data/lib/phlex_kit/propshaft_skip_source.rb +22 -0
  403. data/lib/phlex_kit/version.rb +5 -0
  404. data/lib/phlex_kit.rb +21 -0
  405. metadata +545 -0
@@ -0,0 +1,41 @@
1
+ /* Co-located with carousel.rb — UI::Carousel. ruby_ui's structure kept
2
+ (viewport > flex track > basis-100% items, gap via negative margin + padding);
3
+ embla-carousel dropped, so the track is translated by the phlex-kit--carousel
4
+ controller and transitions here. Geometry from ruby_ui (1rem slide gap, 2rem
5
+ round edge buttons at -3rem). Theme tokens come from the global stylesheet. */
6
+ .pk-carousel { position: relative; }
7
+ .pk-carousel-viewport { overflow: hidden; cursor: grab; }
8
+ .pk-carousel-viewport.dragging { cursor: grabbing; user-select: none; }
9
+ /* Let the free axis keep scrolling the page on touch. */
10
+ .pk-carousel.is-horizontal .pk-carousel-viewport { touch-action: pan-y; }
11
+ .pk-carousel.is-vertical .pk-carousel-viewport { touch-action: pan-x; }
12
+ .pk-carousel-item img { -webkit-user-drag: none; }
13
+
14
+ .pk-carousel-track {
15
+ display: flex;
16
+ transition: transform .3s ease;
17
+ will-change: transform;
18
+ }
19
+ .pk-carousel.is-horizontal .pk-carousel-track { margin-left: -1rem; }
20
+ .pk-carousel.is-vertical .pk-carousel-track { flex-direction: column; margin-top: -1rem; }
21
+
22
+ .pk-carousel-item {
23
+ min-width: 0;
24
+ flex: 0 0 100%;
25
+ }
26
+ .pk-carousel.is-horizontal .pk-carousel-item { padding-left: 1rem; }
27
+ .pk-carousel.is-vertical .pk-carousel-item { padding-top: 1rem; }
28
+
29
+ /* Edge buttons (an outline icon .pk-button; same specificity, later in the
30
+ manifest, so these round overrides win). */
31
+ .pk-button.pk-carousel-previous, .pk-button.pk-carousel-next {
32
+ position: absolute;
33
+ width: 2rem;
34
+ height: 2rem;
35
+ border-radius: 9999px;
36
+ }
37
+ .pk-carousel.is-horizontal .pk-carousel-previous { left: -3rem; top: 50%; transform: translateY(-50%); }
38
+ .pk-carousel.is-horizontal .pk-carousel-next { right: -3rem; top: 50%; transform: translateY(-50%); }
39
+ .pk-carousel.is-vertical .pk-carousel-previous { top: -3rem; left: 50%; transform: translateX(-50%) rotate(90deg); }
40
+ .pk-carousel.is-vertical .pk-carousel-next { bottom: -3rem; left: 50%; transform: translateX(-50%) rotate(90deg); }
41
+ .pk-carousel-previous svg, .pk-carousel-next svg { width: 1rem; height: 1rem; }
@@ -0,0 +1,37 @@
1
+ module PhlexKit
2
+ # Carousel, ported from ruby_ui's RubyUI::Carousel. Upstream drives an
3
+ # embla-carousel instance; that npm dependency is dropped — the
4
+ # phlex-kit--carousel controller is a small translate-based engine (loop,
5
+ # x/y axis from the options value, arrow keys, pointer drag/swipe, button
6
+ # disabled state), so only @hotwired/stimulus is needed. Compose Carousel(orientation:) >
7
+ # CarouselContent > CarouselItem(s), plus CarouselPrevious / CarouselNext.
8
+ # Tailwind → vanilla `.pk-carousel*` (carousel.css).
9
+ class Carousel < BaseComponent
10
+ ORIENTATIONS = { horizontal: "is-horizontal", vertical: "is-vertical" }.freeze
11
+
12
+ def initialize(orientation: :horizontal, options: {}, **attrs)
13
+ @orientation = orientation.to_sym
14
+ @options = options
15
+ @attrs = attrs
16
+ end
17
+
18
+ def view_template(&)
19
+ div(**mix({
20
+ class: [ "pk-carousel", ORIENTATIONS.fetch(@orientation) ].join(" "),
21
+ role: "region",
22
+ aria: { roledescription: "carousel" },
23
+ data: {
24
+ controller: "phlex-kit--carousel",
25
+ phlex_kit__carousel_options_value: JSON.generate(default_options.merge(@options)),
26
+ action: "keydown.right->phlex-kit--carousel#scrollNext:prevent keydown.left->phlex-kit--carousel#scrollPrev:prevent"
27
+ }
28
+ }, @attrs), &)
29
+ end
30
+
31
+ private
32
+
33
+ def default_options
34
+ { axis: (@orientation == :horizontal) ? "x" : "y" }
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,16 @@
1
+ module PhlexKit
2
+ # The clipping viewport + sliding track holding the CarouselItems. The
3
+ # controller translates the track; orientation styling comes from the parent
4
+ # .pk-carousel's is-horizontal/is-vertical modifier. See carousel.rb.
5
+ class CarouselContent < BaseComponent
6
+ def initialize(**attrs)
7
+ @attrs = attrs
8
+ end
9
+
10
+ def view_template(&)
11
+ div(class: "pk-carousel-viewport", data: { phlex_kit__carousel_target: "viewport" }) do
12
+ div(**mix({ class: "pk-carousel-track" }, @attrs), &)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ module PhlexKit
2
+ # One slide in a PhlexKit::CarouselContent. Full-width/-height by default
3
+ # (basis 100%); override with `class:` for multi-up layouts. See carousel.rb.
4
+ class CarouselItem < BaseComponent
5
+ def initialize(**attrs)
6
+ @attrs = attrs
7
+ end
8
+
9
+ def view_template(&)
10
+ div(**mix({
11
+ role: "group",
12
+ aria: { roledescription: "slide" },
13
+ class: "pk-carousel-item"
14
+ }, @attrs), &)
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,39 @@
1
+ module PhlexKit
2
+ # Next-slide button — the CarouselPrevious counterpart on the trailing edge.
3
+ # See carousel.rb.
4
+ class CarouselNext < BaseComponent
5
+ def initialize(**attrs)
6
+ @attrs = attrs
7
+ end
8
+
9
+ def view_template
10
+ render Button.new(variant: :outline, icon: true, disabled: true, **mix({
11
+ class: "pk-carousel-next",
12
+ data: { action: "click->phlex-kit--carousel#scrollNext", phlex_kit__carousel_target: "nextButton" }
13
+ }, @attrs)) do
14
+ icon
15
+ span(class: "pk-sr-only") { "Next slide" }
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def icon
22
+ svg(
23
+ xmlns: "http://www.w3.org/2000/svg",
24
+ width: "24",
25
+ height: "24",
26
+ viewbox: "0 0 24 24",
27
+ fill: "none",
28
+ stroke: "currentColor",
29
+ "stroke-width": "2",
30
+ "stroke-linecap": "round",
31
+ "stroke-linejoin": "round",
32
+ "aria-hidden": "true"
33
+ ) do |s|
34
+ s.path(d: "M5 12h14")
35
+ s.path(d: "m12 5 7 7-7 7")
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,40 @@
1
+ module PhlexKit
2
+ # Previous-slide button — an outline icon PhlexKit::Button anchored outside the
3
+ # track edge (rotated 90° for vertical carousels). Starts disabled; the
4
+ # controller enables it once there is somewhere to scroll. See carousel.rb.
5
+ class CarouselPrevious < BaseComponent
6
+ def initialize(**attrs)
7
+ @attrs = attrs
8
+ end
9
+
10
+ def view_template
11
+ render Button.new(variant: :outline, icon: true, disabled: true, **mix({
12
+ class: "pk-carousel-previous",
13
+ data: { action: "click->phlex-kit--carousel#scrollPrev", phlex_kit__carousel_target: "prevButton" }
14
+ }, @attrs)) do
15
+ icon
16
+ span(class: "pk-sr-only") { "Previous slide" }
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def icon
23
+ svg(
24
+ xmlns: "http://www.w3.org/2000/svg",
25
+ width: "24",
26
+ height: "24",
27
+ viewbox: "0 0 24 24",
28
+ fill: "none",
29
+ stroke: "currentColor",
30
+ "stroke-width": "2",
31
+ "stroke-linecap": "round",
32
+ "stroke-linejoin": "round",
33
+ "aria-hidden": "true"
34
+ ) do |s|
35
+ s.path(d: "m12 19-7-7 7-7")
36
+ s.path(d: "M19 12H5")
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,9 @@
1
+ /* Co-located with chart.rb — UI::Chart (thin wrapper; the host supplies the
2
+ charting library). The canvas just fills its container — sizing is the chart
3
+ library's job once the host wires one up. Theme tokens come from the global
4
+ stylesheet (the controller reads them for chart.js defaults). */
5
+ .pk-chart {
6
+ display: block;
7
+ width: 100%;
8
+ max-width: 100%;
9
+ }
@@ -0,0 +1,31 @@
1
+ module PhlexKit
2
+ # Chart, ported from ruby_ui's RubyUI::Chart — as a thin wrapper only. ruby_ui
3
+ # bundles chart.js; this kit deliberately does NOT (no charting dependency).
4
+ # It renders the <canvas> plus the phlex-kit--chart Stimulus hook, which reads
5
+ # `options:` (a chart.js-shaped config hash) and then:
6
+ #
7
+ # * if the host exposes chart.js as `window.Chart`, builds the chart with
8
+ # ruby_ui's token-derived default colors (mapped to --pk-*), re-rendering
9
+ # on theme change;
10
+ # * otherwise dispatches "phlex-kit--chart:connect" with { canvas, options }
11
+ # so the host can drive any charting library it ships.
12
+ #
13
+ # render PhlexKit::Chart.new(options: { type: "line", data: { labels: [...],
14
+ # datasets: [{ data: [...] }] } })
15
+ class Chart < BaseComponent
16
+ def initialize(options: {}, **attrs)
17
+ @options = options
18
+ @attrs = attrs
19
+ end
20
+
21
+ def view_template(&)
22
+ canvas(**mix({
23
+ class: "pk-chart",
24
+ data: {
25
+ controller: "phlex-kit--chart",
26
+ phlex_kit__chart_options_value: JSON.generate(@options)
27
+ }
28
+ }, @attrs), &)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,27 @@
1
+ /* Co-located with checkbox.rb — UI::Checkbox. ruby_ui draws a fully custom box
2
+ with peer/checked Tailwind utilities; we instead let the native control render
3
+ and tint it with the brand token via accent-color (themes correctly on the
4
+ dark background, no SVG). Vanilla CSS, our own look, redesign later. Theme
5
+ tokens come from the global stylesheet. */
6
+ .pk-checkbox {
7
+ width: 1rem;
8
+ height: 1rem;
9
+ border-radius: calc(var(--pk-radius) - 4px);
10
+ accent-color: var(--pk-brand);
11
+ cursor: pointer;
12
+ }
13
+ .pk-checkbox:focus-visible {
14
+ outline: none;
15
+ box-shadow: 0 0 0 3px color-mix(in oklab, var(--pk-ring) 50%, transparent);
16
+ }
17
+ .pk-checkbox:disabled { cursor: not-allowed; opacity: .5; }
18
+
19
+ /* A checkbox paired inline with its label (ruby_ui's `flex items-center
20
+ space-x-3` row). Used for checkbox lists like store-assignment; vertical
21
+ rhythm between rows comes from the enclosing UI::FormField's flex gap. */
22
+ .pk-checkbox-row {
23
+ display: flex;
24
+ align-items: center;
25
+ gap: .5rem;
26
+ font-weight: 400;
27
+ }
@@ -0,0 +1,26 @@
1
+ module PhlexKit
2
+ # Checkbox, ported from ruby_ui's RubyUI::Checkbox. ruby_ui pairs it with a
3
+ # CheckboxGroup Stimulus controller (cross-box "at least one required"
4
+ # coordination); that's deliberately NOT ported — it's client behaviour we
5
+ # don't need yet, and per the kit's convention reactivity belongs in feature
6
+ # components, not PhlexKit:: primitives. Like upstream it registers as a
7
+ # phlex-kit--form-field input target (live validation inside a FormField);
8
+ # `name:`/`value:`/`checked:`/`**on(...)` pass through via `mix`. Styled by
9
+ # `.pk-checkbox` (checkbox.css).
10
+ class Checkbox < BaseComponent
11
+ def initialize(**attrs)
12
+ @attrs = attrs
13
+ end
14
+
15
+ def view_template
16
+ input(**mix({
17
+ type: :checkbox,
18
+ class: "pk-checkbox",
19
+ data: {
20
+ phlex_kit__form_field_target: "input",
21
+ action: "change->phlex-kit--form-field#onInput invalid->phlex-kit--form-field#onInvalid"
22
+ }
23
+ }, @attrs))
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,8 @@
1
+ /* Co-located with clipboard.rb. CSS-positioned confirmation popover. Tokens global. */
2
+ .pk-clipboard { position: relative; display: inline-block; }
3
+ .pk-clipboard-trigger { display: inline-block; }
4
+ .pk-clipboard-popover { position: absolute; bottom: calc(100% + .5rem); left: 50%; transform: translateX(-50%); z-index: 50; width: max-content; }
5
+ .pk-clipboard-popover-inner {
6
+ border: 1px solid var(--pk-border); border-radius: calc(var(--pk-radius) - 2px); background: var(--pk-surface);
7
+ color: var(--pk-text); padding: .125rem .5rem; font-size: .875rem; box-shadow: 0 8px 24px rgb(0 0 0 / .3);
8
+ }
@@ -0,0 +1,19 @@
1
+ module PhlexKit
2
+ # Copy-to-clipboard with success/error confirmation popovers (CSS-positioned,
3
+ # no @floating-ui). Ported from ruby_ui's RubyUI::Clipboard. Compose Clipboard >
4
+ # (ClipboardSource + ClipboardTrigger). phlex-kit--clipboard.
5
+ class Clipboard < BaseComponent
6
+ def initialize(success: "Copied!", error: "Copy failed!", **attrs)
7
+ @success = success
8
+ @error = error
9
+ @attrs = attrs
10
+ end
11
+ def view_template(&block)
12
+ div(**mix({ class: "pk-clipboard", data: { controller: "phlex-kit--clipboard", action: "click@window->phlex-kit--clipboard#onClickOutside" } }, @attrs)) do
13
+ div(&block)
14
+ render PhlexKit::ClipboardPopover.new(type: :success) { @success }
15
+ render PhlexKit::ClipboardPopover.new(type: :error) { @error }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ module PhlexKit
2
+ class ClipboardPopover < BaseComponent
3
+ TARGETS = { success: "successPopover", error: "errorPopover" }.freeze
4
+ def initialize(type:, **attrs)
5
+ @type = type.to_sym
6
+ @attrs = attrs
7
+ end
8
+ def view_template(&block)
9
+ div(class: "pk-clipboard-popover pk-hidden", data: { phlex_kit__clipboard_target: TARGETS.fetch(@type) }) do
10
+ div(**mix({ class: "pk-clipboard-popover-inner" }, @attrs), &block)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ module PhlexKit
2
+ class ClipboardSource < BaseComponent
3
+ def initialize(**attrs) = (@attrs = attrs)
4
+ def view_template(&) = div(**mix({ data: { phlex_kit__clipboard_target: "source" } }, @attrs), &)
5
+ end
6
+ end
@@ -0,0 +1,6 @@
1
+ module PhlexKit
2
+ class ClipboardTrigger < BaseComponent
3
+ def initialize(**attrs) = (@attrs = attrs)
4
+ def view_template(&) = div(**mix({ class: "pk-clipboard-trigger", data: { phlex_kit__clipboard_target: "trigger", action: "click->phlex-kit--clipboard#copy" } }, @attrs), &)
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ /* Co-located with codeblock.rb. Plain (unhighlighted) code block. Tokens global. */
2
+ .pk-codeblock {
3
+ overflow: auto; border: 1px solid var(--pk-border); border-radius: calc(var(--pk-radius) - 2px);
4
+ background: var(--pk-surface-2); font-size: .875rem;
5
+ }
6
+ .pk-codeblock pre { margin: 0; padding: 1rem; }
7
+ .pk-codeblock code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--pk-text); }
@@ -0,0 +1,23 @@
1
+ module PhlexKit
2
+ # Preformatted code block. Ported from ruby_ui's RubyUI::Codeblock, minus the
3
+ # server-side syntax highlighting (ruby_ui uses the `rouge` gem). Ships a plain
4
+ # styled <pre><code>; add rouge yourself and pass pre-highlighted HTML if wanted.
5
+ class Codeblock < BaseComponent
6
+ def initialize(code = nil, syntax: nil, **attrs)
7
+ @code = code
8
+ @syntax = syntax
9
+ @attrs = attrs
10
+ end
11
+ def view_template(&block)
12
+ div(**mix({ class: "pk-codeblock", data: { syntax: @syntax } }, @attrs)) do
13
+ pre do
14
+ if block
15
+ code(&block)
16
+ else
17
+ code { @code }
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ /* Co-located with collapsible.rb. Theme tokens from the global stylesheet. */
2
+ .pk-collapsible-trigger { cursor: pointer; }
3
+ .pk-collapsible-content { overflow-y: hidden; }
@@ -0,0 +1,13 @@
1
+ module PhlexKit
2
+ # Show/hide a single region. Ported from ruby_ui's RubyUI::Collapsible. Compose
3
+ # Collapsible > (CollapsibleTrigger + CollapsibleContent). phlex-kit--collapsible.
4
+ class Collapsible < BaseComponent
5
+ def initialize(open: false, **attrs)
6
+ @open = open
7
+ @attrs = attrs
8
+ end
9
+ def view_template(&)
10
+ div(**mix({ class: "pk-collapsible", data: { controller: "phlex-kit--collapsible", phlex_kit__collapsible_open_value: @open } }, @attrs), &)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ module PhlexKit
2
+ class CollapsibleContent < BaseComponent
3
+ def initialize(**attrs) = (@attrs = attrs)
4
+ def view_template(&)
5
+ div(**mix({ class: "pk-collapsible-content", data: { phlex_kit__collapsible_target: "content" } }, @attrs), &)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ module PhlexKit
2
+ class CollapsibleTrigger < BaseComponent
3
+ def initialize(**attrs) = (@attrs = attrs)
4
+ def view_template(&)
5
+ div(**mix({ class: "pk-collapsible-trigger", data: { action: "click->phlex-kit--collapsible#toggle" } }, @attrs), &)
6
+ end
7
+ end
8
+ end