@usefidel/design-system 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fidel.manifest.json +2 -2
- package/dist/index.cjs +281 -2
- package/dist/index.css +543 -0
- package/dist/index.d.cts +127 -2
- package/dist/index.d.ts +127 -2
- package/dist/index.js +274 -1
- package/package.json +1 -1
package/dist/index.css
CHANGED
|
@@ -127,6 +127,44 @@
|
|
|
127
127
|
color: #a3a3a3;
|
|
128
128
|
cursor: not-allowed;
|
|
129
129
|
}
|
|
130
|
+
.fds-button--danger {
|
|
131
|
+
background-color: var(--color-error, #b91c1c);
|
|
132
|
+
color: #ffffff;
|
|
133
|
+
}
|
|
134
|
+
.fds-button--danger:hover:not(:disabled) {
|
|
135
|
+
background-color: var(--color-error-text, #991b1b);
|
|
136
|
+
}
|
|
137
|
+
.fds-button--danger:active:not(:disabled) {
|
|
138
|
+
background-color: #7f1d1d;
|
|
139
|
+
}
|
|
140
|
+
.fds-button--danger:focus-visible {
|
|
141
|
+
outline-color: var(--color-error, #b91c1c);
|
|
142
|
+
}
|
|
143
|
+
.fds-button--danger:disabled {
|
|
144
|
+
background-color: var(--color-error-bg, #fef2f2);
|
|
145
|
+
color: #f87171;
|
|
146
|
+
cursor: not-allowed;
|
|
147
|
+
}
|
|
148
|
+
.fds-button--danger-outlined {
|
|
149
|
+
background-color: #ffffff;
|
|
150
|
+
border-color: var(--color-error-border, #fecaca);
|
|
151
|
+
color: var(--color-error, #b91c1c);
|
|
152
|
+
}
|
|
153
|
+
.fds-button--danger-outlined:hover:not(:disabled) {
|
|
154
|
+
background-color: var(--color-error-bg, #fef2f2);
|
|
155
|
+
border-color: #fca5a5;
|
|
156
|
+
}
|
|
157
|
+
.fds-button--danger-outlined:active:not(:disabled) {
|
|
158
|
+
background-color: #fee2e2;
|
|
159
|
+
}
|
|
160
|
+
.fds-button--danger-outlined:focus-visible {
|
|
161
|
+
outline-color: var(--color-error, #b91c1c);
|
|
162
|
+
}
|
|
163
|
+
.fds-button--danger-outlined:disabled {
|
|
164
|
+
border-color: #e5e5e5;
|
|
165
|
+
color: #a3a3a3;
|
|
166
|
+
cursor: not-allowed;
|
|
167
|
+
}
|
|
130
168
|
.fds-button--neutral {
|
|
131
169
|
background-color: var(--color-surface-subtle, #fafafa);
|
|
132
170
|
color: var(--color-text-on-neutral, #404040);
|
|
@@ -778,3 +816,508 @@
|
|
|
778
816
|
line-height: var(--line-height-text-sm, 22px);
|
|
779
817
|
color: var(--color-text-secondary, #525252);
|
|
780
818
|
}
|
|
819
|
+
|
|
820
|
+
/* src/components/AppNav/app-nav.css */
|
|
821
|
+
.fds-app-nav {
|
|
822
|
+
display: flex;
|
|
823
|
+
align-items: center;
|
|
824
|
+
gap: var(--spacing-5, 20px);
|
|
825
|
+
height: 64px;
|
|
826
|
+
padding: 0 var(--spacing-5, 20px);
|
|
827
|
+
background: var(--color-surface, #f4f4f4);
|
|
828
|
+
border-bottom: 1px solid var(--color-border-light, #e5e5e5);
|
|
829
|
+
position: sticky;
|
|
830
|
+
top: 0;
|
|
831
|
+
z-index: 100;
|
|
832
|
+
}
|
|
833
|
+
.fds-app-nav__logo {
|
|
834
|
+
display: flex;
|
|
835
|
+
align-items: center;
|
|
836
|
+
flex-shrink: 0;
|
|
837
|
+
}
|
|
838
|
+
.fds-app-nav__links {
|
|
839
|
+
display: flex;
|
|
840
|
+
align-items: center;
|
|
841
|
+
gap: var(--spacing-2, 8px);
|
|
842
|
+
flex: 1;
|
|
843
|
+
min-width: 0;
|
|
844
|
+
}
|
|
845
|
+
.fds-app-nav__links > * {
|
|
846
|
+
position: relative;
|
|
847
|
+
display: flex;
|
|
848
|
+
align-items: center;
|
|
849
|
+
gap: var(--spacing-2, 8px);
|
|
850
|
+
flex-shrink: 0;
|
|
851
|
+
padding: 10px var(--spacing-3, 12px);
|
|
852
|
+
color: var(--color-text-muted, #a3a3a3);
|
|
853
|
+
font-family: var(--font-display, "Rethink Sans", system-ui, sans-serif);
|
|
854
|
+
font-size: 14px;
|
|
855
|
+
line-height: 20px;
|
|
856
|
+
font-weight: 600;
|
|
857
|
+
white-space: nowrap;
|
|
858
|
+
text-decoration: none;
|
|
859
|
+
transition: color var(--duration-quick, 150ms) var(--ease-out, ease);
|
|
860
|
+
}
|
|
861
|
+
.fds-app-nav__links > *:hover,
|
|
862
|
+
.fds-app-nav__links > [aria-current=page] {
|
|
863
|
+
color: var(--color-text, #171717);
|
|
864
|
+
}
|
|
865
|
+
.fds-app-nav__links > *:focus-visible {
|
|
866
|
+
outline: 2px solid var(--color-accent, #ea580c);
|
|
867
|
+
outline-offset: -2px;
|
|
868
|
+
border-radius: var(--radius-sm, 6px);
|
|
869
|
+
}
|
|
870
|
+
.fds-app-nav__links > [aria-current=page]::after {
|
|
871
|
+
content: "";
|
|
872
|
+
position: absolute;
|
|
873
|
+
left: var(--spacing-3, 12px);
|
|
874
|
+
right: var(--spacing-3, 12px);
|
|
875
|
+
bottom: 2px;
|
|
876
|
+
height: 2px;
|
|
877
|
+
border-radius: 2px;
|
|
878
|
+
background: var(--color-accent, #ea580c);
|
|
879
|
+
}
|
|
880
|
+
.fds-app-nav__actions {
|
|
881
|
+
display: flex;
|
|
882
|
+
align-items: center;
|
|
883
|
+
gap: var(--spacing-3, 12px);
|
|
884
|
+
margin-left: auto;
|
|
885
|
+
flex-shrink: 0;
|
|
886
|
+
}
|
|
887
|
+
.fds-app-nav__toggle {
|
|
888
|
+
display: none;
|
|
889
|
+
}
|
|
890
|
+
@media (max-width: 640px) {
|
|
891
|
+
.fds-app-nav {
|
|
892
|
+
gap: var(--spacing-2, 8px);
|
|
893
|
+
padding: 0 var(--spacing-3, 12px) 0 var(--spacing-4, 16px);
|
|
894
|
+
}
|
|
895
|
+
.fds-app-nav__toggle {
|
|
896
|
+
display: grid;
|
|
897
|
+
place-items: center;
|
|
898
|
+
flex-shrink: 0;
|
|
899
|
+
width: 40px;
|
|
900
|
+
height: 40px;
|
|
901
|
+
padding: 0;
|
|
902
|
+
border: none;
|
|
903
|
+
border-radius: var(--radius-md, 8px);
|
|
904
|
+
background: transparent;
|
|
905
|
+
color: var(--color-text, #171717);
|
|
906
|
+
cursor: pointer;
|
|
907
|
+
transition: background-color var(--duration-quick, 150ms) var(--ease-out, ease);
|
|
908
|
+
}
|
|
909
|
+
.fds-app-nav__toggle:hover,
|
|
910
|
+
.fds-app-nav__toggle[aria-expanded=true] {
|
|
911
|
+
background: var(--color-surface-hover, #ebebeb);
|
|
912
|
+
}
|
|
913
|
+
.fds-app-nav__toggle:focus-visible {
|
|
914
|
+
outline: 2px solid var(--color-accent, #ea580c);
|
|
915
|
+
outline-offset: 2px;
|
|
916
|
+
}
|
|
917
|
+
.fds-app-nav__links {
|
|
918
|
+
display: none;
|
|
919
|
+
position: absolute;
|
|
920
|
+
top: 100%;
|
|
921
|
+
left: 0;
|
|
922
|
+
right: 0;
|
|
923
|
+
flex-direction: column;
|
|
924
|
+
align-items: stretch;
|
|
925
|
+
gap: 0;
|
|
926
|
+
padding: var(--spacing-2, 8px);
|
|
927
|
+
background: var(--color-surface-raised, #ffffff);
|
|
928
|
+
border-bottom: 1px solid var(--color-border-light, #e5e5e5);
|
|
929
|
+
box-shadow: var(--shadow-lg, 0 16px 48px rgba(0, 0, 0, 0.12));
|
|
930
|
+
}
|
|
931
|
+
.fds-app-nav__links[data-open] {
|
|
932
|
+
display: flex;
|
|
933
|
+
animation: fds-app-nav-menu-in var(--duration-quick, 150ms) var(--ease-out, ease) both;
|
|
934
|
+
}
|
|
935
|
+
.fds-app-nav__links > * {
|
|
936
|
+
padding: 12px var(--spacing-3, 12px);
|
|
937
|
+
border-radius: var(--radius-md, 8px);
|
|
938
|
+
font-size: 15px;
|
|
939
|
+
line-height: 22px;
|
|
940
|
+
color: var(--color-text-secondary, #525252);
|
|
941
|
+
}
|
|
942
|
+
.fds-app-nav__links > *:hover {
|
|
943
|
+
background: var(--color-surface, #f4f4f4);
|
|
944
|
+
}
|
|
945
|
+
.fds-app-nav__links > [aria-current=page] {
|
|
946
|
+
color: var(--color-text, #171717);
|
|
947
|
+
background: var(--color-surface, #f4f4f4);
|
|
948
|
+
}
|
|
949
|
+
.fds-app-nav__links > [aria-current=page]::after {
|
|
950
|
+
display: none;
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
@keyframes fds-app-nav-menu-in {
|
|
954
|
+
from {
|
|
955
|
+
opacity: 0;
|
|
956
|
+
transform: translateY(-4px);
|
|
957
|
+
}
|
|
958
|
+
to {
|
|
959
|
+
opacity: 1;
|
|
960
|
+
transform: translateY(0);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
@media (prefers-reduced-motion: reduce) {
|
|
964
|
+
.fds-app-nav__links[data-open] {
|
|
965
|
+
animation: none;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
/* src/components/TabNav/tab-nav.css */
|
|
970
|
+
.fds-tab-nav {
|
|
971
|
+
display: flex;
|
|
972
|
+
align-items: stretch;
|
|
973
|
+
gap: var(--spacing-1, 4px);
|
|
974
|
+
overflow-x: auto;
|
|
975
|
+
scrollbar-width: none;
|
|
976
|
+
box-shadow: inset 0 -1px 0 var(--color-border-light, #e5e5e5);
|
|
977
|
+
}
|
|
978
|
+
.fds-tab-nav::-webkit-scrollbar {
|
|
979
|
+
display: none;
|
|
980
|
+
}
|
|
981
|
+
.fds-tab-nav > * {
|
|
982
|
+
position: relative;
|
|
983
|
+
flex-shrink: 0;
|
|
984
|
+
padding: 10px 14px;
|
|
985
|
+
font-family: var(--font-display, "Rethink Sans", system-ui, sans-serif);
|
|
986
|
+
font-size: 13px;
|
|
987
|
+
font-weight: 500;
|
|
988
|
+
line-height: 20px;
|
|
989
|
+
white-space: nowrap;
|
|
990
|
+
color: var(--color-text-muted, #a3a3a3);
|
|
991
|
+
background: transparent;
|
|
992
|
+
text-decoration: none;
|
|
993
|
+
transition: color var(--duration-quick, 150ms) var(--ease-out, ease);
|
|
994
|
+
}
|
|
995
|
+
.fds-tab-nav > *:hover {
|
|
996
|
+
color: var(--color-text, #171717);
|
|
997
|
+
}
|
|
998
|
+
.fds-tab-nav > *:focus-visible {
|
|
999
|
+
outline: 2px solid var(--color-accent, #ea580c);
|
|
1000
|
+
outline-offset: -2px;
|
|
1001
|
+
border-radius: var(--radius-xs, 4px);
|
|
1002
|
+
}
|
|
1003
|
+
.fds-tab-nav > [aria-current=page] {
|
|
1004
|
+
color: var(--color-text, #171717);
|
|
1005
|
+
font-weight: 600;
|
|
1006
|
+
}
|
|
1007
|
+
.fds-tab-nav > [aria-current=page]::after {
|
|
1008
|
+
content: "";
|
|
1009
|
+
position: absolute;
|
|
1010
|
+
left: var(--spacing-2, 8px);
|
|
1011
|
+
right: var(--spacing-2, 8px);
|
|
1012
|
+
bottom: 0;
|
|
1013
|
+
height: 2px;
|
|
1014
|
+
border-radius: 1px 1px 0 0;
|
|
1015
|
+
background: var(--color-accent, #ea580c);
|
|
1016
|
+
}
|
|
1017
|
+
@media (max-width: 640px) {
|
|
1018
|
+
.fds-tab-nav {
|
|
1019
|
+
-webkit-mask-image:
|
|
1020
|
+
linear-gradient(
|
|
1021
|
+
to right,
|
|
1022
|
+
#000 calc(100% - 24px),
|
|
1023
|
+
transparent);
|
|
1024
|
+
mask-image:
|
|
1025
|
+
linear-gradient(
|
|
1026
|
+
to right,
|
|
1027
|
+
#000 calc(100% - 24px),
|
|
1028
|
+
transparent);
|
|
1029
|
+
padding-right: 24px;
|
|
1030
|
+
}
|
|
1031
|
+
.fds-tab-nav > * {
|
|
1032
|
+
padding: 10px var(--spacing-3, 12px);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
/* src/components/SettingsSection/settings-section.css */
|
|
1037
|
+
.fds-settings-section {
|
|
1038
|
+
display: grid;
|
|
1039
|
+
grid-template-columns: 280px minmax(0, 1fr);
|
|
1040
|
+
gap: var(--spacing-12, 48px);
|
|
1041
|
+
align-items: start;
|
|
1042
|
+
padding: var(--spacing-8, 32px) 0;
|
|
1043
|
+
border-bottom: 1px solid var(--color-border-light, #e5e5e5);
|
|
1044
|
+
}
|
|
1045
|
+
.fds-settings-section:first-child {
|
|
1046
|
+
padding-top: 0;
|
|
1047
|
+
}
|
|
1048
|
+
.fds-settings-section:last-child {
|
|
1049
|
+
border-bottom: none;
|
|
1050
|
+
}
|
|
1051
|
+
.fds-settings-section__head {
|
|
1052
|
+
position: sticky;
|
|
1053
|
+
top: var(--spacing-6, 24px);
|
|
1054
|
+
}
|
|
1055
|
+
.fds-settings-section__title {
|
|
1056
|
+
margin: 0 0 var(--spacing-2, 8px);
|
|
1057
|
+
font-family: var(--font-display, "Rethink Sans", system-ui, sans-serif);
|
|
1058
|
+
font-size: 14.5px;
|
|
1059
|
+
font-weight: 600;
|
|
1060
|
+
letter-spacing: -0.005em;
|
|
1061
|
+
color: var(--color-text, #171717);
|
|
1062
|
+
}
|
|
1063
|
+
.fds-settings-section__description {
|
|
1064
|
+
margin: 0;
|
|
1065
|
+
max-width: 32ch;
|
|
1066
|
+
font-size: 12.5px;
|
|
1067
|
+
line-height: 1.55;
|
|
1068
|
+
color: var(--color-text-muted, #a3a3a3);
|
|
1069
|
+
}
|
|
1070
|
+
.fds-settings-section__body {
|
|
1071
|
+
display: flex;
|
|
1072
|
+
flex-direction: column;
|
|
1073
|
+
gap: var(--spacing-4, 16px);
|
|
1074
|
+
min-width: 0;
|
|
1075
|
+
}
|
|
1076
|
+
@media (max-width: 900px) {
|
|
1077
|
+
.fds-settings-section {
|
|
1078
|
+
grid-template-columns: minmax(0, 1fr);
|
|
1079
|
+
gap: var(--spacing-4, 16px);
|
|
1080
|
+
padding: var(--spacing-6, 24px) 0;
|
|
1081
|
+
}
|
|
1082
|
+
.fds-settings-section__head {
|
|
1083
|
+
position: static;
|
|
1084
|
+
}
|
|
1085
|
+
.fds-settings-section__description {
|
|
1086
|
+
max-width: none;
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/* src/components/Modal/modal.css */
|
|
1091
|
+
.fds-modal__scrim {
|
|
1092
|
+
position: fixed;
|
|
1093
|
+
inset: 0;
|
|
1094
|
+
z-index: 1000;
|
|
1095
|
+
display: grid;
|
|
1096
|
+
grid-template-columns: minmax(0, 1fr);
|
|
1097
|
+
place-items: center;
|
|
1098
|
+
padding: var(--spacing-6, 24px);
|
|
1099
|
+
background: rgba(10, 10, 10, 0.42);
|
|
1100
|
+
animation: fds-modal-scrim-in var(--duration-moderate, 200ms) var(--ease-out, ease) both;
|
|
1101
|
+
}
|
|
1102
|
+
.fds-modal {
|
|
1103
|
+
box-sizing: border-box;
|
|
1104
|
+
position: relative;
|
|
1105
|
+
width: 100%;
|
|
1106
|
+
max-height: calc(100dvh - 2 * var(--spacing-6, 24px));
|
|
1107
|
+
overflow-y: auto;
|
|
1108
|
+
padding: var(--spacing-8, 32px) var(--spacing-8, 32px) var(--spacing-6, 24px);
|
|
1109
|
+
background: var(--color-surface-raised, #ffffff);
|
|
1110
|
+
border: 1px solid var(--color-border, #e5e5e5);
|
|
1111
|
+
border-radius: var(--radius-xl, 16px);
|
|
1112
|
+
box-shadow: var(--shadow-lg, 0 16px 48px rgba(0, 0, 0, 0.12));
|
|
1113
|
+
animation: fds-modal-in var(--duration-slow, 300ms) var(--ease-out, ease) both;
|
|
1114
|
+
}
|
|
1115
|
+
.fds-modal:focus {
|
|
1116
|
+
outline: none;
|
|
1117
|
+
}
|
|
1118
|
+
.fds-modal--small {
|
|
1119
|
+
max-width: 420px;
|
|
1120
|
+
}
|
|
1121
|
+
.fds-modal--medium {
|
|
1122
|
+
max-width: 560px;
|
|
1123
|
+
}
|
|
1124
|
+
.fds-modal__close {
|
|
1125
|
+
position: absolute;
|
|
1126
|
+
top: var(--spacing-4, 16px);
|
|
1127
|
+
right: var(--spacing-4, 16px);
|
|
1128
|
+
display: grid;
|
|
1129
|
+
place-items: center;
|
|
1130
|
+
width: 32px;
|
|
1131
|
+
height: 32px;
|
|
1132
|
+
padding: 0;
|
|
1133
|
+
border: none;
|
|
1134
|
+
border-radius: var(--radius-md, 8px);
|
|
1135
|
+
background: transparent;
|
|
1136
|
+
color: var(--color-text-muted, #a3a3a3);
|
|
1137
|
+
cursor: pointer;
|
|
1138
|
+
transition: color var(--duration-quick, 150ms) var(--ease-out, ease), background-color var(--duration-quick, 150ms) var(--ease-out, ease);
|
|
1139
|
+
}
|
|
1140
|
+
.fds-modal__close:hover:not(:disabled) {
|
|
1141
|
+
color: var(--color-text, #171717);
|
|
1142
|
+
background: var(--color-surface, #f4f4f4);
|
|
1143
|
+
}
|
|
1144
|
+
.fds-modal__close:focus-visible {
|
|
1145
|
+
outline: 2px solid var(--color-accent, #ea580c);
|
|
1146
|
+
outline-offset: 2px;
|
|
1147
|
+
}
|
|
1148
|
+
.fds-modal__close:disabled {
|
|
1149
|
+
cursor: not-allowed;
|
|
1150
|
+
opacity: 0.4;
|
|
1151
|
+
}
|
|
1152
|
+
.fds-modal__icon {
|
|
1153
|
+
display: grid;
|
|
1154
|
+
place-items: center;
|
|
1155
|
+
width: 40px;
|
|
1156
|
+
height: 40px;
|
|
1157
|
+
margin-bottom: var(--spacing-4, 16px);
|
|
1158
|
+
border-radius: var(--radius-full, 9999px);
|
|
1159
|
+
background: var(--color-error-bg, #fef2f2);
|
|
1160
|
+
color: var(--color-error, #b91c1c);
|
|
1161
|
+
}
|
|
1162
|
+
.fds-modal__title {
|
|
1163
|
+
margin: 0 var(--spacing-8, 32px) var(--spacing-3, 12px) 0;
|
|
1164
|
+
font-family: var(--font-display, "Rethink Sans", system-ui, sans-serif);
|
|
1165
|
+
font-size: 20px;
|
|
1166
|
+
font-weight: 600;
|
|
1167
|
+
line-height: 1.25;
|
|
1168
|
+
letter-spacing: -0.015em;
|
|
1169
|
+
color: var(--color-text, #171717);
|
|
1170
|
+
}
|
|
1171
|
+
.fds-modal__description {
|
|
1172
|
+
margin: 0 0 var(--spacing-5, 20px);
|
|
1173
|
+
font-size: 13.5px;
|
|
1174
|
+
line-height: 1.55;
|
|
1175
|
+
color: var(--color-text-secondary, #525252);
|
|
1176
|
+
}
|
|
1177
|
+
.fds-modal__content {
|
|
1178
|
+
margin-bottom: var(--spacing-5, 20px);
|
|
1179
|
+
font-size: 13.5px;
|
|
1180
|
+
line-height: 1.55;
|
|
1181
|
+
color: var(--color-text-secondary, #525252);
|
|
1182
|
+
}
|
|
1183
|
+
.fds-modal__actions {
|
|
1184
|
+
display: flex;
|
|
1185
|
+
justify-content: flex-end;
|
|
1186
|
+
gap: var(--spacing-2, 8px);
|
|
1187
|
+
}
|
|
1188
|
+
@keyframes fds-modal-scrim-in {
|
|
1189
|
+
from {
|
|
1190
|
+
opacity: 0;
|
|
1191
|
+
}
|
|
1192
|
+
to {
|
|
1193
|
+
opacity: 1;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
@keyframes fds-modal-in {
|
|
1197
|
+
from {
|
|
1198
|
+
opacity: 0;
|
|
1199
|
+
transform: translateY(8px);
|
|
1200
|
+
}
|
|
1201
|
+
to {
|
|
1202
|
+
opacity: 1;
|
|
1203
|
+
transform: translateY(0);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
@media (prefers-reduced-motion: reduce) {
|
|
1207
|
+
.fds-modal__scrim,
|
|
1208
|
+
.fds-modal {
|
|
1209
|
+
animation: none;
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
@media (max-width: 480px) {
|
|
1213
|
+
.fds-modal__scrim {
|
|
1214
|
+
padding: var(--spacing-4, 16px);
|
|
1215
|
+
}
|
|
1216
|
+
.fds-modal {
|
|
1217
|
+
max-height: calc(100dvh - 2 * var(--spacing-4, 16px));
|
|
1218
|
+
padding: var(--spacing-6, 24px) var(--spacing-5, 20px) var(--spacing-5, 20px);
|
|
1219
|
+
}
|
|
1220
|
+
.fds-modal__actions {
|
|
1221
|
+
flex-direction: column-reverse;
|
|
1222
|
+
}
|
|
1223
|
+
.fds-modal__actions > * {
|
|
1224
|
+
box-sizing: border-box;
|
|
1225
|
+
width: 100%;
|
|
1226
|
+
}
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
/* src/components/SegmentedControl/segmented-control.css */
|
|
1230
|
+
.fds-segmented {
|
|
1231
|
+
box-sizing: border-box;
|
|
1232
|
+
display: flex;
|
|
1233
|
+
max-width: 100%;
|
|
1234
|
+
gap: var(--spacing-1, 4px);
|
|
1235
|
+
overflow-x: auto;
|
|
1236
|
+
scrollbar-width: none;
|
|
1237
|
+
box-shadow: inset 0 -1px 0 var(--color-border-light, #e5e5e5);
|
|
1238
|
+
}
|
|
1239
|
+
.fds-segmented::-webkit-scrollbar {
|
|
1240
|
+
display: none;
|
|
1241
|
+
}
|
|
1242
|
+
.fds-segmented__option {
|
|
1243
|
+
position: relative;
|
|
1244
|
+
display: inline-flex;
|
|
1245
|
+
align-items: center;
|
|
1246
|
+
gap: 6px;
|
|
1247
|
+
flex-shrink: 0;
|
|
1248
|
+
padding: 10px;
|
|
1249
|
+
border: none;
|
|
1250
|
+
background: transparent;
|
|
1251
|
+
color: var(--color-text-muted, #a3a3a3);
|
|
1252
|
+
font-family: var(--font-body, "Rethink Sans", system-ui, sans-serif);
|
|
1253
|
+
font-size: 13px;
|
|
1254
|
+
font-weight: 500;
|
|
1255
|
+
line-height: 20px;
|
|
1256
|
+
white-space: nowrap;
|
|
1257
|
+
cursor: pointer;
|
|
1258
|
+
transition: color var(--duration-quick, 150ms) var(--ease-out, ease);
|
|
1259
|
+
}
|
|
1260
|
+
.fds-segmented__option:hover:not(:disabled) {
|
|
1261
|
+
color: var(--color-text, #171717);
|
|
1262
|
+
}
|
|
1263
|
+
.fds-segmented__option:focus-visible {
|
|
1264
|
+
outline: 2px solid var(--color-accent, #ea580c);
|
|
1265
|
+
outline-offset: -2px;
|
|
1266
|
+
border-radius: var(--radius-xs, 4px);
|
|
1267
|
+
}
|
|
1268
|
+
.fds-segmented__option[aria-selected=true] {
|
|
1269
|
+
color: var(--color-text, #171717);
|
|
1270
|
+
font-weight: 600;
|
|
1271
|
+
}
|
|
1272
|
+
.fds-segmented__option[aria-selected=true]::after {
|
|
1273
|
+
content: "";
|
|
1274
|
+
position: absolute;
|
|
1275
|
+
left: var(--spacing-2, 8px);
|
|
1276
|
+
right: var(--spacing-2, 8px);
|
|
1277
|
+
bottom: 0;
|
|
1278
|
+
height: 2px;
|
|
1279
|
+
border-radius: 1px 1px 0 0;
|
|
1280
|
+
background: var(--color-text, #171717);
|
|
1281
|
+
}
|
|
1282
|
+
.fds-segmented__option:disabled {
|
|
1283
|
+
color: #d4d4d4;
|
|
1284
|
+
cursor: not-allowed;
|
|
1285
|
+
}
|
|
1286
|
+
.fds-segmented__count {
|
|
1287
|
+
box-sizing: border-box;
|
|
1288
|
+
display: inline-grid;
|
|
1289
|
+
place-items: center;
|
|
1290
|
+
min-width: 20px;
|
|
1291
|
+
height: 20px;
|
|
1292
|
+
padding: 0 6px;
|
|
1293
|
+
border-radius: var(--radius-full, 9999px);
|
|
1294
|
+
background: var(--color-accent-subtle, #ffedd5);
|
|
1295
|
+
color: var(--color-accent-text, #c2410c);
|
|
1296
|
+
font-size: 11px;
|
|
1297
|
+
font-weight: 600;
|
|
1298
|
+
line-height: 1;
|
|
1299
|
+
font-variant-numeric: tabular-nums;
|
|
1300
|
+
}
|
|
1301
|
+
.fds-segmented__option[aria-selected=true] .fds-segmented__count {
|
|
1302
|
+
background: var(--color-accent, #ea580c);
|
|
1303
|
+
color: #ffffff;
|
|
1304
|
+
}
|
|
1305
|
+
.fds-segmented__option:disabled .fds-segmented__count {
|
|
1306
|
+
background: #f5f5f5;
|
|
1307
|
+
color: #a3a3a3;
|
|
1308
|
+
}
|
|
1309
|
+
@media (max-width: 640px) {
|
|
1310
|
+
.fds-segmented {
|
|
1311
|
+
padding-right: 24px;
|
|
1312
|
+
-webkit-mask-image:
|
|
1313
|
+
linear-gradient(
|
|
1314
|
+
to right,
|
|
1315
|
+
#000 calc(100% - 24px),
|
|
1316
|
+
transparent);
|
|
1317
|
+
mask-image:
|
|
1318
|
+
linear-gradient(
|
|
1319
|
+
to right,
|
|
1320
|
+
#000 calc(100% - 24px),
|
|
1321
|
+
transparent);
|
|
1322
|
+
}
|
|
1323
|
+
}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ButtonHTMLAttributes, ReactNode, HTMLAttributes, InputHTMLAttributes } from 'react';
|
|
3
3
|
|
|
4
|
-
type ButtonVariant = 'primary' | 'outlined' | 'text' | 'neutral' | 'link'
|
|
4
|
+
type ButtonVariant = 'primary' | 'outlined' | 'text' | 'neutral' | 'link'
|
|
5
|
+
/** Final confirm of a destructive action ("Delete my account"). */
|
|
6
|
+
| 'danger'
|
|
7
|
+
/** Starts a destructive action ("Delete account", "Remove"). */
|
|
8
|
+
| 'danger-outlined';
|
|
5
9
|
type ButtonSize = 'x-small' | 'small' | 'medium' | 'big';
|
|
6
10
|
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
|
|
7
11
|
/** Visual style. @default 'primary' */
|
|
@@ -248,4 +252,125 @@ interface ToggleProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'
|
|
|
248
252
|
*/
|
|
249
253
|
declare const Toggle: react.ForwardRefExoticComponent<ToggleProps & react.RefAttributes<HTMLInputElement>>;
|
|
250
254
|
|
|
251
|
-
|
|
255
|
+
interface AppNavProps extends HTMLAttributes<HTMLElement> {
|
|
256
|
+
/** Brand mark, usually a link home. */
|
|
257
|
+
logo: ReactNode;
|
|
258
|
+
/** Right-hand area (account menu, admin tools). Never shrinks. */
|
|
259
|
+
actions?: ReactNode;
|
|
260
|
+
/**
|
|
261
|
+
* The nav links (`<a>` or a router link). Mark the current page with
|
|
262
|
+
* `aria-current="page"`; React Router's `NavLink` does this itself.
|
|
263
|
+
*/
|
|
264
|
+
children?: ReactNode;
|
|
265
|
+
/** Accessible label for the mobile menu button. @default 'Menu' */
|
|
266
|
+
menuLabel?: string;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Fidel design-system app navigation bar. Router-agnostic: it styles whatever
|
|
270
|
+
* links it is given. Below 640px the links move into a menu opened from a
|
|
271
|
+
* button at the right of the bar; picking a link, Escape, or a tap outside
|
|
272
|
+
* closes it.
|
|
273
|
+
*/
|
|
274
|
+
declare function AppNav({ logo, actions, children, menuLabel, className, ...rest }: AppNavProps): react.JSX.Element;
|
|
275
|
+
|
|
276
|
+
interface TabNavProps extends HTMLAttributes<HTMLElement> {
|
|
277
|
+
/**
|
|
278
|
+
* The tab links (`<a>` or a router link). Mark the current tab with
|
|
279
|
+
* `aria-current="page"`; React Router's `NavLink` does this itself.
|
|
280
|
+
*/
|
|
281
|
+
children: ReactNode;
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Fidel design-system tab navigation: a row of page-level links with an
|
|
285
|
+
* underline on the current one. Labels never wrap; when the row is wider than
|
|
286
|
+
* its container it scrolls sideways. Give it an `aria-label`.
|
|
287
|
+
*/
|
|
288
|
+
declare function TabNav({ children, className, ...rest }: TabNavProps): react.JSX.Element;
|
|
289
|
+
|
|
290
|
+
interface SettingsSectionProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
|
|
291
|
+
/** Section heading, rendered as an `h2`. */
|
|
292
|
+
title: ReactNode;
|
|
293
|
+
/** Short muted line under the heading. */
|
|
294
|
+
description?: ReactNode;
|
|
295
|
+
/** The section's controls and content. */
|
|
296
|
+
children?: ReactNode;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Fidel design-system settings section: heading and description on the left,
|
|
300
|
+
* content on the right, divided from the next section by a hairline. Stacks
|
|
301
|
+
* into one column below 900px.
|
|
302
|
+
*/
|
|
303
|
+
declare function SettingsSection({ title, description, children, className, ...rest }: SettingsSectionProps): react.JSX.Element;
|
|
304
|
+
|
|
305
|
+
type ModalSize = 'small' | 'medium';
|
|
306
|
+
type ModalTone = 'default' | 'danger';
|
|
307
|
+
interface ModalProps {
|
|
308
|
+
/** Whether the dialog is shown. */
|
|
309
|
+
open: boolean;
|
|
310
|
+
/** Called on Escape, the close button, or a click outside the dialog. */
|
|
311
|
+
onClose: () => void;
|
|
312
|
+
/** Dialog heading; also its accessible name. */
|
|
313
|
+
title: ReactNode;
|
|
314
|
+
/** Muted line under the heading; also its accessible description. */
|
|
315
|
+
description?: ReactNode;
|
|
316
|
+
/** Body content. */
|
|
317
|
+
children?: ReactNode;
|
|
318
|
+
/** Footer buttons, primary action last. Stacked full width on phones. */
|
|
319
|
+
actions?: ReactNode;
|
|
320
|
+
/** Width step: small 420px, medium 560px. @default 'small' */
|
|
321
|
+
size?: ModalSize;
|
|
322
|
+
/** False blocks every way of closing, e.g. while an action is in flight. @default true */
|
|
323
|
+
dismissible?: boolean;
|
|
324
|
+
/** 'danger' marks a destructive confirm with a warning icon; pair it with a `danger` Button. @default 'default' */
|
|
325
|
+
tone?: ModalTone;
|
|
326
|
+
className?: string;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Fidel design-system Modal. Portalled to `document.body`; traps focus, locks
|
|
330
|
+
* page scroll, closes on Escape or a click outside, and returns focus to where
|
|
331
|
+
* it was. Focus starts on the element marked `data-autofocus`, else the first
|
|
332
|
+
* focusable element.
|
|
333
|
+
*/
|
|
334
|
+
declare function Modal({ open, onClose, title, description, children, actions, size, dismissible, tone, className, }: ModalProps): react.ReactPortal | null;
|
|
335
|
+
|
|
336
|
+
interface SegmentedOption<T extends string> {
|
|
337
|
+
value: T;
|
|
338
|
+
label: ReactNode;
|
|
339
|
+
/** Optional number shown after the label, e.g. issues in a severity. */
|
|
340
|
+
count?: number;
|
|
341
|
+
/** Id of the panel this option shows, for `aria-controls`. */
|
|
342
|
+
controls?: string;
|
|
343
|
+
disabled?: boolean;
|
|
344
|
+
}
|
|
345
|
+
interface SegmentedControlProps<T extends string> {
|
|
346
|
+
options: SegmentedOption<T>[];
|
|
347
|
+
value: T;
|
|
348
|
+
onChange: (value: T) => void;
|
|
349
|
+
/** Names the group for screen readers. */
|
|
350
|
+
'aria-label': string;
|
|
351
|
+
className?: string;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Fidel design-system segmented control: pick one of a few options (a mode,
|
|
355
|
+
* a filter). Tabs semantics with a roving tabindex: Arrow keys, Home and End
|
|
356
|
+
* move and select; Tab leaves the group. When the options don't fit, the row
|
|
357
|
+
* scrolls sideways instead of widening the page.
|
|
358
|
+
*/
|
|
359
|
+
declare function SegmentedControl<T extends string>({ options, value, onChange, 'aria-label': ariaLabel, className, }: SegmentedControlProps<T>): react.JSX.Element;
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Layout breakpoints, in px, used as `max-width` media queries.
|
|
363
|
+
* CSS custom properties can't be read inside `@media`, so component CSS and
|
|
364
|
+
* consumers write these same numbers literally: `@media (max-width: 640px)`.
|
|
365
|
+
*/
|
|
366
|
+
declare const breakpoints: {
|
|
367
|
+
/** Phones. */
|
|
368
|
+
readonly sm: 480;
|
|
369
|
+
/** Large phones, small tablets. */
|
|
370
|
+
readonly md: 640;
|
|
371
|
+
/** Tablets, narrow windows. */
|
|
372
|
+
readonly lg: 900;
|
|
373
|
+
};
|
|
374
|
+
type Breakpoint = keyof typeof breakpoints;
|
|
375
|
+
|
|
376
|
+
export { AppNav, type AppNavProps, type Breakpoint, Button, type ButtonProps, type ButtonSize, type ButtonVariant, type DiffElement, type DiffPropertyLine, DiffPropertyList, type DiffPropertyListProps, DiffSection, type DiffSectionProps, MismatchCard, type MismatchCardProps, type MismatchProperty, Modal, type ModalProps, type ModalSize, type ModalTone, SegmentedControl, type SegmentedControlProps, type SegmentedOption, Select, type SelectOption, type SelectProps, SettingsSection, type SettingsSectionProps, TabNav, type TabNavProps, Toggle, type ToggleProps, type ToggleSize, breakpoints };
|