mirror of
https://github.com/nsnail/spectre.console.git
synced 2025-04-14 16:02:50 +08:00
Compare commits
524 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a46321c06b | ||
![]() |
29ab313bb9 | ||
![]() |
92daeb739d | ||
![]() |
43e9669395 | ||
![]() |
ab8384acf6 | ||
![]() |
b2689be3ed | ||
![]() |
835143d95f | ||
![]() |
8f2a859087 | ||
![]() |
2be8e8da4e | ||
![]() |
2a8810affd | ||
![]() |
e1d21e7e61 | ||
![]() |
c7c3ebdf57 | ||
![]() |
b67af32423 | ||
![]() |
10773a5625 | ||
![]() |
4802751357 | ||
![]() |
4515d89705 | ||
![]() |
be45494d6e | ||
![]() |
69689d2ba1 | ||
![]() |
aa9e5c48c6 | ||
![]() |
8d06daf355 | ||
![]() |
cecfdc386c | ||
![]() |
375a708c43 | ||
![]() |
574ead6d46 | ||
![]() |
a87277e859 | ||
![]() |
fdc03f2081 | ||
![]() |
3eb620a44e | ||
![]() |
bc88da8056 | ||
![]() |
00b9aecb4f | ||
![]() |
444dbed259 | ||
![]() |
a32dc8030b | ||
![]() |
75547b2436 | ||
![]() |
22d1cbe01f | ||
![]() |
7f8ed509bb | ||
![]() |
c70a8b8fc5 | ||
![]() |
b470af11f7 | ||
![]() |
23b160a3f5 | ||
![]() |
1345a6347a | ||
![]() |
78f3f80b17 | ||
![]() |
a55b80220d | ||
![]() |
f8a4b2271d | ||
![]() |
dba7ad0875 | ||
![]() |
322ed2efbb | ||
![]() |
156d254208 | ||
![]() |
3437130bf0 | ||
![]() |
32384f7b8d | ||
![]() |
32361d3f15 | ||
![]() |
b9d2d2df6d | ||
![]() |
8e44a83737 | ||
![]() |
fd69ad0b01 | ||
![]() |
753894de94 | ||
![]() |
dc2cb40b79 | ||
![]() |
511f798f0f | ||
![]() |
2081c0fd9a | ||
![]() |
96512f353f | ||
![]() |
56feea11a1 | ||
![]() |
45c24055fa | ||
![]() |
d56139756c | ||
![]() |
7af1eedca7 | ||
![]() |
6116af3844 | ||
![]() |
2cc6c457ad | ||
![]() |
f02b46107e | ||
![]() |
42fd801876 | ||
![]() |
bb72b44d60 | ||
![]() |
d79e6adc5f | ||
![]() |
64b9ef582d | ||
![]() |
a19c84e25a | ||
![]() |
b61fff042b | ||
![]() |
ca441dbe7a | ||
![]() |
f6bcf67cbe | ||
![]() |
5c87d7fa04 | ||
![]() |
0e2ed511a5 | ||
![]() |
7b13148773 | ||
![]() |
e5a6459c52 | ||
![]() |
68b28b57f2 | ||
![]() |
43b5ac99f9 | ||
![]() |
b1b50a21f7 | ||
![]() |
5d4b2c88e5 | ||
![]() |
3acc90e47c | ||
![]() |
88515b7d7f | ||
![]() |
c5e11626b5 | ||
![]() |
2ead177404 | ||
![]() |
71f762f646 | ||
![]() |
95bff47b85 | ||
![]() |
de04619f88 | ||
![]() |
ecdfdd4b85 | ||
![]() |
a893a9601e | ||
![]() |
d52d14e848 | ||
![]() |
a62e79992b | ||
![]() |
4f22f5b7c3 | ||
![]() |
ff7282ecb8 | ||
![]() |
eb38f76a6a | ||
![]() |
20a2f727f7 | ||
![]() |
fc0b553a4a | ||
![]() |
1a3249cdae | ||
![]() |
43f9ae92ad | ||
![]() |
e66d3aab2e | ||
![]() |
d921ac6f02 | ||
![]() |
5acd83a3ef | ||
![]() |
397b742bec | ||
![]() |
d30b08201d | ||
![]() |
8da05bcc17 | ||
![]() |
badcd642ec | ||
![]() |
fde9ee04cf | ||
![]() |
b6e0b2389a | ||
![]() |
3f5e8aabf5 | ||
![]() |
ead874e6b2 | ||
![]() |
e13410861d | ||
![]() |
bf3b91a535 | ||
![]() |
72704529c5 | ||
![]() |
b21e07ea94 | ||
![]() |
703d653ec5 | ||
![]() |
71631b248a | ||
![]() |
63c22575ea | ||
![]() |
9cc888e5ad | ||
![]() |
d5b4621233 | ||
![]() |
cee97821d6 | ||
![]() |
55c763a5c2 | ||
![]() |
d03c10623c | ||
![]() |
5a52c1f277 | ||
![]() |
544e6a92df | ||
![]() |
a94bc15746 | ||
![]() |
e7ce6a69b7 | ||
![]() |
7cf7e84dd8 | ||
![]() |
6f1f29967d | ||
![]() |
006da0f9ea | ||
![]() |
c62f79eded | ||
![]() |
1d19079913 | ||
![]() |
44300c871f | ||
![]() |
989c0b9904 | ||
![]() |
cb52eb63ce | ||
![]() |
7397169a27 | ||
![]() |
ffdb47d77f | ||
![]() |
383bee0e3e | ||
![]() |
4d6541dd14 | ||
![]() |
b1e0896a0d | ||
![]() |
e07ccd9f66 | ||
![]() |
250b1f4c9c | ||
![]() |
023c77ff09 | ||
![]() |
dc402220f2 | ||
![]() |
c448d0d5f6 | ||
![]() |
3da367f29f | ||
![]() |
ead7115cbe | ||
![]() |
1fd028942f | ||
![]() |
4219bbbf61 | ||
![]() |
29a43686d4 | ||
![]() |
63b940cf0e | ||
![]() |
bbf58ee814 | ||
![]() |
e2a674815d | ||
![]() |
343b98944d | ||
![]() |
2bbb7c1ab6 | ||
![]() |
5296e56b1c | ||
![]() |
943c045fab | ||
![]() |
2af3f7faeb | ||
![]() |
ed9e198d60 | ||
![]() |
3bee7212b7 | ||
![]() |
c82d8c4523 | ||
![]() |
bef21e8a21 | ||
![]() |
037e109699 | ||
![]() |
f7befacd79 | ||
![]() |
cec5fb4595 | ||
![]() |
9c86391fb6 | ||
![]() |
a3dcb31729 | ||
![]() |
1002c6fe27 | ||
![]() |
c64797d681 | ||
![]() |
131b37fff8 | ||
![]() |
813a53cdfa | ||
![]() |
2af901a814 | ||
![]() |
83afa97017 | ||
![]() |
e0ded712e8 | ||
![]() |
d484e832f5 | ||
![]() |
71a5d83067 | ||
![]() |
35ce60b596 | ||
![]() |
0ec70a44db | ||
![]() |
1ee2653cf8 | ||
![]() |
4c0178cf9a | ||
![]() |
296bc61837 | ||
![]() |
766ccb1f1b | ||
![]() |
f7314dc2e8 | ||
![]() |
f453890d13 | ||
![]() |
2c8f459806 | ||
![]() |
018f4ebd17 | ||
![]() |
404b052a5f | ||
![]() |
dac2097321 | ||
![]() |
6acf9b8c63 | ||
![]() |
3ec0fee795 | ||
![]() |
5843a4545e | ||
![]() |
d64d3ec770 | ||
![]() |
4dcbd30285 | ||
![]() |
1334319dd1 | ||
![]() |
714cf179cb | ||
![]() |
70da3f40ff | ||
![]() |
5075732564 | ||
![]() |
10467a2912 | ||
![]() |
a7ab1b690e | ||
![]() |
142942b8a2 | ||
![]() |
0bab835293 | ||
![]() |
a6af9a6842 | ||
![]() |
d3f4f5f208 | ||
![]() |
cbbdb3369c | ||
![]() |
6740f0b02b | ||
![]() |
f7f99ec899 | ||
![]() |
955fe07bac | ||
![]() |
819b948e78 | ||
![]() |
baa8220a52 | ||
![]() |
9cd7b24e65 | ||
![]() |
04610cf492 | ||
![]() |
f4183e0462 | ||
![]() |
29846ba505 | ||
![]() |
92318ce1fb | ||
![]() |
720db951f3 | ||
![]() |
e042fe15e4 | ||
![]() |
62b30d6072 | ||
![]() |
beca0b2419 | ||
![]() |
de847b90e4 | ||
![]() |
7b9553dd22 | ||
![]() |
f223f6061c | ||
![]() |
eba2a8cc76 | ||
![]() |
bc6ba26840 | ||
![]() |
54be64ec84 | ||
![]() |
3e6e0990c5 | ||
![]() |
4a8a4ab048 | ||
![]() |
b793482ebb | ||
![]() |
f895bb175d | ||
![]() |
4258cbfb85 | ||
![]() |
83982347f6 | ||
![]() |
879dd9fbb1 | ||
![]() |
c1e9c1a99f | ||
![]() |
a9b97fa4dc | ||
![]() |
55c3f3b7a8 | ||
![]() |
02ff3fc910 | ||
![]() |
c3ec6a7363 | ||
![]() |
9ce3b99cd6 | ||
![]() |
a70cc90797 | ||
![]() |
7dce4af552 | ||
![]() |
02f9d26473 | ||
![]() |
995ef10b8b | ||
![]() |
4ea64ccb9c | ||
![]() |
a755cc5d9c | ||
![]() |
2a493cfee9 | ||
![]() |
9df6ed213c | ||
![]() |
6a4d8c8f30 | ||
![]() |
5f1121e8e1 | ||
![]() |
d7babcc6e4 | ||
![]() |
f085da76c1 | ||
![]() |
8fa53f8fb1 | ||
![]() |
f6a7c96413 | ||
![]() |
a91a3c12ad | ||
![]() |
82de4a55c4 | ||
![]() |
db095217b7 | ||
![]() |
7b23456d3e | ||
![]() |
cbfcc37a46 | ||
![]() |
999c59909b | ||
![]() |
fd8d271a10 | ||
![]() |
8b5836f4e4 | ||
![]() |
5581ad2f05 | ||
![]() |
d339442df8 | ||
![]() |
422012c994 | ||
![]() |
4f0ec87522 | ||
![]() |
eb02c3d534 | ||
![]() |
088db165ed | ||
![]() |
1082ac1efc | ||
![]() |
a60910c15f | ||
![]() |
73ab977f26 | ||
![]() |
79913ab238 | ||
![]() |
9a7ac7b5b2 | ||
![]() |
9cbfda9e4a | ||
![]() |
bb013dcc52 | ||
![]() |
af9f5ea97d | ||
![]() |
e96a821ead | ||
![]() |
506253bc34 | ||
![]() |
90c2d988ab | ||
![]() |
2bd1383cbe | ||
![]() |
00a9ba325e | ||
![]() |
540bc1307c | ||
![]() |
a6618f762c | ||
![]() |
638149f44b | ||
![]() |
0d72b94f9c | ||
![]() |
0d19ccd8a6 | ||
![]() |
78d841e3dc | ||
![]() |
d94dc2fcb2 | ||
![]() |
9d985f0f0a | ||
![]() |
3a7b8aa1d2 | ||
![]() |
dc93edef15 | ||
![]() |
b4cf7a76d3 | ||
![]() |
45a051150f | ||
![]() |
47ef9a685e | ||
![]() |
8ca602b986 | ||
![]() |
a11ae6a93d | ||
![]() |
b13ff8ebcc | ||
![]() |
90e6a1aa21 | ||
![]() |
f3a82073d9 | ||
![]() |
ff8fd9ed2a | ||
![]() |
1eeb32c704 | ||
![]() |
c32decfa55 | ||
![]() |
564c7b8f4e | ||
![]() |
5b2b4375a4 | ||
![]() |
70bbc24911 | ||
![]() |
36ca22ffac | ||
![]() |
b600832e00 | ||
![]() |
da1c471c18 | ||
![]() |
b6b963c03c | ||
![]() |
7e1fb43f21 | ||
![]() |
47fde1875b | ||
![]() |
eb85f5860e | ||
![]() |
25a61bea91 | ||
![]() |
bad6672d76 | ||
![]() |
f614032c82 | ||
![]() |
585f010b26 | ||
![]() |
90b917c38c | ||
![]() |
edbe9d6ebc | ||
![]() |
90de1847d8 | ||
![]() |
38d9386e00 | ||
![]() |
7998ece6b6 | ||
![]() |
1d8154f9b0 | ||
![]() |
1f2629e2e1 | ||
![]() |
a6364e066b | ||
![]() |
fbe1d0b6f2 | ||
![]() |
eb4a7d3bf4 | ||
![]() |
5e41a2f505 | ||
![]() |
921d595269 | ||
![]() |
899dd20b65 | ||
![]() |
8ae3d258e4 | ||
![]() |
974aa1afda | ||
![]() |
66fc949e2a | ||
![]() |
d6cdd1fbda | ||
![]() |
bec3315d91 | ||
![]() |
d465d93a9b | ||
![]() |
782a99d726 | ||
![]() |
b6be693007 | ||
![]() |
f9a85e017a | ||
![]() |
36e5350968 | ||
![]() |
3ac63d2670 | ||
![]() |
c2da268129 | ||
![]() |
74a2e10ff0 | ||
![]() |
e8eb5b85b9 | ||
![]() |
78958aae27 | ||
![]() |
a0e20f299c | ||
![]() |
ff4215f431 | ||
![]() |
f221c1f25c | ||
![]() |
0b988ff65c | ||
![]() |
9a6d8d92b4 | ||
![]() |
52c1d9122b | ||
![]() |
eb6a9d8d04 | ||
![]() |
ec1188b837 | ||
![]() |
1dbaf50935 | ||
![]() |
523adc6c49 | ||
![]() |
bba5f0c5dc | ||
![]() |
19ff48f4b8 | ||
![]() |
8fcd2e59d6 | ||
![]() |
8ce40bac3c | ||
![]() |
8e762e4618 | ||
![]() |
37f661a963 | ||
![]() |
55633b59fa | ||
![]() |
3f561e0902 | ||
![]() |
461348f2fb | ||
![]() |
fd4b96944e | ||
![]() |
2e5d18fa78 | ||
![]() |
168f35202d | ||
![]() |
225305f90e | ||
![]() |
8fed3bc575 | ||
![]() |
19eb273813 | ||
![]() |
48df9cf68b | ||
![]() |
2f6b4f53c4 | ||
![]() |
21ac952307 | ||
![]() |
e86f9d3c5a | ||
![]() |
9c9eb04f91 | ||
![]() |
ba4b7b97f8 | ||
![]() |
b738187b28 | ||
![]() |
b3ef7d4fa6 | ||
![]() |
c5c1852fc3 | ||
![]() |
045d0922c8 | ||
![]() |
949f35defd | ||
![]() |
f5a2735501 | ||
![]() |
d02c9e552e | ||
![]() |
a4ae36738b | ||
![]() |
35d2750b68 | ||
![]() |
4d2d927caa | ||
![]() |
174d285035 | ||
![]() |
e8e92e7f44 | ||
![]() |
3718502eee | ||
![]() |
39cfc7a62f | ||
![]() |
2e90ef28e4 | ||
![]() |
2a3763cdc7 | ||
![]() |
e0395dfa2b | ||
![]() |
ca2e6ce0ad | ||
![]() |
fa15389158 | ||
![]() |
a5716a35e2 | ||
![]() |
644fb76d61 | ||
![]() |
e3dfe23b59 | ||
![]() |
ad23855b0a | ||
![]() |
64f444114a | ||
![]() |
b058c54f3c | ||
![]() |
8cfe06e77a | ||
![]() |
48d49d6e18 | ||
![]() |
49e8a980a7 | ||
![]() |
d34012cad0 | ||
![]() |
c3510f3036 | ||
![]() |
786b7670da | ||
![]() |
ffd24ec451 | ||
![]() |
e081593012 | ||
![]() |
bf95564ebb | ||
![]() |
3c5b98123b | ||
![]() |
7276e11ecc | ||
![]() |
d306ad82d1 | ||
![]() |
d96817dc9c | ||
![]() |
e169df6303 | ||
![]() |
57731c0d55 | ||
![]() |
170901f584 | ||
![]() |
c2b25eea8a | ||
![]() |
223642b797 | ||
![]() |
32d7ea15bd | ||
![]() |
fa5a1e88ec | ||
![]() |
d532e1011f | ||
![]() |
5f97f2300c | ||
![]() |
884cb8ddd4 | ||
![]() |
314e50b531 | ||
![]() |
d9f06413d0 | ||
![]() |
6e2ca8449e | ||
![]() |
58eff30787 | ||
![]() |
aa59f6cd55 | ||
![]() |
2011cb2eff | ||
![]() |
865552c3f2 | ||
![]() |
fa553fd72e | ||
![]() |
a186fd94ac | ||
![]() |
6b5b31957c | ||
![]() |
b92827ce3d | ||
![]() |
c9b178ac96 | ||
![]() |
721d73e9eb | ||
![]() |
8b058d6342 | ||
![]() |
d1048260cc | ||
![]() |
bdcc01ea68 | ||
![]() |
4f293d887d | ||
![]() |
d015a4966f | ||
![]() |
5cbe9d40b0 | ||
![]() |
5faa61fa64 | ||
![]() |
087f216bcf | ||
![]() |
ebd7bb5949 | ||
![]() |
0bf97cb666 | ||
![]() |
ebb1076dd0 | ||
![]() |
21f731ebd5 | ||
![]() |
397860e42e | ||
![]() |
adb600c430 | ||
![]() |
ab83e41051 | ||
![]() |
0d2a75aeee | ||
![]() |
bfdaef95d6 | ||
![]() |
cb8dc97847 | ||
![]() |
450d87f5d3 | ||
![]() |
46abadaccb | ||
![]() |
69fdae70c0 | ||
![]() |
91a0be86a3 | ||
![]() |
ab09a30bc7 | ||
![]() |
a2ed88e2eb | ||
![]() |
3dea412785 | ||
![]() |
5d68020abb | ||
![]() |
315a52f3e9 | ||
![]() |
c147929f16 | ||
![]() |
6549436356 | ||
![]() |
1dfc6bdadc | ||
![]() |
2ba06577ef | ||
![]() |
ea5b7338ad | ||
![]() |
4d88a6ab69 | ||
![]() |
1dd1945297 | ||
![]() |
d1d94cdebe | ||
![]() |
e48ae9600a | ||
![]() |
d63255aa5f | ||
![]() |
9a68b27b31 | ||
![]() |
2a9fbb1ee9 | ||
![]() |
b568098d5e | ||
![]() |
cba02070f9 | ||
![]() |
01f707c78d | ||
![]() |
8d67c0a6b4 | ||
![]() |
3463dde543 | ||
![]() |
91f910326c | ||
![]() |
79af013bf2 | ||
![]() |
04efd1719c | ||
![]() |
f5a9c0ca26 | ||
![]() |
23564612c1 | ||
![]() |
f2b8afffb3 | ||
![]() |
3e2eea730b | ||
![]() |
bc9f610258 | ||
![]() |
ae96606ab7 | ||
![]() |
41ccc0b464 | ||
![]() |
3545e0f6b5 | ||
![]() |
2fe2bb3c32 | ||
![]() |
1fc6f22ea9 | ||
![]() |
6a5c507936 | ||
![]() |
efa3d3b130 | ||
![]() |
6007fcaafc | ||
![]() |
13ac38ed04 | ||
![]() |
ca036f6543 | ||
![]() |
36ec3d1fd3 | ||
![]() |
fe5096dceb | ||
![]() |
39b59c8d4a | ||
![]() |
8cf7794852 | ||
![]() |
4edc647fdd | ||
![]() |
be45a0ff4e | ||
![]() |
256fcdd27f | ||
![]() |
dafbfe63ba | ||
![]() |
a2ab522516 | ||
![]() |
8778ab1739 | ||
![]() |
693e1fa170 | ||
![]() |
4b37a4708f | ||
![]() |
a690ce4955 | ||
![]() |
759b16aed9 | ||
![]() |
254880e93a | ||
![]() |
6f16081f42 | ||
![]() |
6121203fee | ||
![]() |
9204671b27 | ||
![]() |
c765bbd0dd | ||
![]() |
6bceac8a5e | ||
![]() |
1ed7e65fcb | ||
![]() |
20650f1e7e | ||
![]() |
2ba6da3514 | ||
![]() |
8830779875 | ||
![]() |
9c46c21e27 | ||
![]() |
c643ec735d | ||
![]() |
b17eabaa1f | ||
![]() |
7f6f2437b1 | ||
![]() |
c2bab0ebf8 | ||
![]() |
9502aaf2b9 | ||
![]() |
57a8e6ccc1 | ||
![]() |
8c099a0038 | ||
![]() |
08b65cfa47 | ||
![]() |
2540f48622 |
@ -2,7 +2,7 @@ root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = CRLF
|
||||
end_of_line = LF
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
insert_final_newline = false
|
||||
@ -26,10 +26,10 @@ indent_size = 2
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.sh]
|
||||
end_of_line = lf
|
||||
|
||||
[*.cs]
|
||||
# Prefer file scoped namespace declarations
|
||||
csharp_style_namespace_declarations = file_scoped:warning
|
||||
|
||||
# Sort using and Import directives with System.* appearing first
|
||||
dotnet_sort_system_directives_first = true
|
||||
dotnet_separate_import_directive_groups = false
|
||||
|
5
.git-blame-ignore-revs
Normal file
5
.git-blame-ignore-revs
Normal file
@ -0,0 +1,5 @@
|
||||
# Use file scoped namespace declarations
|
||||
7b2da0a4f63bf3ceab99d2c88535e74155f2b99c
|
||||
|
||||
# fix line-endings
|
||||
e2ad4b1ea5555e701cda4fd400bb6592e318e1ff
|
4
.gitattributes
vendored
Normal file
4
.gitattributes
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
* text=auto
|
||||
|
||||
*.cs text eol=lf
|
||||
*.md text eol=lf
|
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
5
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -2,7 +2,7 @@
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
labels: ["bug", "needs triage"]
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
@ -26,3 +26,6 @@ If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
|
||||
---
|
||||
Please upvote :+1: this issue if you are interested in it.
|
5
.github/ISSUE_TEMPLATE/feature_request.md
vendored
5
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@ -2,7 +2,7 @@
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
labels: ["feature", "needs triage"]
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
@ -18,3 +18,6 @@ A clear and concise description of any alternative solutions or features you've
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
|
||||
---
|
||||
Please upvote :+1: this issue if you are interested in it.
|
22
.github/pull_request_template.md
vendored
Normal file
22
.github/pull_request_template.md
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
<!--
|
||||
Do NOT open a PR without discussing the changes on an open issue, first.
|
||||
|
||||
Add the issue number here. e.g. #123
|
||||
-->
|
||||
fixes #
|
||||
|
||||
<!-- formalities. These are not optional. -->
|
||||
|
||||
- [ ] I have read the [Contribution Guidelines](https://github.com/spectreconsole/spectre.console/blob/main/CONTRIBUTING.md)
|
||||
- [ ] I have commented on the issue above and discussed the intended changes
|
||||
- [ ] A maintainer has signed off on the changes and the issue was assigned to me
|
||||
- [ ] All newly added code is adequately covered by tests
|
||||
- [ ] All existing tests are still running without errors
|
||||
- [ ] The documentation was modified to reflect the changes _OR_ no documentation changes are required.
|
||||
|
||||
## Changes
|
||||
|
||||
<!-- describe the changes you made. -->
|
||||
|
||||
---
|
||||
Please upvote :+1: this pull request if you are interested in it.
|
20
.github/renovate.json
vendored
Normal file
20
.github/renovate.json
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:base"
|
||||
],
|
||||
"dependencyDashboard": false,
|
||||
"commitMessagePrefix": "chore:",
|
||||
"labels": ["dependencies"],
|
||||
"npm": {
|
||||
"ignorePaths": [
|
||||
"**/node_modules/**",
|
||||
"**/bower_components/**",
|
||||
"docs/**"
|
||||
]
|
||||
},
|
||||
"ignorePaths": [
|
||||
"resources/scripts/**",
|
||||
"docs/**"
|
||||
]
|
||||
}
|
18
.github/workflows/backlog.yaml
vendored
Normal file
18
.github/workflows/backlog.yaml
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
name: Add issues/PRs to backlog automatically
|
||||
|
||||
on:
|
||||
issues:
|
||||
types:
|
||||
- opened
|
||||
- transferred
|
||||
|
||||
jobs:
|
||||
add-to-project:
|
||||
name: Add issue to backlog
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/spectreconsole/projects/1
|
||||
github-token: ${{ secrets.PROJECT_TOKEN }}
|
64
.github/workflows/ci.yaml
vendored
64
.github/workflows/ci.yaml
vendored
@ -1,4 +1,5 @@
|
||||
name: Continuous Integration
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
name: Pull Request
|
||||
on: pull_request
|
||||
|
||||
env:
|
||||
@ -7,30 +8,6 @@ env:
|
||||
|
||||
jobs:
|
||||
|
||||
###################################################
|
||||
# DOCS
|
||||
###################################################
|
||||
|
||||
docs:
|
||||
name: Documentation
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.100
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
cd docs
|
||||
dotnet run --configuration Release
|
||||
|
||||
###################################################
|
||||
# BUILD
|
||||
###################################################
|
||||
@ -38,48 +15,29 @@ jobs:
|
||||
build:
|
||||
name: Build
|
||||
if: "!contains(github.event.head_commit.message, 'skip-ci')"
|
||||
strategy:
|
||||
matrix:
|
||||
kind: ['linux', 'windows', 'macOS']
|
||||
include:
|
||||
- kind: linux
|
||||
os: ubuntu-latest
|
||||
- kind: windows
|
||||
os: windows-latest
|
||||
- kind: macOS
|
||||
os: macos-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup dotnet 3.1.402
|
||||
uses: actions/setup-dotnet@v1
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 3.1.402
|
||||
|
||||
- name: Setup dotnet 5.0.100
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.100
|
||||
|
||||
- name: Integration Tests
|
||||
shell: bash
|
||||
run: |
|
||||
dotnet tool restore
|
||||
dotnet example --all
|
||||
dotnet-version: |
|
||||
8.0.x
|
||||
9.0.x
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: |
|
||||
dotnet tool restore
|
||||
dotnet cake
|
||||
|
||||
|
||||
- name: Upload Verify Test Results
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: verify-test-results
|
||||
path: |
|
||||
|
35
.github/workflows/docs.yaml
vendored
35
.github/workflows/docs.yaml
vendored
@ -1,35 +0,0 @@
|
||||
name: Deploy Documentation
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- 'src/**'
|
||||
|
||||
jobs:
|
||||
|
||||
###################################################
|
||||
# DOCS
|
||||
###################################################
|
||||
|
||||
build:
|
||||
name: Deploy
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.100
|
||||
|
||||
- name: Publish
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
cd docs
|
||||
dotnet run --configuration Release -- deploy
|
130
.github/workflows/publish.yaml
vendored
130
.github/workflows/publish.yaml
vendored
@ -1,3 +1,4 @@
|
||||
# yaml-language-server: $schema=https://json.schemastore.org/github-workflow.json
|
||||
name: Publish
|
||||
|
||||
on:
|
||||
@ -6,8 +7,6 @@ on:
|
||||
- '*'
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'src/**'
|
||||
|
||||
env:
|
||||
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
|
||||
@ -15,95 +14,26 @@ env:
|
||||
|
||||
jobs:
|
||||
|
||||
###################################################
|
||||
# DOCS
|
||||
###################################################
|
||||
|
||||
docs:
|
||||
name: Documentation
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@master
|
||||
|
||||
- name: Setup dotnet
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.100
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
cd docs
|
||||
dotnet run --configuration Release
|
||||
|
||||
###################################################
|
||||
# BUILD
|
||||
###################################################
|
||||
|
||||
build:
|
||||
name: Build
|
||||
needs: [docs]
|
||||
if: "!contains(github.event.head_commit.message, 'skip-ci') || startsWith(github.ref, 'refs/tags/')"
|
||||
strategy:
|
||||
matrix:
|
||||
kind: ['linux', 'windows', 'macOS']
|
||||
include:
|
||||
- kind: linux
|
||||
os: ubuntu-latest
|
||||
- kind: windows
|
||||
os: windows-latest
|
||||
- kind: macOS
|
||||
os: macos-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup dotnet 3.1.402
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 3.1.402
|
||||
|
||||
- name: Setup dotnet 5.0.100
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.100
|
||||
|
||||
- name: Build
|
||||
shell: bash
|
||||
run: |
|
||||
dotnet tool restore
|
||||
dotnet cake
|
||||
|
||||
###################################################
|
||||
# PUBLISH
|
||||
###################################################
|
||||
|
||||
publish:
|
||||
name: Publish
|
||||
needs: [build]
|
||||
build:
|
||||
name: Publish NuGet Packages
|
||||
if: "!contains(github.event.head_commit.message, 'skip-ci') || startsWith(github.ref, 'refs/tags/')"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup dotnet 3.1.402
|
||||
uses: actions/setup-dotnet@v1
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: 3.1.402
|
||||
|
||||
- name: Setup dotnet 5.0.100
|
||||
uses: actions/setup-dotnet@v1
|
||||
with:
|
||||
dotnet-version: 5.0.100
|
||||
dotnet-version: |
|
||||
8.0.x
|
||||
9.0.x
|
||||
|
||||
- name: Publish
|
||||
shell: bash
|
||||
@ -111,4 +41,44 @@ jobs:
|
||||
dotnet tool restore
|
||||
dotnet cake --target="publish" \
|
||||
--nuget-key="${{secrets.NUGET_API_KEY}}" \
|
||||
--github-key="${{secrets.GITHUB_TOKEN}}"
|
||||
--github-key="${{secrets.GITHUB_TOKEN}}"
|
||||
|
||||
###################################################
|
||||
# DOCS
|
||||
###################################################
|
||||
|
||||
documentation:
|
||||
name: Publish Documentation
|
||||
needs: [build]
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup .NET SDK
|
||||
uses: actions/setup-dotnet@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '16'
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.npm
|
||||
key: npm-${{ hashFiles('package-lock.json') }}
|
||||
restore-keys: npm-
|
||||
|
||||
- name: Publish Documentation
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
NETLIFY_ACCESS_TOKEN: ${{ secrets.NETLIFY_ACCESS_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
|
||||
run: |
|
||||
cd docs
|
||||
dotnet tool restore
|
||||
dotnet run --configuration Release -- deploy
|
24
.github/workflows/top-issues-dashboard.yml
vendored
Normal file
24
.github/workflows/top-issues-dashboard.yml
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
name: Top issues action.
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 */1 * *'
|
||||
|
||||
jobs:
|
||||
ShowAndLabelTopIssues:
|
||||
name: Display and label top issues.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Top Issues action
|
||||
uses: rickstaa/top-issues-action@v1.3.101
|
||||
env:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
top_list_size: 10
|
||||
label: true
|
||||
dashboard: true
|
||||
dashboard_show_total_reactions: true
|
||||
top_issues: true
|
||||
top_bugs: true
|
||||
top_features: true
|
||||
feature_label: feature
|
||||
top_pull_requests: true
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -88,4 +88,6 @@ packages
|
||||
# Windows
|
||||
Thumbs.db
|
||||
|
||||
*.received.*
|
||||
*.received.*
|
||||
|
||||
node_modules
|
@ -2,45 +2,131 @@
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||
identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the overall
|
||||
community
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* The use of sexualized language or imagery, and sexual attention or advances of
|
||||
any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
* Publishing others' private information, such as a physical or email address,
|
||||
without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at hello@spectresystems.se. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at
|
||||
conduct@dotnetfoundation.org.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of
|
||||
actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or permanent
|
||||
ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||
community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.1, available at
|
||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
||||
|
||||
[homepage]: http://contributor-covenant.org
|
||||
[version]: http://contributor-covenant.org/version/1/4/
|
||||
Community Impact Guidelines were inspired by
|
||||
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
||||
[https://www.contributor-covenant.org/translations][translations].
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||
[FAQ]: https://www.contributor-covenant.org/faq
|
||||
[translations]: https://www.contributor-covenant.org/translations
|
@ -22,8 +22,8 @@ By contributing to Spectre.Console, you assert that:
|
||||
* The contribution is your own original work.
|
||||
* You have the right to assign the copyright for the work (it is not owned by your employer, or
|
||||
you have been given copyright assignment in writing).
|
||||
* You [license](https://github.com/spectresystems/spectre.console/blob/main/LICENSE) the contribution under the terms applied to the rest of the Spectre.Console project.
|
||||
* You agree to follow the [code of conduct](https://github.com/spectresystems/spectre.console/blob/main/CODE_OF_CONDUCT.md).
|
||||
* You [license](https://github.com/spectreconsole/spectre.console/blob/main/LICENSE) the contribution under the terms applied to the rest of the Spectre.Console project.
|
||||
* You agree to follow the [code of conduct](https://github.com/spectreconsole/spectre.console/blob/main/CODE_OF_CONDUCT.md).
|
||||
|
||||
## Definition of trivial contributions
|
||||
It's hard to define what is a trivial contribution. Sometimes even a 1 character change can be considered significant.
|
||||
@ -39,7 +39,7 @@ What is generally considered trivial:
|
||||
### Code style
|
||||
|
||||
Normal .NET coding guidelines apply.
|
||||
See the [Framework Design Guidelines](https://msdn.microsoft.com/en-us/library/ms229042%28v=vs.110%29.aspx) for more information.
|
||||
See the [Framework Design Guidelines](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/) for more information.
|
||||
|
||||
### Dependencies
|
||||
|
||||
@ -53,19 +53,19 @@ Any new code should also have reasonable unit test coverage.
|
||||
## Contributing process
|
||||
### Get buyoff or find open community issues or features
|
||||
|
||||
* Through GitHub, or through the [GitHub discussions](https://github.com/spectresystems/spectre.console/discussions) (preferred),
|
||||
* Through GitHub, or through the [GitHub discussions](https://github.com/spectreconsole/spectre.console/discussions) (preferred),
|
||||
you talk about a feature you would like to see (or a bug), and why it should be in Spectre.Console.
|
||||
* If approved through the GitHub discussions, ensure an accompanying GitHub issue is created with
|
||||
information and a link back to the discussion.
|
||||
* Once you get a nod from someone in the Spectre.Console Team, you can start on the feature.
|
||||
* Alternatively, if a feature is on the issues list with the
|
||||
[Up For Grabs](https://github.com/spectresystems/spectre.console/labels/up-for-grabs) label,
|
||||
[good first issue](https://github.com/spectreconsole/spectre.console/labels/good%20first%20issue) label,
|
||||
it is open for a community member (contributor) to patch. You should comment that you are signing up for it on
|
||||
the issue so someone else doesn't also sign up for the work.
|
||||
|
||||
### Set up your environment
|
||||
|
||||
* You create, or update, a fork of `spectresystems/spectre.console` under your GitHub account.
|
||||
* You create, or update, a fork of `spectreconsole/spectre.console` under your GitHub account.
|
||||
* From there you create a branch named specific to the feature.
|
||||
* In the branch you do work specific to the feature.
|
||||
* Please also observe the following:
|
||||
@ -96,7 +96,7 @@ Prerequisites:
|
||||
|
||||
Submitting PR:
|
||||
|
||||
* Once you feel it is ready, submit the pull request to the `spectresystems/spectre.console` repository against the `main` branch
|
||||
* Once you feel it is ready, submit the pull request to the `spectreconsole/spectre.console` repository against the `main` branch
|
||||
unless specifically requested to submit it against another branch.
|
||||
* In the case of a larger change that is going to require more discussion,
|
||||
please submit a PR sooner. Waiting until you are ready may mean more changes than you are
|
||||
@ -129,7 +129,7 @@ the issue/open a new PR (referencing old one).
|
||||
Sometimes we may need you to rebase your commit against the latest code before we can review it further.
|
||||
If this happens, you can do the following:
|
||||
|
||||
* `git fetch upstream` (upstream remote would be `spectresystems/spectre.console`)
|
||||
* `git fetch upstream` (upstream remote would be `spectreconsole/spectre.console`)
|
||||
* `git checkout main`
|
||||
* `git rebase upstream/main`
|
||||
* `git checkout your-branch`
|
||||
@ -158,4 +158,4 @@ Harder for us roughly translates to a longer SLA for your pull request.
|
||||
## Acknowledgement
|
||||
|
||||
This contribution guide was taken from the [Chocolatey project](https://chocolatey.org/)
|
||||
with permission and was edited to follow Spectre.Console's conventions and processes.
|
||||
with permission and was edited to follow Spectre.Console's conventions and processes.
|
||||
|
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Spectre Systems AB
|
||||
Copyright (c) 2020 Patrik Svensson, Phil Scott, Nils Andresen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
6
NuGet.Config
Normal file
6
NuGet.Config
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<packageSources>
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
|
||||
</packageSources>
|
||||
</configuration>
|
27
README.fa.md
27
README.fa.md
@ -4,7 +4,7 @@ _[ برای پایتون، بسیار الهام گرفته شده است.
|
||||
|
||||
## فهرست
|
||||
@ -39,35 +39,18 @@ dotnet add package Spectre.Console
|
||||
مستندات `Spectre.Console` را در اینجا میتوایند پیدا کنید:
|
||||
|
||||
<div dir="ltr">
|
||||
https://spectresystems.github.io/spectre.console/
|
||||
https://spectreconsole.net/
|
||||
</div>
|
||||
|
||||
<h2 id="examples">مثالها</h2>
|
||||
|
||||
برای بررسی `Spectre.Console` در عمل، ابزار سراسری
|
||||
[dotnet-example](https://github.com/patriksvensson/dotnet-example)
|
||||
را نصب کنید.
|
||||
|
||||
<pre dir="ltr">
|
||||
> dotnet tool restore
|
||||
</pre>
|
||||
|
||||
حالا شما میتوانید مثالهای موجود در این مخزن را لیست کنید:
|
||||
|
||||
<pre dir="ltr">
|
||||
> dotnet example
|
||||
</pre>
|
||||
|
||||
و برای اجرای مثال:
|
||||
|
||||
<pre dir="ltr">
|
||||
> dotnet example tables
|
||||
</pre>
|
||||
To see `Spectre.Console` in action, please see the
|
||||
[examples repository](https://github.com/spectreconsole/examples).
|
||||
|
||||
<h2 id="license">مجوز</h2>
|
||||
|
||||
<div dir="ltr">
|
||||
Copyright © Spectre Systems.
|
||||
Copyright © Patrik Svensson, Phil Scott, Nils Andresen, Cédric Luthi, Frank Ray
|
||||
</div>
|
||||
|
||||
همانطور که Spectre.Console تحت مجوز MIT ارائه شده است؛ برای کسب اطلاعات بیشتر به مجوز مراجعه کنید.
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
_[](https://www.nuget.org/packages/spectre.console)_
|
||||
|
||||
綺麗なコンソールアプリケーションを簡単に作成するための.NET Standard 2.0ライブラリです。
|
||||
綺麗なコンソールアプリケーションを簡単に作成するための.NETライブラリです。
|
||||
Python用の素晴らしい[Rich ライブラリ](https://github.com/willmcgugan/rich)に強く影響を受けています。
|
||||
|
||||
## 目次
|
||||
|
77
README.md
77
README.md
@ -1,34 +1,39 @@
|
||||
# `Spectre.Console`
|
||||
|
||||
_[](https://www.nuget.org/packages/spectre.console)_
|
||||
_[](https://www.nuget.org/packages/spectre.console)_ _[](https://www.nuget.org/packages/spectre.console.cli)_ [](https://app.netlify.com/sites/spectreconsole/deploys)
|
||||
|
||||
A .NET 5/.NET Standard 2.0 library that makes it easier to create beautiful, cross platform, console applications.
|
||||
It is heavily inspired by the excellent [Rich library](https://github.com/willmcgugan/rich)
|
||||
for Python.
|
||||
A .NET library that makes it easier to create beautiful, cross platform, console applications.
|
||||
It is heavily inspired by the excellent Python library, [Rich](https://github.com/willmcgugan/rich). Detailed instructions for using `Spectre.Console` are located on the project website, https://spectreconsole.net
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Features](#features)
|
||||
2. [Installing](#installing)
|
||||
3. [Documentation](#documentation)
|
||||
4. [Examples](#examples)
|
||||
5. [Sponsors](#sponsors)
|
||||
5. [License](#license)
|
||||
1. [Installing](#installing)
|
||||
1. [Documentation](#documentation)
|
||||
1. [Examples](#examples)
|
||||
1. [Sponsors](#sponsors)
|
||||
1. [Code of Conduct](#code-of-conduct)
|
||||
1. [.NET Foundation](#net-foundation)
|
||||
1. [License](#license)
|
||||
|
||||
## Features
|
||||
|
||||
* Written with unit testing in mind.
|
||||
* Supports tables, grids, panels, and a [rich](https://github.com/willmcgugan/rich) inspired markup language.
|
||||
* Supports tables, grids, panels, and a [Rich](https://github.com/willmcgugan/rich) inspired markup language.
|
||||
* Supports the most common SRG parameters when it comes to text
|
||||
styling such as bold, dim, italic, underline, strikethrough,
|
||||
and blinking text.
|
||||
* Supports 3/4/8/24-bit colors in the terminal.
|
||||
The library will detect the capabilities of the current terminal
|
||||
and downgrade colors as needed.
|
||||
|
||||
and downgrade colors as needed.
|
||||
* Written with unit testing in mind.
|
||||
|
||||

|
||||
|
||||
## Important Notices
|
||||
|
||||
> [!IMPORTANT]\
|
||||
> We use the [Top Issues Dashboard](https://github.com/spectreconsole/spectre.console/issues/1517) for tracking community demand. Please upvote :+1: the issues and pull requests you are interested in.
|
||||
|
||||
## Installing
|
||||
|
||||
The fastest way of getting started using `Spectre.Console` is to install the NuGet package.
|
||||
@ -40,52 +45,46 @@ dotnet add package Spectre.Console
|
||||
## Documentation
|
||||
|
||||
The documentation for `Spectre.Console` can be found at
|
||||
https://spectresystems.github.io/spectre.console/
|
||||
https://spectreconsole.net
|
||||
|
||||
## Examples
|
||||
|
||||
To see `Spectre.Console` in action, install the
|
||||
[dotnet-example](https://github.com/patriksvensson/dotnet-example)
|
||||
global tool.
|
||||
|
||||
```
|
||||
> dotnet tool restore
|
||||
```
|
||||
|
||||
Now you can list available examples in this repository:
|
||||
|
||||
```
|
||||
> dotnet example
|
||||
```
|
||||
|
||||
And to run an example:
|
||||
|
||||
```
|
||||
> dotnet example tables
|
||||
```
|
||||
To see `Spectre.Console` in action, please see the
|
||||
[examples repository](https://github.com/spectreconsole/examples).
|
||||
|
||||
## Sponsors
|
||||
|
||||
The following people are [sponsoring](https://github.com/sponsors/patriksvensson)
|
||||
Spectre.Console to show their support and to ensure the longevity of the project.
|
||||
`Spectre.Console` to show their support and to ensure the longevity of the project.
|
||||
|
||||
* [Rodney Littles II](https://github.com/RLittlesII)
|
||||
* [Martin Björkström](https://github.com/bjorkstromm)
|
||||
* [Dave Glick](https://github.com/daveaglick)
|
||||
* [Kim Gunanrsson](https://github.com/kimgunnarsson)
|
||||
* [Kim Gunnarsson](https://github.com/kimgunnarsson)
|
||||
* [Andrew McClenaghan](https://github.com/andymac4182)
|
||||
* [C. Augusto Proiete](https://github.com/augustoproiete)
|
||||
* [Viktor Elofsson](https://github.com/vktr)
|
||||
* [Steven Knox](https://github.com/stevenknox)
|
||||
* [David Pendray](https://github.com/dpen2000)
|
||||
* [Elmah.io](https://github.com/elmahio)
|
||||
* [Tom Kerkhove](https://github.com/tomkerkhove)
|
||||
|
||||
I really appreciate it.
|
||||
We really appreciate it.
|
||||
**Thank you very much!**
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
This project has adopted the code of conduct defined by the Contributor Covenant to clarify expected behavior in our community.
|
||||
For more information see the [.NET Foundation Code of Conduct](https://dotnetfoundation.org/code-of-conduct).
|
||||
|
||||
## .NET Foundation
|
||||
|
||||
This project is supported by the [.NET Foundation](https://dotnetfoundation.org).
|
||||
|
||||
## License
|
||||
|
||||
Copyright © Spectre Systems.
|
||||
Copyright © Patrik Svensson, Phil Scott, Nils Andresen, Cédric Luthi, Frank Ray
|
||||
|
||||
Spectre.Console is provided as-is under the MIT license. For more information see LICENSE.
|
||||
`Spectre.Console` is provided as-is under the MIT license. For more information see LICENSE.
|
||||
|
||||
* For SixLabors.ImageSharp, see https://github.com/SixLabors/ImageSharp/blob/master/LICENSE
|
||||
* SixLabors.ImageSharp, a library which `Spectre.Console` relies upon, is licensed under Apache 2.0 when distributed as part of `Spectre.Console`. The Six Labors Split License covers all other usage, see: https://github.com/SixLabors/ImageSharp/blob/master/LICENSE
|
||||
|
74
README.pt-BR.md
Normal file
74
README.pt-BR.md
Normal file
@ -0,0 +1,74 @@
|
||||
# `Spectre.Console`
|
||||
|
||||
_[](https://www.nuget.org/packages/spectre.console)_
|
||||
|
||||
Uma biblioteca .NET que torna mais fácil criar aplicativos de console bonitos e multiplataforma.
|
||||
É fortemente inspirada na excelente [biblioteca Rich](https://github.com/willmcgugan/rich)
|
||||
para Python.
|
||||
|
||||
## Índice de Conteúdo
|
||||
|
||||
1. [Funcionalidades](#funcionalidades)
|
||||
2. [Instalação](#instalação)
|
||||
3. [Documentação](#documentação)
|
||||
4. [Exemplos](#exemplos)
|
||||
5. [Patrocinadores](#patrocinadores)
|
||||
5. [Licença](#licença)
|
||||
|
||||
## Funcionalidades
|
||||
|
||||
* Desenvolvida com testes unitários em mente.
|
||||
* Suporta tabelas, grades, painéis, e uma linguagem de marcação inspirada em [rich](https://github.com/willmcgugan/rich).
|
||||
* Suporta os parâmetros SRG mais comuns quando se trata de estilo de texto,
|
||||
como negrito, esmaecido, itálico, sublinhado, tachado
|
||||
e texto piscando.
|
||||
* Suporta cores de 3/4/8/24 bits no terminal.
|
||||
A biblioteca detectará os recursos do terminal atual
|
||||
e reduz as cores conforme necessário.
|
||||
|
||||

|
||||
|
||||
## Instalação
|
||||
|
||||
A maneira mais rápida de começar a usar o `Spectre.Console` é instalar o pacote NuGet.
|
||||
|
||||
```csharp
|
||||
dotnet add package Spectre.Console
|
||||
```
|
||||
|
||||
## Documentação
|
||||
|
||||
A documentação do `Spectre.Console` pode ser encontrada em
|
||||
https://spectreconsole.net/
|
||||
|
||||
## Exemplos
|
||||
|
||||
To see `Spectre.Console` in action, please see the
|
||||
[examples repository](https://github.com/spectreconsole/examples).
|
||||
|
||||
## Patrocinadores
|
||||
|
||||
As seguintes pessoas estão [patrocinando](https://github.com/sponsors/patriksvensson)
|
||||
o Spectre.Console para mostrar o seu apoio e garantir a longevidade do projeto.
|
||||
|
||||
* [Rodney Littles II](https://github.com/RLittlesII)
|
||||
* [Martin Björkström](https://github.com/bjorkstromm)
|
||||
* [Dave Glick](https://github.com/daveaglick)
|
||||
* [Kim Gunanrsson](https://github.com/kimgunnarsson)
|
||||
* [Andrew McClenaghan](https://github.com/andymac4182)
|
||||
* [C. Augusto Proiete](https://github.com/augustoproiete)
|
||||
* [Viktor Elofsson](https://github.com/vktr)
|
||||
* [Steven Knox](https://github.com/stevenknox)
|
||||
* [David Pendray](https://github.com/dpen2000)
|
||||
* [Elmah.io](https://github.com/elmahio)
|
||||
|
||||
Eu estou muito agradecido.
|
||||
**Muito obrigado!**
|
||||
|
||||
## Licença
|
||||
|
||||
Copyright © Patrik Svensson, Phil Scott, Nils Andresen, Cédric Luthi, Frank Ray
|
||||
|
||||
Spectre.Console é fornecido no estado em que se encontra sob a licença do MIT. Para obter mais informações, consulte o arquivo [LICENSE](LICENSE.md).
|
||||
|
||||
* Para SixLabors.ImageSharp, consulte https://github.com/SixLabors/ImageSharp/blob/master/LICENSE
|
54
README.zh.md
54
README.zh.md
@ -2,17 +2,18 @@
|
||||
|
||||
_[](https://www.nuget.org/packages/spectre.console)_
|
||||
|
||||
`Spectre.Console`是一个 .NET 5/.NET Standard 2.0 的库,能让您在终端里更方便地生成精美的界面。
|
||||
`Spectre.Console`是一个 .NET 的库,可以更轻松地创建美观的跨平台控制台应用程序。
|
||||
|
||||
深受 [Rich](https://github.com/willmcgugan/rich) 这个优秀库的启发。
|
||||
深受 [Rich](https://github.com/willmcgugan/rich) 这个Python优秀库的启发。
|
||||
|
||||
## 目录
|
||||
|
||||
1. [功能](#features)
|
||||
2. [安装](#installing)
|
||||
3. [文档](#documentation)
|
||||
4. [例子](#examples)
|
||||
5. [License](#license)
|
||||
1. [功能](#功能)
|
||||
2. [安装](#安装)
|
||||
3. [文档](#文档)
|
||||
4. [例子](#例子)
|
||||
5. [Sponsors](#Sponsors)
|
||||
6. [开源许可](#开源许可)
|
||||
|
||||
## 功能
|
||||
|
||||
@ -21,11 +22,11 @@ _[
|
||||

|
||||
|
||||
## 安装
|
||||
|
||||
最快的安装方式,就是用NuGet包管理直接安装Spectre.Console。
|
||||
最快的安装方式,就是用NuGet包管理直接安装`Spectre.Console`。
|
||||
|
||||
```csharp
|
||||
dotnet add package Spectre.Console
|
||||
@ -34,31 +35,34 @@ dotnet add package Spectre.Console
|
||||
## 文档
|
||||
|
||||
`Spectre.Console`的文档可以在这里查看
|
||||
https://spectresystems.github.io/spectre.console/
|
||||
https://spectreconsole.net/
|
||||
|
||||
## 例子
|
||||
|
||||
如果想直接运行`Spectre.Console`的例子,则需要安装[dotnet-example](https://github.com/patriksvensson/dotnet-example)工具。
|
||||
To see `Spectre.Console` in action, please see the
|
||||
[examples repository](https://github.com/spectreconsole/examples).
|
||||
|
||||
```
|
||||
> dotnet tool restore
|
||||
```
|
||||
## Sponsors
|
||||
|
||||
然后你可以列出仓库里的所有例子:
|
||||
下面这些用户正在[sponsor](https://github.com/sponsors/patriksvensson)上支持着Spectre.Console,确保这个项目的持续维护。
|
||||
|
||||
```
|
||||
> dotnet example
|
||||
```
|
||||
* [Rodney Littles II](https://github.com/RLittlesII)
|
||||
* [Martin Björkström](https://github.com/bjorkstromm)
|
||||
* [Dave Glick](https://github.com/daveaglick)
|
||||
* [Kim Gunanrsson](https://github.com/kimgunnarsson)
|
||||
* [Andrew McClenaghan](https://github.com/andymac4182)
|
||||
* [C. Augusto Proiete](https://github.com/augustoproiete)
|
||||
* [Viktor Elofsson](https://github.com/vktr)
|
||||
* [Steven Knox](https://github.com/stevenknox)
|
||||
* [David Pendray](https://github.com/dpen2000)
|
||||
* [Elmah.io](https://github.com/elmahio)
|
||||
|
||||
跑一个看看效果:
|
||||
我对此表示十分感激
|
||||
**非常感谢各位!**
|
||||
|
||||
```
|
||||
> dotnet example tables
|
||||
```
|
||||
## 开源许可
|
||||
|
||||
## License
|
||||
|
||||
版权所有 © Spectre Systems。
|
||||
版权所有 © Patrik Svensson, Phil Scott, Nils Andresen, Cédric Luthi, Frank Ray
|
||||
|
||||
Spectre.Console 基于 MIT 协议提供。查看 LICENSE 文件了解更多信息。
|
||||
|
||||
|
88
build.cake
88
build.cake
@ -4,13 +4,33 @@ var configuration = Argument("configuration", "Release");
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Tasks
|
||||
|
||||
Task("Clean")
|
||||
.Does(context =>
|
||||
{
|
||||
context.CleanDirectory("./.artifacts");
|
||||
});
|
||||
|
||||
Task("Build")
|
||||
.IsDependentOn("Clean")
|
||||
.Does(context =>
|
||||
{
|
||||
DotNetCoreBuild("./src/Spectre.Console.sln", new DotNetCoreBuildSettings {
|
||||
Information("Compiling generator...");
|
||||
DotNetBuild("./resources/scripts/Generator/Generator.sln", new DotNetBuildSettings {
|
||||
Configuration = configuration,
|
||||
Verbosity = DotNetVerbosity.Minimal,
|
||||
NoLogo = true,
|
||||
NoIncremental = context.HasArgument("rebuild"),
|
||||
MSBuildSettings = new DotNetCoreMSBuildSettings()
|
||||
MSBuildSettings = new DotNetMSBuildSettings()
|
||||
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
|
||||
});
|
||||
|
||||
Information("\nCompiling Spectre.Console...");
|
||||
DotNetBuild("./src/Spectre.Console.sln", new DotNetBuildSettings {
|
||||
Configuration = configuration,
|
||||
Verbosity = DotNetVerbosity.Minimal,
|
||||
NoLogo = true,
|
||||
NoIncremental = context.HasArgument("rebuild"),
|
||||
MSBuildSettings = new DotNetMSBuildSettings()
|
||||
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
|
||||
});
|
||||
});
|
||||
@ -19,63 +39,41 @@ Task("Test")
|
||||
.IsDependentOn("Build")
|
||||
.Does(context =>
|
||||
{
|
||||
DotNetCoreTest("./src/Spectre.Console.Tests/Spectre.Console.Tests.csproj", new DotNetCoreTestSettings {
|
||||
DotNetTest("./src/Tests/Spectre.Console.Tests/Spectre.Console.Tests.csproj", new DotNetTestSettings {
|
||||
Configuration = configuration,
|
||||
Verbosity = DotNetVerbosity.Minimal,
|
||||
NoLogo = true,
|
||||
NoRestore = true,
|
||||
NoBuild = true,
|
||||
});
|
||||
|
||||
DotNetTest("./src/Tests/Spectre.Console.Cli.Tests/Spectre.Console.Cli.Tests.csproj", new DotNetTestSettings {
|
||||
Configuration = configuration,
|
||||
Verbosity = DotNetVerbosity.Minimal,
|
||||
NoLogo = true,
|
||||
NoRestore = true,
|
||||
NoBuild = true,
|
||||
});
|
||||
});
|
||||
|
||||
Task("Package")
|
||||
.IsDependentOn("Test")
|
||||
//.IsDependentOn("Test")
|
||||
.Does(context =>
|
||||
{
|
||||
context.CleanDirectory("./.artifacts");
|
||||
|
||||
context.DotNetCorePack($"./src/Spectre.Console.sln", new DotNetCorePackSettings {
|
||||
context.DotNetPack($"./src/Spectre.Console.sln", new DotNetPackSettings {
|
||||
Configuration = configuration,
|
||||
NoRestore = true,
|
||||
NoBuild = true,
|
||||
Verbosity = DotNetVerbosity.Minimal,
|
||||
NoLogo = true,
|
||||
NoRestore = false,
|
||||
NoBuild = false,
|
||||
OutputDirectory = "./.artifacts",
|
||||
MSBuildSettings = new DotNetCoreMSBuildSettings()
|
||||
MSBuildSettings = new DotNetMSBuildSettings()
|
||||
.TreatAllWarningsAs(MSBuildTreatAllWarningsAs.Error)
|
||||
});
|
||||
});
|
||||
|
||||
Task("Publish-GitHub")
|
||||
.WithCriteria(ctx => BuildSystem.IsRunningOnGitHubActions, "Not running on GitHub Actions")
|
||||
.IsDependentOn("Package")
|
||||
.Does(context =>
|
||||
{
|
||||
var apiKey = Argument<string>("github-key", null);
|
||||
if(string.IsNullOrWhiteSpace(apiKey)) {
|
||||
throw new CakeException("No GitHub API key was provided.");
|
||||
}
|
||||
|
||||
// Publish to GitHub Packages
|
||||
var exitCode = 0;
|
||||
foreach(var file in context.GetFiles("./.artifacts/*.nupkg"))
|
||||
{
|
||||
context.Information("Publishing {0}...", file.GetFilename().FullPath);
|
||||
exitCode += StartProcess("dotnet",
|
||||
new ProcessSettings {
|
||||
Arguments = new ProcessArgumentBuilder()
|
||||
.Append("gpr")
|
||||
.Append("push")
|
||||
.AppendQuoted(file.FullPath)
|
||||
.AppendSwitchSecret("-k", " ", apiKey)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if(exitCode != 0)
|
||||
{
|
||||
throw new CakeException("Could not push GitHub packages.");
|
||||
}
|
||||
});
|
||||
|
||||
Task("Publish-NuGet")
|
||||
.WithCriteria(ctx => BuildSystem.IsRunningOnGitHubActions, "Not running on GitHub Actions")
|
||||
//.WithCriteria(ctx => BuildSystem.IsRunningOnGitHubActions, "Not running on GitHub Actions")
|
||||
.IsDependentOn("Package")
|
||||
.Does(context =>
|
||||
{
|
||||
@ -88,10 +86,11 @@ Task("Publish-NuGet")
|
||||
foreach(var file in context.GetFiles("./.artifacts/*.nupkg"))
|
||||
{
|
||||
context.Information("Publishing {0}...", file.GetFilename().FullPath);
|
||||
DotNetCoreNuGetPush(file.FullPath, new DotNetCoreNuGetPushSettings
|
||||
DotNetNuGetPush(file.FullPath, new DotNetNuGetPushSettings
|
||||
{
|
||||
Source = "https://api.nuget.org/v3/index.json",
|
||||
ApiKey = apiKey,
|
||||
SkipDuplicate = true
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -100,7 +99,6 @@ Task("Publish-NuGet")
|
||||
// Targets
|
||||
|
||||
Task("Publish")
|
||||
.IsDependentOn("Publish-GitHub")
|
||||
.IsDependentOn("Publish-NuGet");
|
||||
|
||||
Task("Default")
|
||||
|
1
docs/.gitignore
vendored
1
docs/.gitignore
vendored
@ -7,6 +7,7 @@
|
||||
[Tt]ools/
|
||||
![Tt]ools/packages.config
|
||||
[Oo]utput/
|
||||
[Cc]ache/
|
||||
![Ii]nput/
|
||||
nuget.exe
|
||||
*.com
|
||||
|
@ -1,16 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory>
|
||||
<DefaultItemExcludes>$(DefaultItemExcludes);output\**;.gitignore</DefaultItemExcludes>
|
||||
<MinVerSkip Condition="'$(Configuration)' == 'Debug'">true</MinVerSkip>
|
||||
<NoWarn>MVC1000</NoWarn>
|
||||
<MinVerSkip>true</MinVerSkip>
|
||||
<!--
|
||||
Disable NuGetAudit for now, there is an in progress PR with Statiq regarding these packages,
|
||||
but since since this is just a generator we are safe to ignore this for now.
|
||||
-->
|
||||
<NuGetAudit>false</NuGetAudit>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="input\**" />
|
||||
<Compile Remove="sass\**" />
|
||||
<Compile Include="input\api\Sections\_ConstantValue.cshtml.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@ -31,8 +38,13 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.13" />
|
||||
<PackageReference Include="MinVer" PrivateAssets="All" Version="2.3.1" />
|
||||
<PackageReference Include="Microsoft.Playwright" Version="1.49.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Statiq.CodeAnalysis" Version="1.0.0-beta.72" />
|
||||
<PackageReference Include="Statiq.Common" Version="1.0.0-beta.72" />
|
||||
<PackageReference Include="Statiq.Web" Version="1.0.0-beta.60" />
|
||||
<PackageReference Include="MinVer" PrivateAssets="All" Version="6.0.0" />
|
||||
<PackageReference Include="Statiq.Web.Netlify" Version="1.0.0-beta.60" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
2
docs/Preview.ps1
Normal file → Executable file
2
docs/Preview.ps1
Normal file → Executable file
@ -1 +1 @@
|
||||
dotnet run -- preview --virtual-dir "spectre.console"
|
||||
dotnet run -- preview
|
@ -1,7 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Docs.Extensions;
|
||||
using Docs.Shortcodes;
|
||||
using Docs.Utilities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Statiq.App;
|
||||
using Statiq.Common;
|
||||
using Statiq.Core;
|
||||
using Statiq.Web;
|
||||
|
||||
namespace Docs
|
||||
@ -11,16 +16,50 @@ namespace Docs
|
||||
public static async Task<int> Main(string[] args) =>
|
||||
await Bootstrapper.Factory
|
||||
.CreateWeb(args)
|
||||
.AddSetting(Keys.Host, "spectresystems.github.io")
|
||||
.AddSetting(Keys.LinkRoot, "/spectre.console")
|
||||
.AddSetting(Keys.Host, "spectreconsole.net")
|
||||
.AddSetting(Keys.LinksUseHttps, true)
|
||||
.AddSetting(Constants.EditLink, ConfigureEditLink())
|
||||
.ConfigureSite("spectresystems", "spectre.console", "main")
|
||||
.ConfigureDeployment(deployBranch: "docs")
|
||||
.AddSetting(Constants.SourceFiles, new List<string>
|
||||
{
|
||||
"../../src/Spectre.Console/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||
"../../src/Spectre.Console.Cli/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||
"../../src/Extensions/Spectre.Console.ImageSharp/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||
"../../src/Extensions/Spectre.Console.Json/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs"
|
||||
})
|
||||
.AddSetting(Constants.ExampleSourceFiles, new List<string>
|
||||
{
|
||||
"../../examples/**/{!bin,!obj,!packages,!*.Tests,}/**/*.cs",
|
||||
}
|
||||
)
|
||||
.ConfigureServices(i =>
|
||||
{
|
||||
i.AddSingleton(new TypeNameLinks());
|
||||
})
|
||||
.ConfigureSite("spectreconsole", "spectre.console", "main")
|
||||
.AddShortcode("Children", typeof(ChildrenShortcode))
|
||||
.AddShortcode("ColorTable", typeof(ColorTableShortcode))
|
||||
.AddShortcode("EmojiTable", typeof(EmojiTableShortcode))
|
||||
.AddShortcode("Alert", typeof(AlertShortcode))
|
||||
.AddShortcode("Info", typeof(InfoShortcode))
|
||||
.AddShortcode("AsciiCast", typeof(AsciiCastShortcode))
|
||||
.AddShortcode("Example", typeof(ExampleSnippet))
|
||||
.AddPipelines()
|
||||
.BuildPipeline(
|
||||
"Bootstrap",
|
||||
builder => builder
|
||||
.WithInputReadFiles("../node_modules/asciinema-player/dist/bundle/asciinema-player.js")
|
||||
.WithProcessModules(new SetDestination(Config.FromDocument(doc => new NormalizedPath($"./assets/{doc.Source.FileName}")), true))
|
||||
.WithOutputWriteFiles()
|
||||
)
|
||||
.AddProcess(ProcessTiming.Initialization, _ => new ProcessLauncher("npm", "install --audit false --fund false --progress false")
|
||||
{
|
||||
LogErrors = false
|
||||
})
|
||||
.AddProcess(ProcessTiming.Initialization, _ => new ProcessLauncher("dotnet", "playwright install chromium"))
|
||||
.AddProcess(ProcessTiming.BeforeDeployment, _ => new ProcessLauncher("npm", "run build:tailwind")
|
||||
{
|
||||
LogErrors = false
|
||||
})
|
||||
.RunAsync();
|
||||
|
||||
private static Config<string> ConfigureEditLink()
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Documentation
|
||||
|
||||
To start contributing to the [Spectre.Console](https://github.com/spectresystems/spectre.console) documentation, you will need the [.NET Core SDK](https://dot.net) 3.1 or higher.
|
||||
To start contributing to the [Spectre.Console](https://github.com/spectreconsole/spectre.console) documentation, you will need the [.NET Core SDK](https://dot.net) 7.0.100 or higher (as defined in the repository root `global.json` file).
|
||||
|
||||
## Running Preview Site
|
||||
|
||||
@ -10,9 +10,11 @@ The documentation site uses [Statiq](https://statiq.dev), a static site generato
|
||||
> Preview.ps1
|
||||
```
|
||||
|
||||
After the build is complete, you can navigate to [http://localhost:5080/spectre.console](http://localhost:5080/spectre.console).
|
||||
After the build is complete, you can navigate to [http://localhost:5080](http://localhost:5080).
|
||||
|
||||
**Note that the site runs under a virtual directory.**
|
||||
## Npm
|
||||
|
||||
The site uses some tools from the JavaScript ecosystem including npm. While Statiq will execute `npm install` and other commands as needed, you need to have [npm installed](https://www.npmjs.com/get-npm) before running a site build.
|
||||
|
||||
## Editing Content
|
||||
|
||||
@ -21,7 +23,7 @@ The documentation is written using [Markdown](https://www.markdownguide.org/basi
|
||||
Markdown files can be found under the following directories:
|
||||
|
||||
- [/input](./input)
|
||||
- [/appendix](./input/appendix)
|
||||
- [/appendix](./input/appendix)
|
||||
|
||||
## Editing Layout
|
||||
|
||||
@ -35,7 +37,7 @@ The documentation site has custom enhancements to Statiq located under the [./sr
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Spectre Systems AB
|
||||
Copyright (c) 2020 Patrik Svensson, Phil Scott, Nils Andresen
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
12
docs/dotnet-tools.json
Normal file
12
docs/dotnet-tools.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {
|
||||
"microsoft.playwright.cli": {
|
||||
"version": "1.2.3",
|
||||
"commands": [
|
||||
"playwright"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
6
docs/global.json
Normal file
6
docs/global.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "9.0.100",
|
||||
"rollForward": "latestFeature"
|
||||
}
|
||||
}
|
1
docs/input/CNAME
Normal file
1
docs/input/CNAME
Normal file
@ -0,0 +1 @@
|
||||
spectreconsole.net
|
72
docs/input/DOC_TEMPLATE.md
Normal file
72
docs/input/DOC_TEMPLATE.md
Normal file
@ -0,0 +1,72 @@
|
||||
Title: Short title of the Widget being documented. Typically the class name
|
||||
Order: 99999
|
||||
Description: Description of the widget. This will be displayed on social card
|
||||
Highlights:
|
||||
- List features.
|
||||
- These will be used for the social card.
|
||||
- Keep to three items.
|
||||
Reference:
|
||||
- T:Spectre.Console.BarChart
|
||||
Hidden: true
|
||||
---
|
||||
|
||||
<!---
|
||||
Documentation steps
|
||||
1. Edit front matter. Change all fields. Order dictates how it is sorted in the sidebar. Remove hidden attributes.
|
||||
Make sure to reference the appropriate XMLDOC page. You can find this by looking in the generated HTML
|
||||
of the API reference section. You can reference multiple items e.g. types, methods, etc that are related to the Widget.
|
||||
2. Remove comments as you edit the fields.
|
||||
3. All widgets should have at minimum description and a usage section.
|
||||
-->
|
||||
|
||||
<!---
|
||||
Short description of the widget. Can be the same as the description above
|
||||
-->
|
||||
|
||||
|
||||
<!---
|
||||
Optional: Embed an asciicast. The cast parameter should be the base name of the cast. There are two files,
|
||||
one suffixed with -rich.cast and a second named -plain.cast. The cast attribute should be the name without
|
||||
the suffix.
|
||||
|
||||
To generate a new cast file, open the \resources\scripts\Generator\Generator.sln project and add a new sample in the
|
||||
Commands/AsciiCast/Samples/ folder. If the widget is static such as a tree or a table, try and animate the widget
|
||||
using the Live widget to change the content or styling.
|
||||
|
||||
Running the generator project with by executing
|
||||
|
||||
dotnet run -- samples -l
|
||||
|
||||
and pick your sample. This will generate a new asciicast in the docs/input/assets/casts folder which can then be referenced via:
|
||||
|
||||
<?# AsciiCast cast="sample-name" /?>
|
||||
-->
|
||||
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic usage
|
||||
|
||||
<!---
|
||||
Code sample for a default output of the widget. Code Samples can be embedded with a markdown code block or
|
||||
linked to via the Example snipped. The example snippet takes the XMLDOC reference of the snippet from the Examples
|
||||
project that you want to reference.
|
||||
|
||||
If linking to a method it will, by default, only include the method body. Include BodyOnly="false" to include
|
||||
the entire method including the declaration.
|
||||
|
||||
<?# Example symbol="M:Prompt.Program.AskConfirmation" /?>
|
||||
-->
|
||||
|
||||
### Additional Styling
|
||||
|
||||
<!---
|
||||
Include additional examples of styling or functionality
|
||||
-->
|
||||
|
||||
### More styling and functions
|
||||
|
||||
<!---
|
||||
Include additional examples of styling or functionality
|
||||
-->
|
3
docs/input/_ViewStart.cshtml
Normal file
3
docs/input/_ViewStart.cshtml
Normal file
@ -0,0 +1,3 @@
|
||||
@{
|
||||
Layout = @"_layout.cshtml";
|
||||
}
|
@ -1,256 +1,308 @@
|
||||
@using Docs.Extensions
|
||||
@using Statiq.CodeAnalysis
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link href="@Context.GetLink("/assets/bootstrap/bootstrap.css")" rel="stylesheet" />
|
||||
<link href="@Context.GetLink("/assets/css/styles.css")" rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto+Mono:wght@400;700&family=Roboto+Slab:wght@400;700&family=Roboto:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&display=swap" rel="stylesheet" data-no-mirror>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.19.0/themes/prism.css">
|
||||
<link href="@Context.GetLink("/assets/styles.css")" rel="stylesheet"/>
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com"/>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;700&display=swap" rel="stylesheet"/>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
|
||||
<script src="https://kit.fontawesome.com/a1cad7ed9a.js" crossorigin="anonymous" data-no-mirror></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/mermaid@8.4.8/dist/mermaid.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/svg-pan-zoom@3.6.1/dist/svg-pan-zoom.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.19.0/components/prism-core.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/prismjs@1.19.0/plugins/autoloader/prism-autoloader.min.js" data-no-mirror></script>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="@Context.GetLink("/assets/favicons/apple-touch-icon.png")">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="@Context.GetLink("/assets/favicons/favicon-32x32.png")">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="@Context.GetLink("/assets/favicons/favicon-16x16.png")">
|
||||
|
||||
@{
|
||||
string title = @Document.ContainsKey(Keys.Title) ? $"Spectre.Console - {Document.GetString(Keys.Title)}" : "Spectre.Console";
|
||||
@{
|
||||
string title = Document.ContainsKey(Keys.Title) ? $"Spectre.Console - {Document.GetString(Keys.Title)}" : "Spectre.Console";
|
||||
string description = Document.ContainsKey(Constants.Description) ? Document.GetString(Constants.Description) : "Spectre.Console is a .NET library that makes it easier to create beautiful console applications";
|
||||
var card = Context.FindCard(Model.Id);
|
||||
var urlBase = $"https://{Document.GetString(Keys.Host)}/";
|
||||
}
|
||||
<title>@title</title>
|
||||
<meta name="description" content="@description"/>
|
||||
<meta name="xref" content="@HtmlEncoder.Encode(Document.GetString(WebKeys.Xref))" />
|
||||
|
||||
@if (card != null)
|
||||
{
|
||||
<meta name="twitter:card" content="summary_large_image"/>
|
||||
<meta name="og:title" content="@title"/>
|
||||
<meta name="og:description" content="@description"/>
|
||||
<meta name="og:image" content="@(urlBase + card)"/>
|
||||
}
|
||||
|
||||
<script>
|
||||
if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
|
||||
document.documentElement.classList.add('dark');
|
||||
} else {
|
||||
document.documentElement.classList.remove('dark');
|
||||
}
|
||||
<title>@title</title>
|
||||
</head>
|
||||
<body class="d-flex flex-column">
|
||||
<div class="flex-grow-1 d-flex flex-column">
|
||||
</script>
|
||||
|
||||
<nav id="topnav" class="navbar navbar-expand-lg navbar-light">
|
||||
<div class="container py-3">
|
||||
<a class="navbar-brand" href="@Context.GetLink("/")"><img id="logo" src="@Context.GetLink("/assets/logo.svg")" alt="Spectre.Console"> Spectre.Console</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText" aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</head>
|
||||
<body class="antialiased text-slate-800 dark:text-slate-200 bg-slate-100 dark:bg-slate-800 transition-colors min-h-full flex flex-col">
|
||||
<header class="flex-none sticky top-0 z-40 text-sm font-medium bg-slate-200 backdrop-blur dark:bg-slate-800 ring-1 ring-slate-900 dark:ring-slate-700 ring-opacity-5 shadow-lg py-2 md:py-4">
|
||||
<nav class="flex flex-row container mx-auto items-center">
|
||||
<a class="flex flex-row items-center" href="@Context.GetLink("/")">
|
||||
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
id="logo" class="w-auto h-10 md:h-12 fill-slate-700 dark:fill-slate-400 dark:stroke-slate-900" height="48" width="48" viewBox="0 0 1270.000000 1270.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,1270.000000) scale(0.100000,-0.100000)">
|
||||
<path d="M799 10610 c-199 -48 -354 -191 -414 -383 l-25 -78 0 -3084 0 -3084
|
||||
25 -79 c45 -141 155 -270 289 -335 124 -61 -80 -57 2819 -57 l2646 0 5 -43 c3
|
||||
-23 8 -71 11 -105 13 -137 88 -334 179 -471 57 -85 187 -219 247 -254 25 -15
|
||||
76 -34 112 -43 87 -22 163 -7 246 46 120 78 195 211 234 411 l23 124 14 -55
|
||||
c63 -263 172 -511 326 -741 94 -142 229 -291 313 -348 272 -185 583 -197 750
|
||||
-30 66 67 84 109 89 215 4 90 4 91 -51 230 -108 276 -137 477 -122 868 l7 196
|
||||
77 0 c55 0 118 -11 229 -39 l154 -38 50 -84 c103 -172 221 -427 277 -599 38
|
||||
-120 70 -274 86 -412 8 -75 21 -155 29 -178 37 -106 117 -199 220 -253 51 -26
|
||||
202 -35 283 -17 83 18 193 97 268 192 157 199 256 485 286 825 11 122 6 524
|
||||
-7 583 -5 24 -1 26 62 43 64 16 67 16 80 0 39 -50 109 -215 149 -351 25 -85
|
||||
55 -174 67 -199 73 -156 261 -206 441 -117 65 32 110 70 159 135 128 169 178
|
||||
414 157 764 -8 143 -38 350 -55 376 -2 4 7 25 22 46 77 112 168 344 200 504
|
||||
l16 86 87 28 c188 60 391 170 498 269 132 122 183 230 183 383 0 71 -5 98 -24
|
||||
138 -24 52 -82 112 -138 141 -52 28 -205 30 -378 5 -80 -11 -179 -23 -220 -27
|
||||
l-75 -6 -29 56 c-33 65 -137 182 -211 236 -75 55 -156 94 -382 181 -110 43
|
||||
-221 87 -245 100 -54 27 -92 69 -125 138 -25 52 -26 59 -20 180 4 69 16 200
|
||||
26 291 52 430 53 809 5 1170 -54 405 -249 740 -569 979 -136 102 -297 190
|
||||
-419 231 l-36 12 0 433 c0 433 0 434 -25 512 -52 167 -171 292 -341 360 l-69
|
||||
28 -4215 2 c-2318 0 -4231 -3 -4251 -7z m8363 -1476 c417 -53 735 -193 962
|
||||
-423 98 -98 155 -175 210 -282 84 -160 117 -292 141 -559 28 -313 17 -684 -30
|
||||
-1025 -9 -60 -18 -164 -22 -230 -10 -208 22 -314 136 -452 76 -91 124 -118
|
||||
391 -218 307 -116 377 -155 450 -249 23 -31 41 -58 39 -60 -2 -2 -47 8 -99 21
|
||||
-131 35 -268 36 -360 3 -132 -47 -248 -116 -364 -218 -163 -143 -516 -488
|
||||
-703 -687 -350 -372 -504 -514 -701 -644 -348 -231 -878 -408 -1322 -442 -409
|
||||
-31 -796 45 -1059 208 -111 69 -249 210 -292 298 -32 65 -34 76 -33 165 1 104
|
||||
23 178 85 287 75 131 137 194 430 441 181 152 251 295 250 511 -1 152 -16 223
|
||||
-117 560 -35 117 -61 217 -58 222 3 5 20 9 38 9 55 0 217 31 261 50 53 23 103
|
||||
73 132 131 43 88 56 187 59 437 2 266 -1 258 91 292 108 40 254 21 330 -45 35
|
||||
-30 35 -32 53 -170 41 -311 106 -484 206 -546 48 -29 168 -48 381 -59 188 -10
|
||||
432 -1 548 20 76 14 206 56 266 86 64 32 122 101 144 170 15 49 17 82 12 253
|
||||
-5 198 -27 398 -52 482 -42 146 -125 221 -290 265 -57 15 -108 19 -268 19
|
||||
l-197 0 0 45 c0 120 -37 255 -82 300 -76 77 -210 5 -291 -157 -31 -60 -67
|
||||
-184 -67 -229 0 -27 -6 -34 -41 -50 -65 -29 -159 -98 -195 -144 -34 -43 -67
|
||||
-119 -79 -181 l-6 -35 -57 28 c-114 57 -270 58 -379 2 -61 -31 -70 -21 -49 54
|
||||
33 118 16 442 -29 536 -38 79 -114 84 -188 12 -68 -66 -136 -230 -137 -330 l0
|
||||
-29 -61 7 c-34 3 -93 6 -131 6 l-69 0 6 48 c14 97 56 282 84 368 155 475 486
|
||||
821 963 1008 108 42 308 94 430 110 62 9 124 17 138 20 76 11 479 5 592 -10z
|
||||
m-7029 -78 c18 -8 261 -243 569 -552 582 -584 560 -559 543 -651 -6 -33 -69
|
||||
-101 -523 -557 -553 -554 -564 -564 -644 -551 -89 15 -151 110 -128 198 10 37
|
||||
65 95 463 495 l452 452 -472 473 c-414 414 -472 477 -478 510 -25 132 98 235
|
||||
218 183z m7169 -1405 c164 -57 201 -136 234 -502 37 -414 9 -486 -212 -558
|
||||
-155 -50 -298 -64 -579 -57 -249 6 -398 23 -439 50 -95 62 -177 346 -180 621
|
||||
-1 135 0 142 28 203 50 109 148 179 304 218 149 37 329 53 567 50 191 -2 216
|
||||
-4 277 -25z m-2002 -174 c95 -34 118 -52 152 -114 52 -94 63 -159 62 -368 -1
|
||||
-358 -44 -479 -187 -520 -146 -42 -612 -65 -727 -36 -153 38 -196 98 -226 316
|
||||
-16 120 -31 487 -21 527 9 35 89 121 140 151 99 58 228 76 522 73 200 -2 214
|
||||
-3 285 -29z m-1604 -443 c45 -33 67 -70 71 -121 5 -59 -25 -117 -77 -147 -35
|
||||
-21 -47 -21 -980 -24 -520 -2 -964 0 -988 3 -57 8 -116 60 -130 115 -19 75 12
|
||||
146 78 182 34 17 75 18 1017 16 974 -3 982 -3 1009 -24z m5329 -2140 c66 -7
|
||||
173 -14 237 -14 103 0 146 5 247 26 24 5 24 5 18 -64 -15 -159 -89 -371 -180
|
||||
-515 l-43 -68 -57 113 c-72 145 -160 261 -318 422 l-126 128 51 -7 c28 -3 105
|
||||
-13 171 -21z m-812 -652 c53 -41 140 -115 193 -165 96 -91 224 -231 224 -245
|
||||
0 -5 -30 -18 -67 -30 -79 -25 -305 -84 -308 -80 -1 2 -12 53 -24 113 -28 135
|
||||
-70 268 -127 402 -24 57 -44 106 -44 109 0 9 43 -20 153 -104z m-1173 -560
|
||||
c-9 -4 -271 61 -315 78 -29 11 -28 12 79 55 59 24 111 46 114 49 3 3 33 -36
|
||||
67 -87 34 -50 59 -93 55 -95z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="text-lg md:text-2xl font-light ml-2 lg:ml-4 font-mono tracking-tighter">Spectre.Console</span>
|
||||
</a>
|
||||
<div class="ml-auto">
|
||||
<ul class="flex flex-row">
|
||||
<li>
|
||||
<button aria-label="Toggle Dark Mode" class="mr-4 dark:text-yellow-300 stroke-1 opacity-80" onclick="swapTheme()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarText">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
</ul>
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link font-weight-light font-size-lg text-red" href="https://github.com/sponsors/patriksvensson"><i class="far fa-heart"></i> Sponsor</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link font-weight-light font-size-lg" href="https://github.com/spectresystems/spectre.console"><i class="fab fa-github"></i> GitHub</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</li>
|
||||
<li>
|
||||
<a class="flex flex-row items-center text-rose-700 dark:text-rose-500" href="https://github.com/sponsors/patriksvensson">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<title>Sponsor</title>
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
|
||||
</svg>
|
||||
<span class="hidden sm:block">Sponsor</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="ml-4">
|
||||
<a class="flex flex-row items-center text-gray-600 fill-slate-200 stroke-slate-800 fill-slate-900 dark:stroke-slate-500 dark:fill-slate-300 dark:text-slate-300" href="https://github.com/spectreconsole/spectre.console">
|
||||
<svg role="img" class="h-6 w-6 mr-1" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<title>GitHub icon</title>
|
||||
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/>
|
||||
</svg>
|
||||
<span class="hidden sm:block">GitHub</span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
@if (IsSectionDefined(Constants.Sections.Splash))
|
||||
{
|
||||
@RenderSection(Constants.Sections.Splash, false)
|
||||
}
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<main class="container mx-auto pt-8 w-full">
|
||||
<div class="flex flex-col-reverse lg:flex-row">
|
||||
<nav class="flex-none font-light text-sm xl:text-base sm:mr-16 mt-8 pt-6 lg:mt-0 lg:pt-0 lg:pb-10 border-t border-gray-300 lg:border-t-0">
|
||||
@{
|
||||
string section = "docs";
|
||||
}
|
||||
|
||||
<div class="flex-grow-1 d-flex bg-body flex-column @(section != null ? "section-" + section : null)">
|
||||
@if(section != null)
|
||||
{
|
||||
<div id="titlebar" class="py-4">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
@{
|
||||
string titleBarClasses = Document.GetBool(Constants.NoSidebar) ? string.Empty : "offset-md-3 offset-lg-2";
|
||||
}
|
||||
<div class="@titleBarClasses px-3 px-md-0">
|
||||
<div class="section text-uppercase">Spectre.Console</div>
|
||||
<div class="text-white m-0 title">@(Document.GetString(Keys.Title) ?? Document.GetTitle())</div>
|
||||
@if (IsSectionDefined(Constants.Sections.Subtitle))
|
||||
{
|
||||
@RenderSection(Constants.Sections.Subtitle, false)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="undertitle">
|
||||
<div class="container bg-body">
|
||||
<div class="row">
|
||||
@if (Document.GetBool(Constants.NoSidebar))
|
||||
{
|
||||
<div class="col">
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="col-md-3 col-lg-2 bg-body">
|
||||
</div>
|
||||
<div class="col-md-9 col-lg-8 bg-white">
|
||||
</div>
|
||||
}
|
||||
<div class="col-lg-2 d-none d-lg-block bg-section">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div class="flex-grow-1 d-flex flex-column bg-body">
|
||||
@if (Document.GetBool(Constants.NoContainer))
|
||||
var sidebar = Context.GetSidebar();
|
||||
var root = sidebar.Node;
|
||||
<div class="text-xl @(Document.IdEquals(root) ? "font-bold" : null)">
|
||||
@if (sidebar.ShowLink)
|
||||
{
|
||||
<div class="bg-white">
|
||||
@RenderBody()
|
||||
</div>
|
||||
@Html.DocumentLink(root)
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="container flex-grow-1 d-flex flex-column bg-white">
|
||||
<div class="row flex-grow-1 align-items-stretch">
|
||||
@if (Document.GetBool(Constants.NoSidebar))
|
||||
{
|
||||
IgnoreSection(Constants.Sections.Sidebar);
|
||||
@sidebar.Title;
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="col">
|
||||
@RenderBody()
|
||||
</div>
|
||||
@foreach (var sidebarItem in sidebar.Leafs)
|
||||
{
|
||||
var document = sidebarItem.Node;
|
||||
if (string.IsNullOrWhiteSpace(sidebarItem.Title))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var documentChildren = sidebarItem.Leafs;
|
||||
<div class="text-teal-800 font-medium dark:text-teal-400 mt-4">
|
||||
@if (sidebarItem.ShowLink)
|
||||
{
|
||||
@Html.DocumentLink(document)
|
||||
}
|
||||
else
|
||||
{
|
||||
@sidebarItem.Title;
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (documentChildren.Any())
|
||||
{
|
||||
<div class="ml-2 flex flex-row flex-wrap lg:flex-col border-separate">
|
||||
@foreach (var childItem in documentChildren)
|
||||
{
|
||||
var child = childItem.Node;
|
||||
<div class="mt-2 mr-4 @(Document.IdEquals(child) ? "font-bold" : null)">
|
||||
@Html.DocumentLink(child)
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
</nav>
|
||||
<article class="flex-1 min-w-0">
|
||||
<header class="text-slate-900 dark:text-slate-50 mb-4">
|
||||
@RenderSection("header", required: false)
|
||||
@if (!IsSectionDefined("header"))
|
||||
{
|
||||
<h1 class="text-2xl md:text-4xl font-extrabold">@(Document.GetString(Keys.Title) ?? Document.GetTitle())</h1>
|
||||
}
|
||||
|
||||
@RenderSection("subheading", required: false)
|
||||
</header>
|
||||
<div class="prose prose-sm md:prose-base prose-slate dark:prose-invert max-w-full font-light lg:leading-loose">
|
||||
@RenderBody()
|
||||
|
||||
@{
|
||||
var referenceLinks = Model.GetList<string>(Constants.ApiReference);
|
||||
if (referenceLinks != null)
|
||||
{
|
||||
<h3>References</h3>
|
||||
<ul>
|
||||
@foreach (var link in referenceLinks)
|
||||
{
|
||||
if (Context.TryGetXrefDocument(link, out var refDoc, out string error))
|
||||
{
|
||||
<li>
|
||||
@{
|
||||
var kind = refDoc.GetString(CodeAnalysisKeys.SpecificKind);
|
||||
var prefix = string.Empty;
|
||||
var containingType = @refDoc.GetDocument(CodeAnalysisKeys.ContainingType);
|
||||
if (containingType != null)
|
||||
{
|
||||
prefix = containingType.GetString(CodeAnalysisKeys.DisplayName) + ".";
|
||||
}
|
||||
}
|
||||
|
||||
@if (!string.IsNullOrWhiteSpace(prefix)){ <span class="text-slate-600 dark:text-slate-400">@prefix</span>}@Html.DocumentLink(refDoc, refDoc.GetString(CodeAnalysisKeys.DisplayName) ?? refDoc.GetTitle()) <span class="ml-4 uppercase text-xs text-slate-700 dark:text-slate-400">@kind</span>
|
||||
</li>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="sidebar col-md-3 col-lg-2 pt-2 bg-body">
|
||||
@if (IsSectionDefined(Constants.Sections.Sidebar))
|
||||
{
|
||||
@RenderSection(Constants.Sections.Sidebar, false)
|
||||
}
|
||||
else
|
||||
{
|
||||
IDocument root = OutputPages["index.html"].First();
|
||||
<div class="sidebar-nav-item @(Document.IdEquals(root) ? "active" : null)">
|
||||
@if(root.ShowLink())
|
||||
{
|
||||
@Html.DocumentLink(root)
|
||||
}
|
||||
else
|
||||
{
|
||||
@root.GetTitle()
|
||||
}
|
||||
</div>
|
||||
|
||||
@foreach (IDocument document in OutputPages.GetChildrenOf(root).OnlyVisible())
|
||||
{
|
||||
if(string.IsNullOrWhiteSpace(document.GetTitle()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
DocumentList<IDocument> documentChildren = OutputPages.GetChildrenOf(document);
|
||||
<div class="sidebar-nav-item @(Document.IdEquals(document) ? "active" : null) @(documentChildren.Any() ? "has-children" : null)">
|
||||
@if(document.ShowLink())
|
||||
{
|
||||
@Html.DocumentLink(document)
|
||||
}
|
||||
else
|
||||
{
|
||||
@document.GetTitle()
|
||||
}
|
||||
</div>
|
||||
|
||||
@if (documentChildren.OnlyVisible().Any())
|
||||
{
|
||||
<div class="sidebar-nav-children @(Document.IdEquals(document) || documentChildren.Any(x => Document.IdEquals(x)) ? "active" : null)">
|
||||
@foreach (IDocument child in documentChildren.OnlyVisible())
|
||||
{
|
||||
<div class="sidebar-nav-child @(Document.IdEquals(child) ? "active" : null)">
|
||||
@Html.DocumentLink(child)
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
}
|
||||
</div>
|
||||
<div class="col-md-9 col-lg-8 pt-4 pt-md-0 pb-4 px-4">
|
||||
@RenderBody()
|
||||
</div>
|
||||
Context.LogWarning(Model, $"Error finding xref for {link} - {error}");
|
||||
}
|
||||
<div class="col-lg-2 d-none d-lg-block bg-body pl-3 pt-3">
|
||||
@{
|
||||
IReadOnlyList<IDocument> headings = Document.GetDocumentList(Statiq.Html.HtmlKeys.Headings);
|
||||
if (headings.Count > 0)
|
||||
{
|
||||
<div class="border-bottom mb-3">
|
||||
<p class="small font-weight-bold">On This Page</p>
|
||||
@foreach (IDocument heading in headings)
|
||||
{
|
||||
<p class="small"><a href="#@(heading.GetString(Statiq.Html.HtmlKeys.HeadingId))">@(await heading.GetContentStringAsync())</a></p>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@if (Document.ContainsKey("EditLink"))
|
||||
{
|
||||
<p class="small font-weight-bold"><a href="@Document.GetString("EditLink")"><i class="fad fa-pencil"></i> Edit This Page</a></p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</article>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="py-4 md:py-8 mt-8 bg-gray-100 dark:bg-slate-800 text-sm border-t border-gray-200 dark:border-slate-700">
|
||||
<div class="container">
|
||||
<div class="flex flex-row">
|
||||
<span>© @DateTime.Today.Year Patrik Svensson, Phil Scott, Nils Andresen</span>
|
||||
<span class="ml-auto">Powered by <a href="https://www.netlify.com/">Netlify</a></span>
|
||||
<span class="ml-auto">Supported by the <a href="https://dotnetfoundation.org">.NET Foundation</a></span>
|
||||
<span class="ml-auto">@VersionUtilities.GetVersion()</span>
|
||||
</div>
|
||||
<div id="footer" class="p-3 text-white font-size-sm">
|
||||
<div class="container">
|
||||
<div>
|
||||
<span>© @DateTime.Today.Year Spectre Systems AB</span>
|
||||
<span class="float-right" style="color: #888888;">@VersionUtilities.GetVersion()</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
mermaid.initialize(
|
||||
{
|
||||
flowchart:
|
||||
{
|
||||
useMaxWidth: false
|
||||
},
|
||||
startOnLoad: false,
|
||||
cloneCssStyles: false
|
||||
});
|
||||
mermaid.init(undefined, ".mermaid");
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
// Remove the max-width setting that Mermaid sets
|
||||
var mermaidSvg = $('.mermaid svg');
|
||||
mermaidSvg.addClass('img-responsive');
|
||||
mermaidSvg.css('max-width', '');
|
||||
|
||||
// Make it scrollable
|
||||
var target = document.querySelector(".mermaid svg");
|
||||
if(target !== null)
|
||||
{
|
||||
var panZoom = window.panZoom = svgPanZoom(target, {
|
||||
zoomEnabled: true,
|
||||
controlIconsEnabled: true,
|
||||
fit: true,
|
||||
center: true,
|
||||
maxZoom: 20,
|
||||
zoomScaleSensitivity: 0.6
|
||||
});
|
||||
<script>
|
||||
// adapted from https://www.w3schools.com/howto/howto_js_filter_table.asp
|
||||
function search(input, searchTarget, columnIndex) {
|
||||
// Declare variables
|
||||
var filter, table, tr, td, i, txtValue;
|
||||
filter = input.value.toUpperCase();
|
||||
table = document.getElementById(searchTarget);
|
||||
tr = table.getElementsByTagName("tr");
|
||||
|
||||
// Do the reset once right away to fit the diagram
|
||||
panZoom.resize();
|
||||
panZoom.fit();
|
||||
panZoom.center();
|
||||
|
||||
$(window).resize(function(){
|
||||
panZoom.resize();
|
||||
panZoom.fit();
|
||||
panZoom.center();
|
||||
});
|
||||
}
|
||||
// Loop through all table rows, and hide those who don't match the search query
|
||||
for (i = 0; i < tr.length; i++) {
|
||||
td = tr[i].getElementsByTagName("td")[columnIndex];
|
||||
if (td) {
|
||||
txtValue = td.textContent || td.innerText;
|
||||
if (txtValue.toUpperCase().indexOf(filter) > -1) {
|
||||
tr[i].style.display = "";
|
||||
} else {
|
||||
tr[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0/prism.min.js" integrity="sha512-YBk7HhgDZvBxmtOfUdvX0z8IH2d10Hp3aEygaMNhtF8fSOvBZ16D/1bXZTJV6ndk/L/DlXxYStP8jrF77v2MIg==" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.23.0/plugins/autoloader/prism-autoloader.min.js" integrity="sha512-zc7WDnCM3aom2EziyDIRAtQg1mVXLdILE09Bo+aE1xk0AM2c2cVLfSW9NrxE5tKTX44WBY0Z2HClZ05ur9vB6A==" crossorigin="anonymous"></script>
|
||||
<script src="@Context.GetLink("/assets/asciinema-player.js")"></script>
|
||||
<script>
|
||||
document.querySelectorAll('asciinema-player').forEach(cast => {
|
||||
AsciinemaPlayer.create(cast.attributes['src'].value, cast, {autoplay: true, fit: 'none', fontSize: 'inherit'});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
function swapTheme(){
|
||||
if (document.documentElement.classList.contains('dark')) {
|
||||
document.documentElement.classList.remove('dark');
|
||||
localStorage.theme = 'light';
|
||||
} else {
|
||||
document.documentElement.classList.add('dark');
|
||||
localStorage.theme = 'dark';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,42 +0,0 @@
|
||||
<div>
|
||||
@foreach (IDocument post in Document.GetChildren())
|
||||
{
|
||||
IDocument topicDocument = Outputs[nameof(Archives)][$"blog/topics/{post.GetString("topic")}/index.html"];
|
||||
string excerpt = post.GetString(Statiq.Html.HtmlKeys.Excerpt);
|
||||
<div>
|
||||
<div class="p-3 mb-2 bg-light page-box">
|
||||
<h5><a href="@Context.GetLink(post)">@post.GetString("Title")</a></h5>
|
||||
<div class="small text-black-50">
|
||||
@post.GetDateTime("Published").ToLongDateString() in
|
||||
<a href="@(topicDocument.GetLink())"><span class="badge badge-light">@topicDocument.GetTitle()</span></a>
|
||||
</div>
|
||||
@if (!string.IsNullOrEmpty(excerpt))
|
||||
{
|
||||
@Html.Raw(excerpt)
|
||||
<p class="small"><a href="@Context.GetLink(post)">Read more...</a></p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
@{
|
||||
IDocument older = Document.GetDocument(Keys.Next);
|
||||
IDocument newer = Document.GetDocument(Keys.Previous);
|
||||
}
|
||||
@if (older != null || newer != null)
|
||||
{
|
||||
<div class="d-flex flex-row justify-content-between">
|
||||
<div>
|
||||
@if (older != null)
|
||||
{
|
||||
<a class="btn btn-primary" href="@Context.GetLink(older)" role="button">Older</a>
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
@if (newer != null)
|
||||
{
|
||||
<a class="btn btn-primary" href="@Context.GetLink(newer)" role="button">Newer</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
@ -1,3 +0,0 @@
|
||||
@{
|
||||
Layout = @"/_layout.cshtml";
|
||||
}
|
38
docs/input/analyzer/rules/RULE_TEMPLATE.md
Normal file
38
docs/input/analyzer/rules/RULE_TEMPLATE.md
Normal file
@ -0,0 +1,38 @@
|
||||
---
|
||||
Title: SpectreXxxx
|
||||
Description: Rule title
|
||||
Category: Usage
|
||||
Severity: Hidden, Info, Warning, or Error
|
||||
Excluded: true
|
||||
---
|
||||
|
||||
## Cause
|
||||
|
||||
A concise-as-possible description of when this rule is violated. If there's a lot to explain, begin with "A violation of this rule occurs when..."
|
||||
|
||||
## Reason for rule
|
||||
|
||||
Explain why the user should care about the violation.
|
||||
|
||||
## How to fix violations
|
||||
|
||||
To fix a violation of this rule, [describe how to fix a violation].
|
||||
|
||||
## Examples
|
||||
|
||||
### Violates
|
||||
|
||||
Example(s) of code that violates the rule.
|
||||
|
||||
### Does not violate
|
||||
|
||||
Example(s) of code that does not violate the rule.
|
||||
|
||||
## How to suppress violations
|
||||
|
||||
**If the severity of your analyzer isn't _Warning_, delete this section.**
|
||||
|
||||
```csharp
|
||||
#pragma warning disable Spectre1000 // <Rule name>
|
||||
#pragma warning restore Spectre1000 // <Rule name>
|
||||
```
|
56
docs/input/analyzer/rules/Spectre1021.md
Normal file
56
docs/input/analyzer/rules/Spectre1021.md
Normal file
@ -0,0 +1,56 @@
|
||||
---
|
||||
Title: Spectre1021
|
||||
Description: Avoid prompting for input while a current renderable is running.
|
||||
Category: Usage
|
||||
Severity: Warning
|
||||
---
|
||||
|
||||
## Cause
|
||||
|
||||
A violation of this rule occurs when an AnsiConsole prompt is called within the context of an executing renderable e.g. `Progress`, `Status` and `Live`. Concurrent LiveRenderable are not supported and will cause issues when running simultaneously.
|
||||
|
||||
## Reason for rule
|
||||
|
||||
When LiveRenderable such as `Progress`, `Status` or `Live` are running they expect to be running exclusively. They rely on ANSI sequences to draw and keep the console experience consistent. Prompts also rely on ANSI sequences for their drawing. Simultaneous running can result in corrupt output.
|
||||
|
||||
## How to fix violations
|
||||
|
||||
Redesign logic to allow one LiveRenderable to complete before using a prompt or prompt before starting the operation.
|
||||
|
||||
## Examples
|
||||
|
||||
### Violates
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Progress().Start(ctx =>
|
||||
{
|
||||
// code to update progress bar
|
||||
var answer = AnsiConsole.Confirm("Continue?");
|
||||
});
|
||||
```
|
||||
|
||||
### Does not violate
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Progress().Start(ctx =>
|
||||
{
|
||||
// code to update progress bar
|
||||
|
||||
// persist state to restart progress after asking question
|
||||
});
|
||||
|
||||
var answer = AnsiConsole.Confirm("Continue?");
|
||||
|
||||
AnsiConsole.Progress().Start(ctx =>
|
||||
{
|
||||
// apply persisted state
|
||||
// code to update progress bar
|
||||
```
|
||||
|
||||
## How to suppress violations
|
||||
|
||||
```csharp
|
||||
#pragma warning disable Spectre1021 // <Rule name>
|
||||
|
||||
#pragma warning restore Spectre1021 // <Rule name>
|
||||
```
|
3
docs/input/analyzer/rules/_ViewStart.cshtml
Normal file
3
docs/input/analyzer/rules/_ViewStart.cshtml
Normal file
@ -0,0 +1,3 @@
|
||||
@{
|
||||
Layout = @"_layout.cshtml";
|
||||
}
|
10
docs/input/analyzer/rules/_layout.cshtml
Normal file
10
docs/input/analyzer/rules/_layout.cshtml
Normal file
@ -0,0 +1,10 @@
|
||||
@inherits StatiqRazorPage<IDocument>
|
||||
|
||||
@{
|
||||
Layout = @"../../_layout.cshtml";
|
||||
}
|
||||
|
||||
|
||||
<p>@Document.GetString("Description")</p>
|
||||
|
||||
@RenderBody()
|
31
docs/input/analyzer/rules/index.cshtml
Normal file
31
docs/input/analyzer/rules/index.cshtml
Normal file
@ -0,0 +1,31 @@
|
||||
Title: Roslyn Analyzers
|
||||
Order: 20
|
||||
---
|
||||
|
||||
<code>Spectre.Console.Analyzer</code> provides analyzers for common mistakes when using Spectre.Console. It can be installed via nuget
|
||||
|
||||
<pre><code>nuget install Spectre.Console.Analyzer</code></pre>
|
||||
|
||||
<h2>Supported Analyzers</h2>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Analyzer</th>
|
||||
<th>Description</th>
|
||||
<th>Category</th>
|
||||
<th>Severity</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (IDocument child in OutputPages.GetChildrenOf(Document))
|
||||
{
|
||||
<tr>
|
||||
<td>@Html.DocumentLink(child)</td>
|
||||
<td>@child.GetString("Description")</td>
|
||||
<td>@child.GetString("Category") </td>
|
||||
<td>@child.GetString("Severity") </td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
27
docs/input/analyzer/rules/spectre1000.md
Normal file
27
docs/input/analyzer/rules/spectre1000.md
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
Title: Spectre1000
|
||||
Description: Use AnsiConsole instead of System.Console
|
||||
Category: Usage
|
||||
Severity: Warning
|
||||
---
|
||||
|
||||
## Cause
|
||||
|
||||
A violation of this rule occurs when `System.Console` is used for common methods exposed by Spectre.Console.
|
||||
|
||||
## Reason for rule
|
||||
|
||||
Methods implemented in Spectre.Console should be used over direct access to `System.Console` to allow for enhancements and
|
||||
features to be enabled.
|
||||
|
||||
## How to fix violations
|
||||
|
||||
To fix a violation of this rule, change from `System.Console` to `Spectre.Console.AnsiConsole`.
|
||||
|
||||
## How to suppress violations
|
||||
|
||||
```csharp
|
||||
#pragma warning disable Spectre1000 // Use AnsiConsole instead of System.Console
|
||||
|
||||
#pragma warning restore Spectre1000 // Use AnsiConsole instead of System.Console
|
||||
```
|
63
docs/input/analyzer/rules/spectre1010.md
Normal file
63
docs/input/analyzer/rules/spectre1010.md
Normal file
@ -0,0 +1,63 @@
|
||||
---
|
||||
Title: Spectre1010
|
||||
Description: Favor the use of the instance of AnsiConsole over the static helper
|
||||
Category: Usage
|
||||
Severity: Info
|
||||
---
|
||||
|
||||
## Cause
|
||||
|
||||
A violation of this rule occurs when the static helper `AnsiConsole` is used when a field or method parameter of type
|
||||
`IAnsiConsole` is available.
|
||||
|
||||
## Reason for rule
|
||||
|
||||
Use of `IAnsiConsole` improves testability of the code, and also allows upstream callers the ability to customize the console
|
||||
capabilities and features. When a field variable or parameter is available it should be used to ensure the code takes advantage
|
||||
of that configuration.
|
||||
|
||||
## How to fix violations
|
||||
|
||||
To fix a violation of this rule, change from `AnsiConsole` to the name of the local instance.
|
||||
|
||||
## Examples
|
||||
|
||||
### Violates
|
||||
|
||||
```csharp
|
||||
class Example
|
||||
{
|
||||
private IAnsiConsole _ansiConsole;
|
||||
|
||||
public Example(IAnsiConsole ansiConsole)
|
||||
{
|
||||
_ansiConsole = ansiConsole;
|
||||
}
|
||||
|
||||
public Run()
|
||||
{
|
||||
AnsiConsole.WriteLine("Running...");
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### Does not violate
|
||||
|
||||
```csharp
|
||||
class Example
|
||||
{
|
||||
private IAnsiConsole _ansiConsole;
|
||||
|
||||
public Example(IAnsiConsole ansiConsole)
|
||||
{
|
||||
_ansiConsole = ansiConsole;
|
||||
}
|
||||
|
||||
public Run()
|
||||
{
|
||||
_ansiConsole.WriteLine("Running...");
|
||||
}
|
||||
|
||||
}
|
||||
```
|
46
docs/input/analyzer/rules/spectre1020.md
Normal file
46
docs/input/analyzer/rules/spectre1020.md
Normal file
@ -0,0 +1,46 @@
|
||||
---
|
||||
Title: Spectre1020
|
||||
Description: Avoid calling other live renderables while a current renderable is running.
|
||||
Category: Usage
|
||||
Severity: Warning
|
||||
---
|
||||
|
||||
## Cause
|
||||
|
||||
A violation of this rule occurs when a child LiveRenderable i.e. `Progress`, `Status` and `Live` are called within the context of an executing renderable. Concurrent LiveRenderable are not supported and will cause issues when running simultaneously.
|
||||
|
||||
## Reason for rule
|
||||
|
||||
When LiveRenderable such as `Progress`, `Status` or `Live` are running they expect to be running exclusively. They rely on ANSI sequences to draw and keep the console experience consistent. With simultaneous calls both renderables compete with the console causing concurrent writes corrupting the output.
|
||||
|
||||
## How to fix violations
|
||||
|
||||
Redesign logic to allow one LiveRenderable to complete before starting a second renderable.
|
||||
|
||||
## Examples
|
||||
|
||||
### Violates
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Progress().Start(ctx => {
|
||||
AnsiConsole.Status().Start("Running status too...", statusCtx => {});
|
||||
});
|
||||
```
|
||||
|
||||
### Does not violate
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Progress().Start(ctx => {
|
||||
// run progress and complete tasks
|
||||
});
|
||||
|
||||
AnsiConsole.Status().Start("Running status afterwards...", statusCtx => {});
|
||||
```
|
||||
|
||||
## How to suppress violations
|
||||
|
||||
```csharp
|
||||
#pragma warning disable Spectre1020 // <Rule name>
|
||||
|
||||
#pragma warning restore Spectre1020 // <Rule name>
|
||||
```
|
19
docs/input/api/Kind/_Assembly.cshtml
Normal file
19
docs/input/api/Kind/_Assembly.cshtml
Normal file
@ -0,0 +1,19 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Docs.Pipelines
|
||||
@using Docs.Extensions
|
||||
@foreach (IGrouping<string, IDocument> typeGroup
|
||||
in Outputs.FromPipeline(nameof(Api))
|
||||
.Where(x => x.GetBool(CodeAnalysisKeys.IsResult)
|
||||
&& x.GetString(CodeAnalysisKeys.Kind) == "NamedType"
|
||||
&& Document.IdEquals(x.GetDocument(CodeAnalysisKeys.ContainingAssembly)))
|
||||
.GroupBy(x => x.GetString(CodeAnalysisKeys.SpecificKind))
|
||||
.OrderBy(x => x.Key))
|
||||
{
|
||||
<h2>@typeGroup.Key</h2>
|
||||
@foreach (var type in typeGroup)
|
||||
{
|
||||
<ul>
|
||||
<li>@Context.GetTypeLink(type)</li>
|
||||
</ul>
|
||||
}
|
||||
}
|
4
docs/input/api/Kind/_Event.cshtml
Normal file
4
docs/input/api/Kind/_Event.cshtml
Normal file
@ -0,0 +1,4 @@
|
||||
@await Html.PartialAsync("../Sections/_Syntax.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Examples.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Remarks.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_SeeAlso.cshtml")
|
9
docs/input/api/Kind/_Field.cshtml
Normal file
9
docs/input/api/Kind/_Field.cshtml
Normal file
@ -0,0 +1,9 @@
|
||||
@await Html.PartialAsync("../Sections/_Summary.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Syntax.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_SymbolInfo.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Examples.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Remarks.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Attributes.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Parameters.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Value.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_SeeAlso.cshtml")
|
10
docs/input/api/Kind/_Method.cshtml
Normal file
10
docs/input/api/Kind/_Method.cshtml
Normal file
@ -0,0 +1,10 @@
|
||||
@await Html.PartialAsync("../Sections/_Summary.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Syntax.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_SymbolInfo.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Examples.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Remarks.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Attributes.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_TypeParameters.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Parameters.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_ReturnValue.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_SeeAlso.cshtml")
|
15
docs/input/api/Kind/_NamedType.cshtml
Normal file
15
docs/input/api/Kind/_NamedType.cshtml
Normal file
@ -0,0 +1,15 @@
|
||||
@await Html.PartialAsync("../Sections/_Summary.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Syntax.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_SymbolInfo.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Examples.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Remarks.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Attributes.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_TypeParameters.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Constructors.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Events.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Fields.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Properties.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Methods.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_ExtensionMethods.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Operators.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_SeeAlso.cshtml")
|
25
docs/input/api/Kind/_Namespace.cshtml
Normal file
25
docs/input/api/Kind/_Namespace.cshtml
Normal file
@ -0,0 +1,25 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Docs.Extensions
|
||||
@await Html.PartialAsync("../Sections/_Summary.cshtml")
|
||||
@{
|
||||
foreach (IGrouping<string, IDocument> typeGroup
|
||||
in Document.GetDocuments(CodeAnalysisKeys.MemberTypes)
|
||||
.Where(x => x.GetBool(CodeAnalysisKeys.IsResult) && x.GetString(CodeAnalysisKeys.Kind) == "NamedType")
|
||||
.GroupBy(x => x.GetString(CodeAnalysisKeys.SpecificKind)))
|
||||
{
|
||||
<h3>@typeGroup.Key</h3>
|
||||
<div class="doc-summary short-term">
|
||||
<div>
|
||||
<dl>
|
||||
@foreach (var type in typeGroup.OrderBy(x => x.GetString(CodeAnalysisKeys.DisplayName)).ToList())
|
||||
{
|
||||
<div>
|
||||
<dt>@Context.GetTypeLink(type)</dt>
|
||||
<dd>@Html.Raw(type.GetString(CodeAnalysisKeys.Summary))</dd>
|
||||
</div>
|
||||
}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
9
docs/input/api/Kind/_Property.cshtml
Normal file
9
docs/input/api/Kind/_Property.cshtml
Normal file
@ -0,0 +1,9 @@
|
||||
@await Html.PartialAsync("../Sections/_Summary.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Syntax.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_SymbolInfo.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Examples.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Remarks.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Attributes.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Parameters.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_Value.cshtml")
|
||||
@await Html.PartialAsync("../Sections/_SeeAlso.cshtml")
|
26
docs/input/api/Sections/_Attributes.cshtml
Normal file
26
docs/input/api/Sections/_Attributes.cshtml
Normal file
@ -0,0 +1,26 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Docs.Extensions
|
||||
@{
|
||||
IReadOnlyList<IDocument> attributes = Document.GetDocumentList(CodeAnalysisKeys.Attributes);
|
||||
if (attributes?.Count > 0)
|
||||
{
|
||||
<h3>Attributes</h3>
|
||||
<div class="doc-summary">
|
||||
<div>
|
||||
<dl>
|
||||
@foreach (var attribute in attributes)
|
||||
{
|
||||
var type = attribute.GetDocument(CodeAnalysisKeys.Type);
|
||||
|
||||
<div>
|
||||
<dt>
|
||||
@Context.GetTypeLink(type)
|
||||
</dt>
|
||||
<dd>@Html.Raw(type.GetString(CodeAnalysisKeys.Summary))</dd>
|
||||
</div>
|
||||
}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
22
docs/input/api/Sections/_ConstantValue.cshtml
Normal file
22
docs/input/api/Sections/_ConstantValue.cshtml
Normal file
@ -0,0 +1,22 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Microsoft.AspNetCore.Html
|
||||
@if(Document.GetBool(CodeAnalysisKeys.HasConstantValue))
|
||||
{
|
||||
var constantValue = Document.Get(CodeAnalysisKeys.ConstantValue);
|
||||
|
||||
<h3>Constant Value</h3>
|
||||
<div class="doc-summary">
|
||||
<div>
|
||||
<dl>
|
||||
|
||||
<div>
|
||||
|
||||
<dt>
|
||||
@(new HtmlString(constantValue?.ToString() ?? "null"))
|
||||
</dt>
|
||||
<dd>@(new HtmlString(constantValue?.GetType().Name ?? string.Empty))</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
}
|
6
docs/input/api/Sections/_ConstantValue.cshtml.cs
Normal file
6
docs/input/api/Sections/_ConstantValue.cshtml.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace Docs.input.api.Sections;
|
||||
|
||||
public class _ConstantValue_cshtml
|
||||
{
|
||||
|
||||
}
|
29
docs/input/api/Sections/_Constructors.cshtml
Normal file
29
docs/input/api/Sections/_Constructors.cshtml
Normal file
@ -0,0 +1,29 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Docs.Extensions
|
||||
|
||||
@{
|
||||
var constructors = Document.GetDocumentList(CodeAnalysisKeys.Constructors)
|
||||
?.Where(x => x.GetBool(CodeAnalysisKeys.IsResult))
|
||||
.OrderBy(x => x.GetString(CodeAnalysisKeys.DisplayName))
|
||||
.ToList();
|
||||
|
||||
if (constructors?.Count > 0)
|
||||
{
|
||||
<h3>Constructors</h3>
|
||||
<div class="doc-summary">
|
||||
<div>
|
||||
<dl>
|
||||
@foreach (var constructor in constructors)
|
||||
{
|
||||
<div>
|
||||
<dt>
|
||||
@constructor.GetModifiers() @Context.GetTypeLink(constructor, false)
|
||||
</dt>
|
||||
<dd>@Html.Raw(constructor.GetString(CodeAnalysisKeys.Summary))</dd>
|
||||
</div>
|
||||
}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
0
docs/input/api/Sections/_DocumentList.cshtml
Normal file
0
docs/input/api/Sections/_DocumentList.cshtml
Normal file
0
docs/input/api/Sections/_Events.cshtml
Normal file
0
docs/input/api/Sections/_Events.cshtml
Normal file
9
docs/input/api/Sections/_Examples.cshtml
Normal file
9
docs/input/api/Sections/_Examples.cshtml
Normal file
@ -0,0 +1,9 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@{
|
||||
var examples = Document.GetString(CodeAnalysisKeys.Example);
|
||||
if (!examples.IsNullOrWhiteSpace())
|
||||
{
|
||||
<h3>Examples</h3>
|
||||
<div>@Html.Raw(examples)</div>
|
||||
}
|
||||
}
|
40
docs/input/api/Sections/_ExtensionMethods.cshtml
Normal file
40
docs/input/api/Sections/_ExtensionMethods.cshtml
Normal file
@ -0,0 +1,40 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Docs.Extensions
|
||||
@using Microsoft.CodeAnalysis
|
||||
|
||||
@{
|
||||
var modelSymbol = Document.Get<ITypeSymbol>(CodeAnalysisKeys.Symbol);
|
||||
IReadOnlyList<IDocument> methods = Document.GetDocumentList(CodeAnalysisKeys.ExtensionMethods)
|
||||
?.Where(x => x.GetBool(CodeAnalysisKeys.IsResult))
|
||||
.OrderBy(x => x.GetString(CodeAnalysisKeys.DisplayName))
|
||||
.ToList();
|
||||
|
||||
if (methods?.Count > 0)
|
||||
{
|
||||
<h3>Extension Methods</h3>
|
||||
<div class="doc-summary">
|
||||
<div>
|
||||
<dl>
|
||||
@foreach (var method in methods)
|
||||
{
|
||||
ISymbol reducedSymbol = method.Get<IMethodSymbol>(CodeAnalysisKeys.Symbol)?.ReduceExtensionMethod(modelSymbol);
|
||||
string reducedName = reducedSymbol?.ToDisplayString(new SymbolDisplayFormat(
|
||||
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypes,
|
||||
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
|
||||
parameterOptions: SymbolDisplayParameterOptions.IncludeType,
|
||||
memberOptions: SymbolDisplayMemberOptions.IncludeParameters,
|
||||
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes));
|
||||
|
||||
<div>
|
||||
<dt>
|
||||
@method.GetModifiers(skipStatic:true) @method.GetDocument(CodeAnalysisKeys.ReturnType).GetString(CodeAnalysisKeys.DisplayName) @Context.GetTypeLink(method,reducedName, false)
|
||||
</dt>
|
||||
<dd>@Html.Raw(method.GetString(CodeAnalysisKeys.Summary))</dd>
|
||||
</div>
|
||||
}
|
||||
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
59
docs/input/api/Sections/_Fields.cshtml
Normal file
59
docs/input/api/Sections/_Fields.cshtml
Normal file
@ -0,0 +1,59 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Microsoft.AspNetCore.Html
|
||||
@using Docs.Extensions
|
||||
@{
|
||||
var isEnum = Document.GetString(CodeAnalysisKeys.SpecificKind) == "Enum";
|
||||
IReadOnlyList<IDocument> fields;
|
||||
if (isEnum)
|
||||
{
|
||||
fields = Document.GetDocumentList(CodeAnalysisKeys.Members)?.Where(x => x.GetBool(CodeAnalysisKeys.IsResult) && x.GetString(CodeAnalysisKeys.Kind) == "Field")
|
||||
.OrderBy(x => x.Get(CodeAnalysisKeys.ConstantValue) as int? ?? 0)
|
||||
.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
fields = Document.GetDocumentList(CodeAnalysisKeys.Members)?.Where(x => x.GetBool(CodeAnalysisKeys.IsResult) && x.GetString(CodeAnalysisKeys.Kind) == "Field")
|
||||
.OrderBy(x => x.GetString(CodeAnalysisKeys.DisplayName))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
||||
if (fields?.Count > 0)
|
||||
{
|
||||
<h3>Fields</h3>
|
||||
<div class="doc-summary">
|
||||
<div>
|
||||
<dl>
|
||||
@foreach (var field in fields)
|
||||
{
|
||||
<div>
|
||||
<dt>
|
||||
|
||||
<div class="flex flex-row">
|
||||
<div class="w-4/5">
|
||||
@if (isEnum)
|
||||
{
|
||||
@Context.GetTypeLink(field, false)
|
||||
}
|
||||
else
|
||||
{
|
||||
@field.GetModifiers() @Context.GetTypeLink(field.GetDocument(CodeAnalysisKeys.Type))
|
||||
@Context.GetTypeLink(field, false)
|
||||
}
|
||||
</div>
|
||||
<div>
|
||||
@(field.GetBool(CodeAnalysisKeys.HasConstantValue) ? new HtmlString(field.Get(CodeAnalysisKeys.ConstantValue)?.ToString() ?? "null") : new HtmlString(string.Empty))
|
||||
</div>
|
||||
</div>
|
||||
</dt>
|
||||
<dd>
|
||||
@Html.Raw(field.GetString(CodeAnalysisKeys.Summary))
|
||||
</dd>
|
||||
</div>
|
||||
}
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
}
|
||||
}
|
30
docs/input/api/Sections/_Methods.cshtml
Normal file
30
docs/input/api/Sections/_Methods.cshtml
Normal file
@ -0,0 +1,30 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Docs.Extensions
|
||||
|
||||
@{
|
||||
IReadOnlyList<IDocument> methods = Model.GetDocumentList(CodeAnalysisKeys.Members)
|
||||
?.Where(x => x.GetBool(CodeAnalysisKeys.IsResult) && x.GetString(CodeAnalysisKeys.Kind) == "Method")
|
||||
.OrderBy(x => x.GetString(CodeAnalysisKeys.DisplayName))
|
||||
.ToList();
|
||||
|
||||
if (methods?.Count > 0)
|
||||
{
|
||||
<h3>Methods</h3>
|
||||
<div class="doc-summary">
|
||||
<div>
|
||||
<dl>
|
||||
@foreach (var method in methods)
|
||||
{
|
||||
<div>
|
||||
<dt>
|
||||
@method.GetModifiers() @method.GetDocument(CodeAnalysisKeys.ReturnType).GetString(CodeAnalysisKeys.DisplayName) @Context.GetTypeLink(method, false)
|
||||
</dt>
|
||||
<dd>@Html.Raw(method.GetString(CodeAnalysisKeys.Summary))</dd>
|
||||
</div>
|
||||
}
|
||||
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
0
docs/input/api/Sections/_Operators.cshtml
Normal file
0
docs/input/api/Sections/_Operators.cshtml
Normal file
25
docs/input/api/Sections/_Parameters.cshtml
Normal file
25
docs/input/api/Sections/_Parameters.cshtml
Normal file
@ -0,0 +1,25 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Docs.Extensions
|
||||
@{
|
||||
var parameters = Model.GetDocumentList(CodeAnalysisKeys.Parameters);
|
||||
var paramComments = Model.GetList<ReferenceComment>(CodeAnalysisKeys.Params);
|
||||
if (parameters?.Count > 0)
|
||||
{
|
||||
<h3>Parameters</h3>
|
||||
<div class="doc-summary">
|
||||
<div>
|
||||
<dl>
|
||||
@foreach (var parameter in parameters)
|
||||
{
|
||||
<div>
|
||||
<dt>
|
||||
@Context.GetTypeLink(parameter.GetDocument(CodeAnalysisKeys.Type)) <span class="identifier">@parameter.GetString(CodeAnalysisKeys.Name)</span>
|
||||
</dt>
|
||||
<dd>@Html.Raw(paramComments?.Where(x => x.Name.Equals(parameter.GetString(CodeAnalysisKeys.Name))).Select(x => x.Html).FirstOrDefault()) </dd>
|
||||
</div>
|
||||
}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
30
docs/input/api/Sections/_Properties.cshtml
Normal file
30
docs/input/api/Sections/_Properties.cshtml
Normal file
@ -0,0 +1,30 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Docs.Extensions
|
||||
@{
|
||||
IReadOnlyList<IDocument> properties = Model.GetDocumentList(CodeAnalysisKeys.Members)
|
||||
?.Where(x => x.GetBool(CodeAnalysisKeys.IsResult) && x.GetString(CodeAnalysisKeys.Kind) == "Property")
|
||||
.OrderBy(x => x.GetString(CodeAnalysisKeys.DisplayName))
|
||||
.ToList();
|
||||
|
||||
if (properties?.Count > 0)
|
||||
{
|
||||
<h3>Properties</h3>
|
||||
|
||||
<div class="doc-summary">
|
||||
|
||||
<div>
|
||||
<dl>
|
||||
@foreach (var property in properties)
|
||||
{
|
||||
<div>
|
||||
<dt>
|
||||
@property.GetModifiers() @property.GetDocument(CodeAnalysisKeys.Type).GetString(CodeAnalysisKeys.DisplayName) @Context.GetTypeLink(property, false)
|
||||
</dt>
|
||||
<dd>@Html.Raw(property.GetString(CodeAnalysisKeys.Summary))</dd>
|
||||
</div>
|
||||
}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
9
docs/input/api/Sections/_Remarks.cshtml
Normal file
9
docs/input/api/Sections/_Remarks.cshtml
Normal file
@ -0,0 +1,9 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@{
|
||||
var remarks = Document.GetString(CodeAnalysisKeys.Remarks);
|
||||
if (!remarks.IsNullOrWhiteSpace())
|
||||
{
|
||||
<h3>Remarks</h3>
|
||||
<div>@Html.Raw(remarks)</div>
|
||||
}
|
||||
}
|
23
docs/input/api/Sections/_ReturnValue.cshtml
Normal file
23
docs/input/api/Sections/_ReturnValue.cshtml
Normal file
@ -0,0 +1,23 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Docs.Extensions
|
||||
@{
|
||||
var returnType = Model.GetDocument(CodeAnalysisKeys.ReturnType);
|
||||
var returns = Model.GetString(CodeAnalysisKeys.Returns);
|
||||
if ((returnType != null && returnType.GetString(CodeAnalysisKeys.DisplayName) != "void") || !string.IsNullOrWhiteSpace(returns))
|
||||
{
|
||||
<h3>Returns</h3>
|
||||
<div class="doc-summary">
|
||||
<div>
|
||||
<dl>
|
||||
<div>
|
||||
|
||||
<dt>
|
||||
@Context.GetTypeLink(returnType, false)
|
||||
</dt>
|
||||
<dd></dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
14
docs/input/api/Sections/_SeeAlso.cshtml
Normal file
14
docs/input/api/Sections/_SeeAlso.cshtml
Normal file
@ -0,0 +1,14 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@{
|
||||
var seeAlso = Document.GetList<string>(CodeAnalysisKeys.SeeAlso);
|
||||
if (seeAlso?.Count > 0)
|
||||
{
|
||||
<h3 id="SeeAlso">See Also</h3>
|
||||
<ul>
|
||||
@foreach (string seeAlsoComment in seeAlso)
|
||||
{
|
||||
<li>@Html.Raw(seeAlsoComment)</li>
|
||||
}
|
||||
</ul>
|
||||
}
|
||||
}
|
7
docs/input/api/Sections/_Summary.cshtml
Normal file
7
docs/input/api/Sections/_Summary.cshtml
Normal file
@ -0,0 +1,7 @@
|
||||
@{
|
||||
var summary = Document.GetString("Summary");
|
||||
if (!summary.IsNullOrWhiteSpace())
|
||||
{
|
||||
<div class="my-4 md:my-8">@Html.Raw(summary)</div>
|
||||
}
|
||||
}
|
131
docs/input/api/Sections/_SymbolInfo.cshtml
Normal file
131
docs/input/api/Sections/_SymbolInfo.cshtml
Normal file
@ -0,0 +1,131 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Docs.Extensions
|
||||
@{
|
||||
var containingAssembly = Document.GetDocument(CodeAnalysisKeys.ContainingAssembly);
|
||||
var containingNamespace = Document.GetDocument(CodeAnalysisKeys.ContainingNamespace);
|
||||
var containingType = Document.GetDocument(CodeAnalysisKeys.ContainingType);
|
||||
var type = Document.GetDocument(CodeAnalysisKeys.Type);
|
||||
var overridden = Document.GetDocument(CodeAnalysisKeys.Overridden);
|
||||
IReadOnlyList<IDocument> allInterfaces = Document.GetDocumentList(CodeAnalysisKeys.AllInterfaces);
|
||||
IReadOnlyList<IDocument> baseTypes = Document.GetDocumentList(CodeAnalysisKeys.BaseTypes)?
|
||||
.Where(i => !i.GetString(CodeAnalysisKeys.QualifiedName).Equals("System.Object"))
|
||||
.Reverse()
|
||||
.ToList();
|
||||
IReadOnlyList<IDocument> derivedTypes = Document.GetDocumentList(CodeAnalysisKeys.DerivedTypes);
|
||||
IReadOnlyList<IDocument> implementingTypes = Document.GetDocumentList(CodeAnalysisKeys.ImplementingTypes);
|
||||
if (containingAssembly is object
|
||||
|| containingNamespace is object
|
||||
|| allInterfaces?.Count > 0
|
||||
|| baseTypes?.Count > 0
|
||||
|| derivedTypes?.Count > 0
|
||||
|| implementingTypes?.Count > 0)
|
||||
{
|
||||
<div class="doc-summary tiny-term">
|
||||
<div>
|
||||
<dl>
|
||||
|
||||
@if (containingAssembly != null)
|
||||
{
|
||||
<div>
|
||||
<dt>Assembly</dt>
|
||||
<dd>containingAssembly</dd>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (containingNamespace != null)
|
||||
{
|
||||
<div>
|
||||
<dt>Namespace</dt>
|
||||
<dd>@Context.GetTypeLink(containingNamespace)</dd>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (containingType != null)
|
||||
{
|
||||
<div>
|
||||
<dt>Containing Type</dt>
|
||||
<dd>@Context.GetTypeLink(containingType)</dd>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (overridden != null)
|
||||
{
|
||||
<div>
|
||||
<dt>Overridden</dt>
|
||||
<dd>@Context.GetTypeLink(overridden)</dd>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (allInterfaces?.Count > 0)
|
||||
{
|
||||
<div>
|
||||
<dt>Interfaces</dt>
|
||||
<dd>
|
||||
<ul class="list-unstyled">
|
||||
@foreach (var interfaceDocument in allInterfaces)
|
||||
{
|
||||
<li>@Context.GetTypeLink(interfaceDocument)</li>
|
||||
}
|
||||
</ul>
|
||||
</dd>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (baseTypes?.Count > 0)
|
||||
{
|
||||
<div>
|
||||
<dt>Base Types</dt>
|
||||
<dd>
|
||||
<ul class="list-unstyled">
|
||||
@foreach (var baseType in baseTypes)
|
||||
{
|
||||
<li>@Context.GetTypeLink(baseType)</li>
|
||||
}
|
||||
</ul>
|
||||
</dd>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (derivedTypes?.Count > 0)
|
||||
{
|
||||
<div>
|
||||
<dt>Derived Types</dt>
|
||||
<dd>
|
||||
<ul class="list-unstyled">
|
||||
@foreach (var derivedType in derivedTypes)
|
||||
{
|
||||
<li>@Context.GetTypeLink(derivedType)</li>
|
||||
}
|
||||
</ul>
|
||||
</dd>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (implementingTypes?.Count > 0)
|
||||
|
||||
{
|
||||
<div>
|
||||
<dt>Implementing Types</dt>
|
||||
<dd>
|
||||
<ul class="list-unstyled">
|
||||
@foreach (var implementingType in implementingTypes)
|
||||
{
|
||||
<li>@Context.GetTypeLink(implementingType)</li>
|
||||
}
|
||||
</ul>
|
||||
</dd>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (type != null)
|
||||
{
|
||||
<div>
|
||||
<dt>@Document.GetString(CodeAnalysisKeys.Kind) Type</dt>
|
||||
<dd>@Context.GetTypeLink(type)</dd>
|
||||
</div>
|
||||
}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
8
docs/input/api/Sections/_Syntax.cshtml
Normal file
8
docs/input/api/Sections/_Syntax.cshtml
Normal file
@ -0,0 +1,8 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@{
|
||||
string syntax = Document.GetString(CodeAnalysisKeys.Syntax);
|
||||
if (!syntax.IsNullOrWhiteSpace())
|
||||
{
|
||||
<pre class="language-csharp"><code class="language-csharp">@syntax</code></pre>
|
||||
}
|
||||
}
|
26
docs/input/api/Sections/_TypeParameters.cshtml
Normal file
26
docs/input/api/Sections/_TypeParameters.cshtml
Normal file
@ -0,0 +1,26 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
|
||||
@{
|
||||
var typeParameters = Model.GetDocumentList(CodeAnalysisKeys.TypeParameters);
|
||||
var typeParams = Model.GetList<ReferenceComment>(CodeAnalysisKeys.TypeParams);
|
||||
|
||||
if (typeParameters?.Count > 0)
|
||||
{
|
||||
<h3>Parameters</h3>
|
||||
<div class="doc-summary">
|
||||
<div>
|
||||
<dl>
|
||||
@foreach (var typeParam in typeParameters)
|
||||
{
|
||||
<div>
|
||||
<dt>
|
||||
<code>@typeParam.GetString(CodeAnalysisKeys.Name)</code>
|
||||
</dt>
|
||||
<dd>@Html.Raw(typeParams?.Where(x => x.Name.Equals(typeParam.GetString(CodeAnalysisKeys.Name))).Select(x => x.Html).FirstOrDefault()) </dd>
|
||||
</div>
|
||||
}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
12
docs/input/api/Sections/_Value.cshtml
Normal file
12
docs/input/api/Sections/_Value.cshtml
Normal file
@ -0,0 +1,12 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Docs.Extensions
|
||||
@{
|
||||
IDocument type = Document.GetDocument(CodeAnalysisKeys.Type);
|
||||
string value = Document.GetString(CodeAnalysisKeys.Value);
|
||||
}
|
||||
|
||||
@if (type is object && !string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
<p>@Context.GetTypeLink(type)</p>
|
||||
<p>@Html.Raw(value)</p>
|
||||
}
|
48
docs/input/api/_layout.cshtml
Normal file
48
docs/input/api/_layout.cshtml
Normal file
@ -0,0 +1,48 @@
|
||||
@using Statiq.CodeAnalysis
|
||||
@using Docs.Extensions
|
||||
@inherits StatiqRazorPage<IDocument>
|
||||
|
||||
@{
|
||||
Layout = @"../_layout.cshtml";
|
||||
}
|
||||
|
||||
@section header{
|
||||
<h1 class="text-2xl md:text-4xl align-baseline font-extrabold">
|
||||
@Document.GetString(CodeAnalysisKeys.DisplayName) <span class="text-lg md:text-2xl text-uppercase text-sky-600 dark:text-sky-400">@Document.GetString(CodeAnalysisKeys.SpecificKind)</span>
|
||||
</h1>
|
||||
|
||||
<nav class="flex mt-2" aria-label="Breadcrumb">
|
||||
<ol class="flex flex-col sm:flex-row sm:items-center space-x-2 lg:space-x-3">
|
||||
@{
|
||||
var isFirst = true;
|
||||
}
|
||||
@foreach (var parent in Context.GetExecutionCache("sidebar", ctx => ctx.OutputPages).GetAncestorsOf(Document, Document.IdEquals(Model)).Reverse().Skip(1))
|
||||
{
|
||||
<li>
|
||||
<div class="flex items-center">
|
||||
@if (isFirst)
|
||||
{
|
||||
isFirst = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
<svg class="flex-shrink-0 h-5 w-5 mr-2 lg:mr-3 text-slate-400 dark:text-slate-500" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
}
|
||||
|
||||
<span class="font-light text-sm text-slate-600 dark:text-slate-300" >@Html.DocumentLink(parent, parent.GetString(WebKeys.Title, parent.GetTitle()))</span>
|
||||
</div>
|
||||
</li>
|
||||
}
|
||||
</ol>
|
||||
</nav>
|
||||
|
||||
|
||||
}
|
||||
|
||||
@await Html.PartialAsync($"Kind/_{Model.GetString(CodeAnalysisKeys.Kind)}.cshtml", Model)
|
||||
|
||||
@{
|
||||
IgnoreBody();
|
||||
}
|
11
docs/input/api/index.cshtml
Normal file
11
docs/input/api/index.cshtml
Normal file
@ -0,0 +1,11 @@
|
||||
Title: API Reference
|
||||
Order: 10000
|
||||
---
|
||||
<p>The Spectre.Console API reference is organized by namespace. Each namespace has one or more classes for working with Console applications.</p>
|
||||
|
||||
<ul>
|
||||
@foreach (var child in OutputPages.GetChildrenOf(Document).OrderBy(i => i.GetTitle()))
|
||||
{
|
||||
<li>@Html.DocumentLink(child)</li>
|
||||
}
|
||||
</ul>
|
@ -1,14 +1,20 @@
|
||||
Title: Borders
|
||||
Order: 2
|
||||
Description: "*Spectre.Console* makes it easy to create tables and panels with a variety of different styles of borders."
|
||||
Highlights:
|
||||
- Rounded
|
||||
- Square
|
||||
- Heavy
|
||||
- And more...
|
||||
---
|
||||
|
||||
There is different built-in borders you can use for tables and panels.
|
||||
There are different built-in borders you can use for tables and panels.
|
||||
|
||||
# Table borders
|
||||
## Table borders
|
||||
|
||||
<img src="../assets/images/borders/table.png" style="max-width: 100%;">
|
||||

|
||||
|
||||
## Example
|
||||
### Example
|
||||
|
||||
To set a table border to `SimpleHeavy`:
|
||||
|
||||
@ -19,15 +25,15 @@ table.Border = TableBorder.SimpleHeavy;
|
||||
|
||||
---
|
||||
|
||||
# Panel borders
|
||||
## Panel borders
|
||||
|
||||
<img src="../assets/images/borders/panel.png" style="max-width: 100%;">
|
||||

|
||||
|
||||
## Example
|
||||
### Example
|
||||
|
||||
To set a panel border to `Rounded`:
|
||||
|
||||
```csharp
|
||||
var panel = new Panel("Hello World");
|
||||
panel.Border = BoxBorder.Rounded;
|
||||
```
|
||||
```
|
||||
|
@ -1,31 +1,27 @@
|
||||
Title: Colors
|
||||
Order: 0
|
||||
Description: "*Spectre.Console* allows easy rendering of the standard ANSI colors of your terminal, and also supports rendering up to 24-bit colors depending on the capabilities of your terminal."
|
||||
Highlights:
|
||||
- Predefined common colors
|
||||
- Easy syntax for inline styling
|
||||
---
|
||||
|
||||
The following is a list of the standard 8-bit colors supported in terminals.
|
||||
|
||||
Note that the first 16 colors are generally defined by the system or your terminal software, and may not display exactly as rendered here.
|
||||
|
||||
# Usage
|
||||
## Usage
|
||||
|
||||
You can either use the colors in code, such as `new Style(foreground: Color.Maroon)` or
|
||||
in markup text such as `AnsiConsole.Markup("[maroon on blue]Hello[/]")`.
|
||||
|
||||
# Standard colors
|
||||
## Standard colors
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="basic-addon1">
|
||||
<i class="fas fa-search" aria-hidden="true"></i>
|
||||
</span>
|
||||
</div>
|
||||
<input
|
||||
class="form-control w-100 filter"
|
||||
data-table="color-results"
|
||||
type="text" placeholder="Search Colors..." autocomplete="off"
|
||||
aria-label="Search Colors">
|
||||
</div>
|
||||
<input
|
||||
id="colorSearch"
|
||||
type="search"
|
||||
oninput="search(this, 'color-results', 2)"
|
||||
placeholder="Search for colors.."
|
||||
title="Type in a color" />
|
||||
|
||||
<?# ColorTable /?>
|
||||
|
||||
<script type="text/javascript" src="../assets/js/table-search.js"></script>
|
@ -1,5 +1,9 @@
|
||||
Title: Emojis
|
||||
Order: 3
|
||||
Description: "For terminals that support Emojis, *Spectre.Console* supports a simple syntax for rendering emojis."
|
||||
Highlights:
|
||||
- ":rocket: becomes 🚀"
|
||||
- ":waning_gibbous_moon: becomes 🌖"
|
||||
---
|
||||
|
||||
Please note that what emojis that can be used is completely up to
|
||||
@ -13,7 +17,7 @@ before Unicode 13.0 that belongs in the `Emoji_Presentation` category
|
||||
in the official emoji list at
|
||||
https://www.unicode.org/Public/UCD/latest/ucd/emoji/emoji-data.txt
|
||||
|
||||
# Usage
|
||||
## Usage
|
||||
|
||||
```csharp
|
||||
// Markup
|
||||
@ -23,14 +27,14 @@ AnsiConsole.MarkupLine("Hello :globe_showing_europe_africa:!");
|
||||
var hello = "Hello " + Emoji.Known.GlobeShowingEuropeAfrica;
|
||||
```
|
||||
|
||||
# Replacing emojis in text
|
||||
## Replacing emojis in text
|
||||
|
||||
```csharp
|
||||
var phrase = "Mmmm :birthday_cake:";
|
||||
var rendered = Emoji.Replace(phrase);
|
||||
```
|
||||
|
||||
# Remapping or adding an emoji
|
||||
## Remapping or adding an emoji
|
||||
|
||||
Sometimes you want to remap an existing emoji, or
|
||||
add a completely new one. For this you can use the
|
||||
@ -49,24 +53,18 @@ var phrase = "Hello :globe_showing_europe_africa:!";
|
||||
var rendered = Emoji.Replace(phrase);
|
||||
```
|
||||
|
||||
# Emojis
|
||||
## Emojis
|
||||
|
||||
_The images in the table below might not render correctly in your
|
||||
browser for the same reasons mentioned in the `Compatibility` section._
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" id="basic-addon1">
|
||||
<i class="fas fa-search" aria-hidden="true"></i>
|
||||
</span>
|
||||
</div>
|
||||
<input
|
||||
class="form-control w-100 filter"
|
||||
data-table="emoji-results"
|
||||
type="text" placeholder="Search Emojis..." autocomplete="off"
|
||||
aria-label="Search Emojis">
|
||||
</div>
|
||||
|
||||
<?# EmojiTable /?>
|
||||
<input
|
||||
id="emojiSearch"
|
||||
type="search"
|
||||
oninput="search(this, 'emoji-results', 2)"
|
||||
placeholder="Search for emojis.."
|
||||
title="Type in an emoji name" />
|
||||
|
||||
<script type="text/javascript" src="../assets/js/table-search.js"></script>
|
||||
|
||||
<?# EmojiTable /?>
|
@ -1,7 +1,6 @@
|
||||
Title: Appendix
|
||||
Order: 100
|
||||
---
|
||||
|
||||
<h1>Sections</h1>
|
||||
|
||||
<ul>
|
||||
|
@ -1,12 +1,16 @@
|
||||
Title: Spinners
|
||||
Order: 4
|
||||
Description: "*Spectre.Console* supports over 80 different types of spinners, and allows new ones to be defined. They are used automatically with the controls"
|
||||
Highlights:
|
||||
- Status display
|
||||
- Progress display
|
||||
---
|
||||
|
||||
For all available spinners, see https://jsfiddle.net/sindresorhus/2eLtsbey/embedded/result/
|
||||
|
||||
# Usage
|
||||
## Usage
|
||||
|
||||
Spinners can be used with [Progress](xref:progress) and [Status](xref:status).
|
||||
Spinners can be used with [Progress](xref:live-progress) and [Status](xref:live-status).
|
||||
|
||||
```csharp
|
||||
AnsiConsole.Status()
|
||||
@ -16,12 +20,12 @@ AnsiConsole.Status()
|
||||
});
|
||||
```
|
||||
|
||||
# Implementing a spinner
|
||||
## Implementing a spinner
|
||||
|
||||
To implement your own spinner, all you have to do is
|
||||
inherit from the `Spinner` base class.
|
||||
|
||||
In the example below, the spinner will alterate between
|
||||
In the example below, the spinner will alternate between
|
||||
the characters `A`, `B` and `C` every 100 ms.
|
||||
|
||||
```csharp
|
||||
|
@ -1,5 +1,12 @@
|
||||
Title: Styles
|
||||
Order: 1
|
||||
Description: "*Spectre.Console* makes it easy to write text with different styles beyond colors. Depending on your terminal, it can make it easy to use styles such as"
|
||||
Highlights:
|
||||
- Bold, Italic, Underline, strikethrough
|
||||
- Dim, Invert
|
||||
- Conceal, slowblink, rapidblink
|
||||
- Links
|
||||
Xref: appendix-styles
|
||||
---
|
||||
|
||||
Note that what styles that can be used is defined by the system or your terminal software, and may not appear as they should.
|
||||
@ -41,4 +48,8 @@ Note that what styles that can be used is defined by the system or your terminal
|
||||
<td><code>strikethrough</code></td>
|
||||
<td>Shows text with a horizontal line through the center</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>link</code></td>
|
||||
<td>Creates a clickable link within text</td>
|
||||
</tr>
|
||||
</table>
|
BIN
docs/input/assets/CascadiaMonoPL.woff2
Normal file
BIN
docs/input/assets/CascadiaMonoPL.woff2
Normal file
Binary file not shown.
@ -1,51 +0,0 @@
|
||||
//
|
||||
// Base styles
|
||||
//
|
||||
|
||||
.alert {
|
||||
position: relative;
|
||||
padding: $alert-padding-y $alert-padding-x;
|
||||
margin-bottom: $alert-margin-bottom;
|
||||
border: $alert-border-width solid transparent;
|
||||
@include border-radius($alert-border-radius);
|
||||
}
|
||||
|
||||
// Headings for larger alerts
|
||||
.alert-heading {
|
||||
// Specified to prevent conflicts of changing $headings-color
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
// Provide class for links that match alerts
|
||||
.alert-link {
|
||||
font-weight: $alert-link-font-weight;
|
||||
}
|
||||
|
||||
|
||||
// Dismissible alerts
|
||||
//
|
||||
// Expand the right padding and account for the close button's positioning.
|
||||
|
||||
.alert-dismissible {
|
||||
padding-right: $close-font-size + $alert-padding-x * 2;
|
||||
|
||||
// Adjust close link position
|
||||
.close {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: $alert-padding-y $alert-padding-x;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Alternate styles
|
||||
//
|
||||
// Generate contextual modifier classes for colorizing the alert.
|
||||
|
||||
@each $color, $value in $theme-colors {
|
||||
.alert-#{$color} {
|
||||
@include alert-variant(theme-color-level($color, $alert-bg-level), theme-color-level($color, $alert-border-level), theme-color-level($color, $alert-color-level));
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
// Base class
|
||||
//
|
||||
// Requires one of the contextual, color modifier classes for `color` and
|
||||
// `background-color`.
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: $badge-padding-y $badge-padding-x;
|
||||
@include font-size($badge-font-size);
|
||||
font-weight: $badge-font-weight;
|
||||
line-height: 1;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: baseline;
|
||||
@include border-radius($badge-border-radius);
|
||||
@include transition($badge-transition);
|
||||
|
||||
@at-root a#{&} {
|
||||
@include hover-focus() {
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Empty badges collapse automatically
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
// Quick fix for badges in buttons
|
||||
.btn .badge {
|
||||
position: relative;
|
||||
top: -1px;
|
||||
}
|
||||
|
||||
// Pill badges
|
||||
//
|
||||
// Make them extra rounded with a modifier to replace v3's badges.
|
||||
|
||||
.badge-pill {
|
||||
padding-right: $badge-pill-padding-x;
|
||||
padding-left: $badge-pill-padding-x;
|
||||
@include border-radius($badge-pill-border-radius);
|
||||
}
|
||||
|
||||
// Colors
|
||||
//
|
||||
// Contextual variations (linked badges get darker on :hover).
|
||||
|
||||
@each $color, $value in $theme-colors {
|
||||
.badge-#{$color} {
|
||||
@include badge-variant($value);
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
.breadcrumb {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: $breadcrumb-padding-y $breadcrumb-padding-x;
|
||||
margin-bottom: $breadcrumb-margin-bottom;
|
||||
@include font-size($breadcrumb-font-size);
|
||||
list-style: none;
|
||||
background-color: $breadcrumb-bg;
|
||||
@include border-radius($breadcrumb-border-radius);
|
||||
}
|
||||
|
||||
.breadcrumb-item {
|
||||
// The separator between breadcrumbs (by default, a forward-slash: "/")
|
||||
+ .breadcrumb-item {
|
||||
padding-left: $breadcrumb-item-padding;
|
||||
|
||||
&::before {
|
||||
display: inline-block; // Suppress underlining of the separator in modern browsers
|
||||
padding-right: $breadcrumb-item-padding;
|
||||
color: $breadcrumb-divider-color;
|
||||
content: escape-svg($breadcrumb-divider);
|
||||
}
|
||||
}
|
||||
|
||||
// IE9-11 hack to properly handle hyperlink underlines for breadcrumbs built
|
||||
// without `<ul>`s. The `::before` pseudo-element generates an element
|
||||
// *within* the .breadcrumb-item and thereby inherits the `text-decoration`.
|
||||
//
|
||||
// To trick IE into suppressing the underline, we give the pseudo-element an
|
||||
// underline and then immediately remove it.
|
||||
+ .breadcrumb-item:hover::before {
|
||||
text-decoration: underline;
|
||||
}
|
||||
// stylelint-disable-next-line no-duplicate-selectors
|
||||
+ .breadcrumb-item:hover::before {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $breadcrumb-active-color;
|
||||
}
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
|
||||
// Make the div behave like a button
|
||||
.btn-group,
|
||||
.btn-group-vertical {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
vertical-align: middle; // match .btn alignment given font-size hack above
|
||||
|
||||
> .btn {
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
|
||||
// Bring the hover, focused, and "active" buttons to the front to overlay
|
||||
// the borders properly
|
||||
@include hover() {
|
||||
z-index: 1;
|
||||
}
|
||||
&:focus,
|
||||
&:active,
|
||||
&.active {
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Optional: Group multiple button groups together for a toolbar
|
||||
.btn-toolbar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
|
||||
.input-group {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-group {
|
||||
// Prevent double borders when buttons are next to each other
|
||||
> .btn:not(:first-child),
|
||||
> .btn-group:not(:first-child) {
|
||||
margin-left: -$btn-border-width;
|
||||
}
|
||||
|
||||
// Reset rounded corners
|
||||
> .btn:not(:last-child):not(.dropdown-toggle),
|
||||
> .btn-group:not(:last-child) > .btn {
|
||||
@include border-right-radius(0);
|
||||
}
|
||||
|
||||
> .btn:not(:first-child),
|
||||
> .btn-group:not(:first-child) > .btn {
|
||||
@include border-left-radius(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Sizing
|
||||
//
|
||||
// Remix the default button sizing classes into new ones for easier manipulation.
|
||||
|
||||
.btn-group-sm > .btn { @extend .btn-sm; }
|
||||
.btn-group-lg > .btn { @extend .btn-lg; }
|
||||
|
||||
|
||||
//
|
||||
// Split button dropdowns
|
||||
//
|
||||
|
||||
.dropdown-toggle-split {
|
||||
padding-right: $btn-padding-x * .75;
|
||||
padding-left: $btn-padding-x * .75;
|
||||
|
||||
&::after,
|
||||
.dropup &::after,
|
||||
.dropright &::after {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.dropleft &::before {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-sm + .dropdown-toggle-split {
|
||||
padding-right: $btn-padding-x-sm * .75;
|
||||
padding-left: $btn-padding-x-sm * .75;
|
||||
}
|
||||
|
||||
.btn-lg + .dropdown-toggle-split {
|
||||
padding-right: $btn-padding-x-lg * .75;
|
||||
padding-left: $btn-padding-x-lg * .75;
|
||||
}
|
||||
|
||||
|
||||
// The clickable button for toggling the menu
|
||||
// Set the same inset shadow as the :active state
|
||||
.btn-group.show .dropdown-toggle {
|
||||
@include box-shadow($btn-active-box-shadow);
|
||||
|
||||
// Show no shadow for `.btn-link` since it has no other button styles.
|
||||
&.btn-link {
|
||||
@include box-shadow(none);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Vertical button groups
|
||||
//
|
||||
|
||||
.btn-group-vertical {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
|
||||
> .btn,
|
||||
> .btn-group {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
> .btn:not(:first-child),
|
||||
> .btn-group:not(:first-child) {
|
||||
margin-top: -$btn-border-width;
|
||||
}
|
||||
|
||||
// Reset rounded corners
|
||||
> .btn:not(:last-child):not(.dropdown-toggle),
|
||||
> .btn-group:not(:last-child) > .btn {
|
||||
@include border-bottom-radius(0);
|
||||
}
|
||||
|
||||
> .btn:not(:first-child),
|
||||
> .btn-group:not(:first-child) > .btn {
|
||||
@include border-top-radius(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Checkbox and radio options
|
||||
//
|
||||
// In order to support the browser's form validation feedback, powered by the
|
||||
// `required` attribute, we have to "hide" the inputs via `clip`. We cannot use
|
||||
// `display: none;` or `visibility: hidden;` as that also hides the popover.
|
||||
// Simply visually hiding the inputs via `opacity` would leave them clickable in
|
||||
// certain cases which is prevented by using `clip` and `pointer-events`.
|
||||
// This way, we ensure a DOM element is visible to position the popover from.
|
||||
//
|
||||
// See https://github.com/twbs/bootstrap/pull/12794 and
|
||||
// https://github.com/twbs/bootstrap/pull/14559 for more information.
|
||||
|
||||
.btn-group-toggle {
|
||||
> .btn,
|
||||
> .btn-group > .btn {
|
||||
margin-bottom: 0; // Override default `<label>` value
|
||||
|
||||
input[type="radio"],
|
||||
input[type="checkbox"] {
|
||||
position: absolute;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
|
||||
//
|
||||
// Base styles
|
||||
//
|
||||
|
||||
.btn {
|
||||
display: inline-block;
|
||||
font-family: $btn-font-family;
|
||||
font-weight: $btn-font-weight;
|
||||
color: $body-color;
|
||||
text-align: center;
|
||||
white-space: $btn-white-space;
|
||||
vertical-align: middle;
|
||||
cursor: if($enable-pointer-cursor-for-buttons, pointer, null);
|
||||
user-select: none;
|
||||
background-color: transparent;
|
||||
border: $btn-border-width solid transparent;
|
||||
@include button-size($btn-padding-y, $btn-padding-x, $btn-font-size, $btn-line-height, $btn-border-radius);
|
||||
@include transition($btn-transition);
|
||||
|
||||
@include hover() {
|
||||
color: $body-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&.focus {
|
||||
outline: 0;
|
||||
box-shadow: $btn-focus-box-shadow;
|
||||
}
|
||||
|
||||
// Disabled comes first so active can properly restyle
|
||||
&.disabled,
|
||||
&:disabled {
|
||||
opacity: $btn-disabled-opacity;
|
||||
@include box-shadow(none);
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled):active,
|
||||
&:not(:disabled):not(.disabled).active {
|
||||
@include box-shadow($btn-active-box-shadow);
|
||||
|
||||
&:focus {
|
||||
@include box-shadow($btn-focus-box-shadow, $btn-active-box-shadow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Future-proof disabling of clicks on `<a>` elements
|
||||
a.btn.disabled,
|
||||
fieldset:disabled a.btn {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Alternate buttons
|
||||
//
|
||||
|
||||
@each $color, $value in $theme-colors {
|
||||
.btn-#{$color} {
|
||||
@include button-variant($value, $value);
|
||||
}
|
||||
}
|
||||
|
||||
@each $color, $value in $theme-colors {
|
||||
.btn-outline-#{$color} {
|
||||
@include button-outline-variant($value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Link buttons
|
||||
//
|
||||
|
||||
// Make a button look and behave like a link
|
||||
.btn-link {
|
||||
font-weight: $font-weight-normal;
|
||||
color: $link-color;
|
||||
text-decoration: $link-decoration;
|
||||
|
||||
@include hover() {
|
||||
color: $link-hover-color;
|
||||
text-decoration: $link-hover-decoration;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&.focus {
|
||||
text-decoration: $link-hover-decoration;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&:disabled,
|
||||
&.disabled {
|
||||
color: $btn-link-disabled-color;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// No need for an active state here
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Button Sizes
|
||||
//
|
||||
|
||||
.btn-lg {
|
||||
@include button-size($btn-padding-y-lg, $btn-padding-x-lg, $btn-font-size-lg, $btn-line-height-lg, $btn-border-radius-lg);
|
||||
}
|
||||
|
||||
.btn-sm {
|
||||
@include button-size($btn-padding-y-sm, $btn-padding-x-sm, $btn-font-size-sm, $btn-line-height-sm, $btn-border-radius-sm);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Block button
|
||||
//
|
||||
|
||||
.btn-block {
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
||||
// Vertically space out multiple block buttons
|
||||
+ .btn-block {
|
||||
margin-top: $btn-block-spacing-y;
|
||||
}
|
||||
}
|
||||
|
||||
// Specificity overrides
|
||||
input[type="submit"],
|
||||
input[type="reset"],
|
||||
input[type="button"] {
|
||||
&.btn-block {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
@ -1,278 +0,0 @@
|
||||
//
|
||||
// Base styles
|
||||
//
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0; // See https://github.com/twbs/bootstrap/pull/22740#issuecomment-305868106
|
||||
height: $card-height;
|
||||
word-wrap: break-word;
|
||||
background-color: $card-bg;
|
||||
background-clip: border-box;
|
||||
border: $card-border-width solid $card-border-color;
|
||||
@include border-radius($card-border-radius);
|
||||
|
||||
> hr {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
> .list-group:first-child {
|
||||
.list-group-item:first-child {
|
||||
@include border-top-radius($card-border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
> .list-group:last-child {
|
||||
.list-group-item:last-child {
|
||||
@include border-bottom-radius($card-border-radius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-body {
|
||||
// Enable `flex-grow: 1` for decks and groups so that card blocks take up
|
||||
// as much space as possible, ensuring footers are aligned to the bottom.
|
||||
flex: 1 1 auto;
|
||||
// Workaround for the image size bug in IE
|
||||
// See: https://github.com/twbs/bootstrap/pull/28855
|
||||
min-height: 1px;
|
||||
padding: $card-spacer-x;
|
||||
color: $card-color;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
margin-bottom: $card-spacer-y;
|
||||
}
|
||||
|
||||
.card-subtitle {
|
||||
margin-top: -$card-spacer-y / 2;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.card-text:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.card-link {
|
||||
@include hover() {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
+ .card-link {
|
||||
margin-left: $card-spacer-x;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Optional textual caps
|
||||
//
|
||||
|
||||
.card-header {
|
||||
padding: $card-spacer-y $card-spacer-x;
|
||||
margin-bottom: 0; // Removes the default margin-bottom of <hN>
|
||||
color: $card-cap-color;
|
||||
background-color: $card-cap-bg;
|
||||
border-bottom: $card-border-width solid $card-border-color;
|
||||
|
||||
&:first-child {
|
||||
@include border-radius($card-inner-border-radius $card-inner-border-radius 0 0);
|
||||
}
|
||||
|
||||
+ .list-group {
|
||||
.list-group-item:first-child {
|
||||
border-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
padding: $card-spacer-y $card-spacer-x;
|
||||
background-color: $card-cap-bg;
|
||||
border-top: $card-border-width solid $card-border-color;
|
||||
|
||||
&:last-child {
|
||||
@include border-radius(0 0 $card-inner-border-radius $card-inner-border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Header navs
|
||||
//
|
||||
|
||||
.card-header-tabs {
|
||||
margin-right: -$card-spacer-x / 2;
|
||||
margin-bottom: -$card-spacer-y;
|
||||
margin-left: -$card-spacer-x / 2;
|
||||
border-bottom: 0;
|
||||
}
|
||||
|
||||
.card-header-pills {
|
||||
margin-right: -$card-spacer-x / 2;
|
||||
margin-left: -$card-spacer-x / 2;
|
||||
}
|
||||
|
||||
// Card image
|
||||
.card-img-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: $card-img-overlay-padding;
|
||||
}
|
||||
|
||||
.card-img,
|
||||
.card-img-top,
|
||||
.card-img-bottom {
|
||||
flex-shrink: 0; // For IE: https://github.com/twbs/bootstrap/issues/29396
|
||||
width: 100%; // Required because we use flexbox and this inherently applies align-self: stretch
|
||||
}
|
||||
|
||||
.card-img,
|
||||
.card-img-top {
|
||||
@include border-top-radius($card-inner-border-radius);
|
||||
}
|
||||
|
||||
.card-img,
|
||||
.card-img-bottom {
|
||||
@include border-bottom-radius($card-inner-border-radius);
|
||||
}
|
||||
|
||||
|
||||
// Card deck
|
||||
|
||||
.card-deck {
|
||||
.card {
|
||||
margin-bottom: $card-deck-margin;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
margin-right: -$card-deck-margin;
|
||||
margin-left: -$card-deck-margin;
|
||||
|
||||
.card {
|
||||
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
|
||||
flex: 1 0 0%;
|
||||
margin-right: $card-deck-margin;
|
||||
margin-bottom: 0; // Override the default
|
||||
margin-left: $card-deck-margin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Card groups
|
||||
//
|
||||
|
||||
.card-group {
|
||||
// The child selector allows nested `.card` within `.card-group`
|
||||
// to display properly.
|
||||
> .card {
|
||||
margin-bottom: $card-group-margin;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
// The child selector allows nested `.card` within `.card-group`
|
||||
// to display properly.
|
||||
> .card {
|
||||
// Flexbugs #4: https://github.com/philipwalton/flexbugs#flexbug-4
|
||||
flex: 1 0 0%;
|
||||
margin-bottom: 0;
|
||||
|
||||
+ .card {
|
||||
margin-left: 0;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
// Handle rounded corners
|
||||
@if $enable-rounded {
|
||||
&:not(:last-child) {
|
||||
@include border-right-radius(0);
|
||||
|
||||
.card-img-top,
|
||||
.card-header {
|
||||
// stylelint-disable-next-line property-blacklist
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
.card-img-bottom,
|
||||
.card-footer {
|
||||
// stylelint-disable-next-line property-blacklist
|
||||
border-bottom-right-radius: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
@include border-left-radius(0);
|
||||
|
||||
.card-img-top,
|
||||
.card-header {
|
||||
// stylelint-disable-next-line property-blacklist
|
||||
border-top-left-radius: 0;
|
||||
}
|
||||
.card-img-bottom,
|
||||
.card-footer {
|
||||
// stylelint-disable-next-line property-blacklist
|
||||
border-bottom-left-radius: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Columns
|
||||
//
|
||||
|
||||
.card-columns {
|
||||
.card {
|
||||
margin-bottom: $card-columns-margin;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
column-count: $card-columns-count;
|
||||
column-gap: $card-columns-gap;
|
||||
orphans: 1;
|
||||
widows: 1;
|
||||
|
||||
.card {
|
||||
display: inline-block; // Don't let them vertically span multiple columns
|
||||
width: 100%; // Don't let their width change
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Accordion
|
||||
//
|
||||
|
||||
.accordion {
|
||||
> .card {
|
||||
overflow: hidden;
|
||||
|
||||
&:not(:last-of-type) {
|
||||
border-bottom: 0;
|
||||
@include border-bottom-radius(0);
|
||||
}
|
||||
|
||||
&:not(:first-of-type) {
|
||||
@include border-top-radius(0);
|
||||
}
|
||||
|
||||
> .card-header {
|
||||
@include border-radius(0);
|
||||
margin-bottom: -$card-border-width;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,197 +0,0 @@
|
||||
// Notes on the classes:
|
||||
//
|
||||
// 1. .carousel.pointer-event should ideally be pan-y (to allow for users to scroll vertically)
|
||||
// even when their scroll action started on a carousel, but for compatibility (with Firefox)
|
||||
// we're preventing all actions instead
|
||||
// 2. The .carousel-item-left and .carousel-item-right is used to indicate where
|
||||
// the active slide is heading.
|
||||
// 3. .active.carousel-item is the current slide.
|
||||
// 4. .active.carousel-item-left and .active.carousel-item-right is the current
|
||||
// slide in its in-transition state. Only one of these occurs at a time.
|
||||
// 5. .carousel-item-next.carousel-item-left and .carousel-item-prev.carousel-item-right
|
||||
// is the upcoming slide in transition.
|
||||
|
||||
.carousel {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.carousel.pointer-event {
|
||||
touch-action: pan-y;
|
||||
}
|
||||
|
||||
.carousel-inner {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
@include clearfix();
|
||||
}
|
||||
|
||||
.carousel-item {
|
||||
position: relative;
|
||||
display: none;
|
||||
float: left;
|
||||
width: 100%;
|
||||
margin-right: -100%;
|
||||
backface-visibility: hidden;
|
||||
@include transition($carousel-transition);
|
||||
}
|
||||
|
||||
.carousel-item.active,
|
||||
.carousel-item-next,
|
||||
.carousel-item-prev {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.carousel-item-next:not(.carousel-item-left),
|
||||
.active.carousel-item-right {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
.carousel-item-prev:not(.carousel-item-right),
|
||||
.active.carousel-item-left {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Alternate transitions
|
||||
//
|
||||
|
||||
.carousel-fade {
|
||||
.carousel-item {
|
||||
opacity: 0;
|
||||
transition-property: opacity;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.carousel-item.active,
|
||||
.carousel-item-next.carousel-item-left,
|
||||
.carousel-item-prev.carousel-item-right {
|
||||
z-index: 1;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.active.carousel-item-left,
|
||||
.active.carousel-item-right {
|
||||
z-index: 0;
|
||||
opacity: 0;
|
||||
@include transition(opacity 0s $carousel-transition-duration);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Left/right controls for nav
|
||||
//
|
||||
|
||||
.carousel-control-prev,
|
||||
.carousel-control-next {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 1;
|
||||
// Use flex for alignment (1-3)
|
||||
display: flex; // 1. allow flex styles
|
||||
align-items: center; // 2. vertically center contents
|
||||
justify-content: center; // 3. horizontally center contents
|
||||
width: $carousel-control-width;
|
||||
color: $carousel-control-color;
|
||||
text-align: center;
|
||||
opacity: $carousel-control-opacity;
|
||||
@include transition($carousel-control-transition);
|
||||
|
||||
// Hover/focus state
|
||||
@include hover-focus() {
|
||||
color: $carousel-control-color;
|
||||
text-decoration: none;
|
||||
outline: 0;
|
||||
opacity: $carousel-control-hover-opacity;
|
||||
}
|
||||
}
|
||||
.carousel-control-prev {
|
||||
left: 0;
|
||||
@if $enable-gradients {
|
||||
background-image: linear-gradient(90deg, rgba($black, .25), rgba($black, .001));
|
||||
}
|
||||
}
|
||||
.carousel-control-next {
|
||||
right: 0;
|
||||
@if $enable-gradients {
|
||||
background-image: linear-gradient(270deg, rgba($black, .25), rgba($black, .001));
|
||||
}
|
||||
}
|
||||
|
||||
// Icons for within
|
||||
.carousel-control-prev-icon,
|
||||
.carousel-control-next-icon {
|
||||
display: inline-block;
|
||||
width: $carousel-control-icon-width;
|
||||
height: $carousel-control-icon-width;
|
||||
background: no-repeat 50% / 100% 100%;
|
||||
}
|
||||
.carousel-control-prev-icon {
|
||||
background-image: escape-svg($carousel-control-prev-icon-bg);
|
||||
}
|
||||
.carousel-control-next-icon {
|
||||
background-image: escape-svg($carousel-control-next-icon-bg);
|
||||
}
|
||||
|
||||
|
||||
// Optional indicator pips
|
||||
//
|
||||
// Add an ordered list with the following class and add a list item for each
|
||||
// slide your carousel holds.
|
||||
|
||||
.carousel-indicators {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 15;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding-left: 0; // override <ol> default
|
||||
// Use the .carousel-control's width as margin so we don't overlay those
|
||||
margin-right: $carousel-control-width;
|
||||
margin-left: $carousel-control-width;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
box-sizing: content-box;
|
||||
flex: 0 1 auto;
|
||||
width: $carousel-indicator-width;
|
||||
height: $carousel-indicator-height;
|
||||
margin-right: $carousel-indicator-spacer;
|
||||
margin-left: $carousel-indicator-spacer;
|
||||
text-indent: -999px;
|
||||
cursor: pointer;
|
||||
background-color: $carousel-indicator-active-bg;
|
||||
background-clip: padding-box;
|
||||
// Use transparent borders to increase the hit area by 10px on top and bottom.
|
||||
border-top: $carousel-indicator-hit-area-height solid transparent;
|
||||
border-bottom: $carousel-indicator-hit-area-height solid transparent;
|
||||
opacity: .5;
|
||||
@include transition($carousel-indicator-transition);
|
||||
}
|
||||
|
||||
.active {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Optional captions
|
||||
//
|
||||
//
|
||||
|
||||
.carousel-caption {
|
||||
position: absolute;
|
||||
right: (100% - $carousel-caption-width) / 2;
|
||||
bottom: 20px;
|
||||
left: (100% - $carousel-caption-width) / 2;
|
||||
z-index: 10;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
color: $carousel-caption-color;
|
||||
text-align: center;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
.close {
|
||||
float: right;
|
||||
@include font-size($close-font-size);
|
||||
font-weight: $close-font-weight;
|
||||
line-height: 1;
|
||||
color: $close-color;
|
||||
text-shadow: $close-text-shadow;
|
||||
opacity: .5;
|
||||
|
||||
// Override <a>'s hover style
|
||||
@include hover() {
|
||||
color: $close-color;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:not(:disabled):not(.disabled) {
|
||||
@include hover-focus() {
|
||||
opacity: .75;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Additional properties for button version
|
||||
// iOS requires the button element instead of an anchor tag.
|
||||
// If you want the anchor version, it requires `href="#"`.
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
|
||||
|
||||
// stylelint-disable-next-line selector-no-qualifying-type
|
||||
button.close {
|
||||
padding: 0;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
// Future-proof disabling of clicks on `<a>` elements
|
||||
|
||||
// stylelint-disable-next-line selector-no-qualifying-type
|
||||
a.close.disabled {
|
||||
pointer-events: none;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
// Inline code
|
||||
code {
|
||||
@include font-size($code-font-size);
|
||||
color: $code-color;
|
||||
word-wrap: break-word;
|
||||
|
||||
// Streamline the style when inside anchors to avoid broken underline and more
|
||||
a > & {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
// User input typically entered via keyboard
|
||||
kbd {
|
||||
padding: $kbd-padding-y $kbd-padding-x;
|
||||
@include font-size($kbd-font-size);
|
||||
color: $kbd-color;
|
||||
background-color: $kbd-bg;
|
||||
@include border-radius($border-radius-sm);
|
||||
@include box-shadow($kbd-box-shadow);
|
||||
|
||||
kbd {
|
||||
padding: 0;
|
||||
@include font-size(100%);
|
||||
font-weight: $nested-kbd-font-weight;
|
||||
@include box-shadow(none);
|
||||
}
|
||||
}
|
||||
|
||||
// Blocks of code
|
||||
pre {
|
||||
display: block;
|
||||
@include font-size($code-font-size);
|
||||
color: $pre-color;
|
||||
|
||||
// Account for some code outputs that place code tags in pre tags
|
||||
code {
|
||||
@include font-size(inherit);
|
||||
color: inherit;
|
||||
word-break: normal;
|
||||
}
|
||||
}
|
||||
|
||||
// Enable scrollable blocks of code
|
||||
.pre-scrollable {
|
||||
max-height: $pre-scrollable-max-height;
|
||||
overflow-y: scroll;
|
||||
}
|
@ -1,521 +0,0 @@
|
||||
// Embedded icons from Open Iconic.
|
||||
// Released under MIT and copyright 2014 Waybury.
|
||||
// https://useiconic.com/open
|
||||
|
||||
|
||||
// Checkboxes and radios
|
||||
//
|
||||
// Base class takes care of all the key behavioral aspects.
|
||||
|
||||
.custom-control {
|
||||
position: relative;
|
||||
display: block;
|
||||
min-height: $font-size-base * $line-height-base;
|
||||
padding-left: $custom-control-gutter + $custom-control-indicator-size;
|
||||
}
|
||||
|
||||
.custom-control-inline {
|
||||
display: inline-flex;
|
||||
margin-right: $custom-control-spacer-x;
|
||||
}
|
||||
|
||||
.custom-control-input {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
z-index: -1; // Put the input behind the label so it doesn't overlay text
|
||||
width: $custom-control-indicator-size;
|
||||
height: ($font-size-base * $line-height-base + $custom-control-indicator-size) / 2;
|
||||
opacity: 0;
|
||||
|
||||
&:checked ~ .custom-control-label::before {
|
||||
color: $custom-control-indicator-checked-color;
|
||||
border-color: $custom-control-indicator-checked-border-color;
|
||||
@include gradient-bg($custom-control-indicator-checked-bg);
|
||||
@include box-shadow($custom-control-indicator-checked-box-shadow);
|
||||
}
|
||||
|
||||
&:focus ~ .custom-control-label::before {
|
||||
// the mixin is not used here to make sure there is feedback
|
||||
@if $enable-shadows {
|
||||
box-shadow: $input-box-shadow, $input-focus-box-shadow;
|
||||
} @else {
|
||||
box-shadow: $custom-control-indicator-focus-box-shadow;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus:not(:checked) ~ .custom-control-label::before {
|
||||
border-color: $custom-control-indicator-focus-border-color;
|
||||
}
|
||||
|
||||
&:not(:disabled):active ~ .custom-control-label::before {
|
||||
color: $custom-control-indicator-active-color;
|
||||
background-color: $custom-control-indicator-active-bg;
|
||||
border-color: $custom-control-indicator-active-border-color;
|
||||
@include box-shadow($custom-control-indicator-active-box-shadow);
|
||||
}
|
||||
|
||||
// Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
|
||||
&[disabled],
|
||||
&:disabled {
|
||||
~ .custom-control-label {
|
||||
color: $custom-control-label-disabled-color;
|
||||
|
||||
&::before {
|
||||
background-color: $custom-control-indicator-disabled-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Custom control indicators
|
||||
//
|
||||
// Build the custom controls out of pseudo-elements.
|
||||
|
||||
.custom-control-label {
|
||||
position: relative;
|
||||
margin-bottom: 0;
|
||||
color: $custom-control-label-color;
|
||||
vertical-align: top;
|
||||
cursor: $custom-control-cursor;
|
||||
|
||||
// Background-color and (when enabled) gradient
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
|
||||
left: -($custom-control-gutter + $custom-control-indicator-size);
|
||||
display: block;
|
||||
width: $custom-control-indicator-size;
|
||||
height: $custom-control-indicator-size;
|
||||
pointer-events: none;
|
||||
content: "";
|
||||
background-color: $custom-control-indicator-bg;
|
||||
border: $custom-control-indicator-border-color solid $custom-control-indicator-border-width;
|
||||
@include box-shadow($custom-control-indicator-box-shadow);
|
||||
}
|
||||
|
||||
// Foreground (icon)
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: ($font-size-base * $line-height-base - $custom-control-indicator-size) / 2;
|
||||
left: -($custom-control-gutter + $custom-control-indicator-size);
|
||||
display: block;
|
||||
width: $custom-control-indicator-size;
|
||||
height: $custom-control-indicator-size;
|
||||
content: "";
|
||||
background: no-repeat 50% / #{$custom-control-indicator-bg-size};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Checkboxes
|
||||
//
|
||||
// Tweak just a few things for checkboxes.
|
||||
|
||||
.custom-checkbox {
|
||||
.custom-control-label::before {
|
||||
@include border-radius($custom-checkbox-indicator-border-radius);
|
||||
}
|
||||
|
||||
.custom-control-input:checked ~ .custom-control-label {
|
||||
&::after {
|
||||
background-image: escape-svg($custom-checkbox-indicator-icon-checked);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-control-input:indeterminate ~ .custom-control-label {
|
||||
&::before {
|
||||
border-color: $custom-checkbox-indicator-indeterminate-border-color;
|
||||
@include gradient-bg($custom-checkbox-indicator-indeterminate-bg);
|
||||
@include box-shadow($custom-checkbox-indicator-indeterminate-box-shadow);
|
||||
}
|
||||
&::after {
|
||||
background-image: escape-svg($custom-checkbox-indicator-icon-indeterminate);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-control-input:disabled {
|
||||
&:checked ~ .custom-control-label::before {
|
||||
background-color: $custom-control-indicator-checked-disabled-bg;
|
||||
}
|
||||
&:indeterminate ~ .custom-control-label::before {
|
||||
background-color: $custom-control-indicator-checked-disabled-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Radios
|
||||
//
|
||||
// Tweak just a few things for radios.
|
||||
|
||||
.custom-radio {
|
||||
.custom-control-label::before {
|
||||
// stylelint-disable-next-line property-blacklist
|
||||
border-radius: $custom-radio-indicator-border-radius;
|
||||
}
|
||||
|
||||
.custom-control-input:checked ~ .custom-control-label {
|
||||
&::after {
|
||||
background-image: escape-svg($custom-radio-indicator-icon-checked);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-control-input:disabled {
|
||||
&:checked ~ .custom-control-label::before {
|
||||
background-color: $custom-control-indicator-checked-disabled-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// switches
|
||||
//
|
||||
// Tweak a few things for switches
|
||||
|
||||
.custom-switch {
|
||||
padding-left: $custom-switch-width + $custom-control-gutter;
|
||||
|
||||
.custom-control-label {
|
||||
&::before {
|
||||
left: -($custom-switch-width + $custom-control-gutter);
|
||||
width: $custom-switch-width;
|
||||
pointer-events: all;
|
||||
// stylelint-disable-next-line property-blacklist
|
||||
border-radius: $custom-switch-indicator-border-radius;
|
||||
}
|
||||
|
||||
&::after {
|
||||
top: add(($font-size-base * $line-height-base - $custom-control-indicator-size) / 2, $custom-control-indicator-border-width * 2);
|
||||
left: add(-($custom-switch-width + $custom-control-gutter), $custom-control-indicator-border-width * 2);
|
||||
width: $custom-switch-indicator-size;
|
||||
height: $custom-switch-indicator-size;
|
||||
background-color: $custom-control-indicator-border-color;
|
||||
// stylelint-disable-next-line property-blacklist
|
||||
border-radius: $custom-switch-indicator-border-radius;
|
||||
@include transition(transform .15s ease-in-out, $custom-forms-transition);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-control-input:checked ~ .custom-control-label {
|
||||
&::after {
|
||||
background-color: $custom-control-indicator-bg;
|
||||
transform: translateX($custom-switch-width - $custom-control-indicator-size);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-control-input:disabled {
|
||||
&:checked ~ .custom-control-label::before {
|
||||
background-color: $custom-control-indicator-checked-disabled-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Select
|
||||
//
|
||||
// Replaces the browser default select with a custom one, mostly pulled from
|
||||
// https://primer.github.io/.
|
||||
//
|
||||
|
||||
.custom-select {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: $custom-select-height;
|
||||
padding: $custom-select-padding-y ($custom-select-padding-x + $custom-select-indicator-padding) $custom-select-padding-y $custom-select-padding-x;
|
||||
font-family: $custom-select-font-family;
|
||||
@include font-size($custom-select-font-size);
|
||||
font-weight: $custom-select-font-weight;
|
||||
line-height: $custom-select-line-height;
|
||||
color: $custom-select-color;
|
||||
vertical-align: middle;
|
||||
background: $custom-select-bg $custom-select-background;
|
||||
border: $custom-select-border-width solid $custom-select-border-color;
|
||||
@include border-radius($custom-select-border-radius, 0);
|
||||
@include box-shadow($custom-select-box-shadow);
|
||||
appearance: none;
|
||||
|
||||
&:focus {
|
||||
border-color: $custom-select-focus-border-color;
|
||||
outline: 0;
|
||||
@if $enable-shadows {
|
||||
box-shadow: $custom-select-box-shadow, $custom-select-focus-box-shadow;
|
||||
} @else {
|
||||
box-shadow: $custom-select-focus-box-shadow;
|
||||
}
|
||||
|
||||
&::-ms-value {
|
||||
// For visual consistency with other platforms/browsers,
|
||||
// suppress the default white text on blue background highlight given to
|
||||
// the selected option text when the (still closed) <select> receives focus
|
||||
// in IE and (under certain conditions) Edge.
|
||||
// See https://github.com/twbs/bootstrap/issues/19398.
|
||||
color: $input-color;
|
||||
background-color: $input-bg;
|
||||
}
|
||||
}
|
||||
|
||||
&[multiple],
|
||||
&[size]:not([size="1"]) {
|
||||
height: auto;
|
||||
padding-right: $custom-select-padding-x;
|
||||
background-image: none;
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
color: $custom-select-disabled-color;
|
||||
background-color: $custom-select-disabled-bg;
|
||||
}
|
||||
|
||||
// Hides the default caret in IE11
|
||||
&::-ms-expand {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Remove outline from select box in FF
|
||||
&:-moz-focusring {
|
||||
color: transparent;
|
||||
text-shadow: 0 0 0 $custom-select-color;
|
||||
}
|
||||
}
|
||||
|
||||
.custom-select-sm {
|
||||
height: $custom-select-height-sm;
|
||||
padding-top: $custom-select-padding-y-sm;
|
||||
padding-bottom: $custom-select-padding-y-sm;
|
||||
padding-left: $custom-select-padding-x-sm;
|
||||
@include font-size($custom-select-font-size-sm);
|
||||
}
|
||||
|
||||
.custom-select-lg {
|
||||
height: $custom-select-height-lg;
|
||||
padding-top: $custom-select-padding-y-lg;
|
||||
padding-bottom: $custom-select-padding-y-lg;
|
||||
padding-left: $custom-select-padding-x-lg;
|
||||
@include font-size($custom-select-font-size-lg);
|
||||
}
|
||||
|
||||
|
||||
// File
|
||||
//
|
||||
// Custom file input.
|
||||
|
||||
.custom-file {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: $custom-file-height;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.custom-file-input {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
height: $custom-file-height;
|
||||
margin: 0;
|
||||
opacity: 0;
|
||||
|
||||
&:focus ~ .custom-file-label {
|
||||
border-color: $custom-file-focus-border-color;
|
||||
box-shadow: $custom-file-focus-box-shadow;
|
||||
}
|
||||
|
||||
// Use [disabled] and :disabled to work around https://github.com/twbs/bootstrap/issues/28247
|
||||
&[disabled] ~ .custom-file-label,
|
||||
&:disabled ~ .custom-file-label {
|
||||
background-color: $custom-file-disabled-bg;
|
||||
}
|
||||
|
||||
@each $lang, $value in $custom-file-text {
|
||||
&:lang(#{$lang}) ~ .custom-file-label::after {
|
||||
content: $value;
|
||||
}
|
||||
}
|
||||
|
||||
~ .custom-file-label[data-browse]::after {
|
||||
content: attr(data-browse);
|
||||
}
|
||||
}
|
||||
|
||||
.custom-file-label {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
height: $custom-file-height;
|
||||
padding: $custom-file-padding-y $custom-file-padding-x;
|
||||
font-family: $custom-file-font-family;
|
||||
font-weight: $custom-file-font-weight;
|
||||
line-height: $custom-file-line-height;
|
||||
color: $custom-file-color;
|
||||
background-color: $custom-file-bg;
|
||||
border: $custom-file-border-width solid $custom-file-border-color;
|
||||
@include border-radius($custom-file-border-radius);
|
||||
@include box-shadow($custom-file-box-shadow);
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 3;
|
||||
display: block;
|
||||
height: $custom-file-height-inner;
|
||||
padding: $custom-file-padding-y $custom-file-padding-x;
|
||||
line-height: $custom-file-line-height;
|
||||
color: $custom-file-button-color;
|
||||
content: "Browse";
|
||||
@include gradient-bg($custom-file-button-bg);
|
||||
border-left: inherit;
|
||||
@include border-radius(0 $custom-file-border-radius $custom-file-border-radius 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Range
|
||||
//
|
||||
// Style range inputs the same across browsers. Vendor-specific rules for pseudo
|
||||
// elements cannot be mixed. As such, there are no shared styles for focus or
|
||||
// active states on prefixed selectors.
|
||||
|
||||
.custom-range {
|
||||
width: 100%;
|
||||
height: add($custom-range-thumb-height, $custom-range-thumb-focus-box-shadow-width * 2);
|
||||
padding: 0; // Need to reset padding
|
||||
background-color: transparent;
|
||||
appearance: none;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
|
||||
// Pseudo-elements must be split across multiple rulesets to have an effect.
|
||||
// No box-shadow() mixin for focus accessibility.
|
||||
&::-webkit-slider-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
|
||||
&::-moz-range-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
|
||||
&::-ms-thumb { box-shadow: $custom-range-thumb-focus-box-shadow; }
|
||||
}
|
||||
|
||||
&::-moz-focus-outer {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
&::-webkit-slider-thumb {
|
||||
width: $custom-range-thumb-width;
|
||||
height: $custom-range-thumb-height;
|
||||
margin-top: ($custom-range-track-height - $custom-range-thumb-height) / 2; // Webkit specific
|
||||
@include gradient-bg($custom-range-thumb-bg);
|
||||
border: $custom-range-thumb-border;
|
||||
@include border-radius($custom-range-thumb-border-radius);
|
||||
@include box-shadow($custom-range-thumb-box-shadow);
|
||||
@include transition($custom-forms-transition);
|
||||
appearance: none;
|
||||
|
||||
&:active {
|
||||
@include gradient-bg($custom-range-thumb-active-bg);
|
||||
}
|
||||
}
|
||||
|
||||
&::-webkit-slider-runnable-track {
|
||||
width: $custom-range-track-width;
|
||||
height: $custom-range-track-height;
|
||||
color: transparent; // Why?
|
||||
cursor: $custom-range-track-cursor;
|
||||
background-color: $custom-range-track-bg;
|
||||
border-color: transparent;
|
||||
@include border-radius($custom-range-track-border-radius);
|
||||
@include box-shadow($custom-range-track-box-shadow);
|
||||
}
|
||||
|
||||
&::-moz-range-thumb {
|
||||
width: $custom-range-thumb-width;
|
||||
height: $custom-range-thumb-height;
|
||||
@include gradient-bg($custom-range-thumb-bg);
|
||||
border: $custom-range-thumb-border;
|
||||
@include border-radius($custom-range-thumb-border-radius);
|
||||
@include box-shadow($custom-range-thumb-box-shadow);
|
||||
@include transition($custom-forms-transition);
|
||||
appearance: none;
|
||||
|
||||
&:active {
|
||||
@include gradient-bg($custom-range-thumb-active-bg);
|
||||
}
|
||||
}
|
||||
|
||||
&::-moz-range-track {
|
||||
width: $custom-range-track-width;
|
||||
height: $custom-range-track-height;
|
||||
color: transparent;
|
||||
cursor: $custom-range-track-cursor;
|
||||
background-color: $custom-range-track-bg;
|
||||
border-color: transparent; // Firefox specific?
|
||||
@include border-radius($custom-range-track-border-radius);
|
||||
@include box-shadow($custom-range-track-box-shadow);
|
||||
}
|
||||
|
||||
&::-ms-thumb {
|
||||
width: $custom-range-thumb-width;
|
||||
height: $custom-range-thumb-height;
|
||||
margin-top: 0; // Edge specific
|
||||
margin-right: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
|
||||
margin-left: $custom-range-thumb-focus-box-shadow-width; // Workaround that overflowed box-shadow is hidden.
|
||||
@include gradient-bg($custom-range-thumb-bg);
|
||||
border: $custom-range-thumb-border;
|
||||
@include border-radius($custom-range-thumb-border-radius);
|
||||
@include box-shadow($custom-range-thumb-box-shadow);
|
||||
@include transition($custom-forms-transition);
|
||||
appearance: none;
|
||||
|
||||
&:active {
|
||||
@include gradient-bg($custom-range-thumb-active-bg);
|
||||
}
|
||||
}
|
||||
|
||||
&::-ms-track {
|
||||
width: $custom-range-track-width;
|
||||
height: $custom-range-track-height;
|
||||
color: transparent;
|
||||
cursor: $custom-range-track-cursor;
|
||||
background-color: transparent;
|
||||
border-color: transparent;
|
||||
border-width: $custom-range-thumb-height / 2;
|
||||
@include box-shadow($custom-range-track-box-shadow);
|
||||
}
|
||||
|
||||
&::-ms-fill-lower {
|
||||
background-color: $custom-range-track-bg;
|
||||
@include border-radius($custom-range-track-border-radius);
|
||||
}
|
||||
|
||||
&::-ms-fill-upper {
|
||||
margin-right: 15px; // arbitrary?
|
||||
background-color: $custom-range-track-bg;
|
||||
@include border-radius($custom-range-track-border-radius);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
&::-webkit-slider-thumb {
|
||||
background-color: $custom-range-thumb-disabled-bg;
|
||||
}
|
||||
|
||||
&::-webkit-slider-runnable-track {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&::-moz-range-thumb {
|
||||
background-color: $custom-range-thumb-disabled-bg;
|
||||
}
|
||||
|
||||
&::-moz-range-track {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&::-ms-thumb {
|
||||
background-color: $custom-range-thumb-disabled-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.custom-control-label::before,
|
||||
.custom-file-label,
|
||||
.custom-select {
|
||||
@include transition($custom-forms-transition);
|
||||
}
|
@ -1,191 +0,0 @@
|
||||
// The dropdown wrapper (`<div>`)
|
||||
.dropup,
|
||||
.dropright,
|
||||
.dropdown,
|
||||
.dropleft {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
white-space: nowrap;
|
||||
|
||||
// Generate the caret automatically
|
||||
@include caret();
|
||||
}
|
||||
|
||||
// The dropdown menu
|
||||
.dropdown-menu {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
z-index: $zindex-dropdown;
|
||||
display: none; // none by default, but block on "open" of the menu
|
||||
float: left;
|
||||
min-width: $dropdown-min-width;
|
||||
padding: $dropdown-padding-y 0;
|
||||
margin: $dropdown-spacer 0 0; // override default ul
|
||||
@include font-size($dropdown-font-size);
|
||||
color: $dropdown-color;
|
||||
text-align: left; // Ensures proper alignment if parent has it changed (e.g., modal footer)
|
||||
list-style: none;
|
||||
background-color: $dropdown-bg;
|
||||
background-clip: padding-box;
|
||||
border: $dropdown-border-width solid $dropdown-border-color;
|
||||
@include border-radius($dropdown-border-radius);
|
||||
@include box-shadow($dropdown-box-shadow);
|
||||
}
|
||||
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
@include media-breakpoint-up($breakpoint) {
|
||||
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
|
||||
|
||||
.dropdown-menu#{$infix}-left {
|
||||
right: auto;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.dropdown-menu#{$infix}-right {
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Allow for dropdowns to go bottom up (aka, dropup-menu)
|
||||
// Just add .dropup after the standard .dropdown class and you're set.
|
||||
.dropup {
|
||||
.dropdown-menu {
|
||||
top: auto;
|
||||
bottom: 100%;
|
||||
margin-top: 0;
|
||||
margin-bottom: $dropdown-spacer;
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
@include caret(up);
|
||||
}
|
||||
}
|
||||
|
||||
.dropright {
|
||||
.dropdown-menu {
|
||||
top: 0;
|
||||
right: auto;
|
||||
left: 100%;
|
||||
margin-top: 0;
|
||||
margin-left: $dropdown-spacer;
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
@include caret(right);
|
||||
&::after {
|
||||
vertical-align: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropleft {
|
||||
.dropdown-menu {
|
||||
top: 0;
|
||||
right: 100%;
|
||||
left: auto;
|
||||
margin-top: 0;
|
||||
margin-right: $dropdown-spacer;
|
||||
}
|
||||
|
||||
.dropdown-toggle {
|
||||
@include caret(left);
|
||||
&::before {
|
||||
vertical-align: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When enabled Popper.js, reset basic dropdown position
|
||||
// stylelint-disable-next-line no-duplicate-selectors
|
||||
.dropdown-menu {
|
||||
&[x-placement^="top"],
|
||||
&[x-placement^="right"],
|
||||
&[x-placement^="bottom"],
|
||||
&[x-placement^="left"] {
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
}
|
||||
}
|
||||
|
||||
// Dividers (basically an `<hr>`) within the dropdown
|
||||
.dropdown-divider {
|
||||
@include nav-divider($dropdown-divider-bg, $dropdown-divider-margin-y, true);
|
||||
}
|
||||
|
||||
// Links, buttons, and more within the dropdown menu
|
||||
//
|
||||
// `<button>`-specific styles are denoted with `// For <button>s`
|
||||
.dropdown-item {
|
||||
display: block;
|
||||
width: 100%; // For `<button>`s
|
||||
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
|
||||
clear: both;
|
||||
font-weight: $font-weight-normal;
|
||||
color: $dropdown-link-color;
|
||||
text-align: inherit; // For `<button>`s
|
||||
white-space: nowrap; // prevent links from randomly breaking onto new lines
|
||||
background-color: transparent; // For `<button>`s
|
||||
border: 0; // For `<button>`s
|
||||
|
||||
// Prevent dropdown overflow if there's no padding
|
||||
// See https://github.com/twbs/bootstrap/pull/27703
|
||||
@if $dropdown-padding-y == 0 {
|
||||
&:first-child {
|
||||
@include border-top-radius($dropdown-inner-border-radius);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
@include border-bottom-radius($dropdown-inner-border-radius);
|
||||
}
|
||||
}
|
||||
|
||||
@include hover-focus() {
|
||||
color: $dropdown-link-hover-color;
|
||||
text-decoration: none;
|
||||
@include gradient-bg($dropdown-link-hover-bg);
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:active {
|
||||
color: $dropdown-link-active-color;
|
||||
text-decoration: none;
|
||||
@include gradient-bg($dropdown-link-active-bg);
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&:disabled {
|
||||
color: $dropdown-link-disabled-color;
|
||||
pointer-events: none;
|
||||
background-color: transparent;
|
||||
// Remove CSS gradients if they're enabled
|
||||
@if $enable-gradients {
|
||||
background-image: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dropdown-menu.show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
// Dropdown section headers
|
||||
.dropdown-header {
|
||||
display: block;
|
||||
padding: $dropdown-padding-y $dropdown-item-padding-x;
|
||||
margin-bottom: 0; // for use with heading elements
|
||||
@include font-size($font-size-sm);
|
||||
color: $dropdown-header-color;
|
||||
white-space: nowrap; // as with > li > a
|
||||
}
|
||||
|
||||
// Dropdown text
|
||||
.dropdown-item-text {
|
||||
display: block;
|
||||
padding: $dropdown-item-padding-y $dropdown-item-padding-x;
|
||||
color: $dropdown-link-color;
|
||||
}
|
@ -1,338 +0,0 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
|
||||
//
|
||||
// Textual form controls
|
||||
//
|
||||
|
||||
.form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: $input-height;
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
font-family: $input-font-family;
|
||||
@include font-size($input-font-size);
|
||||
font-weight: $input-font-weight;
|
||||
line-height: $input-line-height;
|
||||
color: $input-color;
|
||||
background-color: $input-bg;
|
||||
background-clip: padding-box;
|
||||
border: $input-border-width solid $input-border-color;
|
||||
|
||||
// Note: This has no effect on <select>s in some browsers, due to the limited stylability of `<select>`s in CSS.
|
||||
@include border-radius($input-border-radius, 0);
|
||||
|
||||
@include box-shadow($input-box-shadow);
|
||||
@include transition($input-transition);
|
||||
|
||||
// Unstyle the caret on `<select>`s in IE10+.
|
||||
&::-ms-expand {
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
// Remove select outline from select box in FF
|
||||
&:-moz-focusring {
|
||||
color: transparent;
|
||||
text-shadow: 0 0 0 $input-color;
|
||||
}
|
||||
|
||||
// Customize the `:focus` state to imitate native WebKit styles.
|
||||
@include form-control-focus($ignore-warning: true);
|
||||
|
||||
// Placeholder
|
||||
&::placeholder {
|
||||
color: $input-placeholder-color;
|
||||
// Override Firefox's unusual default opacity; see https://github.com/twbs/bootstrap/pull/11526.
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
// Disabled and read-only inputs
|
||||
//
|
||||
// HTML5 says that controls under a fieldset > legend:first-child won't be
|
||||
// disabled if the fieldset is disabled. Due to implementation difficulty, we
|
||||
// don't honor that edge case; we style them as disabled anyway.
|
||||
&:disabled,
|
||||
&[readonly] {
|
||||
background-color: $input-disabled-bg;
|
||||
// iOS fix for unreadable disabled content; see https://github.com/twbs/bootstrap/issues/11655.
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
select.form-control {
|
||||
&:focus::-ms-value {
|
||||
// Suppress the nested default white text on blue background highlight given to
|
||||
// the selected option text when the (still closed) <select> receives focus
|
||||
// in IE and (under certain conditions) Edge, as it looks bad and cannot be made to
|
||||
// match the appearance of the native widget.
|
||||
// See https://github.com/twbs/bootstrap/issues/19398.
|
||||
color: $input-color;
|
||||
background-color: $input-bg;
|
||||
}
|
||||
}
|
||||
|
||||
// Make file inputs better match text inputs by forcing them to new lines.
|
||||
.form-control-file,
|
||||
.form-control-range {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Labels
|
||||
//
|
||||
|
||||
// For use with horizontal and inline forms, when you need the label (or legend)
|
||||
// text to align with the form controls.
|
||||
.col-form-label {
|
||||
padding-top: add($input-padding-y, $input-border-width);
|
||||
padding-bottom: add($input-padding-y, $input-border-width);
|
||||
margin-bottom: 0; // Override the `<label>/<legend>` default
|
||||
@include font-size(inherit); // Override the `<legend>` default
|
||||
line-height: $input-line-height;
|
||||
}
|
||||
|
||||
.col-form-label-lg {
|
||||
padding-top: add($input-padding-y-lg, $input-border-width);
|
||||
padding-bottom: add($input-padding-y-lg, $input-border-width);
|
||||
@include font-size($input-font-size-lg);
|
||||
line-height: $input-line-height-lg;
|
||||
}
|
||||
|
||||
.col-form-label-sm {
|
||||
padding-top: add($input-padding-y-sm, $input-border-width);
|
||||
padding-bottom: add($input-padding-y-sm, $input-border-width);
|
||||
@include font-size($input-font-size-sm);
|
||||
line-height: $input-line-height-sm;
|
||||
}
|
||||
|
||||
|
||||
// Readonly controls as plain text
|
||||
//
|
||||
// Apply class to a readonly input to make it appear like regular plain
|
||||
// text (without any border, background color, focus indicator)
|
||||
|
||||
.form-control-plaintext {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: $input-padding-y 0;
|
||||
margin-bottom: 0; // match inputs if this class comes on inputs with default margins
|
||||
@include font-size($input-font-size);
|
||||
line-height: $input-line-height;
|
||||
color: $input-plaintext-color;
|
||||
background-color: transparent;
|
||||
border: solid transparent;
|
||||
border-width: $input-border-width 0;
|
||||
|
||||
&.form-control-sm,
|
||||
&.form-control-lg {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Form control sizing
|
||||
//
|
||||
// Build on `.form-control` with modifier classes to decrease or increase the
|
||||
// height and font-size of form controls.
|
||||
//
|
||||
// Repeated in `_input_group.scss` to avoid Sass extend issues.
|
||||
|
||||
.form-control-sm {
|
||||
height: $input-height-sm;
|
||||
padding: $input-padding-y-sm $input-padding-x-sm;
|
||||
@include font-size($input-font-size-sm);
|
||||
line-height: $input-line-height-sm;
|
||||
@include border-radius($input-border-radius-sm);
|
||||
}
|
||||
|
||||
.form-control-lg {
|
||||
height: $input-height-lg;
|
||||
padding: $input-padding-y-lg $input-padding-x-lg;
|
||||
@include font-size($input-font-size-lg);
|
||||
line-height: $input-line-height-lg;
|
||||
@include border-radius($input-border-radius-lg);
|
||||
}
|
||||
|
||||
// stylelint-disable-next-line no-duplicate-selectors
|
||||
select.form-control {
|
||||
&[size],
|
||||
&[multiple] {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
textarea.form-control {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
// Form groups
|
||||
//
|
||||
// Designed to help with the organization and spacing of vertical forms. For
|
||||
// horizontal forms, use the predefined grid classes.
|
||||
|
||||
.form-group {
|
||||
margin-bottom: $form-group-margin-bottom;
|
||||
}
|
||||
|
||||
.form-text {
|
||||
display: block;
|
||||
margin-top: $form-text-margin-top;
|
||||
}
|
||||
|
||||
|
||||
// Form grid
|
||||
//
|
||||
// Special replacement for our grid system's `.row` for tighter form layouts.
|
||||
|
||||
.form-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-right: -$form-grid-gutter-width / 2;
|
||||
margin-left: -$form-grid-gutter-width / 2;
|
||||
|
||||
> .col,
|
||||
> [class*="col-"] {
|
||||
padding-right: $form-grid-gutter-width / 2;
|
||||
padding-left: $form-grid-gutter-width / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Checkboxes and radios
|
||||
//
|
||||
// Indent the labels to position radios/checkboxes as hanging controls.
|
||||
|
||||
.form-check {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding-left: $form-check-input-gutter;
|
||||
}
|
||||
|
||||
.form-check-input {
|
||||
position: absolute;
|
||||
margin-top: $form-check-input-margin-y;
|
||||
margin-left: -$form-check-input-gutter;
|
||||
|
||||
// Use [disabled] and :disabled for workaround https://github.com/twbs/bootstrap/issues/28247
|
||||
&[disabled] ~ .form-check-label,
|
||||
&:disabled ~ .form-check-label {
|
||||
color: $text-muted;
|
||||
}
|
||||
}
|
||||
|
||||
.form-check-label {
|
||||
margin-bottom: 0; // Override default `<label>` bottom margin
|
||||
}
|
||||
|
||||
.form-check-inline {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding-left: 0; // Override base .form-check
|
||||
margin-right: $form-check-inline-margin-x;
|
||||
|
||||
// Undo .form-check-input defaults and add some `margin-right`.
|
||||
.form-check-input {
|
||||
position: static;
|
||||
margin-top: 0;
|
||||
margin-right: $form-check-inline-input-margin-x;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Form validation
|
||||
//
|
||||
// Provide feedback to users when form field values are valid or invalid. Works
|
||||
// primarily for client-side validation via scoped `:invalid` and `:valid`
|
||||
// pseudo-classes but also includes `.is-invalid` and `.is-valid` classes for
|
||||
// server side validation.
|
||||
|
||||
@each $state, $data in $form-validation-states {
|
||||
@include form-validation-state($state, map-get($data, color), map-get($data, icon));
|
||||
}
|
||||
|
||||
// Inline forms
|
||||
//
|
||||
// Make forms appear inline(-block) by adding the `.form-inline` class. Inline
|
||||
// forms begin stacked on extra small (mobile) devices and then go inline when
|
||||
// viewports reach <768px.
|
||||
//
|
||||
// Requires wrapping inputs and labels with `.form-group` for proper display of
|
||||
// default HTML form controls and our custom form controls (e.g., input groups).
|
||||
|
||||
.form-inline {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
align-items: center; // Prevent shorter elements from growing to same height as others (e.g., small buttons growing to normal sized button height)
|
||||
|
||||
// Because we use flex, the initial sizing of checkboxes is collapsed and
|
||||
// doesn't occupy the full-width (which is what we want for xs grid tier),
|
||||
// so we force that here.
|
||||
.form-check {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// Kick in the inline
|
||||
@include media-breakpoint-up(sm) {
|
||||
label {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
// Inline-block all the things for "inline"
|
||||
.form-group {
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
flex-flow: row wrap;
|
||||
align-items: center;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
// Allow folks to *not* use `.form-group`
|
||||
.form-control {
|
||||
display: inline-block;
|
||||
width: auto; // Prevent labels from stacking above inputs in `.form-group`
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
// Make static controls behave like regular ones
|
||||
.form-control-plaintext {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.input-group,
|
||||
.custom-select {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
// Remove default margin on radios/checkboxes that were used for stacking, and
|
||||
// then undo the floating of radios and checkboxes to match.
|
||||
.form-check {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: auto;
|
||||
padding-left: 0;
|
||||
}
|
||||
.form-check-input {
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
margin-top: 0;
|
||||
margin-right: $form-check-input-margin-x;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.custom-control {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.custom-control-label {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,134 +0,0 @@
|
||||
// Bootstrap functions
|
||||
//
|
||||
// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.
|
||||
|
||||
// Ascending
|
||||
// Used to evaluate Sass maps like our grid breakpoints.
|
||||
@mixin _assert-ascending($map, $map-name) {
|
||||
$prev-key: null;
|
||||
$prev-num: null;
|
||||
@each $key, $num in $map {
|
||||
@if $prev-num == null or unit($num) == "%" or unit($prev-num) == "%" {
|
||||
// Do nothing
|
||||
} @else if not comparable($prev-num, $num) {
|
||||
@warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";
|
||||
} @else if $prev-num >= $num {
|
||||
@warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";
|
||||
}
|
||||
$prev-key: $key;
|
||||
$prev-num: $num;
|
||||
}
|
||||
}
|
||||
|
||||
// Starts at zero
|
||||
// Used to ensure the min-width of the lowest breakpoint starts at 0.
|
||||
@mixin _assert-starts-at-zero($map, $map-name: "$grid-breakpoints") {
|
||||
$values: map-values($map);
|
||||
$first-value: nth($values, 1);
|
||||
@if $first-value != 0 {
|
||||
@warn "First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.";
|
||||
}
|
||||
}
|
||||
|
||||
// Replace `$search` with `$replace` in `$string`
|
||||
// Used on our SVG icon backgrounds for custom forms.
|
||||
//
|
||||
// @author Hugo Giraudel
|
||||
// @param {String} $string - Initial string
|
||||
// @param {String} $search - Substring to replace
|
||||
// @param {String} $replace ('') - New value
|
||||
// @return {String} - Updated string
|
||||
@function str-replace($string, $search, $replace: "") {
|
||||
$index: str-index($string, $search);
|
||||
|
||||
@if $index {
|
||||
@return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
|
||||
}
|
||||
|
||||
@return $string;
|
||||
}
|
||||
|
||||
// See https://codepen.io/kevinweber/pen/dXWoRw
|
||||
@function escape-svg($string) {
|
||||
@if str-index($string, "data:image/svg+xml") {
|
||||
@each $char, $encoded in $escaped-characters {
|
||||
$string: str-replace($string, $char, $encoded);
|
||||
}
|
||||
}
|
||||
|
||||
@return $string;
|
||||
}
|
||||
|
||||
// Color contrast
|
||||
@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) {
|
||||
$r: red($color);
|
||||
$g: green($color);
|
||||
$b: blue($color);
|
||||
|
||||
$yiq: (($r * 299) + ($g * 587) + ($b * 114)) / 1000;
|
||||
|
||||
@if ($yiq >= $yiq-contrasted-threshold) {
|
||||
@return $dark;
|
||||
} @else {
|
||||
@return $light;
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve color Sass maps
|
||||
@function color($key: "blue") {
|
||||
@return map-get($colors, $key);
|
||||
}
|
||||
|
||||
@function theme-color($key: "primary") {
|
||||
@return map-get($theme-colors, $key);
|
||||
}
|
||||
|
||||
@function gray($key: "100") {
|
||||
@return map-get($grays, $key);
|
||||
}
|
||||
|
||||
// Request a theme color level
|
||||
@function theme-color-level($color-name: "primary", $level: 0) {
|
||||
$color: theme-color($color-name);
|
||||
$color-base: if($level > 0, $black, $white);
|
||||
$level: abs($level);
|
||||
|
||||
@return mix($color-base, $color, $level * $theme-color-interval);
|
||||
}
|
||||
|
||||
// Return valid calc
|
||||
@function add($value1, $value2, $return-calc: true) {
|
||||
@if $value1 == null {
|
||||
@return $value2;
|
||||
}
|
||||
|
||||
@if $value2 == null {
|
||||
@return $value1;
|
||||
}
|
||||
|
||||
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
|
||||
@return $value1 + $value2;
|
||||
}
|
||||
|
||||
@return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(" + ") + $value2);
|
||||
}
|
||||
|
||||
@function subtract($value1, $value2, $return-calc: true) {
|
||||
@if $value1 == null and $value2 == null {
|
||||
@return null;
|
||||
}
|
||||
|
||||
@if $value1 == null {
|
||||
@return -$value2;
|
||||
}
|
||||
|
||||
@if $value2 == null {
|
||||
@return $value1;
|
||||
}
|
||||
|
||||
@if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {
|
||||
@return $value1 - $value2;
|
||||
}
|
||||
|
||||
@return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(" - ") + $value2);
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
// Container widths
|
||||
//
|
||||
// Set the container width, and override it for fixed navbars in media queries.
|
||||
|
||||
@if $enable-grid-classes {
|
||||
// Single container class with breakpoint max-widths
|
||||
.container {
|
||||
@include make-container();
|
||||
@include make-container-max-widths();
|
||||
}
|
||||
|
||||
// 100% wide container at all breakpoints
|
||||
.container-fluid {
|
||||
@include make-container();
|
||||
}
|
||||
|
||||
// Responsive containers that are 100% wide until a breakpoint
|
||||
@each $breakpoint, $container-max-width in $container-max-widths {
|
||||
.container-#{$breakpoint} {
|
||||
@extend .container-fluid;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up($breakpoint, $grid-breakpoints) {
|
||||
%responsive-container-#{$breakpoint} {
|
||||
max-width: $container-max-width;
|
||||
}
|
||||
|
||||
@each $name, $width in $grid-breakpoints {
|
||||
@if ($container-max-width > $width or $breakpoint == $name) {
|
||||
.container#{breakpoint-infix($name, $grid-breakpoints)} {
|
||||
@extend %responsive-container-#{$breakpoint};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Row
|
||||
//
|
||||
// Rows contain your columns.
|
||||
|
||||
@if $enable-grid-classes {
|
||||
.row {
|
||||
@include make-row();
|
||||
}
|
||||
|
||||
// Remove the negative margin from default .row, then the horizontal padding
|
||||
// from all immediate children columns (to prevent runaway style inheritance).
|
||||
.no-gutters {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
|
||||
> .col,
|
||||
> [class*="col-"] {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Columns
|
||||
//
|
||||
// Common styles for small and large grid columns
|
||||
|
||||
@if $enable-grid-classes {
|
||||
@include make-grid-columns();
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
// Responsive images (ensure images don't scale beyond their parents)
|
||||
//
|
||||
// This is purposefully opt-in via an explicit class rather than being the default for all `<img>`s.
|
||||
// We previously tried the "images are responsive by default" approach in Bootstrap v2,
|
||||
// and abandoned it in Bootstrap v3 because it breaks lots of third-party widgets (including Google Maps)
|
||||
// which weren't expecting the images within themselves to be involuntarily resized.
|
||||
// See also https://github.com/twbs/bootstrap/issues/18178
|
||||
.img-fluid {
|
||||
@include img-fluid();
|
||||
}
|
||||
|
||||
|
||||
// Image thumbnails
|
||||
.img-thumbnail {
|
||||
padding: $thumbnail-padding;
|
||||
background-color: $thumbnail-bg;
|
||||
border: $thumbnail-border-width solid $thumbnail-border-color;
|
||||
@include border-radius($thumbnail-border-radius);
|
||||
@include box-shadow($thumbnail-box-shadow);
|
||||
|
||||
// Keep them at most 100% wide
|
||||
@include img-fluid();
|
||||
}
|
||||
|
||||
//
|
||||
// Figures
|
||||
//
|
||||
|
||||
.figure {
|
||||
// Ensures the caption's text aligns with the image.
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.figure-img {
|
||||
margin-bottom: $spacer / 2;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.figure-caption {
|
||||
@include font-size($figure-caption-font-size);
|
||||
color: $figure-caption-color;
|
||||
}
|
@ -1,191 +0,0 @@
|
||||
// stylelint-disable selector-no-qualifying-type
|
||||
|
||||
//
|
||||
// Base styles
|
||||
//
|
||||
|
||||
.input-group {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-wrap: wrap; // For form validation feedback
|
||||
align-items: stretch;
|
||||
width: 100%;
|
||||
|
||||
> .form-control,
|
||||
> .form-control-plaintext,
|
||||
> .custom-select,
|
||||
> .custom-file {
|
||||
position: relative; // For focus state's z-index
|
||||
flex: 1 1 0%;
|
||||
min-width: 0; // https://stackoverflow.com/questions/36247140/why-dont-flex-items-shrink-past-content-size
|
||||
margin-bottom: 0;
|
||||
|
||||
+ .form-control,
|
||||
+ .custom-select,
|
||||
+ .custom-file {
|
||||
margin-left: -$input-border-width;
|
||||
}
|
||||
}
|
||||
|
||||
// Bring the "active" form control to the top of surrounding elements
|
||||
> .form-control:focus,
|
||||
> .custom-select:focus,
|
||||
> .custom-file .custom-file-input:focus ~ .custom-file-label {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
// Bring the custom file input above the label
|
||||
> .custom-file .custom-file-input:focus {
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
> .form-control,
|
||||
> .custom-select {
|
||||
&:not(:last-child) { @include border-right-radius(0); }
|
||||
&:not(:first-child) { @include border-left-radius(0); }
|
||||
}
|
||||
|
||||
// Custom file inputs have more complex markup, thus requiring different
|
||||
// border-radius overrides.
|
||||
> .custom-file {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&:not(:last-child) .custom-file-label,
|
||||
&:not(:last-child) .custom-file-label::after { @include border-right-radius(0); }
|
||||
&:not(:first-child) .custom-file-label { @include border-left-radius(0); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Prepend and append
|
||||
//
|
||||
// While it requires one extra layer of HTML for each, dedicated prepend and
|
||||
// append elements allow us to 1) be less clever, 2) simplify our selectors, and
|
||||
// 3) support HTML5 form validation.
|
||||
|
||||
.input-group-prepend,
|
||||
.input-group-append {
|
||||
display: flex;
|
||||
|
||||
// Ensure buttons are always above inputs for more visually pleasing borders.
|
||||
// This isn't needed for `.input-group-text` since it shares the same border-color
|
||||
// as our inputs.
|
||||
.btn {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
&:focus {
|
||||
z-index: 3;
|
||||
}
|
||||
}
|
||||
|
||||
.btn + .btn,
|
||||
.btn + .input-group-text,
|
||||
.input-group-text + .input-group-text,
|
||||
.input-group-text + .btn {
|
||||
margin-left: -$input-border-width;
|
||||
}
|
||||
}
|
||||
|
||||
.input-group-prepend { margin-right: -$input-border-width; }
|
||||
.input-group-append { margin-left: -$input-border-width; }
|
||||
|
||||
|
||||
// Textual addons
|
||||
//
|
||||
// Serves as a catch-all element for any text or radio/checkbox input you wish
|
||||
// to prepend or append to an input.
|
||||
|
||||
.input-group-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: $input-padding-y $input-padding-x;
|
||||
margin-bottom: 0; // Allow use of <label> elements by overriding our default margin-bottom
|
||||
@include font-size($input-font-size); // Match inputs
|
||||
font-weight: $font-weight-normal;
|
||||
line-height: $input-line-height;
|
||||
color: $input-group-addon-color;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
background-color: $input-group-addon-bg;
|
||||
border: $input-border-width solid $input-group-addon-border-color;
|
||||
@include border-radius($input-border-radius);
|
||||
|
||||
// Nuke default margins from checkboxes and radios to vertically center within.
|
||||
input[type="radio"],
|
||||
input[type="checkbox"] {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Sizing
|
||||
//
|
||||
// Remix the default form control sizing classes into new ones for easier
|
||||
// manipulation.
|
||||
|
||||
.input-group-lg > .form-control:not(textarea),
|
||||
.input-group-lg > .custom-select {
|
||||
height: $input-height-lg;
|
||||
}
|
||||
|
||||
.input-group-lg > .form-control,
|
||||
.input-group-lg > .custom-select,
|
||||
.input-group-lg > .input-group-prepend > .input-group-text,
|
||||
.input-group-lg > .input-group-append > .input-group-text,
|
||||
.input-group-lg > .input-group-prepend > .btn,
|
||||
.input-group-lg > .input-group-append > .btn {
|
||||
padding: $input-padding-y-lg $input-padding-x-lg;
|
||||
@include font-size($input-font-size-lg);
|
||||
line-height: $input-line-height-lg;
|
||||
@include border-radius($input-border-radius-lg);
|
||||
}
|
||||
|
||||
.input-group-sm > .form-control:not(textarea),
|
||||
.input-group-sm > .custom-select {
|
||||
height: $input-height-sm;
|
||||
}
|
||||
|
||||
.input-group-sm > .form-control,
|
||||
.input-group-sm > .custom-select,
|
||||
.input-group-sm > .input-group-prepend > .input-group-text,
|
||||
.input-group-sm > .input-group-append > .input-group-text,
|
||||
.input-group-sm > .input-group-prepend > .btn,
|
||||
.input-group-sm > .input-group-append > .btn {
|
||||
padding: $input-padding-y-sm $input-padding-x-sm;
|
||||
@include font-size($input-font-size-sm);
|
||||
line-height: $input-line-height-sm;
|
||||
@include border-radius($input-border-radius-sm);
|
||||
}
|
||||
|
||||
.input-group-lg > .custom-select,
|
||||
.input-group-sm > .custom-select {
|
||||
padding-right: $custom-select-padding-x + $custom-select-indicator-padding;
|
||||
}
|
||||
|
||||
|
||||
// Prepend and append rounded corners
|
||||
//
|
||||
// These rulesets must come after the sizing ones to properly override sm and lg
|
||||
// border-radius values when extending. They're more specific than we'd like
|
||||
// with the `.input-group >` part, but without it, we cannot override the sizing.
|
||||
|
||||
|
||||
.input-group > .input-group-prepend > .btn,
|
||||
.input-group > .input-group-prepend > .input-group-text,
|
||||
.input-group > .input-group-append:not(:last-child) > .btn,
|
||||
.input-group > .input-group-append:not(:last-child) > .input-group-text,
|
||||
.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
|
||||
.input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {
|
||||
@include border-right-radius(0);
|
||||
}
|
||||
|
||||
.input-group > .input-group-append > .btn,
|
||||
.input-group > .input-group-append > .input-group-text,
|
||||
.input-group > .input-group-prepend:not(:first-child) > .btn,
|
||||
.input-group > .input-group-prepend:not(:first-child) > .input-group-text,
|
||||
.input-group > .input-group-prepend:first-child > .btn:not(:first-child),
|
||||
.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {
|
||||
@include border-left-radius(0);
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
.jumbotron {
|
||||
padding: $jumbotron-padding ($jumbotron-padding / 2);
|
||||
margin-bottom: $jumbotron-padding;
|
||||
color: $jumbotron-color;
|
||||
background-color: $jumbotron-bg;
|
||||
@include border-radius($border-radius-lg);
|
||||
|
||||
@include media-breakpoint-up(sm) {
|
||||
padding: ($jumbotron-padding * 2) $jumbotron-padding;
|
||||
}
|
||||
}
|
||||
|
||||
.jumbotron-fluid {
|
||||
padding-right: 0;
|
||||
padding-left: 0;
|
||||
@include border-radius(0);
|
||||
}
|
@ -1,158 +0,0 @@
|
||||
// Base class
|
||||
//
|
||||
// Easily usable on <ul>, <ol>, or <div>.
|
||||
|
||||
.list-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
// No need to set list-style: none; since .list-group-item is block level
|
||||
padding-left: 0; // reset padding because ul and ol
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
// Interactive list items
|
||||
//
|
||||
// Use anchor or button elements instead of `li`s or `div`s to create interactive
|
||||
// list items. Includes an extra `.active` modifier class for selected items.
|
||||
|
||||
.list-group-item-action {
|
||||
width: 100%; // For `<button>`s (anchors become 100% by default though)
|
||||
color: $list-group-action-color;
|
||||
text-align: inherit; // For `<button>`s (anchors inherit)
|
||||
|
||||
// Hover state
|
||||
@include hover-focus() {
|
||||
z-index: 1; // Place hover/focus items above their siblings for proper border styling
|
||||
color: $list-group-action-hover-color;
|
||||
text-decoration: none;
|
||||
background-color: $list-group-hover-bg;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: $list-group-action-active-color;
|
||||
background-color: $list-group-action-active-bg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Individual list items
|
||||
//
|
||||
// Use on `li`s or `div`s within the `.list-group` parent.
|
||||
|
||||
.list-group-item {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: $list-group-item-padding-y $list-group-item-padding-x;
|
||||
color: $list-group-color;
|
||||
background-color: $list-group-bg;
|
||||
border: $list-group-border-width solid $list-group-border-color;
|
||||
|
||||
&:first-child {
|
||||
@include border-top-radius($list-group-border-radius);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
@include border-bottom-radius($list-group-border-radius);
|
||||
}
|
||||
|
||||
&.disabled,
|
||||
&:disabled {
|
||||
color: $list-group-disabled-color;
|
||||
pointer-events: none;
|
||||
background-color: $list-group-disabled-bg;
|
||||
}
|
||||
|
||||
// Include both here for `<a>`s and `<button>`s
|
||||
&.active {
|
||||
z-index: 2; // Place active items above their siblings for proper border styling
|
||||
color: $list-group-active-color;
|
||||
background-color: $list-group-active-bg;
|
||||
border-color: $list-group-active-border-color;
|
||||
}
|
||||
|
||||
& + & {
|
||||
border-top-width: 0;
|
||||
|
||||
&.active {
|
||||
margin-top: -$list-group-border-width;
|
||||
border-top-width: $list-group-border-width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Horizontal
|
||||
//
|
||||
// Change the layout of list group items from vertical (default) to horizontal.
|
||||
|
||||
@each $breakpoint in map-keys($grid-breakpoints) {
|
||||
@include media-breakpoint-up($breakpoint) {
|
||||
$infix: breakpoint-infix($breakpoint, $grid-breakpoints);
|
||||
|
||||
.list-group-horizontal#{$infix} {
|
||||
flex-direction: row;
|
||||
|
||||
.list-group-item {
|
||||
&:first-child {
|
||||
@include border-bottom-left-radius($list-group-border-radius);
|
||||
@include border-top-right-radius(0);
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
@include border-top-right-radius($list-group-border-radius);
|
||||
@include border-bottom-left-radius(0);
|
||||
}
|
||||
|
||||
&.active {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
& + .list-group-item {
|
||||
border-top-width: $list-group-border-width;
|
||||
border-left-width: 0;
|
||||
|
||||
&.active {
|
||||
margin-left: -$list-group-border-width;
|
||||
border-left-width: $list-group-border-width;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Flush list items
|
||||
//
|
||||
// Remove borders and border-radius to keep list group items edge-to-edge. Most
|
||||
// useful within other components (e.g., cards).
|
||||
|
||||
.list-group-flush {
|
||||
.list-group-item {
|
||||
border-right-width: 0;
|
||||
border-left-width: 0;
|
||||
@include border-radius(0);
|
||||
|
||||
&:first-child {
|
||||
border-top-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
.list-group-item:last-child {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Contextual variants
|
||||
//
|
||||
// Add modifier classes to change text and background color on individual items.
|
||||
// Organizationally, this must come after the `:hover` states.
|
||||
|
||||
@each $color, $value in $theme-colors {
|
||||
@include list-group-item-variant($color, theme-color-level($color, -9), theme-color-level($color, 6));
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user