@umami/shiso 1.13.0 → 1.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { Nr as __commonJSMin, Pr as __toESM } from "./docs.js";
1
+ import { Ar as __commonJSMin, jr as __toESM } from "./docs.js";
2
2
  import { n as __name } from "./chunk-Y2CYZVJY.js";
3
3
  import { a as nogamma, c as Rgb, d as define_default, f as extend, g as require_dayjs_min, i as hue, m as log, p as select_default, s as Color, u as rgbConvert } from "./src.js";
4
4
  import { H as setAccDescription, K as setDiagramTitle, U as setAccTitle, a as clear, c as configureSvgSize, s as common_default, v as getAccDescription, w as getDiagramTitle, x as getConfig2, y as getAccTitle } from "./chunk-DU6HZSFF.js";
@@ -1,4 +1,4 @@
1
- import { Nr as __commonJSMin, Pr as __toESM } from "./docs.js";
1
+ import { Ar as __commonJSMin, jr as __toESM } from "./docs.js";
2
2
  import { n as __name } from "./chunk-Y2CYZVJY.js";
3
3
 
4
4
  //#region ../../node_modules/.pnpm/dayjs@1.11.23/node_modules/dayjs/dayjs.min.js
@@ -1,3 +1,3 @@
1
- import { $t as Accordion, Bt as Card, C as Tooltip, Ct as useSetPanelContent, Et as Frame, Gt as Info, Ht as Callout, Jt as Warning, Kt as Note, Mt as Column, Nt as Columns, Ot as Expandable, Pt as CodeGroup, Rt as Changelog, S as TreeFolder, Sn as mermaidSource, St as usePanelContent, Tt as Icon, Ut as Check, Vt as CardGroup, Wt as Danger, Xt as Button, Yt as WarningBanner, Zt as Badge, _ as FileTree, _t as PropertiesTable, b as Tree, bt as Panel, dt as Tiles, en as AccordionGroup, ft as Tab, gt as ResponseField, ht as Steps, mt as Step, n as ZoomableImage, pt as Tabs, qt as Tip, ut as Tile, v as FileTreeFile, vt as Param, wt as Link, x as TreeFile, xn as Mermaid, xt as PanelProvider, y as FileTreeFolder, yt as ParamField, zt as Update } from "./chunks/docs.js";
1
+ import { At as Column, Bt as Callout, C as Tooltip, Ct as Icon, Et as Expandable, Gt as Tip, Ht as Danger, It as Changelog, Jt as Button, Kt as Warning, Lt as Update, Mt as CodeGroup, Qt as AccordionGroup, Rt as Card, S as TreeFolder, St as Link, Ut as Info, Vt as Check, Wt as Note, Yt as Badge, Zt as Accordion, _ as FileTree, _t as Param, b as Tree, bn as mermaidSource, bt as usePanelContent, dt as Tiles, ft as Tab, gt as PropertiesTable, ht as Steps, jt as Columns, mt as Step, n as ZoomableImage, pt as Tabs, qt as WarningBanner, ut as Tile, v as FileTreeFile, vt as Panel, wt as Frame, x as TreeFile, xt as useSetPanelContent, y as FileTreeFolder, yn as Mermaid, yt as PanelProvider, zt as CardGroup } from "./chunks/docs.js";
2
2
 
3
- export { Accordion, AccordionGroup, Badge, Button, Callout, Card, CardGroup, Changelog, Check, CodeGroup, Column, Columns, Danger, Expandable, FileTree, FileTreeFile, FileTreeFolder, Frame, Icon, Info, Link, Mermaid, Note, Panel, PanelProvider, Param, ParamField, PropertiesTable, ResponseField, Step, Steps, Tab, Tabs, Tile, Tiles, Tip, Tooltip, Tree, TreeFile, TreeFolder, Update, Warning, WarningBanner, ZoomableImage, mermaidSource, usePanelContent, useSetPanelContent };
3
+ export { Accordion, AccordionGroup, Badge, Button, Callout, Card, CardGroup, Changelog, Check, CodeGroup, Column, Columns, Danger, Expandable, FileTree, FileTreeFile, FileTreeFolder, Frame, Icon, Info, Link, Mermaid, Note, Panel, PanelProvider, Param, PropertiesTable, Step, Steps, Tab, Tabs, Tile, Tiles, Tip, Tooltip, Tree, TreeFile, TreeFolder, Update, Warning, WarningBanner, ZoomableImage, mermaidSource, usePanelContent, useSetPanelContent };
@@ -1,4 +1,4 @@
1
- import { Sr as BrowserRouter } from "./chunks/docs.js";
1
+ import { yr as BrowserRouter } from "./chunks/docs.js";
2
2
  import { h as BASE_URL, t as App } from "./chunks/App.js";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
 
@@ -1,10 +1,10 @@
1
- import { Ar as createPath, Er as Router, Mr as ABSOLUTE_URL_REGEX, jr as parsePath } from "./chunks/docs.js";
1
+ import { Cr as Router, Dr as createPath, Or as parsePath, kr as ABSOLUTE_URL_REGEX } from "./chunks/docs.js";
2
2
  import { a as docsSite, c as getSeo, d as standalonePages, f as getDocModule, g as toAbsoluteUrl, h as BASE_URL, i as docsHomeUrl, l as siteConfig, m as getScopeForPage, n as buildHead, o as getLocaleByPathname, p as getLastModified, r as renderHeadToString, s as getRedirects, t as App, u as siteName } from "./chunks/App.js";
3
3
  import * as React$1 from "react";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
  import { renderToString } from "react-dom/server";
6
6
 
7
- //#region ../../node_modules/.pnpm/react-router@8.3.0_react-do_c27277bcf657dc321048682bd02ab633/node_modules/react-router/dist/production/lib/dom/server.js
7
+ //#region ../../node_modules/.pnpm/react-router@8.3.0_react-dom@19.2.8_react@19.2.8__react@19.2.8/node_modules/react-router/dist/production/lib/dom/server.js
8
8
  /**
9
9
  * react-router v8.3.0
10
10
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umami/shiso",
3
- "version": "1.13.0",
3
+ "version": "1.15.0",
4
4
  "description": "Open-source documentation framework for Markdown and MDX sites.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -97,7 +97,7 @@ function typeLabel(spec, schema) {
97
97
  return `enum<${baseType(schema)}>`;
98
98
  }
99
99
  if (schema.oneOf || schema.anyOf) {
100
- return 'oneOf';
100
+ return schema.oneOf ? 'oneOf' : 'anyOf';
101
101
  }
102
102
  if (schema.type === 'array' || (Array.isArray(schema.type) && schema.type.includes('array'))) {
103
103
  const items = schema.items ? deref(spec, schema.items) : undefined;
@@ -159,6 +159,23 @@ export function schemaTree(spec, schema, { name, required, seen = new Set(), dep
159
159
  depth: depth + 1,
160
160
  }),
161
161
  );
162
+ // Plain scalar alternatives fit in the type cell; keep richer variants
163
+ // expanded so descriptions, constraints, and nested properties remain visible.
164
+ if (
165
+ variants.length <= MAX_CHILDREN &&
166
+ node.children.every(
167
+ child =>
168
+ /^(string|number|integer|boolean|null)$/.test(child.type) &&
169
+ !child.description &&
170
+ !child.enum &&
171
+ child.default === undefined &&
172
+ !child.deprecated &&
173
+ !child.children?.length,
174
+ )
175
+ ) {
176
+ node.type = [...new Set(node.children.map(child => child.type))].join(' | ');
177
+ delete node.children;
178
+ }
162
179
  return node;
163
180
  }
164
181
 
@@ -588,13 +605,26 @@ export function hasOperationParameters(operation) {
588
605
  );
589
606
  }
590
607
 
608
+ function operationParameterSections(operation) {
609
+ return [
610
+ { location: 'header', heading: 'Headers', id: 'headers' },
611
+ { location: 'path', heading: 'Path parameters', id: 'path-parameters' },
612
+ { location: 'query', heading: 'Query parameters', id: 'query-parameters' },
613
+ { location: 'cookie', heading: 'Cookie parameters', id: 'cookie-parameters' },
614
+ ].filter(
615
+ ({ location }) =>
616
+ operation.parameters[location].length > 0 ||
617
+ (location === 'header' && operation.security.length > 0),
618
+ );
619
+ }
620
+
591
621
  /**
592
622
  * Anchor ids for the generated sections, in render order. Mirrors
593
623
  * operationSections in src/lib/openapi.ts (asserted by tests/openapi.test.mjs).
594
624
  */
595
625
  export function operationAnchors(operation) {
596
626
  return [
597
- ...(hasOperationParameters(operation) ? ['parameters'] : []),
627
+ ...operationParameterSections(operation).map(section => section.id),
598
628
  ...(operation.requestBody ? ['request-body'] : []),
599
629
  ...(operation.responses.length ? ['responses'] : []),
600
630
  ...(operation.samples.length ? ['code-samples'] : []),
@@ -617,13 +647,6 @@ export function normalizeOperationKey(value) {
617
647
 
618
648
  /** Search-index sections for an operation, matching operationAnchors ids. */
619
649
  export function operationSearchSections(operation) {
620
- const allParameters = [
621
- ...operation.parameters.path,
622
- ...operation.parameters.query,
623
- ...operation.parameters.header,
624
- ...operation.parameters.cookie,
625
- ];
626
-
627
650
  return [
628
651
  {
629
652
  heading: undefined,
@@ -632,11 +655,16 @@ export function operationSearchSections(operation) {
632
655
  .filter(Boolean)
633
656
  .join(' '),
634
657
  },
635
- {
636
- heading: 'Parameters',
637
- id: 'parameters',
638
- text: allParameters.map(schemaText).join(' '),
639
- },
658
+ ...operationParameterSections(operation).map(({ location, heading, id }) => ({
659
+ heading,
660
+ id,
661
+ text: [
662
+ ...operation.parameters[location].map(schemaText),
663
+ ...(location === 'header' && operation.security.length > 0
664
+ ? ['Authorization Authentication credentials']
665
+ : []),
666
+ ].join(' '),
667
+ })),
640
668
  {
641
669
  heading: 'Request body',
642
670
  id: 'request-body',
@@ -2,16 +2,10 @@ import { CodeBlock } from '@/components/CodeBlock';
2
2
  import { Badge } from '@/components/docs/Badge';
3
3
  import { CodeGroup } from '@/components/docs/CodeGroup';
4
4
  import { Expandable } from '@/components/docs/Expandable';
5
- import { ParamField } from '@/components/docs/ParamField';
6
- import { ResponseField } from '@/components/docs/ResponseField';
7
- import { styles } from '@/components/docs/styles';
8
- import { operationSections, statusColor } from '@/lib/openapi';
5
+ import { PropertiesTable } from '@/components/docs/PropertiesTable';
6
+ import { operationParameterSections, operationSections, statusColor } from '@/lib/openapi';
9
7
  import type { NormalizedOperation, SchemaNode } from '@/lib/types';
10
8
 
11
- type ParamLocation = 'path' | 'query' | 'header' | 'cookie';
12
-
13
- const PARAM_LOCATIONS: ParamLocation[] = ['path', 'query', 'header', 'cookie'];
14
-
15
9
  function FieldChildren({ node }: { node: SchemaNode }) {
16
10
  return (
17
11
  <>
@@ -27,46 +21,48 @@ function FieldChildren({ node }: { node: SchemaNode }) {
27
21
  ))}
28
22
  </div>
29
23
  )}
30
- {node.children && node.children.length > 0 && (
31
- <Expandable title="properties">
32
- {node.children.map(child => (
33
- <SchemaField key={child.name || child.type} node={child} />
34
- ))}
35
- </Expandable>
36
- )}
37
24
  </>
38
25
  );
39
26
  }
40
27
 
41
- function SchemaField({ node }: { node: SchemaNode }) {
42
- const hasDetails = Boolean(node.description || node.enum?.length || node.children?.length);
28
+ function schemaDetails(node: SchemaNode) {
29
+ if (!node.children?.length) return undefined;
43
30
 
44
31
  return (
45
- <ResponseField
46
- name={node.name || node.type}
47
- type={node.name ? node.type : undefined}
48
- required={node.required}
49
- deprecated={node.deprecated}
50
- default={node.default}
32
+ <Expandable
33
+ title={node.type === 'oneOf' || node.type === 'anyOf' ? 'Allowed types' : 'properties'}
51
34
  >
52
- {hasDetails ? <FieldChildren node={node} /> : null}
53
- </ResponseField>
35
+ <SchemaTable nodes={node.children} />
36
+ </Expandable>
37
+ );
38
+ }
39
+
40
+ function SchemaTable({ nodes }: { nodes: SchemaNode[] }) {
41
+ return (
42
+ <PropertiesTable>
43
+ {nodes.map(node => (
44
+ <PropertiesTable.Row
45
+ key={node.name || node.type}
46
+ name={node.name || node.type}
47
+ type={node.type}
48
+ required={node.required}
49
+ deprecated={node.deprecated}
50
+ default={node.default}
51
+ details={schemaDetails(node)}
52
+ >
53
+ <FieldChildren node={node} />
54
+ </PropertiesTable.Row>
55
+ ))}
56
+ </PropertiesTable>
54
57
  );
55
58
  }
56
59
 
57
60
  /** Renders a schema tree: a root object's properties, or the node itself. */
58
61
  function SchemaFields({ node }: { node: SchemaNode }) {
59
- if (!node.name && node.children?.length) {
60
- return (
61
- <>
62
- {node.children.map(child => (
63
- <SchemaField key={child.name || child.type} node={child} />
64
- ))}
65
- </>
66
- );
67
- }
68
-
69
- return <SchemaField node={node} />;
62
+ const isUnion = node.type === 'oneOf' || node.type === 'anyOf';
63
+ return (
64
+ <SchemaTable nodes={!node.name && !isUnion && node.children?.length ? node.children : [node]} />
65
+ );
70
66
  }
71
67
 
72
68
  function HighlightedCode({
@@ -110,35 +106,34 @@ export interface OpenApiOperationProps {
110
106
  /** The generated reference for one API operation, rendered under the page body. */
111
107
  export function OpenApiOperation({ operation }: OpenApiOperationProps) {
112
108
  const sections = new Map(operationSections(operation).map(entry => [entry.name, entry.id]));
113
- const showParameters = sections.has('Parameters');
114
109
 
115
110
  return (
116
111
  <div className="docs-markdown">
117
- {showParameters && (
118
- <section>
119
- <h2 id={sections.get('Parameters')}>Parameters</h2>
120
- <div className={styles.fieldGroup}>
121
- {operation.security.length > 0 && (
122
- <ParamField header="Authorization" type="string" required>
112
+ {operationParameterSections(operation).map(({ location, name }) => (
113
+ <section key={location}>
114
+ <h2 id={sections.get(name)}>{name}</h2>
115
+ <PropertiesTable>
116
+ {location === 'header' && operation.security.length > 0 && (
117
+ <PropertiesTable.Row name="Authorization" type="string" required>
123
118
  Authentication credentials, e.g. <code>Bearer &lt;token&gt;</code>.
124
- </ParamField>
119
+ </PropertiesTable.Row>
125
120
  )}
126
- {PARAM_LOCATIONS.map(location =>
127
- operation.parameters[location].map(parameter => (
128
- <ParamField
129
- key={`${location}-${parameter.name}`}
130
- {...{ [location]: parameter.name }}
131
- type={parameter.type}
132
- required={parameter.required}
133
- >
134
- <FieldChildren node={{ ...parameter, name: undefined, description: undefined }} />
135
- {parameter.description}
136
- </ParamField>
137
- )),
138
- )}
139
- </div>
121
+ {operation.parameters[location].map(parameter => (
122
+ <PropertiesTable.Row
123
+ key={parameter.name}
124
+ name={parameter.name || parameter.type}
125
+ type={parameter.type}
126
+ required={parameter.required}
127
+ deprecated={parameter.deprecated}
128
+ default={parameter.default}
129
+ details={schemaDetails(parameter)}
130
+ >
131
+ <FieldChildren node={parameter} />
132
+ </PropertiesTable.Row>
133
+ ))}
134
+ </PropertiesTable>
140
135
  </section>
141
- )}
136
+ ))}
142
137
  {operation.requestBody && (
143
138
  <section>
144
139
  <h2 id={sections.get('Request body')}>Request body</h2>
@@ -166,11 +161,7 @@ export function OpenApiOperation({ operation }: OpenApiOperationProps) {
166
161
  <span className="text-muted-foreground text-sm">{response.description}</span>
167
162
  )}
168
163
  </div>
169
- {response.schema && (
170
- <div className={styles.fieldGroup}>
171
- <SchemaFields node={response.schema} />
172
- </div>
173
- )}
164
+ {response.schema && <SchemaFields node={response.schema} />}
174
165
  {response.example && (
175
166
  <HighlightedCode
176
167
  language="json"
@@ -0,0 +1,6 @@
1
+ import type { ReactNode } from 'react';
2
+ import { styles } from './styles';
3
+
4
+ export function Param({ children }: { children?: ReactNode }) {
5
+ return <code className={styles.code}>{children}</code>;
6
+ }
@@ -1,13 +1,24 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import { Badge } from './Badge';
3
- import type { ResponseFieldProps } from './ResponseField';
4
3
  import { decodeHtmlEntities, toElementArray } from './utils';
5
4
 
5
+ type FieldValue = string | number | boolean | null | undefined;
6
+
7
+ export interface PropertiesTableRowProps {
8
+ name: string;
9
+ type?: FieldValue;
10
+ default?: FieldValue;
11
+ required?: boolean;
12
+ deprecated?: boolean;
13
+ details?: ReactNode;
14
+ children?: ReactNode;
15
+ }
16
+
6
17
  export interface PropertiesTableProps {
7
18
  children?: ReactNode;
8
19
  }
9
20
 
10
- function displayValue(value: ResponseFieldProps['type']): string | undefined {
21
+ function displayValue(value: PropertiesTableRowProps['type']): string | undefined {
11
22
  if (typeof value === 'string') {
12
23
  return decodeHtmlEntities(value);
13
24
  }
@@ -16,7 +27,7 @@ function displayValue(value: ResponseFieldProps['type']): string | undefined {
16
27
  }
17
28
 
18
29
  export function PropertiesTable({ children }: PropertiesTableProps) {
19
- const rows = toElementArray<ResponseFieldProps>(children);
30
+ const rows = toElementArray<PropertiesTableRowProps>(children);
20
31
 
21
32
  if (!rows.length) {
22
33
  return null;
@@ -25,47 +36,66 @@ export function PropertiesTable({ children }: PropertiesTableProps) {
25
36
  // Rendered as a plain table so the .docs-markdown table rules in global.css
26
37
  // style it exactly like a GFM table; only column widths are set here.
27
38
  return (
28
- <div className="my-4 overflow-x-auto">
29
- <table className="m-0 min-w-[40rem] table-fixed">
39
+ <div data-slot="properties-table" className="my-4 overflow-x-auto">
40
+ <table className="m-0 table-fixed [overflow-wrap:anywhere]">
30
41
  <thead>
31
42
  <tr>
32
- <th className="w-1/5">Name</th>
33
- <th className="w-1/4">Type</th>
43
+ <th className="w-[30%]">Name</th>
44
+ <th className="w-[15%]">Type</th>
34
45
  <th>Description</th>
35
46
  </tr>
36
47
  </thead>
37
- <tbody>
38
- {rows.map(row => {
39
- const { name, type, required, deprecated, children: description } = row.props;
40
- const defaultValue = displayValue(row.props.default);
41
-
42
- return (
43
- <tr key={row.key ?? name}>
44
- <td>
45
- <span className="inline-flex flex-wrap items-center gap-2">
46
- {name}
47
- {required ? (
48
- <Badge size="sm" tone="primary">
49
- required
50
- </Badge>
51
- ) : null}
52
- {deprecated ? <Badge size="sm">deprecated</Badge> : null}
53
- </span>
54
- </td>
55
- <td>{displayValue(type)}</td>
56
- <td className="[&_p]:m-0">
57
- {description}
58
- {defaultValue ? (
59
- <span className="mt-1 block text-muted-foreground">
60
- Default: {defaultValue}
61
- </span>
62
- ) : null}
63
- </td>
64
- </tr>
65
- );
66
- })}
67
- </tbody>
48
+ <tbody>{rows}</tbody>
68
49
  </table>
69
50
  </div>
70
51
  );
71
52
  }
53
+
54
+ function PropertiesTableRow({
55
+ name,
56
+ type,
57
+ required,
58
+ deprecated,
59
+ default: value,
60
+ children,
61
+ details,
62
+ }: PropertiesTableRowProps) {
63
+ const defaultValue = displayValue(value);
64
+
65
+ return (
66
+ <>
67
+ <tr>
68
+ <td>
69
+ <span className="inline-flex flex-wrap items-center gap-2">
70
+ {name}
71
+ {required ? (
72
+ <Badge size="sm" tone="primary">
73
+ required
74
+ </Badge>
75
+ ) : null}
76
+ {deprecated ? <Badge size="sm">deprecated</Badge> : null}
77
+ </span>
78
+ </td>
79
+ <td>{displayValue(type)}</td>
80
+ <td className="[&_p]:m-0">
81
+ {children}
82
+ {defaultValue ? (
83
+ <span className="mt-1 block text-muted-foreground">Default: {defaultValue}</span>
84
+ ) : null}
85
+ </td>
86
+ </tr>
87
+ {details && (
88
+ <tr>
89
+ <td
90
+ colSpan={3}
91
+ className="[&>[data-slot=collapsible]]:my-0 [&_[data-slot=collapsible-trigger]]:py-1 [&_[data-slot=properties-table]]:my-2"
92
+ >
93
+ {details}
94
+ </td>
95
+ </tr>
96
+ )}
97
+ </>
98
+ );
99
+ }
100
+
101
+ PropertiesTable.Row = PropertiesTableRow;
@@ -12,10 +12,9 @@ export * from './Icon';
12
12
  export * from './Link';
13
13
  export * from './Mermaid';
14
14
  export * from './Panel';
15
- export * from './panel-context';
16
- export * from './ParamField';
15
+ export * from './Param';
17
16
  export * from './PropertiesTable';
18
- export * from './ResponseField';
17
+ export * from './panel-context';
19
18
  export * from './Steps';
20
19
  export * from './Tabs';
21
20
  export * from './Tiles';
@@ -67,14 +67,6 @@ export const styles = {
67
67
  frameCaption:
68
68
  'relative mt-3 px-4 pb-1 text-center text-sm leading-5 text-muted-foreground [&_p]:m-0 [&_a]:font-semibold',
69
69
 
70
- field: 'my-3',
71
- fieldGroup:
72
- 'my-4 divide-y divide-border overflow-hidden rounded-lg border border-border text-sm leading-6 [&>[data-slot=field-group-item]]:my-0 [&>[data-slot=field-group-item]]:px-4 [&>[data-slot=field-group-item]]:py-3 [&_[data-slot=field-group-body]]:mt-2 [&_[data-slot=field-group-type]]:text-xs',
73
- paramField: 'my-3',
74
- fieldHeader: 'flex flex-wrap items-center gap-2',
75
- fieldBody: 'mt-3',
76
- fieldType: 'text-[0.9rem] text-muted-foreground',
77
- fieldName: 'font-bold text-foreground',
78
70
  code: 'rounded-sm bg-[color-mix(in_srgb,currentColor_4%,transparent)] px-[0.35rem] py-[0.1rem] text-sm text-foreground font-mono',
79
71
  steps:
80
72
  "relative my-4 flex flex-col gap-5 before:absolute before:top-4 before:bottom-4 before:left-4 before:w-px before:-translate-x-1/2 before:bg-border before:content-['']",
@@ -45,6 +45,22 @@ export function hasParameters(operation: NormalizedOperation): boolean {
45
45
  );
46
46
  }
47
47
 
48
+ /** Parameter groups shared by the renderer and table of contents. */
49
+ export function operationParameterSections(operation: NormalizedOperation) {
50
+ const groups = [
51
+ { location: 'header', name: 'Headers' },
52
+ { location: 'path', name: 'Path parameters' },
53
+ { location: 'query', name: 'Query parameters' },
54
+ { location: 'cookie', name: 'Cookie parameters' },
55
+ ] as const;
56
+
57
+ return groups.filter(
58
+ ({ location }) =>
59
+ operation.parameters[location].length > 0 ||
60
+ (location === 'header' && operation.security.length > 0),
61
+ );
62
+ }
63
+
48
64
  /**
49
65
  * Section headings for an operation, in render order. The single source of
50
66
  * truth for section ids: the component, the table of contents, the content
@@ -53,7 +69,7 @@ export function hasParameters(operation: NormalizedOperation): boolean {
53
69
  export function operationSections(operation: NormalizedOperation): TocEntry[] {
54
70
  const slugger = createSlugger();
55
71
  const names = [
56
- hasParameters(operation) ? 'Parameters' : undefined,
72
+ ...operationParameterSections(operation).map(section => section.name),
57
73
  operation.requestBody ? 'Request body' : undefined,
58
74
  operation.responses.length ? 'Responses' : undefined,
59
75
  operation.samples.length ? 'Code samples' : undefined,
@@ -146,18 +146,6 @@ export interface IconProps {
146
146
 
147
147
  export declare function Icon(props: IconProps): ReactElement | null;
148
148
 
149
- export interface ParamFieldProps {
150
- name?: string;
151
- query?: string;
152
- path?: string;
153
- header?: string;
154
- body?: string;
155
- type?: string;
156
- required?: boolean;
157
- children?: ReactNode;
158
- }
159
-
160
- export declare function ParamField(props: ParamFieldProps): ReactElement;
161
149
  export declare function Param(props: ChildrenProps): ReactElement;
162
150
 
163
151
  export interface PropertiesTableProps {
@@ -168,16 +156,19 @@ export declare function PropertiesTable(props: PropertiesTableProps): ReactEleme
168
156
 
169
157
  type FieldValue = string | number | boolean | null | undefined;
170
158
 
171
- export interface ResponseFieldProps {
159
+ export interface PropertiesTableRowProps {
172
160
  name: string;
173
161
  type?: FieldValue;
174
162
  default?: FieldValue;
175
163
  required?: boolean;
176
164
  deprecated?: boolean;
165
+ details?: ReactNode;
177
166
  children?: ReactNode;
178
167
  }
179
168
 
180
- export declare function ResponseField(props: ResponseFieldProps): ReactElement;
169
+ export declare namespace PropertiesTable {
170
+ function Row(props: PropertiesTableRowProps): ReactElement;
171
+ }
181
172
 
182
173
  export interface StepProps {
183
174
  title?: ReactNode;
@@ -1,57 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import { Badge } from './Badge';
3
- import { styles } from './styles';
4
- import { decodeHtmlEntities } from './utils';
5
-
6
- export interface ParamFieldProps {
7
- name?: string;
8
- query?: string;
9
- path?: string;
10
- header?: string;
11
- body?: string;
12
- type?: string;
13
- required?: boolean;
14
- children?: ReactNode;
15
- }
16
-
17
- export function ParamField({
18
- name,
19
- query,
20
- path,
21
- header,
22
- body,
23
- type,
24
- required,
25
- children,
26
- }: ParamFieldProps) {
27
- const label = name || query || path || header || body || 'parameter';
28
- const location = query ? 'query' : path ? 'path' : header ? 'header' : body ? 'body' : undefined;
29
-
30
- return (
31
- <div className={styles.paramField} data-slot="field-group-item">
32
- <div className={styles.fieldHeader}>
33
- <span className={styles.fieldName}>{label}</span>
34
- {location ? <Badge size="sm">{location}</Badge> : null}
35
- {type ? (
36
- <span className={styles.fieldType} data-slot="field-group-type">
37
- {decodeHtmlEntities(type)}
38
- </span>
39
- ) : null}
40
- {required ? (
41
- <Badge size="sm" tone="primary">
42
- required
43
- </Badge>
44
- ) : null}
45
- </div>
46
- {children ? (
47
- <div className={styles.fieldBody} data-slot="field-group-body">
48
- {children}
49
- </div>
50
- ) : null}
51
- </div>
52
- );
53
- }
54
-
55
- export function Param({ children }: { children?: ReactNode }) {
56
- return <code className={styles.code}>{children}</code>;
57
- }