Localization
Twelve languages ship with the package. Hand the grid the ones your app offers and it picks between them; the same tag drives Intl, so numbers and dates follow the language rather than drifting from it.
A language is chosen per grid, through locales and locale on createDataGrid. Nothing is set globally, so two grids on one page may speak different languages and neither
has to be put back afterwards.
DataGridLabels gains 41 members, 214 to 255, for the wording a pivot brings. Passing the grid a subset is unaffected, and so is a pack of your own; a complete table passed as the base of mergeLabels no longer type-checks and should be merged onto the built-in table instead.Switching Language
Change the language below and watch three things move at once: the toolbar and footer strings, the currency format, and the date format. The sort, the filter and the page stay where they were, because the language is state on the grid rather than a remount.
// locale forces a tag rather than following the page
createDataGrid<Person>({ columns, data, getRowId, locales, locale: 'vi-VN' });
// Assigning it switches in place, keeping the sort, filter and selection
grid.locale = 'ja-JP';
// The same tag drives Intl, so number, currency and date columns that name
// no locale of their own reformat with it.
{ id: 'salary', type: 'currency', typeOptions: { currency: 'EUR' } }
// A tag nobody answers for falls back to English, and 'vi' is answered by
// the 'vi-VN' pack.Loading Packs
There is no "all languages" export on purpose: a pack nobody imports is a pack nobody ships.
The grid below ships one pack, viVN, and
the three tags show the whole rule. The exact tag matches. A bare vi is answered
by the vi-VN pack. A tag no pack answers for falls back to English, which is built in and needs
no import.
import { createDataGrid } from '@sv5ui/datagrid';
import { enUS, jaJP, viVN } from '@sv5ui/datagrid/locales';
// Hand the grid the languages it may use. It picks one from the page's own
// language, so nothing else needs configuring. A pack nobody imports is
// never bundled, which is why there is no "all languages" export.
const grid = createDataGrid<Person>({
columns,
data,
getRowId,
locales: [enUS, viVN, jaJP]
});The Twelve Packs
From @sv5ui/datagrid/locales, named after their tag: enUS, viVN, zhCN, jaJP, koKR, frFR, deDE, esES, ptBR, ruRU, idID, thTH.
| Tag | Language |
|---|---|
en-US | English |
vi-VN | Vietnamese |
zh-CN | Chinese, simplified |
ja-JP | Japanese |
ko-KR | Korean |
fr-FR | French |
de-DE | German |
es-ES | Spanish |
pt-BR | Portuguese, Brazil |
ru-RU | Russian |
id-ID | Indonesian |
th-TH | Thai |
Overriding Single Strings
labels replaces individual strings on top of the chosen pack. The grid below is English with four of
them changed: the search placeholder, the empty text, the selection count and the page-size label.
// labels replaces single strings on top of the chosen pack, any subset
createDataGrid<Person>({
columns,
data,
getRowId,
locales: [enUS],
labels: {
search: 'Find a member',
noData: 'Nobody here yet',
// Functions where a value is interpolated, so a language can put the
// number where it needs it.
selectedRows: (count) => `${count} chosen`,
pageRange: (from, to, total) => `${from} to ${to} of ${total}`,
// Operator maps override one entry at a time
textOps: { contains: 'has' }
},
// The same for what the live region speaks
announcer: {
sorted: (column, direction) => `${column}, ${direction}ending`
}
});What the Labels Cover
All 255 strings the grid renders, grouped by where they appear. A label is a plain string, or a function where a value is interpolated. A feature you do not register never asks for its labels, so the count is what the table can hold, not what any one grid uses.
| Area | Keys |
|---|---|
Toolbar | search, activeFilters, removeFilter, clearAllFilters, chooseColumns, rowDensity, densityCompact, densityStandard, densityComfortable |
Header and column menu | columnMenu, resizeColumn, resizeGroup, sortAscending, sortDescending, clearSort, pinLeft, pinRight, unpin, openFilter, autosize, hideColumn, collapseGroup, expandGroup |
Filter panel and filter row | filterColumn, filterOperator, filterValue, filterRowValue, filterUpperBound, valuePlaceholder, upperBoundPlaceholder, searchValues, blankValue, anyValue, combineConditions, addCondition, removeCondition, matchCase, apply, clear, and, or, yes, no, and the three operator maps textOps, numberOps and dateOps |
Rows | selectRow, selectAllRows, rowActions, dragRow, expandRow, collapseRow |
Footer and status | rowsPerPage, pageSizeOption, pageRange, totalRows, filteredRows, selectedRows, noData, retry. Under a pivot the count reads crossedRows, and crossedFilteredRows while a filter is on: both are functions, taking the number of gathered rows and the number of rows they were measured from |
Menus | copy, copyWithHeaders, exportCsv, exportAllRows, exportLoadedRows, exportSelectedRows, clearSelection |
Grouping | The group panel, the column menu entries that group and ungroup, and the rows grouping draws: groupBy, groupPanelEmpty, addGroup, clearGroups, moveGroupEarlier, moveGroupLater, removeGroup, groupByColumn, ungroupColumn, groupFooter, grandTotal, and the three a server row model uses while a count is still partial, groupLoaded, groupFooterLoaded and grandTotalLoaded |
Pivot | The three column menu entries that start and stop a crossing: pivotByRow, pivotByColumn, removeFromPivot. The four zones of Grid.PivotPanel and their hints: pivotRows, pivotColumns, pivotValues, pivotSettings, pivotRowsHint, pivotColumnsHint, pivotValuesHint, pivotSettingsHint, pivotPanelEmpty. The chips and their controls: addPivotRow, addPivotColumn, addPivotValue, clearPivotAll, pivotAggregation, pivotShare, pivotShareNone, and movePivotEarlier, movePivotLater and removePivotChip, which are functions taking the column header. The settings: pivotTotalColumn, pivotTotalRow, pivotSubtotal, pivotFoldable, pivotSortable, pivotValuesOn, pivotValuesDown, pivotExpandAll, pivotCollapseAll, pivotKeep, pivotKeepAll, pivotKeepOthers, and pivotKeepTop and pivotKeepBottom, which are functions taking the count. pivotSubtotalOf is a function taking a group header, and it also names the subtotal columns a saved view brings back. pivotTotalColumn, pivotTotalRow and pivotKeepOthers double as the headers the panel gives a total or a gathered row it switches on. Two are maps rather than strings, overridden one entry at a time the way textOps is: pivotAggs names the nine reductions a measure chip offers, and pivotShares the seven readings |
Tool panel | Its title, its three tabs and everything inside them: toolPanelTitle, toolPanelColumns, toolPanelGroup, toolPanelValues, toolPanelSearch, toolPanelShowAll, toolPanelHideAll, toolPanelEmpty, toolPanelMoveUp, toolPanelMoveDown, toolPanelNoAggregation, toolPanelActions, toolPanelCollapse, toolPanelExpand |
Cell ranges | What the range status bar reads out: rangeCells, rangeShape, rangeSum, rangeAvg, rangeMin, rangeMax |
Filter builder | The nested condition tree: filterTitle, filterEmpty, filterAddCondition, filterAddGroup, filterRemove, filterJoin, filterNot, filterBuilderColumn, filterBuilderOperator, filterBuilderValue, filterValueTo, filterTrue, filterFalse, filterOp, and filterServerHandled for a condition the server answers |
Find and replace | The bar, its controls and everything it reports: findTitle, findPlaceholder, replacePlaceholder, findCaseSensitive, findWholeCell, findPrevious, findNext, findClose, findReplaceOne, findReplaceAll, findCount, findNoMatch, findReplaced, findNoWritable for matches that cannot be written, and findCountLoaded, findNoMatchLoaded and findServerReadOnly under a server row model |
Saved views | The views bar and sharing: viewsLabel, viewsEmpty, viewsPick, viewNamePlaceholder, viewSave, viewUpdate, viewRevert, viewRemove, viewShare, viewShareCopied, viewModified, and viewShareTooLong for a state that will not fit in a link |
Conditional formatting | The rules bar and the five rule kinds: formatLabel, formatEmpty, formatAdd, formatClear, formatColumn, formatKind, formatKindColorScale, formatKindDataBar, formatKindDuplicates, formatKindTopN, formatKindExpression, formatTopCount, formatExpressionPlaceholder, formatWholeRow, formatRuleName, formatRemoveRule, formatBadExpression |
Data import | The wizard, from the drop zone through mapping to review: importTitle, importDropHere, importChooseFile, importPaste, importEmpty, importUnknownFormat, importHeaderRow, importSheet, importColumnFrom, importSkipColumn, importMatchTitle, importReviewTitle, importBack, importNext, importCancel, importAddRows, importAddValid, importIssues, importReady, importMatched, importNothingMatched, importRowCount, importTooBig, importServerRefusal, and the six that word a bad cell: importNotNumber, importNotDate, importNotBoolean, importInvalid, importDuplicate, importExisting |
Command palette | The palette and every command the built-in features register: commandPaletteTitle, commandPalettePlaceholder, commandPaletteEmpty, commandGroupDefault, commandShowColumn, commandHideColumn, commandUnpinColumn, commandPinColumnLeft, commandPinColumnRight, commandGroupByColumn, commandUngroupColumn, commandExpandAllGroups, commandCollapseAllGroups, commandClearGrouping, commandCopyRange, commandFillDown, commandFillRight, commandFind, commandSaveView, and the three group headings commandGroupColumns, commandGroupGrouping and commandGroupClipboard |
Writing a Pack
A pack says what it has. English answers for the rest, so a pack of five strings works, and one written against this version keeps working when the next names a string it has never heard of: that string arrives in English rather than as a blank or as a build that will not run. Every key it does say is typed, so a translation cannot land on a name the grid does not have.
Which makes spreading enUS.labels into a pack unnecessary, and worse than unnecessary: it freezes today's English into the pack,
so a string added later arrives translated to whatever English said when the pack was written.
The second option below is a pack written in this file, four labels deep. Switch to it and watch the search box, the footer's page-size label and the column chooser change while everything left untranslated stays English.
import type { DataGridLocalePack } from '@sv5ui/datagrid';
// A pack is { tag, labels, announcer } and says what it has. English
// answers for the rest, so two labels is a working pack, and a string the
// grid adds next release arrives in English rather than as a blank.
export const svSE: DataGridLocalePack = {
tag: 'sv-SE',
labels: { search: 'Sok...', noData: 'Inga rader' },
announcer: { sortCleared: () => 'Sortering rensad' }
};
// Every key it does say is typed, so a translation cannot land on a name
// the grid does not have, and a label function keeps its signature.
createDataGrid<Person>({ columns, data, getRowId, locales: [svSE] });
// Layered in this order, so the narrowest wins:
// English -> the pack for grid.locale -> this app's own labels/announcer
createDataGrid<Person>({
columns, data, getRowId,
locales: [svSE],
labels: { search: 'Sok medlemmar...' } // over the pack, over English
});Options
| Option | Default |
|---|---|
locales | [] |
locale | the page language |
labels | - |
announcer | - |