@oprt/react 0.1.0 → 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.
@@ -1092,7 +1092,7 @@ var Chart = forwardRef((allProps, ref) => {
1092
1092
  variant: "ghost",
1093
1093
  size: "sm",
1094
1094
  className: "min-w-0 max-w-full oprt-wrap-anywhere",
1095
- "aria-label": variant === "heatmap" ? `${seriesNumber.get(item.id)} ${item.label}` : item.label,
1095
+ "aria-label": `${variant === "heatmap" ? `${seriesNumber.get(item.id)} ${item.label}` : item.label}${hidden.has(item.id) ? " Hidden" : ""}`,
1096
1096
  "aria-pressed": !hidden.has(item.id),
1097
1097
  disabled,
1098
1098
  onClick: () => {
@@ -21,9 +21,28 @@ var feedbackStyles = cva("min-w-0 break-words font-sans text-oprt-base normal-ca
21
21
  }
22
22
  }
23
23
  });
24
+ var reportedLabels = /* @__PURE__ */ new Set();
25
+ function reportLabelWithoutVisibleText(label) {
26
+ if (process.env.NODE_ENV === "production" || reportedLabels.has(label)) return;
27
+ reportedLabels.add(label);
28
+ console.error(
29
+ JSON.stringify(
30
+ {
31
+ component: "CopyButton",
32
+ error: "LABEL_OMITS_VISIBLE_TEXT",
33
+ prop: "label",
34
+ received: label,
35
+ suggestion: 'The button shows the word "Copy", so its label must contain it (WCAG 2.5.3, Label in Name). Start the label with it: "Copy equipment ID".'
36
+ },
37
+ null,
38
+ 2
39
+ )
40
+ );
41
+ }
24
42
  var CopyButton = forwardRef((allProps, ref) => {
25
43
  const { value, label, onCopy, onCopyError, disabled = false, size = "md", className } = allProps;
26
44
  const [pending, setPending] = useState(false);
45
+ if (!/copy/i.test(label)) reportLabelWithoutVisibleText(label);
27
46
  const [feedback, setFeedback] = useState(null);
28
47
  const pendingRef = useRef(false);
29
48
  const isMounted = useIsMounted();
@@ -11,7 +11,7 @@ var CopyButtonManifest = {
11
11
  label: {
12
12
  type: "string",
13
13
  required: true,
14
- description: 'Accessible action name identifying the value. Feedback reads this label, then the outcome: "Copy equipment ID: copied".'
14
+ description: 'Accessible action name identifying the value. It must contain "Copy", the word the button shows. Feedback reads this label, then the outcome: "Copy equipment ID: copied".'
15
15
  },
16
16
  size: { type: "enum", values: ["sm", "md", "lg"], default: "md" },
17
17
  disabled: { type: "boolean", default: false },
@@ -165,7 +165,7 @@ var LayerControl = forwardRef(
165
165
  {
166
166
  size: "sm",
167
167
  variant: "tertiary",
168
- "aria-label": `Move ${item.label} up`,
168
+ "aria-label": `Move up ${item.label}`,
169
169
  disabled: !canMove(index, -1),
170
170
  onClick: () => move(index, -1),
171
171
  children: "Move up"
@@ -176,7 +176,7 @@ var LayerControl = forwardRef(
176
176
  {
177
177
  size: "sm",
178
178
  variant: "tertiary",
179
- "aria-label": `Move ${item.label} down`,
179
+ "aria-label": `Move down ${item.label}`,
180
180
  disabled: !canMove(index, 1),
181
181
  onClick: () => move(index, 1),
182
182
  children: "Move down"
@@ -23,6 +23,7 @@ import { isSingleElement, SCREEN_MARGIN, toPlacement, TOOLTIP_WIDTH } from "../_
23
23
  import { FocusableWhenUnavailableProvider } from "../_internal/unavailable.js";
24
24
  import { jsx, jsxs } from "react/jsx-runtime";
25
25
  var PLAIN_TRIGGER = "inline-flex min-h-3u items-center border-0 bg-transparent p-0 [color:inherit] [font:inherit] [letter-spacing:inherit] underline decoration-dotted underline-offset-2 cursor-help outline-hidden focus-visible:shadow-oprt-focus";
26
+ var CLOSE_DELAY = 150;
26
27
  var Tooltip = forwardRef(
27
28
  ({
28
29
  content,
@@ -78,7 +79,7 @@ var Tooltip = forwardRef(
78
79
  isOpen,
79
80
  onOpenChange: setOpen,
80
81
  delay: delayDuration,
81
- closeDelay: 0,
82
+ closeDelay: CLOSE_DELAY,
82
83
  shouldCloseOnPress: !unavailable,
83
84
  children: [
84
85
  unavailable ? /* @__PURE__ */ jsx(FocusableWhenUnavailableProvider, { value: true, children: focusable }) : focusable,
@@ -1,7 +1,7 @@
1
1
  // src/Tooltip/Tooltip.manifest.ts
2
2
  var TooltipManifest = {
3
3
  Tooltip: {
4
- description: "Supplementary text on hover or keyboard focus of a trigger, wrapping at about 20rem. A disabled Button trigger stays focusable and announced unavailable, so focus or a tap shows the explanation. Built on React Aria Components (TooltipTrigger + Tooltip), portal'd, with a bordered surface.",
4
+ description: "Supplementary text on hover or keyboard focus of a trigger, wrapping at about 20rem. The pointer can move onto the tooltip without closing it; it closes 150 ms after the pointer has left both. A disabled Button trigger stays focusable and announced unavailable, so focus or a tap shows the explanation. Built on React Aria Components (TooltipTrigger + Tooltip), portal'd, with a bordered surface.",
5
5
  props: {
6
6
  side: { type: "enum", values: ["top", "right", "bottom", "left"], default: "top" },
7
7
  align: { type: "enum", values: ["start", "center", "end"], default: "center" },
@@ -223,7 +223,7 @@ var UploadQueue = forwardRef(
223
223
  }
224
224
  )
225
225
  ] }),
226
- /* @__PURE__ */ jsx("p", { className: "m-0 text-oprt-text-dim", children: /* @__PURE__ */ jsx(ByteCountLabel, { value: item.sizeBytes }) }),
226
+ /* @__PURE__ */ jsx("p", { className: "m-0 text-oprt-text-dim oprt-wrap-anywhere", children: /* @__PURE__ */ jsx(ByteCountLabel, { value: item.sizeBytes }) }),
227
227
  item.message && /* @__PURE__ */ jsx("p", { className: "m-0 oprt-wrap-anywhere", children: item.message }),
228
228
  transferring && (invalidProgress ? /* @__PURE__ */ jsx("p", { className: "m-0 text-oprt-error", children: "Invalid progress counts." }) : item.totalBytes === 0 ? /* @__PURE__ */ jsx("p", { className: "m-0 text-oprt-text-dim", children: `0${NUMBER_UNIT_SPACE}bytes total; no percentage available.` }) : /* @__PURE__ */ jsxs(Fragment, { children: [
229
229
  /* @__PURE__ */ jsx(
@@ -233,7 +233,7 @@ var UploadQueue = forwardRef(
233
233
  ...item.totalBytes !== void 0 && validLoaded ? { value: item.loadedBytes, max: item.totalBytes } : {}
234
234
  }
235
235
  ),
236
- /* @__PURE__ */ jsxs("p", { className: "m-0 font-mono tabular-nums text-oprt-text-dim", children: [
236
+ /* @__PURE__ */ jsxs("p", { className: "m-0 font-mono tabular-nums text-oprt-text-dim oprt-wrap-anywhere", children: [
237
237
  validLoaded ? `${item.loadedBytes}${NUMBER_UNIT_SPACE}bytes transferred` : "Transferred byte count unavailable",
238
238
  item.totalBytes !== void 0 ? ` of ${item.totalBytes}${NUMBER_UNIT_SPACE}bytes` : "; total unknown",
239
239
  "."
package/dist/index.cjs CHANGED
@@ -7448,7 +7448,7 @@ var import_clsx35 = __toESM(require("clsx"), 1);
7448
7448
  // src/Tooltip/Tooltip.manifest.ts
7449
7449
  var TooltipManifest = {
7450
7450
  Tooltip: {
7451
- description: "Supplementary text on hover or keyboard focus of a trigger, wrapping at about 20rem. A disabled Button trigger stays focusable and announced unavailable, so focus or a tap shows the explanation. Built on React Aria Components (TooltipTrigger + Tooltip), portal'd, with a bordered surface.",
7451
+ description: "Supplementary text on hover or keyboard focus of a trigger, wrapping at about 20rem. The pointer can move onto the tooltip without closing it; it closes 150 ms after the pointer has left both. A disabled Button trigger stays focusable and announced unavailable, so focus or a tap shows the explanation. Built on React Aria Components (TooltipTrigger + Tooltip), portal'd, with a bordered surface.",
7452
7452
  props: {
7453
7453
  side: { type: "enum", values: ["top", "right", "bottom", "left"], default: "top" },
7454
7454
  align: { type: "enum", values: ["start", "center", "end"], default: "center" },
@@ -7473,6 +7473,7 @@ var TooltipManifest = {
7473
7473
  // src/Tooltip/Tooltip.tsx
7474
7474
  var import_jsx_runtime36 = require("react/jsx-runtime");
7475
7475
  var PLAIN_TRIGGER = "inline-flex min-h-3u items-center border-0 bg-transparent p-0 [color:inherit] [font:inherit] [letter-spacing:inherit] underline decoration-dotted underline-offset-2 cursor-help outline-hidden focus-visible:shadow-oprt-focus";
7476
+ var CLOSE_DELAY = 150;
7476
7477
  var Tooltip = (0, import_react51.forwardRef)(
7477
7478
  ({
7478
7479
  content,
@@ -7528,7 +7529,7 @@ var Tooltip = (0, import_react51.forwardRef)(
7528
7529
  isOpen,
7529
7530
  onOpenChange: setOpen,
7530
7531
  delay: delayDuration,
7531
- closeDelay: 0,
7532
+ closeDelay: CLOSE_DELAY,
7532
7533
  shouldCloseOnPress: !unavailable,
7533
7534
  children: [
7534
7535
  unavailable ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(FocusableWhenUnavailableProvider, { value: true, children: focusable }) : focusable,
@@ -9105,7 +9106,7 @@ var Chart = (0, import_react53.forwardRef)((allProps, ref) => {
9105
9106
  variant: "ghost",
9106
9107
  size: "sm",
9107
9108
  className: "min-w-0 max-w-full oprt-wrap-anywhere",
9108
- "aria-label": variant === "heatmap" ? `${seriesNumber.get(item.id)} ${item.label}` : item.label,
9109
+ "aria-label": `${variant === "heatmap" ? `${seriesNumber.get(item.id)} ${item.label}` : item.label}${hidden.has(item.id) ? " Hidden" : ""}`,
9109
9110
  "aria-pressed": !hidden.has(item.id),
9110
9111
  disabled,
9111
9112
  onClick: () => {
@@ -12723,7 +12724,7 @@ var CopyButtonManifest = {
12723
12724
  label: {
12724
12725
  type: "string",
12725
12726
  required: true,
12726
- description: 'Accessible action name identifying the value. Feedback reads this label, then the outcome: "Copy equipment ID: copied".'
12727
+ description: 'Accessible action name identifying the value. It must contain "Copy", the word the button shows. Feedback reads this label, then the outcome: "Copy equipment ID: copied".'
12727
12728
  },
12728
12729
  size: { type: "enum", values: ["sm", "md", "lg"], default: "md" },
12729
12730
  disabled: { type: "boolean", default: false },
@@ -12769,9 +12770,28 @@ var feedbackStyles = (0, import_class_variance_authority37.cva)("min-w-0 break-w
12769
12770
  }
12770
12771
  }
12771
12772
  });
12773
+ var reportedLabels = /* @__PURE__ */ new Set();
12774
+ function reportLabelWithoutVisibleText(label) {
12775
+ if (process.env.NODE_ENV === "production" || reportedLabels.has(label)) return;
12776
+ reportedLabels.add(label);
12777
+ console.error(
12778
+ JSON.stringify(
12779
+ {
12780
+ component: "CopyButton",
12781
+ error: "LABEL_OMITS_VISIBLE_TEXT",
12782
+ prop: "label",
12783
+ received: label,
12784
+ suggestion: 'The button shows the word "Copy", so its label must contain it (WCAG 2.5.3, Label in Name). Start the label with it: "Copy equipment ID".'
12785
+ },
12786
+ null,
12787
+ 2
12788
+ )
12789
+ );
12790
+ }
12772
12791
  var CopyButton = (0, import_react72.forwardRef)((allProps, ref) => {
12773
12792
  const { value, label, onCopy, onCopyError, disabled = false, size = "md", className } = allProps;
12774
12793
  const [pending, setPending] = (0, import_react72.useState)(false);
12794
+ if (!/copy/i.test(label)) reportLabelWithoutVisibleText(label);
12775
12795
  const [feedback, setFeedback] = (0, import_react72.useState)(null);
12776
12796
  const pendingRef = (0, import_react72.useRef)(false);
12777
12797
  const isMounted = useIsMounted();
@@ -15551,7 +15571,7 @@ var UploadQueue = (0, import_react86.forwardRef)(
15551
15571
  }
15552
15572
  )
15553
15573
  ] }),
15554
- /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: "m-0 text-oprt-text-dim", children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ByteCountLabel, { value: item.sizeBytes }) }),
15574
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: "m-0 text-oprt-text-dim oprt-wrap-anywhere", children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ByteCountLabel, { value: item.sizeBytes }) }),
15555
15575
  item.message && /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: "m-0 oprt-wrap-anywhere", children: item.message }),
15556
15576
  transferring && (invalidProgress ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: "m-0 text-oprt-error", children: "Invalid progress counts." }) : item.totalBytes === 0 ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { className: "m-0 text-oprt-text-dim", children: `0${NUMBER_UNIT_SPACE}bytes total; no percentage available.` }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)(import_jsx_runtime70.Fragment, { children: [
15557
15577
  /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(
@@ -15561,7 +15581,7 @@ var UploadQueue = (0, import_react86.forwardRef)(
15561
15581
  ...item.totalBytes !== void 0 && validLoaded ? { value: item.loadedBytes, max: item.totalBytes } : {}
15562
15582
  }
15563
15583
  ),
15564
- /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("p", { className: "m-0 font-mono tabular-nums text-oprt-text-dim", children: [
15584
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("p", { className: "m-0 font-mono tabular-nums text-oprt-text-dim oprt-wrap-anywhere", children: [
15565
15585
  validLoaded ? `${item.loadedBytes}${NUMBER_UNIT_SPACE}bytes transferred` : "Transferred byte count unavailable",
15566
15586
  item.totalBytes !== void 0 ? ` of ${item.totalBytes}${NUMBER_UNIT_SPACE}bytes` : "; total unknown",
15567
15587
  "."
@@ -16813,7 +16833,7 @@ var LayerControl = (0, import_react92.forwardRef)(
16813
16833
  {
16814
16834
  size: "sm",
16815
16835
  variant: "tertiary",
16816
- "aria-label": `Move ${item.label} up`,
16836
+ "aria-label": `Move up ${item.label}`,
16817
16837
  disabled: !canMove(index, -1),
16818
16838
  onClick: () => move(index, -1),
16819
16839
  children: "Move up"
@@ -16824,7 +16844,7 @@ var LayerControl = (0, import_react92.forwardRef)(
16824
16844
  {
16825
16845
  size: "sm",
16826
16846
  variant: "tertiary",
16827
- "aria-label": `Move ${item.label} down`,
16847
+ "aria-label": `Move down ${item.label}`,
16828
16848
  disabled: !canMove(index, 1),
16829
16849
  onClick: () => move(index, 1),
16830
16850
  children: "Move down"
@@ -17621,7 +17641,7 @@ var PlaybackControlsManifest = {
17621
17641
  };
17622
17642
 
17623
17643
  // package.json
17624
- var version3 = "0.1.0";
17644
+ var version3 = "0.2.0";
17625
17645
 
17626
17646
  // src/version.ts
17627
17647
  var VERSION = version3;
package/dist/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // package.json
2
- var version = "0.1.0";
2
+ var version = "0.2.0";
3
3
 
4
4
  // src/version.ts
5
5
  var VERSION = version;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oprt/react",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "React components for operational interfaces: command, control and industrial software. 75 component families with interactive behavior from React Aria, styled with Tailwind CSS 4.",
5
5
  "keywords": [
6
6
  "design-system",
@@ -50,7 +50,7 @@
50
50
  "react-aria": "^3.51.0",
51
51
  "react-aria-components": "^1.20.0",
52
52
  "@oprt/icons": "0.1.0",
53
- "@oprt/tokens": "0.1.0"
53
+ "@oprt/tokens": "0.2.0"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@testing-library/jest-dom": "^6.6.3",