feat(SW-441): Added table block component
This commit is contained in:
committed by
Pontus Dreij
parent
ef411b4cf9
commit
dfd40aa7aa
35
components/TempDesignSystem/ScrollWrapper/index.tsx
Normal file
35
components/TempDesignSystem/ScrollWrapper/index.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
"use client"
|
||||
|
||||
import { useMemo } from "react"
|
||||
|
||||
import useScrollShadows from "@/hooks/useScrollShadows"
|
||||
|
||||
import { ScrollWrapperProps } from "./scrollWrapper"
|
||||
|
||||
import styles from "./scrollWrapper.module.css"
|
||||
|
||||
export default function ScrollWrapper({
|
||||
className,
|
||||
children,
|
||||
}: ScrollWrapperProps) {
|
||||
const { containerRef, showLeftShadow, showRightShadow } = useScrollShadows()
|
||||
|
||||
const classNames = useMemo(() => {
|
||||
const cls = [styles.scrollWrapper, className]
|
||||
if (showLeftShadow) {
|
||||
cls.push(styles.leftShadow)
|
||||
}
|
||||
if (showRightShadow) {
|
||||
cls.push(styles.rightShadow)
|
||||
}
|
||||
return cls.join(" ")
|
||||
}, [showLeftShadow, showRightShadow, className])
|
||||
|
||||
return (
|
||||
<div className={classNames}>
|
||||
<div className={styles.content} ref={containerRef}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
.scrollWrapper {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scrollWrapper::before,
|
||||
.scrollWrapper::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
transition: opacity 0.2s ease;
|
||||
opacity: 0;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.scrollWrapper.leftShadow::before {
|
||||
left: 0;
|
||||
background: linear-gradient(to right, rgba(0, 0, 0, 0.3), transparent);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.scrollWrapper.rightShadow::after {
|
||||
right: 0;
|
||||
background: linear-gradient(to left, rgba(0, 0, 0, 0.3), transparent);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.content {
|
||||
overflow-x: auto;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export interface ScrollWrapperProps
|
||||
extends React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>> {}
|
||||
@@ -1,4 +0,0 @@
|
||||
.container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
@@ -5,18 +5,29 @@ import { useIntl } from "react-intl"
|
||||
import { ChevronDownIcon } from "@/components/Icons"
|
||||
import Button from "@/components/TempDesignSystem/Button"
|
||||
|
||||
import styles from "./button.module.css"
|
||||
import { showMoreButtonVariants } from "./variants"
|
||||
|
||||
import type { ShowMoreButtonParams } from "@/types/components/myPages/stays/button"
|
||||
import styles from "./showMoreButton.module.css"
|
||||
|
||||
import type { ShowMoreButtonProps } from "./showMoreButton"
|
||||
|
||||
export default function ShowMoreButton({
|
||||
className,
|
||||
intent,
|
||||
disabled,
|
||||
showLess,
|
||||
loadMoreData,
|
||||
}: ShowMoreButtonParams) {
|
||||
const { formatMessage } = useIntl()
|
||||
}: ShowMoreButtonProps) {
|
||||
const intl = useIntl()
|
||||
const classNames = showMoreButtonVariants({
|
||||
className,
|
||||
intent,
|
||||
})
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={`${classNames} ${showLess ? styles.showLess : ""}`}>
|
||||
<Button
|
||||
className={styles.button}
|
||||
disabled={disabled}
|
||||
onClick={loadMoreData}
|
||||
variant="icon"
|
||||
@@ -24,8 +35,8 @@ export default function ShowMoreButton({
|
||||
theme="base"
|
||||
intent="text"
|
||||
>
|
||||
<ChevronDownIcon />
|
||||
{formatMessage({ id: "Show more" })}
|
||||
<ChevronDownIcon className={styles.icon} />
|
||||
{intl.formatMessage({ id: showLess ? "Show less" : "Show more" })}
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
.container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.table {
|
||||
display: grid;
|
||||
justify-content: stretch;
|
||||
border-top: 1px solid var(--Base-Border-Subtle);
|
||||
background-color: var(--Base-Surface-Primary-light-Normal);
|
||||
}
|
||||
|
||||
.table .button {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.icon {
|
||||
transition: transform 0.3s;
|
||||
}
|
||||
|
||||
.showLess .icon {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
11
components/TempDesignSystem/ShowMoreButton/showMoreButton.ts
Normal file
11
components/TempDesignSystem/ShowMoreButton/showMoreButton.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { showMoreButtonVariants } from "./variants"
|
||||
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
|
||||
export interface ShowMoreButtonProps
|
||||
extends React.PropsWithChildren<React.HTMLAttributes<HTMLDivElement>>,
|
||||
VariantProps<typeof showMoreButtonVariants> {
|
||||
disabled?: boolean
|
||||
showLess?: boolean
|
||||
loadMoreData: () => void
|
||||
}
|
||||
11
components/TempDesignSystem/ShowMoreButton/variants.ts
Normal file
11
components/TempDesignSystem/ShowMoreButton/variants.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from "./showMoreButton.module.css"
|
||||
|
||||
export const showMoreButtonVariants = cva(styles.container, {
|
||||
variants: {
|
||||
intent: {
|
||||
table: styles.table,
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -1,7 +1,13 @@
|
||||
import styles from "./table.module.css"
|
||||
|
||||
function TH({ children }: React.PropsWithChildren) {
|
||||
return <th className={styles.th}>{children}</th>
|
||||
import type { THeadProps } from "./table"
|
||||
|
||||
function TH({ children, width = "auto", ...props }: THeadProps) {
|
||||
return (
|
||||
<th className={styles.th} style={{ width }} {...props}>
|
||||
{children}
|
||||
</th>
|
||||
)
|
||||
}
|
||||
|
||||
export default TH
|
||||
|
||||
@@ -1,13 +1,34 @@
|
||||
import { TableProps } from "./table"
|
||||
import TBody from "./TBody"
|
||||
import TD from "./TD"
|
||||
import TH from "./TH"
|
||||
import THead from "./THead"
|
||||
import TR from "./TR"
|
||||
import { tableVariants } from "./variants"
|
||||
|
||||
import styles from "./table.module.css"
|
||||
function Table({
|
||||
className,
|
||||
intent,
|
||||
borderRadius,
|
||||
variant,
|
||||
layout,
|
||||
width = "100%",
|
||||
children,
|
||||
...props
|
||||
}: TableProps) {
|
||||
const classNames = tableVariants({
|
||||
className,
|
||||
borderRadius,
|
||||
intent,
|
||||
layout,
|
||||
variant,
|
||||
})
|
||||
|
||||
function Table({ children }: React.PropsWithChildren) {
|
||||
return <table className={styles.table}>{children}</table>
|
||||
return (
|
||||
<table className={classNames} style={{ width }} {...props}>
|
||||
{children}
|
||||
</table>
|
||||
)
|
||||
}
|
||||
|
||||
Table.THead = THead
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
.table {
|
||||
border-radius: var(--Corner-radius-Medium);
|
||||
border-collapse: collapse;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.thead {
|
||||
background-color: var(--Base-Background-Secondary-Normal, #f7e1d5);
|
||||
color: var(--Base-Text-High-contrast);
|
||||
background-color: var(--Base-Surface-Primary-dark-Normal);
|
||||
}
|
||||
|
||||
.tbody {
|
||||
background-color: var(--Base-Surface-Primary-light-Normal, #fff);
|
||||
background-color: var(--Base-Surface-Primary-light-Normal);
|
||||
}
|
||||
|
||||
.tr:not(:last-of-type) {
|
||||
border-bottom: 1px solid var(--Primary-Light-On-Surface-Divider, #f0c1b6);
|
||||
border-bottom: 1px solid var(--Base-Border-Subtle);
|
||||
}
|
||||
|
||||
.th {
|
||||
@@ -28,6 +28,35 @@
|
||||
padding: var(--Spacing-x2);
|
||||
}
|
||||
|
||||
.fixed {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.smallRadius {
|
||||
border-radius: var(--Corner-radius-Small);
|
||||
}
|
||||
.mediumRadius {
|
||||
border-radius: var(--Corner-radius-Medium);
|
||||
}
|
||||
.largeRadius {
|
||||
border-radius: var(--Corner-radius-Large);
|
||||
}
|
||||
|
||||
.content .thead {
|
||||
background-color: var(--Base-Surface-Subtle-Hover);
|
||||
}
|
||||
|
||||
.content .tbody {
|
||||
background-color: var(--Base-Background-Primary-Normal);
|
||||
}
|
||||
|
||||
.content.striped .tbody .tr:nth-child(odd) {
|
||||
background-color: var(--Base-Surface-Subtle-Normal);
|
||||
}
|
||||
.content.striped .tbody .tr:nth-child(even) {
|
||||
background-color: var(--Base-Background-Primary-Normal);
|
||||
}
|
||||
|
||||
@media screen and (min-width: 768px) {
|
||||
.th {
|
||||
padding: var(--Spacing-x2) var(--Spacing-x3);
|
||||
|
||||
14
components/TempDesignSystem/Table/table.ts
Normal file
14
components/TempDesignSystem/Table/table.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { tableVariants } from "./variants"
|
||||
|
||||
import type { VariantProps } from "class-variance-authority"
|
||||
|
||||
export interface TableProps
|
||||
extends React.PropsWithChildren<React.HTMLAttributes<HTMLTableElement>>,
|
||||
VariantProps<typeof tableVariants> {
|
||||
width?: string
|
||||
}
|
||||
|
||||
export interface THeadProps
|
||||
extends React.PropsWithChildren<React.HTMLAttributes<HTMLTableCellElement>> {
|
||||
width?: string
|
||||
}
|
||||
27
components/TempDesignSystem/Table/variants.ts
Normal file
27
components/TempDesignSystem/Table/variants.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import styles from "./table.module.css"
|
||||
|
||||
export const tableVariants = cva(styles.table, {
|
||||
variants: {
|
||||
intent: {
|
||||
light: styles.light,
|
||||
striped: styles.striped,
|
||||
},
|
||||
variant: {
|
||||
content: styles.content,
|
||||
},
|
||||
borderRadius: {
|
||||
none: "",
|
||||
small: styles.smallRadius,
|
||||
medium: styles.mediumRadius,
|
||||
large: styles.largeRadius,
|
||||
},
|
||||
layout: {
|
||||
fixed: styles.fixed,
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
borderRadius: "medium",
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user