flowbite-svelte 1.28.3 → 1.29.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.
Files changed (103) hide show
  1. package/dist/command-palette/CommandPalette.svelte +1 -1
  2. package/dist/command-palette/CommandPalette.svelte.d.ts +1 -1
  3. package/dist/kanban/KanbanCard.svelte +1 -1
  4. package/dist/kanban/KanbanCard.svelte.d.ts +1 -1
  5. package/dist/scroll-spy/ScrollSpy.svelte +1 -1
  6. package/dist/scroll-spy/ScrollSpy.svelte.d.ts +1 -1
  7. package/dist/split-pane/Divider.svelte +1 -1
  8. package/dist/split-pane/Divider.svelte.d.ts +1 -1
  9. package/dist/split-pane/Pane.svelte +1 -1
  10. package/dist/split-pane/Pane.svelte.d.ts +1 -1
  11. package/dist/split-pane/SplitPane.svelte +1 -1
  12. package/dist/split-pane/SplitPane.svelte.d.ts +1 -1
  13. package/dist/stepper/BreadcrumbStepper.svelte +118 -33
  14. package/dist/stepper/BreadcrumbStepper.svelte.d.ts +6 -3
  15. package/dist/stepper/CheckmarkIcon.svelte +92 -0
  16. package/dist/stepper/CheckmarkIcon.svelte.d.ts +18 -0
  17. package/dist/stepper/DetailedStepper.svelte +133 -27
  18. package/dist/stepper/DetailedStepper.svelte.d.ts +7 -4
  19. package/dist/stepper/DoubleArrowIcon.svelte +34 -0
  20. package/dist/stepper/DoubleArrowIcon.svelte.d.ts +15 -0
  21. package/dist/stepper/ProfileCardIcon.svelte +25 -0
  22. package/dist/stepper/ProfileCardIcon.svelte.d.ts +15 -0
  23. package/dist/stepper/ProgressStepper.svelte +135 -34
  24. package/dist/stepper/ProgressStepper.svelte.d.ts +7 -4
  25. package/dist/stepper/Stepper.svelte +87 -33
  26. package/dist/stepper/Stepper.svelte.d.ts +6 -3
  27. package/dist/stepper/TimelineStepper.svelte +95 -35
  28. package/dist/stepper/TimelineStepper.svelte.d.ts +6 -3
  29. package/dist/stepper/VerticalStepper.svelte +91 -29
  30. package/dist/stepper/VerticalStepper.svelte.d.ts +6 -3
  31. package/dist/stepper/index.d.ts +3 -0
  32. package/dist/stepper/index.js +3 -0
  33. package/dist/stepper/theme.d.ts +6 -18
  34. package/dist/stepper/theme.js +18 -23
  35. package/dist/table/Table.svelte +1 -1
  36. package/dist/table/Table.svelte.d.ts +1 -1
  37. package/dist/table/TableBody.svelte +1 -1
  38. package/dist/table/TableBody.svelte.d.ts +1 -1
  39. package/dist/table/TableBodyCell.svelte +1 -1
  40. package/dist/table/TableBodyCell.svelte.d.ts +1 -1
  41. package/dist/table/TableBodyRow.svelte +1 -1
  42. package/dist/table/TableBodyRow.svelte.d.ts +1 -1
  43. package/dist/table/TableHead.svelte +1 -1
  44. package/dist/table/TableHead.svelte.d.ts +1 -1
  45. package/dist/table/TableHeadCell.svelte +1 -1
  46. package/dist/table/TableHeadCell.svelte.d.ts +1 -1
  47. package/dist/table/TableSearch.svelte +1 -1
  48. package/dist/table/TableSearch.svelte.d.ts +1 -1
  49. package/dist/tabs/TabItem.svelte +1 -1
  50. package/dist/tabs/TabItem.svelte.d.ts +1 -1
  51. package/dist/tabs/Tabs.svelte +1 -1
  52. package/dist/tabs/Tabs.svelte.d.ts +1 -1
  53. package/dist/timeline/Activity.svelte +1 -1
  54. package/dist/timeline/Activity.svelte.d.ts +1 -1
  55. package/dist/timeline/ActivityItem.svelte +1 -1
  56. package/dist/timeline/ActivityItem.svelte.d.ts +1 -1
  57. package/dist/timeline/Group.svelte +1 -1
  58. package/dist/timeline/Group.svelte.d.ts +1 -1
  59. package/dist/timeline/GroupItem.svelte +1 -1
  60. package/dist/timeline/GroupItem.svelte.d.ts +1 -1
  61. package/dist/timeline/Timeline.svelte +1 -1
  62. package/dist/timeline/Timeline.svelte.d.ts +1 -1
  63. package/dist/timeline/TimelineItem.svelte +1 -1
  64. package/dist/timeline/TimelineItem.svelte.d.ts +1 -1
  65. package/dist/toast/Toast.svelte +1 -1
  66. package/dist/toast/Toast.svelte.d.ts +1 -1
  67. package/dist/toast/ToastContainer.svelte +1 -1
  68. package/dist/toast/ToastContainer.svelte.d.ts +1 -1
  69. package/dist/tooltip/Tooltip.svelte +1 -1
  70. package/dist/tooltip/Tooltip.svelte.d.ts +1 -1
  71. package/dist/types.d.ts +52 -14
  72. package/dist/typography/a/A.svelte +1 -1
  73. package/dist/typography/a/A.svelte.d.ts +1 -1
  74. package/dist/typography/blockquote/Blockquote.svelte +1 -1
  75. package/dist/typography/blockquote/Blockquote.svelte.d.ts +1 -1
  76. package/dist/typography/descriptionlist/DescriptionList.svelte +1 -1
  77. package/dist/typography/descriptionlist/DescriptionList.svelte.d.ts +1 -1
  78. package/dist/typography/heading/Heading.svelte +1 -1
  79. package/dist/typography/heading/Heading.svelte.d.ts +1 -1
  80. package/dist/typography/img/Img.svelte +1 -1
  81. package/dist/typography/img/Img.svelte.d.ts +1 -1
  82. package/dist/typography/layout/Layout.svelte +1 -1
  83. package/dist/typography/layout/Layout.svelte.d.ts +1 -1
  84. package/dist/typography/list/Li.svelte +1 -1
  85. package/dist/typography/list/Li.svelte.d.ts +1 -1
  86. package/dist/typography/list/List.svelte +1 -1
  87. package/dist/typography/list/List.svelte.d.ts +1 -1
  88. package/dist/typography/list/theme.js +1 -1
  89. package/dist/typography/mark/Mark.svelte +1 -1
  90. package/dist/typography/mark/Mark.svelte.d.ts +1 -1
  91. package/dist/typography/paragraph/P.svelte +1 -1
  92. package/dist/typography/paragraph/P.svelte.d.ts +1 -1
  93. package/dist/typography/secondary/Secondary.svelte +1 -1
  94. package/dist/typography/secondary/Secondary.svelte.d.ts +1 -1
  95. package/dist/typography/span/Span.svelte +1 -1
  96. package/dist/typography/span/Span.svelte.d.ts +1 -1
  97. package/dist/utils/Arrow.svelte +1 -1
  98. package/dist/utils/Arrow.svelte.d.ts +1 -1
  99. package/dist/utils/Popper.svelte +1 -1
  100. package/dist/utils/Popper.svelte.d.ts +1 -1
  101. package/dist/video/Video.svelte +1 -1
  102. package/dist/video/Video.svelte.d.ts +1 -1
  103. package/package.json +15 -3
@@ -194,7 +194,7 @@
194
194
  @component
195
195
  [Go to docs](https://flowbite-svelte.com/)
196
196
  ## Type
197
- [CommandPaletteProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2213)
197
+ [CommandPaletteProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2233)
198
198
  ## Props
199
199
  @prop open = $bindable(false)
200
200
  @prop items = []
@@ -2,7 +2,7 @@ import type { CommandPaletteProps } from "../types";
2
2
  /**
3
3
  * [Go to docs](https://flowbite-svelte.com/)
4
4
  * ## Type
5
- * [CommandPaletteProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2213)
5
+ * [CommandPaletteProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2233)
6
6
  * ## Props
7
7
  * @prop open = $bindable(false)
8
8
  * @prop items = []
@@ -47,7 +47,7 @@
47
47
  @component
48
48
  [Go to docs](https://flowbite-svelte.com/)
49
49
  ## Type
50
- [KanbanCardProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2142)
50
+ [KanbanCardProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2162)
51
51
  ## Props
52
52
  @prop card
53
53
  @prop isDragging = false
@@ -2,7 +2,7 @@ import type { KanbanCardProps } from "../types";
2
2
  /**
3
3
  * [Go to docs](https://flowbite-svelte.com/)
4
4
  * ## Type
5
- * [KanbanCardProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2142)
5
+ * [KanbanCardProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2162)
6
6
  * ## Props
7
7
  * @prop card
8
8
  * @prop isDragging = false
@@ -255,7 +255,7 @@
255
255
  @component
256
256
  [Go to docs](https://flowbite-svelte.com/)
257
257
  ## Type
258
- [ScrollSpyProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2228)
258
+ [ScrollSpyProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2248)
259
259
  ## Props
260
260
  @prop items
261
261
  @prop position = "top"
@@ -2,7 +2,7 @@ import type { ScrollSpyProps } from "../types";
2
2
  /**
3
3
  * [Go to docs](https://flowbite-svelte.com/)
4
4
  * ## Type
5
- * [ScrollSpyProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2228)
5
+ * [ScrollSpyProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2248)
6
6
  * ## Props
7
7
  * @prop items
8
8
  * @prop position = "top"
@@ -37,7 +37,7 @@
37
37
  @component
38
38
  [Go to docs](https://flowbite-svelte.com/)
39
39
  ## Type
40
- [DividerProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2171)
40
+ [DividerProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2191)
41
41
  ## Props
42
42
  @prop direction
43
43
  @prop index
@@ -2,7 +2,7 @@ import type { DividerProps } from "../types";
2
2
  /**
3
3
  * [Go to docs](https://flowbite-svelte.com/)
4
4
  * ## Type
5
- * [DividerProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2171)
5
+ * [DividerProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2191)
6
6
  * ## Props
7
7
  * @prop direction
8
8
  * @prop index
@@ -47,7 +47,7 @@
47
47
  @component
48
48
  [Go to docs](https://flowbite-svelte.com/)
49
49
  ## Type
50
- [PaneProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2165)
50
+ [PaneProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2185)
51
51
  ## Props
52
52
  @prop children
53
53
  @prop class: className = ""
@@ -2,7 +2,7 @@ import type { PaneProps } from "../types";
2
2
  /**
3
3
  * [Go to docs](https://flowbite-svelte.com/)
4
4
  * ## Type
5
- * [PaneProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2165)
5
+ * [PaneProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2185)
6
6
  * ## Props
7
7
  * @prop children
8
8
  * @prop class: className = ""
@@ -410,7 +410,7 @@
410
410
  @component
411
411
  [Go to docs](https://flowbite-svelte.com/)
412
412
  ## Type
413
- [SplitPaneProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2151)
413
+ [SplitPaneProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2171)
414
414
  ## Props
415
415
  @prop direction = "horizontal"
416
416
  @prop minSize = 100
@@ -15,7 +15,7 @@ import type { SplitPaneProps } from "../types";
15
15
  /**
16
16
  * [Go to docs](https://flowbite-svelte.com/)
17
17
  * ## Type
18
- * [SplitPaneProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2151)
18
+ * [SplitPaneProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L2171)
19
19
  * ## Props
20
20
  * @prop direction = "horizontal"
21
21
  * @prop minSize = 100
@@ -1,65 +1,150 @@
1
1
  <script lang="ts">
2
2
  import { setContext } from "svelte";
3
+ import CheckmarkIcon from "./CheckmarkIcon.svelte";
4
+ import DoubleArrowIcon from "./DoubleArrowIcon.svelte";
3
5
  import { breadcrumbStepper } from "./theme";
4
6
  import clsx from "clsx";
5
7
  import type { BreadcrumbStepperProps } from "../types";
6
8
  import { getTheme } from "../theme/themeUtils";
7
9
 
8
- let { children, steps = [], class: className, classes, ...restProps }: BreadcrumbStepperProps = $props();
10
+ let { steps = [], class: className, classes, current = $bindable(1), clickable = true, showCheckmarkForCompleted = true, onStepClick, ...restProps }: BreadcrumbStepperProps = $props();
11
+
12
+ // Ensure current is within valid bounds
13
+ $effect(() => {
14
+ if (current < 0) current = 0;
15
+ if (current > steps.length && steps.length > 0) current = steps.length;
16
+ });
9
17
 
10
18
  const theme = getTheme("breadcrumbStepper");
11
19
 
12
20
  setContext("stepperType", "breadcrumb");
13
21
 
14
22
  const { base, item, indicator } = $derived(breadcrumbStepper());
15
- // { class: clsx(theme?.stepper) }
23
+
24
+ // Handle step click
25
+ function handleStepClick(stepIndex: number) {
26
+ if (clickable && stepIndex < steps.length) {
27
+ const last = current;
28
+ // Convert 0-based array index to 1-based current value
29
+ current = stepIndex + 1;
30
+
31
+ // Call custom onStepClick if provided
32
+ if (onStepClick) {
33
+ onStepClick({ current, last });
34
+ }
35
+ }
36
+ }
37
+
38
+ // Determine step status - reactive to current changes
39
+ function getStepStatus(stepIndex: number): "completed" | "current" | "pending" {
40
+ if (current === 0) {
41
+ return "pending";
42
+ }
43
+ if (stepIndex < current - 1) {
44
+ return "completed";
45
+ } else if (stepIndex === current - 1) {
46
+ return "current";
47
+ } else {
48
+ return "pending";
49
+ }
50
+ }
16
51
  </script>
17
52
 
18
53
  <ol class={base({ class: clsx(theme?.base, className) })} {...restProps}>
19
- {#if children}
20
- {@render children()}
21
- {:else if steps}
22
- {#each steps as step, index (step.id)}
23
- <li
24
- class={item({
25
- status: step.status,
26
- hasChevron: index < steps.length - 1,
27
- class: clsx(theme?.item, classes?.item)
28
- })}
29
- >
30
- <span class={indicator({ status: step.status, class: clsx(theme?.indicator, classes?.indicator) })}>
31
- {#if step.status === "completed" && step.icon}
32
- <step.icon class={step.iconClass || "h-3 w-3"} />
33
- {:else}
34
- {step.id}
54
+ {#each steps as step, index (step.id)}
55
+ {@const status = step.status ?? getStepStatus(index)}
56
+ <li
57
+ class={item({
58
+ status,
59
+ hasChevron: index < steps.length - 1,
60
+ class: clsx(theme?.item, classes?.item)
61
+ })}
62
+ >
63
+ {#if clickable}
64
+ <button
65
+ type="button"
66
+ class="flex cursor-pointer items-center transition-opacity hover:opacity-75"
67
+ onclick={() => handleStepClick(index)}
68
+ aria-current={status === "current" ? "step" : undefined}
69
+ >
70
+ <span class={indicator({ status, class: clsx(theme?.indicator, classes?.indicator) })}>
71
+ {#if status === "completed" && showCheckmarkForCompleted}
72
+ {#if step.icon}
73
+ <step.icon class={step.iconClass || "h-3 w-3"} />
74
+ {:else}
75
+ <CheckmarkIcon variant="simple" class="h-3 w-3" />
76
+ {/if}
77
+ {:else if step.icon}
78
+ <step.icon class={step.iconClass || "h-3 w-3"} />
79
+ {:else}
80
+ {step.id}
81
+ {/if}
82
+ </span>
83
+
84
+ {step.label}
85
+
86
+ {#if step.shortLabel}
87
+ <span class="hidden sm:ms-2 sm:inline-flex">{step.shortLabel}</span>
35
88
  {/if}
36
- </span>
89
+ </button>
90
+ {:else}
91
+ <span aria-current={status === "current" ? "step" : undefined} class="flex items-center">
92
+ <span class={indicator({ status, class: clsx(theme?.indicator, classes?.indicator) })}>
93
+ {#if status === "completed" && showCheckmarkForCompleted}
94
+ {#if step.icon}
95
+ <step.icon class={step.iconClass || "h-3 w-3"} />
96
+ {:else}
97
+ <CheckmarkIcon variant="simple" class="h-3 w-3" />
98
+ {/if}
99
+ {:else if step.icon}
100
+ <step.icon class={step.iconClass || "h-3 w-3"} />
101
+ {:else}
102
+ {step.id}
103
+ {/if}
104
+ </span>
37
105
 
38
- {step.label}
106
+ {step.label}
39
107
 
40
- {#if step.shortLabel}
41
- <span class="hidden sm:ms-2 sm:inline-flex">{step.shortLabel}</span>
42
- {/if}
108
+ {#if step.shortLabel}
109
+ <span class="hidden sm:ms-2 sm:inline-flex">{step.shortLabel}</span>
110
+ {/if}
111
+ </span>
112
+ {/if}
43
113
 
44
- {#if index < steps.length - 1}
45
- <svg class="ms-2 h-3 w-3 sm:ms-4 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 12 10">
46
- <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m7 9 4-4-4-4M1 9l4-4-4-4" />
47
- </svg>
48
- {/if}
49
- </li>
50
- {/each}
51
- {/if}
114
+ {#if index < steps.length - 1}
115
+ <DoubleArrowIcon />
116
+ {/if}
117
+ </li>
118
+ {/each}
52
119
  </ol>
53
120
 
121
+ <!--
122
+ ## Features
123
+ - **Clickable navigation**: Click or press Enter/Space on steps to navigate
124
+ - **Auto status**: Automatically determines completed/current/pending status based on current index
125
+ - **Custom icons**: Support for custom icons on completed steps
126
+ - **Accessible**: Keyboard navigation with proper ARIA attributes
127
+
128
+ ## Note
129
+ The `current` prop is 1-based:
130
+ - current=0 means no step is active (all pending)
131
+ - current=1 means first step is active
132
+ - current=2 means first step is completed, second step is active
133
+ - etc.
134
+ -->
135
+
54
136
  <!--
55
137
  @component
56
138
  [Go to docs](https://flowbite-svelte.com/)
57
139
  ## Type
58
- [BreadcrumbStepperProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L1655)
140
+ [BreadcrumbStepperProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L1669)
59
141
  ## Props
60
- @prop children
61
142
  @prop steps = []
62
143
  @prop class: className
63
144
  @prop classes
145
+ @prop current = $bindable(1)
146
+ @prop clickable = true
147
+ @prop showCheckmarkForCompleted = true
148
+ @prop onStepClick
64
149
  @prop ...restProps
65
150
  -->
@@ -2,14 +2,17 @@ import type { BreadcrumbStepperProps } from "../types";
2
2
  /**
3
3
  * [Go to docs](https://flowbite-svelte.com/)
4
4
  * ## Type
5
- * [BreadcrumbStepperProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L1655)
5
+ * [BreadcrumbStepperProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L1669)
6
6
  * ## Props
7
- * @prop children
8
7
  * @prop steps = []
9
8
  * @prop class: className
10
9
  * @prop classes
10
+ * @prop current = $bindable(1)
11
+ * @prop clickable = true
12
+ * @prop showCheckmarkForCompleted = true
13
+ * @prop onStepClick
11
14
  * @prop ...restProps
12
15
  */
13
- declare const BreadcrumbStepper: import("svelte").Component<BreadcrumbStepperProps, {}, "">;
16
+ declare const BreadcrumbStepper: import("svelte").Component<BreadcrumbStepperProps, {}, "current">;
14
17
  type BreadcrumbStepper = ReturnType<typeof BreadcrumbStepper>;
15
18
  export default BreadcrumbStepper;
@@ -0,0 +1,92 @@
1
+ <script lang="ts">
2
+ import type { SVGAttributes } from "svelte/elements";
3
+
4
+ type IconVariant = "default" | "simple" | "tick";
5
+
6
+ interface IconPropsType {
7
+ viewBox: string;
8
+ fill: string | "none";
9
+ pathData?: string;
10
+ pointsData?: string;
11
+ stroke?: string;
12
+ "stroke-width"?: string;
13
+ "stroke-linecap"?: "round" | "butt" | "square" | "inherit";
14
+ "stroke-linejoin"?: "round" | "bevel" | "miter" | "inherit";
15
+ }
16
+
17
+ interface Props extends SVGAttributes<SVGSVGElement> {
18
+ class?: string;
19
+ variant?: IconVariant;
20
+ }
21
+
22
+ let { class: className, variant = "default", ...restProps }: Props = $props();
23
+
24
+ // 1. 'default' (Check inside a circle) - FILL ICON
25
+ const defaultIconProps: IconPropsType = {
26
+ viewBox: "0 0 20 20",
27
+ fill: "currentColor",
28
+ pathData: "M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 8.207-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L9 10.586l3.293-3.293a1 1 0 0 1 1.414 1.414Z",
29
+ stroke: undefined,
30
+ "stroke-linecap": undefined,
31
+ "stroke-linejoin": undefined,
32
+ "stroke-width": undefined
33
+ };
34
+
35
+ // 2. 'simple' (Basic check stroke path) - STROKE ICON
36
+ const simpleIconProps: IconPropsType = {
37
+ viewBox: "0 0 16 12",
38
+ fill: "none",
39
+ pathData: "M1 5.917 5.724 10.5 15 1.5",
40
+ stroke: "currentColor",
41
+ "stroke-linecap": "round",
42
+ "stroke-linejoin": "round",
43
+ "stroke-width": "2"
44
+ };
45
+
46
+ // 3. 'tick' (New V-shaped check stroke) - STROKE ICON
47
+ const polylineIconProps: IconPropsType = {
48
+ viewBox: "0 0 24 24",
49
+ fill: "none",
50
+ pointsData: "20 6 9 17 4 12",
51
+ stroke: "currentColor",
52
+ "stroke-width": "2",
53
+ "stroke-linecap": "round",
54
+ "stroke-linejoin": "round"
55
+ };
56
+
57
+ // Select the appropriate props based on the variant
58
+ const iconProps = variant === "simple" ? simpleIconProps : variant === "tick" ? polylineIconProps : defaultIconProps;
59
+
60
+ // Determine the base class for the SVG
61
+ const baseClass = className || (variant !== "default" ? "h-4 w-4" : "me-2.5 h-3.5 w-3.5 sm:h-4 sm:w-4");
62
+ </script>
63
+
64
+ <svg
65
+ class={baseClass}
66
+ aria-hidden="true"
67
+ xmlns="http://www.w3.org/2000/svg"
68
+ viewBox={iconProps.viewBox}
69
+ fill={iconProps.fill}
70
+ stroke={iconProps.stroke}
71
+ stroke-width={iconProps["stroke-width"]}
72
+ stroke-linecap={iconProps["stroke-linecap"]}
73
+ stroke-linejoin={iconProps["stroke-linejoin"]}
74
+ {...restProps}
75
+ >
76
+ {#if iconProps.pointsData}
77
+ <polyline points={iconProps.pointsData} />
78
+ {:else}
79
+ <path d={iconProps.pathData} />
80
+ {/if}
81
+ </svg>
82
+
83
+ <!--
84
+ @component
85
+ [Go to docs](https://flowbite-svelte.com/)
86
+ ## Type
87
+ Props
88
+ ## Props
89
+ @prop class: className
90
+ @prop variant = "default"
91
+ @prop ...restProps
92
+ -->
@@ -0,0 +1,18 @@
1
+ import type { SVGAttributes } from "svelte/elements";
2
+ type IconVariant = "default" | "simple" | "tick";
3
+ interface Props extends SVGAttributes<SVGSVGElement> {
4
+ class?: string;
5
+ variant?: IconVariant;
6
+ }
7
+ /**
8
+ * [Go to docs](https://flowbite-svelte.com/)
9
+ * ## Type
10
+ * Props
11
+ * ## Props
12
+ * @prop class: className
13
+ * @prop variant = "default"
14
+ * @prop ...restProps
15
+ */
16
+ declare const CheckmarkIcon: import("svelte").Component<Props, {}, "">;
17
+ type CheckmarkIcon = ReturnType<typeof CheckmarkIcon>;
18
+ export default CheckmarkIcon;
@@ -1,53 +1,159 @@
1
1
  <script lang="ts">
2
2
  import { setContext } from "svelte";
3
+ import CheckmarkIcon from "./CheckmarkIcon.svelte";
3
4
  import { detailedStepper } from "./theme";
4
5
  import type { DetailedStepperProps } from "../types";
5
6
  import clsx from "clsx";
6
7
  import { getTheme } from "../theme/themeUtils";
7
8
 
8
- let { children, steps = [], contentClass, class: className, classes, ...restrorps }: DetailedStepperProps = $props();
9
+ let { steps = [], contentClass, class: className, classes, current = $bindable(0), clickable = true, showCheckmarkForCompleted = true, onStepClick, ...restProps }: DetailedStepperProps = $props();
10
+
11
+ // Ensure current is within valid bounds
12
+ $effect(() => {
13
+ if (current < 0) current = 0;
14
+ if (current > steps.length && steps.length > 0) current = steps.length;
15
+ });
9
16
 
10
17
  const theme = getTheme("detailedStepper");
11
18
 
12
19
  setContext("stepperType", "detailed");
13
20
 
14
- const { base, item, indicator } = $derived(detailedStepper());
21
+ // Override the theme to make current step also highlighted
22
+ const stepperTheme = $derived(() => {
23
+ const baseTheme = detailedStepper();
24
+ return {
25
+ base: baseTheme.base,
26
+ item: (props: { status: "completed" | "current" | "pending"; class?: string }) => {
27
+ // Make current status use the same styling as completed
28
+ const status = props.status === "current" ? "completed" : props.status;
29
+ return baseTheme.item({ ...props, status });
30
+ },
31
+ indicator: (props: { status: "completed" | "current" | "pending"; class?: string }) => {
32
+ // Make current status use the same styling as completed
33
+ const status = props.status === "current" ? "completed" : props.status;
34
+ return baseTheme.indicator({ ...props, status });
35
+ }
36
+ };
37
+ });
38
+
39
+ const { base, item, indicator } = $derived(stepperTheme());
40
+
41
+ // Handle step click
42
+ function handleStepClick(stepIndex: number) {
43
+ if (clickable && stepIndex < steps.length) {
44
+ const last = current;
45
+ // Convert 0-based array index to 1-based current value
46
+ current = stepIndex + 1;
47
+
48
+ // Call custom onStepClick if provided
49
+ if (onStepClick) {
50
+ onStepClick({ current, last });
51
+ }
52
+ }
53
+ }
54
+
55
+ // Determine step status - reactive to current changes
56
+ // current = 0: no items highlighted (all pending)
57
+ // current = 1: first item is current
58
+ // current = 2: first is completed, second is current
59
+ function getStepStatus(stepIndex: number): "completed" | "current" | "pending" {
60
+ if (current === 0) {
61
+ return "pending";
62
+ }
63
+ if (stepIndex < current - 1) {
64
+ return "completed";
65
+ } else if (stepIndex === current - 1) {
66
+ return "current";
67
+ } else {
68
+ return "pending";
69
+ }
70
+ }
15
71
  </script>
16
72
 
17
- <ol class={base({ class: clsx(theme?.base, className) })} {...restrorps}>
18
- {#if children}
19
- {@render children()}
20
- {:else if steps}
21
- {#each steps as step (step.id)}
22
- <li class={item({ status: step.status, class: clsx(theme?.item, classes?.item) })}>
23
- <span class={indicator({ status: step.status, class: clsx(theme?.indicator, classes?.indicator) })}>
24
- {#if step.status === "completed" && step.icon}
25
- <step.icon class={clsx(step.iconClass)} />
26
- {:else}
27
- {step.id}
28
- {/if}
29
- </span>
30
- <span class={clsx(contentClass)}>
31
- <h3 class="leading-tight font-medium">{step.label}</h3>
32
- {#if step.description}
33
- <p class="text-sm">{step.description}</p>
34
- {/if}
35
- </span>
36
- </li>
37
- {/each}
38
- {/if}
73
+ <ol class={base({ class: clsx(theme?.base, className) })} {...restProps}>
74
+ {#each steps as step, index (step.id)}
75
+ {@const status = step.status ?? getStepStatus(index)}
76
+ <li class={item({ status, class: clsx(theme?.item, classes?.item) })}>
77
+ {#if clickable}
78
+ <button
79
+ type="button"
80
+ class="flex w-full cursor-pointer items-center space-x-2.5 text-left transition-opacity hover:opacity-75 rtl:space-x-reverse"
81
+ onclick={() => handleStepClick(index)}
82
+ aria-current={status === "current" ? "step" : undefined}
83
+ >
84
+ <span class={indicator({ status, class: clsx(theme?.indicator, classes?.indicator) })}>
85
+ {#if status === "completed" && showCheckmarkForCompleted}
86
+ <!-- Checkmark for completed steps -->
87
+ <CheckmarkIcon variant="tick" />
88
+ {:else if step.icon}
89
+ <!-- Show icon if provided -->
90
+ <step.icon class={clsx(step.iconClass)} />
91
+ {:else}
92
+ <!-- Show number for steps without icon -->
93
+ {step.id}
94
+ {/if}
95
+ </span>
96
+ <span class={clsx(contentClass)}>
97
+ <h3 class="leading-tight font-medium">{step.label}</h3>
98
+ {#if step.description}
99
+ <p class={clsx("text-sm", step.descriptionClass)}>{step.description}</p>
100
+ {/if}
101
+ </span>
102
+ </button>
103
+ {:else}
104
+ <div class="flex items-center space-x-2.5 rtl:space-x-reverse" aria-current={status === "current" ? "step" : undefined}>
105
+ <span class={indicator({ status, class: clsx(theme?.indicator, classes?.indicator) })}>
106
+ {#if status === "completed" && showCheckmarkForCompleted}
107
+ <!-- Checkmark for completed steps -->
108
+ <CheckmarkIcon variant="tick" />
109
+ {:else if step.icon}
110
+ <!-- Show icon if provided -->
111
+ <step.icon class={clsx(step.iconClass)} />
112
+ {:else}
113
+ <!-- Show number for steps without icon -->
114
+ {step.id}
115
+ {/if}
116
+ </span>
117
+ <span class={clsx(contentClass)}>
118
+ <h3 class="leading-tight font-medium">{step.label}</h3>
119
+ {#if step.description}
120
+ <p class={clsx("text-sm", step.descriptionClass)}>{step.description}</p>
121
+ {/if}
122
+ </span>
123
+ </div>
124
+ {/if}
125
+ </li>
126
+ {/each}
39
127
  </ol>
40
128
 
129
+ <!--
130
+ ## Features
131
+ - **Clickable navigation**: Click or press Enter/Space on steps to navigate
132
+ - **Auto status**: Automatically determines completed/current/pending status based on current index
133
+ - **Custom icons**: Support for custom icons on completed steps
134
+ - **Accessible**: Keyboard navigation with proper ARIA attributes
135
+
136
+ ## Note
137
+ The `current` prop is 1-based:
138
+ - current=0 means no step is active (all pending)
139
+ - current=1 means first step is active
140
+ - current=2 means first step is completed, second step is active
141
+ - etc.
142
+ -->
143
+
41
144
  <!--
42
145
  @component
43
146
  [Go to docs](https://flowbite-svelte.com/)
44
147
  ## Type
45
- [DetailedStepperProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L1624)
148
+ [DetailedStepperProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L1632)
46
149
  ## Props
47
- @prop children
48
150
  @prop steps = []
49
151
  @prop contentClass
50
152
  @prop class: className
51
153
  @prop classes
52
- @prop ...restrorps
154
+ @prop current = $bindable(0)
155
+ @prop clickable = true
156
+ @prop showCheckmarkForCompleted = true
157
+ @prop onStepClick
158
+ @prop ...restProps
53
159
  -->
@@ -2,15 +2,18 @@ import type { DetailedStepperProps } from "../types";
2
2
  /**
3
3
  * [Go to docs](https://flowbite-svelte.com/)
4
4
  * ## Type
5
- * [DetailedStepperProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L1624)
5
+ * [DetailedStepperProps](https://github.com/themesberg/flowbite-svelte/blob/main/src/lib/types.ts#L1632)
6
6
  * ## Props
7
- * @prop children
8
7
  * @prop steps = []
9
8
  * @prop contentClass
10
9
  * @prop class: className
11
10
  * @prop classes
12
- * @prop ...restrorps
11
+ * @prop current = $bindable(0)
12
+ * @prop clickable = true
13
+ * @prop showCheckmarkForCompleted = true
14
+ * @prop onStepClick
15
+ * @prop ...restProps
13
16
  */
14
- declare const DetailedStepper: import("svelte").Component<DetailedStepperProps, {}, "">;
17
+ declare const DetailedStepper: import("svelte").Component<DetailedStepperProps, {}, "current">;
15
18
  type DetailedStepper = ReturnType<typeof DetailedStepper>;
16
19
  export default DetailedStepper;