@stack-spot/citric-react 0.42.0 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/citric.css CHANGED
@@ -1895,7 +1895,8 @@ nav[data-citric="menu"].rounded-items, [data-citric="menu"].rounded-items nav {
1895
1895
  [data-citric="select"] select,
1896
1896
  [data-citric="rich-select"],
1897
1897
  [data-citric="multi-select"],
1898
- [data-citric="textarea"] {
1898
+ [data-citric="textarea"],
1899
+ [data-citric="autocomplete"] {
1899
1900
  height: 2.5rem;
1900
1901
  padding: var(--spacing-3);
1901
1902
  outline: none;
@@ -2796,6 +2797,243 @@ a[data-citric="badge"] {
2796
2797
  }
2797
2798
 
2798
2799
 
2800
+ [data-citric="autocomplete"] {
2801
+ --default-padding: 4px 8px;
2802
+ --default-max-height: 300px;
2803
+ --animation-duration: 0.3s;
2804
+ position: relative;
2805
+ height: auto;
2806
+ display: flex;
2807
+ flex-direction: row;
2808
+ align-items: center;
2809
+ box-sizing: border-box;
2810
+
2811
+ &:after {
2812
+ content: '';
2813
+ position: absolute;
2814
+ pointer-events: none;
2815
+ top: 0;
2816
+ left: 0;
2817
+ right: 0;
2818
+ bottom: 0;
2819
+ border: 1px solid var(--border-color, var(--light-600));
2820
+ border-radius: var(--radius-xs);
2821
+ transition: border var(--animation-duration);
2822
+ }
2823
+
2824
+ &.focused,
2825
+ &:has(:focus) {
2826
+ &:after {
2827
+ border: 2px solid var(--border-color, var(--scheme-500, var(--primary-500)));
2828
+ }
2829
+
2830
+ .dropdown-panel:after {
2831
+ border: 2px solid var(--border-color, var(--scheme-500, var(--primary-500)));
2832
+ border-top: none;
2833
+ }
2834
+ }
2835
+
2836
+ &:has(:disabled),
2837
+ &.disabled {
2838
+ background-color: var(--light-500);
2839
+ border-color: var(--light-600);
2840
+ color: var(--light-700);
2841
+ cursor: not-allowed;
2842
+
2843
+ [data-citric="progress-circular"] {
2844
+ border-color: var(--light-400);
2845
+ }
2846
+ }
2847
+
2848
+ header {
2849
+ display: flex;
2850
+ gap: 6px;
2851
+ align-items: center;
2852
+ margin: 0px !important;
2853
+ min-width: 80px;
2854
+ justify-content: space-between;
2855
+ flex: 1;
2856
+ flex-wrap: wrap;
2857
+ outline: none;
2858
+
2859
+ .input-container {
2860
+ display: flex;
2861
+ flex: 1;
2862
+ flex-wrap: wrap;
2863
+ flex-direction: row;
2864
+
2865
+ input {
2866
+ all: unset;
2867
+ width: 0px;
2868
+ min-width: 30px;
2869
+ flex-grow: 1;
2870
+ }
2871
+ }
2872
+
2873
+ .end-adornment {
2874
+ display: flex;
2875
+ align-items: center;
2876
+ gap: 8px;
2877
+ }
2878
+ }
2879
+
2880
+ .loader {
2881
+ display: none;
2882
+ }
2883
+
2884
+ /* Dropdown panel */
2885
+ .dropdown-panel {
2886
+ max-height: 0;
2887
+ overflow: hidden;
2888
+ transition: max-height var(--animation-duration) ease-in;
2889
+ position: absolute;
2890
+ top: calc(100% - 3px);
2891
+ z-index: 9999;
2892
+ left: 0;
2893
+ right: 0;
2894
+ background-color: var(--light-300);
2895
+ display: flex;
2896
+ flex-direction: column;
2897
+ gap: 8px;
2898
+ border-bottom-left-radius: var(--radius-xs);
2899
+ border-bottom-right-radius: var(--radius-xs);
2900
+
2901
+ .message {
2902
+ padding: var(--padding, var(--default-padding));
2903
+ text-align: center;
2904
+ color: var(--light-700);
2905
+ font-style: italic;
2906
+ }
2907
+
2908
+ >.options {
2909
+ margin: 0;
2910
+ padding: 0;
2911
+ list-style: none;
2912
+ display: flex;
2913
+ flex-direction: column;
2914
+ flex: 1;
2915
+ overflow: hidden;
2916
+
2917
+ >.option {
2918
+ padding: var(--padding, var(--default-padding));
2919
+ display: flex;
2920
+ transition: background-color 0.3s;
2921
+ cursor: pointer;
2922
+ align-items: center;
2923
+ gap: 8px;
2924
+
2925
+ &:not(:last-child) {
2926
+ border-bottom: 1px solid var(--light-600);
2927
+ }
2928
+
2929
+ &:hover {
2930
+ background-color: var(--scheme-500, var(--light-500));
2931
+ }
2932
+
2933
+ &.highlighted {
2934
+ background-color: var(--scheme-500, var(--light-500));
2935
+ }
2936
+
2937
+ &.selected {
2938
+ background-color: var(--scheme-400, var(--light-400));
2939
+
2940
+ &:hover {
2941
+ background-color: var(--scheme-500, var(--light-500));
2942
+ }
2943
+ }
2944
+
2945
+ &.create-option {
2946
+ color: var(--light-contrastText);
2947
+ font-weight: 500;
2948
+ border-bottom: 2px solid var(--light-600);
2949
+
2950
+ &:hover {
2951
+ background-color: var(--scheme-300, var(--primary-300));
2952
+ }
2953
+ }
2954
+ }
2955
+ }
2956
+
2957
+ &:after {
2958
+ content: '';
2959
+ position: absolute;
2960
+ top: 0;
2961
+ bottom: 0;
2962
+ left: 0;
2963
+ right: 0;
2964
+ pointer-events: none;
2965
+ border: 1px solid var(--border-color, var(--light-600));
2966
+ border-top: none;
2967
+ transition: border var(--animation-duration);
2968
+ }
2969
+
2970
+ &::-webkit-scrollbar,
2971
+ ::-webkit-scrollbar {
2972
+ width: 0.5rem;
2973
+ }
2974
+ }
2975
+
2976
+ &[aria-busy="true"],
2977
+ &[aria-busy=""] {
2978
+ cursor: progress !important;
2979
+
2980
+ .loader {
2981
+ display: block;
2982
+ }
2983
+ }
2984
+
2985
+ &:not(.open) {
2986
+ .dropdown-panel {
2987
+ opacity: 0;
2988
+ animation: var(--animation-duration) autocomplete-delayed-opacity;
2989
+ }
2990
+ }
2991
+
2992
+ &.open {
2993
+ header:after {
2994
+ transform: rotate(180deg);
2995
+ }
2996
+
2997
+ .dropdown-panel {
2998
+ max-height: var(--max-height, var(--default-max-height));
2999
+ opacity: 1;
3000
+
3001
+ .options {
3002
+ overflow: auto;
3003
+ animation: var(--animation-duration) autocomplete-delayed-overflow;
3004
+ }
3005
+ }
3006
+ }
3007
+ }
3008
+
3009
+ @keyframes autocomplete-delayed-overflow {
3010
+ 0% {
3011
+ overflow: hidden;
3012
+ }
3013
+
3014
+ 99% {
3015
+ overflow: hidden;
3016
+ }
3017
+
3018
+ 100% {
3019
+ overflow: auto;
3020
+ }
3021
+ }
3022
+
3023
+ @keyframes autocomplete-delayed-opacity {
3024
+ 0% {
3025
+ opacity: 1;
3026
+ }
3027
+
3028
+ 99% {
3029
+ opacity: 1;
3030
+ }
3031
+
3032
+ 100% {
3033
+ opacity: 0;
3034
+ }
3035
+ }
3036
+
2799
3037
  [data-citric="alert"] {
2800
3038
  padding: var(--spacing-4);
2801
3039
  font: var(--font-body2);
@@ -0,0 +1,370 @@
1
+ import { ColorPaletteName, ColorSchemeName } from '@stack-spot/portal-theme';
2
+ export interface CustomSelectedTagsConfig {
3
+ /**
4
+ * Color scheme for the tags (badges).
5
+ */
6
+ colorScheme?: ColorSchemeName;
7
+ /**
8
+ * Color palette for the tags (badges).
9
+ */
10
+ colorPalette?: ColorPaletteName;
11
+ /**
12
+ * Appearance of the tags (badges).
13
+ * @default 'circle'
14
+ */
15
+ appearance?: 'square' | 'circle';
16
+ /**
17
+ * Maximum number of tags to show before displaying "+N more".
18
+ */
19
+ maxItems?: number;
20
+ }
21
+ export interface BaseAutocompleteProps<T, Multiple extends boolean = false> {
22
+ /**
23
+ * The list of options available for selection.
24
+ */
25
+ options: T[];
26
+ /**
27
+ * The current value(s) selected.
28
+ * - Single selection: T | undefined
29
+ * - Multiple selection: T[]
30
+ */
31
+ value: Multiple extends true ? T[] : (T | undefined);
32
+ /**
33
+ * Callback fired when the value changes (user selects/removes an option).
34
+ * This is the main callback for getting the final selected value(s).
35
+ *
36
+ * @example
37
+ * ```tsx
38
+ * // Single selection
39
+ * <Autocomplete
40
+ * value={user}
41
+ * onChange={(selectedUser) => {
42
+ * console.log('Selected:', selectedUser)
43
+ * setUser(selectedUser)
44
+ * }}
45
+ * />
46
+ *
47
+ * // Multiple selection
48
+ * <Autocomplete
49
+ * multiple
50
+ * value={selectedUsers}
51
+ * onChange={(users) => {
52
+ * console.log('Selected users:', users)
53
+ * setSelectedUsers(users)
54
+ * }}
55
+ * />
56
+ * ```
57
+ */
58
+ onChange: Multiple extends true ? (value: T[]) => void : (value: T | undefined) => void;
59
+ /**
60
+ * If true, enables multiple selection mode.
61
+ * @default false
62
+ */
63
+ multiple?: Multiple;
64
+ /**
65
+ * If true, allows the user to enter values that are not in the options list.
66
+ * @default false
67
+ */
68
+ freeSolo?: boolean;
69
+ /**
70
+ * If true, allows creating new options when no match is found.
71
+ * Shows an "Add [value]" option at the top of the list.
72
+ * @default false
73
+ */
74
+ creatable?: boolean;
75
+ /**
76
+ * Callback fired when a new option is created.
77
+ * Required when creatable is true and you want manual control.
78
+ */
79
+ onCreate?: (inputValue: string) => void;
80
+ /**
81
+ * Function to create a new option object from the input value.
82
+ * Used when creatable is true and onCreate is NOT defined.
83
+ * Allows automatic option creation on Enter key.
84
+ *
85
+ * Note: This prop has no effect when onCreate is defined, as onCreate takes precedence.
86
+ *
87
+ * @param inputValue - The text typed by the user
88
+ * @returns A new option object
89
+ *
90
+ * @example
91
+ * ```tsx
92
+ * // Auto-create tags on Enter
93
+ * <Autocomplete
94
+ * multiple
95
+ * creatable
96
+ * freeSolo
97
+ * getOptionFromInput={(text) => ({
98
+ * id: Date.now(),
99
+ * name: text,
100
+ * isCustom: true
101
+ * })}
102
+ * />
103
+ * ```
104
+ */
105
+ getOptionFromInput?: (inputValue: string) => T;
106
+ /**
107
+ * The input value (controlled mode).
108
+ * Use this when you need full control over the input text.
109
+ * Usually used with onInputChange for controlled components.
110
+ *
111
+ * @example
112
+ * ```tsx
113
+ * const [inputValue, setInputValue] = useState('')
114
+ *
115
+ * <Autocomplete
116
+ * inputValue={inputValue}
117
+ * onInputChange={setInputValue}
118
+ * options={options}
119
+ * />
120
+ * ```
121
+ */
122
+ inputValue?: string;
123
+ /**
124
+ * Callback fired when the input text changes (user types).
125
+ * Use this to control the input value or perform side effects like API calls.
126
+ * Different from onChange which fires when an option is selected.
127
+ *
128
+ * @param value - The current text in the input field
129
+ *
130
+ * @example
131
+ * ```tsx
132
+ * // Debounced API search
133
+ * <Autocomplete
134
+ * onInputChange={(text) => {
135
+ * console.log('User typed:', text)
136
+ * debouncedSearch(text)
137
+ * }}
138
+ * />
139
+ *
140
+ * // Controlled input
141
+ * <Autocomplete
142
+ * inputValue={inputValue}
143
+ * onInputChange={(text) => setInputValue(text.toUpperCase())}
144
+ * />
145
+ * ```
146
+ */
147
+ onInputChange?: (value: string) => void;
148
+ /**
149
+ * A function to render the item label.
150
+ * @default "the item's toString() result."
151
+ */
152
+ renderLabel?: (option: T) => string;
153
+ /**
154
+ * A function to generate a unique key for each option.
155
+ */
156
+ renderKey?: (option: T) => string | number | undefined;
157
+ /**
158
+ * A function to render an option in the dropdown.
159
+ */
160
+ renderOption?: (option: T) => React.ReactNode;
161
+ /**
162
+ * Custom function to render the selected values display area in multiple mode.
163
+ * When defined, gives you full control over how selected values are displayed.
164
+ * The customSelectedTags prop has no effect when this is defined.
165
+ *
166
+ * @param values - Array of selected options
167
+ * @param onRemove - Function to call when user wants to remove an option
168
+ * @returns React element to display selected values
169
+ *
170
+ * @example
171
+ * ```tsx
172
+ * <Autocomplete
173
+ * multiple
174
+ * renderSelected={(values, onRemove) => (
175
+ * <div style={{ display: 'flex', gap: '4px', flexWrap: 'wrap' }}>
176
+ * {values.map(user => (
177
+ * <div key={user.id} style={{ background: '#e3f2fd', padding: '4px 8px', borderRadius: '12px' }}>
178
+ * <Avatar src={user.avatar} size="xs" />
179
+ * {user.name}
180
+ * <button onClick={() => onRemove(user)}>×</button>
181
+ * </div>
182
+ * ))}
183
+ * </div>
184
+ * )}
185
+ * />
186
+ * ```
187
+ */
188
+ renderSelected?: (values: T[], onRemove: (option: T) => void) => React.ReactElement;
189
+ /**
190
+ * Configuration for the default selected tags appearance in multiple mode.
191
+ * Has no effect when renderSelected is defined.
192
+ *
193
+ * @example
194
+ * ```tsx
195
+ * <Autocomplete
196
+ * multiple
197
+ * customSelectedTags={{
198
+ * colorScheme: 'primary',
199
+ * appearance: 'square',
200
+ * maxItems: 3
201
+ * }}
202
+ * />
203
+ * ```
204
+ */
205
+ customSelectedTags?: CustomSelectedTagsConfig;
206
+ /**
207
+ * Custom filter function for options.
208
+ * When not set, the filter will use the text returned by renderLabel (case-insensitive includes).
209
+ *
210
+ * @param options - The full list of options
211
+ * @param inputValue - The current input text
212
+ * @returns Filtered array of options
213
+ *
214
+ * @example
215
+ * ```tsx
216
+ * // Search by name OR email
217
+ * <Autocomplete
218
+ * filterOptions={(options, input) =>
219
+ * options.filter(user =>
220
+ * user.name.toLowerCase().includes(input.toLowerCase()) ||
221
+ * user.email.toLowerCase().includes(input.toLowerCase())
222
+ * )
223
+ * }
224
+ * />
225
+ * ```
226
+ */
227
+ filterOptions?: (options: T[], inputValue: string) => T[];
228
+ /**
229
+ * If true, shows a loading indicator.
230
+ * @default false
231
+ */
232
+ loading?: boolean;
233
+ /**
234
+ * If true, the component is disabled.
235
+ * @default false
236
+ */
237
+ disabled?: boolean;
238
+ /**
239
+ * Placeholder text for the input.
240
+ */
241
+ placeholder?: string;
242
+ /**
243
+ * Maximum height for the dropdown panel in pixels.
244
+ */
245
+ maxHeight?: number;
246
+ /**
247
+ * If true, automatically highlights the first option.
248
+ * @default false
249
+ */
250
+ autoHighlight?: boolean;
251
+ /**
252
+ * If true, clears the input value when an option is selected.
253
+ * Only applies when multiple is true.
254
+ * When false, the input keeps the text after selection, useful for adding multiple similar items quickly.
255
+ *
256
+ * Note: Adding multiple tags with similar prefixes when clearOnSelect={false}, you can select "React",
257
+ * then easily select "React Native"
258
+ * without retyping "React" from scratch
259
+ * @default true (for multiple mode)
260
+ *
261
+ * @example
262
+ * ```tsx
263
+ * // Clear input after each selection (default)
264
+ * <Autocomplete multiple clearOnSelect />
265
+ *
266
+ * // Keep input text after selection
267
+ * const [tags, setTags] = useState<Tag[]>([])
268
+ *
269
+ * <Autocomplete
270
+ * multiple
271
+ * clearOnSelect={false}
272
+ * value={tags}
273
+ * onChange={setTags}
274
+ * options={availableTags}
275
+ * renderLabel={tag => tag.name}
276
+ * />
277
+ * ```
278
+ */
279
+ clearOnSelect?: boolean;
280
+ /**
281
+ * If true, the popup will open on input focus.
282
+ * @default true
283
+ */
284
+ openOnFocus?: boolean;
285
+ /**
286
+ * Text to display when no options are available.
287
+ */
288
+ noOptionsText?: string;
289
+ /**
290
+ * Text to display when loading.
291
+ */
292
+ loadingText?: string;
293
+ /**
294
+ * Callback fired when the user scrolls to the end of the options list.
295
+ * Useful for implementing infinite scroll/pagination.
296
+ *
297
+ * @example
298
+ * ```tsx
299
+ * <Autocomplete
300
+ * options={options}
301
+ * onScrollEnd={() => fetchMoreOptions()}
302
+ * loading={isFetchingMore}
303
+ * />
304
+ * ```
305
+ */
306
+ onScrollEnd?: () => void;
307
+ /**
308
+ * Margin in pixels before the end of the list to trigger onScrollEnd.
309
+ * @default 200
310
+ */
311
+ scrollEndMargin?: number;
312
+ /**
313
+ * Color scheme for the autocomplete component.
314
+ * Applies the theme's color scheme to the component root.
315
+ */
316
+ colorScheme?: ColorSchemeName;
317
+ /**
318
+ * The id attribute for the input element.
319
+ * Useful for associating with a label element.
320
+ */
321
+ id?: string;
322
+ }
323
+ export type AutocompleteProps<T, Multiple extends boolean = false> = Omit<React.JSX.IntrinsicElements['div'], 'ref' | 'onChange'> & BaseAutocompleteProps<T, Multiple>;
324
+ /**
325
+ * A combination of a text input and a dropdown that suggests options as the user types.
326
+ * Supports both single and multiple selection modes, similar to Material-UI Autocomplete.
327
+ *
328
+ * @example
329
+ * Basic usage (single selection):
330
+ * ```tsx
331
+ * const [value, setValue] = useState<Option | null>(null)
332
+ *
333
+ * <Autocomplete
334
+ * options={options}
335
+ * value={value}
336
+ * onChange={setValue}
337
+ * renderLabel={o => o.name}
338
+ * renderKey={o => o.id}
339
+ * />
340
+ * ```
341
+ *
342
+ * @example
343
+ * Multiple selection with tags:
344
+ * ```tsx
345
+ * const [value, setValue] = useState<Option[]>([])
346
+ *
347
+ * <Autocomplete
348
+ * multiple
349
+ * options={options}
350
+ * value={value}
351
+ * onChange={setValue}
352
+ * renderLabel={o => o.name}
353
+ * renderKey={o => o.id}
354
+ * />
355
+ * ```
356
+ *
357
+ * @example
358
+ * Free solo (allow custom values):
359
+ * ```tsx
360
+ * <Autocomplete
361
+ * freeSolo
362
+ * options={options}
363
+ * value={value}
364
+ * onChange={setValue}
365
+ * renderLabel={o => o.name}
366
+ * />
367
+ * ```
368
+ */
369
+ export declare const Autocomplete: <T, Multiple extends boolean = false>(props: AutocompleteProps<T, Multiple>) => React.ReactElement;
370
+ //# sourceMappingURL=Autocomplete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Autocomplete.d.ts","sourceRoot":"","sources":["../../src/components/Autocomplete.tsx"],"names":[],"mappings":"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"}