uikit_rails 0.1.0
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.
Potentially problematic release.
This version of uikit_rails might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/README.md +259 -0
- data/Rakefile +12 -0
- data/app/controllers/uikit_rails/styleguide_controller.rb +72 -0
- data/app/views/layouts/uikit_rails/application.html.erb +412 -0
- data/app/views/uikit_rails/styleguide/index.html.erb +27 -0
- data/app/views/uikit_rails/styleguide/show.html.erb +56 -0
- data/config/routes.rb +6 -0
- data/lib/uikit_rails/engine.rb +13 -0
- data/lib/uikit_rails/generators/add_generator.rb +110 -0
- data/lib/uikit_rails/generators/install_generator.rb +62 -0
- data/lib/uikit_rails/generators/templates/base_component.rb.tt +32 -0
- data/lib/uikit_rails/generators/templates/uikit_rails.css.tt +69 -0
- data/lib/uikit_rails/templates/components/accordion/USAGE +30 -0
- data/lib/uikit_rails/templates/components/accordion/accordion.css +74 -0
- data/lib/uikit_rails/templates/components/accordion/component.html.erb +13 -0
- data/lib/uikit_rails/templates/components/accordion/component.rb +35 -0
- data/lib/uikit_rails/templates/components/accordion/preview.yml +81 -0
- data/lib/uikit_rails/templates/components/alert/USAGE +25 -0
- data/lib/uikit_rails/templates/components/alert/alert.css +60 -0
- data/lib/uikit_rails/templates/components/alert/component.html.erb +9 -0
- data/lib/uikit_rails/templates/components/alert/component.rb +27 -0
- data/lib/uikit_rails/templates/components/alert/preview.yml +53 -0
- data/lib/uikit_rails/templates/components/alert_dialog/USAGE +38 -0
- data/lib/uikit_rails/templates/components/alert_dialog/alert_dialog.css +108 -0
- data/lib/uikit_rails/templates/components/alert_dialog/component.html.erb +27 -0
- data/lib/uikit_rails/templates/components/alert_dialog/component.rb +23 -0
- data/lib/uikit_rails/templates/components/alert_dialog/preview.yml +94 -0
- data/lib/uikit_rails/templates/components/avatar/USAGE +20 -0
- data/lib/uikit_rails/templates/components/avatar/avatar.css +53 -0
- data/lib/uikit_rails/templates/components/avatar/component.html.erb +7 -0
- data/lib/uikit_rails/templates/components/avatar/component.rb +31 -0
- data/lib/uikit_rails/templates/components/avatar/preview.yml +42 -0
- data/lib/uikit_rails/templates/components/badge/USAGE +13 -0
- data/lib/uikit_rails/templates/components/badge/badge.css +61 -0
- data/lib/uikit_rails/templates/components/badge/component.rb +28 -0
- data/lib/uikit_rails/templates/components/badge/preview.yml +38 -0
- data/lib/uikit_rails/templates/components/breadcrumb/USAGE +23 -0
- data/lib/uikit_rails/templates/components/breadcrumb/breadcrumb.css +55 -0
- data/lib/uikit_rails/templates/components/breadcrumb/component.html.erb +14 -0
- data/lib/uikit_rails/templates/components/breadcrumb/component.rb +40 -0
- data/lib/uikit_rails/templates/components/breadcrumb/preview.yml +42 -0
- data/lib/uikit_rails/templates/components/button/USAGE +21 -0
- data/lib/uikit_rails/templates/components/button/button.css +125 -0
- data/lib/uikit_rails/templates/components/button/component.rb +44 -0
- data/lib/uikit_rails/templates/components/button/preview.yml +106 -0
- data/lib/uikit_rails/templates/components/card/USAGE +33 -0
- data/lib/uikit_rails/templates/components/card/card.css +63 -0
- data/lib/uikit_rails/templates/components/card/component.html.erb +16 -0
- data/lib/uikit_rails/templates/components/card/component.rb +26 -0
- data/lib/uikit_rails/templates/components/card/preview.yml +57 -0
- data/lib/uikit_rails/templates/components/checkbox/USAGE +19 -0
- data/lib/uikit_rails/templates/components/checkbox/checkbox.css +67 -0
- data/lib/uikit_rails/templates/components/checkbox/component.html.erb +6 -0
- data/lib/uikit_rails/templates/components/checkbox/component.rb +26 -0
- data/lib/uikit_rails/templates/components/checkbox/preview.yml +43 -0
- data/lib/uikit_rails/templates/components/collapsible/USAGE +31 -0
- data/lib/uikit_rails/templates/components/collapsible/collapsible.css +55 -0
- data/lib/uikit_rails/templates/components/collapsible/component.html.erb +8 -0
- data/lib/uikit_rails/templates/components/collapsible/component.rb +18 -0
- data/lib/uikit_rails/templates/components/collapsible/preview.yml +65 -0
- data/lib/uikit_rails/templates/components/dialog/USAGE +41 -0
- data/lib/uikit_rails/templates/components/dialog/component.html.erb +23 -0
- data/lib/uikit_rails/templates/components/dialog/component.rb +20 -0
- data/lib/uikit_rails/templates/components/dialog/dialog.css +133 -0
- data/lib/uikit_rails/templates/components/dialog/preview.yml +77 -0
- data/lib/uikit_rails/templates/components/dropdown/USAGE +40 -0
- data/lib/uikit_rails/templates/components/dropdown/component.html.erb +14 -0
- data/lib/uikit_rails/templates/components/dropdown/component.rb +62 -0
- data/lib/uikit_rails/templates/components/dropdown/dropdown.css +104 -0
- data/lib/uikit_rails/templates/components/dropdown/preview.yml +75 -0
- data/lib/uikit_rails/templates/components/input/USAGE +21 -0
- data/lib/uikit_rails/templates/components/input/component.rb +25 -0
- data/lib/uikit_rails/templates/components/input/input.css +43 -0
- data/lib/uikit_rails/templates/components/input/preview.yml +58 -0
- data/lib/uikit_rails/templates/components/label/USAGE +16 -0
- data/lib/uikit_rails/templates/components/label/component.rb +25 -0
- data/lib/uikit_rails/templates/components/label/label.css +25 -0
- data/lib/uikit_rails/templates/components/label/preview.yml +34 -0
- data/lib/uikit_rails/templates/components/pagination/USAGE +45 -0
- data/lib/uikit_rails/templates/components/pagination/component.html.erb +7 -0
- data/lib/uikit_rails/templates/components/pagination/component.rb +90 -0
- data/lib/uikit_rails/templates/components/pagination/pagination.css +89 -0
- data/lib/uikit_rails/templates/components/pagination/preview.yml +61 -0
- data/lib/uikit_rails/templates/components/popover/USAGE +44 -0
- data/lib/uikit_rails/templates/components/popover/component.html.erb +8 -0
- data/lib/uikit_rails/templates/components/popover/component.rb +19 -0
- data/lib/uikit_rails/templates/components/popover/popover.css +94 -0
- data/lib/uikit_rails/templates/components/popover/preview.yml +102 -0
- data/lib/uikit_rails/templates/components/progress/USAGE +15 -0
- data/lib/uikit_rails/templates/components/progress/component.html.erb +3 -0
- data/lib/uikit_rails/templates/components/progress/component.rb +38 -0
- data/lib/uikit_rails/templates/components/progress/preview.yml +44 -0
- data/lib/uikit_rails/templates/components/progress/progress.css +20 -0
- data/lib/uikit_rails/templates/components/select/USAGE +19 -0
- data/lib/uikit_rails/templates/components/select/component.rb +38 -0
- data/lib/uikit_rails/templates/components/select/preview.yml +61 -0
- data/lib/uikit_rails/templates/components/select/select.css +46 -0
- data/lib/uikit_rails/templates/components/separator/USAGE +15 -0
- data/lib/uikit_rails/templates/components/separator/component.rb +34 -0
- data/lib/uikit_rails/templates/components/separator/preview.yml +32 -0
- data/lib/uikit_rails/templates/components/separator/separator.css +21 -0
- data/lib/uikit_rails/templates/components/sheet/USAGE +44 -0
- data/lib/uikit_rails/templates/components/sheet/component.html.erb +23 -0
- data/lib/uikit_rails/templates/components/sheet/component.rb +23 -0
- data/lib/uikit_rails/templates/components/sheet/preview.yml +105 -0
- data/lib/uikit_rails/templates/components/sheet/sheet.css +193 -0
- data/lib/uikit_rails/templates/components/skeleton/USAGE +19 -0
- data/lib/uikit_rails/templates/components/skeleton/component.rb +38 -0
- data/lib/uikit_rails/templates/components/skeleton/preview.yml +44 -0
- data/lib/uikit_rails/templates/components/skeleton/skeleton.css +25 -0
- data/lib/uikit_rails/templates/components/switch/USAGE +19 -0
- data/lib/uikit_rails/templates/components/switch/component.html.erb +19 -0
- data/lib/uikit_rails/templates/components/switch/component.rb +23 -0
- data/lib/uikit_rails/templates/components/switch/preview.yml +43 -0
- data/lib/uikit_rails/templates/components/switch/switch.css +81 -0
- data/lib/uikit_rails/templates/components/table/USAGE +40 -0
- data/lib/uikit_rails/templates/components/table/component.html.erb +14 -0
- data/lib/uikit_rails/templates/components/table/component.rb +25 -0
- data/lib/uikit_rails/templates/components/table/preview.yml +109 -0
- data/lib/uikit_rails/templates/components/table/table.css +86 -0
- data/lib/uikit_rails/templates/components/tabs/USAGE +24 -0
- data/lib/uikit_rails/templates/components/tabs/component.html.erb +10 -0
- data/lib/uikit_rails/templates/components/tabs/component.rb +35 -0
- data/lib/uikit_rails/templates/components/tabs/preview.yml +60 -0
- data/lib/uikit_rails/templates/components/tabs/tabs.css +72 -0
- data/lib/uikit_rails/templates/components/textarea/USAGE +19 -0
- data/lib/uikit_rails/templates/components/textarea/component.rb +25 -0
- data/lib/uikit_rails/templates/components/textarea/preview.yml +47 -0
- data/lib/uikit_rails/templates/components/textarea/textarea.css +39 -0
- data/lib/uikit_rails/templates/components/toggle/USAGE +25 -0
- data/lib/uikit_rails/templates/components/toggle/component.rb +39 -0
- data/lib/uikit_rails/templates/components/toggle/preview.yml +81 -0
- data/lib/uikit_rails/templates/components/toggle/toggle.css +89 -0
- data/lib/uikit_rails/templates/components/tooltip/USAGE +23 -0
- data/lib/uikit_rails/templates/components/tooltip/component.html.erb +8 -0
- data/lib/uikit_rails/templates/components/tooltip/component.rb +19 -0
- data/lib/uikit_rails/templates/components/tooltip/preview.yml +52 -0
- data/lib/uikit_rails/templates/components/tooltip/tooltip.css +78 -0
- data/lib/uikit_rails/templates/stimulus/accordion_controller.js +19 -0
- data/lib/uikit_rails/templates/stimulus/alert_dialog_controller.js +25 -0
- data/lib/uikit_rails/templates/stimulus/collapsible_controller.js +9 -0
- data/lib/uikit_rails/templates/stimulus/dialog_controller.js +19 -0
- data/lib/uikit_rails/templates/stimulus/dropdown_controller.js +47 -0
- data/lib/uikit_rails/templates/stimulus/popover_controller.js +47 -0
- data/lib/uikit_rails/templates/stimulus/sheet_controller.js +19 -0
- data/lib/uikit_rails/templates/stimulus/tabs_controller.js +24 -0
- data/lib/uikit_rails/templates/stimulus/tooltip_controller.js +13 -0
- data/lib/uikit_rails/version.rb +5 -0
- data/lib/uikit_rails.rb +58 -0
- data/sig/uikit_rails.rbs +4 -0
- data/test_app/.dockerignore +51 -0
- data/test_app/.gitattributes +9 -0
- data/test_app/.github/dependabot.yml +12 -0
- data/test_app/.github/workflows/ci.yml +124 -0
- data/test_app/.gitignore +35 -0
- data/test_app/.kamal/hooks/docker-setup.sample +3 -0
- data/test_app/.kamal/hooks/post-app-boot.sample +3 -0
- data/test_app/.kamal/hooks/post-deploy.sample +14 -0
- data/test_app/.kamal/hooks/post-proxy-reboot.sample +3 -0
- data/test_app/.kamal/hooks/pre-app-boot.sample +3 -0
- data/test_app/.kamal/hooks/pre-build.sample +51 -0
- data/test_app/.kamal/hooks/pre-connect.sample +47 -0
- data/test_app/.kamal/hooks/pre-deploy.sample +122 -0
- data/test_app/.kamal/hooks/pre-proxy-reboot.sample +3 -0
- data/test_app/.kamal/secrets +20 -0
- data/test_app/.rubocop.yml +8 -0
- data/test_app/.ruby-version +1 -0
- data/test_app/Dockerfile +77 -0
- data/test_app/Gemfile +68 -0
- data/test_app/Gemfile.lock +587 -0
- data/test_app/README.md +24 -0
- data/test_app/Rakefile +6 -0
- data/test_app/app/assets/images/.keep +0 -0
- data/test_app/app/assets/stylesheets/application.css +10 -0
- data/test_app/app/assets/stylesheets/ui/accordion.css +74 -0
- data/test_app/app/assets/stylesheets/ui/alert.css +60 -0
- data/test_app/app/assets/stylesheets/ui/alert_dialog.css +108 -0
- data/test_app/app/assets/stylesheets/ui/avatar.css +53 -0
- data/test_app/app/assets/stylesheets/ui/badge.css +61 -0
- data/test_app/app/assets/stylesheets/ui/breadcrumb.css +55 -0
- data/test_app/app/assets/stylesheets/ui/button.css +125 -0
- data/test_app/app/assets/stylesheets/ui/card.css +63 -0
- data/test_app/app/assets/stylesheets/ui/checkbox.css +67 -0
- data/test_app/app/assets/stylesheets/ui/collapsible.css +55 -0
- data/test_app/app/assets/stylesheets/ui/dialog.css +133 -0
- data/test_app/app/assets/stylesheets/ui/dropdown.css +104 -0
- data/test_app/app/assets/stylesheets/ui/input.css +43 -0
- data/test_app/app/assets/stylesheets/ui/label.css +25 -0
- data/test_app/app/assets/stylesheets/ui/pagination.css +89 -0
- data/test_app/app/assets/stylesheets/ui/popover.css +94 -0
- data/test_app/app/assets/stylesheets/ui/progress.css +20 -0
- data/test_app/app/assets/stylesheets/ui/select.css +46 -0
- data/test_app/app/assets/stylesheets/ui/separator.css +21 -0
- data/test_app/app/assets/stylesheets/ui/sheet.css +193 -0
- data/test_app/app/assets/stylesheets/ui/skeleton.css +25 -0
- data/test_app/app/assets/stylesheets/ui/switch.css +81 -0
- data/test_app/app/assets/stylesheets/ui/table.css +86 -0
- data/test_app/app/assets/stylesheets/ui/tabs.css +72 -0
- data/test_app/app/assets/stylesheets/ui/textarea.css +39 -0
- data/test_app/app/assets/stylesheets/ui/toggle.css +89 -0
- data/test_app/app/assets/stylesheets/ui/tooltip.css +78 -0
- data/test_app/app/assets/stylesheets/uikit_rails.css +69 -0
- data/test_app/app/components/ui/accordion/component.html.erb +13 -0
- data/test_app/app/components/ui/accordion/component.rb +35 -0
- data/test_app/app/components/ui/accordion/preview.yml +81 -0
- data/test_app/app/components/ui/alert/component.html.erb +9 -0
- data/test_app/app/components/ui/alert/component.rb +27 -0
- data/test_app/app/components/ui/alert/preview.yml +53 -0
- data/test_app/app/components/ui/alert_dialog/component.html.erb +27 -0
- data/test_app/app/components/ui/alert_dialog/component.rb +23 -0
- data/test_app/app/components/ui/alert_dialog/preview.yml +94 -0
- data/test_app/app/components/ui/avatar/component.html.erb +7 -0
- data/test_app/app/components/ui/avatar/component.rb +31 -0
- data/test_app/app/components/ui/avatar/preview.yml +42 -0
- data/test_app/app/components/ui/badge/component.rb +28 -0
- data/test_app/app/components/ui/badge/preview.yml +38 -0
- data/test_app/app/components/ui/base_component.rb +32 -0
- data/test_app/app/components/ui/breadcrumb/component.html.erb +14 -0
- data/test_app/app/components/ui/breadcrumb/component.rb +40 -0
- data/test_app/app/components/ui/breadcrumb/preview.yml +42 -0
- data/test_app/app/components/ui/button/component.rb +44 -0
- data/test_app/app/components/ui/button/preview.yml +106 -0
- data/test_app/app/components/ui/card/component.html.erb +16 -0
- data/test_app/app/components/ui/card/component.rb +26 -0
- data/test_app/app/components/ui/card/preview.yml +57 -0
- data/test_app/app/components/ui/checkbox/component.html.erb +6 -0
- data/test_app/app/components/ui/checkbox/component.rb +26 -0
- data/test_app/app/components/ui/checkbox/preview.yml +43 -0
- data/test_app/app/components/ui/collapsible/component.html.erb +8 -0
- data/test_app/app/components/ui/collapsible/component.rb +18 -0
- data/test_app/app/components/ui/collapsible/preview.yml +65 -0
- data/test_app/app/components/ui/dialog/component.html.erb +23 -0
- data/test_app/app/components/ui/dialog/component.rb +20 -0
- data/test_app/app/components/ui/dialog/preview.yml +77 -0
- data/test_app/app/components/ui/dropdown/component.html.erb +14 -0
- data/test_app/app/components/ui/dropdown/component.rb +62 -0
- data/test_app/app/components/ui/dropdown/preview.yml +75 -0
- data/test_app/app/components/ui/input/component.rb +25 -0
- data/test_app/app/components/ui/input/preview.yml +58 -0
- data/test_app/app/components/ui/label/component.rb +25 -0
- data/test_app/app/components/ui/label/preview.yml +34 -0
- data/test_app/app/components/ui/pagination/component.html.erb +7 -0
- data/test_app/app/components/ui/pagination/component.rb +90 -0
- data/test_app/app/components/ui/pagination/preview.yml +61 -0
- data/test_app/app/components/ui/popover/component.html.erb +8 -0
- data/test_app/app/components/ui/popover/component.rb +19 -0
- data/test_app/app/components/ui/popover/preview.yml +102 -0
- data/test_app/app/components/ui/progress/component.html.erb +3 -0
- data/test_app/app/components/ui/progress/component.rb +38 -0
- data/test_app/app/components/ui/progress/preview.yml +44 -0
- data/test_app/app/components/ui/select/component.rb +38 -0
- data/test_app/app/components/ui/select/preview.yml +61 -0
- data/test_app/app/components/ui/separator/component.rb +34 -0
- data/test_app/app/components/ui/separator/preview.yml +32 -0
- data/test_app/app/components/ui/sheet/component.html.erb +23 -0
- data/test_app/app/components/ui/sheet/component.rb +23 -0
- data/test_app/app/components/ui/sheet/preview.yml +105 -0
- data/test_app/app/components/ui/skeleton/component.rb +38 -0
- data/test_app/app/components/ui/skeleton/preview.yml +44 -0
- data/test_app/app/components/ui/switch/component.html.erb +19 -0
- data/test_app/app/components/ui/switch/component.rb +23 -0
- data/test_app/app/components/ui/switch/preview.yml +43 -0
- data/test_app/app/components/ui/table/component.html.erb +14 -0
- data/test_app/app/components/ui/table/component.rb +25 -0
- data/test_app/app/components/ui/table/preview.yml +109 -0
- data/test_app/app/components/ui/tabs/component.html.erb +10 -0
- data/test_app/app/components/ui/tabs/component.rb +35 -0
- data/test_app/app/components/ui/tabs/preview.yml +60 -0
- data/test_app/app/components/ui/textarea/component.rb +25 -0
- data/test_app/app/components/ui/textarea/preview.yml +47 -0
- data/test_app/app/components/ui/toggle/component.rb +39 -0
- data/test_app/app/components/ui/toggle/preview.yml +81 -0
- data/test_app/app/components/ui/tooltip/component.html.erb +8 -0
- data/test_app/app/components/ui/tooltip/component.rb +19 -0
- data/test_app/app/components/ui/tooltip/preview.yml +52 -0
- data/test_app/app/controllers/application_controller.rb +7 -0
- data/test_app/app/controllers/concerns/.keep +0 -0
- data/test_app/app/helpers/application_helper.rb +2 -0
- data/test_app/app/javascript/application.js +3 -0
- data/test_app/app/javascript/controllers/application.js +9 -0
- data/test_app/app/javascript/controllers/hello_controller.js +7 -0
- data/test_app/app/javascript/controllers/index.js +4 -0
- data/test_app/app/javascript/controllers/ui/accordion_controller.js +19 -0
- data/test_app/app/javascript/controllers/ui/alert_dialog_controller.js +25 -0
- data/test_app/app/javascript/controllers/ui/collapsible_controller.js +9 -0
- data/test_app/app/javascript/controllers/ui/dialog_controller.js +19 -0
- data/test_app/app/javascript/controllers/ui/dropdown_controller.js +47 -0
- data/test_app/app/javascript/controllers/ui/popover_controller.js +47 -0
- data/test_app/app/javascript/controllers/ui/sheet_controller.js +19 -0
- data/test_app/app/javascript/controllers/ui/tabs_controller.js +24 -0
- data/test_app/app/javascript/controllers/ui/tooltip_controller.js +13 -0
- data/test_app/app/jobs/application_job.rb +7 -0
- data/test_app/app/mailers/application_mailer.rb +4 -0
- data/test_app/app/models/application_record.rb +3 -0
- data/test_app/app/models/concerns/.keep +0 -0
- data/test_app/app/views/layouts/application.html.erb +29 -0
- data/test_app/app/views/layouts/mailer.html.erb +13 -0
- data/test_app/app/views/layouts/mailer.text.erb +1 -0
- data/test_app/app/views/pwa/manifest.json.erb +22 -0
- data/test_app/app/views/pwa/service-worker.js +26 -0
- data/test_app/bin/brakeman +7 -0
- data/test_app/bin/bundler-audit +6 -0
- data/test_app/bin/ci +6 -0
- data/test_app/bin/dev +2 -0
- data/test_app/bin/docker-entrypoint +8 -0
- data/test_app/bin/importmap +4 -0
- data/test_app/bin/jobs +6 -0
- data/test_app/bin/kamal +16 -0
- data/test_app/bin/rails +4 -0
- data/test_app/bin/rake +4 -0
- data/test_app/bin/rubocop +8 -0
- data/test_app/bin/setup +35 -0
- data/test_app/bin/thrust +5 -0
- data/test_app/config/application.rb +27 -0
- data/test_app/config/boot.rb +4 -0
- data/test_app/config/bundler-audit.yml +5 -0
- data/test_app/config/cable.yml +17 -0
- data/test_app/config/cache.yml +16 -0
- data/test_app/config/ci.rb +24 -0
- data/test_app/config/credentials.yml.enc +1 -0
- data/test_app/config/database.yml +40 -0
- data/test_app/config/deploy.yml +119 -0
- data/test_app/config/environment.rb +5 -0
- data/test_app/config/environments/development.rb +78 -0
- data/test_app/config/environments/production.rb +90 -0
- data/test_app/config/environments/test.rb +53 -0
- data/test_app/config/importmap.rb +7 -0
- data/test_app/config/initializers/assets.rb +7 -0
- data/test_app/config/initializers/content_security_policy.rb +29 -0
- data/test_app/config/initializers/filter_parameter_logging.rb +8 -0
- data/test_app/config/initializers/inflections.rb +16 -0
- data/test_app/config/locales/en.yml +31 -0
- data/test_app/config/puma.rb +42 -0
- data/test_app/config/queue.yml +18 -0
- data/test_app/config/recurring.yml +15 -0
- data/test_app/config/routes.rb +13 -0
- data/test_app/config/storage.yml +27 -0
- data/test_app/config.ru +6 -0
- data/test_app/db/cable_schema.rb +11 -0
- data/test_app/db/cache_schema.rb +12 -0
- data/test_app/db/queue_schema.rb +129 -0
- data/test_app/db/seeds.rb +9 -0
- data/test_app/lib/tasks/.keep +0 -0
- data/test_app/log/.keep +0 -0
- data/test_app/public/400.html +135 -0
- data/test_app/public/404.html +135 -0
- data/test_app/public/406-unsupported-browser.html +135 -0
- data/test_app/public/422.html +135 -0
- data/test_app/public/500.html +135 -0
- data/test_app/public/icon.png +0 -0
- data/test_app/public/icon.svg +3 -0
- data/test_app/public/robots.txt +1 -0
- data/test_app/script/.keep +0 -0
- data/test_app/storage/.keep +0 -0
- data/test_app/test/controllers/.keep +0 -0
- data/test_app/test/fixtures/files/.keep +0 -0
- data/test_app/test/helpers/.keep +0 -0
- data/test_app/test/integration/.keep +0 -0
- data/test_app/test/mailers/.keep +0 -0
- data/test_app/test/models/.keep +0 -0
- data/test_app/test/test_helper.rb +15 -0
- data/test_app/tmp/.keep +0 -0
- data/test_app/tmp/pids/.keep +0 -0
- data/test_app/tmp/storage/.keep +0 -0
- data/test_app/vendor/.keep +0 -0
- data/test_app/vendor/javascript/.keep +0 -0
- metadata +438 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ui
|
|
4
|
+
module Dropdown
|
|
5
|
+
# Dropdown menu triggered by a button.
|
|
6
|
+
class Component < Ui::BaseComponent
|
|
7
|
+
renders_one :trigger
|
|
8
|
+
renders_many :items, types: {
|
|
9
|
+
item: { renders: ->(**attrs, &block) { Item.new(**attrs, &block) }, as: :item },
|
|
10
|
+
separator: { renders: -> { SeparatorItem.new }, as: :separator },
|
|
11
|
+
label: { renders: ->(**attrs, &block) { LabelItem.new(**attrs, &block) }, as: :label }
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
attr_reader :align, :html_attrs
|
|
15
|
+
|
|
16
|
+
def initialize(align: :start, **html_attrs)
|
|
17
|
+
@align = align.to_sym
|
|
18
|
+
@html_attrs = html_attrs
|
|
19
|
+
super()
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def align_class
|
|
23
|
+
"ui-dropdown__menu--#{align}"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
class Item < Ui::BaseComponent
|
|
27
|
+
attr_reader :href, :html_attrs
|
|
28
|
+
|
|
29
|
+
def initialize(href: nil, **html_attrs)
|
|
30
|
+
@href = href
|
|
31
|
+
@html_attrs = html_attrs
|
|
32
|
+
super()
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def call
|
|
36
|
+
tag_name = href ? :a : :div
|
|
37
|
+
attrs = merge_attrs({ class: "ui-dropdown__item", href: href, role: "menuitem" }.compact, html_attrs)
|
|
38
|
+
content_tag(tag_name, content, **attrs)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class SeparatorItem < Ui::BaseComponent
|
|
43
|
+
def call
|
|
44
|
+
tag.div(class: "ui-dropdown__separator", role: "separator")
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
class LabelItem < Ui::BaseComponent
|
|
49
|
+
attr_reader :html_attrs
|
|
50
|
+
|
|
51
|
+
def initialize(**html_attrs)
|
|
52
|
+
@html_attrs = html_attrs
|
|
53
|
+
super()
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def call
|
|
57
|
+
content_tag(:div, content, class: "ui-dropdown__label", **html_attrs)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
description: A dropdown menu triggered by a button. Supports items, separators, and labels. Uses Stimulus for toggling with outside-click and escape-key dismissal.
|
|
2
|
+
|
|
3
|
+
sections:
|
|
4
|
+
- title: Basic Dropdown
|
|
5
|
+
examples:
|
|
6
|
+
- title: Simple menu
|
|
7
|
+
code: |
|
|
8
|
+
<%= render Ui::Dropdown::Component.new do |dropdown| %>
|
|
9
|
+
<% dropdown.with_trigger do %>
|
|
10
|
+
<%= render Ui::Button::Component.new(variant: :outline) do %>Options<% end %>
|
|
11
|
+
<% end %>
|
|
12
|
+
<% dropdown.with_item do %>Profile<% end %>
|
|
13
|
+
<% dropdown.with_item do %>Settings<% end %>
|
|
14
|
+
<% dropdown.with_separator %>
|
|
15
|
+
<% dropdown.with_item do %>Log out<% end %>
|
|
16
|
+
<% end %>
|
|
17
|
+
|
|
18
|
+
- title: With Labels and Links
|
|
19
|
+
examples:
|
|
20
|
+
- title: Grouped items with label
|
|
21
|
+
code: |
|
|
22
|
+
<%= render Ui::Dropdown::Component.new do |dropdown| %>
|
|
23
|
+
<% dropdown.with_trigger do %>
|
|
24
|
+
<%= render Ui::Button::Component.new(variant: :outline) do %>My Account<% end %>
|
|
25
|
+
<% end %>
|
|
26
|
+
<% dropdown.with_label do %>Account<% end %>
|
|
27
|
+
<% dropdown.with_item(href: "/profile") do %>Profile<% end %>
|
|
28
|
+
<% dropdown.with_item(href: "/billing") do %>Billing<% end %>
|
|
29
|
+
<% dropdown.with_separator %>
|
|
30
|
+
<% dropdown.with_label do %>Team<% end %>
|
|
31
|
+
<% dropdown.with_item(href: "/team") do %>Members<% end %>
|
|
32
|
+
<% dropdown.with_item(href: "/team/settings") do %>Team Settings<% end %>
|
|
33
|
+
<% dropdown.with_separator %>
|
|
34
|
+
<% dropdown.with_item do %>Log out<% end %>
|
|
35
|
+
<% end %>
|
|
36
|
+
|
|
37
|
+
- title: Alignment
|
|
38
|
+
examples:
|
|
39
|
+
- title: Right-aligned menu
|
|
40
|
+
code: |
|
|
41
|
+
<div style="display:flex;justify-content:flex-end;">
|
|
42
|
+
<%= render Ui::Dropdown::Component.new(align: :end) do |dropdown| %>
|
|
43
|
+
<% dropdown.with_trigger do %>
|
|
44
|
+
<%= render Ui::Button::Component.new(variant: :secondary) do %>Actions ▾<% end %>
|
|
45
|
+
<% end %>
|
|
46
|
+
<% dropdown.with_item do %>Edit<% end %>
|
|
47
|
+
<% dropdown.with_item do %>Duplicate<% end %>
|
|
48
|
+
<% dropdown.with_separator %>
|
|
49
|
+
<% dropdown.with_item do %>Archive<% end %>
|
|
50
|
+
<% dropdown.with_item do %>Delete<% end %>
|
|
51
|
+
<% end %>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
- title: Left-aligned menu (default)
|
|
55
|
+
code: |
|
|
56
|
+
<%= render Ui::Dropdown::Component.new(align: :start) do |dropdown| %>
|
|
57
|
+
<% dropdown.with_trigger do %>
|
|
58
|
+
<%= render Ui::Button::Component.new(variant: :ghost) do %>Menu ▾<% end %>
|
|
59
|
+
<% end %>
|
|
60
|
+
<% dropdown.with_item do %>New File<% end %>
|
|
61
|
+
<% dropdown.with_item do %>Open<% end %>
|
|
62
|
+
<% dropdown.with_item do %>Save<% end %>
|
|
63
|
+
<% end %>
|
|
64
|
+
|
|
65
|
+
- title: Custom Attributes
|
|
66
|
+
examples:
|
|
67
|
+
- title: Dropdown with custom data attributes
|
|
68
|
+
code: |
|
|
69
|
+
<%= render Ui::Dropdown::Component.new(class: "my-dropdown", data: { turbo: false }) do |dropdown| %>
|
|
70
|
+
<% dropdown.with_trigger do %>
|
|
71
|
+
<%= render Ui::Button::Component.new do %>More<% end %>
|
|
72
|
+
<% end %>
|
|
73
|
+
<% dropdown.with_item(data: { action: "click->my-controller#export" }) do %>Export<% end %>
|
|
74
|
+
<% dropdown.with_item(data: { action: "click->my-controller#print" }) do %>Print<% end %>
|
|
75
|
+
<% end %>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ui
|
|
4
|
+
module Input
|
|
5
|
+
# Text input field with consistent styling.
|
|
6
|
+
class Component < Ui::BaseComponent
|
|
7
|
+
attr_reader :html_attrs
|
|
8
|
+
|
|
9
|
+
def initialize(**html_attrs)
|
|
10
|
+
@html_attrs = html_attrs
|
|
11
|
+
super()
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def call
|
|
15
|
+
tag.input(**computed_attrs)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def computed_attrs
|
|
21
|
+
merge_attrs({ class: "ui-input", type: "text" }, html_attrs)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
description: A styled text input field. Supports all standard HTML input attributes including type, placeholder, disabled, and name.
|
|
2
|
+
|
|
3
|
+
sections:
|
|
4
|
+
- title: Basic Usage
|
|
5
|
+
examples:
|
|
6
|
+
- title: Default text input
|
|
7
|
+
code: |
|
|
8
|
+
<%= render Ui::Input::Component.new(placeholder: "Enter your name") %>
|
|
9
|
+
|
|
10
|
+
- title: With name attribute
|
|
11
|
+
code: |
|
|
12
|
+
<%= render Ui::Input::Component.new(name: "email", placeholder: "you@example.com") %>
|
|
13
|
+
|
|
14
|
+
- title: Input Types
|
|
15
|
+
examples:
|
|
16
|
+
- title: Email
|
|
17
|
+
code: |
|
|
18
|
+
<%= render Ui::Input::Component.new(type: "email", placeholder: "you@example.com") %>
|
|
19
|
+
|
|
20
|
+
- title: Password
|
|
21
|
+
code: |
|
|
22
|
+
<%= render Ui::Input::Component.new(type: "password", placeholder: "••••••••") %>
|
|
23
|
+
|
|
24
|
+
- title: Number
|
|
25
|
+
code: |
|
|
26
|
+
<%= render Ui::Input::Component.new(type: "number", placeholder: "0", min: 0, max: 100) %>
|
|
27
|
+
|
|
28
|
+
- title: Search
|
|
29
|
+
code: |
|
|
30
|
+
<%= render Ui::Input::Component.new(type: "search", placeholder: "Search...") %>
|
|
31
|
+
|
|
32
|
+
- title: File
|
|
33
|
+
code: |
|
|
34
|
+
<%= render Ui::Input::Component.new(type: "file") %>
|
|
35
|
+
|
|
36
|
+
- title: States
|
|
37
|
+
examples:
|
|
38
|
+
- title: Disabled
|
|
39
|
+
code: |
|
|
40
|
+
<%= render Ui::Input::Component.new(placeholder: "Disabled input", disabled: true) %>
|
|
41
|
+
|
|
42
|
+
- title: With value
|
|
43
|
+
code: |
|
|
44
|
+
<%= render Ui::Input::Component.new(value: "Pre-filled value") %>
|
|
45
|
+
|
|
46
|
+
- title: Required
|
|
47
|
+
code: |
|
|
48
|
+
<%= render Ui::Input::Component.new(placeholder: "Required field", required: true) %>
|
|
49
|
+
|
|
50
|
+
- title: With Custom Attributes
|
|
51
|
+
examples:
|
|
52
|
+
- title: Custom class and data attributes
|
|
53
|
+
code: |
|
|
54
|
+
<%= render Ui::Input::Component.new(
|
|
55
|
+
placeholder: "Custom",
|
|
56
|
+
class: "my-custom-class",
|
|
57
|
+
data: { controller: "input-validator" }
|
|
58
|
+
) %>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ui
|
|
4
|
+
module Label
|
|
5
|
+
# Form label with consistent styling.
|
|
6
|
+
class Component < Ui::BaseComponent
|
|
7
|
+
attr_reader :html_attrs
|
|
8
|
+
|
|
9
|
+
def initialize(**html_attrs)
|
|
10
|
+
@html_attrs = html_attrs
|
|
11
|
+
super()
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def call
|
|
15
|
+
content_tag(:label, content, **computed_attrs)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def computed_attrs
|
|
21
|
+
merge_attrs({ class: "ui-label" }, html_attrs)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
description: A form label element with consistent styling. Accepts a `for` attribute to associate with an input.
|
|
2
|
+
|
|
3
|
+
sections:
|
|
4
|
+
- title: Basic Label
|
|
5
|
+
examples:
|
|
6
|
+
- title: Default
|
|
7
|
+
code: |
|
|
8
|
+
<%= render Ui::Label::Component.new do %>Email<% end %>
|
|
9
|
+
|
|
10
|
+
- title: With for attribute
|
|
11
|
+
code: |
|
|
12
|
+
<%= render Ui::Label::Component.new(for: "email") do %>Email address<% end %>
|
|
13
|
+
|
|
14
|
+
- title: Usage with Form Inputs
|
|
15
|
+
examples:
|
|
16
|
+
- title: Label with text input
|
|
17
|
+
code: |
|
|
18
|
+
<%= render Ui::Label::Component.new(for: "username") do %>Username<% end %>
|
|
19
|
+
<input type="text" id="username" name="username" />
|
|
20
|
+
|
|
21
|
+
- title: Label with required field
|
|
22
|
+
code: |
|
|
23
|
+
<%= render Ui::Label::Component.new(for: "password") do %>Password <span aria-hidden="true">*</span><% end %>
|
|
24
|
+
<input type="password" id="password" name="password" required />
|
|
25
|
+
|
|
26
|
+
- title: With Custom Attributes
|
|
27
|
+
examples:
|
|
28
|
+
- title: Custom class and data attributes
|
|
29
|
+
code: |
|
|
30
|
+
<%= render Ui::Label::Component.new(
|
|
31
|
+
for: "name",
|
|
32
|
+
class: "my-custom-label",
|
|
33
|
+
data: { required: true }
|
|
34
|
+
) do %>Full Name<% end %>
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ui
|
|
4
|
+
module Pagination
|
|
5
|
+
# Page navigation with previous, next, and page links.
|
|
6
|
+
class Component < Ui::BaseComponent
|
|
7
|
+
renders_many :items, types: {
|
|
8
|
+
page: { renders: lambda { |href: "#", active: false, **attrs|
|
|
9
|
+
PageItem.new(href: href, active: active, **attrs)
|
|
10
|
+
}, as: :page },
|
|
11
|
+
prev_page: { renders: lambda { |href: "#", disabled: false, **attrs|
|
|
12
|
+
PrevItem.new(href: href, disabled: disabled, **attrs)
|
|
13
|
+
}, as: :prev_page },
|
|
14
|
+
next_page: { renders: lambda { |href: "#", disabled: false, **attrs|
|
|
15
|
+
NextItem.new(href: href, disabled: disabled, **attrs)
|
|
16
|
+
}, as: :next_page },
|
|
17
|
+
ellipsis: { renders: -> { EllipsisItem.new }, as: :ellipsis }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
attr_reader :html_attrs
|
|
21
|
+
|
|
22
|
+
def initialize(**html_attrs)
|
|
23
|
+
@html_attrs = html_attrs
|
|
24
|
+
super()
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
class PageItem < Ui::BaseComponent
|
|
28
|
+
attr_reader :href, :active, :html_attrs
|
|
29
|
+
|
|
30
|
+
def initialize(href: "#", active: false, **html_attrs)
|
|
31
|
+
@href = href
|
|
32
|
+
@active = active
|
|
33
|
+
@html_attrs = html_attrs
|
|
34
|
+
super()
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def call
|
|
38
|
+
content_tag(:a, content, class: class_names("ui-pagination__item", "ui-pagination__item--active": active),
|
|
39
|
+
href: href, "aria-current": ("page" if active), **html_attrs)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class PrevItem < Ui::BaseComponent
|
|
44
|
+
attr_reader :href, :disabled, :html_attrs
|
|
45
|
+
|
|
46
|
+
def initialize(href: "#", disabled: false, **html_attrs)
|
|
47
|
+
@href = href
|
|
48
|
+
@disabled = disabled
|
|
49
|
+
@html_attrs = html_attrs
|
|
50
|
+
super()
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def call
|
|
54
|
+
classes = class_names("ui-pagination__item ui-pagination__prev", "ui-pagination__item--disabled": disabled)
|
|
55
|
+
if disabled
|
|
56
|
+
content_tag(:span, content.presence || "Previous", class: classes, "aria-disabled": "true", **html_attrs)
|
|
57
|
+
else
|
|
58
|
+
content_tag(:a, content.presence || "Previous", class: classes, href: href, **html_attrs)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
class NextItem < Ui::BaseComponent
|
|
64
|
+
attr_reader :href, :disabled, :html_attrs
|
|
65
|
+
|
|
66
|
+
def initialize(href: "#", disabled: false, **html_attrs)
|
|
67
|
+
@href = href
|
|
68
|
+
@disabled = disabled
|
|
69
|
+
@html_attrs = html_attrs
|
|
70
|
+
super()
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def call
|
|
74
|
+
classes = class_names("ui-pagination__item ui-pagination__next", "ui-pagination__item--disabled": disabled)
|
|
75
|
+
if disabled
|
|
76
|
+
content_tag(:span, content.presence || "Next", class: classes, "aria-disabled": "true", **html_attrs)
|
|
77
|
+
else
|
|
78
|
+
content_tag(:a, content.presence || "Next", class: classes, href: href, **html_attrs)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
class EllipsisItem < Ui::BaseComponent
|
|
84
|
+
def call
|
|
85
|
+
content_tag(:span, "…", class: "ui-pagination__ellipsis")
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
description: Page navigation with previous/next buttons, page numbers, and ellipsis indicators. Compose the pagination using slot items for full flexibility.
|
|
2
|
+
|
|
3
|
+
sections:
|
|
4
|
+
- title: Basic Pagination
|
|
5
|
+
examples:
|
|
6
|
+
- title: Simple page navigation
|
|
7
|
+
code: |
|
|
8
|
+
<%= render Ui::Pagination::Component.new do |pg| %>
|
|
9
|
+
<% pg.with_prev_page(href: "/page/1") %>
|
|
10
|
+
<% pg.with_page(href: "/page/1") do %>1<% end %>
|
|
11
|
+
<% pg.with_page(href: "/page/2", active: true) do %>2<% end %>
|
|
12
|
+
<% pg.with_page(href: "/page/3") do %>3<% end %>
|
|
13
|
+
<% pg.with_next_page(href: "/page/3") %>
|
|
14
|
+
<% end %>
|
|
15
|
+
|
|
16
|
+
- title: With Ellipsis
|
|
17
|
+
examples:
|
|
18
|
+
- title: Many pages with ellipsis
|
|
19
|
+
code: |
|
|
20
|
+
<%= render Ui::Pagination::Component.new do |pg| %>
|
|
21
|
+
<% pg.with_prev_page(href: "/page/3") %>
|
|
22
|
+
<% pg.with_page(href: "/page/1") do %>1<% end %>
|
|
23
|
+
<% pg.with_ellipsis %>
|
|
24
|
+
<% pg.with_page(href: "/page/3") do %>3<% end %>
|
|
25
|
+
<% pg.with_page(href: "/page/4", active: true) do %>4<% end %>
|
|
26
|
+
<% pg.with_page(href: "/page/5") do %>5<% end %>
|
|
27
|
+
<% pg.with_ellipsis %>
|
|
28
|
+
<% pg.with_page(href: "/page/10") do %>10<% end %>
|
|
29
|
+
<% pg.with_next_page(href: "/page/5") %>
|
|
30
|
+
<% end %>
|
|
31
|
+
|
|
32
|
+
- title: Disabled States
|
|
33
|
+
examples:
|
|
34
|
+
- title: First page (previous disabled)
|
|
35
|
+
code: |
|
|
36
|
+
<%= render Ui::Pagination::Component.new do |pg| %>
|
|
37
|
+
<% pg.with_prev_page(disabled: true) %>
|
|
38
|
+
<% pg.with_page(href: "/page/1", active: true) do %>1<% end %>
|
|
39
|
+
<% pg.with_page(href: "/page/2") do %>2<% end %>
|
|
40
|
+
<% pg.with_page(href: "/page/3") do %>3<% end %>
|
|
41
|
+
<% pg.with_next_page(href: "/page/2") %>
|
|
42
|
+
<% end %>
|
|
43
|
+
|
|
44
|
+
- title: Last page (next disabled)
|
|
45
|
+
code: |
|
|
46
|
+
<%= render Ui::Pagination::Component.new do |pg| %>
|
|
47
|
+
<% pg.with_prev_page(href: "/page/4") %>
|
|
48
|
+
<% pg.with_page(href: "/page/3") do %>3<% end %>
|
|
49
|
+
<% pg.with_page(href: "/page/4") do %>4<% end %>
|
|
50
|
+
<% pg.with_page(href: "/page/5", active: true) do %>5<% end %>
|
|
51
|
+
<% pg.with_next_page(disabled: true) %>
|
|
52
|
+
<% end %>
|
|
53
|
+
|
|
54
|
+
- title: Prev/Next Only
|
|
55
|
+
examples:
|
|
56
|
+
- title: Without page numbers
|
|
57
|
+
code: |
|
|
58
|
+
<%= render Ui::Pagination::Component.new do |pg| %>
|
|
59
|
+
<% pg.with_prev_page(href: "/page/2") do %>← Older<% end %>
|
|
60
|
+
<% pg.with_next_page(href: "/page/4") do %>Newer →<% end %>
|
|
61
|
+
<% end %>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<div data-controller="ui--popover" class="ui-popover" <%= tag.attributes(html_attrs) %>>
|
|
2
|
+
<% if trigger? %>
|
|
3
|
+
<div data-action="click->ui--popover#toggle" class="ui-popover__trigger"><%= trigger %></div>
|
|
4
|
+
<% end %>
|
|
5
|
+
<div data-ui--popover-target="content" class="ui-popover__content ui-popover__content--<%= side %> ui-popover__content--<%= align %>">
|
|
6
|
+
<%= content %>
|
|
7
|
+
</div>
|
|
8
|
+
</div>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ui
|
|
4
|
+
module Popover
|
|
5
|
+
# Floating content panel triggered by click.
|
|
6
|
+
class Component < Ui::BaseComponent
|
|
7
|
+
renders_one :trigger
|
|
8
|
+
|
|
9
|
+
attr_reader :align, :side, :html_attrs
|
|
10
|
+
|
|
11
|
+
def initialize(align: :center, side: :bottom, **html_attrs)
|
|
12
|
+
@align = align.to_sym
|
|
13
|
+
@side = side.to_sym
|
|
14
|
+
@html_attrs = html_attrs
|
|
15
|
+
super()
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
description: A floating content panel that appears on click. Unlike dropdowns which are for menu items, popovers are for richer content like forms, info panels, and settings. Supports side and alignment positioning.
|
|
2
|
+
|
|
3
|
+
sections:
|
|
4
|
+
- title: Basic Popover
|
|
5
|
+
examples:
|
|
6
|
+
- title: Default (bottom, center)
|
|
7
|
+
code: |
|
|
8
|
+
<%= render Ui::Popover::Component.new do |popover| %>
|
|
9
|
+
<% popover.with_trigger do %>
|
|
10
|
+
<%= render Ui::Button::Component.new(variant: :outline) do %>Open Popover<% end %>
|
|
11
|
+
<% end %>
|
|
12
|
+
<div style="display:flex;flex-direction:column;gap:0.5rem;">
|
|
13
|
+
<h4 style="margin:0;font-size:var(--ui-font-size-sm);font-weight:600;">Dimensions</h4>
|
|
14
|
+
<p style="margin:0;font-size:var(--ui-font-size-xs);color:var(--ui-muted-foreground);">Set the dimensions for the layer.</p>
|
|
15
|
+
<div style="display:flex;gap:0.5rem;">
|
|
16
|
+
<input type="text" placeholder="Width" style="flex:1;padding:0.375rem 0.5rem;border:1px solid var(--ui-border);border-radius:var(--ui-radius);font-size:var(--ui-font-size-sm);" />
|
|
17
|
+
<input type="text" placeholder="Height" style="flex:1;padding:0.375rem 0.5rem;border:1px solid var(--ui-border);border-radius:var(--ui-radius);font-size:var(--ui-font-size-sm);" />
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
<% end %>
|
|
21
|
+
|
|
22
|
+
- title: Alignment
|
|
23
|
+
examples:
|
|
24
|
+
- title: Align start
|
|
25
|
+
code: |
|
|
26
|
+
<%= render Ui::Popover::Component.new(align: :start) do |popover| %>
|
|
27
|
+
<% popover.with_trigger do %>
|
|
28
|
+
<%= render Ui::Button::Component.new(variant: :outline, size: :sm) do %>Align Start<% end %>
|
|
29
|
+
<% end %>
|
|
30
|
+
<p style="margin:0;">This popover is aligned to the start (left edge) of the trigger.</p>
|
|
31
|
+
<% end %>
|
|
32
|
+
|
|
33
|
+
- title: Align end
|
|
34
|
+
code: |
|
|
35
|
+
<div style="display:flex;justify-content:flex-end;">
|
|
36
|
+
<%= render Ui::Popover::Component.new(align: :end) do |popover| %>
|
|
37
|
+
<% popover.with_trigger do %>
|
|
38
|
+
<%= render Ui::Button::Component.new(variant: :outline, size: :sm) do %>Align End<% end %>
|
|
39
|
+
<% end %>
|
|
40
|
+
<p style="margin:0;">This popover is aligned to the end (right edge) of the trigger.</p>
|
|
41
|
+
<% end %>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
- title: Side Variants
|
|
45
|
+
examples:
|
|
46
|
+
- title: Top side
|
|
47
|
+
code: |
|
|
48
|
+
<div style="margin-top:12rem;">
|
|
49
|
+
<%= render Ui::Popover::Component.new(side: :top) do |popover| %>
|
|
50
|
+
<% popover.with_trigger do %>
|
|
51
|
+
<%= render Ui::Button::Component.new(variant: :outline) do %>Open Top<% end %>
|
|
52
|
+
<% end %>
|
|
53
|
+
<p style="margin:0;">This popover appears above the trigger.</p>
|
|
54
|
+
<% end %>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
- title: Top with start alignment
|
|
58
|
+
code: |
|
|
59
|
+
<div style="margin-top:12rem;">
|
|
60
|
+
<%= render Ui::Popover::Component.new(side: :top, align: :start) do |popover| %>
|
|
61
|
+
<% popover.with_trigger do %>
|
|
62
|
+
<%= render Ui::Button::Component.new(variant: :outline) do %>Top Start<% end %>
|
|
63
|
+
<% end %>
|
|
64
|
+
<p style="margin:0;">Appears above, aligned to the left edge.</p>
|
|
65
|
+
<% end %>
|
|
66
|
+
</div>
|
|
67
|
+
|
|
68
|
+
- title: Popover with Form Content
|
|
69
|
+
examples:
|
|
70
|
+
- title: Settings popover
|
|
71
|
+
code: |
|
|
72
|
+
<%= render Ui::Popover::Component.new(align: :start) do |popover| %>
|
|
73
|
+
<% popover.with_trigger do %>
|
|
74
|
+
<%= render Ui::Button::Component.new do %>Settings<% end %>
|
|
75
|
+
<% end %>
|
|
76
|
+
<div style="display:flex;flex-direction:column;gap:0.75rem;">
|
|
77
|
+
<h4 style="margin:0;font-size:var(--ui-font-size-sm);font-weight:600;">Layout Settings</h4>
|
|
78
|
+
<div>
|
|
79
|
+
<label style="font-size:var(--ui-font-size-xs);font-weight:500;">Grid columns</label>
|
|
80
|
+
<input type="number" value="3" min="1" max="6" style="width:100%;padding:0.375rem 0.5rem;border:1px solid var(--ui-border);border-radius:var(--ui-radius);font-size:var(--ui-font-size-sm);margin-top:0.25rem;" />
|
|
81
|
+
</div>
|
|
82
|
+
<div>
|
|
83
|
+
<label style="font-size:var(--ui-font-size-xs);font-weight:500;">Spacing</label>
|
|
84
|
+
<select style="width:100%;padding:0.375rem 0.5rem;border:1px solid var(--ui-border);border-radius:var(--ui-radius);font-size:var(--ui-font-size-sm);margin-top:0.25rem;">
|
|
85
|
+
<option>Compact</option>
|
|
86
|
+
<option selected>Comfortable</option>
|
|
87
|
+
<option>Spacious</option>
|
|
88
|
+
</select>
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
<% end %>
|
|
92
|
+
|
|
93
|
+
- title: Custom Attributes
|
|
94
|
+
examples:
|
|
95
|
+
- title: Popover with custom class
|
|
96
|
+
code: |
|
|
97
|
+
<%= render Ui::Popover::Component.new(class: "my-custom-popover", data: { turbo_frame: "settings" }) do |popover| %>
|
|
98
|
+
<% popover.with_trigger do %>
|
|
99
|
+
<%= render Ui::Button::Component.new(variant: :secondary) do %>Custom<% end %>
|
|
100
|
+
<% end %>
|
|
101
|
+
<p style="margin:0;">Popover with custom wrapper attributes.</p>
|
|
102
|
+
<% end %>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Ui
|
|
4
|
+
module Progress
|
|
5
|
+
# Progress bar showing completion percentage.
|
|
6
|
+
class Component < Ui::BaseComponent
|
|
7
|
+
attr_reader :value, :max, :html_attrs
|
|
8
|
+
|
|
9
|
+
def initialize(value: 0, max: 100, **html_attrs)
|
|
10
|
+
@value = value.to_i
|
|
11
|
+
@max = max.to_i
|
|
12
|
+
@html_attrs = html_attrs
|
|
13
|
+
super()
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def percentage
|
|
17
|
+
return 0 if max.zero?
|
|
18
|
+
|
|
19
|
+
[(value.to_f / max * 100).round, 100].min
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def computed_attrs
|
|
25
|
+
merge_attrs(
|
|
26
|
+
{
|
|
27
|
+
class: "ui-progress",
|
|
28
|
+
role: "progressbar",
|
|
29
|
+
"aria-valuenow": value,
|
|
30
|
+
"aria-valuemin": 0,
|
|
31
|
+
"aria-valuemax": max
|
|
32
|
+
},
|
|
33
|
+
html_attrs
|
|
34
|
+
)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
description: An accessible progress bar that visually indicates completion percentage. Includes ARIA attributes for screen readers and smooth width transitions.
|
|
2
|
+
|
|
3
|
+
sections:
|
|
4
|
+
- title: Basic Usage
|
|
5
|
+
examples:
|
|
6
|
+
- title: Empty (0%)
|
|
7
|
+
code: |
|
|
8
|
+
<%= render Ui::Progress::Component.new(value: 0) %>
|
|
9
|
+
|
|
10
|
+
- title: Partial (45%)
|
|
11
|
+
code: |
|
|
12
|
+
<%= render Ui::Progress::Component.new(value: 45) %>
|
|
13
|
+
|
|
14
|
+
- title: Complete (100%)
|
|
15
|
+
code: |
|
|
16
|
+
<%= render Ui::Progress::Component.new(value: 100) %>
|
|
17
|
+
|
|
18
|
+
- title: Custom Max
|
|
19
|
+
examples:
|
|
20
|
+
- title: 3 of 5 steps
|
|
21
|
+
code: |
|
|
22
|
+
<%= render Ui::Progress::Component.new(value: 3, max: 5) %>
|
|
23
|
+
|
|
24
|
+
- title: 7 of 10 items
|
|
25
|
+
code: |
|
|
26
|
+
<%= render Ui::Progress::Component.new(value: 7, max: 10) %>
|
|
27
|
+
|
|
28
|
+
- title: With Labels
|
|
29
|
+
examples:
|
|
30
|
+
- title: Progress with percentage label
|
|
31
|
+
code: |
|
|
32
|
+
<div style="display: flex; flex-direction: column; gap: 0.25rem;">
|
|
33
|
+
<div style="display: flex; justify-content: space-between; font-size: 0.875rem;">
|
|
34
|
+
<span>Uploading…</span>
|
|
35
|
+
<span>65%</span>
|
|
36
|
+
</div>
|
|
37
|
+
<%= render Ui::Progress::Component.new(value: 65) %>
|
|
38
|
+
</div>
|
|
39
|
+
|
|
40
|
+
- title: With Custom Attributes
|
|
41
|
+
examples:
|
|
42
|
+
- title: Custom class and data attributes
|
|
43
|
+
code: |
|
|
44
|
+
<%= render Ui::Progress::Component.new(value: 50, class: "my-progress", data: { controller: "upload" }) %>
|