shekel-fe-shared-lib 1.0.1 → 1.0.5

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
@@ -21,7 +21,7 @@ npm install react react-dom
21
21
  ### Import Components and Styles
22
22
 
23
23
  ```tsx
24
- import { Button, StatCard, SearchInput, Card } from 'shekel-fe-shared-lib';
24
+ import { Button, StatCard, SearchInput, Card, Table, Modal } from 'shekel-fe-shared-lib';
25
25
  import 'shekel-fe-shared-lib/styles.css';
26
26
 
27
27
  function App() {
@@ -188,13 +188,6 @@ A customizable search input with icon support and built-in animations.
188
188
  <SearchInput size="sm" icon={true} placeholder="Small" />
189
189
  <SearchInput size="md" icon={true} placeholder="Medium" />
190
190
  <SearchInput size="lg" icon={true} placeholder="Large" />
191
-
192
- // With icon click handler
193
- <SearchInput
194
- icon={true}
195
- onIconClick={() => console.log('Icon clicked')}
196
- placeholder="Click icon to search"
197
- />
198
191
  ```
199
192
 
200
193
  ---
@@ -247,6 +240,501 @@ A versatile container component with customizable padding, shadows, and hover ef
247
240
 
248
241
  ---
249
242
 
243
+ ### Badge
244
+
245
+ A versatile badge component for labels, tags, and status indicators.
246
+
247
+ #### Props
248
+
249
+ | Prop | Type | Default | Description |
250
+ |------|------|---------|-------------|
251
+ | `children` | `React.ReactNode` | **required** | Badge content |
252
+ | `variant` | `'default' \| 'primary' \| 'success' \| 'warning' \| 'danger' \| 'info'` | `'default'` | Badge color variant |
253
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Badge size |
254
+ | `dot` | `boolean` | `false` | Show status dot |
255
+ | `icon` | `React.ReactNode` | `undefined` | Icon to display |
256
+ | `iconPosition` | `'left' \| 'right'` | `'left'` | Icon position |
257
+ | `className` | `string` | `''` | Additional CSS classes |
258
+
259
+ #### Examples
260
+
261
+ ```tsx
262
+ // Basic badges
263
+ <Badge>Default</Badge>
264
+ <Badge variant="primary">Primary</Badge>
265
+ <Badge variant="success">Success</Badge>
266
+ <Badge variant="warning">Warning</Badge>
267
+ <Badge variant="danger">Danger</Badge>
268
+
269
+ // With status dot
270
+ <Badge variant="success" dot>Active</Badge>
271
+ <Badge variant="danger" dot>Offline</Badge>
272
+
273
+ // With icon
274
+ <Badge variant="primary" icon={<StarIcon />}>
275
+ Featured
276
+ </Badge>
277
+
278
+ // Different sizes
279
+ <Badge size="sm">Small</Badge>
280
+ <Badge size="md">Medium</Badge>
281
+ <Badge size="lg">Large</Badge>
282
+ ```
283
+
284
+ ---
285
+
286
+ ### Checkbox
287
+
288
+ A customizable checkbox component with filled and outline variants.
289
+
290
+ #### Props
291
+
292
+ | Prop | Type | Default | Description |
293
+ |------|------|---------|-------------|
294
+ | `checked` | `boolean` | `undefined` | Controlled checked state |
295
+ | `defaultChecked` | `boolean` | `false` | Default checked state (uncontrolled) |
296
+ | `onChange` | `(checked: boolean) => void` | `undefined` | Change handler |
297
+ | `disabled` | `boolean` | `false` | Disabled state |
298
+ | `indeterminate` | `boolean` | `false` | Indeterminate state |
299
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Checkbox size |
300
+ | `variant` | `'filled' \| 'outline'` | `'filled'` | Visual variant |
301
+ | `className` | `string` | `''` | Additional CSS classes |
302
+ | `id`, `name`, `value` | `string` | `undefined` | Standard input attributes |
303
+
304
+ #### Examples
305
+
306
+ ```tsx
307
+ // Basic checkbox
308
+ <Checkbox id="terms" />
309
+
310
+ // Controlled checkbox
311
+ const [checked, setChecked] = useState(false);
312
+ <Checkbox
313
+ checked={checked}
314
+ onChange={setChecked}
315
+ />
316
+
317
+ // With label
318
+ <div className="flex items-center gap-2">
319
+ <Checkbox id="accept" />
320
+ <label htmlFor="accept">Accept terms</label>
321
+ </div>
322
+
323
+ // Outline variant
324
+ <Checkbox variant="outline" />
325
+
326
+ // Indeterminate state
327
+ <Checkbox indeterminate />
328
+
329
+ // Different sizes
330
+ <Checkbox size="sm" />
331
+ <Checkbox size="md" />
332
+ <Checkbox size="lg" />
333
+ ```
334
+
335
+ ---
336
+
337
+ ### Modal
338
+
339
+ A flexible modal dialog component with animations and keyboard support.
340
+
341
+ #### Props
342
+
343
+ | Prop | Type | Default | Description |
344
+ |------|------|---------|-------------|
345
+ | `open` | `boolean` | **required** | Controls modal visibility |
346
+ | `onClose` | `() => void` | **required** | Close handler |
347
+ | `title` | `string` | `undefined` | Modal title |
348
+ | `children` | `React.ReactNode` | **required** | Modal content |
349
+ | `footer` | `React.ReactNode` | `undefined` | Modal footer content |
350
+ | `width` | `string \| number` | `'520px'` | Modal width |
351
+ | `closable` | `boolean` | `true` | Show close button |
352
+ | `maskClosable` | `boolean` | `true` | Close on backdrop click |
353
+ | `centered` | `boolean` | `true` | Center modal vertically |
354
+ | `className` | `string` | `''` | Additional CSS classes |
355
+
356
+ #### Examples
357
+
358
+ ```tsx
359
+ // Basic modal
360
+ const [open, setOpen] = useState(false);
361
+
362
+ <Modal
363
+ open={open}
364
+ onClose={() => setOpen(false)}
365
+ title="Confirm Action"
366
+ >
367
+ <p>Are you sure you want to proceed?</p>
368
+ </Modal>
369
+
370
+ // With footer
371
+ <Modal
372
+ open={open}
373
+ onClose={() => setOpen(false)}
374
+ title="Delete Item"
375
+ footer={
376
+ <>
377
+ <Button variant="outlined" onClick={() => setOpen(false)}>
378
+ Cancel
379
+ </Button>
380
+ <Button variant="primary" onClick={handleDelete}>
381
+ Delete
382
+ </Button>
383
+ </>
384
+ }
385
+ >
386
+ <p>This action cannot be undone.</p>
387
+ </Modal>
388
+
389
+ // Custom width
390
+ <Modal
391
+ open={open}
392
+ onClose={() => setOpen(false)}
393
+ width="800px"
394
+ >
395
+ <p>Wide modal content</p>
396
+ </Modal>
397
+ ```
398
+
399
+ ---
400
+
401
+ ### Dropdown
402
+
403
+ A dropdown menu component with click and hover triggers.
404
+
405
+ #### Props
406
+
407
+ | Prop | Type | Default | Description |
408
+ |------|------|---------|-------------|
409
+ | `items` | `DropdownMenuItem[]` | **required** | Menu items |
410
+ | `trigger` | `'click' \| 'hover'` | `'click'` | Trigger type |
411
+ | `placement` | `'bottomLeft' \| 'bottomRight' \| 'topLeft' \| 'topRight'` | `'bottomLeft'` | Menu placement |
412
+ | `children` | `React.ReactNode` | **required** | Trigger element |
413
+ | `className` | `string` | `''` | Additional CSS classes |
414
+ | `overlayClassName` | `string` | `''` | Menu overlay classes |
415
+ | `disabled` | `boolean` | `false` | Disabled state |
416
+
417
+ #### Examples
418
+
419
+ ```tsx
420
+ // Basic dropdown
421
+ <Dropdown
422
+ items={[
423
+ { key: '1', label: 'Edit', onClick: () => console.log('Edit') },
424
+ { key: '2', label: 'Delete', danger: true, onClick: () => console.log('Delete') },
425
+ ]}
426
+ >
427
+ <Button>Actions</Button>
428
+ </Dropdown>
429
+
430
+ // With icons
431
+ <Dropdown
432
+ items={[
433
+ { key: '1', label: 'Profile', icon: <UserIcon /> },
434
+ { key: '2', label: 'Settings', icon: <SettingsIcon /> },
435
+ { key: '3', label: 'Logout', icon: <LogoutIcon />, danger: true },
436
+ ]}
437
+ >
438
+ <Button variant="outlined">Menu</Button>
439
+ </Dropdown>
440
+
441
+ // Hover trigger
442
+ <Dropdown trigger="hover" items={menuItems}>
443
+ <span>Hover me</span>
444
+ </Dropdown>
445
+ ```
446
+
447
+ ---
448
+
449
+ ### Select
450
+
451
+ A customizable select dropdown with search functionality.
452
+
453
+ #### Props
454
+
455
+ | Prop | Type | Default | Description |
456
+ |------|------|---------|-------------|
457
+ | `options` | `SelectOption[]` | **required** | Select options |
458
+ | `value` | `string \| number` | `undefined` | Controlled value |
459
+ | `defaultValue` | `string \| number` | `undefined` | Default value (uncontrolled) |
460
+ | `placeholder` | `string` | `'Select an option'` | Placeholder text |
461
+ | `onChange` | `(value: string \| number) => void` | `undefined` | Change handler |
462
+ | `disabled` | `boolean` | `false` | Disabled state |
463
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Select size |
464
+ | `fullWidth` | `boolean` | `false` | Full width mode |
465
+ | `allowClear` | `boolean` | `false` | Show clear button |
466
+ | `showSearch` | `boolean` | `false` | Enable search |
467
+ | `searchPlaceholder` | `string` | `'Search...'` | Search placeholder |
468
+ | `className` | `string` | `''` | Additional CSS classes |
469
+
470
+ #### Examples
471
+
472
+ ```tsx
473
+ // Basic select
474
+ <Select
475
+ options={[
476
+ { value: '1', label: 'Option 1' },
477
+ { value: '2', label: 'Option 2' },
478
+ ]}
479
+ placeholder="Choose an option"
480
+ />
481
+
482
+ // With search
483
+ <Select
484
+ options={countries}
485
+ showSearch
486
+ searchPlaceholder="Search countries..."
487
+ placeholder="Select country"
488
+ />
489
+
490
+ // Controlled select
491
+ const [value, setValue] = useState('');
492
+ <Select
493
+ value={value}
494
+ onChange={setValue}
495
+ options={options}
496
+ allowClear
497
+ />
498
+ ```
499
+
500
+ ---
501
+
502
+ ### Table
503
+
504
+ A feature-rich table component with pagination and sorting.
505
+
506
+ #### Props
507
+
508
+ | Prop | Type | Default | Description |
509
+ |------|------|---------|-------------|
510
+ | `columns` | `ColumnDef[]` | **required** | Column definitions |
511
+ | `dataSource` | `T[]` | **required** | Table data |
512
+ | `rowKey` | `string \| ((record: T) => string)` | `'id'` | Unique row key |
513
+ | `pagination` | `PaginationConfig \| false` | Pagination config | Pagination settings |
514
+ | `loading` | `boolean` | `false` | Loading state |
515
+ | `onRow` | `(record: T, index: number) => HTMLAttributes` | `undefined` | Row props |
516
+ | `bordered` | `boolean` | `false` | Show borders |
517
+ | `striped` | `boolean` | `false` | Striped rows |
518
+ | `className` | `string` | `''` | Additional CSS classes |
519
+
520
+ #### Examples
521
+
522
+ ```tsx
523
+ // Basic table
524
+ const columns = [
525
+ { key: 'name', title: 'Name', dataIndex: 'name' },
526
+ { key: 'age', title: 'Age', dataIndex: 'age' },
527
+ {
528
+ key: 'status',
529
+ title: 'Status',
530
+ render: (_, record) => (
531
+ <Badge variant={record.active ? 'success' : 'default'}>
532
+ {record.active ? 'Active' : 'Inactive'}
533
+ </Badge>
534
+ )
535
+ },
536
+ ];
537
+
538
+ <Table
539
+ columns={columns}
540
+ dataSource={data}
541
+ pagination={{ pageSize: 10 }}
542
+ />
543
+
544
+ // With row click
545
+ <Table
546
+ columns={columns}
547
+ dataSource={data}
548
+ onRow={(record) => ({
549
+ onClick: () => console.log('Row clicked', record),
550
+ className: 'cursor-pointer'
551
+ })}
552
+ />
553
+ ```
554
+
555
+ ---
556
+
557
+ ### TableTop
558
+
559
+ A table header component with search, filters, and actions.
560
+
561
+ #### Props
562
+
563
+ | Prop | Type | Default | Description |
564
+ |------|------|---------|-------------|
565
+ | `title` | `string` | `undefined` | Table title |
566
+ | `description` | `string` | `undefined` | Table description |
567
+ | `searchPlaceholder` | `string` | `'Search...'` | Search placeholder |
568
+ | `onSearch` | `(value: string) => void` | `undefined` | Search handler |
569
+ | `actions` | `React.ReactNode` | `undefined` | Action buttons |
570
+ | `filters` | `React.ReactNode` | `undefined` | Filter components |
571
+ | `className` | `string` | `''` | Additional CSS classes |
572
+
573
+ #### Examples
574
+
575
+ ```tsx
576
+ <TableTop
577
+ title="Users"
578
+ description="Manage your users"
579
+ onSearch={handleSearch}
580
+ actions={
581
+ <>
582
+ <Button variant="outlined">Export</Button>
583
+ <Button variant="primary">Add User</Button>
584
+ </>
585
+ }
586
+ filters={
587
+ <>
588
+ <Select options={statusOptions} placeholder="Status" />
589
+ <Select options={roleOptions} placeholder="Role" />
590
+ </>
591
+ }
592
+ />
593
+ ```
594
+
595
+ ---
596
+
597
+ ### Steps
598
+
599
+ A step indicator component for multi-step processes.
600
+
601
+ #### Props
602
+
603
+ | Prop | Type | Default | Description |
604
+ |------|------|---------|-------------|
605
+ | `items` | `StepItem[]` | **required** | Step items |
606
+ | `current` | `number` | `0` | Current step index |
607
+ | `direction` | `'horizontal' \| 'vertical'` | `'vertical'` | Layout direction |
608
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Step size |
609
+ | `variant` | `'default' \| 'outline'` | `'default'` | Visual variant |
610
+ | `className` | `string` | `''` | Additional CSS classes |
611
+
612
+ #### Examples
613
+
614
+ ```tsx
615
+ // Vertical steps
616
+ <Steps
617
+ current={1}
618
+ items={[
619
+ { title: 'Account', description: 'Create your account' },
620
+ { title: 'Profile', description: 'Fill your profile' },
621
+ { title: 'Complete', description: 'All done!' },
622
+ ]}
623
+ />
624
+
625
+ // Horizontal steps
626
+ <Steps
627
+ direction="horizontal"
628
+ current={2}
629
+ items={[
630
+ { title: 'Cart' },
631
+ { title: 'Shipping' },
632
+ { title: 'Payment' },
633
+ { title: 'Confirm' },
634
+ ]}
635
+ />
636
+
637
+ // With custom status
638
+ <Steps
639
+ items={[
640
+ { title: 'Step 1', status: 'finish' },
641
+ { title: 'Step 2', status: 'process' },
642
+ { title: 'Step 3', status: 'error' },
643
+ ]}
644
+ />
645
+ ```
646
+
647
+ ---
648
+
649
+ ### Progress
650
+
651
+ A progress bar component with multiple status variants.
652
+
653
+ #### Props
654
+
655
+ | Prop | Type | Default | Description |
656
+ |------|------|---------|-------------|
657
+ | `percent` | `number` | `0` | Progress percentage (0-100) |
658
+ | `status` | `'normal' \| 'success' \| 'exception' \| 'active'` | `'normal'` | Progress status |
659
+ | `showInfo` | `boolean` | `true` | Show percentage text |
660
+ | `strokeColor` | `string` | `undefined` | Custom bar color |
661
+ | `strokeWidth` | `number` | `undefined` | Custom bar height |
662
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Progress size |
663
+ | `format` | `(percent: number) => ReactNode` | `undefined` | Custom format function |
664
+ | `className` | `string` | `''` | Additional CSS classes |
665
+
666
+ #### Examples
667
+
668
+ ```tsx
669
+ // Basic progress
670
+ <Progress percent={60} />
671
+
672
+ // Success status
673
+ <Progress percent={100} status="success" />
674
+
675
+ // Error status
676
+ <Progress percent={45} status="exception" />
677
+
678
+ // Active animation
679
+ <Progress percent={75} status="active" />
680
+
681
+ // Custom format
682
+ <Progress
683
+ percent={60}
684
+ format={(percent) => `${percent}% Complete`}
685
+ />
686
+
687
+ // Different sizes
688
+ <Progress percent={50} size="sm" />
689
+ <Progress percent={50} size="md" />
690
+ <Progress percent={50} size="lg" />
691
+ ```
692
+
693
+ ---
694
+
695
+ ### SelectedItemsList
696
+
697
+ A list component for displaying and managing selected items.
698
+
699
+ #### Props
700
+
701
+ | Prop | Type | Default | Description |
702
+ |------|------|---------|-------------|
703
+ | `items` | `SelectedItem[]` | **required** | Selected items |
704
+ | `onRemove` | `(id: string \| number) => void` | **required** | Remove handler |
705
+ | `emptyMessage` | `string` | `'No items selected'` | Empty state message |
706
+ | `className` | `string` | `''` | Additional CSS classes |
707
+ | `itemClassName` | `string` | `''` | Item CSS classes |
708
+ | `maxHeight` | `string` | `'300px'` | Max list height |
709
+
710
+ #### Examples
711
+
712
+ ```tsx
713
+ // Basic usage
714
+ const [selectedItems, setSelectedItems] = useState([
715
+ { id: 1, label: 'Item 1', sublabel: 'Category A' },
716
+ { id: 2, label: 'Item 2', sublabel: 'Category B' },
717
+ ]);
718
+
719
+ <SelectedItemsList
720
+ items={selectedItems}
721
+ onRemove={(id) => {
722
+ setSelectedItems(items => items.filter(item => item.id !== id));
723
+ }}
724
+ />
725
+
726
+ // Custom styling
727
+ <SelectedItemsList
728
+ items={selectedItems}
729
+ onRemove={handleRemove}
730
+ maxHeight="500px"
731
+ emptyMessage="No files selected"
732
+ className="my-4"
733
+ />
734
+ ```
735
+
736
+ ---
737
+
250
738
  ## Animations
251
739
 
252
740
  All components include built-in CSS animations:
@@ -255,10 +743,15 @@ All components include built-in CSS animations:
255
743
  - **Card**: Smooth fade-in animation
256
744
  - **Button**: Active scale and smooth transitions
257
745
  - **SearchInput**: Smooth focus transitions
746
+ - **Modal**: Fade and scale animations
747
+ - **Dropdown**: Slide animations
748
+ - **Progress**: Active state animation
258
749
 
259
750
  Additional animation classes available:
260
751
  - `.shimmer` - Loading shimmer effect
261
752
  - `.slide-in-right` - Slide in from right animation
753
+ - `.dropdown-slide-down` - Dropdown slide down animation
754
+ - `.dropdown-slide-up` - Dropdown slide up animation
262
755
 
263
756
  ---
264
757
 
@@ -267,7 +760,28 @@ Additional animation classes available:
267
760
  This library is written in TypeScript and includes full type definitions. All component props are fully typed for the best development experience.
268
761
 
269
762
  ```tsx
270
- import type { ButtonProps, StatCardProps, SearchInputProps, CardProps } from 'shekel-fe-shared-lib';
763
+ import type {
764
+ ButtonProps,
765
+ StatCardProps,
766
+ SearchInputProps,
767
+ CardProps,
768
+ BadgeProps,
769
+ CheckboxProps,
770
+ ModalProps,
771
+ DropdownProps,
772
+ DropdownMenuItem,
773
+ SelectProps,
774
+ SelectOption,
775
+ TableProps,
776
+ ColumnDef,
777
+ PaginationConfig,
778
+ TableTopProps,
779
+ StepsProps,
780
+ StepItem,
781
+ ProgressProps,
782
+ SelectedItemsListProps,
783
+ SelectedItem,
784
+ } from 'shekel-fe-shared-lib';
271
785
  ```
272
786
 
273
787
  ---
@@ -286,10 +800,20 @@ npm run build
286
800
  shekel-fe-shared-lib/
287
801
  ├── src/
288
802
  │ ├── components/
803
+ │ │ ├── Badge.tsx
289
804
  │ │ ├── Button.tsx
290
- │ │ ├── StatCard.tsx
291
- │ │ ├── SearchInput.tsx
292
805
  │ │ ├── Card.tsx
806
+ │ │ ├── Checkbox.tsx
807
+ │ │ ├── Dropdown.tsx
808
+ │ │ ├── Modal.tsx
809
+ │ │ ├── Progress.tsx
810
+ │ │ ├── SearchInput.tsx
811
+ │ │ ├── Select.tsx
812
+ │ │ ├── SelectedItemsList.tsx
813
+ │ │ ├── StatCard.tsx
814
+ │ │ ├── Steps.tsx
815
+ │ │ ├── Table.tsx
816
+ │ │ ├── TableTop.tsx
293
817
  │ │ └── index.ts
294
818
  │ ├── styles.css
295
819
  │ └── index.ts
@@ -315,13 +839,31 @@ import {
315
839
  Button,
316
840
  StatCard,
317
841
  SearchInput,
318
- Card
842
+ Card,
843
+ Table,
844
+ TableTop,
845
+ Badge,
846
+ Dropdown
319
847
  } from 'shekel-fe-shared-lib';
320
848
  import 'shekel-fe-shared-lib/styles.css';
321
849
 
322
850
  function TrackingDashboard() {
323
851
  const [selectedStat, setSelectedStat] = useState('all');
324
852
 
853
+ const columns = [
854
+ { key: 'id', title: 'ID', dataIndex: 'id' },
855
+ { key: 'name', title: 'Name', dataIndex: 'name' },
856
+ {
857
+ key: 'status',
858
+ title: 'Status',
859
+ render: (_, record) => (
860
+ <Badge variant={record.status === 'active' ? 'success' : 'default'}>
861
+ {record.status}
862
+ </Badge>
863
+ )
864
+ },
865
+ ];
866
+
325
867
  return (
326
868
  <div className="p-6">
327
869
  {/* Header */}
@@ -354,30 +896,27 @@ function TrackingDashboard() {
354
896
  <StatCard label="Demurrage" value={0} />
355
897
  </div>
356
898
 
357
- {/* Actions and Search */}
358
- <div className="flex justify-between items-center mb-6">
359
- <h2 className="text-lg font-semibold">Recent Activity</h2>
360
- <div className="flex gap-3">
361
- <Button variant="outlined" icon={<DownloadIcon />}>
362
- Download report
363
- </Button>
364
- <Button variant="outlined" icon={<FilterIcon />}>
365
- Filter
366
- </Button>
367
- <SearchInput
368
- icon={true}
369
- placeholder="Search a shipment"
370
- className="w-80"
371
- />
372
- </div>
373
- </div>
374
-
375
- {/* Content */}
376
- <Card>
377
- <p className="text-center text-gray-500 py-12">
378
- Your gateway to seamless shipment tracking
379
- </p>
380
- </Card>
899
+ {/* Table with search and actions */}
900
+ <TableTop
901
+ title="Recent Activity"
902
+ onSearch={handleSearch}
903
+ actions={
904
+ <>
905
+ <Button variant="outlined" icon={<DownloadIcon />}>
906
+ Download report
907
+ </Button>
908
+ <Button variant="outlined" icon={<FilterIcon />}>
909
+ Filter
910
+ </Button>
911
+ </>
912
+ }
913
+ />
914
+
915
+ <Table
916
+ columns={columns}
917
+ dataSource={shipments}
918
+ pagination={{ pageSize: 10 }}
919
+ />
381
920
  </div>
382
921
  );
383
922
  }