RTL is used for displaying languages that go from Right to Left, eg Hebrew and Arabic. To get AG Grid to display in RTL format, set the property enableRtl=true.
RTL Example Copy Link
Below shows a grid in RTL mode. Use the language selector to switch between Arabic, Hebrew and English to see how the grid adapts to different RTL languages.
import {
AG_GRID_LOCALE_EG,
AG_GRID_LOCALE_IL,
} from "@ag-grid-community/locale";
import { computed, createApp, defineComponent, ref } from "vue";
import type { ColDef } from "ag-grid-community";
import {
ClientSideRowModelModule,
LocaleModule,
ModuleRegistry,
NumberEditorModule,
NumberFilterModule,
TextEditorModule,
TextFilterModule,
enableDevValidations,
} from "ag-grid-community";
import { AgGridVue } from "ag-grid-vue3";
import "./styles.css";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
ModuleRegistry.registerModules([
NumberEditorModule,
TextEditorModule,
TextFilterModule,
NumberFilterModule,
ClientSideRowModelModule,
LocaleModule,
]);
type Language = "arabic" | "hebrew" | "english";
interface LanguageConfig {
localeText: Record<string, string> | undefined;
enableRtl: boolean;
columnDefs: ColDef[];
rowData: Record<string, any>[];
}
const LANGUAGES: Record<Language, LanguageConfig> = {
arabic: {
localeText: AG_GRID_LOCALE_EG,
enableRtl: true,
columnDefs: [
{ field: "city", headerName: "المدينة" },
{ field: "country", headerName: "البلد" },
{ field: "population", headerName: "عدد السكان" },
{ field: "area", headerName: "المساحة (كم²)" },
],
rowData: [
{ city: "القاهرة", country: "مصر", population: 21_323_000, area: 3_085 },
{
city: "الرياض",
country: "السعودية",
population: 7_677_000,
area: 1_798,
},
{ city: "دبي", country: "الإمارات", population: 3_564_000, area: 1_588 },
{
city: "الدار البيضاء",
country: "المغرب",
population: 3_752_000,
area: 384,
},
{ city: "بغداد", country: "العراق", population: 8_126_000, area: 673 },
{ city: "الجزائر", country: "الجزائر", population: 3_915_000, area: 363 },
{ city: "عمّان", country: "الأردن", population: 4_008_000, area: 1_680 },
{ city: "تونس", country: "تونس", population: 2_365_000, area: 212 },
{ city: "بيروت", country: "لبنان", population: 2_434_000, area: 67 },
{ city: "الكويت", country: "الكويت", population: 2_989_000, area: 200 },
],
},
hebrew: {
localeText: AG_GRID_LOCALE_IL,
enableRtl: true,
columnDefs: [
{ field: "city", headerName: "עיר" },
{ field: "country", headerName: "מדינה" },
{ field: "population", headerName: "אוכלוסייה" },
{ field: "area", headerName: "שטח (קמ״ר)" },
],
rowData: [
{ city: "ירושלים", country: "ישראל", population: 982_000, area: 126 },
{ city: "תל אביב", country: "ישראל", population: 467_000, area: 52 },
{ city: "חיפה", country: "ישראל", population: 285_000, area: 64 },
{ city: "ראשון לציון", country: "ישראל", population: 254_000, area: 59 },
{ city: "פתח תקווה", country: "ישראל", population: 247_000, area: 36 },
{ city: "אשדוד", country: "ישראל", population: 226_000, area: 47 },
{ city: "נתניה", country: "ישראל", population: 221_000, area: 29 },
{ city: "באר שבע", country: "ישראל", population: 210_000, area: 117 },
{ city: "חולון", country: "ישראל", population: 196_000, area: 19 },
{ city: "בני ברק", country: "ישראל", population: 204_000, area: 7 },
],
},
english: {
localeText: undefined,
enableRtl: false,
columnDefs: [
{ field: "city", headerName: "City" },
{ field: "country", headerName: "Country" },
{ field: "population", headerName: "Population" },
{ field: "area", headerName: "Area (km²)" },
],
rowData: [
{
city: "London",
country: "United Kingdom",
population: 9_541_000,
area: 1_572,
},
{
city: "New York",
country: "United States",
population: 8_336_000,
area: 783,
},
{
city: "Sydney",
country: "Australia",
population: 5_312_000,
area: 12_368,
},
{ city: "Toronto", country: "Canada", population: 2_794_000, area: 630 },
{ city: "Dublin", country: "Ireland", population: 1_263_000, area: 115 },
{
city: "Cape Town",
country: "South Africa",
population: 4_618_000,
area: 2_461,
},
{
city: "Singapore",
country: "Singapore",
population: 5_917_000,
area: 733,
},
{
city: "Auckland",
country: "New Zealand",
population: 1_657_000,
area: 1_086,
},
{ city: "Mumbai", country: "India", population: 21_297_000, area: 603 },
{ city: "Nairobi", country: "Kenya", population: 4_922_000, area: 696 },
],
},
};
const VueExample = defineComponent({
template: `
<div class="example-wrapper">
<div style="margin-bottom: 0.5rem; display: flex; gap: 0.5rem; align-items: center;">
<label for="language">Language:</label>
<select id="language" v-on:change="onLanguageChange($event)">
<option value="arabic" selected>العربية (Arabic)</option>
<option value="hebrew">עברית (Hebrew)</option>
<option value="english">English</option>
</select>
</div>
<ag-grid-vue
v-if="gridVisible"
style="width: 100%; height: 100%;"
:enableRtl="enableRtl"
:columnDefs="columnDefs"
:rowData="rowData"
:localeText="localeText"
:defaultColDef="defaultColDef"
></ag-grid-vue>
</div>
`,
components: {
"ag-grid-vue": AgGridVue,
},
setup() {
const language = ref<Language>("arabic");
const gridVisible = ref(true);
const defaultColDef = ref<ColDef>({
editable: true,
flex: 1,
minWidth: 100,
filter: true,
});
const columnDefs = computed(() => LANGUAGES[language.value].columnDefs);
const rowData = computed(() => LANGUAGES[language.value].rowData);
const enableRtl = computed(() => LANGUAGES[language.value].enableRtl);
const localeText = computed(() => LANGUAGES[language.value].localeText);
// enableRtl is an initial-only option, so switching language recreates the grid.
const onLanguageChange = (event: Event) => {
const next = (event.target as HTMLSelectElement).value as Language;
gridVisible.value = false;
language.value = next;
setTimeout(() => {
gridVisible.value = true;
});
};
return {
gridVisible,
defaultColDef,
columnDefs,
rowData,
enableRtl,
localeText,
onLanguageChange,
};
},
});
createApp(VueExample).mount("#app");
.example-wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
#myGrid {
flex: 1 1 0px;
width: 100%;
}
Complex Example Copy Link
Below shows a more complex example with the tool panel and pinned areas visible to demonstrate edge cases of RTL. This example uses AG Grid Enterprise, so the tool panel and context menus are active. Use the language selector to switch between RTL languages.
import { AgChartsEnterpriseModule } from "ag-charts-enterprise";
import { createApp, defineComponent, ref, watch } from "vue";
import type {
CellClassParams,
CellStyle,
ColDef,
ColGroupDef,
DefaultMenuItem,
GetContextMenuItemsParams,
ICellRendererParams,
IRowNode,
MenuItemDef,
RowSelectedEvent,
RowSelectionOptions,
SelectionChangedEvent,
ValueSetterParams,
} from "ag-grid-community";
import {
LocaleModule,
ModuleRegistry,
enableDevValidations,
} from "ag-grid-community";
import { AllEnterpriseModule } from "ag-grid-enterprise";
import { AgGridVue } from "ag-grid-vue3";
import CountryCellRenderer from "./countryCellRenderer";
import { COUNTRY_CODES, LANGUAGES, createRowData } from "./data";
import type { LanguageConfig } from "./data";
import "./styles.css";
if (process.env.NODE_ENV !== "production") {
// Enable extended validations only for development
enableDevValidations();
}
ModuleRegistry.registerModules([
AllEnterpriseModule.with(AgChartsEnterpriseModule),
LocaleModule,
]);
const dataSize: string = ".1x22";
// `enableRtl` and `localeText` are initial-only grid options, so switching language rebuilds every language
// dependent grid prop against `currentLang` and remounts the grid (see the `gridVisible` toggle below).
let currentLang: LanguageConfig = LANGUAGES["arabic"];
function getAutoGroupColumnDef(): ColDef {
return {
headerName: currentLang.headers.group,
width: 200,
field: "name",
valueGetter: (params) => {
if (params.node && params.node.group) {
return params.node.key;
} else {
return params.data[params.colDef.field!];
}
},
cellRenderer: "agGroupCellRenderer",
};
}
function getContextMenuItems(
params: GetContextMenuItemsParams,
): (DefaultMenuItem | MenuItemDef)[] {
const result: (DefaultMenuItem | MenuItemDef)[] =
params.defaultItems!.splice(0);
result.push({
name: currentLang.contextMenu.customMenuItem,
icon: '<img src="https://www.ag-grid.com/example-assets/lab.png" style="width: 14px;" />',
action: () => {
const value = params.value ? params.value : "<empty>";
console.log("You clicked a custom menu item on cell " + value);
},
});
return result;
}
function createDefaultCols(): (ColDef | ColGroupDef)[] {
const firstColumn: ColDef = {
headerName: currentLang.headers.name,
field: "name",
width: 200,
editable: true,
enableRowGroup: true,
icons: {
sortAscending: '<i class="fa fa-sort-alpha-up"/>',
sortDescending: '<i class="fa fa-sort-alpha-down"/>',
},
};
const cols: (ColDef | ColGroupDef)[] = [
{
headerName: currentLang.headers.participant,
children: [
firstColumn,
{
headerName: currentLang.headers.language,
field: "language",
width: 150,
editable: true,
filter: "agSetColumnFilter",
cellRenderer: languageCellRenderer,
cellEditor: "agSelectCellEditor",
enableRowGroup: true,
enablePivot: true,
cellEditorParams: {
values: currentLang.editorLanguages,
},
pinned: "right",
headerTooltip: currentLang.headers.languageTooltip,
},
{
headerName: currentLang.headers.country,
field: "country",
width: 150,
editable: true,
cellRenderer: "CountryCellRenderer",
enableRowGroup: true,
enablePivot: true,
cellEditor: "agRichSelectCellEditor",
cellEditorParams: {
cellRenderer: "CountryCellRenderer",
values: currentLang.editorCountries,
},
filterParams: {
cellRenderer: "CountryCellRenderer",
},
},
],
},
{
headerName: currentLang.headers.gameOfChoice,
children: [
{
headerName: currentLang.headers.gameName,
field: "game.name",
width: 180,
editable: true,
filter: "agSetColumnFilter",
tooltip: true,
cellClass: () => {
return "alphabet";
},
enableRowGroup: true,
enablePivot: true,
pinned: "left",
icons: {
sortAscending: '<i class="fa fa-sort-alpha-up"/>',
sortDescending: '<i class="fa fa-sort-alpha-down"/>',
},
},
{
headerName: currentLang.headers.bought,
field: "game.bought",
filter: "agSetColumnFilter",
editable: true,
width: 100,
enableRowGroup: true,
enablePivot: true,
enableValue: true,
cellRenderer: booleanCellRenderer,
cellStyle: { "text-align": "center" },
comparator: booleanComparator,
filterParams: { cellRenderer: booleanFilterCellRenderer },
},
],
},
{
groupId: "performance",
children: [
{
headerName: currentLang.headers.bankBalance,
field: "bankBalance",
width: 150,
editable: true,
cellRenderer: currencyRenderer,
cellStyle: currencyCssFunc,
filter: "agNumberColumnFilter",
enableValue: true,
icons: {
sortAscending: '<i class="fa fa-sort-amount-up"/>',
sortDescending: '<i class="fa fa-sort-amount-down"/>',
},
},
{
headerName: currentLang.headers.extraInfo1,
columnGroupShow: "open",
width: 150,
editable: false,
sortable: false,
suppressHeaderMenuButton: true,
cellStyle: { "text-align": "right" },
cellRenderer: () => {
return currentLang.cellContent.abra;
},
},
{
headerName: currentLang.headers.extraInfo2,
columnGroupShow: "open",
width: 150,
editable: false,
sortable: false,
suppressHeaderMenuButton: true,
cellStyle: { "text-align": "left" },
cellRenderer: () => {
return currentLang.cellContent.cadabra;
},
},
],
},
{
headerName: currentLang.headers.rating,
field: "rating",
width: 100,
editable: true,
cellRenderer: ratingRenderer,
enableRowGroup: true,
enablePivot: true,
enableValue: true,
filterParams: { cellRenderer: ratingFilterRenderer },
},
{
headerName: currentLang.headers.totalWinnings,
field: "totalWinnings",
filter: "agNumberColumnFilter",
editable: true,
valueSetter: numberValueSetter,
width: 150,
enableValue: true,
cellRenderer: currencyRenderer,
cellStyle: currencyCssFunc,
icons: {
sortAscending: '<i class="fa fa-sort-amount-up"/>',
sortDescending: '<i class="fa fa-sort-amount-down"/>',
},
},
];
const monthGroup: ColGroupDef = {
headerName: currentLang.headers.monthlyBreakdown,
children: [],
};
cols.push(monthGroup);
for (let i = 0, len = currentLang.months.length; i < len; ++i) {
const month = currentLang.months[i];
const child: ColDef = {
headerName: month,
field: "month_" + i,
width: 100,
filter: "agNumberColumnFilter",
editable: true,
enableValue: true,
cellClassRules: {
"good-score": 'typeof x === "number" && x > 50000',
"bad-score": 'typeof x === "number" && x < 10000',
},
valueSetter: numberValueSetter,
cellRenderer: currencyRenderer,
cellStyle: { "text-align": "right" },
};
monthGroup.children.push(child);
}
return cols;
}
function getColCount() {
switch (dataSize) {
case "10x100":
return 100;
default:
return 22;
}
}
function createCols() {
const colCount = getColCount();
const defaultCols = createDefaultCols();
const columns = defaultCols.slice(0, colCount);
for (let col = 22; col < colCount; col++) {
const colName = currentLang.colNames[col % currentLang.colNames.length];
const colDef = {
headerName: colName,
field: "col" + col,
width: 200,
editable: true,
};
columns.push(colDef);
}
return columns;
}
function selectionChanged(event: SelectionChangedEvent) {
console.log(
"Callback selectionChanged: selection count = " +
event.selectedNodes?.length,
);
}
function rowSelected(event: RowSelectedEvent) {
// the number of rows selected could be huge, if the user is grouping and selects a group, so
// to stop the console from clogging up, we only print if in the first 10 (by chance we know
// the node id's are assigned from 0 upwards)
if (Number(event.node.id) < 10) {
const valueToPrint = event.node.group
? "group (" + event.node.key + ")"
: event.node.data.name;
console.log("Callback rowSelected: " + valueToPrint);
}
}
function numberValueSetter(params: ValueSetterParams) {
const newValue = params.newValue;
let valueAsNumber;
if (newValue === null || newValue === undefined || newValue === "") {
valueAsNumber = null;
} else {
valueAsNumber = parseFloat(params.newValue);
}
const field = params.colDef.field!;
const data = params.data;
data[field] = valueAsNumber;
return true;
}
function currencyCssFunc(params: CellClassParams): CellStyle {
if (params.value !== null && params.value !== undefined && params.value < 0) {
return { color: "red", "text-align": "right", "font-weight": "bold" };
} else {
return { "text-align": "right" };
}
}
function ratingFilterRenderer(params: ICellRendererParams) {
return ratingRendererGeneral(params.value, true);
}
function ratingRenderer(params: ICellRendererParams) {
return ratingRendererGeneral(params.value, false);
}
function ratingRendererGeneral(value: any, forFilter: boolean) {
if (value === "(Select All)") {
return value;
}
let result = "<span>";
for (let i = 0; i < 5; i++) {
if (value > i) {
result +=
'<img src="https://www.ag-grid.com/example-assets/gold-star.png" />';
}
}
if (forFilter && Number(value) === 0) {
result += currentLang.cellContent.noStars;
}
return result;
}
function currencyRenderer(params: ICellRendererParams) {
if (params.value === null || params.value === undefined) {
return null;
} else if (isNaN(params.value)) {
return "NaN";
} else {
if (params.node.group && params.column!.getAggFunc() === "count") {
return params.value;
} else {
return (
"£" +
Math.floor(params.value)
.toString()
.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
);
}
}
}
function booleanComparator(value1: any, value2: any) {
const value1Cleaned = booleanCleaner(value1);
const value2Cleaned = booleanCleaner(value2);
const value1Ordinal =
value1Cleaned === true ? 0 : value1Cleaned === false ? 1 : 2;
const value2Ordinal =
value2Cleaned === true ? 0 : value2Cleaned === false ? 1 : 2;
return value1Ordinal - value2Ordinal;
}
function booleanCellRenderer(params: ICellRendererParams) {
const valueCleaned = booleanCleaner(params.value);
if (valueCleaned === true) {
return "<span title='true'>✔</span>";
} else if (valueCleaned === false) {
return "<span title='false'>✖</span>";
} else if (params.value !== null && params.value !== undefined) {
return params.value.toString();
} else {
return null;
}
}
function booleanFilterCellRenderer(params: ICellRendererParams) {
const valueCleaned = booleanCleaner(params.value);
if (valueCleaned === true) {
return "✔";
} else if (valueCleaned === false) {
return "✖";
} else if (params.value === "(Select All)") {
return params.value;
} else {
return currentLang.cellContent.empty;
}
}
function booleanCleaner(value: any) {
if (value === "true" || value === true || value === 1) {
return true;
} else if (value === "false" || value === false || value === 0) {
return false;
} else {
return null;
}
}
function languageCellRenderer(params: ICellRendererParams) {
if (params.value !== null && params.value !== undefined) {
return params.value;
} else {
return null;
}
}
const VueExample = defineComponent({
template: `
<div style="height: 100%">
<div class="example-wrapper">
<div style="margin-bottom: 0.5rem; display: flex; gap: 0.5rem; align-items: center">
<label for="language">Language:</label>
<select id="language" v-model="language">
<option value="arabic">العربية (Arabic)</option>
<option value="hebrew">עברית (Hebrew)</option>
<option value="english">English</option>
</select>
</div>
<ag-grid-vue
v-if="gridVisible"
style="width: 100%; height: 100%;"
:columnDefs="columnDefs"
:autoGroupColumnDef="autoGroupColumnDef"
:enableRtl="enableRtl"
:localeText="localeText"
:defaultColDef="defaultColDef"
:sideBar="true"
:rowGroupPanelShow="'always'"
:pivotPanelShow="'always'"
:statusBar="statusBar"
:rowSelection="rowSelection"
:context="context"
:rowData="rowData"
:getContextMenuItems="getContextMenuItems"
:getBusinessKeyForNode="getBusinessKeyForNode"
@row-selected="rowSelected"
@selection-changed="selectionChanged"
></ag-grid-vue>
</div>
</div>
`,
components: {
"ag-grid-vue": AgGridVue,
CountryCellRenderer,
},
setup() {
// Arabic is the default language (RTL locale loaded on first render).
const language = ref("arabic");
const gridVisible = ref(true);
const columnDefs = ref<(ColDef | ColGroupDef)[]>([]);
const autoGroupColumnDef = ref<ColDef>({});
const enableRtl = ref(false);
const localeText = ref<Record<string, string> | undefined>(undefined);
const rowData = ref<any[]>([]);
const defaultColDef: ColDef = {
editable: true,
minWidth: 100,
filter: true,
floatingFilter: true,
};
const context = { COUNTRY_CODES };
const statusBar = {
statusPanels: [{ statusPanel: "agAggregationComponent" }],
};
const rowSelection: RowSelectionOptions = {
mode: "multiRow",
groupSelects: "descendants",
selectAll: "filtered",
};
const getBusinessKeyForNode = (node: IRowNode) => {
if (node.data) {
return node.data.name;
} else {
return "";
}
};
// Rebuild every language-dependent grid prop against the newly selected language. The col-def builders
// and plain renderers read the module-level `currentLang`, so it must be set first.
const rebuild = () => {
currentLang = LANGUAGES[language.value];
columnDefs.value = createCols();
autoGroupColumnDef.value = getAutoGroupColumnDef();
enableRtl.value = currentLang.enableRtl;
localeText.value = currentLang.localeText;
rowData.value = createRowData(language.value);
};
// Initial build for the default (Arabic) language before the first mount.
rebuild();
// `enableRtl`/`localeText` only take effect on grid creation, so tear the grid down and recreate it
// (the grid-state remount idiom) whenever the language changes.
watch(language, () => {
gridVisible.value = false;
setTimeout(() => {
rebuild();
gridVisible.value = true;
});
});
return {
language,
gridVisible,
columnDefs,
autoGroupColumnDef,
enableRtl,
localeText,
rowData,
defaultColDef,
context,
statusBar,
rowSelection,
getContextMenuItems,
getBusinessKeyForNode,
rowSelected,
selectionChanged,
};
},
});
createApp(VueExample).mount("#app");
.example-wrapper {
display: flex;
flex-direction: column;
height: 100%;
}
#myGrid {
flex: 1 1 0px;
width: 100%;
}
export default {
template: `<div v-html="value"></div>`,
data() {
return {
value: "",
};
},
beforeMount() {
const value = this.params.value;
// No country to show (blank cell, or the set filter's "select all" row): render the raw value with no flag.
if (value == null || value === "" || value === "(Select All)") {
this.value = value;
return;
}
// Flags are keyed by the English country name (see COUNTRY_CODES on the grid context). In Arabic/Hebrew
// mode the localised names have no entry, so `code` is undefined and we render the country text with no
// image - this guards against `undefined.png` 404s.
const code = this.params.context.COUNTRY_CODES[value];
if (code) {
const flag = `<img class="flag" border="0" width="15" height="10" src="https://flags.fmcdn.net/data/flags/mini/${code}.png">`;
this.value = `${flag} ${value}`;
} else {
this.value = value;
}
},
};
import {
AG_GRID_LOCALE_EG,
AG_GRID_LOCALE_IL,
} from "@ag-grid-community/locale";
export interface LanguageConfig {
localeText: Record<string, string> | undefined;
enableRtl: boolean;
headers: {
group: string;
participant: string;
name: string;
language: string;
languageTooltip: string;
country: string;
gameOfChoice: string;
gameName: string;
bought: string;
bankBalance: string;
extraInfo1: string;
extraInfo2: string;
rating: string;
totalWinnings: string;
monthlyBreakdown: string;
};
months: string[];
contextMenu: {
customMenuItem: string;
};
cellContent: {
abra: string;
cadabra: string;
noStars: string;
empty: string;
};
colNames: string[];
countries: { country: string; continent: string; language: string }[];
games: string[];
firstNames: string[];
lastNames: string[];
editorLanguages: string[];
editorCountries: string[];
}
const ENGLISH: LanguageConfig = {
localeText: undefined,
enableRtl: false,
headers: {
group: "Group",
participant: "Participant",
name: "Name",
language: "Language",
languageTooltip: "Example tooltip for Language",
country: "Country",
gameOfChoice: "Game of Choice",
gameName: "Game Name",
bought: "Bought",
bankBalance: "Bank Balance",
extraInfo1: "Extra Info 1",
extraInfo2: "Extra Info 2",
rating: "Rating",
totalWinnings: "Total Winnings",
monthlyBreakdown: "Monthly Breakdown",
},
months: [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
],
contextMenu: {
customMenuItem: "Custom Menu Item",
},
cellContent: {
abra: "Abra...",
cadabra: "...cadabra!",
noStars: "(No stars)",
empty: "(empty)",
},
colNames: [
"Station",
"Railway",
"Street",
"Address",
"Toy",
"Soft Box",
"Make and Model",
"Longest Day",
"Shortest Night",
],
countries: [
{ country: "Ireland", continent: "Europe", language: "English" },
{ country: "Spain", continent: "Europe", language: "Spanish" },
{ country: "United Kingdom", continent: "Europe", language: "English" },
{ country: "France", continent: "Europe", language: "French" },
{ country: "Germany", continent: "Europe", language: "German" },
{ country: "Luxembourg", continent: "Europe", language: "French" },
{ country: "Sweden", continent: "Europe", language: "Swedish" },
{ country: "Norway", continent: "Europe", language: "Norwegian" },
{ country: "Italy", continent: "Europe", language: "Italian" },
{ country: "Greece", continent: "Europe", language: "Greek" },
{ country: "Iceland", continent: "Europe", language: "Icelandic" },
{ country: "Portugal", continent: "Europe", language: "Portuguese" },
{ country: "Malta", continent: "Europe", language: "Maltese" },
{ country: "Brazil", continent: "South America", language: "Portuguese" },
{ country: "Argentina", continent: "South America", language: "Spanish" },
{ country: "Colombia", continent: "South America", language: "Spanish" },
{ country: "Peru", continent: "South America", language: "Spanish" },
{ country: "Venezuela", continent: "South America", language: "Spanish" },
{ country: "Uruguay", continent: "South America", language: "Spanish" },
{ country: "Belgium", continent: "Europe", language: "French" },
],
games: [
"Chess",
"Cross and Circle",
"Daldøs",
"Downfall",
"DVONN",
"Fanorona",
"Game of the Generals",
"Ghosts",
"Abalone",
"Agon",
"Backgammon",
"Battleship",
"Blockade",
"Blood Bowl",
"Bul",
"Camelot",
"Checkers",
"Go",
"Gipf",
"Guess Who?",
"Hare and Hounds",
"Hex",
"Hijara",
"Isola",
"Janggi (Korean Chess)",
"Le Jeu de la Guerre",
"Patolli",
"Plateau",
"PÜNCT",
"Rithmomachy",
"Sáhkku",
"Senet",
"Shogi",
"Space Hulk",
"Stratego",
"Sugoroku",
"Tâb",
"Tablut",
"Tantrix",
"Wari",
"Xiangqi (Chinese chess)",
"YINSH",
"ZÈRTZ",
"Kalah",
"Kamisado",
"Liu po",
"Lost Cities",
"Mad Gab",
"Master Mind",
"Nine Men's Morris",
"Obsession",
"Othello",
],
firstNames: [
"Sophie",
"Isabelle",
"Emily",
"Olivia",
"Lily",
"Chloe",
"Isabella",
"Amelia",
"Jessica",
"Sophia",
"Ava",
"Charlotte",
"Mia",
"Lucy",
"Grace",
"Ruby",
"Ella",
"Evie",
"Freya",
"Isla",
"Poppy",
"Daisy",
"Layla",
],
lastNames: [
"Beckham",
"Black",
"Braxton",
"Brennan",
"Brock",
"Bryson",
"Cadwell",
"Cage",
"Carson",
"Chandler",
"Cohen",
"Cole",
"Corbin",
"Dallas",
"Dalton",
"Dane",
"Donovan",
"Easton",
"Fisher",
"Fletcher",
"Grady",
"Greyson",
"Griffin",
"Gunner",
"Hayden",
"Hudson",
"Hunter",
"Jacoby",
"Jagger",
"Jaxon",
"Jett",
"Kade",
"Kane",
"Keating",
"Keegan",
"Kingston",
"Kobe",
],
editorLanguages: [
"English",
"Spanish",
"French",
"Portuguese",
"German",
"Swedish",
"Norwegian",
"Italian",
"Greek",
"Icelandic",
"Portuguese",
"Maltese",
],
editorCountries: [
"Argentina",
"Brazil",
"Colombia",
"France",
"Germany",
"Greece",
"Iceland",
"Ireland",
"Italy",
"Malta",
"Portugal",
"Norway",
"Peru",
"Spain",
"Sweden",
"United Kingdom",
"Uruguay",
"Venezuela",
"Belgium",
"Luxembourg",
],
};
const ARABIC: LanguageConfig = {
localeText: AG_GRID_LOCALE_EG,
enableRtl: true,
headers: {
group: "مجموعة",
participant: "المشارك",
name: "الاسم",
language: "اللغة",
languageTooltip: "تلميح مثال للغة",
country: "البلد",
gameOfChoice: "اللعبة المفضلة",
gameName: "اسم اللعبة",
bought: "تم الشراء",
bankBalance: "الرصيد البنكي",
extraInfo1: "معلومات إضافية 1",
extraInfo2: "معلومات إضافية 2",
rating: "التقييم",
totalWinnings: "إجمالي الأرباح",
monthlyBreakdown: "التفصيل الشهري",
},
months: [
"يناير",
"فبراير",
"مارس",
"أبريل",
"مايو",
"يونيو",
"يوليو",
"أغسطس",
"سبتمبر",
"أكتوبر",
"نوفمبر",
"ديسمبر",
],
contextMenu: {
customMenuItem: "عنصر قائمة مخصص",
},
cellContent: {
abra: "أبرا...",
cadabra: "...كادابرا!",
noStars: "(بدون نجوم)",
empty: "(فارغ)",
},
colNames: [
"محطة",
"سكة حديد",
"شارع",
"عنوان",
"لعبة",
"صندوق",
"الشركة والطراز",
"أطول يوم",
"أقصر ليلة",
],
countries: [
{ country: "أيرلندا", continent: "أوروبا", language: "الإنجليزية" },
{ country: "إسبانيا", continent: "أوروبا", language: "الإسبانية" },
{ country: "المملكة المتحدة", continent: "أوروبا", language: "الإنجليزية" },
{ country: "فرنسا", continent: "أوروبا", language: "الفرنسية" },
{ country: "ألمانيا", continent: "أوروبا", language: "الألمانية" },
{ country: "لوكسمبورغ", continent: "أوروبا", language: "الفرنسية" },
{ country: "السويد", continent: "أوروبا", language: "السويدية" },
{ country: "النرويج", continent: "أوروبا", language: "النرويجية" },
{ country: "إيطاليا", continent: "أوروبا", language: "الإيطالية" },
{ country: "اليونان", continent: "أوروبا", language: "اليونانية" },
{ country: "أيسلندا", continent: "أوروبا", language: "الأيسلندية" },
{ country: "البرتغال", continent: "أوروبا", language: "البرتغالية" },
{ country: "مالطا", continent: "أوروبا", language: "المالطية" },
{
country: "البرازيل",
continent: "أمريكا الجنوبية",
language: "البرتغالية",
},
{
country: "الأرجنتين",
continent: "أمريكا الجنوبية",
language: "الإسبانية",
},
{
country: "كولومبيا",
continent: "أمريكا الجنوبية",
language: "الإسبانية",
},
{ country: "بيرو", continent: "أمريكا الجنوبية", language: "الإسبانية" },
{ country: "فنزويلا", continent: "أمريكا الجنوبية", language: "الإسبانية" },
{
country: "أوروغواي",
continent: "أمريكا الجنوبية",
language: "الإسبانية",
},
{ country: "بلجيكا", continent: "أوروبا", language: "الفرنسية" },
],
games: [
"شطرنج",
"الدائرة والصليب",
"دالدوس",
"السقوط",
"دفون",
"فانورونا",
"لعبة الجنرالات",
"الأشباح",
"أبالون",
"آغون",
"طاولة الزهر",
"سفينة حربية",
"حصار",
"بلود بول",
"بول",
"كاميلوت",
"داما",
"غو",
"غيبف",
"احزر من؟",
"الأرنب والكلاب",
"هيكس",
"هيجارا",
"إيزولا",
"جانغي (شطرنج كوري)",
"لعبة الحرب",
"باتولي",
"بلاتو",
"بونكت",
"ريثموماكي",
"ساهكو",
"سينيت",
"شوغي",
"سبيس هالك",
"ستراتيغو",
"سوغوروكو",
"طاب",
"تابلوت",
"تانتريكس",
"واري",
"شيانغتشي (شطرنج صيني)",
"يينش",
"زيرتز",
"كالاه",
"كاميسادو",
"ليو بو",
"المدن المفقودة",
"ماد غاب",
"ماستر مايند",
"مطحنة الرجال التسعة",
"هوس",
"أوثيلو",
],
firstNames: [
"فاطمة",
"عائشة",
"مريم",
"خديجة",
"زينب",
"نور",
"سارة",
"ليلى",
"هدى",
"أمينة",
"رنا",
"دانا",
"ياسمين",
"لمى",
"سلمى",
"ريم",
"هالة",
"منى",
"سميرة",
"نادية",
"رشا",
"سحر",
"جنى",
],
lastNames: [
"أحمد",
"محمد",
"علي",
"حسن",
"حسين",
"إبراهيم",
"خالد",
"عمر",
"يوسف",
"سعيد",
"مصطفى",
"عبد الله",
"الشريف",
"المنصور",
"الحكيم",
"النجار",
"الخطيب",
"البكري",
"الزهراني",
"القحطاني",
"العتيبي",
"الغامدي",
"الدوسري",
"الشمري",
"المطيري",
"الحربي",
"السبيعي",
"العنزي",
"الرشيدي",
"البلوي",
"الجهني",
"المالكي",
"الثبيتي",
"الزهراء",
"الفهد",
"السلمي",
"الحازمي",
],
editorLanguages: [
"الإنجليزية",
"الإسبانية",
"الفرنسية",
"البرتغالية",
"الألمانية",
"السويدية",
"النرويجية",
"الإيطالية",
"اليونانية",
"الأيسلندية",
"البرتغالية",
"المالطية",
],
editorCountries: [
"الأرجنتين",
"البرازيل",
"كولومبيا",
"فرنسا",
"ألمانيا",
"اليونان",
"أيسلندا",
"أيرلندا",
"إيطاليا",
"مالطا",
"البرتغال",
"النرويج",
"بيرو",
"إسبانيا",
"السويد",
"المملكة المتحدة",
"أوروغواي",
"فنزويلا",
"بلجيكا",
"لوكسمبورغ",
],
};
const HEBREW: LanguageConfig = {
localeText: AG_GRID_LOCALE_IL,
enableRtl: true,
headers: {
group: "קבוצה",
participant: "משתתף",
name: "שם",
language: "שפה",
languageTooltip: "תיאור לדוגמה עבור שפה",
country: "מדינה",
gameOfChoice: "משחק מועדף",
gameName: "שם המשחק",
bought: "נרכש",
bankBalance: "יתרת בנק",
extraInfo1: "מידע נוסף 1",
extraInfo2: "מידע נוסף 2",
rating: "דירוג",
totalWinnings: "סה״כ זכיות",
monthlyBreakdown: "פירוט חודשי",
},
months: [
"ינואר",
"פברואר",
"מרץ",
"אפריל",
"מאי",
"יוני",
"יולי",
"אוגוסט",
"ספטמבר",
"אוקטובר",
"נובמבר",
"דצמבר",
],
contextMenu: {
customMenuItem: "פריט תפריט מותאם",
},
cellContent: {
abra: "...אברא",
cadabra: "!כדברא...",
noStars: "(ללא כוכבים)",
empty: "(ריק)",
},
colNames: [
"תחנה",
"רכבת",
"רחוב",
"כתובת",
"צעצוע",
"קופסה",
"יצרן ודגם",
"היום הארוך",
"הלילה הקצר",
],
countries: [
{ country: "אירלנד", continent: "אירופה", language: "אנגלית" },
{ country: "ספרד", continent: "אירופה", language: "ספרדית" },
{ country: "בריטניה", continent: "אירופה", language: "אנגלית" },
{ country: "צרפת", continent: "אירופה", language: "צרפתית" },
{ country: "גרמניה", continent: "אירופה", language: "גרמנית" },
{ country: "לוקסמבורג", continent: "אירופה", language: "צרפתית" },
{ country: "שוודיה", continent: "אירופה", language: "שוודית" },
{ country: "נורווגיה", continent: "אירופה", language: "נורווגית" },
{ country: "איטליה", continent: "אירופה", language: "איטלקית" },
{ country: "יוון", continent: "אירופה", language: "יוונית" },
{ country: "איסלנד", continent: "אירופה", language: "איסלנדית" },
{ country: "פורטוגל", continent: "אירופה", language: "פורטוגזית" },
{ country: "מלטה", continent: "אירופה", language: "מלטזית" },
{ country: "ברזיל", continent: "דרום אמריקה", language: "פורטוגזית" },
{ country: "ארגנטינה", continent: "דרום אמריקה", language: "ספרדית" },
{ country: "קולומביה", continent: "דרום אמריקה", language: "ספרדית" },
{ country: "פרו", continent: "דרום אמריקה", language: "ספרדית" },
{ country: "ונצואלה", continent: "דרום אמריקה", language: "ספרדית" },
{ country: "אורוגוואי", continent: "דרום אמריקה", language: "ספרדית" },
{ country: "בלגיה", continent: "אירופה", language: "צרפתית" },
],
games: [
"שחמט",
"עיגול וצלב",
"דלדוס",
"מפולת",
"דבון",
"פנורונה",
"משחק הגנרלים",
"רוחות",
"אבלון",
"אגון",
"שש-בש",
"ספינות קרב",
"מצור",
"בלאד באול",
"בול",
"קמלוט",
"דמקה",
"גו",
"גיפף",
"נחש מי?",
"ארנב וכלבים",
"הקס",
"היג׳ארה",
"איזולה",
"ג׳אנגי (שחמט קוריאני)",
"משחק המלחמה",
"פטולי",
"פלאטו",
"פונקט",
"ריתמומכיה",
"סאהקו",
"סנט",
"שוגי",
"ספייס האלק",
"סטרטגו",
"סוגורוקו",
"טאב",
"טבלוט",
"טנטריקס",
"וארי",
"שיאנגצ׳י (שחמט סיני)",
"יינש",
"זרטץ",
"קלח",
"קמיסדו",
"ליו פו",
"ערים אבודות",
"מד גאב",
"מאסטר מיינד",
"טחנת תשעה",
"אובססיה",
"אותלו",
],
firstNames: [
"נועה",
"תמר",
"שירה",
"יעל",
"מיכל",
"רחל",
"דנה",
"אורי",
"הילה",
"ליאת",
"מאיה",
"רונית",
"עדי",
"שרה",
"אביגיל",
"מרים",
"רבקה",
"לאה",
"חנה",
"אסתר",
"גלית",
"ענת",
"טלי",
],
lastNames: [
"כהן",
"לוי",
"מזרחי",
"פרץ",
"ביטון",
"דהן",
"אברהם",
"פרידמן",
"שפירא",
"גולדברג",
"רוזנברג",
"ברקוביץ",
"אלון",
"שלום",
"יוסף",
"דוד",
"חיים",
"גבאי",
"אזולאי",
"מלכה",
"אוחיון",
"שמעון",
"בנימין",
"אליהו",
"מרדכי",
"גרינברג",
"הרשקוביץ",
"שטרנברג",
"ויינשטיין",
"זילברמן",
"קפלן",
"ברנשטיין",
"רוזנטל",
"גולדשטיין",
"הלפרין",
"ליבוביץ",
"פינקלשטיין",
],
editorLanguages: [
"אנגלית",
"ספרדית",
"צרפתית",
"פורטוגזית",
"גרמנית",
"שוודית",
"נורווגית",
"איטלקית",
"יוונית",
"איסלנדית",
"פורטוגזית",
"מלטזית",
],
editorCountries: [
"ארגנטינה",
"ברזיל",
"קולומביה",
"צרפת",
"גרמניה",
"יוון",
"איסלנד",
"אירלנד",
"איטליה",
"מלטה",
"פורטוגל",
"נורווגיה",
"פרו",
"ספרד",
"שוודיה",
"בריטניה",
"אורוגוואי",
"ונצואלה",
"בלגיה",
"לוקסמבורג",
],
};
export const LANGUAGES: Record<string, LanguageConfig> = {
english: ENGLISH,
arabic: ARABIC,
hebrew: HEBREW,
};
// Flag lookup keyed by the English country name. Placed on `gridOptions.context` so every framework's
// CountryCellRenderer reads it identically. Flags therefore resolve in English mode; the localised
// Arabic/Hebrew country names have no entry, so the renderer shows the name without a flag.
export const COUNTRY_CODES: Record<string, string> = {
Ireland: "ie",
Luxembourg: "lu",
Belgium: "be",
Spain: "es",
"United Kingdom": "gb",
France: "fr",
Germany: "de",
Sweden: "se",
Italy: "it",
Greece: "gr",
Iceland: "is",
Portugal: "pt",
Malta: "mt",
Norway: "no",
Brazil: "br",
Argentina: "ar",
Colombia: "co",
Peru: "pe",
Venezuela: "ve",
Uruguay: "uy",
};
const BOOLEAN_VALUES = [true, "true", false, "false"];
// Builds the example's row data for a language synchronously. Shared by every framework variant so the
// grids render identical data; the deterministic pseudo-random seed is reset on each call.
export function createRowData(languageKey: string): any[] {
const lang = LANGUAGES[languageKey];
const rowCount = 100;
let seed = 123456789;
const m = Math.pow(2, 32);
const a = 1103515245;
const c = 12345;
const pseudoRandom = () => {
seed = (a * seed + c) % m;
return seed / m;
};
const data: any[] = [];
for (let row = 0; row < rowCount; row++) {
const rowItem: any = {};
const countries = lang.countries;
const countriesToPickFrom = Math.floor(
countries.length * (((row % 3) + 1) / 3),
);
const countryData = countries[(row * 19) % countriesToPickFrom];
rowItem.country = countryData.country;
rowItem.continent = countryData.continent;
rowItem.language = countryData.language;
const firstName = lang.firstNames[row % lang.firstNames.length];
const lastName = lang.lastNames[row % lang.lastNames.length];
rowItem.name = firstName + " " + lastName;
rowItem.game = {
name: lang.games[Math.floor(((row * 13) / 17) * 19) % lang.games.length],
bought: BOOLEAN_VALUES[row % BOOLEAN_VALUES.length],
};
rowItem.bankBalance = Math.round(pseudoRandom() * 10000000) / 100 - 3000;
rowItem.rating = Math.round(pseudoRandom() * 5);
let totalWinnings = 0;
for (let i = 0, len = lang.months.length; i < len; ++i) {
const value = Math.round(pseudoRandom() * 10000000) / 100 - 20;
rowItem["month_" + i] = value;
totalWinnings += value;
}
rowItem.totalWinnings = totalWinnings;
data.push(rowItem);
}
return data;
}
How it Works Copy Link
If you are creating your own theme, knowing how the RTL is implemented will be useful.
CSS Styling Copy Link
The following CSS classes are added to the grid when RTL is on and off:
- ag-rtl: Added when RTL is ON. It sets the style
'direction=rtl'. - ag-ltr: Added when RTL is OFF. It sets the style
'direction=ltr'.
You can see these classes by inspecting the DOM of AG Grid. A lot of the layout of the grid is reversed with this simple CSS class change.
Themes then also use these styles for adding different values based on whether RTL is used or NOT. For example, the following is used inside the provided themes:
// selection checkbox gets 4px padding to the RIGHT when LTR
.ag-ltr .ag-selection-checkbox {
padding-right 4px;
}
// selection checkbox gets 4px padding to the LEFT when RTL
.ag-rtl .ag-selection-checkbox {
padding-left 4px;
} Pinning and Scroll Bars Copy Link
Under normal operation, when columns are pinned to the right, the vertical scroll will appear alongside the right pinned panel. For RTL the scroll will appear on the left pinned panel when left pinning columns.
Layout of Columns Copy Link
The grid normally lays the columns out from left to right. When doing RTL the columns go from the right to the left. If the grid was using normal HTML layout, then the columns would all reverse by themselves, however the grid used Column Visualisation, so it needs to know exactly where each column is. Hence there is a lot of math logic inside AG Grid that is tied with the scrolling. Not only is the scrolling inverted, all the maths logic is inverted also. All of this is taken care of for you inside AG Grid. Once enableRtl=true is set, the grid will know to use the RTL variant of all the calculations.