@rovula/ui 0.0.7 → 0.0.9
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/dist/cjs/bundle.css +136 -33
- package/dist/cjs/bundle.js +1 -1
- package/dist/cjs/bundle.js.map +1 -1
- package/dist/cjs/types/components/Dropdown/Dropdown.d.ts +26 -0
- package/dist/cjs/types/components/Dropdown/Dropdown.stories.d.ts +367 -0
- package/dist/cjs/types/components/Dropdown/Dropdown.styles.d.ts +11 -0
- package/dist/cjs/types/components/TextInput/TextInput.d.ts +3 -2
- package/dist/cjs/types/components/TextInput/TextInput.stories.d.ts +2 -16
- package/dist/cjs/types/components/TextInput/TextInput.styles.d.ts +0 -1
- package/dist/cjs/types/index.d.ts +1 -0
- package/dist/components/Dropdown/Dropdown.js +58 -0
- package/dist/components/Dropdown/Dropdown.stories.js +43 -0
- package/dist/components/Dropdown/Dropdown.styles.js +47 -0
- package/dist/components/TextInput/TextInput.js +3 -5
- package/dist/components/TextInput/TextInput.stories.js +1 -1
- package/dist/components/TextInput/TextInput.styles.js +13 -21
- package/dist/esm/bundle.css +136 -33
- package/dist/esm/bundle.js +1 -1
- package/dist/esm/bundle.js.map +1 -1
- package/dist/esm/types/components/Dropdown/Dropdown.d.ts +26 -0
- package/dist/esm/types/components/Dropdown/Dropdown.stories.d.ts +367 -0
- package/dist/esm/types/components/Dropdown/Dropdown.styles.d.ts +11 -0
- package/dist/esm/types/components/TextInput/TextInput.d.ts +3 -2
- package/dist/esm/types/components/TextInput/TextInput.stories.d.ts +2 -16
- package/dist/esm/types/components/TextInput/TextInput.styles.d.ts +0 -1
- package/dist/esm/types/index.d.ts +1 -0
- package/dist/index.d.ts +29 -2
- package/dist/index.js +1 -0
- package/dist/src/theme/global.css +170 -38
- package/package.json +1 -1
- package/src/components/Dropdown/Dropdown.stories.tsx +49 -0
- package/src/components/Dropdown/Dropdown.styles.ts +54 -0
- package/src/components/Dropdown/Dropdown.tsx +151 -0
- package/src/components/TextInput/TextInput.stories.tsx +3 -3
- package/src/components/TextInput/TextInput.styles.ts +13 -21
- package/src/components/TextInput/TextInput.tsx +14 -5
- package/src/index.ts +1 -0
|
@@ -812,12 +812,8 @@ video {
|
|
|
812
812
|
right: 0px;
|
|
813
813
|
}
|
|
814
814
|
|
|
815
|
-
.
|
|
816
|
-
|
|
817
|
-
}
|
|
818
|
-
|
|
819
|
-
.top-4 {
|
|
820
|
-
top: 1rem;
|
|
815
|
+
.z-10 {
|
|
816
|
+
z-index: 10;
|
|
821
817
|
}
|
|
822
818
|
|
|
823
819
|
.z-50 {
|
|
@@ -854,6 +850,10 @@ video {
|
|
|
854
850
|
margin-top: 6px;
|
|
855
851
|
}
|
|
856
852
|
|
|
853
|
+
.box-border {
|
|
854
|
+
box-sizing: border-box;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
857
|
.block {
|
|
858
858
|
display: block;
|
|
859
859
|
}
|
|
@@ -893,6 +893,20 @@ video {
|
|
|
893
893
|
height: 1.25rem;
|
|
894
894
|
}
|
|
895
895
|
|
|
896
|
+
.size-6 {
|
|
897
|
+
width: 1.5rem;
|
|
898
|
+
height: 1.5rem;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
.size-\[14px\] {
|
|
902
|
+
width: 14px;
|
|
903
|
+
height: 14px;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
.max-h-60 {
|
|
907
|
+
max-height: 15rem;
|
|
908
|
+
}
|
|
909
|
+
|
|
896
910
|
.w-\[200px\] {
|
|
897
911
|
width: 200px;
|
|
898
912
|
}
|
|
@@ -901,6 +915,10 @@ video {
|
|
|
901
915
|
width: 400px;
|
|
902
916
|
}
|
|
903
917
|
|
|
918
|
+
.w-auto {
|
|
919
|
+
width: auto;
|
|
920
|
+
}
|
|
921
|
+
|
|
904
922
|
.w-full {
|
|
905
923
|
width: 100%;
|
|
906
924
|
}
|
|
@@ -909,6 +927,11 @@ video {
|
|
|
909
927
|
max-width: 48rem;
|
|
910
928
|
}
|
|
911
929
|
|
|
930
|
+
.rotate-180 {
|
|
931
|
+
--tw-rotate: 180deg;
|
|
932
|
+
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
933
|
+
}
|
|
934
|
+
|
|
912
935
|
.cursor-pointer {
|
|
913
936
|
cursor: pointer;
|
|
914
937
|
}
|
|
@@ -974,6 +997,10 @@ video {
|
|
|
974
997
|
overflow-x: auto;
|
|
975
998
|
}
|
|
976
999
|
|
|
1000
|
+
.overflow-y-auto {
|
|
1001
|
+
overflow-y: auto;
|
|
1002
|
+
}
|
|
1003
|
+
|
|
977
1004
|
.whitespace-nowrap {
|
|
978
1005
|
white-space: nowrap;
|
|
979
1006
|
}
|
|
@@ -1002,6 +1029,10 @@ video {
|
|
|
1002
1029
|
border-radius: 0.5rem;
|
|
1003
1030
|
}
|
|
1004
1031
|
|
|
1032
|
+
.rounded-md {
|
|
1033
|
+
border-radius: 0.375rem;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1005
1036
|
.rounded-none {
|
|
1006
1037
|
border-radius: 0px;
|
|
1007
1038
|
}
|
|
@@ -1031,6 +1062,11 @@ video {
|
|
|
1031
1062
|
border-color: rgb(var(--error-100) / var(--tw-border-opacity));
|
|
1032
1063
|
}
|
|
1033
1064
|
|
|
1065
|
+
.border-gray-300 {
|
|
1066
|
+
--tw-border-opacity: 1;
|
|
1067
|
+
border-color: rgb(209 213 219 / var(--tw-border-opacity));
|
|
1068
|
+
}
|
|
1069
|
+
|
|
1034
1070
|
.border-info {
|
|
1035
1071
|
--tw-border-opacity: 1;
|
|
1036
1072
|
border-color: rgb(var(--info-default) / var(--tw-border-opacity));
|
|
@@ -1075,6 +1111,11 @@ video {
|
|
|
1075
1111
|
background-color: rgb(var(--error-100) / var(--tw-bg-opacity));
|
|
1076
1112
|
}
|
|
1077
1113
|
|
|
1114
|
+
.bg-gray-200 {
|
|
1115
|
+
--tw-bg-opacity: 1;
|
|
1116
|
+
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1078
1119
|
.bg-info {
|
|
1079
1120
|
--tw-bg-opacity: 1;
|
|
1080
1121
|
background-color: rgb(var(--info-default) / var(--tw-bg-opacity));
|
|
@@ -1119,6 +1160,11 @@ video {
|
|
|
1119
1160
|
background-color: rgb(var(--warning-default) / var(--tw-bg-opacity));
|
|
1120
1161
|
}
|
|
1121
1162
|
|
|
1163
|
+
.bg-white {
|
|
1164
|
+
--tw-bg-opacity: 1;
|
|
1165
|
+
background-color: rgb(255 255 255 / var(--tw-bg-opacity));
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1122
1168
|
.fill-error {
|
|
1123
1169
|
fill: rgb(var(--error-100) / 1);
|
|
1124
1170
|
}
|
|
@@ -1127,6 +1173,18 @@ video {
|
|
|
1127
1173
|
fill: rgb(var(--input-active-stroke-color) / 1);
|
|
1128
1174
|
}
|
|
1129
1175
|
|
|
1176
|
+
.fill-input-text {
|
|
1177
|
+
fill: rgb(var(--input-default-text-color) / 1);
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
.fill-input-text-active {
|
|
1181
|
+
fill: rgb(var(--input-active-text-color) / 1);
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
.fill-input-text-disabled {
|
|
1185
|
+
fill: rgb(var(--input-disabled-text-color) / 1);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1130
1188
|
.p-1 {
|
|
1131
1189
|
padding: 0.25rem;
|
|
1132
1190
|
}
|
|
@@ -1168,6 +1226,11 @@ video {
|
|
|
1168
1226
|
padding-bottom: 0.25rem;
|
|
1169
1227
|
}
|
|
1170
1228
|
|
|
1229
|
+
.py-14 {
|
|
1230
|
+
padding-top: 3.5rem;
|
|
1231
|
+
padding-bottom: 3.5rem;
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1171
1234
|
.py-2 {
|
|
1172
1235
|
padding-top: 0.5rem;
|
|
1173
1236
|
padding-bottom: 0.5rem;
|
|
@@ -1178,6 +1241,22 @@ video {
|
|
|
1178
1241
|
padding-bottom: 1rem;
|
|
1179
1242
|
}
|
|
1180
1243
|
|
|
1244
|
+
.pe-\[30px\] {
|
|
1245
|
+
padding-inline-end: 30px;
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
.pe-\[40px\] {
|
|
1249
|
+
padding-inline-end: 40px;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
.pe-\[48px\] {
|
|
1253
|
+
padding-inline-end: 48px;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
.text-center {
|
|
1257
|
+
text-align: center;
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1181
1260
|
.align-middle {
|
|
1182
1261
|
vertical-align: middle;
|
|
1183
1262
|
}
|
|
@@ -1445,6 +1524,12 @@ video {
|
|
|
1445
1524
|
text-underline-offset: 4px;
|
|
1446
1525
|
}
|
|
1447
1526
|
|
|
1527
|
+
.shadow-md {
|
|
1528
|
+
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
|
1529
|
+
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
|
|
1530
|
+
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1448
1533
|
.outline-none {
|
|
1449
1534
|
outline: 2px solid transparent;
|
|
1450
1535
|
outline-offset: 2px;
|
|
@@ -1479,6 +1564,10 @@ video {
|
|
|
1479
1564
|
--tw-ring-color: rgb(var(--input-disabled-stroke-color) / var(--tw-ring-opacity));
|
|
1480
1565
|
}
|
|
1481
1566
|
|
|
1567
|
+
.filter {
|
|
1568
|
+
filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1482
1571
|
.transition-all {
|
|
1483
1572
|
transition-property: all;
|
|
1484
1573
|
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
|
|
@@ -1663,6 +1752,11 @@ video {
|
|
|
1663
1752
|
background-color: rgb(var(--error-120) / var(--tw-bg-opacity));
|
|
1664
1753
|
}
|
|
1665
1754
|
|
|
1755
|
+
.hover\:bg-gray-100:hover {
|
|
1756
|
+
--tw-bg-opacity: 1;
|
|
1757
|
+
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1666
1760
|
.hover\:bg-info-100:hover {
|
|
1667
1761
|
--tw-bg-opacity: 1;
|
|
1668
1762
|
background-color: rgb(var(--info-100)) / var(--tw-bg-opacity));
|
|
@@ -1730,9 +1824,9 @@ video {
|
|
|
1730
1824
|
padding-inline-end: 2rem;
|
|
1731
1825
|
}
|
|
1732
1826
|
|
|
1733
|
-
.focus\:ring-
|
|
1827
|
+
.focus\:ring-1:focus {
|
|
1734
1828
|
--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
|
|
1735
|
-
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(
|
|
1829
|
+
--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
|
|
1736
1830
|
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
|
|
1737
1831
|
}
|
|
1738
1832
|
|
|
@@ -1740,73 +1834,111 @@ video {
|
|
|
1740
1834
|
--tw-ring-inset: inset;
|
|
1741
1835
|
}
|
|
1742
1836
|
|
|
1837
|
+
.focus\:ring-error:focus {
|
|
1838
|
+
--tw-ring-opacity: 1;
|
|
1839
|
+
--tw-ring-color: rgb(var(--error-100) / var(--tw-ring-opacity));
|
|
1840
|
+
}
|
|
1841
|
+
|
|
1842
|
+
.focus\:ring-input-stroke-active:focus {
|
|
1843
|
+
--tw-ring-opacity: 1;
|
|
1844
|
+
--tw-ring-color: rgb(var(--input-active-stroke-color) / var(--tw-ring-opacity));
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1743
1847
|
.active\:scale-\[98\%\]:active {
|
|
1744
1848
|
--tw-scale-x: 98%;
|
|
1745
1849
|
--tw-scale-y: 98%;
|
|
1746
1850
|
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
|
|
1747
1851
|
}
|
|
1748
1852
|
|
|
1749
|
-
.peer
|
|
1750
|
-
top:
|
|
1853
|
+
.peer:-moz-placeholder-shown ~ .peer-placeholder-shown\:top-2 {
|
|
1854
|
+
top: 0.5rem;
|
|
1751
1855
|
}
|
|
1752
1856
|
|
|
1753
|
-
.peer:
|
|
1754
|
-
top:
|
|
1857
|
+
.peer:placeholder-shown ~ .peer-placeholder-shown\:top-2 {
|
|
1858
|
+
top: 0.5rem;
|
|
1755
1859
|
}
|
|
1756
1860
|
|
|
1757
|
-
.peer
|
|
1758
|
-
|
|
1861
|
+
.peer:-moz-placeholder-shown ~ .peer-placeholder-shown\:top-4 {
|
|
1862
|
+
top: 1rem;
|
|
1759
1863
|
}
|
|
1760
1864
|
|
|
1761
|
-
.peer:
|
|
1762
|
-
|
|
1763
|
-
background-color: rgb(var(--input-label-background-color) / var(--tw-bg-opacity));
|
|
1865
|
+
.peer:placeholder-shown ~ .peer-placeholder-shown\:top-4 {
|
|
1866
|
+
top: 1rem;
|
|
1764
1867
|
}
|
|
1765
1868
|
|
|
1766
|
-
.peer
|
|
1767
|
-
|
|
1768
|
-
color: rgb(var(--input-active-text-color) / var(--tw-text-opacity));
|
|
1869
|
+
.peer:-moz-placeholder-shown ~ .peer-placeholder-shown\:bg-transparent {
|
|
1870
|
+
background-color: transparent;
|
|
1769
1871
|
}
|
|
1770
1872
|
|
|
1771
|
-
.peer:
|
|
1772
|
-
|
|
1773
|
-
|
|
1873
|
+
.peer:placeholder-shown ~ .peer-placeholder-shown\:bg-transparent {
|
|
1874
|
+
background-color: transparent;
|
|
1875
|
+
}
|
|
1876
|
+
|
|
1877
|
+
.peer:-moz-placeholder-shown ~ .peer-placeholder-shown\:typography-subtitile1 {
|
|
1878
|
+
font-size: 16px;
|
|
1879
|
+
line-height: 24px;
|
|
1774
1880
|
font-weight: 400;
|
|
1775
1881
|
}
|
|
1776
1882
|
|
|
1777
|
-
.peer:
|
|
1778
|
-
font-size:
|
|
1779
|
-
line-height:
|
|
1883
|
+
.peer:placeholder-shown ~ .peer-placeholder-shown\:typography-subtitile1 {
|
|
1884
|
+
font-size: 16px;
|
|
1885
|
+
line-height: 24px;
|
|
1780
1886
|
font-weight: 400;
|
|
1781
1887
|
}
|
|
1782
1888
|
|
|
1783
|
-
.peer
|
|
1784
|
-
|
|
1889
|
+
.peer:-moz-placeholder-shown ~ .peer-placeholder-shown\:typography-subtitile4 {
|
|
1890
|
+
font-size: 14px;
|
|
1891
|
+
line-height: 22px;
|
|
1892
|
+
font-weight: 400;
|
|
1785
1893
|
}
|
|
1786
1894
|
|
|
1787
|
-
.peer:
|
|
1788
|
-
|
|
1895
|
+
.peer:placeholder-shown ~ .peer-placeholder-shown\:typography-subtitile4 {
|
|
1896
|
+
font-size: 14px;
|
|
1897
|
+
line-height: 22px;
|
|
1898
|
+
font-weight: 400;
|
|
1789
1899
|
}
|
|
1790
1900
|
|
|
1791
|
-
.peer
|
|
1901
|
+
.peer:-moz-placeholder-shown ~ .peer-placeholder-shown\:typography-small1 {
|
|
1792
1902
|
font-size: 12px;
|
|
1793
|
-
line-height:
|
|
1903
|
+
line-height: 14px;
|
|
1794
1904
|
font-weight: 400;
|
|
1795
1905
|
}
|
|
1796
1906
|
|
|
1797
|
-
.peer:
|
|
1907
|
+
.peer:placeholder-shown ~ .peer-placeholder-shown\:typography-small1 {
|
|
1798
1908
|
font-size: 12px;
|
|
1799
|
-
line-height:
|
|
1909
|
+
line-height: 14px;
|
|
1800
1910
|
font-weight: 400;
|
|
1801
1911
|
}
|
|
1802
1912
|
|
|
1803
|
-
.peer:
|
|
1804
|
-
|
|
1805
|
-
|
|
1913
|
+
.peer:focus ~ .peer-focus\:-top-1 {
|
|
1914
|
+
top: -0.25rem;
|
|
1915
|
+
}
|
|
1916
|
+
|
|
1917
|
+
.peer:focus ~ .peer-focus\:-top-1\.5 {
|
|
1918
|
+
top: -0.375rem;
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
.peer:focus ~ .peer-focus\:flex {
|
|
1922
|
+
display: flex;
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1925
|
+
.peer:focus ~ .peer-focus\:bg-input-label-background {
|
|
1926
|
+
--tw-bg-opacity: 1;
|
|
1927
|
+
background-color: rgb(var(--input-label-background-color) / var(--tw-bg-opacity));
|
|
1928
|
+
}
|
|
1929
|
+
|
|
1930
|
+
.peer:focus ~ .peer-focus\:text-input-text-active {
|
|
1931
|
+
--tw-text-opacity: 1;
|
|
1932
|
+
color: rgb(var(--input-active-text-color) / var(--tw-text-opacity));
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
.peer:focus ~ .peer-focus\:typography-label1 {
|
|
1936
|
+
font-size: 12px;
|
|
1937
|
+
line-height: 12px;
|
|
1806
1938
|
font-weight: 400;
|
|
1807
1939
|
}
|
|
1808
1940
|
|
|
1809
|
-
.peer:
|
|
1941
|
+
.peer:focus ~ .peer-focus\:typography-label2 {
|
|
1810
1942
|
font-size: 10px;
|
|
1811
1943
|
line-height: 10px;
|
|
1812
1944
|
font-weight: 400;
|
package/package.json
CHANGED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
3
|
+
import Dropdown from "./Dropdown";
|
|
4
|
+
|
|
5
|
+
// More on how to set up stories at: https://storybook.js.org/docs/7.0/react/writing-stories/introduction
|
|
6
|
+
const meta = {
|
|
7
|
+
title: "Components/Dropdown",
|
|
8
|
+
component: Dropdown,
|
|
9
|
+
tags: ["autodocs"],
|
|
10
|
+
parameters: {
|
|
11
|
+
// More on how to position stories at: https://storybook.js.org/docs/7.0/react/configure/story-layout
|
|
12
|
+
layout: "fullscreen",
|
|
13
|
+
},
|
|
14
|
+
decorators: [
|
|
15
|
+
(Story) => (
|
|
16
|
+
<div className="p-5 flex w-full">
|
|
17
|
+
<Story />
|
|
18
|
+
</div>
|
|
19
|
+
),
|
|
20
|
+
],
|
|
21
|
+
} satisfies Meta<typeof Dropdown>;
|
|
22
|
+
|
|
23
|
+
export default meta;
|
|
24
|
+
|
|
25
|
+
const options = new Array(100).fill("").map((__, index) => ({
|
|
26
|
+
value: `option${index + 1}`,
|
|
27
|
+
label: `Option ${index + 1}`,
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
export const Default = {
|
|
31
|
+
args: {
|
|
32
|
+
label: "Choose an option:",
|
|
33
|
+
fullwidth: true,
|
|
34
|
+
options,
|
|
35
|
+
},
|
|
36
|
+
render: (args) => {
|
|
37
|
+
console.log("args ", args);
|
|
38
|
+
const props: typeof args = {
|
|
39
|
+
...args,
|
|
40
|
+
};
|
|
41
|
+
return (
|
|
42
|
+
<div className="flex flex-row gap-4 w-full">
|
|
43
|
+
<Dropdown id="1" size="lg" options={options} {...args} />
|
|
44
|
+
<Dropdown id="2" size="md" options={options} {...args} />
|
|
45
|
+
<Dropdown id="3" size="sm" options={options} {...args} />
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
},
|
|
49
|
+
} satisfies StoryObj;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { cva } from "class-variance-authority";
|
|
3
|
+
|
|
4
|
+
export const iconWrapperVariant = cva(
|
|
5
|
+
["absolute inset-y-0 right-0 flex items-center justify-center"],
|
|
6
|
+
{
|
|
7
|
+
variants: {
|
|
8
|
+
size: {
|
|
9
|
+
sm: "mr-2",
|
|
10
|
+
md: "mr-3",
|
|
11
|
+
lg: "mr-4",
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
defaultVariants: {
|
|
15
|
+
size: "md",
|
|
16
|
+
},
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export const dropdownIconVariant = cva(["transition-all"], {
|
|
21
|
+
variants: {
|
|
22
|
+
size: {
|
|
23
|
+
sm: "size-[14px]",
|
|
24
|
+
md: "size-5",
|
|
25
|
+
lg: "size-6",
|
|
26
|
+
},
|
|
27
|
+
disabled: {
|
|
28
|
+
true: "fill-input-text-disabled",
|
|
29
|
+
false: "fill-input-text",
|
|
30
|
+
},
|
|
31
|
+
isFocus: {
|
|
32
|
+
true: "fill-input-text-active rotate-180",
|
|
33
|
+
false: "",
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
defaultVariants: {
|
|
37
|
+
size: "md",
|
|
38
|
+
disabled: false,
|
|
39
|
+
isFocus: false,
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const customInputVariant = cva([], {
|
|
44
|
+
variants: {
|
|
45
|
+
size: {
|
|
46
|
+
sm: "pe-[30px]",
|
|
47
|
+
md: "pe-[40px]",
|
|
48
|
+
lg: "pe-[48px]",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
defaultVariants: {
|
|
52
|
+
size: "md",
|
|
53
|
+
},
|
|
54
|
+
});
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
2
|
+
|
|
3
|
+
import TextInput, { InputProps } from "../TextInput/TextInput";
|
|
4
|
+
import {
|
|
5
|
+
customInputVariant,
|
|
6
|
+
dropdownIconVariant,
|
|
7
|
+
iconWrapperVariant,
|
|
8
|
+
} from "./Dropdown.styles";
|
|
9
|
+
|
|
10
|
+
import { ChevronDownIcon } from "@heroicons/react/16/solid";
|
|
11
|
+
|
|
12
|
+
type Options = {
|
|
13
|
+
value: string;
|
|
14
|
+
label: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type DropdownProps = {
|
|
18
|
+
id?: string;
|
|
19
|
+
label?: string;
|
|
20
|
+
size?: "sm" | "md" | "lg";
|
|
21
|
+
rounded?: "none" | "normal" | "full";
|
|
22
|
+
variant?: "flat" | "outline" | "underline";
|
|
23
|
+
helperText?: string;
|
|
24
|
+
errorMessage?: string;
|
|
25
|
+
filterMode?: boolean;
|
|
26
|
+
fullwidth?: boolean;
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
error?: boolean;
|
|
29
|
+
required?: boolean;
|
|
30
|
+
className?: string;
|
|
31
|
+
options: Options[];
|
|
32
|
+
value?: Options;
|
|
33
|
+
onChangeText?: InputProps["onChange"];
|
|
34
|
+
onSelect?: (value: Options) => void;
|
|
35
|
+
} & Omit<InputProps, "value">;
|
|
36
|
+
|
|
37
|
+
const Dropdown = ({
|
|
38
|
+
id,
|
|
39
|
+
options,
|
|
40
|
+
value,
|
|
41
|
+
label,
|
|
42
|
+
size = "md",
|
|
43
|
+
rounded = "normal",
|
|
44
|
+
variant = "outline",
|
|
45
|
+
helperText,
|
|
46
|
+
errorMessage,
|
|
47
|
+
fullwidth = true,
|
|
48
|
+
disabled = false,
|
|
49
|
+
error = false,
|
|
50
|
+
filterMode = false,
|
|
51
|
+
required = true,
|
|
52
|
+
onChangeText,
|
|
53
|
+
onSelect,
|
|
54
|
+
...props
|
|
55
|
+
}: DropdownProps) => {
|
|
56
|
+
const _id = id || `${label}-select`;
|
|
57
|
+
|
|
58
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
59
|
+
const [selectedOption, setSelectedOption] = useState<
|
|
60
|
+
Options | null | undefined
|
|
61
|
+
>(null);
|
|
62
|
+
const [textValue, setTextValue] = useState("");
|
|
63
|
+
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (value && !selectedOption) {
|
|
66
|
+
setSelectedOption(value);
|
|
67
|
+
}
|
|
68
|
+
}, [value, selectedOption]);
|
|
69
|
+
|
|
70
|
+
const handleOnChangeText = useCallback(
|
|
71
|
+
(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
72
|
+
onChangeText?.(event);
|
|
73
|
+
setTextValue(event.target.value);
|
|
74
|
+
},
|
|
75
|
+
[onChangeText]
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const handleOptionClick = useCallback(
|
|
79
|
+
(option: Options) => {
|
|
80
|
+
setSelectedOption(option);
|
|
81
|
+
setTextValue(option.label);
|
|
82
|
+
onSelect?.(option);
|
|
83
|
+
},
|
|
84
|
+
[onSelect]
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const optionsFiltered = useMemo(() => {
|
|
88
|
+
return options.filter(
|
|
89
|
+
(option) =>
|
|
90
|
+
!filterMode ||
|
|
91
|
+
option.label?.toLowerCase().includes(textValue?.toLowerCase())
|
|
92
|
+
);
|
|
93
|
+
}, [options, filterMode, textValue]);
|
|
94
|
+
|
|
95
|
+
const renderOptions = () => (
|
|
96
|
+
<ul className="absolute mt-1 w-full bg-white border border-gray-300 rounded-md shadow-md z-10 max-h-60 overflow-y-auto">
|
|
97
|
+
{optionsFiltered.map((option) => (
|
|
98
|
+
<li
|
|
99
|
+
key={option.value}
|
|
100
|
+
onMouseDown={() => handleOptionClick(option)}
|
|
101
|
+
className={`px-4 py-2 hover:bg-gray-100 cursor-pointer ${
|
|
102
|
+
selectedOption?.value === option.value ? " bg-gray-200" : ""
|
|
103
|
+
}`}
|
|
104
|
+
>
|
|
105
|
+
{option.label}
|
|
106
|
+
</li>
|
|
107
|
+
))}
|
|
108
|
+
{optionsFiltered.length === 0 && (
|
|
109
|
+
<li className="px-4 py-14 text-center text-input-text">Not found</li>
|
|
110
|
+
)}
|
|
111
|
+
</ul>
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<div className={`relative ${fullwidth ? "w-full" : ""}`}>
|
|
116
|
+
<TextInput
|
|
117
|
+
{...props}
|
|
118
|
+
readOnly={!filterMode}
|
|
119
|
+
value={textValue}
|
|
120
|
+
onChange={handleOnChangeText}
|
|
121
|
+
label={label}
|
|
122
|
+
placeholder=" "
|
|
123
|
+
type="text"
|
|
124
|
+
rounded={rounded}
|
|
125
|
+
variant={variant}
|
|
126
|
+
helperText={helperText}
|
|
127
|
+
errorMessage={errorMessage}
|
|
128
|
+
fullwidth={fullwidth}
|
|
129
|
+
error={error}
|
|
130
|
+
required={required}
|
|
131
|
+
id={_id}
|
|
132
|
+
disabled={disabled}
|
|
133
|
+
hasClearIcon={false}
|
|
134
|
+
size={size}
|
|
135
|
+
className={customInputVariant({ size })}
|
|
136
|
+
onFocus={() => setIsFocused(true)}
|
|
137
|
+
onBlur={() => setIsFocused(false)}
|
|
138
|
+
endIcon={
|
|
139
|
+
<div className={iconWrapperVariant({ size })}>
|
|
140
|
+
<ChevronDownIcon
|
|
141
|
+
className={dropdownIconVariant({ size, isFocus: isFocused })}
|
|
142
|
+
/>
|
|
143
|
+
</div>
|
|
144
|
+
}
|
|
145
|
+
/>
|
|
146
|
+
{isFocused && renderOptions()}
|
|
147
|
+
</div>
|
|
148
|
+
);
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
export default Dropdown;
|
|
@@ -35,9 +35,9 @@ export const Default = {
|
|
|
35
35
|
};
|
|
36
36
|
return (
|
|
37
37
|
<div className="flex flex-row gap-4 w-full">
|
|
38
|
-
<TextInput id="1"
|
|
39
|
-
<TextInput id="2"
|
|
40
|
-
<TextInput id="3"
|
|
38
|
+
<TextInput id="1" size="lg" {...args} />
|
|
39
|
+
<TextInput id="2" size="md" {...args} />
|
|
40
|
+
<TextInput id="3" size="sm" {...args} />
|
|
41
41
|
</div>
|
|
42
42
|
);
|
|
43
43
|
},
|