@makolabs/ripple 0.0.1-dev.17 → 0.0.1-dev.19

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.
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { cn } from '../../helper/cls.js';
3
3
  import { Color, Size } from '../../variants.js';
4
- import type { ProgressProps } from '../../index.js';
4
+ import type { ProgressProps, ProgressSegment, VariantColors } from '../../index.js';
5
5
 
6
6
  let {
7
7
  value,
@@ -10,19 +10,55 @@
10
10
  color = Color.PRIMARY,
11
11
  showLabel = true,
12
12
  labelPosition = 'right',
13
+ segments = undefined,
14
+ showValues = false,
15
+ showLabels = false,
13
16
  class: className = '',
14
17
  labelClass = '',
15
18
  barClass = ''
16
19
  }: ProgressProps = $props();
17
20
 
18
- const percentage = $derived(Math.min(Math.round((value / max) * 100), 100));
21
+ // Function composition for better readability and maintainability
22
+ function calculatePercentage(val: number, maximum: number): number {
23
+ return Math.min(Math.round((val / maximum) * 100), 100);
24
+ }
19
25
 
26
+ function getColorClass(color: VariantColors): string {
27
+ const colorMap = {
28
+ [Color.PRIMARY]: 'bg-primary-600',
29
+ [Color.SECONDARY]: 'bg-secondary-600',
30
+ [Color.SUCCESS]: 'bg-success-600',
31
+ [Color.DANGER]: 'bg-danger-600',
32
+ [Color.WARNING]: 'bg-warning-600',
33
+ [Color.INFO]: 'bg-info-600',
34
+ [Color.DEFAULT]: 'bg-gray-600'
35
+ };
36
+ return colorMap[color] || colorMap[Color.PRIMARY];
37
+ }
38
+
39
+ function getSizeTextClass(size: string): string {
40
+ if (size === Size.XS || size === Size.SM) return 'text-xs';
41
+ if (size === Size.BASE) return 'text-sm';
42
+ return 'text-base'; // For Size.LG, Size.XL
43
+ }
44
+
45
+ // Derived values
46
+ const percentage = $derived(segments ? 100 : calculatePercentage(value, max));
47
+ const segmentPercentages = $derived(
48
+ segments?.map(segment => ({
49
+ ...segment,
50
+ percentage: calculatePercentage(segment.value, max)
51
+ })) || []
52
+ );
53
+
54
+ // Class compositions
20
55
  const containerClass = $derived(
21
56
  cn(
22
- 'relative flex items-center',
57
+ 'relative',
23
58
  {
24
- 'flex-col gap-1': labelPosition === 'top' || labelPosition === 'bottom',
25
- 'flex-row gap-3': labelPosition === 'right'
59
+ 'flex items-center': !segments,
60
+ 'flex-col gap-1': !segments && (labelPosition === 'top' || labelPosition === 'bottom'),
61
+ 'flex-row gap-3': !segments && labelPosition === 'right'
26
62
  },
27
63
  className
28
64
  )
@@ -35,23 +71,16 @@
35
71
  'h-2.5': size === Size.BASE,
36
72
  'h-3': size === Size.LG,
37
73
  'h-4': size === Size.XL,
38
- 'order-2': labelPosition === 'top',
39
- 'order-1': labelPosition === 'bottom'
74
+ 'order-2': !segments && labelPosition === 'top',
75
+ 'order-1': !segments && labelPosition === 'bottom',
76
+ 'flex overflow-hidden': segments
40
77
  })
41
78
  );
42
79
 
43
80
  const fillClass = $derived(
44
81
  cn(
45
82
  'h-full rounded-full transition-all',
46
- {
47
- 'bg-primary-600': color === Color.PRIMARY,
48
- 'bg-secondary-600': color === Color.SECONDARY,
49
- 'bg-success-600': color === Color.SUCCESS,
50
- 'bg-danger-600': color === Color.DANGER,
51
- 'bg-warning-600': color === Color.WARNING,
52
- 'bg-info-600': color === Color.INFO,
53
- 'bg-gray-600': color === Color.DEFAULT
54
- },
83
+ segments ? '' : getColorClass(color),
55
84
  barClass
56
85
  )
57
86
  );
@@ -59,12 +88,11 @@
59
88
  const labelTextClass = $derived(
60
89
  cn(
61
90
  'text-gray-500',
91
+ getSizeTextClass(size),
62
92
  {
63
- 'text-xs': size === Size.XS || size === Size.SM,
64
- 'text-sm': size === Size.BASE,
65
- 'text-base': size === Size.LG || size === Size.XL,
66
- 'order-1': labelPosition === 'top',
67
- 'order-2': labelPosition === 'bottom'
93
+ 'order-1': !segments && labelPosition === 'top',
94
+ 'order-2': !segments && labelPosition === 'bottom',
95
+ 'mt-1': segments
68
96
  },
69
97
  labelClass
70
98
  )
@@ -79,9 +107,39 @@
79
107
  aria-valuemin="0"
80
108
  aria-valuemax="100"
81
109
  >
82
- <div class={fillClass} style="width: {percentage}%"></div>
110
+ {#if segments}
111
+ {#each segmentPercentages as segment}
112
+ {#if segment.percentage > 0}
113
+ <div
114
+ class={cn(getColorClass(segment.color), barClass)}
115
+ style="width: {segment.percentage}%"
116
+ title={segment.label || `${segment.value} (${segment.percentage}%)`}
117
+ ></div>
118
+ {/if}
119
+ {/each}
120
+ {:else}
121
+ <div class={fillClass} style="width: {percentage}%"></div>
122
+ {/if}
83
123
  </div>
84
- {#if showLabel}
124
+
125
+ {#if segments && (showLabels || showValues)}
126
+ <div class="flex justify-between mt-1">
127
+ {#each segmentPercentages as segment}
128
+ {#if segment.percentage > 0}
129
+ <div class={labelTextClass}>
130
+ {#if showLabels && segment.label}
131
+ {segment.label}
132
+ {/if}
133
+ {#if showValues}
134
+ {#if showLabels && segment.label} ({/if}
135
+ {segment.percentage}%
136
+ {#if showLabels && segment.label}){/if}
137
+ {/if}
138
+ </div>
139
+ {/if}
140
+ {/each}
141
+ </div>
142
+ {:else if showLabel}
85
143
  <span class={labelTextClass}>{percentage}%</span>
86
144
  {/if}
87
145
  </div>
package/dist/index.d.ts CHANGED
@@ -177,7 +177,7 @@ export type TableColumn = {
177
177
  sortable?: boolean;
178
178
  align?: 'left' | 'center' | 'right';
179
179
  width?: string;
180
- cell?: (value: any, row: DataRow) => string | Snippet;
180
+ cell?: (value: any, row: DataRow) => string | ReturnType<import("svelte").Snippet>;
181
181
  };
182
182
  export type TableProps = {
183
183
  data: DataRow[];
@@ -700,34 +700,26 @@ export interface SliderProps {
700
700
  notation?: NotationType;
701
701
  };
702
702
  }
703
- export type ProgressProps = {
704
- value: number;
705
- max?: number;
706
- size?: VariantSizes;
707
- color?: VariantColors;
708
- showLabel?: boolean;
709
- labelPosition?: 'top' | 'bottom' | 'right';
710
- class?: string;
711
- labelClass?: string;
712
- barClass?: string;
713
- };
714
703
  export type ProgressSegment = {
715
704
  value: number;
716
705
  color: VariantColors;
717
706
  label?: string;
718
707
  };
719
- export type DividedProgressProps = {
720
- segments: ProgressSegment[];
708
+ export type ProgressProps = {
709
+ value: number;
721
710
  max?: number;
722
711
  size?: VariantSizes;
712
+ color?: VariantColors;
713
+ showLabel?: boolean;
714
+ labelPosition?: 'top' | 'bottom' | 'right';
715
+ segments?: ProgressSegment[];
723
716
  showLabels?: boolean;
724
717
  showValues?: boolean;
725
- class?: string;
726
- barClass?: string;
718
+ class?: ClassValue;
727
719
  labelClass?: string;
720
+ barClass?: string;
728
721
  };
729
722
  export { default as Progress } from './elements/progress/Progress.svelte';
730
- export { default as DividedProgress } from './elements/progress/DividedProgress.svelte';
731
723
  export interface TimelineItem {
732
724
  title: string;
733
725
  time: Date | string;
package/dist/index.js CHANGED
@@ -62,5 +62,4 @@ export { default as DateRange } from './forms/DateRange.svelte';
62
62
  export { default as Tags } from './forms/Tags.svelte';
63
63
  export { default as RadioPill } from './forms/RadioPill.svelte';
64
64
  export { default as Progress } from './elements/progress/Progress.svelte';
65
- export { default as DividedProgress } from './elements/progress/DividedProgress.svelte';
66
65
  export { default as Timeline } from './elements/timeline/Timeline.svelte';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makolabs/ripple",
3
- "version": "0.0.1-dev.17",
3
+ "version": "0.0.1-dev.19",
4
4
  "description": "Simple Svelte 5 powered component library ✨",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,112 +0,0 @@
1
- <script lang="ts">
2
- import { cn } from '../../helper/cls.js';
3
- import { Color, Size } from '../../variants.js';
4
- import type { DividedProgressProps, ProgressSegment, VariantColors } from '../../index.js';
5
-
6
- let {
7
- segments,
8
- max = 100,
9
- size = Size.BASE,
10
- showLabels = false,
11
- showValues = true,
12
- class: className = '',
13
- barClass = '',
14
- labelClass = ''
15
- }: DividedProgressProps = $props();
16
-
17
- // Calculate derived values
18
- const totalValue = $derived(calculateTotalValue(segments));
19
- const segmentPercentages = $derived(calculateSegmentPercentages(segments, max));
20
-
21
- // Function composition - each function has a single responsibility
22
- function calculateTotalValue(segments: ProgressSegment[]): number {
23
- return segments.reduce((sum, segment) => sum + segment.value, 0);
24
- }
25
-
26
- function calculatePercentage(value: number, max: number): number {
27
- return Math.min(Math.round((value / max) * 100), 100);
28
- }
29
-
30
- function calculateSegmentPercentages(segments: ProgressSegment[], max: number) {
31
- return segments.map(segment => ({
32
- ...segment,
33
- percentage: calculatePercentage(segment.value, max)
34
- }));
35
- }
36
-
37
- // Class compositions
38
- const containerClass = $derived(cn('relative w-full', className));
39
-
40
- const progressClass = $derived(
41
- cn('w-full rounded-full bg-gray-200 flex overflow-hidden', {
42
- 'h-1.5': size === Size.XS,
43
- 'h-2': size === Size.SM,
44
- 'h-2.5': size === Size.BASE,
45
- 'h-3': size === Size.LG,
46
- 'h-4': size === Size.XL
47
- })
48
- );
49
-
50
- function getColorClass(color: VariantColors): string {
51
- const colorMap = {
52
- [Color.PRIMARY]: 'bg-primary-600',
53
- [Color.SECONDARY]: 'bg-secondary-600',
54
- [Color.SUCCESS]: 'bg-success-600',
55
- [Color.DANGER]: 'bg-danger-600',
56
- [Color.WARNING]: 'bg-warning-600',
57
- [Color.INFO]: 'bg-info-600',
58
- [Color.DEFAULT]: 'bg-gray-600'
59
- };
60
-
61
- return colorMap[color] || 'bg-primary-600';
62
- }
63
-
64
- function getSizeTextClass(size: string): string {
65
- if (size === Size.XS || size === Size.SM) return 'text-xs';
66
- if (size === Size.BASE) return 'text-sm';
67
- return 'text-base'; // For Size.LG, Size.XL, and any other sizes
68
- }
69
-
70
- const labelTextClass = $derived(
71
- cn('text-gray-500 mt-1', getSizeTextClass(size), labelClass)
72
- );
73
- </script>
74
-
75
- <div class={containerClass}>
76
- <div
77
- class={progressClass}
78
- role="progressbar"
79
- aria-valuenow={totalValue}
80
- aria-valuemin="0"
81
- aria-valuemax={max}
82
- >
83
- {#each segmentPercentages as segment}
84
- {#if segment.percentage > 0}
85
- <div
86
- class={cn(getColorClass(segment.color), barClass)}
87
- style="width: {segment.percentage}%"
88
- title={segment.label || `${segment.value} (${segment.percentage}%)`}
89
- ></div>
90
- {/if}
91
- {/each}
92
- </div>
93
-
94
- {#if showLabels || showValues}
95
- <div class="flex justify-between mt-1">
96
- {#each segmentPercentages as segment}
97
- {#if segment.percentage > 0}
98
- <div class={labelTextClass}>
99
- {#if showLabels && segment.label}
100
- {segment.label}
101
- {/if}
102
- {#if showValues}
103
- {#if showLabels && segment.label} ({/if}
104
- {segment.percentage}%
105
- {#if showLabels && segment.label}){/if}
106
- {/if}
107
- </div>
108
- {/if}
109
- {/each}
110
- </div>
111
- {/if}
112
- </div>
@@ -1,4 +0,0 @@
1
- import type { DividedProgressProps } from '../../index.js';
2
- declare const DividedProgress: import("svelte").Component<DividedProgressProps, {}, "">;
3
- type DividedProgress = ReturnType<typeof DividedProgress>;
4
- export default DividedProgress;