From dce26e7720e4663a08ce9054c2dfd6c8a82cc929 Mon Sep 17 00:00:00 2001 From: Ali Amori Kadhim Date: Mon, 21 Oct 2024 11:45:02 +0200 Subject: [PATCH] feat: create form-field-react package --- .changeset/grumpy-kings-juggle.md | 5 + .../form-field-react/.eslintrc.json | 8 + .../form-field-react/babel.config.cjs | 12 ++ .../form-field-react/jest.config.mjs | 8 + .../form-field-react/package.json | 68 ++++++++ .../form-field-react/rollup.config.mjs | 87 ++++++++++ .../form-field-react/src/css.tsx | 9 ++ .../form-field-react/src/index.test.tsx | 78 +++++++++ .../form-field-react/src/index.tsx | 51 ++++++ .../form-field-react/tsconfig.build.json | 6 + .../form-field-react/tsconfig.json | 9 ++ .../form-field-react/tsconfig.test.json | 8 + pnpm-lock.yaml | 149 ++++++++++++++---- 13 files changed, 469 insertions(+), 29 deletions(-) create mode 100644 .changeset/grumpy-kings-juggle.md create mode 100644 packages/components-react/form-field-react/.eslintrc.json create mode 100644 packages/components-react/form-field-react/babel.config.cjs create mode 100644 packages/components-react/form-field-react/jest.config.mjs create mode 100644 packages/components-react/form-field-react/package.json create mode 100644 packages/components-react/form-field-react/rollup.config.mjs create mode 100644 packages/components-react/form-field-react/src/css.tsx create mode 100644 packages/components-react/form-field-react/src/index.test.tsx create mode 100644 packages/components-react/form-field-react/src/index.tsx create mode 100644 packages/components-react/form-field-react/tsconfig.build.json create mode 100644 packages/components-react/form-field-react/tsconfig.json create mode 100644 packages/components-react/form-field-react/tsconfig.test.json diff --git a/.changeset/grumpy-kings-juggle.md b/.changeset/grumpy-kings-juggle.md new file mode 100644 index 00000000000..1283028ec0c --- /dev/null +++ b/.changeset/grumpy-kings-juggle.md @@ -0,0 +1,5 @@ +--- +"@utrecht/form-field-react": major +--- + +Create form-field-react package diff --git a/packages/components-react/form-field-react/.eslintrc.json b/packages/components-react/form-field-react/.eslintrc.json new file mode 100644 index 00000000000..5ab00b0ee18 --- /dev/null +++ b/packages/components-react/form-field-react/.eslintrc.json @@ -0,0 +1,8 @@ +{ + "env": { + "jest/globals": true + }, + "rules": { + "react/react-in-jsx-scope": "off" + } +} diff --git a/packages/components-react/form-field-react/babel.config.cjs b/packages/components-react/form-field-react/babel.config.cjs new file mode 100644 index 00000000000..7c9f0f55a12 --- /dev/null +++ b/packages/components-react/form-field-react/babel.config.cjs @@ -0,0 +1,12 @@ +module.exports = { + presets: [ + '@babel/preset-env', + [ + '@babel/preset-react', + { + runtime: 'automatic', + }, + ], + '@babel/preset-typescript', + ], +}; diff --git a/packages/components-react/form-field-react/jest.config.mjs b/packages/components-react/form-field-react/jest.config.mjs new file mode 100644 index 00000000000..004e8e2a748 --- /dev/null +++ b/packages/components-react/form-field-react/jest.config.mjs @@ -0,0 +1,8 @@ +export default { + moduleDirectories: ['node_modules', '/'], + testEnvironment: 'jest-environment-jsdom', + testPathIgnorePatterns: ['/dist/'], + moduleNameMapper: { + '^@utrecht/(.*)$': '/../$1/src/', + }, +}; diff --git a/packages/components-react/form-field-react/package.json b/packages/components-react/form-field-react/package.json new file mode 100644 index 00000000000..547878b1479 --- /dev/null +++ b/packages/components-react/form-field-react/package.json @@ -0,0 +1,68 @@ +{ + "name": "@utrecht/form-field-react", + "version": "0.0.0", + "author": "Community for NL Design System", + "description": "Form Field component for the Municipality of Utrecht based on the NL Design System architecture", + "license": "EUPL-1.2", + "main": "./dist/index.cjs.js", + "module": "./dist/index.esm.js", + "types": "./dist/index.d.ts", + "files": [ + "dist/", + "src/" + ], + "sideEffects": false, + "scripts": { + "clean": "rimraf dist *.tsbuildinfo .rollup.cache coverage", + "build": "rollup --config ./rollup.config.mjs", + "test": "mkdir -p pages && jest --coverage --verbose", + "typecheck": "tsc --noEmit" + }, + "devDependencies": { + "@babel/plugin-transform-runtime": "7.24.7", + "@babel/preset-env": "7.24.7", + "@babel/preset-react": "7.24.7", + "@babel/preset-typescript": "7.24.7", + "@rollup/plugin-babel": "6.0.4", + "@rollup/plugin-commonjs": "26.0.1", + "@rollup/plugin-json": "6.1.0", + "@rollup/plugin-node-resolve": "15.2.3", + "@rollup/plugin-typescript": "12.1.0", + "@testing-library/dom": "8.20.1", + "@testing-library/jest-dom": "6.5.0", + "@testing-library/react": "16.0.1", + "@testing-library/user-event": "14.5.1", + "@types/jest": "29.5.13", + "@types/react": "18.3.3", + "@types/testing-library__jest-dom": "5.14.9", + "@utrecht/form-field-css": "workspace:*", + "jest": "29.7.0", + "jest-environment-jsdom": "29.7.0", + "react": "18.3.1", + "rollup": "4.23.0", + "rollup-plugin-filesize": "10.0.0", + "rollup-plugin-node-externals": "7.1.2", + "rollup-plugin-peer-deps-external": "2.2.4", + "rollup-plugin-postcss": "4.0.2", + "typescript": "5.6.2" + }, + "keywords": [ + "nl-design-system" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git+ssh", + "url": "git@github.com:nl-design-system/utrecht.git", + "directory": "packages/components-react/form-field-react" + }, + "peerDependencies": { + "@babel/runtime": "*", + "react": "18", + "react-dom": "18" + }, + "dependencies": { + "clsx": "2.1.1" + } +} diff --git a/packages/components-react/form-field-react/rollup.config.mjs b/packages/components-react/form-field-react/rollup.config.mjs new file mode 100644 index 00000000000..97d452b8ca0 --- /dev/null +++ b/packages/components-react/form-field-react/rollup.config.mjs @@ -0,0 +1,87 @@ +import babel from '@rollup/plugin-babel'; +import commonjs from '@rollup/plugin-commonjs'; +import json from '@rollup/plugin-json'; +import resolve from '@rollup/plugin-node-resolve'; +import typescript from '@rollup/plugin-typescript'; +import { readFileSync } from 'fs'; +import filesize from 'rollup-plugin-filesize'; +import nodeExternal from 'rollup-plugin-node-externals'; +import peerDepsExternal from 'rollup-plugin-peer-deps-external'; +import postcss from 'rollup-plugin-postcss'; + +const packagePath = new URL('./package.json', import.meta.url).pathname; +const packageJson = JSON.parse(readFileSync(packagePath, 'utf8')); + +/** + * @type {import('rollup').RollupOptions} + */ +export default [ + { + input: './src/index.tsx', + output: [ + { + file: packageJson.main, + format: 'cjs', + sourcemap: true, + }, + { + file: packageJson.module, + format: 'es', + sourcemap: true, + }, + ], + plugins: [ + peerDepsExternal(), + commonjs(), + nodeExternal(), + resolve({ browser: true }), + json(), + typescript({ tsconfig: './tsconfig.build.json' }), + babel({ + presets: ['@babel/preset-react'], + babelHelpers: 'runtime', + exclude: ['node_modules/**', 'dist/**'], + extensions: ['.ts', '.tsx'], + inputSourceMap: true, + plugins: ['@babel/plugin-transform-runtime'], + }), + filesize(), + ], + }, + { + input: './src/css.tsx', + output: [ + { + file: './dist/css.js', + format: 'cjs', + sourcemap: true, + }, + { + file: './dist/css.mjs', + format: 'es', + sourcemap: true, + }, + ], + plugins: [ + peerDepsExternal(), + commonjs(), + nodeExternal(), + resolve({ browser: true }), + json(), + postcss({ + extensions: ['.css', '.scss'], + minimize: true, + }), + typescript({ tsconfig: './tsconfig.build.json' }), + babel({ + presets: ['@babel/preset-react'], + babelHelpers: 'runtime', + exclude: ['node_modules/**', 'dist/**'], + extensions: ['.ts', '.tsx'], + inputSourceMap: true, + plugins: ['@babel/plugin-transform-runtime'], + }), + filesize(), + ], + }, +]; diff --git a/packages/components-react/form-field-react/src/css.tsx b/packages/components-react/form-field-react/src/css.tsx new file mode 100644 index 00000000000..d1a00240005 --- /dev/null +++ b/packages/components-react/form-field-react/src/css.tsx @@ -0,0 +1,9 @@ +/** + * @license EUPL-1.2 + * Copyright (c) 2020-2025 Frameless B.V. + * Copyright (c) 2021-2025 Gemeente Utrecht + */ + +import '@utrecht/form-field-css/src/index.scss'; + +export * from './index'; diff --git a/packages/components-react/form-field-react/src/index.test.tsx b/packages/components-react/form-field-react/src/index.test.tsx new file mode 100644 index 00000000000..0b13cf42935 --- /dev/null +++ b/packages/components-react/form-field-react/src/index.test.tsx @@ -0,0 +1,78 @@ +import { render, screen } from '@testing-library/react'; +import { createRef } from 'react'; +import { FormField } from './index'; +import '@testing-library/jest-dom'; + +describe('Form field', () => { + it('renders an HTML div element', () => { + const { container } = render(); + + const field = container.querySelector('div'); + + expect(field).toBeInTheDocument(); + }); + + it('renders a design system BEM class name', () => { + const { container } = render(); + + const field = container.querySelector('div'); + + expect(field).toHaveClass('utrecht-form-field'); + }); + + it('displays as CSS block element (or equivalent)', () => { + const { container } = render(); + + const field = container.querySelector('div'); + + expect(field).toBeVisible(); + expect(field).not.toHaveStyle({ display: 'inline' }); + expect(field).not.toHaveStyle({ display: 'inline-block' }); + }); + + it('renders rich text content', () => { + render( + + + , + ); + + const textbox = screen.getByRole('textbox'); + + expect(textbox).toBeInTheDocument(); + }); + + it('can be hidden', () => { + const { container } = render(