diff --git a/package-lock.json b/package-lock.json index 97d6ae894a..337b3adccc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "workspaces": [ "packages/antd", "packages/bootstrap-4", + "packages/carbon", "packages/chakra-ui", "packages/core", "packages/docs", @@ -2374,6 +2375,160 @@ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true }, + "node_modules/@carbon/colors": { + "version": "11.22.0", + "resolved": "https://registry.npmjs.org/@carbon/colors/-/colors-11.22.0.tgz", + "integrity": "sha512-IRbzstMpIhD1ULhfYhZ5ne7kIKdhQhiMeltWRPw+7wlFB5ezFoX+kX3ILqdz20CkcrpLu+TVKLD79Zv/+4RD6w==", + "hasInstallScript": true, + "dependencies": { + "@ibm/telemetry-js": "^1.5.0" + } + }, + "node_modules/@carbon/feature-flags": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@carbon/feature-flags/-/feature-flags-0.20.0.tgz", + "integrity": "sha512-OEYrazJa0nEEHbBDyarXIz6kjWgqsJggjbNAcVOxx0Nvma1nZBd+SwXKwdbMkBZagSSC816dV12oZJtr+GIZZg==", + "hasInstallScript": true, + "dependencies": { + "@ibm/telemetry-js": "^1.5.0" + } + }, + "node_modules/@carbon/grid": { + "version": "11.23.0", + "resolved": "https://registry.npmjs.org/@carbon/grid/-/grid-11.23.0.tgz", + "integrity": "sha512-/8SiXzefUdUeIRzMxKB2+xq65knjkDas2TcZj0NS7dnDIEr5HarWTABh/H5b5BTFEJXos3PfEH6X5OUDuK4qpg==", + "hasInstallScript": true, + "dependencies": { + "@carbon/layout": "^11.22.0", + "@ibm/telemetry-js": "^1.5.0" + } + }, + "node_modules/@carbon/icon-helpers": { + "version": "10.48.0", + "resolved": "https://registry.npmjs.org/@carbon/icon-helpers/-/icon-helpers-10.48.0.tgz", + "integrity": "sha512-umCh4iBDKYF0+SB2yu8CqLDek2A9/Bv71YBFxngh77H20KiAheP8Zt7BZjSfI8vbm+q9zbIkBLMF8P5Da8i25w==", + "hasInstallScript": true, + "dependencies": { + "@ibm/telemetry-js": "^1.5.0" + } + }, + "node_modules/@carbon/icons-react": { + "version": "11.43.0", + "resolved": "https://registry.npmjs.org/@carbon/icons-react/-/icons-react-11.43.0.tgz", + "integrity": "sha512-nQUj8s94j0P3ja2+J9Og06rWFsuetvyc+PUNgkUT0w/ZezfMibX05PafX3pdNT0Gjy5cvRqwbrRLlNyYhfwlwQ==", + "hasInstallScript": true, + "dependencies": { + "@carbon/icon-helpers": "^10.48.0", + "@ibm/telemetry-js": "^1.5.0", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">=16" + } + }, + "node_modules/@carbon/layout": { + "version": "11.22.0", + "resolved": "https://registry.npmjs.org/@carbon/layout/-/layout-11.22.0.tgz", + "integrity": "sha512-G9HUJhGW+hNfUKyCLUZior5PDz808prB2Xr3vWF/rqNwLIDKhva/wCXBW2Xl0LavzonuibaCavcSYJGDkpDKhw==", + "hasInstallScript": true, + "dependencies": { + "@ibm/telemetry-js": "^1.5.0" + } + }, + "node_modules/@carbon/motion": { + "version": "11.18.0", + "resolved": "https://registry.npmjs.org/@carbon/motion/-/motion-11.18.0.tgz", + "integrity": "sha512-hVTmRxhXCA+xznXZSTd6m0kmuIRrR8mxnDHvrVKFvN3ksTYDni5Mtx4XNylI4u/fmzyUcvrvVeTHqJ8LbPsDvA==", + "hasInstallScript": true, + "dependencies": { + "@ibm/telemetry-js": "^1.5.0" + } + }, + "node_modules/@carbon/react": { + "version": "1.59.0", + "resolved": "https://registry.npmjs.org/@carbon/react/-/react-1.59.0.tgz", + "integrity": "sha512-uD+I/IT5R4cnZa3k8AcTOMtctICll9a0O5XEI+Y7ezMDXhjPlCbX0Gt1QIomCg6TvEKEWTPEsuYOHSkJKbQK8w==", + "hasInstallScript": true, + "dependencies": { + "@babel/runtime": "^7.18.3", + "@carbon/feature-flags": "^0.20.0", + "@carbon/icons-react": "^11.43.0", + "@carbon/layout": "^11.22.0", + "@carbon/styles": "^1.59.0", + "@floating-ui/react": "^0.26.0", + "@ibm/telemetry-js": "^1.5.0", + "classnames": "2.5.1", + "copy-to-clipboard": "^3.3.1", + "downshift": "8.5.0", + "flatpickr": "4.6.13", + "invariant": "^2.2.3", + "lodash.debounce": "^4.0.8", + "lodash.findlast": "^4.5.0", + "lodash.isequal": "^4.5.0", + "lodash.omit": "^4.5.0", + "lodash.throttle": "^4.1.1", + "prop-types": "^15.7.2", + "react-is": "^18.2.0", + "tabbable": "^6.2.0", + "use-resize-observer": "^6.0.0", + "wicg-inert": "^3.1.1", + "window-or-global": "^1.0.1" + }, + "peerDependencies": { + "react": "^16.8.6 || ^17.0.1 || ^18.2.0", + "react-dom": "^16.8.6 || ^17.0.1 || ^18.2.0", + "sass": "^1.33.0" + } + }, + "node_modules/@carbon/styles": { + "version": "1.59.0", + "resolved": "https://registry.npmjs.org/@carbon/styles/-/styles-1.59.0.tgz", + "integrity": "sha512-AQ4LAsd343i8dMR01itebT4wnvc1VukPUOB5S3UWtT2GlvOVyTncMaVWaEmD9L/ZTTiZh7kD2YzGBlANBZ72yA==", + "hasInstallScript": true, + "dependencies": { + "@carbon/colors": "^11.22.0", + "@carbon/feature-flags": "^0.20.0", + "@carbon/grid": "^11.23.0", + "@carbon/layout": "^11.22.0", + "@carbon/motion": "^11.18.0", + "@carbon/themes": "^11.36.0", + "@carbon/type": "^11.27.0", + "@ibm/plex": "6.0.0-next.6", + "@ibm/telemetry-js": "^1.5.0" + }, + "peerDependencies": { + "sass": "^1.33.0" + }, + "peerDependenciesMeta": { + "sass": { + "optional": true + } + } + }, + "node_modules/@carbon/themes": { + "version": "11.36.0", + "resolved": "https://registry.npmjs.org/@carbon/themes/-/themes-11.36.0.tgz", + "integrity": "sha512-i6v7OdGCe+XisXI53lFLSSIiwFhb9DuVjqT7DU+nnbLnXFOeU6ZPzCGMFzB1HXXvTu7K9s++23Yj3acclTvGnQ==", + "hasInstallScript": true, + "dependencies": { + "@carbon/colors": "^11.22.0", + "@carbon/layout": "^11.22.0", + "@carbon/type": "^11.27.0", + "@ibm/telemetry-js": "^1.5.0", + "color": "^4.0.0" + } + }, + "node_modules/@carbon/type": { + "version": "11.27.0", + "resolved": "https://registry.npmjs.org/@carbon/type/-/type-11.27.0.tgz", + "integrity": "sha512-+YsFTKsch8xcdZ7y40K69B+47j86H7u8HEZ9OfymmXfMYAT+73MTfAtwyO3leS9rWGljKIh0h3I+Ga7wxE0Q6w==", + "hasInstallScript": true, + "dependencies": { + "@carbon/grid": "^11.23.0", + "@carbon/layout": "^11.22.0", + "@ibm/telemetry-js": "^1.5.0" + } + }, "node_modules/@chakra-ui/accordion": { "version": "1.4.12", "resolved": "https://registry.npmjs.org/@chakra-ui/accordion/-/accordion-1.4.12.tgz", @@ -4579,12 +4734,26 @@ "@floating-ui/utils": "^0.2.1" } }, + "node_modules/@floating-ui/react": { + "version": "0.26.16", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.16.tgz", + "integrity": "sha512-HEf43zxZNAI/E781QIVpYSF3K2VH4TTYZpqecjdsFkjsaU1EbaWcM++kw0HXFffj7gDUcBFevX8s0rQGQpxkow==", + "dependencies": { + "@floating-ui/react-dom": "^2.1.0", + "@floating-ui/utils": "^0.2.0", + "tabbable": "^6.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/@floating-ui/react-dom": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.8.tgz", - "integrity": "sha512-HOdqOt3R3OGeTKidaLvJKcgg75S6tibQ3Tif4eyd91QnIJWr0NLvoXFpJA/j8HqkFSL68GDca9AuyWEHlhyClw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.0.tgz", + "integrity": "sha512-lNzj5EQmEKn5FFKc04+zasr09h/uX8RtJRNj5gUXsSQIXHVWTVh+hVAg1vOMCexkX8EgvemMvIFpQfkosnVNyA==", "dependencies": { - "@floating-ui/dom": "^1.6.1" + "@floating-ui/dom": "^1.0.0" }, "peerDependencies": { "react": ">=16.8.0", @@ -6168,6 +6337,22 @@ "node": ">=6.9.0" } }, + "node_modules/@ibm/plex": { + "version": "6.0.0-next.6", + "resolved": "https://registry.npmjs.org/@ibm/plex/-/plex-6.0.0-next.6.tgz", + "integrity": "sha512-B3uGruTn2rS5gweynLmfSe7yCawSRsJguJJQHVQiqf4rh2RNgJFu8YLE2Zd/JHV0ZXoVMOslcXP2k3hMkxKEyA==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@ibm/telemetry-js": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@ibm/telemetry-js/-/telemetry-js-1.5.2.tgz", + "integrity": "sha512-KyvaHbiNMDtz2k/9DltkK3YkWTyvz8y7Pq1sQ4cnXDMzHiEatOyxw3zZgK9li80tgUOYMQLck9DLewEuhvtg7w==", + "bin": { + "ibmtelemetry": "dist/collect.js" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -9501,6 +9686,10 @@ "resolved": "packages/bootstrap-4", "link": true }, + "node_modules/@rjsf/carbon": { + "resolved": "packages/carbon", + "link": true + }, "node_modules/@rjsf/chakra-ui": { "resolved": "packages/chakra-ui", "link": true @@ -13640,6 +13829,18 @@ "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", "dev": true }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -13656,6 +13857,15 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", @@ -15451,6 +15661,26 @@ "node": ">=10" } }, + "node_modules/downshift": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/downshift/-/downshift-8.5.0.tgz", + "integrity": "sha512-BAr/KAZX8GGARwWl4aER6ABv8aAaRXZcVKP0m1oFPKpSIXCGuoqnhi6nRf87glHhYDd/CCPp9RVUK27JKJD/Fw==", + "dependencies": { + "@babel/runtime": "^7.22.15", + "compute-scroll-into-view": "^3.0.3", + "prop-types": "^15.8.1", + "react-is": "^18.2.0", + "tslib": "^2.6.2" + }, + "peerDependencies": { + "react": ">=16.12.0" + } + }, + "node_modules/downshift/node_modules/compute-scroll-into-view": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz", + "integrity": "sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==" + }, "node_modules/duplexer": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", @@ -16950,6 +17180,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/flatpickr": { + "version": "4.6.13", + "resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.13.tgz", + "integrity": "sha512-97PMG/aywoYpB4IvbvUJi0RQi8vearvU0oov1WW3k0WZPBMrTQVqekSX5CjSG/M4Q3i6A/0FKXC7RyAoAUUSPw==" + }, "node_modules/flatted": { "version": "3.2.9", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", @@ -22228,6 +22463,11 @@ "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" }, + "node_modules/lodash.findlast": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.findlast/-/lodash.findlast-4.6.0.tgz", + "integrity": "sha512-+OGwb1FVKjhc2aIEQ9vKqNDW1a0/HaCLr0iCIK10jfVif3dBE0nhQD0jOZNZLh7zOlmFUTrk+vt85eXoH4vKuA==" + }, "node_modules/lodash.flow": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/lodash.flow/-/lodash.flow-3.5.0.tgz", @@ -22239,6 +22479,11 @@ "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==" + }, "node_modules/lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", @@ -22261,6 +22506,16 @@ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz", "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==" }, + "node_modules/lodash.omit": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz", + "integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg==" + }, + "node_modules/lodash.throttle": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", + "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==" + }, "node_modules/lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", @@ -29969,6 +30224,19 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/sinon": { "version": "9.2.4", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", @@ -30926,6 +31194,11 @@ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true }, + "node_modules/tabbable": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", + "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==" + }, "node_modules/tabster": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/tabster/-/tabster-6.0.0.tgz", @@ -32474,6 +32747,18 @@ } } }, + "node_modules/use-resize-observer": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/use-resize-observer/-/use-resize-observer-6.1.0.tgz", + "integrity": "sha512-SiPcWHiIQ1CnHmb6PxbYtygqiZXR0U9dNkkbpX9VYnlstUwF8+QqpUTrzh13pjPwcjMVGR+QIC+nvF5ujfFNng==", + "dependencies": { + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/use-sidecar": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", @@ -33355,6 +33640,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wicg-inert": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/wicg-inert/-/wicg-inert-3.1.2.tgz", + "integrity": "sha512-Ba9tGNYxXwaqKEi9sJJvPMKuo063umUPsHN0JJsjrs2j8KDSzkWLMZGZ+MH1Jf1Fq4OWZ5HsESJID6nRza2ang==" + }, "node_modules/wide-align": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", @@ -33412,6 +33702,11 @@ "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==" }, + "node_modules/window-or-global": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/window-or-global/-/window-or-global-1.0.1.tgz", + "integrity": "sha512-tE12J/NenOv4xdVobD+AD3fT06T4KNqnzRhkv5nBIu7K+pvOH2oLCEgYP+i+5mF2jtI6FEADheOdZkA8YWET9w==" + }, "node_modules/wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", @@ -34570,6 +34865,51 @@ "react-bootstrap": "^1.6.5" } }, + "packages/carbon": { + "name": "@rjsf/carbon", + "version": "5.18.4", + "license": "Apache-2.0", + "devDependencies": { + "@babel/core": "^7.23.9", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.21.0", + "@babel/preset-env": "^7.23.9", + "@babel/preset-react": "^7.23.3", + "@babel/preset-typescript": "^7.23.3", + "@carbon/icons-react": "11.43.0", + "@carbon/react": "1.59.0", + "@rjsf/core": "^5.18.4", + "@rjsf/snapshot-tests": "^5.18.4", + "@rjsf/utils": "^5.18.4", + "@rjsf/validator-ajv8": "^5.18.4", + "@types/jest": "^29.5.12", + "@types/react": "^18.2.58", + "@types/react-dom": "^18.2.19", + "@types/react-test-renderer": "^18.0.7", + "babel-jest": "^29.7.0", + "esbuild": "^0.18.20", + "eslint": "^8.56.0", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "jest-watch-typeahead": "^2.2.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-test-renderer": "^18.2.0", + "rimraf": "^5.0.5", + "rollup": "^3.29.4", + "typescript": "^4.9.5" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@carbon/icons-react": "11.43.0", + "@carbon/react": "1.59.0", + "@rjsf/core": "^5.18.x", + "@rjsf/utils": "^5.18.x", + "react": "^16.14.0 || >=17" + } + }, "packages/chakra-ui": { "name": "@rjsf/chakra-ui", "version": "5.18.4", @@ -34981,6 +35321,8 @@ "dependencies": { "@ant-design/icons": "^4.8.1", "@babel/runtime": "^7.23.9", + "@carbon/icons-react": "11.43.0", + "@carbon/react": "1.59.0", "@chakra-ui/icons": "^1.1.7", "@chakra-ui/react": "^1.8.9", "@fluentui/react": "^8.115.3", @@ -34989,6 +35331,7 @@ "@mui/material": "5.15.2", "@rjsf/antd": "^5.18.4", "@rjsf/bootstrap-4": "^5.18.4", + "@rjsf/carbon": "^5.18.4", "@rjsf/chakra-ui": "^5.18.4", "@rjsf/core": "^5.18.4", "@rjsf/fluent-ui": "^5.18.4", diff --git a/package.json b/package.json index ab2216c78b..7aa75698c4 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "workspaces": [ "packages/antd", "packages/bootstrap-4", + "packages/carbon", "packages/chakra-ui", "packages/core", "packages/docs", diff --git a/packages/carbon/.eslintrc b/packages/carbon/.eslintrc new file mode 100644 index 0000000000..731b36bae0 --- /dev/null +++ b/packages/carbon/.eslintrc @@ -0,0 +1,4 @@ +{ + "extends": ["../../.eslintrc"], + "plugins": ["@typescript-eslint", "jsx-a11y", "react", "import"] +} diff --git a/packages/carbon/README.md b/packages/carbon/README.md new file mode 100644 index 0000000000..0a5e344351 --- /dev/null +++ b/packages/carbon/README.md @@ -0,0 +1,164 @@ +[![Build Status][build-shield]][build-url] +[![npm][npm-shield]][npm-url] +[![npm downloads][npm-dl-shield]][npm-dl-url] +[![Contributors][contributors-shield]][contributors-url] +[![Apache 2.0 License][license-shield]][license-url] + + +
+

+ + Logo + + +

@rjsf/chakra-ui

+ +

+ Chakra UI theme, fields and widgets for react-jsonschema-form. +
+ Explore the docs » +
+
+ View Playground + · + Report Bug + · + Request Feature +

+

+ + + +## Table of Contents + +- [Table of Contents](#table-of-contents) +- [About The Project](#about-the-project) + - [Built With](#built-with) +- [Getting Started](#getting-started) + - [Prerequisites](#prerequisites) + - [Installation](#installation) +- [Usage](#usage) +- [Optional Chakra UI Theme properties](#optional-chakra-ui-theme-properties) + - [Custom Chakra uiSchema Chakra Property](#custom-chakra-uischema-chakra-property) +- [Roadmap](#roadmap) +- [Contributing](#contributing) +- [Contact](#contact) + + + +## About The Project + +[![@rjsf/chakra-ui Screen Shot][product-screenshot]](https://rjsf-team.github.io/@rjsf/chakra-ui) + +Exports `chakra-ui` theme, fields and widgets for `react-jsonschema-form`. + +### Built With + +- [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form/) +- [Chakra UI](https://chakra-ui.com/) +- [TypeScript](https://www.typescriptlang.org/) + + + +## Getting Started + +### Prerequisites + +- `@chakra-ui/react >= 1.7.0` +- `chakra-react-select >= 3.3.8` +- `react >= 17.0.0` +- `framer-motion >= 5.0.0` +- `@rjsf/core >= 2.0.0` + +Refer to the [rjsf installation guide](https://rjsf-team.github.io/react-jsonschema-form/docs/#installation) and [chakra-ui installation guide](https://chakra-ui.com/docs/getting-started#installation) and for more details. + +--- + +### Installation + +```bash +yarn add @chakra-ui/react@^1.7 @emotion/react@^11 @emotion/styled@^11 framer-motion@^5 +``` + +```bash +yarn add @rjsf/chakra-ui @rjsf/core +``` + + + +## Usage + +```js +import Form from '@rjsf/chakra-ui'; +``` + +or + +```js +import { withTheme } from '@rjsf/core'; +import { Theme as ChakraUITheme } from '@rjsf/chakra-ui'; + +// Make modifications to the theme with your own fields and widgets + +const Form = withTheme(ChakraUITheme); +``` + +## Optional Chakra UI Theme properties + +- To pass additional properties to widgets, see this [guide](https://rjsf-team.github.io/react-jsonschema-form/docs/usage/objects#additional-properties). + +You can use `ChakraProvider`, to customize the components at a theme level.\ +And, `uiSchema` allows for the use of a `"chakra"` `"ui:option"` to customize the styling of the form widgets. + +#### Custom Chakra uiSchema Chakra Property + +```json +{ + "ui:options": { + "chakra": { + "p": "1rem", + "color": "blue.200", + "sx": { + "margin": "0 auto" + } + } + } +} +``` + +It accepts the theme accessible [style props](https://chakra-ui.com/docs/features/style-props) provided by [Chakra](https://chakra-ui.com/docs/getting-started) and [Emotion](https://emotion.sh/docs/introduction). + + + +## Roadmap + +See the [open issues](https://github.com/rjsf-team/react-jsonschema-form/issues) for a list of proposed features (and known issues). + + + +## Contributing + +Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started. + + + +## Contact + +rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people) + +GitHub repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form) + + + + +[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg +[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions +[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg +[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors +[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square +[license-url]: https://choosealicense.com/licenses/apache-2.0/ +[npm-shield]: https://img.shields.io/npm/v/@rjsf/chakra-ui/latest.svg?style=flat-square +[npm-url]: https://www.npmjs.com/package/@rjsf/chakra-ui +[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/chakra-ui.svg?style=flat-square +[npm-dl-url]: https://www.npmjs.com/package/@rjsf/chakra-ui +[product-screenshot]: ./screenshot.png diff --git a/packages/carbon/babel.config.js b/packages/carbon/babel.config.js new file mode 100644 index 0000000000..5f772a56c4 --- /dev/null +++ b/packages/carbon/babel.config.js @@ -0,0 +1,3 @@ +const defaultConfig = require('../../babel.config'); + +module.exports = defaultConfig; diff --git a/packages/carbon/jest.config.js b/packages/carbon/jest.config.js new file mode 100644 index 0000000000..2701979b23 --- /dev/null +++ b/packages/carbon/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + testEnvironment: 'jsdom', + testEnvironmentOptions: { + browsers: ['chrome', 'firefox', 'safari'], + }, + transformIgnorePatterns: [`/node_modules/(?!nanoid)`], +}; diff --git a/packages/carbon/logo.png b/packages/carbon/logo.png new file mode 100644 index 0000000000..9e67972393 Binary files /dev/null and b/packages/carbon/logo.png differ diff --git a/packages/carbon/package.json b/packages/carbon/package.json new file mode 100644 index 0000000000..556fbd0cfd --- /dev/null +++ b/packages/carbon/package.json @@ -0,0 +1,78 @@ +{ + "name": "@rjsf/carbon", + "version": "5.18.4", + "description": "Carbon Design UI theme, fields, and widgets for react-jsonschema-form", + "main": "dist/index.js", + "module": "lib/index.js", + "typings": "lib/index.d.ts", + "files": [ + "dist", + "lib", + "src" + ], + "scripts": { + "build:ts": "tsc -b", + "build:cjs": "esbuild ./src/index.ts --bundle --outfile=dist/index.js --sourcemap --packages=external --format=cjs", + "build:esm": "esbuild ./src/index.ts --bundle --outfile=dist/carbon.esm.js --sourcemap --packages=external --format=esm", + "build:umd": "rollup dist/carbon.esm.js --format=umd --file=dist/carbon.umd.js --name=@rjsf/carbon", + "build": "npm run build:ts && npm run build:cjs && npm run build:esm && npm run build:umd", + "cs-check": "prettier -l \"{src,test}/**/*.ts?(x)\"", + "cs-format": "prettier \"{src,test}/**/*.ts?(x)\" --write", + "lint": "eslint src test", + "precommit": "lint-staged", + "test": "jest", + "test:update": "jest --u", + "test:watch": "jest --watch" + }, + "lint-staged": { + "{src,test}/**/*.ts?(x)": [ + "eslint --fix" + ] + }, + "engineStrict": false, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@carbon/icons-react": "11.43.0", + "@carbon/react": "1.59.0", + "@rjsf/core": "^5.18.x", + "@rjsf/utils": "^5.18.x", + "react": "^16.14.0 || >=17" + }, + "publishConfig": { + "access": "public" + }, + "author": "Jianghao Yu ", + "license": "Apache-2.0", + "devDependencies": { + "@babel/core": "^7.23.9", + "@babel/plugin-proposal-class-properties": "^7.18.6", + "@babel/plugin-proposal-optional-chaining": "^7.21.0", + "@babel/preset-env": "^7.23.9", + "@babel/preset-react": "^7.23.3", + "@babel/preset-typescript": "^7.23.3", + "@carbon/icons-react": "11.43.0", + "@carbon/react": "1.59.0", + "@rjsf/core": "^5.18.4", + "@rjsf/snapshot-tests": "^5.18.4", + "@rjsf/utils": "^5.18.4", + "@rjsf/validator-ajv8": "^5.18.4", + "@types/jest": "^29.5.12", + "@types/react": "^18.2.58", + "@types/react-dom": "^18.2.19", + "@types/react-test-renderer": "^18.0.7", + "babel-jest": "^29.7.0", + "esbuild": "^0.18.20", + "eslint": "^8.56.0", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "jest-watch-typeahead": "^2.2.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-test-renderer": "^18.2.0", + "rimraf": "^5.0.5", + "rollup": "^3.29.4", + "typescript": "^4.9.5" + } +} diff --git a/packages/carbon/screenshot.png b/packages/carbon/screenshot.png new file mode 100644 index 0000000000..de7f75089f Binary files /dev/null and b/packages/carbon/screenshot.png differ diff --git a/packages/carbon/src/AddButton/AddButton.tsx b/packages/carbon/src/AddButton/AddButton.tsx new file mode 100644 index 0000000000..6c2dadd777 --- /dev/null +++ b/packages/carbon/src/AddButton/AddButton.tsx @@ -0,0 +1,18 @@ +import { Add } from '@carbon/icons-react'; +import { Button } from '@carbon/react'; +import { FormContextType, IconButtonProps, RJSFSchema, StrictRJSFSchema, TranslatableString } from '@rjsf/utils'; + +/** Implement `ButtonTemplates.AddButton` + */ +export default function AddButton({ + uiSchema, + registry, + ...props +}: IconButtonProps) { + const { translateString } = registry; + return ( + + ); +} diff --git a/packages/carbon/src/AddButton/index.ts b/packages/carbon/src/AddButton/index.ts new file mode 100644 index 0000000000..752d720d32 --- /dev/null +++ b/packages/carbon/src/AddButton/index.ts @@ -0,0 +1,2 @@ +export { default } from './AddButton'; +export * from './AddButton'; diff --git a/packages/carbon/src/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx b/packages/carbon/src/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx new file mode 100644 index 0000000000..8ca3362e3d --- /dev/null +++ b/packages/carbon/src/ArrayFieldItemTemplate/ArrayFieldItemTemplate.tsx @@ -0,0 +1,80 @@ +import { useMemo } from 'react'; +import { ArrayFieldTemplateItemType, FormContextType, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils'; + +/** Implement `ArrayFieldItemTemplate` + */ +export default function ArrayFieldItemTemplate< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>(props: ArrayFieldTemplateItemType) { + const { + className, + children, + disabled, + hasToolbar, + hasCopy, + hasMoveDown, + hasMoveUp, + hasRemove, + index, + onCopyIndexClick, + onDropIndexClick, + onReorderClick, + readonly, + uiSchema, + registry, + } = props; + const { CopyButton, MoveDownButton, MoveUpButton, RemoveButton } = registry.templates.ButtonTemplates; + const onCopyClick = useMemo(() => onCopyIndexClick(index), [index, onCopyIndexClick]); + + const onRemoveClick = useMemo(() => onDropIndexClick(index), [index, onDropIndexClick]); + + const onArrowUpClick = useMemo(() => onReorderClick(index, index - 1), [index, onReorderClick]); + + const onArrowDownClick = useMemo(() => onReorderClick(index, index + 1), [index, onReorderClick]); + + return ( +
+
{children}
+ {hasToolbar && ( +
+ {(hasMoveUp || hasMoveDown) && ( + + )} + {(hasMoveUp || hasMoveDown) && ( + + )} + {hasCopy && ( + + )} + {hasRemove && ( + + )} + +
+ )} +
+ ); +} diff --git a/packages/carbon/src/ArrayFieldItemTemplate/index.ts b/packages/carbon/src/ArrayFieldItemTemplate/index.ts new file mode 100644 index 0000000000..f104431399 --- /dev/null +++ b/packages/carbon/src/ArrayFieldItemTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './ArrayFieldItemTemplate'; +export * from './ArrayFieldItemTemplate'; diff --git a/packages/carbon/src/ArrayFieldTemplate/ArrayFieldTemplate.tsx b/packages/carbon/src/ArrayFieldTemplate/ArrayFieldTemplate.tsx new file mode 100644 index 0000000000..741d30a637 --- /dev/null +++ b/packages/carbon/src/ArrayFieldTemplate/ArrayFieldTemplate.tsx @@ -0,0 +1,95 @@ +import { Stack } from '@carbon/react'; +import { + getTemplate, + getUiOptions, + ArrayFieldTemplateItemType, + ArrayFieldTemplateProps, + StrictRJSFSchema, + RJSFSchema, + FormContextType, +} from '@rjsf/utils'; +import { LayerBackground } from '../components/Layer'; +import getCarbonOptions from '../utils'; + +/** Implement `ArrayFieldTemplate` + */ +export default function ArrayFieldTemplate< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>(props: ArrayFieldTemplateProps) { + const { + className, + canAdd, + disabled, + idSchema, + uiSchema, + items, + onAddClick, + readonly, + registry, + required, + schema, + title, + } = props; + const uiOptions = getUiOptions(uiSchema); + const carbonOptions = getCarbonOptions(registry.formContext, uiOptions); + const ArrayFieldDescriptionTemplate = getTemplate<'ArrayFieldDescriptionTemplate', T, S, F>( + 'ArrayFieldDescriptionTemplate', + registry, + uiOptions + ); + const ArrayFieldItemTemplate = getTemplate<'ArrayFieldItemTemplate', T, S, F>( + 'ArrayFieldItemTemplate', + registry, + uiOptions + ); + const ArrayFieldTitleTemplate = getTemplate<'ArrayFieldTitleTemplate', T, S, F>( + 'ArrayFieldTitleTemplate', + registry, + uiOptions + ); + // Button templates are not overridden in the uiSchema + const { + ButtonTemplates: { AddButton }, + } = registry.templates; + return ( +
+ + + + + {items.length > 0 && ( + + {items.map(({ key, ...itemProps }: ArrayFieldTemplateItemType) => ( + + ))} + + )} + {canAdd && ( + + )} + + +
+ ); +} diff --git a/packages/carbon/src/ArrayFieldTemplate/index.ts b/packages/carbon/src/ArrayFieldTemplate/index.ts new file mode 100644 index 0000000000..ab908dec2c --- /dev/null +++ b/packages/carbon/src/ArrayFieldTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './ArrayFieldTemplate'; +export * from './ArrayFieldTemplate'; diff --git a/packages/carbon/src/BaseInputTemplate/BaseInputTemplate.tsx b/packages/carbon/src/BaseInputTemplate/BaseInputTemplate.tsx new file mode 100644 index 0000000000..94454873bf --- /dev/null +++ b/packages/carbon/src/BaseInputTemplate/BaseInputTemplate.tsx @@ -0,0 +1,96 @@ +import { ChangeEvent, FocusEvent } from 'react'; +import { + ariaDescribedByIds, + BaseInputTemplateProps, + examplesId, + FormContextType, + getInputProps, + getUiOptions, + RJSFSchema, + StrictRJSFSchema, +} from '@rjsf/utils'; +import { TextInput } from '@carbon/react'; +import { LabelValue } from '../components/LabelValue'; +import getCarbonOptions from '../utils'; + +/** Implement `BaseInputTemplate` + */ +export default function BaseInputTemplate< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>(props: BaseInputTemplateProps) { + const { + id, + type, + value, + label, + hideLabel, + schema, + onChange, + onChangeOverride, + onBlur, + onFocus, + options, + required, + readonly, + rawErrors, + autofocus, + placeholder, + disabled, + uiSchema, + } = props; + const inputProps = getInputProps(schema, type, options); + const uiOptions = getUiOptions(uiSchema); + const carbonOptions = getCarbonOptions(props.registry.formContext, uiOptions); + + const _onChange = ({ target: { value } }: ChangeEvent) => + onChange(value === '' ? options.emptyValue : value); + const _onBlur = ({ target: { value } }: FocusEvent) => onBlur(id, value); + const _onFocus = ({ target: { value } }: FocusEvent) => onFocus(id, value); + + return ( +
+ + } + onChange={onChangeOverride || _onChange} + onBlur={_onBlur} + onFocus={_onFocus} + autoFocus={autofocus} + placeholder={placeholder} + required={required} + disabled={disabled || readonly} + invalid={rawErrors && rawErrors.length > 0} + aria-describedby={ariaDescribedByIds(id, !!schema.examples)} + list={schema.examples ? examplesId(id) : undefined} + {...inputProps} + size={carbonOptions.size} + /> + {Array.isArray(schema.examples) ? ( + (id)}> + {(schema.examples as string[]) + .concat(schema.default && !schema.examples.includes(schema.default) ? ([schema.default] as string[]) : []) + .map((example: any) => { + return + ) : null} +
+ ); +} diff --git a/packages/carbon/src/BaseInputTemplate/index.ts b/packages/carbon/src/BaseInputTemplate/index.ts new file mode 100644 index 0000000000..f7ef8d5939 --- /dev/null +++ b/packages/carbon/src/BaseInputTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './BaseInputTemplate'; +export * from './BaseInputTemplate'; diff --git a/packages/carbon/src/CheckboxWidget/CheckboxWidget.tsx b/packages/carbon/src/CheckboxWidget/CheckboxWidget.tsx new file mode 100644 index 0000000000..07b44084f9 --- /dev/null +++ b/packages/carbon/src/CheckboxWidget/CheckboxWidget.tsx @@ -0,0 +1,88 @@ +import { ChangeEvent, FocusEvent } from 'react'; +import { + ariaDescribedByIds, + descriptionId, + getTemplate, + WidgetProps, + schemaRequiresTrueValue, + StrictRJSFSchema, + RJSFSchema, + FormContextType, +} from '@rjsf/utils'; +import { Checkbox } from '@carbon/react'; +import { LabelValue } from '../components/LabelValue'; + +/** Implement `CheckboxWidget` + */ +export default function CheckboxWidget< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>(props: WidgetProps) { + const { + id, + value, + disabled, + readonly, + rawErrors, + onChange, + onBlur, + onFocus, + label, + hideLabel, + registry, + options, + uiSchema, + schema, + } = props; + // Because an unchecked checkbox will cause html5 validation to fail, only add + // the "required" attribute if the field value must be "true", due to the + // "const" or "enum" keywords + const required = schemaRequiresTrueValue(schema); + const DescriptionFieldTemplate = getTemplate<'DescriptionFieldTemplate', T, S, F>( + 'DescriptionFieldTemplate', + registry, + options + ); + const description = options.description || schema.description; + + const _onChange = ({ target: { checked } }: ChangeEvent) => onChange(checked); + const _onBlur = ({ target: { value } }: FocusEvent) => onBlur(id, value); + const _onFocus = ({ target: { value } }: FocusEvent) => onFocus(id, value); + + return ( + <> + + } + checked={typeof value === 'undefined' ? false : value} + disabled={disabled || readonly} + invalid={rawErrors && rawErrors.length > 0} + onChange={_onChange} + onBlur={_onBlur} + onFocus={_onFocus} + aria-describedby={ariaDescribedByIds(id)} + readOnly={readonly} + required={required} + /> + {!hideLabel && !!description && ( + (id)} + description={description} + schema={schema} + uiSchema={uiSchema} + registry={registry} + /> + )} + + ); +} diff --git a/packages/carbon/src/CheckboxWidget/index.ts b/packages/carbon/src/CheckboxWidget/index.ts new file mode 100644 index 0000000000..b9e3c318ec --- /dev/null +++ b/packages/carbon/src/CheckboxWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from './CheckboxWidget'; +export * from './CheckboxWidget'; diff --git a/packages/carbon/src/CheckboxesWidget/CheckboxesWidget.tsx b/packages/carbon/src/CheckboxesWidget/CheckboxesWidget.tsx new file mode 100644 index 0000000000..d320ce7a91 --- /dev/null +++ b/packages/carbon/src/CheckboxesWidget/CheckboxesWidget.tsx @@ -0,0 +1,100 @@ +import { FocusEvent } from 'react'; +// @ts-expect-error No types available for CheckboxGroup +import { CheckboxGroup, Checkbox } from '@carbon/react'; +import { + ariaDescribedByIds, + enumOptionsIndexForValue, + enumOptionsIsSelected, + enumOptionsValueForIndex, + optionId, + FormContextType, + RJSFSchema, + StrictRJSFSchema, + WidgetProps, +} from '@rjsf/utils'; + +/** Implement `CheckboxesWidget` + */ +export default function CheckboxesWidget< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>(props: WidgetProps) { + const { + id, + disabled, + options, + value, + readonly, + onChange, + onBlur, + onFocus, + // uiSchema, + rawErrors = [], + } = props; + const { enumOptions, enumDisabled, emptyValue } = options; + const checkboxesValues = Array.isArray(value) ? value : [value]; + + const _onBlur = ({ target: { value } }: FocusEvent) => + onBlur(id, enumOptionsValueForIndex(value, enumOptions, emptyValue)); + const _onFocus = ({ target: { value } }: FocusEvent) => + onFocus(id, enumOptionsValueForIndex(value, enumOptions, emptyValue)); + + // const row = options ? options.inline : false; + const selectedIndexes = enumOptionsIndexForValue(value, enumOptions, true) as string[]; + + const onCheckboxChange = (changedIndex: number) => { + const option: string[] = [...selectedIndexes]; + if (option.indexOf(String(changedIndex)) !== -1) { + option.splice(option.indexOf(String(changedIndex)), 1); + } else { + option.push(String(changedIndex)); + } + onChange(enumOptionsValueForIndex(option, enumOptions, emptyValue)); + }; + + return ( + <> + + (id)} + invalid={rawErrors && rawErrors.length > 0} + > + {Array.isArray(enumOptions) && + enumOptions.map((option, index) => { + const checked = enumOptionsIsSelected(option.value, checkboxesValues); + const itemDisabled = Array.isArray(enumDisabled) && enumDisabled.indexOf(option.value) !== -1; + return ( + onCheckboxChange(index)} + id={optionId(id, index)} + name={id} + value={String(index)} + checked={checked} + disabled={disabled || itemDisabled || readonly} + onBlur={_onBlur} + onFocus={_onFocus} + readOnly={readonly} + defaultChecked={selectedIndexes.indexOf(String(index)) !== -1} + /> + ); + })} + + + ); +} diff --git a/packages/carbon/src/CheckboxesWidget/index.ts b/packages/carbon/src/CheckboxesWidget/index.ts new file mode 100644 index 0000000000..97152004fa --- /dev/null +++ b/packages/carbon/src/CheckboxesWidget/index.ts @@ -0,0 +1,2 @@ +export { default } from './CheckboxesWidget'; +export * from './CheckboxesWidget'; diff --git a/packages/carbon/src/DescriptionField/DescriptionField.tsx b/packages/carbon/src/DescriptionField/DescriptionField.tsx new file mode 100644 index 0000000000..8506205583 --- /dev/null +++ b/packages/carbon/src/DescriptionField/DescriptionField.tsx @@ -0,0 +1,19 @@ +import { DescriptionFieldProps, FormContextType, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils'; + +/** Implement `DescriptionField` + */ +export default function DescriptionField< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>({ description, id }: DescriptionFieldProps) { + if (!description) { + return null; + } + + return ( +
+ {description} +
+ ); +} diff --git a/packages/carbon/src/DescriptionField/index.ts b/packages/carbon/src/DescriptionField/index.ts new file mode 100644 index 0000000000..401540d99b --- /dev/null +++ b/packages/carbon/src/DescriptionField/index.ts @@ -0,0 +1,2 @@ +export { default } from './DescriptionField'; +export * from './DescriptionField'; diff --git a/packages/carbon/src/ErrorList/ErrorList.tsx b/packages/carbon/src/ErrorList/ErrorList.tsx new file mode 100644 index 0000000000..c3c97720c1 --- /dev/null +++ b/packages/carbon/src/ErrorList/ErrorList.tsx @@ -0,0 +1,44 @@ +import { ErrorListProps, FormContextType, RJSFSchema, StrictRJSFSchema, TranslatableString } from '@rjsf/utils'; +import { InlineNotification, UnorderedList, ListItem } from '@carbon/react'; + +/** Implement `ErrorListTemplate` + */ +export default function ErrorList({ + errors, + registry, +}: ErrorListProps) { + const { translateString } = registry; + return ( + <> + + {}} + > +
+
{translateString(TranslatableString.ErrorsLabel)}
+ + {errors.map((err, i) => ( + + {err.stack} + + ))} + +
+
+ + ); +} diff --git a/packages/carbon/src/ErrorList/index.ts b/packages/carbon/src/ErrorList/index.ts new file mode 100644 index 0000000000..79376ace11 --- /dev/null +++ b/packages/carbon/src/ErrorList/index.ts @@ -0,0 +1,2 @@ +export { default } from './ErrorList'; +export * from './ErrorList'; diff --git a/packages/carbon/src/FieldErrorTemplate/FieldErrorTemplate.tsx b/packages/carbon/src/FieldErrorTemplate/FieldErrorTemplate.tsx new file mode 100644 index 0000000000..038ee6d016 --- /dev/null +++ b/packages/carbon/src/FieldErrorTemplate/FieldErrorTemplate.tsx @@ -0,0 +1,41 @@ +import { errorId, FieldErrorProps, FormContextType, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils'; + +/** Implement `FieldErrorTemplate` + */ +export default function FieldErrorTemplate< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>(props: FieldErrorProps) { + const { errors = [], idSchema } = props; + if (errors.length === 0) { + return null; + } + const id = errorId(idSchema); + + return ( + <> + {/* TODO can we use css file? */} + +
+ {errors.map((error, i: number) => { + return ( +
+ {error} +
+ ); + })} +
+ + ); +} diff --git a/packages/carbon/src/FieldErrorTemplate/index.ts b/packages/carbon/src/FieldErrorTemplate/index.ts new file mode 100644 index 0000000000..2fbf1c353d --- /dev/null +++ b/packages/carbon/src/FieldErrorTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './FieldErrorTemplate'; +export * from './FieldErrorTemplate'; diff --git a/packages/carbon/src/FieldHelpTemplate/FieldHelpTemplate.tsx b/packages/carbon/src/FieldHelpTemplate/FieldHelpTemplate.tsx new file mode 100644 index 0000000000..8a6a8ddd2d --- /dev/null +++ b/packages/carbon/src/FieldHelpTemplate/FieldHelpTemplate.tsx @@ -0,0 +1,20 @@ +import { helpId, FieldHelpProps, FormContextType, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils'; + +/** Implement `FieldHelpTemplate` + */ +export default function FieldHelpTemplate< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>(props: FieldHelpProps) { + const { idSchema, help } = props; + if (!help) { + return null; + } + const id = helpId(idSchema); + return ( +
+ {help} +
+ ); +} diff --git a/packages/carbon/src/FieldHelpTemplate/index.ts b/packages/carbon/src/FieldHelpTemplate/index.ts new file mode 100644 index 0000000000..b439bce3f1 --- /dev/null +++ b/packages/carbon/src/FieldHelpTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './FieldHelpTemplate'; +export * from './FieldHelpTemplate'; diff --git a/packages/carbon/src/FieldTemplate/FieldTemplate.tsx b/packages/carbon/src/FieldTemplate/FieldTemplate.tsx new file mode 100644 index 0000000000..233063ee4a --- /dev/null +++ b/packages/carbon/src/FieldTemplate/FieldTemplate.tsx @@ -0,0 +1,88 @@ +import { FormGroup, Stack } from '@carbon/react'; +import { + FieldTemplateProps, + FormContextType, + getTemplate, + getUiOptions, + RJSFSchema, + StrictRJSFSchema, +} from '@rjsf/utils'; +import { LabelValue } from '../components/LabelValue'; +import getCarbonOptions from '../utils'; + +/** Implement `FieldTemplate` + */ +export default function FieldTemplate< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>(props: FieldTemplateProps) { + const { + id, + children, + classNames, + style, + disabled, + displayLabel, + hidden, + label, + onDropPropertyClick, + onKeyChange, + readonly, + registry, + required, + rawErrors = [], + errors, + help, + description, + rawDescription, + schema, + uiSchema, + } = props; + const uiOptions = getUiOptions(uiSchema); + const carbonOptions = getCarbonOptions(registry.formContext, uiOptions); + const WrapIfAdditionalTemplate = getTemplate<'WrapIfAdditionalTemplate', T, S, F>( + 'WrapIfAdditionalTemplate', + registry, + uiOptions + ); + + if (hidden) { + return
{children}
; + } + + return ( + + + + + } + invalid={rawErrors.length > 0} + > + {children} + + {/* Carbon Design System hide description if there are errors and warnings */} + {rawErrors.length ? ( + errors + ) : displayLabel && rawDescription ? ( +
{description}
+ ) : null} + {help} +
+ ); +} diff --git a/packages/carbon/src/FieldTemplate/index.ts b/packages/carbon/src/FieldTemplate/index.ts new file mode 100644 index 0000000000..6f7dc3861c --- /dev/null +++ b/packages/carbon/src/FieldTemplate/index.ts @@ -0,0 +1,2 @@ +export { default } from './FieldTemplate'; +export * from './FieldTemplate'; diff --git a/packages/carbon/src/Fields/Fields.tsx b/packages/carbon/src/Fields/Fields.tsx new file mode 100644 index 0000000000..da794bd673 --- /dev/null +++ b/packages/carbon/src/Fields/Fields.tsx @@ -0,0 +1,17 @@ +import { FormContextType, RegistryFieldsType, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils'; +import MultiSchemaField from '../MultiSchemaField'; + +/** Generates a set of Fields `carbon` theme uses. + */ +export function generateFields< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>(): RegistryFieldsType { + return { + OneOfField: MultiSchemaField, + AnyOfField: MultiSchemaField, + }; +} + +export default generateFields(); diff --git a/packages/carbon/src/Fields/index.ts b/packages/carbon/src/Fields/index.ts new file mode 100644 index 0000000000..c65ffe072d --- /dev/null +++ b/packages/carbon/src/Fields/index.ts @@ -0,0 +1,2 @@ +export { default } from './Fields'; +export * from './Fields'; diff --git a/packages/carbon/src/Form/Form.tsx b/packages/carbon/src/Form/Form.tsx new file mode 100644 index 0000000000..c301ea124f --- /dev/null +++ b/packages/carbon/src/Form/Form.tsx @@ -0,0 +1,17 @@ +import { ComponentType } from 'react'; +import { withTheme, FormProps } from '@rjsf/core'; +import { generateTheme } from '../Theme'; +import { FormContextType, RJSFSchema, StrictRJSFSchema } from '@rjsf/utils'; + +/** Generate a `Form` component that is customized with the `carbon` theme. + * + */ +export function generateForm< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>(): ComponentType> { + return withTheme(generateTheme()); +} + +export default generateForm(); diff --git a/packages/carbon/src/Form/index.ts b/packages/carbon/src/Form/index.ts new file mode 100644 index 0000000000..60f008b592 --- /dev/null +++ b/packages/carbon/src/Form/index.ts @@ -0,0 +1,2 @@ +export { default } from './Form'; +export * from './Form'; diff --git a/packages/carbon/src/IconButton/IconButton.tsx b/packages/carbon/src/IconButton/IconButton.tsx new file mode 100644 index 0000000000..e73b726d53 --- /dev/null +++ b/packages/carbon/src/IconButton/IconButton.tsx @@ -0,0 +1,90 @@ +import { FormContextType, IconButtonProps, RJSFSchema, StrictRJSFSchema, TranslatableString } from '@rjsf/utils'; + +import { Button } from '@carbon/react'; +import { Copy, ArrowDown, ArrowUp, TrashCan } from '@carbon/icons-react'; + +/** Implement `ButtonTemplates.CopyButton` + */ +export function CopyButton( + props: IconButtonProps +) { + const { + registry: { translateString }, + } = props; + return ( + + ); +} diff --git a/packages/carbon/src/SubmitButton/index.ts b/packages/carbon/src/SubmitButton/index.ts new file mode 100644 index 0000000000..f676497ba2 --- /dev/null +++ b/packages/carbon/src/SubmitButton/index.ts @@ -0,0 +1,2 @@ +export { default } from './SubmitButton'; +export * from './SubmitButton'; diff --git a/packages/carbon/src/Templates/Templates.ts b/packages/carbon/src/Templates/Templates.ts new file mode 100644 index 0000000000..367577eaa0 --- /dev/null +++ b/packages/carbon/src/Templates/Templates.ts @@ -0,0 +1,47 @@ +import { FormContextType, RJSFSchema, StrictRJSFSchema, TemplatesType } from '@rjsf/utils'; +import AddButton from '../AddButton'; +import SubmitButton from '../SubmitButton'; +import { MoveDownButton, MoveUpButton, RemoveButton, CopyButton } from '../IconButton'; +import FieldTemplate from '../FieldTemplate'; +import BaseInputTemplate from '../BaseInputTemplate'; +import ObjectFieldTemplate from '../ObjectFieldTemplate'; +import FieldHelpTemplate from '../FieldHelpTemplate'; +import DescriptionField from '../DescriptionField'; +import FieldErrorTemplate from '../FieldErrorTemplate'; +import TitleField from '../TitleField'; +import ArrayFieldTemplate from '../ArrayFieldTemplate'; +import ArrayFieldItemTemplate from '../ArrayFieldItemTemplate'; +import ErrorList from '../ErrorList'; +import WrapIfAdditionalTemplate from '../WrapIfAdditionalTemplate'; + +/** Generates a set of templates `carbon` theme uses. + */ +export function generateTemplates< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>(): Partial> { + return { + BaseInputTemplate, + ButtonTemplates: { + SubmitButton, + AddButton, + MoveDownButton, + MoveUpButton, + RemoveButton, + CopyButton, + }, + TitleFieldTemplate: TitleField, + DescriptionFieldTemplate: DescriptionField, + ErrorListTemplate: ErrorList, + FieldErrorTemplate, + FieldTemplate, + FieldHelpTemplate, + ObjectFieldTemplate, + ArrayFieldTemplate, + ArrayFieldItemTemplate, + WrapIfAdditionalTemplate, + }; +} + +export default generateTemplates(); diff --git a/packages/carbon/src/Templates/index.ts b/packages/carbon/src/Templates/index.ts new file mode 100644 index 0000000000..612ccf692a --- /dev/null +++ b/packages/carbon/src/Templates/index.ts @@ -0,0 +1,2 @@ +export { default } from './Templates'; +export * from './Templates'; diff --git a/packages/carbon/src/TextareaWidget/TextareaWidget.tsx b/packages/carbon/src/TextareaWidget/TextareaWidget.tsx new file mode 100644 index 0000000000..ac31aff692 --- /dev/null +++ b/packages/carbon/src/TextareaWidget/TextareaWidget.tsx @@ -0,0 +1,51 @@ +import { ChangeEvent, FocusEvent } from 'react'; +import { ariaDescribedByIds, FormContextType, RJSFSchema, StrictRJSFSchema, WidgetProps } from '@rjsf/utils'; +import { TextArea } from '@carbon/react'; +import { LabelValue } from '../components/LabelValue'; + +/** Implement `TextareaWidget` + */ +export default function TextareaWidget< + T = any, + S extends StrictRJSFSchema = RJSFSchema, + F extends FormContextType = any +>({ + id, + placeholder, + value, + label, + hideLabel, + disabled, + autofocus, + readonly, + onBlur, + onFocus, + onChange, + options, + required, + rawErrors, +}: WidgetProps) { + const _onChange = ({ target: { value } }: ChangeEvent) => + onChange(value === '' ? options.emptyValue : value); + const _onBlur = ({ target: { value } }: FocusEvent) => onBlur(id, value); + const _onFocus = ({ target: { value } }: FocusEvent) => onFocus(id, value); + + return ( +