Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add dumi-theme-mobile #287

Merged
merged 35 commits into from
Sep 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
f420a91
feat: add dumi-theme-mobile
xiaohuoni Aug 17, 2020
944c064
fix: test
xiaohuoni Aug 17, 2020
2c954bd
feat: add test for mobile theme
xiaohuoni Aug 18, 2020
c9d5a50
Merge branch 'master' of https://github.com/umijs/dumi into dumi-them…
xiaohuoni Aug 18, 2020
24d2b50
fix: 1、修复切换页面时不触发预览项目变更的问题 2、不需要出现手机窗口的时候出现了 3、窗口和侧边栏菜单应该2选1,不然页面太拥挤
xiaohuoni Aug 18, 2020
98ed744
Merge branch 'master' of https://github.com/umijs/dumi into dumi-them…
xiaohuoni Aug 19, 2020
4dfa421
feat: 使用 src/content 重构代码
xiaohuoni Aug 19, 2020
e5ea8bb
Merge branch 'master' of https://github.com/umijs/dumi into dumi-them…
xiaohuoni Aug 20, 2020
445d173
fix: ci test
xiaohuoni Aug 20, 2020
1b1f3e6
test: add device test
xiaohuoni Aug 20, 2020
e902318
Merge branch 'master' into dumi-theme-mobile
PeachScript Aug 22, 2020
f210044
ci: support to preview mobile theme site
PeachScript Aug 22, 2020
6f0fe8b
ci: add 404 page for surge preview
PeachScript Aug 22, 2020
8196101
chore: remove iframe onload event
xiaohuoni Aug 28, 2020
9ef38d3
Merge branch 'master' into dumi-theme-mobile
PeachScript Aug 31, 2020
524c262
chore: remove useless 404 plugin
PeachScript Aug 31, 2020
4a62bc8
chore(theme): rename dumi-theme-mobile to theme-mobile
PeachScript Aug 31, 2020
6cee8ea
refactor(theme): update mobile device wrapper
PeachScript Aug 31, 2020
71ce9e1
refactor(theme): handle props change for useLocaleProps theme api
PeachScript Aug 31, 2020
e8ffaa3
refactor(theme): update mobile Previewer & content
PeachScript Aug 31, 2020
1499083
fix: qrcode url
xiaohuoni Sep 2, 2020
2bf5bdc
fix: test
xiaohuoni Sep 10, 2020
3f433c5
Merge branch 'master' of https://github.com/umijs/dumi into dumi-them…
xiaohuoni Sep 10, 2020
5113745
feat: support dumi@1.1.0-beta.16
xiaohuoni Sep 10, 2020
8035b78
feat: add demos layout
xiaohuoni Sep 10, 2020
64d83f2
Merge branch 'master' of https://github.com/umijs/dumi into dumi-them…
xiaohuoni Sep 10, 2020
6915b5f
fix: fallback theme builtins path error
xiaohuoni Sep 10, 2020
c1af0d4
test(theme): fix circular effects for useLocaleProps case
PeachScript Sep 10, 2020
15c7c2d
chore: remove useless dependencies
PeachScript Sep 10, 2020
ce39b92
test: add demo layout test
xiaohuoni Sep 10, 2020
93762f0
test(theme): remove useless import for mobile theme case
PeachScript Sep 10, 2020
0246e3b
chore: fix test
xiaohuoni Sep 11, 2020
5b4f9e5
Merge branch 'master' into dumi-theme-mobile
PeachScript Sep 11, 2020
6c0a227
refactor(theme): rename mobile demo layout
PeachScript Sep 11, 2020
34cc1b6
test(theme): improve test coverage for mobile theme
PeachScript Sep 11, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,18 @@ jobs:
yarn build
yarn doc:build
dist: dist
preview-mobile:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: afc163/surge-preview@v1
env:
DUMI_THEME: dumi-theme-mobile
with:
surge_token: ${{ secrets.SURGE_TOKEN }}
github_token: ${{ secrets.GITHUB_TOKEN }}
build: |
yarn
yarn build
yarn doc:build
dist: dist
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"private": true,
"scripts": {
"dev": "cross-env BROWSER=none node ./packages/dumi/bin/dumi.js dev",
"dev:mobile": "cross-env BROWSER=none DUMI_THEME=dumi-theme-mobile node ./packages/dumi/bin/dumi.js dev",
"watch": "npm run build -- --watch",
"doc:build": "cross-env BROWSER=none node ./packages/dumi/bin/dumi.js build",
"build": "father-build",
Expand Down
4 changes: 3 additions & 1 deletion packages/preset-dumi/src/theme/hooks/useLocaleProps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import useLocaleProps from './useLocaleProps';

describe('theme API: useLocaleProps', () => {
it('should transform props by locale', () => {
const { result } = renderHook(() => useLocaleProps('en-US', { title: 2, 'title_en-US': 1 }));
const { result } = renderHook(props => useLocaleProps('en-US', props), {
initialProps: { title: 2, 'title_en-US': 1 },
});

expect(result.current).toEqual({ title: 1 });
});
Expand Down
2 changes: 1 addition & 1 deletion packages/preset-dumi/src/theme/hooks/useLocaleProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default <T>(locale: string, props: T) => {

useEffect(() => {
setLocaleProps(processor(locale, props));
}, [locale]);
}, [locale, props]);

return localeProps;
};
12 changes: 6 additions & 6 deletions packages/preset-dumi/src/theme/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,12 @@ export default async () => {
const builtinPath = path.join(modulePath, 'builtins');
const components = fs.existsSync(builtinPath)
? fs
.readdirSync(builtinPath)
.filter(file => /\.(j|t)sx?$/.test(file))
.map(file => ({
identifier: path.parse(file).name,
source: winPath(path.join(theme, 'builtins', file)),
}))
.readdirSync(builtinPath)
.filter(file => /\.(j|t)sx?$/.test(file))
.map(file => ({
identifier: path.parse(file).name,
source: winPath(path.join(theme, 'builtins', file)),
}))
: [];
const fallbacks = REQUIRED_THEME_BUILTINS.reduce((result, name) => {
if (components.every(({ identifier }) => identifier !== name)) {
Expand Down
1 change: 1 addition & 0 deletions packages/preset-dumi/src/utils/getHostPkgAlias.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ describe('getHostPkgAlias', () => {
'dumi',
'@umijs/preset-dumi',
'dumi-theme-default',
"dumi-theme-mobile",
]);
});
});
1 change: 1 addition & 0 deletions packages/theme-default/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "1.0.0-beta.6",
"description": "The official default theme of dumi",
"files": [
"es",
"src"
],
"repository": {
Expand Down
4 changes: 4 additions & 0 deletions packages/theme-mobile/.fatherrc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default {
cjs: false,
esm: 'babel',
};
40 changes: 40 additions & 0 deletions packages/theme-mobile/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
"name": "dumi-theme-mobile",
"version": "1.0.0-beta.0",
"description": "dumi-theme-mobile",
"files": [
"es",
"src"
],
"repository": {
"type": "git",
"url": "https://github.com/umijs/dumi"
},
"keywords": [
"dumi",
"father-build",
"umi"
],
"authors": [
"xiaohuoni <448627663@qq.com> (https://github.com/xiaohuoni)"
],
"license": "MIT",
"bugs": "http://github.com/umijs/dumi/issues",
"homepage": "https://github.com/umijs/dumi/tree/master/packages/theme-mobile#readme",
"publishConfig": {
"access": "public"
},
"devDependencies": {
"dumi": "1.x"
},
"dependencies": {
"dumi-theme-default": "1.0.0-beta.0",
"lodash.debounce": "^4.0.8",
"qrcode.react": "^1.0.0",
"umi-hd": "^5.0.1"
},
"peerDependencies": {
"@umijs/preset-dumi": "1.x",
"react": "^16.13.1"
}
}
22 changes: 22 additions & 0 deletions packages/theme-mobile/src/builtins/Previewer.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@import (reference) '../style/variables.less';

@media @v-device-show {
.@{prefix}-mobile-previewer {
.@{prefix}-previewer-demo {
display: none;
}

.@{prefix}-previewer-desc,
.@{prefix}-previewer-desc:not([data-title]) + .@{prefix}-previewer-actions {
border-top: none;
}

button[role='source'] {
margin-right: -8px;
width: 0;
opacity: 0;
overflow: hidden;
pointer-events: none;
}
}
}
68 changes: 68 additions & 0 deletions packages/theme-mobile/src/builtins/Previewer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React, { useRef, useEffect, useState } from 'react';
import Previewer, { IPreviewerProps } from 'dumi-theme-default/src/builtins/Previewer';
import debounce from 'lodash.debounce';
import './Previewer.less';

export const ACTIVE_MSG_TYPE = 'dumi:scroll-into-demo';

export default (props: IPreviewerProps) => {
const ref = useRef<HTMLDivElement>();
const [previewerProps, setPreviewerProps] = useState<null | IPreviewerProps>(null);
const [isActive, setIsActive] = useState(false);

useEffect(() => {
const isFirstDemo = document.querySelector('.__dumi-default-mobile-previewer') === ref.current;
const handler = debounce(() => {
const scrollTop = document.documentElement.scrollTop + 128;

// post message if scroll into current demo
if (
// fallback to first demo
(isFirstDemo && scrollTop < ref?.current?.offsetTop) ||
// detect scroll position
(scrollTop > ref?.current?.offsetTop &&
scrollTop < ref?.current?.offsetTop + ref?.current?.offsetHeight)
) {
window.postMessage({ type: ACTIVE_MSG_TYPE, value: props.identifier }, '*');
setIsActive(true);
} else {
setIsActive(false);
}
}, 50);

// only render mobile phone when screen max than 960px
if (window?.outerWidth > 960) {
// active source code wrapper if scroll into demo
handler();
window.addEventListener('scroll', handler);

// rewrite props for device mode
setPreviewerProps(
Object.assign({}, props, {
// omit children
children: null,
// show source code
defaultShowCode: true,
// hide external action
hideActions: ['EXTERNAL' as IPreviewerProps['hideActions'][0]].concat(props.hideActions),
}),
);
} else {
// use standard mode if screen min than 960px
setPreviewerProps(props);
}

return () => window.removeEventListener('scroll', handler);
}, []);

return (
<div className="__dumi-default-mobile-previewer" ref={ref}>
{previewerProps && (
<Previewer
className={isActive ? '__dumi-default-previewer-target' : null}
{...previewerProps}
/>
)}
</div>
);
};
139 changes: 139 additions & 0 deletions packages/theme-mobile/src/components/Device.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
@import (reference) '../style/variables.less';

.gen-device-style(@scale) {
width: @s-device-width * @scale;
min-width: @s-device-width * @scale;
height: @s-device-width * @scale * @s-device-ratio;
box-shadow: 0 0 0 @s-device-border-width * @scale #090a0d,
0 0 0 @s-device-shell-width * @scale #9fa3a8,
0 4px 20px @s-device-shell-width * @scale rgba(0, 0, 0, 0.1);
}

.@{prefix}-device {
position: sticky;
top: @s-device-gap-top;
display: flex;
flex-direction: column;
margin-left: @s-content-margin;
width: @s-device-width;
min-width: @s-device-width;
height: @s-device-width * @s-device-ratio;
border-radius: 32px;
overflow: hidden;
.gen-device-style(1);

@media only screen and (max-width: 1440px) {
.gen-device-style(0.9);
}

@media only screen and (max-width: 1360px) {
.gen-device-style(0.8);
}

@media only screen and (max-width: 960px) {
display: none;
}

&[data-mode='site'] {
top: @s-nav-height + @s-device-shell-width + @s-device-gap-top;
}

&-status,
&-action {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 22px;
}

&-status {
height: 30px;
color: #222;
font-size: 12px;
font-weight: 500;
user-select: none;

span {
display: inline-block;
width: 60px;

&:nth-child(2) {
text-align: center;
}
}

// battery
&::after {
content: '';
display: inline-block;
margin-left: 42px;
width: 14px;
height: 5px;
border-radius: 1px;
background: #50d664;
box-shadow: 0 0 0 1px #fff, 0 0 0 2px #999;
}
}

&-action {
height: 40px;
background: #f3f3f3;
border-top: 1px solid #e3e3e3;

> a,
> button {
padding: 0;
width: 16px;
height: 16px;
box-sizing: content-box;
border: 2px solid transparent;
transition: opacity 0.2s, background 0.2s;
outline: none;
cursor: pointer;

&:hover {
opacity: 0.8;
}

&:active {
opacity: 0.9;
}

&[role='refresh'] {
background-position-x: -144px;
}

&[role='open-demo'] {
background-position-x: -126px;
}

&[role='qrcode'] {
position: relative;
z-index: 1;
background-position-x: -218px;

> canvas {
position: absolute;
bottom: 120%;
left: 50%;
border: 4px solid #fff;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
box-sizing: content-box;
transition: all 0.2s ease-in-out;
transform: translateX(-50%) scale(0);
transform-origin: center bottom;
}

&:hover > canvas,
&:focus > canvas {
transform: translateX(-50%) scale(1);
}
}
}
}

> iframe {
flex: 1;
border: 0;
}
}
Loading