@micha.bigler/ui-core-micha 2.26.2 → 2.26.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -122,11 +122,15 @@ export function PollCard({ message, canClose: canCloseProp }) {
|
|
|
122
122
|
// screenshot of the checkbox/text/percent squeezed onto one tight line
|
|
123
123
|
// with a thin bar close to the text) -- more internal spacing/a taller
|
|
124
124
|
// bar, not a wider bubble (MessageBubble.jsx's maxWidth is untouched).
|
|
125
|
-
const richLabel = _jsxs(Stack, { sx: { flex: 1, minWidth: 0, opacity: pending.has(option.id) ? 0.6 : 1 }, spacing: 0.75, children: [_jsxs(Stack, { direction: "row", justifyContent: "space-between", children: [_jsx(Typography, { variant: "body2", noWrap: true, children: option.text || option.label }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: resultText })] }), _jsx(LinearProgress, { variant: "determinate", value: percent, sx: { borderRadius: 1, height: 8 }, color: votedByMe ? 'primary' : 'inherit' })] });
|
|
125
|
+
const richLabel = _jsxs(Stack, { sx: { flex: 1, minWidth: 0, opacity: pending.has(option.id) ? 0.6 : 1 }, spacing: 0.75, children: [_jsxs(Stack, { direction: "row", justifyContent: "space-between", spacing: 1, children: [_jsx(Typography, { variant: "body2", noWrap: true, children: option.text || option.label }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: resultText })] }), _jsx(LinearProgress, { variant: "determinate", value: percent, sx: { borderRadius: 1, height: 8 }, color: votedByMe ? 'primary' : 'inherit' })] });
|
|
126
126
|
return { accessibleLabel, richLabel };
|
|
127
127
|
};
|
|
128
128
|
const formControlSx = { width: '100%', m: 0, alignItems: 'flex-start' };
|
|
129
|
-
|
|
129
|
+
// MSG-6j: a short question/option set could otherwise pull the whole `MessageBubble`
|
|
130
|
+
// (`width: fit-content`) in tighter than comfortable to read. 260px stays under the
|
|
131
|
+
// bubble's own `maxWidth: min(75%, 680px)` ceiling even at a 375px viewport (75% = 281px)
|
|
132
|
+
// -- verified at that width, not just desktop.
|
|
133
|
+
return _jsx(Paper, { variant: "outlined", sx: { p: 1.5, minWidth: 260 }, "aria-label": t('MessagingPoll.LABEL'), children: _jsxs(Stack, { spacing: 1.5, children: [_jsx(Typography, { variant: "subtitle2", children: poll.question }), poll.allow_multiple
|
|
130
134
|
? (poll.options || []).map((option) => {
|
|
131
135
|
const { accessibleLabel, richLabel } = optionLabel(option);
|
|
132
136
|
return _jsx(FormControlLabel, { disabled: closed, sx: formControlSx, label: richLabel, control: _jsx(Checkbox, { checked: selected.includes(option.id), inputProps: { 'aria-label': accessibleLabel }, onChange: () => tap(option.id), sx: { pt: 0.25 } }) }, option.id);
|
package/package.json
CHANGED
|
@@ -110,7 +110,13 @@ export function PollCard({ message, canClose: canCloseProp }) {
|
|
|
110
110
|
// with a thin bar close to the text) -- more internal spacing/a taller
|
|
111
111
|
// bar, not a wider bubble (MessageBubble.jsx's maxWidth is untouched).
|
|
112
112
|
const richLabel = <Stack sx={{ flex: 1, minWidth: 0, opacity: pending.has(option.id) ? 0.6 : 1 }} spacing={0.75}>
|
|
113
|
-
|
|
113
|
+
{/* MSG-6j: `justifyContent: 'space-between'` only distributes LEFTOVER width -- but
|
|
114
|
+
this row sits inside a `MessageBubble` sized `width: fit-content` around this exact
|
|
115
|
+
content, so there is by construction no leftover width, and space-between alone
|
|
116
|
+
reserved a zero-width gap (the reported bug: label text ran directly into the
|
|
117
|
+
vote-count/percent text). `spacing` adds a real minimum gap via margin, independent
|
|
118
|
+
of justify-content, so the two never touch regardless of available width. */}
|
|
119
|
+
<Stack direction="row" justifyContent="space-between" spacing={1}>
|
|
114
120
|
<Typography variant="body2" noWrap>{option.text || option.label}</Typography>
|
|
115
121
|
<Typography variant="caption" color="text.secondary">{resultText}</Typography>
|
|
116
122
|
</Stack>
|
|
@@ -120,7 +126,11 @@ export function PollCard({ message, canClose: canCloseProp }) {
|
|
|
120
126
|
};
|
|
121
127
|
const formControlSx = { width: '100%', m: 0, alignItems: 'flex-start' };
|
|
122
128
|
|
|
123
|
-
|
|
129
|
+
// MSG-6j: a short question/option set could otherwise pull the whole `MessageBubble`
|
|
130
|
+
// (`width: fit-content`) in tighter than comfortable to read. 260px stays under the
|
|
131
|
+
// bubble's own `maxWidth: min(75%, 680px)` ceiling even at a 375px viewport (75% = 281px)
|
|
132
|
+
// -- verified at that width, not just desktop.
|
|
133
|
+
return <Paper variant="outlined" sx={{ p: 1.5, minWidth: 260 }} aria-label={t('MessagingPoll.LABEL')}><Stack spacing={1.5}>
|
|
124
134
|
<Typography variant="subtitle2">{poll.question}</Typography>
|
|
125
135
|
{poll.allow_multiple
|
|
126
136
|
? (poll.options || []).map((option) => {
|
|
@@ -122,4 +122,21 @@ describe('poll rendering against the real server contract', () => {
|
|
|
122
122
|
screen.getAllByRole('radio').forEach((radio) => expect(radio.disabled).toBe(true));
|
|
123
123
|
expect(screen.getByText('MessagingPoll.CLOSED')).toBeTruthy();
|
|
124
124
|
});
|
|
125
|
+
|
|
126
|
+
it('gives the card a minimum width so a short question/option set is not squeezed narrower than comfortable (MSG-6j)', () => {
|
|
127
|
+
render(<MessagingProvider api={baseApi()} active={false}><PollCard message={{ id: 'msg-1', poll: serverPoll() }} /></MessagingProvider>);
|
|
128
|
+
const card = screen.getByLabelText('MessagingPoll.LABEL');
|
|
129
|
+
expect(getComputedStyle(card).minWidth).toBe('260px');
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('keeps a real gap between an option label and its vote-count/percent text, not merely space-between with nothing to distribute (MSG-6j)', () => {
|
|
133
|
+
// Regression test for the reported bug: `justifyContent: 'space-between'` alone only
|
|
134
|
+
// distributes LEFTOVER width, and this row sits inside a `width: fit-content` bubble
|
|
135
|
+
// sized around this exact content -- there is never leftover width, so space-between
|
|
136
|
+
// reserved a zero-width gap and the option text ran directly into "2 (100 %)". Must
|
|
137
|
+
// fail if the row's own `spacing` is removed.
|
|
138
|
+
render(<MessagingProvider api={baseApi()} active={false}><PollCard message={{ id: 'msg-1', poll: serverPoll() }} /></MessagingProvider>);
|
|
139
|
+
const resultText = screen.getByText(/MessagingPoll\.OPTION_RESULT.*"count":2.*"percent":67/);
|
|
140
|
+
expect(getComputedStyle(resultText).marginLeft).not.toBe('0px');
|
|
141
|
+
});
|
|
125
142
|
});
|