Skip to content

Commit

Permalink
feat(EditorView): change default selection styles
Browse files Browse the repository at this point in the history
  • Loading branch information
whiteformed committed Dec 10, 2024
1 parent 89c9881 commit e3db0bc
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 17 deletions.
24 changes: 24 additions & 0 deletions demo/stories/css-variables/CSSVariables.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,30 @@ export const Story: StoryObj<typeof component> = {
control: {type: 'text'},
description: 'Editor contents padding',
},
'--g-selection-bg-color': {
control: {type: 'text'},
description: 'Editor selection bg color',
},
'--g-selection-border': {
control: {type: 'text'},
description: 'Editor selection border',
},
'--g-selection-border-radius': {
control: {type: 'text'},
description: 'Editor selection border radius',
},
'--g-selection-outline': {
control: {type: 'text'},
description: 'Editor selection outline',
},
'--g-selection-background': {
control: {type: 'text'},
description: 'Editor selection background',
},
'--g-selection-box-shadow': {
control: {type: 'text'},
description: 'Editor selection box-shadow',
},
},
};
Story.storyName = 'Custom CSS Variables';
Expand Down
9 changes: 9 additions & 0 deletions docs/how-to-customize-the-editor.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## How to customize the editor
You can use CSS variables to make editor contents fit your own needs

### Elements styles
| **Variable** | **Description** | **CSS Property Type** | **Default** |
| :---: | :---: | :---: | :---: |
| `--g-md-toolbar-padding` | Toolbar padding | padding | 0px |
Expand All @@ -11,3 +12,11 @@ You can use CSS variables to make editor contents fit your own needs
| `--g-md-toolbar-sticky-offset` | Toolbar offset in sticky mode | top | 0px |
| `--g-md-toolbar-sticky-border` | Toolbar border in sticky mode | border | 1px solid var(--g-color-line-generic-solid) |
| `--g-md-editor-padding` | Editor contents padding | padding | 0px |

### Selection styles
| **Variable** | **Description** | **CSS Property Type** | **Default** |
| `--g-selection-border` | Editor selection border | border | none |
| `--g-selection-border-radius` | Editor selection border radius | border-radius | 6px |
| `--g-selection-outline` | Editor selection outline | outline | none |
| `--g-selection-background` | Editor selection background | background | #e6e6e6 |
| `--g-selection-box-shadow` | Editor selection box shadow | box-shadow | none |
90 changes: 73 additions & 17 deletions src/extensions/base/BaseStyles/index.scss
Original file line number Diff line number Diff line change
@@ -1,28 +1,84 @@
@use '../../../../node_modules/prosemirror-view/style/prosemirror';
$active-node-default-indent-top: calc(-1 * var(--g-spacing-1));
$active-node-default-indent-bottom: calc(-1 * var(--g-spacing-1));
$active-node-default-indent-left: calc(-1 * var(--g-spacing-2));
$active-node-default-indent-right: calc(-1 * var(--g-spacing-2));

// Make outline appear only if ProseMirror is focused
$active-node-selector: '.pm-node-selected';
$basic-elements: h1, h2, h3, h4, h5, h6, p, ul, ol, span, pre, '*[data-html], .g-md-checkbox';

.ProseMirror-selectednode {
outline: none;
$default-selection-border: none;
$default-selection-border-radius: var(--g-border-radius-m);
$default-selection-outline: none;
// TODO: CHANGE TO TOKEN
$default-selection-background: #e6e6e6;
$default-selection-box-shadow: none;

$default-li-marker-width: var(--g-spacing-4);

@mixin node-props {
position: relative;

border: $default-selection-border;
border-radius: $default-selection-border-radius;
outline: $default-selection-outline;
background: var(--g-selection-background, $default-selection-background);
box-shadow: $default-selection-box-shadow;
}

.li.ProseMirror-selectednode:after {
border: none;
@mixin selection-props {
border: var(--g-selection-border, $default-selection-border);
border-radius: var(--g-selection-border-radius, $default-selection-border-radius);
outline: var(--g-selection-outline, $default-selection-outline);
background: var(--g-selection-background, $default-selection-background);
box-shadow: var(--g-selection-box-shadow, $default-selection-box-shadow);
}

.g-md-editor.ProseMirror-focused {
.ProseMirror-selectednode {
outline: 2px solid #8cf;
}
[class].g-md-editor {
@each $basic-element in $basic-elements {
& #{$basic-element}#{$active-node-selector} {
@include node-props;

&::after {
position: absolute;
z-index: -1;
inset: $active-node-default-indent-top
$active-node-default-indent-right
$active-node-default-indent-bottom
$active-node-default-indent-left;

content: '';

li.ProseMirror-selectednode:after {
border: 2px solid #8cf;
@include selection-props;
}

& img {
mix-blend-mode: multiply;
}
}
}
}

.g-md-editor.ProseMirror,
.g-md-editor .ProseMirror {
&:focus {
outline: none;
& li#{$active-node-selector} {
@include node-props;

&::marker {
@include selection-props;
}

&::after {
position: absolute;
z-index: -1;
inset: $active-node-default-indent-top $active-node-default-indent-right
$active-node-default-indent-bottom
calc(
$active-node-default-indent-left - max(
var(--li-marker-width, 0),
$default-li-marker-width
)
);

content: '';

@include selection-props;
}
}
}
21 changes: 21 additions & 0 deletions src/extensions/markdown/Lists/ListsSpecs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,27 @@ export const ListsSpecs: ExtensionAuto = (builder) => {
spec: schemaSpecs[ListNode.ListItem],
toMd: serializerTokens[ListNode.ListItem],
fromMd: {tokenSpec: parserTokens[ListNode.ListItem]},
// @ts-expect-error
view: () => (node, view, getPos) => {
return {
update: (node_) => {
node = node_;

const pos = getPos();
if (pos === undefined) return false;

const dom = view.domAtPos(pos + 1).node as HTMLElement;

const markerWidth = Math.max(
Math.floor(parseFloat(getComputedStyle(dom, '::marker').width)),
);

dom.style.setProperty('--li-marker-width', `${markerWidth}px`);

return true;
},
};
},
}))
.addNode(ListNode.BulletList, () => ({
spec: schemaSpecs[ListNode.BulletList],
Expand Down

0 comments on commit e3db0bc

Please sign in to comment.