Skip to content

Commit baf696f

Browse files
committed
FE: Add styled components for JSON formatting UI
Adds new styled components to support JSON formatting functionality: - ValidationSection: Layout for JSON validation checkbox - FieldGroup: Wrapper for field label and editor with format button - FieldHeader: Flex layout for field label and format button - FormatButton: Compact button styling with accessibility features - ResizableEditorWrapper: CSS-based resize functionality for headers field - ValidationError/FormatSuccess: Feedback styling for user interactions - ScreenReaderOnly: Accessibility helper for screen reader text Features: - Responsive design following existing patterns - Theme-aware styling with proper fallbacks - Focus management and accessibility compliance - Visual feedback for formatting state changes - Enhanced resize handle for better usability
1 parent 3d3b311 commit baf696f

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed

frontend/src/components/Topics/Topic/SendMessage/SendMessage.styled.tsx

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import styled from 'styled-components';
2+
import { Button } from 'components/common/Button/Button';
23

34
export const Wrapper = styled.div`
45
display: block;
@@ -17,6 +18,7 @@ export const Columns = styled.div`
1718
display: flex;
1819
}
1920
`;
21+
2022
export const Flex = styled.div`
2123
display: flex;
2224
flex-direction: row;
@@ -25,6 +27,7 @@ export const Flex = styled.div`
2527
flex-direction: column;
2628
}
2729
`;
30+
2831
export const FlexItem = styled.div`
2932
width: 18rem;
3033
@media screen and (max-width: 1450px) {
@@ -34,3 +37,144 @@ export const FlexItem = styled.div`
3437
width: 100%;
3538
}
3639
`;
40+
41+
// New styled components for JSON formatting functionality
42+
export const ValidationSection = styled.div`
43+
display: flex;
44+
align-items: center;
45+
gap: 8px;
46+
margin-bottom: 8px;
47+
`;
48+
49+
export const FieldGroup = styled.div`
50+
display: flex;
51+
flex-direction: column;
52+
gap: 4px;
53+
`;
54+
55+
export const FieldHeader = styled.div`
56+
display: flex;
57+
justify-content: space-between;
58+
align-items: center;
59+
margin-bottom: 4px;
60+
`;
61+
62+
export const FormatButton = styled(Button)`
63+
font-size: 12px;
64+
padding: 4px 8px;
65+
height: 24px;
66+
min-width: auto;
67+
border-radius: 3px;
68+
69+
&:focus-visible {
70+
outline: 2px solid ${({ theme }) => theme.button.primary.backgroundColor.normal};
71+
outline-offset: 2px;
72+
}
73+
74+
&:disabled {
75+
opacity: 0.5;
76+
cursor: not-allowed;
77+
}
78+
79+
// Ensure proper contrast and accessibility
80+
&[aria-pressed="true"] {
81+
background: ${({ theme }) => theme.button.primary.backgroundColor.active};
82+
color: ${({ theme }) => theme.button.primary.color.active};
83+
}
84+
`;
85+
86+
export const ResizableEditorWrapper = styled.div`
87+
.ace_editor {
88+
resize: vertical !important;
89+
min-height: 40px !important;
90+
max-height: 200px !important;
91+
overflow: auto;
92+
border: 1px solid ${({ theme }) => theme.input?.borderColor?.normal || '#ddd'};
93+
border-radius: 4px;
94+
95+
&:focus-within {
96+
border-color: ${({ theme }) => theme.input?.borderColor?.focus || theme.button.primary.backgroundColor.normal};
97+
box-shadow: 0 0 0 2px ${({ theme }) => theme.button.primary.backgroundColor.normal}33;
98+
}
99+
}
100+
101+
.ace_content {
102+
cursor: text;
103+
}
104+
105+
.ace_scrollbar-v {
106+
right: 0 !important;
107+
}
108+
109+
.ace_scrollbar-h {
110+
bottom: 0 !important;
111+
}
112+
113+
// Enhanced resize handle visibility
114+
.ace_editor::after {
115+
content: '';
116+
position: absolute;
117+
bottom: 0;
118+
right: 0;
119+
width: 12px;
120+
height: 12px;
121+
background: linear-gradient(
122+
135deg,
123+
transparent 0%,
124+
transparent 46%,
125+
${({ theme }) => theme.input?.borderColor?.normal || '#ddd'} 46%,
126+
${({ theme }) => theme.input?.borderColor?.normal || '#ddd'} 50%,
127+
transparent 50%,
128+
transparent 56%,
129+
${({ theme }) => theme.input?.borderColor?.normal || '#ddd'} 56%,
130+
${({ theme }) => theme.input?.borderColor?.normal || '#ddd'} 60%,
131+
transparent 60%
132+
);
133+
cursor: nw-resize;
134+
z-index: 10;
135+
}
136+
`;
137+
138+
// Error state styling for validation feedback
139+
export const ValidationError = styled.div`
140+
color: ${({ theme }) => theme.button.danger.backgroundColor.normal};
141+
font-size: 12px;
142+
margin-top: 4px;
143+
display: flex;
144+
align-items: center;
145+
gap: 4px;
146+
147+
&::before {
148+
content: '⚠';
149+
font-size: 14px;
150+
}
151+
`;
152+
153+
// Success state styling for formatting feedback
154+
export const FormatSuccess = styled.div`
155+
color: ${({ theme }) => theme.button.primary.backgroundColor.normal};
156+
font-size: 12px;
157+
margin-top: 4px;
158+
display: flex;
159+
align-items: center;
160+
gap: 4px;
161+
162+
&::before {
163+
content: '✓';
164+
font-size: 14px;
165+
font-weight: bold;
166+
}
167+
`;
168+
169+
// Accessibility improvements for screen readers
170+
export const ScreenReaderOnly = styled.span`
171+
position: absolute;
172+
width: 1px;
173+
height: 1px;
174+
padding: 0;
175+
margin: -1px;
176+
overflow: hidden;
177+
clip: rect(0, 0, 0, 0);
178+
white-space: nowrap;
179+
border: 0;
180+
`;

0 commit comments

Comments
 (0)