@mks2508/sidebar-headless 0.1.0 → 0.2.1

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,329 @@
1
+ /**
2
+ * Tooltip Transition Keyframes
3
+ *
4
+ * Sistema de animaciones CSS para transiciones de tooltip con:
5
+ * - Items staggered enter/exit
6
+ * - Grid-based height transitions
7
+ * - 3D title rotations
8
+ *
9
+ * Performance: GPU-accelerated (transform + opacity only)
10
+ */
11
+
12
+ /* ============================================================================
13
+ ITEMS ANIMATIONS - Staggered Enter/Exit
14
+ ============================================================================ */
15
+
16
+ @keyframes tooltip-item-enter {
17
+ from {
18
+ opacity: 0;
19
+ transform: translateX(-8px);
20
+ }
21
+ to {
22
+ opacity: 1;
23
+ transform: translateX(0);
24
+ }
25
+ }
26
+
27
+ @keyframes tooltip-item-exit {
28
+ from {
29
+ opacity: 1;
30
+ transform: translateX(0);
31
+ }
32
+ to {
33
+ opacity: 0;
34
+ transform: translateX(-4px);
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Item States con CSS Custom Properties
40
+ *
41
+ * Uso: <div style="--animation-order: 0" data-state="entering">
42
+ */
43
+ .sidebar-sublink[data-state="entering"] {
44
+ animation: tooltip-item-enter 150ms cubic-bezier(0.4, 0, 0.2, 1);
45
+ animation-delay: calc(var(--animation-order, 0) * 30ms + 150ms);
46
+ animation-fill-mode: both;
47
+ }
48
+
49
+ .sidebar-sublink[data-state="leaving"] {
50
+ animation: tooltip-item-exit 100ms cubic-bezier(0.4, 0, 0.6, 1);
51
+ animation-delay: calc(var(--animation-order, 0) * 20ms);
52
+ animation-fill-mode: both;
53
+ }
54
+
55
+ /* ============================================================================
56
+ TITLE 3D ROTATIONS
57
+ ============================================================================ */
58
+
59
+ /**
60
+ * Title Rotate Up (direction-aware)
61
+ * Usado cuando navegamos hacia arriba en el sidebar
62
+ */
63
+ @keyframes tooltip-title-rotate-up {
64
+ from {
65
+ transform: rotateX(0deg);
66
+ opacity: 1;
67
+ }
68
+ to {
69
+ transform: rotateX(-90deg);
70
+ opacity: 0;
71
+ }
72
+ }
73
+
74
+ @keyframes tooltip-title-enter-from-below {
75
+ from {
76
+ transform: rotateX(90deg);
77
+ opacity: 0;
78
+ }
79
+ to {
80
+ transform: rotateX(0deg);
81
+ opacity: 1;
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Title Rotate Down (direction-aware)
87
+ * Usado cuando navegamos hacia abajo en el sidebar
88
+ */
89
+ @keyframes tooltip-title-rotate-down {
90
+ from {
91
+ transform: rotateX(0deg);
92
+ opacity: 1;
93
+ }
94
+ to {
95
+ transform: rotateX(90deg);
96
+ opacity: 0;
97
+ }
98
+ }
99
+
100
+ @keyframes tooltip-title-enter-from-above {
101
+ from {
102
+ transform: rotateX(-90deg);
103
+ opacity: 0;
104
+ }
105
+ to {
106
+ transform: rotateX(0deg);
107
+ opacity: 1;
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Title States
113
+ */
114
+ .tooltip-title[data-direction="up"][data-state="leaving"] {
115
+ animation: tooltip-title-rotate-up 250ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
116
+ }
117
+
118
+ .tooltip-title[data-direction="up"][data-state="entering"] {
119
+ animation: tooltip-title-enter-from-below 250ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
120
+ }
121
+
122
+ .tooltip-title[data-direction="down"][data-state="leaving"] {
123
+ animation: tooltip-title-rotate-down 250ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
124
+ }
125
+
126
+ .tooltip-title[data-direction="down"][data-state="entering"] {
127
+ animation: tooltip-title-enter-from-above 250ms cubic-bezier(0.4, 0, 0.2, 1) forwards;
128
+ }
129
+
130
+ /* ============================================================================
131
+ 3D CUBE FACES (Enfoque A: Multi-cara)
132
+ ============================================================================ */
133
+
134
+ /**
135
+ * Cubo 3D con 6 caras para títulos
136
+ *
137
+ * Estructura:
138
+ * .title-scene (perspective)
139
+ * └─ .title-cube (preserve-3d)
140
+ * ├─ .title-face--front
141
+ * ├─ .title-face--back
142
+ * ├─ .title-face--top
143
+ * ├─ .title-face--bottom
144
+ * ├─ .title-face--left
145
+ * └─ .title-face--right
146
+ */
147
+
148
+ .title-scene {
149
+ perspective: 600px;
150
+ position: relative;
151
+ width: 100%;
152
+ height: 2rem;
153
+ }
154
+
155
+ .title-cube {
156
+ width: 100%;
157
+ height: 100%;
158
+ position: relative;
159
+ transform-style: preserve-3d;
160
+ transition: transform 250ms cubic-bezier(0.4, 0, 0.2, 1);
161
+ /* Empujar hacia atrás para evitar blur en texto */
162
+ transform: translateZ(-1rem);
163
+ }
164
+
165
+ .title-face {
166
+ position: absolute;
167
+ width: 100%;
168
+ height: 100%;
169
+ backface-visibility: hidden;
170
+ display: flex;
171
+ align-items: center;
172
+ justify-content: flex-start;
173
+ padding: 0 1rem;
174
+ font-weight: 500;
175
+ }
176
+
177
+ /* Posicionamiento de caras - Vertical rotation (rotateX) */
178
+ .title-face--front {
179
+ transform: rotateX(0deg) translateZ(1rem);
180
+ }
181
+
182
+ .title-face--top {
183
+ transform: rotateX(90deg) translateZ(1rem);
184
+ }
185
+
186
+ .title-face--bottom {
187
+ transform: rotateX(-90deg) translateZ(1rem);
188
+ }
189
+
190
+ .title-face--back {
191
+ transform: rotateX(180deg) translateZ(1rem);
192
+ }
193
+
194
+ /* Estados del cubo - Direction-aware */
195
+ .title-cube[data-face="front"] {
196
+ transform: translateZ(-1rem) rotateX(0deg);
197
+ }
198
+
199
+ .title-cube[data-face="top"] {
200
+ transform: translateZ(-1rem) rotateX(-90deg);
201
+ }
202
+
203
+ .title-cube[data-face="bottom"] {
204
+ transform: translateZ(-1rem) rotateX(90deg);
205
+ }
206
+
207
+ .title-cube[data-face="back"] {
208
+ transform: translateZ(-1rem) rotateX(180deg);
209
+ }
210
+
211
+ /* ============================================================================
212
+ GRID HEIGHT TRANSITION (Grid Trick)
213
+ ============================================================================ */
214
+
215
+ /**
216
+ * Grid trick para height: auto transitions
217
+ *
218
+ * Técnica: grid-template-rows: 0fr → 1fr
219
+ * Browser support: Chrome 107+, Firefox 117+, Safari 16.4+
220
+ */
221
+
222
+ .tooltip-content-grid {
223
+ display: grid;
224
+ grid-template-rows: 0fr;
225
+ transition: grid-template-rows 200ms cubic-bezier(0.4, 0, 0.2, 1);
226
+ transition-delay: 50ms; /* Empieza después del fade-out de items */
227
+ }
228
+
229
+ .tooltip-content-grid[data-state="open"] {
230
+ grid-template-rows: 1fr;
231
+ }
232
+
233
+ .tooltip-content-inner {
234
+ overflow: hidden;
235
+ min-height: 0; /* Crítico para que grid trick funcione */
236
+ }
237
+
238
+ /* ============================================================================
239
+ UTILITY CLASSES
240
+ ============================================================================ */
241
+
242
+ /**
243
+ * Contenedor con perspective para títulos crossfade
244
+ */
245
+ .tooltip-title-perspective {
246
+ perspective: 600px;
247
+ position: relative;
248
+ width: 100%;
249
+ height: 2rem;
250
+ overflow: hidden;
251
+ }
252
+
253
+ /**
254
+ * Disable animations durante hover rápido (opcional)
255
+ * Usar con cuidado: puede causar flickering
256
+ */
257
+ .tooltip-no-animations * {
258
+ animation: none !important;
259
+ transition: none !important;
260
+ }
261
+
262
+ /* ============================================================================
263
+ DEBUG HELPERS
264
+ ============================================================================ */
265
+
266
+ /**
267
+ * Visualización de estados en debug mode
268
+ */
269
+ [data-tooltip-debug="true"] .sidebar-sublink[data-state]::before {
270
+ content: attr(data-state);
271
+ position: absolute;
272
+ top: 0;
273
+ right: 0;
274
+ font-size: 8px;
275
+ background: rgba(255, 0, 0, 0.8);
276
+ color: white;
277
+ padding: 2px 4px;
278
+ border-radius: 2px;
279
+ pointer-events: none;
280
+ z-index: 1000;
281
+ }
282
+
283
+ [data-tooltip-debug="true"] .tooltip-title[data-direction]::after {
284
+ content: "dir:" attr(data-direction);
285
+ position: absolute;
286
+ bottom: 0;
287
+ left: 0;
288
+ font-size: 8px;
289
+ background: rgba(0, 0, 255, 0.8);
290
+ color: white;
291
+ padding: 2px 4px;
292
+ border-radius: 2px;
293
+ pointer-events: none;
294
+ z-index: 1000;
295
+ }
296
+
297
+ /* ============================================================================
298
+ PERFORMANCE OPTIMIZATIONS
299
+ ============================================================================ */
300
+
301
+ /**
302
+ * GPU acceleration hints
303
+ */
304
+ .sidebar-sublink[data-state],
305
+ .tooltip-title[data-state],
306
+ .title-cube {
307
+ will-change: transform, opacity;
308
+ }
309
+
310
+ /**
311
+ * Contain layout/paint/style para mejor performance
312
+ */
313
+ .tooltip-content-grid {
314
+ contain: layout style paint;
315
+ }
316
+
317
+ /**
318
+ * Reduce motion para accesibilidad
319
+ */
320
+ @media (prefers-reduced-motion: reduce) {
321
+ .sidebar-sublink[data-state],
322
+ .tooltip-title[data-state],
323
+ .title-cube,
324
+ .tooltip-content-grid {
325
+ animation-duration: 0.01ms !important;
326
+ animation-iteration-count: 1 !important;
327
+ transition-duration: 0.01ms !important;
328
+ }
329
+ }
package/package.json CHANGED
@@ -1,99 +1,106 @@
1
- {
2
- "name": "@mks2508/sidebar-headless",
3
- "version": "0.1.0",
4
- "description": "Headless sidebar component for React with advanced animations, keyboard navigation, and full WAI-ARIA accessibility",
5
- "type": "module",
6
- "main": "./dist/index.js",
7
- "module": "./dist/index.js",
8
- "types": "./dist/index.d.ts",
9
- "exports": {
10
- ".": {
11
- "types": "./dist/index.d.ts",
12
- "import": "./dist/index.js",
13
- "require": "./dist/index.js"
14
- },
15
- "./styles.css": "./dist/index.css"
16
- },
17
- "files": [
18
- "dist",
19
- "README.md",
20
- "LICENSE"
21
- ],
22
- "sideEffects": [
23
- "*.css"
24
- ],
25
- "scripts": {
26
- "dev": "cd playground && vite",
27
- "dev:clean": "killall -9 node || true && cd playground && vite",
28
- "build": "tsup",
29
- "build:watch": "tsup --watch",
30
- "preview": "cd playground && vite preview",
31
- "typecheck": "tsc --noEmit",
32
- "prepublishOnly": "bun run build && bun run typecheck"
33
- },
34
- "keywords": [
35
- "react",
36
- "sidebar",
37
- "headless",
38
- "component",
39
- "navigation",
40
- "ui",
41
- "typescript",
42
- "accessibility",
43
- "a11y",
44
- "wai-aria",
45
- "keyboard-navigation",
46
- "glassmorphism",
47
- "fluid-animation"
48
- ],
49
- "author": "MKS2508",
50
- "license": "MIT",
51
- "repository": {
52
- "type": "git",
53
- "url": "https://github.com/mks2508/sidebar-headless.git"
54
- },
55
- "bugs": {
56
- "url": "https://github.com/mks2508/sidebar-headless/issues"
57
- },
58
- "homepage": "https://github.com/mks2508/sidebar-headless#readme",
59
- "peerDependencies": {
60
- "react": ">=18.0.0",
61
- "react-dom": ">=18.0.0"
62
- },
63
- "peerDependenciesMeta": {
64
- "@liquid-svg-glass/core": {
65
- "optional": true
66
- },
67
- "@liquid-svg-glass/react": {
68
- "optional": true
69
- }
70
- },
71
- "dependencies": {
72
- "clsx": "^2.1.1",
73
- "tailwind-merge": "^3.3.1"
74
- },
75
- "devDependencies": {
76
- "@base-ui-components/react": "^1.0.0-beta.4",
77
- "@liquid-svg-glass/react": "file:./lib/@liquid-svg-glass/react",
78
- "@radix-ui/react-label": "^2.1.7",
79
- "@radix-ui/react-select": "^2.2.6",
80
- "@radix-ui/react-slider": "^1.3.6",
81
- "@radix-ui/react-slot": "^1.2.3",
82
- "@tailwindcss/vite": "^4.1.16",
83
- "@types/bun": "latest",
84
- "@types/react": "^19",
85
- "@types/react-dom": "^19",
86
- "@vitejs/plugin-react": "^5.1.0",
87
- "bun-plugin-tailwind": "^0.1.2",
88
- "class-variance-authority": "^0.7.1",
89
- "lucide-react": "^0.545.0",
90
- "motion": "^12.23.24",
91
- "react": "^19",
92
- "react-dom": "^19",
93
- "tailwindcss": "^4.1.11",
94
- "tsup": "^8.5.1",
95
- "tw-animate-css": "^1.4.0",
96
- "typescript": "^5.9.3",
97
- "vite": "^7.1.12"
98
- }
99
- }
1
+ {
2
+ "name": "@mks2508/sidebar-headless",
3
+ "version": "0.2.1",
4
+ "description": "Headless sidebar and mobile bottom navigation components for React with advanced animations, keyboard navigation, and full WAI-ARIA accessibility",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./styles.css": "./dist/index.css",
16
+ "./mobile-optimizations.css": "./dist/MobileOptimizations.css",
17
+ "./tooltip-keyframes.css": "./dist/tooltip-keyframes.css"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "README.md",
22
+ "LICENSE",
23
+ "CHANGELOG.md"
24
+ ],
25
+ "sideEffects": [
26
+ "*.css"
27
+ ],
28
+ "scripts": {
29
+ "dev": "cd playground && vite",
30
+ "dev:clean": "killall -9 node || true && cd playground && vite",
31
+ "build": "tsup",
32
+ "build:watch": "tsup --watch",
33
+ "preview": "cd playground && vite preview",
34
+ "typecheck": "tsc --noEmit",
35
+ "prepublishOnly": "bun run build && bun run typecheck"
36
+ },
37
+ "keywords": [
38
+ "react",
39
+ "sidebar",
40
+ "mobile-bottom-nav",
41
+ "bottom-navigation",
42
+ "headless",
43
+ "component",
44
+ "navigation",
45
+ "ui",
46
+ "typescript",
47
+ "accessibility",
48
+ "a11y",
49
+ "wai-aria",
50
+ "keyboard-navigation",
51
+ "glassmorphism",
52
+ "fluid-animation",
53
+ "mobile",
54
+ "ios"
55
+ ],
56
+ "author": "MKS2508",
57
+ "license": "MIT",
58
+ "repository": {
59
+ "type": "git",
60
+ "url": "git+https://github.com/mks2508/sidebar-headless.git"
61
+ },
62
+ "bugs": {
63
+ "url": "https://github.com/mks2508/sidebar-headless/issues"
64
+ },
65
+ "homepage": "https://github.com/mks2508/sidebar-headless#readme",
66
+ "peerDependencies": {
67
+ "react": ">=18.0.0",
68
+ "react-dom": ">=18.0.0"
69
+ },
70
+ "peerDependenciesMeta": {
71
+ "@liquid-svg-glass/core": {
72
+ "optional": true
73
+ },
74
+ "@liquid-svg-glass/react": {
75
+ "optional": true
76
+ }
77
+ },
78
+ "dependencies": {
79
+ "clsx": "^2.1.1",
80
+ "tailwind-merge": "^3.3.1"
81
+ },
82
+ "devDependencies": {
83
+ "@base-ui-components/react": "^1.0.0-beta.4",
84
+ "@liquid-svg-glass/react": "file:./lib/@liquid-svg-glass/react",
85
+ "@radix-ui/react-label": "^2.1.7",
86
+ "@radix-ui/react-select": "^2.2.6",
87
+ "@radix-ui/react-slider": "^1.3.6",
88
+ "@radix-ui/react-slot": "^1.2.3",
89
+ "@tailwindcss/vite": "^4.1.16",
90
+ "@types/bun": "latest",
91
+ "@types/react": "^19",
92
+ "@types/react-dom": "^19",
93
+ "@vitejs/plugin-react": "^5.1.0",
94
+ "bun-plugin-tailwind": "^0.1.2",
95
+ "class-variance-authority": "^0.7.1",
96
+ "lucide-react": "^0.545.0",
97
+ "motion": "^12.23.24",
98
+ "react": "^19",
99
+ "react-dom": "^19",
100
+ "tailwindcss": "^4.1.11",
101
+ "tsup": "^8.5.1",
102
+ "tw-animate-css": "^1.4.0",
103
+ "typescript": "^5.9.3",
104
+ "vite": "^7.1.12"
105
+ }
106
+ }