Initial commit
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
`,
|
||||
};
|
||||
@@ -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})`,
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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]);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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.
@@ -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);
|
||||
}
|
||||
`,
|
||||
};
|
||||
@@ -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);
|
||||
}
|
||||
`,
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
import breakpoints from './breakpoints';
|
||||
import { sidebarBreakpoints } from './sidebar';
|
||||
|
||||
export { breakpoints, sidebarBreakpoints };
|
||||
@@ -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;
|
||||
`,
|
||||
};
|
||||
@@ -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));
|
||||
}
|
||||
`,
|
||||
};
|
||||
@@ -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}))`,
|
||||
};
|
||||
@@ -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: ' / ';
|
||||
}
|
||||
}
|
||||
`,
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
`;
|
||||
@@ -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;
|
||||
}
|
||||
`,
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
w3m-modal {
|
||||
isolation: isolate;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
Reference in New Issue
Block a user