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 ( +
+ +
+ ); + } ); + }; + + return ( +
+
{ renderCategoryButtons() }
+
+ { getFilteredLanguages().map( ( language: Language ) => ( + + ) ) } +
+
+ ); +}; + +export default LanguagePicker; diff --git a/packages/components/src/language-picker/style.scss b/packages/components/src/language-picker/style.scss new file mode 100644 index 00000000000000..72aba1f48d50e9 --- /dev/null +++ b/packages/components/src/language-picker/style.scss @@ -0,0 +1,43 @@ +@import '~@wordpress/base-styles/breakpoints'; + +.language-picker__language-group { + width: 100%; +} + +.language-picker__language-group > span { + padding-bottom: 4px; + &.is-selected { + padding-bottom: 2px; + border-bottom: 2px solid var( ---studio-blue-40 ); + } +} + +.language-picker__regions-label { + margin: 6px 12px; + color: var( --studio-gray-50 ); + font-size: 13px; + text-transform: uppercase; +} + +.language-picker__page-content { + display: flex; +} + +.language-picker__category-filters { + min-width: 170px; + + @include break-small { + min-width: 220px; + margin-right: 60px; + } +} + +.language-picker__language-buttons { + display: flex; + flex-wrap: wrap; + align-content: flex-start; +} + +.language-picker__language-item { + width: 165px; +} diff --git a/packages/components/tsconfig.json b/packages/components/tsconfig.json index 636edf85cab0f4..cf9a6d74870eb9 100644 --- a/packages/components/tsconfig.json +++ b/packages/components/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "es5", + "target": "es2015", "module": "esnext", "allowJs": true, "checkJs": false, diff --git a/packages/composite-checkout/package.json b/packages/composite-checkout/package.json index dc9098c54daea9..c7e1b14fce3a76 100644 --- a/packages/composite-checkout/package.json +++ b/packages/composite-checkout/package.json @@ -36,7 +36,7 @@ }, "homepage": "https://github.com/Automattic/wp-calypso/tree/HEAD/packages/composite-checkout#readme", "dependencies": { - "@automattic/react-i18n": "^1.0.0-alpha.0", + "@automattic/react-i18n": "file:../react-i18n", "@emotion/core": "^10.0.27", "@emotion/styled": "^10.0.27", "@wordpress/data": "^4.22.3", diff --git a/yarn.lock b/yarn.lock index 0cd7351632124c..41bbb47fc5d77a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,6 +34,13 @@ schema-utils "^1.0.0" webpack-sources "^1.1.0" +"@automattic/react-i18n@file:packages/react-i18n": + version "1.0.0-alpha.0" + dependencies: + "@wordpress/compose" "1.x.x - 3.x.x" + "@wordpress/i18n" "^3.14.0" + tslib "^1.10.0" + "@automattic/react-virtualized@^9.21.2": version "9.21.2" resolved "https://registry.yarnpkg.com/@automattic/react-virtualized/-/react-virtualized-9.21.2.tgz#ea14243e7e7811eaa14daed3f0a6f4579208996f"