@boopdoopgoop/design-system 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +442 -2
- package/dist/components/index.cjs +233 -0
- package/dist/components/index.cjs.map +1 -0
- package/dist/components/index.d.cts +63 -0
- package/dist/components/index.d.ts +63 -0
- package/dist/components/index.js +208 -0
- package/dist/components/index.js.map +1 -0
- package/dist/index.cjs +777 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +775 -0
- package/dist/index.d.ts +775 -0
- package/dist/index.js +745 -0
- package/dist/index.js.map +1 -0
- package/package.json +99 -4
- package/src/tokens/primitives.json +354 -0
- package/src/tokens/semantic.json +133 -0
- package/styles/components.css +290 -0
- package/styles/fonts.css +8 -0
- package/styles/theme.css +271 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/components/index.ts
|
|
21
|
+
var components_exports = {};
|
|
22
|
+
__export(components_exports, {
|
|
23
|
+
Button: () => Button,
|
|
24
|
+
ButtonLink: () => ButtonLink,
|
|
25
|
+
Field: () => Field,
|
|
26
|
+
Input: () => Input,
|
|
27
|
+
Modal: () => Modal,
|
|
28
|
+
Panel: () => Panel,
|
|
29
|
+
Tag: () => Tag,
|
|
30
|
+
Textarea: () => Textarea,
|
|
31
|
+
cn: () => cn
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(components_exports);
|
|
34
|
+
|
|
35
|
+
// src/lib/cn.ts
|
|
36
|
+
var import_clsx = require("clsx");
|
|
37
|
+
var import_tailwind_merge = require("tailwind-merge");
|
|
38
|
+
function cn(...inputs) {
|
|
39
|
+
return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/components/Button.tsx
|
|
43
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
44
|
+
function buttonClassName(variant, className) {
|
|
45
|
+
return cn("ds-button", `ds-button--${variant}`, className);
|
|
46
|
+
}
|
|
47
|
+
function Button({
|
|
48
|
+
className,
|
|
49
|
+
type = "button",
|
|
50
|
+
variant = "primary",
|
|
51
|
+
...props
|
|
52
|
+
}) {
|
|
53
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
54
|
+
"button",
|
|
55
|
+
{
|
|
56
|
+
...props,
|
|
57
|
+
className: buttonClassName(variant, className),
|
|
58
|
+
type
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
function ButtonLink({
|
|
63
|
+
className,
|
|
64
|
+
variant = "primary",
|
|
65
|
+
...props
|
|
66
|
+
}) {
|
|
67
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { ...props, className: buttonClassName(variant, className) });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/components/Control.tsx
|
|
71
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
72
|
+
function Input({ className, ...props }) {
|
|
73
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { ...props, className: cn("ds-control", className) });
|
|
74
|
+
}
|
|
75
|
+
function Textarea({ className, ...props }) {
|
|
76
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
77
|
+
"textarea",
|
|
78
|
+
{
|
|
79
|
+
...props,
|
|
80
|
+
className: cn("ds-control", "ds-textarea", className)
|
|
81
|
+
}
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// src/components/Tag.tsx
|
|
86
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
87
|
+
function Tag({ children, tone = "neutral", className }) {
|
|
88
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: cn("ds-tag", `ds-tag--${tone}`, className), children });
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/components/Panel.tsx
|
|
92
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
93
|
+
function Panel({
|
|
94
|
+
title,
|
|
95
|
+
actions,
|
|
96
|
+
children,
|
|
97
|
+
className,
|
|
98
|
+
headerClassName,
|
|
99
|
+
bodyClassName
|
|
100
|
+
}) {
|
|
101
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: cn("ds-panel", className), children: [
|
|
102
|
+
title ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("header", { className: cn("ds-panel-header", headerClassName), children: [
|
|
103
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: title }),
|
|
104
|
+
actions
|
|
105
|
+
] }) : null,
|
|
106
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: cn("ds-panel-body", bodyClassName), children })
|
|
107
|
+
] });
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/components/Field.tsx
|
|
111
|
+
var import_react = require("react");
|
|
112
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
113
|
+
function Field({
|
|
114
|
+
label,
|
|
115
|
+
hint,
|
|
116
|
+
error,
|
|
117
|
+
children,
|
|
118
|
+
className,
|
|
119
|
+
interactiveLabel = true
|
|
120
|
+
}) {
|
|
121
|
+
const id = (0, import_react.useId)();
|
|
122
|
+
const labelId = `${id}-label`;
|
|
123
|
+
const hintId = `${id}-hint`;
|
|
124
|
+
const errorId = `${id}-error`;
|
|
125
|
+
const Wrapper = interactiveLabel ? "label" : "div";
|
|
126
|
+
const control = (0, import_react.isValidElement)(children) && children.type !== import_react.Fragment && (typeof children.type !== "string" || [
|
|
127
|
+
"input",
|
|
128
|
+
"textarea",
|
|
129
|
+
"select",
|
|
130
|
+
"button",
|
|
131
|
+
"meter",
|
|
132
|
+
"output",
|
|
133
|
+
"progress"
|
|
134
|
+
].includes(children.type)) ? children : null;
|
|
135
|
+
const controlId = control?.props.id ?? `${id}-control`;
|
|
136
|
+
const content = control ? (0, import_react.cloneElement)(control, {
|
|
137
|
+
id: controlId,
|
|
138
|
+
"aria-describedby": [control.props["aria-describedby"], hint && hintId, error && errorId].filter(Boolean).join(" ") || void 0,
|
|
139
|
+
"aria-invalid": error ? true : control.props["aria-invalid"],
|
|
140
|
+
...!interactiveLabel ? {
|
|
141
|
+
"aria-labelledby": [control.props["aria-labelledby"], labelId].filter(Boolean).join(" ")
|
|
142
|
+
} : {}
|
|
143
|
+
}) : children;
|
|
144
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: cn("ds-field", className), children: [
|
|
145
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
146
|
+
Wrapper,
|
|
147
|
+
{
|
|
148
|
+
className: "ds-field-wrapper",
|
|
149
|
+
...interactiveLabel && control ? { htmlFor: controlId } : {},
|
|
150
|
+
children: [
|
|
151
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: labelId, className: "ds-field-label", children: label }),
|
|
152
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "ds-field-control", children: content })
|
|
153
|
+
]
|
|
154
|
+
}
|
|
155
|
+
),
|
|
156
|
+
hint ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: hintId, className: "ds-field-hint", children: hint }) : null,
|
|
157
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { id: errorId, className: "ds-field-error", role: "alert", children: error }) : null
|
|
158
|
+
] });
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/components/Modal.tsx
|
|
162
|
+
var import_react_aria_components = require("react-aria-components");
|
|
163
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
164
|
+
function Modal({
|
|
165
|
+
open,
|
|
166
|
+
title,
|
|
167
|
+
busy = false,
|
|
168
|
+
onClose,
|
|
169
|
+
className,
|
|
170
|
+
bodyClassName,
|
|
171
|
+
footer,
|
|
172
|
+
children
|
|
173
|
+
}) {
|
|
174
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
175
|
+
import_react_aria_components.ModalOverlay,
|
|
176
|
+
{
|
|
177
|
+
isOpen: open,
|
|
178
|
+
onOpenChange: (isOpen) => {
|
|
179
|
+
if (!isOpen && !busy) onClose();
|
|
180
|
+
},
|
|
181
|
+
isDismissable: !busy,
|
|
182
|
+
className: "ds-modal-overlay",
|
|
183
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
184
|
+
import_react_aria_components.Modal,
|
|
185
|
+
{
|
|
186
|
+
className: cn("ds-modal", footer && "ds-modal--with-footer", className),
|
|
187
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_aria_components.Dialog, { className: "ds-modal-dialog", "aria-label": title, children: [
|
|
188
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ds-modal-header", children: [
|
|
189
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_aria_components.Heading, { slot: "title", className: "ds-modal-title", children: title }),
|
|
190
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
191
|
+
"button",
|
|
192
|
+
{
|
|
193
|
+
type: "button",
|
|
194
|
+
"aria-label": "Close",
|
|
195
|
+
disabled: busy,
|
|
196
|
+
onClick: onClose,
|
|
197
|
+
className: "ds-modal-close",
|
|
198
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
199
|
+
"svg",
|
|
200
|
+
{
|
|
201
|
+
viewBox: "0 0 24 24",
|
|
202
|
+
fill: "none",
|
|
203
|
+
stroke: "currentColor",
|
|
204
|
+
strokeWidth: "2",
|
|
205
|
+
"aria-hidden": "true",
|
|
206
|
+
focusable: "false",
|
|
207
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { d: "m6 6 12 12M6 18 18 6" })
|
|
208
|
+
}
|
|
209
|
+
)
|
|
210
|
+
}
|
|
211
|
+
)
|
|
212
|
+
] }),
|
|
213
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: cn("ds-modal-body", bodyClassName), children }),
|
|
214
|
+
footer ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ds-modal-footer", children: footer }) : null
|
|
215
|
+
] })
|
|
216
|
+
}
|
|
217
|
+
)
|
|
218
|
+
}
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
222
|
+
0 && (module.exports = {
|
|
223
|
+
Button,
|
|
224
|
+
ButtonLink,
|
|
225
|
+
Field,
|
|
226
|
+
Input,
|
|
227
|
+
Modal,
|
|
228
|
+
Panel,
|
|
229
|
+
Tag,
|
|
230
|
+
Textarea,
|
|
231
|
+
cn
|
|
232
|
+
});
|
|
233
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/index.ts","../../src/lib/cn.ts","../../src/components/Button.tsx","../../src/components/Control.tsx","../../src/components/Tag.tsx","../../src/components/Panel.tsx","../../src/components/Field.tsx","../../src/components/Modal.tsx"],"sourcesContent":["export {\n Button,\n ButtonLink,\n type ButtonProps,\n type ButtonLinkProps,\n type ButtonVariant,\n} from './Button';\nexport {\n Input,\n Textarea,\n type InputProps,\n type TextareaProps,\n} from './Control';\nexport { Tag, type TagProps, type TagTone } from './Tag';\nexport { Panel, type PanelProps } from './Panel';\nexport { Field, type FieldProps } from './Field';\nexport { Modal, type ModalProps } from './Modal';\nexport { cn } from '../lib/cn';\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import type { AnchorHTMLAttributes, ButtonHTMLAttributes, Ref } from 'react';\nimport { cn } from '../lib/cn';\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'danger';\nexport type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n variant?: ButtonVariant;\n ref?: Ref<HTMLButtonElement>;\n};\nexport type ButtonLinkProps = AnchorHTMLAttributes<HTMLAnchorElement> & {\n variant?: ButtonVariant;\n};\n\nfunction buttonClassName(variant: ButtonVariant, className?: string) {\n return cn('ds-button', `ds-button--${variant}`, className);\n}\n\nexport function Button({\n className,\n type = 'button',\n variant = 'primary',\n ...props\n}: ButtonProps) {\n return (\n <button\n {...props}\n className={buttonClassName(variant, className)}\n type={type}\n />\n );\n}\n\nexport function ButtonLink({\n className,\n variant = 'primary',\n ...props\n}: ButtonLinkProps) {\n return <a {...props} className={buttonClassName(variant, className)} />;\n}\n","import type { ComponentPropsWithRef } from 'react';\nimport { cn } from '../lib/cn';\n\nexport type InputProps = ComponentPropsWithRef<'input'>;\nexport type TextareaProps = ComponentPropsWithRef<'textarea'>;\n\nexport function Input({ className, ...props }: InputProps) {\n return <input {...props} className={cn('ds-control', className)} />;\n}\n\nexport function Textarea({ className, ...props }: TextareaProps) {\n return (\n <textarea\n {...props}\n className={cn('ds-control', 'ds-textarea', className)}\n />\n );\n}\n","import type { ReactNode } from 'react';\nimport { cn } from '../lib/cn';\n\nexport type TagTone = 'neutral' | 'success' | 'warning' | 'danger' | 'info';\nexport type TagProps = {\n children: ReactNode;\n tone?: TagTone;\n className?: string;\n};\n\nexport function Tag({ children, tone = 'neutral', className }: TagProps) {\n return (\n <span className={cn('ds-tag', `ds-tag--${tone}`, className)}>\n {children}\n </span>\n );\n}\n","import type { ReactNode } from 'react';\nimport { cn } from '../lib/cn';\n\nexport type PanelProps = {\n title?: ReactNode;\n actions?: ReactNode;\n children: ReactNode;\n className?: string;\n headerClassName?: string;\n bodyClassName?: string;\n};\n\nexport function Panel({\n title,\n actions,\n children,\n className,\n headerClassName,\n bodyClassName,\n}: PanelProps) {\n return (\n <section className={cn('ds-panel', className)}>\n {title ? (\n <header className={cn('ds-panel-header', headerClassName)}>\n <span>{title}</span>\n {actions}\n </header>\n ) : null}\n <div className={cn('ds-panel-body', bodyClassName)}>{children}</div>\n </section>\n );\n}\n","import {\n cloneElement,\n Fragment,\n isValidElement,\n useId,\n type AriaAttributes,\n type ReactNode,\n} from 'react';\nimport { cn } from '../lib/cn';\n\nexport type FieldProps = {\n label: ReactNode;\n hint?: ReactNode;\n error?: ReactNode;\n children: ReactNode;\n className?: string;\n interactiveLabel?: boolean;\n};\n\ntype ControlAttributes = AriaAttributes & { id?: string };\n\nexport function Field({\n label,\n hint,\n error,\n children,\n className,\n interactiveLabel = true,\n}: FieldProps) {\n const id = useId();\n const labelId = `${id}-label`;\n const hintId = `${id}-hint`;\n const errorId = `${id}-error`;\n const Wrapper = interactiveLabel ? 'label' : 'div';\n const control =\n isValidElement<ControlAttributes>(children) &&\n children.type !== Fragment &&\n (typeof children.type !== 'string' ||\n [\n 'input',\n 'textarea',\n 'select',\n 'button',\n 'meter',\n 'output',\n 'progress',\n ].includes(children.type))\n ? children\n : null;\n const controlId = control?.props.id ?? `${id}-control`;\n const content = control\n ? cloneElement(control, {\n id: controlId,\n 'aria-describedby':\n [control.props['aria-describedby'], hint && hintId, error && errorId]\n .filter(Boolean)\n .join(' ') || undefined,\n 'aria-invalid': error ? true : control.props['aria-invalid'],\n ...(!interactiveLabel\n ? {\n 'aria-labelledby': [control.props['aria-labelledby'], labelId]\n .filter(Boolean)\n .join(' '),\n }\n : {}),\n })\n : children;\n\n return (\n <div className={cn('ds-field', className)}>\n <Wrapper\n className=\"ds-field-wrapper\"\n {...(interactiveLabel && control ? { htmlFor: controlId } : {})}\n >\n <span id={labelId} className=\"ds-field-label\">\n {label}\n </span>\n <span className=\"ds-field-control\">{content}</span>\n </Wrapper>\n {hint ? (\n <span id={hintId} className=\"ds-field-hint\">\n {hint}\n </span>\n ) : null}\n {error ? (\n <span id={errorId} className=\"ds-field-error\" role=\"alert\">\n {error}\n </span>\n ) : null}\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport {\n Dialog,\n Heading,\n Modal as AriaModal,\n ModalOverlay,\n} from 'react-aria-components';\nimport { cn } from '../lib/cn';\n\nexport type ModalProps = {\n open: boolean;\n title: string;\n busy?: boolean;\n onClose: () => void;\n className?: string;\n bodyClassName?: string;\n footer?: ReactNode;\n children: ReactNode;\n};\n\nexport function Modal({\n open,\n title,\n busy = false,\n onClose,\n className,\n bodyClassName,\n footer,\n children,\n}: ModalProps) {\n return (\n <ModalOverlay\n isOpen={open}\n onOpenChange={(isOpen) => {\n if (!isOpen && !busy) onClose();\n }}\n isDismissable={!busy}\n className=\"ds-modal-overlay\"\n >\n <AriaModal\n className={cn('ds-modal', footer && 'ds-modal--with-footer', className)}\n >\n <Dialog className=\"ds-modal-dialog\" aria-label={title}>\n <div className=\"ds-modal-header\">\n <Heading slot=\"title\" className=\"ds-modal-title\">\n {title}\n </Heading>\n <button\n type=\"button\"\n aria-label=\"Close\"\n disabled={busy}\n onClick={onClose}\n className=\"ds-modal-close\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"m6 6 12 12M6 18 18 6\" />\n </svg>\n </button>\n </div>\n <div className={cn('ds-modal-body', bodyClassName)}>{children}</div>\n {footer ? <div className=\"ds-modal-footer\">{footer}</div> : null}\n </Dialog>\n </AriaModal>\n </ModalOverlay>\n );\n}\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime","AriaModal"]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ButtonHTMLAttributes, Ref, AnchorHTMLAttributes, ComponentPropsWithRef, ReactNode } from 'react';
|
|
3
|
+
import { ClassValue } from 'clsx';
|
|
4
|
+
|
|
5
|
+
type ButtonVariant = 'primary' | 'secondary' | 'danger';
|
|
6
|
+
type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
7
|
+
variant?: ButtonVariant;
|
|
8
|
+
ref?: Ref<HTMLButtonElement>;
|
|
9
|
+
};
|
|
10
|
+
type ButtonLinkProps = AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
11
|
+
variant?: ButtonVariant;
|
|
12
|
+
};
|
|
13
|
+
declare function Button({ className, type, variant, ...props }: ButtonProps): react.JSX.Element;
|
|
14
|
+
declare function ButtonLink({ className, variant, ...props }: ButtonLinkProps): react.JSX.Element;
|
|
15
|
+
|
|
16
|
+
type InputProps = ComponentPropsWithRef<'input'>;
|
|
17
|
+
type TextareaProps = ComponentPropsWithRef<'textarea'>;
|
|
18
|
+
declare function Input({ className, ...props }: InputProps): react.JSX.Element;
|
|
19
|
+
declare function Textarea({ className, ...props }: TextareaProps): react.JSX.Element;
|
|
20
|
+
|
|
21
|
+
type TagTone = 'neutral' | 'success' | 'warning' | 'danger' | 'info';
|
|
22
|
+
type TagProps = {
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
tone?: TagTone;
|
|
25
|
+
className?: string;
|
|
26
|
+
};
|
|
27
|
+
declare function Tag({ children, tone, className }: TagProps): react.JSX.Element;
|
|
28
|
+
|
|
29
|
+
type PanelProps = {
|
|
30
|
+
title?: ReactNode;
|
|
31
|
+
actions?: ReactNode;
|
|
32
|
+
children: ReactNode;
|
|
33
|
+
className?: string;
|
|
34
|
+
headerClassName?: string;
|
|
35
|
+
bodyClassName?: string;
|
|
36
|
+
};
|
|
37
|
+
declare function Panel({ title, actions, children, className, headerClassName, bodyClassName, }: PanelProps): react.JSX.Element;
|
|
38
|
+
|
|
39
|
+
type FieldProps = {
|
|
40
|
+
label: ReactNode;
|
|
41
|
+
hint?: ReactNode;
|
|
42
|
+
error?: ReactNode;
|
|
43
|
+
children: ReactNode;
|
|
44
|
+
className?: string;
|
|
45
|
+
interactiveLabel?: boolean;
|
|
46
|
+
};
|
|
47
|
+
declare function Field({ label, hint, error, children, className, interactiveLabel, }: FieldProps): react.JSX.Element;
|
|
48
|
+
|
|
49
|
+
type ModalProps = {
|
|
50
|
+
open: boolean;
|
|
51
|
+
title: string;
|
|
52
|
+
busy?: boolean;
|
|
53
|
+
onClose: () => void;
|
|
54
|
+
className?: string;
|
|
55
|
+
bodyClassName?: string;
|
|
56
|
+
footer?: ReactNode;
|
|
57
|
+
children: ReactNode;
|
|
58
|
+
};
|
|
59
|
+
declare function Modal({ open, title, busy, onClose, className, bodyClassName, footer, children, }: ModalProps): react.JSX.Element;
|
|
60
|
+
|
|
61
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
62
|
+
|
|
63
|
+
export { Button, ButtonLink, type ButtonLinkProps, type ButtonProps, type ButtonVariant, Field, type FieldProps, Input, type InputProps, Modal, type ModalProps, Panel, type PanelProps, Tag, type TagProps, type TagTone, Textarea, type TextareaProps, cn };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { ButtonHTMLAttributes, Ref, AnchorHTMLAttributes, ComponentPropsWithRef, ReactNode } from 'react';
|
|
3
|
+
import { ClassValue } from 'clsx';
|
|
4
|
+
|
|
5
|
+
type ButtonVariant = 'primary' | 'secondary' | 'danger';
|
|
6
|
+
type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
7
|
+
variant?: ButtonVariant;
|
|
8
|
+
ref?: Ref<HTMLButtonElement>;
|
|
9
|
+
};
|
|
10
|
+
type ButtonLinkProps = AnchorHTMLAttributes<HTMLAnchorElement> & {
|
|
11
|
+
variant?: ButtonVariant;
|
|
12
|
+
};
|
|
13
|
+
declare function Button({ className, type, variant, ...props }: ButtonProps): react.JSX.Element;
|
|
14
|
+
declare function ButtonLink({ className, variant, ...props }: ButtonLinkProps): react.JSX.Element;
|
|
15
|
+
|
|
16
|
+
type InputProps = ComponentPropsWithRef<'input'>;
|
|
17
|
+
type TextareaProps = ComponentPropsWithRef<'textarea'>;
|
|
18
|
+
declare function Input({ className, ...props }: InputProps): react.JSX.Element;
|
|
19
|
+
declare function Textarea({ className, ...props }: TextareaProps): react.JSX.Element;
|
|
20
|
+
|
|
21
|
+
type TagTone = 'neutral' | 'success' | 'warning' | 'danger' | 'info';
|
|
22
|
+
type TagProps = {
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
tone?: TagTone;
|
|
25
|
+
className?: string;
|
|
26
|
+
};
|
|
27
|
+
declare function Tag({ children, tone, className }: TagProps): react.JSX.Element;
|
|
28
|
+
|
|
29
|
+
type PanelProps = {
|
|
30
|
+
title?: ReactNode;
|
|
31
|
+
actions?: ReactNode;
|
|
32
|
+
children: ReactNode;
|
|
33
|
+
className?: string;
|
|
34
|
+
headerClassName?: string;
|
|
35
|
+
bodyClassName?: string;
|
|
36
|
+
};
|
|
37
|
+
declare function Panel({ title, actions, children, className, headerClassName, bodyClassName, }: PanelProps): react.JSX.Element;
|
|
38
|
+
|
|
39
|
+
type FieldProps = {
|
|
40
|
+
label: ReactNode;
|
|
41
|
+
hint?: ReactNode;
|
|
42
|
+
error?: ReactNode;
|
|
43
|
+
children: ReactNode;
|
|
44
|
+
className?: string;
|
|
45
|
+
interactiveLabel?: boolean;
|
|
46
|
+
};
|
|
47
|
+
declare function Field({ label, hint, error, children, className, interactiveLabel, }: FieldProps): react.JSX.Element;
|
|
48
|
+
|
|
49
|
+
type ModalProps = {
|
|
50
|
+
open: boolean;
|
|
51
|
+
title: string;
|
|
52
|
+
busy?: boolean;
|
|
53
|
+
onClose: () => void;
|
|
54
|
+
className?: string;
|
|
55
|
+
bodyClassName?: string;
|
|
56
|
+
footer?: ReactNode;
|
|
57
|
+
children: ReactNode;
|
|
58
|
+
};
|
|
59
|
+
declare function Modal({ open, title, busy, onClose, className, bodyClassName, footer, children, }: ModalProps): react.JSX.Element;
|
|
60
|
+
|
|
61
|
+
declare function cn(...inputs: ClassValue[]): string;
|
|
62
|
+
|
|
63
|
+
export { Button, ButtonLink, type ButtonLinkProps, type ButtonProps, type ButtonVariant, Field, type FieldProps, Input, type InputProps, Modal, type ModalProps, Panel, type PanelProps, Tag, type TagProps, type TagTone, Textarea, type TextareaProps, cn };
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
// src/lib/cn.ts
|
|
2
|
+
import { clsx } from "clsx";
|
|
3
|
+
import { twMerge } from "tailwind-merge";
|
|
4
|
+
function cn(...inputs) {
|
|
5
|
+
return twMerge(clsx(inputs));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// src/components/Button.tsx
|
|
9
|
+
import { jsx } from "react/jsx-runtime";
|
|
10
|
+
function buttonClassName(variant, className) {
|
|
11
|
+
return cn("ds-button", `ds-button--${variant}`, className);
|
|
12
|
+
}
|
|
13
|
+
function Button({
|
|
14
|
+
className,
|
|
15
|
+
type = "button",
|
|
16
|
+
variant = "primary",
|
|
17
|
+
...props
|
|
18
|
+
}) {
|
|
19
|
+
return /* @__PURE__ */ jsx(
|
|
20
|
+
"button",
|
|
21
|
+
{
|
|
22
|
+
...props,
|
|
23
|
+
className: buttonClassName(variant, className),
|
|
24
|
+
type
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
function ButtonLink({
|
|
29
|
+
className,
|
|
30
|
+
variant = "primary",
|
|
31
|
+
...props
|
|
32
|
+
}) {
|
|
33
|
+
return /* @__PURE__ */ jsx("a", { ...props, className: buttonClassName(variant, className) });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/components/Control.tsx
|
|
37
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
38
|
+
function Input({ className, ...props }) {
|
|
39
|
+
return /* @__PURE__ */ jsx2("input", { ...props, className: cn("ds-control", className) });
|
|
40
|
+
}
|
|
41
|
+
function Textarea({ className, ...props }) {
|
|
42
|
+
return /* @__PURE__ */ jsx2(
|
|
43
|
+
"textarea",
|
|
44
|
+
{
|
|
45
|
+
...props,
|
|
46
|
+
className: cn("ds-control", "ds-textarea", className)
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// src/components/Tag.tsx
|
|
52
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
53
|
+
function Tag({ children, tone = "neutral", className }) {
|
|
54
|
+
return /* @__PURE__ */ jsx3("span", { className: cn("ds-tag", `ds-tag--${tone}`, className), children });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/components/Panel.tsx
|
|
58
|
+
import { jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
59
|
+
function Panel({
|
|
60
|
+
title,
|
|
61
|
+
actions,
|
|
62
|
+
children,
|
|
63
|
+
className,
|
|
64
|
+
headerClassName,
|
|
65
|
+
bodyClassName
|
|
66
|
+
}) {
|
|
67
|
+
return /* @__PURE__ */ jsxs("section", { className: cn("ds-panel", className), children: [
|
|
68
|
+
title ? /* @__PURE__ */ jsxs("header", { className: cn("ds-panel-header", headerClassName), children: [
|
|
69
|
+
/* @__PURE__ */ jsx4("span", { children: title }),
|
|
70
|
+
actions
|
|
71
|
+
] }) : null,
|
|
72
|
+
/* @__PURE__ */ jsx4("div", { className: cn("ds-panel-body", bodyClassName), children })
|
|
73
|
+
] });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// src/components/Field.tsx
|
|
77
|
+
import {
|
|
78
|
+
cloneElement,
|
|
79
|
+
Fragment,
|
|
80
|
+
isValidElement,
|
|
81
|
+
useId
|
|
82
|
+
} from "react";
|
|
83
|
+
import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
84
|
+
function Field({
|
|
85
|
+
label,
|
|
86
|
+
hint,
|
|
87
|
+
error,
|
|
88
|
+
children,
|
|
89
|
+
className,
|
|
90
|
+
interactiveLabel = true
|
|
91
|
+
}) {
|
|
92
|
+
const id = useId();
|
|
93
|
+
const labelId = `${id}-label`;
|
|
94
|
+
const hintId = `${id}-hint`;
|
|
95
|
+
const errorId = `${id}-error`;
|
|
96
|
+
const Wrapper = interactiveLabel ? "label" : "div";
|
|
97
|
+
const control = isValidElement(children) && children.type !== Fragment && (typeof children.type !== "string" || [
|
|
98
|
+
"input",
|
|
99
|
+
"textarea",
|
|
100
|
+
"select",
|
|
101
|
+
"button",
|
|
102
|
+
"meter",
|
|
103
|
+
"output",
|
|
104
|
+
"progress"
|
|
105
|
+
].includes(children.type)) ? children : null;
|
|
106
|
+
const controlId = control?.props.id ?? `${id}-control`;
|
|
107
|
+
const content = control ? cloneElement(control, {
|
|
108
|
+
id: controlId,
|
|
109
|
+
"aria-describedby": [control.props["aria-describedby"], hint && hintId, error && errorId].filter(Boolean).join(" ") || void 0,
|
|
110
|
+
"aria-invalid": error ? true : control.props["aria-invalid"],
|
|
111
|
+
...!interactiveLabel ? {
|
|
112
|
+
"aria-labelledby": [control.props["aria-labelledby"], labelId].filter(Boolean).join(" ")
|
|
113
|
+
} : {}
|
|
114
|
+
}) : children;
|
|
115
|
+
return /* @__PURE__ */ jsxs2("div", { className: cn("ds-field", className), children: [
|
|
116
|
+
/* @__PURE__ */ jsxs2(
|
|
117
|
+
Wrapper,
|
|
118
|
+
{
|
|
119
|
+
className: "ds-field-wrapper",
|
|
120
|
+
...interactiveLabel && control ? { htmlFor: controlId } : {},
|
|
121
|
+
children: [
|
|
122
|
+
/* @__PURE__ */ jsx5("span", { id: labelId, className: "ds-field-label", children: label }),
|
|
123
|
+
/* @__PURE__ */ jsx5("span", { className: "ds-field-control", children: content })
|
|
124
|
+
]
|
|
125
|
+
}
|
|
126
|
+
),
|
|
127
|
+
hint ? /* @__PURE__ */ jsx5("span", { id: hintId, className: "ds-field-hint", children: hint }) : null,
|
|
128
|
+
error ? /* @__PURE__ */ jsx5("span", { id: errorId, className: "ds-field-error", role: "alert", children: error }) : null
|
|
129
|
+
] });
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// src/components/Modal.tsx
|
|
133
|
+
import {
|
|
134
|
+
Dialog,
|
|
135
|
+
Heading,
|
|
136
|
+
Modal as AriaModal,
|
|
137
|
+
ModalOverlay
|
|
138
|
+
} from "react-aria-components";
|
|
139
|
+
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
140
|
+
function Modal({
|
|
141
|
+
open,
|
|
142
|
+
title,
|
|
143
|
+
busy = false,
|
|
144
|
+
onClose,
|
|
145
|
+
className,
|
|
146
|
+
bodyClassName,
|
|
147
|
+
footer,
|
|
148
|
+
children
|
|
149
|
+
}) {
|
|
150
|
+
return /* @__PURE__ */ jsx6(
|
|
151
|
+
ModalOverlay,
|
|
152
|
+
{
|
|
153
|
+
isOpen: open,
|
|
154
|
+
onOpenChange: (isOpen) => {
|
|
155
|
+
if (!isOpen && !busy) onClose();
|
|
156
|
+
},
|
|
157
|
+
isDismissable: !busy,
|
|
158
|
+
className: "ds-modal-overlay",
|
|
159
|
+
children: /* @__PURE__ */ jsx6(
|
|
160
|
+
AriaModal,
|
|
161
|
+
{
|
|
162
|
+
className: cn("ds-modal", footer && "ds-modal--with-footer", className),
|
|
163
|
+
children: /* @__PURE__ */ jsxs3(Dialog, { className: "ds-modal-dialog", "aria-label": title, children: [
|
|
164
|
+
/* @__PURE__ */ jsxs3("div", { className: "ds-modal-header", children: [
|
|
165
|
+
/* @__PURE__ */ jsx6(Heading, { slot: "title", className: "ds-modal-title", children: title }),
|
|
166
|
+
/* @__PURE__ */ jsx6(
|
|
167
|
+
"button",
|
|
168
|
+
{
|
|
169
|
+
type: "button",
|
|
170
|
+
"aria-label": "Close",
|
|
171
|
+
disabled: busy,
|
|
172
|
+
onClick: onClose,
|
|
173
|
+
className: "ds-modal-close",
|
|
174
|
+
children: /* @__PURE__ */ jsx6(
|
|
175
|
+
"svg",
|
|
176
|
+
{
|
|
177
|
+
viewBox: "0 0 24 24",
|
|
178
|
+
fill: "none",
|
|
179
|
+
stroke: "currentColor",
|
|
180
|
+
strokeWidth: "2",
|
|
181
|
+
"aria-hidden": "true",
|
|
182
|
+
focusable: "false",
|
|
183
|
+
children: /* @__PURE__ */ jsx6("path", { d: "m6 6 12 12M6 18 18 6" })
|
|
184
|
+
}
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
)
|
|
188
|
+
] }),
|
|
189
|
+
/* @__PURE__ */ jsx6("div", { className: cn("ds-modal-body", bodyClassName), children }),
|
|
190
|
+
footer ? /* @__PURE__ */ jsx6("div", { className: "ds-modal-footer", children: footer }) : null
|
|
191
|
+
] })
|
|
192
|
+
}
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
export {
|
|
198
|
+
Button,
|
|
199
|
+
ButtonLink,
|
|
200
|
+
Field,
|
|
201
|
+
Input,
|
|
202
|
+
Modal,
|
|
203
|
+
Panel,
|
|
204
|
+
Tag,
|
|
205
|
+
Textarea,
|
|
206
|
+
cn
|
|
207
|
+
};
|
|
208
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/lib/cn.ts","../../src/components/Button.tsx","../../src/components/Control.tsx","../../src/components/Tag.tsx","../../src/components/Panel.tsx","../../src/components/Field.tsx","../../src/components/Modal.tsx"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import type { AnchorHTMLAttributes, ButtonHTMLAttributes, Ref } from 'react';\nimport { cn } from '../lib/cn';\n\nexport type ButtonVariant = 'primary' | 'secondary' | 'danger';\nexport type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {\n variant?: ButtonVariant;\n ref?: Ref<HTMLButtonElement>;\n};\nexport type ButtonLinkProps = AnchorHTMLAttributes<HTMLAnchorElement> & {\n variant?: ButtonVariant;\n};\n\nfunction buttonClassName(variant: ButtonVariant, className?: string) {\n return cn('ds-button', `ds-button--${variant}`, className);\n}\n\nexport function Button({\n className,\n type = 'button',\n variant = 'primary',\n ...props\n}: ButtonProps) {\n return (\n <button\n {...props}\n className={buttonClassName(variant, className)}\n type={type}\n />\n );\n}\n\nexport function ButtonLink({\n className,\n variant = 'primary',\n ...props\n}: ButtonLinkProps) {\n return <a {...props} className={buttonClassName(variant, className)} />;\n}\n","import type { ComponentPropsWithRef } from 'react';\nimport { cn } from '../lib/cn';\n\nexport type InputProps = ComponentPropsWithRef<'input'>;\nexport type TextareaProps = ComponentPropsWithRef<'textarea'>;\n\nexport function Input({ className, ...props }: InputProps) {\n return <input {...props} className={cn('ds-control', className)} />;\n}\n\nexport function Textarea({ className, ...props }: TextareaProps) {\n return (\n <textarea\n {...props}\n className={cn('ds-control', 'ds-textarea', className)}\n />\n );\n}\n","import type { ReactNode } from 'react';\nimport { cn } from '../lib/cn';\n\nexport type TagTone = 'neutral' | 'success' | 'warning' | 'danger' | 'info';\nexport type TagProps = {\n children: ReactNode;\n tone?: TagTone;\n className?: string;\n};\n\nexport function Tag({ children, tone = 'neutral', className }: TagProps) {\n return (\n <span className={cn('ds-tag', `ds-tag--${tone}`, className)}>\n {children}\n </span>\n );\n}\n","import type { ReactNode } from 'react';\nimport { cn } from '../lib/cn';\n\nexport type PanelProps = {\n title?: ReactNode;\n actions?: ReactNode;\n children: ReactNode;\n className?: string;\n headerClassName?: string;\n bodyClassName?: string;\n};\n\nexport function Panel({\n title,\n actions,\n children,\n className,\n headerClassName,\n bodyClassName,\n}: PanelProps) {\n return (\n <section className={cn('ds-panel', className)}>\n {title ? (\n <header className={cn('ds-panel-header', headerClassName)}>\n <span>{title}</span>\n {actions}\n </header>\n ) : null}\n <div className={cn('ds-panel-body', bodyClassName)}>{children}</div>\n </section>\n );\n}\n","import {\n cloneElement,\n Fragment,\n isValidElement,\n useId,\n type AriaAttributes,\n type ReactNode,\n} from 'react';\nimport { cn } from '../lib/cn';\n\nexport type FieldProps = {\n label: ReactNode;\n hint?: ReactNode;\n error?: ReactNode;\n children: ReactNode;\n className?: string;\n interactiveLabel?: boolean;\n};\n\ntype ControlAttributes = AriaAttributes & { id?: string };\n\nexport function Field({\n label,\n hint,\n error,\n children,\n className,\n interactiveLabel = true,\n}: FieldProps) {\n const id = useId();\n const labelId = `${id}-label`;\n const hintId = `${id}-hint`;\n const errorId = `${id}-error`;\n const Wrapper = interactiveLabel ? 'label' : 'div';\n const control =\n isValidElement<ControlAttributes>(children) &&\n children.type !== Fragment &&\n (typeof children.type !== 'string' ||\n [\n 'input',\n 'textarea',\n 'select',\n 'button',\n 'meter',\n 'output',\n 'progress',\n ].includes(children.type))\n ? children\n : null;\n const controlId = control?.props.id ?? `${id}-control`;\n const content = control\n ? cloneElement(control, {\n id: controlId,\n 'aria-describedby':\n [control.props['aria-describedby'], hint && hintId, error && errorId]\n .filter(Boolean)\n .join(' ') || undefined,\n 'aria-invalid': error ? true : control.props['aria-invalid'],\n ...(!interactiveLabel\n ? {\n 'aria-labelledby': [control.props['aria-labelledby'], labelId]\n .filter(Boolean)\n .join(' '),\n }\n : {}),\n })\n : children;\n\n return (\n <div className={cn('ds-field', className)}>\n <Wrapper\n className=\"ds-field-wrapper\"\n {...(interactiveLabel && control ? { htmlFor: controlId } : {})}\n >\n <span id={labelId} className=\"ds-field-label\">\n {label}\n </span>\n <span className=\"ds-field-control\">{content}</span>\n </Wrapper>\n {hint ? (\n <span id={hintId} className=\"ds-field-hint\">\n {hint}\n </span>\n ) : null}\n {error ? (\n <span id={errorId} className=\"ds-field-error\" role=\"alert\">\n {error}\n </span>\n ) : null}\n </div>\n );\n}\n","import type { ReactNode } from 'react';\nimport {\n Dialog,\n Heading,\n Modal as AriaModal,\n ModalOverlay,\n} from 'react-aria-components';\nimport { cn } from '../lib/cn';\n\nexport type ModalProps = {\n open: boolean;\n title: string;\n busy?: boolean;\n onClose: () => void;\n className?: string;\n bodyClassName?: string;\n footer?: ReactNode;\n children: ReactNode;\n};\n\nexport function Modal({\n open,\n title,\n busy = false,\n onClose,\n className,\n bodyClassName,\n footer,\n children,\n}: ModalProps) {\n return (\n <ModalOverlay\n isOpen={open}\n onOpenChange={(isOpen) => {\n if (!isOpen && !busy) onClose();\n }}\n isDismissable={!busy}\n className=\"ds-modal-overlay\"\n >\n <AriaModal\n className={cn('ds-modal', footer && 'ds-modal--with-footer', className)}\n >\n <Dialog className=\"ds-modal-dialog\" aria-label={title}>\n <div className=\"ds-modal-header\">\n <Heading slot=\"title\" className=\"ds-modal-title\">\n {title}\n </Heading>\n <button\n type=\"button\"\n aria-label=\"Close\"\n disabled={busy}\n onClick={onClose}\n className=\"ds-modal-close\"\n >\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"m6 6 12 12M6 18 18 6\" />\n </svg>\n </button>\n </div>\n <div className={cn('ds-modal-body', bodyClassName)}>{children}</div>\n {footer ? <div className=\"ds-modal-footer\">{footer}</div> : null}\n </Dialog>\n </AriaModal>\n </ModalOverlay>\n );\n}\n"],"mappings":"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","names":["jsx","jsx","jsx","jsx","jsxs","jsx","jsxs"]}
|