Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
"eslint-plugin-react-hooks": "^7.1.1",
"fs-extra": "^11.3.0",
"globals": "^17.9.0",
"highlight.js": "^11.11.1",
"husky": "^9.1.6",
"jsdom": "^25.0.1",
"lightningcss": "^1.29.3",
Expand Down
8 changes: 8 additions & 0 deletions packages/components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
"types": "./dist/markdown.d.ts",
"default": "./dist/markdown.js"
},
"./code-block": {
"types": "./dist/code-block.d.ts",
"default": "./dist/code-block.js"
},
"./style.css": "./dist/style.css"
},
"type": "module",
Expand All @@ -46,6 +50,7 @@
"peerDependencies": {
"@koobiq/design-tokens": "^3.17.2",
"@koobiq/react-icons": "^12.1.1",
"highlight.js": "^11.0.0",
"react": "18.x || 19.x",
"react-dom": "18.x || 19.x",
"react-markdown": "^10.1.0",
Expand All @@ -57,6 +62,9 @@
},
"remark-gfm": {
"optional": true
},
"highlight.js": {
"optional": true
}
}
}
1 change: 1 addition & 0 deletions packages/components/src/code-block.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './components/CodeBlock';
Comment thread
artembelik marked this conversation as resolved.
170 changes: 170 additions & 0 deletions packages/components/src/components/CodeBlock/CodeBlock.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import {
Alert,
Meta,
Story,
Status,
} from '../../../../../.storybook/components';

import * as Stories from './CodeBlock.stories';

<Meta of={Stories} />

# CodeBlock

<Status variant="experimental" />

`CodeBlock` is a component that displays reformatted text content with syntax highlighting.

<Alert title="Note">
For syntax highlighting, the
[`highlight.js@^11`](https://github.com/highlightjs/highlight.js/tree/stable-11) peer dependency is required:

```bash
npm install highlight.js@^11
```

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Сейчас документация начинается с HighlightConfigProvider, хотя он опционален и CodeBlock работает без него. Из-за этого создаётся впечатление, что провайдер обязателен. Может быть, сначала описать основные сценарии CodeBlock, а настройку провайдера перенести ближе к концу документации?

Как идея: можно рассмотреть нейтральный CodeBlockProvider с адаптером вместо конфигурации, привязанной к Highlight.js. По аналогии с адаптерами дат это позволит подключать Highlight.js, Shiki и другие библиотеки, не меняя API самого CodeBlock.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

это перенос документации из https://koobiq.io/en/components/code-block

код блок может работать и без HighlightConfigProvider, но в таком случае будут загружаться все языки из highlightjs, грубо говоря, мы в самом начале говорим, как лучше всего использовать компонент

By default, CodeBlock lazily loads the full highlight.js bundle with all languages (~1 MB). To
reduce bundle size, wrap the app (or a part of it) with CodeBlock.HighlightConfigProvider and specify
only the languages you need:


</Alert>

### Configuring highlight.js

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Документация немного выбивается из общей структуры репозитория: отсутствует раздел Props с <Props of={Stories.Base} />, а после заголовка первого уровня сразу используются ### и ####. Предлагаю выровнять иерархию: основные разделы оформить через ##, вложенные — через ###, а также добавить стандартные разделы Import, Usage и Props.


By default, `CodeBlock` lazily loads the full `highlight.js` bundle with all languages (~1 MB). To
reduce bundle size, wrap the app (or a part of it) with `CodeBlock.HighlightConfigProvider` and specify
only the languages you need:

```tsx
const highlightConfig = {
core: () => import('highlight.js/lib/core'),
languages: {
typescript: () => import('highlight.js/lib/languages/typescript'),
css: () => import('highlight.js/lib/languages/css'),
xml: () => import('highlight.js/lib/languages/xml'),
},
fallbackLanguage: 'plaintext',
};

function App() {
return (
<CodeBlock.HighlightConfigProvider config={highlightConfig}>
<CodeBlock files={files} />
</CodeBlock.HighlightConfigProvider>
);
}
```

Languages are loaded lazily on first use. Note that `html` is an alias of `xml` in `highlight.js`, so
register `xml` to enable HTML syntax highlighting. Pass a stable (module-level or memoized) `config`
object — `CodeBlock` reuses one shared `highlight.js` instance for the app, keyed by that reference.

See the full list of supported languages in the
[highlight.js documentation](https://highlightjs.readthedocs.io/en/stable/supported-languages.html).

### Line numbers

Numbering lines is useful for referencing a specific location in the document. Line numbers are
disabled by default and can be enabled using the `hasLineNumbers` prop.

<Story of={Stories.Overview} />

### Header with title

In the header, use `renderTabLabel` to render a document name or the detected syntax. A shadow appears
under the header when the code content is scrolled.

<Story of={Stories.HeaderPinned} />

### Changing the block height

The block can expand to fill the available screen area if reviewing the code is one of the main tasks
in the interface. When screen space is limited or the code only supplements the main content, use
`maxHeight` to constrain it.

For compactness, use `viewAll` to show a portion of the document with the option to reveal everything.
The block increases in height so all the code is visible, avoiding double scrolling. The wrap setting
is preserved when collapsing and expanding the block.

<Story of={Stories.WithMaxHeight} />

### Soft line wrap

By default, lines don't wrap. Pre-configure the mode using `softWrap`, or let users control it with a
toggle button in the action panel by enabling `canToggleSoftWrap`.

The icon in the button represents the future state after activation and changes after the wrap mode
is toggled.

<Story of={Stories.WithSoftWrap} />

### Displaying multiple documents

Multiple documents are placed in the block as tabs. The tab title is formed from the `filename` field.
Tabs can be hidden using `hideTabs`, and the active tab can be set using `activeFileIndex` or
`defaultActiveFileIndex`.

Tabs are hidden automatically for a single document with an empty `filename`.

<Story of={Stories.WithTabs} />

The tab header is displayed without a shadow by default. If content extends beyond the available area,
a shadow appears under the header when the code content is scrolled.

<Story of={Stories.WithTabsAndShadow} />

### Visual styling

Two visual styles are available: an outlined block (default), or a filled block with a background that
contrasts with the page. The filled style prevents the block from getting lost on a screen with varied
content and is configured using `isFilled`.

<Story of={Stories.WithFilled} />

### Without borders

When the code block should fill an entire container or screen, use `hideBorder` to remove its border.

<Story of={Stories.WithNoBorder} />

### Action panel

The action panel is located in the upper-right corner of the block and remains fixed while scrolling.
The component configuration determines which actions are available.

The panel is always visible when tabs are shown and on touch devices. When tabs are hidden, it appears
on hover or focus on other devices. `alwaysShowActionBar` keeps the panel visible regardless of tabs or
hover and is disabled by default.

```tsx
<CodeBlock files={files} hideTabs alwaysShowActionBar />
```

#### Changing wrap mode

The user can toggle the wrap mode using a button. This option is disabled by default and can be enabled
using `canToggleSoftWrap`.

```tsx
<CodeBlock files={files} canToggleSoftWrap />
```

#### Downloading the document

The user can download the document using an action that is disabled by default and can be enabled with
`canDownload`. The file name and extension are taken from `filename`; when it is empty,
`fallbackFileName` is used instead (`code` by default).

```tsx
<CodeBlock files={files} canDownload />
```

#### Copying the document text

The user can copy the document text by default. Use `hideCopyButton` to hide this action.

```tsx
<CodeBlock files={files} hideCopyButton />
```

#### Opening the document in an external system

The address is taken from the `link` field. The link opens in a new tab.

<Story of={Stories.WithLink} />
Loading
Loading