@oprt/react 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +105 -2
- package/dist/ActionStatus/ActionStatus.js +104 -0
- package/dist/ActionStatus/ActionStatus.manifest.js +64 -0
- package/dist/ActionStatus/index.js +7 -0
- package/dist/Alert/Alert.js +86 -0
- package/dist/Alert/Alert.manifest.js +36 -0
- package/dist/Alert/index.js +7 -0
- package/dist/AppShell/AppShell.js +103 -0
- package/dist/AppShell/AppShell.manifest.js +66 -0
- package/dist/AppShell/index.js +9 -0
- package/dist/AttachmentPreview/AttachmentPreview.js +145 -0
- package/dist/AttachmentPreview/AttachmentPreview.manifest.js +42 -0
- package/dist/AttachmentPreview/index.js +9 -0
- package/dist/Avatar/Avatar.js +87 -0
- package/dist/Avatar/Avatar.manifest.js +25 -0
- package/dist/Avatar/index.js +7 -0
- package/dist/Badge/Badge.js +124 -0
- package/dist/Badge/Badge.manifest.js +41 -0
- package/dist/Badge/index.js +7 -0
- package/dist/Breadcrumb/Breadcrumb.js +64 -0
- package/dist/Breadcrumb/Breadcrumb.manifest.js +28 -0
- package/dist/Breadcrumb/index.js +7 -0
- package/dist/BulkActionBar/BulkActionBar.js +145 -0
- package/dist/BulkActionBar/BulkActionBar.manifest.js +46 -0
- package/dist/BulkActionBar/index.js +9 -0
- package/dist/BulkActionBar/selection.js +44 -0
- package/dist/BulkResults/BulkResults.js +269 -0
- package/dist/BulkResults/BulkResults.manifest.js +45 -0
- package/dist/BulkResults/index.js +7 -0
- package/dist/Button/Button.js +170 -0
- package/dist/Button/Button.manifest.js +36 -0
- package/dist/Button/index.js +7 -0
- package/dist/ButtonGroup/ButtonGroup.js +60 -0
- package/dist/ButtonGroup/ButtonGroup.manifest.js +22 -0
- package/dist/ButtonGroup/index.js +7 -0
- package/dist/Calendar/Calendar.js +106 -0
- package/dist/Calendar/Calendar.manifest.js +32 -0
- package/dist/Calendar/index.js +7 -0
- package/dist/Card/Card.js +70 -0
- package/dist/Card/Card.manifest.js +57 -0
- package/dist/Card/index.js +16 -0
- package/dist/Chart/Chart.js +1200 -0
- package/dist/Chart/Chart.manifest.js +110 -0
- package/dist/Chart/ChartControls.js +190 -0
- package/dist/Chart/geometry.js +217 -0
- package/dist/Chart/index.js +9 -0
- package/dist/Checkbox/Checkbox.js +166 -0
- package/dist/Checkbox/Checkbox.manifest.js +38 -0
- package/dist/Checkbox/index.js +7 -0
- package/dist/Collapsible/Collapsible.js +177 -0
- package/dist/Collapsible/Collapsible.manifest.js +54 -0
- package/dist/Collapsible/index.js +12 -0
- package/dist/CollectionState/CollectionState.js +68 -0
- package/dist/CollectionState/CollectionState.manifest.js +44 -0
- package/dist/CollectionState/index.js +7 -0
- package/dist/ComboBox/ComboBox.js +221 -0
- package/dist/ComboBox/ComboBox.manifest.js +87 -0
- package/dist/ComboBox/index.js +7 -0
- package/dist/CommandPalette/CommandPalette.js +276 -0
- package/dist/CommandPalette/CommandPalette.manifest.js +24 -0
- package/dist/CommandPalette/index.js +7 -0
- package/dist/ConfirmDialog/ConfirmDialog.js +84 -0
- package/dist/ConfirmDialog/ConfirmDialog.manifest.js +32 -0
- package/dist/ConfirmDialog/index.js +7 -0
- package/dist/ContextMenu/ContextMenu.js +192 -0
- package/dist/ContextMenu/ContextMenu.manifest.js +41 -0
- package/dist/ContextMenu/index.js +7 -0
- package/dist/CoordinateInput/CoordinateInput.js +141 -0
- package/dist/CoordinateInput/CoordinateInput.manifest.js +36 -0
- package/dist/CoordinateInput/index.js +9 -0
- package/dist/CopyButton/CopyButton.js +129 -0
- package/dist/CopyButton/CopyButton.manifest.js +35 -0
- package/dist/CopyButton/index.js +7 -0
- package/dist/DataGrid/DataGrid.js +459 -0
- package/dist/DataGrid/DataGrid.manifest.js +135 -0
- package/dist/DataGrid/PageControls.js +41 -0
- package/dist/DataGrid/index.js +9 -0
- package/dist/DataTable/DataTable.js +375 -0
- package/dist/DataTable/DataTable.manifest.js +86 -0
- package/dist/DataTable/index.js +9 -0
- package/dist/DataTable/sort.js +45 -0
- package/dist/DataTable/useScrollsSideways.js +61 -0
- package/dist/DataTable/useTableWindow.js +185 -0
- package/dist/DatePicker/DatePicker.js +187 -0
- package/dist/DatePicker/DatePicker.manifest.js +40 -0
- package/dist/DatePicker/index.js +7 -0
- package/dist/DateRangePicker/DateRangePicker.js +156 -0
- package/dist/DateRangePicker/DateRangePicker.manifest.js +41 -0
- package/dist/DateRangePicker/index.js +7 -0
- package/dist/DateTimePicker/DateTimePicker.js +213 -0
- package/dist/DateTimePicker/DateTimePicker.manifest.js +44 -0
- package/dist/DateTimePicker/index.js +7 -0
- package/dist/DescriptionList/DescriptionList.js +93 -0
- package/dist/DescriptionList/DescriptionList.manifest.js +40 -0
- package/dist/DescriptionList/index.js +9 -0
- package/dist/Dialog/Dialog.js +214 -0
- package/dist/Dialog/Dialog.manifest.js +31 -0
- package/dist/Dialog/index.js +7 -0
- package/dist/Divider/Divider.js +64 -0
- package/dist/Divider/Divider.manifest.js +21 -0
- package/dist/Divider/index.js +7 -0
- package/dist/DropdownMenu/DropdownMenu.js +170 -0
- package/dist/DropdownMenu/DropdownMenu.manifest.js +82 -0
- package/dist/DropdownMenu/index.js +16 -0
- package/dist/EntityPreview/EntityPreview.js +82 -0
- package/dist/EntityPreview/EntityPreview.manifest.js +43 -0
- package/dist/EntityPreview/index.js +7 -0
- package/dist/EventTimeline/EventTimeline.js +249 -0
- package/dist/EventTimeline/EventTimeline.manifest.js +57 -0
- package/dist/EventTimeline/index.js +7 -0
- package/dist/Field/Field.js +81 -0
- package/dist/Field/Field.manifest.js +32 -0
- package/dist/Field/index.js +9 -0
- package/dist/FileUpload/FileUpload.js +215 -0
- package/dist/FileUpload/FileUpload.manifest.js +48 -0
- package/dist/FileUpload/index.js +7 -0
- package/dist/FilterBar/FilterBar.js +173 -0
- package/dist/FilterBar/FilterBar.manifest.js +49 -0
- package/dist/FilterBar/index.js +7 -0
- package/dist/FormErrorSummary/FormErrorSummary.js +70 -0
- package/dist/FormErrorSummary/FormErrorSummary.manifest.js +29 -0
- package/dist/FormErrorSummary/index.js +9 -0
- package/dist/FormSection/FormSection.js +51 -0
- package/dist/FormSection/FormSection.manifest.js +30 -0
- package/dist/FormSection/index.js +7 -0
- package/dist/InlineEdit/InlineEdit.js +261 -0
- package/dist/InlineEdit/InlineEdit.manifest.js +40 -0
- package/dist/InlineEdit/index.js +7 -0
- package/dist/Input/Input.js +126 -0
- package/dist/Input/Input.manifest.js +49 -0
- package/dist/Input/index.js +7 -0
- package/dist/Inspector/Inspector.js +63 -0
- package/dist/Inspector/Inspector.manifest.js +35 -0
- package/dist/Inspector/index.js +7 -0
- package/dist/JobStatus/JobStatus.js +118 -0
- package/dist/JobStatus/JobStatus.manifest.js +53 -0
- package/dist/JobStatus/index.js +7 -0
- package/dist/LayerControl/LayerControl.js +199 -0
- package/dist/LayerControl/LayerControl.manifest.js +34 -0
- package/dist/LayerControl/index.js +7 -0
- package/dist/Link/Link.js +83 -0
- package/dist/Link/Link.manifest.js +37 -0
- package/dist/Link/index.js +7 -0
- package/dist/MapControls/MapControls.js +122 -0
- package/dist/MapControls/MapControls.manifest.js +31 -0
- package/dist/MapControls/index.js +7 -0
- package/dist/MapLegend/MapLegend.js +89 -0
- package/dist/MapLegend/MapLegend.manifest.js +29 -0
- package/dist/MapLegend/index.js +7 -0
- package/dist/MapScale/MapScale.js +96 -0
- package/dist/MapScale/MapScale.manifest.js +31 -0
- package/dist/MapScale/index.js +7 -0
- package/dist/MediaFrame/MediaFrame.js +113 -0
- package/dist/MediaFrame/MediaFrame.manifest.js +57 -0
- package/dist/MediaFrame/index.js +7 -0
- package/dist/MultiSelect/MultiSelect.js +113 -0
- package/dist/MultiSelect/MultiSelect.manifest.js +51 -0
- package/dist/MultiSelect/index.js +7 -0
- package/dist/NumberInput/NumberInput.js +210 -0
- package/dist/NumberInput/NumberInput.manifest.js +56 -0
- package/dist/NumberInput/index.js +7 -0
- package/dist/OperationalStatus/OperationalStatus.js +89 -0
- package/dist/OperationalStatus/OperationalStatus.manifest.js +39 -0
- package/dist/OperationalStatus/index.js +9 -0
- package/dist/PlaybackControls/PlaybackControls.js +289 -0
- package/dist/PlaybackControls/PlaybackControls.manifest.js +85 -0
- package/dist/PlaybackControls/index.js +7 -0
- package/dist/Popover/Popover.js +302 -0
- package/dist/Popover/Popover.manifest.js +50 -0
- package/dist/Popover/index.js +7 -0
- package/dist/Progress/Progress.js +132 -0
- package/dist/Progress/Progress.manifest.js +30 -0
- package/dist/Progress/index.js +7 -0
- package/dist/PropertyFilter/PropertyFilter.js +306 -0
- package/dist/PropertyFilter/PropertyFilter.manifest.js +32 -0
- package/dist/PropertyFilter/index.js +11 -0
- package/dist/PropertyFilter/tokenError.js +17 -0
- package/dist/RadioGroup/RadioGroup.js +143 -0
- package/dist/RadioGroup/RadioGroup.manifest.js +44 -0
- package/dist/RadioGroup/index.js +9 -0
- package/dist/Select/Select.js +219 -0
- package/dist/Select/Select.manifest.js +77 -0
- package/dist/Select/index.js +9 -0
- package/dist/Sidebar/Sidebar.js +146 -0
- package/dist/Sidebar/Sidebar.manifest.js +72 -0
- package/dist/Sidebar/index.js +18 -0
- package/dist/Skeleton/Skeleton.js +76 -0
- package/dist/Skeleton/Skeleton.manifest.js +30 -0
- package/dist/Skeleton/index.js +7 -0
- package/dist/Slider/Slider.js +246 -0
- package/dist/Slider/Slider.manifest.js +56 -0
- package/dist/Slider/index.js +7 -0
- package/dist/Sparkline/Sparkline.js +135 -0
- package/dist/Sparkline/Sparkline.manifest.js +37 -0
- package/dist/Sparkline/index.js +7 -0
- package/dist/SplitPane/SplitPane.js +316 -0
- package/dist/SplitPane/SplitPane.manifest.js +79 -0
- package/dist/SplitPane/index.js +7 -0
- package/dist/StatCard/StatCard.js +163 -0
- package/dist/StatCard/StatCard.manifest.js +45 -0
- package/dist/StatCard/index.js +7 -0
- package/dist/Tabs/Tabs.js +181 -0
- package/dist/Tabs/Tabs.manifest.js +72 -0
- package/dist/Tabs/index.js +16 -0
- package/dist/Tabs/useTabsIndicator.js +71 -0
- package/dist/Tabs/useTabsScroll.js +123 -0
- package/dist/TagGroup/TagGroup.js +142 -0
- package/dist/TagGroup/TagGroup.manifest.js +35 -0
- package/dist/TagGroup/index.js +7 -0
- package/dist/Textarea/Textarea.js +68 -0
- package/dist/Textarea/Textarea.manifest.js +25 -0
- package/dist/Textarea/index.js +7 -0
- package/dist/TimeField/TimeField.js +118 -0
- package/dist/TimeField/TimeField.manifest.js +42 -0
- package/dist/TimeField/index.js +7 -0
- package/dist/TimeRange/TimeRange.js +184 -0
- package/dist/TimeRange/TimeRange.manifest.js +48 -0
- package/dist/TimeRange/index.js +9 -0
- package/dist/Toast/Toast.js +188 -0
- package/dist/Toast/Toast.manifest.js +77 -0
- package/dist/Toast/index.js +9 -0
- package/dist/Toggle/Toggle.js +154 -0
- package/dist/Toggle/Toggle.manifest.js +54 -0
- package/dist/Toggle/index.js +7 -0
- package/dist/Toolbar/Toolbar.js +86 -0
- package/dist/Toolbar/Toolbar.manifest.js +70 -0
- package/dist/Toolbar/index.js +12 -0
- package/dist/Tooltip/Tooltip.js +123 -0
- package/dist/Tooltip/Tooltip.manifest.js +27 -0
- package/dist/Tooltip/index.js +7 -0
- package/dist/TreeView/TreeView.js +129 -0
- package/dist/TreeView/TreeView.manifest.js +56 -0
- package/dist/TreeView/index.js +7 -0
- package/dist/UploadQueue/UploadQueue.js +296 -0
- package/dist/UploadQueue/UploadQueue.manifest.js +34 -0
- package/dist/UploadQueue/index.js +7 -0
- package/dist/_internal/MotionPopover.js +113 -0
- package/dist/_internal/aria.js +40 -0
- package/dist/_internal/bytes.js +18 -0
- package/dist/_internal/controlStyles.js +26 -0
- package/dist/_internal/date.js +179 -0
- package/dist/_internal/devValidate.js +51 -0
- package/dist/_internal/fieldIds.js +50 -0
- package/dist/_internal/hydration.js +74 -0
- package/dist/_internal/manifest-entry.js +0 -0
- package/dist/_internal/mergeRefs.js +68 -0
- package/dist/_internal/motion.js +138 -0
- package/dist/_internal/navigationLandmark.js +13 -0
- package/dist/_internal/numberText.js +176 -0
- package/dist/_internal/overlay.js +53 -0
- package/dist/_internal/segmentField.js +125 -0
- package/dist/_internal/suggestions.js +20 -0
- package/dist/_internal/timestamp.js +25 -0
- package/dist/_internal/unavailable.js +13 -0
- package/dist/_internal/useActionFocus.js +27 -0
- package/dist/_internal/useElementWidth.js +37 -0
- package/dist/_internal/useIsMounted.js +18 -0
- package/dist/_internal/useIsomorphicLayoutEffect.js +8 -0
- package/dist/_internal/useRestoreFocusOnRemoval.js +57 -0
- package/dist/index.cjs +17831 -0
- package/dist/index.d.cts +2330 -0
- package/dist/index.d.ts +2330 -0
- package/dist/index.js +407 -0
- package/dist/version.js +8 -0
- package/package.json +80 -3
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// src/Popover/Popover.manifest.ts
|
|
2
|
+
var PopoverManifest = {
|
|
3
|
+
Popover: {
|
|
4
|
+
description: "Named nonmodal interactive details anchored to an explicitly activated trigger.",
|
|
5
|
+
props: {
|
|
6
|
+
title: {
|
|
7
|
+
type: "string",
|
|
8
|
+
description: "Visible heading that names the dialog; required unless aria-label is set."
|
|
9
|
+
},
|
|
10
|
+
"aria-label": {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "Name without a visible heading; required unless title is set."
|
|
13
|
+
},
|
|
14
|
+
open: { type: "boolean" },
|
|
15
|
+
defaultOpen: { type: "boolean", default: false },
|
|
16
|
+
onOpenChange: { type: "function" },
|
|
17
|
+
side: { type: "enum", values: ["top", "right", "bottom", "left"], default: "bottom" },
|
|
18
|
+
align: { type: "enum", values: ["start", "center", "end"], default: "start" },
|
|
19
|
+
disabled: { type: "boolean", default: false },
|
|
20
|
+
motion: { type: "enum", values: ["auto", "none"], default: "auto" },
|
|
21
|
+
description: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "Short summary: a tooltip preview on the trigger and a line under the title of the open surface, which it describes. A disabled trigger with a description stays focusable, so focus or a tap shows it."
|
|
24
|
+
},
|
|
25
|
+
returnFocusRef: {
|
|
26
|
+
type: "node",
|
|
27
|
+
description: "RefObject<HTMLElement | null> fallback when the trigger is removed."
|
|
28
|
+
},
|
|
29
|
+
onCloseAutoFocus: { type: "function" },
|
|
30
|
+
className: { type: "string" }
|
|
31
|
+
},
|
|
32
|
+
slots: {
|
|
33
|
+
children: { type: "single focusable trigger element", required: true },
|
|
34
|
+
content: { type: "node", required: true }
|
|
35
|
+
},
|
|
36
|
+
composable_with: [
|
|
37
|
+
"Button",
|
|
38
|
+
"EntityPreview",
|
|
39
|
+
"DescriptionList",
|
|
40
|
+
"CopyButton",
|
|
41
|
+
"Inspector",
|
|
42
|
+
"Tooltip"
|
|
43
|
+
],
|
|
44
|
+
never_inside: ["Tooltip"],
|
|
45
|
+
example: '<Popover title="Equipment details" description="Equipment operational" content={<button>Inspect</button>}><Button>Details</Button></Popover>'
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
export {
|
|
49
|
+
PopoverManifest
|
|
50
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/Progress/Progress.tsx
|
|
4
|
+
import { ProgressBar } from "react-aria-components";
|
|
5
|
+
import { cva } from "class-variance-authority";
|
|
6
|
+
import { forwardRef } from "react";
|
|
7
|
+
import clsx from "clsx";
|
|
8
|
+
import { ProgressManifest } from "./Progress.manifest.js";
|
|
9
|
+
import { devValidate } from "../_internal/devValidate.js";
|
|
10
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
var rootStyles = cva(
|
|
12
|
+
"relative w-full overflow-hidden bg-oprt-surface-2 border border-oprt-border",
|
|
13
|
+
{
|
|
14
|
+
variants: {
|
|
15
|
+
size: {
|
|
16
|
+
sm: "h-1.5u",
|
|
17
|
+
md: "h-2u"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
defaultVariants: { size: "md" }
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
var BLOCK_CELLS = 20;
|
|
24
|
+
var SOLID_FILL = "bg-oprt-accent forced-colors:bg-[CanvasText] forced-colors:[forced-color-adjust:none]";
|
|
25
|
+
var HATCH_FILL = "[--oprt-hatch:var(--oprt-accent)] forced-colors:[--oprt-hatch:CanvasText] forced-colors:[forced-color-adjust:none] [background-image:repeating-linear-gradient(135deg,var(--oprt-hatch)_0,var(--oprt-hatch)_var(--oprt-space-0-5),transparent_var(--oprt-space-0-5),transparent_var(--oprt-space-1))]";
|
|
26
|
+
var SLIDE_STILL = "motion-reduce:animate-none forced-colors:animate-none";
|
|
27
|
+
var BLOCK_HATCH = ["\u259A", "\u259E"];
|
|
28
|
+
var Progress = forwardRef((allProps, ref) => {
|
|
29
|
+
const {
|
|
30
|
+
className,
|
|
31
|
+
value,
|
|
32
|
+
max = 100,
|
|
33
|
+
label,
|
|
34
|
+
showValue = false,
|
|
35
|
+
variant,
|
|
36
|
+
size,
|
|
37
|
+
...props
|
|
38
|
+
} = allProps;
|
|
39
|
+
const blocks = variant === "blocks";
|
|
40
|
+
const sizeKey = size === "sm" ? "sm" : "md";
|
|
41
|
+
const safeMax = Number.isFinite(max) && max > 0 ? max : 100;
|
|
42
|
+
const indeterminate = value == null || !Number.isFinite(value);
|
|
43
|
+
const safeValue = indeterminate ? 0 : Math.min(safeMax, Math.max(0, value));
|
|
44
|
+
const pct = safeValue / safeMax * 100;
|
|
45
|
+
const ariaLabel = props["aria-label"] ?? label ?? "Progress";
|
|
46
|
+
const barProps = { maxValue: safeMax, minValue: 0 };
|
|
47
|
+
if (indeterminate) barProps["isIndeterminate"] = true;
|
|
48
|
+
else barProps["value"] = safeValue;
|
|
49
|
+
const filled = Math.round(pct / 100 * BLOCK_CELLS);
|
|
50
|
+
const fillState = indeterminate ? "indeterminate" : "determinate";
|
|
51
|
+
if (process.env.NODE_ENV !== "production") {
|
|
52
|
+
devValidate("Progress", ProgressManifest.Progress.props, allProps);
|
|
53
|
+
}
|
|
54
|
+
return (
|
|
55
|
+
// The wrapper takes the width its container gives it, in a flex row as in a block: a bar has no
|
|
56
|
+
// width of its own, and without this it was 2 px wide beside other content.
|
|
57
|
+
/* @__PURE__ */ jsxs("div", { className: "flex w-full min-w-0 flex-col gap-1u font-sans", children: [
|
|
58
|
+
(label || showValue) && /* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between gap-x-2u", children: [
|
|
59
|
+
label ? /* @__PURE__ */ jsx("span", { className: "m-0 min-w-0 oprt-wrap-anywhere text-oprt-sm uppercase tracking-oprt-sm text-oprt-text-dim", children: label }) : /* @__PURE__ */ jsx("span", { "aria-hidden": "true" }),
|
|
60
|
+
showValue && /* @__PURE__ */ jsx("span", { className: "m-0 shrink-0 font-mono text-oprt-base text-oprt-text tabular-nums", children: indeterminate ? "\u2014" : `${Math.round(pct)}%` })
|
|
61
|
+
] }),
|
|
62
|
+
/* @__PURE__ */ jsx(
|
|
63
|
+
ProgressBar,
|
|
64
|
+
{
|
|
65
|
+
ref,
|
|
66
|
+
"aria-label": ariaLabel,
|
|
67
|
+
className: blocks ? clsx("font-mono text-oprt-base", className) : clsx(rootStyles({ size: sizeKey }), className),
|
|
68
|
+
...barProps,
|
|
69
|
+
...props,
|
|
70
|
+
children: blocks ? indeterminate ? (
|
|
71
|
+
// An unknown amount is a hatch of alternating quarter blocks: neither the empty glyph
|
|
72
|
+
// of 0% nor the full one of 100%. The fill is as wide as the twenty cells and clips the
|
|
73
|
+
// row, which slides two cells (one repeat, a tenth of its width) at a time; two more
|
|
74
|
+
// cells wait just before its start and slide in, so each loop ends as the next begins.
|
|
75
|
+
/* @__PURE__ */ jsx(
|
|
76
|
+
"span",
|
|
77
|
+
{
|
|
78
|
+
"aria-hidden": "true",
|
|
79
|
+
"data-oprt-progress-fill": fillState,
|
|
80
|
+
className: "flex w-fit max-w-full overflow-hidden",
|
|
81
|
+
children: /* @__PURE__ */ jsxs(
|
|
82
|
+
"span",
|
|
83
|
+
{
|
|
84
|
+
className: clsx(
|
|
85
|
+
"relative flex tracking-oprt-md oprt-motion-slide-[10%]",
|
|
86
|
+
SLIDE_STILL
|
|
87
|
+
),
|
|
88
|
+
children: [
|
|
89
|
+
Array.from({ length: BLOCK_CELLS }, (_, i) => /* @__PURE__ */ jsx("span", { className: "text-oprt-accent", children: BLOCK_HATCH[i % 2] }, i)),
|
|
90
|
+
/* @__PURE__ */ jsx("span", { "data-oprt-progress-tail": "", className: "absolute right-full top-0 flex", children: BLOCK_HATCH.map((glyph) => /* @__PURE__ */ jsx("span", { className: "text-oprt-accent", children: glyph }, glyph)) })
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
)
|
|
96
|
+
) : /* @__PURE__ */ jsx(
|
|
97
|
+
"span",
|
|
98
|
+
{
|
|
99
|
+
"aria-hidden": "true",
|
|
100
|
+
"data-oprt-progress-fill": fillState,
|
|
101
|
+
className: "flex tracking-oprt-md",
|
|
102
|
+
children: Array.from({ length: BLOCK_CELLS }, (_, i) => /* @__PURE__ */ jsx("span", { className: i < filled ? "text-oprt-accent" : "text-oprt-text-dim", children: i < filled ? "\u2588" : "\u2591" }, i))
|
|
103
|
+
}
|
|
104
|
+
) : (
|
|
105
|
+
// RAC has no Indicator part; the fill is a plain element inside the progressbar. A known
|
|
106
|
+
// value slides the fill in from the left; an unknown one covers the track with the hatch,
|
|
107
|
+
// and one repeat more before its start, so the slide never uncovers the track.
|
|
108
|
+
/* @__PURE__ */ jsx(
|
|
109
|
+
"div",
|
|
110
|
+
{
|
|
111
|
+
"data-oprt-progress-fill": fillState,
|
|
112
|
+
className: clsx(
|
|
113
|
+
"h-full",
|
|
114
|
+
indeterminate ? clsx(
|
|
115
|
+
HATCH_FILL,
|
|
116
|
+
"-ml-[var(--oprt-slide-distance)] w-[calc(100%+var(--oprt-slide-distance))] oprt-motion-slide",
|
|
117
|
+
SLIDE_STILL
|
|
118
|
+
) : clsx(SOLID_FILL, "w-full transition-transform duration-oprt-normal")
|
|
119
|
+
),
|
|
120
|
+
...indeterminate ? {} : { style: { transform: `translateX(-${100 - pct}%)` } }
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
)
|
|
126
|
+
] })
|
|
127
|
+
);
|
|
128
|
+
});
|
|
129
|
+
Progress.displayName = "Progress";
|
|
130
|
+
export {
|
|
131
|
+
Progress
|
|
132
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/Progress/Progress.manifest.ts
|
|
2
|
+
var ProgressManifest = {
|
|
3
|
+
Progress: {
|
|
4
|
+
description: "Determinate or indeterminate progress indicator rendered as a filled bar or a row of block glyphs. It fills the width its container gives it.",
|
|
5
|
+
props: {
|
|
6
|
+
value: {
|
|
7
|
+
type: "number",
|
|
8
|
+
description: "Current progress, clamped from 0 to max. Omit or pass a non-finite value for an indeterminate (amount unknown) state: a full-width hatched fill that slides gently and stays a still hatch with reduced motion and in forced colors, so it never looks like 0% or 100%."
|
|
9
|
+
},
|
|
10
|
+
max: {
|
|
11
|
+
type: "number",
|
|
12
|
+
default: 100,
|
|
13
|
+
description: "Finite positive upper bound. Zero, negative, and non-finite values fall back to 100."
|
|
14
|
+
},
|
|
15
|
+
label: {
|
|
16
|
+
type: "string",
|
|
17
|
+
description: "Optional short progress heading, displayed uppercase. Long identifiers wrap beside the value."
|
|
18
|
+
},
|
|
19
|
+
showValue: { type: "boolean", default: false },
|
|
20
|
+
variant: { type: "enum", values: ["bar", "blocks"], default: "bar" },
|
|
21
|
+
size: { type: "enum", values: ["sm", "md"], default: "md" }
|
|
22
|
+
},
|
|
23
|
+
composable_with: ["Card", "Field"],
|
|
24
|
+
never_inside: ["Progress"],
|
|
25
|
+
example: "<Progress value={72} showValue />"
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
export {
|
|
29
|
+
ProgressManifest
|
|
30
|
+
};
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/PropertyFilter/PropertyFilter.tsx
|
|
4
|
+
import {
|
|
5
|
+
forwardRef,
|
|
6
|
+
useEffect,
|
|
7
|
+
useId,
|
|
8
|
+
useImperativeHandle,
|
|
9
|
+
useRef,
|
|
10
|
+
useState
|
|
11
|
+
} from "react";
|
|
12
|
+
import { cva } from "class-variance-authority";
|
|
13
|
+
import clsx from "clsx";
|
|
14
|
+
import { Button } from "../Button/Button.js";
|
|
15
|
+
import { Field } from "../Field/Field.js";
|
|
16
|
+
import { Input } from "../Input/Input.js";
|
|
17
|
+
import { Select, SelectOption } from "../Select/Select.js";
|
|
18
|
+
import { TagGroup } from "../TagGroup/TagGroup.js";
|
|
19
|
+
import { joinIds, usePartIds } from "../_internal/fieldIds.js";
|
|
20
|
+
import { useRestoreFocusOnRemoval } from "../_internal/useRestoreFocusOnRemoval.js";
|
|
21
|
+
import {
|
|
22
|
+
getPropertyFilterTokenError
|
|
23
|
+
} from "./tokenError.js";
|
|
24
|
+
import {
|
|
25
|
+
getPropertyFilterTokenError as getPropertyFilterTokenError2
|
|
26
|
+
} from "./tokenError.js";
|
|
27
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
28
|
+
var filterStyles = cva(
|
|
29
|
+
"flex min-w-0 flex-col gap-2u font-sans normal-case text-oprt-base text-oprt-text"
|
|
30
|
+
);
|
|
31
|
+
var controlStyles = "min-w-[min(100%,calc(24*var(--oprt-space-1)))] max-w-full grow basis-[calc(24*var(--oprt-space-1))]";
|
|
32
|
+
var selectStyles = "w-full min-w-0 max-w-full";
|
|
33
|
+
function tokenLabel(token, fields) {
|
|
34
|
+
const field = fields.find((candidate) => candidate.key === token.field);
|
|
35
|
+
const operator = field?.operators.find((candidate) => candidate.key === token.operator);
|
|
36
|
+
const value = field?.options?.find((option) => option.value === token.value)?.label ?? token.value;
|
|
37
|
+
const label = `${field?.label ?? token.field} ${operator?.label ?? token.operator}${value === null ? "" : ` ${value}`}`;
|
|
38
|
+
const error = getPropertyFilterTokenError(token, fields);
|
|
39
|
+
return error ? `Invalid filter: ${label}. ${error}` : label;
|
|
40
|
+
}
|
|
41
|
+
var PropertyFilter = forwardRef(
|
|
42
|
+
({
|
|
43
|
+
fields,
|
|
44
|
+
value,
|
|
45
|
+
onValueChange,
|
|
46
|
+
label = "Filters",
|
|
47
|
+
disabled = false,
|
|
48
|
+
className,
|
|
49
|
+
id,
|
|
50
|
+
onFocusCapture,
|
|
51
|
+
onBlurCapture,
|
|
52
|
+
"aria-labelledby": labelledBy,
|
|
53
|
+
...props
|
|
54
|
+
}, ref) => {
|
|
55
|
+
const instanceId = useId();
|
|
56
|
+
const root = useRef(null);
|
|
57
|
+
useImperativeHandle(ref, () => root.current, []);
|
|
58
|
+
const ids = usePartIds(["error"], {
|
|
59
|
+
id,
|
|
60
|
+
readRendered: () => root.current?.getAttribute("data-oprt-ids")
|
|
61
|
+
});
|
|
62
|
+
const nextId = useRef(0);
|
|
63
|
+
const addRef = useRef(null);
|
|
64
|
+
const clearRef = useRef(null);
|
|
65
|
+
const composing = useRef(false);
|
|
66
|
+
const pendingAdd = useRef(null);
|
|
67
|
+
const [draft, setDraft] = useState({ field: "", operator: "", value: "" });
|
|
68
|
+
const [error, setError] = useState(null);
|
|
69
|
+
const field = fields.find((candidate) => candidate.key === draft.field);
|
|
70
|
+
const operator = field?.operators.find((candidate) => candidate.key === draft.operator);
|
|
71
|
+
const fault = (control) => error?.control === control ? { invalid: true, "aria-describedby": ids.error } : {};
|
|
72
|
+
const clearLeft = useRef(false);
|
|
73
|
+
const restore = useRestoreFocusOnRemoval(root, {
|
|
74
|
+
track: (element) => element === clearRef.current ? void 0 : null,
|
|
75
|
+
findTarget: () => !clearLeft.current && !disabled && value.tokens.length === 0 ? addRef.current : null
|
|
76
|
+
});
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
const pending = pendingAdd.current;
|
|
79
|
+
if (pending && value.tokens.some(
|
|
80
|
+
(token) => token.id === pending.token.id && token.field === pending.token.field && token.operator === pending.token.operator && token.value === pending.token.value
|
|
81
|
+
)) {
|
|
82
|
+
pendingAdd.current = null;
|
|
83
|
+
setDraft((current) => current === pending.draft ? { ...current, value: "" } : current);
|
|
84
|
+
}
|
|
85
|
+
}, [value]);
|
|
86
|
+
function addFilter() {
|
|
87
|
+
if (disabled || fields.length === 0) return;
|
|
88
|
+
if (!field || !operator) {
|
|
89
|
+
setError({
|
|
90
|
+
message: "Choose a field and operator before adding a filter.",
|
|
91
|
+
control: field ? "operator" : "field"
|
|
92
|
+
});
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
let id2;
|
|
96
|
+
do {
|
|
97
|
+
id2 = `filter-${instanceId}-${++nextId.current}`;
|
|
98
|
+
} while (value.tokens.some((token2) => token2.id === id2));
|
|
99
|
+
const token = {
|
|
100
|
+
id: id2,
|
|
101
|
+
field: field.key,
|
|
102
|
+
operator: operator.key,
|
|
103
|
+
value: operator.requiresValue ? draft.value : null
|
|
104
|
+
};
|
|
105
|
+
const tokenError = getPropertyFilterTokenError(token, fields);
|
|
106
|
+
if (tokenError || operator.requiresValue && field.options?.some((option) => option.value === draft.value && option.disabled)) {
|
|
107
|
+
setError({
|
|
108
|
+
message: tokenError ?? `Choose an available value for ${field.label}.`,
|
|
109
|
+
control: "value"
|
|
110
|
+
});
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
setError(null);
|
|
114
|
+
pendingAdd.current = { token, draft };
|
|
115
|
+
onValueChange({ ...value, tokens: [...value.tokens, token] });
|
|
116
|
+
}
|
|
117
|
+
return /* @__PURE__ */ jsxs(
|
|
118
|
+
"div",
|
|
119
|
+
{
|
|
120
|
+
...props,
|
|
121
|
+
ref: root,
|
|
122
|
+
role: "group",
|
|
123
|
+
id: id ?? (labelledBy ? ids.base : void 0),
|
|
124
|
+
"aria-label": label,
|
|
125
|
+
"aria-labelledby": labelledBy ? joinIds(ids.base, labelledBy) : void 0,
|
|
126
|
+
"data-oprt-ids": ids.base,
|
|
127
|
+
className: clsx(filterStyles(), className),
|
|
128
|
+
onFocusCapture: (event) => {
|
|
129
|
+
onFocusCapture?.(event);
|
|
130
|
+
if (event.target === clearRef.current) clearLeft.current = false;
|
|
131
|
+
restore.onFocusCapture(event);
|
|
132
|
+
},
|
|
133
|
+
onBlurCapture: (event) => {
|
|
134
|
+
onBlurCapture?.(event);
|
|
135
|
+
const clear = clearRef.current;
|
|
136
|
+
if (event.target === clear && clear && !clear.disabled)
|
|
137
|
+
clearLeft.current = true;
|
|
138
|
+
restore.onBlurCapture(event);
|
|
139
|
+
},
|
|
140
|
+
children: [
|
|
141
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-wrap items-end gap-2u", children: [
|
|
142
|
+
/* @__PURE__ */ jsx(Field, { label: "Field", className: controlStyles, children: /* @__PURE__ */ jsx(
|
|
143
|
+
Select,
|
|
144
|
+
{
|
|
145
|
+
value: draft.field,
|
|
146
|
+
placeholder: "Choose field",
|
|
147
|
+
disabled: disabled || fields.length === 0,
|
|
148
|
+
className: selectStyles,
|
|
149
|
+
...fault("field"),
|
|
150
|
+
onValueChange: (key) => {
|
|
151
|
+
if (disabled) return;
|
|
152
|
+
const next = fields.find((candidate) => candidate.key === key);
|
|
153
|
+
setDraft({ field: key, operator: next?.operators[0]?.key ?? "", value: "" });
|
|
154
|
+
setError(null);
|
|
155
|
+
},
|
|
156
|
+
children: fields.map((item) => /* @__PURE__ */ jsx(SelectOption, { value: item.key, children: item.label }, item.key))
|
|
157
|
+
}
|
|
158
|
+
) }),
|
|
159
|
+
/* @__PURE__ */ jsx(Field, { label: "Operator", className: controlStyles, children: /* @__PURE__ */ jsx(
|
|
160
|
+
Select,
|
|
161
|
+
{
|
|
162
|
+
value: draft.operator,
|
|
163
|
+
placeholder: "Choose operator",
|
|
164
|
+
disabled: disabled || !field || !field.operators.length,
|
|
165
|
+
className: selectStyles,
|
|
166
|
+
...fault("operator"),
|
|
167
|
+
onValueChange: (key) => {
|
|
168
|
+
if (disabled) return;
|
|
169
|
+
const next = field?.operators.find((candidate) => candidate.key === key);
|
|
170
|
+
setDraft((current) => ({
|
|
171
|
+
...current,
|
|
172
|
+
operator: key,
|
|
173
|
+
value: operator?.requiresValue === next?.requiresValue ? current.value : ""
|
|
174
|
+
}));
|
|
175
|
+
setError(null);
|
|
176
|
+
},
|
|
177
|
+
children: (field?.operators ?? []).map((item) => /* @__PURE__ */ jsx(SelectOption, { value: item.key, children: item.label }, item.key))
|
|
178
|
+
}
|
|
179
|
+
) }),
|
|
180
|
+
operator?.requiresValue && /* @__PURE__ */ jsx(Field, { label: "Value", className: controlStyles, children: field?.options ? /* @__PURE__ */ jsx(
|
|
181
|
+
Select,
|
|
182
|
+
{
|
|
183
|
+
value: draft.value,
|
|
184
|
+
placeholder: "Choose value",
|
|
185
|
+
disabled,
|
|
186
|
+
className: selectStyles,
|
|
187
|
+
...fault("value"),
|
|
188
|
+
onValueChange: (next) => {
|
|
189
|
+
if (!disabled) {
|
|
190
|
+
setDraft((current) => ({ ...current, value: next }));
|
|
191
|
+
setError(null);
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
children: field.options.map((option) => /* @__PURE__ */ jsx(
|
|
195
|
+
SelectOption,
|
|
196
|
+
{
|
|
197
|
+
value: option.value,
|
|
198
|
+
disabled: !!option.disabled,
|
|
199
|
+
children: option.label
|
|
200
|
+
},
|
|
201
|
+
option.value
|
|
202
|
+
))
|
|
203
|
+
}
|
|
204
|
+
) : /* @__PURE__ */ jsx(
|
|
205
|
+
Input,
|
|
206
|
+
{
|
|
207
|
+
value: draft.value,
|
|
208
|
+
disabled,
|
|
209
|
+
className: "w-full min-w-0",
|
|
210
|
+
...fault("value"),
|
|
211
|
+
onChange: (event) => {
|
|
212
|
+
if (!disabled) {
|
|
213
|
+
setDraft((current) => ({ ...current, value: event.target.value }));
|
|
214
|
+
setError(null);
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
onCompositionStart: () => {
|
|
218
|
+
composing.current = true;
|
|
219
|
+
},
|
|
220
|
+
onCompositionEnd: () => {
|
|
221
|
+
composing.current = false;
|
|
222
|
+
},
|
|
223
|
+
onKeyDown: (event) => {
|
|
224
|
+
if (event.key !== "Enter") return;
|
|
225
|
+
if (composing.current || event.nativeEvent.isComposing || event.keyCode === 229)
|
|
226
|
+
return;
|
|
227
|
+
event.preventDefault();
|
|
228
|
+
addFilter();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
) }),
|
|
232
|
+
/* @__PURE__ */ jsx(
|
|
233
|
+
Button,
|
|
234
|
+
{
|
|
235
|
+
ref: addRef,
|
|
236
|
+
disabled: disabled || fields.length === 0,
|
|
237
|
+
onClick: addFilter,
|
|
238
|
+
"aria-describedby": error ? ids.error : void 0,
|
|
239
|
+
children: "Add filter"
|
|
240
|
+
}
|
|
241
|
+
)
|
|
242
|
+
] }),
|
|
243
|
+
error && /* @__PURE__ */ jsx(
|
|
244
|
+
"p",
|
|
245
|
+
{
|
|
246
|
+
id: ids.error,
|
|
247
|
+
role: "alert",
|
|
248
|
+
className: "m-0 oprt-wrap-anywhere text-oprt-base text-oprt-error",
|
|
249
|
+
children: error.message
|
|
250
|
+
}
|
|
251
|
+
),
|
|
252
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-wrap items-end gap-2u", children: [
|
|
253
|
+
/* @__PURE__ */ jsx(Field, { label: "Match", className: "min-w-0 max-w-full", children: /* @__PURE__ */ jsxs(
|
|
254
|
+
Select,
|
|
255
|
+
{
|
|
256
|
+
value: value.match,
|
|
257
|
+
disabled,
|
|
258
|
+
className: selectStyles,
|
|
259
|
+
onValueChange: (match) => {
|
|
260
|
+
if (!disabled && (match === "all" || match === "any"))
|
|
261
|
+
onValueChange({ ...value, match });
|
|
262
|
+
},
|
|
263
|
+
children: [
|
|
264
|
+
/* @__PURE__ */ jsx(SelectOption, { value: "all", children: "All filters" }),
|
|
265
|
+
/* @__PURE__ */ jsx(SelectOption, { value: "any", children: "Any filter" })
|
|
266
|
+
]
|
|
267
|
+
}
|
|
268
|
+
) }),
|
|
269
|
+
/* @__PURE__ */ jsx(
|
|
270
|
+
Button,
|
|
271
|
+
{
|
|
272
|
+
ref: clearRef,
|
|
273
|
+
variant: "ghost",
|
|
274
|
+
disabled: disabled || value.tokens.length === 0,
|
|
275
|
+
onClick: () => {
|
|
276
|
+
if (disabled || value.tokens.length === 0) return;
|
|
277
|
+
onValueChange({ ...value, tokens: [] });
|
|
278
|
+
},
|
|
279
|
+
children: "Clear filters"
|
|
280
|
+
}
|
|
281
|
+
)
|
|
282
|
+
] }),
|
|
283
|
+
/* @__PURE__ */ jsx(
|
|
284
|
+
TagGroup,
|
|
285
|
+
{
|
|
286
|
+
label: `${label}: active filters`,
|
|
287
|
+
items: value.tokens.map((token) => ({ id: token.id, label: tokenLabel(token, fields) })),
|
|
288
|
+
disabled,
|
|
289
|
+
emptyMessage: "No active filters",
|
|
290
|
+
returnFocusRef: addRef,
|
|
291
|
+
onRemove: (id2) => {
|
|
292
|
+
if (!disabled)
|
|
293
|
+
onValueChange({ ...value, tokens: value.tokens.filter((token) => token.id !== id2) });
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
)
|
|
297
|
+
]
|
|
298
|
+
}
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
);
|
|
302
|
+
PropertyFilter.displayName = "PropertyFilter";
|
|
303
|
+
export {
|
|
304
|
+
PropertyFilter,
|
|
305
|
+
getPropertyFilterTokenError2 as getPropertyFilterTokenError
|
|
306
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/PropertyFilter/PropertyFilter.manifest.ts
|
|
2
|
+
var PropertyFilterManifest = {
|
|
3
|
+
PropertyFilter: {
|
|
4
|
+
description: "Controlled flat property-filter editor with text or enum values, all/any matching and removable, semantically validated clauses.",
|
|
5
|
+
props: {
|
|
6
|
+
fields: {
|
|
7
|
+
type: "array",
|
|
8
|
+
required: true,
|
|
9
|
+
description: "Readonly PropertyFilterField[] with key, label, operators and optional value/label/disabled options. Operators have key, label and requiresValue."
|
|
10
|
+
},
|
|
11
|
+
value: {
|
|
12
|
+
type: "node",
|
|
13
|
+
required: true,
|
|
14
|
+
description: "PropertyFilterValue: match all or any, and readonly tokens containing id, field, operator and string or null value."
|
|
15
|
+
},
|
|
16
|
+
onValueChange: {
|
|
17
|
+
type: "function",
|
|
18
|
+
required: true,
|
|
19
|
+
description: "Requests the complete next value. The parent accepts it through value; declined updates keep tokens and addition drafts."
|
|
20
|
+
},
|
|
21
|
+
label: { type: "string", default: "Filters" },
|
|
22
|
+
disabled: { type: "boolean", default: false },
|
|
23
|
+
className: { type: "string" }
|
|
24
|
+
},
|
|
25
|
+
composable_with: ["TagGroup", "DataGrid", "CollectionState"],
|
|
26
|
+
never_inside: ["Button"],
|
|
27
|
+
example: '<PropertyFilter fields={fields} value={filter} onValueChange={setFilter} label="Equipment filters" />'
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
export {
|
|
31
|
+
PropertyFilterManifest
|
|
32
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// src/PropertyFilter/index.ts
|
|
2
|
+
import { PropertyFilter } from "./PropertyFilter.js";
|
|
3
|
+
import {
|
|
4
|
+
getPropertyFilterTokenError
|
|
5
|
+
} from "./tokenError.js";
|
|
6
|
+
import { PropertyFilterManifest } from "./PropertyFilter.manifest.js";
|
|
7
|
+
export {
|
|
8
|
+
PropertyFilter,
|
|
9
|
+
PropertyFilterManifest,
|
|
10
|
+
getPropertyFilterTokenError
|
|
11
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// src/PropertyFilter/tokenError.ts
|
|
2
|
+
function getPropertyFilterTokenError(token, fields) {
|
|
3
|
+
const field = fields.find((candidate) => candidate.key === token.field);
|
|
4
|
+
if (!field) return `Unknown field: ${token.field}.`;
|
|
5
|
+
const operator = field.operators.find((candidate) => candidate.key === token.operator);
|
|
6
|
+
if (!operator) return `Unknown operator for ${field.label}: ${token.operator}.`;
|
|
7
|
+
if (!operator.requiresValue)
|
|
8
|
+
return token.value === null ? null : `${field.label} ${operator.label} does not accept a value.`;
|
|
9
|
+
if (typeof token.value !== "string" || token.value.trim().length === 0)
|
|
10
|
+
return `Enter a value for ${field.label}.`;
|
|
11
|
+
if (field.options && !field.options.some((option) => option.value === token.value))
|
|
12
|
+
return `Unknown value for ${field.label}: ${token.value}.`;
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
export {
|
|
16
|
+
getPropertyFilterTokenError
|
|
17
|
+
};
|