@oprt/react 0.2.0 → 0.3.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/README.md +2 -1
- package/dist/ActionStatus/ActionStatus.js +15 -4
- package/dist/Alert/Alert.js +21 -12
- package/dist/AttachmentPreview/AttachmentPreview.js +15 -12
- package/dist/Chart/Chart.js +9 -1
- package/dist/EventTimeline/EventTimeline.js +9 -1
- package/dist/Popover/Popover.js +6 -5
- package/dist/Tabs/useTabsIndicator.js +1 -1
- package/dist/Toast/Toast.js +1 -1
- package/dist/_internal/hydration.js +2 -2
- package/dist/_internal/liveRegion.js +27 -0
- package/dist/_internal/motion.js +2 -2
- package/dist/index.cjs +721 -661
- package/dist/version.js +1 -1
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -35,7 +35,8 @@ import "@oprt/tokens";
|
|
|
35
35
|
import "./globals.css";
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
Load the tokens from
|
|
38
|
+
Load the tokens from
|
|
39
|
+
JavaScript or a `<link>`, not with an `@import` inside the Tailwind
|
|
39
40
|
stylesheet: the Tailwind CLI inlines an imported file without rewriting its font URLs, and the
|
|
40
41
|
bundled fonts would not load. Inside Tailwind Typography's `prose`, wrap components in an element
|
|
41
42
|
with the `not-prose` class.
|
|
@@ -8,6 +8,7 @@ import { Badge } from "../Badge/Badge.js";
|
|
|
8
8
|
import { Button } from "../Button/Button.js";
|
|
9
9
|
import { useActionFocus } from "../_internal/useActionFocus.js";
|
|
10
10
|
import { devValidate } from "../_internal/devValidate.js";
|
|
11
|
+
import { useHoldBackNewText } from "../_internal/liveRegion.js";
|
|
11
12
|
import { ActionStatusManifest } from "./ActionStatus.manifest.js";
|
|
12
13
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
14
|
var statusStyles = cva(
|
|
@@ -34,6 +35,8 @@ function ActionStatusLine({
|
|
|
34
35
|
requestId,
|
|
35
36
|
children
|
|
36
37
|
}) {
|
|
38
|
+
const spoken = [`${label}, ${state}.`, requestId && `Request: ${requestId}.`, message].filter(Boolean).join(" ");
|
|
39
|
+
const holdBack = useHoldBackNewText(true);
|
|
37
40
|
return /* @__PURE__ */ jsxs(
|
|
38
41
|
"div",
|
|
39
42
|
{
|
|
@@ -42,13 +45,21 @@ function ActionStatusLine({
|
|
|
42
45
|
"aria-atomic": "true",
|
|
43
46
|
className: "flex min-w-0 flex-col gap-1u",
|
|
44
47
|
children: [
|
|
45
|
-
/* @__PURE__ */ jsx("span", { className: "
|
|
46
|
-
/* @__PURE__ */ jsx(
|
|
47
|
-
|
|
48
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: holdBack ? null : spoken }),
|
|
49
|
+
/* @__PURE__ */ jsx(
|
|
50
|
+
"span",
|
|
51
|
+
{
|
|
52
|
+
"aria-hidden": "true",
|
|
53
|
+
className: "min-w-0 oprt-wrap-anywhere font-medium uppercase tracking-oprt-caps",
|
|
54
|
+
children: label
|
|
55
|
+
}
|
|
56
|
+
),
|
|
57
|
+
/* @__PURE__ */ jsx("div", { "aria-hidden": "true", children: /* @__PURE__ */ jsx(Badge, { variant: variants[state], indicator: "dot", children: state }) }),
|
|
58
|
+
requestId && /* @__PURE__ */ jsxs("span", { "aria-hidden": "true", className: "min-w-0 oprt-wrap-anywhere font-mono", children: [
|
|
48
59
|
"Request: ",
|
|
49
60
|
requestId
|
|
50
61
|
] }),
|
|
51
|
-
message && /* @__PURE__ */ jsx("p", { className: "m-0 min-w-0 oprt-wrap-anywhere", children: message }),
|
|
62
|
+
message && /* @__PURE__ */ jsx("p", { "aria-hidden": "true", className: "m-0 min-w-0 oprt-wrap-anywhere", children: message }),
|
|
52
63
|
children
|
|
53
64
|
]
|
|
54
65
|
}
|
package/dist/Alert/Alert.js
CHANGED
|
@@ -7,6 +7,7 @@ import { forwardRef } from "react";
|
|
|
7
7
|
import clsx from "clsx";
|
|
8
8
|
import { AlertManifest } from "./Alert.manifest.js";
|
|
9
9
|
import { devValidate } from "../_internal/devValidate.js";
|
|
10
|
+
import { useHoldBackNewText } from "../_internal/liveRegion.js";
|
|
10
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
12
|
var ICONS = {
|
|
12
13
|
info: Info,
|
|
@@ -48,6 +49,7 @@ var Alert = forwardRef((allProps, ref) => {
|
|
|
48
49
|
...props
|
|
49
50
|
} = allProps;
|
|
50
51
|
const role = variant === "error" || variant === "warning" ? "alert" : "status";
|
|
52
|
+
const holdBack = useHoldBackNewText(role === "status");
|
|
51
53
|
const Icon = ICONS[variant];
|
|
52
54
|
const hasBody = children != null && typeof children !== "boolean" && children !== "";
|
|
53
55
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -55,19 +57,26 @@ var Alert = forwardRef((allProps, ref) => {
|
|
|
55
57
|
}
|
|
56
58
|
return /* @__PURE__ */ jsxs("div", { ref, role, className: clsx(containerStyles({ variant }), className), ...props, children: [
|
|
57
59
|
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: clsx("shrink-0", accentStyles({ variant })), children: /* @__PURE__ */ jsx(Icon, { size: 16 }) }),
|
|
58
|
-
/* @__PURE__ */ jsxs(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
/* @__PURE__ */ jsxs(
|
|
61
|
+
"div",
|
|
62
|
+
{
|
|
63
|
+
className: "flex min-w-0 flex-1 flex-col gap-1u oprt-wrap-anywhere",
|
|
64
|
+
...holdBack ? { "aria-hidden": true } : {},
|
|
65
|
+
children: [
|
|
66
|
+
title && /* @__PURE__ */ jsx(
|
|
67
|
+
"p",
|
|
68
|
+
{
|
|
69
|
+
className: clsx(
|
|
70
|
+
"m-0 text-oprt-sm uppercase tracking-oprt-sm",
|
|
71
|
+
accentStyles({ variant })
|
|
72
|
+
),
|
|
73
|
+
children: title
|
|
74
|
+
}
|
|
65
75
|
),
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
] }),
|
|
76
|
+
hasBody && /* @__PURE__ */ jsx("div", { className: "text-oprt-base normal-case text-oprt-text", children })
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
),
|
|
71
80
|
dismissible && /* @__PURE__ */ jsx(
|
|
72
81
|
"button",
|
|
73
82
|
{
|
|
@@ -77,18 +77,21 @@ var AttachmentPreview = forwardRef(
|
|
|
77
77
|
/* @__PURE__ */ jsx("span", { className: "oprt-wrap-anywhere", children: attachment.mediaType })
|
|
78
78
|
] })
|
|
79
79
|
] }),
|
|
80
|
-
preview.kind === "image" &&
|
|
81
|
-
"
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
80
|
+
preview.kind === "image" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
81
|
+
/* @__PURE__ */ jsx("p", { role: "status", className: imageError ? "m-0 text-oprt-error" : "sr-only", children: imageError }),
|
|
82
|
+
!imageError && /* @__PURE__ */ jsx(
|
|
83
|
+
"img",
|
|
84
|
+
{
|
|
85
|
+
src: preview.src,
|
|
86
|
+
alt: preview.alt,
|
|
87
|
+
onError: () => setImageState(
|
|
88
|
+
(current) => current.key === imageKey ? { key: imageKey, failed: true } : current
|
|
89
|
+
),
|
|
90
|
+
className: clsx(PREVIEW_HEIGHT, "max-w-full self-start object-contain")
|
|
91
|
+
},
|
|
92
|
+
imageKey
|
|
93
|
+
)
|
|
94
|
+
] }),
|
|
92
95
|
preview.kind === "text" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
93
96
|
/* @__PURE__ */ jsx(
|
|
94
97
|
"pre",
|
package/dist/Chart/Chart.js
CHANGED
|
@@ -874,7 +874,15 @@ var Chart = forwardRef((allProps, ref) => {
|
|
|
874
874
|
onBlur: () => setInspectionFocused(false)
|
|
875
875
|
}
|
|
876
876
|
),
|
|
877
|
-
|
|
877
|
+
/* @__PURE__ */ jsx(
|
|
878
|
+
"p",
|
|
879
|
+
{
|
|
880
|
+
role: "status",
|
|
881
|
+
className: empty ? "m-0 py-6u text-oprt-base text-oprt-text-dim" : "sr-only",
|
|
882
|
+
children: empty
|
|
883
|
+
}
|
|
884
|
+
),
|
|
885
|
+
empty ? null : /* @__PURE__ */ jsxs(
|
|
878
886
|
"svg",
|
|
879
887
|
{
|
|
880
888
|
role: "img",
|
|
@@ -172,7 +172,15 @@ var EventTimeline = forwardRef(
|
|
|
172
172
|
"aria-label": label,
|
|
173
173
|
className: clsx(timelineStyles(), className),
|
|
174
174
|
children: [
|
|
175
|
-
|
|
175
|
+
/* @__PURE__ */ jsx(
|
|
176
|
+
"p",
|
|
177
|
+
{
|
|
178
|
+
role: "status",
|
|
179
|
+
className: !validRange ? "m-0 text-oprt-base text-oprt-text-dim" : "sr-only",
|
|
180
|
+
children: !validRange ? "Choose a valid time range with start before end." : ""
|
|
181
|
+
}
|
|
182
|
+
),
|
|
183
|
+
!validRange ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
176
184
|
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap justify-between gap-1u font-mono text-oprt-base text-oprt-text-dim", children: [
|
|
177
185
|
/* @__PURE__ */ jsx("time", { dateTime: new Date(start).toISOString(), children: utc(start) }),
|
|
178
186
|
/* @__PURE__ */ jsx("time", { dateTime: new Date(end).toISOString(), children: utc(end) })
|
package/dist/Popover/Popover.js
CHANGED
|
@@ -69,11 +69,12 @@ var Popover = forwardRef(
|
|
|
69
69
|
const dialog = useRef(null);
|
|
70
70
|
const lastDialog = useRef(null);
|
|
71
71
|
const wasOpen = useRef(false);
|
|
72
|
-
const focusFrame = useRef();
|
|
72
|
+
const focusFrame = useRef(void 0);
|
|
73
73
|
const focusScrollClose = useRef(false);
|
|
74
74
|
const current = useRef({ isOpen, onCloseAutoFocus, returnFocusRef });
|
|
75
75
|
current.current = { isOpen, onCloseAutoFocus, returnFocusRef };
|
|
76
|
-
const
|
|
76
|
+
const triggerChild = children;
|
|
77
|
+
const childRef = parseInt(version, 10) < 19 ? triggerChild.ref : triggerChild.props.ref;
|
|
77
78
|
const rememberTrigger = useCallback((node) => {
|
|
78
79
|
trigger.current = node;
|
|
79
80
|
if (node) lastTrigger.current = node;
|
|
@@ -209,10 +210,10 @@ var Popover = forwardRef(
|
|
|
209
210
|
document.removeEventListener("pointercancel", cancel, true);
|
|
210
211
|
};
|
|
211
212
|
}, [isOpen, requestOpen]);
|
|
212
|
-
const triggerElement = cloneElement(
|
|
213
|
+
const triggerElement = cloneElement(triggerChild, {
|
|
213
214
|
ref: setTrigger,
|
|
214
|
-
disabled: disabled ||
|
|
215
|
-
"aria-disabled": disabled ||
|
|
215
|
+
disabled: disabled || triggerChild.props.disabled,
|
|
216
|
+
"aria-disabled": disabled || triggerChild.props["aria-disabled"],
|
|
216
217
|
"aria-controls": isOpen ? id : void 0
|
|
217
218
|
});
|
|
218
219
|
const pressable = /* @__PURE__ */ jsx(Pressable, { isDisabled: disabled, children: triggerElement });
|
|
@@ -6,7 +6,7 @@ import { createResizeObserver } from "../_internal/useElementWidth.js";
|
|
|
6
6
|
import { useIsomorphicLayoutEffect } from "../_internal/useIsomorphicLayoutEffect.js";
|
|
7
7
|
function useTabsIndicator(list, vertical) {
|
|
8
8
|
const [geometry, setGeometry] = useState();
|
|
9
|
-
const selectedId = useRef();
|
|
9
|
+
const selectedId = useRef(void 0);
|
|
10
10
|
useIsomorphicLayoutEffect(() => {
|
|
11
11
|
const node = list.current;
|
|
12
12
|
if (!node) return;
|
package/dist/Toast/Toast.js
CHANGED
|
@@ -165,7 +165,7 @@ var Toast = forwardRef((allProps, ref) => {
|
|
|
165
165
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 select-text flex-col gap-1u oprt-wrap-anywhere", children: [
|
|
166
166
|
/* @__PURE__ */ jsx(RadixToast.Title, { className: titleStyles({ variant: severity }), children: title }),
|
|
167
167
|
description && /* @__PURE__ */ jsxs(RadixToast.Description, { className: "m-0 text-oprt-base normal-case text-oprt-text", children: [
|
|
168
|
-
/* @__PURE__ */ jsx("span", {
|
|
168
|
+
/* @__PURE__ */ jsx("span", { "data-radix-toast-announce-exclude": "", "data-radix-toast-announce-alt": ". " }),
|
|
169
169
|
description
|
|
170
170
|
] })
|
|
171
171
|
] }),
|
|
@@ -35,11 +35,11 @@ function warnProbeMissing(origin) {
|
|
|
35
35
|
function useHydrationRoot(...forwardedIds) {
|
|
36
36
|
const probe = useId();
|
|
37
37
|
const hydrated = useSyncExternalStore(subscribeNoop, getClientSnapshot, getServerSnapshot);
|
|
38
|
-
const hydratingMount = useRef();
|
|
38
|
+
const hydratingMount = useRef(void 0);
|
|
39
39
|
if (hydratingMount.current === void 0) hydratingMount.current = !hydrated;
|
|
40
40
|
const [disagrees, setDisagrees] = useState(false);
|
|
41
41
|
const clientOnly = useRef(hydrated);
|
|
42
|
-
const origin = useRef();
|
|
42
|
+
const origin = useRef(void 0);
|
|
43
43
|
if (process.env.NODE_ENV !== "production" && origin.current === void 0) {
|
|
44
44
|
origin.current = callerOfHook();
|
|
45
45
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/_internal/liveRegion.ts
|
|
4
|
+
import { useEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
5
|
+
var neverChanges = () => () => {
|
|
6
|
+
};
|
|
7
|
+
var LIVE_REGION_LEAD_MS = 100;
|
|
8
|
+
function useHoldBackNewText(enabled) {
|
|
9
|
+
const hydrating = useSyncExternalStore(
|
|
10
|
+
neverChanges,
|
|
11
|
+
() => false,
|
|
12
|
+
() => true
|
|
13
|
+
);
|
|
14
|
+
const lateArrival = useRef(null);
|
|
15
|
+
if (lateArrival.current === null) lateArrival.current = !hydrating;
|
|
16
|
+
const [held, setHeld] = useState(Boolean(lateArrival.current));
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!held) return;
|
|
19
|
+
const timer = window.setTimeout(() => setHeld(false), LIVE_REGION_LEAD_MS);
|
|
20
|
+
return () => window.clearTimeout(timer);
|
|
21
|
+
}, [held]);
|
|
22
|
+
return enabled && held;
|
|
23
|
+
}
|
|
24
|
+
export {
|
|
25
|
+
LIVE_REGION_LEAD_MS,
|
|
26
|
+
useHoldBackNewText
|
|
27
|
+
};
|
package/dist/_internal/motion.js
CHANGED
|
@@ -25,8 +25,8 @@ function useMotion(mode = "auto", component) {
|
|
|
25
25
|
const [ready, setReady] = useState(false);
|
|
26
26
|
const [keyboard, setKeyboard] = useState(false);
|
|
27
27
|
const pointer = useRef(false);
|
|
28
|
-
const frame = useRef();
|
|
29
|
-
const contactCleanup = useRef();
|
|
28
|
+
const frame = useRef(void 0);
|
|
29
|
+
const contactCleanup = useRef(void 0);
|
|
30
30
|
const clearContact = useCallback(() => {
|
|
31
31
|
contactCleanup.current?.();
|
|
32
32
|
contactCleanup.current = void 0;
|