@pequity/squirrel 8.0.2 → 8.1.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.
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ const vue = require("vue");
3
+ const pIcon_vue_vue_type_script_setup_true_lang = require("./p-icon.js");
4
+ const lodashEs = require("lodash-es");
5
+ const _hoisted_1 = { class: "flex items-center gap-2" };
6
+ const _hoisted_2 = {
7
+ key: 0,
8
+ class: "flex items-center"
9
+ };
10
+ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
11
+ __name: "p-steps",
12
+ props: {
13
+ steps: {},
14
+ currentStep: {},
15
+ stepTitleMap: {}
16
+ },
17
+ setup(__props) {
18
+ const props = __props;
19
+ const currentStepIndex = vue.computed(() => props.steps.findIndex((s) => s === props.currentStep));
20
+ const stepClasses = (step, stepIndex) => {
21
+ if (step === props.currentStep) {
22
+ return "border border-p-blue-50 bg-p-blue-50 text-surface";
23
+ }
24
+ if (currentStepIndex.value < stepIndex) {
25
+ return "border border-p-gray-30 text-p-gray-30";
26
+ }
27
+ return "border border-p-blue-50 text-p-blue-50";
28
+ };
29
+ const stepTitle = (step) => {
30
+ var _a;
31
+ return ((_a = props.stepTitleMap) == null ? void 0 : _a[step]) || lodashEs.startCase(step);
32
+ };
33
+ return (_ctx, _cache) => {
34
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
35
+ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(_ctx.steps, (step, idx) => {
36
+ return vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: step }, [
37
+ vue.createElementVNode("div", {
38
+ class: vue.normalizeClass(["text-nowrap rounded-full border px-4 py-1 text-sm font-semibold", stepClasses(step, idx)])
39
+ }, vue.toDisplayString(stepTitle(step)), 3),
40
+ idx < _ctx.steps.length - 1 ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2, [
41
+ vue.createVNode(pIcon_vue_vue_type_script_setup_true_lang._sfc_main, {
42
+ icon: "material-symbols:arrow-right-alt-rounded",
43
+ class: vue.normalizeClass([currentStepIndex.value <= idx ? "text-p-gray-30" : "text-p-blue-50"])
44
+ }, null, 8, ["class"])
45
+ ])) : vue.createCommentVNode("", true)
46
+ ], 64);
47
+ }), 128))
48
+ ]);
49
+ };
50
+ }
51
+ });
52
+ exports._sfc_main = _sfc_main;
package/dist/cjs/index.js CHANGED
@@ -42,6 +42,7 @@ const string = require("./string.js");
42
42
  const text = require("./text.js");
43
43
  const pSelectPill = require("./p-select-pill.js");
44
44
  const pSkeletonLoader = require("./p-skeleton-loader.js");
45
+ const pSteps_vue_vue_type_script_setup_true_lang = require("./chunks/p-steps.js");
45
46
  const pTable$1 = require("./p-table.js");
46
47
  const usePTableColResize = require("./usePTableColResize.js");
47
48
  const pTableHeaderCell = require("./p-table-header-cell.js");
@@ -1019,6 +1020,7 @@ exports.toString = string.toString;
1019
1020
  exports.splitStringForHighlight = text.splitStringForHighlight;
1020
1021
  exports.PSelectPill = pSelectPill;
1021
1022
  exports.PSkeletonLoader = pSkeletonLoader;
1023
+ exports.PSteps = pSteps_vue_vue_type_script_setup_true_lang._sfc_main;
1022
1024
  exports.MIN_WIDTH_COL_RESIZE = pTable$1.MIN_WIDTH_COL_RESIZE;
1023
1025
  exports.colsInjectionKey = pTable$1.colsInjectionKey;
1024
1026
  exports.isColsResizableInjectionKey = pTable$1.isColsResizableInjectionKey;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ const pSteps_vue_vue_type_script_setup_true_lang = require("./chunks/p-steps.js");
3
+ module.exports = pSteps_vue_vue_type_script_setup_true_lang._sfc_main;
@@ -0,0 +1,53 @@
1
+ import { defineComponent, computed, createElementBlock, openBlock, Fragment, renderList, createElementVNode, createCommentVNode, normalizeClass, toDisplayString, createVNode } from "vue";
2
+ import { _ as _sfc_main$1 } from "./p-icon.js";
3
+ import { startCase } from "lodash-es";
4
+ const _hoisted_1 = { class: "flex items-center gap-2" };
5
+ const _hoisted_2 = {
6
+ key: 0,
7
+ class: "flex items-center"
8
+ };
9
+ const _sfc_main = /* @__PURE__ */ defineComponent({
10
+ __name: "p-steps",
11
+ props: {
12
+ steps: {},
13
+ currentStep: {},
14
+ stepTitleMap: {}
15
+ },
16
+ setup(__props) {
17
+ const props = __props;
18
+ const currentStepIndex = computed(() => props.steps.findIndex((s) => s === props.currentStep));
19
+ const stepClasses = (step, stepIndex) => {
20
+ if (step === props.currentStep) {
21
+ return "border border-p-blue-50 bg-p-blue-50 text-surface";
22
+ }
23
+ if (currentStepIndex.value < stepIndex) {
24
+ return "border border-p-gray-30 text-p-gray-30";
25
+ }
26
+ return "border border-p-blue-50 text-p-blue-50";
27
+ };
28
+ const stepTitle = (step) => {
29
+ var _a;
30
+ return ((_a = props.stepTitleMap) == null ? void 0 : _a[step]) || startCase(step);
31
+ };
32
+ return (_ctx, _cache) => {
33
+ return openBlock(), createElementBlock("div", _hoisted_1, [
34
+ (openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.steps, (step, idx) => {
35
+ return openBlock(), createElementBlock(Fragment, { key: step }, [
36
+ createElementVNode("div", {
37
+ class: normalizeClass(["text-nowrap rounded-full border px-4 py-1 text-sm font-semibold", stepClasses(step, idx)])
38
+ }, toDisplayString(stepTitle(step)), 3),
39
+ idx < _ctx.steps.length - 1 ? (openBlock(), createElementBlock("div", _hoisted_2, [
40
+ createVNode(_sfc_main$1, {
41
+ icon: "material-symbols:arrow-right-alt-rounded",
42
+ class: normalizeClass([currentStepIndex.value <= idx ? "text-p-gray-30" : "text-p-blue-50"])
43
+ }, null, 8, ["class"])
44
+ ])) : createCommentVNode("", true)
45
+ ], 64);
46
+ }), 128))
47
+ ]);
48
+ };
49
+ }
50
+ });
51
+ export {
52
+ _sfc_main as _
53
+ };
package/dist/es/index.js CHANGED
@@ -41,6 +41,7 @@ import { toString } from "./string.js";
41
41
  import { splitStringForHighlight } from "./text.js";
42
42
  import { default as default9 } from "./p-select-pill.js";
43
43
  import { default as default10 } from "./p-skeleton-loader.js";
44
+ import { _ as _19 } from "./chunks/p-steps.js";
44
45
  import { colsInjectionKey, isFirstColFixedInjectionKey, isLastColFixedInjectionKey, isColsResizableInjectionKey } from "./p-table.js";
45
46
  import { MIN_WIDTH_COL_RESIZE } from "./p-table.js";
46
47
  import { usePTableColResize } from "./usePTableColResize.js";
@@ -49,10 +50,10 @@ import PTableTd from "./p-table-td.js";
49
50
  import { _ as _export_sfc } from "./chunks/_plugin-vue_export-helper.js";
50
51
  import { usePTableRowVirtualizer } from "./usePTableRowVirtualizer.js";
51
52
  import { default as default11 } from "./p-table-filter-icon.js";
52
- import { _ as _19 } from "./chunks/p-table-loader.js";
53
+ import { _ as _20 } from "./chunks/p-table-loader.js";
53
54
  import { SORTING_TYPES } from "./p-table-sort.js";
54
- import { _ as _20 } from "./chunks/p-tabs.js";
55
- import { _ as _21 } from "./chunks/p-textarea.js";
55
+ import { _ as _21 } from "./chunks/p-tabs.js";
56
+ import { _ as _22 } from "./chunks/p-textarea.js";
56
57
  import { default as default12 } from "./p-toggle.js";
57
58
  import { squirrelTailwindConfig } from "./config.js";
58
59
  import { S } from "./chunks/p-btn.types.js";
@@ -1018,13 +1019,14 @@ export {
1018
1019
  _sfc_main$2 as PSelectList,
1019
1020
  default9 as PSelectPill,
1020
1021
  default10 as PSkeletonLoader,
1022
+ _19 as PSteps,
1021
1023
  pTable as PTable,
1022
1024
  PTableHeaderCell,
1023
- _19 as PTableLoader,
1025
+ _20 as PTableLoader,
1024
1026
  _sfc_main as PTableSort,
1025
1027
  PTableTd,
1026
- _20 as PTabs,
1027
- _21 as PTextarea,
1028
+ _21 as PTabs,
1029
+ _22 as PTextarea,
1028
1030
  default12 as PToggle,
1029
1031
  P_ICON_ALIASES,
1030
1032
  S as SIZES,
@@ -0,0 +1,4 @@
1
+ import { _ as _sfc_main } from "./chunks/p-steps.js";
2
+ export {
3
+ _sfc_main as default
4
+ };
@@ -37,6 +37,7 @@ import PSelectList from './p-select-list/p-select-list.vue';
37
37
  import { useSelectList } from './p-select-list/useSelectList';
38
38
  import PSelectPill from './p-select-pill/p-select-pill.vue';
39
39
  import PSkeletonLoader from './p-skeleton-loader/p-skeleton-loader.vue';
40
+ import PSteps from './p-steps/p-steps.vue';
40
41
  import { colsInjectionKey, type HeaderCellAttrs, isColsResizableInjectionKey, isFirstColFixedInjectionKey, isLastColFixedInjectionKey, MIN_WIDTH_COL_RESIZE, type TableCol, type ThAttrs } from './p-table/p-table.types';
41
42
  import PTable from './p-table/p-table.vue';
42
43
  import { usePTableColResize } from './p-table/usePTableColResize';
@@ -50,4 +51,4 @@ import PTableTd from './p-table-td/p-table-td.vue';
50
51
  import PTabs from './p-tabs/p-tabs.vue';
51
52
  import PTextarea from './p-textarea/p-textarea.vue';
52
53
  import PToggle from './p-toggle/p-toggle.vue';
53
- export { colsInjectionKey, FileUploadFile, HeaderCellAttrs, isColsResizableInjectionKey, isFirstColFixedInjectionKey, isLastColFixedInjectionKey, MIN_WIDTH_COL_RESIZE, P_ICON_ALIASES, PActionBar, PActionBarAction, PAlert, PAvatar, PBtn, PCard, PCheckbox, PChips, PCloseBtn, PDatePicker, PDrawer, PDropdown, PDropdownSelect, PFileUpload, PFilterIcon, PIcon, PIconAlias, PInfoIcon, PInlineDatePicker, PInput, PInputNumber, PInputPercent, PInputSearch, PLink, PLoading, PModal, PPagination, PPaginationInfo, PProgressBar, PRingLoader, PSelect, PSelectBtn, PSelectList, PSelectPill, PSkeletonLoader, PTable, PTableHeaderCell, PTableLoader, PTableSort, PTableTd, PTabs, PTextarea, PToggle, Size, SORTING_TYPES, SortingType, SortingTypeWithoutNoSorting, TableCol, ThAttrs, usePLoading, usePModal, usePTableColResize, usePTableRowVirtualizer, useSelectList, };
54
+ export { colsInjectionKey, FileUploadFile, HeaderCellAttrs, isColsResizableInjectionKey, isFirstColFixedInjectionKey, isLastColFixedInjectionKey, MIN_WIDTH_COL_RESIZE, P_ICON_ALIASES, PActionBar, PActionBarAction, PAlert, PAvatar, PBtn, PCard, PCheckbox, PChips, PCloseBtn, PDatePicker, PDrawer, PDropdown, PDropdownSelect, PFileUpload, PFilterIcon, PIcon, PIconAlias, PInfoIcon, PInlineDatePicker, PInput, PInputNumber, PInputPercent, PInputSearch, PLink, PLoading, PModal, PPagination, PPaginationInfo, PProgressBar, PRingLoader, PSelect, PSelectBtn, PSelectList, PSelectPill, PSkeletonLoader, PSteps, PTable, PTableHeaderCell, PTableLoader, PTableSort, PTableTd, PTabs, PTextarea, PToggle, Size, SORTING_TYPES, SortingType, SortingTypeWithoutNoSorting, TableCol, ThAttrs, usePLoading, usePModal, usePTableColResize, usePTableRowVirtualizer, useSelectList, };
@@ -0,0 +1,17 @@
1
+ declare const _default: <T extends readonly string[]>(__VLS_props: NonNullable<Awaited<typeof __VLS_setup>>["props"], __VLS_ctx?: __VLS_PrettifyLocal<Pick<NonNullable<Awaited<typeof __VLS_setup>>, "attrs" | "emit" | "slots">>, __VLS_expose?: NonNullable<Awaited<typeof __VLS_setup>>["expose"], __VLS_setup?: Promise<{
2
+ props: __VLS_PrettifyLocal<Pick<Partial<{}> & Omit<{} & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, never>, never> & {
3
+ steps: T;
4
+ currentStep: T[number];
5
+ stepTitleMap?: Partial<Record<T[number], string>>;
6
+ } & Partial<{}>> & import("vue").PublicProps;
7
+ expose(exposed: import("vue").ShallowUnwrapRef<{}>): void;
8
+ attrs: any;
9
+ slots: {};
10
+ emit: {};
11
+ }>) => import("vue").VNode & {
12
+ __ctx?: Awaited<typeof __VLS_setup>;
13
+ };
14
+ export default _default;
15
+ type __VLS_PrettifyLocal<T> = {
16
+ [K in keyof T]: T[K];
17
+ } & {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pequity/squirrel",
3
3
  "description": "Squirrel component library",
4
- "version": "8.0.2",
4
+ "version": "8.1.0",
5
5
  "packageManager": "pnpm@10.6.4",
6
6
  "type": "module",
7
7
  "scripts": {
@@ -37,6 +37,7 @@ import PSelectList from '@squirrel/components/p-select-list/p-select-list.vue';
37
37
  import { useSelectList } from '@squirrel/components/p-select-list/useSelectList';
38
38
  import PSelectPill from '@squirrel/components/p-select-pill/p-select-pill.vue';
39
39
  import PSkeletonLoader from '@squirrel/components/p-skeleton-loader/p-skeleton-loader.vue';
40
+ import PSteps from '@squirrel/components/p-steps/p-steps.vue';
40
41
  import {
41
42
  colsInjectionKey,
42
43
  type HeaderCellAttrs,
@@ -108,6 +109,7 @@ export {
108
109
  PSelectList,
109
110
  PSelectPill,
110
111
  PSkeletonLoader,
112
+ PSteps,
111
113
  PTable,
112
114
  PTableHeaderCell,
113
115
  PTableLoader,
@@ -0,0 +1,16 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`PSteps.vue > renders correctly 1`] = `
4
+ "<div class="flex items-center gap-2">
5
+ <div class="text-nowrap rounded-full border px-4 py-1 text-sm font-semibold border border-p-blue-50 text-p-blue-50">First</div>
6
+ <div class="flex items-center">
7
+ <iconify-icon icon="material-symbols:arrow-right-alt-rounded" class="text-p-blue-50"></iconify-icon>
8
+ </div>
9
+ <div class="text-nowrap rounded-full border px-4 py-1 text-sm font-semibold border border-p-blue-50 bg-p-blue-50 text-surface">Second</div>
10
+ <div class="flex items-center">
11
+ <iconify-icon icon="material-symbols:arrow-right-alt-rounded" class="text-p-gray-30"></iconify-icon>
12
+ </div>
13
+ <div class="text-nowrap rounded-full border px-4 py-1 text-sm font-semibold border border-p-gray-30 text-p-gray-30">Third</div>
14
+ <!--v-if-->
15
+ </div>"
16
+ `;
@@ -0,0 +1,126 @@
1
+ import PSteps from '@squirrel/components/p-steps/p-steps.vue';
2
+ import { createWrapperFor } from '@tests/vitest.helpers';
3
+
4
+ describe('PSteps.vue', () => {
5
+ it('renders correctly', () => {
6
+ const wrapper = createWrapperFor(PSteps, {
7
+ props: {
8
+ steps: ['first', 'second', 'third'],
9
+ currentStep: 'second',
10
+ stepTitleMap: {},
11
+ },
12
+ });
13
+ expect(wrapper.html()).toMatchSnapshot();
14
+ });
15
+
16
+ it('renders the correct number of steps', () => {
17
+ const steps = ['first', 'second', 'third'];
18
+ const wrapper = createWrapperFor(PSteps, {
19
+ props: {
20
+ steps,
21
+ currentStep: 'second',
22
+ stepTitleMap: {},
23
+ },
24
+ });
25
+
26
+ const stepElements = wrapper.findAll('.rounded-full.border');
27
+ expect(stepElements.length).toBe(steps.length);
28
+ });
29
+
30
+ it('applies correct classes for current step', () => {
31
+ const wrapper = createWrapperFor(PSteps, {
32
+ props: {
33
+ steps: ['first', 'second', 'third'],
34
+ currentStep: 'second',
35
+ stepTitleMap: {},
36
+ },
37
+ });
38
+
39
+ const stepElements = wrapper.findAll('.rounded-full.border');
40
+
41
+ // First step should be completed (blue text)
42
+ expect(stepElements[0].classes()).toContain('text-nowrap');
43
+ expect(stepElements[0].classes()).toContain('text-p-blue-50');
44
+ expect(stepElements[0].classes()).toContain('border-p-blue-50');
45
+
46
+ // Second step should be current (blue background)
47
+ expect(stepElements[1].classes()).toContain('text-nowrap');
48
+ expect(stepElements[1].classes()).toContain('bg-p-blue-50');
49
+ expect(stepElements[1].classes()).toContain('text-surface');
50
+ expect(stepElements[1].classes()).toContain('border-p-blue-50');
51
+
52
+ // Third step should be upcoming (gray)
53
+ expect(stepElements[2].classes()).toContain('text-nowrap');
54
+ expect(stepElements[2].classes()).toContain('text-p-gray-30');
55
+ expect(stepElements[2].classes()).toContain('border-p-gray-30');
56
+ });
57
+
58
+ it('displays step titles from stepTitleMap when provided', () => {
59
+ const wrapper = createWrapperFor(PSteps, {
60
+ props: {
61
+ steps: ['step1', 'step2', 'step3'],
62
+ currentStep: 'step2',
63
+ stepTitleMap: {
64
+ step1: 'Custom Step 1',
65
+ step2: 'Custom Step 2',
66
+ step3: 'Custom Step 3',
67
+ },
68
+ },
69
+ });
70
+
71
+ const stepElements = wrapper.findAll('.rounded-full.border');
72
+ expect(stepElements[0].text()).toBe('Custom Step 1');
73
+ expect(stepElements[1].text()).toBe('Custom Step 2');
74
+ expect(stepElements[2].text()).toBe('Custom Step 3');
75
+ });
76
+
77
+ it('uses startCase for step titles when stepTitleMap entry is not provided', () => {
78
+ const wrapper = createWrapperFor(PSteps, {
79
+ props: {
80
+ steps: ['firstStep', 'secondStep', 'thirdStep'],
81
+ currentStep: 'secondStep',
82
+ stepTitleMap: {
83
+ secondStep: 'Custom Second',
84
+ },
85
+ },
86
+ });
87
+
88
+ const stepElements = wrapper.findAll('.rounded-full.border');
89
+ expect(stepElements[0].text()).toBe('First Step'); // startCase applied
90
+ expect(stepElements[1].text()).toBe('Custom Second'); // from map
91
+ expect(stepElements[2].text()).toBe('Third Step'); // startCase applied
92
+ });
93
+
94
+ it('renders the correct number of arrows between steps', () => {
95
+ const wrapper = createWrapperFor(PSteps, {
96
+ props: {
97
+ steps: ['first', 'second', 'third', 'fourth'],
98
+ currentStep: 'second',
99
+ stepTitleMap: {},
100
+ },
101
+ });
102
+
103
+ // There should be 3 arrows for 4 steps
104
+ const arrowElements = wrapper.findAll('[icon="material-symbols:arrow-right-alt-rounded"]');
105
+ expect(arrowElements.length).toBe(3);
106
+ });
107
+
108
+ it('applies the correct classes to arrows based on current step', () => {
109
+ const wrapper = createWrapperFor(PSteps, {
110
+ props: {
111
+ steps: ['first', 'second', 'third', 'fourth'],
112
+ currentStep: 'second',
113
+ stepTitleMap: {},
114
+ },
115
+ });
116
+
117
+ const arrowElements = wrapper.findAll('[icon="material-symbols:arrow-right-alt-rounded"]');
118
+
119
+ // Arrow between first and second step should be colored
120
+ expect(arrowElements[0].classes()).toContain('text-p-blue-50');
121
+
122
+ // Arrow after current step should be gray
123
+ expect(arrowElements[1].classes()).toContain('text-p-gray-30');
124
+ expect(arrowElements[2].classes()).toContain('text-p-gray-30');
125
+ });
126
+ });
@@ -0,0 +1,31 @@
1
+ import PSteps from '@squirrel/components/p-steps/p-steps.vue';
2
+
3
+ export default {
4
+ title: 'Components/PSteps',
5
+ component: PSteps,
6
+ tags: ['autodocs'],
7
+ parameters: {
8
+ docs: {
9
+ description: {
10
+ component: 'Steps Component to be used in wizards',
11
+ },
12
+ },
13
+ },
14
+ };
15
+
16
+ export const Default = {
17
+ render: (args) => ({
18
+ components: { PSteps },
19
+ setup() {
20
+ return { args };
21
+ },
22
+ template: `<PSteps v-bind="args" />`,
23
+ }),
24
+ args: {
25
+ steps: ['stepOne', 'stepTwo', 'stepThree', 'stepFour'],
26
+ currentStep: 'stepTwo',
27
+ stepTitleMap: {
28
+ stepTwo: 'Criteria',
29
+ },
30
+ },
31
+ };
@@ -0,0 +1,47 @@
1
+ <template>
2
+ <div class="flex items-center gap-2">
3
+ <template v-for="(step, idx) in steps" :key="step">
4
+ <div class="text-nowrap rounded-full border px-4 py-1 text-sm font-semibold" :class="stepClasses(step, idx)">
5
+ {{ stepTitle(step) }}
6
+ </div>
7
+ <div v-if="idx < steps.length - 1" class="flex items-center">
8
+ <PIcon
9
+ icon="material-symbols:arrow-right-alt-rounded"
10
+ :class="[currentStepIndex <= idx ? 'text-p-gray-30' : 'text-p-blue-50']"
11
+ />
12
+ </div>
13
+ </template>
14
+ </div>
15
+ </template>
16
+
17
+ <script setup lang="ts" generic="T extends readonly string[]">
18
+ import PIcon from '@squirrel/components/p-icon/p-icon.vue';
19
+ import { startCase } from 'lodash-es';
20
+ import { computed } from 'vue';
21
+
22
+ type Props = {
23
+ steps: T;
24
+ currentStep: T[number];
25
+ stepTitleMap?: Partial<Record<T[number], string>>;
26
+ };
27
+
28
+ const props = defineProps<Props>();
29
+
30
+ const currentStepIndex = computed(() => props.steps.findIndex((s) => s === props.currentStep));
31
+
32
+ const stepClasses = (step: T[number], stepIndex: number) => {
33
+ if (step === props.currentStep) {
34
+ return 'border border-p-blue-50 bg-p-blue-50 text-surface';
35
+ }
36
+
37
+ if (currentStepIndex.value < stepIndex) {
38
+ return 'border border-p-gray-30 text-p-gray-30';
39
+ }
40
+
41
+ return 'border border-p-blue-50 text-p-blue-50';
42
+ };
43
+
44
+ const stepTitle = (step: T[number]) => {
45
+ return props.stepTitleMap?.[step] || startCase(step);
46
+ };
47
+ </script>