diff --git a/src/components/Common/DataView/DataTable/DataTable.test.tsx b/src/components/Common/DataView/DataTable/DataTable.test.tsx
index cfce1cc4bd..e25c05a71d 100644
--- a/src/components/Common/DataView/DataTable/DataTable.test.tsx
+++ b/src/components/Common/DataView/DataTable/DataTable.test.tsx
@@ -221,6 +221,26 @@ describe('DataTable Component', () => {
expect(screen.getByText('Name').closest('div')?.className).toMatch(/cellEnd/)
expect(screen.getByText('Alice').closest('div')?.className).toMatch(/cellEnd/)
})
+
+ test('does not wrap content when justify is unset — even for the last column', () => {
+ // Alignment is now driven solely by column.justify; there is no implicit
+ // "last column right-aligns" behavior, so an unset column must not be wrapped.
+ renderTable({
+ columns: [{ key: 'name', title: 'Name', render: item => item.name }],
+ })
+
+ expect(screen.getByText('Name').closest('div')?.className ?? '').not.toMatch(/cellEnd/)
+ expect(screen.getByText('Alice').closest('div')?.className ?? '').not.toMatch(/cellEnd/)
+ })
+
+ test('end-aligns the injected actions column so the row menu stays flush-right', () => {
+ renderTable({
+ columns: [{ key: 'name', title: 'Name', render: item => item.name }],
+ itemMenu: item => ,
+ })
+
+ expect(screen.getByText('Menu for Alice').closest('div')?.className).toMatch(/cellEnd/)
+ })
})
describe('accessibility', () => {
diff --git a/src/components/Common/DataView/DataTable/DataTable.tsx b/src/components/Common/DataView/DataTable/DataTable.tsx
index 37d7df6668..00e59e654c 100644
--- a/src/components/Common/DataView/DataTable/DataTable.tsx
+++ b/src/components/Common/DataView/DataTable/DataTable.tsx
@@ -116,7 +116,10 @@ export const DataTable = ({
? [
{
key: 'actions-header',
- content: {t('table.actionsColumnHeader')},
+ content: withJustify(
+ {t('table.actionsColumnHeader')},
+ 'end',
+ ),
},
]
: []),
@@ -176,7 +179,7 @@ export const DataTable = ({
? [
{
key: `menu-${rowIndex}`,
- content: itemMenu(item),
+ content: withJustify(itemMenu(item), 'end'),
},
]
: []),
diff --git a/src/components/Common/DataView/DataView.stories.tsx b/src/components/Common/DataView/DataView.stories.tsx
index 35650cd9c7..4aebadaded 100644
--- a/src/components/Common/DataView/DataView.stories.tsx
+++ b/src/components/Common/DataView/DataView.stories.tsx
@@ -373,3 +373,22 @@ export const DataViewWithFooter = () => {
return
}
+
+// Alignment is driven entirely by column.justify: the numeric "Amount" column
+// right-aligns (header, body, and footer), while text columns stay left. The
+// injected row-menu column is always flush-right.
+export const DataViewWithJustifiedColumns = () => {
+ const justifiedColumns: useDataViewProp['columns'] = [
+ { key: 'jobTitle', title: 'Job Title' },
+ { key: 'payType', title: 'Pay Type' },
+ { key: 'amount', title: 'Amount', justify: 'end' },
+ { key: 'payTimePeriod', title: 'Pay Time Period' },
+ ]
+ const dataProps = useDataView({
+ data: compensationData,
+ columns: justifiedColumns,
+ itemMenu: renderItemMenu,
+ footer: () => ({ jobTitle: 'Total', amount: '$1,050.15' }),
+ })
+ return
+}
diff --git a/src/components/Common/UI/Table/Table.module.scss b/src/components/Common/UI/Table/Table.module.scss
index b1993314d7..6c9bc554d8 100644
--- a/src/components/Common/UI/Table/Table.module.scss
+++ b/src/components/Common/UI/Table/Table.module.scss
@@ -106,13 +106,6 @@
outline: var(--g-focusRingWidth) solid var(--g-focusRingColor);
outline-offset: -2px;
}
- &:last-child {
- text-align: right;
-
- :global(.react-aria-Button) {
- display: inline-flex;
- }
- }
// Empty state row styling
:global(.react-aria-Row[data-empty-state='true']) & {
diff --git a/src/components/Company/StateTaxes/TaxRateManagement/TaxRateHistorySection.tsx b/src/components/Company/StateTaxes/TaxRateManagement/TaxRateHistorySection.tsx
index f6f3f36c98..1e47f08ed2 100644
--- a/src/components/Company/StateTaxes/TaxRateManagement/TaxRateHistorySection.tsx
+++ b/src/components/Company/StateTaxes/TaxRateManagement/TaxRateHistorySection.tsx
@@ -68,6 +68,7 @@ export function TaxRateHistorySection({ group, showHeader = true }: TaxRateHisto
...requirementColumns.map(column => ({
key: column.key,
title: column.label ?? column.key,
+ justify: 'end' as const,
render: (row: HistoryRow) => row.values[column.key] ?? '',
})),
],
diff --git a/src/components/Contractor/Payments/PaymentStatement/PaymentStatementPresentation.tsx b/src/components/Contractor/Payments/PaymentStatement/PaymentStatementPresentation.tsx
index df3cb4198a..ed6a6d8dd7 100644
--- a/src/components/Contractor/Payments/PaymentStatement/PaymentStatementPresentation.tsx
+++ b/src/components/Contractor/Payments/PaymentStatement/PaymentStatementPresentation.tsx
@@ -190,6 +190,7 @@ export const PaymentStatementPresentation = ({
},
{
title: t('amountColumn'),
+ justify: 'end',
render: ({ amount }) => amount || '',
},
]}
diff --git a/src/components/Employee/Compensation/onboarding/JobsList/JobsListPresentation.tsx b/src/components/Employee/Compensation/onboarding/JobsList/JobsListPresentation.tsx
index 2cd6fd3730..2dfee1602f 100644
--- a/src/components/Employee/Compensation/onboarding/JobsList/JobsListPresentation.tsx
+++ b/src/components/Employee/Compensation/onboarding/JobsList/JobsListPresentation.tsx
@@ -66,6 +66,7 @@ export function JobsListPresentation({
{
key: 'rate',
title: t('allCompensations.amountColumn'),
+ justify: 'end',
render: (job: Job) => job.rate?.toString() || '',
},
{
diff --git a/src/components/Employee/Deductions/management/DeductionsCard/DeductionsCard.tsx b/src/components/Employee/Deductions/management/DeductionsCard/DeductionsCard.tsx
index 634309cc10..85766f20cb 100644
--- a/src/components/Employee/Deductions/management/DeductionsCard/DeductionsCard.tsx
+++ b/src/components/Employee/Deductions/management/DeductionsCard/DeductionsCard.tsx
@@ -113,6 +113,7 @@ function DeductionsCardContent({ employeeId, onEvent, LoaderComponent }: Deducti
{
key: 'amount',
title: t('columns.withhold'),
+ justify: 'end' as const,
render: (garnishment: Garnishment) =>
formatDeductionAmount(garnishment, {
formatCurrency,
diff --git a/src/components/Employee/Deductions/onboarding/DeductionsList/DeductionsList.tsx b/src/components/Employee/Deductions/onboarding/DeductionsList/DeductionsList.tsx
index d38d9210dd..3065bde654 100644
--- a/src/components/Employee/Deductions/onboarding/DeductionsList/DeductionsList.tsx
+++ b/src/components/Employee/Deductions/onboarding/DeductionsList/DeductionsList.tsx
@@ -60,6 +60,7 @@ export function DeductionsList({
{
key: 'amount',
title: t('withheldColumn'),
+ justify: 'end',
render: deduction =>
formatDeductionAmount(deduction, {
formatCurrency,
diff --git a/src/components/Employee/PaymentMethod/onboarding/ListView.tsx b/src/components/Employee/PaymentMethod/onboarding/ListView.tsx
index 59ddea2965..6fbce40915 100644
--- a/src/components/Employee/PaymentMethod/onboarding/ListView.tsx
+++ b/src/components/Employee/PaymentMethod/onboarding/ListView.tsx
@@ -110,6 +110,7 @@ function ListViewReady({
{
key: 'splitAmount',
title: t('allocationColumn'),
+ justify: 'end',
render: bankAccount => {
const splitAmount =
paymentMethod.splits?.find(split => split.uuid === bankAccount.uuid)?.splitAmount ?? 0
diff --git a/src/components/Employee/Paystubs/management/PaystubsCard/PaystubsCard.tsx b/src/components/Employee/Paystubs/management/PaystubsCard/PaystubsCard.tsx
index 72288c4034..1be9849100 100644
--- a/src/components/Employee/Paystubs/management/PaystubsCard/PaystubsCard.tsx
+++ b/src/components/Employee/Paystubs/management/PaystubsCard/PaystubsCard.tsx
@@ -199,6 +199,7 @@ function PaystubsCardReady({
{
key: 'checkAmount',
title: t('checkAmount'),
+ justify: 'end' as const,
render: (payStub: EmployeePayStub) => {
if (!payStub.netPay) return '-'
const amount = parseFloat(payStub.netPay)
@@ -208,6 +209,7 @@ function PaystubsCardReady({
{
key: 'grossPay',
title: t('grossPay'),
+ justify: 'end' as const,
render: (payStub: EmployeePayStub) => {
if (!payStub.grossPay) return '-'
const amount = parseFloat(payStub.grossPay)
diff --git a/src/components/Payroll/OffCycleTaxWithholdingTable/OffCycleTaxWithholdingTable.module.scss b/src/components/Payroll/OffCycleTaxWithholdingTable/OffCycleTaxWithholdingTable.module.scss
index 32280b229f..35a54a8f0f 100644
--- a/src/components/Payroll/OffCycleTaxWithholdingTable/OffCycleTaxWithholdingTable.module.scss
+++ b/src/components/Payroll/OffCycleTaxWithholdingTable/OffCycleTaxWithholdingTable.module.scss
@@ -32,10 +32,6 @@
:global(.react-aria-Cell) {
width: 50%;
text-align: left;
-
- &:last-child {
- text-align: left;
- }
}
}
}
diff --git a/src/components/Payroll/PayrollConfiguration/PayrollConfigurationPresentation.tsx b/src/components/Payroll/PayrollConfiguration/PayrollConfigurationPresentation.tsx
index e66383f03e..1660fa34c5 100644
--- a/src/components/Payroll/PayrollConfiguration/PayrollConfigurationPresentation.tsx
+++ b/src/components/Payroll/PayrollConfiguration/PayrollConfigurationPresentation.tsx
@@ -216,6 +216,7 @@ export const PayrollConfigurationPresentation = ({
},
{
title: t('tableColumns.hours'),
+ justify: 'end',
render: (item: PayrollEmployeeCompensationsType) => {
const hours = getRegularHours(item)
const overtimeHours = getOvertimeHours(item)
@@ -224,6 +225,7 @@ export const PayrollConfigurationPresentation = ({
},
{
title: t('tableColumns.timeOff'),
+ justify: 'end',
render: (item: PayrollEmployeeCompensationsType) => {
const ptoHours = getTotalPtoHours(item)
return formatHoursDisplay(ptoHours)
@@ -231,6 +233,7 @@ export const PayrollConfigurationPresentation = ({
},
{
title: t('tableColumns.additionalEarnings'),
+ justify: 'end',
render: (item: PayrollEmployeeCompensationsType) => {
const earnings = getAdditionalEarnings(item)
return formatNumberAsCurrency(earnings)
@@ -240,6 +243,7 @@ export const PayrollConfigurationPresentation = ({
? [
{
title: t('tableColumns.reimbursements'),
+ justify: 'end' as const,
render: (item: PayrollEmployeeCompensationsType) => {
const reimbursements = getReimbursements(item)
return formatNumberAsCurrency(reimbursements)
@@ -249,6 +253,7 @@ export const PayrollConfigurationPresentation = ({
: []),
{
title: t('tableColumns.totalPay'),
+ justify: 'end',
render: (item: PayrollEmployeeCompensationsType) => {
const employee = employeeMap.get(item.employeeUuid || '')
const calculatedGrossPay = employee
diff --git a/src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.tsx b/src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.tsx
index 064101b4df..8d156ec5a9 100644
--- a/src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.tsx
+++ b/src/components/Payroll/PayrollEditEmployee/PayrollEditEmployeePresentation.tsx
@@ -450,6 +450,7 @@ export const PayrollEditEmployeePresentation = ({
{
key: 'amount',
title: t('reimbursementAmountColumn'),
+ justify: 'end',
render: row => formatNumberAsCurrency(parseFloat(row.amount || '0')),
},
{
diff --git a/src/components/Payroll/PayrollHistory/PayrollHistoryPresentation.tsx b/src/components/Payroll/PayrollHistory/PayrollHistoryPresentation.tsx
index 7444fa13bd..5e6cdb7e5f 100644
--- a/src/components/Payroll/PayrollHistory/PayrollHistoryPresentation.tsx
+++ b/src/components/Payroll/PayrollHistory/PayrollHistoryPresentation.tsx
@@ -187,6 +187,7 @@ export const PayrollHistoryPresentation = ({
},
{
title: t('columns.totalPayroll'),
+ justify: 'end',
render: (item: Payroll) => formatNumberAsCurrency(calculateTotalPayroll(item)),
},
]}
diff --git a/src/components/Payroll/PayrollOverview/PayrollOverviewPresentation.tsx b/src/components/Payroll/PayrollOverview/PayrollOverviewPresentation.tsx
index 94c2880c97..d6d20401b3 100644
--- a/src/components/Payroll/PayrollOverview/PayrollOverviewPresentation.tsx
+++ b/src/components/Payroll/PayrollOverview/PayrollOverviewPresentation.tsx
@@ -218,6 +218,7 @@ export const PayrollOverviewPresentation = ({
const companyPaysColumns: Array<{
key: string
title: string
+ justify?: 'start' | 'end'
render: (item: EmployeeCompensations) => React.ReactNode
}> = [
{
@@ -236,6 +237,7 @@ export const PayrollOverviewPresentation = ({
{
key: 'grossPay',
title: t('tableHeaders.grossPay'),
+ justify: 'end',
render: (employeeCompensations: EmployeeCompensations) =>
formatCurrency(Number(employeeCompensations.grossPay!)),
},
@@ -244,6 +246,7 @@ export const PayrollOverviewPresentation = ({
{
key: 'reimbursements',
title: t('tableHeaders.reimbursements'),
+ justify: 'end' as const,
render: (employeeCompensation: EmployeeCompensations) =>
formatCurrency(getReimbursements(employeeCompensation)),
},
@@ -252,18 +255,21 @@ export const PayrollOverviewPresentation = ({
{
key: 'companyTaxes',
title: t('tableHeaders.companyTaxes'),
+ justify: 'end',
render: (employeeCompensation: EmployeeCompensations) =>
formatCurrency(getCompanyTaxes(employeeCompensation)),
},
{
key: 'companyBenefits',
title: t('tableHeaders.companyBenefits'),
+ justify: 'end',
render: (employeeCompensation: EmployeeCompensations) =>
formatCurrency(getCompanyBenefits(employeeCompensation)),
},
{
key: 'companyPays',
title: t('tableHeaders.companyPays'),
+ justify: 'end',
render: (employeeCompensation: EmployeeCompensations) =>
formatCurrency(getCompanyCost(employeeCompensation)),
},
diff --git a/src/components/Payroll/PayrollReceipts/PayrollReceiptsPresentation.tsx b/src/components/Payroll/PayrollReceipts/PayrollReceiptsPresentation.tsx
index 3a460edf56..78e7286074 100644
--- a/src/components/Payroll/PayrollReceipts/PayrollReceiptsPresentation.tsx
+++ b/src/components/Payroll/PayrollReceipts/PayrollReceiptsPresentation.tsx
@@ -180,6 +180,7 @@ export const PayrollReceiptsPresentation = ({
},
{
title: t('breakdown.amount'),
+ justify: 'end',
render: (item: { label: string; amount: number }) =>
formatNumberAsCurrency(item.amount),
},
@@ -204,6 +205,7 @@ export const PayrollReceiptsPresentation = ({
},
{
title: t('tax.amount'),
+ justify: 'end',
render: (tax: TaxBreakdownItem) =>
formatNumberAsCurrency(parseFloat(tax.amount || '0')),
},
@@ -259,6 +261,7 @@ export const PayrollReceiptsPresentation = ({
},
{
title: t('employee.childSupport'),
+ justify: 'end',
render: (employee: EmployeeBreakdownItem) =>
formatNumberAsCurrency(parseFloat(employee.childSupportGarnishment || '0')),
},
@@ -266,6 +269,7 @@ export const PayrollReceiptsPresentation = ({
? [
{
title: t('employee.reimbursement'),
+ justify: 'end' as const,
render: (employee: EmployeeBreakdownItem) =>
formatNumberAsCurrency(parseFloat(employee.totalReimbursement || '0')),
},
@@ -273,11 +277,13 @@ export const PayrollReceiptsPresentation = ({
: []),
{
title: t('employee.totalTaxes'),
+ justify: 'end',
render: (employee: EmployeeBreakdownItem) =>
formatNumberAsCurrency(parseFloat(employee.totalTax || '0')),
},
{
title: t('employee.netPay'),
+ justify: 'end',
render: (employee: EmployeeBreakdownItem) =>
formatNumberAsCurrency(parseFloat(employee.netPay || '0')),
},
diff --git a/src/components/Payroll/RecoveryCases/RecoveryCasesList/RecoveryCasesList.tsx b/src/components/Payroll/RecoveryCases/RecoveryCasesList/RecoveryCasesList.tsx
index b1352d7368..e88ebac8b7 100644
--- a/src/components/Payroll/RecoveryCases/RecoveryCasesList/RecoveryCasesList.tsx
+++ b/src/components/Payroll/RecoveryCases/RecoveryCasesList/RecoveryCasesList.tsx
@@ -132,6 +132,7 @@ function Root({ companyId, dictionary, onEvent }: RecoveryCasesListProps) {
{
key: 'totalAmount',
title: t('columns.totalAmount'),
+ justify: 'end',
render: recoveryCase => (
{recoveryCase.eventTotalAmount
@@ -143,6 +144,7 @@ function Root({ companyId, dictionary, onEvent }: RecoveryCasesListProps) {
{
key: 'amountOutstanding',
title: t('columns.amountOutstanding'),
+ justify: 'end',
render: recoveryCase => (
{recoveryCase.amountOutstanding
diff --git a/src/components/TimeOff/shared/EmployeeTable/EmployeeTable.module.scss b/src/components/TimeOff/shared/EmployeeTable/EmployeeTable.module.scss
index c3425c61a6..9b2d5d1ab4 100644
--- a/src/components/TimeOff/shared/EmployeeTable/EmployeeTable.module.scss
+++ b/src/components/TimeOff/shared/EmployeeTable/EmployeeTable.module.scss
@@ -3,15 +3,6 @@
display: flex;
flex-direction: column;
gap: toRem(16);
-
- &:not([data-has-menu]) {
- :global(.react-aria-Cell),
- :global(.react-aria-Column) {
- &:last-child {
- text-align: left;
- }
- }
- }
}
.searchContainer {
diff --git a/src/components/TimeOff/shared/EmployeeTable/EmployeeTable.tsx b/src/components/TimeOff/shared/EmployeeTable/EmployeeTable.tsx
index 871b6b8b6b..03a771606c 100644
--- a/src/components/TimeOff/shared/EmployeeTable/EmployeeTable.tsx
+++ b/src/components/TimeOff/shared/EmployeeTable/EmployeeTable.tsx
@@ -100,7 +100,7 @@ export function EmployeeTable({
} as useDataViewProp)
return (
-