feat: update typography
parent
2515077386
commit
2191656479
|
@ -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 };
|
||||
};
|
|
@ -11,29 +11,26 @@ import Typography, { TypographyProps } from './Typography';
|
|||
import ResizeObserver from '../vc-resize-observer';
|
||||
import Tooltip from '../tooltip';
|
||||
import copy from '../_util/copy-to-clipboard';
|
||||
import { defaultConfigProvider } from '../config-provider';
|
||||
import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
|
||||
import CopyOutlined from '@ant-design/icons-vue/CopyOutlined';
|
||||
import EditOutlined from '@ant-design/icons-vue/EditOutlined';
|
||||
import {
|
||||
defineComponent,
|
||||
inject,
|
||||
VNodeTypes,
|
||||
Text,
|
||||
VNode,
|
||||
reactive,
|
||||
ref,
|
||||
onMounted,
|
||||
onUpdated,
|
||||
onBeforeUnmount,
|
||||
watch,
|
||||
watchEffect,
|
||||
nextTick,
|
||||
CSSProperties,
|
||||
toRaw,
|
||||
computed,
|
||||
} from 'vue';
|
||||
import { filterEmpty } from '../_util/props-util';
|
||||
import { AutoSizeType } from '../input/ResizableTextArea';
|
||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||
|
||||
export type BaseType = 'secondary' | 'success' | 'warning' | 'danger';
|
||||
|
||||
|
@ -63,7 +60,7 @@ interface EditConfig {
|
|||
tooltip?: boolean | VNodeTypes;
|
||||
onStart?: () => void;
|
||||
onChange?: (value: string) => void;
|
||||
maxLength?: number;
|
||||
maxlength?: number;
|
||||
autoSize?: boolean | AutoSizeType;
|
||||
}
|
||||
|
||||
|
@ -74,7 +71,7 @@ export interface EllipsisConfig {
|
|||
symbol?: VNodeTypes;
|
||||
onExpand?: EventHandlerNonNull;
|
||||
onEllipsis?: (ellipsis: boolean) => void;
|
||||
tooltip?: VNodeTypes;
|
||||
tooltip?: boolean | VNodeTypes;
|
||||
}
|
||||
|
||||
export interface BlockProps extends TypographyProps {
|
||||
|
@ -91,6 +88,7 @@ export interface BlockProps extends TypographyProps {
|
|||
delete?: boolean;
|
||||
strong?: boolean;
|
||||
keyboard?: boolean;
|
||||
content?: string;
|
||||
}
|
||||
|
||||
interface Locale {
|
||||
|
@ -110,7 +108,7 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
name: 'Base',
|
||||
inheritAttrs: false,
|
||||
setup(props, { slots, attrs }) {
|
||||
const configProvider = inject('configProvider', defaultConfigProvider);
|
||||
const { prefixCls } = useConfigInject('typography', props);
|
||||
|
||||
const state = reactive({
|
||||
edit: false,
|
||||
|
@ -133,25 +131,20 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
|
||||
const contentRef = 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(() => {
|
||||
state.prevProps = { ...props, children: getChildren() };
|
||||
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(() => {
|
||||
|
@ -160,26 +153,30 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
});
|
||||
|
||||
watch(
|
||||
() => props.ellipsis,
|
||||
[() => ellipsis.value.rows, () => props.content],
|
||||
() => {
|
||||
resizeOnNextFrame();
|
||||
nextTick(() => {
|
||||
resizeOnNextFrame();
|
||||
});
|
||||
},
|
||||
{ flush: 'post', deep: true, immediate: true },
|
||||
);
|
||||
|
||||
watchEffect(() => {
|
||||
const children = getChildren();
|
||||
|
||||
warning(
|
||||
!props.editable || children.every(item => item.type === Text),
|
||||
'Typography',
|
||||
'When `editable` is enabled, the `children` should use string.',
|
||||
);
|
||||
if (!('content' in props)) {
|
||||
warning(
|
||||
!props.editable,
|
||||
'Typography',
|
||||
'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) {
|
||||
contentRef.value = node;
|
||||
}
|
||||
|
@ -189,23 +186,14 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
}
|
||||
|
||||
function getChildrenText(): string {
|
||||
const children = getChildren();
|
||||
return children.length !== 0
|
||||
? children
|
||||
.filter(item => item.type === Text)
|
||||
.map(item => item.children)
|
||||
.reduce((cur, prev) => cur + prev, '')
|
||||
: '';
|
||||
return props.ellipsis || props.editable ? props.content : contentRef.value.text;
|
||||
}
|
||||
|
||||
// =============== Expand ===============
|
||||
function onExpandClick(e: MouseEvent) {
|
||||
const { onExpand } = getEllipsis();
|
||||
const { onExpand } = ellipsis.value;
|
||||
state.expanded = true;
|
||||
|
||||
if (onExpand) {
|
||||
onExpand(e);
|
||||
}
|
||||
onExpand?.(e);
|
||||
}
|
||||
// ================ Edit ================
|
||||
function onEditClick() {
|
||||
|
@ -213,10 +201,8 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
}
|
||||
|
||||
function onEditChange(value: string) {
|
||||
const { onChange } = getEditable();
|
||||
if (onChange) {
|
||||
onChange(value);
|
||||
}
|
||||
const { onChange } = editable.value;
|
||||
onChange?.(value);
|
||||
|
||||
triggerEdit(false);
|
||||
}
|
||||
|
@ -226,7 +212,8 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
}
|
||||
|
||||
// ================ Copy ================
|
||||
function onCopyClick() {
|
||||
function onCopyClick(e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
const { copyable } = props;
|
||||
|
||||
const copyConfig = {
|
||||
|
@ -250,30 +237,18 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
}, 3000);
|
||||
});
|
||||
}
|
||||
|
||||
function getEditable($props?: BlockProps): EditConfig {
|
||||
const editable = ($props || props).editable;
|
||||
const editable = computed(() => {
|
||||
const editable = props.editable;
|
||||
if (!editable) return { editing: state.edit };
|
||||
|
||||
return {
|
||||
editing: state.edit,
|
||||
...(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) {
|
||||
const { onStart } = getEditable();
|
||||
const { onStart } = editable.value;
|
||||
if (edit && onStart) {
|
||||
onStart();
|
||||
}
|
||||
|
@ -295,13 +270,13 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
});
|
||||
}
|
||||
|
||||
function canUseCSSEllipsis(): boolean {
|
||||
const { rows, expandable, suffix } = getEllipsis();
|
||||
const canUseCSSEllipsis = computed(() => {
|
||||
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
|
||||
if (props.editable || props.copyable || expandable || !state.clientRendered) {
|
||||
if (props.editable || props.copyable || expandable || onEllipsis) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -310,40 +285,33 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
}
|
||||
|
||||
return isLineClampSupport;
|
||||
}
|
||||
});
|
||||
|
||||
function syncEllipsis() {
|
||||
const syncEllipsis = () => {
|
||||
const { ellipsisText, isEllipsis } = state;
|
||||
const children = getChildren();
|
||||
const { rows, suffix, onEllipsis } = getEllipsis();
|
||||
const { rows, suffix, onEllipsis } = ellipsis.value;
|
||||
if (!rows || rows < 0 || !contentRef.value?.$el || state.expanded) return;
|
||||
|
||||
// Do not measure if css already support ellipsis
|
||||
if (canUseCSSEllipsis()) return;
|
||||
if (canUseCSSEllipsis.value) return;
|
||||
|
||||
warning(
|
||||
children.every(item => item.type === Text),
|
||||
'Typography',
|
||||
'`ellipsis` should use string as children only.',
|
||||
);
|
||||
|
||||
const { content, text, ellipsis } = measure(
|
||||
const { content, text, ellipsis: ell } = measure(
|
||||
contentRef.value?.$el,
|
||||
{ rows, suffix },
|
||||
children,
|
||||
props.content,
|
||||
renderOperations(true),
|
||||
ELLIPSIS_STR,
|
||||
);
|
||||
|
||||
if (ellipsisText !== text || state.isEllipsis !== ellipsis) {
|
||||
if (ellipsisText !== text || state.isEllipsis !== ell) {
|
||||
state.ellipsisText = text;
|
||||
state.ellipsisContent = content;
|
||||
state.isEllipsis = ellipsis;
|
||||
if (isEllipsis !== ellipsis && onEllipsis) {
|
||||
onEllipsis(ellipsis);
|
||||
state.isEllipsis = ell;
|
||||
if (isEllipsis !== ell && onEllipsis) {
|
||||
onEllipsis(ell);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function wrapperDecorations(
|
||||
{ mark, code, underline, delete: del, strong, keyboard }: BlockProps,
|
||||
|
@ -368,8 +336,7 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
}
|
||||
|
||||
function renderExpand(forceRender?: boolean) {
|
||||
const { expandable, symbol } = getEllipsis();
|
||||
const prefixCls = getPrefixCls();
|
||||
const { expandable, symbol } = ellipsis.value;
|
||||
|
||||
if (!expandable) return null;
|
||||
|
||||
|
@ -386,7 +353,7 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
return (
|
||||
<a
|
||||
key="expand"
|
||||
class={`${prefixCls}-expand`}
|
||||
class={`${prefixCls.value}-expand`}
|
||||
onClick={onExpandClick}
|
||||
aria-label={state.expandStr}
|
||||
>
|
||||
|
@ -398,7 +365,6 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
function renderEdit() {
|
||||
if (!props.editable) return;
|
||||
|
||||
const prefixCls = getPrefixCls();
|
||||
const { icon, tooltip } = props.editable as EditConfig;
|
||||
|
||||
const title = tooltip || state.editStr;
|
||||
|
@ -408,7 +374,7 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
<Tooltip key="edit" title={tooltip === false ? '' : title}>
|
||||
<TransButton
|
||||
ref={saveEditIconRef}
|
||||
class={`${prefixCls}-edit`}
|
||||
class={`${prefixCls.value}-edit`}
|
||||
onClick={onEditClick}
|
||||
aria-label={ariaLabel}
|
||||
>
|
||||
|
@ -421,8 +387,6 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
function renderCopy() {
|
||||
if (!props.copyable) return;
|
||||
|
||||
const prefixCls = getPrefixCls();
|
||||
|
||||
const { tooltips } = props.copyable as CopyConfig;
|
||||
let tooltipNodes = toArray(tooltips) as VNodeTypes[];
|
||||
if (tooltipNodes.length === 0) {
|
||||
|
@ -435,7 +399,10 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
return (
|
||||
<Tooltip key="copy" title={tooltips === false ? '' : title}>
|
||||
<TransButton
|
||||
class={[`${prefixCls}-copy`, { [`${prefixCls}-copy-success`]: state.copied }]}
|
||||
class={[
|
||||
`${prefixCls.value}-copy`,
|
||||
{ [`${prefixCls.value}-copy-success`]: state.copied },
|
||||
]}
|
||||
onClick={onCopyClick}
|
||||
aria-label={ariaLabel}
|
||||
>
|
||||
|
@ -446,19 +413,16 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
}
|
||||
|
||||
function renderEditInput() {
|
||||
const prefixCls = getPrefixCls();
|
||||
const { class: className, style } = attrs;
|
||||
const { maxLength, autoSize } = getEditable();
|
||||
|
||||
const value = getChildrenText();
|
||||
const { maxlength, autoSize } = editable.value;
|
||||
|
||||
return (
|
||||
<Editable
|
||||
class={className}
|
||||
style={style}
|
||||
prefixCls={prefixCls}
|
||||
value={value}
|
||||
maxlength={maxLength}
|
||||
prefixCls={prefixCls.value}
|
||||
value={props.content}
|
||||
maxlength={maxlength}
|
||||
autoSize={autoSize}
|
||||
onSave={onEditChange}
|
||||
onCancel={onEditCancel}
|
||||
|
@ -470,14 +434,14 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
return [renderExpand(forceRenderExpanded), renderEdit(), renderCopy()].filter(node => node);
|
||||
}
|
||||
|
||||
function getPrefixCls() {
|
||||
const getPrefixCls = configProvider.getPrefixCls;
|
||||
return getPrefixCls('typography', props.prefixCls);
|
||||
}
|
||||
|
||||
return () => {
|
||||
const { editing } = getEditable();
|
||||
const children = filterEmpty(slots.default?.());
|
||||
const { editing } = editable.value;
|
||||
const children =
|
||||
props.ellipsis || props.editable
|
||||
? props.content
|
||||
: slots.default
|
||||
? slots.default()
|
||||
: props.content;
|
||||
|
||||
if (editing) {
|
||||
return renderEditInput();
|
||||
|
@ -486,9 +450,11 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
<LocaleReceiver
|
||||
componentName="Text"
|
||||
children={(locale: Locale) => {
|
||||
const { type, disabled, title, ...restProps } = props;
|
||||
const { class: className, style } = attrs;
|
||||
const { rows, suffix } = getEllipsis();
|
||||
const { type, disabled, title, content, class: className, style, ...restProps } = {
|
||||
...props,
|
||||
...attrs,
|
||||
};
|
||||
const { rows, suffix, tooltip } = ellipsis.value;
|
||||
|
||||
const { edit, copy: copyStr, copied, expand } = locale;
|
||||
|
||||
|
@ -510,7 +476,7 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
'keyboard',
|
||||
]);
|
||||
|
||||
const cssEllipsis = canUseCSSEllipsis();
|
||||
const cssEllipsis = canUseCSSEllipsis.value;
|
||||
const cssTextOverflow = 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
|
||||
if (rows && state.isEllipsis && !state.expanded && !cssEllipsis) {
|
||||
ariaLabel = title;
|
||||
if (!title && children.every(item => item.type === Text)) {
|
||||
ariaLabel = children
|
||||
.map(item => item.children)
|
||||
.reduce((cur, prev) => cur + prev, '');
|
||||
if (!title) {
|
||||
ariaLabel = content;
|
||||
}
|
||||
// We move full content to outer element to avoid repeat read the content by accessibility
|
||||
textNode = (
|
||||
|
@ -533,6 +497,14 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
{suffix}
|
||||
</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 {
|
||||
textNode = (
|
||||
<>
|
||||
|
@ -544,23 +516,21 @@ const Base = defineComponent<InternalBlockProps>({
|
|||
|
||||
textNode = wrapperDecorations(props, textNode);
|
||||
|
||||
const prefixCls = getPrefixCls();
|
||||
|
||||
return (
|
||||
<ResizeObserver onResize={resizeOnNextFrame} disabled={!rows}>
|
||||
<Typography
|
||||
ref={saveTypographyRef}
|
||||
class={[
|
||||
{ [`${prefixCls}-${type}`]: type },
|
||||
{ [`${prefixCls}-disabled`]: disabled },
|
||||
{ [`${prefixCls}-ellipsis`]: rows },
|
||||
{ [`${prefixCls}-ellipsis-single-line`]: cssTextOverflow },
|
||||
{ [`${prefixCls}-ellipsis-multiple-line`]: cssLineClamp },
|
||||
{ [`${prefixCls.value}-${type}`]: type },
|
||||
{ [`${prefixCls.value}-disabled`]: disabled },
|
||||
{ [`${prefixCls.value}-ellipsis`]: rows },
|
||||
{ [`${prefixCls.value}-ellipsis-single-line`]: cssTextOverflow },
|
||||
{ [`${prefixCls.value}-ellipsis-multiple-line`]: cssLineClamp },
|
||||
className,
|
||||
]}
|
||||
style={{
|
||||
...(style as CSSProperties),
|
||||
WebkitLineClamp: cssLineClamp ? rows : null,
|
||||
WebkitLineClamp: cssLineClamp ? rows : undefined,
|
||||
}}
|
||||
aria-label={ariaLabel}
|
||||
{...textProps}
|
||||
|
@ -582,7 +552,7 @@ export const baseProps = () => ({
|
|||
copyable: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]),
|
||||
prefixCls: PropTypes.string,
|
||||
component: PropTypes.string,
|
||||
type: PropTypes.oneOf(['secondary', 'danger', 'warning']),
|
||||
type: PropTypes.oneOf(['secondary', 'success', 'danger', 'warning']),
|
||||
disabled: PropTypes.looseBool,
|
||||
ellipsis: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]),
|
||||
code: PropTypes.looseBool,
|
||||
|
@ -591,6 +561,7 @@ export const baseProps = () => ({
|
|||
delete: PropTypes.looseBool,
|
||||
strong: PropTypes.looseBool,
|
||||
keyboard: PropTypes.looseBool,
|
||||
content: PropTypes.string,
|
||||
});
|
||||
|
||||
Base.props = baseProps();
|
||||
|
|
|
@ -25,10 +25,10 @@ const Link: FunctionalComponent<LinkProps> = (props, { slots, attrs }) => {
|
|||
// @ts-ignore
|
||||
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.props = Omit({ ...baseProps(), ellipsis: PropTypes.looseBool }, ['component']);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ const Paragraph: FunctionalComponent<BlockProps> = (props, { slots, attrs }) =>
|
|||
...attrs,
|
||||
};
|
||||
|
||||
return <Base {...paragraphProps}>{slots.default?.()}</Base>;
|
||||
return <Base {...paragraphProps} v-slots={slots}></Base>;
|
||||
};
|
||||
|
||||
Paragraph.displayName = 'ATypographyParagraph';
|
||||
|
|
|
@ -27,7 +27,7 @@ const Text: FunctionalComponent<TextProps> = (props, { slots, attrs }) => {
|
|||
...attrs,
|
||||
};
|
||||
|
||||
return <Base {...textProps}>{slots.default?.()}</Base>;
|
||||
return <Base {...textProps} v-slots={slots}></Base>;
|
||||
};
|
||||
|
||||
Text.displayName = 'ATypographyText';
|
||||
|
|
|
@ -25,7 +25,7 @@ const Title: FunctionalComponent<TitleProps> = (props, { slots, attrs }) => {
|
|||
...attrs,
|
||||
};
|
||||
|
||||
return <Base {...titleProps}>{slots.default?.()}</Base>;
|
||||
return <Base {...titleProps} v-slots={slots}></Base>;
|
||||
};
|
||||
|
||||
Title.displayName = 'ATypographyTitle';
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import { defaultConfigProvider } from '../config-provider';
|
||||
import Text from './Text';
|
||||
import Title from './Title';
|
||||
import Paragraph from './Paragraph';
|
||||
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 {
|
||||
prefixCls?: string;
|
||||
|
@ -18,14 +20,22 @@ const Typography = defineComponent<InternalTypographyProps>({
|
|||
Text: Text,
|
||||
Title: Title,
|
||||
Paragraph: Paragraph,
|
||||
setup(props, { slots }) {
|
||||
const { getPrefixCls } = inject('configProvider', defaultConfigProvider);
|
||||
|
||||
Link: Link,
|
||||
inheritAttrs: false,
|
||||
setup(props, { slots, attrs }) {
|
||||
const { prefixCls } = useConfigInject('typography', props);
|
||||
return () => {
|
||||
const { prefixCls: customizePrefixCls, component: Component = 'article' as any } = props;
|
||||
const prefixCls = getPrefixCls('typography', customizePrefixCls);
|
||||
|
||||
return <Component class={prefixCls}>{slots.default?.()}</Component>;
|
||||
const {
|
||||
prefixCls: _prefixCls,
|
||||
class: _className,
|
||||
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.Title.displayName, Title);
|
||||
app.component(Typography.Paragraph.displayName, Paragraph);
|
||||
app.component(Typography.Link.displayName, Link);
|
||||
return app;
|
||||
};
|
||||
|
||||
|
@ -48,4 +59,5 @@ export default Typography as typeof Typography &
|
|||
readonly Text: typeof Text;
|
||||
readonly Title: typeof Title;
|
||||
readonly Paragraph: typeof Paragraph;
|
||||
readonly Link: typeof Link;
|
||||
};
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
|
||||
&&-danger {
|
||||
color: @error-color;
|
||||
a&:active,
|
||||
a&:focus,
|
||||
a&:hover {
|
||||
color: ~`colorPalette('@{error-color}', 5) `;
|
||||
}
|
||||
}
|
||||
|
||||
&&-disabled {
|
||||
|
@ -60,7 +65,8 @@
|
|||
h1&,
|
||||
h2&,
|
||||
h3&,
|
||||
h4& h5& {
|
||||
h4&,
|
||||
h5& {
|
||||
.@{typography-prefix-cls} + & {
|
||||
margin-top: @typography-title-margin-top;
|
||||
}
|
||||
|
@ -92,16 +98,26 @@
|
|||
a&,
|
||||
a {
|
||||
.operation-unit();
|
||||
text-decoration: @link-decoration;
|
||||
|
||||
&:active,
|
||||
&:hover {
|
||||
text-decoration: @link-hover-decoration;
|
||||
}
|
||||
|
||||
&[disabled] {
|
||||
&[disabled],
|
||||
&.@{typography-prefix-cls}-disabled {
|
||||
color: @disabled-color;
|
||||
cursor: not-allowed;
|
||||
pointer-events: none;
|
||||
|
||||
&:active,
|
||||
&:hover {
|
||||
color: @disabled-color;
|
||||
}
|
||||
|
||||
&:active {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,8 +125,8 @@
|
|||
margin: 0 0.2em;
|
||||
padding: 0.2em 0.4em 0.1em;
|
||||
font-size: 85%;
|
||||
background: rgba(0, 0, 0, 0.06);
|
||||
border: 1px solid rgba(0, 0, 0, 0.06);
|
||||
background: rgba(150, 150, 150, 0.1);
|
||||
border: 1px solid rgba(100, 100, 100, 0.2);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
|
@ -178,11 +194,6 @@
|
|||
bottom: 8px;
|
||||
color: @text-color-secondary;
|
||||
pointer-events: none;
|
||||
|
||||
.@{typography-prefix-cls}-rtl & {
|
||||
right: auto;
|
||||
left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix Editable Textarea flash in Firefox
|
||||
|
@ -215,6 +226,38 @@
|
|||
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-single-line {
|
||||
overflow: hidden;
|
||||
|
@ -230,9 +273,11 @@
|
|||
|
||||
&-ellipsis-multiple-line {
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
-webkit-line-clamp: 3;
|
||||
/*! autoprefixer: ignore next */
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
@import './rtl';
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
</template>
|
||||
<script>
|
||||
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';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
|
|
2
v2-doc
2
v2-doc
|
@ -1 +1 @@
|
|||
Subproject commit 0468ad3010f71ad6b267c66c4f5e28c89c19d83e
|
||||
Subproject commit a295627e3b35302ee9da1215fb102a42210e3ba3
|
Loading…
Reference in New Issue