diff --git a/src/web/components/form/__tests__/__snapshots__/button.jsx.snap b/src/web/components/form/__tests__/__snapshots__/button.jsx.snap
deleted file mode 100644
index d242844dc2..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/button.jsx.snap
+++ /dev/null
@@ -1,77 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`Button tests > should render button 1`] = `
-.c0 {
- display: inline-block;
- padding: 0 15px;
- color: #4C4C4C;
- text-align: center;
- vertical-align: middle;
- font-size: 11px;
- font-weight: bold;
- line-height: 30px;
- -webkit-text-decoration: none;
- text-decoration: none;
- white-space: nowrap;
- background-color: #fff;
- border-radius: 2px;
- border: 1px solid #bfbfbf;
- cursor: pointer;
- overflow: visible;
- z-index: 1;
-}
-
-.c0:focus,
-.c0:hover {
- border: 1px solid #4C4C4C;
-}
-
-.c0:hover {
- -webkit-text-decoration: none;
- text-decoration: none;
- background: #11ab51;
- font-weight: bold;
- color: #fff;
-}
-
-.c0[disabled] {
- cursor: not-allowed;
- opacity: 0.65;
- box-shadow: none;
-}
-
-.c0 img {
- height: 32px;
- width: 32px;
- margin-top: 5px 10px 5px -10px;
- vertical-align: middle;
-}
-
-.c0:link {
- -webkit-text-decoration: none;
- text-decoration: none;
- color: #4C4C4C;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- justify-content: center;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/checkbox.jsx.snap b/src/web/components/form/__tests__/__snapshots__/checkbox.jsx.snap
deleted file mode 100644
index 0e5190278c..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/checkbox.jsx.snap
+++ /dev/null
@@ -1,111 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`CheckBox component tests > should render with children 1`] = `
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c3 {
- margin-left: -5px;
-}
-
-.c3>* {
- display: -webkit-inline-box;
- display: -webkit-inline-flex;
- display: -ms-inline-flexbox;
- display: inline-flex;
-}
-
-.c3>* {
- margin-left: 5px;
-}
-
-.c2 {
- display: -webkit-inline-box;
- display: -webkit-inline-flex;
- display: -ms-inline-flexbox;
- display: inline-flex;
-}
-
-.c0 {
- display: -webkit-inline-box;
- display: -webkit-inline-flex;
- display: -ms-inline-flexbox;
- display: inline-flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- font-weight: normal;
- cursor: pointer;
-}
-
-.c4 {
- font-family: inherit;
- font-size: inherit;
- padding: 0;
- margin: 0;
- margin-left: 10px;
- line-height: normal;
- width: auto;
- height: auto;
-}
-
-.c5 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/download.jsx.snap b/src/web/components/form/__tests__/__snapshots__/download.jsx.snap
deleted file mode 100644
index 7824f5b075..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/download.jsx.snap
+++ /dev/null
@@ -1,20 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`Download tests > should render 1`] = `
-
- Download
-
-`;
-
-exports[`Download tests > should render with filename 1`] = `
-
- Download
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/field.jsx.snap b/src/web/components/form/__tests__/__snapshots__/field.jsx.snap
deleted file mode 100644
index 73bdb851ba..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/field.jsx.snap
+++ /dev/null
@@ -1,89 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`Field tests > should render 1`] = `
-.c0 {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
- display: block;
- height: 22px;
- color: #4C4C4C;
- background-color: #fff;
- background-image: none;
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- padding: 1px 8px;
-}
-
-.c0:-webkit-autofill {
- box-shadow: 0 0 0 1000px white inset;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
-
-exports[`Field tests > should render in disabled state 1`] = `
-.c0 {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
- display: block;
- height: 22px;
- color: #4C4C4C;
- background-color: #fff;
- background-image: none;
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- padding: 1px 8px;
- cursor: not-allowed;
- background-color: #f3f3f3;
- opacity: 0.65;
-}
-
-.c0:-webkit-autofill {
- box-shadow: 0 0 0 1000px white inset;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/filefield.jsx.snap b/src/web/components/form/__tests__/__snapshots__/filefield.jsx.snap
deleted file mode 100644
index 44493bf5ce..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/filefield.jsx.snap
+++ /dev/null
@@ -1,52 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`FileField tests > should render 1`] = `
-.c0 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
-
-exports[`FileField tests > should render in disabled state 1`] = `
-.c0 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/formgroup.jsx.snap b/src/web/components/form/__tests__/__snapshots__/formgroup.jsx.snap
deleted file mode 100644
index f6f8c5a898..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/formgroup.jsx.snap
+++ /dev/null
@@ -1,114 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`FormGroup tests > should render 1`] = `
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c0 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- padding-bottom: 10px;
-}
-
-
-`;
-
-exports[`FormGroup tests > should render with title 1`] = `
-.c2 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c0 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- padding-bottom: 10px;
-}
-
-.c1 {
- display: inline-block;
- max-width: 100%;
- font-weight: bold;
- text-align: right;
- padding-left: 10px;
- padding-right: 10px;
- width: 16.66666667%;
- margin-left: 0;
-}
-
-.c3 {
- width: 83.33333333%;
- padding-left: 10px;
- padding-right: 10px;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/loadingbutton.jsx.snap b/src/web/components/form/__tests__/__snapshots__/loadingbutton.jsx.snap
deleted file mode 100644
index 75b18b097e..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/loadingbutton.jsx.snap
+++ /dev/null
@@ -1,173 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`LoadingButton tests > should render loading 1`] = `
-.c0 {
- display: inline-block;
- padding: 0 15px;
- color: #4C4C4C;
- text-align: center;
- vertical-align: middle;
- font-size: 11px;
- font-weight: bold;
- line-height: 30px;
- -webkit-text-decoration: none;
- text-decoration: none;
- white-space: nowrap;
- background-color: #fff;
- border-radius: 2px;
- border: 1px solid #bfbfbf;
- cursor: pointer;
- overflow: visible;
- z-index: 1;
-}
-
-.c0:focus,
-.c0:hover {
- border: 1px solid #4C4C4C;
-}
-
-.c0:hover {
- -webkit-text-decoration: none;
- text-decoration: none;
- background: #11ab51;
- font-weight: bold;
- color: #fff;
-}
-
-.c0[disabled] {
- cursor: not-allowed;
- opacity: 0.65;
- box-shadow: none;
-}
-
-.c0 img {
- height: 32px;
- width: 32px;
- margin-top: 5px 10px 5px -10px;
- vertical-align: middle;
-}
-
-.c0:link {
- -webkit-text-decoration: none;
- text-decoration: none;
- color: #4C4C4C;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- justify-content: center;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c2 {
- color: rgba(0, 0, 0, 0.0);
- background: #A1DDBA url(/img/loading.gif) center center no-repeat;
-}
-
-.c2 :hover {
- color: rgba(0, 0, 0, 0.0);
- background: #11ab51 url(/img/loading.gif) center center no-repeat;
-}
-
-
-`;
-
-exports[`LoadingButton tests > should render non loading 1`] = `
-.c0 {
- display: inline-block;
- padding: 0 15px;
- color: #4C4C4C;
- text-align: center;
- vertical-align: middle;
- font-size: 11px;
- font-weight: bold;
- line-height: 30px;
- -webkit-text-decoration: none;
- text-decoration: none;
- white-space: nowrap;
- background-color: #fff;
- border-radius: 2px;
- border: 1px solid #bfbfbf;
- cursor: pointer;
- overflow: visible;
- z-index: 1;
-}
-
-.c0:focus,
-.c0:hover {
- border: 1px solid #4C4C4C;
-}
-
-.c0:hover {
- -webkit-text-decoration: none;
- text-decoration: none;
- background: #11ab51;
- font-weight: bold;
- color: #fff;
-}
-
-.c0[disabled] {
- cursor: not-allowed;
- opacity: 0.65;
- box-shadow: none;
-}
-
-.c0 img {
- height: 32px;
- width: 32px;
- margin-top: 5px 10px 5px -10px;
- vertical-align: middle;
-}
-
-.c0:link {
- -webkit-text-decoration: none;
- text-decoration: none;
- color: #4C4C4C;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- justify-content: center;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c2 {
- color: #4C4C4C;
- background: #fff;
-}
-
-.c2 :hover {
- color: #fff;
- background: #11ab51;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/multiselect.jsx.snap b/src/web/components/form/__tests__/__snapshots__/multiselect.jsx.snap
deleted file mode 100644
index 29dfb95510..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/multiselect.jsx.snap
+++ /dev/null
@@ -1,357 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`MultiSelect component tests > should render 1`] = `
-.c3 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- -webkit-box-flex-wrap: wrap;
- -webkit-flex-wrap: wrap;
- -ms-flex-wrap: wrap;
- flex-wrap: wrap;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c4 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- justify-content: center;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c5 {
- background-color: transparent;
- border: none;
- cursor: pointer;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- justify-content: center;
- outline: none;
- margin: 1px;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- cursor: not-allowed;
-}
-
-.c6 {
- height: 16px;
- width: 16px;
- line-height: 16px;
-}
-
-.c6 * {
- height: inherit;
- width: inherit;
-}
-
-.c2 {
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: stretch;
- -webkit-box-align: stretch;
- -ms-flex-align: stretch;
- align-items: stretch;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- padding: 1px 5px;
- background-color: #fff;
- color: #000;
- font-weight: normal;
- background-color: #f3f3f3;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: column;
- -ms-flex-direction: column;
- flex-direction: column;
- position: relative;
- width: 250px;
-}
-
-.c7 {
- color: #c12c30;
- font-weight: bold;
- font-size: 19px;
- padding-bottom: 1px;
- padding-left: 4px;
- display: none;
-}
-
-.c0 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
-}
-
-
-`;
-
-exports[`MultiSelect component tests should render 1`] = `
-.c3 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- -webkit-box-flex-wrap: wrap;
- -webkit-flex-wrap: wrap;
- -ms-flex-wrap: wrap;
- flex-wrap: wrap;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c4 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- justify-content: center;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c5 {
- background-color: transparent;
- border: none;
- cursor: pointer;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- justify-content: center;
- outline: none;
- margin: 1px;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- cursor: not-allowed;
-}
-
-.c6 {
- height: 16px;
- width: 16px;
- line-height: 16px;
-}
-
-.c6 * {
- height: inherit;
- width: inherit;
-}
-
-.c2 {
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: stretch;
- -webkit-box-align: stretch;
- -ms-flex-align: stretch;
- align-items: stretch;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- padding: 1px 5px;
- background-color: #fff;
- color: #000;
- font-weight: normal;
- background-color: #f3f3f3;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: column;
- -ms-flex-direction: column;
- flex-direction: column;
- position: relative;
- width: 250px;
-}
-
-.c7 {
- color: #c12c30;
- font-weight: bold;
- font-size: 19px;
- padding-bottom: 1px;
- padding-left: 4px;
- display: none;
-}
-
-.c0 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/numberfield.jsx.snap b/src/web/components/form/__tests__/__snapshots__/numberfield.jsx.snap
deleted file mode 100644
index af687543d3..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/numberfield.jsx.snap
+++ /dev/null
@@ -1,7 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`NumberField tests > should render 1`] = `
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/passwordfield.jsx.snap b/src/web/components/form/__tests__/__snapshots__/passwordfield.jsx.snap
deleted file mode 100644
index 0d0f66b630..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/passwordfield.jsx.snap
+++ /dev/null
@@ -1,91 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`PasswordField tests > should render 1`] = `
-.c0 {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
- display: block;
- height: 22px;
- color: #4C4C4C;
- background-color: #fff;
- background-image: none;
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- padding: 1px 8px;
-}
-
-.c0:-webkit-autofill {
- box-shadow: 0 0 0 1000px white inset;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
-
-exports[`PasswordField tests > should render in disabled state 1`] = `
-.c0 {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
- display: block;
- height: 22px;
- color: #4C4C4C;
- background-color: #fff;
- background-image: none;
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- padding: 1px 8px;
- cursor: not-allowed;
- background-color: #f3f3f3;
- opacity: 0.65;
-}
-
-.c0:-webkit-autofill {
- box-shadow: 0 0 0 1000px white inset;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/radio.jsx.snap b/src/web/components/form/__tests__/__snapshots__/radio.jsx.snap
deleted file mode 100644
index 02c8c63cda..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/radio.jsx.snap
+++ /dev/null
@@ -1,217 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`Radio tests > should render radio 1`] = `
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c3 {
- margin-left: -5px;
-}
-
-.c3>* {
- display: -webkit-inline-box;
- display: -webkit-inline-flex;
- display: -ms-inline-flexbox;
- display: inline-flex;
-}
-
-.c3>* {
- margin-left: 5px;
-}
-
-.c2 {
- display: -webkit-inline-box;
- display: -webkit-inline-flex;
- display: -ms-inline-flexbox;
- display: inline-flex;
-}
-
-.c0 {
- display: -webkit-inline-box;
- display: -webkit-inline-flex;
- display: -ms-inline-flexbox;
- display: inline-flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- font-weight: normal;
- cursor: pointer;
-}
-
-.c4 {
- font-family: inherit;
- font-size: inherit;
- padding: 0;
- margin: 0;
- margin-left: 10px;
- line-height: normal;
- width: auto;
- height: auto;
-}
-
-.c5 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: flex-start;
- justify-content: flex-start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
-
-exports[`Radio tests > should render radio with children 1`] = `
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c3 {
- margin-left: -5px;
-}
-
-.c3>* {
- display: -webkit-inline-box;
- display: -webkit-inline-flex;
- display: -ms-inline-flexbox;
- display: inline-flex;
-}
-
-.c3>* {
- margin-left: 5px;
-}
-
-.c2 {
- display: -webkit-inline-box;
- display: -webkit-inline-flex;
- display: -ms-inline-flexbox;
- display: inline-flex;
-}
-
-.c0 {
- display: -webkit-inline-box;
- display: -webkit-inline-flex;
- display: -ms-inline-flexbox;
- display: inline-flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- font-weight: normal;
- cursor: pointer;
-}
-
-.c4 {
- font-family: inherit;
- font-size: inherit;
- padding: 0;
- margin: 0;
- margin-left: 10px;
- line-height: normal;
- width: auto;
- height: auto;
-}
-
-.c5 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: flex-start;
- justify-content: flex-start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/select.jsx.snap b/src/web/components/form/__tests__/__snapshots__/select.jsx.snap
deleted file mode 100644
index d32ac6335b..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/select.jsx.snap
+++ /dev/null
@@ -1,355 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`Select component tests > should render 1`] = `
-.c5 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- justify-content: center;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c6 {
- background-color: transparent;
- border: none;
- cursor: pointer;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- justify-content: center;
- outline: none;
- margin: 1px;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- cursor: pointer;
-}
-
-.c7 {
- height: 16px;
- width: 16px;
- line-height: 16px;
-}
-
-.c7 * {
- height: inherit;
- width: inherit;
-}
-
-.c2 {
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: stretch;
- -webkit-box-align: stretch;
- -ms-flex-align: stretch;
- align-items: stretch;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- padding: 1px 5px;
- background-color: #fff;
- color: #000;
- font-weight: normal;
- background-color: #f3f3f3;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: column;
- -ms-flex-direction: column;
- flex-direction: column;
- position: relative;
- width: 180px;
-}
-
-.c3 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- word-break: keep-all;
- white-space: nowrap;
- overflow: hidden;
- cursor: default;
-}
-
-.c8 {
- color: #c12c30;
- font-weight: bold;
- font-size: 19px;
- padding-bottom: 1px;
- padding-left: 4px;
- display: none;
-}
-
-.c4 {
- cursor: default;
-}
-
-.c0 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
-}
-
-
-`;
-
-exports[`Select component tests should render 1`] = `
-.c5 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- justify-content: center;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c6 {
- background-color: transparent;
- border: none;
- cursor: pointer;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- justify-content: center;
- outline: none;
- margin: 1px;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- cursor: pointer;
-}
-
-.c7 {
- height: 16px;
- width: 16px;
- line-height: 16px;
-}
-
-.c7 * {
- height: inherit;
- width: inherit;
-}
-
-.c2 {
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: stretch;
- -webkit-box-align: stretch;
- -ms-flex-align: stretch;
- align-items: stretch;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- padding: 1px 5px;
- background-color: #fff;
- color: #000;
- font-weight: normal;
- background-color: #f3f3f3;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: column;
- -ms-flex-direction: column;
- flex-direction: column;
- position: relative;
- width: 180px;
-}
-
-.c3 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- word-break: keep-all;
- white-space: nowrap;
- overflow: hidden;
- cursor: default;
-}
-
-.c8 {
- color: #c12c30;
- font-weight: bold;
- font-size: 19px;
- padding-bottom: 1px;
- padding-left: 4px;
- display: none;
-}
-
-.c4 {
- cursor: default;
-}
-
-.c0 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/selectelement.jsx.snap b/src/web/components/form/__tests__/__snapshots__/selectelement.jsx.snap
deleted file mode 100644
index 17ce2d3d52..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/selectelement.jsx.snap
+++ /dev/null
@@ -1,462 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`Box tests > should render 1`] = `
-.c0 {
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: stretch;
- -webkit-box-align: stretch;
- -ms-flex-align: stretch;
- align-items: stretch;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- padding: 1px 5px;
- background-color: #fff;
- color: #000;
- font-weight: normal;
-}
-
-
-`;
-
-exports[`Box tests > should render disabled 1`] = `
-.c0 {
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: stretch;
- -webkit-box-align: stretch;
- -ms-flex-align: stretch;
- align-items: stretch;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- padding: 1px 5px;
- background-color: #fff;
- color: #000;
- font-weight: normal;
- background-color: #f3f3f3;
-}
-
-
-`;
-
-exports[`Box tests > should render opened 1`] = `
-.c0 {
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: stretch;
- -webkit-box-align: stretch;
- -ms-flex-align: stretch;
- align-items: stretch;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- padding: 1px 5px;
- background-color: #fff;
- color: #000;
- font-weight: normal;
- border-radius: 2px 2px 0 0;
-}
-
-
-`;
-
-exports[`Input tests > should render 1`] = `
-.c0 {
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- padding: 1px;
- margin: 5px;
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
-}
-
-
-`;
-
-exports[`Item tests > should render 1`] = `
-.c0 {
- padding: 1px 5px;
- cursor: pointer;
-}
-
-.c0:hover {
- background-color: #77acf7;
- color: #fff;
-}
-
-
-`;
-
-exports[`Item tests > should render active 1`] = `
-.c0 {
- padding: 1px 5px;
- cursor: pointer;
- background-color: #77acf7;
- color: #fff;
-}
-
-.c0:hover {
- background-color: #77acf7;
- color: #fff;
-}
-
-
-`;
-
-exports[`Item tests > should render selected 1`] = `
-.c0 {
- padding: 1px 5px;
- cursor: pointer;
- background-color: #e5e5e5;
-}
-
-.c0:hover {
- background-color: #77acf7;
- color: #fff;
-}
-
-
-`;
-
-exports[`ItemContainer tests > should render 1`] = `
-.c0 {
- max-height: 320px;
- overflow-y: auto;
- overflow-x: hidden;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: column;
- -ms-flex-direction: column;
- flex-direction: column;
-}
-
-
-`;
-
-exports[`Menu tests > should render 1`] = `
-.c0 {
- outline: 0;
- border-radius: 0 0 4px 4px;
- -webkit-transition: opacity 0.1s ease;
- transition: opacity 0.1s ease;
- box-shadow: 0 2px 3px 0 rgba(34, 36, 38, 0.15);
- border: 1px solid #bfbfbf;
- background-color: #fff;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: column;
- -ms-flex-direction: column;
- flex-direction: column;
- position: absolute;
- z-index: 600;
- margin-top: -1px;
- box-sizing: border-box;
- top: 0px;
- left: 0px;
- white-space: nowrap;
-}
-
-
-`;
-
-exports[`Menu tests > should render with open direction downwards 1`] = `
-.c0 {
- outline: 0;
- border-radius: 0 0 4px 4px;
- -webkit-transition: opacity 0.1s ease;
- transition: opacity 0.1s ease;
- box-shadow: 0 2px 3px 0 rgba(34, 36, 38, 0.15);
- border: 1px solid #bfbfbf;
- background-color: #fff;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: column;
- -ms-flex-direction: column;
- flex-direction: column;
- position: absolute;
- z-index: 600;
- margin-top: -1px;
- box-sizing: border-box;
- top: 120px;
- left: 50px;
- white-space: nowrap;
-}
-
-
-`;
-
-exports[`Menu tests > should render with open direction upwards 1`] = `
-.c0 {
- outline: 0;
- border-radius: 0 0 4px 4px;
- -webkit-transition: opacity 0.1s ease;
- transition: opacity 0.1s ease;
- box-shadow: 0 2px 3px 0 rgba(34, 36, 38, 0.15);
- border: 1px solid #bfbfbf;
- background-color: #fff;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: column;
- -ms-flex-direction: column;
- flex-direction: column;
- position: absolute;
- z-index: 600;
- margin-top: -1px;
- box-sizing: border-box;
- top: 25px;
- left: 50px;
- white-space: nowrap;
-}
-
-
-`;
-
-exports[`Menu tests > should render with position adjust 1`] = `
-.c0 {
- outline: 0;
- border-radius: 0 0 4px 4px;
- -webkit-transition: opacity 0.1s ease;
- transition: opacity 0.1s ease;
- box-shadow: 0 2px 3px 0 rgba(34, 36, 38, 0.15);
- border: 1px solid #bfbfbf;
- background-color: #fff;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: column;
- -ms-flex-direction: column;
- flex-direction: column;
- position: absolute;
- z-index: 600;
- margin-top: -1px;
- box-sizing: border-box;
- top: 0px;
- left: 0px;
- width: 0px;
-}
-
-
-`;
-
-exports[`Menu tests > should render with position reference to parent element 1`] = `
-.c0 {
- outline: 0;
- border-radius: 0 0 4px 4px;
- -webkit-transition: opacity 0.1s ease;
- transition: opacity 0.1s ease;
- box-shadow: 0 2px 3px 0 rgba(34, 36, 38, 0.15);
- border: 1px solid #bfbfbf;
- background-color: #fff;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: column;
- -ms-flex-direction: column;
- flex-direction: column;
- position: absolute;
- z-index: 600;
- margin-top: -1px;
- box-sizing: border-box;
- top: 120px;
- left: 50px;
- white-space: nowrap;
-}
-
-
-`;
-
-exports[`Menu tests > should render with position right 1`] = `
-.c0 {
- outline: 0;
- border-radius: 0 0 4px 4px;
- -webkit-transition: opacity 0.1s ease;
- transition: opacity 0.1s ease;
- box-shadow: 0 2px 3px 0 rgba(34, 36, 38, 0.15);
- border: 1px solid #bfbfbf;
- background-color: #fff;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: column;
- -ms-flex-direction: column;
- flex-direction: column;
- position: absolute;
- z-index: 600;
- margin-top: -1px;
- box-sizing: border-box;
- top: 0px;
- right: 0px;
- white-space: nowrap;
-}
-
-
-`;
-
-exports[`SelectContainer tests > should render 1`] = `
-.c0 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: column;
- -ms-flex-direction: column;
- flex-direction: column;
- position: relative;
- width: 100px;
-}
-
-
-`;
-
-exports[`SelectValue tests > should render 1`] = `
-.c0 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- word-break: keep-all;
- white-space: nowrap;
- overflow: hidden;
- cursor: pointer;
-}
-
-
-`;
-
-exports[`SelectValue tests > should render disabled 1`] = `
-.c0 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- word-break: keep-all;
- white-space: nowrap;
- overflow: hidden;
- cursor: default;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/spinner.jsx.snap b/src/web/components/form/__tests__/__snapshots__/spinner.jsx.snap
deleted file mode 100644
index 91821e898c..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/spinner.jsx.snap
+++ /dev/null
@@ -1,101 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`Spinner tests > should render 1`] = `
-.c0 {
- border-radius: 2px;
- border: 1px solid #bfbfbf;
- background-color: #fff;
- font-size: 1.1em;
- position: relative;
- display: inline-block;
- overflow: hidden;
- padding: 0;
- vertical-align: middle;
-}
-
-.c1 {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
- border: none;
- background: none;
- color: inherit;
- padding: 0;
- margin: 0.2em 0;
- vertical-align: middle;
- margin-left: 0.4em;
- margin-right: 22px;
-}
-
-.c2 {
- background-color: #e5e5e5;
- color: #7F7F7F;
- border-left: 1px solid #4C4C4C;
- width: 16px;
- height: 50%;
- font-size: 0.6em;
- padding: 0;
- margin: 0;
- text-align: center;
- vertical-align: middle;
- position: absolute;
- right: 0;
- cursor: default;
- display: block;
- overflow: hidden;
- -webkit-text-decoration: none;
- text-decoration: none;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
-}
-
-.c2:hover {
- background-color: #11ab51;
- color: #fff;
- -webkit-text-decoration: none;
- text-decoration: none;
-}
-
-.c2:active {
- background-color: #fff;
- color: #074320;
- -webkit-text-decoration: none;
- text-decoration: none;
-}
-
-.c3 {
- border-top-right-radius: 1px;
- top: 0;
-}
-
-.c4 {
- border-bottom-right-radius: 1px;
- bottom: 0;
-}
-
-
-
-
- ▲
-
-
- ▼
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/textarea.jsx.snap b/src/web/components/form/__tests__/__snapshots__/textarea.jsx.snap
deleted file mode 100644
index 8325093d60..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/textarea.jsx.snap
+++ /dev/null
@@ -1,75 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`TextArea tests > should render 1`] = `
-.c0 {
- display: block;
- height: auto;
- color: #4C4C4C;
- background-color: #fff;
- background-image: none;
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- padding: 4px 8px;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
-
-exports[`TextArea tests > should render in disabled state 1`] = `
-.c0 {
- display: block;
- height: auto;
- color: #4C4C4C;
- background-color: #fff;
- background-image: none;
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- padding: 4px 8px;
- cursor: not-allowed;
- background-color: #f3f3f3;
- opacity: 0.65;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/textfield.jsx.snap b/src/web/components/form/__tests__/__snapshots__/textfield.jsx.snap
deleted file mode 100644
index b58f7386b2..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/textfield.jsx.snap
+++ /dev/null
@@ -1,91 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`TextField tests > should render 1`] = `
-.c0 {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
- display: block;
- height: 22px;
- color: #4C4C4C;
- background-color: #fff;
- background-image: none;
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- padding: 1px 8px;
-}
-
-.c0:-webkit-autofill {
- box-shadow: 0 0 0 1000px white inset;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
-
-exports[`TextField tests > should render in disabled state 1`] = `
-.c0 {
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
- display: block;
- height: 22px;
- color: #4C4C4C;
- background-color: #fff;
- background-image: none;
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- padding: 1px 8px;
- cursor: not-allowed;
- background-color: #f3f3f3;
- opacity: 0.65;
-}
-
-.c0:-webkit-autofill {
- box-shadow: 0 0 0 1000px white inset;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/timezoneselect.jsx.snap b/src/web/components/form/__tests__/__snapshots__/timezoneselect.jsx.snap
deleted file mode 100644
index 22c7404779..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/timezoneselect.jsx.snap
+++ /dev/null
@@ -1,178 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`TimezoneSelect tests > should render 1`] = `
-.c5 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- justify-content: center;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c6 {
- background-color: transparent;
- border: none;
- cursor: pointer;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-pack: center;
- -ms-flex-pack: center;
- -webkit-justify-content: center;
- justify-content: center;
- outline: none;
- margin: 1px;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- cursor: pointer;
-}
-
-.c7 {
- height: 16px;
- width: 16px;
- line-height: 16px;
-}
-
-.c7 * {
- height: inherit;
- width: inherit;
-}
-
-.c2 {
- border: 1px solid #bfbfbf;
- border-radius: 2px;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: stretch;
- -webkit-box-align: stretch;
- -ms-flex-align: stretch;
- align-items: stretch;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- padding: 1px 5px;
- background-color: #fff;
- color: #000;
- font-weight: normal;
-}
-
-.c1 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: column;
- -ms-flex-direction: column;
- flex-direction: column;
- position: relative;
- width: 230px;
-}
-
-.c3 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- -webkit-box-flex: 1;
- -webkit-flex-grow: 1;
- -ms-flex-positive: 1;
- flex-grow: 1;
- word-break: keep-all;
- white-space: nowrap;
- overflow: hidden;
- cursor: pointer;
-}
-
-.c8 {
- color: #c12c30;
- font-weight: bold;
- font-size: 19px;
- padding-bottom: 1px;
- padding-left: 4px;
- display: none;
-}
-
-.c4 {
- cursor: default;
-}
-
-.c0 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
-}
-
-
-
-
-
- Coordinated Universal Time/UTC
-
-
-
- ▼
-
-
-
-
-
- ×
-
-
-`;
diff --git a/src/web/components/form/__tests__/__snapshots__/yesnoradio.jsx.snap b/src/web/components/form/__tests__/__snapshots__/yesnoradio.jsx.snap
deleted file mode 100644
index 11455953a9..0000000000
--- a/src/web/components/form/__tests__/__snapshots__/yesnoradio.jsx.snap
+++ /dev/null
@@ -1,153 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`YesNoRadio tests > should render 1`] = `
-.c0 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: start;
- justify-content: start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-.c2 {
- margin-left: -5px;
-}
-
-.c2>* {
- display: -webkit-inline-box;
- display: -webkit-inline-flex;
- display: -ms-inline-flexbox;
- display: inline-flex;
-}
-
-.c2>* {
- margin-left: 5px;
-}
-
-.c1 {
- display: -webkit-inline-box;
- display: -webkit-inline-flex;
- display: -ms-inline-flexbox;
- display: inline-flex;
-}
-
-.c3 {
- display: -webkit-inline-box;
- display: -webkit-inline-flex;
- display: -ms-inline-flexbox;
- display: inline-flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- font-weight: normal;
- cursor: pointer;
-}
-
-.c4 {
- font-family: inherit;
- font-size: inherit;
- padding: 0;
- margin: 0;
- margin-left: 10px;
- line-height: normal;
- width: auto;
- height: auto;
-}
-
-.c6 {
- opacity: 1;
-}
-
-.c5 {
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- -webkit-flex-direction: row;
- -ms-flex-direction: row;
- flex-direction: row;
- -webkit-box-pack: start;
- -ms-flex-pack: start;
- -webkit-justify-content: flex-start;
- justify-content: flex-start;
- -webkit-align-items: center;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
-}
-
-
-`;
diff --git a/src/web/components/form/__tests__/button.jsx b/src/web/components/form/__tests__/button.jsx
index 96e1ee5cc5..19ab065e2b 100644
--- a/src/web/components/form/__tests__/button.jsx
+++ b/src/web/components/form/__tests__/button.jsx
@@ -17,7 +17,7 @@
*/
import {describe, test, expect, testing} from '@gsa/testing';
-import {render, fireEvent} from 'web/utils/testing';
+import {render, fireEvent, screen} from 'web/utils/testing';
import Button from '../button';
@@ -25,7 +25,9 @@ describe('Button tests', () => {
test('should call click handler', () => {
const handler = testing.fn();
- const {element} = render();
+ render();
+
+ const element = screen.getByRole('button');
fireEvent.click(element);
@@ -35,7 +37,9 @@ describe('Button tests', () => {
test('should call click handler with value', () => {
const handler = testing.fn();
- const {element} = render();
+ render();
+
+ const element = screen.getByRole('button');
fireEvent.click(element);
@@ -45,9 +49,9 @@ describe('Button tests', () => {
test('should call click handler with value and name', () => {
const handler = testing.fn();
- const {element} = render(
- ,
- );
+ render();
+
+ const element = screen.getByRole('button');
fireEvent.click(element);
@@ -57,22 +61,45 @@ describe('Button tests', () => {
test('should render button', () => {
const {element} = render();
- expect(element).toMatchSnapshot();
+ expect(element).toBeInTheDocument();
});
test('should render title', () => {
const {element} = render();
- expect(element).toHaveAttribute('title', 'foo');
expect(element).toHaveTextContent('foo');
});
- test('should render title and children', () => {
+ test('should prefer children over title', () => {
const {element} = render();
- expect(element).toHaveAttribute('title', 'foo');
expect(element).toHaveTextContent('bar');
});
+
+ test('should render disabled', () => {
+ const {element} = render();
+
+ expect(element).toBeDisabled();
+ });
+
+ test('should not call click handler when disabled', () => {
+ const handler = testing.fn();
+
+ render();
+
+ const element = screen.getByRole('button');
+
+ fireEvent.click(element);
+
+ expect(handler).not.toHaveBeenCalled();
+ });
+
+ test('should render loading', () => {
+ render();
+
+ const element = screen.getByRole('button');
+ expect(element).toHaveAttribute('data-loading', 'true');
+ });
});
// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/__tests__/checkbox.jsx b/src/web/components/form/__tests__/checkbox.jsx
index cba3337126..9f99084be1 100644
--- a/src/web/components/form/__tests__/checkbox.jsx
+++ b/src/web/components/form/__tests__/checkbox.jsx
@@ -17,18 +17,23 @@
*/
import {describe, test, expect, testing} from '@gsa/testing';
-import {render, fireEvent} from 'web/utils/testing';
+import {render, fireEvent, screen} from 'web/utils/testing';
import CheckBox from '../checkbox';
describe('CheckBox component tests', () => {
test('should call change handler', () => {
const change = testing.fn();
- const {element} = render(
- ,
+ render(
+ ,
);
- const input = element.querySelector('input');
+ const input = screen.getByTestId('checkbox');
fireEvent.click(input);
@@ -37,8 +42,9 @@ describe('CheckBox component tests', () => {
test('should use checkedValue', () => {
const change = testing.fn();
- const {element} = render(
+ render(
{
/>,
);
- const input = element.querySelector('input');
+ const input = screen.getByTestId('checkbox');
fireEvent.click(input);
@@ -56,8 +62,9 @@ describe('CheckBox component tests', () => {
test('should use unCheckedValue', () => {
const change = testing.fn();
- const {element} = render(
+ render(
{
/>,
);
- const input = element.querySelector('input');
+ const input = screen.getByTestId('checkbox');
fireEvent.click(input);
@@ -75,8 +82,9 @@ describe('CheckBox component tests', () => {
test('should not call change handler if disabled', () => {
const change = testing.fn();
- const {element} = render(
+ render(
{
/>,
);
- const input = element.querySelector('input');
+ const input = screen.getByTestId('checkbox');
fireEvent.click(input);
@@ -94,20 +102,10 @@ describe('CheckBox component tests', () => {
});
test('should render title', () => {
- const {getByTestId} = render();
-
- const titleElement = getByTestId('checkbox-title');
- expect(titleElement).toHaveTextContent('bar');
- });
+ render();
- test('should render with children', () => {
- const {element} = render(
-
- child1
- child2
- ,
- );
- expect(element).toMatchSnapshot();
+ screen.getByTestId('checkbox');
+ screen.getByLabelText('bar');
});
});
diff --git a/src/web/components/form/__tests__/download.jsx b/src/web/components/form/__tests__/download.jsx
index fd4868d44f..8a3b01e80a 100644
--- a/src/web/components/form/__tests__/download.jsx
+++ b/src/web/components/form/__tests__/download.jsx
@@ -24,11 +24,11 @@ import Download from '../download';
describe('Download tests', () => {
test('should render', () => {
const {element} = render();
- expect(element).toMatchSnapshot();
+ expect(element).toBeInTheDocument();
});
test('should render with filename', () => {
const {element} = render();
- expect(element).toMatchSnapshot();
+ expect(element).toBeInTheDocument();
});
});
diff --git a/src/web/components/form/__tests__/field.jsx b/src/web/components/form/__tests__/field.jsx
deleted file mode 100644
index 1132d0c36a..0000000000
--- a/src/web/components/form/__tests__/field.jsx
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Copyright (C) 2018-2022 Greenbone AG
- *
- * SPDX-License-Identifier: AGPL-3.0-or-later
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-import {describe, test, expect, testing} from '@gsa/testing';
-
-import Theme from 'web/utils/theme';
-import {render, fireEvent} from 'web/utils/testing';
-
-import Field, {DISABLED_OPACITY} from '../field';
-
-describe('Field tests', () => {
- test('should render', () => {
- const {element} = render();
-
- expect(element).not.toHaveStyleRule('cursor');
- expect(element).not.toHaveStyleRule('opacity');
- expect(element).toHaveStyleRule('background-color', Theme.white);
-
- expect(element).toMatchSnapshot();
- });
-
- test('should render in disabled state', () => {
- const {element} = render();
-
- expect(element).toHaveStyleRule('cursor', 'not-allowed');
- expect(element).toHaveStyleRule('opacity', `${DISABLED_OPACITY}`);
- expect(element).toHaveStyleRule('background-color', Theme.dialogGray);
-
- expect(element).toMatchSnapshot();
- });
-
- test('should call change handler with value', () => {
- const onChange = testing.fn();
-
- const {element} = render();
-
- fireEvent.change(element, {target: {value: 'bar'}});
-
- expect(onChange).toHaveBeenCalledWith('bar', undefined);
- });
-
- test('should call change handler with value and name', () => {
- const onChange = testing.fn();
-
- const {element} = render(
- ,
- );
-
- fireEvent.change(element, {target: {value: 'bar'}});
-
- expect(onChange).toHaveBeenCalledWith('bar', 'foo');
- });
-
- test('should not call change handler if disabled', () => {
- const onChange = testing.fn();
-
- const {element} = render(
- ,
- );
-
- fireEvent.change(element, {target: {value: 'bar'}});
-
- expect(onChange).not.toHaveBeenCalled();
- });
-});
-
-// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/__tests__/filefield.jsx b/src/web/components/form/__tests__/filefield.jsx
index 64c9286f2e..7bbfd27c50 100644
--- a/src/web/components/form/__tests__/filefield.jsx
+++ b/src/web/components/form/__tests__/filefield.jsx
@@ -24,12 +24,8 @@ import FileField from '../filefield';
describe('FileField tests', () => {
test('should render', () => {
const {element} = render();
- expect(element).toMatchSnapshot();
- });
- test('should render in disabled state', () => {
- const {element} = render();
- expect(element).toMatchSnapshot();
+ expect(element).toBeInTheDocument();
});
test('should call change handler with file', () => {
@@ -37,7 +33,9 @@ describe('FileField tests', () => {
const {element} = render();
- fireEvent.change(element, {target: {files: ['bar']}});
+ const input = element.querySelector('input[type=file]');
+
+ fireEvent.change(input, {target: {files: ['bar']}});
expect(onChange).toHaveBeenCalledWith('bar', undefined);
});
@@ -47,7 +45,9 @@ describe('FileField tests', () => {
const {element} = render();
- fireEvent.change(element, {target: {files: ['bar']}});
+ const input = element.querySelector('input[type=file]');
+
+ fireEvent.change(input, {target: {files: ['bar']}});
expect(onChange).toHaveBeenCalledWith('bar', 'foo');
});
@@ -57,7 +57,9 @@ describe('FileField tests', () => {
const {element} = render();
- fireEvent.change(element, {target: {files: ['bar']}});
+ const input = element.querySelector('input[type=file]');
+
+ fireEvent.change(input, {target: {files: ['bar']}});
expect(onChange).not.toHaveBeenCalled();
});
diff --git a/src/web/components/form/__tests__/formgroup.jsx b/src/web/components/form/__tests__/formgroup.jsx
index 24698c95b6..154d822257 100644
--- a/src/web/components/form/__tests__/formgroup.jsx
+++ b/src/web/components/form/__tests__/formgroup.jsx
@@ -17,79 +17,31 @@
*/
import {describe, test, expect} from '@gsa/testing';
-import {render} from 'web/utils/testing';
+import {render, screen} from 'web/utils/testing';
import FormGroup from '../formgroup';
describe('FormGroup tests', () => {
test('should render', () => {
- const {element, getByTestId} = render();
+ const {element} = render();
- expect(element).toHaveStyleRule('display', 'flex');
- expect(element).toHaveStyleRule('padding-bottom', '10px');
-
- const content = getByTestId('formgroup-content');
- expect(content).toHaveStyleRule('display', 'flex');
- expect(content).toHaveStyleRule('flex-direction', 'row');
-
- expect(element).toMatchSnapshot();
+ expect(element).toBeInTheDocument();
});
test('should render with title', () => {
- const {element, getByTestId} = render();
-
- const titleElement = getByTestId('formgroup-title');
- expect(titleElement).toHaveTextContent('Foo');
+ const {element} = render();
- expect(element).toMatchSnapshot();
+ expect(element).toHaveTextContent('Foo');
});
test('should render with children', () => {
- const {getByTestId} = render(
+ render(
- Foo
+ Foo
,
);
- const content = getByTestId('formgroup-content');
+ const content = screen.getByTestId('inner');
expect(content).toHaveTextContent('Foo');
});
-
- test('should allow to set size', () => {
- const {getByTestId} = render();
-
- const content = getByTestId('formgroup-content');
- expect(content).toHaveStyleRule('width', '50%');
- });
-
- test('should allow to set offset', () => {
- const {getByTestId} = render();
-
- const content = getByTestId('formgroup-content');
- expect(content).toHaveStyleRule('margin-left', '25%');
- });
-
- test('should allow to set title offset', () => {
- const {getByTestId} = render();
-
- const content = getByTestId('formgroup-content');
- expect(content).toHaveStyleRule('width', '66.66666667%');
-
- const titleElement = getByTestId('formgroup-title');
- expect(titleElement).toHaveStyleRule('width', '16.66666667%');
- expect(titleElement).toHaveStyleRule('margin-left', '16.66666667%');
- });
-
- test('should allow to set title size', () => {
- const {getByTestId} = render();
-
- const content = getByTestId('formgroup-content');
- expect(content).toHaveStyleRule('width', '66.66666667%');
-
- const titleElement = getByTestId('formgroup-title');
- expect(titleElement).toHaveStyleRule('width', '33.33333333%');
- expect(titleElement).toHaveStyleRule('margin-left', '0');
- });
});
-
-// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/__tests__/loadingbutton.jsx b/src/web/components/form/__tests__/loadingbutton.jsx
deleted file mode 100644
index 7511f0594a..0000000000
--- a/src/web/components/form/__tests__/loadingbutton.jsx
+++ /dev/null
@@ -1,100 +0,0 @@
-/* Copyright (C) 2018-2022 Greenbone AG
- *
- * SPDX-License-Identifier: AGPL-3.0-or-later
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-import {describe, test, expect, testing} from '@gsa/testing';
-
-import Theme from 'web/utils/theme';
-import {render, fireEvent} from 'web/utils/testing';
-
-import LoadingButton from '../loadingbutton';
-
-describe('LoadingButton tests', () => {
- test('should render non loading', () => {
- const {element} = render();
-
- expect(element).toMatchSnapshot();
- });
-
- test('should render loading', () => {
- const {element} = render();
-
- expect(element).toMatchSnapshot();
- });
-
- test('should call click handler', () => {
- const handler = testing.fn();
-
- const {element} = render();
-
- fireEvent.click(element);
-
- expect(handler).toHaveBeenCalled();
- });
-
- test('should call click handler with value', () => {
- const handler = testing.fn();
-
- const {element} = render();
-
- fireEvent.click(element);
-
- expect(handler).toHaveBeenCalledWith('bar', undefined);
- });
-
- test('should call click handler with value and name', () => {
- const handler = testing.fn();
-
- const {element} = render(
- ,
- );
-
- fireEvent.click(element);
-
- expect(handler).toHaveBeenCalledWith('bar', 'foo');
- });
-
- test('should render title', () => {
- const {element} = render();
-
- expect(element).toHaveAttribute('title', 'foo');
- expect(element).toHaveTextContent('foo');
- });
-
- test('should render title and children', () => {
- const {element} = render(bar);
-
- expect(element).toHaveAttribute('title', 'foo');
- expect(element).toHaveTextContent('bar');
- });
-
- test('should render non loading with title', () => {
- const {element} = render();
-
- expect(element).toHaveStyleRule('background', Theme.white);
- });
-
- test('should render loading with title', () => {
- const {element} = render();
-
- expect(element).toHaveStyleRule(
- 'background',
- `${Theme.lightGreen} url(/img/loading.gif) center center no-repeat`,
- );
- });
-});
-
-// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/__tests__/multiselect.jsx b/src/web/components/form/__tests__/multiselect.jsx
index 8378db55fe..f7b8eb94ad 100644
--- a/src/web/components/form/__tests__/multiselect.jsx
+++ b/src/web/components/form/__tests__/multiselect.jsx
@@ -18,28 +18,37 @@
import {describe, test, expect, testing} from '@gsa/testing';
-import {render, fireEvent} from 'web/utils/testing';
+import {render, fireEvent, screen, userEvent} from 'web/utils/testing';
import MultiSelect from '../multiselect';
-const openInputElement = element => {
- const button = element.querySelector('[type="button"]');
- fireEvent.click(button);
+const openSelectElement = async select => {
+ select = select || getSelectElement();
+ await userEvent.click(select);
};
-const getItemElements = baseElement => {
- const portal = baseElement.querySelector('#portals');
- return portal.querySelectorAll('span');
+const getItemElements = () => {
+ return screen.queryAllByRole('option');
};
-describe('MultiSelect component tests', () => {
- test('should render', () => {
- const {element} = render();
+const getSelectElement = () => {
+ const select = screen.queryByRole('searchbox');
+ if (select) {
+ return select;
+ }
+ return screen.getByRole('textbox');
+};
+
+const getSelectedItems = element => {
+ return element.querySelectorAll('.mantine-MultiSelect-value');
+};
- expect(element).toMatchSnapshot();
+describe('MultiSelect tests', () => {
+ test('should render', () => {
+ render();
});
- test('should render with items', () => {
+ test('should render with items', async () => {
const items = [
{
value: 'bar',
@@ -51,20 +60,19 @@ describe('MultiSelect component tests', () => {
},
];
- const {element, baseElement} = render();
+ render();
- let domItems = getItemElements(baseElement);
- expect(domItems.length).toEqual(0);
+ expect(getItemElements().length).toEqual(0);
- openInputElement(element);
+ await openSelectElement();
- domItems = getItemElements(baseElement);
+ const domItems = getItemElements();
expect(domItems.length).toEqual(2);
expect(domItems[0]).toHaveTextContent('Bar');
expect(domItems[1]).toHaveTextContent('Foo');
});
- test('should render loading', () => {
+ test('should render loading', async () => {
const items = [
{
value: '0',
@@ -72,22 +80,20 @@ describe('MultiSelect component tests', () => {
},
];
- const {element, baseElement} = render(
- ,
- );
+ render();
- expect(element).toHaveTextContent('Loading...');
+ const element = getSelectElement();
- let domItems = getItemElements(baseElement);
- expect(domItems.length).toEqual(0);
+ expect(element).toHaveAttribute('placeholder', 'Loading...');
- openInputElement(element);
+ expect(getItemElements().length).toEqual(0);
- domItems = getItemElements(baseElement);
- expect(domItems.length).toEqual(0);
+ await openSelectElement(element);
+
+ expect(getItemElements().length).toEqual(0);
});
- test('should render invalid state', () => {
+ test('should render error', () => {
const items = [
{
value: '0',
@@ -95,13 +101,14 @@ describe('MultiSelect component tests', () => {
},
];
- const {element} = render();
+ render();
+
+ getSelectElement();
- expect(element).toHaveTextContent('×');
- expect(element).toHaveStyleRule('background-color: #f2dede');
+ expect(screen.getByText('Some Error')).toBeVisible();
});
- test('should call onChange handler', () => {
+ test('should call onChange handler', async () => {
const items = [
{
value: 'bar',
@@ -115,22 +122,19 @@ describe('MultiSelect component tests', () => {
const onChange = testing.fn();
- const {element, baseElement} = render(
- ,
- );
+ render();
- openInputElement(element);
+ await openSelectElement();
- const domItems = getItemElements(baseElement);
+ const domItems = getItemElements();
expect(domItems.length).toEqual(2);
- fireEvent.click(domItems[1]);
+ await userEvent.click(domItems[1]);
- expect(onChange).toBeCalled();
- expect(onChange).toBeCalledWith(['foo'], undefined);
+ expect(onChange).toHaveBeenCalledWith(['foo'], undefined);
});
- test('should call onChange handler with name', () => {
+ test('should call onChange handler with name', async () => {
const items = [
{
value: 'bar',
@@ -144,22 +148,19 @@ describe('MultiSelect component tests', () => {
const onChange = testing.fn();
- const {element, baseElement} = render(
- ,
- );
+ render();
- openInputElement(element);
+ await openSelectElement();
- const domItems = getItemElements(baseElement);
+ const domItems = getItemElements();
expect(domItems.length).toEqual(2);
- fireEvent.click(domItems[0]);
+ await userEvent.click(domItems[0]);
- expect(onChange).toBeCalled();
- expect(onChange).toBeCalledWith(['bar'], 'abc');
+ expect(onChange).toHaveBeenCalledWith(['bar'], 'abc');
});
- test('should change displayed values', () => {
+ test('should change displayed values', async () => {
const items = [
{
value: 'bar',
@@ -171,29 +172,29 @@ describe('MultiSelect component tests', () => {
},
];
- const {rerender, getAllByTestId} = render(
+ const {element, rerender} = render(
,
);
- let displayedItems = getAllByTestId('multiselect-selected-label');
+ let displayedItems = getSelectedItems(element);
expect(displayedItems.length).toEqual(1);
expect(displayedItems[0]).toHaveTextContent('Bar');
rerender();
- displayedItems = getAllByTestId('multiselect-selected-label');
+ displayedItems = getSelectedItems(element);
expect(displayedItems.length).toEqual(1);
expect(displayedItems[0]).toHaveTextContent('Foo');
rerender();
- displayedItems = getAllByTestId('multiselect-selected-label');
+ displayedItems = getSelectedItems(element);
expect(displayedItems.length).toEqual(2);
expect(displayedItems[0]).toHaveTextContent('Foo');
expect(displayedItems[1]).toHaveTextContent('Bar');
});
- test('should filter items', () => {
+ test('should filter items', async () => {
const items = [
{
value: 'bar',
@@ -209,27 +210,21 @@ describe('MultiSelect component tests', () => {
},
];
- const {element, getByTestId, getAllByTestId} = render(
- ,
- );
+ render();
- openInputElement(element);
+ const input = getSelectElement();
- let domItems = getAllByTestId('multiselect-item-label');
- expect(domItems.length).toEqual(3);
-
- const input = getByTestId('multiselect-input');
+ await openSelectElement(input);
+ expect(getItemElements().length).toEqual(3);
fireEvent.change(input, {target: {value: 'ba'}});
- domItems = getAllByTestId('multiselect-item-label');
- expect(domItems.length).toEqual(2);
+ expect(getItemElements().length).toEqual(2);
fireEvent.change(input, {target: {value: 'F'}});
- domItems = getAllByTestId('multiselect-item-label');
- expect(domItems.length).toEqual(1);
+ expect(getItemElements().length).toEqual(1);
});
- test('should call onChange handler to remove selected item', () => {
+ test('should call onChange handler to remove selected item', async () => {
const items = [
{
value: 'bar',
@@ -243,19 +238,16 @@ describe('MultiSelect component tests', () => {
const onChange = testing.fn();
- const {getAllByTestId} = render(
+ const {element} = render(
,
);
- const selectedItems = getAllByTestId('multiselect-selected-label');
+ const selectedItems = getSelectedItems(element);
expect(selectedItems.length).toEqual(2);
- const deleteIcons = getAllByTestId('multiselect-selected-delete');
- expect(deleteIcons.length).toEqual(2);
- fireEvent.click(deleteIcons[0]);
+ const deleteIcon = selectedItems[0].querySelector('button');
+ await userEvent.click(deleteIcon);
expect(onChange).toHaveBeenCalledWith(['foo'], undefined);
});
});
-
-// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/__tests__/numberfield.jsx b/src/web/components/form/__tests__/numberfield.jsx
index 0d3c24d699..50432413f9 100644
--- a/src/web/components/form/__tests__/numberfield.jsx
+++ b/src/web/components/form/__tests__/numberfield.jsx
@@ -17,23 +17,24 @@
*/
import {describe, test, expect, testing} from '@gsa/testing';
-import {KeyCode} from 'gmp/utils/event';
-
-import {render, fireEvent} from 'web/utils/testing';
+import {render, fireEvent, screen} from 'web/utils/testing';
import NumberField from '../numberfield';
describe('NumberField tests', () => {
test('should render', () => {
- const {element} = render();
+ render();
+
+ const element = screen.getByTestId('input');
expect(element).toHaveAttribute('value', '1');
- expect(element).toMatchSnapshot();
});
test('should call change handler', () => {
const onChange = testing.fn();
- const {element} = render();
+ render();
+
+ const element = screen.getByTestId('input');
fireEvent.change(element, {target: {value: '2'}});
@@ -41,12 +42,43 @@ describe('NumberField tests', () => {
expect(element).toHaveAttribute('value', '2');
});
+ test('should call change handler for characters with empty string', () => {
+ const onChange = testing.fn();
+ render();
+
+ const element = screen.getByTestId('input');
+
+ fireEvent.change(element, {target: {value: 'ABC'}});
+
+ expect(onChange).toHaveBeenCalledWith('', undefined);
+ expect(element).toHaveAttribute('value', '');
+ });
+
+ test('should allow to clear input', () => {
+ const onChange = testing.fn();
+ render();
+
+ const element = screen.getByTestId('input');
+
+ fireEvent.change(element, {target: {value: ''}});
+
+ expect(onChange).toHaveBeenCalledWith('', undefined);
+ expect(element).toHaveAttribute('value', '');
+ });
+
test('should call change handler with value and name', () => {
const onChange = testing.fn();
- const {element} = render(
- ,
+ render(
+ ,
);
+ const element = screen.getByTestId('input');
+
fireEvent.change(element, {target: {value: '2'}});
expect(onChange).toHaveBeenCalledWith(2, 'foo');
@@ -55,186 +87,69 @@ describe('NumberField tests', () => {
test('should not call change handler if disabled', () => {
const onChange = testing.fn();
- const {element} = render(
- ,
+ render(
+ ,
);
+ const element = screen.getByTestId('input');
+
fireEvent.change(element, {target: {value: '2'}});
expect(onChange).not.toHaveBeenCalled();
- expect(element).toHaveAttribute('value', '1');
});
test('should update value', () => {
const onChange = testing.fn();
- const {element, rerender} = render(
- ,
+ const {rerender} = render(
+ ,
);
+ const element = screen.getByTestId('input');
+
fireEvent.change(element, {target: {value: '2'}});
expect(onChange).toHaveBeenCalledWith(2, undefined);
expect(element).toHaveAttribute('value', '2');
- rerender();
+ rerender();
expect(element).toHaveAttribute('value', '2');
- rerender();
+ rerender();
expect(element).toHaveAttribute('value', '3');
});
- test('should not call change handler if value > max', () => {
+ test('should use max if value > max', () => {
const onChange = testing.fn();
- const {element} = render(
- ,
+ render(
+ ,
);
- fireEvent.change(element, {target: {value: '3'}});
-
- expect(onChange).not.toHaveBeenCalled();
- // value will be shown but reset on blur
- expect(element).toHaveAttribute('value', '3');
- });
-
- test('should reset to max', () => {
- const onChange = testing.fn();
- const {element} = render(
- ,
- );
+ const element = screen.getByTestId('input');
fireEvent.change(element, {target: {value: '3'}});
- expect(onChange).not.toHaveBeenCalled();
- expect(element).toHaveAttribute('value', '3');
-
- fireEvent.keyDown(element, {key: 'Enter', keyCode: KeyCode.ENTER});
-
+ expect(onChange).toHaveBeenCalledWith(2, undefined);
expect(element).toHaveAttribute('value', '2');
});
- test('should not call change handler if value < min', () => {
- const onChange = testing.fn();
- const {element} = render(
- ,
- );
-
- fireEvent.change(element, {target: {value: '0'}});
-
- expect(onChange).not.toHaveBeenCalled();
- // will be set to min after blur only
- expect(element).toHaveAttribute('value', '0');
- });
-
- test('should reset to min', () => {
+ test('should use min if value < min', () => {
const onChange = testing.fn();
- const {element} = render(
- ,
+ render(
+ ,
);
- expect(element).toHaveAttribute('value', '2');
+ const element = screen.getByTestId('input');
fireEvent.change(element, {target: {value: '0'}});
- expect(onChange).not.toHaveBeenCalled();
- expect(element).toHaveAttribute('value', '0');
-
- fireEvent.keyDown(element, {key: 'Enter', keyCode: KeyCode.ENTER});
-
+ expect(onChange).toHaveBeenCalledWith(1, undefined);
expect(element).toHaveAttribute('value', '1');
});
-
- test('should reset to last valid value', () => {
- const onChange = testing.fn();
- const {element} = render(
- ,
- );
-
- expect(element).toHaveAttribute('value', '2');
-
- fireEvent.change(element, {target: {value: 'a'}});
-
- expect(onChange).not.toHaveBeenCalled();
- expect(element).toHaveAttribute('value', 'a');
-
- fireEvent.keyDown(element, {key: 'Enter', keyCode: KeyCode.ENTER});
-
- expect(element).toHaveAttribute('value', '2');
- });
-
- test('should not allow to add letters', () => {
- const handler = testing.fn();
- const {element} = render();
-
- fireEvent.keyDown(element, {key: 'a', keyCode: 65});
-
- expect(handler).not.toHaveBeenCalled();
- });
-
- test('should allow to add numbers', () => {
- const handler = testing.fn();
- const {element} = render();
-
- fireEvent.keyDown(element, {key: '1', keyCode: 49});
- fireEvent.keyDown(element, {key: '2', keyCode: 50});
-
- expect(handler).toHaveBeenCalledTimes(2);
- });
-
- test('should allow point key for float numbers', () => {
- const handler = testing.fn();
- const {element} = render(
- ,
- );
-
- fireEvent.keyDown(element, {key: '.', keyCode: KeyCode.PERIOD});
- fireEvent.keyDown(element, {key: '2', keyCode: 50});
-
- expect(handler).toHaveBeenCalledTimes(2);
- });
-
- test('should not allow point key for int numbers', () => {
- const handler = testing.fn();
- const {element} = render(
- ,
- );
-
- fireEvent.keyDown(element, {key: '.', keyCode: KeyCode.PERIOD});
- fireEvent.keyDown(element, {key: '2', keyCode: 50});
-
- expect(handler).toHaveBeenCalledTimes(1);
- });
-
- test('should call onDownKeyPressed handler', () => {
- const handler = testing.fn();
- const {element} = render(
- ,
- );
-
- fireEvent.keyDown(element, {key: '1', keyCode: 49});
- expect(handler).not.toHaveBeenCalled();
-
- fireEvent.keyDown(element, {key: 'PageDown', keyCode: KeyCode.PAGE_DOWN});
- fireEvent.keyDown(element, {key: 'ArrowDown', keyCode: KeyCode.DOWN});
-
- expect(handler).toHaveBeenCalledTimes(2);
- });
-
- test('should call onUpKeyPressed handler', () => {
- const handler = testing.fn();
- const {element} = render(
- ,
- );
-
- fireEvent.keyDown(element, {key: '1', keyCode: 49});
- expect(handler).not.toHaveBeenCalled();
-
- fireEvent.keyDown(element, {key: 'PageUp', keyCode: KeyCode.PAGE_UP});
- fireEvent.keyDown(element, {key: 'ArrowUp', keyCode: KeyCode.UP});
-
- expect(handler).toHaveBeenCalledTimes(2);
- });
});
-
-// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/__tests__/passwordfield.jsx b/src/web/components/form/__tests__/passwordfield.jsx
index 4885c9d954..8f89cb84b0 100644
--- a/src/web/components/form/__tests__/passwordfield.jsx
+++ b/src/web/components/form/__tests__/passwordfield.jsx
@@ -17,29 +17,29 @@
*/
import {describe, test, expect, testing} from '@gsa/testing';
-import {render, fireEvent} from 'web/utils/testing';
+import {render, fireEvent, screen} from 'web/utils/testing';
import PasswordField from '../passwordfield';
describe('PasswordField tests', () => {
test('should render', () => {
- const {element} = render();
+ render();
+
+ const element = screen.getByTestId('input');
// ensure type is password to NOT SHOW plain text
expect(element).toHaveAttribute('type', 'password');
-
- expect(element).toMatchSnapshot();
- });
-
- test('should render in disabled state', () => {
- const {element} = render();
- expect(element).toMatchSnapshot();
+ expect(element).toBeInTheDocument();
});
test('should call change handler with value', () => {
const onChange = testing.fn();
- const {element} = render();
+ render(
+ ,
+ );
+
+ const element = screen.getByTestId('input');
fireEvent.change(element, {target: {value: 'bar'}});
@@ -49,10 +49,17 @@ describe('PasswordField tests', () => {
test('should call change handler with value and name', () => {
const onChange = testing.fn();
- const {element} = render(
- ,
+ render(
+ ,
);
+ const element = screen.getByTestId('input');
+
fireEvent.change(element, {target: {value: 'bar'}});
expect(onChange).toHaveBeenCalledWith('bar', 'foo');
@@ -61,14 +68,33 @@ describe('PasswordField tests', () => {
test('should not call change handler if disabled', () => {
const onChange = testing.fn();
- const {element} = render(
- ,
+ render(
+ ,
);
+ const element = screen.getByTestId('input');
+
fireEvent.change(element, {target: {value: 'bar'}});
expect(onChange).not.toHaveBeenCalled();
});
-});
-// vim: set ts=2 sw=2 tw=80:
+ test('should allow to clear input', () => {
+ const onChange = testing.fn();
+
+ render(
+ ,
+ );
+
+ const element = screen.getByTestId('input');
+
+ fireEvent.change(element, {target: {value: ''}});
+
+ expect(onChange).toHaveBeenCalledWith('', undefined);
+ });
+});
diff --git a/src/web/components/form/__tests__/radio.jsx b/src/web/components/form/__tests__/radio.jsx
index 9539caa40b..6b59464de2 100644
--- a/src/web/components/form/__tests__/radio.jsx
+++ b/src/web/components/form/__tests__/radio.jsx
@@ -17,70 +17,23 @@
*/
import {describe, test, expect, testing} from '@gsa/testing';
-import {render, fireEvent} from 'web/utils/testing';
+import {render, fireEvent, screen} from 'web/utils/testing';
-import Radio, {StyledElement, StyledInput, StyledTitle} from '../radio';
-
-describe('StyledElement tests', () => {
- test('should render', () => {
- const {element} = render();
- expect(element).toHaveStyleRule('cursor', 'pointer');
- });
-
- test('should render in disabled state', () => {
- const {element} = render();
- expect(element).toHaveStyleRule('cursor', 'not-allowed');
- });
-});
-
-describe('StyledInput tests', () => {
- test('should render', () => {
- const {element} = render();
- expect(element).not.toHaveStyleRule('cursor');
- expect(element).not.toHaveStyleRule('opacity');
- });
-
- test('should render in disabled state', () => {
- const {element} = render();
- expect(element).toHaveStyleRule('cursor', 'not-allowed');
- expect(element).toHaveStyleRule('opacity', '0.7');
- });
-});
-
-describe('StyledTitle tests', () => {
- test('should render', () => {
- const {element} = render();
- expect(element).not.toHaveStyleRule('cursor');
- expect(element).toHaveStyleRule('opacity', '1');
- });
-
- test('should render in disabled state', () => {
- const {element} = render();
- expect(element).toHaveStyleRule('cursor', 'not-allowed');
- expect(element).toHaveStyleRule('opacity', '0.5');
- });
-});
+import Radio from '../radio';
describe('Radio tests', () => {
test('should render radio', () => {
const {element} = render();
- expect(element).toMatchSnapshot();
- });
- test('should render radio with children', () => {
- const {element} = render(
-
- child1
- child2
- ,
- );
- expect(element).toMatchSnapshot();
+ expect(element).toBeInTheDocument();
});
test('should call change handler', () => {
const onChange = testing.fn();
- const {element} = render();
+ render();
+
+ const element = screen.getByTestId('input');
fireEvent.click(element);
@@ -90,7 +43,9 @@ describe('Radio tests', () => {
test('should call change handler with value', () => {
const onChange = testing.fn();
- const {element} = render();
+ render();
+
+ const element = screen.getByTestId('input');
fireEvent.click(element);
@@ -100,10 +55,12 @@ describe('Radio tests', () => {
test('should call change handler with value and name', () => {
const onChange = testing.fn();
- const {element} = render(
- ,
+ render(
+ ,
);
+ const element = screen.getByTestId('input');
+
fireEvent.click(element);
expect(onChange).toHaveBeenCalledWith('foo', 'bar');
@@ -112,7 +69,9 @@ describe('Radio tests', () => {
test('should not call change handler if disabled', () => {
const onChange = testing.fn();
- const {element} = render();
+ render();
+
+ const element = screen.getByTestId('input');
fireEvent.click(element);
@@ -120,23 +79,28 @@ describe('Radio tests', () => {
});
test('should render title', () => {
- const {getByTestId} = render();
+ const {element} = render();
- const titleElement = getByTestId('radio-title');
+ const titleElement = element.querySelector('label');
expect(titleElement).toHaveTextContent('foo');
});
test('should not call change handler if already checked', () => {
const onChange = testing.fn();
- const {element} = render(
- ,
+ render(
+ ,
);
+ const element = screen.getByTestId('input');
+
fireEvent.click(element);
expect(onChange).not.toHaveBeenCalled();
});
});
-
-// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/__tests__/select.jsx b/src/web/components/form/__tests__/select.jsx
index c111c6bc69..ec72551007 100644
--- a/src/web/components/form/__tests__/select.jsx
+++ b/src/web/components/form/__tests__/select.jsx
@@ -17,38 +17,42 @@
*/
import {describe, test, expect, testing} from '@gsa/testing';
-import {
- render,
- fireEvent,
- queryAllByTestId,
- getByTestId,
-} from 'web/utils/testing';
+import {render, fireEvent, screen, userEvent, act} from 'web/utils/testing';
import Select from '../select';
-export const openSelectElement = element => {
- const openButton = getByTestId(element, 'select-open-button');
- fireEvent.click(openButton);
+export const openSelectElement = async select => {
+ await act(async () => {
+ select = select || getSelectElement();
+ await userEvent.click(select);
+ });
+};
+
+export const getItemElements = () => {
+ return screen.queryAllByRole('option');
};
-export const getItemElements = baseElement => {
- const portal = baseElement.querySelector('#portals');
- return queryAllByTestId(portal, 'select-item');
+export const getSelectElement = () => {
+ const select = screen.queryByRole('searchbox');
+ if (select) {
+ return select;
+ }
+ return screen.getByRole('textbox');
};
-export const getInputBox = baseElement => {
- const portal = baseElement.querySelector('#portals');
- return getByTestId(portal, 'select-search-input');
+export const clickItem = async item => {
+ await act(async () => {
+ await userEvent.click(item);
+ });
};
describe('Select component tests', () => {
test('should render', () => {
const {element} = render();
-
- expect(element).toMatchSnapshot();
+ expect(element).toBeInTheDocument();
});
- test('should render with items', () => {
+ test('should render with items', async () => {
const items = [
{
value: 'bar',
@@ -59,22 +63,23 @@ describe('Select component tests', () => {
label: 'Foo',
},
];
- const {element, baseElement} = render();
- let domItems = getItemElements(baseElement);
+ render();
+
+ const element = getSelectElement();
- expect(domItems.length).toEqual(0);
+ expect(getItemElements().length).toEqual(0);
- openSelectElement(element);
+ await openSelectElement(element);
- domItems = getItemElements(baseElement);
+ const domItems = getItemElements();
expect(domItems.length).toEqual(2);
expect(domItems[0]).toHaveTextContent('Bar');
expect(domItems[1]).toHaveTextContent('Foo');
});
- test('should render loading', () => {
+ test('should render loading', async () => {
const items = [
{
value: '0',
@@ -82,22 +87,20 @@ describe('Select component tests', () => {
},
];
- const {element, baseElement} = render(
- ,
- );
+ render();
+
+ const element = getSelectElement();
- expect(element).toHaveTextContent('Loading...');
+ expect(element).toHaveAttribute('placeholder', 'Loading...');
- let domItems = getItemElements(baseElement);
- expect(domItems.length).toEqual(0);
+ expect(getItemElements().length).toEqual(0);
- openSelectElement(element);
+ await openSelectElement(element);
- domItems = getItemElements(baseElement);
- expect(domItems.length).toEqual(0);
+ expect(getItemElements().length).toEqual(0);
});
- test('should render invalid state', () => {
+ test('should render error', () => {
const items = [
{
value: '0',
@@ -105,13 +108,14 @@ describe('Select component tests', () => {
},
];
- const {element} = render();
+ render();
- expect(element).toHaveTextContent('×');
- expect(element).toHaveStyleRule('background-color: #f2dede');
+ getSelectElement();
+
+ expect(screen.getByText('Some Error')).toBeVisible();
});
- test('should call onChange handler', () => {
+ test('should call onChange handler', async () => {
const items = [
{
value: 'bar',
@@ -125,23 +129,20 @@ describe('Select component tests', () => {
const onChange = testing.fn();
- const {element, baseElement} = render(
- ,
- );
+ render();
- openSelectElement(element);
+ await openSelectElement();
- const domItems = getItemElements(baseElement);
+ const domItems = getItemElements();
expect(domItems.length).toEqual(2);
- fireEvent.click(domItems[0]);
+ await clickItem(domItems[0]);
- expect(onChange).toBeCalled();
- expect(onChange).toBeCalledWith('bar', undefined);
+ expect(onChange).toHaveBeenCalledWith('bar', undefined);
});
- test('should call onChange handler with name', () => {
+ test('should call onChange handler with name', async () => {
const items = [
{
value: 'bar',
@@ -155,21 +156,39 @@ describe('Select component tests', () => {
const onChange = testing.fn();
- const {element, baseElement} = render(
- ,
- );
+ render();
+
+ await openSelectElement();
+
+ const domItems = getItemElements();
+
+ await clickItem(domItems[0]);
+
+ expect(onChange).toHaveBeenCalledWith('bar', 'abc');
+ });
+
+ test('should render value', async () => {
+ const items = [
+ {
+ value: 'bar',
+ label: 'Bar',
+ },
+ {
+ value: 'foo',
+ label: 'Foo',
+ },
+ ];
- openSelectElement(element);
+ const onChange = testing.fn();
- const domItems = getItemElements(baseElement);
+ render();
- fireEvent.click(domItems[0]);
+ const input = getSelectElement();
- expect(onChange).toBeCalled();
- expect(onChange).toBeCalledWith('bar', 'abc');
+ expect(input).toHaveValue('Bar');
});
- test('should change value', () => {
+ test('should call change handler when changing item', async () => {
const items = [
{
value: 'bar',
@@ -183,25 +202,20 @@ describe('Select component tests', () => {
const onChange = testing.fn();
- // eslint-disable-next-line no-shadow
- const {baseElement, element, getByTestId} = render(
- ,
- );
+ render();
- const displayedValue = getByTestId('select-selected-value');
- expect(displayedValue).toHaveTextContent('Bar');
+ const input = getSelectElement();
- openSelectElement(element);
+ await openSelectElement(input);
- const domItems = getItemElements(baseElement);
+ const domItems = getItemElements();
- fireEvent.click(domItems[1]);
+ await clickItem(domItems[1]);
- expect(onChange).toBeCalled();
- expect(onChange).toBeCalledWith('foo', undefined);
+ expect(onChange).toHaveBeenCalledWith('foo', undefined);
});
- test('should filter items', () => {
+ test('should filter items', async () => {
const items = [
{
value: 'bar',
@@ -217,24 +231,21 @@ describe('Select component tests', () => {
},
];
- const {element, baseElement} = render();
+ render();
- openSelectElement(element);
+ await openSelectElement();
- let domItems = getItemElements(baseElement);
- expect(domItems.length).toEqual(3);
+ expect(getItemElements().length).toEqual(3);
- const input = getInputBox(baseElement);
+ const input = getSelectElement();
fireEvent.change(input, {target: {value: 'ba'}});
- domItems = getItemElements(baseElement);
- expect(domItems.length).toEqual(2);
+ expect(getItemElements().length).toEqual(2);
fireEvent.change(input, {target: {value: 'F'}});
- domItems = getItemElements(baseElement);
- expect(domItems.length).toEqual(1);
+ expect(getItemElements().length).toEqual(1);
});
});
diff --git a/src/web/components/form/__tests__/selectelement.jsx b/src/web/components/form/__tests__/selectelement.jsx
deleted file mode 100644
index b17bf93746..0000000000
--- a/src/web/components/form/__tests__/selectelement.jsx
+++ /dev/null
@@ -1,324 +0,0 @@
-/* Copyright (C) 2018-2022 Greenbone AG
- *
- * SPDX-License-Identifier: AGPL-3.0-or-later
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-import {describe, test, expect, testing} from '@gsa/testing';
-
-import React from 'react';
-
-import {isFunction} from 'gmp/utils/identity';
-
-import {render} from 'web/utils/testing';
-import Theme from 'web/utils/theme';
-import PropTypes from 'web/utils/proptypes';
-
-import {
- Box,
- Item,
- Input,
- ItemContainer,
- Menu,
- SelectContainer,
- SelectedValue,
- caseInsensitiveFilter,
-} from '../selectelements';
-
-describe('Box tests', () => {
- test('should render', () => {
- const {element} = render();
-
- expect(element).toHaveStyleRule('background-color', Theme.white);
- expect(element).toHaveStyleRule('border-radius', '2px');
- expect(element).toMatchSnapshot();
- });
-
- test('should render opened', () => {
- const {element} = render();
-
- expect(element).toHaveStyleRule('border-radius', '2px 2px 0 0');
- expect(element).toMatchSnapshot();
- });
-
- test('should render disabled', () => {
- const {element} = render();
-
- expect(element).toHaveStyleRule('background-color', Theme.dialogGray);
- expect(element).toMatchSnapshot();
- });
-});
-
-describe('Input tests', () => {
- test('should render', () => {
- const {element} = render();
- expect(element).toMatchSnapshot();
- });
-});
-
-describe('Item tests', () => {
- test('should render', () => {
- const {element} = render( );
-
- expect(element).not.toHaveStyleRule('background-color');
- expect(element).not.toHaveStyleRule('color');
- expect(element).toMatchSnapshot();
- });
-
- test('should render active', () => {
- const {element} = render( );
-
- expect(element).toHaveStyleRule('background-color', Theme.mediumBlue);
- expect(element).toHaveStyleRule('color', Theme.white);
- expect(element).toMatchSnapshot();
- });
-
- test('should render selected', () => {
- const {element} = render( );
-
- expect(element).toHaveStyleRule('background-color', Theme.lightGray);
- expect(element).not.toHaveStyleRule('color');
- expect(element).toMatchSnapshot();
- });
-});
-
-describe('ItemContainer tests', () => {
- test('should render', () => {
- const {element} = render();
- expect(element).toMatchSnapshot();
- });
-});
-
-describe('SelectContainer tests', () => {
- test('should render', () => {
- const {element} = render();
-
- expect(element).toHaveStyleRule('width', '100px');
- expect(element).toMatchSnapshot();
- });
-});
-
-describe('SelectValue tests', () => {
- test('should render', () => {
- const {element} = render();
-
- expect(element).toHaveStyleRule('cursor', 'pointer');
- expect(element).toMatchSnapshot();
- });
-
- test('should render disabled', () => {
- const {element} = render();
-
- expect(element).toHaveStyleRule('cursor', 'default');
- expect(element).toMatchSnapshot();
- });
-});
-
-describe('caseInsensitiveFilter tests', () => {
- test('should not filter if search term is undefined', () => {
- const filter = caseInsensitiveFilter();
- const items = [
- {
- value: 'foo',
- label: 'Foo',
- },
- {
- value: 'bar',
- label: 'Bar',
- },
- ];
-
- expect(isFunction(filter)).toEqual(true);
- expect(items.filter(filter)).toEqual(items);
- });
-
- test('should not filter if search term is empty', () => {
- const filter = caseInsensitiveFilter();
- const items = [
- {
- value: 1,
- label: 'Foo',
- },
- {
- value: 2,
- label: 'Bar',
- },
- ];
-
- expect(isFunction(filter)).toEqual(true);
- expect(items.filter(filter)).toEqual(items);
- });
-
- test('should filter by search term', () => {
- const filter = caseInsensitiveFilter('Foo');
- const items = [
- {
- value: 1,
- label: 'Foo',
- },
- {
- value: 2,
- label: 'Bar',
- },
- ];
-
- expect(isFunction(filter)).toEqual(true);
- expect(items.filter(filter)).toEqual([
- {
- value: 1,
- label: 'Foo',
- },
- ]);
- });
-
- test('should filter by search term case insensitive', () => {
- const filter = caseInsensitiveFilter('OO');
- const items = [
- {
- value: 1,
- label: 'Foo',
- },
- {
- value: 2,
- label: 'Bar',
- },
- ];
-
- expect(isFunction(filter)).toEqual(true);
- expect(items.filter(filter)).toEqual([
- {
- value: 1,
- label: 'Foo',
- },
- ]);
- });
-});
-
-class MenuTestComponent extends React.Component {
- constructor(...args) {
- super(...args);
-
- this.target = React.createRef();
- const {mockBoundingClientRect, ...otherProps} = this.props;
- this.mockBoundingClientRect = mockBoundingClientRect;
- this.otherProps = otherProps;
- this.notifyRefAssigned = testing.fn();
- }
-
- render() {
- const hasTarget = this.target.current !== null;
- if (hasTarget && this.mockBoundingClientRect) {
- const rect = this.target.current.closest('.multiselect-scroll');
- if (rect !== null) {
- testing.spyOn(rect, 'getBoundingClientRect').mockImplementation(() => {
- return {
- top: 100,
- bottom: 50,
- height: 20,
- width: 100,
- right: 10,
- left: 50,
- };
- });
- }
- }
- return (
-
-
- {hasTarget && (
-
- )}
-
- );
- }
-}
-
-MenuTestComponent.propTypes = {
- mockBoundingClientRect: PropTypes.bool,
-};
-
-describe('Menu tests', () => {
- window.innerHeight = 180;
- const renderTest = props => {
- const {rerender, ...other} = render();
- rerender();
- return other;
- };
-
- test('should render', () => {
- const {getByTestId} = renderTest();
- const menu = getByTestId('select-menu');
- expect(menu).toMatchSnapshot();
- });
-
- test('should render with position reference to parent element', () => {
- const {getByTestId} = renderTest({mockBoundingClientRect: true});
- const menu = getByTestId('select-menu');
- expect(menu).toHaveStyleRule({top: '120px'});
- expect(menu).toMatchSnapshot();
- });
-
- test('should render with position adjust', () => {
- const {getByTestId} = renderTest({position: 'adjust'});
-
- const menu = getByTestId('select-menu');
-
- expect(menu).toMatchSnapshot();
- });
-
- test('should render with position right', () => {
- const {getByTestId} = renderTest({position: 'right'});
-
- const menu = getByTestId('select-menu');
-
- expect(menu).toMatchSnapshot();
- });
-
- test('should not render without target', () => {
- const notifyRefAssigned = testing.fn();
- const {queryByTestId} = render(
- ,
- );
-
- const menu = queryByTestId('select-menu');
-
- expect(menu).toBeNull();
- });
-
- test('should render with open direction upwards', () => {
- const {getByTestId} = renderTest({
- mockBoundingClientRect: true,
- menuHeight: 75,
- });
- const menu = getByTestId('select-menu');
- expect(menu).toMatchSnapshot();
- });
-
- test('should render with open direction downwards', () => {
- const {getByTestId} = renderTest({
- mockBoundingClientRect: true,
- menuHeight: 55,
- });
- const menu = getByTestId('select-menu');
- expect(menu).toMatchSnapshot();
- });
-});
diff --git a/src/web/components/form/__tests__/spinner.jsx b/src/web/components/form/__tests__/spinner.jsx
index a734b646df..6865a9dee5 100644
--- a/src/web/components/form/__tests__/spinner.jsx
+++ b/src/web/components/form/__tests__/spinner.jsx
@@ -19,208 +19,243 @@ import {describe, test, expect, testing} from '@gsa/testing';
import {KeyCode} from 'gmp/utils/event';
-import {render, fireEvent} from 'web/utils/testing';
+import {render, fireEvent, screen, userEvent} from 'web/utils/testing';
import Spinner from '../spinner';
+const getInput = element =>
+ element.querySelector('input.mantine-NumberInput-input');
+
+const getIncrementButton = element =>
+ element.querySelector('.mantine-NumberInput-controlUp');
+const getDecrementButton = element =>
+ element.querySelector('.mantine-NumberInput-controlDown');
+
+const clickIncrementButton = async element =>
+ await userEvent.click(getIncrementButton(element));
+
+const clickDecrementButton = async element =>
+ await userEvent.click(getDecrementButton(element));
+
describe('Spinner tests', () => {
test('should render', () => {
- const {element, getByTestId} = render();
+ render();
- const input = getByTestId('spinner-input');
- expect(input).toHaveAttribute('value', '1');
+ const element = screen.getByTestId('input');
- expect(element).toMatchSnapshot();
+ expect(element).toHaveAttribute('value', '1');
});
test('should call change handler', () => {
- const handler = testing.fn();
- const {getByTestId} = render();
+ const onChange = testing.fn();
+ render();
- const input = getByTestId('spinner-input');
- fireEvent.change(input, {target: {value: '2'}});
+ const element = screen.getByTestId('input');
- expect(handler).toHaveBeenCalledWith(2, undefined);
+ fireEvent.change(element, {target: {value: '2'}});
+
+ expect(onChange).toHaveBeenCalledWith(2, undefined);
+ expect(element).toHaveAttribute('value', '2');
});
- test('should call change handler with name', () => {
- const handler = testing.fn();
- const {getByTestId} = render(
- ,
- );
+ test('should call change handler for characters with empty string', () => {
+ const onChange = testing.fn();
+ render();
- const input = getByTestId('spinner-input');
- fireEvent.change(input, {target: {value: '2'}});
+ const element = screen.getByTestId('input');
- expect(handler).toHaveBeenCalledWith(2, 'foo');
+ fireEvent.change(element, {target: {value: 'ABC'}});
+
+ expect(onChange).toHaveBeenCalledWith('', undefined);
+ expect(element).toHaveAttribute('value', '');
});
- test('should increment value on button click', () => {
- const handler = testing.fn();
- const {getByTestId} = render();
+ test('should allow to clear input', () => {
+ const onChange = testing.fn();
+ render();
- const button = getByTestId('spinner-up');
- fireEvent.click(button);
+ const element = screen.getByTestId('input');
- expect(handler).toHaveBeenCalledWith(2, undefined);
+ fireEvent.change(element, {target: {value: ''}});
+
+ expect(onChange).toHaveBeenCalledWith('', undefined);
+ expect(element).toHaveAttribute('value', '');
});
- test('should decrement value on button click', () => {
- const handler = testing.fn();
- const {getByTestId} = render();
+ test('should call change handler with value and name', () => {
+ const onChange = testing.fn();
+ render(
+ ,
+ );
- const button = getByTestId('spinner-down');
- fireEvent.click(button);
+ const element = screen.getByTestId('input');
- expect(handler).toHaveBeenCalledWith(0, undefined);
+ fireEvent.change(element, {target: {value: '2'}});
+
+ expect(onChange).toHaveBeenCalledWith(2, 'foo');
+ expect(element).toHaveAttribute('value', '2');
});
- test('should increment value on wheel up', () => {
- const handler = testing.fn();
- const {getByTestId} = render();
+ test('should not call change handler if disabled', () => {
+ const onChange = testing.fn();
+ render(
+ ,
+ );
- const input = getByTestId('spinner-input');
- fireEvent.wheel(input, {deltaY: 2});
+ const element = screen.getByTestId('input');
- expect(handler).toHaveBeenCalledWith(2, undefined);
+ fireEvent.change(element, {target: {value: '2'}});
+
+ expect(onChange).not.toHaveBeenCalled();
});
- test('should decrement value on wheel down', () => {
- const handler = testing.fn();
- const {getByTestId} = render();
+ test('should update value', () => {
+ const onChange = testing.fn();
+ const {rerender} = render(
+ ,
+ );
- const input = getByTestId('spinner-input');
- fireEvent.wheel(input, {deltaY: -2});
+ const element = screen.getByTestId('input');
- expect(handler).toHaveBeenCalledWith(0, undefined);
+ fireEvent.change(element, {target: {value: '2'}});
+
+ expect(onChange).toHaveBeenCalledWith(2, undefined);
+ expect(element).toHaveAttribute('value', '2');
+
+ rerender();
+
+ expect(element).toHaveAttribute('value', '2');
+
+ rerender();
+
+ expect(element).toHaveAttribute('value', '3');
});
- test('should increment on key up', () => {
- const handler = testing.fn();
- const {getByTestId} = render();
+ test('should use max if value > max', () => {
+ const onChange = testing.fn();
+ render(
+ ,
+ );
- const input = getByTestId('spinner-input');
- fireEvent.keyDown(input, {key: 'ArrowUp', keyCode: KeyCode.UP});
+ const element = screen.getByTestId('input');
- expect(handler).toHaveBeenCalledWith(2, undefined);
+ fireEvent.change(element, {target: {value: '3'}});
+
+ expect(onChange).toHaveBeenCalledWith(2, undefined);
+ expect(element).toHaveAttribute('value', '2');
+ });
+
+ test('should use min if value < min', () => {
+ const onChange = testing.fn();
+ render(
+ ,
+ );
+
+ const element = screen.getByTestId('input');
+
+ fireEvent.change(element, {target: {value: '0'}});
+
+ expect(onChange).toHaveBeenCalledWith(1, undefined);
+ expect(element).toHaveAttribute('value', '1');
});
- test('should increment on key page up', () => {
+ test('should increment value on button click', async () => {
const handler = testing.fn();
- const {getByTestId} = render();
+ const {element} = render();
- const input = getByTestId('spinner-input');
- fireEvent.keyDown(input, {key: 'PageUp', keyCode: KeyCode.PAGE_UP});
+ await clickIncrementButton(element);
expect(handler).toHaveBeenCalledWith(2, undefined);
});
- test('should decrement on key down', () => {
+ test('should decrement value on button click', async () => {
const handler = testing.fn();
- const {getByTestId} = render();
+ const {element} = render();
- const input = getByTestId('spinner-input');
- fireEvent.keyDown(input, {key: 'ArrowDown', keyCode: KeyCode.DOWN});
+ await clickDecrementButton(element);
expect(handler).toHaveBeenCalledWith(0, undefined);
});
- test('should decrement on key page down', () => {
+ test('should increment on key up', () => {
const handler = testing.fn();
- const {getByTestId} = render();
+ const {element} = render();
- const input = getByTestId('spinner-input');
- fireEvent.keyDown(input, {key: 'PageDown', keyCode: KeyCode.PAGE_DOWN});
+ const input = getInput(element);
- expect(handler).toHaveBeenCalledWith(0, undefined);
+ fireEvent.keyDown(input, {key: 'ArrowUp', keyCode: KeyCode.UP});
+
+ expect(handler).toHaveBeenCalledWith(2, undefined);
});
- test('should not call event handler if disabled', () => {
+ test('should decrement on key down', () => {
const handler = testing.fn();
- const {getByTestId} = render(
- ,
- );
+ const {element} = render();
- const input = getByTestId('spinner-input');
- fireEvent.wheel(input, {deltaY: 2});
- fireEvent.wheel(input, {deltaY: -2});
+ const input = getInput(element);
- fireEvent.keyDown(input, {key: 'PageDown', keyCode: KeyCode.PAGE_DOWN});
- fireEvent.keyDown(input, {key: 'PageUp', keyCode: KeyCode.PAGE_UP});
fireEvent.keyDown(input, {key: 'ArrowDown', keyCode: KeyCode.DOWN});
- fireEvent.keyDown(input, {key: 'ArrowUp', keyCode: KeyCode.UP});
- const dbutton = getByTestId('spinner-down');
- fireEvent.click(dbutton);
- const ubutton = getByTestId('spinner-up');
- fireEvent.click(ubutton);
-
- expect(handler).not.toHaveBeenCalled();
+ expect(handler).toHaveBeenCalledWith(0, undefined);
});
- test('should debounce notification', () => {
- testing.useFakeTimers();
-
+ test('should not call event handler if disabled', () => {
const handler = testing.fn();
- const {getByTestId} = render(
- ,
+ const {element} = render(
+ ,
);
- const ubutton = getByTestId('spinner-up');
- fireEvent.click(ubutton);
- fireEvent.click(ubutton);
- fireEvent.click(ubutton);
+ const input = getInput(element);
+ fireEvent.keyDown(input, {key: 'ArrowDown', keyCode: KeyCode.DOWN});
+ fireEvent.keyDown(input, {key: 'ArrowUp', keyCode: KeyCode.UP});
- testing.runAllTimers();
+ expect(getIncrementButton(element)).toBeNull();
+ expect(getDecrementButton(element)).toBeNull();
- expect(handler).toHaveBeenCalledTimes(1);
- expect(handler).toHaveBeenCalledWith(2, undefined);
+ expect(handler).not.toHaveBeenCalled();
});
- test('should not increment value beyond max', () => {
+ test('should not increment value beyond max', async () => {
const handler = testing.fn();
- const {getByTestId} = render(
- ,
- );
+ const {element} = render();
- const button = getByTestId('spinner-up');
- fireEvent.click(button);
+ await clickIncrementButton(element);
expect(handler).toHaveBeenCalledWith(1, undefined);
});
- test('should not decrement value below min', () => {
+ test('should not decrement value below min', async () => {
const handler = testing.fn();
- const {getByTestId} = render(
- ,
- );
+ const {element} = render();
- const button = getByTestId('spinner-down');
- fireEvent.click(button);
+ await clickDecrementButton(element);
expect(handler).toHaveBeenCalledWith(1, undefined);
});
- test('should increment float value', () => {
+ test('should increment float value', async () => {
const handler = testing.fn();
- const {getByTestId} = render(
- ,
+ const {element} = render(
+ ,
);
- const button = getByTestId('spinner-up');
- fireEvent.click(button);
+ await clickIncrementButton(element);
- expect(handler).toHaveBeenCalledWith(1.1, undefined);
+ expect(handler).toHaveBeenCalledWith(1.2, undefined);
});
- test('should increment value with step', () => {
+ test('should increment value with step', async () => {
const handler = testing.fn();
- const {getByTestId} = render(
+ const {element} = render(
,
);
- const button = getByTestId('spinner-up');
- fireEvent.click(button);
+ await clickIncrementButton(element);
expect(handler).toHaveBeenCalledWith(1.5, undefined);
});
diff --git a/src/web/components/form/__tests__/textarea.jsx b/src/web/components/form/__tests__/textarea.jsx
index 700d0606f1..cf2bb60516 100644
--- a/src/web/components/form/__tests__/textarea.jsx
+++ b/src/web/components/form/__tests__/textarea.jsx
@@ -17,43 +17,29 @@
*/
import {describe, test, expect, testing} from '@gsa/testing';
-import Theme from 'web/utils/theme';
-import {render, fireEvent} from 'web/utils/testing';
+import {render, fireEvent, screen} from 'web/utils/testing';
-import {DISABLED_OPACITY} from '../field';
import TextArea from '../textarea';
describe('TextArea tests', () => {
test('should render', () => {
const {element} = render();
- expect(element).not.toHaveStyleRule('cursor');
- expect(element).not.toHaveStyleRule('opacity');
- expect(element).toHaveStyleRule('background-color', Theme.white);
-
- expect(element).toMatchSnapshot();
+ expect(element).toBeInTheDocument();
});
- test('should render in disabled state', () => {
- const {element} = render();
-
- expect(element).toHaveStyleRule('cursor', 'not-allowed');
- expect(element).toHaveStyleRule('opacity', `${DISABLED_OPACITY}`);
- expect(element).toHaveStyleRule('background-color', Theme.dialogGray);
-
- expect(element).toMatchSnapshot();
- });
+ test('should render error', () => {
+ render();
- test('should render invalid state', () => {
- const {element, baseElement} = render();
- expect(baseElement).toHaveTextContent('×');
- expect(element).toHaveStyleRule('background-color: #f2dede');
+ expect(screen.getByText('Some Error')).toBeVisible();
});
test('should call change handler with value', () => {
const onChange = testing.fn();
- const {element} = render();
+ render();
+
+ const element = screen.getByTestId('input');
fireEvent.change(element, {target: {value: 'bar'}});
@@ -63,10 +49,17 @@ describe('TextArea tests', () => {
test('should call change handler with value and name', () => {
const onChange = testing.fn();
- const {element} = render(
- ,
+ render(
+ ,
);
+ const element = screen.getByTestId('input');
+
fireEvent.change(element, {target: {value: 'bar'}});
expect(onChange).toHaveBeenCalledWith('bar', 'foo');
@@ -75,14 +68,19 @@ describe('TextArea tests', () => {
test('should not call change handler if disabled', () => {
const onChange = testing.fn();
- const {element} = render(
- ,
+ render(
+ ,
);
+ const element = screen.getByTestId('input');
+
fireEvent.change(element, {target: {value: 'bar'}});
expect(onChange).not.toHaveBeenCalled();
});
});
-
-// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/__tests__/textfield.jsx b/src/web/components/form/__tests__/textfield.jsx
index 352823d71f..ed8e2c934d 100644
--- a/src/web/components/form/__tests__/textfield.jsx
+++ b/src/web/components/form/__tests__/textfield.jsx
@@ -17,31 +17,29 @@
*/
import {describe, test, expect, testing} from '@gsa/testing';
-import {render, fireEvent} from 'web/utils/testing';
+import {render, fireEvent, screen} from 'web/utils/testing';
import TextField from '../textfield';
describe('TextField tests', () => {
test('should render', () => {
const {element} = render();
- expect(element).toMatchSnapshot();
- });
- test('should render in disabled state', () => {
- const {element} = render();
- expect(element).toMatchSnapshot();
+ expect(element).toBeInTheDocument();
});
test('should render invalid state', () => {
- const {element, baseElement} = render();
- expect(baseElement).toHaveTextContent('×');
- expect(element).toHaveStyleRule('background-color: #f2dede');
+ render();
+
+ expect(screen.getByText('Some Error')).toBeVisible();
});
test('should call change handler with value', () => {
const onChange = testing.fn();
- const {element} = render();
+ render();
+
+ const element = screen.getByTestId('input');
fireEvent.change(element, {target: {value: 'bar'}});
@@ -51,10 +49,17 @@ describe('TextField tests', () => {
test('should call change handler with value and name', () => {
const onChange = testing.fn();
- const {element} = render(
- ,
+ render(
+ ,
);
+ const element = screen.getByTestId('input');
+
fireEvent.change(element, {target: {value: 'bar'}});
expect(onChange).toHaveBeenCalledWith('bar', 'foo');
@@ -63,14 +68,19 @@ describe('TextField tests', () => {
test('should not call change handler if disabled', () => {
const onChange = testing.fn();
- const {element} = render(
- ,
+ render(
+ ,
);
+ const element = screen.getByTestId('input');
+
fireEvent.change(element, {target: {value: 'bar'}});
expect(onChange).not.toHaveBeenCalled();
});
});
-
-// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/__tests__/timezoneselect.jsx b/src/web/components/form/__tests__/timezoneselect.jsx
index 137672e0ac..0c06615b66 100644
--- a/src/web/components/form/__tests__/timezoneselect.jsx
+++ b/src/web/components/form/__tests__/timezoneselect.jsx
@@ -17,70 +17,58 @@
*/
import {describe, test, expect, testing} from '@gsa/testing';
-import {setLocale} from 'gmp/locale/lang';
import timezones from 'gmp/timezones';
-import {render, fireEvent} from 'web/utils/testing';
+import {render, userEvent} from 'web/utils/testing';
import TimezoneSelect from '../timezoneselect';
-setLocale('en');
+import {openSelectElement, getItemElements, getSelectElement} from './select';
describe('TimezoneSelect tests', () => {
test('should render', () => {
- const {element, getByTestId} = render();
+ const {element} = render();
- const selected = getByTestId('select-selected-value');
- expect(selected).toHaveTextContent('Coordinated Universal Time/UTC');
-
- expect(element).toMatchSnapshot();
+ expect(element).toBeInTheDocument();
});
- test('should render all timezones in selection', () => {
- const {getByTestId, getAllByTestId} = render();
+ test('should render all timezones in selection', async () => {
+ render();
- const button = getByTestId('select-open-button');
- fireEvent.click(button);
+ await openSelectElement();
- const items = getAllByTestId('select-item');
- expect(items.length).toEqual(timezones.length + 1);
+ expect(getItemElements().length).toEqual(timezones.length + 1);
});
- test('should call onChange handler', () => {
+ test('should call onChange handler', async () => {
const handler = testing.fn();
- const {getByTestId, getAllByTestId} = render(
- ,
- );
+ render();
- const button = getByTestId('select-open-button');
- fireEvent.click(button);
+ await openSelectElement();
- const items = getAllByTestId('select-item');
- fireEvent.click(items[1]);
+ const items = getItemElements();
+ await userEvent.click(items[1]);
expect(handler).toHaveBeenCalledWith(timezones[0].name, undefined);
});
- test('should call onChange handler with name', () => {
+ test('should call onChange handler with name', async () => {
const handler = testing.fn();
- const {getByTestId, getAllByTestId} = render(
- ,
- );
+ render();
- const button = getByTestId('select-open-button');
- fireEvent.click(button);
+ await openSelectElement();
- const items = getAllByTestId('select-item');
- fireEvent.click(items[1]);
+ const items = getItemElements();
+ await userEvent.click(items[1]);
expect(handler).toHaveBeenCalledWith(timezones[0].name, 'foo');
});
test('should render selected value', () => {
const timezone = timezones[1]; // eslint-disable-line prefer-destructuring
- const {getByTestId} = render();
+ render();
- const selected = getByTestId('select-selected-value');
- expect(selected).toHaveTextContent(timezone.name);
+ const input = getSelectElement();
+ expect(input).toHaveValue(timezone.name);
});
});
diff --git a/src/web/components/form/__tests__/useFormValidation.jsx b/src/web/components/form/__tests__/useFormValidation.jsx
index 0c3463bf13..33e8c40687 100644
--- a/src/web/components/form/__tests__/useFormValidation.jsx
+++ b/src/web/components/form/__tests__/useFormValidation.jsx
@@ -23,7 +23,7 @@ import {describe, test, expect, testing} from '@gsa/testing';
import React, {useState} from 'react';
-import {rendererWith, fireEvent, screen} from 'web/utils/testing';
+import {render, fireEvent, screen} from 'web/utils/testing';
import TextField from '../textfield';
import Button from '../button';
@@ -59,25 +59,23 @@ const UseFormValidationTestComponent = ({onSave}) => {
},
);
return (
-
+ <>
{values.foo}
{hasError && {error}}
+ >
);
};
describe('useFormValidation tests', () => {
test('should validate form value successfully', async () => {
- const {render} = rendererWith();
const handleSave = testing.fn();
render();
@@ -91,7 +89,6 @@ describe('useFormValidation tests', () => {
});
test('should show error if validation fails', async () => {
- const {render} = rendererWith();
const handleSave = testing.fn();
render();
diff --git a/src/web/components/form/__tests__/useValueChange.jsx b/src/web/components/form/__tests__/useValueChange.jsx
index c559686db2..e14e381c19 100644
--- a/src/web/components/form/__tests__/useValueChange.jsx
+++ b/src/web/components/form/__tests__/useValueChange.jsx
@@ -2,11 +2,13 @@
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
+import {describe, test, expect, testing} from '@gsa/testing';
import {render, screen, fireEvent} from 'web/utils/testing';
import useValueChange from '../useValueChange';
+// eslint-disable-next-line react/prop-types
const TestComponent = ({value, onChange, name, disabled}) => {
const handleChange = useValueChange({onChange, name, disabled});
@@ -17,7 +19,7 @@ const TestComponent = ({value, onChange, name, disabled}) => {
describe('onValueChange Tests', () => {
test('should call onChange when value changes', () => {
- const onChange = jest.fn();
+ const onChange = testing.fn();
render();
@@ -30,9 +32,16 @@ describe('onValueChange Tests', () => {
});
test('should not call onChange when disabled', () => {
- const onChange = jest.fn();
-
- render();
+ const onChange = testing.fn();
+
+ render(
+ ,
+ );
const input = screen.getByRole('textbox');
diff --git a/src/web/components/form/__tests__/yesnoradio.jsx b/src/web/components/form/__tests__/yesnoradio.jsx
index 30d66a5517..61a7bfa60f 100644
--- a/src/web/components/form/__tests__/yesnoradio.jsx
+++ b/src/web/components/form/__tests__/yesnoradio.jsx
@@ -17,28 +17,31 @@
*/
import {describe, test, expect, testing} from '@gsa/testing';
+import {NO_VALUE, YES_VALUE} from 'gmp/parser';
+
import {render, fireEvent} from 'web/utils/testing';
import YesNoRadio from '../yesnoradio';
-import {YES_VALUE, NO_VALUE} from 'gmp/parser';
+
+const getLabels = element => element.querySelectorAll('label');
+const getRadioInputs = element =>
+ element.querySelectorAll('.mantine-Radio-radio');
describe('YesNoRadio tests', () => {
test('should render', () => {
- const {element, getAllByTestId} = render();
+ const {element} = render();
- expect(element).toMatchSnapshot();
+ const labels = getLabels(element);
- const titleElements = getAllByTestId('radio-title');
- expect(titleElements.length).toEqual(2);
- expect(titleElements[0]).toHaveTextContent('Yes');
- expect(titleElements[1]).toHaveTextContent('No');
+ expect(labels[0]).toHaveTextContent('Yes');
+ expect(labels[1]).toHaveTextContent('No');
});
test('should call change handler', () => {
const onChange = testing.fn();
- const {getAllByTestId} = render();
+ const {element} = render();
- const inputs = getAllByTestId('radio-input');
+ const inputs = getRadioInputs(element);
expect(inputs.length).toEqual(2);
fireEvent.click(inputs[0]);
@@ -52,11 +55,9 @@ describe('YesNoRadio tests', () => {
test('should call change handler with name', () => {
const onChange = testing.fn();
- const {getAllByTestId} = render(
- ,
- );
+ const {element} = render();
- const inputs = getAllByTestId('radio-input');
+ const inputs = getRadioInputs(element);
expect(inputs.length).toEqual(2);
fireEvent.click(inputs[0]);
@@ -66,7 +67,7 @@ describe('YesNoRadio tests', () => {
test('should allow to set values for yes and no state', () => {
const onChange = testing.fn();
- const {getAllByTestId} = render(
+ const {element} = render(
v}
name="ipsum"
@@ -76,7 +77,7 @@ describe('YesNoRadio tests', () => {
/>,
);
- const inputs = getAllByTestId('radio-input');
+ const inputs = getRadioInputs(element);
expect(inputs.length).toEqual(2);
fireEvent.click(inputs[0]);
@@ -90,11 +91,11 @@ describe('YesNoRadio tests', () => {
test('should call change handler only if checked state changes', () => {
const onChange = testing.fn();
- const {getAllByTestId} = render(
+ const {element} = render(
,
);
- const inputs = getAllByTestId('radio-input');
+ const inputs = getRadioInputs(element);
expect(inputs.length).toEqual(2);
fireEvent.click(inputs[0]);
@@ -108,11 +109,11 @@ describe('YesNoRadio tests', () => {
test('should not call change handler if disabled', () => {
const onChange = testing.fn();
- const {getAllByTestId} = render(
+ const {element} = render(
,
);
- const inputs = getAllByTestId('radio-input');
+ const inputs = getRadioInputs(element);
expect(inputs.length).toEqual(2);
fireEvent.click(inputs[0]);
@@ -124,5 +125,3 @@ describe('YesNoRadio tests', () => {
expect(onChange).not.toHaveBeenCalled();
});
});
-
-// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/button.jsx b/src/web/components/form/button.jsx
index b52997797d..453f0cdf2e 100644
--- a/src/web/components/form/button.jsx
+++ b/src/web/components/form/button.jsx
@@ -18,73 +18,53 @@
import React from 'react';
-import styled from 'styled-components';
+import {Button as OpenSightButton} from '@greenbone/opensight-ui-components';
-import compose from 'web/utils/compose';
import PropTypes from 'web/utils/proptypes';
-import Theme from 'web/utils/theme';
-import withLayout from 'web/components/layout/withLayout';
+import useValueChange from './useValueChange';
-import withClickHandler from './withClickHandler';
-
-const StyledButton = styled.button`
- display: inline-block;
- padding: 0 15px;
- color: ${Theme.darkGray};
- text-align: center;
- vertical-align: middle;
- font-size: 11px;
- font-weight: bold;
- line-height: 30px;
- text-decoration: none;
- white-space: nowrap;
- background-color: ${Theme.white};
- border-radius: 2px;
- border: 1px solid ${Theme.inputBorderGray};
- cursor: pointer;
- overflow: visible;
- z-index: ${Theme.Layers.higher}; /* Don't interfere with dialog resizer */
- &:focus,
- &:hover {
- border: 1px solid ${Theme.darkGray};
- }
- &:hover {
- text-decoration: none;
- background: ${Theme.green};
- font-weight: bold;
- color: ${Theme.white};
- }
- &[disabled] {
- cursor: not-allowed;
- opacity: 0.65;
- box-shadow: none;
- }
- & img {
- height: 32px;
- width: 32px;
- margin-top: 5px 10px 5px -10px;
- vertical-align: middle;
- }
- &:link {
- text-decoration: none;
- color: ${Theme.darkGray};
- }
-`;
-
-const Button = ({title, children = title, ...other}) => (
-
- {children}
-
-);
+const Button = ({
+ title,
+ children = title,
+ convert,
+ disabled,
+ isLoading = false,
+ name,
+ value,
+ onClick,
+ ...other
+}) => {
+ const handleChange = useValueChange({
+ disabled,
+ onChange: onClick,
+ convert,
+ name,
+ });
+ return (
+
+ {children}
+
+ );
+};
Button.propTypes = {
+ convert: PropTypes.func,
+ disabled: PropTypes.bool,
+ isLoading: PropTypes.bool,
+ name: PropTypes.string,
title: PropTypes.string,
+ value: PropTypes.any,
+ onClick: PropTypes.func,
};
-export default compose(
- withLayout({align: ['center', 'center']}),
- withClickHandler(),
-)(Button);
+export default Button;
// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/checkbox.jsx b/src/web/components/form/checkbox.jsx
index 609ae0dfb5..d1d863eb59 100644
--- a/src/web/components/form/checkbox.jsx
+++ b/src/web/components/form/checkbox.jsx
@@ -15,19 +15,15 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-import React from 'react';
+import React, {useCallback} from 'react';
+
+import {Checkbox as OpenSightCheckbox} from '@greenbone/opensight-ui-components';
import {isDefined} from 'gmp/utils/identity';
import PropTypes from 'web/utils/proptypes';
-import {StyledElement, StyledInput, StyledTitle} from './radio';
-
-import Divider from 'web/components/layout/divider';
-import withLayout from 'web/components/layout/withLayout';
-
-const convertChecked = (value, props) => {
- const {checkedValue, unCheckedValue} = props;
+const convertChecked = (value, checkedValue, unCheckedValue) => {
let val;
if (value && isDefined(checkedValue)) {
val = checkedValue;
@@ -41,54 +37,41 @@ const convertChecked = (value, props) => {
const valueFunc = event => event.target.checked;
-const CheckboxComponent = ({
+const Checkbox = ({
title,
- children,
+ name,
disabled,
checkedValue,
- toolTipTitle,
unCheckedValue,
- ...other
+ toolTipTitle,
+ onChange,
+ ...props
}) => {
- const notifyChange = val => {
- const {name, onChange} = other;
-
- if (isDefined(onChange) && !disabled) {
- onChange(val, name);
- }
- };
-
- const getCheckboxValues = () => {
- return {checkedValue, unCheckedValue};
- };
-
- const handleChange = event => {
- const val = convertChecked(valueFunc(event), getCheckboxValues());
-
- notifyChange(val);
- };
-
+ const handleChange = useCallback(
+ event => {
+ const newValue = convertChecked(
+ valueFunc(event),
+ checkedValue,
+ unCheckedValue,
+ );
+ if (!disabled && onChange) {
+ onChange(newValue, name);
+ }
+ },
+ [onChange, disabled, name, checkedValue, unCheckedValue],
+ );
return (
-
-
-
- {isDefined(title) && (
-
- {title}
-
- )}
- {children}
-
-
+
);
};
-CheckboxComponent.propTypes = {
+Checkbox.propTypes = {
checkedValue: PropTypes.any,
disabled: PropTypes.bool,
name: PropTypes.string,
@@ -98,6 +81,6 @@ CheckboxComponent.propTypes = {
onChange: PropTypes.func,
};
-export default withLayout()(CheckboxComponent);
+export default Checkbox;
// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/field.jsx b/src/web/components/form/field.jsx
deleted file mode 100644
index 777c5fb9bf..0000000000
--- a/src/web/components/form/field.jsx
+++ /dev/null
@@ -1,99 +0,0 @@
-/* Copyright (C) 2016-2022 Greenbone AG
- *
- * SPDX-License-Identifier: AGPL-3.0-or-later
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-import React, {useCallback} from 'react';
-import {isDefined} from 'gmp/utils/identity';
-import PropTypes from 'web/utils/proptypes';
-
-import styled from 'styled-components';
-
-import {styledExcludeProps} from 'web/utils/styledConfig';
-import Theme from 'web/utils/theme';
-
-import withLayout from 'web/components/layout/withLayout';
-
-export const DISABLED_OPACITY = 0.65;
-
-const StyledInput = styledExcludeProps(styled.input, ['convert', 'hasError'])`
- /* use font and line settings from parents not from browser default */
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
- display: block;
- height: 22px;
- color: ${Theme.darkGray};
- background-color: ${Theme.white};
- background-image: none;
- border: 1px solid ${Theme.inputBorderGray};
- border-radius: 2px;
- padding: 1px 8px;
- /* "hack" to overshadow default color in Chrome's autofilled input fields */
- &:-webkit-autofill {
- box-shadow: 0 0 0 1000px white inset;
- }
- cursor: ${props => (props.disabled ? 'not-allowed' : undefined)};
- background-color: ${props => {
- if (props.hasError) {
- return Theme.lightRed;
- } else if (props.disabled) {
- return Theme.dialogGray;
- }
- }};
- opacity: ${props => (props.disabled ? DISABLED_OPACITY : undefined)};
-`;
-
-const Field = ({name, onChange, disabled = false, value, ...other}) => {
- const notifyChange = useCallback(
- val => {
- if (isDefined(onChange) && !disabled) {
- onChange(val, name);
- }
- },
- [disabled, name, onChange],
- );
-
- const handleChange = useCallback(
- event => {
- const val = event.target.value;
-
- notifyChange(val);
- },
- [notifyChange],
- );
-
- return (
-
- );
-};
-
-Field.propTypes = {
- disabled: PropTypes.bool,
- name: PropTypes.string,
- value: PropTypes.any,
- onChange: PropTypes.func,
-};
-
-export default withLayout()(Field);
-
-// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/filefield.jsx b/src/web/components/form/filefield.jsx
index d5a1fcba2f..6f1896d937 100644
--- a/src/web/components/form/filefield.jsx
+++ b/src/web/components/form/filefield.jsx
@@ -16,35 +16,44 @@
* along with this program. If not, see .
*/
-import React from 'react';
+import React, {useCallback} from 'react';
-import {isDefined} from 'gmp/utils/identity';
+import {FileInput} from '@greenbone/opensight-ui-components';
-import withLayout from 'web/components/layout/withLayout';
+import {isDefined} from 'gmp/utils/identity';
import PropTypes from 'web/utils/proptypes';
-const FileFieldComponent = props => {
- const handleChange = event => {
- const {onChange, disabled, name} = props;
-
- event.preventDefault();
-
- if (!disabled && isDefined(onChange)) {
- onChange(event.target.files[0], name);
- }
- };
-
- const {onChange, ...args} = props;
- return ;
+const FileField = ({disabled, grow, name, title, onChange, ...props}) => {
+ const handleChange = useCallback(
+ file => {
+ if (!disabled && isDefined(onChange)) {
+ onChange(file, name);
+ }
+ },
+ [onChange, disabled, name],
+ );
+
+ return (
+
+ );
};
-FileFieldComponent.propTypes = {
+FileField.propTypes = {
disabled: PropTypes.bool,
+ grow: PropTypes.numberOrNumberString,
name: PropTypes.string,
+ title: PropTypes.string,
onChange: PropTypes.func,
};
-export default withLayout()(FileFieldComponent);
+export default FileField;
// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/formgroup.jsx b/src/web/components/form/formgroup.jsx
index d557d0e9d8..a33830b284 100644
--- a/src/web/components/form/formgroup.jsx
+++ b/src/web/components/form/formgroup.jsx
@@ -17,120 +17,41 @@
*/
import React from 'react';
-import styled from 'styled-components';
+import {LabelWithIcon as Label} from '@greenbone/opensight-ui-components';
import {isDefined} from 'gmp/utils/identity';
-import {parseInt} from 'gmp/parser';
+import Row from 'web/components/layout/row';
+import Column from 'web/components/layout/column';
-import Layout from 'web/components/layout/layout';
import PropTypes from 'web/utils/proptypes';
-import {styledExcludeProps} from 'web/utils/styledConfig';
-
-const COLUMNS = [
- '0',
- '8.33333333%',
- '16.66666667%',
- '25%',
- '33.33333333%',
- '41.66666667%',
- '50%',
- '58.33333333%',
- '66.66666667%',
- '75%',
- '83.33333333%',
- '91.66666667%',
- '100%',
-];
-
-const FormGroupLayout = styled.div`
- display: flex;
- align-items: center;
- justify-content: start;
- padding-bottom: 10px;
-`;
-
-const Title = styledExcludeProps(styled.label, ['titleSize', 'titleOffset'])`
- display: inline-block;
- max-width: 100%;
- font-weight: bold;
- text-align: right;
- padding-left: 10px;
- padding-right: 10px;
- width: ${props => COLUMNS[props.titleSize]};
- margin-left: ${props => COLUMNS[props.titleOffset]};
-`;
-
-const FormGroupContent = styledExcludeProps(styled(Layout), [
- 'size',
- 'offset',
- 'paddingLeft',
-])`
- ${props => {
- const ret = {};
- if (isDefined(props.size)) {
- ret.width = COLUMNS[parseInt(props.size)];
- ret.paddingLeft = isDefined(props.paddingLeft)
- ? props.paddingLeft
- : '10px';
- ret.paddingRight = '10px';
- }
- if (isDefined(props.offset)) {
- ret.marginLeft = COLUMNS[parseInt(props.offset)];
- }
- return ret;
- }}
-`;
const FormGroup = ({
children,
- className,
- offset,
- size,
title,
- titleOffset = 0,
- titleSize = 2,
- paddingLeft,
- ...other
+ gap = 'md',
+ direction = 'column',
+ 'data-testid': dataTestId,
}) => {
- titleOffset = parseInt(titleOffset);
- titleSize = parseInt(titleSize);
-
- if (title && !isDefined(size)) {
- size = 12 - titleSize - titleOffset;
- }
+ const Layout = direction === 'column' ? Column : Row;
return (
-
- {isDefined(title) && (
-
- {title}
-
- )}
-
- {children}
-
-
+
+ {isDefined(title) && }
+ {children}
+
);
};
FormGroup.propTypes = {
- className: PropTypes.string,
- offset: PropTypes.numberOrNumberString,
- paddingLeft: PropTypes.numberOrNumberString,
- size: PropTypes.numberOrNumberString,
+ 'data-testid': PropTypes.string,
+ direction: PropTypes.oneOf(['row', 'column']),
+ gap: PropTypes.string,
title: PropTypes.string,
- titleOffset: PropTypes.numberOrNumberString,
- titleSize: PropTypes.numberOrNumberString,
};
export default FormGroup;
diff --git a/src/web/components/form/loadingbutton.jsx b/src/web/components/form/loadingbutton.jsx
deleted file mode 100644
index 84241d2b58..0000000000
--- a/src/web/components/form/loadingbutton.jsx
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Copyright (C) 2019-2022 Greenbone AG
- *
- * SPDX-License-Identifier: AGPL-3.0-or-later
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-import styled from 'styled-components';
-
-import Button from 'web/components/form/button';
-
-import Theme from 'web/utils/theme';
-import {styledExcludeProps} from 'web/utils/styledConfig';
-
-const LoadingButton = styledExcludeProps(styled(Button), ['isLoading'])`
- color: ${props => (props.isLoading ? 'rgba(0, 0, 0, 0.0)' : Theme.darkGray)};
- background: ${props =>
- props.isLoading
- ? Theme.lightGreen + ' url(/img/loading.gif) center center no-repeat'
- : Theme.white};
-
- /* when hovering these settings have to be overwritten explicitly */
- :hover {
- color: ${props => (props.isLoading ? 'rgba(0, 0, 0, 0.0)' : Theme.white)};
- background: ${props =>
- props.isLoading
- ? Theme.green + ' url(/img/loading.gif) center center no-repeat'
- : Theme.green};
- }
-`;
-
-export default LoadingButton;
diff --git a/src/web/components/form/multiselect.jsx b/src/web/components/form/multiselect.jsx
index ed9c076212..99a22ab8bf 100644
--- a/src/web/components/form/multiselect.jsx
+++ b/src/web/components/form/multiselect.jsx
@@ -16,301 +16,92 @@
* along with this program. If not, see .
*/
-import React from 'react';
+import React, {useCallback} from 'react';
-import styled from 'styled-components';
-
-import Downshift from 'downshift';
-
-import _ from 'gmp/locale';
+import {
+ MultiSelect as MantineMultiSelect,
+ TextInput,
+ Loader,
+} from '@mantine/core';
import {isDefined} from 'gmp/utils/identity';
-import ArrowIcon from 'web/components/icon/arrowicon';
-
-import Layout from 'web/components/layout/layout';
-
import PropTypes from 'web/utils/proptypes';
-import Theme from 'web/utils/theme';
-
-import {
- Box,
- caseInsensitiveFilter,
- Input,
- Item,
- ItemContainer,
- Menu,
- SelectContainer,
- SelectedValue,
-} from './selectelements';
-
-import {Marker} from './useFormValidation';
-
-const DEFAULT_WIDTH = '250px';
-
-const Div = styled.div`
- display: flex;
-`;
-
-export const MultiSelectedValue = styled(SelectedValue)`
- display: inline;
- border: 1px solid ${Theme.inputBorderGray};
- border-radius: 2px;
- padding: 0 3px;
- margin-right: 4px;
- margin-top: 1px;
- margin-bottom: 0px;
- background-color: ${Theme.lightGray};
- width: 80px; /* acts similar to minWidth? */
-`;
-
-const DeleteButton = styled.div`
- display: inline;
- color: ${Theme.mediumGray};
- margin-right: 2px;
- &:hover {
- color: ${Theme.black};
- }
-`;
-
-const Label = styled.span`
- text-overflow: ellipsis;
- overflow: hidden;
-`;
-
-class MultiSelect extends React.Component {
- constructor(...args) {
- super(...args);
-
- this.state = {
- search: '',
- isMenuRefAssigned: false,
- };
-
- this.input = React.createRef();
- this.box = React.createRef();
- this.menu = React.createRef();
-
- this.handleRemoveItem = this.handleRemoveItem.bind(this);
- this.handleSearch = this.handleSearch.bind(this);
- this.handleSelect = this.handleSelect.bind(this);
- this.renderItem = this.renderItem.bind(this);
- this.notifyRefAssigned = this.notifyRefAssigned.bind(this);
- }
-
- notifyRefAssigned() {
- this.setState({isMenuRefAssigned: true});
- }
-
- notifyChange(value) {
- const {name, onChange} = this.props;
-
- if (isDefined(onChange)) {
- onChange(value, name);
- }
- }
-
- handleSearch(event) {
- const {value} = event.target;
- event.preventDefault(); // prevent input by downshift
-
- this.setState({search: value});
- }
-
- handleSelect(selectedItem) {
- const {value} = this.props;
-
- let newSelectedItems = [];
-
- if (isDefined(value)) {
- if (value.includes(selectedItem)) {
- this.handleRemoveItem(selectedItem);
- return;
+import useTranslation from 'web/hooks/useTranslation';
+
+const MultiSelect = ({
+ disabled,
+ dropdownPosition,
+ errorContent,
+ grow,
+ items = [],
+ isLoading,
+ label,
+ name,
+ placeholder,
+ searchable = true,
+ title,
+ value,
+ onChange,
+ ...props
+}) => {
+ const [_] = useTranslation();
+ const handleChange = useCallback(
+ newValue => {
+ if (isDefined(onChange)) {
+ onChange(newValue, name);
}
-
- newSelectedItems = [...value, selectedItem];
- } else {
- newSelectedItems = [selectedItem];
- }
-
- this.setState({
- // reset search term
- search: '',
- });
-
- this.notifyChange(newSelectedItems);
- }
-
- handleRemoveItem(item) {
- const copy = [...this.props.value];
- const index = copy.findIndex(elem => elem === item);
-
- copy.splice(index, 1);
-
- this.notifyChange(copy);
- }
-
- renderItem(value, items) {
- const {disabled} = this.props;
- const item = items.find(i => i.value === value);
- const itemLabel = isDefined(item) ? item.label : value;
-
- return (
-
-
- this.handleRemoveItem(value)}
- >
- × {/* Javascript unicode: \u00D7 */}
-
-
-
-
- );
- }
-
- render() {
- let {disabled = false} = this.props;
- const {
- className,
- hasError = false,
- errorContent,
- items,
- menuPosition = 'adjust',
- width = DEFAULT_WIDTH,
- grow,
- isLoading = false,
- title,
- value = [],
- } = this.props;
-
- const {search} = this.state;
-
- disabled = disabled || !isDefined(items) || items.length === 0 || isLoading;
-
- const displayedItems = isDefined(items)
- ? items.filter(caseInsensitiveFilter(search))
- : [];
-
+ },
+ [name, onChange],
+ );
+ if (isLoading) {
return (
-
- {({
- getInputProps,
- getItemProps,
- getMenuProps,
- getRootProps,
- getToggleButtonProps,
- highlightedIndex,
- inputValue,
- isOpen,
- openMenu,
- selectItem,
- }) => {
- return (
-
-
-
-
- {isLoading
- ? _('Loading...')
- : value.map(item => this.renderItem(item, items))}
-
-
- {
- event.preventDownshiftDefault = true; // don't call default handler from downshift
- openMenu(() => {
- const {current: input} = this.input;
- input !== null && input.focus();
- });
- },
- })}
- size="small"
- isLoading={isLoading}
- />
-
-
- {isOpen && !disabled && (
-
- )}
-
-
×
-
- );
- }}
-
+ }
+ />
);
}
-}
+ return (
+
+ );
+};
MultiSelect.propTypes = {
disabled: PropTypes.bool,
- errorContent: PropTypes.string,
- grow: PropTypes.number,
- hasError: PropTypes.bool,
+ dropdownPosition: PropTypes.oneOf(['top', 'bottom']),
+ errorContent: PropTypes.toString,
+ grow: PropTypes.numberOrNumberString,
isLoading: PropTypes.bool,
- items: PropTypes.arrayOf(PropTypes.object),
- menuPosition: PropTypes.oneOf(['left', 'right', 'adjust']),
+ items: PropTypes.arrayOf(
+ PropTypes.shape({
+ label: PropTypes.any.isRequired,
+ value: PropTypes.any.isRequired,
+ }),
+ ),
+ label: PropTypes.string,
name: PropTypes.string,
+ placeholder: PropTypes.string,
+ searchable: PropTypes.bool,
title: PropTypes.string,
value: PropTypes.array,
- width: PropTypes.string,
onChange: PropTypes.func,
};
diff --git a/src/web/components/form/numberfield.jsx b/src/web/components/form/numberfield.jsx
index 7d4321eb47..27f20781bd 100644
--- a/src/web/components/form/numberfield.jsx
+++ b/src/web/components/form/numberfield.jsx
@@ -16,220 +16,84 @@
* along with this program. If not, see .
*/
-import React from 'react';
+import React, {useCallback} from 'react';
-import {KeyCode} from 'gmp/utils/event';
-import {isDefined} from 'gmp/utils/identity';
-import {fixedValue} from 'gmp/utils/number';
-
-import {parseFloat} from 'gmp/parser';
+import {NumberInput} from '@mantine/core';
import PropTypes from 'web/utils/proptypes';
+import {parseFloat, parseInt} from 'gmp/parser';
+import {isDefined} from 'gmp/utils/identity';
-class NumberField extends React.Component {
- constructor(...args) {
- super(...args);
-
- const {value = 0, type, precision} = this.props;
-
- this.allowed = [KeyCode.SUBTRACT, KeyCode.MINUS];
-
- if (type === 'float') {
- this.allowed.push(KeyCode.PERIOD);
- }
-
- this.disallowed = [KeyCode.SPACE];
-
- const displayedValue = fixedValue(value, precision);
-
- this.state = {
- displayedValue: displayedValue,
- lastValidValue: value,
- prevValue: value,
- };
-
- this.handleChange = this.handleChange.bind(this);
- this.handleKeyDown = this.handleKeyDown.bind(this);
- this.handleBlur = this.handleBlur.bind(this);
- }
-
- static getDerivedStateFromProps(props, state) {
- const {value = 0, precision} = props;
- if (value !== state.prevValue) {
- if (value !== state.lastValidValue) {
- const displayedValue = fixedValue(value, precision);
- return {
- prevValue: value,
- displayedValue,
- lastValidValue: value,
- };
- }
- return {
- prevValue: value,
- };
- }
- return null;
- }
-
- notifyChange(value) {
- const {onChange, name, disabled = false} = this.props;
-
- if (!disabled && onChange && isDefined(value)) {
- onChange(value, name);
- }
+const NumberField = ({
+ disabled,
+ errorContent,
+ hideControls = true,
+ max,
+ min,
+ name,
+ placeholder,
+ precision,
+ prefix,
+ suffix,
+ step,
+ title,
+ type = 'int',
+ value,
+ onChange,
+ ...props
+}) => {
+ if (!isDefined(step)) {
+ step = type === 'float' ? 0.1 : 1;
}
-
- handleChange(event) {
- let {min = 0, max} = this.props;
- const {disabled = false} = this.props;
- const {value} = event.target;
-
- if (disabled) {
- return;
- }
-
- const parsedValue = parseFloat(value);
- min = parseFloat(min);
- max = isDefined(max) ? parseFloat(max) : Number.POSITIVE_INFINITY;
-
- const update =
- isDefined(parsedValue) && parsedValue <= max && parsedValue >= min;
-
- if (update) {
- this.setState({
- displayedValue: value,
- lastValidValue: parsedValue,
- });
-
- this.notifyChange(parsedValue);
- } else {
- this.setState({displayedValue: value});
- }
+ if (!isDefined(precision)) {
+ precision = type === 'float' ? 2 : 0;
}
- handleBlur() {
- let {min = 0, max} = this.props;
- const {precision} = this.props;
- const {lastValidValue, displayedValue} = this.state;
-
- min = parseFloat(min);
- max = isDefined(max) ? parseFloat(max) : Number.POSITIVE_INFINITY;
-
- let parsedValue = parseFloat(displayedValue);
-
- if (isDefined(parsedValue)) {
- if (parsedValue > max) {
- parsedValue = max;
- } else if (parsedValue < min) {
- parsedValue = min;
+ const handleChange = useCallback(
+ newValue => {
+ if (!disabled && onChange) {
+ onChange(newValue, name);
}
-
- const newDisplayedValue = fixedValue(parsedValue, precision);
-
- this.setState({
- displayedValue: newDisplayedValue,
- lastValidValue: parsedValue,
- });
- } else {
- this.setState({displayedValue: fixedValue(lastValidValue, precision)});
- }
- }
-
- handleDown() {
- const {name, onDownKeyPressed} = this.props;
- const {lastValidValue: value} = this.state;
-
- if (isDefined(onDownKeyPressed)) {
- onDownKeyPressed(value, name);
- }
- }
-
- handleUp() {
- const {name, onUpKeyPressed} = this.props;
- const {lastValidValue: value} = this.state;
-
- if (isDefined(onUpKeyPressed)) {
- onUpKeyPressed(value, name);
- }
- }
-
- handleKeyDown(event) {
- const {keyCode} = event;
-
- // '9' == keycode 57 and 105 on numpad
- // '0' == keycode 48 and 96 on numpad
- // umlauts seems to have keycode 0
- if (
- (keyCode <= 0 ||
- (keyCode > 57 && keyCode < 96) ||
- keyCode > 105 ||
- this.disallowed.includes(keyCode)) &&
- !this.allowed.includes(keyCode) &&
- !event.ctrlKey
- ) {
- event.preventDefault();
- return;
- }
-
- switch (keyCode) {
- case KeyCode.UP:
- case KeyCode.PAGE_UP:
- event.preventDefault();
- this.handleUp();
- return;
- case KeyCode.DOWN:
- case KeyCode.PAGE_DOWN:
- event.preventDefault();
- this.handleDown();
- return;
- case KeyCode.ENTER:
- event.preventDefault();
- this.handleBlur();
- return;
- default:
- break;
- }
-
- const {onKeyDown} = this.props; // eslint-disable-line react/prop-types
- if (isDefined(onKeyDown)) {
- // should only be used for testing
- onKeyDown(event);
- }
- }
-
- render() {
- const {
- precision,
- type,
- onChange,
- onDownKeyPressed,
- onUpKeyPressed,
- ...props
- } = this.props;
- const {displayedValue} = this.state;
- return (
-
- );
- }
-}
+ },
+ [onChange, disabled, name],
+ );
+ return (
+ = 7.0.0
+ error={isDefined(errorContent) && `${errorContent}`}
+ precision={parseFloat(precision)}
+ disabled={disabled}
+ hideControls={hideControls}
+ label={title}
+ max={parseInt(max)}
+ min={parseInt(min)}
+ name={name}
+ // prefix={prefix} // requires @mantine/core >= 7.0.0
+ // suffix={suffix} // requires @mantine/core >= 7.0.0
+ step={parseFloat(step)}
+ value={value}
+ onChange={handleChange}
+ />
+ );
+};
NumberField.propTypes = {
disabled: PropTypes.bool,
+ errorContent: PropTypes.toString,
+ hideControls: PropTypes.bool,
max: PropTypes.numberOrNumberString,
min: PropTypes.numberOrNumberString,
name: PropTypes.string,
- precision: PropTypes.number,
+ placeholder: PropTypes.string,
+ precision: PropTypes.numberOrNumberString,
+ prefix: PropTypes.string,
+ step: PropTypes.numberOrNumberString,
+ suffix: PropTypes.string,
+ title: PropTypes.string,
type: PropTypes.oneOf(['int', 'float']),
- value: PropTypes.number.isRequired,
+ value: PropTypes.number,
onChange: PropTypes.func,
- onDownKeyPressed: PropTypes.func,
- onUpKeyPressed: PropTypes.func,
};
export default NumberField;
diff --git a/src/web/components/form/passwordfield.jsx b/src/web/components/form/passwordfield.jsx
index 54097a2d79..ab36601b79 100644
--- a/src/web/components/form/passwordfield.jsx
+++ b/src/web/components/form/passwordfield.jsx
@@ -18,9 +18,57 @@
import React from 'react';
-import Field from './field';
+import {PasswordInput} from '@greenbone/opensight-ui-components';
-const PasswordField = props => ;
+import {isDefined} from 'gmp/utils/identity';
+
+import PropTypes from 'web/utils/proptypes';
+
+import useValueChange from './useValueChange';
+
+const PasswordField = ({
+ autoComplete,
+ disabled,
+ errorContent,
+ grow,
+ name,
+ placeholder,
+ title,
+ value,
+ onChange,
+ onKeyDown,
+ ...props
+}) => {
+ const handleChange = useValueChange({onChange, name, disabled});
+ return (
+
+ );
+};
+
+PasswordField.propTypes = {
+ autoComplete: PropTypes.string,
+ disabled: PropTypes.bool,
+ errorContent: PropTypes.toString,
+ grow: PropTypes.numberOrNumberString,
+ name: PropTypes.string,
+ placeholder: PropTypes.string,
+ title: PropTypes.string,
+ value: PropTypes.any,
+ onChange: PropTypes.func,
+ onKeyDown: PropTypes.func,
+};
export default PasswordField;
diff --git a/src/web/components/form/radio.jsx b/src/web/components/form/radio.jsx
index 034f48268f..00df0ab8ca 100644
--- a/src/web/components/form/radio.jsx
+++ b/src/web/components/form/radio.jsx
@@ -15,110 +15,51 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
-import React, {useState} from 'react';
+import React from 'react';
-import styled from 'styled-components';
+import {RadioButton as GreenboneRadio} from '@greenbone/opensight-ui-components';
-import {isDefined} from 'gmp/utils/identity';
-
-import compose from 'web/utils/compose';
import PropTypes from 'web/utils/proptypes';
-import {styledExcludeProps} from 'web/utils/styledConfig';
-
-import Divider from 'web/components/layout/divider';
-import withLayout from 'web/components/layout/withLayout';
-
-export const StyledElement = styled.label`
- display: inline-flex;
- flex-direction: row;
- align-items: center;
- font-weight: normal;
- cursor: pointer;
- ${props => (props.disabled ? {cursor: 'not-allowed'} : undefined)};
-`;
-
-export const StyledInput = styledExcludeProps(styled.input, ['convert'])`
- /* use font and line settings from parents not from browser default */
- font-family: inherit;
- font-size: inherit;
-
- padding: 0;
- margin: 0;
- margin-left: 10px;
- line-height: normal;
- width: auto;
- height: auto;
- ${props =>
- props.disabled
- ? {
- cursor: 'not-allowed',
- opacity: 0.7,
- }
- : undefined};
-`;
-
-export const StyledTitle = styled.span`
- cursor: ${props => (props.disabled ? 'not-allowed' : '')};
- opacity: ${props => (props.disabled ? '0.5' : '1')};
-`;
-
-const RadioComponent = ({title, children, disabled, ...other}) => {
- const {value: initVal, convert} = other;
- const [val, setVal] = useState(initVal);
-
- const notifyChange = value => {
- const {name, onChange} = other;
-
- if (isDefined(onChange) && !disabled) {
- onChange(value, name);
- }
- };
-
- const handleChange = event => {
- let newVal;
- if (isDefined(convert)) {
- newVal = convert(event.target.value);
- } else {
- newVal = event.target.value;
- }
- setVal(newVal);
- notifyChange(newVal);
- };
+import useValueChange from './useValueChange';
+
+const Radio = ({
+ checked,
+ disabled,
+ name,
+ title,
+ value,
+ convert,
+ onChange,
+ ...props
+}) => {
+ const handleChange = useValueChange({
+ onChange,
+ convert,
+ name,
+ disabled,
+ });
return (
-
-
-
- {isDefined(title) && (
-
- {title}
-
- )}
- {children}
-
-
+
);
};
-RadioComponent.propTypes = {
+Radio.propTypes = {
+ checked: PropTypes.bool,
+ convert: PropTypes.func,
disabled: PropTypes.bool,
name: PropTypes.string,
title: PropTypes.string,
+ value: PropTypes.any,
onChange: PropTypes.func,
};
-export default compose(
- withLayout({
- align: ['start', 'center'],
- flex: 'row',
- }),
-)(RadioComponent);
-
-// vim: set ts=2 sw=2 tw=80:
+export default Radio;
diff --git a/src/web/components/form/select.jsx b/src/web/components/form/select.jsx
index 6a931d8eb8..3a551cc4b5 100644
--- a/src/web/components/form/select.jsx
+++ b/src/web/components/form/select.jsx
@@ -16,70 +16,52 @@
* along with this program. If not, see .
*/
-import React from 'react';
+import React, {useCallback} from 'react';
-import Downshift from 'downshift';
+import {TextInput, Loader} from '@mantine/core';
-import _ from 'gmp/locale';
+import {Select as OpenSightSelect} from '@greenbone/opensight-ui-components';
import {isDefined, isArray} from 'gmp/utils/identity';
import PropTypes, {mayRequire} from 'web/utils/proptypes';
-import ArrowIcon from 'web/components/icon/arrowicon';
+import useTranslation from 'web/hooks/useTranslation';
-import Layout from 'web/components/layout/layout';
-
-import styled from 'styled-components';
-
-import {
- Box,
- caseInsensitiveFilter,
- Input,
- Item,
- ItemContainer,
- Menu,
- SelectContainer,
- SelectedValue,
-} from './selectelements';
-
-import {Marker} from './useFormValidation';
-import {styledExcludeProps} from 'web/utils/styledConfig';
+const findItem = (items, value) =>
+ isDefined(items) ? items.find(i => i.value === value) : undefined;
-const SingleSelectedValue = styled(SelectedValue)`
- cursor: default;
-`;
+const SelectValueValidator = (props, propName, componentName) => {
+ const value = props[propName];
+ const {items} = props;
-const Div = styledExcludeProps(styled.div, ['hasError'])`
- display: flex;
-`;
+ if (!items || !items.length) {
+ return;
+ }
-const SelectValueValidator = (props, prop_name, component_name) => {
- const value = props[prop_name];
- const {items} = props;
- const item = find_item(items, value);
+ const item = findItem(items, value);
if (isArray(items) && isDefined(value) && !isDefined(item)) {
if (items.length === 0) {
return new Error(
'Invalid prop ' +
- prop_name +
+ propName +
' `' +
value +
'` for ' +
- component_name +
+ componentName +
' component. items prop is empty.',
);
}
return new Error(
'Invalid prop ' +
- prop_name +
+ propName +
' `' +
value +
'` for ' +
- component_name +
+ componentName +
' component. Prop ' +
- prop_name +
+ propName +
' can not be ' +
'found in items `' +
items.map(i => i.value) +
@@ -90,231 +72,78 @@ const SelectValueValidator = (props, prop_name, component_name) => {
const selectValue = mayRequire(SelectValueValidator);
-const find_item = (items, value) =>
- isDefined(items) ? items.find(i => i.value === value) : undefined;
-
-const find_label = (items, value) => {
- const item = find_item(items, value);
- if (isDefined(item)) {
- return React.isValidElement(item.label) ? item.label : `${item.label}`;
- }
- return value;
-};
-
-const DEFAULT_WIDTH = '180px';
-
-class Select extends React.Component {
- constructor(...args) {
- super(...args);
-
- this.state = {
- search: '',
- isMenuRefAssigned: false,
- };
-
- this.input = React.createRef();
- this.box = React.createRef();
- this.menu = React.createRef();
-
- this.handleChange = this.handleChange.bind(this);
- this.handleSearch = this.handleSearch.bind(this);
- this.handleSelect = this.handleSelect.bind(this);
- this.notifyRefAssigned = this.notifyRefAssigned.bind(this);
- }
-
- notifyRefAssigned() {
- this.setState({isMenuRefAssigned: true});
- }
-
- handleChange(value) {
- const {name, onChange} = this.props;
-
- if (isDefined(onChange)) {
- onChange(value, name);
- }
- }
-
- handleSearch(event) {
- const {value} = event.target;
- event.preventDefault(); // prevent handling input by downshift
-
- this.setState({search: value});
- }
-
- handleSelect() {
- // reset search term
- this.setState({search: ''});
- }
-
- render() {
- let {disabled = false} = this.props;
- const {
- className,
- errorContent,
- hasError = false,
- items,
- itemToString,
- menuPosition,
- value,
- toolTipTitle,
- width = DEFAULT_WIDTH,
- isLoading = false,
- } = this.props;
-
- const {search} = this.state;
-
- disabled = disabled || !isDefined(items) || items.length === 0 || isLoading;
-
- const displayedItems = isDefined(items)
- ? items.filter(caseInsensitiveFilter(search))
- : [];
-
+const Select = ({
+ disabled,
+ dropdownPosition,
+ errorContent,
+ grow,
+ isLoading,
+ items = [],
+ label,
+ name,
+ placeholder,
+ searchable = true,
+ toolTipTitle,
+ value,
+ onChange,
+ ...props
+}) => {
+ const [_] = useTranslation();
+
+ const handleChange = useCallback(
+ newValue => {
+ if (isDefined(onChange)) {
+ onChange(newValue, name);
+ }
+ },
+ [name, onChange],
+ );
+
+ if (isLoading) {
return (
- {
- if (isDefined(changes) && isDefined(changes.isOpen)) {
- return {
- ...changes,
- highlightedIndex: displayedItems.findIndex(
- item => item.value === state.selectedItem,
- ),
- };
- }
- return changes;
- }}
- onChange={this.handleChange}
- onSelect={this.handleSelect}
- >
- {({
- closeMenu,
- getInputProps,
- getItemProps,
- getMenuProps,
- getRootProps,
- getToggleButtonProps,
- highlightedIndex,
- inputValue,
- isOpen,
- openMenu,
- selectItem,
- selectedItem,
- }) => {
- const label = isLoading
- ? _('Loading...')
- : find_label(items, selectedItem);
- return (
-
-
- {
- closeMenu();
- }
- : event => {
- event.preventDownshiftDefault = true; // don't call default handler from downshift
- openMenu(() => {
- const {current: input} = this.input;
- input !== null && input.focus();
- }); // set focus to input field after menu is opened
- },
- })}
- hasError={hasError}
- isOpen={isOpen}
- title={hasError ? errorContent : toolTipTitle}
- ref={this.box}
- >
-
- {label}
-
-
-
-
-
- {isOpen && !disabled && (
-
- )}
-
-
×
-
- );
- }}
-
+ }
+ />
);
}
-}
+ return (
+
+ );
+};
Select.propTypes = {
disabled: PropTypes.bool,
- errorContent: PropTypes.string,
- hasError: PropTypes.bool,
+ dropdownPosition: PropTypes.oneOf(['top', 'bottom']),
+ errorContent: PropTypes.toString,
+ grow: PropTypes.numberOrNumberString,
isLoading: PropTypes.bool,
- itemToString: PropTypes.func,
items: PropTypes.arrayOf(
PropTypes.shape({
label: PropTypes.any.isRequired,
value: PropTypes.any.isRequired,
- key: PropTypes.toString,
}),
),
- menuPosition: PropTypes.oneOf(['left', 'right', 'adjust']),
+ label: PropTypes.string,
name: PropTypes.string,
+ placeholder: PropTypes.string,
+ searchable: PropTypes.bool,
toolTipTitle: PropTypes.string,
value: selectValue,
width: PropTypes.string,
@@ -322,5 +151,3 @@ Select.propTypes = {
};
export default Select;
-
-// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/selectelements.jsx b/src/web/components/form/selectelements.jsx
deleted file mode 100644
index decc43b124..0000000000
--- a/src/web/components/form/selectelements.jsx
+++ /dev/null
@@ -1,282 +0,0 @@
-/* Copyright (C) 2018-2022 Greenbone AG
- *
- * SPDX-License-Identifier: AGPL-3.0-or-later
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Affero General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-import React from 'react';
-
-import styled from 'styled-components';
-
-import {isDefined, hasValue} from 'gmp/utils/identity';
-
-import Theme from 'web/utils/theme';
-import PropTypes from 'web/utils/proptypes';
-import {styledExcludeProps} from 'web/utils/styledConfig';
-
-import Portal from 'web/components/portal/portal';
-
-export const Box = styledExcludeProps(styled.div, ['hasError', 'isOpen'])`
- border: 1px solid ${Theme.inputBorderGray};
- border-radius: 2px;
- display: flex;
- flex-direction: row;
- align-items: stretch;
- flex-grow: 1;
- padding: 1px 5px;
- background-color: ${Theme.white};
- color: ${Theme.black};
- font-weight: normal;
- border-radius: ${props => (props.isOpen ? '2px 2px 0 0' : null)};
- background-color: ${props => {
- if (props.hasError) {
- return Theme.lightRed;
- } else if (props.disabled) {
- return Theme.dialogGray;
- }
- }};
-`;
-
-export const Input = styled.input`
- flex-grow: 1;
- padding: 1px;
- margin: 5px;
-
- /* use font and line settings from parents not from browser default */
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
-`;
-
-export const Item = styledExcludeProps(styled.span, ['isActive', 'isSelected'])`
- padding: 1px 5px;
- cursor: pointer;
- &:hover {
- background-color: ${Theme.mediumBlue};
- color: ${Theme.white};
- }
- background-color: ${props => (props.isSelected ? Theme.lightGray : null)};
- ${props =>
- props.isActive
- ? {
- backgroundColor: Theme.mediumBlue,
- color: Theme.white,
- }
- : null};
-`;
-
-export const ItemContainer = styled.div`
- max-height: 320px;
- overflow-y: auto;
- overflow-x: hidden;
- display: flex;
- flex-direction: column;
-`;
-
-const MenuContainer = styledExcludeProps(styled.div, ['position'])`
- outline: 0;
- border-radius: 0 0 4px 4px;
- transition: opacity 0.1s ease;
- box-shadow: 0 2px 3px 0 rgba(34, 36, 38, 0.15);
- border: 1px solid ${Theme.inputBorderGray};
- background-color: ${Theme.white};
- display: flex;
- flex-direction: column;
- position: absolute;
- z-index: ${Theme.Layers.menu};
- margin-top: -1px; /* collapse top border */
- box-sizing: border-box;
- top: ${props => props.y}px;
- ${props => {
- switch (props.position) {
- case 'adjust':
- return {
- left: props.x + 'px',
- width: props.width + 'px',
- };
- case 'right':
- return {
- right: props.right + 'px',
- whiteSpace: 'nowrap',
- };
- default:
- return {
- left: props.x + 'px',
- whiteSpace: 'nowrap',
- };
- }
- }};
-`;
-
-const getParentNode = element => {
- if (element.nodeName === 'HTML') {
- return element;
- }
- return element.parentNode;
-};
-
-const getStyleComputedProperty = (element, property) => {
- if (element.nodeType !== Node.ELEMENT_NODE) {
- return [];
- }
- const css = getComputedStyle(element);
- return property ? css[property] : css;
-};
-
-const getScrollParent = element => {
- if (!hasValue(element)) {
- return document.body;
- }
-
- if (element.nodeName === 'HTML' || element.nodeName === 'BODY') {
- return element.ownerDocument.body;
- }
-
- if (element.nodeName === '#document') {
- return element.body;
- }
-
- const {overflow, overflowX, overflowY} = getStyleComputedProperty(element);
- if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {
- return element;
- }
-
- return getScrollParent(getParentNode(element));
-};
-
-const getScrollX = () =>
- isDefined(window.scrollX) ? window.scrollX : window.pageXOffset;
-
-const getScrollY = () =>
- isDefined(window.scrollY) ? window.scrollY : window.pageYOffset;
-
-class MenuComponent extends React.Component {
- constructor(...args) {
- super(...args);
-
- this.handleScroll = this.handleScroll.bind(this);
- }
-
- handleScroll() {
- this.forceUpdate();
- }
-
- componentDidMount() {
- const {target} = this.props;
-
- this.eventTarget = getScrollParent(target);
-
- this.eventTarget.addEventListener('scroll', this.handleScroll, {
- passive: true,
- });
-
- if (this.eventTarget !== window) {
- window.addEventListener('scroll', this.handleScroll, {passive: true});
- }
- this.props.notifyRefAssigned();
- }
-
- componentWillUnmount() {
- this.eventTarget.removeEventListener('scroll', this.handleScroll);
-
- if (this.eventTarget !== window) {
- window.removeEventListener('scroll', this.handleScroll);
- }
- }
-
- render() {
- const {target, forwardedRef, menuHeight, notifyRefAssigned, ...props} =
- this.props;
-
- if (!hasValue(target) || target.current === null) {
- return null;
- }
-
- const rect = hasValue(target.current.closest('.multiselect-scroll'))
- ? target.current.closest('.multiselect-scroll').getBoundingClientRect()
- : target.current.getBoundingClientRect();
-
- const {height, width, right, left, top} = rect;
-
- const y = top + getScrollY() + height;
-
- return (
-
-
-
- );
- }
-}
-
-MenuComponent.propTypes = {
- forwardedRef: PropTypes.ref,
- menuHeight: PropTypes.number,
- notifyRefAssigned: PropTypes.func,
- target: PropTypes.ref,
-};
-
-export const Menu = React.forwardRef((props, ref) => (
-
-));
-
-export const SelectContainer = styled.div`
- display: flex;
- flex-direction: column;
- flex-grow: ${props => props.grow};
- position: relative;
- width: ${props => props.width};
-`;
-
-export const SelectedValue = styled.div`
- display: flex;
- align-items: center;
- flex-grow: 1;
- word-break: keep-all;
- white-space: nowrap;
- overflow: hidden;
- cursor: ${props => (props.disabled ? 'default' : 'pointer')};
-`;
-
-/**
- * Creates a filter function for select items element
- *
- * The created functions checks all items if their label contains the passed
- * search term. The comparison takes place case-insensitive.
- *
- * @param {String} search case-insensitive keyword to search for
- *
- * @returns {Function} filter function
- */
-export const caseInsensitiveFilter = search => {
- if (!isDefined(search) || search.length === 0) {
- return () => true;
- }
- search = search.toLowerCase();
- return ({label}) => ('' + label).toLowerCase().includes(search);
-};
-
-// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/spinner.jsx b/src/web/components/form/spinner.jsx
index 552ce6cc6b..e7b757e876 100644
--- a/src/web/components/form/spinner.jsx
+++ b/src/web/components/form/spinner.jsx
@@ -18,298 +18,10 @@
import React from 'react';
-import styled from 'styled-components';
-
-import {debounce} from 'gmp/utils/event';
-import {isDefined} from 'gmp/utils/identity';
-import {fixedValue} from 'gmp/utils/number';
-
-import {parseFloat, parseInt} from 'gmp/parser';
-
-import PropTypes from 'web/utils/proptypes';
-import Theme from 'web/utils/theme';
-
-import withLayout from '../layout/withLayout';
-
import NumberField from './numberfield';
-const precisionOf = num => {
- const str = num.toString();
- const decimal = str.indexOf('.');
-
- return decimal === -1 ? 0 : str.length - decimal - 1;
+const Spinner = props => {
+ return ;
};
-const StyledSpinner = styled.span`
- border-radius: 2px;
- border: 1px solid ${Theme.inputBorderGray};
- background-color: ${Theme.white};
- font-size: 1.1em;
- position: relative;
- display: inline-block;
- overflow: hidden;
- padding: 0;
- vertical-align: middle;
- ${props =>
- props.disabled
- ? {
- color: Theme.lightGray,
- cursor: 'not-allowed',
- }
- : undefined};
-`;
-
-const StyledInput = styled(NumberField)`
- /* use font and line settings from parents not from browser default */
- font-family: inherit;
- font-size: inherit;
- line-height: inherit;
-
- border: none;
- background: none;
- color: inherit;
- padding: 0;
- margin: 0.2em 0;
- vertical-align: middle;
- margin-left: 0.4em;
- margin-right: 22px;
-`;
-
-const SpinnerButton = styled.span`
- background-color: ${Theme.lightGray};
- color: ${Theme.mediumGray};
- border-left: 1px solid ${Theme.darkGray};
- width: 16px;
- height: 50%;
- font-size: 0.6em;
- padding: 0;
- margin: 0;
- text-align: center;
- vertical-align: middle;
- position: absolute;
- right: 0;
- cursor: default;
- display: block;
- overflow: hidden;
- text-decoration: none;
- user-select: none; /* don't select icon text on double click */
- &:hover {
- background-color: ${Theme.green};
- color: ${Theme.white};
- text-decoration: none;
- }
- &:active {
- background-color: ${Theme.white};
- color: ${Theme.darkGreen};
- text-decoration: none;
- }
- ${props =>
- props.disabled
- ? {
- color: Theme.lightGray,
- background: Theme.dialogGray,
- cursor: 'not-allowed',
- '&:hover': {
- color: Theme.mediumGray,
- background: Theme.lightGray,
- cursor: 'not-allowed',
- },
- }
- : undefined}
-`;
-
-const SpinnerButtonUp = styled(SpinnerButton)`
- border-top-right-radius: 1px;
- top: 0;
-`;
-
-const SpinnerButtonDown = styled(SpinnerButton)`
- border-bottom-right-radius: 1px;
- bottom: 0;
-`;
-
-const SpinnerComponent = props => {
- const getStep = () => {
- const {step, type} = props;
-
- if (isDefined(step)) {
- return parseFloat(step);
- }
- return type === 'float' ? 0.1 : 1;
- };
-
- const handleUpButton = event => {
- const step = getStep();
-
- event.preventDefault();
-
- const {value = 0} = props;
-
- setAdjustedValue(parseFloat(value) + step);
- };
-
- const handleUpKey = value => {
- const step = getStep();
- setAdjustedValue(value + step);
- };
-
- const handleDownButton = event => {
- const step = getStep();
-
- event.preventDefault();
-
- const {value = 0} = props;
-
- setAdjustedValue(parseFloat(value) - step);
- };
-
- const handleDownKey = value => {
- const step = getStep();
- setAdjustedValue(value - step);
- };
-
- const handleMouseWheel = event => {
- const direction = event.deltaY > 1 ? 1 : -1;
- const step = getStep();
-
- event.preventDefault();
-
- const {value = 0} = props;
-
- setAdjustedValue(parseFloat(value) + step * direction);
- };
-
- const handleDbClick = event => {
- event.preventDefault();
- };
-
- let notifyChange;
-
- notifyChange = value => {
- const {onChange, name, disabled = false} = props;
-
- if (!disabled && onChange) {
- onChange(value, name);
- }
- };
-
- const debounceValue = parseInt(props.debounce);
-
- if (isDefined(debounceValue) && debounceValue > 0) {
- notifyChange = debounce(notifyChange, debounceValue);
- }
-
- const setAdjustedValue = value => {
- const step = getStep();
- const {min = 0, disabled} = props;
-
- if (disabled) {
- return;
- }
-
- const base = parseFloat(min);
-
- let aboveMin = value - base;
-
- // - round to the nearest step
- aboveMin = Math.round(aboveMin / step) * step;
-
- // - rounding is based on 0, so adjust back to our base
- value = base + aboveMin;
-
- // Fix precision from bad JS floating point math
- value = parseFloat(fixedValue(value, getPrecision()));
-
- setValue(value);
- };
-
- const setValue = value => {
- let {min, max} = props;
-
- min = parseFloat(min);
- max = parseFloat(max);
-
- if (isDefined(value)) {
- if (isDefined(max) && value > max) {
- value = max;
- }
- if (isDefined(min) && value < min) {
- value = min;
- }
-
- notifyChange(value);
- }
- };
-
- const getPrecision = () => {
- const {precision = 0} = props;
- const step = getStep();
-
- return Math.max(precision, precisionOf(step));
- };
-
- const {value = 0} = props;
- const {size, type, min, max, disabled, maxLength, name} = props;
- const precision = getPrecision();
- return (
-
-
-
- ▲
-
-
- ▼
-
-
- );
-};
-
-SpinnerComponent.defaultProps = {
- size: 4,
- maxLength: 5,
- type: 'int',
-};
-
-SpinnerComponent.propTypes = {
- className: PropTypes.string,
- debounce: PropTypes.numberOrNumberString,
- disabled: PropTypes.bool,
- max: PropTypes.numberOrNumberString,
- maxLength: PropTypes.numberOrNumberString,
- min: PropTypes.numberOrNumberString,
- name: PropTypes.string,
- precision: PropTypes.number,
- size: PropTypes.numberOrNumberString,
- step: PropTypes.numberOrNumberString,
- type: PropTypes.oneOf(['int', 'float']),
- value: PropTypes.number.isRequired,
- onChange: PropTypes.func,
-};
-
-export default withLayout()(SpinnerComponent);
-
-// vim: set ts=2 sw=2 tw=80:
+export default Spinner;
diff --git a/src/web/components/form/textarea.jsx b/src/web/components/form/textarea.jsx
index 3bc08942d4..2133f530ba 100644
--- a/src/web/components/form/textarea.jsx
+++ b/src/web/components/form/textarea.jsx
@@ -16,97 +16,60 @@
* along with this program. If not, see .
*/
-import React, {useCallback} from 'react';
-import {isDefined} from 'gmp/utils/identity';
-import PropTypes from 'web/utils/proptypes';
+import React from 'react';
-import styled from 'styled-components';
+import {Textarea as GreenboneTextArea} from '@greenbone/opensight-ui-components';
-import Theme from 'web/utils/theme';
-
-import withLayout from 'web/components/layout/withLayout';
+import {isDefined} from 'gmp/utils/identity';
-import {DISABLED_OPACITY} from './field';
-import {Marker} from './useFormValidation';
-import {styledExcludeProps} from 'web/utils/styledConfig';
+import PropTypes from 'web/utils/proptypes';
-const StyledTextArea = styledExcludeProps(styled.textarea, [
- 'convert',
- 'hasError',
-])`
- display: block;
- height: auto;
- color: ${Theme.darkGray};
- background-color: ${Theme.white};
- background-image: none;
- border: 1px solid ${Theme.inputBorderGray};
- border-radius: 2px;
- padding: 4px 8px;
- cursor: ${props => (props.disabled ? 'not-allowed' : undefined)};
- background-color: ${props => {
- if (props.hasError) {
- return Theme.lightRed;
- } else if (props.disabled) {
- return Theme.dialogGray;
- }
- }};
- opacity: ${props => (props.disabled ? DISABLED_OPACITY : undefined)};
-`;
+import useValueChange from './useValueChange';
const TextArea = ({
- hasError = false,
+ autosize,
+ disabled = false,
errorContent,
- title,
- value,
+ maxRows,
+ minRows,
name,
onChange,
- disabled = false,
+ placeholder,
+ title,
+ value,
...props
}) => {
- const notifyChange = useCallback(
- val => {
- if (isDefined(onChange) && !disabled) {
- onChange(val, name);
- }
- },
- [disabled, name, onChange],
- );
-
- const handleChange = useCallback(
- event => {
- const val = event.target.value;
-
- notifyChange(val);
- },
- [notifyChange],
- );
-
+ const handleChange = useValueChange({disabled, name, onChange});
return (
-
-
- ×
-
+
);
};
TextArea.propTypes = {
+ autosize: PropTypes.bool,
disabled: PropTypes.bool,
errorContent: PropTypes.toString,
- hasError: PropTypes.bool,
+ maxRows: PropTypes.numberOrNumberString,
+ minRows: PropTypes.numberOrNumberString,
name: PropTypes.string,
+ placeholder: PropTypes.string,
title: PropTypes.string,
value: PropTypes.string,
onChange: PropTypes.func,
};
-export default withLayout()(TextArea);
+export default TextArea;
// vim: set ts=2 sw=2 tw=80:
diff --git a/src/web/components/form/textfield.jsx b/src/web/components/form/textfield.jsx
index fdaee53e62..7206c55675 100644
--- a/src/web/components/form/textfield.jsx
+++ b/src/web/components/form/textfield.jsx
@@ -18,29 +18,56 @@
import React from 'react';
+import {Input} from '@greenbone/opensight-ui-components';
+
+import {isDefined} from 'gmp/utils/identity';
+
import PropTypes from 'web/utils/proptypes';
-import Field from './field';
-import {Marker} from './useFormValidation';
+import useValueChange from './useValueChange';
-const TextField = ({hasError = false, errorContent, title, ...props}) => {
+const TextField = ({
+ autoComplete,
+ disabled,
+ errorContent,
+ grow,
+ name,
+ placeholder,
+ title,
+ value,
+ onChange,
+ onKeyDown,
+ ...props
+}) => {
+ const handleChange = useValueChange({onChange, disabled, name});
return (
-
-
- ×
-
+
);
};
TextField.propTypes = {
+ autoComplete: PropTypes.string,
+ disabled: PropTypes.bool,
errorContent: PropTypes.toString,
- hasError: PropTypes.bool,
+ grow: PropTypes.numberOrNumberString,
+ name: PropTypes.string,
+ placeholder: PropTypes.string,
title: PropTypes.string,
+ value: PropTypes.any,
+ onChange: PropTypes.func,
+ onKeyDown: PropTypes.func,
};
export default TextField;
diff --git a/src/web/components/form/timezoneselect.jsx b/src/web/components/form/timezoneselect.jsx
index 1a1c1f8f4a..4fb65990c5 100644
--- a/src/web/components/form/timezoneselect.jsx
+++ b/src/web/components/form/timezoneselect.jsx
@@ -16,9 +16,7 @@
* along with this program. If not, see .
*/
-import React from 'react';
-
-import _ from 'gmp/locale';
+import React, {useMemo} from 'react';
import {map} from 'gmp/utils/array';
@@ -26,29 +24,27 @@ import timezones from 'gmp/timezones';
import PropTypes from 'web/utils/proptypes';
+import useTranslation from 'web/hooks/useTranslation';
+
import Select from './select';
const TimeZoneSelectComponent = ({value = 'UTC', ...props}) => {
- const timezoneItems = [
- {
- label: _('Coordinated Universal Time/UTC'),
- value: 'UTC',
- },
- ...map(timezones, ({name}) => ({
- label: name,
- value: name,
- })),
- ];
-
- return (
-
+ const [_] = useTranslation();
+ const timezoneItems = useMemo(
+ () => [
+ {
+ label: _('Coordinated Universal Time/UTC'),
+ value: 'UTC',
+ },
+ ...map(timezones, ({name}) => ({
+ label: name,
+ value: name,
+ })),
+ ],
+ [_],
);
+
+ return ;
};
TimeZoneSelectComponent.propTypes = {
diff --git a/src/web/components/form/useFormValidation.jsx b/src/web/components/form/useFormValidation.jsx
index 2aee67d78a..3a7309f3b7 100644
--- a/src/web/components/form/useFormValidation.jsx
+++ b/src/web/components/form/useFormValidation.jsx
@@ -49,13 +49,7 @@ const useFormValidation = (
{onValidationSuccess, onValidationError, fieldsToValidate},
) => {
const [hasError, setHasError] = useState(false);
- const [errors, setErrors] = useState(() => {
- const fieldNames = fieldsToValidate ?? Object.keys(values);
- return fieldNames.reduce((status, name) => {
- status[name] = {};
- return status;
- }, {});
- });
+ const [errors, setErrors] = useState({});
const validateValue = useCallback(
(value, name) => {
diff --git a/src/web/components/form/yesnoradio.jsx b/src/web/components/form/yesnoradio.jsx
index f3aefa9ac5..e1c6110351 100644
--- a/src/web/components/form/yesnoradio.jsx
+++ b/src/web/components/form/yesnoradio.jsx
@@ -23,8 +23,7 @@ import {parseYesNo, YES_VALUE, NO_VALUE} from 'gmp/parser';
import PropTypes from 'web/utils/proptypes';
-import Divider from 'web/components/layout/divider';
-import Layout from 'web/components/layout/layout';
+import Row from 'web/components/layout/row';
import Radio from './radio';
@@ -36,30 +35,27 @@ const YesNoRadio = ({
yesValue = YES_VALUE,
noValue = NO_VALUE,
onChange,
- ...other
}) => (
-
-
-
-
-
-
+
+
+
+
);
YesNoRadio.propTypes = {