diff --git a/.github/workflows/build_rails.yml b/.github/workflows/build_rails.yml deleted file mode 100644 index 69575af3..00000000 --- a/.github/workflows/build_rails.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Test superglue_rails -on: - push: - pull_request: - schedule: - - cron: "0 0 * * 0" - workflow_dispatch: - -jobs: - build: - name: Ruby ${{ matrix.ruby }}. Rails ${{ matrix.version }} - strategy: - fail-fast: false - matrix: - ruby: ["3.3", "3.2", "3.1"] - version: ["70", "71", "72", "80"] - exclude: - - ruby: 3.1 - version: 80 - runs-on: "ubuntu-latest" - - steps: - - uses: actions/checkout@v3 - - uses: actions/setup-node@v3 - with: - node-version: 18 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ matrix.ruby }} - - name: Which bundler? - working-directory: ./superglue_rails - run: bundle -v - - name: Using Gemfile - working-directory: ./superglue_rails - run: | - mv -f Gemfile.${{ matrix.version }} ./Gemfile - - name: Bundle install - working-directory: ./superglue_rails - run: bundle install - - name: Run unit test - working-directory: ./superglue_rails - run: bundle exec rake test - - name: Run acceptance test - working-directory: ./superglue_rails - run: BUNDLE_GEMFILE='' ruby -Ilib:test test/acceptance/superglue_installation_acceptance.rb diff --git a/.github/workflows/schedule_rails_main.yml b/.github/workflows/schedule_rails_main.yml deleted file mode 100644 index 5467425d..00000000 --- a/.github/workflows/schedule_rails_main.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Scheduled Rails Main - -on: - schedule: - - cron: '0 0 * * 4' - -jobs: - build: - name: Rails main - runs-on: ubuntu-latest - - strategy: - fail-fast: false - - steps: - - uses: actions/checkout@v4 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.3' - bundler-cache: true - - name: Using Gemfile - working-directory: ./superglue_rails - run: | - mv -f Gemfile.main ./Gemfile - - name: Bundle install - working-directory: ./superglue_rails - run: bundle install - - name: Run unit test - working-directory: ./superglue_rails - run: bundle exec rake test - - name: Run acceptance test - working-directory: ./superglue_rails - run: BUNDLE_GEMFILE='' ruby -Ilib:test test/acceptance/superglue_installation_acceptance.rb diff --git a/README.md b/README.md index c855f971..84850e92 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ Use classic Rails to build rich React Redux applications with **NO APIs** and **NO client-side routing**. [![Test superglue_js](https://github.com/thoughtbot/superglue/actions/workflows/build_js.yml/badge.svg)](https://github.com/thoughtbot/superglue/actions/workflows/build_js.yml) -[![Test superglue_rails](https://github.com/thoughtbot/superglue/actions/workflows/build_rails.yml/badge.svg)](https://github.com/thoughtbot/superglue/actions/workflows/build_rails.yml) Superglue makes React and Redux as productive as Hotwire, Turbo and Stimulus. Its inspired by Turbolinks and designed to feel like a natural extension of diff --git a/VERSION b/VERSION deleted file mode 100644 index 3eefcb9d..00000000 --- a/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.0.0 diff --git a/bin/prepare b/bin/prepare deleted file mode 100755 index 042814a3..00000000 --- a/bin/prepare +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env ruby - -version_str = ARGV[0] - -ROOT_DIR = File.expand_path('..', File.dirname(__FILE__)) -VERSION_FILE = File.join(ROOT_DIR, 'VERSION') -PACKAGE_JSON = File.join(ROOT_DIR, 'superglue/package.json') - -# Write new version to package.json -package_json = File.read(PACKAGE_JSON) -package_json.gsub!(/^.+version":.+$/, " \"version\": \"#{version_str}\",") -File.open(PACKAGE_JSON, 'w') {|f| f.write(package_json) } - -# Write new version to VERSION -File.open(VERSION_FILE, 'w') {|f| f.write(version_str) } -system("git add #{VERSION_FILE}") -system("git add #{PACKAGE_JSON}") -system("git commit -m 'Version bump to #{version_str}'") diff --git a/bin/release b/bin/release deleted file mode 100755 index 8f32a3db..00000000 --- a/bin/release +++ /dev/null @@ -1,88 +0,0 @@ -#!/usr/bin/env ruby - -ROOT_DIR = File.expand_path('..', File.dirname(__FILE__)) -VERSION_FILE = File.join(ROOT_DIR, 'VERSION') -SUPERGLUE_DIR = File.join(ROOT_DIR, 'superglue') -SUPERGLUE_RAILS_DIR = File.join(ROOT_DIR, 'superglue_rails') -PACKAGE_JSON = File.join(SUPERGLUE_DIR, 'package.json') - -def prompt_version - print "Enter the new version number (e.g., 1.0.0): " - version_str = gets.strip - if version_str.empty? - puts "Version number cannot be empty." - prompt_version - else - version_str - end -end - -def confirm_version(version_str) - print "Are you sure you want to release version #{version_str}? (y/n): " - confirmation = gets.strip.downcase - unless confirmation == 'y' - puts "Release aborted." - exit 1 - end -end - -def update_version_files(version_str) - # Update VERSION file - File.open(VERSION_FILE, 'w') { |f| f.write(version_str) } - - # Update package.json - package_json = File.read(PACKAGE_JSON) - package_json.gsub!(/^.+version":.+$/, " \"version\": \"#{version_str}\",") - File.open(PACKAGE_JSON, 'w') { |f| f.write(package_json) } - - # Commit changes - system("git add #{VERSION_FILE} #{PACKAGE_JSON}") - system("git commit -m 'Version bump to #{version_str}'") -end - -def run_tests - puts "Running tests..." - - Dir.chdir(SUPERGLUE_RAILS_DIR) do - if system("bundle exec rake test") - puts "Tests passed." - else - puts "Tests failed. Aborting release." - exit 1 - end - end -end - -def build_and_publish_gem(version_str) - Dir.chdir(SUPERGLUE_RAILS_DIR) do - system("gem build superglue.gemspec") - system("gem push superglue-#{version_str}.gem") - end -end - -def build_and_publish_npm_package - Dir.chdir(SUPERGLUE_DIR) do - system("npm run build") - end - - Dir.chdir("#{SUPERGLUE_DIR}/dist") do - system("npm publish") - end -end - -def tag_and_push_git(version_str) - system("git tag v#{version_str}") - system("git push origin v#{version_str}") - system("git push origin main") -end - -# Main release script -version_str = ARGV[0] || prompt_version -confirm_version(version_str) -update_version_files(version_str) -run_tests -build_and_publish_gem(version_str) -build_and_publish_npm_package -tag_and_push_git(version_str) - -puts "Release process completed successfully." diff --git a/superglue_rails/Gemfile b/superglue_rails/Gemfile deleted file mode 100644 index 1291856d..00000000 --- a/superglue_rails/Gemfile +++ /dev/null @@ -1,11 +0,0 @@ -source 'https://rubygems.org' -gemspec - -gem 'rails', '~> 7.2.0' -gem 'selenium-webdriver' -gem 'props_template' -gem 'standard' -gem 'capybara' -gem 'minitest' -gem 'rake' -gem 'sqlite3', '~> 1.4' diff --git a/superglue_rails/Gemfile.70 b/superglue_rails/Gemfile.70 deleted file mode 100644 index b4180bf7..00000000 --- a/superglue_rails/Gemfile.70 +++ /dev/null @@ -1,11 +0,0 @@ -source 'https://rubygems.org' -gemspec - -gem 'rails', '~> 7.0.0' -gem 'selenium-webdriver' -gem 'props_template' -gem 'standard' -gem 'capybara' -gem 'minitest' -gem 'rake' -gem 'sqlite3', '~> 1.4' diff --git a/superglue_rails/Gemfile.71 b/superglue_rails/Gemfile.71 deleted file mode 100644 index c118d20c..00000000 --- a/superglue_rails/Gemfile.71 +++ /dev/null @@ -1,11 +0,0 @@ -source 'https://rubygems.org' -gemspec - -gem 'rails', '~> 7.1.0' -gem 'selenium-webdriver' -gem 'props_template' -gem 'standard' -gem 'capybara' -gem 'minitest' -gem 'rake' -gem 'sqlite3', '~> 1.4' diff --git a/superglue_rails/Gemfile.72 b/superglue_rails/Gemfile.72 deleted file mode 100644 index 1291856d..00000000 --- a/superglue_rails/Gemfile.72 +++ /dev/null @@ -1,11 +0,0 @@ -source 'https://rubygems.org' -gemspec - -gem 'rails', '~> 7.2.0' -gem 'selenium-webdriver' -gem 'props_template' -gem 'standard' -gem 'capybara' -gem 'minitest' -gem 'rake' -gem 'sqlite3', '~> 1.4' diff --git a/superglue_rails/Gemfile.80 b/superglue_rails/Gemfile.80 deleted file mode 100644 index 0445fa79..00000000 --- a/superglue_rails/Gemfile.80 +++ /dev/null @@ -1,11 +0,0 @@ -source 'https://rubygems.org' -gemspec - -gem 'rails', '~> 8.0.0' -gem 'selenium-webdriver' -gem 'props_template' -gem 'standard' -gem 'capybara' -gem 'minitest' -gem 'rake' -gem 'sqlite3' diff --git a/superglue_rails/Gemfile.main b/superglue_rails/Gemfile.main deleted file mode 100644 index fcad52ba..00000000 --- a/superglue_rails/Gemfile.main +++ /dev/null @@ -1,11 +0,0 @@ -source 'https://rubygems.org' -gemspec - -gem 'rails', git: 'https://github.com/rails/rails', ref: 'main' -gem 'selenium-webdriver' -gem 'props_template' -gem 'standard' -gem 'capybara' -gem 'minitest' -gem 'rake' -gem 'sqlite3', '~> 1.4' diff --git a/superglue_rails/Rakefile b/superglue_rails/Rakefile deleted file mode 100644 index 92a5d982..00000000 --- a/superglue_rails/Rakefile +++ /dev/null @@ -1,9 +0,0 @@ -require "rake/testtask" -require "standard/rake" - -Rake::TestTask.new do |t| - t.libs << "test" - t.pattern = "test/**/*_test.rb" - t.warning = false - t.verbose = true -end diff --git a/superglue_rails/lib/generators/superglue/install/install_generator.rb b/superglue_rails/lib/generators/superglue/install/install_generator.rb deleted file mode 100644 index 9c45c575..00000000 --- a/superglue_rails/lib/generators/superglue/install/install_generator.rb +++ /dev/null @@ -1,119 +0,0 @@ -require "rails/generators/named_base" -require "rails/generators/resource_helpers" - -module Superglue - module Generators - class InstallGenerator < Rails::Generators::Base - source_root File.expand_path("../templates", __FILE__) - - class_option :typescript, - type: :boolean, - required: false, - default: false, - desc: "Use typescript" - - def create_files - remove_file "#{app_js_path}/application.js" - - use_typescript = options["typescript"] - if use_typescript - copy_ts_files - else - copy_js_files - end - - say "Copying Superglue initializer" - copy_file "#{__dir__}/templates/initializer.rb", "config/initializers/superglue.rb" - - say "Copying application.json.props" - copy_file "#{__dir__}/templates/application.json.props", "app/views/layouts/application.json.props" - - say "Adding required member methods to ApplicationRecord" - add_member_methods - - say "Installing Superglue and friends" - run "yarn add react react-dom @reduxjs/toolkit react-redux @thoughtbot/superglue" - - if use_typescript - run "yarn add -D @types/react-dom @types/react @types/node @thoughtbot/candy_wrapper" - end - - say "Superglue is Installed! 🎉", :green - end - - private - - def copy_ts_files - say "Copying application.tsx file to #{app_js_path}" - copy_file "#{__dir__}/templates/ts/application.tsx", "#{app_js_path}/application.tsx" - - say "Copying page_to_page_mapping.ts file to #{app_js_path}" - copy_file "#{__dir__}/templates/ts/page_to_page_mapping.ts", "#{app_js_path}/page_to_page_mapping.ts" - - say "Copying flash.ts file to #{app_js_path}" - copy_file "#{__dir__}/templates/ts/flash.ts", "#{app_js_path}/slices/flash.ts" - - say "Copying store.ts file to #{app_js_path}" - copy_file "#{__dir__}/templates/ts/store.ts", "#{app_js_path}/store.ts" - - say "Copying application_visit.ts file to #{app_js_path}" - copy_file "#{__dir__}/templates/ts/application_visit.ts", "#{app_js_path}/application_visit.ts" - - say "Copying components to #{app_js_path}" - copy_file "#{__dir__}/templates/ts/inputs.tsx", "#{app_js_path}/components/Inputs.tsx" - copy_file "#{__dir__}/templates/ts/layout.tsx", "#{app_js_path}/components/Layout.tsx" - copy_file "#{__dir__}/templates/ts/components.ts", "#{app_js_path}/components/index.ts" - - say "Copying tsconfig.json file to #{app_js_path}" - copy_file "#{__dir__}/templates/ts/tsconfig.json", "tsconfig.json" - end - - def copy_js_files - say "Copying application.js file to #{app_js_path}" - copy_file "#{__dir__}/templates/js/application.jsx", "#{app_js_path}/application.jsx" - - say "Copying page_to_page_mapping.js file to #{app_js_path}" - copy_file "#{__dir__}/templates/js/page_to_page_mapping.js", "#{app_js_path}/page_to_page_mapping.js" - - say "Copying flash.js file to #{app_js_path}" - copy_file "#{__dir__}/templates/js/flash.js", "#{app_js_path}/slices/flash.js" - - say "Copying store.js file to #{app_js_path}" - copy_file "#{__dir__}/templates/js/store.js", "#{app_js_path}/store.js" - - say "Copying application_visit.js file to #{app_js_path}" - copy_file "#{__dir__}/templates/js/application_visit.js", "#{app_js_path}/application_visit.js" - - say "Copying components to #{app_js_path}" - copy_file "#{__dir__}/templates/js/inputs.jsx", "#{app_js_path}/components/Inputs.jsx" - copy_file "#{__dir__}/templates/js/layout.jsx", "#{app_js_path}/components/Layout.jsx" - copy_file "#{__dir__}/templates/js/components.js", "#{app_js_path}/components/index.js" - - say "Copying jsconfig.json file to #{app_js_path}" - copy_file "#{__dir__}/templates/js/jsconfig.json", "jsconfig.json" - end - - def add_member_methods - inject_into_file "app/models/application_record.rb", after: "class ApplicationRecord < ActiveRecord::Base\n" do - <<-RUBY - # This enables digging by index when used with props_template - # see https://thoughtbot.github.io/superglue/digging/#index-based-selection - def self.member_at(index) - offset(index).limit(1).first - end - - # This enables digging by attribute when used with props_template - # see https://thoughtbot.github.io/superglue/digging/#attribute-based-selection - def self.member_by(attr, value) - find_by(Hash[attr, value]) - end - RUBY - end - end - - def app_js_path - "app/javascript/" - end - end - end -end diff --git a/superglue_rails/lib/generators/superglue/install/templates/application.json.props b/superglue_rails/lib/generators/superglue/install/templates/application.json.props deleted file mode 100644 index e197f53c..00000000 --- a/superglue_rails/lib/generators/superglue/install/templates/application.json.props +++ /dev/null @@ -1,27 +0,0 @@ -path = request.format.json? ? param_to_dig_path(params[:props_at]) : nil - -json.data(dig: path) do - yield json -end - -json.componentIdentifier active_template_virtual_path -json.defers json.deferred! -json.fragments json.fragments! -json.assets [ asset_path('application.js') ] - -if protect_against_forgery? - json.csrfToken form_authenticity_token -end - -if path - json.action 'graft' - json.path params[:props_at] -end - -json.restoreStrategy 'fromCacheAndRevisitInBackground' - -json.renderedAt Time.now.to_i - -json.slices do - json.flash flash.to_h -end diff --git a/superglue_rails/lib/generators/superglue/install/templates/initializer.rb b/superglue_rails/lib/generators/superglue/install/templates/initializer.rb deleted file mode 100644 index ac9d2876..00000000 --- a/superglue_rails/lib/generators/superglue/install/templates/initializer.rb +++ /dev/null @@ -1 +0,0 @@ -require "props_template/core_ext" diff --git a/superglue_rails/lib/generators/superglue/install/templates/js/application.jsx b/superglue_rails/lib/generators/superglue/install/templates/js/application.jsx deleted file mode 100644 index d75bd5e4..00000000 --- a/superglue_rails/lib/generators/superglue/install/templates/js/application.jsx +++ /dev/null @@ -1,35 +0,0 @@ -import React from "react" -import { createRoot } from "react-dom/client" -import { Application } from "@thoughtbot/superglue" -import { buildVisitAndRemote } from "./application_visit" -import { pageIdentifierToPageComponent } from "./page_to_page_mapping" -import { store } from "./store" - -if (typeof window !== "undefined") { - document.addEventListener("DOMContentLoaded", function() { - const appEl = document.getElementById("app") - const location = window.location - - if (appEl) { - const root = createRoot(appEl) - root.render( - - ) - } - }) -} diff --git a/superglue_rails/lib/generators/superglue/install/templates/js/application_visit.js b/superglue_rails/lib/generators/superglue/install/templates/js/application_visit.js deleted file mode 100644 index cc004eec..00000000 --- a/superglue_rails/lib/generators/superglue/install/templates/js/application_visit.js +++ /dev/null @@ -1,113 +0,0 @@ -import { visit, remote } from "@thoughtbot/superglue/action_creators" - -/** - * This function returns a wrapped visit and remote that will be used by UJS, - * the Navigation component, and passed to your page components through the - * NavigationContext. - * - * You can customize both functions to your liking. For example, for a progress - * bar. This file also adds support for data-sg-remote. - */ -export const buildVisitAndRemote = (ref, store) => { - const appRemote = (path, { dataset, ...options }) => { - /** - * You can make use of `dataset` to add custom UJS options. - * If you are implementing a progress bar, you can selectively - * hide it for some links. For example: - * - * ``` - * - * Click me - * - * ``` - * - * This would be available as `sgHideProgress` on the dataset - */ - return store.dispatch(remote(path, options)) - } - - const appVisit = (path, { dataset, ...options } = {}) => { - /** - * Do something before we make a request. - * e.g, show a [progress bar](https://thoughtbot.github.io/superglue/recipes/progress-bar/). - * - * Hint: you can access the current pageKey - * via `store.getState().superglue.currentPageKey` - */ - return store - .dispatch(visit(path, options)) - .then(meta => { - /** - * The assets fingerprints changed, instead of transitioning - * just go to the URL directly to retrieve new assets - */ - if (meta.needsRefresh) { - window.location.href = meta.pageKey - return meta - } - - /** - * Your first expanded UJS option, `data-sg-replace` - * - * This option overrides the `navigationAction` to allow a link click or - * a form submission to replace history instead of the usual push. - */ - const navigatonAction = !!dataset?.sgReplace - ? "replace" - : meta.navigationAction - ref.current?.navigateTo(meta.pageKey, { - action: navigatonAction - }) - - /** - * Return the meta object, it's used for scroll restoration when - * handling the back button. You can skip returning, but Superglue - * will warn you about scroll restoration. - */ - return meta - }) - .finally(() => { - /** - * Do something after a request. - * - * This is where you hide a progress bar. - */ - }) - .catch(err => { - const response = err.response - - if (!response) { - /** - * This is for errors that are NOT from a HTTP request. - * - * Tooling like Sentry can capture console errors. If not, feel - * free to customize to send the error to your telemetry tool of choice. - */ - console.error(err) - return - } - - if (response.ok) { - /** - * This is for errors that are from a HTTP request. - * - * If the response is OK, it must be an HTML body, we'll - * go to that locaton directly. - */ - window.location = response.url - } else { - if (response.status >= 400 && response.status < 500) { - window.location.href = "/400.html" - return - } - - if (response.status >= 500) { - window.location.href = "/500.html" - return - } - } - }) - } - - return { visit: appVisit, remote: appRemote } -} diff --git a/superglue_rails/lib/generators/superglue/install/templates/js/components.js b/superglue_rails/lib/generators/superglue/install/templates/js/components.js deleted file mode 100644 index 4730e239..00000000 --- a/superglue_rails/lib/generators/superglue/install/templates/js/components.js +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./Layout" -export * from "./Inputs" diff --git a/superglue_rails/lib/generators/superglue/install/templates/js/flash.js b/superglue_rails/lib/generators/superglue/install/templates/js/flash.js deleted file mode 100644 index 1f76b745..00000000 --- a/superglue_rails/lib/generators/superglue/install/templates/js/flash.js +++ /dev/null @@ -1,44 +0,0 @@ -import { createSlice } from "@reduxjs/toolkit" -import { saveResponse, beforeVisit } from "@thoughtbot/superglue" - -const initialState = {} - -export const flashSlice = createSlice({ - name: "flash", - initialState: initialState, - reducers: { - clearFlash(state, { payload }) { - const key = payload - if (!key) { - return {} - } - - delete state[key] - - return { - ...state - } - }, - flash(state, { payload }) { - return { - ...state, - ...payload - } - } - }, - extraReducers: builder => { - builder.addCase(beforeVisit, (_state, _action) => { - return {} - }) - builder.addCase(saveResponse, (state, action) => { - const { page } = action.payload - - return { - ...state, - ...page.slices.flash - } - }) - } -}) - -export const { clearFlash, flash } = flashSlice.actions diff --git a/superglue_rails/lib/generators/superglue/install/templates/js/inputs.jsx b/superglue_rails/lib/generators/superglue/install/templates/js/inputs.jsx deleted file mode 100644 index 59366e8d..00000000 --- a/superglue_rails/lib/generators/superglue/install/templates/js/inputs.jsx +++ /dev/null @@ -1,302 +0,0 @@ -/** - * Vanilla is a minimum set of - * [candy_wrappers](https://github.com/thoughtbot/candy_wrapper) around react - * HTML tags. It works with the output from - * [FormProps](https://github.com/thoughtbot/form_props). - * - * There is no style and structured with bare necessities. You should modify - * these components to fit your design needs. - */ -import React, { useContext, createContext, useMemo } from "react"; -export const ValidationContext = createContext({}); -export const useErrorKeyValidation = ({ errorKey, }) => { - const errors = useContext(ValidationContext); - return useMemo(() => { - return errors[errorKey]; - }, [errors, errorKey]); -}; -/** - * Extras renders the hidden inputs generated by form_props. - * - * Its meant to be used with a form component and renders hidden values for - * utf8, crsf_token, _method - */ -export const Extras = (hiddenInputAttributes) => { - const hiddenProps = Object.values(hiddenInputAttributes); - const hiddenInputs = hiddenProps.map((props) => ()); - return <>{hiddenInputs}; -}; -/** - * A basic form component that supports inline errors. - * - * It's meant to be used with FormProps and mimics the ways that - * Rails forms are generated. - */ -export const Form = ({ extras, validationErrors = {}, children, ...props }) => { - return (
- - - {children} - -
); -}; -/** - * An inline error component. - * - * When a Field has an error, this will show below the label and input. - * Please modify this to your liking. - */ -export const FieldError = ({ errorKey }) => { - const errors = useContext(ValidationContext); - if (!errorKey || !errors) { - return null; - } - const validationError = errors[errorKey]; - const hasErrors = errorKey && validationError; - if (!hasErrors) { - return null; - } - const errorMessages = Array.isArray(validationError) - ? validationError - : [validationError]; - return {errorMessages.join(" ")}; -}; -/** - * A Field component. - * - * Combines a label, input and a FieldError. Please modify this to your liking. - */ -export const FieldBase = ({ label, errorKey, children, ...props }) => { - return (<> - - {children || } - - ); -}; -export const Checkbox = ({ type: _type, includeHidden, uncheckedValue, errorKey, ...rest }) => { - const { name } = rest; - return ( - {includeHidden && ()} - - ); -}; -/** - * A collection checkbox component. - * - * Designed to work with a payload form_props's [collection_check_boxes helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#collection-select). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const CollectionCheckboxes = ({ includeHidden, collection, label, errorKey, }) => { - if (collection.length == 0) { - return null; - } - const checkboxes = collection.map((options) => { - return ; - }); - const { name } = collection[0]; - return (<> - {includeHidden && ()} - - {checkboxes} - - ); -}; -/** - * A collection radio button component. - * - * Designed to work with a payload form_props's [collection_radio_buttons helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#collection-select). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const CollectionRadioButtons = ({ includeHidden, collection, label, errorKey, }) => { - if (collection.length == 0) { - return null; - } - const radioButtons = collection.map((options) => { - return (
- - -
); - }); - const { name } = collection[0]; - return (<> - {includeHidden && ()} - - {radioButtons} - - ); -}; -/** - * A text field component. - * - * Designed to work with a payload form_props's [text_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#text-helpers). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const TextField = ({ type: _type, ...rest }) => { - return ; -}; -/** - * A email field component. - * - * Designed to work with a payload form_props's [email_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#text-helpers). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const EmailField = ({ type: _type, ...rest }) => { - return ; -}; -/** - * A color field component. - * - * Designed to work with a payload form_props's [color_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#text-helpers). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const ColorField = ({ type: _type, ...rest }) => { - return ; -}; -/** - * A date field component. - * - * Designed to work with a payload form_props's [date_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#date-helpers). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const DateField = ({ type: _type, ...rest }) => { - return ; -}; -/** - * A date field component. - * - * Designed to work with a payload form_props's [date_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#date-helpers). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const DateTimeLocalField = ({ type: _type, ...rest }) => { - return ; -}; -/** - * A search field component. - * - * Designed to work with a payload form_props's [search_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#text-helpers). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const SearchField = ({ type: _type, ...rest }) => { - return ; -}; -/** - * A tel field component. - * - * Designed to work with a payload form_props's [tel_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#text-helpers). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const TelField = ({ type: _type, ...rest }) => { - return ; -}; -/** - * A url field component. - * - * Designed to work with a payload form_props's [tel_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#text-helpers). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const UrlField = ({ type: _type, ...rest }) => { - return ; -}; -/** - * A month field component. - * - * Designed to work with a payload form_props's [month_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#date-helpers). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const MonthField = ({ type: _type, ...rest }) => { - return ; -}; -/** - * A month field component. - * - * Designed to work with a payload form_props's [month_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#date-helpers). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const TimeField = ({ type: _type, ...rest }) => { - return ; -}; -/** - * A number field component. - * - * Designed to work with a payload form_props's [month_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#number-helpers). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const NumberField = ({ type: _type, ...rest }) => { - return ; -}; -/** - * A range field component. - * - * Designed to work with a payload form_props's [range_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#number-helpers). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const RangeField = ({ type: _type, ...rest }) => { - return ; -}; -/** - * A password field component. - * - * Designed to work with a payload form_props's [password_field helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#text-helpers). - * Mimics the rails equivalent. Please modify to your liking. - */ -export const PasswordField = ({ type: _type, ...rest }) => { - return ; -}; -/** - * A select component. - * - * Designed to work with a payload form_props's [select helpers](https://github.com/thoughtbot/form_props?tab=readme-ov-file#select-helpers), - * [collection_select helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#collection-select), and [grouped_collection_select helper](https://github.com/thoughtbot/form_props?tab=readme-ov-file#group-collection-select). - * - * Please modify to your liking. - */ -export const Select = ({ includeHidden, name, id, children, options, multiple, type: _type, ...rest }) => { - const addHidden = includeHidden && multiple; - const optionElements = options.map((item) => { - if ("options" in item) { - return ( - {item.options.map((opt) => (); - } - else { - return