@tonyarbor/components 0.1.0 → 0.2.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.
- 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/Checkbox.d.mts +52 -0
- package/dist/Checkbox.d.ts +52 -0
- package/dist/Checkbox.js +194 -0
- package/dist/Checkbox.js.map +1 -0
- package/dist/Checkbox.mjs +7 -0
- package/dist/Checkbox.mjs.map +1 -0
- package/dist/Combobox.d.mts +67 -0
- package/dist/Combobox.d.ts +67 -0
- package/dist/Combobox.js +329 -0
- package/dist/Combobox.js.map +1 -0
- package/dist/Combobox.mjs +7 -0
- package/dist/Combobox.mjs.map +1 -0
- 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/NumericInput.d.mts +68 -0
- package/dist/NumericInput.d.ts +68 -0
- package/dist/NumericInput.js +319 -0
- package/dist/NumericInput.js.map +1 -0
- package/dist/NumericInput.mjs +7 -0
- package/dist/NumericInput.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.d.mts +48 -0
- package/dist/Radio.d.ts +48 -0
- package/dist/Radio.js +194 -0
- package/dist/Radio.js.map +1 -0
- package/dist/Radio.mjs +7 -0
- package/dist/Radio.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-5BUXFTPW.mjs +283 -0
- package/dist/chunk-5BUXFTPW.mjs.map +1 -0
- package/dist/chunk-7OWLBYNM.mjs +293 -0
- package/dist/chunk-7OWLBYNM.mjs.map +1 -0
- package/dist/chunk-AI2U34CF.mjs +159 -0
- package/dist/chunk-AI2U34CF.mjs.map +1 -0
- package/dist/chunk-C25FFMRQ.mjs +255 -0
- package/dist/chunk-C25FFMRQ.mjs.map +1 -0
- package/dist/chunk-CUTYEIFE.mjs +158 -0
- 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-M6DVBEEL.mjs +158 -0
- 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-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-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 +22 -1
- package/dist/index.d.ts +22 -1
- package/dist/index.js +3559 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +61 -1
- package/package.json +81 -3
|
@@ -0,0 +1,301 @@
|
|
|
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/Pagination/index.ts
|
|
31
|
+
var Pagination_exports = {};
|
|
32
|
+
__export(Pagination_exports, {
|
|
33
|
+
Pagination: () => Pagination
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(Pagination_exports);
|
|
36
|
+
|
|
37
|
+
// src/Pagination/Pagination.tsx
|
|
38
|
+
var React = __toESM(require("react"));
|
|
39
|
+
var import_clsx = require("clsx");
|
|
40
|
+
var import_lucide_react = require("lucide-react");
|
|
41
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
42
|
+
var containerStyles = {
|
|
43
|
+
display: "flex",
|
|
44
|
+
alignItems: "center",
|
|
45
|
+
gap: "8px",
|
|
46
|
+
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
|
|
47
|
+
};
|
|
48
|
+
var buttonStyles = {
|
|
49
|
+
width: "24px",
|
|
50
|
+
height: "24px",
|
|
51
|
+
borderRadius: "50%",
|
|
52
|
+
border: "none",
|
|
53
|
+
background: "transparent",
|
|
54
|
+
cursor: "pointer",
|
|
55
|
+
display: "flex",
|
|
56
|
+
alignItems: "center",
|
|
57
|
+
justifyContent: "center",
|
|
58
|
+
padding: 0,
|
|
59
|
+
transition: "background-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out",
|
|
60
|
+
flexShrink: 0,
|
|
61
|
+
WebkitTapHighlightColor: "transparent",
|
|
62
|
+
outline: "none"
|
|
63
|
+
};
|
|
64
|
+
var buttonDisabledStyles = {
|
|
65
|
+
cursor: "not-allowed",
|
|
66
|
+
opacity: 0.5
|
|
67
|
+
};
|
|
68
|
+
var labelStyles = {
|
|
69
|
+
fontSize: "13px",
|
|
70
|
+
fontWeight: 600,
|
|
71
|
+
lineHeight: "1.5",
|
|
72
|
+
color: "#2f2f2f"
|
|
73
|
+
};
|
|
74
|
+
var inputWrapperStyles = {
|
|
75
|
+
display: "flex",
|
|
76
|
+
alignItems: "center",
|
|
77
|
+
gap: "8px"
|
|
78
|
+
};
|
|
79
|
+
var inputStyles = {
|
|
80
|
+
width: "60px",
|
|
81
|
+
paddingTop: "12px",
|
|
82
|
+
paddingBottom: "12px",
|
|
83
|
+
paddingLeft: "16px",
|
|
84
|
+
paddingRight: "16px",
|
|
85
|
+
fontSize: "13px",
|
|
86
|
+
fontWeight: 400,
|
|
87
|
+
lineHeight: "1.5",
|
|
88
|
+
color: "#2f2f2f",
|
|
89
|
+
backgroundColor: "white",
|
|
90
|
+
border: "1px solid #dfdfdf",
|
|
91
|
+
borderRadius: "8px",
|
|
92
|
+
fontFamily: "inherit",
|
|
93
|
+
textAlign: "center",
|
|
94
|
+
outline: "none"
|
|
95
|
+
};
|
|
96
|
+
var inputFocusStyles = {
|
|
97
|
+
boxShadow: "0px 0px 0px 3px #3cad51"
|
|
98
|
+
};
|
|
99
|
+
var textStyles = {
|
|
100
|
+
fontSize: "13px",
|
|
101
|
+
fontWeight: 400,
|
|
102
|
+
lineHeight: "1.5",
|
|
103
|
+
color: "#2f2f2f"
|
|
104
|
+
};
|
|
105
|
+
var Pagination = React.forwardRef(
|
|
106
|
+
({
|
|
107
|
+
currentPage,
|
|
108
|
+
totalPages,
|
|
109
|
+
onPageChange,
|
|
110
|
+
className,
|
|
111
|
+
style,
|
|
112
|
+
"data-testid": dataTestId
|
|
113
|
+
}, ref) => {
|
|
114
|
+
const [inputValue, setInputValue] = React.useState(currentPage.toString());
|
|
115
|
+
const [focusedButton, setFocusedButton] = React.useState(null);
|
|
116
|
+
const [hoveredButton, setHoveredButton] = React.useState(null);
|
|
117
|
+
const [activeButton, setActiveButton] = React.useState(null);
|
|
118
|
+
const [inputFocused, setInputFocused] = React.useState(false);
|
|
119
|
+
React.useEffect(() => {
|
|
120
|
+
setInputValue(currentPage.toString());
|
|
121
|
+
}, [currentPage]);
|
|
122
|
+
const handleFirstPage = () => {
|
|
123
|
+
if (currentPage !== 1) {
|
|
124
|
+
onPageChange(1);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
const handlePreviousPage = () => {
|
|
128
|
+
if (currentPage > 1) {
|
|
129
|
+
onPageChange(currentPage - 1);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
const handleNextPage = () => {
|
|
133
|
+
if (currentPage < totalPages) {
|
|
134
|
+
onPageChange(currentPage + 1);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
const handleLastPage = () => {
|
|
138
|
+
if (currentPage !== totalPages) {
|
|
139
|
+
onPageChange(totalPages);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const handleInputChange = (e) => {
|
|
143
|
+
const value = e.target.value;
|
|
144
|
+
if (value === "" || /^\d+$/.test(value)) {
|
|
145
|
+
setInputValue(value);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
const handleInputBlur = () => {
|
|
149
|
+
setInputFocused(false);
|
|
150
|
+
const pageNumber = parseInt(inputValue, 10);
|
|
151
|
+
if (isNaN(pageNumber) || pageNumber < 1) {
|
|
152
|
+
setInputValue(currentPage.toString());
|
|
153
|
+
} else if (pageNumber > totalPages) {
|
|
154
|
+
setInputValue(totalPages.toString());
|
|
155
|
+
onPageChange(totalPages);
|
|
156
|
+
} else if (pageNumber !== currentPage) {
|
|
157
|
+
onPageChange(pageNumber);
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
const handleInputKeyDown = (e) => {
|
|
161
|
+
if (e.key === "Enter") {
|
|
162
|
+
handleInputBlur();
|
|
163
|
+
e.target.blur();
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
const getButtonStyle = (buttonName, disabled) => {
|
|
167
|
+
if (disabled) {
|
|
168
|
+
return { ...buttonStyles, ...buttonDisabledStyles };
|
|
169
|
+
}
|
|
170
|
+
const isHovered = hoveredButton === buttonName;
|
|
171
|
+
const isFocused = focusedButton === buttonName;
|
|
172
|
+
const isActive = activeButton === buttonName;
|
|
173
|
+
const style2 = {
|
|
174
|
+
...buttonStyles
|
|
175
|
+
};
|
|
176
|
+
if (isHovered && !isFocused && !isActive) {
|
|
177
|
+
style2.backgroundColor = "#efefef";
|
|
178
|
+
}
|
|
179
|
+
if (isActive && !isFocused) {
|
|
180
|
+
style2.backgroundColor = "transparent";
|
|
181
|
+
}
|
|
182
|
+
if (isFocused) {
|
|
183
|
+
style2.boxShadow = "0px 0px 0px 3px #3cad51";
|
|
184
|
+
style2.backgroundColor = "rgba(255, 255, 255, 0.01)";
|
|
185
|
+
}
|
|
186
|
+
return style2;
|
|
187
|
+
};
|
|
188
|
+
const isFirstDisabled = currentPage === 1;
|
|
189
|
+
const isPreviousDisabled = currentPage === 1;
|
|
190
|
+
const isNextDisabled = currentPage === totalPages;
|
|
191
|
+
const isLastDisabled = currentPage === totalPages;
|
|
192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
193
|
+
"div",
|
|
194
|
+
{
|
|
195
|
+
ref,
|
|
196
|
+
className: (0, import_clsx.clsx)("arbor-pagination", className),
|
|
197
|
+
style: { ...containerStyles, ...style },
|
|
198
|
+
"data-testid": dataTestId,
|
|
199
|
+
children: [
|
|
200
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
201
|
+
"button",
|
|
202
|
+
{
|
|
203
|
+
type: "button",
|
|
204
|
+
onClick: handleFirstPage,
|
|
205
|
+
disabled: isFirstDisabled,
|
|
206
|
+
onMouseEnter: () => setHoveredButton("first"),
|
|
207
|
+
onMouseLeave: () => setHoveredButton(null),
|
|
208
|
+
onMouseDown: () => setActiveButton("first"),
|
|
209
|
+
onMouseUp: () => setActiveButton(null),
|
|
210
|
+
onFocus: () => setFocusedButton("first"),
|
|
211
|
+
onBlur: () => setFocusedButton(null),
|
|
212
|
+
style: getButtonStyle("first", isFirstDisabled),
|
|
213
|
+
"aria-label": "Go to first page",
|
|
214
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ChevronsLeft, { size: 16, color: "#2f2f2f" })
|
|
215
|
+
}
|
|
216
|
+
),
|
|
217
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
218
|
+
"button",
|
|
219
|
+
{
|
|
220
|
+
type: "button",
|
|
221
|
+
onClick: handlePreviousPage,
|
|
222
|
+
disabled: isPreviousDisabled,
|
|
223
|
+
onMouseEnter: () => setHoveredButton("previous"),
|
|
224
|
+
onMouseLeave: () => setHoveredButton(null),
|
|
225
|
+
onMouseDown: () => setActiveButton("previous"),
|
|
226
|
+
onMouseUp: () => setActiveButton(null),
|
|
227
|
+
onFocus: () => setFocusedButton("previous"),
|
|
228
|
+
onBlur: () => setFocusedButton(null),
|
|
229
|
+
style: getButtonStyle("previous", isPreviousDisabled),
|
|
230
|
+
"aria-label": "Go to previous page",
|
|
231
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ChevronLeft, { size: 16, color: "#2f2f2f" })
|
|
232
|
+
}
|
|
233
|
+
),
|
|
234
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: inputWrapperStyles, children: [
|
|
235
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: labelStyles, children: "Page" }),
|
|
236
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
237
|
+
"input",
|
|
238
|
+
{
|
|
239
|
+
type: "text",
|
|
240
|
+
value: inputValue,
|
|
241
|
+
onChange: handleInputChange,
|
|
242
|
+
onBlur: handleInputBlur,
|
|
243
|
+
onFocus: () => setInputFocused(true),
|
|
244
|
+
onKeyDown: handleInputKeyDown,
|
|
245
|
+
style: {
|
|
246
|
+
...inputStyles,
|
|
247
|
+
...inputFocused && inputFocusStyles
|
|
248
|
+
},
|
|
249
|
+
"aria-label": `Page ${currentPage} of ${totalPages}`
|
|
250
|
+
}
|
|
251
|
+
),
|
|
252
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: textStyles, children: [
|
|
253
|
+
"of ",
|
|
254
|
+
totalPages
|
|
255
|
+
] })
|
|
256
|
+
] }),
|
|
257
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
258
|
+
"button",
|
|
259
|
+
{
|
|
260
|
+
type: "button",
|
|
261
|
+
onClick: handleNextPage,
|
|
262
|
+
disabled: isNextDisabled,
|
|
263
|
+
onMouseEnter: () => setHoveredButton("next"),
|
|
264
|
+
onMouseLeave: () => setHoveredButton(null),
|
|
265
|
+
onMouseDown: () => setActiveButton("next"),
|
|
266
|
+
onMouseUp: () => setActiveButton(null),
|
|
267
|
+
onFocus: () => setFocusedButton("next"),
|
|
268
|
+
onBlur: () => setFocusedButton(null),
|
|
269
|
+
style: getButtonStyle("next", isNextDisabled),
|
|
270
|
+
"aria-label": "Go to next page",
|
|
271
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ChevronRight, { size: 16, color: "#2f2f2f" })
|
|
272
|
+
}
|
|
273
|
+
),
|
|
274
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
275
|
+
"button",
|
|
276
|
+
{
|
|
277
|
+
type: "button",
|
|
278
|
+
onClick: handleLastPage,
|
|
279
|
+
disabled: isLastDisabled,
|
|
280
|
+
onMouseEnter: () => setHoveredButton("last"),
|
|
281
|
+
onMouseLeave: () => setHoveredButton(null),
|
|
282
|
+
onMouseDown: () => setActiveButton("last"),
|
|
283
|
+
onMouseUp: () => setActiveButton(null),
|
|
284
|
+
onFocus: () => setFocusedButton("last"),
|
|
285
|
+
onBlur: () => setFocusedButton(null),
|
|
286
|
+
style: getButtonStyle("last", isLastDisabled),
|
|
287
|
+
"aria-label": "Go to last page",
|
|
288
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ChevronsRight, { size: 16, color: "#2f2f2f" })
|
|
289
|
+
}
|
|
290
|
+
)
|
|
291
|
+
]
|
|
292
|
+
}
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
);
|
|
296
|
+
Pagination.displayName = "Pagination";
|
|
297
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
298
|
+
0 && (module.exports = {
|
|
299
|
+
Pagination
|
|
300
|
+
});
|
|
301
|
+
//# sourceMappingURL=Pagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/Pagination/index.ts","../src/Pagination/Pagination.tsx"],"sourcesContent":["export { Pagination } from './Pagination';\nexport type { PaginationProps } from './Pagination';\n","import * as React from 'react';\nimport { clsx } from 'clsx';\nimport { ChevronsLeft, ChevronLeft, ChevronRight, ChevronsRight } from 'lucide-react';\n\nexport interface PaginationProps {\n /**\n * Current page number (1-indexed)\n */\n currentPage: number;\n /**\n * Total number of pages\n */\n totalPages: number;\n /**\n * Callback when page changes\n */\n onPageChange: (page: number) => 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\nconst containerStyles: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n};\n\nconst buttonStyles: React.CSSProperties = {\n width: '24px',\n height: '24px',\n borderRadius: '50%',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: 0,\n transition: 'background-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out',\n flexShrink: 0,\n WebkitTapHighlightColor: 'transparent',\n outline: 'none',\n};\n\nconst buttonDisabledStyles: React.CSSProperties = {\n cursor: 'not-allowed',\n opacity: 0.5,\n};\n\nconst labelStyles: React.CSSProperties = {\n fontSize: '13px',\n fontWeight: 600,\n lineHeight: '1.5',\n color: '#2f2f2f',\n};\n\nconst inputWrapperStyles: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n};\n\nconst inputStyles: React.CSSProperties = {\n width: '60px',\n paddingTop: '12px',\n paddingBottom: '12px',\n paddingLeft: '16px',\n paddingRight: '16px',\n fontSize: '13px',\n fontWeight: 400,\n lineHeight: '1.5',\n color: '#2f2f2f',\n backgroundColor: 'white',\n border: '1px solid #dfdfdf',\n borderRadius: '8px',\n fontFamily: 'inherit',\n textAlign: 'center',\n outline: 'none',\n};\n\nconst inputFocusStyles: React.CSSProperties = {\n boxShadow: '0px 0px 0px 3px #3cad51',\n};\n\nconst textStyles: React.CSSProperties = {\n fontSize: '13px',\n fontWeight: 400,\n lineHeight: '1.5',\n color: '#2f2f2f',\n};\n\n/**\n * Pagination component - Arbor Design System\n *\n * A pagination control with first/previous/next/last buttons and a page input field.\n */\nexport const Pagination = React.forwardRef<HTMLDivElement, PaginationProps>(\n (\n {\n currentPage,\n totalPages,\n onPageChange,\n className,\n style,\n 'data-testid': dataTestId,\n },\n ref\n ) => {\n const [inputValue, setInputValue] = React.useState(currentPage.toString());\n const [focusedButton, setFocusedButton] = React.useState<string | null>(null);\n const [hoveredButton, setHoveredButton] = React.useState<string | null>(null);\n const [activeButton, setActiveButton] = React.useState<string | null>(null);\n const [inputFocused, setInputFocused] = React.useState(false);\n\n React.useEffect(() => {\n setInputValue(currentPage.toString());\n }, [currentPage]);\n\n const handleFirstPage = () => {\n if (currentPage !== 1) {\n onPageChange(1);\n }\n };\n\n const handlePreviousPage = () => {\n if (currentPage > 1) {\n onPageChange(currentPage - 1);\n }\n };\n\n const handleNextPage = () => {\n if (currentPage < totalPages) {\n onPageChange(currentPage + 1);\n }\n };\n\n const handleLastPage = () => {\n if (currentPage !== totalPages) {\n onPageChange(totalPages);\n }\n };\n\n const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value;\n // Allow empty or valid numbers\n if (value === '' || /^\\d+$/.test(value)) {\n setInputValue(value);\n }\n };\n\n const handleInputBlur = () => {\n setInputFocused(false);\n const pageNumber = parseInt(inputValue, 10);\n if (isNaN(pageNumber) || pageNumber < 1) {\n setInputValue(currentPage.toString());\n } else if (pageNumber > totalPages) {\n setInputValue(totalPages.toString());\n onPageChange(totalPages);\n } else if (pageNumber !== currentPage) {\n onPageChange(pageNumber);\n }\n };\n\n const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n handleInputBlur();\n (e.target as HTMLInputElement).blur();\n }\n };\n\n const getButtonStyle = (buttonName: string, disabled: boolean): React.CSSProperties => {\n if (disabled) {\n return { ...buttonStyles, ...buttonDisabledStyles };\n }\n\n const isHovered = hoveredButton === buttonName;\n const isFocused = focusedButton === buttonName;\n const isActive = activeButton === buttonName;\n\n const style: React.CSSProperties = {\n ...buttonStyles,\n };\n\n // Apply hover state (light gray background)\n if (isHovered && !isFocused && !isActive) {\n style.backgroundColor = '#efefef';\n }\n\n // Apply active state (same as hover or transparent)\n if (isActive && !isFocused) {\n style.backgroundColor = 'transparent';\n }\n\n // Apply focus state (green ring, transparent background)\n if (isFocused) {\n style.boxShadow = '0px 0px 0px 3px #3cad51';\n style.backgroundColor = 'rgba(255, 255, 255, 0.01)';\n }\n\n return style;\n };\n\n const isFirstDisabled = currentPage === 1;\n const isPreviousDisabled = currentPage === 1;\n const isNextDisabled = currentPage === totalPages;\n const isLastDisabled = currentPage === totalPages;\n\n return (\n <div\n ref={ref}\n className={clsx('arbor-pagination', className)}\n style={{ ...containerStyles, ...style }}\n data-testid={dataTestId}\n >\n {/* First page button */}\n <button\n type=\"button\"\n onClick={handleFirstPage}\n disabled={isFirstDisabled}\n onMouseEnter={() => setHoveredButton('first')}\n onMouseLeave={() => setHoveredButton(null)}\n onMouseDown={() => setActiveButton('first')}\n onMouseUp={() => setActiveButton(null)}\n onFocus={() => setFocusedButton('first')}\n onBlur={() => setFocusedButton(null)}\n style={getButtonStyle('first', isFirstDisabled)}\n aria-label=\"Go to first page\"\n >\n <ChevronsLeft size={16} color=\"#2f2f2f\" />\n </button>\n\n {/* Previous page button */}\n <button\n type=\"button\"\n onClick={handlePreviousPage}\n disabled={isPreviousDisabled}\n onMouseEnter={() => setHoveredButton('previous')}\n onMouseLeave={() => setHoveredButton(null)}\n onMouseDown={() => setActiveButton('previous')}\n onMouseUp={() => setActiveButton(null)}\n onFocus={() => setFocusedButton('previous')}\n onBlur={() => setFocusedButton(null)}\n style={getButtonStyle('previous', isPreviousDisabled)}\n aria-label=\"Go to previous page\"\n >\n <ChevronLeft size={16} color=\"#2f2f2f\" />\n </button>\n\n {/* Page input */}\n <div style={inputWrapperStyles}>\n <span style={labelStyles}>Page</span>\n <input\n type=\"text\"\n value={inputValue}\n onChange={handleInputChange}\n onBlur={handleInputBlur}\n onFocus={() => setInputFocused(true)}\n onKeyDown={handleInputKeyDown}\n style={{\n ...inputStyles,\n ...(inputFocused && inputFocusStyles),\n }}\n aria-label={`Page ${currentPage} of ${totalPages}`}\n />\n <span style={textStyles}>of {totalPages}</span>\n </div>\n\n {/* Next page button */}\n <button\n type=\"button\"\n onClick={handleNextPage}\n disabled={isNextDisabled}\n onMouseEnter={() => setHoveredButton('next')}\n onMouseLeave={() => setHoveredButton(null)}\n onMouseDown={() => setActiveButton('next')}\n onMouseUp={() => setActiveButton(null)}\n onFocus={() => setFocusedButton('next')}\n onBlur={() => setFocusedButton(null)}\n style={getButtonStyle('next', isNextDisabled)}\n aria-label=\"Go to next page\"\n >\n <ChevronRight size={16} color=\"#2f2f2f\" />\n </button>\n\n {/* Last page button */}\n <button\n type=\"button\"\n onClick={handleLastPage}\n disabled={isLastDisabled}\n onMouseEnter={() => setHoveredButton('last')}\n onMouseLeave={() => setHoveredButton(null)}\n onMouseDown={() => setActiveButton('last')}\n onMouseUp={() => setActiveButton(null)}\n onFocus={() => setFocusedButton('last')}\n onBlur={() => setFocusedButton(null)}\n style={getButtonStyle('last', isLastDisabled)}\n aria-label=\"Go to last page\"\n >\n <ChevronsRight size={16} color=\"#2f2f2f\" />\n </button>\n </div>\n );\n }\n);\n\nPagination.displayName = 'Pagination';\n"],"mappings":"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","names":["style"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/Radio.d.mts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
interface RadioProps {
|
|
4
|
+
/**
|
|
5
|
+
* The label for the radio button
|
|
6
|
+
*/
|
|
7
|
+
label?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Whether the radio is selected
|
|
10
|
+
*/
|
|
11
|
+
checked?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Callback when selection changes
|
|
14
|
+
*/
|
|
15
|
+
onChange?: (checked: boolean) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Whether the radio is disabled
|
|
18
|
+
*/
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Custom className
|
|
22
|
+
*/
|
|
23
|
+
className?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Custom style
|
|
26
|
+
*/
|
|
27
|
+
style?: React.CSSProperties;
|
|
28
|
+
/**
|
|
29
|
+
* Test ID for testing
|
|
30
|
+
*/
|
|
31
|
+
'data-testid'?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Name attribute for form submission (groups radios together)
|
|
34
|
+
*/
|
|
35
|
+
name?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Value attribute for form submission
|
|
38
|
+
*/
|
|
39
|
+
value?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Radio component - Arbor Design System
|
|
43
|
+
*
|
|
44
|
+
* A radio button input with label support.
|
|
45
|
+
*/
|
|
46
|
+
declare const Radio: React.ForwardRefExoticComponent<RadioProps & React.RefAttributes<HTMLInputElement>>;
|
|
47
|
+
|
|
48
|
+
export { Radio, type RadioProps };
|
package/dist/Radio.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
interface RadioProps {
|
|
4
|
+
/**
|
|
5
|
+
* The label for the radio button
|
|
6
|
+
*/
|
|
7
|
+
label?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Whether the radio is selected
|
|
10
|
+
*/
|
|
11
|
+
checked?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Callback when selection changes
|
|
14
|
+
*/
|
|
15
|
+
onChange?: (checked: boolean) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Whether the radio is disabled
|
|
18
|
+
*/
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Custom className
|
|
22
|
+
*/
|
|
23
|
+
className?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Custom style
|
|
26
|
+
*/
|
|
27
|
+
style?: React.CSSProperties;
|
|
28
|
+
/**
|
|
29
|
+
* Test ID for testing
|
|
30
|
+
*/
|
|
31
|
+
'data-testid'?: string;
|
|
32
|
+
/**
|
|
33
|
+
* Name attribute for form submission (groups radios together)
|
|
34
|
+
*/
|
|
35
|
+
name?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Value attribute for form submission
|
|
38
|
+
*/
|
|
39
|
+
value?: string;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Radio component - Arbor Design System
|
|
43
|
+
*
|
|
44
|
+
* A radio button input with label support.
|
|
45
|
+
*/
|
|
46
|
+
declare const Radio: React.ForwardRefExoticComponent<RadioProps & React.RefAttributes<HTMLInputElement>>;
|
|
47
|
+
|
|
48
|
+
export { Radio, type RadioProps };
|
package/dist/Radio.js
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
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/Radio/index.ts
|
|
31
|
+
var Radio_exports = {};
|
|
32
|
+
__export(Radio_exports, {
|
|
33
|
+
Radio: () => Radio
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(Radio_exports);
|
|
36
|
+
|
|
37
|
+
// src/Radio/Radio.tsx
|
|
38
|
+
var React = __toESM(require("react"));
|
|
39
|
+
var import_clsx = require("clsx");
|
|
40
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
41
|
+
var radioStyles = {
|
|
42
|
+
width: "16px",
|
|
43
|
+
height: "16px",
|
|
44
|
+
border: "1px solid #7e7e7e",
|
|
45
|
+
// grey-500
|
|
46
|
+
borderRadius: "50%",
|
|
47
|
+
display: "flex",
|
|
48
|
+
alignItems: "center",
|
|
49
|
+
justifyContent: "center",
|
|
50
|
+
cursor: "pointer",
|
|
51
|
+
transition: "all 0.2s ease-in-out",
|
|
52
|
+
flexShrink: 0,
|
|
53
|
+
backgroundColor: "#ffffff"
|
|
54
|
+
};
|
|
55
|
+
var checkedStyles = {
|
|
56
|
+
border: "1px solid #0e8a0e"
|
|
57
|
+
// brand-600
|
|
58
|
+
};
|
|
59
|
+
var checkedHoverStyles = {
|
|
60
|
+
border: "1px solid #005700"
|
|
61
|
+
// brand-800
|
|
62
|
+
};
|
|
63
|
+
var uncheckedHoverStyles = {
|
|
64
|
+
border: "1px solid #2f2f2f"
|
|
65
|
+
// grey-900
|
|
66
|
+
};
|
|
67
|
+
var innerDotStyles = {
|
|
68
|
+
width: "10px",
|
|
69
|
+
height: "10px",
|
|
70
|
+
borderRadius: "50%",
|
|
71
|
+
backgroundColor: "#0e8a0e",
|
|
72
|
+
// brand-600
|
|
73
|
+
transition: "all 0.2s ease-in-out"
|
|
74
|
+
};
|
|
75
|
+
var innerDotHoverStyles = {
|
|
76
|
+
backgroundColor: "#005700"
|
|
77
|
+
// brand-800
|
|
78
|
+
};
|
|
79
|
+
var labelStyles = {
|
|
80
|
+
fontSize: "13px",
|
|
81
|
+
color: "#2f2f2f",
|
|
82
|
+
cursor: "pointer",
|
|
83
|
+
userSelect: "none",
|
|
84
|
+
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
|
|
85
|
+
};
|
|
86
|
+
var wrapperStyles = {
|
|
87
|
+
display: "flex",
|
|
88
|
+
alignItems: "center",
|
|
89
|
+
gap: "8px"
|
|
90
|
+
};
|
|
91
|
+
var Radio = React.forwardRef(
|
|
92
|
+
({
|
|
93
|
+
label,
|
|
94
|
+
checked = false,
|
|
95
|
+
onChange,
|
|
96
|
+
disabled = false,
|
|
97
|
+
className,
|
|
98
|
+
style,
|
|
99
|
+
"data-testid": dataTestId,
|
|
100
|
+
name,
|
|
101
|
+
value
|
|
102
|
+
}, ref) => {
|
|
103
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
104
|
+
const [isHovered, setIsHovered] = React.useState(false);
|
|
105
|
+
const radioId = React.useId();
|
|
106
|
+
const handleChange = (e) => {
|
|
107
|
+
if (!disabled) {
|
|
108
|
+
onChange?.(e.target.checked);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const circleStyle = {
|
|
112
|
+
...radioStyles,
|
|
113
|
+
...checked && !disabled && checkedStyles,
|
|
114
|
+
...isHovered && !disabled && !checked && uncheckedHoverStyles,
|
|
115
|
+
...isHovered && !disabled && checked && checkedHoverStyles,
|
|
116
|
+
...disabled && !checked && { backgroundColor: "#efefef", border: "1px solid #7e7e7e" },
|
|
117
|
+
...disabled && checked && { backgroundColor: "#efefef", border: "1px solid #7e7e7e" },
|
|
118
|
+
...isFocused && !disabled && {
|
|
119
|
+
boxShadow: "0px 0px 0px 3px #3cad51"
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
const dotStyle = {
|
|
123
|
+
...innerDotStyles,
|
|
124
|
+
...isHovered && !disabled && innerDotHoverStyles,
|
|
125
|
+
...disabled && { backgroundColor: "#7e7e7e" }
|
|
126
|
+
};
|
|
127
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
128
|
+
"div",
|
|
129
|
+
{
|
|
130
|
+
className: (0, import_clsx.clsx)("arbor-radio-wrapper", className),
|
|
131
|
+
style: { ...wrapperStyles, ...style },
|
|
132
|
+
"data-testid": dataTestId,
|
|
133
|
+
children: [
|
|
134
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
135
|
+
"input",
|
|
136
|
+
{
|
|
137
|
+
ref,
|
|
138
|
+
id: radioId,
|
|
139
|
+
type: "radio",
|
|
140
|
+
checked,
|
|
141
|
+
onChange: handleChange,
|
|
142
|
+
onFocus: () => setIsFocused(true),
|
|
143
|
+
onBlur: () => setIsFocused(false),
|
|
144
|
+
disabled,
|
|
145
|
+
name,
|
|
146
|
+
value,
|
|
147
|
+
style: {
|
|
148
|
+
position: "absolute",
|
|
149
|
+
opacity: 0,
|
|
150
|
+
width: 0,
|
|
151
|
+
height: 0
|
|
152
|
+
},
|
|
153
|
+
"aria-checked": checked
|
|
154
|
+
}
|
|
155
|
+
),
|
|
156
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
157
|
+
"label",
|
|
158
|
+
{
|
|
159
|
+
htmlFor: radioId,
|
|
160
|
+
onMouseEnter: () => !disabled && setIsHovered(true),
|
|
161
|
+
onMouseLeave: () => !disabled && setIsHovered(false),
|
|
162
|
+
style: {
|
|
163
|
+
display: "flex",
|
|
164
|
+
alignItems: "center",
|
|
165
|
+
gap: "8px",
|
|
166
|
+
cursor: disabled ? "not-allowed" : "pointer"
|
|
167
|
+
},
|
|
168
|
+
children: [
|
|
169
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: circleStyle, children: checked && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: dotStyle }) }),
|
|
170
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
171
|
+
"span",
|
|
172
|
+
{
|
|
173
|
+
style: {
|
|
174
|
+
...labelStyles,
|
|
175
|
+
color: disabled ? "#7e7e7e" : "#2f2f2f",
|
|
176
|
+
cursor: disabled ? "not-allowed" : "pointer"
|
|
177
|
+
},
|
|
178
|
+
children: label
|
|
179
|
+
}
|
|
180
|
+
)
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
)
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
Radio.displayName = "Radio";
|
|
190
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
191
|
+
0 && (module.exports = {
|
|
192
|
+
Radio
|
|
193
|
+
});
|
|
194
|
+
//# sourceMappingURL=Radio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/Radio/index.ts","../src/Radio/Radio.tsx"],"sourcesContent":["export { Radio } from './Radio';\nexport type { RadioProps } from './Radio';\n","import * as React from 'react';\nimport { clsx } from 'clsx';\n\nexport interface RadioProps {\n /**\n * The label for the radio button\n */\n label?: string;\n /**\n * Whether the radio is selected\n */\n checked?: boolean;\n /**\n * Callback when selection changes\n */\n onChange?: (checked: boolean) => void;\n /**\n * Whether the radio 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 (groups radios together)\n */\n name?: string;\n /**\n * Value attribute for form submission\n */\n value?: string;\n}\n\nconst radioStyles: React.CSSProperties = {\n width: '16px',\n height: '16px',\n border: '1px solid #7e7e7e', // grey-500\n borderRadius: '50%',\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 border: '1px solid #0e8a0e', // brand-600\n};\n\nconst checkedHoverStyles: React.CSSProperties = {\n border: '1px solid #005700', // brand-800\n};\n\nconst uncheckedHoverStyles: React.CSSProperties = {\n border: '1px solid #2f2f2f', // grey-900\n};\n\nconst innerDotStyles: React.CSSProperties = {\n width: '10px',\n height: '10px',\n borderRadius: '50%',\n backgroundColor: '#0e8a0e', // brand-600\n transition: 'all 0.2s ease-in-out',\n};\n\nconst innerDotHoverStyles: React.CSSProperties = {\n backgroundColor: '#005700', // brand-800\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 * Radio component - Arbor Design System\n *\n * A radio button input with label support.\n */\nexport const Radio = React.forwardRef<HTMLInputElement, RadioProps>(\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 },\n ref\n ) => {\n const [isFocused, setIsFocused] = React.useState(false);\n const [isHovered, setIsHovered] = React.useState(false);\n const radioId = React.useId();\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n if (!disabled) {\n onChange?.(e.target.checked);\n }\n };\n\n const circleStyle: React.CSSProperties = {\n ...radioStyles,\n ...(checked && !disabled && checkedStyles),\n ...(isHovered && !disabled && !checked && uncheckedHoverStyles),\n ...(isHovered && !disabled && checked && checkedHoverStyles),\n ...(disabled && !checked && { backgroundColor: '#efefef', border: '1px solid #7e7e7e' }),\n ...(disabled && checked && { backgroundColor: '#efefef', border: '1px solid #7e7e7e' }),\n ...(isFocused && !disabled && {\n boxShadow: '0px 0px 0px 3px #3cad51',\n }),\n };\n\n const dotStyle: React.CSSProperties = {\n ...innerDotStyles,\n ...(isHovered && !disabled && innerDotHoverStyles),\n ...(disabled && { backgroundColor: '#7e7e7e' }),\n };\n\n return (\n <div\n className={clsx('arbor-radio-wrapper', className)}\n style={{ ...wrapperStyles, ...style }}\n data-testid={dataTestId}\n >\n <input\n ref={ref}\n id={radioId}\n type=\"radio\"\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={checked}\n />\n <label\n htmlFor={radioId}\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={circleStyle}>\n {checked && <div style={dotStyle} />}\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\nRadio.displayName = 'Radio';\n"],"mappings":"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","names":[]}
|
package/dist/Radio.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|