astro-tractstack 2.0.0-rc.31 → 2.0.0-rc.32

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-tractstack",
3
- "version": "2.0.0-rc.31",
3
+ "version": "2.0.0-rc.32",
4
4
  "description": "Astro integration for TractStack - redeeming the web from boring experiences",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -173,10 +173,12 @@ const PanelSwitch = ({
173
173
  case 'style-link-remove':
174
174
  case 'style-link-remove-hover':
175
175
  if (clickedNode && signal.className)
176
- <StyleLinkRemovePanel
177
- node={clickedNode}
178
- className={signal.className}
179
- />;
176
+ return (
177
+ <StyleLinkRemovePanel
178
+ node={clickedNode}
179
+ className={signal.className}
180
+ />
181
+ );
180
182
  break;
181
183
 
182
184
  case 'style-link-config':
@@ -317,12 +319,12 @@ const PanelSwitch = ({
317
319
  case 'style-code-add':
318
320
  case 'style-code-container-add':
319
321
  case 'style-code-outer-add':
320
- if (clickedNode && markdownNode && signal.childId)
322
+ if (clickedNode && markdownNode)
321
323
  return (
322
324
  <StyleWidgetAddPanel
323
325
  node={clickedNode}
324
326
  parentNode={markdownNode}
325
- childId={signal.childId}
327
+ childId={signal?.childId}
326
328
  />
327
329
  );
328
330
  break;
@@ -17,7 +17,11 @@ const SettingsPanel = ({ config, availableCodeHooks }: SettingsPanelProps) => {
17
17
  const ctx = getCtx();
18
18
  const { value: toolModeVal } = useStore(ctx.toolModeValStore);
19
19
 
20
- if (toolModeVal !== 'styles' || !signal) {
20
+ const isLinkInsertSignal = signal?.action === 'style-link';
21
+ const shouldShow =
22
+ toolModeVal === 'styles' || (toolModeVal === 'text' && isLinkInsertSignal);
23
+
24
+ if (!shouldShow || !signal) {
21
25
  return null;
22
26
  }
23
27
 
@@ -1,5 +1,5 @@
1
1
  import { useState, useCallback, useEffect, useMemo, useRef } from 'react';
2
- import { Combobox, Switch } from '@ark-ui/react';
2
+ import { Combobox, Switch, Portal } from '@ark-ui/react';
3
3
  import { createListCollection } from '@ark-ui/react/collection';
4
4
  import XMarkIcon from '@heroicons/react/24/outline/XMarkIcon';
5
5
  import PlusIcon from '@heroicons/react/24/outline/PlusIcon';
@@ -8,7 +8,7 @@ import ExclamationTriangleIcon from '@heroicons/react/24/outline/ExclamationTria
8
8
  import CheckIcon from '@heroicons/react/24/outline/CheckIcon';
9
9
  import { settingsPanelStore } from '@/stores/storykeep';
10
10
  import { getCtx } from '@/stores/nodes';
11
- import { cloneDeep } from '@/utils/helpers';
11
+ import { cloneDeep, useDropdownDirection } from '@/utils/helpers';
12
12
  import { isPaneNode } from '@/utils/compositor/typeGuards';
13
13
  import type { PaneNode, BasePanelProps } from '@/types/compositorTypes';
14
14
 
@@ -30,7 +30,8 @@ const StyleCodeHookPanel = ({
30
30
 
31
31
  const [localTarget, setLocalTarget] = useState(node.codeHookTarget || '');
32
32
  const [query, setQuery] = useState('');
33
- const inputRef = useRef<HTMLInputElement>(null);
33
+ const comboboxRef = useRef<HTMLDivElement>(null);
34
+ const { openAbove } = useDropdownDirection(comboboxRef);
34
35
 
35
36
  // Parse the nested options from JSON string
36
37
  const [localOptions, setLocalOptions] = useState<OptionState[]>(() => {
@@ -320,42 +321,52 @@ const StyleCodeHookPanel = ({
320
321
  loopFocus={true}
321
322
  openOnKeyPress={true}
322
323
  composite={true}
324
+ positioning={{
325
+ placement: openAbove ? 'top' : 'bottom',
326
+ gutter: 4,
327
+ sameWidth: true,
328
+ }}
323
329
  >
324
- <div className="relative">
325
- <Combobox.Input
326
- ref={inputRef}
327
- className={commonInputClass}
328
- placeholder="Select a code hook..."
329
- onBlur={handleBlur}
330
- />
331
- <Combobox.Trigger className="absolute inset-y-0 right-0 flex items-center pr-2">
332
- <ChevronUpDownIcon
333
- className="text-mydarkgrey h-5 w-5"
334
- aria-hidden="true"
330
+ <Combobox.Control ref={comboboxRef}>
331
+ <div className="relative">
332
+ <Combobox.Input
333
+ className={commonInputClass}
334
+ placeholder="Select a code hook..."
335
+ onBlur={handleBlur}
335
336
  />
336
- </Combobox.Trigger>
337
- </div>
338
-
339
- <Combobox.Content className="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
340
- {collection.items.length === 0 ? (
341
- <div className="text-mydarkgrey relative cursor-default select-none px-4 py-2">
342
- Nothing found.
343
- </div>
344
- ) : (
345
- collection.items.map((hook) => (
346
- <Combobox.Item
347
- key={hook}
348
- item={hook}
349
- className="codehook-item relative cursor-default select-none py-2 pl-10 pr-4"
350
- >
351
- <span className="block truncate">{hook}</span>
352
- <span className="codehook-indicator absolute inset-y-0 left-0 flex items-center pl-3 text-cyan-600">
353
- <CheckIcon className="h-5 w-5" aria-hidden="true" />
354
- </span>
355
- </Combobox.Item>
356
- ))
357
- )}
358
- </Combobox.Content>
337
+ <Combobox.Trigger className="absolute inset-y-0 right-0 flex items-center pr-2">
338
+ <ChevronUpDownIcon
339
+ className="text-mydarkgrey h-5 w-5"
340
+ aria-hidden="true"
341
+ />
342
+ </Combobox.Trigger>
343
+ </div>
344
+ </Combobox.Control>
345
+
346
+ <Portal>
347
+ <Combobox.Positioner style={{ zIndex: 1002 }}>
348
+ <Combobox.Content className="z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm">
349
+ {collection.items.length === 0 ? (
350
+ <div className="text-mydarkgrey relative cursor-default select-none px-4 py-2">
351
+ Nothing found.
352
+ </div>
353
+ ) : (
354
+ collection.items.map((hook) => (
355
+ <Combobox.Item
356
+ key={hook}
357
+ item={hook}
358
+ className="codehook-item relative cursor-default select-none py-2 pl-10 pr-4"
359
+ >
360
+ <span className="block truncate">{hook}</span>
361
+ <span className="codehook-indicator absolute inset-y-0 left-0 flex items-center pl-3 text-cyan-600">
362
+ <CheckIcon className="h-5 w-5" aria-hidden="true" />
363
+ </span>
364
+ </Combobox.Item>
365
+ ))
366
+ )}
367
+ </Combobox.Content>
368
+ </Combobox.Positioner>
369
+ </Portal>
359
370
  </Combobox.Root>
360
371
  </div>
361
372
  {!isValidCodeHook && localTarget && (
@@ -1,5 +1,5 @@
1
- import { useEffect, useState, useCallback, useMemo } from 'react';
2
- import { Combobox } from '@ark-ui/react';
1
+ import { useEffect, useState, useCallback, useMemo, useRef } from 'react';
2
+ import { Combobox, Portal } from '@ark-ui/react';
3
3
  import { createListCollection } from '@ark-ui/react/collection';
4
4
  import ChevronUpDownIcon from '@heroicons/react/24/outline/ChevronUpDownIcon';
5
5
  import CheckIcon from '@heroicons/react/24/outline/CheckIcon';
@@ -10,6 +10,7 @@ import {
10
10
  } from '@/stores/storykeep';
11
11
  import { tailwindClasses } from '@/utils/compositor/tailwindClasses';
12
12
  import { isMarkdownPaneFragmentNode } from '@/utils/compositor/typeGuards';
13
+ import { useDropdownDirection } from '@/utils/helpers';
13
14
  import {
14
15
  tagTitles,
15
16
  type Tag,
@@ -126,6 +127,8 @@ const StyleElementPanelAdd = ({
126
127
  const [query, setQuery] = useState('');
127
128
  const [showAdvanced, setShowAdvanced] = useState(false);
128
129
  const [selectedStyle, setSelectedStyle] = useState<string | null>(null);
130
+ const comboboxRef = useRef<HTMLDivElement>(null);
131
+ const { openAbove } = useDropdownDirection(comboboxRef);
129
132
 
130
133
  if (
131
134
  !node ||
@@ -138,7 +141,6 @@ const StyleElementPanelAdd = ({
138
141
 
139
142
  const currentClasses = new Set<string>();
140
143
 
141
- // Get existing classes from default classes in parent
142
144
  if (parentNode.defaultClasses?.[node.tagName]) {
143
145
  const defaults = parentNode.defaultClasses[node.tagName];
144
146
  Object.keys(defaults.mobile).forEach((key) => currentClasses.add(key));
@@ -148,33 +150,26 @@ const StyleElementPanelAdd = ({
148
150
  Object.keys(defaults.desktop).forEach((key) => currentClasses.add(key));
149
151
  }
150
152
 
151
- // Get existing classes from override classes in node
152
153
  if (node.overrideClasses) {
153
154
  Object.values(node.overrideClasses).forEach((viewportClasses) => {
154
155
  Object.keys(viewportClasses).forEach((key) => currentClasses.add(key));
155
156
  });
156
157
  }
157
158
 
158
- // Get filtered styles based on query and existing classes
159
159
  const styles = getFilteredStyles(showAdvanced, currentClasses);
160
- const filteredStyles =
161
- query === ''
162
- ? styles
163
- : styles.filter(
164
- (style) =>
165
- style.title.toLowerCase().includes(query.toLowerCase()) ||
166
- style.key.toLowerCase().includes(query.toLowerCase())
167
- );
168
160
 
169
- // Create collection for Ark UI Combobox
170
161
  const collection = useMemo(
171
162
  () =>
172
163
  createListCollection({
173
- items: filteredStyles,
164
+ items: styles.filter(
165
+ (style) =>
166
+ style.title.toLowerCase().includes(query.toLowerCase()) ||
167
+ style.key.toLowerCase().includes(query.toLowerCase())
168
+ ),
174
169
  itemToValue: (item: StyleOption) => item.key,
175
170
  itemToString: (item: StyleOption) => item.title,
176
171
  }),
177
- [filteredStyles]
172
+ [styles, query]
178
173
  );
179
174
 
180
175
  const availableRecommendedStyles =
@@ -228,7 +223,6 @@ const StyleElementPanelAdd = ({
228
223
  };
229
224
  }, [parentNode.id, node.tagName]);
230
225
 
231
- // CSS to properly style the combobox items with hover and selection
232
226
  const comboboxItemStyles = `
233
227
  .style-item[data-highlighted] {
234
228
  background-color: #0891b2; /* bg-cyan-600 */
@@ -283,46 +277,57 @@ const StyleElementPanelAdd = ({
283
277
  loopFocus={true}
284
278
  openOnKeyPress={true}
285
279
  composite={true}
280
+ positioning={{
281
+ placement: openAbove ? 'top' : 'bottom',
282
+ gutter: 4,
283
+ sameWidth: true,
284
+ }}
286
285
  >
287
- <div className="relative">
288
- <Combobox.Input
289
- className="border-mydarkgrey focus:border-myblue focus:ring-myblue w-full rounded-md py-2 pl-3 pr-10 text-xl shadow-sm"
290
- onChange={(e) => setQuery(e.target.value)}
291
- placeholder="Search styles..."
292
- />
293
- <Combobox.Trigger className="absolute inset-y-0 right-0 flex items-center pr-2">
294
- <ChevronUpDownIcon
295
- className="text-mydarkgrey h-5 w-5"
296
- aria-hidden="true"
286
+ <Combobox.Control ref={comboboxRef}>
287
+ <div className="relative">
288
+ <Combobox.Input
289
+ className="border-mydarkgrey focus:border-myblue focus:ring-myblue w-full rounded-md py-2 pl-3 pr-10 text-xl shadow-sm"
290
+ onChange={(e) => setQuery(e.target.value)}
291
+ placeholder="Search styles..."
297
292
  />
298
- </Combobox.Trigger>
299
- </div>
293
+ <Combobox.Trigger className="absolute inset-y-0 right-0 flex items-center pr-2">
294
+ <ChevronUpDownIcon
295
+ className="text-mydarkgrey h-5 w-5"
296
+ aria-hidden="true"
297
+ />
298
+ </Combobox.Trigger>
299
+ </div>
300
+ </Combobox.Control>
300
301
 
301
- <Combobox.Content className="absolute z-50 mt-1 max-h-64 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
302
- {collection.items.length === 0 ? (
303
- <div className="text-mydarkgrey relative cursor-default select-none px-4 py-2">
304
- Nothing found.
305
- </div>
306
- ) : (
307
- collection.items.map((style) => (
308
- <Combobox.Item
309
- key={style.key}
310
- item={style}
311
- className="style-item relative cursor-default select-none py-2 pl-10 pr-4 text-black"
312
- >
313
- <span className="block truncate">
314
- {style.title}
315
- <span className="ml-2 text-sm opacity-60">
316
- {style.className}
317
- </span>
318
- </span>
319
- <span className="style-indicator absolute inset-y-0 left-0 flex items-center pl-3 text-cyan-600">
320
- <CheckIcon className="h-5 w-5" aria-hidden="true" />
321
- </span>
322
- </Combobox.Item>
323
- ))
324
- )}
325
- </Combobox.Content>
302
+ <Portal>
303
+ <Combobox.Positioner style={{ zIndex: 1002 }}>
304
+ <Combobox.Content className="max-h-64 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
305
+ {collection.items.length === 0 ? (
306
+ <div className="text-mydarkgrey relative cursor-default select-none px-4 py-2">
307
+ Nothing found.
308
+ </div>
309
+ ) : (
310
+ collection.items.map((style) => (
311
+ <Combobox.Item
312
+ key={style.key}
313
+ item={style}
314
+ className="style-item relative cursor-default select-none py-2 pl-10 pr-4 text-black"
315
+ >
316
+ <span className="block truncate">
317
+ {style.title}
318
+ <span className="ml-2 text-sm opacity-60">
319
+ {style.className}
320
+ </span>
321
+ </span>
322
+ <span className="style-indicator absolute inset-y-0 left-0 flex items-center pl-3 text-cyan-600">
323
+ <CheckIcon className="h-5 w-5" aria-hidden="true" />
324
+ </span>
325
+ </Combobox.Item>
326
+ ))
327
+ )}
328
+ </Combobox.Content>
329
+ </Combobox.Positioner>
330
+ </Portal>
326
331
  </Combobox.Root>
327
332
  </div>
328
333
 
@@ -1,5 +1,5 @@
1
- import { useState, useCallback, useMemo } from 'react';
2
- import { Combobox } from '@ark-ui/react';
1
+ import { useState, useCallback, useMemo, useRef } from 'react';
2
+ import { Combobox, Portal } from '@ark-ui/react';
3
3
  import { createListCollection } from '@ark-ui/react/collection';
4
4
  import ChevronUpDownIcon from '@heroicons/react/24/outline/ChevronUpDownIcon';
5
5
  import CheckIcon from '@heroicons/react/24/outline/CheckIcon';
@@ -7,6 +7,7 @@ import { settingsPanelStore } from '@/stores/storykeep';
7
7
  import { getCtx } from '@/stores/nodes';
8
8
  import { tailwindClasses } from '@/utils/compositor/tailwindClasses';
9
9
  import { isMarkdownPaneFragmentNode } from '@/utils/compositor/typeGuards';
10
+ import { useDropdownDirection } from '@/utils/helpers';
10
11
  import type { BasePanelProps } from '@/types/compositorTypes';
11
12
 
12
13
  // Recommended styles for images
@@ -73,6 +74,8 @@ const StyleImagePanelAdd = ({ node, parentNode, childId }: BasePanelProps) => {
73
74
  const [query, setQuery] = useState('');
74
75
  const [showAdvanced, setShowAdvanced] = useState(false);
75
76
  const [selectedStyle, setSelectedStyle] = useState<string | null>(null);
77
+ const comboboxRef = useRef<HTMLDivElement>(null);
78
+ const { openAbove } = useDropdownDirection(comboboxRef);
76
79
 
77
80
  if (!node?.tagName || !parentNode || !isMarkdownPaneFragmentNode(parentNode))
78
81
  return null;
@@ -84,13 +87,11 @@ const StyleImagePanelAdd = ({ node, parentNode, childId }: BasePanelProps) => {
84
87
  const ctx = getCtx();
85
88
  const allNodes = ctx.allNodes.get();
86
89
 
87
- // When styling container or outer container, use their IDs directly
88
90
  const targetNode = allNodes.get(node.id);
89
91
  if (!targetNode) return null;
90
92
 
91
93
  const currentClasses = new Set<string>();
92
94
 
93
- // Get existing classes from default classes in parent for THIS element type
94
95
  if (parentNode.defaultClasses?.[node.tagName]) {
95
96
  const defaults = parentNode.defaultClasses[node.tagName];
96
97
  Object.keys(defaults.mobile).forEach((key) => currentClasses.add(key));
@@ -100,14 +101,12 @@ const StyleImagePanelAdd = ({ node, parentNode, childId }: BasePanelProps) => {
100
101
  Object.keys(defaults.desktop).forEach((key) => currentClasses.add(key));
101
102
  }
102
103
 
103
- // Get existing override classes for THIS element
104
104
  if (`overrideClasses` in targetNode && targetNode.overrideClasses) {
105
105
  Object.values(targetNode.overrideClasses).forEach((viewportClasses) => {
106
106
  Object.keys(viewportClasses).forEach((key) => currentClasses.add(key));
107
107
  });
108
108
  }
109
109
 
110
- // Create collection for combobox with filtered styles
111
110
  const styles = getFilteredStyles(showAdvanced, currentClasses);
112
111
  const filteredStyles =
113
112
  query === ''
@@ -118,7 +117,6 @@ const StyleImagePanelAdd = ({ node, parentNode, childId }: BasePanelProps) => {
118
117
  style.key.toLowerCase().includes(query.toLowerCase())
119
118
  );
120
119
 
121
- // Create collection for Ark UI Combobox
122
120
  const collection = useMemo(() => {
123
121
  return createListCollection({
124
122
  items: filteredStyles,
@@ -127,7 +125,6 @@ const StyleImagePanelAdd = ({ node, parentNode, childId }: BasePanelProps) => {
127
125
  });
128
126
  }, [filteredStyles]);
129
127
 
130
- // Get appropriate recommended styles based on element type
131
128
  const recommendedStyles = isOuterContainer
132
129
  ? OUTER_CONTAINER_STYLES
133
130
  : isContainer
@@ -151,7 +148,7 @@ const StyleImagePanelAdd = ({ node, parentNode, childId }: BasePanelProps) => {
151
148
  ? 'style-img-container-update'
152
149
  : 'style-img-update',
153
150
  nodeId: node.id,
154
- childId, // Preserve childId for container context
151
+ childId,
155
152
  className: styleKey,
156
153
  expanded: true,
157
154
  });
@@ -160,10 +157,9 @@ const StyleImagePanelAdd = ({ node, parentNode, childId }: BasePanelProps) => {
160
157
  );
161
158
 
162
159
  const handleCancel = () => {
163
- // Return to main panel with correct context
164
160
  settingsPanelStore.set({
165
161
  action: 'style-image',
166
- nodeId: childId || node.id, // Use childId when available for context
162
+ nodeId: childId || node.id,
167
163
  expanded: true,
168
164
  });
169
165
  };
@@ -174,7 +170,6 @@ const StyleImagePanelAdd = ({ node, parentNode, childId }: BasePanelProps) => {
174
170
  ? 'Container'
175
171
  : 'Image';
176
172
 
177
- // CSS to properly style the combobox items with hover and selection
178
173
  const comboboxItemStyles = `
179
174
  .style-item[data-highlighted] {
180
175
  background-color: #0891b2; /* bg-cyan-600 */
@@ -230,46 +225,57 @@ const StyleImagePanelAdd = ({ node, parentNode, childId }: BasePanelProps) => {
230
225
  loopFocus={true}
231
226
  openOnKeyPress={true}
232
227
  composite={true}
228
+ positioning={{
229
+ placement: openAbove ? 'top' : 'bottom',
230
+ gutter: 4,
231
+ sameWidth: true,
232
+ }}
233
233
  >
234
- <div className="relative">
235
- <Combobox.Input
236
- className="border-mydarkgrey focus:border-myblue focus:ring-myblue w-full rounded-md py-2 pl-3 pr-10 text-xl shadow-sm"
237
- onChange={(e) => setQuery(e.target.value)}
238
- placeholder="Search styles..."
239
- />
240
- <Combobox.Trigger className="absolute inset-y-0 right-0 flex items-center pr-2">
241
- <ChevronUpDownIcon
242
- className="text-mydarkgrey h-5 w-5"
243
- aria-hidden="true"
234
+ <Combobox.Control ref={comboboxRef}>
235
+ <div className="relative">
236
+ <Combobox.Input
237
+ className="border-mydarkgrey focus:border-myblue focus:ring-myblue w-full rounded-md py-2 pl-3 pr-10 text-xl shadow-sm"
238
+ onChange={(e) => setQuery(e.target.value)}
239
+ placeholder="Search styles..."
244
240
  />
245
- </Combobox.Trigger>
246
- </div>
241
+ <Combobox.Trigger className="absolute inset-y-0 right-0 flex items-center pr-2">
242
+ <ChevronUpDownIcon
243
+ className="text-mydarkgrey h-5 w-5"
244
+ aria-hidden="true"
245
+ />
246
+ </Combobox.Trigger>
247
+ </div>
248
+ </Combobox.Control>
247
249
 
248
- <Combobox.Content className="absolute z-50 mt-1 max-h-64 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
249
- {collection.items.length === 0 ? (
250
- <div className="text-mydarkgrey relative cursor-default select-none px-4 py-2">
251
- Nothing found.
252
- </div>
253
- ) : (
254
- collection.items.map((style) => (
255
- <Combobox.Item
256
- key={style.key}
257
- item={style}
258
- className="style-item relative cursor-default select-none py-2 pl-10 pr-4 text-black"
259
- >
260
- <span className="block truncate">
261
- {style.title}
262
- <span className="ml-2 text-sm opacity-60">
263
- {style.className}
264
- </span>
265
- </span>
266
- <span className="style-indicator absolute inset-y-0 left-0 flex items-center pl-3 text-cyan-600">
267
- <CheckIcon className="h-5 w-5" aria-hidden="true" />
268
- </span>
269
- </Combobox.Item>
270
- ))
271
- )}
272
- </Combobox.Content>
250
+ <Portal>
251
+ <Combobox.Positioner style={{ zIndex: 1002 }}>
252
+ <Combobox.Content className="max-h-64 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
253
+ {collection.items.length === 0 ? (
254
+ <div className="text-mydarkgrey relative cursor-default select-none px-4 py-2">
255
+ Nothing found.
256
+ </div>
257
+ ) : (
258
+ collection.items.map((style) => (
259
+ <Combobox.Item
260
+ key={style.key}
261
+ item={style}
262
+ className="style-item relative cursor-default select-none py-2 pl-10 pr-4 text-black"
263
+ >
264
+ <span className="block truncate">
265
+ {style.title}
266
+ <span className="ml-2 text-sm opacity-60">
267
+ {style.className}
268
+ </span>
269
+ </span>
270
+ <span className="style-indicator absolute inset-y-0 left-0 flex items-center pl-3 text-cyan-600">
271
+ <CheckIcon className="h-5 w-5" aria-hidden="true" />
272
+ </span>
273
+ </Combobox.Item>
274
+ ))
275
+ )}
276
+ </Combobox.Content>
277
+ </Combobox.Positioner>
278
+ </Portal>
273
279
  </Combobox.Root>
274
280
  </div>
275
281