Initial commit

This commit is contained in:
James Jia - Test
2023-09-08 13:52:13 -07:00
commit 4b86068d8f
584 changed files with 59963 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
:root {
--ease-in-expo: cubic-bezier(0.7, 0, 0.84, 0);
--ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
--ease-in-out-expo: cubic-bezier(0.87, 0, 0.13, 1);
--ease-in-circ: cubic-bezier(0.55, 0, 1, 0.45);
--ease-out-circ: cubic-bezier(0, 0.55, 0.45, 1);
}
+26
View File
@@ -0,0 +1,26 @@
import styled, { css, type FlattenSimpleInterpolation } from 'styled-components';
import breakpoints from './breakpoints';
export const breakpointMixins = {
mobileOnly: css`
@media ${breakpoints.notMobile} {
display: none !important;
}
`,
notMobileOnly: css`
@media ${breakpoints.mobile} {
display: none !important;
}
`,
tabletOnly: css`
@media ${breakpoints.notTablet} {
display: none !important;
}
`,
notTabletOnly: css`
@media ${breakpoints.tablet} {
display: none !important;
}
`,
};
+11
View File
@@ -0,0 +1,11 @@
import { BREAKPOINT_REM } from '@/constants/page';
export default {
mobile: `(max-width: ${BREAKPOINT_REM.mobile})`,
notMobile: `(min-width: ${BREAKPOINT_REM.mobile})`,
tablet: `(max-width: ${BREAKPOINT_REM.tablet})`,
notTablet: `(min-width: ${BREAKPOINT_REM.tablet})`,
desktopSmall: `(max-width: ${BREAKPOINT_REM.desktopSmall})`,
desktopMedium: `(min-width: ${BREAKPOINT_REM.desktopMedium})`,
desktopLarge: `(min-width: ${BREAKPOINT_REM.desktopLarge})`,
};
+179
View File
@@ -0,0 +1,179 @@
:root {
/* Parameters */
/*
--layer-base-hue
--layer-base-saturation
--layer-base-lightness
--color-text-0
--color-text-1
--color-text-2
--color-accent
--color-positive
--color-negative
--color-success
--color-warning
--color-error
--color-favorite
*/
/* Computed: Layers */
--color-layer-0: hsl(
var(--layer-base-hue),
var(--layer-base-saturation),
calc(var(--layer-base-lightness) - 12%)
);
--color-layer-1: hsl(
var(--layer-base-hue),
var(--layer-base-saturation),
calc(var(--layer-base-lightness) - 8%)
);
--color-layer-2: hsl(
var(--layer-base-hue),
var(--layer-base-saturation),
calc(var(--layer-base-lightness) - 4%)
);
--color-layer-3: hsl(
var(--layer-base-hue),
var(--layer-base-saturation),
var(--layer-base-lightness)
);
--color-layer-4: hsl(
var(--layer-base-hue),
var(--layer-base-saturation),
calc(var(--layer-base-lightness) + 4%)
);
--color-layer-5: hsl(
var(--layer-base-hue),
calc(var(--layer-base-saturation) - 2%),
calc(var(--layer-base-lightness) + 7%)
);
--color-layer-6: hsl(
var(--layer-base-hue),
calc(var(--layer-base-saturation) - 4%),
calc(var(--layer-base-lightness) + 10%)
);
--color-layer-7: hsla(var(--layer-base-hue), 0%, 100%, 0.07);
--color-gradient-base-0: hsl(
var(--layer-base-hue),
calc(var(--layer-base-saturation) - 5%),
var(--layer-base-lightness)
);
--color-gradient-base-1: hsl(
var(--layer-base-hue),
calc(var(--layer-base-saturation) - 1%),
calc(var(--layer-base-lightness) + 7%)
);
/* Computed: Borders */
--color-border: var(--color-layer-5);
--color-border-white: hsla(0, 0%, 100%, 0.2);
--color-border-red: hsla(360, 73%, 61%, 0.2);
}
/* Theme: Classic (default) */
:root {
/* Constants */
--theme-classic-hue-purple: 240;
--theme-classic-color-green: hsl(159, 67%, 39%);
--theme-classic-color-yellow: hsl(36, 100%, 64%);
--theme-classic-color-red: hsl(360, 73%, 61%);
/* Parameters */
--layer-base-hue: var(--theme-classic-hue-purple);
--layer-base-saturation: 20%;
--layer-base-lightness: 16%;
--color-text-0: hsl(245, 11%, 55%);
--color-text-1: hsl(244, 18%, 81%);
--color-text-2: hsl(240, 43%, 99%);
--color-accent: hsl(var(--theme-classic-hue-purple), 100%, 70%);
--color-positive: var(--theme-classic-color-green);
--color-negative: var(--theme-classic-color-red);
--color-success: var(--theme-classic-color-green);
--color-warning: var(--theme-classic-color-yellow);
--color-error: var(--theme-classic-color-red);
--color-favorite: var(--theme-classic-color-yellow);
--color-white: #fff;
--color-black: #000;
--color-gradient-positive: hsla(158, 49%, 48%, 0.16);
--color-gradient-negative: hsla(0, 100%, 66%, 0.16);
--color-risk-low: var(--theme-classic-color-green);
--color-risk-medium: var(--theme-classic-color-yellow);
--color-risk-high: var(--theme-classic-color-red);
}
/* Theme: Light */
:root.theme-light {
/* Constants */
--theme-light-hue-purple: 234;
--theme-light-color-green: hsl(159, 67%, 39%);
--theme-light-color-yellow: hsl(36, 100%, 64%);
--theme-light-color-red: hsl(360, 73%, 61%);
/* Parameters */
--layer-base-hue: var(--theme-light-hue-purple);
--layer-base-saturation: 0%;
--layer-base-lightness: 86%;
--color-text-0: hsl(0, 0%, 55%);
--color-text-1: hsl(0, 0%, 40%);
--color-text-2: hsl(0, 0%, 5%);
--color-accent: hsl(var(--theme-light-hue-purple), 100%, 70%);
--color-positive: var(--theme-light-color-green);
--color-negative: var(--theme-light-color-red);
--color-success: var(--theme-light-color-green);
--color-warning: var(--theme-light-color-yellow);
--color-error: var(--theme-light-color-red);
--color-favorite: var(--theme-light-color-yellow);
}
/* Theme: Dark */
:root.theme-dark {
/* Constants */
--theme-dark-hue-purple: 240;
--theme-dark-color-green: hsl(159, 67%, 39%);
--theme-dark-color-yellow: hsl(36, 100%, 64%);
--theme-dark-color-red: hsl(360, 73%, 61%);
/* Parameters */
--layer-base-hue: 0;
--layer-base-saturation: 0%;
--layer-base-lightness: 16%;
--color-text-0: hsl(0, 0%, 47%);
--color-text-1: hsl(0, 0%, 67%);
--color-text-2: hsl(0, 0%, 100%);
--color-accent: hsl(var(--theme-dark-hue-purple), 100%, 70%);
--color-positive: var(--theme-dark-color-green);
--color-negative: var(--theme-dark-color-red);
--color-success: var(--theme-dark-color-green);
--color-warning: var(--theme-dark-color-yellow);
--color-error: var(--theme-dark-color-red);
--color-favorite: var(--theme-dark-color-yellow);
}
+125
View File
@@ -0,0 +1,125 @@
import { css } from 'styled-components';
import { type RiskLevels } from '@/constants/abacus';
import { AppTheme } from '@/state/configs';
const BaseElements = {
[AppTheme.Classic]: {
hue: 240,
saturation: 20,
lightness: 16,
},
[AppTheme.Dark]: {
hue: 0,
saturation: 0,
lightness: 16,
},
[AppTheme.Light]: {
hue: 234,
saturation: 0,
lightness: 86,
},
};
const LayerColors = ({ theme }: { theme: AppTheme }) => {
const { hue, saturation, lightness } = BaseElements[theme];
return {
layer0: `hsl(${hue}, ${saturation}%, ${lightness - 12}%)`,
layer1: `hsl(${hue}, ${saturation}%, ${lightness - 8}%)`,
layer2: `hsl(${hue}, ${saturation}%, ${lightness - 4}%)`,
layer3: `hsl(${hue}, ${saturation}%, ${lightness}%)`,
layer4: `hsl(${hue}, ${saturation}%, ${lightness + 4}%)`,
layer5: `hsl(${hue}, ${saturation - 2}%, ${lightness + 7}%)`,
layer6: `hsl(${hue}, ${saturation - 4}%, ${lightness + 10}%)`,
};
};
const AccentColor = ({ theme }: { theme: AppTheme }) => {
const purpleHue = {
Classic: 240,
Dark: 240,
Light: 234,
}[theme];
return {
accent: `hsl(${purpleHue}, 100%, 70%)`,
};
};
export const Colors = {
[AppTheme.Classic]: {
...LayerColors({ theme: AppTheme.Classic }),
text0: 'hsl(245, 11%, 55%)',
text1: 'hsl(244, 18%, 81%)',
text2: 'hsl(240, 43%, 99%)',
...AccentColor({ theme: AppTheme.Classic }),
green: 'hsl(159, 67%, 39%)',
yellow: 'hsl(36, 100%, 64%)',
red: 'hsl(360, 73%, 61%)',
positive: 'hsl(159, 67%, 39%)',
negative: 'hsl(360, 73%, 61%)',
success: 'hsl(159, 67%, 39%)',
warning: 'hsl(36, 100%, 64%)',
error: 'hsl(360, 73%, 61%)',
favorite: 'hsl(36, 100%, 64%)',
},
[AppTheme.Dark]: {
...LayerColors({ theme: AppTheme.Dark }),
text0: 'hsl(0, 0%, 47%)',
text1: 'hsl(0, 0%, 67%)',
text2: 'hsl(0, 0%, 100%)',
...AccentColor({ theme: AppTheme.Dark }),
green: 'hsl(159, 67%, 39%)',
yellow: 'hsl(36, 100%, 64%)',
red: 'hsl(360, 73%, 61%)',
positive: 'hsl(159, 67%, 39%)',
negative: 'hsl(360, 73%, 61%)',
success: 'hsl(159, 67%, 39%)',
warning: 'hsl(36, 100%, 64%)',
error: 'hsl(360, 73%, 61%)',
favorite: 'hsl(36, 100%, 64%)',
},
[AppTheme.Light]: {
...LayerColors({ theme: AppTheme.Light }),
text0: 'hsl(0, 0%, 55%)',
text1: 'hsl(0, 0%, 40%)',
text2: 'hsl(0, 0%, 5%)',
...AccentColor({ theme: AppTheme.Light }),
green: 'hsl(159, 67%, 39%)',
yellow: 'hsl(36, 100%, 64%)',
red: 'hsl(360, 73%, 61%)',
positive: 'hsl(159, 67%, 39%)',
negative: 'hsl(360, 73%, 61%)',
success: 'hsl(159, 67%, 39%)',
warning: 'hsl(36, 100%, 64%)',
error: 'hsl(360, 73%, 61%)',
favorite: 'hsl(36, 100%, 64%)',
},
};
export const UsageColorFromRiskLevel = (riskLevel: RiskLevels) =>
({
low: css`
color: var(--color-risk-low);
`,
medium: css`
color: var(--color-risk-medium);
`,
high: css`
color: var(--color-risk-high);
`,
}[riskLevel.name]);
+54
View File
@@ -0,0 +1,54 @@
:root {
/* Borders */
--default-border-width: 1px;
/* Header + footer constants */
--page-header-height: 2.9rem;
--page-header-height-mobile: 4rem;
--page-footer-height: 2.25rem;
--page-footer-height-mobile: 4.5rem;
/* Sidebar constants */
--sidebar-width: 20.25rem;
--collapsed-sidebar-width: 3.5rem;
/* Content constants */
--default-page-content-max-width: 80rem;
/* Trade constants */
--market-info-row-height: 3rem;
--market-info-row-height-mobile: 4.5rem;
--tabs-height: 2.75rem;
--tabs-height-mobile: 3.25rem;
--orderbook-trades-width: 18.75rem;
--tableHeader-height: 2.5rem;
--tableHeader-height-mobile: 3.25rem;
--account-info-section-height: 11.25rem;
--position-details-width: 23rem;
/* Auto grid constants */
--single-unit-min-width: 15.625rem;
--single-unit-max-width: 23.4375rem;
--single-unit-height: 9.375rem;
/* Modal constants */
--sidebar-modal-width: 18.75rem;
--modal-small-width: 18.75rem;
--modal-medium-width: 20.5rem;
--modal-large-width: 26.25rem;
--modal-header-height: 4rem;
/* Market Selector constants */
--marketsDropdown-openWidth: 45rem;
/* Form constants */
--form-input-gap: 0.625rem;
--form-input-height: 3rem;
--form-input-height-mobile: 3.5rem;
--form-input-paddingY: 0.375rem;
--form-input-paddingX: 0.625rem;
}
+42
View File
@@ -0,0 +1,42 @@
/**
* @license
*
* Font Family: Satoshi
* Designed by: Deni Anggara
* URL: https://www.fontshare.com/fonts/satoshi
* © 2023 Indian Type Foundry
*
* Font Styles:
* Satoshi Regular
* Satoshi Medium
* Satoshi Bold
* Satoshi Black
*/
@font-face {
src: url("fonts/Satoshi-Regular.woff2") format("woff2");
font-family: "Satoshi";
font-weight: 400;
}
@font-face {
src: url("fonts/Satoshi-Medium.woff2") format("woff2");
font-family: "Satoshi";
font-weight: 500;
}
@font-face {
src: url("fonts/Satoshi-Bold.woff2") format("woff2");
font-family: "Satoshi";
font-weight: 700;
}
@font-face {
src: url("fonts/Satoshi-Black.woff2") format("woff2");
font-family: "Satoshi";
font-weight: 900;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+133
View File
@@ -0,0 +1,133 @@
import {
css,
type FlattenInterpolation,
type FlattenSimpleInterpolation,
type ThemeProps,
} from 'styled-components';
import { layoutMixins } from './layoutMixins';
import breakpoints from './breakpoints';
export const formMixins: Record<
string,
FlattenSimpleInterpolation | FlattenInterpolation<ThemeProps<any>>
> = {
inputsColumn: css`
${layoutMixins.flexColumn}
gap: var(--form-input-gap);
`,
inputContainer: css`
--input-radius: 0.5em;
--input-height: var(--form-input-height);
--input-width: 100%;
--input-backgroundColor: var(--color-layer-4);
--input-borderColor: var(--color-layer-6);
${layoutMixins.row}
justify-content: space-between;
width: var(--input-width);
min-width: var(--input-width);
flex: 1;
height: var(--input-height);
min-height: var(--input-height);
background-color: var(--input-backgroundColor);
border: var(--border-width) solid var(--input-borderColor);
border-radius: var(--input-radius);
&:focus-within {
filter: brightness(1.1);
}
@media ${breakpoints.tablet} {
--input-height: var(--form-input-height-mobile);
}
`,
inputInnerButton: css`
--button-textColor: var(--color-text-1);
--button-backgroundColor: var(--color-layer-5);
--button-border: var(--border-width) solid var(--color-layer-6);
`,
inputInnerToggleButton: css`
${() => formMixins.inputInnerButton}
--button-toggle-off-backgroundColor: var(--color-layer-5);
--button-toggle-off-textColor: var(--color-text-1);
--button-toggle-on-backgroundColor: var(--color-layer-5);
--button-toggle-on-textColor: var(--color-text-1);
`,
// TODO: replace with select menu design system
inputSelectMenu: css`
--trigger-textColor: var(--color-text-2);
--trigger-backgroundColor: var(--color-layer-4);
--trigger-open-backgroundColor: var(--color-layer-4);
--trigger-border: solid var(--border-width) var(--color-layer-6);
--trigger-padding: var(--form-input-paddingY) var(--form-input-paddingX);
--trigger-height: var(--form-input-height);
--popover-backgroundColor: var(--color-layer-5);
--popover-border: var(--border-width) solid var(--color-layer-6);
font: var(--font-base-book);
@media ${breakpoints.tablet} {
--trigger-height: var(--form-input-height-mobile);
}
`,
inputSelectMenuItem: css`
--item-checked-backgroundColor: var(--color-layer-4);
--item-padding: 1rem var(--form-input-paddingX);
font: var(--font-small-book);
`,
inputInnerSelectMenu: css`
--trigger-textColor: var(--color-text-1);
--trigger-backgroundColor: var(--color-layer-5);
--trigger-open-backgroundColor: var(--color-layer-5);
--trigger-border: solid var(--border-width) var(--color-layer-6);
--trigger-padding: 0 0.33rem;
--trigger-height: 1.875rem;
--popover-backgroundColor: var(--color-layer-5);
--popover-border: solid var(--border-width) var(--color-layer-6);
font: var(--font-small-book);
`,
inputInnerSelectMenuItem: css`
--item-checked-backgroundColor: var(--color-layer-4);
font: var(--font-small-book);
`,
inputLabel: css`
position: relative;
height: 100%;
width: 100%;
gap: 0;
border-radius: inherit;
`,
inputToggleGroup: css`
display: flex;
flex-wrap: wrap;
width: 100%;
gap: 0.5rem;
> * {
flex: 1 1 0.625rem;
}
> button {
--button-toggle-off-backgroundColor: var(--color-layer-4);
--button-toggle-off-textColor: var(--color-text-1);
}
`,
};
+32
View File
@@ -0,0 +1,32 @@
import { css } from 'styled-components';
export const headerMixins = {
dropdownTrigger: css`
--trigger-backgroundColor: transparent;
--trigger-textColor: var(--color-text-0);
--trigger-hover-backgroundColor: var(--color-layer-3);
--trigger-hover-textColor: var(--color-text-2);
--trigger-open-backgroundColor: var(--color-layer-1);
--trigger-open-textColor: var(--color-text-2);
&:hover:not(:disabled) {
background-color: var(--trigger-hover-backgroundColor);
color: var(--trigger-hover-textColor);
}
`,
button: css`
--button-backgroundColor: transparent;
--button-textColor: var(--color-text-0);
--button-hover-backgroundColor: var(--color-layer-4);
--button-hover-textColor: var(--color-text-2);
&:hover:not(:disabled) {
background-color: var(--button-hover-backgroundColor);
color: var(--button-hover-textColor);
}
`,
};
+4
View File
@@ -0,0 +1,4 @@
import breakpoints from './breakpoints';
import { sidebarBreakpoints } from './sidebar';
export { breakpoints, sidebarBreakpoints };
+926
View File
@@ -0,0 +1,926 @@
import {
css,
keyframes,
type FlattenInterpolation,
type FlattenSimpleInterpolation,
type ThemeProps,
} from 'styled-components';
import breakpoints from './breakpoints';
export const layoutMixins: Record<
string,
FlattenSimpleInterpolation | FlattenInterpolation<ThemeProps<any>>
> = {
// A standalone row
row: css`
display: flex;
flex-direction: row;
align-items: center;
`,
spacedRow: css`
display: grid;
grid-auto-flow: column;
align-items: center;
justify-content: space-between;
`,
// Use within a block/inline layout
inlineRow: css`
display: inline-flex;
align-items: center;
gap: 0.5ch;
min-width: max-content;
`,
// A standalone column (shrinks to fit container)
column: css`
display: grid;
grid-auto-flow: row;
grid-template-columns: minmax(0, 1fr);
`,
// A standalone column (shrinks to fit container)
flexColumn: css`
display: flex;
flex-direction: column;
min-width: 0;
`,
// A column as a child of a row
rowColumn: css`
display: grid;
grid-auto-flow: row;
min-width: max-content;
`,
// A column with a fixed header and expanding content
expandingColumnWithHeader: css`
// Expand if within a flexColumn
flex: 1;
display: grid;
/* prettier-ignore */
grid-template:
auto
minmax(0, 1fr)
/ minmax(0, 1fr);
`,
// A column with a fixed footer and expanding content
expandingColumnWithFooter: css`
// Expand if within a flexColumn
flex: 1;
display: grid;
/* prettier-ignore */
grid-template:
minmax(0, 1fr)
auto
/ minmax(0, 1fr);
`,
gridEqualColumns: css`
display: grid;
grid-template-columns: repeat(auto-fit, minmax(0, 1fr));
`,
gridConstrainedColumns: css`
// Params
--grid-max-columns: 2;
--column-gap: var(--border-width);
--column-min-width: 20rem;
--column-max-width: 25rem;
--single-column-max-width: 22.5rem;
// Computed
--grid-max-width: calc(
var(--grid-max-columns) * var(--column-max-width) + (var(--grid-max-columns) - 1) *
var(--column-gap)
);
--column-width: calc(
(100% - ((var(--grid-max-columns) - 1) * var(--column-gap))) / var(--grid-max-columns)
);
// Rules
max-width: var(--grid-max-width);
display: grid;
grid-template-columns: repeat(
auto-fill,
minmax(
clamp(min(100%, var(--column-min-width)), var(--column-width), var(--column-max-width)),
clamp(
var(--column-min-width),
((var(--column-min-width) * 2 + var(--column-gap)) - 100%) * 100000000000,
/* Width is smaller than 2 grid columns */ var(--single-column-max-width)
)
)
);
column-gap: var(--column-gap);
`,
flexEqualColumns: css`
display: flex;
> * {
flex: 1;
}
`,
flexEqualRow: css`
display: flex;
gap: 0.5rem;
> * {
flex: 1;
}
`,
stack: css`
display: grid;
grid-template-areas: 'stack';
> *,
&:before,
&:after {
grid-area: stack;
}
`,
// A Container is an elevated stacking context with an inner pseudo-background for inner popover overlays to appear behind.
container: css`
/* Stacking context */
isolation: isolate;
z-index: 1;
position: relative;
/*
Inner layers:
- Pseudo background with border (z = -1)
- Popover overlays (z = -2)
*/
&:before {
content: '';
position: absolute;
z-index: -1;
inset: 0;
background: inherit;
${() => layoutMixins.withOuterBorder}
pointer-events: none;
}
/* Popover blur: detect state with :has() */
/*
--popover-overlay-blur-duration: 0.2s;
&:after {
content: '';
position: absolute;
inset: 0;
z-index: -2;
pointer-events: none;
&:hover {
will-change: backdrop-filter;
}
@media (prefers-reduced-motion: no-preference) {
transition: var(--popover-overlay-blur-duration);
}
}
&:has([data-state='open']):after {
backdrop-filter: blur(4px) contrast(1.01);
inset: -100vmax;
} */
/* Popover blur: detect state with :has(), blur next siblings */
/*
--popover-overlay-blur-duration: 0.2s;
~ * {
transition: var(--popover-overlay-blur-duration);
}
&:has([data-state='open']) ~ * {
filter: blur(4px) contrast(1.01);
} */
`,
// A content container column
contentContainer: css`
/* Params */
--content-container-width: 100%;
--content-max-width: 100%;
/* Overrides */
--bordered-content-outer-container-width: var(--content-container-width);
--bordered-content-max-width: var(--content-max-width);
/* Rules */
${() => layoutMixins.flexColumn}
isolation: isolate;
/* $ {() => layoutMixins.scrollArea} */
`,
// A content container with dynamic padding and children with a max width of --content-max-width
contentContainerPage: css`
/* Overrides */
${() => layoutMixins.contentContainer}
--content-container-width: 100vw;
--content-max-width: var(--default-page-content-max-width);
/* Computed */
--contentContainerPage-paddingLeft: calc(
(var(--content-container-width) - var(--content-max-width)) / 2
);
--contentContainerPage-paddingRight: calc(
(var(--content-container-width) - var(--content-max-width)) / 2
);
/* Rules */
${() => layoutMixins.stickyHeaderArea}
${() => layoutMixins.scrollSnapItem}
min-height: 100%;
/* height: max-content; */
--padding-y: clamp(0rem, (var(--content-container-width) - var(--content-max-width)) / 2, 2rem);
padding-top: var(--padding-y);
padding-bottom: var(--padding-y);
scroll-padding-top: var(--padding-y);
scroll-padding-bottom: var(--padding-y);
padding-left: var(--contentContainerPage-paddingLeft);
padding-right: var(--contentContainerPage-paddingRight);
`,
// Section
// Use within contentContainer or contentContainerPage
contentSection: css`
${() => layoutMixins.scrollSnapItem}
`,
// Section containing horizontally-overflowing content that scrolls with the outer scrollArea
// Use within contentContainer or contentContainerPage
contentSectionAttached: css`
${() => layoutMixins.contentSection}
min-width: max-content;
/* max-width: none; */
`,
// Section that defines its own horizontal scrollArea and does not scroll with the outer scrollArea
// Use within contentContainer or contentContainerPage
contentSectionDetached: css`
${() => layoutMixins.contentSection}
${() => layoutMixins.stickyLeft}
max-width: min(var(--content-container-width), var(--content-max-width));
transition: max-width 0.3s var(--ease-out-expo);
`,
// Section that defines its own horizontal scrollArea and does not scroll with the outer scrollArea
// Use within contentContainer or contentContainerPage
contentSectionDetachedScrollable: css`
${() => layoutMixins.contentSectionDetached}
${() => layoutMixins.scrollArea}
`,
sticky: css`
/* Params */
--stickyArea-totalInsetTop: ;
--stickyArea-totalInsetBottom: ;
--stickyArea-totalInsetLeft: ;
--stickyArea-totalInsetRight: ;
z-index: 1;
position: sticky;
inset: 0;
top: var(--stickyArea-totalInsetTop, 0px);
bottom: var(--stickyArea-totalInsetBottom, 0px);
left: var(--stickyArea-totalInsetLeft, 0px);
right: var(--stickyArea-totalInsetRight, 0px);
backdrop-filter: blur(10px);
`,
// An item within a horizontally scrollable container that is unaffected by the horizontal scroll position.
// Use when a sibling is horizontally overflowing (e.g. a table with many columns).
stickyLeft: css`
z-index: 1;
position: sticky;
left: var(--stickyArea-totalInsetLeft, 0px);
transition: left 0.3s var(--ease-out-expo);
`,
stickyRight: css`
z-index: 1;
position: sticky;
right: var(--stickyArea-totalInsetRight, 0px);
transition: right 0.3s var(--ease-out-expo);
`,
// Creates a scrollable container that can contain sticky and/or scroll-snapped descendants.
scrollArea: css`
/* Params */
--scrollArea-height: 100%;
--scrollArea-width: 100%;
/* Rules */
isolation: isolate;
height: var(--scrollArea-height);
position: relative;
overflow: auto;
/* scroll-snap-type: both proximity; */
@media (prefers-reduced-motion: no-preference) {
scroll-behavior: smooth;
}
`,
/**
* A container for positioning sticky items using simulated padding, width, height and gap properties.
* Use on layoutMixins.scrollArea or as a descendant of layoutMixins.scrollArea
*/
stickyArea: css`
/* Params */
--stickyArea-paddingTop: ;
--stickyArea-height: var(--scrollArea-height, 100%);
--stickyArea-topHeight: ;
--stickyArea-topGap: ;
--stickyArea-bottomGap: ;
--stickyArea-paddingBottom: ;
--stickyArea-bottomHeight: ;
--stickyArea-paddingLeft: ;
--stickyArea-width: var(--scrollArea-width, 100%);
--stickyArea-leftWidth: ;
--stickyArea-leftGap: ;
--stickyArea-paddingRight: ;
--stickyArea-rightGap: ;
--stickyArea-rightWidth: ;
--stickyArea-background: ;
/* Computed */
--stickyArea-totalInsetTop: var(--stickyArea-paddingTop);
--stickyArea-totalInsetBottom: var(--stickyArea-paddingBottom);
--stickyArea-innerHeight: calc(
var(--stickyArea-height, 100%) -
(
var(--stickyArea-paddingTop, 0px) + var(--stickyArea-topHeight, 0px) +
var(--stickyArea-topGap, 0px)
) -
(
var(--stickyArea-paddingBottom, 0px) + var(--stickyArea-bottomHeight, 0px) +
var(--stickyArea-bottomGap, 0px)
)
);
--stickyArea-totalInsetLeft: var(--stickyArea-paddingLeft);
--stickyArea-totalInsetRight: var(--stickyArea-paddingRight);
--stickyArea-innerWidth: calc(
var(--stickyArea-width, 100%) -
(
var(--stickyArea-paddingLeft, 0px) + var(--stickyArea-leftWidth, 0px) +
var(--stickyArea-leftGap, 0px)
) -
(
var(--stickyArea-paddingRight, 0px) + var(--stickyArea-rightWidth, 0px) +
var(--stickyArea-rightGap, 0px)
)
);
/* Rules */
/* scroll-padding-top: var(--stickyArea-topHeight);
scroll-padding-bottom: var(--stickyArea-bottomHeight); */
/* scroll-padding-top: var(--stickyArea-totalInsetTop);
scroll-padding-bottom: var(--stickyArea-totalInsetBottom); */
/* scroll-padding-block-end: 4rem; */
/* Firefox: opaque background required for backdrop-filter to work */
background: var(--stickyArea-background, var(--color-layer-2));
`,
/**
* A sticky area that may contain nested sticky areas.
* Use with layoutMixins.scrollArea or as a descendant of layoutMixins.scrollArea
*/
stickyArea0: css`
/* Params */
--stickyArea0-paddingTop: 0px;
--stickyArea0-topHeight: 0px;
--stickyArea0-topGap: 0px;
--stickyArea0-bottomGap: 0px;
--stickyArea0-bottomHeight: 0px;
--stickyArea0-paddingBottom: 0px;
--stickyArea0-paddingLeft: 0px;
--stickyArea0-leftWidth: 0px;
--stickyArea0-leftGap: 0px;
--stickyArea0-rightGap: 0px;
--stickyArea0-rightWidth: 0px;
--stickyArea0-paddingRight: 0px;
--stickyArea0-background: ;
/* Computed */
--stickyArea0-height: var(--scrollArea-height, 100%);
--stickyArea0-totalInsetTop: var(--stickyArea0-paddingTop);
--stickyArea0-totalInsetBottom: var(--stickyArea0-paddingBottom);
--stickyArea0-width: var(--scrollArea-width, 100%);
--stickyArea0-totalInsetLeft: var(--stickyArea0-paddingLeft);
--stickyArea0-totalInsetRight: var(--stickyArea0-paddingRight);
/* Rules */
${() => layoutMixins.stickyArea}
--stickyArea-height: var(--stickyArea0-height);
--stickyArea-totalInsetTop: var(--stickyArea0-totalInsetTop);
--stickyArea-paddingTop: var(--stickyArea0-paddingTop);
--stickyArea-topHeight: var(--stickyArea0-topHeight);
--stickyArea-topGap: var(--stickyArea0-topGap);
--stickyArea-innerHeight: var(--stickyArea1-height);
--stickyArea-bottomGap: var(--stickyArea0-bottomGap);
--stickyArea-bottomHeight: var(--stickyArea0-bottomHeight);
--stickyArea-paddingBottom: var(--stickyArea0-paddingBottom);
--stickyArea-totalInsetBottom: var(--stickyArea0-totalInsetBottom);
--stickyArea-width: var(--stickyArea0-width);
--stickyArea-totalInsetLeft: var(--stickyArea0-totalInsetLeft);
--stickyArea-paddingLeft: var(--stickyArea0-paddingLeft);
--stickyArea-leftWidth: var(--stickyArea0-leftWidth);
--stickyArea-leftGap: var(--stickyArea0-leftGap);
--stickyArea-innerWidth: var(--stickyArea1-width);
--stickyArea-rightGap: var(--stickyArea0-rightGap);
--stickyArea-rightWidth: var(--stickyArea0-rightWidth);
--stickyArea-paddingRight: var(--stickyArea0-paddingRight);
--stickyArea-totalInsetRight: var(--stickyArea0-totalInsetRight);
--stickyArea-background: var(--stickyArea0-background);
`,
/**
* A nested sticky area that calculates sticky item inset values cumulatively.
* Use as a descendant of layoutMixins.stickyArea0
*/
stickyArea1: css`
/* Params */
--stickyArea1-paddingTop: 0px;
--stickyArea1-topHeight: 0px;
--stickyArea1-topGap: 0px;
--stickyArea1-bottomGap: 0px;
--stickyArea1-bottomHeight: 0px;
--stickyArea1-paddingBottom: 0px;
--stickyArea1-paddingLeft: 0px;
--stickyArea1-leftWidth: 0px;
--stickyArea1-leftGap: 0px;
--stickyArea1-rightGap: 0px;
--stickyArea1-rightWidth: 0px;
--stickyArea1-paddingRight: 0px;
--stickyArea1-background: ;
/* Computed */
--stickyArea1-height: calc(
var(--stickyArea0-height) -
(var(--stickyArea0-paddingTop) + var(--stickyArea0-topHeight) + var(--stickyArea0-topGap)) -
(
var(--stickyArea0-paddingBottom) + var(--stickyArea0-bottomHeight) +
var(--stickyArea0-bottomGap)
)
);
--stickyArea1-totalInsetTop: calc(
var(--stickyArea0-totalInsetTop) + var(--stickyArea0-topHeight) + var(--stickyArea0-topGap) +
var(--stickyArea1-paddingTop)
);
--stickyArea1-totalInsetBottom: calc(
var(--stickyArea0-totalInsetBottom) + var(--stickyArea0-bottomHeight) +
var(--stickyArea0-bottomGap) + var(--stickyArea1-paddingBottom)
);
--stickyArea1-width: calc(
var(--stickyArea0-width) -
(var(--stickyArea0-paddingLeft) + var(--stickyArea0-leftWidth) + var(--stickyArea0-leftGap)) -
(
var(--stickyArea0-paddingRight) + var(--stickyArea0-rightWidth) +
var(--stickyArea0-rightGap)
)
);
--stickyArea1-totalInsetLeft: calc(
var(--stickyArea0-totalInsetLeft) + var(--stickyArea0-leftWidth) + var(--stickyArea0-leftGap) +
var(--stickyArea1-paddingLeft)
);
--stickyArea1-totalInsetRight: calc(
var(--stickyArea0-totalInsetRight) + var(--stickyArea0-rightWidth) +
var(--stickyArea0-rightGap) + var(--stickyArea1-paddingRight)
);
/* Rules */
${() => layoutMixins.stickyArea}
--stickyArea-height: var(--stickyArea1-height);
--stickyArea-totalInsetTop: var(--stickyArea1-totalInsetTop);
--stickyArea-paddingTop: var(--stickyArea1-paddingTop);
--stickyArea-topHeight: var(--stickyArea1-topHeight);
--stickyArea-topGap: var(--stickyArea1-topGap);
--stickyArea-innerHeight: var(--stickyArea2-height);
--stickyArea-bottomGap: var(--stickyArea1-bottomGap);
--stickyArea-bottomHeight: var(--stickyArea1-bottomHeight);
--stickyArea-paddingBottom: var(--stickyArea1-paddingBottom);
--stickyArea-totalInsetBottom: var(--stickyArea1-totalInsetBottom);
--stickyArea-width: var(--stickyArea1-width);
--stickyArea-totalInsetLeft: var(--stickyArea1-totalInsetLeft);
--stickyArea-paddingLeft: var(--stickyArea1-paddingLeft);
--stickyArea-leftWidth: var(--stickyArea1-leftWidth);
--stickyArea-leftGap: var(--stickyArea1-leftGap);
--stickyArea-innerWidth: var(--stickyArea2-width);
--stickyArea-rightGap: var(--stickyArea1-rightGap);
--stickyArea-rightWidth: var(--stickyArea1-rightWidth);
--stickyArea-paddingRight: var(--stickyArea1-paddingRight);
--stickyArea-totalInsetRight: var(--stickyArea1-totalInsetRight);
--stickyArea-background: var(--stickyArea1-background);
`,
/**
* A nested sticky area that calculates sticky item inset values cumulatively.
* Use as a descendant of layoutMixins.stickyArea1
*/
stickyArea2: css`
/* Params */
--stickyArea2-paddingTop: 0px;
--stickyArea2-topHeight: 0px;
--stickyArea2-topGap: 0px;
--stickyArea2-bottomGap: 0px;
--stickyArea2-bottomHeight: 0px;
--stickyArea2-paddingBottom: 0px;
--stickyArea2-paddingLeft: 0px;
--stickyArea2-leftWidth: 0px;
--stickyArea2-leftGap: 0px;
--stickyArea2-rightGap: 0px;
--stickyArea2-rightWidth: 0px;
--stickyArea2-paddingRight: 0px;
--stickyArea2-background: ;
/* Computed */
--stickyArea2-height: calc(
var(--stickyArea1-height) -
(var(--stickyArea1-paddingTop) + var(--stickyArea1-topHeight) + var(--stickyArea1-topGap)) -
(
var(--stickyArea1-paddingBottom) + var(--stickyArea1-bottomHeight) +
var(--stickyArea1-bottomGap)
)
);
--stickyArea2-totalInsetTop: calc(
var(--stickyArea1-totalInsetTop) + var(--stickyArea1-topHeight) + var(--stickyArea1-topGap) +
var(--stickyArea2-paddingTop)
);
--stickyArea2-totalInsetBottom: calc(
var(--stickyArea1-totalInsetBottom) + var(--stickyArea1-bottomHeight) +
var(--stickyArea1-bottomGap) + var(--stickyArea2-paddingBottom)
);
--stickyArea2-width: calc(
var(--stickyArea1-width) -
(var(--stickyArea1-paddingLeft) + var(--stickyArea1-leftWidth) + var(--stickyArea1-leftGap)) -
(
var(--stickyArea1-paddingRight) + var(--stickyArea1-rightWidth) +
var(--stickyArea1-rightGap)
)
);
--stickyArea2-totalInsetLeft: calc(
var(--stickyArea1-totalInsetLeft) + var(--stickyArea1-leftWidth) + var(--stickyArea1-leftGap) +
var(--stickyArea2-paddingLeft)
);
--stickyArea2-totalInsetRight: calc(
var(--stickyArea1-totalInsetRight) + var(--stickyArea1-rightWidth) +
var(--stickyArea1-rightGap) + var(--stickyArea2-paddingRight)
);
/* Rules */
${() => layoutMixins.stickyArea}
--stickyArea-height: var(--stickyArea2-height);
--stickyArea-totalInsetTop: var(--stickyArea2-totalInsetTop);
--stickyArea-paddingTop: var(--stickyArea2-paddingTop);
--stickyArea-topHeight: var(--stickyArea2-topHeight);
--stickyArea-topGap: var(--stickyArea2-topGap);
--stickyArea-innerHeight: var(--stickyArea3-height);
--stickyArea-bottomGap: var(--stickyArea2-bottomGap);
--stickyArea-bottomHeight: var(--stickyArea2-bottomHeight);
--stickyArea-paddingBottom: var(--stickyArea2-paddingBottom);
--stickyArea-totalInsetBottom: var(--stickyArea2-totalInsetBottom);
--stickyArea-width: var(--stickyArea2-width);
--stickyArea-totalInsetLeft: var(--stickyArea2-totalInsetLeft);
--stickyArea-paddingLeft: var(--stickyArea2-paddingLeft);
--stickyArea-leftWidth: var(--stickyArea2-leftWidth);
--stickyArea-leftGap: var(--stickyArea2-leftGap);
--stickyArea-innerWidth: var(--stickyArea3-width);
--stickyArea-rightGap: var(--stickyArea2-rightGap);
--stickyArea-rightWidth: var(--stickyArea2-rightWidth);
--stickyArea-paddingRight: var(--stickyArea2-paddingRight);
--stickyArea-totalInsetRight: var(--stickyArea2-totalInsetRight);
--stickyArea-background: var(--stickyArea2-background);
`,
/**
* A nested sticky area that calculates sticky item inset values cumulatively.
* Use as a descendant of layoutMixins.stickyArea2
*/
stickyArea3: css`
/* Params */
--stickyArea3-paddingTop: 0px;
--stickyArea3-topHeight: 0px;
--stickyArea3-topGap: 0px;
--stickyArea3-bottomGap: 0px;
--stickyArea3-bottomHeight: 0px;
--stickyArea3-paddingBottom: 0px;
--stickyArea3-paddingLeft: 0px;
--stickyArea3-leftWidth: 0px;
--stickyArea3-leftGap: 0px;
--stickyArea3-rightGap: 0px;
--stickyArea3-rightWidth: 0px;
--stickyArea3-paddingRight: 0px;
--stickyArea3-background: ;
/* Computed */
--stickyArea3-height: calc(
var(--stickyArea2-height) -
(var(--stickyArea2-paddingTop) + var(--stickyArea2-topHeight) + var(--stickyArea2-topGap)) -
(
var(--stickyArea2-paddingBottom) + var(--stickyArea2-bottomHeight) +
var(--stickyArea2-bottomGap)
)
);
--stickyArea3-totalInsetTop: calc(
var(--stickyArea2-totalInsetTop) + var(--stickyArea2-topHeight) + var(--stickyArea2-topGap) +
var(--stickyArea3-paddingTop)
);
--stickyArea3-totalInsetBottom: calc(
var(--stickyArea2-totalInsetBottom) + var(--stickyArea2-bottomHeight) +
var(--stickyArea2-bottomGap) + var(--stickyArea3-paddingBottom)
);
--stickyArea3-width: calc(
var(--stickyArea2-width) -
(var(--stickyArea2-paddingLeft) + var(--stickyArea2-leftWidth) + var(--stickyArea2-leftGap)) -
(
var(--stickyArea2-paddingRight) + var(--stickyArea2-rightWidth) +
var(--stickyArea2-rightGap)
)
);
--stickyArea3-totalInsetLeft: calc(
var(--stickyArea2-totalInsetLeft) + var(--stickyArea2-leftWidth) + var(--stickyArea2-leftGap) +
var(--stickyArea3-paddingLeft)
);
--stickyArea3-totalInsetRight: calc(
var(--stickyArea2-totalInsetRight) + var(--stickyArea2-rightWidth) +
var(--stickyArea2-rightGap) + var(--stickyArea3-paddingRight)
);
/* Rules */
${() => layoutMixins.stickyArea}
--stickyArea-height: var(--stickyArea3-height);
--stickyArea-totalInsetTop: var(--stickyArea3-totalInsetTop);
--stickyArea-paddingTop: var(--stickyArea3-paddingTop);
--stickyArea-topHeight: var(--stickyArea3-topHeight);
--stickyArea-topGap: var(--stickyArea3-topGap);
--stickyArea-innerHeight: var(--stickyArea4-height);
--stickyArea-bottomGap: var(--stickyArea3-bottomGap);
--stickyArea-bottomHeight: var(--stickyArea3-bottomHeight);
--stickyArea-paddingBottom: var(--stickyArea3-paddingBottom);
--stickyArea-totalInsetBottom: var(--stickyArea3-totalInsetBottom);
--stickyArea-width: var(--stickyArea3-width);
--stickyArea-totalInsetLeft: var(--stickyArea3-totalInsetLeft);
--stickyArea-paddingLeft: var(--stickyArea3-paddingLeft);
--stickyArea-leftWidth: var(--stickyArea3-leftWidth);
--stickyArea-leftGap: var(--stickyArea3-leftGap);
--stickyArea-innerWidth: var(--stickyArea4-width);
--stickyArea-rightGap: var(--stickyArea3-rightGap);
--stickyArea-rightWidth: var(--stickyArea3-rightWidth);
--stickyArea-paddingRight: var(--stickyArea3-paddingRight);
--stickyArea-totalInsetRight: var(--stickyArea3-totalInsetRight);
--stickyArea-background: var(--stickyArea3-background);
`,
// Use as a descendant of layoutMixins.stickyArea
stickyHeader: css`
${() => layoutMixins.sticky}
min-height: var(--stickyArea-topHeight);
flex-shrink: 0;
${() => layoutMixins.scrollSnapItem}
`,
// Use as a descendant of layoutMixins.stickyArea
stickyFooter: css`
${() => layoutMixins.sticky}
min-height: var(--stickyArea-bottomHeight);
flex-shrink: 0;
${() => layoutMixins.scrollSnapItem}
`,
// Use as a descendant of layoutMixins.scrollArea
scrollSnapItem: css`
scroll-snap-align: start;
scroll-margin-top: var(--stickyArea-totalInsetTop);
scroll-margin-bottom: var(--stickyArea-totalInsetBottom);
scroll-margin-left: var(--stickyArea-totalInsetLeft);
scroll-margin-right: var(--stickyArea-totalInsetRight);
`,
// Use with layoutMixins.stickyFooter
withStickyFooterBackdrop: css`
/* Params */
--stickyFooterBackdrop-outsetY: ;
--stickyFooterBackdrop-outsetX: ;
/* Rules */
backdrop-filter: none;
&:before {
content: '';
z-index: -1;
position: absolute;
inset: calc(-1 * var(--stickyFooterBackdrop-outsetY, 0px))
calc(-1 * var(--stickyFooterBackdrop-outsetX, 0px));
background: linear-gradient(transparent, var(--stickyArea-background));
pointer-events: none;
}
`,
withOuterBorder: css`
box-shadow: 0 0 0 var(--border-width) var(--border-color);
`,
// Show "borders" between and around grid/flex items using gap + box-shadow
// Apply to element with display: grid or display: flex
withOuterAndInnerBorders: css`
--border-width: var(--default-border-width);
--border-color: var(--color-border);
gap: var(--border-width);
> * {
${() => layoutMixins.withOuterBorder}
}
`,
withInnerHorizontalBorders: css`
--border-width: var(--default-border-width);
--border-color: var(--color-border);
gap: var(--border-width);
> * {
box-shadow: 0 var(--border-width) var(--border-color),
0 calc(-1 * var(--border-width)) var(--border-color);
}
`,
// An outer border with a dynamic radius + clip effect based on a "max" width and the current container width.
withOuterBorderClipped: css`
/* Parameters */
--bordered-content-outer-container-width: inherit;
--bordered-content-max-width: inherit;
--bordered-content-border-radius: 1rem;
--border-width: var(--default-border-width);
--border-color: var(--color-border);
/* Computed */
--computed-radius: clamp(
0px,
var(--bordered-content-outer-container-width) - var(--bordered-content-max-width),
var(--bordered-content-border-radius)
);
/* Rules */
clip-path: inset(
calc(-1 * var(--border-width)) round calc(var(--computed-radius) + var(--border-width))
);
overflow-clip-margin: var(--border-width);
position: relative;
&:after {
content: '';
z-index: 2;
position: absolute;
inset: 0;
border-radius: var(--computed-radius);
${() => layoutMixins.withOuterBorder}
pointer-events: none;
}
`,
textOverflow: css`
display: inline-block;
overflow-x: auto;
&:not(:hover) {
text-overflow: ellipsis;
scroll-snap-type: x proximity;
// Reset scroll position when mouse leaves
animation: ${keyframes`
from {
zoom: 0.0001;
}
`} 0.1ms;
}
* {
display: inline !important;
}
scrollbar-width: none;
::-webkit-scrollbar {
display: none;
}
`,
perspectiveArea: css`
perspective: 100rem;
transform-style: preserve-3d;
`,
absolute: css`
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
`,
expandingColumnWithStickyFooter: css`
// Expand if within a flexColumn
flex: 1;
display: grid;
grid-template:
minmax(0, 1fr)
auto
/ minmax(0, 1fr);
align-items: start;
> :last-child {
${() => layoutMixins.stickyFooter}
${() => layoutMixins.withStickyFooterBackdrop}
}
`,
noPointerEvents: css`
pointer-events: none;
> * {
pointer-events: initial;
}
`,
centered: css`
display: grid;
grid-template-columns: minmax(0, 1fr);
min-height: 100%;
place-items: center;
`,
};
+238
View File
@@ -0,0 +1,238 @@
import { css, keyframes } from 'styled-components';
import { layoutMixins } from './layoutMixins';
export const popoverMixins = {
triggerWithGrid: css`
display: grid;
overflow: hidden;
border: 1px solid var(--color-layer-6);
`,
trigger: css`
--trigger-padding: 0.5em 1em;
--trigger-radius: 0.5em;
--trigger-border: none;
--trigger-height: ;
--trigger-backgroundColor: var(--color-layer-2);
--trigger-textColor: var(--color-text-0);
--trigger-open-backgroundColor: var(--color-layer-1);
--trigger-open-textColor: var(--color-text-2);
--trigger-active-filter: brightness(0.9);
--trigger-hover-filter: brightness(1.1);
display: flex;
align-items: center;
gap: 0.5em;
height: var(--trigger-height);
padding: var(--trigger-padding);
border-radius: var(--trigger-radius);
border: var(--trigger-border);
background-color: var(--trigger-backgroundColor);
color: var(--trigger-textColor);
cursor: pointer;
&:hover:not(:disabled) {
filter: var(--trigger-hover-filter);
}
&:active:not(:disabled) {
filter: var(--trigger-active-filter);
}
&[data-state='open'] {
background-color: var(--trigger-open-backgroundColor);
color: var(--trigger-open-textColor);
}
`,
searchSelectTrigger: css`
--trigger-backgroundColor: var(--color-layer-4);
--trigger-textColor: var(--color-text-0);
--trigger-open-backgroundColor: var(--color-layer-4);
--trigger-open-textColor: var(--color-text-2);
${layoutMixins.spacedRow}
grid-template-columns: 1fr auto;
gap: 0;
border: 1px solid var(--color-layer-6);
`,
marketDropdownTrigger: css`
--trigger-radius: 0;
--trigger-open-backgroundColor: var(--color-layer-2);
display: grid;
overflow: hidden;
`,
popover: css`
--border-width: var(--default-border-width);
--border-color: var(--color-border);
--popover-padding: 0;
--popover-margin: 0;
--popover-width: auto;
--popover-radius: 0.5em;
--popover-backgroundColor: var(--color-layer-3);
--popover-textColor: ;
--popover-shadow-color: var(--color-border);
--popover-shadow-size: 0;
--popover-backdrop-filter: saturate(120%) blur(6px);
--popover-origin: var(--radix-popper-transform-origin);
--popover-border: none;
z-index: 1;
color: var(--popover-textColor, inherit);
padding: var(--popover-padding);
margin: var(--popover-margin);
width: var(--popover-width);
overflow: hidden;
backdrop-filter: var(--popover-backdrop-filter);
background-color: var(--popover-backgroundColor);
/* clip-path: inset(0 round calc(var(--popover-radius))); */
border-radius: var(--popover-radius);
box-shadow: 0 0 0 var(--popover-shadow-size) var(--popover-shadow-color);
border: var(--popover-border);
transform-origin: var(--popover-origin);
`,
popoverAnimation: css`
--popover-animation-duration: 0.2s;
--popover-closed-height: 0;
transform-origin: var(--popover-origin);
@media (prefers-reduced-motion: no-preference) {
&[data-state='open'],
&[data-state='instant-open'], /* Tooltip */
&[data-state='delayed-open'] /* Tooltip */ {
animation: ${keyframes`
from {
opacity: 0;
filter: blur(2px);
backdrop-filter: none;
box-shadow: 0 0 0 transparent;
}
/* Don't interfere with Floating UI positioning */
0.01% {
max-height: var(--popover-closed-height);
scale: 0.9;
}
`} var(--popover-animation-duration) var(--ease-out-expo);
}
&[data-state='closed'] {
animation: ${keyframes`
to {
opacity: 0;
filter: blur(2px);
backdrop-filter: none;
box-shadow: 0 0 0 transparent;
max-height: var(--popover-closed-height);
scale: 0.9;
}
`} var(--popover-animation-duration);
pointer-events: none;
}
}
`,
// Use with container mixin to position popover overlay within a stacking context
backdropOverlay: css`
--popover-overlay-blur-duration: 0.2s;
&:after {
content: '';
position: fixed;
inset: 0;
/* position: absolute;
inset: -100vh -100vw; */
z-index: -2;
pointer-events: none;
&:hover {
will-change: backdrop-filter;
}
@media (prefers-reduced-motion: no-preference) {
transition: backdrop-filter var(--popover-overlay-blur-duration);
}
}
&[data-state='open']:after {
backdrop-filter: blur(6px);
}
`,
item: css`
--item-font-size: inherit;
--item-checked-backgroundColor: var(--color-layer-2);
--item-checked-textColor: currentColor;
--item-highlighted-backgroundColor: var(--color-layer-2);
--item-highlighted-textColor: var(--color-text-2);
--item-radius: 0px;
--item-padding: 0.5em 1em;
display: flex;
justify-content: space-between;
align-items: center;
gap: 0.5em;
padding: var(--item-padding);
border-radius: var(--item-radius);
font-size: var(--item-font-size);
transition: 0.1s;
cursor: pointer;
&[data-disabled] {
opacity: 0.25;
cursor: not-allowed;
}
&:not([data-disabled]) {
/* &:hover, */
/* :not(:has(* > [data-highlighted])) > &:hover, */
&[data-radix-collection-item]:hover, // @radix-ui/react-navigation-menu
/* &:focus-visible, */
&[aria-selected="true"], // cmdk
&[data-highlighted] // @radix-ui
{
filter: brightness(1.1);
background-color: var(--item-highlighted-backgroundColor);
color: var(--item-highlighted-textColor, var(--trigger-textColor, inherit)) !important;
outline: none;
}
}
&[data-state='checked'], // @radix-ui
&[aria-current='page'] // <a>
{
background-color: var(
--item-checked-backgroundColor,
var(--trigger-selected-color, var(--popover-backgroundColor, inherit))
);
color: var(--item-checked-textColor, var(--trigger-textColor, inherit));
}
`,
};
+6
View File
@@ -0,0 +1,6 @@
import { PAGE_REM } from '@/constants/page';
export const sidebarBreakpoints = {
sidebarCollapse: `(max-width: calc(${PAGE_REM.maxContentWidth} + ${PAGE_REM.collapsedSidebarWidth}))`,
sidebarOpen: `(max-width: calc(${PAGE_REM.maxContentWidth} + ${PAGE_REM.sidebarWidth}))`,
};
+54
View File
@@ -0,0 +1,54 @@
import {
css,
type FlattenInterpolation,
type FlattenSimpleInterpolation,
type ThemeProps,
} from 'styled-components';
import breakpoints from './breakpoints';
import { layoutMixins } from './layoutMixins';
export const tableMixins: Record<
string,
FlattenSimpleInterpolation | FlattenInterpolation<ThemeProps<any>>
> = {
/** Use as a direct child of <th> or <td> */
cellContent: css`
${layoutMixins.row}
gap: 0.5em;
color: var(--color-text-1);
text-align: var(--table-cell-currentAlign);
justify-content: var(--table-cell-currentAlign);
`,
/** Use as a direct child of tableMixins.cellContent */
cellContentColumn: css`
${layoutMixins.rowColumn}
color: var(--color-text-1);
> * {
justify-content: var(--table-cell-currentAlign);
}
> :nth-child(2) {
font: var(--font-mini-book);
color: var(--color-text-0);
margin-top: 0.125rem;
}
`,
/** Use as a direct child of <th> */
headerCellContent: css`
${() => tableMixins.cellContent}
color: var(--tableHeader-textColor, var(--color-text-0));
span:nth-child(2) {
:before {
content: ' / ';
}
}
`,
};
+88
View File
@@ -0,0 +1,88 @@
/* Constants */
:root {
--fontFamily-base: "Satoshi", system-ui, -apple-system, Helvetica, Arial, sans-serif;
--fontFamily-monospace: Courier, monospace, var(--fontFamily-base);
--fontWeight-base-0: 450;
--fontWeight-base-1: 500;
--fontWeight-base-2: 700;
--letter-spacing-base: -0.02em;
/* New Typography system */
--fontSize-tiny: 0.625rem; /* 10px/11px */
--fontSize-mini: 0.75rem; /* 12px/13px */
--fontSize-small: 0.8438rem; /* 13.5px/14.5px */
--fontSize-base: 0.9375rem; /* 15px/16px */
--fontSize-medium: 1.125rem; /* 18px/18px */
--fontSize-large: 1.375rem; /* 22px/22px */
--fontSize-extra: 1.75rem; /* 28px/25px */
--fontWeight-regular: 400;
--fontWeight-book: 450;
--fontWeight-medium: 500;
--font-tiny-regular: var(--fontWeight-regular) var(--fontSize-tiny) var(--fontFamily-base);
--font-tiny-book: var(--fontWeight-book) var(--fontSize-tiny) var(--fontFamily-base);
--font-tiny-medium: var(--fontWeight-medium) var(--fontSize-tiny) var(--fontFamily-base);
--font-mini-regular: var(--fontWeight-regular) var(--fontSize-mini) var(--fontFamily-base);
--font-mini-book: var(--fontWeight-book) var(--fontSize-mini) var(--fontFamily-base);
--font-mini-medium: var(--fontWeight-medium) var(--fontSize-mini) var(--fontFamily-base);
--font-small-regular: var(--fontWeight-regular) var(--fontSize-small) var(--fontFamily-base);
--font-small-book: var(--fontWeight-book) var(--fontSize-small) var(--fontFamily-base);
--font-small-medium: var(--fontWeight-medium) var(--fontSize-small) var(--fontFamily-base);
--font-base-regular: var(--fontWeight-regular) var(--fontSize-base) var(--fontFamily-base);
--font-base-book: var(--fontWeight-book) var(--fontSize-base) var(--fontFamily-base);
--font-base-medium: var(--fontWeight-medium) var(--fontSize-base) var(--fontFamily-base);
--font-medium-regular: var(--fontWeight-regular) var(--fontSize-medium) var(--fontFamily-base);
--font-medium-book: var(--fontWeight-book) var(--fontSize-medium) var(--fontFamily-base);
--font-medium-medium: var(--fontWeight-medium) var(--fontSize-medium) var(--fontFamily-base);
--font-large-regular: var(--fontWeight-regular) var(--fontSize-large) var(--fontFamily-base);
--font-large-book: var(--fontWeight-book) var(--fontSize-large) var(--fontFamily-base);
--font-large-medium: var(--fontWeight-medium) var(--fontSize-large) var(--fontFamily-base);
--font-extra-regular: var(--fontWeight-regular) var(--fontSize-extra) var(--fontFamily-base);
--font-extra-book: var(--fontWeight-book) var(--fontSize-extra) var(--fontFamily-base);
--font-extra-medium: var(--fontWeight-medium) var(--fontSize-extra) var(--fontFamily-base);
--fontFeature-monoNumbers: 'tnum' on, 'lnum' on, 'zero' 1;
}
@media screen and (max-width: 64rem) {
:root {
--fontSize-tiny: 0.6875rem;
--fontSize-mini: 0.8125rem;
--fontSize-small: 0.9063rem;
--fontSize-base: 1rem;
--fontSize-medium: 1.125rem;
--fontSize-large: 1.375rem;
--fontSize-extra: 1.5625rem;
}
}
/* Global defaults */
:root {
font-family: var(--fontFamily-base);
font-weight: var(--fontWeight-base-0);
letter-spacing: var(--letter-spacing-base);
font-size: 1em;
line-height: 1.3;
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: 100%;
}
* {
font: inherit;
}
+79
View File
@@ -0,0 +1,79 @@
import type { Story } from '@ladle/react';
import styled, { type AnyStyledComponent } from 'styled-components';
import { layoutMixins } from '@/styles/layoutMixins';
import { StoryWrapper } from '.ladle/components';
const FONT_SIZES = ['tiny', 'mini', 'small', 'base', 'medium', 'large', 'extra'];
export const TextStory: Story = () => (
<StoryWrapper>
<Styled.Table>
<thead>
<tr>
<th>Regular(-)</th>
<th>Book</th>
<th>Medium(+)</th>
<th>Mono(#)</th>
</tr>
</thead>
<tbody>
{FONT_SIZES.map((size) => (
<tr key={size}>
<td
style={{
font: `var(--font-${size}-regular)`,
}}
>{`${size}-`}</td>
<td
style={{
font: `var(--font-${size}-book)`,
}}
>
{size}
</td>
<td
style={{
font: `var(--font-${size}-medium)`,
}}
>{`${size}+`}</td>
<td
style={{
font: `var(--font-${size}-book)`,
fontFeatureSettings: 'var(--fontFeature-monoNumbers)',
}}
>
123,456
</td>
</tr>
))}
</tbody>
</Styled.Table>
</StoryWrapper>
);
const Styled: Record<string, AnyStyledComponent> = {};
Styled.Table = styled.table`
width: 100%;
text-align: left;
border-collapse: separate;
border-spacing: 0 var(--border-width);
--default-border-width: 1px;
${layoutMixins.withOuterAndInnerBorders}
thead,
tbody {
${layoutMixins.withInnerHorizontalBorders}
}
th {
padding: 0.5rem 0.25rem;
}
td {
padding: 0.25rem;
}
`;
+26
View File
@@ -0,0 +1,26 @@
import {
css,
type FlattenInterpolation,
type FlattenSimpleInterpolation,
type ThemeProps,
} from 'styled-components';
export const tradeViewMixins: Record<
string,
FlattenSimpleInterpolation | FlattenInterpolation<ThemeProps<any>>
> = {
horizontalTable: css`
--tableCell-padding: 0.5rem 1rem;
--tableHeader-backgroundColor: var(--color-layer-2);
--tableRow-backgroundColor: var(--color-layer-2);
font: var(--font-mini-book);
tbody {
font: var(--font-small-book);
}
thead tr {
box-shadow: none;
}
`,
};
+5
View File
@@ -0,0 +1,5 @@
w3m-modal {
isolation: isolate;
position: relative;
z-index: 2;
}