Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion packages/common
5 changes: 3 additions & 2 deletions packages/pro-components/chat/chat-actionbar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ comment | String | - | 评价内容 | N
content | String | - | 被复制的内容 | N
copy-mode | String | markdown | 【实验】复制内容的模式,可选 'markdown'(复制markdown原文)或 'text'(复制纯文本)。可选项:markdown/text | N
disabled | Boolean | false | 【讨论中】操作按钮是否可点击 | N
placement | String | start | 【实验】操作栏位置。可选项:start/end/space-around/space-between | N
long-press-position | Object | - | 【实验】长按触发点的位置信息,用于定位 popover。TS 类型:`{pageX: number; pageY: number; clientX: number; clientY: number; x: number; y: number}` | N
placement | String | start | 【实验】操作栏位置。可选项:start/end/space-around/space-between/longpress | N

### ChatActionbar Events

名称 | 参数 | 描述
-- | -- | --
actions | `(detail: {name: string, active: boolean})` | 点击点赞,点踩,复制,分享,重新生成按钮时触发发
actions | `(detail: {name: string, active: boolean, chatId: string})` | 点击点赞,点踩,复制,分享,重新生成按钮时触发发
81 changes: 67 additions & 14 deletions packages/pro-components/chat/chat-actionbar/chat-actionbar.less
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
@chat-actionbar: ~'@{prefix}-chat-actionbar';

@chat-actionbar-padding: var(--chat-actionbar-padding, 0);
@chat-actionbar-item-padding: var(--chat-actionbar-item-padding, 16rpx 28rpx);
@chat-actionbar-item-padding: var(--chat-actionbar-item-padding, 4rpx 28rpx);
@chat-actionbar-item-margin: 12rpx 0;
@chat-actionbar-item-color: @text-color-primary;
@chat-actionbar-item-active: @brand-color;

// TODO: 长按弹出层样式
@chat-actionbar-popover-background: @mask-active;
@chat-actionbar-popover-radius: 32rpx;
@chat-actionbar-popover-padding: 45rpx;
@chat-actionbar-popover-background: rgba(0, 0, 0, 0.9);
@chat-actionbar-popover-radius: 6rpx;
@chat-actionbar-popover-padding: 8rpx 16rpx;
@chat-actionbar-popover-padding-tri-width: 24rpx;
@chat-actionbar-popover-padding-tri-height: 10rpx;
@chat-actionbar-popover-item-color: @font-white-1;

.@{chat-actionbar} {
display: flex;
Expand All @@ -25,6 +29,63 @@
justify-content: flex-end;
}

// 弹出层
&--popover {
position: fixed;
display: none;
padding: @chat-actionbar-popover-padding;
color: @font-white-1;
background-color: @chat-actionbar-popover-background;
border-radius: @chat-actionbar-popover-radius;
max-width: 544rpx;

// 顶部三角形
&::before {
content: '';
position: absolute;
top: calc(@chat-actionbar-popover-padding-tri-height * -2);
left: 50%;
transform: translateX(-50%);
width: 0;
height: 0;
border-left: @chat-actionbar-popover-padding-tri-width solid transparent;
border-right: @chat-actionbar-popover-padding-tri-width solid transparent;
border-bottom: calc(@chat-actionbar-popover-padding-tri-height * 2) solid @chat-actionbar-popover-background;
}

&.popover-visible {
display: block;
}

.@{chat-actionbar}__inner {
background-color: unset;
border: none;
display: flex;
flex-wrap: wrap;
gap: 4rpx;

&--column {
gap: 8rpx;
}
}

.@{chat-actionbar}__item--popover {
color: #fff;
background-color: unset;
padding: 0;
margin: 0;
font-size: 28rpx;
line-height: 42rpx;
width: 128rpx;
height: 156rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8rpx;
}
}

// 内部容器
&__inner {
background-color: @bg-color-secondarycontainer;
Expand All @@ -42,14 +103,6 @@
align-items: center;
justify-content: space-between;
}

// 弹出层
&--popover {
padding: @chat-actionbar-popover-padding;
background-color: @chat-actionbar-popover-background;
border-radius: @chat-actionbar-popover-radius;
color: @font-white-1;
}
}

// 左侧内容
Expand All @@ -62,8 +115,8 @@
// 操作项
&__item {
color: @chat-actionbar-item-color;
margin: 12rpx 0;
padding: 4rpx 28rpx;
margin: @chat-actionbar-item-margin;
padding: @chat-actionbar-item-padding;
border-right: 2rpx solid @component-stroke;
background-color: unset;
outline: none;
Expand Down
45 changes: 42 additions & 3 deletions packages/pro-components/chat/chat-actionbar/chat-actionbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default class ChatActionbar extends SuperComponent {
actions: [],
classPrefix: name,
pComment: '',
computedPlacement: '',
iconMap: {
good: 'thumb-up',
bad: 'thumb-down',
Expand All @@ -28,17 +29,25 @@ export default class ChatActionbar extends SuperComponent {
good: 'thumb-up-filled',
bad: 'thumb-down-filled',
},
popoverPosition: '',
};

observers = {
comment(newVal) {
this.setData({
pComment: newVal || '',
});
this.setPComment(newVal);
},
'actionBar, pComment'() {
this.setActions();
},
longPressPosition(newVal) {
if (this.properties.placement === 'longpress') {
if (newVal) {
this.showPopover(newVal);
} else {
this.hidePopover();
}
}
},
};

methods = {
Expand Down Expand Up @@ -95,6 +104,7 @@ export default class ChatActionbar extends SuperComponent {
this.triggerEvent('actions', {
name,
active: !isActive,
chatId: this.properties.chatId,
});
} else if (name === 'bad') {
const isActive = this.data.pComment === 'bad';
Expand All @@ -104,10 +114,12 @@ export default class ChatActionbar extends SuperComponent {
this.triggerEvent('actions', {
name,
active: !isActive,
chatId: this.properties.chatId,
});
} else {
this.triggerEvent('actions', {
name,
chatId: this.properties.chatId,
});
}
},
Expand All @@ -122,6 +134,12 @@ export default class ChatActionbar extends SuperComponent {
});
},

setComputedPlacement() {
this.setData({
computedPlacement: this.properties.placement || 'start',
});
},

setActions() {
const baseActions = [];
if (Array.isArray(this.properties.actionBar)) {
Expand All @@ -143,13 +161,34 @@ export default class ChatActionbar extends SuperComponent {
actions: baseActions,
});
},

setPComment(newVal) {
this.setData({
pComment: newVal || '',
});
},

showPopover(pos) {
const lineNumber = Math.min(this.data.actions.length, 4);
const width = (lineNumber * 128 + (lineNumber - 1) * 8 + 16 * 2) / 2;
this.setData({
popoverPosition: `top:${pos.y}px;left:${pos.x}px;margin-left:-${width}rpx`,
});
},

hidePopover() {
this.setData({ popoverPosition: '' });
},
};

lifetimes = {
created() {
this.data.filterSpecialChars = this.filterSpecialChars.bind(this);
this.data.handleActionClick = this.handleActionClick.bind(this);
this.data.handleCopy = this.handleCopy.bind(this);
this.data.showPopover = this.showPopover.bind(this);
this.data.hidePopover = this.hidePopover.bind(this);
this.data.setPComment = this.setPComment.bind(this);
},

attached() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
<wxs src="../../../components/common/utils.wxs" module="_" />
<!-- TODO: api 可选项 longpress 下个版本迭代发布长按气泡样式 -->
<view
class="class {{[classPrefix, placement==='longpress' ? classPrefix+'__inner--popover' : '', computedPlacement]}}"
style="{{_._style([style, customStyle])}}"
class="{{[classPrefix, placement==='longpress' ? classPrefix+'--popover' : '', computedPlacement, popoverPosition ? 'popover-visible' : '']}}"
style="{{_._style([style, customStyle, popoverPosition])}}"
>
<view class="{{classPrefix}}__inner {{classPrefix}}__inner--column">
<view class="{{classPrefix}}__item {{classPrefix}}__left">
<view
class="{{classPrefix}}__left {{placement==='longpress' ? classPrefix+'__item--popover' : classPrefix+'__item'}}"
>
<slot name="prefix" />
</view>
<block wx:for="{{actions}}" wx:for-item="item" wx:for-index="index" wx:key="index">
<!-- 分享按钮使用 button 标签 -->
<button
wx:if="{{item.name === 'share'}}"
data-name="{{item.name}}"
class="{{_.cls(classPrefix + '__item', [['active', item.isActive]])}}"
class="{{_.cls(placement==='longpress' ? classPrefix+'__item--popover' : classPrefix+'__item', [['active', item.isActive]])}}"
open-type="{{content ? 'share' : 'none'}}"
data-chat-id="{{chatId}}"
bindtap="handleActionClick"
>
<t-icon name="{{item.isActive ? iconActiveMap[item.name] : iconMap[item.name]}}" size="40rpx" />
<view wx:if="{{placement==='longpress'}}" class="{{classPrefix}}__item__text">{{item.name}}</view>
</button>

<!-- 其他按钮使用 view 标签 -->
<view
wx:else
data-name="{{item.name}}"
class="{{_.cls(classPrefix + '__item', [['active', item.isActive]])}}"
class="{{_.cls(placement==='longpress' ? classPrefix+'__item--popover' : classPrefix+'__item', [['active', item.isActive]])}}"
bindtap="handleActionClick"
>
<t-icon name="{{item.isActive ? iconActiveMap[item.name] : iconMap[item.name]}}" size="40rpx" />
<view wx:if="{{placement==='longpress'}}" class="{{classPrefix}}__item__text">{{item.name}}</view>
</view>
</block>
</view>
Expand Down
5 changes: 5 additions & 0 deletions packages/pro-components/chat/chat-actionbar/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ const props: TdChatActionbarProps = {
type: String,
value: 'start',
},
/** 【实验】长按触发点的位置信息,用于定位 popover */
longPressPosition: {
type: Object,
value: null,
},
};

export default props;
16 changes: 15 additions & 1 deletion packages/pro-components/chat/chat-actionbar/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,20 @@ export interface TdChatActionbarProps {
*/
placement?: {
type: StringConstructor;
value?: 'start' | 'end' | 'space-around' | 'space-between';
value?: 'start' | 'end' | 'space-around' | 'space-between' | 'longpress';
};
/**
* 【实验】长按触发点的位置信息,用于定位 popover
*/
longPressPosition?: {
type: ObjectConstructor;
value?: {
pageX: number;
pageY: number;
clientX: number;
clientY: number;
x: number;
y: number;
};
};
}
Loading
Loading