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.
- checksums.yaml +7 -0
- data/.gitattributes +6 -0
- data/CHANGELOG.md +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +87 -0
- data/THIRD_PARTY_NOTICES.md +201 -0
- data/app/components/poetry/ui/accordion/component.html.erb +3 -0
- data/app/components/poetry/ui/accordion/component.rb +197 -0
- data/app/components/poetry/ui/accordion/preview.rb +39 -0
- data/app/components/poetry/ui/accordion/style.rb +37 -0
- data/app/components/poetry/ui/alert/component.html.erb +6 -0
- data/app/components/poetry/ui/alert/component.rb +61 -0
- data/app/components/poetry/ui/alert/preview.rb +35 -0
- data/app/components/poetry/ui/alert/style.rb +24 -0
- data/app/components/poetry/ui/alert_dialog/component.html.erb +17 -0
- data/app/components/poetry/ui/alert_dialog/component.rb +208 -0
- data/app/components/poetry/ui/alert_dialog/preview.rb +48 -0
- data/app/components/poetry/ui/alert_dialog/style.rb +46 -0
- data/app/components/poetry/ui/aspect_ratio/component.rb +63 -0
- data/app/components/poetry/ui/aspect_ratio/preview.rb +29 -0
- data/app/components/poetry/ui/aspect_ratio/style.rb +13 -0
- data/app/components/poetry/ui/attachment/component.html.erb +13 -0
- data/app/components/poetry/ui/attachment/component.rb +139 -0
- data/app/components/poetry/ui/attachment/preview.rb +83 -0
- data/app/components/poetry/ui/attachment/style.rb +59 -0
- data/app/components/poetry/ui/autocomplete/component.html.erb +16 -0
- data/app/components/poetry/ui/autocomplete/component.rb +193 -0
- data/app/components/poetry/ui/autocomplete/preview.rb +39 -0
- data/app/components/poetry/ui/autocomplete/style.rb +18 -0
- data/app/components/poetry/ui/avatar/component.rb +103 -0
- data/app/components/poetry/ui/avatar/group_preview.html.erb +11 -0
- data/app/components/poetry/ui/avatar/preview.rb +50 -0
- data/app/components/poetry/ui/avatar/style.rb +34 -0
- data/app/components/poetry/ui/badge/component.rb +73 -0
- data/app/components/poetry/ui/badge/preview.rb +54 -0
- data/app/components/poetry/ui/badge/style.rb +35 -0
- data/app/components/poetry/ui/breadcrumb/component.html.erb +32 -0
- data/app/components/poetry/ui/breadcrumb/component.rb +102 -0
- data/app/components/poetry/ui/breadcrumb/dropdown_crumb_preview.html.erb +21 -0
- data/app/components/poetry/ui/breadcrumb/preview.rb +45 -0
- data/app/components/poetry/ui/breadcrumb/style.rb +25 -0
- data/app/components/poetry/ui/bubble/component.html.erb +4 -0
- data/app/components/poetry/ui/bubble/component.rb +106 -0
- data/app/components/poetry/ui/bubble/preview.rb +62 -0
- data/app/components/poetry/ui/bubble/style.rb +47 -0
- data/app/components/poetry/ui/button/component.html.erb +14 -0
- data/app/components/poetry/ui/button/component.rb +168 -0
- data/app/components/poetry/ui/button/preview.rb +94 -0
- data/app/components/poetry/ui/button/style.rb +41 -0
- data/app/components/poetry/ui/button_group/component.rb +70 -0
- data/app/components/poetry/ui/button_group/popup_triggers_preview.html.erb +21 -0
- data/app/components/poetry/ui/button_group/preview.rb +46 -0
- data/app/components/poetry/ui/button_group/style.rb +27 -0
- data/app/components/poetry/ui/button_group/text_prefix_preview.html.erb +7 -0
- data/app/components/poetry/ui/calendar/component.html.erb +72 -0
- data/app/components/poetry/ui/calendar/component.rb +366 -0
- data/app/components/poetry/ui/calendar/preview.rb +55 -0
- data/app/components/poetry/ui/calendar/style.rb +55 -0
- data/app/components/poetry/ui/card/component.html.erb +11 -0
- data/app/components/poetry/ui/card/component.rb +90 -0
- data/app/components/poetry/ui/card/preview.rb +29 -0
- data/app/components/poetry/ui/card/style.rb +23 -0
- data/app/components/poetry/ui/carousel/component.html.erb +17 -0
- data/app/components/poetry/ui/carousel/component.rb +179 -0
- data/app/components/poetry/ui/carousel/preview.rb +67 -0
- data/app/components/poetry/ui/carousel/style.rb +39 -0
- data/app/components/poetry/ui/checkbox/component.html.erb +22 -0
- data/app/components/poetry/ui/checkbox/component.rb +179 -0
- data/app/components/poetry/ui/checkbox/preview.rb +68 -0
- data/app/components/poetry/ui/checkbox/style.rb +28 -0
- data/app/components/poetry/ui/clipboard_text/component.html.erb +15 -0
- data/app/components/poetry/ui/clipboard_text/component.rb +154 -0
- data/app/components/poetry/ui/clipboard_text/preview.rb +24 -0
- data/app/components/poetry/ui/clipboard_text/style.rb +23 -0
- data/app/components/poetry/ui/code_block/component.html.erb +13 -0
- data/app/components/poetry/ui/code_block/component.rb +141 -0
- data/app/components/poetry/ui/code_block/preview.rb +40 -0
- data/app/components/poetry/ui/code_block/style.rb +38 -0
- data/app/components/poetry/ui/collapsible/component.html.erb +4 -0
- data/app/components/poetry/ui/collapsible/component.rb +134 -0
- data/app/components/poetry/ui/collapsible/preview.rb +24 -0
- data/app/components/poetry/ui/combobox/component.html.erb +49 -0
- data/app/components/poetry/ui/combobox/component.rb +1086 -0
- data/app/components/poetry/ui/combobox/preview.rb +164 -0
- data/app/components/poetry/ui/combobox/style.rb +148 -0
- data/app/components/poetry/ui/command/component.html.erb +20 -0
- data/app/components/poetry/ui/command/component.rb +526 -0
- data/app/components/poetry/ui/command/dialog_component.html.erb +14 -0
- data/app/components/poetry/ui/command/dialog_component.rb +206 -0
- data/app/components/poetry/ui/command/dialog_preview.rb +39 -0
- data/app/components/poetry/ui/command/preview.rb +121 -0
- data/app/components/poetry/ui/command/style.rb +78 -0
- data/app/components/poetry/ui/composable_trigger.rb +63 -0
- data/app/components/poetry/ui/context_menu/component.html.erb +6 -0
- data/app/components/poetry/ui/context_menu/component.rb +358 -0
- data/app/components/poetry/ui/context_menu/preview.rb +111 -0
- data/app/components/poetry/ui/context_menu/style.rb +59 -0
- data/app/components/poetry/ui/data_table/component.html.erb +78 -0
- data/app/components/poetry/ui/data_table/component.rb +277 -0
- data/app/components/poetry/ui/data_table/preview.rb +68 -0
- data/app/components/poetry/ui/data_table/state.rb +115 -0
- data/app/components/poetry/ui/data_table/style.rb +42 -0
- data/app/components/poetry/ui/date_field/component.html.erb +7 -0
- data/app/components/poetry/ui/date_field/component.rb +209 -0
- data/app/components/poetry/ui/date_field/preview.rb +42 -0
- data/app/components/poetry/ui/date_field/style.rb +35 -0
- data/app/components/poetry/ui/date_picker/component.html.erb +23 -0
- data/app/components/poetry/ui/date_picker/component.rb +242 -0
- data/app/components/poetry/ui/date_picker/preview.rb +31 -0
- data/app/components/poetry/ui/date_picker/style.rb +25 -0
- data/app/components/poetry/ui/deferred/component.html.erb +16 -0
- data/app/components/poetry/ui/deferred/component.rb +90 -0
- data/app/components/poetry/ui/deferred/preview.rb +24 -0
- data/app/components/poetry/ui/dialog/component.html.erb +21 -0
- data/app/components/poetry/ui/dialog/component.rb +194 -0
- data/app/components/poetry/ui/dialog/preview.rb +33 -0
- data/app/components/poetry/ui/dialog/style.rb +30 -0
- data/app/components/poetry/ui/drawer/component.html.erb +16 -0
- data/app/components/poetry/ui/drawer/component.rb +207 -0
- data/app/components/poetry/ui/drawer/preview.rb +69 -0
- data/app/components/poetry/ui/drawer/style.rb +105 -0
- data/app/components/poetry/ui/dropdown_menu/component.html.erb +6 -0
- data/app/components/poetry/ui/dropdown_menu/component.rb +350 -0
- data/app/components/poetry/ui/dropdown_menu/preview.rb +101 -0
- data/app/components/poetry/ui/dropdown_menu/style.rb +60 -0
- data/app/components/poetry/ui/empty/component.html.erb +10 -0
- data/app/components/poetry/ui/empty/component.rb +79 -0
- data/app/components/poetry/ui/empty/preview.rb +27 -0
- data/app/components/poetry/ui/empty/style.rb +27 -0
- data/app/components/poetry/ui/family_identity.rb +52 -0
- data/app/components/poetry/ui/field/component.html.erb +19 -0
- data/app/components/poetry/ui/field/component.rb +183 -0
- data/app/components/poetry/ui/field/preview.html.erb +30 -0
- data/app/components/poetry/ui/field/preview.rb +72 -0
- data/app/components/poetry/ui/field/style.rb +68 -0
- data/app/components/poetry/ui/field_group/component.rb +61 -0
- data/app/components/poetry/ui/field_group/preview.html.erb +30 -0
- data/app/components/poetry/ui/field_group/preview.rb +20 -0
- data/app/components/poetry/ui/field_group/style.rb +25 -0
- data/app/components/poetry/ui/field_separator/component.rb +70 -0
- data/app/components/poetry/ui/field_separator/preview.rb +18 -0
- data/app/components/poetry/ui/field_separator/style.rb +20 -0
- data/app/components/poetry/ui/fieldset/component.rb +90 -0
- data/app/components/poetry/ui/fieldset/preview.html.erb +22 -0
- data/app/components/poetry/ui/fieldset/preview.rb +25 -0
- data/app/components/poetry/ui/fieldset/style.rb +18 -0
- data/app/components/poetry/ui/file_input/component.html.erb +14 -0
- data/app/components/poetry/ui/file_input/component.rb +188 -0
- data/app/components/poetry/ui/file_input/preview.rb +30 -0
- data/app/components/poetry/ui/file_input/style.rb +35 -0
- data/app/components/poetry/ui/hover_card/component.html.erb +6 -0
- data/app/components/poetry/ui/hover_card/component.rb +201 -0
- data/app/components/poetry/ui/hover_card/preview.rb +60 -0
- data/app/components/poetry/ui/hover_card/style.rb +17 -0
- data/app/components/poetry/ui/icon/component.rb +127 -0
- data/app/components/poetry/ui/icon/preview.rb +21 -0
- data/app/components/poetry/ui/input/component.rb +80 -0
- data/app/components/poetry/ui/input/preview.rb +35 -0
- data/app/components/poetry/ui/input/style.rb +18 -0
- data/app/components/poetry/ui/input_group/button_preview.html.erb +12 -0
- data/app/components/poetry/ui/input_group/component.rb +69 -0
- data/app/components/poetry/ui/input_group/preview.rb +23 -0
- data/app/components/poetry/ui/input_group/search_preview.html.erb +13 -0
- data/app/components/poetry/ui/input_group/style.rb +40 -0
- data/app/components/poetry/ui/input_group/textarea_preview.html.erb +10 -0
- data/app/components/poetry/ui/input_group_field.rb +61 -0
- data/app/components/poetry/ui/input_otp/component.html.erb +25 -0
- data/app/components/poetry/ui/input_otp/component.rb +250 -0
- data/app/components/poetry/ui/input_otp/preview.rb +91 -0
- data/app/components/poetry/ui/input_otp/style.rb +36 -0
- data/app/components/poetry/ui/item/component.html.erb +13 -0
- data/app/components/poetry/ui/item/component.rb +99 -0
- data/app/components/poetry/ui/item/group_preview.html.erb +15 -0
- data/app/components/poetry/ui/item/preview.rb +52 -0
- data/app/components/poetry/ui/item/style.rb +45 -0
- data/app/components/poetry/ui/kbd/component.rb +47 -0
- data/app/components/poetry/ui/kbd/group_preview.html.erb +4 -0
- data/app/components/poetry/ui/kbd/preview.rb +23 -0
- data/app/components/poetry/ui/kbd/style.rb +13 -0
- data/app/components/poetry/ui/label/component.rb +46 -0
- data/app/components/poetry/ui/label/preview.html.erb +5 -0
- data/app/components/poetry/ui/label/preview.rb +16 -0
- data/app/components/poetry/ui/label/style.rb +13 -0
- data/app/components/poetry/ui/link/component.rb +62 -0
- data/app/components/poetry/ui/link/preview.rb +31 -0
- data/app/components/poetry/ui/link/style.rb +20 -0
- data/app/components/poetry/ui/marker/component.html.erb +4 -0
- data/app/components/poetry/ui/marker/component.rb +81 -0
- data/app/components/poetry/ui/marker/preview.rb +43 -0
- data/app/components/poetry/ui/marker/style.rb +24 -0
- data/app/components/poetry/ui/menubar/component.html.erb +3 -0
- data/app/components/poetry/ui/menubar/component.rb +493 -0
- data/app/components/poetry/ui/menubar/preview.rb +164 -0
- data/app/components/poetry/ui/menubar/style.rb +71 -0
- data/app/components/poetry/ui/menus.rb +386 -0
- data/app/components/poetry/ui/message/component.html.erb +8 -0
- data/app/components/poetry/ui/message/component.rb +64 -0
- data/app/components/poetry/ui/message/preview.rb +33 -0
- data/app/components/poetry/ui/message/style.rb +29 -0
- data/app/components/poetry/ui/message_scroller/component.html.erb +15 -0
- data/app/components/poetry/ui/message_scroller/component.rb +163 -0
- data/app/components/poetry/ui/message_scroller/preview.rb +33 -0
- data/app/components/poetry/ui/message_scroller/style.rb +39 -0
- data/app/components/poetry/ui/metadata_list/component.rb +88 -0
- data/app/components/poetry/ui/metadata_list/preview.rb +55 -0
- data/app/components/poetry/ui/metadata_list/style.rb +35 -0
- data/app/components/poetry/ui/meter/component.rb +117 -0
- data/app/components/poetry/ui/meter/preview.rb +28 -0
- data/app/components/poetry/ui/meter/style.rb +16 -0
- data/app/components/poetry/ui/native_select/component.rb +124 -0
- data/app/components/poetry/ui/native_select/labelled_preview.html.erb +7 -0
- data/app/components/poetry/ui/native_select/preview.rb +20 -0
- data/app/components/poetry/ui/native_select/style.rb +22 -0
- data/app/components/poetry/ui/navigation_menu/bar_preview.html.erb +14 -0
- data/app/components/poetry/ui/navigation_menu/component.html.erb +25 -0
- data/app/components/poetry/ui/navigation_menu/component.rb +254 -0
- data/app/components/poetry/ui/navigation_menu/preview.rb +20 -0
- data/app/components/poetry/ui/navigation_menu/style.rb +73 -0
- data/app/components/poetry/ui/navigation_menu/viewport_preview.html.erb +23 -0
- data/app/components/poetry/ui/number_field/component.html.erb +19 -0
- data/app/components/poetry/ui/number_field/component.rb +263 -0
- data/app/components/poetry/ui/number_field/preview.rb +66 -0
- data/app/components/poetry/ui/number_field/style.rb +14 -0
- data/app/components/poetry/ui/pagination/component.html.erb +40 -0
- data/app/components/poetry/ui/pagination/component.rb +182 -0
- data/app/components/poetry/ui/pagination/preview.rb +47 -0
- data/app/components/poetry/ui/pagination/style.rb +27 -0
- data/app/components/poetry/ui/popover/component.html.erb +17 -0
- data/app/components/poetry/ui/popover/component.rb +203 -0
- data/app/components/poetry/ui/popover/preview.html.erb +29 -0
- data/app/components/poetry/ui/popover/preview.rb +66 -0
- data/app/components/poetry/ui/popover/style.rb +26 -0
- data/app/components/poetry/ui/popper_consumer.rb +69 -0
- data/app/components/poetry/ui/progress/component.rb +95 -0
- data/app/components/poetry/ui/progress/preview.rb +22 -0
- data/app/components/poetry/ui/progress/style.rb +19 -0
- data/app/components/poetry/ui/questionnaire/component.html.erb +80 -0
- data/app/components/poetry/ui/questionnaire/component.rb +396 -0
- data/app/components/poetry/ui/questionnaire/preview.rb +99 -0
- data/app/components/poetry/ui/questionnaire/style.rb +53 -0
- data/app/components/poetry/ui/radio_group/component.html.erb +4 -0
- data/app/components/poetry/ui/radio_group/component.rb +323 -0
- data/app/components/poetry/ui/radio_group/preview.rb +109 -0
- data/app/components/poetry/ui/radio_group/style.rb +53 -0
- data/app/components/poetry/ui/resizable/component.html.erb +10 -0
- data/app/components/poetry/ui/resizable/component.rb +178 -0
- data/app/components/poetry/ui/resizable/preview.rb +42 -0
- data/app/components/poetry/ui/resizable/style.rb +30 -0
- data/app/components/poetry/ui/scroll_area/component.rb +76 -0
- data/app/components/poetry/ui/scroll_area/preview.rb +35 -0
- data/app/components/poetry/ui/scroll_area/style.rb +19 -0
- data/app/components/poetry/ui/search_field/component.html.erb +15 -0
- data/app/components/poetry/ui/search_field/component.rb +137 -0
- data/app/components/poetry/ui/search_field/preview.rb +23 -0
- data/app/components/poetry/ui/search_field/style.rb +18 -0
- data/app/components/poetry/ui/select/component.html.erb +15 -0
- data/app/components/poetry/ui/select/component.rb +639 -0
- data/app/components/poetry/ui/select/preview.rb +113 -0
- data/app/components/poetry/ui/select/style.rb +58 -0
- data/app/components/poetry/ui/sensitive_input/component.html.erb +29 -0
- data/app/components/poetry/ui/sensitive_input/component.rb +274 -0
- data/app/components/poetry/ui/sensitive_input/preview.rb +40 -0
- data/app/components/poetry/ui/sensitive_input/style.rb +49 -0
- data/app/components/poetry/ui/separator/component.rb +57 -0
- data/app/components/poetry/ui/separator/preview.rb +19 -0
- data/app/components/poetry/ui/separator/style.rb +15 -0
- data/app/components/poetry/ui/sheet/component.html.erb +21 -0
- data/app/components/poetry/ui/sheet/component.rb +97 -0
- data/app/components/poetry/ui/sheet/preview.rb +57 -0
- data/app/components/poetry/ui/sheet/style.rb +47 -0
- data/app/components/poetry/ui/sidebar/component.html.erb +20 -0
- data/app/components/poetry/ui/sidebar/component.rb +249 -0
- data/app/components/poetry/ui/sidebar/preview.rb +21 -0
- data/app/components/poetry/ui/sidebar/shell_preview.html.erb +47 -0
- data/app/components/poetry/ui/sidebar/style.rb +139 -0
- data/app/components/poetry/ui/skeleton/component.rb +39 -0
- data/app/components/poetry/ui/skeleton/preview.rb +22 -0
- data/app/components/poetry/ui/skeleton/style.rb +13 -0
- data/app/components/poetry/ui/slider/component.html.erb +13 -0
- data/app/components/poetry/ui/slider/component.rb +360 -0
- data/app/components/poetry/ui/slider/preview.rb +73 -0
- data/app/components/poetry/ui/slider/style.rb +55 -0
- data/app/components/poetry/ui/spinner/component.rb +58 -0
- data/app/components/poetry/ui/spinner/preview.rb +22 -0
- data/app/components/poetry/ui/spinner/style.rb +12 -0
- data/app/components/poetry/ui/stat/component.html.erb +13 -0
- data/app/components/poetry/ui/stat/component.rb +102 -0
- data/app/components/poetry/ui/stat/preview.rb +47 -0
- data/app/components/poetry/ui/stat/style.rb +29 -0
- data/app/components/poetry/ui/switch/component.html.erb +15 -0
- data/app/components/poetry/ui/switch/component.rb +136 -0
- data/app/components/poetry/ui/switch/preview.rb +66 -0
- data/app/components/poetry/ui/switch/style.rb +22 -0
- data/app/components/poetry/ui/table/component.html.erb +3 -0
- data/app/components/poetry/ui/table/component.rb +93 -0
- data/app/components/poetry/ui/table/preview.rb +96 -0
- data/app/components/poetry/ui/table/style.rb +26 -0
- data/app/components/poetry/ui/tabs/component.html.erb +10 -0
- data/app/components/poetry/ui/tabs/component.rb +253 -0
- data/app/components/poetry/ui/tabs/preview.rb +43 -0
- data/app/components/poetry/ui/tabs/style.rb +49 -0
- data/app/components/poetry/ui/tag_group/component.html.erb +8 -0
- data/app/components/poetry/ui/tag_group/component.rb +203 -0
- data/app/components/poetry/ui/tag_group/preview.rb +43 -0
- data/app/components/poetry/ui/tag_group/style.rb +29 -0
- data/app/components/poetry/ui/textarea/component.rb +64 -0
- data/app/components/poetry/ui/textarea/preview.rb +75 -0
- data/app/components/poetry/ui/textarea/style.rb +18 -0
- data/app/components/poetry/ui/time_field/component.html.erb +6 -0
- data/app/components/poetry/ui/time_field/component.rb +85 -0
- data/app/components/poetry/ui/time_field/preview.rb +40 -0
- data/app/components/poetry/ui/time_field/style.rb +30 -0
- data/app/components/poetry/ui/timeline/component.rb +134 -0
- data/app/components/poetry/ui/timeline/preview.rb +61 -0
- data/app/components/poetry/ui/timeline/style.rb +54 -0
- data/app/components/poetry/ui/toast/component.html.erb +24 -0
- data/app/components/poetry/ui/toast/component.rb +178 -0
- data/app/components/poetry/ui/toast/preview.rb +69 -0
- data/app/components/poetry/ui/toast/style.rb +33 -0
- data/app/components/poetry/ui/toast_trigger/addressed_preview.html.erb +12 -0
- data/app/components/poetry/ui/toast_trigger/component.html.erb +3 -0
- data/app/components/poetry/ui/toast_trigger/component.rb +82 -0
- data/app/components/poetry/ui/toast_trigger/default_preview.html.erb +11 -0
- data/app/components/poetry/ui/toast_trigger/preview.rb +19 -0
- data/app/components/poetry/ui/toaster/component.html.erb +1 -0
- data/app/components/poetry/ui/toaster/component.rb +99 -0
- data/app/components/poetry/ui/toaster/positions_preview.html.erb +24 -0
- data/app/components/poetry/ui/toaster/preview.rb +46 -0
- data/app/components/poetry/ui/toaster/stamp_preview.html.erb +15 -0
- data/app/components/poetry/ui/toaster/style.rb +26 -0
- data/app/components/poetry/ui/toggle/component.rb +120 -0
- data/app/components/poetry/ui/toggle/preview.rb +79 -0
- data/app/components/poetry/ui/toggle/style.rb +33 -0
- data/app/components/poetry/ui/toggle_group/component.html.erb +4 -0
- data/app/components/poetry/ui/toggle_group/component.rb +252 -0
- data/app/components/poetry/ui/toggle_group/preview.rb +143 -0
- data/app/components/poetry/ui/toggle_group/style.rb +33 -0
- data/app/components/poetry/ui/toolbar/component.rb +125 -0
- data/app/components/poetry/ui/toolbar/preview.rb +41 -0
- data/app/components/poetry/ui/toolbar/style.rb +20 -0
- data/app/components/poetry/ui/tooltip/component.html.erb +20 -0
- data/app/components/poetry/ui/tooltip/component.rb +185 -0
- data/app/components/poetry/ui/tooltip/preview.rb +74 -0
- data/app/components/poetry/ui/tooltip/previews/provider_row.html.erb +25 -0
- data/app/components/poetry/ui/tooltip/style.rb +24 -0
- data/app/components/poetry/ui/tree/component.html.erb +32 -0
- data/app/components/poetry/ui/tree/component.rb +233 -0
- data/app/components/poetry/ui/tree/preview.rb +55 -0
- data/app/components/poetry/ui/tree/style.rb +29 -0
- data/app/components/poetry/ui/typeset/component.rb +73 -0
- data/app/components/poetry/ui/typeset/preview.rb +45 -0
- data/app/components/poetry/ui/typeset/style.rb +15 -0
- data/app/controllers/poetry/ui/llms_controller.rb +28 -0
- data/app/helpers/poetry/ui/components_helper.rb +1794 -0
- data/app/helpers/poetry/ui/form_builder/type_inference.rb +117 -0
- data/app/helpers/poetry/ui/form_builder.rb +916 -0
- data/app/helpers/poetry/ui/optimistic_form_builder.rb +55 -0
- data/app/helpers/poetry/ui/toast_stream_actions.rb +27 -0
- data/config/component_descriptions.yml +96 -0
- data/config/component_registry.yml +12257 -0
- data/config/locales/en.yml +93 -0
- data/config/routes.rb +8 -0
- data/config/template_classes.txt +113 -0
- data/lib/generators/poetry/add/add_generator.rb +218 -0
- data/lib/generators/poetry/agent_rules/agent_rules_generator.rb +91 -0
- data/lib/generators/poetry/agents/agents_generator.rb +24 -0
- data/lib/generators/poetry/agents_section.rb +148 -0
- data/lib/generators/poetry/block/block_generator.rb +67 -0
- data/lib/generators/poetry/block/templates/action_bar.html.erb +45 -0
- data/lib/generators/poetry/block/templates/app_shell.html.erb +139 -0
- data/lib/generators/poetry/block/templates/data_index.html.erb +85 -0
- data/lib/generators/poetry/block/templates/destructive_panel.html.erb +26 -0
- data/lib/generators/poetry/block/templates/page_header.html.erb +25 -0
- data/lib/generators/poetry/block/templates/section_card.html.erb +42 -0
- data/lib/generators/poetry/block/templates/stepper.html.erb +79 -0
- data/lib/generators/poetry/block/templates/top_nav.html.erb +44 -0
- data/lib/generators/poetry/diff/diff_generator.rb +135 -0
- data/lib/generators/poetry/editor/editor_generator.rb +344 -0
- data/lib/generators/poetry/editor/templates/poetry-check-hook +81 -0
- data/lib/generators/poetry/install/install_generator.rb +364 -0
- data/lib/generators/poetry/pagination/pagination_generator.rb +76 -0
- data/lib/generators/poetry/pagination/templates/kaminari_paginator.html.erb +29 -0
- data/lib/generators/poetry/pagination/templates/poetry_link_renderer.rb +34 -0
- data/lib/generators/poetry/pagination/templates/poetry_pagy_helper.rb +28 -0
- data/lib/generators/poetry/recipes/agent_embed/app/javascript/controllers/agent_demo_controller.js +131 -0
- data/lib/generators/poetry/recipes/screen_data_index/app/controllers/orders_controller.rb +15 -0
- data/lib/generators/poetry/recipes/screen_data_index/app/views/orders/index.html.erb +7 -0
- data/lib/generators/poetry/recipes/screen_data_index/test/system/orders_index_test.rb +16 -0
- data/lib/generators/poetry/recipes/screen_settings/app/controllers/settings_controller.rb +14 -0
- data/lib/generators/poetry/recipes/screen_settings/app/views/settings/show.html.erb +9 -0
- data/lib/generators/poetry/recipes/screen_settings/test/system/settings_show_test.rb +16 -0
- data/lib/generators/poetry/scaffold_templates/scaffold_templates_generator.rb +60 -0
- data/lib/generators/poetry/scaffold_templates/templates/_form.html.erb.tt +77 -0
- data/lib/generators/poetry/scaffold_templates/templates/controller.rb.tt +78 -0
- data/lib/generators/poetry/scaffold_templates/templates/edit.html.erb.tt +14 -0
- data/lib/generators/poetry/scaffold_templates/templates/index.html.erb.tt +24 -0
- data/lib/generators/poetry/scaffold_templates/templates/new.html.erb.tt +11 -0
- data/lib/generators/poetry/scaffold_templates/templates/partial.html.erb.tt +13 -0
- data/lib/generators/poetry/scaffold_templates/templates/show.html.erb.tt +18 -0
- data/lib/generators/poetry/skill/skill_generator.rb +34 -0
- data/lib/generators/poetry/skill/templates/poetry-component/SKILL.md +58 -0
- data/lib/generators/poetry/skill/templates/poetry-component/references/anatomy.md +152 -0
- data/lib/generators/poetry/skill/templates/poetry-component/references/checklist.md +67 -0
- data/lib/generators/poetry/skill/templates/poetry-component/references/documentation.md +137 -0
- data/lib/generators/poetry/skill/templates/poetry-design/SKILL.md +56 -0
- data/lib/generators/poetry/skill/templates/poetry-design/references/audit.md +123 -0
- data/lib/generators/poetry/skill/templates/poetry-design/references/compose.md +73 -0
- data/lib/generators/poetry/skill/templates/poetry-design/references/figma.md +68 -0
- data/lib/generators/poetry/skill/templates/poetry-design/references/paper.md +56 -0
- data/lib/generators/poetry/skill/templates/poetry-design/references/study.md +47 -0
- data/lib/generators/poetry/skill/templates/poetry-design/references/theme.md +70 -0
- data/lib/generators/poetry/skills_section.rb +58 -0
- data/lib/poetry/ui/chat.rb +283 -0
- data/lib/poetry/ui/code_block_highlighter.rb +60 -0
- data/lib/poetry/ui/engine.rb +55 -0
- data/lib/poetry/ui/recipes.rb +157 -0
- data/lib/poetry/ui/testing/combobox.rb +167 -0
- data/lib/poetry/ui/testing/dialog.rb +73 -0
- data/lib/poetry/ui/testing/menu.rb +127 -0
- data/lib/poetry/ui/testing/registration.rb +58 -0
- data/lib/poetry/ui/testing/select.rb +147 -0
- data/lib/poetry/ui/testing/tester.rb +130 -0
- data/lib/poetry/ui/testing.rb +130 -0
- data/lib/poetry/ui/themes.rb +109 -0
- data/lib/poetry/ui/version.rb +8 -0
- data/lib/poetry/ui/webmcp.rb +91 -0
- data/lib/poetry/ui.rb +285 -0
- data/lib/poetry-ui.rb +5 -0
- data/lib/tasks/poetry/check.rake +73 -0
- data/lib/tasks/poetry/design.rake +293 -0
- data/lib/tasks/poetry/verify.rake +36 -0
- data/themes/default.css +1793 -0
- data/themes/luma.css +1764 -0
- data/themes/lyra.css +1768 -0
- data/themes/maia.css +1768 -0
- data/themes/mira.css +1760 -0
- data/themes/nova.css +1755 -0
- data/themes/rhea.css +1771 -0
- data/themes/sera.css +1757 -0
- data/themes/vega.css +1775 -0
- data/typeset/typeset.css +499 -0
- metadata +502 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
# The Item family - the generic list row.
|
|
6
|
+
module Item
|
|
7
|
+
# The Item - the generic list row (Empty's sibling): media, a
|
|
8
|
+
# title/description content column, and trailing actions, with
|
|
9
|
+
# variant (default/outline/muted) and density (default/sm/xs).
|
|
10
|
+
# Rows stack inside poetry_item_group (role=list) separated by
|
|
11
|
+
# poetry_item_separator. Renders as a div by default; pass tag: :a
|
|
12
|
+
# (+ href via passthrough) for a fully-clickable row.
|
|
13
|
+
#
|
|
14
|
+
# @example
|
|
15
|
+
# render Poetry::Ui::Item::Component.new(variant: :outline) do |item|
|
|
16
|
+
# item.with_title { "Backups" }
|
|
17
|
+
# item.with_description { "Nightly, retained 30 days" }
|
|
18
|
+
# end
|
|
19
|
+
class Component < Poetry::Core::Component
|
|
20
|
+
# The closed vocabulary for the variant axis.
|
|
21
|
+
VARIANTS = %i[default outline muted].freeze
|
|
22
|
+
# The closed vocabulary for the size (density) axis.
|
|
23
|
+
SIZES = %i[default sm xs].freeze
|
|
24
|
+
# The closed vocabulary for the media_variant axis.
|
|
25
|
+
MEDIA_VARIANTS = %i[default icon image].freeze
|
|
26
|
+
|
|
27
|
+
# Projected into the registry, llms.txt, and the agent surface.
|
|
28
|
+
AGENT_RULES = [
|
|
29
|
+
"Rows live inside poetry_item_group (role=list) and each row passes role: \"listitem\" - " \
|
|
30
|
+
"a role=list parent with roleless children fails aria-required-children.",
|
|
31
|
+
"Separate grouped rows with poetry_item_separator.",
|
|
32
|
+
"Compose with the slots (media/title/description/actions); loose content lands in the " \
|
|
33
|
+
"content column after the description.",
|
|
34
|
+
"media_variant: :icon for a glyph, :image for a thumbnail (sized/rounded automatically).",
|
|
35
|
+
"A clickable row is tag: :a with href: - never wrap an Item in a bare <a>."
|
|
36
|
+
].freeze
|
|
37
|
+
|
|
38
|
+
renders_one :media, doc: "The leading media cell - a glyph or thumbnail (see media_variant)."
|
|
39
|
+
renders_one :title, doc: "The title row."
|
|
40
|
+
renders_one :description, doc: "The muted description line (clamps to two lines)."
|
|
41
|
+
renders_one :actions, doc: "The trailing actions cell - buttons, a menu, a switch."
|
|
42
|
+
renders_one :header, doc: "Full-width row above the media/content columns."
|
|
43
|
+
renders_one :footer, doc: "Full-width row below the media/content columns."
|
|
44
|
+
|
|
45
|
+
style :variant, default: :default, required: true, variants: VARIANTS,
|
|
46
|
+
doc: "The row's visual treatment - :outline boxes it, :muted recedes."
|
|
47
|
+
style :size, default: :default, required: true, variants: SIZES, doc: "The row's density."
|
|
48
|
+
|
|
49
|
+
option :tag, :symbol, default: :div,
|
|
50
|
+
doc: "The root element - tag: :a (href via passthrough) makes the whole row clickable."
|
|
51
|
+
option :media_variant, :symbol, default: :default,
|
|
52
|
+
doc: "The media treatment - :icon for a glyph, :image for a thumbnail."
|
|
53
|
+
|
|
54
|
+
validates :media_variant, inclusion: { in: MEDIA_VARIANTS }
|
|
55
|
+
|
|
56
|
+
part "item", "The row root (a div by default; tag: :a for a clickable row) - variant and " \
|
|
57
|
+
"density land here as data attributes",
|
|
58
|
+
states: {
|
|
59
|
+
"data-variant" => { condition: "the row's visual variant", values: VARIANTS.map(&:to_s) },
|
|
60
|
+
"data-size" => { condition: "the row's density", values: SIZES.map(&:to_s) }
|
|
61
|
+
}
|
|
62
|
+
part "item-media", "The leading media cell - sized and rounded by its variant",
|
|
63
|
+
states: {
|
|
64
|
+
"data-variant" => { condition: "the media treatment", values: MEDIA_VARIANTS.map(&:to_s) }
|
|
65
|
+
}
|
|
66
|
+
part "item-content", "The center column collecting title, description, and loose content"
|
|
67
|
+
part "item-title", "The title row"
|
|
68
|
+
part "item-description", "The muted description line"
|
|
69
|
+
part "item-header", "Full-width row above the media/content columns"
|
|
70
|
+
part "item-actions", "The trailing actions cell"
|
|
71
|
+
part "item-footer", "Full-width row below the media/content columns"
|
|
72
|
+
|
|
73
|
+
# Whether the center column renders (title, description, or loose content).
|
|
74
|
+
# @api private
|
|
75
|
+
def content_column?
|
|
76
|
+
title? || description? || content.present?
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# The media cell's classes for the resolved media_variant.
|
|
80
|
+
# @api private
|
|
81
|
+
def media_classes
|
|
82
|
+
"#{css(:media)} #{css(:"media_#{media_variant}")}".strip
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# The row root's attributes.
|
|
86
|
+
# @api private
|
|
87
|
+
def root_attributes
|
|
88
|
+
html_attributes.merge_if_not_set(
|
|
89
|
+
{
|
|
90
|
+
"data-slot" => "item", "data-variant" => variant, "data-size" => size
|
|
91
|
+
}.merge(component_data_attributes)
|
|
92
|
+
)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
private :content_column?, :media_classes, :root_attributes
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<%# A grouped list: rows in poetry_item_group (role=list) - each row wears
|
|
2
|
+
role=listitem (upstream omits it and fails aria-required-children). %>
|
|
3
|
+
<div class="p-4">
|
|
4
|
+
<%= poetry_item_group do %>
|
|
5
|
+
<%= poetry_item(variant: :muted, size: :sm, role: "listitem") do |item| %>
|
|
6
|
+
<% item.with_title { "Invoices synced" } %>
|
|
7
|
+
<% item.with_description { "All invoices are up to date." } %>
|
|
8
|
+
<% end %>
|
|
9
|
+
<%= poetry_item_separator %>
|
|
10
|
+
<%= poetry_item(size: :sm, role: "listitem") do |item| %>
|
|
11
|
+
<% item.with_title { "Payment pending" } %>
|
|
12
|
+
<% item.with_description { "One transfer awaits confirmation." } %>
|
|
13
|
+
<% end %>
|
|
14
|
+
<% end %>
|
|
15
|
+
</div>
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
module Item
|
|
6
|
+
# The Item preview: a basic row, an outline row with an icon and
|
|
7
|
+
# actions, and the grouped list via the sidecar template.
|
|
8
|
+
class Preview < Poetry::Core::Preview::Base
|
|
9
|
+
def default
|
|
10
|
+
render_component do |item|
|
|
11
|
+
item.with_title { "Basic Item" }
|
|
12
|
+
item.with_description { "A simple item with title and description." }
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# The full-width header/footer rows around the columns.
|
|
17
|
+
def with_header_and_footer
|
|
18
|
+
render_component do |item|
|
|
19
|
+
item.with_header { "Pinned" }
|
|
20
|
+
item.with_title { "Framed Item" }
|
|
21
|
+
item.with_description { "Header above, footer below." }
|
|
22
|
+
item.with_footer { "Updated 2 hours ago" }
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def outline_with_icon_and_actions
|
|
27
|
+
render_component(variant: :outline, media_variant: :icon) do |item|
|
|
28
|
+
item.with_media { embed(Poetry::Ui::Icon::Component.new(name: :"badge-check")) }
|
|
29
|
+
item.with_title { "Your profile has been verified." }
|
|
30
|
+
item.with_actions do
|
|
31
|
+
embed(Poetry::Ui::Button::Component.new(size: :sm, variant: :outline).with_content("View"))
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# The tightest row (sm lives in the group template below).
|
|
37
|
+
def size_xs
|
|
38
|
+
render_component(size: :xs) do |item|
|
|
39
|
+
item.with_title { "Cache cleared" }
|
|
40
|
+
item.with_description { "2 minutes ago" }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def group
|
|
45
|
+
# An explicit per-example template (a class-level preview.html.erb
|
|
46
|
+
# would shadow every other example - see Avatar's group note).
|
|
47
|
+
render_with_template(template: "poetry/ui/item/group_preview")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
module Item
|
|
6
|
+
# Re-expressed through the cn-* theme layer. The media variants
|
|
7
|
+
# use upstream's cn-item-media-variant-* names. Upstream's unused
|
|
8
|
+
# group/item-group marker stays dropped (the compiled-CSS gate).
|
|
9
|
+
class Style < Poetry::Core::Style
|
|
10
|
+
base "cn-item group/item flex w-full flex-wrap items-center transition-colors " \
|
|
11
|
+
"duration-100 outline-none focus-visible:border-ring focus-visible:ring-[3px] " \
|
|
12
|
+
"focus-visible:ring-ring/50 [a]:transition-colors"
|
|
13
|
+
|
|
14
|
+
variant :variant, {
|
|
15
|
+
default: "cn-item-variant-default",
|
|
16
|
+
outline: "cn-item-variant-outline",
|
|
17
|
+
muted: "cn-item-variant-muted"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
variant :size, {
|
|
21
|
+
default: "cn-item-size-default",
|
|
22
|
+
sm: "cn-item-size-sm",
|
|
23
|
+
xs: "cn-item-size-xs"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
element :media, "cn-item-media flex shrink-0 items-center justify-center " \
|
|
27
|
+
"[&_svg]:pointer-events-none"
|
|
28
|
+
element :media_default, "cn-item-media-variant-default"
|
|
29
|
+
element :media_icon, "cn-item-media-variant-icon"
|
|
30
|
+
element :media_image, "cn-item-media-variant-image"
|
|
31
|
+
element :content, "cn-item-content flex flex-1 flex-col [&+[data-slot=item-content]]:flex-none"
|
|
32
|
+
element :title, "cn-item-title line-clamp-1 flex w-fit items-center"
|
|
33
|
+
element :description, "cn-item-description line-clamp-2 font-normal [&>a]:underline " \
|
|
34
|
+
"[&>a]:underline-offset-4 [&>a:hover]:text-primary"
|
|
35
|
+
element :actions, "cn-item-actions flex items-center"
|
|
36
|
+
element :header, "cn-item-header flex basis-full items-center justify-between"
|
|
37
|
+
element :footer, "cn-item-footer flex basis-full items-center justify-between"
|
|
38
|
+
|
|
39
|
+
# The list wrapper + row separator (poetry_item_group / _separator).
|
|
40
|
+
element :group, "cn-item-group flex w-full flex-col"
|
|
41
|
+
element :separator, "cn-item-separator"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
# The Kbd family - the keyboard-key chip.
|
|
6
|
+
module Kbd
|
|
7
|
+
# The Kbd - a real <kbd> element for a keyboard key or shortcut. The
|
|
8
|
+
# content is the key text (⌘, Ctrl, K); compose several for a chord.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# render Poetry::Ui::Kbd::Component.new { "Esc" }
|
|
12
|
+
class Component < Poetry::Core::Component
|
|
13
|
+
requires_content "the key text"
|
|
14
|
+
|
|
15
|
+
# Projected into the registry, llms.txt, and the agent surface.
|
|
16
|
+
AGENT_RULES = [
|
|
17
|
+
"Kbd renders a real <kbd> - the key text is the content block (⌘, Esc, Ctrl).",
|
|
18
|
+
"For a chord (⌘+K) render one Kbd per key inside an inline-flex row."
|
|
19
|
+
].freeze
|
|
20
|
+
|
|
21
|
+
part "kbd", "The <kbd> element itself - the key text renders here"
|
|
22
|
+
|
|
23
|
+
# Enforces the required key text before render.
|
|
24
|
+
# @api private
|
|
25
|
+
def before_render
|
|
26
|
+
ensure_content!
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Renders the <kbd> element.
|
|
30
|
+
# @api private
|
|
31
|
+
def call
|
|
32
|
+
content_tag(:kbd, content, **root_attributes.to_attributes)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# The <kbd> element's attributes.
|
|
36
|
+
# @api private
|
|
37
|
+
def root_attributes
|
|
38
|
+
html_attributes.merge_if_not_set(
|
|
39
|
+
{ "data-slot" => "kbd" }.merge(component_data_attributes)
|
|
40
|
+
)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private :root_attributes
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
module Kbd
|
|
6
|
+
# The Kbd preview: single keys.
|
|
7
|
+
class Preview < Poetry::Core::Preview::Base
|
|
8
|
+
def default
|
|
9
|
+
render_component { "Esc" }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def command
|
|
13
|
+
render_component { "⌘" }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# A chord run in the themed group wrapper.
|
|
17
|
+
def group
|
|
18
|
+
render_with_template(template: "poetry/ui/kbd/group_preview")
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
module Kbd
|
|
6
|
+
# Re-expressed through the cn-* theme layer: the keyboard-key
|
|
7
|
+
# chip's look (incl. the tooltip inversion) rides themes/default.css.
|
|
8
|
+
class Style < Poetry::Core::Style
|
|
9
|
+
base "cn-kbd pointer-events-none inline-flex items-center justify-center select-none"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
# A caption for a form control.
|
|
6
|
+
module Label
|
|
7
|
+
# A <label> for a form control, wired to it via for_id:. The
|
|
8
|
+
# caption is the content block.
|
|
9
|
+
#
|
|
10
|
+
# Omit for_id: when the label names a GROUP of controls rather
|
|
11
|
+
# than one element: a for= pointing at a non-control is inert, so
|
|
12
|
+
# in group mode the group names itself via aria-labelledby at this
|
|
13
|
+
# label's id instead.
|
|
14
|
+
#
|
|
15
|
+
# @example A label wired to its control
|
|
16
|
+
# render Poetry::Ui::Label::Component.new(for_id: "email").with_content("Email")
|
|
17
|
+
class Component < Poetry::Core::Component
|
|
18
|
+
# Projected into the registry, llms.txt, and the agent surface.
|
|
19
|
+
AGENT_RULES = [
|
|
20
|
+
"Every control gets a Label wired via for_id - placeholder text is never the label."
|
|
21
|
+
].freeze
|
|
22
|
+
|
|
23
|
+
option :for_id, :string,
|
|
24
|
+
doc: "The id of the control this label names; omit it for a group label (the group then points at " \
|
|
25
|
+
"this label via aria-labelledby)."
|
|
26
|
+
|
|
27
|
+
part "label", "The <label> element itself - for= rides it (dropped in group mode, " \
|
|
28
|
+
"where the group names itself via aria-labelledby at this label's id)"
|
|
29
|
+
|
|
30
|
+
# @api private
|
|
31
|
+
def call
|
|
32
|
+
content_tag(:label, content, **root_attributes.to_attributes)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# @api private
|
|
36
|
+
def root_attributes
|
|
37
|
+
attrs = { "data-slot" => "label" }
|
|
38
|
+
attrs["for"] = for_id if for_id.present?
|
|
39
|
+
html_attributes.merge_if_not_set(attrs.merge(component_data_attributes))
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private :root_attributes
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
module Label
|
|
6
|
+
# The Label preview - always tied to a control via for_id (the
|
|
7
|
+
# component's whole contract), so the sidecar preview.html.erb renders
|
|
8
|
+
# the label/input pair.
|
|
9
|
+
class Preview < Poetry::Core::Preview::Base
|
|
10
|
+
def default
|
|
11
|
+
render_with(component: Component.new(for_id: "label-full-name"))
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
module Label
|
|
6
|
+
# Re-expressed through the cn-* theme layer.
|
|
7
|
+
class Style < Poetry::Core::Style
|
|
8
|
+
base "cn-label flex items-center select-none peer-disabled:cursor-not-allowed " \
|
|
9
|
+
"group-data-[disabled=true]:pointer-events-none"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
# A navigation link.
|
|
6
|
+
module Link
|
|
7
|
+
# A themed navigation link - a real <a>. Links navigate; buttons
|
|
8
|
+
# act - reach for Button when the click performs an action.
|
|
9
|
+
# current: true marks the active nav item via aria-current, and
|
|
10
|
+
# external: true opens a new tab with the safe rel pairing.
|
|
11
|
+
#
|
|
12
|
+
# @example
|
|
13
|
+
# render Poetry::Ui::Link::Component.new(href: "/docs") { "Documentation" }
|
|
14
|
+
class Component < Poetry::Core::Component
|
|
15
|
+
# Projected into the registry, llms.txt, and the agent surface.
|
|
16
|
+
AGENT_RULES = [
|
|
17
|
+
"Use poetry_link for navigation - poetry_button for actions (never an <a> styled by hand).",
|
|
18
|
+
"Mark the active nav item with current: true (aria-current), never with a bespoke class.",
|
|
19
|
+
"external: true handles target/rel safely - never hand-write target=_blank."
|
|
20
|
+
].freeze
|
|
21
|
+
|
|
22
|
+
style :underline, default: :hover, variants: %i[hover always none],
|
|
23
|
+
doc: "When the underline appears; :none suits links styled by their container."
|
|
24
|
+
|
|
25
|
+
option :href, :string, required: true, doc: "The destination URL."
|
|
26
|
+
option :external, :boolean, default: false,
|
|
27
|
+
doc: "Opens in a new tab with rel=\"noopener noreferrer\" - never hand-write " \
|
|
28
|
+
"target=_blank."
|
|
29
|
+
option :current, :boolean, default: false, doc: "Marks this link as the current page via aria-current=page."
|
|
30
|
+
|
|
31
|
+
part "link", "The rendered <a> - the whole component; current: marks it aria-current=page"
|
|
32
|
+
|
|
33
|
+
# An empty link would be a focusable, invisible <a> - the visible
|
|
34
|
+
# text is required.
|
|
35
|
+
requires_content "the visible link text"
|
|
36
|
+
|
|
37
|
+
# @api private
|
|
38
|
+
def before_render
|
|
39
|
+
ensure_content!
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# @api private
|
|
43
|
+
def call
|
|
44
|
+
content_tag(:a, content, **root_attributes.to_attributes)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# @api private
|
|
48
|
+
def root_attributes
|
|
49
|
+
attrs = { "href" => href, "data-slot" => "link" }.merge(component_data_attributes)
|
|
50
|
+
attrs["aria-current"] = "page" if current
|
|
51
|
+
if external
|
|
52
|
+
attrs["target"] = "_blank"
|
|
53
|
+
attrs["rel"] = "noopener noreferrer"
|
|
54
|
+
end
|
|
55
|
+
html_attributes.merge_if_not_set(attrs)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private :root_attributes
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
module Link
|
|
6
|
+
# The Link preview: the default hover underline, the aria-current
|
|
7
|
+
# nav item, an external link, and both underline extremes.
|
|
8
|
+
class Preview < Poetry::Core::Preview::Base
|
|
9
|
+
def default
|
|
10
|
+
render_component(href: "#") { "Documentation" }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def current_nav_item
|
|
14
|
+
render_component(href: "#", current: true) { "Dashboard" }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def external
|
|
18
|
+
render_component(href: "https://example.com", external: true) { "API reference" }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def always_underlined
|
|
22
|
+
render_component(href: "#", underline: :always) { "Terms of service" }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def never_underlined
|
|
26
|
+
render_component(href: "#", underline: :none) { "Settings" }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
module Link
|
|
6
|
+
# Re-expressed through the cn-* theme layer. No upstream
|
|
7
|
+
# counterpart - the split follows the category rule:
|
|
8
|
+
# layout/behavior inline, color/decoration/focus ring themed.
|
|
9
|
+
class Style < Poetry::Core::Style
|
|
10
|
+
base "cn-link inline-flex items-center outline-none transition-colors"
|
|
11
|
+
|
|
12
|
+
variant :underline, {
|
|
13
|
+
hover: "cn-link-underline-hover",
|
|
14
|
+
always: "cn-link-underline-always",
|
|
15
|
+
none: "cn-link-underline-none"
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
<%= content_tag(tag, **root_attributes.to_attributes) do %>
|
|
2
|
+
<% if icon? %><span data-slot="marker-icon" aria-hidden="true" class="<%= css(:icon) %>"><%= icon %></span><% end %>
|
|
3
|
+
<span data-slot="marker-content" class="<%= css(:content) %>"><%= content %></span>
|
|
4
|
+
<% end %>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
# A transcript divider or inline status line for chat UIs.
|
|
6
|
+
module Marker
|
|
7
|
+
# A transcript divider or inline status line for chat UIs: date
|
|
8
|
+
# breaks, "3 new messages", an in-flight status. The label is real
|
|
9
|
+
# announced content - the decorative divider lines render around
|
|
10
|
+
# it, and the marker never takes a separator role. announce:
|
|
11
|
+
# :status turns it into a live status region for the single
|
|
12
|
+
# in-flight marker a transcript shows while streaming.
|
|
13
|
+
#
|
|
14
|
+
# @example
|
|
15
|
+
# render Poetry::Ui::Marker::Component.new(variant: :separator) { "Yesterday" }
|
|
16
|
+
class Component < Poetry::Core::Component
|
|
17
|
+
# The closed vocabulary for the variant axis.
|
|
18
|
+
VARIANTS = %i[default separator border].freeze
|
|
19
|
+
# The closed vocabulary for the announce axis.
|
|
20
|
+
ANNOUNCE = %i[none status].freeze
|
|
21
|
+
|
|
22
|
+
# Projected into the registry, llms.txt, and the agent surface.
|
|
23
|
+
AGENT_RULES = [
|
|
24
|
+
"The marker text is real announced content - never mark it aria-hidden or role=separator.",
|
|
25
|
+
"announce: :status is for the ONE in-flight marker (streaming status); static dividers never announce.",
|
|
26
|
+
"Icons ride the icon slot (decorative always): with_icon(name:) for a lucide glyph, " \
|
|
27
|
+
"with_icon { } for other media (a Spinner mid-run).",
|
|
28
|
+
"Use variant: :separator for date/section breaks; :border under pinned headers."
|
|
29
|
+
].freeze
|
|
30
|
+
|
|
31
|
+
renders_one :icon,
|
|
32
|
+
doc: "Optional leading visual: name: renders an icon glyph; a block carries other media (a " \
|
|
33
|
+
"Spinner mid-run). Either way it sits in an aria-hidden cell and stays decorative - the " \
|
|
34
|
+
"marker root does the announcing.",
|
|
35
|
+
renders: lambda { |name: nil, **options, &block|
|
|
36
|
+
next Poetry::Ui::Icon::Component.new(name: name, **options) if name
|
|
37
|
+
|
|
38
|
+
content_tag(:span, &block)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
style :variant, default: :default, required: true, variants: VARIANTS,
|
|
42
|
+
doc: "The divider treatment - :separator for date/section breaks, :border for a full-width " \
|
|
43
|
+
"rule under pinned headers."
|
|
44
|
+
|
|
45
|
+
option :tag, :symbol, default: :div, doc: "The root element's tag."
|
|
46
|
+
option :announce, :symbol, default: :none,
|
|
47
|
+
doc: "Makes the marker a live status region (role=status) for the one in-flight " \
|
|
48
|
+
"marker; static dividers never announce."
|
|
49
|
+
|
|
50
|
+
validates :announce, inclusion: { in: ANNOUNCE }
|
|
51
|
+
|
|
52
|
+
part "marker", "The divider/status root - the label is real announced content " \
|
|
53
|
+
"(role=status when announce: :status; never role=separator)",
|
|
54
|
+
states: {
|
|
55
|
+
"data-variant" => { condition: "always - the resolved variant",
|
|
56
|
+
values: VARIANTS.map(&:to_s) }
|
|
57
|
+
}
|
|
58
|
+
# "The label IS the information" - an empty marker renders a bare
|
|
59
|
+
# divider span pretending to inform.
|
|
60
|
+
requires_content "the marker label"
|
|
61
|
+
|
|
62
|
+
part "marker-icon", "Decorative icon wrapper (aria-hidden always)"
|
|
63
|
+
part "marker-content", "The label span - the marker text itself"
|
|
64
|
+
|
|
65
|
+
# @api private
|
|
66
|
+
def before_render
|
|
67
|
+
ensure_content!
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# @api private
|
|
71
|
+
def root_attributes
|
|
72
|
+
attrs = { "data-slot" => "marker", "data-variant" => variant }.merge(component_data_attributes)
|
|
73
|
+
attrs["role"] = "status" if announce == :status
|
|
74
|
+
html_attributes.merge_if_not_set(attrs)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
private :root_attributes
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
module Marker
|
|
6
|
+
# The Marker preview matrix.
|
|
7
|
+
class Preview < Poetry::Core::Preview::Base
|
|
8
|
+
def default
|
|
9
|
+
render_component { "Assistant is thinking" }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def separator
|
|
13
|
+
render_component(variant: :separator) { "Yesterday" }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def border
|
|
17
|
+
render_component(variant: :border) { "Earlier in this thread" }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def with_icon
|
|
21
|
+
render_component do |marker|
|
|
22
|
+
marker.with_icon(name: :sparkles)
|
|
23
|
+
"Generating a summary"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def announcing_status
|
|
28
|
+
render_component(announce: :status) { "Searching the web…" }
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# The block icon path: other media in the decorative cell - the
|
|
32
|
+
# Spinner's own status role is hidden by the aria-hidden wrapper,
|
|
33
|
+
# the marker root announces.
|
|
34
|
+
def status_with_spinner
|
|
35
|
+
render_component(announce: :status) do |marker|
|
|
36
|
+
marker.with_icon { render(Spinner::Component.new) }
|
|
37
|
+
"Compacting conversation"
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Poetry
|
|
4
|
+
module Ui
|
|
5
|
+
module Marker
|
|
6
|
+
# Re-expressed through the cn-* theme layer. The separator
|
|
7
|
+
# lines stay ::before/::after pseudo-elements (AT never sees them) -
|
|
8
|
+
# now in the variant theme rule.
|
|
9
|
+
class Style < Poetry::Core::Style
|
|
10
|
+
base "cn-marker group/marker relative flex w-full items-center"
|
|
11
|
+
|
|
12
|
+
variant :variant, {
|
|
13
|
+
default: "",
|
|
14
|
+
separator: "cn-marker-variant-separator",
|
|
15
|
+
border: "cn-marker-variant-border"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
element :icon, "cn-marker-icon shrink-0"
|
|
19
|
+
|
|
20
|
+
element :content, "cn-marker-content min-w-0 wrap-break-word"
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|