@gkucmierz/nano-ui 1.6.0 β 1.7.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/README.md +383 -38
- package/dist/nano-ui-512.png +0 -0
- package/dist/nano-ui-dark.svg +54 -0
- package/dist/nano-ui.css +1 -1
- package/dist/nano-ui.js +629 -210
- package/dist/nano-ui.svg +89 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -1,8 +1,37 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<img src="https://nano-ui.7u.pl/nano-ui.svg" width="120" height="120" alt="Nano UI Logo" />
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# @gkucmierz/nano-ui
|
|
6
|
+
|
|
7
|
+
**High-performance, minimal-footprint Vue 3 UI library, interactive 3D charts, and directives.**
|
|
8
|
+
Engineered for glassmorphism aesthetics, continuous Hermite kinematics, and zero-FOUC offline-first applications.
|
|
9
|
+
|
|
10
|
+
[](https://www.npmjs.com/package/@gkucmierz/nano-ui)
|
|
11
|
+
[](LICENSE)
|
|
12
|
+
[](https://vuejs.org/)
|
|
13
|
+
[](src/locales/)
|
|
14
|
+
[](#zero-fouc-architecture)
|
|
15
|
+
[](#zero-trust-offline-first)
|
|
16
|
+
|
|
17
|
+
π **[Live Interactive Playground & Documentation](https://nano-ui.7u.pl)**
|
|
18
|
+
|
|
19
|
+
</div>
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## π Key Highlights
|
|
24
|
+
|
|
25
|
+
- β‘ **Continuous Hermite Kinematics (`KineticRotator`):** Velocity-preserving $C^1$ continuity on interrupts, geodesic shortest-path interpolation, and dynamic momentum preservation.
|
|
26
|
+
- ποΈ **Multi-Resolution DAW Scrubber (`PrecisionScrubber`):** Vertical-distance 2D precision scaling (1x → 0.1x → 0.01x → 0.001x) with floating HUD overlay.
|
|
27
|
+
- π **Morphing Sticky Navigation (`MutatingHeader`):** Transitions smoothly between a floating glassmorphism card and an edge-to-edge docked navbar with configurable hysteresis.
|
|
28
|
+
- π **3D SVG Data Visualizations (`ThreeDDonutChart`):** Interactive 3D perspective donut & pie charts with auto-balancing side callouts, depth slope ratio, and slice locking.
|
|
29
|
+
- ποΈ **Accessible Glass Controls (`NanoSwitch`, `NanoModal`):** Lightweight toggle switches and hash-routed modals with universal dismissal triad (ESC, backdrop click, header close).
|
|
30
|
+
- π§ **Optimized Micro-Directives (`v-ripple`, `v-tooltip`):** Material ripples and GPU-accelerated tooltips with minimal runtime overhead.
|
|
31
|
+
- π **Zero-Dependency i18n:** Built-in reactive English/Polish localization engine featuring line-correlated translation dictionaries.
|
|
32
|
+
- π‘οΈ **Zero-Trust Offline-First:** Zero external runtime CDNs (`esm.sh`, `unpkg`, `cdnjs`) — 100% bundled locally for offline PWA reliability.
|
|
33
|
+
|
|
34
|
+
---
|
|
6
35
|
|
|
7
36
|
## π¦ Installation
|
|
8
37
|
|
|
@@ -10,17 +39,19 @@ High-performance, minimal footprint Vue 3 UI library and directives designed for
|
|
|
10
39
|
npm install @gkucmierz/nano-ui
|
|
11
40
|
```
|
|
12
41
|
|
|
13
|
-
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## π οΈ Quick Start
|
|
14
45
|
|
|
15
|
-
### Global
|
|
46
|
+
### Global Registration
|
|
16
47
|
|
|
17
|
-
|
|
48
|
+
Register Nano UI and its core design tokens globally in your Vue 3 application:
|
|
18
49
|
|
|
19
50
|
```javascript
|
|
20
51
|
import { createApp } from 'vue';
|
|
21
52
|
import App from './App.vue';
|
|
22
53
|
import NanoUI from '@gkucmierz/nano-ui';
|
|
23
|
-
import '@gkucmierz/nano-ui/style.css'; //
|
|
54
|
+
import '@gkucmierz/nano-ui/style.css'; // Core design tokens, animations, and typography
|
|
24
55
|
|
|
25
56
|
const app = createApp(App);
|
|
26
57
|
|
|
@@ -28,34 +59,228 @@ app.use(NanoUI);
|
|
|
28
59
|
app.mount('#app');
|
|
29
60
|
```
|
|
30
61
|
|
|
31
|
-
###
|
|
62
|
+
### Individual Component Import
|
|
63
|
+
|
|
64
|
+
You can also import individual components and directives on demand:
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
import {
|
|
68
|
+
KineticRotator,
|
|
69
|
+
MutatingHeader,
|
|
70
|
+
PrecisionScrubber,
|
|
71
|
+
NanoSwitch,
|
|
72
|
+
ThreeDDonutChart,
|
|
73
|
+
NanoModal,
|
|
74
|
+
Ripple,
|
|
75
|
+
tooltipDirective
|
|
76
|
+
} from '@gkucmierz/nano-ui';
|
|
77
|
+
import '@gkucmierz/nano-ui/style.css';
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## π§© Component Catalog & API
|
|
83
|
+
|
|
84
|
+
### π `KineticRotator`
|
|
85
|
+
|
|
86
|
+
A high-performance angular rotator component powered by Cubic Hermite spline kinematics. Unlike standard CSS transitions which snap or restart upon target changes, `KineticRotator` samples the instantaneous angular velocity ($v_0$) at the moment of interruption, guaranteeing $C^1$ velocity continuity and zero jarring visual jerks.
|
|
32
87
|
|
|
33
|
-
|
|
88
|
+
#### Features
|
|
89
|
+
- **Continuous Velocity Preservation ($C^1$ Continuity):** Seamless retargeting mid-flight with boundary conditions $P(0) = 0$, $P'(0) = v_0$, $P(1) = 1$, $P'(1) = 0$.
|
|
90
|
+
- **Geodesic Shortest-Path Navigation:** Modulo $360^\circ$ difference wrapping minimizes rotational distance while preserving rotational momentum.
|
|
91
|
+
- **Dynamic Timing Modes:**
|
|
92
|
+
- `proportional` *(Isokinetic, $v \approx \text{const}$)*: Duration scales proportionally with angular displacement ($|\Delta\theta|$).
|
|
93
|
+
- `fixed` *(Isochronous, $T = \text{const}$)*: Duration is constant regardless of angle distance.
|
|
94
|
+
- **In-Flight Duration Adaptation:** Dynamically updates duration without spatial jumps on the normalized time axis.
|
|
34
95
|
|
|
96
|
+
#### Code Example
|
|
35
97
|
```vue
|
|
36
98
|
<template>
|
|
37
|
-
|
|
38
|
-
|
|
99
|
+
<div class="rotator-container">
|
|
100
|
+
<KineticRotator
|
|
101
|
+
ref="rotatorRef"
|
|
102
|
+
v-model="angle"
|
|
103
|
+
:duration="1000"
|
|
104
|
+
:speed-multiplier="1"
|
|
105
|
+
timing-mode="proportional"
|
|
106
|
+
:shortest-path="true"
|
|
107
|
+
:inertia-threshold="0.25"
|
|
108
|
+
:size="260"
|
|
109
|
+
@frame="onFrame"
|
|
110
|
+
@settled="onSettled"
|
|
111
|
+
>
|
|
112
|
+
<template #default="{ currentAngle, velocity, isMoving }">
|
|
113
|
+
<div class="custom-compass-tile">
|
|
114
|
+
<span class="compass-pointer">β¬</span>
|
|
115
|
+
<span class="telemetry">{{ Math.round(currentAngle) }}Β° ({{ Math.round(velocity) }}Β°/s)</span>
|
|
116
|
+
</div>
|
|
117
|
+
</template>
|
|
118
|
+
</KineticRotator>
|
|
39
119
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
120
|
+
<div class="controls">
|
|
121
|
+
<button @click="rotatorRef?.rotateBy(90)">+90Β°</button>
|
|
122
|
+
<button @click="rotatorRef?.rotateBy(-90)">-90Β°</button>
|
|
123
|
+
<button @click="rotatorRef?.reset()">Reset</button>
|
|
124
|
+
</div>
|
|
43
125
|
</div>
|
|
44
126
|
</template>
|
|
45
127
|
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
128
|
+
<script setup>
|
|
129
|
+
import { ref } from 'vue';
|
|
130
|
+
import { KineticRotator } from '@gkucmierz/nano-ui';
|
|
131
|
+
|
|
132
|
+
const angle = ref(0);
|
|
133
|
+
const rotatorRef = ref(null);
|
|
134
|
+
|
|
135
|
+
const onFrame = (telemetry) => {
|
|
136
|
+
// telemetry: { currentAngle, targetAngle, velocity, acceleration, progress, isMoving, timestamp }
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const onSettled = ({ angle, normalizedAngle }) => {
|
|
140
|
+
console.log('Rotator settled at:', angle, 'modulo:', normalizedAngle);
|
|
141
|
+
};
|
|
142
|
+
</script>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### Props
|
|
146
|
+
| Prop | Type | Default | Description |
|
|
147
|
+
|---|---|---|---|
|
|
148
|
+
| `modelValue` | `Number` | `0` | Target angle in degrees. Supports `v-model`. |
|
|
149
|
+
| `duration` | `Number` | `1000` | Base duration in milliseconds for a $90^\circ$ rotation step. |
|
|
150
|
+
| `speedMultiplier` | `Number` | `1` | Speed scaling factor (e.g., `0.5` = half speed, `2.0` = double speed). |
|
|
151
|
+
| `step` | `Number` | `90` | Reference step angle in degrees used for proportional duration scaling. |
|
|
152
|
+
| `shortestPath` | `Boolean` | `true` | When true, targets are reduced modulo $360^\circ$ along the shortest geodesic arc. |
|
|
153
|
+
| `timingMode` | `String` | `'proportional'` | `'proportional'` (isokinetic, $v \approx \text{const}$) or `'fixed'` (isochronous, $T = \text{const}$). |
|
|
154
|
+
| `inertiaThreshold` | `Number` | `0.25` | Momentum threshold (in seconds) to avoid abrupt directional reversals during high-speed motion. |
|
|
155
|
+
| `size` | `Number \| String` | `260` | Width and height of the rotator bounding box in pixels or CSS units. |
|
|
156
|
+
|
|
157
|
+
#### Events
|
|
158
|
+
| Event | Payload | Description |
|
|
159
|
+
|---|---|---|
|
|
160
|
+
| `update:modelValue` | `Number` | Emitted when motion settles to update the `v-model` binding. |
|
|
161
|
+
| `change` | `Number` | Emitted immediately when a new target destination is committed. |
|
|
162
|
+
| `settled` | `{ angle, normalizedAngle }` | Emitted once motion comes to a complete rest. |
|
|
163
|
+
| `frame` | `Object` | Emitted every `requestAnimationFrame` with live kinematics telemetry. |
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
### ποΈ `PrecisionScrubber`
|
|
168
|
+
|
|
169
|
+
A 2D jog-dial precision scrubbing widget inspired by digital audio workstations (DAWs) and professional video editing suites. Dragging horizontally adjusts the parameter value, while dragging vertically increases resolution precision exponentially (up to $0.001\times$) with a floating HUD anchor guide.
|
|
170
|
+
|
|
171
|
+
#### Code Example
|
|
172
|
+
```vue
|
|
173
|
+
<template>
|
|
174
|
+
<PrecisionScrubber
|
|
175
|
+
v-model="frequency"
|
|
176
|
+
:min="20"
|
|
177
|
+
:max="20000"
|
|
178
|
+
:step="1"
|
|
179
|
+
label="Cutoff Frequency"
|
|
180
|
+
unit="Hz"
|
|
181
|
+
:sensitivity="1"
|
|
182
|
+
:relative="true"
|
|
183
|
+
/>
|
|
184
|
+
</template>
|
|
185
|
+
|
|
186
|
+
<script setup>
|
|
187
|
+
import { ref } from 'vue';
|
|
188
|
+
import { PrecisionScrubber } from '@gkucmierz/nano-ui';
|
|
189
|
+
|
|
190
|
+
const frequency = ref(440);
|
|
191
|
+
</script>
|
|
52
192
|
```
|
|
53
193
|
|
|
54
|
-
|
|
194
|
+
#### Props
|
|
195
|
+
| Prop | Type | Default | Description |
|
|
196
|
+
|---|---|---|---|
|
|
197
|
+
| `modelValue` | `Number` | *Required* | Current numerical value (`v-model`). |
|
|
198
|
+
| `min` | `Number` | `0` | Minimum allowed value boundary. |
|
|
199
|
+
| `max` | `Number` | `100` | Maximum allowed value boundary. |
|
|
200
|
+
| `step` | `Number` | `1` | Increment step size at base $1\times$ resolution. |
|
|
201
|
+
| `label` | `String` | `''` | Descriptive label displayed on the scrubber track. |
|
|
202
|
+
| `unit` | `String` | `''` | Value unit suffix (e.g., `'ms'`, `'px'`, `'%'`, `'Hz'`). |
|
|
203
|
+
| `sensitivity` | `Number` | `1` | Horizontal drag sensitivity multiplier. |
|
|
204
|
+
| `relative` | `Boolean` | `true` | Enables vertical distance dynamic precision scaling. |
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
### π `MutatingHeader`
|
|
55
209
|
|
|
56
|
-
A
|
|
210
|
+
A reactive, scroll-docking navigation container that dynamically morphs between an elevated floating glassmorphism card and an edge-to-edge docked navbar as the user scrolls.
|
|
57
211
|
|
|
58
212
|
#### Code Example
|
|
213
|
+
```vue
|
|
214
|
+
<template>
|
|
215
|
+
<MutatingHeader
|
|
216
|
+
:threshold="24"
|
|
217
|
+
:hysteresis="8"
|
|
218
|
+
height="60px"
|
|
219
|
+
floating-margin="12px 24px 0 24px"
|
|
220
|
+
floating-radius="16px"
|
|
221
|
+
:glassmorphism="true"
|
|
222
|
+
@change="onDockStateChange"
|
|
223
|
+
>
|
|
224
|
+
<div class="nav-content">
|
|
225
|
+
<span class="brand">Project Nexus</span>
|
|
226
|
+
<nav class="links">
|
|
227
|
+
<a href="#overview">Overview</a>
|
|
228
|
+
<a href="#features">Features</a>
|
|
229
|
+
</nav>
|
|
230
|
+
</div>
|
|
231
|
+
</MutatingHeader>
|
|
232
|
+
</template>
|
|
233
|
+
|
|
234
|
+
<script setup>
|
|
235
|
+
import { MutatingHeader } from '@gkucmierz/nano-ui';
|
|
236
|
+
|
|
237
|
+
const onDockStateChange = (isDocked) => {
|
|
238
|
+
console.log('Header docked status:', isDocked);
|
|
239
|
+
};
|
|
240
|
+
</script>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
#### Props
|
|
244
|
+
| Prop | Type | Default | Description |
|
|
245
|
+
|---|---|---|---|
|
|
246
|
+
| `threshold` | `Number` | `24` | Scroll distance in pixels after which the header docks edge-to-edge. |
|
|
247
|
+
| `hysteresis` | `Number` | `8` | Scroll delta in pixels below threshold required to un-dock back into floating card. |
|
|
248
|
+
| `scrollContainer`| `String \| Object` | `null` | Target scroll container selector or DOM element (defaults to `window`). |
|
|
249
|
+
| `height` | `String` | `'60px'` | Height of the header bar. |
|
|
250
|
+
| `floatingMargin` | `String` | `'12px 24px 0 24px'` | Outer margins when floating at the top of the viewport. |
|
|
251
|
+
| `floatingRadius` | `String` | `'16px'` | Corner border radius when in floating card state. |
|
|
252
|
+
| `glassmorphism` | `Boolean` | `true` | Enables blurred backdrop filter glassmorphism effect. |
|
|
253
|
+
| `stuck` | `Boolean` | `undefined` | Controlled dock state override via `v-model:stuck`. |
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
### π `NanoSwitch`
|
|
258
|
+
|
|
259
|
+
A lightweight, accessible toggle switch component featuring glassmorphism styles, keyboard accessibility (`Space` / `Enter`), and smooth state transitions.
|
|
260
|
+
|
|
261
|
+
```vue
|
|
262
|
+
<template>
|
|
263
|
+
<NanoSwitch
|
|
264
|
+
v-model="isEnabled"
|
|
265
|
+
label="Hardware Acceleration"
|
|
266
|
+
size="md"
|
|
267
|
+
/>
|
|
268
|
+
</template>
|
|
269
|
+
|
|
270
|
+
<script setup>
|
|
271
|
+
import { ref } from 'vue';
|
|
272
|
+
import { NanoSwitch } from '@gkucmierz/nano-ui';
|
|
273
|
+
|
|
274
|
+
const isEnabled = ref(true);
|
|
275
|
+
</script>
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
### π `ThreeDDonutChart`
|
|
281
|
+
|
|
282
|
+
A premium 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.
|
|
283
|
+
|
|
59
284
|
```vue
|
|
60
285
|
<template>
|
|
61
286
|
<div class="chart-container">
|
|
@@ -69,7 +294,7 @@ A premium, highly interactive 3D SVG Donut and Pie Chart component for Vue 3. Fe
|
|
|
69
294
|
:autoRotate="true"
|
|
70
295
|
:selectable="true"
|
|
71
296
|
valueDecimals="2"
|
|
72
|
-
centerLabel="Total
|
|
297
|
+
centerLabel="Total Portfolio"
|
|
73
298
|
/>
|
|
74
299
|
</div>
|
|
75
300
|
</template>
|
|
@@ -80,32 +305,152 @@ import { ThreeDDonutChart } from '@gkucmierz/nano-ui';
|
|
|
80
305
|
|
|
81
306
|
const selectedId = ref(null);
|
|
82
307
|
const chartData = ref([
|
|
83
|
-
{ id: '1', name: '
|
|
84
|
-
{ id: '2', name: '
|
|
85
|
-
{ id: '3', name: '
|
|
308
|
+
{ id: '1', name: 'Ethereum', value: 140, color: '#3b82f6', unit: 'ETH' },
|
|
309
|
+
{ id: '2', name: 'Solana', value: 95, color: '#10b981', unit: 'SOL' },
|
|
310
|
+
{ id: '3', name: 'Bitcoin', value: 55, color: '#f59e0b', unit: 'BTC' }
|
|
86
311
|
]);
|
|
87
312
|
</script>
|
|
88
313
|
```
|
|
89
314
|
|
|
90
|
-
####
|
|
315
|
+
#### Props
|
|
91
316
|
| Prop | Type | Default | Description |
|
|
92
317
|
|---|---|---|---|
|
|
93
318
|
| `data` | `Array` | *Required* | Array of objects: `{ id, name, value, color, unit }`. |
|
|
94
|
-
| `isExpanded` | `Boolean` | `false` | Large container layout with margins
|
|
319
|
+
| `isExpanded` | `Boolean` | `false` | Large container layout with callout margins (`true`) or compact mini layout (`false`). |
|
|
95
320
|
| `showLabels` | `Boolean` | `true` | Show/hide side callouts and leader lines (applicable when `isExpanded` is true). |
|
|
96
321
|
| `is3D` | `Boolean` | `true` | Enables 3D perspective rendering (depth and tilt). When false, renders in flat 2D. |
|
|
97
322
|
| `slopeRatio` | `Number` | `0.5` | Vertical tilt factor of the 3D plane (from `0.2` to `1.0`). |
|
|
98
323
|
| `rotationAngle` | `Number` | `-90` | Starting rotation angle of the chart in degrees. |
|
|
99
|
-
| `autoRotate` | `Boolean` | `false` | Dynamically optimizes rotation to
|
|
324
|
+
| `autoRotate` | `Boolean` | `false` | Dynamically optimizes rotation to balance side labels evenly. |
|
|
100
325
|
| `selectable` | `Boolean` | `false` | Enables slice selection/locking on click or tap. |
|
|
101
|
-
| `selectedItemId` | `String \| Number` | `null` |
|
|
102
|
-
| `centerValue` | `String \| Number` | `''` |
|
|
103
|
-
| `centerLabel` | `String` | `''` | Sub-label text displayed below
|
|
104
|
-
| `centerValueFormatter` | `Function` | `null` |
|
|
105
|
-
| `valueDecimals` | `Number` | `undefined` | Decimals to round slice values
|
|
106
|
-
| `aggregateOthers` | `Boolean` | `false` | Merges
|
|
107
|
-
| `othersThreshold
|
|
326
|
+
| `selectedItemId` | `String \| Number` | `null` | ID of the currently locked slice (`v-model:selectedItemId`). |
|
|
327
|
+
| `centerValue` | `String \| Number` | `''` | Custom text inside donut hole (defaults to sum of all items). |
|
|
328
|
+
| `centerLabel` | `String` | `''` | Sub-label text displayed below center value. |
|
|
329
|
+
| `centerValueFormatter` | `Function` | `null` | Formatter function: `(value, item) => string`. |
|
|
330
|
+
| `valueDecimals` | `Number` | `undefined` | Decimals to round slice values on callouts. |
|
|
331
|
+
| `aggregateOthers` | `Boolean` | `false` | Merges slices below threshold into an "Other" item. |
|
|
332
|
+
| `othersThreshold` | `Number` | `0.01` | Fraction threshold (e.g. `0.05` for 5%) for "Other" aggregation. |
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
### πͺ `NanoModal`
|
|
337
|
+
|
|
338
|
+
Standardized modal dialog adhering to the **Universal Dismissal Triad** (ESC key with `event.stopPropagation()`, backdrop click `@click.self`, and header close `β`), with deep-linking URL hash synchronization support.
|
|
339
|
+
|
|
340
|
+
```vue
|
|
341
|
+
<template>
|
|
342
|
+
<NanoModal
|
|
343
|
+
v-model="isOpen"
|
|
344
|
+
title="System Configuration"
|
|
345
|
+
icon="βοΈ"
|
|
346
|
+
max-width="540px"
|
|
347
|
+
@close="isOpen = false"
|
|
348
|
+
>
|
|
349
|
+
<div class="modal-body">
|
|
350
|
+
<p>Configure hardware telemetry parameters and sync preferences.</p>
|
|
351
|
+
</div>
|
|
352
|
+
</NanoModal>
|
|
353
|
+
</template>
|
|
354
|
+
|
|
355
|
+
<script setup>
|
|
356
|
+
import { ref } from 'vue';
|
|
357
|
+
import { NanoModal } from '@gkucmierz/nano-ui';
|
|
358
|
+
|
|
359
|
+
const isOpen = ref(false);
|
|
360
|
+
</script>
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
### π§ Directives
|
|
366
|
+
|
|
367
|
+
#### `v-ripple`
|
|
368
|
+
Material-style ripple effect directive with configurable colors:
|
|
369
|
+
|
|
370
|
+
```vue
|
|
371
|
+
<template>
|
|
372
|
+
<button v-ripple class="btn">Default Ripple</button>
|
|
373
|
+
<div v-ripple="'rgba(0, 242, 254, 0.3)'" class="card">Custom Cyan Ripple</div>
|
|
374
|
+
</template>
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
#### `v-tooltip`
|
|
378
|
+
Lightweight, accessible tooltip directive powered by `@gkucmierz/nano-ui` composable state:
|
|
379
|
+
|
|
380
|
+
```vue
|
|
381
|
+
<template>
|
|
382
|
+
<button v-tooltip="'Synchronize system telemetry'">Sync Now</button>
|
|
383
|
+
<span v-tooltip="{ text: 'High-precision sensor', position: 'bottom' }">Sensor A</span>
|
|
384
|
+
</template>
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## π Built-in i18n Architecture
|
|
390
|
+
|
|
391
|
+
Nano UI includes a zero-dependency, ultra-lightweight reactive internationalization engine (`src/locales.js`) featuring **strictly line-correlated JSON translation dictionaries**:
|
|
392
|
+
|
|
393
|
+
```javascript
|
|
394
|
+
import { t, currentLang, setLang, toggleLang } from '@gkucmierz/nano-ui/locales';
|
|
395
|
+
|
|
396
|
+
// Switch language reactively
|
|
397
|
+
setLang('pl'); // 'en' | 'pl'
|
|
398
|
+
toggleLang();
|
|
399
|
+
|
|
400
|
+
// Translate keys with parameter interpolation
|
|
401
|
+
const label = t('rotator.isokinetic');
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
The translation files (`src/locales/en.json` and `src/locales/pl.json`) are maintained in strict 1:1 line synchronization, enabling seamless structural diffing and zero missing-key drift.
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
<a id="zero-fouc-architecture"></a>
|
|
409
|
+
## β‘ Zero-FOUC Architecture
|
|
410
|
+
|
|
411
|
+
Nano UI provides synchronized design tokens with automatic system and dark-mode adaptation. Zero Flash of Unstyled Content (FOUC) is guaranteed through immediate inline CSS variable evaluation before Vue hydration:
|
|
412
|
+
|
|
413
|
+
```css
|
|
414
|
+
:root {
|
|
415
|
+
--nano-bg-main: #060913;
|
|
416
|
+
--nano-bg-card: rgba(15, 23, 42, 0.75);
|
|
417
|
+
--nano-border-card: rgba(255, 255, 255, 0.12);
|
|
418
|
+
--nano-state-active: #00f2fe;
|
|
419
|
+
--nano-state-accent: #6366f1;
|
|
420
|
+
--nano-radius-md: 10px;
|
|
421
|
+
--nano-radius-lg: 16px;
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
<a id="zero-trust-offline-first"></a>
|
|
428
|
+
## π‘οΈ Zero-Trust Offline-First
|
|
429
|
+
|
|
430
|
+
In accordance with workspace reliability standards:
|
|
431
|
+
- **No External CDNs:** Zero runtime script imports from `unpkg.com`, `esm.sh`, `jsdelivr`, or `cdnjs`.
|
|
432
|
+
- **Bundled Assets:** All SVG graphics and fonts resolve locally to guarantee 100% offline functionality in air-gapped environments or Progressive Web Apps (PWAs).
|
|
433
|
+
|
|
434
|
+
---
|
|
435
|
+
|
|
436
|
+
## π Scripts & Development
|
|
437
|
+
|
|
438
|
+
```bash
|
|
439
|
+
# Start local Vite development server & playground
|
|
440
|
+
npm run dev
|
|
441
|
+
|
|
442
|
+
# Build the production library distribution (dist/nano-ui.js & dist/nano-ui.css)
|
|
443
|
+
npm run build
|
|
444
|
+
|
|
445
|
+
# Build the standalone documentation & playground application
|
|
446
|
+
npm run build:app
|
|
447
|
+
|
|
448
|
+
# Regenerate master branding assets (SVG -> 512x512 PNG)
|
|
449
|
+
npm run icons
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
---
|
|
108
453
|
|
|
109
|
-
##
|
|
454
|
+
## π License
|
|
110
455
|
|
|
111
|
-
MIT
|
|
456
|
+
[MIT](LICENSE) Β© [Grzegorz KuΔmierz](https://gkucmierz.com)
|
|
Binary file
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
|
|
2
|
+
<defs>
|
|
3
|
+
<!-- Background Squircle Gradient -->
|
|
4
|
+
<linearGradient id="nanoBgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
5
|
+
<stop offset="0%" stop-color="#0f172a" />
|
|
6
|
+
<stop offset="100%" stop-color="#020617" />
|
|
7
|
+
</linearGradient>
|
|
8
|
+
|
|
9
|
+
<!-- Ambient Core Radial Glow -->
|
|
10
|
+
<radialGradient id="nanoAmbientGlow" cx="50%" cy="50%" r="50%">
|
|
11
|
+
<stop offset="0%" stop-color="#6366f1" stop-opacity="0.38" />
|
|
12
|
+
<stop offset="55%" stop-color="#00f2fe" stop-opacity="0.14" />
|
|
13
|
+
<stop offset="100%" stop-color="#020617" stop-opacity="0" />
|
|
14
|
+
</radialGradient>
|
|
15
|
+
|
|
16
|
+
<!-- Continuous Kinetic Energy Monogram Gradient -->
|
|
17
|
+
<linearGradient id="nanoKineticGrad" x1="136" y1="376" x2="376" y2="136" gradientUnits="userSpaceOnUse">
|
|
18
|
+
<stop offset="0%" stop-color="#4f46e5" />
|
|
19
|
+
<stop offset="28%" stop-color="#6366f1" />
|
|
20
|
+
<stop offset="58%" stop-color="#38bdf8" />
|
|
21
|
+
<stop offset="100%" stop-color="#00f2fe" />
|
|
22
|
+
</linearGradient>
|
|
23
|
+
</defs>
|
|
24
|
+
|
|
25
|
+
<!-- Squircle Base Canvas (App Icon & OG Surface) -->
|
|
26
|
+
<rect width="512" height="512" rx="144" fill="url(#nanoBgGrad)" stroke="rgba(255, 255, 255, 0.14)" stroke-width="4" />
|
|
27
|
+
|
|
28
|
+
<!-- Ambient Glow -->
|
|
29
|
+
<circle cx="256" cy="256" r="220" fill="url(#nanoAmbientGlow)" />
|
|
30
|
+
|
|
31
|
+
<!-- High-Precision Quantum Reticle Rings -->
|
|
32
|
+
<circle cx="256" cy="256" r="208" stroke="rgba(255, 255, 255, 0.08)" stroke-width="2" stroke-dasharray="8 12" />
|
|
33
|
+
<circle cx="256" cy="256" r="160" stroke="rgba(255, 255, 255, 0.05)" stroke-width="1.5" />
|
|
34
|
+
|
|
35
|
+
<!-- Diagonal Alignment Axis -->
|
|
36
|
+
<line x1="84" y1="84" x2="428" y2="428" stroke="rgba(255, 255, 255, 0.05)" stroke-width="1.5" stroke-dasharray="6 10" />
|
|
37
|
+
|
|
38
|
+
<!-- BOLD KINETIC 'N' MONOGRAM (Continuous 72px Joined Path) -->
|
|
39
|
+
<path
|
|
40
|
+
d="M136 376 V136 L376 376 V136"
|
|
41
|
+
stroke="url(#nanoKineticGrad)"
|
|
42
|
+
stroke-width="72"
|
|
43
|
+
stroke-linecap="round"
|
|
44
|
+
stroke-linejoin="round"
|
|
45
|
+
/>
|
|
46
|
+
|
|
47
|
+
<!-- Prominent Quantum Pulsar (Upper Right) -->
|
|
48
|
+
<circle cx="376" cy="136" r="54" fill="rgba(0, 242, 254, 0.24)" />
|
|
49
|
+
<circle cx="376" cy="136" r="32" fill="#00f2fe" />
|
|
50
|
+
<circle cx="376" cy="136" r="13" fill="#ffffff" />
|
|
51
|
+
|
|
52
|
+
<!-- Secondary Anchor Core (Bottom Left) -->
|
|
53
|
+
<circle cx="136" cy="376" r="15" fill="#4f46e5" />
|
|
54
|
+
</svg>
|