@tonyarbor/components 0.4.0 → 0.7.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/Button.d.mts +1 -1
- package/dist/Button.d.ts +1 -1
- package/dist/Button.js +56 -0
- package/dist/Button.js.map +1 -1
- package/dist/Button.mjs +1 -1
- package/dist/ButtonSegmented.d.mts +61 -0
- package/dist/ButtonSegmented.d.ts +61 -0
- package/dist/ButtonSegmented.js +167 -0
- package/dist/ButtonSegmented.js.map +1 -0
- package/dist/ButtonSegmented.mjs +7 -0
- package/dist/ButtonSegmented.mjs.map +1 -0
- package/dist/ListRow.d.mts +72 -0
- package/dist/ListRow.d.ts +72 -0
- package/dist/ListRow.js +194 -0
- package/dist/ListRow.js.map +1 -0
- package/dist/ListRow.mjs +7 -0
- package/dist/ListRow.mjs.map +1 -0
- package/dist/ListRowMultiLine.d.mts +56 -0
- package/dist/ListRowMultiLine.d.ts +56 -0
- package/dist/ListRowMultiLine.js +182 -0
- package/dist/ListRowMultiLine.js.map +1 -0
- package/dist/ListRowMultiLine.mjs +7 -0
- package/dist/ListRowMultiLine.mjs.map +1 -0
- package/dist/Logo.d.mts +39 -0
- package/dist/Logo.d.ts +39 -0
- package/dist/Logo.js +119 -0
- package/dist/Logo.js.map +1 -0
- package/dist/Logo.mjs +7 -0
- package/dist/Logo.mjs.map +1 -0
- package/dist/Modal.d.mts +73 -0
- package/dist/Modal.d.ts +73 -0
- package/dist/Modal.js +114 -0
- package/dist/Modal.js.map +1 -0
- package/dist/Modal.mjs +9 -0
- package/dist/Modal.mjs.map +1 -0
- package/dist/ModalFooter.d.mts +40 -0
- package/dist/ModalFooter.d.ts +40 -0
- package/dist/ModalFooter.js +73 -0
- package/dist/ModalFooter.js.map +1 -0
- package/dist/ModalFooter.mjs +7 -0
- package/dist/ModalFooter.mjs.map +1 -0
- package/dist/ModalHeader.d.mts +65 -0
- package/dist/ModalHeader.d.ts +65 -0
- package/dist/ModalHeader.js +257 -0
- package/dist/ModalHeader.js.map +1 -0
- package/dist/ModalHeader.mjs +8 -0
- package/dist/ModalHeader.mjs.map +1 -0
- package/dist/Section.d.mts +57 -0
- package/dist/Section.d.ts +57 -0
- package/dist/Section.js +72 -0
- package/dist/Section.js.map +1 -0
- package/dist/Section.mjs +7 -0
- package/dist/Section.mjs.map +1 -0
- package/dist/SectionHeading.d.mts +111 -0
- package/dist/SectionHeading.d.ts +111 -0
- package/dist/SectionHeading.js +385 -0
- package/dist/SectionHeading.js.map +1 -0
- package/dist/SectionHeading.mjs +8 -0
- package/dist/SectionHeading.mjs.map +1 -0
- package/dist/SectionHeadingInteractive.d.mts +67 -0
- package/dist/SectionHeadingInteractive.d.ts +67 -0
- package/dist/SectionHeadingInteractive.js +225 -0
- package/dist/SectionHeadingInteractive.js.map +1 -0
- package/dist/SectionHeadingInteractive.mjs +7 -0
- package/dist/SectionHeadingInteractive.mjs.map +1 -0
- package/dist/SectionIcon.d.mts +35 -0
- package/dist/SectionIcon.d.ts +35 -0
- package/dist/SectionIcon.js +142 -0
- package/dist/SectionIcon.js.map +1 -0
- package/dist/SectionIcon.mjs +7 -0
- package/dist/SectionIcon.mjs.map +1 -0
- package/dist/SubSectionHeading.d.mts +75 -0
- package/dist/SubSectionHeading.d.ts +75 -0
- package/dist/SubSectionHeading.js +225 -0
- package/dist/SubSectionHeading.js.map +1 -0
- package/dist/SubSectionHeading.mjs +7 -0
- package/dist/SubSectionHeading.mjs.map +1 -0
- package/dist/SubSectionInteractive.d.mts +65 -0
- package/dist/SubSectionInteractive.d.ts +65 -0
- package/dist/SubSectionInteractive.js +211 -0
- package/dist/SubSectionInteractive.js.map +1 -0
- package/dist/SubSectionInteractive.mjs +7 -0
- package/dist/SubSectionInteractive.mjs.map +1 -0
- package/dist/chunk-7JWINM2N.mjs +77 -0
- package/dist/chunk-7JWINM2N.mjs.map +1 -0
- package/dist/chunk-7NYBJKJS.mjs +106 -0
- package/dist/chunk-7NYBJKJS.mjs.map +1 -0
- package/dist/chunk-ALLCJATI.mjs +189 -0
- package/dist/chunk-ALLCJATI.mjs.map +1 -0
- package/dist/chunk-F6JVEIWC.mjs +158 -0
- package/dist/chunk-F6JVEIWC.mjs.map +1 -0
- package/dist/chunk-GHATS25Y.mjs +249 -0
- package/dist/chunk-GHATS25Y.mjs.map +1 -0
- package/dist/chunk-GIQDPHZQ.mjs +121 -0
- package/dist/chunk-GIQDPHZQ.mjs.map +1 -0
- package/dist/chunk-ILLGBZ6R.mjs +131 -0
- package/dist/chunk-ILLGBZ6R.mjs.map +1 -0
- package/dist/chunk-NNYU4DPD.mjs +83 -0
- package/dist/chunk-NNYU4DPD.mjs.map +1 -0
- package/dist/{chunk-ALEJXAZY.mjs → chunk-NOUFR6W2.mjs} +57 -1
- package/dist/chunk-NOUFR6W2.mjs.map +1 -0
- package/dist/chunk-ODKT7LGV.mjs +146 -0
- package/dist/chunk-ODKT7LGV.mjs.map +1 -0
- package/dist/chunk-P7RKUESQ.mjs +37 -0
- package/dist/chunk-P7RKUESQ.mjs.map +1 -0
- package/dist/chunk-RL4G7MR3.mjs +189 -0
- package/dist/chunk-RL4G7MR3.mjs.map +1 -0
- package/dist/chunk-X2CW5GF3.mjs +175 -0
- package/dist/chunk-X2CW5GF3.mjs.map +1 -0
- package/dist/chunk-YJ36ZZJQ.mjs +36 -0
- package/dist/chunk-YJ36ZZJQ.mjs.map +1 -0
- package/dist/index.d.mts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +1722 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +55 -1
- package/package.json +66 -1
- package/dist/chunk-ALEJXAZY.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/SubSectionHeading/SubSectionHeading.tsx"],"sourcesContent":["import * as React from 'react';\nimport { clsx } from 'clsx';\n\nexport interface SubSectionHeadingProps {\n /**\n * The heading text (required)\n */\n title: string;\n /**\n * Show an info icon next to the heading text\n * @default false\n */\n icon?: boolean;\n /**\n * Button variant to display on the right\n * - 'primary': Green button with white text\n * - 'tertiary': Gray button with dark text\n * - undefined: No button\n */\n button?: 'primary' | 'tertiary';\n /**\n * Text to display in the button (required if button is specified)\n */\n buttonText?: string;\n /**\n * Icon to display in the button (renders before button text)\n */\n buttonIcon?: React.ReactNode;\n /**\n * Click handler for the button\n */\n onButtonClick?: () => void;\n /**\n * Additional CSS class name\n */\n className?: string;\n /**\n * Additional inline styles\n */\n style?: React.CSSProperties;\n}\n\n// Info icon (circle with i)\nconst InfoIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"8\" cy=\"8\" r=\"6.5\" stroke=\"#2f2f2f\" strokeWidth=\"1.2\" />\n <path\n d=\"M8 7V11\"\n stroke=\"#2f2f2f\"\n strokeWidth=\"1.2\"\n strokeLinecap=\"round\"\n />\n <circle cx=\"8\" cy=\"5\" r=\"0.75\" fill=\"#2f2f2f\" />\n </svg>\n);\n\n// Default plus icon for buttons\nconst PlusIcon = ({ color = '#2f2f2f' }: { color?: string }) => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8 3V13M3 8H13\"\n stroke={color}\n strokeWidth=\"1.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\n// Arbor Design System sub-section heading styles\nconst subSectionHeadingStyles = {\n container: {\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n borderBottom: '1px solid #efefef',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n boxSizing: 'border-box' as const,\n },\n containerNoButton: {\n padding: '12px 8px',\n gap: '0px',\n },\n containerWithButton: {\n padding: '8px',\n gap: '12px',\n justifyContent: 'space-between',\n },\n textContainer: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n flex: 1,\n minHeight: '16px',\n },\n title: {\n fontSize: '18px',\n fontWeight: '600',\n color: '#2f2f2f',\n lineHeight: '1.25',\n margin: 0,\n whiteSpace: 'nowrap' as const,\n },\n iconWrapper: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '16px',\n height: '16px',\n flexShrink: 0,\n },\n buttonBase: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n height: '32px',\n minHeight: '32px',\n padding: '0 16px',\n borderRadius: '99px',\n border: 'none',\n cursor: 'pointer',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n fontSize: '13px',\n fontWeight: '600',\n lineHeight: '1.5',\n whiteSpace: 'nowrap' as const,\n flexShrink: 0,\n transition: 'background-color 0.15s ease-in-out, opacity 0.15s ease-in-out',\n },\n buttonPrimary: {\n backgroundColor: '#0e8a0e',\n color: '#ffffff',\n },\n buttonPrimaryHover: {\n backgroundColor: '#0a6b0a',\n },\n buttonTertiary: {\n backgroundColor: '#efefef',\n color: '#2f2f2f',\n },\n buttonTertiaryHover: {\n backgroundColor: '#e5e5e5',\n },\n buttonIconWrapper: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '16px',\n height: '16px',\n flexShrink: 0,\n },\n};\n\n/**\n * SubSectionHeading component - Arbor Design System\n *\n * A sub-section heading component for dividing content within sections.\n * Supports optional icon next to text and optional button on the right.\n *\n * @example\n * ```tsx\n * // Basic sub-section heading\n * <SubSectionHeading title=\"Details\" />\n *\n * // With info icon\n * <SubSectionHeading title=\"Details\" icon />\n *\n * // With primary button\n * <SubSectionHeading\n * title=\"Items\"\n * button=\"primary\"\n * buttonText=\"Add Item\"\n * onButtonClick={() => handleAdd()}\n * />\n *\n * // With tertiary button and icon\n * <SubSectionHeading\n * title=\"Settings\"\n * icon\n * button=\"tertiary\"\n * buttonText=\"Configure\"\n * onButtonClick={() => handleConfigure()}\n * />\n * ```\n */\nexport const SubSectionHeading = React.forwardRef<HTMLDivElement, SubSectionHeadingProps>(\n (\n {\n title,\n icon = false,\n button,\n buttonText = 'Button Text',\n buttonIcon,\n onButtonClick,\n className,\n style,\n ...props\n },\n ref\n ) => {\n const [isButtonHovered, setIsButtonHovered] = React.useState(false);\n\n const containerStyle: React.CSSProperties = {\n ...subSectionHeadingStyles.container,\n ...(button\n ? subSectionHeadingStyles.containerWithButton\n : subSectionHeadingStyles.containerNoButton),\n ...style,\n };\n\n const getButtonStyle = (): React.CSSProperties => {\n const baseStyle = { ...subSectionHeadingStyles.buttonBase };\n\n if (button === 'primary') {\n return {\n ...baseStyle,\n ...subSectionHeadingStyles.buttonPrimary,\n ...(isButtonHovered && subSectionHeadingStyles.buttonPrimaryHover),\n };\n }\n\n if (button === 'tertiary') {\n return {\n ...baseStyle,\n ...subSectionHeadingStyles.buttonTertiary,\n ...(isButtonHovered && subSectionHeadingStyles.buttonTertiaryHover),\n };\n }\n\n return baseStyle;\n };\n\n const renderButtonIcon = () => {\n if (buttonIcon) {\n return (\n <span style={subSectionHeadingStyles.buttonIconWrapper}>{buttonIcon}</span>\n );\n }\n // Default icon based on button type\n return (\n <span style={subSectionHeadingStyles.buttonIconWrapper}>\n <PlusIcon color={button === 'primary' ? '#ffffff' : '#2f2f2f'} />\n </span>\n );\n };\n\n return (\n <div\n ref={ref}\n className={clsx('arbor-sub-section-heading', className)}\n style={containerStyle}\n {...props}\n >\n <div style={subSectionHeadingStyles.textContainer}>\n <h3 style={subSectionHeadingStyles.title}>{title}</h3>\n {icon && (\n <span style={subSectionHeadingStyles.iconWrapper}>\n <InfoIcon />\n </span>\n )}\n </div>\n {button && (\n <button\n type=\"button\"\n style={getButtonStyle()}\n onClick={onButtonClick}\n onMouseEnter={() => setIsButtonHovered(true)}\n onMouseLeave={() => setIsButtonHovered(false)}\n >\n {renderButtonIcon()}\n <span>{buttonText}</span>\n </button>\n )}\n </div>\n );\n }\n);\n\nSubSectionHeading.displayName = 'SubSectionHeading';\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// src/ListRow/ListRow.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { clsx } from "clsx";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
var CaretIcon = ({ isHovered }) => {
|
|
6
|
+
if (isHovered) {
|
|
7
|
+
return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx(
|
|
8
|
+
"path",
|
|
9
|
+
{
|
|
10
|
+
d: "M6 4L10 8L6 12",
|
|
11
|
+
stroke: "#2f2f2f",
|
|
12
|
+
strokeWidth: "1.2",
|
|
13
|
+
strokeLinecap: "round",
|
|
14
|
+
strokeLinejoin: "round"
|
|
15
|
+
}
|
|
16
|
+
) });
|
|
17
|
+
}
|
|
18
|
+
return /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsx(
|
|
19
|
+
"path",
|
|
20
|
+
{
|
|
21
|
+
d: "M6 4L10 8L6 12",
|
|
22
|
+
stroke: "#b3b3b3",
|
|
23
|
+
strokeWidth: "1.2",
|
|
24
|
+
strokeLinecap: "round",
|
|
25
|
+
strokeLinejoin: "round"
|
|
26
|
+
}
|
|
27
|
+
) });
|
|
28
|
+
};
|
|
29
|
+
var listRowStyles = {
|
|
30
|
+
container: {
|
|
31
|
+
display: "flex",
|
|
32
|
+
alignItems: "center",
|
|
33
|
+
width: "100%",
|
|
34
|
+
borderBottom: "1px solid #f8f8f8",
|
|
35
|
+
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
|
|
36
|
+
boxSizing: "border-box",
|
|
37
|
+
borderRadius: "8px",
|
|
38
|
+
transition: "background-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out",
|
|
39
|
+
outline: "none"
|
|
40
|
+
},
|
|
41
|
+
containerHover: {
|
|
42
|
+
backgroundColor: "#f8f8f8"
|
|
43
|
+
},
|
|
44
|
+
containerFocus: {
|
|
45
|
+
outline: "3px solid #3cad51",
|
|
46
|
+
outlineOffset: "-3px"
|
|
47
|
+
},
|
|
48
|
+
containerClickable: {
|
|
49
|
+
cursor: "pointer"
|
|
50
|
+
},
|
|
51
|
+
content: {
|
|
52
|
+
display: "flex",
|
|
53
|
+
alignItems: "center",
|
|
54
|
+
justifyContent: "space-between",
|
|
55
|
+
width: "100%",
|
|
56
|
+
padding: "4px 8px",
|
|
57
|
+
minHeight: "28px"
|
|
58
|
+
},
|
|
59
|
+
label: {
|
|
60
|
+
fontSize: "13px",
|
|
61
|
+
fontWeight: "600",
|
|
62
|
+
color: "#2f2f2f",
|
|
63
|
+
lineHeight: "1.5",
|
|
64
|
+
width: "190px",
|
|
65
|
+
flexShrink: 0
|
|
66
|
+
},
|
|
67
|
+
valueContainer: {
|
|
68
|
+
flex: 1,
|
|
69
|
+
display: "flex",
|
|
70
|
+
alignItems: "center"
|
|
71
|
+
},
|
|
72
|
+
value: {
|
|
73
|
+
fontSize: "13px",
|
|
74
|
+
fontWeight: "400",
|
|
75
|
+
color: "#2f2f2f",
|
|
76
|
+
lineHeight: "1.5"
|
|
77
|
+
},
|
|
78
|
+
rightContainer: {
|
|
79
|
+
display: "flex",
|
|
80
|
+
alignItems: "center",
|
|
81
|
+
justifyContent: "flex-end",
|
|
82
|
+
gap: "8px",
|
|
83
|
+
flexShrink: 0
|
|
84
|
+
},
|
|
85
|
+
note: {
|
|
86
|
+
fontSize: "13px",
|
|
87
|
+
fontWeight: "400",
|
|
88
|
+
fontStyle: "italic",
|
|
89
|
+
color: "#2f2f2f",
|
|
90
|
+
lineHeight: "1.5",
|
|
91
|
+
textAlign: "right"
|
|
92
|
+
},
|
|
93
|
+
iconWrapper: {
|
|
94
|
+
display: "flex",
|
|
95
|
+
alignItems: "center",
|
|
96
|
+
justifyContent: "center",
|
|
97
|
+
width: "16px",
|
|
98
|
+
height: "16px",
|
|
99
|
+
flexShrink: 0
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
var ListRow = React.forwardRef(
|
|
103
|
+
({ value, label, note, icon = false, onClick, className, style, ...props }, ref) => {
|
|
104
|
+
const [isHovered, setIsHovered] = React.useState(false);
|
|
105
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
106
|
+
const showHoverState = icon && isHovered;
|
|
107
|
+
const isClickable = icon && onClick;
|
|
108
|
+
const containerStyle = {
|
|
109
|
+
...listRowStyles.container,
|
|
110
|
+
...showHoverState && listRowStyles.containerHover,
|
|
111
|
+
...isFocused && listRowStyles.containerFocus,
|
|
112
|
+
...isClickable && listRowStyles.containerClickable,
|
|
113
|
+
...style
|
|
114
|
+
};
|
|
115
|
+
const handleClick = () => {
|
|
116
|
+
if (isClickable && onClick) {
|
|
117
|
+
onClick();
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
const handleKeyDown = (event) => {
|
|
121
|
+
if (isClickable && (event.key === "Enter" || event.key === " ")) {
|
|
122
|
+
event.preventDefault();
|
|
123
|
+
onClick?.();
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
return /* @__PURE__ */ jsx(
|
|
127
|
+
"div",
|
|
128
|
+
{
|
|
129
|
+
ref,
|
|
130
|
+
className: clsx("arbor-list-row", className),
|
|
131
|
+
style: containerStyle,
|
|
132
|
+
onClick: handleClick,
|
|
133
|
+
onMouseEnter: () => icon && setIsHovered(true),
|
|
134
|
+
onMouseLeave: () => setIsHovered(false),
|
|
135
|
+
onFocus: () => setIsFocused(true),
|
|
136
|
+
onBlur: () => setIsFocused(false),
|
|
137
|
+
onKeyDown: handleKeyDown,
|
|
138
|
+
tabIndex: isClickable ? 0 : void 0,
|
|
139
|
+
role: isClickable ? "button" : void 0,
|
|
140
|
+
...props,
|
|
141
|
+
children: /* @__PURE__ */ jsxs("div", { style: listRowStyles.content, children: [
|
|
142
|
+
label && /* @__PURE__ */ jsx("div", { style: listRowStyles.label, children: label }),
|
|
143
|
+
/* @__PURE__ */ jsx("div", { style: listRowStyles.valueContainer, children: /* @__PURE__ */ jsx("span", { style: listRowStyles.value, children: value }) }),
|
|
144
|
+
/* @__PURE__ */ jsxs("div", { style: listRowStyles.rightContainer, children: [
|
|
145
|
+
note && /* @__PURE__ */ jsx("span", { style: listRowStyles.note, children: note }),
|
|
146
|
+
icon && /* @__PURE__ */ jsx("div", { style: listRowStyles.iconWrapper, children: /* @__PURE__ */ jsx(CaretIcon, { isHovered }) })
|
|
147
|
+
] })
|
|
148
|
+
] })
|
|
149
|
+
}
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
ListRow.displayName = "ListRow";
|
|
154
|
+
|
|
155
|
+
export {
|
|
156
|
+
ListRow
|
|
157
|
+
};
|
|
158
|
+
//# sourceMappingURL=chunk-F6JVEIWC.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ListRow/ListRow.tsx"],"sourcesContent":["import * as React from 'react';\nimport { clsx } from 'clsx';\n\nexport interface ListRowProps {\n /**\n * The main value/content text (required)\n */\n value: string;\n /**\n * Optional label text displayed on the left\n */\n label?: string;\n /**\n * Optional note text displayed on the right (italic)\n */\n note?: string;\n /**\n * Show the right arrow icon - enables hover state and indicates row is clickable\n * @default false\n */\n icon?: boolean;\n /**\n * Click handler - typically used with icon prop for navigation\n */\n onClick?: () => void;\n /**\n * Additional CSS class name\n */\n className?: string;\n /**\n * Additional inline styles\n */\n style?: React.CSSProperties;\n}\n\n// Caret/Arrow icon - transforms on hover\nconst CaretIcon = ({ isHovered }: { isHovered: boolean }) => {\n if (isHovered) {\n // Arrow pointing right on hover\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M6 4L10 8L6 12\"\n stroke=\"#2f2f2f\"\n strokeWidth=\"1.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n }\n // Default caret (chevron right)\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M6 4L10 8L6 12\"\n stroke=\"#b3b3b3\"\n strokeWidth=\"1.2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n );\n};\n\n// Arbor Design System list row styles\nconst listRowStyles = {\n container: {\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n borderBottom: '1px solid #f8f8f8',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n boxSizing: 'border-box' as const,\n borderRadius: '8px',\n transition: 'background-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out',\n outline: 'none',\n },\n containerHover: {\n backgroundColor: '#f8f8f8',\n },\n containerFocus: {\n outline: '3px solid #3cad51',\n outlineOffset: '-3px',\n },\n containerClickable: {\n cursor: 'pointer',\n },\n content: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n padding: '4px 8px',\n minHeight: '28px',\n },\n label: {\n fontSize: '13px',\n fontWeight: '600',\n color: '#2f2f2f',\n lineHeight: '1.5',\n width: '190px',\n flexShrink: 0,\n },\n valueContainer: {\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n },\n value: {\n fontSize: '13px',\n fontWeight: '400',\n color: '#2f2f2f',\n lineHeight: '1.5',\n },\n rightContainer: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: '8px',\n flexShrink: 0,\n },\n note: {\n fontSize: '13px',\n fontWeight: '400',\n fontStyle: 'italic',\n color: '#2f2f2f',\n lineHeight: '1.5',\n textAlign: 'right' as const,\n },\n iconWrapper: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '16px',\n height: '16px',\n flexShrink: 0,\n },\n};\n\n/**\n * ListRow component - Arbor Design System\n *\n * A flexible list row component for displaying content within sections.\n * Supports optional label, note, and icon props.\n * Hover state is only enabled when icon is present (indicating clickable row).\n *\n * @example\n * ```tsx\n * // Basic row with just value\n * <ListRow value=\"John Smith\" />\n *\n * // With label\n * <ListRow label=\"Name\" value=\"John Smith\" />\n *\n * // With label and note\n * <ListRow label=\"Name\" value=\"John Smith\" note=\"Primary contact\" />\n *\n * // Clickable row with icon\n * <ListRow\n * label=\"Name\"\n * value=\"John Smith\"\n * icon\n * onClick={() => navigate('/user/123')}\n * />\n *\n * // All props\n * <ListRow\n * label=\"Name\"\n * value=\"John Smith\"\n * note=\"View profile\"\n * icon\n * onClick={() => navigate('/user/123')}\n * />\n * ```\n */\nexport const ListRow = React.forwardRef<HTMLDivElement, ListRowProps>(\n ({ value, label, note, icon = false, onClick, className, style, ...props }, ref) => {\n const [isHovered, setIsHovered] = React.useState(false);\n const [isFocused, setIsFocused] = React.useState(false);\n\n // Only enable hover state when icon is present\n const showHoverState = icon && isHovered;\n const isClickable = icon && onClick;\n\n const containerStyle: React.CSSProperties = {\n ...listRowStyles.container,\n ...(showHoverState && listRowStyles.containerHover),\n ...(isFocused && listRowStyles.containerFocus),\n ...(isClickable && listRowStyles.containerClickable),\n ...style,\n };\n\n const handleClick = () => {\n if (isClickable && onClick) {\n onClick();\n }\n };\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (isClickable && (event.key === 'Enter' || event.key === ' ')) {\n event.preventDefault();\n onClick?.();\n }\n };\n\n return (\n <div\n ref={ref}\n className={clsx('arbor-list-row', className)}\n style={containerStyle}\n onClick={handleClick}\n onMouseEnter={() => icon && setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n onKeyDown={handleKeyDown}\n tabIndex={isClickable ? 0 : undefined}\n role={isClickable ? 'button' : undefined}\n {...props}\n >\n <div style={listRowStyles.content}>\n {label && <div style={listRowStyles.label}>{label}</div>}\n <div style={listRowStyles.valueContainer}>\n <span style={listRowStyles.value}>{value}</span>\n </div>\n <div style={listRowStyles.rightContainer}>\n {note && <span style={listRowStyles.note}>{note}</span>}\n {icon && (\n <div style={listRowStyles.iconWrapper}>\n <CaretIcon isHovered={isHovered} />\n </div>\n )}\n </div>\n </div>\n </div>\n );\n }\n);\n\nListRow.displayName = 'ListRow';\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SectionIcon
|
|
3
|
+
} from "./chunk-7NYBJKJS.mjs";
|
|
4
|
+
|
|
5
|
+
// src/SectionHeading/SectionHeading.tsx
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { clsx } from "clsx";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
var AvatarPlaceholder = () => /* @__PURE__ */ jsxs("svg", { width: "22", height: "33", viewBox: "0 0 22 33", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
10
|
+
/* @__PURE__ */ jsx("circle", { cx: "11", cy: "7", r: "7", fill: "#d1d1d1" }),
|
|
11
|
+
/* @__PURE__ */ jsx("ellipse", { cx: "11", cy: "33", rx: "11", ry: "11", fill: "#d1d1d1" })
|
|
12
|
+
] });
|
|
13
|
+
var sectionHeadingStyles = {
|
|
14
|
+
container: {
|
|
15
|
+
display: "flex",
|
|
16
|
+
alignItems: "center",
|
|
17
|
+
gap: "12px",
|
|
18
|
+
padding: "8px",
|
|
19
|
+
borderBottom: "1px solid #f8f8f8",
|
|
20
|
+
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
|
|
21
|
+
minHeight: "56px",
|
|
22
|
+
boxSizing: "border-box"
|
|
23
|
+
},
|
|
24
|
+
title: {
|
|
25
|
+
fontSize: "22px",
|
|
26
|
+
fontWeight: "600",
|
|
27
|
+
color: "#2f2f2f",
|
|
28
|
+
lineHeight: "1.25",
|
|
29
|
+
flex: 1,
|
|
30
|
+
overflow: "hidden",
|
|
31
|
+
textOverflow: "ellipsis",
|
|
32
|
+
whiteSpace: "nowrap",
|
|
33
|
+
margin: 0
|
|
34
|
+
},
|
|
35
|
+
titleWithIcon: {
|
|
36
|
+
display: "flex",
|
|
37
|
+
alignItems: "center",
|
|
38
|
+
gap: "8px",
|
|
39
|
+
flex: 1
|
|
40
|
+
},
|
|
41
|
+
iconBadge: {
|
|
42
|
+
display: "flex",
|
|
43
|
+
alignItems: "center",
|
|
44
|
+
flexShrink: 0
|
|
45
|
+
},
|
|
46
|
+
avatar: {
|
|
47
|
+
width: "48px",
|
|
48
|
+
height: "48px",
|
|
49
|
+
borderRadius: "8px",
|
|
50
|
+
border: "1px solid #efefef",
|
|
51
|
+
backgroundColor: "#f8f8f8",
|
|
52
|
+
flexShrink: 0,
|
|
53
|
+
overflow: "hidden",
|
|
54
|
+
display: "flex",
|
|
55
|
+
alignItems: "center",
|
|
56
|
+
justifyContent: "center"
|
|
57
|
+
},
|
|
58
|
+
avatarImage: {
|
|
59
|
+
width: "100%",
|
|
60
|
+
height: "100%",
|
|
61
|
+
objectFit: "cover"
|
|
62
|
+
},
|
|
63
|
+
avatarInitials: {
|
|
64
|
+
fontSize: "18px",
|
|
65
|
+
fontWeight: "600",
|
|
66
|
+
color: "#595959"
|
|
67
|
+
},
|
|
68
|
+
button: {
|
|
69
|
+
display: "inline-flex",
|
|
70
|
+
alignItems: "center",
|
|
71
|
+
justifyContent: "center",
|
|
72
|
+
gap: "8px",
|
|
73
|
+
height: "32px",
|
|
74
|
+
padding: "0 16px",
|
|
75
|
+
backgroundColor: "#0e8a0e",
|
|
76
|
+
color: "#ffffff",
|
|
77
|
+
border: "none",
|
|
78
|
+
borderRadius: "99px",
|
|
79
|
+
fontSize: "13px",
|
|
80
|
+
fontWeight: "600",
|
|
81
|
+
cursor: "pointer",
|
|
82
|
+
transition: "background-color 0.15s ease-in-out",
|
|
83
|
+
whiteSpace: "nowrap",
|
|
84
|
+
flexShrink: 0
|
|
85
|
+
},
|
|
86
|
+
buttonHover: {
|
|
87
|
+
backgroundColor: "#005700"
|
|
88
|
+
},
|
|
89
|
+
buttonGroup: {
|
|
90
|
+
container: {
|
|
91
|
+
display: "inline-flex",
|
|
92
|
+
alignItems: "center",
|
|
93
|
+
gap: "8px",
|
|
94
|
+
padding: "8px",
|
|
95
|
+
backgroundColor: "#ffffff",
|
|
96
|
+
border: "1px solid #efefef",
|
|
97
|
+
borderRadius: "99px",
|
|
98
|
+
flexShrink: 0
|
|
99
|
+
},
|
|
100
|
+
button: {
|
|
101
|
+
base: {
|
|
102
|
+
display: "inline-flex",
|
|
103
|
+
alignItems: "center",
|
|
104
|
+
justifyContent: "center",
|
|
105
|
+
gap: "8px",
|
|
106
|
+
padding: "8px 16px",
|
|
107
|
+
borderRadius: "99px",
|
|
108
|
+
border: "none",
|
|
109
|
+
cursor: "pointer",
|
|
110
|
+
fontSize: "13px",
|
|
111
|
+
fontWeight: "600",
|
|
112
|
+
lineHeight: "1.5",
|
|
113
|
+
transition: "all 0.15s ease-in-out",
|
|
114
|
+
outline: "none",
|
|
115
|
+
whiteSpace: "nowrap"
|
|
116
|
+
},
|
|
117
|
+
default: {
|
|
118
|
+
backgroundColor: "transparent",
|
|
119
|
+
color: "#595959"
|
|
120
|
+
},
|
|
121
|
+
hover: {
|
|
122
|
+
backgroundColor: "#f8f8f8",
|
|
123
|
+
color: "#2f2f2f"
|
|
124
|
+
},
|
|
125
|
+
active: {
|
|
126
|
+
backgroundColor: "#0e8a0e",
|
|
127
|
+
color: "#ffffff"
|
|
128
|
+
},
|
|
129
|
+
activeHover: {
|
|
130
|
+
backgroundColor: "#005700",
|
|
131
|
+
color: "#ffffff"
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
var SectionHeading = React.forwardRef(
|
|
137
|
+
({ title, icon, avatar, button, buttonGroup, className, style, ...props }, ref) => {
|
|
138
|
+
const [buttonHovered, setButtonHovered] = React.useState(false);
|
|
139
|
+
const [hoveredGroupIndex, setHoveredGroupIndex] = React.useState(null);
|
|
140
|
+
if (button && buttonGroup) {
|
|
141
|
+
console.warn("SectionHeading: button and buttonGroup are mutually exclusive. Only button will be rendered.");
|
|
142
|
+
}
|
|
143
|
+
const renderAvatar = () => {
|
|
144
|
+
if (!avatar) return null;
|
|
145
|
+
return /* @__PURE__ */ jsx("div", { style: sectionHeadingStyles.avatar, children: avatar.src ? /* @__PURE__ */ jsx(
|
|
146
|
+
"img",
|
|
147
|
+
{
|
|
148
|
+
src: avatar.src,
|
|
149
|
+
alt: avatar.alt || "Avatar",
|
|
150
|
+
style: sectionHeadingStyles.avatarImage
|
|
151
|
+
}
|
|
152
|
+
) : avatar.initials ? /* @__PURE__ */ jsx("span", { style: sectionHeadingStyles.avatarInitials, children: avatar.initials }) : /* @__PURE__ */ jsx(AvatarPlaceholder, {}) });
|
|
153
|
+
};
|
|
154
|
+
const renderTitle = () => {
|
|
155
|
+
if (icon) {
|
|
156
|
+
const iconVariant = typeof icon === "string" ? icon : "info";
|
|
157
|
+
return /* @__PURE__ */ jsxs("div", { style: sectionHeadingStyles.titleWithIcon, children: [
|
|
158
|
+
/* @__PURE__ */ jsx("h2", { style: { ...sectionHeadingStyles.title, flex: "none" }, children: title }),
|
|
159
|
+
/* @__PURE__ */ jsx("div", { style: sectionHeadingStyles.iconBadge, children: /* @__PURE__ */ jsx(SectionIcon, { variant: iconVariant }) })
|
|
160
|
+
] });
|
|
161
|
+
}
|
|
162
|
+
return /* @__PURE__ */ jsx("h2", { style: sectionHeadingStyles.title, children: title });
|
|
163
|
+
};
|
|
164
|
+
const renderButton = () => {
|
|
165
|
+
if (!button) return null;
|
|
166
|
+
return /* @__PURE__ */ jsxs(
|
|
167
|
+
"button",
|
|
168
|
+
{
|
|
169
|
+
type: "button",
|
|
170
|
+
style: {
|
|
171
|
+
...sectionHeadingStyles.button,
|
|
172
|
+
...buttonHovered && sectionHeadingStyles.buttonHover
|
|
173
|
+
},
|
|
174
|
+
onClick: button.onClick,
|
|
175
|
+
onMouseEnter: () => setButtonHovered(true),
|
|
176
|
+
onMouseLeave: () => setButtonHovered(false),
|
|
177
|
+
children: [
|
|
178
|
+
button.icon && /* @__PURE__ */ jsx("span", { style: { display: "flex", alignItems: "center", width: "16px", height: "16px" }, children: button.icon }),
|
|
179
|
+
button.label
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
);
|
|
183
|
+
};
|
|
184
|
+
const renderButtonGroup = () => {
|
|
185
|
+
if (!buttonGroup || button) return null;
|
|
186
|
+
const { items, activeIndex = 0, onChange } = buttonGroup;
|
|
187
|
+
return /* @__PURE__ */ jsx("div", { style: sectionHeadingStyles.buttonGroup.container, children: items.slice(0, 4).map((item, index) => {
|
|
188
|
+
const isActive = index === activeIndex;
|
|
189
|
+
const isHovered = hoveredGroupIndex === index;
|
|
190
|
+
let btnStyle = {
|
|
191
|
+
...sectionHeadingStyles.buttonGroup.button.base
|
|
192
|
+
};
|
|
193
|
+
if (isActive) {
|
|
194
|
+
btnStyle = {
|
|
195
|
+
...btnStyle,
|
|
196
|
+
...sectionHeadingStyles.buttonGroup.button.active,
|
|
197
|
+
...isHovered && sectionHeadingStyles.buttonGroup.button.activeHover
|
|
198
|
+
};
|
|
199
|
+
} else {
|
|
200
|
+
btnStyle = {
|
|
201
|
+
...btnStyle,
|
|
202
|
+
...sectionHeadingStyles.buttonGroup.button.default,
|
|
203
|
+
...isHovered && sectionHeadingStyles.buttonGroup.button.hover
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
return /* @__PURE__ */ jsxs(
|
|
207
|
+
"button",
|
|
208
|
+
{
|
|
209
|
+
type: "button",
|
|
210
|
+
style: btnStyle,
|
|
211
|
+
onClick: () => {
|
|
212
|
+
if (index !== activeIndex && onChange) {
|
|
213
|
+
onChange(index);
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
onMouseEnter: () => setHoveredGroupIndex(index),
|
|
217
|
+
onMouseLeave: () => setHoveredGroupIndex(null),
|
|
218
|
+
children: [
|
|
219
|
+
item.icon && /* @__PURE__ */ jsx("span", { style: { display: "flex", alignItems: "center", width: "16px", height: "16px" }, children: item.icon }),
|
|
220
|
+
item.label
|
|
221
|
+
]
|
|
222
|
+
},
|
|
223
|
+
item.value || index
|
|
224
|
+
);
|
|
225
|
+
}) });
|
|
226
|
+
};
|
|
227
|
+
return /* @__PURE__ */ jsxs(
|
|
228
|
+
"div",
|
|
229
|
+
{
|
|
230
|
+
ref,
|
|
231
|
+
className: clsx("arbor-section-heading", className),
|
|
232
|
+
style: { ...sectionHeadingStyles.container, ...style },
|
|
233
|
+
...props,
|
|
234
|
+
children: [
|
|
235
|
+
renderAvatar(),
|
|
236
|
+
renderTitle(),
|
|
237
|
+
renderButton(),
|
|
238
|
+
renderButtonGroup()
|
|
239
|
+
]
|
|
240
|
+
}
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
);
|
|
244
|
+
SectionHeading.displayName = "SectionHeading";
|
|
245
|
+
|
|
246
|
+
export {
|
|
247
|
+
SectionHeading
|
|
248
|
+
};
|
|
249
|
+
//# sourceMappingURL=chunk-GHATS25Y.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/SectionHeading/SectionHeading.tsx"],"sourcesContent":["import * as React from 'react';\nimport { clsx } from 'clsx';\nimport { SectionIcon, SectionIconVariant } from '../SectionIcon';\n\nexport interface SectionHeadingButton {\n /**\n * The label for the button\n */\n label: string;\n /**\n * Optional icon to display before the label\n */\n icon?: React.ReactNode;\n /**\n * Click handler for the button\n */\n onClick?: () => void;\n}\n\nexport interface SectionHeadingButtonGroupItem {\n /**\n * The label for the button\n */\n label: string;\n /**\n * Optional icon to display before the label\n */\n icon?: React.ReactNode;\n /**\n * Optional value identifier\n */\n value?: string;\n}\n\nexport interface SectionHeadingProps {\n /**\n * The heading title text\n */\n title: string;\n /**\n * Show an icon badge next to the title.\n * Can be a boolean (defaults to 'info') or a specific variant.\n * Available variants: 'warning', 'danger', 'info', 'success'\n */\n icon?: boolean | SectionIconVariant;\n /**\n * Avatar configuration - can be an image URL or initials\n */\n avatar?: {\n src?: string;\n initials?: string;\n alt?: string;\n };\n /**\n * Primary button configuration (mutually exclusive with buttonGroup)\n */\n button?: SectionHeadingButton;\n /**\n * Button group configuration (mutually exclusive with button)\n */\n buttonGroup?: {\n items: SectionHeadingButtonGroupItem[];\n activeIndex?: number;\n onChange?: (index: number) => void;\n };\n /**\n * Additional CSS class name\n */\n className?: string;\n /**\n * Additional inline styles\n */\n style?: React.CSSProperties;\n}\n\n// Placeholder icon for avatar\nconst AvatarPlaceholder = () => (\n <svg width=\"22\" height=\"33\" viewBox=\"0 0 22 33\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"11\" cy=\"7\" r=\"7\" fill=\"#d1d1d1\" />\n <ellipse cx=\"11\" cy=\"33\" rx=\"11\" ry=\"11\" fill=\"#d1d1d1\" />\n </svg>\n);\n\n// Arbor Design System section heading styles\nconst sectionHeadingStyles = {\n container: {\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n padding: '8px',\n borderBottom: '1px solid #f8f8f8',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n minHeight: '56px',\n boxSizing: 'border-box' as const,\n },\n title: {\n fontSize: '22px',\n fontWeight: '600',\n color: '#2f2f2f',\n lineHeight: '1.25',\n flex: 1,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap' as const,\n margin: 0,\n },\n titleWithIcon: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n flex: 1,\n },\n iconBadge: {\n display: 'flex',\n alignItems: 'center',\n flexShrink: 0,\n },\n avatar: {\n width: '48px',\n height: '48px',\n borderRadius: '8px',\n border: '1px solid #efefef',\n backgroundColor: '#f8f8f8',\n flexShrink: 0,\n overflow: 'hidden',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n },\n avatarImage: {\n width: '100%',\n height: '100%',\n objectFit: 'cover' as const,\n },\n avatarInitials: {\n fontSize: '18px',\n fontWeight: '600',\n color: '#595959',\n },\n button: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n height: '32px',\n padding: '0 16px',\n backgroundColor: '#0e8a0e',\n color: '#ffffff',\n border: 'none',\n borderRadius: '99px',\n fontSize: '13px',\n fontWeight: '600',\n cursor: 'pointer',\n transition: 'background-color 0.15s ease-in-out',\n whiteSpace: 'nowrap' as const,\n flexShrink: 0,\n },\n buttonHover: {\n backgroundColor: '#005700',\n },\n buttonGroup: {\n container: {\n display: 'inline-flex',\n alignItems: 'center',\n gap: '8px',\n padding: '8px',\n backgroundColor: '#ffffff',\n border: '1px solid #efefef',\n borderRadius: '99px',\n flexShrink: 0,\n },\n button: {\n base: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '8px',\n padding: '8px 16px',\n borderRadius: '99px',\n border: 'none',\n cursor: 'pointer',\n fontSize: '13px',\n fontWeight: '600',\n lineHeight: '1.5',\n transition: 'all 0.15s ease-in-out',\n outline: 'none',\n whiteSpace: 'nowrap' as const,\n },\n default: {\n backgroundColor: 'transparent',\n color: '#595959',\n },\n hover: {\n backgroundColor: '#f8f8f8',\n color: '#2f2f2f',\n },\n active: {\n backgroundColor: '#0e8a0e',\n color: '#ffffff',\n },\n activeHover: {\n backgroundColor: '#005700',\n color: '#ffffff',\n },\n },\n },\n};\n\n/**\n * SectionHeading component - Arbor Design System\n *\n * A flexible section heading component that can include an icon, avatar,\n * button, or button group. Button and button group are mutually exclusive.\n *\n * @example\n * ```tsx\n * // Basic heading\n * <SectionHeading title=\"Section Title\" />\n *\n * // With icon\n * <SectionHeading title=\"Section Title\" icon />\n *\n * // With avatar\n * <SectionHeading\n * title=\"User Profile\"\n * avatar={{ src: \"/avatar.jpg\", alt: \"User\" }}\n * />\n *\n * // With button\n * <SectionHeading\n * title=\"Section Title\"\n * button={{ label: \"Add Item\", onClick: () => {} }}\n * />\n *\n * // With button group\n * <SectionHeading\n * title=\"Section Title\"\n * buttonGroup={{\n * items: [{ label: \"Day\" }, { label: \"Week\" }],\n * activeIndex: 0,\n * onChange: (index) => {}\n * }}\n * />\n * ```\n */\nexport const SectionHeading = React.forwardRef<HTMLDivElement, SectionHeadingProps>(\n ({ title, icon, avatar, button, buttonGroup, className, style, ...props }, ref) => {\n const [buttonHovered, setButtonHovered] = React.useState(false);\n const [hoveredGroupIndex, setHoveredGroupIndex] = React.useState<number | null>(null);\n\n // Warn if both button and buttonGroup are provided\n if (button && buttonGroup) {\n console.warn('SectionHeading: button and buttonGroup are mutually exclusive. Only button will be rendered.');\n }\n\n const renderAvatar = () => {\n if (!avatar) return null;\n\n return (\n <div style={sectionHeadingStyles.avatar}>\n {avatar.src ? (\n <img\n src={avatar.src}\n alt={avatar.alt || 'Avatar'}\n style={sectionHeadingStyles.avatarImage}\n />\n ) : avatar.initials ? (\n <span style={sectionHeadingStyles.avatarInitials}>{avatar.initials}</span>\n ) : (\n <AvatarPlaceholder />\n )}\n </div>\n );\n };\n\n const renderTitle = () => {\n if (icon) {\n // Determine the icon variant - default to 'info' if boolean true\n const iconVariant: SectionIconVariant = typeof icon === 'string' ? icon : 'info';\n\n return (\n <div style={sectionHeadingStyles.titleWithIcon}>\n <h2 style={{ ...sectionHeadingStyles.title, flex: 'none' }}>{title}</h2>\n <div style={sectionHeadingStyles.iconBadge}>\n <SectionIcon variant={iconVariant} />\n </div>\n </div>\n );\n }\n\n return <h2 style={sectionHeadingStyles.title}>{title}</h2>;\n };\n\n const renderButton = () => {\n if (!button) return null;\n\n return (\n <button\n type=\"button\"\n style={{\n ...sectionHeadingStyles.button,\n ...(buttonHovered && sectionHeadingStyles.buttonHover),\n }}\n onClick={button.onClick}\n onMouseEnter={() => setButtonHovered(true)}\n onMouseLeave={() => setButtonHovered(false)}\n >\n {button.icon && (\n <span style={{ display: 'flex', alignItems: 'center', width: '16px', height: '16px' }}>\n {button.icon}\n </span>\n )}\n {button.label}\n </button>\n );\n };\n\n const renderButtonGroup = () => {\n if (!buttonGroup || button) return null;\n\n const { items, activeIndex = 0, onChange } = buttonGroup;\n\n return (\n <div style={sectionHeadingStyles.buttonGroup.container}>\n {items.slice(0, 4).map((item, index) => {\n const isActive = index === activeIndex;\n const isHovered = hoveredGroupIndex === index;\n\n let btnStyle: React.CSSProperties = {\n ...sectionHeadingStyles.buttonGroup.button.base,\n };\n\n if (isActive) {\n btnStyle = {\n ...btnStyle,\n ...sectionHeadingStyles.buttonGroup.button.active,\n ...(isHovered && sectionHeadingStyles.buttonGroup.button.activeHover),\n };\n } else {\n btnStyle = {\n ...btnStyle,\n ...sectionHeadingStyles.buttonGroup.button.default,\n ...(isHovered && sectionHeadingStyles.buttonGroup.button.hover),\n };\n }\n\n return (\n <button\n key={item.value || index}\n type=\"button\"\n style={btnStyle}\n onClick={() => {\n if (index !== activeIndex && onChange) {\n onChange(index);\n }\n }}\n onMouseEnter={() => setHoveredGroupIndex(index)}\n onMouseLeave={() => setHoveredGroupIndex(null)}\n >\n {item.icon && (\n <span style={{ display: 'flex', alignItems: 'center', width: '16px', height: '16px' }}>\n {item.icon}\n </span>\n )}\n {item.label}\n </button>\n );\n })}\n </div>\n );\n };\n\n return (\n <div\n ref={ref}\n className={clsx('arbor-section-heading', className)}\n style={{ ...sectionHeadingStyles.container, ...style }}\n {...props}\n >\n {renderAvatar()}\n {renderTitle()}\n {renderButton()}\n {renderButtonGroup()}\n </div>\n );\n }\n);\n\nSectionHeading.displayName = 'SectionHeading';\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SectionIcon
|
|
3
|
+
} from "./chunk-7NYBJKJS.mjs";
|
|
4
|
+
|
|
5
|
+
// src/ModalHeader/ModalHeader.tsx
|
|
6
|
+
import * as React from "react";
|
|
7
|
+
import { clsx } from "clsx";
|
|
8
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
+
var CloseIcon = () => /* @__PURE__ */ jsx(
|
|
10
|
+
"svg",
|
|
11
|
+
{
|
|
12
|
+
width: "10",
|
|
13
|
+
height: "10",
|
|
14
|
+
viewBox: "0 0 10 10",
|
|
15
|
+
fill: "none",
|
|
16
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
17
|
+
children: /* @__PURE__ */ jsx(
|
|
18
|
+
"path",
|
|
19
|
+
{
|
|
20
|
+
d: "M1 1L9 9M9 1L1 9",
|
|
21
|
+
stroke: "#2f2f2f",
|
|
22
|
+
strokeWidth: "1.5",
|
|
23
|
+
strokeLinecap: "round",
|
|
24
|
+
strokeLinejoin: "round"
|
|
25
|
+
}
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
var modalHeaderStyles = {
|
|
30
|
+
container: {
|
|
31
|
+
display: "flex",
|
|
32
|
+
alignItems: "center",
|
|
33
|
+
justifyContent: "space-between",
|
|
34
|
+
width: "100%",
|
|
35
|
+
padding: "16px",
|
|
36
|
+
backgroundColor: "#ffffff",
|
|
37
|
+
boxSizing: "border-box",
|
|
38
|
+
fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
|
|
39
|
+
minHeight: "56px"
|
|
40
|
+
},
|
|
41
|
+
leftContent: {
|
|
42
|
+
display: "flex",
|
|
43
|
+
alignItems: "center",
|
|
44
|
+
gap: "16px",
|
|
45
|
+
flex: 1
|
|
46
|
+
},
|
|
47
|
+
title: {
|
|
48
|
+
fontSize: "22px",
|
|
49
|
+
fontWeight: "600",
|
|
50
|
+
color: "#2f2f2f",
|
|
51
|
+
lineHeight: "1.25",
|
|
52
|
+
margin: 0
|
|
53
|
+
},
|
|
54
|
+
closeButton: {
|
|
55
|
+
display: "flex",
|
|
56
|
+
alignItems: "center",
|
|
57
|
+
justifyContent: "center",
|
|
58
|
+
width: "32px",
|
|
59
|
+
height: "32px",
|
|
60
|
+
borderRadius: "16px",
|
|
61
|
+
backgroundColor: "#ffffff",
|
|
62
|
+
border: "none",
|
|
63
|
+
cursor: "pointer",
|
|
64
|
+
padding: 0,
|
|
65
|
+
flexShrink: 0,
|
|
66
|
+
transition: "background-color 0.15s ease-in-out"
|
|
67
|
+
},
|
|
68
|
+
closeButtonHover: {
|
|
69
|
+
backgroundColor: "#f8f8f8"
|
|
70
|
+
},
|
|
71
|
+
closeButtonFocus: {
|
|
72
|
+
outline: "3px solid #3cad51",
|
|
73
|
+
outlineOffset: "-3px"
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
var ModalHeader = React.forwardRef(
|
|
77
|
+
({ title, icon, onClose, className, style, ...props }, ref) => {
|
|
78
|
+
const [isHovered, setIsHovered] = React.useState(false);
|
|
79
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
80
|
+
const closeButtonStyle = {
|
|
81
|
+
...modalHeaderStyles.closeButton,
|
|
82
|
+
...isHovered && modalHeaderStyles.closeButtonHover,
|
|
83
|
+
...isFocused && modalHeaderStyles.closeButtonFocus
|
|
84
|
+
};
|
|
85
|
+
return /* @__PURE__ */ jsxs(
|
|
86
|
+
"div",
|
|
87
|
+
{
|
|
88
|
+
ref,
|
|
89
|
+
className: clsx("arbor-modal-header", className),
|
|
90
|
+
style: { ...modalHeaderStyles.container, ...style },
|
|
91
|
+
...props,
|
|
92
|
+
children: [
|
|
93
|
+
/* @__PURE__ */ jsxs("div", { style: modalHeaderStyles.leftContent, children: [
|
|
94
|
+
icon && /* @__PURE__ */ jsx(SectionIcon, { variant: icon }),
|
|
95
|
+
/* @__PURE__ */ jsx("h2", { style: modalHeaderStyles.title, children: title })
|
|
96
|
+
] }),
|
|
97
|
+
onClose && /* @__PURE__ */ jsx(
|
|
98
|
+
"button",
|
|
99
|
+
{
|
|
100
|
+
type: "button",
|
|
101
|
+
onClick: onClose,
|
|
102
|
+
onMouseEnter: () => setIsHovered(true),
|
|
103
|
+
onMouseLeave: () => setIsHovered(false),
|
|
104
|
+
onFocus: () => setIsFocused(true),
|
|
105
|
+
onBlur: () => setIsFocused(false),
|
|
106
|
+
style: closeButtonStyle,
|
|
107
|
+
"aria-label": "Close modal",
|
|
108
|
+
children: /* @__PURE__ */ jsx(CloseIcon, {})
|
|
109
|
+
}
|
|
110
|
+
)
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
ModalHeader.displayName = "ModalHeader";
|
|
117
|
+
|
|
118
|
+
export {
|
|
119
|
+
ModalHeader
|
|
120
|
+
};
|
|
121
|
+
//# sourceMappingURL=chunk-GIQDPHZQ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ModalHeader/ModalHeader.tsx"],"sourcesContent":["import * as React from 'react';\nimport { clsx } from 'clsx';\nimport { SectionIcon, SectionIconVariant } from '../SectionIcon';\n\nexport interface ModalHeaderProps {\n /**\n * The title text for the modal header\n */\n title: string;\n /**\n * Optional icon variant to display before the title\n * Uses the SectionIcon component variants: 'warning', 'danger', 'info', 'success'\n */\n icon?: SectionIconVariant;\n /**\n * Callback when close button is clicked\n * If not provided, close button will not be shown\n */\n onClose?: () => void;\n /**\n * Additional CSS class name\n */\n className?: string;\n /**\n * Additional inline styles\n */\n style?: React.CSSProperties;\n}\n\n// Close X icon\nconst CloseIcon = () => (\n <svg\n width=\"10\"\n height=\"10\"\n viewBox=\"0 0 10 10\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M1 1L9 9M9 1L1 9\"\n stroke=\"#2f2f2f\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n);\n\n// Arbor Design System modal header styles\nconst modalHeaderStyles = {\n container: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n width: '100%',\n padding: '16px',\n backgroundColor: '#ffffff',\n boxSizing: 'border-box' as const,\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n minHeight: '56px',\n },\n leftContent: {\n display: 'flex',\n alignItems: 'center',\n gap: '16px',\n flex: 1,\n },\n title: {\n fontSize: '22px',\n fontWeight: '600',\n color: '#2f2f2f',\n lineHeight: '1.25',\n margin: 0,\n },\n closeButton: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '32px',\n height: '32px',\n borderRadius: '16px',\n backgroundColor: '#ffffff',\n border: 'none',\n cursor: 'pointer',\n padding: 0,\n flexShrink: 0,\n transition: 'background-color 0.15s ease-in-out',\n },\n closeButtonHover: {\n backgroundColor: '#f8f8f8',\n },\n closeButtonFocus: {\n outline: '3px solid #3cad51',\n outlineOffset: '-3px',\n },\n};\n\n/**\n * ModalHeader component - Arbor Design System\n *\n * The header part of a modal dialog with title, optional icon, and close button.\n * The icon uses SectionIcon variants (warning, danger, info, success).\n *\n * @example\n * ```tsx\n * // Basic modal header with close button\n * <ModalHeader\n * title=\"What would you like to do?\"\n * onClose={() => setIsOpen(false)}\n * />\n *\n * // Modal header with warning icon\n * <ModalHeader\n * title=\"Are you sure?\"\n * icon=\"warning\"\n * onClose={() => setIsOpen(false)}\n * />\n *\n * // Modal header with danger icon (error state)\n * <ModalHeader\n * title=\"Sorry, we can't find this page\"\n * icon=\"danger\"\n * onClose={() => setIsOpen(false)}\n * />\n *\n * // Modal header without close button\n * <ModalHeader\n * title=\"Processing...\"\n * icon=\"info\"\n * />\n * ```\n */\nexport const ModalHeader = React.forwardRef<HTMLDivElement, ModalHeaderProps>(\n ({ title, icon, onClose, className, style, ...props }, ref) => {\n const [isHovered, setIsHovered] = React.useState(false);\n const [isFocused, setIsFocused] = React.useState(false);\n\n const closeButtonStyle: React.CSSProperties = {\n ...modalHeaderStyles.closeButton,\n ...(isHovered && modalHeaderStyles.closeButtonHover),\n ...(isFocused && modalHeaderStyles.closeButtonFocus),\n };\n\n return (\n <div\n ref={ref}\n className={clsx('arbor-modal-header', className)}\n style={{ ...modalHeaderStyles.container, ...style }}\n {...props}\n >\n <div style={modalHeaderStyles.leftContent}>\n {icon && <SectionIcon variant={icon} />}\n <h2 style={modalHeaderStyles.title}>{title}</h2>\n </div>\n {onClose && (\n <button\n type=\"button\"\n onClick={onClose}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n style={closeButtonStyle}\n aria-label=\"Close modal\"\n >\n <CloseIcon />\n </button>\n )}\n </div>\n );\n }\n);\n\nModalHeader.displayName = 'ModalHeader';\n"],"mappings":";;;;;AAAA,YAAY,WAAW;AACvB,SAAS,YAAY;AAqCjB,cAgHI,YAhHJ;AARJ,IAAM,YAAY,MAChB;AAAA,EAAC;AAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAO;AAAA,IACP,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,OAAM;AAAA,IAEN;AAAA,MAAC;AAAA;AAAA,QACC,GAAE;AAAA,QACF,QAAO;AAAA,QACP,aAAY;AAAA,QACZ,eAAc;AAAA,QACd,gBAAe;AAAA;AAAA,IACjB;AAAA;AACF;AAIF,IAAM,oBAAoB;AAAA,EACxB,WAAW;AAAA,IACT,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,OAAO;AAAA,IACP,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,WAAW;AAAA,EACb;AAAA,EACA,aAAa;AAAA,IACX,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,KAAK;AAAA,IACL,MAAM;AAAA,EACR;AAAA,EACA,OAAO;AAAA,IACL,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,QAAQ;AAAA,EACV;AAAA,EACA,aAAa;AAAA,IACX,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AAAA,EACA,kBAAkB;AAAA,IAChB,iBAAiB;AAAA,EACnB;AAAA,EACA,kBAAkB;AAAA,IAChB,SAAS;AAAA,IACT,eAAe;AAAA,EACjB;AACF;AAqCO,IAAM,cAAoB;AAAA,EAC/B,CAAC,EAAE,OAAO,MAAM,SAAS,WAAW,OAAO,GAAG,MAAM,GAAG,QAAQ;AAC7D,UAAM,CAAC,WAAW,YAAY,IAAU,eAAS,KAAK;AACtD,UAAM,CAAC,WAAW,YAAY,IAAU,eAAS,KAAK;AAEtD,UAAM,mBAAwC;AAAA,MAC5C,GAAG,kBAAkB;AAAA,MACrB,GAAI,aAAa,kBAAkB;AAAA,MACnC,GAAI,aAAa,kBAAkB;AAAA,IACrC;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,KAAK,sBAAsB,SAAS;AAAA,QAC/C,OAAO,EAAE,GAAG,kBAAkB,WAAW,GAAG,MAAM;AAAA,QACjD,GAAG;AAAA,QAEJ;AAAA,+BAAC,SAAI,OAAO,kBAAkB,aAC3B;AAAA,oBAAQ,oBAAC,eAAY,SAAS,MAAM;AAAA,YACrC,oBAAC,QAAG,OAAO,kBAAkB,OAAQ,iBAAM;AAAA,aAC7C;AAAA,UACC,WACC;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS;AAAA,cACT,cAAc,MAAM,aAAa,IAAI;AAAA,cACrC,cAAc,MAAM,aAAa,KAAK;AAAA,cACtC,SAAS,MAAM,aAAa,IAAI;AAAA,cAChC,QAAQ,MAAM,aAAa,KAAK;AAAA,cAChC,OAAO;AAAA,cACP,cAAW;AAAA,cAEX,8BAAC,aAAU;AAAA;AAAA,UACb;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,YAAY,cAAc;","names":[]}
|