Components
Button
The AntD Button in house dress — .btn-ant-primary paints Save/primary actions with the 310deg navy gradient, .opacity-8 dims Cancel, and every button is fixed at 30px tall by the global .ant-btn rule.
Variants
Six recurring shapes. Every button is 30px tall — each module’s App.css pins .ant-btn { height: 30px !important }, so AntD’s size prop changes padding and font, never height. Button label text uses font-size-13.
// Primary / Save — the house gradient. Always pair type="primary" with the class.
<Button type="primary" className="btn-ant-primary">Save</Button>
// Cancel / secondary — default type, dimmed to 80%.
<Button className="opacity-8">Cancel</Button>
// Plain default (bordered).
<Button>Default</Button>
// Ghost secondary — outlined, secondary colour. Used for actions like "Add Step".
<Button type="primary" ghost>Add Step</Button>
// Small icon-only — renders 28×28 in the MFEs via .ant-btn-sm.ant-btn-icon-only.
<Button size="small" type="primary" ghost icon={<PlusOutlined />} aria-label="Add" />
// Disabled — inherited from AntD.
<Button disabled>Disabled</Button>Loading state
Async Save buttons pass loading={isLoading} so the spinner replaces double-submits. Click Save below to see the production behaviour.
<Button loading={isLoading} htmlType="submit" className="btn-ant-primary text-white font-size-13">
Save
</Button>Markup
The canonical Save/Cancel pair — always rendered inside the sticky AppFormFooter (see Patterns → Form footer).
/* React (rate-fe, reference-fe, racar-fe, header-fe, authentication-fe) */
import { Button } from 'antd';
import AppFormFooter from '@/components/common/AppFormFooter';
// In form component:
<AppFormFooter>
<Button
loading={isLoading}
htmlType="submit"
size="middle"
className="btn-ant-primary text-white font-size-13"
>
Save
</Button>
<Button
size="middle"
onClick={handleCancel}
className="font-size-13 opacity-8"
>
Cancel
</Button>
</AppFormFooter>SCSS
The gradient lives once in @rvn/shared-styles (raffles-antd.scss); the 30px height override is repeated in each module’s App.css.
/* PRIMARY BUTTON (Save/Submit) — Gradient style from shared-styles */
.btn-ant-primary {
background-image: linear-gradient(310deg, $secondary 0%, $primary 100%);
&:hover {
background: linear-gradient(310deg, $primary 0%, $secondary 100%) !important;
background-color: linear-gradient(310deg, $primary 0%, $secondary 100%) !important;
}
}
/* SECONDARY ACTION (Cancel/Default) — Dimmed to 80% opacity */
.opacity-8 {
opacity: 0.8 !important;
}
/* Base AntD button height override — applied across all modules */
.ant-btn {
height: 30px !important;
}
/* Color variables from shared-styles (raffles-antd.scss) */
$primary: #003087 !default;
$secondary: #1351a8 !default;Classes
| Name | Type | Default | Description |
|---|---|---|---|
btn-ant-primary | class | — | Navy→blue gradient fill (310deg, #1351a8 → #003087) with white text; hover swaps the stops. For Save/Submit — pair with type="primary". |
opacity-8 | class | — | Dims Cancel/secondary buttons to 80%. The !important means it also holds on hover — no lightening. |
font-size-13 | class | — | The house 13px button-label size. Applied to both Save and Cancel. |
btn-none-border | class | — | Strips border and box-shadow for text-like buttons inside toolbars and table cells. |
Notes
.ant-btn is forced to 30px in every module. The one exception: small icon-only buttons (.ant-btn-sm.ant-btn-icon-only) are 28×28px, with margin-top: -5px on the child span to re-centre the icon vertically.$primary → $secondary) for the swap effect. Primary #003087 is navy, secondary #1351a8 is blue.For modal confirmations, pass the class through the OK-button props instead of re-rendering your own footer:
<!-- Usage in modal confirm buttons -->
<Modal
:ok-button-props="{ class: 'btn-ant-primary' }"
@ok="handleSubmit"
>
Modal content...
</Modal>#074382 via .login-btn-primary on the login page only. Do not copy it elsewhere.