Skip to content

Commit a2c08d9

Browse files
committed
Nice cozy "Show More" behavior
1 parent 9d0e453 commit a2c08d9

File tree

2 files changed

+81
-27
lines changed

2 files changed

+81
-27
lines changed

src/components/Offer.js

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@ import { transparentize } from "polished";
55

66
import { Link, Tag, Reaction } from "@components";
77
import { darkPink, pink } from "@utils/theme";
8+
import { ShowMore } from "./ShowMore";
89

910
const Wrapper = styled.article`
10-
&:not(:last-of-type) {
11+
border-top: 2px solid ${pink};
12+
margin-top: 2.5rem;
13+
14+
&:last-of-type {
1115
border-bottom: 2px solid ${pink};
1216
margin-bottom: 2.5rem;
1317
}
@@ -16,16 +20,14 @@ const Wrapper = styled.article`
1620
}
1721
`;
1822
const PostBody = styled.div`
19-
margin-bottom: 1.75rem;
23+
padding-bottom: 1.75rem;
2024
`;
2125
const Tags = styled.div`
2226
display: flex;
2327
flex-wrap: wrap;
2428
margin-bottom: 0.5rem;
2529
`;
26-
const Reactions = styled(Tags)`
27-
padding-bottom: 2rem;
28-
`;
30+
const Reactions = styled(Tags)``;
2931

3032
const GetInTouch = styled.button`
3133
background: none;
@@ -87,29 +89,31 @@ export const Offer = ({
8789
}) => {
8890
return (
8991
<Wrapper>
90-
<Author
91-
authorHref={getAuthorLink(author.id)}
92-
name={author.displayName}
93-
messageHref={messageLink}
94-
authorImageSrc={author.avatar}
95-
postTime={createdAt}
96-
onInfoClick={onClickGetInTouch}
97-
/>
98-
<Tags>
99-
{tags.map((tag) => (
100-
<Tag key={tag}>{tag}</Tag>
101-
))}
102-
</Tags>
103-
<PostBody dangerouslySetInnerHTML={{ __html: description }} />
104-
{reactions.length > 0 && (
105-
<Reactions>
106-
{reactions.map(([e, c]) => (
107-
<Reaction key={e}>
108-
{e} {c}
109-
</Reaction>
92+
<ShowMore>
93+
<Author
94+
authorHref={getAuthorLink(author.id)}
95+
name={author.displayName}
96+
messageHref={messageLink}
97+
authorImageSrc={author.avatar}
98+
postTime={createdAt}
99+
onInfoClick={onClickGetInTouch}
100+
/>
101+
<Tags>
102+
{tags.map((tag) => (
103+
<Tag key={tag}>{tag}</Tag>
110104
))}
111-
</Reactions>
112-
)}
105+
</Tags>
106+
{reactions.length > 0 && (
107+
<Reactions>
108+
{reactions.map(([e, c]) => (
109+
<Reaction key={e}>
110+
{e} {c}
111+
</Reaction>
112+
))}
113+
</Reactions>
114+
)}
115+
<PostBody dangerouslySetInnerHTML={{ __html: description }} />
116+
</ShowMore>
113117
</Wrapper>
114118
);
115119
};

src/components/ShowMore.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { background, foreground, pink } from "@utils/theme";
2+
import React from "react";
3+
import styled from "styled-components";
4+
5+
const SecretInput = styled.input.attrs({ type: "checkbox" })`
6+
display: none;
7+
`;
8+
const Shrinkable = styled.div`
9+
position: relative;
10+
11+
${SecretInput}:not(:checked) ~ & {
12+
max-height: 25rem;
13+
overflow: hidden;
14+
}
15+
`;
16+
const ShowMoreLabel = styled.label`
17+
&::before {
18+
content: "Show more";
19+
display: block;
20+
}
21+
${SecretInput}:checked ~ ${Shrinkable} &::before {
22+
content: "Show less";
23+
}
24+
25+
font-size: 1.5rem;
26+
text-align: center;
27+
color: ${foreground};
28+
position: absolute;
29+
top: 0;
30+
right: 0;
31+
height: 2rem;
32+
width: 10rem;
33+
background: ${background};
34+
border-bottom-left-radius: 0.5rem;
35+
border-left: 2px solid ${pink};
36+
border-bottom: 2px solid ${pink};
37+
`;
38+
39+
export const ShowMore = ({ children }: { children: React.ReactChildren }) => {
40+
const name = React.useMemo(() => Math.random().toString(), []);
41+
return (
42+
<>
43+
<SecretInput id={name} />
44+
<Shrinkable>
45+
{children}
46+
<ShowMoreLabel htmlFor={name}></ShowMoreLabel>
47+
</Shrinkable>
48+
</>
49+
);
50+
};

0 commit comments

Comments
 (0)