| @@ -1,71 +1,68 @@ | ||
| 1 | 1 | import React, { useState } from 'react' |
| 2 | 2 | import classnames from 'classnames' |
| 3 | -import { __ } from '@wordpress/i18n' | |
| 3 | +import { __, sprintf } from '@wordpress/i18n' | |
| 4 | 4 | import { WithRestAPIContext } from '../../hooks/useRestAPI' |
| 5 | -import { fetchQueryParam, updateQueryParams } from '../../utils/urls' | |
| 5 | +import { ScreenMetaSlot } from '../common/ScreenMetaSlot' | |
| 6 | +import { SubnavTabs, getTabFromQuery } from '../common/SubnavTabs' | |
| 6 | 7 | import { Toolbar } from '../common/Toolbar' |
| 7 | 8 | import { UploadForm } from './UploadForm/UploadForm' |
| 8 | 9 | import { MigrateForm } from './MigrateForm/MigrateForm' |
| 10 | +import type { SubnavTab} from '../common/SubnavTabs' | |
| 9 | 11 | import type { ReactNode } from 'react' |
| 10 | 12 | |
| 11 | -const TABS = ['upload', 'migrate'] as const | |
| 13 | +const TAB_QUERY_PARAM = 'tab' | |
| 12 | 14 | |
| 13 | -type TabType = typeof TABS[number] | |
| 14 | - | |
| 15 | -const TAB_CONTENT: Record<TabType, ReactNode> = { | |
| 16 | - upload: <UploadForm />, | |
| 17 | - migrate: <MigrateForm /> | |
| 15 | +interface ImportMenuTab extends SubnavTab<'upload' | 'migrate'> { | |
| 16 | + content: ReactNode | |
| 18 | 17 | } |
| 19 | 18 | |
| 20 | -const TAB_LABELS: Record<TabType, string> = { | |
| 21 | - upload: __('Upload snippets', 'code-snippets'), | |
| 22 | - migrate: __('Migrate from other plugins', 'code-snippets') | |
| 23 | -} | |
| 19 | +const TABS: ImportMenuTab[] = [ | |
| 20 | + { | |
| 21 | + name: 'upload', | |
| 22 | + label: __('Upload snippets', 'code-snippets'), | |
| 23 | + content: <UploadForm /> | |
| 24 | + }, | |
| 25 | + { | |
| 26 | + name: 'migrate', | |
| 27 | + label: __('Migrate from other plugins', 'code-snippets'), | |
| 28 | + content: <MigrateForm /> | |
| 29 | + } | |
| 30 | +] | |
| 24 | 31 | |
| 25 | -const isValidTab = (value: string): value is TabType => | |
| 26 | - TABS.includes(value as TabType) | |
| 27 | - | |
| 28 | -const getDefaultTab = (): TabType => { | |
| 29 | - const tabParam = fetchQueryParam('tab') | |
| 30 | - return tabParam && isValidTab(tabParam) ? tabParam : TABS[0] | |
| 31 | -} | |
| 32 | - | |
| 33 | 32 | export const ImportMenu: React.FC = () => { |
| 34 | - const [activeTab, setActiveTab] = useState<TabType>(getDefaultTab) | |
| 33 | + const [currentTab, setCurrentTab] = useState<ImportMenuTab>(() => getTabFromQuery(TABS, TAB_QUERY_PARAM)) | |
| 35 | 34 | |
| 36 | 35 | return ( |
| 37 | 36 | <> |
| 38 | 37 | <Toolbar /> |
| 39 | - <> | |
| 40 | - <h2>{__('Import Snippets', 'code-snippets')}</h2> | |
| 41 | 38 | |
| 42 | - <hr className="wp-header-end" /> | |
| 39 | + <SubnavTabs | |
| 40 | + className="import-type-nav" | |
| 41 | + ariaLabel={__('Import sources', 'code-snippets')} | |
| 42 | + tabs={TABS} | |
| 43 | + currentTab={currentTab} | |
| 44 | + queryParamName={TAB_QUERY_PARAM} | |
| 45 | + setCurrentTab={setCurrentTab} | |
| 46 | + /> | |
| 43 | 47 | |
| 44 | - <nav | |
| 45 | - className="nav-tab-wrapper" | |
| 46 | - aria-label={__('Import sources', 'code-snippets')} | |
| 47 | - > | |
| 48 | - {TABS.map(tab => | |
| 49 | - <button | |
| 50 | - key={tab} | |
| 51 | - type="button" | |
| 52 | - className={classnames('nav-tab', { 'nav-tab-active': tab === activeTab })} | |
| 53 | - onClick={() => { | |
| 54 | - setActiveTab(tab) | |
| 55 | - updateQueryParams({ tab }) | |
| 56 | - }} | |
| 57 | - > | |
| 58 | - {TAB_LABELS[tab]} | |
| 59 | - </button>)} | |
| 60 | - </nav> | |
| 48 | + <ScreenMetaSlot /> | |
| 61 | 49 | |
| 62 | - <WithRestAPIContext> | |
| 63 | - {TABS.map(tab => | |
| 64 | - <div key={tab} className={classnames('import-snippets-section', { 'active-section': tab === activeTab })}> | |
| 65 | - {TAB_CONTENT[tab]} | |
| 66 | - </div>)} | |
| 67 | - </WithRestAPIContext> | |
| 68 | - </> | |
| 50 | + <div className="snippets-page-header"> | |
| 51 | + <h1>{// translators: %s: label of the currently selected import tab. | |
| 52 | + sprintf(__('Import: %s', 'code-snippets'), currentTab.label)}</h1> | |
| 53 | + </div> | |
| 54 | + | |
| 55 | + <hr className="wp-header-end" /> | |
| 56 | + | |
| 57 | + <WithRestAPIContext> | |
| 58 | + {TABS.map(tab => | |
| 59 | + <div | |
| 60 | + key={tab.name} | |
| 61 | + className={classnames('import-snippets-section', { 'active-section': tab.name === currentTab.name })} | |
| 62 | + > | |
| 63 | + {tab.content} | |
| 64 | + </div>)} | |
| 65 | + </WithRestAPIContext> | |
| 69 | 66 | </> |
| 70 | 67 | ) |
| 71 | 68 | } |