Skip to content

Commit 5fc37f6

Browse files
committed
fix(ui-drilldown): fix for prevent option selection when Drilldown or its sub-components get disabled prop
1 parent 04e93c8 commit 5fc37f6

File tree

5 files changed

+120
-7
lines changed

5 files changed

+120
-7
lines changed

packages/ui-drilldown/src/Drilldown/DrilldownGroup/__tests__/DrilldownGroup.test.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,26 @@ describe('<Drilldown.Group />', () => {
234234
expect(option_1).not.toHaveAttribute('aria-disabled')
235235
expect(option_2).not.toHaveAttribute('aria-disabled')
236236
})
237+
238+
it('should not allow selection if the Drilldown.Group is disabled', async () => {
239+
render(
240+
<Drilldown rootPageId="page0">
241+
<Drilldown.Page id="page0">
242+
<Drilldown.Group id="group0" selectableType="multiple" disabled>
243+
<Drilldown.Option id="opt1">Disabled Option</Drilldown.Option>
244+
</Drilldown.Group>
245+
</Drilldown.Page>
246+
</Drilldown>
247+
)
248+
const optionItemContainer = screen.getByLabelText('Disabled Option')
249+
const optionContent = screen.getByText('Disabled Option')
250+
251+
expect(optionItemContainer).toHaveAttribute('aria-checked', 'false')
252+
253+
await userEvent.click(optionContent)
254+
255+
expect(optionItemContainer).toHaveAttribute('aria-checked', 'false')
256+
})
237257
})
238258

239259
describe('role prop', () => {

packages/ui-drilldown/src/Drilldown/DrilldownOption/__tests__/DrilldownOption.test.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,28 @@ describe('<Drilldown.Option />', () => {
231231

232232
expect(option).toHaveAttribute('aria-disabled', 'true')
233233
})
234+
235+
it('should not allow selection if the Drilldown.Option itself is disabled', async () => {
236+
render(
237+
<Drilldown rootPageId="page0">
238+
<Drilldown.Page id="page0">
239+
<Drilldown.Group id="group0" selectableType="multiple">
240+
<Drilldown.Option id="opt1" disabled>
241+
Disabled Option
242+
</Drilldown.Option>
243+
</Drilldown.Group>
244+
</Drilldown.Page>
245+
</Drilldown>
246+
)
247+
const optionItemContainer = screen.getByLabelText('Disabled Option')
248+
const optionContent = screen.getByText('Disabled Option')
249+
250+
expect(optionItemContainer).toHaveAttribute('aria-checked', 'false')
251+
252+
await userEvent.click(optionContent)
253+
254+
expect(optionItemContainer).toHaveAttribute('aria-checked', 'false')
255+
})
234256
})
235257

236258
describe('href prop', () => {

packages/ui-drilldown/src/Drilldown/DrilldownPage/__tests__/DrilldownPage.test.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,26 @@ describe('<Drilldown.Page />', () => {
315315
})
316316
})
317317

318+
it('should not allow selection if the Drilldown.Page is disabled', async () => {
319+
render(
320+
<Drilldown rootPageId="page0">
321+
<Drilldown.Page id="page0" disabled>
322+
<Drilldown.Group id="group0" selectableType="multiple">
323+
<Drilldown.Option id="opt1">Disabled Option</Drilldown.Option>
324+
</Drilldown.Group>
325+
</Drilldown.Page>
326+
</Drilldown>
327+
)
328+
const optionItemContainer = screen.getByLabelText('Disabled Option')
329+
const optionContent = screen.getByText('Disabled Option')
330+
331+
expect(optionItemContainer).toHaveAttribute('aria-checked', 'false')
332+
333+
await userEvent.click(optionContent)
334+
335+
expect(optionItemContainer).toHaveAttribute('aria-checked', 'false')
336+
})
337+
318338
it("shouldn't make header Back options disabled", async () => {
319339
render(
320340
<Drilldown rootPageId="page0">

packages/ui-drilldown/src/Drilldown/__tests__/Drilldown.test.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,49 @@ describe('<Drilldown />', () => {
183183
expect(option).toHaveAttribute('aria-disabled', 'true')
184184
})
185185
})
186+
187+
it('should not allow selection if the main Drilldown is disabled', async () => {
188+
render(
189+
<Drilldown rootPageId="page0" disabled>
190+
<Drilldown.Page id="page0">
191+
<Drilldown.Group id="group0" selectableType="multiple">
192+
<Drilldown.Option id="opt1">Disabled Option</Drilldown.Option>
193+
</Drilldown.Group>
194+
</Drilldown.Page>
195+
</Drilldown>
196+
)
197+
const optionItemContainer = screen.getByLabelText('Disabled Option')
198+
const optionContent = screen.getByText('Disabled Option')
199+
200+
expect(optionItemContainer).toHaveAttribute('aria-checked', 'false')
201+
202+
await userEvent.click(optionContent)
203+
204+
expect(optionItemContainer).toHaveAttribute('aria-checked', 'false')
205+
})
206+
207+
it('should always allow back navigation even if the page is disabled', async () => {
208+
render(
209+
<Drilldown rootPageId="page0">
210+
<Drilldown.Page id="page0" renderTitle="First Page">
211+
<Drilldown.Option id="opt1" subPageId="page1">
212+
Go to Disabled Page
213+
</Drilldown.Option>
214+
</Drilldown.Page>
215+
<Drilldown.Page id="page1" renderTitle="Disabled Page" disabled>
216+
</Drilldown.Page>
217+
</Drilldown>
218+
)
219+
220+
// 1. Navigate to the disabled page
221+
await userEvent.click(screen.getByText('Go to Disabled Page'))
222+
expect(screen.getByText('Disabled Page')).toBeInTheDocument()
223+
224+
await userEvent.click(screen.getByText('Back'))
225+
226+
// 4. Verify we have successfully navigated back
227+
expect(screen.getByText('First Page')).toBeInTheDocument()
228+
})
186229
})
187230

188231
describe('as prop', () => {

packages/ui-drilldown/src/Drilldown/index.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -787,13 +787,21 @@ class Drilldown extends Component<DrilldownProps, DrilldownState> {
787787
// TODO: this line can be removed when React 16 is no longer supported
788788
event.persist()
789789

790-
if (
791-
!id ||
792-
!selectedOption ||
793-
selectedOption.props.disabled ||
794-
(event.target as HTMLElement).getAttribute('disabled') ||
795-
(event.target as HTMLElement).getAttribute('aria-disabled')
796-
) {
790+
if (!id || !selectedOption) {
791+
event.preventDefault()
792+
event.stopPropagation()
793+
return
794+
}
795+
796+
const isOptionDisabled =
797+
id !== this._headerBackId && (
798+
this.props.disabled ||
799+
this.currentPage?.disabled ||
800+
selectedOption.groupProps?.disabled ||
801+
selectedOption.props.disabled
802+
)
803+
804+
if (isOptionDisabled) {
797805
event.preventDefault()
798806
event.stopPropagation()
799807
return

0 commit comments

Comments
 (0)