Skip to content

Commit 28dfde7

Browse files
committed
fixes
1 parent 51e6097 commit 28dfde7

File tree

11 files changed

+166
-128
lines changed

11 files changed

+166
-128
lines changed

web/src/components/Docs/ReferencedBy.tsx

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,31 @@ import { KindIcon } from "./utils/components";
77
const COLLAPSE_THRESHOLD = 8;
88

99
const Wrapper = styled.div`
10-
padding: 8px 12px;
11-
border-top: 1px solid ${(props) => props.theme.groupBorder};
10+
padding: 10px 14px;
11+
border-top: 1px solid ${(props) => props.theme.groupSeparator};
1212
`;
1313

1414
const Title = styled.div`
15-
font-size: 12px;
15+
font-size: 14px;
1616
font-weight: 600;
1717
text-transform: uppercase;
1818
letter-spacing: 0.04em;
1919
color: ${(props) => props.theme.textDim};
20-
margin-bottom: 4px;
20+
margin-bottom: 6px;
2121
`;
2222

2323
const RefList = styled.div`
2424
display: flex;
2525
flex-wrap: wrap;
26-
gap: 4px;
26+
gap: 5px;
2727
`;
2828

2929
const RefLink = styled(Link)`
3030
display: inline-flex;
3131
align-items: center;
32-
gap: 3px;
33-
padding: 2px 8px;
34-
border-radius: 4px;
32+
gap: 4px;
33+
padding: 3px 10px;
34+
border-radius: 6px;
3535
font-size: 14px;
3636
text-decoration: none;
3737
color: ${(props) => props.theme.text};
@@ -56,7 +56,7 @@ const ToggleButton = styled.button`
5656
background: none;
5757
border: none;
5858
color: ${(props) => props.theme.textDim};
59-
font-size: 12px;
59+
font-size: 14px;
6060
cursor: pointer;
6161
padding: 2px 4px;
6262

web/src/components/Docs/SchemaClass.tsx

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import React, { useContext } from "react";
1+
import React, { useContext, useMemo } from "react";
2+
import { Link } from "react-router-dom";
23
import styled from "styled-components";
34
import * as api from "./api";
45
import { SchemaTypeView, MetadataTags } from "./SchemaType";
56
import { ReferencedBy } from "./ReferencedBy";
67
import { KindIcon } from "./utils/components";
78
import { DeclarationsContext } from "./DeclarationsContext";
9+
import { useSearchWords } from "./utils/filtering";
810
import {
911
CommonGroupMembers,
1012
CommonGroupSignature,
@@ -14,7 +16,7 @@ import {
1416
} from "./utils/styles";
1517

1618
const ClassExtendsWrapper = styled.span`
17-
font-size: 14px;
19+
font-size: 16px;
1820
font-weight: normal;
1921
color: ${(props) => props.theme.textDim};
2022
@@ -24,23 +26,33 @@ const ClassExtendsWrapper = styled.span`
2426
`;
2527

2628
const ClassMembers = styled(CommonGroupMembers)`
27-
padding: 6px 10px 6px 12px;
28-
2929
> :not(:last-child) {
3030
margin-bottom: 6px;
3131
}
3232
`;
3333

34-
const FieldRow = styled.div`
35-
padding: 5px 8px;
36-
background-color: ${(props) => props.theme.group};
34+
const FieldRow = styled.div<{ $highlighted?: boolean }>`
35+
padding: 6px 10px;
36+
background-color: ${(props) => props.$highlighted ? props.theme.searchHighlight : props.theme.group};
3737
border: 1px solid ${(props) => props.theme.groupBorder};
38-
border-radius: 6px;
38+
border-radius: 8px;
3939
`;
4040

4141
const FieldSignature = styled.div`
4242
font-weight: 600;
43+
font-size: 16px;
44+
`;
45+
46+
const CollapsedFieldsLink = styled(Link)`
47+
display: block;
48+
padding: 4px 8px;
4349
font-size: 14px;
50+
color: ${(props) => props.theme.textDim};
51+
text-decoration: none;
52+
53+
&:hover {
54+
text-decoration: underline;
55+
}
4456
`;
4557

4658
export const ModuleBadge: React.FC<{ module: string }> = ({ module }) => (
@@ -53,18 +65,36 @@ const StyledModuleBadge = styled.span`
5365
color: ${(props) => props.theme.textDim};
5466
background-color: ${(props) => props.theme.groupMembers};
5567
border: 1px solid ${(props) => props.theme.groupBorder};
56-
padding: 1px 6px;
57-
border-radius: 4px;
68+
padding: 2px 8px;
69+
border-radius: 6px;
5870
margin-left: 8px;
5971
vertical-align: middle;
6072
`;
6173

74+
export function matchesWords(name: string, words: string[]): boolean {
75+
const lower = name.toLowerCase();
76+
return words.every((w) => lower.includes(w));
77+
}
78+
6279
export const SchemaClassView: React.FC<{
6380
className?: string;
6481
style?: React.CSSProperties;
6582
declaration: api.SchemaClass;
6683
}> = ({ className, style, declaration }) => {
6784
const { root } = useContext(DeclarationsContext);
85+
const searchWords = useSearchWords();
86+
87+
const nameMatches = searchWords.length === 0 || matchesWords(declaration.name, searchWords);
88+
const collapseNonMatching = searchWords.length > 0 && !nameMatches;
89+
90+
const { matchingFields, hiddenCount } = useMemo(() => {
91+
if (!collapseNonMatching) {
92+
return { matchingFields: declaration.fields, hiddenCount: 0 };
93+
}
94+
const matching = declaration.fields.filter((f) => matchesWords(f.name, searchWords));
95+
return { matchingFields: matching, hiddenCount: declaration.fields.length - matching.length };
96+
}, [declaration.fields, searchWords, collapseNonMatching]);
97+
6898
return (
6999
<CommonGroupWrapper className={className} style={style}>
70100
<DeclarationHeader>
@@ -87,21 +117,26 @@ export const SchemaClassView: React.FC<{
87117
</CommonGroupSignature>
88118
</DeclarationHeader>
89119
<MetadataTags metadata={declaration.metadata} />
90-
{declaration.fields.length > 0 && (
120+
{(matchingFields.length > 0 || hiddenCount > 0) && (
91121
<ClassMembers>
92-
{declaration.fields.map((field) => (
93-
<SchemaFieldView key={field.name} field={field} />
122+
{matchingFields.map((field) => (
123+
<SchemaFieldView key={field.name} field={field} highlighted={searchWords.length > 0 && matchesWords(field.name, searchWords)} />
94124
))}
125+
{hiddenCount > 0 && (
126+
<CollapsedFieldsLink to={`${root}/${declaration.name}`}>
127+
{hiddenCount} more field{hiddenCount !== 1 ? "s" : ""}
128+
</CollapsedFieldsLink>
129+
)}
95130
</ClassMembers>
96131
)}
97-
<ReferencedBy name={declaration.name} />
132+
{!collapseNonMatching && <ReferencedBy name={declaration.name} />}
98133
</CommonGroupWrapper>
99134
);
100135
};
101136

102-
function SchemaFieldView({ field }: { field: api.SchemaField }) {
137+
function SchemaFieldView({ field, highlighted }: { field: api.SchemaField; highlighted: boolean }) {
103138
return (
104-
<FieldRow>
139+
<FieldRow $highlighted={highlighted}>
105140
<FieldSignature>
106141
<KindIcon kind="field" size="small" />
107142
{field.name}: <SchemaTypeView type={field.type} />

web/src/components/Docs/SchemaEnum.tsx

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import * as api from "./api";
2-
import React, { useContext } from "react";
2+
import React, { useContext, useMemo } from "react";
3+
import { Link } from "react-router-dom";
34
import styled from "styled-components";
45
import { ColoredSyntax } from "~components/ColoredSyntax";
56
import { KindIcon } from "./utils/components";
67
import { DeclarationsContext } from "./DeclarationsContext";
78
import { MetadataTags } from "./SchemaType";
89
import { ReferencedBy } from "./ReferencedBy";
9-
import { ModuleBadge } from "./SchemaClass";
10+
import { ModuleBadge, matchesWords } from "./SchemaClass";
11+
import { useSearchWords } from "./utils/filtering";
1012
import {
1113
CommonGroupMembers,
1214
CommonGroupSignature,
@@ -23,25 +25,39 @@ const alignmentToType: Record<number, string> = {
2325
};
2426

2527
const EnumTypeWrapper = styled.span`
26-
font-size: 14px;
28+
font-size: 16px;
2729
font-weight: normal;
2830
color: ${(props) => props.theme.textDim};
2931
margin-left: 8px;
3032
`;
3133

3234
const EnumMembers = styled(CommonGroupMembers)`
3335
> :not(:last-child) {
34-
margin-bottom: 1px;
36+
margin-bottom: 2px;
3537
}
3638
`;
3739

38-
const EnumMemberWrapper = styled.div`
39-
padding: 2px 6px;
40+
const EnumMemberWrapper = styled.div<{ $highlighted?: boolean }>`
41+
padding: 3px 8px;
42+
background-color: ${(props) => props.$highlighted ? props.theme.searchHighlight : "transparent"};
43+
border-radius: 6px;
4044
`;
4145

4246
const EnumMemberSignature = styled.div`
4347
font-weight: 600;
48+
font-size: 16px;
49+
`;
50+
51+
const CollapsedMembersLink = styled(Link)`
52+
display: block;
53+
padding: 4px 8px;
4454
font-size: 14px;
55+
color: ${(props) => props.theme.textDim};
56+
text-decoration: none;
57+
58+
&:hover {
59+
text-decoration: underline;
60+
}
4561
`;
4662

4763
export const SchemaEnumView: React.FC<{
@@ -50,6 +66,19 @@ export const SchemaEnumView: React.FC<{
5066
declaration: api.SchemaEnum;
5167
}> = ({ className, style, declaration }) => {
5268
const { root } = useContext(DeclarationsContext);
69+
const searchWords = useSearchWords();
70+
71+
const nameMatches = searchWords.length === 0 || matchesWords(declaration.name, searchWords);
72+
const collapseNonMatching = searchWords.length > 0 && !nameMatches;
73+
74+
const { matchingMembers, hiddenCount } = useMemo(() => {
75+
if (!collapseNonMatching) {
76+
return { matchingMembers: declaration.members, hiddenCount: 0 };
77+
}
78+
const matching = declaration.members.filter((m) => matchesWords(m.name, searchWords));
79+
return { matchingMembers: matching, hiddenCount: declaration.members.length - matching.length };
80+
}, [declaration.members, searchWords, collapseNonMatching]);
81+
5382
return (
5483
<CommonGroupWrapper className={className} style={style}>
5584
<DeclarationHeader>
@@ -61,21 +90,26 @@ export const SchemaEnumView: React.FC<{
6190
</CommonGroupSignature>
6291
</DeclarationHeader>
6392
<MetadataTags metadata={declaration.metadata} />
64-
{declaration.members.length > 0 && (
93+
{(matchingMembers.length > 0 || hiddenCount > 0) && (
6594
<EnumMembers>
66-
{declaration.members.map((member) => (
67-
<EnumMemberView key={member.name} member={member} />
95+
{matchingMembers.map((member) => (
96+
<EnumMemberView key={member.name} member={member} highlighted={searchWords.length > 0 && matchesWords(member.name, searchWords)} />
6897
))}
98+
{hiddenCount > 0 && (
99+
<CollapsedMembersLink to={`${root}/${declaration.name}`}>
100+
{hiddenCount} more member{hiddenCount !== 1 ? "s" : ""}
101+
</CollapsedMembersLink>
102+
)}
69103
</EnumMembers>
70104
)}
71-
<ReferencedBy name={declaration.name} />
105+
{!collapseNonMatching && <ReferencedBy name={declaration.name} />}
72106
</CommonGroupWrapper>
73107
);
74108
};
75109

76-
function EnumMemberView({ member }: { member: api.SchemaEnumMember }) {
110+
function EnumMemberView({ member, highlighted }: { member: api.SchemaEnumMember; highlighted: boolean }) {
77111
return (
78-
<EnumMemberWrapper>
112+
<EnumMemberWrapper $highlighted={highlighted}>
79113
<EnumMemberSignature>
80114
{member.name} = <ColoredSyntax kind="literal">{member.value}</ColoredSyntax>
81115
</EnumMemberSignature>

web/src/components/Docs/utils/filtering.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ export function useFilteredData(declarations: api.Declaration[]) {
2020
}, [declarations, search, scope]);
2121
}
2222

23+
export function useSearchWords(): string[] {
24+
const { search } = useContext(SearchContext);
25+
return useMemo(
26+
() => search ? search.toLowerCase().split(" ").filter((x) => !x.startsWith("module:")) : [],
27+
[search],
28+
);
29+
}
30+
2331
export function doSearch(declarations: api.Declaration[], words: string[]): api.Declaration[] {
2432
const moduleWords = words.filter((x) => x.startsWith("module:")).map((x) => x.replace(/^module:/, ""));
2533
const nameWords = words.filter((x) => !x.startsWith("module:"));

web/src/components/Docs/utils/styles.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,18 @@ export const CommonGroupWrapper = styled.div`
66
flex-flow: column;
77
background-color: ${(props) => props.theme.group};
88
border: 1px solid ${(props) => props.theme.groupBorder};
9-
border-radius: 8px;
9+
border-radius: 10px;
10+
box-shadow: ${(props) => props.theme.groupShadow};
1011
overflow: hidden;
1112
word-break: break-all;
1213
`;
1314

1415
export const CommonGroupMembers = styled.div`
1516
background-color: ${(props) => props.theme.groupMembers};
16-
padding: 8px 8px 8px 12px;
17+
padding: 10px 12px;
1718
1819
> :not(:last-child) {
19-
margin-bottom: 3px;
20+
margin-bottom: 4px;
2021
}
2122
`;
2223

@@ -34,11 +35,11 @@ export const CommonGroupSignature = styled.div`
3435
`;
3536

3637
export const DeclarationHeader = styled(CommonGroupHeader)`
37-
padding: 10px 12px;
38+
padding: 12px 14px;
3839
`;
3940

4041
export const DeclarationNameLink = styled(Link)`
41-
font-size: 20px;
42+
font-size: 24px;
4243
font-weight: 700;
4344
text-decoration: none;
4445
color: inherit;

web/src/components/GlobalStyle.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export const GlobalStyle = createGlobalStyle`
77
margin: 0;
88
background-color: ${(props) => props.theme.background};
99
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
10-
font-size: 14px;
10+
font-size: 16px;
1111
-webkit-font-smoothing: antialiased;
1212
-moz-osx-font-smoothing: grayscale;
1313
scrollbar-color: ${(props) => props.theme.scrollbar.thumb} ${(props) => props.theme.scrollbar.track};

web/src/components/Search/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ export function useCtrlFHook<T extends HTMLElement>() {
2424
export const SearchInput = styled.input.attrs({ type: "search" })`
2525
width: 100%;
2626
box-sizing: border-box;
27-
padding: 7px 12px;
27+
padding: 8px 14px;
2828
border: 1px solid ${(props) => props.theme.groupBorder};
29-
border-radius: 8px;
29+
border-radius: 10px;
3030
background: ${(props) => props.theme.searchbox.background};
3131
color: ${(props) => props.theme.text};
3232
font-family: inherit;
33-
font-size: 14px;
33+
font-size: 16px;
3434
outline: none;
3535
transition: border-color 0.15s, box-shadow 0.15s;
3636

0 commit comments

Comments
 (0)