pgo-ui 1.0.96 → 1.1.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pgo-ui",
3
- "version": "1.0.96",
3
+ "version": "1.1.2",
4
4
  "description": "A Vue 3 component library with PGO design system",
5
5
  "private": false,
6
6
  "type": "module",
@@ -42,7 +42,7 @@
42
42
  "build": "vite build",
43
43
  "preview": "vite preview",
44
44
  "postinstall": "node ./src/copy-assets.cjs",
45
- "release": "npm version patch --no-git-tag-version && npm run build && npm --//registry.npmjs.org/:_authToken=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 publish"
45
+ "release": "npm version patch --no-git-tag-version && npm run build && npm --//registry.npmjs.org/:_authToken=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 publish"
46
46
  },
47
47
  "dependencies": {
48
48
  "@heroicons/vue": "^2.2.0",
@@ -59,14 +59,12 @@
59
59
  "@vuepic/vue-datepicker": "^12.1.0",
60
60
  "@vueuse/components": "^14.0.0",
61
61
  "@vueuse/core": "^14.0.0",
62
- "apexcharts": "^5.10.6",
63
62
  "axios": "^1.13.2",
64
63
  "core-js": "^3.49.0",
65
64
  "date-fns": "^4.1.0",
66
65
  "pdfjs-dist": "^5.5.207",
67
66
  "vue": "^3.0.0",
68
67
  "vue-pdf-embed": "^2.1.4",
69
- "vue3-apexcharts": "^1.11.1",
70
68
  "vue3-tailwind-components": "^0.3.3"
71
69
  },
72
70
  "devDependencies": {
@@ -0,0 +1,66 @@
1
+ <template>
2
+ <div class="space-y-4">
3
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
4
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
5
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Default</p>
6
+ <DonutChart
7
+ :series="[
8
+ { label: 'Approved', value: 120 },
9
+ { label: 'Pending', value: 45 },
10
+ { label: 'Rejected', value: 10 }
11
+ ]"
12
+ :height="280"
13
+ />
14
+ </div>
15
+
16
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
17
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Custom Colors + Bilingual Labels</p>
18
+ <DonutChart
19
+ :series="[
20
+ { label: { en: 'Letters Replied', dv: 'ޖަވާބު ލިބިފައިވާ ސިޓީ' }, value: 60 },
21
+ { label: { en: 'Letters Submitted', dv: 'ހުށަހަޅާފައިވާ ސިޓީ' }, value: 1344 },
22
+ { label: { en: 'Letters Received', dv: 'ހުށަހެޅުނު ސިޓީ' }, value: 80 }
23
+ ]"
24
+ :colors="['#10B981', '#3B82F6', '#F59E0B']"
25
+ :total-label="{ en: 'Total', dv: 'ޖުމްލަ' }"
26
+ :height="280"
27
+ />
28
+ </div>
29
+ </div>
30
+
31
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
32
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
33
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">No Legend, No Total</p>
34
+ <DonutChart
35
+ :series="[
36
+ { label: 'A', value: 30 },
37
+ { label: 'B', value: 70 }
38
+ ]"
39
+ :show-legend="false"
40
+ :show-total="false"
41
+ donut-size="70%"
42
+ :height="200"
43
+ />
44
+ </div>
45
+
46
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
47
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">No Data Labels</p>
48
+ <DonutChart
49
+ :series="[
50
+ { label: 'Category 1', value: 40 },
51
+ { label: 'Category 2', value: 25 },
52
+ { label: 'Category 3', value: 35 },
53
+ { label: 'Category 4', value: 15 }
54
+ ]"
55
+ :colors="['#8B5CF6', '#EC4899', '#14B8A6', '#F97316']"
56
+ :show-data-labels="false"
57
+ :height="200"
58
+ />
59
+ </div>
60
+ </div>
61
+ </div>
62
+ </template>
63
+
64
+ <script setup>
65
+ import { DonutChart } from '../pgo'
66
+ </script>
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div class="space-y-4">
3
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
4
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
5
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Default (Smooth Curves)</p>
6
+ <LineChart
7
+ :series="[
8
+ { name: 'Revenue', data: [30, 40, 35, 50, 49, 60] },
9
+ { name: 'Expenses', data: [20, 30, 25, 40, 30, 45] }
10
+ ]"
11
+ :categories="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']"
12
+ :height="280"
13
+ />
14
+ </div>
15
+
16
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
17
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Straight Lines + Data Labels</p>
18
+ <LineChart
19
+ :series="[
20
+ { name: 'Users', data: [100, 150, 200, 180, 250, 300] }
21
+ ]"
22
+ :categories="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']"
23
+ :colors="['#8B5CF6']"
24
+ :curved="false"
25
+ :show-data-labels="true"
26
+ :height="280"
27
+ />
28
+ </div>
29
+ </div>
30
+
31
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
32
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
33
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Bilingual Labels</p>
34
+ <LineChart
35
+ :series="[
36
+ { name: { en: 'Letters', dv: 'ސިޓީ' }, data: [40, 55, 70, 48, 90, 60] },
37
+ { name: { en: 'Cases', dv: 'މައްސަލަ' }, data: [20, 35, 25, 50, 45, 65] }
38
+ ]"
39
+ :categories="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']"
40
+ :colors="['#3B82F6', '#10B981']"
41
+ :height="280"
42
+ />
43
+ </div>
44
+
45
+ <div class="border border-[var(--vts-color-border)] rounded-lg p-4">
46
+ <p class="text-xs font-semibold text-[var(--vts-color-textSecondary)] uppercase tracking-wider mb-2">Custom Stroke + No Legend</p>
47
+ <LineChart
48
+ :series="[
49
+ { name: 'Temperature', data: [28, 30, 32, 31, 33, 35, 34] }
50
+ ]"
51
+ :categories="['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']"
52
+ :colors="['#EF4444']"
53
+ :stroke-width="5"
54
+ :show-legend="false"
55
+ :height="200"
56
+ />
57
+ </div>
58
+ </div>
59
+ </div>
60
+ </template>
61
+
62
+ <script setup>
63
+ import { LineChart } from '../pgo'
64
+ </script>
@@ -28,6 +28,8 @@ import TimelineExample from './TimelineExample.vue'
28
28
  import TooltipExample from './TooltipExample.vue'
29
29
  import VueDatePickerShowcase from './VueDatePickerShowcase.vue'
30
30
  import CardViewExample from './CardViewExample.vue'
31
+ import DonutChartExample from './DonutChartExample.vue'
32
+ import LineChartExample from './LineChartExample.vue'
31
33
 
32
34
  export {
33
35
  AppBarExample,
@@ -57,6 +59,8 @@ export {
57
59
  TimelineExample,
58
60
  TooltipExample,
59
61
  VueDatePickerShowcase,
60
- CardViewExample
62
+ CardViewExample,
63
+ DonutChartExample,
64
+ LineChartExample
61
65
 
62
66
  }
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <VueApexCharts
3
+ v-if="ready"
3
4
  type="donut"
4
5
  :options="chartOptions"
5
6
  :series="chartSeries"
@@ -8,9 +9,17 @@
8
9
  </template>
9
10
 
10
11
  <script setup>
11
- import { computed, inject } from 'vue'
12
+ import { computed, inject, ref, onMounted } from 'vue'
12
13
  import VueApexCharts from 'vue3-apexcharts'
13
14
 
15
+ const ready = ref(false)
16
+
17
+ onMounted(() => {
18
+ requestAnimationFrame(() => {
19
+ ready.value = true
20
+ })
21
+ })
22
+
14
23
  const i18n = inject('i18n', null)
15
24
 
16
25
  const defaultColors = ['#10B981', '#3B82F6', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899', '#14B8A6', '#F97316']
@@ -1,5 +1,6 @@
1
1
  <template>
2
2
  <VueApexCharts
3
+ v-if="ready"
3
4
  type="line"
4
5
  :options="chartOptions"
5
6
  :series="chartSeries"
@@ -8,9 +9,17 @@
8
9
  </template>
9
10
 
10
11
  <script setup>
11
- import { computed, inject } from 'vue'
12
+ import { computed, inject, ref, onMounted } from 'vue'
12
13
  import VueApexCharts from 'vue3-apexcharts'
13
14
 
15
+ const ready = ref(false)
16
+
17
+ onMounted(() => {
18
+ requestAnimationFrame(() => {
19
+ ready.value = true
20
+ })
21
+ })
22
+
14
23
  const i18n = inject('i18n', null)
15
24
 
16
25
  const defaultColors = ['#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899', '#14B8A6', '#F97316']
@@ -594,37 +594,76 @@ const initializeFormData = () => {
594
594
 
595
595
  try {
596
596
  // Build safe variable declarations instead of using function parameters
597
- const varDeclarations = Object.keys(context)
598
- .filter(key => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key)) // only valid JS identifiers
599
- .map(key => {
600
- const value = context[key];
601
- if (value === null || value === undefined) {
602
- return `var ${key} = ${JSON.stringify(null)};`;
603
- } else if (typeof value === 'function') {
604
- return ''; // skip functions
597
+ const functionKeys = []
598
+ const functionValues = []
599
+ const varDeclarations = []
600
+
601
+ Object.keys(context)
602
+ .filter(key => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key))
603
+ .forEach(key => {
604
+ const value = context[key]
605
+
606
+ if (typeof value === 'function') {
607
+ // Pass functions as parameters
608
+ functionKeys.push(key)
609
+ functionValues.push(value)
610
+ } else if (value === null || value === undefined) {
611
+ varDeclarations.push(`var ${key} = null;`)
605
612
  } else if (typeof value === 'object') {
606
613
  try {
607
- return `var ${key} = ${JSON.stringify(value)};`;
614
+ varDeclarations.push(`var ${key} = ${JSON.stringify(value)};`)
608
615
  } catch {
609
- return `var ${key} = null;`; // skip non-serializable objects
616
+ varDeclarations.push(`var ${key} = null;`)
610
617
  }
611
618
  } else if (typeof value === 'string') {
612
- return `var ${key} = ${JSON.stringify(value)};`;
619
+ varDeclarations.push(`var ${key} = ${JSON.stringify(value)};`)
613
620
  } else {
614
- return `var ${key} = ${value};`;
621
+ varDeclarations.push(`var ${key} = ${value};`)
615
622
  }
616
623
  })
617
- .filter(Boolean)
618
- .join('\n');
619
624
 
620
- const fn = new Function(varDeclarations + `\nreturn (${expression});`);
621
- return fn();
625
+ const body = varDeclarations.join('\n') + `\nreturn (${expression});`
626
+ const fn = new Function(...functionKeys, body)
627
+ return fn(...functionValues)
622
628
  } catch (error) {
623
- console.warn('Error evaluating expression:', expression, error.message);
624
- return false;
629
+ console.warn('Error evaluating expression:', expression, error.message)
630
+ return false
625
631
  }
626
632
  };
627
633
 
634
+ const safeEval = (expression, context) => {
635
+ const functionKeys = []
636
+ const functionValues = []
637
+ const varDeclarations = []
638
+
639
+ Object.keys(context)
640
+ .filter(key => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key))
641
+ .forEach(key => {
642
+ const value = context[key]
643
+
644
+ if (typeof value === 'function') {
645
+ functionKeys.push(key)
646
+ functionValues.push(value)
647
+ } else if (value === null || value === undefined) {
648
+ varDeclarations.push(`var ${key} = null;`)
649
+ } else if (typeof value === 'object') {
650
+ try {
651
+ varDeclarations.push(`var ${key} = ${JSON.stringify(value)};`)
652
+ } catch {
653
+ varDeclarations.push(`var ${key} = null;`)
654
+ }
655
+ } else if (typeof value === 'string') {
656
+ varDeclarations.push(`var ${key} = ${JSON.stringify(value)};`)
657
+ } else {
658
+ varDeclarations.push(`var ${key} = ${value};`)
659
+ }
660
+ })
661
+
662
+ const body = varDeclarations.join('\n') + `\n${expression}`
663
+ const fn = new Function(...functionKeys, body)
664
+ return fn(...functionValues)
665
+ }
666
+
628
667
  // Simplified getFieldProps function
629
668
  const getFieldProps = (field) => {
630
669
  if (!field) {
@@ -240,6 +240,8 @@ import {
240
240
  TooltipExample,
241
241
  VueDatePickerShowcase,
242
242
  CardViewExample,
243
+ DonutChartExample,
244
+ LineChartExample,
243
245
  } from '@/components/examples/index.ts'
244
246
 
245
247
  // ─── Example component map (index → component) ────────────────────────────
@@ -271,6 +273,8 @@ const exampleMap = [
271
273
  TooltipExample, // 24
272
274
  VueDatePickerShowcase, // 25
273
275
  CardViewExample, // 26
276
+ DonutChartExample, // 27
277
+ LineChartExample, // 28
274
278
  ]
275
279
 
276
280
  // ─── Category definitions with colour tokens ──────────────────────────────
@@ -361,6 +365,18 @@ const categories = [
361
365
  { name: 'CardView', index: 26 },
362
366
  ],
363
367
  },
368
+ {
369
+ name: 'Charts',
370
+ dotClass: 'bg-orange-500',
371
+ textClass: 'text-orange-500',
372
+ activeClass: 'bg-orange-500/10 text-orange-600 font-semibold',
373
+ gradientClass: 'bg-gradient-to-r from-orange-400 to-amber-500',
374
+ badgeClass: 'text-orange-600 border-orange-300 bg-orange-50',
375
+ items: [
376
+ { name: 'DonutChart', index: 27 },
377
+ { name: 'LineChart', index: 28 },
378
+ ],
379
+ },
364
380
  {
365
381
  name: 'Utilities',
366
382
  dotClass: 'bg-slate-400',
@@ -1423,6 +1439,66 @@ const docs = [
1423
1439
  slots: [],
1424
1440
  },
1425
1441
 
1442
+ // ── 27 · DonutChart ─────────────────────────
1443
+ {
1444
+ name: 'DonutChart',
1445
+ description: 'ApexCharts-powered donut chart with bilingual labels, configurable colors, center total, and legend. Wraps vue3-apexcharts internally — no extra install needed.',
1446
+ usage:
1447
+ `<DonutChart
1448
+ :series="[
1449
+ { label: { en: 'Approved', dv: 'ފާސް' }, value: 120 },
1450
+ { label: { en: 'Pending', dv: 'ނުނިމި' }, value: 45 },
1451
+ { label: { en: 'Rejected', dv: 'ބޭރު' }, value: 10 }
1452
+ ]"
1453
+ :colors="['#10B981', '#F59E0B', '#EF4444']"
1454
+ :total-label="{ en: 'Total', dv: 'ޖުމްލަ' }"
1455
+ :height="350"
1456
+ />`,
1457
+ props: [
1458
+ { name: 'series', type: 'Array', default: 'required', description: 'Data items: [{ label: string | {en,dv}, value: number }].' },
1459
+ { name: 'colors', type: 'Array', default: 'built-in palette', description: 'Hex color strings per slice.' },
1460
+ { name: 'height', type: 'String|Number', default: '350', description: 'Chart height in pixels.' },
1461
+ { name: 'showLegend', type: 'Boolean', default: 'true', description: 'Show/hide the bottom legend.' },
1462
+ { name: 'showDataLabels', type: 'Boolean', default: 'true', description: 'Show percentage labels on slices.' },
1463
+ { name: 'donutSize', type: 'String', default: "'55%'", description: 'Inner donut hole size.' },
1464
+ { name: 'showTotal', type: 'Boolean', default: 'true', description: 'Show total value in center.' },
1465
+ { name: 'totalLabel', type: 'String|Object', default: "{en:'Total',dv:'ޖުމްލަ'}", description: 'Center label text (bilingual).' },
1466
+ { name: 'lang', type: 'String', default: 'injected', description: 'Language override (reads from i18n if omitted).' },
1467
+ ],
1468
+ events: [],
1469
+ slots: [],
1470
+ },
1471
+
1472
+ // ── 28 · LineChart ──────────────────────────
1473
+ {
1474
+ name: 'LineChart',
1475
+ description: 'ApexCharts-powered line chart with bilingual series names, smooth/straight curves, configurable stroke, and responsive layout.',
1476
+ usage:
1477
+ `<LineChart
1478
+ :series="[
1479
+ { name: { en: 'Revenue', dv: 'އާމްދަނީ' }, data: [30, 40, 35, 50, 49, 60] },
1480
+ { name: { en: 'Expenses', dv: 'ޚަރަދު' }, data: [20, 30, 25, 40, 30, 45] }
1481
+ ]"
1482
+ :categories="['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']"
1483
+ :colors="['#3B82F6', '#EF4444']"
1484
+ :curved="true"
1485
+ :height="350"
1486
+ />`,
1487
+ props: [
1488
+ { name: 'series', type: 'Array', default: 'required', description: 'Line data: [{ name: string | {en,dv}, data: number[] }].' },
1489
+ { name: 'categories', type: 'Array', default: '[]', description: 'X-axis labels.' },
1490
+ { name: 'colors', type: 'Array', default: 'built-in palette', description: 'Color per line.' },
1491
+ { name: 'height', type: 'String|Number', default: '350', description: 'Chart height in pixels.' },
1492
+ { name: 'showLegend', type: 'Boolean', default: 'true', description: 'Show/hide the legend.' },
1493
+ { name: 'showDataLabels', type: 'Boolean', default: 'false', description: 'Show value labels on data points.' },
1494
+ { name: 'curved', type: 'Boolean', default: 'true', description: 'Smooth curves (true) or straight lines (false).' },
1495
+ { name: 'strokeWidth', type: 'Number', default: '3', description: 'Line thickness in pixels.' },
1496
+ { name: 'lang', type: 'String', default: 'injected', description: 'Language override (reads from i18n if omitted).' },
1497
+ ],
1498
+ events: [],
1499
+ slots: [],
1500
+ },
1501
+
1426
1502
  ]
1427
1503
  </script>
1428
1504
 
@@ -1,4 +0,0 @@
1
- import { _ as f } from "./index-ZWMgoNTb.js";
2
- export {
3
- f as default
4
- };