tailuicss 1.0.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.
@@ -0,0 +1,74 @@
1
+ @layer components {
2
+ /* Base */
3
+ .ui-file-input {
4
+ @apply relative flex items-center justify-center w-full border-2 border-dashed border-gray-300 rounded-xl bg-gray-50 cursor-pointer transition-all duration-200 hover:border-blue-400 hover:bg-blue-50/30;
5
+ min-height: 8rem;
6
+ }
7
+
8
+ .ui-file-input input[type="file"] {
9
+ @apply absolute inset-0 w-full h-full opacity-0 cursor-pointer;
10
+ }
11
+
12
+ /* Content */
13
+ .ui-file-input .ui-placeholder {
14
+ @apply flex flex-col items-center gap-2 text-center pointer-events-none;
15
+ }
16
+
17
+ .ui-file-input .ui-icon {
18
+ @apply text-gray-400 text-3xl;
19
+ }
20
+
21
+ .ui-file-input .ui-text {
22
+ @apply text-sm text-gray-500;
23
+ }
24
+
25
+ .ui-file-input .ui-hint {
26
+ @apply text-xs text-gray-400;
27
+ }
28
+
29
+ /* Drag active */
30
+ .ui-file-input.ui-dragover {
31
+ @apply border-blue-500 bg-blue-50;
32
+ }
33
+
34
+ /* Compact */
35
+ .ui-file-input.ui-compact {
36
+ @apply flex-row gap-3 px-4;
37
+ min-height: 3rem;
38
+ }
39
+
40
+ .ui-file-input.ui-compact .ui-placeholder {
41
+ @apply flex-row;
42
+ }
43
+
44
+ /* Error */
45
+ .ui-file-input.ui-error {
46
+ @apply border-red-300 bg-red-50/30 hover:border-red-400;
47
+ }
48
+
49
+ /* Disabled */
50
+ .ui-file-input.ui-disabled {
51
+ @apply opacity-50 cursor-not-allowed hover:border-gray-300 hover:bg-gray-50;
52
+ }
53
+
54
+ /* Dark mode */
55
+ [data-theme="dark"] .ui-file-input {
56
+ @apply border-gray-600 bg-gray-800/50 hover:border-blue-500 hover:bg-blue-900/20;
57
+ }
58
+
59
+ [data-theme="dark"] .ui-file-input .ui-icon {
60
+ @apply text-gray-500;
61
+ }
62
+
63
+ [data-theme="dark"] .ui-file-input .ui-text {
64
+ @apply text-gray-400;
65
+ }
66
+
67
+ [data-theme="dark"] .ui-file-input .ui-hint {
68
+ @apply text-gray-500;
69
+ }
70
+
71
+ [data-theme="dark"] .ui-file-input.ui-dragover {
72
+ @apply border-blue-400 bg-blue-900/30;
73
+ }
74
+ }
@@ -0,0 +1,85 @@
1
+ @layer components {
2
+ /* Base */
3
+ .ui-input {
4
+ @apply w-full px-4 py-2.5 rounded-lg border border-gray-300 bg-white text-gray-900 text-sm transition-all duration-200 outline-none;
5
+ @style {
6
+ --ui-input-ring: theme('colors.blue.500');
7
+ }
8
+ }
9
+
10
+ .ui-input:focus {
11
+ @apply border-blue-500 ring-2 ring-blue-500/20;
12
+ }
13
+
14
+ .ui-input::placeholder {
15
+ @apply text-gray-400;
16
+ }
17
+
18
+ /* Error */
19
+ .ui-input.ui-error {
20
+ @apply border-red-500 text-red-900;
21
+ }
22
+
23
+ .ui-input.ui-error:focus {
24
+ @apply ring-red-500/20 border-red-500;
25
+ }
26
+
27
+ /* Success */
28
+ .ui-input.ui-success {
29
+ @apply border-green-500;
30
+ }
31
+
32
+ .ui-input.ui-success:focus {
33
+ @apply ring-green-500/20 border-green-500;
34
+ }
35
+
36
+ /* Disabled */
37
+ .ui-input.ui-disabled {
38
+ @apply bg-gray-100 text-gray-400 cursor-not-allowed;
39
+ }
40
+
41
+ /* Sizes */
42
+ .ui-input.ui-sm {
43
+ @apply text-xs px-3 py-1.5;
44
+ }
45
+
46
+ .ui-input.ui-lg {
47
+ @apply text-base px-5 py-3;
48
+ }
49
+
50
+ /* Label */
51
+ .ui-label {
52
+ @apply block text-sm font-medium text-gray-700 mb-1.5;
53
+ }
54
+
55
+ /* Helper text */
56
+ .ui-helper {
57
+ @apply text-xs text-gray-500 mt-1;
58
+ }
59
+
60
+ .ui-helper.ui-error {
61
+ @apply text-red-500;
62
+ }
63
+
64
+ /* Input group */
65
+ .ui-input-group {
66
+ @apply flex flex-col gap-1;
67
+ }
68
+
69
+ /* Dark mode */
70
+ [data-theme="dark"] .ui-input {
71
+ @apply bg-gray-800 border-gray-600 text-white;
72
+ }
73
+
74
+ [data-theme="dark"] .ui-input::placeholder {
75
+ @apply text-gray-500;
76
+ }
77
+
78
+ [data-theme="dark"] .ui-label {
79
+ @apply text-gray-300;
80
+ }
81
+
82
+ [data-theme="dark"] .ui-helper {
83
+ @apply text-gray-400;
84
+ }
85
+ }
@@ -0,0 +1,81 @@
1
+ @layer components {
2
+ /* Base */
3
+ .ui-list {
4
+ @apply flex flex-col divide-y divide-gray-200 border border-gray-200 rounded-xl overflow-hidden;
5
+ }
6
+
7
+ /* Item */
8
+ .ui-list-item {
9
+ @apply flex items-center gap-3 px-4 py-3 bg-white text-sm text-gray-800;
10
+ }
11
+
12
+ /* Interactive */
13
+ .ui-list.ui-interactive .ui-list-item {
14
+ @apply cursor-pointer transition-colors duration-150 hover:bg-gray-50;
15
+ }
16
+
17
+ .ui-list.ui-interactive .ui-list-item:active {
18
+ @apply bg-gray-100;
19
+ }
20
+
21
+ /* Selected */
22
+ .ui-list-item.ui-selected {
23
+ @apply bg-blue-50 text-blue-700;
24
+ }
25
+
26
+ /* Slots */
27
+ .ui-list-item .ui-leading {
28
+ @apply shrink-0;
29
+ }
30
+
31
+ .ui-list-item .ui-content {
32
+ @apply flex-1 min-w-0;
33
+ }
34
+
35
+ .ui-list-item .ui-trailing {
36
+ @apply shrink-0 text-gray-400;
37
+ }
38
+
39
+ .ui-list-item .ui-title {
40
+ @apply font-medium truncate;
41
+ }
42
+
43
+ .ui-list-item .ui-subtitle {
44
+ @apply text-xs text-gray-500 truncate;
45
+ }
46
+
47
+ /* Flush (no border) */
48
+ .ui-list.ui-flush {
49
+ @apply border-none rounded-none;
50
+ }
51
+
52
+ /* Compact */
53
+ .ui-list.ui-compact .ui-list-item {
54
+ @apply px-3 py-2 text-xs;
55
+ }
56
+
57
+ /* Dark mode */
58
+ [data-theme="dark"] .ui-list {
59
+ @apply border-gray-700 divide-gray-700;
60
+ }
61
+
62
+ [data-theme="dark"] .ui-list-item {
63
+ @apply bg-gray-900 text-gray-200;
64
+ }
65
+
66
+ [data-theme="dark"] .ui-list.ui-interactive .ui-list-item:hover {
67
+ @apply bg-gray-800;
68
+ }
69
+
70
+ [data-theme="dark"] .ui-list-item.ui-selected {
71
+ @apply bg-blue-900/30 text-blue-300;
72
+ }
73
+
74
+ [data-theme="dark"] .ui-list-item .ui-subtitle {
75
+ @apply text-gray-500;
76
+ }
77
+
78
+ [data-theme="dark"] .ui-list-item .ui-trailing {
79
+ @apply text-gray-600;
80
+ }
81
+ }
@@ -0,0 +1,65 @@
1
+ @layer components {
2
+ /* Overlay */
3
+ .ui-overlay {
4
+ @apply fixed inset-0 bg-black/50 z-40 flex items-center justify-center;
5
+ @style {
6
+ backdrop-filter: blur(var(--ui-overlay-blur, 4px));
7
+ }
8
+ }
9
+
10
+ /* Modal base */
11
+ .ui-modal {
12
+ @apply bg-white rounded-2xl shadow-2xl z-50 w-full max-w-lg mx-4 overflow-hidden;
13
+ @style {
14
+ max-height: var(--ui-modal-max-height, 85vh);
15
+ }
16
+ }
17
+
18
+ /* Sizes */
19
+ .ui-modal.ui-sm {
20
+ @apply max-w-sm;
21
+ }
22
+
23
+ .ui-modal.ui-lg {
24
+ @apply max-w-2xl;
25
+ }
26
+
27
+ .ui-modal.ui-xl {
28
+ @apply max-w-4xl;
29
+ }
30
+
31
+ .ui-modal.ui-full {
32
+ @apply max-w-none mx-0 rounded-none h-screen;
33
+ }
34
+
35
+ /* Modal slots (reuses card slots) */
36
+ .ui-modal .ui-header {
37
+ @apply px-6 py-4 border-b border-gray-100 font-semibold text-lg;
38
+ }
39
+
40
+ .ui-modal .ui-body {
41
+ @apply p-6 overflow-y-auto;
42
+ }
43
+
44
+ .ui-modal .ui-footer {
45
+ @apply px-6 py-4 border-t border-gray-100 flex justify-end gap-3;
46
+ }
47
+
48
+ /* Centered variant */
49
+ .ui-modal.ui-centered .ui-body {
50
+ @apply text-center;
51
+ }
52
+
53
+ /* Dark mode */
54
+ [data-theme="dark"] .ui-modal {
55
+ @apply bg-gray-900 text-white;
56
+ }
57
+
58
+ [data-theme="dark"] .ui-modal .ui-header {
59
+ @apply border-gray-700;
60
+ }
61
+
62
+ [data-theme="dark"] .ui-modal .ui-footer {
63
+ @apply border-gray-700;
64
+ }
65
+ }
@@ -0,0 +1,84 @@
1
+ @layer components {
2
+ /* Base */
3
+ .ui-progress {
4
+ @apply w-full bg-gray-200 rounded-full overflow-hidden;
5
+ height: 0.5rem;
6
+ }
7
+
8
+ .ui-progress .ui-bar {
9
+ @apply h-full rounded-full transition-all duration-500 ease-out;
10
+ @style {
11
+ width: var(--ui-progress-value, 0%);
12
+ }
13
+ }
14
+
15
+ /* Colors */
16
+ .ui-progress .ui-bar {
17
+ @apply bg-blue-600;
18
+ }
19
+
20
+ .ui-progress.ui-success .ui-bar {
21
+ @apply bg-green-500;
22
+ }
23
+
24
+ .ui-progress.ui-warning .ui-bar {
25
+ @apply bg-yellow-500;
26
+ }
27
+
28
+ .ui-progress.ui-danger .ui-bar {
29
+ @apply bg-red-500;
30
+ }
31
+
32
+ /* Sizes */
33
+ .ui-progress.ui-sm {
34
+ height: 0.25rem;
35
+ }
36
+
37
+ .ui-progress.ui-lg {
38
+ height: 0.75rem;
39
+ }
40
+
41
+ .ui-progress.ui-xl {
42
+ height: 1rem;
43
+ }
44
+
45
+ /* Striped */
46
+ .ui-progress.ui-striped .ui-bar {
47
+ background-image: linear-gradient(
48
+ 45deg,
49
+ rgba(255, 255, 255, 0.15) 25%,
50
+ transparent 25%,
51
+ transparent 50%,
52
+ rgba(255, 255, 255, 0.15) 50%,
53
+ rgba(255, 255, 255, 0.15) 75%,
54
+ transparent 75%,
55
+ transparent
56
+ );
57
+ background-size: 1rem 1rem;
58
+ }
59
+
60
+ /* Animated */
61
+ .ui-progress.ui-animated .ui-bar {
62
+ animation: ui-progress-stripes 1s linear infinite;
63
+ }
64
+
65
+ @keyframes ui-progress-stripes {
66
+ from { background-position: 1rem 0; }
67
+ to { background-position: 0 0; }
68
+ }
69
+
70
+ /* Label */
71
+ .ui-progress.ui-labeled {
72
+ @apply relative;
73
+ height: 1.25rem;
74
+ }
75
+
76
+ .ui-progress.ui-labeled .ui-bar {
77
+ @apply flex items-center justify-center text-xs font-medium text-white;
78
+ }
79
+
80
+ /* Dark mode */
81
+ [data-theme="dark"] .ui-progress {
82
+ @apply bg-gray-700;
83
+ }
84
+ }
@@ -0,0 +1,68 @@
1
+ @layer components {
2
+ /* Radio group */
3
+ .ui-radio-group {
4
+ @apply flex flex-col gap-2;
5
+ }
6
+
7
+ .ui-radio-group.ui-horizontal {
8
+ @apply flex-row gap-4;
9
+ }
10
+
11
+ /* Radio item */
12
+ .ui-radio {
13
+ @apply inline-flex items-center gap-2 cursor-pointer text-sm text-gray-700;
14
+ }
15
+
16
+ .ui-radio input[type="radio"] {
17
+ @apply w-4 h-4 border-2 border-gray-300 rounded-full appearance-none cursor-pointer transition-all duration-150;
18
+ }
19
+
20
+ .ui-radio input[type="radio"]:checked {
21
+ @apply border-blue-600;
22
+ box-shadow: inset 0 0 0 3px white, inset 0 0 0 6px currentColor;
23
+ color: theme('colors.blue.600');
24
+ }
25
+
26
+ .ui-radio input[type="radio"]:focus-visible {
27
+ @apply ring-2 ring-blue-500/20 ring-offset-1;
28
+ }
29
+
30
+ /* Disabled */
31
+ .ui-radio.ui-disabled {
32
+ @apply opacity-50 cursor-not-allowed;
33
+ }
34
+
35
+ .ui-radio.ui-disabled input[type="radio"] {
36
+ @apply cursor-not-allowed;
37
+ }
38
+
39
+ /* Sizes */
40
+ .ui-radio.ui-sm {
41
+ @apply text-xs;
42
+ }
43
+
44
+ .ui-radio.ui-sm input[type="radio"] {
45
+ @apply w-3.5 h-3.5;
46
+ }
47
+
48
+ .ui-radio.ui-lg {
49
+ @apply text-base;
50
+ }
51
+
52
+ .ui-radio.ui-lg input[type="radio"] {
53
+ @apply w-5 h-5;
54
+ }
55
+
56
+ /* Dark mode */
57
+ [data-theme="dark"] .ui-radio {
58
+ @apply text-gray-300;
59
+ }
60
+
61
+ [data-theme="dark"] .ui-radio input[type="radio"] {
62
+ @apply border-gray-600;
63
+ }
64
+
65
+ [data-theme="dark"] .ui-radio input[type="radio"]:checked {
66
+ box-shadow: inset 0 0 0 3px theme('colors.gray.900'), inset 0 0 0 6px currentColor;
67
+ }
68
+ }
@@ -0,0 +1,76 @@
1
+ @layer components {
2
+ /* Base */
3
+ .ui-rate {
4
+ @apply inline-flex items-center gap-1;
5
+ }
6
+
7
+ /* Star */
8
+ .ui-rate .ui-star {
9
+ @apply cursor-pointer transition-colors duration-150 text-gray-300;
10
+ font-size: 1.5rem;
11
+ line-height: 1;
12
+ }
13
+
14
+ .ui-rate .ui-star::before {
15
+ content: '\2605';
16
+ }
17
+
18
+ .ui-rate .ui-star.ui-active {
19
+ @apply text-yellow-400;
20
+ }
21
+
22
+ .ui-rate .ui-star:hover {
23
+ @apply text-yellow-300;
24
+ }
25
+
26
+ /* Readonly */
27
+ .ui-rate.ui-readonly .ui-star {
28
+ @apply cursor-default;
29
+ }
30
+
31
+ .ui-rate.ui-readonly .ui-star:hover {
32
+ @apply text-gray-300;
33
+ }
34
+
35
+ .ui-rate.ui-readonly .ui-star.ui-active:hover {
36
+ @apply text-yellow-400;
37
+ }
38
+
39
+ /* Sizes */
40
+ .ui-rate.ui-sm .ui-star {
41
+ font-size: 1rem;
42
+ }
43
+
44
+ .ui-rate.ui-lg .ui-star {
45
+ font-size: 2rem;
46
+ }
47
+
48
+ /* Half star support */
49
+ .ui-rate .ui-star.ui-half {
50
+ @apply relative text-gray-300;
51
+ }
52
+
53
+ .ui-rate .ui-star.ui-half::after {
54
+ content: '\2605';
55
+ @apply absolute inset-0 text-yellow-400 overflow-hidden;
56
+ width: 50%;
57
+ }
58
+
59
+ /* Disabled */
60
+ .ui-rate.ui-disabled {
61
+ @apply opacity-50 pointer-events-none;
62
+ }
63
+
64
+ /* Dark mode */
65
+ [data-theme="dark"] .ui-rate .ui-star {
66
+ @apply text-gray-600;
67
+ }
68
+
69
+ [data-theme="dark"] .ui-rate .ui-star.ui-active {
70
+ @apply text-yellow-400;
71
+ }
72
+
73
+ [data-theme="dark"] .ui-rate .ui-star:hover {
74
+ @apply text-yellow-300;
75
+ }
76
+ }
@@ -0,0 +1,125 @@
1
+ @layer components {
2
+ /* Base */
3
+ .ui-select {
4
+ @apply relative w-full;
5
+ }
6
+
7
+ /* Trigger */
8
+ .ui-select .ui-select-trigger {
9
+ @apply w-full flex items-center justify-between px-4 py-2.5 rounded-lg border border-gray-300 bg-white text-gray-900 text-sm cursor-pointer transition-all duration-200;
10
+ }
11
+
12
+ .ui-select .ui-select-trigger:focus,
13
+ .ui-select.ui-open .ui-select-trigger {
14
+ @apply border-blue-500 ring-2 ring-blue-500/20;
15
+ }
16
+
17
+ .ui-select .ui-select-trigger .ui-placeholder {
18
+ @apply text-gray-400;
19
+ }
20
+
21
+ .ui-select .ui-select-trigger::after {
22
+ content: '';
23
+ @apply w-2 h-2 border-r-2 border-b-2 border-gray-400 rotate-45 transition-transform duration-200 shrink-0 ml-2;
24
+ }
25
+
26
+ .ui-select.ui-open .ui-select-trigger::after {
27
+ @apply -rotate-[135deg];
28
+ }
29
+
30
+ /* Dropdown */
31
+ .ui-select .ui-select-menu {
32
+ @apply absolute z-50 w-full mt-1 bg-white border border-gray-200 rounded-xl shadow-lg py-1 max-h-60 overflow-y-auto opacity-0 invisible transition-all duration-150;
33
+ }
34
+
35
+ .ui-select.ui-open .ui-select-menu {
36
+ @apply opacity-100 visible;
37
+ }
38
+
39
+ /* Option */
40
+ .ui-select .ui-option {
41
+ @apply flex items-center gap-2 px-4 py-2 text-sm text-gray-700 cursor-pointer transition-colors duration-100 hover:bg-gray-50;
42
+ }
43
+
44
+ .ui-select .ui-option.ui-selected {
45
+ @apply bg-blue-50 text-blue-700 font-medium;
46
+ }
47
+
48
+ .ui-select .ui-option.ui-disabled {
49
+ @apply opacity-50 cursor-not-allowed hover:bg-transparent;
50
+ }
51
+
52
+ /* Group */
53
+ .ui-select .ui-option-group {
54
+ @apply px-4 py-2 text-xs font-semibold text-gray-400 uppercase tracking-wider;
55
+ }
56
+
57
+ /* States */
58
+ .ui-select.ui-error .ui-select-trigger {
59
+ @apply border-red-500;
60
+ }
61
+
62
+ .ui-select.ui-disabled .ui-select-trigger {
63
+ @apply bg-gray-100 text-gray-400 cursor-not-allowed;
64
+ }
65
+
66
+ /* Sizes */
67
+ .ui-select.ui-sm .ui-select-trigger {
68
+ @apply text-xs px-3 py-1.5;
69
+ }
70
+
71
+ .ui-select.ui-lg .ui-select-trigger {
72
+ @apply text-base px-5 py-3;
73
+ }
74
+
75
+ /* Search variant */
76
+ .ui-select .ui-search-input {
77
+ @apply w-full px-4 py-2 border-b border-gray-100 text-sm outline-none bg-transparent;
78
+ }
79
+
80
+ .ui-select .ui-search-input::placeholder {
81
+ @apply text-gray-400;
82
+ }
83
+
84
+ .ui-select .ui-no-results {
85
+ @apply px-4 py-3 text-sm text-gray-400 text-center;
86
+ }
87
+
88
+ /* Multi-select */
89
+ .ui-select.ui-multi .ui-select-trigger {
90
+ @apply flex-wrap gap-1;
91
+ }
92
+
93
+ .ui-select .ui-tag {
94
+ @apply inline-flex items-center gap-1 px-2 py-0.5 bg-blue-100 text-blue-800 text-xs rounded-md;
95
+ }
96
+
97
+ .ui-select .ui-tag .ui-remove {
98
+ @apply cursor-pointer opacity-60 hover:opacity-100;
99
+ }
100
+
101
+ /* Dark mode */
102
+ [data-theme="dark"] .ui-select .ui-select-trigger {
103
+ @apply bg-gray-800 border-gray-600 text-white;
104
+ }
105
+
106
+ [data-theme="dark"] .ui-select .ui-select-menu {
107
+ @apply bg-gray-800 border-gray-700;
108
+ }
109
+
110
+ [data-theme="dark"] .ui-select .ui-option {
111
+ @apply text-gray-300 hover:bg-gray-700;
112
+ }
113
+
114
+ [data-theme="dark"] .ui-select .ui-option.ui-selected {
115
+ @apply bg-blue-900/30 text-blue-300;
116
+ }
117
+
118
+ [data-theme="dark"] .ui-select .ui-search-input {
119
+ @apply border-gray-700 text-white;
120
+ }
121
+
122
+ [data-theme="dark"] .ui-select .ui-tag {
123
+ @apply bg-blue-900/50 text-blue-300;
124
+ }
125
+ }