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,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module ModeSwitcher
|
|
5
|
+
# Port of apps/v4/components/mode-switcher.tsx — the single button used in
|
|
6
|
+
# shadcn's own site header, which flips straight between light and dark
|
|
7
|
+
# rather than offering the three-way menu.
|
|
8
|
+
#
|
|
9
|
+
# The icon is the same half-filled circle upstream draws inline.
|
|
10
|
+
class Component < ApplicationViewComponent
|
|
11
|
+
ICON = %(<path stroke="none" d="M0 0h24v24H0z" fill="none"/>) +
|
|
12
|
+
%(<path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0"/>) +
|
|
13
|
+
%(<path d="M12 3l0 18"/><path d="M12 9l4.65 -4.65"/>) +
|
|
14
|
+
%(<path d="M12 14.3l7.37 -7.37"/><path d="M12 19.6l8.85 -8.85"/>)
|
|
15
|
+
|
|
16
|
+
ICON_ATTRIBUTES = {
|
|
17
|
+
"xmlns" => "http://www.w3.org/2000/svg",
|
|
18
|
+
"width" => "24",
|
|
19
|
+
"height" => "24",
|
|
20
|
+
"viewBox" => "0 0 24 24",
|
|
21
|
+
"fill" => "none",
|
|
22
|
+
"stroke" => "currentColor",
|
|
23
|
+
"stroke-width" => "2",
|
|
24
|
+
"stroke-linecap" => "round",
|
|
25
|
+
"stroke-linejoin" => "round",
|
|
26
|
+
"class" => "size-4.5"
|
|
27
|
+
}.freeze
|
|
28
|
+
|
|
29
|
+
slot_name :"mode-switcher"
|
|
30
|
+
|
|
31
|
+
attr_reader :variant
|
|
32
|
+
|
|
33
|
+
def initialize(variant: :ghost, **attributes)
|
|
34
|
+
@variant = variant&.to_sym || :ghost
|
|
35
|
+
super(**attributes)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def element_attributes(**defaults)
|
|
39
|
+
super(**{
|
|
40
|
+
style: merged_style(CONTENTS_STYLE),
|
|
41
|
+
"data-controller" => "shadcn--theme"
|
|
42
|
+
}.merge(defaults))
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def call
|
|
46
|
+
render_element(body: button)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
def button
|
|
52
|
+
render(Button::Component.new(
|
|
53
|
+
variant:,
|
|
54
|
+
size: :icon,
|
|
55
|
+
class: "group/toggle extend-touch-target size-8",
|
|
56
|
+
"data-action": "shadcn--theme#toggle"
|
|
57
|
+
)) do
|
|
58
|
+
safe_join([ tag.svg(raw(ICON), **ICON_ATTRIBUTES), label ])
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def label
|
|
63
|
+
tag.span(shadcn_t("theme.toggle"), class: "sr-only")
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module ModeToggle
|
|
5
|
+
# Port of registry/new-york-v4/examples/mode-toggle.tsx — the dropdown
|
|
6
|
+
# shadcn documents for switching between light, dark and system.
|
|
7
|
+
#
|
|
8
|
+
# In React the items call next-themes' `setTheme`; here they hand the mode
|
|
9
|
+
# to the `shadcn--theme` Stimulus controller wrapping them.
|
|
10
|
+
class Component < ApplicationViewComponent
|
|
11
|
+
SUN_CLASSES = "h-[1.2rem] w-[1.2rem] scale-100 rotate-0 transition-all " \
|
|
12
|
+
"dark:scale-0 dark:-rotate-90"
|
|
13
|
+
|
|
14
|
+
MOON_CLASSES = "absolute h-[1.2rem] w-[1.2rem] scale-0 rotate-90 transition-all " \
|
|
15
|
+
"dark:scale-100 dark:rotate-0"
|
|
16
|
+
|
|
17
|
+
MODES = %w[light dark system].freeze
|
|
18
|
+
|
|
19
|
+
slot_name :"mode-toggle"
|
|
20
|
+
|
|
21
|
+
attr_reader :variant, :align
|
|
22
|
+
|
|
23
|
+
def initialize(variant: :outline, align: :end, **attributes)
|
|
24
|
+
@variant = variant&.to_sym || :outline
|
|
25
|
+
@align = align&.to_sym || :end
|
|
26
|
+
super(**attributes)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def element_attributes(**defaults)
|
|
30
|
+
super(**{
|
|
31
|
+
style: merged_style(CONTENTS_STYLE),
|
|
32
|
+
"data-controller" => "shadcn--theme"
|
|
33
|
+
}.merge(defaults))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def call
|
|
37
|
+
render_element(body: menu)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def menu
|
|
43
|
+
render(DropdownMenu::Component.new(align:)) do |dropdown|
|
|
44
|
+
dropdown.with_trigger(class: trigger_classes) { trigger_content }
|
|
45
|
+
dropdown.with_menu_content { items }
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def trigger_classes
|
|
50
|
+
Button::Component.variant_classes(variant:, size: :icon)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def trigger_content
|
|
54
|
+
safe_join([
|
|
55
|
+
render(Icon::Component.new("sun", class: SUN_CLASSES)),
|
|
56
|
+
render(Icon::Component.new("moon", class: MOON_CLASSES)),
|
|
57
|
+
tag.span(shadcn_t("theme.toggle"), class: "sr-only")
|
|
58
|
+
])
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def items
|
|
62
|
+
safe_join(MODES.map { |mode| item(mode) })
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Only the extra action goes here: the item already carries the dropdown's
|
|
66
|
+
# own, and `data-action` is concatenated rather than replaced.
|
|
67
|
+
def item(mode)
|
|
68
|
+
render(DropdownMenu::Item::Component.new(
|
|
69
|
+
"data-mode": mode,
|
|
70
|
+
"data-action": "click->shadcn--theme#setMode"
|
|
71
|
+
)) { shadcn_t("theme.#{mode}") }
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<div class="flex flex-col gap-6">
|
|
2
|
+
<div class="flex items-center gap-3">
|
|
3
|
+
<%= render(Shadcn::ModeToggle::Component.new) %>
|
|
4
|
+
<span class="text-sm text-muted-foreground">Light / Dark / System</span>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<%= render(Shadcn::Card::Component.new(class: "w-full max-w-sm")) do |card| %>
|
|
8
|
+
<% card.with_header do |header| %>
|
|
9
|
+
<% header.with_title { "It follows the mode" } %>
|
|
10
|
+
<% header.with_description { "Every token swaps with the .dark class." } %>
|
|
11
|
+
<% end %>
|
|
12
|
+
<% card.with_card_content do %>
|
|
13
|
+
<div class="flex flex-wrap gap-2">
|
|
14
|
+
<%= render(Shadcn::Button::Component.new) { "Primary" } %>
|
|
15
|
+
<%= render(Shadcn::Button::Component.new(variant: :secondary)) { "Secondary" } %>
|
|
16
|
+
<%= render(Shadcn::Badge::Component.new) { "Badge" } %>
|
|
17
|
+
</div>
|
|
18
|
+
<% end %>
|
|
19
|
+
<% end %>
|
|
20
|
+
</div>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module NativeSelect
|
|
5
|
+
# Port of registry/new-york-v4/ui/native-select.tsx — a real <select> with
|
|
6
|
+
# the native chevron replaced by a lucide icon.
|
|
7
|
+
class Component < ApplicationViewComponent
|
|
8
|
+
WRAPPER_CLASSES = "group/native-select relative w-fit has-[select:disabled]:opacity-50"
|
|
9
|
+
|
|
10
|
+
ICON_CLASSES = "pointer-events-none absolute top-1/2 right-3.5 size-4 " \
|
|
11
|
+
"-translate-y-1/2 text-muted-foreground opacity-50 select-none"
|
|
12
|
+
|
|
13
|
+
default_tag :select
|
|
14
|
+
slot_name :"native-select"
|
|
15
|
+
|
|
16
|
+
style do
|
|
17
|
+
base {
|
|
18
|
+
"h-9 w-full min-w-0 appearance-none rounded-md border border-input bg-transparent " \
|
|
19
|
+
"px-3 py-2 pr-9 text-sm shadow-xs transition-[color,box-shadow] outline-none " \
|
|
20
|
+
"selection:bg-primary selection:text-primary-foreground " \
|
|
21
|
+
"placeholder:text-muted-foreground disabled:pointer-events-none " \
|
|
22
|
+
"disabled:cursor-not-allowed data-[size=sm]:h-8 data-[size=sm]:py-1 " \
|
|
23
|
+
"dark:bg-input/30 dark:hover:bg-input/50 " \
|
|
24
|
+
"focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 " \
|
|
25
|
+
"aria-invalid:border-destructive aria-invalid:ring-destructive/20 " \
|
|
26
|
+
"dark:aria-invalid:ring-destructive/40"
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
attr_reader :size
|
|
31
|
+
|
|
32
|
+
def initialize(size: :default, **attributes)
|
|
33
|
+
@size = size&.to_sym || :default
|
|
34
|
+
super(**attributes)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def element_attributes(**defaults)
|
|
38
|
+
super(**{ "data-size" => size }.merge(defaults))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def call
|
|
42
|
+
tag.div(class: WRAPPER_CLASSES, "data-slot": "native-select-wrapper") do
|
|
43
|
+
safe_join([ render_element(body: content), chevron ])
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def chevron
|
|
50
|
+
render(Icon::Component.new(
|
|
51
|
+
"chevron-down",
|
|
52
|
+
class: ICON_CLASSES,
|
|
53
|
+
"aria-hidden": "true",
|
|
54
|
+
"data-slot": "native-select-icon"
|
|
55
|
+
))
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module NativeSelect
|
|
5
|
+
class Preview < ApplicationViewComponentPreview
|
|
6
|
+
def default
|
|
7
|
+
render_with_template
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Upstream's "With Groups", "Disabled" and "Invalid".
|
|
11
|
+
def groups
|
|
12
|
+
render_with_template
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<div class="flex items-center gap-4">
|
|
2
|
+
<% %i[default sm].each do |size| %>
|
|
3
|
+
<%= render(Shadcn::NativeSelect::Component.new(size:, "aria-label": "Favourite fruit")) do %>
|
|
4
|
+
<% %w[Apple Banana Blueberry].each do |fruit| %>
|
|
5
|
+
<%= render(Shadcn::NativeSelect::Option::Component.new(value: fruit.downcase)) { fruit } %>
|
|
6
|
+
<% end %>
|
|
7
|
+
<% end %>
|
|
8
|
+
<% end %>
|
|
9
|
+
</div>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<%# Upstream's "With Groups", "Disabled" and "Invalid". The optgroup is the one
|
|
2
|
+
thing the styled Select cannot do with a real element — this is a `<select>`,
|
|
3
|
+
so the browser draws the grouping itself. %>
|
|
4
|
+
<div class="flex items-start gap-4">
|
|
5
|
+
<%= render(Shadcn::NativeSelect::Component.new("aria-label": "Timezone")) do %>
|
|
6
|
+
<%= render(Shadcn::NativeSelect::OptGroup::Component.new(label: "Europe")) do %>
|
|
7
|
+
<% %w[London Paris Berlin].each do |city| %>
|
|
8
|
+
<%= render(Shadcn::NativeSelect::Option::Component.new(value: city.downcase)) { city } %>
|
|
9
|
+
<% end %>
|
|
10
|
+
<% end %>
|
|
11
|
+
<%= render(Shadcn::NativeSelect::OptGroup::Component.new(label: "Americas")) do %>
|
|
12
|
+
<% %w[Toronto Chicago].each do |city| %>
|
|
13
|
+
<%= render(Shadcn::NativeSelect::Option::Component.new(value: city.downcase)) { city } %>
|
|
14
|
+
<% end %>
|
|
15
|
+
<% end %>
|
|
16
|
+
<% end %>
|
|
17
|
+
|
|
18
|
+
<%= render(Shadcn::NativeSelect::Component.new("aria-label": "Disabled", disabled: true)) do %>
|
|
19
|
+
<%= render(Shadcn::NativeSelect::Option::Component.new(value: "one")) { "Not available" } %>
|
|
20
|
+
<% end %>
|
|
21
|
+
|
|
22
|
+
<%= render(Shadcn::NativeSelect::Component.new("aria-label": "Invalid", "aria-invalid": "true")) do %>
|
|
23
|
+
<%= render(Shadcn::NativeSelect::Option::Component.new(value: "")) { "Pick one" } %>
|
|
24
|
+
<%= render(Shadcn::NativeSelect::Option::Component.new(value: "one")) { "One" } %>
|
|
25
|
+
<% end %>
|
|
26
|
+
</div>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
# The parts of the NativeSelect 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 NativeSelect
|
|
8
|
+
extend Parts
|
|
9
|
+
|
|
10
|
+
part :opt_group, tag: :optgroup, slot: "native-select-optgroup",
|
|
11
|
+
classes: "bg-[Canvas] text-[CanvasText]"
|
|
12
|
+
|
|
13
|
+
part :option, tag: :option, slot: "native-select-option",
|
|
14
|
+
classes: "bg-[Canvas] text-[CanvasText]"
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module NavigationMenu
|
|
5
|
+
# Port of registry/new-york-v4/ui/navigation-menu.tsx, whose behaviour is
|
|
6
|
+
# Radix's `NavigationMenu` — 1,403 lines against shadcn's 168, vendored at
|
|
7
|
+
# `vendor/radix/ui/navigation-menu.tsx`.
|
|
8
|
+
#
|
|
9
|
+
# **`data-viewport` is always `false` here, and that is the decision this
|
|
10
|
+
# port turns on.** Upstream's default renders every panel into one shared
|
|
11
|
+
# box that animates between their sizes — measured on the live demo, the
|
|
12
|
+
# content's parent is `navigation-menu-viewport`, which means React has
|
|
13
|
+
# moved it there through a portal. Nothing is portalled in this gem, for the
|
|
14
|
+
# reason in decisions/02-javascript.md, so that mode cannot be reproduced
|
|
15
|
+
# without giving up the rule every other component here was built on.
|
|
16
|
+
#
|
|
17
|
+
# `viewport={false}` is not a workaround: it is a configuration shadcn
|
|
18
|
+
# supports and ships classes for, and in it each panel stays inside its own
|
|
19
|
+
# item with its own border, background and shadow. See
|
|
20
|
+
# features/navigation-menu.md.
|
|
21
|
+
class Component < ApplicationViewComponent
|
|
22
|
+
slot_name :"navigation-menu"
|
|
23
|
+
|
|
24
|
+
style do
|
|
25
|
+
base {
|
|
26
|
+
"group/navigation-menu relative flex max-w-max flex-1 items-center justify-center"
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
attr_reader :delay_duration, :skip_delay_duration
|
|
31
|
+
|
|
32
|
+
# Radix's own defaults (navigation-menu.tsx:136-137). `skip_delay_duration`
|
|
33
|
+
# is the grace period after a panel closes in which the next one opens at
|
|
34
|
+
# once — it is what stops a menu feeling sticky when you sweep across it.
|
|
35
|
+
def initialize(delay_duration: 200, skip_delay_duration: 300, **attributes)
|
|
36
|
+
@delay_duration = delay_duration
|
|
37
|
+
@skip_delay_duration = skip_delay_duration
|
|
38
|
+
super(**attributes)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def element_attributes(**defaults)
|
|
42
|
+
super(**{
|
|
43
|
+
"data-viewport" => "false",
|
|
44
|
+
"data-controller" => "shadcn--navigation-menu",
|
|
45
|
+
"data-shadcn--navigation-menu-delay-value" => delay_duration,
|
|
46
|
+
"data-shadcn--navigation-menu-skip-delay-value" => skip_delay_duration
|
|
47
|
+
}.merge(defaults))
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module NavigationMenu
|
|
5
|
+
module Content
|
|
6
|
+
# A panel. It stays inside its own item — see the root for why — so every
|
|
7
|
+
# class here that reads `group-data-[viewport=false]/navigation-menu:` is
|
|
8
|
+
# the one doing the work: the border, the surface, the shadow and the
|
|
9
|
+
# zoom are all in that half of the string.
|
|
10
|
+
#
|
|
11
|
+
# `data-motion` is the direction the panel arrives from, which the
|
|
12
|
+
# controller sets by comparing the item you left with the one you reached.
|
|
13
|
+
class Component < ApplicationViewComponent
|
|
14
|
+
slot_name :"navigation-menu-content"
|
|
15
|
+
|
|
16
|
+
style do
|
|
17
|
+
base {
|
|
18
|
+
"top-0 left-0 w-full p-2 pr-2.5 " \
|
|
19
|
+
"data-[motion=from-end]:slide-in-from-right-52 " \
|
|
20
|
+
"data-[motion=from-start]:slide-in-from-left-52 " \
|
|
21
|
+
"data-[motion=to-end]:slide-out-to-right-52 " \
|
|
22
|
+
"data-[motion=to-start]:slide-out-to-left-52 " \
|
|
23
|
+
"data-[motion^=from-]:animate-in data-[motion^=from-]:fade-in " \
|
|
24
|
+
"data-[motion^=to-]:animate-out data-[motion^=to-]:fade-out " \
|
|
25
|
+
"md:absolute md:w-auto " \
|
|
26
|
+
"group-data-[viewport=false]/navigation-menu:top-full " \
|
|
27
|
+
"group-data-[viewport=false]/navigation-menu:mt-1.5 " \
|
|
28
|
+
"group-data-[viewport=false]/navigation-menu:overflow-hidden " \
|
|
29
|
+
"group-data-[viewport=false]/navigation-menu:rounded-md " \
|
|
30
|
+
"group-data-[viewport=false]/navigation-menu:border " \
|
|
31
|
+
"group-data-[viewport=false]/navigation-menu:bg-popover " \
|
|
32
|
+
"group-data-[viewport=false]/navigation-menu:text-popover-foreground " \
|
|
33
|
+
"group-data-[viewport=false]/navigation-menu:shadow " \
|
|
34
|
+
"group-data-[viewport=false]/navigation-menu:duration-200 " \
|
|
35
|
+
"**:data-[slot=navigation-menu-link]:focus:ring-0 " \
|
|
36
|
+
"**:data-[slot=navigation-menu-link]:focus:outline-none " \
|
|
37
|
+
"group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out " \
|
|
38
|
+
"group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 " \
|
|
39
|
+
"group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 " \
|
|
40
|
+
"group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in " \
|
|
41
|
+
"group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 " \
|
|
42
|
+
"group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95"
|
|
43
|
+
}
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def element_attributes(**defaults)
|
|
47
|
+
super(**{
|
|
48
|
+
hidden: true,
|
|
49
|
+
"data-state" => "closed",
|
|
50
|
+
"data-shadcn--navigation-menu-target" => "content",
|
|
51
|
+
"data-action" => "pointerenter->shadcn--navigation-menu#pointerEnter " \
|
|
52
|
+
"pointerleave->shadcn--navigation-menu#pointerLeave"
|
|
53
|
+
}.merge(defaults))
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<%# Upstream's example, in the one configuration this port reproduces: each
|
|
2
|
+
panel stays inside its own item rather than being moved into a shared
|
|
3
|
+
viewport. shadcn supports both and ships the classes for this one — see
|
|
4
|
+
`features/navigation-menu.md` for why the other cannot be done here.
|
|
5
|
+
|
|
6
|
+
Three items so the panels have somewhere to slide *from*: `data-motion` is
|
|
7
|
+
computed by comparing the item you left with the one you reached, and with
|
|
8
|
+
two the direction is the same either way. The third item is a plain link,
|
|
9
|
+
which is what `Trigger::Component.new.css_classes` is for — upstream
|
|
10
|
+
exports the same string as `navigationMenuTriggerStyle`. %>
|
|
11
|
+
<div class="flex h-72 items-start justify-center pt-6">
|
|
12
|
+
<%= render(Shadcn::NavigationMenu::Component.new) do %>
|
|
13
|
+
<%= render(Shadcn::NavigationMenu::List::Component.new) do %>
|
|
14
|
+
<% {
|
|
15
|
+
"Getting started" => [
|
|
16
|
+
[ "Introduction", "Re-usable components built with Radix and Tailwind." ],
|
|
17
|
+
[ "Installation", "How to install dependencies and structure your app." ]
|
|
18
|
+
],
|
|
19
|
+
"Components" => [
|
|
20
|
+
[ "Accordion", "A vertically stacked set of interactive headings." ],
|
|
21
|
+
[ "Dialog", "A window overlaid on the primary window." ]
|
|
22
|
+
]
|
|
23
|
+
}.each do |label, links| %>
|
|
24
|
+
<%= render(Shadcn::NavigationMenu::Item::Component.new) do %>
|
|
25
|
+
<%= render(Shadcn::NavigationMenu::Trigger::Component.new) { label } %>
|
|
26
|
+
<%= render(Shadcn::NavigationMenu::Content::Component.new(class: "md:w-[400px]")) do %>
|
|
27
|
+
<ul class="grid gap-1">
|
|
28
|
+
<% links.each do |title, blurb| %>
|
|
29
|
+
<li>
|
|
30
|
+
<%= render(Shadcn::NavigationMenu::Link::Component.new(as: :a, href: "#")) do %>
|
|
31
|
+
<div class="text-sm leading-none font-medium"><%= title %></div>
|
|
32
|
+
<p class="text-sm leading-snug text-muted-foreground"><%= blurb %></p>
|
|
33
|
+
<% end %>
|
|
34
|
+
</li>
|
|
35
|
+
<% end %>
|
|
36
|
+
</ul>
|
|
37
|
+
<% end %>
|
|
38
|
+
<% end %>
|
|
39
|
+
<% end %>
|
|
40
|
+
|
|
41
|
+
<%= render(Shadcn::NavigationMenu::Item::Component.new) do %>
|
|
42
|
+
<%= render(Shadcn::NavigationMenu::Link::Component.new(
|
|
43
|
+
as: :a, href: "#",
|
|
44
|
+
class: Shadcn::NavigationMenu::Trigger::Component.new.css_classes
|
|
45
|
+
)) { "Documentation" } %>
|
|
46
|
+
<% end %>
|
|
47
|
+
<% end %>
|
|
48
|
+
<% end %>
|
|
49
|
+
</div>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module NavigationMenu
|
|
5
|
+
module Trigger
|
|
6
|
+
# The button that opens a panel. Its classes are exported upstream as
|
|
7
|
+
# `navigationMenuTriggerStyle` so a plain link can borrow them; the same
|
|
8
|
+
# is available here as `Component.new.css_classes`, which is how the
|
|
9
|
+
# sidebar preview borrows the menu button's.
|
|
10
|
+
class Component < ApplicationViewComponent
|
|
11
|
+
default_tag :button
|
|
12
|
+
slot_name :"navigation-menu-trigger"
|
|
13
|
+
|
|
14
|
+
style do
|
|
15
|
+
base {
|
|
16
|
+
"group inline-flex h-9 w-max items-center justify-center rounded-md " \
|
|
17
|
+
"bg-background px-4 py-2 text-sm font-medium transition-[color,box-shadow] " \
|
|
18
|
+
"outline-none hover:bg-accent hover:text-accent-foreground " \
|
|
19
|
+
"focus:bg-accent focus:text-accent-foreground focus-visible:ring-[3px] " \
|
|
20
|
+
"focus-visible:ring-ring/50 focus-visible:outline-1 " \
|
|
21
|
+
"disabled:pointer-events-none disabled:opacity-50 " \
|
|
22
|
+
"data-[state=open]:bg-accent/50 data-[state=open]:text-accent-foreground " \
|
|
23
|
+
"data-[state=open]:hover:bg-accent data-[state=open]:focus:bg-accent"
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def element_attributes(**defaults)
|
|
28
|
+
super(**{
|
|
29
|
+
type: "button",
|
|
30
|
+
"data-state" => "closed",
|
|
31
|
+
"aria-expanded" => "false",
|
|
32
|
+
"data-shadcn--navigation-menu-target" => "trigger",
|
|
33
|
+
"data-action" => "pointerenter->shadcn--navigation-menu#pointerEnter " \
|
|
34
|
+
"pointerleave->shadcn--navigation-menu#pointerLeave " \
|
|
35
|
+
"click->shadcn--navigation-menu#toggle " \
|
|
36
|
+
"keydown->shadcn--navigation-menu#keydown"
|
|
37
|
+
}.merge(defaults))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# The chevron is upstream's, and so is the space before it: shadcn
|
|
41
|
+
# writes `{children}{" "}` rather than a gap utility (navigation-menu.tsx:76).
|
|
42
|
+
def call
|
|
43
|
+
render_element(
|
|
44
|
+
body: safe_join([
|
|
45
|
+
content,
|
|
46
|
+
" ",
|
|
47
|
+
render(Shadcn::Icon::Component.new(
|
|
48
|
+
"chevron-down",
|
|
49
|
+
class: "relative top-[1px] ml-1 size-3 transition duration-300 " \
|
|
50
|
+
"group-data-[state=open]:rotate-180",
|
|
51
|
+
"aria-hidden": true
|
|
52
|
+
))
|
|
53
|
+
])
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
# The parts of the NavigationMenu family that are an element with a
|
|
5
|
+
# `data-slot` and a fixed set of classes.
|
|
6
|
+
module NavigationMenu
|
|
7
|
+
extend Parts
|
|
8
|
+
|
|
9
|
+
part :list, slot: "navigation-menu-list", tag: :ul,
|
|
10
|
+
classes: "group flex flex-1 list-none items-center justify-center gap-1"
|
|
11
|
+
|
|
12
|
+
part :item, slot: "navigation-menu-item", tag: :li, classes: "relative"
|
|
13
|
+
|
|
14
|
+
# The rows inside a panel. `data-active` is the caller's — this is a nav, so
|
|
15
|
+
# which link is current is the application's business, not the menu's.
|
|
16
|
+
part :link, slot: "navigation-menu-link",
|
|
17
|
+
classes: "flex flex-col gap-1 rounded-sm p-2 text-sm transition-all " \
|
|
18
|
+
"outline-none hover:bg-accent hover:text-accent-foreground " \
|
|
19
|
+
"focus:bg-accent focus:text-accent-foreground " \
|
|
20
|
+
"focus-visible:ring-[3px] focus-visible:ring-ring/50 " \
|
|
21
|
+
"focus-visible:outline-1 data-[active=true]:bg-accent/50 " \
|
|
22
|
+
"data-[active=true]:text-accent-foreground " \
|
|
23
|
+
"data-[active=true]:hover:bg-accent " \
|
|
24
|
+
"data-[active=true]:focus:bg-accent " \
|
|
25
|
+
"[&_svg:not([class*='size-'])]:size-4 " \
|
|
26
|
+
"[&_svg:not([class*='text-'])]:text-muted-foreground"
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Pagination
|
|
5
|
+
# Port of registry/new-york-v4/ui/pagination.tsx
|
|
6
|
+
class Component < ApplicationViewComponent
|
|
7
|
+
default_tag :nav
|
|
8
|
+
slot_name :pagination
|
|
9
|
+
|
|
10
|
+
style do
|
|
11
|
+
base { "mx-auto flex w-full justify-center" }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def element_attributes(**defaults)
|
|
15
|
+
super(**{ role: "navigation", "aria-label" => shadcn_t("pagination.label") }.merge(defaults))
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Pagination
|
|
5
|
+
module Ellipsis
|
|
6
|
+
# PaginationEllipsis
|
|
7
|
+
class Component < ApplicationViewComponent
|
|
8
|
+
default_tag :span
|
|
9
|
+
slot_name :"pagination-ellipsis"
|
|
10
|
+
|
|
11
|
+
style do
|
|
12
|
+
base { "flex size-9 items-center justify-center" }
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def element_attributes(**defaults)
|
|
16
|
+
super(**{ "aria-hidden" => true }.merge(defaults))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def call
|
|
20
|
+
render_element(body: safe_join([
|
|
21
|
+
render(Icon::Component.new("more-horizontal", class: "size-4")),
|
|
22
|
+
tag.span(shadcn_t("pagination.more"), class: "sr-only")
|
|
23
|
+
]))
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|