Skip to content

Commit 3c9e1e6

Browse files
authored
feat: show line numbers (#91)
* feat: show line numbers * chore: update yarn version * chore fix vulnerabilities * chore: update readme * chore: updating packages * refactor!: removing the initalCollapsedDepth prop * chore: removed lodash to reduce bundle size * doc: udpate changelog * chore: bump version
1 parent db08ecf commit 3c9e1e6

File tree

29 files changed

+10945
-9865
lines changed

29 files changed

+10945
-9865
lines changed

.github/workflows/npm-publish.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,12 @@ jobs:
1212
- uses: actions/checkout@v4
1313
- uses: actions/setup-node@v4
1414
with:
15-
node-version: '20.x'
15+
node-version: '22.x'
1616
registry-url: 'https://registry.npmjs.org'
17+
- name: Install latest Yarn
18+
run: corepack prepare yarn@4 --activate
19+
- name: Activate latest Yarn
20+
run: yarn set version 4
1721
- run: yarn
1822
- run: yarn build
1923
- run: npm publish --provenance --access public

.github/workflows/qa.yml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@ jobs:
1111
runs-on: ubuntu-latest
1212
steps:
1313
- name: Checkout
14-
uses: actions/checkout@v3
14+
uses: actions/checkout@v4
1515
- name: Setup node
16-
uses: actions/setup-node@v3
16+
uses: actions/setup-node@v4
1717
with:
18-
node-version: 16
18+
node-version: 22
19+
- name: Install latest Yarn
20+
run: corepack prepare yarn@4 --activate
21+
- name: Activate latest Yarn
22+
run: yarn set version 4
1923
- name: Install dependencies
2024
run: yarn
2125
- name: Run lint

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ dist
44
.DS_Store
55
coverage
66
test.xml
7-
7+
.yarn/

.storybook/main.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,29 @@ const { mergeConfig } = require('vite');
55

66
const config: StorybookConfig = {
77
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
8+
89
addons: [
910
'@storybook/addon-links',
1011
'@storybook/addon-essentials',
1112
'@storybook/addon-interactions',
13+
'@chromatic-com/storybook'
1214
],
15+
1316
framework: {
1417
name: '@storybook/react-vite',
1518
options: {},
1619
},
17-
docs: {
18-
autodocs: 'tag',
19-
},
20+
21+
docs: {},
22+
2023
async viteFinal(config) {
2124
return mergeConfig(config, {
2225
plugins: [viteTsconfig()],
2326
});
2427
},
28+
29+
typescript: {
30+
reactDocgen: 'react-docgen-typescript'
31+
}
2532
};
2633
export default config;

.storybook/preview.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import type { Preview } from "@storybook/react";
22

33
const preview: Preview = {
44
parameters: {
5-
actions: { argTypesRegex: "^on[A-Z].*" },
65
controls: {
76
matchers: {
87
color: /(background|color)$/i,

.yarnrc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nodeLinker: node-modules

CHANGELOG.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
## 3.0.0
2+
_May 25, 2025_
3+
4+
- feat: show line numbers
5+
- chore: updating dependencies
6+
- fix: fixing vulnerabilities
7+
- doc: improving README
8+
- BREAKING CHANGES: removed the initalCollapsedDepth prop
9+
- refactor: removed lodash to reduce bundle size
10+
11+
## 2.0.4
12+
13+
_Feb 25, 2025_
14+
15+
- fix: react 19 compatibility
16+
117
## 2.0.4
218

319
_Oct 22, 2024_

README.md

Lines changed: 92 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,139 @@
11
[Buy me a coffee ☕](https://www.buymeacoffee.com/alissonmbr)
22

3-
43
# react-xml-viewer
4+
55
[![NPM](https://img.shields.io/npm/v/react-xml-viewer.svg)](https://www.npmjs.com/package/react-xml-viewer)\
66
Simple and configurable React component to prettify XMLs.
77

8-
9-
108
<img src="https://raw.githubusercontent.com/alissonmbr/react-xml-viewer/example.png" width="300"/>
119

1210
## Live demo
13-
[![Edit react-xml-view](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-xml-viewer-v2-example-6xh9yq)
1411

12+
[![Edit react-xml-view](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/react-xml-viewer-v2-example-6xh9yq)
1513

1614
## Install
1715

1816
#### npm
17+
1918
```bash
2019
npm install --save react-xml-viewer
2120
```
2221

2322
#### yarn
23+
2424
```bash
2525
yarn add react-xml-viewer
2626
```
2727

2828
## Usage
2929

3030
```jsx
31-
import React, { Component } from 'react'
32-
import XMLViewer from 'react-xml-viewer'
31+
import React, { Component } from 'react';
32+
import XMLViewer from 'react-xml-viewer';
3333

34-
const xml = '<hello>World</hello>'
34+
const xml = '<hello>World</hello>';
3535

3636
export function App() {
37-
return (
38-
<div>
39-
<XMLViewer xml={xml} />
40-
</div>
41-
)
37+
return (
38+
<div>
39+
<XMLViewer xml={xml} />
40+
</div>
41+
);
4242
}
4343
```
4444

4545
## Props
46-
### xml (string)
47-
A xml string to prettify.\
48-
**Default**: undefined\
49-
**Example**: `<hello>World</hello>`
50-
51-
### indentSize (number)
52-
The size of the indentation.\
53-
**Default**: 2
54-
55-
### invalidXml (JSX.Element)
56-
When the xml is invalid, invalidXml component will be returned.\
57-
**Default**: `<div>Invalid XML!</div>`
58-
59-
### collapsible (boolean)
60-
Allow collapse/expand tags by click on them. When tag is collapsed its content and attributes are hidden.\
61-
**Default**: false
62-
63-
### initialCollapsedDepth (number)
64-
When the **collapsible** is true, this set the level that will be started as collapsed. For example, if you want to everything starts as collapsed, set 0.\
65-
**Default**: undefined
66-
67-
### theme (object)
68-
An object to customize the default theme.
69-
70-
| Key | Type | Default | Description |
71-
| --- | ---- | ------- | ----------- |
72-
| attributeKeyColor | color | #2a7ab0 | Set the attribute key color (`<tag attribute-key="hello" />`) |
73-
| attributeValueColor | color | #008000 | Set the attribute value color (` <tag attr="Attribute value">`) |
74-
| cdataColor | color | #1D781D | Set the cdata element color (`<![CDATA[some stuff]]>`) |
75-
| commentColor | color | #aaa | Set the comment color (`<!-- this is a comment -->`)
76-
| fontFamily | font | monospace | Set the font family
77-
| separatorColor | color | #333 | Set the separators colors (`<, >, </, />, =, <?, ?>`)
78-
| tagColor | color | #d43900 | Set the tag name color (`<tag-name />`) |
79-
| textColor | color | #333 | Set the text color (`<tag>Text</tag>`)|
46+
47+
```tsx
48+
<XMLViewer
49+
// A xml string to prettify.
50+
// Default: undefined
51+
xml="<hello>World</hello>"
52+
53+
// The size of the indentation.
54+
// Default: 2
55+
indentSize={2}
56+
57+
// When the xml is invalid, invalidXml component will be displayed.
58+
// Default: <div>Invalid XML!</div>
59+
invalidXml={<div>Invalid XML!</div>}
60+
61+
// Enable collapsing or expanding tags by clicking on them.
62+
// Default: false
63+
collapsible={false}
64+
65+
// When collapsible is true, this sets the level that will be started as collapsed.
66+
// Default: undefined
67+
initialCollapsedDepth={undefined}
68+
69+
// Displays line numbers on the left side when set to true.
70+
// Default: false
71+
showLineNumbers={false}
72+
73+
// An object to customize the theme.
74+
theme={{
75+
// Set the attribute key color (<tag attribute-key="hello" />)
76+
// Default: #2a7ab0
77+
attributeKeyColor: '#2a7ab0',
78+
79+
// Set the attribute value color (<tag attr="Attribute value">)
80+
// Default: #008000
81+
attributeValueColor: '#008000',
82+
83+
// Set the cdata element color (<![CDATA[some stuff]]>)
84+
// Default: #1D781D
85+
cdataColor: '#1D781D',
86+
87+
// Set the comment color (<!-- this is a comment -->)
88+
// Default: #aaa
89+
commentColor: '#aaa',
90+
91+
// Set the font family
92+
// Default: monospace
93+
fontFamily: 'monospace',
94+
95+
// Set the separators colors (<, >, </, />, =, <?, ?>)
96+
// Default: #333
97+
separatorColor: '#333',
98+
99+
// Set the tag name color (<tag-name />)
100+
// Default: #d43900
101+
tagColor: '#d43900',
102+
103+
// Set the text color (<tag>Text</tag>)
104+
// Default: #333
105+
textColor: '#333',
106+
107+
// Set the line numbers container background color
108+
// Default: #eee
109+
lineNumberBackground: '#eee',
110+
111+
// Set the line numbers color
112+
// Default: #222
113+
lineNumberColor: '#222',
114+
}}
115+
/>
116+
```
80117

81118
**Example**:
82119
Changing attribute key and value color
83-
``` jsx
84-
import React, { Component } from 'react'
85-
import XMLViewer from 'react-xml-viewer'
86120

87-
const xml = '<hello attr="World" />'
121+
```jsx
122+
import React, { Component } from 'react';
123+
import XMLViewer from 'react-xml-viewer';
124+
125+
const xml = '<hello attr="World" />';
88126
const customTheme = {
89-
"attributeKeyColor": "#FF0000",
90-
"attributeValueColor": "#000FF"
91-
}
127+
attributeKeyColor: '#FF0000',
128+
attributeValueColor: '#000FF',
129+
};
92130

93131
export function App() {
94132
return (
95133
<div>
96134
<XMLViewer xml={xml} theme={customTheme} />
97135
</div>
98-
)
136+
);
99137
}
100138
```
101139

package.json

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-xml-viewer",
3-
"version": "2.0.5",
3+
"version": "3.0.0",
44
"description": "Simple xml viewer component for React",
55
"author": "alissonmbr",
66
"license": "MIT",
@@ -31,7 +31,8 @@
3131
"storybook": "storybook dev -p 6006",
3232
"build-storybook": "storybook build",
3333
"test": "jest",
34-
"test-coverage": "jest --coverage"
34+
"test-coverage": "jest --coverage",
35+
"analyze": "npx vite-bundle-visualizer"
3536
},
3637
"peerDependencies": {
3738
"react": ">= 16.8.4",
@@ -40,14 +41,15 @@
4041
"devDependencies": {
4142
"@babel/preset-env": "^7.22.5",
4243
"@babel/preset-react": "^7.22.5",
43-
"@storybook/addon-essentials": "^7.0.23",
44-
"@storybook/addon-interactions": "^7.0.23",
45-
"@storybook/addon-links": "^7.0.23",
46-
"@storybook/blocks": "^7.0.23",
47-
"@storybook/react": "^7.0.23",
48-
"@storybook/react-vite": "^7.0.23",
49-
"@storybook/testing-library": "^0.2.0",
50-
"@testing-library/jest-dom": "^5.16.5",
44+
"@chromatic-com/storybook": "^3",
45+
"@storybook/addon-essentials": "^8.6.14",
46+
"@storybook/addon-interactions": "^8.6.14",
47+
"@storybook/addon-links": "^8.6.14",
48+
"@storybook/blocks": "^8.6.14",
49+
"@storybook/react": "^8.6.14",
50+
"@storybook/react-vite": "^8.6.14",
51+
"@storybook/test": "^8.6.14",
52+
"@testing-library/jest-dom": "^6.6.3",
5153
"@testing-library/react": "^14.0.0",
5254
"@types/jest": "^29.5.2",
5355
"@types/react": "^18.2.14",
@@ -71,10 +73,10 @@
7173
"prop-types": "^15.8.1",
7274
"react": "^18.2.0",
7375
"react-dom": "^18.2.0",
74-
"storybook": "^7.0.23",
76+
"storybook": "^8.6.14",
7577
"ts-jest": "^29.1.0",
7678
"typescript": "~5.0.2",
77-
"vite": "^4.3.9",
79+
"vite": "^4.5.11",
7880
"vite-plugin-dts": "^2.3.0",
7981
"vite-plugin-svgr": "^3.2.0",
8082
"vite-tsconfig-paths": "^4.2.0"
@@ -83,7 +85,7 @@
8385
"dist"
8486
],
8587
"dependencies": {
86-
"fast-xml-parser": "^4.5.0",
87-
"lodash": "^4.17.21"
88-
}
88+
"fast-xml-parser": "^4.5.0"
89+
},
90+
"packageManager": "[email protected]"
8991
}

src/components/CDataTag/index.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
11
import { useXMLViewerContext } from 'context/xml-viewer-context';
2+
import { useLineNumber } from 'hooks/useLineNumber';
23
import { ReactNode } from 'react';
34

45
export interface CDataTagProps {
56
indentation: string;
67
children: ReactNode;
78
isInline: boolean;
9+
keyValue: string;
810
}
911

1012
export function CDataTag(props: CDataTagProps) {
11-
const { indentation, children, isInline } = props;
13+
const { indentation, children, isInline, keyValue } = props;
1214
const { theme } = useXMLViewerContext();
15+
const openTagRef = useLineNumber<HTMLSpanElement>(keyValue);
16+
const closeTagRef = useLineNumber<HTMLSpanElement>(`${keyValue}-close`, !isInline);
1317

1418
return (
1519
<div style={{ color: theme.cdataColor }}>
16-
<span>{`${indentation}<![CDATA[`}</span>
20+
<span ref={openTagRef}>{`${indentation}<![CDATA[`}</span>
1721
{children}
18-
<span>{`${isInline ? '' : indentation}]]>`}</span>
22+
<span ref={closeTagRef}>{`${isInline ? '' : indentation}]]>`}</span>
1923
</div>
2024
);
2125
}

0 commit comments

Comments
 (0)