PluginProbe
Code Snippets / 3.10.2
Code Snippets v3.10.2
4.0.0-beta.2 3.10.2 3.10.1 3.10.0 3.10.0-beta.2 3.10.0-beta.1 4.0.0-beta.1 3.9.6 trunk 2.10.0 2.10.1 2.12.0 2.12.1 2.13.0 2.13.1 2.13.2 2.13.3 2.14.0 2.14.1 2.14.2 2.14.3 2.14.4 2.14.5 2.14.6 3.0.0 All 65 releases
code-snippets / js / components / common / SubnavTabs.tsx

SubnavTabs.tsx in Code Snippets 3.10.2, at js/components/common/SubnavTabs.tsx

90 lines 2.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import classnames from 'classnames'
2 import { __ } from '@wordpress/i18n'
3 import React from 'react'
4 import { isLicensed } from '../../utils/screen'
5 import { useHorizontalScrollOverflow } from '../../hooks/useHorizontalScrollOverflow'
6 import { fetchQueryParam, updateQueryParams } from '../../utils/urls'
7
8 export interface SubnavTab<T extends string> {
9 name: T
10 label: string
11 pro?: boolean
12 }
13
14 export const getTabFromQuery = <Tab extends SubnavTab<string>>(
15 tabs: Tab[],
16 queryParamName: string
17 ): Tab => {
18 const tabParam = fetchQueryParam(queryParamName)
19
20 for (const tab of tabs) {
21 if (tab.name === tabParam) {
22 return tab
23 }
24 }
25
26 return tabs[0]
27 }
28
29 export interface SubnavTabsProps<Tab extends SubnavTab<string>> {
30 tabs: readonly Tab[]
31 ariaLabel: string
32 className?: string
33 currentTab: Tab
34 getTabCount?: (tab: Tab) => number | undefined
35 setCurrentTab: (tab: Tab) => void
36 queryParamName?: string
37 }
38
39 export const SubnavTabs = <Tab extends SubnavTab<string>>({
40 tabs,
41 ariaLabel,
42 className,
43 currentTab,
44 getTabCount,
45 setCurrentTab,
46 queryParamName,
47 }: SubnavTabsProps<Tab>) => {
48 const { atStart, atEnd, scrollRef } = useHorizontalScrollOverflow()
49
50 return (
51 <div
52 className={classnames('snippet-type-nav-wrapper', {
53 'has-scroll-start': !atStart,
54 'has-scroll-end': !atEnd
55 })}
56 >
57 <nav ref={scrollRef} className={classnames('snippet-type-nav', className)} aria-label={ariaLabel}>
58 <ul>
59 {tabs.map(tab => {
60 const count = getTabCount?.(tab)
61
62 return (
63 <li key={tab.name}>
64 <button
65 type="button"
66 className={classnames('snippet-type-link', `${tab.name}-subnav-link`, {
67 'active-type': tab.name === currentTab.name
68 })}
69 aria-current={tab.name === currentTab.name ? 'page' : undefined}
70 onClick={() => {
71 setCurrentTab(tab)
72
73 if (queryParamName) {
74 updateQueryParams({ [queryParamName]: tab.name })
75 }
76 }}
77 >
78 <span>{tab.label}</span>
79 {count && <span className="subnav-count">{count}</span>}
80 {tab.pro && !isLicensed() && <span className="pro-chip">{__('Pro', 'code-snippets')}</span>}
81 </button>
82 </li>
83 )
84 })}
85 </ul>
86 </nav>
87 </div>
88 )
89 }
90