@iress-oss/ids-mcp-server 0.0.1-dev.4 → 0.0.1-dev.6

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.
@@ -274,6 +274,79 @@ export const SelectAsync \= () \=> (
274
274
 
275
275
  Copy
276
276
 
277
+ ### [](#minimum-search-length-for-async-options)Minimum search length for async options
278
+
279
+ When using asynchronous options, you can set a minimum number of characters required before triggering the search using the `minSearchLength` prop. This prevents unnecessary API calls and loading states for very short queries.
280
+
281
+ By default, async searches are triggered after 1 character. Setting a higher value (e.g., 3) means no search request will be made and no loading spinner will appear until the user types at least that many characters.
282
+
283
+ Default behavior (1 character)
284
+
285
+ Type any character...
286
+
287
+ Search requires 3+ characters
288
+
289
+ Type at least 3 characters...
290
+
291
+ Hide code
292
+
293
+ \[data-radix-scroll-area-viewport\] { scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; } \[data-radix-scroll-area-viewport\]::-webkit-scrollbar { display: none; } :where(\[data-radix-scroll-area-viewport\]) { display: flex; flex-direction: column; align-items: stretch; } :where(\[data-radix-scroll-area-content\]) { flex-grow: 1; }
294
+
295
+ interface StarWarsCharacter {
296
+ name: string;
297
+ gender: string;
298
+ }
299
+ interface StarWarsCharacterApi {
300
+ results: StarWarsCharacter\[\];
301
+ }
302
+ const options \= async (query: string) \=> {
303
+ if (!query) return \[\];
304
+ if (query \=== 'error') {
305
+ throw new Error();
306
+ }
307
+ const data \= await fetch(
308
+ \`https://swapi.py4e.com/api/people/?search=${query}\`,
309
+ ).then((response) \=> response.json() as Promise<StarWarsCharacterApi\>);
310
+ return data.results.map((character: StarWarsCharacter) \=> ({
311
+ label: character.name,
312
+ value: character.name,
313
+ meta: character.gender,
314
+ }));
315
+ };
316
+ export const SelectAsyncMinLength \= () \=> (
317
+ <IressRow gutter\="md"\>
318
+ <IressCol\>
319
+ <IressField
320
+ label\="Default behavior (1 character)"
321
+ htmlFor\="default-select"
322
+ \>
323
+ <IressRichSelect
324
+ container\={document.body}
325
+ options\={options}
326
+ id\="default-select"
327
+ placeholder\="Type any character..."
328
+ />
329
+ </IressField\>
330
+ </IressCol\>
331
+ <IressCol\>
332
+ <IressField
333
+ label\="Search requires 3+ characters"
334
+ htmlFor\="min-length-select"
335
+ \>
336
+ <IressRichSelect
337
+ container\={document.body}
338
+ options\={options}
339
+ id\="min-length-select"
340
+ minSearchLength\={3}
341
+ placeholder\="Type at least 3 characters..."
342
+ />
343
+ </IressField\>
344
+ </IressCol\>
345
+ </IressRow\>
346
+ );
347
+
348
+ Copy
349
+
277
350
  ### [](#initial-options)Initial options
278
351
 
279
352
  If you are using asynchronous options, you can provide an initial set of options to display before the user has interacted with the select using the `initialOptions` prop.
@@ -307,6 +380,200 @@ export const SelectInitialOptions \= () \=> (
307
380
 
308
381
  Copy
309
382
 
383
+ ### [](#long-text-content-in-select-options)Long text content in select options
384
+
385
+ When working with options that contain long text content, you can control how the dropdown width behaves using the `matchActivatorWidth` prop.
386
+
387
+ By default (`matchActivatorWidth={true}`), the dropdown width matches the width of the select input, which constrains long text content and may cause truncation. This is ideal for consistent layouts where you want the dropdown to align with the input size.
388
+
389
+ Setting `matchActivatorWidth={false}` allows the dropdown to expand to accommodate the content width, which is useful when displaying long option labels or when content readability is more important than layout consistency.
390
+
391
+ This example demonstrates both single-select and multi-select behavior with long text content, allowing you to toggle between the two width behaviors to see the difference.
392
+
393
+ **matchActivatorWidth: True**
394
+
395
+ Match input width (default)
396
+
397
+ Single select with long text
398
+
399
+ Type anything to start search
400
+
401
+ Multi-select with long text
402
+
403
+ Type anything to start search
404
+
405
+ Selected: None
406
+
407
+ Hide code
408
+
409
+ \[data-radix-scroll-area-viewport\] { scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; } \[data-radix-scroll-area-viewport\]::-webkit-scrollbar { display: none; } :where(\[data-radix-scroll-area-viewport\]) { display: flex; flex-direction: column; align-items: stretch; } :where(\[data-radix-scroll-area-content\]) { flex-grow: 1; }
410
+
411
+ interface LongTextItem {
412
+ id: string;
413
+ title: string;
414
+ description: string;
415
+ category: string;
416
+ }
417
+ // Mock data with long text content
418
+ const longTextItems: LongTextItem\[\] \= \[
419
+ {
420
+ id: '1',
421
+ title:
422
+ 'Strategic Enterprise Architecture Implementation and Digital Transformation Framework',
423
+ description:
424
+ 'A comprehensive approach to modernizing legacy systems while maintaining operational continuity across multiple business units and geographical locations with complex regulatory requirements',
425
+ category: 'Enterprise Solutions',
426
+ },
427
+ {
428
+ id: '2',
429
+ title:
430
+ 'Advanced Machine Learning Pipeline for Predictive Analytics in Financial Services',
431
+ description:
432
+ 'Implementation of sophisticated algorithms for risk assessment, fraud detection, and customer behavior analysis using neural networks and deep learning methodologies',
433
+ category: 'Artificial Intelligence',
434
+ },
435
+ {
436
+ id: '3',
437
+ title:
438
+ 'Cloud-Native Microservices Architecture with Containerized Deployment Strategy',
439
+ description:
440
+ 'Scalable distributed system design utilizing Kubernetes orchestration, service mesh technology, and automated CI/CD pipelines for high-availability applications',
441
+ category: 'Cloud Computing',
442
+ },
443
+ {
444
+ id: '4',
445
+ title:
446
+ 'Cybersecurity Framework for Multi-Tenant SaaS Applications with Zero-Trust Architecture',
447
+ description:
448
+ 'Comprehensive security implementation including identity management, threat detection, vulnerability assessment, and compliance monitoring for enterprise-grade applications',
449
+ category: 'Security',
450
+ },
451
+ {
452
+ id: '5',
453
+ title:
454
+ 'Real-Time Data Processing and Analytics Platform for Internet of Things Devices',
455
+ description:
456
+ 'High-throughput data ingestion and processing system capable of handling millions of sensor readings per second with edge computing capabilities',
457
+ category: 'IoT & Analytics',
458
+ },
459
+ {
460
+ id: '6',
461
+ title:
462
+ 'Blockchain-Based Supply Chain Management System with Smart Contract Integration',
463
+ description:
464
+ 'Decentralized tracking and verification system ensuring transparency, authenticity, and compliance throughout the entire supply chain lifecycle',
465
+ category: 'Blockchain',
466
+ },
467
+ {
468
+ id: '7',
469
+ title:
470
+ 'Advanced Natural Language Processing Engine for Document Analysis and Information Extraction',
471
+ description:
472
+ 'AI-powered system for parsing complex documents, extracting key information, and generating automated summaries with multi-language support',
473
+ category: 'Natural Language Processing',
474
+ },
475
+ {
476
+ id: '8',
477
+ title:
478
+ 'Augmented Reality Mobile Application Development for Industrial Training and Maintenance',
479
+ description:
480
+ 'Immersive training platform utilizing AR technology to provide hands-on learning experiences for complex machinery operation and maintenance procedures',
481
+ category: 'Augmented Reality',
482
+ },
483
+ {
484
+ id: '9',
485
+ title:
486
+ 'High-Performance Computing Cluster for Scientific Research and Mathematical Modeling',
487
+ description:
488
+ 'Parallel processing infrastructure designed for complex simulations, weather modeling, genome sequencing, and other computationally intensive research applications',
489
+ category: 'High Performance Computing',
490
+ },
491
+ {
492
+ id: '10',
493
+ title:
494
+ 'Automated DevSecOps Pipeline with Continuous Security Testing and Compliance Monitoring',
495
+ description:
496
+ 'Integrated development and operations workflow incorporating security scanning, vulnerability assessment, and regulatory compliance checks at every stage',
497
+ category: 'DevSecOps',
498
+ },
499
+ \];
500
+ const options \= async (query: string) \=> {
501
+ // Simulate network delay
502
+ await new Promise((resolve) \=> setTimeout(resolve, 300));
503
+ if (!query) return \[\];
504
+ if (query \=== 'error') {
505
+ throw new Error('Simulated search error');
506
+ }
507
+ // Filter items based on search query (case-insensitive)
508
+ const filteredItems \= longTextItems.filter(
509
+ (item) \=>
510
+ item.title.toLowerCase().includes(query.toLowerCase()) ||
511
+ item.description.toLowerCase().includes(query.toLowerCase()) ||
512
+ item.category.toLowerCase().includes(query.toLowerCase()),
513
+ );
514
+ return filteredItems.map((item) \=> ({
515
+ label: item.title,
516
+ value: item.id,
517
+ meta: item.category,
518
+ // Include description in a data attribute for potential tooltip use
519
+ description: item.description,
520
+ }));
521
+ };
522
+ export const SelectOptionLongText \= () \=> {
523
+ const \[matchActivatorWidth, setMatchActivatorWidth\] \= useState(true);
524
+ return (
525
+ <IressStack gutter\="md"\>
526
+ <IressField
527
+ label\={\`matchActivatorWidth: ${matchActivatorWidth ? 'True' : 'False'}\`}
528
+ \>
529
+ <IressToggle
530
+ checked\={matchActivatorWidth}
531
+ onChange\={setMatchActivatorWidth}
532
+ \>
533
+ <IressText\>
534
+ {matchActivatorWidth
535
+ ? 'Match input width (default)'
536
+ : 'Auto-size to content'}
537
+ </IressText\>
538
+ </IressToggle\>
539
+ </IressField\>
540
+ <div style\={{ display: 'flex', gap: '1rem' }}\>
541
+ <div style\={{ width: '400px' }}\>
542
+ <IressField
543
+ label\="Single select with long text"
544
+ htmlFor\="single-select-long"
545
+ \>
546
+ <IressRichSelect
547
+ container\={document.body}
548
+ options\={options}
549
+ id\="single-select-long"
550
+ placeholder\="Type anything to start search"
551
+ matchActivatorWidth\={matchActivatorWidth}
552
+ />
553
+ </IressField\>
554
+ </div\>
555
+ <div style\={{ width: '400px' }}\>
556
+ <IressField
557
+ label\="Multi-select with long text"
558
+ htmlFor\="multi-select-long"
559
+ \>
560
+ <IressRichSelect
561
+ container\={document.body}
562
+ options\={options}
563
+ id\="multi-select-long"
564
+ multiSelect
565
+ placeholder\="Type anything to start search"
566
+ matchActivatorWidth\={matchActivatorWidth}
567
+ />
568
+ </IressField\>
569
+ </div\>
570
+ </div\>
571
+ </IressStack\>
572
+ );
573
+ };
574
+
575
+ Copy
576
+
310
577
  ### [](#sizing)Sizing
311
578
 
312
579
  Rich selects can be resized to suit a specific number of characters. This sets an expectation of what data is to be presented; for example using the `16` width for a credit card number.
@@ -1205,6 +1472,57 @@ Hide code
1205
1472
 
1206
1473
  Copy
1207
1474
 
1475
+ ### [](#reactive-footer)Reactive footer
1476
+
1477
+ You can also make the footer reactive to the search results by using the `renderOptionsFooter` prop. It expects a function that returns a ReactNode.
1478
+
1479
+ Has a custom footer that uses render props
1480
+
1481
+ Hide code
1482
+
1483
+ \[data-radix-scroll-area-viewport\] { scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; } \[data-radix-scroll-area-viewport\]::-webkit-scrollbar { display: none; } :where(\[data-radix-scroll-area-viewport\]) { display: flex; flex-direction: column; align-items: stretch; } :where(\[data-radix-scroll-area-content\]) { flex-grow: 1; }
1484
+
1485
+ interface StarWarsCharacter {
1486
+ name: string;
1487
+ gender: string;
1488
+ }
1489
+ interface StarWarsCharacterApi {
1490
+ results: StarWarsCharacter\[\];
1491
+ }
1492
+ const options \= async (query: string) \=> {
1493
+ if (!query) return \[\];
1494
+ if (query \=== 'error') {
1495
+ throw new Error();
1496
+ }
1497
+ const data \= await fetch(
1498
+ \`https://swapi.py4e.com/api/people/?search=${query}\`,
1499
+ ).then((response) \=> response.json() as Promise<StarWarsCharacterApi\>);
1500
+ return data.results.map((character: StarWarsCharacter) \=> ({
1501
+ label: character.name,
1502
+ value: character.name,
1503
+ meta: character.gender,
1504
+ }));
1505
+ };
1506
+ export const SelectOptionsFooter \= () \=> (
1507
+ <IressField
1508
+ label\="Has a custom footer that uses render props"
1509
+ htmlFor\="single-select"
1510
+ \>
1511
+ <IressRichSelect
1512
+ container\={document.body}
1513
+ options\={options}
1514
+ id\="single-select"
1515
+ renderOptionsFooter\={({ results }) \=>
1516
+ results.length \> 0 && (
1517
+ <IressPanel noBorderRadius\>Found {results.length} results</IressPanel\>
1518
+ )
1519
+ }
1520
+ />
1521
+ </IressField\>
1522
+ );
1523
+
1524
+ Copy
1525
+
1208
1526
  ### [](#readonly)Readonly
1209
1527
 
1210
1528
  The `readonly` prop can be set to `true` to prevent the user from changing the value of the select. This will change the select to a custom read-only style, and will display multiple values seperated with a comma.
@@ -1319,7 +1637,7 @@ These are completely optional, the default behaviour should be sufficient for mo
1319
1637
 
1320
1638
  Below is a mapping of the available sub-components to the previous [Create new option example](#create-new-option).
1321
1639
 
1322
- ![](/@fs/app/packages/components/src/components/RichSelect/assets/ids-rich-select--sub-component-mapping.svg)
1640
+ ![](/@fs/workspace/packages/components/src/components/RichSelect/assets/ids-rich-select--sub-component-mapping.svg)
1323
1641
 
1324
1642
  ### [](#iressselectbody)IressSelectBody
1325
1643
 
@@ -2413,12 +2731,15 @@ On this page
2413
2731
  * [Single select](#single-select)
2414
2732
  * [Multi-select](#multi-select)
2415
2733
  * [Asynchronous options](#asynchronous-options)
2734
+ * [Minimum search length for async options](#minimum-search-length-for-async-options)
2416
2735
  * [Initial options](#initial-options)
2736
+ * [Long text content in select options](#long-text-content-in-select-options)
2417
2737
  * [Sizing](#sizing)
2418
2738
  * [Custom label](#custom-label)
2419
2739
  * [Custom options](#custom-options)
2420
2740
  * [Create new option](#create-new-option)
2421
2741
  * [Header and Footer](#header-and-footer)
2742
+ * [Reactive footer](#reactive-footer)
2422
2743
  * [Readonly](#readonly)
2423
2744
  * [Sub-components](#sub-components)
2424
2745
  * [IressSelectBody](#iressselectbody)
@@ -749,7 +749,7 @@ Hide code
749
749
  <IressText element\="h2"\>
750
750
  Vertical align: top </IressText\>
751
751
  <IressRow
752
- className\="ids-styles--set-height-v5150"
752
+ className\="ids-styles--set-height-v5200"
753
753
  verticalAlign\="top"
754
754
  \>
755
755
  <React.Fragment key\=".0"\>
@@ -778,7 +778,7 @@ Hide code
778
778
  <IressText element\="h2"\>
779
779
  Vertical align: middle </IressText\>
780
780
  <IressRow
781
- className\="ids-styles--set-height-v5150"
781
+ className\="ids-styles--set-height-v5200"
782
782
  verticalAlign\="middle"
783
783
  \>
784
784
  <React.Fragment key\=".0"\>
@@ -807,7 +807,7 @@ Hide code
807
807
  <IressText element\="h2"\>
808
808
  Vertical align: bottom </IressText\>
809
809
  <IressRow
810
- className\="ids-styles--set-height-v5150"
810
+ className\="ids-styles--set-height-v5200"
811
811
  verticalAlign\="bottom"
812
812
  \>
813
813
  <React.Fragment key\=".0"\>
@@ -836,7 +836,7 @@ Hide code
836
836
  <IressText element\="h2"\>
837
837
  Vertical align: stretch </IressText\>
838
838
  <IressRow
839
- className\="ids-styles--set-height-v5150"
839
+ className\="ids-styles--set-height-v5200"
840
840
  verticalAlign\="stretch"
841
841
  \>
842
842
  <React.Fragment key\=".0"\>
@@ -25,7 +25,7 @@ Hide code
25
25
  }}
26
26
  />
27
27
  <main
28
- className\="iress-u-container iress-u-text iress-u-panel ids-styles--highlight-on-focus-v5150"
28
+ className\="iress-u-container iress-u-text iress-u-panel ids-styles--highlight-on-focus-v5200"
29
29
  id\="main"
30
30
  tabIndex\={\-1}
31
31
  \>