@gridkitjs/react 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -81,6 +81,24 @@ function GroupIcon() {
81
81
  function FilterIcon() {
82
82
  return /* @__PURE__ */ jsx2(Icon, { children: /* @__PURE__ */ jsx2("path", { d: "M22 3H2l8 9.46V19l4 2v-8.54z" }) });
83
83
  }
84
+ function ChevronLeftIcon() {
85
+ return /* @__PURE__ */ jsx2(Icon, { children: /* @__PURE__ */ jsx2("path", { d: "m15 18-6-6 6-6" }) });
86
+ }
87
+ function ChevronRightIcon() {
88
+ return /* @__PURE__ */ jsx2(Icon, { children: /* @__PURE__ */ jsx2("path", { d: "m9 18 6-6-6-6" }) });
89
+ }
90
+ function ChevronsLeftIcon() {
91
+ return /* @__PURE__ */ jsxs(Icon, { children: [
92
+ /* @__PURE__ */ jsx2("path", { d: "m11 17-5-5 5-5" }),
93
+ /* @__PURE__ */ jsx2("path", { d: "m18 17-5-5 5-5" })
94
+ ] });
95
+ }
96
+ function ChevronsRightIcon() {
97
+ return /* @__PURE__ */ jsxs(Icon, { children: [
98
+ /* @__PURE__ */ jsx2("path", { d: "m6 17 5-5-5-5" }),
99
+ /* @__PURE__ */ jsx2("path", { d: "m13 17 5-5-5-5" })
100
+ ] });
101
+ }
84
102
 
85
103
  // src/DataGrid/isOwnEvent.ts
86
104
  function isOwnEvent(event) {
@@ -119,7 +137,11 @@ function useGridNavigation({
119
137
  };
120
138
  const [gridFocus] = useState(() => createGridFocus(options));
121
139
  gridFocus.setOptions(options);
122
- const focus = useSyncExternalStore(gridFocus.subscribe, gridFocus.getFocus);
140
+ const focus = useSyncExternalStore(
141
+ gridFocus.subscribe,
142
+ gridFocus.getFocus,
143
+ gridFocus.getFocus
144
+ );
123
145
  const [rows] = useState(() => ({
124
146
  getHeaderRow: () => headerTableRef.current?.tHead?.rows[0] ?? null,
125
147
  getBodyRow: (rowIndex) => findBodyRow(bodyTableRef.current, rowIndex)
@@ -221,7 +243,7 @@ function GridHeader({
221
243
  panels.open("filter", { area: "header", columnId });
222
244
  }
223
245
  }
224
- return /* @__PURE__ */ jsxs2("thead", { children: [
246
+ return /* @__PURE__ */ jsxs2("thead", { role: "rowgroup", children: [
225
247
  /* @__PURE__ */ jsx3("tr", { className: "grid-header", role: "row", "aria-rowindex": 1, children: columns.map((entry, index) => {
226
248
  const { column } = entry;
227
249
  const resizing = resize.activeColumnId === entry.id;
@@ -904,6 +926,7 @@ function GridBody({
904
926
  return /* @__PURE__ */ jsxs5(
905
927
  "tbody",
906
928
  {
929
+ role: "rowgroup",
907
930
  className: "grid-body",
908
931
  onFocus: (event) => {
909
932
  const group = groupRowFrom(event.target);
@@ -1087,9 +1110,10 @@ function GridFooter({
1087
1110
  aggregates,
1088
1111
  results,
1089
1112
  rows,
1090
- locale
1113
+ locale,
1114
+ ariaRowIndex
1091
1115
  }) {
1092
- return /* @__PURE__ */ jsx8("tfoot", { children: /* @__PURE__ */ jsx8("tr", { className: "grid-footer", role: "row", children: columns.map((entry) => {
1116
+ return /* @__PURE__ */ jsx8("tfoot", { role: "rowgroup", children: /* @__PURE__ */ jsx8("tr", { className: "grid-footer", role: "row", "aria-rowindex": ariaRowIndex, children: columns.map((entry) => {
1093
1117
  const specs = aggregates.filter(
1094
1118
  (candidate) => candidate.columnId === entry.id
1095
1119
  );
@@ -1120,10 +1144,37 @@ function GridFooter({
1120
1144
  // src/DataGrid/components/GridPager.tsx
1121
1145
  import { paginationWindow } from "@gridkitjs/core";
1122
1146
  import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
1147
+ function PagerNavButton({
1148
+ className,
1149
+ label,
1150
+ disabled,
1151
+ onClick,
1152
+ children
1153
+ }) {
1154
+ return /* @__PURE__ */ jsx9(
1155
+ "button",
1156
+ {
1157
+ type: "button",
1158
+ className: `grid-pager-button grid-pager-nav ${className}`,
1159
+ "aria-label": label,
1160
+ title: label,
1161
+ ...ariaAttr(disabled, "aria-disabled", true),
1162
+ onClick: () => {
1163
+ if (!disabled) onClick();
1164
+ },
1165
+ children
1166
+ }
1167
+ );
1168
+ }
1123
1169
  function GridPager({ pager, config, messages }) {
1124
1170
  const { pagination, pageCount, currentPage } = pager;
1125
1171
  const variant = config?.variant ?? "compact";
1126
1172
  const sizeOptions = config?.sizeOptions;
1173
+ const atFirst = pagination.pageIndex <= 0;
1174
+ const atLast = pagination.pageIndex >= pageCount - 1;
1175
+ const barStyle = {
1176
+ "--gridkit-pager-digits": String(String(Math.max(1, pageCount)).length)
1177
+ };
1127
1178
  return /* @__PURE__ */ jsxs6(
1128
1179
  "div",
1129
1180
  {
@@ -1131,59 +1182,90 @@ function GridPager({ pager, config, messages }) {
1131
1182
  role: "group",
1132
1183
  "aria-label": messages.pagerLabel,
1133
1184
  children: [
1134
- /* @__PURE__ */ jsx9(
1135
- "button",
1136
- {
1137
- type: "button",
1138
- className: "grid-pager-button",
1139
- disabled: pagination.pageIndex <= 0,
1140
- onClick: () => {
1141
- pager.previousPage();
1142
- },
1143
- children: messages.previousPage
1144
- }
1145
- ),
1146
- variant === "numbered" ? paginationWindow(currentPage, pageCount, {
1147
- boundaryCount: config?.boundaryCount,
1148
- siblingCount: config?.siblingCount
1149
- }).map(
1150
- (entry, index) => entry === "ellipsis" ? /* @__PURE__ */ jsx9(
1151
- "span",
1185
+ /* @__PURE__ */ jsxs6("div", { className: "grid-pager-bar", style: barStyle, children: [
1186
+ /* @__PURE__ */ jsx9(
1187
+ PagerNavButton,
1152
1188
  {
1153
- className: "grid-pager-ellipsis",
1154
- "aria-hidden": "true",
1155
- children: "\u2026"
1156
- },
1157
- `ellipsis-${String(index)}`
1158
- ) : /* @__PURE__ */ jsx9(
1159
- "button",
1189
+ className: "grid-pager-first",
1190
+ label: messages.firstPage,
1191
+ disabled: atFirst,
1192
+ onClick: () => {
1193
+ pager.goToPage(0);
1194
+ },
1195
+ children: /* @__PURE__ */ jsx9(ChevronsLeftIcon, {})
1196
+ }
1197
+ ),
1198
+ /* @__PURE__ */ jsx9(
1199
+ PagerNavButton,
1160
1200
  {
1161
- type: "button",
1162
- className: "grid-pager-button",
1163
- "aria-label": messages.pageButtonLabel(entry),
1164
- "aria-current": entry === currentPage ? "page" : void 0,
1201
+ className: "grid-pager-previous",
1202
+ label: messages.previousPage,
1203
+ disabled: atFirst,
1165
1204
  onClick: () => {
1166
- pager.goToPage(entry - 1);
1205
+ pager.previousPage();
1167
1206
  },
1168
- children: entry
1169
- },
1170
- entry
1207
+ children: /* @__PURE__ */ jsx9(ChevronLeftIcon, {})
1208
+ }
1209
+ ),
1210
+ variant === "numbered" ? paginationWindow(currentPage, pageCount, {
1211
+ boundaryCount: config?.boundaryCount,
1212
+ siblingCount: config?.siblingCount
1213
+ }).map(
1214
+ (entry, index) => entry === "ellipsis" ? /* @__PURE__ */ jsx9(
1215
+ "span",
1216
+ {
1217
+ className: "grid-pager-ellipsis",
1218
+ "aria-hidden": "true",
1219
+ children: "\u2026"
1220
+ },
1221
+ `ellipsis-${String(index)}`
1222
+ ) : /* @__PURE__ */ jsx9(
1223
+ "button",
1224
+ {
1225
+ type: "button",
1226
+ className: "grid-pager-button grid-pager-page",
1227
+ "aria-label": messages.pageButtonLabel(entry),
1228
+ "aria-current": entry === currentPage ? "page" : void 0,
1229
+ onClick: () => {
1230
+ pager.goToPage(entry - 1);
1231
+ },
1232
+ children: entry
1233
+ },
1234
+ entry
1235
+ )
1236
+ ) : /* @__PURE__ */ jsxs6("span", { className: "grid-pager-status-slot", children: [
1237
+ /* @__PURE__ */ jsx9("span", { className: "grid-pager-status", children: messages.pageStatus(
1238
+ pageCount === 0 ? 0 : currentPage,
1239
+ pageCount
1240
+ ) }),
1241
+ /* @__PURE__ */ jsx9("span", { className: "grid-pager-status-sizer", "aria-hidden": "true", children: messages.pageStatus(pageCount, pageCount) })
1242
+ ] }),
1243
+ /* @__PURE__ */ jsx9(
1244
+ PagerNavButton,
1245
+ {
1246
+ className: "grid-pager-next",
1247
+ label: messages.nextPage,
1248
+ disabled: atLast,
1249
+ onClick: () => {
1250
+ pager.nextPage();
1251
+ },
1252
+ children: /* @__PURE__ */ jsx9(ChevronRightIcon, {})
1253
+ }
1254
+ ),
1255
+ /* @__PURE__ */ jsx9(
1256
+ PagerNavButton,
1257
+ {
1258
+ className: "grid-pager-last",
1259
+ label: messages.lastPage,
1260
+ disabled: atLast,
1261
+ onClick: () => {
1262
+ pager.goToPage(pageCount - 1);
1263
+ },
1264
+ children: /* @__PURE__ */ jsx9(ChevronsRightIcon, {})
1265
+ }
1171
1266
  )
1172
- ) : /* @__PURE__ */ jsx9("span", { className: "grid-pager-status", children: messages.pageStatus(pageCount === 0 ? 0 : currentPage, pageCount) }),
1173
- /* @__PURE__ */ jsx9(
1174
- "button",
1175
- {
1176
- type: "button",
1177
- className: "grid-pager-button",
1178
- disabled: pagination.pageIndex >= pageCount - 1,
1179
- onClick: () => {
1180
- pager.nextPage();
1181
- },
1182
- children: messages.nextPage
1183
- }
1184
- ),
1267
+ ] }),
1185
1268
  sizeOptions !== void 0 && sizeOptions.length > 0 && /* @__PURE__ */ jsxs6("label", { className: "grid-pager-page-size", children: [
1186
- messages.pageSizeLabel,
1187
1269
  /* @__PURE__ */ jsx9(
1188
1270
  "select",
1189
1271
  {
@@ -1193,7 +1275,8 @@ function GridPager({ pager, config, messages }) {
1193
1275
  },
1194
1276
  children: sizeOptions.map((size) => /* @__PURE__ */ jsx9("option", { value: size, children: size }, size))
1195
1277
  }
1196
- )
1278
+ ),
1279
+ /* @__PURE__ */ jsx9("span", { className: "grid-pager-page-size-label", children: messages.pageSizeLabel })
1197
1280
  ] })
1198
1281
  ]
1199
1282
  }
@@ -1891,10 +1974,10 @@ function CheckIcon() {
1891
1974
  function ChevronDownIcon() {
1892
1975
  return /* @__PURE__ */ jsx12(Icon, { children: /* @__PURE__ */ jsx12("path", { d: "m6 9 6 6 6-6" }) });
1893
1976
  }
1894
- function ChevronLeftIcon() {
1977
+ function ChevronLeftIcon2() {
1895
1978
  return /* @__PURE__ */ jsx12(Icon, { children: /* @__PURE__ */ jsx12("path", { d: "m15 18-6-6 6-6" }) });
1896
1979
  }
1897
- function ChevronRightIcon() {
1980
+ function ChevronRightIcon2() {
1898
1981
  return /* @__PURE__ */ jsx12(Icon, { children: /* @__PURE__ */ jsx12("path", { d: "m9 18 6-6-6-6" }) });
1899
1982
  }
1900
1983
 
@@ -1931,7 +2014,7 @@ function MenuItem({
1931
2014
  /* @__PURE__ */ jsx13("span", { className: "menu-item-icon", "aria-hidden": "true", children: checked === true ? /* @__PURE__ */ jsx13(CheckIcon, {}) : /* @__PURE__ */ jsx13(MenuIcon, { name: entry.icon }) }),
1932
2015
  /* @__PURE__ */ jsx13("span", { className: "menu-item-label", children: entry.label }),
1933
2016
  shortcut !== void 0 && /* @__PURE__ */ jsx13("span", { className: "menu-item-shortcut", "aria-hidden": "true", children: shortcut }),
1934
- !isItem2 && /* @__PURE__ */ jsx13("span", { className: "menu-submenu-indicator", "aria-hidden": "true", children: /* @__PURE__ */ jsx13(ChevronRightIcon, {}) })
2017
+ !isItem2 && /* @__PURE__ */ jsx13("span", { className: "menu-submenu-indicator", "aria-hidden": "true", children: /* @__PURE__ */ jsx13(ChevronRightIcon2, {}) })
1935
2018
  ]
1936
2019
  }
1937
2020
  );
@@ -2571,7 +2654,7 @@ function OperatorMenuButton({
2571
2654
  children: [
2572
2655
  /* @__PURE__ */ jsx16("span", { className: "filter-menu-submenu-icon", "aria-hidden": "true", children: active !== void 0 && /* @__PURE__ */ jsx16(CheckIcon, {}) }),
2573
2656
  label,
2574
- /* @__PURE__ */ jsx16("span", { className: "filter-menu-submenu-indicator", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(ChevronRightIcon, {}) })
2657
+ /* @__PURE__ */ jsx16("span", { className: "filter-menu-submenu-indicator", "aria-hidden": "true", children: /* @__PURE__ */ jsx16(ChevronRightIcon2, {}) })
2575
2658
  ]
2576
2659
  }
2577
2660
  ),
@@ -3078,7 +3161,7 @@ function ExcelFilterEditor({
3078
3161
  switchTo(null);
3079
3162
  },
3080
3163
  children: [
3081
- /* @__PURE__ */ jsx20("span", { className: "filter-menu-back-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx20(ChevronLeftIcon, {}) }),
3164
+ /* @__PURE__ */ jsx20("span", { className: "filter-menu-back-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx20(ChevronLeftIcon2, {}) }),
3082
3165
  messages.filterBackToValues
3083
3166
  ]
3084
3167
  }
@@ -4043,7 +4126,11 @@ function useGridController(options) {
4043
4126
  () => createGridController(options)
4044
4127
  );
4045
4128
  controller.setOptions(options);
4046
- const state = useSyncExternalStore2(controller.subscribe, controller.getState);
4129
+ const state = useSyncExternalStore2(
4130
+ controller.subscribe,
4131
+ controller.getState,
4132
+ controller.getState
4133
+ );
4047
4134
  return { controller, state, view: controller.getView() };
4048
4135
  }
4049
4136
 
@@ -4224,8 +4311,8 @@ function DataGrid(props) {
4224
4311
  const gridId = useId2();
4225
4312
  const announce = useLiveAnnouncer(viewportRef);
4226
4313
  const messages = useMemo5(
4227
- () => resolveMessages(messageOverrides),
4228
- [messageOverrides]
4314
+ () => resolveMessages(messageOverrides, locale),
4315
+ [messageOverrides, locale]
4229
4316
  );
4230
4317
  const { controller, state, view } = useGridController({
4231
4318
  ...props,
@@ -4502,6 +4589,7 @@ function DataGrid(props) {
4502
4589
  selection.columnMode === false ? "" : "selectable-columns",
4503
4590
  selection.cellMode === false ? "" : "selectable-cells"
4504
4591
  );
4592
+ const hasFooter = aggregates.length > 0;
4505
4593
  return /* @__PURE__ */ jsxs19("div", { className: "gridkit-data-grid-viewport", ref: viewportRef, children: [
4506
4594
  /* @__PURE__ */ jsx26(
4507
4595
  GridToolbar,
@@ -4535,7 +4623,7 @@ function DataGrid(props) {
4535
4623
  id: gridId,
4536
4624
  className: "gridkit-data-grid-tables",
4537
4625
  role: state.groupBy.length > 0 ? "treegrid" : "grid",
4538
- "aria-rowcount": view.displayRows.length + 1,
4626
+ "aria-rowcount": view.displayRows.length + (hasFooter ? 2 : 1),
4539
4627
  "aria-colcount": view.columns.length,
4540
4628
  ...ariaAttr(multiselectable, "aria-multiselectable", true),
4541
4629
  ...ariaAttr(labelledBy !== void 0, "aria-labelledby", labelledBy),
@@ -4564,6 +4652,7 @@ function DataGrid(props) {
4564
4652
  "table",
4565
4653
  {
4566
4654
  ref: headerTableRef,
4655
+ role: "presentation",
4567
4656
  style: { width: totalColumnWidth(view.columns) },
4568
4657
  className: classNames(gridTableClassName, "gridkit-data-grid-header"),
4569
4658
  children: [
@@ -4601,6 +4690,7 @@ function DataGrid(props) {
4601
4690
  "table",
4602
4691
  {
4603
4692
  ref: bodyTableRef,
4693
+ role: "presentation",
4604
4694
  style: { width: totalColumnWidth(view.columns) },
4605
4695
  className: gridTableClassName,
4606
4696
  children: [
@@ -4634,9 +4724,10 @@ function DataGrid(props) {
4634
4724
  )
4635
4725
  }
4636
4726
  ),
4637
- aggregates.length > 0 && /* @__PURE__ */ jsxs19(
4727
+ hasFooter && /* @__PURE__ */ jsxs19(
4638
4728
  "table",
4639
4729
  {
4730
+ role: "presentation",
4640
4731
  style: { width: totalColumnWidth(view.columns) },
4641
4732
  className: classNames(
4642
4733
  gridTableClassName,
@@ -4651,7 +4742,8 @@ function DataGrid(props) {
4651
4742
  aggregates,
4652
4743
  results: view.grandTotal,
4653
4744
  rows: view.rows.map((entry) => entry.row),
4654
- locale
4745
+ locale,
4746
+ ariaRowIndex: view.displayRows.length + 2
4655
4747
  }
4656
4748
  )
4657
4749
  ]
@@ -4694,10 +4786,14 @@ function useGridSnapshot(gridRef, getSnapshot, fallback) {
4694
4786
  },
4695
4787
  [gridRef]
4696
4788
  );
4697
- return useSyncExternalStore3(subscribe, () => {
4698
- const api = gridRef.current;
4699
- return api === null ? fallback : getSnapshot(api);
4700
- });
4789
+ return useSyncExternalStore3(
4790
+ subscribe,
4791
+ () => {
4792
+ const api = gridRef.current;
4793
+ return api === null ? fallback : getSnapshot(api);
4794
+ },
4795
+ () => fallback
4796
+ );
4701
4797
  }
4702
4798
 
4703
4799
  // src/DataGrid/hooks/usePaginationState.ts