@tonyarbor/components 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,173 @@
1
+ // src/SearchGlobal/SearchGlobal.tsx
2
+ import * as React from "react";
3
+ import { Search, X } from "lucide-react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ var SearchGlobal = React.forwardRef(
6
+ ({
7
+ value = "",
8
+ onChange,
9
+ onSubmit,
10
+ onClear,
11
+ placeholder = "Search",
12
+ className,
13
+ style,
14
+ "data-testid": dataTestId
15
+ }, ref) => {
16
+ const [isFocused, setIsFocused] = React.useState(false);
17
+ const [isHovered, setIsHovered] = React.useState(false);
18
+ const inputRef = React.useRef(null);
19
+ React.useImperativeHandle(ref, () => inputRef.current);
20
+ const handleFocus = () => {
21
+ setIsFocused(true);
22
+ };
23
+ const handleBlur = () => {
24
+ setIsFocused(false);
25
+ };
26
+ const handleChange = (e) => {
27
+ onChange?.(e.target.value);
28
+ };
29
+ const handleKeyDown = (e) => {
30
+ if (e.key === "Enter") {
31
+ onSubmit?.(value);
32
+ }
33
+ };
34
+ const handleClear = () => {
35
+ onChange?.("");
36
+ onClear?.();
37
+ inputRef.current?.focus();
38
+ };
39
+ const containerStyles = {
40
+ position: "relative",
41
+ width: isFocused ? "300px" : "160px",
42
+ height: "32px",
43
+ backgroundColor: isFocused ? "#ffffff" : isHovered ? "#efefef" : "#f8f8f8",
44
+ borderRadius: "16px",
45
+ padding: "8px 16px",
46
+ display: "flex",
47
+ alignItems: "center",
48
+ gap: isFocused ? "8px" : "8px",
49
+ cursor: "text",
50
+ transition: "all 0.2s ease-in-out",
51
+ boxSizing: "border-box",
52
+ border: isFocused ? "1px solid #efefef" : "none",
53
+ boxShadow: isFocused ? "0px 0px 0px 3px #3cad51" : "none",
54
+ marginLeft: isFocused ? "-140px" : "0",
55
+ // Expand to the left
56
+ ...style
57
+ };
58
+ const iconContainerStyles = {
59
+ display: "flex",
60
+ alignItems: "center",
61
+ justifyContent: "center",
62
+ flexShrink: 0,
63
+ padding: "2px"
64
+ };
65
+ const inputStyles = {
66
+ border: "none",
67
+ outline: "none",
68
+ backgroundColor: "transparent",
69
+ fontFamily: "'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
70
+ fontSize: "13px",
71
+ fontWeight: 400,
72
+ color: "#2f2f2f",
73
+ lineHeight: "1.5",
74
+ flex: 1,
75
+ width: "100%",
76
+ minWidth: 0
77
+ };
78
+ const keyboardShortcutStyles = {
79
+ display: "flex",
80
+ alignItems: "center",
81
+ gap: "0px",
82
+ flexShrink: 0
83
+ };
84
+ const keyStyles = {
85
+ border: "1px solid #2f2f2f",
86
+ borderRadius: "5px",
87
+ padding: "0px 3px",
88
+ height: "16px",
89
+ display: "flex",
90
+ alignItems: "center",
91
+ justifyContent: "center",
92
+ fontFamily: "'Work Sans', sans-serif",
93
+ fontSize: "8px",
94
+ fontWeight: 400,
95
+ color: "#2f2f2f",
96
+ letterSpacing: "-0.08px",
97
+ lineHeight: "1.5",
98
+ minWidth: "16px"
99
+ };
100
+ const plusStyles = {
101
+ fontFamily: "'Work Sans', sans-serif",
102
+ fontSize: "8px",
103
+ fontWeight: 400,
104
+ color: "#2f2f2f",
105
+ letterSpacing: "-0.08px",
106
+ lineHeight: "1.5",
107
+ padding: "0 2px"
108
+ };
109
+ const clearButtonStyles = {
110
+ display: "flex",
111
+ alignItems: "center",
112
+ justifyContent: "center",
113
+ flexShrink: 0,
114
+ width: "16px",
115
+ height: "16px",
116
+ cursor: "pointer",
117
+ border: "none",
118
+ background: "none",
119
+ padding: 0
120
+ };
121
+ const showKeyboardShortcut = isHovered && !isFocused;
122
+ const showClearButton = isFocused;
123
+ return /* @__PURE__ */ jsxs(
124
+ "div",
125
+ {
126
+ className,
127
+ style: containerStyles,
128
+ onMouseEnter: () => setIsHovered(true),
129
+ onMouseLeave: () => setIsHovered(false),
130
+ onClick: () => inputRef.current?.focus(),
131
+ "data-testid": dataTestId,
132
+ children: [
133
+ /* @__PURE__ */ jsx("div", { style: iconContainerStyles, children: /* @__PURE__ */ jsx(Search, { size: 12, color: "#2f2f2f", strokeWidth: 2 }) }),
134
+ /* @__PURE__ */ jsx(
135
+ "input",
136
+ {
137
+ ref: inputRef,
138
+ type: "text",
139
+ value,
140
+ onChange: handleChange,
141
+ onFocus: handleFocus,
142
+ onBlur: handleBlur,
143
+ onKeyDown: handleKeyDown,
144
+ placeholder: isFocused ? "" : placeholder,
145
+ style: inputStyles
146
+ }
147
+ ),
148
+ showKeyboardShortcut && /* @__PURE__ */ jsxs("div", { style: keyboardShortcutStyles, children: [
149
+ /* @__PURE__ */ jsx("div", { style: keyStyles, children: "\u2318" }),
150
+ /* @__PURE__ */ jsx("span", { style: plusStyles, children: "+" }),
151
+ /* @__PURE__ */ jsx("div", { style: keyStyles, children: "K" })
152
+ ] }),
153
+ showClearButton && /* @__PURE__ */ jsx(
154
+ "button",
155
+ {
156
+ type: "button",
157
+ onClick: handleClear,
158
+ style: clearButtonStyles,
159
+ "aria-label": "Clear search",
160
+ children: /* @__PURE__ */ jsx(X, { size: 13.333, color: "#2f2f2f", strokeWidth: 2 })
161
+ }
162
+ )
163
+ ]
164
+ }
165
+ );
166
+ }
167
+ );
168
+ SearchGlobal.displayName = "SearchGlobal";
169
+
170
+ export {
171
+ SearchGlobal
172
+ };
173
+ //# sourceMappingURL=chunk-UPBHDBAK.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/SearchGlobal/SearchGlobal.tsx"],"sourcesContent":["import * as React from 'react';\nimport { Search, X } from 'lucide-react';\n\nexport interface SearchGlobalProps {\n /**\n * Value of the search input\n */\n value?: string;\n /**\n * Callback when value changes\n */\n onChange?: (value: string) => void;\n /**\n * Callback when search is submitted\n */\n onSubmit?: (value: string) => void;\n /**\n * Callback when clear button is clicked\n */\n onClear?: () => void;\n /**\n * Placeholder text\n */\n placeholder?: string;\n /**\n * Custom className\n */\n className?: string;\n /**\n * Custom style\n */\n style?: React.CSSProperties;\n /**\n * Test ID for testing\n */\n 'data-testid'?: string;\n}\n\n/**\n * SearchGlobal component - Arbor Design System\n *\n * A search input that expands from 160px to 300px when focused.\n * Shows keyboard shortcut (⌘ K) on hover and X button when focused.\n */\nexport const SearchGlobal = React.forwardRef<HTMLInputElement, SearchGlobalProps>(\n (\n {\n value = '',\n onChange,\n onSubmit,\n onClear,\n placeholder = 'Search',\n className,\n style,\n 'data-testid': dataTestId,\n },\n ref\n ) => {\n const [isFocused, setIsFocused] = React.useState(false);\n const [isHovered, setIsHovered] = React.useState(false);\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n // Merge refs\n React.useImperativeHandle(ref, () => inputRef.current as HTMLInputElement);\n\n const handleFocus = () => {\n setIsFocused(true);\n };\n\n const handleBlur = () => {\n setIsFocused(false);\n };\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange?.(e.target.value);\n };\n\n const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n onSubmit?.(value);\n }\n };\n\n const handleClear = () => {\n onChange?.('');\n onClear?.();\n inputRef.current?.focus();\n };\n\n const containerStyles: React.CSSProperties = {\n position: 'relative',\n width: isFocused ? '300px' : '160px',\n height: '32px',\n backgroundColor: isFocused ? '#ffffff' : isHovered ? '#efefef' : '#f8f8f8',\n borderRadius: '16px',\n padding: '8px 16px',\n display: 'flex',\n alignItems: 'center',\n gap: isFocused ? '8px' : '8px',\n cursor: 'text',\n transition: 'all 0.2s ease-in-out',\n boxSizing: 'border-box',\n border: isFocused ? '1px solid #efefef' : 'none',\n boxShadow: isFocused ? '0px 0px 0px 3px #3cad51' : 'none',\n marginLeft: isFocused ? '-140px' : '0', // Expand to the left\n ...style,\n };\n\n const iconContainerStyles: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n padding: '2px',\n };\n\n const inputStyles: React.CSSProperties = {\n border: 'none',\n outline: 'none',\n backgroundColor: 'transparent',\n fontFamily: \"'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif\",\n fontSize: '13px',\n fontWeight: 400,\n color: '#2f2f2f',\n lineHeight: '1.5',\n flex: 1,\n width: '100%',\n minWidth: 0,\n };\n\n const keyboardShortcutStyles: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: '0px',\n flexShrink: 0,\n };\n\n const keyStyles: React.CSSProperties = {\n border: '1px solid #2f2f2f',\n borderRadius: '5px',\n padding: '0px 3px',\n height: '16px',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontFamily: \"'Work Sans', sans-serif\",\n fontSize: '8px',\n fontWeight: 400,\n color: '#2f2f2f',\n letterSpacing: '-0.08px',\n lineHeight: '1.5',\n minWidth: '16px',\n };\n\n const plusStyles: React.CSSProperties = {\n fontFamily: \"'Work Sans', sans-serif\",\n fontSize: '8px',\n fontWeight: 400,\n color: '#2f2f2f',\n letterSpacing: '-0.08px',\n lineHeight: '1.5',\n padding: '0 2px',\n };\n\n const clearButtonStyles: React.CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n flexShrink: 0,\n width: '16px',\n height: '16px',\n cursor: 'pointer',\n border: 'none',\n background: 'none',\n padding: 0,\n };\n\n const showKeyboardShortcut = isHovered && !isFocused;\n const showClearButton = isFocused;\n\n return (\n <div\n className={className}\n style={containerStyles}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() => inputRef.current?.focus()}\n data-testid={dataTestId}\n >\n <div style={iconContainerStyles}>\n <Search size={12} color=\"#2f2f2f\" strokeWidth={2} />\n </div>\n\n <input\n ref={inputRef}\n type=\"text\"\n value={value}\n onChange={handleChange}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n placeholder={isFocused ? '' : placeholder}\n style={inputStyles}\n />\n\n {showKeyboardShortcut && (\n <div style={keyboardShortcutStyles}>\n <div style={keyStyles}>⌘</div>\n <span style={plusStyles}>+</span>\n <div style={keyStyles}>K</div>\n </div>\n )}\n\n {showClearButton && (\n <button\n type=\"button\"\n onClick={handleClear}\n style={clearButtonStyles}\n aria-label=\"Clear search\"\n >\n <X size={13.333} color=\"#2f2f2f\" strokeWidth={2} />\n </button>\n )}\n </div>\n );\n }\n);\n\nSearchGlobal.displayName = 'SearchGlobal';\n"],"mappings":"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","names":[]}
package/dist/index.d.mts CHANGED
@@ -17,6 +17,10 @@ export { Pagination, PaginationProps } from './Pagination.mjs';
17
17
  export { TableFooterPagination, TableFooterPaginationProps } from './TableFooterPagination.mjs';
18
18
  export { TableControls, TableControlsProps } from './TableControls.mjs';
19
19
  export { Table, TableColumn, TableProps, TableRow } from './Table.mjs';
20
+ export { Avatar, AvatarProps, AvatarSize } from './Avatar.mjs';
21
+ export { SearchGlobal, SearchGlobalProps } from './SearchGlobal.mjs';
22
+ export { SearchOnPage, SearchOnPageProps } from './SearchOnPage.mjs';
23
+ export { BreadcrumbItem, Breadcrumbs, BreadcrumbsProps } from './Breadcrumbs.mjs';
20
24
  import 'react';
21
25
 
22
26
  /**
package/dist/index.d.ts CHANGED
@@ -17,6 +17,10 @@ export { Pagination, PaginationProps } from './Pagination.js';
17
17
  export { TableFooterPagination, TableFooterPaginationProps } from './TableFooterPagination.js';
18
18
  export { TableControls, TableControlsProps } from './TableControls.js';
19
19
  export { Table, TableColumn, TableProps, TableRow } from './Table.js';
20
+ export { Avatar, AvatarProps, AvatarSize } from './Avatar.js';
21
+ export { SearchGlobal, SearchGlobalProps } from './SearchGlobal.js';
22
+ export { SearchOnPage, SearchOnPageProps } from './SearchOnPage.js';
23
+ export { BreadcrumbItem, Breadcrumbs, BreadcrumbsProps } from './Breadcrumbs.js';
20
24
  import 'react';
21
25
 
22
26
  /**