From 7aba37ba4a2249a1964d7eff5a69863dd5595461 Mon Sep 17 00:00:00 2001 From: Pranay Kothapalli Date: Sun, 30 Jun 2024 11:14:40 +0530 Subject: [PATCH] Add useRef and event handlers for AccordionItem --- .../ui/Accordion/Accordion.stories.js | 1 - .../ui/Accordion/shards/AccordionItem.tsx | 23 +++++++++++++++---- .../ui/Accordion/shards/AccordionRoot.tsx | 10 ++++---- .../ui/Accordion/shards/AccordionTrigger.tsx | 14 ++++------- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/components/ui/Accordion/Accordion.stories.js b/src/components/ui/Accordion/Accordion.stories.js index 9cd0229f..ca6e86a9 100644 --- a/src/components/ui/Accordion/Accordion.stories.js +++ b/src/components/ui/Accordion/Accordion.stories.js @@ -9,7 +9,6 @@ export default {
-
, diff --git a/src/components/ui/Accordion/shards/AccordionItem.tsx b/src/components/ui/Accordion/shards/AccordionItem.tsx index b3141150..a43d4c7c 100644 --- a/src/components/ui/Accordion/shards/AccordionItem.tsx +++ b/src/components/ui/Accordion/shards/AccordionItem.tsx @@ -1,4 +1,4 @@ -import React, {useState, useContext, useId, useEffect} from 'react'; +import React, {useState, useContext, useId, useEffect, useRef} from 'react'; import {AccordionContext} from '../contexts/AccordionContext'; import {AccordionItemContext} from '../contexts/AccordionItemContext'; @@ -10,6 +10,7 @@ export type AccordionItemProps = { } const AccordionItem: React.FC = ({children, value, className='', ...props}) => { + const accordionItemRef = useRef(null); const [itemValue, setItemValue] = useState(value); const {rootClass, activeItem, focusItem} = useContext(AccordionContext); @@ -31,10 +32,25 @@ const AccordionItem: React.FC = ({children, value, className shouldAddFocusDataAttribute = true; } + const handleBlurEvent = () => { + // if clicked outside of the accordion, set activeItem to null + const elem = accordionItemRef.current; + // remove `data-rad-ui-focus-element` attribute as we are not focusing on this item anymore + elem.removeAttribute('data-rad-ui-focus-element'); + }; + + const handleClickEvent = () => { + // if clicked outside of the accordion, set activeItem to null + const elem = accordionItemRef.current; + // remove `data-rad-ui-focus-element` attribute as we are not focusing on this item anymore + elem.setAttribute('data-rad-ui-focus-element', ''); + }; + return ( - +
= ({children, value, className aria-hidden={!isOpen} data-state={isOpen ? 'open' : 'closed'} data-rad-ui-batch-element - // need to add `data-rad-ui-focus-element` when itemValue === activeItem - // we set it here - {...shouldAddFocusDataAttribute ? {'data-rad-ui-focus-element': ''} : {}} diff --git a/src/components/ui/Accordion/shards/AccordionRoot.tsx b/src/components/ui/Accordion/shards/AccordionRoot.tsx index 51a0151f..86994e0a 100644 --- a/src/components/ui/Accordion/shards/AccordionRoot.tsx +++ b/src/components/ui/Accordion/shards/AccordionRoot.tsx @@ -2,7 +2,7 @@ import React, {useState, useRef, useEffect} from 'react'; import {customClassSwitcher} from '~/core'; import {AccordionContext} from '../contexts/AccordionContext'; -import {getAllBatchElements, getActiveBatchItem, getNextBatchItem, getPrevBatchItem} from '~/core/batches'; +import {getAllBatchElements, getNextBatchItem, getPrevBatchItem} from '~/core/batches'; const COMPONENT_NAME = 'Accordion'; @@ -13,14 +13,13 @@ export type AccordionRootProps = { const AccordionRoot= ({children, customRootClass}: AccordionRootProps) => { const accordionRef = useRef(null); - - const [activeItem, setActiveItem] = useState(null); - const [focusItem, setFocusItem] = useState(null); const rootClass = customClassSwitcher(customRootClass, COMPONENT_NAME); + const [activeItem, setActiveItem] = useState(null); // keeps track of the active item, stores the + const [focusItem, setFocusItem] = useState(null); // stores the id of the item that should be focused + const focusNextItem = () => { - // get button const batches = getAllBatchElements(accordionRef.current); const nextItem = getNextBatchItem(batches); setFocusItem(nextItem); @@ -30,6 +29,7 @@ const AccordionRoot= ({children, customRootClass}: AccordionRootProps) => { button?.focus(); } }; + const focusPrevItem = () => { const batches = getAllBatchElements(accordionRef.current); const prevItem = getPrevBatchItem(batches); diff --git a/src/components/ui/Accordion/shards/AccordionTrigger.tsx b/src/components/ui/Accordion/shards/AccordionTrigger.tsx index 8e191d2a..f4b19b23 100644 --- a/src/components/ui/Accordion/shards/AccordionTrigger.tsx +++ b/src/components/ui/Accordion/shards/AccordionTrigger.tsx @@ -1,7 +1,6 @@ -import React, {useContext, useState} from 'react'; +import React, {useContext} from 'react'; import {AccordionContext} from '../contexts/AccordionContext'; import {AccordionItemContext} from '../contexts/AccordionItemContext'; -import {getAllBatchElements, getActiveBatchItem, getNextBatchItem, getPrevBatchItem} from '~/core/batches'; type AccordionTriggerProps = { @@ -13,18 +12,14 @@ type AccordionTriggerProps = { }; const AccordionTrigger: React.FC = ({children, index, activeIndex, className=''}) => { - const {setActiveItem, rootClass, focusNextItem, focusPrevItem, activeItem, setFocusItem, accordionRef} = useContext(AccordionContext); + const {setActiveItem, rootClass, focusNextItem, focusPrevItem, activeItem} = useContext(AccordionContext); - const {itemValue} = useContext(AccordionItemContext); + const {itemValue, handleBlurEvent, handleClickEvent} = useContext(AccordionItemContext); const onClickHandler = () => { setActiveItem(itemValue); - - const batches = getAllBatchElements(accordionRef.current); - console.log(batches); - const activeItem = getActiveBatchItem(batches); - console.log(activeItem); + handleClickEvent(); }; @@ -32,6 +27,7 @@ const AccordionTrigger: React.FC = ({children, index, act