diff --git a/.vscode/settings.json b/.vscode/settings.json
index 5b02ce63..54e29c2e 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,8 +1,8 @@
{
"editor.codeActionsOnSave": {
- "source.fixAll.eslint": true,
- "source.fixAll.stylelint": false,
- "source.organizeImports": false
+ "source.fixAll.eslint": "explicit",
+ "source.fixAll.stylelint": "never",
+ "source.organizeImports": "never"
},
"editor.formatOnSave": true,
"eslint.options": {
diff --git a/components/src/components/atoms/ScrollBox/ScrollBox.test.tsx b/components/src/components/atoms/ScrollBox/ScrollBox.test.tsx
index 4bdc719e..a5eccb2f 100644
--- a/components/src/components/atoms/ScrollBox/ScrollBox.test.tsx
+++ b/components/src/components/atoms/ScrollBox/ScrollBox.test.tsx
@@ -44,12 +44,9 @@ const mockIntersectionObserver = makeMockIntersectionObserver(
)
const expectLine = (e: 'top' | 'bottom', visible: boolean) =>
- expect(screen.getByTestId('scroll-box')).toHaveStyleRule(
- 'background-color',
- `hsla(0 0% 91% / ${visible ? '1' : '0'})`,
- {
- modifier: e === 'top' ? '::before' : '::after',
- },
+ expect(screen.getByTestId('scroll-box')).toHaveAttribute(
+ `data-${e}-line`,
+ visible ? 'true' : 'false',
)
describe('', () => {
diff --git a/components/src/components/atoms/ScrollBox/ScrollBox.tsx b/components/src/components/atoms/ScrollBox/ScrollBox.tsx
index 4381bfb0..e6f7b2bb 100644
--- a/components/src/components/atoms/ScrollBox/ScrollBox.tsx
+++ b/components/src/components/atoms/ScrollBox/ScrollBox.tsx
@@ -1,55 +1,80 @@
import * as React from 'react'
import styled, { css } from 'styled-components'
-const StyledScrollBox = styled.div<{ $showTop: boolean; $showBottom: boolean }>(
- ({ theme, $showTop, $showBottom }) => css`
+const StyledScrollBox = styled.div(
+ ({ theme }) => css`
overflow: auto;
position: relative;
- border-color: ${theme.colors.greyLight};
- transition: border-color 0.15s ease-in-out;
+ @property --scrollbar {
+ syntax: '';
+ inherits: true;
+ initial-value: ${theme.colors.greyLight};
+ }
- /* stylelint-disable-next-line selector-pseudo-element-no-unknown */
- &::-webkit-scrollbar-track {
- background-color: transparent;
+ @property --top-line-color {
+ syntax: '';
+ inherits: true;
+ initial-value: transparent;
}
- &::-webkit-scrollbar {
- background-color: transparent;
+ @property --bottom-line-color {
+ syntax: '';
+ inherits: true;
+ initial-value: transparent;
}
- &::-webkit-scrollbar:vertical {
- width: ${theme.space['1.5']};
+ /* stylelint-disable custom-property-no-missing-var-function */
+ transition: --scrollbar 0.15s ease-in-out,
+ height 0.15s ${theme.transitionTimingFunction.popIn},
+ --top-line-color 0.15s ease-in-out, --bottom-line-color 0.15s ease-in-out;
+ /* stylelint-enable custom-property-no-missing-var-function */
+
+ ::-webkit-scrollbar {
+ width: ${theme.space['3.5']};
+ transition: box-shadow 0.15s ease-in-out;
+ }
+
+ ::-webkit-scrollbar,
+ ::-webkit-scrollbar-track,
+ ::-webkit-scrollbar-track-piece {
background-color: transparent;
}
- &::-webkit-scrollbar:horizontal {
- height: ${theme.space['1.5']};
+ ::-webkit-scrollbar-button {
+ display: none;
+ }
+
+ ::-webkit-scrollbar-thumb {
+ transition: box-shadow 0.15s ease-in-out;
+ box-shadow: inset 0 0 ${theme.space['3']} ${theme.space['3']}
+ var(--scrollbar);
+ border: solid ${theme.space['1']} transparent;
+ border-radius: ${theme.space['3']};
background-color: transparent;
}
- &::-webkit-scrollbar-thumb:vertical {
- border: none;
- border-radius: ${theme.radii.full};
- border-right-style: inset;
- border-right-width: calc(100vw + 100vh);
- border-color: inherit;
+ &:hover {
+ --scrollbar: ${theme.colors.greyBright};
}
- &::-webkit-scrollbar-thumb:horizontal {
- border: none;
- border-radius: ${theme.radii.full};
- border-bottom-style: inset;
- border-bottom-width: calc(100vw + 100vh);
- border-color: inherit;
+ &[data-top-line='true'] {
+ --top-line-color: ${theme.colors.greyLight};
+ &::before {
+ z-index: 100;
+ }
}
- &::-webkit-scrollbar-button {
- display: none;
+ &[data-bottom-line='true'] {
+ --bottom-line-color: ${theme.colors.greyLight};
+ &::after {
+ z-index: 100;
+ }
}
- &:hover {
- border-color: ${theme.colors.greyBright};
+ ::-webkit-scrollbar-track {
+ border-top: solid ${theme.space['px']} var(--top-line-color);
+ border-bottom: solid ${theme.space['px']} var(--bottom-line-color);
}
&::before,
@@ -60,25 +85,15 @@ const StyledScrollBox = styled.div<{ $showTop: boolean; $showBottom: boolean }>(
width: 100%;
display: block;
height: ${theme.space.px};
- background-color: hsla(${theme.colors.raw.greyLight} / 0);
- transition: background-color 0.15s ease-in-out;
}
&::before {
top: 0;
- ${$showTop &&
- css`
- background-color: hsla(${theme.colors.raw.greyLight} / 1);
- z-index: 100;
- `}
+ background-color: var(--top-line-color);
}
&::after {
bottom: 0;
- ${$showBottom &&
- css`
- background-color: hsla(${theme.colors.raw.greyLight} / 1);
- z-index: 100;
- `}
+ background-color: var(--bottom-line-color);
}
`,
)
@@ -170,8 +185,8 @@ export const ScrollBox = ({
return (