@popsure/dirty-swan 0.66.27 → 0.66.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/cjs/index.js +14 -6
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/lib/components/downloadButton/index.test.d.ts +1 -0
  4. package/dist/cjs/lib/components/input/autoSuggestInput/index.test.d.ts +1 -0
  5. package/dist/cjs/lib/components/tabs/Tabs.d.ts +1 -0
  6. package/dist/esm/components/autocompleteAddress/index.js +2 -2
  7. package/dist/esm/components/autocompleteAddress/index.js.map +1 -1
  8. package/dist/esm/components/autocompleteAddress/index.test.js +21 -12
  9. package/dist/esm/components/autocompleteAddress/index.test.js.map +1 -1
  10. package/dist/esm/components/downloadButton/index.js +1 -1
  11. package/dist/esm/components/downloadButton/index.js.map +1 -1
  12. package/dist/esm/components/downloadButton/index.test.js +25 -0
  13. package/dist/esm/components/downloadButton/index.test.js.map +1 -0
  14. package/dist/esm/components/input/autoSuggestInput/index.js +1 -1
  15. package/dist/esm/components/input/autoSuggestInput/index.js.map +1 -1
  16. package/dist/esm/components/input/autoSuggestInput/index.test.js +24 -0
  17. package/dist/esm/components/input/autoSuggestInput/index.test.js.map +1 -0
  18. package/dist/esm/components/table/Table.js +9 -1
  19. package/dist/esm/components/table/Table.js.map +1 -1
  20. package/dist/esm/components/table/Table.test.js +25 -0
  21. package/dist/esm/components/table/Table.test.js.map +1 -1
  22. package/dist/esm/components/tabs/Tabs.js +1 -1
  23. package/dist/esm/components/tabs/Tabs.js.map +1 -1
  24. package/dist/esm/lib/components/downloadButton/index.test.d.ts +1 -0
  25. package/dist/esm/lib/components/input/autoSuggestInput/index.test.d.ts +1 -0
  26. package/dist/esm/lib/components/tabs/Tabs.d.ts +1 -0
  27. package/package.json +1 -1
  28. package/src/lib/components/autocompleteAddress/index.test.tsx +17 -11
  29. package/src/lib/components/autocompleteAddress/index.tsx +7 -0
  30. package/src/lib/components/downloadButton/index.test.tsx +22 -0
  31. package/src/lib/components/downloadButton/index.tsx +1 -0
  32. package/src/lib/components/input/autoSuggestInput/index.test.tsx +22 -0
  33. package/src/lib/components/input/autoSuggestInput/index.tsx +1 -0
  34. package/src/lib/components/table/Table.test.tsx +43 -0
  35. package/src/lib/components/table/Table.tsx +9 -1
  36. package/src/lib/components/tabs/Tabs.tsx +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"Table.test.js","sources":["../../../../../src/lib/components/table/Table.test.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { render, screen } from '../../util/testUtils';\nimport { useMediaQuery } from '../../hooks/useMediaQuery';\nimport { Table } from './Table';\nimport { TableSectionData } from './types';\n\njest.mock('../../hooks/useMediaQuery', () => ({\n useMediaQuery: jest.fn(() => false),\n}));\n\nconst tableData: TableSectionData[] = [\n {\n section: {\n title: 'Section 1',\n icon: <span>Icon 1</span>,\n },\n rows: [[{ text: 'Item 1', cellId: '#item1' }, { text: 'Item 2' }]],\n },\n {\n section: {\n title: 'Section 2',\n icon: 'https://placehold.co/30x30/orange/white',\n },\n rows: [\n [{ text: 'Item 3' }, { text: 'Item 4', modalContent: 'Additional item' }],\n ],\n },\n];\n\ndescribe('Table', () => {\n it('renders the table with sections and items', () => {\n render(<Table tableData={tableData} title=\"Test Table\" />);\n\n expect(screen.getByText('Section 1')).toBeInTheDocument();\n expect(screen.getByText('Section 2')).toBeInTheDocument();\n\n expect(screen.getAllByText('Item 1')[0]).toBeInTheDocument();\n expect(screen.getAllByText('Item 2')[0]).toBeInTheDocument();\n expect(screen.getByText('Item 3')).toBeInTheDocument();\n expect(screen.getByText('Item 4')).toBeInTheDocument();\n });\n\n it('renders the table without sections', () => {\n const dataWithoutSections = [{ rows: tableData[0].rows }];\n\n render(<Table tableData={dataWithoutSections} title=\"Test Table\" />);\n\n expect(screen.getAllByText('Item 1')[0]).toBeVisible();\n expect(screen.getAllByText('Item 2')[0]).toBeVisible();\n });\n\n it('hides the show/hide details button if hideDetails is false', () => {\n render(<Table tableData={tableData} hideDetails title=\"Test Table\" />);\n\n expect(screen.queryByTestId('show-hide-details')).toBeInTheDocument();\n });\n\n it('shows the show/hide details button if hideDetails is true', () => {\n render(<Table tableData={tableData} hideDetails title=\"Test Table\" />);\n\n expect(screen.getByTestId('show-hide-details')).toBeInTheDocument();\n });\n\n it('hides the sections if hideDetails is true', () => {\n render(<Table tableData={tableData} hideDetails title=\"Test Table\" />);\n\n expect(screen.queryByText('Section 2')).not.toBeInTheDocument();\n expect(screen.getByTestId('show-hide-details')).toBeInTheDocument();\n });\n\n it('hides the sections if hideDetails is true and shows if clicking on button', async () => {\n const { user } = render(\n <Table tableData={tableData} hideDetails title=\"Test Table\" />\n );\n\n expect(screen.getByText('Show details')).toBeVisible();\n\n await user.click(screen.getByTestId('show-hide-details'));\n\n expect(screen.getByText('Section 2')).toBeVisible();\n expect(screen.getByText('Hide details')).toBeVisible();\n });\n\n it('does not render the sticky header row when hideStickyHeader is true', () => {\n const { rerender } = render(\n <Table tableData={tableData} title=\"Test Table\" />\n );\n const countWithStickyHeader = screen.getAllByText('Item 1').length;\n\n rerender(\n <Table tableData={tableData} hideStickyHeader title=\"Test Table\" />\n );\n\n expect(screen.getAllByText('Item 1')).toHaveLength(\n countWithStickyHeader - 1\n );\n });\n\n it('shows a modal when clicking on info icon', async () => {\n const { user } = render(<Table tableData={tableData} title=\"Test Table\" />);\n\n await user.click(screen.getByTestId('ds-table-info-button'));\n\n expect(screen.getByText('Additional item')).toBeVisible();\n });\n\n it('renders the table with cell replacements', () => {\n render(\n <Table\n tableData={tableData}\n title=\"Test Table\"\n cellReplacements={{\n '#item1': {\n text: 'I was replaced',\n },\n }}\n />\n );\n\n expect(screen.getByText('Section 1')).toBeInTheDocument();\n expect(screen.getByText('Section 2')).toBeInTheDocument();\n\n expect(screen.getAllByText('I was replaced')[0]).toBeInTheDocument();\n expect(screen.getAllByText('Item 2')[0]).toBeInTheDocument();\n expect(screen.getAllByText('Item 3')[0]).toBeInTheDocument();\n expect(screen.getAllByText('Item 4')[0]).toBeInTheDocument();\n });\n\n it('renders icons with a custom image component', () => {\n const CustomImageComponent = ({ src }: { src: string }) => (\n <>\n <p>I am custom</p>\n <img src={src} alt=\"\" />\n </>\n );\n\n render(\n <Table\n tableData={tableData}\n title=\"Test Table\"\n imageComponent={CustomImageComponent}\n />\n );\n\n expect(screen.getByText('I am custom')).toBeInTheDocument();\n });\n});\n\ndescribe('Table on mobile with a parent-controlled section', () => {\n const planTable: TableSectionData[] = [\n {\n rows: [\n [{ text: 'Choose your plan' }, { text: 'Basic' }, { text: 'Advanced' }],\n ],\n },\n ];\n\n const ControlledTable = ({\n onSelectionChanged,\n }: {\n onSelectionChanged: (index: number) => void;\n }) => {\n const [activeSection, setActiveSection] = useState(2);\n\n return (\n <Table\n title=\"Plans\"\n tableData={planTable}\n activeSection={activeSection}\n onSelectionChanged={(index) => {\n onSelectionChanged(index);\n setActiveSection(index);\n }}\n />\n );\n };\n\n beforeAll(() => {\n HTMLElement.prototype.scroll = jest.fn();\n (useMediaQuery as jest.Mock).mockReturnValue(true);\n });\n\n afterAll(() => {\n (useMediaQuery as jest.Mock).mockReturnValue(false);\n });\n\n it('settles on the parent section instead of bouncing between columns', () => {\n const reported: number[] = [];\n\n render(\n <ControlledTable\n onSelectionChanged={(index) => {\n reported.push(index);\n if (reported.length > 5) {\n throw new Error(`selection bounced: ${reported.join(',')}`);\n }\n }}\n />\n );\n\n expect(reported).toEqual([2]);\n expect(screen.getByTestId('previous-section-button')).toBeEnabled();\n expect(screen.getByTestId('next-section-button')).toBeDisabled();\n });\n});\n"],"names":["_jsx","render","_jsxs","_Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"Table.test.js","sources":["../../../../../src/lib/components/table/Table.test.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { render, screen } from '../../util/testUtils';\nimport { useMediaQuery } from '../../hooks/useMediaQuery';\nimport { Table } from './Table';\nimport { TableSectionData } from './types';\n\njest.mock('../../hooks/useMediaQuery', () => ({\n useMediaQuery: jest.fn(() => false),\n}));\n\nconst tableData: TableSectionData[] = [\n {\n section: {\n title: 'Section 1',\n icon: <span>Icon 1</span>,\n },\n rows: [[{ text: 'Item 1', cellId: '#item1' }, { text: 'Item 2' }]],\n },\n {\n section: {\n title: 'Section 2',\n icon: 'https://placehold.co/30x30/orange/white',\n },\n rows: [\n [{ text: 'Item 3' }, { text: 'Item 4', modalContent: 'Additional item' }],\n ],\n },\n];\n\ndescribe('Table', () => {\n it('renders the table with sections and items', () => {\n render(<Table tableData={tableData} title=\"Test Table\" />);\n\n expect(screen.getByText('Section 1')).toBeInTheDocument();\n expect(screen.getByText('Section 2')).toBeInTheDocument();\n\n expect(screen.getAllByText('Item 1')[0]).toBeInTheDocument();\n expect(screen.getAllByText('Item 2')[0]).toBeInTheDocument();\n expect(screen.getByText('Item 3')).toBeInTheDocument();\n expect(screen.getByText('Item 4')).toBeInTheDocument();\n });\n\n it('renders the table without sections', () => {\n const dataWithoutSections = [{ rows: tableData[0].rows }];\n\n render(<Table tableData={dataWithoutSections} title=\"Test Table\" />);\n\n expect(screen.getAllByText('Item 1')[0]).toBeVisible();\n expect(screen.getAllByText('Item 2')[0]).toBeVisible();\n });\n\n it('hides the show/hide details button if hideDetails is false', () => {\n render(<Table tableData={tableData} hideDetails title=\"Test Table\" />);\n\n expect(screen.queryByTestId('show-hide-details')).toBeInTheDocument();\n });\n\n it('shows the show/hide details button if hideDetails is true', () => {\n render(<Table tableData={tableData} hideDetails title=\"Test Table\" />);\n\n expect(screen.getByTestId('show-hide-details')).toBeInTheDocument();\n });\n\n it('hides the sections if hideDetails is true', () => {\n render(<Table tableData={tableData} hideDetails title=\"Test Table\" />);\n\n expect(screen.queryByText('Section 2')).not.toBeInTheDocument();\n expect(screen.getByTestId('show-hide-details')).toBeInTheDocument();\n });\n\n it('hides the sections if hideDetails is true and shows if clicking on button', async () => {\n const { user } = render(\n <Table tableData={tableData} hideDetails title=\"Test Table\" />\n );\n\n expect(screen.getByText('Show details')).toBeVisible();\n\n await user.click(screen.getByTestId('show-hide-details'));\n\n expect(screen.getByText('Section 2')).toBeVisible();\n expect(screen.getByText('Hide details')).toBeVisible();\n });\n\n it('does not render the sticky header row when hideStickyHeader is true', () => {\n const { rerender } = render(\n <Table tableData={tableData} title=\"Test Table\" />\n );\n const countWithStickyHeader = screen.getAllByText('Item 1').length;\n\n rerender(\n <Table tableData={tableData} hideStickyHeader title=\"Test Table\" />\n );\n\n expect(screen.getAllByText('Item 1')).toHaveLength(\n countWithStickyHeader - 1\n );\n });\n\n it('shows a modal when clicking on info icon', async () => {\n const { user } = render(<Table tableData={tableData} title=\"Test Table\" />);\n\n await user.click(screen.getByTestId('ds-table-info-button'));\n\n expect(screen.getByText('Additional item')).toBeVisible();\n });\n\n it('renders the table with cell replacements', () => {\n render(\n <Table\n tableData={tableData}\n title=\"Test Table\"\n cellReplacements={{\n '#item1': {\n text: 'I was replaced',\n },\n }}\n />\n );\n\n expect(screen.getByText('Section 1')).toBeInTheDocument();\n expect(screen.getByText('Section 2')).toBeInTheDocument();\n\n expect(screen.getAllByText('I was replaced')[0]).toBeInTheDocument();\n expect(screen.getAllByText('Item 2')[0]).toBeInTheDocument();\n expect(screen.getAllByText('Item 3')[0]).toBeInTheDocument();\n expect(screen.getAllByText('Item 4')[0]).toBeInTheDocument();\n });\n\n it('renders icons with a custom image component', () => {\n const CustomImageComponent = ({ src }: { src: string }) => (\n <>\n <p>I am custom</p>\n <img src={src} alt=\"\" />\n </>\n );\n\n render(\n <Table\n tableData={tableData}\n title=\"Test Table\"\n imageComponent={CustomImageComponent}\n />\n );\n\n expect(screen.getByText('I am custom')).toBeInTheDocument();\n });\n});\n\ndescribe('Table on mobile with a parent-controlled section', () => {\n const planTable: TableSectionData[] = [\n {\n rows: [\n [{ text: 'Choose your plan' }, { text: 'Basic' }, { text: 'Advanced' }],\n ],\n },\n ];\n\n const ControlledTable = ({\n onSelectionChanged,\n }: {\n onSelectionChanged: (index: number) => void;\n }) => {\n const [activeSection, setActiveSection] = useState(2);\n\n return (\n <Table\n title=\"Plans\"\n tableData={planTable}\n activeSection={activeSection}\n onSelectionChanged={(index) => {\n onSelectionChanged(index);\n setActiveSection(index);\n }}\n />\n );\n };\n\n beforeAll(() => {\n HTMLElement.prototype.scroll = jest.fn();\n (useMediaQuery as jest.Mock).mockReturnValue(true);\n });\n\n afterAll(() => {\n (useMediaQuery as jest.Mock).mockReturnValue(false);\n });\n\n it('settles on the parent section instead of bouncing between columns', () => {\n const reported: number[] = [];\n\n render(\n <ControlledTable\n onSelectionChanged={(index) => {\n reported.push(index);\n if (reported.length > 5) {\n throw new Error(`selection bounced: ${reported.join(',')}`);\n }\n }}\n />\n );\n\n expect(reported).toEqual([2]);\n expect(screen.getByTestId('previous-section-button')).toBeEnabled();\n expect(screen.getByTestId('next-section-button')).toBeDisabled();\n });\n});\n\ndescribe('Table on mobile with tabs navigation', () => {\n const planTable: TableSectionData[] = [\n {\n rows: [\n [\n { text: 'Choose your plan' },\n { text: 'Basic', cellId: 'basic' },\n { text: 'Advanced', cellId: 'advanced', dataTestId: 'advanced-plan' },\n ],\n ],\n },\n ];\n\n beforeAll(() => {\n HTMLElement.prototype.scroll = jest.fn();\n (useMediaQuery as jest.Mock).mockReturnValue(true);\n });\n\n afterAll(() => {\n (useMediaQuery as jest.Mock).mockReturnValue(false);\n });\n\n it('forwards the header cell test ids to the tabs, preferring cell replacements', () => {\n render(\n <Table\n title=\"Plans\"\n tableData={planTable}\n mobileNavigationMode=\"tabs\"\n cellReplacements={{ basic: { dataTestId: 'basic-plan' } }}\n />\n );\n\n expect(screen.getByRole('tab', { name: 'Basic' })).toHaveAttribute(\n 'data-testid',\n 'basic-plan'\n );\n expect(screen.getByRole('tab', { name: 'Advanced' })).toHaveAttribute(\n 'data-testid',\n 'advanced-plan'\n );\n });\n});\n"],"names":["_jsx","render","_jsxs","_Fragment"],"mappings":"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"}
@@ -32,7 +32,7 @@ var Tabs = function (_a) {
32
32
  var _a;
33
33
  return (jsx("button", { ref: setTabRef(index), type: "button", role: "tab", "aria-selected": activeIndex === index, tabIndex: activeIndex === index ? 0 : -1, className: classNames('p-p bg-transparent c-pointer', styles.tab, (_a = {},
34
34
  _a[styles.tabActive] = activeIndex === index,
35
- _a)), onClick: function () { return onTabChange(index); }, onKeyDown: function (e) { return handleKeyDown(e, index); }, children: tab.label }, tab.id));
35
+ _a)), onClick: function () { return onTabChange(index); }, onKeyDown: function (e) { return handleKeyDown(e, index); }, "data-testid": tab.dataTestId, children: tab.label }, tab.id));
36
36
  }) }));
37
37
  };
38
38
 
@@ -1 +1 @@
1
- {"version":3,"file":"Tabs.js","sources":["../../../../../src/lib/components/tabs/Tabs.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport { KeyboardEvent, useCallback, useRef } from 'react';\n\nimport styles from './Tabs.module.scss';\n\nexport interface TabItem {\n id: string;\n label: string;\n}\n\nexport interface TabsProps {\n tabs: TabItem[];\n activeIndex: number;\n onTabChange: (index: number) => void;\n className?: string;\n}\n\nconst Tabs = ({ tabs, activeIndex, onTabChange, className }: TabsProps) => {\n const tabRefs = useRef<(HTMLButtonElement | null)[]>([]);\n\n const setTabRef = useCallback(\n (index: number) => (el: HTMLButtonElement | null) => {\n tabRefs.current[index] = el;\n },\n []\n );\n\n const handleKeyDown = (e: KeyboardEvent, index: number) => {\n const count = tabs.length;\n let nextIndex: number | null = null;\n\n if (e.key === 'ArrowRight') nextIndex = (index + 1) % count;\n if (e.key === 'ArrowLeft') nextIndex = (index - 1 + count) % count;\n\n if (nextIndex !== null) {\n e.preventDefault();\n onTabChange(nextIndex);\n tabRefs.current[nextIndex]?.focus({ preventScroll: true });\n }\n };\n\n return (\n <div className={classNames(styles.tabs, className)} role=\"tablist\">\n {tabs.map((tab, index) => (\n <button\n ref={setTabRef(index)}\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={activeIndex === index}\n tabIndex={activeIndex === index ? 0 : -1}\n className={classNames('p-p bg-transparent c-pointer', styles.tab, {\n [styles.tabActive]: activeIndex === index,\n })}\n onClick={() => onTabChange(index)}\n onKeyDown={(e) => handleKeyDown(e, index)}\n >\n {tab.label}\n </button>\n ))}\n </div>\n );\n};\n\nexport { Tabs };\n"],"names":["_jsx"],"mappings":";;;;;;;;;;AAiBA,IAAM,IAAI,GAAG,UAAC,EAAwD,EAAA;QAAtD,IAAI,GAAA,EAAA,CAAA,IAAA,EAAE,WAAW,GAAA,EAAA,CAAA,WAAA,EAAE,WAAW,GAAA,EAAA,CAAA,WAAA,EAAE,SAAS,GAAA,EAAA,CAAA,SAAA;AACvD,IAAA,IAAM,OAAO,GAAG,MAAM,CAA+B,EAAE,CAAC;IAExD,IAAM,SAAS,GAAG,WAAW,CAC3B,UAAC,KAAa,EAAA,EAAK,OAAA,UAAC,EAA4B,EAAA;AAC9C,QAAA,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;AAC7B,IAAA,CAAC,CAAA,CAFkB,CAElB,EACD,EAAE,CACH;AAED,IAAA,IAAM,aAAa,GAAG,UAAC,CAAgB,EAAE,KAAa,EAAA;;AACpD,QAAA,IAAM,KAAK,GAAG,IAAI,CAAC,MAAM;QACzB,IAAI,SAAS,GAAkB,IAAI;AAEnC,QAAA,IAAI,CAAC,CAAC,GAAG,KAAK,YAAY;YAAE,SAAS,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,KAAK;AAC3D,QAAA,IAAI,CAAC,CAAC,GAAG,KAAK,WAAW;YAAE,SAAS,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK,IAAI,KAAK;AAElE,QAAA,IAAI,SAAS,KAAK,IAAI,EAAE;YACtB,CAAC,CAAC,cAAc,EAAE;YAClB,WAAW,CAAC,SAAS,CAAC;AACtB,YAAA,CAAA,EAAA,GAAA,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,KAAK,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;QAC5D;AACF,IAAA,CAAC;IAED,QACEA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,IAAI,EAAC,SAAS,EAAA,QAAA,EAC/D,IAAI,CAAC,GAAG,CAAC,UAAC,GAAG,EAAE,KAAK,EAAA;;YAAK,QACxBA,gBACE,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,EAErB,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,mBACK,WAAW,KAAK,KAAK,EACpC,QAAQ,EAAE,WAAW,KAAK,KAAK,GAAG,CAAC,GAAG,EAAE,EACxC,SAAS,EAAE,UAAU,CAAC,8BAA8B,EAAE,MAAM,CAAC,GAAG,GAAA,EAAA,GAAA,EAAA;AAC9D,oBAAA,EAAA,CAAC,MAAM,CAAC,SAAS,CAAA,GAAG,WAAW,KAAK,KAAK;AACzC,oBAAA,EAAA,EAAA,EACF,OAAO,EAAE,YAAA,EAAM,OAAA,WAAW,CAAC,KAAK,CAAC,CAAA,CAAlB,CAAkB,EACjC,SAAS,EAAE,UAAC,CAAC,EAAA,EAAK,OAAA,aAAa,CAAC,CAAC,EAAE,KAAK,CAAC,EAAvB,CAAuB,EAAA,QAAA,EAExC,GAAG,CAAC,KAAK,EAAA,EAXL,GAAG,CAAC,EAAE,CAYJ;QAfe,CAgBzB,CAAC,EAAA,CACE;AAEV;;;;"}
1
+ {"version":3,"file":"Tabs.js","sources":["../../../../../src/lib/components/tabs/Tabs.tsx"],"sourcesContent":["import classNames from 'classnames';\nimport { KeyboardEvent, useCallback, useRef } from 'react';\n\nimport styles from './Tabs.module.scss';\n\nexport interface TabItem {\n id: string;\n label: string;\n dataTestId?: string;\n}\n\nexport interface TabsProps {\n tabs: TabItem[];\n activeIndex: number;\n onTabChange: (index: number) => void;\n className?: string;\n}\n\nconst Tabs = ({ tabs, activeIndex, onTabChange, className }: TabsProps) => {\n const tabRefs = useRef<(HTMLButtonElement | null)[]>([]);\n\n const setTabRef = useCallback(\n (index: number) => (el: HTMLButtonElement | null) => {\n tabRefs.current[index] = el;\n },\n []\n );\n\n const handleKeyDown = (e: KeyboardEvent, index: number) => {\n const count = tabs.length;\n let nextIndex: number | null = null;\n\n if (e.key === 'ArrowRight') nextIndex = (index + 1) % count;\n if (e.key === 'ArrowLeft') nextIndex = (index - 1 + count) % count;\n\n if (nextIndex !== null) {\n e.preventDefault();\n onTabChange(nextIndex);\n tabRefs.current[nextIndex]?.focus({ preventScroll: true });\n }\n };\n\n return (\n <div className={classNames(styles.tabs, className)} role=\"tablist\">\n {tabs.map((tab, index) => (\n <button\n ref={setTabRef(index)}\n key={tab.id}\n type=\"button\"\n role=\"tab\"\n aria-selected={activeIndex === index}\n tabIndex={activeIndex === index ? 0 : -1}\n className={classNames('p-p bg-transparent c-pointer', styles.tab, {\n [styles.tabActive]: activeIndex === index,\n })}\n onClick={() => onTabChange(index)}\n onKeyDown={(e) => handleKeyDown(e, index)}\n data-testid={tab.dataTestId}\n >\n {tab.label}\n </button>\n ))}\n </div>\n );\n};\n\nexport { Tabs };\n"],"names":["_jsx"],"mappings":";;;;;;;;;;AAkBA,IAAM,IAAI,GAAG,UAAC,EAAwD,EAAA;QAAtD,IAAI,GAAA,EAAA,CAAA,IAAA,EAAE,WAAW,GAAA,EAAA,CAAA,WAAA,EAAE,WAAW,GAAA,EAAA,CAAA,WAAA,EAAE,SAAS,GAAA,EAAA,CAAA,SAAA;AACvD,IAAA,IAAM,OAAO,GAAG,MAAM,CAA+B,EAAE,CAAC;IAExD,IAAM,SAAS,GAAG,WAAW,CAC3B,UAAC,KAAa,EAAA,EAAK,OAAA,UAAC,EAA4B,EAAA;AAC9C,QAAA,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;AAC7B,IAAA,CAAC,CAAA,CAFkB,CAElB,EACD,EAAE,CACH;AAED,IAAA,IAAM,aAAa,GAAG,UAAC,CAAgB,EAAE,KAAa,EAAA;;AACpD,QAAA,IAAM,KAAK,GAAG,IAAI,CAAC,MAAM;QACzB,IAAI,SAAS,GAAkB,IAAI;AAEnC,QAAA,IAAI,CAAC,CAAC,GAAG,KAAK,YAAY;YAAE,SAAS,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,KAAK;AAC3D,QAAA,IAAI,CAAC,CAAC,GAAG,KAAK,WAAW;YAAE,SAAS,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK,IAAI,KAAK;AAElE,QAAA,IAAI,SAAS,KAAK,IAAI,EAAE;YACtB,CAAC,CAAC,cAAc,EAAE;YAClB,WAAW,CAAC,SAAS,CAAC;AACtB,YAAA,CAAA,EAAA,GAAA,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,KAAK,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;QAC5D;AACF,IAAA,CAAC;IAED,QACEA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,IAAI,EAAC,SAAS,EAAA,QAAA,EAC/D,IAAI,CAAC,GAAG,CAAC,UAAC,GAAG,EAAE,KAAK,EAAA;;YAAK,QACxBA,gBACE,GAAG,EAAE,SAAS,CAAC,KAAK,CAAC,EAErB,IAAI,EAAC,QAAQ,EACb,IAAI,EAAC,KAAK,mBACK,WAAW,KAAK,KAAK,EACpC,QAAQ,EAAE,WAAW,KAAK,KAAK,GAAG,CAAC,GAAG,EAAE,EACxC,SAAS,EAAE,UAAU,CAAC,8BAA8B,EAAE,MAAM,CAAC,GAAG,GAAA,EAAA,GAAA,EAAA;AAC9D,oBAAA,EAAA,CAAC,MAAM,CAAC,SAAS,CAAA,GAAG,WAAW,KAAK,KAAK;AACzC,oBAAA,EAAA,EAAA,EACF,OAAO,EAAE,YAAA,EAAM,OAAA,WAAW,CAAC,KAAK,CAAC,CAAA,CAAlB,CAAkB,EACjC,SAAS,EAAE,UAAC,CAAC,EAAA,EAAK,OAAA,aAAa,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA,CAAvB,CAAuB,EAAA,aAAA,EAC5B,GAAG,CAAC,UAAU,EAAA,QAAA,EAE1B,GAAG,CAAC,KAAK,EAAA,EAZL,GAAG,CAAC,EAAE,CAaJ;QAhBe,CAiBzB,CAAC,EAAA,CACE;AAEV;;;;"}
@@ -1,6 +1,7 @@
1
1
  export interface TabItem {
2
2
  id: string;
3
3
  label: string;
4
+ dataTestId?: string;
4
5
  }
5
6
  export interface TabsProps {
6
7
  tabs: TabItem[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@popsure/dirty-swan",
3
- "version": "0.66.27",
3
+ "version": "0.66.29",
4
4
  "author": "Vincent Audoire <vincent@getpopsure.com>",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -24,7 +24,13 @@ const setup = (
24
24
  );
25
25
  };
26
26
 
27
- const inputTestId = 'ds-input-input';
27
+ const addressFieldTestIds = [
28
+ 'autocomplete',
29
+ 'autocomplete-house-number',
30
+ 'autocomplete-additional-info',
31
+ 'autocomplete-postcode',
32
+ 'autocomplete-city',
33
+ ];
28
34
 
29
35
  describe('AutocompleteAddress component', () => {
30
36
  it('Should show all address fields once a search is completed', async () => {
@@ -55,30 +61,30 @@ describe('AutocompleteAddress component', () => {
55
61
  }
56
62
  };
57
63
 
58
- const { getAllByTestId, getByDisplayValue, getByTestId } = setup();
64
+ const { getByDisplayValue, getByTestId } = setup();
59
65
 
60
- fireEvent.change(getByTestId(inputTestId), {
66
+ fireEvent.change(getByTestId('autocomplete'), {
61
67
  target: { value: 'Köpeniker' },
62
68
  });
63
69
 
64
- expect(getAllByTestId(inputTestId).length).toEqual(5);
70
+ addressFieldTestIds.forEach((testId) =>
71
+ expect(getByTestId(testId)).toBeInTheDocument()
72
+ );
65
73
  expect(getByDisplayValue('Köpeniker Strasse')).toBeVisible();
66
74
  });
67
75
 
68
76
  it('Should enable to enter the address manually', async () => {
69
77
  const callback = jest.fn();
70
- const { findByText, getAllByTestId, user } = setup(undefined, callback);
78
+ const { findByText, getByTestId, user } = setup(undefined, callback);
71
79
  const btn = await findByText('enter address manually');
72
80
 
73
81
  await user.click(btn);
74
82
 
75
83
  // fill out all fields
76
- const inputs = getAllByTestId(inputTestId);
77
-
78
- await user.type(inputs[0], 'Köpeniker Strasse');
79
- await user.type(inputs[1], '4000');
80
- await user.type(inputs[3], '10179');
81
- await user.type(inputs[4], 'Berlin');
84
+ await user.type(getByTestId('autocomplete'), 'Köpeniker Strasse');
85
+ await user.type(getByTestId('autocomplete-house-number'), '4000');
86
+ await user.type(getByTestId('autocomplete-postcode'), '10179');
87
+ await user.type(getByTestId('autocomplete-city'), 'Berlin');
82
88
 
83
89
  // callback should be called with a complete address
84
90
  expect(callback).toHaveBeenCalledWith(address);
@@ -265,6 +265,7 @@ const AutocompleteAddress = ({
265
265
  id="autocomplete"
266
266
  key="autocomplete-search"
267
267
  data-cy="autocomplete"
268
+ data-testid="autocomplete"
268
269
  type="text"
269
270
  placeholder={
270
271
  placeholders?.manualAddressEntry || 'Search for address'
@@ -275,6 +276,7 @@ const AutocompleteAddress = ({
275
276
  {hasLoadedGoogleAPI === false && (
276
277
  <div
277
278
  data-cy="google-api-loader"
279
+ data-testid="google-api-loader"
278
280
  className={styles['loading-spinner']}
279
281
  >
280
282
  <div className="ds-spinner ds-spinner__m" />
@@ -287,6 +289,7 @@ const AutocompleteAddress = ({
287
289
  <Input
288
290
  className="w100"
289
291
  data-cy="autocomplete"
292
+ data-testid="autocomplete"
290
293
  key="autocomplete-street"
291
294
  type="text"
292
295
  placeholder={placeholders?.street || 'Street'}
@@ -298,6 +301,7 @@ const AutocompleteAddress = ({
298
301
  <Input
299
302
  className={`wmx2 ${styles['house-number-input']}`}
300
303
  data-cy="autocomplete-house-number"
304
+ data-testid="autocomplete-house-number"
301
305
  key="autocomplete-house-number"
302
306
  placeholder={placeholders?.houseNumber || 'House number'}
303
307
  value={address?.houseNumber || ''}
@@ -309,6 +313,7 @@ const AutocompleteAddress = ({
309
313
  <Input
310
314
  className="mt16"
311
315
  data-cy="autocomplete-additional-info"
316
+ data-testid="autocomplete-additional-info"
312
317
  key="autocomplete-additional-info"
313
318
  placeholder={
314
319
  placeholders?.additionalInformation ||
@@ -323,6 +328,7 @@ const AutocompleteAddress = ({
323
328
  <Input
324
329
  className="w100"
325
330
  data-cy="autocomplete-postcode"
331
+ data-testid="autocomplete-postcode"
326
332
  key="autocomplete-postcode"
327
333
  placeholder={placeholders?.postcode || 'Postcode'}
328
334
  value={address?.postcode || ''}
@@ -333,6 +339,7 @@ const AutocompleteAddress = ({
333
339
  <Input
334
340
  className="w100"
335
341
  data-cy="autocomplete-city"
342
+ data-testid="autocomplete-city"
336
343
  key="autocomplete-city"
337
344
  placeholder={placeholders?.city || 'City'}
338
345
  value={address?.city || ''}
@@ -0,0 +1,22 @@
1
+ import { fireEvent, render, screen } from '../../util/testUtils';
2
+ import { DownloadButton } from '.';
3
+
4
+ describe('DownloadButton', () => {
5
+ it.each(['INITIAL', 'FAILED'] as const)(
6
+ 'exposes the %s download button as download-documents-button',
7
+ (downloadStatus) => {
8
+ const onDownload = jest.fn();
9
+
10
+ render(
11
+ <DownloadButton
12
+ downloadStatus={downloadStatus}
13
+ onDownload={onDownload}
14
+ />
15
+ );
16
+
17
+ fireEvent.click(screen.getByTestId('download-documents-button'));
18
+
19
+ expect(onDownload).toHaveBeenCalledTimes(1);
20
+ }
21
+ );
22
+ });
@@ -16,6 +16,7 @@ const InitialButton = ({ onDownload }: { onDownload: () => void }) => (
16
16
  leftIcon={<DownloadIcon />}
17
17
  onClick={onDownload}
18
18
  data-cy="download-documents-button"
19
+ data-testid="download-documents-button"
19
20
  >
20
21
  Download
21
22
  </Button>
@@ -0,0 +1,22 @@
1
+ import { render, screen } from '../../../util/testUtils';
2
+ import { AutoSuggestInput } from '.';
3
+
4
+ describe('AutoSuggestInput', () => {
5
+ it('exposes its input as suggest-multi-select-input', () => {
6
+ render(
7
+ <AutoSuggestInput
8
+ currentOption=""
9
+ suggestions={[]}
10
+ handleSuggestionSelected={jest.fn()}
11
+ onChange={jest.fn()}
12
+ handleSuggestionFetchRequest={jest.fn()}
13
+ handleSuggestionClearRequest={jest.fn()}
14
+ placeholder="Search countries"
15
+ />
16
+ );
17
+
18
+ expect(screen.getByTestId('suggest-multi-select-input').tagName).toBe(
19
+ 'INPUT'
20
+ );
21
+ });
22
+ });
@@ -56,6 +56,7 @@ export const AutoSuggestInput = ({
56
56
  {...autoSuggestInputProps}
57
57
  placeholder={placeholder}
58
58
  data-cy="suggest-multi-select-input"
59
+ data-testid="suggest-multi-select-input"
59
60
  />
60
61
  );
61
62
 
@@ -203,3 +203,46 @@ describe('Table on mobile with a parent-controlled section', () => {
203
203
  expect(screen.getByTestId('next-section-button')).toBeDisabled();
204
204
  });
205
205
  });
206
+
207
+ describe('Table on mobile with tabs navigation', () => {
208
+ const planTable: TableSectionData[] = [
209
+ {
210
+ rows: [
211
+ [
212
+ { text: 'Choose your plan' },
213
+ { text: 'Basic', cellId: 'basic' },
214
+ { text: 'Advanced', cellId: 'advanced', dataTestId: 'advanced-plan' },
215
+ ],
216
+ ],
217
+ },
218
+ ];
219
+
220
+ beforeAll(() => {
221
+ HTMLElement.prototype.scroll = jest.fn();
222
+ (useMediaQuery as jest.Mock).mockReturnValue(true);
223
+ });
224
+
225
+ afterAll(() => {
226
+ (useMediaQuery as jest.Mock).mockReturnValue(false);
227
+ });
228
+
229
+ it('forwards the header cell test ids to the tabs, preferring cell replacements', () => {
230
+ render(
231
+ <Table
232
+ title="Plans"
233
+ tableData={planTable}
234
+ mobileNavigationMode="tabs"
235
+ cellReplacements={{ basic: { dataTestId: 'basic-plan' } }}
236
+ />
237
+ );
238
+
239
+ expect(screen.getByRole('tab', { name: 'Basic' })).toHaveAttribute(
240
+ 'data-testid',
241
+ 'basic-plan'
242
+ );
243
+ expect(screen.getByRole('tab', { name: 'Advanced' })).toHaveAttribute(
244
+ 'data-testid',
245
+ 'advanced-plan'
246
+ );
247
+ });
248
+ });
@@ -58,6 +58,9 @@ const defaultTextOverrides = {
58
58
  hideDetails: 'Hide details',
59
59
  };
60
60
 
61
+ const getCellDataTestId = (cell?: Partial<TableCellData>) =>
62
+ cell && 'dataTestId' in cell ? cell.dataTestId : undefined;
63
+
61
64
  const Table = ({
62
65
  cellReplacements,
63
66
  className,
@@ -117,7 +120,12 @@ const Table = ({
117
120
  if (!cell.type) label = String(cell.text || '');
118
121
  else if (cell.type === 'CTA') label = String(cell.title || '');
119
122
  else if (cell.type === 'BUTTON') label = String(cell.buttonCaption || '');
120
- return { id: String(index), label };
123
+ const replacement = cell.cellId
124
+ ? cellReplacements?.[cell.cellId]
125
+ : undefined;
126
+ const dataTestId =
127
+ getCellDataTestId(replacement) ?? getCellDataTestId(cell);
128
+ return { id: String(index), label, dataTestId };
121
129
  }) ?? []
122
130
  : [];
123
131
 
@@ -6,6 +6,7 @@ import styles from './Tabs.module.scss';
6
6
  export interface TabItem {
7
7
  id: string;
8
8
  label: string;
9
+ dataTestId?: string;
9
10
  }
10
11
 
11
12
  export interface TabsProps {
@@ -54,6 +55,7 @@ const Tabs = ({ tabs, activeIndex, onTabChange, className }: TabsProps) => {
54
55
  })}
55
56
  onClick={() => onTabChange(index)}
56
57
  onKeyDown={(e) => handleKeyDown(e, index)}
58
+ data-testid={tab.dataTestId}
57
59
  >
58
60
  {tab.label}
59
61
  </button>