@tonyarbor/components 0.2.0 → 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.
- package/dist/Avatar.d.mts +42 -0
- package/dist/Avatar.d.ts +42 -0
- package/dist/Avatar.js +158 -0
- package/dist/Avatar.js.map +1 -0
- package/dist/Avatar.mjs +7 -0
- package/dist/Avatar.mjs.map +1 -0
- package/dist/Banner.d.mts +59 -0
- package/dist/Banner.d.ts +59 -0
- package/dist/Banner.js +222 -0
- package/dist/Banner.js.map +1 -0
- package/dist/Banner.mjs +7 -0
- package/dist/Banner.mjs.map +1 -0
- package/dist/Breadcrumbs.d.mts +51 -0
- package/dist/Breadcrumbs.d.ts +51 -0
- package/dist/Breadcrumbs.js +276 -0
- package/dist/Breadcrumbs.js.map +1 -0
- package/dist/Breadcrumbs.mjs +7 -0
- package/dist/Breadcrumbs.mjs.map +1 -0
- package/dist/Checkbox.d.mts +4 -0
- package/dist/Checkbox.d.ts +4 -0
- package/dist/Checkbox.js +45 -16
- package/dist/Checkbox.js.map +1 -1
- package/dist/Checkbox.mjs +1 -1
- package/dist/DatePicker.d.mts +68 -0
- package/dist/DatePicker.d.ts +68 -0
- package/dist/DatePicker.js +490 -0
- package/dist/DatePicker.js.map +1 -0
- package/dist/DatePicker.mjs +7 -0
- package/dist/DatePicker.mjs.map +1 -0
- package/dist/Pagination.d.mts +36 -0
- package/dist/Pagination.d.ts +36 -0
- package/dist/Pagination.js +301 -0
- package/dist/Pagination.js.map +1 -0
- package/dist/Pagination.mjs +7 -0
- package/dist/Pagination.mjs.map +1 -0
- package/dist/Radio.js +32 -12
- package/dist/Radio.js.map +1 -1
- package/dist/Radio.mjs +1 -1
- package/dist/SearchGlobal.d.mts +45 -0
- package/dist/SearchGlobal.d.ts +45 -0
- package/dist/SearchGlobal.js +209 -0
- package/dist/SearchGlobal.js.map +1 -0
- package/dist/SearchGlobal.mjs +7 -0
- package/dist/SearchGlobal.mjs.map +1 -0
- package/dist/SearchOnPage.d.mts +45 -0
- package/dist/SearchOnPage.d.ts +45 -0
- package/dist/SearchOnPage.js +171 -0
- package/dist/SearchOnPage.js.map +1 -0
- package/dist/SearchOnPage.mjs +7 -0
- package/dist/SearchOnPage.mjs.map +1 -0
- package/dist/Table.d.mts +80 -0
- package/dist/Table.d.ts +80 -0
- package/dist/Table.js +347 -0
- package/dist/Table.js.map +1 -0
- package/dist/Table.mjs +8 -0
- package/dist/Table.mjs.map +1 -0
- package/dist/TableControls.d.mts +76 -0
- package/dist/TableControls.d.ts +76 -0
- package/dist/TableControls.js +461 -0
- package/dist/TableControls.js.map +1 -0
- package/dist/TableControls.mjs +7 -0
- package/dist/TableControls.mjs.map +1 -0
- package/dist/TableFooterPagination.d.mts +56 -0
- package/dist/TableFooterPagination.d.ts +56 -0
- package/dist/TableFooterPagination.js +499 -0
- package/dist/TableFooterPagination.js.map +1 -0
- package/dist/TableFooterPagination.mjs +7 -0
- package/dist/TableFooterPagination.mjs.map +1 -0
- package/dist/Tabs.d.mts +50 -0
- package/dist/Tabs.d.ts +50 -0
- package/dist/Tabs.js +187 -0
- package/dist/Tabs.js.map +1 -0
- package/dist/Tabs.mjs +7 -0
- package/dist/Tabs.mjs.map +1 -0
- package/dist/TextArea.d.mts +64 -0
- package/dist/TextArea.d.ts +64 -0
- package/dist/TextArea.js +171 -0
- package/dist/TextArea.js.map +1 -0
- package/dist/TextArea.mjs +7 -0
- package/dist/TextArea.mjs.map +1 -0
- package/dist/Toast.d.mts +48 -0
- package/dist/Toast.d.ts +48 -0
- package/dist/Toast.js +169 -0
- package/dist/Toast.js.map +1 -0
- package/dist/Toast.mjs +7 -0
- package/dist/Toast.mjs.map +1 -0
- package/dist/Toggle.d.mts +48 -0
- package/dist/Toggle.d.ts +48 -0
- package/dist/Toggle.js +291 -0
- package/dist/Toggle.js.map +1 -0
- package/dist/Toggle.mjs +7 -0
- package/dist/Toggle.mjs.map +1 -0
- package/dist/Tooltip.d.mts +32 -0
- package/dist/Tooltip.d.ts +32 -0
- package/dist/Tooltip.js +109 -0
- package/dist/Tooltip.js.map +1 -0
- package/dist/Tooltip.mjs +7 -0
- package/dist/Tooltip.mjs.map +1 -0
- package/dist/chunk-52TG3BFX.mjs +463 -0
- package/dist/chunk-52TG3BFX.mjs.map +1 -0
- package/dist/chunk-AI2U34CF.mjs +159 -0
- package/dist/chunk-AI2U34CF.mjs.map +1 -0
- package/dist/chunk-B7RX3TPX.mjs +135 -0
- package/dist/chunk-B7RX3TPX.mjs.map +1 -0
- package/dist/chunk-C25FFMRQ.mjs +255 -0
- package/dist/chunk-C25FFMRQ.mjs.map +1 -0
- package/dist/{chunk-BCYJIUQX.mjs → chunk-CUTYEIFE.mjs} +47 -18
- package/dist/chunk-CUTYEIFE.mjs.map +1 -0
- package/dist/chunk-DULH2KRW.mjs +133 -0
- package/dist/chunk-DULH2KRW.mjs.map +1 -0
- package/dist/chunk-G5NVKF2G.mjs +434 -0
- package/dist/chunk-G5NVKF2G.mjs.map +1 -0
- package/dist/chunk-JSG27ZZS.mjs +122 -0
- package/dist/chunk-JSG27ZZS.mjs.map +1 -0
- package/dist/{chunk-ARBHNHO7.mjs → chunk-M6DVBEEL.mjs} +33 -13
- package/dist/chunk-M6DVBEEL.mjs.map +1 -0
- package/dist/chunk-MBUMR2XJ.mjs +135 -0
- package/dist/chunk-MBUMR2XJ.mjs.map +1 -0
- package/dist/chunk-MNH2TGUX.mjs +73 -0
- package/dist/chunk-MNH2TGUX.mjs.map +1 -0
- package/dist/chunk-RQP6ZGD7.mjs +240 -0
- package/dist/chunk-RQP6ZGD7.mjs.map +1 -0
- package/dist/chunk-RRMG2SSZ.mjs +265 -0
- package/dist/chunk-RRMG2SSZ.mjs.map +1 -0
- package/dist/chunk-U4JXKZZG.mjs +186 -0
- package/dist/chunk-U4JXKZZG.mjs.map +1 -0
- package/dist/chunk-UPBHDBAK.mjs +173 -0
- package/dist/chunk-UPBHDBAK.mjs.map +1 -0
- package/dist/chunk-W55QJIAN.mjs +467 -0
- package/dist/chunk-W55QJIAN.mjs.map +1 -0
- package/dist/chunk-YV4OXFIM.mjs +151 -0
- package/dist/chunk-YV4OXFIM.mjs.map +1 -0
- package/dist/index.d.mts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +3414 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +63 -3
- package/package.json +78 -1
- package/dist/chunk-ARBHNHO7.mjs.map +0 -1
- package/dist/chunk-BCYJIUQX.mjs.map +0 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
interface BreadcrumbItem {
|
|
4
|
+
/**
|
|
5
|
+
* The label to display for this breadcrumb
|
|
6
|
+
*/
|
|
7
|
+
label: string;
|
|
8
|
+
/**
|
|
9
|
+
* Optional href for the breadcrumb link
|
|
10
|
+
*/
|
|
11
|
+
href?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Optional click handler
|
|
14
|
+
*/
|
|
15
|
+
onClick?: () => void;
|
|
16
|
+
/**
|
|
17
|
+
* Whether this breadcrumb has a dropdown menu
|
|
18
|
+
*/
|
|
19
|
+
hasDropdown?: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface BreadcrumbsProps {
|
|
22
|
+
/**
|
|
23
|
+
* Array of breadcrumb items
|
|
24
|
+
*/
|
|
25
|
+
items: BreadcrumbItem[];
|
|
26
|
+
/**
|
|
27
|
+
* Callback when copy button is clicked
|
|
28
|
+
*/
|
|
29
|
+
onCopy?: () => void;
|
|
30
|
+
/**
|
|
31
|
+
* Custom className
|
|
32
|
+
*/
|
|
33
|
+
className?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Custom style
|
|
36
|
+
*/
|
|
37
|
+
style?: React.CSSProperties;
|
|
38
|
+
/**
|
|
39
|
+
* Test ID for testing
|
|
40
|
+
*/
|
|
41
|
+
'data-testid'?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Breadcrumbs component - Arbor Design System
|
|
45
|
+
*
|
|
46
|
+
* Navigation component showing the current page's location in the site hierarchy.
|
|
47
|
+
* Automatically truncates to show first and last breadcrumb with ellipsis when more than 6 items.
|
|
48
|
+
*/
|
|
49
|
+
declare const Breadcrumbs: React.ForwardRefExoticComponent<BreadcrumbsProps & React.RefAttributes<HTMLDivElement>>;
|
|
50
|
+
|
|
51
|
+
export { type BreadcrumbItem, Breadcrumbs, type BreadcrumbsProps };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
interface BreadcrumbItem {
|
|
4
|
+
/**
|
|
5
|
+
* The label to display for this breadcrumb
|
|
6
|
+
*/
|
|
7
|
+
label: string;
|
|
8
|
+
/**
|
|
9
|
+
* Optional href for the breadcrumb link
|
|
10
|
+
*/
|
|
11
|
+
href?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Optional click handler
|
|
14
|
+
*/
|
|
15
|
+
onClick?: () => void;
|
|
16
|
+
/**
|
|
17
|
+
* Whether this breadcrumb has a dropdown menu
|
|
18
|
+
*/
|
|
19
|
+
hasDropdown?: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface BreadcrumbsProps {
|
|
22
|
+
/**
|
|
23
|
+
* Array of breadcrumb items
|
|
24
|
+
*/
|
|
25
|
+
items: BreadcrumbItem[];
|
|
26
|
+
/**
|
|
27
|
+
* Callback when copy button is clicked
|
|
28
|
+
*/
|
|
29
|
+
onCopy?: () => void;
|
|
30
|
+
/**
|
|
31
|
+
* Custom className
|
|
32
|
+
*/
|
|
33
|
+
className?: string;
|
|
34
|
+
/**
|
|
35
|
+
* Custom style
|
|
36
|
+
*/
|
|
37
|
+
style?: React.CSSProperties;
|
|
38
|
+
/**
|
|
39
|
+
* Test ID for testing
|
|
40
|
+
*/
|
|
41
|
+
'data-testid'?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Breadcrumbs component - Arbor Design System
|
|
45
|
+
*
|
|
46
|
+
* Navigation component showing the current page's location in the site hierarchy.
|
|
47
|
+
* Automatically truncates to show first and last breadcrumb with ellipsis when more than 6 items.
|
|
48
|
+
*/
|
|
49
|
+
declare const Breadcrumbs: React.ForwardRefExoticComponent<BreadcrumbsProps & React.RefAttributes<HTMLDivElement>>;
|
|
50
|
+
|
|
51
|
+
export { type BreadcrumbItem, Breadcrumbs, type BreadcrumbsProps };
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/Breadcrumbs/index.ts
|
|
31
|
+
var Breadcrumbs_exports = {};
|
|
32
|
+
__export(Breadcrumbs_exports, {
|
|
33
|
+
Breadcrumbs: () => Breadcrumbs
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(Breadcrumbs_exports);
|
|
36
|
+
|
|
37
|
+
// src/Breadcrumbs/Breadcrumbs.tsx
|
|
38
|
+
var React = __toESM(require("react"));
|
|
39
|
+
var import_lucide_react = require("lucide-react");
|
|
40
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
41
|
+
var Breadcrumbs = React.forwardRef(
|
|
42
|
+
({
|
|
43
|
+
items,
|
|
44
|
+
onCopy,
|
|
45
|
+
className,
|
|
46
|
+
style,
|
|
47
|
+
"data-testid": dataTestId
|
|
48
|
+
}, ref) => {
|
|
49
|
+
const [hoveredIndex, setHoveredIndex] = React.useState(null);
|
|
50
|
+
const [focusedIndex, setFocusedIndex] = React.useState(null);
|
|
51
|
+
const [showCopyTooltip, setShowCopyTooltip] = React.useState(false);
|
|
52
|
+
const [ellipsisFocused, setEllipsisFocused] = React.useState(false);
|
|
53
|
+
const [ellipsisHovered, setEllipsisHovered] = React.useState(false);
|
|
54
|
+
const displayItems = React.useMemo(() => {
|
|
55
|
+
if (items.length > 6) {
|
|
56
|
+
return [items[0], { label: "...", isEllipsis: true }, items[items.length - 1]];
|
|
57
|
+
}
|
|
58
|
+
return items;
|
|
59
|
+
}, [items]);
|
|
60
|
+
const handleCopy = () => {
|
|
61
|
+
onCopy?.();
|
|
62
|
+
const trail = items.map((item) => item.label).join(" / ");
|
|
63
|
+
navigator.clipboard.writeText(trail);
|
|
64
|
+
};
|
|
65
|
+
const containerStyles = {
|
|
66
|
+
display: "flex",
|
|
67
|
+
alignItems: "center",
|
|
68
|
+
gap: "8px",
|
|
69
|
+
...style
|
|
70
|
+
};
|
|
71
|
+
const breadcrumbItemStyles = (index, isActive, isEllipsis) => {
|
|
72
|
+
const isFocused = focusedIndex === index;
|
|
73
|
+
if (isEllipsis) {
|
|
74
|
+
return {
|
|
75
|
+
display: "flex",
|
|
76
|
+
alignItems: "center",
|
|
77
|
+
gap: "4px",
|
|
78
|
+
height: "24px",
|
|
79
|
+
overflow: "hidden"
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
display: "flex",
|
|
84
|
+
alignItems: "center",
|
|
85
|
+
gap: "4px",
|
|
86
|
+
height: "24px",
|
|
87
|
+
overflow: "hidden",
|
|
88
|
+
backgroundColor: isFocused ? "rgba(255, 255, 255, 0.01)" : "transparent",
|
|
89
|
+
borderRadius: "99px",
|
|
90
|
+
boxShadow: isFocused ? "0px 0px 0px 3px #3cad51" : "none",
|
|
91
|
+
padding: isFocused ? "0 6px" : "0 2px",
|
|
92
|
+
margin: isFocused ? "0" : "0 4px",
|
|
93
|
+
cursor: isActive ? "default" : "pointer",
|
|
94
|
+
textDecoration: "none"
|
|
95
|
+
};
|
|
96
|
+
};
|
|
97
|
+
const linkStyles = (isActive, isHovered) => ({
|
|
98
|
+
fontFamily: isActive ? "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif" : "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
|
|
99
|
+
fontSize: "13px",
|
|
100
|
+
fontWeight: isActive ? 600 : 400,
|
|
101
|
+
color: isActive ? isHovered ? "#0e8a0e" : "#2f2f2f" : isHovered ? "#0e8a0e" : "#595959",
|
|
102
|
+
lineHeight: "1.5",
|
|
103
|
+
whiteSpace: "nowrap"
|
|
104
|
+
});
|
|
105
|
+
const dividerStyles = {
|
|
106
|
+
fontFamily: "'PT Sans', sans-serif",
|
|
107
|
+
fontSize: "14px",
|
|
108
|
+
color: "#595959",
|
|
109
|
+
lineHeight: "normal",
|
|
110
|
+
whiteSpace: "nowrap"
|
|
111
|
+
};
|
|
112
|
+
const ellipsisButtonStyles = {
|
|
113
|
+
display: "flex",
|
|
114
|
+
alignItems: "center",
|
|
115
|
+
justifyContent: "center",
|
|
116
|
+
width: "24px",
|
|
117
|
+
height: "24px",
|
|
118
|
+
borderRadius: "99px",
|
|
119
|
+
border: "none",
|
|
120
|
+
background: "transparent",
|
|
121
|
+
cursor: "pointer",
|
|
122
|
+
backgroundColor: ellipsisFocused ? "rgba(255, 255, 255, 0.01)" : ellipsisHovered ? "#efefef" : "transparent",
|
|
123
|
+
boxShadow: ellipsisFocused ? "0px 0px 0px 3px #3cad51" : "none"
|
|
124
|
+
};
|
|
125
|
+
const copyButtonStyles = {
|
|
126
|
+
display: "flex",
|
|
127
|
+
alignItems: "center",
|
|
128
|
+
justifyContent: "center",
|
|
129
|
+
width: "24px",
|
|
130
|
+
height: "24px",
|
|
131
|
+
borderRadius: "99px",
|
|
132
|
+
border: "none",
|
|
133
|
+
background: showCopyTooltip ? "#efefef" : "transparent",
|
|
134
|
+
cursor: "pointer",
|
|
135
|
+
position: "relative"
|
|
136
|
+
};
|
|
137
|
+
const tooltipStyles = {
|
|
138
|
+
position: "absolute",
|
|
139
|
+
top: "100%",
|
|
140
|
+
left: "50%",
|
|
141
|
+
transform: "translateX(-50%)",
|
|
142
|
+
marginTop: "8px",
|
|
143
|
+
backgroundColor: "#2f2f2f",
|
|
144
|
+
color: "white",
|
|
145
|
+
padding: "12px",
|
|
146
|
+
borderRadius: "8px",
|
|
147
|
+
fontSize: "13px",
|
|
148
|
+
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
|
|
149
|
+
fontWeight: 400,
|
|
150
|
+
lineHeight: "1.5",
|
|
151
|
+
whiteSpace: "nowrap",
|
|
152
|
+
boxShadow: "0px 4px 12px rgba(32, 32, 32, 0.08)",
|
|
153
|
+
zIndex: 1e3
|
|
154
|
+
};
|
|
155
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
156
|
+
"div",
|
|
157
|
+
{
|
|
158
|
+
ref,
|
|
159
|
+
className,
|
|
160
|
+
style: containerStyles,
|
|
161
|
+
"data-testid": dataTestId,
|
|
162
|
+
children: displayItems.map((item, index) => {
|
|
163
|
+
const isActive = index === displayItems.length - 1;
|
|
164
|
+
const isEllipsis = "isEllipsis" in item && item.isEllipsis;
|
|
165
|
+
if (isEllipsis) {
|
|
166
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(React.Fragment, { children: [
|
|
167
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
168
|
+
"button",
|
|
169
|
+
{
|
|
170
|
+
style: ellipsisButtonStyles,
|
|
171
|
+
onFocus: () => setEllipsisFocused(true),
|
|
172
|
+
onBlur: () => setEllipsisFocused(false),
|
|
173
|
+
onMouseEnter: () => setEllipsisHovered(true),
|
|
174
|
+
onMouseLeave: () => setEllipsisHovered(false),
|
|
175
|
+
"aria-label": "More breadcrumbs",
|
|
176
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
177
|
+
import_lucide_react.MoreHorizontal,
|
|
178
|
+
{
|
|
179
|
+
size: 12,
|
|
180
|
+
color: "#2f2f2f",
|
|
181
|
+
strokeWidth: 2,
|
|
182
|
+
style: { display: "block", flexShrink: 0 }
|
|
183
|
+
}
|
|
184
|
+
)
|
|
185
|
+
}
|
|
186
|
+
),
|
|
187
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: dividerStyles, children: " /" })
|
|
188
|
+
] }, `ellipsis-${index}`);
|
|
189
|
+
}
|
|
190
|
+
const breadcrumbItem = item;
|
|
191
|
+
if (isActive) {
|
|
192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(React.Fragment, { children: [
|
|
193
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
194
|
+
"div",
|
|
195
|
+
{
|
|
196
|
+
style: breadcrumbItemStyles(index, true),
|
|
197
|
+
onMouseEnter: () => setHoveredIndex(index),
|
|
198
|
+
onMouseLeave: () => setHoveredIndex(null),
|
|
199
|
+
onFocus: () => setFocusedIndex(index),
|
|
200
|
+
onBlur: () => setFocusedIndex(null),
|
|
201
|
+
tabIndex: 0,
|
|
202
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: linkStyles(true, hoveredIndex === index), children: breadcrumbItem.label })
|
|
203
|
+
}
|
|
204
|
+
),
|
|
205
|
+
onCopy && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
206
|
+
"button",
|
|
207
|
+
{
|
|
208
|
+
style: copyButtonStyles,
|
|
209
|
+
onClick: handleCopy,
|
|
210
|
+
onMouseEnter: () => setShowCopyTooltip(true),
|
|
211
|
+
onMouseLeave: () => setShowCopyTooltip(false),
|
|
212
|
+
"aria-label": "Copy breadcrumb trail",
|
|
213
|
+
children: [
|
|
214
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
215
|
+
import_lucide_react.Link,
|
|
216
|
+
{
|
|
217
|
+
size: 12,
|
|
218
|
+
color: "#2f2f2f",
|
|
219
|
+
strokeWidth: 2,
|
|
220
|
+
style: { display: "block", flexShrink: 0 }
|
|
221
|
+
}
|
|
222
|
+
),
|
|
223
|
+
showCopyTooltip && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: tooltipStyles, children: "Copy breadcrumb trail" })
|
|
224
|
+
]
|
|
225
|
+
}
|
|
226
|
+
)
|
|
227
|
+
] }, index);
|
|
228
|
+
}
|
|
229
|
+
const Element = breadcrumbItem.href ? "a" : "button";
|
|
230
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(React.Fragment, { children: [
|
|
231
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
232
|
+
Element,
|
|
233
|
+
{
|
|
234
|
+
...breadcrumbItem.href ? { href: breadcrumbItem.href } : {},
|
|
235
|
+
style: {
|
|
236
|
+
...breadcrumbItemStyles(index, false),
|
|
237
|
+
border: "none",
|
|
238
|
+
background: "transparent"
|
|
239
|
+
},
|
|
240
|
+
onClick: (e) => {
|
|
241
|
+
if (!breadcrumbItem.href && breadcrumbItem.onClick) {
|
|
242
|
+
e.preventDefault();
|
|
243
|
+
breadcrumbItem.onClick();
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
onMouseEnter: () => setHoveredIndex(index),
|
|
247
|
+
onMouseLeave: () => setHoveredIndex(null),
|
|
248
|
+
onFocus: () => setFocusedIndex(index),
|
|
249
|
+
onBlur: () => setFocusedIndex(null),
|
|
250
|
+
children: [
|
|
251
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: linkStyles(false, hoveredIndex === index), children: breadcrumbItem.label }),
|
|
252
|
+
breadcrumbItem.hasDropdown && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
253
|
+
import_lucide_react.ChevronDown,
|
|
254
|
+
{
|
|
255
|
+
size: 12,
|
|
256
|
+
color: hoveredIndex === index ? "#0e8a0e" : "#595959",
|
|
257
|
+
strokeWidth: 2,
|
|
258
|
+
style: { marginLeft: "2px", display: "inline-block", flexShrink: 0 }
|
|
259
|
+
}
|
|
260
|
+
)
|
|
261
|
+
]
|
|
262
|
+
}
|
|
263
|
+
),
|
|
264
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: dividerStyles, children: " /" })
|
|
265
|
+
] }, index);
|
|
266
|
+
})
|
|
267
|
+
}
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
);
|
|
271
|
+
Breadcrumbs.displayName = "Breadcrumbs";
|
|
272
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
273
|
+
0 && (module.exports = {
|
|
274
|
+
Breadcrumbs
|
|
275
|
+
});
|
|
276
|
+
//# sourceMappingURL=Breadcrumbs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/Breadcrumbs/index.ts","../src/Breadcrumbs/Breadcrumbs.tsx"],"sourcesContent":["export { Breadcrumbs } from './Breadcrumbs';\nexport type { BreadcrumbsProps, BreadcrumbItem } from './Breadcrumbs';\n","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":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/Checkbox.d.mts
CHANGED
package/dist/Checkbox.d.ts
CHANGED
package/dist/Checkbox.js
CHANGED
|
@@ -40,10 +40,10 @@ var import_clsx = require("clsx");
|
|
|
40
40
|
var import_lucide_react = require("lucide-react");
|
|
41
41
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
42
42
|
var checkboxStyles = {
|
|
43
|
-
width: "
|
|
44
|
-
height: "
|
|
45
|
-
border: "
|
|
46
|
-
// grey-
|
|
43
|
+
width: "16px",
|
|
44
|
+
height: "16px",
|
|
45
|
+
border: "1px solid #7e7e7e",
|
|
46
|
+
// grey-500
|
|
47
47
|
borderRadius: "4px",
|
|
48
48
|
display: "flex",
|
|
49
49
|
alignItems: "center",
|
|
@@ -54,9 +54,18 @@ var checkboxStyles = {
|
|
|
54
54
|
backgroundColor: "#ffffff"
|
|
55
55
|
};
|
|
56
56
|
var checkedStyles = {
|
|
57
|
-
backgroundColor: "#
|
|
58
|
-
// brand-
|
|
59
|
-
|
|
57
|
+
backgroundColor: "#0e8a0e",
|
|
58
|
+
// brand-600
|
|
59
|
+
border: "1px solid #0e8a0e"
|
|
60
|
+
};
|
|
61
|
+
var checkedHoverStyles = {
|
|
62
|
+
backgroundColor: "#005700",
|
|
63
|
+
// brand-800
|
|
64
|
+
border: "1px solid #005700"
|
|
65
|
+
};
|
|
66
|
+
var uncheckedHoverStyles = {
|
|
67
|
+
border: "1px solid #474747"
|
|
68
|
+
// grey-700
|
|
60
69
|
};
|
|
61
70
|
var labelStyles = {
|
|
62
71
|
fontSize: "13px",
|
|
@@ -80,10 +89,24 @@ var Checkbox = React.forwardRef(
|
|
|
80
89
|
style,
|
|
81
90
|
"data-testid": dataTestId,
|
|
82
91
|
name,
|
|
83
|
-
value
|
|
92
|
+
value,
|
|
93
|
+
indeterminate = false
|
|
84
94
|
}, ref) => {
|
|
85
95
|
const [isFocused, setIsFocused] = React.useState(false);
|
|
96
|
+
const [isHovered, setIsHovered] = React.useState(false);
|
|
86
97
|
const checkboxId = React.useId();
|
|
98
|
+
const innerRef = React.useRef(null);
|
|
99
|
+
React.useEffect(() => {
|
|
100
|
+
const node = innerRef.current;
|
|
101
|
+
if (node) {
|
|
102
|
+
node.indeterminate = indeterminate;
|
|
103
|
+
if (typeof ref === "function") {
|
|
104
|
+
ref(node);
|
|
105
|
+
} else if (ref) {
|
|
106
|
+
ref.current = node;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}, [indeterminate, ref]);
|
|
87
110
|
const handleChange = (e) => {
|
|
88
111
|
if (!disabled) {
|
|
89
112
|
onChange?.(e.target.checked);
|
|
@@ -91,12 +114,16 @@ var Checkbox = React.forwardRef(
|
|
|
91
114
|
};
|
|
92
115
|
const boxStyle = {
|
|
93
116
|
...checkboxStyles,
|
|
94
|
-
...checked && !disabled && checkedStyles,
|
|
95
|
-
...
|
|
96
|
-
...
|
|
97
|
-
...
|
|
117
|
+
...(checked || indeterminate) && !disabled && checkedStyles,
|
|
118
|
+
...isHovered && !disabled && !(checked || indeterminate) && uncheckedHoverStyles,
|
|
119
|
+
...isHovered && !disabled && (checked || indeterminate) && checkedHoverStyles,
|
|
120
|
+
...disabled && !checked && !indeterminate && { backgroundColor: "#efefef", border: "1px solid #b3b3b3" },
|
|
121
|
+
...disabled && (checked || indeterminate) && { backgroundColor: "#b3b3b3", border: "1px solid #b3b3b3" },
|
|
122
|
+
...isFocused && !disabled && {
|
|
123
|
+
boxShadow: "0px 0px 0px 3px #3cad51"
|
|
124
|
+
}
|
|
98
125
|
};
|
|
99
|
-
const checkmarkColor =
|
|
126
|
+
const checkmarkColor = "#ffffff";
|
|
100
127
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
101
128
|
"div",
|
|
102
129
|
{
|
|
@@ -107,7 +134,7 @@ var Checkbox = React.forwardRef(
|
|
|
107
134
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
108
135
|
"input",
|
|
109
136
|
{
|
|
110
|
-
ref,
|
|
137
|
+
ref: innerRef,
|
|
111
138
|
id: checkboxId,
|
|
112
139
|
type: "checkbox",
|
|
113
140
|
checked,
|
|
@@ -123,13 +150,15 @@ var Checkbox = React.forwardRef(
|
|
|
123
150
|
width: 0,
|
|
124
151
|
height: 0
|
|
125
152
|
},
|
|
126
|
-
"aria-checked": checked
|
|
153
|
+
"aria-checked": indeterminate ? "mixed" : checked
|
|
127
154
|
}
|
|
128
155
|
),
|
|
129
156
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
130
157
|
"label",
|
|
131
158
|
{
|
|
132
159
|
htmlFor: checkboxId,
|
|
160
|
+
onMouseEnter: () => !disabled && setIsHovered(true),
|
|
161
|
+
onMouseLeave: () => !disabled && setIsHovered(false),
|
|
133
162
|
style: {
|
|
134
163
|
display: "flex",
|
|
135
164
|
alignItems: "center",
|
|
@@ -137,7 +166,7 @@ var Checkbox = React.forwardRef(
|
|
|
137
166
|
cursor: disabled ? "not-allowed" : "pointer"
|
|
138
167
|
},
|
|
139
168
|
children: [
|
|
140
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: boxStyle, children: checked && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Check, { size:
|
|
169
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: boxStyle, children: (checked || indeterminate) && (indeterminate ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Minus, { size: 12, color: checkmarkColor, strokeWidth: 3 }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Check, { size: 16, color: checkmarkColor, strokeWidth: 3 })) }),
|
|
141
170
|
label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
142
171
|
"span",
|
|
143
172
|
{
|
package/dist/Checkbox.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/Checkbox/index.ts","../src/Checkbox/Checkbox.tsx"],"sourcesContent":["export { Checkbox } from './Checkbox';\nexport type { CheckboxProps } from './Checkbox';\n","import * as React from 'react';\nimport { clsx } from 'clsx';\nimport { Check } from 'lucide-react';\n\nexport interface CheckboxProps {\n /**\n * The label for the checkbox\n */\n label?: string;\n /**\n * Whether the checkbox is checked\n */\n checked?: boolean;\n /**\n * Callback when checked state changes\n */\n onChange?: (checked: boolean) => void;\n /**\n * Whether the checkbox is disabled\n */\n disabled?: boolean;\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 * Name attribute for form submission\n */\n name?: string;\n /**\n * Value attribute for form submission\n */\n value?: string;\n}\n\nconst checkboxStyles: React.CSSProperties = {\n width: '
|
|
1
|
+
{"version":3,"sources":["../src/Checkbox/index.ts","../src/Checkbox/Checkbox.tsx"],"sourcesContent":["export { Checkbox } from './Checkbox';\nexport type { CheckboxProps } from './Checkbox';\n","import * as React from 'react';\nimport { clsx } from 'clsx';\nimport { Check, Minus } from 'lucide-react';\n\nexport interface CheckboxProps {\n /**\n * The label for the checkbox\n */\n label?: string;\n /**\n * Whether the checkbox is checked\n */\n checked?: boolean;\n /**\n * Callback when checked state changes\n */\n onChange?: (checked: boolean) => void;\n /**\n * Whether the checkbox is disabled\n */\n disabled?: boolean;\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 * Name attribute for form submission\n */\n name?: string;\n /**\n * Value attribute for form submission\n */\n value?: string;\n /**\n * Indeterminate state (shows minus icon)\n */\n indeterminate?: boolean;\n}\n\nconst checkboxStyles: React.CSSProperties = {\n width: '16px',\n height: '16px',\n border: '1px solid #7e7e7e', // grey-500\n borderRadius: '4px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n cursor: 'pointer',\n transition: 'all 0.2s ease-in-out',\n flexShrink: 0,\n backgroundColor: '#ffffff',\n};\n\nconst checkedStyles: React.CSSProperties = {\n backgroundColor: '#0e8a0e', // brand-600\n border: '1px solid #0e8a0e',\n};\n\nconst checkedHoverStyles: React.CSSProperties = {\n backgroundColor: '#005700', // brand-800\n border: '1px solid #005700',\n};\n\nconst uncheckedHoverStyles: React.CSSProperties = {\n border: '1px solid #474747', // grey-700\n};\n\nconst labelStyles: React.CSSProperties = {\n fontSize: '13px',\n color: '#2f2f2f',\n cursor: 'pointer',\n userSelect: 'none' as const,\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n};\n\nconst wrapperStyles: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n};\n\n/**\n * Checkbox component - Arbor Design System\n *\n * A checkbox input with label support.\n */\nexport const Checkbox = React.forwardRef<HTMLInputElement, CheckboxProps>(\n (\n {\n label,\n checked = false,\n onChange,\n disabled = false,\n className,\n style,\n 'data-testid': dataTestId,\n name,\n value,\n indeterminate = false,\n },\n ref\n ) => {\n const [isFocused, setIsFocused] = React.useState(false);\n const [isHovered, setIsHovered] = React.useState(false);\n const checkboxId = React.useId();\n const innerRef = React.useRef<HTMLInputElement | null>(null);\n\n // Merge refs\n React.useEffect(() => {\n const node = innerRef.current;\n if (node) {\n // Set indeterminate property on the native input element\n node.indeterminate = indeterminate;\n\n // Forward to external ref if provided\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }\n }\n }, [indeterminate, ref]);\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!disabled) {\n onChange?.(e.target.checked);\n }\n };\n\n const boxStyle: React.CSSProperties = {\n ...checkboxStyles,\n ...((checked || indeterminate) && !disabled && checkedStyles),\n ...(isHovered && !disabled && !(checked || indeterminate) && uncheckedHoverStyles),\n ...(isHovered && !disabled && (checked || indeterminate) && checkedHoverStyles),\n ...(disabled && !checked && !indeterminate && { backgroundColor: '#efefef', border: '1px solid #b3b3b3' }),\n ...(disabled && (checked || indeterminate) && { backgroundColor: '#b3b3b3', border: '1px solid #b3b3b3' }),\n ...(isFocused && !disabled && {\n boxShadow: '0px 0px 0px 3px #3cad51',\n }),\n };\n\n const checkmarkColor = '#ffffff';\n\n return (\n <div\n className={clsx('arbor-checkbox-wrapper', className)}\n style={{ ...wrapperStyles, ...style }}\n data-testid={dataTestId}\n >\n <input\n ref={innerRef}\n id={checkboxId}\n type=\"checkbox\"\n checked={checked}\n onChange={handleChange}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n disabled={disabled}\n name={name}\n value={value}\n style={{\n position: 'absolute',\n opacity: 0,\n width: 0,\n height: 0,\n }}\n aria-checked={indeterminate ? 'mixed' : checked}\n />\n <label\n htmlFor={checkboxId}\n onMouseEnter={() => !disabled && setIsHovered(true)}\n onMouseLeave={() => !disabled && setIsHovered(false)}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n cursor: disabled ? 'not-allowed' : 'pointer',\n }}\n >\n <div style={boxStyle}>\n {(checked || indeterminate) && (\n indeterminate ? (\n <Minus size={12} color={checkmarkColor} strokeWidth={3} />\n ) : (\n <Check size={16} color={checkmarkColor} strokeWidth={3} />\n )\n )}\n </div>\n {label && (\n <span\n style={{\n ...labelStyles,\n color: disabled ? '#7e7e7e' : '#2f2f2f',\n cursor: disabled ? 'not-allowed' : 'pointer',\n }}\n >\n {label}\n </span>\n )}\n </label>\n </div>\n );\n }\n);\n\nCheckbox.displayName = 'Checkbox';\n"],"mappings":"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","names":[]}
|