@vuu-ui/vuu-filters 0.13.23 → 0.13.25
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/cjs/column-filter/ColumnFilter.css.js +6 -0
- package/cjs/column-filter/ColumnFilter.css.js.map +1 -0
- package/cjs/column-filter/ColumnFilter.js +78 -0
- package/cjs/column-filter/ColumnFilter.js.map +1 -0
- package/cjs/column-filter/useColumnFilter.js +24 -0
- package/cjs/column-filter/useColumnFilter.js.map +1 -0
- package/cjs/filter-bar/FilterBar.js.map +1 -1
- package/cjs/filter-clause/filterClauseFocusManagement.js +1 -1
- package/cjs/filter-clause/filterClauseFocusManagement.js.map +1 -1
- package/cjs/filter-clause/value-editors/FilterClauseValueEditor.js +12 -0
- package/cjs/filter-clause/value-editors/FilterClauseValueEditor.js.map +1 -1
- package/cjs/filter-clause/value-editors/FilterClauseValueEditorTime.js +62 -0
- package/cjs/filter-clause/value-editors/FilterClauseValueEditorTime.js.map +1 -0
- package/cjs/index.js +2 -0
- package/cjs/index.js.map +1 -1
- package/esm/column-filter/ColumnFilter.css.js +4 -0
- package/esm/column-filter/ColumnFilter.css.js.map +1 -0
- package/esm/column-filter/ColumnFilter.js +76 -0
- package/esm/column-filter/ColumnFilter.js.map +1 -0
- package/esm/column-filter/useColumnFilter.js +22 -0
- package/esm/column-filter/useColumnFilter.js.map +1 -0
- package/esm/filter-bar/FilterBar.js.map +1 -1
- package/esm/filter-clause/filterClauseFocusManagement.js +1 -1
- package/esm/filter-clause/filterClauseFocusManagement.js.map +1 -1
- package/esm/filter-clause/value-editors/FilterClauseValueEditor.js +13 -1
- package/esm/filter-clause/value-editors/FilterClauseValueEditor.js.map +1 -1
- package/esm/filter-clause/value-editors/FilterClauseValueEditorTime.js +60 -0
- package/esm/filter-clause/value-editors/FilterClauseValueEditorTime.js.map +1 -0
- package/esm/index.js +1 -0
- package/esm/index.js.map +1 -1
- package/package.json +11 -11
- package/types/column-filter/ColumnFilter.d.ts +16 -0
- package/types/column-filter/useColumnFilter.d.ts +8 -0
- package/types/filter-bar/FilterBar.d.ts +1 -1
- package/types/filter-clause/value-editors/FilterClauseValueEditorTime.d.ts +9 -0
- package/types/index.d.ts +1 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var columnFilterCss = ".vuuColumnFilter {\n border: solid 1px var(--salt-editable-borderColor);\n border-radius: 4px;\n max-width: 200px;\n}\n\n.vuuColumnFilter-trigger {\n --saltButton-borderRadius: 4px 0px 0px 4px;\n --saltButton-padding: var(--salt-spacing-200);\n}\n";
|
|
4
|
+
|
|
5
|
+
module.exports = columnFilterCss;
|
|
6
|
+
//# sourceMappingURL=ColumnFilter.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColumnFilter.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var core = require('@salt-ds/core');
|
|
5
|
+
var styles = require('@salt-ds/styles');
|
|
6
|
+
var window = require('@salt-ds/window');
|
|
7
|
+
var cx = require('clsx');
|
|
8
|
+
var ColumnFilter$1 = require('./ColumnFilter.css.js');
|
|
9
|
+
var vuuDataReact = require('@vuu-ui/vuu-data-react');
|
|
10
|
+
var react = require('react');
|
|
11
|
+
var useColumnFilter = require('./useColumnFilter.js');
|
|
12
|
+
|
|
13
|
+
const classBase = "vuuColumnFilter";
|
|
14
|
+
const ColumnFilter = ({
|
|
15
|
+
column,
|
|
16
|
+
className,
|
|
17
|
+
operator = "=",
|
|
18
|
+
showOperatorPicker = false,
|
|
19
|
+
table,
|
|
20
|
+
value,
|
|
21
|
+
...buttonGroupProps
|
|
22
|
+
}) => {
|
|
23
|
+
const targetWindow = window.useWindow();
|
|
24
|
+
styles.useComponentCssInjection({
|
|
25
|
+
testId: "vuu-filter-bar",
|
|
26
|
+
css: ColumnFilter$1,
|
|
27
|
+
window: targetWindow
|
|
28
|
+
});
|
|
29
|
+
react.useMemo(
|
|
30
|
+
() => useColumnFilter.assertValidValue(column, operator, value),
|
|
31
|
+
[column, operator, value]
|
|
32
|
+
);
|
|
33
|
+
const onCommit = react.useCallback((e, value2) => {
|
|
34
|
+
console.log(`onCommit ${value2}`);
|
|
35
|
+
}, []);
|
|
36
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
37
|
+
core.SegmentedButtonGroup,
|
|
38
|
+
{
|
|
39
|
+
...buttonGroupProps,
|
|
40
|
+
className: cx(classBase, className),
|
|
41
|
+
children: [
|
|
42
|
+
showOperatorPicker ? /* @__PURE__ */ jsxRuntime.jsxs(core.Menu, { placement: "bottom-start", children: [
|
|
43
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.MenuTrigger, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
44
|
+
core.Button,
|
|
45
|
+
{
|
|
46
|
+
appearance: "solid",
|
|
47
|
+
"aria-label": "Open Menu",
|
|
48
|
+
className: `${classBase}-trigger`,
|
|
49
|
+
"data-embedded": true,
|
|
50
|
+
sentiment: "neutral",
|
|
51
|
+
children: operator
|
|
52
|
+
}
|
|
53
|
+
) }),
|
|
54
|
+
/* @__PURE__ */ jsxRuntime.jsxs(core.MenuPanel, { children: [
|
|
55
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.MenuItem, { children: "=" }),
|
|
56
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.MenuItem, { children: "!=" }),
|
|
57
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.MenuItem, { children: "starts" }),
|
|
58
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.MenuItem, { children: "ends" }),
|
|
59
|
+
/* @__PURE__ */ jsxRuntime.jsx(core.MenuItem, { children: "contains" })
|
|
60
|
+
] })
|
|
61
|
+
] }) : null,
|
|
62
|
+
vuuDataReact.getDataItemEditControl({
|
|
63
|
+
dataDescriptor: column,
|
|
64
|
+
onCommit,
|
|
65
|
+
table
|
|
66
|
+
}),
|
|
67
|
+
operator === "between" ? vuuDataReact.getDataItemEditControl({
|
|
68
|
+
dataDescriptor: column,
|
|
69
|
+
onCommit,
|
|
70
|
+
table
|
|
71
|
+
}) : null
|
|
72
|
+
]
|
|
73
|
+
}
|
|
74
|
+
);
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
exports.ColumnFilter = ColumnFilter;
|
|
78
|
+
//# sourceMappingURL=ColumnFilter.js.map
|
|
@@ -0,0 +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 { useCallback, useMemo } from \"react\";\nimport { CommitHandler } from \"@vuu-ui/vuu-utils\";\nimport { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n assertValidValue,\n ColumnFilterHookProps,\n FilterValue,\n} from \"./useColumnFilter\";\n\nconst classBase = \"vuuColumnFilter\";\n\nexport interface ColumnFilterProps\n extends ColumnFilterHookProps,\n SegmentedButtonGroupProps {\n showOperatorPicker?: boolean;\n /**\n * VuuTable is required if typeahead support is expected.\n */\n table?: VuuTable;\n\n /**\n * Initial filter value. Pair of values expewcted when operator is\n * 'between'\n */\n value?: FilterValue | [FilterValue, FilterValue];\n}\n\nexport const ColumnFilter = ({\n column,\n className,\n operator = \"=\",\n showOperatorPicker = false,\n table,\n value,\n ...buttonGroupProps\n}: ColumnFilterProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-filter-bar\",\n css: columnFilterCss,\n window: targetWindow,\n });\n\n useMemo(\n () => assertValidValue(column, operator, value),\n [column, operator, value],\n );\n\n const onCommit = useCallback<CommitHandler<HTMLElement>>((e, value) => {\n console.log(`onCommit ${value}`);\n }, []);\n\n return (\n <SegmentedButtonGroup\n {...buttonGroupProps}\n className={cx(classBase, className)}\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 {operator}\n </Button>\n </MenuTrigger>\n <MenuPanel>\n <MenuItem>=</MenuItem>\n <MenuItem>!=</MenuItem>\n <MenuItem>starts</MenuItem>\n <MenuItem>ends</MenuItem>\n <MenuItem>contains</MenuItem>\n </MenuPanel>\n </Menu>\n ) : null}\n {getDataItemEditControl({\n dataDescriptor: column,\n onCommit,\n table,\n })}\n {operator === \"between\"\n ? getDataItemEditControl({\n dataDescriptor: column,\n onCommit,\n table,\n })\n : null}\n </SegmentedButtonGroup>\n );\n};\n"],"names":["useWindow","useComponentCssInjection","columnFilterCss","useMemo","assertValidValue","useCallback","value","jsxs","SegmentedButtonGroup","Menu","jsx","MenuTrigger","Button","MenuPanel","MenuItem","getDataItemEditControl"],"mappings":";;;;;;;;;;;;AAwBA,MAAM,SAAY,GAAA,iBAAA;AAkBX,MAAM,eAAe,CAAC;AAAA,EAC3B,MAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAW,GAAA,GAAA;AAAA,EACX,kBAAqB,GAAA,KAAA;AAAA,EACrB,KAAA;AAAA,EACA,KAAA;AAAA,EACA,GAAG;AACL,CAAyB,KAAA;AACvB,EAAA,MAAM,eAAeA,gBAAU,EAAA;AAC/B,EAAyBC,+BAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,gBAAA;AAAA,IACR,GAAK,EAAAC,cAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAAC,aAAA;AAAA,IACE,MAAMC,gCAAA,CAAiB,MAAQ,EAAA,QAAA,EAAU,KAAK,CAAA;AAAA,IAC9C,CAAC,MAAQ,EAAA,QAAA,EAAU,KAAK;AAAA,GAC1B;AAEA,EAAA,MAAM,QAAW,GAAAC,iBAAA,CAAwC,CAAC,CAAA,EAAGC,MAAU,KAAA;AACrE,IAAQ,OAAA,CAAA,GAAA,CAAI,CAAYA,SAAAA,EAAAA,MAAK,CAAE,CAAA,CAAA;AAAA,GACjC,EAAG,EAAE,CAAA;AAEL,EACE,uBAAAC,eAAA;AAAA,IAACC,yBAAA;AAAA,IAAA;AAAA,MACE,GAAG,gBAAA;AAAA,MACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CAAA;AAAA,MAEjC,QAAA,EAAA;AAAA,QACC,kBAAA,mBAAAD,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,0CACCC,cACC,EAAA,EAAA,QAAA,EAAA;AAAA,4BAAAH,cAAA,CAACI,iBAAS,QAAC,EAAA,GAAA,EAAA,CAAA;AAAA,4BACXJ,cAAA,CAACI,iBAAS,QAAE,EAAA,IAAA,EAAA,CAAA;AAAA,4BACZJ,cAAA,CAACI,iBAAS,QAAM,EAAA,QAAA,EAAA,CAAA;AAAA,4BAChBJ,cAAA,CAACI,iBAAS,QAAI,EAAA,MAAA,EAAA,CAAA;AAAA,4BACdJ,cAAA,CAACI,iBAAS,QAAQ,EAAA,UAAA,EAAA;AAAA,WACpB,EAAA;AAAA,SAAA,EACF,CACE,GAAA,IAAA;AAAA,QACHC,mCAAuB,CAAA;AAAA,UACtB,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,QACA,QAAA,KAAa,YACVA,mCAAuB,CAAA;AAAA,UACrB,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAA;AAAA,UACA;AAAA,SACD,CACD,GAAA;AAAA;AAAA;AAAA,GACN;AAEJ;;;;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const assertValidValue = ({ serverDataType: _ }, operator, value) => {
|
|
4
|
+
if (value !== void 0) {
|
|
5
|
+
if (operator === "between") {
|
|
6
|
+
if (!Array.isArray(value)) {
|
|
7
|
+
throw Error(
|
|
8
|
+
"[useColumnFilter] 'between operator requires array of two values'"
|
|
9
|
+
);
|
|
10
|
+
} else if (value.length !== 2) {
|
|
11
|
+
throw Error(
|
|
12
|
+
`[useColumnFilter] 'between operator requires two values, received ${value.length}'`
|
|
13
|
+
);
|
|
14
|
+
} else if (typeof value[0] !== typeof value[1]) {
|
|
15
|
+
throw Error(
|
|
16
|
+
`[useColumnFilter] 'between operator values must be of same type, received ${typeof value[0]} and ${typeof value[1]}`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
exports.assertValidValue = assertValidValue;
|
|
24
|
+
//# sourceMappingURL=useColumnFilter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/useColumnFilter.ts"],"sourcesContent":["import { FilterOp } from \"@vuu-ui/vuu-filter-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\n\nexport type FilterValue = string | number;\n\nexport const assertValidValue = (\n { serverDataType: _ }: ColumnDescriptor,\n operator: FilterOp | \"between\",\n value?: FilterValue | FilterValue[],\n) => {\n if (value !== undefined) {\n if (operator === \"between\") {\n if (!Array.isArray(value)) {\n throw Error(\n \"[useColumnFilter] 'between operator requires array of two values'\",\n );\n } else if (value.length !== 2) {\n throw Error(\n `[useColumnFilter] 'between operator requires two values, received ${value.length}'`,\n );\n } else if (typeof value[0] !== typeof value[1]) {\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 interface ColumnFilterHookProps {\n column: ColumnDescriptor;\n operator?: FilterOp | \"between\";\n}\n\n// export const useColumnFilter = ({\n// column,\n// operator = \"=\",\n// }: ColumnFilterHookProps) => {};\n"],"names":[],"mappings":";;AAKO,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,KAAA,CAAM,OAAQ,CAAA,KAAK,CAAG,EAAA;AACzB,QAAM,MAAA,KAAA;AAAA,UACJ;AAAA,SACF;AAAA,OACF,MAAA,IAAW,KAAM,CAAA,MAAA,KAAW,CAAG,EAAA;AAC7B,QAAM,MAAA,KAAA;AAAA,UACJ,CAAA,kEAAA,EAAqE,MAAM,MAAM,CAAA,CAAA;AAAA,SACnF;AAAA,OACF,MAAA,IAAW,OAAO,KAAM,CAAA,CAAC,MAAM,OAAO,KAAA,CAAM,CAAC,CAAG,EAAA;AAC9C,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;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterBar.js","sources":["../../../../packages/vuu-filters/src/filter-bar/FilterBar.tsx"],"sourcesContent":["import { DataSourceFilter } from \"@vuu-ui/vuu-data-types\";\nimport { Filter, FilterState } from \"@vuu-ui/vuu-filter-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { Icon } from \"@vuu-ui/vuu-ui-controls\";\nimport { ToggleButton, ToggleButtonGroup } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport { HTMLAttributes, useMemo } from \"react\";\nimport { CustomFilters } from \"../custom-filters\";\nimport { QuickFilterProps, QuickFilters } from \"../quick-filters\";\nimport { FilterMode, useFilterBar } from \"./useFilterBar\";\
|
|
1
|
+
{"version":3,"file":"FilterBar.js","sources":["../../../../packages/vuu-filters/src/filter-bar/FilterBar.tsx"],"sourcesContent":["import { DataSourceFilter } from \"@vuu-ui/vuu-data-types\";\nimport { Filter, FilterState } from \"@vuu-ui/vuu-filter-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { Icon } from \"@vuu-ui/vuu-ui-controls\";\nimport { ToggleButton, ToggleButtonGroup } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport { HTMLAttributes, useMemo } from \"react\";\nimport { CustomFilters } from \"../custom-filters\";\nimport { QuickFilterProps, QuickFilters } from \"../quick-filters\";\nimport { FilterMode, useFilterBar } from \"./useFilterBar\";\nimport type { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\n\nimport filterBarCss from \"./FilterBar.css\";\n\nexport type FilterBarVariant =\n | \"custom-filters-only\"\n | \"quick-filters-only\"\n | \"full-filters\";\n\nexport interface FilterBarProps extends HTMLAttributes<HTMLDivElement> {\n QuickFilterProps?: Pick<\n QuickFilterProps,\n \"quickFilterColumns\" | \"onChangeQuickFilterColumns\"\n >;\n /**\n * Used to ensure we present filter editors appropriate to the data type of column.\n * NOTE: Always make sure that these are passed with proper re-render optimization (i.e make\n * sure its a stable reference, in React terminology), otherwise might end up with infinite\n * state updates.\n */\n columnDescriptors: ColumnDescriptor[];\n defaultFilterMode?: FilterMode;\n defaultFilterState?: FilterState;\n filterMode?: FilterMode;\n filterState?: FilterState;\n onApplyFilter: (filter: DataSourceFilter) => void;\n onChangeFilterMode?: (filterMode: FilterMode) => void;\n onFilterDeleted?: (filter: Filter) => void;\n onFilterRenamed?: (filter: Filter, name: string) => void;\n onFilterStateChanged?: (state: FilterState) => void;\n /**\n * Defines table used in call to Vuu Typeahead service\n */\n vuuTable?: VuuTable;\n variant?: FilterBarVariant;\n}\n\nconst classBase = \"vuuFilterBar\";\n\nexport const FilterBar = ({\n QuickFilterProps,\n className: classNameProp,\n columnDescriptors,\n defaultFilterMode,\n defaultFilterState,\n filterMode: filterModeProp,\n filterState,\n onApplyFilter,\n onChangeFilterMode: onChangeFilterModeProp,\n onFilterDeleted,\n onFilterRenamed,\n onFilterStateChanged,\n vuuTable,\n variant = \"custom-filters-only\",\n ...htmlAttributes\n}: FilterBarProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-filter-bar\",\n css: filterBarCss,\n window: targetWindow,\n });\n\n const allowCustomFilters = variant !== \"quick-filters-only\";\n const allowQuickFilters = variant !== \"custom-filters-only\";\n\n const controlledFilterMode: FilterMode | undefined = !allowCustomFilters\n ? \"quick-filter\"\n : !allowQuickFilters\n ? \"custom-filter\"\n : filterModeProp;\n\n const { filterMode, onChangeFilterMode } = useFilterBar({\n defaultFilterMode,\n filterMode: controlledFilterMode,\n onChangeFilterMode: onChangeFilterModeProp,\n });\n\n const className = cx(classBase, classNameProp);\n\n const startAdornment = useMemo(() => {\n if (!allowQuickFilters) {\n return <Icon name=\"filter\" size={16} style={{ top: 4 }} />;\n } else {\n return (\n <ToggleButtonGroup\n data-variant=\"secondary\"\n onChange={onChangeFilterMode}\n value={filterMode}\n >\n <ToggleButton\n className=\"vuuIconToggleButton\"\n key=\"custom-filter\"\n value=\"custom-filter\"\n aria-label=\"Custom filters\"\n tabIndex={-1}\n >\n <Icon name=\"grid\" size={16} />\n </ToggleButton>\n <ToggleButton\n className=\"vuuIconToggleButton\"\n key=\"quick-filter\"\n value=\"quick-filter\"\n aria-label=\"Quick filters\"\n tabIndex={-1}\n >\n <Icon name=\"tune\" size={16} />\n </ToggleButton>\n </ToggleButtonGroup>\n );\n }\n }, [allowQuickFilters, filterMode, onChangeFilterMode]);\n\n return (\n <div\n {...htmlAttributes}\n className={cx(className, `${classBase}-${filterMode}-mode`)}\n >\n {variant === \"quick-filters-only\" ? null : (\n <div className={`${classBase}-iconContainer`}>{startAdornment}</div>\n )}\n {filterMode === \"custom-filter\" ? (\n <CustomFilters\n columnDescriptors={columnDescriptors}\n defaultFilterState={defaultFilterState}\n filterState={filterState}\n onApplyFilter={onApplyFilter}\n onFilterDeleted={onFilterDeleted}\n onFilterRenamed={onFilterRenamed}\n onFilterStateChanged={onFilterStateChanged}\n vuuTable={vuuTable}\n />\n ) : (\n <QuickFilters\n {...QuickFilterProps}\n availableColumns={columnDescriptors}\n onApplyFilter={onApplyFilter}\n vuuTable={vuuTable}\n />\n )}\n </div>\n );\n};\n"],"names":["QuickFilterProps","useWindow","useComponentCssInjection","filterBarCss","useFilterBar","useMemo","jsx","Icon","jsxs","ToggleButtonGroup","ToggleButton","CustomFilters","QuickFilters"],"mappings":"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"}
|
|
@@ -31,7 +31,7 @@ const getFocusedFieldDetails = () => {
|
|
|
31
31
|
return [vuuUtils.getElementDataIndex(filterClause), getFilterClauseDetails(field)];
|
|
32
32
|
}
|
|
33
33
|
} else if (field?.matches(".saltCalendar")) {
|
|
34
|
-
console.log("
|
|
34
|
+
console.log("its in a calendar");
|
|
35
35
|
}
|
|
36
36
|
return [];
|
|
37
37
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filterClauseFocusManagement.js","sources":["../../../../packages/vuu-filters/src/filter-clause/filterClauseFocusManagement.ts"],"sourcesContent":["import { getElementDataIndex, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { KeyboardEvent } from \"react\";\n\nconst getFilterClauseElement = (possiblyDescendant?: HTMLElement) =>\n possiblyDescendant?.closest(\".vuuFilterClause\") as HTMLElement;\n\nconst getFilterClauseFieldElement = (possiblyDescendant?: HTMLElement) =>\n possiblyDescendant?.closest(\".vuuFilterClauseField\") as HTMLElement;\n\ntype FilterClauseFieldName = \"column\" | \"operator\" | \"value\";\nconst mapFilterFieldToClassName: Record<FilterClauseFieldName, string> = {\n column: \"vuuFilterClauseColumn\",\n operator: \"vuuFilterClauseOperator\",\n value: \"vuuFilterClauseValue\",\n};\n\nconst getFilterClauseDetails = ({ classList }: HTMLElement) => {\n if (classList.contains(\"vuuFilterClauseColumn\")) {\n return \"column\";\n } else if (classList.contains(\"vuuFilterClauseOperator\")) {\n return \"operator\";\n } else if (classList.contains(\"vuuFilterClauseValue\")) {\n return \"value\";\n } else {\n throw Error(\n \"getFilterClauseField, filterClauseElemnent is missing required class name\",\n );\n }\n};\n\nexport const getFocusedFieldDetails = (): [number, string] | [] => {\n const el = document.activeElement as HTMLElement;\n const field = queryClosest(el, \".vuuFilterClauseField,.saltCalendar\");\n if (field?.matches(\".vuuFilterClauseField\")) {\n const filterClause = queryClosest(field, \".vuuFilterClause\");\n if (filterClause && field) {\n return [getElementDataIndex(filterClause), getFilterClauseDetails(field)];\n }\n } else if (field?.matches(\".saltCalendar\")) {\n console.log(\"muthafucker is ins a calendar\");\n }\n // const filterClause = queryClosest(field, \".vuuFilterClause\");\n // if (filterClause && field) {\n // return [getElementDataIndex(filterClause), getFilterClauseDetails(field)];\n // } else {\n return [];\n // }\n};\n\n// Focus the input control within field. If clause passed, will\n// focus first field within clause\nconst focusField = (fieldOrClause: HTMLElement | null) => {\n const input = fieldOrClause?.querySelector(\"input\");\n if (input) {\n input.focus();\n requestAnimationFrame(() => {\n input?.select();\n });\n }\n};\n\nexport const elementIsFilterCombinator = (\n element: Element | null,\n): element is HTMLElement =>\n element !== null && element.classList.contains(\"vuuFilterClauseCombinator\");\n\nexport const elementIsFilterClause = (\n element: Element | null,\n): element is HTMLElement =>\n element !== null && element.classList.contains(\"vuuFilterClause\");\n\nexport const focusFilterClauseField = (\n filterEditor: HTMLElement,\n filterClauseIndex: number,\n fieldName: FilterClauseFieldName = \"value\",\n) => {\n if (filterEditor) {\n const fieldClassName = mapFilterFieldToClassName[fieldName];\n const field = filterEditor.querySelector(\n `.vuuFilterClause[data-index=\"${filterClauseIndex}\"] .${fieldClassName}`,\n ) as HTMLElement;\n focusField(field);\n }\n};\n\nexport const focusLastClauseValue = (filterEditor: HTMLElement) => {\n console.log(\"focusLastClauseValue\");\n const field = Array.from(\n filterEditor?.querySelectorAll(\".vuuFilterClauseField\"),\n ).at(-1) as HTMLElement;\n focusField(field);\n};\n\nexport const focusNextFocusableElement = (direction: \"fwd\" | \"bwd\" = \"fwd\") => {\n const activeField = getFocusedField() as HTMLElement;\n const filterClause = getFilterClauseElement(activeField);\n if (direction === \"fwd\" && filterClause?.lastChild === activeField) {\n requestAnimationFrame(() => {\n focusNextFocusableElement();\n });\n } else {\n const nextField =\n direction === \"fwd\"\n ? (activeField?.nextElementSibling as HTMLElement)\n : (activeField?.previousElementSibling as HTMLElement);\n\n nextField?.querySelector(\"input\")?.focus();\n }\n};\n\nconst getFocusedField = () => {\n const activeElement = document.activeElement as HTMLElement;\n if (activeElement?.classList.contains(\"vuuFilterClause-clearButton\")) {\n return activeElement as HTMLElement;\n } else {\n return getFilterClauseFieldElement(activeElement);\n }\n};\n\nexport const focusNextElement = () => {\n const filterClauseField = getFocusedField();\n const filterClause = getFilterClauseElement(filterClauseField);\n if (filterClause && filterClauseField) {\n if (filterClauseField.classList.contains(\"vuuFilterClauseValue\")) {\n const clearButton = filterClause.querySelector(\n \".vuuFilterClause-clearButton\",\n ) as HTMLButtonElement;\n clearButton?.focus();\n } else {\n focusNextFocusableElement();\n }\n }\n};\n\nconst cursorAtTextStart = (input: HTMLInputElement) =>\n input.selectionStart === 0;\n\nconst cursorAtTextEnd = (input: HTMLInputElement) =>\n input.selectionStart === input.value.length;\n\nconst getFieldName = (field: HTMLElement) =>\n field?.classList.contains(\"vuuFilterClauseColumn\")\n ? \"column\"\n : field?.classList.contains(\"vuuFilterClauseOperator\")\n ? \"operator\"\n : \"value\";\n\nexport const clauseIsNotFirst = (el: HTMLElement) => {\n const clause = getFilterClauseElement(el);\n if (clause) {\n const index = getElementDataIndex(clause);\n return index > 0;\n }\n};\n\nconst clauseIsNotLast = (el: HTMLElement) => {\n const clause = getFilterClauseElement(el);\n const nextClause = clause?.nextElementSibling as HTMLElement;\n return nextClause?.classList.contains(\"vuuFilterClauseCombinator\");\n};\n\nexport const tabToPreviousFilterCombinator = (currentElement: HTMLElement) => {\n const filterClause = getFilterClauseElement(currentElement);\n const nextItem = filterClause.previousSibling as HTMLElement;\n console.log(`tab to previous combinator`);\n nextItem?.focus();\n};\n\nexport const navigateToNextFilterClause = (\n currentElement: HTMLElement,\n direction: \"bwd\" | \"fwd\" = \"fwd\",\n) => {\n if (direction === \"bwd\") {\n if (elementIsFilterCombinator(currentElement)) {\n const nextClause = currentElement.previousElementSibling;\n if (elementIsFilterClause(nextClause)) {\n const nextField = nextClause.querySelector(\n \".vuuFilterClauseValue\",\n ) as HTMLElement;\n console.log(`focus field Value ${nextField?.classList}`);\n focusField(nextField);\n }\n } else {\n const filterClause = getFilterClauseElement(currentElement);\n const nextClause = filterClause.previousSibling as HTMLElement;\n const nextField = nextClause.querySelector(\n \".vuuFilterClauseValue\",\n ) as HTMLElement;\n focusField(nextField);\n }\n } else {\n const nextClause = currentElement.nextSibling as HTMLElement;\n focusField(nextClause);\n }\n};\n\n// The logic around preventDefault/stopPropagation is important\n// in this function\nexport const navigateToNextItemIfAtBoundary = (\n evt: KeyboardEvent<HTMLInputElement>,\n) => {\n const input = evt.target as HTMLInputElement;\n const field = getFilterClauseFieldElement(input);\n if (evt.key === \"ArrowLeft\") {\n if (cursorAtTextStart(input)) {\n const fieldName = getFieldName(field);\n if (fieldName === \"column\") {\n if (clauseIsNotFirst(input)) {\n const filterClause = getFilterClauseElement(field);\n const combinator = filterClause.previousElementSibling as HTMLElement;\n combinator?.focus();\n }\n } else {\n evt.preventDefault();\n focusField(field.previousSibling as HTMLElement);\n }\n }\n // stopPropagation, even if cursor is not at start. We want the arrowLeft to move the cursor\n evt.stopPropagation();\n } else if (evt.key === \"ArrowRight\") {\n if (cursorAtTextEnd(input as HTMLInputElement)) {\n const fieldName = getFieldName(field);\n if (fieldName === \"value\") {\n if (clauseIsNotLast(input)) {\n const filterClause = getFilterClauseElement(field);\n const combinator = filterClause.nextElementSibling as HTMLElement;\n combinator?.focus();\n }\n // Do not preventDefault, stopPropagation\n return;\n } else {\n evt.preventDefault();\n focusField(field.nextSibling as HTMLElement);\n }\n }\n // stopPropagation, even if cursor is not at end. We want the arrowRight to move the cursor\n evt.stopPropagation();\n }\n};\n\nexport const focusFirstClauseIfAllClausesValid = (\n filterEditor: HTMLElement,\n) => {\n const columInput = Array.from(\n filterEditor.querySelectorAll(\".vuuFilterClauseColumn input\"),\n ) as HTMLInputElement[];\n if (columInput.every((input) => input.value.length > 0)) {\n setTimeout(() => {\n const input = columInput.at(0);\n input?.select();\n input?.focus();\n }, 100);\n }\n};\n"],"names":["queryClosest","getElementDataIndex"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"filterClauseFocusManagement.js","sources":["../../../../packages/vuu-filters/src/filter-clause/filterClauseFocusManagement.ts"],"sourcesContent":["import { getElementDataIndex, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { KeyboardEvent } from \"react\";\n\nconst getFilterClauseElement = (possiblyDescendant?: HTMLElement) =>\n possiblyDescendant?.closest(\".vuuFilterClause\") as HTMLElement;\n\nconst getFilterClauseFieldElement = (possiblyDescendant?: HTMLElement) =>\n possiblyDescendant?.closest(\".vuuFilterClauseField\") as HTMLElement;\n\ntype FilterClauseFieldName = \"column\" | \"operator\" | \"value\";\nconst mapFilterFieldToClassName: Record<FilterClauseFieldName, string> = {\n column: \"vuuFilterClauseColumn\",\n operator: \"vuuFilterClauseOperator\",\n value: \"vuuFilterClauseValue\",\n};\n\nconst getFilterClauseDetails = ({ classList }: HTMLElement) => {\n if (classList.contains(\"vuuFilterClauseColumn\")) {\n return \"column\";\n } else if (classList.contains(\"vuuFilterClauseOperator\")) {\n return \"operator\";\n } else if (classList.contains(\"vuuFilterClauseValue\")) {\n return \"value\";\n } else {\n throw Error(\n \"getFilterClauseField, filterClauseElemnent is missing required class name\",\n );\n }\n};\n\nexport const getFocusedFieldDetails = (): [number, string] | [] => {\n const el = document.activeElement as HTMLElement;\n const field = queryClosest(el, \".vuuFilterClauseField,.saltCalendar\");\n if (field?.matches(\".vuuFilterClauseField\")) {\n const filterClause = queryClosest(field, \".vuuFilterClause\");\n if (filterClause && field) {\n return [getElementDataIndex(filterClause), getFilterClauseDetails(field)];\n }\n } else if (field?.matches(\".saltCalendar\")) {\n console.log(\"its in a calendar\");\n }\n // const filterClause = queryClosest(field, \".vuuFilterClause\");\n // if (filterClause && field) {\n // return [getElementDataIndex(filterClause), getFilterClauseDetails(field)];\n // } else {\n return [];\n // }\n};\n\n// Focus the input control within field. If clause passed, will\n// focus first field within clause\nconst focusField = (fieldOrClause: HTMLElement | null) => {\n const input = fieldOrClause?.querySelector(\"input\");\n if (input) {\n input.focus();\n requestAnimationFrame(() => {\n input?.select();\n });\n }\n};\n\nexport const elementIsFilterCombinator = (\n element: Element | null,\n): element is HTMLElement =>\n element !== null && element.classList.contains(\"vuuFilterClauseCombinator\");\n\nexport const elementIsFilterClause = (\n element: Element | null,\n): element is HTMLElement =>\n element !== null && element.classList.contains(\"vuuFilterClause\");\n\nexport const focusFilterClauseField = (\n filterEditor: HTMLElement,\n filterClauseIndex: number,\n fieldName: FilterClauseFieldName = \"value\",\n) => {\n if (filterEditor) {\n const fieldClassName = mapFilterFieldToClassName[fieldName];\n const field = filterEditor.querySelector(\n `.vuuFilterClause[data-index=\"${filterClauseIndex}\"] .${fieldClassName}`,\n ) as HTMLElement;\n focusField(field);\n }\n};\n\nexport const focusLastClauseValue = (filterEditor: HTMLElement) => {\n console.log(\"focusLastClauseValue\");\n const field = Array.from(\n filterEditor?.querySelectorAll(\".vuuFilterClauseField\"),\n ).at(-1) as HTMLElement;\n focusField(field);\n};\n\nexport const focusNextFocusableElement = (direction: \"fwd\" | \"bwd\" = \"fwd\") => {\n const activeField = getFocusedField() as HTMLElement;\n const filterClause = getFilterClauseElement(activeField);\n if (direction === \"fwd\" && filterClause?.lastChild === activeField) {\n requestAnimationFrame(() => {\n focusNextFocusableElement();\n });\n } else {\n const nextField =\n direction === \"fwd\"\n ? (activeField?.nextElementSibling as HTMLElement)\n : (activeField?.previousElementSibling as HTMLElement);\n\n nextField?.querySelector(\"input\")?.focus();\n }\n};\n\nconst getFocusedField = () => {\n const activeElement = document.activeElement as HTMLElement;\n if (activeElement?.classList.contains(\"vuuFilterClause-clearButton\")) {\n return activeElement as HTMLElement;\n } else {\n return getFilterClauseFieldElement(activeElement);\n }\n};\n\nexport const focusNextElement = () => {\n const filterClauseField = getFocusedField();\n const filterClause = getFilterClauseElement(filterClauseField);\n if (filterClause && filterClauseField) {\n if (filterClauseField.classList.contains(\"vuuFilterClauseValue\")) {\n const clearButton = filterClause.querySelector(\n \".vuuFilterClause-clearButton\",\n ) as HTMLButtonElement;\n clearButton?.focus();\n } else {\n focusNextFocusableElement();\n }\n }\n};\n\nconst cursorAtTextStart = (input: HTMLInputElement) =>\n input.selectionStart === 0;\n\nconst cursorAtTextEnd = (input: HTMLInputElement) =>\n input.selectionStart === input.value.length;\n\nconst getFieldName = (field: HTMLElement) =>\n field?.classList.contains(\"vuuFilterClauseColumn\")\n ? \"column\"\n : field?.classList.contains(\"vuuFilterClauseOperator\")\n ? \"operator\"\n : \"value\";\n\nexport const clauseIsNotFirst = (el: HTMLElement) => {\n const clause = getFilterClauseElement(el);\n if (clause) {\n const index = getElementDataIndex(clause);\n return index > 0;\n }\n};\n\nconst clauseIsNotLast = (el: HTMLElement) => {\n const clause = getFilterClauseElement(el);\n const nextClause = clause?.nextElementSibling as HTMLElement;\n return nextClause?.classList.contains(\"vuuFilterClauseCombinator\");\n};\n\nexport const tabToPreviousFilterCombinator = (currentElement: HTMLElement) => {\n const filterClause = getFilterClauseElement(currentElement);\n const nextItem = filterClause.previousSibling as HTMLElement;\n console.log(`tab to previous combinator`);\n nextItem?.focus();\n};\n\nexport const navigateToNextFilterClause = (\n currentElement: HTMLElement,\n direction: \"bwd\" | \"fwd\" = \"fwd\",\n) => {\n if (direction === \"bwd\") {\n if (elementIsFilterCombinator(currentElement)) {\n const nextClause = currentElement.previousElementSibling;\n if (elementIsFilterClause(nextClause)) {\n const nextField = nextClause.querySelector(\n \".vuuFilterClauseValue\",\n ) as HTMLElement;\n console.log(`focus field Value ${nextField?.classList}`);\n focusField(nextField);\n }\n } else {\n const filterClause = getFilterClauseElement(currentElement);\n const nextClause = filterClause.previousSibling as HTMLElement;\n const nextField = nextClause.querySelector(\n \".vuuFilterClauseValue\",\n ) as HTMLElement;\n focusField(nextField);\n }\n } else {\n const nextClause = currentElement.nextSibling as HTMLElement;\n focusField(nextClause);\n }\n};\n\n// The logic around preventDefault/stopPropagation is important\n// in this function\nexport const navigateToNextItemIfAtBoundary = (\n evt: KeyboardEvent<HTMLInputElement>,\n) => {\n const input = evt.target as HTMLInputElement;\n const field = getFilterClauseFieldElement(input);\n if (evt.key === \"ArrowLeft\") {\n if (cursorAtTextStart(input)) {\n const fieldName = getFieldName(field);\n if (fieldName === \"column\") {\n if (clauseIsNotFirst(input)) {\n const filterClause = getFilterClauseElement(field);\n const combinator = filterClause.previousElementSibling as HTMLElement;\n combinator?.focus();\n }\n } else {\n evt.preventDefault();\n focusField(field.previousSibling as HTMLElement);\n }\n }\n // stopPropagation, even if cursor is not at start. We want the arrowLeft to move the cursor\n evt.stopPropagation();\n } else if (evt.key === \"ArrowRight\") {\n if (cursorAtTextEnd(input as HTMLInputElement)) {\n const fieldName = getFieldName(field);\n if (fieldName === \"value\") {\n if (clauseIsNotLast(input)) {\n const filterClause = getFilterClauseElement(field);\n const combinator = filterClause.nextElementSibling as HTMLElement;\n combinator?.focus();\n }\n // Do not preventDefault, stopPropagation\n return;\n } else {\n evt.preventDefault();\n focusField(field.nextSibling as HTMLElement);\n }\n }\n // stopPropagation, even if cursor is not at end. We want the arrowRight to move the cursor\n evt.stopPropagation();\n }\n};\n\nexport const focusFirstClauseIfAllClausesValid = (\n filterEditor: HTMLElement,\n) => {\n const columInput = Array.from(\n filterEditor.querySelectorAll(\".vuuFilterClauseColumn input\"),\n ) as HTMLInputElement[];\n if (columInput.every((input) => input.value.length > 0)) {\n setTimeout(() => {\n const input = columInput.at(0);\n input?.select();\n input?.focus();\n }, 100);\n }\n};\n"],"names":["queryClosest","getElementDataIndex"],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ var FilterClauseValueEditorText = require('./FilterClauseValueEditorText.js');
|
|
|
7
7
|
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
8
8
|
var react = require('react');
|
|
9
9
|
var FilterClauseValueEditorDate = require('./FilterClauseValueEditorDate.js');
|
|
10
|
+
var FilterClauseValueEditorTime = require('./FilterClauseValueEditorTime.js');
|
|
10
11
|
|
|
11
12
|
const classBase = "vuuFilterClause";
|
|
12
13
|
const FilterClauseValueEditor = react.forwardRef(
|
|
@@ -34,6 +35,17 @@ const FilterClauseValueEditor = react.forwardRef(
|
|
|
34
35
|
onChangeValue
|
|
35
36
|
}
|
|
36
37
|
);
|
|
38
|
+
} else if (vuuUtils.isTimeDataValue(selectedColumn)) {
|
|
39
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
40
|
+
FilterClauseValueEditorTime.FilterClauseValueEditorTime,
|
|
41
|
+
{
|
|
42
|
+
inputProps,
|
|
43
|
+
className: cx(`${classBase}Field`, `${classBase}Value`),
|
|
44
|
+
value,
|
|
45
|
+
operator,
|
|
46
|
+
onChangeValue
|
|
47
|
+
}
|
|
48
|
+
);
|
|
37
49
|
}
|
|
38
50
|
switch (selectedColumn.serverDataType) {
|
|
39
51
|
case "string":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterClauseValueEditor.js","sources":["../../../../../packages/vuu-filters/src/filter-clause/value-editors/FilterClauseValueEditor.tsx"],"sourcesContent":["import { TableSchemaTable } from \"@vuu-ui/vuu-data-types\";\nimport cx from \"clsx\";\nimport { useFilterClause } from \"../useFilterClause\";\nimport { FilterClauseValueEditorNumber } from \"./FilterClauseValueEditorNumber\";\nimport { FilterClauseValueEditorText } from \"./FilterClauseValueEditorText\";\n\nimport {\n NumericFilterClauseOp,\n SingleValueFilterClauseOp,\n} from \"@vuu-ui/vuu-filter-types\";\nimport { isDateTimeDataValue } from \"@vuu-ui/vuu-utils\";\nimport { ForwardedRef, forwardRef } from \"react\";\nimport { FilterClauseValueEditorDate } from \"./FilterClauseValueEditorDate\";\n\nconst classBase = \"vuuFilterClause\";\n\ntype FilterClauseValueEditorProps = Pick<\n ReturnType<typeof useFilterClause>,\n | \"selectedColumn\"\n | \"inputProps\"\n | \"onChangeValue\"\n | \"onDeselectValue\"\n | \"onOpenChange\"\n> & {\n table?: TableSchemaTable;\n} & {\n operator?: SingleValueFilterClauseOp | \"in\";\n value?: string | string[] | number | number[] | boolean | boolean[];\n};\n\nexport const FilterClauseValueEditor = forwardRef(\n function FilterClauseValueEditor(\n {\n selectedColumn,\n operator,\n inputProps,\n onChangeValue,\n onDeselectValue,\n onOpenChange,\n table,\n value,\n }: FilterClauseValueEditorProps,\n forwardedRef: ForwardedRef<HTMLDivElement>,\n ) {\n if (selectedColumn === undefined || operator === undefined) {\n return null;\n }\n\n if (isDateTimeDataValue(selectedColumn)) {\n return (\n <FilterClauseValueEditorDate\n inputProps={inputProps}\n className={cx(`${classBase}Field`, `${classBase}Value`)}\n
|
|
1
|
+
{"version":3,"file":"FilterClauseValueEditor.js","sources":["../../../../../packages/vuu-filters/src/filter-clause/value-editors/FilterClauseValueEditor.tsx"],"sourcesContent":["import { TableSchemaTable } from \"@vuu-ui/vuu-data-types\";\nimport cx from \"clsx\";\nimport { useFilterClause } from \"../useFilterClause\";\nimport { FilterClauseValueEditorNumber } from \"./FilterClauseValueEditorNumber\";\nimport { FilterClauseValueEditorText } from \"./FilterClauseValueEditorText\";\n\nimport {\n NumericFilterClauseOp,\n SingleValueFilterClauseOp,\n} from \"@vuu-ui/vuu-filter-types\";\nimport { isDateTimeDataValue, isTimeDataValue } from \"@vuu-ui/vuu-utils\";\nimport { ForwardedRef, forwardRef } from \"react\";\nimport { FilterClauseValueEditorDate } from \"./FilterClauseValueEditorDate\";\nimport { FilterClauseValueEditorTime } from \"./FilterClauseValueEditorTime\";\n\nconst classBase = \"vuuFilterClause\";\n\ntype FilterClauseValueEditorProps = Pick<\n ReturnType<typeof useFilterClause>,\n | \"selectedColumn\"\n | \"inputProps\"\n | \"onChangeValue\"\n | \"onDeselectValue\"\n | \"onOpenChange\"\n> & {\n table?: TableSchemaTable;\n} & {\n operator?: SingleValueFilterClauseOp | \"in\";\n value?: string | string[] | number | number[] | boolean | boolean[];\n};\n\nexport const FilterClauseValueEditor = forwardRef(\n function FilterClauseValueEditor(\n {\n selectedColumn,\n operator,\n inputProps,\n onChangeValue,\n onDeselectValue,\n onOpenChange,\n table,\n value,\n }: FilterClauseValueEditorProps,\n forwardedRef: ForwardedRef<HTMLDivElement>,\n ) {\n if (selectedColumn === undefined || operator === undefined) {\n return null;\n }\n\n if (isDateTimeDataValue(selectedColumn)) {\n return (\n <FilterClauseValueEditorDate\n inputProps={inputProps}\n className={cx(`${classBase}Field`, `${classBase}Value`)}\n value={value as number}\n operator={operator as NumericFilterClauseOp}\n onChangeValue={onChangeValue}\n />\n );\n } else if (isTimeDataValue(selectedColumn)) {\n return (\n <FilterClauseValueEditorTime\n inputProps={inputProps}\n className={cx(`${classBase}Field`, `${classBase}Value`)}\n value={value as number}\n operator={operator as NumericFilterClauseOp}\n onChangeValue={onChangeValue}\n />\n );\n }\n\n switch (selectedColumn.serverDataType) {\n case \"string\":\n case \"char\":\n return (\n <FilterClauseValueEditorText\n inputProps={inputProps}\n className={cx(`${classBase}Field`, `${classBase}Value`)}\n column={selectedColumn}\n onDeselect={onDeselectValue}\n onChangeValue={onChangeValue}\n onOpenChange={onOpenChange}\n operator={operator}\n ref={forwardedRef}\n table={table}\n value={\n value === undefined\n ? \"\"\n : Array.isArray(value)\n ? value.map((val) => val.toString())\n : (value.toString() as string | string[])\n }\n />\n );\n case \"int\":\n case \"long\":\n case \"double\":\n return (\n <FilterClauseValueEditorNumber\n inputProps={inputProps}\n className={cx(`${classBase}Field`, `${classBase}Value`)}\n column={selectedColumn}\n data-field=\"value\"\n onChangeValue={onChangeValue}\n operator={operator}\n ref={forwardedRef}\n />\n );\n default:\n console.log(\"returning null\");\n return null;\n }\n },\n);\n"],"names":["forwardRef","FilterClauseValueEditor","isDateTimeDataValue","jsx","FilterClauseValueEditorDate","isTimeDataValue","FilterClauseValueEditorTime","FilterClauseValueEditorText","FilterClauseValueEditorNumber"],"mappings":";;;;;;;;;;;AAeA,MAAM,SAAY,GAAA,iBAAA;AAgBX,MAAM,uBAA0B,GAAAA,gBAAA;AAAA,EACrC,SAASC,wBACP,CAAA;AAAA,IACE,cAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA,eAAA;AAAA,IACA,YAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,KAEF,YACA,EAAA;AACA,IAAI,IAAA,cAAA,KAAmB,KAAa,CAAA,IAAA,QAAA,KAAa,KAAW,CAAA,EAAA;AAC1D,MAAO,OAAA,IAAA;AAAA;AAGT,IAAI,IAAAC,4BAAA,CAAoB,cAAc,CAAG,EAAA;AACvC,MACE,uBAAAC,cAAA;AAAA,QAACC,uDAAA;AAAA,QAAA;AAAA,UACC,UAAA;AAAA,UACA,WAAW,EAAG,CAAA,CAAA,EAAG,SAAS,CAAS,KAAA,CAAA,EAAA,CAAA,EAAG,SAAS,CAAO,KAAA,CAAA,CAAA;AAAA,UACtD,KAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA;AAAA,OACF;AAAA,KAEJ,MAAA,IAAWC,wBAAgB,CAAA,cAAc,CAAG,EAAA;AAC1C,MACE,uBAAAF,cAAA;AAAA,QAACG,uDAAA;AAAA,QAAA;AAAA,UACC,UAAA;AAAA,UACA,WAAW,EAAG,CAAA,CAAA,EAAG,SAAS,CAAS,KAAA,CAAA,EAAA,CAAA,EAAG,SAAS,CAAO,KAAA,CAAA,CAAA;AAAA,UACtD,KAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA;AAAA,OACF;AAAA;AAIJ,IAAA,QAAQ,eAAe,cAAgB;AAAA,MACrC,KAAK,QAAA;AAAA,MACL,KAAK,MAAA;AACH,QACE,uBAAAH,cAAA;AAAA,UAACI,uDAAA;AAAA,UAAA;AAAA,YACC,UAAA;AAAA,YACA,WAAW,EAAG,CAAA,CAAA,EAAG,SAAS,CAAS,KAAA,CAAA,EAAA,CAAA,EAAG,SAAS,CAAO,KAAA,CAAA,CAAA;AAAA,YACtD,MAAQ,EAAA,cAAA;AAAA,YACR,UAAY,EAAA,eAAA;AAAA,YACZ,aAAA;AAAA,YACA,YAAA;AAAA,YACA,QAAA;AAAA,YACA,GAAK,EAAA,YAAA;AAAA,YACL,KAAA;AAAA,YACA,OACE,KAAU,KAAA,KAAA,CAAA,GACN,EACA,GAAA,KAAA,CAAM,QAAQ,KAAK,CAAA,GACjB,KAAM,CAAA,GAAA,CAAI,CAAC,GAAQ,KAAA,GAAA,CAAI,UAAU,CAAA,GAChC,MAAM,QAAS;AAAA;AAAA,SAE1B;AAAA,MAEJ,KAAK,KAAA;AAAA,MACL,KAAK,MAAA;AAAA,MACL,KAAK,QAAA;AACH,QACE,uBAAAJ,cAAA;AAAA,UAACK,2DAAA;AAAA,UAAA;AAAA,YACC,UAAA;AAAA,YACA,WAAW,EAAG,CAAA,CAAA,EAAG,SAAS,CAAS,KAAA,CAAA,EAAA,CAAA,EAAG,SAAS,CAAO,KAAA,CAAA,CAAA;AAAA,YACtD,MAAQ,EAAA,cAAA;AAAA,YACR,YAAW,EAAA,OAAA;AAAA,YACX,aAAA;AAAA,YACA,QAAA;AAAA,YACA,GAAK,EAAA;AAAA;AAAA,SACP;AAAA,MAEJ;AACE,QAAA,OAAA,CAAQ,IAAI,gBAAgB,CAAA;AAC5B,QAAO,OAAA,IAAA;AAAA;AACX;AAEJ;;;;"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var react = require('react');
|
|
5
|
+
var date = require('@internationalized/date');
|
|
6
|
+
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
7
|
+
var vuuUiControls = require('@vuu-ui/vuu-ui-controls');
|
|
8
|
+
|
|
9
|
+
const FilterClauseValueEditorTime = (props) => {
|
|
10
|
+
const { className, onChangeValue, operator, value } = props;
|
|
11
|
+
const toEpochMilliS = getEpochMillisConverter(operator);
|
|
12
|
+
const [date, setDate] = react.useState(
|
|
13
|
+
() => getInitialState(value)
|
|
14
|
+
);
|
|
15
|
+
const handleCommit = react.useCallback(
|
|
16
|
+
(e, selectedDateInputValue) => {
|
|
17
|
+
console.log("change time");
|
|
18
|
+
if (selectedDateInputValue) {
|
|
19
|
+
const dateValue = vuuUtils.toCalendarDate(new Date(selectedDateInputValue));
|
|
20
|
+
setDate(dateValue);
|
|
21
|
+
if (selectedDateInputValue) {
|
|
22
|
+
onChangeValue(toEpochMilliS(dateValue));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
[onChangeValue, toEpochMilliS]
|
|
27
|
+
);
|
|
28
|
+
const onBlur = react.useCallback(() => {
|
|
29
|
+
date && onChangeValue(toEpochMilliS(date));
|
|
30
|
+
}, [date, onChangeValue, toEpochMilliS]);
|
|
31
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
32
|
+
vuuUiControls.VuuTimePicker,
|
|
33
|
+
{
|
|
34
|
+
"data-field": "value",
|
|
35
|
+
className,
|
|
36
|
+
onBlur,
|
|
37
|
+
onCommit: handleCommit
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
function getInitialState(value) {
|
|
42
|
+
return value ? vuuUtils.toCalendarDate(new Date(value)) : void 0;
|
|
43
|
+
}
|
|
44
|
+
const getEpochMillisConverter = (op) => (date$1, timezone = date.getLocalTimeZone()) => {
|
|
45
|
+
const d = date$1.toDate(timezone);
|
|
46
|
+
switch (op) {
|
|
47
|
+
case ">":
|
|
48
|
+
case "<=":
|
|
49
|
+
d.setHours(23, 59, 59, 999);
|
|
50
|
+
return d.getTime();
|
|
51
|
+
case ">=":
|
|
52
|
+
case "<":
|
|
53
|
+
case "=":
|
|
54
|
+
// converted to "< `start of next day` and >= `start of this day`" when query is created
|
|
55
|
+
case "!=":
|
|
56
|
+
d.setHours(0, 0, 0, 0);
|
|
57
|
+
return d.getTime();
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
exports.FilterClauseValueEditorTime = FilterClauseValueEditorTime;
|
|
62
|
+
//# sourceMappingURL=FilterClauseValueEditorTime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterClauseValueEditorTime.js","sources":["../../../../../packages/vuu-filters/src/filter-clause/value-editors/FilterClauseValueEditorTime.tsx"],"sourcesContent":["import { useCallback, useState } from \"react\";\nimport { getLocalTimeZone, DateValue } from \"@internationalized/date\";\nimport { CommitHandler, toCalendarDate } from \"@vuu-ui/vuu-utils\";\nimport { NumericFilterClauseOp } from \"@vuu-ui/vuu-filter-types\";\nimport { FilterClauseValueEditor } from \"../filterClauseTypes\";\nimport { VuuTimePicker } from \"@vuu-ui/vuu-ui-controls\";\n\ninterface FilterClauseValueEditorTimeProps\n extends Pick<FilterClauseValueEditor, \"onChangeValue\" | \"inputProps\"> {\n className?: string;\n value: number | undefined;\n operator: NumericFilterClauseOp;\n}\n\nexport const FilterClauseValueEditorTime = (\n props: FilterClauseValueEditorTimeProps,\n) => {\n const { className, onChangeValue, operator, value } = props;\n const toEpochMilliS = getEpochMillisConverter(operator);\n\n const [date, setDate] = useState<DateValue | undefined>(() =>\n getInitialState(value),\n );\n\n const handleCommit = useCallback<CommitHandler<HTMLElement, number>>(\n (e, selectedDateInputValue) => {\n console.log(\"change time\");\n if (selectedDateInputValue) {\n const dateValue = toCalendarDate(new Date(selectedDateInputValue));\n setDate(dateValue);\n if (selectedDateInputValue /* && source === \"calendar\"*/) {\n onChangeValue(toEpochMilliS(dateValue));\n }\n }\n },\n [onChangeValue, toEpochMilliS],\n );\n\n const onBlur = useCallback(() => {\n date && onChangeValue(toEpochMilliS(date));\n }, [date, onChangeValue, toEpochMilliS]);\n\n return (\n <VuuTimePicker\n data-field=\"value\"\n // inputProps={inputProps}\n className={className}\n onBlur={onBlur}\n onCommit={handleCommit}\n // selectedDate={date}\n />\n );\n};\n\nfunction getInitialState(value: FilterClauseValueEditorTimeProps[\"value\"]) {\n return value ? toCalendarDate(new Date(value)) : undefined;\n}\n\nconst getEpochMillisConverter =\n (op: NumericFilterClauseOp) =>\n (date: DateValue, timezone: string = getLocalTimeZone()): number => {\n const d = date.toDate(timezone);\n switch (op) {\n case \">\":\n case \"<=\":\n d.setHours(23, 59, 59, 999);\n return d.getTime();\n case \">=\":\n case \"<\":\n case \"=\": // converted to \"< `start of next day` and >= `start of this day`\" when query is created\n case \"!=\": // converted to \">= `start of next day` or < `start of this day`\" when query is created\n d.setHours(0, 0, 0, 0);\n return d.getTime();\n }\n };\n"],"names":["useState","useCallback","toCalendarDate","jsx","VuuTimePicker","date","getLocalTimeZone"],"mappings":";;;;;;;;AAca,MAAA,2BAAA,GAA8B,CACzC,KACG,KAAA;AACH,EAAA,MAAM,EAAE,SAAA,EAAW,aAAe,EAAA,QAAA,EAAU,OAAU,GAAA,KAAA;AACtD,EAAM,MAAA,aAAA,GAAgB,wBAAwB,QAAQ,CAAA;AAEtD,EAAM,MAAA,CAAC,IAAM,EAAA,OAAO,CAAI,GAAAA,cAAA;AAAA,IAAgC,MACtD,gBAAgB,KAAK;AAAA,GACvB;AAEA,EAAA,MAAM,YAAe,GAAAC,iBAAA;AAAA,IACnB,CAAC,GAAG,sBAA2B,KAAA;AAC7B,MAAA,OAAA,CAAQ,IAAI,aAAa,CAAA;AACzB,MAAA,IAAI,sBAAwB,EAAA;AAC1B,QAAA,MAAM,SAAY,GAAAC,uBAAA,CAAe,IAAI,IAAA,CAAK,sBAAsB,CAAC,CAAA;AACjE,QAAA,OAAA,CAAQ,SAAS,CAAA;AACjB,QAAA,IAAI,sBAAsD,EAAA;AACxD,UAAc,aAAA,CAAA,aAAA,CAAc,SAAS,CAAC,CAAA;AAAA;AACxC;AACF,KACF;AAAA,IACA,CAAC,eAAe,aAAa;AAAA,GAC/B;AAEA,EAAM,MAAA,MAAA,GAASD,kBAAY,MAAM;AAC/B,IAAQ,IAAA,IAAA,aAAA,CAAc,aAAc,CAAA,IAAI,CAAC,CAAA;AAAA,GACxC,EAAA,CAAC,IAAM,EAAA,aAAA,EAAe,aAAa,CAAC,CAAA;AAEvC,EACE,uBAAAE,cAAA;AAAA,IAACC,2BAAA;AAAA,IAAA;AAAA,MACC,YAAW,EAAA,OAAA;AAAA,MAEX,SAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAU,EAAA;AAAA;AAAA,GAEZ;AAEJ;AAEA,SAAS,gBAAgB,KAAkD,EAAA;AACzE,EAAA,OAAO,QAAQF,uBAAe,CAAA,IAAI,IAAK,CAAA,KAAK,CAAC,CAAI,GAAA,KAAA,CAAA;AACnD;AAEA,MAAM,0BACJ,CAAC,EAAA,KACD,CAACG,MAAiB,EAAA,QAAA,GAAmBC,uBAA+B,KAAA;AAClE,EAAM,MAAA,CAAA,GAAID,MAAK,CAAA,MAAA,CAAO,QAAQ,CAAA;AAC9B,EAAA,QAAQ,EAAI;AAAA,IACV,KAAK,GAAA;AAAA,IACL,KAAK,IAAA;AACH,MAAA,CAAA,CAAE,QAAS,CAAA,EAAA,EAAI,EAAI,EAAA,EAAA,EAAI,GAAG,CAAA;AAC1B,MAAA,OAAO,EAAE,OAAQ,EAAA;AAAA,IACnB,KAAK,IAAA;AAAA,IACL,KAAK,GAAA;AAAA,IACL,KAAK,GAAA;AAAA;AAAA,IACL,KAAK,IAAA;AACH,MAAA,CAAA,CAAE,QAAS,CAAA,CAAA,EAAG,CAAG,EAAA,CAAA,EAAG,CAAC,CAAA;AACrB,MAAA,OAAO,EAAE,OAAQ,EAAA;AAAA;AAEvB,CAAA;;;;"}
|
package/cjs/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var FilterModel = require('./FilterModel.js');
|
|
4
|
+
var ColumnFilter = require('./column-filter/ColumnFilter.js');
|
|
4
5
|
var FilterBar = require('./filter-bar/FilterBar.js');
|
|
5
6
|
var ColumnPicker = require('./filter-clause/ColumnPicker.js');
|
|
6
7
|
var ExpandoCombobox = require('./filter-clause/ExpandoCombobox.js');
|
|
@@ -16,6 +17,7 @@ var QuickFilters = require('./quick-filters/QuickFilters.js');
|
|
|
16
17
|
|
|
17
18
|
exports.FilterClauseModel = FilterModel.FilterClauseModel;
|
|
18
19
|
exports.FilterModel = FilterModel.FilterModel;
|
|
20
|
+
exports.ColumnFilter = ColumnFilter.ColumnFilter;
|
|
19
21
|
exports.FilterBar = FilterBar.FilterBar;
|
|
20
22
|
exports.ColumnPicker = ColumnPicker.ColumnPicker;
|
|
21
23
|
exports.ExpandoCombobox = ExpandoCombobox.ExpandoCombobox;
|
package/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var columnFilterCss = ".vuuColumnFilter {\n border: solid 1px var(--salt-editable-borderColor);\n border-radius: 4px;\n max-width: 200px;\n}\n\n.vuuColumnFilter-trigger {\n --saltButton-borderRadius: 4px 0px 0px 4px;\n --saltButton-padding: var(--salt-spacing-200);\n}\n";
|
|
2
|
+
|
|
3
|
+
export { columnFilterCss as default };
|
|
4
|
+
//# sourceMappingURL=ColumnFilter.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ColumnFilter.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { SegmentedButtonGroup, Menu, MenuTrigger, Button, MenuPanel, MenuItem } from '@salt-ds/core';
|
|
3
|
+
import { useComponentCssInjection } from '@salt-ds/styles';
|
|
4
|
+
import { useWindow } from '@salt-ds/window';
|
|
5
|
+
import cx from 'clsx';
|
|
6
|
+
import columnFilterCss from './ColumnFilter.css.js';
|
|
7
|
+
import { getDataItemEditControl } from '@vuu-ui/vuu-data-react';
|
|
8
|
+
import { useMemo, useCallback } from 'react';
|
|
9
|
+
import { assertValidValue } from './useColumnFilter.js';
|
|
10
|
+
|
|
11
|
+
const classBase = "vuuColumnFilter";
|
|
12
|
+
const ColumnFilter = ({
|
|
13
|
+
column,
|
|
14
|
+
className,
|
|
15
|
+
operator = "=",
|
|
16
|
+
showOperatorPicker = false,
|
|
17
|
+
table,
|
|
18
|
+
value,
|
|
19
|
+
...buttonGroupProps
|
|
20
|
+
}) => {
|
|
21
|
+
const targetWindow = useWindow();
|
|
22
|
+
useComponentCssInjection({
|
|
23
|
+
testId: "vuu-filter-bar",
|
|
24
|
+
css: columnFilterCss,
|
|
25
|
+
window: targetWindow
|
|
26
|
+
});
|
|
27
|
+
useMemo(
|
|
28
|
+
() => assertValidValue(column, operator, value),
|
|
29
|
+
[column, operator, value]
|
|
30
|
+
);
|
|
31
|
+
const onCommit = useCallback((e, value2) => {
|
|
32
|
+
console.log(`onCommit ${value2}`);
|
|
33
|
+
}, []);
|
|
34
|
+
return /* @__PURE__ */ jsxs(
|
|
35
|
+
SegmentedButtonGroup,
|
|
36
|
+
{
|
|
37
|
+
...buttonGroupProps,
|
|
38
|
+
className: cx(classBase, className),
|
|
39
|
+
children: [
|
|
40
|
+
showOperatorPicker ? /* @__PURE__ */ jsxs(Menu, { placement: "bottom-start", children: [
|
|
41
|
+
/* @__PURE__ */ jsx(MenuTrigger, { children: /* @__PURE__ */ jsx(
|
|
42
|
+
Button,
|
|
43
|
+
{
|
|
44
|
+
appearance: "solid",
|
|
45
|
+
"aria-label": "Open Menu",
|
|
46
|
+
className: `${classBase}-trigger`,
|
|
47
|
+
"data-embedded": true,
|
|
48
|
+
sentiment: "neutral",
|
|
49
|
+
children: operator
|
|
50
|
+
}
|
|
51
|
+
) }),
|
|
52
|
+
/* @__PURE__ */ jsxs(MenuPanel, { children: [
|
|
53
|
+
/* @__PURE__ */ jsx(MenuItem, { children: "=" }),
|
|
54
|
+
/* @__PURE__ */ jsx(MenuItem, { children: "!=" }),
|
|
55
|
+
/* @__PURE__ */ jsx(MenuItem, { children: "starts" }),
|
|
56
|
+
/* @__PURE__ */ jsx(MenuItem, { children: "ends" }),
|
|
57
|
+
/* @__PURE__ */ jsx(MenuItem, { children: "contains" })
|
|
58
|
+
] })
|
|
59
|
+
] }) : null,
|
|
60
|
+
getDataItemEditControl({
|
|
61
|
+
dataDescriptor: column,
|
|
62
|
+
onCommit,
|
|
63
|
+
table
|
|
64
|
+
}),
|
|
65
|
+
operator === "between" ? getDataItemEditControl({
|
|
66
|
+
dataDescriptor: column,
|
|
67
|
+
onCommit,
|
|
68
|
+
table
|
|
69
|
+
}) : null
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export { ColumnFilter };
|
|
76
|
+
//# sourceMappingURL=ColumnFilter.js.map
|
|
@@ -0,0 +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 { useCallback, useMemo } from \"react\";\nimport { CommitHandler } from \"@vuu-ui/vuu-utils\";\nimport { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\nimport {\n assertValidValue,\n ColumnFilterHookProps,\n FilterValue,\n} from \"./useColumnFilter\";\n\nconst classBase = \"vuuColumnFilter\";\n\nexport interface ColumnFilterProps\n extends ColumnFilterHookProps,\n SegmentedButtonGroupProps {\n showOperatorPicker?: boolean;\n /**\n * VuuTable is required if typeahead support is expected.\n */\n table?: VuuTable;\n\n /**\n * Initial filter value. Pair of values expewcted when operator is\n * 'between'\n */\n value?: FilterValue | [FilterValue, FilterValue];\n}\n\nexport const ColumnFilter = ({\n column,\n className,\n operator = \"=\",\n showOperatorPicker = false,\n table,\n value,\n ...buttonGroupProps\n}: ColumnFilterProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-filter-bar\",\n css: columnFilterCss,\n window: targetWindow,\n });\n\n useMemo(\n () => assertValidValue(column, operator, value),\n [column, operator, value],\n );\n\n const onCommit = useCallback<CommitHandler<HTMLElement>>((e, value) => {\n console.log(`onCommit ${value}`);\n }, []);\n\n return (\n <SegmentedButtonGroup\n {...buttonGroupProps}\n className={cx(classBase, className)}\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 {operator}\n </Button>\n </MenuTrigger>\n <MenuPanel>\n <MenuItem>=</MenuItem>\n <MenuItem>!=</MenuItem>\n <MenuItem>starts</MenuItem>\n <MenuItem>ends</MenuItem>\n <MenuItem>contains</MenuItem>\n </MenuPanel>\n </Menu>\n ) : null}\n {getDataItemEditControl({\n dataDescriptor: column,\n onCommit,\n table,\n })}\n {operator === \"between\"\n ? getDataItemEditControl({\n dataDescriptor: column,\n onCommit,\n table,\n })\n : null}\n </SegmentedButtonGroup>\n );\n};\n"],"names":["value"],"mappings":";;;;;;;;;;AAwBA,MAAM,SAAY,GAAA,iBAAA;AAkBX,MAAM,eAAe,CAAC;AAAA,EAC3B,MAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAW,GAAA,GAAA;AAAA,EACX,kBAAqB,GAAA,KAAA;AAAA,EACrB,KAAA;AAAA,EACA,KAAA;AAAA,EACA,GAAG;AACL,CAAyB,KAAA;AACvB,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,gBAAA;AAAA,IACR,GAAK,EAAA,eAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAA,OAAA;AAAA,IACE,MAAM,gBAAA,CAAiB,MAAQ,EAAA,QAAA,EAAU,KAAK,CAAA;AAAA,IAC9C,CAAC,MAAQ,EAAA,QAAA,EAAU,KAAK;AAAA,GAC1B;AAEA,EAAA,MAAM,QAAW,GAAA,WAAA,CAAwC,CAAC,CAAA,EAAGA,MAAU,KAAA;AACrE,IAAQ,OAAA,CAAA,GAAA,CAAI,CAAYA,SAAAA,EAAAA,MAAK,CAAE,CAAA,CAAA;AAAA,GACjC,EAAG,EAAE,CAAA;AAEL,EACE,uBAAA,IAAA;AAAA,IAAC,oBAAA;AAAA,IAAA;AAAA,MACE,GAAG,gBAAA;AAAA,MACJ,SAAA,EAAW,EAAG,CAAA,SAAA,EAAW,SAAS,CAAA;AAAA,MAEjC,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,+BACC,SACC,EAAA,EAAA,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,YAAS,QAAC,EAAA,GAAA,EAAA,CAAA;AAAA,4BACX,GAAA,CAAC,YAAS,QAAE,EAAA,IAAA,EAAA,CAAA;AAAA,4BACZ,GAAA,CAAC,YAAS,QAAM,EAAA,QAAA,EAAA,CAAA;AAAA,4BAChB,GAAA,CAAC,YAAS,QAAI,EAAA,MAAA,EAAA,CAAA;AAAA,4BACd,GAAA,CAAC,YAAS,QAAQ,EAAA,UAAA,EAAA;AAAA,WACpB,EAAA;AAAA,SAAA,EACF,CACE,GAAA,IAAA;AAAA,QACH,sBAAuB,CAAA;AAAA,UACtB,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAA;AAAA,UACA;AAAA,SACD,CAAA;AAAA,QACA,QAAA,KAAa,YACV,sBAAuB,CAAA;AAAA,UACrB,cAAgB,EAAA,MAAA;AAAA,UAChB,QAAA;AAAA,UACA;AAAA,SACD,CACD,GAAA;AAAA;AAAA;AAAA,GACN;AAEJ;;;;"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const assertValidValue = ({ serverDataType: _ }, operator, value) => {
|
|
2
|
+
if (value !== void 0) {
|
|
3
|
+
if (operator === "between") {
|
|
4
|
+
if (!Array.isArray(value)) {
|
|
5
|
+
throw Error(
|
|
6
|
+
"[useColumnFilter] 'between operator requires array of two values'"
|
|
7
|
+
);
|
|
8
|
+
} else if (value.length !== 2) {
|
|
9
|
+
throw Error(
|
|
10
|
+
`[useColumnFilter] 'between operator requires two values, received ${value.length}'`
|
|
11
|
+
);
|
|
12
|
+
} else if (typeof value[0] !== typeof value[1]) {
|
|
13
|
+
throw Error(
|
|
14
|
+
`[useColumnFilter] 'between operator values must be of same type, received ${typeof value[0]} and ${typeof value[1]}`
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export { assertValidValue };
|
|
22
|
+
//# sourceMappingURL=useColumnFilter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useColumnFilter.js","sources":["../../../../packages/vuu-filters/src/column-filter/useColumnFilter.ts"],"sourcesContent":["import { FilterOp } from \"@vuu-ui/vuu-filter-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\n\nexport type FilterValue = string | number;\n\nexport const assertValidValue = (\n { serverDataType: _ }: ColumnDescriptor,\n operator: FilterOp | \"between\",\n value?: FilterValue | FilterValue[],\n) => {\n if (value !== undefined) {\n if (operator === \"between\") {\n if (!Array.isArray(value)) {\n throw Error(\n \"[useColumnFilter] 'between operator requires array of two values'\",\n );\n } else if (value.length !== 2) {\n throw Error(\n `[useColumnFilter] 'between operator requires two values, received ${value.length}'`,\n );\n } else if (typeof value[0] !== typeof value[1]) {\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 interface ColumnFilterHookProps {\n column: ColumnDescriptor;\n operator?: FilterOp | \"between\";\n}\n\n// export const useColumnFilter = ({\n// column,\n// operator = \"=\",\n// }: ColumnFilterHookProps) => {};\n"],"names":[],"mappings":"AAKO,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,KAAA,CAAM,OAAQ,CAAA,KAAK,CAAG,EAAA;AACzB,QAAM,MAAA,KAAA;AAAA,UACJ;AAAA,SACF;AAAA,OACF,MAAA,IAAW,KAAM,CAAA,MAAA,KAAW,CAAG,EAAA;AAC7B,QAAM,MAAA,KAAA;AAAA,UACJ,CAAA,kEAAA,EAAqE,MAAM,MAAM,CAAA,CAAA;AAAA,SACnF;AAAA,OACF,MAAA,IAAW,OAAO,KAAM,CAAA,CAAC,MAAM,OAAO,KAAA,CAAM,CAAC,CAAG,EAAA;AAC9C,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;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterBar.js","sources":["../../../../packages/vuu-filters/src/filter-bar/FilterBar.tsx"],"sourcesContent":["import { DataSourceFilter } from \"@vuu-ui/vuu-data-types\";\nimport { Filter, FilterState } from \"@vuu-ui/vuu-filter-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { Icon } from \"@vuu-ui/vuu-ui-controls\";\nimport { ToggleButton, ToggleButtonGroup } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport { HTMLAttributes, useMemo } from \"react\";\nimport { CustomFilters } from \"../custom-filters\";\nimport { QuickFilterProps, QuickFilters } from \"../quick-filters\";\nimport { FilterMode, useFilterBar } from \"./useFilterBar\";\
|
|
1
|
+
{"version":3,"file":"FilterBar.js","sources":["../../../../packages/vuu-filters/src/filter-bar/FilterBar.tsx"],"sourcesContent":["import { DataSourceFilter } from \"@vuu-ui/vuu-data-types\";\nimport { Filter, FilterState } from \"@vuu-ui/vuu-filter-types\";\nimport { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport { Icon } from \"@vuu-ui/vuu-ui-controls\";\nimport { ToggleButton, ToggleButtonGroup } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport cx from \"clsx\";\nimport { HTMLAttributes, useMemo } from \"react\";\nimport { CustomFilters } from \"../custom-filters\";\nimport { QuickFilterProps, QuickFilters } from \"../quick-filters\";\nimport { FilterMode, useFilterBar } from \"./useFilterBar\";\nimport type { VuuTable } from \"@vuu-ui/vuu-protocol-types\";\n\nimport filterBarCss from \"./FilterBar.css\";\n\nexport type FilterBarVariant =\n | \"custom-filters-only\"\n | \"quick-filters-only\"\n | \"full-filters\";\n\nexport interface FilterBarProps extends HTMLAttributes<HTMLDivElement> {\n QuickFilterProps?: Pick<\n QuickFilterProps,\n \"quickFilterColumns\" | \"onChangeQuickFilterColumns\"\n >;\n /**\n * Used to ensure we present filter editors appropriate to the data type of column.\n * NOTE: Always make sure that these are passed with proper re-render optimization (i.e make\n * sure its a stable reference, in React terminology), otherwise might end up with infinite\n * state updates.\n */\n columnDescriptors: ColumnDescriptor[];\n defaultFilterMode?: FilterMode;\n defaultFilterState?: FilterState;\n filterMode?: FilterMode;\n filterState?: FilterState;\n onApplyFilter: (filter: DataSourceFilter) => void;\n onChangeFilterMode?: (filterMode: FilterMode) => void;\n onFilterDeleted?: (filter: Filter) => void;\n onFilterRenamed?: (filter: Filter, name: string) => void;\n onFilterStateChanged?: (state: FilterState) => void;\n /**\n * Defines table used in call to Vuu Typeahead service\n */\n vuuTable?: VuuTable;\n variant?: FilterBarVariant;\n}\n\nconst classBase = \"vuuFilterBar\";\n\nexport const FilterBar = ({\n QuickFilterProps,\n className: classNameProp,\n columnDescriptors,\n defaultFilterMode,\n defaultFilterState,\n filterMode: filterModeProp,\n filterState,\n onApplyFilter,\n onChangeFilterMode: onChangeFilterModeProp,\n onFilterDeleted,\n onFilterRenamed,\n onFilterStateChanged,\n vuuTable,\n variant = \"custom-filters-only\",\n ...htmlAttributes\n}: FilterBarProps) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"vuu-filter-bar\",\n css: filterBarCss,\n window: targetWindow,\n });\n\n const allowCustomFilters = variant !== \"quick-filters-only\";\n const allowQuickFilters = variant !== \"custom-filters-only\";\n\n const controlledFilterMode: FilterMode | undefined = !allowCustomFilters\n ? \"quick-filter\"\n : !allowQuickFilters\n ? \"custom-filter\"\n : filterModeProp;\n\n const { filterMode, onChangeFilterMode } = useFilterBar({\n defaultFilterMode,\n filterMode: controlledFilterMode,\n onChangeFilterMode: onChangeFilterModeProp,\n });\n\n const className = cx(classBase, classNameProp);\n\n const startAdornment = useMemo(() => {\n if (!allowQuickFilters) {\n return <Icon name=\"filter\" size={16} style={{ top: 4 }} />;\n } else {\n return (\n <ToggleButtonGroup\n data-variant=\"secondary\"\n onChange={onChangeFilterMode}\n value={filterMode}\n >\n <ToggleButton\n className=\"vuuIconToggleButton\"\n key=\"custom-filter\"\n value=\"custom-filter\"\n aria-label=\"Custom filters\"\n tabIndex={-1}\n >\n <Icon name=\"grid\" size={16} />\n </ToggleButton>\n <ToggleButton\n className=\"vuuIconToggleButton\"\n key=\"quick-filter\"\n value=\"quick-filter\"\n aria-label=\"Quick filters\"\n tabIndex={-1}\n >\n <Icon name=\"tune\" size={16} />\n </ToggleButton>\n </ToggleButtonGroup>\n );\n }\n }, [allowQuickFilters, filterMode, onChangeFilterMode]);\n\n return (\n <div\n {...htmlAttributes}\n className={cx(className, `${classBase}-${filterMode}-mode`)}\n >\n {variant === \"quick-filters-only\" ? null : (\n <div className={`${classBase}-iconContainer`}>{startAdornment}</div>\n )}\n {filterMode === \"custom-filter\" ? (\n <CustomFilters\n columnDescriptors={columnDescriptors}\n defaultFilterState={defaultFilterState}\n filterState={filterState}\n onApplyFilter={onApplyFilter}\n onFilterDeleted={onFilterDeleted}\n onFilterRenamed={onFilterRenamed}\n onFilterStateChanged={onFilterStateChanged}\n vuuTable={vuuTable}\n />\n ) : (\n <QuickFilters\n {...QuickFilterProps}\n availableColumns={columnDescriptors}\n onApplyFilter={onApplyFilter}\n vuuTable={vuuTable}\n />\n )}\n </div>\n );\n};\n"],"names":["QuickFilterProps"],"mappings":"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"}
|
|
@@ -29,7 +29,7 @@ const getFocusedFieldDetails = () => {
|
|
|
29
29
|
return [getElementDataIndex(filterClause), getFilterClauseDetails(field)];
|
|
30
30
|
}
|
|
31
31
|
} else if (field?.matches(".saltCalendar")) {
|
|
32
|
-
console.log("
|
|
32
|
+
console.log("its in a calendar");
|
|
33
33
|
}
|
|
34
34
|
return [];
|
|
35
35
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filterClauseFocusManagement.js","sources":["../../../../packages/vuu-filters/src/filter-clause/filterClauseFocusManagement.ts"],"sourcesContent":["import { getElementDataIndex, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { KeyboardEvent } from \"react\";\n\nconst getFilterClauseElement = (possiblyDescendant?: HTMLElement) =>\n possiblyDescendant?.closest(\".vuuFilterClause\") as HTMLElement;\n\nconst getFilterClauseFieldElement = (possiblyDescendant?: HTMLElement) =>\n possiblyDescendant?.closest(\".vuuFilterClauseField\") as HTMLElement;\n\ntype FilterClauseFieldName = \"column\" | \"operator\" | \"value\";\nconst mapFilterFieldToClassName: Record<FilterClauseFieldName, string> = {\n column: \"vuuFilterClauseColumn\",\n operator: \"vuuFilterClauseOperator\",\n value: \"vuuFilterClauseValue\",\n};\n\nconst getFilterClauseDetails = ({ classList }: HTMLElement) => {\n if (classList.contains(\"vuuFilterClauseColumn\")) {\n return \"column\";\n } else if (classList.contains(\"vuuFilterClauseOperator\")) {\n return \"operator\";\n } else if (classList.contains(\"vuuFilterClauseValue\")) {\n return \"value\";\n } else {\n throw Error(\n \"getFilterClauseField, filterClauseElemnent is missing required class name\",\n );\n }\n};\n\nexport const getFocusedFieldDetails = (): [number, string] | [] => {\n const el = document.activeElement as HTMLElement;\n const field = queryClosest(el, \".vuuFilterClauseField,.saltCalendar\");\n if (field?.matches(\".vuuFilterClauseField\")) {\n const filterClause = queryClosest(field, \".vuuFilterClause\");\n if (filterClause && field) {\n return [getElementDataIndex(filterClause), getFilterClauseDetails(field)];\n }\n } else if (field?.matches(\".saltCalendar\")) {\n console.log(\"muthafucker is ins a calendar\");\n }\n // const filterClause = queryClosest(field, \".vuuFilterClause\");\n // if (filterClause && field) {\n // return [getElementDataIndex(filterClause), getFilterClauseDetails(field)];\n // } else {\n return [];\n // }\n};\n\n// Focus the input control within field. If clause passed, will\n// focus first field within clause\nconst focusField = (fieldOrClause: HTMLElement | null) => {\n const input = fieldOrClause?.querySelector(\"input\");\n if (input) {\n input.focus();\n requestAnimationFrame(() => {\n input?.select();\n });\n }\n};\n\nexport const elementIsFilterCombinator = (\n element: Element | null,\n): element is HTMLElement =>\n element !== null && element.classList.contains(\"vuuFilterClauseCombinator\");\n\nexport const elementIsFilterClause = (\n element: Element | null,\n): element is HTMLElement =>\n element !== null && element.classList.contains(\"vuuFilterClause\");\n\nexport const focusFilterClauseField = (\n filterEditor: HTMLElement,\n filterClauseIndex: number,\n fieldName: FilterClauseFieldName = \"value\",\n) => {\n if (filterEditor) {\n const fieldClassName = mapFilterFieldToClassName[fieldName];\n const field = filterEditor.querySelector(\n `.vuuFilterClause[data-index=\"${filterClauseIndex}\"] .${fieldClassName}`,\n ) as HTMLElement;\n focusField(field);\n }\n};\n\nexport const focusLastClauseValue = (filterEditor: HTMLElement) => {\n console.log(\"focusLastClauseValue\");\n const field = Array.from(\n filterEditor?.querySelectorAll(\".vuuFilterClauseField\"),\n ).at(-1) as HTMLElement;\n focusField(field);\n};\n\nexport const focusNextFocusableElement = (direction: \"fwd\" | \"bwd\" = \"fwd\") => {\n const activeField = getFocusedField() as HTMLElement;\n const filterClause = getFilterClauseElement(activeField);\n if (direction === \"fwd\" && filterClause?.lastChild === activeField) {\n requestAnimationFrame(() => {\n focusNextFocusableElement();\n });\n } else {\n const nextField =\n direction === \"fwd\"\n ? (activeField?.nextElementSibling as HTMLElement)\n : (activeField?.previousElementSibling as HTMLElement);\n\n nextField?.querySelector(\"input\")?.focus();\n }\n};\n\nconst getFocusedField = () => {\n const activeElement = document.activeElement as HTMLElement;\n if (activeElement?.classList.contains(\"vuuFilterClause-clearButton\")) {\n return activeElement as HTMLElement;\n } else {\n return getFilterClauseFieldElement(activeElement);\n }\n};\n\nexport const focusNextElement = () => {\n const filterClauseField = getFocusedField();\n const filterClause = getFilterClauseElement(filterClauseField);\n if (filterClause && filterClauseField) {\n if (filterClauseField.classList.contains(\"vuuFilterClauseValue\")) {\n const clearButton = filterClause.querySelector(\n \".vuuFilterClause-clearButton\",\n ) as HTMLButtonElement;\n clearButton?.focus();\n } else {\n focusNextFocusableElement();\n }\n }\n};\n\nconst cursorAtTextStart = (input: HTMLInputElement) =>\n input.selectionStart === 0;\n\nconst cursorAtTextEnd = (input: HTMLInputElement) =>\n input.selectionStart === input.value.length;\n\nconst getFieldName = (field: HTMLElement) =>\n field?.classList.contains(\"vuuFilterClauseColumn\")\n ? \"column\"\n : field?.classList.contains(\"vuuFilterClauseOperator\")\n ? \"operator\"\n : \"value\";\n\nexport const clauseIsNotFirst = (el: HTMLElement) => {\n const clause = getFilterClauseElement(el);\n if (clause) {\n const index = getElementDataIndex(clause);\n return index > 0;\n }\n};\n\nconst clauseIsNotLast = (el: HTMLElement) => {\n const clause = getFilterClauseElement(el);\n const nextClause = clause?.nextElementSibling as HTMLElement;\n return nextClause?.classList.contains(\"vuuFilterClauseCombinator\");\n};\n\nexport const tabToPreviousFilterCombinator = (currentElement: HTMLElement) => {\n const filterClause = getFilterClauseElement(currentElement);\n const nextItem = filterClause.previousSibling as HTMLElement;\n console.log(`tab to previous combinator`);\n nextItem?.focus();\n};\n\nexport const navigateToNextFilterClause = (\n currentElement: HTMLElement,\n direction: \"bwd\" | \"fwd\" = \"fwd\",\n) => {\n if (direction === \"bwd\") {\n if (elementIsFilterCombinator(currentElement)) {\n const nextClause = currentElement.previousElementSibling;\n if (elementIsFilterClause(nextClause)) {\n const nextField = nextClause.querySelector(\n \".vuuFilterClauseValue\",\n ) as HTMLElement;\n console.log(`focus field Value ${nextField?.classList}`);\n focusField(nextField);\n }\n } else {\n const filterClause = getFilterClauseElement(currentElement);\n const nextClause = filterClause.previousSibling as HTMLElement;\n const nextField = nextClause.querySelector(\n \".vuuFilterClauseValue\",\n ) as HTMLElement;\n focusField(nextField);\n }\n } else {\n const nextClause = currentElement.nextSibling as HTMLElement;\n focusField(nextClause);\n }\n};\n\n// The logic around preventDefault/stopPropagation is important\n// in this function\nexport const navigateToNextItemIfAtBoundary = (\n evt: KeyboardEvent<HTMLInputElement>,\n) => {\n const input = evt.target as HTMLInputElement;\n const field = getFilterClauseFieldElement(input);\n if (evt.key === \"ArrowLeft\") {\n if (cursorAtTextStart(input)) {\n const fieldName = getFieldName(field);\n if (fieldName === \"column\") {\n if (clauseIsNotFirst(input)) {\n const filterClause = getFilterClauseElement(field);\n const combinator = filterClause.previousElementSibling as HTMLElement;\n combinator?.focus();\n }\n } else {\n evt.preventDefault();\n focusField(field.previousSibling as HTMLElement);\n }\n }\n // stopPropagation, even if cursor is not at start. We want the arrowLeft to move the cursor\n evt.stopPropagation();\n } else if (evt.key === \"ArrowRight\") {\n if (cursorAtTextEnd(input as HTMLInputElement)) {\n const fieldName = getFieldName(field);\n if (fieldName === \"value\") {\n if (clauseIsNotLast(input)) {\n const filterClause = getFilterClauseElement(field);\n const combinator = filterClause.nextElementSibling as HTMLElement;\n combinator?.focus();\n }\n // Do not preventDefault, stopPropagation\n return;\n } else {\n evt.preventDefault();\n focusField(field.nextSibling as HTMLElement);\n }\n }\n // stopPropagation, even if cursor is not at end. We want the arrowRight to move the cursor\n evt.stopPropagation();\n }\n};\n\nexport const focusFirstClauseIfAllClausesValid = (\n filterEditor: HTMLElement,\n) => {\n const columInput = Array.from(\n filterEditor.querySelectorAll(\".vuuFilterClauseColumn input\"),\n ) as HTMLInputElement[];\n if (columInput.every((input) => input.value.length > 0)) {\n setTimeout(() => {\n const input = columInput.at(0);\n input?.select();\n input?.focus();\n }, 100);\n }\n};\n"],"names":[],"mappings":";;AAGA,MAAM,sBAAyB,GAAA,CAAC,kBAC9B,KAAA,kBAAA,EAAoB,QAAQ,kBAAkB,CAAA;AAEhD,MAAM,2BAA8B,GAAA,CAAC,kBACnC,KAAA,kBAAA,EAAoB,QAAQ,uBAAuB,CAAA;AAGrD,MAAM,yBAAmE,GAAA;AAAA,EACvE,MAAQ,EAAA,uBAAA;AAAA,EACR,QAAU,EAAA,yBAAA;AAAA,EACV,KAAO,EAAA;AACT,CAAA;AAEA,MAAM,sBAAyB,GAAA,CAAC,EAAE,SAAA,EAA6B,KAAA;AAC7D,EAAI,IAAA,SAAA,CAAU,QAAS,CAAA,uBAAuB,CAAG,EAAA;AAC/C,IAAO,OAAA,QAAA;AAAA,GACE,MAAA,IAAA,SAAA,CAAU,QAAS,CAAA,yBAAyB,CAAG,EAAA;AACxD,IAAO,OAAA,UAAA;AAAA,GACE,MAAA,IAAA,SAAA,CAAU,QAAS,CAAA,sBAAsB,CAAG,EAAA;AACrD,IAAO,OAAA,OAAA;AAAA,GACF,MAAA;AACL,IAAM,MAAA,KAAA;AAAA,MACJ;AAAA,KACF;AAAA;AAEJ,CAAA;AAEO,MAAM,yBAAyB,MAA6B;AACjE,EAAA,MAAM,KAAK,QAAS,CAAA,aAAA;AACpB,EAAM,MAAA,KAAA,GAAQ,YAAa,CAAA,EAAA,EAAI,qCAAqC,CAAA;AACpE,EAAI,IAAA,KAAA,EAAO,OAAQ,CAAA,uBAAuB,CAAG,EAAA;AAC3C,IAAM,MAAA,YAAA,GAAe,YAAa,CAAA,KAAA,EAAO,kBAAkB,CAAA;AAC3D,IAAA,IAAI,gBAAgB,KAAO,EAAA;AACzB,MAAA,OAAO,CAAC,mBAAoB,CAAA,YAAY,CAAG,EAAA,sBAAA,CAAuB,KAAK,CAAC,CAAA;AAAA;AAC1E,GACS,MAAA,IAAA,KAAA,EAAO,OAAQ,CAAA,eAAe,CAAG,EAAA;AAC1C,IAAA,OAAA,CAAQ,IAAI,+BAA+B,CAAA;AAAA;AAM7C,EAAA,OAAO,EAAC;AAEV;AAIA,MAAM,UAAA,GAAa,CAAC,aAAsC,KAAA;AACxD,EAAM,MAAA,KAAA,GAAQ,aAAe,EAAA,aAAA,CAAc,OAAO,CAAA;AAClD,EAAA,IAAI,KAAO,EAAA;AACT,IAAA,KAAA,CAAM,KAAM,EAAA;AACZ,IAAA,qBAAA,CAAsB,MAAM;AAC1B,MAAA,KAAA,EAAO,MAAO,EAAA;AAAA,KACf,CAAA;AAAA;AAEL,CAAA;AAEa,MAAA,yBAAA,GAA4B,CACvC,OAEA,KAAA,OAAA,KAAY,QAAQ,OAAQ,CAAA,SAAA,CAAU,SAAS,2BAA2B;AAE/D,MAAA,qBAAA,GAAwB,CACnC,OAEA,KAAA,OAAA,KAAY,QAAQ,OAAQ,CAAA,SAAA,CAAU,SAAS,iBAAiB;AAE3D,MAAM,sBAAyB,GAAA,CACpC,YACA,EAAA,iBAAA,EACA,YAAmC,OAChC,KAAA;AACH,EAAA,IAAI,YAAc,EAAA;AAChB,IAAM,MAAA,cAAA,GAAiB,0BAA0B,SAAS,CAAA;AAC1D,IAAA,MAAM,QAAQ,YAAa,CAAA,aAAA;AAAA,MACzB,CAAA,6BAAA,EAAgC,iBAAiB,CAAA,IAAA,EAAO,cAAc,CAAA;AAAA,KACxE;AACA,IAAA,UAAA,CAAW,KAAK,CAAA;AAAA;AAEpB;AAEa,MAAA,oBAAA,GAAuB,CAAC,YAA8B,KAAA;AACjE,EAAA,OAAA,CAAQ,IAAI,sBAAsB,CAAA;AAClC,EAAA,MAAM,QAAQ,KAAM,CAAA,IAAA;AAAA,IAClB,YAAA,EAAc,iBAAiB,uBAAuB;AAAA,GACxD,CAAE,GAAG,CAAE,CAAA,CAAA;AACP,EAAA,UAAA,CAAW,KAAK,CAAA;AAClB;AAEa,MAAA,yBAAA,GAA4B,CAAC,SAAA,GAA2B,KAAU,KAAA;AAC7E,EAAA,MAAM,cAAc,eAAgB,EAAA;AACpC,EAAM,MAAA,YAAA,GAAe,uBAAuB,WAAW,CAAA;AACvD,EAAA,IAAI,SAAc,KAAA,KAAA,IAAS,YAAc,EAAA,SAAA,KAAc,WAAa,EAAA;AAClE,IAAA,qBAAA,CAAsB,MAAM;AAC1B,MAA0B,yBAAA,EAAA;AAAA,KAC3B,CAAA;AAAA,GACI,MAAA;AACL,IAAA,MAAM,SACJ,GAAA,SAAA,KAAc,KACT,GAAA,WAAA,EAAa,qBACb,WAAa,EAAA,sBAAA;AAEpB,IAAW,SAAA,EAAA,aAAA,CAAc,OAAO,CAAA,EAAG,KAAM,EAAA;AAAA;AAE7C;AAEA,MAAM,kBAAkB,MAAM;AAC5B,EAAA,MAAM,gBAAgB,QAAS,CAAA,aAAA;AAC/B,EAAA,IAAI,aAAe,EAAA,SAAA,CAAU,QAAS,CAAA,6BAA6B,CAAG,EAAA;AACpE,IAAO,OAAA,aAAA;AAAA,GACF,MAAA;AACL,IAAA,OAAO,4BAA4B,aAAa,CAAA;AAAA;AAEpD,CAAA;AAEO,MAAM,mBAAmB,MAAM;AACpC,EAAA,MAAM,oBAAoB,eAAgB,EAAA;AAC1C,EAAM,MAAA,YAAA,GAAe,uBAAuB,iBAAiB,CAAA;AAC7D,EAAA,IAAI,gBAAgB,iBAAmB,EAAA;AACrC,IAAA,IAAI,iBAAkB,CAAA,SAAA,CAAU,QAAS,CAAA,sBAAsB,CAAG,EAAA;AAChE,MAAA,MAAM,cAAc,YAAa,CAAA,aAAA;AAAA,QAC/B;AAAA,OACF;AACA,MAAA,WAAA,EAAa,KAAM,EAAA;AAAA,KACd,MAAA;AACL,MAA0B,yBAAA,EAAA;AAAA;AAC5B;AAEJ;AAEA,MAAM,iBAAoB,GAAA,CAAC,KACzB,KAAA,KAAA,CAAM,cAAmB,KAAA,CAAA;AAE3B,MAAM,kBAAkB,CAAC,KAAA,KACvB,KAAM,CAAA,cAAA,KAAmB,MAAM,KAAM,CAAA,MAAA;AAEvC,MAAM,YAAe,GAAA,CAAC,KACpB,KAAA,KAAA,EAAO,UAAU,QAAS,CAAA,uBAAuB,CAC7C,GAAA,QAAA,GACA,KAAO,EAAA,SAAA,CAAU,QAAS,CAAA,yBAAyB,IACjD,UACA,GAAA,OAAA;AAEK,MAAA,gBAAA,GAAmB,CAAC,EAAoB,KAAA;AACnD,EAAM,MAAA,MAAA,GAAS,uBAAuB,EAAE,CAAA;AACxC,EAAA,IAAI,MAAQ,EAAA;AACV,IAAM,MAAA,KAAA,GAAQ,oBAAoB,MAAM,CAAA;AACxC,IAAA,OAAO,KAAQ,GAAA,CAAA;AAAA;AAEnB;AAEA,MAAM,eAAA,GAAkB,CAAC,EAAoB,KAAA;AAC3C,EAAM,MAAA,MAAA,GAAS,uBAAuB,EAAE,CAAA;AACxC,EAAA,MAAM,aAAa,MAAQ,EAAA,kBAAA;AAC3B,EAAO,OAAA,UAAA,EAAY,SAAU,CAAA,QAAA,CAAS,2BAA2B,CAAA;AACnE,CAAA;AAEa,MAAA,6BAAA,GAAgC,CAAC,cAAgC,KAAA;AAC5E,EAAM,MAAA,YAAA,GAAe,uBAAuB,cAAc,CAAA;AAC1D,EAAA,MAAM,WAAW,YAAa,CAAA,eAAA;AAC9B,EAAA,OAAA,CAAQ,IAAI,CAA4B,0BAAA,CAAA,CAAA;AACxC,EAAA,QAAA,EAAU,KAAM,EAAA;AAClB;AAEO,MAAM,0BAA6B,GAAA,CACxC,cACA,EAAA,SAAA,GAA2B,KACxB,KAAA;AACH,EAAA,IAAI,cAAc,KAAO,EAAA;AACvB,IAAI,IAAA,yBAAA,CAA0B,cAAc,CAAG,EAAA;AAC7C,MAAA,MAAM,aAAa,cAAe,CAAA,sBAAA;AAClC,MAAI,IAAA,qBAAA,CAAsB,UAAU,CAAG,EAAA;AACrC,QAAA,MAAM,YAAY,UAAW,CAAA,aAAA;AAAA,UAC3B;AAAA,SACF;AACA,QAAA,OAAA,CAAQ,GAAI,CAAA,CAAA,kBAAA,EAAqB,SAAW,EAAA,SAAS,CAAE,CAAA,CAAA;AACvD,QAAA,UAAA,CAAW,SAAS,CAAA;AAAA;AACtB,KACK,MAAA;AACL,MAAM,MAAA,YAAA,GAAe,uBAAuB,cAAc,CAAA;AAC1D,MAAA,MAAM,aAAa,YAAa,CAAA,eAAA;AAChC,MAAA,MAAM,YAAY,UAAW,CAAA,aAAA;AAAA,QAC3B;AAAA,OACF;AACA,MAAA,UAAA,CAAW,SAAS,CAAA;AAAA;AACtB,GACK,MAAA;AACL,IAAA,MAAM,aAAa,cAAe,CAAA,WAAA;AAClC,IAAA,UAAA,CAAW,UAAU,CAAA;AAAA;AAEzB;AAIa,MAAA,8BAAA,GAAiC,CAC5C,GACG,KAAA;AACH,EAAA,MAAM,QAAQ,GAAI,CAAA,MAAA;AAClB,EAAM,MAAA,KAAA,GAAQ,4BAA4B,KAAK,CAAA;AAC/C,EAAI,IAAA,GAAA,CAAI,QAAQ,WAAa,EAAA;AAC3B,IAAI,IAAA,iBAAA,CAAkB,KAAK,CAAG,EAAA;AAC5B,MAAM,MAAA,SAAA,GAAY,aAAa,KAAK,CAAA;AACpC,MAAA,IAAI,cAAc,QAAU,EAAA;AAC1B,QAAI,IAAA,gBAAA,CAAiB,KAAK,CAAG,EAAA;AAC3B,UAAM,MAAA,YAAA,GAAe,uBAAuB,KAAK,CAAA;AACjD,UAAA,MAAM,aAAa,YAAa,CAAA,sBAAA;AAChC,UAAA,UAAA,EAAY,KAAM,EAAA;AAAA;AACpB,OACK,MAAA;AACL,QAAA,GAAA,CAAI,cAAe,EAAA;AACnB,QAAA,UAAA,CAAW,MAAM,eAA8B,CAAA;AAAA;AACjD;AAGF,IAAA,GAAA,CAAI,eAAgB,EAAA;AAAA,GACtB,MAAA,IAAW,GAAI,CAAA,GAAA,KAAQ,YAAc,EAAA;AACnC,IAAI,IAAA,eAAA,CAAgB,KAAyB,CAAG,EAAA;AAC9C,MAAM,MAAA,SAAA,GAAY,aAAa,KAAK,CAAA;AACpC,MAAA,IAAI,cAAc,OAAS,EAAA;AACzB,QAAI,IAAA,eAAA,CAAgB,KAAK,CAAG,EAAA;AAC1B,UAAM,MAAA,YAAA,GAAe,uBAAuB,KAAK,CAAA;AACjD,UAAA,MAAM,aAAa,YAAa,CAAA,kBAAA;AAChC,UAAA,UAAA,EAAY,KAAM,EAAA;AAAA;AAGpB,QAAA;AAAA,OACK,MAAA;AACL,QAAA,GAAA,CAAI,cAAe,EAAA;AACnB,QAAA,UAAA,CAAW,MAAM,WAA0B,CAAA;AAAA;AAC7C;AAGF,IAAA,GAAA,CAAI,eAAgB,EAAA;AAAA;AAExB;AAEa,MAAA,iCAAA,GAAoC,CAC/C,YACG,KAAA;AACH,EAAA,MAAM,aAAa,KAAM,CAAA,IAAA;AAAA,IACvB,YAAA,CAAa,iBAAiB,8BAA8B;AAAA,GAC9D;AACA,EAAI,IAAA,UAAA,CAAW,MAAM,CAAC,KAAA,KAAU,MAAM,KAAM,CAAA,MAAA,GAAS,CAAC,CAAG,EAAA;AACvD,IAAA,UAAA,CAAW,MAAM;AACf,MAAM,MAAA,KAAA,GAAQ,UAAW,CAAA,EAAA,CAAG,CAAC,CAAA;AAC7B,MAAA,KAAA,EAAO,MAAO,EAAA;AACd,MAAA,KAAA,EAAO,KAAM,EAAA;AAAA,OACZ,GAAG,CAAA;AAAA;AAEV;;;;"}
|
|
1
|
+
{"version":3,"file":"filterClauseFocusManagement.js","sources":["../../../../packages/vuu-filters/src/filter-clause/filterClauseFocusManagement.ts"],"sourcesContent":["import { getElementDataIndex, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { KeyboardEvent } from \"react\";\n\nconst getFilterClauseElement = (possiblyDescendant?: HTMLElement) =>\n possiblyDescendant?.closest(\".vuuFilterClause\") as HTMLElement;\n\nconst getFilterClauseFieldElement = (possiblyDescendant?: HTMLElement) =>\n possiblyDescendant?.closest(\".vuuFilterClauseField\") as HTMLElement;\n\ntype FilterClauseFieldName = \"column\" | \"operator\" | \"value\";\nconst mapFilterFieldToClassName: Record<FilterClauseFieldName, string> = {\n column: \"vuuFilterClauseColumn\",\n operator: \"vuuFilterClauseOperator\",\n value: \"vuuFilterClauseValue\",\n};\n\nconst getFilterClauseDetails = ({ classList }: HTMLElement) => {\n if (classList.contains(\"vuuFilterClauseColumn\")) {\n return \"column\";\n } else if (classList.contains(\"vuuFilterClauseOperator\")) {\n return \"operator\";\n } else if (classList.contains(\"vuuFilterClauseValue\")) {\n return \"value\";\n } else {\n throw Error(\n \"getFilterClauseField, filterClauseElemnent is missing required class name\",\n );\n }\n};\n\nexport const getFocusedFieldDetails = (): [number, string] | [] => {\n const el = document.activeElement as HTMLElement;\n const field = queryClosest(el, \".vuuFilterClauseField,.saltCalendar\");\n if (field?.matches(\".vuuFilterClauseField\")) {\n const filterClause = queryClosest(field, \".vuuFilterClause\");\n if (filterClause && field) {\n return [getElementDataIndex(filterClause), getFilterClauseDetails(field)];\n }\n } else if (field?.matches(\".saltCalendar\")) {\n console.log(\"its in a calendar\");\n }\n // const filterClause = queryClosest(field, \".vuuFilterClause\");\n // if (filterClause && field) {\n // return [getElementDataIndex(filterClause), getFilterClauseDetails(field)];\n // } else {\n return [];\n // }\n};\n\n// Focus the input control within field. If clause passed, will\n// focus first field within clause\nconst focusField = (fieldOrClause: HTMLElement | null) => {\n const input = fieldOrClause?.querySelector(\"input\");\n if (input) {\n input.focus();\n requestAnimationFrame(() => {\n input?.select();\n });\n }\n};\n\nexport const elementIsFilterCombinator = (\n element: Element | null,\n): element is HTMLElement =>\n element !== null && element.classList.contains(\"vuuFilterClauseCombinator\");\n\nexport const elementIsFilterClause = (\n element: Element | null,\n): element is HTMLElement =>\n element !== null && element.classList.contains(\"vuuFilterClause\");\n\nexport const focusFilterClauseField = (\n filterEditor: HTMLElement,\n filterClauseIndex: number,\n fieldName: FilterClauseFieldName = \"value\",\n) => {\n if (filterEditor) {\n const fieldClassName = mapFilterFieldToClassName[fieldName];\n const field = filterEditor.querySelector(\n `.vuuFilterClause[data-index=\"${filterClauseIndex}\"] .${fieldClassName}`,\n ) as HTMLElement;\n focusField(field);\n }\n};\n\nexport const focusLastClauseValue = (filterEditor: HTMLElement) => {\n console.log(\"focusLastClauseValue\");\n const field = Array.from(\n filterEditor?.querySelectorAll(\".vuuFilterClauseField\"),\n ).at(-1) as HTMLElement;\n focusField(field);\n};\n\nexport const focusNextFocusableElement = (direction: \"fwd\" | \"bwd\" = \"fwd\") => {\n const activeField = getFocusedField() as HTMLElement;\n const filterClause = getFilterClauseElement(activeField);\n if (direction === \"fwd\" && filterClause?.lastChild === activeField) {\n requestAnimationFrame(() => {\n focusNextFocusableElement();\n });\n } else {\n const nextField =\n direction === \"fwd\"\n ? (activeField?.nextElementSibling as HTMLElement)\n : (activeField?.previousElementSibling as HTMLElement);\n\n nextField?.querySelector(\"input\")?.focus();\n }\n};\n\nconst getFocusedField = () => {\n const activeElement = document.activeElement as HTMLElement;\n if (activeElement?.classList.contains(\"vuuFilterClause-clearButton\")) {\n return activeElement as HTMLElement;\n } else {\n return getFilterClauseFieldElement(activeElement);\n }\n};\n\nexport const focusNextElement = () => {\n const filterClauseField = getFocusedField();\n const filterClause = getFilterClauseElement(filterClauseField);\n if (filterClause && filterClauseField) {\n if (filterClauseField.classList.contains(\"vuuFilterClauseValue\")) {\n const clearButton = filterClause.querySelector(\n \".vuuFilterClause-clearButton\",\n ) as HTMLButtonElement;\n clearButton?.focus();\n } else {\n focusNextFocusableElement();\n }\n }\n};\n\nconst cursorAtTextStart = (input: HTMLInputElement) =>\n input.selectionStart === 0;\n\nconst cursorAtTextEnd = (input: HTMLInputElement) =>\n input.selectionStart === input.value.length;\n\nconst getFieldName = (field: HTMLElement) =>\n field?.classList.contains(\"vuuFilterClauseColumn\")\n ? \"column\"\n : field?.classList.contains(\"vuuFilterClauseOperator\")\n ? \"operator\"\n : \"value\";\n\nexport const clauseIsNotFirst = (el: HTMLElement) => {\n const clause = getFilterClauseElement(el);\n if (clause) {\n const index = getElementDataIndex(clause);\n return index > 0;\n }\n};\n\nconst clauseIsNotLast = (el: HTMLElement) => {\n const clause = getFilterClauseElement(el);\n const nextClause = clause?.nextElementSibling as HTMLElement;\n return nextClause?.classList.contains(\"vuuFilterClauseCombinator\");\n};\n\nexport const tabToPreviousFilterCombinator = (currentElement: HTMLElement) => {\n const filterClause = getFilterClauseElement(currentElement);\n const nextItem = filterClause.previousSibling as HTMLElement;\n console.log(`tab to previous combinator`);\n nextItem?.focus();\n};\n\nexport const navigateToNextFilterClause = (\n currentElement: HTMLElement,\n direction: \"bwd\" | \"fwd\" = \"fwd\",\n) => {\n if (direction === \"bwd\") {\n if (elementIsFilterCombinator(currentElement)) {\n const nextClause = currentElement.previousElementSibling;\n if (elementIsFilterClause(nextClause)) {\n const nextField = nextClause.querySelector(\n \".vuuFilterClauseValue\",\n ) as HTMLElement;\n console.log(`focus field Value ${nextField?.classList}`);\n focusField(nextField);\n }\n } else {\n const filterClause = getFilterClauseElement(currentElement);\n const nextClause = filterClause.previousSibling as HTMLElement;\n const nextField = nextClause.querySelector(\n \".vuuFilterClauseValue\",\n ) as HTMLElement;\n focusField(nextField);\n }\n } else {\n const nextClause = currentElement.nextSibling as HTMLElement;\n focusField(nextClause);\n }\n};\n\n// The logic around preventDefault/stopPropagation is important\n// in this function\nexport const navigateToNextItemIfAtBoundary = (\n evt: KeyboardEvent<HTMLInputElement>,\n) => {\n const input = evt.target as HTMLInputElement;\n const field = getFilterClauseFieldElement(input);\n if (evt.key === \"ArrowLeft\") {\n if (cursorAtTextStart(input)) {\n const fieldName = getFieldName(field);\n if (fieldName === \"column\") {\n if (clauseIsNotFirst(input)) {\n const filterClause = getFilterClauseElement(field);\n const combinator = filterClause.previousElementSibling as HTMLElement;\n combinator?.focus();\n }\n } else {\n evt.preventDefault();\n focusField(field.previousSibling as HTMLElement);\n }\n }\n // stopPropagation, even if cursor is not at start. We want the arrowLeft to move the cursor\n evt.stopPropagation();\n } else if (evt.key === \"ArrowRight\") {\n if (cursorAtTextEnd(input as HTMLInputElement)) {\n const fieldName = getFieldName(field);\n if (fieldName === \"value\") {\n if (clauseIsNotLast(input)) {\n const filterClause = getFilterClauseElement(field);\n const combinator = filterClause.nextElementSibling as HTMLElement;\n combinator?.focus();\n }\n // Do not preventDefault, stopPropagation\n return;\n } else {\n evt.preventDefault();\n focusField(field.nextSibling as HTMLElement);\n }\n }\n // stopPropagation, even if cursor is not at end. We want the arrowRight to move the cursor\n evt.stopPropagation();\n }\n};\n\nexport const focusFirstClauseIfAllClausesValid = (\n filterEditor: HTMLElement,\n) => {\n const columInput = Array.from(\n filterEditor.querySelectorAll(\".vuuFilterClauseColumn input\"),\n ) as HTMLInputElement[];\n if (columInput.every((input) => input.value.length > 0)) {\n setTimeout(() => {\n const input = columInput.at(0);\n input?.select();\n input?.focus();\n }, 100);\n }\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -2,9 +2,10 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import cx from 'clsx';
|
|
3
3
|
import { FilterClauseValueEditorNumber } from './FilterClauseValueEditorNumber.js';
|
|
4
4
|
import { FilterClauseValueEditorText } from './FilterClauseValueEditorText.js';
|
|
5
|
-
import { isDateTimeDataValue } from '@vuu-ui/vuu-utils';
|
|
5
|
+
import { isDateTimeDataValue, isTimeDataValue } from '@vuu-ui/vuu-utils';
|
|
6
6
|
import { forwardRef } from 'react';
|
|
7
7
|
import { FilterClauseValueEditorDate } from './FilterClauseValueEditorDate.js';
|
|
8
|
+
import { FilterClauseValueEditorTime } from './FilterClauseValueEditorTime.js';
|
|
8
9
|
|
|
9
10
|
const classBase = "vuuFilterClause";
|
|
10
11
|
const FilterClauseValueEditor = forwardRef(
|
|
@@ -32,6 +33,17 @@ const FilterClauseValueEditor = forwardRef(
|
|
|
32
33
|
onChangeValue
|
|
33
34
|
}
|
|
34
35
|
);
|
|
36
|
+
} else if (isTimeDataValue(selectedColumn)) {
|
|
37
|
+
return /* @__PURE__ */ jsx(
|
|
38
|
+
FilterClauseValueEditorTime,
|
|
39
|
+
{
|
|
40
|
+
inputProps,
|
|
41
|
+
className: cx(`${classBase}Field`, `${classBase}Value`),
|
|
42
|
+
value,
|
|
43
|
+
operator,
|
|
44
|
+
onChangeValue
|
|
45
|
+
}
|
|
46
|
+
);
|
|
35
47
|
}
|
|
36
48
|
switch (selectedColumn.serverDataType) {
|
|
37
49
|
case "string":
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterClauseValueEditor.js","sources":["../../../../../packages/vuu-filters/src/filter-clause/value-editors/FilterClauseValueEditor.tsx"],"sourcesContent":["import { TableSchemaTable } from \"@vuu-ui/vuu-data-types\";\nimport cx from \"clsx\";\nimport { useFilterClause } from \"../useFilterClause\";\nimport { FilterClauseValueEditorNumber } from \"./FilterClauseValueEditorNumber\";\nimport { FilterClauseValueEditorText } from \"./FilterClauseValueEditorText\";\n\nimport {\n NumericFilterClauseOp,\n SingleValueFilterClauseOp,\n} from \"@vuu-ui/vuu-filter-types\";\nimport { isDateTimeDataValue } from \"@vuu-ui/vuu-utils\";\nimport { ForwardedRef, forwardRef } from \"react\";\nimport { FilterClauseValueEditorDate } from \"./FilterClauseValueEditorDate\";\n\nconst classBase = \"vuuFilterClause\";\n\ntype FilterClauseValueEditorProps = Pick<\n ReturnType<typeof useFilterClause>,\n | \"selectedColumn\"\n | \"inputProps\"\n | \"onChangeValue\"\n | \"onDeselectValue\"\n | \"onOpenChange\"\n> & {\n table?: TableSchemaTable;\n} & {\n operator?: SingleValueFilterClauseOp | \"in\";\n value?: string | string[] | number | number[] | boolean | boolean[];\n};\n\nexport const FilterClauseValueEditor = forwardRef(\n function FilterClauseValueEditor(\n {\n selectedColumn,\n operator,\n inputProps,\n onChangeValue,\n onDeselectValue,\n onOpenChange,\n table,\n value,\n }: FilterClauseValueEditorProps,\n forwardedRef: ForwardedRef<HTMLDivElement>,\n ) {\n if (selectedColumn === undefined || operator === undefined) {\n return null;\n }\n\n if (isDateTimeDataValue(selectedColumn)) {\n return (\n <FilterClauseValueEditorDate\n inputProps={inputProps}\n className={cx(`${classBase}Field`, `${classBase}Value`)}\n
|
|
1
|
+
{"version":3,"file":"FilterClauseValueEditor.js","sources":["../../../../../packages/vuu-filters/src/filter-clause/value-editors/FilterClauseValueEditor.tsx"],"sourcesContent":["import { TableSchemaTable } from \"@vuu-ui/vuu-data-types\";\nimport cx from \"clsx\";\nimport { useFilterClause } from \"../useFilterClause\";\nimport { FilterClauseValueEditorNumber } from \"./FilterClauseValueEditorNumber\";\nimport { FilterClauseValueEditorText } from \"./FilterClauseValueEditorText\";\n\nimport {\n NumericFilterClauseOp,\n SingleValueFilterClauseOp,\n} from \"@vuu-ui/vuu-filter-types\";\nimport { isDateTimeDataValue, isTimeDataValue } from \"@vuu-ui/vuu-utils\";\nimport { ForwardedRef, forwardRef } from \"react\";\nimport { FilterClauseValueEditorDate } from \"./FilterClauseValueEditorDate\";\nimport { FilterClauseValueEditorTime } from \"./FilterClauseValueEditorTime\";\n\nconst classBase = \"vuuFilterClause\";\n\ntype FilterClauseValueEditorProps = Pick<\n ReturnType<typeof useFilterClause>,\n | \"selectedColumn\"\n | \"inputProps\"\n | \"onChangeValue\"\n | \"onDeselectValue\"\n | \"onOpenChange\"\n> & {\n table?: TableSchemaTable;\n} & {\n operator?: SingleValueFilterClauseOp | \"in\";\n value?: string | string[] | number | number[] | boolean | boolean[];\n};\n\nexport const FilterClauseValueEditor = forwardRef(\n function FilterClauseValueEditor(\n {\n selectedColumn,\n operator,\n inputProps,\n onChangeValue,\n onDeselectValue,\n onOpenChange,\n table,\n value,\n }: FilterClauseValueEditorProps,\n forwardedRef: ForwardedRef<HTMLDivElement>,\n ) {\n if (selectedColumn === undefined || operator === undefined) {\n return null;\n }\n\n if (isDateTimeDataValue(selectedColumn)) {\n return (\n <FilterClauseValueEditorDate\n inputProps={inputProps}\n className={cx(`${classBase}Field`, `${classBase}Value`)}\n value={value as number}\n operator={operator as NumericFilterClauseOp}\n onChangeValue={onChangeValue}\n />\n );\n } else if (isTimeDataValue(selectedColumn)) {\n return (\n <FilterClauseValueEditorTime\n inputProps={inputProps}\n className={cx(`${classBase}Field`, `${classBase}Value`)}\n value={value as number}\n operator={operator as NumericFilterClauseOp}\n onChangeValue={onChangeValue}\n />\n );\n }\n\n switch (selectedColumn.serverDataType) {\n case \"string\":\n case \"char\":\n return (\n <FilterClauseValueEditorText\n inputProps={inputProps}\n className={cx(`${classBase}Field`, `${classBase}Value`)}\n column={selectedColumn}\n onDeselect={onDeselectValue}\n onChangeValue={onChangeValue}\n onOpenChange={onOpenChange}\n operator={operator}\n ref={forwardedRef}\n table={table}\n value={\n value === undefined\n ? \"\"\n : Array.isArray(value)\n ? value.map((val) => val.toString())\n : (value.toString() as string | string[])\n }\n />\n );\n case \"int\":\n case \"long\":\n case \"double\":\n return (\n <FilterClauseValueEditorNumber\n inputProps={inputProps}\n className={cx(`${classBase}Field`, `${classBase}Value`)}\n column={selectedColumn}\n data-field=\"value\"\n onChangeValue={onChangeValue}\n operator={operator}\n ref={forwardedRef}\n />\n );\n default:\n console.log(\"returning null\");\n return null;\n }\n },\n);\n"],"names":["FilterClauseValueEditor"],"mappings":";;;;;;;;;AAeA,MAAM,SAAY,GAAA,iBAAA;AAgBX,MAAM,uBAA0B,GAAA,UAAA;AAAA,EACrC,SAASA,wBACP,CAAA;AAAA,IACE,cAAA;AAAA,IACA,QAAA;AAAA,IACA,UAAA;AAAA,IACA,aAAA;AAAA,IACA,eAAA;AAAA,IACA,YAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,KAEF,YACA,EAAA;AACA,IAAI,IAAA,cAAA,KAAmB,KAAa,CAAA,IAAA,QAAA,KAAa,KAAW,CAAA,EAAA;AAC1D,MAAO,OAAA,IAAA;AAAA;AAGT,IAAI,IAAA,mBAAA,CAAoB,cAAc,CAAG,EAAA;AACvC,MACE,uBAAA,GAAA;AAAA,QAAC,2BAAA;AAAA,QAAA;AAAA,UACC,UAAA;AAAA,UACA,WAAW,EAAG,CAAA,CAAA,EAAG,SAAS,CAAS,KAAA,CAAA,EAAA,CAAA,EAAG,SAAS,CAAO,KAAA,CAAA,CAAA;AAAA,UACtD,KAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA;AAAA,OACF;AAAA,KAEJ,MAAA,IAAW,eAAgB,CAAA,cAAc,CAAG,EAAA;AAC1C,MACE,uBAAA,GAAA;AAAA,QAAC,2BAAA;AAAA,QAAA;AAAA,UACC,UAAA;AAAA,UACA,WAAW,EAAG,CAAA,CAAA,EAAG,SAAS,CAAS,KAAA,CAAA,EAAA,CAAA,EAAG,SAAS,CAAO,KAAA,CAAA,CAAA;AAAA,UACtD,KAAA;AAAA,UACA,QAAA;AAAA,UACA;AAAA;AAAA,OACF;AAAA;AAIJ,IAAA,QAAQ,eAAe,cAAgB;AAAA,MACrC,KAAK,QAAA;AAAA,MACL,KAAK,MAAA;AACH,QACE,uBAAA,GAAA;AAAA,UAAC,2BAAA;AAAA,UAAA;AAAA,YACC,UAAA;AAAA,YACA,WAAW,EAAG,CAAA,CAAA,EAAG,SAAS,CAAS,KAAA,CAAA,EAAA,CAAA,EAAG,SAAS,CAAO,KAAA,CAAA,CAAA;AAAA,YACtD,MAAQ,EAAA,cAAA;AAAA,YACR,UAAY,EAAA,eAAA;AAAA,YACZ,aAAA;AAAA,YACA,YAAA;AAAA,YACA,QAAA;AAAA,YACA,GAAK,EAAA,YAAA;AAAA,YACL,KAAA;AAAA,YACA,OACE,KAAU,KAAA,KAAA,CAAA,GACN,EACA,GAAA,KAAA,CAAM,QAAQ,KAAK,CAAA,GACjB,KAAM,CAAA,GAAA,CAAI,CAAC,GAAQ,KAAA,GAAA,CAAI,UAAU,CAAA,GAChC,MAAM,QAAS;AAAA;AAAA,SAE1B;AAAA,MAEJ,KAAK,KAAA;AAAA,MACL,KAAK,MAAA;AAAA,MACL,KAAK,QAAA;AACH,QACE,uBAAA,GAAA;AAAA,UAAC,6BAAA;AAAA,UAAA;AAAA,YACC,UAAA;AAAA,YACA,WAAW,EAAG,CAAA,CAAA,EAAG,SAAS,CAAS,KAAA,CAAA,EAAA,CAAA,EAAG,SAAS,CAAO,KAAA,CAAA,CAAA;AAAA,YACtD,MAAQ,EAAA,cAAA;AAAA,YACR,YAAW,EAAA,OAAA;AAAA,YACX,aAAA;AAAA,YACA,QAAA;AAAA,YACA,GAAK,EAAA;AAAA;AAAA,SACP;AAAA,MAEJ;AACE,QAAA,OAAA,CAAQ,IAAI,gBAAgB,CAAA;AAC5B,QAAO,OAAA,IAAA;AAAA;AACX;AAEJ;;;;"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useState, useCallback } from 'react';
|
|
3
|
+
import { getLocalTimeZone } from '@internationalized/date';
|
|
4
|
+
import { toCalendarDate } from '@vuu-ui/vuu-utils';
|
|
5
|
+
import { VuuTimePicker } from '@vuu-ui/vuu-ui-controls';
|
|
6
|
+
|
|
7
|
+
const FilterClauseValueEditorTime = (props) => {
|
|
8
|
+
const { className, onChangeValue, operator, value } = props;
|
|
9
|
+
const toEpochMilliS = getEpochMillisConverter(operator);
|
|
10
|
+
const [date, setDate] = useState(
|
|
11
|
+
() => getInitialState(value)
|
|
12
|
+
);
|
|
13
|
+
const handleCommit = useCallback(
|
|
14
|
+
(e, selectedDateInputValue) => {
|
|
15
|
+
console.log("change time");
|
|
16
|
+
if (selectedDateInputValue) {
|
|
17
|
+
const dateValue = toCalendarDate(new Date(selectedDateInputValue));
|
|
18
|
+
setDate(dateValue);
|
|
19
|
+
if (selectedDateInputValue) {
|
|
20
|
+
onChangeValue(toEpochMilliS(dateValue));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
[onChangeValue, toEpochMilliS]
|
|
25
|
+
);
|
|
26
|
+
const onBlur = useCallback(() => {
|
|
27
|
+
date && onChangeValue(toEpochMilliS(date));
|
|
28
|
+
}, [date, onChangeValue, toEpochMilliS]);
|
|
29
|
+
return /* @__PURE__ */ jsx(
|
|
30
|
+
VuuTimePicker,
|
|
31
|
+
{
|
|
32
|
+
"data-field": "value",
|
|
33
|
+
className,
|
|
34
|
+
onBlur,
|
|
35
|
+
onCommit: handleCommit
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
};
|
|
39
|
+
function getInitialState(value) {
|
|
40
|
+
return value ? toCalendarDate(new Date(value)) : void 0;
|
|
41
|
+
}
|
|
42
|
+
const getEpochMillisConverter = (op) => (date, timezone = getLocalTimeZone()) => {
|
|
43
|
+
const d = date.toDate(timezone);
|
|
44
|
+
switch (op) {
|
|
45
|
+
case ">":
|
|
46
|
+
case "<=":
|
|
47
|
+
d.setHours(23, 59, 59, 999);
|
|
48
|
+
return d.getTime();
|
|
49
|
+
case ">=":
|
|
50
|
+
case "<":
|
|
51
|
+
case "=":
|
|
52
|
+
// converted to "< `start of next day` and >= `start of this day`" when query is created
|
|
53
|
+
case "!=":
|
|
54
|
+
d.setHours(0, 0, 0, 0);
|
|
55
|
+
return d.getTime();
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export { FilterClauseValueEditorTime };
|
|
60
|
+
//# sourceMappingURL=FilterClauseValueEditorTime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterClauseValueEditorTime.js","sources":["../../../../../packages/vuu-filters/src/filter-clause/value-editors/FilterClauseValueEditorTime.tsx"],"sourcesContent":["import { useCallback, useState } from \"react\";\nimport { getLocalTimeZone, DateValue } from \"@internationalized/date\";\nimport { CommitHandler, toCalendarDate } from \"@vuu-ui/vuu-utils\";\nimport { NumericFilterClauseOp } from \"@vuu-ui/vuu-filter-types\";\nimport { FilterClauseValueEditor } from \"../filterClauseTypes\";\nimport { VuuTimePicker } from \"@vuu-ui/vuu-ui-controls\";\n\ninterface FilterClauseValueEditorTimeProps\n extends Pick<FilterClauseValueEditor, \"onChangeValue\" | \"inputProps\"> {\n className?: string;\n value: number | undefined;\n operator: NumericFilterClauseOp;\n}\n\nexport const FilterClauseValueEditorTime = (\n props: FilterClauseValueEditorTimeProps,\n) => {\n const { className, onChangeValue, operator, value } = props;\n const toEpochMilliS = getEpochMillisConverter(operator);\n\n const [date, setDate] = useState<DateValue | undefined>(() =>\n getInitialState(value),\n );\n\n const handleCommit = useCallback<CommitHandler<HTMLElement, number>>(\n (e, selectedDateInputValue) => {\n console.log(\"change time\");\n if (selectedDateInputValue) {\n const dateValue = toCalendarDate(new Date(selectedDateInputValue));\n setDate(dateValue);\n if (selectedDateInputValue /* && source === \"calendar\"*/) {\n onChangeValue(toEpochMilliS(dateValue));\n }\n }\n },\n [onChangeValue, toEpochMilliS],\n );\n\n const onBlur = useCallback(() => {\n date && onChangeValue(toEpochMilliS(date));\n }, [date, onChangeValue, toEpochMilliS]);\n\n return (\n <VuuTimePicker\n data-field=\"value\"\n // inputProps={inputProps}\n className={className}\n onBlur={onBlur}\n onCommit={handleCommit}\n // selectedDate={date}\n />\n );\n};\n\nfunction getInitialState(value: FilterClauseValueEditorTimeProps[\"value\"]) {\n return value ? toCalendarDate(new Date(value)) : undefined;\n}\n\nconst getEpochMillisConverter =\n (op: NumericFilterClauseOp) =>\n (date: DateValue, timezone: string = getLocalTimeZone()): number => {\n const d = date.toDate(timezone);\n switch (op) {\n case \">\":\n case \"<=\":\n d.setHours(23, 59, 59, 999);\n return d.getTime();\n case \">=\":\n case \"<\":\n case \"=\": // converted to \"< `start of next day` and >= `start of this day`\" when query is created\n case \"!=\": // converted to \">= `start of next day` or < `start of this day`\" when query is created\n d.setHours(0, 0, 0, 0);\n return d.getTime();\n }\n };\n"],"names":[],"mappings":";;;;;;AAca,MAAA,2BAAA,GAA8B,CACzC,KACG,KAAA;AACH,EAAA,MAAM,EAAE,SAAA,EAAW,aAAe,EAAA,QAAA,EAAU,OAAU,GAAA,KAAA;AACtD,EAAM,MAAA,aAAA,GAAgB,wBAAwB,QAAQ,CAAA;AAEtD,EAAM,MAAA,CAAC,IAAM,EAAA,OAAO,CAAI,GAAA,QAAA;AAAA,IAAgC,MACtD,gBAAgB,KAAK;AAAA,GACvB;AAEA,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,CAAC,GAAG,sBAA2B,KAAA;AAC7B,MAAA,OAAA,CAAQ,IAAI,aAAa,CAAA;AACzB,MAAA,IAAI,sBAAwB,EAAA;AAC1B,QAAA,MAAM,SAAY,GAAA,cAAA,CAAe,IAAI,IAAA,CAAK,sBAAsB,CAAC,CAAA;AACjE,QAAA,OAAA,CAAQ,SAAS,CAAA;AACjB,QAAA,IAAI,sBAAsD,EAAA;AACxD,UAAc,aAAA,CAAA,aAAA,CAAc,SAAS,CAAC,CAAA;AAAA;AACxC;AACF,KACF;AAAA,IACA,CAAC,eAAe,aAAa;AAAA,GAC/B;AAEA,EAAM,MAAA,MAAA,GAAS,YAAY,MAAM;AAC/B,IAAQ,IAAA,IAAA,aAAA,CAAc,aAAc,CAAA,IAAI,CAAC,CAAA;AAAA,GACxC,EAAA,CAAC,IAAM,EAAA,aAAA,EAAe,aAAa,CAAC,CAAA;AAEvC,EACE,uBAAA,GAAA;AAAA,IAAC,aAAA;AAAA,IAAA;AAAA,MACC,YAAW,EAAA,OAAA;AAAA,MAEX,SAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAU,EAAA;AAAA;AAAA,GAEZ;AAEJ;AAEA,SAAS,gBAAgB,KAAkD,EAAA;AACzE,EAAA,OAAO,QAAQ,cAAe,CAAA,IAAI,IAAK,CAAA,KAAK,CAAC,CAAI,GAAA,KAAA,CAAA;AACnD;AAEA,MAAM,0BACJ,CAAC,EAAA,KACD,CAAC,IAAiB,EAAA,QAAA,GAAmB,kBAA+B,KAAA;AAClE,EAAM,MAAA,CAAA,GAAI,IAAK,CAAA,MAAA,CAAO,QAAQ,CAAA;AAC9B,EAAA,QAAQ,EAAI;AAAA,IACV,KAAK,GAAA;AAAA,IACL,KAAK,IAAA;AACH,MAAA,CAAA,CAAE,QAAS,CAAA,EAAA,EAAI,EAAI,EAAA,EAAA,EAAI,GAAG,CAAA;AAC1B,MAAA,OAAO,EAAE,OAAQ,EAAA;AAAA,IACnB,KAAK,IAAA;AAAA,IACL,KAAK,GAAA;AAAA,IACL,KAAK,GAAA;AAAA;AAAA,IACL,KAAK,IAAA;AACH,MAAA,CAAA,CAAE,QAAS,CAAA,CAAA,EAAG,CAAG,EAAA,CAAA,EAAG,CAAC,CAAA;AACrB,MAAA,OAAO,EAAE,OAAQ,EAAA;AAAA;AAEvB,CAAA;;;;"}
|
package/esm/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { FilterClauseModel, FilterModel } from './FilterModel.js';
|
|
2
|
+
export { ColumnFilter } from './column-filter/ColumnFilter.js';
|
|
2
3
|
export { FilterBar } from './filter-bar/FilterBar.js';
|
|
3
4
|
export { ColumnPicker } from './filter-clause/ColumnPicker.js';
|
|
4
5
|
export { ExpandoCombobox } from './filter-clause/ExpandoCombobox.js';
|
package/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.13.
|
|
2
|
+
"version": "0.13.25",
|
|
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.
|
|
8
|
-
"@vuu-ui/vuu-protocol-types": "0.13.
|
|
9
|
-
"@vuu-ui/vuu-table-types": "0.13.
|
|
10
|
-
"@vuu-ui/vuu-filter-types": "0.13.
|
|
7
|
+
"@vuu-ui/vuu-data-types": "0.13.25",
|
|
8
|
+
"@vuu-ui/vuu-protocol-types": "0.13.25",
|
|
9
|
+
"@vuu-ui/vuu-table-types": "0.13.25",
|
|
10
|
+
"@vuu-ui/vuu-filter-types": "0.13.25"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@vuu-ui/vuu-data-react": "0.13.
|
|
14
|
-
"@vuu-ui/vuu-filter-parser": "0.13.
|
|
15
|
-
"@vuu-ui/vuu-popups": "0.13.
|
|
16
|
-
"@vuu-ui/vuu-ui-controls": "0.13.
|
|
17
|
-
"@vuu-ui/vuu-table": "0.13.
|
|
18
|
-
"@vuu-ui/vuu-utils": "0.13.
|
|
13
|
+
"@vuu-ui/vuu-data-react": "0.13.25",
|
|
14
|
+
"@vuu-ui/vuu-filter-parser": "0.13.25",
|
|
15
|
+
"@vuu-ui/vuu-popups": "0.13.25",
|
|
16
|
+
"@vuu-ui/vuu-ui-controls": "0.13.25",
|
|
17
|
+
"@vuu-ui/vuu-table": "0.13.25",
|
|
18
|
+
"@vuu-ui/vuu-utils": "0.13.25",
|
|
19
19
|
"@salt-ds/core": "1.43.0",
|
|
20
20
|
"@salt-ds/styles": "0.2.1",
|
|
21
21
|
"@salt-ds/window": "0.1.1"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { SegmentedButtonGroupProps } from "@salt-ds/core";
|
|
2
|
+
import { VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
3
|
+
import { ColumnFilterHookProps, FilterValue } from "./useColumnFilter";
|
|
4
|
+
export interface ColumnFilterProps extends ColumnFilterHookProps, SegmentedButtonGroupProps {
|
|
5
|
+
showOperatorPicker?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* VuuTable is required if typeahead support is expected.
|
|
8
|
+
*/
|
|
9
|
+
table?: VuuTable;
|
|
10
|
+
/**
|
|
11
|
+
* Initial filter value. Pair of values expewcted when operator is
|
|
12
|
+
* 'between'
|
|
13
|
+
*/
|
|
14
|
+
value?: FilterValue | [FilterValue, FilterValue];
|
|
15
|
+
}
|
|
16
|
+
export declare const ColumnFilter: ({ column, className, operator, showOperatorPicker, table, value, ...buttonGroupProps }: ColumnFilterProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FilterOp } from "@vuu-ui/vuu-filter-types";
|
|
2
|
+
import { ColumnDescriptor } from "@vuu-ui/vuu-table-types";
|
|
3
|
+
export type FilterValue = string | number;
|
|
4
|
+
export declare const assertValidValue: ({ serverDataType: _ }: ColumnDescriptor, operator: FilterOp | "between", value?: FilterValue | FilterValue[]) => void;
|
|
5
|
+
export interface ColumnFilterHookProps {
|
|
6
|
+
column: ColumnDescriptor;
|
|
7
|
+
operator?: FilterOp | "between";
|
|
8
|
+
}
|
|
@@ -4,7 +4,7 @@ import { ColumnDescriptor } from "@vuu-ui/vuu-table-types";
|
|
|
4
4
|
import { HTMLAttributes } from "react";
|
|
5
5
|
import { QuickFilterProps } from "../quick-filters";
|
|
6
6
|
import { FilterMode } from "./useFilterBar";
|
|
7
|
-
import { VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
7
|
+
import type { VuuTable } from "@vuu-ui/vuu-protocol-types";
|
|
8
8
|
export type FilterBarVariant = "custom-filters-only" | "quick-filters-only" | "full-filters";
|
|
9
9
|
export interface FilterBarProps extends HTMLAttributes<HTMLDivElement> {
|
|
10
10
|
QuickFilterProps?: Pick<QuickFilterProps, "quickFilterColumns" | "onChangeQuickFilterColumns">;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { NumericFilterClauseOp } from "@vuu-ui/vuu-filter-types";
|
|
2
|
+
import { FilterClauseValueEditor } from "../filterClauseTypes";
|
|
3
|
+
interface FilterClauseValueEditorTimeProps extends Pick<FilterClauseValueEditor, "onChangeValue" | "inputProps"> {
|
|
4
|
+
className?: string;
|
|
5
|
+
value: number | undefined;
|
|
6
|
+
operator: NumericFilterClauseOp;
|
|
7
|
+
}
|
|
8
|
+
export declare const FilterClauseValueEditorTime: (props: FilterClauseValueEditorTimeProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|