@plone/volto 19.0.0-alpha.7 → 19.0.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -17,6 +17,14 @@ myst:
17
17
 
18
18
  <!-- towncrier release notes start -->
19
19
 
20
+ ## 19.0.0-alpha.8 (2025-10-22)
21
+
22
+ ### Internal
23
+
24
+ - Modernize and update `tsconfig.json` settings for core. @sneridagh [#7531.1](https://github.com/plone/volto/issues/7531.1)
25
+ - Refactor `LanguageSelector` into TypeScript. @sneridagh [#7531.2](https://github.com/plone/volto/issues/7531.2)
26
+ - Re-enable scripts pnpm build. Remove why. @sneridagh [#7532](https://github.com/plone/volto/issues/7532)
27
+
20
28
  ## 19.0.0-alpha.7 (2025-10-21)
21
29
 
22
30
  ### Breaking
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  }
10
10
  ],
11
11
  "license": "MIT",
12
- "version": "19.0.0-alpha.7",
12
+ "version": "19.0.0-alpha.8",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "git@github.com:plone/volto.git"
@@ -237,8 +237,8 @@
237
237
  "use-deep-compare-effect": "1.8.1",
238
238
  "uuid": "^8.3.2",
239
239
  "@plone/registry": "3.0.0-alpha.6",
240
- "@plone/scripts": "4.0.0-alpha.3",
241
- "@plone/volto-slate": "19.0.0-alpha.6"
240
+ "@plone/volto-slate": "19.0.0-alpha.6",
241
+ "@plone/scripts": "4.0.0-alpha.3"
242
242
  },
243
243
  "devDependencies": {
244
244
  "@babel/core": "^7.0.0",
@@ -279,8 +279,10 @@
279
279
  "@types/node": "^22.13.0",
280
280
  "@types/react": "^18",
281
281
  "@types/react-dom": "^18",
282
+ "@types/react-intl-redux": "^0.1.19",
282
283
  "@types/react-router-dom": "^5.3.3",
283
284
  "@types/react-test-renderer": "18.0.7",
285
+ "@types/redux-mock-store": "^1.5.0",
284
286
  "@types/uuid": "^9.0.2",
285
287
  "@typescript-eslint/eslint-plugin": "^7.7.0",
286
288
  "@typescript-eslint/parser": "^7.7.0",
@@ -363,8 +365,7 @@
363
365
  "webpack-bundle-analyzer": "4.10.1",
364
366
  "webpack-dev-server": "4.11.1",
365
367
  "webpack-node-externals": "3.0.0",
366
- "why": "0.6.2",
367
- "@plone/types": "2.0.0-alpha.6",
368
+ "@plone/types": "2.0.0-alpha.7",
368
369
  "@plone/volto-coresandbox": "1.0.0"
369
370
  },
370
371
  "volta": {
@@ -0,0 +1,89 @@
1
+ import { Link } from 'react-router-dom';
2
+
3
+ import { useSelector } from 'react-redux';
4
+ import cx from 'classnames';
5
+
6
+ import Helmet from '@plone/volto/helpers/Helmet/Helmet';
7
+ import langmap from '@plone/volto/helpers/LanguageMap/LanguageMap';
8
+ import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
9
+ import { toReactIntlLang } from '@plone/volto/helpers/Utils/Utils';
10
+
11
+ import { defineMessages, useIntl, type IntlShape } from 'react-intl';
12
+ import type {
13
+ Content,
14
+ GetSiteResponse,
15
+ GetTranslationResponse,
16
+ } from '@plone/types';
17
+
18
+ const messages = defineMessages({
19
+ switchLanguageTo: {
20
+ id: 'Switch to',
21
+ defaultMessage: 'Switch to',
22
+ },
23
+ });
24
+
25
+ type FormState = {
26
+ content: {
27
+ data: Content;
28
+ };
29
+ intl: IntlShape;
30
+ site: {
31
+ data: GetSiteResponse;
32
+ };
33
+ };
34
+
35
+ const LanguageSelector = ({
36
+ onClickAction = () => {},
37
+ }: {
38
+ onClickAction?: () => void;
39
+ }) => {
40
+ const intl = useIntl();
41
+ const currentLang = useSelector<FormState, IntlShape['locale']>(
42
+ (state) => state.intl.locale,
43
+ );
44
+ const translations = useSelector<
45
+ FormState,
46
+ GetTranslationResponse['items'] | undefined
47
+ >((state) => state.content.data?.['@components']?.translations?.items);
48
+ const isMultilingual = useSelector<
49
+ FormState,
50
+ GetSiteResponse['features']['multilingual']
51
+ >((state) => state.site.data.features?.multilingual);
52
+ const availableLanguages = useSelector<
53
+ FormState,
54
+ GetSiteResponse['plone.available_languages']
55
+ >((state) => state.site.data?.['plone.available_languages']);
56
+
57
+ return isMultilingual ? (
58
+ <div className="language-selector">
59
+ {availableLanguages?.map((lang) => {
60
+ const langKey = lang as keyof typeof langmap;
61
+ const translation = translations?.find(
62
+ (t: { language: string }) => t.language === lang,
63
+ );
64
+ return (
65
+ <Link
66
+ aria-label={`${intl.formatMessage(
67
+ messages.switchLanguageTo,
68
+ )} ${langmap[langKey].nativeName.toLowerCase()}`}
69
+ className={cx({ selected: toReactIntlLang(lang) === currentLang })}
70
+ to={translation ? flattenToAppURL(translation['@id']) : `/${lang}`}
71
+ title={langmap[langKey].nativeName}
72
+ onClick={() => {
73
+ onClickAction();
74
+ }}
75
+ key={`language-selector-${lang}`}
76
+ >
77
+ {langmap[langKey].nativeName}
78
+ </Link>
79
+ );
80
+ })}
81
+ </div>
82
+ ) : (
83
+ <Helmet>
84
+ <html lang={toReactIntlLang(currentLang)} />
85
+ </Helmet>
86
+ );
87
+ };
88
+
89
+ export default LanguageSelector;
package/tsconfig.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "target": "ESNext",
4
- "lib": ["DOM", "DOM.Iterable", "ESNext"],
3
+ "target": "es2022",
4
+ "lib": ["es2022", "dom", "dom.iterable"],
5
5
  "types": ["vitest/globals", "jest"],
6
- "module": "commonjs",
6
+ "module": "preserve",
7
7
  "allowJs": true,
8
8
  "skipLibCheck": true,
9
9
  "esModuleInterop": true,
@@ -11,7 +11,6 @@
11
11
  "strict": true,
12
12
  "forceConsistentCasingInFileNames": true,
13
13
  "strictPropertyInitialization": false,
14
- "moduleResolution": "Node",
15
14
  "resolveJsonModule": true,
16
15
  "isolatedModules": true,
17
16
  "noEmit": true,
@@ -1,11 +1,4 @@
1
+ declare const LanguageSelector: ({ onClickAction, }: {
2
+ onClickAction?: () => void;
3
+ }) => import("react/jsx-runtime").JSX.Element;
1
4
  export default LanguageSelector;
2
- declare function LanguageSelector(props: any): import("react/jsx-runtime").JSX.Element;
3
- declare namespace LanguageSelector {
4
- namespace propTypes {
5
- let onClickAction: any;
6
- }
7
- namespace defaultProps {
8
- export function onClickAction_1(): void;
9
- export { onClickAction_1 as onClickAction };
10
- }
11
- }
@@ -50,6 +50,7 @@ declare namespace reducers {
50
50
  export { site };
51
51
  export { navroot };
52
52
  }
53
+ import { intlReducer } from 'react-intl-redux';
53
54
  import reduxAsyncConnect from './asyncConnect/asyncConnect';
54
55
  import actions from '@plone/volto/reducers/actions/actions';
55
56
  import addons from '@plone/volto/reducers/addons/addons';
package/package-why.json DELETED
@@ -1,34 +0,0 @@
1
- {
2
- "scripts": {
3
- "postinstall": "Description for `npm run postinstall` command",
4
- "analyze": "Description for `npm run analyze` command",
5
- "start": "Description for `npm run start` command",
6
- "build": "Description for `npm run build` command",
7
- "build:clean": "Description for `npm run build:clean` command",
8
- "dist:clean": "Description for `npm run dist:clean` command",
9
- "build:dist": "Description for `npm run build:dist` command",
10
- "test": "Description for `npm run test` command",
11
- "test:ci": "Description for `npm run test:ci` command",
12
- "test:husky": "Description for `npm run test:husky` command",
13
- "test:debug": "Description for `npm run test:debug` command",
14
- "start:prod": "Description for `npm run start:prod` command",
15
- "start:dist": "Description for `npm run start:dist` command",
16
- "prettier": "Description for `npm run prettier` command",
17
- "prettier:fix": "Description for `npm run prettier:fix` command",
18
- "stylelint": "Description for `npm run stylelint` command",
19
- "stylelint:overrides": "Description for `npm run stylelint:overrides` command",
20
- "stylelint:fix": "Description for `npm run stylelint:fix` command",
21
- "lint": "Description for `npm run lint` command",
22
- "lint:fix": "Description for `npm run lint:fix` command",
23
- "i18n": "Description for `npm run i18n` command",
24
- "i18n:ci": "Description for `npm run i18n:ci` command",
25
- "stylelint:patches": "Description for `npm run stylelint:patches` command",
26
- "patches": "Description for `npm run patches` command",
27
- "dry-release": "Description for `npm run dry-release` command",
28
- "release": "Description for `npm run release` command",
29
- "release-major-alpha": "Description for `npm run release-major-alpha` command",
30
- "release-alpha": "Description for `npm run release-alpha` command",
31
- "storybook": "Description for `npm run storybook` command",
32
- "build-storybook": "Description for `npm run build-storybook` command"
33
- }
34
- }
@@ -1,79 +0,0 @@
1
- /**
2
- * Language selector component.
3
- * @module components/LanguageSelector/LanguageSelector
4
- */
5
-
6
- import React from 'react';
7
- import PropTypes from 'prop-types';
8
- import { Link } from 'react-router-dom';
9
-
10
- import { useSelector } from 'react-redux';
11
- import cx from 'classnames';
12
- import find from 'lodash/find';
13
- import map from 'lodash/map';
14
-
15
- import Helmet from '@plone/volto/helpers/Helmet/Helmet';
16
- import langmap from '@plone/volto/helpers/LanguageMap/LanguageMap';
17
- import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
18
- import { toReactIntlLang } from '@plone/volto/helpers/Utils/Utils';
19
-
20
- import { defineMessages, useIntl } from 'react-intl';
21
-
22
- const messages = defineMessages({
23
- switchLanguageTo: {
24
- id: 'Switch to',
25
- defaultMessage: 'Switch to',
26
- },
27
- });
28
-
29
- const LanguageSelector = (props) => {
30
- const intl = useIntl();
31
- const currentLang = useSelector((state) => state.intl.locale);
32
- const translations = useSelector(
33
- (state) => state.content.data?.['@components']?.translations?.items,
34
- );
35
- const isMultilingual = useSelector(
36
- (state) => state.site.data.features?.multilingual,
37
- );
38
- const availableLanguages = useSelector(
39
- (state) => state.site.data?.['plone.available_languages'],
40
- );
41
-
42
- return isMultilingual ? (
43
- <div className="language-selector">
44
- {map(availableLanguages, (lang) => {
45
- const translation = find(translations, { language: lang });
46
- return (
47
- <Link
48
- aria-label={`${intl.formatMessage(
49
- messages.switchLanguageTo,
50
- )} ${langmap[lang].nativeName.toLowerCase()}`}
51
- className={cx({ selected: toReactIntlLang(lang) === currentLang })}
52
- to={translation ? flattenToAppURL(translation['@id']) : `/${lang}`}
53
- title={langmap[lang].nativeName}
54
- onClick={() => {
55
- props.onClickAction();
56
- }}
57
- key={`language-selector-${lang}`}
58
- >
59
- {langmap[lang].nativeName}
60
- </Link>
61
- );
62
- })}
63
- </div>
64
- ) : (
65
- <Helmet>
66
- <html lang={toReactIntlLang(currentLang)} />
67
- </Helmet>
68
- );
69
- };
70
-
71
- LanguageSelector.propTypes = {
72
- onClickAction: PropTypes.func,
73
- };
74
-
75
- LanguageSelector.defaultProps = {
76
- onClickAction: () => {},
77
- };
78
-
79
- export default LanguageSelector;