@kiva/kv-components 8.9.1 → 8.10.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,202 @@
1
+ import { PropType } from 'vue';
2
+ export interface KvPieChartV2Item {
3
+ label: string;
4
+ value: number;
5
+ color?: string;
6
+ }
7
+ export type PieChartUnit = 'percent' | 'amount' | 'count';
8
+ interface ComputedSegment {
9
+ label: string;
10
+ value: number;
11
+ percent: number;
12
+ color: string;
13
+ dashLength: number;
14
+ startDeg: number;
15
+ delay: number;
16
+ isVisible: boolean;
17
+ }
18
+ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
19
+ values: {
20
+ type: PropType<KvPieChartV2Item[]>;
21
+ default: () => any[];
22
+ };
23
+ unit: {
24
+ type: PropType<PieChartUnit>;
25
+ default: string;
26
+ validator: (value: string) => boolean;
27
+ };
28
+ loading: {
29
+ type: BooleanConstructor;
30
+ default: boolean;
31
+ };
32
+ shownSegments: {
33
+ type: NumberConstructor;
34
+ default: number;
35
+ };
36
+ strokeWidth: {
37
+ type: NumberConstructor;
38
+ default: number;
39
+ };
40
+ segmentGap: {
41
+ type: NumberConstructor;
42
+ default: number;
43
+ };
44
+ initialDelay: {
45
+ type: NumberConstructor;
46
+ default: number;
47
+ };
48
+ animateOut: {
49
+ type: BooleanConstructor;
50
+ default: boolean;
51
+ };
52
+ }>, {
53
+ CX: number;
54
+ CY: number;
55
+ radius: import('vue').ComputedRef<number>;
56
+ circumference: import('vue').ComputedRef<number>;
57
+ LOADING_BG_COLOR: string;
58
+ OTHER_SEGMENT_BG_COLOR: string;
59
+ showOtherLightbox: import('vue').Ref<boolean, boolean>;
60
+ animatedIn: import('vue').Ref<boolean, boolean>;
61
+ displayValues: import('vue').Ref<number[], number[]>;
62
+ hasData: import('vue').ComputedRef<boolean>;
63
+ visibleSegments: import('vue').ComputedRef<ComputedSegment[]>;
64
+ otherSegment: import('vue').ComputedRef<ComputedSegment>;
65
+ otherItems: import('vue').ComputedRef<{
66
+ color: string;
67
+ label: string;
68
+ value: number;
69
+ }[]>;
70
+ allItemsWithColors: import('vue').ComputedRef<{
71
+ color: string;
72
+ label: string;
73
+ value: number;
74
+ }[]>;
75
+ valueMinWidth: import('vue').ComputedRef<string>;
76
+ formatDisplayValue: (index: number) => string;
77
+ formatItemValue: (item: {
78
+ value: number;
79
+ }) => string;
80
+ formatOtherDisplayValue: () => string;
81
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
82
+ values: {
83
+ type: PropType<KvPieChartV2Item[]>;
84
+ default: () => any[];
85
+ };
86
+ unit: {
87
+ type: PropType<PieChartUnit>;
88
+ default: string;
89
+ validator: (value: string) => boolean;
90
+ };
91
+ loading: {
92
+ type: BooleanConstructor;
93
+ default: boolean;
94
+ };
95
+ shownSegments: {
96
+ type: NumberConstructor;
97
+ default: number;
98
+ };
99
+ strokeWidth: {
100
+ type: NumberConstructor;
101
+ default: number;
102
+ };
103
+ segmentGap: {
104
+ type: NumberConstructor;
105
+ default: number;
106
+ };
107
+ initialDelay: {
108
+ type: NumberConstructor;
109
+ default: number;
110
+ };
111
+ animateOut: {
112
+ type: BooleanConstructor;
113
+ default: boolean;
114
+ };
115
+ }>> & Readonly<{}>, {
116
+ values: KvPieChartV2Item[];
117
+ loading: boolean;
118
+ unit: PieChartUnit;
119
+ shownSegments: number;
120
+ strokeWidth: number;
121
+ segmentGap: number;
122
+ initialDelay: number;
123
+ animateOut: boolean;
124
+ }, {}, {
125
+ KvLightbox: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
126
+ blurBackground: {
127
+ type: BooleanConstructor;
128
+ default: boolean;
129
+ };
130
+ visible: {
131
+ type: BooleanConstructor;
132
+ default: boolean;
133
+ };
134
+ variant: {
135
+ type: StringConstructor;
136
+ default: string;
137
+ validator(value: string): boolean;
138
+ };
139
+ title: {
140
+ type: StringConstructor;
141
+ required: true;
142
+ };
143
+ preventClose: {
144
+ type: BooleanConstructor;
145
+ default: boolean;
146
+ };
147
+ }>, {
148
+ mdiClose: string;
149
+ role: import('vue').ComputedRef<"alertdialog" | "dialog">;
150
+ kvLightbox: import('vue').Ref<any, any>;
151
+ kvLightboxBody: import('vue').Ref<any, any>;
152
+ onKeyUp: any;
153
+ onScreenClick: () => void;
154
+ hide: (closedBy?: string) => void;
155
+ show: () => void;
156
+ controlsRef: import('vue').Ref<any, any>;
157
+ }, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, "lightbox-closed"[], "lightbox-closed", import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
158
+ blurBackground: {
159
+ type: BooleanConstructor;
160
+ default: boolean;
161
+ };
162
+ visible: {
163
+ type: BooleanConstructor;
164
+ default: boolean;
165
+ };
166
+ variant: {
167
+ type: StringConstructor;
168
+ default: string;
169
+ validator(value: string): boolean;
170
+ };
171
+ title: {
172
+ type: StringConstructor;
173
+ required: true;
174
+ };
175
+ preventClose: {
176
+ type: BooleanConstructor;
177
+ default: boolean;
178
+ };
179
+ }>> & Readonly<{
180
+ "onLightbox-closed"?: (...args: any[]) => any;
181
+ }>, {
182
+ variant: string;
183
+ visible: boolean;
184
+ preventClose: boolean;
185
+ blurBackground: boolean;
186
+ }, {}, {
187
+ KvMaterialIcon: import('vue').DefineComponent<import('vue').ExtractPropTypes<{
188
+ icon: {
189
+ type: StringConstructor;
190
+ default: string;
191
+ };
192
+ }>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<{
193
+ icon: {
194
+ type: StringConstructor;
195
+ default: string;
196
+ };
197
+ }>> & Readonly<{}>, {
198
+ icon: string;
199
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
200
+ }, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
201
+ }, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
202
+ export default _default;
@@ -0,0 +1,232 @@
1
+ import { toRefs as z, ref as I, computed as u, onMounted as J, watch as U, onUnmounted as Q } from "vue";
2
+ import { getPieChartColor as $, LOADING_BG_COLOR as Z, OTHER_SEGMENT_BG_COLOR as ee } from "../utils/pieChartColors.js";
3
+ import { easeInOutCubic as te } from "../utils/useCountUp.js";
4
+ import ae from "./KvLightbox.js";
5
+ const E = 262, le = E / 2, ne = E / 2, W = 500, ue = 500, ve = {
6
+ name: "KvPieChartV2",
7
+ components: {
8
+ KvLightbox: ae
9
+ },
10
+ props: {
11
+ /**
12
+ * Chart data items. Each must have a label and numeric value.
13
+ */
14
+ values: {
15
+ type: Array,
16
+ default: () => []
17
+ },
18
+ /**
19
+ * How values are displayed in legend pills.
20
+ * @values percent, amount, count
21
+ */
22
+ unit: {
23
+ type: String,
24
+ default: "percent",
25
+ validator: (g) => ["percent", "amount", "count"].includes(g)
26
+ },
27
+ /**
28
+ * Shows a skeleton donut ring when true.
29
+ */
30
+ loading: {
31
+ type: Boolean,
32
+ default: !1
33
+ },
34
+ /**
35
+ * Maximum number of visible segments before remaining items collapse into "Other".
36
+ */
37
+ shownSegments: {
38
+ type: Number,
39
+ default: 5
40
+ },
41
+ /**
42
+ * Donut ring thickness in SVG user units (viewBox is 262x262). The radius
43
+ * shrinks as this grows, so the outer edge always fits within the viewBox.
44
+ */
45
+ strokeWidth: {
46
+ type: Number,
47
+ default: 56
48
+ },
49
+ /**
50
+ * Visual gap between adjacent segments, in SVG user units along the ring's
51
+ * circumference. Set to 0 for no gap.
52
+ */
53
+ segmentGap: {
54
+ type: Number,
55
+ default: 2
56
+ },
57
+ /**
58
+ * Delay in milliseconds before the first segment starts animating in.
59
+ * Subsequent segments stagger from this baseline.
60
+ */
61
+ initialDelay: {
62
+ type: Number,
63
+ default: 1e3
64
+ },
65
+ /**
66
+ * When changed from false to true, plays the reverse sweep-out animation.
67
+ */
68
+ animateOut: {
69
+ type: Boolean,
70
+ default: !1
71
+ }
72
+ },
73
+ setup(g) {
74
+ const {
75
+ values: A,
76
+ unit: m,
77
+ loading: M,
78
+ shownSegments: d,
79
+ strokeWidth: B,
80
+ segmentGap: T,
81
+ initialDelay: D,
82
+ animateOut: y
83
+ } = z(g), k = I(!1), c = I(!1), G = u(() => Math.max((E - B.value) / 2, 1)), b = u(() => 2 * Math.PI * G.value), h = u(() => [...A.value].sort((e, t) => t.value - e.value)), o = u(() => h.value.reduce((e, t) => e + t.value, 0)), O = u(() => A.value.length > 0), S = u(() => h.value.slice(0, d.value)), C = u(() => h.value.slice(d.value).map((t, n) => ({
84
+ ...t,
85
+ color: $(d.value + n, t.color)
86
+ }))), q = u(() => h.value.map((e, t) => ({
87
+ ...e,
88
+ color: $(t, e.color)
89
+ }))), w = u(() => C.value.reduce((e, t) => e + t.value, 0)), R = u(() => o.value > 0 ? w.value / o.value : 0), f = u(() => {
90
+ let e = 0;
91
+ return S.value.map((t, n) => {
92
+ const a = o.value > 0 ? t.value / o.value : 0, l = Math.max(a * b.value - T.value, 0), s = e * 360 - 90;
93
+ return e += a, {
94
+ label: t.label,
95
+ value: t.value,
96
+ percent: a,
97
+ color: $(n, t.color),
98
+ dashLength: l,
99
+ startDeg: s,
100
+ delay: D.value + n * W,
101
+ isVisible: c.value && !y.value
102
+ };
103
+ });
104
+ }), v = u(() => {
105
+ if (C.value.length === 0) return null;
106
+ let e = 0;
107
+ S.value.forEach((l) => {
108
+ e += o.value > 0 ? l.value / o.value : 0;
109
+ });
110
+ const t = Math.max(R.value * b.value - T.value, 0), n = e * 360 - 90, a = S.value.length;
111
+ return {
112
+ label: "Other",
113
+ value: w.value,
114
+ percent: R.value,
115
+ color: "#C4C4C4",
116
+ dashLength: t,
117
+ startDeg: n,
118
+ delay: D.value + a * W,
119
+ isVisible: c.value && !y.value
120
+ };
121
+ }), r = I([]), p = [], i = [], V = (e) => m.value === "percent" ? Math.round(e.percent * 100) : e.value, _ = (e, t, n) => {
122
+ let a = null;
123
+ function l(s) {
124
+ a === null && (a = s);
125
+ const L = s - a, P = Math.min(L / ue, 1), Y = te(P), j = Math.round(t + (n - t) * Y);
126
+ r.value[e] = j, P < 1 && (i[e] = requestAnimationFrame(l));
127
+ }
128
+ i[e] = requestAnimationFrame(l);
129
+ }, x = (e = !1) => {
130
+ p.forEach(clearTimeout), p.length = 0, i.forEach(cancelAnimationFrame), i.length = 0;
131
+ const t = [
132
+ ...f.value,
133
+ ...v.value ? [v.value] : []
134
+ ];
135
+ for (; r.value.length < t.length; )
136
+ r.value.push(0);
137
+ t.forEach((n, a) => {
138
+ const l = V(n), { delay: s } = n, L = setTimeout(() => {
139
+ e ? _(a, r.value[a], 0) : _(a, 0, l);
140
+ }, s);
141
+ p.push(L);
142
+ });
143
+ }, N = (e) => {
144
+ const t = r.value[e] ?? 0;
145
+ switch (m.value) {
146
+ case "percent":
147
+ return `${t}%`;
148
+ case "amount":
149
+ return `$${t.toLocaleString()}`;
150
+ case "count":
151
+ default:
152
+ return `${t.toLocaleString()}`;
153
+ }
154
+ }, K = (e) => {
155
+ const t = o.value > 0 ? e.value / o.value : 0;
156
+ switch (m.value) {
157
+ case "percent":
158
+ return `${Math.round(t * 100)}%`;
159
+ case "amount":
160
+ return `$${e.value.toLocaleString()}`;
161
+ case "count":
162
+ default:
163
+ return `${e.value.toLocaleString()}`;
164
+ }
165
+ }, X = () => {
166
+ const e = f.value.length;
167
+ return N(e);
168
+ }, H = u(() => {
169
+ const e = [
170
+ ...f.value,
171
+ ...v.value ? [v.value] : []
172
+ ];
173
+ let t = 0;
174
+ return e.forEach((n) => {
175
+ const a = V(n);
176
+ let l;
177
+ switch (m.value) {
178
+ case "percent":
179
+ l = `${a}%`;
180
+ break;
181
+ case "amount":
182
+ l = `$${a.toLocaleString()}`;
183
+ break;
184
+ default:
185
+ l = `${a.toLocaleString()}`;
186
+ }
187
+ l.length > t && (t = l.length);
188
+ }), `${t}ch`;
189
+ }), F = () => {
190
+ requestAnimationFrame(() => {
191
+ requestAnimationFrame(() => {
192
+ c.value = !0, x(!1);
193
+ });
194
+ });
195
+ };
196
+ return J(() => {
197
+ !M.value && O.value && F();
198
+ }), U(M, (e) => {
199
+ !e && O.value && F();
200
+ }), U(y, (e) => {
201
+ e && (c.value = !1, x(!0));
202
+ }), Q(() => {
203
+ p.forEach(clearTimeout), i.forEach(cancelAnimationFrame);
204
+ }), {
205
+ // Constants
206
+ CX: le,
207
+ CY: ne,
208
+ radius: G,
209
+ circumference: b,
210
+ LOADING_BG_COLOR: Z,
211
+ OTHER_SEGMENT_BG_COLOR: ee,
212
+ // State
213
+ showOtherLightbox: k,
214
+ animatedIn: c,
215
+ displayValues: r,
216
+ // Computed
217
+ hasData: O,
218
+ visibleSegments: f,
219
+ otherSegment: v,
220
+ otherItems: C,
221
+ allItemsWithColors: q,
222
+ valueMinWidth: H,
223
+ // Methods
224
+ formatDisplayValue: N,
225
+ formatItemValue: K,
226
+ formatOtherDisplayValue: X
227
+ };
228
+ }
229
+ };
230
+ export {
231
+ ve as default
232
+ };
@@ -64,9 +64,9 @@ declare const _default: import('vue').DefineComponent<import('vue').ExtractPropT
64
64
  };
65
65
  }>> & Readonly<{}>, {
66
66
  color: string;
67
+ strokeWidth: number;
67
68
  arcScale: number;
68
69
  rotate: number;
69
- strokeWidth: number;
70
70
  showNumber: boolean;
71
71
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
72
72
  export default _default;
@@ -58,6 +58,7 @@ export { default as KvMaterialIcon } from './KvMaterialIcon.vue';
58
58
  export { default as KvPageContainer } from './KvPageContainer.vue';
59
59
  export { default as KvPagination } from './KvPagination.vue';
60
60
  export { default as KvPieChart } from './KvPieChart.vue';
61
+ export { default as KvPieChartV2 } from './KvPieChartV2.vue';
61
62
  export { default as KvPill } from './KvPill.vue';
62
63
  export { default as KvPopper } from './KvPopper.vue';
63
64
  export { default as KvProgressBar } from './KvProgressBar.vue';