@1771technologies/lytenyte-pro 1.0.15 → 1.0.16

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.
Files changed (129) hide show
  1. package/dist/__play__/filter-select/filter-select.play.d.ts +4 -0
  2. package/dist/__play__/filter-select/filter-select.play.js +76 -0
  3. package/dist/__play__/test-utils/row-handler.js +3 -4
  4. package/dist/cell-selection/bound-selection-rect.js +1 -1
  5. package/dist/cell-selection/cell-selection-driver.js +7 -6
  6. package/dist/column-manager/branch.d.ts +1 -1
  7. package/dist/column-manager/branch.js +1 -1
  8. package/dist/column-manager/label.d.ts +1 -1
  9. package/dist/column-manager/label.js +1 -1
  10. package/dist/column-manager/leaf.js +1 -1
  11. package/dist/column-manager/move-handle.d.ts +1 -1
  12. package/dist/column-manager/move-handle.js +1 -2
  13. package/dist/column-manager/visibility-checkbox.d.ts +1 -1
  14. package/dist/column-manager/visibility-checkbox.js +1 -1
  15. package/dist/filter-selects/apply.d.ts +7 -0
  16. package/dist/filter-selects/apply.js +22 -0
  17. package/dist/filter-selects/context.d.ts +12 -0
  18. package/dist/filter-selects/context.js +3 -0
  19. package/dist/filter-selects/filter-combinator.d.ts +10 -0
  20. package/dist/filter-selects/filter-combinator.js +19 -0
  21. package/dist/filter-selects/filter-row-context.d.ts +30 -0
  22. package/dist/filter-selects/filter-row-context.js +3 -0
  23. package/dist/filter-selects/filter-row.d.ts +13 -0
  24. package/dist/filter-selects/filter-row.js +118 -0
  25. package/dist/filter-selects/index.d.ts +20 -0
  26. package/dist/filter-selects/index.js +18 -0
  27. package/dist/filter-selects/is-complete-filter.d.ts +2 -0
  28. package/dist/filter-selects/is-complete-filter.js +5 -0
  29. package/dist/filter-selects/operator-select.d.ts +14 -0
  30. package/dist/filter-selects/operator-select.js +25 -0
  31. package/dist/filter-selects/options.d.ts +9 -0
  32. package/dist/filter-selects/options.js +100 -0
  33. package/dist/filter-selects/reset.d.ts +7 -0
  34. package/dist/filter-selects/reset.js +22 -0
  35. package/dist/filter-selects/root.d.ts +13 -0
  36. package/dist/filter-selects/root.js +5 -0
  37. package/dist/filter-selects/to-filter-item.d.ts +3 -0
  38. package/dist/filter-selects/to-filter-item.js +7 -0
  39. package/dist/filter-selects/use-filter-select.d.ts +37 -0
  40. package/dist/filter-selects/use-filter-select.js +158 -0
  41. package/dist/filter-selects/value-input.d.ts +12 -0
  42. package/dist/filter-selects/value-input.js +27 -0
  43. package/dist/filter-tree/branch.d.ts +1 -1
  44. package/dist/filter-tree/branch.js +1 -1
  45. package/dist/filter-tree/hooks/use-filter-tree.js +1 -1
  46. package/dist/filter-tree/inclusion-checkbox.d.ts +1 -1
  47. package/dist/filter-tree/inclusion-checkbox.js +1 -1
  48. package/dist/filter-tree/label.d.ts +1 -1
  49. package/dist/filter-tree/label.js +1 -1
  50. package/dist/filter-tree/root.d.ts +1 -1
  51. package/dist/filter-tree/root.js +1 -1
  52. package/dist/grid/header-cell.d.ts +1 -1
  53. package/dist/grid/header-cell.js +1 -2
  54. package/dist/grid/header.d.ts +1 -1
  55. package/dist/grid/row-full-width.d.ts +1 -1
  56. package/dist/grid/row-full-width.js +1 -2
  57. package/dist/grid/row.d.ts +1 -1
  58. package/dist/grid/row.js +0 -1
  59. package/dist/grid/rows-container.d.ts +1 -1
  60. package/dist/grid-box/item.d.ts +1 -1
  61. package/dist/grid-box/item.js +1 -2
  62. package/dist/grid-box/panel.js +1 -1
  63. package/dist/grid-box/use-aggregation-box-items.js +1 -1
  64. package/dist/grid-box/use-column-box-items.js +1 -1
  65. package/dist/grid-box/use-row-group-box-items.js +1 -1
  66. package/dist/grid.d.ts +2 -2
  67. package/dist/index.d.ts +2 -1
  68. package/dist/index.js +2 -1
  69. package/dist/license/index.d.ts +1 -0
  70. package/dist/license/index.js +1 -0
  71. package/dist/license/license.d.ts +3 -0
  72. package/dist/license/license.js +215 -0
  73. package/dist/license/md5-hash.d.ts +9 -0
  74. package/dist/license/md5-hash.js +167 -0
  75. package/dist/license.js +1 -1
  76. package/dist/listbox/item.js +1 -1
  77. package/dist/listbox/panel.js +2 -2
  78. package/dist/row-data-source-client/filter/compute-filtered-rows.js +1 -1
  79. package/dist/row-data-source-client/pivots/create-pivot-columns-from-paths.js +1 -1
  80. package/dist/row-data-source-client/use-client-data-source-paginated.js +3 -2
  81. package/dist/row-data-source-client/use-client-data-source.js +3 -2
  82. package/dist/row-data-source-client/use-client-tree-data-source.js +3 -2
  83. package/dist/row-data-source-server/server-data.js +1 -1
  84. package/dist/row-data-source-server/use-server-data-source.js +2 -2
  85. package/dist/sort-manager/hooks/use-sort-manager.js +2 -2
  86. package/dist/sort-manager/hooks/use-sort-row-item.js +1 -1
  87. package/dist/sort-manager/sort-add.d.ts +1 -1
  88. package/dist/sort-manager/sort-add.js +1 -1
  89. package/dist/sort-manager/sort-apply.d.ts +1 -1
  90. package/dist/sort-manager/sort-apply.js +2 -2
  91. package/dist/sort-manager/sort-cancel.d.ts +1 -1
  92. package/dist/sort-manager/sort-cancel.js +2 -2
  93. package/dist/sort-manager/sort-clear.d.ts +1 -1
  94. package/dist/sort-manager/sort-clear.js +1 -1
  95. package/dist/sort-manager/sort-column-select.d.ts +1 -1
  96. package/dist/sort-manager/sort-column-select.js +1 -1
  97. package/dist/sort-manager/sort-direction-select.d.ts +1 -1
  98. package/dist/sort-manager/sort-direction-select.js +1 -1
  99. package/dist/sort-manager/sort-remove.d.ts +1 -1
  100. package/dist/sort-manager/sort-remove.js +1 -1
  101. package/dist/sort-manager/sort-value-select.d.ts +1 -1
  102. package/dist/sort-manager/sort-value-select.js +1 -1
  103. package/dist/state/+types.d.ts +2 -1
  104. package/dist/state/api/column-field.js +1 -1
  105. package/dist/state/api/edit-begin.js +1 -1
  106. package/dist/state/api/focus-cell.js +1 -1
  107. package/dist/state/api/position-from-element.d.ts +5 -2
  108. package/dist/state/api/position-from-element.js +3 -3
  109. package/dist/state/api/row-handle-select.js +1 -1
  110. package/dist/state/api/use-row-drag.js +3 -2
  111. package/dist/state/helpers/column-add-row-group.js +1 -1
  112. package/dist/state/helpers/column-marker.js +1 -1
  113. package/dist/state/use-lytenyte.js +18 -3
  114. package/dist/tree-view/branch/branch.d.ts +1 -1
  115. package/dist/tree-view/branch/branch.js +1 -1
  116. package/dist/tree-view/branch/use-branch-keys.js +2 -2
  117. package/dist/tree-view/leaf.js +1 -1
  118. package/dist/tree-view/panel/make-handle-navigation.js +1 -1
  119. package/dist/tree-view/panel/make-handle-selection.js +1 -1
  120. package/dist/tree-view/panel/panel.js +2 -2
  121. package/dist/tree-view/panel/use-tree-navigation.js +1 -1
  122. package/dist/tree-view/root.js +1 -1
  123. package/dist/tree-view/utils/get-focusable-nodes.js +1 -1
  124. package/dist/tree-view/utils/get-focused-node.js +1 -1
  125. package/dist/tree-view/utils/get-sibling-branches.js +1 -1
  126. package/dist/tree-view/virtualized/use-row-start-and-end.d.ts +1 -1
  127. package/dist/tree-view/virtualized/use-row-start-and-end.js +1 -1
  128. package/dist/tree-view/virtualized/use-virtualized-tree.js +1 -1
  129. package/package.json +3 -7
@@ -0,0 +1,4 @@
1
+ import "../../../main.css";
2
+ export default function FilterSelection({ data }: {
3
+ data?: any[];
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -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 = fastDeepMemo((props) => {
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 = fastDeepMemo(RowFor);
32
+ const Memo = RowFor;
@@ -1,4 +1,4 @@
1
- import { clamp } from "@1771technologies/lytenyte-js-utils";
1
+ import { clamp } from "@1771technologies/lytenyte-shared";
2
2
  export function boundSelectionRect(grid, rect) {
3
3
  const rowCount = grid.state.rowDataStore.rowCount.get();
4
4
  const maxRow = rowCount;
@@ -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-js-utils";
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-dom-utils";
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,4 +1,4 @@
1
- import { type SlotComponent } from "@1771technologies/lytenyte-react-hooks";
1
+ import { type SlotComponent } from "@1771technologies/lytenyte-core/yinternal";
2
2
  export interface LabelProps {
3
3
  readonly as?: SlotComponent;
4
4
  }
@@ -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,4 +1,4 @@
1
- import { type SlotComponent } from "@1771technologies/lytenyte-react-hooks";
1
+ import { type SlotComponent } from "@1771technologies/lytenyte-core/yinternal";
2
2
  export interface MoveHandleProps {
3
3
  readonly as?: SlotComponent;
4
4
  }
@@ -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,4 +1,4 @@
1
- import { type SlotComponent } from "@1771technologies/lytenyte-react-hooks";
1
+ import { type SlotComponent } from "@1771technologies/lytenyte-core/yinternal";
2
2
  export interface VisibilityCheckbox {
3
3
  readonly as?: SlotComponent<{
4
4
  visible: boolean;
@@ -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,12 @@
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
+ }
11
+ export declare const context: import("react").Context<FilterSelectRoot>;
12
+ export declare const useFilterSelectRoot: () => FilterSelectRoot;
@@ -0,0 +1,3 @@
1
+ import { createContext, useContext } from "react";
2
+ export const context = createContext({});
3
+ export const useFilterSelectRoot = () => useContext(context);
@@ -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,3 @@
1
+ import { createContext, useContext } from "react";
2
+ export const context = createContext({});
3
+ export const useFilterRow = () => useContext(context);
@@ -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,20 @@
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
+ defaultFilter: import("./use-filter-select.js").FilterSelectFlat;
7
+ filters: import("./use-filter-select.js").FilterSelectFlat[];
8
+ setFilters: (v: import("./use-filter-select.js").FilterSelectFlat[] | ((v: import("./use-filter-select.js").FilterSelectFlat[]) => import("./use-filter-select.js").FilterSelectFlat[])) => void;
9
+ maxCount: number;
10
+ };
11
+ Root: typeof Root;
12
+ FilterRow: import("react").ForwardRefExoticComponent<import("./filter-row.js").FilterRowProps & {
13
+ children?: import("react").ReactNode | undefined;
14
+ } & import("react").RefAttributes<HTMLDivElement>>;
15
+ OperatorSelect: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLSelectElement> & import("react").SelectHTMLAttributes<HTMLSelectElement> & import("./operator-select.js").OperatorSelectProps, "ref"> & import("react").RefAttributes<HTMLSelectElement>>;
16
+ ValueInput: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLInputElement> & import("react").InputHTMLAttributes<HTMLInputElement> & import("./value-input.js").ValueInputProps, "ref"> & import("react").RefAttributes<HTMLInputElement>>;
17
+ FilterCombinator: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLDivElement> & import("react").HTMLAttributes<HTMLDivElement> & import("./filter-combinator.js").FilterCombinatorProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
18
+ Apply: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement> & import("./apply.js").ApplyProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
19
+ Reset: import("react").ForwardRefExoticComponent<Omit<import("react").ClassAttributes<HTMLButtonElement> & import("react").ButtonHTMLAttributes<HTMLButtonElement> & import("./reset.js").ResetProps, "ref"> & import("react").RefAttributes<HTMLButtonElement>>;
20
+ };
@@ -0,0 +1,18 @@
1
+ import { Apply } from "./apply.js";
2
+ import { FilterCombinator } from "./filter-combinator.js";
3
+ import { FilterRow } from "./filter-row.js";
4
+ import { OperatorSelect } from "./operator-select.js";
5
+ import { Reset } from "./reset.js";
6
+ import { Root } from "./root.js";
7
+ import { useFilterSelect } from "./use-filter-select.js";
8
+ import { ValueInput } from "./value-input.js";
9
+ export const FilterSelect = {
10
+ useFilterSelect,
11
+ Root,
12
+ FilterRow,
13
+ OperatorSelect,
14
+ ValueInput,
15
+ FilterCombinator,
16
+ Apply,
17
+ Reset,
18
+ };
@@ -0,0 +1,2 @@
1
+ import type { FilterSelectFlat } from "./use-filter-select";
2
+ export declare function isCompleteFilter(c: FilterSelectFlat): boolean;
@@ -0,0 +1,5 @@
1
+ export function isCompleteFilter(c) {
2
+ if (c.kind === "function")
3
+ return true;
4
+ return c.operator != null && c.value !== undefined;
5
+ }
@@ -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);
@@ -0,0 +1,9 @@
1
+ import type { SelectOption } from "./operator-select";
2
+ export declare const numberOptions: SelectOption[];
3
+ export declare const stringOptions: SelectOption[];
4
+ export declare const dateOptions: SelectOption[];
5
+ export declare const operatorToOption: {
6
+ [k: string]: SelectOption;
7
+ };
8
+ export declare const operatorsThatAreNumbers: Set<string>;
9
+ export declare const filterNeedsValue: Set<string>;