@kiva/kv-components 8.5.4 → 8.5.6

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.js CHANGED
@@ -2,15 +2,15 @@ import { default as r } from "./vue/KvAccordionItem.js";
2
2
  import { default as a } from "./vue/KvActivityRow.js";
3
3
  import { default as l } from "./vue/KvBorrowerImage.js";
4
4
  import { default as s } from "./vue/KvButton.js";
5
- import { default as p } from "./vue/KvCardFrame.js";
6
- import { default as u } from "./vue/KvCarousel.js";
5
+ import { default as d } from "./vue/KvCardFrame.js";
6
+ import { default as x } from "./vue/KvCarousel.js";
7
7
  import { default as K } from "./vue/KvCartModal.js";
8
8
  import { default as A } from "./vue/KvCartPill.js";
9
- import { default as C } from "./vue/KvCheckbox.js";
10
- import { default as L } from "./vue/KvCheckoutReceipt.js";
11
- import { default as c } from "./vue/KvChip.js";
9
+ import { default as i } from "./vue/KvCheckbox.js";
10
+ import { default as c } from "./vue/KvCheckoutReceipt.js";
11
+ import { default as N } from "./vue/KvChip.js";
12
12
  import { default as E } from "./vue/KvClassicLoanCard.js";
13
- import { default as O } from "./vue/KvCompactLoanCard.js";
13
+ import { default as M } from "./vue/KvCompactLoanCard.js";
14
14
  import { default as I } from "./vue/KvCommentsAdd.js";
15
15
  import { default as g } from "./vue/KvCommentsContainer.js";
16
16
  import { default as G } from "./vue/KvCommentsHeartButton.js";
@@ -21,23 +21,23 @@ import { default as k } from "./vue/KvContentfulImg.js";
21
21
  import { default as w } from "./vue/KvCountdownTimer.js";
22
22
  import { default as H } from "./vue/KvDatePicker.js";
23
23
  import { default as z } from "./vue/KvExpandable.js";
24
- import { default as q } from "./vue/KvExpandableQuestion.js";
25
- import { default as X } from "./vue/KvFlag.js";
26
- import { default as Z } from "./vue/KvGrid.js";
24
+ import { default as Z } from "./vue/KvExpandableQuestion.js";
25
+ import { default as J } from "./vue/KvFlag.js";
26
+ import { default as Y } from "./vue/KvGrid.js";
27
27
  import { default as oo } from "./vue/KvIconButton.js";
28
28
  import { default as ro } from "./vue/KvImpactDashboardHeader.js";
29
29
  import { default as ao } from "./vue/KvImpactVerticalSelector.js";
30
30
  import { default as lo } from "./vue/KvInlineActivityCard.js";
31
31
  import { default as so } from "./vue/KvInlineActivityFeed.js";
32
- import { default as xo } from "./vue/KvIntroductionLoanCard.js";
32
+ import { default as uo } from "./vue/KvIntroductionLoanCard.js";
33
33
  import { default as no } from "./vue/KvLendAmountButton.js";
34
34
  import { default as vo } from "./vue/KvLendCta.js";
35
- import { default as io } from "./vue/KvLightbox.js";
35
+ import { default as Co } from "./vue/KvLightbox.js";
36
36
  import { default as _o } from "./vue/KvLineGraph.js";
37
- import { default as No } from "./vue/KvLoanActivities.js";
37
+ import { default as Lo } from "./vue/KvLoanActivities.js";
38
38
  import { default as To } from "./vue/KvLoanBookmark.js";
39
39
  import { default as Ro } from "./vue/KvLoanCallouts.js";
40
- import { KV_LOAN_INFO_CARD_FRAGMENT as Mo, default as Io } from "./vue/KvLoanInfoCard.js";
40
+ import { KV_LOAN_INFO_CARD_FRAGMENT as Oo, default as Io } from "./vue/KvLoanInfoCard.js";
41
41
  import { default as go } from "./vue/KvLoanProgressGroup.js";
42
42
  import { default as Go } from "./vue/KvLoanTag.js";
43
43
  import { default as ho } from "./vue/KvLoanTeamPick.js";
@@ -47,23 +47,23 @@ import { default as ko } from "./vue/KvLoadingSpinner.js";
47
47
  import { default as wo } from "./vue/KvMap.js";
48
48
  import { default as Ho } from "./vue/KvMaterialIcon.js";
49
49
  import { default as zo } from "./vue/KvPageContainer.js";
50
- import { default as qo } from "./vue/KvPagination.js";
51
- import { default as Xo } from "./vue/KvPieChart.js";
52
- import { default as Zo } from "./vue/KvPill.js";
50
+ import { default as Zo } from "./vue/KvPagination.js";
51
+ import { default as Jo } from "./vue/KvPieChart.js";
52
+ import { default as Yo } from "./vue/KvPill.js";
53
53
  import { default as oe } from "./vue/KvPopper.js";
54
54
  import { default as re } from "./vue/KvProgressBar.js";
55
55
  import { default as ae } from "./vue/KvProgressCircle.js";
56
56
  import { default as le } from "./vue/KvPulsingDot.js";
57
57
  import { default as se } from "./vue/KvRadio.js";
58
- import { default as pe } from "./vue/KvSelect.js";
59
- import { default as ue } from "./vue/KvSideSheet.js";
58
+ import { default as de } from "./vue/KvSelect.js";
59
+ import { default as xe } from "./vue/KvSideSheet.js";
60
60
  import { default as Ke } from "./vue/KvSwitch.js";
61
61
  import { default as Ae } from "./vue/KvTab.js";
62
- import { default as Ce } from "./vue/KvTabPanel.js";
63
- import { default as Le } from "./vue/KvTabs.js";
64
- import { default as ce } from "./vue/KvTextInput.js";
62
+ import { default as ie } from "./vue/KvTabPanel.js";
63
+ import { default as ce } from "./vue/KvTabs.js";
64
+ import { default as Ne } from "./vue/KvTextInput.js";
65
65
  import { default as Ee } from "./vue/KvTextLink.js";
66
- import { default as Oe } from "./vue/KvThemeProvider.js";
66
+ import { default as Me } from "./vue/KvThemeProvider.js";
67
67
  import { default as Ie } from "./vue/KvToast.js";
68
68
  import { default as ge } from "./vue/KvTooltip.js";
69
69
  import { default as Ge } from "./vue/KvTreeMapChart.js";
@@ -74,69 +74,69 @@ import { default as ke } from "./vue/KvVotingCard.js";
74
74
  import { default as we } from "./vue/KvVotingCardV2.js";
75
75
  import { default as He } from "./vue/KvWideLoanCard.js";
76
76
  import { default as ze } from "./vue/KvAtbModal.js";
77
- import { default as qe } from "./vue/KvSecondaryNav.js";
78
- import { default as Xe } from "./vue/KvWwwHeader.js";
79
- import { default as Ze, Mash as $e } from "./utils/Alea.js";
77
+ import { default as Ze } from "./vue/KvSecondaryNav.js";
78
+ import { default as Je } from "./vue/KvWwwHeader.js";
79
+ import { default as Ye, Mash as $e } from "./utils/Alea.js";
80
80
  import { groupBy as er, sortBy as rr } from "./utils/arrayUtils.js";
81
81
  import { useAttrs as ar } from "./utils/attrs.js";
82
82
  import { carouselUtil as lr } from "./utils/carousels.js";
83
- import { abc as sr, indexIn as dr, startsWith as pr } from "./utils/comparators.js";
84
- import { debounce as ur } from "./utils/debounce.js";
83
+ import { abc as sr, indexIn as pr, startsWith as dr } from "./utils/comparators.js";
84
+ import { debounce as xr } from "./utils/debounce.js";
85
85
  import { useEventListener as Kr } from "./utils/event.js";
86
- import { collapse as Ar, expand as ir } from "./utils/expander.js";
87
- import { getKivaImageUrl as _r, isLegacyPlaceholderAvatar as Lr, randomizedUserAvatarClass as Nr } from "./utils/imageUtils.js";
88
- import { LOAN_CALLOUTS_FRAGMENT as Tr, LOAN_GEOCODE_FRAGMENT as Er, LOAN_PROGRESS_FRAGMENT as Rr, loanCardComputedProperties as Or, loanCardMethods as Mr } from "./utils/loanCard.js";
86
+ import { collapse as Ar, expand as Cr } from "./utils/expander.js";
87
+ import { getKivaImageUrl as _r, isLegacyPlaceholderAvatar as cr, randomizedUserAvatarClass as Lr } from "./utils/imageUtils.js";
88
+ import { LOAN_CALLOUTS_FRAGMENT as Tr, LOAN_GEOCODE_FRAGMENT as Er, LOAN_PROGRESS_FRAGMENT as Rr, loanCardComputedProperties as Mr, loanCardMethods as Or } from "./utils/loanCard.js";
89
89
  import { BALANCE_CAMPAIGN as Sr, BASE_CAMPAIGN as gr, ERL_COOKIE_NAME as Pr, NO_BALANCE_CAMPAIGN as Gr, TOP_UP_CAMPAIGN as Fr, getDropdownPriceArray as hr, getLendCtaSelectedOption as Vr, isBetween25And50 as Br, isLessThan25 as Dr, truncateStringByWords as yr } from "./utils/loanUtils.js";
90
- import { animationCoordinator as kr, generateMapMarkers as Ur, getCoordinatesBetween as wr, getCountryColor as Wr, getLoansIntervals as Hr } from "./utils/mapUtils.js";
91
- import { lockPrintSingleEl as zr, unlockPrintSingleEl as Qr } from "./utils/printing.js";
92
- import { lockScroll as Jr, lockScrollSmallOnly as Xr, unlockScroll as Yr, unlockScrollSmallOnly as Zr } from "./utils/scrollLock.js";
93
- import { buildTailwindClassName as ot, headerNumberCase as et, kebabCase as rt, removeObjectProperty as tt } from "./utils/themeUtils.js";
94
- import { throttle as ft } from "./utils/throttle.js";
95
- import { isTargetElement as mt, offBodyTouchstart as st, onBodyTouchstart as dt } from "./utils/touchEvents.js";
96
- import { getTreemap as xt } from "./utils/treemap.js";
97
- import { KvBlueskyIcon as nt } from "./assets/icons/bluesky.js";
98
- import { KV_CLASSIC_LOAN_CARD_FRAGMENT as vt, KV_CLASSIC_LOAN_CARD_USER_FRAGMET as At } from "./vue/KvClassicLoanCard2.js";
99
- import { KV_COMPACT_LOAN_CARD_FRAGMENT as Ct, KV_COMPACT_LOAN_CARD_USER_FRAGMENT as _t } from "./vue/KvCompactLoanCard2.js";
100
- import { KV_INTRODUCTION_LOAN_CARD_FRAGMENT as Nt, KV_INTRODUCTION_LOAN_CARD_USER_FRAGMENT as ct } from "./vue/KvIntroductionLoanCard2.js";
101
- import { KV_LEND_CTA_FRAGMENT as Et, KV_LEND_CTA_USER_FRAGMENT as Rt } from "./vue/KvLendCta2.js";
102
- import { KV_LOAN_ACTIVITIES_FRAGMENT as Mt } from "./vue/KvLoanActivities2.js";
103
- import { KV_LOAN_BOOKMARK_FRAGMENT as St } from "./vue/KvLoanBookmark2.js";
104
- import { KV_LOAN_TAG_FRAGMENT as Pt } from "./vue/KvLoanTag2.js";
105
- import { KV_LOAN_USE_FRAGMENT as Ft } from "./vue/KvLoanUse2.js";
106
- import { KV_WIDE_LOAN_CARD_FRAGMENT as Vt, KV_WIDE_LOAN_CARD_USER_FRAGMENT as Bt } from "./vue/KvWideLoanCard2.js";
90
+ import { animationCoordinator as kr, computeMapCenter as Ur, computeMapZoom as wr, generateMapMarkers as Wr, getCoordinatesBetween as Hr, getCountryColor as jr, getLoansIntervals as zr } from "./utils/mapUtils.js";
91
+ import { lockPrintSingleEl as Zr, unlockPrintSingleEl as qr } from "./utils/printing.js";
92
+ import { lockScroll as Xr, lockScrollSmallOnly as Yr, unlockScroll as $r, unlockScrollSmallOnly as ot } from "./utils/scrollLock.js";
93
+ import { buildTailwindClassName as rt, headerNumberCase as tt, kebabCase as at, removeObjectProperty as ft } from "./utils/themeUtils.js";
94
+ import { throttle as mt } from "./utils/throttle.js";
95
+ import { isTargetElement as pt, offBodyTouchstart as dt, onBodyTouchstart as ut } from "./utils/touchEvents.js";
96
+ import { getTreemap as nt } from "./utils/treemap.js";
97
+ import { KvBlueskyIcon as vt } from "./assets/icons/bluesky.js";
98
+ import { KV_CLASSIC_LOAN_CARD_FRAGMENT as Ct, KV_CLASSIC_LOAN_CARD_USER_FRAGMET as it } from "./vue/KvClassicLoanCard2.js";
99
+ import { KV_COMPACT_LOAN_CARD_FRAGMENT as ct, KV_COMPACT_LOAN_CARD_USER_FRAGMENT as Lt } from "./vue/KvCompactLoanCard2.js";
100
+ import { KV_INTRODUCTION_LOAN_CARD_FRAGMENT as Tt, KV_INTRODUCTION_LOAN_CARD_USER_FRAGMENT as Et } from "./vue/KvIntroductionLoanCard2.js";
101
+ import { KV_LEND_CTA_FRAGMENT as Mt, KV_LEND_CTA_USER_FRAGMENT as Ot } from "./vue/KvLendCta2.js";
102
+ import { KV_LOAN_ACTIVITIES_FRAGMENT as St } from "./vue/KvLoanActivities2.js";
103
+ import { KV_LOAN_BOOKMARK_FRAGMENT as Pt } from "./vue/KvLoanBookmark2.js";
104
+ import { KV_LOAN_TAG_FRAGMENT as Ft } from "./vue/KvLoanTag2.js";
105
+ import { KV_LOAN_USE_FRAGMENT as Vt } from "./vue/KvLoanUse2.js";
106
+ import { KV_WIDE_LOAN_CARD_FRAGMENT as Dt, KV_WIDE_LOAN_CARD_USER_FRAGMENT as yt } from "./vue/KvWideLoanCard2.js";
107
107
  export {
108
- Ze as Alea,
108
+ Ye as Alea,
109
109
  Sr as BALANCE_CAMPAIGN,
110
110
  gr as BASE_CAMPAIGN,
111
111
  Pr as ERL_COOKIE_NAME,
112
- vt as KV_CLASSIC_LOAN_CARD_FRAGMENT,
113
- At as KV_CLASSIC_LOAN_CARD_USER_FRAGMET,
114
- Ct as KV_COMPACT_LOAN_CARD_FRAGMENT,
115
- _t as KV_COMPACT_LOAN_CARD_USER_FRAGMENT,
116
- Nt as KV_INTRODUCTION_LOAN_CARD_FRAGMENT,
117
- ct as KV_INTRODUCTION_LOAN_CARD_USER_FRAGMENT,
118
- Et as KV_LEND_CTA_FRAGMENT,
119
- Rt as KV_LEND_CTA_USER_FRAGMENT,
120
- Mt as KV_LOAN_ACTIVITIES_FRAGMENT,
121
- St as KV_LOAN_BOOKMARK_FRAGMENT,
122
- Mo as KV_LOAN_INFO_CARD_FRAGMENT,
123
- Pt as KV_LOAN_TAG_FRAGMENT,
124
- Ft as KV_LOAN_USE_FRAGMENT,
125
- Vt as KV_WIDE_LOAN_CARD_FRAGMENT,
126
- Bt as KV_WIDE_LOAN_CARD_USER_FRAGMENT,
112
+ Ct as KV_CLASSIC_LOAN_CARD_FRAGMENT,
113
+ it as KV_CLASSIC_LOAN_CARD_USER_FRAGMET,
114
+ ct as KV_COMPACT_LOAN_CARD_FRAGMENT,
115
+ Lt as KV_COMPACT_LOAN_CARD_USER_FRAGMENT,
116
+ Tt as KV_INTRODUCTION_LOAN_CARD_FRAGMENT,
117
+ Et as KV_INTRODUCTION_LOAN_CARD_USER_FRAGMENT,
118
+ Mt as KV_LEND_CTA_FRAGMENT,
119
+ Ot as KV_LEND_CTA_USER_FRAGMENT,
120
+ St as KV_LOAN_ACTIVITIES_FRAGMENT,
121
+ Pt as KV_LOAN_BOOKMARK_FRAGMENT,
122
+ Oo as KV_LOAN_INFO_CARD_FRAGMENT,
123
+ Ft as KV_LOAN_TAG_FRAGMENT,
124
+ Vt as KV_LOAN_USE_FRAGMENT,
125
+ Dt as KV_WIDE_LOAN_CARD_FRAGMENT,
126
+ yt as KV_WIDE_LOAN_CARD_USER_FRAGMENT,
127
127
  r as KvAccordionItem,
128
128
  a as KvActivityRow,
129
129
  ze as KvAtbModal,
130
- nt as KvBlueskyIcon,
130
+ vt as KvBlueskyIcon,
131
131
  l as KvBorrowerImage,
132
132
  s as KvButton,
133
- p as KvCardFrame,
134
- u as KvCarousel,
133
+ d as KvCardFrame,
134
+ x as KvCarousel,
135
135
  K as KvCartModal,
136
136
  A as KvCartPill,
137
- C as KvCheckbox,
138
- L as KvCheckoutReceipt,
139
- c as KvChip,
137
+ i as KvCheckbox,
138
+ c as KvCheckoutReceipt,
139
+ N as KvChip,
140
140
  E as KvClassicLoanCard,
141
141
  I as KvCommentsAdd,
142
142
  g as KvCommentsContainer,
@@ -144,27 +144,27 @@ export {
144
144
  h as KvCommentsList,
145
145
  B as KvCommentsListItem,
146
146
  y as KvCommentsReplyButton,
147
- O as KvCompactLoanCard,
147
+ M as KvCompactLoanCard,
148
148
  k as KvContentfulImg,
149
149
  w as KvCountdownTimer,
150
150
  H as KvDatePicker,
151
151
  z as KvExpandable,
152
- q as KvExpandableQuestion,
153
- X as KvFlag,
154
- Z as KvGrid,
152
+ Z as KvExpandableQuestion,
153
+ J as KvFlag,
154
+ Y as KvGrid,
155
155
  oo as KvIconButton,
156
156
  ro as KvImpactDashboardHeader,
157
157
  ao as KvImpactVerticalSelector,
158
158
  lo as KvInlineActivityCard,
159
159
  so as KvInlineActivityFeed,
160
- xo as KvIntroductionLoanCard,
160
+ uo as KvIntroductionLoanCard,
161
161
  no as KvLendAmountButton,
162
162
  vo as KvLendCta,
163
- io as KvLightbox,
163
+ Co as KvLightbox,
164
164
  _o as KvLineGraph,
165
165
  yo as KvLoadingPlaceholder,
166
166
  ko as KvLoadingSpinner,
167
- No as KvLoanActivities,
167
+ Lo as KvLoanActivities,
168
168
  To as KvLoanBookmark,
169
169
  Ro as KvLoanCallouts,
170
170
  Io as KvLoanInfoCard,
@@ -175,24 +175,24 @@ export {
175
175
  wo as KvMap,
176
176
  Ho as KvMaterialIcon,
177
177
  zo as KvPageContainer,
178
- qo as KvPagination,
179
- Xo as KvPieChart,
180
- Zo as KvPill,
178
+ Zo as KvPagination,
179
+ Jo as KvPieChart,
180
+ Yo as KvPill,
181
181
  oe as KvPopper,
182
182
  re as KvProgressBar,
183
183
  ae as KvProgressCircle,
184
184
  le as KvPulsingDot,
185
185
  se as KvRadio,
186
- qe as KvSecondaryNav,
187
- pe as KvSelect,
188
- ue as KvSideSheet,
186
+ Ze as KvSecondaryNav,
187
+ de as KvSelect,
188
+ xe as KvSideSheet,
189
189
  Ke as KvSwitch,
190
190
  Ae as KvTab,
191
- Ce as KvTabPanel,
192
- Le as KvTabs,
193
- ce as KvTextInput,
191
+ ie as KvTabPanel,
192
+ ce as KvTabs,
193
+ Ne as KvTextInput,
194
194
  Ee as KvTextLink,
195
- Oe as KvThemeProvider,
195
+ Me as KvThemeProvider,
196
196
  Ie as KvToast,
197
197
  ge as KvTooltip,
198
198
  Ge as KvTreeMapChart,
@@ -202,7 +202,7 @@ export {
202
202
  ke as KvVotingCard,
203
203
  we as KvVotingCardV2,
204
204
  He as KvWideLoanCard,
205
- Xe as KvWwwHeader,
205
+ Je as KvWwwHeader,
206
206
  Tr as LOAN_CALLOUTS_FRAGMENT,
207
207
  Er as LOAN_GEOCODE_FRAGMENT,
208
208
  Rr as LOAN_PROGRESS_FRAGMENT,
@@ -211,43 +211,45 @@ export {
211
211
  Fr as TOP_UP_CAMPAIGN,
212
212
  sr as abc,
213
213
  kr as animationCoordinator,
214
- ot as buildTailwindClassName,
214
+ rt as buildTailwindClassName,
215
215
  lr as carouselUtil,
216
216
  Ar as collapse,
217
- ur as debounce,
218
- ir as expand,
219
- Ur as generateMapMarkers,
220
- wr as getCoordinatesBetween,
221
- Wr as getCountryColor,
217
+ Ur as computeMapCenter,
218
+ wr as computeMapZoom,
219
+ xr as debounce,
220
+ Cr as expand,
221
+ Wr as generateMapMarkers,
222
+ Hr as getCoordinatesBetween,
223
+ jr as getCountryColor,
222
224
  hr as getDropdownPriceArray,
223
225
  _r as getKivaImageUrl,
224
226
  Vr as getLendCtaSelectedOption,
225
- Hr as getLoansIntervals,
226
- xt as getTreemap,
227
+ zr as getLoansIntervals,
228
+ nt as getTreemap,
227
229
  er as groupBy,
228
- et as headerNumberCase,
229
- dr as indexIn,
230
+ tt as headerNumberCase,
231
+ pr as indexIn,
230
232
  Br as isBetween25And50,
231
- Lr as isLegacyPlaceholderAvatar,
233
+ cr as isLegacyPlaceholderAvatar,
232
234
  Dr as isLessThan25,
233
- mt as isTargetElement,
234
- rt as kebabCase,
235
- Or as loanCardComputedProperties,
236
- Mr as loanCardMethods,
237
- zr as lockPrintSingleEl,
238
- Jr as lockScroll,
239
- Xr as lockScrollSmallOnly,
240
- st as offBodyTouchstart,
241
- dt as onBodyTouchstart,
242
- Nr as randomizedUserAvatarClass,
243
- tt as removeObjectProperty,
235
+ pt as isTargetElement,
236
+ at as kebabCase,
237
+ Mr as loanCardComputedProperties,
238
+ Or as loanCardMethods,
239
+ Zr as lockPrintSingleEl,
240
+ Xr as lockScroll,
241
+ Yr as lockScrollSmallOnly,
242
+ dt as offBodyTouchstart,
243
+ ut as onBodyTouchstart,
244
+ Lr as randomizedUserAvatarClass,
245
+ ft as removeObjectProperty,
244
246
  rr as sortBy,
245
- pr as startsWith,
246
- ft as throttle,
247
+ dr as startsWith,
248
+ mt as throttle,
247
249
  yr as truncateStringByWords,
248
- Qr as unlockPrintSingleEl,
249
- Yr as unlockScroll,
250
- Zr as unlockScrollSmallOnly,
250
+ qr as unlockPrintSingleEl,
251
+ $r as unlockScroll,
252
+ ot as unlockScrollSmallOnly,
251
253
  ar as useAttrs,
252
254
  Kr as useEventListener
253
255
  };
@@ -3,3 +3,14 @@ export declare function generateMapMarkers(mapInstance: any, borrowerPoints: any
3
3
  export declare function animationCoordinator(mapInstance: any, borrowerPoints: any): Promise<void>;
4
4
  export declare const getLoansIntervals: (min: number, max: number, nbIntervals: number) => number[][];
5
5
  export declare const getCountryColor: (lenderLoans: number, countriesData: any[], kvTokensPrimitives: any, defaultBaseColor: string) => string;
6
+ export declare const computeMapCenter: (data: Array<{
7
+ lat: number;
8
+ long: number;
9
+ }>) => {
10
+ lat: number;
11
+ long: number;
12
+ };
13
+ export declare const computeMapZoom: (data: Array<{
14
+ lat: number;
15
+ long: number;
16
+ }>) => number;
@@ -1,9 +1,9 @@
1
- function p(e, o, r) {
1
+ function y(e, o, r) {
2
2
  return (Math.random() * (o - e) + e).toFixed(r) * 1;
3
3
  }
4
- const d = Array.from(
4
+ const M = Array.from(
5
5
  { length: 20 },
6
- () => [p(-180, 180, 3), p(-90, 90, 3)]
6
+ () => [y(-180, 180, 3), y(-90, 90, 3)]
7
7
  ), m = [
8
8
  100,
9
9
  300,
@@ -12,18 +12,18 @@ const d = Array.from(
12
12
  800,
13
13
  1e3
14
14
  ];
15
- function M(e, o, r) {
15
+ function d(e, o, r) {
16
16
  if (!e || !o || !r || r < 1 || !Array.isArray(e) || !Array.isArray(o) || e.length !== 2 || o.length !== 2)
17
17
  return [];
18
- const n = o[0] - e[0], s = o[1] - e[1], i = n / r, a = s / r;
18
+ const n = o[0] - e[0], i = o[1] - e[1], a = n / r, s = i / r;
19
19
  let t = 0, l = 0;
20
20
  const c = [];
21
- for (; Math.abs(t) < Math.abs(n) || Math.abs(l) < Math.abs(s); )
22
- c.push([e[0] + t, e[1] + l]), Math.abs(t) < Math.abs(n) && (t += i), Math.abs(l) < Math.abs(s) && (l += a);
21
+ for (; Math.abs(t) < Math.abs(n) || Math.abs(l) < Math.abs(i); )
22
+ c.push([e[0] + t, e[1] + l]), Math.abs(t) < Math.abs(n) && (t += a), Math.abs(l) < Math.abs(i) && (l += s);
23
23
  return c[c.length - 1] = [o[0], o[1]], c;
24
24
  }
25
- function b(e, o, r) {
26
- return new Promise((s) => {
25
+ function S(e, o, r) {
26
+ return new Promise((i) => {
27
27
  e.addSource("endpoint", {
28
28
  type: "geojson",
29
29
  data: {
@@ -34,8 +34,8 @@ function b(e, o, r) {
34
34
  ]
35
35
  }
36
36
  });
37
- const i = (a, t, l, c = !1) => {
38
- const f = M(a, t, 100);
37
+ const a = (s, t, l, c = !1) => {
38
+ const f = d(s, t, 100);
39
39
  let h = 0;
40
40
  const u = {
41
41
  type: "FeatureCollection",
@@ -52,8 +52,8 @@ function b(e, o, r) {
52
52
  data: {
53
53
  type: "Point",
54
54
  coordinates: [
55
- a[0],
56
- a[1]
55
+ s[0],
56
+ s[1]
57
57
  ]
58
58
  }
59
59
  }), e.addLayer({
@@ -72,22 +72,22 @@ function b(e, o, r) {
72
72
  "line-width": 2
73
73
  }
74
74
  });
75
- const y = () => {
75
+ const p = () => {
76
76
  if (h < f.length)
77
- u.features[0].geometry.coordinates.push(f[h]), e.getSource(`line-animation${l}`).setData(u), requestAnimationFrame(y), h += 1;
77
+ u.features[0].geometry.coordinates.push(f[h]), e.getSource(`line-animation${l}`).setData(u), requestAnimationFrame(p), h += 1;
78
78
  else {
79
79
  const g = u.features[0].geometry.coordinates;
80
- g.shift(), g.shift(), g.length > 0 ? (u.features[0].geometry.coordinates = g, e.getSource(`line-animation${l}`).setData(u), requestAnimationFrame(y)) : (e.removeLayer(`line-animation${l}`), e.removeSource(`line-animation${l}`), e.removeSource(`startPoint${l}`), c && (e.removeSource("endpoint"), s()));
80
+ g.shift(), g.shift(), g.length > 0 ? (u.features[0].geometry.coordinates = g, e.getSource(`line-animation${l}`).setData(u), requestAnimationFrame(p)) : (e.removeLayer(`line-animation${l}`), e.removeSource(`line-animation${l}`), e.removeSource(`startPoint${l}`), c && (e.removeSource("endpoint"), i()));
81
81
  }
82
82
  };
83
- y();
83
+ p();
84
84
  };
85
- o.forEach((a, t) => {
86
- i(a, r, t, t === o.length - 1);
85
+ o.forEach((s, t) => {
86
+ a(s, r, t, t === o.length - 1);
87
87
  });
88
88
  });
89
89
  }
90
- function $(e, o) {
90
+ function F(e, o) {
91
91
  const r = {
92
92
  type: "FeatureCollection"
93
93
  };
@@ -103,15 +103,15 @@ function $(e, o) {
103
103
  coordinates: n.location
104
104
  }
105
105
  })), r.features.forEach((n) => {
106
- const s = document.createElement("div");
107
- s.className = "map-marker", s.style.backgroundImage = `url(${n.properties.image})`, s.style.width = `${n.properties.iconSize[0]}px`, s.style.height = `${n.properties.iconSize[1]}px`, new maplibregl.Marker({ element: s }).setLngLat(n.geometry.coordinates).addTo(e);
106
+ const i = document.createElement("div");
107
+ i.className = "map-marker", i.style.backgroundImage = `url(${n.properties.image})`, i.style.width = `${n.properties.iconSize[0]}px`, i.style.height = `${n.properties.iconSize[1]}px`, new maplibregl.Marker({ element: i }).setLngLat(n.geometry.coordinates).addTo(e);
108
108
  });
109
109
  }
110
- function A(e, o) {
110
+ function $(e, o) {
111
111
  return new Promise((r) => {
112
- const n = o.map((t) => t.location), s = n.length;
113
- let i = 0;
114
- const a = (t) => {
112
+ const n = o.map((t) => t.location), i = n.length;
113
+ let a = 0;
114
+ const s = (t) => {
115
115
  e.flyTo({
116
116
  // These options control the ending camera position: centered at
117
117
  // the target, at zoom level 9, and north up.
@@ -135,45 +135,59 @@ function A(e, o) {
135
135
  }, { flyEnd: !0 });
136
136
  };
137
137
  e.on("moveend", (t) => {
138
- t.flyEnd === !0 && b(e, d, n[i]).then(() => {
139
- i < s - 1 ? (i += 1, a(i)) : r();
138
+ t.flyEnd === !0 && S(e, M, n[a]).then(() => {
139
+ a < i - 1 ? (a += 1, s(a)) : r();
140
140
  });
141
- }), a(i);
141
+ }), s(a);
142
142
  });
143
143
  }
144
- const F = (e, o, r) => {
145
- const n = Math.floor((o - e) / r), s = [];
144
+ const b = (e, o, r) => {
145
+ const n = Math.floor((o - e) / r), i = [];
146
146
  if (n <= 0) return [[e, o]];
147
- for (let i = 0; i < r; i += 1) {
148
- let a = e + i * n, t = a + n < o ? a + n : o;
149
- if (i > 0 && (a += 1 * i, t += 1 * i), i > 0 && t > o && (t = o), i === r - 1 && (t < o || t > o) && (t = o), s.push([a, t]), t >= o) break;
147
+ for (let a = 0; a < r; a += 1) {
148
+ let s = e + a * n, t = s + n < o ? s + n : o;
149
+ if (a > 0 && (s += 1 * a, t += 1 * a), a > 0 && t > o && (t = o), a === r - 1 && (t < o || t > o) && (t = o), i.push([s, t]), t >= o) break;
150
150
  }
151
- return s;
152
- }, S = (e, o, r, n) => {
153
- const s = [];
151
+ return i;
152
+ }, A = (e, o, r, n) => {
153
+ const i = [];
154
154
  o.forEach((t) => {
155
- s.push(t.value);
155
+ i.push(t.value);
156
156
  });
157
- const i = Math.max(...s), a = F(1, i, 6);
158
- if (a.length === 1) {
159
- const [t, l] = a[0];
157
+ const a = Math.max(...i), s = b(1, a, 6);
158
+ if (s.length === 1) {
159
+ const [t, l] = s[0];
160
160
  for (let c = 0; c < l; c += 1) {
161
161
  const f = c + 1;
162
162
  if (e && e >= f && e < f + 1)
163
163
  return r.colors.brand[m[c]];
164
164
  }
165
165
  } else
166
- for (let t = 0; t < a.length; t += 1) {
167
- const [l, c] = a[t];
166
+ for (let t = 0; t < s.length; t += 1) {
167
+ const [l, c] = s[t];
168
168
  if (e && e >= l && e <= c)
169
169
  return r.colors.brand[m[t]];
170
170
  }
171
171
  return n || r.colors.gray[300];
172
+ }, j = (e) => {
173
+ if (!e.length) return { lat: 0, long: 0 };
174
+ const o = e.reduce((n, i) => n + i.lat, 0) / e.length, r = e.reduce((n, i) => n + i.long, 0) / e.length;
175
+ return { lat: o, long: r };
176
+ }, w = (e) => {
177
+ if (!e.length) return 2;
178
+ if (e.length === 1) return 5;
179
+ const o = e.map((t) => t.lat), r = e.map((t) => t.long), n = Math.max(...o) - Math.min(...o), i = Math.max(...r) - Math.min(...r), a = Math.max(n, i);
180
+ if (a < 1) return 6;
181
+ if (a < 10) return 5;
182
+ const s = Math.floor(Math.log2(360 / (a * 2.5)));
183
+ return Math.max(1, Math.min(s, 6));
172
184
  };
173
185
  export {
174
- A as animationCoordinator,
175
- $ as generateMapMarkers,
176
- M as getCoordinatesBetween,
177
- S as getCountryColor,
178
- F as getLoansIntervals
186
+ $ as animationCoordinator,
187
+ j as computeMapCenter,
188
+ w as computeMapZoom,
189
+ F as generateMapMarkers,
190
+ d as getCoordinatesBetween,
191
+ A as getCountryColor,
192
+ b as getLoansIntervals
179
193
  };
@@ -72,6 +72,10 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
72
72
  type: StringConstructor;
73
73
  default: any;
74
74
  };
75
+ optimizeInitialMapZoom: {
76
+ type: BooleanConstructor;
77
+ default: boolean;
78
+ };
75
79
  }>, {}, {
76
80
  hasWebGL: boolean;
77
81
  leafletReady: boolean;
@@ -87,6 +91,13 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
87
91
  paddingBottom: string;
88
92
  };
89
93
  refString(): string;
94
+ computedCenter(): {
95
+ lat: number;
96
+ long: number;
97
+ };
98
+ effectiveLat(): any;
99
+ effectiveLong(): any;
100
+ effectiveZoomLevel(): any;
90
101
  }, {
91
102
  activateZoom(zoomOut?: boolean): false;
92
103
  createWrapperObserver(): void;
@@ -190,6 +201,10 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
190
201
  type: StringConstructor;
191
202
  default: any;
192
203
  };
204
+ optimizeInitialMapZoom: {
205
+ type: BooleanConstructor;
206
+ default: boolean;
207
+ };
193
208
  }>> & Readonly<{}>, {
194
209
  height: number;
195
210
  width: number;
@@ -209,5 +224,6 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
209
224
  showFundraisingLoans: boolean;
210
225
  showTooltips: boolean;
211
226
  defaultBaseColor: string;
227
+ optimizeInitialMapZoom: boolean;
212
228
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
213
229
  export default _default;
@@ -1,6 +1,6 @@
1
1
  import o from "@kiva/kv-tokens";
2
- import { generateMapMarkers as l, animationCoordinator as h, getCountryColor as r } from "../utils/mapUtils.js";
3
- const c = {
2
+ import { computeMapCenter as l, computeMapZoom as h, generateMapMarkers as c, animationCoordinator as m, getCountryColor as r } from "../utils/mapUtils.js";
3
+ const f = {
4
4
  name: "KvMap",
5
5
  props: {
6
6
  /**
@@ -152,6 +152,17 @@ const c = {
152
152
  defaultBaseColor: {
153
153
  type: String,
154
154
  default: null
155
+ },
156
+ /**
157
+ * Automatically compute optimal map center and zoom level based on countriesData distribution.
158
+ * This is an alternative to setting lat/long/zoomLevel directly.
159
+ * Requires: countriesData prop must contain data with lat/long coordinates.
160
+ * Note: Explicit lat/long props will override the computed center when provided.
161
+ * When enabled, zoomLevel prop is ignored in favor of the computed optimal zoom.
162
+ */
163
+ optimizeInitialMapZoom: {
164
+ type: Boolean,
165
+ default: !1
155
166
  }
156
167
  },
157
168
  data() {
@@ -177,14 +188,48 @@ const c = {
177
188
  },
178
189
  refString() {
179
190
  return `mapholder${this.mapId}`;
191
+ },
192
+ /**
193
+ * Computed center from countriesData when optimizeInitialMapZoom is enabled
194
+ */
195
+ computedCenter() {
196
+ var e;
197
+ return !this.optimizeInitialMapZoom || !((e = this.countriesData) != null && e.length) ? { lat: 0, long: 0 } : l(this.countriesData);
198
+ },
199
+ /**
200
+ * Effective latitude: explicit prop overrides computed value
201
+ */
202
+ effectiveLat() {
203
+ var e;
204
+ return this.lat !== null ? this.lat : this.optimizeInitialMapZoom && ((e = this.countriesData) != null && e.length) ? this.computedCenter.lat : null;
205
+ },
206
+ /**
207
+ * Effective longitude: explicit prop overrides computed value
208
+ */
209
+ effectiveLong() {
210
+ var e;
211
+ return this.long !== null ? this.long : this.optimizeInitialMapZoom && ((e = this.countriesData) != null && e.length) ? this.computedCenter.long : null;
212
+ },
213
+ /**
214
+ * Effective zoom level: when optimizing, always use computed zoom
215
+ */
216
+ effectiveZoomLevel() {
217
+ var e;
218
+ return this.optimizeInitialMapZoom && ((e = this.countriesData) != null && e.length) ? h(this.countriesData) : this.zoomLevel;
180
219
  }
181
220
  },
182
221
  watch: {
183
222
  lat(e, t) {
184
- t === null && this.long !== null && !this.mapLibreReady && !this.leafletReady && this.initializeMap();
223
+ t === null && this.effectiveLong !== null && !this.mapLibreReady && !this.leafletReady && this.initializeMap();
185
224
  },
186
225
  long(e, t) {
187
- t === null && this.lat !== null && !this.mapLibreReady && !this.leafletReady && this.initializeMap();
226
+ t === null && this.effectiveLat !== null && !this.mapLibreReady && !this.leafletReady && this.initializeMap();
227
+ },
228
+ countriesData: {
229
+ handler() {
230
+ this.optimizeInitialMapZoom && !this.mapLibreReady && !this.leafletReady && this.initializeMap();
231
+ },
232
+ deep: !0
188
233
  },
189
234
  showFundraisingLoans() {
190
235
  this.mapInstance && (this.mapInstance.remove(), this.initializeLeaflet());
@@ -199,13 +244,13 @@ const c = {
199
244
  methods: {
200
245
  activateZoom(e = !1) {
201
246
  const { mapInstance: t, hasWebGL: i, mapLibreReady: a } = this, s = t.getZoom();
202
- if (!e && s === this.zoomLevel || e && s === this.initialZoom) return !1;
247
+ if (!e && s === this.effectiveZoomLevel || e && s === this.initialZoom) return !1;
203
248
  this.zoomActive = !0;
204
249
  const n = window.setTimeout(() => {
205
250
  i && a ? t.zoomTo(
206
- e ? this.initialZoom : this.zoomLevel,
251
+ e ? this.initialZoom : this.effectiveZoomLevel,
207
252
  { duration: 1200 }
208
- ) : t.setZoom(e ? this.initialZoom : this.zoomLevel), clearTimeout(n), this.zoomActive = !1;
253
+ ) : t.setZoom(e ? this.initialZoom : this.effectiveZoomLevel), clearTimeout(n), this.zoomActive = !1;
209
254
  }, this.autoZoomDelay);
210
255
  },
211
256
  createWrapperObserver() {
@@ -231,15 +276,15 @@ const c = {
231
276
  initializeMap() {
232
277
  const e = document.createElement("script"), t = document.createElement("link");
233
278
  e.setAttribute("async", ""), e.setAttribute("defer", ""), t.setAttribute("rel", "stylesheet"), this.checkWebGL() ? (e.setAttribute("vmid", `maplibregljs${this.mapId}`), t.setAttribute("vmid", `maplibreglcss${this.mapId}`), e.setAttribute("src", "https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.js"), t.setAttribute("href", "https://unpkg.com/maplibre-gl@latest/dist/maplibre-gl.css"), this.testDelayedGlobalLibrary("maplibregl").then((i) => {
234
- i.loaded && !this.mapLoaded && !this.useLeaflet && this.lat != null && this.long != null && (this.initializeMapLibre(), this.mapLibreReady = !0);
279
+ i.loaded && !this.mapLoaded && !this.useLeaflet && this.effectiveLat != null && this.effectiveLong != null && (this.initializeMapLibre(), this.mapLibreReady = !0);
235
280
  })) : (e.setAttribute("vmid", `leafletjs${this.mapId}`), t.setAttribute("vmid", `leaftletcss${this.mapId}`), e.setAttribute("src", "https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"), t.setAttribute("href", "https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"), this.testDelayedGlobalLibrary("L").then((i) => {
236
- i.loaded && !this.mapLoaded && this.lat != null && this.long != null && (this.initializeLeaflet(), this.leafletReady = !0);
281
+ i.loaded && !this.mapLoaded && this.effectiveLat != null && this.effectiveLong != null && (this.initializeLeaflet(), this.leafletReady = !0);
237
282
  })), document.head.appendChild(e), document.head.appendChild(t);
238
283
  },
239
284
  initializeLeaflet() {
240
285
  this.mapInstance = L.map(`kv-map-holder-${this.mapId}`, {
241
- center: [this.lat, this.long],
242
- zoom: this.initialZoom || this.zoomLevel,
286
+ center: [this.effectiveLat, this.effectiveLong],
287
+ zoom: this.initialZoom || this.effectiveZoomLevel,
243
288
  // todo make props for the following options
244
289
  dragging: this.allowDragging,
245
290
  zoomControl: this.showZoomControl,
@@ -279,8 +324,8 @@ const c = {
279
324
  this.showLabels && (e = "https://api.maptiler.com/maps/bright/style.json?key=n1Mz5ziX3k6JfdjFe7mx"), this.mapInstance = new maplibregl.Map({
280
325
  container: `kv-map-holder-${this.mapId}`,
281
326
  style: e,
282
- center: [this.long, this.lat],
283
- zoom: this.initialZoom || this.zoomLevel,
327
+ center: [this.effectiveLong, this.effectiveLat],
328
+ zoom: this.initialZoom || this.effectiveZoomLevel,
284
329
  attributionControl: !1,
285
330
  dragPan: this.allowDragging,
286
331
  scrollZoom: !1,
@@ -294,11 +339,11 @@ const c = {
294
339
  animateMap() {
295
340
  this.mapInstance.style.stylesheet.layers.forEach((e) => {
296
341
  e.type === "symbol" && this.mapInstance.removeLayer(e.id);
297
- }), l(this.mapInstance, this.advancedAnimation.borrowerPoints), setTimeout(() => {
298
- h(this.mapInstance, this.advancedAnimation.borrowerPoints).then(() => {
342
+ }), c(this.mapInstance, this.advancedAnimation.borrowerPoints), setTimeout(() => {
343
+ m(this.mapInstance, this.advancedAnimation.borrowerPoints).then(() => {
299
344
  this.mapInstance.dragPan.enable(), this.mapInstance.scrollZoom.enable(), this.mapInstance.scrollZoom.enable(), this.mapInstance.easeTo({
300
- center: [this.long, this.lat],
301
- zoom: this.initialZoom || this.zoomLevel
345
+ center: [this.effectiveLong, this.effectiveLat],
346
+ zoom: this.initialZoom || this.effectiveZoomLevel
302
347
  });
303
348
  });
304
349
  }, 500);
@@ -372,5 +417,5 @@ const c = {
372
417
  }
373
418
  };
374
419
  export {
375
- c as default
420
+ f as default
376
421
  };
@@ -73,10 +73,15 @@ Required steps:
73
73
  Template Variables to Fill:
74
74
 
75
75
  **Basic Info:**
76
+ - {{folderPrefix}} - Storybook folder prefix for the component (see prefix guidance below)
76
77
  - {{ComponentName}} - Component name (e.g., KvButton, KvModal)
77
78
  - {{componentDescription}} - One-sentence component purpose
78
79
  - {{componentOverviewDescription}} - Brief paragraph about the component
79
80
 
81
+ **Storybook Folder Prefixes:**
82
+
83
+ The MDX `<Meta title="..." />` MUST include a folder prefix matching the component's `.stories.js` file. See **[Storybook Folder Prefixes](./storybook-folder-prefixes.md)** for the full list of prefixes, guidelines, and examples. If uncertain about which prefix to use, **ASK THE USER**.
84
+
80
85
  **Variations:**
81
86
  - {{variationsDescription}} - Describe all available variations
82
87
 
@@ -59,8 +59,9 @@ import ComponentName from '../ComponentName.vue';
59
59
  // or omit this import + docs.page until docs are ready.
60
60
  import ComponentNameDocsMdx from './ComponentNameDocs.mdx';
61
61
 
62
+ // IMPORTANT: Title must include a folder prefix (see guidance below)
62
63
  export default {
63
- title: 'ComponentName',
64
+ title: 'Folder Prefix/ComponentName',
64
65
  component: ComponentName,
65
66
  parameters: {
66
67
  docs: {
@@ -73,6 +74,10 @@ export default {
73
74
  },
74
75
  };
75
76
 
77
+ **Storybook Folder Prefixes:**
78
+
79
+ All story titles MUST include a folder prefix. See **[Storybook Folder Prefixes](./storybook-folder-prefixes.md)** for the full list of prefixes, guidelines, and examples. If uncertain about which prefix to use, **ASK THE USER**.
80
+
76
81
  // Default story - Interactive playground
77
82
  export const Default = {
78
83
  args: {
@@ -149,8 +154,13 @@ Template Variables to Fill:
149
154
  - {{ComponentName}} - Component name (e.g., KvButton, KvModal)
150
155
 
151
156
  **Story Configuration:**
157
+ - {{folderPrefix}} - Storybook folder prefix (see prefix guidance below)
152
158
  - {{argTypes}} - Complete argTypes object with controls for all props
153
159
 
160
+ **Storybook Folder Prefixes:**
161
+
162
+ All story titles MUST include a folder prefix. See **[Storybook Folder Prefixes](./storybook-folder-prefixes.md)** for the full list of prefixes, guidelines, and examples. If uncertain about which prefix to use, **ASK THE USER**.
163
+
154
164
  **ComponentOverview Story:**
155
165
  - {{dataSection}} - data() function if reactive state needed (optional, remove if not needed)
156
166
  - {{setupSection}} - setup() function with icons/constants
@@ -26,7 +26,9 @@ Use this checklist to ensure comprehensive, high-quality component documentation
26
26
  - [ ] MDX file created in `src/vue/stories/[ComponentName]Docs.mdx`
27
27
  - [ ] Correct imports for Storybook blocks (Canvas, Meta, Story, Controls)
28
28
  - [ ] Story file imported correctly (`import * as ComponentStories from './Component.stories.js'`)
29
- - [ ] Meta tag configured with component name and reference
29
+ - [ ] Meta tag includes folder prefix matching the .stories.js file (see [Storybook Folder Prefixes](./storybook-folder-prefixes.md))
30
+ - [ ] If uncertain about prefix, asked for clarification or checked existing similar components
31
+ - [ ] Meta tag configured with component reference
30
32
  - [ ] **No freeform MDX structure** - All template sections present
31
33
 
32
34
  ## Content Sections
@@ -65,16 +65,22 @@ See component-stories-guide.md for implementation details.
65
65
  import { Canvas, Meta, Story, Controls } from '@storybook/addon-docs/blocks';
66
66
  import * as KvComponentStories from './KvComponent.stories.js';
67
67
 
68
- <Meta title="KvComponent" component={KvComponentStories.Component} />
68
+ <Meta title="Folder Prefix/KvComponent" component={KvComponentStories.Component} />
69
69
 
70
70
  ## Component Overview
71
71
 
72
72
  <Story of={KvComponentStories.ComponentOverview} />
73
73
  ```
74
74
 
75
+ **Important:** The `<Meta title="..." />` MUST include a folder prefix that matches the component's `.stories.js` file. See the **Storybook Folder Prefixes** section below for guidance.
76
+
75
77
  The MDX import requires a real stories file. Use a stub with matching export names (ComponentOverview, AllVariations,
76
78
  Default, etc.) so Storybook can load while you flesh out the stories.
77
79
 
80
+ #### Storybook Folder Prefixes
81
+
82
+ The MDX `<Meta title="..." />` MUST include a folder prefix matching the component's `.stories.js` file. See **[Storybook Folder Prefixes](./storybook-folder-prefixes.md)** for the full list of prefixes, guidelines, and examples.
83
+
78
84
  ## Documentation Structure
79
85
 
80
86
  Every component should have a corresponding `.mdx` documentation file in `src/vue/stories/` that follows this structure:
@@ -33,7 +33,9 @@ Use this checklist to ensure comprehensive, high-quality Storybook stories for c
33
33
 
34
34
  ## Default Export Configuration
35
35
 
36
- - [ ] `title` matches component name
36
+ - [ ] `title` includes appropriate folder prefix (see [Storybook Folder Prefixes](./storybook-folder-prefixes.md))
37
+ - [ ] If uncertain about prefix, asked for clarification or checked existing similar components
38
+ - [ ] `title` matches format: 'Folder Prefix/ComponentName'
37
39
  - [ ] `component` references the Vue component correctly
38
40
  - [ ] `parameters.docs.page` points to MDX file
39
41
  - [ ] `parameters.docs.title` is descriptive
@@ -104,7 +104,7 @@ import ComponentNameDocsMdx from './ComponentNameDocs.mdx';
104
104
 
105
105
  ```javascript
106
106
  export default {
107
- title: 'ComponentName',
107
+ title: 'Folder Prefix/ComponentName',
108
108
  component: ComponentName,
109
109
  parameters: {
110
110
  docs: {
@@ -119,11 +119,15 @@ export default {
119
119
  ```
120
120
 
121
121
  **Key elements:**
122
- - **title**: Display name in Storybook sidebar (matches component name)
122
+ - **title**: Display name in Storybook sidebar - MUST include folder prefix (see guidance below)
123
123
  - **component**: Reference to the Vue component
124
124
  - **parameters.docs.page**: Links to the MDX documentation
125
125
  - **argTypes**: Defines interactive controls and their configuration
126
126
 
127
+ #### Storybook Folder Prefixes
128
+
129
+ All story titles MUST include a folder prefix. See **[Storybook Folder Prefixes](./storybook-folder-prefixes.md)** for the full list of prefixes, guidelines, and examples.
130
+
127
131
  ### 3. argTypes Configuration
128
132
 
129
133
  Configure controls for component props to enable interactive testing:
@@ -0,0 +1,36 @@
1
+ # Storybook Folder Prefixes
2
+
3
+ All story titles and MDX `<Meta title="..." />` tags MUST include a folder prefix to organize components in the Storybook sidebar. The prefix in the MDX file MUST match the prefix in the corresponding `.stories.js` file.
4
+
5
+ Use one of the existing prefixes below, or ask for clarification if none fit.
6
+
7
+ ## Existing Folder Prefixes
8
+
9
+ - **Base Styling/** - Style guide, theme provider, and foundational styling components
10
+ - **Charts/** - Chart and data visualization components (e.g., KvPieChart, KvLineGraph, KvTreeMapChart)
11
+ - **Checkout/** - Checkout flow components (e.g., KvAtbModal, KvCartModal, KvCartPill, KvCheckoutReceipt)
12
+ - **Comments/** - Comment-related components (e.g., KvCommentsAdd, KvCommentsList, KvCommentsListItem)
13
+ - **Components/** - General-purpose components that don't fit other categories (e.g., KvCarousel, KvLightbox, KvMap, KvUtilityMenu)
14
+ - **Forms/** - Form controls and input components (e.g., KvButton, KvCheckbox, KvTextInput, KvSelect, KvSwitch)
15
+ - **Interface Elements/** - General UI elements, indicators, and feedback components (e.g., KvToast, KvTooltip, KvProgressBar, KvLoadingSpinner)
16
+ - **Loan Display/** - Loan-specific display components (e.g., KvLoanInfoCard, KvClassicLoanCard, KvBorrowerImage)
17
+ - **Page Frame/** - Page layout and structural components (e.g., KvPageContainer, KvGrid, KvWwwHeader)
18
+
19
+ ## Guidelines
20
+
21
+ - If the component clearly fits an existing category, use that prefix
22
+ - If uncertain or the component represents a new category, **ask for clarification** on which prefix to use or if a new folder prefix should be created
23
+ - Never omit the folder prefix
24
+ - The prefix creates the folder structure in the Storybook sidebar navigation
25
+
26
+ ## Examples
27
+
28
+ **Story titles:**
29
+ - `'Forms/KvButton'`
30
+ - `'Loan Display/KvLoanInfoCard'`
31
+ - `'Interface Elements/KvToast'`
32
+
33
+ **MDX Meta tags:**
34
+ - `<Meta title="Forms/KvButton" ... />`
35
+ - `<Meta title="Loan Display/KvLoanInfoCard" ... />`
36
+ - `<Meta title="Interface Elements/KvToast" ... />`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kiva/kv-components",
3
- "version": "8.5.4",
3
+ "version": "8.5.6",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -125,5 +125,5 @@
125
125
  "embla-carousel-fade",
126
126
  "popper.js"
127
127
  ],
128
- "gitHead": "79d1606e5c72b3b1a4e64fe7b94944030d3a23aa"
128
+ "gitHead": "f5556880afcdae5bef45601e29353e5c9406160f"
129
129
  }