Compare commits

...

11 Commits
v2.4.0 ... main

Author SHA1 Message Date
dependabot[bot]
ba863af102
chore(deps-dev): bump http-proxy-middleware from 2.0.7 to 2.0.9 (#2687)
Bumps [http-proxy-middleware](https://github.com/chimurai/http-proxy-middleware) from 2.0.7 to 2.0.9.
- [Release notes](https://github.com/chimurai/http-proxy-middleware/releases)
- [Changelog](https://github.com/chimurai/http-proxy-middleware/blob/v2.0.9/CHANGELOG.md)
- [Commits](https://github.com/chimurai/http-proxy-middleware/compare/v2.0.7...v2.0.9)

---
updated-dependencies:
- dependency-name: http-proxy-middleware
  dependency-version: 2.0.9
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-06-26 12:55:47 +03:00
Roman Hotsiy
ce27184254 fix: fix headin slugs 2025-05-29 00:25:56 +08:00
Andrew Tatomyr
3ae251b7e4
docs: remove deprecated CLI commands from docs (#2691) 2025-05-20 19:47:37 +02:00
Alex Varchuk
00bc6edfc4
chore: v2.5.0 (#2684) 2025-04-14 18:17:50 +03:00
Alex Varchuk
45476135ad
chore: fix moderate vulnerabilities (#2683) 2025-04-14 16:45:31 +03:00
dependabot[bot]
05a04c85ed
chore(deps): bump @babel/runtime from 7.23.2 to 7.27.0 (#2679)
Bumps [@babel/runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime) from 7.23.2 to 7.27.0.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.27.0/packages/babel-runtime)

---
updated-dependencies:
- dependency-name: "@babel/runtime"
  dependency-version: 7.27.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-14 15:59:27 +03:00
Imamuzzaki Abu Salam
2db293bfb2
fix: enhance accessibility for menu items with keyboard support (#2655) 2025-04-14 15:54:15 +03:00
Imamuzzaki Abu Salam
1b4126fde4
feat: add keyboard navigation support to JsonViewer component (#2654) 2025-04-14 15:48:23 +03:00
dependabot[bot]
1fa13270a1
chore(deps): bump esbuild and esbuild-loader (#2661)
Bumps [esbuild](https://github.com/evanw/esbuild) to 0.25.0 and updates ancestor dependency [esbuild-loader](https://github.com/privatenumber/esbuild-loader). These dependencies need to be updated together.


Updates `esbuild` from 0.17.19 to 0.25.0
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/main/CHANGELOG-2023.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.17.19...v0.25.0)

Updates `esbuild-loader` from 3.0.1 to 4.3.0
- [Release notes](https://github.com/privatenumber/esbuild-loader/releases)
- [Commits](https://github.com/privatenumber/esbuild-loader/compare/v3.0.1...v4.3.0)

---
updated-dependencies:
- dependency-name: esbuild
  dependency-type: indirect
- dependency-name: esbuild-loader
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: kanoru <kanoru3101@gmail.com>
2025-04-08 15:47:37 +03:00
dependabot[bot]
7cedd59826
chore(deps): bump dompurify from 3.1.3 to 3.2.4 (#2667)
* chore(deps): bump dompurify from 3.1.3 to 3.2.4

Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.1.3 to 3.2.4.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.1.3...3.2.4)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): update dompurify

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: kanoru <kanoru3101@gmail.com>
2025-04-08 15:06:41 +03:00
dependabot[bot]
cab07bad3b
chore(deps): bump prismjs from 1.29.0 to 1.30.0 (#2672)
Bumps [prismjs](https://github.com/PrismJS/prism) from 1.29.0 to 1.30.0.
- [Release notes](https://github.com/PrismJS/prism/releases)
- [Changelog](https://github.com/PrismJS/prism/blob/master/CHANGELOG.md)
- [Commits](https://github.com/PrismJS/prism/compare/v1.29.0...v1.30.0)

---
updated-dependencies:
- dependency-name: prismjs
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-11 10:59:04 +02:00
11 changed files with 711 additions and 540 deletions

View File

@ -1,3 +1,17 @@
# [2.5.0](https://github.com/Redocly/redoc/compare/v2.4.0...v2.5.0) (2025-04-14)
### Bug Fixes
* enhance accessibility for menu items with keyboard support ([#2655](https://github.com/Redocly/redoc/issues/2655)) ([2db293b](https://github.com/Redocly/redoc/commit/2db293bfb2973497dd33f31dc99e97f5bb90bbe8))
### Features
* add keyboard navigation support to JsonViewer component ([#2654](https://github.com/Redocly/redoc/issues/2654)) ([1b4126f](https://github.com/Redocly/redoc/commit/1b4126fde4531387f49c90f52efbd0c0e5f7b6ea))
# [2.4.0](https://github.com/Redocly/redoc/compare/v2.3.0...v2.4.0) (2025-02-07)

View File

@ -12,9 +12,9 @@ With Redocly CLI, you can bundle your OpenAPI definition and API documentation
First, you need to install the `@redocly/cli` package.
You can install it [globally](../../cli/installation.md#install-globally) using npm or Yarn.
You can install it [globally](../../cli/installation#install-globally) using npm.
Or you can install it during [runtime](../../cli/installation.md#use-npx-at-runtime) using npx or Docker.
Or you can install it during [runtime](../../cli/installation#use-npx-at-runtime) using npx or Docker.
## Step 2 - Build the HTML file
@ -27,9 +27,9 @@ replacing `apis/openapi.yaml` with your API definition file's name and path:
redocly build-docs apis/openapi.yaml
```
See the [build-docs](../../cli/commands/build-docs.md) documentation for more information
See the [build-docs](../../cli/commands/build-docs) documentation for more information
on the different options and ways you can use the command.
Also, check out [Redocly CLI commands](../../cli/commands/index.md), for more
Also, check out [Redocly CLI commands](../../cli/commands), for more
information on the different things you can do with Redocly CLI including
linting, splitting, and bundling your API definition file.

View File

@ -45,34 +45,6 @@ section in the documentation.
If you want to view your Redoc output locally, you can simulate an HTTP server.
#### Redocly CLI
Redocly CLI is an open source command-line tool that includes a command
for simulating an HTTP server to provide a preview of your OpenAPI definition locally.
If you have [Redocly CLI](https://redocly.com/docs/cli/#installation-and-usage) installed, `cd` into your
project directory and run the following command:
```bash
redocly preview-docs openapi.yaml
```
Replace `openapi.yaml` in the example command with the file path to your OpenAPI definition.
By default, without providing a port, the preview starts on port 8080, and can be accessed at `http://localhost:8080`.
To exit the preview, use `control+C`.
You can alter the port if you are using 8080 already, for example:
```bash
redocly preview-docs -p 8888 openapi.yaml
```
Replace `openapi.yaml` in the example command with the file path to your OpenAPI definition.
For more information about the `preview-docs` command, refer to
[Redocly CLI commands](https://redocly.com/docs/cli/commands/preview-docs/#preview-docs) in the Redocly CLI documentation.
#### Python
If you have [Python 3](https://www.python.org/downloads/) installed, `cd` into your

View File

@ -57,7 +57,7 @@ Check out the [deployment documentation](./deployment/intro.md) for more options
Redoc is highly configurable. Each deployment option accepts configuration in a way that's appropriate to that platform, but the options are the same for each. For example:
* Using [Redocly CLI](../cli/index.md), configuration goes in the `redocly.yaml` file, or can be supplied as command line parameters, such as `--theme.openapi.disableSearch`.
* Using [Redocly CLI](../cli), configuration goes in the `redocly.yaml` file, or can be supplied as command line parameters, such as `--theme.openapi.disableSearch`.
* Using HTML or React, configure by setting `option` in the tag.
Here's a sample `redocly.yaml` configuration file, showing a few common settings and tweaking some of the visual theme settings:
@ -85,13 +85,13 @@ theme:
Redocly CLI detects a file named `redocly.yaml` in the same directory as you run the command and uses it. See the documentation with a command like this:
```sh
redocly preview-docs openapi.yaml
redocly build-docs openapi.yaml
```
There are many, many more options available. Visit the [configuration reference](./config.md) for a complete list.
## Next steps
* If you are new to OpenAPI, try the [OpenAPI starter project](../cli/openapi-starter.md) for a great introduction.
* If you are new to OpenAPI, try the [OpenAPI starter project](../cli/openapi-starter) for a great introduction.
* Ready to build documentation from an existing OpenAPI file? Go to the [Redoc quickstart](./quickstart.md) and get started.
* Learn more about the project by visiting [Redoc on GitHub](https://github.com/Redocly/redoc).

View File

@ -12,38 +12,39 @@ You can use the following [vendor extensions](https://redocly.com/docs/openapi-v
- [x-tagGroups example](#x-taggroups-example)
- [Info Object](#info-object)
- [x-logo](#x-logo)
- [How to use with Redoc](#how-to-use-with-redoc-2)
- [How to use with Redoc](#how-to-use-with-redoc-1)
- [Logo Object](#logo-object)
- [Fixed fields](#fixed-fields-1)
- [x-logo example](#x-logo-example)
- [Tag Object](#tag-object)
- [x-traitTag](#x-traittag)
- [How to use with Redoc](#how-to-use-with-redoc-3)
- [How to use with Redoc](#how-to-use-with-redoc-2)
- [x-traitTag example](#x-traittag-example)
- [x-displayName](#x-displayname)
- [Operation Object vendor extensions](#operation-object-vendor-extensions)
- [x-codeSamples](#x-codesamples)
- [How to use with Redoc](#how-to-use-with-redoc-4)
- [How to use with Redoc](#how-to-use-with-redoc-3)
- [Code Sample Object](#code-sample-object)
- [Fixed fields](#fixed-fields-2)
- [Code Sample Object example](#code-sample-object-example)
- [x-badges](#x-badges)
- [Parameter Object](#parameter-object)
- [x-examples](#x-examples)
- [How to use with Redoc](#how-to-use-with-redoc-5)
- [How to use with Redoc](#how-to-use-with-redoc-4)
- [Response Object vendor extensions](#response-object-vendor-extensions)
- [x-summary](#x-summary)
- [How to use with Redoc](#how-to-use-with-redoc-6)
- [How to use with Redoc](#how-to-use-with-redoc-5)
- [Schema Object](#schema-object)
- [x-nullable](#x-nullable)
- [How to use with Redoc](#how-to-use-with-redoc-7)
- [How to use with Redoc](#how-to-use-with-redoc-6)
- [x-additionalPropertiesName](#x-additionalpropertiesname)
- [How to use with Redoc](#how-to-use-with-redoc-9)
- [How to use with Redoc](#how-to-use-with-redoc-7)
- [x-additionalPropertiesName example](#x-additionalpropertiesname-example)
- [x-explicitMappingOnly](#x-explicitmappingonly)
- [How to use with Redoc](#how-to-use-with-redoc-10)
- [How to use with Redoc](#how-to-use-with-redoc-8)
- [x-explicitMappingOnly example](#x-explicitmappingonly-example)
- [x-enumDescriptions](#x-enumdescriptions)
- [How to use with Redoc](#how-to-use-with-redoc-11)
- [How to use with Redoc](#how-to-use-with-redoc-9)
- [x-enumDescriptions example](#x-enumdescriptions-example)
## Swagger Object
@ -67,6 +68,7 @@ Before you use `x-tagGroups`, make sure you **add all tags to a group**, since a
#### Tag Group Object
Information about tags group
##### Fixed fields
| Field Name | Type | Description |
| :---------- | :--------: | :---------- |
| name | string | The group name |
@ -120,6 +122,7 @@ Extends the OpenAPI [Info Object](https://redocly.com/docs/openapi-visual-refere
The information about API logo
#### Fixed fields
| Field Name | Type | Description |
| :-------------- | :------: | :---------- |
| url | string | The URL pointing to the spec logo. MUST be in the format of a URL. It SHOULD be an absolute URL so your API definition is usable from any location |
@ -158,6 +161,7 @@ info:
Extends the OpenAPI [Tag Object](https://redocly.com/docs/openapi-visual-reference/tags/)
### x-traitTag
| Field Name | Type | Description |
| :------------- | :------: | :---------- |
| x-traitTag | boolean | In Swagger two operations can have multiple tags. This property distinguishes between tags that are used to group operations (default) from tags that are used to mark operation with certain trait (`true` value) |
@ -192,6 +196,7 @@ x-traitTag: true
Extends the OpenAPI [Operation Object](https://redocly.com/docs/openapi-visual-reference/operation/)
### x-codeSamples
| Field Name | Type | Description |
| :------------- | :------: | :---------- |
| x-codeSamples | [ [Code Sample Object](#code-sample-object) ] | A list of code samples associated with operation |
@ -205,6 +210,7 @@ Extends the OpenAPI [Operation Object](https://redocly.com/docs/openapi-visual-r
Operation code sample
#### Fixed fields
| Field Name | Type | Description |
| :---------- | :------: | :----------- |
| lang | string | Code sample language. Value should be one of the following [list](https://github.com/github/linguist/blob/master/lib/linguist/popular.yml) |
@ -227,6 +233,7 @@ source: console.log('Hello World');
```
### x-badges
| Field Name | Type | Description |
| :------------- | :------: | :---------- |
| x-badges | [[Badge Object](https://redocly.com/docs/realm/author/reference/openapi-extensions/x-badges#badge-object)] | A list of badges associated with the operation |
@ -235,6 +242,7 @@ source: console.log('Hello World');
Extends the OpenAPI [Parameter Object](https://redocly.com/docs/openapi-visual-reference/parameter/)
### x-examples
| Field Name | Type | Description |
| :------------- | :------: | :---------- |
| x-examples | [Example Object](https://redocly.com/docs/openapi-visual-reference/example/) | Object that contains examples for the request. Applies when `in` is `body` and mime-type is `application/json` |
@ -246,6 +254,7 @@ Extends the OpenAPI [Parameter Object](https://redocly.com/docs/openapi-visual-r
Extends the OpenAPI [Response Object](https://redocly.com/docs/openapi-visual-reference/response/).
### x-summary
| Field Name | Type | Description |
| :------------- | :------: | :---------- |
| x-summary | string | a short summary of the response |
@ -257,6 +266,7 @@ If specified, you can use `x-summary` as the response button text, with descript
Extends the OpenAPI [Schema Object](https://redocly.com/docs/openapi-visual-reference/schemas/)
### x-nullable
| Field Name | Type | Description |
| :------------- | :------: | :---------- |
| x-nullable | boolean | marks schema as a nullable |
@ -325,6 +335,7 @@ Pet:
Shows in the selectpicker only the items `cat` and `bee`, even though the `Dog` class inherits from the `Pet` class.
### x-enumDescriptions
| Field Name | Type | Description |
| :------------- | :------: | :---------- |
| x-enumDescriptions | [[Enum Description Object](https://redocly.com/docs/realm/author/reference/openapi-extensions/x-enum-descriptions#enum-description-object)] | A list of the enum values and descriptions to include in the documentation. |

1085
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "redoc",
"version": "2.4.0",
"version": "2.5.0",
"description": "ReDoc",
"repository": {
"type": "git",
@ -93,7 +93,7 @@
"cypress": "^13.8.1",
"enzyme": "^3.11.0",
"enzyme-to-json": "^3.6.2",
"esbuild-loader": "^3.0.1",
"esbuild-loader": "^4.3.0",
"eslint": "^7.27.0",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-react": "^7.34.2",
@ -141,7 +141,7 @@
"@redocly/openapi-core": "^1.4.0",
"classnames": "^2.3.2",
"decko": "^1.2.0",
"dompurify": "^3.0.6",
"dompurify": "^3.2.4",
"eventemitter3": "^5.0.1",
"json-pointer": "^0.6.2",
"lunr": "^2.3.9",

View File

@ -41,6 +41,7 @@ const Json = (props: JsonProps) => {
<OptionsContext.Consumer>
{options => (
<PrismDiv
tabIndex={0}
className={props.className}
// tslint:disable-next-line
ref={node => setNode(node!)}

View File

@ -6,11 +6,14 @@ import { StylingMarkdownProps } from './Markdown';
import { StyledMarkdownBlock } from './styled.elements';
import styled from 'styled-components';
// Workaround for DOMPurify type issues (https://github.com/cure53/DOMPurify/issues/1034)
const dompurify = DOMPurify['default'] as DOMPurify.DOMPurify;
const StyledMarkdownSpan = styled(StyledMarkdownBlock)`
display: inline;
`;
const sanitize = (sanitize, html) => (sanitize ? DOMPurify.sanitize(html) : html);
const sanitize = (sanitize, html) => (sanitize ? dompurify.sanitize(html) : html);
export function SanitizedMarkdownHTML({
inline,

View File

@ -2,14 +2,14 @@ import { observer } from 'mobx-react';
import * as React from 'react';
import { ShelfIcon } from '../../common-elements/shelfs';
import type { IMenuItem } from '../../services';
import { OperationModel } from '../../services';
import { shortenHTTPVerb } from '../../utils/openapi';
import { MenuItems } from './MenuItems';
import { MenuItemLabel, MenuItemLi, MenuItemTitle, OperationBadge } from './styled.elements';
import { l } from '../../services/Labels';
import { scrollIntoViewIfNeeded } from '../../utils';
import { shortenHTTPVerb } from '../../utils/openapi';
import { OptionsContext } from '../OptionsProvider';
import type { IMenuItem } from '../../services';
import { MenuItems } from './MenuItems';
import { MenuItemLabel, MenuItemLi, MenuItemTitle, OperationBadge } from './styled.elements';
export interface MenuItemProps {
item: IMenuItem;
@ -47,9 +47,18 @@ export class MenuItem extends React.Component<MenuItemProps> {
<MenuItemLi
tabIndex={0}
onClick={this.activate}
onKeyDown={evt => {
// Space or Enter key will activate the menu item
if (evt.key === 'Enter' || evt.key === ' ') {
this.props.onActivate!(this.props.item);
evt.stopPropagation();
}
}}
depth={item.depth}
data-item-id={item.id}
role="menuitem"
aria-label={item.sidebarLabel}
aria-expanded={item.expanded}
>
{item.type === 'operation' ? (
<OperationMenuItemContent {...this.props} item={item as OperationModel} />

View File

@ -2,6 +2,7 @@
import { mount, ReactWrapper } from 'enzyme';
import * as React from 'react';
import { act } from 'react';
import { JsonViewer } from '../';
import { withTheme } from '../testProviders';
@ -50,5 +51,54 @@ describe('Components', () => {
expect(flatDataComponent.html()).not.toContain('Expand all');
expect(flatDataComponent.html()).not.toContain('Collapse all');
});
describe('Keyboard Navigation', () => {
let component: ReactWrapper;
const data = {
a: 1,
b: {
c:
// Long string to test horizontal scrolling
Array(100).fill('hello').join(''),
},
};
beforeEach(() => {
component = mount(withTheme(<JsonViewer data={data} />));
ClipboardService.copySelected = origCopySelected;
});
test('should handle arrow key navigation', () => {
const prismDiv = component.find('div[tabIndex=0]');
const divElement = prismDiv.getDOMNode();
// Mock scrollLeft before events
Object.defineProperty(divElement, 'scrollLeft', {
get: jest.fn(() => 0),
set: jest.fn(),
});
// Trigger events inside act()
act(() => {
divElement.dispatchEvent(
new KeyboardEvent('keydown', {
key: 'ArrowRight',
bubbles: true,
}),
);
});
act(() => {
divElement.dispatchEvent(
new KeyboardEvent('keydown', {
key: 'ArrowLeft',
bubbles: true,
}),
);
});
expect(divElement.scrollLeft).toBe(0);
});
});
});
});