@1771technologies/lytenyte-pro 1.0.15 → 1.0.17-dev.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/+types.d.ts +442 -65
- package/dist/__play__/filter-select/filter-select.play.d.ts +4 -0
- package/dist/__play__/filter-select/filter-select.play.js +76 -0
- package/dist/__play__/test-utils/row-handler.js +3 -4
- package/dist/cell-selection/bound-selection-rect.js +1 -1
- package/dist/cell-selection/cell-selection-driver.js +7 -6
- package/dist/column-manager/branch.d.ts +1 -1
- package/dist/column-manager/branch.js +1 -1
- package/dist/column-manager/label.d.ts +1 -1
- package/dist/column-manager/label.js +1 -1
- package/dist/column-manager/leaf.js +1 -1
- package/dist/column-manager/move-handle.d.ts +1 -1
- package/dist/column-manager/move-handle.js +1 -2
- package/dist/column-manager/visibility-checkbox.d.ts +1 -1
- package/dist/column-manager/visibility-checkbox.js +1 -1
- package/dist/filter-selects/apply.d.ts +7 -0
- package/dist/filter-selects/apply.js +22 -0
- package/dist/filter-selects/clear.d.ts +7 -0
- package/dist/filter-selects/clear.js +22 -0
- package/dist/filter-selects/context.d.ts +13 -0
- package/dist/filter-selects/context.js +3 -0
- package/dist/filter-selects/filter-combinator.d.ts +10 -0
- package/dist/filter-selects/filter-combinator.js +19 -0
- package/dist/filter-selects/filter-row-context.d.ts +30 -0
- package/dist/filter-selects/filter-row-context.js +3 -0
- package/dist/filter-selects/filter-row.d.ts +13 -0
- package/dist/filter-selects/filter-row.js +118 -0
- package/dist/filter-selects/index.d.ts +22 -0
- package/dist/filter-selects/index.js +20 -0
- package/dist/filter-selects/is-complete-filter.d.ts +2 -0
- package/dist/filter-selects/is-complete-filter.js +5 -0
- package/dist/filter-selects/operator-select.d.ts +14 -0
- package/dist/filter-selects/operator-select.js +25 -0
- package/dist/filter-selects/options.d.ts +9 -0
- package/dist/filter-selects/options.js +100 -0
- package/dist/filter-selects/reset.d.ts +7 -0
- package/dist/filter-selects/reset.js +22 -0
- package/dist/filter-selects/root.d.ts +14 -0
- package/dist/filter-selects/root.js +5 -0
- package/dist/filter-selects/to-filter-item.d.ts +3 -0
- package/dist/filter-selects/to-filter-item.js +7 -0
- package/dist/filter-selects/use-filter-select.d.ts +38 -0
- package/dist/filter-selects/use-filter-select.js +168 -0
- package/dist/filter-selects/value-input.d.ts +12 -0
- package/dist/filter-selects/value-input.js +27 -0
- package/dist/filter-tree/branch.d.ts +1 -1
- package/dist/filter-tree/branch.js +1 -1
- package/dist/filter-tree/hooks/use-filter-tree.js +1 -1
- package/dist/filter-tree/inclusion-checkbox.d.ts +1 -1
- package/dist/filter-tree/inclusion-checkbox.js +1 -1
- package/dist/filter-tree/label.d.ts +1 -1
- package/dist/filter-tree/label.js +1 -1
- package/dist/filter-tree/root.d.ts +1 -1
- package/dist/filter-tree/root.js +1 -1
- package/dist/grid/header-cell.d.ts +1 -1
- package/dist/grid/header-cell.js +1 -2
- package/dist/grid/header.d.ts +1 -1
- package/dist/grid/row-full-width.d.ts +1 -1
- package/dist/grid/row-full-width.js +1 -2
- package/dist/grid/row.d.ts +1 -1
- package/dist/grid/row.js +0 -1
- package/dist/grid/rows-container.d.ts +1 -1
- package/dist/grid-box/item.d.ts +1 -1
- package/dist/grid-box/item.js +1 -2
- package/dist/grid-box/panel.js +1 -1
- package/dist/grid-box/use-aggregation-box-items.js +1 -1
- package/dist/grid-box/use-column-box-items.js +1 -1
- package/dist/grid-box/use-row-group-box-items.js +1 -1
- package/dist/grid.d.ts +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/license/index.d.ts +1 -0
- package/dist/license/index.js +1 -0
- package/dist/license/license.d.ts +3 -0
- package/dist/license/license.js +215 -0
- package/dist/license/md5-hash.d.ts +9 -0
- package/dist/license/md5-hash.js +167 -0
- package/dist/license.js +1 -1
- package/dist/listbox/item.js +1 -1
- package/dist/listbox/panel.js +2 -2
- package/dist/row-data-source-client/filter/compute-filtered-rows.js +1 -1
- package/dist/row-data-source-client/pivots/create-pivot-columns-from-paths.js +1 -1
- package/dist/row-data-source-client/use-client-data-source-paginated.js +3 -2
- package/dist/row-data-source-client/use-client-data-source.js +3 -2
- package/dist/row-data-source-client/use-client-tree-data-source.js +3 -2
- package/dist/row-data-source-server/server-data.d.ts +24 -2
- package/dist/row-data-source-server/server-data.js +173 -30
- package/dist/row-data-source-server/use-server-data-source.d.ts +1 -1
- package/dist/row-data-source-server/use-server-data-source.js +80 -11
- package/dist/sort-manager/hooks/use-sort-manager.js +2 -2
- package/dist/sort-manager/hooks/use-sort-row-item.js +1 -1
- package/dist/sort-manager/sort-add.d.ts +1 -1
- package/dist/sort-manager/sort-add.js +1 -1
- package/dist/sort-manager/sort-apply.d.ts +1 -1
- package/dist/sort-manager/sort-apply.js +2 -2
- package/dist/sort-manager/sort-cancel.d.ts +1 -1
- package/dist/sort-manager/sort-cancel.js +2 -2
- package/dist/sort-manager/sort-clear.d.ts +1 -1
- package/dist/sort-manager/sort-clear.js +1 -1
- package/dist/sort-manager/sort-column-select.d.ts +1 -1
- package/dist/sort-manager/sort-column-select.js +1 -1
- package/dist/sort-manager/sort-direction-select.d.ts +1 -1
- package/dist/sort-manager/sort-direction-select.js +1 -1
- package/dist/sort-manager/sort-remove.d.ts +1 -1
- package/dist/sort-manager/sort-remove.js +1 -1
- package/dist/sort-manager/sort-value-select.d.ts +1 -1
- package/dist/sort-manager/sort-value-select.js +1 -1
- package/dist/state/+types.d.ts +2 -1
- package/dist/state/api/column-field.js +1 -1
- package/dist/state/api/edit-begin.js +1 -1
- package/dist/state/api/focus-cell.js +1 -1
- package/dist/state/api/position-from-element.d.ts +5 -2
- package/dist/state/api/position-from-element.js +3 -3
- package/dist/state/api/row-handle-select.js +1 -1
- package/dist/state/api/use-row-drag.js +3 -2
- package/dist/state/helpers/column-add-row-group.js +1 -1
- package/dist/state/helpers/column-marker.js +1 -1
- package/dist/state/use-lytenyte.js +18 -3
- package/dist/tree-view/branch/branch.d.ts +1 -1
- package/dist/tree-view/branch/branch.js +1 -1
- package/dist/tree-view/branch/use-branch-keys.js +2 -2
- package/dist/tree-view/leaf.js +1 -1
- package/dist/tree-view/panel/make-handle-navigation.js +1 -1
- package/dist/tree-view/panel/make-handle-selection.js +1 -1
- package/dist/tree-view/panel/panel.js +2 -2
- package/dist/tree-view/panel/use-tree-navigation.js +1 -1
- package/dist/tree-view/root.js +1 -1
- package/dist/tree-view/utils/get-focusable-nodes.js +1 -1
- package/dist/tree-view/utils/get-focused-node.js +1 -1
- package/dist/tree-view/utils/get-sibling-branches.js +1 -1
- package/dist/tree-view/virtualized/use-row-start-and-end.d.ts +1 -1
- package/dist/tree-view/virtualized/use-row-start-and-end.js +1 -1
- package/dist/tree-view/virtualized/use-virtualized-tree.js +1 -1
- package/package.json +3 -7
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import "../../../main.css";
|
|
3
|
+
import { useClientRowDataSource } from "../../row-data-source-client/use-client-data-source.js";
|
|
4
|
+
import { useLyteNyte } from "../../state/use-lytenyte.js";
|
|
5
|
+
import { useId } from "react";
|
|
6
|
+
import { Viewport } from "../../grid/viewport.js";
|
|
7
|
+
import { Root } from "../../grid/root.js";
|
|
8
|
+
import { Header } from "../../grid/header.js";
|
|
9
|
+
import { HeaderRow } from "../../grid/header-row.js";
|
|
10
|
+
import { HeaderGroupCell } from "../../grid/header-group-cell.js";
|
|
11
|
+
import { HeaderCell } from "../../grid/header-cell.js";
|
|
12
|
+
import { RowsContainer } from "../../grid/rows-container.js";
|
|
13
|
+
import { RowsBottom, RowsCenter, RowsTop } from "../../grid/rows-sections.js";
|
|
14
|
+
import { RowHandler } from "../test-utils/row-handler.js";
|
|
15
|
+
import { bankDataSmall } from "../test-utils/bank-data-smaller.js";
|
|
16
|
+
import { FilterSelect } from "../../filter-selects/index.js";
|
|
17
|
+
const columns = [
|
|
18
|
+
{ id: "age", type: "number" },
|
|
19
|
+
{ id: "job", type: "date" },
|
|
20
|
+
{ id: "balance", pin: "start" },
|
|
21
|
+
{ id: "education" },
|
|
22
|
+
{ id: "marital" },
|
|
23
|
+
{ id: "default" },
|
|
24
|
+
{ id: "housing" },
|
|
25
|
+
{ id: "loan" },
|
|
26
|
+
{ id: "contact" },
|
|
27
|
+
{ id: "day" },
|
|
28
|
+
{ id: "month" },
|
|
29
|
+
{ id: "duration" },
|
|
30
|
+
{ id: "campaign" },
|
|
31
|
+
{ id: "pdays" },
|
|
32
|
+
{ id: "previous" },
|
|
33
|
+
{ id: "poutcome" },
|
|
34
|
+
{ id: "y" },
|
|
35
|
+
];
|
|
36
|
+
export default function FilterSelection({ data = bankDataSmall }) {
|
|
37
|
+
const ds = useClientRowDataSource({
|
|
38
|
+
data: data,
|
|
39
|
+
});
|
|
40
|
+
const g = useLyteNyte({
|
|
41
|
+
gridId: useId(),
|
|
42
|
+
columns,
|
|
43
|
+
rowDataSource: ds,
|
|
44
|
+
});
|
|
45
|
+
const view = g.view.useValue();
|
|
46
|
+
const rootAge = FilterSelect.useFilterSelect({ grid: g, column: columns[0], maxCount: 3 });
|
|
47
|
+
const rootJob = FilterSelect.useFilterSelect({ grid: g, column: columns[1], maxCount: 3 });
|
|
48
|
+
return (_jsxs("div", { style: { display: "flex" }, children: [_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 20 }, children: [_jsx("div", { children: _jsxs(FilterSelect.Root, { root: rootAge, children: [rootAge.filters.map((c, i) => {
|
|
49
|
+
return (_jsxs(FilterSelect.FilterRow, { filter: c, children: [_jsx(FilterSelect.OperatorSelect, {}), _jsx(FilterSelect.ValueInput, {}), _jsx(FilterSelect.FilterCombinator, {})] }, i));
|
|
50
|
+
}), _jsx(FilterSelect.Apply, {}), _jsx(FilterSelect.Reset, {})] }) }), _jsx("div", { children: _jsxs(FilterSelect.Root, { root: rootJob, children: [rootJob.filters.map((c, i) => {
|
|
51
|
+
return (_jsxs(FilterSelect.FilterRow, { filter: c, children: [_jsx(FilterSelect.OperatorSelect, {}), _jsx(FilterSelect.ValueInput, {}), _jsx(FilterSelect.FilterCombinator, {})] }, i));
|
|
52
|
+
}), _jsx(FilterSelect.Apply, {}), _jsx(FilterSelect.Reset, {})] }) })] }), _jsx("div", { style: { width: "100%", height: "90vh", border: "1px solid black" }, children: _jsx(Root, { grid: g, children: _jsxs(Viewport, { children: [_jsx(Header, { children: view.header.layout.map((row, i) => {
|
|
53
|
+
return (_jsx(HeaderRow, { headerRowIndex: i, children: row.map((c) => {
|
|
54
|
+
if (c.kind === "group") {
|
|
55
|
+
return (_jsx(HeaderGroupCell, { cell: c, style: {
|
|
56
|
+
paddingInline: "16px",
|
|
57
|
+
background: "light-dark(rgb(200,200,200),rgb(57, 39, 39))",
|
|
58
|
+
color: "light-dark(black,white)",
|
|
59
|
+
display: "flex",
|
|
60
|
+
alignItems: "center",
|
|
61
|
+
borderBottom: "1px solid light-dark(gray, #444242)",
|
|
62
|
+
borderRight: "1px solid light-dark(gray, #444242)",
|
|
63
|
+
} }, c.idOccurrence));
|
|
64
|
+
}
|
|
65
|
+
return (_jsx(HeaderCell, { cell: c, style: {
|
|
66
|
+
paddingInline: "16px",
|
|
67
|
+
background: "light-dark(rgb(200,200,200),rgb(57, 39, 39))",
|
|
68
|
+
color: "light-dark(black,white)",
|
|
69
|
+
display: "flex",
|
|
70
|
+
alignItems: "center",
|
|
71
|
+
borderBottom: "1px solid light-dark(gray, #444242)",
|
|
72
|
+
borderRight: "1px solid light-dark(gray, #444242)",
|
|
73
|
+
} }, c.column.id));
|
|
74
|
+
}) }, i));
|
|
75
|
+
}) }), _jsxs(RowsContainer, { children: [_jsx(RowsTop, { children: _jsx(RowHandler, { rows: view.rows.top, withStyles: true, pinned: true }) }), _jsx(RowsCenter, { children: _jsx(RowHandler, { rows: view.rows.center, withStyles: true }) }), _jsx(RowsBottom, { children: _jsx(RowHandler, { rows: view.rows.bottom, withStyles: true, pinned: true }) })] })] }) }) })] }));
|
|
76
|
+
}
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { fastDeepMemo } from "@1771technologies/lytenyte-react-hooks";
|
|
3
2
|
import { Row } from "../../grid/row.js";
|
|
4
3
|
import { Cell } from "../../grid/cell.js";
|
|
5
4
|
import { RowFullWidth } from "../../grid/row-full-width.js";
|
|
6
|
-
export const RowHandler =
|
|
5
|
+
export const RowHandler = (props) => {
|
|
7
6
|
return props.rows.map((row) => {
|
|
8
7
|
if (row.kind === "full-width")
|
|
9
8
|
return _jsx(RowFullWidth, { row: row }, row.id);
|
|
10
9
|
return _jsx(Memo, { row: row, withStyles: props.withStyles, pinned: props.pinned }, row.id);
|
|
11
10
|
});
|
|
12
|
-
}
|
|
11
|
+
};
|
|
13
12
|
function RowFor({ row, withStyles, pinned, }) {
|
|
14
13
|
const styles = withStyles
|
|
15
14
|
? {
|
|
@@ -30,4 +29,4 @@ function RowFor({ row, withStyles, pinned, }) {
|
|
|
30
29
|
return _jsx(Cell, { cell: cell, style: styles }, cell.id);
|
|
31
30
|
}) }));
|
|
32
31
|
}
|
|
33
|
-
const Memo =
|
|
32
|
+
const Memo = RowFor;
|
|
@@ -2,9 +2,9 @@ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { useEffect } from "react";
|
|
3
3
|
import { useGridRoot } from "../context.js";
|
|
4
4
|
import { useEdgeScroll } from "./use-edge-scroll.js";
|
|
5
|
-
import { equal, getClientX, getClientY, getRelativeXPosition, getRelativeYPosition, } from "@1771technologies/lytenyte-
|
|
5
|
+
import { equal, getClientX, getClientY, getRelativeXPosition, getRelativeYPosition, } from "@1771technologies/lytenyte-shared";
|
|
6
6
|
import { getNearestFocusable, getPositionFromFocusable } from "@1771technologies/lytenyte-shared";
|
|
7
|
-
import { isHTMLElement } from "@1771technologies/lytenyte-
|
|
7
|
+
import { isHTMLElement } from "@1771technologies/lytenyte-shared";
|
|
8
8
|
import { updateAdditiveCellSelection } from "./update-additive-cell-selection.js";
|
|
9
9
|
import { deselectRectRange } from "./deselect-rect-range.js";
|
|
10
10
|
import { isWithinSelectionRect } from "./is-within-selection-rect.js";
|
|
@@ -31,6 +31,7 @@ export function CellSelectionDriver() {
|
|
|
31
31
|
let pointerStartY = 0;
|
|
32
32
|
let lastRect = null;
|
|
33
33
|
let animFrame = null;
|
|
34
|
+
const gridId = grid.state.gridId.get();
|
|
34
35
|
const pointerMove = (event) => {
|
|
35
36
|
if (animFrame)
|
|
36
37
|
cancelAnimationFrame(animFrame);
|
|
@@ -41,10 +42,10 @@ export function CellSelectionDriver() {
|
|
|
41
42
|
const target = event.target;
|
|
42
43
|
if (!isHTMLElement(target))
|
|
43
44
|
return;
|
|
44
|
-
const focusable = getNearestFocusable(target);
|
|
45
|
+
const focusable = getNearestFocusable(gridId, target);
|
|
45
46
|
if (!focusable)
|
|
46
47
|
return;
|
|
47
|
-
const position = getPositionFromFocusable(focusable);
|
|
48
|
+
const position = getPositionFromFocusable(focusable, gridId);
|
|
48
49
|
if (position.kind !== "cell" && position.kind !== "full-width")
|
|
49
50
|
return;
|
|
50
51
|
const rowIndex = position.rowIndex;
|
|
@@ -128,10 +129,10 @@ export function CellSelectionDriver() {
|
|
|
128
129
|
const target = event.target;
|
|
129
130
|
if (!isHTMLElement(target))
|
|
130
131
|
return;
|
|
131
|
-
const focusable = getNearestFocusable(target);
|
|
132
|
+
const focusable = getNearestFocusable(gridId, target);
|
|
132
133
|
if (!focusable)
|
|
133
134
|
return;
|
|
134
|
-
const position = getPositionFromFocusable(focusable);
|
|
135
|
+
const position = getPositionFromFocusable(focusable, gridId);
|
|
135
136
|
if (position.kind !== "cell" && position.kind !== "full-width")
|
|
136
137
|
return;
|
|
137
138
|
const rowIndex = position.rowIndex;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { CSSProperties } from "react";
|
|
2
2
|
import type { Column } from "../+types";
|
|
3
|
-
import type { SlotComponent } from "@1771technologies/lytenyte-react-hooks";
|
|
4
3
|
import type { PathBranch } from "@1771technologies/lytenyte-shared";
|
|
4
|
+
import { type SlotComponent } from "@1771technologies/lytenyte-core/yinternal";
|
|
5
5
|
export interface ColumnManagerBranchProps {
|
|
6
6
|
readonly item: PathBranch<Column<any>>;
|
|
7
7
|
readonly label: SlotComponent;
|
|
@@ -2,9 +2,9 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef, useCallback, useMemo } from "react";
|
|
3
3
|
import { TreeBranch } from "../tree-view/branch/branch.js";
|
|
4
4
|
import { ColumnItemContext } from "./context.js";
|
|
5
|
-
import { dragState, DropWrap } from "@1771technologies/lytenyte-dragon";
|
|
6
5
|
import { useGrid } from "../grid-provider/use-grid.js";
|
|
7
6
|
import { useColumnsFromContext } from "./use-columns-from-context.js";
|
|
7
|
+
import { dragState, DropWrap } from "@1771technologies/lytenyte-core/yinternal";
|
|
8
8
|
export const Branch = forwardRef(function Branch({ item, label, labelWrapClassName, labelWrapStyle, ...props }, forwarded) {
|
|
9
9
|
const grid = useGrid();
|
|
10
10
|
const id = grid.state.gridId.useValue();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useSlot } from "@1771technologies/lytenyte-react-hooks";
|
|
3
2
|
import { forwardRef, useMemo } from "react";
|
|
4
3
|
import { useColumnItemContext } from "./context.js";
|
|
4
|
+
import { useSlot } from "@1771technologies/lytenyte-core/yinternal";
|
|
5
5
|
export const Label = forwardRef(function Label({ as, ...props }, forwarded) {
|
|
6
6
|
const { item } = useColumnItemContext();
|
|
7
7
|
const label = useMemo(() => {
|
|
@@ -2,9 +2,9 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { forwardRef, useCallback, useMemo } from "react";
|
|
3
3
|
import { ColumnItemContext } from "./context.js";
|
|
4
4
|
import { TreeLeaf } from "../tree-view/leaf.js";
|
|
5
|
-
import { dragState, DropWrap } from "@1771technologies/lytenyte-dragon";
|
|
6
5
|
import { useGrid } from "../grid-provider/use-grid.js";
|
|
7
6
|
import { useColumnsFromContext } from "./use-columns-from-context.js";
|
|
7
|
+
import { dragState, DropWrap } from "@1771technologies/lytenyte-core/yinternal";
|
|
8
8
|
export const Leaf = forwardRef(function ColumnManagerLeaf({ item, ...props }, forwarded) {
|
|
9
9
|
const context = useMemo(() => {
|
|
10
10
|
return { item: item };
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useDraggable } from "@1771technologies/lytenyte-dragon";
|
|
3
|
-
import { useCombinedRefs, useSlot, } from "@1771technologies/lytenyte-react-hooks";
|
|
4
2
|
import { forwardRef, useMemo } from "react";
|
|
5
3
|
import { useColumnItemContext } from "./context.js";
|
|
6
4
|
import { useColumnsFromContext } from "./use-columns-from-context.js";
|
|
7
5
|
import { useGrid } from "../grid-provider/use-grid.js";
|
|
6
|
+
import { useCombinedRefs, useDraggable, useSlot, } from "@1771technologies/lytenyte-core/yinternal";
|
|
8
7
|
export const MoveHandle = forwardRef(function MoveHandle({ as, ...props }, forwarded) {
|
|
9
8
|
const item = useColumnItemContext().item;
|
|
10
9
|
const grid = useGrid();
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { useSlot } from "@1771technologies/lytenyte-react-hooks";
|
|
3
2
|
import { useColumnItemContext } from "./context.js";
|
|
4
3
|
import { forwardRef, useCallback, useMemo } from "react";
|
|
5
4
|
import { useGrid } from "../grid-provider/use-grid.js";
|
|
6
5
|
import { useColumnsFromContext } from "./use-columns-from-context.js";
|
|
6
|
+
import { useSlot } from "@1771technologies/lytenyte-core/yinternal";
|
|
7
7
|
export const VisibilityCheckbox = forwardRef(function VisibilityCheckbox({ as, ...props }, forwarded) {
|
|
8
8
|
const { item } = useColumnItemContext();
|
|
9
9
|
const grid = useGrid();
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type SlotComponent } from "@1771technologies/lytenyte-core/yinternal";
|
|
2
|
+
export interface ApplyProps {
|
|
3
|
+
readonly as?: SlotComponent<{
|
|
4
|
+
onApply: () => void;
|
|
5
|
+
}>;
|
|
6
|
+
}
|
|
7
|
+
export declare const Apply: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement> & ApplyProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useSlot } from "@1771technologies/lytenyte-core/yinternal";
|
|
3
|
+
import { forwardRef } from "react";
|
|
4
|
+
import { useFilterSelectRoot } from "./context.js";
|
|
5
|
+
function ApplyImpl({ as, ...props }, ref) {
|
|
6
|
+
const ctx = useFilterSelectRoot();
|
|
7
|
+
const slot = useSlot({
|
|
8
|
+
props: [
|
|
9
|
+
{
|
|
10
|
+
onClick: ctx.apply,
|
|
11
|
+
},
|
|
12
|
+
props,
|
|
13
|
+
],
|
|
14
|
+
ref: ref,
|
|
15
|
+
slot: as ?? _jsx("button", { children: "Apply" }),
|
|
16
|
+
state: {
|
|
17
|
+
onReset: ctx.apply,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
return slot;
|
|
21
|
+
}
|
|
22
|
+
export const Apply = forwardRef(ApplyImpl);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type SlotComponent } from "@1771technologies/lytenyte-core/yinternal";
|
|
2
|
+
export interface ClearProps {
|
|
3
|
+
readonly as?: SlotComponent<{
|
|
4
|
+
onClear: () => void;
|
|
5
|
+
}>;
|
|
6
|
+
}
|
|
7
|
+
export declare const Clear: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement> & ClearProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useSlot } from "@1771technologies/lytenyte-core/yinternal";
|
|
3
|
+
import { forwardRef } from "react";
|
|
4
|
+
import { useFilterSelectRoot } from "./context.js";
|
|
5
|
+
function ClearImpl({ as, ...props }, ref) {
|
|
6
|
+
const ctx = useFilterSelectRoot();
|
|
7
|
+
const slot = useSlot({
|
|
8
|
+
props: [
|
|
9
|
+
{
|
|
10
|
+
onClick: ctx.clear,
|
|
11
|
+
},
|
|
12
|
+
props,
|
|
13
|
+
],
|
|
14
|
+
ref: ref,
|
|
15
|
+
slot: as ?? _jsx("button", { children: "Clear" }),
|
|
16
|
+
state: {
|
|
17
|
+
onReset: ctx.clear,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
return slot;
|
|
21
|
+
}
|
|
22
|
+
export const Clear = forwardRef(ClearImpl);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type Dispatch, type SetStateAction } from "react";
|
|
2
|
+
import type { FilterSelectFlat } from "./use-filter-select";
|
|
3
|
+
export interface FilterSelectRoot {
|
|
4
|
+
readonly defaultFilter: FilterSelectFlat;
|
|
5
|
+
readonly filters: FilterSelectFlat[];
|
|
6
|
+
readonly setFilters: Dispatch<SetStateAction<FilterSelectFlat[]>>;
|
|
7
|
+
readonly maxCount: number;
|
|
8
|
+
readonly apply: () => void;
|
|
9
|
+
readonly reset: () => void;
|
|
10
|
+
readonly clear: () => void;
|
|
11
|
+
}
|
|
12
|
+
export declare const context: import("react").Context<FilterSelectRoot>;
|
|
13
|
+
export declare const useFilterSelectRoot: () => FilterSelectRoot;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type SlotComponent } from "@1771technologies/lytenyte-core/yinternal";
|
|
2
|
+
export interface FilterCombinatorSlotProps {
|
|
3
|
+
readonly value: "AND" | "OR" | null;
|
|
4
|
+
readonly onChange: (v: "AND" | "OR" | null) => void;
|
|
5
|
+
readonly shouldShow: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface FilterCombinatorProps {
|
|
8
|
+
readonly as?: SlotComponent<FilterCombinatorSlotProps>;
|
|
9
|
+
}
|
|
10
|
+
export declare const FilterCombinator: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & FilterCombinatorProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useSlot } from "@1771technologies/lytenyte-core/yinternal";
|
|
3
|
+
import { forwardRef } from "react";
|
|
4
|
+
import { useFilterRow } from "./filter-row-context.js";
|
|
5
|
+
function FilterCombinatorImpl({ as, ...props }, ref) {
|
|
6
|
+
const ctx = useFilterRow();
|
|
7
|
+
const slot = useSlot({
|
|
8
|
+
props: [props],
|
|
9
|
+
ref: ref,
|
|
10
|
+
slot: as ?? (_jsx(_Fragment, { children: ctx.showExtender && (_jsxs("div", { ...props, ref: ref, children: [_jsxs("label", { children: ["AND", _jsx("input", { type: "radio", checked: ctx.extender === "AND", value: "AND", onChange: (e) => ctx.onExtenderChange(e.target.value) })] }), _jsxs("label", { children: ["OR", _jsx("input", { type: "radio", checked: ctx.extender === "OR", value: "OR", onChange: (e) => ctx.onExtenderChange(e.target.value) })] })] })) })),
|
|
11
|
+
state: {
|
|
12
|
+
onChange: ctx.onExtenderChange,
|
|
13
|
+
shouldShow: ctx.showExtender,
|
|
14
|
+
value: ctx.extender,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
return slot;
|
|
18
|
+
}
|
|
19
|
+
export const FilterCombinator = forwardRef(FilterCombinatorImpl);
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { SelectOption } from "./operator-select";
|
|
2
|
+
import type { FilterSelectFlat } from "./use-filter-select";
|
|
3
|
+
export declare const context: import("react").Context<{
|
|
4
|
+
readonly filter: FilterSelectFlat;
|
|
5
|
+
readonly extender: "AND" | "OR" | null;
|
|
6
|
+
readonly showExtender: boolean;
|
|
7
|
+
readonly onExtenderChange: (v: "AND" | "OR" | null) => void;
|
|
8
|
+
readonly operatorOptions: SelectOption[];
|
|
9
|
+
readonly operatorValue: SelectOption | null;
|
|
10
|
+
readonly operatorOnChange: (v: SelectOption) => void;
|
|
11
|
+
readonly value: string | number | null | undefined;
|
|
12
|
+
readonly valueDisabled: boolean;
|
|
13
|
+
readonly onValueChange: (v: string | number | null) => void;
|
|
14
|
+
readonly isNumberInput: boolean;
|
|
15
|
+
readonly filterHasNoValue: boolean;
|
|
16
|
+
}>;
|
|
17
|
+
export declare const useFilterRow: () => {
|
|
18
|
+
readonly filter: FilterSelectFlat;
|
|
19
|
+
readonly extender: "AND" | "OR" | null;
|
|
20
|
+
readonly showExtender: boolean;
|
|
21
|
+
readonly onExtenderChange: (v: "AND" | "OR" | null) => void;
|
|
22
|
+
readonly operatorOptions: SelectOption[];
|
|
23
|
+
readonly operatorValue: SelectOption | null;
|
|
24
|
+
readonly operatorOnChange: (v: SelectOption) => void;
|
|
25
|
+
readonly value: string | number | null | undefined;
|
|
26
|
+
readonly valueDisabled: boolean;
|
|
27
|
+
readonly onValueChange: (v: string | number | null) => void;
|
|
28
|
+
readonly isNumberInput: boolean;
|
|
29
|
+
readonly filterHasNoValue: boolean;
|
|
30
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { FilterSelectFlat } from "./use-filter-select";
|
|
2
|
+
import type { SelectOption } from "./operator-select";
|
|
3
|
+
export interface SelectSlotProps {
|
|
4
|
+
readonly options: SelectOption[];
|
|
5
|
+
readonly value: SelectOption | null;
|
|
6
|
+
readonly onChange: (v: SelectOption) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface FilterRowProps {
|
|
9
|
+
readonly filter: FilterSelectFlat;
|
|
10
|
+
}
|
|
11
|
+
export declare const FilterRow: import("react").ForwardRefExoticComponent<FilterRowProps & {
|
|
12
|
+
children?: import("react").ReactNode | undefined;
|
|
13
|
+
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef, useCallback, useMemo } from "react";
|
|
3
|
+
import { useFilterSelectRoot } from "./context.js";
|
|
4
|
+
import { context } from "./filter-row-context.js";
|
|
5
|
+
import { dateOptions, filterNeedsValue, numberOptions, operatorsThatAreNumbers, operatorToOption, stringOptions, } from "./options.js";
|
|
6
|
+
function FilterRowImpl({ filter, children }, forwarded) {
|
|
7
|
+
const ctx = useFilterSelectRoot();
|
|
8
|
+
const index = ctx.filters.indexOf(filter);
|
|
9
|
+
const isLast = ctx.filters.at(-1) === filter;
|
|
10
|
+
if (index === -1)
|
|
11
|
+
throw new Error("Filter should be defined among the root filters.");
|
|
12
|
+
const onOperatorChange = useCallback((opt) => {
|
|
13
|
+
ctx.setFilters((prev) => {
|
|
14
|
+
const next = [...prev];
|
|
15
|
+
const filter = next[index];
|
|
16
|
+
if (filter.kind === "function")
|
|
17
|
+
return prev;
|
|
18
|
+
next[index] = {
|
|
19
|
+
...filter,
|
|
20
|
+
operator: opt.value,
|
|
21
|
+
};
|
|
22
|
+
return next;
|
|
23
|
+
});
|
|
24
|
+
}, [ctx, index]);
|
|
25
|
+
const options = useMemo(() => {
|
|
26
|
+
if (filter.kind === "function")
|
|
27
|
+
return [];
|
|
28
|
+
if (filter.kind === "number")
|
|
29
|
+
return numberOptions;
|
|
30
|
+
if (filter.kind === "date")
|
|
31
|
+
return dateOptions;
|
|
32
|
+
return stringOptions;
|
|
33
|
+
}, [filter.kind]);
|
|
34
|
+
const operatorValue = useMemo(() => {
|
|
35
|
+
if (filter.kind === "function")
|
|
36
|
+
return { value: "-", label: "-" };
|
|
37
|
+
return operatorToOption[filter.operator ?? "equals"];
|
|
38
|
+
}, [filter]);
|
|
39
|
+
const value = useMemo(() => {
|
|
40
|
+
if (filter.kind === "function")
|
|
41
|
+
return null;
|
|
42
|
+
return filter.value;
|
|
43
|
+
}, [filter]);
|
|
44
|
+
const onValueChange = useCallback((v) => {
|
|
45
|
+
if (filter.kind === "function")
|
|
46
|
+
return;
|
|
47
|
+
ctx.setFilters((prev) => {
|
|
48
|
+
const next = [...prev];
|
|
49
|
+
const filter = next[index];
|
|
50
|
+
if (filter.kind === "function")
|
|
51
|
+
return prev;
|
|
52
|
+
if (filter.kind === "number") {
|
|
53
|
+
next[index] = {
|
|
54
|
+
...filter,
|
|
55
|
+
value: filter.operator === "not_equals" || filter.operator === "equals"
|
|
56
|
+
? typeof v === "number"
|
|
57
|
+
? v
|
|
58
|
+
: !v
|
|
59
|
+
? null
|
|
60
|
+
: Number.parseFloat(v)
|
|
61
|
+
: typeof v === "number"
|
|
62
|
+
? v
|
|
63
|
+
: Number.parseFloat(v ?? ""),
|
|
64
|
+
};
|
|
65
|
+
return next;
|
|
66
|
+
}
|
|
67
|
+
const isNumber = operatorsThatAreNumbers.has(filter.operator);
|
|
68
|
+
next[index] = {
|
|
69
|
+
...filter,
|
|
70
|
+
value: isNumber ? (typeof v === "number" ? v : Number.parseFloat(v)) : v,
|
|
71
|
+
};
|
|
72
|
+
return next;
|
|
73
|
+
});
|
|
74
|
+
}, [ctx, filter.kind, index]);
|
|
75
|
+
const extenderValue = useMemo(() => {
|
|
76
|
+
return filter.kind == "function" ? null : (filter.nextExtender ?? "AND");
|
|
77
|
+
}, [filter]);
|
|
78
|
+
const onExtenderChange = useCallback((v) => {
|
|
79
|
+
ctx.setFilters((prev) => {
|
|
80
|
+
const next = [...prev];
|
|
81
|
+
const filter = next[index];
|
|
82
|
+
if (filter.kind === "function")
|
|
83
|
+
return prev;
|
|
84
|
+
next[index] = {
|
|
85
|
+
...filter,
|
|
86
|
+
nextExtender: v,
|
|
87
|
+
};
|
|
88
|
+
return next;
|
|
89
|
+
});
|
|
90
|
+
}, [ctx, index]);
|
|
91
|
+
const showExtender = useMemo(() => {
|
|
92
|
+
if (filter.kind === "function")
|
|
93
|
+
return false;
|
|
94
|
+
// If the filter isn't the last one then show the extender
|
|
95
|
+
if (!isLast)
|
|
96
|
+
return true;
|
|
97
|
+
if (filter.operator != null && filter.value != null && index + 1 < ctx.maxCount)
|
|
98
|
+
return true;
|
|
99
|
+
return false;
|
|
100
|
+
}, [ctx.maxCount, filter, index, isLast]);
|
|
101
|
+
return (_jsx(context.Provider, { value: {
|
|
102
|
+
filter,
|
|
103
|
+
extender: extenderValue,
|
|
104
|
+
onExtenderChange,
|
|
105
|
+
showExtender: showExtender,
|
|
106
|
+
operatorOnChange: onOperatorChange,
|
|
107
|
+
operatorOptions: options,
|
|
108
|
+
operatorValue: operatorValue,
|
|
109
|
+
value,
|
|
110
|
+
onValueChange,
|
|
111
|
+
isNumberInput: filter.kind === "function"
|
|
112
|
+
? false
|
|
113
|
+
: filter.kind === "number" || operatorsThatAreNumbers.has(filter.operator),
|
|
114
|
+
filterHasNoValue: filter.kind === "function" || filterNeedsValue.has(filter.operator),
|
|
115
|
+
valueDisabled: filter.kind === "function" || !filter.operator,
|
|
116
|
+
}, children: _jsx("div", { ref: forwarded, children: children }) }));
|
|
117
|
+
}
|
|
118
|
+
export const FilterRow = forwardRef(FilterRowImpl);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Root } from "./root.js";
|
|
2
|
+
export declare const FilterSelect: {
|
|
3
|
+
useFilterSelect: <T>({ grid, column, maxCount }: import("./use-filter-select.js").UseFilterSelectParams<T>) => {
|
|
4
|
+
reset: () => void;
|
|
5
|
+
apply: () => void;
|
|
6
|
+
clear: () => void;
|
|
7
|
+
defaultFilter: import("./use-filter-select.js").FilterSelectFlat;
|
|
8
|
+
filters: import("./use-filter-select.js").FilterSelectFlat[];
|
|
9
|
+
setFilters: (v: import("./use-filter-select.js").FilterSelectFlat[] | ((v: import("./use-filter-select.js").FilterSelectFlat[]) => import("./use-filter-select.js").FilterSelectFlat[])) => void;
|
|
10
|
+
maxCount: number;
|
|
11
|
+
};
|
|
12
|
+
Root: typeof Root;
|
|
13
|
+
FilterRow: import("react").ForwardRefExoticComponent<import("./filter-row.js").FilterRowProps & {
|
|
14
|
+
children?: import("react").ReactNode | undefined;
|
|
15
|
+
} & import("react").RefAttributes<HTMLDivElement>>;
|
|
16
|
+
OperatorSelect: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSelectElement> & import("react").SelectHTMLAttributes<HTMLSelectElement> & import("./operator-select.js").OperatorSelectProps, "ref"> & import("react").RefAttributes<HTMLSelectElement>>;
|
|
17
|
+
ValueInput: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLInputElement> & import("react").InputHTMLAttributes<HTMLInputElement> & import("./value-input.js").ValueInputProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
|
|
18
|
+
FilterCombinator: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & import("./filter-combinator.js").FilterCombinatorProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
19
|
+
Apply: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement> & import("./apply.js").ApplyProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
20
|
+
Reset: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement> & import("./reset.js").ResetProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
21
|
+
Clear: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement> & import("./clear.js").ClearProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
|
|
22
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Apply } from "./apply.js";
|
|
2
|
+
import { Clear } from "./clear.js";
|
|
3
|
+
import { FilterCombinator } from "./filter-combinator.js";
|
|
4
|
+
import { FilterRow } from "./filter-row.js";
|
|
5
|
+
import { OperatorSelect } from "./operator-select.js";
|
|
6
|
+
import { Reset } from "./reset.js";
|
|
7
|
+
import { Root } from "./root.js";
|
|
8
|
+
import { useFilterSelect } from "./use-filter-select.js";
|
|
9
|
+
import { ValueInput } from "./value-input.js";
|
|
10
|
+
export const FilterSelect = {
|
|
11
|
+
useFilterSelect,
|
|
12
|
+
Root,
|
|
13
|
+
FilterRow,
|
|
14
|
+
OperatorSelect,
|
|
15
|
+
ValueInput,
|
|
16
|
+
FilterCombinator,
|
|
17
|
+
Apply,
|
|
18
|
+
Reset,
|
|
19
|
+
Clear,
|
|
20
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type SlotComponent } from "@1771technologies/lytenyte-core/yinternal";
|
|
2
|
+
export type SelectOption = {
|
|
3
|
+
label: string;
|
|
4
|
+
value: string;
|
|
5
|
+
};
|
|
6
|
+
export interface OperatorSelectSlotProps {
|
|
7
|
+
readonly options: SelectOption[];
|
|
8
|
+
readonly value: SelectOption | null;
|
|
9
|
+
readonly onChange: (v: SelectOption) => void;
|
|
10
|
+
}
|
|
11
|
+
export interface OperatorSelectProps {
|
|
12
|
+
readonly as?: SlotComponent<OperatorSelectSlotProps>;
|
|
13
|
+
}
|
|
14
|
+
export declare const OperatorSelect: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSelectElement> & import("react").SelectHTMLAttributes<HTMLSelectElement> & OperatorSelectProps, "ref"> & import("react").RefAttributes<HTMLSelectElement>>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useSlot } from "@1771technologies/lytenyte-core/yinternal";
|
|
3
|
+
import { forwardRef } from "react";
|
|
4
|
+
import { useFilterRow } from "./filter-row-context.js";
|
|
5
|
+
function OperatorSelectImpl({ as, ...props }, ref) {
|
|
6
|
+
const ctx = useFilterRow();
|
|
7
|
+
const slot = useSlot({
|
|
8
|
+
props: [props],
|
|
9
|
+
state: {
|
|
10
|
+
options: ctx.operatorOptions,
|
|
11
|
+
value: ctx.operatorValue,
|
|
12
|
+
onChange: ctx.operatorOnChange,
|
|
13
|
+
},
|
|
14
|
+
ref: ref,
|
|
15
|
+
slot: as ?? (_jsx("select", { value: ctx.operatorValue?.value ?? "", onChange: (c) => {
|
|
16
|
+
const val = c.target.value;
|
|
17
|
+
const opt = ctx.operatorOptions.find((c) => c.value === val);
|
|
18
|
+
ctx.operatorOnChange(opt);
|
|
19
|
+
}, children: ctx.operatorOptions.map((c) => {
|
|
20
|
+
return (_jsx("option", { value: c.value, children: c.label }, c.value));
|
|
21
|
+
}) })),
|
|
22
|
+
});
|
|
23
|
+
return slot;
|
|
24
|
+
}
|
|
25
|
+
export const OperatorSelect = forwardRef(OperatorSelectImpl);
|