1- import React , {
2- CSSProperties ,
3- useCallback ,
4- useEffect ,
5- useRef ,
6- useState ,
7- } from "react"
1+ import React from "react"
2+ import type { CSSProperties } from "react"
83
94import { token } from "@atlaskit/tokens"
10- import styled from "@emotion/styled "
5+ import { css } from "@emotion/css "
116
12- import ChevronUpIcon from "@atlaskit/icon/glyph/chevron-up"
13- import ChevronDownIcon from "@atlaskit/icon/glyph/chevron-down"
7+ import { Collapsible } from "./Collapsible"
148
159const borderColor = token ( "color.border" , "#091e4224" )
16- const headerBackgroundColor = token ( "elevation.surface.sunken" , "#f4f5f7" )
17- const bodyBackgroundColor = token ( "elevation.surface" , "#fff" )
10+ const headerBackgroundColor = token ( "elevation.surface.sunken" , "#f7f8f9" )
1811
1912const headerTitleColor = token ( "color.text" , "#172B4D" )
2013const headerSubtitleTextColor = token ( "color.text.subtlest" , "#6b778c" )
2114
22- const bookCardBaseStyle : CSSProperties = {
23- display : "flex" ,
24- flexDirection : "column" ,
25- minWidth : 0 ,
26- flex : "1 1 0" ,
27- marginTop : "14px" ,
28- borderRadius : "4px" ,
29- border : `1px solid ${ borderColor } ` ,
30- overflow : "hidden" ,
31- }
15+ const bodyBackgroundColor = token ( "elevation.surface" , "#fff" )
3216
33- function CardBase ( {
34- children,
17+ const CardBase = ( {
3518 header,
3619 closed,
20+ children,
3721} : {
38- children ?: React . ReactNode
3922 header : React . ReactNode
4023 closed ?: boolean | undefined | null
41- } ) {
42- const detailsRef = useRef < HTMLDetailsElement > ( null )
43- const [ isClosed , setIsClosed ] = useState < boolean | undefined | null > ( closed )
44-
45- useEffect ( ( ) => {
46- setIsClosed ( closed )
47- } , [ closed ] )
48-
49- const onToggledCB = useCallback ( ( ) => {
50- if ( closed ) {
51- return
52- }
53- setIsClosed ( ( prev ) => ! prev )
54- } , [ closed ] )
55-
56- return (
57- < details
58- ref = { detailsRef }
59- style = { bookCardBaseStyle }
60- { ...( ( closed == undefined || ! closed ) && { open : true } ) }
61- //onToggle={onToggledCB}
62- onClick = { ( e ) => e . preventDefault ( ) }
24+ children ?: React . ReactNode
25+ } ) => (
26+ < Collapsible
27+ openButtonPosition = { closed != null ? "right" : "hidden" }
28+ header = { header }
29+ opened = { ! closed }
30+ headerContainerStyle = { {
31+ backgroundColor : headerBackgroundColor ,
32+ border : `1px solid ${ borderColor } ` ,
33+ } }
34+ >
35+ < div
36+ className = "border-b border-x rounded-b"
37+ style = { {
38+ backgroundColor : bodyBackgroundColor ,
39+ borderColor : borderColor ,
40+ } }
6341 >
64- < summary
65- style = { {
66- listStyle : "none" ,
67- margin : 0 ,
68- padding : 0 ,
69- display : "flex" ,
70- alignItems : "center" ,
71- justifyContent : "space-between" ,
72- backgroundColor : headerBackgroundColor ,
73- borderBottom : `1px solid ${ borderColor } ` ,
74- borderTopRightRadius : "4px" ,
75- } }
76- >
77- < div
78- style = { {
79- width : "100%" ,
80- marginBottom : "-1px" ,
81- //userSelect: "none",
82- } }
83- >
84- { header }
85- </ div >
86- { closed != undefined && (
87- < div
88- style = { {
89- marginLeft : "-8px" ,
90- marginRight : "4px" ,
91- } }
92- onClick = { onToggledCB }
93- >
94- { ! isClosed ? (
95- < ChevronUpIcon label = "close" />
96- ) : (
97- < ChevronDownIcon label = "open" />
98- ) }
99- </ div >
100- ) }
101- </ summary >
10242 { children }
103- </ details >
104- )
105- }
106-
107- const CardHeader = styled . div `
108- // book-card-header
109- display: flex;
110- flex-direction: row;
111- justify-content: space-between;
112- gap: 30px;
113- min-width: 0;
114-
115- padding: 12px;
116-
117- border-top-left-radius: 4px;
118- border-top-right-radius: 4px;
119- background: ${ headerBackgroundColor } ;
120- border-bottom: 1px solid ${ borderColor } ;
121- `
122-
123- const CardHeaderMeta = styled . div `
124- // book-card-header-meta
125- display: flex;
126- flex-direction: column;
127- min-width: 0;
128- flex: 1;
129- `
130-
131- const CardHeaderTitle = styled . h3 `
132- text-overflow: ellipsis;
133- white-space: nowrap;
134- overflow: hidden;
135- color: ${ headerTitleColor } ;
136- `
137-
138- const CardHeaderSubtitle = styled . h6 `
139- margin-top: 5px;
140-
141- text-overflow: ellipsis;
142- white-space: nowrap;
143- overflow: hidden;
144- color: ${ headerSubtitleTextColor } ;
145- `
146-
147- const CardHeaderActions = styled . div `
148- // book-card-header-actions
149- display: flex;
150- align-items: center;
151- justify-content: flex-end;
152- `
153-
154- const CardHeaderActionsInfo = styled . div `
155- // book-card-header-actions-info
156- margin-right: 10px;
157- align-items: center;
158-
159- & > span:not([role="presentation"]) {
160- vertical-align: super;
161- }
162- `
163-
164- const CardGridBody = styled . div `
165- display: grid;
166- grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
167- overflow: auto;
168- border-collapse: collapse;
169- margin-right: -1px;
170- margin-bottom: -1px;
171- > * {
172- padding: 8px 12px;
173- border-bottom: 1px solid ${ borderColor } ;
174- border-right: 1px solid ${ borderColor } ;
175- }
176- `
177-
178- const CardRowBody = styled . div `
179- display: grid;
180- overflow-x: auto;
181- overflow-y: hidden;
182- grid-auto-flow: column;
183- grid-auto-columns: minmax(150px, 1fr);
184- border-collapse: collapse;
185- margin-right: -1px;
186- margin-bottom: -1px;
43+ </ div >
44+ </ Collapsible >
45+ )
46+
47+ const CardHeader = ( { children } : { children : React . ReactNode } ) => (
48+ < div className = "flex flex-1 justify-between p-3 align-baseline" >
49+ { children }
50+ </ div >
51+ )
52+
53+ const CardHeaderMeta = ( { children } : { children : React . ReactNode } ) => (
54+ < div className = "flex flex-1 flex-col items-baseline" > { children } </ div >
55+ )
56+
57+ const CardHeaderTitle = ( { children } : { children : React . ReactNode } ) => (
58+ < h3
59+ className = "no-wrap text-ellipsis overflow-hidden"
60+ style = { { color : headerTitleColor } }
61+ >
62+ { children }
63+ </ h3 >
64+ )
65+
66+ const CardHeaderSubtitle = ( { children } : { children : React . ReactNode } ) => (
67+ < h6
68+ className = "no-wrap mt-1 text-ellipsis overflow-hidden"
69+ style = { { color : headerSubtitleTextColor } }
70+ >
71+ { children }
72+ </ h6 >
73+ )
74+
75+ const CardHeaderActions = ( { children } : { children : React . ReactNode } ) => (
76+ < div className = "flex content-end items-center" > { children } </ div >
77+ )
78+
79+ const CardHeaderActionsInfo = ( { children } : { children : React . ReactNode } ) => (
80+ < div className = "mr-2 text-sm items-center" > { children } </ div >
81+ )
82+
83+ const cardBodyEntryBaseStyle = css `
18784 > * {
18885 padding : 8px 12px ;
18986 border-bottom : 1px solid ${ borderColor } ;
19087 border-right : 1px solid ${ borderColor } ;
19188 }
19289`
193-
194- const CardColumnBody = styled . div `
195- display: grid;
196- grid-auto-flow: row;
197- overflow: auto;
198- border-collapse: collapse;
199- margin-right: -1px;
200- margin-bottom: -1px;
201- > * {
202- padding: 8px 12px;
203- border-bottom: 1px solid ${ borderColor } ;
204- border-right: 1px solid ${ borderColor } ;
205- }
206- `
207-
208- const CardBodyEntry = styled . div `
209- display: flex;
210- flex: 1 1 0;
211- align-items: baseline;
212- flex-direction: column;
213- background-color: ${ bodyBackgroundColor } ;
214-
215- font-size: smaller;
216- `
217-
218- const CardBodyEntryTitle = styled . span `
219- font-size: ${ token ( "font.heading.sm" , "13px" ) } ;
220- font-weight: ${ token ( "font.weight.bold" , "600" ) } ;
221- `
90+ const CardGridBody = ( { children } : { children : React . ReactNode } ) => (
91+ < div
92+ className = { `grid border-collapse overflow-auto ${ cardBodyEntryBaseStyle } ${ css `
93+ grid-template-columns : repeat (auto-fit, minmax (150px , 1fr ));
94+ ` } `}
95+ >
96+ { children }
97+ </ div >
98+ )
99+
100+ const CardRowBody = ( { children } : { children : React . ReactNode } ) => (
101+ < div
102+ className = { `grid overflow-x-auto overflow-y-hidden border-collapse grid-flow-col ${ cardBodyEntryBaseStyle } ${ css `
103+ grid-auto-columns : minmax (150px , 1fr );
104+ ` } `}
105+ >
106+ { children }
107+ </ div >
108+ )
109+
110+ const CardColumnBody = ( { children } : { children : React . ReactNode } ) => (
111+ < div
112+ className = { `grid overflow-auto border-collapse grid-flow-row ${ cardBodyEntryBaseStyle } ${ css `
113+ grid-auto-rows : minmax (150px , 1fr );
114+ ` } `}
115+ >
116+ { children }
117+ </ div >
118+ )
119+
120+ const CardBodyEntry = ( { children } : { children : React . ReactNode } ) => (
121+ < div className = "flex flex-1 flex-col items-baseline text-xs" >
122+ { children }
123+ </ div >
124+ )
125+
126+ const CardBodyEntryTitle = ( { children } : { children : React . ReactNode } ) => (
127+ < span className = "text-sm font-bold" > { children } </ span >
128+ )
222129
223130const BookCardComponents = {
224131 CardBase,
@@ -243,7 +150,6 @@ type BookCardProps = {
243150 closed ?: boolean | undefined | null
244151 bodyLayout : "row" | "grid" | "column"
245152 bodyStyle ?: CSSProperties
246- maxBodyHeight ?: string
247153 actions ?: React . ReactNode
248154 actionsInfo ?: React . ReactNode
249155 children ?: React . ReactNode
@@ -294,7 +200,9 @@ export function BookCard({
294200 </ CardHeader >
295201 }
296202 >
297- < div style = { bodyStyle } > { body } </ div >
203+ < div className = "-mb-[1px] -mx-[1px]" >
204+ < div style = { bodyStyle } > { body } </ div >
205+ </ div >
298206 </ CardBase >
299207 )
300208}
0 commit comments