@gkucmierz/nano-ui 1.2.1 → 1.4.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.
package/README.md CHANGED
@@ -51,6 +51,60 @@ A highly optimized material-style ripple effect directive.
51
51
  </style>
52
52
  ```
53
53
 
54
+ ### 📊 `ThreeDDonutChart` Component
55
+
56
+ A premium, highly interactive 3D SVG Donut and Pie Chart component for Vue 3. Features smooth morphing animations, dynamic 2D/3D perspective transitions, responsive side-label columns with callout leader lines, auto-rotation label balancing, and slice selection locking.
57
+
58
+ #### Code Example
59
+ ```vue
60
+ <template>
61
+ <div class="chart-container">
62
+ <ThreeDDonutChart
63
+ v-model:selectedItemId="selectedId"
64
+ :data="chartData"
65
+ :isExpanded="true"
66
+ :showLabels="true"
67
+ :is3D="true"
68
+ :slopeRatio="0.55"
69
+ :autoRotate="true"
70
+ :selectable="true"
71
+ valueDecimals="2"
72
+ centerLabel="Total Value"
73
+ />
74
+ </div>
75
+ </template>
76
+
77
+ <script setup>
78
+ import { ref } from 'vue';
79
+ import { ThreeDDonutChart } from '@gkucmierz/nano-ui';
80
+
81
+ const selectedId = ref(null);
82
+ const chartData = ref([
83
+ { id: '1', name: 'Product A', value: 120, color: '#3b82f6', unit: 'USD' },
84
+ { id: '2', name: 'Product B', value: 85, color: '#10b981', unit: 'USD' },
85
+ { id: '3', name: 'Product C', value: 45, color: '#a855f7', unit: 'USD' }
86
+ ]);
87
+ </script>
88
+ ```
89
+
90
+ #### Component API (Props)
91
+ | Prop | Type | Default | Description |
92
+ |---|---|---|---|
93
+ | `data` | `Array` | *Required* | Array of objects: `{ id, name, value, color, unit }`. |
94
+ | `isExpanded` | `Boolean` | `false` | Large container layout with margins for labels (`true`) or compact `120x120px` mini layout (`false`). |
95
+ | `showLabels` | `Boolean` | `true` | Show/hide side callouts and leader lines (applicable when `isExpanded` is true). |
96
+ | `is3D` | `Boolean` | `true` | Enables 3D perspective rendering (depth and tilt). When false, renders in flat 2D. |
97
+ | `slopeRatio` | `Number` | `0.5` | Vertical tilt factor of the 3D plane (from `0.2` to `1.0`). |
98
+ | `rotationAngle` | `Number` | `-90` | Starting rotation angle of the chart in degrees. |
99
+ | `autoRotate` | `Boolean` | `false` | Dynamically optimizes rotation to distribute side-labels evenly. |
100
+ | `selectable` | `Boolean` | `false` | Enables slice selection/locking on click or tap. |
101
+ | `selectedItemId` | `String \| Number` | `null` | The ID of the currently locked slice (supports `v-model:selectedItemId`). |
102
+ | `centerValue` | `String \| Number` | `''` | Value displayed inside the donut hole (defaults to sum of all items). |
103
+ | `centerLabel` | `String` | `''` | Sub-label text displayed below the center value. |
104
+ | `valueDecimals` | `Number` | `undefined` | Decimals to round slice values to on label callouts. |
105
+ | `aggregateOthers` | `Boolean` | `false` | Merges small items below a threshold into an "Other" slice. |
106
+ | `othersThreshold`| `Number` | `0.01` | Fraction threshold (e.g. `0.05` for 5%) below which items are aggregated. |
107
+
54
108
  ## 📜 License
55
109
 
56
110
  MIT License
package/dist/nano-ui.css CHANGED
@@ -1,2 +1,2 @@
1
- .global-tooltip[data-v-37c91a21]{--nu-tooltip-bg:#0f172af2;--nu-tooltip-color:#f8fafc;--nu-tooltip-radius:8px;--nu-tooltip-padding:8px 14px;--nu-tooltip-shadow:0 8px 24px #0000004d;--nu-tooltip-border:1px solid #ffffff1a;--nu-tooltip-arrow-border:#ffffff1a;z-index:99999;background:var(--nu-tooltip-bg);-webkit-backdrop-filter:blur(8px);color:var(--nu-tooltip-color);padding:var(--nu-tooltip-padding);border-radius:var(--nu-tooltip-radius);text-align:center;white-space:normal;word-wrap:break-word;pointer-events:none;width:max-content;max-width:min(350px,100vw - 32px);box-shadow:var(--nu-tooltip-shadow);border:var(--nu-tooltip-border);opacity:0;visibility:hidden;font-size:.85rem;font-weight:500;line-height:1.4;transition:opacity .2s cubic-bezier(.16,1,.3,1),transform .2s cubic-bezier(.16,1,.3,1);position:fixed;top:0;left:0;transform:translateY(4px)scale(.95)}.global-tooltip[data-v-37c91a21]:after{content:"";left:calc(50% + var(--arrow-offset,0px));background:var(--nu-tooltip-bg);-webkit-backdrop-filter:blur(8px);border-right:1px solid var(--nu-tooltip-arrow-border);border-bottom:1px solid var(--nu-tooltip-arrow-border);clip-path:polygon(100% 0,100% 100%,0 100%);border-radius:0 0 2px;width:10px;height:10px;margin-left:-5px;position:absolute;bottom:-5px;transform:rotate(45deg)}.global-tooltip.tooltip-bottom[data-v-37c91a21]:after{border-bottom:none;border-right:none;border-left:1px solid var(--nu-tooltip-arrow-border);border-top:1px solid var(--nu-tooltip-arrow-border);clip-path:polygon(0 0,100% 0,0 100%);border-radius:2px 0 0;top:-5px;bottom:auto}.global-tooltip.visible[data-v-37c91a21]{opacity:1;visibility:visible}span.ripple{background-color:var(--nano-ripple-color,#fff6);pointer-events:none;border-radius:50%;animation:.6s linear nano-ripple-anim;position:absolute;transform:scale(0)}@keyframes nano-ripple-anim{to{opacity:0;transform:scale(4)}}
1
+ .global-tooltip[data-v-37c91a21]{--nu-tooltip-bg:#0f172af2;--nu-tooltip-color:#f8fafc;--nu-tooltip-radius:8px;--nu-tooltip-padding:8px 14px;--nu-tooltip-shadow:0 8px 24px #0000004d;--nu-tooltip-border:1px solid #ffffff1a;--nu-tooltip-arrow-border:#ffffff1a;z-index:99999;background:var(--nu-tooltip-bg);-webkit-backdrop-filter:blur(8px);color:var(--nu-tooltip-color);padding:var(--nu-tooltip-padding);border-radius:var(--nu-tooltip-radius);text-align:center;white-space:normal;word-wrap:break-word;pointer-events:none;width:max-content;max-width:min(350px,100vw - 32px);box-shadow:var(--nu-tooltip-shadow);border:var(--nu-tooltip-border);opacity:0;visibility:hidden;font-size:.85rem;font-weight:500;line-height:1.4;transition:opacity .2s cubic-bezier(.16,1,.3,1),transform .2s cubic-bezier(.16,1,.3,1);position:fixed;top:0;left:0;transform:translateY(4px)scale(.95)}.global-tooltip[data-v-37c91a21]:after{content:"";left:calc(50% + var(--arrow-offset,0px));background:var(--nu-tooltip-bg);-webkit-backdrop-filter:blur(8px);border-right:1px solid var(--nu-tooltip-arrow-border);border-bottom:1px solid var(--nu-tooltip-arrow-border);clip-path:polygon(100% 0,100% 100%,0 100%);border-radius:0 0 2px;width:10px;height:10px;margin-left:-5px;position:absolute;bottom:-5px;transform:rotate(45deg)}.global-tooltip.tooltip-bottom[data-v-37c91a21]:after{border-bottom:none;border-right:none;border-left:1px solid var(--nu-tooltip-arrow-border);border-top:1px solid var(--nu-tooltip-arrow-border);clip-path:polygon(0 0,100% 0,0 100%);border-radius:2px 0 0;top:-5px;bottom:auto}.global-tooltip.visible[data-v-37c91a21]{opacity:1;visibility:visible}:root{--nano-modal-bg:#1e1e24;--nano-modal-glass-bg:#1e1e24d9;--nano-modal-border:#ffffff1a;--nano-modal-text:#fff;--nano-modal-text-muted:#a0a0a0;--nano-modal-backdrop:#0009;--nano-modal-radius:12px;--nano-btn-primary:#3498db;--nano-btn-primary-hover:#2980b9;--nano-btn-secondary:#34495e;--nano-btn-secondary-hover:#2c3e50}.nano-modal-overlay{z-index:99999;background:var(--nano-modal-backdrop);box-sizing:border-box;outline:none;justify-content:center;align-items:center;width:100vw;height:100vh;padding:20px;display:flex;position:fixed;top:0;left:0}.nano-modal-overlay.nano-glass{-webkit-backdrop-filter:blur(8px)}.nano-modal-window{background:var(--nano-modal-bg);border:1px solid var(--nano-modal-border);border-radius:var(--nano-modal-radius);max-height:90vh;color:var(--nano-modal-text);flex-direction:column;display:flex;position:relative;box-shadow:0 24px 48px #00000080}.nano-modal-window:not([style*="position: absolute"]){margin:auto}.nano-glass .nano-modal-window{background:var(--nano-modal-glass-bg);-webkit-backdrop-filter:blur(16px)}.nano-modal-header{border-bottom:1px solid var(--nano-modal-border);-webkit-user-select:none;user-select:none;background:#0003;justify-content:space-between;align-items:center;padding:16px 24px;display:flex}.nano-modal-header.is-draggable{cursor:grab}.nano-modal-header.is-draggable:active{cursor:grabbing}.nano-modal-title{margin:0;font-size:1.25rem;font-weight:600;line-height:1.4}.nano-modal-close-btn{color:var(--nano-modal-text-muted);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:4px;transition:all .2s;display:flex}.nano-modal-close-btn:hover{color:var(--nano-modal-text);background:#ffffff1a}.nano-modal-body{flex:1;padding:24px;overflow-y:auto}.nano-modal-footer{border-top:1px solid var(--nano-modal-border);background:#00000026;justify-content:flex-end;padding:16px 24px;display:flex}.nano-modal-actions{gap:12px;display:flex}.nano-btn{cursor:pointer;color:#fff;border:none;border-radius:6px;padding:8px 16px;font-size:.95rem;font-weight:600;transition:all .2s}.nano-btn-primary{background:var(--nano-btn-primary)}.nano-btn-primary:hover{background:var(--nano-btn-primary-hover)}.nano-btn-secondary{background:var(--nano-btn-secondary)}.nano-btn-secondary:hover{background:var(--nano-btn-secondary-hover)}.nano-modal-resizer{cursor:se-resize;width:16px;height:16px;color:var(--nano-modal-text-muted);z-index:10;justify-content:center;align-items:center;transition:color .2s;display:flex;position:absolute;bottom:4px;right:4px}.nano-modal-resizer:hover{color:var(--nano-modal-text)}.nano-modal-fade-enter-active,.nano-modal-fade-leave-active{transition:opacity .25s}.nano-modal-fade-enter-active .nano-modal-window{transition:transform .3s cubic-bezier(.175,.885,.32,1.275)}.nano-modal-fade-leave-active .nano-modal-window{transition:transform .2s ease-in}.nano-modal-fade-enter-from,.nano-modal-fade-leave-to{opacity:0}.nano-modal-fade-enter-from .nano-modal-window{transform:scale(.9)translateY(10px)}.nano-modal-fade-leave-to .nano-modal-window{transform:scale(.95)translateY(-10px)}.donut-canvas-wrapper[data-v-fcf8b2a7]{flex-shrink:0;justify-content:center;align-items:center;width:120px;height:120px;transition:width .45s cubic-bezier(.25,1,.5,1),height .45s cubic-bezier(.25,1,.5,1);display:flex;position:relative}.donut-canvas-wrapper.is-expanded[data-v-fcf8b2a7]{width:100%;max-width:760px;height:320px}@media (width<=760px){.donut-canvas-wrapper.is-expanded[data-v-fcf8b2a7]{height:42vw}}.items-svg-chart[data-v-fcf8b2a7]{width:100%;height:100%;display:block;overflow:visible}.slice-group-3d[data-v-fcf8b2a7]{cursor:pointer;transition:transform .25s cubic-bezier(.25,1,.5,1),opacity .25s}.slice-group-3d.is-dimmed[data-v-fcf8b2a7]{opacity:.35}.label-group[data-v-fcf8b2a7]{transition:opacity .25s}.label-group path[data-v-fcf8b2a7]{transition:d .25s cubic-bezier(.25,1,.5,1),stroke-width .2s,opacity .2s}.label-group text[data-v-fcf8b2a7]{transition:transform .25s cubic-bezier(.25,1,.5,1),font-weight .2s,opacity .2s}.label-group.is-hovered path[data-v-fcf8b2a7]{stroke-width:2.2px}.label-group.is-hovered text[data-v-fcf8b2a7]{font-weight:700}.label-group.is-dimmed[data-v-fcf8b2a7]{opacity:.25}.no-transitions .label-group[data-v-fcf8b2a7],.no-transitions .label-group path[data-v-fcf8b2a7],.no-transitions .label-group text[data-v-fcf8b2a7],.no-transitions .slice-group-3d[data-v-fcf8b2a7]{transition:none!important}.center-text-value[data-v-fcf8b2a7]{fill:#fff;filter:drop-shadow(0 0 3px #000c)}.center-text-label[data-v-fcf8b2a7]{fill:#94a3b8;filter:drop-shadow(0 0 2px #000c)}:root[data-theme=light] .center-text-value[data-v-fcf8b2a7]{fill:#0f172a;filter:drop-shadow(0 0 3px #ffffffe6)}:root[data-theme=light] .center-text-label[data-v-fcf8b2a7]{fill:#475569;filter:drop-shadow(0 0 2px #ffffffe6)}span.ripple{background-color:var(--nano-ripple-color,#fff6);pointer-events:none;border-radius:50%;animation:.6s linear nano-ripple-anim;position:absolute;transform:scale(0)}@keyframes nano-ripple-anim{to{opacity:0;transform:scale(4)}}
2
2
  /*$vite$:1*/