diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..ab23284 --- /dev/null +++ b/TODO.md @@ -0,0 +1,60 @@ +# Categories + +- Action + - [X] ActionButton +- Blob (choose to extract each preview component to their own library?) + - [ ] FileSelectBox +- Choice + - [X] ComboBox + - [X] DropdownSelect + - [X] MenuSelect + - [X] RadioButton + - [X] RadioTickBox +- Color + - [ ] ColorPicker + - [X] Swatch +- Formatted + - [X] EmailInput + - [X] PhoneNumberInput + - [X] UrlInput +- Freeform + - [X] MaskedTextInput + - [X] MultilineTextInput + - [X] TextInput +- Geo + - [ ] Map +- Information + - [X] Badge + - [X] KeyValueTable +- MultiChoice + - [X] MenuMultiSelect + - [X] TagInput + - [X] ToggleButton + - [X] ToggleSwitch + - [X] ToggleTickBox +- Navigation + - [ ] Breadcrumb + - [X] LinkButton + - [ ] Pagination + - [ ] Steps +- Number + - [X] Slider + - [X] Spinner + - [ ] Matrix2D +- Rating + - [ ] Rating +- RichText + - [ ] RichTextInput +- Temporal + - [ ] Calendar + - [ ] DateDropdown + - [ ] DateTimeRangeInput + - [ ] MonthInput + - [ ] MonthDayInput + - [ ] TimeSpinner + - [ ] YearMonthInput + - [ ] YearWeekInput + - [ ] YearInput + +# Others +- [ ] Add `select-none` to input labels, etc. diff --git a/base/.eslintrc b/base/.eslintrc new file mode 100644 index 0000000..35cfb79 --- /dev/null +++ b/base/.eslintrc @@ -0,0 +1,9 @@ +{ + "root": true, + "extends": [ + "lxsmnsyc/typescript" + ], + "parserOptions": { + "project": "./tsconfig.eslint.json" + } +} diff --git a/base/.gitignore b/base/.gitignore new file mode 100644 index 0000000..53992de --- /dev/null +++ b/base/.gitignore @@ -0,0 +1,107 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.production +.env.development + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +.npmrc diff --git a/base/LICENSE b/base/LICENSE new file mode 100644 index 0000000..f24dd21 --- /dev/null +++ b/base/LICENSE @@ -0,0 +1,7 @@ +MIT License Copyright (c) 2023 TheoryOfNekomata + +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 (including the next paragraph) 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. \ No newline at end of file diff --git a/packages/web/base/selectcontrol/package.json b/base/package.json similarity index 73% rename from packages/web/base/selectcontrol/package.json rename to base/package.json index 7739de9..fd3f540 100644 --- a/packages/web/base/selectcontrol/package.json +++ b/base/package.json @@ -1,27 +1,26 @@ { - "name": "@tesseract-design/web-base-selectcontrol", + "name": "@tesseract-design/web-base", "version": "0.0.0", "files": [ "dist", "src" ], "engines": { - "node": ">=10" + "node": ">=12" }, "license": "MIT", "keywords": [ "pridepack" ], "devDependencies": { - "@types/node": "^18.0.0", - "eslint": "^8.20.0", - "eslint-config-lxsmnsyc": "^0.4.7", + "@types/node": "^18.14.1", + "eslint": "^8.35.0", + "eslint-config-lxsmnsyc": "^0.5.0", "pridepack": "2.4.4", - "tslib": "^2.4.0", - "typescript": "^4.7.4", - "vitest": "^0.19.1" + "tslib": "^2.5.0", + "typescript": "^4.9.5", + "vitest": "^0.28.1" }, - "dependencies": {}, "scripts": { "prepublishOnly": "pridepack clean && pridepack build", "build": "pridepack build", @@ -33,8 +32,8 @@ "dev": "pridepack dev", "test": "vitest" }, - "private": true, - "description": "Base select control styles for Tesseract.", + "private": false, + "description": "Base types for Tesseract.", "repository": { "url": "", "type": "git" @@ -45,9 +44,11 @@ }, "author": "TheoryOfNekomata ", "publishConfig": { - "access": "restricted" + "access": "public" }, "types": "./dist/types/index.d.ts", + "main": "./dist/cjs/production/index.js", + "module": "./dist/esm/production/index.js", "exports": { ".": { "development": { @@ -61,7 +62,5 @@ }, "typesVersions": { "*": {} - }, - "main": "./dist/cjs/production/index.js", - "module": "./dist/esm/production/index.js" + } } diff --git a/base/pridepack.json b/base/pridepack.json new file mode 100644 index 0000000..841fb58 --- /dev/null +++ b/base/pridepack.json @@ -0,0 +1,3 @@ +{ + "target": "es2018" +} \ No newline at end of file diff --git a/base/src/button.ts b/base/src/button.ts new file mode 100644 index 0000000..c6f134e --- /dev/null +++ b/base/src/button.ts @@ -0,0 +1,5 @@ +export type Type = 'submit' | 'reset' | 'button'; + +export type Variant = 'bare' | 'filled' | 'outline'; + +export type Size = 'small' | 'medium' | 'large'; diff --git a/base/src/index.ts b/base/src/index.ts new file mode 100644 index 0000000..4dc8062 --- /dev/null +++ b/base/src/index.ts @@ -0,0 +1,2 @@ +export * as Button from './button'; +export * as TextControl from './text-control'; diff --git a/base/src/text-control.ts b/base/src/text-control.ts new file mode 100644 index 0000000..d43ea88 --- /dev/null +++ b/base/src/text-control.ts @@ -0,0 +1,7 @@ +export type Size = 'small' | 'medium' | 'large'; + +export type Variant = 'default' | 'alternate'; + +export type InputType = 'text' | 'search'; + +export type InputMode = 'none' | 'numeric' | 'decimal' | InputType; diff --git a/base/tsconfig.eslint.json b/base/tsconfig.eslint.json new file mode 100644 index 0000000..459f2a1 --- /dev/null +++ b/base/tsconfig.eslint.json @@ -0,0 +1,21 @@ +{ + "exclude": ["node_modules"], + "include": ["src", "types", "test"], + "compilerOptions": { + "module": "ESNext", + "lib": ["ESNext"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "jsx": "react", + "esModuleInterop": true, + "target": "es2018" + } +} diff --git a/base/tsconfig.json b/base/tsconfig.json new file mode 100644 index 0000000..e210542 --- /dev/null +++ b/base/tsconfig.json @@ -0,0 +1,21 @@ +{ + "exclude": ["node_modules"], + "include": ["src", "types"], + "compilerOptions": { + "module": "ESNext", + "lib": ["ESNext"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./src", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "jsx": "react", + "esModuleInterop": true, + "target": "es2018" + } +} diff --git a/categories/action/react/.eslintrc b/categories/action/react/.eslintrc new file mode 100644 index 0000000..8a6172f --- /dev/null +++ b/categories/action/react/.eslintrc @@ -0,0 +1,14 @@ +{ + "root": true, + "rules": { + "quote-props": "off", + "react/jsx-props-no-spreading": "off", + "react/button-has-type": "off" + }, + "extends": [ + "lxsmnsyc/typescript/react" + ], + "parserOptions": { + "project": "./tsconfig.eslint.json" + } +} diff --git a/categories/action/react/.gitignore b/categories/action/react/.gitignore new file mode 100644 index 0000000..53992de --- /dev/null +++ b/categories/action/react/.gitignore @@ -0,0 +1,107 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.production +.env.development + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +.npmrc diff --git a/categories/action/react/LICENSE b/categories/action/react/LICENSE new file mode 100644 index 0000000..f24dd21 --- /dev/null +++ b/categories/action/react/LICENSE @@ -0,0 +1,7 @@ +MIT License Copyright (c) 2023 TheoryOfNekomata + +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 (including the next paragraph) 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. \ No newline at end of file diff --git a/packages/web/categories/action/react/package.json b/categories/action/react/package.json similarity index 68% rename from packages/web/categories/action/react/package.json rename to categories/action/react/package.json index 505da7a..b65a403 100644 --- a/packages/web/categories/action/react/package.json +++ b/categories/action/react/package.json @@ -6,32 +6,27 @@ "src" ], "engines": { - "node": ">=10" + "node": ">=12" }, "license": "MIT", "keywords": [ "pridepack" ], - "dependencies": { - "@tesseract-design/web-base-button": "link:../../../base/button" - }, "devDependencies": { - "@testing-library/jest-dom": "^5.16.4", - "@testing-library/react": "^13.3.0", - "@testing-library/react-hooks": "^8.0.1", - "@testing-library/user-event": "^13.5.0", - "@types/node": "^18.0.0", - "@types/react": "^18.0.14", - "eslint": "^8.20.0", - "eslint-config-lxsmnsyc": "^0.4.7", - "jsdom": "^20.0.0", + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@types/node": "^18.14.1", + "@types/react": "^18.0.27", + "eslint": "^8.35.0", + "eslint-config-lxsmnsyc": "^0.5.0", + "jsdom": "^21.1.0", "pridepack": "2.4.4", "react": "^18.2.0", "react-dom": "^18.2.0", "react-test-renderer": "^18.2.0", - "tslib": "^2.4.0", - "typescript": "^4.7.4", - "vitest": "^0.31.0" + "tslib": "^2.5.0", + "typescript": "^4.9.5", + "vitest": "^0.28.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", @@ -48,8 +43,8 @@ "dev": "pridepack dev", "test": "vitest" }, - "private": true, - "description": "Action components for Tesseract for use in React.", + "private": false, + "description": "Tesseract components for committing actions for forms.", "repository": { "url": "", "type": "git" @@ -60,9 +55,15 @@ }, "author": "TheoryOfNekomata ", "publishConfig": { - "access": "restricted" + "access": "public" + }, + "dependencies": { + "clsx": "^1.2.1", + "@tesseract-design/web-base": "workspace:*" }, "types": "./dist/types/index.d.ts", + "main": "./dist/cjs/production/index.js", + "module": "./dist/esm/production/index.js", "exports": { ".": { "development": { @@ -76,7 +77,5 @@ }, "typesVersions": { "*": {} - }, - "main": "./dist/cjs/production/index.js", - "module": "./dist/esm/production/index.js" + } } diff --git a/categories/action/react/pridepack.json b/categories/action/react/pridepack.json new file mode 100644 index 0000000..841fb58 --- /dev/null +++ b/categories/action/react/pridepack.json @@ -0,0 +1,3 @@ +{ + "target": "es2018" +} \ No newline at end of file diff --git a/categories/action/react/src/components/ActionButton/index.tsx b/categories/action/react/src/components/ActionButton/index.tsx new file mode 100644 index 0000000..b72c44d --- /dev/null +++ b/categories/action/react/src/components/ActionButton/index.tsx @@ -0,0 +1,134 @@ +import * as React from 'react'; +import clsx from 'clsx'; +import { Button } from '@tesseract-design/web-base'; + +export type ActionButtonDerivedElement = HTMLButtonElement; + +export interface ActionButtonProps extends Omit, 'type' | 'size'> { + type?: Button.Type; + variant?: Button.Variant; + block?: boolean; + subtext?: React.ReactNode; + badge?: React.ReactNode; + menuItem?: boolean; + size?: Button.Size; + compact?: boolean; +} + +export const ActionButton = React.forwardRef(( + { + type = 'button' as const, + variant = 'bare' as const, + subtext, + badge, + menuItem = false, + children, + size = 'medium' as const, + compact = false, + className, + block = false, + ...etcProps + }, + forwardedRef, +) => ( + +)); + +ActionButton.displayName = 'ActionButton'; + +ActionButton.defaultProps = { + type: 'button', + variant: 'bare', + block: false, + subtext: undefined, + badge: undefined, + menuItem: false, + size: 'medium', + compact: false, +}; diff --git a/packages/web/categories/action/react/src/index.ts b/categories/action/react/src/index.ts similarity index 100% rename from packages/web/categories/action/react/src/index.ts rename to categories/action/react/src/index.ts diff --git a/categories/action/react/tsconfig.eslint.json b/categories/action/react/tsconfig.eslint.json new file mode 100644 index 0000000..16f2e87 --- /dev/null +++ b/categories/action/react/tsconfig.eslint.json @@ -0,0 +1,21 @@ +{ + "exclude": ["node_modules"], + "include": ["src", "types", "test"], + "compilerOptions": { + "module": "ESNext", + "lib": ["DOM", "ESNext"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "jsx": "react", + "esModuleInterop": true, + "target": "es2018" + } +} diff --git a/categories/action/react/tsconfig.json b/categories/action/react/tsconfig.json new file mode 100644 index 0000000..0ed68f4 --- /dev/null +++ b/categories/action/react/tsconfig.json @@ -0,0 +1,21 @@ +{ + "exclude": ["node_modules"], + "include": ["src", "types"], + "compilerOptions": { + "module": "ESNext", + "lib": ["DOM", "ESNext"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./src", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "jsx": "react", + "esModuleInterop": true, + "target": "es2018" + } +} diff --git a/categories/action/react/vitest.config.ts b/categories/action/react/vitest.config.ts new file mode 100644 index 0000000..a104d21 --- /dev/null +++ b/categories/action/react/vitest.config.ts @@ -0,0 +1,8 @@ +/// + +export default ({ + test: { + global: true, + environment: 'jsdom', + }, +}); diff --git a/categories/action/swift-ui/Package.swift b/categories/action/swift-ui/Package.swift new file mode 100644 index 0000000..2ce9a13 --- /dev/null +++ b/categories/action/swift-ui/Package.swift @@ -0,0 +1,22 @@ +import PackageDescription + +let package = Package( + name: "Action", + platforms: [ + .macOS(.v11), + .iOS(.v13) + ], + products: [ + .library( + name: "Action", + targets: ["Action"]), + ], + dependencies: [], + targets: [ + .target( + name: "Action", + dependencies: [], + path: "src", + ), + ] +) diff --git a/categories/action/swift-ui/src/components/ActionButton/ActionButton.swift b/categories/action/swift-ui/src/components/ActionButton/ActionButton.swift new file mode 100644 index 0000000..873e338 --- /dev/null +++ b/categories/action/swift-ui/src/components/ActionButton/ActionButton.swift @@ -0,0 +1,4 @@ +import SwiftUI + +public struct ActionButton: View { +} diff --git a/categories/blob/react/.eslintrc b/categories/blob/react/.eslintrc new file mode 100644 index 0000000..7d22244 --- /dev/null +++ b/categories/blob/react/.eslintrc @@ -0,0 +1,9 @@ +{ + "root": true, + "extends": [ + "lxsmnsyc/typescript/react" + ], + "parserOptions": { + "project": "./tsconfig.eslint.json" + } +} diff --git a/categories/blob/react/.gitignore b/categories/blob/react/.gitignore new file mode 100644 index 0000000..53992de --- /dev/null +++ b/categories/blob/react/.gitignore @@ -0,0 +1,107 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.production +.env.development + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +.npmrc diff --git a/categories/blob/react/LICENSE b/categories/blob/react/LICENSE new file mode 100644 index 0000000..f24dd21 --- /dev/null +++ b/categories/blob/react/LICENSE @@ -0,0 +1,7 @@ +MIT License Copyright (c) 2023 TheoryOfNekomata + +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 (including the next paragraph) 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. \ No newline at end of file diff --git a/categories/blob/react/package.json b/categories/blob/react/package.json new file mode 100644 index 0000000..92190a2 --- /dev/null +++ b/categories/blob/react/package.json @@ -0,0 +1,81 @@ +{ + "name": "@tesseract-design/web-blob-react", + "version": "0.0.0", + "files": [ + "dist", + "src" + ], + "engines": { + "node": ">=12" + }, + "license": "MIT", + "keywords": [ + "pridepack" + ], + "devDependencies": { + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@types/node": "^18.14.1", + "@types/react": "^18.0.27", + "eslint": "^8.35.0", + "eslint-config-lxsmnsyc": "^0.5.0", + "jsdom": "^21.1.0", + "pridepack": "2.4.4", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-test-renderer": "^18.2.0", + "tslib": "^2.5.0", + "typescript": "^4.9.5", + "vitest": "^0.28.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "scripts": { + "prepublishOnly": "pridepack clean && pridepack build", + "build": "pridepack build", + "type-check": "pridepack check", + "lint": "pridepack lint", + "clean": "pridepack clean", + "watch": "pridepack watch", + "start": "pridepack start", + "dev": "pridepack dev", + "test": "vitest" + }, + "private": false, + "description": "Tesseract components for displaying data.", + "repository": { + "url": "", + "type": "git" + }, + "homepage": "", + "bugs": { + "url": "" + }, + "author": "TheoryOfNekomata ", + "publishConfig": { + "access": "public" + }, + "dependencies": { + "clsx": "^1.2.1", + "@modal-sh/react-utils": "workspace:*" + }, + "types": "./dist/types/index.d.ts", + "main": "./dist/cjs/production/index.js", + "module": "./dist/esm/production/index.js", + "exports": { + ".": { + "development": { + "require": "./dist/cjs/development/index.js", + "import": "./dist/esm/development/index.js" + }, + "require": "./dist/cjs/production/index.js", + "import": "./dist/esm/production/index.js", + "types": "./dist/types/index.d.ts" + } + }, + "typesVersions": { + "*": {} + } +} diff --git a/categories/blob/react/pridepack.json b/categories/blob/react/pridepack.json new file mode 100644 index 0000000..841fb58 --- /dev/null +++ b/categories/blob/react/pridepack.json @@ -0,0 +1,3 @@ +{ + "target": "es2018" +} \ No newline at end of file diff --git a/categories/blob/react/src/components/FileSelectBox/index.tsx b/categories/blob/react/src/components/FileSelectBox/index.tsx new file mode 100644 index 0000000..5f62277 --- /dev/null +++ b/categories/blob/react/src/components/FileSelectBox/index.tsx @@ -0,0 +1,300 @@ +import * as React from 'react'; +import { delegateTriggerEvent, useClientSide } from '@modal-sh/react-utils'; +import clsx from 'clsx'; + +export interface CommonPreviewProps = Partial> { + file?: F; + disabled?: boolean; + enhanced?: boolean; + mini?: boolean; +} + +export type FileSelectBoxDerivedElement = HTMLInputElement; + +export interface FileSelectBoxProps< + F extends Partial = Partial, + P extends CommonPreviewProps = CommonPreviewProps +> extends Omit, 'size' | 'type' | 'style' | 'label' | 'list'> { + /** + * Should the component display a border? + */ + border?: boolean, + /** + * Should the component occupy the whole width of its parent? + */ + block?: boolean, + /** + * Short textual description indicating the nature of the component's value. + */ + label?: React.ReactNode, + /** + * Short textual description as guidelines for valid input values. + */ + hint?: React.ReactNode, + enhanced?: boolean, + /** + * Is the label hidden? + */ + hiddenLabel?: boolean, + previewComponent: React.ElementType

, +} + +export const FileSelectBox = React.forwardRef( + ( + { + label = '', + hint = '', + border = false, + block = false, + enhanced: enhancedProp = false, + hiddenLabel = false, + multiple = false, + onChange, + disabled = false, + className, + id: idProp, + previewComponent: FilePreviewComponent, + ...etcProps + }: FileSelectBoxProps, + forwardedRef, + ) => { + const { clientSide } = useClientSide({ clientSide: enhancedProp }); + const [fileList, setFileList] = React.useState(); + const [lastUpdated, setLastUpdated] = React.useState(); + const defaultRef = React.useRef(null); + const ref = forwardedRef ?? defaultRef; + const labelId = React.useId(); + const defaultId = React.useId(); + const id = idProp ?? defaultId; + + const doSetFileList: React.ChangeEventHandler = (e) => { + if (enhancedProp) { + setFileList(e.currentTarget.files as FileList); + setLastUpdated(Date.now()); + } + onChange?.(e); + }; + + const doClearFileList: React.MouseEventHandler = (e) => { + e.preventDefault(); + if (!(typeof ref === 'object' && ref)) { + return; + } + const { current } = ref; + if (!current) { + return; + } + + current.value = ''; + setFileList(undefined); + setLastUpdated(Date.now()); + setTimeout(() => { + delegateTriggerEvent('change', current); + }); + }; + + const cancelEvent = (e: React.DragEvent) => { + e.stopPropagation(); + e.preventDefault(); + }; + + const handleDropZone: React.DragEventHandler = async (e) => { + cancelEvent(e); + if (!(typeof ref === 'object' && ref)) { + return; + } + const { current } = ref; + if (!current) { + return; + } + const { dataTransfer } = e; + const { files } = dataTransfer; + if (!(files && files.length > 0)) { + return; + } + setFileList(current.files = files); + setLastUpdated(Date.now()); + setTimeout(() => { + delegateTriggerEvent('change', current); + }); + }; + + const filesCount = fileList?.length ?? 0; + + return ( +

+
+ ); + } +); + +FileSelectBox.displayName = 'FileSelectBox'; diff --git a/categories/blob/react/src/index.ts b/categories/blob/react/src/index.ts new file mode 100644 index 0000000..8c9ec95 --- /dev/null +++ b/categories/blob/react/src/index.ts @@ -0,0 +1 @@ +export * from './components/FileSelectBox'; diff --git a/categories/blob/react/tsconfig.eslint.json b/categories/blob/react/tsconfig.eslint.json new file mode 100644 index 0000000..16f2e87 --- /dev/null +++ b/categories/blob/react/tsconfig.eslint.json @@ -0,0 +1,21 @@ +{ + "exclude": ["node_modules"], + "include": ["src", "types", "test"], + "compilerOptions": { + "module": "ESNext", + "lib": ["DOM", "ESNext"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "jsx": "react", + "esModuleInterop": true, + "target": "es2018" + } +} diff --git a/categories/blob/react/tsconfig.json b/categories/blob/react/tsconfig.json new file mode 100644 index 0000000..0ed68f4 --- /dev/null +++ b/categories/blob/react/tsconfig.json @@ -0,0 +1,21 @@ +{ + "exclude": ["node_modules"], + "include": ["src", "types"], + "compilerOptions": { + "module": "ESNext", + "lib": ["DOM", "ESNext"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./src", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "jsx": "react", + "esModuleInterop": true, + "target": "es2018" + } +} diff --git a/categories/blob/react/vitest.config.ts b/categories/blob/react/vitest.config.ts new file mode 100644 index 0000000..a104d21 --- /dev/null +++ b/categories/blob/react/vitest.config.ts @@ -0,0 +1,8 @@ +/// + +export default ({ + test: { + global: true, + environment: 'jsdom', + }, +}); diff --git a/categories/choice/react/.eslintrc b/categories/choice/react/.eslintrc new file mode 100644 index 0000000..f16a3e8 --- /dev/null +++ b/categories/choice/react/.eslintrc @@ -0,0 +1,13 @@ +{ + "root": true, + "rules": { + "quote-props": "off", + "react/jsx-props-no-spreading": "off" + }, + "extends": [ + "lxsmnsyc/typescript/react" + ], + "parserOptions": { + "project": "./tsconfig.eslint.json" + } +} diff --git a/categories/choice/react/.gitignore b/categories/choice/react/.gitignore new file mode 100644 index 0000000..53992de --- /dev/null +++ b/categories/choice/react/.gitignore @@ -0,0 +1,107 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.production +.env.development + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +.npmrc diff --git a/categories/choice/react/LICENSE b/categories/choice/react/LICENSE new file mode 100644 index 0000000..f24dd21 --- /dev/null +++ b/categories/choice/react/LICENSE @@ -0,0 +1,7 @@ +MIT License Copyright (c) 2023 TheoryOfNekomata + +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 (including the next paragraph) 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. \ No newline at end of file diff --git a/categories/choice/react/package.json b/categories/choice/react/package.json new file mode 100644 index 0000000..d415f08 --- /dev/null +++ b/categories/choice/react/package.json @@ -0,0 +1,84 @@ +{ + "name": "@tesseract-design/web-choice-react", + "version": "0.0.0", + "files": [ + "dist", + "src" + ], + "engines": { + "node": ">=12" + }, + "license": "MIT", + "keywords": [ + "pridepack" + ], + "devDependencies": { + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@types/node": "^18.14.1", + "@types/react": "^18.0.27", + "eslint": "^8.35.0", + "eslint-config-lxsmnsyc": "^0.5.0", + "jsdom": "^21.1.0", + "pridepack": "2.4.4", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-test-renderer": "^18.2.0", + "tslib": "^2.5.0", + "tsx": "^3.12.7", + "typescript": "^4.9.5", + "vitest": "^0.28.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "scripts": { + "prepublishOnly": "pridepack clean && pridepack build", + "build": "pridepack build && tsx scripts/build.ts", + "type-check": "pridepack check", + "lint": "pridepack lint", + "clean": "pridepack clean", + "watch": "pridepack watch", + "start": "pridepack start", + "dev": "pridepack dev", + "test": "vitest" + }, + "private": false, + "description": "Tesseract components for selecting a single value across an array of options.", + "repository": { + "url": "", + "type": "git" + }, + "homepage": "", + "bugs": { + "url": "" + }, + "author": "TheoryOfNekomata ", + "publishConfig": { + "access": "public" + }, + "dependencies": { + "@tesseract-design/web-base": "workspace:*", + "clsx": "^1.2.1" + }, + "types": "./dist/types/index.d.ts", + "main": "./dist/cjs/production/index.js", + "module": "./dist/esm/production/index.js", + "exports": { + ".": { + "development": { + "require": "./dist/cjs/development/index.js", + "import": "./dist/esm/development/index.js" + }, + "require": "./dist/cjs/production/index.js", + "import": "./dist/esm/production/index.js", + "types": "./dist/types/index.d.ts" + }, + "./dist/RadioButton.css": "./dist/RadioButton.css", + "./dist/RadioTickBox.css": "./dist/RadioTickBox.css" + }, + "typesVersions": { + "*": {} + } +} diff --git a/categories/choice/react/pridepack.json b/categories/choice/react/pridepack.json new file mode 100644 index 0000000..841fb58 --- /dev/null +++ b/categories/choice/react/pridepack.json @@ -0,0 +1,3 @@ +{ + "target": "es2018" +} \ No newline at end of file diff --git a/categories/choice/react/scripts/build.ts b/categories/choice/react/scripts/build.ts new file mode 100644 index 0000000..78992e9 --- /dev/null +++ b/categories/choice/react/scripts/build.ts @@ -0,0 +1,14 @@ +import { copyFileSync } from 'fs'; +import { resolve } from 'path'; + +const doCopy = (src: string, dest: string) => { + const trueSrc = resolve(src); + const trueDest = resolve(dest); + console.log('Copying...'); + console.log(`${trueSrc} -> ${trueDest}`); + copyFileSync(trueSrc, trueDest); + console.log('Done'); +} + +doCopy('./src/components/RadioButton/RadioButton.css', './dist/RadioButton.css'); +doCopy('./src/components/RadioTickBox/RadioTickBox.css', './dist/RadioTickBox.css'); diff --git a/categories/choice/react/src/components/ComboBox/index.tsx b/categories/choice/react/src/components/ComboBox/index.tsx new file mode 100644 index 0000000..1619094 --- /dev/null +++ b/categories/choice/react/src/components/ComboBox/index.tsx @@ -0,0 +1,242 @@ +import * as React from 'react'; +import { TextControl } from '@tesseract-design/web-base'; +import clsx from 'clsx'; + +export type ComboBoxDerivedElement = HTMLInputElement; + +export interface ComboBoxProps extends Omit, 'size' | 'type' | 'style' | 'label' | 'list' | 'inputMode'> { + /** + * Short textual description indicating the nature of the component's value. + */ + label?: React.ReactNode, + /** + * Short textual description as guidelines for valid input values. + */ + hint?: React.ReactNode, + /** + * Size of the component. + */ + size?: TextControl.Size, + /** + * Additional description, usually graphical, indicating the nature of the component's value. + */ + indicator?: React.ReactNode, + /** + * Should the component display a border? + */ + border?: boolean, + /** + * Should the component occupy the whole width of its parent? + */ + block?: boolean, + /** + * Type of the component value. + */ + type?: TextControl.InputType, + /** + * Style of the component. + */ + variant?: TextControl.Variant, + /** + * Is the label hidden? + */ + hiddenLabel?: boolean, + /** + * Input mode of the component. + */ + inputMode?: TextControl.InputMode, +} + +/** + * Component for inputting textual values. + * + * This component supports multiline input and adjusts its layout accordingly. + */ +export const ComboBox = React.forwardRef(( + { + label, + hint, + indicator, + size = 'medium' as const, + border = false, + block = false, + type = 'text' as const, + variant = 'default' as const, + hiddenLabel = false, + className, + children, + inputMode = 'text' as const, + id: idProp, + ...etcProps + }: ComboBoxProps, + forwardedRef, +) => { + const labelId = React.useId(); + const datalistId = React.useId(); + const defaultId = React.useId(); + const id = idProp ?? defaultId; + + let resultInputMode = inputMode as React.HTMLProps['inputMode']; + if (type === 'text' && resultInputMode === 'search') { + resultInputMode = 'text'; + } else if (type === 'search' && resultInputMode === 'text') { + resultInputMode = 'search'; + } + + return ( + <> + + {children} + +
+ + { + label && ( + + ) + } + {hint && ( +
+
+ {hint} +
+
+ )} + {indicator && ( +
+ {indicator} +
+ )} + { + border && ( + + ) + } +
+ + ); +}); + +ComboBox.displayName = 'ComboBox'; + +ComboBox.defaultProps = { + label: undefined, + hint: undefined, + indicator: undefined, + size: 'medium', + border: false, + block: false, + type: 'text', + variant: 'default', + hiddenLabel: false, + inputMode: 'text', +}; diff --git a/categories/choice/react/src/components/DropdownSelect/index.tsx b/categories/choice/react/src/components/DropdownSelect/index.tsx new file mode 100644 index 0000000..338fbae --- /dev/null +++ b/categories/choice/react/src/components/DropdownSelect/index.tsx @@ -0,0 +1,216 @@ +import * as React from 'react'; +import { TextControl } from '@tesseract-design/web-base'; +import clsx from 'clsx'; + +export type DropdownSelectDerivedElement = HTMLSelectElement; + +export interface DropdownSelectProps extends Omit, 'size' | 'type' | 'style' | 'label' | 'list' | 'multiple'> { + /** + * Short textual description indicating the nature of the component's value. + */ + label?: React.ReactNode, + /** + * Short textual description as guidelines for valid input values. + */ + hint?: React.ReactNode, + /** + * Size of the component. + */ + size?: TextControl.Size, + /** + * Additional description, usually graphical, indicating the nature of the component's value. + */ + indicator?: React.ReactNode, + /** + * Should the component display a border? + */ + border?: boolean, + /** + * Should the component occupy the whole width of its parent? + */ + block?: boolean, + /** + * Style of the component. + */ + variant?: TextControl.Variant, + /** + * Is the label hidden? + */ + hiddenLabel?: boolean, +} + +/** + * Component for inputting textual values. + * + * This component supports multiline input and adjusts its layout accordingly. + */ +export const DropdownSelect = React.forwardRef( + ( + { + label, + hint, + indicator, + size = 'medium' as const, + border = false, + block = false, + variant = 'default' as const, + hiddenLabel = false, + className, + children, + id: idProp, + ...etcProps + }: DropdownSelectProps, + forwardedRef, + ) => { + const labelId = React.useId(); + const defaultId = React.useId(); + const id = idProp ?? defaultId; + + return ( +
+ + { + label && ( + + ) + } + {hint && ( +
+
+ {hint} +
+
+ )} + {indicator && ( +
+ {indicator} +
+ )} + { + border && ( + + ) + } +
+ ); + }, +); + +DropdownSelect.displayName = 'DropdownSelect'; + +DropdownSelect.defaultProps = { + label: undefined, + hint: undefined, + indicator: undefined, + size: 'medium', + border: false, + block: false, + variant: 'default', + hiddenLabel: false, +}; diff --git a/categories/choice/react/src/components/MenuSelect/index.tsx b/categories/choice/react/src/components/MenuSelect/index.tsx new file mode 100644 index 0000000..a457684 --- /dev/null +++ b/categories/choice/react/src/components/MenuSelect/index.tsx @@ -0,0 +1,234 @@ +import * as React from 'react'; +import { TextControl } from '@tesseract-design/web-base'; +import clsx from 'clsx'; + +export type MenuSelectDerivedElement = HTMLSelectElement; + +export interface MenuSelectProps extends Omit, 'size' | 'style' | 'label' | 'multiple'> { + /** + * Short textual description indicating the nature of the component's value. + */ + label?: React.ReactNode, + /** + * Short textual description as guidelines for valid input values. + */ + hint?: React.ReactNode, + /** + * Size of the component. + */ + size?: TextControl.Size, + /** + * Additional description, usually graphical, indicating the nature of the component's value. + */ + indicator?: React.ReactNode, + /** + * Should the component display a border? + */ + border?: boolean, + /** + * Should the component occupy the whole width of its parent? + */ + block?: boolean, + /** + * Style of the component. + */ + variant?: TextControl.Variant, + /** + * Is the label hidden? + */ + hiddenLabel?: boolean, + /** + * Starting height of the component. + */ + startingHeight?: number | string, +} + +/** + * Component for inputting textual values. + * + * This component supports multiline input and adjusts its layout accordingly. + */ +export const MenuSelect = React.forwardRef( + ( + { + label, + hint, + indicator, + size = 'medium' as const, + border = false, + block = false, + variant = 'default' as const, + hiddenLabel = false, + className, + startingHeight = '15rem', + id: idProp, + ...etcProps + }: MenuSelectProps, + forwardedRef, + ) => { + const labelId = React.useId(); + const defaultId = React.useId(); + const id = idProp ?? defaultId; + + return ( +
+ + + + ); +}); + +RadioButton.displayName = 'RadioButton'; + +RadioButton.defaultProps = { + badge: undefined, + block: false, + compact: false, + subtext: undefined, + size: 'medium', + variant: 'filled', +}; diff --git a/categories/choice/react/src/components/RadioTickBox/RadioTickBox.css b/categories/choice/react/src/components/RadioTickBox/RadioTickBox.css new file mode 100644 index 0000000..e71a167 --- /dev/null +++ b/categories/choice/react/src/components/RadioTickBox/RadioTickBox.css @@ -0,0 +1,7 @@ +.tesseract-design-radio-tick-box + label + label > :first-child > :first-child { + display: none; +} + +.tesseract-design-radio-tick-box:checked + label + label > :first-child > :first-child { + display: block; +} diff --git a/categories/choice/react/src/components/RadioTickBox/index.tsx b/categories/choice/react/src/components/RadioTickBox/index.tsx new file mode 100644 index 0000000..124eb82 --- /dev/null +++ b/categories/choice/react/src/components/RadioTickBox/index.tsx @@ -0,0 +1,92 @@ +import * as React from 'react'; +import clsx from 'clsx'; + +export type RadioTickBoxDerivedElement = HTMLInputElement; + +export interface RadioTickBoxProps extends Omit, 'type' | 'size'> { + block?: boolean; + subtext?: React.ReactNode; +} + +export const RadioTickBox = React.forwardRef(( + { + children, + block = false, + id: idProp, + className, + subtext, + style, + ...etcProps + }, + forwardedRef, +) => { + const defaultId = React.useId(); + const id = idProp ?? defaultId; + return ( +
+ + + + {subtext && ( +
+ {subtext} +
+ )} +
+ ); +}); + +RadioTickBox.displayName = 'RadioTickBox'; + +RadioTickBox.defaultProps = { + block: false, + subtext: undefined, +}; diff --git a/packages/web/categories/option/react/src/index.ts b/categories/choice/react/src/index.ts similarity index 55% rename from packages/web/categories/option/react/src/index.ts rename to categories/choice/react/src/index.ts index 0d8a157..c756fdb 100644 --- a/packages/web/categories/option/react/src/index.ts +++ b/categories/choice/react/src/index.ts @@ -3,7 +3,3 @@ export * from './components/DropdownSelect'; export * from './components/MenuSelect'; export * from './components/RadioButton'; export * from './components/RadioTickBox'; -export * from './components/TagInput'; -export * from './components/ToggleButton'; -export * from './components/ToggleSwitch'; -export * from './components/ToggleTickBox'; diff --git a/categories/choice/react/tsconfig.eslint.json b/categories/choice/react/tsconfig.eslint.json new file mode 100644 index 0000000..16f2e87 --- /dev/null +++ b/categories/choice/react/tsconfig.eslint.json @@ -0,0 +1,21 @@ +{ + "exclude": ["node_modules"], + "include": ["src", "types", "test"], + "compilerOptions": { + "module": "ESNext", + "lib": ["DOM", "ESNext"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "jsx": "react", + "esModuleInterop": true, + "target": "es2018" + } +} diff --git a/categories/choice/react/tsconfig.json b/categories/choice/react/tsconfig.json new file mode 100644 index 0000000..0ed68f4 --- /dev/null +++ b/categories/choice/react/tsconfig.json @@ -0,0 +1,21 @@ +{ + "exclude": ["node_modules"], + "include": ["src", "types"], + "compilerOptions": { + "module": "ESNext", + "lib": ["DOM", "ESNext"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./src", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "jsx": "react", + "esModuleInterop": true, + "target": "es2018" + } +} diff --git a/categories/choice/react/vitest.config.ts b/categories/choice/react/vitest.config.ts new file mode 100644 index 0000000..a104d21 --- /dev/null +++ b/categories/choice/react/vitest.config.ts @@ -0,0 +1,8 @@ +/// + +export default ({ + test: { + global: true, + environment: 'jsdom', + }, +}); diff --git a/categories/color/react/.eslintrc b/categories/color/react/.eslintrc new file mode 100644 index 0000000..4df382e --- /dev/null +++ b/categories/color/react/.eslintrc @@ -0,0 +1,12 @@ +{ + "root": true, + "rules": { + "react/jsx-props-no-spreading": "off" + }, + "extends": [ + "lxsmnsyc/typescript/react" + ], + "parserOptions": { + "project": "./tsconfig.eslint.json" + } +} diff --git a/categories/color/react/.gitignore b/categories/color/react/.gitignore new file mode 100644 index 0000000..53992de --- /dev/null +++ b/categories/color/react/.gitignore @@ -0,0 +1,107 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.production +.env.development + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +.npmrc diff --git a/categories/color/react/LICENSE b/categories/color/react/LICENSE new file mode 100644 index 0000000..f24dd21 --- /dev/null +++ b/categories/color/react/LICENSE @@ -0,0 +1,7 @@ +MIT License Copyright (c) 2023 TheoryOfNekomata + +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 (including the next paragraph) 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. \ No newline at end of file diff --git a/categories/color/react/package.json b/categories/color/react/package.json new file mode 100644 index 0000000..d58f29c --- /dev/null +++ b/categories/color/react/package.json @@ -0,0 +1,80 @@ +{ + "name": "@tesseract-design/web-color-react", + "version": "0.0.0", + "files": [ + "dist", + "src" + ], + "engines": { + "node": ">=12" + }, + "license": "MIT", + "keywords": [ + "pridepack" + ], + "devDependencies": { + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@types/node": "^18.14.1", + "@types/react": "^18.0.27", + "eslint": "^8.35.0", + "eslint-config-lxsmnsyc": "^0.5.0", + "jsdom": "^21.1.0", + "pridepack": "2.4.4", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-test-renderer": "^18.2.0", + "tslib": "^2.5.0", + "typescript": "^4.9.5", + "vitest": "^0.28.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "scripts": { + "prepublishOnly": "pridepack clean && pridepack build", + "build": "pridepack build", + "type-check": "pridepack check", + "lint": "pridepack lint", + "clean": "pridepack clean", + "watch": "pridepack watch", + "start": "pridepack start", + "dev": "pridepack dev", + "test": "vitest" + }, + "private": false, + "description": "Tesseract components for inputting color data.", + "repository": { + "url": "", + "type": "git" + }, + "homepage": "", + "bugs": { + "url": "" + }, + "author": "TheoryOfNekomata ", + "publishConfig": { + "access": "public" + }, + "dependencies": { + "clsx": "^1.2.1" + }, + "types": "./dist/types/index.d.ts", + "main": "./dist/cjs/production/index.js", + "module": "./dist/esm/production/index.js", + "exports": { + ".": { + "development": { + "require": "./dist/cjs/development/index.js", + "import": "./dist/esm/development/index.js" + }, + "require": "./dist/cjs/production/index.js", + "import": "./dist/esm/production/index.js", + "types": "./dist/types/index.d.ts" + } + }, + "typesVersions": { + "*": {} + } +} diff --git a/categories/color/react/pridepack.json b/categories/color/react/pridepack.json new file mode 100644 index 0000000..841fb58 --- /dev/null +++ b/categories/color/react/pridepack.json @@ -0,0 +1,3 @@ +{ + "target": "es2018" +} \ No newline at end of file diff --git a/categories/color/react/src/components/Swatch/index.tsx b/categories/color/react/src/components/Swatch/index.tsx new file mode 100644 index 0000000..138f851 --- /dev/null +++ b/categories/color/react/src/components/Swatch/index.tsx @@ -0,0 +1,102 @@ +import * as React from 'react'; +import clsx from 'clsx'; + +type RgbTuple = [number, number, number]; + +export type SwatchDerivedElement = HTMLInputElement; + +export interface SwatchProps extends Omit, 'color'> { + color: RgbTuple; + mode?: 'rgb' | 'hsl'; +} + +export const useSwatchControls = () => { + const id = React.useId(); + const copyColor: React.ReactEventHandler = React.useCallback((e) => { + const { value } = e.currentTarget; + // eslint-disable-next-line no-void + void window.navigator.clipboard.writeText(value); + }, []); + return React.useMemo(() => ({ + id, + copyColor, + }), [id, copyColor]); +}; + +export const Swatch = React.forwardRef(({ + color, + mode = 'rgb', + className, + style, + ...etcProps +}, forwardedRef) => { + const { id, copyColor } = useSwatchControls(); + const colorValue = `${mode}(${color.join(', ')})`; + + return ( + + + + + ); +}); + +Swatch.displayName = 'Swatch'; + +Swatch.defaultProps = { + mode: 'rgb', +}; diff --git a/categories/color/react/src/index.ts b/categories/color/react/src/index.ts new file mode 100644 index 0000000..a436d9f --- /dev/null +++ b/categories/color/react/src/index.ts @@ -0,0 +1 @@ +export * from './components/Swatch'; diff --git a/categories/color/react/tsconfig.eslint.json b/categories/color/react/tsconfig.eslint.json new file mode 100644 index 0000000..16f2e87 --- /dev/null +++ b/categories/color/react/tsconfig.eslint.json @@ -0,0 +1,21 @@ +{ + "exclude": ["node_modules"], + "include": ["src", "types", "test"], + "compilerOptions": { + "module": "ESNext", + "lib": ["DOM", "ESNext"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "jsx": "react", + "esModuleInterop": true, + "target": "es2018" + } +} diff --git a/categories/color/react/tsconfig.json b/categories/color/react/tsconfig.json new file mode 100644 index 0000000..0ed68f4 --- /dev/null +++ b/categories/color/react/tsconfig.json @@ -0,0 +1,21 @@ +{ + "exclude": ["node_modules"], + "include": ["src", "types"], + "compilerOptions": { + "module": "ESNext", + "lib": ["DOM", "ESNext"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./src", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "jsx": "react", + "esModuleInterop": true, + "target": "es2018" + } +} diff --git a/categories/color/react/vitest.config.ts b/categories/color/react/vitest.config.ts new file mode 100644 index 0000000..a104d21 --- /dev/null +++ b/categories/color/react/vitest.config.ts @@ -0,0 +1,8 @@ +/// + +export default ({ + test: { + global: true, + environment: 'jsdom', + }, +}); diff --git a/categories/formatted/react/.eslintrc b/categories/formatted/react/.eslintrc new file mode 100644 index 0000000..f16a3e8 --- /dev/null +++ b/categories/formatted/react/.eslintrc @@ -0,0 +1,13 @@ +{ + "root": true, + "rules": { + "quote-props": "off", + "react/jsx-props-no-spreading": "off" + }, + "extends": [ + "lxsmnsyc/typescript/react" + ], + "parserOptions": { + "project": "./tsconfig.eslint.json" + } +} diff --git a/categories/formatted/react/.gitignore b/categories/formatted/react/.gitignore new file mode 100644 index 0000000..53992de --- /dev/null +++ b/categories/formatted/react/.gitignore @@ -0,0 +1,107 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.production +.env.development + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +.npmrc diff --git a/categories/formatted/react/LICENSE b/categories/formatted/react/LICENSE new file mode 100644 index 0000000..f24dd21 --- /dev/null +++ b/categories/formatted/react/LICENSE @@ -0,0 +1,7 @@ +MIT License Copyright (c) 2023 TheoryOfNekomata + +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 (including the next paragraph) 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. \ No newline at end of file diff --git a/packages/web/categories/formatted/react/package.json b/categories/formatted/react/package.json similarity index 68% rename from packages/web/categories/formatted/react/package.json rename to categories/formatted/react/package.json index a108b6c..355a1af 100644 --- a/packages/web/categories/formatted/react/package.json +++ b/categories/formatted/react/package.json @@ -6,32 +6,27 @@ "src" ], "engines": { - "node": ">=10" + "node": ">=12" }, "license": "MIT", "keywords": [ "pridepack" ], - "dependencies": { - "@tesseract-design/web-base-textcontrol": "link:../../../base/textcontrol" - }, "devDependencies": { - "@testing-library/jest-dom": "^5.16.4", - "@testing-library/react": "^13.3.0", - "@testing-library/react-hooks": "^8.0.1", - "@testing-library/user-event": "^13.5.0", - "@types/node": "^18.0.0", - "@types/react": "^18.0.14", - "eslint": "^8.20.0", - "eslint-config-lxsmnsyc": "^0.4.7", - "jsdom": "^20.0.0", + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@types/node": "^18.14.1", + "@types/react": "^18.0.27", + "eslint": "^8.35.0", + "eslint-config-lxsmnsyc": "^0.5.0", + "jsdom": "^21.1.0", "pridepack": "2.4.4", "react": "^18.2.0", "react-dom": "^18.2.0", "react-test-renderer": "^18.2.0", - "tslib": "^2.4.0", - "typescript": "^4.7.4", - "vitest": "^0.31.0" + "tslib": "^2.5.0", + "typescript": "^4.9.5", + "vitest": "^0.28.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", @@ -48,8 +43,8 @@ "dev": "pridepack dev", "test": "vitest" }, - "private": true, - "description": "Formatted components for Tesseract for use in React.", + "private": false, + "description": "Tesseract components for inputting formatted data.", "repository": { "url": "", "type": "git" @@ -60,9 +55,15 @@ }, "author": "TheoryOfNekomata ", "publishConfig": { - "access": "restricted" + "access": "public" + }, + "dependencies": { + "clsx": "^1.2.1", + "@tesseract-design/web-base": "workspace:*" }, "types": "./dist/types/index.d.ts", + "main": "./dist/cjs/production/index.js", + "module": "./dist/esm/production/index.js", "exports": { ".": { "development": { @@ -76,7 +77,5 @@ }, "typesVersions": { "*": {} - }, - "main": "./dist/cjs/production/index.js", - "module": "./dist/esm/production/index.js" + } } diff --git a/categories/formatted/react/pridepack.json b/categories/formatted/react/pridepack.json new file mode 100644 index 0000000..841fb58 --- /dev/null +++ b/categories/formatted/react/pridepack.json @@ -0,0 +1,3 @@ +{ + "target": "es2018" +} \ No newline at end of file diff --git a/categories/formatted/react/src/components/EmailInput/index.tsx b/categories/formatted/react/src/components/EmailInput/index.tsx new file mode 100644 index 0000000..36073e7 --- /dev/null +++ b/categories/formatted/react/src/components/EmailInput/index.tsx @@ -0,0 +1,214 @@ +import * as React from 'react'; +import { TextControl } from '@tesseract-design/web-base'; +import clsx from 'clsx'; + +export type EmailInputDerivedElement = HTMLInputElement; + +export interface EmailInputProps extends Omit, 'size' | 'type' | 'label' | 'inputMode'> { + /** + * Short textual description indicating the nature of the component's value. + */ + label?: React.ReactNode, + /** + * Short textual description as guidelines for valid input values. + */ + hint?: React.ReactNode, + /** + * Size of the component. + */ + size?: TextControl.Size, + /** + * Additional description, usually graphical, indicating the nature of the component's value. + */ + indicator?: React.ReactNode, + /** + * Should the component display a border? + */ + border?: boolean, + /** + * Should the component occupy the whole width of its parent? + */ + block?: boolean, + /** + * Style of the component. + */ + variant?: TextControl.Variant, + /** + * Is the label hidden? + */ + hiddenLabel?: boolean, +} + +/** + * Component for inputting textual values. + */ +export const EmailInput = React.forwardRef( + ( + { + label, + hint, + indicator, + size = 'medium' as const, + border = false, + block = false, + variant = 'default' as const, + hiddenLabel = false, + className, + id: idProp, + style, + ...etcProps + }: EmailInputProps, + forwardedRef, + ) => { + const labelId = React.useId(); + const defaultId = React.useId(); + const id = idProp ?? defaultId; + + return ( +
+ + { + label && ( + + ) + } + {hint && ( +
+
+ {hint} +
+
+ )} + {indicator && ( +
+ {indicator} +
+ )} + { + border && ( + + ) + } +
+ ); + }, +); + +EmailInput.displayName = 'EmailInput'; + +EmailInput.defaultProps = { + label: undefined, + hint: undefined, + indicator: undefined, + size: 'medium', + border: false, + block: false, + variant: 'default', + hiddenLabel: false, +}; diff --git a/categories/formatted/react/src/components/PhoneNumberInput/index.tsx b/categories/formatted/react/src/components/PhoneNumberInput/index.tsx new file mode 100644 index 0000000..fc88417 --- /dev/null +++ b/categories/formatted/react/src/components/PhoneNumberInput/index.tsx @@ -0,0 +1,215 @@ +import * as React from 'react'; +import { TextControl } from '@tesseract-design/web-base'; +import clsx from 'clsx'; + +export type PhoneNumberInputDerivedElement = HTMLInputElement; + +export interface PhoneNumberInputProps extends Omit, 'size' | 'type' | 'label' | 'inputMode'> { + /** + * Short textual description indicating the nature of the component's value. + */ + label?: React.ReactNode, + /** + * Short textual description as guidelines for valid input values. + */ + hint?: React.ReactNode, + /** + * Size of the component. + */ + size?: TextControl.Size, + /** + * Additional description, usually graphical, indicating the nature of the component's value. + */ + indicator?: React.ReactNode, + /** + * Should the component display a border? + */ + border?: boolean, + /** + * Should the component occupy the whole width of its parent? + */ + block?: boolean, + /** + * Style of the component. + */ + variant?: TextControl.Variant, + /** + * Is the label hidden? + */ + hiddenLabel?: boolean, +} + +/** + * Component for inputting textual values. + */ +export const PhoneNumberInput = React.forwardRef< + PhoneNumberInputDerivedElement, + PhoneNumberInputProps +>(( + { + label, + hint, + indicator, + size = 'medium' as const, + border = false, + block = false, + variant = 'default' as const, + hiddenLabel = false, + className, + id: idProp, + style, + ...etcProps + }: PhoneNumberInputProps, + forwardedRef, +) => { + const labelId = React.useId(); + const defaultId = React.useId(); + const id = idProp ?? defaultId; + + return ( +
+ + { + label && ( + + ) + } + {hint && ( +
+
+ {hint} +
+
+ )} + {indicator && ( +
+ {indicator} +
+ )} + { + border && ( + + ) + } +
+ ); +}); + +PhoneNumberInput.displayName = 'PhoneNumberInput'; + +PhoneNumberInput.defaultProps = { + label: undefined, + hint: undefined, + indicator: undefined, + size: 'medium', + border: false, + block: false, + variant: 'default', + hiddenLabel: false, +}; diff --git a/categories/formatted/react/src/components/UrlInput/index.tsx b/categories/formatted/react/src/components/UrlInput/index.tsx new file mode 100644 index 0000000..00e03ff --- /dev/null +++ b/categories/formatted/react/src/components/UrlInput/index.tsx @@ -0,0 +1,212 @@ +import * as React from 'react'; +import { TextControl } from '@tesseract-design/web-base'; +import clsx from 'clsx'; + +export type UrlInputDerivedElement = HTMLInputElement; + +export interface UrlInputProps extends Omit, 'size' | 'type' | 'label' | 'inputMode'> { + /** + * Short textual description indicating the nature of the component's value. + */ + label?: React.ReactNode, + /** + * Short textual description as guidelines for valid input values. + */ + hint?: React.ReactNode, + /** + * Size of the component. + */ + size?: TextControl.Size, + /** + * Additional description, usually graphical, indicating the nature of the component's value. + */ + indicator?: React.ReactNode, + /** + * Should the component display a border? + */ + border?: boolean, + /** + * Should the component occupy the whole width of its parent? + */ + block?: boolean, + /** + * Style of the component. + */ + variant?: TextControl.Variant, + /** + * Is the label hidden? + */ + hiddenLabel?: boolean, +} + +/** + * Component for inputting textual values. + */ +export const UrlInput = React.forwardRef(( + { + label, + hint, + indicator, + size = 'medium' as const, + border = false, + block = false, + variant = 'default' as const, + hiddenLabel = false, + className, + style, + id: idProp, + ...etcProps + }: UrlInputProps, + forwardedRef, +) => { + const labelId = React.useId(); + const defaultId = React.useId(); + const id = idProp ?? defaultId; + + return ( +
+ + { + label && ( + + ) + } + {hint && ( +
+
+ {hint} +
+
+ )} + {indicator && ( +
+ {indicator} +
+ )} + { + border && ( + + ) + } +
+ ); +}); + +UrlInput.displayName = 'UrlInput'; + +UrlInput.defaultProps = { + label: undefined, + hint: undefined, + indicator: undefined, + size: 'medium', + border: false, + block: false, + variant: 'default', + hiddenLabel: false, +}; diff --git a/packages/web/categories/formatted/react/src/index.ts b/categories/formatted/react/src/index.ts similarity index 64% rename from packages/web/categories/formatted/react/src/index.ts rename to categories/formatted/react/src/index.ts index f4a2222..7b0c349 100644 --- a/packages/web/categories/formatted/react/src/index.ts +++ b/categories/formatted/react/src/index.ts @@ -1,3 +1,3 @@ -export * from './components/EmailAddressInput'; +export * from './components/EmailInput'; export * from './components/PhoneNumberInput'; export * from './components/UrlInput'; diff --git a/categories/formatted/react/tsconfig.eslint.json b/categories/formatted/react/tsconfig.eslint.json new file mode 100644 index 0000000..16f2e87 --- /dev/null +++ b/categories/formatted/react/tsconfig.eslint.json @@ -0,0 +1,21 @@ +{ + "exclude": ["node_modules"], + "include": ["src", "types", "test"], + "compilerOptions": { + "module": "ESNext", + "lib": ["DOM", "ESNext"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "jsx": "react", + "esModuleInterop": true, + "target": "es2018" + } +} diff --git a/categories/formatted/react/tsconfig.json b/categories/formatted/react/tsconfig.json new file mode 100644 index 0000000..0ed68f4 --- /dev/null +++ b/categories/formatted/react/tsconfig.json @@ -0,0 +1,21 @@ +{ + "exclude": ["node_modules"], + "include": ["src", "types"], + "compilerOptions": { + "module": "ESNext", + "lib": ["DOM", "ESNext"], + "importHelpers": true, + "declaration": true, + "sourceMap": true, + "rootDir": "./src", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "jsx": "react", + "esModuleInterop": true, + "target": "es2018" + } +} diff --git a/categories/formatted/react/vitest.config.ts b/categories/formatted/react/vitest.config.ts new file mode 100644 index 0000000..a104d21 --- /dev/null +++ b/categories/formatted/react/vitest.config.ts @@ -0,0 +1,8 @@ +/// + +export default ({ + test: { + global: true, + environment: 'jsdom', + }, +}); diff --git a/categories/freeform/react/.eslintrc b/categories/freeform/react/.eslintrc new file mode 100644 index 0000000..f16a3e8 --- /dev/null +++ b/categories/freeform/react/.eslintrc @@ -0,0 +1,13 @@ +{ + "root": true, + "rules": { + "quote-props": "off", + "react/jsx-props-no-spreading": "off" + }, + "extends": [ + "lxsmnsyc/typescript/react" + ], + "parserOptions": { + "project": "./tsconfig.eslint.json" + } +} diff --git a/categories/freeform/react/.gitignore b/categories/freeform/react/.gitignore new file mode 100644 index 0000000..53992de --- /dev/null +++ b/categories/freeform/react/.gitignore @@ -0,0 +1,107 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.production +.env.development + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +.npmrc diff --git a/categories/freeform/react/LICENSE b/categories/freeform/react/LICENSE new file mode 100644 index 0000000..f24dd21 --- /dev/null +++ b/categories/freeform/react/LICENSE @@ -0,0 +1,7 @@ +MIT License Copyright (c) 2023 TheoryOfNekomata + +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 (including the next paragraph) 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. \ No newline at end of file diff --git a/packages/web/categories/freeform/react/package.json b/categories/freeform/react/package.json similarity index 68% rename from packages/web/categories/freeform/react/package.json rename to categories/freeform/react/package.json index cfec58b..d4c1bd9 100644 --- a/packages/web/categories/freeform/react/package.json +++ b/categories/freeform/react/package.json @@ -6,32 +6,27 @@ "src" ], "engines": { - "node": ">=10" + "node": ">=12" }, "license": "MIT", "keywords": [ "pridepack" ], - "dependencies": { - "@tesseract-design/web-base-textcontrol": "link:../../../base/textcontrol" - }, "devDependencies": { - "@testing-library/jest-dom": "^5.16.4", - "@testing-library/react": "^13.3.0", - "@testing-library/react-hooks": "^8.0.1", - "@testing-library/user-event": "^13.5.0", - "@types/node": "^18.0.0", - "@types/react": "^18.0.14", - "eslint": "^8.20.0", - "eslint-config-lxsmnsyc": "^0.4.7", - "jsdom": "^20.0.0", + "@testing-library/jest-dom": "^5.16.5", + "@testing-library/react": "^13.4.0", + "@types/node": "^18.14.1", + "@types/react": "^18.0.27", + "eslint": "^8.35.0", + "eslint-config-lxsmnsyc": "^0.5.0", + "jsdom": "^21.1.0", "pridepack": "2.4.4", "react": "^18.2.0", "react-dom": "^18.2.0", "react-test-renderer": "^18.2.0", - "tslib": "^2.4.0", - "typescript": "^4.7.4", - "vitest": "^0.31.0" + "tslib": "^2.5.0", + "typescript": "^4.9.5", + "vitest": "^0.28.1" }, "peerDependencies": { "react": "^16.8 || ^17.0 || ^18.0", @@ -48,8 +43,8 @@ "dev": "pridepack dev", "test": "vitest" }, - "private": true, - "description": "Freeform components for Tesseract for use in React.", + "private": false, + "description": "Tesseract components for inputting freeform data.", "repository": { "url": "", "type": "git" @@ -60,9 +55,15 @@ }, "author": "TheoryOfNekomata ", "publishConfig": { - "access": "restricted" + "access": "public" + }, + "dependencies": { + "clsx": "^1.2.1", + "@tesseract-design/web-base": "workspace:*" }, "types": "./dist/types/index.d.ts", + "main": "./dist/cjs/production/index.js", + "module": "./dist/esm/production/index.js", "exports": { ".": { "development": { @@ -76,7 +77,5 @@ }, "typesVersions": { "*": {} - }, - "main": "./dist/cjs/production/index.js", - "module": "./dist/esm/production/index.js" + } } diff --git a/categories/freeform/react/pridepack.json b/categories/freeform/react/pridepack.json new file mode 100644 index 0000000..841fb58 --- /dev/null +++ b/categories/freeform/react/pridepack.json @@ -0,0 +1,3 @@ +{ + "target": "es2018" +} \ No newline at end of file diff --git a/categories/freeform/react/src/components/MaskedTextInput/index.tsx b/categories/freeform/react/src/components/MaskedTextInput/index.tsx new file mode 100644 index 0000000..d89fe99 --- /dev/null +++ b/categories/freeform/react/src/components/MaskedTextInput/index.tsx @@ -0,0 +1,215 @@ +import * as React from 'react'; +import { TextControl } from '@tesseract-design/web-base'; +import clsx from 'clsx'; + +export type MaskedTextInputDerivedElement = HTMLInputElement; + +export interface MaskedTextInputProps extends Omit, 'size' | 'type' | 'label'> { + /** + * Short textual description indicating the nature of the component's value. + */ + label?: React.ReactNode, + /** + * Short textual description as guidelines for valid input values. + */ + hint?: React.ReactNode, + /** + * Size of the component. + */ + size?: TextControl.Size, + /** + * Additional description, usually graphical, indicating the nature of the component's value. + */ + indicator?: React.ReactNode, + /** + * Should the component display a border? + */ + border?: boolean, + /** + * Should the component occupy the whole width of its parent? + */ + block?: boolean, + /** + * Style of the component. + */ + variant?: TextControl.Variant, + /** + * Is the label hidden? + */ + hiddenLabel?: boolean, +} + +/** + * Component for inputting textual values. + */ +export const MaskedTextInput = React.forwardRef< + MaskedTextInputDerivedElement, + MaskedTextInputProps +>(( + { + label, + hint, + indicator, + size = 'medium' as const, + border = false, + block = false, + variant = 'default' as const, + hiddenLabel = false, + className, + id: idProp, + style, + ...etcProps + }: MaskedTextInputProps, + forwardedRef, +) => { + const labelId = React.useId(); + const defaultId = React.useId(); + const id = idProp ?? defaultId; + + return ( +
+ + { + label && ( + + ) + } + {hint && ( +
+
+ {hint} +
+
+ )} + {indicator && ( +
+ {indicator} +
+ )} + { + border && ( + + ) + } +
+ ); +}); + +MaskedTextInput.displayName = 'MaskedTextInput'; + +MaskedTextInput.defaultProps = { + label: undefined, + hint: undefined, + size: 'medium', + indicator: undefined, + border: false, + block: false, + variant: 'default', + hiddenLabel: false, +}; diff --git a/categories/freeform/react/src/components/MultilineTextInput/index.tsx b/categories/freeform/react/src/components/MultilineTextInput/index.tsx new file mode 100644 index 0000000..93a8c76 --- /dev/null +++ b/categories/freeform/react/src/components/MultilineTextInput/index.tsx @@ -0,0 +1,230 @@ +import * as React from 'react'; +import { TextControl } from '@tesseract-design/web-base'; +import clsx from 'clsx'; + +export type MultilineTextInputDerivedElement = HTMLTextAreaElement; + +export interface MultilineTextInputProps extends Omit, 'size' | 'label' | 'inputMode'> { + /** + * Short textual description indicating the nature of the component's value. + */ + label?: React.ReactNode, + /** + * Short textual description as guidelines for valid input values. + */ + hint?: React.ReactNode, + /** + * Size of the component. + */ + size?: TextControl.Size, + /** + * Additional description, usually graphical, indicating the nature of the component's value. + */ + indicator?: React.ReactNode, + /** + * Should the component display a border? + */ + border?: boolean, + /** + * Should the component occupy the whole width of its parent? + */ + block?: boolean, + /** + * Style of the component. + */ + variant?: TextControl.Variant, + /** + * Is the label hidden? + */ + hiddenLabel?: boolean, +} + +/** + * Component for inputting textual values. + * + * This component supports multiline input and adjusts its layout accordingly. + */ +export const MultilineTextInput = React.forwardRef< + MultilineTextInputDerivedElement, + MultilineTextInputProps +>(( + { + label, + hint, + indicator, + size = 'medium' as const, + border = false, + block = false, + variant = 'default' as const, + hiddenLabel = false, + className, + style, + id: idProp, + ...etcProps + }: MultilineTextInputProps, + forwardedRef, +) => { + const labelId = React.useId(); + const defaultId = React.useId(); + const id = idProp ?? defaultId; + + return ( +
+