@procore/data-table 14.46.2 → 14.46.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Change Log
2
2
 
3
+ ## 14.46.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 05247ae: Fix inconsistent keyboard focus management across Filters, Configure, and Bulk Edit panels
8
+ - Move focus to the panel container on open and return focus to the trigger button on close
9
+ - Add `role="region"` and `aria-label` to panel containers for screen reader announcements
10
+ - Centralize focus logic in `useContextPanel` hook, removing scattered per-panel implementations
11
+ - Updated dependencies [05247ae]
12
+ - @procore/toast-alert@5.2.0
13
+
3
14
  ## 14.46.2
4
15
 
5
16
  ### Patch Changes
@@ -1402,7 +1402,7 @@ ag-grid, ag-grid-angular, ag-grid-ng2, ag-grid-polymer, ag-grid-aurelia {
1402
1402
  animation-iteration-count: infinite;
1403
1403
  animation-name: ag-shake-left-to-right;
1404
1404
  }
1405
- @keyframes _ag-shake-left-to-right_1ern5_342 {
1405
+ @keyframes _ag-shake-left-to-right_pphrk_342 {
1406
1406
  from {
1407
1407
  padding-left: 6px;
1408
1408
  padding-right: 2px;
@@ -5403,7 +5403,7 @@ input[class^=ag-][type=button]:focus, button[class^=ag-]:focus {
5403
5403
  animation-iteration-count: infinite;
5404
5404
  animation-timing-function: linear;
5405
5405
  }
5406
- @keyframes _spin_1ern5_1 {
5406
+ @keyframes _spin_pphrk_1 {
5407
5407
  from {
5408
5408
  transform: rotate(0deg);
5409
5409
  }
@@ -7935,7 +7935,7 @@ input[class^=ag-][type=range]:disabled {
7935
7935
  padding-left: 16px;
7936
7936
  }
7937
7937
 
7938
- div._contextPanel_1ern5_7159 {
7938
+ div._contextPanel_pphrk_7159 {
7939
7939
  width: 400px;
7940
7940
  transition: all ease 500ms;
7941
7941
  flex: 0 0 auto;
@@ -7944,7 +7944,12 @@ div._contextPanel_1ern5_7159 {
7944
7944
  border: 1px solid #d6dadc;
7945
7945
  display: flex;
7946
7946
  }
7947
- div._contextPanel--hidden_1ern5_7168 {
7947
+ div._contextPanel_pphrk_7159:focus {
7948
+ border-color: #2066df;
7949
+ box-shadow: inset 0 0 1px 0 #2066df;
7950
+ outline: none;
7951
+ }
7952
+ div._contextPanel--hidden_pphrk_7173 {
7948
7953
  border: none;
7949
7954
  overflow: hidden;
7950
7955
  padding: 0px;
@@ -7952,50 +7957,50 @@ div._contextPanel--hidden_1ern5_7168 {
7952
7957
  width: 0px;
7953
7958
  }
7954
7959
 
7955
- ._contextPanelWrapper_1ern5_7176 {
7960
+ ._contextPanelWrapper_pphrk_7181 {
7956
7961
  position: relative;
7957
7962
  flex-grow: 1;
7958
7963
  }
7959
7964
 
7960
- ._contextPanelBody_1ern5_7181 {
7965
+ ._contextPanelBody_pphrk_7186 {
7961
7966
  width: clamp(380px, 400px, 100%);
7962
7967
  }
7963
7968
 
7964
- ._contextPanel-stickyHeader_1ern5_7185 {
7969
+ ._contextPanel-stickyHeader_pphrk_7190 {
7965
7970
  background-color: #ffffff;
7966
7971
  position: sticky;
7967
7972
  top: 0;
7968
7973
  z-index: 5;
7969
7974
  }
7970
7975
 
7971
- ._filters-list_1ern5_7192 {
7976
+ ._filters-list_pphrk_7197 {
7972
7977
  padding: 0;
7973
7978
  margin: 0;
7974
7979
  }
7975
- ._filters-list_1ern5_7192 ol {
7980
+ ._filters-list_pphrk_7197 ol {
7976
7981
  padding: 0;
7977
7982
  margin: 0;
7978
7983
  }
7979
7984
 
7980
- ._col-drag-column-icon_1ern5_7201 {
7985
+ ._col-drag-column-icon_pphrk_7206 {
7981
7986
  color: #6a767c;
7982
7987
  }
7983
7988
 
7984
- ._tabular-nums_1ern5_7205 {
7989
+ ._tabular-nums_pphrk_7210 {
7985
7990
  font-variant-numeric: tabular-nums;
7986
7991
  }`;
7987
7992
  document.head.appendChild(document.createElement("style")).appendChild(document.createTextNode(css));
7988
7993
  var styles_default = {
7989
- "contextPanel": "_contextPanel_1ern5_7159",
7990
- "contextPanel--hidden": "_contextPanel--hidden_1ern5_7168",
7991
- "contextPanelWrapper": "_contextPanelWrapper_1ern5_7176",
7992
- "contextPanelBody": "_contextPanelBody_1ern5_7181",
7993
- "contextPanel-stickyHeader": "_contextPanel-stickyHeader_1ern5_7185",
7994
- "filters-list": "_filters-list_1ern5_7192",
7995
- "col-drag-column-icon": "_col-drag-column-icon_1ern5_7201",
7996
- "tabular-nums": "_tabular-nums_1ern5_7205",
7997
- "ag-shake-left-to-right": "_ag-shake-left-to-right_1ern5_342",
7998
- "spin": "_spin_1ern5_1"
7994
+ "contextPanel": "_contextPanel_pphrk_7159",
7995
+ "contextPanel--hidden": "_contextPanel--hidden_pphrk_7173",
7996
+ "contextPanelWrapper": "_contextPanelWrapper_pphrk_7181",
7997
+ "contextPanelBody": "_contextPanelBody_pphrk_7186",
7998
+ "contextPanel-stickyHeader": "_contextPanel-stickyHeader_pphrk_7190",
7999
+ "filters-list": "_filters-list_pphrk_7197",
8000
+ "col-drag-column-icon": "_col-drag-column-icon_pphrk_7206",
8001
+ "tabular-nums": "_tabular-nums_pphrk_7210",
8002
+ "ag-shake-left-to-right": "_ag-shake-left-to-right_pphrk_342",
8003
+ "spin": "_spin_pphrk_1"
7999
8004
  };
8000
8005
 
8001
8006
  // src/CellRenderers/BooleanCell.tsx
@@ -58025,6 +58030,7 @@ var InternalTableContext = React80__default.default.createContext({
58025
58030
  hide: () => {
58026
58031
  },
58027
58032
  isVisible: false,
58033
+ panelRef: React80__default.default.createRef(),
58028
58034
  show: () => {
58029
58035
  }
58030
58036
  },
@@ -59829,14 +59835,16 @@ var useRowSelectionState = () => {
59829
59835
  var BulkEditActionButton = (props) => {
59830
59836
  const { contextPanel } = useInternalTableContext();
59831
59837
  const i18n = coreReact.useI18nContext();
59838
+ const buttonRef = React80__default.default.useRef(null);
59832
59839
  const editActionLabel = props.actionText ?? i18n.t("dataTable.bulkActions.editValues");
59833
59840
  return /* @__PURE__ */ React80__default.default.createElement(
59834
59841
  coreReact.Button,
59835
59842
  {
59843
+ ref: buttonRef,
59836
59844
  "aria-label": i18n.t("dataTable.bulkActions.bulkEdit"),
59837
59845
  "data-qa": "bulkEditIcon",
59838
59846
  icon: /* @__PURE__ */ React80__default.default.createElement(coreIcons.Pencil, null),
59839
- onClick: () => contextPanel.show("bulkEdit"),
59847
+ onClick: () => contextPanel.show("bulkEdit", buttonRef.current ?? void 0),
59840
59848
  variant: "tertiary"
59841
59849
  },
59842
59850
  props.showLabel && editActionLabel
@@ -104481,11 +104489,6 @@ var BulkEditPanel = ({}) => {
104481
104489
  const { contextPanel, suppressBulkEditToasts } = useInternalTableContext();
104482
104490
  const I18n = coreReact.useI18nContext();
104483
104491
  const bulkEditRef = React80__default.default.useRef(null);
104484
- const bodyRef = React80__default.default.useRef(null);
104485
- React80.useEffect(() => {
104486
- var _a;
104487
- (_a = bodyRef.current) == null ? void 0 : _a.focus();
104488
- }, []);
104489
104492
  return /* @__PURE__ */ React80__default.default.createElement(coreReact.Panel, null, /* @__PURE__ */ React80__default.default.createElement(
104490
104493
  coreReact.Panel.Header,
104491
104494
  {
@@ -104496,7 +104499,7 @@ var BulkEditPanel = ({}) => {
104496
104499
  }
104497
104500
  },
104498
104501
  /* @__PURE__ */ React80__default.default.createElement(coreReact.Panel.Title, null, I18n.t("dataTable.bulkActions.editValues"))
104499
- ), /* @__PURE__ */ React80__default.default.createElement(coreReact.Panel.Body, { ref: bodyRef }, /* @__PURE__ */ React80__default.default.createElement(coreReact.Panel.Section, null, /* @__PURE__ */ React80__default.default.createElement(
104502
+ ), /* @__PURE__ */ React80__default.default.createElement(coreReact.Panel.Body, null, /* @__PURE__ */ React80__default.default.createElement(coreReact.Panel.Section, null, /* @__PURE__ */ React80__default.default.createElement(
104500
104503
  BulkEdit,
104501
104504
  {
104502
104505
  ref: bulkEditRef,
@@ -104942,18 +104945,34 @@ var ConfigurationPanel = ({
104942
104945
  function useContextPanel() {
104943
104946
  const [content, setContent] = React80.useState();
104944
104947
  const visibility = coreReact.useVisibility({ afterHide: () => setContent(void 0) });
104945
- const show = React80.useCallback((panelContent) => {
104946
- setContent(panelContent);
104947
- visibility.show();
104948
- }, []);
104948
+ const triggerRef = React80.useRef(null);
104949
+ const panelRef = React80.useRef(null);
104950
+ const show = React80.useCallback(
104951
+ (panelContent, trigger) => {
104952
+ triggerRef.current = trigger ?? null;
104953
+ setContent(panelContent);
104954
+ visibility.show();
104955
+ },
104956
+ []
104957
+ );
104949
104958
  const hide = React80.useCallback(() => {
104959
+ const trigger = triggerRef.current;
104950
104960
  setContent(void 0);
104951
104961
  visibility.hide();
104962
+ trigger == null ? void 0 : trigger.focus();
104963
+ triggerRef.current = null;
104952
104964
  }, []);
104965
+ React80.useEffect(() => {
104966
+ var _a;
104967
+ if (content) {
104968
+ (_a = panelRef.current) == null ? void 0 : _a.focus();
104969
+ }
104970
+ }, [content]);
104953
104971
  return {
104954
104972
  content,
104955
104973
  hide,
104956
104974
  isVisible: visibility.isVisible,
104975
+ panelRef,
104957
104976
  show
104958
104977
  };
104959
104978
  }
@@ -111273,9 +111292,26 @@ var ContextPanel = ({
111273
111292
  ...props
111274
111293
  }) => {
111275
111294
  const { contextPanel } = useInternalTableContext();
111295
+ const I18n = coreReact.useI18nContext();
111296
+ const cardRef = React80__default.default.useRef(null);
111297
+ const panelLabelKeys = {
111298
+ configuration: "dataTable.tableSettings.tableSettings",
111299
+ bulkEdit: "dataTable.bulkActions.editValues"
111300
+ };
111301
+ const panelLabel = contextPanel.content ? panelLabelKeys[contextPanel.content] : void 0;
111302
+ const ariaLabel = panelLabel ? I18n.t(panelLabel) : void 0;
111303
+ React80__default.default.useLayoutEffect(() => {
111304
+ if (contextPanel.content && contextPanel.content !== "filters") {
111305
+ contextPanel.panelRef.current = cardRef.current;
111306
+ }
111307
+ }, [contextPanel.content, contextPanel.panelRef]);
111276
111308
  return /* @__PURE__ */ React80__default.default.createElement(
111277
111309
  coreReact.Card,
111278
111310
  {
111311
+ ref: cardRef,
111312
+ tabIndex: -1,
111313
+ role: "region",
111314
+ "aria-label": ariaLabel,
111279
111315
  className: cx19("contextPanel", className, {
111280
111316
  "contextPanel--hidden": !contextPanel.isVisible || contextPanel.content === "filters"
111281
111317
  }),
@@ -111548,19 +111584,27 @@ var BaseFiltersPanel = ({
111548
111584
  onClearAllFilters = noop5,
111549
111585
  ...props
111550
111586
  }) => {
111551
- const ref = React80__default.default.useRef(null);
111587
+ const cardRef = React80__default.default.useRef(null);
111552
111588
  const { contextPanel, filtersBodyId, filtersPanelId } = useInternalTableContext();
111553
111589
  const I18n = coreReact.useI18nContext();
111554
111590
  const hidden = !contextPanel.isVisible || contextPanel.content !== "filters";
111555
111591
  React80__default.default.useLayoutEffect(() => {
111556
- if (ref.current) {
111557
- ref.current.inert = hidden;
111592
+ if (contextPanel.content === "filters") {
111593
+ contextPanel.panelRef.current = cardRef.current;
111594
+ }
111595
+ }, [contextPanel.content, contextPanel.panelRef]);
111596
+ React80__default.default.useLayoutEffect(() => {
111597
+ if (cardRef.current) {
111598
+ cardRef.current.inert = hidden;
111558
111599
  }
111559
111600
  }, [hidden]);
111560
111601
  return /* @__PURE__ */ React80__default.default.createElement(
111561
111602
  coreReact.Card,
111562
111603
  {
111563
- ref,
111604
+ ref: cardRef,
111605
+ tabIndex: -1,
111606
+ role: "region",
111607
+ "aria-label": I18n.t("dataTable.filters.filters"),
111564
111608
  style: { maxHeight: "100vh" },
111565
111609
  className: cx20("contextPanel", className, {
111566
111610
  "contextPanel--hidden": hidden
@@ -111615,6 +111659,7 @@ var ConfigPanelButton = () => {
111615
111659
  const { contextPanel } = useInternalTableContext();
111616
111660
  const hasNoContent = useTableHasNoContent();
111617
111661
  const I18n = coreReact.useI18nContext();
111662
+ const buttonRef = React80__default.default.useRef(null);
111618
111663
  return /* @__PURE__ */ React80__default.default.createElement(
111619
111664
  EmptyResultsControlTooltip,
111620
111665
  {
@@ -111624,12 +111669,13 @@ var ConfigPanelButton = () => {
111624
111669
  /* @__PURE__ */ React80__default.default.createElement(
111625
111670
  coreReact.ToggleButton,
111626
111671
  {
111672
+ ref: buttonRef,
111627
111673
  disabled: hasNoContent,
111628
111674
  onClick: () => {
111629
111675
  if (contextPanel.content === "configuration") {
111630
111676
  contextPanel.hide();
111631
111677
  } else {
111632
- contextPanel.show("configuration");
111678
+ contextPanel.show("configuration", buttonRef.current ?? void 0);
111633
111679
  }
111634
111680
  },
111635
111681
  icon: /* @__PURE__ */ React80__default.default.createElement(
@@ -112806,27 +112852,12 @@ var SingleSelectQuickFilterRenderer = (props) => {
112806
112852
  return /* @__PURE__ */ React80__default.default.createElement(ClientSideSingleSelectQuickFilter, { ...props });
112807
112853
  };
112808
112854
  var SingleSelectQuickFilterRenderer_default = SingleSelectQuickFilterRenderer;
112809
- var FOCUSABLE_SELECTOR2 = 'button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
112810
112855
  var FiltersPanelToggleButton = ({ hasDefinedFilters }) => {
112811
112856
  const I18n = coreReact.useI18nContext();
112812
- const { contextPanel, filtersBodyId, filtersPanelId } = useInternalTableContext();
112857
+ const { contextPanel, filtersPanelId } = useInternalTableContext();
112813
112858
  const hasNoContent = useTableHasNoContent();
112814
112859
  const buttonRef = React80__default.default.useRef(null);
112815
112860
  const isFiltersOpen = contextPanel.content === "filters";
112816
- const isMounted = React80__default.default.useRef(false);
112817
- React80__default.default.useEffect(() => {
112818
- var _a, _b;
112819
- if (!isMounted.current) {
112820
- isMounted.current = true;
112821
- return;
112822
- }
112823
- if (isFiltersOpen) {
112824
- const panel = filtersBodyId ? document.getElementById(filtersBodyId) : null;
112825
- (_a = panel == null ? void 0 : panel.querySelector(FOCUSABLE_SELECTOR2)) == null ? void 0 : _a.focus();
112826
- } else {
112827
- (_b = buttonRef.current) == null ? void 0 : _b.focus();
112828
- }
112829
- }, [isFiltersOpen, filtersBodyId]);
112830
112861
  if (!hasDefinedFilters) {
112831
112862
  return null;
112832
112863
  }
@@ -112847,7 +112878,7 @@ var FiltersPanelToggleButton = ({ hasDefinedFilters }) => {
112847
112878
  "aria-controls": filtersPanelId,
112848
112879
  onClick: () => {
112849
112880
  if (!isFiltersOpen) {
112850
- contextPanel.show("filters");
112881
+ contextPanel.show("filters", buttonRef.current ?? void 0);
112851
112882
  } else {
112852
112883
  contextPanel.hide();
112853
112884
  }
@@ -724,7 +724,8 @@ interface ContextPanelApi {
724
724
  content?: ContextPanelContent;
725
725
  hide: () => void;
726
726
  isVisible: boolean;
727
- show: (content: ContextPanelContent) => void;
727
+ panelRef: React.RefObject<HTMLElement>;
728
+ show: (content: ContextPanelContent, trigger?: HTMLElement) => void;
728
729
  }
729
730
  interface CustomFooterConfig {
730
731
  height?: RowSize;
@@ -724,7 +724,8 @@ interface ContextPanelApi {
724
724
  content?: ContextPanelContent;
725
725
  hide: () => void;
726
726
  isVisible: boolean;
727
- show: (content: ContextPanelContent) => void;
727
+ panelRef: React.RefObject<HTMLElement>;
728
+ show: (content: ContextPanelContent, trigger?: HTMLElement) => void;
728
729
  }
729
730
  interface CustomFooterConfig {
730
731
  height?: RowSize;
@@ -1389,7 +1389,7 @@ ag-grid, ag-grid-angular, ag-grid-ng2, ag-grid-polymer, ag-grid-aurelia {
1389
1389
  animation-iteration-count: infinite;
1390
1390
  animation-name: ag-shake-left-to-right;
1391
1391
  }
1392
- @keyframes _ag-shake-left-to-right_1ern5_342 {
1392
+ @keyframes _ag-shake-left-to-right_pphrk_342 {
1393
1393
  from {
1394
1394
  padding-left: 6px;
1395
1395
  padding-right: 2px;
@@ -5390,7 +5390,7 @@ input[class^=ag-][type=button]:focus, button[class^=ag-]:focus {
5390
5390
  animation-iteration-count: infinite;
5391
5391
  animation-timing-function: linear;
5392
5392
  }
5393
- @keyframes _spin_1ern5_1 {
5393
+ @keyframes _spin_pphrk_1 {
5394
5394
  from {
5395
5395
  transform: rotate(0deg);
5396
5396
  }
@@ -7922,7 +7922,7 @@ input[class^=ag-][type=range]:disabled {
7922
7922
  padding-left: 16px;
7923
7923
  }
7924
7924
 
7925
- div._contextPanel_1ern5_7159 {
7925
+ div._contextPanel_pphrk_7159 {
7926
7926
  width: 400px;
7927
7927
  transition: all ease 500ms;
7928
7928
  flex: 0 0 auto;
@@ -7931,7 +7931,12 @@ div._contextPanel_1ern5_7159 {
7931
7931
  border: 1px solid #d6dadc;
7932
7932
  display: flex;
7933
7933
  }
7934
- div._contextPanel--hidden_1ern5_7168 {
7934
+ div._contextPanel_pphrk_7159:focus {
7935
+ border-color: #2066df;
7936
+ box-shadow: inset 0 0 1px 0 #2066df;
7937
+ outline: none;
7938
+ }
7939
+ div._contextPanel--hidden_pphrk_7173 {
7935
7940
  border: none;
7936
7941
  overflow: hidden;
7937
7942
  padding: 0px;
@@ -7939,50 +7944,50 @@ div._contextPanel--hidden_1ern5_7168 {
7939
7944
  width: 0px;
7940
7945
  }
7941
7946
 
7942
- ._contextPanelWrapper_1ern5_7176 {
7947
+ ._contextPanelWrapper_pphrk_7181 {
7943
7948
  position: relative;
7944
7949
  flex-grow: 1;
7945
7950
  }
7946
7951
 
7947
- ._contextPanelBody_1ern5_7181 {
7952
+ ._contextPanelBody_pphrk_7186 {
7948
7953
  width: clamp(380px, 400px, 100%);
7949
7954
  }
7950
7955
 
7951
- ._contextPanel-stickyHeader_1ern5_7185 {
7956
+ ._contextPanel-stickyHeader_pphrk_7190 {
7952
7957
  background-color: #ffffff;
7953
7958
  position: sticky;
7954
7959
  top: 0;
7955
7960
  z-index: 5;
7956
7961
  }
7957
7962
 
7958
- ._filters-list_1ern5_7192 {
7963
+ ._filters-list_pphrk_7197 {
7959
7964
  padding: 0;
7960
7965
  margin: 0;
7961
7966
  }
7962
- ._filters-list_1ern5_7192 ol {
7967
+ ._filters-list_pphrk_7197 ol {
7963
7968
  padding: 0;
7964
7969
  margin: 0;
7965
7970
  }
7966
7971
 
7967
- ._col-drag-column-icon_1ern5_7201 {
7972
+ ._col-drag-column-icon_pphrk_7206 {
7968
7973
  color: #6a767c;
7969
7974
  }
7970
7975
 
7971
- ._tabular-nums_1ern5_7205 {
7976
+ ._tabular-nums_pphrk_7210 {
7972
7977
  font-variant-numeric: tabular-nums;
7973
7978
  }`;
7974
7979
  document.head.appendChild(document.createElement("style")).appendChild(document.createTextNode(css));
7975
7980
  var styles_default = {
7976
- "contextPanel": "_contextPanel_1ern5_7159",
7977
- "contextPanel--hidden": "_contextPanel--hidden_1ern5_7168",
7978
- "contextPanelWrapper": "_contextPanelWrapper_1ern5_7176",
7979
- "contextPanelBody": "_contextPanelBody_1ern5_7181",
7980
- "contextPanel-stickyHeader": "_contextPanel-stickyHeader_1ern5_7185",
7981
- "filters-list": "_filters-list_1ern5_7192",
7982
- "col-drag-column-icon": "_col-drag-column-icon_1ern5_7201",
7983
- "tabular-nums": "_tabular-nums_1ern5_7205",
7984
- "ag-shake-left-to-right": "_ag-shake-left-to-right_1ern5_342",
7985
- "spin": "_spin_1ern5_1"
7981
+ "contextPanel": "_contextPanel_pphrk_7159",
7982
+ "contextPanel--hidden": "_contextPanel--hidden_pphrk_7173",
7983
+ "contextPanelWrapper": "_contextPanelWrapper_pphrk_7181",
7984
+ "contextPanelBody": "_contextPanelBody_pphrk_7186",
7985
+ "contextPanel-stickyHeader": "_contextPanel-stickyHeader_pphrk_7190",
7986
+ "filters-list": "_filters-list_pphrk_7197",
7987
+ "col-drag-column-icon": "_col-drag-column-icon_pphrk_7206",
7988
+ "tabular-nums": "_tabular-nums_pphrk_7210",
7989
+ "ag-shake-left-to-right": "_ag-shake-left-to-right_pphrk_342",
7990
+ "spin": "_spin_pphrk_1"
7986
7991
  };
7987
7992
 
7988
7993
  // src/CellRenderers/BooleanCell.tsx
@@ -58012,6 +58017,7 @@ var InternalTableContext = React80.createContext({
58012
58017
  hide: () => {
58013
58018
  },
58014
58019
  isVisible: false,
58020
+ panelRef: React80.createRef(),
58015
58021
  show: () => {
58016
58022
  }
58017
58023
  },
@@ -59816,14 +59822,16 @@ var useRowSelectionState = () => {
59816
59822
  var BulkEditActionButton = (props) => {
59817
59823
  const { contextPanel } = useInternalTableContext();
59818
59824
  const i18n = useI18nContext();
59825
+ const buttonRef = React80.useRef(null);
59819
59826
  const editActionLabel = props.actionText ?? i18n.t("dataTable.bulkActions.editValues");
59820
59827
  return /* @__PURE__ */ React80.createElement(
59821
59828
  Button,
59822
59829
  {
59830
+ ref: buttonRef,
59823
59831
  "aria-label": i18n.t("dataTable.bulkActions.bulkEdit"),
59824
59832
  "data-qa": "bulkEditIcon",
59825
59833
  icon: /* @__PURE__ */ React80.createElement(Pencil, null),
59826
- onClick: () => contextPanel.show("bulkEdit"),
59834
+ onClick: () => contextPanel.show("bulkEdit", buttonRef.current ?? void 0),
59827
59835
  variant: "tertiary"
59828
59836
  },
59829
59837
  props.showLabel && editActionLabel
@@ -104468,11 +104476,6 @@ var BulkEditPanel = ({}) => {
104468
104476
  const { contextPanel, suppressBulkEditToasts } = useInternalTableContext();
104469
104477
  const I18n = useI18nContext();
104470
104478
  const bulkEditRef = React80.useRef(null);
104471
- const bodyRef = React80.useRef(null);
104472
- useEffect(() => {
104473
- var _a;
104474
- (_a = bodyRef.current) == null ? void 0 : _a.focus();
104475
- }, []);
104476
104479
  return /* @__PURE__ */ React80.createElement(Panel, null, /* @__PURE__ */ React80.createElement(
104477
104480
  Panel.Header,
104478
104481
  {
@@ -104483,7 +104486,7 @@ var BulkEditPanel = ({}) => {
104483
104486
  }
104484
104487
  },
104485
104488
  /* @__PURE__ */ React80.createElement(Panel.Title, null, I18n.t("dataTable.bulkActions.editValues"))
104486
- ), /* @__PURE__ */ React80.createElement(Panel.Body, { ref: bodyRef }, /* @__PURE__ */ React80.createElement(Panel.Section, null, /* @__PURE__ */ React80.createElement(
104489
+ ), /* @__PURE__ */ React80.createElement(Panel.Body, null, /* @__PURE__ */ React80.createElement(Panel.Section, null, /* @__PURE__ */ React80.createElement(
104487
104490
  BulkEdit,
104488
104491
  {
104489
104492
  ref: bulkEditRef,
@@ -104929,18 +104932,34 @@ var ConfigurationPanel = ({
104929
104932
  function useContextPanel() {
104930
104933
  const [content, setContent] = useState();
104931
104934
  const visibility = useVisibility({ afterHide: () => setContent(void 0) });
104932
- const show = useCallback((panelContent) => {
104933
- setContent(panelContent);
104934
- visibility.show();
104935
- }, []);
104935
+ const triggerRef = useRef(null);
104936
+ const panelRef = useRef(null);
104937
+ const show = useCallback(
104938
+ (panelContent, trigger) => {
104939
+ triggerRef.current = trigger ?? null;
104940
+ setContent(panelContent);
104941
+ visibility.show();
104942
+ },
104943
+ []
104944
+ );
104936
104945
  const hide = useCallback(() => {
104946
+ const trigger = triggerRef.current;
104937
104947
  setContent(void 0);
104938
104948
  visibility.hide();
104949
+ trigger == null ? void 0 : trigger.focus();
104950
+ triggerRef.current = null;
104939
104951
  }, []);
104952
+ useEffect(() => {
104953
+ var _a;
104954
+ if (content) {
104955
+ (_a = panelRef.current) == null ? void 0 : _a.focus();
104956
+ }
104957
+ }, [content]);
104940
104958
  return {
104941
104959
  content,
104942
104960
  hide,
104943
104961
  isVisible: visibility.isVisible,
104962
+ panelRef,
104944
104963
  show
104945
104964
  };
104946
104965
  }
@@ -111260,9 +111279,26 @@ var ContextPanel = ({
111260
111279
  ...props
111261
111280
  }) => {
111262
111281
  const { contextPanel } = useInternalTableContext();
111282
+ const I18n = useI18nContext();
111283
+ const cardRef = React80.useRef(null);
111284
+ const panelLabelKeys = {
111285
+ configuration: "dataTable.tableSettings.tableSettings",
111286
+ bulkEdit: "dataTable.bulkActions.editValues"
111287
+ };
111288
+ const panelLabel = contextPanel.content ? panelLabelKeys[contextPanel.content] : void 0;
111289
+ const ariaLabel = panelLabel ? I18n.t(panelLabel) : void 0;
111290
+ React80.useLayoutEffect(() => {
111291
+ if (contextPanel.content && contextPanel.content !== "filters") {
111292
+ contextPanel.panelRef.current = cardRef.current;
111293
+ }
111294
+ }, [contextPanel.content, contextPanel.panelRef]);
111263
111295
  return /* @__PURE__ */ React80.createElement(
111264
111296
  Card,
111265
111297
  {
111298
+ ref: cardRef,
111299
+ tabIndex: -1,
111300
+ role: "region",
111301
+ "aria-label": ariaLabel,
111266
111302
  className: cx19("contextPanel", className, {
111267
111303
  "contextPanel--hidden": !contextPanel.isVisible || contextPanel.content === "filters"
111268
111304
  }),
@@ -111535,19 +111571,27 @@ var BaseFiltersPanel = ({
111535
111571
  onClearAllFilters = noop5,
111536
111572
  ...props
111537
111573
  }) => {
111538
- const ref = React80.useRef(null);
111574
+ const cardRef = React80.useRef(null);
111539
111575
  const { contextPanel, filtersBodyId, filtersPanelId } = useInternalTableContext();
111540
111576
  const I18n = useI18nContext();
111541
111577
  const hidden = !contextPanel.isVisible || contextPanel.content !== "filters";
111542
111578
  React80.useLayoutEffect(() => {
111543
- if (ref.current) {
111544
- ref.current.inert = hidden;
111579
+ if (contextPanel.content === "filters") {
111580
+ contextPanel.panelRef.current = cardRef.current;
111581
+ }
111582
+ }, [contextPanel.content, contextPanel.panelRef]);
111583
+ React80.useLayoutEffect(() => {
111584
+ if (cardRef.current) {
111585
+ cardRef.current.inert = hidden;
111545
111586
  }
111546
111587
  }, [hidden]);
111547
111588
  return /* @__PURE__ */ React80.createElement(
111548
111589
  Card,
111549
111590
  {
111550
- ref,
111591
+ ref: cardRef,
111592
+ tabIndex: -1,
111593
+ role: "region",
111594
+ "aria-label": I18n.t("dataTable.filters.filters"),
111551
111595
  style: { maxHeight: "100vh" },
111552
111596
  className: cx20("contextPanel", className, {
111553
111597
  "contextPanel--hidden": hidden
@@ -111602,6 +111646,7 @@ var ConfigPanelButton = () => {
111602
111646
  const { contextPanel } = useInternalTableContext();
111603
111647
  const hasNoContent = useTableHasNoContent();
111604
111648
  const I18n = useI18nContext();
111649
+ const buttonRef = React80.useRef(null);
111605
111650
  return /* @__PURE__ */ React80.createElement(
111606
111651
  EmptyResultsControlTooltip,
111607
111652
  {
@@ -111611,12 +111656,13 @@ var ConfigPanelButton = () => {
111611
111656
  /* @__PURE__ */ React80.createElement(
111612
111657
  ToggleButton,
111613
111658
  {
111659
+ ref: buttonRef,
111614
111660
  disabled: hasNoContent,
111615
111661
  onClick: () => {
111616
111662
  if (contextPanel.content === "configuration") {
111617
111663
  contextPanel.hide();
111618
111664
  } else {
111619
- contextPanel.show("configuration");
111665
+ contextPanel.show("configuration", buttonRef.current ?? void 0);
111620
111666
  }
111621
111667
  },
111622
111668
  icon: /* @__PURE__ */ React80.createElement(
@@ -112793,27 +112839,12 @@ var SingleSelectQuickFilterRenderer = (props) => {
112793
112839
  return /* @__PURE__ */ React80.createElement(ClientSideSingleSelectQuickFilter, { ...props });
112794
112840
  };
112795
112841
  var SingleSelectQuickFilterRenderer_default = SingleSelectQuickFilterRenderer;
112796
- var FOCUSABLE_SELECTOR2 = 'button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
112797
112842
  var FiltersPanelToggleButton = ({ hasDefinedFilters }) => {
112798
112843
  const I18n = useI18nContext();
112799
- const { contextPanel, filtersBodyId, filtersPanelId } = useInternalTableContext();
112844
+ const { contextPanel, filtersPanelId } = useInternalTableContext();
112800
112845
  const hasNoContent = useTableHasNoContent();
112801
112846
  const buttonRef = React80.useRef(null);
112802
112847
  const isFiltersOpen = contextPanel.content === "filters";
112803
- const isMounted = React80.useRef(false);
112804
- React80.useEffect(() => {
112805
- var _a, _b;
112806
- if (!isMounted.current) {
112807
- isMounted.current = true;
112808
- return;
112809
- }
112810
- if (isFiltersOpen) {
112811
- const panel = filtersBodyId ? document.getElementById(filtersBodyId) : null;
112812
- (_a = panel == null ? void 0 : panel.querySelector(FOCUSABLE_SELECTOR2)) == null ? void 0 : _a.focus();
112813
- } else {
112814
- (_b = buttonRef.current) == null ? void 0 : _b.focus();
112815
- }
112816
- }, [isFiltersOpen, filtersBodyId]);
112817
112848
  if (!hasDefinedFilters) {
112818
112849
  return null;
112819
112850
  }
@@ -112834,7 +112865,7 @@ var FiltersPanelToggleButton = ({ hasDefinedFilters }) => {
112834
112865
  "aria-controls": filtersPanelId,
112835
112866
  onClick: () => {
112836
112867
  if (!isFiltersOpen) {
112837
- contextPanel.show("filters");
112868
+ contextPanel.show("filters", buttonRef.current ?? void 0);
112838
112869
  } else {
112839
112870
  contextPanel.hide();
112840
112871
  }
@@ -1400,7 +1400,7 @@ ag-grid, ag-grid-angular, ag-grid-ng2, ag-grid-polymer, ag-grid-aurelia {
1400
1400
  animation-iteration-count: infinite;
1401
1401
  animation-name: ag-shake-left-to-right;
1402
1402
  }
1403
- @keyframes _ag-shake-left-to-right_1ern5_342 {
1403
+ @keyframes _ag-shake-left-to-right_pphrk_342 {
1404
1404
  from {
1405
1405
  padding-left: 6px;
1406
1406
  padding-right: 2px;
@@ -5401,7 +5401,7 @@ input[class^=ag-][type=button]:focus, button[class^=ag-]:focus {
5401
5401
  animation-iteration-count: infinite;
5402
5402
  animation-timing-function: linear;
5403
5403
  }
5404
- @keyframes _spin_1ern5_1 {
5404
+ @keyframes _spin_pphrk_1 {
5405
5405
  from {
5406
5406
  transform: rotate(0deg);
5407
5407
  }
@@ -7933,7 +7933,7 @@ input[class^=ag-][type=range]:disabled {
7933
7933
  padding-left: 16px;
7934
7934
  }
7935
7935
 
7936
- div._contextPanel_1ern5_7159 {
7936
+ div._contextPanel_pphrk_7159 {
7937
7937
  width: 400px;
7938
7938
  transition: all ease 500ms;
7939
7939
  flex: 0 0 auto;
@@ -7942,7 +7942,12 @@ div._contextPanel_1ern5_7159 {
7942
7942
  border: 1px solid #d6dadc;
7943
7943
  display: flex;
7944
7944
  }
7945
- div._contextPanel--hidden_1ern5_7168 {
7945
+ div._contextPanel_pphrk_7159:focus {
7946
+ border-color: #2066df;
7947
+ box-shadow: inset 0 0 1px 0 #2066df;
7948
+ outline: none;
7949
+ }
7950
+ div._contextPanel--hidden_pphrk_7173 {
7946
7951
  border: none;
7947
7952
  overflow: hidden;
7948
7953
  padding: 0px;
@@ -7950,50 +7955,50 @@ div._contextPanel--hidden_1ern5_7168 {
7950
7955
  width: 0px;
7951
7956
  }
7952
7957
 
7953
- ._contextPanelWrapper_1ern5_7176 {
7958
+ ._contextPanelWrapper_pphrk_7181 {
7954
7959
  position: relative;
7955
7960
  flex-grow: 1;
7956
7961
  }
7957
7962
 
7958
- ._contextPanelBody_1ern5_7181 {
7963
+ ._contextPanelBody_pphrk_7186 {
7959
7964
  width: clamp(380px, 400px, 100%);
7960
7965
  }
7961
7966
 
7962
- ._contextPanel-stickyHeader_1ern5_7185 {
7967
+ ._contextPanel-stickyHeader_pphrk_7190 {
7963
7968
  background-color: #ffffff;
7964
7969
  position: sticky;
7965
7970
  top: 0;
7966
7971
  z-index: 5;
7967
7972
  }
7968
7973
 
7969
- ._filters-list_1ern5_7192 {
7974
+ ._filters-list_pphrk_7197 {
7970
7975
  padding: 0;
7971
7976
  margin: 0;
7972
7977
  }
7973
- ._filters-list_1ern5_7192 ol {
7978
+ ._filters-list_pphrk_7197 ol {
7974
7979
  padding: 0;
7975
7980
  margin: 0;
7976
7981
  }
7977
7982
 
7978
- ._col-drag-column-icon_1ern5_7201 {
7983
+ ._col-drag-column-icon_pphrk_7206 {
7979
7984
  color: #6a767c;
7980
7985
  }
7981
7986
 
7982
- ._tabular-nums_1ern5_7205 {
7987
+ ._tabular-nums_pphrk_7210 {
7983
7988
  font-variant-numeric: tabular-nums;
7984
7989
  }`;
7985
7990
  document.head.appendChild(document.createElement("style")).appendChild(document.createTextNode(css));
7986
7991
  var styles_default = {
7987
- "contextPanel": "_contextPanel_1ern5_7159",
7988
- "contextPanel--hidden": "_contextPanel--hidden_1ern5_7168",
7989
- "contextPanelWrapper": "_contextPanelWrapper_1ern5_7176",
7990
- "contextPanelBody": "_contextPanelBody_1ern5_7181",
7991
- "contextPanel-stickyHeader": "_contextPanel-stickyHeader_1ern5_7185",
7992
- "filters-list": "_filters-list_1ern5_7192",
7993
- "col-drag-column-icon": "_col-drag-column-icon_1ern5_7201",
7994
- "tabular-nums": "_tabular-nums_1ern5_7205",
7995
- "ag-shake-left-to-right": "_ag-shake-left-to-right_1ern5_342",
7996
- "spin": "_spin_1ern5_1"
7992
+ "contextPanel": "_contextPanel_pphrk_7159",
7993
+ "contextPanel--hidden": "_contextPanel--hidden_pphrk_7173",
7994
+ "contextPanelWrapper": "_contextPanelWrapper_pphrk_7181",
7995
+ "contextPanelBody": "_contextPanelBody_pphrk_7186",
7996
+ "contextPanel-stickyHeader": "_contextPanel-stickyHeader_pphrk_7190",
7997
+ "filters-list": "_filters-list_pphrk_7197",
7998
+ "col-drag-column-icon": "_col-drag-column-icon_pphrk_7206",
7999
+ "tabular-nums": "_tabular-nums_pphrk_7210",
8000
+ "ag-shake-left-to-right": "_ag-shake-left-to-right_pphrk_342",
8001
+ "spin": "_spin_pphrk_1"
7997
8002
  };
7998
8003
 
7999
8004
  // src/CellRenderers/BooleanCell.tsx
@@ -57916,6 +57921,7 @@ var InternalTableContext = React80__default.default.createContext({
57916
57921
  hide: () => {
57917
57922
  },
57918
57923
  isVisible: false,
57924
+ panelRef: React80__default.default.createRef(),
57919
57925
  show: () => {
57920
57926
  }
57921
57927
  },
@@ -59719,14 +59725,16 @@ var useRowSelectionState = () => {
59719
59725
  var BulkEditActionButton = (props) => {
59720
59726
  const { contextPanel } = useInternalTableContext();
59721
59727
  const i18n = coreReact.useI18nContext();
59728
+ const buttonRef = React80__default.default.useRef(null);
59722
59729
  const editActionLabel = props.actionText ?? i18n.t("dataTable.bulkActions.editValues");
59723
59730
  return /* @__PURE__ */ React80__default.default.createElement(
59724
59731
  coreReact.Button,
59725
59732
  {
59733
+ ref: buttonRef,
59726
59734
  "aria-label": i18n.t("dataTable.bulkActions.bulkEdit"),
59727
59735
  "data-qa": "bulkEditIcon",
59728
59736
  icon: /* @__PURE__ */ React80__default.default.createElement(coreIcons.Pencil, null),
59729
- onClick: () => contextPanel.show("bulkEdit"),
59737
+ onClick: () => contextPanel.show("bulkEdit", buttonRef.current ?? void 0),
59730
59738
  variant: "tertiary"
59731
59739
  },
59732
59740
  props.showLabel && editActionLabel
@@ -104353,10 +104361,6 @@ var BulkEditPanel = ({}) => {
104353
104361
  const { contextPanel, suppressBulkEditToasts } = useInternalTableContext();
104354
104362
  const I18n = coreReact.useI18nContext();
104355
104363
  const bulkEditRef = React80__default.default.useRef(null);
104356
- const bodyRef = React80__default.default.useRef(null);
104357
- React80.useEffect(() => {
104358
- bodyRef.current?.focus();
104359
- }, []);
104360
104364
  return /* @__PURE__ */ React80__default.default.createElement(coreReact.Panel, null, /* @__PURE__ */ React80__default.default.createElement(
104361
104365
  coreReact.Panel.Header,
104362
104366
  {
@@ -104366,7 +104370,7 @@ var BulkEditPanel = ({}) => {
104366
104370
  }
104367
104371
  },
104368
104372
  /* @__PURE__ */ React80__default.default.createElement(coreReact.Panel.Title, null, I18n.t("dataTable.bulkActions.editValues"))
104369
- ), /* @__PURE__ */ React80__default.default.createElement(coreReact.Panel.Body, { ref: bodyRef }, /* @__PURE__ */ React80__default.default.createElement(coreReact.Panel.Section, null, /* @__PURE__ */ React80__default.default.createElement(
104373
+ ), /* @__PURE__ */ React80__default.default.createElement(coreReact.Panel.Body, null, /* @__PURE__ */ React80__default.default.createElement(coreReact.Panel.Section, null, /* @__PURE__ */ React80__default.default.createElement(
104370
104374
  BulkEdit,
104371
104375
  {
104372
104376
  ref: bulkEditRef,
@@ -104801,18 +104805,33 @@ var ConfigurationPanel = ({
104801
104805
  function useContextPanel() {
104802
104806
  const [content, setContent] = React80.useState();
104803
104807
  const visibility = coreReact.useVisibility({ afterHide: () => setContent(void 0) });
104804
- const show = React80.useCallback((panelContent) => {
104805
- setContent(panelContent);
104806
- visibility.show();
104807
- }, []);
104808
+ const triggerRef = React80.useRef(null);
104809
+ const panelRef = React80.useRef(null);
104810
+ const show = React80.useCallback(
104811
+ (panelContent, trigger) => {
104812
+ triggerRef.current = trigger ?? null;
104813
+ setContent(panelContent);
104814
+ visibility.show();
104815
+ },
104816
+ []
104817
+ );
104808
104818
  const hide = React80.useCallback(() => {
104819
+ const trigger = triggerRef.current;
104809
104820
  setContent(void 0);
104810
104821
  visibility.hide();
104822
+ trigger?.focus();
104823
+ triggerRef.current = null;
104811
104824
  }, []);
104825
+ React80.useEffect(() => {
104826
+ if (content) {
104827
+ panelRef.current?.focus();
104828
+ }
104829
+ }, [content]);
104812
104830
  return {
104813
104831
  content,
104814
104832
  hide,
104815
104833
  isVisible: visibility.isVisible,
104834
+ panelRef,
104816
104835
  show
104817
104836
  };
104818
104837
  }
@@ -111076,9 +111095,26 @@ var ContextPanel = ({
111076
111095
  ...props
111077
111096
  }) => {
111078
111097
  const { contextPanel } = useInternalTableContext();
111098
+ const I18n = coreReact.useI18nContext();
111099
+ const cardRef = React80__default.default.useRef(null);
111100
+ const panelLabelKeys = {
111101
+ configuration: "dataTable.tableSettings.tableSettings",
111102
+ bulkEdit: "dataTable.bulkActions.editValues"
111103
+ };
111104
+ const panelLabel = contextPanel.content ? panelLabelKeys[contextPanel.content] : void 0;
111105
+ const ariaLabel = panelLabel ? I18n.t(panelLabel) : void 0;
111106
+ React80__default.default.useLayoutEffect(() => {
111107
+ if (contextPanel.content && contextPanel.content !== "filters") {
111108
+ contextPanel.panelRef.current = cardRef.current;
111109
+ }
111110
+ }, [contextPanel.content, contextPanel.panelRef]);
111079
111111
  return /* @__PURE__ */ React80__default.default.createElement(
111080
111112
  coreReact.Card,
111081
111113
  {
111114
+ ref: cardRef,
111115
+ tabIndex: -1,
111116
+ role: "region",
111117
+ "aria-label": ariaLabel,
111082
111118
  className: cx19("contextPanel", className, {
111083
111119
  "contextPanel--hidden": !contextPanel.isVisible || contextPanel.content === "filters"
111084
111120
  }),
@@ -111350,19 +111386,27 @@ var BaseFiltersPanel = ({
111350
111386
  onClearAllFilters = noop5,
111351
111387
  ...props
111352
111388
  }) => {
111353
- const ref = React80__default.default.useRef(null);
111389
+ const cardRef = React80__default.default.useRef(null);
111354
111390
  const { contextPanel, filtersBodyId, filtersPanelId } = useInternalTableContext();
111355
111391
  const I18n = coreReact.useI18nContext();
111356
111392
  const hidden = !contextPanel.isVisible || contextPanel.content !== "filters";
111357
111393
  React80__default.default.useLayoutEffect(() => {
111358
- if (ref.current) {
111359
- ref.current.inert = hidden;
111394
+ if (contextPanel.content === "filters") {
111395
+ contextPanel.panelRef.current = cardRef.current;
111396
+ }
111397
+ }, [contextPanel.content, contextPanel.panelRef]);
111398
+ React80__default.default.useLayoutEffect(() => {
111399
+ if (cardRef.current) {
111400
+ cardRef.current.inert = hidden;
111360
111401
  }
111361
111402
  }, [hidden]);
111362
111403
  return /* @__PURE__ */ React80__default.default.createElement(
111363
111404
  coreReact.Card,
111364
111405
  {
111365
- ref,
111406
+ ref: cardRef,
111407
+ tabIndex: -1,
111408
+ role: "region",
111409
+ "aria-label": I18n.t("dataTable.filters.filters"),
111366
111410
  style: { maxHeight: "100vh" },
111367
111411
  className: cx20("contextPanel", className, {
111368
111412
  "contextPanel--hidden": hidden
@@ -111416,6 +111460,7 @@ var ConfigPanelButton = () => {
111416
111460
  const { contextPanel } = useInternalTableContext();
111417
111461
  const hasNoContent = useTableHasNoContent();
111418
111462
  const I18n = coreReact.useI18nContext();
111463
+ const buttonRef = React80__default.default.useRef(null);
111419
111464
  return /* @__PURE__ */ React80__default.default.createElement(
111420
111465
  EmptyResultsControlTooltip,
111421
111466
  {
@@ -111425,12 +111470,13 @@ var ConfigPanelButton = () => {
111425
111470
  /* @__PURE__ */ React80__default.default.createElement(
111426
111471
  coreReact.ToggleButton,
111427
111472
  {
111473
+ ref: buttonRef,
111428
111474
  disabled: hasNoContent,
111429
111475
  onClick: () => {
111430
111476
  if (contextPanel.content === "configuration") {
111431
111477
  contextPanel.hide();
111432
111478
  } else {
111433
- contextPanel.show("configuration");
111479
+ contextPanel.show("configuration", buttonRef.current ?? void 0);
111434
111480
  }
111435
111481
  },
111436
111482
  icon: /* @__PURE__ */ React80__default.default.createElement(
@@ -112583,26 +112629,12 @@ var SingleSelectQuickFilterRenderer = (props) => {
112583
112629
  return /* @__PURE__ */ React80__default.default.createElement(ClientSideSingleSelectQuickFilter, { ...props });
112584
112630
  };
112585
112631
  var SingleSelectQuickFilterRenderer_default = SingleSelectQuickFilterRenderer;
112586
- var FOCUSABLE_SELECTOR2 = 'button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
112587
112632
  var FiltersPanelToggleButton = ({ hasDefinedFilters }) => {
112588
112633
  const I18n = coreReact.useI18nContext();
112589
- const { contextPanel, filtersBodyId, filtersPanelId } = useInternalTableContext();
112634
+ const { contextPanel, filtersPanelId } = useInternalTableContext();
112590
112635
  const hasNoContent = useTableHasNoContent();
112591
112636
  const buttonRef = React80__default.default.useRef(null);
112592
112637
  const isFiltersOpen = contextPanel.content === "filters";
112593
- const isMounted = React80__default.default.useRef(false);
112594
- React80__default.default.useEffect(() => {
112595
- if (!isMounted.current) {
112596
- isMounted.current = true;
112597
- return;
112598
- }
112599
- if (isFiltersOpen) {
112600
- const panel = filtersBodyId ? document.getElementById(filtersBodyId) : null;
112601
- panel?.querySelector(FOCUSABLE_SELECTOR2)?.focus();
112602
- } else {
112603
- buttonRef.current?.focus();
112604
- }
112605
- }, [isFiltersOpen, filtersBodyId]);
112606
112638
  if (!hasDefinedFilters) {
112607
112639
  return null;
112608
112640
  }
@@ -112623,7 +112655,7 @@ var FiltersPanelToggleButton = ({ hasDefinedFilters }) => {
112623
112655
  "aria-controls": filtersPanelId,
112624
112656
  onClick: () => {
112625
112657
  if (!isFiltersOpen) {
112626
- contextPanel.show("filters");
112658
+ contextPanel.show("filters", buttonRef.current ?? void 0);
112627
112659
  } else {
112628
112660
  contextPanel.hide();
112629
112661
  }
@@ -724,7 +724,8 @@ interface ContextPanelApi {
724
724
  content?: ContextPanelContent;
725
725
  hide: () => void;
726
726
  isVisible: boolean;
727
- show: (content: ContextPanelContent) => void;
727
+ panelRef: React.RefObject<HTMLElement>;
728
+ show: (content: ContextPanelContent, trigger?: HTMLElement) => void;
728
729
  }
729
730
  interface CustomFooterConfig {
730
731
  height?: RowSize;
@@ -724,7 +724,8 @@ interface ContextPanelApi {
724
724
  content?: ContextPanelContent;
725
725
  hide: () => void;
726
726
  isVisible: boolean;
727
- show: (content: ContextPanelContent) => void;
727
+ panelRef: React.RefObject<HTMLElement>;
728
+ show: (content: ContextPanelContent, trigger?: HTMLElement) => void;
728
729
  }
729
730
  interface CustomFooterConfig {
730
731
  height?: RowSize;
@@ -1387,7 +1387,7 @@ ag-grid, ag-grid-angular, ag-grid-ng2, ag-grid-polymer, ag-grid-aurelia {
1387
1387
  animation-iteration-count: infinite;
1388
1388
  animation-name: ag-shake-left-to-right;
1389
1389
  }
1390
- @keyframes _ag-shake-left-to-right_1ern5_342 {
1390
+ @keyframes _ag-shake-left-to-right_pphrk_342 {
1391
1391
  from {
1392
1392
  padding-left: 6px;
1393
1393
  padding-right: 2px;
@@ -5388,7 +5388,7 @@ input[class^=ag-][type=button]:focus, button[class^=ag-]:focus {
5388
5388
  animation-iteration-count: infinite;
5389
5389
  animation-timing-function: linear;
5390
5390
  }
5391
- @keyframes _spin_1ern5_1 {
5391
+ @keyframes _spin_pphrk_1 {
5392
5392
  from {
5393
5393
  transform: rotate(0deg);
5394
5394
  }
@@ -7920,7 +7920,7 @@ input[class^=ag-][type=range]:disabled {
7920
7920
  padding-left: 16px;
7921
7921
  }
7922
7922
 
7923
- div._contextPanel_1ern5_7159 {
7923
+ div._contextPanel_pphrk_7159 {
7924
7924
  width: 400px;
7925
7925
  transition: all ease 500ms;
7926
7926
  flex: 0 0 auto;
@@ -7929,7 +7929,12 @@ div._contextPanel_1ern5_7159 {
7929
7929
  border: 1px solid #d6dadc;
7930
7930
  display: flex;
7931
7931
  }
7932
- div._contextPanel--hidden_1ern5_7168 {
7932
+ div._contextPanel_pphrk_7159:focus {
7933
+ border-color: #2066df;
7934
+ box-shadow: inset 0 0 1px 0 #2066df;
7935
+ outline: none;
7936
+ }
7937
+ div._contextPanel--hidden_pphrk_7173 {
7933
7938
  border: none;
7934
7939
  overflow: hidden;
7935
7940
  padding: 0px;
@@ -7937,50 +7942,50 @@ div._contextPanel--hidden_1ern5_7168 {
7937
7942
  width: 0px;
7938
7943
  }
7939
7944
 
7940
- ._contextPanelWrapper_1ern5_7176 {
7945
+ ._contextPanelWrapper_pphrk_7181 {
7941
7946
  position: relative;
7942
7947
  flex-grow: 1;
7943
7948
  }
7944
7949
 
7945
- ._contextPanelBody_1ern5_7181 {
7950
+ ._contextPanelBody_pphrk_7186 {
7946
7951
  width: clamp(380px, 400px, 100%);
7947
7952
  }
7948
7953
 
7949
- ._contextPanel-stickyHeader_1ern5_7185 {
7954
+ ._contextPanel-stickyHeader_pphrk_7190 {
7950
7955
  background-color: #ffffff;
7951
7956
  position: sticky;
7952
7957
  top: 0;
7953
7958
  z-index: 5;
7954
7959
  }
7955
7960
 
7956
- ._filters-list_1ern5_7192 {
7961
+ ._filters-list_pphrk_7197 {
7957
7962
  padding: 0;
7958
7963
  margin: 0;
7959
7964
  }
7960
- ._filters-list_1ern5_7192 ol {
7965
+ ._filters-list_pphrk_7197 ol {
7961
7966
  padding: 0;
7962
7967
  margin: 0;
7963
7968
  }
7964
7969
 
7965
- ._col-drag-column-icon_1ern5_7201 {
7970
+ ._col-drag-column-icon_pphrk_7206 {
7966
7971
  color: #6a767c;
7967
7972
  }
7968
7973
 
7969
- ._tabular-nums_1ern5_7205 {
7974
+ ._tabular-nums_pphrk_7210 {
7970
7975
  font-variant-numeric: tabular-nums;
7971
7976
  }`;
7972
7977
  document.head.appendChild(document.createElement("style")).appendChild(document.createTextNode(css));
7973
7978
  var styles_default = {
7974
- "contextPanel": "_contextPanel_1ern5_7159",
7975
- "contextPanel--hidden": "_contextPanel--hidden_1ern5_7168",
7976
- "contextPanelWrapper": "_contextPanelWrapper_1ern5_7176",
7977
- "contextPanelBody": "_contextPanelBody_1ern5_7181",
7978
- "contextPanel-stickyHeader": "_contextPanel-stickyHeader_1ern5_7185",
7979
- "filters-list": "_filters-list_1ern5_7192",
7980
- "col-drag-column-icon": "_col-drag-column-icon_1ern5_7201",
7981
- "tabular-nums": "_tabular-nums_1ern5_7205",
7982
- "ag-shake-left-to-right": "_ag-shake-left-to-right_1ern5_342",
7983
- "spin": "_spin_1ern5_1"
7979
+ "contextPanel": "_contextPanel_pphrk_7159",
7980
+ "contextPanel--hidden": "_contextPanel--hidden_pphrk_7173",
7981
+ "contextPanelWrapper": "_contextPanelWrapper_pphrk_7181",
7982
+ "contextPanelBody": "_contextPanelBody_pphrk_7186",
7983
+ "contextPanel-stickyHeader": "_contextPanel-stickyHeader_pphrk_7190",
7984
+ "filters-list": "_filters-list_pphrk_7197",
7985
+ "col-drag-column-icon": "_col-drag-column-icon_pphrk_7206",
7986
+ "tabular-nums": "_tabular-nums_pphrk_7210",
7987
+ "ag-shake-left-to-right": "_ag-shake-left-to-right_pphrk_342",
7988
+ "spin": "_spin_pphrk_1"
7984
7989
  };
7985
7990
 
7986
7991
  // src/CellRenderers/BooleanCell.tsx
@@ -57903,6 +57908,7 @@ var InternalTableContext = React80.createContext({
57903
57908
  hide: () => {
57904
57909
  },
57905
57910
  isVisible: false,
57911
+ panelRef: React80.createRef(),
57906
57912
  show: () => {
57907
57913
  }
57908
57914
  },
@@ -59706,14 +59712,16 @@ var useRowSelectionState = () => {
59706
59712
  var BulkEditActionButton = (props) => {
59707
59713
  const { contextPanel } = useInternalTableContext();
59708
59714
  const i18n = useI18nContext();
59715
+ const buttonRef = React80.useRef(null);
59709
59716
  const editActionLabel = props.actionText ?? i18n.t("dataTable.bulkActions.editValues");
59710
59717
  return /* @__PURE__ */ React80.createElement(
59711
59718
  Button,
59712
59719
  {
59720
+ ref: buttonRef,
59713
59721
  "aria-label": i18n.t("dataTable.bulkActions.bulkEdit"),
59714
59722
  "data-qa": "bulkEditIcon",
59715
59723
  icon: /* @__PURE__ */ React80.createElement(Pencil, null),
59716
- onClick: () => contextPanel.show("bulkEdit"),
59724
+ onClick: () => contextPanel.show("bulkEdit", buttonRef.current ?? void 0),
59717
59725
  variant: "tertiary"
59718
59726
  },
59719
59727
  props.showLabel && editActionLabel
@@ -104340,10 +104348,6 @@ var BulkEditPanel = ({}) => {
104340
104348
  const { contextPanel, suppressBulkEditToasts } = useInternalTableContext();
104341
104349
  const I18n = useI18nContext();
104342
104350
  const bulkEditRef = React80.useRef(null);
104343
- const bodyRef = React80.useRef(null);
104344
- useEffect(() => {
104345
- bodyRef.current?.focus();
104346
- }, []);
104347
104351
  return /* @__PURE__ */ React80.createElement(Panel, null, /* @__PURE__ */ React80.createElement(
104348
104352
  Panel.Header,
104349
104353
  {
@@ -104353,7 +104357,7 @@ var BulkEditPanel = ({}) => {
104353
104357
  }
104354
104358
  },
104355
104359
  /* @__PURE__ */ React80.createElement(Panel.Title, null, I18n.t("dataTable.bulkActions.editValues"))
104356
- ), /* @__PURE__ */ React80.createElement(Panel.Body, { ref: bodyRef }, /* @__PURE__ */ React80.createElement(Panel.Section, null, /* @__PURE__ */ React80.createElement(
104360
+ ), /* @__PURE__ */ React80.createElement(Panel.Body, null, /* @__PURE__ */ React80.createElement(Panel.Section, null, /* @__PURE__ */ React80.createElement(
104357
104361
  BulkEdit,
104358
104362
  {
104359
104363
  ref: bulkEditRef,
@@ -104788,18 +104792,33 @@ var ConfigurationPanel = ({
104788
104792
  function useContextPanel() {
104789
104793
  const [content, setContent] = useState();
104790
104794
  const visibility = useVisibility({ afterHide: () => setContent(void 0) });
104791
- const show = useCallback((panelContent) => {
104792
- setContent(panelContent);
104793
- visibility.show();
104794
- }, []);
104795
+ const triggerRef = useRef(null);
104796
+ const panelRef = useRef(null);
104797
+ const show = useCallback(
104798
+ (panelContent, trigger) => {
104799
+ triggerRef.current = trigger ?? null;
104800
+ setContent(panelContent);
104801
+ visibility.show();
104802
+ },
104803
+ []
104804
+ );
104795
104805
  const hide = useCallback(() => {
104806
+ const trigger = triggerRef.current;
104796
104807
  setContent(void 0);
104797
104808
  visibility.hide();
104809
+ trigger?.focus();
104810
+ triggerRef.current = null;
104798
104811
  }, []);
104812
+ useEffect(() => {
104813
+ if (content) {
104814
+ panelRef.current?.focus();
104815
+ }
104816
+ }, [content]);
104799
104817
  return {
104800
104818
  content,
104801
104819
  hide,
104802
104820
  isVisible: visibility.isVisible,
104821
+ panelRef,
104803
104822
  show
104804
104823
  };
104805
104824
  }
@@ -111063,9 +111082,26 @@ var ContextPanel = ({
111063
111082
  ...props
111064
111083
  }) => {
111065
111084
  const { contextPanel } = useInternalTableContext();
111085
+ const I18n = useI18nContext();
111086
+ const cardRef = React80.useRef(null);
111087
+ const panelLabelKeys = {
111088
+ configuration: "dataTable.tableSettings.tableSettings",
111089
+ bulkEdit: "dataTable.bulkActions.editValues"
111090
+ };
111091
+ const panelLabel = contextPanel.content ? panelLabelKeys[contextPanel.content] : void 0;
111092
+ const ariaLabel = panelLabel ? I18n.t(panelLabel) : void 0;
111093
+ React80.useLayoutEffect(() => {
111094
+ if (contextPanel.content && contextPanel.content !== "filters") {
111095
+ contextPanel.panelRef.current = cardRef.current;
111096
+ }
111097
+ }, [contextPanel.content, contextPanel.panelRef]);
111066
111098
  return /* @__PURE__ */ React80.createElement(
111067
111099
  Card,
111068
111100
  {
111101
+ ref: cardRef,
111102
+ tabIndex: -1,
111103
+ role: "region",
111104
+ "aria-label": ariaLabel,
111069
111105
  className: cx19("contextPanel", className, {
111070
111106
  "contextPanel--hidden": !contextPanel.isVisible || contextPanel.content === "filters"
111071
111107
  }),
@@ -111337,19 +111373,27 @@ var BaseFiltersPanel = ({
111337
111373
  onClearAllFilters = noop5,
111338
111374
  ...props
111339
111375
  }) => {
111340
- const ref = React80.useRef(null);
111376
+ const cardRef = React80.useRef(null);
111341
111377
  const { contextPanel, filtersBodyId, filtersPanelId } = useInternalTableContext();
111342
111378
  const I18n = useI18nContext();
111343
111379
  const hidden = !contextPanel.isVisible || contextPanel.content !== "filters";
111344
111380
  React80.useLayoutEffect(() => {
111345
- if (ref.current) {
111346
- ref.current.inert = hidden;
111381
+ if (contextPanel.content === "filters") {
111382
+ contextPanel.panelRef.current = cardRef.current;
111383
+ }
111384
+ }, [contextPanel.content, contextPanel.panelRef]);
111385
+ React80.useLayoutEffect(() => {
111386
+ if (cardRef.current) {
111387
+ cardRef.current.inert = hidden;
111347
111388
  }
111348
111389
  }, [hidden]);
111349
111390
  return /* @__PURE__ */ React80.createElement(
111350
111391
  Card,
111351
111392
  {
111352
- ref,
111393
+ ref: cardRef,
111394
+ tabIndex: -1,
111395
+ role: "region",
111396
+ "aria-label": I18n.t("dataTable.filters.filters"),
111353
111397
  style: { maxHeight: "100vh" },
111354
111398
  className: cx20("contextPanel", className, {
111355
111399
  "contextPanel--hidden": hidden
@@ -111403,6 +111447,7 @@ var ConfigPanelButton = () => {
111403
111447
  const { contextPanel } = useInternalTableContext();
111404
111448
  const hasNoContent = useTableHasNoContent();
111405
111449
  const I18n = useI18nContext();
111450
+ const buttonRef = React80.useRef(null);
111406
111451
  return /* @__PURE__ */ React80.createElement(
111407
111452
  EmptyResultsControlTooltip,
111408
111453
  {
@@ -111412,12 +111457,13 @@ var ConfigPanelButton = () => {
111412
111457
  /* @__PURE__ */ React80.createElement(
111413
111458
  ToggleButton,
111414
111459
  {
111460
+ ref: buttonRef,
111415
111461
  disabled: hasNoContent,
111416
111462
  onClick: () => {
111417
111463
  if (contextPanel.content === "configuration") {
111418
111464
  contextPanel.hide();
111419
111465
  } else {
111420
- contextPanel.show("configuration");
111466
+ contextPanel.show("configuration", buttonRef.current ?? void 0);
111421
111467
  }
111422
111468
  },
111423
111469
  icon: /* @__PURE__ */ React80.createElement(
@@ -112570,26 +112616,12 @@ var SingleSelectQuickFilterRenderer = (props) => {
112570
112616
  return /* @__PURE__ */ React80.createElement(ClientSideSingleSelectQuickFilter, { ...props });
112571
112617
  };
112572
112618
  var SingleSelectQuickFilterRenderer_default = SingleSelectQuickFilterRenderer;
112573
- var FOCUSABLE_SELECTOR2 = 'button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
112574
112619
  var FiltersPanelToggleButton = ({ hasDefinedFilters }) => {
112575
112620
  const I18n = useI18nContext();
112576
- const { contextPanel, filtersBodyId, filtersPanelId } = useInternalTableContext();
112621
+ const { contextPanel, filtersPanelId } = useInternalTableContext();
112577
112622
  const hasNoContent = useTableHasNoContent();
112578
112623
  const buttonRef = React80.useRef(null);
112579
112624
  const isFiltersOpen = contextPanel.content === "filters";
112580
- const isMounted = React80.useRef(false);
112581
- React80.useEffect(() => {
112582
- if (!isMounted.current) {
112583
- isMounted.current = true;
112584
- return;
112585
- }
112586
- if (isFiltersOpen) {
112587
- const panel = filtersBodyId ? document.getElementById(filtersBodyId) : null;
112588
- panel?.querySelector(FOCUSABLE_SELECTOR2)?.focus();
112589
- } else {
112590
- buttonRef.current?.focus();
112591
- }
112592
- }, [isFiltersOpen, filtersBodyId]);
112593
112625
  if (!hasDefinedFilters) {
112594
112626
  return null;
112595
112627
  }
@@ -112610,7 +112642,7 @@ var FiltersPanelToggleButton = ({ hasDefinedFilters }) => {
112610
112642
  "aria-controls": filtersPanelId,
112611
112643
  onClick: () => {
112612
112644
  if (!isFiltersOpen) {
112613
- contextPanel.show("filters");
112645
+ contextPanel.show("filters", buttonRef.current ?? void 0);
112614
112646
  } else {
112615
112647
  contextPanel.hide();
112616
112648
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@procore/data-table",
3
- "version": "14.46.2",
3
+ "version": "14.46.3",
4
4
  "description": "Complex data grid built on top of ag-grid, with DST components and styles.",
5
5
  "author": "Procore Technologies",
6
6
  "homepage": "https://github.com/procore/core/tree/main/packages/data-table",
@@ -77,7 +77,7 @@
77
77
  "@procore/error-pages": "^0.2.3",
78
78
  "@procore/labs-datetime-select": "^0.2.2",
79
79
  "@procore/labs-group-by-select": "4.1.0",
80
- "@procore/toast-alert": "^5.1.3",
80
+ "@procore/toast-alert": "^5.2.0",
81
81
  "@procore/web-sdk-storage": "^0.1.0",
82
82
  "classnames": "2.5.1",
83
83
  "date-fns": "2.29.1",
@@ -106,9 +106,9 @@
106
106
  "@dotenvx/dotenvx": "1.6.4",
107
107
  "@ngneat/falso": "6.4.0",
108
108
  "@procore/core-css": "10.17.0",
109
- "@procore/core-icons": "^12.17.0",
109
+ "@procore/core-icons": "^12.18.0",
110
110
  "@procore/core-prettier": "10.2.0",
111
- "@procore/core-react": "^12.48.2",
111
+ "@procore/core-react": "^12.49.0",
112
112
  "@procore/eslint-config": "10.0.0",
113
113
  "@procore/globalization-toolkit": "3.1.0",
114
114
  "@procore/labs-financials-utils": "4.3.1",