@vifui/styles 0.4.0-alpha.6

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,393 @@
1
+ /**
2
+ * Card Component
3
+ *
4
+ * Architecture inspired by Vuesax v3 (MIT License)
5
+ * Built with modern Tailwind CSS and CSS variables
6
+ */
7
+
8
+ /* ============================================ */
9
+ /* Base Card */
10
+ /* ============================================ */
11
+
12
+ .vif-card {
13
+ /* Layout */
14
+ @apply relative block w-full;
15
+
16
+ /* Background */
17
+ background: var(--surface);
18
+
19
+ /* Border */
20
+ border-radius: var(--radius-lg);
21
+
22
+ /* Transitions - smooth like Vuesax */
23
+ transition: var(--card-transition);
24
+
25
+ /* Typography */
26
+ color: var(--surface-foreground);
27
+
28
+ /* Performance */
29
+ contain: layout style;
30
+ }
31
+
32
+ /* ============================================ */
33
+ /* Variant: Elevated (Default - Vuesax style) */
34
+ /* ============================================ */
35
+
36
+ .vif-card--elevated {
37
+ box-shadow: var(--card-shadow);
38
+ }
39
+
40
+ /* ============================================ */
41
+ /* Variant: Outlined */
42
+ /* ============================================ */
43
+
44
+ .vif-card--outlined {
45
+ border: 1px solid var(--border);
46
+ box-shadow: none;
47
+ }
48
+
49
+ /* ============================================ */
50
+ /* Variant: Flat */
51
+ /* ============================================ */
52
+
53
+ .vif-card--flat {
54
+ background: var(--default);
55
+ box-shadow: none;
56
+ }
57
+
58
+ /* ============================================ */
59
+ /* Variant: Ghost */
60
+ /* ============================================ */
61
+
62
+ .vif-card--ghost {
63
+ background: transparent;
64
+ box-shadow: none;
65
+ }
66
+
67
+ /* ============================================ */
68
+ /* Hoverable State (Vuesax withHover) */
69
+ /* ============================================ */
70
+
71
+ .vif-card--hoverable {
72
+ cursor: var(--cursor-interactive);
73
+
74
+ &:hover {
75
+ transform: translateY(-4px);
76
+ box-shadow: var(--card-shadow-hover);
77
+ }
78
+
79
+ &:active {
80
+ transform: translateY(-2px);
81
+ }
82
+ }
83
+
84
+ /* Hoverable + Outlined */
85
+ .vif-card--hoverable.vif-card--outlined {
86
+ &:hover {
87
+ border-color: var(--primary);
88
+ box-shadow: var(--shadow-md);
89
+ }
90
+ }
91
+
92
+ /* Hoverable + Flat */
93
+ .vif-card--hoverable.vif-card--flat {
94
+ &:hover {
95
+ /* background: var(--default-hover); */
96
+ box-shadow: var(--shadow-xs);
97
+ }
98
+ }
99
+
100
+ /* Hoverable + Ghost */
101
+ .vif-card--hoverable.vif-card--ghost {
102
+ &:hover {
103
+ background: var(--default);
104
+ box-shadow: var(--shadow-sm);
105
+ }
106
+ }
107
+
108
+ /* ============================================ */
109
+ /* Size Variants */
110
+ /* ============================================ */
111
+
112
+ .vif-card--sm {
113
+ --card-padding: 0.75rem;
114
+ }
115
+
116
+ .vif-card--md {
117
+ --card-padding: 1rem;
118
+ }
119
+
120
+ .vif-card--lg {
121
+ --card-padding: 1.5rem;
122
+ }
123
+
124
+ /* ============================================ */
125
+ /* Color Variants */
126
+ /* ============================================ */
127
+
128
+ /* Neutral (Default) */
129
+ .vif-card--neutral {
130
+ /* Uses default surface colors */
131
+ }
132
+
133
+ /* Brand */
134
+ .vif-card--brand.vif-card--outlined {
135
+ border-color: var(--primary);
136
+ }
137
+
138
+ .vif-card--brand.vif-card--flat {
139
+ background: color-mix(in srgb, var(--primary) 5%, transparent);
140
+ }
141
+
142
+ /* Success */
143
+ .vif-card--success.vif-card--outlined {
144
+ border-color: var(--success);
145
+ }
146
+
147
+ .vif-card--success.vif-card--flat {
148
+ background: color-mix(in srgb, var(--success) 5%, transparent);
149
+ }
150
+
151
+ /* Warning */
152
+ .vif-card--warning.vif-card--outlined {
153
+ border-color: var(--warning);
154
+ }
155
+
156
+ .vif-card--warning.vif-card--flat {
157
+ background: color-mix(in srgb, var(--warning) 5%, transparent);
158
+ }
159
+
160
+ /* Danger */
161
+ .vif-card--danger.vif-card--outlined {
162
+ border-color: var(--danger);
163
+ }
164
+
165
+ .vif-card--danger.vif-card--flat {
166
+ background: color-mix(in srgb, var(--danger) 5%, transparent);
167
+ }
168
+
169
+ /* ============================================ */
170
+ /* Full Height (Vuesax fixedHeight) */
171
+ /* ============================================ */
172
+
173
+ .vif-card--full-height {
174
+ height: 100%;
175
+ display: flex;
176
+ flex-direction: column;
177
+ }
178
+
179
+ /* ============================================ */
180
+ /* Card Header */
181
+ /* ============================================ */
182
+
183
+ .vif-card__header {
184
+ @apply relative;
185
+ padding: var(--card-padding, 1rem);
186
+ box-shadow: 0px 10px 15px -10px rgba(0, 0, 0, 0.05);
187
+
188
+ /* Typography */
189
+ & h3,
190
+ & h4 {
191
+ @apply m-0 p-0 font-semibold;
192
+ }
193
+
194
+ & h3 {
195
+ @apply text-lg;
196
+ }
197
+
198
+ & h4 {
199
+ @apply text-base;
200
+ }
201
+ }
202
+
203
+ /* ============================================ */
204
+ /* Card Body */
205
+ /* ============================================ */
206
+
207
+ .vif-card__body {
208
+ @apply relative;
209
+ padding: var(--card-padding, 1rem);
210
+ font-size: 0.875rem;
211
+ flex: 1; /* For full-height cards */
212
+ }
213
+
214
+ /* ============================================ */
215
+ /* Card Footer */
216
+ /* ============================================ */
217
+
218
+ .vif-card__footer {
219
+ @apply relative;
220
+ padding: var(--card-padding, 1rem);
221
+ padding-top: 0;
222
+ }
223
+
224
+ /* Footer in full-height cards */
225
+ .vif-card--full-height .vif-card__footer {
226
+ margin-top: 0;
227
+ transform: none;
228
+ }
229
+
230
+ /* ============================================ */
231
+ /* Card Media (Image wrapper with zoom effect) */
232
+ /* ============================================ */
233
+
234
+ .vif-card__media {
235
+ @apply relative w-full overflow-hidden;
236
+
237
+ /* Rounded top corners */
238
+ border-radius: var(--radius-lg) var(--radius-lg) 0 0;
239
+
240
+ /* Base styles for media elements */
241
+ & > :first-child {
242
+ @apply block w-full;
243
+ transition: transform 250ms var(--ease-smooth);
244
+ vertical-align: middle;
245
+ }
246
+ }
247
+
248
+ /* ============================================ */
249
+ /* Media: Auto Ratio (Natural dimensions) */
250
+ /* ============================================ */
251
+
252
+ .vif-card__media:not(.vif-card__media--square):not(.vif-card__media--video):not(
253
+ .vif-card__media--portrait
254
+ ) {
255
+ max-height: 230px;
256
+
257
+ & > :first-child {
258
+ width: 100%;
259
+ height: 100%;
260
+ object-fit: cover;
261
+ }
262
+ }
263
+
264
+ /* ============================================ */
265
+ /* Media: Fixed Aspect Ratios */
266
+ /* ============================================ */
267
+
268
+ /* Square (1:1) */
269
+ .vif-card__media--square {
270
+ aspect-ratio: 1 / 1;
271
+
272
+ & > :first-child {
273
+ @apply h-full w-full object-cover;
274
+ }
275
+ }
276
+
277
+ /* Video (16:9) */
278
+ .vif-card__media--video {
279
+ aspect-ratio: 16 / 9;
280
+
281
+ & > :first-child {
282
+ @apply h-full w-full object-cover;
283
+ }
284
+ }
285
+
286
+ /* Portrait (3:4) */
287
+ .vif-card__media--portrait {
288
+ aspect-ratio: 3 / 4;
289
+
290
+ & > :first-child {
291
+ @apply h-full w-full object-cover;
292
+ }
293
+ }
294
+
295
+ /* ============================================ */
296
+ /* Media: Hover Zoom Effect */
297
+ /* ============================================ */
298
+
299
+ .vif-card--hoverable:hover .vif-card__media > :first-child {
300
+ transform: scale(var(--card-image-scale, 1.05));
301
+ }
302
+
303
+ /* Aspect ratio helpers */
304
+ .vif-card__media--square {
305
+ aspect-ratio: 1 / 1;
306
+
307
+ & > :first-child {
308
+ @apply h-full w-full object-cover;
309
+ }
310
+ }
311
+
312
+ .vif-card__media--video {
313
+ aspect-ratio: 16 / 9;
314
+
315
+ & > :first-child {
316
+ @apply h-full w-full object-cover;
317
+ }
318
+ }
319
+
320
+ .vif-card__media--portrait {
321
+ aspect-ratio: 3 / 4;
322
+
323
+ & > :first-child {
324
+ @apply h-full w-full object-cover;
325
+ }
326
+ }
327
+
328
+ /* ============================================ */
329
+ /* Disabled State */
330
+ /* ============================================ */
331
+
332
+ .vif-card--disabled {
333
+ opacity: var(--disabled-opacity);
334
+ pointer-events: none;
335
+ cursor: var(--cursor-disabled);
336
+ }
337
+
338
+ /* ============================================ */
339
+ /* Loading State */
340
+ /* ============================================ */
341
+
342
+ .vif-card--loading {
343
+ @apply pointer-events-none relative;
344
+
345
+ /* Blur the entire card content with smooth animation */
346
+ & > * {
347
+ filter: blur(4px);
348
+ opacity: 0.6;
349
+ transition:
350
+ filter 100ms var(--ease-smooth),
351
+ opacity 100ms var(--ease-smooth);
352
+ }
353
+
354
+ /* Loading overlay with fade in */
355
+ &::after {
356
+ content: "";
357
+ @apply absolute inset-0 flex items-center justify-center;
358
+ background: var(--surface);
359
+ opacity: 0.4;
360
+ z-index: 10;
361
+ /* animation: vif-fade-in 100ms var(--ease-smooth); */
362
+ }
363
+
364
+ /* Animated spinner
365
+ &::before {
366
+ content: "";
367
+ @apply absolute left-1/2 top-1/2 z-20;
368
+ width: 40px;
369
+ height: 40px;
370
+ margin: -20px 0 0 -20px;
371
+ border: 3px solid var(--primary);
372
+ border-top-color: transparent;
373
+ border-radius: 50%;
374
+ animation:
375
+ vif-spin 0.8s linear infinite,
376
+ vif-fade-in 200ms var(--ease-smooth);
377
+ } */
378
+ }
379
+
380
+ /* @keyframes vif-spin {
381
+ to {
382
+ transform: rotate(360deg);
383
+ }
384
+ }
385
+
386
+ @keyframes vif-fade-in {
387
+ from {
388
+ opacity: 0;
389
+ }
390
+ to {
391
+ opacity: 1;
392
+ }
393
+ } */
@@ -0,0 +1,293 @@
1
+ /**
2
+ * Checkbox Component
3
+ *
4
+ * Architecture inspired by Vuesax v3 (MIT License)
5
+ * Built with modern Tailwind CSS and CSS variables
6
+ * Uses Reka UI primitives with data attributes
7
+ */
8
+
9
+ /* ============================================ */
10
+ /* Base Checkbox Root */
11
+ /* ============================================ */
12
+
13
+ .vif-checkbox {
14
+ @apply relative inline-flex items-center justify-center;
15
+
16
+ /* Spacing */
17
+ margin-left: 5px;
18
+ margin-right: 5px;
19
+
20
+ /* Cursor */
21
+ cursor: var(--cursor-interactive);
22
+ }
23
+
24
+ /* ============================================ */
25
+ /* Checkbox Box (Visual Square) */
26
+ /* ============================================ */
27
+
28
+ .vif-checkbox__box {
29
+ @apply relative flex items-center justify-center;
30
+ @apply rounded-sm overflow-hidden;
31
+
32
+ /* Size - default (overridden by size variants) */
33
+ width: 20px;
34
+ height: 20px;
35
+
36
+ /* Border */
37
+ border: 2px solid rgb(180, 180, 180);
38
+
39
+ /* Animation */
40
+ transition: all 0.2s var(--ease-smooth);
41
+ transform: rotate(-90deg);
42
+ transform-origin: center;
43
+
44
+ /* Box model */
45
+ box-sizing: border-box;
46
+ }
47
+
48
+ /* ============================================ */
49
+ /* Checkbox Check Background (Animated Slide) */
50
+ /* ============================================ */
51
+
52
+ .vif-checkbox__check {
53
+ @apply absolute inset-0;
54
+
55
+ /* Initial state - hidden to the right */
56
+ transform: translate(100%);
57
+ transform-origin: right;
58
+
59
+ /* Animation */
60
+ transition: all 0.2s var(--ease-smooth);
61
+
62
+ z-index: 10;
63
+ }
64
+
65
+ /* ============================================ */
66
+ /* Checkbox Indicator (Icon Wrapper) */
67
+ /* ============================================ */
68
+
69
+ .vif-checkbox__indicator {
70
+ @apply flex items-center justify-center;
71
+
72
+ /* Initial state - hidden */
73
+ opacity: 0;
74
+ transform: translate(30px);
75
+
76
+ /* Animation */
77
+ transition: all 0.2s ease-out;
78
+ backface-visibility: visible;
79
+ transform-origin: center;
80
+
81
+ /* Size */
82
+ font-size: 1.125em;
83
+
84
+ z-index: 100;
85
+ }
86
+
87
+ /* ============================================ */
88
+ /* Checked State */
89
+ /* ============================================ */
90
+
91
+ .vif-checkbox[data-state="checked"],
92
+ .vif-checkbox[data-state="indeterminate"] {
93
+ .vif-checkbox__box {
94
+ /* Rotate to upright position */
95
+ transform: rotate(0deg);
96
+ }
97
+
98
+ .vif-checkbox__check {
99
+ /* Slide in from right */
100
+ transform: translate(0%);
101
+ }
102
+
103
+ .vif-checkbox__indicator {
104
+ /* Fade and slide in */
105
+ opacity: 1;
106
+ transform: translate(0);
107
+ color: rgb(255, 255, 255);
108
+ }
109
+ }
110
+
111
+ /* ============================================ */
112
+ /* Active State (Click Animation) */
113
+ /* ============================================ */
114
+
115
+ .vif-checkbox[data-state="checked"]:active,
116
+ .vif-checkbox[data-state="indeterminate"]:active {
117
+ .vif-checkbox__check {
118
+ transform: translate(3px);
119
+ }
120
+
121
+ .vif-checkbox__indicator {
122
+ transform: translate(6px);
123
+ }
124
+ }
125
+
126
+ /* ============================================ */
127
+ /* Disabled State */
128
+ /* ============================================ */
129
+
130
+ .vif-checkbox[data-disabled] {
131
+ opacity: var(--disabled-opacity);
132
+ cursor: var(--cursor-disabled);
133
+ pointer-events: none;
134
+
135
+ .vif-checkbox__box {
136
+ cursor: var(--cursor-disabled);
137
+ }
138
+ }
139
+
140
+ /* ============================================ */
141
+ /* Size Variants */
142
+ /* ============================================ */
143
+
144
+ .vif-checkbox--sm {
145
+ .vif-checkbox__box {
146
+ width: 15px;
147
+ height: 15px;
148
+ }
149
+
150
+ .vif-checkbox__indicator {
151
+ font-size: 0.7rem;
152
+ }
153
+ }
154
+
155
+ .vif-checkbox--md {
156
+ .vif-checkbox__box {
157
+ width: 20px;
158
+ height: 20px;
159
+ }
160
+
161
+ .vif-checkbox__indicator {
162
+ font-size: 1.125em;
163
+ }
164
+ }
165
+
166
+ .vif-checkbox--lg {
167
+ .vif-checkbox__box {
168
+ width: 24px;
169
+ height: 24px;
170
+ }
171
+
172
+ .vif-checkbox__indicator {
173
+ font-size: 1.25em;
174
+ }
175
+ }
176
+
177
+ /* ============================================ */
178
+ /* Color Variants */
179
+ /* ============================================ */
180
+
181
+ /* Brand */
182
+ .vif-checkbox--brand[data-state="checked"],
183
+ .vif-checkbox--brand[data-state="indeterminate"] {
184
+ .vif-checkbox__box {
185
+ border-color: var(--primary);
186
+ background: var(--primary);
187
+ }
188
+
189
+ .vif-checkbox__check {
190
+ background: var(--primary);
191
+ }
192
+ }
193
+
194
+ /* Success */
195
+ .vif-checkbox--success[data-state="checked"],
196
+ .vif-checkbox--success[data-state="indeterminate"] {
197
+ .vif-checkbox__box {
198
+ border-color: var(--success);
199
+ background: var(--success);
200
+ }
201
+
202
+ .vif-checkbox__check {
203
+ background: var(--success);
204
+ }
205
+ }
206
+
207
+ /* Warning */
208
+ .vif-checkbox--warning[data-state="checked"],
209
+ .vif-checkbox--warning[data-state="indeterminate"] {
210
+ .vif-checkbox__box {
211
+ border-color: var(--warning);
212
+ background: var(--warning);
213
+ }
214
+
215
+ .vif-checkbox__check {
216
+ background: var(--warning);
217
+ }
218
+ }
219
+
220
+ /* Danger */
221
+ .vif-checkbox--danger[data-state="checked"],
222
+ .vif-checkbox--danger[data-state="indeterminate"] {
223
+ .vif-checkbox__box {
224
+ border-color: var(--danger);
225
+ background: var(--danger);
226
+ }
227
+
228
+ .vif-checkbox__check {
229
+ background: var(--danger);
230
+ }
231
+ }
232
+
233
+ /* Neutral */
234
+ .vif-checkbox--neutral[data-state="checked"],
235
+ .vif-checkbox--neutral[data-state="indeterminate"] {
236
+ .vif-checkbox__box {
237
+ border-color: var(--foreground);
238
+ background: var(--foreground);
239
+ }
240
+
241
+ .vif-checkbox__check {
242
+ background: var(--foreground);
243
+ }
244
+ }
245
+
246
+ /* ============================================ */
247
+ /* Checkbox Group */
248
+ /* ============================================ */
249
+
250
+ .vif-checkbox-group {
251
+ @apply flex gap-4;
252
+ }
253
+
254
+ /* Vertical orientation (default) */
255
+ .vif-checkbox-group--vertical {
256
+ @apply flex-col;
257
+ }
258
+
259
+ /* Horizontal orientation */
260
+ .vif-checkbox-group--horizontal {
261
+ @apply flex-row flex-wrap;
262
+ }
263
+
264
+ /* Group item wrapper */
265
+ .vif-checkbox-group__item {
266
+ @apply flex items-center gap-2;
267
+ }
268
+
269
+ /* ============================================ */
270
+ /* Checkbox Label */
271
+ /* ============================================ */
272
+
273
+ .vif-checkbox__label {
274
+ @apply text-sm cursor-pointer select-none;
275
+ color: var(--foreground);
276
+
277
+ /* Spacing */
278
+ margin-left: 8px;
279
+ }
280
+
281
+ .vif-checkbox[data-disabled] + .vif-checkbox__label {
282
+ opacity: var(--disabled-opacity);
283
+ cursor: var(--cursor-disabled);
284
+ }
285
+
286
+ /* ============================================ */
287
+ /* Focus Styles */
288
+ /* ============================================ */
289
+
290
+ .vif-checkbox:focus-visible .vif-checkbox__box {
291
+ outline: 2px solid var(--focus);
292
+ outline-offset: 2px;
293
+ }