@cratis/components 4.25.2 → 4.26.1
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/compat-manifest.json +11 -11
- package/dist/esm/SchemaEditor/NameCell.d.ts +5 -1
- package/dist/esm/SchemaEditor/NameCell.d.ts.map +1 -1
- package/dist/esm/SchemaEditor/NameCell.js +2 -2
- package/dist/esm/SchemaEditor/NameCell.js.map +1 -1
- package/dist/esm/SchemaEditor/SchemaEditor.d.ts +63 -48
- package/dist/esm/SchemaEditor/SchemaEditor.d.ts.map +1 -1
- package/dist/esm/SchemaEditor/SchemaEditor.js +83 -25
- package/dist/esm/SchemaEditor/SchemaEditor.js.map +1 -1
- package/dist/esm/SchemaEditor/SchemaEditorLabels.d.ts +98 -0
- package/dist/esm/SchemaEditor/SchemaEditorLabels.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/SchemaEditorLabels.js +4 -0
- package/dist/esm/SchemaEditor/SchemaEditorLabels.js.map +1 -0
- package/dist/esm/SchemaEditor/SchemaEditorLayout.d.ts +6 -0
- package/dist/esm/SchemaEditor/SchemaEditorLayout.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/SchemaEditorLayout.js +4 -0
- package/dist/esm/SchemaEditor/SchemaEditorLayout.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/Property.d.ts +30 -0
- package/dist/esm/SchemaEditor/Tree/Property.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/Property.js +4 -0
- package/dist/esm/SchemaEditor/Tree/Property.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConcept.d.ts +15 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConcept.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConcept.js +4 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConcept.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConceptsContext.d.ts +22 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConceptsContext.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConceptsContext.js +10 -0
- package/dist/esm/SchemaEditor/Tree/PropertyConceptsContext.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyType.d.ts +22 -0
- package/dist/esm/SchemaEditor/Tree/PropertyType.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyType.js +15 -0
- package/dist/esm/SchemaEditor/Tree/PropertyType.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeBadge.d.ts +20 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeBadge.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeBadge.js +12 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeBadge.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeGlyph.d.ts +12 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeGlyph.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeGlyph.js +29 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeGlyph.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeMenu.d.ts +28 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeMenu.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeMenu.js +38 -0
- package/dist/esm/SchemaEditor/Tree/PropertyTypeMenu.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorContext.d.ts +42 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorContext.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorContext.js +12 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorContext.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorParts.d.ts +60 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorParts.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorParts.js +4 -0
- package/dist/esm/SchemaEditor/Tree/SchemaEditorParts.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyContext.d.ts +13 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyContext.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyContext.js +4 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyContext.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRow.d.ts +13 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRow.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRow.js +107 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRow.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRowState.d.ts +16 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRowState.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRowState.js +4 -0
- package/dist/esm/SchemaEditor/Tree/SchemaPropertyRowState.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/TreeSchemaEditor.d.ts +116 -0
- package/dist/esm/SchemaEditor/Tree/TreeSchemaEditor.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/TreeSchemaEditor.js +96 -0
- package/dist/esm/SchemaEditor/Tree/TreeSchemaEditor.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/propertyNaming.d.ts +35 -0
- package/dist/esm/SchemaEditor/Tree/propertyNaming.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/propertyNaming.js +34 -0
- package/dist/esm/SchemaEditor/Tree/propertyNaming.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/propertyTree.d.ts +30 -0
- package/dist/esm/SchemaEditor/Tree/propertyTree.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/propertyTree.js +36 -0
- package/dist/esm/SchemaEditor/Tree/propertyTree.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/propertyTypeDisplay.d.ts +20 -0
- package/dist/esm/SchemaEditor/Tree/propertyTypeDisplay.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/propertyTypeDisplay.js +34 -0
- package/dist/esm/SchemaEditor/Tree/propertyTypeDisplay.js.map +1 -0
- package/dist/esm/SchemaEditor/Tree/schemaConversion.d.ts +95 -0
- package/dist/esm/SchemaEditor/Tree/schemaConversion.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/Tree/schemaConversion.js +171 -0
- package/dist/esm/SchemaEditor/Tree/schemaConversion.js.map +1 -0
- package/dist/esm/SchemaEditor/TypeCell.d.ts +3 -1
- package/dist/esm/SchemaEditor/TypeCell.d.ts.map +1 -1
- package/dist/esm/SchemaEditor/TypeCell.js +2 -2
- package/dist/esm/SchemaEditor/TypeCell.js.map +1 -1
- package/dist/esm/SchemaEditor/defaultSchemaEditorLabels.d.ts +9 -0
- package/dist/esm/SchemaEditor/defaultSchemaEditorLabels.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/defaultSchemaEditorLabels.js +51 -0
- package/dist/esm/SchemaEditor/defaultSchemaEditorLabels.js.map +1 -0
- package/dist/esm/SchemaEditor/index.d.ts +12 -0
- package/dist/esm/SchemaEditor/index.d.ts.map +1 -1
- package/dist/esm/SchemaEditor/index.js +7 -1
- package/dist/esm/SchemaEditor/index.js.map +1 -1
- package/dist/esm/SchemaEditor/resolveSchemaEditorLabels.d.ts +4 -0
- package/dist/esm/SchemaEditor/resolveSchemaEditorLabels.d.ts.map +1 -0
- package/dist/esm/SchemaEditor/resolveSchemaEditorLabels.js +13 -0
- package/dist/esm/SchemaEditor/resolveSchemaEditorLabels.js.map +1 -0
- package/dist/esm/styles.SchemaEditor.css +391 -0
- package/dist/esm/styles.css +391 -0
- package/dist/esm/types/parts.d.ts +25 -0
- package/dist/esm/types/parts.d.ts.map +1 -1
- package/dist/esm/types/parts.js +25 -0
- package/dist/esm/types/parts.js.map +1 -1
- package/package.json +2 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
var PropertyType;
|
|
2
|
+
(function (PropertyType) {
|
|
3
|
+
PropertyType["String"] = "string";
|
|
4
|
+
PropertyType["Number"] = "number";
|
|
5
|
+
PropertyType["Boolean"] = "boolean";
|
|
6
|
+
PropertyType["Date"] = "date";
|
|
7
|
+
PropertyType["Time"] = "time";
|
|
8
|
+
PropertyType["Object"] = "object";
|
|
9
|
+
PropertyType["StringArray"] = "stringArray";
|
|
10
|
+
PropertyType["NumberArray"] = "numberArray";
|
|
11
|
+
PropertyType["ObjectArray"] = "objectArray";
|
|
12
|
+
})(PropertyType || (PropertyType = {}));
|
|
13
|
+
|
|
14
|
+
export { PropertyType };
|
|
15
|
+
//# sourceMappingURL=PropertyType.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PropertyType.js","sources":["../../../../SchemaEditor/Tree/PropertyType.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\n/** The kinds of value a {@link Property} can hold. */\nexport enum PropertyType {\n /** Text. */\n String = 'string',\n /** A number, integer or fractional. */\n Number = 'number',\n /** A true or false value. */\n Boolean = 'boolean',\n /** A calendar date. */\n Date = 'date',\n /** A time of day. */\n Time = 'time',\n /** A nested object with its own properties. */\n Object = 'object',\n /** A list of text values. */\n StringArray = 'stringArray',\n /** A list of numbers. */\n NumberArray = 'numberArray',\n /** A list of nested objects, each with the same properties. */\n ObjectArray = 'objectArray',\n}\n"],"names":[],"mappings":"IAIY;AAAZ,CAAA,UAAY,YAAY,EAAA;AAEpB,IAAA,YAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AAEjB,IAAA,YAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AAEjB,IAAA,YAAA,CAAA,SAAA,CAAA,GAAA,SAAmB;AAEnB,IAAA,YAAA,CAAA,MAAA,CAAA,GAAA,MAAa;AAEb,IAAA,YAAA,CAAA,MAAA,CAAA,GAAA,MAAa;AAEb,IAAA,YAAA,CAAA,QAAA,CAAA,GAAA,QAAiB;AAEjB,IAAA,YAAA,CAAA,aAAA,CAAA,GAAA,aAA2B;AAE3B,IAAA,YAAA,CAAA,aAAA,CAAA,GAAA,aAA2B;AAE3B,IAAA,YAAA,CAAA,aAAA,CAAA,GAAA,aAA2B;AAC/B,CAAC,EAnBW,YAAY,KAAZ,YAAY,GAAA,EAAA,CAAA,CAAA;;"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Property } from './Property.js';
|
|
2
|
+
import type { SchemaEditorLabels } from '../SchemaEditorLabels.js';
|
|
3
|
+
import type { SchemaEditorPartAttributes } from './SchemaEditorParts.js';
|
|
4
|
+
/** Props for the type badge of a property. */
|
|
5
|
+
export interface PropertyTypeBadgeProps {
|
|
6
|
+
/** The property whose type is shown. */
|
|
7
|
+
property: Pick<Property, 'type' | 'concept'>;
|
|
8
|
+
/** The resolved labels. */
|
|
9
|
+
labels: Required<SchemaEditorLabels>;
|
|
10
|
+
/** Attributes for the `badge` part. */
|
|
11
|
+
part?: SchemaEditorPartAttributes<HTMLSpanElement>;
|
|
12
|
+
/** Why the type is locked; shown as the badge's tooltip and exposed as its accessible description. */
|
|
13
|
+
lockReason?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Shows what a property is typed as: a short glyph for the primitive, followed by the concept's name when the
|
|
17
|
+
* property is typed as a concept, or the type's name when it is not. The glyph is decorative.
|
|
18
|
+
*/
|
|
19
|
+
export declare const PropertyTypeBadge: ({ property, labels, part, lockReason }: PropertyTypeBadgeProps) => import("react").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=PropertyTypeBadge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PropertyTypeBadge.d.ts","sourceRoot":"","sources":["../../../../SchemaEditor/Tree/PropertyTypeBadge.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,wBAAqB,CAAC;AAItE,8CAA8C;AAC9C,MAAM,WAAW,sBAAsB;IACnC,wCAAwC;IACxC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IAE7C,2BAA2B;IAC3B,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAErC,uCAAuC;IACvC,IAAI,CAAC,EAAE,0BAA0B,CAAC,eAAe,CAAC,CAAC;IAEnD,sGAAsG;IACtG,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,2CAA4C,sBAAsB,gCAkB/F,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useId } from 'react';
|
|
3
|
+
import { propertyTypeName } from './propertyTypeDisplay.js';
|
|
4
|
+
import { PropertyTypeGlyph } from './PropertyTypeGlyph.js';
|
|
5
|
+
|
|
6
|
+
const PropertyTypeBadge = ({ property, labels, part, lockReason }) => {
|
|
7
|
+
const reasonId = useId();
|
|
8
|
+
return (jsxs("span", { ...part, title: lockReason ?? part?.title, "aria-describedby": lockReason ? reasonId : part?.['aria-describedby'], className: `cratis-schema-editor__badge ${part?.className ?? ''}`, "data-cratis-part": 'badge', "data-property-type": property.type, "data-concept": property.concept ? true : undefined, "data-locked": lockReason ? true : undefined, children: [jsx(PropertyTypeGlyph, { type: property.type }), jsx("span", { className: 'cratis-schema-editor__badge-name', children: property.concept ?? propertyTypeName(property.type, labels) }), lockReason && jsx("span", { id: reasonId, className: 'cratis-schema-editor__visually-hidden', children: lockReason })] }));
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { PropertyTypeBadge };
|
|
12
|
+
//# sourceMappingURL=PropertyTypeBadge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PropertyTypeBadge.js","sources":["../../../../SchemaEditor/Tree/PropertyTypeBadge.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { useId } from 'react';\nimport type { Property } from './Property';\nimport type { SchemaEditorLabels } from '../SchemaEditorLabels';\nimport type { SchemaEditorPartAttributes } from './SchemaEditorParts';\nimport { propertyTypeName } from './propertyTypeDisplay';\nimport { PropertyTypeGlyph } from './PropertyTypeGlyph';\n\n/** Props for the type badge of a property. */\nexport interface PropertyTypeBadgeProps {\n /** The property whose type is shown. */\n property: Pick<Property, 'type' | 'concept'>;\n\n /** The resolved labels. */\n labels: Required<SchemaEditorLabels>;\n\n /** Attributes for the `badge` part. */\n part?: SchemaEditorPartAttributes<HTMLSpanElement>;\n\n /** Why the type is locked; shown as the badge's tooltip and exposed as its accessible description. */\n lockReason?: string;\n}\n\n/**\n * Shows what a property is typed as: a short glyph for the primitive, followed by the concept's name when the\n * property is typed as a concept, or the type's name when it is not. The glyph is decorative.\n */\nexport const PropertyTypeBadge = ({ property, labels, part, lockReason }: PropertyTypeBadgeProps) => {\n const reasonId = useId();\n return (\n <span\n {...part}\n title={lockReason ?? part?.title}\n aria-describedby={lockReason ? reasonId : part?.['aria-describedby']}\n className={`cratis-schema-editor__badge ${part?.className ?? ''}`}\n data-cratis-part='badge'\n data-property-type={property.type}\n data-concept={property.concept ? true : undefined}\n data-locked={lockReason ? true : undefined}\n >\n <PropertyTypeGlyph type={property.type} />\n <span className='cratis-schema-editor__badge-name'>{property.concept ?? propertyTypeName(property.type, labels)}</span>\n {lockReason && <span id={reasonId} className='cratis-schema-editor__visually-hidden'>{lockReason}</span>}\n </span>\n );\n};\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;AA6BO,MAAM,iBAAiB,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAA0B,KAAI;AAChG,IAAA,MAAM,QAAQ,GAAG,KAAK,EAAE;IACxB,QACIA,IAAA,CAAA,MAAA,EAAA,EAAA,GACQ,IAAI,EACR,KAAK,EAAE,UAAU,IAAI,IAAI,EAAE,KAAK,EAAA,kBAAA,EACd,UAAU,GAAG,QAAQ,GAAG,IAAI,GAAG,kBAAkB,CAAC,EACpE,SAAS,EAAE,CAAA,4BAAA,EAA+B,IAAI,EAAE,SAAS,IAAI,EAAE,CAAA,CAAE,EAAA,kBAAA,EAChD,OAAO,EAAA,oBAAA,EACJ,QAAQ,CAAC,IAAI,EAAA,cAAA,EACnB,QAAQ,CAAC,OAAO,GAAG,IAAI,GAAG,SAAS,EAAA,aAAA,EACpC,UAAU,GAAG,IAAI,GAAG,SAAS,EAAA,QAAA,EAAA,CAE1CC,GAAA,CAAC,iBAAiB,EAAA,EAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAA,CAAI,EAC1CA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,kCAAkC,EAAA,QAAA,EAAE,QAAQ,CAAC,OAAO,IAAI,gBAAgB,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,EAAA,CAAQ,EACtH,UAAU,IAAIA,GAAA,CAAA,MAAA,EAAA,EAAM,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAC,uCAAuC,YAAE,UAAU,EAAA,CAAQ,CAAA,EAAA,CACrG;AAEf;;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { PropertyType } from './PropertyType.js';
|
|
2
|
+
/** Props for the glyph of a property type. */
|
|
3
|
+
export interface PropertyTypeGlyphProps {
|
|
4
|
+
/** The type whose glyph is shown. */
|
|
5
|
+
type: PropertyType;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A short colored chip identifying a property type at a glance. It is decorative: the type's name is always
|
|
9
|
+
* next to it, so it is hidden from assistive technology.
|
|
10
|
+
*/
|
|
11
|
+
export declare const PropertyTypeGlyph: ({ type }: PropertyTypeGlyphProps) => import("react").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=PropertyTypeGlyph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PropertyTypeGlyph.d.ts","sourceRoot":"","sources":["../../../../SchemaEditor/Tree/PropertyTypeGlyph.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAgB,CAAC;AAoC9C,8CAA8C;AAC9C,MAAM,WAAW,sBAAsB;IACnC,qCAAqC;IACrC,IAAI,EAAE,YAAY,CAAC;CACtB;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,aAAc,sBAAsB,gCAEjE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { PropertyType } from './PropertyType.js';
|
|
3
|
+
|
|
4
|
+
const iconProps = {
|
|
5
|
+
viewBox: '0 0 12 12',
|
|
6
|
+
fill: 'none',
|
|
7
|
+
stroke: 'currentColor',
|
|
8
|
+
strokeWidth: 1.5,
|
|
9
|
+
strokeLinecap: 'round',
|
|
10
|
+
strokeLinejoin: 'round',
|
|
11
|
+
width: 11,
|
|
12
|
+
height: 11,
|
|
13
|
+
'aria-hidden': true,
|
|
14
|
+
};
|
|
15
|
+
const glyphs = {
|
|
16
|
+
[PropertyType.String]: 'Aa',
|
|
17
|
+
[PropertyType.Number]: '123',
|
|
18
|
+
[PropertyType.Boolean]: 'T/F',
|
|
19
|
+
[PropertyType.Date]: (jsxs("svg", { ...iconProps, children: [jsx("rect", { x: '1', y: '2.5', width: '10', height: '8.5', rx: '1.5' }), jsx("path", { d: 'M1 5.5h10M4 1v3M8 1v3' })] })),
|
|
20
|
+
[PropertyType.Time]: (jsxs("svg", { ...iconProps, children: [jsx("circle", { cx: '6', cy: '6', r: '4.5' }), jsx("path", { d: 'M6 3.5v2.5l2 1' })] })),
|
|
21
|
+
[PropertyType.Object]: '{}',
|
|
22
|
+
[PropertyType.StringArray]: '[A]',
|
|
23
|
+
[PropertyType.NumberArray]: '[#]',
|
|
24
|
+
[PropertyType.ObjectArray]: '[{}]',
|
|
25
|
+
};
|
|
26
|
+
const PropertyTypeGlyph = ({ type }) => (jsx("span", { className: 'cratis-schema-editor__badge-glyph', "data-property-type": type, "aria-hidden": 'true', children: glyphs[type] }));
|
|
27
|
+
|
|
28
|
+
export { PropertyTypeGlyph };
|
|
29
|
+
//# sourceMappingURL=PropertyTypeGlyph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PropertyTypeGlyph.js","sources":["../../../../SchemaEditor/Tree/PropertyTypeGlyph.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { PropertyType } from './PropertyType';\n\nconst iconProps = {\n viewBox: '0 0 12 12',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 1.5,\n strokeLinecap: 'round',\n strokeLinejoin: 'round',\n width: 11,\n height: 11,\n 'aria-hidden': true,\n} as const;\n\nconst glyphs: Record<PropertyType, React.ReactNode> = {\n [PropertyType.String]: 'Aa',\n [PropertyType.Number]: '123',\n [PropertyType.Boolean]: 'T/F',\n [PropertyType.Date]: (\n <svg {...iconProps}>\n <rect x='1' y='2.5' width='10' height='8.5' rx='1.5' />\n <path d='M1 5.5h10M4 1v3M8 1v3' />\n </svg>\n ),\n [PropertyType.Time]: (\n <svg {...iconProps}>\n <circle cx='6' cy='6' r='4.5' />\n <path d='M6 3.5v2.5l2 1' />\n </svg>\n ),\n [PropertyType.Object]: '{}',\n [PropertyType.StringArray]: '[A]',\n [PropertyType.NumberArray]: '[#]',\n [PropertyType.ObjectArray]: '[{}]',\n};\n\n/** Props for the glyph of a property type. */\nexport interface PropertyTypeGlyphProps {\n /** The type whose glyph is shown. */\n type: PropertyType;\n}\n\n/**\n * A short colored chip identifying a property type at a glance. It is decorative: the type's name is always\n * next to it, so it is hidden from assistive technology.\n */\nexport const PropertyTypeGlyph = ({ type }: PropertyTypeGlyphProps) => (\n <span className='cratis-schema-editor__badge-glyph' data-property-type={type} aria-hidden='true'>{glyphs[type]}</span>\n);\n"],"names":["_jsxs","_jsx"],"mappings":";;;AAKA,MAAM,SAAS,GAAG;AACd,IAAA,OAAO,EAAE,WAAW;AACpB,IAAA,IAAI,EAAE,MAAM;AACZ,IAAA,MAAM,EAAE,cAAc;AACtB,IAAA,WAAW,EAAE,GAAG;AAChB,IAAA,aAAa,EAAE,OAAO;AACtB,IAAA,cAAc,EAAE,OAAO;AACvB,IAAA,KAAK,EAAE,EAAE;AACT,IAAA,MAAM,EAAE,EAAE;AACV,IAAA,aAAa,EAAE,IAAI;CACb;AAEV,MAAM,MAAM,GAA0C;AAClD,IAAA,CAAC,YAAY,CAAC,MAAM,GAAG,IAAI;AAC3B,IAAA,CAAC,YAAY,CAAC,MAAM,GAAG,KAAK;AAC5B,IAAA,CAAC,YAAY,CAAC,OAAO,GAAG,KAAK;AAC7B,IAAA,CAAC,YAAY,CAAC,IAAI,IACdA,IAAA,CAAA,KAAA,EAAA,EAAA,GAAS,SAAS,EAAA,QAAA,EAAA,CACdC,GAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,GAAG,EAAC,CAAC,EAAC,KAAK,EAAC,KAAK,EAAC,IAAI,EAAC,MAAM,EAAC,KAAK,EAAC,EAAE,EAAC,KAAK,EAAA,CAAG,EACvDA,GAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,uBAAuB,EAAA,CAAG,IAChC,CACT;AACD,IAAA,CAAC,YAAY,CAAC,IAAI,IACdD,IAAA,CAAA,KAAA,EAAA,EAAA,GAAS,SAAS,EAAA,QAAA,EAAA,CACdC,GAAA,CAAA,QAAA,EAAA,EAAQ,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,CAAC,EAAC,KAAK,EAAA,CAAG,EAChCA,GAAA,CAAA,MAAA,EAAA,EAAM,CAAC,EAAC,gBAAgB,EAAA,CAAG,IACzB,CACT;AACD,IAAA,CAAC,YAAY,CAAC,MAAM,GAAG,IAAI;AAC3B,IAAA,CAAC,YAAY,CAAC,WAAW,GAAG,KAAK;AACjC,IAAA,CAAC,YAAY,CAAC,WAAW,GAAG,KAAK;AACjC,IAAA,CAAC,YAAY,CAAC,WAAW,GAAG,MAAM;CACrC;AAYM,MAAM,iBAAiB,GAAG,CAAC,EAAE,IAAI,EAA0B,MAC9DA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAC,mCAAmC,EAAA,oBAAA,EAAqB,IAAI,EAAA,aAAA,EAAc,MAAM,EAAA,QAAA,EAAE,MAAM,CAAC,IAAI,CAAC,EAAA,CAAQ;;"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { PropertyConcept } from './PropertyConcept.js';
|
|
3
|
+
import type { PropertyType } from './PropertyType.js';
|
|
4
|
+
import type { SchemaEditorLabels } from '../SchemaEditorLabels.js';
|
|
5
|
+
import type { SchemaEditorParts } from './SchemaEditorParts.js';
|
|
6
|
+
/** Props for the menu of types the editor offers when adding a property or changing its type. */
|
|
7
|
+
export interface PropertyTypeMenuProps {
|
|
8
|
+
/** The resolved labels. */
|
|
9
|
+
labels: Required<SchemaEditorLabels>;
|
|
10
|
+
/** The concepts offered after the primitive types. `undefined` when the host has not opted into concepts; an empty list shows a disabled hint. */
|
|
11
|
+
concepts: PropertyConcept[] | undefined;
|
|
12
|
+
/** The part of the editor the trigger button is: the add button or the row's type button. */
|
|
13
|
+
triggerPart: 'add' | 'typeButton';
|
|
14
|
+
/** The accessible name of the trigger. */
|
|
15
|
+
triggerLabel: string;
|
|
16
|
+
/** The content of the trigger. */
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
/** The parts the host styles. */
|
|
19
|
+
parts: SchemaEditorParts | undefined;
|
|
20
|
+
/** Called with the chosen type, and the concept's name when a concept was chosen. */
|
|
21
|
+
onSelect: (type: PropertyType, concept?: string) => void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The accessible menu of types: the primitives, the concepts of the domain, then the composite types. It is a
|
|
25
|
+
* React Aria menu in a popover, so it handles keyboard navigation, typeahead, focus return and dismissal.
|
|
26
|
+
*/
|
|
27
|
+
export declare const PropertyTypeMenu: ({ labels, concepts, triggerPart, triggerLabel, children, parts, onSelect }: PropertyTypeMenuProps) => import("react").JSX.Element;
|
|
28
|
+
//# sourceMappingURL=PropertyTypeMenu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PropertyTypeMenu.d.ts","sourceRoot":"","sources":["../../../../SchemaEditor/Tree/PropertyTypeMenu.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAgD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAQrF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAgB,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAqB,CAAC;AAO7D,iGAAiG;AACjG,MAAM,WAAW,qBAAqB;IAClC,2BAA2B;IAC3B,MAAM,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAErC,kJAAkJ;IAClJ,QAAQ,EAAE,eAAe,EAAE,GAAG,SAAS,CAAC;IAExC,6FAA6F;IAC7F,WAAW,EAAE,KAAK,GAAG,YAAY,CAAC;IAElC,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;IAErB,kCAAkC;IAClC,QAAQ,EAAE,SAAS,CAAC;IAEpB,iCAAiC;IACjC,KAAK,EAAE,iBAAiB,GAAG,SAAS,CAAC;IAErC,qFAAqF;IACrF,QAAQ,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5D;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,+EAAgF,qBAAqB,gCA0FjI,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { UNSAFE_PortalProvider } from 'react-aria';
|
|
4
|
+
import { Button } from 'react-aria-components/Button';
|
|
5
|
+
import { MenuTrigger, Popover, Menu, MenuSection, Header, MenuItem, Separator } from 'react-aria-components/Menu';
|
|
6
|
+
import { asReactAriaButtonProps } from '../../Common/reactAriaProps.js';
|
|
7
|
+
import { zIndexAboveDialog, OVERLAY_OFFSET } from '../../renderer/dialogStack.js';
|
|
8
|
+
import { useNearestDialogZIndex } from '../../renderer/DialogStackContext.js';
|
|
9
|
+
import { unstable_useOverlayEnvironment } from '../../renderer/RendererContext.js';
|
|
10
|
+
import { primitivePropertyTypes, compositePropertyTypes, propertyTypeName } from './propertyTypeDisplay.js';
|
|
11
|
+
import { PropertyTypeGlyph } from './PropertyTypeGlyph.js';
|
|
12
|
+
|
|
13
|
+
const typePrefix = 'type:';
|
|
14
|
+
const conceptPrefix = 'concept:';
|
|
15
|
+
const PropertyTypeMenu = ({ labels, concepts, triggerPart, triggerLabel, children, parts, onSelect }) => {
|
|
16
|
+
const overlayEnvironment = unstable_useOverlayEnvironment();
|
|
17
|
+
const nearestDialogZIndex = useNearestDialogZIndex();
|
|
18
|
+
const zIndex = nearestDialogZIndex === null
|
|
19
|
+
? 'var(--cratis-z-index-overlay)'
|
|
20
|
+
: zIndexAboveDialog(nearestDialogZIndex, OVERLAY_OFFSET);
|
|
21
|
+
const sortedConcepts = useMemo(() => [...(concepts ?? [])].sort((left, right) => left.name.localeCompare(right.name)), [concepts]);
|
|
22
|
+
const handleAction = (key) => {
|
|
23
|
+
const identifier = String(key);
|
|
24
|
+
if (identifier.startsWith(conceptPrefix)) {
|
|
25
|
+
const concept = sortedConcepts.find(candidate => candidate.name === identifier.slice(conceptPrefix.length));
|
|
26
|
+
if (concept)
|
|
27
|
+
onSelect(concept.type, concept.name);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
onSelect(identifier.slice(typePrefix.length));
|
|
31
|
+
};
|
|
32
|
+
const typeItem = (type) => (jsxs(MenuItem, { id: `${typePrefix}${type}`, textValue: propertyTypeName(type, labels), className: `cratis-schema-editor__menu-item ${parts?.menuItem?.className ?? ''}`, "data-cratis-part": 'menuItem', children: [jsx(PropertyTypeGlyph, { type: type }), propertyTypeName(type, labels)] }, type));
|
|
33
|
+
const triggerAttributes = parts?.[triggerPart];
|
|
34
|
+
return (jsx(UNSAFE_PortalProvider, { getContainer: overlayEnvironment.getContainer, children: jsxs(MenuTrigger, { children: [jsx(Button, { ...asReactAriaButtonProps(triggerAttributes), "aria-label": triggerLabel, className: `cratis-schema-editor__${triggerPart === 'add' ? 'add' : 'type-button'} ${triggerAttributes?.className ?? ''}`, "data-cratis-part": triggerPart === 'add' ? 'add' : 'typeButton', children: children }), jsx(Popover, { ...parts?.menu, className: `cratis-schema-editor__menu ${parts?.menu?.className ?? ''}`, style: { zIndex, ...parts?.menu?.style }, "data-cratis-part": 'menu', children: jsxs(Menu, { "aria-label": labels.propertyTypes, onAction: handleAction, className: 'cratis-schema-editor__menu-list', children: [primitivePropertyTypes.map(typeItem), concepts !== undefined && (jsxs(MenuSection, { className: 'cratis-schema-editor__menu-section', children: [jsx(Header, { className: 'cratis-schema-editor__menu-heading', children: labels.concepts }), sortedConcepts.length === 0 && (jsx(MenuItem, { id: 'concept-hint', isDisabled: true, textValue: labels.noConcepts, className: `cratis-schema-editor__menu-item cratis-schema-editor__menu-hint ${parts?.menuItem?.className ?? ''}`, "data-cratis-part": 'menuItem', children: labels.noConcepts })), sortedConcepts.map(concept => (jsxs(MenuItem, { id: `${conceptPrefix}${concept.name}`, textValue: concept.name, className: `cratis-schema-editor__menu-item ${parts?.menuItem?.className ?? ''}`, "data-cratis-part": 'menuItem', children: [jsx(PropertyTypeGlyph, { type: concept.type }), concept.name] }, concept.name)))] })), jsx(Separator, { className: 'cratis-schema-editor__menu-separator' }), compositePropertyTypes.map(typeItem)] }) })] }) }));
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export { PropertyTypeMenu };
|
|
38
|
+
//# sourceMappingURL=PropertyTypeMenu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PropertyTypeMenu.js","sources":["../../../../SchemaEditor/Tree/PropertyTypeMenu.tsx"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { useMemo, type ButtonHTMLAttributes, type Key, type ReactNode } from 'react';\nimport { UNSAFE_PortalProvider } from 'react-aria';\nimport { Button as AriaButton } from 'react-aria-components/Button';\nimport { Header, Menu, MenuItem, MenuSection, MenuTrigger, Popover, Separator } from 'react-aria-components/Menu';\nimport { asReactAriaButtonProps } from '../../Common/reactAriaProps';\nimport { OVERLAY_OFFSET, zIndexAboveDialog } from '../../renderer/dialogStack';\nimport { useNearestDialogZIndex } from '../../renderer/DialogStackContext';\nimport { unstable_useOverlayEnvironment } from '../../renderer/RendererContext';\nimport type { PropertyConcept } from './PropertyConcept';\nimport type { PropertyType } from './PropertyType';\nimport type { SchemaEditorLabels } from '../SchemaEditorLabels';\nimport type { SchemaEditorParts } from './SchemaEditorParts';\nimport { compositePropertyTypes, primitivePropertyTypes, propertyTypeName } from './propertyTypeDisplay';\nimport { PropertyTypeGlyph } from './PropertyTypeGlyph';\n\nconst typePrefix = 'type:';\nconst conceptPrefix = 'concept:';\n\n/** Props for the menu of types the editor offers when adding a property or changing its type. */\nexport interface PropertyTypeMenuProps {\n /** The resolved labels. */\n labels: Required<SchemaEditorLabels>;\n\n /** The concepts offered after the primitive types. `undefined` when the host has not opted into concepts; an empty list shows a disabled hint. */\n concepts: PropertyConcept[] | undefined;\n\n /** The part of the editor the trigger button is: the add button or the row's type button. */\n triggerPart: 'add' | 'typeButton';\n\n /** The accessible name of the trigger. */\n triggerLabel: string;\n\n /** The content of the trigger. */\n children: ReactNode;\n\n /** The parts the host styles. */\n parts: SchemaEditorParts | undefined;\n\n /** Called with the chosen type, and the concept's name when a concept was chosen. */\n onSelect: (type: PropertyType, concept?: string) => void;\n}\n\n/**\n * The accessible menu of types: the primitives, the concepts of the domain, then the composite types. It is a\n * React Aria menu in a popover, so it handles keyboard navigation, typeahead, focus return and dismissal.\n */\nexport const PropertyTypeMenu = ({ labels, concepts, triggerPart, triggerLabel, children, parts, onSelect }: PropertyTypeMenuProps) => {\n const overlayEnvironment = unstable_useOverlayEnvironment();\n const nearestDialogZIndex = useNearestDialogZIndex();\n const zIndex = nearestDialogZIndex === null\n ? 'var(--cratis-z-index-overlay)'\n : zIndexAboveDialog(nearestDialogZIndex, OVERLAY_OFFSET);\n\n const sortedConcepts = useMemo(\n () => [...(concepts ?? [])].sort((left, right) => left.name.localeCompare(right.name)),\n [concepts]);\n\n const handleAction = (key: Key) => {\n const identifier = String(key);\n if (identifier.startsWith(conceptPrefix)) {\n const concept = sortedConcepts.find(candidate => candidate.name === identifier.slice(conceptPrefix.length));\n if (concept) onSelect(concept.type, concept.name);\n return;\n }\n onSelect(identifier.slice(typePrefix.length) as PropertyType);\n };\n\n const typeItem = (type: PropertyType) => (\n <MenuItem\n key={type}\n id={`${typePrefix}${type}`}\n textValue={propertyTypeName(type, labels)}\n className={`cratis-schema-editor__menu-item ${parts?.menuItem?.className ?? ''}`}\n data-cratis-part='menuItem'\n >\n <PropertyTypeGlyph type={type} />\n {propertyTypeName(type, labels)}\n </MenuItem>\n );\n\n const triggerAttributes: ButtonHTMLAttributes<HTMLButtonElement> | undefined = parts?.[triggerPart];\n\n return (\n <UNSAFE_PortalProvider getContainer={overlayEnvironment.getContainer}>\n <MenuTrigger>\n <AriaButton\n {...asReactAriaButtonProps(triggerAttributes)}\n aria-label={triggerLabel}\n className={`cratis-schema-editor__${triggerPart === 'add' ? 'add' : 'type-button'} ${triggerAttributes?.className ?? ''}`}\n data-cratis-part={triggerPart === 'add' ? 'add' : 'typeButton'}\n >\n {children}\n </AriaButton>\n <Popover\n {...parts?.menu}\n className={`cratis-schema-editor__menu ${parts?.menu?.className ?? ''}`}\n style={{ zIndex, ...parts?.menu?.style } as React.CSSProperties}\n data-cratis-part='menu'\n >\n <Menu aria-label={labels.propertyTypes} onAction={handleAction} className='cratis-schema-editor__menu-list'>\n {primitivePropertyTypes.map(typeItem)}\n {concepts !== undefined && (\n <MenuSection className='cratis-schema-editor__menu-section'>\n <Header className='cratis-schema-editor__menu-heading'>{labels.concepts}</Header>\n {sortedConcepts.length === 0 && (\n <MenuItem\n id='concept-hint'\n isDisabled\n textValue={labels.noConcepts}\n className={`cratis-schema-editor__menu-item cratis-schema-editor__menu-hint ${parts?.menuItem?.className ?? ''}`}\n data-cratis-part='menuItem'\n >\n {labels.noConcepts}\n </MenuItem>\n )}\n {sortedConcepts.map(concept => (\n <MenuItem\n key={concept.name}\n id={`${conceptPrefix}${concept.name}`}\n textValue={concept.name}\n className={`cratis-schema-editor__menu-item ${parts?.menuItem?.className ?? ''}`}\n data-cratis-part='menuItem'\n >\n <PropertyTypeGlyph type={concept.type} />\n {concept.name}\n </MenuItem>\n ))}\n </MenuSection>\n )}\n <Separator className='cratis-schema-editor__menu-separator' />\n {compositePropertyTypes.map(typeItem)}\n </Menu>\n </Popover>\n </MenuTrigger>\n </UNSAFE_PortalProvider>\n );\n};\n"],"names":["_jsxs","_jsx","AriaButton"],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { Property } from './Property.js';
|
|
3
|
+
import type { PropertyConcept } from './PropertyConcept.js';
|
|
4
|
+
import type { PropertyType } from './PropertyType.js';
|
|
5
|
+
import type { SchemaEditorLabels } from '../SchemaEditorLabels.js';
|
|
6
|
+
import type { SchemaEditorParts } from './SchemaEditorParts.js';
|
|
7
|
+
import type { SchemaPropertyContext } from './SchemaPropertyContext.js';
|
|
8
|
+
import type { SchemaPropertyRowState } from './SchemaPropertyRowState.js';
|
|
9
|
+
/** The edits the editor can currently perform. An edit that is `undefined` is not offered. */
|
|
10
|
+
export interface SchemaEditorOperations {
|
|
11
|
+
addChild?: (parentId: string, type: PropertyType, concept?: string) => void;
|
|
12
|
+
remove?: (propertyId: string) => void;
|
|
13
|
+
rename?: (propertyId: string, name: string) => void;
|
|
14
|
+
changeType?: (propertyId: string, type: PropertyType, concept?: string) => void;
|
|
15
|
+
setKey?: (propertyId: string) => void;
|
|
16
|
+
setRequired?: (propertyId: string, isRequired: boolean) => void;
|
|
17
|
+
}
|
|
18
|
+
/** Everything the rows of an editor share. Internal: hosts configure the editor through its props. */
|
|
19
|
+
export interface SchemaEditorContextValue {
|
|
20
|
+
labels: Required<SchemaEditorLabels>;
|
|
21
|
+
parts: SchemaEditorParts | undefined;
|
|
22
|
+
properties: Property[];
|
|
23
|
+
concepts: PropertyConcept[] | undefined;
|
|
24
|
+
readOnly: boolean;
|
|
25
|
+
operations: SchemaEditorOperations;
|
|
26
|
+
selectedPropertyId: string | null | undefined;
|
|
27
|
+
onPropertyClick: ((propertyId: string) => void) | undefined;
|
|
28
|
+
isKeyAllowed: (property: Property, context: SchemaPropertyContext) => boolean;
|
|
29
|
+
isRequiredAllowed: boolean;
|
|
30
|
+
isProtected: (property: Property) => boolean;
|
|
31
|
+
validateName: ((name: string, property: Property, siblings: Property[]) => string | undefined) | undefined;
|
|
32
|
+
getRowState: ((property: Property, context: SchemaPropertyContext) => SchemaPropertyRowState | undefined) | undefined;
|
|
33
|
+
renderLeading: ((property: Property, context: SchemaPropertyContext) => ReactNode) | undefined;
|
|
34
|
+
renderAccessory: ((property: Property, context: SchemaPropertyContext) => ReactNode) | undefined;
|
|
35
|
+
renderDetails: ((property: Property, context: SchemaPropertyContext) => ReactNode) | undefined;
|
|
36
|
+
renderTypeBadge: ((property: Property, context: SchemaPropertyContext, defaultBadge: ReactNode) => ReactNode) | undefined;
|
|
37
|
+
}
|
|
38
|
+
/** Carries the editor's shared configuration to its rows. */
|
|
39
|
+
export declare const SchemaEditorContext: import("react").Context<SchemaEditorContextValue | undefined>;
|
|
40
|
+
/** Reads the editor's shared configuration. Rows only render inside an editor. */
|
|
41
|
+
export declare const useSchemaEditorContext: () => SchemaEditorContextValue;
|
|
42
|
+
//# sourceMappingURL=SchemaEditorContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaEditorContext.d.ts","sourceRoot":"","sources":["../../../../SchemaEditor/Tree/SchemaEditorContext.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
const SchemaEditorContext = createContext(undefined);
|
|
4
|
+
const useSchemaEditorContext = () => {
|
|
5
|
+
const value = useContext(SchemaEditorContext);
|
|
6
|
+
if (!value)
|
|
7
|
+
throw new Error('A schema property row must be rendered inside a SchemaEditor.');
|
|
8
|
+
return value;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export { SchemaEditorContext, useSchemaEditorContext };
|
|
12
|
+
//# sourceMappingURL=SchemaEditorContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaEditorContext.js","sources":["../../../../SchemaEditor/Tree/SchemaEditorContext.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { createContext, useContext, type ReactNode } from 'react';\nimport type { Property } from './Property';\nimport type { PropertyConcept } from './PropertyConcept';\nimport type { PropertyType } from './PropertyType';\nimport type { SchemaEditorLabels } from '../SchemaEditorLabels';\nimport type { SchemaEditorParts } from './SchemaEditorParts';\nimport type { SchemaPropertyContext } from './SchemaPropertyContext';\nimport type { SchemaPropertyRowState } from './SchemaPropertyRowState';\n\n/** The edits the editor can currently perform. An edit that is `undefined` is not offered. */\nexport interface SchemaEditorOperations {\n addChild?: (parentId: string, type: PropertyType, concept?: string) => void;\n remove?: (propertyId: string) => void;\n rename?: (propertyId: string, name: string) => void;\n changeType?: (propertyId: string, type: PropertyType, concept?: string) => void;\n setKey?: (propertyId: string) => void;\n setRequired?: (propertyId: string, isRequired: boolean) => void;\n}\n\n/** Everything the rows of an editor share. Internal: hosts configure the editor through its props. */\nexport interface SchemaEditorContextValue {\n labels: Required<SchemaEditorLabels>;\n parts: SchemaEditorParts | undefined;\n properties: Property[];\n concepts: PropertyConcept[] | undefined;\n readOnly: boolean;\n operations: SchemaEditorOperations;\n selectedPropertyId: string | null | undefined;\n onPropertyClick: ((propertyId: string) => void) | undefined;\n isKeyAllowed: (property: Property, context: SchemaPropertyContext) => boolean;\n isRequiredAllowed: boolean;\n isProtected: (property: Property) => boolean;\n validateName: ((name: string, property: Property, siblings: Property[]) => string | undefined) | undefined;\n getRowState: ((property: Property, context: SchemaPropertyContext) => SchemaPropertyRowState | undefined) | undefined;\n renderLeading: ((property: Property, context: SchemaPropertyContext) => ReactNode) | undefined;\n renderAccessory: ((property: Property, context: SchemaPropertyContext) => ReactNode) | undefined;\n renderDetails: ((property: Property, context: SchemaPropertyContext) => ReactNode) | undefined;\n renderTypeBadge: ((property: Property, context: SchemaPropertyContext, defaultBadge: ReactNode) => ReactNode) | undefined;\n}\n\n/** Carries the editor's shared configuration to its rows. */\nexport const SchemaEditorContext = createContext<SchemaEditorContextValue | undefined>(undefined);\n\n/** Reads the editor's shared configuration. Rows only render inside an editor. */\nexport const useSchemaEditorContext = (): SchemaEditorContextValue => {\n const value = useContext(SchemaEditorContext);\n if (!value) throw new Error('A schema property row must be rendered inside a SchemaEditor.');\n return value;\n};\n"],"names":[],"mappings":";;MA4Ca,mBAAmB,GAAG,aAAa,CAAuC,SAAS;AAGzF,MAAM,sBAAsB,GAAG,MAA+B;AACjE,IAAA,MAAM,KAAK,GAAG,UAAU,CAAC,mBAAmB,CAAC;AAC7C,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC;AAC5F,IAAA,OAAO,KAAK;AAChB;;"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { ButtonHTMLAttributes, HTMLAttributes, InputHTMLAttributes } from 'react';
|
|
2
|
+
/** Attributes passed through to one part of the editor, including `data-*` attributes. */
|
|
3
|
+
export type SchemaEditorPartAttributes<TElement> = HTMLAttributes<TElement> & {
|
|
4
|
+
[attribute: `data-${string}`]: string | number | boolean | undefined;
|
|
5
|
+
};
|
|
6
|
+
/** Styling attributes passed to a part the editor renders through a popover menu. */
|
|
7
|
+
export type SchemaEditorMenuPartAttributes = Pick<HTMLAttributes<HTMLElement>, 'className' | 'style'> & {
|
|
8
|
+
[attribute: `data-${string}`]: string | number | boolean | undefined;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Stable Cratis-owned parts for styling a {@link SchemaEditor}. Each is marked with a matching
|
|
12
|
+
* `data-cratis-part` attribute and receives what is passed here; the editor's own wiring wins.
|
|
13
|
+
*/
|
|
14
|
+
export interface SchemaEditorParts {
|
|
15
|
+
/** The editor root. Carries `data-readonly` while the editor is read-only. */
|
|
16
|
+
root?: SchemaEditorPartAttributes<HTMLDivElement>;
|
|
17
|
+
/** The wrapper of the host's `header`. */
|
|
18
|
+
header?: SchemaEditorPartAttributes<HTMLDivElement>;
|
|
19
|
+
/** A list of properties: the root list, or the properties nested under a property. */
|
|
20
|
+
list?: SchemaEditorPartAttributes<HTMLUListElement>;
|
|
21
|
+
/** One property with everything nested under it. Carries `data-property-type`. */
|
|
22
|
+
property?: SchemaEditorPartAttributes<HTMLLIElement>;
|
|
23
|
+
/** The row of one property. Carries `data-selected` while the host marks it selected. */
|
|
24
|
+
row?: SchemaEditorPartAttributes<HTMLDivElement>;
|
|
25
|
+
/** The wrapper of the host's leading slot. */
|
|
26
|
+
leading?: SchemaEditorPartAttributes<HTMLSpanElement>;
|
|
27
|
+
/** The control that shows the name and starts renaming. */
|
|
28
|
+
name?: ButtonHTMLAttributes<HTMLButtonElement>;
|
|
29
|
+
/** The input shown while renaming. Carries `data-invalid` for a name that cannot be used. */
|
|
30
|
+
nameInput?: InputHTMLAttributes<HTMLInputElement>;
|
|
31
|
+
/** The read-only badge of a property's type. Carries `data-property-type`, and `data-locked` while the type is locked. */
|
|
32
|
+
badge?: SchemaEditorPartAttributes<HTMLSpanElement>;
|
|
33
|
+
/** The button that opens the menu of types. */
|
|
34
|
+
typeButton?: ButtonHTMLAttributes<HTMLButtonElement>;
|
|
35
|
+
/** The popover of the menu of types. */
|
|
36
|
+
menu?: SchemaEditorMenuPartAttributes;
|
|
37
|
+
/** One entry of the menu of types. */
|
|
38
|
+
menuItem?: SchemaEditorMenuPartAttributes;
|
|
39
|
+
/** The label of the required toggle. */
|
|
40
|
+
required?: SchemaEditorPartAttributes<HTMLLabelElement>;
|
|
41
|
+
/** The key toggle. Carries `data-pressed` while the property is the key. */
|
|
42
|
+
key?: ButtonHTMLAttributes<HTMLButtonElement>;
|
|
43
|
+
/** The wrapper of the host's accessory slot. */
|
|
44
|
+
accessory?: SchemaEditorPartAttributes<HTMLSpanElement>;
|
|
45
|
+
/** The button that removes a property. */
|
|
46
|
+
remove?: ButtonHTMLAttributes<HTMLButtonElement>;
|
|
47
|
+
/** The marker shown instead of the remove button for a protected property. */
|
|
48
|
+
protected?: SchemaEditorPartAttributes<HTMLSpanElement>;
|
|
49
|
+
/** The wrapper of the host's details slot, shown under the row. */
|
|
50
|
+
details?: SchemaEditorPartAttributes<HTMLDivElement>;
|
|
51
|
+
/** The button that adds a property, at the root or in a nested object. */
|
|
52
|
+
add?: ButtonHTMLAttributes<HTMLButtonElement>;
|
|
53
|
+
/** The text shown when there are no properties. */
|
|
54
|
+
empty?: SchemaEditorPartAttributes<HTMLParagraphElement>;
|
|
55
|
+
/** A validation message. */
|
|
56
|
+
message?: SchemaEditorPartAttributes<HTMLParagraphElement>;
|
|
57
|
+
/** The wrapper of the host's `footer`, beside the add button. */
|
|
58
|
+
footer?: SchemaEditorPartAttributes<HTMLDivElement>;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=SchemaEditorParts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaEditorParts.d.ts","sourceRoot":"","sources":["../../../../SchemaEditor/Tree/SchemaEditorParts.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,OAAO,CAAC;AAEvF,0FAA0F;AAC1F,MAAM,MAAM,0BAA0B,CAAC,QAAQ,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG;IAC1E,CAAC,SAAS,EAAE,QAAQ,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CACxE,CAAC;AAEF,qFAAqF;AACrF,MAAM,MAAM,8BAA8B,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG;IACpG,CAAC,SAAS,EAAE,QAAQ,MAAM,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;CACxE,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAC9B,8EAA8E;IAC9E,IAAI,CAAC,EAAE,0BAA0B,CAAC,cAAc,CAAC,CAAC;IAElD,0CAA0C;IAC1C,MAAM,CAAC,EAAE,0BAA0B,CAAC,cAAc,CAAC,CAAC;IAEpD,sFAAsF;IACtF,IAAI,CAAC,EAAE,0BAA0B,CAAC,gBAAgB,CAAC,CAAC;IAEpD,kFAAkF;IAClF,QAAQ,CAAC,EAAE,0BAA0B,CAAC,aAAa,CAAC,CAAC;IAErD,yFAAyF;IACzF,GAAG,CAAC,EAAE,0BAA0B,CAAC,cAAc,CAAC,CAAC;IAEjD,8CAA8C;IAC9C,OAAO,CAAC,EAAE,0BAA0B,CAAC,eAAe,CAAC,CAAC;IAEtD,2DAA2D;IAC3D,IAAI,CAAC,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAE/C,6FAA6F;IAC7F,SAAS,CAAC,EAAE,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;IAElD,0HAA0H;IAC1H,KAAK,CAAC,EAAE,0BAA0B,CAAC,eAAe,CAAC,CAAC;IAEpD,+CAA+C;IAC/C,UAAU,CAAC,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAErD,wCAAwC;IACxC,IAAI,CAAC,EAAE,8BAA8B,CAAC;IAEtC,sCAAsC;IACtC,QAAQ,CAAC,EAAE,8BAA8B,CAAC;IAE1C,wCAAwC;IACxC,QAAQ,CAAC,EAAE,0BAA0B,CAAC,gBAAgB,CAAC,CAAC;IAExD,4EAA4E;IAC5E,GAAG,CAAC,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAE9C,gDAAgD;IAChD,SAAS,CAAC,EAAE,0BAA0B,CAAC,eAAe,CAAC,CAAC;IAExD,0CAA0C;IAC1C,MAAM,CAAC,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAEjD,8EAA8E;IAC9E,SAAS,CAAC,EAAE,0BAA0B,CAAC,eAAe,CAAC,CAAC;IAExD,mEAAmE;IACnE,OAAO,CAAC,EAAE,0BAA0B,CAAC,cAAc,CAAC,CAAC;IAErD,0EAA0E;IAC1E,GAAG,CAAC,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAE9C,mDAAmD;IACnD,KAAK,CAAC,EAAE,0BAA0B,CAAC,oBAAoB,CAAC,CAAC;IAEzD,4BAA4B;IAC5B,OAAO,CAAC,EAAE,0BAA0B,CAAC,oBAAoB,CAAC,CAAC;IAE3D,iEAAiE;IACjE,MAAM,CAAC,EAAE,0BAA0B,CAAC,cAAc,CAAC,CAAC;CACvD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaEditorParts.js","sourceRoot":"","sources":["../../../../SchemaEditor/Tree/SchemaEditorParts.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,qGAAqG","sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport type { ButtonHTMLAttributes, HTMLAttributes, InputHTMLAttributes } from 'react';\n\n/** Attributes passed through to one part of the editor, including `data-*` attributes. */\nexport type SchemaEditorPartAttributes<TElement> = HTMLAttributes<TElement> & {\n [attribute: `data-${string}`]: string | number | boolean | undefined;\n};\n\n/** Styling attributes passed to a part the editor renders through a popover menu. */\nexport type SchemaEditorMenuPartAttributes = Pick<HTMLAttributes<HTMLElement>, 'className' | 'style'> & {\n [attribute: `data-${string}`]: string | number | boolean | undefined;\n};\n\n/**\n * Stable Cratis-owned parts for styling a {@link SchemaEditor}. Each is marked with a matching\n * `data-cratis-part` attribute and receives what is passed here; the editor's own wiring wins.\n */\nexport interface SchemaEditorParts {\n /** The editor root. Carries `data-readonly` while the editor is read-only. */\n root?: SchemaEditorPartAttributes<HTMLDivElement>;\n\n /** The wrapper of the host's `header`. */\n header?: SchemaEditorPartAttributes<HTMLDivElement>;\n\n /** A list of properties: the root list, or the properties nested under a property. */\n list?: SchemaEditorPartAttributes<HTMLUListElement>;\n\n /** One property with everything nested under it. Carries `data-property-type`. */\n property?: SchemaEditorPartAttributes<HTMLLIElement>;\n\n /** The row of one property. Carries `data-selected` while the host marks it selected. */\n row?: SchemaEditorPartAttributes<HTMLDivElement>;\n\n /** The wrapper of the host's leading slot. */\n leading?: SchemaEditorPartAttributes<HTMLSpanElement>;\n\n /** The control that shows the name and starts renaming. */\n name?: ButtonHTMLAttributes<HTMLButtonElement>;\n\n /** The input shown while renaming. Carries `data-invalid` for a name that cannot be used. */\n nameInput?: InputHTMLAttributes<HTMLInputElement>;\n\n /** The read-only badge of a property's type. Carries `data-property-type`, and `data-locked` while the type is locked. */\n badge?: SchemaEditorPartAttributes<HTMLSpanElement>;\n\n /** The button that opens the menu of types. */\n typeButton?: ButtonHTMLAttributes<HTMLButtonElement>;\n\n /** The popover of the menu of types. */\n menu?: SchemaEditorMenuPartAttributes;\n\n /** One entry of the menu of types. */\n menuItem?: SchemaEditorMenuPartAttributes;\n\n /** The label of the required toggle. */\n required?: SchemaEditorPartAttributes<HTMLLabelElement>;\n\n /** The key toggle. Carries `data-pressed` while the property is the key. */\n key?: ButtonHTMLAttributes<HTMLButtonElement>;\n\n /** The wrapper of the host's accessory slot. */\n accessory?: SchemaEditorPartAttributes<HTMLSpanElement>;\n\n /** The button that removes a property. */\n remove?: ButtonHTMLAttributes<HTMLButtonElement>;\n\n /** The marker shown instead of the remove button for a protected property. */\n protected?: SchemaEditorPartAttributes<HTMLSpanElement>;\n\n /** The wrapper of the host's details slot, shown under the row. */\n details?: SchemaEditorPartAttributes<HTMLDivElement>;\n\n /** The button that adds a property, at the root or in a nested object. */\n add?: ButtonHTMLAttributes<HTMLButtonElement>;\n\n /** The text shown when there are no properties. */\n empty?: SchemaEditorPartAttributes<HTMLParagraphElement>;\n\n /** A validation message. */\n message?: SchemaEditorPartAttributes<HTMLParagraphElement>;\n\n /** The wrapper of the host's `footer`, beside the add button. */\n footer?: SchemaEditorPartAttributes<HTMLDivElement>;\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Property } from './Property.js';
|
|
2
|
+
/** What the {@link SchemaEditor} tells the host about the row it is asking it to render or describe. */
|
|
3
|
+
export interface SchemaPropertyContext {
|
|
4
|
+
/** How deeply the property is nested; root properties are at depth `0`. */
|
|
5
|
+
depth: number;
|
|
6
|
+
/** The properties that share the property's parent, including the property itself. */
|
|
7
|
+
siblings: Property[];
|
|
8
|
+
/** The whole property tree currently shown, so a slot can resolve other properties by id or name. */
|
|
9
|
+
properties: Property[];
|
|
10
|
+
/** Whether the editor is read-only. A slot should offer no edits while it is. */
|
|
11
|
+
readOnly: boolean;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=SchemaPropertyContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaPropertyContext.d.ts","sourceRoot":"","sources":["../../../../SchemaEditor/Tree/SchemaPropertyContext.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAY,CAAC;AAE3C,wGAAwG;AACxG,MAAM,WAAW,qBAAqB;IAClC,2EAA2E;IAC3E,KAAK,EAAE,MAAM,CAAC;IAEd,sFAAsF;IACtF,QAAQ,EAAE,QAAQ,EAAE,CAAC;IAErB,qGAAqG;IACrG,UAAU,EAAE,QAAQ,EAAE,CAAC;IAEvB,iFAAiF;IACjF,QAAQ,EAAE,OAAO,CAAC;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaPropertyContext.js","sourceRoot":"","sources":["../../../../SchemaEditor/Tree/SchemaPropertyContext.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,qGAAqG","sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport type { Property } from './Property';\n\n/** What the {@link SchemaEditor} tells the host about the row it is asking it to render or describe. */\nexport interface SchemaPropertyContext {\n /** How deeply the property is nested; root properties are at depth `0`. */\n depth: number;\n\n /** The properties that share the property's parent, including the property itself. */\n siblings: Property[];\n\n /** The whole property tree currently shown, so a slot can resolve other properties by id or name. */\n properties: Property[];\n\n /** Whether the editor is read-only. A slot should offer no edits while it is. */\n readOnly: boolean;\n}\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Property } from './Property.js';
|
|
2
|
+
/** Props for one row of the editor, and everything nested under it. */
|
|
3
|
+
export interface SchemaPropertyRowProps {
|
|
4
|
+
/** The property shown. */
|
|
5
|
+
property: Property;
|
|
6
|
+
/** The properties that share its parent, including itself. */
|
|
7
|
+
siblings: Property[];
|
|
8
|
+
/** How deeply the property is nested. */
|
|
9
|
+
depth: number;
|
|
10
|
+
}
|
|
11
|
+
/** One property: its row of controls, the host's details beneath it, and the properties nested under it. */
|
|
12
|
+
export declare const SchemaPropertyRow: ({ property, siblings, depth }: SchemaPropertyRowProps) => import("react").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=SchemaPropertyRow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaPropertyRow.d.ts","sourceRoot":"","sources":["../../../../SchemaEditor/Tree/SchemaPropertyRow.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAY,CAAC;AAQ3C,uEAAuE;AACvE,MAAM,WAAW,sBAAsB;IACnC,0BAA0B;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IAEnB,8DAA8D;IAC9D,QAAQ,EAAE,QAAQ,EAAE,CAAC;IAErB,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;CACjB;AAID,4GAA4G;AAC5G,eAAO,MAAM,iBAAiB,kCAAmC,sBAAsB,gCAsRtF,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useId, useRef, useState, useEffect } from 'react';
|
|
3
|
+
import { FaKey, FaLock, FaXmark, FaPlus } from 'react-icons/fa6';
|
|
4
|
+
import { findPropertyNameProblem, PropertyNameProblem } from './propertyNaming.js';
|
|
5
|
+
import { PropertyTypeBadge } from './PropertyTypeBadge.js';
|
|
6
|
+
import { PropertyTypeMenu } from './PropertyTypeMenu.js';
|
|
7
|
+
import { useSchemaEditorContext } from './SchemaEditorContext.js';
|
|
8
|
+
import { hasNestedProperties, propertyTypeName } from './propertyTypeDisplay.js';
|
|
9
|
+
|
|
10
|
+
const interactiveSelector = 'button, input, label, textarea, select, a, [role="menu"]';
|
|
11
|
+
const SchemaPropertyRow = ({ property, siblings, depth }) => {
|
|
12
|
+
const context = useSchemaEditorContext();
|
|
13
|
+
const { labels, parts, operations, readOnly } = context;
|
|
14
|
+
const messageId = useId();
|
|
15
|
+
const nameInput = useRef(null);
|
|
16
|
+
const [isEditing, setIsEditing] = useState(false);
|
|
17
|
+
const [draftName, setDraftName] = useState(property.name);
|
|
18
|
+
const [problem, setProblem] = useState(undefined);
|
|
19
|
+
const rowContext = { depth, siblings, properties: context.properties, readOnly };
|
|
20
|
+
const rowState = context.getRowState?.(property, rowContext);
|
|
21
|
+
const details = context.renderDetails?.(property, rowContext);
|
|
22
|
+
const isProtected = context.isProtected(property);
|
|
23
|
+
const canRename = !readOnly && !isProtected && operations.rename !== undefined;
|
|
24
|
+
const canRemove = !readOnly && !isProtected && operations.remove !== undefined;
|
|
25
|
+
const canChangeType = !readOnly && operations.changeType !== undefined && rowState?.lockType !== true;
|
|
26
|
+
const canSetRequired = context.isRequiredAllowed && operations.setRequired !== undefined;
|
|
27
|
+
const canSetKey = !readOnly && operations.setKey !== undefined && context.isKeyAllowed(property, rowContext);
|
|
28
|
+
const canAddChild = !readOnly && operations.addChild !== undefined && hasNestedProperties(property.type);
|
|
29
|
+
const lockReason = rowState?.lockType === true ? rowState.lockTypeReason : undefined;
|
|
30
|
+
const isSelected = context.selectedPropertyId === property.id;
|
|
31
|
+
const typeName = propertyTypeName(property.type, labels);
|
|
32
|
+
const nestedLabel = labels.nestedProperties(property.name);
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
if (isEditing)
|
|
35
|
+
nameInput.current?.select();
|
|
36
|
+
}, [isEditing]);
|
|
37
|
+
const startEditing = () => {
|
|
38
|
+
if (!canRename)
|
|
39
|
+
return;
|
|
40
|
+
setDraftName(property.name);
|
|
41
|
+
setProblem(undefined);
|
|
42
|
+
setIsEditing(true);
|
|
43
|
+
};
|
|
44
|
+
const stopEditing = () => {
|
|
45
|
+
setIsEditing(false);
|
|
46
|
+
setProblem(undefined);
|
|
47
|
+
};
|
|
48
|
+
const describe = (name) => {
|
|
49
|
+
const found = findPropertyNameProblem(name, property.id, siblings);
|
|
50
|
+
if (found === PropertyNameProblem.Empty)
|
|
51
|
+
return labels.nameRequired;
|
|
52
|
+
if (found === PropertyNameProblem.Reserved)
|
|
53
|
+
return labels.nameReserved(name);
|
|
54
|
+
if (found === PropertyNameProblem.Duplicate)
|
|
55
|
+
return labels.nameDuplicate(name);
|
|
56
|
+
return context.validateName?.(name, property, siblings);
|
|
57
|
+
};
|
|
58
|
+
const commit = () => {
|
|
59
|
+
const name = draftName.trim();
|
|
60
|
+
if (name === property.name) {
|
|
61
|
+
stopEditing();
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
const message = describe(name);
|
|
65
|
+
if (message) {
|
|
66
|
+
setProblem(message);
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
stopEditing();
|
|
70
|
+
operations.rename?.(property.id, name);
|
|
71
|
+
return true;
|
|
72
|
+
};
|
|
73
|
+
const handleEditKeyDown = (event) => {
|
|
74
|
+
if (event.key === 'Enter') {
|
|
75
|
+
event.preventDefault();
|
|
76
|
+
commit();
|
|
77
|
+
}
|
|
78
|
+
else if (event.key === 'Escape') {
|
|
79
|
+
event.stopPropagation();
|
|
80
|
+
stopEditing();
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const handleRowClick = (event) => {
|
|
84
|
+
const target = event.target;
|
|
85
|
+
const optedIn = target.closest('[data-schema-row-select]');
|
|
86
|
+
if (optedIn && event.currentTarget.contains(optedIn)) {
|
|
87
|
+
context.onPropertyClick?.(property.id);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const interactive = target.closest(interactiveSelector);
|
|
91
|
+
if (interactive && interactive.getAttribute('data-cratis-part') !== 'name')
|
|
92
|
+
return;
|
|
93
|
+
context.onPropertyClick?.(property.id);
|
|
94
|
+
};
|
|
95
|
+
const defaultBadge = jsx(PropertyTypeBadge, { property: property, labels: labels, part: parts?.badge, lockReason: lockReason });
|
|
96
|
+
const typeBadge = context.renderTypeBadge ? context.renderTypeBadge(property, rowContext, defaultBadge) : defaultBadge;
|
|
97
|
+
const rowAttributes = rowState?.attributes ?? {};
|
|
98
|
+
const isSelectable = context.onPropertyClick !== undefined;
|
|
99
|
+
return (jsxs("li", { ...parts?.property, className: `cratis-schema-editor__property ${parts?.property?.className ?? ''}`, "data-cratis-part": 'property', "data-property-type": property.type, children: [jsxs("div", { ...parts?.row, ...rowAttributes, title: rowState?.title, className: `cratis-schema-editor__row ${rowState?.className ?? ''} ${parts?.row?.className ?? ''}`, "data-cratis-part": 'row', "data-selected": isSelected || undefined, onClick: handleRowClick, children: [context.renderLeading && (jsx("span", { ...parts?.leading, className: `cratis-schema-editor__leading ${parts?.leading?.className ?? ''}`, "data-cratis-part": 'leading', children: context.renderLeading(property, rowContext) })), isEditing ? (jsxs("span", { className: 'cratis-schema-editor__name-edit', children: [jsx("input", { ...parts?.nameInput, ref: nameInput, type: 'text', value: draftName, "aria-label": labels.propertyNameFor(property.name), "aria-invalid": problem !== undefined || undefined, "aria-describedby": problem ? messageId : undefined, className: `cratis-schema-editor__name-input ${parts?.nameInput?.className ?? ''}`, "data-cratis-part": 'nameInput', "data-invalid": problem !== undefined || undefined, onChange: event => { setDraftName(event.target.value); setProblem(undefined); }, onBlur: () => { if (!commit())
|
|
100
|
+
stopEditing(); }, onKeyDown: handleEditKeyDown }), problem && (jsx("p", { ...parts?.message, id: messageId, role: 'alert', className: `cratis-schema-editor__message ${parts?.message?.className ?? ''}`, "data-cratis-part": 'message', children: problem }))] })) : canRename || isSelectable ? (jsx("button", { ...parts?.name, type: 'button', title: canRename ? labels.renameHint : undefined, "aria-keyshortcuts": canRename ? 'F2' : undefined, className: `cratis-schema-editor__name ${parts?.name?.className ?? ''}`, "data-cratis-part": 'name', onDoubleClick: startEditing, onKeyDown: event => { if (event.key === 'F2') {
|
|
101
|
+
event.preventDefault();
|
|
102
|
+
startEditing();
|
|
103
|
+
} }, children: property.name })) : (jsx("span", { className: `cratis-schema-editor__name cratis-schema-editor__name--static ${parts?.name?.className ?? ''}`, "data-cratis-part": 'name', children: property.name })), canChangeType ? (jsx(PropertyTypeMenu, { labels: labels, concepts: context.concepts, triggerPart: 'typeButton', triggerLabel: labels.changeType(property.name, property.concept ?? typeName), parts: parts, onSelect: (type, concept) => operations.changeType?.(property.id, type, concept), children: typeBadge })) : typeBadge, canSetRequired && (jsxs("label", { ...parts?.required, title: labels.requiredHelp, className: `cratis-schema-editor__required ${parts?.required?.className ?? ''}`, "data-cratis-part": 'required', children: [jsx("input", { type: 'checkbox', checked: property.isRequired === true, disabled: readOnly, "aria-label": labels.requiredProperty(property.name), "aria-description": labels.requiredHelp, onChange: event => operations.setRequired?.(property.id, event.target.checked) }), labels.required] })), canSetKey && (jsx("button", { ...parts?.key, type: 'button', "aria-pressed": property.isKey === true, "aria-label": labels.keyProperty(property.name), title: property.isKey ? labels.isKey : labels.setAsKey, className: `cratis-schema-editor__key ${parts?.key?.className ?? ''}`, "data-cratis-part": 'key', "data-pressed": property.isKey === true || undefined, onClick: () => operations.setKey?.(property.id), children: jsx(FaKey, { "aria-hidden": 'true' }) })), context.renderAccessory && (jsx("span", { ...parts?.accessory, className: `cratis-schema-editor__accessory ${parts?.accessory?.className ?? ''}`, "data-cratis-part": 'accessory', children: context.renderAccessory(property, rowContext) })), isProtected ? (jsx("span", { ...parts?.protected, role: 'img', "aria-label": labels.protectedProperty, title: labels.protectedProperty, className: `cratis-schema-editor__protected ${parts?.protected?.className ?? ''}`, "data-cratis-part": 'protected', children: jsx(FaLock, { "aria-hidden": 'true' }) })) : canRemove && (jsx("button", { ...parts?.remove, type: 'button', "aria-label": labels.deletePropertyFor(property.name), title: labels.deletePropertyFor(property.name), className: `cratis-schema-editor__remove ${parts?.remove?.className ?? ''}`, "data-cratis-part": 'remove', onClick: () => operations.remove?.(property.id), children: jsx(FaXmark, { "aria-hidden": 'true' }) }))] }), details && (jsx("div", { ...parts?.details, className: `cratis-schema-editor__details ${parts?.details?.className ?? ''}`, "data-cratis-part": 'details', children: details })), hasNestedProperties(property.type) && (jsxs(Fragment, { children: [(property.children ?? []).length > 0 && (jsx("ul", { ...parts?.list, "aria-label": nestedLabel, className: `cratis-schema-editor__list cratis-schema-editor__list--nested ${parts?.list?.className ?? ''}`, "data-cratis-part": 'list', children: (property.children ?? []).map(child => (jsx(SchemaPropertyRow, { property: child, siblings: property.children ?? [], depth: depth + 1 }, child.id))) })), canAddChild && (jsxs(PropertyTypeMenu, { labels: labels, concepts: context.concepts, triggerPart: 'add', triggerLabel: labels.addPropertyTo(property.name), parts: parts, onSelect: (type, concept) => operations.addChild?.(property.id, type, concept), children: [jsx(FaPlus, { "aria-hidden": 'true' }), labels.addProperty] }))] }))] }));
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export { SchemaPropertyRow };
|
|
107
|
+
//# sourceMappingURL=SchemaPropertyRow.js.map
|