velvetkit 0.1.0.beta
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 +16 -0
- data/LICENSE.txt +21 -0
- data/README.md +197 -0
- data/lib/generators/velvetkit/add/add_generator.rb +111 -0
- data/lib/generators/velvetkit/ai/ai_generator.rb +78 -0
- data/lib/generators/velvetkit/helpers.rb +64 -0
- data/lib/generators/velvetkit/install/install_generator.rb +108 -0
- data/lib/velvetkit/namespace.rb +57 -0
- data/lib/velvetkit/reference.rb +108 -0
- data/lib/velvetkit/registry.rb +162 -0
- data/lib/velvetkit/version.rb +5 -0
- data/lib/velvetkit.rb +28 -0
- data/registry/app/assets/tailwind/velvetkit.css +342 -0
- data/registry/app/components/ui/accordion/content.html.erb +5 -0
- data/registry/app/components/ui/accordion/content.rb +34 -0
- data/registry/app/components/ui/accordion/item.html.erb +1 -0
- data/registry/app/components/ui/accordion/item.rb +40 -0
- data/registry/app/components/ui/accordion/trigger.html.erb +1 -0
- data/registry/app/components/ui/accordion/trigger.rb +37 -0
- data/registry/app/components/ui/accordion.html.erb +7 -0
- data/registry/app/components/ui/accordion.rb +34 -0
- data/registry/app/components/ui/alert/description.html.erb +1 -0
- data/registry/app/components/ui/alert/description.rb +12 -0
- data/registry/app/components/ui/alert/title.html.erb +1 -0
- data/registry/app/components/ui/alert/title.rb +12 -0
- data/registry/app/components/ui/alert.html.erb +16 -0
- data/registry/app/components/ui/alert.rb +55 -0
- data/registry/app/components/ui/avatar/fallback.html.erb +1 -0
- data/registry/app/components/ui/avatar/fallback.rb +12 -0
- data/registry/app/components/ui/avatar/image.rb +20 -0
- data/registry/app/components/ui/avatar.html.erb +1 -0
- data/registry/app/components/ui/avatar.rb +56 -0
- data/registry/app/components/ui/avatar_group.html.erb +1 -0
- data/registry/app/components/ui/avatar_group.rb +35 -0
- data/registry/app/components/ui/badge.html.erb +1 -0
- data/registry/app/components/ui/badge.rb +38 -0
- data/registry/app/components/ui/banner.html.erb +10 -0
- data/registry/app/components/ui/banner.rb +47 -0
- data/registry/app/components/ui/base.rb +53 -0
- data/registry/app/components/ui/breadcrumb/auto_ellipsis.html.erb +23 -0
- data/registry/app/components/ui/breadcrumb/auto_ellipsis.rb +12 -0
- data/registry/app/components/ui/breadcrumb/ellipsis.html.erb +18 -0
- data/registry/app/components/ui/breadcrumb/ellipsis.rb +8 -0
- data/registry/app/components/ui/breadcrumb/item.html.erb +1 -0
- data/registry/app/components/ui/breadcrumb/item.rb +12 -0
- data/registry/app/components/ui/breadcrumb/item_slot.html.erb +10 -0
- data/registry/app/components/ui/breadcrumb/item_slot.rb +47 -0
- data/registry/app/components/ui/breadcrumb/list.html.erb +1 -0
- data/registry/app/components/ui/breadcrumb/list.rb +12 -0
- data/registry/app/components/ui/breadcrumb/separator.html.erb +1 -0
- data/registry/app/components/ui/breadcrumb/separator.rb +12 -0
- data/registry/app/components/ui/breadcrumb.html.erb +30 -0
- data/registry/app/components/ui/breadcrumb.rb +83 -0
- data/registry/app/components/ui/button.html.erb +1 -0
- data/registry/app/components/ui/button.rb +81 -0
- data/registry/app/components/ui/button_to.html.erb +1 -0
- data/registry/app/components/ui/button_to.rb +33 -0
- data/registry/app/components/ui/card/content.html.erb +1 -0
- data/registry/app/components/ui/card/content.rb +12 -0
- data/registry/app/components/ui/card/description.html.erb +1 -0
- data/registry/app/components/ui/card/description.rb +12 -0
- data/registry/app/components/ui/card/footer.html.erb +1 -0
- data/registry/app/components/ui/card/footer.rb +12 -0
- data/registry/app/components/ui/card/header.html.erb +1 -0
- data/registry/app/components/ui/card/header.rb +15 -0
- data/registry/app/components/ui/card/title.html.erb +1 -0
- data/registry/app/components/ui/card/title.rb +12 -0
- data/registry/app/components/ui/card.html.erb +1 -0
- data/registry/app/components/ui/card.rb +18 -0
- data/registry/app/components/ui/checkbox.html.erb +18 -0
- data/registry/app/components/ui/checkbox.rb +133 -0
- data/registry/app/components/ui/data_grid.html.erb +2 -0
- data/registry/app/components/ui/data_grid.rb +84 -0
- data/registry/app/components/ui/date_picker.html.erb +70 -0
- data/registry/app/components/ui/date_picker.rb +111 -0
- data/registry/app/components/ui/dialog/close.html.erb +7 -0
- data/registry/app/components/ui/dialog/close.rb +53 -0
- data/registry/app/components/ui/dialog/content.html.erb +26 -0
- data/registry/app/components/ui/dialog/content.rb +102 -0
- data/registry/app/components/ui/dialog/description.html.erb +1 -0
- data/registry/app/components/ui/dialog/description.rb +16 -0
- data/registry/app/components/ui/dialog/footer.html.erb +1 -0
- data/registry/app/components/ui/dialog/footer.rb +14 -0
- data/registry/app/components/ui/dialog/header.html.erb +1 -0
- data/registry/app/components/ui/dialog/header.rb +16 -0
- data/registry/app/components/ui/dialog/title.html.erb +1 -0
- data/registry/app/components/ui/dialog/title.rb +16 -0
- data/registry/app/components/ui/dialog/trigger.html.erb +5 -0
- data/registry/app/components/ui/dialog/trigger.rb +75 -0
- data/registry/app/components/ui/dialog.html.erb +3 -0
- data/registry/app/components/ui/dialog.rb +41 -0
- data/registry/app/components/ui/divider.html.erb +9 -0
- data/registry/app/components/ui/divider.rb +41 -0
- data/registry/app/components/ui/icon.html.erb +1 -0
- data/registry/app/components/ui/icon.rb +41 -0
- data/registry/app/components/ui/image.html.erb +1 -0
- data/registry/app/components/ui/image.rb +74 -0
- data/registry/app/components/ui/input.html.erb +9 -0
- data/registry/app/components/ui/input.rb +127 -0
- data/registry/app/components/ui/input_group/addon.html.erb +6 -0
- data/registry/app/components/ui/input_group/addon.rb +51 -0
- data/registry/app/components/ui/input_group/field.rb +26 -0
- data/registry/app/components/ui/input_group.html.erb +5 -0
- data/registry/app/components/ui/input_group.rb +55 -0
- data/registry/app/components/ui/label.html.erb +2 -0
- data/registry/app/components/ui/label.rb +48 -0
- data/registry/app/components/ui/link.html.erb +1 -0
- data/registry/app/components/ui/link.rb +64 -0
- data/registry/app/components/ui/menu/content.html.erb +5 -0
- data/registry/app/components/ui/menu/content.rb +106 -0
- data/registry/app/components/ui/menu/group.html.erb +1 -0
- data/registry/app/components/ui/menu/group.rb +19 -0
- data/registry/app/components/ui/menu/item.html.erb +1 -0
- data/registry/app/components/ui/menu/item.rb +68 -0
- data/registry/app/components/ui/menu/label.html.erb +1 -0
- data/registry/app/components/ui/menu/label.rb +33 -0
- data/registry/app/components/ui/menu/separator.html.erb +1 -0
- data/registry/app/components/ui/menu/separator.rb +20 -0
- data/registry/app/components/ui/menu/trigger.html.erb +1 -0
- data/registry/app/components/ui/menu/trigger.rb +29 -0
- data/registry/app/components/ui/menu.html.erb +3 -0
- data/registry/app/components/ui/menu.rb +23 -0
- data/registry/app/components/ui/native_select.html.erb +16 -0
- data/registry/app/components/ui/native_select.rb +109 -0
- data/registry/app/components/ui/pagination.html.erb +34 -0
- data/registry/app/components/ui/pagination.rb +62 -0
- data/registry/app/components/ui/password_input.html.erb +20 -0
- data/registry/app/components/ui/password_input.rb +94 -0
- data/registry/app/components/ui/popover/content.html.erb +12 -0
- data/registry/app/components/ui/popover/content.rb +83 -0
- data/registry/app/components/ui/popover/trigger.html.erb +1 -0
- data/registry/app/components/ui/popover/trigger.rb +29 -0
- data/registry/app/components/ui/popover.html.erb +3 -0
- data/registry/app/components/ui/popover.rb +24 -0
- data/registry/app/components/ui/radio_group/item.html.erb +18 -0
- data/registry/app/components/ui/radio_group/item.rb +97 -0
- data/registry/app/components/ui/radio_group.html.erb +1 -0
- data/registry/app/components/ui/radio_group.rb +35 -0
- data/registry/app/components/ui/select.html.erb +60 -0
- data/registry/app/components/ui/select.rb +181 -0
- data/registry/app/components/ui/sheet/close.rb +4 -0
- data/registry/app/components/ui/sheet/content.html.erb +24 -0
- data/registry/app/components/ui/sheet/content.rb +97 -0
- data/registry/app/components/ui/sheet/trigger.rb +4 -0
- data/registry/app/components/ui/sheet.html.erb +3 -0
- data/registry/app/components/ui/sheet.rb +37 -0
- data/registry/app/components/ui/sidebar/content.html.erb +1 -0
- data/registry/app/components/ui/sidebar/content.rb +18 -0
- data/registry/app/components/ui/sidebar/footer.html.erb +3 -0
- data/registry/app/components/ui/sidebar/footer.rb +16 -0
- data/registry/app/components/ui/sidebar/group.html.erb +1 -0
- data/registry/app/components/ui/sidebar/group.rb +19 -0
- data/registry/app/components/ui/sidebar/group_label.html.erb +1 -0
- data/registry/app/components/ui/sidebar/group_label.rb +18 -0
- data/registry/app/components/ui/sidebar/header.html.erb +1 -0
- data/registry/app/components/ui/sidebar/header.rb +16 -0
- data/registry/app/components/ui/sidebar/inset.html.erb +1 -0
- data/registry/app/components/ui/sidebar/inset.rb +17 -0
- data/registry/app/components/ui/sidebar/menu.html.erb +1 -0
- data/registry/app/components/ui/sidebar/menu.rb +18 -0
- data/registry/app/components/ui/sidebar/menu_button.html.erb +1 -0
- data/registry/app/components/ui/sidebar/menu_button.rb +30 -0
- data/registry/app/components/ui/sidebar/menu_item.html.erb +1 -0
- data/registry/app/components/ui/sidebar/menu_item.rb +23 -0
- data/registry/app/components/ui/sidebar/trigger.html.erb +1 -0
- data/registry/app/components/ui/sidebar/trigger.rb +24 -0
- data/registry/app/components/ui/sidebar/wrapper.html.erb +1 -0
- data/registry/app/components/ui/sidebar/wrapper.rb +40 -0
- data/registry/app/components/ui/sidebar.html.erb +11 -0
- data/registry/app/components/ui/sidebar.rb +29 -0
- data/registry/app/components/ui/spinner.html.erb +1 -0
- data/registry/app/components/ui/spinner.rb +20 -0
- data/registry/app/components/ui/switch.html.erb +12 -0
- data/registry/app/components/ui/switch.rb +109 -0
- data/registry/app/components/ui/table/cell.html.erb +1 -0
- data/registry/app/components/ui/table/cell.rb +16 -0
- data/registry/app/components/ui/table/column.html.erb +1 -0
- data/registry/app/components/ui/table/column.rb +18 -0
- data/registry/app/components/ui/table/head.html.erb +1 -0
- data/registry/app/components/ui/table/head.rb +13 -0
- data/registry/app/components/ui/table/row.html.erb +1 -0
- data/registry/app/components/ui/table/row.rb +26 -0
- data/registry/app/components/ui/table.html.erb +4 -0
- data/registry/app/components/ui/table.rb +45 -0
- data/registry/app/components/ui/tabs/content.html.erb +1 -0
- data/registry/app/components/ui/tabs/content.rb +43 -0
- data/registry/app/components/ui/tabs/list.html.erb +1 -0
- data/registry/app/components/ui/tabs/list.rb +28 -0
- data/registry/app/components/ui/tabs/trigger.html.erb +1 -0
- data/registry/app/components/ui/tabs/trigger.rb +91 -0
- data/registry/app/components/ui/tabs.html.erb +3 -0
- data/registry/app/components/ui/tabs.rb +27 -0
- data/registry/app/components/ui/text.html.erb +1 -0
- data/registry/app/components/ui/text.rb +48 -0
- data/registry/app/components/ui/theme_toggle.html.erb +9 -0
- data/registry/app/components/ui/theme_toggle.rb +63 -0
- data/registry/app/components/ui/tooltip/content.html.erb +1 -0
- data/registry/app/components/ui/tooltip/content.rb +65 -0
- data/registry/app/components/ui/tooltip/trigger.html.erb +1 -0
- data/registry/app/components/ui/tooltip/trigger.rb +33 -0
- data/registry/app/components/ui/tooltip.html.erb +3 -0
- data/registry/app/components/ui/tooltip.rb +24 -0
- data/registry/app/components/ui/typography/blockquote.html.erb +1 -0
- data/registry/app/components/ui/typography/blockquote.rb +15 -0
- data/registry/app/components/ui/typography/code.html.erb +1 -0
- data/registry/app/components/ui/typography/code.rb +25 -0
- data/registry/app/components/ui/typography/h1.rb +7 -0
- data/registry/app/components/ui/typography/h2.rb +7 -0
- data/registry/app/components/ui/typography/h3.rb +7 -0
- data/registry/app/components/ui/typography/h4.rb +7 -0
- data/registry/app/components/ui/typography/large.rb +7 -0
- data/registry/app/components/ui/typography/lead.rb +7 -0
- data/registry/app/components/ui/typography/muted.rb +7 -0
- data/registry/app/components/ui/typography/small.rb +7 -0
- data/registry/app/javascript/ag_grid.ts +26 -0
- data/registry/app/javascript/cally.ts +8 -0
- data/registry/app/javascript/controllers/ui/_internal/use_dismiss.ts +88 -0
- data/registry/app/javascript/controllers/ui/_internal/use_floating.ts +112 -0
- data/registry/app/javascript/controllers/ui/accordion_controller.ts +100 -0
- data/registry/app/javascript/controllers/ui/alert_controller.ts +7 -0
- data/registry/app/javascript/controllers/ui/banner_controller.ts +7 -0
- data/registry/app/javascript/controllers/ui/data_grid_controller.ts +198 -0
- data/registry/app/javascript/controllers/ui/date_picker_controller.ts +141 -0
- data/registry/app/javascript/controllers/ui/dialog_controller.ts +70 -0
- data/registry/app/javascript/controllers/ui/menu_controller.ts +201 -0
- data/registry/app/javascript/controllers/ui/password_visibility_controller.ts +43 -0
- data/registry/app/javascript/controllers/ui/popover_controller.ts +108 -0
- data/registry/app/javascript/controllers/ui/select_controller.ts +274 -0
- data/registry/app/javascript/controllers/ui/sidebar_controller.ts +64 -0
- data/registry/app/javascript/controllers/ui/tabs_controller.ts +74 -0
- data/registry/app/javascript/controllers/ui/theme_controller.ts +101 -0
- data/registry/app/javascript/controllers/ui/tooltip_controller.ts +102 -0
- data/registry/app/javascript/velvetkit_icons.ts +58 -0
- data/registry/app/views/layouts/_theme_script.html.erb +19 -0
- data/registry/components.yml +102 -0
- data/registry/config/locales/velvetkit.en.yml +56 -0
- data/registry/docs/agents.md +62 -0
- data/registry/test/components/previews/ui/accordion_preview/faq_style.html.erb +20 -0
- data/registry/test/components/previews/ui/accordion_preview/multiple.html.erb +27 -0
- data/registry/test/components/previews/ui/accordion_preview/single.html.erb +22 -0
- data/registry/test/components/previews/ui/accordion_preview.rb +31 -0
- data/registry/test/components/previews/ui/alert_preview/title_only.html.erb +12 -0
- data/registry/test/components/previews/ui/alert_preview/variants.html.erb +22 -0
- data/registry/test/components/previews/ui/alert_preview/with_icon.html.erb +12 -0
- data/registry/test/components/previews/ui/alert_preview/with_link.html.erb +18 -0
- data/registry/test/components/previews/ui/alert_preview.rb +34 -0
- data/registry/test/components/previews/ui/avatar_group_preview/default.html.erb +11 -0
- data/registry/test/components/previews/ui/avatar_group_preview/overflow.html.erb +23 -0
- data/registry/test/components/previews/ui/avatar_group_preview/small.html.erb +12 -0
- data/registry/test/components/previews/ui/avatar_group_preview.rb +23 -0
- data/registry/test/components/previews/ui/avatar_preview/colors.html.erb +8 -0
- data/registry/test/components/previews/ui/avatar_preview/shapes.html.erb +10 -0
- data/registry/test/components/previews/ui/avatar_preview/sizes.html.erb +8 -0
- data/registry/test/components/previews/ui/avatar_preview/with_image.html.erb +10 -0
- data/registry/test/components/previews/ui/avatar_preview.rb +24 -0
- data/registry/test/components/previews/ui/badge_preview/sizes.html.erb +5 -0
- data/registry/test/components/previews/ui/badge_preview/variants.html.erb +8 -0
- data/registry/test/components/previews/ui/badge_preview/with_icon.html.erb +14 -0
- data/registry/test/components/previews/ui/badge_preview.rb +20 -0
- data/registry/test/components/previews/ui/banner_preview/introduction.html.erb +9 -0
- data/registry/test/components/previews/ui/banner_preview/promotion.html.erb +9 -0
- data/registry/test/components/previews/ui/banner_preview/with_illustration.html.erb +12 -0
- data/registry/test/components/previews/ui/banner_preview.rb +25 -0
- data/registry/test/components/previews/ui/breadcrumb_preview/collapsed.html.erb +50 -0
- data/registry/test/components/previews/ui/breadcrumb_preview/default.html.erb +8 -0
- data/registry/test/components/previews/ui/breadcrumb_preview/long_path.html.erb +8 -0
- data/registry/test/components/previews/ui/breadcrumb_preview/medium.html.erb +7 -0
- data/registry/test/components/previews/ui/breadcrumb_preview/with_avatar.html.erb +8 -0
- data/registry/test/components/previews/ui/breadcrumb_preview.rb +66 -0
- data/registry/test/components/previews/ui/button_preview/disabled.html.erb +39 -0
- data/registry/test/components/previews/ui/button_preview/icon_only.html.erb +17 -0
- data/registry/test/components/previews/ui/button_preview/loading.html.erb +12 -0
- data/registry/test/components/previews/ui/button_preview/sizes.html.erb +6 -0
- data/registry/test/components/previews/ui/button_preview/variants.html.erb +8 -0
- data/registry/test/components/previews/ui/button_preview/with_both_icons.html.erb +12 -0
- data/registry/test/components/previews/ui/button_preview/with_leading_icon.html.erb +22 -0
- data/registry/test/components/previews/ui/button_preview/with_trailing_icon.html.erb +14 -0
- data/registry/test/components/previews/ui/button_preview.rb +65 -0
- data/registry/test/components/previews/ui/button_to_preview/states.html.erb +8 -0
- data/registry/test/components/previews/ui/button_to_preview/variants.html.erb +5 -0
- data/registry/test/components/previews/ui/button_to_preview/with_icon.html.erb +11 -0
- data/registry/test/components/previews/ui/button_to_preview.rb +21 -0
- data/registry/test/components/previews/ui/card_preview/complete.html.erb +31 -0
- data/registry/test/components/previews/ui/card_preview/default.html.erb +7 -0
- data/registry/test/components/previews/ui/card_preview/settings_form.html.erb +25 -0
- data/registry/test/components/previews/ui/card_preview/with_footer.html.erb +13 -0
- data/registry/test/components/previews/ui/card_preview/with_header.html.erb +11 -0
- data/registry/test/components/previews/ui/card_preview.rb +44 -0
- data/registry/test/components/previews/ui/checkbox_preview/in_form.html.erb +9 -0
- data/registry/test/components/previews/ui/checkbox_preview/states.html.erb +22 -0
- data/registry/test/components/previews/ui/checkbox_preview/with_label.html.erb +5 -0
- data/registry/test/components/previews/ui/checkbox_preview.rb +27 -0
- data/registry/test/components/previews/ui/data_grid_preview.rb +18 -0
- data/registry/test/components/previews/ui/date_picker_preview/default.html.erb +3 -0
- data/registry/test/components/previews/ui/date_picker_preview/states.html.erb +7 -0
- data/registry/test/components/previews/ui/date_picker_preview.rb +13 -0
- data/registry/test/components/previews/ui/dialog_preview/confirmation.html.erb +11 -0
- data/registry/test/components/previews/ui/dialog_preview/custom_trigger.html.erb +16 -0
- data/registry/test/components/previews/ui/dialog_preview/default.html.erb +15 -0
- data/registry/test/components/previews/ui/dialog_preview/long_content.html.erb +16 -0
- data/registry/test/components/previews/ui/dialog_preview/playground.html.erb +12 -0
- data/registry/test/components/previews/ui/dialog_preview/scrollable_body.html.erb +29 -0
- data/registry/test/components/previews/ui/dialog_preview/sizes.html.erb +46 -0
- data/registry/test/components/previews/ui/dialog_preview/without_close_button.html.erb +11 -0
- data/registry/test/components/previews/ui/dialog_preview/without_title.html.erb +13 -0
- data/registry/test/components/previews/ui/dialog_preview.rb +38 -0
- data/registry/test/components/previews/ui/divider_preview/horizontal.html.erb +5 -0
- data/registry/test/components/previews/ui/divider_preview/vertical.html.erb +9 -0
- data/registry/test/components/previews/ui/divider_preview/with_label.html.erb +5 -0
- data/registry/test/components/previews/ui/divider_preview.rb +19 -0
- data/registry/test/components/previews/ui/icon_preview/common.html.erb +8 -0
- data/registry/test/components/previews/ui/icon_preview/sizes.html.erb +7 -0
- data/registry/test/components/previews/ui/icon_preview.rb +20 -0
- data/registry/test/components/previews/ui/image_preview/radii.html.erb +8 -0
- data/registry/test/components/previews/ui/image_preview/sizing.html.erb +9 -0
- data/registry/test/components/previews/ui/image_preview.rb +16 -0
- data/registry/test/components/previews/ui/input_group_preview/addons.html.erb +29 -0
- data/registry/test/components/previews/ui/input_group_preview/playground.html.erb +12 -0
- data/registry/test/components/previews/ui/input_group_preview.rb +17 -0
- data/registry/test/components/previews/ui/input_preview/sizes.html.erb +5 -0
- data/registry/test/components/previews/ui/input_preview/states.html.erb +7 -0
- data/registry/test/components/previews/ui/input_preview/with_labels.html.erb +10 -0
- data/registry/test/components/previews/ui/input_preview.rb +33 -0
- data/registry/test/components/previews/ui/label_preview/sizes.html.erb +6 -0
- data/registry/test/components/previews/ui/label_preview/states.html.erb +6 -0
- data/registry/test/components/previews/ui/label_preview/weights.html.erb +5 -0
- data/registry/test/components/previews/ui/label_preview.rb +22 -0
- data/registry/test/components/previews/ui/link_preview/sizes.html.erb +5 -0
- data/registry/test/components/previews/ui/link_preview/variants.html.erb +8 -0
- data/registry/test/components/previews/ui/link_preview/with_icons.html.erb +11 -0
- data/registry/test/components/previews/ui/link_preview.rb +20 -0
- data/registry/test/components/previews/ui/menu_preview/positions.html.erb +122 -0
- data/registry/test/components/previews/ui/menu_preview/variants.html.erb +218 -0
- data/registry/test/components/previews/ui/menu_preview.rb +26 -0
- data/registry/test/components/previews/ui/native_select_preview/sizes.html.erb +6 -0
- data/registry/test/components/previews/ui/native_select_preview/states.html.erb +6 -0
- data/registry/test/components/previews/ui/native_select_preview.rb +23 -0
- data/registry/test/components/previews/ui/pagination_preview/states.html.erb +15 -0
- data/registry/test/components/previews/ui/pagination_preview.rb +15 -0
- data/registry/test/components/previews/ui/password_input_preview/states.html.erb +19 -0
- data/registry/test/components/previews/ui/password_input_preview.rb +21 -0
- data/registry/test/components/previews/ui/popover_preview/default.html.erb +7 -0
- data/registry/test/components/previews/ui/popover_preview/positions.html.erb +30 -0
- data/registry/test/components/previews/ui/popover_preview/with_close_button.html.erb +8 -0
- data/registry/test/components/previews/ui/popover_preview/with_rich_content.html.erb +17 -0
- data/registry/test/components/previews/ui/popover_preview/without_title.html.erb +9 -0
- data/registry/test/components/previews/ui/popover_preview.rb +32 -0
- data/registry/test/components/previews/ui/radio_group_preview/default.html.erb +10 -0
- data/registry/test/components/previews/ui/radio_group_preview/disabled.html.erb +17 -0
- data/registry/test/components/previews/ui/radio_group_preview/with_required.html.erb +10 -0
- data/registry/test/components/previews/ui/radio_group_preview.rb +25 -0
- data/registry/test/components/previews/ui/select_preview/default.html.erb +4 -0
- data/registry/test/components/previews/ui/select_preview/long_list.html.erb +5 -0
- data/registry/test/components/previews/ui/select_preview/multiple.html.erb +6 -0
- data/registry/test/components/previews/ui/select_preview/sizes.html.erb +5 -0
- data/registry/test/components/previews/ui/select_preview/states.html.erb +6 -0
- data/registry/test/components/previews/ui/select_preview.rb +45 -0
- data/registry/test/components/previews/ui/sheet_preview/bottom.html.erb +12 -0
- data/registry/test/components/previews/ui/sheet_preview/left.html.erb +10 -0
- data/registry/test/components/previews/ui/sheet_preview/playground.html.erb +15 -0
- data/registry/test/components/previews/ui/sheet_preview/right.html.erb +11 -0
- data/registry/test/components/previews/ui/sheet_preview/top.html.erb +8 -0
- data/registry/test/components/previews/ui/sheet_preview.rb +22 -0
- data/registry/test/components/previews/ui/sidebar_preview/_brand.html.erb +14 -0
- data/registry/test/components/previews/ui/sidebar_preview/_shell.html.erb +60 -0
- data/registry/test/components/previews/ui/sidebar_preview/collapsible.html.erb +55 -0
- data/registry/test/components/previews/ui/sidebar_preview/default.html.erb +17 -0
- data/registry/test/components/previews/ui/sidebar_preview/with_dropdown_header.html.erb +33 -0
- data/registry/test/components/previews/ui/sidebar_preview/with_groups.html.erb +22 -0
- data/registry/test/components/previews/ui/sidebar_preview.rb +15 -0
- data/registry/test/components/previews/ui/spinner_preview/in_buttons.html.erb +7 -0
- data/registry/test/components/previews/ui/spinner_preview/sizes.html.erb +7 -0
- data/registry/test/components/previews/ui/spinner_preview.rb +19 -0
- data/registry/test/components/previews/ui/switch_preview/default.html.erb +4 -0
- data/registry/test/components/previews/ui/switch_preview/sizes.html.erb +5 -0
- data/registry/test/components/previews/ui/switch_preview/states.html.erb +7 -0
- data/registry/test/components/previews/ui/switch_preview.rb +26 -0
- data/registry/test/components/previews/ui/table_preview/customers.html.erb +15 -0
- data/registry/test/components/previews/ui/table_preview/empty.html.erb +8 -0
- data/registry/test/components/previews/ui/table_preview/with_caption.html.erb +14 -0
- data/registry/test/components/previews/ui/table_preview.rb +12 -0
- data/registry/test/components/previews/ui/tabs_preview/default.html.erb +39 -0
- data/registry/test/components/previews/ui/tabs_preview/pill_variant.html.erb +18 -0
- data/registry/test/components/previews/ui/tabs_preview/settings_form.html.erb +42 -0
- data/registry/test/components/previews/ui/tabs_preview/with_icons.html.erb +34 -0
- data/registry/test/components/previews/ui/tabs_preview.rb +33 -0
- data/registry/test/components/previews/ui/text_preview/sizes.html.erb +10 -0
- data/registry/test/components/previews/ui/text_preview/tones.html.erb +5 -0
- data/registry/test/components/previews/ui/text_preview/weights.html.erb +6 -0
- data/registry/test/components/previews/ui/text_preview.rb +26 -0
- data/registry/test/components/previews/ui/theme_toggle_preview/in_a_header.html.erb +14 -0
- data/registry/test/components/previews/ui/theme_toggle_preview/palette.html.erb +47 -0
- data/registry/test/components/previews/ui/theme_toggle_preview.rb +15 -0
- data/registry/test/components/previews/ui/tooltip_preview/default.html.erb +8 -0
- data/registry/test/components/previews/ui/tooltip_preview/positions.html.erb +34 -0
- data/registry/test/components/previews/ui/tooltip_preview/with_button.html.erb +8 -0
- data/registry/test/components/previews/ui/tooltip_preview/with_icon.html.erb +10 -0
- data/registry/test/components/previews/ui/tooltip_preview.rb +29 -0
- data/registry/test/components/previews/ui/typography_preview/article.html.erb +11 -0
- data/registry/test/components/previews/ui/typography_preview/code_and_quotes.html.erb +6 -0
- data/registry/test/components/previews/ui/typography_preview/headings.html.erb +6 -0
- data/registry/test/components/previews/ui/typography_preview/text_styles.html.erb +7 -0
- data/registry/test/components/previews/ui/typography_preview.rb +23 -0
- data/registry/test/components/ui/accordion/content_test.rb +64 -0
- data/registry/test/components/ui/accordion/item_test.rb +61 -0
- data/registry/test/components/ui/accordion/trigger_test.rb +80 -0
- data/registry/test/components/ui/accordion_test.rb +96 -0
- data/registry/test/components/ui/alert/description_test.rb +37 -0
- data/registry/test/components/ui/alert/title_test.rb +38 -0
- data/registry/test/components/ui/alert_test.rb +184 -0
- data/registry/test/components/ui/avatar_group_test.rb +79 -0
- data/registry/test/components/ui/avatar_test.rb +129 -0
- data/registry/test/components/ui/badge_test.rb +112 -0
- data/registry/test/components/ui/banner_test.rb +116 -0
- data/registry/test/components/ui/base_test.rb +98 -0
- data/registry/test/components/ui/breadcrumb/ellipsis_test.rb +51 -0
- data/registry/test/components/ui/breadcrumb/item_test.rb +39 -0
- data/registry/test/components/ui/breadcrumb/list_test.rb +34 -0
- data/registry/test/components/ui/breadcrumb/separator_test.rb +36 -0
- data/registry/test/components/ui/breadcrumb_test.rb +276 -0
- data/registry/test/components/ui/button_test.rb +276 -0
- data/registry/test/components/ui/button_to_test.rb +74 -0
- data/registry/test/components/ui/card/content_test.rb +41 -0
- data/registry/test/components/ui/card/description_test.rb +32 -0
- data/registry/test/components/ui/card/footer_test.rb +34 -0
- data/registry/test/components/ui/card/header_test.rb +57 -0
- data/registry/test/components/ui/card/title_test.rb +34 -0
- data/registry/test/components/ui/card_test.rb +67 -0
- data/registry/test/components/ui/checkbox_test.rb +236 -0
- data/registry/test/components/ui/data_grid_test.rb +88 -0
- data/registry/test/components/ui/date_picker_test.rb +168 -0
- data/registry/test/components/ui/dialog/content_test.rb +156 -0
- data/registry/test/components/ui/dialog/trigger_test.rb +74 -0
- data/registry/test/components/ui/dialog_test.rb +54 -0
- data/registry/test/components/ui/divider_test.rb +69 -0
- data/registry/test/components/ui/icon_test.rb +82 -0
- data/registry/test/components/ui/image_test.rb +74 -0
- data/registry/test/components/ui/input_group_test.rb +143 -0
- data/registry/test/components/ui/input_test.rb +251 -0
- data/registry/test/components/ui/label_test.rb +96 -0
- data/registry/test/components/ui/link_test.rb +95 -0
- data/registry/test/components/ui/menu/content_test.rb +233 -0
- data/registry/test/components/ui/menu/group_test.rb +24 -0
- data/registry/test/components/ui/menu/item_test.rb +76 -0
- data/registry/test/components/ui/menu/label_test.rb +43 -0
- data/registry/test/components/ui/menu/separator_test.rb +32 -0
- data/registry/test/components/ui/menu/trigger_test.rb +109 -0
- data/registry/test/components/ui/menu_test.rb +152 -0
- data/registry/test/components/ui/native_select_test.rb +118 -0
- data/registry/test/components/ui/pagination_test.rb +92 -0
- data/registry/test/components/ui/password_input_test.rb +98 -0
- data/registry/test/components/ui/popover/content_test.rb +226 -0
- data/registry/test/components/ui/popover/trigger_test.rb +83 -0
- data/registry/test/components/ui/popover_test.rb +101 -0
- data/registry/test/components/ui/radio_group/item_test.rb +14 -0
- data/registry/test/components/ui/radio_group_test.rb +139 -0
- data/registry/test/components/ui/select_test.rb +181 -0
- data/registry/test/components/ui/sheet/content_test.rb +135 -0
- data/registry/test/components/ui/sheet/trigger_test.rb +23 -0
- data/registry/test/components/ui/sheet_test.rb +43 -0
- data/registry/test/components/ui/sidebar/menu_button_test.rb +43 -0
- data/registry/test/components/ui/sidebar/trigger_test.rb +17 -0
- data/registry/test/components/ui/sidebar/wrapper_test.rb +15 -0
- data/registry/test/components/ui/sidebar_test.rb +43 -0
- data/registry/test/components/ui/spinner_test.rb +63 -0
- data/registry/test/components/ui/switch_test.rb +206 -0
- data/registry/test/components/ui/table_test.rb +106 -0
- data/registry/test/components/ui/tabs/content_test.rb +93 -0
- data/registry/test/components/ui/tabs/list_test.rb +65 -0
- data/registry/test/components/ui/tabs/trigger_test.rb +159 -0
- data/registry/test/components/ui/tabs_test.rb +88 -0
- data/registry/test/components/ui/text_test.rb +84 -0
- data/registry/test/components/ui/theme_toggle_test.rb +88 -0
- data/registry/test/components/ui/tooltip/content_test.rb +135 -0
- data/registry/test/components/ui/tooltip/trigger_test.rb +52 -0
- data/registry/test/components/ui/tooltip_test.rb +97 -0
- data/registry/test/components/ui/typography/code_blockquote_test.rb +57 -0
- data/registry/test/components/ui/typography/heading_test.rb +71 -0
- data/registry/test/components/ui/typography/text_variants_test.rb +71 -0
- metadata +540 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<div class="flex flex-wrap items-center gap-3">
|
|
2
|
+
<%= render(UI::Button.new(variant: :default)) do |btn|
|
|
3
|
+
btn.with_leading_icon(name: "lock")
|
|
4
|
+
"Sign in"
|
|
5
|
+
end %>
|
|
6
|
+
<%= render(UI::Button.new(variant: :outline)) do |btn|
|
|
7
|
+
btn.with_leading_icon(name: "eye")
|
|
8
|
+
"Preview"
|
|
9
|
+
end %>
|
|
10
|
+
<%= render(UI::Button.new(variant: :secondary)) do |btn|
|
|
11
|
+
btn.with_leading_icon(name: "badge-check")
|
|
12
|
+
"Verified"
|
|
13
|
+
end %>
|
|
14
|
+
<%= render(UI::Button.new(variant: :destructive)) do |btn|
|
|
15
|
+
btn.with_leading_icon(name: "x")
|
|
16
|
+
"Delete"
|
|
17
|
+
end %>
|
|
18
|
+
<%= render(UI::Button.new(variant: :ghost)) do |btn|
|
|
19
|
+
btn.with_leading_icon(name: "user")
|
|
20
|
+
"Profile"
|
|
21
|
+
end %>
|
|
22
|
+
</div>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<div class="flex flex-wrap items-center gap-3">
|
|
2
|
+
<%= render(UI::Button.new(variant: :default)) do |btn|
|
|
3
|
+
btn.with_trailing_icon(name: "arrow-right")
|
|
4
|
+
"Continue"
|
|
5
|
+
end %>
|
|
6
|
+
<%= render(UI::Button.new(variant: :outline)) do |btn|
|
|
7
|
+
btn.with_trailing_icon(name: "chevrons-up-down")
|
|
8
|
+
"Sort"
|
|
9
|
+
end %>
|
|
10
|
+
<%= render(UI::Button.new(variant: :link)) do |btn|
|
|
11
|
+
btn.with_trailing_icon(name: "arrow-right")
|
|
12
|
+
"Read more"
|
|
13
|
+
end %>
|
|
14
|
+
</div>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class UI::ButtonPreview < ViewComponent::Preview
|
|
4
|
+
# @label Playground
|
|
5
|
+
# @param text text "Button text"
|
|
6
|
+
# @param variant select { choices: [default, destructive, outline, secondary, ghost, link] }
|
|
7
|
+
# @param size select { choices: [default, sm, lg, icon] }
|
|
8
|
+
# @param leading_icon select { choices: [none, lock, arrow-right, badge-check, eye, user] }
|
|
9
|
+
# @param trailing_icon select { choices: [none, arrow-right, chevrons-up-down, eye, x] }
|
|
10
|
+
# @param full_width toggle
|
|
11
|
+
# @param loading toggle
|
|
12
|
+
# @param disabled toggle
|
|
13
|
+
def playground(text: "Click me", variant: :default, size: :default,
|
|
14
|
+
leading_icon: :none, trailing_icon: :none,
|
|
15
|
+
full_width: false, loading: false, disabled: false)
|
|
16
|
+
render(UI::Button.new(
|
|
17
|
+
variant: variant.to_sym, size: size.to_sym,
|
|
18
|
+
full_width: full_width, loading: loading, disabled: disabled
|
|
19
|
+
)) do |btn|
|
|
20
|
+
btn.with_leading_icon(name: leading_icon.to_s) unless leading_icon.to_s == "none"
|
|
21
|
+
btn.with_trailing_icon(name: trailing_icon.to_s) unless trailing_icon.to_s == "none"
|
|
22
|
+
text
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @label All Variants
|
|
27
|
+
def variants
|
|
28
|
+
render_with_template
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# @label All Sizes
|
|
32
|
+
def sizes
|
|
33
|
+
render_with_template
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @label With Leading Icon
|
|
37
|
+
def with_leading_icon
|
|
38
|
+
render_with_template
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @label With Trailing Icon
|
|
42
|
+
def with_trailing_icon
|
|
43
|
+
render_with_template
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @label With Both Icons
|
|
47
|
+
def with_both_icons
|
|
48
|
+
render_with_template
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @label Icon Only
|
|
52
|
+
def icon_only
|
|
53
|
+
render_with_template
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# @label Loading
|
|
57
|
+
def loading
|
|
58
|
+
render_with_template
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @label Disabled
|
|
62
|
+
def disabled
|
|
63
|
+
render_with_template
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<div class="flex flex-wrap items-center gap-3">
|
|
2
|
+
<%= render(UI::ButtonTo.new("#")) { "Default" } %>
|
|
3
|
+
<%= render(UI::ButtonTo.new("#", loading: true)) { "Loading" } %>
|
|
4
|
+
<%= render(UI::ButtonTo.new("#", disabled: true)) { "Disabled" } %>
|
|
5
|
+
</div>
|
|
6
|
+
<div class="mt-6 max-w-xs">
|
|
7
|
+
<%= render(UI::ButtonTo.new("#", variant: :outline, full_width: true, form_class: "w-full")) { "Full width" } %>
|
|
8
|
+
</div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<%# Icon slots render here, unlike the Velvet component this replaces. %>
|
|
2
|
+
<div class="flex flex-wrap items-center gap-3">
|
|
3
|
+
<%= render(UI::ButtonTo.new("#", variant: :outline)) do |button| %>
|
|
4
|
+
<% button.with_leading_icon(name: "mail") %>
|
|
5
|
+
Sign in with email
|
|
6
|
+
<% end %>
|
|
7
|
+
<%= render(UI::ButtonTo.new("#")) do |button| %>
|
|
8
|
+
<% button.with_trailing_icon(name: "arrow-right") %>
|
|
9
|
+
Continue
|
|
10
|
+
<% end %>
|
|
11
|
+
</div>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class UI::ButtonToPreview < ViewComponent::Preview
|
|
4
|
+
# @label Playground
|
|
5
|
+
# @param variant select { choices: [default, destructive, outline, secondary, ghost, link] }
|
|
6
|
+
# @param size select { choices: [sm, default, lg] }
|
|
7
|
+
# @param full_width toggle
|
|
8
|
+
# @param text text
|
|
9
|
+
def playground(variant: :default, size: :default, full_width: false, text: "Submit")
|
|
10
|
+
render(UI::ButtonTo.new("#", variant: variant.to_sym, size: size.to_sym, full_width: full_width)) { text }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# @label Variants
|
|
14
|
+
def variants; render_with_template; end
|
|
15
|
+
|
|
16
|
+
# @label With Icon
|
|
17
|
+
def with_icon; render_with_template; end
|
|
18
|
+
|
|
19
|
+
# @label States
|
|
20
|
+
def states; render_with_template; end
|
|
21
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<div class="max-w-sm">
|
|
2
|
+
<%= render(UI::Card.new) do |card| %>
|
|
3
|
+
<% card.with_header do |header| %>
|
|
4
|
+
<% header.with_title { "Team Members" } %>
|
|
5
|
+
<% header.with_description { "Manage your team and permissions." } %>
|
|
6
|
+
<% end %>
|
|
7
|
+
<% card.with_content do %>
|
|
8
|
+
<div class="space-y-3">
|
|
9
|
+
<div class="flex items-center gap-3">
|
|
10
|
+
<div class="h-8 w-8 rounded-full bg-primary/10 flex items-center justify-center text-xs font-medium text-primary">JD</div>
|
|
11
|
+
<div>
|
|
12
|
+
<p class="text-sm font-medium">John Doe</p>
|
|
13
|
+
<p class="text-xs text-muted-foreground">Admin</p>
|
|
14
|
+
</div>
|
|
15
|
+
</div>
|
|
16
|
+
<div class="flex items-center gap-3">
|
|
17
|
+
<div class="h-8 w-8 rounded-full bg-primary/10 flex items-center justify-center text-xs font-medium text-primary">AS</div>
|
|
18
|
+
<div>
|
|
19
|
+
<p class="text-sm font-medium">Alice Smith</p>
|
|
20
|
+
<p class="text-xs text-muted-foreground">Editor</p>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
<% end %>
|
|
25
|
+
<% card.with_footer do %>
|
|
26
|
+
<div class="flex gap-2 w-full">
|
|
27
|
+
<%= render(UI::Button.new(variant: :outline, size: :sm, class: "w-full")) { "Invite Member" } %>
|
|
28
|
+
</div>
|
|
29
|
+
<% end %>
|
|
30
|
+
<% end %>
|
|
31
|
+
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<div class="max-w-sm">
|
|
2
|
+
<%= render(UI::Card.new) do |card| %>
|
|
3
|
+
<% card.with_header do |header| %>
|
|
4
|
+
<% header.with_title { "Account Settings" } %>
|
|
5
|
+
<% header.with_description { "Update your account preferences." } %>
|
|
6
|
+
<% end %>
|
|
7
|
+
<% card.with_content do %>
|
|
8
|
+
<div class="space-y-4">
|
|
9
|
+
<div class="space-y-2">
|
|
10
|
+
<%= render(UI::Label.new(for: "name")) { "Display Name" } %>
|
|
11
|
+
<%= render(UI::Input.new(id: "name", placeholder: "Enter your name")) %>
|
|
12
|
+
</div>
|
|
13
|
+
<div class="space-y-2">
|
|
14
|
+
<%= render(UI::Label.new(for: "username")) { "Username" } %>
|
|
15
|
+
<%= render(UI::Input.new(id: "username", placeholder: "@username")) %>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
<% end %>
|
|
19
|
+
<% card.with_footer do %>
|
|
20
|
+
<div class="flex gap-2">
|
|
21
|
+
<%= render(UI::Button.new(variant: :primary, size: :sm)) { "Save Changes" } %>
|
|
22
|
+
</div>
|
|
23
|
+
<% end %>
|
|
24
|
+
<% end %>
|
|
25
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<div class="max-w-sm">
|
|
2
|
+
<%= render(UI::Card.new) do |card| %>
|
|
3
|
+
<% card.with_content do %>
|
|
4
|
+
<p class="text-sm text-muted-foreground">Card with body content and a footer containing actions.</p>
|
|
5
|
+
<% end %>
|
|
6
|
+
<% card.with_footer do %>
|
|
7
|
+
<div class="flex gap-2">
|
|
8
|
+
<%= render(UI::Button.new(variant: :primary, size: :sm)) { "Save" } %>
|
|
9
|
+
<%= render(UI::Button.new(variant: :outline, size: :sm)) { "Cancel" } %>
|
|
10
|
+
</div>
|
|
11
|
+
<% end %>
|
|
12
|
+
<% end %>
|
|
13
|
+
</div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<div class="max-w-sm">
|
|
2
|
+
<%= render(UI::Card.new) do |card| %>
|
|
3
|
+
<% card.with_header do |header| %>
|
|
4
|
+
<% header.with_title { "Notifications" } %>
|
|
5
|
+
<% header.with_description { "Configure how you receive notifications." } %>
|
|
6
|
+
<% end %>
|
|
7
|
+
<% card.with_content do %>
|
|
8
|
+
<p class="text-sm text-muted-foreground">Card with a header containing a title and description.</p>
|
|
9
|
+
<% end %>
|
|
10
|
+
<% end %>
|
|
11
|
+
</div>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class UI::CardPreview < ViewComponent::Preview
|
|
4
|
+
# @label Playground
|
|
5
|
+
# @param title text
|
|
6
|
+
# @param description text
|
|
7
|
+
# @param show_footer toggle
|
|
8
|
+
def playground(title: "Create project", description: "Deploy your new project in one click.", show_footer: true)
|
|
9
|
+
render(UI::Card.new) do |card|
|
|
10
|
+
card.with_header do |header|
|
|
11
|
+
header.with_title { title }
|
|
12
|
+
header.with_description { description }
|
|
13
|
+
end
|
|
14
|
+
card.with_content do
|
|
15
|
+
tag.p(class: "text-sm text-muted-foreground") { "Card body content goes here." }
|
|
16
|
+
end
|
|
17
|
+
if show_footer
|
|
18
|
+
card.with_footer do
|
|
19
|
+
tag.div(class: "flex gap-2") do
|
|
20
|
+
safe_join([
|
|
21
|
+
render(UI::Button.new(variant: :primary, size: :sm)) { "Deploy" },
|
|
22
|
+
render(UI::Button.new(variant: :outline, size: :sm)) { "Cancel" }
|
|
23
|
+
])
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @label Default (content only)
|
|
31
|
+
def default; render_with_template; end
|
|
32
|
+
|
|
33
|
+
# @label With Header
|
|
34
|
+
def with_header; render_with_template; end
|
|
35
|
+
|
|
36
|
+
# @label With Footer
|
|
37
|
+
def with_footer; render_with_template; end
|
|
38
|
+
|
|
39
|
+
# @label Complete (all sections)
|
|
40
|
+
def complete; render_with_template; end
|
|
41
|
+
|
|
42
|
+
# @label Settings Form
|
|
43
|
+
def settings_form; render_with_template; end
|
|
44
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<form class="space-y-4 border rounded-md p-6 max-w-sm" action="#" method="post">
|
|
2
|
+
<fieldset class="space-y-3">
|
|
3
|
+
<legend class="text-sm font-medium mb-2">Notification preferences</legend>
|
|
4
|
+
<%= render(UI::Checkbox.new(name: "prefs[email]", checked: true, label: "Email notifications")) %>
|
|
5
|
+
<%= render(UI::Checkbox.new(name: "prefs[push]", label: "Push notifications")) %>
|
|
6
|
+
<%= render(UI::Checkbox.new(name: "prefs[sms]", disabled: true, label: "SMS (unavailable)")) %>
|
|
7
|
+
</fieldset>
|
|
8
|
+
<%= render(UI::Button.new(type: :submit)) { "Save preferences" } %>
|
|
9
|
+
</form>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<div class="flex flex-col gap-4">
|
|
2
|
+
<div class="flex items-center gap-4">
|
|
3
|
+
<%= render(UI::Checkbox.new(name: "unchecked")) %>
|
|
4
|
+
<span class="text-sm text-muted-foreground">Unchecked</span>
|
|
5
|
+
</div>
|
|
6
|
+
<div class="flex items-center gap-4">
|
|
7
|
+
<%= render(UI::Checkbox.new(name: "checked", checked: true)) %>
|
|
8
|
+
<span class="text-sm text-muted-foreground">Checked</span>
|
|
9
|
+
</div>
|
|
10
|
+
<div class="flex items-center gap-4">
|
|
11
|
+
<%= render(UI::Checkbox.new(name: "disabled", disabled: true)) %>
|
|
12
|
+
<span class="text-sm text-muted-foreground">Disabled</span>
|
|
13
|
+
</div>
|
|
14
|
+
<div class="flex items-center gap-4">
|
|
15
|
+
<%= render(UI::Checkbox.new(name: "disabled-checked", disabled: true, checked: true)) %>
|
|
16
|
+
<span class="text-sm text-muted-foreground">Disabled + Checked</span>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="flex items-center gap-4">
|
|
19
|
+
<%= render(UI::Checkbox.new(name: "error", error: true)) %>
|
|
20
|
+
<span class="text-sm text-destructive">Error</span>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<div class="flex flex-col gap-4">
|
|
2
|
+
<%= render(UI::Checkbox.new(name: "small", label: "Small checkbox", size: :sm)) %>
|
|
3
|
+
<%= render(UI::Checkbox.new(name: "default", label: "Default checkbox", size: :default)) %>
|
|
4
|
+
<%= render(UI::Checkbox.new(name: "large", label: "Large checkbox", size: :lg)) %>
|
|
5
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class UI::CheckboxPreview < ViewComponent::Preview
|
|
4
|
+
# @label Playground
|
|
5
|
+
# @param label text
|
|
6
|
+
# @param size select { choices: [sm, default, lg] }
|
|
7
|
+
# @param checked toggle
|
|
8
|
+
# @param required toggle
|
|
9
|
+
# @param error toggle
|
|
10
|
+
# @param disabled toggle
|
|
11
|
+
def playground(label: "Accept terms", size: :default,
|
|
12
|
+
checked: false, required: false, error: false, disabled: false)
|
|
13
|
+
render(UI::Checkbox.new(
|
|
14
|
+
name: "demo", label: label, size: size.to_sym,
|
|
15
|
+
checked: checked, required: required, error: error, disabled: disabled
|
|
16
|
+
))
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# @label States
|
|
20
|
+
def states; render_with_template; end
|
|
21
|
+
|
|
22
|
+
# @label With Label
|
|
23
|
+
def with_label; render_with_template; end
|
|
24
|
+
|
|
25
|
+
# @label In Form
|
|
26
|
+
def in_form; render_with_template; end
|
|
27
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class UI::DataGridPreview < ViewComponent::Preview
|
|
4
|
+
# The grid fetches its rows from the server, so a preview needs a real class
|
|
5
|
+
# endpoint to point at, so here it shows the markup and the reserved height.
|
|
6
|
+
# velvetkit.com's Data grid page has a live one.
|
|
7
|
+
#
|
|
8
|
+
# @label Playground
|
|
9
|
+
# @param page_size number
|
|
10
|
+
def playground(page_size: 15)
|
|
11
|
+
render(UI::DataGrid.new(url: "/customers.json", page_size: page_size.to_i)) do |grid|
|
|
12
|
+
grid.column(:id, "ID", width: 90, type: :number)
|
|
13
|
+
grid.column(:name, "Name")
|
|
14
|
+
grid.column(:plan, "Plan")
|
|
15
|
+
grid.column(:owner, "Owner", sortable: false, filterable: false)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<div class="flex max-w-xs flex-col gap-6">
|
|
2
|
+
<%= render(UI::DatePicker.new(name: "a", label: "Empty")) %>
|
|
3
|
+
<%= render(UI::DatePicker.new(name: "b", label: "Required", required: true)) %>
|
|
4
|
+
<%= render(UI::DatePicker.new(name: "c", label: "With an error", error: true, value: Date.new(2026, 10, 21))) %>
|
|
5
|
+
<%= render(UI::DatePicker.new(name: "d", label: "Disabled", disabled: true, value: Date.new(2026, 10, 21))) %>
|
|
6
|
+
<%= render(UI::DatePicker.new(name: "e", label: "Without the hint", hint: false)) %>
|
|
7
|
+
</div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<%= render(UI::Dialog.new) do |dialog| %>
|
|
2
|
+
<% dialog.with_trigger(variant: :destructive) { "Delete project" } %>
|
|
3
|
+
<% dialog.with_content(size: :sm) do |content| %>
|
|
4
|
+
<% content.with_title { "Delete this project?" } %>
|
|
5
|
+
<% content.with_description { "This action cannot be undone. All project data will be removed permanently." } %>
|
|
6
|
+
<% content.with_footer do %>
|
|
7
|
+
<%= render(UI::Dialog::Close.new(variant: :outline, class: "static")) { "Cancel" } %>
|
|
8
|
+
<%= render(UI::Button.new(variant: :destructive)) { "Delete" } %>
|
|
9
|
+
<% end %>
|
|
10
|
+
<% end %>
|
|
11
|
+
<% end %>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<%= render(UI::Dialog.new) do |dialog| %>
|
|
2
|
+
<% dialog.with_trigger(as_child: true, variant: :ghost) do %>
|
|
3
|
+
<a href="#dialog-demo" class="inline-flex items-center gap-2 text-sm font-medium underline underline-offset-4">
|
|
4
|
+
Review release notes
|
|
5
|
+
<%= render(UI::Icon.new(name: "arrow-right", size: :sm)) %>
|
|
6
|
+
</a>
|
|
7
|
+
<% end %>
|
|
8
|
+
<% dialog.with_content do |content| %>
|
|
9
|
+
<% content.with_title { "Release notes" } %>
|
|
10
|
+
<% content.with_description { "A custom trigger can adopt the dialog semantics without rendering a nested button." } %>
|
|
11
|
+
<div class="space-y-2 text-sm text-muted-foreground">
|
|
12
|
+
<p>Dialog trigger attributes are merged into the anchor element.</p>
|
|
13
|
+
<p>The trigger keeps its own classes while inheriting the chosen button variant tokens.</p>
|
|
14
|
+
</div>
|
|
15
|
+
<% end %>
|
|
16
|
+
<% end %>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<%= render(UI::Dialog.new) do |dialog| %>
|
|
2
|
+
<% dialog.with_trigger(variant: :outline) { "Open dialog" } %>
|
|
3
|
+
<% dialog.with_content do |content| %>
|
|
4
|
+
<% content.with_title { "Edit profile" } %>
|
|
5
|
+
<% content.with_description { "Make changes to your profile here. Click save when you're done." } %>
|
|
6
|
+
<% content.with_footer do %>
|
|
7
|
+
<%= render(UI::Dialog::Close.new(variant: :outline, class: "static")) { "Cancel" } %>
|
|
8
|
+
<%= render(UI::Button.new) { "Save changes" } %>
|
|
9
|
+
<% end %>
|
|
10
|
+
<div class="grid gap-3">
|
|
11
|
+
<%= render(UI::Input.new(type: :text, value: "Rain Root")) %>
|
|
12
|
+
<%= render(UI::Input.new(type: :email, value: "rainroot@example.com")) %>
|
|
13
|
+
</div>
|
|
14
|
+
<% end %>
|
|
15
|
+
<% end %>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<%= render(UI::Dialog.new) do |dialog| %>
|
|
2
|
+
<% dialog.with_trigger(variant: :secondary) { "Open policy dialog" } %>
|
|
3
|
+
<% dialog.with_content(size: :lg) do |content| %>
|
|
4
|
+
<% content.with_title { "Usage policy" } %>
|
|
5
|
+
<% content.with_description { "Long-form modal content should remain readable and keep actions pinned at the end." } %>
|
|
6
|
+
<div class="space-y-4 text-sm leading-6 text-muted-foreground">
|
|
7
|
+
<p>Dialogs are best reserved for focused tasks, decisions, or short forms.</p>
|
|
8
|
+
<p>Because the component uses the native dialog element, focus is moved into the modal and restored to the opener when it closes.</p>
|
|
9
|
+
<p>The content element is portaled under <code>body</code> at runtime so the backdrop and stacking context stay predictable.</p>
|
|
10
|
+
</div>
|
|
11
|
+
<% content.with_footer do %>
|
|
12
|
+
<%= render(UI::Dialog::Close.new(variant: :outline, class: "static")) { "Close" } %>
|
|
13
|
+
<%= render(UI::Button.new(variant: :secondary)) { "Acknowledge" } %>
|
|
14
|
+
<% end %>
|
|
15
|
+
<% end %>
|
|
16
|
+
<% end %>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<%= render(UI::Dialog.new) do |dialog| %>
|
|
2
|
+
<% dialog.with_trigger(variant: @trigger_variant) { "Open dialog" } %>
|
|
3
|
+
<% dialog.with_content(size: @size, show_close: @show_close) do |content| %>
|
|
4
|
+
<% content.with_title { "Edit profile" } %>
|
|
5
|
+
<% content.with_description { "Make changes to your profile here. Click save when you're done." } %>
|
|
6
|
+
<% content.with_footer do %>
|
|
7
|
+
<%= render(UI::Dialog::Close.new(variant: :outline)) { "Cancel" } %>
|
|
8
|
+
<%= render(UI::Button.new) { "Save changes" } %>
|
|
9
|
+
<% end %>
|
|
10
|
+
Dialog body content lives here.
|
|
11
|
+
<% end %>
|
|
12
|
+
<% end %>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<%= render(UI::Dialog.new) do |dialog| %>
|
|
2
|
+
<% dialog.with_trigger(variant: :secondary) { "Open scrollable dialog" } %>
|
|
3
|
+
<% dialog.with_content(size: :lg) do |content| %>
|
|
4
|
+
<% content.with_title { "Terms of Service" } %>
|
|
5
|
+
<% content.with_description { "Please review the full terms before continuing." } %>
|
|
6
|
+
<div class="space-y-4 text-sm leading-6 text-muted-foreground">
|
|
7
|
+
<p><strong>1. Acceptance of Terms</strong><br>
|
|
8
|
+
By accessing or using our services, you agree to be bound by these Terms of Service. If you do not agree to all the terms and conditions, you may not access the service.</p>
|
|
9
|
+
<p><strong>2. Changes to Terms</strong><br>
|
|
10
|
+
We reserve the right, at our sole discretion, to modify or replace these Terms at any time. It is your responsibility to review these Terms periodically for changes.</p>
|
|
11
|
+
<p><strong>3. Use License</strong><br>
|
|
12
|
+
Permission is granted to temporarily use the materials on our website for personal, non-commercial transitory viewing only. This is the grant of a license, not a transfer of title.</p>
|
|
13
|
+
<p><strong>4. Disclaimer</strong><br>
|
|
14
|
+
The materials on our website are provided on an 'as is' basis. We make no warranties, expressed or implied, and hereby disclaim and negate all other warranties including, without limitation, implied warranties or conditions of merchantability, fitness for a particular purpose, or non-infringement of intellectual property or other violation of rights.</p>
|
|
15
|
+
<p><strong>5. Limitations</strong><br>
|
|
16
|
+
In no event shall we or our suppliers be liable for any damages arising out of the use or inability to use the materials on our website, even if we or an authorized representative has been notified orally or in writing of the possibility of such damage.</p>
|
|
17
|
+
<p><strong>6. Accuracy of Materials</strong><br>
|
|
18
|
+
The materials appearing on our website could include technical, typographical, or photographic errors. We do not warrant that any of the materials on our website are accurate, complete, or current.</p>
|
|
19
|
+
<p><strong>7. Links</strong><br>
|
|
20
|
+
We have not reviewed all of the sites linked to our website and are not responsible for the contents of any such linked site. The inclusion of any link does not imply endorsement by us of the site.</p>
|
|
21
|
+
<p><strong>8. Governing Law</strong><br>
|
|
22
|
+
These terms and conditions are governed by and construed in accordance with the laws of the jurisdiction in which we operate, and you irrevocably submit to the exclusive jurisdiction of the courts in that location.</p>
|
|
23
|
+
</div>
|
|
24
|
+
<% content.with_footer do %>
|
|
25
|
+
<%= render(UI::Dialog::Close.new(variant: :outline, class: "static")) { "Decline" } %>
|
|
26
|
+
<%= render(UI::Button.new) { "Accept" } %>
|
|
27
|
+
<% end %>
|
|
28
|
+
<% end %>
|
|
29
|
+
<% end %>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<div class="flex flex-wrap gap-4">
|
|
2
|
+
<%= render(UI::Dialog.new) do |dialog| %>
|
|
3
|
+
<% dialog.with_trigger(variant: :outline, size: :sm) { "Open sm" } %>
|
|
4
|
+
<% dialog.with_content(size: :sm) do |content| %>
|
|
5
|
+
<% content.with_title { "Small dialog" } %>
|
|
6
|
+
<% content.with_description { "This is the smallest dialog size, great for confirmations." } %>
|
|
7
|
+
<% content.with_footer do %>
|
|
8
|
+
<%= render(UI::Dialog::Close.new(variant: :outline, class: "static")) { "Cancel" } %>
|
|
9
|
+
<%= render(UI::Button.new(size: :sm)) { "Confirm" } %>
|
|
10
|
+
<% end %>
|
|
11
|
+
<% end %>
|
|
12
|
+
<% end %>
|
|
13
|
+
<%= render(UI::Dialog.new) do |dialog| %>
|
|
14
|
+
<% dialog.with_trigger(variant: :outline) { "Open default" } %>
|
|
15
|
+
<% dialog.with_content do |content| %>
|
|
16
|
+
<% content.with_title { "Default dialog" } %>
|
|
17
|
+
<% content.with_description { "This is the default dialog size for most use cases." } %>
|
|
18
|
+
<% content.with_footer do %>
|
|
19
|
+
<%= render(UI::Dialog::Close.new(variant: :outline, class: "static")) { "Cancel" } %>
|
|
20
|
+
<%= render(UI::Button.new) { "Confirm" } %>
|
|
21
|
+
<% end %>
|
|
22
|
+
<% end %>
|
|
23
|
+
<% end %>
|
|
24
|
+
<%= render(UI::Dialog.new) do |dialog| %>
|
|
25
|
+
<% dialog.with_trigger(variant: :outline) { "Open lg" } %>
|
|
26
|
+
<% dialog.with_content(size: :lg) do |content| %>
|
|
27
|
+
<% content.with_title { "Large dialog" } %>
|
|
28
|
+
<% content.with_description { "This is a large dialog, useful for forms and detailed content." } %>
|
|
29
|
+
<% content.with_footer do %>
|
|
30
|
+
<%= render(UI::Dialog::Close.new(variant: :outline, class: "static")) { "Cancel" } %>
|
|
31
|
+
<%= render(UI::Button.new) { "Confirm" } %>
|
|
32
|
+
<% end %>
|
|
33
|
+
<% end %>
|
|
34
|
+
<% end %>
|
|
35
|
+
<%= render(UI::Dialog.new) do |dialog| %>
|
|
36
|
+
<% dialog.with_trigger(variant: :outline) { "Open xl" } %>
|
|
37
|
+
<% dialog.with_content(size: :xl) do |content| %>
|
|
38
|
+
<% content.with_title { "Extra large dialog" } %>
|
|
39
|
+
<% content.with_description { "This is the largest dialog size, ideal for complex workflows." } %>
|
|
40
|
+
<% content.with_footer do %>
|
|
41
|
+
<%= render(UI::Dialog::Close.new(variant: :outline, class: "static")) { "Cancel" } %>
|
|
42
|
+
<%= render(UI::Button.new) { "Confirm" } %>
|
|
43
|
+
<% end %>
|
|
44
|
+
<% end %>
|
|
45
|
+
<% end %>
|
|
46
|
+
</div>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<%= render(UI::Dialog.new) do |dialog| %>
|
|
2
|
+
<% dialog.with_trigger(variant: :outline) { "Open dialog" } %>
|
|
3
|
+
<% dialog.with_content(show_close: false) do |content| %>
|
|
4
|
+
<% content.with_title { "No close button" } %>
|
|
5
|
+
<% content.with_description { "This dialog hides the default close button. Users must interact with the footer actions to dismiss it." } %>
|
|
6
|
+
<% content.with_footer do %>
|
|
7
|
+
<%= render(UI::Dialog::Close.new(variant: :outline, class: "static")) { "Dismiss" } %>
|
|
8
|
+
<%= render(UI::Button.new) { "Continue" } %>
|
|
9
|
+
<% end %>
|
|
10
|
+
<% end %>
|
|
11
|
+
<% end %>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<%= render(UI::Dialog.new) do |dialog| %>
|
|
2
|
+
<% dialog.with_trigger(variant: :outline) { "Open dialog" } %>
|
|
3
|
+
<% dialog.with_content do %>
|
|
4
|
+
<div class="space-y-3 text-sm text-muted-foreground">
|
|
5
|
+
<p>This dialog has no title or description header.</p>
|
|
6
|
+
<p>Use this pattern when the content speaks for itself or when you want a cleaner, minimal modal.</p>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="mt-4 flex justify-end gap-2">
|
|
9
|
+
<%= render(UI::Dialog::Close.new(variant: :outline, class: "static")) { "Close" } %>
|
|
10
|
+
<%= render(UI::Button.new) { "Okay" } %>
|
|
11
|
+
</div>
|
|
12
|
+
<% end %>
|
|
13
|
+
<% end %>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class UI::DialogPreview < ViewComponent::Preview
|
|
4
|
+
# @label Playground
|
|
5
|
+
# @param trigger_variant select { choices: [default, outline, secondary, ghost] }
|
|
6
|
+
# @param size select { choices: [sm, default, lg, xl] }
|
|
7
|
+
# @param show_close toggle
|
|
8
|
+
def playground(trigger_variant: :outline, size: :default, show_close: true)
|
|
9
|
+
@trigger_variant = trigger_variant.to_sym
|
|
10
|
+
@size = size.to_sym
|
|
11
|
+
@show_close = show_close
|
|
12
|
+
render_with_template
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @label Default
|
|
16
|
+
def default; render_with_template; end
|
|
17
|
+
|
|
18
|
+
# @label Confirmation
|
|
19
|
+
def confirmation; render_with_template; end
|
|
20
|
+
|
|
21
|
+
# @label Custom Trigger
|
|
22
|
+
def custom_trigger; render_with_template; end
|
|
23
|
+
|
|
24
|
+
# @label Long Content
|
|
25
|
+
def long_content; render_with_template; end
|
|
26
|
+
|
|
27
|
+
# @label Sizes
|
|
28
|
+
def sizes; render_with_template; end
|
|
29
|
+
|
|
30
|
+
# @label Without Close Button
|
|
31
|
+
def without_close_button; render_with_template; end
|
|
32
|
+
|
|
33
|
+
# @label Without Title
|
|
34
|
+
def without_title; render_with_template; end
|
|
35
|
+
|
|
36
|
+
# @label Scrollable Body
|
|
37
|
+
def scrollable_body; render_with_template; end
|
|
38
|
+
end
|