@linzjs/step-ag-grid 12.0.1 → 12.1.1

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/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@linzjs/step-ag-grid",
3
3
  "repository": "github:linz/step-ag-grid.git",
4
4
  "license": "MIT",
5
- "version": "12.0.1",
5
+ "version": "12.1.1",
6
6
  "keywords": [
7
7
  "aggrid",
8
8
  "ag-grid",
@@ -1,12 +1,15 @@
1
1
  import { useContext, useEffect } from "react";
2
2
  import { GridContext, GridFilterExternal } from "../contexts/GridContext";
3
+ import { GridBaseRow } from "./Grid";
3
4
 
4
- export const useGridFilter = (filter: GridFilterExternal) => {
5
+ export const useGridFilter = <RowType extends GridBaseRow>(filter: GridFilterExternal<RowType> | undefined) => {
5
6
  const { addExternalFilter, removeExternalFilter } = useContext(GridContext);
6
7
 
7
8
  useEffect(() => {
8
9
  const thisFilter = filter;
9
- addExternalFilter(thisFilter);
10
- return () => removeExternalFilter(thisFilter);
10
+ thisFilter && addExternalFilter(thisFilter);
11
+ return () => {
12
+ thisFilter && removeExternalFilter(thisFilter);
13
+ };
11
14
  }, [addExternalFilter, filter, removeExternalFilter]);
12
15
  };
@@ -0,0 +1,52 @@
1
+ import clsx, { ClassValue } from "clsx";
2
+ import { useMemo, useState } from "react";
3
+ import { LuiButton, LuiButtonGroup } from "@linzjs/lui";
4
+ import { LuiButtonProps } from "@linzjs/lui/dist/components/LuiButton/LuiButton";
5
+ import { GridBaseRow } from "../Grid";
6
+ import { GridFilterExternal } from "../../contexts/GridContext";
7
+ import { useGridFilter } from "../GridFilter";
8
+
9
+ interface GridFilterButtonsOption<RowType extends GridBaseRow> {
10
+ defaultSelected?: boolean;
11
+ filter?: GridFilterExternal<RowType>;
12
+ label: string;
13
+ }
14
+
15
+ export type GridFilterButtonsProps<RowType extends GridBaseRow> = {
16
+ className?: ClassValue;
17
+ luiButtonProps?: Partial<LuiButtonProps>;
18
+ options: GridFilterButtonsOption<RowType>[];
19
+ };
20
+
21
+ export const GridFilterButtons = <RowType extends GridBaseRow>({
22
+ className,
23
+ luiButtonProps,
24
+ options,
25
+ }: GridFilterButtonsProps<RowType>): JSX.Element => {
26
+ // Select defaultSelected option, otherwise first option. If no options select none.
27
+ const [selectedOption, setSelectedOption] = useState(options.find((option) => option.defaultSelected) ?? options[0]);
28
+
29
+ const filter = useMemo(() => selectedOption?.filter, [selectedOption]);
30
+ useGridFilter(filter);
31
+
32
+ return (
33
+ <div className={clsx("lui-margin-top-xxs lui-margin-bottom-xxs", className)}>
34
+ <LuiButtonGroup>
35
+ {options.map((option, index) => (
36
+ <LuiButton
37
+ key={`${index}`}
38
+ {...luiButtonProps}
39
+ className={clsx(
40
+ `lui-button lui-button-secondary`,
41
+ selectedOption?.label === option.label && `lui-button-active`,
42
+ luiButtonProps?.className,
43
+ )}
44
+ onClick={() => setSelectedOption(option)}
45
+ >
46
+ {option.label}
47
+ </LuiButton>
48
+ ))}
49
+ </LuiButtonGroup>
50
+ </div>
51
+ );
52
+ };
@@ -1,10 +1,10 @@
1
- import { createContext } from "react";
1
+ import { createContext, useContext } from "react";
2
2
  import { GridApi, RowNode } from "ag-grid-community";
3
3
  import { GridBaseRow } from "../components/Grid";
4
4
 
5
- export type GridFilterExternal = (data: any, rowNode: RowNode) => boolean;
5
+ export type GridFilterExternal<RowType extends GridBaseRow> = (data: RowType, rowNode: RowNode) => boolean;
6
6
 
7
- export interface GridContextType {
7
+ export interface GridContextType<RowType extends GridBaseRow> {
8
8
  gridReady: boolean;
9
9
  setGridApi: (gridApi: GridApi | undefined) => void;
10
10
  prePopupOps: () => void;
@@ -33,13 +33,13 @@ export interface GridContextType {
33
33
  externallySelectedItemsAreInSync: boolean;
34
34
  setExternallySelectedItemsAreInSync: (inSync: boolean) => void;
35
35
  waitForExternallySelectedItemsToBeInSync: () => Promise<void>;
36
- addExternalFilter: (filter: GridFilterExternal) => void;
37
- removeExternalFilter: (filter: GridFilterExternal) => void;
36
+ addExternalFilter: (filter: GridFilterExternal<RowType>) => void;
37
+ removeExternalFilter: (filter: GridFilterExternal<RowType>) => void;
38
38
  isExternalFilterPresent: () => boolean;
39
39
  doesExternalFilterPass: (node: RowNode) => boolean;
40
40
  }
41
41
 
42
- export const GridContext = createContext<GridContextType>({
42
+ export const GridContext = createContext<GridContextType<any>>({
43
43
  gridReady: false,
44
44
  prePopupOps: () => {
45
45
  console.error("no context provider for prePopupOps");
@@ -125,3 +125,5 @@ export const GridContext = createContext<GridContextType>({
125
125
  return true;
126
126
  },
127
127
  });
128
+
129
+ export const useGridContext = <RowType extends GridBaseRow>() => useContext<GridContextType<RowType>>(GridContext);
@@ -16,7 +16,7 @@ interface GridContextProps {
16
16
  * Make sure you wrap AgGrid in this.
17
17
  * Also, make sure the provider is created in a separate component, otherwise it won't be found.
18
18
  */
19
- export const GridContextProvider = (props: GridContextProps): ReactElement => {
19
+ export const GridContextProvider = <RowType extends GridBaseRow>(props: GridContextProps): ReactElement => {
20
20
  const { modifyUpdating } = useContext(GridUpdatingContext);
21
21
  const [gridApi, _setGridApi] = useState<GridApi>();
22
22
  const [gridReady, setGridReady] = useState(false);
@@ -24,7 +24,7 @@ export const GridContextProvider = (props: GridContextProps): ReactElement => {
24
24
  const idsBeforeUpdate = useRef<number[]>([]);
25
25
  const prePopupFocusedCell = useRef<CellPosition>();
26
26
  const [externallySelectedItemsAreInSync, setExternallySelectedItemsAreInSync] = useState(false);
27
- const externalFilters = useRef<GridFilterExternal[]>([]);
27
+ const externalFilters = useRef<GridFilterExternal<RowType>[]>([]);
28
28
 
29
29
  /**
30
30
  * Set quick filter directly on grid, based on previously save quickFilter state.
@@ -390,12 +390,12 @@ export const GridContextProvider = (props: GridContextProps): ReactElement => {
390
390
  [gridApi],
391
391
  );
392
392
 
393
- const addExternalFilter = (filter: GridFilterExternal) => {
393
+ const addExternalFilter = (filter: GridFilterExternal<RowType>) => {
394
394
  externalFilters.current.push(filter);
395
395
  onFilterChanged();
396
396
  };
397
397
 
398
- const removeExternalFilter = (filter: GridFilterExternal) => {
398
+ const removeExternalFilter = (filter: GridFilterExternal<RowType>) => {
399
399
  remove(externalFilters.current, (v) => v === filter);
400
400
  onFilterChanged();
401
401
  };
@@ -18,6 +18,7 @@ import { GridIcon } from "../../components/GridIcon";
18
18
  import { useGridFilter } from "../../components/GridFilter";
19
19
  import { GridFilterQuick } from "../../components/gridFilter/GridFilterQuick";
20
20
  import { GridFilters } from "../../components/gridFilter/GridFilters";
21
+ import { GridFilterButtons } from "../../components/gridFilter/GridFilterButtons";
21
22
  import { GridWrapper } from "../../components/GridWrapper";
22
23
 
23
24
  export default {
@@ -204,13 +205,25 @@ const GridReadOnlyTemplate: ComponentStory<typeof Grid> = (props: GridProps) =>
204
205
  ]);
205
206
 
206
207
  return (
207
- <GridWrapper maxHeight={200}>
208
+ <GridWrapper maxHeight={300}>
208
209
  <GridFilters>
209
210
  <GridFilterQuick quickFilterPlaceholder={"Custom placeholder..."} />
210
211
  <div>
211
212
  Custom filter: Age less than:
212
213
  <GridFilterLessThan field={"age"} />
213
214
  </div>
215
+ <GridFilterButtons<ITestRow>
216
+ luiButtonProps={{ style: { whiteSpace: "nowrap" } }}
217
+ options={[
218
+ {
219
+ label: "All",
220
+ },
221
+ {
222
+ label: "< 30",
223
+ filter: (row) => row.age < 30,
224
+ },
225
+ ]}
226
+ />
214
227
  </GridFilters>
215
228
  <Grid
216
229
  {...props}