Skip to content

Commit

Permalink
feat: support custom padding (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
huozhi authored Feb 16, 2025
1 parent ca9c4de commit b10d218
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 45 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ The following props are supported by the `Editor` component:
- `title` (optional): A string representing the title of the editor.
- `controls` (optional): A boolean value indicating whether to display the controls for the editor.
- `lineNumbers` (optional): A boolean value indicating whether to display line numbers in the editor.
- `lineNumbersWidth` (optional): A string representing the width of the line numbers column. The default value is `2.5rem`.
- `padding` (optional): A string representing the padding of the code block. The default value is `1rem`.
- `fontSize` (optional): A string representing the font size of the editor. The default value is `inherit`.

Additionally, you can pass any other props to the `Editor` component, which will be applied to the root `div` element.
Expand All @@ -57,10 +59,12 @@ import { Code } from 'codice'

- `title` (optional): A string representing the title of the code block.
- `controls` (optional): A boolean value indicating whether to display the controls for the code block.
- `lineNumbers` (optional): A boolean value indicating whether to display line numbers in the code block.
- `preformatted` (optional): A boolean value indicating whether the code should be displayed as preformatted text. If `true`, the code will be displayed in a `pre` and a `code` element. If `false`, the code will be displayed in a `div` element.
- `asMarkup` (optional): A boolean value indicating whether the code should be displayed as markup. If `true`, the code will be displayed with HTML entities escaped. If `false`, the code will be displayed as plain text. default is `false`.
- `fontSize` (optional): A string representing the font size of the editor. The default value is `inherit`.
- `lineNumbers` (optional): A boolean value indicating whether to display line numbers in the code block.
- `lineNumbersWidth` (optional): A string representing the width of the line numbers column. The default value is `2.5rem`.
- `padding` (optional): A string representing the padding of the code block. The default value is `1rem`.
- `children`: The code content to be displayed in the code block.

### Styling
Expand All @@ -74,7 +78,6 @@ Usually you don't need to style the editor, it comes with a default theme. Howev
- `--codice-caret-color`: The color of the caret in the editor. (default: `inherit`)
- `--codice-control-color`: The color of the control items in the code frame and editor. (default: `#8d8989`)


For example, you can define the following CSS variables in your stylesheet to customize the appearance:
```css
:root {
Expand Down
52 changes: 46 additions & 6 deletions site/app/live-editor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import { Editor } from 'codice'
import React, { useState } from 'react'
import React, { useId, useState } from 'react'
import domToImage from 'dom-to-image'

const CODE_QUERY_KEY = 'c'
Expand Down Expand Up @@ -62,25 +62,35 @@ function Input({
function RangeSelector({
value,
onChange,
text,
min,
max,
step,
className,
...props
}: {
value: number;
text: string;
min: number;
max: number;
step: number;
onChange: (value: number) => void
className: string
}) {
const id = useId()
return (
<div className={className}>
<label
className='controls-manager-label controls-manager-label--checked'
htmlFor="font-size">{`fontSize={`}<b><span>{value}</span></b>{`}`}
htmlFor={id}>{text}{`={`}<b><span>{value}</span></b>{`}`}
</label>
<input
{...props}
id={id}
type="range"
min="12"
max="24"
step="2"
min={min}
max={max}
step={step}
value={value}
onChange={(e) => onChange(Number(e.target.value))}
/>
Expand Down Expand Up @@ -140,6 +150,8 @@ export function LiveEditor({
const [controls, setControls] = useState(true)
const [lineNumbers, setLineNumbers] = useState(true)
const [fontSize, setFontSize] = useState(14)
const [padding, setPadding] = useState(1) // rem
const [lineNumbersWidth, setLineNumbersWidth] = useState(2.5) // rem

return (
<div>
Expand Down Expand Up @@ -169,7 +181,33 @@ export function LiveEditor({
propName="lineNumbers"
/>
</div>
<RangeSelector className="font-size-control" value={fontSize} onChange={setFontSize} />
<RangeSelector
text="fontSize"
className="range-control"
min={12}
max={24}
step={2}
value={fontSize}
onChange={setFontSize}
/>
<RangeSelector
text="padding"
className="range-control"
min={1}
max={2}
step={0.1}
value={padding}
onChange={setPadding}
/>
<RangeSelector
text="lineNumbersWidth"
className="range-control"
value={lineNumbersWidth}
min={1}
max={2}
step={0.2}
onChange={setLineNumbersWidth}
/>

<div className='editor-layout'>
<span
Expand All @@ -195,6 +233,8 @@ export function LiveEditor({
controls={controls}
fontSize={fontSize}
lineNumbers={lineNumbers}
lineNumbersWidth={`${lineNumbersWidth}rem`}
padding={`${padding}rem`}
onChange={(text) => setCode(text)}
/>
</div>
Expand Down
24 changes: 14 additions & 10 deletions site/app/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,9 @@ input[type=radio] {
.code-example__item__title {
margin: 0 0 2rem;
}
.controls-manager {
margin: 2rem 0;
}
.controls-manager-label {
display: inline-block;
width: 180px;
padding: 3px 8px;
border-radius: 8px;
cursor: pointer;
Expand Down Expand Up @@ -147,21 +145,22 @@ input[type=radio] {
.controls-manager-input::selection {
background-color: #565656;
}
.font-size-control {
margin: 2rem 4px;
.range-control {
font-size: 14px;
margin: 8px auto;
}
.font-size-control label {
.range-control label {
margin-right: 8px;
}
.font-size-control input[type="range"],
.font-size-control input[type="range"]::-webkit-slider-runnable-track {
.range-control input[type="range"],
.range-control input[type="range"]::-webkit-slider-runnable-track {
appearance: none;
-webkit-appearance: none;
background: var(--control-bg-color);
height: 0.5rem;
border-radius: 999px;
}
.font-size-control input[type="range"]::-webkit-slider-thumb {
.range-control input[type="range"]::-webkit-slider-thumb {
appearance: none;
-webkit-appearance: none;
width: 1rem;
Expand All @@ -171,11 +170,16 @@ input[type=radio] {
cursor: pointer;
transform: translateY(-0.25rem);
}
.controls-manager {
display: flex;
font-size: 14px;
margin: 0.5rem 0;
}
.controls-manager label span {
font-size: 12px;
}
.controls-manager .control-button {
margin: 4px;
margin-right: auto;
}

.controls-manager input[type="checkbox"] {
Expand Down
20 changes: 15 additions & 5 deletions src/code/code.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ describe('Code', () => {
--codice-code-highlight-color: #555555;
--codice-control-color: #8d8989;
--codice-font-size: inherit;
--codice-code-line-number-width: 2.5rem;
--codice-code-padding: 1rem;
}
[data-codice-code=":R0:"] pre {
white-space: pre-wrap;
Expand All @@ -23,7 +25,7 @@ describe('Code', () => {
width: 100%;
}
[data-codice-code=":R0:"] .sh__line:has(> [data-codice-code-line-number]) {
padding-left: 40px;
padding-left: var(--codice-code-line-number-width);
}
[data-codice-code=":R0:"] .sh__line[data-highlight] {
background-color: var(--codice-code-highlight-color);
Expand Down Expand Up @@ -75,6 +77,8 @@ describe('Code', () => {
--codice-code-highlight-color: #555555;
--codice-control-color: #8d8989;
--codice-font-size: inherit;
--codice-code-line-number-width: 2.5rem;
--codice-code-padding: 1rem;
}
[data-codice-code=":R0:"] pre {
white-space: pre-wrap;
Expand All @@ -88,7 +92,7 @@ describe('Code', () => {
width: 100%;
}
[data-codice-code=":R0:"] .sh__line:has(> [data-codice-code-line-number]) {
padding-left: 40px;
padding-left: var(--codice-code-line-number-width);
}
[data-codice-code=":R0:"] .sh__line[data-highlight] {
background-color: var(--codice-code-highlight-color);
Expand Down Expand Up @@ -173,6 +177,8 @@ describe('Code', () => {
--codice-code-highlight-color: #555555;
--codice-control-color: #8d8989;
--codice-font-size: inherit;
--codice-code-line-number-width: 2.5rem;
--codice-code-padding: 1rem;
}
[data-codice-code=":R0:"] pre {
white-space: pre-wrap;
Expand All @@ -186,7 +192,7 @@ describe('Code', () => {
width: 100%;
}
[data-codice-code=":R0:"] .sh__line:has(> [data-codice-code-line-number]) {
padding-left: 40px;
padding-left: var(--codice-code-line-number-width);
}
[data-codice-code=":R0:"] .sh__line[data-highlight] {
background-color: var(--codice-code-highlight-color);
Expand Down Expand Up @@ -271,6 +277,8 @@ describe('Code', () => {
--codice-code-highlight-color: #555555;
--codice-control-color: #8d8989;
--codice-font-size: 14px;
--codice-code-line-number-width: 2.5rem;
--codice-code-padding: 1rem;
}
[data-codice-code=":R0:"] pre {
white-space: pre-wrap;
Expand All @@ -284,7 +292,7 @@ describe('Code', () => {
width: 100%;
}
[data-codice-code=":R0:"] .sh__line:has(> [data-codice-code-line-number]) {
padding-left: 40px;
padding-left: var(--codice-code-line-number-width);
}
[data-codice-code=":R0:"] .sh__line[data-highlight] {
background-color: var(--codice-code-highlight-color);
Expand Down Expand Up @@ -334,6 +342,8 @@ describe('Code', () => {
--codice-code-highlight-color: #555555;
--codice-control-color: #8d8989;
--codice-font-size: 1rem;
--codice-code-line-number-width: 2.5rem;
--codice-code-padding: 1rem;
}
[data-codice-code=":R0:"] pre {
white-space: pre-wrap;
Expand All @@ -347,7 +357,7 @@ describe('Code', () => {
width: 100%;
}
[data-codice-code=":R0:"] .sh__line:has(> [data-codice-code-line-number]) {
padding-left: 40px;
padding-left: var(--codice-code-line-number-width);
}
[data-codice-code=":R0:"] .sh__line[data-highlight] {
background-color: var(--codice-code-highlight-color);
Expand Down
6 changes: 5 additions & 1 deletion src/code/code.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ export function Code({
highlightLines,
preformatted = true,
lineNumbers = false,
lineNumbersWidth,
padding,
asMarkup = false,
...props
}: {
Expand All @@ -150,10 +152,12 @@ export function Code({
title?: string
controls?: boolean
lineNumbers?: boolean
lineNumbersWidth?: string
padding?: string
asMarkup?: boolean
} & React.HTMLAttributes<HTMLDivElement>) {
const id = useId()
const styles = css(id, { fontSize, lineNumbers })
const styles = css(id, { fontSize, lineNumbers, lineNumbersWidth, padding })

const lineElements = useMemo(() =>
asMarkup
Expand Down
12 changes: 9 additions & 3 deletions src/code/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ ${C} .sh__line {
width: 100%;
}
${C} .sh__line:has(> [data-codice-code-line-number]) {
padding-left: 40px;
padding-left: var(--codice-code-line-number-width);
}
${C} .sh__line[data-highlight] {
background-color: var(--codice-code-highlight-color);
Expand Down Expand Up @@ -71,21 +71,25 @@ const lineNumbersCss = (id: string) => `\
content: counter(codice-code-line-number);
display: inline-block;
min-width: calc(2rem - 6px);
margin-left: -40px;
width: var(--codice-code-line-number-width);
margin-left: calc(var(--codice-code-line-number-width) * -1);
margin-right: 16px;
text-align: right;
user-select: none;
color: var(--codice-code-line-number-color);
}
`


export const css = (id: string, {
fontSize,
lineNumbers,
lineNumbersWidth = '2.5rem',
padding = '1rem',
}: {
fontSize: string | number | undefined
lineNumbers: boolean
lineNumbersWidth: string
padding: string
}): string => {
const U = `[data-codice-code="${id}"]`
const fz = fontSizeCss(fontSize)
Expand All @@ -95,6 +99,8 @@ ${U} {
--codice-code-highlight-color: #555555;
--codice-control-color: #8d8989;
--codice-font-size: ${fz};
--codice-code-line-number-width: ${lineNumbersWidth};
--codice-code-padding: ${padding};
}
${baseCss(id)}
${headerCss(id)}
Expand Down
13 changes: 9 additions & 4 deletions src/editor/css.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { fontSizeCss } from '../style'


export const css = (id: string, {
fontSize
fontSize,
lineNumbersWidth = '2.5rem',
padding = '1rem',
}: {
fontSize?: string | number
lineNumbersWidth: string
padding: string
}) => {
const R = `[data-codice-editor="${id}"]`
return `\
Expand All @@ -13,6 +16,8 @@ ${R} {
--codice-background-color: transparent;
--codice-caret-color: inherit;
--codice-font-size: ${fontSizeCss(fontSize)};
--codice-code-line-number-width: ${lineNumbersWidth};
--codice-code-padding: ${padding};
position: relative;
overflow-y: scroll;
Expand All @@ -27,7 +32,7 @@ ${R} textarea {
line-break: anywhere;
overflow-wrap: break-word;
scrollbar-width: none;
padding: 24px 16px;
padding: calc(var(--codice-code-padding) * 1.5) var(--codice-code-padding);
line-height: 1.5;
font-size: var(--codice-font-size);
caret-color: var(--codice-caret-color);
Expand Down Expand Up @@ -61,7 +66,7 @@ ${R} textarea {
overflow: hidden;
}
${R}[data-codice-line-numbers="true"] textarea {
padding-left: 55px;
padding-left: calc(var(--codice-code-line-number-width) + var(--codice-code-padding));
}
`
// line number padding-left is [[width 24px] margin-right 16px] + 15px
Expand Down
Loading

0 comments on commit b10d218

Please sign in to comment.