@delightui/components 0.1.113 → 0.1.115

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/index.d.ts CHANGED
@@ -313,6 +313,8 @@ type FormProviderProps<T extends FormState = FormState> = {
313
313
  formValidator?: FormValidator<T>;
314
314
  onSubmit?: FormSubmitHandler<T>;
315
315
  validateOnChange?: boolean;
316
+ autosave?: boolean;
317
+ autosaveDelayMs?: number;
316
318
  };
317
319
 
318
320
  /**
@@ -1245,7 +1247,7 @@ type ListProps<T extends ListItemType> = Omit<HTMLAttributes<HTMLUListElement>,
1245
1247
  * @param data
1246
1248
  * @returns
1247
1249
  */
1248
- updateSortOrder?: (data: T[]) => void;
1250
+ updateSortOrder?: (data: T[], oldIndex: number, newIndex: number) => void;
1249
1251
  };
1250
1252
 
1251
1253
  /**
@@ -24,7 +24,7 @@ A flexible list component that renders collections of data with support for cust
24
24
  | `wrap` | `boolean` | - | No | Whether list content should wrap |
25
25
  | `align` | `'Horizontal' \| 'Vertical'` | `'Vertical'` | No | Layout direction for the list |
26
26
  | `sortable` | `boolean` | - | No | Enable drag-and-drop sorting |
27
- | `updateSortOrder` | `(data: T[]) => void` | - | No | Callback when sort order changes |
27
+ | `updateSortOrder` | `(data: T[], oldIndex: number, newIndex: number) => void` | - | No | Callback when sort order changes |
28
28
  | `className` | `string` | - | No | Additional CSS class names |
29
29
 
30
30
  Plus all standard HTML ul attributes (role, aria-*, data-*, etc.).
@@ -26,7 +26,7 @@ A navigation link component that handles both internal routing and external link
26
26
  | `leadingIcon` | `ReactNode` | - | No | Icon displayed before the link text |
27
27
  | `trailingIcon` | `ReactNode` | - | No | Icon displayed after the link text |
28
28
  | `component-variant` | `string` | - | No | Override styling variant |
29
- | `children` | `ReactNode` | - | Yes | Link content (text, icons, etc.) |
29
+ | `children` | `ReactNode` | - | Yes | Link content (text, icons, components like cards, etc.) |
30
30
 
31
31
  Plus all React Router Link props and Button styling props.
32
32
 
@@ -496,4 +496,158 @@ function LoadingStateLinksExample() {
496
496
  </div>
497
497
  );
498
498
  }
499
+ ```
500
+
501
+ ### Wrapping Complex Components (Cards)
502
+ ```tsx
503
+ function CardNavigationExample() {
504
+ const dashboardCards = [
505
+ {
506
+ id: 'analytics',
507
+ title: 'Analytics Dashboard',
508
+ description: 'View detailed analytics and metrics',
509
+ icon: 'BarChart',
510
+ path: '/dashboard/analytics'
511
+ },
512
+ {
513
+ id: 'users',
514
+ title: 'User Management',
515
+ description: 'Manage users and permissions',
516
+ icon: 'People',
517
+ path: '/dashboard/users'
518
+ },
519
+ {
520
+ id: 'settings',
521
+ title: 'System Settings',
522
+ description: 'Configure application settings',
523
+ icon: 'Settings',
524
+ path: '/dashboard/settings'
525
+ }
526
+ ];
527
+
528
+ return (
529
+ <div className="card-navigation-grid">
530
+ {dashboardCards.map(card => (
531
+ <NavLink key={card.id} to={card.path} className="card-nav-link">
532
+ <Card className="dashboard-card">
533
+ <CardHeader>
534
+ <Icon icon={card.icon} size="Large" />
535
+ <Text type="Heading4">{card.title}</Text>
536
+ </CardHeader>
537
+ <CardContent>
538
+ <Text type="Body">{card.description}</Text>
539
+ </CardContent>
540
+ </Card>
541
+ </NavLink>
542
+ ))}
543
+ </div>
544
+ );
545
+ }
546
+ ```
547
+
548
+ ### Wrapping Complex Components (List Items)
549
+ ```tsx
550
+ function NavigableListExample() {
551
+ const projectItems = [
552
+ {
553
+ id: 1,
554
+ name: 'E-commerce Platform',
555
+ status: 'Active',
556
+ lastUpdated: '2024-01-15',
557
+ path: '/projects/ecommerce'
558
+ },
559
+ {
560
+ id: 2,
561
+ name: 'Mobile App Redesign',
562
+ status: 'In Progress',
563
+ lastUpdated: '2024-01-14',
564
+ path: '/projects/mobile-app'
565
+ },
566
+ {
567
+ id: 3,
568
+ name: 'Analytics Dashboard',
569
+ status: 'Completed',
570
+ lastUpdated: '2024-01-10',
571
+ path: '/projects/analytics'
572
+ }
573
+ ];
574
+
575
+ return (
576
+ <div className="navigable-list">
577
+ {projectItems.map(project => (
578
+ <NavLink key={project.id} to={project.path} className="list-nav-link">
579
+ <ListItem className="project-item">
580
+ <ListItemContent>
581
+ <div className="project-header">
582
+ <Text type="Heading5">{project.name}</Text>
583
+ <Chip type={project.status === 'Active' ? 'Success' : 'Default'}>
584
+ {project.status}
585
+ </Chip>
586
+ </div>
587
+ <Text type="BodySmall" className="project-date">
588
+ Last updated: {project.lastUpdated}
589
+ </Text>
590
+ </ListItemContent>
591
+ <ListItemAction>
592
+ <Icon icon="ChevronRight" />
593
+ </ListItemAction>
594
+ </ListItem>
595
+ </NavLink>
596
+ ))}
597
+ </div>
598
+ );
599
+ }
600
+ ```
601
+
602
+ ### Wrapping Complex Components (Panels)
603
+ ```tsx
604
+ function PanelNavigationExample() {
605
+ const toolPanels = [
606
+ {
607
+ id: 'editor',
608
+ title: 'Code Editor',
609
+ description: 'Edit and manage your code files',
610
+ icon: 'Code',
611
+ path: '/tools/editor',
612
+ isActive: true
613
+ },
614
+ {
615
+ id: 'debugger',
616
+ title: 'Debugger',
617
+ description: 'Debug and troubleshoot your applications',
618
+ icon: 'Bug',
619
+ path: '/tools/debugger',
620
+ isActive: false
621
+ },
622
+ {
623
+ id: 'terminal',
624
+ title: 'Terminal',
625
+ description: 'Access command line interface',
626
+ icon: 'Terminal',
627
+ path: '/tools/terminal',
628
+ isActive: false
629
+ }
630
+ ];
631
+
632
+ return (
633
+ <div className="panel-navigation">
634
+ {toolPanels.map(panel => (
635
+ <NavLink key={panel.id} to={panel.path} className="panel-nav-link">
636
+ <Panel className={`tool-panel ${panel.isActive ? 'active' : ''}`}>
637
+ <PanelHeader>
638
+ <Icon icon={panel.icon} />
639
+ <Text type="Heading5">{panel.title}</Text>
640
+ {panel.isActive && (
641
+ <Chip type="Primary" size="Small">Active</Chip>
642
+ )}
643
+ </PanelHeader>
644
+ <PanelContent>
645
+ <Text type="Body">{panel.description}</Text>
646
+ </PanelContent>
647
+ </Panel>
648
+ </NavLink>
649
+ ))}
650
+ </div>
651
+ );
652
+ }
499
653
  ```
@@ -18,7 +18,7 @@ A versatile search input component that supports both automatic and manual searc
18
18
 
19
19
  | Prop | Type | Default | Required | Description |
20
20
  |------|------|---------|----------|-------------|
21
- | `mode` | `'Auto' \| 'Manual'` | `'Auto'` | No | Search mode - 'Auto' for debounced search on input, 'Manual' for search on enter/submit |
21
+ | `style` | `'Auto' \| 'Manual'` | `'Auto'` | No | Search mode - 'Auto' for debounced search on input, 'Manual' for search on enter/submit |
22
22
  | `onSearch` | `SearchCallback` | - | No | Callback function to handle search with the query string |
23
23
  | `debounceMs` | `number` | `300` | No | Debounce delay in milliseconds for auto mode |
24
24
  | `minCharacters` | `number` | `1` | No | Minimum characters required to trigger search in auto mode |
@@ -53,7 +53,7 @@ function BasicAutoSearch() {
53
53
  return (
54
54
  <div>
55
55
  <Search
56
- mode="Auto"
56
+ style="Auto"
57
57
  onSearch={handleSearch}
58
58
  loading={loading}
59
59
  placeholder="Search products..."
@@ -100,7 +100,7 @@ function ManualSearchExample() {
100
100
  return (
101
101
  <div>
102
102
  <Search
103
- mode="Manual"
103
+ style="Manual"
104
104
  value={query}
105
105
  onValueChange={setQuery}
106
106
  onSearch={handleSearch}
@@ -180,7 +180,7 @@ function AdvancedSearchExample() {
180
180
  <div className="advanced-search">
181
181
  <div className="search-header">
182
182
  <Search
183
- mode="Auto"
183
+ style="Auto"
184
184
  value={searchState.query}
185
185
  onValueChange={(query) => setSearchState(prev => ({ ...prev, query }))}
186
186
  onSearch={performSearch}
@@ -298,7 +298,7 @@ function UserSearchExample() {
298
298
  <div className="search-section">
299
299
  <Text type="Heading6">Add Team Members</Text>
300
300
  <Search
301
- mode="Auto"
301
+ style="Auto"
302
302
  onSearch={searchUsers}
303
303
  loading={searching}
304
304
  placeholder="Search by name or email..."
@@ -396,7 +396,7 @@ function DocumentSearchExample() {
396
396
  <div className="document-search">
397
397
  <div className="search-bar">
398
398
  <Search
399
- mode="Auto"
399
+ style="Auto"
400
400
  value={searchState.query}
401
401
  onValueChange={(query) => setSearchState(prev => ({ ...prev, query }))}
402
402
  onSearch={searchDocuments}
@@ -508,7 +508,7 @@ function SearchWithHistoryExample() {
508
508
  <div className="search-with-history">
509
509
  <div className="search-container">
510
510
  <Search
511
- mode="Manual"
511
+ style="Manual"
512
512
  value={currentQuery}
513
513
  onValueChange={setCurrentQuery}
514
514
  onSearch={performSearch}
@@ -626,7 +626,7 @@ function RealTimeSearchExample() {
626
626
  <div className="realtime-search">
627
627
  <div className="search-input-container">
628
628
  <Search
629
- mode="Auto"
629
+ style="Auto"
630
630
  value={searchState.query}
631
631
  onValueChange={handleQueryChange}
632
632
  onSearch={performFullSearch}
@@ -24,6 +24,8 @@ A comprehensive form management component that provides state management, valida
24
24
  | `formValidator` | `FormValidator` | - | No | Function to validate entire form |
25
25
  | `onSubmit` | `FormSubmitHandler` | - | No | Form submission handler |
26
26
  | `validateOnChange` | `boolean` | - | No | Whether to validate on field changes |
27
+ | `autosave` | `boolean` | `false` | No | Enable automatic form submission on value changes |
28
+ | `autosaveDelayMs` | `number` | - | No | Delay in milliseconds before autosave triggers |
27
29
 
28
30
  Plus all standard HTML form attributes (method, action, encType, target, etc.) except `onSubmit`.
29
31
 
@@ -530,4 +532,129 @@ function AsyncFormExample() {
530
532
  </Form>
531
533
  );
532
534
  }
535
+ ```
536
+
537
+ ### Autosave Form
538
+ ```tsx
539
+ function AutosaveFormExample() {
540
+ const [saveCount, setSaveCount] = useState(0);
541
+ const [lastSaved, setLastSaved] = useState(null);
542
+
543
+ const handleSubmit = async (values, setError) => {
544
+ try {
545
+ // Simulate API call to save draft
546
+ const response = await fetch('/api/drafts', {
547
+ method: 'POST',
548
+ headers: { 'Content-Type': 'application/json' },
549
+ body: JSON.stringify(values)
550
+ });
551
+
552
+ if (response.ok) {
553
+ setSaveCount(prev => prev + 1);
554
+ setLastSaved(new Date().toLocaleTimeString());
555
+ console.log('Draft auto-saved:', values);
556
+ }
557
+ } catch (error) {
558
+ console.error('Failed to save draft:', error);
559
+ }
560
+ };
561
+
562
+ return (
563
+ <div>
564
+ <Form
565
+ onSubmit={handleSubmit}
566
+ autosave={true}
567
+ autosaveDelayMs={2000} // Wait 2 seconds after user stops typing
568
+ >
569
+ <FormField name="title" label="Title">
570
+ <Input placeholder="Enter title" />
571
+ </FormField>
572
+
573
+ <FormField name="content" label="Content">
574
+ <TextArea
575
+ placeholder="Start writing..."
576
+ rows={10}
577
+ />
578
+ </FormField>
579
+
580
+ <FormField name="tags" label="Tags">
581
+ <ChipInput
582
+ placeholder="Add tags"
583
+ options={['react', 'typescript', 'design', 'tutorial']}
584
+ />
585
+ </FormField>
586
+
587
+ {lastSaved && (
588
+ <Text type="BodySmall">
589
+ Auto-saved {saveCount} times. Last saved at {lastSaved}
590
+ </Text>
591
+ )}
592
+ </Form>
593
+ </div>
594
+ );
595
+ }
596
+ ```
597
+
598
+ ### Autosave with Manual Submit
599
+ ```tsx
600
+ function AutosaveWithManualSubmitExample() {
601
+ const [isDraft, setIsDraft] = useState(true);
602
+
603
+ const handleAutosave = (values, setError) => {
604
+ if (isDraft) {
605
+ console.log('Draft auto-saved:', values);
606
+ // Save to local storage or draft API
607
+ localStorage.setItem('formDraft', JSON.stringify(values));
608
+ }
609
+ };
610
+
611
+ const handlePublish = () => {
612
+ setIsDraft(false);
613
+ // Form will now submit normally
614
+ };
615
+
616
+ return (
617
+ <Form
618
+ onSubmit={handleAutosave}
619
+ autosave={isDraft}
620
+ autosaveDelayMs={1000}
621
+ formState={{
622
+ title: localStorage.getItem('formDraft')?.title || '',
623
+ content: localStorage.getItem('formDraft')?.content || ''
624
+ }}
625
+ >
626
+ <FormField name="title" label="Article Title" required>
627
+ <Input placeholder="Enter title" />
628
+ </FormField>
629
+
630
+ <FormField name="content" label="Article Content" required>
631
+ <TextArea placeholder="Write your article..." rows={15} />
632
+ </FormField>
633
+
634
+ <FormField name="category" label="Category">
635
+ <Select>
636
+ <Option value="tech">Technology</Option>
637
+ <Option value="design">Design</Option>
638
+ <Option value="business">Business</Option>
639
+ </Select>
640
+ </FormField>
641
+
642
+ <div className="form-actions">
643
+ <Button type="Outlined">Save as Draft</Button>
644
+ <Button
645
+ actionType="submit"
646
+ onClick={handlePublish}
647
+ >
648
+ Publish Article
649
+ </Button>
650
+ </div>
651
+
652
+ {isDraft && (
653
+ <Text type="BodySmall" style={{ marginTop: '8px' }}>
654
+ Your changes are automatically saved as you type
655
+ </Text>
656
+ )}
657
+ </Form>
658
+ );
659
+ }
533
660
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delightui/components",
3
- "version": "0.1.113",
3
+ "version": "0.1.115",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "start": "vite",