@tonyarbor/components 0.2.1 → 0.4.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.
@@ -0,0 +1,7 @@
1
+ import {
2
+ SearchOnPage
3
+ } from "./chunk-B7RX3TPX.mjs";
4
+ export {
5
+ SearchOnPage
6
+ };
7
+ //# sourceMappingURL=SearchOnPage.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,135 @@
1
+ // src/SearchOnPage/SearchOnPage.tsx
2
+ import * as React from "react";
3
+ import { Search, X } from "lucide-react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ var SearchOnPage = React.forwardRef(
6
+ ({
7
+ value = "",
8
+ onChange,
9
+ onSubmit,
10
+ onClear,
11
+ placeholder = "Search Reports",
12
+ className,
13
+ style,
14
+ "data-testid": dataTestId
15
+ }, ref) => {
16
+ const [isFocused, setIsFocused] = React.useState(false);
17
+ const [isHovered, setIsHovered] = React.useState(false);
18
+ const inputRef = React.useRef(null);
19
+ React.useImperativeHandle(ref, () => inputRef.current);
20
+ const handleFocus = () => {
21
+ setIsFocused(true);
22
+ };
23
+ const handleBlur = () => {
24
+ setIsFocused(false);
25
+ };
26
+ const handleChange = (e) => {
27
+ onChange?.(e.target.value);
28
+ };
29
+ const handleKeyDown = (e) => {
30
+ if (e.key === "Enter") {
31
+ onSubmit?.(value);
32
+ }
33
+ };
34
+ const handleClear = () => {
35
+ onChange?.("");
36
+ onClear?.();
37
+ inputRef.current?.focus();
38
+ };
39
+ const containerStyles = {
40
+ position: "relative",
41
+ width: "200px",
42
+ height: "32px",
43
+ backgroundColor: isFocused ? "#ffffff" : isHovered ? "#efefef" : "#ffffff",
44
+ borderRadius: "16px",
45
+ padding: "8px 16px",
46
+ display: "flex",
47
+ alignItems: "center",
48
+ gap: "8px",
49
+ cursor: "text",
50
+ transition: "all 0.2s ease-in-out",
51
+ boxSizing: "border-box",
52
+ border: isFocused ? "1px solid #efefef" : "none",
53
+ boxShadow: isFocused ? "0px 0px 0px 3px #3cad51" : "none",
54
+ ...style
55
+ };
56
+ const iconContainerStyles = {
57
+ display: "flex",
58
+ alignItems: "center",
59
+ justifyContent: "center",
60
+ flexShrink: 0,
61
+ padding: "2px"
62
+ };
63
+ const inputStyles = {
64
+ border: "none",
65
+ outline: "none",
66
+ backgroundColor: "transparent",
67
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
68
+ fontSize: "13px",
69
+ fontWeight: 400,
70
+ color: "#2f2f2f",
71
+ lineHeight: "1.5",
72
+ flex: 1,
73
+ width: "100%",
74
+ minWidth: 0
75
+ };
76
+ const clearButtonStyles = {
77
+ display: "flex",
78
+ alignItems: "center",
79
+ justifyContent: "center",
80
+ flexShrink: 0,
81
+ width: "16px",
82
+ height: "16px",
83
+ cursor: "pointer",
84
+ border: "none",
85
+ background: "none",
86
+ padding: 0
87
+ };
88
+ const showClearButton = isFocused && value.length > 0;
89
+ const iconColor = isFocused || isHovered ? "#2f2f2f" : "#595959";
90
+ return /* @__PURE__ */ jsxs(
91
+ "div",
92
+ {
93
+ className,
94
+ style: containerStyles,
95
+ onMouseEnter: () => setIsHovered(true),
96
+ onMouseLeave: () => setIsHovered(false),
97
+ onClick: () => inputRef.current?.focus(),
98
+ "data-testid": dataTestId,
99
+ children: [
100
+ /* @__PURE__ */ jsx("div", { style: iconContainerStyles, children: /* @__PURE__ */ jsx(Search, { size: 12, color: iconColor, strokeWidth: 2 }) }),
101
+ /* @__PURE__ */ jsx(
102
+ "input",
103
+ {
104
+ ref: inputRef,
105
+ type: "text",
106
+ value,
107
+ onChange: handleChange,
108
+ onFocus: handleFocus,
109
+ onBlur: handleBlur,
110
+ onKeyDown: handleKeyDown,
111
+ placeholder: isFocused ? "" : placeholder,
112
+ style: inputStyles
113
+ }
114
+ ),
115
+ showClearButton && /* @__PURE__ */ jsx(
116
+ "button",
117
+ {
118
+ type: "button",
119
+ onClick: handleClear,
120
+ style: clearButtonStyles,
121
+ "aria-label": "Clear search",
122
+ children: /* @__PURE__ */ jsx(X, { size: 13.333, color: "#2f2f2f", strokeWidth: 2 })
123
+ }
124
+ )
125
+ ]
126
+ }
127
+ );
128
+ }
129
+ );
130
+ SearchOnPage.displayName = "SearchOnPage";
131
+
132
+ export {
133
+ SearchOnPage
134
+ };
135
+ //# sourceMappingURL=chunk-B7RX3TPX.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/SearchOnPage/SearchOnPage.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Search, X } from 'lucide-react';\n\nexport interface SearchOnPageProps {\n /**\n * Value of the search input\n */\n value?: string;\n /**\n * Callback when value changes\n */\n onChange?: (value: string) => void;\n /**\n * Callback when search is submitted\n */\n onSubmit?: (value: string) => void;\n /**\n * Callback when clear button is clicked\n */\n onClear?: () => void;\n /**\n * Placeholder text\n */\n placeholder?: string;\n /**\n * Custom className\n */\n className?: string;\n /**\n * Custom style\n */\n style?: React.CSSProperties;\n /**\n * Test ID for testing\n */\n 'data-testid'?: string;\n}\n\n/**\n * SearchOnPage component - Arbor Design System\n *\n * A search input with fixed 200px width for filtering content on the current page.\n * Shows green focus ring when active and X button to clear.\n */\nexport const SearchOnPage = React.forwardRef<HTMLInputElement, SearchOnPageProps>(\n (\n {\n value = '',\n onChange,\n onSubmit,\n onClear,\n placeholder = 'Search Reports',\n className,\n style,\n 'data-testid': dataTestId,\n },\n ref\n ) => {\n const [isFocused, setIsFocused] = React.useState(false);\n const [isHovered, setIsHovered] = React.useState(false);\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n // Merge refs\n React.useImperativeHandle(ref, () => inputRef.current as HTMLInputElement);\n\n const handleFocus = () => {\n setIsFocused(true);\n };\n\n const handleBlur = () => {\n setIsFocused(false);\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange?.(e.target.value);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n onSubmit?.(value);\n }\n };\n\n const handleClear = () => {\n onChange?.('');\n onClear?.();\n inputRef.current?.focus();\n };\n\n const containerStyles: React.CSSProperties = {\n position: 'relative',\n width: '200px',\n height: '32px',\n backgroundColor: isFocused ? '#ffffff' : isHovered ? '#efefef' : '#ffffff',\n borderRadius: '16px',\n padding: '8px 16px',\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n cursor: 'text',\n transition: 'all 0.2s ease-in-out',\n boxSizing: 'border-box',\n border: isFocused ? '1px solid #efefef' : 'none',\n boxShadow: isFocused ? '0px 0px 0px 3px #3cad51' : 'none',\n ...style,\n };\n\n const iconContainerStyles: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n padding: '2px',\n };\n\n const inputStyles: React.CSSProperties = {\n border: 'none',\n outline: 'none',\n backgroundColor: 'transparent',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n fontSize: '13px',\n fontWeight: 400,\n color: '#2f2f2f',\n lineHeight: '1.5',\n flex: 1,\n width: '100%',\n minWidth: 0,\n };\n\n const clearButtonStyles: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n width: '16px',\n height: '16px',\n cursor: 'pointer',\n border: 'none',\n background: 'none',\n padding: 0,\n };\n\n const showClearButton = isFocused && value.length > 0;\n const iconColor = isFocused || isHovered ? '#2f2f2f' : '#595959';\n\n return (\n <div\n className={className}\n style={containerStyles}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() => inputRef.current?.focus()}\n data-testid={dataTestId}\n >\n <div style={iconContainerStyles}>\n <Search size={12} color={iconColor} strokeWidth={2} />\n </div>\n\n <input\n ref={inputRef}\n type=\"text\"\n value={value}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n placeholder={isFocused ? '' : placeholder}\n style={inputStyles}\n />\n\n {showClearButton && (\n <button\n type=\"button\"\n onClick={handleClear}\n style={clearButtonStyles}\n aria-label=\"Clear search\"\n >\n <X size={13.333} color=\"#2f2f2f\" strokeWidth={2} />\n </button>\n )}\n </div>\n );\n }\n);\n\nSearchOnPage.displayName = 'SearchOnPage';\n"],"mappings":"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","names":[]}
@@ -0,0 +1,122 @@
1
+ // src/Avatar/Avatar.tsx
2
+ import * as React from "react";
3
+ import { User } from "lucide-react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ var sizeConfig = {
6
+ small: {
7
+ size: 20,
8
+ fontSize: 0,
9
+ // Too small for initials
10
+ fontWeight: 400,
11
+ iconSize: 12,
12
+ borderRadius: "99px"
13
+ },
14
+ medium: {
15
+ size: 32,
16
+ fontSize: 13,
17
+ fontWeight: 400,
18
+ iconSize: 16,
19
+ borderRadius: "99px"
20
+ },
21
+ large: {
22
+ size: 48,
23
+ fontSize: 13,
24
+ fontWeight: 400,
25
+ iconSize: 24,
26
+ borderRadius: "4px"
27
+ },
28
+ "extra-large": {
29
+ size: 96,
30
+ fontSize: 27,
31
+ fontWeight: 600,
32
+ iconSize: 48,
33
+ borderRadius: "8px"
34
+ }
35
+ };
36
+ var Avatar = React.forwardRef(
37
+ ({
38
+ size = "medium",
39
+ src,
40
+ initials,
41
+ alt = "Avatar",
42
+ className,
43
+ style,
44
+ "data-testid": dataTestId
45
+ }, ref) => {
46
+ const [isHovered, setIsHovered] = React.useState(false);
47
+ const [imageError, setImageError] = React.useState(false);
48
+ const config = sizeConfig[size];
49
+ const hasHoverState = size === "small";
50
+ const containerStyles = {
51
+ width: `${config.size}px`,
52
+ height: `${config.size}px`,
53
+ borderRadius: config.borderRadius,
54
+ border: "1px solid #efefef",
55
+ overflow: "hidden",
56
+ position: "relative",
57
+ backgroundColor: "#f8f8f8",
58
+ display: "flex",
59
+ alignItems: "center",
60
+ justifyContent: "center",
61
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
62
+ cursor: "default",
63
+ boxSizing: "border-box",
64
+ ...style
65
+ };
66
+ const hoverOverlayStyles = {
67
+ position: "absolute",
68
+ inset: 0,
69
+ pointerEvents: "none",
70
+ boxShadow: isHovered && hasHoverState ? "inset 0px 4px 100px 0px rgba(32, 32, 32, 0.3)" : "none",
71
+ borderRadius: config.borderRadius,
72
+ transition: "box-shadow 0.2s ease-in-out"
73
+ };
74
+ const imageStyles = {
75
+ width: "100%",
76
+ height: "100%",
77
+ objectFit: "cover"
78
+ };
79
+ const initialsStyles = {
80
+ fontSize: `${config.fontSize}px`,
81
+ fontWeight: config.fontWeight,
82
+ color: "#2f2f2f",
83
+ lineHeight: 1.5,
84
+ textAlign: "center",
85
+ userSelect: "none"
86
+ };
87
+ const showImage = src && !imageError;
88
+ const showInitials = !showImage && initials && size !== "small";
89
+ const showPlaceholder = !showImage && !showInitials;
90
+ return /* @__PURE__ */ jsxs(
91
+ "div",
92
+ {
93
+ ref,
94
+ className,
95
+ style: containerStyles,
96
+ onMouseEnter: () => setIsHovered(true),
97
+ onMouseLeave: () => setIsHovered(false),
98
+ "data-testid": dataTestId,
99
+ children: [
100
+ showImage && /* @__PURE__ */ jsx(
101
+ "img",
102
+ {
103
+ src,
104
+ alt,
105
+ style: imageStyles,
106
+ onError: () => setImageError(true)
107
+ }
108
+ ),
109
+ showInitials && /* @__PURE__ */ jsx("span", { style: initialsStyles, children: initials.slice(0, 2).toUpperCase() }),
110
+ showPlaceholder && /* @__PURE__ */ jsx(User, { size: config.iconSize, color: "#d1d1d1", strokeWidth: 2 }),
111
+ /* @__PURE__ */ jsx("div", { style: hoverOverlayStyles })
112
+ ]
113
+ }
114
+ );
115
+ }
116
+ );
117
+ Avatar.displayName = "Avatar";
118
+
119
+ export {
120
+ Avatar
121
+ };
122
+ //# sourceMappingURL=chunk-JSG27ZZS.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Avatar/Avatar.tsx"],"sourcesContent":["import * as React from 'react';\nimport { User } from 'lucide-react';\n\nexport type AvatarSize = 'small' | 'medium' | 'large' | 'extra-large';\n\nexport interface AvatarProps {\n /**\n * Size of the avatar\n */\n size?: AvatarSize;\n /**\n * Image source URL\n */\n src?: string;\n /**\n * Initials to display (2 characters) when no image is provided\n */\n initials?: string;\n /**\n * Alt text for the image\n */\n alt?: string;\n /**\n * Custom className\n */\n className?: string;\n /**\n * Custom style\n */\n style?: React.CSSProperties;\n /**\n * Test ID for testing\n */\n 'data-testid'?: string;\n}\n\nconst sizeConfig = {\n small: {\n size: 20,\n fontSize: 0, // Too small for initials\n fontWeight: 400,\n iconSize: 12,\n borderRadius: '99px',\n },\n medium: {\n size: 32,\n fontSize: 13,\n fontWeight: 400,\n iconSize: 16,\n borderRadius: '99px',\n },\n large: {\n size: 48,\n fontSize: 13,\n fontWeight: 400,\n iconSize: 24,\n borderRadius: '4px',\n },\n 'extra-large': {\n size: 96,\n fontSize: 27,\n fontWeight: 600,\n iconSize: 48,\n borderRadius: '8px',\n },\n};\n\n/**\n * Avatar component - Arbor Design System\n *\n * Displays a user avatar with support for images, initials, or a placeholder icon.\n * Features hover state with inner shadow effect.\n */\nexport const Avatar = React.forwardRef<HTMLDivElement, AvatarProps>(\n (\n {\n size = 'medium',\n src,\n initials,\n alt = 'Avatar',\n className,\n style,\n 'data-testid': dataTestId,\n },\n ref\n ) => {\n const [isHovered, setIsHovered] = React.useState(false);\n const [imageError, setImageError] = React.useState(false);\n const config = sizeConfig[size];\n\n // Only apply hover state for small size\n const hasHoverState = size === 'small';\n\n const containerStyles: React.CSSProperties = {\n width: `${config.size}px`,\n height: `${config.size}px`,\n borderRadius: config.borderRadius,\n border: '1px solid #efefef',\n overflow: 'hidden',\n position: 'relative',\n backgroundColor: '#f8f8f8',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n cursor: 'default',\n boxSizing: 'border-box',\n ...style,\n };\n\n const hoverOverlayStyles: React.CSSProperties = {\n position: 'absolute',\n inset: 0,\n pointerEvents: 'none',\n boxShadow: isHovered && hasHoverState ? 'inset 0px 4px 100px 0px rgba(32, 32, 32, 0.3)' : 'none',\n borderRadius: config.borderRadius,\n transition: 'box-shadow 0.2s ease-in-out',\n };\n\n const imageStyles: React.CSSProperties = {\n width: '100%',\n height: '100%',\n objectFit: 'cover',\n };\n\n const initialsStyles: React.CSSProperties = {\n fontSize: `${config.fontSize}px`,\n fontWeight: config.fontWeight,\n color: '#2f2f2f',\n lineHeight: 1.5,\n textAlign: 'center',\n userSelect: 'none',\n };\n\n // Determine what to display\n const showImage = src && !imageError;\n const showInitials = !showImage && initials && size !== 'small';\n const showPlaceholder = !showImage && !showInitials;\n\n return (\n <div\n ref={ref}\n className={className}\n style={containerStyles}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n data-testid={dataTestId}\n >\n {showImage && (\n <img\n src={src}\n alt={alt}\n style={imageStyles}\n onError={() => setImageError(true)}\n />\n )}\n\n {showInitials && (\n <span style={initialsStyles}>\n {initials.slice(0, 2).toUpperCase()}\n </span>\n )}\n\n {showPlaceholder && (\n <User size={config.iconSize} color=\"#d1d1d1\" strokeWidth={2} />\n )}\n\n <div style={hoverOverlayStyles} />\n </div>\n );\n }\n);\n\nAvatar.displayName = 'Avatar';\n"],"mappings":";AAAA,YAAY,WAAW;AACvB,SAAS,YAAY;AA2If,SASI,KATJ;AAxGN,IAAM,aAAa;AAAA,EACjB,OAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU;AAAA;AAAA,IACV,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,cAAc;AAAA,EAChB;AAAA,EACA,QAAQ;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,cAAc;AAAA,EAChB;AAAA,EACA,OAAO;AAAA,IACL,MAAM;AAAA,IACN,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,cAAc;AAAA,EAChB;AAAA,EACA,eAAe;AAAA,IACb,MAAM;AAAA,IACN,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,cAAc;AAAA,EAChB;AACF;AAQO,IAAM,SAAe;AAAA,EAC1B,CACE;AAAA,IACE,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,eAAe;AAAA,EACjB,GACA,QACG;AACH,UAAM,CAAC,WAAW,YAAY,IAAU,eAAS,KAAK;AACtD,UAAM,CAAC,YAAY,aAAa,IAAU,eAAS,KAAK;AACxD,UAAM,SAAS,WAAW,IAAI;AAG9B,UAAM,gBAAgB,SAAS;AAE/B,UAAM,kBAAuC;AAAA,MAC3C,OAAO,GAAG,OAAO,IAAI;AAAA,MACrB,QAAQ,GAAG,OAAO,IAAI;AAAA,MACtB,cAAc,OAAO;AAAA,MACrB,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,UAAU;AAAA,MACV,iBAAiB;AAAA,MACjB,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,GAAG;AAAA,IACL;AAEA,UAAM,qBAA0C;AAAA,MAC9C,UAAU;AAAA,MACV,OAAO;AAAA,MACP,eAAe;AAAA,MACf,WAAW,aAAa,gBAAgB,kDAAkD;AAAA,MAC1F,cAAc,OAAO;AAAA,MACrB,YAAY;AAAA,IACd;AAEA,UAAM,cAAmC;AAAA,MACvC,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,WAAW;AAAA,IACb;AAEA,UAAM,iBAAsC;AAAA,MAC1C,UAAU,GAAG,OAAO,QAAQ;AAAA,MAC5B,YAAY,OAAO;AAAA,MACnB,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAGA,UAAM,YAAY,OAAO,CAAC;AAC1B,UAAM,eAAe,CAAC,aAAa,YAAY,SAAS;AACxD,UAAM,kBAAkB,CAAC,aAAa,CAAC;AAEvC,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,cAAc,MAAM,aAAa,IAAI;AAAA,QACrC,cAAc,MAAM,aAAa,KAAK;AAAA,QACtC,eAAa;AAAA,QAEZ;AAAA,uBACC;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA;AAAA,cACA,OAAO;AAAA,cACP,SAAS,MAAM,cAAc,IAAI;AAAA;AAAA,UACnC;AAAA,UAGD,gBACC,oBAAC,UAAK,OAAO,gBACV,mBAAS,MAAM,GAAG,CAAC,EAAE,YAAY,GACpC;AAAA,UAGD,mBACC,oBAAC,QAAK,MAAM,OAAO,UAAU,OAAM,WAAU,aAAa,GAAG;AAAA,UAG/D,oBAAC,SAAI,OAAO,oBAAoB;AAAA;AAAA;AAAA,IAClC;AAAA,EAEJ;AACF;AAEA,OAAO,cAAc;","names":[]}
@@ -0,0 +1,240 @@
1
+ // src/Breadcrumbs/Breadcrumbs.tsx
2
+ import * as React from "react";
3
+ import { Link, ChevronDown, MoreHorizontal } from "lucide-react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ var Breadcrumbs = React.forwardRef(
6
+ ({
7
+ items,
8
+ onCopy,
9
+ className,
10
+ style,
11
+ "data-testid": dataTestId
12
+ }, ref) => {
13
+ const [hoveredIndex, setHoveredIndex] = React.useState(null);
14
+ const [focusedIndex, setFocusedIndex] = React.useState(null);
15
+ const [showCopyTooltip, setShowCopyTooltip] = React.useState(false);
16
+ const [ellipsisFocused, setEllipsisFocused] = React.useState(false);
17
+ const [ellipsisHovered, setEllipsisHovered] = React.useState(false);
18
+ const displayItems = React.useMemo(() => {
19
+ if (items.length > 6) {
20
+ return [items[0], { label: "...", isEllipsis: true }, items[items.length - 1]];
21
+ }
22
+ return items;
23
+ }, [items]);
24
+ const handleCopy = () => {
25
+ onCopy?.();
26
+ const trail = items.map((item) => item.label).join(" / ");
27
+ navigator.clipboard.writeText(trail);
28
+ };
29
+ const containerStyles = {
30
+ display: "flex",
31
+ alignItems: "center",
32
+ gap: "8px",
33
+ ...style
34
+ };
35
+ const breadcrumbItemStyles = (index, isActive, isEllipsis) => {
36
+ const isFocused = focusedIndex === index;
37
+ if (isEllipsis) {
38
+ return {
39
+ display: "flex",
40
+ alignItems: "center",
41
+ gap: "4px",
42
+ height: "24px",
43
+ overflow: "hidden"
44
+ };
45
+ }
46
+ return {
47
+ display: "flex",
48
+ alignItems: "center",
49
+ gap: "4px",
50
+ height: "24px",
51
+ overflow: "hidden",
52
+ backgroundColor: isFocused ? "rgba(255, 255, 255, 0.01)" : "transparent",
53
+ borderRadius: "99px",
54
+ boxShadow: isFocused ? "0px 0px 0px 3px #3cad51" : "none",
55
+ padding: isFocused ? "0 6px" : "0 2px",
56
+ margin: isFocused ? "0" : "0 4px",
57
+ cursor: isActive ? "default" : "pointer",
58
+ textDecoration: "none"
59
+ };
60
+ };
61
+ const linkStyles = (isActive, isHovered) => ({
62
+ fontFamily: isActive ? "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif" : "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
63
+ fontSize: "13px",
64
+ fontWeight: isActive ? 600 : 400,
65
+ color: isActive ? isHovered ? "#0e8a0e" : "#2f2f2f" : isHovered ? "#0e8a0e" : "#595959",
66
+ lineHeight: "1.5",
67
+ whiteSpace: "nowrap"
68
+ });
69
+ const dividerStyles = {
70
+ fontFamily: "'PT Sans', sans-serif",
71
+ fontSize: "14px",
72
+ color: "#595959",
73
+ lineHeight: "normal",
74
+ whiteSpace: "nowrap"
75
+ };
76
+ const ellipsisButtonStyles = {
77
+ display: "flex",
78
+ alignItems: "center",
79
+ justifyContent: "center",
80
+ width: "24px",
81
+ height: "24px",
82
+ borderRadius: "99px",
83
+ border: "none",
84
+ background: "transparent",
85
+ cursor: "pointer",
86
+ backgroundColor: ellipsisFocused ? "rgba(255, 255, 255, 0.01)" : ellipsisHovered ? "#efefef" : "transparent",
87
+ boxShadow: ellipsisFocused ? "0px 0px 0px 3px #3cad51" : "none"
88
+ };
89
+ const copyButtonStyles = {
90
+ display: "flex",
91
+ alignItems: "center",
92
+ justifyContent: "center",
93
+ width: "24px",
94
+ height: "24px",
95
+ borderRadius: "99px",
96
+ border: "none",
97
+ background: showCopyTooltip ? "#efefef" : "transparent",
98
+ cursor: "pointer",
99
+ position: "relative"
100
+ };
101
+ const tooltipStyles = {
102
+ position: "absolute",
103
+ top: "100%",
104
+ left: "50%",
105
+ transform: "translateX(-50%)",
106
+ marginTop: "8px",
107
+ backgroundColor: "#2f2f2f",
108
+ color: "white",
109
+ padding: "12px",
110
+ borderRadius: "8px",
111
+ fontSize: "13px",
112
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
113
+ fontWeight: 400,
114
+ lineHeight: "1.5",
115
+ whiteSpace: "nowrap",
116
+ boxShadow: "0px 4px 12px rgba(32, 32, 32, 0.08)",
117
+ zIndex: 1e3
118
+ };
119
+ return /* @__PURE__ */ jsx(
120
+ "div",
121
+ {
122
+ ref,
123
+ className,
124
+ style: containerStyles,
125
+ "data-testid": dataTestId,
126
+ children: displayItems.map((item, index) => {
127
+ const isActive = index === displayItems.length - 1;
128
+ const isEllipsis = "isEllipsis" in item && item.isEllipsis;
129
+ if (isEllipsis) {
130
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
131
+ /* @__PURE__ */ jsx(
132
+ "button",
133
+ {
134
+ style: ellipsisButtonStyles,
135
+ onFocus: () => setEllipsisFocused(true),
136
+ onBlur: () => setEllipsisFocused(false),
137
+ onMouseEnter: () => setEllipsisHovered(true),
138
+ onMouseLeave: () => setEllipsisHovered(false),
139
+ "aria-label": "More breadcrumbs",
140
+ children: /* @__PURE__ */ jsx(
141
+ MoreHorizontal,
142
+ {
143
+ size: 12,
144
+ color: "#2f2f2f",
145
+ strokeWidth: 2,
146
+ style: { display: "block", flexShrink: 0 }
147
+ }
148
+ )
149
+ }
150
+ ),
151
+ /* @__PURE__ */ jsx("span", { style: dividerStyles, children: " /" })
152
+ ] }, `ellipsis-${index}`);
153
+ }
154
+ const breadcrumbItem = item;
155
+ if (isActive) {
156
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
157
+ /* @__PURE__ */ jsx(
158
+ "div",
159
+ {
160
+ style: breadcrumbItemStyles(index, true),
161
+ onMouseEnter: () => setHoveredIndex(index),
162
+ onMouseLeave: () => setHoveredIndex(null),
163
+ onFocus: () => setFocusedIndex(index),
164
+ onBlur: () => setFocusedIndex(null),
165
+ tabIndex: 0,
166
+ children: /* @__PURE__ */ jsx("span", { style: linkStyles(true, hoveredIndex === index), children: breadcrumbItem.label })
167
+ }
168
+ ),
169
+ onCopy && /* @__PURE__ */ jsxs(
170
+ "button",
171
+ {
172
+ style: copyButtonStyles,
173
+ onClick: handleCopy,
174
+ onMouseEnter: () => setShowCopyTooltip(true),
175
+ onMouseLeave: () => setShowCopyTooltip(false),
176
+ "aria-label": "Copy breadcrumb trail",
177
+ children: [
178
+ /* @__PURE__ */ jsx(
179
+ Link,
180
+ {
181
+ size: 12,
182
+ color: "#2f2f2f",
183
+ strokeWidth: 2,
184
+ style: { display: "block", flexShrink: 0 }
185
+ }
186
+ ),
187
+ showCopyTooltip && /* @__PURE__ */ jsx("div", { style: tooltipStyles, children: "Copy breadcrumb trail" })
188
+ ]
189
+ }
190
+ )
191
+ ] }, index);
192
+ }
193
+ const Element = breadcrumbItem.href ? "a" : "button";
194
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
195
+ /* @__PURE__ */ jsxs(
196
+ Element,
197
+ {
198
+ ...breadcrumbItem.href ? { href: breadcrumbItem.href } : {},
199
+ style: {
200
+ ...breadcrumbItemStyles(index, false),
201
+ border: "none",
202
+ background: "transparent"
203
+ },
204
+ onClick: (e) => {
205
+ if (!breadcrumbItem.href && breadcrumbItem.onClick) {
206
+ e.preventDefault();
207
+ breadcrumbItem.onClick();
208
+ }
209
+ },
210
+ onMouseEnter: () => setHoveredIndex(index),
211
+ onMouseLeave: () => setHoveredIndex(null),
212
+ onFocus: () => setFocusedIndex(index),
213
+ onBlur: () => setFocusedIndex(null),
214
+ children: [
215
+ /* @__PURE__ */ jsx("span", { style: linkStyles(false, hoveredIndex === index), children: breadcrumbItem.label }),
216
+ breadcrumbItem.hasDropdown && /* @__PURE__ */ jsx(
217
+ ChevronDown,
218
+ {
219
+ size: 12,
220
+ color: hoveredIndex === index ? "#0e8a0e" : "#595959",
221
+ strokeWidth: 2,
222
+ style: { marginLeft: "2px", display: "inline-block", flexShrink: 0 }
223
+ }
224
+ )
225
+ ]
226
+ }
227
+ ),
228
+ /* @__PURE__ */ jsx("span", { style: dividerStyles, children: " /" })
229
+ ] }, index);
230
+ })
231
+ }
232
+ );
233
+ }
234
+ );
235
+ Breadcrumbs.displayName = "Breadcrumbs";
236
+
237
+ export {
238
+ Breadcrumbs
239
+ };
240
+ //# sourceMappingURL=chunk-RQP6ZGD7.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Breadcrumbs/Breadcrumbs.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Link, ChevronDown, MoreHorizontal } from 'lucide-react';\n\nexport interface BreadcrumbItem {\n /**\n * The label to display for this breadcrumb\n */\n label: string;\n /**\n * Optional href for the breadcrumb link\n */\n href?: string;\n /**\n * Optional click handler\n */\n onClick?: () => void;\n /**\n * Whether this breadcrumb has a dropdown menu\n */\n hasDropdown?: boolean;\n}\n\nexport interface BreadcrumbsProps {\n /**\n * Array of breadcrumb items\n */\n items: BreadcrumbItem[];\n /**\n * Callback when copy button is clicked\n */\n onCopy?: () => void;\n /**\n * Custom className\n */\n className?: string;\n /**\n * Custom style\n */\n style?: React.CSSProperties;\n /**\n * Test ID for testing\n */\n 'data-testid'?: string;\n}\n\n/**\n * Breadcrumbs component - Arbor Design System\n *\n * Navigation component showing the current page's location in the site hierarchy.\n * Automatically truncates to show first and last breadcrumb with ellipsis when more than 6 items.\n */\nexport const Breadcrumbs = React.forwardRef<HTMLDivElement, BreadcrumbsProps>(\n (\n {\n items,\n onCopy,\n className,\n style,\n 'data-testid': dataTestId,\n },\n ref\n ) => {\n const [hoveredIndex, setHoveredIndex] = React.useState<number | null>(null);\n const [focusedIndex, setFocusedIndex] = React.useState<number | null>(null);\n const [showCopyTooltip, setShowCopyTooltip] = React.useState(false);\n const [ellipsisFocused, setEllipsisFocused] = React.useState(false);\n const [ellipsisHovered, setEllipsisHovered] = React.useState(false);\n\n // Truncate breadcrumbs if more than 6 items\n const displayItems = React.useMemo(() => {\n if (items.length > 6) {\n // Show first item, ellipsis, and last item\n return [items[0], { label: '...', isEllipsis: true }, items[items.length - 1]];\n }\n return items;\n }, [items]);\n\n const handleCopy = () => {\n onCopy?.();\n // Copy the breadcrumb trail to clipboard\n const trail = items.map(item => item.label).join(' / ');\n navigator.clipboard.writeText(trail);\n };\n\n const containerStyles: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n ...style,\n };\n\n const breadcrumbItemStyles = (index: number, isActive: boolean, isEllipsis?: boolean): React.CSSProperties => {\n const isFocused = focusedIndex === index;\n\n if (isEllipsis) {\n return {\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n height: '24px',\n overflow: 'hidden',\n };\n }\n\n return {\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n height: '24px',\n overflow: 'hidden',\n backgroundColor: isFocused ? 'rgba(255, 255, 255, 0.01)' : 'transparent',\n borderRadius: '99px',\n boxShadow: isFocused ? '0px 0px 0px 3px #3cad51' : 'none',\n padding: isFocused ? '0 6px' : '0 2px',\n margin: isFocused ? '0' : '0 4px',\n cursor: isActive ? 'default' : 'pointer',\n textDecoration: 'none',\n };\n };\n\n const linkStyles = (isActive: boolean, isHovered: boolean): React.CSSProperties => ({\n fontFamily: isActive\n ? \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\"\n : \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n fontSize: '13px',\n fontWeight: isActive ? 600 : 400,\n color: isActive\n ? isHovered\n ? '#0e8a0e'\n : '#2f2f2f'\n : isHovered\n ? '#0e8a0e'\n : '#595959',\n lineHeight: '1.5',\n whiteSpace: 'nowrap',\n });\n\n const dividerStyles: React.CSSProperties = {\n fontFamily: \"'PT Sans', sans-serif\",\n fontSize: '14px',\n color: '#595959',\n lineHeight: 'normal',\n whiteSpace: 'nowrap',\n };\n\n const ellipsisButtonStyles: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n borderRadius: '99px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n backgroundColor: ellipsisFocused ? 'rgba(255, 255, 255, 0.01)' : ellipsisHovered ? '#efefef' : 'transparent',\n boxShadow: ellipsisFocused ? '0px 0px 0px 3px #3cad51' : 'none',\n };\n\n const copyButtonStyles: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '24px',\n height: '24px',\n borderRadius: '99px',\n border: 'none',\n background: showCopyTooltip ? '#efefef' : 'transparent',\n cursor: 'pointer',\n position: 'relative',\n };\n\n const tooltipStyles: React.CSSProperties = {\n position: 'absolute',\n top: '100%',\n left: '50%',\n transform: 'translateX(-50%)',\n marginTop: '8px',\n backgroundColor: '#2f2f2f',\n color: 'white',\n padding: '12px',\n borderRadius: '8px',\n fontSize: '13px',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n fontWeight: 400,\n lineHeight: '1.5',\n whiteSpace: 'nowrap',\n boxShadow: '0px 4px 12px rgba(32, 32, 32, 0.08)',\n zIndex: 1000,\n };\n\n return (\n <div\n ref={ref}\n className={className}\n style={containerStyles}\n data-testid={dataTestId}\n >\n {displayItems.map((item, index) => {\n const isActive = index === displayItems.length - 1;\n const isEllipsis = 'isEllipsis' in item && item.isEllipsis;\n\n if (isEllipsis) {\n return (\n <React.Fragment key={`ellipsis-${index}`}>\n <button\n style={ellipsisButtonStyles}\n onFocus={() => setEllipsisFocused(true)}\n onBlur={() => setEllipsisFocused(false)}\n onMouseEnter={() => setEllipsisHovered(true)}\n onMouseLeave={() => setEllipsisHovered(false)}\n aria-label=\"More breadcrumbs\"\n >\n <MoreHorizontal\n size={12}\n color=\"#2f2f2f\"\n strokeWidth={2}\n style={{ display: 'block', flexShrink: 0 }}\n />\n </button>\n <span style={dividerStyles}> /</span>\n </React.Fragment>\n );\n }\n\n const breadcrumbItem = item as BreadcrumbItem;\n\n if (isActive) {\n // Active breadcrumb (last item) - not clickable\n return (\n <React.Fragment key={index}>\n <div\n style={breadcrumbItemStyles(index, true)}\n onMouseEnter={() => setHoveredIndex(index)}\n onMouseLeave={() => setHoveredIndex(null)}\n onFocus={() => setFocusedIndex(index)}\n onBlur={() => setFocusedIndex(null)}\n tabIndex={0}\n >\n <span style={linkStyles(true, hoveredIndex === index)}>\n {breadcrumbItem.label}\n </span>\n </div>\n {/* Copy button - appears immediately after active breadcrumb */}\n {onCopy && (\n <button\n style={copyButtonStyles}\n onClick={handleCopy}\n onMouseEnter={() => setShowCopyTooltip(true)}\n onMouseLeave={() => setShowCopyTooltip(false)}\n aria-label=\"Copy breadcrumb trail\"\n >\n <Link\n size={12}\n color=\"#2f2f2f\"\n strokeWidth={2}\n style={{ display: 'block', flexShrink: 0 }}\n />\n {showCopyTooltip && (\n <div style={tooltipStyles}>Copy breadcrumb trail</div>\n )}\n </button>\n )}\n </React.Fragment>\n );\n }\n\n // Regular breadcrumb link\n const Element = breadcrumbItem.href ? 'a' : 'button';\n return (\n <React.Fragment key={index}>\n <Element\n {...(breadcrumbItem.href ? { href: breadcrumbItem.href } : {})}\n style={{\n ...breadcrumbItemStyles(index, false),\n border: 'none',\n background: 'transparent',\n }}\n onClick={(e) => {\n if (!breadcrumbItem.href && breadcrumbItem.onClick) {\n e.preventDefault();\n breadcrumbItem.onClick();\n }\n }}\n onMouseEnter={() => setHoveredIndex(index)}\n onMouseLeave={() => setHoveredIndex(null)}\n onFocus={() => setFocusedIndex(index)}\n onBlur={() => setFocusedIndex(null)}\n >\n <span style={linkStyles(false, hoveredIndex === index)}>\n {breadcrumbItem.label}\n </span>\n {breadcrumbItem.hasDropdown && (\n <ChevronDown\n size={12}\n color={hoveredIndex === index ? '#0e8a0e' : '#595959'}\n strokeWidth={2}\n style={{ marginLeft: '2px', display: 'inline-block', flexShrink: 0 }}\n />\n )}\n </Element>\n <span style={dividerStyles}> /</span>\n </React.Fragment>\n );\n })}\n </div>\n );\n }\n);\n\nBreadcrumbs.displayName = 'Breadcrumbs';\n"],"mappings":"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","names":[]}