Make twilight/mocha scrollbar tracks transparent so the editor no longer shows a vertical strip, size standalone emoji to 100px, loosen zalgo clipping with padded overflow, and handle insertReplacementText via onDOMBeforeInput so Slate does not insert the correction twice.
307 lines
6.4 KiB
TypeScript
307 lines
6.4 KiB
TypeScript
import { style } from '@vanilla-extract/css';
|
|
import { recipe } from '@vanilla-extract/recipes';
|
|
import { color, config, DefaultReset, toRem } from 'folds';
|
|
import { ContainerColor } from './ContainerColor.css';
|
|
|
|
export const MarginSpaced = style({
|
|
marginBottom: config.space.S200,
|
|
marginTop: config.space.S200,
|
|
selectors: {
|
|
'&:first-child': {
|
|
marginTop: 0,
|
|
},
|
|
'&:last-child': {
|
|
marginBottom: 0,
|
|
},
|
|
},
|
|
});
|
|
|
|
export const Paragraph = style([
|
|
DefaultReset,
|
|
{
|
|
// Zalgo clipping is handled by MessageTextBody padding + overflow
|
|
lineHeight: '1.5',
|
|
},
|
|
]);
|
|
|
|
export const Heading = style([
|
|
DefaultReset,
|
|
MarginSpaced,
|
|
{
|
|
marginTop: config.space.S400,
|
|
lineHeight: '1.5',
|
|
selectors: {
|
|
'&:first-child': {
|
|
marginTop: 0,
|
|
},
|
|
},
|
|
},
|
|
]);
|
|
|
|
export const BlockQuote = style([
|
|
DefaultReset,
|
|
MarginSpaced,
|
|
{
|
|
paddingLeft: config.space.S200,
|
|
borderLeft: `${config.borderWidth.B700} solid ${color.SurfaceVariant.ContainerLine}`,
|
|
fontStyle: 'italic',
|
|
lineHeight: '1.5',
|
|
},
|
|
]);
|
|
|
|
const BaseCode = style({
|
|
color: color.SurfaceVariant.OnContainer,
|
|
background: color.SurfaceVariant.Container,
|
|
border: `${config.borderWidth.B300} solid ${color.SurfaceVariant.ContainerLine}`,
|
|
borderRadius: config.radii.R300,
|
|
});
|
|
const CodeFont = style({
|
|
fontFamily: 'monospace',
|
|
});
|
|
|
|
export const InlineCodeWrapper = style({
|
|
position: 'relative',
|
|
display: 'inline-block',
|
|
});
|
|
|
|
export const Code = style([
|
|
DefaultReset,
|
|
BaseCode,
|
|
CodeFont,
|
|
{
|
|
padding: `0 ${config.space.S100}`,
|
|
display: 'inline',
|
|
lineHeight: '1.5',
|
|
},
|
|
]);
|
|
|
|
export const InlineCodeCopyButton = style({
|
|
position: 'absolute',
|
|
top: 0,
|
|
right: 0,
|
|
transform: 'translateY(-100%)',
|
|
opacity: 0,
|
|
transition: 'opacity 0.15s ease-in-out',
|
|
background: color.SurfaceVariant.Container,
|
|
border: `${config.borderWidth.B300} solid ${color.SurfaceVariant.ContainerLine}`,
|
|
borderBottom: 'none',
|
|
borderTopLeftRadius: config.radii.R300,
|
|
borderTopRightRadius: config.radii.R300,
|
|
padding: `${config.space.S200} ${config.space.S300}`,
|
|
cursor: 'pointer',
|
|
fontSize: toRem(11),
|
|
color: color.SurfaceVariant.OnContainer,
|
|
fontWeight: config.fontWeight.W500,
|
|
whiteSpace: 'nowrap',
|
|
zIndex: 1,
|
|
display: 'flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
selectors: {
|
|
[`${InlineCodeWrapper}:hover &`]: {
|
|
opacity: 1,
|
|
},
|
|
'&:hover': {
|
|
background: color.SurfaceVariant.ContainerHover,
|
|
},
|
|
'&:active': {
|
|
background: color.SurfaceVariant.ContainerActive,
|
|
},
|
|
},
|
|
});
|
|
|
|
export const Spoiler = recipe({
|
|
base: [
|
|
DefaultReset,
|
|
{
|
|
padding: `0 ${config.space.S100}`,
|
|
backgroundColor: color.SurfaceVariant.ContainerActive,
|
|
borderRadius: config.radii.R300,
|
|
lineHeight: '1.5',
|
|
selectors: {
|
|
'&[aria-pressed=true]': {
|
|
color: 'transparent',
|
|
},
|
|
},
|
|
},
|
|
],
|
|
variants: {
|
|
active: {
|
|
true: {
|
|
color: 'transparent',
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
export const CodeBlock = style([
|
|
DefaultReset,
|
|
BaseCode,
|
|
MarginSpaced,
|
|
{
|
|
fontStyle: 'normal',
|
|
position: 'relative',
|
|
overflow: 'hidden',
|
|
lineHeight: '1.5',
|
|
},
|
|
]);
|
|
export const CodeBlockHeader = style([
|
|
ContainerColor({ variant: 'Surface' }),
|
|
{
|
|
padding: `0 ${config.space.S200} 0 ${config.space.S300}`,
|
|
borderBottomWidth: config.borderWidth.B300,
|
|
gap: config.space.S200,
|
|
},
|
|
]);
|
|
export const CodeBlockInternal = style([
|
|
CodeFont,
|
|
{
|
|
padding: `${config.space.S200} ${config.space.S200} 0`,
|
|
minWidth: toRem(200),
|
|
},
|
|
]);
|
|
|
|
export const CodeBlockBottomShadow = style({
|
|
position: 'absolute',
|
|
bottom: 0,
|
|
left: 0,
|
|
right: 0,
|
|
pointerEvents: 'none',
|
|
|
|
height: config.space.S400,
|
|
background: `linear-gradient(to top, #00000022, #00000000)`,
|
|
});
|
|
|
|
export const List = style([
|
|
DefaultReset,
|
|
MarginSpaced,
|
|
{
|
|
padding: `0 ${config.space.S100}`,
|
|
paddingLeft: config.space.S600,
|
|
lineHeight: '1.5',
|
|
},
|
|
]);
|
|
|
|
export const Img = style([
|
|
DefaultReset,
|
|
MarginSpaced,
|
|
{
|
|
maxWidth: toRem(296),
|
|
borderRadius: config.radii.R300,
|
|
},
|
|
]);
|
|
|
|
export const InlineChromiumBugfix = style({
|
|
fontSize: 0,
|
|
lineHeight: 0,
|
|
});
|
|
|
|
export const Mention = recipe({
|
|
base: [
|
|
DefaultReset,
|
|
{
|
|
backgroundColor: color.SurfaceVariant.Container,
|
|
color: color.SurfaceVariant.OnContainer,
|
|
boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.SurfaceVariant.ContainerLine}`,
|
|
padding: `0 ${toRem(2)}`,
|
|
borderRadius: config.radii.R300,
|
|
fontWeight: config.fontWeight.W500,
|
|
lineHeight: '1.5',
|
|
},
|
|
],
|
|
variants: {
|
|
highlight: {
|
|
true: {
|
|
backgroundColor: color.Success.Container,
|
|
color: color.Success.OnContainer,
|
|
boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.Success.ContainerLine}`,
|
|
},
|
|
},
|
|
focus: {
|
|
true: {
|
|
boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.SurfaceVariant.OnContainer}`,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
export const Command = recipe({
|
|
base: [
|
|
DefaultReset,
|
|
{
|
|
padding: `0 ${toRem(2)}`,
|
|
borderRadius: config.radii.R300,
|
|
fontWeight: config.fontWeight.W500,
|
|
lineHeight: '1.5',
|
|
},
|
|
],
|
|
variants: {
|
|
focus: {
|
|
true: {
|
|
boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.Warning.OnContainer}`,
|
|
},
|
|
},
|
|
active: {
|
|
true: {
|
|
backgroundColor: color.Warning.Container,
|
|
color: color.Warning.OnContainer,
|
|
boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.Warning.ContainerLine}`,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
export const EmoticonBase = style([
|
|
DefaultReset,
|
|
{
|
|
display: 'inline-block',
|
|
padding: '0.05rem',
|
|
height: '1em',
|
|
verticalAlign: 'middle',
|
|
},
|
|
]);
|
|
|
|
export const Emoticon = recipe({
|
|
base: [
|
|
DefaultReset,
|
|
{
|
|
display: 'inline-flex',
|
|
justifyContent: 'center',
|
|
alignItems: 'center',
|
|
|
|
height: '1em',
|
|
minWidth: '1em',
|
|
fontSize: '1.33em',
|
|
lineHeight: '1em',
|
|
verticalAlign: 'middle',
|
|
position: 'relative',
|
|
top: '-0.35em',
|
|
borderRadius: config.radii.R300,
|
|
},
|
|
],
|
|
variants: {
|
|
focus: {
|
|
true: {
|
|
boxShadow: `0 0 0 ${config.borderWidth.B300} ${color.SurfaceVariant.OnContainer}`,
|
|
},
|
|
},
|
|
},
|
|
});
|
|
|
|
export const EmoticonImg = style([
|
|
DefaultReset,
|
|
{
|
|
height: '1em',
|
|
cursor: 'default',
|
|
},
|
|
]);
|
|
|
|
export const highlightText = style([
|
|
DefaultReset,
|
|
{
|
|
backgroundColor: 'yellow',
|
|
color: 'black',
|
|
lineHeight: '1.5',
|
|
},
|
|
]);
|