@undefine-ui/design-system 3.2.0 → 3.4.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/README.md CHANGED
@@ -84,7 +84,7 @@ The package includes a comprehensive icon library with 45+ SVG icons organized b
84
84
  - **Navigation:** NavArrowLeft, NavArrowRight, NavArrowDown, NavArrowDownSolid, LongArrowUpLeftSolid
85
85
  - **User:** User, UserSolid, Building, Bank
86
86
  - **Form Controls:** CheckboxDefault, CheckboxSelect, CheckboxIndeterminate, RadioDefault, RadioSelect
87
- - **Actions:** Search, Copy, Trash, XMark, XMarkSolid, CloudUpload, Download, Settings, Plus, PlusSquare, Attachment
87
+ - **Actions:** Search, Copy, Trash, XMark, XMarkSolid, CloudUpload, Download, Settings, Plus, PlusSquare, Attachment, FilterList
88
88
  - **Feedback:** InfoCircle, InfoCircleSolid, CheckCircleSolid, HelpCircle, ClipboardCheck, Loader, BellNotification, Circle
89
89
  - **Visibility:** Eye, EyeClosed
90
90
  - **Date & Time:** Calendar, Clock
@@ -364,6 +364,241 @@ const MyForm = () => {
364
364
  - **Theme-styled:** Uses your theme's TextField styling
365
365
  - **Click-to-open:** Opens picker on text field click
366
366
 
367
+ ### DateRangePicker
368
+
369
+ A date range picker with preset options (Today, Last 7 Days, etc.), dual calendars for start/end date selection, and custom date range support. Includes both a standalone `DateRangePicker` component and a `DateRangeDropdown` for toolbar integration.
370
+
371
+ **Usage:**
372
+
373
+ ```tsx
374
+ import {
375
+ DateRangePicker,
376
+ DateRangeDropdown,
377
+ defaultPresets,
378
+ getDateRangeFromPreset,
379
+ type DateRange,
380
+ type DatePreset
381
+ } from '@undefine-ui/design-system';
382
+
383
+ // Standalone DateRangePicker
384
+ const [range, setRange] = useState<DateRange>({ start: null, end: null });
385
+ const [preset, setPreset] = useState<DatePreset>('last30days');
386
+
387
+ <DateRangePicker
388
+ value={range}
389
+ preset={preset}
390
+ onChange={(newRange, newPreset) => {
391
+ setRange(newRange);
392
+ setPreset(newPreset);
393
+ }}
394
+ onCancel={() => console.log('Cancelled')}
395
+ />
396
+
397
+ // DateRangeDropdown (for toolbars)
398
+ <DateRangeDropdown
399
+ value={range}
400
+ preset={preset}
401
+ onChange={(newRange, newPreset) => {
402
+ setRange(newRange);
403
+ setPreset(newPreset);
404
+ }}
405
+ />
406
+
407
+ // With custom presets
408
+ const customPresets = [
409
+ { value: 'today', label: 'Today' },
410
+ { value: 'last7days', label: 'This Week' },
411
+ { value: 'last30days', label: 'This Month' },
412
+ { value: 'custom', label: 'Pick Dates' }
413
+ ];
414
+
415
+ <DateRangePicker presets={customPresets} {...props} />
416
+
417
+ // Get date range programmatically
418
+ const last7DaysRange = getDateRangeFromPreset('last7days');
419
+ // { start: Date, end: Date }
420
+ ```
421
+
422
+ **DateRangePicker Props:**
423
+
424
+ - `value` - Currently selected date range `{ start: Date | null, end: Date | null }`
425
+ - `preset` - Currently selected preset (`'today'`, `'yesterday'`, `'last7days'`, `'last30days'`, `'last6months'`, `'lastyear'`, `'alltime'`, `'custom'`)
426
+ - `onChange` - Callback when date range changes `(range, preset) => void`
427
+ - `onCancel` - Callback when cancel is clicked
428
+ - `presets` - Custom preset options array (default: `defaultPresets`)
429
+ - `showPresets` - Show preset radio buttons (default: `true`)
430
+ - `showActions` - Show Cancel/Apply buttons (default: `true`)
431
+ - `dateFormat` - Date format for input display (default: `'dd/MM/yyyy'`)
432
+ - `minDate` / `maxDate` - Date constraints
433
+
434
+ **DateRangeDropdown Props:**
435
+
436
+ - Inherits all `DateRangePicker` props
437
+ - `buttonLabel` - Fallback label for the dropdown button (default: `'Date'`)
438
+ - `disabled` - Disable the dropdown
439
+ - `popoverSx` - Custom styles for the popover
440
+ - Button label automatically updates to show selected preset or custom date range (e.g., "Dec 1 - Dec 15, 2024")
441
+
442
+ **Exported Helpers:**
443
+
444
+ - `defaultPresets` - Default preset options array
445
+ - `getDateRangeFromPreset(preset)` - Convert preset to actual date range
446
+
447
+ **React Hook Form Integration (Field.DateRange):**
448
+
449
+ ```tsx
450
+ import { Form, Field } from '@undefine-ui/design-system';
451
+ import { useForm } from 'react-hook-form';
452
+
453
+ const MyForm = () => {
454
+ const methods = useForm({
455
+ defaultValues: {
456
+ dateRange: { start: null, end: null, preset: 'today' }
457
+ }
458
+ });
459
+
460
+ return (
461
+ <Form methods={methods} onSubmit={(data) => console.log(data)}>
462
+ <Field.DateRange name="dateRange" label="Select Date Range" />
463
+ </Form>
464
+ );
465
+ };
466
+ ```
467
+
468
+ **Field.DateRange Props:**
469
+
470
+ - `name` - Form field name (required, stores `{ start, end, preset }`)
471
+ - `label` - Label for the text field
472
+ - `placeholder` - Placeholder text (default: `'Select date range'`)
473
+ - `helperText` - Helper text below the input
474
+ - `dateFormat` - Date format for display (default: `'MMM d, yyyy'`)
475
+ - `presets` - Custom preset options
476
+ - `disabled` - Disable the field
477
+ - `size` - TextField size (`'small'` | `'medium'`)
478
+ - `fullWidth` - Full width mode (default: `true`)
479
+
480
+ ### Toolbar Components
481
+
482
+ A collection of components for building data table toolbars with search, filters, sorting, view switching, and date range selection.
483
+
484
+ **Usage:**
485
+
486
+ ```tsx
487
+ import {
488
+ ToolbarButton,
489
+ ToolbarSearchField,
490
+ ToolbarViewSwitcher,
491
+ ToolbarFilterButton,
492
+ ToolbarSortButton,
493
+ ToolbarSettingsButton,
494
+ ToolbarTodayButton,
495
+ ToolbarDatePickerButton,
496
+ FilterDropdown,
497
+ SortDropdown,
498
+ DateRangeDropdown,
499
+ type ViewOption,
500
+ type SortOption,
501
+ type SortDirection
502
+ } from '@undefine-ui/design-system';
503
+
504
+ // Base toolbar button with icon and label
505
+ <ToolbarButton icon="Filter" label="Filter" onClick={handleClick} />
506
+
507
+ // Specialized button components
508
+ <ToolbarFilterButton onClick={handleFilter} />
509
+ <ToolbarSortButton onClick={handleSort} />
510
+ <ToolbarSettingsButton onClick={handleSettings} />
511
+ <ToolbarTodayButton onClick={handleToday} />
512
+ <ToolbarDatePickerButton label="Last 30 days" onClick={handleDate} />
513
+
514
+ // Search field with clear button
515
+ <ToolbarSearchField
516
+ value={search}
517
+ onChange={(e) => setSearch(e.target.value)}
518
+ onClear={() => setSearch('')}
519
+ placeholder="Search..."
520
+ />
521
+
522
+ // View switcher (year/month/week/day dropdown button)
523
+ const [view, setView] = useState<ViewOption>('week');
524
+ <ToolbarViewSwitcher value={view} onClick={() => setView('month')} />
525
+
526
+ // Filter dropdown - manages its own popover state, just pass children
527
+ <FilterDropdown>
528
+ <Form methods={methods}>
529
+ <Field.Text name="status" label="Status" size="small" select>
530
+ <MenuItem value="active">Active</MenuItem>
531
+ <MenuItem value="inactive">Inactive</MenuItem>
532
+ </Field.Text>
533
+ {/* Add more filter controls */}
534
+ </Form>
535
+ </FilterDropdown>
536
+
537
+ // Sort dropdown with unified onChange callback
538
+ const [sortValue, setSortValue] = useState('name');
539
+ const [sortDirection, setSortDirection] = useState<SortDirection>('asc');
540
+
541
+ const sortOptions: SortOption[] = [
542
+ { value: 'name', label: 'Name' },
543
+ { value: 'date', label: 'Date Created' }
544
+ ];
545
+
546
+ <SortDropdown
547
+ options={sortOptions}
548
+ value={sortValue}
549
+ direction={sortDirection}
550
+ onChange={(value, direction) => {
551
+ setSortValue(value);
552
+ setSortDirection(direction);
553
+ }}
554
+ />
555
+
556
+ // Complete toolbar example
557
+ <Stack direction="row" spacing={1} alignItems="center">
558
+ <ToolbarSearchField value={search} onChange={...} onClear={...} />
559
+ <Box sx={{ flexGrow: 1 }} />
560
+ <DateRangeDropdown value={range} preset={preset} onChange={...} />
561
+ <FilterDropdown>{filterContent}</FilterDropdown>
562
+ <SortDropdown options={sortOptions} value={sortValue} direction={sortDirection} onChange={...} />
563
+ <Divider orientation="vertical" flexItem />
564
+ <ToolbarViewSwitcher value={view} onClick={...} />
565
+ </Stack>
566
+ ```
567
+
568
+ **ToolbarButton Props:**
569
+
570
+ - `icon` - Icon name from the icon library
571
+ - `label` - Button label text
572
+ - `open` - Whether the button is in open/active state
573
+ - `disabled` - Disable the button
574
+ - All standard MUI ButtonBase props
575
+
576
+ **FilterDropdown Props:**
577
+
578
+ - `children` - Content to render inside the popover (use Form + Field components)
579
+ - `buttonLabel` - Custom label for the filter button (default: `'Filter'`)
580
+ - `onClose` - Called when the popover closes
581
+ - `disabled` - Disable the dropdown
582
+ - `popoverSx` - Custom styles for the popover paper
583
+ - `PopoverProps` - Additional popover props
584
+
585
+ **SortDropdown Props:**
586
+
587
+ - `options` - Array of sort options `{ value: string, label: string }[]`
588
+ - `value` - Currently selected sort field
589
+ - `direction` - Current sort direction (`'asc'` or `'desc'`)
590
+ - `onChange` - Callback when sort changes `(value: string, direction: SortDirection) => void`
591
+ - `buttonLabel` - Custom label for the sort button (default: `'Sort'`)
592
+ - `ascLabel` - Custom label for ascending (default: `'Ascending'`)
593
+ - `descLabel` - Custom label for descending (default: `'Descending'`)
594
+ - `disabled` - Disable the dropdown
595
+
596
+ **ToolbarViewSwitcher Props:**
597
+
598
+ - `value` - Currently selected view (`'year'` | `'month'` | `'week'` | `'day'`)
599
+ - `open` - Whether the button is in open/active state
600
+ - All standard MUI ButtonBase props
601
+
367
602
  ### OTP Input
368
603
 
369
604
  A one-time password input component with keyboard navigation, paste support, and validation. Perfect for email/SMS verification, PIN codes, and security codes.
@@ -425,6 +660,177 @@ import { OTPInput, Field } from '@undefine-ui/design-system';
425
660
 
426
661
  The `Field.OTP` component automatically integrates with React Hook Form, providing validation and error handling out of the box.
427
662
 
663
+ ### Dialog
664
+
665
+ Custom dialog components with close button and feedback variations. Includes a base `CustomDialog` with a close button positioned on the right, and a `FeedbackDialog` for success, error, and confirmation states.
666
+
667
+ **Usage:**
668
+
669
+ ```tsx
670
+ import { CustomDialog, FeedbackDialog } from '@undefine-ui/design-system';
671
+
672
+ // Basic CustomDialog with close button
673
+ <CustomDialog open={open} onClose={handleClose}>
674
+ <Typography variant="h6">Custom Dialog Title</Typography>
675
+ <Typography variant="body2">
676
+ This is a custom dialog with a close button on the right.
677
+ </Typography>
678
+ </CustomDialog>
679
+
680
+ // Success feedback dialog
681
+ <FeedbackDialog
682
+ open={open}
683
+ onClose={handleClose}
684
+ image="/path/to/success-image.png"
685
+ title="Board added successfully"
686
+ description="Your new board has been created."
687
+ actions={
688
+ <>
689
+ <Button variant="contained" fullWidth onClick={handleGoToBoard}>
690
+ Go to board
691
+ </Button>
692
+ <Button variant="text" color="inherit" fullWidth onClick={handleClose}>
693
+ Close
694
+ </Button>
695
+ </>
696
+ }
697
+ />
698
+
699
+ // Confirmation dialog with horizontal actions
700
+ <FeedbackDialog
701
+ open={open}
702
+ onClose={handleClose}
703
+ title="Confirm deletion"
704
+ description="Are you sure you want to delete this item?"
705
+ actions={
706
+ <Stack direction="row" spacing={1.5} sx={{ width: '100%' }}>
707
+ <Button variant="outlined" fullWidth onClick={handleClose}>
708
+ Cancel
709
+ </Button>
710
+ <Button variant="contained" color="error" fullWidth onClick={handleDelete}>
711
+ Delete
712
+ </Button>
713
+ </Stack>
714
+ }
715
+ feedbackSlotProps={{
716
+ actions: { flexDirection: 'row' }
717
+ }}
718
+ />
719
+
720
+ // Custom styling
721
+ <FeedbackDialog
722
+ open={open}
723
+ onClose={handleClose}
724
+ title="Welcome aboard! 🎉"
725
+ description="Your account has been created successfully."
726
+ actions={
727
+ <Button variant="contained" fullWidth>Get Started</Button>
728
+ }
729
+ feedbackSlotProps={{
730
+ title: { fontSize: '1.5rem', color: 'primary.main' },
731
+ description: { maxWidth: 280 }
732
+ }}
733
+ />
734
+ ```
735
+
736
+ **CustomDialog Props:**
737
+
738
+ - `open` - Controls dialog visibility (required)
739
+ - `onClose` - Callback when close button is clicked
740
+ - All MUI `DialogProps` are supported
741
+
742
+ **FeedbackDialog Props:**
743
+
744
+ - `open` - Controls dialog visibility (required)
745
+ - `onClose` - Callback when close button is clicked
746
+ - `image` - URL for the feedback image
747
+ - `title` - Title text to display
748
+ - `description` - Description text below the title
749
+ - `actions` - Action elements (buttons, etc.)
750
+ - `feedbackSlotProps` - Custom styles for `image`, `title`, `description`, and `actions` slots
751
+
752
+ **Features:**
753
+
754
+ - **Close button:** Positioned on the top-right for easy dismissal
755
+ - **Flexible content:** CustomDialog accepts any children content
756
+ - **Feedback states:** FeedbackDialog supports success, error, and confirmation patterns
757
+ - **Customizable:** Style individual elements via feedbackSlotProps
758
+ - **Theme integration:** Uses theme variables for consistent styling
759
+
760
+ ### Drawer
761
+
762
+ A drawer component with a fixed header containing a title and close button. The content area is scrollable while the header remains fixed. Built on top of MUI Drawer with enhanced styling and layout.
763
+
764
+ **Usage:**
765
+
766
+ ```tsx
767
+ import { CustomDrawer } from '@undefine-ui/design-system';
768
+
769
+ // Basic drawer
770
+ <CustomDrawer open={open} onClose={handleClose} title="Drawer Title">
771
+ <Typography variant="body2">
772
+ This is the drawer content. It scrolls independently while the header stays fixed.
773
+ </Typography>
774
+ </CustomDrawer>
775
+
776
+ // Drawer with details layout
777
+ <CustomDrawer open={open} onClose={handleClose} title="Booking details">
778
+ <Stack spacing={3}>
779
+ <Box>
780
+ <Typography variant="body2" color="text.body">Status</Typography>
781
+ <Chip label="Confirm" color="success" size="small" />
782
+ </Box>
783
+ <Box>
784
+ <Typography variant="body2" color="text.body">Booking ID</Typography>
785
+ <Typography variant="subtitle2">#001</Typography>
786
+ </Box>
787
+ <Box>
788
+ <Typography variant="body2" color="text.body">Amount</Typography>
789
+ <Typography variant="subtitle2">N250,000</Typography>
790
+ </Box>
791
+ </Stack>
792
+ </CustomDrawer>
793
+
794
+ // Left-anchored drawer
795
+ <CustomDrawer
796
+ open={open}
797
+ onClose={handleClose}
798
+ title="Left Drawer"
799
+ anchor="left"
800
+ >
801
+ <Typography variant="body2">
802
+ This drawer opens from the left side.
803
+ </Typography>
804
+ </CustomDrawer>
805
+
806
+ // Drawer with form
807
+ <CustomDrawer open={open} onClose={handleClose} title="Time slot">
808
+ <Stack spacing={3}>
809
+ <TextField label="Date" size="small" fullWidth />
810
+ <TextField label="Time" size="small" fullWidth />
811
+ <Button variant="contained" fullWidth>Save</Button>
812
+ </Stack>
813
+ </CustomDrawer>
814
+ ```
815
+
816
+ **Props:**
817
+
818
+ - `open` - Controls drawer visibility (required)
819
+ - `title` - Title text displayed in the fixed header
820
+ - `onClose` - Callback when close button is clicked
821
+ - `anchor` - Side from which the drawer appears (default: `'right'`)
822
+ - `slotProps` - Custom props for MUI Drawer slots (paper, etc.)
823
+ - All MUI `DrawerProps` are supported
824
+
825
+ **Features:**
826
+
827
+ - **Fixed header:** Title and close button stay visible while scrolling
828
+ - **Scrollable content:** Content area scrolls independently
829
+ - **Responsive width:** Full width on mobile, 400px on larger screens
830
+ - **Multiple anchors:** Supports left, right, top, and bottom positioning
831
+ - **Close button:** XMark icon button for easy dismissal
832
+ - **Theme integration:** Uses theme variables for consistent styling
833
+
428
834
  ### Empty Content
429
835
 
430
836
  A flexible empty state component for displaying placeholder content when data is unavailable. Perfect for empty lists, search results, or any state where content hasn't been loaded yet.
@@ -551,17 +957,68 @@ The animated logo automatically plays on mount with:
551
957
 
552
958
  Ideal for splash screens, loading overlays, or brand storytelling moments.
553
959
 
960
+ ### ApexCharts Styling
961
+
962
+ The design system provides styling utilities for ApexCharts integration, ensuring charts match the Define theme.
963
+
964
+ **Installation:**
965
+
966
+ ```bash
967
+ pnpm add apexcharts react-apexcharts
968
+ ```
969
+
970
+ **Usage:**
971
+
972
+ ```tsx
973
+ import ReactApexChart from 'react-apexcharts';
974
+ import { useTheme, styled } from '@mui/material/styles';
975
+ import { apexChartsStyles, getDefaultChartOptions } from '@undefine-ui/design-system';
976
+
977
+ // Create a styled wrapper
978
+ const ChartWrapper = styled('div')(({ theme }) => ({
979
+ ...apexChartsStyles(theme)
980
+ }));
981
+
982
+ function LineChart() {
983
+ const theme = useTheme();
984
+
985
+ const chartOptions = {
986
+ ...getDefaultChartOptions(theme),
987
+ xaxis: {
988
+ ...getDefaultChartOptions(theme).xaxis,
989
+ categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul']
990
+ }
991
+ };
992
+
993
+ const chartSeries = [
994
+ { name: 'Bookings', data: [10, 41, 35, 51, 49, 62, 69] },
995
+ { name: 'Revenue', data: [20, 35, 50, 30, 45, 55, 40] }
996
+ ];
997
+
998
+ return (
999
+ <ChartWrapper>
1000
+ <ReactApexChart type="line" series={chartSeries} options={chartOptions} height={350} />
1001
+ </ChartWrapper>
1002
+ );
1003
+ }
1004
+ ```
1005
+
1006
+ **Available exports:**
1007
+
1008
+ - `apexChartsStyles(theme)` - CSS styles to apply to a wrapper element (tooltips, legends, labels)
1009
+ - `getDefaultChartOptions(theme)` - Default ApexCharts options with theme colors, typography, and grid styling
1010
+
554
1011
  ## Export surface
555
1012
 
556
1013
  Everything is re-exported from `src/index.ts`. Key groups:
557
1014
 
558
- | Group | Exports |
559
- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
560
- | Components | `CopyButton`, `EmptyContent`, `HookForm` helpers (`Form`, `Field`, `RHFSwitch`, etc.), `Icon`, `Image`, `Logo`, `LoadingScreen`, `OTPInput`, `Table`, `Upload` |
561
- | Hooks | `useBoolean`, `useCopyToClipboard`, `useEventListener`, `useLocalStorage`, `useResponsive`, `useSettings`, `useSetState`, `useScrollOffsetTop`, `usePopover`, `useCountdown` |
562
- | Contexts | `SettingsProvider`, `SettingsContext`, `defaultSettings`, `SettingsValueProps` |
563
- | Theme | `ThemeProvider`, `createTheme`, `colorSchemes`, `components`, `palette`, `radius`, `shadows`, `customSpacing`, utilities such as `varAlpha`, `bgGradient`, `hideScrollX/Y` |
564
- | Utilities | `changeCase` helpers, `formatNumber`, `fullname-utils`, generic `helpers` |
1015
+ | Group | Exports |
1016
+ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1017
+ | Components | `CopyButton`, `CustomDialog`, `CustomDrawer`, `EmptyContent`, `FeedbackDialog`, `HookForm` helpers (`Form`, `Field`, `RHFSwitch`, etc.), `Icon`, `Image`, `Logo`, `LoadingScreen`, `OTPInput`, `Table`, `Upload` |
1018
+ | Hooks | `useBoolean`, `useCopyToClipboard`, `useEventListener`, `useLocalStorage`, `useResponsive`, `useSettings`, `useSetState`, `useScrollOffsetTop`, `usePopover`, `useCountdown` |
1019
+ | Contexts | `SettingsProvider`, `SettingsContext`, `defaultSettings`, `SettingsValueProps` |
1020
+ | Theme | `ThemeProvider`, `createTheme`, `colorSchemes`, `components`, `palette`, `radius`, `shadows`, `customSpacing`, utilities such as `varAlpha`, `bgGradient`, `hideScrollX/Y` |
1021
+ | Utilities | `changeCase` helpers, `formatNumber`, `fullname-utils`, generic `helpers` |
565
1022
 
566
1023
  You can also import the theme pieces directly to compose your own MUI theme or to extend tokens in Storybook.
567
1024