Mark James
Mark James

Reputation: 558

How to handle onKeyDown/Up opening the list items in React

I have a list of sports news and when a user clicks on a document --> doc is open in `right-slider.

Need to implement that when a user clicks on document, after that he should be able to open under and above documents by pressing onKeyDown and onKeyUp.

This is how the list of news looks when one document is open:

enter image description here

Now when doc is open if user clicks onKeyDown open / select next doc.

Don't know how to make onKeyDown works in this case.

This is a Document component:

const NewsItem = ({
  cover_image,
  title,
  body,
  publishing_date,
  author_name,
  topics,
  handleClick,
  isFullDocViewActive,
  isRowGridActive,
  hideText,
  style,
  className,
  id,
  type,
  isSliderView,
  newsTextCssClass,
  paragraphTextCssClass,
  permalink,
  isUnreadDoc,
  t
}) => (
  <Context.Consumer>
    {({ language }) => {
      const topicNames = topics.map((topic) => topic.name[language]);
      return (
        <div
          style={style}
          className={`${className || ''} ${
            isRowGridActive ? 'news-row-grid' : 'news-column-grid'
          } ${isUnreadDoc ? 'selected-doc' : ''}`}
          onKeyDown={(e) => {
            console.warn('on Click down', e.key);
          }}
        >
          <div className={isFullDocViewActive || isSliderView ? 'border-none' : 'border-bottom'}>
            <div className="card-labels">
              <div className="text-labels">
                {getLabelStatus(publishing_date, t)}
                {topicNames.length ? (
                  <span className="trending-label">
                    <span className="trending-icon">
                      <i className="material-icons md-19 trending-icon">trending_up</i>
                    </span>
                    <span className="topics-label" title={topicNames.join(', ')}>
                      {topicNames[0]}
                    </span>
                  </span>
                ) : (
                  ''
                )}
              </div>
              <div className="btn-icons">
                <a className="icon-btn" onClick={() => toClipboard(body[language])} role="button">
                  <i className="material-icons md-20">file_copy</i>
                </a>
                <a href={permalink} rel="noopener noreferrer" target="_blank" className="icon-btn">
                  <i className="material-icons md-21">open_in_new</i>
                </a>
              </div>
            </div>
            <div
              className="card-content-wrapper"
              role="button"
              onClick={() => handleClick && handleClick(id)}
            >
              <div className="card-content">
                <div className="card-image" style={getBackgroundImage(cover_image)} />
                <div className="card-title-section">
                  <p>
                    <span className="card-news-date">
                      {new Date(publishing_date).toLocaleDateString('ch')}
                    </span>
                    <span className="card-grey-text">
                      {type} - {author_name}
                    </span>
                  </p>
                  <p className="card-news-title" id={id}>
                    {title[language] || body[language]}
                  </p>
                </div>
              </div>
              {!hideText ? (
                <div className={newsTextCssClass || 'card-news-text'}>
                  <p className={paragraphTextCssClass}>{body[language]}</p>
                </div>
              ) : (
                ''
              )}
            </div>
          </div>
        </div>
      );
    }}
  </Context.Consumer>
);

Upvotes: 0

Views: 362

Answers (1)

Mteuahasan
Mteuahasan

Reputation: 520

Assuming the parent component contains both the doc's list and the drawer, you could bind a keyDown event to document on mount (and unbind it on unmount) :

import React, { useEffect } from React

const parentComponent = () => {
  useEffect(() => {
    document.addEventListener('keydown', (e) => {
      handleKeyDown(e)
    })
    return (() => {
      document.removeEventListener('keydown', handleKeyDown)
    })
  })
}

Then in the handleKeyDown function increment or decrement the index of the selected doc (the one in the drawer). And pass it to the drawer component

Upvotes: 1

Related Questions