Waldur HomePort UI/UX consistency patterns and design system rules...
Ensures consistent, accessible UI across Waldur HomePort.
// ALWAYS use renderFieldOrDash - never || 'N/A' or || ''
import { renderFieldOrDash } from '@/table/utils';
{renderFieldOrDash(value)}
// ALWAYS provide a reason explaining WHY disabled — prefer BaseButton's own
// disabledReason prop over wrapping it in a separate Tooltip
<BaseButton
disabled={disabled}
disabledReason={disabled ? translate('Resource must be in OK state') : undefined}
label={translate('Action')}
/>
// ALWAYS use NoResult with actionable CTA
<NoResult
title={translate('No projects yet')}
message={translate('Create your first project.')}
actions={<CreateButton />}
/>
// Use solid color tokens - NEVER opacity
className={isDisabled ? 'text-muted' : ''} // correct
className={isDisabled ? 'opacity-50' : ''} // wrong
Hide vs Disable Button?
Which Empty State?
For full patterns, examples, and anti-patterns: docs/ui-consistency-guidelines.md
Sections include:
Before completing UI work, verify:
renderFieldOrDash()NoResult with CTAopacity-50 for disabled states (use text-muted)hasPermission() utilityimport { NoResult } from '@/navigation/header/search/NoResult';
import { renderFieldOrDash } from '@/table/utils';
import { BaseButton, Tooltip } from 'waldur-ui';
import { hasPermission } from '@/permissions/hasPermission';
import { StateIndicator } from '@/core/StateIndicator';
import { LoadingErred } from '@/core/LoadingErred';