chordia-ui 3.2.3 → 3.2.5
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/IntegrationCard.cjs.js +2 -0
- package/dist/IntegrationCard.cjs.js.map +1 -0
- package/dist/IntegrationCard.es.js +188 -0
- package/dist/IntegrationCard.es.js.map +1 -0
- package/dist/SideDrawer.cjs.js +2 -0
- package/dist/SideDrawer.cjs.js.map +1 -0
- package/dist/SideDrawer.es.js +486 -0
- package/dist/SideDrawer.es.js.map +1 -0
- package/dist/UploadInteraction.cjs.js +2 -0
- package/dist/UploadInteraction.cjs.js.map +1 -0
- package/dist/UploadInteraction.es.js +379 -0
- package/dist/UploadInteraction.es.js.map +1 -0
- package/dist/components/common.cjs.js +1 -1
- package/dist/components/common.es.js +13 -11
- package/dist/components/layout.cjs.js +2 -2
- package/dist/components/layout.cjs.js.map +1 -1
- package/dist/components/layout.es.js +202 -411
- package/dist/components/layout.es.js.map +1 -1
- package/dist/components/navigation.cjs.js +1 -1
- package/dist/components/navigation.cjs.js.map +1 -1
- package/dist/components/navigation.es.js +212 -203
- package/dist/components/navigation.es.js.map +1 -1
- package/dist/components/onboarding.cjs.js +2 -0
- package/dist/components/onboarding.cjs.js.map +1 -0
- package/dist/components/onboarding.es.js +712 -0
- package/dist/components/onboarding.es.js.map +1 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs2.js +1 -1
- package/dist/index.cjs2.js.map +1 -1
- package/dist/index.es.js +74 -64
- package/dist/index.es.js.map +1 -1
- package/dist/index.es2.js +2 -2
- package/dist/index.es2.js.map +1 -1
- package/dist/pages/interactionDetails.cjs.js +1 -1
- package/dist/pages/interactionDetails.cjs.js.map +1 -1
- package/dist/pages/interactionDetails.es.js +16 -15
- package/dist/pages/interactionDetails.es.js.map +1 -1
- package/package.json +5 -1
- package/src/components/common/SideDrawer.jsx +321 -0
- package/src/components/common/index.js +1 -0
- package/src/components/index.js +4 -1
- package/src/components/layout/IntegrationCard.jsx +151 -141
- package/src/components/login/LoginPage.jsx +2 -2
- package/src/components/navigation/Sidebar.jsx +59 -39
- package/src/components/onboarding/AddTeammates.jsx +278 -0
- package/src/components/onboarding/GettingStarted.jsx +4 -0
- package/src/components/onboarding/UploadInteraction.jsx +3 -3
- package/src/components/onboarding/index.js +5 -0
- package/dist/AutoSearch.cjs.js +0 -2
- package/dist/AutoSearch.cjs.js.map +0 -1
- package/dist/AutoSearch.es.js +0 -190
- package/dist/AutoSearch.es.js.map +0 -1
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
import { Search } from 'lucide-react';
|
|
3
|
+
|
|
4
|
+
const FF = 'var(--font-sans)';
|
|
5
|
+
|
|
6
|
+
// ─── Styles ───
|
|
7
|
+
|
|
8
|
+
const containerStyle = {
|
|
9
|
+
fontFamily: FF,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const sectionTitleStyle = {
|
|
13
|
+
fontSize: 20,
|
|
14
|
+
fontWeight: 600,
|
|
15
|
+
fontStyle: 'normal',
|
|
16
|
+
fontFamily: FF,
|
|
17
|
+
color: 'var(--grey-strong)',
|
|
18
|
+
margin: 0,
|
|
19
|
+
lineHeight: 'normal',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const sectionSubtitleStyle = {
|
|
23
|
+
fontSize: 13,
|
|
24
|
+
fontWeight: 400,
|
|
25
|
+
fontStyle: 'normal',
|
|
26
|
+
color: 'var(--color-text-secondary)',
|
|
27
|
+
fontFamily: FF,
|
|
28
|
+
margin: '4px 0 0',
|
|
29
|
+
lineHeight: '140%',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const searchRowStyle = {
|
|
33
|
+
display: 'flex',
|
|
34
|
+
alignItems: 'center',
|
|
35
|
+
gap: 12,
|
|
36
|
+
marginTop: 24,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const searchInputWrapStyle = {
|
|
40
|
+
display: 'flex',
|
|
41
|
+
alignItems: 'center',
|
|
42
|
+
flex: 1,
|
|
43
|
+
height: 44,
|
|
44
|
+
padding: '0 14px',
|
|
45
|
+
borderRadius: 10,
|
|
46
|
+
border: '1px solid var(--color-input-border)',
|
|
47
|
+
background: 'var(--grey-white)',
|
|
48
|
+
boxSizing: 'border-box',
|
|
49
|
+
gap: 8,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const searchIconStyle = {
|
|
53
|
+
flexShrink: 0,
|
|
54
|
+
color: 'var(--color-text-secondary)',
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const emailTagStyle = {
|
|
58
|
+
display: 'inline-flex',
|
|
59
|
+
alignItems: 'center',
|
|
60
|
+
gap: 4,
|
|
61
|
+
padding: '4px 10px',
|
|
62
|
+
borderRadius: 6,
|
|
63
|
+
background: 'var(--hover-warm)',
|
|
64
|
+
fontSize: 14,
|
|
65
|
+
fontWeight: 500,
|
|
66
|
+
fontFamily: FF,
|
|
67
|
+
color: 'var(--grey-strong)',
|
|
68
|
+
whiteSpace: 'nowrap',
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const emailTagRemoveStyle = {
|
|
72
|
+
cursor: 'pointer',
|
|
73
|
+
fontSize: 16,
|
|
74
|
+
lineHeight: 1,
|
|
75
|
+
color: 'var(--color-text-secondary)',
|
|
76
|
+
marginLeft: 2,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const searchInputStyle = {
|
|
80
|
+
flex: 1,
|
|
81
|
+
border: 'none',
|
|
82
|
+
outline: 'none',
|
|
83
|
+
fontSize: 14,
|
|
84
|
+
fontWeight: 400,
|
|
85
|
+
fontFamily: FF,
|
|
86
|
+
color: 'var(--grey-strong)',
|
|
87
|
+
background: 'transparent',
|
|
88
|
+
height: '100%',
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const inviteBtnStyle = {
|
|
92
|
+
display: 'flex',
|
|
93
|
+
height: 44,
|
|
94
|
+
padding: '0 24px',
|
|
95
|
+
justifyContent: 'center',
|
|
96
|
+
alignItems: 'center',
|
|
97
|
+
borderRadius: 10,
|
|
98
|
+
background: 'var(--grey-strong)',
|
|
99
|
+
fontSize: 14,
|
|
100
|
+
fontWeight: 600,
|
|
101
|
+
fontFamily: FF,
|
|
102
|
+
color: 'var(--grey-white)',
|
|
103
|
+
border: 'none',
|
|
104
|
+
cursor: 'pointer',
|
|
105
|
+
transition: 'var(--transition-fast)',
|
|
106
|
+
outline: 'none',
|
|
107
|
+
flexShrink: 0,
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const suggestionsListStyle = {
|
|
111
|
+
marginTop: 8,
|
|
112
|
+
border: '1px solid var(--border)',
|
|
113
|
+
borderRadius: 10,
|
|
114
|
+
overflow: 'hidden',
|
|
115
|
+
background: 'var(--grey-white)',
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const suggestionItemStyle = {
|
|
119
|
+
display: 'flex',
|
|
120
|
+
alignItems: 'center',
|
|
121
|
+
gap: 12,
|
|
122
|
+
padding: '14px 16px',
|
|
123
|
+
cursor: 'pointer',
|
|
124
|
+
transition: 'var(--transition-fast)',
|
|
125
|
+
borderBottom: '1px solid var(--border-subtle)',
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
const avatarStyle = (color) => ({
|
|
129
|
+
width: 40,
|
|
130
|
+
height: 40,
|
|
131
|
+
borderRadius: 9999,
|
|
132
|
+
background: color || 'var(--hover-warm)',
|
|
133
|
+
display: 'flex',
|
|
134
|
+
alignItems: 'center',
|
|
135
|
+
justifyContent: 'center',
|
|
136
|
+
fontSize: 14,
|
|
137
|
+
fontWeight: 600,
|
|
138
|
+
fontFamily: FF,
|
|
139
|
+
color: 'var(--color-green)',
|
|
140
|
+
flexShrink: 0,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
const suggestionNameStyle = {
|
|
144
|
+
fontSize: 14,
|
|
145
|
+
fontWeight: 600,
|
|
146
|
+
fontFamily: FF,
|
|
147
|
+
color: 'var(--grey-strong)',
|
|
148
|
+
margin: 0,
|
|
149
|
+
lineHeight: '120%',
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const suggestionEmailStyle = {
|
|
153
|
+
fontSize: 13,
|
|
154
|
+
fontWeight: 400,
|
|
155
|
+
fontFamily: FF,
|
|
156
|
+
color: 'var(--color-text-secondary)',
|
|
157
|
+
margin: '2px 0 0',
|
|
158
|
+
lineHeight: '140%',
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// ─── Default Suggestions ───
|
|
162
|
+
|
|
163
|
+
const DEFAULT_SUGGESTIONS = [
|
|
164
|
+
{ name: 'Alex Rivera', email: 'alex.rivera@company.com', initials: 'AR' },
|
|
165
|
+
{ name: 'Alexandra Smith', email: 'a.smith@design.co', initials: 'AS' },
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
// ─── Component ───
|
|
169
|
+
|
|
170
|
+
const AddTeammates = ({ suggestions = DEFAULT_SUGGESTIONS, onInvite }) => {
|
|
171
|
+
const [inputValue, setInputValue] = useState('');
|
|
172
|
+
const [emails, setEmails] = useState([]);
|
|
173
|
+
const [focused, setFocused] = useState(false);
|
|
174
|
+
|
|
175
|
+
const filteredSuggestions = suggestions.filter(
|
|
176
|
+
(s) =>
|
|
177
|
+
!emails.includes(s.email) &&
|
|
178
|
+
(s.name.toLowerCase().includes(inputValue.toLowerCase()) ||
|
|
179
|
+
s.email.toLowerCase().includes(inputValue.toLowerCase()))
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
const addEmail = (email) => {
|
|
183
|
+
if (email && !emails.includes(email)) {
|
|
184
|
+
setEmails([...emails, email]);
|
|
185
|
+
setInputValue('');
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
const removeEmail = (email) => {
|
|
190
|
+
setEmails(emails.filter((e) => e !== email));
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const handleKeyDown = (e) => {
|
|
194
|
+
if (e.key === 'Enter' && inputValue.includes('@')) {
|
|
195
|
+
e.preventDefault();
|
|
196
|
+
addEmail(inputValue.trim());
|
|
197
|
+
}
|
|
198
|
+
if (e.key === 'Backspace' && !inputValue && emails.length) {
|
|
199
|
+
removeEmail(emails[emails.length - 1]);
|
|
200
|
+
}
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const handleInvite = () => {
|
|
204
|
+
if (emails.length) {
|
|
205
|
+
onInvite?.(emails);
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
return (
|
|
210
|
+
<div style={containerStyle}>
|
|
211
|
+
<h2 style={sectionTitleStyle}>Add Teammates</h2>
|
|
212
|
+
<p style={sectionSubtitleStyle}>Collaborate with your team to accelerate your workflow.</p>
|
|
213
|
+
|
|
214
|
+
<div style={searchRowStyle}>
|
|
215
|
+
<div
|
|
216
|
+
style={{
|
|
217
|
+
...searchInputWrapStyle,
|
|
218
|
+
borderColor: focused ? 'var(--color-green)' : 'var(--color-input-border)',
|
|
219
|
+
boxShadow: focused ? '0 0 0 3px var(--color-green-ring)' : 'none',
|
|
220
|
+
}}
|
|
221
|
+
>
|
|
222
|
+
<Search size={18} style={searchIconStyle} />
|
|
223
|
+
{emails.map((email) => (
|
|
224
|
+
<span key={email} style={emailTagStyle}>
|
|
225
|
+
{email}
|
|
226
|
+
<span style={emailTagRemoveStyle} onClick={() => removeEmail(email)}>×</span>
|
|
227
|
+
</span>
|
|
228
|
+
))}
|
|
229
|
+
<input
|
|
230
|
+
type="text"
|
|
231
|
+
placeholder={emails.length ? '' : 'Search by name or email...'}
|
|
232
|
+
value={inputValue}
|
|
233
|
+
onChange={(e) => setInputValue(e.target.value)}
|
|
234
|
+
onFocus={() => setFocused(true)}
|
|
235
|
+
onBlur={() => setTimeout(() => setFocused(false), 150)}
|
|
236
|
+
onKeyDown={handleKeyDown}
|
|
237
|
+
style={searchInputStyle}
|
|
238
|
+
/>
|
|
239
|
+
</div>
|
|
240
|
+
<button
|
|
241
|
+
style={inviteBtnStyle}
|
|
242
|
+
onClick={handleInvite}
|
|
243
|
+
onMouseEnter={(e) => { e.currentTarget.style.opacity = '0.85'; }}
|
|
244
|
+
onMouseLeave={(e) => { e.currentTarget.style.opacity = '1'; }}
|
|
245
|
+
>
|
|
246
|
+
Invite
|
|
247
|
+
</button>
|
|
248
|
+
</div>
|
|
249
|
+
|
|
250
|
+
{focused && filteredSuggestions.length > 0 && (
|
|
251
|
+
<div style={suggestionsListStyle}>
|
|
252
|
+
{filteredSuggestions.map((suggestion, idx) => (
|
|
253
|
+
<div
|
|
254
|
+
key={suggestion.email}
|
|
255
|
+
style={{
|
|
256
|
+
...suggestionItemStyle,
|
|
257
|
+
...(idx === filteredSuggestions.length - 1 ? { borderBottom: 'none' } : {}),
|
|
258
|
+
}}
|
|
259
|
+
onMouseDown={() => addEmail(suggestion.email)}
|
|
260
|
+
onMouseEnter={(e) => { e.currentTarget.style.background = 'var(--hover-warm-subtle)'; }}
|
|
261
|
+
onMouseLeave={(e) => { e.currentTarget.style.background = 'var(--grey-white)'; }}
|
|
262
|
+
>
|
|
263
|
+
<div style={avatarStyle()}>
|
|
264
|
+
{suggestion.initials}
|
|
265
|
+
</div>
|
|
266
|
+
<div>
|
|
267
|
+
<p style={suggestionNameStyle}>{suggestion.name}</p>
|
|
268
|
+
<p style={suggestionEmailStyle}>{suggestion.email}</p>
|
|
269
|
+
</div>
|
|
270
|
+
</div>
|
|
271
|
+
))}
|
|
272
|
+
</div>
|
|
273
|
+
)}
|
|
274
|
+
</div>
|
|
275
|
+
);
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
export default AddTeammates;
|
|
@@ -2,6 +2,7 @@ import { useState } from 'react';
|
|
|
2
2
|
import { MessageSquare, Database, Users, BookOpen, SlidersHorizontal, Briefcase } from 'lucide-react';
|
|
3
3
|
import UploadInteraction from './UploadInteraction';
|
|
4
4
|
import ConnectData from './ConnectData';
|
|
5
|
+
import AddTeammates from './AddTeammates';
|
|
5
6
|
|
|
6
7
|
const FF = 'var(--font-sans)';
|
|
7
8
|
|
|
@@ -511,6 +512,9 @@ const GettingStarted = ({
|
|
|
511
512
|
{activeStepId === 'connect' && (
|
|
512
513
|
<ConnectData />
|
|
513
514
|
)}
|
|
515
|
+
{activeStepId === 'invite' && (
|
|
516
|
+
<AddTeammates />
|
|
517
|
+
)}
|
|
514
518
|
</div>
|
|
515
519
|
</div>
|
|
516
520
|
</div>
|
|
@@ -145,13 +145,13 @@ const UploadInteraction = ({ onFileSelect }) => {
|
|
|
145
145
|
<div style={containerStyle}>
|
|
146
146
|
<h2 style={sectionTitleStyle}>Evaluate Interaction</h2>
|
|
147
147
|
<p style={sectionSubtitleStyle}>
|
|
148
|
-
Upload
|
|
148
|
+
Upload interactions to generate insights, explore results, and identify patterns.
|
|
149
149
|
</p>
|
|
150
150
|
|
|
151
151
|
<input
|
|
152
152
|
ref={fileInputRef}
|
|
153
153
|
type="file"
|
|
154
|
-
accept="
|
|
154
|
+
accept="audio/mpeg,audio/wav,audio/x-ms-wma,audio/mp4,video/mp4,video/webm"
|
|
155
155
|
multiple
|
|
156
156
|
style={{ display: 'none' }}
|
|
157
157
|
onChange={handleFileChange}
|
|
@@ -177,7 +177,7 @@ const UploadInteraction = ({ onFileSelect }) => {
|
|
|
177
177
|
>
|
|
178
178
|
Browse files
|
|
179
179
|
</button>
|
|
180
|
-
<p style={dropzoneHintStyle}>Supports: MP3, WMA
|
|
180
|
+
<p style={dropzoneHintStyle}>Supports: MP3, WAV, WMA, MP4, and WEBM</p>
|
|
181
181
|
</div>
|
|
182
182
|
</div>
|
|
183
183
|
);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as UploadEvaluate } from './UploadEvaluate';
|
|
2
|
+
export { default as GettingStarted } from './GettingStarted';
|
|
3
|
+
export { default as UploadInteraction } from './UploadInteraction';
|
|
4
|
+
export { default as ConnectData } from './ConnectData';
|
|
5
|
+
export { default as AddTeammates } from './AddTeammates';
|
package/dist/AutoSearch.cjs.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";const r=require("react/jsx-runtime"),o=require("react"),p=require("lucide-react"),q=require("./TextInput.cjs.js"),j=require("./SmallButton.cjs.js"),E=({options:m=[],value:c=null,onChange:l,placeholder:g="Search...",disabled:k=!1,showSuggestions:n=!0,styling:w,isAddNew:u=!1})=>{const[a,i]=o.useState(""),[f,s]=o.useState(!1),[d,x]=o.useState(null),b=o.useRef(null),y=o.useMemo(()=>{if(!n)return[];const e=a.toLowerCase();return m.filter(t=>{if(!t)return!1;const v=t.label||"",h=t.value||"";return(v.toLowerCase().includes(e)||h.toLowerCase().includes(e))&&(!d||t.value!==d.value)})},[a,m,n,d]),S=o.useMemo(()=>{if(!u)return!1;const e=a.toLowerCase();return m.some(t=>{if(!t)return!1;const v=t.label||"",h=t.value||"";return v.toLowerCase()===e||h.toLowerCase()===e})},[m,a,u]);o.useEffect(()=>{if(!f)return;const e=t=>{b.current&&!b.current.contains(t.target)&&s(!1)};return document.addEventListener("mousedown",e),()=>document.removeEventListener("mousedown",e)},[f]);const L=e=>{l==null||l(e),i(""),s(!1),x(null)},N=()=>{const e={label:a,value:a};x(e),l==null||l(e),s(!1),i("")},O=()=>{l==null||l(null),i(""),s(!1),x(null)},T=e=>{const t=e.target.value;n?(i(t),s(!0)):u?(i(t),s(t.length>=3)):l==null||l(t)},I=()=>{(n||u)&&s(!0)},R=f&&!c&&a.length>=3;return r.jsxs("div",{className:"relative w-full",ref:b,children:[r.jsxs("div",{className:w||"flex items-center gap-2 border rounded-md px-3 py-2 bg-white shadow-sm",children:[r.jsx(p.Search,{className:"w-4 h-4 text-gray-400"}),r.jsx("div",{className:"flex-1",children:n&&c?r.jsx("div",{className:"text-gray-800 truncate",title:c.label,style:{fontSize:"var(--text-sm)",fontWeight:"var(--font-medium)",letterSpacing:"var(--tracking-normal)",lineHeight:"var(--leading-normal)",textTransform:"none",textDecoration:"none",fontFamily:"var(--font-sans)"},children:c.label}):r.jsx(q.TextInput,{value:n||u?a:c||"",onChange:e=>T({target:{value:e}}),placeholder:g,disabled:k,style:{border:"none",boxShadow:"none",padding:0,backgroundColor:"transparent"},onFocus:I})}),(c||d)&&r.jsx(j.SmallButton,{type:"button",variant:"ghost",size:"sm",onClick:O,style:{padding:0,width:20,height:20,border:"none",backgroundColor:"transparent",color:"rgba(107,114,128,1)"},children:r.jsx(p.X,{className:"w-3 h-3"})})]}),R&&r.jsxs("div",{className:"absolute w-full rounded-md border border-gray-300 bg-white shadow-lg custom-thin-scrollbar-library",style:{maxHeight:240,overflowY:"auto",zIndex:30},children:[y.length>0&&r.jsx("ul",{className:"m-0 p-0 list-none",children:y.map(e=>r.jsx("li",{onClick:()=>L(e),onMouseEnter:t=>{t.currentTarget.style.backgroundColor="var(--hover-warm)"},onMouseLeave:t=>{t.currentTarget.style.backgroundColor="transparent"},className:"cursor-pointer px-4 py-2",title:e.label,children:r.jsx("span",{className:"truncate block w-full",style:{fontFamily:"var(--font-sans)",color:"var(--text-base)",fontSize:"var(--text-sm)",fontWeight:"var(--font-medium)",letterSpacing:"var(--tracking-normal)",lineHeight:"var(--leading-normal)",textTransform:"none",textDecoration:"none"},children:e.label})},e.value))}),u&&!S&&!d&&a.length>=3&&r.jsxs(j.SmallButton,{type:"button",variant:"secondary",onClick:N,style:{width:"100%",justifyContent:"space-between",padding:"8px 10px",border:"none",borderTop:"1px solid rgba(229, 231, 235, 1)",borderRadius:0,backgroundColor:"transparent",color:"rgba(107,114,128,1)"},children:[r.jsx("span",{children:`Add "${a}"`}),r.jsx(p.PlusCircle,{className:"w-5 h-5 text-green-500"})]})]})]})};exports.AutoSearch=E;
|
|
2
|
-
//# sourceMappingURL=AutoSearch.cjs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AutoSearch.cjs.js","sources":["../src/components/common/AutoSearch.jsx"],"sourcesContent":["\"use client\";\n\nimport React, { useState, useMemo, useRef, useEffect } from \"react\";\nimport { X, Search, PlusCircle } from \"lucide-react\";\nimport TextInput from \"../primitives/TextInput\";\nimport SmallButton from \"../primitives/SmallButton\";\n\nconst AutoSearch = ({\n options = [],\n value = null,\n onChange,\n placeholder = \"Search...\",\n disabled = false,\n showSuggestions = true,\n styling,\n isAddNew = false,\n}) => {\n const [search, setSearch] = useState(\"\");\n const [isOpen, setIsOpen] = useState(false);\n const [addedOption, setAddedOption] = useState(null);\n\n const containerRef = useRef(null);\n\n const filteredOptions = useMemo(() => {\n if (!showSuggestions) return [];\n const lower = search.toLowerCase();\n\n return options.filter((opt) => {\n if (!opt) return false;\n const label = opt.label || \"\";\n const val = opt.value || \"\";\n return (\n (label.toLowerCase().includes(lower) ||\n val.toLowerCase().includes(lower)) &&\n (!addedOption || opt.value !== addedOption.value)\n );\n });\n }, [search, options, showSuggestions, addedOption]);\n\n const exactMatchExists = useMemo(() => {\n if (!isAddNew) return false;\n const lower = search.toLowerCase();\n return options.some((opt) => {\n if (!opt) return false;\n const label = opt.label || \"\";\n const val = opt.value || \"\";\n return label.toLowerCase() === lower || val.toLowerCase() === lower;\n });\n }, [options, search, isAddNew]);\n\n // Close dropdown on outside click\n useEffect(() => {\n if (!isOpen) return;\n const handleClickOutside = (event) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target)\n ) {\n setIsOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, [isOpen]);\n\n const handleSelect = (opt) => {\n onChange?.(opt);\n setSearch(\"\");\n setIsOpen(false);\n setAddedOption(null);\n };\n\n const handleAddNew = () => {\n const newOpt = { label: search, value: search };\n setAddedOption(newOpt);\n onChange?.(newOpt);\n setIsOpen(false);\n setSearch(\"\");\n };\n\n const handleClear = () => {\n onChange?.(null);\n setSearch(\"\");\n setIsOpen(false);\n setAddedOption(null);\n };\n\n const handleInputChange = (e) => {\n const newValue = e.target.value;\n if (showSuggestions) {\n setSearch(newValue);\n setIsOpen(true);\n } else if (isAddNew) {\n setSearch(newValue);\n setIsOpen(newValue.length >= 3);\n } else {\n onChange?.(newValue);\n }\n };\n\n const handleInputFocus = () => {\n if (showSuggestions || isAddNew) {\n setIsOpen(true);\n }\n };\n\n const shouldShowDropdown =\n isOpen && !value && (showSuggestions ? search.length >= 3 : search.length >= 3);\n\n return (\n <div className=\"relative w-full\" ref={containerRef}>\n <div\n className={\n styling\n ? styling\n : \"flex items-center gap-2 border rounded-md px-3 py-2 bg-white shadow-sm\"\n }\n >\n <Search className=\"w-4 h-4 text-gray-400\" />\n <div className=\"flex-1\">\n {showSuggestions && value ? (\n <div\n className=\"text-gray-800 truncate\"\n title={value.label}\n style={{\n fontSize: 'var(--text-sm)',\n fontWeight: 'var(--font-medium)',\n letterSpacing: 'var(--tracking-normal)',\n lineHeight: 'var(--leading-normal)',\n textTransform: 'none',\n textDecoration: 'none',\n fontFamily: 'var(--font-sans)',\n }}\n >\n {value.label}\n </div>\n ) : (\n <TextInput\n value={showSuggestions || isAddNew ? search : value || \"\"}\n onChange={(val) =>\n handleInputChange({ target: { value: val } })\n }\n placeholder={placeholder}\n disabled={disabled}\n style={{\n border: \"none\",\n boxShadow: \"none\",\n padding: 0,\n backgroundColor: \"transparent\",\n }}\n onFocus={handleInputFocus}\n />\n )}\n </div>\n {(value || addedOption) && (\n <SmallButton\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleClear}\n style={{\n padding: 0,\n width: 20,\n height: 20,\n border: \"none\",\n backgroundColor: \"transparent\",\n color: \"rgba(107,114,128,1)\",\n }}\n >\n <X className=\"w-3 h-3\" />\n </SmallButton>\n )}\n </div>\n\n {shouldShowDropdown && (\n <div\n className=\"absolute w-full rounded-md border border-gray-300 bg-white shadow-lg custom-thin-scrollbar-library\"\n style={{\n maxHeight: 240,\n overflowY: \"auto\",\n zIndex: 30,\n }}\n >\n {filteredOptions.length > 0 && (\n <ul className=\"m-0 p-0 list-none\">\n {filteredOptions.map((opt) => (\n <li\n key={opt.value}\n onClick={() => handleSelect(opt)}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"var(--hover-warm)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n }}\n className=\"cursor-pointer px-4 py-2\"\n title={opt.label}\n >\n <span\n className=\"truncate block w-full\"\n style={{\n fontFamily: \"var(--font-sans)\",\n color: \"var(--text-base)\",\n fontSize: \"var(--text-sm)\",\n fontWeight: \"var(--font-medium)\",\n letterSpacing: \"var(--tracking-normal)\",\n lineHeight: \"var(--leading-normal)\",\n textTransform: \"none\",\n textDecoration: \"none\",\n }}\n >\n {opt.label}\n </span>\n </li>\n ))}\n </ul>\n )}\n\n {isAddNew &&\n !exactMatchExists &&\n !addedOption &&\n search.length >= 3 && (\n <SmallButton\n type=\"button\"\n variant=\"secondary\"\n onClick={handleAddNew}\n style={{\n width: \"100%\",\n justifyContent: \"space-between\",\n padding: \"8px 10px\",\n border: \"none\",\n borderTop: \"1px solid rgba(229, 231, 235, 1)\",\n borderRadius: 0,\n backgroundColor: \"transparent\",\n color: \"rgba(107,114,128,1)\",\n }}\n >\n <span>{`Add \"${search}\"`}</span>\n <PlusCircle className=\"w-5 h-5 text-green-500\" />\n </SmallButton>\n )}\n </div>\n )}\n </div>\n );\n};\n\nexport default AutoSearch;\n\n"],"names":["AutoSearch","options","value","onChange","placeholder","disabled","showSuggestions","styling","isAddNew","search","setSearch","useState","isOpen","setIsOpen","addedOption","setAddedOption","containerRef","useRef","filteredOptions","useMemo","lower","opt","label","val","exactMatchExists","useEffect","handleClickOutside","event","handleSelect","handleAddNew","newOpt","handleClear","handleInputChange","newValue","handleInputFocus","shouldShowDropdown","jsxs","jsx","Search","TextInput","SmallButton","X","e","PlusCircle"],"mappings":"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"}
|
package/dist/AutoSearch.es.js
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import { jsxs as m, jsx as a } from "react/jsx-runtime";
|
|
2
|
-
import { useState as x, useRef as M, useMemo as g, useEffect as j } from "react";
|
|
3
|
-
import { Search as D, X as H, PlusCircle as R } from "lucide-react";
|
|
4
|
-
import { T as W } from "./TextInput.es.js";
|
|
5
|
-
import { S as k } from "./SmallButton.es.js";
|
|
6
|
-
const Y = ({
|
|
7
|
-
options: u = [],
|
|
8
|
-
value: s = null,
|
|
9
|
-
onChange: r,
|
|
10
|
-
placeholder: L = "Search...",
|
|
11
|
-
disabled: S = !1,
|
|
12
|
-
showSuggestions: n = !0,
|
|
13
|
-
styling: w,
|
|
14
|
-
isAddNew: c = !1
|
|
15
|
-
}) => {
|
|
16
|
-
const [l, i] = x(""), [f, o] = x(!1), [d, b] = x(null), v = M(null), y = g(() => {
|
|
17
|
-
if (!n)
|
|
18
|
-
return [];
|
|
19
|
-
const e = l.toLowerCase();
|
|
20
|
-
return u.filter((t) => {
|
|
21
|
-
if (!t)
|
|
22
|
-
return !1;
|
|
23
|
-
const p = t.label || "", h = t.value || "";
|
|
24
|
-
return (p.toLowerCase().includes(e) || h.toLowerCase().includes(e)) && (!d || t.value !== d.value);
|
|
25
|
-
});
|
|
26
|
-
}, [l, u, n, d]), N = g(() => {
|
|
27
|
-
if (!c)
|
|
28
|
-
return !1;
|
|
29
|
-
const e = l.toLowerCase();
|
|
30
|
-
return u.some((t) => {
|
|
31
|
-
if (!t)
|
|
32
|
-
return !1;
|
|
33
|
-
const p = t.label || "", h = t.value || "";
|
|
34
|
-
return p.toLowerCase() === e || h.toLowerCase() === e;
|
|
35
|
-
});
|
|
36
|
-
}, [u, l, c]);
|
|
37
|
-
j(() => {
|
|
38
|
-
if (!f)
|
|
39
|
-
return;
|
|
40
|
-
const e = (t) => {
|
|
41
|
-
v.current && !v.current.contains(t.target) && o(!1);
|
|
42
|
-
};
|
|
43
|
-
return document.addEventListener("mousedown", e), () => document.removeEventListener("mousedown", e);
|
|
44
|
-
}, [f]);
|
|
45
|
-
const O = (e) => {
|
|
46
|
-
r == null || r(e), i(""), o(!1), b(null);
|
|
47
|
-
}, T = () => {
|
|
48
|
-
const e = { label: l, value: l };
|
|
49
|
-
b(e), r == null || r(e), o(!1), i("");
|
|
50
|
-
}, E = () => {
|
|
51
|
-
r == null || r(null), i(""), o(!1), b(null);
|
|
52
|
-
}, I = (e) => {
|
|
53
|
-
const t = e.target.value;
|
|
54
|
-
n ? (i(t), o(!0)) : c ? (i(t), o(t.length >= 3)) : r == null || r(t);
|
|
55
|
-
}, z = () => {
|
|
56
|
-
(n || c) && o(!0);
|
|
57
|
-
}, F = f && !s && l.length >= 3;
|
|
58
|
-
return /* @__PURE__ */ m("div", { className: "relative w-full", ref: v, children: [
|
|
59
|
-
/* @__PURE__ */ m(
|
|
60
|
-
"div",
|
|
61
|
-
{
|
|
62
|
-
className: w || "flex items-center gap-2 border rounded-md px-3 py-2 bg-white shadow-sm",
|
|
63
|
-
children: [
|
|
64
|
-
/* @__PURE__ */ a(D, { className: "w-4 h-4 text-gray-400" }),
|
|
65
|
-
/* @__PURE__ */ a("div", { className: "flex-1", children: n && s ? /* @__PURE__ */ a(
|
|
66
|
-
"div",
|
|
67
|
-
{
|
|
68
|
-
className: "text-gray-800 truncate",
|
|
69
|
-
title: s.label,
|
|
70
|
-
style: {
|
|
71
|
-
fontSize: "var(--text-sm)",
|
|
72
|
-
fontWeight: "var(--font-medium)",
|
|
73
|
-
letterSpacing: "var(--tracking-normal)",
|
|
74
|
-
lineHeight: "var(--leading-normal)",
|
|
75
|
-
textTransform: "none",
|
|
76
|
-
textDecoration: "none",
|
|
77
|
-
fontFamily: "var(--font-sans)"
|
|
78
|
-
},
|
|
79
|
-
children: s.label
|
|
80
|
-
}
|
|
81
|
-
) : /* @__PURE__ */ a(
|
|
82
|
-
W,
|
|
83
|
-
{
|
|
84
|
-
value: n || c ? l : s || "",
|
|
85
|
-
onChange: (e) => I({ target: { value: e } }),
|
|
86
|
-
placeholder: L,
|
|
87
|
-
disabled: S,
|
|
88
|
-
style: {
|
|
89
|
-
border: "none",
|
|
90
|
-
boxShadow: "none",
|
|
91
|
-
padding: 0,
|
|
92
|
-
backgroundColor: "transparent"
|
|
93
|
-
},
|
|
94
|
-
onFocus: z
|
|
95
|
-
}
|
|
96
|
-
) }),
|
|
97
|
-
(s || d) && /* @__PURE__ */ a(
|
|
98
|
-
k,
|
|
99
|
-
{
|
|
100
|
-
type: "button",
|
|
101
|
-
variant: "ghost",
|
|
102
|
-
size: "sm",
|
|
103
|
-
onClick: E,
|
|
104
|
-
style: {
|
|
105
|
-
padding: 0,
|
|
106
|
-
width: 20,
|
|
107
|
-
height: 20,
|
|
108
|
-
border: "none",
|
|
109
|
-
backgroundColor: "transparent",
|
|
110
|
-
color: "rgba(107,114,128,1)"
|
|
111
|
-
},
|
|
112
|
-
children: /* @__PURE__ */ a(H, { className: "w-3 h-3" })
|
|
113
|
-
}
|
|
114
|
-
)
|
|
115
|
-
]
|
|
116
|
-
}
|
|
117
|
-
),
|
|
118
|
-
F && /* @__PURE__ */ m(
|
|
119
|
-
"div",
|
|
120
|
-
{
|
|
121
|
-
className: "absolute w-full rounded-md border border-gray-300 bg-white shadow-lg custom-thin-scrollbar-library",
|
|
122
|
-
style: {
|
|
123
|
-
maxHeight: 240,
|
|
124
|
-
overflowY: "auto",
|
|
125
|
-
zIndex: 30
|
|
126
|
-
},
|
|
127
|
-
children: [
|
|
128
|
-
y.length > 0 && /* @__PURE__ */ a("ul", { className: "m-0 p-0 list-none", children: y.map((e) => /* @__PURE__ */ a(
|
|
129
|
-
"li",
|
|
130
|
-
{
|
|
131
|
-
onClick: () => O(e),
|
|
132
|
-
onMouseEnter: (t) => {
|
|
133
|
-
t.currentTarget.style.backgroundColor = "var(--hover-warm)";
|
|
134
|
-
},
|
|
135
|
-
onMouseLeave: (t) => {
|
|
136
|
-
t.currentTarget.style.backgroundColor = "transparent";
|
|
137
|
-
},
|
|
138
|
-
className: "cursor-pointer px-4 py-2",
|
|
139
|
-
title: e.label,
|
|
140
|
-
children: /* @__PURE__ */ a(
|
|
141
|
-
"span",
|
|
142
|
-
{
|
|
143
|
-
className: "truncate block w-full",
|
|
144
|
-
style: {
|
|
145
|
-
fontFamily: "var(--font-sans)",
|
|
146
|
-
color: "var(--text-base)",
|
|
147
|
-
fontSize: "var(--text-sm)",
|
|
148
|
-
fontWeight: "var(--font-medium)",
|
|
149
|
-
letterSpacing: "var(--tracking-normal)",
|
|
150
|
-
lineHeight: "var(--leading-normal)",
|
|
151
|
-
textTransform: "none",
|
|
152
|
-
textDecoration: "none"
|
|
153
|
-
},
|
|
154
|
-
children: e.label
|
|
155
|
-
}
|
|
156
|
-
)
|
|
157
|
-
},
|
|
158
|
-
e.value
|
|
159
|
-
)) }),
|
|
160
|
-
c && !N && !d && l.length >= 3 && /* @__PURE__ */ m(
|
|
161
|
-
k,
|
|
162
|
-
{
|
|
163
|
-
type: "button",
|
|
164
|
-
variant: "secondary",
|
|
165
|
-
onClick: T,
|
|
166
|
-
style: {
|
|
167
|
-
width: "100%",
|
|
168
|
-
justifyContent: "space-between",
|
|
169
|
-
padding: "8px 10px",
|
|
170
|
-
border: "none",
|
|
171
|
-
borderTop: "1px solid rgba(229, 231, 235, 1)",
|
|
172
|
-
borderRadius: 0,
|
|
173
|
-
backgroundColor: "transparent",
|
|
174
|
-
color: "rgba(107,114,128,1)"
|
|
175
|
-
},
|
|
176
|
-
children: [
|
|
177
|
-
/* @__PURE__ */ a("span", { children: `Add "${l}"` }),
|
|
178
|
-
/* @__PURE__ */ a(R, { className: "w-5 h-5 text-green-500" })
|
|
179
|
-
]
|
|
180
|
-
}
|
|
181
|
-
)
|
|
182
|
-
]
|
|
183
|
-
}
|
|
184
|
-
)
|
|
185
|
-
] });
|
|
186
|
-
};
|
|
187
|
-
export {
|
|
188
|
-
Y as A
|
|
189
|
-
};
|
|
190
|
-
//# sourceMappingURL=AutoSearch.es.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AutoSearch.es.js","sources":["../src/components/common/AutoSearch.jsx"],"sourcesContent":["\"use client\";\n\nimport React, { useState, useMemo, useRef, useEffect } from \"react\";\nimport { X, Search, PlusCircle } from \"lucide-react\";\nimport TextInput from \"../primitives/TextInput\";\nimport SmallButton from \"../primitives/SmallButton\";\n\nconst AutoSearch = ({\n options = [],\n value = null,\n onChange,\n placeholder = \"Search...\",\n disabled = false,\n showSuggestions = true,\n styling,\n isAddNew = false,\n}) => {\n const [search, setSearch] = useState(\"\");\n const [isOpen, setIsOpen] = useState(false);\n const [addedOption, setAddedOption] = useState(null);\n\n const containerRef = useRef(null);\n\n const filteredOptions = useMemo(() => {\n if (!showSuggestions) return [];\n const lower = search.toLowerCase();\n\n return options.filter((opt) => {\n if (!opt) return false;\n const label = opt.label || \"\";\n const val = opt.value || \"\";\n return (\n (label.toLowerCase().includes(lower) ||\n val.toLowerCase().includes(lower)) &&\n (!addedOption || opt.value !== addedOption.value)\n );\n });\n }, [search, options, showSuggestions, addedOption]);\n\n const exactMatchExists = useMemo(() => {\n if (!isAddNew) return false;\n const lower = search.toLowerCase();\n return options.some((opt) => {\n if (!opt) return false;\n const label = opt.label || \"\";\n const val = opt.value || \"\";\n return label.toLowerCase() === lower || val.toLowerCase() === lower;\n });\n }, [options, search, isAddNew]);\n\n // Close dropdown on outside click\n useEffect(() => {\n if (!isOpen) return;\n const handleClickOutside = (event) => {\n if (\n containerRef.current &&\n !containerRef.current.contains(event.target)\n ) {\n setIsOpen(false);\n }\n };\n document.addEventListener(\"mousedown\", handleClickOutside);\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\n }, [isOpen]);\n\n const handleSelect = (opt) => {\n onChange?.(opt);\n setSearch(\"\");\n setIsOpen(false);\n setAddedOption(null);\n };\n\n const handleAddNew = () => {\n const newOpt = { label: search, value: search };\n setAddedOption(newOpt);\n onChange?.(newOpt);\n setIsOpen(false);\n setSearch(\"\");\n };\n\n const handleClear = () => {\n onChange?.(null);\n setSearch(\"\");\n setIsOpen(false);\n setAddedOption(null);\n };\n\n const handleInputChange = (e) => {\n const newValue = e.target.value;\n if (showSuggestions) {\n setSearch(newValue);\n setIsOpen(true);\n } else if (isAddNew) {\n setSearch(newValue);\n setIsOpen(newValue.length >= 3);\n } else {\n onChange?.(newValue);\n }\n };\n\n const handleInputFocus = () => {\n if (showSuggestions || isAddNew) {\n setIsOpen(true);\n }\n };\n\n const shouldShowDropdown =\n isOpen && !value && (showSuggestions ? search.length >= 3 : search.length >= 3);\n\n return (\n <div className=\"relative w-full\" ref={containerRef}>\n <div\n className={\n styling\n ? styling\n : \"flex items-center gap-2 border rounded-md px-3 py-2 bg-white shadow-sm\"\n }\n >\n <Search className=\"w-4 h-4 text-gray-400\" />\n <div className=\"flex-1\">\n {showSuggestions && value ? (\n <div\n className=\"text-gray-800 truncate\"\n title={value.label}\n style={{\n fontSize: 'var(--text-sm)',\n fontWeight: 'var(--font-medium)',\n letterSpacing: 'var(--tracking-normal)',\n lineHeight: 'var(--leading-normal)',\n textTransform: 'none',\n textDecoration: 'none',\n fontFamily: 'var(--font-sans)',\n }}\n >\n {value.label}\n </div>\n ) : (\n <TextInput\n value={showSuggestions || isAddNew ? search : value || \"\"}\n onChange={(val) =>\n handleInputChange({ target: { value: val } })\n }\n placeholder={placeholder}\n disabled={disabled}\n style={{\n border: \"none\",\n boxShadow: \"none\",\n padding: 0,\n backgroundColor: \"transparent\",\n }}\n onFocus={handleInputFocus}\n />\n )}\n </div>\n {(value || addedOption) && (\n <SmallButton\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleClear}\n style={{\n padding: 0,\n width: 20,\n height: 20,\n border: \"none\",\n backgroundColor: \"transparent\",\n color: \"rgba(107,114,128,1)\",\n }}\n >\n <X className=\"w-3 h-3\" />\n </SmallButton>\n )}\n </div>\n\n {shouldShowDropdown && (\n <div\n className=\"absolute w-full rounded-md border border-gray-300 bg-white shadow-lg custom-thin-scrollbar-library\"\n style={{\n maxHeight: 240,\n overflowY: \"auto\",\n zIndex: 30,\n }}\n >\n {filteredOptions.length > 0 && (\n <ul className=\"m-0 p-0 list-none\">\n {filteredOptions.map((opt) => (\n <li\n key={opt.value}\n onClick={() => handleSelect(opt)}\n onMouseEnter={(e) => {\n e.currentTarget.style.backgroundColor = \"var(--hover-warm)\";\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.backgroundColor = \"transparent\";\n }}\n className=\"cursor-pointer px-4 py-2\"\n title={opt.label}\n >\n <span\n className=\"truncate block w-full\"\n style={{\n fontFamily: \"var(--font-sans)\",\n color: \"var(--text-base)\",\n fontSize: \"var(--text-sm)\",\n fontWeight: \"var(--font-medium)\",\n letterSpacing: \"var(--tracking-normal)\",\n lineHeight: \"var(--leading-normal)\",\n textTransform: \"none\",\n textDecoration: \"none\",\n }}\n >\n {opt.label}\n </span>\n </li>\n ))}\n </ul>\n )}\n\n {isAddNew &&\n !exactMatchExists &&\n !addedOption &&\n search.length >= 3 && (\n <SmallButton\n type=\"button\"\n variant=\"secondary\"\n onClick={handleAddNew}\n style={{\n width: \"100%\",\n justifyContent: \"space-between\",\n padding: \"8px 10px\",\n border: \"none\",\n borderTop: \"1px solid rgba(229, 231, 235, 1)\",\n borderRadius: 0,\n backgroundColor: \"transparent\",\n color: \"rgba(107,114,128,1)\",\n }}\n >\n <span>{`Add \"${search}\"`}</span>\n <PlusCircle className=\"w-5 h-5 text-green-500\" />\n </SmallButton>\n )}\n </div>\n )}\n </div>\n );\n};\n\nexport default AutoSearch;\n\n"],"names":["AutoSearch","options","value","onChange","placeholder","disabled","showSuggestions","styling","isAddNew","search","setSearch","useState","isOpen","setIsOpen","addedOption","setAddedOption","containerRef","useRef","filteredOptions","useMemo","lower","opt","label","val","exactMatchExists","useEffect","handleClickOutside","event","handleSelect","handleAddNew","newOpt","handleClear","handleInputChange","newValue","handleInputFocus","shouldShowDropdown","jsxs","jsx","Search","TextInput","SmallButton","X","e","PlusCircle"],"mappings":"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"}
|