-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Expand file tree
/
Copy pathInstallationMethodDropdown.tsx
More file actions
90 lines (79 loc) · 3.48 KB
/
InstallationMethodDropdown.tsx
File metadata and controls
90 lines (79 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
'use client';
import Select from '@node-core/ui-components/Common/Select';
import { useTranslations } from 'next-intl';
import { use, useEffect, useMemo } from 'react';
import { ReleaseContext } from '#site/providers/releaseProvider';
import { nextItem, INSTALL_METHODS, parseCompat } from '#site/util/download';
import type { InstallationMethod } from '#site/types/release';
import type { FC } from 'react';
const InstallationMethodDropdown: FC = () => {
const release = use(ReleaseContext);
const t = useTranslations();
// We parse the compatibility of the dropdown items
const parsedInstallMethods = useMemo(
() => parseCompat(INSTALL_METHODS, release),
// We only want to react on the change of the OS and Version
// eslint-disable-next-line @eslint-react/exhaustive-deps
[release.os, release.version]
);
// We group Platforms on the Platform Dropdown to provide the User
// understanding of what is recommended/official and what is not.
const grouppedMethods = useMemo(
() => [
{
label: t('layouts.download.dropdown.platformGroups.official'),
items: parsedInstallMethods.filter(({ recommended }) => recommended),
},
{
label: t('layouts.download.dropdown.platformGroups.unofficial'),
items: parsedInstallMethods.filter(({ recommended }) => !recommended),
},
],
// We only want to react on the change of the parsedPlatforms
// eslint-disable-next-line @eslint-react/exhaustive-deps
[parsedInstallMethods]
);
useEffect(() => {
// We should only define the initial Platform if the current platform is empty
// (aka has not yet been set) and the OS has finished loading (in the sense that)
// `detectOS` has finished running and decided what platform we are running on.
if (release.os !== 'LOADING' && release.installMethod === '') {
const installationMethod =
// Sets either the utmost recommended platform or the first non-disabled one
// Note that the first item of groupped platforms is always the recommended one
nextItem<InstallationMethod | ''>('', grouppedMethods[0].items) ||
nextItem<InstallationMethod | ''>('', parsedInstallMethods);
// This will never return an empty string as there should always be an item
// when the OS has finished loading for a given installation method
release.setInstallMethod(installationMethod as InstallationMethod);
}
// eslint-disable-next-line @eslint-react/exhaustive-deps
}, [parsedInstallMethods, release.installMethod, release.os]);
// We set the Platform to the next available platform when the current
// one is not valid anymore due to OS or Version changes
useEffect(
() => {
if (release.os !== 'LOADING' && release.installMethod !== '') {
release.setInstallMethod(
nextItem(release.installMethod, parsedInstallMethods)
);
}
},
// We only want to react on the change of the OS and Version
// eslint-disable-next-line @eslint-react/exhaustive-deps
[release.os, release.version]
);
return (
<Select<InstallationMethod | ''>
values={grouppedMethods}
value={release.installMethod}
loading={release.os === 'LOADING' || release.installMethod === ''}
ariaLabel={t('layouts.download.dropdown.platform')}
onChange={platform => platform && release.setInstallMethod(platform)}
className="min-w-28"
dropdownClassName="!max-h-none"
inline={true}
/>
);
};
export default InstallationMethodDropdown;