diff --git a/packages/components/package.json b/packages/components/package.json index 345b1f5ab11866..0c8e4a6eb93089 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -28,7 +28,11 @@ ], "types": "dist/types", "dependencies": { + "@automattic/react-i18n": "file:../react-i18n", "@babel/runtime": "^7.11.1", + "@wordpress/base-styles": "^2.0.1", + "@wordpress/components": "^10.0.5", + "@wordpress/i18n": "^3.14.0", "classnames": "^2.2.6", "gridicons": "^3.3.1", "lodash": "^4.17.15", diff --git a/packages/components/src/index.js b/packages/components/src/index.js index 42c60c5985825e..670865e23b6526 100644 --- a/packages/components/src/index.js +++ b/packages/components/src/index.js @@ -2,6 +2,7 @@ export { default as Button } from './button'; export { default as Card } from './card'; export { default as CompactCard } from './card/compact'; export { default as Dialog } from './dialog'; +export { default as LanguagePicker } from './language-picker'; export { default as ProductIcon } from './product-icon'; export { default as ProgressBar } from './progress-bar'; export { default as Ribbon } from './ribbon'; diff --git a/packages/components/src/language-picker/index.tsx b/packages/components/src/language-picker/index.tsx new file mode 100644 index 00000000000000..aa6d270474857c --- /dev/null +++ b/packages/components/src/language-picker/index.tsx @@ -0,0 +1,116 @@ +/** + * External dependencies + */ +import React, { useState } from 'react'; +import { useI18n } from '@automattic/react-i18n'; +import { find, includes } from 'lodash'; + +/** + * WordPress dependencies + */ +import { I18n } from '@wordpress/i18n'; +import { Button } from '@wordpress/components'; + +/** + * Style dependencies + */ +import './style.scss'; + +export type LanguageGroup = { + id: string; + name: ( translate: I18n[ '__' ] ) => string; + subTerritories?: string[]; + countries?: string[]; + default?: boolean; +}; + +type LanguageSlug = string; +type WPLocale = string; + +type BaseLanguage = { + langSlug: LanguageSlug; + name: string; + popular?: number; + rtl?: boolean; + territories: string[]; + value: number; + wpLocale: WPLocale | ''; +}; + +type SubLanguage = BaseLanguage & { parentLangSlug: string }; + +export type Language = BaseLanguage | SubLanguage; + +type Props = { + onSelectLanguage: ( language: Language ) => void; + languages: Language[]; + languageGroups: LanguageGroup[]; + defaultLananguageGroupId: string; +}; + +const LanguagePicker = ( { + onSelectLanguage, + languages, + languageGroups, + defaultLananguageGroupId, +}: Props ) => { + const { __ } = useI18n(); + const [ filter, setFilter ] = useState< string >( defaultLananguageGroupId ); + + const getFilteredLanguages = () => { + switch ( filter ) { + case 'popular': + return languages + .filter( ( language: Language ) => language.popular ) + .sort( + ( a: Language, b: Language ) => ( a.popular as number ) - ( b.popular as number ) + ); + default: { + const languageGroup = find( languageGroups, ( l: LanguageGroup ) => l.id === filter ); + const subTerritories = languageGroup ? languageGroup.subTerritories : []; + return languages + .filter( ( language: Language ) => + language.territories.some( ( t ) => includes( subTerritories, t ) ) + ) + .sort( ( a: Language, b: Language ) => a.name.localeCompare( b.name ) ); + } + } + }; + + const renderCategoryButtons = () => { + return languageGroups.map( ( languageGroup ) => { + const isSelected = filter === languageGroup.id; + + const onClick = () => { + setFilter( languageGroup.id ); + }; + return ( +