docs: generate documentation for UI components (#5849)
* added tool to generate spec files for React components * use typedoc for missing descriptions and types * improvements and fixes * improvements * added doc comments for half of the components * add custom resolver + more doc comments * added all tsdocs * general improvements * add specs to UI docs * added github action * remove unnecessary api route * Added readme for react-docs-generator * remove comment * Update packages/design-system/ui/src/components/currency-input/currency-input.tsx Co-authored-by: Kasper Fabricius Kristensen <45367945+kasperkristensen@users.noreply.github.com> * remove description of aria fields + add generate script --------- Co-authored-by: Kasper Fabricius Kristensen <45367945+kasperkristensen@users.noreply.github.com>
This commit is contained in:
1 parent
edc49bfe1d
commit
245e5c9a69
288 files changed
+6029
-1447
No files matched your search
@@ -117,3 +117,54 @@ jobs:
|
|||||||
add-paths: www/apps/api-reference/specs
|
add-paths: www/apps/api-reference/specs
|
||||||
branch: "docs/generate-api-ref"
|
branch: "docs/generate-api-ref"
|
||||||
branch-suffix: "timestamp"
|
branch-suffix: "timestamp"
|
||||||
|
ui:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ github.event_name == 'release' || github.event.inputs.referenceName == 'all' || github.event.inputs.referenceName == 'ui' }}
|
||||||
|
steps:
|
||||||
|
- name: Cancel Previous Runs
|
||||||
|
uses: styfle/cancel-workflow-action@0.11.0
|
||||||
|
with:
|
||||||
|
access_token: ${{ github.token }}
|
||||||
|
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
token: ${{ secrets.REFERENCE_PAT }}
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Setup Node.js environment
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: "16.10.0"
|
||||||
|
cache: "yarn"
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
uses: ./.github/actions/cache-deps
|
||||||
|
with:
|
||||||
|
extension: reference
|
||||||
|
|
||||||
|
- name: Build Packages
|
||||||
|
run: yarn build
|
||||||
|
|
||||||
|
- name: Install Workspace dependencies
|
||||||
|
run: yarn install
|
||||||
|
working-directory: docs-util
|
||||||
|
|
||||||
|
- name: Build Workspace dependencies
|
||||||
|
run: yarn build
|
||||||
|
working-directory: docs-util
|
||||||
|
|
||||||
|
- name: Generate UI Specs
|
||||||
|
run: yarn generate:ui
|
||||||
|
working-directory: docs-util/packages/react-docs-generator
|
||||||
|
|
||||||
|
- name: Create Pull Request
|
||||||
|
uses: peter-evans/create-pull-request@v4
|
||||||
|
with:
|
||||||
|
commit-message: "chore(docs): Generated UI Reference"
|
||||||
|
base: "develop"
|
||||||
|
title: "chore(docs): Updated UI Reference"
|
||||||
|
labels: "type: chore"
|
||||||
|
add-paths: www/apps/ui/src/specs
|
||||||
|
branch: "docs/generate-ui-ref"
|
||||||
|
branch-suffix: "timestamp"
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# react-docs-generator
|
||||||
|
|
||||||
|
Tool that generates documentation for React components. It's built with [react-docgen](https://react-docgen.dev/) and [Typedoc](https://typedoc.org/).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn start --src ./path/to/src --output ./path/to/output/dir
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
- `--src <srcPath>`: (required) A path to a file containing React components or a directory to scan its sub-directories and files for components.
|
||||||
|
- `--output <outputPath>`: (required) Path to the directory to store the output in.
|
||||||
|
- `--clean`: If used, the output directory is emptied before generating the new output.
|
||||||
|
- `--tsconfigPath <path>`: Path to a TS Config file which is used by Typedoc. By default, the file at `docs-util/packages/typedoc-config/extended-tsconfig/ui.json` is used.
|
||||||
|
- `--disable-typedoc`: Whether to disable Typedoc and generate the spec file using `react-docgen` only. Useful for debugging.
|
||||||
|
- `--verbose-typedoc`: Whether to show the output of Typedoc. By default, it's disabeld.
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"name": "react-docs-generator",
|
||||||
|
"license": "MIT",
|
||||||
|
"scripts": {
|
||||||
|
"start": "ts-node src/index.ts",
|
||||||
|
"generate:ui": "yarn start --src ../../../packages/design-system/ui/src --output ../../../www/apps/ui/src/specs --clean",
|
||||||
|
"build": "tsc",
|
||||||
|
"watch": "tsc --watch",
|
||||||
|
"prepublishOnly": "cross-env NODE_ENV=production tsc --build"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public"
|
||||||
|
},
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"exports": "./dist/index.js",
|
||||||
|
"bin": "dist/index.js",
|
||||||
|
"dependencies": {
|
||||||
|
"chalk": "^5.3.0",
|
||||||
|
"commander": "^11.1.0",
|
||||||
|
"glob": "^10.3.10",
|
||||||
|
"react-docgen": "^7.0.1",
|
||||||
|
"resolve": "^1.22.8",
|
||||||
|
"ts-node": "^10.9.1",
|
||||||
|
"typedoc": "^0.25.4",
|
||||||
|
"typedoc-plugin-custom": "*",
|
||||||
|
"typescript": "5.2",
|
||||||
|
"utils": "*"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.9.4"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typedoc": "0.25.x"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,578 @@
|
|||||||
|
/* eslint-disable no-case-declarations */
|
||||||
|
import { Documentation } from "react-docgen"
|
||||||
|
import {
|
||||||
|
FunctionSignatureType,
|
||||||
|
ObjectSignatureType,
|
||||||
|
TSFunctionSignatureType,
|
||||||
|
TypeDescriptor,
|
||||||
|
} from "react-docgen/dist/Documentation.js"
|
||||||
|
import { Comment } from "typedoc"
|
||||||
|
import {
|
||||||
|
Application,
|
||||||
|
Context,
|
||||||
|
Converter,
|
||||||
|
DeclarationReflection,
|
||||||
|
ProjectReflection,
|
||||||
|
Reflection,
|
||||||
|
SignatureReflection,
|
||||||
|
SomeType,
|
||||||
|
SourceReference,
|
||||||
|
} from "typedoc"
|
||||||
|
import {
|
||||||
|
getFunctionType,
|
||||||
|
getProjectChild,
|
||||||
|
getType,
|
||||||
|
getTypeChildren,
|
||||||
|
} from "utils"
|
||||||
|
|
||||||
|
type MappedReflectionSignature = {
|
||||||
|
source: SourceReference
|
||||||
|
signatures: SignatureReflection[]
|
||||||
|
}
|
||||||
|
|
||||||
|
type Options = {
|
||||||
|
tsconfigPath: string
|
||||||
|
disable?: boolean
|
||||||
|
verbose?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
type TsType = TypeDescriptor<TSFunctionSignatureType>
|
||||||
|
|
||||||
|
type ExcludeExternalOptions = {
|
||||||
|
parentReflection: DeclarationReflection
|
||||||
|
childReflection: DeclarationReflection
|
||||||
|
signature?: SignatureReflection
|
||||||
|
propDescription?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const MAX_LEVEL = 3
|
||||||
|
|
||||||
|
export default class TypedocManager {
|
||||||
|
private app: Application | undefined
|
||||||
|
private options: Options
|
||||||
|
private mappedReflectionSignatures: MappedReflectionSignature[]
|
||||||
|
private project: ProjectReflection | undefined
|
||||||
|
private getTypeOptions = {
|
||||||
|
hideLink: true,
|
||||||
|
wrapBackticks: false,
|
||||||
|
escape: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(options: Options) {
|
||||||
|
this.options = options
|
||||||
|
this.mappedReflectionSignatures = []
|
||||||
|
}
|
||||||
|
|
||||||
|
async setup(filePath: string): Promise<ProjectReflection | undefined> {
|
||||||
|
if (this.options.disable) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.app = await Application.bootstrapWithPlugins({
|
||||||
|
entryPoints: [filePath],
|
||||||
|
tsconfig: this.options.tsconfigPath,
|
||||||
|
plugin: ["typedoc-plugin-custom"],
|
||||||
|
enableInternalResolve: true,
|
||||||
|
logLevel: this.options.verbose ? "Verbose" : "None",
|
||||||
|
})
|
||||||
|
|
||||||
|
// This listener sets the content of mappedReflectionSignatures
|
||||||
|
this.app.converter.on(
|
||||||
|
Converter.EVENT_RESOLVE,
|
||||||
|
(context: Context, reflection: Reflection) => {
|
||||||
|
if (reflection instanceof DeclarationReflection) {
|
||||||
|
if (reflection.sources?.length && reflection.signatures?.length) {
|
||||||
|
this.mappedReflectionSignatures.push({
|
||||||
|
source: reflection.sources[0],
|
||||||
|
signatures: reflection.signatures,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
this.project = await this.app.convert()
|
||||||
|
|
||||||
|
return this.project
|
||||||
|
}
|
||||||
|
|
||||||
|
tryFillWithTypedocData(
|
||||||
|
spec: Documentation,
|
||||||
|
reflectionPathName: string[]
|
||||||
|
): Documentation {
|
||||||
|
if (!this.isProjectSetUp()) {
|
||||||
|
return spec
|
||||||
|
}
|
||||||
|
if (!spec.props) {
|
||||||
|
spec.props = {}
|
||||||
|
}
|
||||||
|
// since the component may be a child of an exported component
|
||||||
|
// we use the reflectionPathName to retrieve the component
|
||||||
|
// by its "reflection path"
|
||||||
|
const reflection = this.project?.getChildByName(
|
||||||
|
reflectionPathName
|
||||||
|
) as DeclarationReflection
|
||||||
|
if (!reflection) {
|
||||||
|
return spec
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieve the signature of the reflection
|
||||||
|
// this is helpful to retrieve the props of the component
|
||||||
|
const mappedSignature = reflection.sources?.length
|
||||||
|
? this.getMappedSignatureFromSource(reflection.sources[0])
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
if (
|
||||||
|
mappedSignature?.signatures[0].parameters?.length &&
|
||||||
|
mappedSignature.signatures[0].parameters[0].type
|
||||||
|
) {
|
||||||
|
const signature = mappedSignature.signatures[0]
|
||||||
|
// get the props of the component from the
|
||||||
|
// first parameter in the signature.
|
||||||
|
const props = getTypeChildren(
|
||||||
|
signature.parameters![0].type!,
|
||||||
|
this.project
|
||||||
|
)
|
||||||
|
|
||||||
|
// this stores props that should be removed from the
|
||||||
|
// spec
|
||||||
|
const propsToRemove = new Set<string>()
|
||||||
|
|
||||||
|
// loop over props in the spec to either add missing descriptions or
|
||||||
|
// push a prop into the `propsToRemove` set.
|
||||||
|
Object.entries(spec.props!).forEach(([propName, propDetails]) => {
|
||||||
|
// retrieve the reflection of the prop
|
||||||
|
const reflectionPropType = props.find(
|
||||||
|
(propType) => propType.name === propName
|
||||||
|
)
|
||||||
|
if (!reflectionPropType) {
|
||||||
|
// if the reflection doesn't exist and the
|
||||||
|
// prop doesn't have a description, it should
|
||||||
|
// be removed.
|
||||||
|
if (!propDetails.description) {
|
||||||
|
propsToRemove.add(propName)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// if the component has the `@excludeExternal` tag,
|
||||||
|
// the prop is external, and it doesn't have the
|
||||||
|
// `@keep` tag, the prop is removed.
|
||||||
|
if (
|
||||||
|
this.shouldExcludeExternal({
|
||||||
|
parentReflection: reflection,
|
||||||
|
childReflection: reflectionPropType,
|
||||||
|
propDescription: propDetails.description,
|
||||||
|
signature,
|
||||||
|
})
|
||||||
|
) {
|
||||||
|
propsToRemove.add(propName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// if the prop doesn't have description, retrieve it using Typedoc
|
||||||
|
propDetails.description =
|
||||||
|
propDetails.description || this.getDescription(reflectionPropType)
|
||||||
|
// if the prop still doesn't have description, remove it.
|
||||||
|
if (!propDetails.description) {
|
||||||
|
propsToRemove.add(propName)
|
||||||
|
} else {
|
||||||
|
propDetails.description = this.normalizeDescription(
|
||||||
|
propDetails.description
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// delete props in the `propsToRemove` set from the specs.
|
||||||
|
propsToRemove.forEach((prop) => delete spec.props![prop])
|
||||||
|
|
||||||
|
// try to add missing props
|
||||||
|
props
|
||||||
|
.filter(
|
||||||
|
(prop) =>
|
||||||
|
// Filter out props that are already in the
|
||||||
|
// specs, are already in the `propsToRemove` set
|
||||||
|
// (meaning they've been removed), don't have a
|
||||||
|
// comment, are React props, and are external props (if
|
||||||
|
// the component excludes them).
|
||||||
|
!Object.hasOwn(spec.props!, prop.name) &&
|
||||||
|
!propsToRemove.has(prop.name) &&
|
||||||
|
this.getReflectionComment(prop) &&
|
||||||
|
!this.isFromReact(prop) &&
|
||||||
|
!this.shouldExcludeExternal({
|
||||||
|
parentReflection: reflection,
|
||||||
|
childReflection: prop,
|
||||||
|
signature,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.forEach((prop) => {
|
||||||
|
// If the prop has description (retrieved)
|
||||||
|
// through Typedoc, it's added into the spec.
|
||||||
|
const description = this.normalizeDescription(
|
||||||
|
this.getDescription(prop)
|
||||||
|
)
|
||||||
|
if (!description) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
spec.props![prop.name] = {
|
||||||
|
description: this.normalizeDescription(this.getDescription(prop)),
|
||||||
|
required: !prop.flags.isOptional,
|
||||||
|
tsType: prop.type
|
||||||
|
? this.getTsType(prop.type)
|
||||||
|
: prop.signatures?.length
|
||||||
|
? this.getFunctionTsType(prop.signatures[0])
|
||||||
|
: undefined,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!spec.props![prop.name].tsType) {
|
||||||
|
delete spec.props![prop.name].tsType
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return spec
|
||||||
|
}
|
||||||
|
|
||||||
|
isProjectSetUp() {
|
||||||
|
return this.project && this.mappedReflectionSignatures
|
||||||
|
}
|
||||||
|
|
||||||
|
getMappedSignatureFromSource(
|
||||||
|
origSource: SourceReference
|
||||||
|
): MappedReflectionSignature | undefined {
|
||||||
|
return this.mappedReflectionSignatures.find(({ source }) => {
|
||||||
|
return (
|
||||||
|
source.fileName === origSource.fileName &&
|
||||||
|
source.line === origSource.line &&
|
||||||
|
source.character === origSource.character
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieves the `tsType` stored in a spec's prop
|
||||||
|
// The format is based on the expected format of React Docgen.
|
||||||
|
getTsType(reflectionType: SomeType, level = 1): TsType {
|
||||||
|
const rawValue = getType({
|
||||||
|
reflectionType,
|
||||||
|
...this.getTypeOptions,
|
||||||
|
})
|
||||||
|
if (level > MAX_LEVEL) {
|
||||||
|
return {
|
||||||
|
name: rawValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (reflectionType.type) {
|
||||||
|
case "array": {
|
||||||
|
const elements = this.getTsType(reflectionType.elementType, level + 1)
|
||||||
|
return {
|
||||||
|
name: "Array",
|
||||||
|
elements: [elements],
|
||||||
|
raw: rawValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "reference":
|
||||||
|
const referenceReflection: DeclarationReflection | undefined =
|
||||||
|
(reflectionType.reflection as DeclarationReflection) ||
|
||||||
|
getProjectChild(this.project!, reflectionType.name)
|
||||||
|
const elements: TsType[] = []
|
||||||
|
if (referenceReflection?.children) {
|
||||||
|
referenceReflection.children?.forEach((child) => {
|
||||||
|
if (!child.type) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
elements.push(this.getTsType(child.type, level + 1))
|
||||||
|
})
|
||||||
|
} else if (referenceReflection?.type) {
|
||||||
|
elements.push(this.getTsType(referenceReflection.type, level + 1))
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
name: reflectionType.name,
|
||||||
|
elements: elements,
|
||||||
|
raw: rawValue,
|
||||||
|
}
|
||||||
|
case "reflection":
|
||||||
|
const reflection = reflectionType.declaration
|
||||||
|
if (reflection.signatures?.length) {
|
||||||
|
return this.getFunctionTsType(
|
||||||
|
reflection.signatures[0],
|
||||||
|
rawValue,
|
||||||
|
level + 1
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
const typeData: ObjectSignatureType = {
|
||||||
|
name: "signature",
|
||||||
|
type: "object",
|
||||||
|
raw: rawValue,
|
||||||
|
signature: {
|
||||||
|
properties: [],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
reflection.children?.map((property) => {
|
||||||
|
typeData.signature.properties.push({
|
||||||
|
key: property.name,
|
||||||
|
value: property.type
|
||||||
|
? this.getTsType(property.type, level + 1)
|
||||||
|
: {
|
||||||
|
name: "unknown",
|
||||||
|
},
|
||||||
|
description: this.getDescription(property),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
return typeData
|
||||||
|
}
|
||||||
|
case "literal":
|
||||||
|
if (reflectionType.value === null) {
|
||||||
|
return {
|
||||||
|
name: `null`,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
name: "literal",
|
||||||
|
value: rawValue,
|
||||||
|
}
|
||||||
|
case "union":
|
||||||
|
case "intersection":
|
||||||
|
return {
|
||||||
|
name: reflectionType.type,
|
||||||
|
raw: rawValue,
|
||||||
|
elements: this.getElementsTypes(reflectionType.types, level),
|
||||||
|
}
|
||||||
|
case "tuple":
|
||||||
|
return {
|
||||||
|
name: "tuple",
|
||||||
|
raw: rawValue,
|
||||||
|
elements: this.getElementsTypes(reflectionType.elements, level),
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return {
|
||||||
|
name: rawValue,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieves the TsType of nested elements. (Helpful for
|
||||||
|
// Reflection types like `intersection` or `union`).
|
||||||
|
getElementsTypes(elements: SomeType[], level = 1): TsType[] {
|
||||||
|
const elementData: TsType[] = []
|
||||||
|
|
||||||
|
elements.forEach((element) => {
|
||||||
|
elementData.push(this.getTsType(element, level + 1))
|
||||||
|
})
|
||||||
|
|
||||||
|
return elementData
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes tags like `@keep` and `@ignore` from a
|
||||||
|
// prop or component's description. These aren't removed
|
||||||
|
// by React Docgen.
|
||||||
|
normalizeDescription(description: string): string {
|
||||||
|
return description
|
||||||
|
.replace("@keep", "")
|
||||||
|
.replace("@ignore", "")
|
||||||
|
.replace("@excludeExternal", "")
|
||||||
|
.trim()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the description of a reflection (component or prop)
|
||||||
|
// through its summary.
|
||||||
|
getDescription(reflection: DeclarationReflection): string {
|
||||||
|
let commentDisplay = this.getReflectionComment(reflection)?.summary
|
||||||
|
if (!commentDisplay) {
|
||||||
|
const signature = reflection.signatures?.find(
|
||||||
|
(sig) => this.getReflectionComment(sig)?.summary.length
|
||||||
|
)
|
||||||
|
if (signature) {
|
||||||
|
commentDisplay = this.getReflectionComment(signature)!.summary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return commentDisplay?.map(({ text }) => text).join("") || ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieves the TsType for a function
|
||||||
|
getFunctionTsType(
|
||||||
|
signature: SignatureReflection,
|
||||||
|
rawValue?: string,
|
||||||
|
level = 1
|
||||||
|
): TsType {
|
||||||
|
if (!rawValue) {
|
||||||
|
rawValue = getFunctionType({
|
||||||
|
modelSignatures: [signature],
|
||||||
|
...this.getTypeOptions,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const typeData: FunctionSignatureType = {
|
||||||
|
name: "signature",
|
||||||
|
type: "function",
|
||||||
|
raw: rawValue!,
|
||||||
|
signature: {
|
||||||
|
arguments: [],
|
||||||
|
return: undefined,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
signature.parameters?.forEach((parameter) => {
|
||||||
|
const parameterType = parameter.type
|
||||||
|
? this.getTsType(parameter.type, level + 1)
|
||||||
|
: undefined
|
||||||
|
typeData.signature.arguments.push({
|
||||||
|
name: parameter.name,
|
||||||
|
type: parameterType,
|
||||||
|
rest: parameter.flags.isRest,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
typeData.signature.return = signature.type
|
||||||
|
? this.getTsType(signature.type, level + 1)
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
return typeData
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if a TsType only has a `name` field.
|
||||||
|
doesOnlyHaveName(obj: TsType): boolean {
|
||||||
|
const primitiveTypes = ["string", "number", "object", "boolean", "function"]
|
||||||
|
const keys = Object.keys(obj)
|
||||||
|
|
||||||
|
return (
|
||||||
|
keys.length === 1 &&
|
||||||
|
keys[0] === "name" &&
|
||||||
|
!primitiveTypes.includes(obj.name)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// retrieves a reflection by the provided name
|
||||||
|
// and check if its type is ReactNode
|
||||||
|
// this is useful for the CustomResolver to check
|
||||||
|
// if a variable is a React component.
|
||||||
|
isReactComponent(name: string): boolean {
|
||||||
|
const reflection = this.getReflectionByName(name)
|
||||||
|
|
||||||
|
if (
|
||||||
|
!reflection ||
|
||||||
|
!(reflection instanceof DeclarationReflection) ||
|
||||||
|
!reflection.signatures
|
||||||
|
) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return reflection.signatures.some(
|
||||||
|
(signature) =>
|
||||||
|
signature.type?.type === "reference" &&
|
||||||
|
signature.type.name === "ReactNode"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the TsType of a child of a reflection.
|
||||||
|
resolveChildType(reflectionName: string, childName: string): TsType | null {
|
||||||
|
if (!this.project) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const reflection = this.getReflectionByName(reflectionName)
|
||||||
|
|
||||||
|
if (!reflection) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
let childReflection: DeclarationReflection | undefined
|
||||||
|
|
||||||
|
if (reflection.children) {
|
||||||
|
childReflection = reflection.getChildByName(
|
||||||
|
childName
|
||||||
|
) as DeclarationReflection
|
||||||
|
} else if (reflection.type) {
|
||||||
|
getTypeChildren(reflection.type, this.project).some((child) => {
|
||||||
|
if (child.name === childName) {
|
||||||
|
childReflection = child
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!childReflection ||
|
||||||
|
!("type" in childReflection) ||
|
||||||
|
(this.isFromReact(childReflection as DeclarationReflection) &&
|
||||||
|
!this.getReflectionComment(childReflection)?.summary)
|
||||||
|
) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.getTsType(childReflection.type as SomeType)
|
||||||
|
}
|
||||||
|
|
||||||
|
// used to check if a reflection (typically of a prop)
|
||||||
|
// is inherited from React (for example, the className prop)
|
||||||
|
isFromReact(reflection: DeclarationReflection) {
|
||||||
|
// check first if the reflection has the `@keep` modifier
|
||||||
|
if (this.getReflectionComment(reflection)?.hasModifier("@keep")) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return reflection.sources?.some((source) =>
|
||||||
|
source.fileName.includes("@types/react")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if a parent reflection has the `@excludeExternal`
|
||||||
|
// which means external child reflections should be ignored.
|
||||||
|
// external child reflections aren't ignored if they have the
|
||||||
|
// `@keep` tag.
|
||||||
|
shouldExcludeExternal({
|
||||||
|
parentReflection,
|
||||||
|
childReflection,
|
||||||
|
propDescription,
|
||||||
|
signature,
|
||||||
|
}: ExcludeExternalOptions): boolean {
|
||||||
|
const parentHasExcludeExternalsModifier =
|
||||||
|
this.getReflectionComment(parentReflection)?.hasModifier(
|
||||||
|
"@excludeExternal"
|
||||||
|
) ||
|
||||||
|
(signature &&
|
||||||
|
this.getReflectionComment(signature)?.hasModifier(
|
||||||
|
"@excludeExternal"
|
||||||
|
)) ||
|
||||||
|
false
|
||||||
|
const childHasKeepModifier =
|
||||||
|
this.getReflectionComment(childReflection)?.hasModifier("@keep") ||
|
||||||
|
propDescription?.includes("@keep")
|
||||||
|
const childHasExternalSource =
|
||||||
|
childReflection.sources?.some((source) =>
|
||||||
|
source.fileName.startsWith("node_modules")
|
||||||
|
) || false
|
||||||
|
return (
|
||||||
|
parentHasExcludeExternalsModifier &&
|
||||||
|
!childHasKeepModifier &&
|
||||||
|
childHasExternalSource
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets comments of a reflection.
|
||||||
|
getReflectionComment(reflection: Reflection): Comment | undefined {
|
||||||
|
if (reflection.comment) {
|
||||||
|
return reflection.comment
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
reflection instanceof DeclarationReflection &&
|
||||||
|
reflection.signatures?.length
|
||||||
|
) {
|
||||||
|
return reflection.signatures.find(
|
||||||
|
(signature) => signature.comment !== undefined
|
||||||
|
)?.comment
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets a reflection by its name.
|
||||||
|
getReflectionByName(name: string): DeclarationReflection | undefined {
|
||||||
|
return this.project
|
||||||
|
? (Object.values(this.project?.reflections || {}).find(
|
||||||
|
(ref) => ref.name === name
|
||||||
|
) as DeclarationReflection)
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
import path from "path"
|
||||||
|
import readFiles from "../utils/read-files.js"
|
||||||
|
import { builtinHandlers, parse } from "react-docgen"
|
||||||
|
import { existsSync, mkdirSync, rmSync, writeFileSync } from "fs"
|
||||||
|
import TypedocManager from "../classes/typedoc-manager.js"
|
||||||
|
import chalk from "chalk"
|
||||||
|
import CustomResolver from "../resolvers/custom-resolver.js"
|
||||||
|
import argsPropHandler from "../handlers/argsPropHandler.js"
|
||||||
|
|
||||||
|
type GenerateOptions = {
|
||||||
|
src: string
|
||||||
|
output: string
|
||||||
|
clean?: boolean
|
||||||
|
tsconfigPath: string
|
||||||
|
disableTypedoc: boolean
|
||||||
|
verboseTypedoc: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function ({
|
||||||
|
src,
|
||||||
|
output,
|
||||||
|
clean,
|
||||||
|
tsconfigPath,
|
||||||
|
disableTypedoc,
|
||||||
|
verboseTypedoc,
|
||||||
|
}: GenerateOptions) {
|
||||||
|
const fileContents = readFiles(src)
|
||||||
|
let outputExists = existsSync(output)
|
||||||
|
|
||||||
|
if (clean && outputExists) {
|
||||||
|
// remove the directory which will be created in the next condition block
|
||||||
|
rmSync(output, { recursive: true, force: true })
|
||||||
|
outputExists = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// create output directory if it doesn't exist
|
||||||
|
if (!outputExists) {
|
||||||
|
mkdirSync(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
// optionally use typedoc to add missing props, descriptions
|
||||||
|
// or types.
|
||||||
|
const typedocManager = new TypedocManager({
|
||||||
|
tsconfigPath,
|
||||||
|
disable: disableTypedoc,
|
||||||
|
verbose: verboseTypedoc,
|
||||||
|
})
|
||||||
|
|
||||||
|
await typedocManager.setup(src)
|
||||||
|
|
||||||
|
for (const [filePath, fileContent] of fileContents) {
|
||||||
|
try {
|
||||||
|
const relativePath = path.resolve(filePath)
|
||||||
|
// retrieve the specs of a file
|
||||||
|
const specs = parse(fileContent, {
|
||||||
|
filename: relativePath,
|
||||||
|
resolver: new CustomResolver(typedocManager),
|
||||||
|
handlers: [
|
||||||
|
// Built-in handlers
|
||||||
|
builtinHandlers.childContextTypeHandler,
|
||||||
|
builtinHandlers.codeTypeHandler,
|
||||||
|
builtinHandlers.componentDocblockHandler,
|
||||||
|
builtinHandlers.componentMethodsHandler,
|
||||||
|
builtinHandlers.contextTypeHandler,
|
||||||
|
builtinHandlers.defaultPropsHandler,
|
||||||
|
builtinHandlers.displayNameHandler,
|
||||||
|
builtinHandlers.propDocblockHandler,
|
||||||
|
builtinHandlers.propTypeCompositionHandler,
|
||||||
|
builtinHandlers.propTypeHandler,
|
||||||
|
// Custom handlers
|
||||||
|
(documentation, componentPath) =>
|
||||||
|
argsPropHandler(documentation, componentPath, typedocManager),
|
||||||
|
],
|
||||||
|
babelOptions: {
|
||||||
|
ast: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// write each of the specs into output directory
|
||||||
|
specs.forEach((spec) => {
|
||||||
|
if (!spec.displayName) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const specNameSplit = spec.displayName.split(".")
|
||||||
|
let filePath = output
|
||||||
|
|
||||||
|
if (spec.description) {
|
||||||
|
spec.description = typedocManager.normalizeDescription(
|
||||||
|
spec.description
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// if typedoc isn't disabled, this method will try to fill
|
||||||
|
// missing descriptions and types, and add missing props.
|
||||||
|
spec = typedocManager.tryFillWithTypedocData(spec, specNameSplit)
|
||||||
|
|
||||||
|
// put the spec in a sub-directory
|
||||||
|
filePath = path.join(filePath, specNameSplit[0])
|
||||||
|
if (!existsSync(filePath)) {
|
||||||
|
mkdirSync(filePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
// write spec to output path
|
||||||
|
writeFileSync(
|
||||||
|
path.join(filePath, `${spec.displayName}.json`),
|
||||||
|
JSON.stringify(spec, null, 2)
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log(chalk.green(`Created spec file for ${spec.displayName}.`))
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.error(chalk.red(`Failed to parse ${filePath}: ${e}`))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
import { utils, DocumentationBuilder, NodePath } from "react-docgen"
|
||||||
|
import { ComponentNode } from "react-docgen/dist/resolver/index.js"
|
||||||
|
import { getDocblock } from "react-docgen/dist/utils/docblock.js"
|
||||||
|
import TypedocManager from "../classes/typedoc-manager.js"
|
||||||
|
import emptyPropDescriptor from "../utils/empty-prop-descriptor.js"
|
||||||
|
import { Node } from "@babel/core"
|
||||||
|
import isEmptyPropDescriptor from "../utils/is-empty-prop-descriptor.js"
|
||||||
|
|
||||||
|
function resolveDocumentation(
|
||||||
|
documentation: DocumentationBuilder,
|
||||||
|
path: NodePath<ComponentNode>,
|
||||||
|
typedocManager?: TypedocManager
|
||||||
|
) {
|
||||||
|
if (!path.isObjectExpression() && !path.isObjectPattern()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
path.get("properties").forEach((propertyPath) => {
|
||||||
|
if (propertyPath.isSpreadElement() || propertyPath.isRestElement()) {
|
||||||
|
const resolvedValuePath = utils.resolveToValue(
|
||||||
|
propertyPath.get("argument")
|
||||||
|
) as NodePath<ComponentNode>
|
||||||
|
resolveDocumentation(documentation, resolvedValuePath)
|
||||||
|
} else if (
|
||||||
|
propertyPath.isObjectProperty() ||
|
||||||
|
propertyPath.isObjectMethod()
|
||||||
|
) {
|
||||||
|
const propertyName = utils.getPropertyName(propertyPath)
|
||||||
|
const propDescriptor = propertyName
|
||||||
|
? documentation.getPropDescriptor(propertyName)
|
||||||
|
: undefined
|
||||||
|
const description =
|
||||||
|
propDescriptor?.description || getDocblock(propertyPath)
|
||||||
|
const propExists = propertyName !== null && propDescriptor !== undefined
|
||||||
|
const shouldRemoveProp =
|
||||||
|
description?.includes("@ignore") ||
|
||||||
|
(!description &&
|
||||||
|
(!propDescriptor || isEmptyPropDescriptor(propDescriptor)))
|
||||||
|
|
||||||
|
// remove property if it doesn't have a description or
|
||||||
|
// if its description includes the `@ignore` tag.
|
||||||
|
if (!propExists || shouldRemoveProp) {
|
||||||
|
if (shouldRemoveProp && propExists) {
|
||||||
|
// prop is removed if its descriptor is empty,
|
||||||
|
// so we empty it to remove it.
|
||||||
|
emptyPropDescriptor(propDescriptor)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// set description
|
||||||
|
utils.setPropDescription(documentation, propertyPath)
|
||||||
|
|
||||||
|
// set type if missing
|
||||||
|
if (!propDescriptor.tsType && typedocManager) {
|
||||||
|
const typeAnnotation = utils.getTypeAnnotation(path)
|
||||||
|
if (typeAnnotation?.isTSTypeReference) {
|
||||||
|
const typeName = typeAnnotation.get("typeName")
|
||||||
|
if (
|
||||||
|
!Array.isArray(typeName) &&
|
||||||
|
typeName.hasNode() &&
|
||||||
|
typeName.isIdentifier()
|
||||||
|
) {
|
||||||
|
const tsType = typedocManager.resolveChildType(
|
||||||
|
typeName.node.name,
|
||||||
|
propertyName
|
||||||
|
)
|
||||||
|
|
||||||
|
if (tsType) {
|
||||||
|
propDescriptor.tsType = tsType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (
|
||||||
|
propDescriptor.tsType &&
|
||||||
|
typedocManager?.doesOnlyHaveName(propDescriptor.tsType)
|
||||||
|
) {
|
||||||
|
// see if the type needs to be resolved.
|
||||||
|
const typeReflection = typedocManager?.getReflectionByName(
|
||||||
|
propDescriptor.tsType.name
|
||||||
|
)
|
||||||
|
if (typeReflection && typeReflection.type) {
|
||||||
|
propDescriptor.tsType =
|
||||||
|
typedocManager?.getTsType(typeReflection.type) ||
|
||||||
|
propDescriptor.tsType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A handler that resolves props from arguments and
|
||||||
|
* sets their description, type, etc...
|
||||||
|
*/
|
||||||
|
const argsPropHandler = (
|
||||||
|
documentation: DocumentationBuilder,
|
||||||
|
componentDefinition: NodePath<ComponentNode>,
|
||||||
|
typedocManager?: TypedocManager
|
||||||
|
) => {
|
||||||
|
let componentParams: NodePath<Node>[] = []
|
||||||
|
if (componentDefinition.isCallExpression()) {
|
||||||
|
const args = componentDefinition.get("arguments")
|
||||||
|
args.forEach((arg) => {
|
||||||
|
const params = arg.get("params")
|
||||||
|
if (Array.isArray(params)) {
|
||||||
|
componentParams.push(...params)
|
||||||
|
} else {
|
||||||
|
componentParams.push(params)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (componentDefinition.isArrowFunctionExpression()) {
|
||||||
|
componentParams = componentDefinition.get("params")
|
||||||
|
}
|
||||||
|
|
||||||
|
componentParams.forEach((param) => {
|
||||||
|
const resolvedParam = utils.resolveToValue(param) as NodePath<ComponentNode>
|
||||||
|
|
||||||
|
if (!resolvedParam) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// set description and type of prop
|
||||||
|
resolveDocumentation(documentation, resolvedParam, typedocManager)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default argsPropHandler
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
import { program } from "commander"
|
||||||
|
import generate from "./commands/generate.js"
|
||||||
|
import path from "path"
|
||||||
|
import { fileURLToPath } from "url"
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url)
|
||||||
|
const __dirname = path.dirname(__filename)
|
||||||
|
|
||||||
|
program
|
||||||
|
.description("Generate React specs used for documentation purposes.")
|
||||||
|
.requiredOption(
|
||||||
|
"-s, --src <srcPath>",
|
||||||
|
"Path to a file containing a React component or a directory of React components."
|
||||||
|
)
|
||||||
|
.requiredOption("-o, --output <outputPath>", "Path to the output directory.")
|
||||||
|
.option(
|
||||||
|
"--clean",
|
||||||
|
"Clean the output directory before creating the new specs",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
.option(
|
||||||
|
"--tsconfigPath <tsconfigPath>",
|
||||||
|
"Path to TSConfig file.",
|
||||||
|
path.join(
|
||||||
|
__dirname,
|
||||||
|
"..",
|
||||||
|
"..",
|
||||||
|
"typedoc-config",
|
||||||
|
"extended-tsconfig",
|
||||||
|
"ui.json"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.option("--disable-typedoc", "Whether to disable Typedoc", false)
|
||||||
|
.option("--verbose-typedoc", "Whether to show Typedoc logs.", false)
|
||||||
|
.parse()
|
||||||
|
|
||||||
|
void generate(program.opts())
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
import { visitors } from "@babel/traverse"
|
||||||
|
import { utils, builtinResolvers, FileState, NodePath } from "react-docgen"
|
||||||
|
import { ComponentNodePath } from "react-docgen/dist/resolver/index.js"
|
||||||
|
import TypedocManager from "../classes/typedoc-manager.js"
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
foundDefinitions: Set<ComponentNodePath>
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This resolver extends react-docgen's FindAllDefinitionsResolver
|
||||||
|
* + adds the ability to resolve variable components such as:
|
||||||
|
*
|
||||||
|
* ```tsx
|
||||||
|
* const Value = SelectPrimitive.Value
|
||||||
|
* Value.displayName = "Select.Value"
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
export default class CustomResolver
|
||||||
|
implements builtinResolvers.FindAllDefinitionsResolver
|
||||||
|
{
|
||||||
|
private typedocManager: TypedocManager
|
||||||
|
constructor(typedocManager: TypedocManager) {
|
||||||
|
this.typedocManager = typedocManager
|
||||||
|
}
|
||||||
|
resolve(file: FileState): ComponentNodePath[] {
|
||||||
|
const state = {
|
||||||
|
foundDefinitions: new Set<ComponentNodePath>(),
|
||||||
|
}
|
||||||
|
file.traverse(
|
||||||
|
visitors.explode({
|
||||||
|
FunctionDeclaration: { enter: this.statelessVisitor },
|
||||||
|
FunctionExpression: { enter: this.statelessVisitor },
|
||||||
|
ObjectMethod: { enter: this.statelessVisitor },
|
||||||
|
ArrowFunctionExpression: { enter: this.statelessVisitor },
|
||||||
|
ClassExpression: { enter: this.classVisitor },
|
||||||
|
ClassDeclaration: { enter: this.classVisitor },
|
||||||
|
VariableDeclaration: {
|
||||||
|
enter: (path, state: State) => {
|
||||||
|
const found = path.node.declarations.some((declaration) => {
|
||||||
|
if (
|
||||||
|
"name" in declaration.id &&
|
||||||
|
this.typedocManager.isReactComponent(declaration.id.name) &&
|
||||||
|
declaration.init
|
||||||
|
) {
|
||||||
|
const init = path.get("declarations")[0].get("init")
|
||||||
|
if (init.isMemberExpression()) {
|
||||||
|
state.foundDefinitions.add(
|
||||||
|
path as unknown as ComponentNodePath
|
||||||
|
)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if (found) {
|
||||||
|
return path.skip()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
CallExpression: {
|
||||||
|
enter: (path, state: State) => {
|
||||||
|
const argument = path.get("arguments")[0]
|
||||||
|
if (!argument) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (utils.isReactForwardRefCall(path)) {
|
||||||
|
// If the the inner function was previously identified as a component
|
||||||
|
// replace it with the parent node
|
||||||
|
const inner = utils.resolveToValue(argument) as ComponentNodePath
|
||||||
|
state.foundDefinitions.delete(inner)
|
||||||
|
state.foundDefinitions.add(path)
|
||||||
|
// Do not traverse into arguments
|
||||||
|
return path.skip()
|
||||||
|
} else if (utils.isReactCreateClassCall(path)) {
|
||||||
|
const resolvedPath = utils.resolveToValue(argument)
|
||||||
|
if (resolvedPath.isObjectExpression()) {
|
||||||
|
state.foundDefinitions.add(resolvedPath)
|
||||||
|
}
|
||||||
|
// Do not traverse into arguments
|
||||||
|
return path.skip()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
state
|
||||||
|
)
|
||||||
|
return Array.from(state.foundDefinitions)
|
||||||
|
}
|
||||||
|
|
||||||
|
classVisitor(path: NodePath, state: State) {
|
||||||
|
if (utils.isReactComponentClass(path)) {
|
||||||
|
utils.normalizeClassDefinition(path)
|
||||||
|
state.foundDefinitions.add(path)
|
||||||
|
}
|
||||||
|
path.skip()
|
||||||
|
}
|
||||||
|
statelessVisitor(path: NodePath, state: State) {
|
||||||
|
if (utils.isStatelessComponent(path)) {
|
||||||
|
state.foundDefinitions.add(path)
|
||||||
|
}
|
||||||
|
path.skip()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { PropDescriptor } from "react-docgen/dist/Documentation.js"
|
||||||
|
|
||||||
|
export default function emptyPropDescriptor(propDescriptor: PropDescriptor) {
|
||||||
|
const objKeys = Object.keys(propDescriptor)
|
||||||
|
objKeys.forEach((key) => {
|
||||||
|
delete propDescriptor[key as keyof PropDescriptor]
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { PropDescriptor } from "react-docgen/dist/Documentation.js"
|
||||||
|
|
||||||
|
export default function isEmptyPropDescriptor(propDescriptor: PropDescriptor) {
|
||||||
|
const objKeys = Object.keys(propDescriptor)
|
||||||
|
return (
|
||||||
|
objKeys.length === 0 ||
|
||||||
|
objKeys.every((objKey) => {
|
||||||
|
const value = propDescriptor[objKey as keyof PropDescriptor]
|
||||||
|
switch (typeof value) {
|
||||||
|
case "string":
|
||||||
|
return value.length === 0
|
||||||
|
case "object":
|
||||||
|
return Object.keys(value).length === 0
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
const BLACKLISTED_PROPS = ["className", "children"]
|
||||||
|
|
||||||
|
export default function isPropBlacklisted(propName: string) {
|
||||||
|
return BLACKLISTED_PROPS.includes(propName)
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import { statSync, readFileSync } from "fs"
|
||||||
|
import { globSync } from "glob"
|
||||||
|
|
||||||
|
export default function readFiles(path: string): Map<string, string> {
|
||||||
|
const files = new Map<string, string>()
|
||||||
|
// check if path is for a file
|
||||||
|
const fileStats = statSync(path)
|
||||||
|
if (fileStats.isFile()) {
|
||||||
|
files.set(path, readFileSync(path, "utf-8"))
|
||||||
|
} else {
|
||||||
|
const filePaths = globSync(`${path}/**/*.{tsx,jsx}`, {
|
||||||
|
ignore: [`${path}/**/*.spec.*`, `${path}/**/*.stories.*`],
|
||||||
|
})
|
||||||
|
filePaths.forEach((filePath) => {
|
||||||
|
files.set(filePath, readFileSync(filePath, "utf-8"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return files
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"extends": "../../tsconfig",
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ESNext",
|
||||||
|
"module": "Node16",
|
||||||
|
"moduleResolution": "node16",
|
||||||
|
"outDir": "./dist",
|
||||||
|
"rootDir": "./src",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
},
|
||||||
|
"include": ["src", "../typedoc-plugin-custom/src/types"],
|
||||||
|
"ts-node": {
|
||||||
|
"esm": true,
|
||||||
|
"experimentalSpecifierResolution": "node",
|
||||||
|
"transpileOnly": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"glob": "^10.3.10",
|
"glob": "^10.3.10",
|
||||||
"randomcolor": "^0.6.2",
|
"randomcolor": "^0.6.2",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typedoc": "0.25.1",
|
"typedoc": "^0.25.4",
|
||||||
"typedoc-config": "*",
|
"typedoc-config": "*",
|
||||||
"typedoc-monorepo-link-types": "^0.0.2",
|
"typedoc-monorepo-link-types": "^0.0.2",
|
||||||
"typedoc-plugin-custom": "*",
|
"typedoc-plugin-custom": "*",
|
||||||
|
|||||||
@@ -25,6 +25,14 @@
|
|||||||
{
|
{
|
||||||
"tagName": "@docHideSignature",
|
"tagName": "@docHideSignature",
|
||||||
"syntaxKind": "modifier"
|
"syntaxKind": "modifier"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tagName": "@keep",
|
||||||
|
"syntaxKind": "modifier"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"tagName": "@excludeExternal",
|
||||||
|
"syntaxKind": "modifier"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"$schema": "http://json.schemastore.org/tsconfig",
|
||||||
|
"extends": [
|
||||||
|
"../../../../packages/design-system/ui/tsconfig.esm.json"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -180,8 +180,8 @@ function addComments(schema: Schema, reflection: Reflection) {
|
|||||||
"type" in reflection
|
"type" in reflection
|
||||||
? getTypeChildren(reflection.type as SomeType, reflection.project)
|
? getTypeChildren(reflection.type as SomeType, reflection.project)
|
||||||
: "children" in reflection
|
: "children" in reflection
|
||||||
? (reflection.children as DeclarationReflection[])
|
? (reflection.children as DeclarationReflection[])
|
||||||
: []
|
: []
|
||||||
|
|
||||||
Object.entries(schema.properties).forEach(([key, value]) => {
|
Object.entries(schema.properties).forEach(([key, value]) => {
|
||||||
const childItem =
|
const childItem =
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ let hasMonkeyPatched = false
|
|||||||
|
|
||||||
export function load(app: Application) {
|
export function load(app: Application) {
|
||||||
if (hasMonkeyPatched) {
|
if (hasMonkeyPatched) {
|
||||||
throw new Error(
|
throw new Error("typedoc-plugin-custom cannot be loaded multiple times")
|
||||||
"typedoc-plugin-missing-exports cannot be loaded multiple times"
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
hasMonkeyPatched = true
|
hasMonkeyPatched = true
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
export declare module "typedoc" {
|
||||||
|
declare interface TypeDocOptionMap {
|
||||||
|
enableInternalResolve: boolean
|
||||||
|
internalModule: string
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,5 +4,6 @@
|
|||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"rootDir": "./src"
|
"rootDir": "./src"
|
||||||
},
|
},
|
||||||
"include": ["src"]
|
"include": ["src", "src/types"],
|
||||||
|
"typeRoots": ["./src/types/index.d.ts"]
|
||||||
}
|
}
|
||||||
+2
-1
@@ -1,7 +1,8 @@
|
|||||||
import * as Handlebars from "handlebars"
|
import * as Handlebars from "handlebars"
|
||||||
import { PageEvent } from "typedoc"
|
import { PageEvent } from "typedoc"
|
||||||
import { MarkdownTheme } from "../../theme"
|
import { MarkdownTheme } from "../../theme"
|
||||||
import { escapeChars, getDisplayName } from "../../utils"
|
import { getDisplayName } from "../../utils"
|
||||||
|
import { escapeChars } from "utils"
|
||||||
|
|
||||||
export default function (theme: MarkdownTheme) {
|
export default function (theme: MarkdownTheme) {
|
||||||
Handlebars.registerHelper("breadcrumbs", function (this: PageEvent) {
|
Handlebars.registerHelper("breadcrumbs", function (this: PageEvent) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import * as Handlebars from "handlebars"
|
|||||||
import * as Path from "path"
|
import * as Path from "path"
|
||||||
import { CommentDisplayPart } from "typedoc/dist/lib/models/comments/comment"
|
import { CommentDisplayPart } from "typedoc/dist/lib/models/comments/comment"
|
||||||
import { MarkdownTheme } from "../../theme"
|
import { MarkdownTheme } from "../../theme"
|
||||||
import { escapeChars } from "../../utils"
|
import { escapeChars } from "utils"
|
||||||
|
|
||||||
export default function (theme: MarkdownTheme) {
|
export default function (theme: MarkdownTheme) {
|
||||||
Handlebars.registerHelper("comment", function (parts: CommentDisplayPart[]) {
|
Handlebars.registerHelper("comment", function (parts: CommentDisplayPart[]) {
|
||||||
@@ -30,8 +30,8 @@ export default function (theme: MarkdownTheme) {
|
|||||||
typeof part.target === "string"
|
typeof part.target === "string"
|
||||||
? part.target
|
? part.target
|
||||||
: "url" in part.target
|
: "url" in part.target
|
||||||
? Handlebars.helpers.relativeURL(part.target.url)
|
? Handlebars.helpers.relativeURL(part.target.url)
|
||||||
: ""
|
: ""
|
||||||
const wrap = part.tag === "@linkcode" ? "`" : ""
|
const wrap = part.tag === "@linkcode" ? "`" : ""
|
||||||
result.push(
|
result.push(
|
||||||
url ? `[${wrap}${part.text}${wrap}](${url})` : part.text
|
url ? `[${wrap}${part.text}${wrap}](${url})` : part.text
|
||||||
|
|||||||
+2
-6
@@ -7,12 +7,8 @@ import {
|
|||||||
ReflectionType,
|
ReflectionType,
|
||||||
} from "typedoc"
|
} from "typedoc"
|
||||||
import { MarkdownTheme } from "../../theme"
|
import { MarkdownTheme } from "../../theme"
|
||||||
import {
|
import { memberSymbol, stripComments } from "../../utils"
|
||||||
escapeChars,
|
import { escapeChars, stripLineBreaks } from "utils"
|
||||||
memberSymbol,
|
|
||||||
stripComments,
|
|
||||||
stripLineBreaks,
|
|
||||||
} from "../../utils"
|
|
||||||
|
|
||||||
export default function (theme: MarkdownTheme) {
|
export default function (theme: MarkdownTheme) {
|
||||||
Handlebars.registerHelper(
|
Handlebars.registerHelper(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import * as Handlebars from "handlebars"
|
import * as Handlebars from "handlebars"
|
||||||
import { escapeChars } from "../../utils"
|
import { escapeChars } from "utils"
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
Handlebars.registerHelper("escape", function (str: string) {
|
Handlebars.registerHelper("escape", function (str: string) {
|
||||||
|
|||||||
+2
-1
@@ -1,7 +1,8 @@
|
|||||||
import * as Handlebars from "handlebars"
|
import * as Handlebars from "handlebars"
|
||||||
import { PageEvent, ParameterReflection, ReflectionKind } from "typedoc"
|
import { PageEvent, ParameterReflection, ReflectionKind } from "typedoc"
|
||||||
import { MarkdownTheme } from "../../theme"
|
import { MarkdownTheme } from "../../theme"
|
||||||
import { escapeChars, getDisplayName } from "../../utils"
|
import { getDisplayName } from "../../utils"
|
||||||
|
import { escapeChars } from "utils"
|
||||||
|
|
||||||
export default function (theme: MarkdownTheme) {
|
export default function (theme: MarkdownTheme) {
|
||||||
Handlebars.registerHelper(
|
Handlebars.registerHelper(
|
||||||
|
|||||||
+2
-1
@@ -4,8 +4,9 @@ import {
|
|||||||
ReflectionKind,
|
ReflectionKind,
|
||||||
SignatureReflection,
|
SignatureReflection,
|
||||||
} from "typedoc"
|
} from "typedoc"
|
||||||
import { getHTMLChar, memberSymbol } from "../../utils"
|
import { memberSymbol } from "../../utils"
|
||||||
import { MarkdownTheme } from "../../theme"
|
import { MarkdownTheme } from "../../theme"
|
||||||
|
import { getHTMLChar } from "utils"
|
||||||
|
|
||||||
export default function (theme: MarkdownTheme) {
|
export default function (theme: MarkdownTheme) {
|
||||||
Handlebars.registerHelper(
|
Handlebars.registerHelper(
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import {
|
|||||||
ReflectionGroup,
|
ReflectionGroup,
|
||||||
} from "typedoc"
|
} from "typedoc"
|
||||||
import { MarkdownTheme } from "../../theme"
|
import { MarkdownTheme } from "../../theme"
|
||||||
import { escapeChars } from "../../utils"
|
import { escapeChars } from "utils"
|
||||||
|
|
||||||
export default function (theme: MarkdownTheme) {
|
export default function (theme: MarkdownTheme) {
|
||||||
Handlebars.registerHelper(
|
Handlebars.registerHelper(
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
import * as Handlebars from "handlebars"
|
import * as Handlebars from "handlebars"
|
||||||
import { SignatureReflection } from "typedoc"
|
import { SignatureReflection } from "typedoc"
|
||||||
import { ArrayType, ReferenceType } from "typedoc/dist/lib/models/types"
|
import { ArrayType, ReferenceType } from "typedoc/dist/lib/models/types"
|
||||||
import { escapeChars } from "../../utils"
|
import { escapeChars } from "utils"
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
Handlebars.registerHelper(
|
Handlebars.registerHelper(
|
||||||
|
|||||||
+1
-1
@@ -1,10 +1,10 @@
|
|||||||
import * as Handlebars from "handlebars"
|
import * as Handlebars from "handlebars"
|
||||||
import { DeclarationReflection, ReflectionType } from "typedoc"
|
import { DeclarationReflection, ReflectionType } from "typedoc"
|
||||||
import { MarkdownTheme } from "../../theme"
|
import { MarkdownTheme } from "../../theme"
|
||||||
import { escapeChars, stripLineBreaks } from "../../utils"
|
|
||||||
import { parseParams } from "../../utils/params-utils"
|
import { parseParams } from "../../utils/params-utils"
|
||||||
import { ReflectionParameterType } from "../../types"
|
import { ReflectionParameterType } from "../../types"
|
||||||
import reflectionFormatter from "../../utils/reflection-formatter"
|
import reflectionFormatter from "../../utils/reflection-formatter"
|
||||||
|
import { escapeChars, stripLineBreaks } from "utils"
|
||||||
|
|
||||||
export default function (theme: MarkdownTheme) {
|
export default function (theme: MarkdownTheme) {
|
||||||
Handlebars.registerHelper(
|
Handlebars.registerHelper(
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@ import {
|
|||||||
getTableHeaders,
|
getTableHeaders,
|
||||||
reflectionTableFormatter,
|
reflectionTableFormatter,
|
||||||
} from "../../utils/reflection-formatter"
|
} from "../../utils/reflection-formatter"
|
||||||
import { hasTypes } from "../../utils/type-utils"
|
import { hasTypes } from "utils"
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
Handlebars.registerHelper(
|
Handlebars.registerHelper(
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
UnionType,
|
UnionType,
|
||||||
UnknownType,
|
UnknownType,
|
||||||
} from "typedoc"
|
} from "typedoc"
|
||||||
import getType, { Collapse } from "../../utils/type-utils"
|
import { Collapse, getType } from "utils"
|
||||||
|
|
||||||
export default function () {
|
export default function () {
|
||||||
Handlebars.registerHelper(
|
Handlebars.registerHelper(
|
||||||
@@ -43,6 +43,7 @@ export default function () {
|
|||||||
reflectionType: this,
|
reflectionType: this,
|
||||||
collapse,
|
collapse,
|
||||||
wrapBackticks: emphasis,
|
wrapBackticks: emphasis,
|
||||||
|
getRelativeUrlMethod: Handlebars.helpers.relativeURL,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
ReflectionKind,
|
ReflectionKind,
|
||||||
SignatureReflection,
|
SignatureReflection,
|
||||||
} from "typedoc"
|
} from "typedoc"
|
||||||
|
import { stripLineBreaks } from "utils"
|
||||||
|
|
||||||
export function formatContents(contents: string) {
|
export function formatContents(contents: string) {
|
||||||
return (
|
return (
|
||||||
@@ -16,19 +17,6 @@ export function formatContents(contents: string) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getHTMLChar(str: string) {
|
|
||||||
return str
|
|
||||||
.replace(/</g, "<")
|
|
||||||
.replace(/{/g, "{")
|
|
||||||
.replace(/}/g, "}")
|
|
||||||
.replace(/>/g, ">")
|
|
||||||
}
|
|
||||||
|
|
||||||
export function escapeChars(str: string, escapeBackticks = true) {
|
|
||||||
const result = getHTMLChar(str).replace(/_/g, "\\_").replace(/\|/g, "\\|")
|
|
||||||
return escapeBackticks ? result.replace(/`/g, "\\`") : result
|
|
||||||
}
|
|
||||||
|
|
||||||
export function memberSymbol(
|
export function memberSymbol(
|
||||||
reflection: DeclarationReflection | ParameterReflection | SignatureReflection
|
reflection: DeclarationReflection | ParameterReflection | SignatureReflection
|
||||||
) {
|
) {
|
||||||
@@ -57,17 +45,6 @@ export function stripComments(str: string) {
|
|||||||
.replace(/^\s+|\s+$|(\s)+/g, "$1")
|
.replace(/^\s+|\s+$|(\s)+/g, "$1")
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stripLineBreaks(str: string) {
|
|
||||||
return str
|
|
||||||
? str
|
|
||||||
.replace(/\n/g, " ")
|
|
||||||
.replace(/\r/g, " ")
|
|
||||||
.replace(/\t/g, " ")
|
|
||||||
.replace(/[\s]{2,}/g, " ")
|
|
||||||
.trim()
|
|
||||||
: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
export function stripCode(str: string) {
|
export function stripCode(str: string) {
|
||||||
return stripLineBreaks(str.replace("```ts", "").replace("```", ""))
|
return stripLineBreaks(str.replace("```ts", "").replace("```", ""))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,14 @@ import {
|
|||||||
ReflectionType,
|
ReflectionType,
|
||||||
} from "typedoc"
|
} from "typedoc"
|
||||||
import * as Handlebars from "handlebars"
|
import * as Handlebars from "handlebars"
|
||||||
import { stripCode, stripLineBreaks } from "../utils"
|
import { stripCode } from "../utils"
|
||||||
import { Parameter, ParameterStyle, ReflectionParameterType } from "../types"
|
import { Parameter, ParameterStyle, ReflectionParameterType } from "../types"
|
||||||
import getType, { getReflectionType } from "./type-utils"
|
import {
|
||||||
import { getTypeChildren } from "utils"
|
getReflectionType,
|
||||||
|
getType,
|
||||||
|
getTypeChildren,
|
||||||
|
stripLineBreaks,
|
||||||
|
} from "utils"
|
||||||
import { MarkdownTheme } from "../theme"
|
import { MarkdownTheme } from "../theme"
|
||||||
|
|
||||||
const ALLOWED_KINDS: ReflectionKind[] = [
|
const ALLOWED_KINDS: ReflectionKind[] = [
|
||||||
@@ -124,12 +128,14 @@ export function reflectionComponentFormatter({
|
|||||||
reflectionType: reflection.type,
|
reflectionType: reflection.type,
|
||||||
collapse: "object",
|
collapse: "object",
|
||||||
project: reflection.project,
|
project: reflection.project,
|
||||||
|
getRelativeUrlMethod: Handlebars.helpers.relativeURL,
|
||||||
})
|
})
|
||||||
: getReflectionType({
|
: getReflectionType({
|
||||||
reflectionType: reflection,
|
reflectionType: reflection,
|
||||||
collapse: "object",
|
collapse: "object",
|
||||||
wrapBackticks: true,
|
wrapBackticks: true,
|
||||||
project: reflection.project,
|
project: reflection.project,
|
||||||
|
getRelativeUrlMethod: Handlebars.helpers.relativeURL,
|
||||||
}),
|
}),
|
||||||
description: comments
|
description: comments
|
||||||
? Handlebars.helpers.comments(comments, true, false)
|
? Handlebars.helpers.comments(comments, true, false)
|
||||||
|
|||||||
+3
-2
@@ -7,14 +7,13 @@ import {
|
|||||||
TypeParameterReflection,
|
TypeParameterReflection,
|
||||||
} from "typedoc"
|
} from "typedoc"
|
||||||
import * as Handlebars from "handlebars"
|
import * as Handlebars from "handlebars"
|
||||||
import getType from "./type-utils"
|
|
||||||
import { Parameter } from "../types"
|
import { Parameter } from "../types"
|
||||||
import {
|
import {
|
||||||
getDefaultValue,
|
getDefaultValue,
|
||||||
reflectionComponentFormatter,
|
reflectionComponentFormatter,
|
||||||
} from "./reflection-formatter"
|
} from "./reflection-formatter"
|
||||||
import { MarkdownTheme } from "../theme"
|
import { MarkdownTheme } from "../theme"
|
||||||
import { getProjectChild, getTypeChildren } from "utils"
|
import { getProjectChild, getType, getTypeChildren } from "utils"
|
||||||
|
|
||||||
type ReturnReflectionComponentFormatterParams = {
|
type ReturnReflectionComponentFormatterParams = {
|
||||||
reflectionType: SomeType
|
reflectionType: SomeType
|
||||||
@@ -37,11 +36,13 @@ export function returnReflectionComponentFormatter({
|
|||||||
wrapBackticks: false,
|
wrapBackticks: false,
|
||||||
hideLink: true,
|
hideLink: true,
|
||||||
project,
|
project,
|
||||||
|
getRelativeUrlMethod: Handlebars.helpers.relativeURL,
|
||||||
})
|
})
|
||||||
const type = getType({
|
const type = getType({
|
||||||
reflectionType: reflectionType,
|
reflectionType: reflectionType,
|
||||||
collapse: "object",
|
collapse: "object",
|
||||||
project,
|
project,
|
||||||
|
getRelativeUrlMethod: Handlebars.helpers.relativeURL,
|
||||||
})
|
})
|
||||||
const componentItem: Parameter[] = []
|
const componentItem: Parameter[] = []
|
||||||
const canRetrieveChildren = level + 1 <= (maxLevel || MarkdownTheme.MAX_LEVEL)
|
const canRetrieveChildren = level + 1 <= (maxLevel || MarkdownTheme.MAX_LEVEL)
|
||||||
|
|||||||
@@ -22,12 +22,15 @@ export function getTypeChildren(
|
|||||||
break
|
break
|
||||||
case "reference":
|
case "reference":
|
||||||
// eslint-disable-next-line no-case-declarations
|
// eslint-disable-next-line no-case-declarations
|
||||||
const referencedReflection =
|
const referencedReflection = reflectionType.reflection
|
||||||
reflectionType.reflection && "children" in reflectionType.reflection
|
? "children" in reflectionType.reflection
|
||||||
? reflectionType.reflection
|
? reflectionType.reflection
|
||||||
: project
|
: project
|
||||||
? getProjectChild(project, reflectionType.name)
|
? project.getReflectionById(reflectionType.reflection.id)
|
||||||
: undefined
|
: undefined
|
||||||
|
: project
|
||||||
|
? getProjectChild(project, reflectionType.name)
|
||||||
|
: undefined
|
||||||
|
|
||||||
if (referencedReflection instanceof DeclarationReflection) {
|
if (referencedReflection instanceof DeclarationReflection) {
|
||||||
if (referencedReflection.children) {
|
if (referencedReflection.children) {
|
||||||
|
|||||||
+14
-11
@@ -7,6 +7,7 @@ import {
|
|||||||
IntersectionType,
|
IntersectionType,
|
||||||
IntrinsicType,
|
IntrinsicType,
|
||||||
LiteralType,
|
LiteralType,
|
||||||
|
ParameterReflection,
|
||||||
ProjectReflection,
|
ProjectReflection,
|
||||||
QueryType,
|
QueryType,
|
||||||
ReferenceType,
|
ReferenceType,
|
||||||
@@ -19,10 +20,13 @@ import {
|
|||||||
UnionType,
|
UnionType,
|
||||||
UnknownType,
|
UnknownType,
|
||||||
} from "typedoc"
|
} from "typedoc"
|
||||||
import * as Handlebars from "handlebars"
|
import { escapeChars, getHTMLChar } from "./str-utils"
|
||||||
import { ReflectionParameterType } from "../types"
|
import { getProjectChild } from "./get-project-child"
|
||||||
import { escapeChars, getHTMLChar } from "../utils"
|
|
||||||
import { getProjectChild } from "utils"
|
export type ReflectionParameterType =
|
||||||
|
| ParameterReflection
|
||||||
|
| DeclarationReflection
|
||||||
|
| TypeParameterReflection
|
||||||
|
|
||||||
export type Collapse = "object" | "function" | "all" | "none"
|
export type Collapse = "object" | "function" | "all" | "none"
|
||||||
|
|
||||||
@@ -33,12 +37,10 @@ export type TypeOptions<T = SomeType> = {
|
|||||||
hideLink?: boolean
|
hideLink?: boolean
|
||||||
escape?: boolean
|
escape?: boolean
|
||||||
project?: ProjectReflection
|
project?: ProjectReflection
|
||||||
|
getRelativeUrlMethod?: (url: string) => string
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function getType({
|
export function getType({ reflectionType, ...options }: TypeOptions): string {
|
||||||
reflectionType,
|
|
||||||
...options
|
|
||||||
}: TypeOptions): string {
|
|
||||||
if (reflectionType instanceof ReferenceType) {
|
if (reflectionType instanceof ReferenceType) {
|
||||||
return getReferenceType({
|
return getReferenceType({
|
||||||
reflectionType,
|
reflectionType,
|
||||||
@@ -304,6 +306,7 @@ export function getReferenceType({
|
|||||||
hideLink = false,
|
hideLink = false,
|
||||||
escape,
|
escape,
|
||||||
project,
|
project,
|
||||||
|
getRelativeUrlMethod,
|
||||||
...options
|
...options
|
||||||
}: TypeOptions<ReferenceType>): string {
|
}: TypeOptions<ReferenceType>): string {
|
||||||
escape = getShouldEscape(wrapBackticks, escape)
|
escape = getShouldEscape(wrapBackticks, escape)
|
||||||
@@ -321,9 +324,9 @@ export function getReferenceType({
|
|||||||
if (modelReflection?.url) {
|
if (modelReflection?.url) {
|
||||||
reflection.push(
|
reflection.push(
|
||||||
shouldShowLink
|
shouldShowLink
|
||||||
? `[${modelReflection.name}](${Handlebars.helpers.relativeURL(
|
? `[${modelReflection.name}](${
|
||||||
modelReflection.url
|
getRelativeUrlMethod?.(modelReflection.url) || modelReflection.url
|
||||||
)})`
|
})`
|
||||||
: getFormattedStr(modelReflection.name, false, escape)
|
: getFormattedStr(modelReflection.name, false, escape)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
export * from "./get-type-children"
|
export * from "./get-type-children"
|
||||||
export * from "./get-project-child"
|
export * from "./get-project-child"
|
||||||
|
export * from "./get-type-str"
|
||||||
|
export * from "./str-utils"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
export function getHTMLChar(str: string) {
|
||||||
|
return str
|
||||||
|
.replace(/</g, "<")
|
||||||
|
.replace(/{/g, "{")
|
||||||
|
.replace(/}/g, "}")
|
||||||
|
.replace(/>/g, ">")
|
||||||
|
}
|
||||||
|
|
||||||
|
export function escapeChars(str: string, escapeBackticks = true) {
|
||||||
|
const result = getHTMLChar(str).replace(/_/g, "\\_").replace(/\|/g, "\\|")
|
||||||
|
return escapeBackticks ? result.replace(/`/g, "\\`") : result
|
||||||
|
}
|
||||||
|
|
||||||
|
export function stripLineBreaks(str: string) {
|
||||||
|
return str
|
||||||
|
? str
|
||||||
|
.replace(/\n/g, " ")
|
||||||
|
.replace(/\r/g, " ")
|
||||||
|
.replace(/\t/g, " ")
|
||||||
|
.replace(/[\s]{2,}/g, " ")
|
||||||
|
.trim()
|
||||||
|
: ""
|
||||||
|
}
|
||||||
+213
-8
@@ -52,6 +52,16 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@babel/code-frame@npm:^7.23.5":
|
||||||
|
version: 7.23.5
|
||||||
|
resolution: "@babel/code-frame@npm:7.23.5"
|
||||||
|
dependencies:
|
||||||
|
"@babel/highlight": ^7.23.4
|
||||||
|
chalk: ^2.4.2
|
||||||
|
checksum: a10e843595ddd9f97faa99917414813c06214f4d9205294013e20c70fbdf4f943760da37dec1d998bf3e6fc20fa2918a47c0e987a7e458663feb7698063ad7c6
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@babel/compat-data@npm:^7.22.9":
|
"@babel/compat-data@npm:^7.22.9":
|
||||||
version: 7.23.3
|
version: 7.23.3
|
||||||
resolution: "@babel/compat-data@npm:7.23.3"
|
resolution: "@babel/compat-data@npm:7.23.3"
|
||||||
@@ -59,6 +69,29 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@babel/core@npm:^7.18.9":
|
||||||
|
version: 7.23.5
|
||||||
|
resolution: "@babel/core@npm:7.23.5"
|
||||||
|
dependencies:
|
||||||
|
"@ampproject/remapping": ^2.2.0
|
||||||
|
"@babel/code-frame": ^7.23.5
|
||||||
|
"@babel/generator": ^7.23.5
|
||||||
|
"@babel/helper-compilation-targets": ^7.22.15
|
||||||
|
"@babel/helper-module-transforms": ^7.23.3
|
||||||
|
"@babel/helpers": ^7.23.5
|
||||||
|
"@babel/parser": ^7.23.5
|
||||||
|
"@babel/template": ^7.22.15
|
||||||
|
"@babel/traverse": ^7.23.5
|
||||||
|
"@babel/types": ^7.23.5
|
||||||
|
convert-source-map: ^2.0.0
|
||||||
|
debug: ^4.1.0
|
||||||
|
gensync: ^1.0.0-beta.2
|
||||||
|
json5: ^2.2.3
|
||||||
|
semver: ^6.3.1
|
||||||
|
checksum: 311a512a870ee330a3f9a7ea89e5df790b2b5af0b1bd98b10b4edc0de2ac440f0df4d69ea2c0ee38a4b89041b9a495802741d93603be7d4fd834ec8bb6970bd2
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@babel/core@npm:^7.23.0":
|
"@babel/core@npm:^7.23.0":
|
||||||
version: 7.23.3
|
version: 7.23.3
|
||||||
resolution: "@babel/core@npm:7.23.3"
|
resolution: "@babel/core@npm:7.23.3"
|
||||||
@@ -108,6 +141,18 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@babel/generator@npm:^7.23.5":
|
||||||
|
version: 7.23.5
|
||||||
|
resolution: "@babel/generator@npm:7.23.5"
|
||||||
|
dependencies:
|
||||||
|
"@babel/types": ^7.23.5
|
||||||
|
"@jridgewell/gen-mapping": ^0.3.2
|
||||||
|
"@jridgewell/trace-mapping": ^0.3.17
|
||||||
|
jsesc: ^2.5.1
|
||||||
|
checksum: 14c6e874f796c4368e919bed6003bb0adc3ce837760b08f9e646d20aeb5ae7d309723ce6e4f06bcb4a2b5753145446c8e4425851380f695e40e71e1760f49e7b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@babel/helper-compilation-targets@npm:^7.22.15":
|
"@babel/helper-compilation-targets@npm:^7.22.15":
|
||||||
version: 7.22.15
|
version: 7.22.15
|
||||||
resolution: "@babel/helper-compilation-targets@npm:7.22.15"
|
resolution: "@babel/helper-compilation-targets@npm:7.22.15"
|
||||||
@@ -221,6 +266,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@babel/helpers@npm:^7.23.5":
|
||||||
|
version: 7.23.5
|
||||||
|
resolution: "@babel/helpers@npm:7.23.5"
|
||||||
|
dependencies:
|
||||||
|
"@babel/template": ^7.22.15
|
||||||
|
"@babel/traverse": ^7.23.5
|
||||||
|
"@babel/types": ^7.23.5
|
||||||
|
checksum: a37e2728eb4378a4888e5d614e28de7dd79b55ac8acbecd0e5c761273e2a02a8f33b34b1932d9069db55417ace2937cbf8ec37c42f1030ce6d228857d7ccaa4f
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@babel/highlight@npm:^7.23.4":
|
"@babel/highlight@npm:^7.23.4":
|
||||||
version: 7.23.4
|
version: 7.23.4
|
||||||
resolution: "@babel/highlight@npm:7.23.4"
|
resolution: "@babel/highlight@npm:7.23.4"
|
||||||
@@ -232,6 +288,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.5":
|
||||||
|
version: 7.23.5
|
||||||
|
resolution: "@babel/parser@npm:7.23.5"
|
||||||
|
bin:
|
||||||
|
parser: ./bin/babel-parser.js
|
||||||
|
checksum: 3356aa90d7bafb4e2c7310e7c2c3d443c4be4db74913f088d3d577a1eb914ea4188e05fd50a47ce907a27b755c4400c4e3cbeee73dbeb37761f6ca85954f5a20
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.3, @babel/parser@npm:^7.23.4":
|
"@babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.3, @babel/parser@npm:^7.23.4":
|
||||||
version: 7.23.4
|
version: 7.23.4
|
||||||
resolution: "@babel/parser@npm:7.23.4"
|
resolution: "@babel/parser@npm:7.23.4"
|
||||||
@@ -252,6 +317,24 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@babel/traverse@npm:^7.18.9, @babel/traverse@npm:^7.23.5":
|
||||||
|
version: 7.23.5
|
||||||
|
resolution: "@babel/traverse@npm:7.23.5"
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame": ^7.23.5
|
||||||
|
"@babel/generator": ^7.23.5
|
||||||
|
"@babel/helper-environment-visitor": ^7.22.20
|
||||||
|
"@babel/helper-function-name": ^7.23.0
|
||||||
|
"@babel/helper-hoist-variables": ^7.22.5
|
||||||
|
"@babel/helper-split-export-declaration": ^7.22.6
|
||||||
|
"@babel/parser": ^7.23.5
|
||||||
|
"@babel/types": ^7.23.5
|
||||||
|
debug: ^4.1.0
|
||||||
|
globals: ^11.1.0
|
||||||
|
checksum: c5ea793080ca6719b0a1612198fd25e361cee1f3c14142d7a518d2a1eeb5c1d21f7eec1b26c20ea6e1ddd8ed12ab50b960ff95ffd25be353b6b46e1b54d6f825
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@babel/traverse@npm:^7.23.3, @babel/traverse@npm:^7.23.4":
|
"@babel/traverse@npm:^7.23.3, @babel/traverse@npm:^7.23.4":
|
||||||
version: 7.23.4
|
version: 7.23.4
|
||||||
resolution: "@babel/traverse@npm:7.23.4"
|
resolution: "@babel/traverse@npm:7.23.4"
|
||||||
@@ -270,6 +353,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.23.5":
|
||||||
|
version: 7.23.5
|
||||||
|
resolution: "@babel/types@npm:7.23.5"
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-string-parser": ^7.23.4
|
||||||
|
"@babel/helper-validator-identifier": ^7.22.20
|
||||||
|
to-fast-properties: ^2.0.0
|
||||||
|
checksum: 7dd5e2f59828ed046ad0b06b039df2524a8b728d204affb4fc08da2502b9dd3140b1356b5166515d229dc811539a8b70dcd4bc507e06d62a89f4091a38d0b0fb
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@babel/types@npm:^7.22.15, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.3, @babel/types@npm:^7.23.4, @babel/types@npm:^7.8.3":
|
"@babel/types@npm:^7.22.15, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.3, @babel/types@npm:^7.23.4, @babel/types@npm:^7.8.3":
|
||||||
version: 7.23.4
|
version: 7.23.4
|
||||||
resolution: "@babel/types@npm:7.23.4"
|
resolution: "@babel/types@npm:7.23.4"
|
||||||
@@ -900,6 +994,54 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/babel__core@npm:^7.18.0":
|
||||||
|
version: 7.20.5
|
||||||
|
resolution: "@types/babel__core@npm:7.20.5"
|
||||||
|
dependencies:
|
||||||
|
"@babel/parser": ^7.20.7
|
||||||
|
"@babel/types": ^7.20.7
|
||||||
|
"@types/babel__generator": "*"
|
||||||
|
"@types/babel__template": "*"
|
||||||
|
"@types/babel__traverse": "*"
|
||||||
|
checksum: bdee3bb69951e833a4b811b8ee9356b69a61ed5b7a23e1a081ec9249769117fa83aaaf023bb06562a038eb5845155ff663e2d5c75dd95c1d5ccc91db012868ff
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/babel__generator@npm:*":
|
||||||
|
version: 7.6.7
|
||||||
|
resolution: "@types/babel__generator@npm:7.6.7"
|
||||||
|
dependencies:
|
||||||
|
"@babel/types": ^7.0.0
|
||||||
|
checksum: 2427203864ef231857e102eeb32b731a419164863983119cdd4dac9f1503c2831eb4262d05ade95d4574aa410b94c16e54e36a616758452f685a34881f4596d9
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/babel__template@npm:*":
|
||||||
|
version: 7.4.4
|
||||||
|
resolution: "@types/babel__template@npm:7.4.4"
|
||||||
|
dependencies:
|
||||||
|
"@babel/parser": ^7.1.0
|
||||||
|
"@babel/types": ^7.0.0
|
||||||
|
checksum: cc84f6c6ab1eab1427e90dd2b76ccee65ce940b778a9a67be2c8c39e1994e6f5bbc8efa309f6cea8dc6754994524cd4d2896558df76d92e7a1f46ecffee7112b
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/babel__traverse@npm:*, @types/babel__traverse@npm:^7.18.0":
|
||||||
|
version: 7.20.4
|
||||||
|
resolution: "@types/babel__traverse@npm:7.20.4"
|
||||||
|
dependencies:
|
||||||
|
"@babel/types": ^7.20.7
|
||||||
|
checksum: e76cb4974c7740fd61311152dc497e7b05c1c46ba554aab875544ab0a7457f343cafcad34ba8fb2ff543ab0e012ef2d3fa0c13f1a4e9a4cd9c4c703c7a2a8d62
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/doctrine@npm:^0.0.9":
|
||||||
|
version: 0.0.9
|
||||||
|
resolution: "@types/doctrine@npm:0.0.9"
|
||||||
|
checksum: cdaca493f13c321cf0cacd1973efc0ae74569633145d9e6fc1128f32217a6968c33bea1f858275239fe90c98f3be57ec8f452b416a9ff48b8e8c1098b20fa51c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/json-schema@npm:^7.0.12":
|
"@types/json-schema@npm:^7.0.12":
|
||||||
version: 7.0.15
|
version: 7.0.15
|
||||||
resolution: "@types/json-schema@npm:7.0.15"
|
resolution: "@types/json-schema@npm:7.0.15"
|
||||||
@@ -930,6 +1072,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/resolve@npm:^1.20.2":
|
||||||
|
version: 1.20.6
|
||||||
|
resolution: "@types/resolve@npm:1.20.6"
|
||||||
|
checksum: a9b0549d816ff2c353077365d865a33655a141d066d0f5a3ba6fd4b28bc2f4188a510079f7c1f715b3e7af505a27374adce2a5140a3ece2a059aab3d6e1a4244
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/semver@npm:^7.5.0":
|
"@types/semver@npm:^7.5.0":
|
||||||
version: 7.5.6
|
version: 7.5.6
|
||||||
resolution: "@types/semver@npm:7.5.6"
|
resolution: "@types/semver@npm:7.5.6"
|
||||||
@@ -2911,6 +3060,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"min-indent@npm:^1.0.1":
|
||||||
|
version: 1.0.1
|
||||||
|
resolution: "min-indent@npm:1.0.1"
|
||||||
|
checksum: 7e207bd5c20401b292de291f02913230cb1163abca162044f7db1d951fa245b174dc00869d40dd9a9f32a885ad6a5f3e767ee104cf278f399cb4e92d3f582d5c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"minimatch@npm:^3.0.2, minimatch@npm:^3.0.3, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
|
"minimatch@npm:^3.0.2, minimatch@npm:^3.0.3, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
|
||||||
version: 3.1.2
|
version: 3.1.2
|
||||||
resolution: "minimatch@npm:3.1.2"
|
resolution: "minimatch@npm:3.1.2"
|
||||||
@@ -3524,6 +3680,46 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"react-docgen@npm:^7.0.1":
|
||||||
|
version: 7.0.1
|
||||||
|
resolution: "react-docgen@npm:7.0.1"
|
||||||
|
dependencies:
|
||||||
|
"@babel/core": ^7.18.9
|
||||||
|
"@babel/traverse": ^7.18.9
|
||||||
|
"@babel/types": ^7.18.9
|
||||||
|
"@types/babel__core": ^7.18.0
|
||||||
|
"@types/babel__traverse": ^7.18.0
|
||||||
|
"@types/doctrine": ^0.0.9
|
||||||
|
"@types/resolve": ^1.20.2
|
||||||
|
doctrine: ^3.0.0
|
||||||
|
resolve: ^1.22.1
|
||||||
|
strip-indent: ^4.0.0
|
||||||
|
checksum: 870c1193211f14497bf7a96137f96840dc058842ca75ff7251d91e88c3c71d7a41d5f1a124cc1b53bfbf1f2b6b58bfccc4dd6e22592814a5155d3894953274be
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"react-docs-generator@workspace:packages/react-docs-generator":
|
||||||
|
version: 0.0.0-use.local
|
||||||
|
resolution: "react-docs-generator@workspace:packages/react-docs-generator"
|
||||||
|
dependencies:
|
||||||
|
"@types/node": ^20.9.4
|
||||||
|
chalk: ^5.3.0
|
||||||
|
commander: ^11.1.0
|
||||||
|
glob: ^10.3.10
|
||||||
|
react-docgen: ^7.0.1
|
||||||
|
resolve: ^1.22.8
|
||||||
|
ts-node: ^10.9.1
|
||||||
|
typedoc: ^0.25.4
|
||||||
|
typedoc-plugin-custom: "*"
|
||||||
|
typescript: 5.2
|
||||||
|
utils: "*"
|
||||||
|
peerDependencies:
|
||||||
|
typedoc: 0.25.x
|
||||||
|
bin:
|
||||||
|
react-docs-generator: dist/index.js
|
||||||
|
languageName: unknown
|
||||||
|
linkType: soft
|
||||||
|
|
||||||
"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0":
|
"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0":
|
||||||
version: 3.6.2
|
version: 3.6.2
|
||||||
resolution: "readable-stream@npm:3.6.2"
|
resolution: "readable-stream@npm:3.6.2"
|
||||||
@@ -3608,7 +3804,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"resolve@npm:^1.20.0":
|
"resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.8":
|
||||||
version: 1.22.8
|
version: 1.22.8
|
||||||
resolution: "resolve@npm:1.22.8"
|
resolution: "resolve@npm:1.22.8"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3621,7 +3817,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"resolve@patch:resolve@^1.20.0#~builtin<compat/resolve>":
|
"resolve@patch:resolve@^1.20.0#~builtin<compat/resolve>, resolve@patch:resolve@^1.22.1#~builtin<compat/resolve>, resolve@patch:resolve@^1.22.8#~builtin<compat/resolve>":
|
||||||
version: 1.22.8
|
version: 1.22.8
|
||||||
resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin<compat/resolve>::version=1.22.8&hash=07638b"
|
resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin<compat/resolve>::version=1.22.8&hash=07638b"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -3719,7 +3915,7 @@ __metadata:
|
|||||||
glob: ^10.3.10
|
glob: ^10.3.10
|
||||||
randomcolor: ^0.6.2
|
randomcolor: ^0.6.2
|
||||||
ts-node: ^10.9.1
|
ts-node: ^10.9.1
|
||||||
typedoc: 0.25.1
|
typedoc: ^0.25.4
|
||||||
typedoc-config: "*"
|
typedoc-config: "*"
|
||||||
typedoc-monorepo-link-types: ^0.0.2
|
typedoc-monorepo-link-types: ^0.0.2
|
||||||
typedoc-plugin-custom: "*"
|
typedoc-plugin-custom: "*"
|
||||||
@@ -3917,6 +4113,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"strip-indent@npm:^4.0.0":
|
||||||
|
version: 4.0.0
|
||||||
|
resolution: "strip-indent@npm:4.0.0"
|
||||||
|
dependencies:
|
||||||
|
min-indent: ^1.0.1
|
||||||
|
checksum: 6b1fb4e22056867f5c9e7a6f3f45922d9a2436cac758607d58aeaac0d3b16ec40b1c43317de7900f1b8dd7a4107352fa47fb960f2c23566538c51e8585c8870e
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"strip-json-comments@npm:^3.1.1":
|
"strip-json-comments@npm:^3.1.1":
|
||||||
version: 3.1.1
|
version: 3.1.1
|
||||||
resolution: "strip-json-comments@npm:3.1.1"
|
resolution: "strip-json-comments@npm:3.1.1"
|
||||||
@@ -4323,19 +4528,19 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"typedoc@npm:0.25.1":
|
"typedoc@npm:^0.25.4":
|
||||||
version: 0.25.1
|
version: 0.25.4
|
||||||
resolution: "typedoc@npm:0.25.1"
|
resolution: "typedoc@npm:0.25.4"
|
||||||
dependencies:
|
dependencies:
|
||||||
lunr: ^2.3.9
|
lunr: ^2.3.9
|
||||||
marked: ^4.3.0
|
marked: ^4.3.0
|
||||||
minimatch: ^9.0.3
|
minimatch: ^9.0.3
|
||||||
shiki: ^0.14.1
|
shiki: ^0.14.1
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x
|
typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x
|
||||||
bin:
|
bin:
|
||||||
typedoc: bin/typedoc
|
typedoc: bin/typedoc
|
||||||
checksum: 11d91302378d618ce451cc5857fcfd4d7923a20075c15ef7b7be663f827d3c2e01260b23ddb97d0d2d47b414b5ed3953a8fabc1adcb582c093d667cf704b5e48
|
checksum: 2790b3f16b26a477cfc9b72f81b4f209c885c554f9c7b2557d5d85ea4c8bd6a51584af8d29eec123a26398c4986f52b0c3c7a9c32352a223c33a96bd211f288f
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|||||||
@@ -52,12 +52,34 @@ interface AvatarProps
|
|||||||
fallback: string
|
fallback: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Avatar](https://www.radix-ui.com/primitives/docs/components/avatar) primitive.
|
||||||
|
*/
|
||||||
const Avatar = React.forwardRef<
|
const Avatar = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.Root>,
|
React.ElementRef<typeof Primitives.Root>,
|
||||||
AvatarProps
|
AvatarProps
|
||||||
>(
|
>(
|
||||||
(
|
(
|
||||||
{ src, fallback, variant = "rounded", size = "base", className, ...props },
|
{
|
||||||
|
/**
|
||||||
|
* The URL of the image used in the Avatar.
|
||||||
|
*/
|
||||||
|
src,
|
||||||
|
/**
|
||||||
|
* Text to show in the avatar if the URL provided in `src` can't be opened.
|
||||||
|
*/
|
||||||
|
fallback,
|
||||||
|
/**
|
||||||
|
* The style of the avatar.
|
||||||
|
*/
|
||||||
|
variant = "rounded",
|
||||||
|
/**
|
||||||
|
* The size of the avatar's border radius.
|
||||||
|
*/
|
||||||
|
size = "base",
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: AvatarProps,
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -49,16 +49,32 @@ interface BadgeProps
|
|||||||
asChild?: boolean
|
asChild?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `div` element and supports all of its props
|
||||||
|
*/
|
||||||
const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(
|
const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
className,
|
className,
|
||||||
|
/**
|
||||||
|
* The badge's size.
|
||||||
|
*/
|
||||||
size = "base",
|
size = "base",
|
||||||
|
/**
|
||||||
|
* The style of the badge's border radius.
|
||||||
|
*/
|
||||||
rounded = "base",
|
rounded = "base",
|
||||||
|
/**
|
||||||
|
* The badge's color.
|
||||||
|
*/
|
||||||
color = "grey",
|
color = "grey",
|
||||||
|
/**
|
||||||
|
* Whether to remove the wrapper `span` element and use the
|
||||||
|
* passed child element instead.
|
||||||
|
*/
|
||||||
asChild = false,
|
asChild = false,
|
||||||
...props
|
...props
|
||||||
},
|
}: BadgeProps,
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const Component = asChild ? Slot : "span"
|
const Component = asChild ? Slot : "span"
|
||||||
|
|||||||
@@ -59,18 +59,34 @@ interface ButtonProps
|
|||||||
asChild?: boolean
|
asChild?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `button` element and supports all of its props
|
||||||
|
*/
|
||||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The button's style.
|
||||||
|
*/
|
||||||
variant = "primary",
|
variant = "primary",
|
||||||
|
/**
|
||||||
|
* The button's size.
|
||||||
|
*/
|
||||||
size = "base",
|
size = "base",
|
||||||
className,
|
className,
|
||||||
|
/**
|
||||||
|
* Whether to remove the wrapper `button` element and use the
|
||||||
|
* passed child element instead.
|
||||||
|
*/
|
||||||
asChild = false,
|
asChild = false,
|
||||||
children,
|
children,
|
||||||
|
/**
|
||||||
|
* Whether to show a loading spinner.
|
||||||
|
*/
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
disabled,
|
disabled,
|
||||||
...props
|
...props
|
||||||
},
|
}: ButtonProps,
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const Component = asChild ? Slot : "button"
|
const Component = asChild ? Slot : "button"
|
||||||
|
|||||||
@@ -22,6 +22,9 @@ type KeysToOmit = "showWeekNumber" | "captionLayout" | "mode"
|
|||||||
type SingleProps = OmitKeys<DayPickerSingleProps, KeysToOmit>
|
type SingleProps = OmitKeys<DayPickerSingleProps, KeysToOmit>
|
||||||
type RangeProps = OmitKeys<DayPickerRangeProps, KeysToOmit>
|
type RangeProps = OmitKeys<DayPickerRangeProps, KeysToOmit>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @interface
|
||||||
|
*/
|
||||||
type CalendarProps =
|
type CalendarProps =
|
||||||
| ({
|
| ({
|
||||||
mode: "single"
|
mode: "single"
|
||||||
@@ -33,10 +36,29 @@ type CalendarProps =
|
|||||||
mode: "range"
|
mode: "range"
|
||||||
} & RangeProps)
|
} & RangeProps)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [react-date-picker](https://www.npmjs.com/package/react-date-picker) package.
|
||||||
|
*
|
||||||
|
* @excludeExternal
|
||||||
|
*/
|
||||||
const Calendar = ({
|
const Calendar = ({
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
className,
|
className,
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
classNames,
|
classNames,
|
||||||
|
/**
|
||||||
|
* The calendar's mode.
|
||||||
|
*/
|
||||||
mode = "single",
|
mode = "single",
|
||||||
|
/**
|
||||||
|
* Whether to show days of previous and next months.
|
||||||
|
*
|
||||||
|
* @keep
|
||||||
|
*/
|
||||||
showOutsideDays = true,
|
showOutsideDays = true,
|
||||||
...props
|
...props
|
||||||
}: CalendarProps) => {
|
}: CalendarProps) => {
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ import * as React from "react"
|
|||||||
|
|
||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Checkbox](https://www.radix-ui.com/primitives/docs/components/checkbox) primitive.
|
||||||
|
*/
|
||||||
const Checkbox = React.forwardRef<
|
const Checkbox = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.Root>,
|
React.ElementRef<typeof Primitives.Root>,
|
||||||
React.ComponentPropsWithoutRef<typeof Primitives.Root>
|
React.ComponentPropsWithoutRef<typeof Primitives.Root>
|
||||||
|
|||||||
@@ -6,10 +6,25 @@ import { Copy } from "@/components/copy"
|
|||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
|
|
||||||
export type CodeSnippet = {
|
export type CodeSnippet = {
|
||||||
|
/**
|
||||||
|
* The label of the code snippet's tab.
|
||||||
|
*/
|
||||||
label: string
|
label: string
|
||||||
|
/**
|
||||||
|
* The language of the code snippet. For example, `tsx`.
|
||||||
|
*/
|
||||||
language: string
|
language: string
|
||||||
|
/**
|
||||||
|
* The code snippet.
|
||||||
|
*/
|
||||||
code: string
|
code: string
|
||||||
|
/**
|
||||||
|
* Whether to hide the line numbers shown as the side of the code snippet.
|
||||||
|
*/
|
||||||
hideLineNumbers?: boolean
|
hideLineNumbers?: boolean
|
||||||
|
/**
|
||||||
|
* Whether to hide the copy button.
|
||||||
|
*/
|
||||||
hideCopy?: boolean
|
hideCopy?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +51,13 @@ type RootProps = {
|
|||||||
snippets: CodeSnippet[]
|
snippets: CodeSnippet[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `div` element and supports all of its props
|
||||||
|
*/
|
||||||
const Root = ({
|
const Root = ({
|
||||||
|
/**
|
||||||
|
* The code snippets.
|
||||||
|
*/
|
||||||
snippets,
|
snippets,
|
||||||
className,
|
className,
|
||||||
children,
|
children,
|
||||||
@@ -58,14 +79,21 @@ const Root = ({
|
|||||||
</CodeBlockContext.Provider>
|
</CodeBlockContext.Provider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Root.displayName = "CodeBlock"
|
||||||
|
|
||||||
type HeaderProps = {
|
type HeaderProps = {
|
||||||
hideLabels?: boolean
|
hideLabels?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `div` element and supports all of its props
|
||||||
|
*/
|
||||||
const HeaderComponent = ({
|
const HeaderComponent = ({
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
|
/**
|
||||||
|
* Whether to hide the code snippets' labels.
|
||||||
|
*/
|
||||||
hideLabels = false,
|
hideLabels = false,
|
||||||
...props
|
...props
|
||||||
}: React.HTMLAttributes<HTMLDivElement> & HeaderProps) => {
|
}: React.HTMLAttributes<HTMLDivElement> & HeaderProps) => {
|
||||||
@@ -98,7 +126,11 @@ const HeaderComponent = ({
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
HeaderComponent.displayName = "CodeBlock.Header"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `div` element and supports all of its props
|
||||||
|
*/
|
||||||
const Meta = ({
|
const Meta = ({
|
||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
@@ -110,9 +142,13 @@ const Meta = ({
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Meta.displayName = "CodeBlock.Header.Meta"
|
||||||
|
|
||||||
const Header = Object.assign(HeaderComponent, { Meta })
|
const Header = Object.assign(HeaderComponent, { Meta })
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `div` element and supports all of its props
|
||||||
|
*/
|
||||||
const Body = ({
|
const Body = ({
|
||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
@@ -240,6 +276,7 @@ const Body = ({
|
|||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Body.displayName = "CodeBlock.Body"
|
||||||
|
|
||||||
const CodeBlock = Object.assign(Root, { Body, Header, Meta })
|
const CodeBlock = Object.assign(Root, { Body, Header, Meta })
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `code` element and supports all of its props
|
||||||
|
*/
|
||||||
const Code = React.forwardRef<
|
const Code = React.forwardRef<
|
||||||
HTMLElement,
|
HTMLElement,
|
||||||
React.ComponentPropsWithoutRef<"code">
|
React.ComponentPropsWithoutRef<"code">
|
||||||
|
|||||||
@@ -7,17 +7,32 @@ import * as React from "react"
|
|||||||
import { Kbd } from "@/components/kbd"
|
import { Kbd } from "@/components/kbd"
|
||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
|
|
||||||
type CommandBarProps = React.PropsWithChildren<{
|
interface CommandBarProps extends React.PropsWithChildren {
|
||||||
open?: boolean
|
open?: boolean
|
||||||
onOpenChange?: (open: boolean) => void
|
onOpenChange?: (open: boolean) => void
|
||||||
defaultOpen?: boolean
|
defaultOpen?: boolean
|
||||||
disableAutoFocus?: boolean
|
disableAutoFocus?: boolean
|
||||||
}>
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The root component of the command bar. This component manages the state of the command bar.
|
||||||
|
*/
|
||||||
const Root = ({
|
const Root = ({
|
||||||
|
/**
|
||||||
|
* Whether to open (show) the command bar.
|
||||||
|
*/
|
||||||
open = false,
|
open = false,
|
||||||
|
/**
|
||||||
|
* Specify a function to handle the change of `open`'s value.
|
||||||
|
*/
|
||||||
onOpenChange,
|
onOpenChange,
|
||||||
|
/**
|
||||||
|
* Whether the command bar is open by default.
|
||||||
|
*/
|
||||||
defaultOpen = false,
|
defaultOpen = false,
|
||||||
|
/**
|
||||||
|
* Whether to disable focusing automatically on the command bar when it's opened.
|
||||||
|
*/
|
||||||
disableAutoFocus = true,
|
disableAutoFocus = true,
|
||||||
children,
|
children,
|
||||||
}: CommandBarProps) => {
|
}: CommandBarProps) => {
|
||||||
@@ -53,6 +68,10 @@ const Root = ({
|
|||||||
}
|
}
|
||||||
Root.displayName = "CommandBar"
|
Root.displayName = "CommandBar"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value component of the command bar. This component is used to display a value,
|
||||||
|
* such as the number of selected items which the commands will act on.
|
||||||
|
*/
|
||||||
const Value = React.forwardRef<
|
const Value = React.forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDivElement,
|
||||||
React.ComponentPropsWithoutRef<"div">
|
React.ComponentPropsWithoutRef<"div">
|
||||||
@@ -70,6 +89,9 @@ const Value = React.forwardRef<
|
|||||||
})
|
})
|
||||||
Value.displayName = "CommandBar.Value"
|
Value.displayName = "CommandBar.Value"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bar component of the command bar. This component is used to display the commands.
|
||||||
|
*/
|
||||||
const Bar = React.forwardRef<
|
const Bar = React.forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDivElement,
|
||||||
React.ComponentPropsWithoutRef<"div">
|
React.ComponentPropsWithoutRef<"div">
|
||||||
@@ -88,6 +110,9 @@ const Bar = React.forwardRef<
|
|||||||
})
|
})
|
||||||
Bar.displayName = "CommandBar.Bar"
|
Bar.displayName = "CommandBar.Bar"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The seperator component of the command bar. This component is used to display a seperator between commands.
|
||||||
|
*/
|
||||||
const Seperator = React.forwardRef<
|
const Seperator = React.forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDivElement,
|
||||||
Omit<React.ComponentPropsWithoutRef<"div">, "children">
|
Omit<React.ComponentPropsWithoutRef<"div">, "children">
|
||||||
@@ -112,9 +137,29 @@ interface CommandProps
|
|||||||
shortcut: string
|
shortcut: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The command component of the command bar. This component is used to display a command, as well as registering the keyboad shortcut.
|
||||||
|
*/
|
||||||
const Command = React.forwardRef<HTMLButtonElement, CommandProps>(
|
const Command = React.forwardRef<HTMLButtonElement, CommandProps>(
|
||||||
(
|
(
|
||||||
{ className, type = "button", label, action, shortcut, disabled, ...props },
|
{
|
||||||
|
className,
|
||||||
|
type = "button",
|
||||||
|
/**
|
||||||
|
* The command's label.
|
||||||
|
*/
|
||||||
|
label,
|
||||||
|
/**
|
||||||
|
* The function to execute when the command is triggered.
|
||||||
|
*/
|
||||||
|
action,
|
||||||
|
/**
|
||||||
|
* The command's shortcut
|
||||||
|
*/
|
||||||
|
shortcut,
|
||||||
|
disabled,
|
||||||
|
...props
|
||||||
|
}: CommandProps,
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ import { Copy } from "@/components/copy"
|
|||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
import React from "react"
|
import React from "react"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the div element and supports all of its props
|
||||||
|
*/
|
||||||
const CommandComponent = ({
|
const CommandComponent = ({
|
||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
@@ -19,6 +22,7 @@ const CommandComponent = ({
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
CommandComponent.displayName = "Command"
|
||||||
|
|
||||||
const Command = Object.assign(CommandComponent, { Copy })
|
const Command = Object.assign(CommandComponent, { Copy })
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import * as React from "react"
|
|||||||
|
|
||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `div` element and supports all of its props
|
||||||
|
*/
|
||||||
const Container = React.forwardRef<
|
const Container = React.forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDivElement,
|
||||||
React.ComponentPropsWithoutRef<"div">
|
React.ComponentPropsWithoutRef<"div">
|
||||||
|
|||||||
@@ -7,15 +7,31 @@ import { Slot } from "@radix-ui/react-slot"
|
|||||||
import copy from "copy-to-clipboard"
|
import copy from "copy-to-clipboard"
|
||||||
import React, { useState } from "react"
|
import React, { useState } from "react"
|
||||||
|
|
||||||
type CopyProps = {
|
type CopyProps = React.HTMLAttributes<HTMLButtonElement> & {
|
||||||
content: string
|
content: string
|
||||||
asChild?: boolean
|
asChild?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `button` element and supports all of its props
|
||||||
|
*/
|
||||||
const Copy = React.forwardRef<
|
const Copy = React.forwardRef<
|
||||||
HTMLButtonElement,
|
HTMLButtonElement,
|
||||||
React.HTMLAttributes<HTMLButtonElement> & CopyProps
|
CopyProps
|
||||||
>(({ children, className, content, asChild = false, ...props }, ref) => {
|
>(({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
/**
|
||||||
|
* The content to copy.
|
||||||
|
*/
|
||||||
|
content,
|
||||||
|
/**
|
||||||
|
* Whether to remove the wrapper `button` element and use the
|
||||||
|
* passed child element instead.
|
||||||
|
*/
|
||||||
|
asChild = false,
|
||||||
|
...props
|
||||||
|
}: CopyProps, ref) => {
|
||||||
const [done, setDone] = useState(false)
|
const [done, setDone] = useState(false)
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
const [text, setText] = useState("Copy")
|
const [text, setText] = useState("Copy")
|
||||||
|
|||||||
@@ -34,9 +34,31 @@ interface CurrencyInputProps
|
|||||||
code: string
|
code: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the input element and supports all of its props
|
||||||
|
*
|
||||||
|
* @excludeExternal
|
||||||
|
*/
|
||||||
const CurrencyInput = React.forwardRef<HTMLInputElement, CurrencyInputProps>(
|
const CurrencyInput = React.forwardRef<HTMLInputElement, CurrencyInputProps>(
|
||||||
(
|
(
|
||||||
{ size = "base", symbol, code, disabled, onInvalid, className, ...props },
|
{
|
||||||
|
/**
|
||||||
|
* The input's size.
|
||||||
|
*/
|
||||||
|
size = "base",
|
||||||
|
/**
|
||||||
|
* The symbol to show in the input.
|
||||||
|
*/
|
||||||
|
symbol,
|
||||||
|
/**
|
||||||
|
* The currency code to show in the input.
|
||||||
|
*/
|
||||||
|
code,
|
||||||
|
disabled,
|
||||||
|
onInvalid,
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: CurrencyInputProps,
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const innerRef = React.useRef<HTMLInputElement>(null)
|
const innerRef = React.useRef<HTMLInputElement>(null)
|
||||||
|
|||||||
@@ -34,13 +34,27 @@ const displayVariants = cva({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
interface DisplayProps extends React.ComponentProps<"button"> {
|
||||||
|
placeholder?: string
|
||||||
|
size?: "small" | "base"
|
||||||
|
}
|
||||||
|
|
||||||
const Display = React.forwardRef<
|
const Display = React.forwardRef<
|
||||||
HTMLButtonElement,
|
HTMLButtonElement,
|
||||||
React.ComponentProps<"button"> & {
|
DisplayProps
|
||||||
placeholder?: string
|
>(({
|
||||||
size?: "small" | "base"
|
className,
|
||||||
}
|
children,
|
||||||
>(({ className, children, placeholder, size = "base", ...props }, ref) => {
|
/**
|
||||||
|
* Placeholder of the date picker's input.
|
||||||
|
*/
|
||||||
|
placeholder,
|
||||||
|
/**
|
||||||
|
* The size of the date picker's input.
|
||||||
|
*/
|
||||||
|
size = "base",
|
||||||
|
...props
|
||||||
|
}: DisplayProps, ref) => {
|
||||||
return (
|
return (
|
||||||
<Primitives.Trigger asChild>
|
<Primitives.Trigger asChild>
|
||||||
<button
|
<button
|
||||||
@@ -88,14 +102,23 @@ const Flyout = React.forwardRef<
|
|||||||
Flyout.displayName = "DatePicker.Flyout"
|
Flyout.displayName = "DatePicker.Flyout"
|
||||||
|
|
||||||
interface Preset {
|
interface Preset {
|
||||||
|
/**
|
||||||
|
* The preset's label.
|
||||||
|
*/
|
||||||
label: string
|
label: string
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DatePreset extends Preset {
|
interface DatePreset extends Preset {
|
||||||
|
/**
|
||||||
|
* The preset's selected date.
|
||||||
|
*/
|
||||||
date: Date
|
date: Date
|
||||||
}
|
}
|
||||||
|
|
||||||
interface DateRangePreset extends Preset {
|
interface DateRangePreset extends Preset {
|
||||||
|
/**
|
||||||
|
* The preset's selected date range.
|
||||||
|
*/
|
||||||
dateRange: DateRange
|
dateRange: DateRange
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,8 +129,17 @@ type PresetContainerProps<TPreset extends Preset, TValue> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PresetContainer = <TPreset extends Preset, TValue>({
|
const PresetContainer = <TPreset extends Preset, TValue>({
|
||||||
|
/**
|
||||||
|
* Selectable preset configurations.
|
||||||
|
*/
|
||||||
presets,
|
presets,
|
||||||
|
/**
|
||||||
|
* A function that handles the event when a preset is selected.
|
||||||
|
*/
|
||||||
onSelect,
|
onSelect,
|
||||||
|
/**
|
||||||
|
* The currently selected preset.
|
||||||
|
*/
|
||||||
currentValue,
|
currentValue,
|
||||||
}: PresetContainerProps<TPreset, TValue>) => {
|
}: PresetContainerProps<TPreset, TValue>) => {
|
||||||
const isDateRangePresets = (preset: any): preset is DateRangePreset => {
|
const isDateRangePresets = (preset: any): preset is DateRangePreset => {
|
||||||
@@ -203,6 +235,7 @@ const PresetContainer = <TPreset extends Preset, TValue>({
|
|||||||
</ul>
|
</ul>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
PresetContainer.displayName = "DatePicker.PresetContainer"
|
||||||
|
|
||||||
const formatDate = (date: Date, includeTime?: boolean) => {
|
const formatDate = (date: Date, includeTime?: boolean) => {
|
||||||
const usesAmPm = !isBrowserLocaleClockType24h()
|
const usesAmPm = !isBrowserLocaleClockType24h()
|
||||||
@@ -219,21 +252,60 @@ const formatDate = (date: Date, includeTime?: boolean) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CalendarProps = {
|
type CalendarProps = {
|
||||||
|
/**
|
||||||
|
* The year to start showing the dates from.
|
||||||
|
*/
|
||||||
fromYear?: number
|
fromYear?: number
|
||||||
|
/**
|
||||||
|
* The year to show dates to.
|
||||||
|
*/
|
||||||
toYear?: number
|
toYear?: number
|
||||||
|
/**
|
||||||
|
* The month to start showing dates from.
|
||||||
|
*/
|
||||||
fromMonth?: Date
|
fromMonth?: Date
|
||||||
|
/**
|
||||||
|
* The month to show dates to.
|
||||||
|
*/
|
||||||
toMonth?: Date
|
toMonth?: Date
|
||||||
|
/**
|
||||||
|
* The day to start showing dates from.
|
||||||
|
*/
|
||||||
fromDay?: Date
|
fromDay?: Date
|
||||||
|
/**
|
||||||
|
* The day to show dates to.
|
||||||
|
*/
|
||||||
toDay?: Date
|
toDay?: Date
|
||||||
|
/**
|
||||||
|
* The date to show dates from.
|
||||||
|
*/
|
||||||
fromDate?: Date
|
fromDate?: Date
|
||||||
|
/**
|
||||||
|
* The date to show dates to.
|
||||||
|
*/
|
||||||
toDate?: Date
|
toDate?: Date
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PickerProps extends CalendarProps {
|
interface PickerProps extends CalendarProps {
|
||||||
|
/**
|
||||||
|
* The class name to apply on the date picker.
|
||||||
|
*/
|
||||||
className?: string
|
className?: string
|
||||||
|
/**
|
||||||
|
* Whether the date picker's input is disabled.
|
||||||
|
*/
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
|
/**
|
||||||
|
* Whether the date picker's input is required.
|
||||||
|
*/
|
||||||
required?: boolean
|
required?: boolean
|
||||||
|
/**
|
||||||
|
* The date picker's size.
|
||||||
|
*/
|
||||||
size?: "small" | "base"
|
size?: "small" | "base"
|
||||||
|
/**
|
||||||
|
* Whether to show a time picker along with the date picker.
|
||||||
|
*/
|
||||||
showTimePicker?: boolean
|
showTimePicker?: boolean
|
||||||
id?: string
|
id?: string
|
||||||
"aria-invalid"?: boolean
|
"aria-invalid"?: boolean
|
||||||
@@ -466,11 +538,23 @@ interface RangeProps extends PickerProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const RangeDatePicker = ({
|
const RangeDatePicker = ({
|
||||||
|
/**
|
||||||
|
* The date range selected by default.
|
||||||
|
*/
|
||||||
defaultValue,
|
defaultValue,
|
||||||
|
/**
|
||||||
|
* The selected date range.
|
||||||
|
*/
|
||||||
value,
|
value,
|
||||||
|
/**
|
||||||
|
* A function to handle the change in the selected date range.
|
||||||
|
*/
|
||||||
onChange,
|
onChange,
|
||||||
size = "base",
|
size = "base",
|
||||||
showTimePicker,
|
showTimePicker,
|
||||||
|
/**
|
||||||
|
* Provide selectable preset configurations.
|
||||||
|
*/
|
||||||
presets,
|
presets,
|
||||||
disabled,
|
disabled,
|
||||||
className,
|
className,
|
||||||
@@ -732,6 +816,14 @@ const RangeDatePicker = ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @interface
|
||||||
|
*
|
||||||
|
* @prop presets - Provide selectable preset configurations.
|
||||||
|
* @prop defaultValue - The date selected by default.
|
||||||
|
* @prop value - The selected date.
|
||||||
|
* @prop onChange - A function to handle the change in the selected date.
|
||||||
|
*/
|
||||||
type DatePickerProps = (
|
type DatePickerProps = (
|
||||||
| {
|
| {
|
||||||
mode?: "single"
|
mode?: "single"
|
||||||
@@ -891,7 +983,17 @@ const validatePresets = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const DatePicker = ({ mode = "single", ...props }: DatePickerProps) => {
|
/**
|
||||||
|
* This component is based on the [Calendar](https://docs.medusajs.com/ui/components/calendar)
|
||||||
|
* component and [Radix UI Popover](https://www.radix-ui.com/primitives/docs/components/popover).
|
||||||
|
*/
|
||||||
|
const DatePicker = ({
|
||||||
|
/**
|
||||||
|
* The date picker's mode.
|
||||||
|
*/
|
||||||
|
mode = "single",
|
||||||
|
...props
|
||||||
|
}: DatePickerProps) => {
|
||||||
if (props.presets) {
|
if (props.presets) {
|
||||||
validatePresets(props.presets, props)
|
validatePresets(props.presets, props)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,12 +10,15 @@ import { Kbd } from "@/components/kbd"
|
|||||||
import { Text } from "@/components/text"
|
import { Text } from "@/components/text"
|
||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dialog](https://www.radix-ui.com/primitives/docs/components/dialog) primitives.
|
||||||
|
*/
|
||||||
const DrawerRoot = (
|
const DrawerRoot = (
|
||||||
props: React.ComponentPropsWithoutRef<typeof DrawerPrimitives.Root>
|
props: React.ComponentPropsWithoutRef<typeof DrawerPrimitives.Root>
|
||||||
) => {
|
) => {
|
||||||
return <DrawerPrimitives.Root {...props} />
|
return <DrawerPrimitives.Root {...props} />
|
||||||
}
|
}
|
||||||
DrawerRoot.displayName = "Drawer.Root"
|
DrawerRoot.displayName = "Drawer"
|
||||||
|
|
||||||
const DrawerTrigger = React.forwardRef<
|
const DrawerTrigger = React.forwardRef<
|
||||||
React.ElementRef<typeof DrawerPrimitives.Trigger>,
|
React.ElementRef<typeof DrawerPrimitives.Trigger>,
|
||||||
|
|||||||
@@ -6,21 +6,39 @@ import * as React from "react"
|
|||||||
|
|
||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dropdown Menu](https://www.radix-ui.com/primitives/docs/components/dropdown-menu) primitive.
|
||||||
|
*/
|
||||||
const Root = Primitives.Root
|
const Root = Primitives.Root
|
||||||
Root.displayName = "DropdownMenu.Root"
|
Root.displayName = "DropdownMenu"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dropdown Menu Trigger](https://www.radix-ui.com/primitives/docs/components/dropdown-menu#trigger) primitive.
|
||||||
|
*/
|
||||||
const Trigger = Primitives.Trigger
|
const Trigger = Primitives.Trigger
|
||||||
Trigger.displayName = "DropdownMenu.Trigger"
|
Trigger.displayName = "DropdownMenu.Trigger"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dropdown Menu Group](https://www.radix-ui.com/primitives/docs/components/dropdown-menu#group) primitive.
|
||||||
|
*/
|
||||||
const Group = Primitives.Group
|
const Group = Primitives.Group
|
||||||
Group.displayName = "DropdownMenu.Group"
|
Group.displayName = "DropdownMenu.Group"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dropdown Menu Sub](https://www.radix-ui.com/primitives/docs/components/dropdown-menu#sub) primitive.
|
||||||
|
*/
|
||||||
const SubMenu = Primitives.Sub
|
const SubMenu = Primitives.Sub
|
||||||
SubMenu.displayName = "DropdownMenu.SubMenu"
|
SubMenu.displayName = "DropdownMenu.SubMenu"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dropdown Menu RadioGroup](https://www.radix-ui.com/primitives/docs/components/dropdown-menu#radiogroup) primitive.
|
||||||
|
*/
|
||||||
const RadioGroup = Primitives.RadioGroup
|
const RadioGroup = Primitives.RadioGroup
|
||||||
RadioGroup.displayName = "DropdownMenu.RadioGroup"
|
RadioGroup.displayName = "DropdownMenu.RadioGroup"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dropdown Menu SubTrigger](https://www.radix-ui.com/primitives/docs/components/dropdown-menu#subtrigger) primitive.
|
||||||
|
*/
|
||||||
const SubMenuTrigger = React.forwardRef<
|
const SubMenuTrigger = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.SubTrigger>,
|
React.ElementRef<typeof Primitives.SubTrigger>,
|
||||||
React.ComponentPropsWithoutRef<typeof Primitives.SubTrigger>
|
React.ComponentPropsWithoutRef<typeof Primitives.SubTrigger>
|
||||||
@@ -39,6 +57,9 @@ const SubMenuTrigger = React.forwardRef<
|
|||||||
))
|
))
|
||||||
SubMenuTrigger.displayName = "DropdownMenu.SubMenuTrigger"
|
SubMenuTrigger.displayName = "DropdownMenu.SubMenuTrigger"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dropdown Menu SubContent](https://www.radix-ui.com/primitives/docs/components/dropdown-menu#subcontent) primitive.
|
||||||
|
*/
|
||||||
const SubMenuContent = React.forwardRef<
|
const SubMenuContent = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.SubContent>,
|
React.ElementRef<typeof Primitives.SubContent>,
|
||||||
React.ComponentPropsWithoutRef<typeof Primitives.SubContent>
|
React.ComponentPropsWithoutRef<typeof Primitives.SubContent>
|
||||||
@@ -58,6 +79,9 @@ const SubMenuContent = React.forwardRef<
|
|||||||
))
|
))
|
||||||
SubMenuContent.displayName = "DropdownMenu.SubMenuContent"
|
SubMenuContent.displayName = "DropdownMenu.SubMenuContent"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dropdown Menu Content](https://www.radix-ui.com/primitives/docs/components/dropdown-menu#content) primitive.
|
||||||
|
*/
|
||||||
const Content = React.forwardRef<
|
const Content = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.Content>,
|
React.ElementRef<typeof Primitives.Content>,
|
||||||
React.ComponentPropsWithoutRef<typeof Primitives.Content>
|
React.ComponentPropsWithoutRef<typeof Primitives.Content>
|
||||||
@@ -90,6 +114,9 @@ const Content = React.forwardRef<
|
|||||||
)
|
)
|
||||||
Content.displayName = "DropdownMenu.Content"
|
Content.displayName = "DropdownMenu.Content"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dropdown Menu Item](https://www.radix-ui.com/primitives/docs/components/dropdown-menu#item) primitive.
|
||||||
|
*/
|
||||||
const Item = React.forwardRef<
|
const Item = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.Item>,
|
React.ElementRef<typeof Primitives.Item>,
|
||||||
React.ComponentPropsWithoutRef<typeof Primitives.Item>
|
React.ComponentPropsWithoutRef<typeof Primitives.Item>
|
||||||
@@ -105,6 +132,9 @@ const Item = React.forwardRef<
|
|||||||
))
|
))
|
||||||
Item.displayName = "DropdownMenu.Item"
|
Item.displayName = "DropdownMenu.Item"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dropdown Menu CheckboxItem](https://www.radix-ui.com/primitives/docs/components/dropdown-menu#checkboxitem) primitive.
|
||||||
|
*/
|
||||||
const CheckboxItem = React.forwardRef<
|
const CheckboxItem = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.CheckboxItem>,
|
React.ElementRef<typeof Primitives.CheckboxItem>,
|
||||||
React.ComponentPropsWithoutRef<typeof Primitives.CheckboxItem>
|
React.ComponentPropsWithoutRef<typeof Primitives.CheckboxItem>
|
||||||
@@ -128,6 +158,9 @@ const CheckboxItem = React.forwardRef<
|
|||||||
))
|
))
|
||||||
CheckboxItem.displayName = "DropdownMenu.CheckboxItem"
|
CheckboxItem.displayName = "DropdownMenu.CheckboxItem"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dropdown Menu RadioItem](https://www.radix-ui.com/primitives/docs/components/dropdown-menu#radioitem) primitive.
|
||||||
|
*/
|
||||||
const RadioItem = React.forwardRef<
|
const RadioItem = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.RadioItem>,
|
React.ElementRef<typeof Primitives.RadioItem>,
|
||||||
React.ComponentPropsWithoutRef<typeof Primitives.RadioItem>
|
React.ComponentPropsWithoutRef<typeof Primitives.RadioItem>
|
||||||
@@ -150,6 +183,9 @@ const RadioItem = React.forwardRef<
|
|||||||
))
|
))
|
||||||
RadioItem.displayName = "DropdownMenu.RadioItem"
|
RadioItem.displayName = "DropdownMenu.RadioItem"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dropdown Menu Label](https://www.radix-ui.com/primitives/docs/components/dropdown-menu#label) primitive.
|
||||||
|
*/
|
||||||
const Label = React.forwardRef<
|
const Label = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.Label>,
|
React.ElementRef<typeof Primitives.Label>,
|
||||||
React.ComponentPropsWithoutRef<typeof Primitives.Label>
|
React.ComponentPropsWithoutRef<typeof Primitives.Label>
|
||||||
@@ -165,6 +201,9 @@ const Label = React.forwardRef<
|
|||||||
))
|
))
|
||||||
Label.displayName = "DropdownMenu.Label"
|
Label.displayName = "DropdownMenu.Label"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dropdown Menu Separator](https://www.radix-ui.com/primitives/docs/components/dropdown-menu#separator) primitive.
|
||||||
|
*/
|
||||||
const Separator = React.forwardRef<
|
const Separator = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.Separator>,
|
React.ElementRef<typeof Primitives.Separator>,
|
||||||
React.ComponentPropsWithoutRef<typeof Primitives.Separator>
|
React.ComponentPropsWithoutRef<typeof Primitives.Separator>
|
||||||
@@ -177,6 +216,9 @@ const Separator = React.forwardRef<
|
|||||||
))
|
))
|
||||||
Separator.displayName = "DropdownMenu.Separator"
|
Separator.displayName = "DropdownMenu.Separator"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `span` element and supports all of its props
|
||||||
|
*/
|
||||||
const Shortcut = ({
|
const Shortcut = ({
|
||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
@@ -193,6 +235,9 @@ const Shortcut = ({
|
|||||||
}
|
}
|
||||||
Shortcut.displayName = "DropdownMenu.Shortcut"
|
Shortcut.displayName = "DropdownMenu.Shortcut"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `span` element and supports all of its props
|
||||||
|
*/
|
||||||
const Hint = ({
|
const Hint = ({
|
||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
|
|||||||
@@ -8,8 +8,20 @@ import { IconButton } from "@/components/icon-button"
|
|||||||
import { Kbd } from "@/components/kbd"
|
import { Kbd } from "@/components/kbd"
|
||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @prop defaultOpen - Whether the modal is opened by default.
|
||||||
|
* @prop open - Whether the modal is opened.
|
||||||
|
* @prop onOpenChange - A function to handle when the modal is opened or closed.
|
||||||
|
*/
|
||||||
|
interface FocusModalRootProps
|
||||||
|
extends React.ComponentPropsWithoutRef<typeof FocusModalPrimitives.Root> {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Dialog](https://www.radix-ui.com/primitives/docs/components/dialog) primitives.
|
||||||
|
*/
|
||||||
const FocusModalRoot = (
|
const FocusModalRoot = (
|
||||||
props: React.ComponentPropsWithoutRef<typeof FocusModalPrimitives.Root>
|
props: FocusModalRootProps
|
||||||
) => {
|
) => {
|
||||||
return <FocusModalPrimitives.Root {...props} />
|
return <FocusModalPrimitives.Root {...props} />
|
||||||
}
|
}
|
||||||
@@ -72,6 +84,9 @@ const FocusModalContent = React.forwardRef<
|
|||||||
})
|
})
|
||||||
FocusModalContent.displayName = "FocusModal.Content"
|
FocusModalContent.displayName = "FocusModal.Content"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `div` element and supports all of its props
|
||||||
|
*/
|
||||||
const FocusModalHeader = React.forwardRef<
|
const FocusModalHeader = React.forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDivElement,
|
||||||
React.ComponentPropsWithoutRef<"div">
|
React.ComponentPropsWithoutRef<"div">
|
||||||
@@ -99,6 +114,9 @@ const FocusModalHeader = React.forwardRef<
|
|||||||
})
|
})
|
||||||
FocusModalHeader.displayName = "FocusModal.Header"
|
FocusModalHeader.displayName = "FocusModal.Header"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `div` element and supports all of its props
|
||||||
|
*/
|
||||||
const FocusModalBody = React.forwardRef<
|
const FocusModalBody = React.forwardRef<
|
||||||
HTMLDivElement,
|
HTMLDivElement,
|
||||||
React.ComponentPropsWithoutRef<"div">
|
React.ComponentPropsWithoutRef<"div">
|
||||||
|
|||||||
@@ -17,11 +17,22 @@ const headingVariants = cva({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
type HeadingProps = VariantProps<typeof headingVariants> &
|
interface HeadingProps extends VariantProps<typeof headingVariants>,
|
||||||
React.HTMLAttributes<HTMLHeadingElement>
|
React.HTMLAttributes<HTMLHeadingElement> {}
|
||||||
|
|
||||||
const Heading = ({ level, className, ...props }: HeadingProps) => {
|
/**
|
||||||
const Component = level ? level : "h1"
|
* This component is based on the heading element (`h1`, `h2`, etc...) depeneding on the specified level
|
||||||
|
* and supports all of its props
|
||||||
|
*/
|
||||||
|
const Heading = ({
|
||||||
|
/**
|
||||||
|
* The heading level which specifies which heading element is used.
|
||||||
|
*/
|
||||||
|
level = "h1",
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: HeadingProps) => {
|
||||||
|
const Component = level || "h1"
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Component
|
<Component
|
||||||
|
|||||||
@@ -17,11 +17,19 @@ const hintVariants = cva({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
type HintProps = VariantProps<typeof hintVariants> &
|
interface HintProps extends VariantProps<typeof hintVariants>,
|
||||||
React.ComponentPropsWithoutRef<"span">
|
React.ComponentPropsWithoutRef<"span"> {}
|
||||||
|
|
||||||
const Hint = React.forwardRef<HTMLSpanElement, HintProps>(
|
const Hint = React.forwardRef<HTMLSpanElement, HintProps>(
|
||||||
({ className, variant = "info", children, ...props }, ref) => {
|
({
|
||||||
|
className,
|
||||||
|
/**
|
||||||
|
* The hint's style.
|
||||||
|
*/
|
||||||
|
variant = "info",
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: HintProps, ref) => {
|
||||||
return (
|
return (
|
||||||
<span
|
<span
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
@@ -22,16 +22,29 @@ interface IconBadgeProps
|
|||||||
asChild?: boolean
|
asChild?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `span` element and supports all of its props
|
||||||
|
*/
|
||||||
const IconBadge = React.forwardRef<HTMLSpanElement, IconBadgeProps>(
|
const IconBadge = React.forwardRef<HTMLSpanElement, IconBadgeProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
children,
|
children,
|
||||||
className,
|
className,
|
||||||
|
/**
|
||||||
|
* The badge's color.
|
||||||
|
*/
|
||||||
color = "grey",
|
color = "grey",
|
||||||
|
/**
|
||||||
|
* The badge's size.
|
||||||
|
*/
|
||||||
size = "base",
|
size = "base",
|
||||||
|
/**
|
||||||
|
* Whether to remove the wrapper `span` element and use the
|
||||||
|
* passed child element instead.
|
||||||
|
*/
|
||||||
asChild = false,
|
asChild = false,
|
||||||
...props
|
...props
|
||||||
},
|
}: IconBadgeProps,
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const Component = asChild ? Slot : "span"
|
const Component = asChild ? Slot : "span"
|
||||||
|
|||||||
@@ -46,18 +46,34 @@ interface IconButtonProps
|
|||||||
isLoading?: boolean
|
isLoading?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `button` element and supports all of its props
|
||||||
|
*/
|
||||||
const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(
|
const IconButton = React.forwardRef<HTMLButtonElement, IconButtonProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The button's style.
|
||||||
|
*/
|
||||||
variant = "primary",
|
variant = "primary",
|
||||||
|
/**
|
||||||
|
* The button's size.
|
||||||
|
*/
|
||||||
size = "base",
|
size = "base",
|
||||||
|
/**
|
||||||
|
* Whether to remove the wrapper `button` element and use the
|
||||||
|
* passed child element instead.
|
||||||
|
*/
|
||||||
asChild = false,
|
asChild = false,
|
||||||
className,
|
className,
|
||||||
children,
|
children,
|
||||||
|
/**
|
||||||
|
* Whether to show a loading spinner.
|
||||||
|
*/
|
||||||
isLoading = false,
|
isLoading = false,
|
||||||
disabled,
|
disabled,
|
||||||
...props
|
...props
|
||||||
},
|
}: IconButtonProps,
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const Component = asChild ? Slot : "button"
|
const Component = asChild ? Slot : "button"
|
||||||
|
|||||||
@@ -29,11 +29,24 @@ const inputVariants = cva({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
interface InputProps extends VariantProps<typeof inputVariants>,
|
||||||
|
Omit<React.InputHTMLAttributes<HTMLInputElement>, "size"> {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `input` element and supports all of its props
|
||||||
|
*/
|
||||||
const Input = React.forwardRef<
|
const Input = React.forwardRef<
|
||||||
HTMLInputElement,
|
HTMLInputElement,
|
||||||
VariantProps<typeof inputVariants> &
|
InputProps
|
||||||
Omit<React.InputHTMLAttributes<HTMLInputElement>, "size">
|
>(({
|
||||||
>(({ className, type, size = "base", ...props }, ref) => {
|
className,
|
||||||
|
type,
|
||||||
|
/**
|
||||||
|
* The input's size.
|
||||||
|
*/
|
||||||
|
size = "base",
|
||||||
|
...props
|
||||||
|
}: InputProps, ref) => {
|
||||||
const [typeState, setTypeState] = React.useState(type)
|
const [typeState, setTypeState] = React.useState(type)
|
||||||
|
|
||||||
const isPassword = type === "password"
|
const isPassword = type === "password"
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import * as React from "react"
|
|||||||
|
|
||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `kbd` element and supports all of its props
|
||||||
|
*/
|
||||||
const Kbd = React.forwardRef<
|
const Kbd = React.forwardRef<
|
||||||
HTMLElement,
|
HTMLElement,
|
||||||
React.ComponentPropsWithoutRef<"kbd">
|
React.ComponentPropsWithoutRef<"kbd">
|
||||||
|
|||||||
@@ -30,8 +30,22 @@ interface LabelProps
|
|||||||
extends React.ComponentPropsWithoutRef<"label">,
|
extends React.ComponentPropsWithoutRef<"label">,
|
||||||
VariantProps<typeof labelVariants> {}
|
VariantProps<typeof labelVariants> {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Label](https://www.radix-ui.com/primitives/docs/components/label) primitive.
|
||||||
|
*/
|
||||||
const Label = React.forwardRef<HTMLLabelElement, LabelProps>(
|
const Label = React.forwardRef<HTMLLabelElement, LabelProps>(
|
||||||
({ className, size = "base", weight = "regular", ...props }, ref) => {
|
({
|
||||||
|
className,
|
||||||
|
/**
|
||||||
|
* The label's size.
|
||||||
|
*/
|
||||||
|
size = "base",
|
||||||
|
/**
|
||||||
|
* The label's font weight.
|
||||||
|
*/
|
||||||
|
weight = "regular",
|
||||||
|
...props
|
||||||
|
}: LabelProps, ref) => {
|
||||||
return (
|
return (
|
||||||
<Primitives.Root
|
<Primitives.Root
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ import * as React from "react"
|
|||||||
|
|
||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Popover](https://www.radix-ui.com/primitives/docs/components/popover) primitves.
|
||||||
|
*/
|
||||||
const Root = (
|
const Root = (
|
||||||
props: React.ComponentPropsWithoutRef<typeof Primitives.Root>
|
props: React.ComponentPropsWithoutRef<typeof Primitives.Root>
|
||||||
) => {
|
) => {
|
||||||
@@ -34,19 +37,34 @@ const Close = React.forwardRef<
|
|||||||
})
|
})
|
||||||
Close.displayName = "Popover.Close"
|
Close.displayName = "Popover.Close"
|
||||||
|
|
||||||
|
interface ContentProps extends React.ComponentPropsWithoutRef<typeof Primitives.Content> {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @excludeExternal
|
||||||
|
*/
|
||||||
const Content = React.forwardRef<
|
const Content = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.Content>,
|
React.ElementRef<typeof Primitives.Content>,
|
||||||
React.ComponentPropsWithoutRef<typeof Primitives.Content>
|
ContentProps
|
||||||
>(
|
>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
className,
|
className,
|
||||||
|
/**
|
||||||
|
* The distance in pixels from the anchor.
|
||||||
|
*/
|
||||||
sideOffset = 8,
|
sideOffset = 8,
|
||||||
|
/**
|
||||||
|
* The preferred side of the anchor to render against when open.
|
||||||
|
* Will be reversed when collisions occur and `avoidCollisions` is enabled.
|
||||||
|
*/
|
||||||
side = "bottom",
|
side = "bottom",
|
||||||
|
/**
|
||||||
|
* The preferred alignment against the anchor. May change when collisions occur.
|
||||||
|
*/
|
||||||
align = "start",
|
align = "start",
|
||||||
collisionPadding,
|
collisionPadding,
|
||||||
...props
|
...props
|
||||||
},
|
}: ContentProps,
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
return (
|
return (
|
||||||
|
|||||||
+39
-20
@@ -13,6 +13,9 @@ import { ProgressStatus } from "@/types"
|
|||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
import { IconButton } from "../icon-button"
|
import { IconButton } from "../icon-button"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Accordion](https://radix-ui.com/primitives/docs/components/accordion) primitves.
|
||||||
|
*/
|
||||||
const Root = (props: React.ComponentPropsWithoutRef<typeof Primitves.Root>) => {
|
const Root = (props: React.ComponentPropsWithoutRef<typeof Primitves.Root>) => {
|
||||||
return <Primitves.Root {...props} />
|
return <Primitves.Root {...props} />
|
||||||
}
|
}
|
||||||
@@ -44,7 +47,13 @@ interface StatusIndicatorProps extends React.ComponentPropsWithoutRef<"span"> {
|
|||||||
status: ProgressStatus
|
status: ProgressStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgressIndicator = ({ status, ...props }: StatusIndicatorProps) => {
|
const ProgressIndicator = ({
|
||||||
|
/**
|
||||||
|
* The current status.
|
||||||
|
*/
|
||||||
|
status,
|
||||||
|
...props
|
||||||
|
}: StatusIndicatorProps) => {
|
||||||
const Icon = React.useMemo(() => {
|
const Icon = React.useMemo(() => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case "not-started":
|
case "not-started":
|
||||||
@@ -67,29 +76,39 @@ const ProgressIndicator = ({ status, ...props }: StatusIndicatorProps) => {
|
|||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
ProgressIndicator.displayName = "ProgressAccordion.ProgressIndicator"
|
||||||
|
|
||||||
const Header = React.forwardRef<
|
const Header = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitves.Header>,
|
React.ElementRef<typeof Primitves.Header>,
|
||||||
HeaderProps
|
HeaderProps
|
||||||
>(({ className, status = "not-started", children, ...props }, ref) => {
|
>((
|
||||||
return (
|
{
|
||||||
<Primitves.Header
|
className,
|
||||||
ref={ref}
|
/**
|
||||||
className={clx(
|
* The current status.
|
||||||
"h3-core text-ui-fg-base group flex w-full flex-1 items-center gap-4 px-8",
|
*/
|
||||||
className
|
status = "not-started",
|
||||||
)}
|
children,
|
||||||
{...props}
|
...props
|
||||||
>
|
}: HeaderProps, ref) => {
|
||||||
<ProgressIndicator status={status} />
|
return (
|
||||||
{children}
|
<Primitves.Header
|
||||||
<Primitves.Trigger asChild className="ml-auto">
|
ref={ref}
|
||||||
<IconButton variant="transparent">
|
className={clx(
|
||||||
<Plus className="transform transition-transform group-data-[state=open]:rotate-45" />
|
"h3-core text-ui-fg-base group flex w-full flex-1 items-center gap-4 px-8",
|
||||||
</IconButton>
|
className
|
||||||
</Primitves.Trigger>
|
)}
|
||||||
</Primitves.Header>
|
{...props}
|
||||||
)
|
>
|
||||||
|
<ProgressIndicator status={status} />
|
||||||
|
{children}
|
||||||
|
<Primitves.Trigger asChild className="ml-auto">
|
||||||
|
<IconButton variant="transparent">
|
||||||
|
<Plus className="transform transition-transform group-data-[state=open]:rotate-45" />
|
||||||
|
</IconButton>
|
||||||
|
</Primitves.Trigger>
|
||||||
|
</Primitves.Header>
|
||||||
|
)
|
||||||
})
|
})
|
||||||
Header.displayName = "ProgressAccordion.Header"
|
Header.displayName = "ProgressAccordion.Header"
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ import * as React from "react"
|
|||||||
import { ProgressStatus } from "@/types"
|
import { ProgressStatus } from "@/types"
|
||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Tabs](https://radix-ui.com/primitives/docs/components/tabs) primitves.
|
||||||
|
*
|
||||||
|
* @excludeExternal
|
||||||
|
*/
|
||||||
const ProgressTabsRoot = (props: ProgressTabsPrimitives.TabsProps) => {
|
const ProgressTabsRoot = (props: ProgressTabsPrimitives.TabsProps) => {
|
||||||
return <ProgressTabsPrimitives.Root {...props} />
|
return <ProgressTabsPrimitives.Root {...props} />
|
||||||
}
|
}
|
||||||
@@ -18,10 +23,17 @@ ProgressTabsRoot.displayName = "ProgressTabs"
|
|||||||
|
|
||||||
interface IndicatorProps
|
interface IndicatorProps
|
||||||
extends Omit<React.ComponentPropsWithoutRef<"span">, "children"> {
|
extends Omit<React.ComponentPropsWithoutRef<"span">, "children"> {
|
||||||
|
/**
|
||||||
|
* The current status.
|
||||||
|
*/
|
||||||
status?: ProgressStatus
|
status?: ProgressStatus
|
||||||
}
|
}
|
||||||
|
|
||||||
const ProgressIndicator = ({ status, className, ...props }: IndicatorProps) => {
|
const ProgressIndicator = ({
|
||||||
|
status,
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: IndicatorProps) => {
|
||||||
const Icon = React.useMemo(() => {
|
const Icon = React.useMemo(() => {
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case "not-started":
|
case "not-started":
|
||||||
@@ -47,6 +59,7 @@ const ProgressIndicator = ({ status, className, ...props }: IndicatorProps) => {
|
|||||||
</span>
|
</span>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
ProgressIndicator.displayName = "ProgressTabs.ProgressIndicator"
|
||||||
|
|
||||||
interface ProgressTabsTriggerProps
|
interface ProgressTabsTriggerProps
|
||||||
extends Omit<
|
extends Omit<
|
||||||
@@ -59,7 +72,7 @@ interface ProgressTabsTriggerProps
|
|||||||
const ProgressTabsTrigger = React.forwardRef<
|
const ProgressTabsTrigger = React.forwardRef<
|
||||||
React.ElementRef<typeof ProgressTabsPrimitives.Trigger>,
|
React.ElementRef<typeof ProgressTabsPrimitives.Trigger>,
|
||||||
ProgressTabsTriggerProps
|
ProgressTabsTriggerProps
|
||||||
>(({ className, children, status = "not-started", ...props }, ref) => (
|
>(({ className, children, status = "not-started", ...props }: ProgressTabsTriggerProps, ref) => (
|
||||||
<ProgressTabsPrimitives.Trigger
|
<ProgressTabsPrimitives.Trigger
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={clx(
|
className={clx(
|
||||||
|
|||||||
@@ -7,8 +7,11 @@ import { Button } from "@/components/button"
|
|||||||
import { Heading } from "@/components/heading"
|
import { Heading } from "@/components/heading"
|
||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Alert Dialog](https://www.radix-ui.com/primitives/docs/components/alert-dialog) primitives.
|
||||||
|
*/
|
||||||
const Root = Primitives.AlertDialog
|
const Root = Primitives.AlertDialog
|
||||||
Root.displayName = "Prompt.Root"
|
Root.displayName = "Prompt"
|
||||||
|
|
||||||
const Trigger = Primitives.Trigger
|
const Trigger = Primitives.Trigger
|
||||||
Trigger.displayName = "Prompt.Trigger"
|
Trigger.displayName = "Prompt.Trigger"
|
||||||
@@ -111,6 +114,9 @@ const Cancel = React.forwardRef<
|
|||||||
})
|
})
|
||||||
Cancel.displayName = "Prompt.Cancel"
|
Cancel.displayName = "Prompt.Cancel"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `div` element and supports all of its props
|
||||||
|
*/
|
||||||
const Header = ({
|
const Header = ({
|
||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
@@ -122,7 +128,11 @@ const Header = ({
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Header.displayName = "Prompt.Header"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `div` element and supports all of its props
|
||||||
|
*/
|
||||||
const Footer = ({
|
const Footer = ({
|
||||||
className,
|
className,
|
||||||
...props
|
...props
|
||||||
@@ -134,6 +144,7 @@ const Footer = ({
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Footer.displayName = "Prompt.Footer"
|
||||||
|
|
||||||
const Prompt = Object.assign(Root, {
|
const Prompt = Object.assign(Root, {
|
||||||
Trigger,
|
Trigger,
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ import { clx } from "@/utils/clx"
|
|||||||
import { Hint } from "../hint"
|
import { Hint } from "../hint"
|
||||||
import { Label } from "../label"
|
import { Label } from "../label"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Radio Group](https://www.radix-ui.com/primitives/docs/components/radio-group) primitives.
|
||||||
|
*/
|
||||||
const Root = React.forwardRef<
|
const Root = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.Root>,
|
React.ElementRef<typeof Primitives.Root>,
|
||||||
React.ComponentPropsWithoutRef<typeof Primitives.Root>
|
React.ComponentPropsWithoutRef<typeof Primitives.Root>
|
||||||
@@ -19,7 +22,7 @@ const Root = React.forwardRef<
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
Root.displayName = "RadioGroup.Root"
|
Root.displayName = "RadioGroup"
|
||||||
|
|
||||||
const Indicator = React.forwardRef<
|
const Indicator = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.Indicator>,
|
React.ElementRef<typeof Primitives.Indicator>,
|
||||||
|
|||||||
@@ -28,17 +28,38 @@ const useSelectContext = () => {
|
|||||||
return context
|
return context
|
||||||
}
|
}
|
||||||
|
|
||||||
const Root = ({ children, size = "base", ...props }: SelectProps) => {
|
/**
|
||||||
|
* This component is based on [Radix UI Select](https://www.radix-ui.com/primitives/docs/components/select).
|
||||||
|
* It also accepts all props of the HTML `select` component.
|
||||||
|
*/
|
||||||
|
const Root = ({
|
||||||
|
children,
|
||||||
|
/**
|
||||||
|
* The select's size.
|
||||||
|
*/
|
||||||
|
size = "base",
|
||||||
|
...props
|
||||||
|
}: SelectProps) => {
|
||||||
return (
|
return (
|
||||||
<SelectContext.Provider value={React.useMemo(() => ({ size }), [size])}>
|
<SelectContext.Provider value={React.useMemo(() => ({ size }), [size])}>
|
||||||
<SelectPrimitive.Root {...props}>{children}</SelectPrimitive.Root>
|
<SelectPrimitive.Root {...props}>{children}</SelectPrimitive.Root>
|
||||||
</SelectContext.Provider>
|
</SelectContext.Provider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Root.displayName = "Select"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Groups multiple items together.
|
||||||
|
*/
|
||||||
const Group = SelectPrimitive.Group
|
const Group = SelectPrimitive.Group
|
||||||
|
Group.displayName = "Select.Group"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the selected value, or a placeholder if no value is selected.
|
||||||
|
* It's based on [Radix UI Select Value](https://www.radix-ui.com/primitives/docs/components/select#value).
|
||||||
|
*/
|
||||||
const Value = SelectPrimitive.Value
|
const Value = SelectPrimitive.Value
|
||||||
|
Value.displayName = "Select.Value"
|
||||||
|
|
||||||
const triggerVariants = cva({
|
const triggerVariants = cva({
|
||||||
base: clx(
|
base: clx(
|
||||||
@@ -59,6 +80,9 @@ const triggerVariants = cva({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The trigger that toggles the select.
|
||||||
|
*/
|
||||||
const Trigger = React.forwardRef<
|
const Trigger = React.forwardRef<
|
||||||
React.ElementRef<typeof SelectPrimitive.Trigger>,
|
React.ElementRef<typeof SelectPrimitive.Trigger>,
|
||||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger>
|
||||||
@@ -78,7 +102,7 @@ const Trigger = React.forwardRef<
|
|||||||
</SelectPrimitive.Trigger>
|
</SelectPrimitive.Trigger>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
Trigger.displayName = SelectPrimitive.Trigger.displayName
|
Trigger.displayName = "Select.Trigger"
|
||||||
|
|
||||||
const Content = React.forwardRef<
|
const Content = React.forwardRef<
|
||||||
React.ElementRef<typeof SelectPrimitive.Content>,
|
React.ElementRef<typeof SelectPrimitive.Content>,
|
||||||
@@ -127,8 +151,11 @@ const Content = React.forwardRef<
|
|||||||
</SelectPrimitive.Portal>
|
</SelectPrimitive.Portal>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
Content.displayName = SelectPrimitive.Content.displayName
|
Content.displayName = "Select.Content"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to label a group of items.
|
||||||
|
*/
|
||||||
const Label = React.forwardRef<
|
const Label = React.forwardRef<
|
||||||
React.ElementRef<typeof SelectPrimitive.Label>,
|
React.ElementRef<typeof SelectPrimitive.Label>,
|
||||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Label>
|
||||||
@@ -142,8 +169,12 @@ const Label = React.forwardRef<
|
|||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
Label.displayName = SelectPrimitive.Label.displayName
|
Label.displayName = "Select.Label"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An item in the select. It's based on [Radix UI Select Item](https://www.radix-ui.com/primitives/docs/components/select#item)
|
||||||
|
* and accepts its props.
|
||||||
|
*/
|
||||||
const Item = React.forwardRef<
|
const Item = React.forwardRef<
|
||||||
React.ElementRef<typeof SelectPrimitive.Item>,
|
React.ElementRef<typeof SelectPrimitive.Item>,
|
||||||
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
|
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item>
|
||||||
@@ -177,7 +208,7 @@ const Item = React.forwardRef<
|
|||||||
</SelectPrimitive.Item>
|
</SelectPrimitive.Item>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
Item.displayName = SelectPrimitive.Item.displayName
|
Item.displayName = "Select.Item"
|
||||||
|
|
||||||
const Separator = React.forwardRef<
|
const Separator = React.forwardRef<
|
||||||
React.ElementRef<typeof SelectPrimitive.Separator>,
|
React.ElementRef<typeof SelectPrimitive.Separator>,
|
||||||
@@ -189,7 +220,7 @@ const Separator = React.forwardRef<
|
|||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
Separator.displayName = SelectPrimitive.Separator.displayName
|
Separator.displayName = "Select.Separator"
|
||||||
|
|
||||||
const Select = Object.assign(Root, {
|
const Select = Object.assign(Root, {
|
||||||
Group,
|
Group,
|
||||||
|
|||||||
@@ -15,8 +15,19 @@ interface StatusBadgeProps
|
|||||||
color?: "green" | "red" | "blue" | "orange" | "grey" | "purple"
|
color?: "green" | "red" | "blue" | "orange" | "grey" | "purple"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the span element and supports all of its props
|
||||||
|
*/
|
||||||
const StatusBadge = React.forwardRef<HTMLSpanElement, StatusBadgeProps>(
|
const StatusBadge = React.forwardRef<HTMLSpanElement, StatusBadgeProps>(
|
||||||
({ children, className, color = "grey", ...props }, ref) => {
|
({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
/**
|
||||||
|
* The status's color.
|
||||||
|
*/
|
||||||
|
color = "grey",
|
||||||
|
...props
|
||||||
|
}: StatusBadgeProps, ref) => {
|
||||||
const StatusIndicator = {
|
const StatusIndicator = {
|
||||||
green: EllipseGreenSolid,
|
green: EllipseGreenSolid,
|
||||||
red: EllipseRedSolid,
|
red: EllipseRedSolid,
|
||||||
|
|||||||
@@ -40,10 +40,20 @@ interface SwitchProps
|
|||||||
>,
|
>,
|
||||||
VariantProps<typeof switchVariants> {}
|
VariantProps<typeof switchVariants> {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Switch](https://www.radix-ui.com/primitives/docs/components/switch) primitive.
|
||||||
|
*/
|
||||||
const Switch = React.forwardRef<
|
const Switch = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.Root>,
|
React.ElementRef<typeof Primitives.Root>,
|
||||||
SwitchProps
|
SwitchProps
|
||||||
>(({ className, size = "base", ...props }, ref) => (
|
>(({
|
||||||
|
className,
|
||||||
|
/**
|
||||||
|
* The switch's size.
|
||||||
|
*/
|
||||||
|
size = "base",
|
||||||
|
...props
|
||||||
|
}: SwitchProps, ref) => (
|
||||||
<Primitives.Root
|
<Primitives.Root
|
||||||
className={clx(switchVariants({ size }), className)}
|
className={clx(switchVariants({ size }), className)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
@@ -4,6 +4,18 @@ import * as React from "react"
|
|||||||
import { Button } from "@/components/button"
|
import { Button } from "@/components/button"
|
||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the table element and its various children:
|
||||||
|
*
|
||||||
|
* - `Table`: `table`
|
||||||
|
* - `Table.Header`: `thead`
|
||||||
|
* - `Table.Row`: `tr`
|
||||||
|
* - `Table.HeaderCell`: `th`
|
||||||
|
* - `Table.Body`: `tbody`
|
||||||
|
* - `Table.Cell`: `td`
|
||||||
|
*
|
||||||
|
* Each component supports the props or attributes of its equivalent HTML element.
|
||||||
|
*/
|
||||||
const Root = React.forwardRef<
|
const Root = React.forwardRef<
|
||||||
HTMLTableElement,
|
HTMLTableElement,
|
||||||
React.HTMLAttributes<HTMLTableElement>
|
React.HTMLAttributes<HTMLTableElement>
|
||||||
@@ -87,20 +99,49 @@ interface TablePaginationProps extends React.HTMLAttributes<HTMLDivElement> {
|
|||||||
nextPage: () => void
|
nextPage: () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `div` element and supports all of its props
|
||||||
|
*/
|
||||||
const Pagination = React.forwardRef<HTMLDivElement, TablePaginationProps>(
|
const Pagination = React.forwardRef<HTMLDivElement, TablePaginationProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
className,
|
className,
|
||||||
|
/**
|
||||||
|
* The total number of items.
|
||||||
|
*/
|
||||||
count,
|
count,
|
||||||
|
/**
|
||||||
|
* The number of items per page.
|
||||||
|
*/
|
||||||
pageSize,
|
pageSize,
|
||||||
|
/**
|
||||||
|
* The total number of pages.
|
||||||
|
*/
|
||||||
pageCount,
|
pageCount,
|
||||||
|
/**
|
||||||
|
* The current page index.
|
||||||
|
*/
|
||||||
pageIndex,
|
pageIndex,
|
||||||
|
/**
|
||||||
|
* Whether there's a previous page that can be navigated to.
|
||||||
|
*/
|
||||||
canPreviousPage,
|
canPreviousPage,
|
||||||
|
/**
|
||||||
|
* Whether there's a next page that can be navigated to.
|
||||||
|
*/
|
||||||
canNextPage,
|
canNextPage,
|
||||||
|
/**
|
||||||
|
* A function that handles navigating to the next page.
|
||||||
|
* This function should handle retrieving data for the next page.
|
||||||
|
*/
|
||||||
nextPage,
|
nextPage,
|
||||||
|
/**
|
||||||
|
* A function that handles navigating to the previous page.
|
||||||
|
* This function should handle retrieving data for the previous page.
|
||||||
|
*/
|
||||||
previousPage,
|
previousPage,
|
||||||
...props
|
...props
|
||||||
},
|
}: TablePaginationProps,
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const { from, to } = React.useMemo(() => {
|
const { from, to } = React.useMemo(() => {
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ import * as React from "react"
|
|||||||
|
|
||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Tabs](https://radix-ui.com/primitives/docs/components/tabs) primitves
|
||||||
|
*/
|
||||||
const TabsRoot = (
|
const TabsRoot = (
|
||||||
props: React.ComponentPropsWithoutRef<typeof TabsPrimitives.Root>
|
props: React.ComponentPropsWithoutRef<typeof TabsPrimitives.Root>
|
||||||
) => {
|
) => {
|
||||||
|
|||||||
@@ -93,19 +93,41 @@ interface TextProps
|
|||||||
as?: "p" | "span" | "div"
|
as?: "p" | "span" | "div"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `p` element and supports all of its props
|
||||||
|
*/
|
||||||
const Text = React.forwardRef<HTMLParagraphElement, TextProps>(
|
const Text = React.forwardRef<HTMLParagraphElement, TextProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
className,
|
className,
|
||||||
|
/**
|
||||||
|
* Whether to remove the wrapper `button` element and use the
|
||||||
|
* passed child element instead.
|
||||||
|
*/
|
||||||
asChild = false,
|
asChild = false,
|
||||||
|
/**
|
||||||
|
* The wrapper element to use when `asChild` is disabled.
|
||||||
|
*/
|
||||||
as = "p",
|
as = "p",
|
||||||
|
/**
|
||||||
|
* The text's size.
|
||||||
|
*/
|
||||||
size = "base",
|
size = "base",
|
||||||
|
/**
|
||||||
|
* The text's font weight.
|
||||||
|
*/
|
||||||
weight = "regular",
|
weight = "regular",
|
||||||
|
/**
|
||||||
|
* The text's font family.
|
||||||
|
*/
|
||||||
family = "sans",
|
family = "sans",
|
||||||
|
/**
|
||||||
|
* The text's line height.
|
||||||
|
*/
|
||||||
leading = "normal",
|
leading = "normal",
|
||||||
children,
|
children,
|
||||||
...props
|
...props
|
||||||
},
|
}: TextProps,
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const Component = asChild ? Slot : as
|
const Component = asChild ? Slot : as
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ import * as React from "react"
|
|||||||
import { clx } from "@/utils/clx"
|
import { clx } from "@/utils/clx"
|
||||||
import { inputBaseStyles } from "../input"
|
import { inputBaseStyles } from "../input"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `textarea` element and supports all of its props
|
||||||
|
*/
|
||||||
const Textarea = React.forwardRef<
|
const Textarea = React.forwardRef<
|
||||||
HTMLTextAreaElement,
|
HTMLTextAreaElement,
|
||||||
React.ComponentPropsWithoutRef<"textarea">
|
React.ComponentPropsWithoutRef<"textarea">
|
||||||
|
|||||||
@@ -71,8 +71,18 @@ type TimeInputProps = Omit<
|
|||||||
"label" | "shouldForceLeadingZeros" | "description" | "errorMessage"
|
"label" | "shouldForceLeadingZeros" | "description" | "errorMessage"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the `div` element and supports all of its props.
|
||||||
|
*/
|
||||||
const TimeInput = React.forwardRef<HTMLDivElement, TimeInputProps>(
|
const TimeInput = React.forwardRef<HTMLDivElement, TimeInputProps>(
|
||||||
({ hourCycle, ...props }: TimeInputProps, ref) => {
|
({
|
||||||
|
/**
|
||||||
|
* The time's format. If no value is specified, the format is
|
||||||
|
* set based on the user's locale.
|
||||||
|
*/
|
||||||
|
hourCycle,
|
||||||
|
...props
|
||||||
|
}: TimeInputProps, ref) => {
|
||||||
const innerRef = React.useRef<HTMLDivElement>(null)
|
const innerRef = React.useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
React.useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(
|
React.useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const ToastViewport = React.forwardRef<
|
|||||||
{...props}
|
{...props}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
ToastViewport.displayName = "ToastViewport"
|
ToastViewport.displayName = "Toast.Viewport"
|
||||||
|
|
||||||
interface ActionProps {
|
interface ActionProps {
|
||||||
label: string
|
label: string
|
||||||
@@ -45,6 +45,11 @@ interface ToastProps
|
|||||||
disableDismiss?: boolean
|
disableDismiss?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Toast](https://www.radix-ui.com/primitives/docs/components/toast) primitives.
|
||||||
|
*
|
||||||
|
* @excludeExternal
|
||||||
|
*/
|
||||||
const Toast = React.forwardRef<
|
const Toast = React.forwardRef<
|
||||||
React.ElementRef<typeof Primitives.Root>,
|
React.ElementRef<typeof Primitives.Root>,
|
||||||
ToastProps
|
ToastProps
|
||||||
@@ -52,13 +57,28 @@ const Toast = React.forwardRef<
|
|||||||
(
|
(
|
||||||
{
|
{
|
||||||
className,
|
className,
|
||||||
|
/**
|
||||||
|
* The toast's style.
|
||||||
|
*/
|
||||||
variant,
|
variant,
|
||||||
|
/**
|
||||||
|
* The toast's title.
|
||||||
|
*/
|
||||||
title,
|
title,
|
||||||
|
/**
|
||||||
|
* The toast's content.
|
||||||
|
*/
|
||||||
description,
|
description,
|
||||||
|
/**
|
||||||
|
* The actions to show in the toast as buttons.
|
||||||
|
*/
|
||||||
action,
|
action,
|
||||||
|
/**
|
||||||
|
* Whether to hide the Close button.
|
||||||
|
*/
|
||||||
disableDismiss = false,
|
disableDismiss = false,
|
||||||
...props
|
...props
|
||||||
},
|
}: ToastProps,
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
let Icon = undefined
|
let Icon = undefined
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ interface TooltipProps
|
|||||||
maxWidth?: number
|
maxWidth?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This component is based on the [Radix UI Tooltip](https://www.radix-ui.com/primitives/docs/components/tooltip) primitive.
|
||||||
|
*
|
||||||
|
* @excludeExternal
|
||||||
|
*/
|
||||||
const Tooltip = ({
|
const Tooltip = ({
|
||||||
children,
|
children,
|
||||||
content,
|
content,
|
||||||
@@ -24,6 +29,9 @@ const Tooltip = ({
|
|||||||
defaultOpen,
|
defaultOpen,
|
||||||
onOpenChange,
|
onOpenChange,
|
||||||
delayDuration,
|
delayDuration,
|
||||||
|
/**
|
||||||
|
* The maximum width of the tooltip.
|
||||||
|
*/
|
||||||
maxWidth = 220,
|
maxWidth = 220,
|
||||||
className,
|
className,
|
||||||
side,
|
side,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { Input } from "@/components/input"
|
|||||||
import { Label } from "@/components/label"
|
import { Label } from "@/components/label"
|
||||||
import { Prompt } from "@/components/prompt"
|
import { Prompt } from "@/components/prompt"
|
||||||
|
|
||||||
export type RenderPromptProps = {
|
export interface RenderPromptProps {
|
||||||
open: boolean
|
open: boolean
|
||||||
title: string
|
title: string
|
||||||
description: string
|
description: string
|
||||||
@@ -18,13 +18,37 @@ export type RenderPromptProps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const RenderPrompt = ({
|
export const RenderPrompt = ({
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
open,
|
open,
|
||||||
|
/**
|
||||||
|
* The prompt's title.
|
||||||
|
*/
|
||||||
title,
|
title,
|
||||||
|
/**
|
||||||
|
* The prompt's description.
|
||||||
|
*/
|
||||||
description,
|
description,
|
||||||
|
/**
|
||||||
|
* The text the user has to input in order to confirm the action.
|
||||||
|
*/
|
||||||
verificationText,
|
verificationText,
|
||||||
|
/**
|
||||||
|
* The label for the Cancel button.
|
||||||
|
*/
|
||||||
cancelText = "Cancel",
|
cancelText = "Cancel",
|
||||||
|
/**
|
||||||
|
* Label for the Confirm button.
|
||||||
|
*/
|
||||||
confirmText = "Confirm",
|
confirmText = "Confirm",
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
onConfirm,
|
onConfirm,
|
||||||
|
/**
|
||||||
|
* @ignore
|
||||||
|
*/
|
||||||
onCancel,
|
onCancel,
|
||||||
}: RenderPromptProps) => {
|
}: RenderPromptProps) => {
|
||||||
const [userInput, setUserInput] = React.useState("")
|
const [userInput, setUserInput] = React.useState("")
|
||||||
@@ -108,3 +132,4 @@ export const RenderPrompt = ({
|
|||||||
</Prompt>
|
</Prompt>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
RenderPrompt.displayName = "RenderPrompt"
|
||||||
@@ -1,6 +1,12 @@
|
|||||||
export type ProgressStatus = "not-started" | "in-progress" | "completed"
|
export type ProgressStatus = "not-started" | "in-progress" | "completed"
|
||||||
|
|
||||||
export type DateRange = {
|
export type DateRange = {
|
||||||
|
/**
|
||||||
|
* The range's start date.
|
||||||
|
*/
|
||||||
from: Date | undefined
|
from: Date | undefined
|
||||||
|
/**
|
||||||
|
* The range's end date.
|
||||||
|
*/
|
||||||
to?: Date | undefined
|
to?: Date | undefined
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import getSectionId from "@/utils/get-section-id"
|
import getSectionId from "@/utils/get-section-id"
|
||||||
import fetcher from "@/utils/swr-fetcher"
|
|
||||||
import type { OpenAPIV3 } from "openapi-types"
|
import type { OpenAPIV3 } from "openapi-types"
|
||||||
import useSWR from "swr"
|
import useSWR from "swr"
|
||||||
import type { Operation, PathsObject } from "@/types/openapi"
|
import type { Operation, PathsObject } from "@/types/openapi"
|
||||||
import { SidebarItemSections, useSidebar, type SidebarItemType } from "docs-ui"
|
import {
|
||||||
|
SidebarItemSections,
|
||||||
|
useSidebar,
|
||||||
|
type SidebarItemType,
|
||||||
|
swrFetcher,
|
||||||
|
} from "docs-ui"
|
||||||
import { Fragment, useEffect, useMemo } from "react"
|
import { Fragment, useEffect, useMemo } from "react"
|
||||||
import dynamic from "next/dynamic"
|
import dynamic from "next/dynamic"
|
||||||
import type { TagOperationProps } from "../Operation"
|
import type { TagOperationProps } from "../Operation"
|
||||||
@@ -45,7 +49,7 @@ const TagPaths = ({ tag, className }: TagPathsProps) => {
|
|||||||
!Object.keys(paths).length
|
!Object.keys(paths).length
|
||||||
? getLinkWithBasePath(`/tag?tagName=${tagSlugName}&area=${area}`)
|
? getLinkWithBasePath(`/tag?tagName=${tagSlugName}&area=${area}`)
|
||||||
: null,
|
: null,
|
||||||
fetcher,
|
swrFetcher,
|
||||||
{
|
{
|
||||||
errorRetryInterval: 2000,
|
errorRetryInterval: 2000,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,12 @@
|
|||||||
import type { OpenAPIV3 } from "openapi-types"
|
import type { OpenAPIV3 } from "openapi-types"
|
||||||
import { useEffect, useState } from "react"
|
import { useEffect, useState } from "react"
|
||||||
import useSWR from "swr"
|
import useSWR from "swr"
|
||||||
import fetcher from "@/utils/swr-fetcher"
|
|
||||||
import { useBaseSpecs } from "@/providers/base-specs"
|
import { useBaseSpecs } from "@/providers/base-specs"
|
||||||
import dynamic from "next/dynamic"
|
import dynamic from "next/dynamic"
|
||||||
import type { TagSectionProps } from "./Section"
|
import type { TagSectionProps } from "./Section"
|
||||||
import { useArea } from "@/providers/area"
|
import { useArea } from "@/providers/area"
|
||||||
import getLinkWithBasePath from "@/utils/get-link-with-base-path"
|
import getLinkWithBasePath from "@/utils/get-link-with-base-path"
|
||||||
import { SidebarItemSections, useSidebar } from "docs-ui"
|
import { SidebarItemSections, swrFetcher, useSidebar } from "docs-ui"
|
||||||
import getSectionId from "@/utils/get-section-id"
|
import getSectionId from "@/utils/get-section-id"
|
||||||
import { ExpandedDocument } from "@/types/openapi"
|
import { ExpandedDocument } from "@/types/openapi"
|
||||||
import getTagChildSidebarItems from "@/utils/get-tag-child-sidebar-items"
|
import getTagChildSidebarItems from "@/utils/get-tag-child-sidebar-items"
|
||||||
@@ -38,7 +37,7 @@ const Tags = () => {
|
|||||||
loadData && !baseSpecs
|
loadData && !baseSpecs
|
||||||
? getLinkWithBasePath(`/base-specs?area=${area}&expand=${expand}`)
|
? getLinkWithBasePath(`/base-specs?area=${area}&expand=${expand}`)
|
||||||
: null,
|
: null,
|
||||||
fetcher,
|
swrFetcher,
|
||||||
{
|
{
|
||||||
errorRetryInterval: 2000,
|
errorRetryInterval: 2000,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^8.49.0",
|
"eslint": "^8.49.0",
|
||||||
|
"react-docgen": "^7.0.1",
|
||||||
"ts-node": "^10.9.1"
|
"ts-node": "^10.9.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
import { Spinner } from "@medusajs/icons"
|
|
||||||
import { Container } from "@medusajs/ui"
|
|
||||||
import * as React from "react"
|
|
||||||
|
|
||||||
import { PropRegistry } from "@/registries/prop-registry"
|
|
||||||
import { Feedback } from "./feedback"
|
|
||||||
|
|
||||||
type ComponentPropsProps = {
|
|
||||||
component: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const ComponentProps = ({ component }: ComponentPropsProps) => {
|
|
||||||
const Props = React.useMemo(() => {
|
|
||||||
const Table = PropRegistry[component]?.table
|
|
||||||
|
|
||||||
if (!Table) {
|
|
||||||
return (
|
|
||||||
<div className="flex min-h-[200px] w-full items-center justify-center">
|
|
||||||
<p className="txt-compact-small">
|
|
||||||
No API reference found for{" "}
|
|
||||||
<span className="txt-compact-small-plus">{component}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return <Table />
|
|
||||||
}, [component])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Container className="mb-6 mt-8 overflow-hidden p-0">
|
|
||||||
<React.Suspense
|
|
||||||
fallback={
|
|
||||||
<div className="text-medusa-fg-muted flex flex-1 items-center justify-center">
|
|
||||||
<Spinner className="animate-spin" />
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{Props}
|
|
||||||
</React.Suspense>
|
|
||||||
</Container>
|
|
||||||
<Feedback title={`props of ${component}`} />
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export { ComponentProps }
|
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
import { Documentation } from "react-docgen"
|
||||||
|
import { Suspense } from "react"
|
||||||
|
import { Spinner } from "@medusajs/icons"
|
||||||
|
import { PropTable } from "./props-table"
|
||||||
|
import { Container, clx } from "@medusajs/ui"
|
||||||
|
import { Feedback } from "./feedback"
|
||||||
|
import { MarkdownContent } from "docs-ui"
|
||||||
|
import { components } from "./mdx-components"
|
||||||
|
|
||||||
|
type ComponentReferenceProps = {
|
||||||
|
mainComponent: string
|
||||||
|
componentsToShow?: string[]
|
||||||
|
specsSrc?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const ComponentReference = ({
|
||||||
|
mainComponent,
|
||||||
|
componentsToShow = [mainComponent],
|
||||||
|
specsSrc,
|
||||||
|
}: ComponentReferenceProps) => {
|
||||||
|
if (!specsSrc) {
|
||||||
|
return <></>
|
||||||
|
}
|
||||||
|
|
||||||
|
const specs = JSON.parse(specsSrc) as Documentation[]
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{componentsToShow.map((component, index) => {
|
||||||
|
const componentSpec = specs?.find(
|
||||||
|
(spec) => spec.displayName === component
|
||||||
|
)
|
||||||
|
const hasProps =
|
||||||
|
componentSpec?.props && Object.keys(componentSpec.props).length > 0
|
||||||
|
return (
|
||||||
|
<Suspense
|
||||||
|
fallback={
|
||||||
|
<div className="text-medusa-fg-muted flex flex-1 items-center justify-center">
|
||||||
|
<Spinner className="animate-spin" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
key={index}
|
||||||
|
>
|
||||||
|
{componentSpec && (
|
||||||
|
<>
|
||||||
|
{componentsToShow.length > 1 && (
|
||||||
|
<h3 className={clx("h3-docs mb-2 mt-10 text-medusa-fg-base")}>
|
||||||
|
{componentSpec.displayName || component}
|
||||||
|
</h3>
|
||||||
|
)}
|
||||||
|
{componentSpec.description && (
|
||||||
|
<MarkdownContent components={components}>
|
||||||
|
{componentSpec.description}
|
||||||
|
</MarkdownContent>
|
||||||
|
)}
|
||||||
|
{hasProps && (
|
||||||
|
<>
|
||||||
|
<Container className="mb-6 mt-8 overflow-hidden p-0">
|
||||||
|
<Suspense
|
||||||
|
fallback={
|
||||||
|
<div className="text-medusa-fg-muted flex flex-1 items-center justify-center">
|
||||||
|
<Spinner className="animate-spin" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<PropTable props={componentSpec.props!} />
|
||||||
|
</Suspense>
|
||||||
|
</Container>
|
||||||
|
<Feedback title={`props of ${component}`} />
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Suspense>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { ComponentReference }
|
||||||
@@ -3,6 +3,7 @@ import { Table, Tooltip } from "@medusajs/ui"
|
|||||||
|
|
||||||
import { HookData, HookDataMap } from "@/types/hooks"
|
import { HookData, HookDataMap } from "@/types/hooks"
|
||||||
import { EnumType, FunctionType, ObjectType } from "@/types/props"
|
import { EnumType, FunctionType, ObjectType } from "@/types/props"
|
||||||
|
import { InlineCode } from "docs-ui"
|
||||||
|
|
||||||
const HookTable = ({ props }: { props: HookDataMap }) => {
|
const HookTable = ({ props }: { props: HookDataMap }) => {
|
||||||
return (
|
return (
|
||||||
@@ -47,7 +48,9 @@ const Row = ({ value, type, description }: HookData) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Table.Row className="code-body">
|
<Table.Row className="code-body">
|
||||||
<Table.Cell>{value}</Table.Cell>
|
<Table.Cell>
|
||||||
|
<InlineCode>{value}</InlineCode>
|
||||||
|
</Table.Cell>
|
||||||
<Table.Cell>
|
<Table.Cell>
|
||||||
{!isComplexType && type.toString()}
|
{!isComplexType && type.toString()}
|
||||||
{isEnum(type) && (
|
{isEnum(type) && (
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ import * as React from "react"
|
|||||||
|
|
||||||
import { Colors } from "@/components/colors"
|
import { Colors } from "@/components/colors"
|
||||||
import { ComponentExample } from "@/components/component-example"
|
import { ComponentExample } from "@/components/component-example"
|
||||||
import { ComponentProps } from "@/components/component-props"
|
|
||||||
import { HookValues } from "@/components/hook-values"
|
import { HookValues } from "@/components/hook-values"
|
||||||
import { IconSearch } from "@/components/icon-search"
|
import { IconSearch } from "@/components/icon-search"
|
||||||
import { PackageInstall } from "@/components/package-install"
|
import { PackageInstall } from "@/components/package-install"
|
||||||
import { Feedback } from "@/components/feedback"
|
import { Feedback } from "@/components/feedback"
|
||||||
import { FigmaIcon } from "@/components/figma-icon"
|
import { FigmaIcon } from "@/components/figma-icon"
|
||||||
|
import { ComponentReference } from "@/components/component-reference"
|
||||||
import clsx from "clsx"
|
import clsx from "clsx"
|
||||||
import { NextLink, Card, BorderedIcon, CodeMdx, CodeBlock } from "docs-ui"
|
import { NextLink, Card, BorderedIcon, CodeMdx, CodeBlock } from "docs-ui"
|
||||||
|
|
||||||
@@ -120,7 +120,6 @@ const components = {
|
|||||||
return <hr className={clx("mb-4", className)} {...props} />
|
return <hr className={clx("mb-4", className)} {...props} />
|
||||||
},
|
},
|
||||||
HookValues,
|
HookValues,
|
||||||
ComponentProps,
|
|
||||||
CodeBlock,
|
CodeBlock,
|
||||||
ComponentExample,
|
ComponentExample,
|
||||||
PackageInstall,
|
PackageInstall,
|
||||||
@@ -130,6 +129,7 @@ const components = {
|
|||||||
Card,
|
Card,
|
||||||
BorderedIcon,
|
BorderedIcon,
|
||||||
FigmaIcon,
|
FigmaIcon,
|
||||||
|
ComponentReference,
|
||||||
}
|
}
|
||||||
|
|
||||||
const Mdx = ({ code }: MdxProps) => {
|
const Mdx = ({ code }: MdxProps) => {
|
||||||
@@ -142,4 +142,4 @@ const Mdx = ({ code }: MdxProps) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Mdx }
|
export { Mdx, components }
|
||||||
@@ -3,13 +3,9 @@
|
|||||||
import { InformationCircleSolid } from "@medusajs/icons"
|
import { InformationCircleSolid } from "@medusajs/icons"
|
||||||
import { Table, Tooltip } from "@medusajs/ui"
|
import { Table, Tooltip } from "@medusajs/ui"
|
||||||
|
|
||||||
import {
|
import { PropData, PropDataMap, PropSpecType } from "@/types/props"
|
||||||
EnumType,
|
import { useCallback, useMemo } from "react"
|
||||||
FunctionType,
|
import { InlineCode, MarkdownContent } from "docs-ui"
|
||||||
ObjectType,
|
|
||||||
PropData,
|
|
||||||
PropDataMap,
|
|
||||||
} from "@/types/props"
|
|
||||||
|
|
||||||
type PropTableProps = {
|
type PropTableProps = {
|
||||||
props: PropDataMap
|
props: PropDataMap
|
||||||
@@ -26,101 +22,162 @@ const PropTable = ({ props }: PropTableProps) => {
|
|||||||
</Table.Row>
|
</Table.Row>
|
||||||
</Table.Header>
|
</Table.Header>
|
||||||
<Table.Body className="border-b-0 [&_tr:last-child]:border-b-0">
|
<Table.Body className="border-b-0 [&_tr:last-child]:border-b-0">
|
||||||
{/* eslint-disable-next-line react/prop-types */}
|
{Object.entries(props).map(([propName, propData]) => (
|
||||||
{props.map((propData, index) => (
|
<Row key={propName} propName={propName} propData={propData} />
|
||||||
<Row key={index} {...propData} />
|
|
||||||
))}
|
))}
|
||||||
</Table.Body>
|
</Table.Body>
|
||||||
</Table>
|
</Table>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const Row = ({ prop, type, defaultValue }: PropData) => {
|
type RowProps = {
|
||||||
const isEnum = (t: unknown): t is EnumType => {
|
propName: string
|
||||||
return (t as EnumType).type !== undefined && (t as EnumType).type === "enum"
|
propData: PropData
|
||||||
}
|
}
|
||||||
|
|
||||||
const isObject = (t: unknown): t is ObjectType => {
|
type TypeNode = {
|
||||||
return (
|
text: string
|
||||||
(t as ObjectType).type !== undefined &&
|
tooltipContent?: string
|
||||||
(t as ObjectType).type === "object"
|
canBeCopied?: boolean
|
||||||
)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const isFunction = (t: unknown): t is FunctionType => {
|
const Row = ({
|
||||||
return (
|
propName,
|
||||||
(t as FunctionType).type !== undefined &&
|
propData: { tsType: tsType, defaultValue, description },
|
||||||
(t as FunctionType).type === "function"
|
}: RowProps) => {
|
||||||
)
|
const normalizeRaw = (str: string): string => {
|
||||||
|
return str.replace("\\|", "|")
|
||||||
}
|
}
|
||||||
|
const getTypeRaw = useCallback((type: PropSpecType): string => {
|
||||||
const defaultValueRenderer = (
|
let raw = "raw" in type ? type.raw || type.name : type.name
|
||||||
v: string | number | boolean | null | undefined
|
if ("type" in type) {
|
||||||
) => {
|
if (type.type === "object") {
|
||||||
if (v === undefined) {
|
raw = `{\n ${type.signature.properties
|
||||||
return "-"
|
.map((property) => `${property.key}: ${property.value.name}`)
|
||||||
|
.join("\n ")}\n}`
|
||||||
|
} else {
|
||||||
|
raw = type.raw
|
||||||
|
}
|
||||||
|
} else if (type.name === "Array" && "elements" in type) {
|
||||||
|
raw = type.elements.map((element) => getTypeRaw(element)).join(" | ")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof v === "boolean") {
|
return normalizeRaw(raw)
|
||||||
return v ? "true" : "false"
|
}, [])
|
||||||
|
const getTypeText = useCallback((type: PropSpecType): string => {
|
||||||
|
if (type?.name === "signature" && "type" in type) {
|
||||||
|
return type.type
|
||||||
|
} else if (type?.name === "Array" && type.raw) {
|
||||||
|
return normalizeRaw(type.raw) || "array"
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v === null) {
|
return type.name || ""
|
||||||
return "null"
|
}, [])
|
||||||
|
const getTypeTooltipContent = useCallback(
|
||||||
|
(type: PropSpecType): string | undefined => {
|
||||||
|
if (type?.name === "signature" && "type" in type) {
|
||||||
|
return getTypeRaw(type)
|
||||||
|
} else if (type?.name === "Array" && type.raw) {
|
||||||
|
return getTypeRaw(type)
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
},
|
||||||
|
[getTypeRaw]
|
||||||
|
)
|
||||||
|
|
||||||
|
const typeNodes = useMemo((): TypeNode[] => {
|
||||||
|
const typeNodes: TypeNode[] = []
|
||||||
|
if (tsType?.name === "union" && "elements" in tsType) {
|
||||||
|
tsType.elements.forEach((element) => {
|
||||||
|
if (
|
||||||
|
("elements" in element && element.elements.length) ||
|
||||||
|
"signature" in element
|
||||||
|
) {
|
||||||
|
const elementTypeText = getTypeText(element)
|
||||||
|
const elementTooltipContent = getTypeTooltipContent(element)
|
||||||
|
typeNodes.push({
|
||||||
|
text: elementTypeText,
|
||||||
|
tooltipContent:
|
||||||
|
elementTypeText !== elementTooltipContent
|
||||||
|
? elementTooltipContent
|
||||||
|
: undefined,
|
||||||
|
})
|
||||||
|
} else if ("value" in element) {
|
||||||
|
typeNodes.push({
|
||||||
|
text: element.value,
|
||||||
|
canBeCopied: true,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
typeNodes.push({
|
||||||
|
text: element.name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (tsType) {
|
||||||
|
typeNodes.push({
|
||||||
|
text: getTypeText(tsType),
|
||||||
|
tooltipContent: getTypeTooltipContent(tsType),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof v === "string") {
|
return typeNodes
|
||||||
return `"${v}"`
|
}, [tsType, getTypeText, getTypeTooltipContent])
|
||||||
}
|
|
||||||
|
|
||||||
return v
|
const defaultVal: string | undefined = defaultValue?.value as string
|
||||||
}
|
|
||||||
|
|
||||||
const isComplexType = isEnum(type) || isObject(type) || isFunction(type)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Table.Row className="code-body">
|
<Table.Row>
|
||||||
<Table.Cell>{prop}</Table.Cell>
|
|
||||||
<Table.Cell>
|
<Table.Cell>
|
||||||
{!isComplexType && type.toString()}
|
<div className="flex items-center gap-x-1">
|
||||||
{isEnum(type) && (
|
<InlineCode>{propName}</InlineCode>
|
||||||
<Tooltip
|
{description && (
|
||||||
content={type.values.map((v) => `"${v}"`).join(" | ")}
|
<Tooltip
|
||||||
className="font-mono"
|
content={
|
||||||
>
|
<MarkdownContent
|
||||||
<div className="flex items-center gap-x-1">
|
allowedElements={["a", "code"]}
|
||||||
<span>enum</span>
|
unwrapDisallowed={true}
|
||||||
|
>
|
||||||
|
{description}
|
||||||
|
</MarkdownContent>
|
||||||
|
}
|
||||||
|
>
|
||||||
<InformationCircleSolid className="text-medusa-fg-subtle" />
|
<InformationCircleSolid className="text-medusa-fg-subtle" />
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Table.Cell>
|
||||||
|
<Table.Cell>
|
||||||
|
<div className="flex items-center flex-wrap gap-1 py-1">
|
||||||
|
{typeNodes.map((typeNode, index) => (
|
||||||
|
<div key={index} className="flex items-center gap-x-1">
|
||||||
|
{index > 0 && <span>|</span>}
|
||||||
|
{typeNode.tooltipContent && (
|
||||||
|
<Tooltip
|
||||||
|
content={<pre>{typeNode.tooltipContent}</pre>}
|
||||||
|
className="font-mono !max-w-none"
|
||||||
|
>
|
||||||
|
<div className="flex items-center gap-x-1">
|
||||||
|
<code>{typeNode.text}</code>
|
||||||
|
<InformationCircleSolid className="text-medusa-fg-subtle" />
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
|
)}
|
||||||
|
{!typeNode.tooltipContent && (
|
||||||
|
<>
|
||||||
|
{typeNode.canBeCopied && (
|
||||||
|
<InlineCode>{typeNode.text}</InlineCode>
|
||||||
|
)}
|
||||||
|
{!typeNode.canBeCopied && <code>{typeNode.text}</code>}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Tooltip>
|
))}
|
||||||
)}
|
</div>
|
||||||
{isObject(type) && (
|
|
||||||
<Tooltip
|
|
||||||
content={<pre>{type.shape}</pre>}
|
|
||||||
className="font-mono"
|
|
||||||
maxWidth={500}
|
|
||||||
>
|
|
||||||
<div className="flex items-center gap-x-1">
|
|
||||||
<span>{type.name}</span>
|
|
||||||
<InformationCircleSolid className="text-medusa-fg-subtle" />
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
{isFunction(type) && (
|
|
||||||
<Tooltip
|
|
||||||
content={<pre>{type.signature}</pre>}
|
|
||||||
className="font-mono"
|
|
||||||
maxWidth={500}
|
|
||||||
>
|
|
||||||
<div className="flex items-center gap-x-1">
|
|
||||||
<span>function</span>
|
|
||||||
<InformationCircleSolid className="text-medusa-fg-subtle" />
|
|
||||||
</div>
|
|
||||||
</Tooltip>
|
|
||||||
)}
|
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
<Table.Cell className="text-right">
|
<Table.Cell className="text-right">
|
||||||
{defaultValueRenderer(defaultValue)}
|
{defaultVal && <InlineCode>{defaultVal}</InlineCode>}
|
||||||
|
{!defaultVal && " - "}
|
||||||
</Table.Cell>
|
</Table.Cell>
|
||||||
</Table.Row>
|
</Table.Row>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import { clx } from "@medusajs/ui"
|
|
||||||
import * as Primitives from "@radix-ui/react-scroll-area"
|
|
||||||
import clsx from "clsx"
|
|
||||||
import { Key } from "@/types/props"
|
|
||||||
|
|
||||||
type ScrollbarProps = React.ComponentProps<typeof Primitives.Scrollbar>
|
|
||||||
|
|
||||||
const Scrollbar = ({ key, ...props }: ScrollbarProps) => {
|
|
||||||
return (
|
|
||||||
<Primitives.Scrollbar
|
|
||||||
className={clsx(
|
|
||||||
"bg-medusa-bg-baseflex touch-none select-none p-0.5 transition-colors ease-out",
|
|
||||||
"data-[orientation=horizontal]:h-2.5 data-[orientation=vertical]:w-2.5 data-[orientation=horizontal]:flex-col"
|
|
||||||
)}
|
|
||||||
key={key as Key}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ThumbProps = React.ComponentProps<typeof Primitives.Thumb>
|
|
||||||
|
|
||||||
const Thumb = ({ className, key, ...props }: ThumbProps) => {
|
|
||||||
return (
|
|
||||||
<Primitives.Thumb
|
|
||||||
className={clx(
|
|
||||||
"bg-medusa-bg-component relative flex-1 rounded-[10px] before:absolute before:left-1/2 before:top-1/2 before:h-full",
|
|
||||||
"before:min-h-[44px] before:w-full before:min-w-[44px] before:-translate-x-1/2 before:-translate-y-1/2 before:content-['']",
|
|
||||||
className
|
|
||||||
)}
|
|
||||||
key={key as Key}
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
type ScrollAreaProps = React.ComponentProps<typeof Primitives.Root>
|
|
||||||
|
|
||||||
const ScrollArea = ({ children, className }: ScrollAreaProps) => {
|
|
||||||
return (
|
|
||||||
<Primitives.Root
|
|
||||||
className={clx("h-full w-full overflow-hidden", className)}
|
|
||||||
>
|
|
||||||
<Primitives.Viewport className="h-full w-full">
|
|
||||||
{children}
|
|
||||||
</Primitives.Viewport>
|
|
||||||
<Scrollbar orientation="vertical">
|
|
||||||
<Thumb />
|
|
||||||
</Scrollbar>
|
|
||||||
<Scrollbar orientation="horizontal">
|
|
||||||
<Thumb />
|
|
||||||
</Scrollbar>
|
|
||||||
<Primitives.Corner />
|
|
||||||
</Primitives.Root>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export { ScrollArea }
|
|
||||||
@@ -25,6 +25,4 @@ import { Avatar } from "@medusajs/ui"
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This component is based on the [Radix UI Avatar](https://www.radix-ui.com/primitives/docs/components/avatar) primitive.
|
<ComponentReference mainComponent="Avatar" />
|
||||||
|
|
||||||
<ComponentProps component="avatar" />
|
|
||||||
@@ -22,9 +22,7 @@ import { Badge } from "@medusajs/ui"
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This component is based on the `div` element and supports all props of this element.
|
<ComponentReference mainComponent="Badge" />
|
||||||
|
|
||||||
<ComponentProps component="badge" />
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import { Button } from "@medusajs/ui"
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This component is based on the `button` element and supports all props of this element.
|
<ComponentReference mainComponent="Button" />
|
||||||
|
|
||||||
<ComponentProps component="button" />
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import { Calendar } from "@medusajs/ui"
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This component is based on the [react-date-picker](https://www.npmjs.com/package/react-date-picker) package.
|
<ComponentReference mainComponent="Calendar" />
|
||||||
|
|
||||||
<ComponentProps component="calendar" />
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import { Checkbox } from "@medusajs/ui"
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This component is based on the [Radix UI Checkbox](https://www.radix-ui.com/primitives/docs/components/checkbox) primitive.
|
<ComponentReference mainComponent="Checkbox" />
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|||||||
@@ -34,25 +34,12 @@ import { CodeBlock } from "@medusajs/ui"
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### CodeBlock
|
<ComponentReference mainComponent="CodeBlock" componentsToShow={[
|
||||||
|
"CodeBlock",
|
||||||
This component is based on the `div` element and supports all props of this element.
|
"CodeBlock.Header",
|
||||||
|
"CodeBlock.Header.Meta",
|
||||||
<ComponentProps component="code-block" />
|
"CodeBlock.Body"
|
||||||
|
]} />
|
||||||
### CodeBlock.Header
|
|
||||||
|
|
||||||
This component is based on the `div` element and supports all props of this element.
|
|
||||||
|
|
||||||
<ComponentProps component="code-block-header" />
|
|
||||||
|
|
||||||
### CodeBlock.Header.Meta
|
|
||||||
|
|
||||||
This component is based on the `div` element and supports all props of this element.
|
|
||||||
|
|
||||||
### CodeBlock.Body
|
|
||||||
|
|
||||||
This component is based on the `div` element and supports all props of this element.
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|||||||
@@ -38,26 +38,10 @@ import { CommandBar } from "@medusajs/ui"
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### CommandBar
|
<ComponentReference mainComponent="CommandBar" componentsToShow={[
|
||||||
|
"CommandBar",
|
||||||
The root component of the command bar. This component manages the state of the command bar.
|
"CommandBar.Bar",
|
||||||
|
"CommandBar.Value",
|
||||||
<ComponentProps component="command-bar" />
|
"CommandBar.Seperator",
|
||||||
|
"CommandBar.Command"
|
||||||
### CommandBar.Bar
|
]} />
|
||||||
|
|
||||||
The bar component of the command bar. This component is used to display the commands.
|
|
||||||
|
|
||||||
### CommandBar.Value
|
|
||||||
|
|
||||||
The value component of the command bar. This component is used to display a value, such as the number of selected items which the commands will act on.
|
|
||||||
|
|
||||||
### CommandBar.Seperator
|
|
||||||
|
|
||||||
The seperator component of the command bar. This component is used to display a seperator between commands.
|
|
||||||
|
|
||||||
### CommandBar.Command
|
|
||||||
|
|
||||||
The command component of the command bar. This component is used to display a command, as well as registering the keyboad shortcut.
|
|
||||||
|
|
||||||
<ComponentProps component="command-bar-command" />
|
|
||||||
@@ -24,4 +24,4 @@ import { Command } from "@medusajs/ui"
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This component is based on the `div` element and supports all props of this element.
|
<ComponentReference mainComponent="Command" />
|
||||||
@@ -22,7 +22,7 @@ import { Container } from "@medusajs/ui"
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This component is based on the `div` element and supports all props of this element.
|
<ComponentReference mainComponent="Container" />
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import { Copy } from "@medusajs/ui"
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This component is based on the `button` element and supports all props of this element.
|
<ComponentReference mainComponent="Copy" />
|
||||||
|
|
||||||
<ComponentProps component="copy" />
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import { CurrencyInput } from "@medusajs/ui"
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This component is based on the `input` element and supports all props of this element.
|
<ComponentReference mainComponent="CurrencyInput" />
|
||||||
|
|
||||||
<ComponentProps component="currency-input" />
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ import { DatePicker } from "@medusajs/ui"
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This component is based on the [Calendar](/components/calendar) component and [Radix UI Popover](https://www.radix-ui.com/primitives/docs/components/popover).
|
<ComponentReference mainComponent="DatePicker" />
|
||||||
|
|
||||||
<ComponentProps component="date-picker" />
|
|
||||||
|
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|||||||
Loaded 100 of 288 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user