@makolabs/ripple 1.0.1 → 1.0.3

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
@@ -317,6 +317,8 @@ export { tv, cn } from './helper/cls.js';
317
317
  export { isRouteActive } from './helper/nav.svelte.js';
318
318
  export { default as Button } from './button/Button.svelte';
319
319
  export { default as Modal } from './modal/Modal.svelte';
320
+ export { default as Pipeline } from './pipeline/Pipeline.svelte';
321
+ export type { PipelineStage } from './pipeline/Pipeline.svelte';
320
322
  export { default as Drawer } from './drawer/Drawer.svelte';
321
323
  export { default as PageHeader } from './header/PageHeader.svelte';
322
324
  export { default as Breadcrumbs } from './header/Breadcrumbs.svelte';
package/dist/index.js CHANGED
@@ -16,6 +16,8 @@ export { isRouteActive } from './helper/nav.svelte.js';
16
16
  export { default as Button } from './button/Button.svelte';
17
17
  // Modal
18
18
  export { default as Modal } from './modal/Modal.svelte';
19
+ // Pipeline
20
+ export { default as Pipeline } from './pipeline/Pipeline.svelte';
19
21
  // Drawer
20
22
  export { default as Drawer } from './drawer/Drawer.svelte';
21
23
  // Header
@@ -0,0 +1,158 @@
1
+ <script lang="ts">
2
+ import { tv } from 'tailwind-variants';
3
+ import type { Snippet } from 'svelte';
4
+
5
+ export type PipelineStage = {
6
+ label: string;
7
+ count?: number | string;
8
+ color?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info';
9
+ active?: boolean;
10
+ };
11
+
12
+ interface Props {
13
+ stages: PipelineStage[];
14
+ class?: string;
15
+ size?: 'sm' | 'base' | 'lg';
16
+ equalWidth?: boolean;
17
+ children?: Snippet<[PipelineStage, number]>;
18
+ }
19
+
20
+ let {
21
+ stages = [],
22
+ class: className = '',
23
+ size = 'base',
24
+ equalWidth = true,
25
+ children
26
+ }: Props = $props();
27
+
28
+ const pipeline = tv({
29
+ slots: {
30
+ container: 'flex items-center gap-0 w-full',
31
+ stage: 'relative transition-all duration-300',
32
+ borderLayer: 'absolute inset-0 h-20 transition-all duration-300',
33
+ innerLayer: 'relative h-20 flex items-center justify-center bg-white transition-all duration-300',
34
+ content: 'text-center px-4',
35
+ label: 'text-xs mb-1 leading-tight font-medium tracking-wide text-gray-600',
36
+ count: 'text-2xl font-bold tracking-tight text-gray-900'
37
+ },
38
+ variants: {
39
+ size: {
40
+ sm: {
41
+ stage: 'min-w-[100px]',
42
+ borderLayer: 'h-16',
43
+ innerLayer: 'h-16',
44
+ label: 'text-xs',
45
+ count: 'text-lg',
46
+ content: 'px-3'
47
+ },
48
+ base: {
49
+ stage: 'min-w-[120px]',
50
+ borderLayer: 'h-20',
51
+ innerLayer: 'h-20',
52
+ label: 'text-xs',
53
+ count: 'text-2xl',
54
+ content: 'px-4'
55
+ },
56
+ lg: {
57
+ stage: 'min-w-[140px]',
58
+ borderLayer: 'h-24',
59
+ innerLayer: 'h-24',
60
+ label: 'text-sm',
61
+ count: 'text-3xl',
62
+ content: 'px-5'
63
+ }
64
+ },
65
+ color: {
66
+ default: {
67
+ borderLayer: 'bg-gray-200'
68
+ },
69
+ primary: {
70
+ borderLayer: 'bg-blue-500',
71
+ label: 'text-gray-700',
72
+ count: 'text-gray-900'
73
+ },
74
+ success: {
75
+ borderLayer: 'bg-green-500',
76
+ label: 'text-gray-700',
77
+ count: 'text-gray-900'
78
+ },
79
+ warning: {
80
+ borderLayer: 'bg-amber-500',
81
+ label: 'text-gray-700',
82
+ count: 'text-gray-900'
83
+ },
84
+ danger: {
85
+ borderLayer: 'bg-rose-500',
86
+ label: 'text-gray-700',
87
+ count: 'text-gray-900'
88
+ },
89
+ info: {
90
+ borderLayer: 'bg-purple-500',
91
+ label: 'text-gray-700',
92
+ count: 'text-gray-900'
93
+ }
94
+ },
95
+ active: {
96
+ true: {
97
+ borderLayer: 'ring-2 ring-blue-500 ring-offset-2'
98
+ }
99
+ },
100
+ equalWidth: {
101
+ true: {
102
+ stage: 'flex-1'
103
+ },
104
+ false: {
105
+ stage: ''
106
+ }
107
+ }
108
+ }
109
+ });
110
+
111
+ const styles = $derived(pipeline({ size, equalWidth }));
112
+
113
+ function getStageStyles(stage: PipelineStage) {
114
+ return pipeline({
115
+ size,
116
+ color: stage.color || 'default',
117
+ active: stage.active,
118
+ equalWidth
119
+ });
120
+ }
121
+ </script>
122
+
123
+ <div class="{styles.container()} {className}">
124
+ {#each stages as stage, index}
125
+ {@const isFirst = index === 0}
126
+ {@const isLast = index === stages.length - 1}
127
+ {@const chevronWidth = 20}
128
+
129
+ <div class={getStageStyles(stage).stage()} style="{!isFirst ? `margin-left: -${chevronWidth}px; z-index: ${stages.length - index}` : `z-index: ${stages.length - index}`}">
130
+ <!-- BACKGROUND LAYER (Border color - larger) -->
131
+ <div
132
+ class="{getStageStyles(stage).borderLayer()}"
133
+ style="clip-path: polygon({isFirst ? '0' : '0'} 0%, calc(100% - {chevronWidth}px) 0%, 100% 50%, calc(100% - {chevronWidth}px) 100%, {isFirst ? '0' : '0'} 100%, {isFirst ? '0' : `${chevronWidth}px`} 50%);"
134
+ ></div>
135
+
136
+ <!-- FOREGROUND LAYER (White - smaller, creates border effect) -->
137
+ <div
138
+ class="{getStageStyles(stage).innerLayer()}"
139
+ style="clip-path: polygon({isFirst ? '2px' : '2px'} 2px, calc(100% - {chevronWidth}px - 2px) 2px, calc(100% - 2px) 50%, calc(100% - {chevronWidth}px - 2px) calc(100% - 2px), {isFirst ? '2px' : '2px'} calc(100% - 2px), {isFirst ? '2px' : `${chevronWidth + 2}px`} 50%);"
140
+ >
141
+ <div class={getStageStyles(stage).content()}>
142
+ {#if children}
143
+ {@render children(stage, index)}
144
+ {:else}
145
+ <span class={getStageStyles(stage).label()}>
146
+ {stage.label}
147
+ </span>
148
+ {#if stage.count !== undefined}
149
+ <span class={getStageStyles(stage).count()}>
150
+ {stage.count}
151
+ </span>
152
+ {/if}
153
+ {/if}
154
+ </div>
155
+ </div>
156
+ </div>
157
+ {/each}
158
+ </div>
@@ -0,0 +1,17 @@
1
+ import type { Snippet } from 'svelte';
2
+ export type PipelineStage = {
3
+ label: string;
4
+ count?: number | string;
5
+ color?: 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info';
6
+ active?: boolean;
7
+ };
8
+ interface Props {
9
+ stages: PipelineStage[];
10
+ class?: string;
11
+ size?: 'sm' | 'base' | 'lg';
12
+ equalWidth?: boolean;
13
+ children?: Snippet<[PipelineStage, number]>;
14
+ }
15
+ declare const Pipeline: import("svelte").Component<Props, {}, "">;
16
+ type Pipeline = ReturnType<typeof Pipeline>;
17
+ export default Pipeline;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makolabs/ripple",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Simple Svelte 5 powered component library ✨",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "repository": {