@vuu-ui/vuu-filters 0.13.38 → 0.13.40

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.
@@ -20,6 +20,7 @@ const ColumnFilter = react.forwardRef(function ColumnFilter2({
20
20
  table,
21
21
  value,
22
22
  onColumnFilterChange,
23
+ onColumnRangeFilterChange,
23
24
  ...buttonGroupProps
24
25
  }, forwardRef2) {
25
26
  const targetWindow = window.useWindow();
@@ -41,7 +42,8 @@ const ColumnFilter = react.forwardRef(function ColumnFilter2({
41
42
  operator,
42
43
  column,
43
44
  value,
44
- onColumnFilterChange
45
+ onColumnFilterChange,
46
+ onColumnRangeFilterChange
45
47
  });
46
48
  return /* @__PURE__ */ jsxRuntime.jsxs(
47
49
  core.SegmentedButtonGroup,
@@ -1 +1 @@
1
- {"version":3,"file":"ColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/ColumnFilter.tsx"],"sourcesContent":["import {\n Button,\n Menu,\n MenuItem,\n MenuPanel,\n MenuTrigger,\n SegmentedButtonGroup,\n SegmentedButtonGroupProps,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\n\nimport columnFilterCss from \"./ColumnFilter.css\";\nimport { getDataItemEditControl } from \"@vuu-ui/vuu-data-react\";\nimport { ForwardedRef, forwardRef, ReactElement } from \"react\";\nimport { ColumnFilterHookProps, useColumnFilter } from \"./useColumnFilter\";\nimport { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\n\nconst classBase = \"vuuColumnFilter\";\n\nexport interface ColumnFilterProps\n extends SegmentedButtonGroupProps,\n ColumnFilterHookProps {\n /**\n * Display operator picker.\n */\n showOperatorPicker?: boolean;\n /**\n * VuuTable is required if typeahead support is expected.\n */\n table?: VuuTable;\n}\n\nexport const ColumnFilter = forwardRef(function ColumnFilter(\n {\n column,\n className,\n onCommit: onCommitProp,\n operator = \"=\",\n showOperatorPicker = false,\n table,\n value,\n onColumnFilterChange,\n ...buttonGroupProps\n }: ColumnFilterProps,\n forwardRef: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-column-filter\",\n css: columnFilterCss,\n window: targetWindow,\n });\n\n const {\n op,\n allowedOperators,\n inputProps,\n rangeInputProps,\n handleOperatorChange,\n onCommit,\n onCommitRange,\n } = useColumnFilter({\n onCommit: onCommitProp,\n operator,\n column,\n value,\n onColumnFilterChange,\n });\n\n return (\n <SegmentedButtonGroup\n {...buttonGroupProps}\n className={cx(classBase, className)}\n ref={forwardRef}\n >\n {showOperatorPicker ? (\n <Menu placement=\"bottom-start\">\n <MenuTrigger>\n <Button\n appearance=\"solid\"\n aria-label=\"Open Menu\"\n className={`${classBase}-trigger`}\n data-embedded\n sentiment=\"neutral\"\n >\n {op}\n </Button>\n </MenuTrigger>\n <MenuPanel>\n {allowedOperators.map((allowedOp) => (\n <MenuItem\n key={`allowedOp`}\n onClick={() => handleOperatorChange(allowedOp)}\n >\n {allowedOp}\n </MenuItem>\n ))}\n </MenuPanel>\n </Menu>\n ) : null}\n {getDataItemEditControl({\n InputProps: { inputProps },\n commitOnBlur: false,\n commitWhenCleared: true,\n dataDescriptor: column,\n onCommit,\n table,\n })}\n {op === \"between\"\n ? getDataItemEditControl({\n className: `${classBase}-rangeHigh`,\n commitWhenCleared: true,\n InputProps: { inputProps: rangeInputProps },\n dataDescriptor: column,\n onCommit: onCommitRange,\n table,\n })\n : null}\n </SegmentedButtonGroup>\n );\n}) as (\n props: ColumnFilterProps & {\n ref?: ForwardedRef<HTMLDivElement>;\n },\n) => ReactElement<ColumnFilterProps>;\n"],"names":["forwardRef","ColumnFilter","useWindow","useComponentCssInjection","columnFilterCss","useColumnFilter","jsxs","SegmentedButtonGroup","Menu","jsx","MenuTrigger","Button","MenuPanel","MenuItem","getDataItemEditControl"],"mappings":";;;;;;;;;;;;AAmBA,MAAM,SAAY,GAAA,iBAAA;AAeL,MAAA,YAAA,GAAeA,gBAAW,CAAA,SAASC,aAC9C,CAAA;AAAA,EACE,MAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAU,EAAA,YAAA;AAAA,EACV,QAAW,GAAA,GAAA;AAAA,EACX,kBAAqB,GAAA,KAAA;AAAA,EACrB,KAAA;AAAA,EACA,KAAA;AAAA,EACA,oBAAA;AAAA,EACA,GAAG;AACL,CAAA,EACAD,WACA,EAAA;AACA,EAAA,MAAM,eAAeE,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,mBAAA;AAAA,IACR,GAAK,EAAAC,cAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA;AAAA,IACJ,EAAA;AAAA,IACA,gBAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA,oBAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,MACEC,+BAAgB,CAAA;AAAA,IAClB,QAAU,EAAA,YAAA;AAAA,IACV,QAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EACE,uBAAAC,eAAA;AAAA,IAACC,yBAAA;AAAA,IAAA;AAAA,MACE,GAAG,gBAAA;AAAA,MACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CAAA;AAAA,MAClC,GAAKP,EAAAA,WAAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,QACC,kBAAA,mBAAAM,eAAA,CAACE,SAAK,EAAA,EAAA,SAAA,EAAU,cACd,EAAA,QAAA,EAAA;AAAA,0BAAAC,cAAA,CAACC,gBACC,EAAA,EAAA,QAAA,kBAAAD,cAAA;AAAA,YAACE,WAAA;AAAA,YAAA;AAAA,cACC,UAAW,EAAA,OAAA;AAAA,cACX,YAAW,EAAA,WAAA;AAAA,cACX,SAAA,EAAW,GAAG,SAAS,CAAA,QAAA,CAAA;AAAA,cACvB,eAAa,EAAA,IAAA;AAAA,cACb,SAAU,EAAA,SAAA;AAAA,cAET,QAAA,EAAA;AAAA;AAAA,WAEL,EAAA,CAAA;AAAA,0BACCF,cAAA,CAAAG,cAAA,EAAA,EACE,QAAiB,EAAA,gBAAA,CAAA,GAAA,CAAI,CAAC,SACrB,qBAAAH,cAAA;AAAA,YAACI,aAAA;AAAA,YAAA;AAAA,cAEC,OAAA,EAAS,MAAM,oBAAA,CAAqB,SAAS,CAAA;AAAA,cAE5C,QAAA,EAAA;AAAA,aAAA;AAAA,YAHI,CAAA,SAAA;AAAA,WAKR,CACH,EAAA;AAAA,SAAA,EACF,CACE,GAAA,IAAA;AAAA,QACHC,mCAAuB,CAAA;AAAA,UACtB,UAAA,EAAY,EAAE,UAAW,EAAA;AAAA,UACzB,YAAc,EAAA,KAAA;AAAA,UACd,iBAAmB,EAAA,IAAA;AAAA,UACnB,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,QACA,EAAA,KAAO,YACJA,mCAAuB,CAAA;AAAA,UACrB,SAAA,EAAW,GAAG,SAAS,CAAA,UAAA,CAAA;AAAA,UACvB,iBAAmB,EAAA,IAAA;AAAA,UACnB,UAAA,EAAY,EAAE,UAAA,EAAY,eAAgB,EAAA;AAAA,UAC1C,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAU,EAAA,aAAA;AAAA,UACV;AAAA,SACD,CACD,GAAA;AAAA;AAAA;AAAA,GACN;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"ColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/ColumnFilter.tsx"],"sourcesContent":["import {\n Button,\n Menu,\n MenuItem,\n MenuPanel,\n MenuTrigger,\n SegmentedButtonGroup,\n SegmentedButtonGroupProps,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\n\nimport columnFilterCss from \"./ColumnFilter.css\";\nimport { getDataItemEditControl } from \"@vuu-ui/vuu-data-react\";\nimport { ForwardedRef, forwardRef, ReactElement } from \"react\";\nimport { ColumnFilterHookProps, useColumnFilter } from \"./useColumnFilter\";\nimport { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\n\nconst classBase = \"vuuColumnFilter\";\n\nexport interface ColumnFilterProps\n extends SegmentedButtonGroupProps,\n ColumnFilterHookProps {\n /**\n * Display operator picker.\n */\n showOperatorPicker?: boolean;\n /**\n * VuuTable is required if typeahead support is expected.\n */\n table?: VuuTable;\n}\n\nexport const ColumnFilter = forwardRef(function ColumnFilter(\n {\n column,\n className,\n onCommit: onCommitProp,\n operator = \"=\",\n showOperatorPicker = false,\n table,\n value,\n onColumnFilterChange,\n onColumnRangeFilterChange,\n ...buttonGroupProps\n }: ColumnFilterProps,\n forwardRef: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-column-filter\",\n css: columnFilterCss,\n window: targetWindow,\n });\n\n const {\n op,\n allowedOperators,\n inputProps,\n rangeInputProps,\n handleOperatorChange,\n onCommit,\n onCommitRange,\n } = useColumnFilter({\n onCommit: onCommitProp,\n operator,\n column,\n value,\n onColumnFilterChange,\n onColumnRangeFilterChange,\n });\n\n return (\n <SegmentedButtonGroup\n {...buttonGroupProps}\n className={cx(classBase, className)}\n ref={forwardRef}\n >\n {showOperatorPicker ? (\n <Menu placement=\"bottom-start\">\n <MenuTrigger>\n <Button\n appearance=\"solid\"\n aria-label=\"Open Menu\"\n className={`${classBase}-trigger`}\n data-embedded\n sentiment=\"neutral\"\n >\n {op}\n </Button>\n </MenuTrigger>\n <MenuPanel>\n {allowedOperators.map((allowedOp) => (\n <MenuItem\n key={`allowedOp`}\n onClick={() => handleOperatorChange(allowedOp)}\n >\n {allowedOp}\n </MenuItem>\n ))}\n </MenuPanel>\n </Menu>\n ) : null}\n {getDataItemEditControl({\n InputProps: { inputProps },\n commitOnBlur: false,\n commitWhenCleared: true,\n dataDescriptor: column,\n onCommit,\n table,\n })}\n {op === \"between\"\n ? getDataItemEditControl({\n className: `${classBase}-rangeHigh`,\n commitWhenCleared: true,\n InputProps: { inputProps: rangeInputProps },\n dataDescriptor: column,\n onCommit: onCommitRange,\n table,\n })\n : null}\n </SegmentedButtonGroup>\n );\n}) as (\n props: ColumnFilterProps & {\n ref?: ForwardedRef<HTMLDivElement>;\n },\n) => ReactElement<ColumnFilterProps>;\n"],"names":["forwardRef","ColumnFilter","useWindow","useComponentCssInjection","columnFilterCss","useColumnFilter","jsxs","SegmentedButtonGroup","Menu","jsx","MenuTrigger","Button","MenuPanel","MenuItem","getDataItemEditControl"],"mappings":";;;;;;;;;;;;AAmBA,MAAM,SAAY,GAAA,iBAAA;AAeL,MAAA,YAAA,GAAeA,gBAAW,CAAA,SAASC,aAC9C,CAAA;AAAA,EACE,MAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAU,EAAA,YAAA;AAAA,EACV,QAAW,GAAA,GAAA;AAAA,EACX,kBAAqB,GAAA,KAAA;AAAA,EACrB,KAAA;AAAA,EACA,KAAA;AAAA,EACA,oBAAA;AAAA,EACA,yBAAA;AAAA,EACA,GAAG;AACL,CAAA,EACAD,WACA,EAAA;AACA,EAAA,MAAM,eAAeE,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,mBAAA;AAAA,IACR,GAAK,EAAAC,cAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA;AAAA,IACJ,EAAA;AAAA,IACA,gBAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA,oBAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,MACEC,+BAAgB,CAAA;AAAA,IAClB,QAAU,EAAA,YAAA;AAAA,IACV,QAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,oBAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EACE,uBAAAC,eAAA;AAAA,IAACC,yBAAA;AAAA,IAAA;AAAA,MACE,GAAG,gBAAA;AAAA,MACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CAAA;AAAA,MAClC,GAAKP,EAAAA,WAAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,QACC,kBAAA,mBAAAM,eAAA,CAACE,SAAK,EAAA,EAAA,SAAA,EAAU,cACd,EAAA,QAAA,EAAA;AAAA,0BAAAC,cAAA,CAACC,gBACC,EAAA,EAAA,QAAA,kBAAAD,cAAA;AAAA,YAACE,WAAA;AAAA,YAAA;AAAA,cACC,UAAW,EAAA,OAAA;AAAA,cACX,YAAW,EAAA,WAAA;AAAA,cACX,SAAA,EAAW,GAAG,SAAS,CAAA,QAAA,CAAA;AAAA,cACvB,eAAa,EAAA,IAAA;AAAA,cACb,SAAU,EAAA,SAAA;AAAA,cAET,QAAA,EAAA;AAAA;AAAA,WAEL,EAAA,CAAA;AAAA,0BACCF,cAAA,CAAAG,cAAA,EAAA,EACE,QAAiB,EAAA,gBAAA,CAAA,GAAA,CAAI,CAAC,SACrB,qBAAAH,cAAA;AAAA,YAACI,aAAA;AAAA,YAAA;AAAA,cAEC,OAAA,EAAS,MAAM,oBAAA,CAAqB,SAAS,CAAA;AAAA,cAE5C,QAAA,EAAA;AAAA,aAAA;AAAA,YAHI,CAAA,SAAA;AAAA,WAKR,CACH,EAAA;AAAA,SAAA,EACF,CACE,GAAA,IAAA;AAAA,QACHC,mCAAuB,CAAA;AAAA,UACtB,UAAA,EAAY,EAAE,UAAW,EAAA;AAAA,UACzB,YAAc,EAAA,KAAA;AAAA,UACd,iBAAmB,EAAA,IAAA;AAAA,UACnB,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,QACA,EAAA,KAAO,YACJA,mCAAuB,CAAA;AAAA,UACrB,SAAA,EAAW,GAAG,SAAS,CAAA,UAAA,CAAA;AAAA,UACvB,iBAAmB,EAAA,IAAA;AAAA,UACnB,UAAA,EAAY,EAAE,UAAA,EAAY,eAAgB,EAAA;AAAA,UAC1C,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAU,EAAA,aAAA;AAAA,UACV;AAAA,SACD,CACD,GAAA;AAAA;AAAA;AAAA,GACN;AAEJ,CAAC;;;;"}
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  var react = require('react');
4
- var vuuUtils = require('@vuu-ui/vuu-utils');
5
4
  var operatorUtils = require('../filter-clause/operator-utils.js');
6
5
 
7
6
  const assertValidOperator = (allowedOperators, column, op) => {
@@ -31,7 +30,8 @@ const useColumnFilter = ({
31
30
  operator = "=",
32
31
  value,
33
32
  column,
34
- onColumnFilterChange
33
+ onColumnFilterChange,
34
+ onColumnRangeFilterChange
35
35
  }) => {
36
36
  const [op, setOp] = react.useState(operator);
37
37
  const allowedOperators = react.useMemo(() => operatorUtils.getOperators(column), [column]);
@@ -61,18 +61,15 @@ const useColumnFilter = ({
61
61
  );
62
62
  const handleInputChange = react.useCallback(
63
63
  (e) => {
64
- if (Array.isArray(value)) {
65
- const editControl = vuuUtils.queryClosest(e.target, "[data-edit-control]", true);
66
- const updated = [
67
- !editControl.className.includes("rangeHigh") ? e.target.value : value[0],
68
- editControl.className?.includes("rangeHigh") ? e.target.value : value[1]
69
- ];
70
- onColumnFilterChange?.(updated, column, op);
71
- } else {
72
- onColumnFilterChange?.(e.target.value, column, op);
73
- }
64
+ onColumnFilterChange?.(e.target.value, column, op);
65
+ },
66
+ [onColumnFilterChange, column, op]
67
+ );
68
+ const handleRangeInputChange = react.useCallback(
69
+ (e) => {
70
+ onColumnRangeFilterChange?.(e.target.value, column, op);
74
71
  },
75
- [value, onColumnFilterChange, column, op]
72
+ [onColumnRangeFilterChange, column, op]
76
73
  );
77
74
  const inputProps = react.useMemo(
78
75
  () => ({
@@ -83,10 +80,10 @@ const useColumnFilter = ({
83
80
  );
84
81
  const rangeInputProps = react.useMemo(
85
82
  () => Array.isArray(value) ? {
86
- onChange: handleInputChange,
83
+ onChange: handleRangeInputChange,
87
84
  value: value[1]
88
85
  } : void 0,
89
- [handleInputChange, value]
86
+ [handleRangeInputChange, value]
90
87
  );
91
88
  return {
92
89
  op,
@@ -1 +1 @@
1
- {"version":3,"file":"useColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/useColumnFilter.ts"],"sourcesContent":["import {\n ColumnFilterChangeHandler,\n ColumnFilterOp,\n ColumnFilterValue,\n FilterClauseOp,\n} from \"@vuu-ui/vuu-filter-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { ChangeEventHandler, useCallback, useMemo, useState } from \"react\";\nimport { CommitHandler, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { VuuTypeaheadInputProps } from \"@vuu-ui/vuu-ui-controls\";\nimport { getOperators } from \"../filter-clause/operator-utils\";\n\nexport const assertValidOperator = (\n allowedOperators: FilterClauseOp[],\n column: ColumnDescriptor,\n op: ColumnFilterOp,\n) => {\n if (op !== \"between\" && !allowedOperators.includes(op)) {\n console.warn(\n `[useColumnFilter] '${op} not supported for column ${column.name}'`,\n );\n }\n};\n\nexport type ColumnFilterCommitHandler = (\n column: ColumnDescriptor,\n op: FilterClauseOp | \"between\",\n value: ColumnFilterValue,\n) => void;\n\nexport const assertValidValue = (\n { serverDataType: _ }: ColumnDescriptor,\n operator: ColumnFilterOp,\n value?: ColumnFilterValue,\n) => {\n if (value !== undefined) {\n if (operator === \"between\") {\n if (!Array.isArray(value) || value.length !== 2) {\n throw Error(\n `[useColumnFilter] between operator requires array of two values, received ${value}`,\n );\n } else if (\n value[0] !== undefined &&\n value[1] !== undefined &&\n typeof value[0] !== typeof value[1]\n ) {\n throw Error(\n `[useColumnFilter] 'between operator values must be of same type, received ${typeof value[0]} and ${typeof value[1]}`,\n );\n }\n }\n // TODO validate value(s) against serverDataType\n }\n};\n\nexport type ColumnFilterHookProps = {\n column: ColumnDescriptor;\n operator?: ColumnFilterOp;\n /**\n * Filter value. Pair of values expected when operator is\n * 'between'\n */\n value?: ColumnFilterValue;\n /**\n * Filter change events.\n */\n onColumnFilterChange?: ColumnFilterChangeHandler;\n /**\n * Called when user 'commits' filter value, either by pressing enter,\n * tabbing away from control or making selection from list\n */\n onCommit: ColumnFilterCommitHandler;\n};\n\nexport const useColumnFilter = ({\n onCommit,\n operator = \"=\",\n value,\n column,\n onColumnFilterChange,\n}: ColumnFilterHookProps) => {\n const [op, setOp] = useState(operator);\n const allowedOperators = useMemo(() => getOperators(column), [column]);\n\n useMemo(() => {\n assertValidOperator(allowedOperators, column, operator);\n assertValidValue(column, op, value);\n }, [allowedOperators, column, operator, op, value]);\n\n const handleOperatorChange = useCallback((changedOp: ColumnFilterOp) => {\n setOp(changedOp);\n }, []);\n\n const handleCommit = useCallback<CommitHandler<HTMLElement>>(\n (_e, newValue) => {\n if (Array.isArray(value)) {\n onCommit?.(column, op, [`${newValue}`, value[1]]);\n } else {\n onCommit?.(column, op, `${newValue}`);\n }\n },\n [value, onCommit, column, op],\n );\n\n const handleRangeCommit = useCallback<CommitHandler<HTMLElement>>(\n (_e, newValue) => {\n const [firstValue] = value as [string, string];\n onCommit?.(column, op, [firstValue, `${newValue}`]);\n },\n [onCommit, column, op, value],\n );\n\n const handleInputChange = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (e) => {\n if (Array.isArray(value)) {\n const editControl = queryClosest(e.target, \"[data-edit-control]\", true);\n const updated: ColumnFilterValue = [\n !editControl.className.includes(\"rangeHigh\")\n ? e.target.value\n : value[0],\n editControl.className?.includes(\"rangeHigh\")\n ? e.target.value\n : value[1],\n ];\n onColumnFilterChange?.(updated, column, op);\n } else {\n onColumnFilterChange?.(e.target.value, column, op);\n }\n },\n [value, onColumnFilterChange, column, op],\n );\n\n const inputProps = useMemo<VuuTypeaheadInputProps[\"inputProps\"]>(\n () => ({\n onChange: handleInputChange,\n value: Array.isArray(value) ? value[0] : value,\n }),\n [handleInputChange, value],\n );\n\n const rangeInputProps = useMemo<VuuTypeaheadInputProps[\"inputProps\"]>(\n () =>\n Array.isArray(value)\n ? {\n onChange: handleInputChange,\n value: value[1],\n }\n : undefined,\n [handleInputChange, value],\n );\n\n return {\n op,\n allowedOperators,\n inputProps,\n rangeInputProps,\n onCommit: handleCommit,\n onCommitRange: handleRangeCommit,\n handleOperatorChange,\n };\n};\n"],"names":["useState","useMemo","getOperators","useCallback","queryClosest"],"mappings":";;;;;;AAYO,MAAM,mBAAsB,GAAA,CACjC,gBACA,EAAA,MAAA,EACA,EACG,KAAA;AACH,EAAA,IAAI,OAAO,SAAa,IAAA,CAAC,gBAAiB,CAAA,QAAA,CAAS,EAAE,CAAG,EAAA;AACtD,IAAQ,OAAA,CAAA,IAAA;AAAA,MACN,CAAsB,mBAAA,EAAA,EAAE,CAA6B,0BAAA,EAAA,MAAA,CAAO,IAAI,CAAA,CAAA;AAAA,KAClE;AAAA;AAEJ;AAQO,MAAM,mBAAmB,CAC9B,EAAE,gBAAgB,CAAE,EAAA,EACpB,UACA,KACG,KAAA;AACH,EAAA,IAAI,UAAU,KAAW,CAAA,EAAA;AACvB,IAAA,IAAI,aAAa,SAAW,EAAA;AAC1B,MAAA,IAAI,CAAC,KAAM,CAAA,OAAA,CAAQ,KAAK,CAAK,IAAA,KAAA,CAAM,WAAW,CAAG,EAAA;AAC/C,QAAM,MAAA,KAAA;AAAA,UACJ,6EAA6E,KAAK,CAAA;AAAA,SACpF;AAAA,iBAEA,KAAM,CAAA,CAAC,CAAM,KAAA,KAAA,CAAA,IACb,MAAM,CAAC,CAAA,KAAM,KACb,CAAA,IAAA,OAAO,MAAM,CAAC,CAAA,KAAM,OAAO,KAAA,CAAM,CAAC,CAClC,EAAA;AACA,QAAM,MAAA,KAAA;AAAA,UACJ,CAAA,0EAAA,EAA6E,OAAO,KAAM,CAAA,CAAC,CAAC,CAAQ,KAAA,EAAA,OAAO,KAAM,CAAA,CAAC,CAAC,CAAA;AAAA,SACrH;AAAA;AACF;AACF;AAGJ;AAqBO,MAAM,kBAAkB,CAAC;AAAA,EAC9B,QAAA;AAAA,EACA,QAAW,GAAA,GAAA;AAAA,EACX,KAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAA6B,KAAA;AAC3B,EAAA,MAAM,CAAC,EAAA,EAAI,KAAK,CAAA,GAAIA,eAAS,QAAQ,CAAA;AACrC,EAAM,MAAA,gBAAA,GAAmBC,cAAQ,MAAMC,0BAAA,CAAa,MAAM,CAAG,EAAA,CAAC,MAAM,CAAC,CAAA;AAErE,EAAAD,aAAA,CAAQ,MAAM;AACZ,IAAoB,mBAAA,CAAA,gBAAA,EAAkB,QAAQ,QAAQ,CAAA;AACtD,IAAiB,gBAAA,CAAA,MAAA,EAAQ,IAAI,KAAK,CAAA;AAAA,KACjC,CAAC,gBAAA,EAAkB,QAAQ,QAAU,EAAA,EAAA,EAAI,KAAK,CAAC,CAAA;AAElD,EAAM,MAAA,oBAAA,GAAuBE,iBAAY,CAAA,CAAC,SAA8B,KAAA;AACtE,IAAA,KAAA,CAAM,SAAS,CAAA;AAAA,GACjB,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,YAAe,GAAAA,iBAAA;AAAA,IACnB,CAAC,IAAI,QAAa,KAAA;AAChB,MAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,KAAK,CAAG,EAAA;AACxB,QAAW,QAAA,GAAA,MAAA,EAAQ,IAAI,CAAC,CAAA,EAAG,QAAQ,CAAI,CAAA,EAAA,KAAA,CAAM,CAAC,CAAC,CAAC,CAAA;AAAA,OAC3C,MAAA;AACL,QAAA,QAAA,GAAW,MAAQ,EAAA,EAAA,EAAI,CAAG,EAAA,QAAQ,CAAE,CAAA,CAAA;AAAA;AACtC,KACF;AAAA,IACA,CAAC,KAAA,EAAO,QAAU,EAAA,MAAA,EAAQ,EAAE;AAAA,GAC9B;AAEA,EAAA,MAAM,iBAAoB,GAAAA,iBAAA;AAAA,IACxB,CAAC,IAAI,QAAa,KAAA;AAChB,MAAM,MAAA,CAAC,UAAU,CAAI,GAAA,KAAA;AACrB,MAAA,QAAA,GAAW,QAAQ,EAAI,EAAA,CAAC,YAAY,CAAG,EAAA,QAAQ,EAAE,CAAC,CAAA;AAAA,KACpD;AAAA,IACA,CAAC,QAAA,EAAU,MAAQ,EAAA,EAAA,EAAI,KAAK;AAAA,GAC9B;AAEA,EAAA,MAAM,iBAAoB,GAAAA,iBAAA;AAAA,IACxB,CAAC,CAAM,KAAA;AACL,MAAI,IAAA,KAAA,CAAM,OAAQ,CAAA,KAAK,CAAG,EAAA;AACxB,QAAA,MAAM,WAAc,GAAAC,qBAAA,CAAa,CAAE,CAAA,MAAA,EAAQ,uBAAuB,IAAI,CAAA;AACtE,QAAA,MAAM,OAA6B,GAAA;AAAA,UACjC,CAAC,WAAY,CAAA,SAAA,CAAU,QAAS,CAAA,WAAW,IACvC,CAAE,CAAA,MAAA,CAAO,KACT,GAAA,KAAA,CAAM,CAAC,CAAA;AAAA,UACX,WAAA,CAAY,WAAW,QAAS,CAAA,WAAW,IACvC,CAAE,CAAA,MAAA,CAAO,KACT,GAAA,KAAA,CAAM,CAAC;AAAA,SACb;AACA,QAAuB,oBAAA,GAAA,OAAA,EAAS,QAAQ,EAAE,CAAA;AAAA,OACrC,MAAA;AACL,QAAA,oBAAA,GAAuB,CAAE,CAAA,MAAA,CAAO,KAAO,EAAA,MAAA,EAAQ,EAAE,CAAA;AAAA;AACnD,KACF;AAAA,IACA,CAAC,KAAA,EAAO,oBAAsB,EAAA,MAAA,EAAQ,EAAE;AAAA,GAC1C;AAEA,EAAA,MAAM,UAAa,GAAAH,aAAA;AAAA,IACjB,OAAO;AAAA,MACL,QAAU,EAAA,iBAAA;AAAA,MACV,OAAO,KAAM,CAAA,OAAA,CAAQ,KAAK,CAAI,GAAA,KAAA,CAAM,CAAC,CAAI,GAAA;AAAA,KAC3C,CAAA;AAAA,IACA,CAAC,mBAAmB,KAAK;AAAA,GAC3B;AAEA,EAAA,MAAM,eAAkB,GAAAA,aAAA;AAAA,IACtB,MACE,KAAA,CAAM,OAAQ,CAAA,KAAK,CACf,GAAA;AAAA,MACE,QAAU,EAAA,iBAAA;AAAA,MACV,KAAA,EAAO,MAAM,CAAC;AAAA,KAEhB,GAAA,KAAA,CAAA;AAAA,IACN,CAAC,mBAAmB,KAAK;AAAA,GAC3B;AAEA,EAAO,OAAA;AAAA,IACL,EAAA;AAAA,IACA,gBAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA,QAAU,EAAA,YAAA;AAAA,IACV,aAAe,EAAA,iBAAA;AAAA,IACf;AAAA,GACF;AACF;;;;;;"}
1
+ {"version":3,"file":"useColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/useColumnFilter.ts"],"sourcesContent":["import {\n ColumnFilterChangeHandler,\n ColumnFilterOp,\n ColumnFilterValue,\n FilterClauseOp,\n} from \"@vuu-ui/vuu-filter-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { ChangeEventHandler, useCallback, useMemo, useState } from \"react\";\nimport { CommitHandler } from \"@vuu-ui/vuu-utils\";\nimport { VuuTypeaheadInputProps } from \"@vuu-ui/vuu-ui-controls\";\nimport { getOperators } from \"../filter-clause/operator-utils\";\n\nexport const assertValidOperator = (\n allowedOperators: FilterClauseOp[],\n column: ColumnDescriptor,\n op: ColumnFilterOp,\n) => {\n if (op !== \"between\" && !allowedOperators.includes(op)) {\n console.warn(\n `[useColumnFilter] '${op} not supported for column ${column.name}'`,\n );\n }\n};\n\nexport type ColumnFilterCommitHandler = (\n column: ColumnDescriptor,\n op: FilterClauseOp | \"between\",\n value: ColumnFilterValue,\n) => void;\n\nexport const assertValidValue = (\n { serverDataType: _ }: ColumnDescriptor,\n operator: ColumnFilterOp,\n value?: ColumnFilterValue,\n) => {\n if (value !== undefined) {\n if (operator === \"between\") {\n if (!Array.isArray(value) || value.length !== 2) {\n throw Error(\n `[useColumnFilter] between operator requires array of two values, received ${value}`,\n );\n } else if (\n value[0] !== undefined &&\n value[1] !== undefined &&\n typeof value[0] !== typeof value[1]\n ) {\n throw Error(\n `[useColumnFilter] 'between operator values must be of same type, received ${typeof value[0]} and ${typeof value[1]}`,\n );\n }\n }\n // TODO validate value(s) against serverDataType\n }\n};\n\nexport type ColumnFilterHookProps = {\n column: ColumnDescriptor;\n operator?: ColumnFilterOp;\n /**\n * Filter value. Pair of values expected when operator is\n * 'between'\n */\n value?: ColumnFilterValue;\n /**\n * Filter change events.\n */\n onColumnFilterChange?: ColumnFilterChangeHandler;\n /**\n * Filter change events on second control in range filter\n */\n onColumnRangeFilterChange?: ColumnFilterChangeHandler;\n /**\n * Called when user 'commits' filter value, either by pressing enter,\n * tabbing away from control or making selection from list\n */\n onCommit: ColumnFilterCommitHandler;\n};\n\nexport const useColumnFilter = ({\n onCommit,\n operator = \"=\",\n value,\n column,\n onColumnFilterChange,\n onColumnRangeFilterChange,\n}: ColumnFilterHookProps) => {\n const [op, setOp] = useState(operator);\n const allowedOperators = useMemo(() => getOperators(column), [column]);\n\n useMemo(() => {\n assertValidOperator(allowedOperators, column, operator);\n assertValidValue(column, op, value);\n }, [allowedOperators, column, operator, op, value]);\n\n const handleOperatorChange = useCallback((changedOp: ColumnFilterOp) => {\n setOp(changedOp);\n }, []);\n\n const handleCommit = useCallback<CommitHandler<HTMLElement>>(\n (_e, newValue) => {\n if (Array.isArray(value)) {\n onCommit?.(column, op, [`${newValue}`, value[1]]);\n } else {\n onCommit?.(column, op, `${newValue}`);\n }\n },\n [value, onCommit, column, op],\n );\n\n const handleRangeCommit = useCallback<CommitHandler<HTMLElement>>(\n (_e, newValue) => {\n const [firstValue] = value as [string, string];\n onCommit?.(column, op, [firstValue, `${newValue}`]);\n },\n [onCommit, column, op, value],\n );\n\n const handleInputChange = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (e) => {\n onColumnFilterChange?.(e.target.value, column, op);\n },\n [onColumnFilterChange, column, op],\n );\n\n const handleRangeInputChange = useCallback<\n ChangeEventHandler<HTMLInputElement>\n >(\n (e) => {\n onColumnRangeFilterChange?.(e.target.value, column, op);\n },\n [onColumnRangeFilterChange, column, op],\n );\n\n const inputProps = useMemo<VuuTypeaheadInputProps[\"inputProps\"]>(\n () => ({\n onChange: handleInputChange,\n value: Array.isArray(value) ? value[0] : value,\n }),\n [handleInputChange, value],\n );\n\n const rangeInputProps = useMemo<VuuTypeaheadInputProps[\"inputProps\"]>(\n () =>\n Array.isArray(value)\n ? {\n onChange: handleRangeInputChange,\n value: value[1],\n }\n : undefined,\n [handleRangeInputChange, value],\n );\n\n return {\n op,\n allowedOperators,\n inputProps,\n rangeInputProps,\n onCommit: handleCommit,\n onCommitRange: handleRangeCommit,\n handleOperatorChange,\n };\n};\n"],"names":["useState","useMemo","getOperators","useCallback"],"mappings":"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"}
@@ -18,6 +18,7 @@ const ColumnFilter = forwardRef(function ColumnFilter2({
18
18
  table,
19
19
  value,
20
20
  onColumnFilterChange,
21
+ onColumnRangeFilterChange,
21
22
  ...buttonGroupProps
22
23
  }, forwardRef2) {
23
24
  const targetWindow = useWindow();
@@ -39,7 +40,8 @@ const ColumnFilter = forwardRef(function ColumnFilter2({
39
40
  operator,
40
41
  column,
41
42
  value,
42
- onColumnFilterChange
43
+ onColumnFilterChange,
44
+ onColumnRangeFilterChange
43
45
  });
44
46
  return /* @__PURE__ */ jsxs(
45
47
  SegmentedButtonGroup,
@@ -1 +1 @@
1
- {"version":3,"file":"ColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/ColumnFilter.tsx"],"sourcesContent":["import {\n Button,\n Menu,\n MenuItem,\n MenuPanel,\n MenuTrigger,\n SegmentedButtonGroup,\n SegmentedButtonGroupProps,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\n\nimport columnFilterCss from \"./ColumnFilter.css\";\nimport { getDataItemEditControl } from \"@vuu-ui/vuu-data-react\";\nimport { ForwardedRef, forwardRef, ReactElement } from \"react\";\nimport { ColumnFilterHookProps, useColumnFilter } from \"./useColumnFilter\";\nimport { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\n\nconst classBase = \"vuuColumnFilter\";\n\nexport interface ColumnFilterProps\n extends SegmentedButtonGroupProps,\n ColumnFilterHookProps {\n /**\n * Display operator picker.\n */\n showOperatorPicker?: boolean;\n /**\n * VuuTable is required if typeahead support is expected.\n */\n table?: VuuTable;\n}\n\nexport const ColumnFilter = forwardRef(function ColumnFilter(\n {\n column,\n className,\n onCommit: onCommitProp,\n operator = \"=\",\n showOperatorPicker = false,\n table,\n value,\n onColumnFilterChange,\n ...buttonGroupProps\n }: ColumnFilterProps,\n forwardRef: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-column-filter\",\n css: columnFilterCss,\n window: targetWindow,\n });\n\n const {\n op,\n allowedOperators,\n inputProps,\n rangeInputProps,\n handleOperatorChange,\n onCommit,\n onCommitRange,\n } = useColumnFilter({\n onCommit: onCommitProp,\n operator,\n column,\n value,\n onColumnFilterChange,\n });\n\n return (\n <SegmentedButtonGroup\n {...buttonGroupProps}\n className={cx(classBase, className)}\n ref={forwardRef}\n >\n {showOperatorPicker ? (\n <Menu placement=\"bottom-start\">\n <MenuTrigger>\n <Button\n appearance=\"solid\"\n aria-label=\"Open Menu\"\n className={`${classBase}-trigger`}\n data-embedded\n sentiment=\"neutral\"\n >\n {op}\n </Button>\n </MenuTrigger>\n <MenuPanel>\n {allowedOperators.map((allowedOp) => (\n <MenuItem\n key={`allowedOp`}\n onClick={() => handleOperatorChange(allowedOp)}\n >\n {allowedOp}\n </MenuItem>\n ))}\n </MenuPanel>\n </Menu>\n ) : null}\n {getDataItemEditControl({\n InputProps: { inputProps },\n commitOnBlur: false,\n commitWhenCleared: true,\n dataDescriptor: column,\n onCommit,\n table,\n })}\n {op === \"between\"\n ? getDataItemEditControl({\n className: `${classBase}-rangeHigh`,\n commitWhenCleared: true,\n InputProps: { inputProps: rangeInputProps },\n dataDescriptor: column,\n onCommit: onCommitRange,\n table,\n })\n : null}\n </SegmentedButtonGroup>\n );\n}) as (\n props: ColumnFilterProps & {\n ref?: ForwardedRef<HTMLDivElement>;\n },\n) => ReactElement<ColumnFilterProps>;\n"],"names":["ColumnFilter","forwardRef"],"mappings":";;;;;;;;;;AAmBA,MAAM,SAAY,GAAA,iBAAA;AAeL,MAAA,YAAA,GAAe,UAAW,CAAA,SAASA,aAC9C,CAAA;AAAA,EACE,MAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAU,EAAA,YAAA;AAAA,EACV,QAAW,GAAA,GAAA;AAAA,EACX,kBAAqB,GAAA,KAAA;AAAA,EACrB,KAAA;AAAA,EACA,KAAA;AAAA,EACA,oBAAA;AAAA,EACA,GAAG;AACL,CAAA,EACAC,WACA,EAAA;AACA,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,mBAAA;AAAA,IACR,GAAK,EAAA,eAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA;AAAA,IACJ,EAAA;AAAA,IACA,gBAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA,oBAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,MACE,eAAgB,CAAA;AAAA,IAClB,QAAU,EAAA,YAAA;AAAA,IACV,QAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EACE,uBAAA,IAAA;AAAA,IAAC,oBAAA;AAAA,IAAA;AAAA,MACE,GAAG,gBAAA;AAAA,MACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CAAA;AAAA,MAClC,GAAKA,EAAAA,WAAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,QACC,kBAAA,mBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAU,cACd,EAAA,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,WACC,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,UAAW,EAAA,OAAA;AAAA,cACX,YAAW,EAAA,WAAA;AAAA,cACX,SAAA,EAAW,GAAG,SAAS,CAAA,QAAA,CAAA;AAAA,cACvB,eAAa,EAAA,IAAA;AAAA,cACb,SAAU,EAAA,SAAA;AAAA,cAET,QAAA,EAAA;AAAA;AAAA,WAEL,EAAA,CAAA;AAAA,0BACC,GAAA,CAAA,SAAA,EAAA,EACE,QAAiB,EAAA,gBAAA,CAAA,GAAA,CAAI,CAAC,SACrB,qBAAA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cAEC,OAAA,EAAS,MAAM,oBAAA,CAAqB,SAAS,CAAA;AAAA,cAE5C,QAAA,EAAA;AAAA,aAAA;AAAA,YAHI,CAAA,SAAA;AAAA,WAKR,CACH,EAAA;AAAA,SAAA,EACF,CACE,GAAA,IAAA;AAAA,QACH,sBAAuB,CAAA;AAAA,UACtB,UAAA,EAAY,EAAE,UAAW,EAAA;AAAA,UACzB,YAAc,EAAA,KAAA;AAAA,UACd,iBAAmB,EAAA,IAAA;AAAA,UACnB,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,QACA,EAAA,KAAO,YACJ,sBAAuB,CAAA;AAAA,UACrB,SAAA,EAAW,GAAG,SAAS,CAAA,UAAA,CAAA;AAAA,UACvB,iBAAmB,EAAA,IAAA;AAAA,UACnB,UAAA,EAAY,EAAE,UAAA,EAAY,eAAgB,EAAA;AAAA,UAC1C,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAU,EAAA,aAAA;AAAA,UACV;AAAA,SACD,CACD,GAAA;AAAA;AAAA;AAAA,GACN;AAEJ,CAAC;;;;"}
1
+ {"version":3,"file":"ColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/ColumnFilter.tsx"],"sourcesContent":["import {\n Button,\n Menu,\n MenuItem,\n MenuPanel,\n MenuTrigger,\n SegmentedButtonGroup,\n SegmentedButtonGroupProps,\n} from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\n\nimport columnFilterCss from \"./ColumnFilter.css\";\nimport { getDataItemEditControl } from \"@vuu-ui/vuu-data-react\";\nimport { ForwardedRef, forwardRef, ReactElement } from \"react\";\nimport { ColumnFilterHookProps, useColumnFilter } from \"./useColumnFilter\";\nimport { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\n\nconst classBase = \"vuuColumnFilter\";\n\nexport interface ColumnFilterProps\n extends SegmentedButtonGroupProps,\n ColumnFilterHookProps {\n /**\n * Display operator picker.\n */\n showOperatorPicker?: boolean;\n /**\n * VuuTable is required if typeahead support is expected.\n */\n table?: VuuTable;\n}\n\nexport const ColumnFilter = forwardRef(function ColumnFilter(\n {\n column,\n className,\n onCommit: onCommitProp,\n operator = \"=\",\n showOperatorPicker = false,\n table,\n value,\n onColumnFilterChange,\n onColumnRangeFilterChange,\n ...buttonGroupProps\n }: ColumnFilterProps,\n forwardRef: ForwardedRef<HTMLDivElement>,\n) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-column-filter\",\n css: columnFilterCss,\n window: targetWindow,\n });\n\n const {\n op,\n allowedOperators,\n inputProps,\n rangeInputProps,\n handleOperatorChange,\n onCommit,\n onCommitRange,\n } = useColumnFilter({\n onCommit: onCommitProp,\n operator,\n column,\n value,\n onColumnFilterChange,\n onColumnRangeFilterChange,\n });\n\n return (\n <SegmentedButtonGroup\n {...buttonGroupProps}\n className={cx(classBase, className)}\n ref={forwardRef}\n >\n {showOperatorPicker ? (\n <Menu placement=\"bottom-start\">\n <MenuTrigger>\n <Button\n appearance=\"solid\"\n aria-label=\"Open Menu\"\n className={`${classBase}-trigger`}\n data-embedded\n sentiment=\"neutral\"\n >\n {op}\n </Button>\n </MenuTrigger>\n <MenuPanel>\n {allowedOperators.map((allowedOp) => (\n <MenuItem\n key={`allowedOp`}\n onClick={() => handleOperatorChange(allowedOp)}\n >\n {allowedOp}\n </MenuItem>\n ))}\n </MenuPanel>\n </Menu>\n ) : null}\n {getDataItemEditControl({\n InputProps: { inputProps },\n commitOnBlur: false,\n commitWhenCleared: true,\n dataDescriptor: column,\n onCommit,\n table,\n })}\n {op === \"between\"\n ? getDataItemEditControl({\n className: `${classBase}-rangeHigh`,\n commitWhenCleared: true,\n InputProps: { inputProps: rangeInputProps },\n dataDescriptor: column,\n onCommit: onCommitRange,\n table,\n })\n : null}\n </SegmentedButtonGroup>\n );\n}) as (\n props: ColumnFilterProps & {\n ref?: ForwardedRef<HTMLDivElement>;\n },\n) => ReactElement<ColumnFilterProps>;\n"],"names":["ColumnFilter","forwardRef"],"mappings":";;;;;;;;;;AAmBA,MAAM,SAAY,GAAA,iBAAA;AAeL,MAAA,YAAA,GAAe,UAAW,CAAA,SAASA,aAC9C,CAAA;AAAA,EACE,MAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAU,EAAA,YAAA;AAAA,EACV,QAAW,GAAA,GAAA;AAAA,EACX,kBAAqB,GAAA,KAAA;AAAA,EACrB,KAAA;AAAA,EACA,KAAA;AAAA,EACA,oBAAA;AAAA,EACA,yBAAA;AAAA,EACA,GAAG;AACL,CAAA,EACAC,WACA,EAAA;AACA,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,mBAAA;AAAA,IACR,GAAK,EAAA,eAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA;AAAA,IACJ,EAAA;AAAA,IACA,gBAAA;AAAA,IACA,UAAA;AAAA,IACA,eAAA;AAAA,IACA,oBAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,MACE,eAAgB,CAAA;AAAA,IAClB,QAAU,EAAA,YAAA;AAAA,IACV,QAAA;AAAA,IACA,MAAA;AAAA,IACA,KAAA;AAAA,IACA,oBAAA;AAAA,IACA;AAAA,GACD,CAAA;AAED,EACE,uBAAA,IAAA;AAAA,IAAC,oBAAA;AAAA,IAAA;AAAA,MACE,GAAG,gBAAA;AAAA,MACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CAAA;AAAA,MAClC,GAAKA,EAAAA,WAAAA;AAAA,MAEJ,QAAA,EAAA;AAAA,QACC,kBAAA,mBAAA,IAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAU,cACd,EAAA,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,WACC,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,YAAC,MAAA;AAAA,YAAA;AAAA,cACC,UAAW,EAAA,OAAA;AAAA,cACX,YAAW,EAAA,WAAA;AAAA,cACX,SAAA,EAAW,GAAG,SAAS,CAAA,QAAA,CAAA;AAAA,cACvB,eAAa,EAAA,IAAA;AAAA,cACb,SAAU,EAAA,SAAA;AAAA,cAET,QAAA,EAAA;AAAA;AAAA,WAEL,EAAA,CAAA;AAAA,0BACC,GAAA,CAAA,SAAA,EAAA,EACE,QAAiB,EAAA,gBAAA,CAAA,GAAA,CAAI,CAAC,SACrB,qBAAA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cAEC,OAAA,EAAS,MAAM,oBAAA,CAAqB,SAAS,CAAA;AAAA,cAE5C,QAAA,EAAA;AAAA,aAAA;AAAA,YAHI,CAAA,SAAA;AAAA,WAKR,CACH,EAAA;AAAA,SAAA,EACF,CACE,GAAA,IAAA;AAAA,QACH,sBAAuB,CAAA;AAAA,UACtB,UAAA,EAAY,EAAE,UAAW,EAAA;AAAA,UACzB,YAAc,EAAA,KAAA;AAAA,UACd,iBAAmB,EAAA,IAAA;AAAA,UACnB,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,QACA,EAAA,KAAO,YACJ,sBAAuB,CAAA;AAAA,UACrB,SAAA,EAAW,GAAG,SAAS,CAAA,UAAA,CAAA;AAAA,UACvB,iBAAmB,EAAA,IAAA;AAAA,UACnB,UAAA,EAAY,EAAE,UAAA,EAAY,eAAgB,EAAA;AAAA,UAC1C,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAU,EAAA,aAAA;AAAA,UACV;AAAA,SACD,CACD,GAAA;AAAA;AAAA;AAAA,GACN;AAEJ,CAAC;;;;"}
@@ -1,5 +1,4 @@
1
1
  import { useState, useMemo, useCallback } from 'react';
2
- import { queryClosest } from '@vuu-ui/vuu-utils';
3
2
  import { getOperators } from '../filter-clause/operator-utils.js';
4
3
 
5
4
  const assertValidOperator = (allowedOperators, column, op) => {
@@ -29,7 +28,8 @@ const useColumnFilter = ({
29
28
  operator = "=",
30
29
  value,
31
30
  column,
32
- onColumnFilterChange
31
+ onColumnFilterChange,
32
+ onColumnRangeFilterChange
33
33
  }) => {
34
34
  const [op, setOp] = useState(operator);
35
35
  const allowedOperators = useMemo(() => getOperators(column), [column]);
@@ -59,18 +59,15 @@ const useColumnFilter = ({
59
59
  );
60
60
  const handleInputChange = useCallback(
61
61
  (e) => {
62
- if (Array.isArray(value)) {
63
- const editControl = queryClosest(e.target, "[data-edit-control]", true);
64
- const updated = [
65
- !editControl.className.includes("rangeHigh") ? e.target.value : value[0],
66
- editControl.className?.includes("rangeHigh") ? e.target.value : value[1]
67
- ];
68
- onColumnFilterChange?.(updated, column, op);
69
- } else {
70
- onColumnFilterChange?.(e.target.value, column, op);
71
- }
62
+ onColumnFilterChange?.(e.target.value, column, op);
63
+ },
64
+ [onColumnFilterChange, column, op]
65
+ );
66
+ const handleRangeInputChange = useCallback(
67
+ (e) => {
68
+ onColumnRangeFilterChange?.(e.target.value, column, op);
72
69
  },
73
- [value, onColumnFilterChange, column, op]
70
+ [onColumnRangeFilterChange, column, op]
74
71
  );
75
72
  const inputProps = useMemo(
76
73
  () => ({
@@ -81,10 +78,10 @@ const useColumnFilter = ({
81
78
  );
82
79
  const rangeInputProps = useMemo(
83
80
  () => Array.isArray(value) ? {
84
- onChange: handleInputChange,
81
+ onChange: handleRangeInputChange,
85
82
  value: value[1]
86
83
  } : void 0,
87
- [handleInputChange, value]
84
+ [handleRangeInputChange, value]
88
85
  );
89
86
  return {
90
87
  op,
@@ -1 +1 @@
1
- {"version":3,"file":"useColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/useColumnFilter.ts"],"sourcesContent":["import {\n ColumnFilterChangeHandler,\n ColumnFilterOp,\n ColumnFilterValue,\n FilterClauseOp,\n} from \"@vuu-ui/vuu-filter-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { ChangeEventHandler, useCallback, useMemo, useState } from \"react\";\nimport { CommitHandler, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { VuuTypeaheadInputProps } from \"@vuu-ui/vuu-ui-controls\";\nimport { getOperators } from \"../filter-clause/operator-utils\";\n\nexport const assertValidOperator = (\n allowedOperators: FilterClauseOp[],\n column: ColumnDescriptor,\n op: ColumnFilterOp,\n) => {\n if (op !== \"between\" && !allowedOperators.includes(op)) {\n console.warn(\n `[useColumnFilter] '${op} not supported for column ${column.name}'`,\n );\n }\n};\n\nexport type ColumnFilterCommitHandler = (\n column: ColumnDescriptor,\n op: FilterClauseOp | \"between\",\n value: ColumnFilterValue,\n) => void;\n\nexport const assertValidValue = (\n { serverDataType: _ }: ColumnDescriptor,\n operator: ColumnFilterOp,\n value?: ColumnFilterValue,\n) => {\n if (value !== undefined) {\n if (operator === \"between\") {\n if (!Array.isArray(value) || value.length !== 2) {\n throw Error(\n `[useColumnFilter] between operator requires array of two values, received ${value}`,\n );\n } else if (\n value[0] !== undefined &&\n value[1] !== undefined &&\n typeof value[0] !== typeof value[1]\n ) {\n throw Error(\n `[useColumnFilter] 'between operator values must be of same type, received ${typeof value[0]} and ${typeof value[1]}`,\n );\n }\n }\n // TODO validate value(s) against serverDataType\n }\n};\n\nexport type ColumnFilterHookProps = {\n column: ColumnDescriptor;\n operator?: ColumnFilterOp;\n /**\n * Filter value. Pair of values expected when operator is\n * 'between'\n */\n value?: ColumnFilterValue;\n /**\n * Filter change events.\n */\n onColumnFilterChange?: ColumnFilterChangeHandler;\n /**\n * Called when user 'commits' filter value, either by pressing enter,\n * tabbing away from control or making selection from list\n */\n onCommit: ColumnFilterCommitHandler;\n};\n\nexport const useColumnFilter = ({\n onCommit,\n operator = \"=\",\n value,\n column,\n onColumnFilterChange,\n}: ColumnFilterHookProps) => {\n const [op, setOp] = useState(operator);\n const allowedOperators = useMemo(() => getOperators(column), [column]);\n\n useMemo(() => {\n assertValidOperator(allowedOperators, column, operator);\n assertValidValue(column, op, value);\n }, [allowedOperators, column, operator, op, value]);\n\n const handleOperatorChange = useCallback((changedOp: ColumnFilterOp) => {\n setOp(changedOp);\n }, []);\n\n const handleCommit = useCallback<CommitHandler<HTMLElement>>(\n (_e, newValue) => {\n if (Array.isArray(value)) {\n onCommit?.(column, op, [`${newValue}`, value[1]]);\n } else {\n onCommit?.(column, op, `${newValue}`);\n }\n },\n [value, onCommit, column, op],\n );\n\n const handleRangeCommit = useCallback<CommitHandler<HTMLElement>>(\n (_e, newValue) => {\n const [firstValue] = value as [string, string];\n onCommit?.(column, op, [firstValue, `${newValue}`]);\n },\n [onCommit, column, op, value],\n );\n\n const handleInputChange = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (e) => {\n if (Array.isArray(value)) {\n const editControl = queryClosest(e.target, \"[data-edit-control]\", true);\n const updated: ColumnFilterValue = [\n !editControl.className.includes(\"rangeHigh\")\n ? e.target.value\n : value[0],\n editControl.className?.includes(\"rangeHigh\")\n ? e.target.value\n : value[1],\n ];\n onColumnFilterChange?.(updated, column, op);\n } else {\n onColumnFilterChange?.(e.target.value, column, op);\n }\n },\n [value, onColumnFilterChange, column, op],\n );\n\n const inputProps = useMemo<VuuTypeaheadInputProps[\"inputProps\"]>(\n () => ({\n onChange: handleInputChange,\n value: Array.isArray(value) ? value[0] : value,\n }),\n [handleInputChange, value],\n );\n\n const rangeInputProps = useMemo<VuuTypeaheadInputProps[\"inputProps\"]>(\n () =>\n Array.isArray(value)\n ? {\n onChange: handleInputChange,\n value: value[1],\n }\n : undefined,\n [handleInputChange, value],\n );\n\n return {\n op,\n allowedOperators,\n inputProps,\n rangeInputProps,\n onCommit: handleCommit,\n onCommitRange: handleRangeCommit,\n handleOperatorChange,\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/useColumnFilter.ts"],"sourcesContent":["import {\n ColumnFilterChangeHandler,\n ColumnFilterOp,\n ColumnFilterValue,\n FilterClauseOp,\n} from \"@vuu-ui/vuu-filter-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { ChangeEventHandler, useCallback, useMemo, useState } from \"react\";\nimport { CommitHandler } from \"@vuu-ui/vuu-utils\";\nimport { VuuTypeaheadInputProps } from \"@vuu-ui/vuu-ui-controls\";\nimport { getOperators } from \"../filter-clause/operator-utils\";\n\nexport const assertValidOperator = (\n allowedOperators: FilterClauseOp[],\n column: ColumnDescriptor,\n op: ColumnFilterOp,\n) => {\n if (op !== \"between\" && !allowedOperators.includes(op)) {\n console.warn(\n `[useColumnFilter] '${op} not supported for column ${column.name}'`,\n );\n }\n};\n\nexport type ColumnFilterCommitHandler = (\n column: ColumnDescriptor,\n op: FilterClauseOp | \"between\",\n value: ColumnFilterValue,\n) => void;\n\nexport const assertValidValue = (\n { serverDataType: _ }: ColumnDescriptor,\n operator: ColumnFilterOp,\n value?: ColumnFilterValue,\n) => {\n if (value !== undefined) {\n if (operator === \"between\") {\n if (!Array.isArray(value) || value.length !== 2) {\n throw Error(\n `[useColumnFilter] between operator requires array of two values, received ${value}`,\n );\n } else if (\n value[0] !== undefined &&\n value[1] !== undefined &&\n typeof value[0] !== typeof value[1]\n ) {\n throw Error(\n `[useColumnFilter] 'between operator values must be of same type, received ${typeof value[0]} and ${typeof value[1]}`,\n );\n }\n }\n // TODO validate value(s) against serverDataType\n }\n};\n\nexport type ColumnFilterHookProps = {\n column: ColumnDescriptor;\n operator?: ColumnFilterOp;\n /**\n * Filter value. Pair of values expected when operator is\n * 'between'\n */\n value?: ColumnFilterValue;\n /**\n * Filter change events.\n */\n onColumnFilterChange?: ColumnFilterChangeHandler;\n /**\n * Filter change events on second control in range filter\n */\n onColumnRangeFilterChange?: ColumnFilterChangeHandler;\n /**\n * Called when user 'commits' filter value, either by pressing enter,\n * tabbing away from control or making selection from list\n */\n onCommit: ColumnFilterCommitHandler;\n};\n\nexport const useColumnFilter = ({\n onCommit,\n operator = \"=\",\n value,\n column,\n onColumnFilterChange,\n onColumnRangeFilterChange,\n}: ColumnFilterHookProps) => {\n const [op, setOp] = useState(operator);\n const allowedOperators = useMemo(() => getOperators(column), [column]);\n\n useMemo(() => {\n assertValidOperator(allowedOperators, column, operator);\n assertValidValue(column, op, value);\n }, [allowedOperators, column, operator, op, value]);\n\n const handleOperatorChange = useCallback((changedOp: ColumnFilterOp) => {\n setOp(changedOp);\n }, []);\n\n const handleCommit = useCallback<CommitHandler<HTMLElement>>(\n (_e, newValue) => {\n if (Array.isArray(value)) {\n onCommit?.(column, op, [`${newValue}`, value[1]]);\n } else {\n onCommit?.(column, op, `${newValue}`);\n }\n },\n [value, onCommit, column, op],\n );\n\n const handleRangeCommit = useCallback<CommitHandler<HTMLElement>>(\n (_e, newValue) => {\n const [firstValue] = value as [string, string];\n onCommit?.(column, op, [firstValue, `${newValue}`]);\n },\n [onCommit, column, op, value],\n );\n\n const handleInputChange = useCallback<ChangeEventHandler<HTMLInputElement>>(\n (e) => {\n onColumnFilterChange?.(e.target.value, column, op);\n },\n [onColumnFilterChange, column, op],\n );\n\n const handleRangeInputChange = useCallback<\n ChangeEventHandler<HTMLInputElement>\n >(\n (e) => {\n onColumnRangeFilterChange?.(e.target.value, column, op);\n },\n [onColumnRangeFilterChange, column, op],\n );\n\n const inputProps = useMemo<VuuTypeaheadInputProps[\"inputProps\"]>(\n () => ({\n onChange: handleInputChange,\n value: Array.isArray(value) ? value[0] : value,\n }),\n [handleInputChange, value],\n );\n\n const rangeInputProps = useMemo<VuuTypeaheadInputProps[\"inputProps\"]>(\n () =>\n Array.isArray(value)\n ? {\n onChange: handleRangeInputChange,\n value: value[1],\n }\n : undefined,\n [handleRangeInputChange, value],\n );\n\n return {\n op,\n allowedOperators,\n inputProps,\n rangeInputProps,\n onCommit: handleCommit,\n onCommitRange: handleRangeCommit,\n handleOperatorChange,\n };\n};\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,21 +1,21 @@
1
1
  {
2
- "version": "0.13.38",
2
+ "version": "0.13.40",
3
3
  "author": "heswell",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "devDependencies": {
7
- "@vuu-ui/vuu-data-types": "0.13.38",
8
- "@vuu-ui/vuu-protocol-types": "0.13.38",
9
- "@vuu-ui/vuu-table-types": "0.13.38",
10
- "@vuu-ui/vuu-filter-types": "0.13.38"
7
+ "@vuu-ui/vuu-data-types": "0.13.40",
8
+ "@vuu-ui/vuu-protocol-types": "0.13.40",
9
+ "@vuu-ui/vuu-table-types": "0.13.40",
10
+ "@vuu-ui/vuu-filter-types": "0.13.40"
11
11
  },
12
12
  "dependencies": {
13
- "@vuu-ui/vuu-data-react": "0.13.38",
14
- "@vuu-ui/vuu-filter-parser": "0.13.38",
15
- "@vuu-ui/vuu-popups": "0.13.38",
16
- "@vuu-ui/vuu-ui-controls": "0.13.38",
17
- "@vuu-ui/vuu-table": "0.13.38",
18
- "@vuu-ui/vuu-utils": "0.13.38",
13
+ "@vuu-ui/vuu-data-react": "0.13.40",
14
+ "@vuu-ui/vuu-filter-parser": "0.13.40",
15
+ "@vuu-ui/vuu-popups": "0.13.40",
16
+ "@vuu-ui/vuu-ui-controls": "0.13.40",
17
+ "@vuu-ui/vuu-table": "0.13.40",
18
+ "@vuu-ui/vuu-utils": "0.13.40",
19
19
  "@salt-ds/core": "1.43.0",
20
20
  "@salt-ds/styles": "0.2.1",
21
21
  "@salt-ds/window": "0.1.1"
@@ -16,13 +16,17 @@ export type ColumnFilterHookProps = {
16
16
  * Filter change events.
17
17
  */
18
18
  onColumnFilterChange?: ColumnFilterChangeHandler;
19
+ /**
20
+ * Filter change events on second control in range filter
21
+ */
22
+ onColumnRangeFilterChange?: ColumnFilterChangeHandler;
19
23
  /**
20
24
  * Called when user 'commits' filter value, either by pressing enter,
21
25
  * tabbing away from control or making selection from list
22
26
  */
23
27
  onCommit: ColumnFilterCommitHandler;
24
28
  };
25
- export declare const useColumnFilter: ({ onCommit, operator, value, column, onColumnFilterChange, }: ColumnFilterHookProps) => {
29
+ export declare const useColumnFilter: ({ onCommit, operator, value, column, onColumnFilterChange, onColumnRangeFilterChange, }: ColumnFilterHookProps) => {
26
30
  op: "contains" | "starts" | "=" | "!=" | ">" | ">=" | "<=" | "<" | "ends" | "in" | "between";
27
31
  allowedOperators: FilterClauseOp[];
28
32
  inputProps: (Partial<import("react").InputHTMLAttributes<HTMLInputElement>> & import("@salt-ds/core").DataAttributes) | undefined;