@parqui/react 1.2.0 → 1.2.2

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/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Business Source License 1.1
2
+
3
+ SPDX short identifier: BUSL-1.1
4
+
5
+ Copyright (c) 2026 Parqui
6
+
7
+ Use of this package is governed by the Business Source License 1.1.
8
+ The licensor for this package is Parqui.
9
+
10
+ Additional Use Grant:
11
+ - Personal, educational, and open-source usage is permitted at no cost.
12
+ - Commercial usage requires a paid Parqui commercial license.
13
+
14
+ Change Date: 2030-01-01
15
+ Change License: Apache-2.0
16
+
17
+ For the full legal text of Business Source License 1.1, see:
18
+ https://mariadb.com/bsl11/
package/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # @parqui/react
2
+
3
+ [![npm version](https://img.shields.io/npm/v/%40parqui%2Freact)](https://www.npmjs.com/package/@parqui/react)
4
+ [![npm downloads](https://img.shields.io/npm/dm/%40parqui%2Freact)](https://www.npmjs.com/package/@parqui/react)
5
+
6
+ High-performance React Parquet file viewer component for Apache Parquet datasets. Includes virtual scrolling data grid, filtering, sorting, grouping, search, and column controls.
7
+
8
+ ## Why `@parqui/react`
9
+
10
+ - Plug-and-play Parquet viewer for React 18/19
11
+ - Virtualized table for large parquet files
12
+ - Built-in filtering, multi-sort, grouping, and quick search
13
+ - Keyboard navigation and interactive column management
14
+ - Fully client-side: inspect parquet data without server uploads
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @parqui/react
20
+ ```
21
+
22
+ Peer dependencies:
23
+
24
+ - `react` `^18 || ^19`
25
+ - `react-dom` `^18 || ^19`
26
+
27
+ ## Quick Start
28
+
29
+ ```tsx
30
+ import { Parkui } from "@parqui/react";
31
+
32
+ export function App() {
33
+ return (
34
+ <div style={{ height: "80vh" }}>
35
+ <Parkui />
36
+ </div>
37
+ );
38
+ }
39
+ ```
40
+
41
+ Open behavior:
42
+
43
+ - If no `source` is passed, users can open a local `.parquet` file via the built-in UI.
44
+ - You can pass a predefined source from `@parqui/core` for controlled integrations.
45
+
46
+ ```tsx
47
+ import { Parkui } from "@parqui/react";
48
+ import { sourceFromUrl } from "@parqui/core";
49
+
50
+ const source = sourceFromUrl("https://example.com/data/events.parquet");
51
+
52
+ export function App() {
53
+ return <Parkui source={source} />;
54
+ }
55
+ ```
56
+
57
+ ## Key Props
58
+
59
+ - `source`: predefined parquet source (`File`, URL source, or custom `ParquetSource`)
60
+ - `columns`: limit visible columns
61
+ - `allowOpen`: enable/disable built-in file open flow
62
+ - `showToolbar`: show/hide toolbar with search and pipeline chips
63
+ - `onMetadataLoad`: callback when parquet metadata is available
64
+ - `onRequestOpen`: custom open handler for desktop/in-app file pickers
65
+
66
+ ## Package Ecosystem
67
+
68
+ - Core engine: [`@parqui/core`](https://www.npmjs.com/package/@parqui/core)
69
+ - Vue wrapper: [`@parqui/vue`](https://www.npmjs.com/package/@parqui/vue)
70
+ - Angular wrapper: [`@parqui/angular`](https://www.npmjs.com/package/@parqui/angular)
71
+
72
+ ## Links
73
+
74
+ - Website: [parqui.dev](https://parqui.dev)
75
+
76
+ ## License
77
+
78
+ Business Source License 1.1 (`BUSL-1.1`). See `LICENSE`.
package/dist/index.cjs CHANGED
@@ -514,18 +514,18 @@ function useParquetData(inputSource, columns, searchText) {
514
514
  }
515
515
  compute();
516
516
  }, [sourceState.source, sourceState.metadata, sourceState.totalRows, pipeline, searchText]);
517
- const toggleSort = (0, import_react4.useCallback)((column) => {
517
+ const toggleSort = (0, import_react4.useCallback)((column, multi = false) => {
518
518
  setPipeline((prev) => {
519
519
  const existing = prev.sorts.find((s2) => s2.column === column);
520
520
  let newSorts;
521
521
  if (!existing) {
522
- newSorts = [...prev.sorts, { column, direction: "asc" }];
522
+ newSorts = multi ? [...prev.sorts, { column, direction: "asc" }] : [{ column, direction: "asc" }];
523
523
  } else if (existing.direction === "asc") {
524
- newSorts = prev.sorts.map(
524
+ newSorts = multi ? prev.sorts.map(
525
525
  (s2) => s2.column === column ? { ...s2, direction: "desc" } : s2
526
- );
526
+ ) : [{ column, direction: "desc" }];
527
527
  } else {
528
- newSorts = prev.sorts.filter((s2) => s2.column !== column);
528
+ newSorts = multi ? prev.sorts.filter((s2) => s2.column !== column) : [];
529
529
  }
530
530
  return { ...prev, sorts: newSorts };
531
531
  });
@@ -1806,7 +1806,7 @@ function ColumnHeader({
1806
1806
  const handleClick = (0, import_react11.useCallback)(
1807
1807
  (e) => {
1808
1808
  if (e.target.dataset.resize) return;
1809
- onSortClick(column.key);
1809
+ onSortClick(column.key, e.ctrlKey || e.metaKey);
1810
1810
  },
1811
1811
  [column.key, onSortClick]
1812
1812
  );
@@ -3139,7 +3139,7 @@ function Parkui({
3139
3139
  [keyboard, scrollRowCount, colManager.visibleColumns.length]
3140
3140
  );
3141
3141
  const handleSortClick = (0, import_react16.useCallback)(
3142
- (column) => pq.toggleSort(column),
3142
+ (column, multi) => pq.toggleSort(column, multi),
3143
3143
  [pq.toggleSort]
3144
3144
  );
3145
3145
  const handleContextMenu = (0, import_react16.useCallback)(