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,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Sidebar
|
|
5
|
+
module MenuAction
|
|
6
|
+
# SidebarMenuAction — the small button that sits on a menu item. It has a
|
|
7
|
+
# variant, which is why it is a component rather than a `sidebar_part`.
|
|
8
|
+
class Component < ApplicationViewComponent
|
|
9
|
+
default_tag :button
|
|
10
|
+
slot_name :"sidebar-menu-action"
|
|
11
|
+
|
|
12
|
+
style do
|
|
13
|
+
base {
|
|
14
|
+
"absolute top-1.5 right-1 flex aspect-square w-5 items-center " \
|
|
15
|
+
"justify-center rounded-md p-0 text-sidebar-foreground " \
|
|
16
|
+
"ring-sidebar-ring outline-hidden transition-transform " \
|
|
17
|
+
"peer-hover/menu-button:text-sidebar-accent-foreground " \
|
|
18
|
+
"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground " \
|
|
19
|
+
"focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0 after:absolute " \
|
|
20
|
+
"after:-inset-2 md:after:hidden peer-data-[size=sm]/menu-button:top-1 " \
|
|
21
|
+
"peer-data-[size=default]/menu-button:top-1.5 " \
|
|
22
|
+
"peer-data-[size=lg]/menu-button:top-2.5 " \
|
|
23
|
+
"group-data-[collapsible=icon]:hidden"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
variants {
|
|
27
|
+
show_on_hover {
|
|
28
|
+
yes {
|
|
29
|
+
"group-focus-within/menu-item:opacity-100 " \
|
|
30
|
+
"group-hover/menu-item:opacity-100 " \
|
|
31
|
+
"peer-data-[active=true]/menu-button:text-sidebar-accent-foreground " \
|
|
32
|
+
"data-[state=open]:opacity-100 md:opacity-0"
|
|
33
|
+
}
|
|
34
|
+
no { "" }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
defaults { { show_on_hover: :no } }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
attr_reader :show_on_hover
|
|
42
|
+
|
|
43
|
+
def initialize(show_on_hover: false, **attributes)
|
|
44
|
+
@show_on_hover = show_on_hover
|
|
45
|
+
super(**attributes)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def style_variants
|
|
49
|
+
{ show_on_hover: show_on_hover ? :yes : :no }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def element_attributes(**defaults)
|
|
53
|
+
super(**{ type: "button", "data-sidebar" => "menu-action" }.merge(defaults))
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Sidebar
|
|
5
|
+
module MenuButton
|
|
6
|
+
# SidebarMenuButton — the row a sidebar is mostly made of.
|
|
7
|
+
#
|
|
8
|
+
# `tooltip:` wraps the button in a Tooltip, as upstream does
|
|
9
|
+
# (vendor/shadcn/ui/sidebar.tsx:534-542). Upstream decides whether to show
|
|
10
|
+
# it with a runtime prop — `hidden={state !== "collapsed" || isMobile}` —
|
|
11
|
+
# which a server cannot evaluate. Here the same two conditions are CSS,
|
|
12
|
+
# read off the panel's own `group`: `data-state` is what the controller
|
|
13
|
+
# already writes, and `data-mobile` is what it sets while the mobile sheet
|
|
14
|
+
# is open. Same result, decided by the browser rather than by the render.
|
|
15
|
+
class Component < ApplicationViewComponent
|
|
16
|
+
default_tag :button
|
|
17
|
+
slot_name :"sidebar-menu-button"
|
|
18
|
+
|
|
19
|
+
style do
|
|
20
|
+
base {
|
|
21
|
+
"peer/menu-button flex w-full items-center gap-2 overflow-hidden " \
|
|
22
|
+
"rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden " \
|
|
23
|
+
"transition-[width,height,padding] " \
|
|
24
|
+
"group-has-data-[sidebar=menu-action]/menu-item:pr-8 " \
|
|
25
|
+
"group-data-[collapsible=icon]:size-8! " \
|
|
26
|
+
"group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent " \
|
|
27
|
+
"hover:text-sidebar-accent-foreground focus-visible:ring-2 " \
|
|
28
|
+
"active:bg-sidebar-accent active:text-sidebar-accent-foreground " \
|
|
29
|
+
"disabled:pointer-events-none disabled:opacity-50 " \
|
|
30
|
+
"aria-disabled:pointer-events-none aria-disabled:opacity-50 " \
|
|
31
|
+
"data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium " \
|
|
32
|
+
"data-[active=true]:text-sidebar-accent-foreground " \
|
|
33
|
+
"data-[state=open]:hover:bg-sidebar-accent " \
|
|
34
|
+
"data-[state=open]:hover:text-sidebar-accent-foreground " \
|
|
35
|
+
"[&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
variants {
|
|
39
|
+
variant {
|
|
40
|
+
default { "hover:bg-sidebar-accent hover:text-sidebar-accent-foreground" }
|
|
41
|
+
outline {
|
|
42
|
+
"bg-background shadow-[0_0_0_1px_var(--sidebar-border)] " \
|
|
43
|
+
"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground " \
|
|
44
|
+
"hover:shadow-[0_0_0_1px_var(--sidebar-accent)]"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
size {
|
|
49
|
+
default { "h-8 text-sm" }
|
|
50
|
+
sm { "h-7 text-xs" }
|
|
51
|
+
lg { "h-12 text-sm group-data-[collapsible=icon]:p-0!" }
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
defaults { { variant: :default, size: :default } }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# A tooltip is only of use when the label beside the icon is gone, so it
|
|
59
|
+
# is hidden while the sidebar is expanded, and while the mobile sheet is
|
|
60
|
+
# showing the full labels anyway.
|
|
61
|
+
TOOLTIP_CLASSES = "group-data-[state=expanded]:hidden group-data-[mobile=true]:hidden"
|
|
62
|
+
|
|
63
|
+
attr_reader :variant, :size, :active, :tooltip
|
|
64
|
+
|
|
65
|
+
def initialize(variant: :default, size: :default, active: false, tooltip: nil, **attributes)
|
|
66
|
+
@variant = variant&.to_sym || :default
|
|
67
|
+
@size = size&.to_sym || :default
|
|
68
|
+
@active = active
|
|
69
|
+
@tooltip = tooltip
|
|
70
|
+
super(**attributes)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def call
|
|
74
|
+
return render_element(body: content) if tooltip.blank?
|
|
75
|
+
|
|
76
|
+
render(Shadcn::Tooltip::Component.new(side: :right, align: :center)) do |wrapper|
|
|
77
|
+
# The trigger takes this button's own attributes, `data-slot`
|
|
78
|
+
# included, so the element in the document is still a
|
|
79
|
+
# `sidebar-menu-button` — which is what upstream's `asChild` does.
|
|
80
|
+
wrapper.with_trigger(as: tag_name, **element_attributes.transform_keys(&:to_sym)) { content }
|
|
81
|
+
wrapper.with_tooltip_content(class: TOOLTIP_CLASSES) { tooltip }
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def style_variants
|
|
86
|
+
{ variant:, size: }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def element_attributes(**defaults)
|
|
90
|
+
super(**{
|
|
91
|
+
type: "button",
|
|
92
|
+
"data-sidebar" => "menu-button",
|
|
93
|
+
"data-size" => size,
|
|
94
|
+
"data-active" => active.to_s
|
|
95
|
+
}.merge(defaults))
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Sidebar
|
|
5
|
+
module MenuSkeleton
|
|
6
|
+
# SidebarMenuSkeleton — a placeholder row. Upstream randomises the text
|
|
7
|
+
# width between 50% and 90% so a column of them does not look like a
|
|
8
|
+
# barcode (vendor/shadcn/ui/sidebar.tsx:611-613); the same range is used
|
|
9
|
+
# here, drawn once per instance.
|
|
10
|
+
class Component < ApplicationViewComponent
|
|
11
|
+
slot_name :"sidebar-menu-skeleton"
|
|
12
|
+
|
|
13
|
+
style do
|
|
14
|
+
base { "flex h-8 items-center gap-2 rounded-md px-2" }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
attr_reader :show_icon
|
|
18
|
+
|
|
19
|
+
def initialize(show_icon: false, **attributes)
|
|
20
|
+
@show_icon = show_icon
|
|
21
|
+
@width = "#{rand(50..89)}%"
|
|
22
|
+
super(**attributes)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def element_attributes(**defaults)
|
|
26
|
+
super(**{ "data-sidebar" => "menu-skeleton" }.merge(defaults))
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def call
|
|
30
|
+
render_element(body: safe_join([ icon, text ].compact))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def icon
|
|
36
|
+
return unless show_icon
|
|
37
|
+
|
|
38
|
+
render(Skeleton::Component.new(class: "size-4 rounded-md", "data-sidebar": "menu-skeleton-icon"))
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def text
|
|
42
|
+
render(Skeleton::Component.new(
|
|
43
|
+
class: "h-4 max-w-(--skeleton-width) flex-1",
|
|
44
|
+
"data-sidebar": "menu-skeleton-text",
|
|
45
|
+
style: "--skeleton-width: #{@width};"
|
|
46
|
+
))
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Sidebar
|
|
5
|
+
module MenuSubButton
|
|
6
|
+
# SidebarMenuSubButton — an `<a>` rather than a button, because a submenu
|
|
7
|
+
# row is a link upstream (vendor/shadcn/ui/sidebar.tsx:680).
|
|
8
|
+
class Component < ApplicationViewComponent
|
|
9
|
+
default_tag :a
|
|
10
|
+
slot_name :"sidebar-menu-sub-button"
|
|
11
|
+
|
|
12
|
+
style do
|
|
13
|
+
base {
|
|
14
|
+
"flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden " \
|
|
15
|
+
"rounded-md px-2 text-sidebar-foreground ring-sidebar-ring " \
|
|
16
|
+
"outline-hidden hover:bg-sidebar-accent " \
|
|
17
|
+
"hover:text-sidebar-accent-foreground focus-visible:ring-2 " \
|
|
18
|
+
"active:bg-sidebar-accent active:text-sidebar-accent-foreground " \
|
|
19
|
+
"disabled:pointer-events-none disabled:opacity-50 " \
|
|
20
|
+
"aria-disabled:pointer-events-none aria-disabled:opacity-50 " \
|
|
21
|
+
"[&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 " \
|
|
22
|
+
"[&>svg]:text-sidebar-accent-foreground " \
|
|
23
|
+
"data-[active=true]:bg-sidebar-accent " \
|
|
24
|
+
"data-[active=true]:text-sidebar-accent-foreground sm md " \
|
|
25
|
+
"group-data-[collapsible=icon]:hidden"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
variants {
|
|
29
|
+
size {
|
|
30
|
+
sm { "text-xs" }
|
|
31
|
+
md { "text-sm" }
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
defaults { { size: :md } }
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
attr_reader :size, :active
|
|
39
|
+
|
|
40
|
+
def initialize(size: :md, active: false, **attributes)
|
|
41
|
+
@size = size&.to_sym || :md
|
|
42
|
+
@active = active
|
|
43
|
+
super(**attributes)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def style_variants
|
|
47
|
+
{ size: }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def element_attributes(**defaults)
|
|
51
|
+
super(**{
|
|
52
|
+
"data-sidebar" => "menu-sub-button",
|
|
53
|
+
"data-size" => size,
|
|
54
|
+
"data-active" => active.to_s
|
|
55
|
+
}.merge(defaults))
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Sidebar
|
|
5
|
+
class Preview < ApplicationViewComponentPreview
|
|
6
|
+
def default
|
|
7
|
+
render_with_template
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Upstream's `floating` variant. Its own page: the panel is `fixed`, so
|
|
11
|
+
# two of them cannot share one.
|
|
12
|
+
def floating
|
|
13
|
+
render_with_template
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Upstream's `inset` variant, for the same reason.
|
|
17
|
+
def inset
|
|
18
|
+
render_with_template
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
<%# shadcn's own `sidebar-demo`, read from the iframe it renders in —
|
|
2
|
+
ui.shadcn.com/view/radix-nova/sidebar-demo — with `collapsible: :icon`,
|
|
3
|
+
which is what that demo uses: collapsing leaves a rail of icons rather than
|
|
4
|
+
sliding the whole panel away.
|
|
5
|
+
|
|
6
|
+
The icons are inlined rather than bundled. `Icon::Component`'s PATHS holds
|
|
7
|
+
the icons the *components* need; these are a demo's decoration, and putting
|
|
8
|
+
eight of them into a library's payload for one preview is the wrong trade.
|
|
9
|
+
Their paths were read from upstream's rendered demo rather than recalled.
|
|
10
|
+
|
|
11
|
+
The Projects rows carry `tooltip:`, which is what labels their icons once
|
|
12
|
+
the sidebar collapses. The Platform rows cannot: each is a Collapsible
|
|
13
|
+
trigger wearing the menu button's classes rather than a MenuButton, so it
|
|
14
|
+
takes a plain `title:` — the browser's own tooltip — instead. That
|
|
15
|
+
difference is upstream's too, and the reason is the same on both sides. %>
|
|
16
|
+
<%
|
|
17
|
+
icons = {
|
|
18
|
+
"gallery-vertical-end" => %(<path d="M7 2h10"/><path d="M5 6h14"/><rect width="18" height="12" x="3" y="10" rx="2"/>),
|
|
19
|
+
"square-terminal" => %(<path d="m7 11 2-2-2-2"/><path d="M11 13h4"/><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/>),
|
|
20
|
+
"bot" => %(<path d="M12 8V4H8"/><rect width="16" height="12" x="4" y="8" rx="2"/><path d="M2 14h2"/><path d="M20 14h2"/><path d="M15 13v2"/><path d="M9 13v2"/>),
|
|
21
|
+
"book-open" => %(<path d="M12 7v14"/><path d="M3 18a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h5a4 4 0 0 1 4 4 4 4 0 0 1 4-4h5a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1h-6a3 3 0 0 0-3 3 3 3 0 0 0-3-3z"/>),
|
|
22
|
+
"settings-2" => %(<path d="M20 7h-9"/><path d="M14 17H5"/><circle cx="17" cy="17" r="3"/><circle cx="7" cy="7" r="3"/>),
|
|
23
|
+
"frame" => %(<line x1="22" x2="2" y1="6" y2="6"/><line x1="22" x2="2" y1="18" y2="18"/><line x1="6" x2="6" y1="2" y2="22"/><line x1="18" x2="18" y1="2" y2="22"/>),
|
|
24
|
+
"chart-pie" => %(<path d="M21 12c.552 0 1.005-.449.95-.998a10 10 0 0 0-8.953-8.951c-.55-.055-.998.398-.998.95v8a1 1 0 0 0 1 1z"/><path d="M21.21 15.89A10 10 0 1 1 8 2.83"/>),
|
|
25
|
+
"map" => %(<path d="M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z"/><path d="M15 5.764v15"/><path d="M9 3.236v15"/>),
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
glyph = ->(name, extra = nil) do
|
|
29
|
+
tag.svg(
|
|
30
|
+
icons.fetch(name).html_safe,
|
|
31
|
+
xmlns: "http://www.w3.org/2000/svg", width: 24, height: 24,
|
|
32
|
+
viewBox: "0 0 24 24", fill: "none", stroke: "currentColor",
|
|
33
|
+
"stroke-width": 2, "stroke-linecap": "round", "stroke-linejoin": "round",
|
|
34
|
+
class: [ "size-4 shrink-0", extra ].compact.join(" "), "aria-hidden": true
|
|
35
|
+
)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
platform = {
|
|
39
|
+
"Playground" => [ "square-terminal", %w[History Starred Settings] ],
|
|
40
|
+
"Models" => [ "bot", %w[Genesis Explorer Quantum] ],
|
|
41
|
+
"Documentation" => [ "book-open", [ "Introduction", "Get Started", "Tutorials" ] ],
|
|
42
|
+
"Settings" => [ "settings-2", %w[General Team Billing] ]
|
|
43
|
+
}
|
|
44
|
+
projects = [ [ "Design Engineering", "frame" ], [ "Sales & Marketing", "chart-pie" ], [ "Travel", "map" ] ]
|
|
45
|
+
%>
|
|
46
|
+
<%= render(Shadcn::Sidebar::Provider::Component.new) do %>
|
|
47
|
+
<%= render(Shadcn::Sidebar::Component.new(collapsible: :icon)) do %>
|
|
48
|
+
<%= render(Shadcn::Sidebar::Header::Component.new) do %>
|
|
49
|
+
<%= render(Shadcn::Sidebar::Menu::Component.new) do %>
|
|
50
|
+
<%= render(Shadcn::Sidebar::MenuItem::Component.new) do %>
|
|
51
|
+
<%= render(Shadcn::DropdownMenu::Component.new) do |menu| %>
|
|
52
|
+
<% menu.with_trigger(
|
|
53
|
+
class: Shadcn::Sidebar::MenuButton::Component.new(size: :lg).css_classes,
|
|
54
|
+
"data-size": "lg"
|
|
55
|
+
) do %>
|
|
56
|
+
<div class="flex aspect-square size-8 shrink-0 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground">
|
|
57
|
+
<%= glyph.call("gallery-vertical-end") %>
|
|
58
|
+
</div>
|
|
59
|
+
<div class="grid flex-1 text-left text-sm leading-tight">
|
|
60
|
+
<span class="truncate font-medium">Acme Inc</span>
|
|
61
|
+
<span class="truncate text-xs">Enterprise</span>
|
|
62
|
+
</div>
|
|
63
|
+
<%= render(Shadcn::Icon::Component.new("chevrons-up-down", class: "ml-auto")) %>
|
|
64
|
+
<% end %>
|
|
65
|
+
<% menu.with_menu_content(class: "w-56") do %>
|
|
66
|
+
<%= render(Shadcn::DropdownMenu::Label::Component.new) { "Teams" } %>
|
|
67
|
+
<% [ "Acme Inc", "Acme Corp.", "Evil Corp." ].each do |team| %>
|
|
68
|
+
<%= render(Shadcn::DropdownMenu::Item::Component.new) { team } %>
|
|
69
|
+
<% end %>
|
|
70
|
+
<%= render(Shadcn::DropdownMenu::Separator::Component.new) %>
|
|
71
|
+
<%= render(Shadcn::DropdownMenu::Item::Component.new) { "Add team" } %>
|
|
72
|
+
<% end %>
|
|
73
|
+
<% end %>
|
|
74
|
+
<% end %>
|
|
75
|
+
<% end %>
|
|
76
|
+
<% end %>
|
|
77
|
+
|
|
78
|
+
<%= render(Shadcn::Sidebar::Content::Component.new) do %>
|
|
79
|
+
<%= render(Shadcn::Sidebar::Group::Component.new) do %>
|
|
80
|
+
<%= render(Shadcn::Sidebar::GroupLabel::Component.new) { "Platform" } %>
|
|
81
|
+
<%= render(Shadcn::Sidebar::Menu::Component.new) do %>
|
|
82
|
+
<% platform.each_with_index do |(section, (name, pages)), index| %>
|
|
83
|
+
<%= render(Shadcn::Sidebar::MenuItem::Component.new) do %>
|
|
84
|
+
<%= render(Shadcn::Collapsible::Component.new(open: index.zero?, class: "group/collapsible")) do %>
|
|
85
|
+
<%# Neither slot is used, and that is deliberate. Slot content
|
|
86
|
+
renders before block content, so `with_panel` would put the
|
|
87
|
+
submenu above its own trigger; and the trigger has to *be*
|
|
88
|
+
the MenuButton, not a plain trigger wearing its classes,
|
|
89
|
+
because that is where `tooltip:` lives and a collapsed rail
|
|
90
|
+
of icons has nothing else to label it. Upstream composes it
|
|
91
|
+
the same way: `<CollapsibleTrigger asChild>
|
|
92
|
+
<SidebarMenuButton tooltip={…}>`. %>
|
|
93
|
+
<%= render(Shadcn::Sidebar::MenuButton::Component.new(
|
|
94
|
+
tooltip: section,
|
|
95
|
+
"data-shadcn--collapsible-target": "trigger",
|
|
96
|
+
"data-action": "shadcn--collapsible#toggle",
|
|
97
|
+
"aria-expanded": index.zero?.to_s
|
|
98
|
+
)) do %>
|
|
99
|
+
<%= glyph.call(name) %>
|
|
100
|
+
<span><%= section %></span>
|
|
101
|
+
<%= render(Shadcn::Icon::Component.new(
|
|
102
|
+
"chevron-right",
|
|
103
|
+
class: "ml-auto transition-transform group-data-[state=open]/collapsible:rotate-90"
|
|
104
|
+
)) %>
|
|
105
|
+
<% end %>
|
|
106
|
+
|
|
107
|
+
<%= render(Shadcn::Collapsible::Content::Component.new) do %>
|
|
108
|
+
<%= render(Shadcn::Sidebar::MenuSub::Component.new) do %>
|
|
109
|
+
<% pages.each do |page| %>
|
|
110
|
+
<%= render(Shadcn::Sidebar::MenuSubItem::Component.new) do %>
|
|
111
|
+
<%= render(Shadcn::Sidebar::MenuSubButton::Component.new(href: "#")) do %>
|
|
112
|
+
<span><%= page %></span>
|
|
113
|
+
<% end %>
|
|
114
|
+
<% end %>
|
|
115
|
+
<% end %>
|
|
116
|
+
<% end %>
|
|
117
|
+
<% end %>
|
|
118
|
+
<% end %>
|
|
119
|
+
<% end %>
|
|
120
|
+
<% end %>
|
|
121
|
+
<% end %>
|
|
122
|
+
<% end %>
|
|
123
|
+
|
|
124
|
+
<%= render(Shadcn::Sidebar::Group::Component.new(class: "group-data-[collapsible=icon]:hidden")) do %>
|
|
125
|
+
<%= render(Shadcn::Sidebar::GroupLabel::Component.new) { "Projects" } %>
|
|
126
|
+
<%= render(Shadcn::Sidebar::Menu::Component.new) do %>
|
|
127
|
+
<% projects.each do |(project, name)| %>
|
|
128
|
+
<%= render(Shadcn::Sidebar::MenuItem::Component.new) do %>
|
|
129
|
+
<%= render(Shadcn::Sidebar::MenuButton::Component.new(as: :a, href: "#", tooltip: project)) do %>
|
|
130
|
+
<%= glyph.call(name) %>
|
|
131
|
+
<span><%= project %></span>
|
|
132
|
+
<% end %>
|
|
133
|
+
<%= render(Shadcn::Sidebar::MenuAction::Component.new(show_on_hover: true, "aria-label": "More")) do %>
|
|
134
|
+
<%= render(Shadcn::Icon::Component.new("more-horizontal")) %>
|
|
135
|
+
<% end %>
|
|
136
|
+
<% end %>
|
|
137
|
+
<% end %>
|
|
138
|
+
<% end %>
|
|
139
|
+
<% end %>
|
|
140
|
+
<% end %>
|
|
141
|
+
|
|
142
|
+
<%= render(Shadcn::Sidebar::Footer::Component.new) do %>
|
|
143
|
+
<%= render(Shadcn::Sidebar::Menu::Component.new) do %>
|
|
144
|
+
<%= render(Shadcn::Sidebar::MenuItem::Component.new) do %>
|
|
145
|
+
<%= render(Shadcn::DropdownMenu::Component.new(side: :top)) do |menu| %>
|
|
146
|
+
<% menu.with_trigger(
|
|
147
|
+
class: Shadcn::Sidebar::MenuButton::Component.new(size: :lg).css_classes,
|
|
148
|
+
"data-size": "lg"
|
|
149
|
+
) do %>
|
|
150
|
+
<%= render(Shadcn::Avatar::Component.new(class: "size-8 shrink-0 rounded-lg")) do |avatar| %>
|
|
151
|
+
<% avatar.with_fallback { "SC" } %>
|
|
152
|
+
<% end %>
|
|
153
|
+
<div class="grid flex-1 text-left text-sm leading-tight">
|
|
154
|
+
<span class="truncate font-medium">shadcn</span>
|
|
155
|
+
<span class="truncate text-xs">m@example.com</span>
|
|
156
|
+
</div>
|
|
157
|
+
<%= render(Shadcn::Icon::Component.new("chevrons-up-down", class: "ml-auto")) %>
|
|
158
|
+
<% end %>
|
|
159
|
+
<% menu.with_menu_content(class: "w-56") do %>
|
|
160
|
+
<%= render(Shadcn::DropdownMenu::Label::Component.new) { "m@example.com" } %>
|
|
161
|
+
<%= render(Shadcn::DropdownMenu::Separator::Component.new) %>
|
|
162
|
+
<% [ "Account", "Billing", "Notifications" ].each do |entry| %>
|
|
163
|
+
<%= render(Shadcn::DropdownMenu::Item::Component.new) { entry } %>
|
|
164
|
+
<% end %>
|
|
165
|
+
<%= render(Shadcn::DropdownMenu::Separator::Component.new) %>
|
|
166
|
+
<%= render(Shadcn::DropdownMenu::Item::Component.new) { "Log out" } %>
|
|
167
|
+
<% end %>
|
|
168
|
+
<% end %>
|
|
169
|
+
<% end %>
|
|
170
|
+
<% end %>
|
|
171
|
+
<% end %>
|
|
172
|
+
|
|
173
|
+
<%# Inside the panel, last, exactly where upstream puts it: its `absolute`
|
|
174
|
+
is meant to resolve against `sidebar-container`, and its
|
|
175
|
+
`group-data-[side=left]:-right-4` against the panel's own `group`.
|
|
176
|
+
Rendered as a sibling instead it positions against the page and draws a
|
|
177
|
+
line straight through the icons. %>
|
|
178
|
+
<%= render(Shadcn::Sidebar::Rail::Component.new) %>
|
|
179
|
+
<% end %>
|
|
180
|
+
|
|
181
|
+
<%= render(Shadcn::Sidebar::Inset::Component.new) do %>
|
|
182
|
+
<div class="flex items-center gap-2 border-b p-2">
|
|
183
|
+
<%= render(Shadcn::Sidebar::Trigger::Component.new) %>
|
|
184
|
+
<%= render(Shadcn::Sidebar::Separator::Component.new(orientation: :vertical, class: "h-4")) %>
|
|
185
|
+
<span class="text-sm font-medium">Dashboard</span>
|
|
186
|
+
</div>
|
|
187
|
+
<p class="p-4 text-sm text-muted-foreground">Page content.</p>
|
|
188
|
+
<% end %>
|
|
189
|
+
<% end %>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<%# Upstream's `floating` variant, which the default preview does not show.
|
|
2
|
+
|
|
3
|
+
A page of its own, and that is forced rather than chosen: the desktop panel
|
|
4
|
+
is `fixed inset-y-0 … h-svh` (sidebar.tsx), so it is measured against the
|
|
5
|
+
viewport and cannot be put in a box. The first version of this preview put
|
|
6
|
+
two providers in two bordered `h-64` divs to compare the variants side by
|
|
7
|
+
side; both panels escaped their boxes, one covered the other, and the label
|
|
8
|
+
beside each said the wrong thing. Lookbook gives every preview its own
|
|
9
|
+
iframe, which is the only frame a sidebar can be shown in.
|
|
10
|
+
|
|
11
|
+
`floating` gives the panel its own rounded border and shadow and stands it
|
|
12
|
+
off the edge; `inset` leaves the panel flush and pulls the page's container
|
|
13
|
+
in beside it. Both read `group-data-[variant=…]` off the provider, so the
|
|
14
|
+
difference is on `SidebarInset` as much as on the panel. %>
|
|
15
|
+
<%= render(Shadcn::Sidebar::Provider::Component.new) do %>
|
|
16
|
+
<%= render(Shadcn::Sidebar::Component.new(variant: :floating, collapsible: :icon)) do %>
|
|
17
|
+
<%= render(Shadcn::Sidebar::Content::Component.new) do %>
|
|
18
|
+
<%= render(Shadcn::Sidebar::Group::Component.new) do %>
|
|
19
|
+
<%= render(Shadcn::Sidebar::GroupLabel::Component.new) { "Workspace" } %>
|
|
20
|
+
<%= render(Shadcn::Sidebar::Menu::Component.new) do %>
|
|
21
|
+
<% [["search", "Search"], ["circle", "Projects"], ["check", "Done"]].each do |icon, label| %>
|
|
22
|
+
<%= render(Shadcn::Sidebar::MenuItem::Component.new) do %>
|
|
23
|
+
<%= render(Shadcn::Sidebar::MenuButton::Component.new(tooltip: label)) do %>
|
|
24
|
+
<%= render(Shadcn::Icon::Component.new(icon)) %>
|
|
25
|
+
<span><%= label %></span>
|
|
26
|
+
<% end %>
|
|
27
|
+
<% end %>
|
|
28
|
+
<% end %>
|
|
29
|
+
<% end %>
|
|
30
|
+
<% end %>
|
|
31
|
+
<% end %>
|
|
32
|
+
<% end %>
|
|
33
|
+
<%= render(Shadcn::Sidebar::Inset::Component.new) do %>
|
|
34
|
+
<div class="flex items-center gap-2 border-b p-4">
|
|
35
|
+
<%= render(Shadcn::Sidebar::Trigger::Component.new) %>
|
|
36
|
+
<span class="text-sm text-muted-foreground">The page beside a floating panel — the trigger collapses it to a rail.</span>
|
|
37
|
+
</div>
|
|
38
|
+
<% end %>
|
|
39
|
+
<% end %>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<%# Upstream's `inset` variant, which the default preview does not show.
|
|
2
|
+
|
|
3
|
+
A page of its own, and that is forced rather than chosen: the desktop panel
|
|
4
|
+
is `fixed inset-y-0 … h-svh` (sidebar.tsx), so it is measured against the
|
|
5
|
+
viewport and cannot be put in a box. The first version of this preview put
|
|
6
|
+
two providers in two bordered `h-64` divs to compare the variants side by
|
|
7
|
+
side; both panels escaped their boxes, one covered the other, and the label
|
|
8
|
+
beside each said the wrong thing. Lookbook gives every preview its own
|
|
9
|
+
iframe, which is the only frame a sidebar can be shown in.
|
|
10
|
+
|
|
11
|
+
`inset` leaves the panel flush and pulls the page's container in beside it,
|
|
12
|
+
which reads `group-data-[variant=inset]` off the provider — so the variant
|
|
13
|
+
shows on `SidebarInset` as much as on the panel.
|
|
14
|
+
|
|
15
|
+
**The wrapper's background is overridden here, and that is a divergence.**
|
|
16
|
+
Upstream puts `has-data-[variant=inset]:bg-sidebar` on it (sidebar.tsx:142),
|
|
17
|
+
which is what makes the panel and the page look like two cards floating on
|
|
18
|
+
the sidebar's own colour — the whole idea of the variant. This preview asks
|
|
19
|
+
for `bg-background` instead. It is the caller's class, not the component's:
|
|
20
|
+
`cn` replaces the conflicting one, `parity_spec` still sees upstream's
|
|
21
|
+
string in the component source, and a host that says nothing still gets
|
|
22
|
+
upstream's look. `bg-background` rather than a literal white, so it follows
|
|
23
|
+
the theme instead of turning into a white slab in the dark one. %>
|
|
24
|
+
<%= render(Shadcn::Sidebar::Provider::Component.new(class: "has-data-[variant=inset]:bg-background")) do %>
|
|
25
|
+
<%= render(Shadcn::Sidebar::Component.new(variant: :inset, collapsible: :icon)) do %>
|
|
26
|
+
<%= render(Shadcn::Sidebar::Content::Component.new) do %>
|
|
27
|
+
<%= render(Shadcn::Sidebar::Group::Component.new) do %>
|
|
28
|
+
<%= render(Shadcn::Sidebar::GroupLabel::Component.new) { "Workspace" } %>
|
|
29
|
+
<%= render(Shadcn::Sidebar::Menu::Component.new) do %>
|
|
30
|
+
<% [["search", "Search"], ["circle", "Projects"], ["check", "Done"]].each do |icon, label| %>
|
|
31
|
+
<%= render(Shadcn::Sidebar::MenuItem::Component.new) do %>
|
|
32
|
+
<%= render(Shadcn::Sidebar::MenuButton::Component.new(tooltip: label)) do %>
|
|
33
|
+
<%= render(Shadcn::Icon::Component.new(icon)) %>
|
|
34
|
+
<span><%= label %></span>
|
|
35
|
+
<% end %>
|
|
36
|
+
<% end %>
|
|
37
|
+
<% end %>
|
|
38
|
+
<% end %>
|
|
39
|
+
<% end %>
|
|
40
|
+
<% end %>
|
|
41
|
+
<% end %>
|
|
42
|
+
<%= render(Shadcn::Sidebar::Inset::Component.new) do %>
|
|
43
|
+
<div class="flex items-center gap-2 border-b p-4">
|
|
44
|
+
<%= render(Shadcn::Sidebar::Trigger::Component.new) %>
|
|
45
|
+
<span class="text-sm text-muted-foreground">The page beside a inset panel — the trigger collapses it to a rail.</span>
|
|
46
|
+
</div>
|
|
47
|
+
<% end %>
|
|
48
|
+
<% end %>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Sidebar
|
|
5
|
+
module Provider
|
|
6
|
+
# SidebarProvider — the wrapper that holds the state for everything below
|
|
7
|
+
# it. In React that state is a context (vendor/shadcn/ui/sidebar.tsx:56);
|
|
8
|
+
# here it is the Stimulus controller, which is why this element and not
|
|
9
|
+
# the panel carries `data-controller`.
|
|
10
|
+
#
|
|
11
|
+
# Upstream also wraps its children in a `TooltipProvider` with
|
|
12
|
+
# `delayDuration={0}`, so a collapsed sidebar's icons can explain
|
|
13
|
+
# themselves. This port has no provider component — each Tooltip carries
|
|
14
|
+
# its own delay — so there is nothing to reproduce here.
|
|
15
|
+
class Component < ApplicationViewComponent
|
|
16
|
+
WIDTH = "16rem"
|
|
17
|
+
WIDTH_ICON = "3rem"
|
|
18
|
+
# Upstream's `SIDEBAR_WIDTH_MOBILE` (sidebar.tsx:31), which it applies by
|
|
19
|
+
# overriding `--sidebar-width` on the Sheet it renders instead of the
|
|
20
|
+
# panel. There is no second element here to override it on, so it is
|
|
21
|
+
# published as its own variable and the panel reaches for it directly.
|
|
22
|
+
WIDTH_MOBILE = "18rem"
|
|
23
|
+
|
|
24
|
+
slot_name :"sidebar-wrapper"
|
|
25
|
+
|
|
26
|
+
style do
|
|
27
|
+
base { "group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar" }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
attr_reader :open
|
|
31
|
+
|
|
32
|
+
# `open:` is what a Rails layout passes after reading the
|
|
33
|
+
# `sidebar_state` cookie, the way a Next.js layout passes `defaultOpen`.
|
|
34
|
+
# It defaults to open, as upstream's does.
|
|
35
|
+
def initialize(open: true, **attributes)
|
|
36
|
+
@open = open
|
|
37
|
+
super(**attributes)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def element_attributes(**defaults)
|
|
41
|
+
super(**{
|
|
42
|
+
style: merged_style(
|
|
43
|
+
"--sidebar-width: #{WIDTH}; --sidebar-width-icon: #{WIDTH_ICON}; " \
|
|
44
|
+
"--sidebar-width-mobile: #{WIDTH_MOBILE};"
|
|
45
|
+
),
|
|
46
|
+
"data-controller" => "shadcn--sidebar",
|
|
47
|
+
"data-shadcn--sidebar-open-value" => open
|
|
48
|
+
}.merge(defaults))
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|