From c6aa635f7d814d17ce556ee4f19a38e5c2f54922 Mon Sep 17 00:00:00 2001 From: Johny Ho Date: Tue, 19 Nov 2024 05:46:36 -0500 Subject: [PATCH] Add wrappers --- .github/workflows/build_js.yml | 25 + .github/workflows/dynamic-security.yml | 19 + .gitignore | 4 +- .prettierrc | 7 + CODEOWNERS | 15 + CODE_OF_CONDUCT.md | 6 + LICENSE | 21 + SECURITY.md | 20 + package.json | 38 +- rails/CheckBox.js | 25 - rails/CollectionCheckBoxes.js | 30 -- rails/CollectionRadioButtons.js | 30 -- rails/Select.js | 53 -- src/README.md | 133 +++++ src/hooks.ts | 17 + src/index.ts | 2 + src/types.ts | 165 ++++++ tsconfig.json | 6 +- tsup.config.ts | 3 +- types.ts | 498 ------------------ vitest.config.ts | 8 +- wrappers/js/basic/index.jsx | 266 ++++++++++ .../ts/basic}/Checkbox.test.jsx | 7 +- .../ts/basic}/CollectionCheckboxes.test.jsx | 7 +- .../ts/basic}/CollectionRadioButtons.test.jsx | 5 +- .../ts/basic}/ColorField.test.jsx | 3 +- .../ts/basic}/DateField.test.jsx | 5 +- .../ts/basic}/EmailField.test.jsx | 3 +- .../ts/basic}/FieldError.test.jsx | 19 +- .../ts/basic}/MonthField.test.jsx | 15 +- .../ts/basic}/NumberField.test.jsx | 5 +- .../ts/basic}/PasswordField.test.jsx | 3 +- .../ts/basic}/RangeField.test.jsx | 5 +- .../ts/basic}/SearchField.test.jsx | 3 +- {rails => wrappers/ts/basic}/Select.test.jsx | 34 +- .../ts/basic}/TelField.test.jsx | 3 +- wrappers/ts/basic/TextArea.test.jsx | 49 ++ .../ts/basic}/TextField.test.jsx | 3 +- .../ts/basic}/TimeField.test.jsx | 3 +- .../ts/basic}/UrlField.test.jsx | 3 +- {rails => wrappers/ts/basic}/index.tsx | 235 +++++++-- wrappers/tsconfig.json | 11 + 42 files changed, 1048 insertions(+), 764 deletions(-) create mode 100644 .github/workflows/build_js.yml create mode 100644 .github/workflows/dynamic-security.yml create mode 100644 .prettierrc create mode 100644 CODEOWNERS create mode 100644 CODE_OF_CONDUCT.md create mode 100644 LICENSE create mode 100644 SECURITY.md delete mode 100644 rails/CheckBox.js delete mode 100644 rails/CollectionCheckBoxes.js delete mode 100644 rails/CollectionRadioButtons.js delete mode 100644 rails/Select.js create mode 100644 src/README.md create mode 100644 src/hooks.ts create mode 100644 src/index.ts create mode 100644 src/types.ts delete mode 100644 types.ts create mode 100644 wrappers/js/basic/index.jsx rename {rails => wrappers/ts/basic}/Checkbox.test.jsx (95%) rename {rails => wrappers/ts/basic}/CollectionCheckboxes.test.jsx (96%) rename {rails => wrappers/ts/basic}/CollectionRadioButtons.test.jsx (96%) rename {rails => wrappers/ts/basic}/ColorField.test.jsx (92%) rename {rails => wrappers/ts/basic}/DateField.test.jsx (93%) rename {rails => wrappers/ts/basic}/EmailField.test.jsx (93%) rename {rails => wrappers/ts/basic}/FieldError.test.jsx (75%) rename {rails => wrappers/ts/basic}/MonthField.test.jsx (82%) rename {rails => wrappers/ts/basic}/NumberField.test.jsx (92%) rename {rails => wrappers/ts/basic}/PasswordField.test.jsx (93%) rename {rails => wrappers/ts/basic}/RangeField.test.jsx (92%) rename {rails => wrappers/ts/basic}/SearchField.test.jsx (93%) rename {rails => wrappers/ts/basic}/Select.test.jsx (87%) rename {rails => wrappers/ts/basic}/TelField.test.jsx (93%) create mode 100644 wrappers/ts/basic/TextArea.test.jsx rename {rails => wrappers/ts/basic}/TextField.test.jsx (93%) rename {rails => wrappers/ts/basic}/TimeField.test.jsx (94%) rename {rails => wrappers/ts/basic}/UrlField.test.jsx (92%) rename {rails => wrappers/ts/basic}/index.tsx (51%) create mode 100644 wrappers/tsconfig.json diff --git a/.github/workflows/build_js.yml b/.github/workflows/build_js.yml new file mode 100644 index 0000000..7f07382 --- /dev/null +++ b/.github/workflows/build_js.yml @@ -0,0 +1,25 @@ +name: Test +on: + push: + pull_request: + workflow_dispatch: + +jobs: + build: + name: Test Wrapper + strategy: + fail-fast: false + + runs-on: 'ubuntu-latest' + + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 18 + - name: Setup project + run: npm install + - name: Lint + run: npm run lint + - name: Test + run: npm run test diff --git a/.github/workflows/dynamic-security.yml b/.github/workflows/dynamic-security.yml new file mode 100644 index 0000000..26a424d --- /dev/null +++ b/.github/workflows/dynamic-security.yml @@ -0,0 +1,19 @@ +name: update-security + +on: + push: + paths: + - SECURITY.md + branches: + - main + workflow_dispatch: + +jobs: + update-security: + permissions: + contents: write + pull-requests: write + pages: write + uses: thoughtbot/templates/.github/workflows/dynamic-security.yaml@main + secrets: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 3b7f80d..96ab72e 100644 --- a/.gitignore +++ b/.gitignore @@ -63,4 +63,6 @@ dist/ package-lock.json coverage/ -todo.txt \ No newline at end of file +todo.txt + +temp/ \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..26ac540 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "semi": false, + "singleQuote": true, + "printWidth": 80, + "useTabs": false, + "tabWidth": 2 +} diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..0917974 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,15 @@ +# Lines starting with '#' are comments. +# Each line is a file pattern followed by one or more owners. + +# More details are here: https://help.github.com/articles/about-codeowners/ + +# The '*' pattern is global owners. + +# Order is important. The last matching pattern has the most precedence. +# The folders are ordered as follows: + +# In each subsection folders are ordered first by depth, then alphabetically. +# This should make it easy to add new rules without breaking existing ones. + +# Global rule: +* @jho406 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..848a59a --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,6 @@ +# Code of conduct + +By participating in this project, you agree to abide by the +[thoughtbot code of conduct][1]. + +[1]: https://thoughtbot.com/open-source-code-of-conduct diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bcf5227 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Johny Ho + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..af66180 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,20 @@ + +# Security Policy + +## Supported Versions + +Only the the latest version of this project is supported at a given time. If +you find a security issue with an older version, please try updating to the +latest version first. + +If for some reason you can't update to the latest version, please let us know +your reasons so that we can have a better understanding of your situation. + +## Reporting a Vulnerability + +For security inquiries or vulnerability reports, visit +. + +If you have any suggestions to improve this policy, visit . + + diff --git a/package.json b/package.json index 7b38fcf..74ba72e 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,14 @@ { - "name": "@thoughtbot/candywrappa", + "name": "@thoughtbot/candy_wrapper", "version": "0.0.1", - "description": "bare forms", + "description": "Use rails forms with popular react UI libraries", "scripts": { "build": "tsup", + "build:wrappers": "tsc --project ./wrappers/tsconfig.json && rm -r wrappers/js/* && mv -v temp/wrappers/ts/* wrappers/js", "dev": "tsup --watch", "clean": "rm -rf dist", "lint": "run-p lint:eslint lint:types lint:prettier", - "lint:eslint": "eslint --max-warnings=0 --ext js,jsx,ts,tsx ./candywrappa", + "lint:eslint": "eslint --max-warnings=0 --ext js,jsx,ts,tsx ./candy_wrapper", "lint:prettier": "prettier --check '**/*' --ignore-unknown", "lint:types": "tsc", "fix:prettier": "prettier --write '**/*' --ignore-unknown", @@ -20,25 +21,20 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/thoughtbot/form_props.git" + "url": "git+https://github.com/thoughtbot/candy_wrapper.git" }, "author": "Johny Ho", - "main": "dist/cjs/form_props.cjs", - "module": "dist/form_props.mjs", - "types": "dist/form_props.d.mts", + "main": "dist/cjs/candy_wrapper.cjs", + "module": "dist/candy_wrapper.mjs", + "types": "dist/candy_wrapper.d.mts", "exports": { - "./package.json": "./package.json", - "./components": { - "types": "./dist/form_props.d.mts", - "import": "./dist/form_props.mjs", - "default": "./dist/cjs/form_props.cjs" - } + "./package.json": "./package.json" }, "license": "MIT", "bugs": { - "url": "https://github.com/thoughtbot/form_props/issues" + "url": "https://github.com/thoughtbot/candy_wrapper/issues" }, - "homepage": "https://github.com/thoughtbot/form_props#readme", + "homepage": "https://github.com/thoughtbot/candy_wrapper#readme", "devDependencies": { "@nextui-org/react": "^2.4.8", "@react-aria/test-utils": "^1.0.0-alpha.2", @@ -63,16 +59,10 @@ "typedoc-plugin-markdown": "^4.2.3", "typedoc-plugin-missing-exports": "^3.0.0", "typescript": "^5.5.3", - "vitest": "^2.0.2" + "vitest": "^2.0.2", + "@types/react": "^18.3.12" }, "peerDependencies": { - "react": "^18.3.1" - }, - "dependencies": { - "@types/react": "^18.3.12", - "@types/react-dom": "^18.3.1", - "react-aria-components": "^1.4.1", - "react-stately": "^3.33.0", - "yarn": "^1.22.22" + "react": "^18 || ^19" } } diff --git a/rails/CheckBox.js b/rails/CheckBox.js deleted file mode 100644 index ab1e641..0000000 --- a/rails/CheckBox.js +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from 'react' - -export default ({ - includeHidden = true, - name = null, - uncheckedValue = null, - children, - ...rest -}) => { - return ( - <> - {includeHidden && ( - - )} - - {children} - - - ) -} diff --git a/rails/CollectionCheckBoxes.js b/rails/CollectionCheckBoxes.js deleted file mode 100644 index f3a4aac..0000000 --- a/rails/CollectionCheckBoxes.js +++ /dev/null @@ -1,30 +0,0 @@ -import * as React from 'react' - -export default ({ includeHidden = true, collection = [], ...rest }) => { - if (collection.length == 0) { - return null - } - - const checkboxes = collection.map((options) => { - const { id } = options - const { uncheckedValue, label, ...inputOptions } = options - - return ( - <> - - - - ) - }) - - const { name } = collection[0] - - return ( - <> - {includeHidden && ( - - )} - {checkboxes} - - ) -} diff --git a/rails/CollectionRadioButtons.js b/rails/CollectionRadioButtons.js deleted file mode 100644 index dc91de5..0000000 --- a/rails/CollectionRadioButtons.js +++ /dev/null @@ -1,30 +0,0 @@ -import * as React from 'react' - -export default ({ includeHidden = true, collection = [], ...rest }) => { - if (collection.length == 0) { - return null - } - - const checkboxes = collection.map((options) => { - const { id } = options - const { label, ...inputOptions } = options - - return ( - <> - - - - ) - }) - - const { name } = collection[0] - - return ( - <> - {includeHidden && ( - - )} - {checkboxes} - - ) -} diff --git a/rails/Select.js b/rails/Select.js deleted file mode 100644 index 27c1a16..0000000 --- a/rails/Select.js +++ /dev/null @@ -1,53 +0,0 @@ -import * as React from 'react' - -export default ({ - includeHidden = true, - name = null, - id = null, - children, - options = [], - multiple = false, - disabled = false, - type = null, - ...rest -}) => { - const addHidden = includeHidden && multiple - - const optionElements = options.map((option) => { - if (option.hasOwnProperty('options')) { - return ( - - {option.options.map((opt) => ( - - ) - } else { - return