Skip to content

Commit 05f5448

Browse files
committed
feat: make description of ChatItemFormItemsWrapper collapsible
1 parent a8f7415 commit 05f5448

File tree

3 files changed

+113
-6
lines changed

3 files changed

+113
-6
lines changed

src/components/chat-item/chat-item-form-items.ts

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ import { TextArea } from '../form-items/text-area';
2222
import { TextInput } from '../form-items/text-input';
2323
import { Icon, MynahIcons } from '../icon';
2424
import { Overlay, OverlayHorizontalDirection, OverlayVerticalDirection } from '../overlay';
25+
import { MoreContentIndicator } from '../more-content-indicator';
2526
const TOOLTIP_DELAY = 350;
27+
const FORM_DESCRIPTION_COLLAPSED_HEIGHT_RATIO = 16; // Show less content when collapsed
2628
export interface ChatItemFormItemsWrapperProps {
2729
tabId: string;
2830
chatItem: Partial<ChatItem>;
@@ -75,16 +77,53 @@ export class ChatItemFormItemsWrapper {
7577
chatItemOption.value = chatItemOption.options?.[0]?.value;
7678
}
7779
}
78-
let description;
80+
let description: ExtendedHTMLElement | undefined;
7981
if (chatItemOption.description != null) {
80-
description = DomBuilder.getInstance().build({
82+
const descriptionContent = DomBuilder.getInstance().build({
8183
type: 'span',
84+
classNames: [ 'mynah-ui-form-item-description-content' ],
85+
children: [ chatItemOption.description ]
86+
});
87+
88+
description = DomBuilder.getInstance().build({
89+
type: 'div',
8290
testId: testIds.chatItem.chatItemForm.description,
8391
classNames: [ 'mynah-ui-form-item-description' ],
84-
children: [
85-
chatItemOption.description,
86-
]
92+
children: [ descriptionContent ]
8793
});
94+
95+
// Add MoreContentIndicator for long descriptions
96+
const moreContentIndicator = new MoreContentIndicator({
97+
icon: MynahIcons.DOWN_OPEN,
98+
border: false,
99+
onClick: () => {
100+
if (description?.hasClass('mynah-ui-form-item-description-collapsed') === true) {
101+
description.removeClass('mynah-ui-form-item-description-collapsed');
102+
moreContentIndicator.update({ icon: MynahIcons.UP_OPEN });
103+
} else {
104+
description?.addClass('mynah-ui-form-item-description-collapsed');
105+
moreContentIndicator.update({ icon: MynahIcons.DOWN_OPEN });
106+
}
107+
},
108+
testId: `${testIds.chatItem.chatItemForm.description}-more-content-indicator`
109+
});
110+
111+
description.insertChild('beforeend', moreContentIndicator.render);
112+
113+
// Check if content needs collapsing after a short delay
114+
setTimeout(() => {
115+
const collapsedHeight = window.innerHeight / FORM_DESCRIPTION_COLLAPSED_HEIGHT_RATIO;
116+
117+
// Show MoreContentIndicator if content exceeds the collapsed max-height
118+
if (descriptionContent.scrollHeight > collapsedHeight) {
119+
description?.addClass('mynah-ui-form-item-description-auto-collapse');
120+
description?.addClass('mynah-ui-form-item-description-collapsed');
121+
// Set the collapsed height dynamically
122+
description?.style.setProperty('--form-description-collapsed-height', `${collapsedHeight}px`);
123+
} else {
124+
moreContentIndicator.render.addClass('hidden');
125+
}
126+
}, 50);
88127
}
89128
const fireModifierAndEnterKeyPress = (): void => {
90129
if ((chatItemOption as TextBasedFormItem).checkModifierEnterKeyPress === true && this.isFormValid()) {

src/styles/components/_detailed-list.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
display: none;
4040
}
4141
> .mynah-chat-item-form-items-container {
42-
gap: var(--mynah-sizing-4);
42+
gap: var(--mynah-sizing-5);
4343
}
4444
}
4545
> .mynah-detailed-list-filter-actions-wrapper {

src/styles/components/_form-input.scss

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,76 @@
2626
}
2727
}
2828
.mynah-ui-form-item-description {
29+
position: relative;
2930
font-size: var(--mynah-font-size-small);
3031
color: var(--mynah-color-text-weak);
32+
33+
.mynah-ui-form-item-description-content {
34+
display: block;
35+
line-height: 1.4;
36+
}
37+
38+
&.mynah-ui-form-item-description-auto-collapse {
39+
.mynah-ui-form-item-description-content {
40+
position: relative;
41+
42+
// Default state - no fade effect
43+
&::after {
44+
content: '';
45+
position: absolute;
46+
bottom: 0;
47+
left: 0;
48+
right: 0;
49+
height: 1rem;
50+
background: linear-gradient(transparent, var(--mynah-color-bg));
51+
pointer-events: none;
52+
opacity: 0;
53+
transition: opacity 0.15s ease-in-out;
54+
}
55+
}
56+
57+
// Only show fade effect when collapsed
58+
&.mynah-ui-form-item-description-collapsed {
59+
.mynah-ui-form-item-description-content {
60+
max-height: var(--form-description-collapsed-height, 3.125vh); // window.innerHeight / 32
61+
overflow: hidden;
62+
transition: max-height 0.3s ease-in-out;
63+
64+
&::after {
65+
opacity: 1;
66+
}
67+
}
68+
}
69+
70+
// When expanded, ensure no fade and smooth transition
71+
&:not(.mynah-ui-form-item-description-collapsed) {
72+
.mynah-ui-form-item-description-content {
73+
max-height: none;
74+
overflow: visible;
75+
transition: max-height 0.3s ease-in-out;
76+
77+
&::after {
78+
opacity: 0;
79+
}
80+
}
81+
}
82+
}
83+
84+
.more-content-indicator {
85+
margin-top: var(--mynah-sizing-1);
86+
87+
&.hidden {
88+
display: none;
89+
}
90+
}
91+
92+
// Only remove shadow when expanded (not collapsed)
93+
&:not(.mynah-ui-form-item-description-collapsed) {
94+
.more-content-indicator {
95+
box-shadow: none;
96+
background-color: transparent;
97+
}
98+
}
3199
}
32100
.mynah-form-input-container {
33101
position: relative;

0 commit comments

Comments
 (0)