feat: update typography

zkwolf-typography
tangjinzhou 2021-03-14 22:50:17 +08:00
parent 2515077386
commit 2191656479
11 changed files with 248 additions and 158 deletions

View File

@ -0,0 +1,8 @@
import { computed, inject } from 'vue';
import { defaultConfigProvider } from '../../config-provider';
export default (name: string, props: Record<any, any>) => {
const configProvider = inject('configProvider', defaultConfigProvider);
const prefixCls = computed(() => configProvider.getPrefixCls(name, props.prefixCls));
return { configProvider, prefixCls };
};

View File

@ -11,29 +11,26 @@ import Typography, { TypographyProps } from './Typography';
import ResizeObserver from '../vc-resize-observer'; import ResizeObserver from '../vc-resize-observer';
import Tooltip from '../tooltip'; import Tooltip from '../tooltip';
import copy from '../_util/copy-to-clipboard'; import copy from '../_util/copy-to-clipboard';
import { defaultConfigProvider } from '../config-provider';
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined'; import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
import CopyOutlined from '@ant-design/icons-vue/CopyOutlined'; import CopyOutlined from '@ant-design/icons-vue/CopyOutlined';
import EditOutlined from '@ant-design/icons-vue/EditOutlined'; import EditOutlined from '@ant-design/icons-vue/EditOutlined';
import { import {
defineComponent, defineComponent,
inject,
VNodeTypes, VNodeTypes,
Text,
VNode, VNode,
reactive, reactive,
ref, ref,
onMounted, onMounted,
onUpdated,
onBeforeUnmount, onBeforeUnmount,
watch, watch,
watchEffect, watchEffect,
nextTick, nextTick,
CSSProperties, CSSProperties,
toRaw, toRaw,
computed,
} from 'vue'; } from 'vue';
import { filterEmpty } from '../_util/props-util';
import { AutoSizeType } from '../input/ResizableTextArea'; import { AutoSizeType } from '../input/ResizableTextArea';
import useConfigInject from '../_util/hooks/useConfigInject';
export type BaseType = 'secondary' | 'success' | 'warning' | 'danger'; export type BaseType = 'secondary' | 'success' | 'warning' | 'danger';
@ -63,7 +60,7 @@ interface EditConfig {
tooltip?: boolean | VNodeTypes; tooltip?: boolean | VNodeTypes;
onStart?: () => void; onStart?: () => void;
onChange?: (value: string) => void; onChange?: (value: string) => void;
maxLength?: number; maxlength?: number;
autoSize?: boolean | AutoSizeType; autoSize?: boolean | AutoSizeType;
} }
@ -74,7 +71,7 @@ export interface EllipsisConfig {
symbol?: VNodeTypes; symbol?: VNodeTypes;
onExpand?: EventHandlerNonNull; onExpand?: EventHandlerNonNull;
onEllipsis?: (ellipsis: boolean) => void; onEllipsis?: (ellipsis: boolean) => void;
tooltip?: VNodeTypes; tooltip?: boolean | VNodeTypes;
} }
export interface BlockProps extends TypographyProps { export interface BlockProps extends TypographyProps {
@ -91,6 +88,7 @@ export interface BlockProps extends TypographyProps {
delete?: boolean; delete?: boolean;
strong?: boolean; strong?: boolean;
keyboard?: boolean; keyboard?: boolean;
content?: string;
} }
interface Locale { interface Locale {
@ -110,7 +108,7 @@ const Base = defineComponent<InternalBlockProps>({
name: 'Base', name: 'Base',
inheritAttrs: false, inheritAttrs: false,
setup(props, { slots, attrs }) { setup(props, { slots, attrs }) {
const configProvider = inject('configProvider', defaultConfigProvider); const { prefixCls } = useConfigInject('typography', props);
const state = reactive({ const state = reactive({
edit: false, edit: false,
@ -133,25 +131,20 @@ const Base = defineComponent<InternalBlockProps>({
const contentRef = ref(); const contentRef = ref();
const editIcon = ref(); const editIcon = ref();
const ellipsis = computed(
(): EllipsisConfig => {
const ellipsis = props.ellipsis;
if (!ellipsis) return {};
return {
rows: 1,
expandable: false,
...(typeof ellipsis === 'object' ? ellipsis : null),
};
},
);
onMounted(() => { onMounted(() => {
state.prevProps = { ...props, children: getChildren() };
state.clientRendered = true; state.clientRendered = true;
resizeOnNextFrame();
});
onUpdated(() => {
const ellipsis = getEllipsis();
const prevEllipsis = getEllipsis(state.prevProps);
const children = getChildren();
if (
JSON.stringify(children) !== JSON.stringify(toRaw(state.prevProps.children)) ||
ellipsis.rows !== prevEllipsis.rows
) {
resizeOnNextFrame();
}
state.prevProps = { ...props, children };
}); });
onBeforeUnmount(() => { onBeforeUnmount(() => {
@ -160,25 +153,29 @@ const Base = defineComponent<InternalBlockProps>({
}); });
watch( watch(
() => props.ellipsis, [() => ellipsis.value.rows, () => props.content],
() => { () => {
nextTick(() => {
resizeOnNextFrame(); resizeOnNextFrame();
});
}, },
{ flush: 'post', deep: true, immediate: true },
); );
watchEffect(() => { watchEffect(() => {
const children = getChildren(); if (!('content' in props)) {
warning( warning(
!props.editable || children.every(item => item.type === Text), !props.editable,
'Typography', 'Typography',
'When `editable` is enabled, the `children` should use string.', 'When `editable` is enabled, please use `content` instead of children',
);
warning(
!props.ellipsis,
'Typography',
'When `ellipsis` is enabled, please use `content` instead of children',
); );
});
function getChildren() {
return filterEmpty(slots.default?.());
} }
});
function saveTypographyRef(node: VNode) { function saveTypographyRef(node: VNode) {
contentRef.value = node; contentRef.value = node;
@ -189,23 +186,14 @@ const Base = defineComponent<InternalBlockProps>({
} }
function getChildrenText(): string { function getChildrenText(): string {
const children = getChildren(); return props.ellipsis || props.editable ? props.content : contentRef.value.text;
return children.length !== 0
? children
.filter(item => item.type === Text)
.map(item => item.children)
.reduce((cur, prev) => cur + prev, '')
: '';
} }
// =============== Expand =============== // =============== Expand ===============
function onExpandClick(e: MouseEvent) { function onExpandClick(e: MouseEvent) {
const { onExpand } = getEllipsis(); const { onExpand } = ellipsis.value;
state.expanded = true; state.expanded = true;
onExpand?.(e);
if (onExpand) {
onExpand(e);
}
} }
// ================ Edit ================ // ================ Edit ================
function onEditClick() { function onEditClick() {
@ -213,10 +201,8 @@ const Base = defineComponent<InternalBlockProps>({
} }
function onEditChange(value: string) { function onEditChange(value: string) {
const { onChange } = getEditable(); const { onChange } = editable.value;
if (onChange) { onChange?.(value);
onChange(value);
}
triggerEdit(false); triggerEdit(false);
} }
@ -226,7 +212,8 @@ const Base = defineComponent<InternalBlockProps>({
} }
// ================ Copy ================ // ================ Copy ================
function onCopyClick() { function onCopyClick(e: MouseEvent) {
e.preventDefault();
const { copyable } = props; const { copyable } = props;
const copyConfig = { const copyConfig = {
@ -250,30 +237,18 @@ const Base = defineComponent<InternalBlockProps>({
}, 3000); }, 3000);
}); });
} }
const editable = computed(() => {
function getEditable($props?: BlockProps): EditConfig { const editable = props.editable;
const editable = ($props || props).editable;
if (!editable) return { editing: state.edit }; if (!editable) return { editing: state.edit };
return { return {
editing: state.edit, editing: state.edit,
...(typeof editable === 'object' ? editable : null), ...(typeof editable === 'object' ? editable : null),
}; };
} });
function getEllipsis($props?: BlockProps): EllipsisConfig {
const ellipsis = ($props || props).ellipsis;
if (!ellipsis) return {};
return {
rows: 1,
expandable: false,
...(typeof ellipsis === 'object' ? ellipsis : null),
};
}
function triggerEdit(edit: boolean) { function triggerEdit(edit: boolean) {
const { onStart } = getEditable(); const { onStart } = editable.value;
if (edit && onStart) { if (edit && onStart) {
onStart(); onStart();
} }
@ -295,13 +270,13 @@ const Base = defineComponent<InternalBlockProps>({
}); });
} }
function canUseCSSEllipsis(): boolean { const canUseCSSEllipsis = computed(() => {
const { rows, expandable, suffix } = getEllipsis(); const { rows, expandable, suffix, onEllipsis, tooltip } = ellipsis.value;
if (suffix) return false; if (suffix || tooltip) return false;
// Can't use css ellipsis since we need to provide the place for button // Can't use css ellipsis since we need to provide the place for button
if (props.editable || props.copyable || expandable || !state.clientRendered) { if (props.editable || props.copyable || expandable || onEllipsis) {
return false; return false;
} }
@ -310,40 +285,33 @@ const Base = defineComponent<InternalBlockProps>({
} }
return isLineClampSupport; return isLineClampSupport;
} });
function syncEllipsis() { const syncEllipsis = () => {
const { ellipsisText, isEllipsis } = state; const { ellipsisText, isEllipsis } = state;
const children = getChildren(); const { rows, suffix, onEllipsis } = ellipsis.value;
const { rows, suffix, onEllipsis } = getEllipsis();
if (!rows || rows < 0 || !contentRef.value?.$el || state.expanded) return; if (!rows || rows < 0 || !contentRef.value?.$el || state.expanded) return;
// Do not measure if css already support ellipsis // Do not measure if css already support ellipsis
if (canUseCSSEllipsis()) return; if (canUseCSSEllipsis.value) return;
warning( const { content, text, ellipsis: ell } = measure(
children.every(item => item.type === Text),
'Typography',
'`ellipsis` should use string as children only.',
);
const { content, text, ellipsis } = measure(
contentRef.value?.$el, contentRef.value?.$el,
{ rows, suffix }, { rows, suffix },
children, props.content,
renderOperations(true), renderOperations(true),
ELLIPSIS_STR, ELLIPSIS_STR,
); );
if (ellipsisText !== text || state.isEllipsis !== ellipsis) { if (ellipsisText !== text || state.isEllipsis !== ell) {
state.ellipsisText = text; state.ellipsisText = text;
state.ellipsisContent = content; state.ellipsisContent = content;
state.isEllipsis = ellipsis; state.isEllipsis = ell;
if (isEllipsis !== ellipsis && onEllipsis) { if (isEllipsis !== ell && onEllipsis) {
onEllipsis(ellipsis); onEllipsis(ell);
}
} }
} }
};
function wrapperDecorations( function wrapperDecorations(
{ mark, code, underline, delete: del, strong, keyboard }: BlockProps, { mark, code, underline, delete: del, strong, keyboard }: BlockProps,
@ -368,8 +336,7 @@ const Base = defineComponent<InternalBlockProps>({
} }
function renderExpand(forceRender?: boolean) { function renderExpand(forceRender?: boolean) {
const { expandable, symbol } = getEllipsis(); const { expandable, symbol } = ellipsis.value;
const prefixCls = getPrefixCls();
if (!expandable) return null; if (!expandable) return null;
@ -386,7 +353,7 @@ const Base = defineComponent<InternalBlockProps>({
return ( return (
<a <a
key="expand" key="expand"
class={`${prefixCls}-expand`} class={`${prefixCls.value}-expand`}
onClick={onExpandClick} onClick={onExpandClick}
aria-label={state.expandStr} aria-label={state.expandStr}
> >
@ -398,7 +365,6 @@ const Base = defineComponent<InternalBlockProps>({
function renderEdit() { function renderEdit() {
if (!props.editable) return; if (!props.editable) return;
const prefixCls = getPrefixCls();
const { icon, tooltip } = props.editable as EditConfig; const { icon, tooltip } = props.editable as EditConfig;
const title = tooltip || state.editStr; const title = tooltip || state.editStr;
@ -408,7 +374,7 @@ const Base = defineComponent<InternalBlockProps>({
<Tooltip key="edit" title={tooltip === false ? '' : title}> <Tooltip key="edit" title={tooltip === false ? '' : title}>
<TransButton <TransButton
ref={saveEditIconRef} ref={saveEditIconRef}
class={`${prefixCls}-edit`} class={`${prefixCls.value}-edit`}
onClick={onEditClick} onClick={onEditClick}
aria-label={ariaLabel} aria-label={ariaLabel}
> >
@ -421,8 +387,6 @@ const Base = defineComponent<InternalBlockProps>({
function renderCopy() { function renderCopy() {
if (!props.copyable) return; if (!props.copyable) return;
const prefixCls = getPrefixCls();
const { tooltips } = props.copyable as CopyConfig; const { tooltips } = props.copyable as CopyConfig;
let tooltipNodes = toArray(tooltips) as VNodeTypes[]; let tooltipNodes = toArray(tooltips) as VNodeTypes[];
if (tooltipNodes.length === 0) { if (tooltipNodes.length === 0) {
@ -435,7 +399,10 @@ const Base = defineComponent<InternalBlockProps>({
return ( return (
<Tooltip key="copy" title={tooltips === false ? '' : title}> <Tooltip key="copy" title={tooltips === false ? '' : title}>
<TransButton <TransButton
class={[`${prefixCls}-copy`, { [`${prefixCls}-copy-success`]: state.copied }]} class={[
`${prefixCls.value}-copy`,
{ [`${prefixCls.value}-copy-success`]: state.copied },
]}
onClick={onCopyClick} onClick={onCopyClick}
aria-label={ariaLabel} aria-label={ariaLabel}
> >
@ -446,19 +413,16 @@ const Base = defineComponent<InternalBlockProps>({
} }
function renderEditInput() { function renderEditInput() {
const prefixCls = getPrefixCls();
const { class: className, style } = attrs; const { class: className, style } = attrs;
const { maxLength, autoSize } = getEditable(); const { maxlength, autoSize } = editable.value;
const value = getChildrenText();
return ( return (
<Editable <Editable
class={className} class={className}
style={style} style={style}
prefixCls={prefixCls} prefixCls={prefixCls.value}
value={value} value={props.content}
maxlength={maxLength} maxlength={maxlength}
autoSize={autoSize} autoSize={autoSize}
onSave={onEditChange} onSave={onEditChange}
onCancel={onEditCancel} onCancel={onEditCancel}
@ -470,14 +434,14 @@ const Base = defineComponent<InternalBlockProps>({
return [renderExpand(forceRenderExpanded), renderEdit(), renderCopy()].filter(node => node); return [renderExpand(forceRenderExpanded), renderEdit(), renderCopy()].filter(node => node);
} }
function getPrefixCls() {
const getPrefixCls = configProvider.getPrefixCls;
return getPrefixCls('typography', props.prefixCls);
}
return () => { return () => {
const { editing } = getEditable(); const { editing } = editable.value;
const children = filterEmpty(slots.default?.()); const children =
props.ellipsis || props.editable
? props.content
: slots.default
? slots.default()
: props.content;
if (editing) { if (editing) {
return renderEditInput(); return renderEditInput();
@ -486,9 +450,11 @@ const Base = defineComponent<InternalBlockProps>({
<LocaleReceiver <LocaleReceiver
componentName="Text" componentName="Text"
children={(locale: Locale) => { children={(locale: Locale) => {
const { type, disabled, title, ...restProps } = props; const { type, disabled, title, content, class: className, style, ...restProps } = {
const { class: className, style } = attrs; ...props,
const { rows, suffix } = getEllipsis(); ...attrs,
};
const { rows, suffix, tooltip } = ellipsis.value;
const { edit, copy: copyStr, copied, expand } = locale; const { edit, copy: copyStr, copied, expand } = locale;
@ -510,7 +476,7 @@ const Base = defineComponent<InternalBlockProps>({
'keyboard', 'keyboard',
]); ]);
const cssEllipsis = canUseCSSEllipsis(); const cssEllipsis = canUseCSSEllipsis.value;
const cssTextOverflow = rows === 1 && cssEllipsis; const cssTextOverflow = rows === 1 && cssEllipsis;
const cssLineClamp = rows && rows > 1 && cssEllipsis; const cssLineClamp = rows && rows > 1 && cssEllipsis;
@ -520,10 +486,8 @@ const Base = defineComponent<InternalBlockProps>({
// Only use js ellipsis when css ellipsis not support // Only use js ellipsis when css ellipsis not support
if (rows && state.isEllipsis && !state.expanded && !cssEllipsis) { if (rows && state.isEllipsis && !state.expanded && !cssEllipsis) {
ariaLabel = title; ariaLabel = title;
if (!title && children.every(item => item.type === Text)) { if (!title) {
ariaLabel = children ariaLabel = content;
.map(item => item.children)
.reduce((cur, prev) => cur + prev, '');
} }
// We move full content to outer element to avoid repeat read the content by accessibility // We move full content to outer element to avoid repeat read the content by accessibility
textNode = ( textNode = (
@ -533,6 +497,14 @@ const Base = defineComponent<InternalBlockProps>({
{suffix} {suffix}
</span> </span>
); );
// If provided tooltip, we need wrap with span to let Tooltip inject events
if (tooltip) {
textNode = (
<Tooltip title={tooltip === true ? children : tooltip}>
<span>{textNode}</span>
</Tooltip>
);
}
} else { } else {
textNode = ( textNode = (
<> <>
@ -544,23 +516,21 @@ const Base = defineComponent<InternalBlockProps>({
textNode = wrapperDecorations(props, textNode); textNode = wrapperDecorations(props, textNode);
const prefixCls = getPrefixCls();
return ( return (
<ResizeObserver onResize={resizeOnNextFrame} disabled={!rows}> <ResizeObserver onResize={resizeOnNextFrame} disabled={!rows}>
<Typography <Typography
ref={saveTypographyRef} ref={saveTypographyRef}
class={[ class={[
{ [`${prefixCls}-${type}`]: type }, { [`${prefixCls.value}-${type}`]: type },
{ [`${prefixCls}-disabled`]: disabled }, { [`${prefixCls.value}-disabled`]: disabled },
{ [`${prefixCls}-ellipsis`]: rows }, { [`${prefixCls.value}-ellipsis`]: rows },
{ [`${prefixCls}-ellipsis-single-line`]: cssTextOverflow }, { [`${prefixCls.value}-ellipsis-single-line`]: cssTextOverflow },
{ [`${prefixCls}-ellipsis-multiple-line`]: cssLineClamp }, { [`${prefixCls.value}-ellipsis-multiple-line`]: cssLineClamp },
className, className,
]} ]}
style={{ style={{
...(style as CSSProperties), ...(style as CSSProperties),
WebkitLineClamp: cssLineClamp ? rows : null, WebkitLineClamp: cssLineClamp ? rows : undefined,
}} }}
aria-label={ariaLabel} aria-label={ariaLabel}
{...textProps} {...textProps}
@ -582,7 +552,7 @@ export const baseProps = () => ({
copyable: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]), copyable: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]),
prefixCls: PropTypes.string, prefixCls: PropTypes.string,
component: PropTypes.string, component: PropTypes.string,
type: PropTypes.oneOf(['secondary', 'danger', 'warning']), type: PropTypes.oneOf(['secondary', 'success', 'danger', 'warning']),
disabled: PropTypes.looseBool, disabled: PropTypes.looseBool,
ellipsis: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]), ellipsis: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]),
code: PropTypes.looseBool, code: PropTypes.looseBool,
@ -591,6 +561,7 @@ export const baseProps = () => ({
delete: PropTypes.looseBool, delete: PropTypes.looseBool,
strong: PropTypes.looseBool, strong: PropTypes.looseBool,
keyboard: PropTypes.looseBool, keyboard: PropTypes.looseBool,
content: PropTypes.string,
}); });
Base.props = baseProps(); Base.props = baseProps();

View File

@ -25,10 +25,10 @@ const Link: FunctionalComponent<LinkProps> = (props, { slots, attrs }) => {
// @ts-ignore // @ts-ignore
delete mergedProps.navigate; delete mergedProps.navigate;
return <Base {...mergedProps}>{slots.default?.()}</Base>; return <Base {...mergedProps} v-slots={slots}></Base>;
}; };
Link.displayName = 'ATypographyText'; Link.displayName = 'ATypographyLink';
Link.inheritAttrs = false; Link.inheritAttrs = false;
Link.props = Omit({ ...baseProps(), ellipsis: PropTypes.looseBool }, ['component']); Link.props = Omit({ ...baseProps(), ellipsis: PropTypes.looseBool }, ['component']);

View File

@ -9,7 +9,7 @@ const Paragraph: FunctionalComponent<BlockProps> = (props, { slots, attrs }) =>
...attrs, ...attrs,
}; };
return <Base {...paragraphProps}>{slots.default?.()}</Base>; return <Base {...paragraphProps} v-slots={slots}></Base>;
}; };
Paragraph.displayName = 'ATypographyParagraph'; Paragraph.displayName = 'ATypographyParagraph';

View File

@ -27,7 +27,7 @@ const Text: FunctionalComponent<TextProps> = (props, { slots, attrs }) => {
...attrs, ...attrs,
}; };
return <Base {...textProps}>{slots.default?.()}</Base>; return <Base {...textProps} v-slots={slots}></Base>;
}; };
Text.displayName = 'ATypographyText'; Text.displayName = 'ATypographyText';

View File

@ -25,7 +25,7 @@ const Title: FunctionalComponent<TitleProps> = (props, { slots, attrs }) => {
...attrs, ...attrs,
}; };
return <Base {...titleProps}>{slots.default?.()}</Base>; return <Base {...titleProps} v-slots={slots}></Base>;
}; };
Title.displayName = 'ATypographyTitle'; Title.displayName = 'ATypographyTitle';

View File

@ -1,9 +1,11 @@
import { defaultConfigProvider } from '../config-provider';
import Text from './Text'; import Text from './Text';
import Title from './Title'; import Title from './Title';
import Paragraph from './Paragraph'; import Paragraph from './Paragraph';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';
import { defineComponent, HTMLAttributes, inject, App, Plugin } from 'vue'; import { defineComponent, HTMLAttributes, App, Plugin, computed } from 'vue';
import useConfigInject from '../_util/hooks/useConfigInject';
import Link from './Link';
import classNames from '../_util/classNames';
export interface TypographyProps extends HTMLAttributes { export interface TypographyProps extends HTMLAttributes {
prefixCls?: string; prefixCls?: string;
@ -18,14 +20,22 @@ const Typography = defineComponent<InternalTypographyProps>({
Text: Text, Text: Text,
Title: Title, Title: Title,
Paragraph: Paragraph, Paragraph: Paragraph,
setup(props, { slots }) { Link: Link,
const { getPrefixCls } = inject('configProvider', defaultConfigProvider); inheritAttrs: false,
setup(props, { slots, attrs }) {
const { prefixCls } = useConfigInject('typography', props);
return () => { return () => {
const { prefixCls: customizePrefixCls, component: Component = 'article' as any } = props; const {
const prefixCls = getPrefixCls('typography', customizePrefixCls); prefixCls: _prefixCls,
class: _className,
return <Component class={prefixCls}>{slots.default?.()}</Component>; component: Component = 'article' as any,
...restProps
} = { ...props, ...attrs };
return (
<Component class={classNames(prefixCls.value, attrs.class)} {...restProps}>
{slots.default?.()}
</Component>
);
}; };
}, },
}); });
@ -40,6 +50,7 @@ Typography.install = function(app: App) {
app.component(Typography.Text.displayName, Text); app.component(Typography.Text.displayName, Text);
app.component(Typography.Title.displayName, Title); app.component(Typography.Title.displayName, Title);
app.component(Typography.Paragraph.displayName, Paragraph); app.component(Typography.Paragraph.displayName, Paragraph);
app.component(Typography.Link.displayName, Link);
return app; return app;
}; };
@ -48,4 +59,5 @@ export default Typography as typeof Typography &
readonly Text: typeof Text; readonly Text: typeof Text;
readonly Title: typeof Title; readonly Title: typeof Title;
readonly Paragraph: typeof Paragraph; readonly Paragraph: typeof Paragraph;
readonly Link: typeof Link;
}; };

View File

@ -22,6 +22,11 @@
&&-danger { &&-danger {
color: @error-color; color: @error-color;
a&:active,
a&:focus,
a&:hover {
color: ~`colorPalette('@{error-color}', 5) `;
}
} }
&&-disabled { &&-disabled {
@ -60,7 +65,8 @@
h1&, h1&,
h2&, h2&,
h3&, h3&,
h4& h5& { h4&,
h5& {
.@{typography-prefix-cls} + & { .@{typography-prefix-cls} + & {
margin-top: @typography-title-margin-top; margin-top: @typography-title-margin-top;
} }
@ -92,25 +98,35 @@
a&, a&,
a { a {
.operation-unit(); .operation-unit();
text-decoration: @link-decoration;
&:active, &:active,
&:hover { &:hover {
text-decoration: @link-hover-decoration; text-decoration: @link-hover-decoration;
} }
&[disabled] { &[disabled],
&.@{typography-prefix-cls}-disabled {
color: @disabled-color; color: @disabled-color;
cursor: not-allowed; cursor: not-allowed;
&:active,
&:hover {
color: @disabled-color;
}
&:active {
pointer-events: none; pointer-events: none;
} }
} }
}
code { code {
margin: 0 0.2em; margin: 0 0.2em;
padding: 0.2em 0.4em 0.1em; padding: 0.2em 0.4em 0.1em;
font-size: 85%; font-size: 85%;
background: rgba(0, 0, 0, 0.06); background: rgba(150, 150, 150, 0.1);
border: 1px solid rgba(0, 0, 0, 0.06); border: 1px solid rgba(100, 100, 100, 0.2);
border-radius: 3px; border-radius: 3px;
} }
@ -178,11 +194,6 @@
bottom: 8px; bottom: 8px;
color: @text-color-secondary; color: @text-color-secondary;
pointer-events: none; pointer-events: none;
.@{typography-prefix-cls}-rtl & {
right: auto;
left: 10px;
}
} }
// Fix Editable Textarea flash in Firefox // Fix Editable Textarea flash in Firefox
@ -215,6 +226,38 @@
list-style-type: decimal; list-style-type: decimal;
} }
// pre & block
pre,
blockquote {
margin: 1em 0;
}
pre {
padding: 0.4em 0.6em;
white-space: pre-wrap;
word-wrap: break-word;
background: rgba(150, 150, 150, 0.1);
border: 1px solid rgba(100, 100, 100, 0.2);
border-radius: 3px;
// Compatible for marked
code {
display: inline;
margin: 0;
padding: 0;
font-size: inherit;
font-family: inherit;
background: transparent;
border: 0;
}
}
blockquote {
padding: 0 0 0 0.6em;
border-left: 4px solid rgba(100, 100, 100, 0.2);
opacity: 0.85;
}
// ============ Ellipsis ============ // ============ Ellipsis ============
&-ellipsis-single-line { &-ellipsis-single-line {
overflow: hidden; overflow: hidden;
@ -230,9 +273,11 @@
&-ellipsis-multiple-line { &-ellipsis-multiple-line {
display: -webkit-box; display: -webkit-box;
overflow: hidden;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
/*! autoprefixer: ignore next */ /*! autoprefixer: ignore next */
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
overflow: hidden;
} }
} }
@import './rtl';

View File

@ -0,0 +1,54 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@typography-prefix-cls: ~'@{ant-prefix}-typography';
.@{typography-prefix-cls} {
&-rtl {
direction: rtl;
}
// Operation
&-expand,
&-edit,
&-copy {
.@{typography-prefix-cls}-rtl & {
margin-right: 4px;
margin-left: 0;
}
}
&-expand {
.@{typography-prefix-cls}-rtl & {
float: left;
}
}
// Text input area
&-edit-content {
div& {
&.@{typography-prefix-cls}-rtl {
right: -@input-padding-horizontal - 1px;
left: auto;
}
}
&-confirm {
.@{typography-prefix-cls}-rtl & {
right: auto;
left: 10px;
}
}
}
// list
ul,
ol {
li {
.@{typography-prefix-cls}-rtl& {
margin: 0 20px 0 0;
padding: 0 4px 0 0;
}
}
}
}

View File

@ -5,7 +5,7 @@
</template> </template>
<script> <script>
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import demo from '../v2-doc/src/docs/affix/demo/basic.vue'; import demo from '../v2-doc/src/docs/typography/demo/text.vue';
// import Affix from '../components/affix'; // import Affix from '../components/affix';
export default defineComponent({ export default defineComponent({
components: { components: {

2
v2-doc

@ -1 +1 @@
Subproject commit 0468ad3010f71ad6b267c66c4f5e28c89c19d83e Subproject commit a295627e3b35302ee9da1215fb102a42210e3ba3