shadcn_view_component 0.3.3
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/CHANGELOG.md +255 -0
- data/MIT-LICENSE +20 -0
- data/README.md +604 -0
- data/app/assets/stylesheets/shadcn-themes.css +1075 -0
- data/app/assets/stylesheets/shadcn.css +853 -0
- data/app/components/shadcn/accordion/component.rb +44 -0
- data/app/components/shadcn/accordion/content/component.rb +44 -0
- data/app/components/shadcn/accordion/item/component.rb +41 -0
- data/app/components/shadcn/accordion/preview.rb +16 -0
- data/app/components/shadcn/accordion/previews/default.html.erb +10 -0
- data/app/components/shadcn/accordion/previews/multiple.html.erb +13 -0
- data/app/components/shadcn/accordion/trigger/component.rb +52 -0
- data/app/components/shadcn/alert/component.rb +52 -0
- data/app/components/shadcn/alert/preview.rb +11 -0
- data/app/components/shadcn/alert/previews/default.html.erb +8 -0
- data/app/components/shadcn/alert.rb +17 -0
- data/app/components/shadcn/alert_dialog/action/component.rb +35 -0
- data/app/components/shadcn/alert_dialog/cancel/component.rb +16 -0
- data/app/components/shadcn/alert_dialog/component.rb +20 -0
- data/app/components/shadcn/alert_dialog/content/component.rb +55 -0
- data/app/components/shadcn/alert_dialog/header/component.rb +33 -0
- data/app/components/shadcn/alert_dialog/preview.rb +16 -0
- data/app/components/shadcn/alert_dialog/previews/default.html.erb +13 -0
- data/app/components/shadcn/alert_dialog/previews/small_with_media.html.erb +38 -0
- data/app/components/shadcn/alert_dialog.rb +32 -0
- data/app/components/shadcn/application_view_component.rb +225 -0
- data/app/components/shadcn/application_view_component_preview.rb +8 -0
- data/app/components/shadcn/aspect_ratio/component.rb +34 -0
- data/app/components/shadcn/aspect_ratio/preview.rb +16 -0
- data/app/components/shadcn/aspect_ratio/previews/default.html.erb +5 -0
- data/app/components/shadcn/aspect_ratio/previews/ratios.html.erb +12 -0
- data/app/components/shadcn/attachment/action/component.rb +19 -0
- data/app/components/shadcn/attachment/component.rb +76 -0
- data/app/components/shadcn/attachment/media/component.rb +56 -0
- data/app/components/shadcn/attachment/preview.rb +11 -0
- data/app/components/shadcn/attachment/previews/default.html.erb +80 -0
- data/app/components/shadcn/attachment/trigger/component.rb +31 -0
- data/app/components/shadcn/attachment.rb +42 -0
- data/app/components/shadcn/avatar/component.rb +43 -0
- data/app/components/shadcn/avatar/fallback/component.rb +23 -0
- data/app/components/shadcn/avatar/image/component.rb +20 -0
- data/app/components/shadcn/avatar/preview.rb +11 -0
- data/app/components/shadcn/avatar/previews/default.html.erb +13 -0
- data/app/components/shadcn/avatar.rb +32 -0
- data/app/components/shadcn/badge/component.rb +57 -0
- data/app/components/shadcn/badge/preview.rb +11 -0
- data/app/components/shadcn/badge/previews/default.html.erb +5 -0
- data/app/components/shadcn/breadcrumb/component.rb +15 -0
- data/app/components/shadcn/breadcrumb/ellipsis/component.rb +28 -0
- data/app/components/shadcn/breadcrumb/page/component.rb +25 -0
- data/app/components/shadcn/breadcrumb/preview.rb +16 -0
- data/app/components/shadcn/breadcrumb/previews/custom_separator.html.erb +17 -0
- data/app/components/shadcn/breadcrumb/previews/default.html.erb +15 -0
- data/app/components/shadcn/breadcrumb/separator/component.rb +31 -0
- data/app/components/shadcn/breadcrumb.rb +18 -0
- data/app/components/shadcn/bubble/component.rb +90 -0
- data/app/components/shadcn/bubble/preview.rb +16 -0
- data/app/components/shadcn/bubble/previews/alignment.html.erb +33 -0
- data/app/components/shadcn/bubble/previews/default.html.erb +22 -0
- data/app/components/shadcn/bubble/reactions/component.rb +54 -0
- data/app/components/shadcn/bubble.rb +24 -0
- data/app/components/shadcn/button/component.rb +85 -0
- data/app/components/shadcn/button/preview.rb +31 -0
- data/app/components/shadcn/button/previews/default.html.erb +8 -0
- data/app/components/shadcn/button/previews/sizes.html.erb +5 -0
- data/app/components/shadcn/button/previews/variants.html.erb +5 -0
- data/app/components/shadcn/button_group/component.rb +53 -0
- data/app/components/shadcn/button_group/preview.rb +15 -0
- data/app/components/shadcn/button_group/previews/default.html.erb +18 -0
- data/app/components/shadcn/button_group/previews/vertical.html.erb +5 -0
- data/app/components/shadcn/button_group/separator/component.rb +30 -0
- data/app/components/shadcn/button_group/text/component.rb +20 -0
- data/app/components/shadcn/calendar/component.rb +558 -0
- data/app/components/shadcn/calendar/month.rb +74 -0
- data/app/components/shadcn/calendar/preview.rb +64 -0
- data/app/components/shadcn/calendar/previews/booked.html.erb +18 -0
- data/app/components/shadcn/calendar/previews/custom_cell_size.html.erb +11 -0
- data/app/components/shadcn/calendar/previews/date_and_time.html.erb +31 -0
- data/app/components/shadcn/calendar/previews/default.html.erb +8 -0
- data/app/components/shadcn/calendar/previews/dropdown_caption.html.erb +11 -0
- data/app/components/shadcn/calendar/previews/in_a_form.html.erb +8 -0
- data/app/components/shadcn/calendar/previews/presets.html.erb +20 -0
- data/app/components/shadcn/calendar/previews/range.html.erb +10 -0
- data/app/components/shadcn/calendar/previews/week_numbers.html.erb +8 -0
- data/app/components/shadcn/card/component.rb +24 -0
- data/app/components/shadcn/card/header/component.rb +26 -0
- data/app/components/shadcn/card/preview.rb +16 -0
- data/app/components/shadcn/card/previews/default.html.erb +18 -0
- data/app/components/shadcn/card/previews/image.html.erb +37 -0
- data/app/components/shadcn/card.rb +21 -0
- data/app/components/shadcn/carousel/component.rb +61 -0
- data/app/components/shadcn/carousel/content/component.rb +86 -0
- data/app/components/shadcn/carousel/item/component.rb +42 -0
- data/app/components/shadcn/carousel/next/component.rb +59 -0
- data/app/components/shadcn/carousel/preview.rb +22 -0
- data/app/components/shadcn/carousel/previews/default.html.erb +22 -0
- data/app/components/shadcn/carousel/previews/sizes.html.erb +42 -0
- data/app/components/shadcn/carousel/previews/vertical.html.erb +27 -0
- data/app/components/shadcn/carousel/previous/component.rb +59 -0
- data/app/components/shadcn/chart/area/component.rb +43 -0
- data/app/components/shadcn/chart/bar/component.rb +75 -0
- data/app/components/shadcn/chart/cartesian/component.rb +152 -0
- data/app/components/shadcn/chart/component.rb +124 -0
- data/app/components/shadcn/chart/focusable.rb +38 -0
- data/app/components/shadcn/chart/legend/component.rb +55 -0
- data/app/components/shadcn/chart/line/component.rb +50 -0
- data/app/components/shadcn/chart/pie/component.rb +169 -0
- data/app/components/shadcn/chart/plot.rb +147 -0
- data/app/components/shadcn/chart/preview.rb +45 -0
- data/app/components/shadcn/chart/previews/area.html.erb +31 -0
- data/app/components/shadcn/chart/previews/bar.html.erb +32 -0
- data/app/components/shadcn/chart/previews/bar_stacked.html.erb +30 -0
- data/app/components/shadcn/chart/previews/default.html.erb +30 -0
- data/app/components/shadcn/chart/previews/donut.html.erb +16 -0
- data/app/components/shadcn/chart/previews/line.html.erb +30 -0
- data/app/components/shadcn/chart/previews/percentages.html.erb +17 -0
- data/app/components/shadcn/chart/table/component.rb +75 -0
- data/app/components/shadcn/chart/tooltip/component.rb +111 -0
- data/app/components/shadcn/checkbox/component.rb +109 -0
- data/app/components/shadcn/checkbox/preview.rb +16 -0
- data/app/components/shadcn/checkbox/previews/default.html.erb +14 -0
- data/app/components/shadcn/checkbox/previews/states.html.erb +23 -0
- data/app/components/shadcn/collapsible/component.rb +35 -0
- data/app/components/shadcn/collapsible/content/component.rb +20 -0
- data/app/components/shadcn/collapsible/preview.rb +11 -0
- data/app/components/shadcn/collapsible/previews/default.html.erb +9 -0
- data/app/components/shadcn/collapsible/trigger/component.rb +23 -0
- data/app/components/shadcn/combobox/chip/component.rb +60 -0
- data/app/components/shadcn/combobox/chip_input/component.rb +43 -0
- data/app/components/shadcn/combobox/chips/component.rb +54 -0
- data/app/components/shadcn/combobox/clear/component.rb +32 -0
- data/app/components/shadcn/combobox/component.rb +113 -0
- data/app/components/shadcn/combobox/content/component.rb +59 -0
- data/app/components/shadcn/combobox/empty/component.rb +23 -0
- data/app/components/shadcn/combobox/input/component.rb +85 -0
- data/app/components/shadcn/combobox/item/component.rb +69 -0
- data/app/components/shadcn/combobox/list/component.rb +27 -0
- data/app/components/shadcn/combobox/preview.rb +31 -0
- data/app/components/shadcn/combobox/previews/default.html.erb +20 -0
- data/app/components/shadcn/combobox/previews/grouped.html.erb +25 -0
- data/app/components/shadcn/combobox/previews/multiple.html.erb +28 -0
- data/app/components/shadcn/combobox/previews/with_clear.html.erb +16 -0
- data/app/components/shadcn/combobox/trigger/component.rb +54 -0
- data/app/components/shadcn/combobox.rb +16 -0
- data/app/components/shadcn/command/component.rb +67 -0
- data/app/components/shadcn/command/dialog/component.rb +72 -0
- data/app/components/shadcn/command/empty/component.rb +29 -0
- data/app/components/shadcn/command/group/component.rb +63 -0
- data/app/components/shadcn/command/input/component.rb +66 -0
- data/app/components/shadcn/command/item/component.rb +62 -0
- data/app/components/shadcn/command/list/component.rb +36 -0
- data/app/components/shadcn/command/preview.rb +26 -0
- data/app/components/shadcn/command/previews/default.html.erb +41 -0
- data/app/components/shadcn/command/previews/dialog.html.erb +33 -0
- data/app/components/shadcn/command/previews/ranking.html.erb +16 -0
- data/app/components/shadcn/command/separator/component.rb +33 -0
- data/app/components/shadcn/command.rb +14 -0
- data/app/components/shadcn/concerns/modal_root.rb +43 -0
- data/app/components/shadcn/concerns/submits_value.rb +81 -0
- data/app/components/shadcn/context_menu/component.rb +45 -0
- data/app/components/shadcn/context_menu/content/component.rb +40 -0
- data/app/components/shadcn/context_menu/preview.rb +16 -0
- data/app/components/shadcn/context_menu/previews/default.html.erb +34 -0
- data/app/components/shadcn/context_menu/previews/items.html.erb +35 -0
- data/app/components/shadcn/context_menu/sub/component.rb +47 -0
- data/app/components/shadcn/context_menu/sub_content/component.rb +31 -0
- data/app/components/shadcn/context_menu/trigger/component.rb +50 -0
- data/app/components/shadcn/context_menu.rb +43 -0
- data/app/components/shadcn/dialog/close/component.rb +20 -0
- data/app/components/shadcn/dialog/component.rb +20 -0
- data/app/components/shadcn/dialog/content/component.rb +78 -0
- data/app/components/shadcn/dialog/header/component.rb +23 -0
- data/app/components/shadcn/dialog/overlay/component.rb +28 -0
- data/app/components/shadcn/dialog/preview.rb +28 -0
- data/app/components/shadcn/dialog/previews/default.html.erb +17 -0
- data/app/components/shadcn/dialog/previews/inside_stacking_context.html.erb +25 -0
- data/app/components/shadcn/dialog/previews/no_close_button.html.erb +15 -0
- data/app/components/shadcn/dialog/previews/scrollable_content.html.erb +29 -0
- data/app/components/shadcn/dialog/trigger/component.rb +24 -0
- data/app/components/shadcn/dialog.rb +17 -0
- data/app/components/shadcn/drawer/component.rb +33 -0
- data/app/components/shadcn/drawer/content/component.rb +95 -0
- data/app/components/shadcn/drawer/header/component.rb +34 -0
- data/app/components/shadcn/drawer/preview.rb +29 -0
- data/app/components/shadcn/drawer/previews/default.html.erb +21 -0
- data/app/components/shadcn/drawer/previews/scrollable.html.erb +20 -0
- data/app/components/shadcn/drawer/previews/scrollable_side.html.erb +21 -0
- data/app/components/shadcn/drawer/previews/sides.html.erb +17 -0
- data/app/components/shadcn/drawer.rb +27 -0
- data/app/components/shadcn/dropdown_menu/checkbox_item/component.rb +61 -0
- data/app/components/shadcn/dropdown_menu/component.rb +48 -0
- data/app/components/shadcn/dropdown_menu/content/component.rb +49 -0
- data/app/components/shadcn/dropdown_menu/group/component.rb +16 -0
- data/app/components/shadcn/dropdown_menu/item/component.rb +50 -0
- data/app/components/shadcn/dropdown_menu/preview.rb +16 -0
- data/app/components/shadcn/dropdown_menu/previews/checkboxes_and_radio.html.erb +34 -0
- data/app/components/shadcn/dropdown_menu/previews/default.html.erb +23 -0
- data/app/components/shadcn/dropdown_menu/radio_group/component.rb +16 -0
- data/app/components/shadcn/dropdown_menu/radio_item/component.rb +63 -0
- data/app/components/shadcn/dropdown_menu/sub/component.rb +44 -0
- data/app/components/shadcn/dropdown_menu/sub_content/component.rb +45 -0
- data/app/components/shadcn/dropdown_menu/sub_trigger/component.rb +58 -0
- data/app/components/shadcn/dropdown_menu/trigger/component.rb +25 -0
- data/app/components/shadcn/dropdown_menu.rb +18 -0
- data/app/components/shadcn/empty/component.rb +17 -0
- data/app/components/shadcn/empty/media/component.rb +48 -0
- data/app/components/shadcn/empty/preview.rb +16 -0
- data/app/components/shadcn/empty/previews/default.html.erb +15 -0
- data/app/components/shadcn/empty/previews/media.html.erb +32 -0
- data/app/components/shadcn/empty.rb +26 -0
- data/app/components/shadcn/field/component.rb +61 -0
- data/app/components/shadcn/field/error/component.rb +49 -0
- data/app/components/shadcn/field/legend/component.rb +30 -0
- data/app/components/shadcn/field/preview.rb +17 -0
- data/app/components/shadcn/field/previews/default.html.erb +29 -0
- data/app/components/shadcn/field/previews/form_builder.html.erb +38 -0
- data/app/components/shadcn/field/separator/component.rb +35 -0
- data/app/components/shadcn/field.rb +44 -0
- data/app/components/shadcn/hover_card/component.rb +51 -0
- data/app/components/shadcn/hover_card/content/component.rb +45 -0
- data/app/components/shadcn/hover_card/preview.rb +16 -0
- data/app/components/shadcn/hover_card/previews/default.html.erb +36 -0
- data/app/components/shadcn/hover_card/previews/sides.html.erb +15 -0
- data/app/components/shadcn/hover_card/trigger/component.rb +33 -0
- data/app/components/shadcn/icon/component.rb +76 -0
- data/app/components/shadcn/icon.rb +43 -0
- data/app/components/shadcn/input/component.rb +26 -0
- data/app/components/shadcn/input/preview.rb +16 -0
- data/app/components/shadcn/input/previews/default.html.erb +5 -0
- data/app/components/shadcn/input/previews/states.html.erb +20 -0
- data/app/components/shadcn/input_group/addon/component.rb +65 -0
- data/app/components/shadcn/input_group/button/component.rb +40 -0
- data/app/components/shadcn/input_group/component.rb +43 -0
- data/app/components/shadcn/input_group/input/component.rb +25 -0
- data/app/components/shadcn/input_group/preview.rb +17 -0
- data/app/components/shadcn/input_group/previews/addons.html.erb +53 -0
- data/app/components/shadcn/input_group/previews/default.html.erb +25 -0
- data/app/components/shadcn/input_group/text/component.rb +20 -0
- data/app/components/shadcn/input_group/textarea/component.rb +21 -0
- data/app/components/shadcn/input_otp/component.rb +95 -0
- data/app/components/shadcn/input_otp/preview.rb +17 -0
- data/app/components/shadcn/input_otp/previews/default.html.erb +19 -0
- data/app/components/shadcn/input_otp/previews/variations.html.erb +33 -0
- data/app/components/shadcn/input_otp/separator/component.rb +21 -0
- data/app/components/shadcn/input_otp/slot/component.rb +60 -0
- data/app/components/shadcn/input_otp.rb +11 -0
- data/app/components/shadcn/item/component.rb +56 -0
- data/app/components/shadcn/item/group/component.rb +53 -0
- data/app/components/shadcn/item/media/component.rb +53 -0
- data/app/components/shadcn/item/preview.rb +20 -0
- data/app/components/shadcn/item/previews/default.html.erb +32 -0
- data/app/components/shadcn/item/previews/link.html.erb +39 -0
- data/app/components/shadcn/item/previews/outline.html.erb +8 -0
- data/app/components/shadcn/item/separator/component.rb +24 -0
- data/app/components/shadcn/item.rb +34 -0
- data/app/components/shadcn/kbd/component.rb +23 -0
- data/app/components/shadcn/kbd/group/component.rb +17 -0
- data/app/components/shadcn/kbd/preview.rb +11 -0
- data/app/components/shadcn/kbd/previews/default.html.erb +4 -0
- data/app/components/shadcn/label/component.rb +20 -0
- data/app/components/shadcn/label/preview.rb +11 -0
- data/app/components/shadcn/label/previews/default.html.erb +4 -0
- data/app/components/shadcn/marker/component.rb +46 -0
- data/app/components/shadcn/marker/icon/component.rb +23 -0
- data/app/components/shadcn/marker/preview.rb +17 -0
- data/app/components/shadcn/marker/previews/default.html.erb +18 -0
- data/app/components/shadcn/marker/previews/status.html.erb +32 -0
- data/app/components/shadcn/marker.rb +17 -0
- data/app/components/shadcn/menubar/component.rb +36 -0
- data/app/components/shadcn/menubar/content/component.rb +49 -0
- data/app/components/shadcn/menubar/menu/component.rb +39 -0
- data/app/components/shadcn/menubar/preview.rb +16 -0
- data/app/components/shadcn/menubar/previews/default.html.erb +52 -0
- data/app/components/shadcn/menubar/previews/items.html.erb +38 -0
- data/app/components/shadcn/menubar/sub/component.rb +43 -0
- data/app/components/shadcn/menubar/sub_content/component.rb +31 -0
- data/app/components/shadcn/menubar/sub_trigger/component.rb +31 -0
- data/app/components/shadcn/menubar/trigger/component.rb +41 -0
- data/app/components/shadcn/menubar.rb +47 -0
- data/app/components/shadcn/message/component.rb +33 -0
- data/app/components/shadcn/message/preview.rb +16 -0
- data/app/components/shadcn/message/previews/actions.html.erb +51 -0
- data/app/components/shadcn/message/previews/default.html.erb +35 -0
- data/app/components/shadcn/message.rb +35 -0
- data/app/components/shadcn/message_scroller/button/component.rb +78 -0
- data/app/components/shadcn/message_scroller/component.rb +59 -0
- data/app/components/shadcn/message_scroller/content/component.rb +50 -0
- data/app/components/shadcn/message_scroller/item/component.rb +45 -0
- data/app/components/shadcn/message_scroller/preview.rb +11 -0
- data/app/components/shadcn/message_scroller/previews/default.html.erb +72 -0
- data/app/components/shadcn/message_scroller/viewport/component.rb +41 -0
- data/app/components/shadcn/mode_switcher/component.rb +67 -0
- data/app/components/shadcn/mode_switcher/preview.rb +11 -0
- data/app/components/shadcn/mode_switcher/previews/default.html.erb +5 -0
- data/app/components/shadcn/mode_toggle/component.rb +75 -0
- data/app/components/shadcn/mode_toggle/preview.rb +11 -0
- data/app/components/shadcn/mode_toggle/previews/default.html.erb +20 -0
- data/app/components/shadcn/native_select/component.rb +59 -0
- data/app/components/shadcn/native_select/preview.rb +16 -0
- data/app/components/shadcn/native_select/previews/default.html.erb +9 -0
- data/app/components/shadcn/native_select/previews/groups.html.erb +26 -0
- data/app/components/shadcn/native_select.rb +16 -0
- data/app/components/shadcn/navigation_menu/component.rb +51 -0
- data/app/components/shadcn/navigation_menu/content/component.rb +58 -0
- data/app/components/shadcn/navigation_menu/preview.rb +11 -0
- data/app/components/shadcn/navigation_menu/previews/default.html.erb +49 -0
- data/app/components/shadcn/navigation_menu/trigger/component.rb +59 -0
- data/app/components/shadcn/navigation_menu.rb +28 -0
- data/app/components/shadcn/pagination/component.rb +19 -0
- data/app/components/shadcn/pagination/ellipsis/component.rb +28 -0
- data/app/components/shadcn/pagination/link/component.rb +37 -0
- data/app/components/shadcn/pagination/next/component.rb +31 -0
- data/app/components/shadcn/pagination/preview.rb +16 -0
- data/app/components/shadcn/pagination/previews/default.html.erb +18 -0
- data/app/components/shadcn/pagination/previews/simple.html.erb +39 -0
- data/app/components/shadcn/pagination/previous/component.rb +31 -0
- data/app/components/shadcn/pagination.rb +14 -0
- data/app/components/shadcn/parts.rb +38 -0
- data/app/components/shadcn/popover/anchor/component.rb +17 -0
- data/app/components/shadcn/popover/component.rb +42 -0
- data/app/components/shadcn/popover/content/component.rb +40 -0
- data/app/components/shadcn/popover/preview.rb +28 -0
- data/app/components/shadcn/popover/previews/align.html.erb +13 -0
- data/app/components/shadcn/popover/previews/default.html.erb +9 -0
- data/app/components/shadcn/popover/previews/inside_containing_block.html.erb +41 -0
- data/app/components/shadcn/popover/previews/inside_stacking_context.html.erb +30 -0
- data/app/components/shadcn/popover/trigger/component.rb +24 -0
- data/app/components/shadcn/popover.rb +16 -0
- data/app/components/shadcn/progress/component.rb +62 -0
- data/app/components/shadcn/progress/preview.rb +11 -0
- data/app/components/shadcn/progress/previews/default.html.erb +5 -0
- data/app/components/shadcn/radio_group/component.rb +51 -0
- data/app/components/shadcn/radio_group/item/component.rb +74 -0
- data/app/components/shadcn/radio_group/preview.rb +16 -0
- data/app/components/shadcn/radio_group/previews/default.html.erb +15 -0
- data/app/components/shadcn/radio_group/previews/states.html.erb +41 -0
- data/app/components/shadcn/resizable/component.rb +59 -0
- data/app/components/shadcn/resizable/handle/component.rb +70 -0
- data/app/components/shadcn/resizable/panel/component.rb +53 -0
- data/app/components/shadcn/resizable/preview.rb +23 -0
- data/app/components/shadcn/resizable/previews/default.html.erb +25 -0
- data/app/components/shadcn/resizable/previews/vertical.html.erb +19 -0
- data/app/components/shadcn/resizable/previews/with_handle.html.erb +17 -0
- data/app/components/shadcn/scroll_area/component.rb +84 -0
- data/app/components/shadcn/scroll_area/preview.rb +11 -0
- data/app/components/shadcn/scroll_area/previews/default.html.erb +36 -0
- data/app/components/shadcn/scroll_area/scrollbar/component.rb +72 -0
- data/app/components/shadcn/scroll_area/viewport/component.rb +70 -0
- data/app/components/shadcn/scroll_area.rb +14 -0
- data/app/components/shadcn/select/component.rb +67 -0
- data/app/components/shadcn/select/content/component.rb +157 -0
- data/app/components/shadcn/select/empty/component.rb +38 -0
- data/app/components/shadcn/select/group/component.rb +16 -0
- data/app/components/shadcn/select/item/component.rb +71 -0
- data/app/components/shadcn/select/list/component.rb +41 -0
- data/app/components/shadcn/select/preview.rb +24 -0
- data/app/components/shadcn/select/previews/default.html.erb +17 -0
- data/app/components/shadcn/select/previews/scrollable.html.erb +19 -0
- data/app/components/shadcn/select/previews/searchable.html.erb +18 -0
- data/app/components/shadcn/select/previews/states.html.erb +25 -0
- data/app/components/shadcn/select/search/component.rb +54 -0
- data/app/components/shadcn/select/trigger/component.rb +78 -0
- data/app/components/shadcn/select/value/component.rb +28 -0
- data/app/components/shadcn/select.rb +15 -0
- data/app/components/shadcn/separator/component.rb +41 -0
- data/app/components/shadcn/separator/preview.rb +11 -0
- data/app/components/shadcn/separator/previews/default.html.erb +9 -0
- data/app/components/shadcn/sheet/component.rb +16 -0
- data/app/components/shadcn/sheet/content/component.rb +98 -0
- data/app/components/shadcn/sheet/header/component.rb +23 -0
- data/app/components/shadcn/sheet/preview.rb +16 -0
- data/app/components/shadcn/sheet/previews/default.html.erb +16 -0
- data/app/components/shadcn/sheet/previews/no_close_button.html.erb +14 -0
- data/app/components/shadcn/sheet.rb +22 -0
- data/app/components/shadcn/sidebar/component.rb +232 -0
- data/app/components/shadcn/sidebar/input/component.rb +25 -0
- data/app/components/shadcn/sidebar/menu_action/component.rb +58 -0
- data/app/components/shadcn/sidebar/menu_button/component.rb +100 -0
- data/app/components/shadcn/sidebar/menu_skeleton/component.rb +51 -0
- data/app/components/shadcn/sidebar/menu_sub_button/component.rb +60 -0
- data/app/components/shadcn/sidebar/preview.rb +22 -0
- data/app/components/shadcn/sidebar/previews/default.html.erb +189 -0
- data/app/components/shadcn/sidebar/previews/floating.html.erb +39 -0
- data/app/components/shadcn/sidebar/previews/inset.html.erb +48 -0
- data/app/components/shadcn/sidebar/provider/component.rb +53 -0
- data/app/components/shadcn/sidebar/rail/component.rb +43 -0
- data/app/components/shadcn/sidebar/separator/component.rb +23 -0
- data/app/components/shadcn/sidebar/trigger/component.rb +39 -0
- data/app/components/shadcn/sidebar.rb +98 -0
- data/app/components/shadcn/skeleton/component.rb +14 -0
- data/app/components/shadcn/skeleton/preview.rb +11 -0
- data/app/components/shadcn/skeleton/previews/default.html.erb +7 -0
- data/app/components/shadcn/slider/component.rb +145 -0
- data/app/components/shadcn/slider/preview.rb +16 -0
- data/app/components/shadcn/slider/previews/default.html.erb +17 -0
- data/app/components/shadcn/slider/previews/vertical.html.erb +7 -0
- data/app/components/shadcn/slider/range/component.rb +51 -0
- data/app/components/shadcn/slider/thumb/component.rb +58 -0
- data/app/components/shadcn/slider/track/component.rb +32 -0
- data/app/components/shadcn/spinner/component.rb +21 -0
- data/app/components/shadcn/spinner/preview.rb +11 -0
- data/app/components/shadcn/spinner/previews/default.html.erb +7 -0
- data/app/components/shadcn/switch/component.rb +104 -0
- data/app/components/shadcn/switch/preview.rb +11 -0
- data/app/components/shadcn/switch/previews/default.html.erb +24 -0
- data/app/components/shadcn/table/component.rb +26 -0
- data/app/components/shadcn/table/preview.rb +16 -0
- data/app/components/shadcn/table/previews/default.html.erb +19 -0
- data/app/components/shadcn/table/previews/footer.html.erb +25 -0
- data/app/components/shadcn/table.rb +33 -0
- data/app/components/shadcn/tabs/component.rb +40 -0
- data/app/components/shadcn/tabs/content/component.rb +34 -0
- data/app/components/shadcn/tabs/list/component.rb +51 -0
- data/app/components/shadcn/tabs/preview.rb +16 -0
- data/app/components/shadcn/tabs/previews/default.html.erb +21 -0
- data/app/components/shadcn/tabs/previews/line.html.erb +23 -0
- data/app/components/shadcn/tabs/trigger/component.rb +66 -0
- data/app/components/shadcn/textarea/component.rb +24 -0
- data/app/components/shadcn/textarea/preview.rb +16 -0
- data/app/components/shadcn/textarea/previews/default.html.erb +3 -0
- data/app/components/shadcn/textarea/previews/states.html.erb +18 -0
- data/app/components/shadcn/theme_selector/component.rb +88 -0
- data/app/components/shadcn/theme_selector/preview.rb +17 -0
- data/app/components/shadcn/theme_selector/previews/all_themes.html.erb +20 -0
- data/app/components/shadcn/theme_selector/previews/default.html.erb +18 -0
- data/app/components/shadcn/toaster/component.rb +139 -0
- data/app/components/shadcn/toaster/preview.rb +16 -0
- data/app/components/shadcn/toaster/previews/default.html.erb +19 -0
- data/app/components/shadcn/toaster/previews/from_the_server.html.erb +15 -0
- data/app/components/shadcn/toaster/toast/component.rb +134 -0
- data/app/components/shadcn/toggle/component.rb +81 -0
- data/app/components/shadcn/toggle/preview.rb +11 -0
- data/app/components/shadcn/toggle/previews/default.html.erb +6 -0
- data/app/components/shadcn/toggle_group/component.rb +62 -0
- data/app/components/shadcn/toggle_group/item/component.rb +59 -0
- data/app/components/shadcn/toggle_group/preview.rb +16 -0
- data/app/components/shadcn/toggle_group/previews/default.html.erb +12 -0
- data/app/components/shadcn/toggle_group/previews/sizes.html.erb +37 -0
- data/app/components/shadcn/tooltip/component.rb +38 -0
- data/app/components/shadcn/tooltip/content/component.rb +62 -0
- data/app/components/shadcn/tooltip/preview.rb +21 -0
- data/app/components/shadcn/tooltip/previews/default.html.erb +4 -0
- data/app/components/shadcn/tooltip/previews/sides.html.erb +19 -0
- data/app/components/shadcn/tooltip/previews/with_keyboard_shortcut.html.erb +11 -0
- data/app/components/shadcn/tooltip/provider/component.rb +28 -0
- data/app/components/shadcn/tooltip/trigger/component.rb +25 -0
- data/app/helpers/shadcn_view_component/form_helper.rb +25 -0
- data/app/helpers/shadcn_view_component/theme_helper.rb +61 -0
- data/app/javascript/shadcn/animation.js +180 -0
- data/app/javascript/shadcn/command_score.js +110 -0
- data/app/javascript/shadcn/controllers/accordion_controller.js +127 -0
- data/app/javascript/shadcn/controllers/avatar_controller.js +32 -0
- data/app/javascript/shadcn/controllers/calendar_controller.js +633 -0
- data/app/javascript/shadcn/controllers/carousel_controller.js +139 -0
- data/app/javascript/shadcn/controllers/chart_controller.js +110 -0
- data/app/javascript/shadcn/controllers/checkbox_controller.js +61 -0
- data/app/javascript/shadcn/controllers/collapsible_controller.js +55 -0
- data/app/javascript/shadcn/controllers/combobox_controller.js +360 -0
- data/app/javascript/shadcn/controllers/command_controller.js +199 -0
- data/app/javascript/shadcn/controllers/dialog_controller.js +154 -0
- data/app/javascript/shadcn/controllers/drawer_controller.js +265 -0
- data/app/javascript/shadcn/controllers/dropdown_menu_controller.js +259 -0
- data/app/javascript/shadcn/controllers/hover_card_controller.js +85 -0
- data/app/javascript/shadcn/controllers/input_group_controller.js +17 -0
- data/app/javascript/shadcn/controllers/input_otp_controller.js +80 -0
- data/app/javascript/shadcn/controllers/menubar_controller.js +151 -0
- data/app/javascript/shadcn/controllers/message_scroller_controller.js +456 -0
- data/app/javascript/shadcn/controllers/navigation_menu_controller.js +211 -0
- data/app/javascript/shadcn/controllers/popover_controller.js +66 -0
- data/app/javascript/shadcn/controllers/radio_group_controller.js +69 -0
- data/app/javascript/shadcn/controllers/resizable_controller.js +167 -0
- data/app/javascript/shadcn/controllers/scroll_area_controller.js +253 -0
- data/app/javascript/shadcn/controllers/select_controller.js +320 -0
- data/app/javascript/shadcn/controllers/sidebar_controller.js +273 -0
- data/app/javascript/shadcn/controllers/slider_controller.js +230 -0
- data/app/javascript/shadcn/controllers/switch_controller.js +39 -0
- data/app/javascript/shadcn/controllers/tabs_controller.js +81 -0
- data/app/javascript/shadcn/controllers/theme_controller.js +67 -0
- data/app/javascript/shadcn/controllers/toaster_controller.js +281 -0
- data/app/javascript/shadcn/controllers/toggle_controller.js +24 -0
- data/app/javascript/shadcn/controllers/toggle_group_controller.js +73 -0
- data/app/javascript/shadcn/controllers/tooltip_controller.js +58 -0
- data/app/javascript/shadcn/direction.js +41 -0
- data/app/javascript/shadcn/dismiss.js +73 -0
- data/app/javascript/shadcn/floating.js +207 -0
- data/app/javascript/shadcn/focus.js +86 -0
- data/app/javascript/shadcn/id.js +14 -0
- data/app/javascript/shadcn/index.js +110 -0
- data/app/javascript/shadcn/popper.js +262 -0
- data/app/javascript/shadcn/scroll_geometry.js +267 -0
- data/app/javascript/shadcn/theme.js +161 -0
- data/app/javascript/shadcn/top_layer.js +59 -0
- data/app/javascript/shadcn/typeahead.js +99 -0
- data/config/importmap.rb +6 -0
- data/config/locales/en.yml +62 -0
- data/lib/generators/shadcn_view_component/install/install_generator.rb +149 -0
- data/lib/shadcn_view_component/engine.rb +73 -0
- data/lib/shadcn_view_component/form_builder.rb +264 -0
- data/lib/shadcn_view_component/icon_registry.rb +66 -0
- data/lib/shadcn_view_component/icons.rb +32 -0
- data/lib/shadcn_view_component/themes.rb +1065 -0
- data/lib/shadcn_view_component/version.rb +3 -0
- data/lib/shadcn_view_component.rb +82 -0
- data/lib/tasks/icons.rake +53 -0
- data/lib/tasks/themes.rake +171 -0
- metadata +608 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module ContextMenu
|
|
5
|
+
module Content
|
|
6
|
+
# The panel. Its own class string rather than the dropdown's, for one
|
|
7
|
+
# reason worth stating: the two differ only in which `--radix-*` custom
|
|
8
|
+
# properties they read, and those are the properties `popper.js` writes
|
|
9
|
+
# under the controller's `prefix`. Sharing the string would leave the
|
|
10
|
+
# menu reading variables nothing sets.
|
|
11
|
+
class Component < ApplicationViewComponent
|
|
12
|
+
slot_name :"context-menu-content"
|
|
13
|
+
|
|
14
|
+
style do
|
|
15
|
+
base {
|
|
16
|
+
"z-50 max-h-(--radix-context-menu-content-available-height) min-w-[8rem] " \
|
|
17
|
+
"origin-(--radix-context-menu-content-transform-origin) overflow-x-hidden " \
|
|
18
|
+
"overflow-y-auto rounded-md border bg-popover p-1 text-popover-foreground " \
|
|
19
|
+
"shadow-md data-[side=bottom]:slide-in-from-top-2 " \
|
|
20
|
+
"data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 " \
|
|
21
|
+
"data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out " \
|
|
22
|
+
"data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 " \
|
|
23
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 " \
|
|
24
|
+
"data-[state=open]:zoom-in-95"
|
|
25
|
+
}
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def element_attributes(**defaults)
|
|
29
|
+
super(**{
|
|
30
|
+
role: "menu",
|
|
31
|
+
hidden: true,
|
|
32
|
+
"data-state" => "closed",
|
|
33
|
+
"data-shadcn--dropdown-menu-target" => "content",
|
|
34
|
+
"data-action" => "keydown->shadcn--dropdown-menu#contentKeydown"
|
|
35
|
+
}.merge(defaults))
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module ContextMenu
|
|
5
|
+
class Preview < ApplicationViewComponentPreview
|
|
6
|
+
def default
|
|
7
|
+
render_with_template
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Upstream's "Radio", "Destructive", "Icons" and "Groups".
|
|
11
|
+
def items
|
|
12
|
+
render_with_template
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<%# Right-click the dashed area. The trigger has no classes of its own upstream
|
|
2
|
+
— it is a region rather than a control — so the border here is the caller's,
|
|
3
|
+
which is the only way to see where the region is.
|
|
4
|
+
|
|
5
|
+
Everything below the trigger is the dropdown menu's, restamped: same items,
|
|
6
|
+
same submenu, same checkbox and radio behaviour, same controller. %>
|
|
7
|
+
<div class="flex h-72 items-start justify-center pt-6">
|
|
8
|
+
<%= render(Shadcn::ContextMenu::Component.new) do |menu| %>
|
|
9
|
+
<% menu.with_trigger(class: "flex h-40 w-72 items-center justify-center rounded-md border border-dashed text-sm") do %>
|
|
10
|
+
Right-click here
|
|
11
|
+
<% end %>
|
|
12
|
+
<% menu.with_menu_content(class: "w-52") do %>
|
|
13
|
+
<%= render(Shadcn::ContextMenu::Item::Component.new) do %>
|
|
14
|
+
Back
|
|
15
|
+
<%= render(Shadcn::ContextMenu::Shortcut::Component.new) { "⌘[" } %>
|
|
16
|
+
<% end %>
|
|
17
|
+
<%= render(Shadcn::ContextMenu::Item::Component.new(disabled: true)) do %>
|
|
18
|
+
Forward
|
|
19
|
+
<%= render(Shadcn::ContextMenu::Shortcut::Component.new) { "⌘]" } %>
|
|
20
|
+
<% end %>
|
|
21
|
+
<%= render(Shadcn::ContextMenu::Separator::Component.new) %>
|
|
22
|
+
<%= render(Shadcn::ContextMenu::Sub::Component.new) do |sub| %>
|
|
23
|
+
<% sub.with_trigger { "More tools" } %>
|
|
24
|
+
<% sub.with_menu_content do %>
|
|
25
|
+
<%= render(Shadcn::ContextMenu::Item::Component.new) { "Save page" } %>
|
|
26
|
+
<%= render(Shadcn::ContextMenu::Item::Component.new) { "Create shortcut" } %>
|
|
27
|
+
<% end %>
|
|
28
|
+
<% end %>
|
|
29
|
+
<%= render(Shadcn::ContextMenu::Separator::Component.new) %>
|
|
30
|
+
<%= render(Shadcn::ContextMenu::CheckboxItem::Component.new(checked: true)) { "Show bookmarks" } %>
|
|
31
|
+
<%= render(Shadcn::ContextMenu::CheckboxItem::Component.new) { "Show full URLs" } %>
|
|
32
|
+
<% end %>
|
|
33
|
+
<% end %>
|
|
34
|
+
</div>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<%# Upstream's "Radio", "Destructive", "Icons" and "Groups": the four kinds of
|
|
2
|
+
item the default preview leaves out, which has the plain items, a submenu,
|
|
3
|
+
the shortcuts and the checkboxes.
|
|
4
|
+
|
|
5
|
+
All four are the dropdown's — this family declares no controller of its own
|
|
6
|
+
— so what is worth seeing here is that a right-click reaches them at all. %>
|
|
7
|
+
<%= render(Shadcn::ContextMenu::Component.new) do |menu| %>
|
|
8
|
+
<% menu.with_trigger(class: "flex h-40 items-center justify-center rounded-md border border-dashed text-sm text-muted-foreground") do %>
|
|
9
|
+
Right-click here
|
|
10
|
+
<% end %>
|
|
11
|
+
<% menu.with_menu_content(class: "w-52") do %>
|
|
12
|
+
<%= render(Shadcn::ContextMenu::Group::Component.new) do %>
|
|
13
|
+
<%= render(Shadcn::ContextMenu::Label::Component.new) { "Sort by" } %>
|
|
14
|
+
<%= render(Shadcn::ContextMenu::RadioGroup::Component.new) do %>
|
|
15
|
+
<% %w[Name Size Modified].each do |option| %>
|
|
16
|
+
<%= render(Shadcn::ContextMenu::RadioItem::Component.new(value: option.downcase, checked: option == "Name")) { option } %>
|
|
17
|
+
<% end %>
|
|
18
|
+
<% end %>
|
|
19
|
+
<% end %>
|
|
20
|
+
<%= render(Shadcn::ContextMenu::Separator::Component.new) %>
|
|
21
|
+
<%= render(Shadcn::ContextMenu::Item::Component.new) do %>
|
|
22
|
+
<%= render(Shadcn::Icon::Component.new("search")) %>
|
|
23
|
+
Find in folder
|
|
24
|
+
<% end %>
|
|
25
|
+
<%= render(Shadcn::ContextMenu::Item::Component.new) do %>
|
|
26
|
+
<%= render(Shadcn::Icon::Component.new("check")) %>
|
|
27
|
+
Select all
|
|
28
|
+
<% end %>
|
|
29
|
+
<%= render(Shadcn::ContextMenu::Separator::Component.new) %>
|
|
30
|
+
<%= render(Shadcn::ContextMenu::Item::Component.new(variant: :destructive)) do %>
|
|
31
|
+
<%= render(Shadcn::Icon::Component.new("x")) %>
|
|
32
|
+
Move to bin
|
|
33
|
+
<% end %>
|
|
34
|
+
<% end %>
|
|
35
|
+
<% end %>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module ContextMenu
|
|
5
|
+
module Sub
|
|
6
|
+
# A nested menu. Written out rather than subclassed: ViewComponent refuses
|
|
7
|
+
# to redeclare an inherited slot, and this one has to hold *this* family's
|
|
8
|
+
# sub-content — which differs from the dropdown's in the only way that
|
|
9
|
+
# matters here, the `--radix-*` properties it reads.
|
|
10
|
+
#
|
|
11
|
+
# Another `shadcn--dropdown-menu` controller, carrying the prefix so
|
|
12
|
+
# `popper.js` writes the properties that content looks for.
|
|
13
|
+
class Component < ApplicationViewComponent
|
|
14
|
+
renders_one :trigger, "Shadcn::ContextMenu::SubTrigger::Component"
|
|
15
|
+
renders_one :menu_content, "Shadcn::ContextMenu::SubContent::Component"
|
|
16
|
+
|
|
17
|
+
slot_name :"context-menu-sub"
|
|
18
|
+
|
|
19
|
+
attr_reader :open, :side, :align, :side_offset
|
|
20
|
+
|
|
21
|
+
def initialize(open: false, side: :right, align: :start, side_offset: 0, **attributes)
|
|
22
|
+
@open = open
|
|
23
|
+
@side = side&.to_sym || :right
|
|
24
|
+
@align = align&.to_sym || :start
|
|
25
|
+
@side_offset = side_offset
|
|
26
|
+
super(**attributes)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def element_attributes(**defaults)
|
|
30
|
+
super(**{
|
|
31
|
+
style: merged_style(CONTENTS_STYLE),
|
|
32
|
+
"data-controller" => "shadcn--dropdown-menu",
|
|
33
|
+
"data-shadcn--dropdown-menu-prefix-value" => "context-menu",
|
|
34
|
+
"data-shadcn--dropdown-menu-open-value" => open,
|
|
35
|
+
"data-shadcn--dropdown-menu-side-value" => side,
|
|
36
|
+
"data-shadcn--dropdown-menu-align-value" => align,
|
|
37
|
+
"data-shadcn--dropdown-menu-side-offset-value" => side_offset
|
|
38
|
+
}.merge(defaults))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def call
|
|
42
|
+
render_element(body: safe_join([ trigger, menu_content, content ].compact))
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module ContextMenu
|
|
5
|
+
module SubContent
|
|
6
|
+
# Its own class string rather than the dropdown's, and the reason is the
|
|
7
|
+
# one thing `parity_spec` cannot see: the two differ only in which
|
|
8
|
+
# `--radix-*` custom properties they read, and those are what `popper.js`
|
|
9
|
+
# writes under the controller's prefix. Inheriting the dropdown's would
|
|
10
|
+
# leave a context submenu reading variables nothing sets — and parity
|
|
11
|
+
# would still pass, because it asks whether a token appears anywhere in
|
|
12
|
+
# the family, not whether it appears on the right element.
|
|
13
|
+
class Component < Shadcn::DropdownMenu::SubContent::Component
|
|
14
|
+
slot_name :"context-menu-sub-content"
|
|
15
|
+
|
|
16
|
+
style do
|
|
17
|
+
base {
|
|
18
|
+
"z-50 min-w-[8rem] origin-(--radix-context-menu-content-transform-origin) " \
|
|
19
|
+
"overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground " \
|
|
20
|
+
"shadow-lg data-[side=bottom]:slide-in-from-top-2 " \
|
|
21
|
+
"data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 " \
|
|
22
|
+
"data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out " \
|
|
23
|
+
"data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 " \
|
|
24
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 " \
|
|
25
|
+
"data-[state=open]:zoom-in-95"
|
|
26
|
+
}
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module ContextMenu
|
|
5
|
+
module Trigger
|
|
6
|
+
# The area you right-click. Upstream gives it no classes at all
|
|
7
|
+
# (context-menu.tsx:19) — it is a region, not a control, and what it looks
|
|
8
|
+
# like is the caller's business.
|
|
9
|
+
#
|
|
10
|
+
# A `<span>`, which is Radix's (`Primitive.span`, context-menu.tsx:151) and
|
|
11
|
+
# not a detail: a `<div>` would be block where this is inline, so the same
|
|
12
|
+
# markup would lay out differently. Measured on the live demo before it
|
|
13
|
+
# was believed.
|
|
14
|
+
#
|
|
15
|
+
# `-webkit-touch-callout: none` is Radix's too, and is the only reason a
|
|
16
|
+
# long press on iOS does not raise the system menu over this one.
|
|
17
|
+
#
|
|
18
|
+
# No `aria-haspopup` and no `role`: there is no keyboard route to a
|
|
19
|
+
# context menu, and claiming one would promise something that does not
|
|
20
|
+
# exist. Radix does not add either.
|
|
21
|
+
class Component < ApplicationViewComponent
|
|
22
|
+
default_tag :span
|
|
23
|
+
slot_name :"context-menu-trigger"
|
|
24
|
+
|
|
25
|
+
attr_reader :disabled
|
|
26
|
+
|
|
27
|
+
def initialize(disabled: false, **attributes)
|
|
28
|
+
@disabled = disabled
|
|
29
|
+
super(**attributes)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def element_attributes(**defaults)
|
|
33
|
+
attributes = {
|
|
34
|
+
style: merged_style("-webkit-touch-callout: none;"),
|
|
35
|
+
"data-state" => "closed",
|
|
36
|
+
"data-disabled" => (disabled.presence && ""),
|
|
37
|
+
"data-shadcn--dropdown-menu-target" => "trigger"
|
|
38
|
+
}.compact
|
|
39
|
+
|
|
40
|
+
# A disabled trigger hands the gesture back to the browser rather than
|
|
41
|
+
# swallowing it, which is Radix's own choice (`:158-161`): a region
|
|
42
|
+
# that does nothing should not also take away the menu you expected.
|
|
43
|
+
attributes["data-action"] = "contextmenu->shadcn--dropdown-menu#openAtPointer" unless disabled
|
|
44
|
+
|
|
45
|
+
super(**attributes.merge(defaults))
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
# The ContextMenu family.
|
|
5
|
+
#
|
|
6
|
+
# Measured against `dropdown-menu.tsx`: the two files declare the same fifteen
|
|
7
|
+
# slots, and eleven of them carry byte-identical class strings once the
|
|
8
|
+
# prefix is normalised. So most of this family *is* the dropdown's, restamped
|
|
9
|
+
# — the same relationship `Sheet` has with `Dialog` here, and the reason both
|
|
10
|
+
# are driven by one controller rather than two.
|
|
11
|
+
#
|
|
12
|
+
# The four that differ: `label` gains `text-foreground`; `content` reads
|
|
13
|
+
# `--radix-context-menu-*` rather than `--radix-dropdown-menu-*`; `sub-trigger`
|
|
14
|
+
# spells the chevron's size through its own `[&_svg…]:size-4` instead of on
|
|
15
|
+
# the icon; and `trigger` is the area you right-click rather than a button.
|
|
16
|
+
module ContextMenu
|
|
17
|
+
extend Parts
|
|
18
|
+
|
|
19
|
+
part :label, slot: "context-menu-label",
|
|
20
|
+
classes: "px-2 py-1.5 text-sm font-medium text-foreground data-[inset]:pl-8"
|
|
21
|
+
|
|
22
|
+
part :separator, slot: "context-menu-separator", classes: "-mx-1 my-1 h-px bg-border"
|
|
23
|
+
|
|
24
|
+
part :shortcut, tag: :span, slot: "context-menu-shortcut",
|
|
25
|
+
classes: "ml-auto text-xs tracking-widest text-muted-foreground"
|
|
26
|
+
|
|
27
|
+
part :group, slot: "context-menu-group", from: DropdownMenu::Group::Component
|
|
28
|
+
|
|
29
|
+
part :radio_group, slot: "context-menu-radio-group",
|
|
30
|
+
from: DropdownMenu::RadioGroup::Component
|
|
31
|
+
|
|
32
|
+
part :item, slot: "context-menu-item", from: DropdownMenu::Item::Component
|
|
33
|
+
|
|
34
|
+
part :checkbox_item, slot: "context-menu-checkbox-item",
|
|
35
|
+
from: DropdownMenu::CheckboxItem::Component
|
|
36
|
+
|
|
37
|
+
part :radio_item, slot: "context-menu-radio-item",
|
|
38
|
+
from: DropdownMenu::RadioItem::Component
|
|
39
|
+
|
|
40
|
+
part :sub_trigger, slot: "context-menu-sub-trigger",
|
|
41
|
+
from: DropdownMenu::SubTrigger::Component
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Dialog
|
|
5
|
+
module Close
|
|
6
|
+
# DialogClose
|
|
7
|
+
class Component < ApplicationViewComponent
|
|
8
|
+
default_tag :button
|
|
9
|
+
slot_name :"dialog-close"
|
|
10
|
+
|
|
11
|
+
def element_attributes(**defaults)
|
|
12
|
+
super(**{
|
|
13
|
+
type: "button",
|
|
14
|
+
"data-action" => "shadcn--dialog#close"
|
|
15
|
+
}.merge(defaults))
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Dialog
|
|
5
|
+
# Port of registry/new-york-v4/ui/dialog.tsx
|
|
6
|
+
#
|
|
7
|
+
# Radix's Dialog.Root is a context provider and renders no DOM. Stimulus
|
|
8
|
+
# needs an element to attach to, so the root is a `display: contents`
|
|
9
|
+
# wrapper — invisible to layout, and it gives shadcn's `data-slot="dialog"`
|
|
10
|
+
# somewhere to live.
|
|
11
|
+
class Component < ApplicationViewComponent
|
|
12
|
+
include Concerns::ModalRoot
|
|
13
|
+
|
|
14
|
+
renders_one :trigger, "Shadcn::Dialog::Trigger::Component"
|
|
15
|
+
renders_one :dialog_content, "Shadcn::Dialog::Content::Component"
|
|
16
|
+
|
|
17
|
+
slot_name :dialog
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Dialog
|
|
5
|
+
module Content
|
|
6
|
+
# DialogContent — renders its own overlay, as the TSX does, and the
|
|
7
|
+
# dismiss button in the corner unless asked not to.
|
|
8
|
+
class Component < ApplicationViewComponent
|
|
9
|
+
CLOSE_CLASSES = "absolute top-4 right-4 rounded-xs opacity-70 ring-offset-background " \
|
|
10
|
+
"transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring " \
|
|
11
|
+
"focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none " \
|
|
12
|
+
"data-[state=open]:bg-accent data-[state=open]:text-muted-foreground " \
|
|
13
|
+
"[&_svg]:pointer-events-none [&_svg]:shrink-0 " \
|
|
14
|
+
"[&_svg:not([class*='size-'])]:size-4"
|
|
15
|
+
|
|
16
|
+
renders_one :header, "Shadcn::Dialog::Header::Component"
|
|
17
|
+
renders_one :footer, "Shadcn::Dialog::Footer::Component"
|
|
18
|
+
|
|
19
|
+
slot_name :"dialog-content"
|
|
20
|
+
|
|
21
|
+
style do
|
|
22
|
+
base {
|
|
23
|
+
"fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] " \
|
|
24
|
+
"translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border bg-background p-6 " \
|
|
25
|
+
"shadow-lg duration-200 outline-none data-[state=closed]:animate-out " \
|
|
26
|
+
"data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 " \
|
|
27
|
+
"data-[state=open]:animate-in data-[state=open]:fade-in-0 " \
|
|
28
|
+
"data-[state=open]:zoom-in-95 sm:max-w-lg"
|
|
29
|
+
}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
attr_reader :show_close_button
|
|
33
|
+
|
|
34
|
+
def initialize(show_close_button: true, **attributes)
|
|
35
|
+
@show_close_button = show_close_button
|
|
36
|
+
super(**attributes)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def element_attributes(**defaults)
|
|
40
|
+
super(**{
|
|
41
|
+
role: "dialog",
|
|
42
|
+
"aria-modal" => "true",
|
|
43
|
+
tabindex: "-1",
|
|
44
|
+
"data-state" => "closed",
|
|
45
|
+
hidden: true,
|
|
46
|
+
"data-shadcn--dialog-target" => "content"
|
|
47
|
+
}.merge(defaults))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# shadcn wraps the overlay and the content in a DialogPortal. Radix
|
|
51
|
+
# relocates that element to `document.body`; here it stays put (see
|
|
52
|
+
# the `shadcn--dialog` controller for why) and is `display: contents`,
|
|
53
|
+
# so it adds no box of its own.
|
|
54
|
+
def call
|
|
55
|
+
tag.div("data-slot": "dialog-portal", style: CONTENTS_STYLE) do
|
|
56
|
+
safe_join([
|
|
57
|
+
render(Overlay::Component.new),
|
|
58
|
+
render_element(body: safe_join([ header, content, footer, close_button ].compact))
|
|
59
|
+
])
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def close_button
|
|
66
|
+
return unless show_close_button
|
|
67
|
+
|
|
68
|
+
render(Close::Component.new(class: CLOSE_CLASSES)) do
|
|
69
|
+
safe_join([
|
|
70
|
+
render(Icon::Component.new("x")),
|
|
71
|
+
tag.span(shadcn_t("dialog.close"), class: "sr-only")
|
|
72
|
+
])
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Dialog
|
|
5
|
+
module Header
|
|
6
|
+
# DialogHeader
|
|
7
|
+
class Component < ApplicationViewComponent
|
|
8
|
+
renders_one :title, "Shadcn::Dialog::Title::Component"
|
|
9
|
+
renders_one :description, "Shadcn::Dialog::Description::Component"
|
|
10
|
+
|
|
11
|
+
slot_name :"dialog-header"
|
|
12
|
+
|
|
13
|
+
style do
|
|
14
|
+
base { "flex flex-col gap-2 text-center sm:text-left" }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def call
|
|
18
|
+
render_element(body: safe_join([ title, description, content ].compact))
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Dialog
|
|
5
|
+
module Overlay
|
|
6
|
+
# DialogOverlay
|
|
7
|
+
class Component < ApplicationViewComponent
|
|
8
|
+
slot_name :"dialog-overlay"
|
|
9
|
+
|
|
10
|
+
style do
|
|
11
|
+
base {
|
|
12
|
+
"fixed inset-0 z-50 bg-black/50 data-[state=closed]:animate-out " \
|
|
13
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:animate-in " \
|
|
14
|
+
"data-[state=open]:fade-in-0"
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def element_attributes(**defaults)
|
|
19
|
+
super(**{
|
|
20
|
+
"data-state" => "closed",
|
|
21
|
+
hidden: true,
|
|
22
|
+
"data-shadcn--dialog-target" => "overlay"
|
|
23
|
+
}.merge(defaults))
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Dialog
|
|
5
|
+
class Preview < ApplicationViewComponentPreview
|
|
6
|
+
def default
|
|
7
|
+
render_with_template
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# The case the layering has to survive: a modal opened from inside an
|
|
11
|
+
# ancestor that creates a stacking context.
|
|
12
|
+
def inside_stacking_context
|
|
13
|
+
render_with_template
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Upstream's "No Close Button": the corner dismiss left out.
|
|
17
|
+
def no_close_button
|
|
18
|
+
render_with_template
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Upstream's "Scrollable Content": a body that scrolls under a header and
|
|
22
|
+
# footer that do not.
|
|
23
|
+
def scrollable_content
|
|
24
|
+
render_with_template
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<%= render(Shadcn::Dialog::Component.new) do |d| %>
|
|
2
|
+
<% d.with_trigger(class: Shadcn::Button::Component.variant_classes(variant: :outline)) { "Edit profile" } %>
|
|
3
|
+
<% d.with_dialog_content do |c| %>
|
|
4
|
+
<% c.with_header do |h| %>
|
|
5
|
+
<% h.with_title { "Edit profile" } %>
|
|
6
|
+
<% h.with_description { "Make changes to your profile here. Click save when you are done." } %>
|
|
7
|
+
<% end %>
|
|
8
|
+
<div class="flex flex-col gap-4">
|
|
9
|
+
<%= render(Shadcn::Label::Component.new(for: "dlg-name")) { "Name" } %>
|
|
10
|
+
<%= render(Shadcn::Input::Component.new(id: "dlg-name", value: "Pedro Duarte")) %>
|
|
11
|
+
</div>
|
|
12
|
+
<% c.with_footer do %>
|
|
13
|
+
<%= render(Shadcn::Dialog::Close::Component.new(class: Shadcn::Button::Component.variant_classes(variant: :outline))) { "Cancel" } %>
|
|
14
|
+
<%= render(Shadcn::Button::Component.new) { "Save changes" } %>
|
|
15
|
+
<% end %>
|
|
16
|
+
<% end %>
|
|
17
|
+
<% end %>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<%# A modal opened from inside a stacking context — a "Delete" button in a
|
|
2
|
+
sticky toolbar, say. The overlay and the content are separate fixed
|
|
3
|
+
elements, so both have to reach the top layer, and in that order. %>
|
|
4
|
+
|
|
5
|
+
<div class="relative z-10 flex items-center gap-3 rounded-lg border bg-card p-4"
|
|
6
|
+
data-testid="stacking-header">
|
|
7
|
+
<span class="text-sm text-muted-foreground">A toolbar at z-10</span>
|
|
8
|
+
|
|
9
|
+
<%= render(Shadcn::Dialog::Component.new) do |dialog| %>
|
|
10
|
+
<% dialog.with_trigger(class: Shadcn::Button::Component.variant_classes(variant: :outline)) do %>
|
|
11
|
+
Open dialog
|
|
12
|
+
<% end %>
|
|
13
|
+
<% dialog.with_dialog_content do |content| %>
|
|
14
|
+
<% content.with_header do |header| %>
|
|
15
|
+
<% header.with_title { "Am I on top?" } %>
|
|
16
|
+
<% header.with_description { "If the panel below covers this, the modal lost to a stacking context." } %>
|
|
17
|
+
<% end %>
|
|
18
|
+
<% end %>
|
|
19
|
+
<% end %>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<div class="relative z-20 mt-2 h-96 rounded-lg border bg-muted p-4"
|
|
23
|
+
data-testid="stacking-sibling">
|
|
24
|
+
<span class="text-sm font-medium">A sibling at z-20</span>
|
|
25
|
+
</div>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<%# Upstream's "No Close Button": the corner dismiss is left out, so the only
|
|
2
|
+
ways out are the footer, Escape and a click outside. %>
|
|
3
|
+
<%= render(Shadcn::Dialog::Component.new) do |d| %>
|
|
4
|
+
<% d.with_trigger(class: Shadcn::Button::Component.variant_classes(variant: :outline)) { "Open" } %>
|
|
5
|
+
<% d.with_dialog_content(show_close_button: false) do |c| %>
|
|
6
|
+
<% c.with_header do |h| %>
|
|
7
|
+
<% h.with_title { "Terms of service" } %>
|
|
8
|
+
<% h.with_description { "You have to answer before this closes from inside." } %>
|
|
9
|
+
<% end %>
|
|
10
|
+
<% c.with_footer do %>
|
|
11
|
+
<%= render(Shadcn::Dialog::Close::Component.new(class: Shadcn::Button::Component.variant_classes(variant: :outline))) { "Decline" } %>
|
|
12
|
+
<%= render(Shadcn::Button::Component.new) { "Accept" } %>
|
|
13
|
+
<% end %>
|
|
14
|
+
<% end %>
|
|
15
|
+
<% end %>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<%# Upstream's "Scrollable Content": the body scrolls and the header and footer
|
|
2
|
+
stay put, which is what a dialog taller than the viewport has to do.
|
|
3
|
+
|
|
4
|
+
Two classes carry it, and the first version of this preview had neither, so
|
|
5
|
+
the panel simply grew past its own `max-h` and pushed its footer off the
|
|
6
|
+
screen. The content is a grid, so the rows have to be told which one gives —
|
|
7
|
+
`grid-rows-[auto_1fr_auto]` — and a grid item's `min-height` is `auto`,
|
|
8
|
+
which means it refuses to shrink below its content until `min-h-0` says it
|
|
9
|
+
may. Neither is upstream's markup: they are what a caller has to add, and
|
|
10
|
+
that is what this preview is for. %>
|
|
11
|
+
<%= render(Shadcn::Dialog::Component.new) do |d| %>
|
|
12
|
+
<% d.with_trigger(class: Shadcn::Button::Component.variant_classes(variant: :outline)) { "Open a long dialog" } %>
|
|
13
|
+
<% d.with_dialog_content(class: "grid max-h-[80vh] grid-rows-[auto_1fr_auto] gap-0 p-0") do |c| %>
|
|
14
|
+
<% c.with_header(class: "border-b p-6") do |h| %>
|
|
15
|
+
<% h.with_title { "Release notes" } %>
|
|
16
|
+
<% h.with_description { "Everything that changed in this version." } %>
|
|
17
|
+
<% end %>
|
|
18
|
+
<div class="min-h-0 overflow-y-auto px-6 py-4">
|
|
19
|
+
<% 20.times do |i| %>
|
|
20
|
+
<p class="border-b py-3 text-sm text-muted-foreground last:border-b-0">
|
|
21
|
+
Change <%= i + 1 %> — a line long enough to make the body worth scrolling.
|
|
22
|
+
</p>
|
|
23
|
+
<% end %>
|
|
24
|
+
</div>
|
|
25
|
+
<% c.with_footer(class: "border-t p-6") do %>
|
|
26
|
+
<%= render(Shadcn::Dialog::Close::Component.new(class: Shadcn::Button::Component.variant_classes(variant: :outline))) { "Close" } %>
|
|
27
|
+
<% end %>
|
|
28
|
+
<% end %>
|
|
29
|
+
<% end %>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Dialog
|
|
5
|
+
module Trigger
|
|
6
|
+
# DialogTrigger
|
|
7
|
+
class Component < ApplicationViewComponent
|
|
8
|
+
default_tag :button
|
|
9
|
+
slot_name :"dialog-trigger"
|
|
10
|
+
|
|
11
|
+
def element_attributes(**defaults)
|
|
12
|
+
super(**{
|
|
13
|
+
type: "button",
|
|
14
|
+
"aria-haspopup" => "dialog",
|
|
15
|
+
"aria-expanded" => "false",
|
|
16
|
+
"data-state" => "closed",
|
|
17
|
+
"data-shadcn--dialog-target" => "trigger",
|
|
18
|
+
"data-action" => "shadcn--dialog#open"
|
|
19
|
+
}.merge(defaults))
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
# The parts of the Dialog family that are just an element with a
|
|
5
|
+
# `data-slot` and a fixed set of classes. Anything with variants, slots or
|
|
6
|
+
# markup of its own keeps its own `component.rb`.
|
|
7
|
+
module Dialog
|
|
8
|
+
extend Parts
|
|
9
|
+
|
|
10
|
+
part :description, tag: :p, slot: "dialog-description", classes: "text-sm text-muted-foreground"
|
|
11
|
+
|
|
12
|
+
part :footer, slot: "dialog-footer",
|
|
13
|
+
classes: "flex flex-col-reverse gap-2 sm:flex-row sm:justify-end"
|
|
14
|
+
|
|
15
|
+
part :title, tag: :h2, slot: "dialog-title", classes: "text-lg leading-none font-semibold"
|
|
16
|
+
end
|
|
17
|
+
end
|