fix(inputs): cap room-name / display-name length client-side (H10)

The room-name (settings + create-room) and display-name inputs had no client-side
length guard, so an over-long value only failed after a server round-trip. Add
maxLength={255} (matching the existing inline-rename cap in RoomNavItem; under
Synapse's 256 max_displayname_length). Also clamp the emoji-picker prepend in the
two room-name fields, since programmatic setState isn't constrained by the DOM
maxLength and could otherwise push past the cap.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-07 20:58:10 -04:00
parent 3f9fea1cf2
commit f9c03d5e33
3 changed files with 9 additions and 2 deletions
@@ -122,7 +122,9 @@ export function RoomProfileEdit({
const [emojiAnchor, setEmojiAnchor] = useState<RectCords>(); const [emojiAnchor, setEmojiAnchor] = useState<RectCords>();
const handleEmojiSelect = useCallback((unicode: string) => { const handleEmojiSelect = useCallback((unicode: string) => {
setNameValue((prev) => unicode + prev); // Clamp to the same cap as the input's maxLength — programmatic setState isn't
// constrained by the DOM maxLength, so the picker could otherwise exceed it.
setNameValue((prev) => (unicode + prev).slice(0, 255));
setEmojiAnchor(undefined); setEmojiAnchor(undefined);
}, []); }, []);
@@ -309,6 +311,7 @@ export function RoomProfileEdit({
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setNameValue(e.target.value)} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setNameValue(e.target.value)}
variant="Secondary" variant="Secondary"
radii="300" radii="300"
maxLength={255}
readOnly={!canEditName || submitting} readOnly={!canEditName || submitting}
style={{ width: '100%' }} style={{ width: '100%' }}
/> />
+4 -1
View File
@@ -102,7 +102,9 @@ export function CreateRoomForm({
const [emojiAnchor, setEmojiAnchor] = useState<RectCords>(); const [emojiAnchor, setEmojiAnchor] = useState<RectCords>();
const handleEmojiSelect = useCallback((unicode: string) => { const handleEmojiSelect = useCallback((unicode: string) => {
setNameValue((prev) => unicode + prev); // Clamp to the same cap as the input's maxLength — programmatic setState isn't
// constrained by the DOM maxLength, so the picker could otherwise exceed it.
setNameValue((prev) => (unicode + prev).slice(0, 255));
setEmojiAnchor(undefined); setEmojiAnchor(undefined);
}, []); }, []);
@@ -240,6 +242,7 @@ export function CreateRoomForm({
disabled={disabled} disabled={disabled}
value={nameValue} value={nameValue}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => setNameValue(e.target.value)} onChange={(e: React.ChangeEvent<HTMLInputElement>) => setNameValue(e.target.value)}
maxLength={255}
style={{ width: '100%' }} style={{ width: '100%' }}
/> />
</Box> </Box>
@@ -285,6 +285,7 @@ function ProfileDisplayName({ profile, userId }: ProfileProps) {
onChange={handleChange} onChange={handleChange}
variant="Secondary" variant="Secondary"
radii="300" radii="300"
maxLength={255}
style={{ paddingRight: config.space.S200 }} style={{ paddingRight: config.space.S200 }}
readOnly={changingDisplayName || disableSetDisplayname} readOnly={changingDisplayName || disableSetDisplayname}
after={ after={