frappe-ui 0.1.274 → 0.1.275
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/package.json +1 -1
- package/src/components/Charts/AxisChart.vue +5 -1
- package/src/components/Charts/DonutChart.vue +5 -1
- package/src/components/Charts/ECharts.vue +1 -1
- package/src/components/Charts/FunnelChart.vue +5 -1
- package/src/components/Charts/axisChartOptions.ts +7 -2
- package/src/components/Charts/donutChartOptions.ts +4 -2
- package/src/components/Charts/eChartOptions.ts +27 -16
- package/src/components/Charts/funnelChartOptions.ts +4 -2
- package/src/components/Charts/types.ts +3 -0
- package/src/components/TextInput/TextInput.vue +18 -18
package/package.json
CHANGED
|
@@ -13,7 +13,11 @@ const props = defineProps<{ config: AxisChartConfig }>()
|
|
|
13
13
|
const error = ref('')
|
|
14
14
|
const options = computed(() => {
|
|
15
15
|
try {
|
|
16
|
-
|
|
16
|
+
const config = {
|
|
17
|
+
...props.config,
|
|
18
|
+
isRTL: props.config.isRTL ?? document.documentElement.dir === 'rtl',
|
|
19
|
+
}
|
|
20
|
+
return useAxisChartOptions(config)
|
|
17
21
|
} catch (e: any) {
|
|
18
22
|
error.value = e.message
|
|
19
23
|
return {}
|
|
@@ -13,7 +13,11 @@ const props = defineProps<{ config: DonutChartConfig }>()
|
|
|
13
13
|
const error = ref('')
|
|
14
14
|
const options = computed(() => {
|
|
15
15
|
try {
|
|
16
|
-
|
|
16
|
+
const config = {
|
|
17
|
+
...props.config,
|
|
18
|
+
isRTL: props.config.isRTL ?? document.documentElement.dir === 'rtl',
|
|
19
|
+
}
|
|
20
|
+
return useDonutChartOptions(config)
|
|
17
21
|
} catch (e: any) {
|
|
18
22
|
error.value = e.message
|
|
19
23
|
return {}
|
|
@@ -56,7 +56,7 @@ watch(
|
|
|
56
56
|
</script>
|
|
57
57
|
|
|
58
58
|
<template>
|
|
59
|
-
<div ref="chartDiv" v-show="!error" :class="chartClass"></div>
|
|
59
|
+
<div ref="chartDiv" v-show="!error" dir="ltr" :class="chartClass"></div>
|
|
60
60
|
<div
|
|
61
61
|
v-show="error"
|
|
62
62
|
class="flex h-full w-full items-center justify-center text-center text-ink-red-3"
|
|
@@ -13,7 +13,11 @@ const props = defineProps<{ config: FunnelChartConfig }>()
|
|
|
13
13
|
const error = ref('')
|
|
14
14
|
const options = computed(() => {
|
|
15
15
|
try {
|
|
16
|
-
|
|
16
|
+
const config = {
|
|
17
|
+
...props.config,
|
|
18
|
+
isRTL: props.config.isRTL ?? document.documentElement.dir === 'rtl',
|
|
19
|
+
}
|
|
20
|
+
return useFunnelChartOptions(config)
|
|
17
21
|
} catch (e: any) {
|
|
18
22
|
error.value = e.message
|
|
19
23
|
return {}
|
|
@@ -22,6 +22,7 @@ export default function useAxisChartOptions(config: AxisChartConfig) {
|
|
|
22
22
|
throw new Error('Swap axes is not supported for non-bar series or y2 axis')
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
const isRTL = config.isRTL
|
|
25
26
|
const swapXY = config.swapXY
|
|
26
27
|
const lastBarSeriesIdx = config.series
|
|
27
28
|
.slice()
|
|
@@ -39,7 +40,7 @@ export default function useAxisChartOptions(config: AxisChartConfig) {
|
|
|
39
40
|
labelPosition = idx == lastBarSeriesIdx ? 'top' : 'inside'
|
|
40
41
|
}
|
|
41
42
|
if (s.type == 'bar' && swapXY) {
|
|
42
|
-
labelPosition = 'right'
|
|
43
|
+
labelPosition = isRTL ? 'left' : 'right'
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
const standardSeriesOptions = {
|
|
@@ -90,7 +91,11 @@ export default function useAxisChartOptions(config: AxisChartConfig) {
|
|
|
90
91
|
}
|
|
91
92
|
|
|
92
93
|
function getBarSeriesOptions(config: AxisChartConfig, series: BarSeriesConfig) {
|
|
93
|
-
const
|
|
94
|
+
const isRTL = config.isRTL
|
|
95
|
+
let roundedCorners = config.swapXY ? [0, 2, 2, 0] : [2, 2, 0, 0]
|
|
96
|
+
if (config.swapXY && isRTL) {
|
|
97
|
+
roundedCorners = [2, 0, 0, 2]
|
|
98
|
+
}
|
|
94
99
|
const idx = config.series.findIndex((s) => s.name === series.name)
|
|
95
100
|
const lastBarSeriesIdx = config.series
|
|
96
101
|
.slice()
|
|
@@ -3,6 +3,7 @@ import { formatValue } from './helpers'
|
|
|
3
3
|
import { DonutChartConfig } from './types'
|
|
4
4
|
|
|
5
5
|
export default function useDonutChartOptions(config: DonutChartConfig) {
|
|
6
|
+
const isRTL = config.isRTL
|
|
6
7
|
let data = config.data || []
|
|
7
8
|
|
|
8
9
|
data = data.sort((a, b) => {
|
|
@@ -44,7 +45,7 @@ export default function useDonutChartOptions(config: DonutChartConfig) {
|
|
|
44
45
|
animationDuration: 700,
|
|
45
46
|
color: config.colors,
|
|
46
47
|
textStyle: { fontFamily: ['InterVar', 'sans-serif'] },
|
|
47
|
-
title: getTitleOptions(config.title, config.subtitle),
|
|
48
|
+
title: getTitleOptions(config.title, config.subtitle, isRTL),
|
|
48
49
|
dataset: {
|
|
49
50
|
source: [
|
|
50
51
|
[config.categoryColumn, config.valueColumn],
|
|
@@ -117,13 +118,14 @@ export default function useDonutChartOptions(config: DonutChartConfig) {
|
|
|
117
118
|
confine: true,
|
|
118
119
|
appendToBody: false,
|
|
119
120
|
formatter: function (params: any) {
|
|
121
|
+
const dirAttr = isRTL ? ' dir="rtl"' : ''
|
|
120
122
|
const p = params as any
|
|
121
123
|
const value = p.value[1]
|
|
122
124
|
const percentage = total > 0 ? (value / total) * 100 : 0
|
|
123
125
|
const formatted = isNaN(value) ? value : formatValue(value, 1, true)
|
|
124
126
|
const formattedPercentage = percentage.toFixed(0)
|
|
125
127
|
return `
|
|
126
|
-
<div class="flex items-center justify-between gap-5">
|
|
128
|
+
<div${dirAttr} class="flex items-center justify-between gap-5">
|
|
127
129
|
<div>${p.name}</div>
|
|
128
130
|
<div class="font-bold">
|
|
129
131
|
${formatted} (${formattedPercentage}%)
|
|
@@ -11,6 +11,7 @@ export const SUBTITLE_HEIGHT = 18
|
|
|
11
11
|
export const TITLE_BOTTOM = 24
|
|
12
12
|
|
|
13
13
|
export default function useEchartsOptions(config: AxisChartConfig) {
|
|
14
|
+
const isRTL = config.isRTL
|
|
14
15
|
const title = config.title
|
|
15
16
|
const subtitle = config.subtitle
|
|
16
17
|
const hasTitle = title ? 1 : 0
|
|
@@ -27,11 +28,11 @@ export default function useEchartsOptions(config: AxisChartConfig) {
|
|
|
27
28
|
animation: true,
|
|
28
29
|
animationDuration: 700,
|
|
29
30
|
textStyle: { fontFamily: ['InterVar', 'sans-serif'] },
|
|
30
|
-
title: getTitleOptions(title, subtitle),
|
|
31
|
+
title: getTitleOptions(title, subtitle, isRTL),
|
|
31
32
|
color: config.colors,
|
|
32
33
|
grid: {
|
|
33
|
-
left: '1%',
|
|
34
|
-
right: config.swapXY ? '2.5%' : '1.5%',
|
|
34
|
+
left: isRTL ? (config.swapXY ? '2.5%' : '1.5%') : '1%',
|
|
35
|
+
right: isRTL ? '1%' : config.swapXY ? '2.5%' : '1.5%',
|
|
35
36
|
top:
|
|
36
37
|
PADDING_TOP +
|
|
37
38
|
TITLE_HEIGHT * hasTitle +
|
|
@@ -47,6 +48,8 @@ export default function useEchartsOptions(config: AxisChartConfig) {
|
|
|
47
48
|
show: true,
|
|
48
49
|
trigger: 'axis',
|
|
49
50
|
formatter: (params: Object | Array<Object>) => {
|
|
51
|
+
const dirAttr = isRTL ? ' dir="rtl"' : ''
|
|
52
|
+
|
|
50
53
|
if (Array.isArray(params)) {
|
|
51
54
|
params = params
|
|
52
55
|
// remove zero values
|
|
@@ -60,7 +63,7 @@ export default function useEchartsOptions(config: AxisChartConfig) {
|
|
|
60
63
|
const value = config.swapXY ? p.value[0] : p.value[1]
|
|
61
64
|
const formatted = isNaN(value) ? value : formatValue(value)
|
|
62
65
|
return `
|
|
63
|
-
<div class="flex items-center justify-between gap-5">
|
|
66
|
+
<div${dirAttr} class="flex items-center justify-between gap-5">
|
|
64
67
|
<div>${p.name}</div>
|
|
65
68
|
<div class="font-bold">${formatted}</div>
|
|
66
69
|
</div>
|
|
@@ -77,7 +80,7 @@ export default function useEchartsOptions(config: AxisChartConfig) {
|
|
|
77
80
|
: xValue
|
|
78
81
|
const formattedY = isNaN(yValue) ? yValue : formatValue(yValue)
|
|
79
82
|
return `
|
|
80
|
-
<div class="flex flex-col">
|
|
83
|
+
<div${dirAttr} class="flex flex-col">
|
|
81
84
|
${idx == 0 ? `<div>${formattedX}</div>` : ''}
|
|
82
85
|
<div class="flex items-center justify-between gap-5">
|
|
83
86
|
<div class="flex gap-1 items-center">
|
|
@@ -130,13 +133,13 @@ export default function useEchartsOptions(config: AxisChartConfig) {
|
|
|
130
133
|
}
|
|
131
134
|
}
|
|
132
135
|
|
|
133
|
-
export function getTitleOptions(title: string, subtitle?: string) {
|
|
136
|
+
export function getTitleOptions(title: string, subtitle?: string, isRTL?: boolean) {
|
|
134
137
|
return {
|
|
135
138
|
top: '4px',
|
|
136
|
-
left: '0.8%',
|
|
139
|
+
left: isRTL ? 'right' : '0.8%',
|
|
140
|
+
padding: isRTL ? [0, 10, 0, 0] : 0,
|
|
137
141
|
text: title,
|
|
138
142
|
subtext: subtitle,
|
|
139
|
-
padding: 0,
|
|
140
143
|
itemGap: -3,
|
|
141
144
|
textStyle: {
|
|
142
145
|
fontSize: 14,
|
|
@@ -154,6 +157,8 @@ export function getTitleOptions(title: string, subtitle?: string) {
|
|
|
154
157
|
}
|
|
155
158
|
|
|
156
159
|
function getXAxisOptions(config: AxisChartConfig) {
|
|
160
|
+
const isRTL = config.isRTL
|
|
161
|
+
|
|
157
162
|
const options = config.swapXY
|
|
158
163
|
? {
|
|
159
164
|
show: true,
|
|
@@ -161,12 +166,13 @@ function getXAxisOptions(config: AxisChartConfig) {
|
|
|
161
166
|
z: 2,
|
|
162
167
|
scale: false,
|
|
163
168
|
boundaryGap: false,
|
|
169
|
+
inverse: isRTL,
|
|
164
170
|
position: 'top',
|
|
165
|
-
name: `${config.yAxis.title} →`,
|
|
171
|
+
name: isRTL ? `← ${config.yAxis.title}` : `${config.yAxis.title} →`,
|
|
166
172
|
nameGap: 6,
|
|
167
173
|
nameLocation: 'end',
|
|
168
174
|
nameTextStyle: {
|
|
169
|
-
align: 'right',
|
|
175
|
+
align: isRTL ? 'left' : 'right',
|
|
170
176
|
verticalAlign: 'bottom',
|
|
171
177
|
padding: [0, 0, 26, 0],
|
|
172
178
|
backgroundColor: 'var(--surface-white)',
|
|
@@ -205,6 +211,7 @@ function getXAxisOptions(config: AxisChartConfig) {
|
|
|
205
211
|
z: 2,
|
|
206
212
|
type: config.xAxis.type,
|
|
207
213
|
scale: true,
|
|
214
|
+
inverse: isRTL,
|
|
208
215
|
splitLine: {
|
|
209
216
|
show: false,
|
|
210
217
|
},
|
|
@@ -228,6 +235,8 @@ function getXAxisOptions(config: AxisChartConfig) {
|
|
|
228
235
|
}
|
|
229
236
|
|
|
230
237
|
function getYAxisOptions(config: AxisChartConfig) {
|
|
238
|
+
const isRTL = config.isRTL
|
|
239
|
+
|
|
231
240
|
let primaryYAxisOptions = config.swapXY
|
|
232
241
|
? {
|
|
233
242
|
show: true,
|
|
@@ -235,6 +244,7 @@ function getYAxisOptions(config: AxisChartConfig) {
|
|
|
235
244
|
z: 2,
|
|
236
245
|
scale: true,
|
|
237
246
|
inverse: 'true',
|
|
247
|
+
position: isRTL ? 'right' : 'left',
|
|
238
248
|
splitLine: {
|
|
239
249
|
show: false,
|
|
240
250
|
},
|
|
@@ -256,14 +266,15 @@ function getYAxisOptions(config: AxisChartConfig) {
|
|
|
256
266
|
type: 'value',
|
|
257
267
|
z: 2,
|
|
258
268
|
scale: false,
|
|
269
|
+
position: isRTL ? 'right' : 'left',
|
|
259
270
|
boundaryGap: ['0%', '1%'],
|
|
260
271
|
name: `↑ ${config.yAxis.title}`,
|
|
261
272
|
nameGap: 6,
|
|
262
273
|
nameLocation: 'end',
|
|
263
274
|
nameTextStyle: {
|
|
264
|
-
align: 'left',
|
|
275
|
+
align: isRTL ? 'right' : 'left',
|
|
265
276
|
verticalAlign: 'top',
|
|
266
|
-
padding: [0, 0, 0, -2],
|
|
277
|
+
padding: isRTL ? [0, -2, 0, 0] : [0, 0, 0, -2],
|
|
267
278
|
backgroundColor: 'var(--surface-white)',
|
|
268
279
|
borderColor: 'var(--surface-white)',
|
|
269
280
|
color: 'var(--ink-gray-8)',
|
|
@@ -307,13 +318,14 @@ function getYAxisOptions(config: AxisChartConfig) {
|
|
|
307
318
|
z: 2,
|
|
308
319
|
alignTicks: true,
|
|
309
320
|
scale: false,
|
|
321
|
+
position: isRTL ? 'left' : 'right',
|
|
310
322
|
boundaryGap: ['0%', '1%'],
|
|
311
|
-
name: `${config.y2Axis?.title} ↑`,
|
|
323
|
+
name: isRTL ? `↑ ${config.y2Axis?.title}` : `${config.y2Axis?.title} ↑`,
|
|
312
324
|
nameLocation: 'end',
|
|
313
325
|
nameTextStyle: {
|
|
314
|
-
align: 'right',
|
|
326
|
+
align: isRTL ? 'left' : 'right',
|
|
315
327
|
verticalAlign: 'top',
|
|
316
|
-
padding: [0, 5, 0, 0],
|
|
328
|
+
padding: isRTL ? [0, 0, 0, 5] : [0, 5, 0, 0],
|
|
317
329
|
backgroundColor: 'var(--surface-white)',
|
|
318
330
|
borderColor: 'var(--surface-white)',
|
|
319
331
|
color: 'var(--ink-gray-8)',
|
|
@@ -341,7 +353,6 @@ function getYAxisOptions(config: AxisChartConfig) {
|
|
|
341
353
|
formatter: function (value: number) {
|
|
342
354
|
return formatValue(value, 1, true)
|
|
343
355
|
},
|
|
344
|
-
// color: '#000',
|
|
345
356
|
},
|
|
346
357
|
min: config.y2Axis?.yMin,
|
|
347
358
|
max: config.y2Axis?.yMax,
|
|
@@ -9,6 +9,7 @@ import { formatValue } from './helpers'
|
|
|
9
9
|
import { FunnelChartConfig } from './types'
|
|
10
10
|
|
|
11
11
|
export default function getFunnelChartOptions(config: FunnelChartConfig) {
|
|
12
|
+
const isRTL = config.isRTL
|
|
12
13
|
let data = config.data || []
|
|
13
14
|
|
|
14
15
|
const labelPosition = 'alternate'
|
|
@@ -37,7 +38,7 @@ export default function getFunnelChartOptions(config: FunnelChartConfig) {
|
|
|
37
38
|
animationDuration: 700,
|
|
38
39
|
color: colors,
|
|
39
40
|
textStyle: { fontFamily: ['InterVar', 'sans-serif'] },
|
|
40
|
-
title: getTitleOptions(config.title, config.subtitle),
|
|
41
|
+
title: getTitleOptions(config.title, config.subtitle, isRTL),
|
|
41
42
|
series: [
|
|
42
43
|
{
|
|
43
44
|
name: 'Funnel',
|
|
@@ -98,13 +99,14 @@ export default function getFunnelChartOptions(config: FunnelChartConfig) {
|
|
|
98
99
|
confine: true,
|
|
99
100
|
appendToBody: false,
|
|
100
101
|
formatter: function (params: any) {
|
|
102
|
+
const dirAttr = isRTL ? ' dir="rtl"' : ''
|
|
101
103
|
const p = params as any
|
|
102
104
|
const value = p.value
|
|
103
105
|
const percentage = total > 0 ? (value / total) * 100 : 0
|
|
104
106
|
const formatted = isNaN(value) ? value : formatValue(value, 1, true)
|
|
105
107
|
const formattedPercentage = percentage.toFixed(0)
|
|
106
108
|
return `
|
|
107
|
-
<div class="flex items-center justify-between gap-5">
|
|
109
|
+
<div${dirAttr} class="flex items-center justify-between gap-5">
|
|
108
110
|
<div>${p.name}</div>
|
|
109
111
|
<div class="font-bold">
|
|
110
112
|
${formatted} (${formattedPercentage}%)
|
|
@@ -5,6 +5,7 @@ export type AxisChartConfig = {
|
|
|
5
5
|
title: string
|
|
6
6
|
subtitle?: string
|
|
7
7
|
colors?: string[]
|
|
8
|
+
isRTL?: boolean
|
|
8
9
|
xAxis: {
|
|
9
10
|
key: string
|
|
10
11
|
type: 'category' | 'time' | 'value'
|
|
@@ -72,6 +73,7 @@ export type DonutChartConfig = {
|
|
|
72
73
|
title: string
|
|
73
74
|
subtitle?: string
|
|
74
75
|
colors?: string[]
|
|
76
|
+
isRTL?: boolean
|
|
75
77
|
categoryColumn: string
|
|
76
78
|
valueColumn: string
|
|
77
79
|
maxSliceCount?: number
|
|
@@ -86,6 +88,7 @@ export type FunnelChartConfig = {
|
|
|
86
88
|
title: string
|
|
87
89
|
subtitle?: string
|
|
88
90
|
colors?: string[]
|
|
91
|
+
isRTL?: boolean
|
|
89
92
|
categoryColumn: string
|
|
90
93
|
valueColumn: string
|
|
91
94
|
showPercentages?: boolean
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
>
|
|
7
7
|
<div
|
|
8
8
|
:class="[
|
|
9
|
-
'absolute inset-y-0
|
|
9
|
+
'absolute inset-y-0 start-0 flex items-center',
|
|
10
10
|
textColor,
|
|
11
11
|
prefixClasses,
|
|
12
12
|
]"
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
/>
|
|
30
30
|
<div
|
|
31
31
|
:class="[
|
|
32
|
-
'absolute inset-y-0
|
|
32
|
+
'absolute inset-y-0 end-0 flex items-center',
|
|
33
33
|
textColor,
|
|
34
34
|
suffixClasses,
|
|
35
35
|
]"
|
|
@@ -94,23 +94,23 @@ const inputClasses = computed(() => {
|
|
|
94
94
|
let paddingClasses = {
|
|
95
95
|
sm: [
|
|
96
96
|
'py-1.5',
|
|
97
|
-
slots.prefix ? '
|
|
98
|
-
slots.suffix ? '
|
|
97
|
+
slots.prefix ? 'ps-8' : 'ps-2',
|
|
98
|
+
slots.suffix ? 'pe-8' : 'pe-2',
|
|
99
99
|
],
|
|
100
100
|
md: [
|
|
101
101
|
'py-1.5',
|
|
102
|
-
slots.prefix ? '
|
|
103
|
-
slots.suffix ? '
|
|
102
|
+
slots.prefix ? 'ps-9' : 'ps-2.5',
|
|
103
|
+
slots.suffix ? 'pe-9' : 'pe-2.5',
|
|
104
104
|
],
|
|
105
105
|
lg: [
|
|
106
106
|
'py-1.5',
|
|
107
|
-
slots.prefix ? '
|
|
108
|
-
slots.suffix ? '
|
|
107
|
+
slots.prefix ? 'ps-10' : 'ps-3',
|
|
108
|
+
slots.suffix ? 'pe-10' : 'pe-3',
|
|
109
109
|
],
|
|
110
110
|
xl: [
|
|
111
111
|
'py-1.5',
|
|
112
|
-
slots.prefix ? '
|
|
113
|
-
slots.suffix ? '
|
|
112
|
+
slots.prefix ? 'ps-10' : 'ps-3',
|
|
113
|
+
slots.suffix ? 'pe-10' : 'pe-3',
|
|
114
114
|
],
|
|
115
115
|
}[props.size]
|
|
116
116
|
|
|
@@ -140,19 +140,19 @@ const inputClasses = computed(() => {
|
|
|
140
140
|
|
|
141
141
|
let prefixClasses = computed(() => {
|
|
142
142
|
return {
|
|
143
|
-
sm: '
|
|
144
|
-
md: '
|
|
145
|
-
lg: '
|
|
146
|
-
xl: '
|
|
143
|
+
sm: 'ps-2',
|
|
144
|
+
md: 'ps-2.5',
|
|
145
|
+
lg: 'ps-3',
|
|
146
|
+
xl: 'ps-3',
|
|
147
147
|
}[props.size]
|
|
148
148
|
})
|
|
149
149
|
|
|
150
150
|
let suffixClasses = computed(() => {
|
|
151
151
|
return {
|
|
152
|
-
sm: '
|
|
153
|
-
md: '
|
|
154
|
-
lg: '
|
|
155
|
-
xl: '
|
|
152
|
+
sm: 'pe-2',
|
|
153
|
+
md: 'pe-2.5',
|
|
154
|
+
lg: 'pe-3',
|
|
155
|
+
xl: 'pe-3',
|
|
156
156
|
}[props.size]
|
|
157
157
|
})
|
|
158
158
|
|