Skip to content

Commit

Permalink
Merge pull request #126 from heluxjs/doc
Browse files Browse the repository at this point in the history
chore: optimize playground, allow input slash
  • Loading branch information
fantasticsoul authored Jan 14, 2024
2 parents 8f8c6b6 + e75e5f1 commit c52639e
Show file tree
Hide file tree
Showing 13 changed files with 920 additions and 23 deletions.
2 changes: 2 additions & 0 deletions docs/.dumi/theme/slots/Features/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
@media @mobile {
width: 100%;
margin-inline-end: 0;
margin-top: 60px;
height: 290px !important;
}
}

Expand Down
17 changes: 8 additions & 9 deletions docs/.dumi/theme/slots/Features/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,14 @@ const imgs = [
'https://tnfe.gtimg.com/image/ngex07gcez_1651755956158.png',
'https://tnfe.gtimg.com/image/harzqyxcgz_1651755973579.png',
];
const defaultImg = imgs[0];
const stWrap: React.CSSProperties = {
boxShadow: '1px 2px 2px 1px rgba(0, 0, 255, .2)',
backgroundColor: '#fff',
borderRadius: '6px',
padding: '24px 24px',
boxSizing: 'border-box',
height: '270px',
};

function getImg(idx: number) {
return imgs[idx] || imgs[0];
Expand Down Expand Up @@ -39,14 +46,6 @@ const Features: FC = () => {
);
}

const stWrap: React.CSSProperties = {
boxShadow: '1px 2px 2px 1px rgba(0, 0, 255, .2)',
backgroundColor: '#fff',
borderRadius: '6px',
padding: '24px 24px',
boxSizing: 'border-box',
height: '270px',
};
return (
<div
key={title}
Expand Down
50 changes: 50 additions & 0 deletions docs/.dumi/theme/slots/SearchBar/Input.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useIntl } from 'dumi';
import React, { forwardRef, useImperativeHandle, useRef } from 'react';

type NativeInputProps = React.DetailedHTMLProps<
React.InputHTMLAttributes<HTMLInputElement>,
HTMLInputElement
>;

type InputProps = {
onChange: (keywords: string) => void;
} & Pick<NativeInputProps, 'onFocus' | 'onBlur'>;

export const Input = forwardRef<HTMLInputElement, InputProps>((props, ref) => {
const intl = useIntl();

const imeWaiting = useRef(false);
const nativeInputRef = useRef<HTMLInputElement>(null);

useImperativeHandle(ref, () => nativeInputRef.current!);

return (
<input
className="dumi-default-search-bar-input"
onCompositionStart={() => (imeWaiting.current = true)}
onCompositionEnd={(ev) => {
imeWaiting.current = false;
// special case: press Enter open IME panel will not trigger onChange
props.onChange(ev.currentTarget.value);
}}
onFocus={props.onFocus}
onBlur={props.onBlur}
onKeyDown={(ev) => {
if (['ArrowDown', 'ArrowUp'].includes(ev.key)) ev.preventDefault();
// esc to blur input
if (ev.key === 'Escape' && !imeWaiting.current) ev.currentTarget.blur();
}}
onChange={(ev) => {
// wait for onCompositionEnd event be triggered
const value = ev.target.value;
setTimeout(() => {
if (!imeWaiting.current) {
props.onChange(value);
}
}, 1);
}}
placeholder={intl.formatMessage({ id: 'header.search.placeholder' })}
ref={nativeInputRef}
/>
);
});
29 changes: 29 additions & 0 deletions docs/.dumi/theme/slots/SearchBar/Mask.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { useEffect, type FC, type ReactNode } from 'react';

type MaskProps = {
visible: boolean;
children: ReactNode;
onMaskClick?: () => void;
onClose?: () => void;
};

export const Mask: FC<MaskProps> = (props) => {
useEffect(() => {
if (props.visible) {
document.body.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
props.onClose?.();
}
}, [props.visible]);

return props.visible ? (
<div className="dumi-default-search-modal">
<div
className="dumi-default-search-modal-mask"
onClick={props.onMaskClick}
/>
<div className="dumi-default-search-modal-content">{props.children}</div>
</div>
) : null;
};
244 changes: 244 additions & 0 deletions docs/.dumi/theme/slots/SearchBar/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
@import (reference) '../../styles/variables.less';

.@{prefix}-search-bar {
position: relative;

@media @mobile {
// TODO: support search for mobile devices
display: none;
}

&:not(:last-child) {
margin-inline-end: 28px;
}

&-svg {
position: absolute;
top: 50%;
margin-top: 1px;
inset-inline-start: 16px;
width: 16px;
fill: @c-text-note;
transform: translateY(-50%);

@{dark-selector} & {
fill: @c-text-note-dark;
}
}

&-input {
width: 280px;
height: 40px;
padding: 0;
padding-inline-start: 40px;
padding-inline-end: 12px;
color: @c-text;
font-size: 14px;
border: 1px solid @c-border;
border-radius: 20px;
box-sizing: border-box;
outline: none;
transition: all 0.3s;
background-color: transparent;

@{dark-selector} & {
color: @c-text-dark;
border-color: @c-border-dark;
}

&:focus {
border-color: fade(@c-primary, 50%);
background-color: #fff;
box-shadow: 0 0 0 3px fade(@c-primary, 10%);

@{dark-selector} & {
border-color: fade(@c-primary-dark, 50%);
background-color: @c-site-bg-dark;
box-shadow: 0 0 0 3px fade(@c-primary-dark, 10%);
}
}

&:focus,
&:not(:placeholder-shown) {
~ .@{prefix}-search-shortcut {
opacity: 0;
}
}
}

.@{prefix}-search-shortcut {
position: absolute;
top: 50%;
inset-inline-end: 11px;
display: inline-block;
padding: 4px 8px;
color: @c-text-note;
font-size: 12px;
line-height: 1;
white-space: nowrap;
background-color: fade(#fff, 80%);
border-radius: 11px;
border: 1px solid @c-border;
transform: translateY(-50%);
transition: all 0.3s;
pointer-events: none;

@{dark-selector} & {
background-color: fade(#000, 20%);
border-color: @c-border-dark;
}

@media @mobile {
display: none;
}
}

.@{prefix}-search-popover {
position: absolute;
top: 100%;
inset-inline-end: 0;
display: flex;
flex-direction: column;
width: 540px;
max-height: 460px;
margin-top: 18px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 20%);

@{dark-selector} & {
background-color: lighten(@c-site-bg-dark, 6%);
}

&::before {
content: '';
position: absolute;
bottom: 100%;
inset-inline-end: 100px;
display: inline-block;
width: 0;
height: 0;
border: 8px solid transparent;
border-bottom-color: #fff;

@{dark-selector} & {
border-bottom-color: lighten(@c-site-bg-dark, 6%);
}
}

> section {
flex: 1;
min-height: 60px;
overflow: auto;
overscroll-behavior: contain;
-webkit-overflow-scrolling: touch;
border-radius: inherit;
}
}

.@{prefix}-search-modal {
position: fixed;
top: 0;
inset-inline-start: 0;
z-index: 1000;
width: 100vw;
height: 100vh;
display: flex;
justify-content: center;

&-mask {
background-color: rgba(0, 0, 0, 45%);
width: 100%;
height: 100%;
}

&-content {
position: absolute;
top: 60px;
background-color: #fff;
width: 500px;
padding: 12px;
box-sizing: border-box;
box-shadow: inset 1px 1px 0 0 hsla(0deg, 0%, 100%, 50%),
0 3px 8px 0 #555a64;
border-radius: 8px;
max-height: calc(100% - 120px);
display: flex;
flex-direction: column;

@{dark-selector} & {
background-color: lighten(@c-site-bg-dark, 6%);
}
}

.@{prefix}-search-bar-input {
width: 100%;
border-radius: 4px;
}

.@{prefix}-search-result {
min-height: 60px;
margin-top: 12px;
flex: auto;
overflow: auto;

> dl > dd {
margin: 0 auto;
}
}

&-commands {
justify-content: flex-start;
font-size: 12px;
color: @c-text-note;
list-style: none;
padding: 0;
margin: 0;
border-top: 1px solid @c-border-light;
padding-top: 12px;
display: flex;
align-items: center;
user-select: none;

@{dark-selector} & {
color: @c-text-note-dark;
border-top-color: @c-border-less-dark;
}

> li {
margin-inline-end: 10px;
}

&-arrow {
.@{prefix}-search-modal-shortcut {
margin-inline-end: 4px;
}
}

&-text {
margin-inline-start: 5px;
}
}

&-shortcut {
display: inline-block;
padding: 4px 8px;
color: @c-text-note;
font-size: 12px;
line-height: 1;
white-space: nowrap;
background-color: @c-site-bg;
border-radius: 3px;
border: 1px solid @c-border;
border-bottom-width: 2px;
transition: all 0.3s;
pointer-events: none;

@{dark-selector} & {
color: @c-text-note-dark;
background-color: @c-site-bg-dark;
border-color: @c-border-dark;
}
}
}
}
Loading

0 comments on commit c52639e

Please sign in to comment.