mirror of
https://github.com/SomboChea/ui
synced 2026-01-13 22:55:48 +07:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76115d2fdd | ||
|
|
03114a842b | ||
|
|
6552f4c13f | ||
|
|
9f275b7b00 | ||
|
|
f321f7b6fe | ||
|
|
e7db3e4967 | ||
|
|
e0eb6b0a3c | ||
|
|
cdad5cf70d | ||
|
|
91434cc814 | ||
|
|
4071e272af | ||
|
|
f81c1984da | ||
|
|
b2255fca88 | ||
|
|
8c2800e156 |
@@ -37,4 +37,4 @@
|
||||
],
|
||||
"results": {},
|
||||
"version": "0.12.4"
|
||||
}
|
||||
}
|
||||
47
CHANGELOG.md
47
CHANGELOG.md
@@ -2,6 +2,51 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [1.4.0](https://github.com/verdaccio/ui/compare/v1.3.0...v1.4.0) (2020-04-02)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* added zh-CN translations to the UI ([#448](https://github.com/verdaccio/ui/issues/448)) ([03114a8](https://github.com/verdaccio/ui/commit/03114a842b88ae0f482f389e7ae91af62e00bca4))
|
||||
|
||||
## [1.3.0](https://github.com/verdaccio/ui/compare/v1.0.4...v1.3.0) (2020-04-01)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **style:** added dark mode ([#446](https://github.com/verdaccio/ui/issues/446)) ([cdad5cf](https://github.com/verdaccio/ui/commit/cdad5cf70d69b7bb045fce461a32108def81721d))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **chore:** droped release ([#449](https://github.com/verdaccio/ui/issues/449)) ([f321f7b](https://github.com/verdaccio/ui/commit/f321f7b6fe1ac44897753f0bfdbbaa6ca7eca515))
|
||||
|
||||
## [1.2.0](https://github.com/verdaccio/ui/compare/v1.0.4...v1.2.0) (2020-04-01)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **style:** added dark mode ([#446](https://github.com/verdaccio/ui/issues/446)) ([cdad5cf](https://github.com/verdaccio/ui/commit/cdad5cf70d69b7bb045fce461a32108def81721d))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **chore:** droped release ([#449](https://github.com/verdaccio/ui/issues/449)) ([f321f7b](https://github.com/verdaccio/ui/commit/f321f7b6fe1ac44897753f0bfdbbaa6ca7eca515))
|
||||
|
||||
## [1.1.0](https://github.com/verdaccio/ui/compare/v1.0.4...v1.1.0) (2020-04-01)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **style:** added dark mode ([#446](https://github.com/verdaccio/ui/issues/446)) ([cdad5cf](https://github.com/verdaccio/ui/commit/cdad5cf70d69b7bb045fce461a32108def81721d))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **chore:** droped release ([#449](https://github.com/verdaccio/ui/issues/449)) ([f321f7b](https://github.com/verdaccio/ui/commit/f321f7b6fe1ac44897753f0bfdbbaa6ca7eca515))
|
||||
|
||||
### [1.0.4](https://github.com/verdaccio/ui/compare/v1.0.0...v1.0.4) (2020-03-17)
|
||||
|
||||
## [1.0.0](https://github.com/verdaccio/ui/compare/v0.3.13...v1.0.0) (2020-03-13)
|
||||
|
||||
|
||||
@@ -367,4 +412,4 @@ All notable changes to this project will be documented in this file. See [standa
|
||||
|
||||
|
||||
<a name="0.0.3"></a>
|
||||
## 0.0.3 (2019-04-04)
|
||||
## 0.0.3 (2019-04-04)
|
||||
@@ -93,7 +93,7 @@ If you have any issue you can try the following options, do no desist to ask or
|
||||
|
||||
* [Blog](https://medium.com/verdaccio)
|
||||
* [Donations](https://opencollective.com/verdaccio)
|
||||
* [Roadmaps](https://github.com/verdaccio/verdaccio/projects)
|
||||
* [Roadmaps](https://github.com/verdaccio/ui/projects)
|
||||
* [Reporting an issue](https://github.com/verdaccio/verdaccio/blob/master/CONTRIBUTING.md#reporting-a-bug)
|
||||
* [Running discussions](https://github.com/verdaccio/verdaccio/issues?q=is%3Aissue+is%3Aopen+label%3Adiscuss)
|
||||
* [Chat](http://chat.verdaccio.org/)
|
||||
@@ -101,6 +101,10 @@ If you have any issue you can try the following options, do no desist to ask or
|
||||
* [FAQ](https://github.com/verdaccio/verdaccio/issues?utf8=%E2%9C%93&q=is%3Aissue%20label%3Aquestion%20)
|
||||
* [Docker Examples](https://github.com/verdaccio/docker-examples)
|
||||
|
||||
### Translations
|
||||
|
||||
Translations are handled locally. I18n files can be found in the folder ```i18n/translations/*``` of this repository. We would love to provide translations from other languages, embracing all our users, but unfortunately we cannot do this without your help. Would you like to help us? Please feel **super welcome** to add a locale by opening a pull request.
|
||||
|
||||
### License
|
||||
|
||||
Verdaccio is [MIT licensed](https://github.com/verdaccio/verdaccio/blob/master/LICENSE)
|
||||
|
||||
@@ -5,6 +5,7 @@ import translationEN from './translations/en-US.json';
|
||||
import translationPT from './translations/pt-BR.json';
|
||||
import translationES from './translations/es-ES.json';
|
||||
import translationDE from './translations/de-DE.json';
|
||||
import translationCN from './translations/zh-CN.json';
|
||||
|
||||
i18n
|
||||
// pass the i18n instance to react-i18next.
|
||||
@@ -15,7 +16,7 @@ i18n
|
||||
// in case window.VEDACCIO_LANGUAGE is undefined,it will fall back to 'en-US'
|
||||
lng: window?.__VERDACCIO_BASENAME_UI_OPTIONS?.language,
|
||||
fallbackLng: 'en-US',
|
||||
whitelist: ['en-US', 'pt-BR', 'es-ES', 'de-DE'],
|
||||
whitelist: ['en-US', 'pt-BR', 'es-ES', 'de-DE', 'zh-CN'],
|
||||
load: 'currentOnly',
|
||||
resources: {
|
||||
'en-US': {
|
||||
@@ -30,6 +31,9 @@ i18n
|
||||
'de-DE': {
|
||||
translation: translationDE,
|
||||
},
|
||||
'zh-CN': {
|
||||
translation: translationCN,
|
||||
},
|
||||
},
|
||||
debug: false,
|
||||
interpolation: {
|
||||
|
||||
@@ -133,6 +133,7 @@
|
||||
"sorry-we-could-not-find-it": "Entschuldigung, wir konnten es nicht finden..."
|
||||
},
|
||||
"app-context-not-correct-used": "Der App-Kontext wurde nicht korrekt verwendet",
|
||||
"theme-context-not-correct-used": "Der Theme-Kontext wurde nicht korrekt verwendet",
|
||||
"package-meta-is-required-at-detail-context": "packageMeta wird bei DetailContext benötigt"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@
|
||||
"sorry-we-could-not-find-it": "Sorry, we couldn't find it..."
|
||||
},
|
||||
"app-context-not-correct-used": "The app context was not correct used",
|
||||
"theme-context-not-correct-used": "The theme context was not correct used",
|
||||
"package-meta-is-required-at-detail-context": "packageMeta is required at DetailContext"
|
||||
}
|
||||
}
|
||||
@@ -133,6 +133,7 @@
|
||||
"sorry-we-could-not-find-it": "Lo siento, no hemos podido encontrarlo..."
|
||||
},
|
||||
"app-context-not-correct-used": "El contexto de la aplicación no fue correctamente usado",
|
||||
"theme-context-not-correct-used": "El contexto del tema no fue correctamente usado",
|
||||
"package-meta-is-required-at-detail-context": "packageMeta es requerido en DetailContext"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,6 +133,7 @@
|
||||
"sorry-we-could-not-find-it": "Desculpe, não conseguimos encontrar..."
|
||||
},
|
||||
"app-context-not-correct-used": "O contexto do aplicativo não foi usado corretamente",
|
||||
"theme-context-not-correct-used": "O contexto do tema não foi usado corretamente",
|
||||
"package-meta-is-required-at-detail-context": "packageMeta é requerido em DetailContext"
|
||||
}
|
||||
}
|
||||
138
i18n/translations/zh-CN.json
Normal file
138
i18n/translations/zh-CN.json
Normal file
@@ -0,0 +1,138 @@
|
||||
{
|
||||
"copy-to-clipboard": "复制到粘贴板",
|
||||
"author-anonymous": "匿名",
|
||||
"action-bar-action": {
|
||||
"visit-home-page": "访问主页",
|
||||
"open-an-issue": "提交问题",
|
||||
"download-tarball": "下载 tarball"
|
||||
},
|
||||
"dialog": {
|
||||
"registry-info": {
|
||||
"title": "注册信息"
|
||||
}
|
||||
},
|
||||
"header": {
|
||||
"documentation": "文档",
|
||||
"registry-info": "登记信息",
|
||||
"greetings": "您好 "
|
||||
},
|
||||
"search": {
|
||||
"packages": "查找Packages"
|
||||
},
|
||||
"auto-complete": {
|
||||
"loading": "加载中...",
|
||||
"no-results-found": "没有找到结果"
|
||||
},
|
||||
"tab": {
|
||||
"uplinks": "Uplinks",
|
||||
"versions": "版本",
|
||||
"dependencies": "依赖",
|
||||
"readme": "Readme"
|
||||
},
|
||||
"uplinks": {
|
||||
"title": "Uplinks",
|
||||
"no-items": "{{name}} has no uplinks."
|
||||
},
|
||||
"versions": {
|
||||
"current-tags": "当前标签",
|
||||
"version-history": "历史版本",
|
||||
"not-available": "不可用"
|
||||
},
|
||||
"package": {
|
||||
"published-on": "发表于 {{time}} •",
|
||||
"version": "v{{version}}",
|
||||
"visit-home-page": "访问主页",
|
||||
"homepage": "主页",
|
||||
"open-an-issue": "提交问题",
|
||||
"bugs": "Bugs",
|
||||
"download": "下载 {{what}}",
|
||||
"the-tar-file": "tar 文件",
|
||||
"tarball": "Tarball"
|
||||
},
|
||||
"dependencies": {
|
||||
"has-no-dependencies": "{{package}} 没有依赖包.",
|
||||
"dependency-block": "{{package}}@{{version}}"
|
||||
},
|
||||
"form": {
|
||||
"username": "用户名",
|
||||
"password": "密码"
|
||||
},
|
||||
"form-placeholder": {
|
||||
"username": "您的用户名",
|
||||
"password": "您的密码"
|
||||
},
|
||||
"form-validation": {
|
||||
"required-field": "必填项",
|
||||
"required-min-length": "长度不能小于{{length}}",
|
||||
"unable-to-sign-in": "登录失败",
|
||||
"username-or-password-cant-be-empty": "用户名或密码不能为空!"
|
||||
},
|
||||
"help": {
|
||||
"title": "还没有发布任何NPM包.",
|
||||
"sub-title": "发布第一个NPM包:",
|
||||
"first-step": "1. 登录",
|
||||
"first-step-command-line": "npm adduser --registry {{registryUrl}}",
|
||||
"second-step": "2. 发布",
|
||||
"second-step-command-line": "npm publish --registry {{registryUrl}}",
|
||||
"third-step": "3. 刷新当前页面."
|
||||
},
|
||||
"sidebar": {
|
||||
"detail": {
|
||||
"latest-version": "最新版本 v{{version}}",
|
||||
"version": "v{{version}}"
|
||||
},
|
||||
"installation": {
|
||||
"title": "安装",
|
||||
"install-using-yarn": "使用yarn安装",
|
||||
"install-using-yarn-command": "yarn add {{packageName}}",
|
||||
"install-using-npm": "使用npm安装",
|
||||
"install-using-npm-command": "npm install {{packageName}}",
|
||||
"install-using-pnpm": "使用pnpm安装",
|
||||
"install-using-pnpm-command": "pnpm install {{packageName}}"
|
||||
},
|
||||
"repository": {
|
||||
"title": "库"
|
||||
},
|
||||
"author": {
|
||||
"title": "作者"
|
||||
},
|
||||
"distribution": {
|
||||
"title": "最后发布",
|
||||
"license": "License",
|
||||
"size": "大小",
|
||||
"file-count": "文件数量"
|
||||
},
|
||||
"maintainers": {
|
||||
"title": "维护人"
|
||||
},
|
||||
"contributors": {
|
||||
"title": "贡献者"
|
||||
},
|
||||
"engines": {
|
||||
"npm-version": "NPM Version",
|
||||
"node-js": "NODE JS"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"powered-by": "Powered by",
|
||||
"made-with-love-on": "Made with <0>♥</0> on"
|
||||
},
|
||||
"button": {
|
||||
"close": "关闭",
|
||||
"cancel": "取消",
|
||||
"login": "登录",
|
||||
"logout": "注销",
|
||||
"go-to-the-home-page": "跳转到主页",
|
||||
"learn-more": "了解更多",
|
||||
"fund-this-package": "<0>Fund</0> this package"
|
||||
},
|
||||
"error": {
|
||||
"unspecific": "发生错误.",
|
||||
"404": {
|
||||
"page-not-found": "404 - 页面不存在",
|
||||
"sorry-we-could-not-find-it": "对不起, 我们没找到..."
|
||||
},
|
||||
"app-context-not-correct-used": "The app context was not correct used",
|
||||
"package-meta-is-required-at-detail-context": "packageMeta is required at DetailContext"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@verdaccio/ui-theme",
|
||||
"version": "1.0.0",
|
||||
"version": "1.4.0",
|
||||
"description": "Verdaccio User Interface",
|
||||
"author": {
|
||||
"name": "Verdaccio Core Team",
|
||||
|
||||
@@ -19,7 +19,7 @@ import AppRoute, { history } from './AppRoute';
|
||||
import loadDayJSLocale from './load-dayjs-locale';
|
||||
|
||||
const StyledBox = styled(Box)<{ theme?: Theme }>(({ theme }) => ({
|
||||
backgroundColor: theme && theme.palette.white,
|
||||
backgroundColor: theme?.palette.background.default,
|
||||
}));
|
||||
|
||||
const StyledBoxContent = styled(Box)<{ theme?: Theme }>(({ theme }) => ({
|
||||
|
||||
@@ -522,6 +522,30 @@ exports[`<App /> should display the Header component 1`] = `
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-colorInherit"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M6.76 4.84l-1.8-1.79-1.41 1.41 1.79 1.79 1.42-1.41zM4 10.5H1v2h3v-2zm9-9.95h-2V3.5h2V.55zm7.45 3.91l-1.41-1.41-1.79 1.79 1.41 1.41 1.79-1.79zm-3.21 13.7l1.79 1.8 1.41-1.41-1.8-1.79-1.4 1.4zM20 10.5v2h3v-2h-3zm-8-5c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm-1 16.95h2V19.5h-2v2.95zm-7.45-3.91l1.41 1.41 1.79-1.8-1.41-1.41-1.79 1.8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-colorInherit"
|
||||
data-testid="header--button-login"
|
||||
@@ -1176,6 +1200,30 @@ exports[`<App /> should display the Loading component at the beginning 1`] = `
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-colorInherit"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M6.76 4.84l-1.8-1.79-1.41 1.41 1.79 1.79 1.42-1.41zM4 10.5H1v2h3v-2zm9-9.95h-2V3.5h2V.55zm7.45 3.91l-1.41-1.41-1.79 1.79 1.41 1.41 1.79-1.79zm-3.21 13.7l1.79 1.8 1.41-1.41-1.8-1.79-1.4 1.4zM20 10.5v2h3v-2h-3zm-8-5c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm-1 16.95h2V19.5h-2v2.95zm-7.45-3.91l1.41 1.41 1.79-1.8-1.41-1.41-1.79 1.8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-colorInherit"
|
||||
data-testid="header--button-login"
|
||||
|
||||
@@ -44,6 +44,12 @@ function loadDayJSLocale() {
|
||||
dayjs.locale('es');
|
||||
}
|
||||
break;
|
||||
case 'zh-cn':
|
||||
{
|
||||
require('dayjs/locale/zh-cn');
|
||||
dayjs.locale('zh-cn');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
import { default as MuiTabs } from '../../muiComponents/Tabs';
|
||||
import Tab from '../../muiComponents/Tab';
|
||||
import { Theme } from '../../design-tokens/theme';
|
||||
|
||||
interface Props {
|
||||
onChange: (event, newValue) => void;
|
||||
@@ -14,12 +15,7 @@ const DetailContainerTabs: React.FC<Props> = ({ tabPosition, onChange }) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Tabs
|
||||
indicatorColor={'primary'}
|
||||
onChange={onChange}
|
||||
textColor={'primary'}
|
||||
value={tabPosition}
|
||||
variant={'fullWidth'}>
|
||||
<Tabs color={'primary'} indicatorColor={'primary'} onChange={onChange} value={tabPosition} variant={'fullWidth'}>
|
||||
<Tab data-testid={'readme-tab'} id={'readme-tab'} label={t('tab.readme')} />
|
||||
<Tab data-testid={'dependencies-tab'} id={'dependencies-tab'} label={t('tab.dependencies')} />
|
||||
<Tab data-testid={'versions-tab'} id={'versions-tab'} label={t('tab.versions')} />
|
||||
@@ -30,6 +26,6 @@ const DetailContainerTabs: React.FC<Props> = ({ tabPosition, onChange }) => {
|
||||
|
||||
export default DetailContainerTabs;
|
||||
|
||||
const Tabs = styled(MuiTabs)({
|
||||
const Tabs = styled(MuiTabs)<{ theme?: Theme }>({
|
||||
marginBottom: 16,
|
||||
});
|
||||
|
||||
@@ -10,6 +10,7 @@ exports[`DetailContainer renders correctly 1`] = `
|
||||
>
|
||||
<div
|
||||
class="MuiTabs-root emotion-0 emotion-1"
|
||||
color="primary"
|
||||
>
|
||||
<div
|
||||
class="MuiTabs-scroller MuiTabs-fixed"
|
||||
@@ -21,7 +22,7 @@ exports[`DetailContainer renders correctly 1`] = `
|
||||
>
|
||||
<button
|
||||
aria-selected="true"
|
||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorPrimary Mui-selected MuiTab-fullWidth"
|
||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit Mui-selected MuiTab-fullWidth"
|
||||
data-testid="readme-tab"
|
||||
id="readme-tab"
|
||||
role="tab"
|
||||
@@ -39,7 +40,7 @@ exports[`DetailContainer renders correctly 1`] = `
|
||||
</button>
|
||||
<button
|
||||
aria-selected="false"
|
||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorPrimary MuiTab-fullWidth"
|
||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit MuiTab-fullWidth"
|
||||
data-testid="dependencies-tab"
|
||||
id="dependencies-tab"
|
||||
role="tab"
|
||||
@@ -57,7 +58,7 @@ exports[`DetailContainer renders correctly 1`] = `
|
||||
</button>
|
||||
<button
|
||||
aria-selected="false"
|
||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorPrimary MuiTab-fullWidth"
|
||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit MuiTab-fullWidth"
|
||||
data-testid="versions-tab"
|
||||
id="versions-tab"
|
||||
role="tab"
|
||||
@@ -75,7 +76,7 @@ exports[`DetailContainer renders correctly 1`] = `
|
||||
</button>
|
||||
<button
|
||||
aria-selected="false"
|
||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorPrimary MuiTab-fullWidth"
|
||||
class="MuiButtonBase-root MuiTab-root MuiTab-textColorInherit MuiTab-fullWidth"
|
||||
data-testid="uplinks-tab"
|
||||
id="uplinks-tab"
|
||||
role="tab"
|
||||
|
||||
@@ -15,10 +15,6 @@ import { Theme } from '../../design-tokens/theme';
|
||||
import DetailSidebarTitle from './DetailSidebarTitle';
|
||||
import DetailSidebarFundButton from './DetailSidebarFundButton';
|
||||
|
||||
const StyledPaper = styled(Paper)<{ theme?: Theme }>(({ theme }) => ({
|
||||
padding: theme.spacing(3, 2),
|
||||
}));
|
||||
|
||||
const DetailSidebar: React.FC = () => {
|
||||
const detailContext = useContext(DetailContext);
|
||||
|
||||
@@ -50,3 +46,7 @@ const DetailSidebar: React.FC = () => {
|
||||
};
|
||||
|
||||
export default DetailSidebar;
|
||||
|
||||
const StyledPaper = styled(Paper)<{ theme?: Theme }>(({ theme }) => ({
|
||||
padding: theme?.spacing(3, 2),
|
||||
}));
|
||||
|
||||
@@ -13,15 +13,6 @@ interface Props {
|
||||
isLatest: boolean;
|
||||
}
|
||||
|
||||
const StyledHeading = styled(Heading)({
|
||||
fontSize: '1rem',
|
||||
fontWeight: 700,
|
||||
});
|
||||
|
||||
const StyledBoxVersion = styled(Box)<{ theme?: Theme }>(({ theme }) => ({
|
||||
color: theme && theme.palette.text.secondary,
|
||||
}));
|
||||
|
||||
const DetailSidebarTitle: React.FC<Props> = ({ description, packageName, version, isLatest }) => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
@@ -36,3 +27,12 @@ const DetailSidebarTitle: React.FC<Props> = ({ description, packageName, version
|
||||
};
|
||||
|
||||
export default DetailSidebarTitle;
|
||||
|
||||
const StyledHeading = styled(Heading)({
|
||||
fontSize: '1rem',
|
||||
fontWeight: 700,
|
||||
});
|
||||
|
||||
const StyledBoxVersion = styled(Box)<{ theme?: Theme }>(({ theme }) => ({
|
||||
color: theme && theme.palette.text.secondary,
|
||||
}));
|
||||
|
||||
@@ -93,7 +93,7 @@ exports[`test Developers should render the component for contributors with items
|
||||
margin="10px 0 10px 0"
|
||||
>
|
||||
<div
|
||||
className="MuiBox-root MuiBox-root-60 emotion-8 emotion-9"
|
||||
className="MuiBox-root MuiBox-root-91 emotion-8 emotion-9"
|
||||
>
|
||||
<ForwardRef(ToolTip)
|
||||
key="dave.methvin@gmail.com"
|
||||
|
||||
@@ -3,10 +3,10 @@ import styled from '@emotion/styled';
|
||||
import Icon from '../Icon/Icon';
|
||||
import { Theme } from '../../design-tokens/theme';
|
||||
|
||||
export const Wrapper = styled('div')<{ theme?: Theme }>(props => ({
|
||||
background: props.theme && props.theme.palette.snow,
|
||||
borderTop: `1px solid ${props.theme && props.theme.palette.greyGainsboro}`,
|
||||
color: props.theme && props.theme.palette.nobel01,
|
||||
export const Wrapper = styled('div')<{ theme?: Theme }>(({ theme }) => ({
|
||||
background: theme?.palette.type === 'dark' ? theme?.palette.primary.main : theme?.palette.snow,
|
||||
borderTop: `1px solid ${theme?.palette.greyGainsboro}`,
|
||||
color: theme?.palette.type === 'dark' ? theme?.palette.white : theme?.palette.nobel01,
|
||||
fontSize: '14px',
|
||||
padding: '20px',
|
||||
}));
|
||||
|
||||
@@ -30,7 +30,6 @@ const Header: React.FC<Props> = ({ withoutSearch }) => {
|
||||
}
|
||||
|
||||
const { user, scope, setUser } = appContext;
|
||||
const logo = window.VERDACCIO_LOGO;
|
||||
|
||||
/**
|
||||
* Logouts user
|
||||
@@ -46,7 +45,7 @@ const Header: React.FC<Props> = ({ withoutSearch }) => {
|
||||
<>
|
||||
<NavBar data-testid="header" position="static">
|
||||
<InnerNavBar>
|
||||
<HeaderLeft logo={logo} />
|
||||
<HeaderLeft />
|
||||
<HeaderRight
|
||||
onLogout={handleLogout}
|
||||
onOpenRegistryInfoDialog={() => setOpenInfoDialog(true)}
|
||||
|
||||
@@ -3,23 +3,22 @@ import styled from '@emotion/styled';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import Search from '../Search/';
|
||||
import Logo from '../Logo';
|
||||
|
||||
import HeaderLogo from './HeaderLogo';
|
||||
import { LeftSide, SearchWrapper } from './styles';
|
||||
|
||||
interface Props {
|
||||
withoutSearch?: boolean;
|
||||
logo?: string;
|
||||
}
|
||||
|
||||
const StyledLink = styled(Link)({
|
||||
marginRight: '1em',
|
||||
});
|
||||
|
||||
const HeaderLeft: React.FC<Props> = ({ withoutSearch = false, logo }) => (
|
||||
const HeaderLeft: React.FC<Props> = ({ withoutSearch = false }) => (
|
||||
<LeftSide>
|
||||
<StyledLink to={'/'}>
|
||||
<HeaderLogo logo={logo} />
|
||||
<Logo />
|
||||
</StyledLink>
|
||||
{!withoutSearch && (
|
||||
<SearchWrapper>
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import Logo from '../Logo';
|
||||
|
||||
interface Props {
|
||||
logo?: string;
|
||||
}
|
||||
|
||||
const HeaderLogo: React.FC<Props> = ({ logo }) => {
|
||||
if (logo) {
|
||||
const Wrapper = styled('div')({
|
||||
fontSize: 0,
|
||||
});
|
||||
return (
|
||||
<Wrapper>
|
||||
<img alt="logo" height="40px" src={logo} />
|
||||
</Wrapper>
|
||||
);
|
||||
}
|
||||
|
||||
return <Logo />;
|
||||
};
|
||||
|
||||
export default HeaderLogo;
|
||||
@@ -1,7 +1,8 @@
|
||||
import React, { useState, useEffect, MouseEvent } from 'react';
|
||||
import React, { useState, useEffect, useContext, MouseEvent } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import Button from '../../muiComponents/Button';
|
||||
import ThemeContext from '../../design-tokens/ThemeContext';
|
||||
|
||||
import { RightSide } from './styles';
|
||||
import HeaderToolTip from './HeaderToolTip';
|
||||
@@ -24,10 +25,16 @@ const HeaderRight: React.FC<Props> = ({
|
||||
onToggleMobileNav,
|
||||
onOpenRegistryInfoDialog,
|
||||
}) => {
|
||||
const themeContext = useContext(ThemeContext);
|
||||
const [anchorEl, setAnchorEl] = useState();
|
||||
const [isMenuOpen, setIsMenuOpen] = useState();
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
if (!themeContext) {
|
||||
throw Error(t('theme-context-not-correct-used'));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setIsMenuOpen(Boolean(anchorEl));
|
||||
}, [anchorEl]);
|
||||
@@ -54,6 +61,12 @@ const HeaderRight: React.FC<Props> = ({
|
||||
onToggleLogin();
|
||||
};
|
||||
|
||||
const handleToggleDarkLightMode = () => {
|
||||
setTimeout(() => {
|
||||
themeContext.setIsDarkMode(!themeContext.isDarkMode);
|
||||
}, 300);
|
||||
};
|
||||
|
||||
return (
|
||||
<RightSide data-testid="header-right">
|
||||
{!withoutSearch && (
|
||||
@@ -61,6 +74,12 @@ const HeaderRight: React.FC<Props> = ({
|
||||
)}
|
||||
<HeaderToolTip title={t('header.documentation')} tooltipIconType={'help'} />
|
||||
<HeaderToolTip onClick={onOpenRegistryInfoDialog} title={t('header.registry-info')} tooltipIconType={'info'} />
|
||||
<HeaderToolTip
|
||||
onClick={handleToggleDarkLightMode}
|
||||
title={t('header.documentation')}
|
||||
tooltipIconType={themeContext.isDarkMode ? 'dark-mode' : 'light-mode'}
|
||||
/>
|
||||
|
||||
{username ? (
|
||||
<HeaderMenu
|
||||
anchorEl={anchorEl}
|
||||
|
||||
@@ -2,12 +2,14 @@ import React, { forwardRef } from 'react';
|
||||
import Info from '@material-ui/icons/Info';
|
||||
import Help from '@material-ui/icons/Help';
|
||||
import Search from '@material-ui/icons/Search';
|
||||
import NightsStay from '@material-ui/icons/NightsStay';
|
||||
import WbSunny from '@material-ui/icons/WbSunny';
|
||||
|
||||
import IconButton from '../../muiComponents/IconButton';
|
||||
|
||||
import { IconSearchButton, StyledLink } from './styles';
|
||||
|
||||
export type TooltipIconType = 'search' | 'help' | 'info';
|
||||
export type TooltipIconType = 'search' | 'help' | 'info' | 'dark-mode' | 'light-mode';
|
||||
interface Props {
|
||||
tooltipIconType: TooltipIconType;
|
||||
onClick?: () => void;
|
||||
@@ -50,6 +52,21 @@ const HeaderToolTipIcon = forwardRef<HeaderToolTipIconRef, Props>(function Heade
|
||||
<Search />
|
||||
</IconSearchButton>
|
||||
);
|
||||
case 'dark-mode':
|
||||
// todo(Priscila): Add Zoom transition effect
|
||||
return (
|
||||
<IconButton color="inherit" onClick={onClick} ref={ref}>
|
||||
<NightsStay />
|
||||
</IconButton>
|
||||
);
|
||||
|
||||
case 'light-mode':
|
||||
// todo(Priscila): Add Zoom transition effect
|
||||
return (
|
||||
<IconButton color="inherit" onClick={onClick} ref={ref}>
|
||||
<WbSunny />
|
||||
</IconButton>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -302,6 +302,30 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-colorInherit"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M6.76 4.84l-1.8-1.79-1.41 1.41 1.79 1.79 1.42-1.41zM4 10.5H1v2h3v-2zm9-9.95h-2V3.5h2V.55zm7.45 3.91l-1.41-1.41-1.79 1.79 1.41 1.41 1.79-1.79zm-3.21 13.7l1.79 1.8 1.41-1.41-1.8-1.79-1.4 1.4zM20 10.5v2h3v-2h-3zm-8-5c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm-1 16.95h2V19.5h-2v2.95zm-7.45-3.91l1.41 1.41 1.79-1.8-1.41-1.41-1.79 1.8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-colorInherit"
|
||||
data-testid="header--menu-accountcircle"
|
||||
@@ -635,6 +659,30 @@ exports[`<Header /> component with logged in state should load the component in
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiIconButton-root MuiIconButton-colorInherit"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
role="presentation"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M6.76 4.84l-1.8-1.79-1.41 1.41 1.79 1.79 1.42-1.41zM4 10.5H1v2h3v-2zm9-9.95h-2V3.5h2V.55zm7.45 3.91l-1.41-1.41-1.79 1.79 1.41 1.41 1.79-1.79zm-3.21 13.7l1.79 1.8 1.41-1.41-1.8-1.79-1.4 1.4zM20 10.5v2h3v-2h-3zm-8-5c-3.31 0-6 2.69-6 6s2.69 6 6 6 6-2.69 6-6-2.69-6-6-6zm-1 16.95h2V19.5h-2v2.95zm-7.45-3.91l1.41 1.41 1.79-1.8-1.41-1.41-1.79 1.8z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-colorInherit"
|
||||
data-testid="header--button-login"
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { Theme } from '../../design-tokens/theme';
|
||||
|
||||
export const Wrapper = styled('div')({
|
||||
transform: 'translate(-50%, -50%)',
|
||||
top: '50%',
|
||||
@@ -7,9 +9,9 @@ export const Wrapper = styled('div')({
|
||||
position: 'absolute',
|
||||
});
|
||||
|
||||
export const Badge = styled('div')({
|
||||
export const Badge = styled('div')<{ theme?: Theme }>(({ theme }) => ({
|
||||
margin: '0 0 30px 0',
|
||||
borderRadius: 25,
|
||||
boxShadow: '0 10px 20px 0 rgba(69, 58, 100, 0.2)',
|
||||
background: '#f7f8f6',
|
||||
});
|
||||
background: theme?.palette.type === 'dark' ? theme?.palette.black : '#f7f8f6',
|
||||
}));
|
||||
|
||||
@@ -8,13 +8,14 @@ import { Theme } from '../../design-tokens/theme';
|
||||
import { LoginError } from '../../utils/login';
|
||||
|
||||
const StyledSnackbarContent = styled(SnackbarContent)<{ theme?: Theme }>(({ theme }) => ({
|
||||
backgroundColor: theme.palette.error.dark,
|
||||
backgroundColor: theme?.palette.error.dark,
|
||||
color: theme?.palette.white,
|
||||
}));
|
||||
|
||||
const StyledErrorIcon = styled(Error)<{ theme?: Theme }>(({ theme }) => ({
|
||||
fontSize: 20,
|
||||
opacity: 0.9,
|
||||
marginRight: theme.spacing(1),
|
||||
marginRight: theme?.spacing(1),
|
||||
}));
|
||||
|
||||
export interface FormValues {
|
||||
|
||||
@@ -13,6 +13,7 @@ import { Theme } from '../../design-tokens/theme';
|
||||
const StyledAvatar = styled(Avatar)<{ theme?: Theme }>(({ theme }) => ({
|
||||
margin: theme.spacing(1),
|
||||
backgroundColor: theme.palette.primary.main,
|
||||
color: theme.palette.white,
|
||||
}));
|
||||
|
||||
const StyledIconButton = styled(IconButton)<{ theme?: Theme }>(({ theme }) => ({
|
||||
|
||||
@@ -1,31 +1,52 @@
|
||||
import React from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import logo from './img/logo.svg';
|
||||
import { Theme } from '../../design-tokens/theme';
|
||||
|
||||
import defaultLogo from './img/logo.svg';
|
||||
import blackAndWithLogo from './img/logo-black-and-white.svg';
|
||||
|
||||
export enum Size {
|
||||
Small = '40px',
|
||||
Big = '90px',
|
||||
}
|
||||
|
||||
const logos = {
|
||||
light: defaultLogo,
|
||||
dark: blackAndWithLogo,
|
||||
};
|
||||
|
||||
const logo = window.VERDACCIO_LOGO;
|
||||
|
||||
interface Props {
|
||||
size?: Size;
|
||||
}
|
||||
|
||||
const StyledLogo = styled('div')<Props>(props => ({
|
||||
const Logo: React.FC<Props> = ({ size = Size.Small }) => {
|
||||
if (logo) {
|
||||
return (
|
||||
<ImageLogo>
|
||||
<img alt="logo" height="40px" src={logo} />
|
||||
</ImageLogo>
|
||||
);
|
||||
}
|
||||
return <StyledLogo size={size} />;
|
||||
};
|
||||
|
||||
export default Logo;
|
||||
|
||||
const ImageLogo = styled('div')({
|
||||
fontSize: 0,
|
||||
});
|
||||
|
||||
const StyledLogo = styled('div')<Props & { theme?: Theme }>(({ size, theme }) => ({
|
||||
display: 'inline-block',
|
||||
verticalAlign: 'middle',
|
||||
boxSizing: 'border-box',
|
||||
backgroundPosition: 'center',
|
||||
backgroundSize: 'contain',
|
||||
backgroundImage: `url(${logo})`,
|
||||
backgroundImage: `url(${logos[theme?.palette.type]})`,
|
||||
backgroundRepeat: ' no-repeat',
|
||||
width: props.size,
|
||||
height: props.size,
|
||||
width: size,
|
||||
height: size,
|
||||
}));
|
||||
|
||||
const Logo: React.FC<Props> = ({ size = Size.Small }) => {
|
||||
return <StyledLogo size={size} />;
|
||||
};
|
||||
|
||||
export default Logo;
|
||||
|
||||
1
src/components/Logo/img/logo-black-and-white.svg
Normal file
1
src/components/Logo/img/logo-black-and-white.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><filter x="-19.8%" y="-11.7%" width="139.6%" height="140.4%" filterUnits="objectBoundingBox" id="a"><feOffset dy="4" in="SourceAlpha" result="shadowOffsetOuter1"/><feGaussianBlur stdDeviation="2.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"/><feComposite in="shadowBlurOuter1" in2="SourceAlpha" operator="out" result="shadowBlurOuter1"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0906646286 0" in="shadowBlurOuter1"/></filter><filter x="-33.9%" y="-50%" width="167.9%" height="272.7%" filterUnits="objectBoundingBox" id="c"><feOffset dy="4" in="SourceAlpha" result="shadowOffsetOuter1"/><feGaussianBlur stdDeviation="2.5" in="shadowOffsetOuter1" result="shadowBlurOuter1"/><feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.0906646286 0" in="shadowBlurOuter1"/></filter><path id="b" d="M48 16.729L32.672 47h-8.874L0 0h15.328l12.907 25.492 4.437-8.763H48z"/><path d="M35.2 11H28V8.643h8.4l1.2-2.357H32V3.929h6.8l.8-1.572H36V0h20l-5.6 11H35.2z" id="d"/></defs><g fill="none" fill-rule="evenodd"><rect fill="#000" width="100" height="100" rx="37"/><g transform="translate(22 30)"><use fill="#000" filter="url(#a)" xlink:href="#b"/><use fill-opacity=".6" fill="#FFF" xlink:href="#b"/></g><g transform="translate(22 30)"><use fill="#000" filter="url(#c)" xlink:href="#d"/><use fill="#FFF" xlink:href="#d"/></g><path fill="#FFF" d="M54.785 77H45.88L22 30h15.38L58 70.718z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -15,7 +15,7 @@ export const OverviewItem = styled('span')<{ theme?: Theme }>(({ theme }) => ({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
margin: '0 0 0 16px',
|
||||
color: theme && theme.palette.greyLight2,
|
||||
color: theme?.palette.type === 'light' ? theme?.palette.greyLight2 : theme?.palette.dodgerBlue,
|
||||
fontSize: 12,
|
||||
[`@media (max-width: ${theme && theme.breakPoints.medium}px)`]: {
|
||||
':nth-of-type(3)': {
|
||||
@@ -29,20 +29,20 @@ export const OverviewItem = styled('span')<{ theme?: Theme }>(({ theme }) => ({
|
||||
},
|
||||
}));
|
||||
|
||||
export const Icon = styled(Ico)<{ theme?: Theme }>(props => ({
|
||||
export const Icon = styled(Ico)<{ theme?: Theme }>(({ theme }) => ({
|
||||
margin: '2px 10px 0 0',
|
||||
fill: props.theme && props.theme.palette.greyLight2,
|
||||
fill: theme?.palette.type === 'light' ? theme?.palette.greyLight2 : theme?.palette.dodgerBlue,
|
||||
}));
|
||||
|
||||
export const Published = styled('span')<{ theme?: Theme }>(props => ({
|
||||
color: props.theme && props.theme.palette.greyLight2,
|
||||
export const Published = styled('span')<{ theme?: Theme }>(({ theme }) => ({
|
||||
color: theme?.palette.type === 'light' ? theme?.palette.greyLight2 : theme?.palette.dodgerBlue,
|
||||
margin: '0 5px 0 0',
|
||||
}));
|
||||
|
||||
export const Text = styled(Label)<{ theme?: Theme }>(props => ({
|
||||
export const Text = styled(Label)<{ theme?: Theme }>(({ theme }) => ({
|
||||
fontSize: '12px',
|
||||
fontWeight: props.theme && props.theme.fontWeight.semiBold,
|
||||
color: props.theme && props.theme.palette.greyLight2,
|
||||
fontWeight: theme?.fontWeight.semiBold,
|
||||
color: theme?.palette.type === 'light' ? theme?.palette.greyLight2 : theme?.palette.dodgerBlue,
|
||||
}));
|
||||
|
||||
export const Details = styled('span')({
|
||||
@@ -71,11 +71,8 @@ export const PackageTitle = styled('span')<{ theme?: Theme }>(({ theme }) => ({
|
||||
fontSize: 20,
|
||||
display: 'block',
|
||||
marginBottom: 12,
|
||||
color: theme && theme.palette.eclipse,
|
||||
color: theme?.palette.type == 'dark' ? theme?.palette.white : theme?.palette.eclipse,
|
||||
cursor: 'pointer',
|
||||
':hover': {
|
||||
color: theme && theme.palette.black,
|
||||
},
|
||||
[`@media (max-width: ${theme && theme.breakPoints.small}px)`]: {
|
||||
fontSize: 14,
|
||||
marginBottom: 8,
|
||||
@@ -86,14 +83,15 @@ export const GridRightAligned = styled(Grid)({
|
||||
textAlign: 'right',
|
||||
});
|
||||
|
||||
export const PackageList = styled(List)<{ theme?: Theme }>(props => ({
|
||||
export const PackageList = styled(List)<{ theme?: Theme }>(({ theme }) => ({
|
||||
padding: '12px 0 12px 0',
|
||||
':hover': {
|
||||
backgroundColor: props.theme && props.theme.palette.greyLight3,
|
||||
backgroundColor: theme?.palette?.type == 'dark' ? theme?.palette?.primary.main : theme?.palette?.greyLight3,
|
||||
},
|
||||
'> :last-child': {
|
||||
paddingTop: 0,
|
||||
},
|
||||
borderRadius: 4,
|
||||
}));
|
||||
|
||||
export const IconButton = styled(MuiIconButton)({
|
||||
|
||||
@@ -12,7 +12,9 @@ describe('<Readme /> component', () => {
|
||||
|
||||
test('should dangerously set html', () => {
|
||||
const wrapper = mount(<Readme description="<h1>This is a test string</h1>" />);
|
||||
expect(wrapper.html()).toEqual('<div class="markdown-body"><h1>This is a test string</h1></div>');
|
||||
expect(wrapper.html()).toEqual(
|
||||
'<div class="markdown-body css-beaqbv-Wrapper ecnabbe0"><h1>This is a test string</h1></div>'
|
||||
);
|
||||
expect(wrapper.html()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
import React from 'react';
|
||||
import 'github-markdown-css';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { Theme } from '../../design-tokens/theme';
|
||||
|
||||
import { Props } from './types';
|
||||
|
||||
const Readme: React.FC<Props> = ({ description }) => (
|
||||
<div className="markdown-body" dangerouslySetInnerHTML={{ __html: description }} />
|
||||
<Wrapper className="markdown-body" dangerouslySetInnerHTML={{ __html: description }} />
|
||||
);
|
||||
|
||||
export default Readme;
|
||||
|
||||
const Wrapper = styled('div')<{ theme?: Theme }>(({ theme }) => ({
|
||||
background: theme?.palette.white,
|
||||
color: theme?.palette.black,
|
||||
padding: theme?.spacing(2, 3),
|
||||
}));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Readme /> component should dangerously set html 1`] = `"<div class=\\"markdown-body\\"><h1>This is a test string</h1></div>"`;
|
||||
exports[`<Readme /> component should dangerously set html 1`] = `"<div class=\\"markdown-body css-beaqbv-Wrapper ecnabbe0\\"><h1>This is a test string</h1></div>"`;
|
||||
|
||||
exports[`<Readme /> component should load the component in default state 1`] = `"<div class=\\"markdown-body\\">test</div>"`;
|
||||
exports[`<Readme /> component should load the component in default state 1`] = `"<div class=\\"markdown-body css-beaqbv-Wrapper ecnabbe0\\">test</div>"`;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import React, { useState } from 'react';
|
||||
import { css } from '@emotion/core';
|
||||
|
||||
import CopyToClipBoard from '../CopyToClipBoard';
|
||||
import { getCLISetRegistry, getCLIChangePassword, getCLISetConfigRegistry } from '../../utils/cli-utils';
|
||||
@@ -48,10 +47,10 @@ const RegistryInfoContent: React.FC<Props> = props => {
|
||||
return (
|
||||
<>
|
||||
<Tabs
|
||||
color={'primary'}
|
||||
data-testid={'tabs-el'}
|
||||
indicatorColor="primary"
|
||||
indicatorColor={'primary'}
|
||||
onChange={handleChange}
|
||||
textColor="primary"
|
||||
value={tabPosition}
|
||||
variant="fullWidth">
|
||||
<Tab data-testid={'npm-tab'} label={NODE_MANAGER.npm} />
|
||||
@@ -69,14 +68,7 @@ const RegistryInfoContent: React.FC<Props> = props => {
|
||||
const TabContainer = ({ children }): JSX.Element => {
|
||||
return (
|
||||
<CommandContainer>
|
||||
<Typography
|
||||
// className={css`
|
||||
// padding: 0;
|
||||
// min-height: 170;
|
||||
// `}
|
||||
component="div">
|
||||
{children}
|
||||
</Typography>
|
||||
<Typography component="div">{children}</Typography>
|
||||
</CommandContainer>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -10,6 +10,7 @@ export const Title = styled(DialogTitle)<{ theme?: Theme }>(props => ({
|
||||
fontSize: props.theme && props.theme.fontSize.lg,
|
||||
}));
|
||||
|
||||
export const Content = styled(DialogContent)({
|
||||
export const Content = styled(DialogContent)<{ theme?: Theme }>(({ theme }) => ({
|
||||
padding: '0 24px',
|
||||
});
|
||||
backgroundColor: theme?.palette.background.default,
|
||||
}));
|
||||
|
||||
@@ -6,6 +6,7 @@ import Avatar from '../../muiComponents/Avatar';
|
||||
import Text from '../../muiComponents/Text';
|
||||
import ListItem from '../../muiComponents/ListItem';
|
||||
import ListItemText from '../../muiComponents/ListItemText';
|
||||
import Link from '../Link';
|
||||
import { isURL } from '../../utils/url';
|
||||
import CopyToClipBoard from '../CopyToClipBoard';
|
||||
import List from '../../muiComponents/List';
|
||||
@@ -19,8 +20,11 @@ const StyledText = styled(Text)<{ theme?: Theme }>(props => ({
|
||||
textTransform: 'capitalize',
|
||||
}));
|
||||
|
||||
const GithubLink = styled('a')<{ theme?: Theme }>(props => ({
|
||||
color: props.theme && props.theme.palette.primary.main,
|
||||
const GithubLink = styled(Link)<{ theme?: Theme }>(({ theme }) => ({
|
||||
color: theme?.palette.type === 'light' ? theme?.palette.primary.main : theme?.palette.white,
|
||||
':hover': {
|
||||
color: theme?.palette.dodgerBlue,
|
||||
},
|
||||
}));
|
||||
|
||||
const RepositoryListItem = styled(ListItem)({
|
||||
@@ -72,7 +76,7 @@ const Repository: React.FC = () => {
|
||||
<RepositoryListItemText
|
||||
primary={
|
||||
<CopyToClipBoard text={repositoryURL}>
|
||||
<GithubLink href={repositoryURL} target="_blank">
|
||||
<GithubLink external={true} to={repositoryURL}>
|
||||
{repositoryURL}
|
||||
</GithubLink>
|
||||
</CopyToClipBoard>
|
||||
|
||||
@@ -19,6 +19,6 @@ export const Wrapper = styled('div')<WrapperProps>(props => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
export const Circular = styled(CircularProgress)<{ theme?: Theme }>(props => ({
|
||||
color: props.theme && props.theme.palette.primary.main,
|
||||
export const Circular = styled(CircularProgress)<{ theme?: Theme }>(({ theme }) => ({
|
||||
color: theme?.palette.type === 'dark' ? theme?.palette.white : theme?.palette.primary.main,
|
||||
}));
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
exports[`<UpLinks /> component should render the component when there is no uplink 1`] = `"<h6 class=\\"MuiTypography-root MuiTypography-subtitle1 MuiTypography-gutterBottom\\">uplinks.no-items</h6>"`;
|
||||
|
||||
exports[`<UpLinks /> component should render the component with uplinks 1`] = `"<h6 class=\\"MuiTypography-root css-5wp24z-StyledText e14i1sy10 MuiTypography-subtitle1\\">uplinks.title</h6><ul class=\\"MuiList-root MuiList-padding\\"><li class=\\"MuiListItem-root MuiListItem-gutters\\"><div class=\\"MuiListItemText-root css-1pxn9ma-ListItemText e14i1sy12\\"><span class=\\"MuiTypography-root MuiListItemText-primary MuiTypography-body1\\">npmjs</span></div><div class=\\"css-t1rp47-Spacer e14i1sy11\\"></div><div class=\\"MuiListItemText-root css-1pxn9ma-ListItemText e14i1sy12\\"><span class=\\"MuiTypography-root MuiListItemText-primary MuiTypography-body1\\">2 years ago</span></div></li></ul>"`;
|
||||
exports[`<UpLinks /> component should render the component with uplinks 1`] = `"<h6 class=\\"MuiTypography-root css-5wp24z-StyledText e14i1sy10 MuiTypography-subtitle1\\">uplinks.title</h6><ul class=\\"MuiList-root MuiList-padding\\"><li class=\\"MuiListItem-root MuiListItem-gutters\\"><div class=\\"MuiListItemText-root css-1ork7s0-ListItemText e14i1sy12\\"><span class=\\"MuiTypography-root MuiListItemText-primary MuiTypography-body1\\">npmjs</span></div><div class=\\"css-4lqckn-Spacer e14i1sy11\\"></div><div class=\\"MuiListItemText-root css-1ork7s0-ListItemText e14i1sy12\\"><span class=\\"MuiTypography-root MuiListItemText-primary MuiTypography-body1\\">2 years ago</span></div></li></ul>"`;
|
||||
|
||||
@@ -8,15 +8,15 @@ export const StyledText = styled(Text)<{ theme?: Theme }>(props => ({
|
||||
fontWeight: props.theme && props.theme.fontWeight.bold,
|
||||
}));
|
||||
|
||||
export const Spacer = styled('div')({
|
||||
export const Spacer = styled('div')<{ theme?: Theme }>(({ theme }) => ({
|
||||
flex: '1 1 auto',
|
||||
borderBottom: '1px dotted rgba(0, 0, 0, 0.2)',
|
||||
borderBottom: `1px dotted ${theme?.palette.type == 'light' ? 'rgba(0, 0, 0, 0.2)' : 'rgba(255, 255, 255, 0.2)'} `,
|
||||
whiteSpace: 'nowrap',
|
||||
height: '0.5em',
|
||||
});
|
||||
}));
|
||||
|
||||
export const ListItemText = styled(MuiListItemText)({
|
||||
export const ListItemText = styled(MuiListItemText)<{ theme?: Theme }>(({ theme }) => ({
|
||||
flex: 'none',
|
||||
color: 'black',
|
||||
color: theme?.palette.type == 'light' ? theme?.palette.black : theme?.palette.white,
|
||||
opacity: 0.6,
|
||||
});
|
||||
}));
|
||||
|
||||
@@ -7,6 +7,7 @@ import { DIST_TAGS } from '../../../lib/constants';
|
||||
import { StyledText } from './styles';
|
||||
import VersionsTagList from './VersionsTagList';
|
||||
import VersionsHistoryList from './VersionsHistoryList';
|
||||
|
||||
const Versions: React.FC = () => {
|
||||
const detailContext = useContext(DetailContext);
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -9,19 +9,19 @@ export const StyledText = styled(Text)<{ theme?: Theme }>(props => ({
|
||||
fontWeight: props.theme && props.theme.fontWeight.bold,
|
||||
}));
|
||||
|
||||
export const Spacer = styled('div')({
|
||||
export const Spacer = styled('div')<{ theme?: Theme }>(({ theme }) => ({
|
||||
flex: '1 1 auto',
|
||||
borderBottom: '1px dotted rgba(0, 0, 0, 0.2)',
|
||||
borderBottom: `1px dotted ${theme?.palette.type == 'light' ? 'rgba(0, 0, 0, 0.2)' : 'rgba(255, 255, 255, 0.2)'} `,
|
||||
whiteSpace: 'nowrap',
|
||||
height: '0.5em',
|
||||
margin: '0 16px',
|
||||
});
|
||||
}));
|
||||
|
||||
export const ListItemText = styled(MuiListItemText)({
|
||||
export const ListItemText = styled(MuiListItemText)<{ theme?: Theme }>(({ theme }) => ({
|
||||
flex: 'none',
|
||||
color: 'black',
|
||||
opacity: 0.6,
|
||||
});
|
||||
color: theme?.palette.type == 'light' ? theme?.palette.black : theme?.palette.white,
|
||||
}));
|
||||
|
||||
export const StyledLink = styled(Link)({
|
||||
textDecoration: 'none',
|
||||
|
||||
10
src/design-tokens/ThemeContext.ts
Normal file
10
src/design-tokens/ThemeContext.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
interface Props {
|
||||
isDarkMode: boolean;
|
||||
setIsDarkMode: (isDarkMode: boolean) => void;
|
||||
}
|
||||
|
||||
const ThemeContext = createContext<undefined | Props>(undefined);
|
||||
|
||||
export default ThemeContext;
|
||||
@@ -2,12 +2,23 @@ import React from 'react';
|
||||
import { ThemeProvider as MuiThemeProvider } from '@material-ui/core/styles';
|
||||
import { ThemeProvider as EmotionThemeProvider } from 'emotion-theming';
|
||||
|
||||
import theme from './theme';
|
||||
import ThemeContext from './ThemeContext';
|
||||
import { getTheme, ThemeMode } from './theme';
|
||||
import useLocalStorage from './useLocalStorage';
|
||||
|
||||
const ThemeProvider: React.FC = ({ children }) => (
|
||||
<EmotionThemeProvider theme={theme}>
|
||||
<MuiThemeProvider theme={theme}>{children}</MuiThemeProvider>
|
||||
</EmotionThemeProvider>
|
||||
);
|
||||
const ThemeProvider: React.FC = ({ children }) => {
|
||||
const isDarkModeDefault = window?.__VERDACCIO_BASENAME_UI_OPTIONS?.darkMode;
|
||||
const [isDarkMode, setIsDarkMode] = useLocalStorage('darkMode', !!isDarkModeDefault);
|
||||
|
||||
const themeMode: ThemeMode = isDarkMode ? 'dark' : 'light';
|
||||
|
||||
return (
|
||||
<ThemeContext.Provider value={{ isDarkMode, setIsDarkMode }}>
|
||||
<EmotionThemeProvider theme={getTheme(themeMode)}>
|
||||
<MuiThemeProvider theme={getTheme(themeMode)}>{children}</MuiThemeProvider>
|
||||
</EmotionThemeProvider>
|
||||
</ThemeContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export default ThemeProvider;
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import createMuiTheme from '@material-ui/core/styles/createMuiTheme';
|
||||
|
||||
// Main colors
|
||||
// -------------------------
|
||||
const colors = {
|
||||
black: '#000',
|
||||
white: '#fff',
|
||||
@@ -25,9 +23,23 @@ const colors = {
|
||||
nobel02: '#9f9f9f',
|
||||
primary: window.VERDACCIO_PRIMARY_COLOR || '#4b5e40',
|
||||
secondary: '#20232a',
|
||||
background: '#fff',
|
||||
dodgerBlue: '#1ba1f2',
|
||||
};
|
||||
|
||||
export type Colors = keyof typeof colors;
|
||||
const themeModes = {
|
||||
light: {
|
||||
...colors,
|
||||
},
|
||||
dark: {
|
||||
...colors,
|
||||
primary: '#253341',
|
||||
secondary: '#20232a',
|
||||
background: '#1A202C',
|
||||
},
|
||||
};
|
||||
|
||||
export type ThemeMode = keyof typeof themeModes;
|
||||
|
||||
const fontSize = {
|
||||
xxl: 26,
|
||||
@@ -67,20 +79,27 @@ const customizedTheme = {
|
||||
|
||||
type CustomizedTheme = typeof customizedTheme;
|
||||
|
||||
export const theme = createMuiTheme({
|
||||
typography: {
|
||||
fontFamily: 'inherit',
|
||||
},
|
||||
palette: {
|
||||
...colors,
|
||||
primary: { main: colors.primary },
|
||||
secondary: { main: colors.secondary },
|
||||
error: { main: colors.red },
|
||||
},
|
||||
...customizedTheme,
|
||||
});
|
||||
export const getTheme = (themeMode: ThemeMode) => {
|
||||
const palette = themeModes[themeMode];
|
||||
return createMuiTheme({
|
||||
typography: {
|
||||
fontFamily: 'inherit',
|
||||
},
|
||||
palette: {
|
||||
type: themeMode,
|
||||
...palette,
|
||||
primary: { main: palette.primary },
|
||||
secondary: { main: palette.secondary },
|
||||
error: { main: palette.red },
|
||||
background: {
|
||||
default: palette.background,
|
||||
},
|
||||
},
|
||||
...customizedTheme,
|
||||
});
|
||||
};
|
||||
|
||||
export type Theme = typeof theme;
|
||||
export type Theme = ReturnType<typeof getTheme>;
|
||||
|
||||
declare module '@material-ui/core/styles/createMuiTheme' {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-empty-interface */
|
||||
@@ -111,6 +130,8 @@ declare module '@material-ui/core/styles/createPalette' {
|
||||
love: string;
|
||||
nobel01: string;
|
||||
nobel02: string;
|
||||
background: string;
|
||||
dodgerBlue: string;
|
||||
}
|
||||
|
||||
/* eslint-disable-next-line @typescript-eslint/no-empty-interface */
|
||||
@@ -118,5 +139,3 @@ declare module '@material-ui/core/styles/createPalette' {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-empty-interface */
|
||||
interface PaletteOptions extends Partial<CustomPalette> {}
|
||||
}
|
||||
|
||||
export default { ...theme };
|
||||
|
||||
38
src/design-tokens/useLocalStorage.ts
Normal file
38
src/design-tokens/useLocalStorage.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { useState } from 'react';
|
||||
|
||||
// based on https://usehooks.com/useLocalStorage/
|
||||
const useLocalStorage = <V>(key: string, initialValue: V) => {
|
||||
// State to store our value
|
||||
// Pass initial state function to useState so logic is only executed once
|
||||
const [storedValue, setStoredValue] = useState(() => {
|
||||
try {
|
||||
// Get from local storage by key
|
||||
const item = window.localStorage.getItem(key);
|
||||
// Parse stored json or if none return initialValue
|
||||
return item ? JSON.parse(item) : initialValue;
|
||||
} catch (error) {
|
||||
// If error also return initialValue
|
||||
console.error('An error occurred getting a sessionStorage key', error);
|
||||
return initialValue;
|
||||
}
|
||||
});
|
||||
|
||||
// Return a wrapped version of useState's setter function that ...
|
||||
// ... persists the new value to localStorage.
|
||||
const setValue = (value: V) => {
|
||||
try {
|
||||
// Allow value to be a function so we have same API as useState
|
||||
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
||||
// Save state
|
||||
setStoredValue(valueToStore);
|
||||
// Save to local storage
|
||||
window.localStorage.setItem(key, JSON.stringify(valueToStore));
|
||||
} catch (error) {
|
||||
console.error('An error occurred writing to sessionStorage', error);
|
||||
}
|
||||
};
|
||||
|
||||
return [storedValue, setValue];
|
||||
};
|
||||
|
||||
export default useLocalStorage;
|
||||
7
src/design-tokens/useTheme.ts
Normal file
7
src/design-tokens/useTheme.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { useTheme as muiUseTheme } from '@material-ui/styles';
|
||||
|
||||
import { Theme } from './theme';
|
||||
|
||||
const useTheme = () => muiUseTheme<Theme>();
|
||||
|
||||
export default useTheme;
|
||||
@@ -41,7 +41,6 @@ export default {
|
||||
}),
|
||||
title: 'Verdaccio Dev UI',
|
||||
scope: '',
|
||||
logo: 'https://verdaccio.org/img/logo/symbol/svg/verdaccio-tiny.svg',
|
||||
filename: 'index.html',
|
||||
verdaccioURL: '//localhost:4872',
|
||||
template: `${env.SRC_ROOT}/template/index.html`,
|
||||
|
||||
@@ -3,6 +3,7 @@ export interface VerdaccioOptions {
|
||||
url_prefix: string;
|
||||
base: string;
|
||||
language?: string;
|
||||
darkMode?: boolean;
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -2988,9 +2988,9 @@ acorn-walk@^6.0.1, acorn-walk@^6.1.1:
|
||||
integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
|
||||
|
||||
acorn@^5.5.3:
|
||||
version "5.7.3"
|
||||
resolved "https://registry.verdaccio.org/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
|
||||
integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
|
||||
version "5.7.4"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e"
|
||||
integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==
|
||||
|
||||
acorn@^6.0.1, acorn@^6.0.7, acorn@^6.2.1:
|
||||
version "6.3.0"
|
||||
|
||||
Reference in New Issue
Block a user