@mintplayer/ng-spark 22.8.0 → 22.9.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/fesm2022/mintplayer-ng-spark-attribute-description.mjs +68 -0
- package/fesm2022/mintplayer-ng-spark-attribute-description.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-grid.mjs +3 -2
- package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-pipes.mjs +4 -2
- package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs +3 -2
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-form.mjs +5 -4
- package/fesm2022/mintplayer-ng-spark-po-form.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-renderers.mjs +6 -4
- package/fesm2022/mintplayer-ng-spark-renderers.mjs.map +1 -1
- package/package.json +5 -1
- package/types/mintplayer-ng-spark-attribute-description.d.ts +30 -0
- package/types/mintplayer-ng-spark-models.d.ts +4 -0
- package/types/mintplayer-ng-spark-renderers.d.ts +6 -4
|
@@ -28,10 +28,12 @@ function rendererValue(attr) {
|
|
|
28
28
|
/**
|
|
29
29
|
* The renderer-facing value of a query-result cell.
|
|
30
30
|
*
|
|
31
|
-
* A
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
31
|
+
* A cell is a single channel: whatever a renderer needs is already on `value` — for a single-child
|
|
32
|
+
* AsDetail column that is the nested PersistentObject itself, put there by the server so this
|
|
33
|
+
* matches what {@link rendererValue} falls through to on a detail page. There is nothing to fall
|
|
34
|
+
* back to, which is why this is deliberately not the same function: keeping them separate is what
|
|
35
|
+
* stops a renderer silently receiving `undefined` because it was written against the attribute
|
|
36
|
+
* shape's `object` / `objects` fields, which a row does not carry.
|
|
35
37
|
*/
|
|
36
38
|
function cellValue(value) {
|
|
37
39
|
return value?.value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mintplayer-ng-spark-renderers.mjs","sources":["../../renderers/src/renderer-inputs.ts","../../renderers/src/spark-attribute-renderer-registry.ts","../../renderers/mintplayer-ng-spark-renderers.ts"],"sourcesContent":["import { reflectComponentType, Type } from '@angular/core';\nimport { PersistentObjectAttribute, QueryResultItemValue } from '@mintplayer/ng-spark/models';\n\n// Reflection result cached per component type: the input builders are template\n// expressions re-evaluated every CD pass (and query-list virtual-scrolls).\nconst declaredInputs = new Map<Type<any>, Set<string>>();\n\n/**\n * Drops entries the component doesn't declare, so every contract member is\n * genuinely optional — NgComponentOutlet throws on an undeclared input.\n */\nexport function withDeclaredInputs(component: Type<any>, inputs: Record<string, any>): Record<string, any> {\n let declared = declaredInputs.get(component);\n if (!declared) {\n declared = new Set(reflectComponentType(component)?.inputs.map(i => i.templateName) ?? []);\n declaredInputs.set(component, declared);\n }\n return Object.fromEntries(Object.entries(inputs).filter(([k]) => declared!.has(k)));\n}\n\n/**\n * The renderer-facing value of an attribute: the flat value, or for AsDetail\n * attributes (whose flat value the server nulls on purpose) the nested\n * PersistentObject (single) / PersistentObject[] (array).\n *\n * Used by the detail and edit paths, which still work in attributes.\n */\nexport function rendererValue(attr: PersistentObjectAttribute | undefined): any {\n return attr?.value ?? attr?.object ?? attr?.objects;\n}\n\n/**\n * The renderer-facing value of a query-result cell.\n *\n * A
|
|
1
|
+
{"version":3,"file":"mintplayer-ng-spark-renderers.mjs","sources":["../../renderers/src/renderer-inputs.ts","../../renderers/src/spark-attribute-renderer-registry.ts","../../renderers/mintplayer-ng-spark-renderers.ts"],"sourcesContent":["import { reflectComponentType, Type } from '@angular/core';\nimport { PersistentObjectAttribute, QueryResultItemValue } from '@mintplayer/ng-spark/models';\n\n// Reflection result cached per component type: the input builders are template\n// expressions re-evaluated every CD pass (and query-list virtual-scrolls).\nconst declaredInputs = new Map<Type<any>, Set<string>>();\n\n/**\n * Drops entries the component doesn't declare, so every contract member is\n * genuinely optional — NgComponentOutlet throws on an undeclared input.\n */\nexport function withDeclaredInputs(component: Type<any>, inputs: Record<string, any>): Record<string, any> {\n let declared = declaredInputs.get(component);\n if (!declared) {\n declared = new Set(reflectComponentType(component)?.inputs.map(i => i.templateName) ?? []);\n declaredInputs.set(component, declared);\n }\n return Object.fromEntries(Object.entries(inputs).filter(([k]) => declared!.has(k)));\n}\n\n/**\n * The renderer-facing value of an attribute: the flat value, or for AsDetail\n * attributes (whose flat value the server nulls on purpose) the nested\n * PersistentObject (single) / PersistentObject[] (array).\n *\n * Used by the detail and edit paths, which still work in attributes.\n */\nexport function rendererValue(attr: PersistentObjectAttribute | undefined): any {\n return attr?.value ?? attr?.object ?? attr?.objects;\n}\n\n/**\n * The renderer-facing value of a query-result cell.\n *\n * A cell is a single channel: whatever a renderer needs is already on `value` — for a single-child\n * AsDetail column that is the nested PersistentObject itself, put there by the server so this\n * matches what {@link rendererValue} falls through to on a detail page. There is nothing to fall\n * back to, which is why this is deliberately not the same function: keeping them separate is what\n * stops a renderer silently receiving `undefined` because it was written against the attribute\n * shape's `object` / `objects` fields, which a row does not carry.\n */\nexport function cellValue(value: QueryResultItemValue | undefined): any {\n return value?.value;\n}\n","import { InjectionToken, Provider, Type } from '@angular/core';\n\nexport interface SparkAttributeRendererRegistration {\n /** The renderer name (must match attr.renderer in model JSON) */\n name: string;\n /** Component for the PO detail page. Must implement SparkAttributeDetailRenderer. Omit for a column/edit-only renderer. */\n detailComponent?: Type<any> | null;\n /** Component for query-list column cells. Must implement SparkAttributeColumnRenderer. Omit for a detail/edit-only renderer. */\n columnComponent?: Type<any> | null;\n /** Optional component for create/edit forms. Must implement SparkAttributeEditRenderer. When omitted, the default input is used. */\n editComponent?: Type<any>;\n}\n\nexport const SPARK_ATTRIBUTE_RENDERERS = new InjectionToken<SparkAttributeRendererRegistration[]>(\n 'SparkAttributeRenderers',\n { factory: () => [] }\n);\n\n/**\n * Register custom attribute renderers globally.\n *\n * @example\n * provideSparkAttributeRenderers([\n * { name: 'video-player', detailComponent: VideoDetailComponent, columnComponent: VideoColumnComponent },\n * { name: 'color-swatch', detailComponent: ColorDetailComponent, columnComponent: ColorColumnComponent },\n * ])\n */\nexport function provideSparkAttributeRenderers(\n renderers: SparkAttributeRendererRegistration[]\n): Provider {\n return {\n provide: SPARK_ATTRIBUTE_RENDERERS,\n useValue: renderers,\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;AAGA;AACA;AACA,MAAM,cAAc,GAAG,IAAI,GAAG,EAA0B;AAExD;;;AAGG;AACG,SAAU,kBAAkB,CAAC,SAAoB,EAAE,MAA2B,EAAA;IAClF,IAAI,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC;IAC5C,IAAI,CAAC,QAAQ,EAAE;QACb,QAAQ,GAAG,IAAI,GAAG,CAAC,oBAAoB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;AAC1F,QAAA,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC;IACzC;AACA,IAAA,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,QAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACrF;AAEA;;;;;;AAMG;AACG,SAAU,aAAa,CAAC,IAA2C,EAAA;IACvE,OAAO,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,MAAM,IAAI,IAAI,EAAE,OAAO;AACrD;AAEA;;;;;;;;;AASG;AACG,SAAU,SAAS,CAAC,KAAuC,EAAA;IAC/D,OAAO,KAAK,EAAE,KAAK;AACrB;;AC9BO,MAAM,yBAAyB,GAAG,IAAI,cAAc,CACzD,yBAAyB,EACzB,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE;AAGvB;;;;;;;;AAQG;AACG,SAAU,8BAA8B,CAC5C,SAA+C,EAAA;IAE/C,OAAO;AACL,QAAA,OAAO,EAAE,yBAAyB;AAClC,QAAA,QAAQ,EAAE,SAAS;KACpB;AACH;;AClCA;;AAEG;;;;"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mintplayer/ng-spark",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "22.
|
|
4
|
+
"version": "22.9.0",
|
|
5
5
|
"description": "Angular component library for MintPlayer.Spark CRUD applications",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -29,6 +29,10 @@
|
|
|
29
29
|
"types": "./types/mintplayer-ng-spark.d.ts",
|
|
30
30
|
"default": "./fesm2022/mintplayer-ng-spark.mjs"
|
|
31
31
|
},
|
|
32
|
+
"./attribute-description": {
|
|
33
|
+
"types": "./types/mintplayer-ng-spark-attribute-description.d.ts",
|
|
34
|
+
"default": "./fesm2022/mintplayer-ng-spark-attribute-description.mjs"
|
|
35
|
+
},
|
|
32
36
|
"./client-operations": {
|
|
33
37
|
"types": "./types/mintplayer-ng-spark-client-operations.d.ts",
|
|
34
38
|
"default": "./fesm2022/mintplayer-ng-spark-client-operations.mjs"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { TranslatedString } from '@mintplayer/ng-spark/models';
|
|
3
|
+
|
|
4
|
+
type SparkAttributeDescriptionPosition = 'top' | 'bottom' | 'start' | 'end';
|
|
5
|
+
/**
|
|
6
|
+
* The [i] beside an attribute label: a focusable button whose tooltip shows the attribute's
|
|
7
|
+
* `description` (#348). Renders nothing when the model declares no description, so every label
|
|
8
|
+
* site can include it unconditionally.
|
|
9
|
+
*
|
|
10
|
+
* Accessibility comes from `*bsTooltip`: it opens on hover AND focus, closes on Escape, and sets
|
|
11
|
+
* `aria-describedby` on the button while open. The button's own name is the description text, so
|
|
12
|
+
* a screen reader announces the help on focus without waiting for the tooltip.
|
|
13
|
+
*
|
|
14
|
+
* Clicks are stopped: the [i] lives inside sortable grid headers and `<label for>` elements, and
|
|
15
|
+
* must neither toggle the sort nor move focus into the input.
|
|
16
|
+
*/
|
|
17
|
+
declare class SparkAttributeDescriptionComponent {
|
|
18
|
+
/** The attribute's `description`; `undefined` (the common case) renders nothing. */
|
|
19
|
+
description: _angular_core.InputSignal<TranslatedString | undefined>;
|
|
20
|
+
/** Where the tooltip opens relative to the [i]. */
|
|
21
|
+
position: _angular_core.InputSignal<SparkAttributeDescriptionPosition>;
|
|
22
|
+
/** Resolved for the current language; re-evaluates when the user switches language. */
|
|
23
|
+
text: _angular_core.Signal<string>;
|
|
24
|
+
onClick(event: MouseEvent): void;
|
|
25
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<SparkAttributeDescriptionComponent, never>;
|
|
26
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<SparkAttributeDescriptionComponent, "spark-attribute-description", never, { "description": { "alias": "description"; "required": false; "isSignal": true; }; "position": { "alias": "position"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { SparkAttributeDescriptionComponent };
|
|
30
|
+
export type { SparkAttributeDescriptionPosition };
|
|
@@ -123,6 +123,8 @@ interface EntityAttributeDefinition {
|
|
|
123
123
|
id: string;
|
|
124
124
|
name: string;
|
|
125
125
|
label?: TranslatedString;
|
|
126
|
+
/** Help text rendered as an [i] tooltip beside the label. Absent when the model declares none. */
|
|
127
|
+
description?: TranslatedString;
|
|
126
128
|
dataType: string;
|
|
127
129
|
isRequired: boolean;
|
|
128
130
|
isVisible: boolean;
|
|
@@ -265,6 +267,8 @@ interface QueryResult {
|
|
|
265
267
|
interface SparkCellColumn {
|
|
266
268
|
name: string;
|
|
267
269
|
label?: TranslatedString;
|
|
270
|
+
/** Help text rendered as an [i] tooltip in the column header. Absent when the model declares none. */
|
|
271
|
+
description?: TranslatedString;
|
|
268
272
|
dataType: string;
|
|
269
273
|
isArray?: boolean;
|
|
270
274
|
renderer?: string;
|
|
@@ -17,10 +17,12 @@ declare function rendererValue(attr: PersistentObjectAttribute | undefined): any
|
|
|
17
17
|
/**
|
|
18
18
|
* The renderer-facing value of a query-result cell.
|
|
19
19
|
*
|
|
20
|
-
* A
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
20
|
+
* A cell is a single channel: whatever a renderer needs is already on `value` — for a single-child
|
|
21
|
+
* AsDetail column that is the nested PersistentObject itself, put there by the server so this
|
|
22
|
+
* matches what {@link rendererValue} falls through to on a detail page. There is nothing to fall
|
|
23
|
+
* back to, which is why this is deliberately not the same function: keeping them separate is what
|
|
24
|
+
* stops a renderer silently receiving `undefined` because it was written against the attribute
|
|
25
|
+
* shape's `object` / `objects` fields, which a row does not carry.
|
|
24
26
|
*/
|
|
25
27
|
declare function cellValue(value: QueryResultItemValue | undefined): any;
|
|
26
28
|
|