@tonyarbor/components 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,194 @@
1
+ // src/Button/Button.tsx
2
+ import * as React from "react";
3
+ import { Slot } from "@radix-ui/react-slot";
4
+ import { clsx } from "clsx";
5
+ import { jsx } from "react/jsx-runtime";
6
+ var buttonStyles = {
7
+ base: {
8
+ display: "inline-flex",
9
+ alignItems: "center",
10
+ justifyContent: "center",
11
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
12
+ fontWeight: "500",
13
+ borderRadius: "99px",
14
+ // Pill shape
15
+ border: "none",
16
+ cursor: "pointer",
17
+ transition: "all 0.2s ease-in-out",
18
+ outline: "none"
19
+ },
20
+ variants: {
21
+ primary: {
22
+ backgroundColor: "#0e8a0e",
23
+ // brand-600
24
+ color: "#ffffff",
25
+ ":hover": {
26
+ backgroundColor: "#005700"
27
+ // brand-800
28
+ },
29
+ ":active": {
30
+ backgroundColor: "#024002"
31
+ // brand-900
32
+ },
33
+ ":focus-visible": {
34
+ outline: "3px solid #3cad51",
35
+ // brand-500
36
+ outlineOffset: "0px"
37
+ },
38
+ ":disabled": {
39
+ backgroundColor: "#b3b3b3",
40
+ // grey-400
41
+ cursor: "not-allowed"
42
+ }
43
+ },
44
+ secondary: {
45
+ backgroundColor: "#ffffff",
46
+ color: "#2f2f2f",
47
+ // grey-900
48
+ border: "1px solid #d1d1d1",
49
+ // grey-300
50
+ ":hover": {
51
+ backgroundColor: "#f8f8f8"
52
+ // grey-050
53
+ },
54
+ ":active": {
55
+ backgroundColor: "#efefef"
56
+ // grey-100
57
+ },
58
+ ":focus-visible": {
59
+ outline: "3px solid #3cad51",
60
+ // brand-500
61
+ outlineOffset: "0px"
62
+ },
63
+ ":disabled": {
64
+ backgroundColor: "#f8f8f8",
65
+ color: "#b3b3b3",
66
+ cursor: "not-allowed"
67
+ }
68
+ },
69
+ destructive: {
70
+ backgroundColor: "#c93232",
71
+ // destructive-500
72
+ color: "#ffffff",
73
+ ":hover": {
74
+ backgroundColor: "#920a0a"
75
+ // destructive-700
76
+ },
77
+ ":active": {
78
+ backgroundColor: "#610202"
79
+ // destructive-800
80
+ },
81
+ ":focus-visible": {
82
+ outline: "3px solid #e86565",
83
+ // destructive-300
84
+ outlineOffset: "0px"
85
+ },
86
+ ":disabled": {
87
+ backgroundColor: "#b3b3b3",
88
+ cursor: "not-allowed"
89
+ }
90
+ },
91
+ ghost: {
92
+ backgroundColor: "transparent",
93
+ color: "#0b800b",
94
+ // brand-700 for link style
95
+ textDecoration: "underline",
96
+ ":hover": {
97
+ color: "#005700"
98
+ // brand-800
99
+ },
100
+ ":active": {
101
+ color: "#024002"
102
+ // brand-900
103
+ },
104
+ ":focus-visible": {
105
+ outline: "3px solid #3cad51",
106
+ outlineOffset: "2px"
107
+ },
108
+ ":disabled": {
109
+ color: "#b3b3b3",
110
+ cursor: "not-allowed"
111
+ }
112
+ }
113
+ },
114
+ sizes: {
115
+ small: {
116
+ height: "32px",
117
+ fontSize: "13px",
118
+ padding: "8px 16px"
119
+ },
120
+ medium: {
121
+ height: "36px",
122
+ fontSize: "13px",
123
+ padding: "8px 16px"
124
+ }
125
+ }
126
+ };
127
+ var Button = React.forwardRef(
128
+ ({
129
+ variant = "primary",
130
+ size = "medium",
131
+ asChild = false,
132
+ className,
133
+ disabled,
134
+ style,
135
+ children,
136
+ onMouseEnter,
137
+ onMouseLeave,
138
+ onFocus,
139
+ onBlur,
140
+ ...props
141
+ }, ref) => {
142
+ const Comp = asChild ? Slot : "button";
143
+ const [isHovered, setIsHovered] = React.useState(false);
144
+ const [isFocused, setIsFocused] = React.useState(false);
145
+ const variantStyles = buttonStyles.variants[variant];
146
+ const sizeStyles = buttonStyles.sizes[size];
147
+ const combinedStyle = {
148
+ ...buttonStyles.base,
149
+ ...variantStyles,
150
+ ...sizeStyles,
151
+ ...isHovered && !disabled && variantStyles[":hover"],
152
+ ...isFocused && !disabled && variantStyles[":focus-visible"],
153
+ ...disabled && variantStyles[":disabled"],
154
+ ...style
155
+ };
156
+ const handleMouseEnter = (e) => {
157
+ setIsHovered(true);
158
+ onMouseEnter?.(e);
159
+ };
160
+ const handleMouseLeave = (e) => {
161
+ setIsHovered(false);
162
+ onMouseLeave?.(e);
163
+ };
164
+ const handleFocus = (e) => {
165
+ setIsFocused(true);
166
+ onFocus?.(e);
167
+ };
168
+ const handleBlur = (e) => {
169
+ setIsFocused(false);
170
+ onBlur?.(e);
171
+ };
172
+ return /* @__PURE__ */ jsx(
173
+ Comp,
174
+ {
175
+ ref,
176
+ className: clsx("arbor-button", className),
177
+ style: combinedStyle,
178
+ disabled,
179
+ onMouseEnter: handleMouseEnter,
180
+ onMouseLeave: handleMouseLeave,
181
+ onFocus: handleFocus,
182
+ onBlur: handleBlur,
183
+ ...props,
184
+ children
185
+ }
186
+ );
187
+ }
188
+ );
189
+ Button.displayName = "Button";
190
+
191
+ export {
192
+ Button
193
+ };
194
+ //# sourceMappingURL=chunk-ALEJXAZY.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' | 'destructive' | '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 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 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,153 @@
1
+ // src/Input/Input.tsx
2
+ import * as React from "react";
3
+ import { clsx } from "clsx";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ var inputStyles = {
6
+ base: {
7
+ width: "100%",
8
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
9
+ backgroundColor: "#ffffff",
10
+ borderRadius: "8px",
11
+ transition: "all 0.2s ease-in-out",
12
+ outline: "none",
13
+ margin: "0",
14
+ display: "block"
15
+ },
16
+ sizes: {
17
+ small: {
18
+ height: "32px",
19
+ fontSize: "13px",
20
+ padding: "8px"
21
+ },
22
+ medium: {
23
+ height: "36px",
24
+ fontSize: "13px",
25
+ padding: "8px"
26
+ }
27
+ },
28
+ states: {
29
+ default: {
30
+ border: "1px solid #d1d1d1",
31
+ // grey-300
32
+ color: "#2f2f2f",
33
+ // grey-900
34
+ ":focus": {
35
+ borderColor: "#3cad51",
36
+ // brand-500
37
+ outline: "3px solid rgba(60, 173, 81, 0.2)"
38
+ },
39
+ ":disabled": {
40
+ backgroundColor: "#f8f8f8",
41
+ // grey-050
42
+ borderColor: "#efefef",
43
+ // grey-100
44
+ color: "#7e7e7e",
45
+ // grey-500
46
+ cursor: "not-allowed"
47
+ }
48
+ },
49
+ error: {
50
+ border: "1px solid #c93232",
51
+ // destructive-500
52
+ color: "#2f2f2f",
53
+ ":focus": {
54
+ borderColor: "#c93232",
55
+ outline: "3px solid rgba(201, 50, 50, 0.2)"
56
+ }
57
+ },
58
+ success: {
59
+ border: "1px solid #16a33d",
60
+ // success-500
61
+ color: "#2f2f2f",
62
+ ":focus": {
63
+ borderColor: "#16a33d",
64
+ outline: "3px solid rgba(22, 163, 61, 0.2)"
65
+ }
66
+ }
67
+ }
68
+ };
69
+ var labelStyles = {
70
+ display: "block",
71
+ fontSize: "13px",
72
+ fontWeight: "600",
73
+ color: "#2f2f2f",
74
+ // grey-900
75
+ marginBottom: "4px",
76
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
77
+ };
78
+ var helperTextStyles = {
79
+ fontSize: "13px",
80
+ margin: "0",
81
+ marginTop: "2px",
82
+ color: "#595959",
83
+ // grey-600
84
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
85
+ lineHeight: "1.4"
86
+ };
87
+ var errorTextStyles = {
88
+ ...helperTextStyles,
89
+ color: "#a62323",
90
+ // destructive-600 (accessible)
91
+ display: "flex",
92
+ alignItems: "center",
93
+ gap: "4px"
94
+ };
95
+ var Input = React.forwardRef(
96
+ ({
97
+ size = "medium",
98
+ state = "default",
99
+ label,
100
+ error,
101
+ helperText,
102
+ className,
103
+ style,
104
+ disabled,
105
+ ...props
106
+ }, ref) => {
107
+ const inputId = React.useId();
108
+ const helperTextId = React.useId();
109
+ const errorId = React.useId();
110
+ const [isFocused, setIsFocused] = React.useState(false);
111
+ const sizeStyles = inputStyles.sizes[size];
112
+ const stateStyles = inputStyles.states[error ? "error" : state];
113
+ const inputStyle = {
114
+ ...inputStyles.base,
115
+ ...sizeStyles,
116
+ ...stateStyles,
117
+ ...isFocused && !disabled && stateStyles[":focus"],
118
+ ...disabled && inputStyles.states.default[":disabled"]
119
+ };
120
+ return /* @__PURE__ */ jsxs("div", { className: clsx("arbor-input-wrapper", className), style, children: [
121
+ label && /* @__PURE__ */ jsx("label", { htmlFor: inputId, style: labelStyles, children: label }),
122
+ /* @__PURE__ */ jsx(
123
+ "input",
124
+ {
125
+ ref,
126
+ id: inputId,
127
+ className: "arbor-input",
128
+ style: inputStyle,
129
+ disabled,
130
+ "aria-invalid": error ? "true" : "false",
131
+ "aria-describedby": error ? errorId : helperText ? helperTextId : void 0,
132
+ onFocus: (e) => {
133
+ setIsFocused(true);
134
+ props.onFocus?.(e);
135
+ },
136
+ onBlur: (e) => {
137
+ setIsFocused(false);
138
+ props.onBlur?.(e);
139
+ },
140
+ ...props
141
+ }
142
+ ),
143
+ error && /* @__PURE__ */ jsx("p", { id: errorId, style: errorTextStyles, role: "alert", children: error }),
144
+ !error && helperText && /* @__PURE__ */ jsx("p", { id: helperTextId, style: helperTextStyles, children: helperText })
145
+ ] });
146
+ }
147
+ );
148
+ Input.displayName = "Input";
149
+
150
+ export {
151
+ Input
152
+ };
153
+ //# sourceMappingURL=chunk-NOHUMPXV.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Input/Input.tsx"],"sourcesContent":["import * as React from 'react';\nimport { clsx } from 'clsx';\n\nexport type InputSize = 'small' | 'medium';\nexport type ValidationState = 'default' | 'error' | 'success';\n\nexport interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'> {\n /**\n * The size of the input\n * @default 'medium'\n */\n size?: InputSize;\n /**\n * The validation state of the input\n * @default 'default'\n */\n state?: ValidationState;\n /**\n * Optional label for the input\n */\n label?: string;\n /**\n * Optional error message to display\n */\n error?: string;\n /**\n * Optional helper text to display\n */\n helperText?: string;\n}\n\n// Arbor Design System input styles\nconst inputStyles = {\n base: {\n width: '100%',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n backgroundColor: '#ffffff',\n borderRadius: '8px',\n transition: 'all 0.2s ease-in-out',\n outline: 'none',\n margin: '0',\n display: 'block',\n },\n sizes: {\n small: {\n height: '32px',\n fontSize: '13px',\n padding: '8px',\n },\n medium: {\n height: '36px',\n fontSize: '13px',\n padding: '8px',\n },\n },\n states: {\n default: {\n border: '1px solid #d1d1d1', // grey-300\n color: '#2f2f2f', // grey-900\n ':focus': {\n borderColor: '#3cad51', // brand-500\n outline: '3px solid rgba(60, 173, 81, 0.2)',\n },\n ':disabled': {\n backgroundColor: '#f8f8f8', // grey-050\n borderColor: '#efefef', // grey-100\n color: '#7e7e7e', // grey-500\n cursor: 'not-allowed',\n },\n },\n error: {\n border: '1px solid #c93232', // destructive-500\n color: '#2f2f2f',\n ':focus': {\n borderColor: '#c93232',\n outline: '3px solid rgba(201, 50, 50, 0.2)',\n },\n },\n success: {\n border: '1px solid #16a33d', // success-500\n color: '#2f2f2f',\n ':focus': {\n borderColor: '#16a33d',\n outline: '3px solid rgba(22, 163, 61, 0.2)',\n },\n },\n },\n};\n\nconst labelStyles: React.CSSProperties = {\n display: 'block',\n fontSize: '13px',\n fontWeight: '600',\n color: '#2f2f2f', // grey-900\n marginBottom: '4px',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n};\n\nconst helperTextStyles: React.CSSProperties = {\n fontSize: '13px',\n margin: '0',\n marginTop: '2px',\n color: '#595959', // grey-600\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n lineHeight: '1.4',\n};\n\nconst errorTextStyles: React.CSSProperties = {\n ...helperTextStyles,\n color: '#a62323', // destructive-600 (accessible)\n display: 'flex',\n alignItems: 'center',\n gap: '4px',\n};\n\n/**\n * Input component - Arbor Design System\n *\n * A text input component following Arbor's design specifications.\n * Supports labels, validation states (error/success), and helper text.\n * Uses 8px border radius and Inter font family.\n *\n * @example\n * ```tsx\n * <Input\n * label=\"Email\"\n * type=\"email\"\n * placeholder=\"you@example.com\"\n * helperText=\"We'll never share your email\"\n * />\n * ```\n */\nexport const Input = React.forwardRef<HTMLInputElement, InputProps>(\n (\n {\n size = 'medium',\n state = 'default',\n label,\n error,\n helperText,\n className,\n style,\n disabled,\n ...props\n },\n ref\n ) => {\n const inputId = React.useId();\n const helperTextId = React.useId();\n const errorId = React.useId();\n const [isFocused, setIsFocused] = React.useState(false);\n\n const sizeStyles = inputStyles.sizes[size];\n const stateStyles = inputStyles.states[error ? 'error' : state];\n\n const inputStyle: React.CSSProperties = {\n ...inputStyles.base,\n ...sizeStyles,\n ...stateStyles,\n ...(isFocused && !disabled && stateStyles[':focus']),\n ...(disabled && inputStyles.states.default[':disabled']),\n };\n\n return (\n <div className={clsx('arbor-input-wrapper', className)} style={style}>\n {label && (\n <label htmlFor={inputId} style={labelStyles}>\n {label}\n </label>\n )}\n <input\n ref={ref}\n id={inputId}\n className=\"arbor-input\"\n style={inputStyle}\n disabled={disabled}\n aria-invalid={error ? 'true' : 'false'}\n aria-describedby={\n error ? errorId : helperText ? helperTextId : undefined\n }\n onFocus={(e) => {\n setIsFocused(true);\n props.onFocus?.(e);\n }}\n onBlur={(e) => {\n setIsFocused(false);\n props.onBlur?.(e);\n }}\n {...props}\n />\n {error && (\n <p id={errorId} style={errorTextStyles} role=\"alert\">\n {error}\n </p>\n )}\n {!error && helperText && (\n <p id={helperTextId} style={helperTextStyles}>\n {helperText}\n </p>\n )}\n </div>\n );\n }\n);\n\nInput.displayName = 'Input';\n"],"mappings":"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","names":[]}
@@ -0,0 +1,77 @@
1
+ // src/Tag/Tag.tsx
2
+ import * as React from "react";
3
+ import { clsx } from "clsx";
4
+ import { jsx } from "react/jsx-runtime";
5
+ var tagStyles = {
6
+ base: {
7
+ display: "inline-flex",
8
+ alignItems: "center",
9
+ padding: "4px 8px",
10
+ borderRadius: "99px",
11
+ // Pill shape
12
+ fontSize: "11px",
13
+ // Type 1
14
+ fontWeight: "600",
15
+ gap: "4px",
16
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
17
+ lineHeight: "1.2"
18
+ },
19
+ variants: {
20
+ default: {
21
+ backgroundColor: "#fff4e5",
22
+ // caution-100
23
+ color: "#975a00"
24
+ // caution-700
25
+ },
26
+ success: {
27
+ backgroundColor: "#e5f9eb",
28
+ // success-100
29
+ color: "#005a19"
30
+ // success-800
31
+ },
32
+ error: {
33
+ backgroundColor: "#ffeaea",
34
+ // destructive-100
35
+ color: "#a62323"
36
+ // destructive-600
37
+ },
38
+ info: {
39
+ backgroundColor: "#e5f4ff",
40
+ // info-100
41
+ color: "#003d80"
42
+ // info-800
43
+ },
44
+ neutral: {
45
+ backgroundColor: "#f8f8f8",
46
+ // grey-050
47
+ color: "#595959"
48
+ // grey-600
49
+ }
50
+ }
51
+ };
52
+ var Tag = React.forwardRef(
53
+ ({ variant = "default", className, style, children, ...props }, ref) => {
54
+ const variantStyles = tagStyles.variants[variant];
55
+ const combinedStyle = {
56
+ ...tagStyles.base,
57
+ ...variantStyles,
58
+ ...style
59
+ };
60
+ return /* @__PURE__ */ jsx(
61
+ "span",
62
+ {
63
+ ref,
64
+ className: clsx("arbor-tag", `arbor-tag--${variant}`, className),
65
+ style: combinedStyle,
66
+ ...props,
67
+ children
68
+ }
69
+ );
70
+ }
71
+ );
72
+ Tag.displayName = "Tag";
73
+
74
+ export {
75
+ Tag
76
+ };
77
+ //# sourceMappingURL=chunk-QCRIECT7.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Tag/Tag.tsx"],"sourcesContent":["import * as React from 'react';\nimport { clsx } from 'clsx';\n\nexport type TagVariant = 'default' | 'success' | 'error' | 'info' | 'neutral';\n\nexport interface TagProps extends React.HTMLAttributes<HTMLSpanElement> {\n /**\n * The visual style variant of the tag\n * @default 'default'\n */\n variant?: TagVariant;\n /**\n * The content of the tag\n */\n children: React.ReactNode;\n}\n\n// Arbor Design System tag styles\nconst tagStyles = {\n base: {\n display: 'inline-flex',\n alignItems: 'center',\n padding: '4px 8px',\n borderRadius: '99px', // Pill shape\n fontSize: '11px', // Type 1\n fontWeight: '600',\n gap: '4px',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n lineHeight: '1.2',\n },\n variants: {\n default: {\n backgroundColor: '#fff4e5', // caution-100\n color: '#975a00', // caution-700\n },\n success: {\n backgroundColor: '#e5f9eb', // success-100\n color: '#005a19', // success-800\n },\n error: {\n backgroundColor: '#ffeaea', // destructive-100\n color: '#a62323', // destructive-600\n },\n info: {\n backgroundColor: '#e5f4ff', // info-100\n color: '#003d80', // info-800\n },\n neutral: {\n backgroundColor: '#f8f8f8', // grey-050\n color: '#595959', // grey-600\n },\n },\n};\n\n/**\n * Tag component - Arbor Design System\n *\n * A label component for categorization and status indication.\n * Uses pill shape (99px radius) with semantic color variants.\n *\n * @example\n * ```tsx\n * <Tag variant=\"success\">Active</Tag>\n * <Tag variant=\"error\">Overdue</Tag>\n * <Tag variant=\"info\">New</Tag>\n * ```\n */\nexport const Tag = React.forwardRef<HTMLSpanElement, TagProps>(\n ({ variant = 'default', className, style, children, ...props }, ref) => {\n const variantStyles = tagStyles.variants[variant];\n\n const combinedStyle: React.CSSProperties = {\n ...tagStyles.base,\n ...variantStyles,\n ...style,\n };\n\n return (\n <span\n ref={ref}\n className={clsx('arbor-tag', `arbor-tag--${variant}`, className)}\n style={combinedStyle}\n {...props}\n >\n {children}\n </span>\n );\n }\n);\n\nTag.displayName = 'Tag';\n"],"mappings":";AAAA,YAAY,WAAW;AACvB,SAAS,YAAY;AA6Ef;AA5DN,IAAM,YAAY;AAAA,EAChB,MAAM;AAAA,IACJ,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,cAAc;AAAA;AAAA,IACd,UAAU;AAAA;AAAA,IACV,YAAY;AAAA,IACZ,KAAK;AAAA,IACL,YAAY;AAAA,IACZ,YAAY;AAAA,EACd;AAAA,EACA,UAAU;AAAA,IACR,SAAS;AAAA,MACP,iBAAiB;AAAA;AAAA,MACjB,OAAO;AAAA;AAAA,IACT;AAAA,IACA,SAAS;AAAA,MACP,iBAAiB;AAAA;AAAA,MACjB,OAAO;AAAA;AAAA,IACT;AAAA,IACA,OAAO;AAAA,MACL,iBAAiB;AAAA;AAAA,MACjB,OAAO;AAAA;AAAA,IACT;AAAA,IACA,MAAM;AAAA,MACJ,iBAAiB;AAAA;AAAA,MACjB,OAAO;AAAA;AAAA,IACT;AAAA,IACA,SAAS;AAAA,MACP,iBAAiB;AAAA;AAAA,MACjB,OAAO;AAAA;AAAA,IACT;AAAA,EACF;AACF;AAeO,IAAM,MAAY;AAAA,EACvB,CAAC,EAAE,UAAU,WAAW,WAAW,OAAO,UAAU,GAAG,MAAM,GAAG,QAAQ;AACtE,UAAM,gBAAgB,UAAU,SAAS,OAAO;AAEhD,UAAM,gBAAqC;AAAA,MACzC,GAAG,UAAU;AAAA,MACb,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,KAAK,aAAa,cAAc,OAAO,IAAI,SAAS;AAAA,QAC/D,OAAO;AAAA,QACN,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,IAAI,cAAc;","names":[]}
@@ -0,0 +1,56 @@
1
+ // src/Card/Card.tsx
2
+ import * as React from "react";
3
+ import { clsx } from "clsx";
4
+ import { jsx } from "react/jsx-runtime";
5
+ var cardStyles = {
6
+ base: {
7
+ backgroundColor: "#ffffff",
8
+ borderRadius: "8px",
9
+ border: "1px solid #efefef",
10
+ // grey-100 - subtle border
11
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif"
12
+ },
13
+ padding: {
14
+ none: {
15
+ padding: "0"
16
+ },
17
+ small: {
18
+ padding: "8px"
19
+ // small spacing
20
+ },
21
+ medium: {
22
+ padding: "16px"
23
+ // large spacing
24
+ },
25
+ large: {
26
+ padding: "24px"
27
+ // xlarge spacing
28
+ }
29
+ }
30
+ };
31
+ var Card = React.forwardRef(
32
+ ({ padding = "large", className, style, children, ...props }, ref) => {
33
+ const paddingStyles = cardStyles.padding[padding];
34
+ const combinedStyle = {
35
+ ...cardStyles.base,
36
+ ...paddingStyles,
37
+ ...style
38
+ };
39
+ return /* @__PURE__ */ jsx(
40
+ "div",
41
+ {
42
+ ref,
43
+ className: clsx("arbor-card", className),
44
+ style: combinedStyle,
45
+ ...props,
46
+ children
47
+ }
48
+ );
49
+ }
50
+ );
51
+ Card.displayName = "Card";
52
+
53
+ export {
54
+ Card
55
+ };
56
+ //# sourceMappingURL=chunk-ZFKW3P6P.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/Card/Card.tsx"],"sourcesContent":["import * as React from 'react';\nimport { clsx } from 'clsx';\n\ntype PaddingVariant = 'none' | 'small' | 'medium' | 'large';\n\nexport interface CardProps extends React.HTMLAttributes<HTMLDivElement> {\n /**\n * The padding variant of the card\n * @default 'large'\n */\n padding?: PaddingVariant;\n /**\n * The content of the card\n */\n children: React.ReactNode;\n}\n\n// Arbor Design System card styles\nconst cardStyles = {\n base: {\n backgroundColor: '#ffffff',\n borderRadius: '8px',\n border: '1px solid #efefef', // grey-100 - subtle border\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n },\n padding: {\n none: {\n padding: '0',\n },\n small: {\n padding: '8px', // small spacing\n },\n medium: {\n padding: '16px', // large spacing\n },\n large: {\n padding: '24px', // xlarge spacing\n },\n },\n};\n\n/**\n * Card component - Arbor Design System\n *\n * A container component that provides consistent styling for content cards.\n * Uses subtle borders rather than shadows, following Arbor's minimal design approach.\n *\n * @example\n * ```tsx\n * <Card padding=\"large\">\n * <h2>Card Title</h2>\n * <p>Card content goes here</p>\n * </Card>\n * ```\n */\nexport const Card = React.forwardRef<HTMLDivElement, CardProps>(\n ({ padding = 'large', className, style, children, ...props }, ref) => {\n const paddingStyles = cardStyles.padding[padding];\n\n const combinedStyle: React.CSSProperties = {\n ...cardStyles.base,\n ...paddingStyles,\n ...style,\n };\n\n return (\n <div\n ref={ref}\n className={clsx('arbor-card', className)}\n style={combinedStyle}\n {...props}\n >\n {children}\n </div>\n );\n }\n);\n\nCard.displayName = 'Card';\n"],"mappings":";AAAA,YAAY,WAAW;AACvB,SAAS,YAAY;AAiEf;AAhDN,IAAM,aAAa;AAAA,EACjB,MAAM;AAAA,IACJ,iBAAiB;AAAA,IACjB,cAAc;AAAA,IACd,QAAQ;AAAA;AAAA,IACR,YAAY;AAAA,EACd;AAAA,EACA,SAAS;AAAA,IACP,MAAM;AAAA,MACJ,SAAS;AAAA,IACX;AAAA,IACA,OAAO;AAAA,MACL,SAAS;AAAA;AAAA,IACX;AAAA,IACA,QAAQ;AAAA,MACN,SAAS;AAAA;AAAA,IACX;AAAA,IACA,OAAO;AAAA,MACL,SAAS;AAAA;AAAA,IACX;AAAA,EACF;AACF;AAgBO,IAAM,OAAa;AAAA,EACxB,CAAC,EAAE,UAAU,SAAS,WAAW,OAAO,UAAU,GAAG,MAAM,GAAG,QAAQ;AACpE,UAAM,gBAAgB,WAAW,QAAQ,OAAO;AAEhD,UAAM,gBAAqC;AAAA,MACzC,GAAG,WAAW;AAAA,MACd,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,WAAW,KAAK,cAAc,SAAS;AAAA,QACvC,OAAO;AAAA,QACN,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,KAAK,cAAc;","names":[]}
@@ -0,0 +1,17 @@
1
+ export { Button, ButtonProps } from './Button.mjs';
2
+ export { Card, CardProps } from './Card.mjs';
3
+ export { Input, InputProps } from './Input.mjs';
4
+ export { Tag, TagProps } from './Tag.mjs';
5
+ import 'react';
6
+
7
+ /**
8
+ * Shared TypeScript types for Arbor Design System components
9
+ */
10
+ type ButtonVariant = 'primary' | 'secondary' | 'destructive' | 'ghost';
11
+ type ButtonSize = 'small' | 'medium';
12
+ type InputSize = 'small' | 'medium';
13
+ type ValidationState = 'default' | 'error' | 'success';
14
+ type CardPadding = 'none' | 'small' | 'medium' | 'large';
15
+ type TagVariant = 'default' | 'success' | 'error' | 'info' | 'neutral';
16
+
17
+ export type { ButtonSize, ButtonVariant, CardPadding, InputSize, TagVariant, ValidationState };
@@ -0,0 +1,17 @@
1
+ export { Button, ButtonProps } from './Button.js';
2
+ export { Card, CardProps } from './Card.js';
3
+ export { Input, InputProps } from './Input.js';
4
+ export { Tag, TagProps } from './Tag.js';
5
+ import 'react';
6
+
7
+ /**
8
+ * Shared TypeScript types for Arbor Design System components
9
+ */
10
+ type ButtonVariant = 'primary' | 'secondary' | 'destructive' | 'ghost';
11
+ type ButtonSize = 'small' | 'medium';
12
+ type InputSize = 'small' | 'medium';
13
+ type ValidationState = 'default' | 'error' | 'success';
14
+ type CardPadding = 'none' | 'small' | 'medium' | 'large';
15
+ type TagVariant = 'default' | 'success' | 'error' | 'info' | 'neutral';
16
+
17
+ export type { ButtonSize, ButtonVariant, CardPadding, InputSize, TagVariant, ValidationState };