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,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Sidebar
|
|
5
|
+
module Rail
|
|
6
|
+
# SidebarRail — the thin strip along the panel's edge that toggles it, and
|
|
7
|
+
# shows a resize cursor while doing so. `tabindex="-1"` is upstream's:
|
|
8
|
+
# the rail duplicates the trigger, so it is deliberately out of the tab
|
|
9
|
+
# order (vendor/shadcn/ui/sidebar.tsx:282-305).
|
|
10
|
+
class Component < ApplicationViewComponent
|
|
11
|
+
default_tag :button
|
|
12
|
+
slot_name :"sidebar-rail"
|
|
13
|
+
|
|
14
|
+
style do
|
|
15
|
+
base {
|
|
16
|
+
"absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear " \
|
|
17
|
+
"group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute " \
|
|
18
|
+
"after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex " \
|
|
19
|
+
"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize " \
|
|
20
|
+
"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize " \
|
|
21
|
+
"[[data-side=right][data-state=collapsed]_&]:cursor-w-resize " \
|
|
22
|
+
"group-data-[collapsible=offcanvas]:translate-x-0 " \
|
|
23
|
+
"group-data-[collapsible=offcanvas]:after:left-full " \
|
|
24
|
+
"hover:group-data-[collapsible=offcanvas]:bg-sidebar " \
|
|
25
|
+
"[[data-side=left][data-collapsible=offcanvas]_&]:-right-2 " \
|
|
26
|
+
"[[data-side=right][data-collapsible=offcanvas]_&]:-left-2"
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def element_attributes(**defaults)
|
|
31
|
+
super(**{
|
|
32
|
+
type: "button",
|
|
33
|
+
"data-sidebar" => "rail",
|
|
34
|
+
"aria-label" => shadcn_t("sidebar.toggle"),
|
|
35
|
+
"tabindex" => "-1",
|
|
36
|
+
title: shadcn_t("sidebar.toggle"),
|
|
37
|
+
"data-action" => "click->shadcn--sidebar#toggle"
|
|
38
|
+
}.merge(defaults))
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Sidebar
|
|
5
|
+
module Separator
|
|
6
|
+
# SidebarSeparator — the ported Separator, restamped and tinted to the
|
|
7
|
+
# sidebar's own border colour.
|
|
8
|
+
class Component < Shadcn::Separator::Component
|
|
9
|
+
slot_name :"sidebar-separator"
|
|
10
|
+
|
|
11
|
+
EXTRA_CLASSES = "mx-2 w-auto bg-sidebar-border"
|
|
12
|
+
|
|
13
|
+
def css_classes(extra = nil)
|
|
14
|
+
super([ EXTRA_CLASSES, extra ].compact.join(" "))
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def element_attributes(**defaults)
|
|
18
|
+
super(**{ "data-sidebar" => "separator" }.merge(defaults))
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Sidebar
|
|
5
|
+
module Trigger
|
|
6
|
+
# SidebarTrigger — upstream renders a ghost icon Button
|
|
7
|
+
# (vendor/shadcn/ui/sidebar.tsx:256-280), so this borrows the button's own
|
|
8
|
+
# compiled variants rather than restating them, as PaginationLink does.
|
|
9
|
+
class Component < ApplicationViewComponent
|
|
10
|
+
default_tag :button
|
|
11
|
+
slot_name :"sidebar-trigger"
|
|
12
|
+
|
|
13
|
+
def element_attributes(**defaults)
|
|
14
|
+
super(**{
|
|
15
|
+
type: "button",
|
|
16
|
+
"data-sidebar" => "trigger",
|
|
17
|
+
"data-shadcn--sidebar-target" => "trigger",
|
|
18
|
+
"data-action" => "click->shadcn--sidebar#toggle"
|
|
19
|
+
}.merge(defaults))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def css_classes(extra = nil)
|
|
23
|
+
Button::Component.variant_classes(variant: :ghost, size: :icon, class: [ "size-7", extra ].compact.join(" "))
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# The label is `sr-only` rather than an `aria-label`: upstream puts it in
|
|
27
|
+
# the button's content, and a visible-to-screen-readers span survives
|
|
28
|
+
# translation tooling that an attribute does not.
|
|
29
|
+
def call
|
|
30
|
+
render_element(body: safe_join([
|
|
31
|
+
render(Icon::Component.new("panel-left")),
|
|
32
|
+
tag.span(shadcn_t("sidebar.toggle"), class: "sr-only"),
|
|
33
|
+
content
|
|
34
|
+
].compact))
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
# The parts of the Sidebar family that are an element with its two attributes
|
|
5
|
+
# and a fixed set of classes. Anything with variants, slots or markup of its
|
|
6
|
+
# own keeps its own `component.rb`.
|
|
7
|
+
#
|
|
8
|
+
# This family needs a macro of its own because shadcn stamps a *second*
|
|
9
|
+
# attribute on every one of its 24 parts — `data-sidebar="header"` beside
|
|
10
|
+
# `data-slot="sidebar-header"` — and `part` declares a slot, classes and a tag
|
|
11
|
+
# and deliberately nothing else. Taken literally that meant 23 files of eleven
|
|
12
|
+
# lines each, which is precisely what `part` was written to remove.
|
|
13
|
+
#
|
|
14
|
+
# `sidebar_part` is not `part` widened to take attributes; that was considered
|
|
15
|
+
# and rejected in decisions/01-architecture.md, on the grounds that it turns a
|
|
16
|
+
# lookup table into a configuration language. It adds exactly one attribute and
|
|
17
|
+
# *derives* it: measured across the whole vendored source, `data-sidebar` is
|
|
18
|
+
# `data-slot` without its `sidebar-` prefix in 21 of 21 cases, no exceptions.
|
|
19
|
+
# A rule, not a parameter. If upstream ever breaks it, one file changes.
|
|
20
|
+
module Sidebar
|
|
21
|
+
extend Parts
|
|
22
|
+
|
|
23
|
+
# Declares a part and stamps the derived `data-sidebar` on it. Caller
|
|
24
|
+
# attributes still win, as they do everywhere else here.
|
|
25
|
+
def self.sidebar_part(name, slot:, **options)
|
|
26
|
+
marker = slot.to_s.delete_prefix("sidebar-")
|
|
27
|
+
|
|
28
|
+
part(name, slot:, **options).tap do |component|
|
|
29
|
+
component.define_method(:element_attributes) do |**defaults|
|
|
30
|
+
super(**{ "data-sidebar" => marker }.merge(defaults))
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
sidebar_part :header, slot: "sidebar-header", classes: "flex flex-col gap-2 p-2"
|
|
36
|
+
|
|
37
|
+
sidebar_part :footer, slot: "sidebar-footer", classes: "flex flex-col gap-2 p-2"
|
|
38
|
+
|
|
39
|
+
sidebar_part :content, slot: "sidebar-content",
|
|
40
|
+
classes: "flex min-h-0 flex-1 flex-col gap-2 overflow-auto " \
|
|
41
|
+
"group-data-[collapsible=icon]:overflow-hidden"
|
|
42
|
+
|
|
43
|
+
sidebar_part :group, slot: "sidebar-group",
|
|
44
|
+
classes: "relative flex w-full min-w-0 flex-col p-2"
|
|
45
|
+
|
|
46
|
+
sidebar_part :group_label, slot: "sidebar-group-label",
|
|
47
|
+
classes: "flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium " \
|
|
48
|
+
"text-sidebar-foreground/70 ring-sidebar-ring outline-hidden " \
|
|
49
|
+
"transition-[margin,opacity] duration-200 ease-linear " \
|
|
50
|
+
"focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0 " \
|
|
51
|
+
"group-data-[collapsible=icon]:-mt-8 " \
|
|
52
|
+
"group-data-[collapsible=icon]:opacity-0"
|
|
53
|
+
|
|
54
|
+
sidebar_part :group_action, slot: "sidebar-group-action", tag: :button,
|
|
55
|
+
classes: "absolute top-3.5 right-3 flex aspect-square w-5 items-center " \
|
|
56
|
+
"justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring " \
|
|
57
|
+
"outline-hidden transition-transform hover:bg-sidebar-accent " \
|
|
58
|
+
"hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 " \
|
|
59
|
+
"[&>svg]:shrink-0 after:absolute after:-inset-2 md:after:hidden " \
|
|
60
|
+
"group-data-[collapsible=icon]:hidden"
|
|
61
|
+
|
|
62
|
+
sidebar_part :group_content, slot: "sidebar-group-content",
|
|
63
|
+
classes: "w-full text-sm"
|
|
64
|
+
|
|
65
|
+
sidebar_part :menu, slot: "sidebar-menu", tag: :ul,
|
|
66
|
+
classes: "flex w-full min-w-0 flex-col gap-1"
|
|
67
|
+
|
|
68
|
+
sidebar_part :menu_item, slot: "sidebar-menu-item", tag: :li,
|
|
69
|
+
classes: "group/menu-item relative"
|
|
70
|
+
|
|
71
|
+
sidebar_part :menu_badge, slot: "sidebar-menu-badge",
|
|
72
|
+
classes: "pointer-events-none absolute right-1 flex h-5 min-w-5 items-center " \
|
|
73
|
+
"justify-center rounded-md px-1 text-xs font-medium " \
|
|
74
|
+
"text-sidebar-foreground tabular-nums select-none " \
|
|
75
|
+
"peer-hover/menu-button:text-sidebar-accent-foreground " \
|
|
76
|
+
"peer-data-[active=true]/menu-button:text-sidebar-accent-foreground " \
|
|
77
|
+
"peer-data-[size=sm]/menu-button:top-1 " \
|
|
78
|
+
"peer-data-[size=default]/menu-button:top-1.5 " \
|
|
79
|
+
"peer-data-[size=lg]/menu-button:top-2.5 " \
|
|
80
|
+
"group-data-[collapsible=icon]:hidden"
|
|
81
|
+
|
|
82
|
+
sidebar_part :menu_sub, slot: "sidebar-menu-sub", tag: :ul,
|
|
83
|
+
classes: "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l " \
|
|
84
|
+
"border-sidebar-border px-2.5 py-0.5 group-data-[collapsible=icon]:hidden"
|
|
85
|
+
|
|
86
|
+
sidebar_part :menu_sub_item, slot: "sidebar-menu-sub-item", tag: :li,
|
|
87
|
+
classes: "group/menu-sub-item relative"
|
|
88
|
+
|
|
89
|
+
# The one part upstream stamps with `data-slot` alone, so it takes the plain
|
|
90
|
+
# macro and must not gain a `data-sidebar`.
|
|
91
|
+
part :inset, slot: "sidebar-inset", tag: :main,
|
|
92
|
+
classes: "relative flex w-full flex-1 flex-col bg-background " \
|
|
93
|
+
"md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 " \
|
|
94
|
+
"md:peer-data-[variant=inset]:rounded-xl " \
|
|
95
|
+
"md:peer-data-[variant=inset]:shadow-sm " \
|
|
96
|
+
"md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2"
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Skeleton
|
|
5
|
+
# Port of registry/new-york-v4/ui/skeleton.tsx
|
|
6
|
+
class Component < ApplicationViewComponent
|
|
7
|
+
slot_name :skeleton
|
|
8
|
+
|
|
9
|
+
style do
|
|
10
|
+
base { "animate-pulse rounded-md bg-accent" }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<div class="flex items-center gap-4">
|
|
2
|
+
<%= render(Shadcn::Skeleton::Component.new(class: "size-12 rounded-full")) %>
|
|
3
|
+
<div class="flex flex-col gap-2">
|
|
4
|
+
<%= render(Shadcn::Skeleton::Component.new(class: "h-4 w-[250px]")) %>
|
|
5
|
+
<%= render(Shadcn::Skeleton::Component.new(class: "h-4 w-[200px]")) %>
|
|
6
|
+
</div>
|
|
7
|
+
</div>
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Slider
|
|
5
|
+
# Port of registry/new-york-v4/ui/slider.tsx, whose behaviour is Radix's
|
|
6
|
+
# `Slider` — 1,044 lines against shadcn's 63, vendored at
|
|
7
|
+
# `vendor/radix/ui/slider.tsx`.
|
|
8
|
+
#
|
|
9
|
+
# Composes the whole thing, as shadcn's own does: a track holding the filled
|
|
10
|
+
# range, and one thumb per value. Every position is computed here as well as
|
|
11
|
+
# in the controller, so the slider is in the right place before any
|
|
12
|
+
# JavaScript runs — the server knows the values, and a slider that starts at
|
|
13
|
+
# zero and jumps is worse than one that never moves.
|
|
14
|
+
class Component < ApplicationViewComponent
|
|
15
|
+
slot_name :slider
|
|
16
|
+
|
|
17
|
+
style do
|
|
18
|
+
base {
|
|
19
|
+
"relative flex w-full touch-none items-center select-none " \
|
|
20
|
+
"data-[disabled]:opacity-50 data-[orientation=vertical]:h-full " \
|
|
21
|
+
"data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto " \
|
|
22
|
+
"data-[orientation=vertical]:flex-col"
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
attr_reader :values, :min, :max, :step, :orientation, :disabled,
|
|
27
|
+
:min_steps_between_thumbs, :name, :aria_label
|
|
28
|
+
|
|
29
|
+
# `value:` takes a number or a list. Upstream's default when neither
|
|
30
|
+
# `value` nor `defaultValue` is given is `[min, max]` — two thumbs, which
|
|
31
|
+
# is surprising until you notice it is what makes the component's own
|
|
32
|
+
# example a range (slider.tsx:17-24).
|
|
33
|
+
def initialize(value: nil, min: 0, max: 100, step: 1, orientation: :horizontal,
|
|
34
|
+
disabled: false, min_steps_between_thumbs: 0, name: nil,
|
|
35
|
+
aria_label: nil, **attributes)
|
|
36
|
+
@min = min
|
|
37
|
+
@max = max
|
|
38
|
+
@step = step
|
|
39
|
+
@orientation = orientation&.to_sym || :horizontal
|
|
40
|
+
@disabled = disabled
|
|
41
|
+
@min_steps_between_thumbs = min_steps_between_thumbs
|
|
42
|
+
@name = name
|
|
43
|
+
@aria_label = aria_label
|
|
44
|
+
@values = Array(value.nil? ? [ min, max ] : value)
|
|
45
|
+
super(**attributes)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def element_attributes(**defaults)
|
|
49
|
+
super(**{
|
|
50
|
+
"data-orientation" => orientation,
|
|
51
|
+
"data-disabled" => (disabled.presence && ""),
|
|
52
|
+
"aria-disabled" => (disabled.presence && "true"),
|
|
53
|
+
"data-controller" => "shadcn--slider",
|
|
54
|
+
"data-shadcn--slider-min-value" => min,
|
|
55
|
+
"data-shadcn--slider-max-value" => max,
|
|
56
|
+
"data-shadcn--slider-step-value" => step,
|
|
57
|
+
"data-shadcn--slider-orientation-value" => orientation,
|
|
58
|
+
"data-shadcn--slider-disabled-value" => disabled,
|
|
59
|
+
"data-shadcn--slider-min-steps-value" => min_steps_between_thumbs,
|
|
60
|
+
"data-action" => "pointerdown->shadcn--slider#trackDown",
|
|
61
|
+
# The transform every thumb's wrapper reads. Radix publishes it on the
|
|
62
|
+
# root so one declaration serves every thumb and the axis is decided
|
|
63
|
+
# in one place.
|
|
64
|
+
style: merged_style(
|
|
65
|
+
"--radix-slider-thumb-transform: #{orientation == :vertical ? 'translateY(50%)' : 'translateX(-50%)'};"
|
|
66
|
+
)
|
|
67
|
+
}.compact.merge(defaults))
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def call
|
|
71
|
+
render_element(body: safe_join([ track, *thumbs, *inputs ]))
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def percent_of(value)
|
|
77
|
+
return 0 if max == min
|
|
78
|
+
|
|
79
|
+
((value.to_f - min) / (max - min) * 100).clamp(0, 100)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# A single-thumb slider fills from the start of the scale, not from its own
|
|
83
|
+
# value — otherwise the fill has zero width and there is nothing to see.
|
|
84
|
+
# Radix's rule: `valuesCount > 1 ? Math.min(...percentages) : 0`
|
|
85
|
+
# (slider.tsx:592).
|
|
86
|
+
def range_start
|
|
87
|
+
values.size > 1 ? percent_of(values.min) : 0
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def track
|
|
91
|
+
render(Shadcn::Slider::Track::Component.new(orientation:)) do
|
|
92
|
+
render(Shadcn::Slider::Range::Component.new(
|
|
93
|
+
orientation:,
|
|
94
|
+
start_percent: range_start,
|
|
95
|
+
end_percent: percent_of(values.max)
|
|
96
|
+
))
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# A bare wrapper carries the position so the thumb itself can keep a
|
|
101
|
+
# transition on colour alone. `calc(P% - 8px)` is the flat half of Radix's
|
|
102
|
+
# `getThumbInBoundsOffset` (slider.tsx:908): the exact version slides the
|
|
103
|
+
# correction from +half to −half across the track so the thumb stays
|
|
104
|
+
# inside at both ends, and the controller applies that once it knows the
|
|
105
|
+
# thumb's measured width.
|
|
106
|
+
def thumbs
|
|
107
|
+
values.each_with_index.map do |value, index|
|
|
108
|
+
tag.span(
|
|
109
|
+
render(Shadcn::Slider::Thumb::Component.new(
|
|
110
|
+
orientation:, value:, min:, max:, disabled:, index:,
|
|
111
|
+
"aria-label": label_for(index)
|
|
112
|
+
)),
|
|
113
|
+
style: "transform: var(--radix-slider-thumb-transform); position: absolute; " \
|
|
114
|
+
"#{orientation == :vertical ? 'bottom' : 'left'}: calc(#{percent_of(value)}% - 8px);",
|
|
115
|
+
"data-shadcn--slider-target": "wrapper"
|
|
116
|
+
)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# A thumb is a `role="slider"`, and a role does not take its name from the
|
|
121
|
+
# markup around it — the same trap Select, Checkbox and Switch fall into
|
|
122
|
+
# here, and axe fails the page without one. `aria_label:` takes a string
|
|
123
|
+
# or one per thumb, because a two-handled range is two controls and
|
|
124
|
+
# "Price" twice is not a name for either of them.
|
|
125
|
+
def label_for(index)
|
|
126
|
+
return nil if aria_label.blank?
|
|
127
|
+
|
|
128
|
+
aria_label.is_a?(Array) ? aria_label[index] : aria_label
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# What a Rails form actually submits. Radix renders these too — shadcn's
|
|
132
|
+
# file does not, because in React the value is state rather than markup.
|
|
133
|
+
def inputs
|
|
134
|
+
return [] if name.blank?
|
|
135
|
+
|
|
136
|
+
values.map do |value|
|
|
137
|
+
tag.input(
|
|
138
|
+
type: "hidden", name: values.size > 1 ? "#{name}[]" : name, value:,
|
|
139
|
+
"data-shadcn--slider-target": "input"
|
|
140
|
+
)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Slider
|
|
5
|
+
class Preview < ApplicationViewComponentPreview
|
|
6
|
+
def default
|
|
7
|
+
render_with_template
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Upstream's "Vertical".
|
|
11
|
+
def vertical
|
|
12
|
+
render_with_template
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<%# Three, because the component behaves differently in each.
|
|
2
|
+
|
|
3
|
+
One thumb is the ordinary case. Two is what upstream's own default gives
|
|
4
|
+
you when you pass no value at all — `[min, max]` — and is where
|
|
5
|
+
`min_steps_between_thumbs` and "which thumb does a press move" start to
|
|
6
|
+
mean something. The third is disabled, which is a state and not a variant:
|
|
7
|
+
the root carries `data-disabled` and the thumbs leave the tab order. %>
|
|
8
|
+
<div class="flex w-[420px] flex-col gap-8">
|
|
9
|
+
<%= render(Shadcn::Slider::Component.new(value: 50, name: "volume", aria_label: "Volume")) %>
|
|
10
|
+
|
|
11
|
+
<%= render(Shadcn::Slider::Component.new(
|
|
12
|
+
value: [ 25, 75 ], min_steps_between_thumbs: 1, name: "range",
|
|
13
|
+
aria_label: [ "Minimum price", "Maximum price" ]
|
|
14
|
+
)) %>
|
|
15
|
+
|
|
16
|
+
<%= render(Shadcn::Slider::Component.new(value: 30, disabled: true, aria_label: "Brightness")) %>
|
|
17
|
+
</div>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<%# Upstream's "Vertical". The orientation is the root's argument and the
|
|
2
|
+
thumbs' arrow keys follow it, so Up and Down move a vertical slider where
|
|
3
|
+
Left and Right move a horizontal one. %>
|
|
4
|
+
<div class="flex h-56 items-start gap-10">
|
|
5
|
+
<%= render(Shadcn::Slider::Component.new(value: 40, orientation: :vertical, class: "h-48", aria_label: "Volume")) %>
|
|
6
|
+
<%= render(Shadcn::Slider::Component.new(value: [ 20, 80 ], orientation: :vertical, class: "h-48", aria_label: [ "Lowest", "Highest" ])) %>
|
|
7
|
+
</div>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Slider
|
|
5
|
+
module Range
|
|
6
|
+
# The filled part of the groove, between the lowest and highest thumb.
|
|
7
|
+
# Two inline percentages rather than a width, which is Radix's own
|
|
8
|
+
# (measured: `left:25%;right:50%` for values 25 and 50) and is what makes
|
|
9
|
+
# a two-thumb range one element instead of two.
|
|
10
|
+
class Component < ApplicationViewComponent
|
|
11
|
+
slot_name :"slider-range"
|
|
12
|
+
|
|
13
|
+
style do
|
|
14
|
+
base {
|
|
15
|
+
"absolute bg-primary data-[orientation=horizontal]:h-full " \
|
|
16
|
+
"data-[orientation=vertical]:w-full"
|
|
17
|
+
}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
attr_reader :orientation, :start_percent, :end_percent
|
|
21
|
+
|
|
22
|
+
def initialize(orientation: :horizontal, start_percent: 0, end_percent: 100, **attributes)
|
|
23
|
+
@orientation = orientation
|
|
24
|
+
@start_percent = start_percent
|
|
25
|
+
@end_percent = end_percent
|
|
26
|
+
super(**attributes)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def element_attributes(**defaults)
|
|
30
|
+
super(**{
|
|
31
|
+
"data-orientation" => orientation,
|
|
32
|
+
"data-shadcn--slider-target" => "range",
|
|
33
|
+
style: merged_style(edges)
|
|
34
|
+
}.merge(defaults))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
# Vertical sliders fill from the bottom, so the pair of edges changes
|
|
40
|
+
# with the axis rather than the numbers doing.
|
|
41
|
+
def edges
|
|
42
|
+
if orientation.to_sym == :vertical
|
|
43
|
+
"bottom: #{start_percent}%; top: #{100 - end_percent}%;"
|
|
44
|
+
else
|
|
45
|
+
"left: #{start_percent}%; right: #{100 - end_percent}%;"
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Slider
|
|
5
|
+
module Thumb
|
|
6
|
+
# The handle, and the only focusable thing in the component: `role="slider"`
|
|
7
|
+
# with its own `aria-valuenow`, so a two-thumb range is two controls rather
|
|
8
|
+
# than one with two numbers.
|
|
9
|
+
#
|
|
10
|
+
# Positioning lives on a wrapper the root renders, not here — Radix does
|
|
11
|
+
# the same, and it is what lets the thumb keep `transition-[color,box-shadow]`
|
|
12
|
+
# without the position transitioning too.
|
|
13
|
+
class Component < ApplicationViewComponent
|
|
14
|
+
default_tag :span
|
|
15
|
+
slot_name :"slider-thumb"
|
|
16
|
+
|
|
17
|
+
style do
|
|
18
|
+
base {
|
|
19
|
+
"block size-4 shrink-0 rounded-full border border-primary bg-white " \
|
|
20
|
+
"shadow-sm ring-ring/50 transition-[color,box-shadow] hover:ring-4 " \
|
|
21
|
+
"focus-visible:ring-4 focus-visible:outline-hidden " \
|
|
22
|
+
"disabled:pointer-events-none disabled:opacity-50"
|
|
23
|
+
}
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
attr_reader :orientation, :value, :min, :max, :disabled, :index
|
|
27
|
+
|
|
28
|
+
def initialize(orientation: :horizontal, value: 0, min: 0, max: 100,
|
|
29
|
+
disabled: false, index: 0, **attributes)
|
|
30
|
+
@orientation = orientation
|
|
31
|
+
@value = value
|
|
32
|
+
@min = min
|
|
33
|
+
@max = max
|
|
34
|
+
@disabled = disabled
|
|
35
|
+
@index = index
|
|
36
|
+
super(**attributes)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def element_attributes(**defaults)
|
|
40
|
+
super(**{
|
|
41
|
+
role: "slider",
|
|
42
|
+
tabindex: disabled ? -1 : 0,
|
|
43
|
+
"aria-valuemin" => min,
|
|
44
|
+
"aria-valuemax" => max,
|
|
45
|
+
"aria-valuenow" => value,
|
|
46
|
+
"aria-orientation" => orientation,
|
|
47
|
+
"aria-disabled" => (disabled.presence && "true"),
|
|
48
|
+
"data-orientation" => orientation,
|
|
49
|
+
"data-index" => index,
|
|
50
|
+
"data-shadcn--slider-target" => "thumb",
|
|
51
|
+
"data-action" => "keydown->shadcn--slider#keydown " \
|
|
52
|
+
"pointerdown->shadcn--slider#thumbDown"
|
|
53
|
+
}.compact.merge(defaults))
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Slider
|
|
5
|
+
module Track
|
|
6
|
+
# The groove. Its own file only for `data-orientation`, which every part
|
|
7
|
+
# of this family carries and which `part` does not do.
|
|
8
|
+
class Component < ApplicationViewComponent
|
|
9
|
+
slot_name :"slider-track"
|
|
10
|
+
|
|
11
|
+
style do
|
|
12
|
+
base {
|
|
13
|
+
"relative grow overflow-hidden rounded-full bg-muted " \
|
|
14
|
+
"data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full " \
|
|
15
|
+
"data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5"
|
|
16
|
+
}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
attr_reader :orientation
|
|
20
|
+
|
|
21
|
+
def initialize(orientation: :horizontal, **attributes)
|
|
22
|
+
@orientation = orientation
|
|
23
|
+
super(**attributes)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def element_attributes(**defaults)
|
|
27
|
+
super(**{ "data-orientation" => orientation }.merge(defaults))
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Shadcn
|
|
4
|
+
module Spinner
|
|
5
|
+
# Port of registry/new-york-v4/ui/spinner.tsx — the lucide Loader2 icon
|
|
6
|
+
# with a status role.
|
|
7
|
+
class Component < Icon::Component
|
|
8
|
+
def initialize(**attributes)
|
|
9
|
+
super("loader-2", **attributes)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def element_attributes(**defaults)
|
|
13
|
+
super(**{ role: "status", "aria-label" => shadcn_t("spinner.loading") }.merge(defaults))
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def css_classes(extra = nil)
|
|
17
|
+
super(ShadcnViewComponent.cn("size-4 animate-spin", extra))
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<div class="flex items-center gap-4">
|
|
2
|
+
<%= render(Shadcn::Spinner::Component.new) %>
|
|
3
|
+
<%= render(Shadcn::Spinner::Component.new(class: "size-8")) %>
|
|
4
|
+
<%= render(Shadcn::Button::Component.new(disabled: true)) do %>
|
|
5
|
+
<%= render(Shadcn::Spinner::Component.new) %> Loading
|
|
6
|
+
<% end %>
|
|
7
|
+
</div>
|