@wallarm-org/design-system 0.71.0 → 0.71.1

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.
@@ -1,5 +1,6 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { useCallback, useRef } from "react";
3
+ import { composeRefs } from "@radix-ui/react-compose-refs";
3
4
  import { useControlled } from "../../hooks/index.js";
4
5
  import { cn } from "../../utils/cn.js";
5
6
  import { hasTextSelection } from "../../utils/hasTextSelection.js";
@@ -77,19 +78,18 @@ const ParameterPath = ({ ref, method, segments, encoding, attack = false, expand
77
78
  "data-slot": "parameter-path",
78
79
  "data-truncated": isTruncated || void 0,
79
80
  "data-expanded": isExpanded || void 0,
80
- ref: ref,
81
+ ref: composeRefs(ref, containerRef),
81
82
  onCopy: handleCopy,
82
83
  role: interactive ? 'button' : void 0,
83
84
  tabIndex: interactive ? 0 : void 0,
84
85
  "aria-expanded": interactive ? isExpanded : void 0,
85
86
  onClick: interactive ? toggleExpanded : void 0,
86
87
  onKeyDown: interactive ? handleKeyDown : void 0,
87
- className: cn('relative flex items-center min-w-0', interactive && 'cursor-pointer', className),
88
+ className: cn('relative flex w-full items-center min-w-0', interactive && 'cursor-pointer', className),
88
89
  children: /*#__PURE__*/ jsxs(TestIdProvider, {
89
90
  value: testId,
90
91
  children: [
91
92
  /*#__PURE__*/ jsx(ParameterPathRow, {
92
- ref: containerRef,
93
93
  forMeasurement: false,
94
94
  isExpanded: isExpanded,
95
95
  indices: indices,
@@ -42,17 +42,22 @@ const ParameterPathRow = ({ ref, method, segments, encoding, attack, forMeasurem
42
42
  "data-measure": measure(MEASURE.encoding),
43
43
  children: encoding
44
44
  }, "enc"));
45
- if (forMeasurement) return /*#__PURE__*/ jsx("div", {
46
- ref: ref,
47
- "data-slot": "parameter-path-row",
48
- "data-row": ROW.measure,
49
- "aria-hidden": "true",
50
- className: "flex items-center gap-0 absolute left-[-9999px] top-0 invisible pointer-events-none",
51
- children: /*#__PURE__*/ jsx(TestIdProvider, {
52
- value: void 0,
53
- children: items
54
- })
55
- });
45
+ if (forMeasurement) {
46
+ items.push(/*#__PURE__*/ jsx(ParameterPathEllipsis, {
47
+ "data-measure": MEASURE.ellipsis
48
+ }, "measure-ellipsis"));
49
+ return /*#__PURE__*/ jsx("div", {
50
+ ref: ref,
51
+ "data-slot": "parameter-path-row",
52
+ "data-row": ROW.measure,
53
+ "aria-hidden": "true",
54
+ className: "flex items-center gap-0 absolute left-[-9999px] top-0 invisible pointer-events-none",
55
+ children: /*#__PURE__*/ jsx(TestIdProvider, {
56
+ value: void 0,
57
+ children: items
58
+ })
59
+ });
60
+ }
56
61
  return /*#__PURE__*/ jsx("div", {
57
62
  ref: ref,
58
63
  "data-slot": "parameter-path-row",
@@ -3,6 +3,7 @@ export declare const MEASURE: {
3
3
  readonly joint: "joint";
4
4
  readonly segment: "segment";
5
5
  readonly encoding: "encoding";
6
+ readonly ellipsis: "ellipsis";
6
7
  };
7
8
  export declare const ROW: {
8
9
  readonly visible: "visible";
@@ -2,7 +2,8 @@ const MEASURE = {
2
2
  method: 'method',
3
3
  joint: 'joint',
4
4
  segment: 'segment',
5
- encoding: 'encoding'
5
+ encoding: 'encoding',
6
+ ellipsis: 'ellipsis'
6
7
  };
7
8
  const ROW = {
8
9
  visible: 'visible',
@@ -5,12 +5,14 @@ interface ComputeArgs {
5
5
  encodingWidth: number;
6
6
  segmentWidths: number[];
7
7
  jointsWidth: number;
8
+ jointWidth: number;
9
+ ellipsisWidth: number;
8
10
  }
9
11
  interface TruncationResult {
10
12
  isTruncated: boolean;
11
13
  visibleSegmentIndices: number[];
12
14
  }
13
- export declare const computeTruncation: ({ containerWidth, methodWidth, encodingWidth, segmentWidths, jointsWidth, }: ComputeArgs) => TruncationResult;
15
+ export declare const computeTruncation: ({ containerWidth, methodWidth, encodingWidth, segmentWidths, jointsWidth, jointWidth, ellipsisWidth, }: ComputeArgs) => TruncationResult;
14
16
  interface UseTruncationArgs {
15
17
  containerRef: RefObject<HTMLElement | null>;
16
18
  measurementRef: RefObject<HTMLElement | null>;
@@ -2,7 +2,8 @@ import { useLayoutEffect, useState } from "react";
2
2
  import { range } from "../../utils/range.js";
3
3
  import { useContainerWidth } from "../Table/lib/useContainerWidth.js";
4
4
  import { MEASURE } from "./constants.js";
5
- const computeTruncation = ({ containerWidth, methodWidth, encodingWidth, segmentWidths, jointsWidth })=>{
5
+ const EPSILON = 1;
6
+ const computeTruncation = ({ containerWidth, methodWidth, encodingWidth, segmentWidths, jointsWidth, jointWidth, ellipsisWidth })=>{
6
7
  const segCount = segmentWidths.length;
7
8
  const allIndices = range(segCount);
8
9
  if (segCount <= 2 || containerWidth <= 0) return {
@@ -10,7 +11,13 @@ const computeTruncation = ({ containerWidth, methodWidth, encodingWidth, segment
10
11
  visibleSegmentIndices: allIndices
11
12
  };
12
13
  const totalWidth = methodWidth + encodingWidth + segmentWidths.reduce((acc, w)=>acc + w, 0) + jointsWidth;
13
- if (totalWidth <= containerWidth) return {
14
+ if (totalWidth <= containerWidth + EPSILON) return {
15
+ isTruncated: false,
16
+ visibleSegmentIndices: allIndices
17
+ };
18
+ const middleWidth = segmentWidths.slice(1, -1).reduce((acc, w)=>acc + w, 0) + (segCount - 3) * jointWidth;
19
+ const collapsedWidth = totalWidth - middleWidth + ellipsisWidth;
20
+ if (collapsedWidth + EPSILON >= totalWidth) return {
14
21
  isTruncated: false,
15
22
  visibleSegmentIndices: allIndices
16
23
  };
@@ -34,18 +41,22 @@ const useParameterPathTruncation = ({ containerRef, measurementRef, segmentCount
34
41
  if (!root) return;
35
42
  const methodEl = root.querySelector(`[data-measure="${MEASURE.method}"]`);
36
43
  const encodingEl = root.querySelector(`[data-measure="${MEASURE.encoding}"]`);
44
+ const ellipsisEl = root.querySelector(`[data-measure="${MEASURE.ellipsis}"]`);
37
45
  const jointEls = Array.from(root.querySelectorAll(`[data-measure="${MEASURE.joint}"]`));
38
46
  const segmentEls = Array.from(root.querySelectorAll(`[data-measure="${MEASURE.segment}"]`));
39
47
  const segmentWidths = segmentEls.map((el)=>el.getBoundingClientRect().width);
40
48
  const methodWidth = hasMethod && methodEl ? methodEl.getBoundingClientRect().width : 0;
41
49
  const encodingWidth = hasEncoding && encodingEl ? encodingEl.getBoundingClientRect().width : 0;
42
- const jointsWidth = jointEls.reduce((acc, el)=>acc + el.getBoundingClientRect().width, 0);
50
+ const jointWidths = jointEls.map((el)=>el.getBoundingClientRect().width);
51
+ const jointsWidth = jointWidths.reduce((acc, w)=>acc + w, 0);
43
52
  const next = computeTruncation({
44
53
  containerWidth,
45
54
  methodWidth,
46
55
  encodingWidth,
47
56
  segmentWidths,
48
- jointsWidth
57
+ jointsWidth,
58
+ jointWidth: jointWidths[0] ?? 0,
59
+ ellipsisWidth: ellipsisEl?.getBoundingClientRect().width ?? 0
49
60
  });
50
61
  setResult((prev)=>prev.isTruncated === next.isTruncated && indicesEqual(prev.visibleSegmentIndices, next.visibleSegmentIndices) ? prev : next);
51
62
  }, [
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "0.70.0",
3
- "generatedAt": "2026-07-02T11:59:11.867Z",
2
+ "version": "0.71.0",
3
+ "generatedAt": "2026-07-02T15:16:13.659Z",
4
4
  "components": [
5
5
  {
6
6
  "name": "Accordion",
@@ -44886,6 +44886,10 @@
44886
44886
  },
44887
44887
  {
44888
44888
  "name": "ExpandableTruncated",
44889
+ "code": "() => (\n <div style={{ width: 600 }}>\n {/* The root is w-full (it must span the available space to measure it),\n so centering happens inside the component, not on the container. */}\n <ParameterPath\n className='justify-center'\n method='POST'\n segments={[\n 'multipart',\n 'json_abc',\n 'json_doc',\n 'qwerty_doc',\n 'hash',\n 'formData',\n 'session_token',\n 'nested_payload',\n 'get',\n ]}\n attack\n expandable\n />\n </div>\n)"
44890
+ },
44891
+ {
44892
+ "name": "ExpandableFitsInline",
44889
44893
  "code": "() => (\n <div style={{ width: 720, display: 'flex', justifyContent: 'center' }}>\n <ParameterPath\n method='POST'\n segments={['multipart', 'json_abc', 'json_doc', 'qwerty_doc', 'hash', 'formData', 'get']}\n attack\n expandable\n />\n </div>\n)"
44890
44894
  },
44891
44895
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wallarm-org/design-system",
3
- "version": "0.71.0",
3
+ "version": "0.71.1",
4
4
  "description": "Core design system library with React components and Storybook documentation",
5
5
  "publishConfig": {
6
6
  "access": "public",