diff --git a/demo/examples/openapi-array-query-params.yaml b/demo/examples/openapi-array-query-params.yaml
new file mode 100644
index 00000000..189c551e
--- /dev/null
+++ b/demo/examples/openapi-array-query-params.yaml
@@ -0,0 +1,43 @@
+openapi: 3.0.3
+info:
+ version: 1.0.0
+ title: ""
+servers:
+ - url: https://example.com
+paths:
+ /Things:
+ get:
+ summary: View Things
+ parameters:
+ - name: "arrayParam"
+ in: "query"
+ required: false
+ description: "You can pass 0, 1 or 2 occurrences of this in the query string"
+ style: "form"
+ explode: true
+ schema:
+ type: "array"
+ maxItems: 2
+ items:
+ type: "string"
+ responses:
+ "200":
+ description: OK
+ /Stuff:
+ get:
+ summary: View Stuff
+ parameters:
+ - name: "arrayParam"
+ in: "query"
+ required: false
+ description: "You can pass 0, 1 or 2 occurrences of this in the query string"
+ style: "pipeDelimited"
+ explode: false
+ schema:
+ type: "array"
+ maxItems: 2
+ items:
+ type: "string"
+ responses:
+ "200":
+ description: OK
diff --git a/packages/docusaurus-plugin-openapi/src/openapi/types.ts b/packages/docusaurus-plugin-openapi/src/openapi/types.ts
index 748ca606..2ac2ad07 100644
--- a/packages/docusaurus-plugin-openapi/src/openapi/types.ts
+++ b/packages/docusaurus-plugin-openapi/src/openapi/types.ts
@@ -179,7 +179,7 @@ export interface ParameterObject {
allowEmptyValue?: boolean;
//
style?: string;
- explode?: string;
+ explode?: boolean;
allowReserved?: boolean;
schema?: SchemaObject;
example?: any;
diff --git a/packages/docusaurus-theme-openapi/src/theme/ApiDemoPanel/ParamOptions/index.tsx b/packages/docusaurus-theme-openapi/src/theme/ApiDemoPanel/ParamOptions/index.tsx
index 9099026d..10e2d2ba 100644
--- a/packages/docusaurus-theme-openapi/src/theme/ApiDemoPanel/ParamOptions/index.tsx
+++ b/packages/docusaurus-theme-openapi/src/theme/ApiDemoPanel/ParamOptions/index.tsx
@@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
* ========================================================================== */
-import React, { useState, useEffect } from "react";
+import React, { useState } from "react";
import { nanoid } from "@reduxjs/toolkit";
@@ -21,6 +21,11 @@ interface ParamProps {
param: Param;
}
+interface Item {
+ id: string;
+ value?: string;
+}
+
function ParamOption({ param }: ParamProps) {
if (param.schema?.type === "array" && param.schema.items?.enum) {
return ;
@@ -161,10 +166,16 @@ function ArrayItem({
}
function ParamArrayFormItem({ param }: ParamProps) {
- const [items, setItems] = useState<{ id: string; value?: string }[]>([]);
+ const [items, setItems] = useState- ([]);
const dispatch = useTypedDispatch();
function handleAddItem() {
+ if (
+ param?.schema?.maxItems !== undefined &&
+ items.length >= param.schema.maxItems
+ ) {
+ return;
+ }
setItems((i) => [
...i,
{
@@ -173,7 +184,7 @@ function ParamArrayFormItem({ param }: ParamProps) {
]);
}
- useEffect(() => {
+ function updateItems(items: Array
- ) {
const values = items
.map((item) => item.value)
.filter((item): item is string => !!item);
@@ -184,12 +195,13 @@ function ParamArrayFormItem({ param }: ParamProps) {
value: values.length > 0 ? values : undefined,
})
);
- }, [dispatch, items, param]);
+ }
function handleDeleteItem(itemToDelete: { id: string }) {
return () => {
const newItems = items.filter((i) => i.id !== itemToDelete.id);
setItems(newItems);
+ updateItems(newItems);
};
}
@@ -202,6 +214,7 @@ function ParamArrayFormItem({ param }: ParamProps) {
return i;
});
setItems(newItems);
+ updateItems(newItems);
};
}
@@ -230,7 +243,14 @@ function ParamArrayFormItem({ param }: ParamProps) {
))}
-