@tonyarbor/components 0.6.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.
@@ -66,6 +66,32 @@ var buttonStyles = {
66
66
  cursor: "not-allowed"
67
67
  }
68
68
  },
69
+ tertiary: {
70
+ backgroundColor: "#efefef",
71
+ // grey-100
72
+ color: "#2f2f2f",
73
+ // grey-900
74
+ ":hover": {
75
+ backgroundColor: "#dfdfdf"
76
+ // grey-200
77
+ },
78
+ ":active": {
79
+ backgroundColor: "#d1d1d1"
80
+ // grey-300
81
+ },
82
+ ":focus-visible": {
83
+ outline: "3px solid #3cad51",
84
+ // brand-500
85
+ outlineOffset: "0px"
86
+ },
87
+ ":disabled": {
88
+ backgroundColor: "#f8f8f8",
89
+ // grey-050
90
+ color: "#b3b3b3",
91
+ // grey-400
92
+ cursor: "not-allowed"
93
+ }
94
+ },
69
95
  destructive: {
70
96
  backgroundColor: "#c93232",
71
97
  // destructive-500
@@ -88,6 +114,36 @@ var buttonStyles = {
88
114
  cursor: "not-allowed"
89
115
  }
90
116
  },
117
+ "destructive-secondary": {
118
+ backgroundColor: "#ffffff",
119
+ color: "#a62323",
120
+ // destructive-600
121
+ border: "1px solid #c93232",
122
+ // destructive-500
123
+ ":hover": {
124
+ backgroundColor: "#a62323",
125
+ // destructive-600
126
+ color: "#ffffff",
127
+ border: "1px solid #a62323"
128
+ },
129
+ ":active": {
130
+ backgroundColor: "#920a0a",
131
+ // destructive-700
132
+ color: "#ffffff",
133
+ border: "1px solid #920a0a"
134
+ },
135
+ ":focus-visible": {
136
+ outline: "3px solid #3cad51",
137
+ // brand-500 (green focus ring)
138
+ outlineOffset: "0px"
139
+ },
140
+ ":disabled": {
141
+ backgroundColor: "#ffffff",
142
+ color: "#b3b3b3",
143
+ border: "1px solid #d1d1d1",
144
+ cursor: "not-allowed"
145
+ }
146
+ },
91
147
  ghost: {
92
148
  backgroundColor: "transparent",
93
149
  color: "#0b800b",
@@ -191,4 +247,4 @@ Button.displayName = "Button";
191
247
  export {
192
248
  Button
193
249
  };
194
- //# sourceMappingURL=chunk-ALEJXAZY.mjs.map
250
+ //# sourceMappingURL=chunk-NOUFR6W2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Button/Button.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { clsx } from 'clsx';\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'destructive' | 'destructive-secondary' | 'ghost';\nexport type ButtonSize = 'small' | 'medium';\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /**\n * The visual style variant of the button\n * @default 'primary'\n */\n variant?: ButtonVariant;\n /**\n * The size of the button\n * @default 'medium'\n */\n size?: ButtonSize;\n /**\n * If true, the component will be rendered as a child element\n * and merge its props with the child\n */\n asChild?: boolean;\n /**\n * The content of the button\n */\n children: React.ReactNode;\n}\n\n// Arbor Design System button styles\nconst buttonStyles = {\n base: {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n fontWeight: '500',\n borderRadius: '99px', // Pill shape\n border: 'none',\n cursor: 'pointer',\n transition: 'all 0.2s ease-in-out',\n outline: 'none',\n },\n variants: {\n primary: {\n backgroundColor: '#0e8a0e', // brand-600\n color: '#ffffff',\n ':hover': {\n backgroundColor: '#005700', // brand-800\n },\n ':active': {\n backgroundColor: '#024002', // brand-900\n },\n ':focus-visible': {\n outline: '3px solid #3cad51', // brand-500\n outlineOffset: '0px',\n },\n ':disabled': {\n backgroundColor: '#b3b3b3', // grey-400\n cursor: 'not-allowed',\n },\n },\n secondary: {\n backgroundColor: '#ffffff',\n color: '#2f2f2f', // grey-900\n border: '1px solid #d1d1d1', // grey-300\n ':hover': {\n backgroundColor: '#f8f8f8', // grey-050\n },\n ':active': {\n backgroundColor: '#efefef', // grey-100\n },\n ':focus-visible': {\n outline: '3px solid #3cad51', // brand-500\n outlineOffset: '0px',\n },\n ':disabled': {\n backgroundColor: '#f8f8f8',\n color: '#b3b3b3',\n cursor: 'not-allowed',\n },\n },\n tertiary: {\n backgroundColor: '#efefef', // grey-100\n color: '#2f2f2f', // grey-900\n ':hover': {\n backgroundColor: '#dfdfdf', // grey-200\n },\n ':active': {\n backgroundColor: '#d1d1d1', // grey-300\n },\n ':focus-visible': {\n outline: '3px solid #3cad51', // brand-500\n outlineOffset: '0px',\n },\n ':disabled': {\n backgroundColor: '#f8f8f8', // grey-050\n color: '#b3b3b3', // grey-400\n cursor: 'not-allowed',\n },\n },\n destructive: {\n backgroundColor: '#c93232', // destructive-500\n color: '#ffffff',\n ':hover': {\n backgroundColor: '#920a0a', // destructive-700\n },\n ':active': {\n backgroundColor: '#610202', // destructive-800\n },\n ':focus-visible': {\n outline: '3px solid #e86565', // destructive-300\n outlineOffset: '0px',\n },\n ':disabled': {\n backgroundColor: '#b3b3b3',\n cursor: 'not-allowed',\n },\n },\n 'destructive-secondary': {\n backgroundColor: '#ffffff',\n color: '#a62323', // destructive-600\n border: '1px solid #c93232', // destructive-500\n ':hover': {\n backgroundColor: '#a62323', // destructive-600\n color: '#ffffff',\n border: '1px solid #a62323',\n },\n ':active': {\n backgroundColor: '#920a0a', // destructive-700\n color: '#ffffff',\n border: '1px solid #920a0a',\n },\n ':focus-visible': {\n outline: '3px solid #3cad51', // brand-500 (green focus ring)\n outlineOffset: '0px',\n },\n ':disabled': {\n backgroundColor: '#ffffff',\n color: '#b3b3b3',\n border: '1px solid #d1d1d1',\n cursor: 'not-allowed',\n },\n },\n ghost: {\n backgroundColor: 'transparent',\n color: '#0b800b', // brand-700 for link style\n textDecoration: 'underline',\n ':hover': {\n color: '#005700', // brand-800\n },\n ':active': {\n color: '#024002', // brand-900\n },\n ':focus-visible': {\n outline: '3px solid #3cad51',\n outlineOffset: '2px',\n },\n ':disabled': {\n color: '#b3b3b3',\n cursor: 'not-allowed',\n },\n },\n },\n sizes: {\n small: {\n height: '32px',\n fontSize: '13px',\n padding: '8px 16px',\n },\n medium: {\n height: '36px',\n fontSize: '13px',\n padding: '8px 16px',\n },\n },\n};\n\n/**\n * Button component - Arbor Design System\n *\n * A flexible button component with pill-shaped design following Arbor's design system.\n * Supports primary (green), secondary (outlined), destructive (red), and ghost (link-style) variants.\n *\n * @example\n * ```tsx\n * <Button variant=\"primary\" size=\"medium\">\n * Save Changes\n * </Button>\n * ```\n */\nexport const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n variant = 'primary',\n size = 'medium',\n asChild = false,\n className,\n disabled,\n style,\n children,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n ...props\n },\n ref\n ) => {\n const Comp = asChild ? Slot : 'button';\n const [isHovered, setIsHovered] = React.useState(false);\n const [isFocused, setIsFocused] = React.useState(false);\n\n const variantStyles = buttonStyles.variants[variant];\n const sizeStyles = buttonStyles.sizes[size];\n\n const combinedStyle: React.CSSProperties = {\n ...buttonStyles.base,\n ...variantStyles,\n ...sizeStyles,\n ...(isHovered && !disabled && variantStyles[':hover']),\n ...(isFocused && !disabled && variantStyles[':focus-visible']),\n ...(disabled && variantStyles[':disabled']),\n ...style,\n };\n\n const handleMouseEnter = (e: React.MouseEvent<HTMLButtonElement>) => {\n setIsHovered(true);\n onMouseEnter?.(e);\n };\n\n const handleMouseLeave = (e: React.MouseEvent<HTMLButtonElement>) => {\n setIsHovered(false);\n onMouseLeave?.(e);\n };\n\n const handleFocus = (e: React.FocusEvent<HTMLButtonElement>) => {\n setIsFocused(true);\n onFocus?.(e);\n };\n\n const handleBlur = (e: React.FocusEvent<HTMLButtonElement>) => {\n setIsFocused(false);\n onBlur?.(e);\n };\n\n return (\n <Comp\n ref={ref}\n className={clsx('arbor-button', className)}\n style={combinedStyle}\n disabled={disabled}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n {...props}\n >\n {children}\n </Comp>\n );\n }\n);\n\nButton.displayName = 'Button';\n"],"mappings":"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","names":[]}
@@ -0,0 +1,37 @@
1
+ // src/ModalFooter/ModalFooter.tsx
2
+ import * as React from "react";
3
+ import { clsx } from "clsx";
4
+ import { jsx } from "react/jsx-runtime";
5
+ var modalFooterStyles = {
6
+ container: {
7
+ display: "flex",
8
+ alignItems: "center",
9
+ justifyContent: "flex-end",
10
+ gap: "16px",
11
+ width: "100%",
12
+ padding: "16px",
13
+ backgroundColor: "#ffffff",
14
+ boxSizing: "border-box",
15
+ maxHeight: "56px"
16
+ }
17
+ };
18
+ var ModalFooter = React.forwardRef(
19
+ ({ children, className, style, ...props }, ref) => {
20
+ return /* @__PURE__ */ jsx(
21
+ "div",
22
+ {
23
+ ref,
24
+ className: clsx("arbor-modal-footer", className),
25
+ style: { ...modalFooterStyles.container, ...style },
26
+ ...props,
27
+ children
28
+ }
29
+ );
30
+ }
31
+ );
32
+ ModalFooter.displayName = "ModalFooter";
33
+
34
+ export {
35
+ ModalFooter
36
+ };
37
+ //# sourceMappingURL=chunk-P7RKUESQ.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ModalFooter/ModalFooter.tsx"],"sourcesContent":["import * as React from 'react';\nimport { clsx } from 'clsx';\n\nexport interface ModalFooterProps {\n /**\n * The content of the footer, typically buttons\n */\n children: React.ReactNode;\n /**\n * Additional CSS class name\n */\n className?: string;\n /**\n * Additional inline styles\n */\n style?: React.CSSProperties;\n}\n\n// Arbor Design System modal footer styles\nconst modalFooterStyles = {\n container: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'flex-end',\n gap: '16px',\n width: '100%',\n padding: '16px',\n backgroundColor: '#ffffff',\n boxSizing: 'border-box' as const,\n maxHeight: '56px',\n },\n};\n\n/**\n * ModalFooter component - Arbor Design System\n *\n * The footer part of a modal dialog, typically containing action buttons.\n * Buttons are right-aligned by default.\n *\n * @example\n * ```tsx\n * // Footer with two buttons\n * <ModalFooter>\n * <Button variant=\"tertiary\">Cancel</Button>\n * <Button variant=\"primary\">Save</Button>\n * </ModalFooter>\n *\n * // Footer with destructive action\n * <ModalFooter>\n * <Button variant=\"tertiary\">Cancel</Button>\n * <Button variant=\"destructive-secondary\">Delete</Button>\n * </ModalFooter>\n * ```\n */\nexport const ModalFooter = React.forwardRef<HTMLDivElement, ModalFooterProps>(\n ({ children, className, style, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={clsx('arbor-modal-footer', className)}\n style={{ ...modalFooterStyles.container, ...style }}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nModalFooter.displayName = 'ModalFooter';\n"],"mappings":";AAAA,YAAY,WAAW;AACvB,SAAS,YAAY;AAwDf;AAtCN,IAAM,oBAAoB;AAAA,EACxB,WAAW;AAAA,IACT,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,gBAAgB;AAAA,IAChB,KAAK;AAAA,IACL,OAAO;AAAA,IACP,SAAS;AAAA,IACT,iBAAiB;AAAA,IACjB,WAAW;AAAA,IACX,WAAW;AAAA,EACb;AACF;AAuBO,IAAM,cAAoB;AAAA,EAC/B,CAAC,EAAE,UAAU,WAAW,OAAO,GAAG,MAAM,GAAG,QAAQ;AACjD,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,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,YAAY,cAAc;","names":[]}
package/dist/index.d.mts CHANGED
@@ -31,12 +31,15 @@ export { SubSectionHeading, SubSectionHeadingProps } from './SubSectionHeading.m
31
31
  export { SubSectionInteractive, SubSectionInteractiveProps } from './SubSectionInteractive.mjs';
32
32
  export { SectionHeadingInteractive, SectionHeadingInteractiveProps } from './SectionHeadingInteractive.mjs';
33
33
  export { Section, SectionProps } from './Section.mjs';
34
+ export { ModalHeader, ModalHeaderProps } from './ModalHeader.mjs';
35
+ export { ModalFooter, ModalFooterProps } from './ModalFooter.mjs';
36
+ export { Modal, ModalContent, ModalContentProps, ModalProps } from './Modal.mjs';
34
37
  import 'react';
35
38
 
36
39
  /**
37
40
  * Shared TypeScript types for Arbor Design System components
38
41
  */
39
- type ButtonVariant = 'primary' | 'secondary' | 'destructive' | 'ghost';
42
+ type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'destructive' | 'destructive-secondary' | 'ghost';
40
43
  type ButtonSize = 'small' | 'medium';
41
44
  type InputSize = 'small' | 'medium';
42
45
  type ValidationState = 'default' | 'error' | 'success';
package/dist/index.d.ts CHANGED
@@ -31,12 +31,15 @@ export { SubSectionHeading, SubSectionHeadingProps } from './SubSectionHeading.j
31
31
  export { SubSectionInteractive, SubSectionInteractiveProps } from './SubSectionInteractive.js';
32
32
  export { SectionHeadingInteractive, SectionHeadingInteractiveProps } from './SectionHeadingInteractive.js';
33
33
  export { Section, SectionProps } from './Section.js';
34
+ export { ModalHeader, ModalHeaderProps } from './ModalHeader.js';
35
+ export { ModalFooter, ModalFooterProps } from './ModalFooter.js';
36
+ export { Modal, ModalContent, ModalContentProps, ModalProps } from './Modal.js';
34
37
  import 'react';
35
38
 
36
39
  /**
37
40
  * Shared TypeScript types for Arbor Design System components
38
41
  */
39
- type ButtonVariant = 'primary' | 'secondary' | 'destructive' | 'ghost';
42
+ type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'destructive' | 'destructive-secondary' | 'ghost';
40
43
  type ButtonSize = 'small' | 'medium';
41
44
  type InputSize = 'small' | 'medium';
42
45
  type ValidationState = 'default' | 'error' | 'success';
package/dist/index.js CHANGED
@@ -43,6 +43,10 @@ __export(src_exports, {
43
43
  ListRow: () => ListRow,
44
44
  ListRowMultiLine: () => ListRowMultiLine,
45
45
  Logo: () => Logo,
46
+ Modal: () => Modal,
47
+ ModalContent: () => ModalContent,
48
+ ModalFooter: () => ModalFooter,
49
+ ModalHeader: () => ModalHeader,
46
50
  NumericInput: () => NumericInput,
47
51
  Pagination: () => Pagination,
48
52
  Radio: () => Radio,
@@ -134,6 +138,32 @@ var buttonStyles = {
134
138
  cursor: "not-allowed"
135
139
  }
136
140
  },
141
+ tertiary: {
142
+ backgroundColor: "#efefef",
143
+ // grey-100
144
+ color: "#2f2f2f",
145
+ // grey-900
146
+ ":hover": {
147
+ backgroundColor: "#dfdfdf"
148
+ // grey-200
149
+ },
150
+ ":active": {
151
+ backgroundColor: "#d1d1d1"
152
+ // grey-300
153
+ },
154
+ ":focus-visible": {
155
+ outline: "3px solid #3cad51",
156
+ // brand-500
157
+ outlineOffset: "0px"
158
+ },
159
+ ":disabled": {
160
+ backgroundColor: "#f8f8f8",
161
+ // grey-050
162
+ color: "#b3b3b3",
163
+ // grey-400
164
+ cursor: "not-allowed"
165
+ }
166
+ },
137
167
  destructive: {
138
168
  backgroundColor: "#c93232",
139
169
  // destructive-500
@@ -156,6 +186,36 @@ var buttonStyles = {
156
186
  cursor: "not-allowed"
157
187
  }
158
188
  },
189
+ "destructive-secondary": {
190
+ backgroundColor: "#ffffff",
191
+ color: "#a62323",
192
+ // destructive-600
193
+ border: "1px solid #c93232",
194
+ // destructive-500
195
+ ":hover": {
196
+ backgroundColor: "#a62323",
197
+ // destructive-600
198
+ color: "#ffffff",
199
+ border: "1px solid #a62323"
200
+ },
201
+ ":active": {
202
+ backgroundColor: "#920a0a",
203
+ // destructive-700
204
+ color: "#ffffff",
205
+ border: "1px solid #920a0a"
206
+ },
207
+ ":focus-visible": {
208
+ outline: "3px solid #3cad51",
209
+ // brand-500 (green focus ring)
210
+ outlineOffset: "0px"
211
+ },
212
+ ":disabled": {
213
+ backgroundColor: "#ffffff",
214
+ color: "#b3b3b3",
215
+ border: "1px solid #d1d1d1",
216
+ cursor: "not-allowed"
217
+ }
218
+ },
159
219
  ghost: {
160
220
  backgroundColor: "transparent",
161
221
  color: "#0b800b",
@@ -6130,6 +6190,224 @@ var Section = React33.forwardRef(
6130
6190
  }
6131
6191
  );
6132
6192
  Section.displayName = "Section";
6193
+
6194
+ // src/ModalHeader/ModalHeader.tsx
6195
+ var React34 = __toESM(require("react"));
6196
+ var import_clsx29 = require("clsx");
6197
+ var import_jsx_runtime34 = require("react/jsx-runtime");
6198
+ var CloseIcon = () => /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6199
+ "svg",
6200
+ {
6201
+ width: "10",
6202
+ height: "10",
6203
+ viewBox: "0 0 10 10",
6204
+ fill: "none",
6205
+ xmlns: "http://www.w3.org/2000/svg",
6206
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6207
+ "path",
6208
+ {
6209
+ d: "M1 1L9 9M9 1L1 9",
6210
+ stroke: "#2f2f2f",
6211
+ strokeWidth: "1.5",
6212
+ strokeLinecap: "round",
6213
+ strokeLinejoin: "round"
6214
+ }
6215
+ )
6216
+ }
6217
+ );
6218
+ var modalHeaderStyles = {
6219
+ container: {
6220
+ display: "flex",
6221
+ alignItems: "center",
6222
+ justifyContent: "space-between",
6223
+ width: "100%",
6224
+ padding: "16px",
6225
+ backgroundColor: "#ffffff",
6226
+ boxSizing: "border-box",
6227
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
6228
+ minHeight: "56px"
6229
+ },
6230
+ leftContent: {
6231
+ display: "flex",
6232
+ alignItems: "center",
6233
+ gap: "16px",
6234
+ flex: 1
6235
+ },
6236
+ title: {
6237
+ fontSize: "22px",
6238
+ fontWeight: "600",
6239
+ color: "#2f2f2f",
6240
+ lineHeight: "1.25",
6241
+ margin: 0
6242
+ },
6243
+ closeButton: {
6244
+ display: "flex",
6245
+ alignItems: "center",
6246
+ justifyContent: "center",
6247
+ width: "32px",
6248
+ height: "32px",
6249
+ borderRadius: "16px",
6250
+ backgroundColor: "#ffffff",
6251
+ border: "none",
6252
+ cursor: "pointer",
6253
+ padding: 0,
6254
+ flexShrink: 0,
6255
+ transition: "background-color 0.15s ease-in-out"
6256
+ },
6257
+ closeButtonHover: {
6258
+ backgroundColor: "#f8f8f8"
6259
+ },
6260
+ closeButtonFocus: {
6261
+ outline: "3px solid #3cad51",
6262
+ outlineOffset: "-3px"
6263
+ }
6264
+ };
6265
+ var ModalHeader = React34.forwardRef(
6266
+ ({ title, icon, onClose, className, style, ...props }, ref) => {
6267
+ const [isHovered, setIsHovered] = React34.useState(false);
6268
+ const [isFocused, setIsFocused] = React34.useState(false);
6269
+ const closeButtonStyle = {
6270
+ ...modalHeaderStyles.closeButton,
6271
+ ...isHovered && modalHeaderStyles.closeButtonHover,
6272
+ ...isFocused && modalHeaderStyles.closeButtonFocus
6273
+ };
6274
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
6275
+ "div",
6276
+ {
6277
+ ref,
6278
+ className: (0, import_clsx29.clsx)("arbor-modal-header", className),
6279
+ style: { ...modalHeaderStyles.container, ...style },
6280
+ ...props,
6281
+ children: [
6282
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { style: modalHeaderStyles.leftContent, children: [
6283
+ icon && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(SectionIcon, { variant: icon }),
6284
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("h2", { style: modalHeaderStyles.title, children: title })
6285
+ ] }),
6286
+ onClose && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6287
+ "button",
6288
+ {
6289
+ type: "button",
6290
+ onClick: onClose,
6291
+ onMouseEnter: () => setIsHovered(true),
6292
+ onMouseLeave: () => setIsHovered(false),
6293
+ onFocus: () => setIsFocused(true),
6294
+ onBlur: () => setIsFocused(false),
6295
+ style: closeButtonStyle,
6296
+ "aria-label": "Close modal",
6297
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(CloseIcon, {})
6298
+ }
6299
+ )
6300
+ ]
6301
+ }
6302
+ );
6303
+ }
6304
+ );
6305
+ ModalHeader.displayName = "ModalHeader";
6306
+
6307
+ // src/ModalFooter/ModalFooter.tsx
6308
+ var React35 = __toESM(require("react"));
6309
+ var import_clsx30 = require("clsx");
6310
+ var import_jsx_runtime35 = require("react/jsx-runtime");
6311
+ var modalFooterStyles = {
6312
+ container: {
6313
+ display: "flex",
6314
+ alignItems: "center",
6315
+ justifyContent: "flex-end",
6316
+ gap: "16px",
6317
+ width: "100%",
6318
+ padding: "16px",
6319
+ backgroundColor: "#ffffff",
6320
+ boxSizing: "border-box",
6321
+ maxHeight: "56px"
6322
+ }
6323
+ };
6324
+ var ModalFooter = React35.forwardRef(
6325
+ ({ children, className, style, ...props }, ref) => {
6326
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
6327
+ "div",
6328
+ {
6329
+ ref,
6330
+ className: (0, import_clsx30.clsx)("arbor-modal-footer", className),
6331
+ style: { ...modalFooterStyles.container, ...style },
6332
+ ...props,
6333
+ children
6334
+ }
6335
+ );
6336
+ }
6337
+ );
6338
+ ModalFooter.displayName = "ModalFooter";
6339
+
6340
+ // src/Modal/Modal.tsx
6341
+ var React36 = __toESM(require("react"));
6342
+ var import_clsx31 = require("clsx");
6343
+ var import_jsx_runtime36 = require("react/jsx-runtime");
6344
+ var modalStyles = {
6345
+ container: {
6346
+ display: "flex",
6347
+ flexDirection: "column",
6348
+ alignItems: "flex-start",
6349
+ backgroundColor: "#f8f8f8",
6350
+ // grey-050
6351
+ borderRadius: "8px",
6352
+ boxShadow: "0px 8px 24px 0px rgba(32, 32, 32, 0.12)",
6353
+ overflow: "hidden",
6354
+ boxSizing: "border-box",
6355
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
6356
+ },
6357
+ content: {
6358
+ display: "flex",
6359
+ alignItems: "center",
6360
+ justifyContent: "center",
6361
+ width: "100%",
6362
+ padding: "32px 16px",
6363
+ backgroundColor: "#f8f8f8",
6364
+ // grey-050
6365
+ boxSizing: "border-box"
6366
+ },
6367
+ contentText: {
6368
+ flex: 1,
6369
+ fontSize: "13px",
6370
+ fontWeight: "400",
6371
+ color: "#2f2f2f",
6372
+ lineHeight: "1.5"
6373
+ }
6374
+ };
6375
+ var Modal = React36.forwardRef(
6376
+ ({ children, width = 584, className, style, ...props }, ref) => {
6377
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6378
+ "div",
6379
+ {
6380
+ ref,
6381
+ className: (0, import_clsx31.clsx)("arbor-modal", className),
6382
+ style: {
6383
+ ...modalStyles.container,
6384
+ width: typeof width === "number" ? `${width}px` : width,
6385
+ ...style
6386
+ },
6387
+ role: "dialog",
6388
+ "aria-modal": "true",
6389
+ ...props,
6390
+ children
6391
+ }
6392
+ );
6393
+ }
6394
+ );
6395
+ Modal.displayName = "Modal";
6396
+ var ModalContent = React36.forwardRef(
6397
+ ({ children, className, style, ...props }, ref) => {
6398
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6399
+ "div",
6400
+ {
6401
+ ref,
6402
+ className: (0, import_clsx31.clsx)("arbor-modal-content", className),
6403
+ style: { ...modalStyles.content, ...style },
6404
+ ...props,
6405
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { style: modalStyles.contentText, children })
6406
+ }
6407
+ );
6408
+ }
6409
+ );
6410
+ ModalContent.displayName = "ModalContent";
6133
6411
  // Annotate the CommonJS export names for ESM import in node:
6134
6412
  0 && (module.exports = {
6135
6413
  Avatar,
@@ -6145,6 +6423,10 @@ Section.displayName = "Section";
6145
6423
  ListRow,
6146
6424
  ListRowMultiLine,
6147
6425
  Logo,
6426
+ Modal,
6427
+ ModalContent,
6428
+ ModalFooter,
6429
+ ModalHeader,
6148
6430
  NumericInput,
6149
6431
  Pagination,
6150
6432
  Radio,