From 48351fea68cc1df6db802232f7a08943d274bd34 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Fri, 13 May 2022 16:35:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E7=BB=84=E5=90=88?= =?UTF-8?q?=E5=BC=8F=E5=A4=B4=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 5 + .../design/components/Avatar/combined.css | 64 +++++++++++ .../design/components/Avatar/combined.tsx | 102 ++++++++++++++++++ .../components/Avatar/index.stories.tsx | 74 ++++++++++++- packages/design/components/Avatar/index.tsx | 2 +- 5 files changed, 244 insertions(+), 3 deletions(-) create mode 100644 packages/design/components/Avatar/combined.css create mode 100644 packages/design/components/Avatar/combined.tsx diff --git a/package.json b/package.json index 5ffbf965..9c234c0f 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,11 @@ "preinstall": "npx only-allow pnpm", "test": "cd web && pnpm test" }, + "pnpm": { + "peerDependencyRules": { + "ignoreMissing": ["acorn"] + } + }, "lint-staged": { "src/*.{json,less}": [ "prettier --write --config ./.prettierrc.json" diff --git a/packages/design/components/Avatar/combined.css b/packages/design/components/Avatar/combined.css new file mode 100644 index 00000000..27eb8227 --- /dev/null +++ b/packages/design/components/Avatar/combined.css @@ -0,0 +1,64 @@ +.td-combined-avatar { + position: relative; + overflow: hidden; +} + +.td-combined-avatar-2::after { + content: ''; + position: absolute; + height: 100%; + width: 1px; + background-color: white; + left: 50%; + top: 0; + z-index: 1; +} + +.td-combined-avatar-3::before { + content: ''; + position: absolute; + width: 50%; + height: 1px; + background-color: white; + right: 0; + top: 50%; + z-index: 1; +} + +.td-combined-avatar-3::after { + content: ''; + position: absolute; + height: 100%; + width: 1px; + background-color: white; + left: 50%; + top: 0; + z-index: 1; +} + +.td-combined-avatar-4::before { + content: ''; + position: absolute; + width: 100%; + height: 1px; + background-color: white; + left: 0; + top: 50%; + z-index: 1; +} + +.td-combined-avatar-4::after { + content: ''; + position: absolute; + height: 100%; + width: 1px; + background-color: white; + left: 50%; + top: 0; + z-index: 1; +} + +.td-combined-avatar__item { + position: absolute; + border-radius: 0; +} diff --git a/packages/design/components/Avatar/combined.tsx b/packages/design/components/Avatar/combined.tsx new file mode 100644 index 00000000..27ef3bcd --- /dev/null +++ b/packages/design/components/Avatar/combined.tsx @@ -0,0 +1,102 @@ +import { Avatar, AvatarProps } from '.'; +import React from 'react'; +import _take from 'lodash/take'; +import './combined.css'; + +interface CombinedAvatarProps { + shape?: 'circle' | 'square'; + size?: number; + items: AvatarProps[]; +} + +/** + * 组装式头像 + */ +export const CombinedAvatar: React.FC = React.memo( + (props) => { + const { size = 16, shape = 'circle' } = props; + const items = _take(props.items, 4); + + const length = items.length; + const getCellStyle = (i: number): React.CSSProperties => { + if (length === 1) { + return {}; + } + + if (length === 2) { + if (i === 0) { + return { + width: '50%', + overflow: 'hidden', + position: 'absolute', + left: 0, + }; + } + if (i === 1) { + return { + width: '50%', + overflow: 'hidden', + position: 'absolute', + right: 0, + }; + } + } + + if (length === 3) { + if (i === 0) { + return { + width: '50%', + overflow: 'hidden', + position: 'absolute', + left: 0, + }; + } + if (i === 1) { + return { transform: 'scale(50%)', transformOrigin: '100% 0 0' }; + } + if (i === 2) { + return { transform: 'scale(50%)', transformOrigin: '100% 100% 0' }; + } + } + + if (length === 4) { + if (i === 0) { + return { transform: 'scale(50%)', transformOrigin: '0 0 0' }; + } + if (i === 1) { + return { transform: 'scale(50%)', transformOrigin: '100% 0 0' }; + } + if (i === 2) { + return { transform: 'scale(50%)', transformOrigin: '0 100% 0' }; + } + if (i === 3) { + return { transform: 'scale(50%)', transformOrigin: '100% 100% 0' }; + } + } + + return {}; + }; + + return ( +
+ {items.map((item, i) => ( + + ))} +
+ ); + } +); +CombinedAvatar.displayName = 'CombinedAvatar'; diff --git a/packages/design/components/Avatar/index.stories.tsx b/packages/design/components/Avatar/index.stories.tsx index c8c7abb8..98a48674 100644 --- a/packages/design/components/Avatar/index.stories.tsx +++ b/packages/design/components/Avatar/index.stories.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { ComponentStory, ComponentMeta } from '@storybook/react'; - +import type { ComponentStory, ComponentMeta } from '@storybook/react'; import { Avatar } from '.'; +import { CombinedAvatar } from './combined'; export default { title: 'Tailchat/Avatar', @@ -48,3 +48,73 @@ withImage.args = { name: 'Anonymous', src: 'http://dummyimage.com/50x50', }; + +const CombinedTemplate: ComponentStory = (args) => ( +
+ +
+); + +export const combined1 = CombinedTemplate.bind({}); +combined1.args = { + size: 48, + items: [ + { + name: 'Anonymous', + src: 'http://dummyimage.com/50x50', + }, + ], +}; + +export const combined2 = CombinedTemplate.bind({}); +combined2.args = { + size: 48, + items: [ + { + name: 'Anonymous', + src: 'http://dummyimage.com/50x50', + }, + { + name: 'Anonymous', + }, + ], +}; + +export const combined3 = CombinedTemplate.bind({}); +combined3.args = { + size: 48, + items: [ + { + name: 'Anonymous', + src: 'http://dummyimage.com/50x50', + }, + { + name: 'Anonymous', + src: 'http://dummyimage.com/50x50', + }, + { + name: 'Anonymous', + }, + ], +}; + +export const combined4 = CombinedTemplate.bind({}); +combined4.args = { + size: 48, + items: [ + { + name: 'Anonymous', + src: 'http://dummyimage.com/50x50', + }, + { + name: 'Anonymous', + src: 'http://dummyimage.com/50x50', + }, + { + name: 'Anonymous', + }, + { + name: 'Anonymous', + }, + ], +}; diff --git a/packages/design/components/Avatar/index.tsx b/packages/design/components/Avatar/index.tsx index 0d8557ae..49a72916 100644 --- a/packages/design/components/Avatar/index.tsx +++ b/packages/design/components/Avatar/index.tsx @@ -9,7 +9,7 @@ import type { AvatarProps as AntdAvatarProps } from 'antd/lib/avatar'; import { getTextColorHex } from './utils'; import { isValidStr } from '../utils'; -interface AvatarProps extends AntdAvatarProps { +export interface AvatarProps extends AntdAvatarProps { name?: string; isOnline?: boolean; }