Skip to content
Merged
Show file tree
Hide file tree
Changes from 247 commits
Commits
Show all changes
248 commits
Select commit Hold shift + click to select a range
c043f7b
docs(fuselage): propose that components take no styling props
ggazzo Oct 20, 2026
93aa765
docs(fuselage): migrate Skeleton last
ggazzo Oct 22, 2026
3f66a59
chore: stop passing rcx-* props to Fuselage components in the app
ggazzo Oct 22, 2026
126144f
chore: space Icons with gap on their container instead of margins
ggazzo Oct 22, 2026
bcc0646
refactor: drop Divider margin that repeats its default
ggazzo Oct 22, 2026
e4c5391
refactor: let containers space and size Divider instead of its props
ggazzo Oct 22, 2026
ccea384
chore: space Callouts with gap on their container instead of margins
ggazzo Oct 22, 2026
2aacb1f
chore: drop styling props from FieldLabel that its layout already gives
ggazzo Oct 22, 2026
d2c35ea
chore: lay out FieldRow children with a Box instead of FieldRow styli…
ggazzo Oct 22, 2026
01f1ebd
chore: lay out FieldError content with a Box instead of FieldError st…
ggazzo Oct 22, 2026
19f95a0
chore: space and lay out Fields from their container instead of Field…
ggazzo Oct 22, 2026
87e6bc8
chore: size and space FieldGroups from their container instead of Fie…
ggazzo Oct 22, 2026
6261e56
chore: lay out Buttons from their container instead of styling props
ggazzo Oct 22, 2026
45f381c
chore: space IconButtons with gap on their container instead of margins
ggazzo Oct 22, 2026
0910d7d
refactor: let containers size and space TextInput instead of its props
ggazzo Oct 22, 2026
06cb6a8
refactor: drop PasswordInput flexGrow that repeats its default
ggazzo Oct 22, 2026
c0417a7
refactor: let containers space InputBox instead of Margins and flexGrow
ggazzo Oct 22, 2026
39816dc
refactor: drop TextAreaInput flex props that change nothing
ggazzo Oct 22, 2026
7701c64
refactor: drop NumberInput and EmailInput sizing props that change no…
ggazzo Oct 22, 2026
a33d53c
refactor: drop Select family sizing props that change nothing
ggazzo Oct 22, 2026
69717d5
refactor: let field rows size the paginated autocompletes
ggazzo Oct 22, 2026
0ea5b32
refactor: stop passing styling props to ModalContent
ggazzo Oct 22, 2026
ee16609
refactor: let containers space and lay out Label instead of its props
ggazzo Oct 22, 2026
6af10c6
refactor: lay out the image gallery states in a Box inside ModalBackdrop
ggazzo Oct 22, 2026
00539f7
refactor: drop ModalHeroImage max height that resets nothing
ggazzo Oct 22, 2026
dd5c4b7
refactor: stop passing layout props to MessageBlock
ggazzo Oct 22, 2026
d2b6b58
refactor: stop passing margins to CodeSnippet
ggazzo Oct 22, 2026
b0b90ee
chore(fuselage): keep Icons from shrinking in flex containers
ggazzo Oct 22, 2026
9431a67
chore: stop centring input addon Icons by hand
ggazzo Oct 22, 2026
e4b66fb
chore: let Button and Tag space their own icons
ggazzo Oct 22, 2026
9d7ef60
chore: drop CheckBox margins that never reached the box
ggazzo Oct 22, 2026
a4a2bb4
chore: space omnichannel tag and filter Chips from their container
ggazzo Oct 22, 2026
4d06ae4
chore: space and size Tags from their container instead of Tag stylin…
ggazzo Oct 22, 2026
e19f654
chore: drop Throbber's redundant centering and space it from its cont…
ggazzo Oct 22, 2026
902c883
chore: let CardGrid and ReportCard stretch their Cards instead of Car…
ggazzo Oct 22, 2026
7c046aa
chore: lay out Tabs and TabsItem from their container instead of styl…
ggazzo Oct 22, 2026
b9ae270
chore: size and center Accordions from their container
ggazzo Oct 22, 2026
447b9c7
chore: let the report card center its States instead of sizing them
ggazzo Oct 22, 2026
e60d0ad
chore: style engagement dashboard empty Tiles through their content
ggazzo Oct 22, 2026
345bdd9
chore: keep the watermark's bottom inset inside its content
ggazzo Oct 22, 2026
85d10ec
chore: space the instances description list from its own container
ggazzo Oct 22, 2026
302935a
chore: lay out remaining Icons from their container
ggazzo Oct 22, 2026
0a03e06
chore: space the two-factor settings with gap instead of Margins
ggazzo Oct 22, 2026
3d462c0
chore: space admin views with gap instead of Margins
ggazzo Oct 22, 2026
063eb56
chore: space audit, directory and video conference views with gap ins…
ggazzo Oct 22, 2026
80c9dd7
chore: space omnichannel analytics and contact history with gap inste…
ggazzo Oct 22, 2026
cdf411c
chore: space onboarding and feature preview pages with gap instead of…
ggazzo Oct 22, 2026
0ed4f25
refactor(fuselage): declare Skeleton width and height
ggazzo Oct 22, 2026
38e7f24
chore(fuselage): space ContextualbarSkeleton placeholders with gap
ggazzo Oct 22, 2026
5c32911
chore: space stacked Skeletons with gap on their container instead of…
ggazzo Oct 22, 2026
75d997a
chore: lay out Skeleton rows from their container instead of margins …
ggazzo Oct 22, 2026
cf56a6b
chore: size the parent room Skeleton with width and height instead of…
ggazzo Oct 22, 2026
93d93b3
feat(fuselage): add Stack
ggazzo Oct 22, 2026
c502188
refactor: lay out gap containers with Stack
ggazzo Oct 22, 2026
a2ad0c3
chore(fuselage): pass internal rcx-* classes as className instead of …
ggazzo Oct 22, 2026
46ca8c1
chore(fuselage): space CardGrid items from its own styles instead of …
ggazzo Oct 22, 2026
7930289
chore(fuselage): move spacing and layout Fuselage passes to its own c…
ggazzo Oct 22, 2026
928a5d6
chore(fuselage): render Options and Dropdown surfaces as tile Boxes i…
ggazzo Oct 22, 2026
cb70d4d
chore(fuselage): space select addons and filter inputs from Select st…
ggazzo Oct 22, 2026
b0acadd
chore(fuselage): space PaginatedMultiSelect chips with gap instead of…
ggazzo Oct 22, 2026
cf8f952
chore(fuselage): space AudioPlayer controls with gap instead of Margins
ggazzo Oct 22, 2026
874db8b
chore(fuselage): color the Sidebar story footer text with a Box inste…
ggazzo Oct 22, 2026
a7a7852
fix: keep the outbound message retry icon spinning while loading
ggazzo Oct 22, 2026
aee6bbd
fix(fuselage): keep Stack from forwarding is and color to Box
ggazzo Oct 22, 2026
80e8fbf
fix(fuselage): give the fixed-width MessageBlock a valid width
ggazzo Oct 22, 2026
dcd5c8f
chore: drop the unused oembed maxWidth
ggazzo Oct 22, 2026
45e1e73
chore: space the emoji picker divider with one padding box
ggazzo Oct 22, 2026
a023fd9
chore: give the E2EE and playground edit-menu dividers their own padd…
ggazzo Oct 22, 2026
ca7deed
chore: give the room info ABAC divider its own box instead of spacing…
ggazzo Oct 22, 2026
a08a964
chore: let the audit date range picker lay out its own row
ggazzo Oct 22, 2026
3de4fe7
chore: share the omnichannel not-available callout
ggazzo Oct 22, 2026
56f165e
chore: reuse the shared FormSkeleton in the omnichannel directory
ggazzo Oct 22, 2026
4539f39
chore: lay out the audit form filter row with Stack
ggazzo Oct 22, 2026
e0c5df5
test(fuselage): add visual regression baselines for Stack
ggazzo Oct 22, 2026
d1a383b
fix(fuselage): keep the positioned element's own style in Position
ggazzo Oct 22, 2026
9a7e935
chore: let Icons inherit their colour where it matches the text
ggazzo Oct 22, 2026
6c47fbc
chore: colour icon rows from their container
ggazzo Oct 22, 2026
9ded9e9
chore(uikit-playground): colour the tree rows from the row
ggazzo Oct 22, 2026
e821484
chore: drop redundant is='th' from TableHead cells
ggazzo Oct 22, 2026
f78d61a
fix: mark instance property names as row headers
ggazzo Oct 22, 2026
65eccf0
chore: keep square buttons at their size in stretched ButtonGroups
ggazzo Oct 22, 2026
22db4cc
chore: give equal-width button rows ButtonGroup stretch='equal'
ggazzo Oct 22, 2026
0011f3d
chore: add Button compact for UiKit's short-label buttons
ggazzo Oct 22, 2026
189654c
chore: position overlay buttons with a wrapping Box
ggazzo Oct 22, 2026
552fb6c
feat(fuselage): add a flush Divider that leaves spacing to its container
ggazzo Oct 22, 2026
deb9ec8
feat(fuselage): add a light Divider variation
ggazzo Oct 22, 2026
0bcd054
feat(fuselage): add small and stretch vertical Divider
ggazzo Oct 22, 2026
cd76a1c
feat(fuselage): add a small Chip for the 20px search filter chips
ggazzo Oct 22, 2026
4a93a0c
feat(fuselage): add an uppercase label Chip for app categories
ggazzo Oct 22, 2026
92a9698
feat(fuselage): add CardGridItem with column spans and a CardGrid min…
ggazzo Oct 22, 2026
9293fe4
feat(fuselage): add stretch Tabs for the wizard tabs
ggazzo Oct 22, 2026
83e9236
chore: colour status icons from their container where the text sets i…
ggazzo Oct 22, 2026
340c6a9
feat(fuselage): add StatusIcon
ggazzo Oct 22, 2026
f7e277a
chore: draw status icons with StatusIcon
ggazzo Oct 22, 2026
9282be9
feat(fuselage): ModalIcon variant and ModalTagline subtle
ggazzo Oct 22, 2026
9bd4f94
feat(fuselage): Modal declares its size, hidden and a fill ModalContent
ggazzo Oct 22, 2026
a98c4ab
feat(fuselage): ModalBackdrop transparent
ggazzo Oct 22, 2026
2497a6e
feat(fuselage): ModalHeroImage declares its size
ggazzo Oct 22, 2026
af73b1c
refactor: Labels used as text become Box
ggazzo Oct 22, 2026
a840c23
refactor: Select rows space their items with gap
ggazzo Oct 22, 2026
8f67ab1
refactor: import pages space their Throbbers with gap
ggazzo Oct 22, 2026
1aeb4bf
refactor: wrapping filter rows use columnGap
ggazzo Oct 22, 2026
b9e3eee
refactor: loading skeletons take spacing from their container
ggazzo Oct 22, 2026
16bc8a3
refactor: drop Margins from the email inbox form, analytics chart and…
ggazzo Oct 22, 2026
0a6d6ee
refactor(fuselage): labelled Divider has no inline padding
ggazzo Oct 22, 2026
5623208
fix: modal icons take their colour from ModalIcon variant
ggazzo Oct 22, 2026
1241fdd
chore: add changeset for the GenericModal status icon colours
ggazzo Oct 22, 2026
506d5e7
chore: lay out inline icons with a flex row and gap
ggazzo Oct 22, 2026
bdd1c34
chore: colour status icons with StatusIcon
ggazzo Oct 22, 2026
17fa25c
chore: add changeset for the UiKit icon element status colours
ggazzo Oct 22, 2026
2fdc7ae
fix(fuselage): keep ModalContent fill a boolean and use the flex shor…
ggazzo Oct 22, 2026
0cdf176
test(fuselage): add visual regression baselines for the new component…
ggazzo Oct 22, 2026
56520e8
chore: stop pulling the contextual bar header 1px up
ggazzo Oct 22, 2026
195119b
chore: space margin-collapsed siblings with gap
ggazzo Oct 22, 2026
7dfee0f
chore: drop one-off margins on Field parts
ggazzo Oct 22, 2026
cddb174
chore: use ModalIcon in the team removal and conversion modals
ggazzo Oct 22, 2026
cf3fd84
chore: render each action setting as one Field
ggazzo Oct 22, 2026
1107cb8
chore: space a setting's callout and upgrade button with gap
ggazzo Oct 22, 2026
67151f5
chore: lay out asset and range settings like the other inputs
ggazzo Oct 22, 2026
8f6a75d
fix(fuselage): keep Select's hidden select out of its container's layout
ggazzo Oct 22, 2026
cb70922
refactor(omnichannel): build the Analytics filter bar from Fields
ggazzo Oct 22, 2026
de23e44
refactor(omnichannel): build the Livechat queue filter bar from Fields
ggazzo Oct 22, 2026
ca93a1d
refactor(omnichannel): build the Real-time monitoring filters from Fi…
ggazzo Oct 22, 2026
2f3ce60
refactor(omnichannel): build the Canned responses filter bar from Fields
ggazzo Oct 22, 2026
dc1c8d3
refactor: size the date range Fields with wrapper Boxes
ggazzo Oct 22, 2026
bb8d7cc
chore: AppInstances status Tag uses the secondary-danger variant
ggazzo Oct 22, 2026
9381fa6
chore: UserCard actions split the row equally
ggazzo Oct 22, 2026
017cf32
feat(fuselage): pin the IconButton badge to the bottom end corner wit…
ggazzo Oct 22, 2026
d27023d
chore: header thread action and user menu use the IconButton badge slot
ggazzo Oct 22, 2026
1b73d1a
chore: profile account actions keep their natural width
ggazzo Oct 22, 2026
85663d6
chore: draw the real-time counter dividers as full-height lines
ggazzo Oct 22, 2026
cddf50e
refactor(audit): size the audit tab Fields with wrapper Boxes
ggazzo Oct 22, 2026
ed2c9f0
feat(fuselage): Tile flush
ggazzo Oct 22, 2026
df43c68
chore(fuselage): render Options and Dropdown surfaces with Tile flush
ggazzo Oct 22, 2026
f8428aa
fix(fuselage): vertical Divider ignores the danger variation
ggazzo Oct 22, 2026
f9f6f97
feat(fuselage): Chip has a fixed 28px height
ggazzo Oct 22, 2026
5bba9d4
feat(fuselage): AutoComplete and MultiSelect space selected items wit…
ggazzo Oct 22, 2026
e917875
fix(fuselage): date and time inputs no longer grow past their line he…
ggazzo Oct 22, 2026
8b755c4
refactor: drop the height compensation on date and time InputBoxes
ggazzo Oct 22, 2026
b337293
test(fuselage): update visual regression baselines for Tile flush, ba…
ggazzo Oct 22, 2026
3fe9eed
refactor: UsersInRolePage spaces the users table and pagination with gap
ggazzo Oct 22, 2026
b9a5cc0
refactor: CreateRoomModalSkeleton stacks its input skeletons with gap
ggazzo Oct 22, 2026
7eb6129
refactor: drop styling props from Dialpad TextInput and 40px Buttons
ggazzo Oct 22, 2026
5127918
fix(fuselage): give InputBoxes with an addon the 40px minimum height
ggazzo Oct 22, 2026
f4c2cce
refactor: drop the 40px boxes around inputs with an addon
ggazzo Oct 22, 2026
338596c
test(fuselage): update visual regression baselines for 40px addon inputs
ggazzo Oct 22, 2026
55a39e4
feat(fuselage): Button and IconButton accept only 'button' or 'a' as is
ggazzo Oct 22, 2026
f842b4f
feat(fuselage): TableCell accepts only 'td' or 'th' as is
ggazzo Oct 22, 2026
4d4d507
fix(fuselage): legacy selects label their focusable control
ggazzo Oct 22, 2026
94e2e91
fix(fuselage): legacy selects forward id to their focusable control
ggazzo Oct 22, 2026
cb22da8
test: locate legacy selects by their label
ggazzo Oct 22, 2026
5cf2ab9
refactor: drop is='span' from FieldLabel next to select fields
ggazzo Oct 22, 2026
35eaff5
refactor(layout): Form wraps a Tile instead of rendering the Tile as …
ggazzo Oct 22, 2026
95c6433
fix: user menu button exposes the user's status to assistive technology
ggazzo Oct 22, 2026
05db8d0
fix(fuselage): Button and IconButton links drop type='button', IconBu…
ggazzo Oct 22, 2026
f13f27a
refactor: space app menu option icons with gap
ggazzo Oct 22, 2026
c9570cd
refactor: space message actions from their containers
ggazzo Oct 22, 2026
8c34e00
refactor: inset the AI search divider from its container
ggazzo Oct 22, 2026
93ab9d1
refactor: inset the intelligent search results button from its container
ggazzo Oct 22, 2026
41b925a
refactor: inset the AI Center callout button from its container
ggazzo Oct 22, 2026
80a3bcf
refactor: space subscription callouts from their container
ggazzo Oct 22, 2026
b05bf9b
refactor: space the outbound retry button from its container
ggazzo Oct 22, 2026
8491c89
refactor: space the generic file preview icon with gap
ggazzo Oct 22, 2026
c3f5633
refactor(omnichannel): paginated selects keep their width from a wrap…
ggazzo Oct 22, 2026
e6af80b
refactor: FilterByText sizes its search input from the container
ggazzo Oct 22, 2026
2a85df1
refactor: drop the unused optionWidth from UserStatusMenu
ggazzo Oct 22, 2026
72fa155
refactor: SidePanelTag caps its width with a wrapper Box
ggazzo Oct 22, 2026
a5eb28b
refactor(marketplace): space the app price Tag with gap
ggazzo Oct 22, 2026
c1a0def
refactor(omnichannel): outbound wizard forms scroll and pad a Box aro…
ggazzo Oct 22, 2026
71d06c6
refactor(uikit-playground): drop styling props from Fuselage components
ggazzo Oct 22, 2026
8dee3c5
refactor(ui-client): page header spaces its buttons with gap
ggazzo Oct 22, 2026
b893298
refactor: federated origin tag renders its icon in the Tag icon slot
ggazzo Oct 22, 2026
6d71be6
refactor(ui-voip): widget info slots space the icon with gap
ggazzo Oct 22, 2026
98f865b
refactor(ui-voip): call history buttons space the icon with gap
ggazzo Oct 22, 2026
c9a2edb
refactor(web-ui-registration): login services divider spaced by its c…
ggazzo Oct 22, 2026
24bec91
feat(fuselage): Skeleton inverted, for placeholders on dark surfaces
ggazzo Oct 22, 2026
9d5fb53
refactor: tooltip loading skeletons use the inverted Skeleton
ggazzo Oct 22, 2026
397e33e
refactor: drop the size FramedIcon ignores
ggazzo Oct 22, 2026
3212b07
fix: import history Counters header spans the Total column
ggazzo Oct 22, 2026
2b13462
feat(fuselage): Table declares its columns
ggazzo Oct 22, 2026
689bb7a
feat(fuselage): TableCell rowHeader
ggazzo Oct 22, 2026
6b2d179
refactor: import tables declare their column widths on Table
ggazzo Oct 22, 2026
ab951d1
refactor: instance details label cells use TableCell rowHeader
ggazzo Oct 22, 2026
f5565a2
feat(fuselage): PopoverSurface
ggazzo Oct 22, 2026
41fd498
refactor(fuselage): dropdown and option lists use PopoverSurface
ggazzo Oct 22, 2026
68e359f
refactor: Marketplace filter lists use PopoverSurface
ggazzo Oct 22, 2026
7247750
refactor(ui-client): MultiSelectCustom list uses PopoverSurface
ggazzo Oct 22, 2026
9080563
refactor: desktop emoji picker dropdown uses PopoverSurface
ggazzo Oct 22, 2026
1c235a8
refactor(onboarding-ui): cloud workspace form pads its Grid instead o…
ggazzo Oct 22, 2026
96497ee
refactor(ui-composer): MessageFooterCallout spaces its children with gap
ggazzo Oct 22, 2026
05ce0c6
feat(fuselage): inputs with a flush end addon
ggazzo Oct 22, 2026
b9511a0
refactor: flush the avatar URL button through endAddonFlush
ggazzo Oct 22, 2026
4806933
refactor: flush the app install Browse Files button through endAddonF…
ggazzo Oct 22, 2026
accbb5c
chore: priority menu icons take their colour from the priority status
ggazzo Oct 22, 2026
a648f96
feat(fuselage): Icon declares color from the semantic font tokens
ggazzo Oct 22, 2026
9eee9ca
refactor(web-ui-registration): language switch buttons are spaced wit…
ggazzo Oct 22, 2026
5bf5d67
refactor(marketplace): app status button group spaces the Buy button …
ggazzo Oct 22, 2026
494fbb7
refactor: users table search input sized by a wrapper Box
ggazzo Oct 22, 2026
876d028
refactor: room header row spaces its items with columnGap
ggazzo Oct 22, 2026
7c0cd71
refactor: attachment author row spaces its items with gap
ggazzo Oct 22, 2026
c3542ec
refactor(omnichannel): drop the full-bleed divider from contact details
ggazzo Oct 22, 2026
5b2470b
refactor(audit): space the page and the form with gap instead of Margins
ggazzo Oct 22, 2026
0796d0f
feat(fuselage): PopoverSurface elevation
ggazzo Oct 22, 2026
4d8a353
refactor(fuselage): OptionContainer surface is a PopoverSurface
ggazzo Oct 22, 2026
a0abc54
refactor: navbar search results list uses PopoverSurface
ggazzo Oct 22, 2026
e8ff442
refactor: navbar AI search list uses PopoverSurface
ggazzo Oct 22, 2026
39a5b39
refactor: canned responses placeholder dropdown uses PopoverSurface
ggazzo Oct 22, 2026
0d0ce9d
refactor: composer popups use PopoverSurface
ggazzo Oct 22, 2026
f5c2c30
refactor: favorite and category menu colour the icon, not the button
ggazzo Oct 22, 2026
2265c04
refactor: status icons use Icon color
ggazzo Oct 22, 2026
a2459f2
refactor(fuselage): drop StatusIcon
ggazzo Oct 22, 2026
134a151
feat(fuselage): FieldRow justify='end'
ggazzo Oct 22, 2026
183b31a
refactor: form labels drop their typography props
ggazzo Oct 22, 2026
d4efc2e
refactor: labels and their actions share a FieldRow
ggazzo Oct 22, 2026
636ad58
refactor: page-width forms cap their width with a wrapper Box
ggazzo Oct 22, 2026
1bec3fc
refactor: Field spacing and trailing links use the container or Field…
ggazzo Oct 22, 2026
9b67a1b
feat(fuselage): IconButton color
ggazzo Oct 22, 2026
55145db
refactor(fuselage): Button spaces its icon in its own styles
ggazzo Oct 22, 2026
d91aa8b
refactor(web-ui-registration): login on the web joins the login servi…
ggazzo Oct 22, 2026
a7d2391
refactor: admin user form and invite buttons use Button small and a p…
ggazzo Oct 22, 2026
55c2e7b
refactor: drop styling props that change nothing on Fuselage components
ggazzo Oct 22, 2026
5d3e887
refactor: inline icons align through an inline-flex container
ggazzo Oct 22, 2026
b3ede59
refactor: ABAC room attribute selects drop withTruncatedText and thei…
ggazzo Oct 22, 2026
6ec27e1
refactor: insets around tabs, callouts and a field row become contain…
ggazzo Oct 22, 2026
b87394d
refactor: instance value cells color their text with a Box
ggazzo Oct 22, 2026
1691460
refactor(ui-voip): keypad keys size themselves through their existing…
ggazzo Oct 22, 2026
4df202c
refactor(web-ui-registration): login service brand colors go through …
ggazzo Oct 22, 2026
7b543d0
refactor(fuselage-ui-kit): linear scale buttons are spaced by the but…
ggazzo Oct 22, 2026
3b81853
refactor(layout): vertical wizard form sizes its Tile with a wrapper
ggazzo Oct 22, 2026
fdfeeaf
test(fuselage): add visual regression baselines for the new stories
ggazzo Oct 23, 2026
5df0755
refactor(fuselage-ui-kit): surfaces space their blocks with gap
ggazzo Oct 22, 2026
047906f
refactor(fuselage-ui-kit): context block spaces its elements with gap
ggazzo Oct 23, 2026
e371b82
chore: merge the changesets of this pull request into one
ggazzo Oct 23, 2026
ae77106
fixup! chore: profile account actions keep their natural width
ggazzo Oct 23, 2026
ffd41f0
fixup! refactor: labels and their actions share a FieldRow
ggazzo Oct 23, 2026
0f653b5
fixup! chore: lay out asset and range settings like the other inputs
ggazzo Oct 23, 2026
e352264
fixup! chore: lay out inline icons with a flex row and gap
ggazzo Oct 23, 2026
1235dcc
fixup! refactor: drop Margins from the email inbox form, analytics ch…
ggazzo Oct 23, 2026
9681cb8
fixup! refactor: form labels drop their typography props
ggazzo Oct 23, 2026
5767ef4
fixup! chore: space audit, directory and video conference views with …
ggazzo Oct 23, 2026
b706e74
fixup! chore: space margin-collapsed siblings with gap
ggazzo Oct 23, 2026
c82d65c
fixup! fix: user menu button exposes the user's status to assistive t…
ggazzo Oct 23, 2026
73b12e5
fixup! chore: header thread action and user menu use the IconButton b…
ggazzo Oct 23, 2026
f15e846
fix: associate asset and action setting labels with their controls
ggazzo Oct 23, 2026
22aeac4
fixup! refactor: form labels drop their typography props
ggazzo Oct 23, 2026
77ea36d
fixup! refactor: inline icons align through an inline-flex container
ggazzo Oct 23, 2026
8747cb8
chore: lower the styling-props limit to 1 and raise the raw-layout li…
ggazzo Oct 23, 2026
d5362b4
fix(fuselage): IconButton badge stays in its corner while pressed
ggazzo Oct 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
113 changes: 113 additions & 0 deletions .changeset/fuselage-no-styling-props.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
'@rocket.chat/fuselage': minor
'@rocket.chat/fuselage-ui-kit': patch
'@rocket.chat/layout': patch
'@rocket.chat/meteor': patch
'@rocket.chat/onboarding-ui': patch
'@rocket.chat/ui-client': patch
'@rocket.chat/ui-composer': patch
'@rocket.chat/ui-voip': patch
'@rocket.chat/web-ui-registration': patch
---

Fuselage components no longer take Box styling props from their callers: containers own layout through `gap`, and components declare the variations they support.

**fuselage**

- `Button` accepts `compact`, which lowers its minimum width so a label of one or two characters fits.
- `ButtonGroup` accepts `stretch='equal'`, which stretches its buttons and gives them all the same width.
- Square buttons, such as `IconButton`, keep their size inside a `ButtonGroup` with `stretch` instead of growing with the other buttons.
- The icon inside a `Button` takes its spacing from the Button styles instead of a styling prop.
- `CardGrid` accepts `CardGridItem` children with their own column spans and a `minRowHeight`, and skips empty children instead of rendering empty cells.
- `CardGrid` stretches each card to the height of its row, so cards no longer need `height='full'`.
- `Chip` accepts `label`, which renders its text in uppercase for chips that categorize rather than select.
- `Chip` accepts `small`, which renders a 20px tall chip.
- Inputs with an addon have the same minimum height as the other inputs.
- `AutoComplete` and `MultiSelect` space their input and selected items with a 4px gap instead of wrapping them in `Margins`, so a `renderSelected` item no longer needs to forward its class name or bring its own margin to be spaced.
- Button and IconButton render only as a button or a link: `is` accepts `'button'` or `'a'`.
- Button and IconButton rendered as links no longer carry `type="button"`, and IconButton accepts `external` to open its link in a new tab.
- `Chip` has a fixed 28px height, so chips holding an inline avatar no longer grow past it; `small` chips stay 20px.
- Date and time inputs match the other inputs' height
- Adds a `flush` prop to `Divider` that removes its own margin, so its container sets the spacing.
- Adds a `light` variation to `Divider`, drawn with the `stroke-light` color.
- A vertical `Divider` with `variation='danger'` is drawn in the error colour instead of the default grey.
- Adds `small` and `stretch` props to the vertical `Divider`: `small` uses a 4px inline margin, `stretch` makes it as tall as its container.
- Adds a `justify='end'` variation to `FieldRow` that packs the row's content at the end of the line.
- Declares `color` on `Icon`, `MenuItemIcon` and `MessageStatusIndicatorItem`, restricted to the semantic text and status font tokens.
- Icons no longer shrink in a flex container.
- Adds `endAddonFlush` to `InputBox` and the inputs built on it, so a button in `endAddon` sits flush with the input edge without negative margins
- Adds a `transparent` flag to `ModalBackdrop` that drops its overlay colour.
- Declares `width` and `height` on `ModalHeroImage`, the size the image renders at.
- Adds a `variant` (`danger`, `warning`, `info`, `success`) to `ModalIcon` that tints the icon, and a `subtle` flag to `ModalTagline` that mutes its colour.
- Declares `width` and `height` on `Modal`, makes its `hidden` attribute hide it while keeping it mounted, and adds a `fill` mode to `ModalContent` that stretches the content to the modal's height.
- Adds `PopoverSurface`, the raised and scrolling surface of a dropdown or popover, which takes `maxHeight`, `flush` and `elevation` instead of `Box` styling props.
- Adds the `inverted` variation to `Skeleton`, for placeholders on a dark surface such as a tooltip.
- Adds `Stack`, a flex container that lays out its children in a row or a column spaced by `gap`, without taking `Box` styling props.
- TableCell renders only as a data or header cell: `is` accepts `'td'` or `'th'`.
- `Tag` now spaces its `icon` from the label, so the icon no longer needs a margin of its own.
- Adds a `flush` flag to `Tile` that drops its default padding, for surfaces whose content brings its own.
- Adds `badgePosition` to `IconButton`, which pins the badge to the top end (default) or bottom end corner.
- `IconButton` accepts `color`, `'default'` or `'danger'`, which paints the icon with that font color.
- A Divider with a label no longer adds 20px of inline padding, so its bars run from edge to edge of its container.
- `SelectLegacy`, `SelectFiltered`, `PaginatedSelectFiltered` and `PaginatedMultiSelectFiltered` put `id` on their focusable control, so clicking a `FieldLabel` whose `htmlFor` points to that `id` focuses the field.
- `SelectLegacy`, `SelectFiltered`, `PaginatedSelectFiltered` and `PaginatedMultiSelectFiltered` put `aria-labelledby`, `aria-describedby` and `aria-invalid` on their focusable control instead of the wrapper, so screen readers announce the field's label instead of its placeholder.
- `MessageGenericPreviewIcon` takes its icon colour from the preview's styles and no longer accepts a `color` prop.
- Fixes `Select` adding an extra gap before its trigger when placed directly inside a container that spaces its children with `gap`.
- `TableCell` accepts `rowHeader`, which renders the cell as the header of its row, styled as the label of a key/value pair.
- `Table` accepts `columns`, which declares the width of each column once instead of on every cell.
- `Tabs` accepts `stretch`, which grows its items to fill the whole width.

**fuselage-ui-kit**

- The `context` block spaces its elements with an 8px column gap instead of margins, so it no longer overhangs the surface edges and its images sit 8px from their neighbours.
- The `linear_scale` element spaces its buttons with the button group's gap alone, so they sit 8px apart instead of 12px.
- UiKit surfaces space their blocks with a 16px gap instead of per-block margins, so blocks sit 16px apart, divider and tabs no longer add their own 24px margins, and only the message surface keeps 16px of space after its last block.
- Colours UiKit icon elements with `danger`, `warning` and `secondary` variants through Fuselage's `Icon` `color`; `secondary` now uses the hint colour.

**layout**

- `Form` renders a form element that wraps its `Tile`, instead of rendering the `Tile` itself as the form.
- Narrows `ListItem`'s `iconColor` to a status (`hint`, `info`, `danger`, `warning` or `success`); without one the icon follows the item's text colour, as it already did.
- `VerticalWizardLayoutForm` sizes its `Tile` with a full-width wrapper instead of a `width` prop on `Tile`.

**meteor**

- When an app has no price, its status tags on the details page sit 8px closer to the Buy button.
- The author row of quote and message attachments spaces its avatar, name, timestamp and jump link 4px apart.
- Audited messages on the Message auditing page no longer inherit an extra vertical margin, so each one is 8px shorter.
- The contact details panel no longer draws a divider above the custom fields; they follow the other fields with the same spacing.
- The custom emoji upload button and the canned response preview toggle sit next to their label in a `FieldRow` instead of inside the label.
- Form labels in the thread composer, the workspace registration terms, the onboarding terms and the new-user password options use the default field label typography, and the close-chat modal note is shown as a field hint.
- Fixes the "Counters" header of the import history table so it also spans the "Total" column.
- Fixes the instances modal announcing each property name as a column header instead of a row header
- Colours the icons of the room priority menu like the priority icon shown in the room, by the priority's status.
- The room header leaves 4px instead of 8px after the encrypted and translated status icons.
- Fixes the user menu button so screen readers announce the user's current status and its changes.

**onboarding-ui**

- The cloud workspace form spaces its server region and language fields with padding around the grid instead of a margin on it, which adds 24 to 32px of height to the form.

**ui-client**

- Fixes the warning and success icons of `GenericModal` showing in the default text colour instead of their status colours.
- `HeaderTagIcon` no longer carries a trailing margin; pass it to `HeaderTag`'s `icon` prop, which spaces it from the text.
- Page header spaces its sidebar toggler and back button with gap; `SidebarToggler` no longer carries a trailing margin.
- `HeaderContentRow` spaces its items 4px apart, and `HeaderState` no longer adds its own trailing margin.
- The `MultiSelectCustom` list is drawn on Fuselage's `PopoverSurface`, so its corners are rounded like the other dropdowns.

**ui-composer**

- `MessageFooterCallout` spaces its children with an 8px gap instead of margins on `MessageComposerIcon`, `MessageFooterCalloutContent`, `MessageFooterCalloutDivider` and `MessageFooterCalloutAction`, so the action button now sits flush with the callout padding.

**ui-voip**

- Call history footer buttons lay out their icon and label with gap.
- The keypad keys take their size and corner radius from their own class instead of styling props on `Button`.
- Call widget info slots lay out their icon and text with gap.

**web-ui-registration**

- The desktop app's "Log in on the web" button sits in the same button group as the login services.
- The login services divider takes its spacing from a padded container.
- The login language switch buttons are spaced with an 8px gap instead of a trailing margin, so they are centred in the footer.
4 changes: 2 additions & 2 deletions .github/workflows/ci-code-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ jobs:

- name: Styling props on Fuselage components
if: matrix.check == 'lint'
run: node scripts/scan-style-props.mjs --max 914 "$RUNNER_TEMP/style-props-findings.json"
run: node scripts/scan-style-props.mjs --max 1 "$RUNNER_TEMP/style-props-findings.json"

- name: Raw layout elements in screens
if: matrix.check == 'lint'
run: node scripts/scan-raw-layout.mjs --max 1166 "$RUNNER_TEMP/raw-layout-findings.json"
run: node scripts/scan-raw-layout.mjs --max 1248 "$RUNNER_TEMP/raw-layout-findings.json"
Comment thread
ggazzo marked this conversation as resolved.
Resolved

- name: Stylelint
if: matrix.check == 'lint'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const AbacAttributesRemovalWarning = ({ roomNames }: AbacAttributesRemovalWarnin
const enforcementOn = useIsAbacEnforcementOn();

return (
<Callout type='warning' marginBlockStart={16}>
<Callout type='warning'>
{roomNames ? t('ABAC_Attributes_will_be_removed_from_rooms', { rooms: roomNames.join(', ') }) : t('ABAC_Attributes_will_be_removed')}
{enforcementOn &&
` ${roomNames ? t('ABAC_Rooms_locked_until_attributes_reassigned') : t('ABAC_Room_locked_until_attributes_reassigned')}`}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ const AbacMembershipPreview = ({ data, isPending, isError, error }: AbacMembersh

if (isPending) {
return (
<Box>
<Box display='flex' flexDirection='column' gap={8} marginBlockEnd={8}>
{Array.from({ length: 4 }, (_, index) => (
<Skeleton key={index} marginBlockEnd={8} />
<Skeleton key={index} />
))}
</Box>
);
Expand All @@ -33,27 +33,13 @@ const AbacMembershipPreview = ({ data, isPending, isError, error }: AbacMembersh
const hasCompliant = compliant.length > 0;

return (
<Box>
{!hasCompliant && (
<Callout type='danger' marginBlockEnd={16}>
{t('ABAC_Preview_No_Compliant_Members')}
</Callout>
)}
<Box display='flex' flexDirection='column' gap={16} marginBlockEnd={16}>
{!hasCompliant && <Callout type='danger'>{t('ABAC_Preview_No_Compliant_Members')}</Callout>}
{hasCompliant && (nonCompliant.length > 0 || inconclusive.length > 0) && (
<Callout icon='info-circled' marginBlockEnd={16}>
{t('ABAC_Preview_Only_Compliant_Added')}
</Callout>
)}
{hasCompliant && creator === 'nonCompliant' && (
<Callout type='warning' marginBlockEnd={16}>
{t('ABAC_Preview_Creator_Not_Added')}
</Callout>
)}
{inconclusive.length > 0 && (
<Callout type='warning' marginBlockEnd={16}>
{t('ABAC_Preview_Inconclusive_Warning')}
</Callout>
<Callout icon='info-circled'>{t('ABAC_Preview_Only_Compliant_Added')}</Callout>
)}
{hasCompliant && creator === 'nonCompliant' && <Callout type='warning'>{t('ABAC_Preview_Creator_Not_Added')}</Callout>}
{inconclusive.length > 0 && <Callout type='warning'>{t('ABAC_Preview_Inconclusive_Warning')}</Callout>}
<AbacPreviewMemberGroup title={t('ABAC_Preview_Compliant')} members={compliant} verdict='compliant' />
<AbacPreviewMemberGroup title={t('ABAC_Preview_Non_Compliant')} members={nonCompliant} verdict='nonCompliant' />
<AbacPreviewMemberGroup title={t('ABAC_Preview_Inconclusive')} members={inconclusive} verdict='inconclusive' />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ const AbacPreviewMemberGroup = ({ title, members, verdict }: AbacPreviewMemberGr
}

return (
<Box is='section' aria-label={title} marginBlockEnd={16}>
<Box is='section' aria-label={title}>
<Box display='flex' justifyContent='space-between' fontScale='c2' color='hint'>
<span>{title}</span>
<span>{members.length}</span>
</Box>
<Divider marginBlock={8} />
<Divider />
<Box is='ul'>
{members.map(({ _id, username, name }) => (
<Box is='li' key={_id} display='flex' alignItems='center' paddingBlock={4}>
Expand All @@ -35,7 +35,7 @@ const AbacPreviewMemberGroup = ({ title, members, verdict }: AbacPreviewMemberGr
<UserAvatar username={username} size='x20' />
</Box>
)}
<Box flexGrow={1} withTruncatedText marginInlineStart={8}>
<Box flexGrow={1} withTruncatedText marginInline={8}>
<Box is='span' fontScale='p2m' color='default'>
{name || username}
</Box>
Expand All @@ -45,16 +45,7 @@ const AbacPreviewMemberGroup = ({ title, members, verdict }: AbacPreviewMemberGr
</Box>
)}
</Box>
<Icon
{...verdictIcons[verdict]}
size='x16'
flexShrink={0}
marginInlineStart={8}
role='img'
aria-hidden={false}
aria-label={title}
title={title}
/>
<Icon {...verdictIcons[verdict]} size='x16' role='img' aria-hidden={false} aria-label={title} title={title} />
</Box>
))}
</Box>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { InputBoxSkeleton, Modal, ModalClose, ModalContent, ModalHeader, ModalTitle } from '@rocket.chat/fuselage';
import { Box, InputBoxSkeleton, Modal, ModalClose, ModalContent, ModalHeader, ModalTitle } from '@rocket.chat/fuselage';
import { useTranslation } from 'react-i18next';

type CreateRoomModalSkeletonProps = {
Expand All @@ -15,10 +15,12 @@ const CreateRoomModalSkeleton = ({ title, onClose }: CreateRoomModalSkeletonProp
<ModalTitle>{title}</ModalTitle>
<ModalClose title={t('Close')} onClick={onClose} />
</ModalHeader>
<ModalContent marginBlockEnd={24}>
{Array.from({ length: 4 }, (_, index) => (
<InputBoxSkeleton key={index} marginBlockEnd={16} />
))}
<ModalContent>
<Box display='flex' flexDirection='column' gap={16} marginBlockEnd={24}>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This replaces each skeleton's trailing 16px margin with a flex gap, which only applies between children, so the modal loses 16px of bottom spacing. Preserve the former trailing space with paddingBlockEnd={16} (or an equivalent bottom spacing declaration) on this container.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At apps/meteor/client/components/ABAC/AbacRoomCreation/CreateRoomModalSkeleton.tsx, line 19:

<comment>This replaces each skeleton's trailing `16px` margin with a flex gap, which only applies between children, so the modal loses 16px of bottom spacing. Preserve the former trailing space with `paddingBlockEnd={16}` (or an equivalent bottom spacing declaration) on this container.</comment>

<file context>
@@ -15,10 +15,12 @@ const CreateRoomModalSkeleton = ({ title, onClose }: CreateRoomModalSkeletonProp
-					<InputBoxSkeleton key={index} marginBlockEnd={16} />
-				))}
+			<ModalContent>
+				<Box display='flex' flexDirection='column' gap={16} marginBlockEnd={24}>
+					{Array.from({ length: 4 }, (_, index) => (
+						<InputBoxSkeleton key={index} />
</file context>
Suggested change
<Box display='flex' flexDirection='column' gap={16} marginBlockEnd={24}>
<Box display='flex' flexDirection='column' gap={16} paddingBlockEnd={16} marginBlockEnd={24}>

{Array.from({ length: 4 }, (_, index) => (
<InputBoxSkeleton key={index} />
))}
</Box>
</ModalContent>
</Modal>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
Accordion,
AccordionItem,
Box,
Button,
ModalContent,
ModalFooter,
Expand Down Expand Up @@ -32,34 +33,36 @@ const CreateRoomSteps = ({ abac, flow, details, security, onCancel, submitDisabl

return (
<>
<ModalContent marginBlockEnd={2}>
{step === 'details' && (
<>
{details}
{!isStepped && (
<Accordion>
<AccordionItem title={t('Advanced_settings')}>{security}</AccordionItem>
</Accordion>
)}
</>
)}
{step === 'attributes' && (
<AbacAttributesStep
requiredKeys={abac?.requiredAttributes ?? []}
assignable={flow.assignable.data}
isPending={flow.assignable.isPending}
error={flow.assignable.error}
/>
)}
{step === 'security' && security}
{step === 'preview' && (
<AbacMembershipPreview
data={flow.preview.data}
isPending={flow.preview.isPending}
isError={flow.preview.isError}
error={flow.preview.error}
/>
)}
<ModalContent>
<Box marginBlockEnd={2}>
{step === 'details' && (
<>
{details}
{!isStepped && (
<Accordion>
<AccordionItem title={t('Advanced_settings')}>{security}</AccordionItem>
</Accordion>
)}
</>
)}
{step === 'attributes' && (
<AbacAttributesStep
requiredKeys={abac?.requiredAttributes ?? []}
assignable={flow.assignable.data}
isPending={flow.assignable.isPending}
error={flow.assignable.error}
/>
)}
{step === 'security' && security}
{step === 'preview' && (
<AbacMembershipPreview
data={flow.preview.data}
isPending={flow.preview.isPending}
isError={flow.preview.isError}
error={flow.preview.error}
/>
)}
</Box>
</ModalContent>
<ModalFooter justifyContent={isStepped ? 'space-between' : undefined}>
{isStepped && <ModalFooterAnnotation>{t('Step_of_total', { step: index + 1, total })}</ModalFooterAnnotation>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ const AbacRoomPreviewLoadMore = ({ context }: { context?: AbacRoomPreviewLoadMor
const { t } = useTranslation();

return (
<Box paddingInline={24} paddingBlock={12}>
<Button small secondary width='full' disabled={!context?.canLoadMore} onClick={context?.onLoadMore}>
<Box paddingInline={24} paddingBlock={12} display='flex' flexDirection='column'>
<Button small secondary disabled={!context?.canLoadMore} onClick={context?.onLoadMore}>
{t('Load_more')}
</Button>
</Box>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const AbacRoomPreviewMemberRow = ({ member: { username, name, verdict, roles = [
<UserAvatar username={username} size='x28' />
</Box>
)}
<Box display='flex' alignItems='center' flexGrow={1} minWidth={0} marginInlineStart={8}>
<Box display='flex' alignItems='center' flexGrow={1} minWidth={0} marginInline={8}>
<Box withTruncatedText title={fullName}>
<Box is='span' fontScale='p2m' color='default'>
{name || username}
Expand All @@ -52,7 +52,7 @@ const AbacRoomPreviewMemberRow = ({ member: { username, name, verdict, roles = [
</Box>
)}
</Box>
<Icon {...icon} size='x20' marginInlineStart={8} title={t(label)} />
<Icon {...icon} size='x20' title={t(label)} />
</Box>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,17 @@ import { Box, Skeleton } from '@rocket.chat/fuselage';
const AbacRoomPreviewSkeleton = () => (
<>
{Array.from({ length: 3 }, (_, index) => (
<Box key={index} display='flex' alignItems='center' paddingInline={24} paddingBlock={8}>
<Skeleton variant='rect' width='x28' height='x28' flexShrink={0} />
<Skeleton width='full' marginInlineStart={8} />
<Box
key={index}
display='grid'
alignItems='center'
gap={8}
paddingInline={24}
paddingBlock={8}
style={{ gridTemplateColumns: 'auto 1fr' }}
>
<Skeleton variant='rect' width='x28' height='x28' />
<Skeleton width='full' />
</Box>
))}
</>
Expand Down
2 changes: 1 addition & 1 deletion apps/meteor/client/components/Backdrop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ import type { ComponentProps } from 'react';

export type BackdropProps = ComponentProps<typeof ModalBackdrop>;

export const Backdrop = (props: BackdropProps) => <ModalBackdrop backgroundColor='transparent' {...props} />;
export const Backdrop = (props: BackdropProps) => <ModalBackdrop transparent {...props} />;
4 changes: 1 addition & 3 deletions apps/meteor/client/components/FilterByText.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,12 @@ const FilterByText = forwardRef<HTMLInputElement, FilterByTextProps>(function Fi

return (
<Box marginBlock={16} marginInline='neg-x4' is='form' onSubmit={handleFormSubmit} display='flex' flexWrap='wrap' alignItems='center'>
<Box marginInline={4} display='flex' flexGrow={1}>
<Box marginInline={4} display='flex' flexGrow={1} minWidth='x280'>
<TextInput
{...props}
placeholder={placeholder ?? t('Search')}
ref={mergedRefs}
endAddon={<Icon name='magnifier' size='x20' />}
flexGrow={2}
minWidth='x220'
aria-label={placeholder ?? t('Search')}
/>
</Box>
Expand Down
Loading
Loading