From 0c1ef992a7b46e3ab02141cf27998ac45779e8fb Mon Sep 17 00:00:00 2001 From: soleksy-splunk <143183665+soleksy-splunk@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:28:03 +0100 Subject: [PATCH] chore: dimmed as default disable method (#1502) **Issue number:** N/A ### PR Type **What kind of change does this PR introduce?** * [ ] Feature * [ ] Bug Fix * [ ] Refactoring (no functional or API changes) * [ ] Documentation Update * [x] Maintenance (dependency updates, CI, etc.) ## Summary Allows users to use assistance technologies for disabled buttons and text fields. ### Changes Adapt to documentation suggestion to use "dimmed" option for disabled fields: [Text](https://splunkui.splunk.com/Packages/react-ui/Text?section=examples#Dimmed) [Button](https://splunkui.splunk.com/Packages/react-ui/Button?section=examples#Dimmed) ### User experience Users can navigate by disabled buttons and text fields by using tab. ## Checklist If an item doesn't apply to your changes, leave it unchecked. * [x] I have performed a self-review of this change according to the [development guidelines](https://splunk.github.io/addonfactory-ucc-generator/contributing/#development-guidelines) * [ ] Tests have been added/modified to cover the changes [(testing doc)](https://splunk.github.io/addonfactory-ucc-generator/contributing/#build-and-test) * [ ] Changes are documented * [x] PR title and description follows the [contributing principles](https://splunk.github.io/addonfactory-ucc-generator/contributing/#pull-requests) --------- Co-authored-by: srv-rr-github-token <94607705+srv-rr-github-token@users.noreply.github.com> --- ui/jest.setup.ts | 3 +- ui/package.json | 1 + ui/src/components/AcceptModal/AcceptModal.tsx | 9 ++- ui/src/components/ConfigurationFormView.jsx | 10 ++-- .../DashboardInfoModal/DashboardInfoModal.tsx | 7 +-- ui/src/components/DeleteModal/DeleteModal.tsx | 14 ++--- .../EntityModal/EntityModal.test.tsx | 14 ++--- ui/src/components/EntityModal/EntityModal.tsx | 18 +++--- ui/src/components/EntityPage/EntityPage.tsx | 13 ++--- ui/src/components/ErrorModal/ErrorModal.tsx | 4 +- .../FormModifications.test.tsx | 12 ++-- ui/src/components/MenuInput/MenuInput.tsx | 15 ++--- .../MultiInputComponent.test.tsx | 2 +- .../TextComponent/TextComponent.tsx | 2 +- .../stories/TextComponent.stories.tsx | 11 ++++ .../TextComponent-all-props-true-chromium.png | 3 + ui/src/components/UCCButton/UCCButton.tsx | 29 ++++++++++ ui/src/components/table/TableHeader.jsx | 10 +--- ui/src/pages/Dashboard/DataIngestionModal.tsx | 6 +- ui/src/tests/expectExtenders.ts | 55 +++++++++++++++++++ ui/src/types/modules.d.ts | 8 --- ui/yarn.lock | 18 +++++- 22 files changed, 177 insertions(+), 87 deletions(-) create mode 100644 ui/src/components/TextComponent/stories/__images__/TextComponent-all-props-true-chromium.png create mode 100644 ui/src/components/UCCButton/UCCButton.tsx create mode 100644 ui/src/tests/expectExtenders.ts diff --git a/ui/jest.setup.ts b/ui/jest.setup.ts index 72eba6f54..54ea9a007 100644 --- a/ui/jest.setup.ts +++ b/ui/jest.setup.ts @@ -1,8 +1,9 @@ import '@testing-library/jest-dom'; import '@testing-library/jest-dom/jest-globals'; - import { configure } from '@testing-library/react'; + import { server } from './src/mocks/server'; +import './src/tests/expectExtenders'; /** * Configure test attributes diff --git a/ui/package.json b/ui/package.json index 536bdd914..28d9f03cd 100644 --- a/ui/package.json +++ b/ui/package.json @@ -74,6 +74,7 @@ "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^14.5.2", "@types/jest": "^29.5.14", + "@types/jest-image-snapshot": "^6.4.0", "@types/js-yaml": "^4.0.9", "@types/node": "^20.17.6", "@types/react": "^16.14.62", diff --git a/ui/src/components/AcceptModal/AcceptModal.tsx b/ui/src/components/AcceptModal/AcceptModal.tsx index 27b5f088e..675f697bd 100644 --- a/ui/src/components/AcceptModal/AcceptModal.tsx +++ b/ui/src/components/AcceptModal/AcceptModal.tsx @@ -2,7 +2,8 @@ import React from 'react'; import Modal from '@splunk/react-ui/Modal'; import Message from '@splunk/react-ui/Message'; import styled from 'styled-components'; -import { StyledButton } from '../../pages/EntryPageStyle'; + +import { UCCButton } from '../UCCButton/UCCButton'; const ModalWrapper = styled(Modal)` width: 600px; @@ -30,13 +31,11 @@ function AcceptModal(props: AcceptModalProps) { - props.handleRequestClose(false)} label={props.declineBtnLabel || 'Cancel'} /> - props.handleRequestClose(true)} label={props.acceptBtnLabel || 'OK'} /> diff --git a/ui/src/components/ConfigurationFormView.jsx b/ui/src/components/ConfigurationFormView.jsx index 8bab71111..99667e260 100644 --- a/ui/src/components/ConfigurationFormView.jsx +++ b/ui/src/components/ConfigurationFormView.jsx @@ -3,10 +3,9 @@ import PropTypes from 'prop-types'; import { _ } from '@splunk/ui-utils/i18n'; import styled from 'styled-components'; -import WaitSpinner from '@splunk/react-ui/WaitSpinner'; import BaseFormView from './BaseFormView/BaseFormView'; -import { StyledButton } from '../pages/EntryPageStyle'; +import { UCCButton } from './UCCButton/UCCButton'; import { getRequest, generateEndPointUrl } from '../util/api'; import { MODE_CONFIG } from '../constants/modes'; import { WaitSpinnerWrapper } from './table/CustomTableStyle'; @@ -88,12 +87,11 @@ function ConfigurationFormView({ serviceName }) { )} - : _('Save')} + label={_('Save')} onClick={handleSubmit} - disabled={isSubmitting} + loading={isSubmitting} /> diff --git a/ui/src/components/DashboardInfoModal/DashboardInfoModal.tsx b/ui/src/components/DashboardInfoModal/DashboardInfoModal.tsx index 7745c79d6..ad0309033 100644 --- a/ui/src/components/DashboardInfoModal/DashboardInfoModal.tsx +++ b/ui/src/components/DashboardInfoModal/DashboardInfoModal.tsx @@ -6,7 +6,7 @@ import Heading from '@splunk/react-ui/Heading'; import P from '@splunk/react-ui/Paragraph'; import QuestionCircle from '@splunk/react-icons/QuestionCircle'; -import { StyledButton } from '../../pages/EntryPageStyle'; +import { UCCButton } from '../UCCButton/UCCButton'; const ModalWrapper = styled(Modal)` width: 700px; @@ -48,15 +48,14 @@ function DashboardInfoModal(props: DashboardInfoModalProps) { {props?.troubleshootingButton?.link ? ( // to do change it into troubleshooting link - } to={props?.troubleshootingButton?.link} label={props.troubleshootingButton?.label || 'Troubleshooting {add-on}'} openInNewContext /> ) : null} - props.handleRequestClose()} label={props.closeBtnLabel || 'Close'} /> diff --git a/ui/src/components/DeleteModal/DeleteModal.tsx b/ui/src/components/DeleteModal/DeleteModal.tsx index d989d1ac2..c9487ecf0 100644 --- a/ui/src/components/DeleteModal/DeleteModal.tsx +++ b/ui/src/components/DeleteModal/DeleteModal.tsx @@ -2,17 +2,16 @@ import React, { Component } from 'react'; import Modal from '@splunk/react-ui/Modal'; import Message from '@splunk/react-ui/Message'; import styled from 'styled-components'; -import WaitSpinner from '@splunk/react-ui/WaitSpinner'; import update from 'immutability-helper'; import { _ } from '@splunk/ui-utils/i18n'; -import { generateToast } from '../../util/util'; -import { StyledButton } from '../../pages/EntryPageStyle'; +import { generateToast } from '../../util/util'; import { deleteRequest, generateEndPointUrl } from '../../util/api'; import TableContext from '../../context/TableContext'; import { parseErrorMsg, getFormattedMessage } from '../../util/messageUtil'; import { PAGE_INPUT } from '../../constants/pages'; import { StandardPages } from '../../types/components/shareableTypes'; +import { UCCButton } from '../UCCButton/UCCButton'; const ModalWrapper = styled(Modal)` width: 800px; @@ -109,17 +108,16 @@ class DeleteModal extends Component {

{deleteMsg}

- - : _('Delete')} + diff --git a/ui/src/components/EntityModal/EntityModal.test.tsx b/ui/src/components/EntityModal/EntityModal.test.tsx index c18ddf671..a43d8a556 100644 --- a/ui/src/components/EntityModal/EntityModal.test.tsx +++ b/ui/src/components/EntityModal/EntityModal.test.tsx @@ -62,7 +62,7 @@ describe('Oauth field disabled on edit - diableonEdit property', () => { renderModalWithProps(props); const oauthTextBox = getDisabledOauthField(); expect(oauthTextBox).toBeInTheDocument(); - expect(oauthTextBox).not.toHaveAttribute('disabled'); + expect(oauthTextBox).toBeVisuallyEnabled(); }); it('Oauth Oauth - disableonEdit = true, oauth field disabled on edit', async () => { @@ -82,7 +82,7 @@ describe('Oauth field disabled on edit - diableonEdit property', () => { const oauthTextBox = getDisabledOauthField(); expect(oauthTextBox).toBeInTheDocument(); - expect(oauthTextBox).toHaveAttribute('disabled'); + expect(oauthTextBox).toBeVisuallyDisabled(); }); it('Oauth Basic - Enable field equal false, so field disabled', async () => { @@ -102,7 +102,7 @@ describe('Oauth field disabled on edit - diableonEdit property', () => { const oauthTextBox = getDisabledBasicField(); expect(oauthTextBox).toBeInTheDocument(); - expect(oauthTextBox).toHaveAttribute('disabled'); + expect(oauthTextBox).toBeVisuallyDisabled(); }); it('if oauth field not disabled with create after disableonEdit true', async () => { @@ -120,7 +120,7 @@ describe('Oauth field disabled on edit - diableonEdit property', () => { renderModalWithProps(props); const oauthTextBox = getDisabledBasicField(); expect(oauthTextBox).toBeInTheDocument(); - expect(oauthTextBox).not.toHaveAttribute('disabled'); + expect(oauthTextBox).toBeVisuallyEnabled(); }); }); @@ -163,7 +163,7 @@ describe('Options - Enable field property', () => { renderModalWithProps(props); const oauthTextBox = getDisabledOauthField(); expect(oauthTextBox).toBeInTheDocument(); - expect(oauthTextBox).toHaveAttribute('disabled'); + expect(oauthTextBox).toBeVisuallyDisabled(); }); it('Oauth Basic - Enable field equal false, so field disabled', async () => { @@ -181,7 +181,7 @@ describe('Options - Enable field property', () => { renderModalWithProps(props); const oauthTextBox = getDisabledOauthField(); expect(oauthTextBox).toBeInTheDocument(); - expect(oauthTextBox).toHaveAttribute('disabled'); + expect(oauthTextBox).toBeVisuallyDisabled(); }); it('Oauth Basic - Fully enabled field, enabled: true, disableonEdit: false', async () => { @@ -199,7 +199,7 @@ describe('Options - Enable field property', () => { renderModalWithProps(props); const oauthTextBox = getDisabledOauthField(); expect(oauthTextBox).toBeInTheDocument(); - expect(oauthTextBox).not.toHaveAttribute('disabled'); + expect(oauthTextBox).toBeVisuallyEnabled(); }); }); diff --git a/ui/src/components/EntityModal/EntityModal.tsx b/ui/src/components/EntityModal/EntityModal.tsx index dabe627e8..d7447b19d 100644 --- a/ui/src/components/EntityModal/EntityModal.tsx +++ b/ui/src/components/EntityModal/EntityModal.tsx @@ -1,15 +1,14 @@ -import React, { Component, ReactElement } from 'react'; +import React, { Component } from 'react'; import Modal from '@splunk/react-ui/Modal'; import styled from 'styled-components'; -import WaitSpinner from '@splunk/react-ui/WaitSpinner'; import { _ } from '@splunk/ui-utils/i18n'; - import { ButtonClickHandler } from '@splunk/react-ui/Button'; + import { Mode, MODE_CLONE, MODE_CREATE, MODE_EDIT } from '../../constants/modes'; -import { StyledButton } from '../../pages/EntryPageStyle'; import BaseFormView from '../BaseFormView/BaseFormView'; import { StandardPages } from '../../types/components/shareableTypes'; import PageContext from '../../context/PageContext'; +import { UCCButton } from '../UCCButton/UCCButton'; const ModalWrapper = styled(Modal)` width: 800px; @@ -33,7 +32,7 @@ interface EntityModalState { class EntityModal extends Component { form: React.RefObject; - buttonText: string | ReactElement; + buttonText: string; constructor(props: EntityModalProps) { super(props); @@ -98,18 +97,17 @@ class EntityModal extends Component { - - : this.buttonText} + label={this.buttonText} + loading={this.state.isSubmititng} onClick={this.handleSubmit} - disabled={this.state.isSubmititng} /> diff --git a/ui/src/components/EntityPage/EntityPage.tsx b/ui/src/components/EntityPage/EntityPage.tsx index 181d6b0fd..dff3b1cd3 100644 --- a/ui/src/components/EntityPage/EntityPage.tsx +++ b/ui/src/components/EntityPage/EntityPage.tsx @@ -1,7 +1,6 @@ import React, { memo, useRef, useState } from 'react'; import Link from '@splunk/react-ui/Link'; -import WaitSpinner from '@splunk/react-ui/WaitSpinner'; import ColumnLayout from '@splunk/react-ui/ColumnLayout'; import { _ } from '@splunk/ui-utils/i18n'; import { variables } from '@splunk/themes'; @@ -9,13 +8,14 @@ import { variables } from '@splunk/themes'; import Heading from '@splunk/react-ui/Heading'; import styled from 'styled-components'; import { ButtonClickHandler } from '@splunk/react-ui/Button'; + import { MODE_CLONE, MODE_CREATE, MODE_EDIT, Mode } from '../../constants/modes'; import BaseFormView from '../BaseFormView/BaseFormView'; import { SubTitleComponent } from '../../pages/Input/InputPageStyle'; import { PAGE_INPUT } from '../../constants/pages'; -import { StyledButton } from '../../pages/EntryPageStyle'; import { StandardPages } from '../../types/components/shareableTypes'; import PageContext from '../../context/PageContext'; +import { UCCButton } from '../UCCButton/UCCButton'; interface EntityPageProps { handleRequestClose: () => void; @@ -108,19 +108,18 @@ function EntityPage({ - - : buttonText} + label={buttonText} onClick={handleSubmit} - disabled={isSubmitting} + loading={isSubmitting} style={{ width: '80px' }} /> diff --git a/ui/src/components/ErrorModal/ErrorModal.tsx b/ui/src/components/ErrorModal/ErrorModal.tsx index 6153609f9..e41fe2260 100644 --- a/ui/src/components/ErrorModal/ErrorModal.tsx +++ b/ui/src/components/ErrorModal/ErrorModal.tsx @@ -4,7 +4,7 @@ import Message from '@splunk/react-ui/Message'; import styled from 'styled-components'; import { getFormattedMessage } from '../../util/messageUtil'; -import { StyledButton } from '../../pages/EntryPageStyle'; +import { UCCButton } from '../UCCButton/UCCButton'; const ModalWrapper = styled(Modal)` width: 600px; @@ -31,7 +31,7 @@ function ErrorModal(props: ErrorModalProps) { - + ); diff --git a/ui/src/components/FormModifications/FormModifications.test.tsx b/ui/src/components/FormModifications/FormModifications.test.tsx index 5a0f21d12..5e139b23e 100644 --- a/ui/src/components/FormModifications/FormModifications.test.tsx +++ b/ui/src/components/FormModifications/FormModifications.test.tsx @@ -127,18 +127,22 @@ it('verify modification after text components change', async () => { expect(parentElement).toHaveTextContent(mods.label); }; - expect(componentInput).toBeDisabled(); + expect(componentInput).toBeVisuallyDisabled(); + verifyAllProps(componentParentElement, componentInput, mods1Field1); - expect(component2Input).toBeDisabled(); + expect(component2Input).toBeVisuallyDisabled(); + verifyAllProps(component2ParentElement, component2Input, mods1Field2); await userEvent.type(componentMakingModsTextBox1, secondValueToInput); - expect(componentInput).toBeEnabled(); + expect(component2Input).toBeVisuallyEnabled(); + verifyAllProps(componentParentElement, componentInput, mods2Field1); - expect(component2Input).toBeEnabled(); + expect(component2Input).toBeVisuallyEnabled(); + verifyAllProps(component2ParentElement, component2Input, mods2Field2); }); diff --git a/ui/src/components/MenuInput/MenuInput.tsx b/ui/src/components/MenuInput/MenuInput.tsx index 430cd5665..2d6b0442d 100644 --- a/ui/src/components/MenuInput/MenuInput.tsx +++ b/ui/src/components/MenuInput/MenuInput.tsx @@ -8,13 +8,14 @@ import ChevronLeft from '@splunk/react-icons/ChevronLeft'; import { _ as i18n } from '@splunk/ui-utils/i18n'; import styled from 'styled-components'; import { variables } from '@splunk/themes'; + import { getFormattedMessage } from '../../util/messageUtil'; import { getUnifiedConfigs } from '../../util/util'; import CustomMenu from '../CustomMenu'; -import { StyledButton } from '../../pages/EntryPageStyle'; import { invariant } from '../../util/invariant'; import { usePageContext } from '../../context/usePageContext'; import { shouldHideForPlatform } from '../../util/pageContext'; +import { UCCButton } from '../UCCButton/UCCButton'; const CustomSubTitle = styled.span` color: ${variables.brandColorD20}; @@ -67,14 +68,7 @@ function MenuInput({ handleRequestOpen }: MenuInputProps) { }, [inputs.services, pageContext.platform]); const closeReasons = ['clickAway', 'escapeKey', 'offScreen', 'toggleClick']; - const toggle = ( - - ); + const toggle = ; useEffect(() => { if (!isSubMenu) { @@ -211,9 +205,8 @@ function MenuInput({ handleRequestOpen }: MenuInputProps) { // Making a dropdown if we have one service const makeInputButton = () => ( - { handleRequestOpen({ serviceName: services[0].name }); diff --git a/ui/src/components/MultiInputComponent/MultiInputComponent.test.tsx b/ui/src/components/MultiInputComponent/MultiInputComponent.test.tsx index 30958e470..fed1af8a3 100644 --- a/ui/src/components/MultiInputComponent/MultiInputComponent.test.tsx +++ b/ui/src/components/MultiInputComponent/MultiInputComponent.test.tsx @@ -76,7 +76,7 @@ it('renders as disabled correctly', () => { renderFeature({ disabled: true }); const inputComponent = screen.getByTestId('multiselect'); expect(inputComponent).toBeInTheDocument(); - expect(inputComponent.getAttribute('aria-disabled')).toEqual('true'); + expect(inputComponent).toHaveAttribute('aria-disabled', 'true'); }); it.each(defaultInputProps.controlOptions.items)('handler called correctly', async (item) => { diff --git a/ui/src/components/TextComponent/TextComponent.tsx b/ui/src/components/TextComponent/TextComponent.tsx index ede7349ce..70e63e8f0 100755 --- a/ui/src/components/TextComponent/TextComponent.tsx +++ b/ui/src/components/TextComponent/TextComponent.tsx @@ -29,7 +29,7 @@ class TextComponent extends Component { inline error={this.props.error} className={this.props.field} - disabled={this.props.disabled} + disabled={this.props.disabled && 'dimmed'} value={ this.props.value === null || typeof this.props.value === 'undefined' ? '' diff --git a/ui/src/components/TextComponent/stories/TextComponent.stories.tsx b/ui/src/components/TextComponent/stories/TextComponent.stories.tsx index c3eb48128..f6331a5bf 100644 --- a/ui/src/components/TextComponent/stories/TextComponent.stories.tsx +++ b/ui/src/components/TextComponent/stories/TextComponent.stories.tsx @@ -38,3 +38,14 @@ export const Base: Story = { disabled: false, }, }; + +export const AllPropsTrue: Story = { + args: { + handleChange: fn(), + value: 'default value', + field: 'field', + error: true, + encrypted: true, + disabled: true, + }, +}; diff --git a/ui/src/components/TextComponent/stories/__images__/TextComponent-all-props-true-chromium.png b/ui/src/components/TextComponent/stories/__images__/TextComponent-all-props-true-chromium.png new file mode 100644 index 000000000..3daaf24fb --- /dev/null +++ b/ui/src/components/TextComponent/stories/__images__/TextComponent-all-props-true-chromium.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3f3fdd40742f1150cc38601eef1ebf351e47595c3a184834a246e5805ba6c24 +size 3722 diff --git a/ui/src/components/UCCButton/UCCButton.tsx b/ui/src/components/UCCButton/UCCButton.tsx new file mode 100644 index 000000000..cf708ab2b --- /dev/null +++ b/ui/src/components/UCCButton/UCCButton.tsx @@ -0,0 +1,29 @@ +import React, { ComponentProps } from 'react'; + +import Button from '@splunk/react-ui/Button'; +import WaitSpinner from '@splunk/react-ui/WaitSpinner'; +import styled from 'styled-components'; + +const StyledButton = styled(Button)` + min-width: 80px; +`; + +type Props = { + label: string; + appearance?: 'default' | 'secondary' | 'primary' | 'destructive' | 'pill' | 'toggle' | 'flat'; + disabled?: boolean; + loading?: boolean; +} & Partial>; + +export const UCCButton = React.forwardRef( + ({ disabled, loading, appearance, ...rest }, ref) => ( + : rest.icon} + label={loading ? '' : rest.label} // do not display text nor icon when loading + appearance={appearance || 'primary'} + disabled={(disabled || loading) && 'dimmed'} + /> // disable when loading + ) +); diff --git a/ui/src/components/table/TableHeader.jsx b/ui/src/components/table/TableHeader.jsx index ff3daf6c0..27bf140a8 100644 --- a/ui/src/components/table/TableHeader.jsx +++ b/ui/src/components/table/TableHeader.jsx @@ -7,10 +7,10 @@ import { Typography } from '@splunk/react-ui/Typography'; import styled from 'styled-components'; import { _ } from '@splunk/ui-utils/i18n'; +import { UCCButton } from '../UCCButton/UCCButton'; import TableFilter from './TableFilter'; import { TableSelectBoxWrapper } from './CustomTableStyle'; import { PAGE_INPUT } from '../../constants/pages'; -import { StyledButton } from '../../pages/EntryPageStyle'; import { InteractAllStatusButtons } from '../InteractAllStatusButton'; import { useTableContext } from '../../context/useTableContext'; @@ -124,13 +124,7 @@ function TableHeader({ alwaysShowLastPageLink totalPages={Math.ceil(totalElement / pageSize)} /> - {isTabs && ( - - )} + {isTabs && } - diff --git a/ui/src/tests/expectExtenders.ts b/ui/src/tests/expectExtenders.ts new file mode 100644 index 000000000..05afce0f0 --- /dev/null +++ b/ui/src/tests/expectExtenders.ts @@ -0,0 +1,55 @@ +import { invariant } from '../util/invariant'; + +expect.extend({ + toBeVisuallyEnabled(field: HTMLElement | null | Element) { + invariant(field); + + if (field.getAttribute('readonly')) { + return { pass: false, message: () => 'Field contains "readonly" attribute' }; + } + + const ariaDisabled = field.getAttribute('aria-disabled'); + + if (ariaDisabled === 'false') { + return { pass: true, message: () => 'Field is enabled' }; + } + + return { + pass: false, + message: () => + `Attribute "aria-disabled" is incorrect expected "false", got "${ariaDisabled}"`, + }; + }, + toBeVisuallyDisabled(field: HTMLElement | null | Element) { + invariant(field); + + if (field.getAttribute('readonly') === null) { + return { + pass: false, + message: () => `Field "readonly" attribute is null`, + }; + } + + const ariaDisabled = field.getAttribute('aria-disabled'); + + if (ariaDisabled === 'true') { + return { pass: true, message: () => 'Field is disabled' }; + } + + return { + pass: false, + message: () => + `Attribute "aria-disabled" is incorrect expected "true", got ${ariaDisabled}`, + }; + }, +}); + +declare global { + // eslint-disable-next-line @typescript-eslint/no-namespace + namespace jest { + interface Matchers { + toBeVisuallyDisabled(): R; + toBeVisuallyEnabled(): R; + } + } +} diff --git a/ui/src/types/modules.d.ts b/ui/src/types/modules.d.ts index 16698a4a1..65d0329d1 100644 --- a/ui/src/types/modules.d.ts +++ b/ui/src/types/modules.d.ts @@ -84,11 +84,3 @@ declare module '@splunk/search-job'; declare module '@splunk/ui-utils/i18n'; declare module 'uuid'; - -declare global { - namespace jest { - interface Matchers { - toMatchImageSnapshot(): R; - } - } -} diff --git a/ui/yarn.lock b/ui/yarn.lock index 9ffbb60f7..21f4729ef 100644 --- a/ui/yarn.lock +++ b/ui/yarn.lock @@ -4511,7 +4511,16 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^29.5.14": +"@types/jest-image-snapshot@^6.4.0": + version "6.4.0" + resolved "https://registry.npmjs.org/@types/jest-image-snapshot/-/jest-image-snapshot-6.4.0.tgz#641054d2fa2ff130a49c844ee7a9a68f281b6017" + integrity sha512-8TQ/EgqFCX0UWSpH488zAc21fCkJNpZPnnp3xWFMqElxApoJV5QOoqajnVRV7AhfF0rbQWTVyc04KG7tXnzCPA== + dependencies: + "@types/jest" "*" + "@types/pixelmatch" "*" + ssim.js "^3.1.1" + +"@types/jest@*", "@types/jest@^29.5.14": version "29.5.14" resolved "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz#2b910912fa1d6856cadcd0c1f95af7df1d6049e5" integrity sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ== @@ -4613,6 +4622,13 @@ resolved "https://registry.npmjs.org/@types/pbf/-/pbf-3.0.5.tgz#a9495a58d8c75be4ffe9a0bd749a307715c07404" integrity sha512-j3pOPiEcWZ34R6a6mN07mUkM4o4Lwf6hPNt8eilOeZhTFbxFXmKhvXl9Y28jotFPaI1bpPDJsbCprUoNke6OrA== +"@types/pixelmatch@*": + version "5.2.6" + resolved "https://registry.npmjs.org/@types/pixelmatch/-/pixelmatch-5.2.6.tgz#fba6de304ac958495f27d85989f5c6bb7499a686" + integrity sha512-wC83uexE5KGuUODn6zkm9gMzTwdY5L0chiK+VrKcDfEjzxh1uadlWTvOmAbCpnM9zx/Ww3f8uKlYQVnO/TrqVg== + dependencies: + "@types/node" "*" + "@types/prop-types@*": version "15.7.13" resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz#2af91918ee12d9d32914feb13f5326658461b451"