@orianatech/pire 0.17.0 → 0.19.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/components/layout/SplitPane.d.cts +34 -0
- package/dist/components/layout/SplitPane.d.ts +35 -0
- package/dist/components/layout/SplitPane.d.ts.map +1 -0
- package/dist/components.css +27 -0
- package/dist/i18n/messages.d.cts +6 -0
- package/dist/i18n/messages.d.ts +6 -0
- package/dist/i18n/messages.d.ts.map +1 -1
- package/dist/index.cjs +102 -59
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +101 -59
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
export interface SplitPaneProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
3
|
+
/** The narrow column: a list of records, kept in view while one of them is read. */
|
|
4
|
+
list: React.ReactNode;
|
|
5
|
+
/** The wide column. Leave it out when nothing is selected — `emptyDetail` fills the space. */
|
|
6
|
+
detail?: React.ReactNode;
|
|
7
|
+
/** Width of the list column. A number is pixels. */
|
|
8
|
+
listWidth?: number | string;
|
|
9
|
+
/** Names the list region for assistive tech. Both panes are landmarks, so both want a name. */
|
|
10
|
+
listLabel?: string;
|
|
11
|
+
detailLabel?: string;
|
|
12
|
+
/** Shown in place of the detail column when there is no `detail`. */
|
|
13
|
+
emptyDetail?: React.ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* Returns to the list on a narrow container, where only one column fits at a time.
|
|
16
|
+
*
|
|
17
|
+
* Without it a narrow layout can reach the detail and never leave it, so pass it whenever the
|
|
18
|
+
* pane can be seen on a small screen.
|
|
19
|
+
*/
|
|
20
|
+
onBack?: () => void;
|
|
21
|
+
backLabel?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Two columns that live side by side and scroll independently — a list on the left, the selected
|
|
25
|
+
* record on the right.
|
|
26
|
+
*
|
|
27
|
+
* Distinct from `SidePanel`, which is an overlay: this one is a layout, the panes coexist, and
|
|
28
|
+
* nothing is dismissed to get back to the list.
|
|
29
|
+
*
|
|
30
|
+
* It fills the box it is given and owns the scrolling inside it, so give it a parent with a
|
|
31
|
+
* definite height and no padding of its own. A wrapper that scrolls as well produces two nested
|
|
32
|
+
* scrollbars, which is the usual way this pattern goes wrong.
|
|
33
|
+
*/
|
|
34
|
+
export declare function SplitPane({ list, detail, listWidth, listLabel, detailLabel, emptyDetail, onBack, backLabel, className, style, ...rest }: SplitPaneProps): React.JSX.Element;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type * as React from 'react';
|
|
2
|
+
export interface SplitPaneProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
3
|
+
/** The narrow column: a list of records, kept in view while one of them is read. */
|
|
4
|
+
list: React.ReactNode;
|
|
5
|
+
/** The wide column. Leave it out when nothing is selected — `emptyDetail` fills the space. */
|
|
6
|
+
detail?: React.ReactNode;
|
|
7
|
+
/** Width of the list column. A number is pixels. */
|
|
8
|
+
listWidth?: number | string;
|
|
9
|
+
/** Names the list region for assistive tech. Both panes are landmarks, so both want a name. */
|
|
10
|
+
listLabel?: string;
|
|
11
|
+
detailLabel?: string;
|
|
12
|
+
/** Shown in place of the detail column when there is no `detail`. */
|
|
13
|
+
emptyDetail?: React.ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* Returns to the list on a narrow container, where only one column fits at a time.
|
|
16
|
+
*
|
|
17
|
+
* Without it a narrow layout can reach the detail and never leave it, so pass it whenever the
|
|
18
|
+
* pane can be seen on a small screen.
|
|
19
|
+
*/
|
|
20
|
+
onBack?: () => void;
|
|
21
|
+
backLabel?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Two columns that live side by side and scroll independently — a list on the left, the selected
|
|
25
|
+
* record on the right.
|
|
26
|
+
*
|
|
27
|
+
* Distinct from `SidePanel`, which is an overlay: this one is a layout, the panes coexist, and
|
|
28
|
+
* nothing is dismissed to get back to the list.
|
|
29
|
+
*
|
|
30
|
+
* It fills the box it is given and owns the scrolling inside it, so give it a parent with a
|
|
31
|
+
* definite height and no padding of its own. A wrapper that scrolls as well produces two nested
|
|
32
|
+
* scrollbars, which is the usual way this pattern goes wrong.
|
|
33
|
+
*/
|
|
34
|
+
export declare function SplitPane({ list, detail, listWidth, listLabel, detailLabel, emptyDetail, onBack, backLabel, className, style, ...rest }: SplitPaneProps): React.JSX.Element;
|
|
35
|
+
//# sourceMappingURL=SplitPane.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SplitPane.d.ts","sourceRoot":"","sources":["../../../src/components/layout/SplitPane.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,KAAK,MAAM,OAAO,CAAC;AAKpC,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzF,oFAAoF;IACpF,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IACtB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACzB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,+FAA+F;IAC/F,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC9B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAmB,EAAE,SAAS,EAAE,WAAW,EACnF,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,qBAsB5E"}
|
package/dist/components.css
CHANGED
|
@@ -742,6 +742,33 @@
|
|
|
742
742
|
command the user cannot run. */
|
|
743
743
|
.pire-menu-item[data-disabled] .pire-kbd{color:var(--text-disabled);border-color:var(--border-subtle)}
|
|
744
744
|
|
|
745
|
+
/* ---- SplitPane ---------------------------------------------------------- */
|
|
746
|
+
/* A **container** query, not a media query: this is a layout primitive that can sit inside a shell
|
|
747
|
+
with a nav rail, a dialog or a card, and the viewport width says nothing about how much room it
|
|
748
|
+
actually has. The container is named so a nested SplitPane cannot answer the outer one's query.
|
|
749
|
+
|
|
750
|
+
45rem is the width below which two columns stop being two columns — the list at its default
|
|
751
|
+
24rem plus a detail pane narrow enough to be useless. */
|
|
752
|
+
.pire-split{container-type:inline-size;container-name:pire-split;display:flex;min-height:0;height:100%;overflow:hidden;background:var(--surface-card)}
|
|
753
|
+
/* Each pane scrolls on its own. `min-height:0` on both is what lets them do that inside a flex
|
|
754
|
+
parent, which otherwise sizes them to their content and pushes the scroll up to the page. */
|
|
755
|
+
.pire-split-list{flex:0 0 var(--pire-split-list-w,24rem);min-width:0;min-height:0;overflow:auto;border-inline-end:1px solid var(--border-subtle)}
|
|
756
|
+
/* Block, not flex. As a flex column its children shrank to fit instead of overflowing, so tall
|
|
757
|
+
detail content was squashed into the pane rather than scrolling inside it. */
|
|
758
|
+
.pire-split-detail{flex:1;min-width:0;min-height:0;overflow:auto}
|
|
759
|
+
.pire-split-empty{min-height:100%;display:grid;place-items:center;padding:var(--sp-8);text-align:center;color:var(--text-secondary)}
|
|
760
|
+
/* Present in the markup at every size and revealed by the query below, so returning to the list
|
|
761
|
+
never depends on JavaScript having measured anything. */
|
|
762
|
+
.pire-split-back{display:none}
|
|
763
|
+
|
|
764
|
+
@container pire-split (max-width: 45rem){
|
|
765
|
+
/* One column at a time. Which one depends on whether there is a record to read. */
|
|
766
|
+
.pire-split-list{flex:1 1 auto;border-inline-end:0}
|
|
767
|
+
.pire-split[data-has-detail="true"] .pire-split-list{display:none}
|
|
768
|
+
.pire-split:not([data-has-detail="true"]) .pire-split-detail{display:none}
|
|
769
|
+
.pire-split-back{display:flex;flex:0 0 auto;padding:var(--sp-2);border-block-end:1px solid var(--border-subtle);background:var(--surface-card);position:sticky;top:0;z-index:1}
|
|
770
|
+
}
|
|
771
|
+
|
|
745
772
|
/* ---- CommandPalette ----------------------------------------------------- */
|
|
746
773
|
/* Anchored near the top rather than centred: the list grows downwards as it fills, and a centred
|
|
747
774
|
palette would shift its own input under the caret while the user is still typing. */
|
package/dist/i18n/messages.d.cts
CHANGED
|
@@ -80,6 +80,12 @@ export interface PireMessages {
|
|
|
80
80
|
paginationRowsPerPage: string;
|
|
81
81
|
/** Landmark name of the main SideNav. Override it when a screen has more than one nav. */
|
|
82
82
|
sideNavLabel: string;
|
|
83
|
+
/** Names SplitPane's list column. */
|
|
84
|
+
splitPaneList: string;
|
|
85
|
+
/** Names SplitPane's detail column. */
|
|
86
|
+
splitPaneDetail: string;
|
|
87
|
+
/** Returns to the list when SplitPane is narrow enough to show one column. */
|
|
88
|
+
splitPaneBack: string;
|
|
83
89
|
/** Button that opens the OS file picker. */
|
|
84
90
|
fileUploadChoose: string;
|
|
85
91
|
/** Removes one picked file. `{name}` is replaced with the file name. */
|
package/dist/i18n/messages.d.ts
CHANGED
|
@@ -80,6 +80,12 @@ export interface PireMessages {
|
|
|
80
80
|
paginationRowsPerPage: string;
|
|
81
81
|
/** Landmark name of the main SideNav. Override it when a screen has more than one nav. */
|
|
82
82
|
sideNavLabel: string;
|
|
83
|
+
/** Names SplitPane's list column. */
|
|
84
|
+
splitPaneList: string;
|
|
85
|
+
/** Names SplitPane's detail column. */
|
|
86
|
+
splitPaneDetail: string;
|
|
87
|
+
/** Returns to the list when SplitPane is narrow enough to show one column. */
|
|
88
|
+
splitPaneBack: string;
|
|
83
89
|
/** Button that opens the OS file picker. */
|
|
84
90
|
fileUploadChoose: string;
|
|
85
91
|
/** Removes one picked file. `{name}` is replaced with the file name. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/i18n/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,iBAAiB,EAAE,MAAM,CAAC;IAE1B,qEAAqE;IACrE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qDAAqD;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oDAAoD;IACpD,gBAAgB,EAAE,MAAM,CAAC;IACzB,6FAA6F;IAC7F,mBAAmB,EAAE,MAAM,CAAC;IAE5B,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,cAAc,EAAE,MAAM,CAAC;IAEvB,6DAA6D;IAC7D,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uDAAuD;IACvD,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,CAAC;IAEzB,kEAAkE;IAClE;oGACgG;IAChG,WAAW,EAAE,MAAM,CAAC;IAEpB,uBAAuB,EAAE,MAAM,CAAC;IAChC,mEAAmE;IACnE,eAAe,EAAE,MAAM,CAAC;IAExB,qEAAqE;IACrE,sBAAsB,EAAE,MAAM,CAAC;IAC/B,uBAAuB,EAAE,MAAM,CAAC;IAChC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,6DAA6D;IAC7D,qBAAqB,EAAE,MAAM,CAAC;IAE9B,oDAAoD;IACpD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAE5B,kEAAkE;IAClE,oEAAoE;IACpE,UAAU,EAAE,MAAM,CAAC;IAEnB,yEAAyE;IACzE,yBAAyB,EAAE,MAAM,CAAC;IAClC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,qFAAqF;IACrF,uBAAuB,EAAE,MAAM,CAAC;IAChC,uEAAuE;IACvE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iEAAiE;IACjE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gDAAgD;IAChD,gCAAgC,EAAE,MAAM,CAAC;IACzC,6CAA6C;IAC7C,oBAAoB,EAAE,MAAM,CAAC;IAC7B,uDAAuD;IACvD,qBAAqB,EAAE,MAAM,CAAC;IAE9B,mDAAmD;IACnD,eAAe,EAAE,MAAM,CAAC;IACxB,wFAAwF;IACxF,eAAe,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,qBAAqB,EAAE,MAAM,CAAC;IAE9B,0FAA0F;IAC1F,YAAY,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/i18n/messages.ts"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -97,6 +97,7 @@ __export(src_exports, {
|
|
|
97
97
|
SidePanel: () => SidePanel,
|
|
98
98
|
Skeleton: () => Skeleton,
|
|
99
99
|
SkeletonTableRow: () => SkeletonTableRow,
|
|
100
|
+
SplitPane: () => SplitPane,
|
|
100
101
|
Strong: () => Strong,
|
|
101
102
|
SubmenuTrigger: () => import_react_aria_components34.SubmenuTrigger,
|
|
102
103
|
Switch: () => Switch,
|
|
@@ -876,6 +877,9 @@ var enMessages = {
|
|
|
876
877
|
paginationNext: "Next page",
|
|
877
878
|
paginationRowsPerPage: "Rows per page",
|
|
878
879
|
sideNavLabel: "Main navigation",
|
|
880
|
+
splitPaneList: "List",
|
|
881
|
+
splitPaneDetail: "Detail",
|
|
882
|
+
splitPaneBack: "Back to list",
|
|
879
883
|
fileUploadChoose: "Choose files",
|
|
880
884
|
fileUploadRemoveNamed: "Remove {name}",
|
|
881
885
|
fileUploadUploading: "Uploading",
|
|
@@ -932,6 +936,9 @@ var esMessages = {
|
|
|
932
936
|
paginationNext: "P\xE1gina siguiente",
|
|
933
937
|
paginationRowsPerPage: "Filas por p\xE1gina",
|
|
934
938
|
sideNavLabel: "Navegaci\xF3n principal",
|
|
939
|
+
splitPaneList: "Lista",
|
|
940
|
+
splitPaneDetail: "Detalle",
|
|
941
|
+
splitPaneBack: "Volver a la lista",
|
|
935
942
|
fileUploadChoose: "Elegir archivos",
|
|
936
943
|
fileUploadRemoveNamed: "Quitar {name}",
|
|
937
944
|
fileUploadUploading: "Subiendo",
|
|
@@ -3409,8 +3416,43 @@ function FooterBar({ note, actions, children, className, ...rest }) {
|
|
|
3409
3416
|
] });
|
|
3410
3417
|
}
|
|
3411
3418
|
|
|
3412
|
-
// src/components/
|
|
3419
|
+
// src/components/layout/SplitPane.tsx
|
|
3413
3420
|
var import_jsx_runtime58 = require("react/jsx-runtime");
|
|
3421
|
+
function SplitPane({
|
|
3422
|
+
list,
|
|
3423
|
+
detail,
|
|
3424
|
+
listWidth = "24rem",
|
|
3425
|
+
listLabel,
|
|
3426
|
+
detailLabel,
|
|
3427
|
+
emptyDetail,
|
|
3428
|
+
onBack,
|
|
3429
|
+
backLabel,
|
|
3430
|
+
className,
|
|
3431
|
+
style,
|
|
3432
|
+
...rest
|
|
3433
|
+
}) {
|
|
3434
|
+
const msg = usePireMessages();
|
|
3435
|
+
const width = typeof listWidth === "number" ? `${listWidth}px` : listWidth;
|
|
3436
|
+
return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(
|
|
3437
|
+
"div",
|
|
3438
|
+
{
|
|
3439
|
+
className: cx("pire-split", className),
|
|
3440
|
+
"data-has-detail": detail != null ? "true" : void 0,
|
|
3441
|
+
style: { ["--pire-split-list-w"]: width, ...style },
|
|
3442
|
+
...rest,
|
|
3443
|
+
children: [
|
|
3444
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsx)("section", { className: "pire-split-list", "aria-label": listLabel ?? msg.splitPaneList, children: list }),
|
|
3445
|
+
/* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("section", { className: "pire-split-detail", "aria-label": detailLabel ?? msg.splitPaneDetail, children: [
|
|
3446
|
+
onBack ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "pire-split-back", children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(Button, { variant: "tertiary", size: "sm", icon: "arrow-left", onPress: onBack, children: backLabel ?? msg.splitPaneBack }) }) : null,
|
|
3447
|
+
detail ?? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "pire-split-empty", children: emptyDetail })
|
|
3448
|
+
] })
|
|
3449
|
+
]
|
|
3450
|
+
}
|
|
3451
|
+
);
|
|
3452
|
+
}
|
|
3453
|
+
|
|
3454
|
+
// src/components/patterns/ConfirmDialog.tsx
|
|
3455
|
+
var import_jsx_runtime59 = require("react/jsx-runtime");
|
|
3414
3456
|
function ConfirmDialog({
|
|
3415
3457
|
isOpen,
|
|
3416
3458
|
title,
|
|
@@ -3424,7 +3466,7 @@ function ConfirmDialog({
|
|
|
3424
3466
|
onConfirm,
|
|
3425
3467
|
onCancel
|
|
3426
3468
|
}) {
|
|
3427
|
-
return /* @__PURE__ */ (0,
|
|
3469
|
+
return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
|
|
3428
3470
|
Dialog,
|
|
3429
3471
|
{
|
|
3430
3472
|
isOpen,
|
|
@@ -3434,12 +3476,12 @@ function ConfirmDialog({
|
|
|
3434
3476
|
onClose: onCancel,
|
|
3435
3477
|
isDismissable: !isBusy,
|
|
3436
3478
|
showClose: false,
|
|
3437
|
-
footer: /* @__PURE__ */ (0,
|
|
3438
|
-
/* @__PURE__ */ (0,
|
|
3439
|
-
/* @__PURE__ */ (0,
|
|
3479
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_jsx_runtime59.Fragment, { children: [
|
|
3480
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Button, { variant: "tertiary", isDisabled: isBusy, onPress: onCancel, children: cancelLabel }),
|
|
3481
|
+
/* @__PURE__ */ (0, import_jsx_runtime59.jsx)(Button, { variant: tone === "danger" ? "danger" : "primary", isDisabled: isBusy, onPress: onConfirm, children: isBusy ? "Working\u2026" : confirmLabel })
|
|
3440
3482
|
] }),
|
|
3441
3483
|
children: [
|
|
3442
|
-
consequence ? /* @__PURE__ */ (0,
|
|
3484
|
+
consequence ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(InlineMessage, { kind: tone === "danger" ? "error" : "warning", style: { marginBottom: children ? "var(--sp-3)" : 0 }, children: consequence }) : null,
|
|
3443
3485
|
children
|
|
3444
3486
|
]
|
|
3445
3487
|
}
|
|
@@ -3449,7 +3491,7 @@ function ConfirmDialog({
|
|
|
3449
3491
|
// src/components/patterns/CommandPalette.tsx
|
|
3450
3492
|
var React18 = __toESM(require("react"), 1);
|
|
3451
3493
|
var import_react_aria_components31 = require("react-aria-components");
|
|
3452
|
-
var
|
|
3494
|
+
var import_jsx_runtime60 = require("react/jsx-runtime");
|
|
3453
3495
|
var RESULTS_SECTION_KEY = "__pire_results__";
|
|
3454
3496
|
var searchableText = (item) => [item.label, item.description, item.keywords].filter(Boolean).join(" ");
|
|
3455
3497
|
function CommandPalette({
|
|
@@ -3490,7 +3532,7 @@ function CommandPalette({
|
|
|
3490
3532
|
};
|
|
3491
3533
|
const sections = [...groups, ...resultsGroup ? [{ ...resultsGroup, id: RESULTS_SECTION_KEY }] : []];
|
|
3492
3534
|
const status = isLoading ? loadingLabel ?? msg.commandPaletteLoading : emptyLabel ?? msg.commandPaletteEmpty;
|
|
3493
|
-
return /* @__PURE__ */ (0,
|
|
3535
|
+
return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
3494
3536
|
import_react_aria_components31.ModalOverlay,
|
|
3495
3537
|
{
|
|
3496
3538
|
className: "pire-cp-overlay",
|
|
@@ -3499,11 +3541,11 @@ function CommandPalette({
|
|
|
3499
3541
|
onOpenChange: (open) => {
|
|
3500
3542
|
if (!open) onOpenChange?.(false);
|
|
3501
3543
|
},
|
|
3502
|
-
children: /* @__PURE__ */ (0,
|
|
3503
|
-
/* @__PURE__ */ (0,
|
|
3504
|
-
/* @__PURE__ */ (0,
|
|
3505
|
-
/* @__PURE__ */ (0,
|
|
3506
|
-
/* @__PURE__ */ (0,
|
|
3544
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_react_aria_components31.Modal, { className: cx("pire-cp-modal", className), style, children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_react_aria_components31.Dialog, { className: "pire-cp-dialog", "aria-label": ariaLabel ?? msg.commandPaletteLabel, children: [
|
|
3545
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_react_aria_components31.Autocomplete, { filter, inputValue: query, onInputChange: handleInputChange, children: [
|
|
3546
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_react_aria_components31.SearchField, { className: "pire-cp-search", "aria-label": msg.commandPaletteSearchLabel, children: [
|
|
3547
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Icon, { name: "search", size: 18, className: "pire-cp-search-icon" }),
|
|
3548
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
3507
3549
|
import_react_aria_components31.Input,
|
|
3508
3550
|
{
|
|
3509
3551
|
className: "pire-cp-input",
|
|
@@ -3512,16 +3554,16 @@ function CommandPalette({
|
|
|
3512
3554
|
}
|
|
3513
3555
|
)
|
|
3514
3556
|
] }),
|
|
3515
|
-
isLoading ? /* @__PURE__ */ (0,
|
|
3516
|
-
/* @__PURE__ */ (0,
|
|
3557
|
+
isLoading ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "pire-cp-loading", role: "status", "aria-live": "polite", children: loadingLabel ?? msg.commandPaletteLoading }) : null,
|
|
3558
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
3517
3559
|
import_react_aria_components31.Menu,
|
|
3518
3560
|
{
|
|
3519
3561
|
className: "pire-cp-list",
|
|
3520
3562
|
onAction: (key) => onAction?.(String(key)),
|
|
3521
|
-
renderEmptyState: () => /* @__PURE__ */ (0,
|
|
3522
|
-
children: sections.map((section) => /* @__PURE__ */ (0,
|
|
3523
|
-
section.label ? /* @__PURE__ */ (0,
|
|
3524
|
-
section.items.map((item) => /* @__PURE__ */ (0,
|
|
3563
|
+
renderEmptyState: () => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "pire-cp-status", children: status }),
|
|
3564
|
+
children: sections.map((section) => /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_react_aria_components31.MenuSection, { id: section.id, className: "pire-cp-section", children: [
|
|
3565
|
+
section.label ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(import_react_aria_components31.Header, { className: "pire-cp-section-title", children: section.label }) : null,
|
|
3566
|
+
section.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
|
|
3525
3567
|
MenuItem,
|
|
3526
3568
|
{
|
|
3527
3569
|
id: item.id,
|
|
@@ -3542,18 +3584,18 @@ function CommandPalette({
|
|
|
3542
3584
|
// aria-hidden: the glyphs are a sighted affordance for discovering the keys. A screen
|
|
3543
3585
|
// reader already announces the listbox semantics that make those keys work, so reading
|
|
3544
3586
|
// "up arrow down arrow navigate" out loud is noise on every open.
|
|
3545
|
-
/* @__PURE__ */ (0,
|
|
3546
|
-
/* @__PURE__ */ (0,
|
|
3547
|
-
/* @__PURE__ */ (0,
|
|
3548
|
-
/* @__PURE__ */ (0,
|
|
3587
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "pire-cp-foot", "aria-hidden": "true", children: footer ?? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
|
|
3588
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "pire-cp-hint", children: [
|
|
3589
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Kbd, { children: "\u2191" }),
|
|
3590
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Kbd, { children: "\u2193" }),
|
|
3549
3591
|
msg.commandPaletteHintNavigate
|
|
3550
3592
|
] }),
|
|
3551
|
-
/* @__PURE__ */ (0,
|
|
3552
|
-
/* @__PURE__ */ (0,
|
|
3593
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "pire-cp-hint", children: [
|
|
3594
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Kbd, { children: "\u21B5" }),
|
|
3553
3595
|
msg.commandPaletteHintSelect
|
|
3554
3596
|
] }),
|
|
3555
|
-
/* @__PURE__ */ (0,
|
|
3556
|
-
/* @__PURE__ */ (0,
|
|
3597
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "pire-cp-hint", children: [
|
|
3598
|
+
/* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Kbd, { children: "esc" }),
|
|
3557
3599
|
msg.commandPaletteHintClose
|
|
3558
3600
|
] })
|
|
3559
3601
|
] }) })
|
|
@@ -3580,10 +3622,10 @@ function useCommandPaletteShortcut(onTrigger, { key = "k", isDisabled } = {}) {
|
|
|
3580
3622
|
|
|
3581
3623
|
// src/components/patterns/SidePanel.tsx
|
|
3582
3624
|
var import_react_aria_components32 = require("react-aria-components");
|
|
3583
|
-
var
|
|
3625
|
+
var import_jsx_runtime61 = require("react/jsx-runtime");
|
|
3584
3626
|
function SidePanel({ isOpen, title, subtitle, width = 400, children, footer, onClose, className }) {
|
|
3585
3627
|
const msg = usePireMessages();
|
|
3586
|
-
return /* @__PURE__ */ (0,
|
|
3628
|
+
return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
|
|
3587
3629
|
import_react_aria_components32.ModalOverlay,
|
|
3588
3630
|
{
|
|
3589
3631
|
className: "pire-sidepanel-overlay",
|
|
@@ -3592,28 +3634,28 @@ function SidePanel({ isOpen, title, subtitle, width = 400, children, footer, onC
|
|
|
3592
3634
|
onOpenChange: (o) => {
|
|
3593
3635
|
if (!o) onClose?.();
|
|
3594
3636
|
},
|
|
3595
|
-
children: /* @__PURE__ */ (0,
|
|
3596
|
-
/* @__PURE__ */ (0,
|
|
3597
|
-
/* @__PURE__ */ (0,
|
|
3598
|
-
/* @__PURE__ */ (0,
|
|
3599
|
-
subtitle ? /* @__PURE__ */ (0,
|
|
3637
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_react_aria_components32.Modal, { className: cx("pire-sidepanel", className), style: { width }, children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)(import_react_aria_components32.Dialog, { className: "pire-dialog", style: { height: "100%" }, children: [
|
|
3638
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("header", { className: "pire-dialog-head", children: [
|
|
3639
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [
|
|
3640
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(import_react_aria_components32.Heading, { slot: "title", className: "pire-dialog-title", children: title }),
|
|
3641
|
+
subtitle ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { className: "pire-dialog-sub", style: { margin: 0 }, children: subtitle }) : null
|
|
3600
3642
|
] }),
|
|
3601
|
-
/* @__PURE__ */ (0,
|
|
3643
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)(IconButton, { icon: "x", label: msg.sidePanelClose, size: "sm", onPress: onClose })
|
|
3602
3644
|
] }),
|
|
3603
|
-
/* @__PURE__ */ (0,
|
|
3604
|
-
footer ? /* @__PURE__ */ (0,
|
|
3645
|
+
/* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "pire-dialog-body", style: { flex: 1 }, children }),
|
|
3646
|
+
footer ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("footer", { className: "pire-dialog-foot", children: footer }) : null
|
|
3605
3647
|
] }) })
|
|
3606
3648
|
}
|
|
3607
3649
|
);
|
|
3608
3650
|
}
|
|
3609
3651
|
|
|
3610
3652
|
// src/components/patterns/EmptyState.tsx
|
|
3611
|
-
var
|
|
3653
|
+
var import_jsx_runtime62 = require("react/jsx-runtime");
|
|
3612
3654
|
function EmptyState({ icon = "file-text", title, action, compact, children, className, ...rest }) {
|
|
3613
|
-
return /* @__PURE__ */ (0,
|
|
3614
|
-
/* @__PURE__ */ (0,
|
|
3615
|
-
title ? /* @__PURE__ */ (0,
|
|
3616
|
-
children ? /* @__PURE__ */ (0,
|
|
3655
|
+
return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: cx("pire-empty", className), "data-compact": compact ? "true" : void 0, ...rest, children: [
|
|
3656
|
+
/* @__PURE__ */ (0, import_jsx_runtime62.jsx)(Icon, { name: icon, size: 24, className: "pire-empty-icon" }),
|
|
3657
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "pire-empty-title", style: { margin: 0 }, children: title }) : null,
|
|
3658
|
+
children ? /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "pire-empty-body", style: { margin: 0 }, children }) : null,
|
|
3617
3659
|
action
|
|
3618
3660
|
] });
|
|
3619
3661
|
}
|
|
@@ -3621,7 +3663,7 @@ function EmptyState({ icon = "file-text", title, action, compact, children, clas
|
|
|
3621
3663
|
// src/components/patterns/FileDropZone.tsx
|
|
3622
3664
|
var React19 = __toESM(require("react"), 1);
|
|
3623
3665
|
var import_react_aria_components33 = require("react-aria-components");
|
|
3624
|
-
var
|
|
3666
|
+
var import_jsx_runtime63 = require("react/jsx-runtime");
|
|
3625
3667
|
var isImage2 = (file) => file.type.startsWith("image/");
|
|
3626
3668
|
function FileDropZone({
|
|
3627
3669
|
label,
|
|
@@ -3670,12 +3712,12 @@ function FileDropZone({
|
|
|
3670
3712
|
commit(allowsMultiple ? [...files, ...wrapped] : wrapped.slice(0, 1));
|
|
3671
3713
|
};
|
|
3672
3714
|
const remove = (target) => commit(files.filter((f) => f.file !== target));
|
|
3673
|
-
return /* @__PURE__ */ (0,
|
|
3674
|
-
label ? /* @__PURE__ */ (0,
|
|
3715
|
+
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: cx("pire-field", className), style, "data-full-width": String(fullWidth), children: [
|
|
3716
|
+
label ? /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "pire-field-label", children: [
|
|
3675
3717
|
label,
|
|
3676
|
-
isRequired ? /* @__PURE__ */ (0,
|
|
3718
|
+
isRequired ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "pire-field-req", "aria-hidden": "true", children: "*" }) : null
|
|
3677
3719
|
] }) : null,
|
|
3678
|
-
/* @__PURE__ */ (0,
|
|
3720
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(
|
|
3679
3721
|
import_react_aria_components33.DropZone,
|
|
3680
3722
|
{
|
|
3681
3723
|
className: "pire-dropzone",
|
|
@@ -3688,25 +3730,25 @@ function FileDropZone({
|
|
|
3688
3730
|
accept(dropped);
|
|
3689
3731
|
},
|
|
3690
3732
|
children: [
|
|
3691
|
-
/* @__PURE__ */ (0,
|
|
3692
|
-
/* @__PURE__ */ (0,
|
|
3693
|
-
/* @__PURE__ */ (0,
|
|
3733
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Icon, { name: "download", size: 24, className: "pire-dropzone-icon" }),
|
|
3734
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "pire-dropzone-prompt", children: promptLabel ?? msg.fileDropZonePrompt }),
|
|
3735
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
3694
3736
|
import_react_aria_components33.FileTrigger,
|
|
3695
3737
|
{
|
|
3696
3738
|
acceptedFileTypes,
|
|
3697
3739
|
allowsMultiple,
|
|
3698
3740
|
onSelect: (list) => accept(list ? [...list] : []),
|
|
3699
|
-
children: /* @__PURE__ */ (0,
|
|
3741
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Button, { variant: "secondary", isDisabled: isDisabled || isReadOnly, children: msg.fileUploadChoose })
|
|
3700
3742
|
}
|
|
3701
3743
|
)
|
|
3702
3744
|
]
|
|
3703
3745
|
}
|
|
3704
3746
|
),
|
|
3705
|
-
files.length ? /* @__PURE__ */ (0,
|
|
3706
|
-
previewUrl ? /* @__PURE__ */ (0,
|
|
3707
|
-
/* @__PURE__ */ (0,
|
|
3708
|
-
/* @__PURE__ */ (0,
|
|
3709
|
-
isDisabled || isReadOnly ? null : /* @__PURE__ */ (0,
|
|
3747
|
+
files.length ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("ul", { className: "pire-fileupload-list", children: files.map(({ file, previewUrl }) => /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("li", { className: "pire-fileupload-item", children: [
|
|
3748
|
+
previewUrl ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("img", { className: "pire-fileupload-thumb", src: previewUrl, alt: "" }) : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Icon, { name: "file-text", size: 16, className: "pire-fileupload-icon" }),
|
|
3749
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "pire-fileupload-name", children: file.name }),
|
|
3750
|
+
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "pire-fileupload-size", children: formatFileSize(file.size) }),
|
|
3751
|
+
isDisabled || isReadOnly ? null : /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
|
|
3710
3752
|
IconButton,
|
|
3711
3753
|
{
|
|
3712
3754
|
icon: "x",
|
|
@@ -3716,9 +3758,9 @@ function FileDropZone({
|
|
|
3716
3758
|
}
|
|
3717
3759
|
)
|
|
3718
3760
|
] }, `${file.name}-${file.size}-${file.lastModified}`)) }) : null,
|
|
3719
|
-
uploadProgress != null ? /* @__PURE__ */ (0,
|
|
3720
|
-
description ? /* @__PURE__ */ (0,
|
|
3721
|
-
isInvalid && errorMessage ? /* @__PURE__ */ (0,
|
|
3761
|
+
uploadProgress != null ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(ProgressBar, { value: uploadProgress, label: msg.fileUploadUploading }) : null,
|
|
3762
|
+
description ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "pire-field-hint", children: description }) : null,
|
|
3763
|
+
isInvalid && errorMessage ? /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "pire-field-error", children: errorMessage }) : null
|
|
3722
3764
|
] });
|
|
3723
3765
|
}
|
|
3724
3766
|
|
|
@@ -3794,6 +3836,7 @@ var import_react_aria_components35 = require("react-aria-components");
|
|
|
3794
3836
|
SidePanel,
|
|
3795
3837
|
Skeleton,
|
|
3796
3838
|
SkeletonTableRow,
|
|
3839
|
+
SplitPane,
|
|
3797
3840
|
Strong,
|
|
3798
3841
|
SubmenuTrigger,
|
|
3799
3842
|
Switch,
|