@praxisui/dynamic-fields 3.0.0-beta.5 → 3.0.0-beta.7
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 +12 -0
- package/fesm2022/praxisui-dynamic-fields.mjs +973 -269
- package/fesm2022/praxisui-dynamic-fields.mjs.map +1 -1
- package/index.d.ts +11 -1
- package/package.json +5 -5
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as i1$3 from '@angular/forms';
|
|
2
2
|
import { NgControl, FormControl, Validators, ReactiveFormsModule, NG_VALUE_ACCESSOR, FormGroup, FormsModule } from '@angular/forms';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { InjectionToken, inject, DestroyRef, ElementRef, ChangeDetectorRef, Injector, signal, output, computed, Input, Directive, viewChild, effect, Injectable, EventEmitter, ViewContainerRef, ViewChild, HostListener, HostBinding, Output, ViewEncapsulation, ChangeDetectionStrategy, Component, Inject, forwardRef,
|
|
4
|
+
import { InjectionToken, inject, DestroyRef, ElementRef, ChangeDetectorRef, Injector, signal, output, computed, Input, Directive, viewChild, effect, Injectable, LOCALE_ID, EventEmitter, ViewContainerRef, ViewChild, HostListener, HostBinding, Output, ViewEncapsulation, ChangeDetectionStrategy, Component, Inject, forwardRef, ViewChildren, TemplateRef, ContentChild, ENVIRONMENT_INITIALIZER, APP_INITIALIZER, Optional } from '@angular/core';
|
|
5
5
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
6
|
-
import { providePraxisI18n, PraxisI18nService, isCssTextTransform, getTextTransformer, GenericCrudService, GlobalConfigService, INLINE_FILTER_CONTROL_TYPES, FieldControlType, FieldSelectorRegistry, FIELD_SELECTOR_REGISTRY_BASE, FIELD_SELECTOR_REGISTRY_DISABLE_DEFAULTS, LoggerService, resolveInlineFilterControlType, DEFAULT_FIELD_SELECTOR_CONTROL_TYPE_MAP, PraxisIconDirective, resolveBuiltinPresets, createCpfCnpjValidator, NumericFormat, interpolatePraxisTranslation, ComponentMetadataRegistry, FIELD_METADATA_CAPABILITIES } from '@praxisui/core';
|
|
6
|
+
import { providePraxisI18n, PraxisI18nService, isCssTextTransform, getTextTransformer, GenericCrudService, GlobalConfigService, INLINE_FILTER_CONTROL_TYPES, FieldControlType, FieldSelectorRegistry, FIELD_SELECTOR_REGISTRY_BASE, FIELD_SELECTOR_REGISTRY_DISABLE_DEFAULTS, LoggerService, resolveInlineFilterControlType, DEFAULT_FIELD_SELECTOR_CONTROL_TYPE_MAP, resolveValuePresentation, FieldDataType, PraxisIconDirective, resolveBuiltinPresets, createCpfCnpjValidator, NumericFormat, interpolatePraxisTranslation, ComponentMetadataRegistry, FIELD_METADATA_CAPABILITIES } from '@praxisui/core';
|
|
7
7
|
import { BehaviorSubject, combineLatest, Subscription, firstValueFrom, fromEvent, take as take$1, of, EMPTY } from 'rxjs';
|
|
8
8
|
import { Router } from '@angular/router';
|
|
9
9
|
import * as i1$2 from '@angular/material/dialog';
|
|
@@ -12,7 +12,7 @@ import { take, startWith, debounceTime, filter, distinctUntilChanged, switchMap,
|
|
|
12
12
|
import * as i4$2 from '@angular/material/select';
|
|
13
13
|
import { MatSelect, MatSelectModule } from '@angular/material/select';
|
|
14
14
|
import * as i1 from '@angular/common';
|
|
15
|
-
import { CommonModule, registerLocaleData, CurrencyPipe } from '@angular/common';
|
|
15
|
+
import { formatDate, CommonModule, registerLocaleData, CurrencyPipe } from '@angular/common';
|
|
16
16
|
import * as i1$1 from '@angular/material/button';
|
|
17
17
|
import { MatButtonModule } from '@angular/material/button';
|
|
18
18
|
import * as i3 from '@angular/material/icon';
|
|
@@ -4147,47 +4147,33 @@ const LoggerPresets = {
|
|
|
4147
4147
|
}
|
|
4148
4148
|
};
|
|
4149
4149
|
|
|
4150
|
+
const EMPTY_DISPLAY = '-- Nao informado';
|
|
4150
4151
|
function isISODate(v) {
|
|
4151
4152
|
return /^\d{4}-\d{2}-\d{2}$/.test(v);
|
|
4152
4153
|
}
|
|
4153
4154
|
function isISODateTimeLocal(v) {
|
|
4154
4155
|
return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(:\d{2})?$/.test(v);
|
|
4155
4156
|
}
|
|
4156
|
-
function
|
|
4157
|
-
try {
|
|
4158
|
-
const d = new Date(v);
|
|
4159
|
-
if (!isNaN(d.getTime()))
|
|
4160
|
-
return d.toLocaleDateString();
|
|
4161
|
-
}
|
|
4162
|
-
catch { }
|
|
4163
|
-
return v;
|
|
4164
|
-
}
|
|
4165
|
-
function tryFormatDateTime(v) {
|
|
4166
|
-
try {
|
|
4167
|
-
const d = new Date(v.replace('T', ' '));
|
|
4168
|
-
if (!isNaN(d.getTime()))
|
|
4169
|
-
return d.toLocaleString();
|
|
4170
|
-
}
|
|
4171
|
-
catch { }
|
|
4172
|
-
return v.replace('T', ' ');
|
|
4173
|
-
}
|
|
4174
|
-
function formatDisplayValue(field, value) {
|
|
4157
|
+
function formatDisplayValue(field, value, options) {
|
|
4175
4158
|
if (value == null)
|
|
4176
|
-
return
|
|
4177
|
-
if (typeof value === 'boolean') {
|
|
4178
|
-
return value ? 'Sim' : 'Não';
|
|
4179
|
-
}
|
|
4180
|
-
// Arrays → join labels or values
|
|
4159
|
+
return EMPTY_DISPLAY;
|
|
4181
4160
|
if (Array.isArray(value)) {
|
|
4182
4161
|
const parts = value.map((item) => {
|
|
4183
4162
|
if (item && typeof item === 'object') {
|
|
4184
|
-
return item.label ??
|
|
4163
|
+
return (item.label ??
|
|
4164
|
+
item.name ??
|
|
4165
|
+
String(item.id ?? ''));
|
|
4185
4166
|
}
|
|
4186
4167
|
return String(item);
|
|
4187
4168
|
});
|
|
4188
4169
|
return parts.filter(Boolean).join(', ');
|
|
4189
4170
|
}
|
|
4190
|
-
|
|
4171
|
+
if (value instanceof Date) {
|
|
4172
|
+
const explicit = resolveFieldPresentation(field, value, options);
|
|
4173
|
+
return explicit
|
|
4174
|
+
? formatTypedValue(field, value, explicit)
|
|
4175
|
+
: formatHeuristicDateTime(value, options);
|
|
4176
|
+
}
|
|
4191
4177
|
if (value && typeof value === 'object') {
|
|
4192
4178
|
const obj = value;
|
|
4193
4179
|
if (obj.label)
|
|
@@ -4205,29 +4191,30 @@ function formatDisplayValue(field, value) {
|
|
|
4205
4191
|
return String(obj);
|
|
4206
4192
|
}
|
|
4207
4193
|
}
|
|
4194
|
+
const presentation = resolveFieldPresentation(field, value, options);
|
|
4208
4195
|
if (typeof value === 'string') {
|
|
4209
4196
|
const trimmed = value.trim();
|
|
4210
4197
|
if (!trimmed)
|
|
4211
|
-
return
|
|
4198
|
+
return EMPTY_DISPLAY;
|
|
4199
|
+
if (presentation) {
|
|
4200
|
+
return formatTypedValue(field, trimmed, presentation);
|
|
4201
|
+
}
|
|
4212
4202
|
if (isISODate(trimmed))
|
|
4213
|
-
return
|
|
4214
|
-
if (isISODateTimeLocal(trimmed))
|
|
4215
|
-
return
|
|
4203
|
+
return formatHeuristicDate(trimmed, options);
|
|
4204
|
+
if (isISODateTimeLocal(trimmed)) {
|
|
4205
|
+
return formatHeuristicDateTime(trimmed, options);
|
|
4206
|
+
}
|
|
4216
4207
|
return trimmed;
|
|
4217
4208
|
}
|
|
4218
4209
|
if (typeof value === 'number') {
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
}
|
|
4228
|
-
catch {
|
|
4229
|
-
return String(value);
|
|
4230
|
-
}
|
|
4210
|
+
if (presentation) {
|
|
4211
|
+
return formatTypedValue(field, value, presentation);
|
|
4212
|
+
}
|
|
4213
|
+
return String(value);
|
|
4214
|
+
}
|
|
4215
|
+
if (typeof value === 'boolean') {
|
|
4216
|
+
if (presentation) {
|
|
4217
|
+
return formatTypedValue(field, value, presentation);
|
|
4231
4218
|
}
|
|
4232
4219
|
return String(value);
|
|
4233
4220
|
}
|
|
@@ -4237,22 +4224,437 @@ function formatDisplayValue(field, value) {
|
|
|
4237
4224
|
* Formats a value for presentation and linkifies emails/URLs.
|
|
4238
4225
|
* Rely on Angular's built-in sanitization when binding via [innerHTML].
|
|
4239
4226
|
*/
|
|
4240
|
-
function formatDisplayHtml(field, value) {
|
|
4241
|
-
const text = formatDisplayValue(field, value);
|
|
4242
|
-
// Email
|
|
4227
|
+
function formatDisplayHtml(field, value, options) {
|
|
4228
|
+
const text = formatDisplayValue(field, value, options);
|
|
4243
4229
|
const emailRe = /^([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,})$/i;
|
|
4244
4230
|
if (emailRe.test(text)) {
|
|
4245
4231
|
const mailto = `mailto:${text}`;
|
|
4246
4232
|
return `<a href="${mailto}">${text}</a>`;
|
|
4247
4233
|
}
|
|
4248
|
-
// URL (http/https only)
|
|
4249
4234
|
const urlRe = /^(https?:\/\/[^\s]+)$/i;
|
|
4250
4235
|
if (urlRe.test(text)) {
|
|
4251
|
-
|
|
4252
|
-
return `<a href="${url}" target="_blank" rel="noopener noreferrer">${text}</a>`;
|
|
4236
|
+
return `<a href="${text}" target="_blank" rel="noopener noreferrer">${text}</a>`;
|
|
4253
4237
|
}
|
|
4254
4238
|
return text;
|
|
4255
4239
|
}
|
|
4240
|
+
function resolveFieldPresentation(field, value, options) {
|
|
4241
|
+
const config = buildValuePresentationConfig(field, value);
|
|
4242
|
+
if (!config)
|
|
4243
|
+
return null;
|
|
4244
|
+
return resolveValuePresentation(config, {
|
|
4245
|
+
valueLocale: resolveFieldLocale(field),
|
|
4246
|
+
localization: mergeLocalization(options?.localization, buildLegacyFieldLocalization(field)),
|
|
4247
|
+
surfaceLocale: options?.surfaceLocale || undefined,
|
|
4248
|
+
appLocale: options?.appLocale || undefined,
|
|
4249
|
+
});
|
|
4250
|
+
}
|
|
4251
|
+
function buildValuePresentationConfig(field, value) {
|
|
4252
|
+
const explicit = normalizeExplicitValuePresentation(field?.valuePresentation);
|
|
4253
|
+
if (explicit) {
|
|
4254
|
+
return {
|
|
4255
|
+
...explicit,
|
|
4256
|
+
currency: {
|
|
4257
|
+
...resolveLegacyCurrencyOverrides(field),
|
|
4258
|
+
...(explicit.currency || {}),
|
|
4259
|
+
},
|
|
4260
|
+
number: {
|
|
4261
|
+
...resolveLegacyNumberOverrides(field),
|
|
4262
|
+
...(explicit.number || {}),
|
|
4263
|
+
},
|
|
4264
|
+
};
|
|
4265
|
+
}
|
|
4266
|
+
const inferredType = inferValuePresentationType(field, value);
|
|
4267
|
+
if (!inferredType)
|
|
4268
|
+
return null;
|
|
4269
|
+
return {
|
|
4270
|
+
type: inferredType,
|
|
4271
|
+
style: inferLegacyPresentationStyle(field),
|
|
4272
|
+
format: normalizeString(field?.format) || undefined,
|
|
4273
|
+
currency: resolveLegacyCurrencyOverrides(field),
|
|
4274
|
+
number: resolveLegacyNumberOverrides(field),
|
|
4275
|
+
};
|
|
4276
|
+
}
|
|
4277
|
+
function normalizeExplicitValuePresentation(value) {
|
|
4278
|
+
if (!value || typeof value !== 'object')
|
|
4279
|
+
return null;
|
|
4280
|
+
const config = value;
|
|
4281
|
+
if (!config.type)
|
|
4282
|
+
return null;
|
|
4283
|
+
return config;
|
|
4284
|
+
}
|
|
4285
|
+
function inferValuePresentationType(field, value) {
|
|
4286
|
+
const controlType = String(field?.controlType || '').trim().toLowerCase();
|
|
4287
|
+
const dataType = String(field?.dataType || '').trim().toLowerCase();
|
|
4288
|
+
const numericFormat = String(field?.numericFormat || '').trim().toLowerCase();
|
|
4289
|
+
const format = normalizeString(field?.format)?.toLowerCase();
|
|
4290
|
+
if (field?.currency || field?.numberFormat?.currency) {
|
|
4291
|
+
return 'currency';
|
|
4292
|
+
}
|
|
4293
|
+
if (numericFormat === 'percent' || format === 'percent') {
|
|
4294
|
+
return 'percentage';
|
|
4295
|
+
}
|
|
4296
|
+
if (controlType === 'currency' ||
|
|
4297
|
+
controlType === 'inlinecurrency') {
|
|
4298
|
+
return 'currency';
|
|
4299
|
+
}
|
|
4300
|
+
if (controlType === 'date' ||
|
|
4301
|
+
controlType === 'dateinput' ||
|
|
4302
|
+
controlType === 'inlinedate') {
|
|
4303
|
+
return 'date';
|
|
4304
|
+
}
|
|
4305
|
+
if (controlType === 'datetime' ||
|
|
4306
|
+
controlType === 'datetimelocal' ||
|
|
4307
|
+
controlType === 'datetimepicker') {
|
|
4308
|
+
return 'datetime';
|
|
4309
|
+
}
|
|
4310
|
+
if (controlType === 'time' ||
|
|
4311
|
+
controlType === 'timepicker' ||
|
|
4312
|
+
controlType === 'inlinetime') {
|
|
4313
|
+
return 'time';
|
|
4314
|
+
}
|
|
4315
|
+
if (controlType === 'numerictextbox' ||
|
|
4316
|
+
controlType === 'inlinenumber' ||
|
|
4317
|
+
controlType === 'year' ||
|
|
4318
|
+
controlType === 'month') {
|
|
4319
|
+
return 'number';
|
|
4320
|
+
}
|
|
4321
|
+
if (dataType === FieldDataType.DATE) {
|
|
4322
|
+
return 'date';
|
|
4323
|
+
}
|
|
4324
|
+
if (dataType === FieldDataType.NUMBER) {
|
|
4325
|
+
return 'number';
|
|
4326
|
+
}
|
|
4327
|
+
if (typeof value === 'boolean') {
|
|
4328
|
+
return 'boolean';
|
|
4329
|
+
}
|
|
4330
|
+
if (typeof value === 'string') {
|
|
4331
|
+
if (isISODate(value.trim()))
|
|
4332
|
+
return 'date';
|
|
4333
|
+
if (isISODateTimeLocal(value.trim()))
|
|
4334
|
+
return 'datetime';
|
|
4335
|
+
}
|
|
4336
|
+
return null;
|
|
4337
|
+
}
|
|
4338
|
+
function inferLegacyPresentationStyle(field) {
|
|
4339
|
+
const style = normalizeString(field?.displayStyle || field?.styleVariant);
|
|
4340
|
+
switch ((style || '').toLowerCase()) {
|
|
4341
|
+
case 'short':
|
|
4342
|
+
return 'short';
|
|
4343
|
+
case 'medium':
|
|
4344
|
+
return 'medium';
|
|
4345
|
+
case 'long':
|
|
4346
|
+
return 'long';
|
|
4347
|
+
case 'full':
|
|
4348
|
+
return 'full';
|
|
4349
|
+
case 'compact':
|
|
4350
|
+
return 'compact';
|
|
4351
|
+
default:
|
|
4352
|
+
return undefined;
|
|
4353
|
+
}
|
|
4354
|
+
}
|
|
4355
|
+
function resolveFieldLocale(field) {
|
|
4356
|
+
return (normalizeString(field?.locale) ||
|
|
4357
|
+
normalizeString(field?.numberFormat?.locale) ||
|
|
4358
|
+
undefined);
|
|
4359
|
+
}
|
|
4360
|
+
function buildLegacyFieldLocalization(field) {
|
|
4361
|
+
const locale = resolveFieldLocale(field);
|
|
4362
|
+
const currency = resolveLegacyCurrencyOverrides(field);
|
|
4363
|
+
const number = resolveLegacyNumberOverrides(field);
|
|
4364
|
+
if (!locale && !currency && !number) {
|
|
4365
|
+
return undefined;
|
|
4366
|
+
}
|
|
4367
|
+
return {
|
|
4368
|
+
...(locale ? { locale } : {}),
|
|
4369
|
+
direction: 'ltr',
|
|
4370
|
+
...(currency ? { currency } : {}),
|
|
4371
|
+
...(number ? { number } : {}),
|
|
4372
|
+
};
|
|
4373
|
+
}
|
|
4374
|
+
function resolveLegacyCurrencyOverrides(field) {
|
|
4375
|
+
const code = normalizeString(field?.currency) ||
|
|
4376
|
+
normalizeString(field?.numberFormat?.currency);
|
|
4377
|
+
const position = normalizeCurrencyPosition(field?.currencyPosition) ||
|
|
4378
|
+
normalizeCurrencyPosition(field?.numberFormat?.currencyPosition);
|
|
4379
|
+
const precision = resolveLegacyPrecision(field);
|
|
4380
|
+
if (!code && !position && precision == null) {
|
|
4381
|
+
return undefined;
|
|
4382
|
+
}
|
|
4383
|
+
return {
|
|
4384
|
+
code: code || 'USD',
|
|
4385
|
+
symbol: code || 'USD',
|
|
4386
|
+
position: position || 'before',
|
|
4387
|
+
spacing: true,
|
|
4388
|
+
precision: precision ?? 2,
|
|
4389
|
+
};
|
|
4390
|
+
}
|
|
4391
|
+
function resolveLegacyNumberOverrides(field) {
|
|
4392
|
+
const precision = resolveLegacyPrecision(field);
|
|
4393
|
+
const decimalSeparator = normalizeString(field?.decimalSeparator);
|
|
4394
|
+
const thousandsSeparator = normalizeString(field?.thousandsSeparator);
|
|
4395
|
+
if (precision == null &&
|
|
4396
|
+
!decimalSeparator &&
|
|
4397
|
+
!thousandsSeparator) {
|
|
4398
|
+
return undefined;
|
|
4399
|
+
}
|
|
4400
|
+
return {
|
|
4401
|
+
defaultPrecision: precision ?? 2,
|
|
4402
|
+
decimalSeparator: decimalSeparator || '.',
|
|
4403
|
+
thousandsSeparator: thousandsSeparator || ',',
|
|
4404
|
+
negativeSign: '-',
|
|
4405
|
+
negativeSignPosition: 'before',
|
|
4406
|
+
};
|
|
4407
|
+
}
|
|
4408
|
+
function resolveLegacyPrecision(field) {
|
|
4409
|
+
const direct = toFiniteNumber(field?.decimalPlaces);
|
|
4410
|
+
if (direct != null)
|
|
4411
|
+
return direct;
|
|
4412
|
+
const nested = toFiniteNumber(field?.numberFormat?.decimalPlaces);
|
|
4413
|
+
if (nested != null)
|
|
4414
|
+
return nested;
|
|
4415
|
+
return undefined;
|
|
4416
|
+
}
|
|
4417
|
+
function normalizeCurrencyPosition(value) {
|
|
4418
|
+
return value === 'before' || value === 'after' ? value : undefined;
|
|
4419
|
+
}
|
|
4420
|
+
function mergeLocalization(base, override) {
|
|
4421
|
+
if (!base && !override)
|
|
4422
|
+
return undefined;
|
|
4423
|
+
return {
|
|
4424
|
+
...(base || {}),
|
|
4425
|
+
...(override || {}),
|
|
4426
|
+
...((base?.dateTime || override?.dateTime)
|
|
4427
|
+
? {
|
|
4428
|
+
dateTime: {
|
|
4429
|
+
...(base?.dateTime || {}),
|
|
4430
|
+
...(override?.dateTime || {}),
|
|
4431
|
+
},
|
|
4432
|
+
}
|
|
4433
|
+
: {}),
|
|
4434
|
+
...((base?.number || override?.number)
|
|
4435
|
+
? {
|
|
4436
|
+
number: {
|
|
4437
|
+
...(base?.number || {}),
|
|
4438
|
+
...(override?.number || {}),
|
|
4439
|
+
},
|
|
4440
|
+
}
|
|
4441
|
+
: {}),
|
|
4442
|
+
...((base?.currency || override?.currency)
|
|
4443
|
+
? {
|
|
4444
|
+
currency: {
|
|
4445
|
+
...(base?.currency || {}),
|
|
4446
|
+
...(override?.currency || {}),
|
|
4447
|
+
},
|
|
4448
|
+
}
|
|
4449
|
+
: {}),
|
|
4450
|
+
...((base?.formatting || override?.formatting)
|
|
4451
|
+
? {
|
|
4452
|
+
formatting: {
|
|
4453
|
+
...(base?.formatting || {}),
|
|
4454
|
+
...(override?.formatting || {}),
|
|
4455
|
+
},
|
|
4456
|
+
}
|
|
4457
|
+
: {}),
|
|
4458
|
+
};
|
|
4459
|
+
}
|
|
4460
|
+
function formatTypedValue(field, value, presentation) {
|
|
4461
|
+
switch (presentation.type) {
|
|
4462
|
+
case 'boolean':
|
|
4463
|
+
return formatBooleanPresentation(value, presentation.locale);
|
|
4464
|
+
case 'date':
|
|
4465
|
+
case 'datetime':
|
|
4466
|
+
case 'time':
|
|
4467
|
+
return formatDatePresentation(value, presentation);
|
|
4468
|
+
case 'currency':
|
|
4469
|
+
return formatNumberPresentation(value, presentation, {
|
|
4470
|
+
style: 'currency',
|
|
4471
|
+
currency: presentation.currency?.code || 'USD',
|
|
4472
|
+
currencyPosition: presentation.currency?.position ||
|
|
4473
|
+
normalizeCurrencyPosition(field?.currencyPosition),
|
|
4474
|
+
});
|
|
4475
|
+
case 'percentage':
|
|
4476
|
+
return formatNumberPresentation(value, presentation, {
|
|
4477
|
+
style: 'percent',
|
|
4478
|
+
});
|
|
4479
|
+
case 'number':
|
|
4480
|
+
return formatNumberPresentation(value, presentation, {
|
|
4481
|
+
style: 'decimal',
|
|
4482
|
+
});
|
|
4483
|
+
default:
|
|
4484
|
+
return String(value);
|
|
4485
|
+
}
|
|
4486
|
+
}
|
|
4487
|
+
function formatBooleanPresentation(value, locale) {
|
|
4488
|
+
const [trueLabel, falseLabel] = resolveBooleanLabels(locale);
|
|
4489
|
+
if (typeof value === 'string') {
|
|
4490
|
+
const normalized = value.trim().toLowerCase();
|
|
4491
|
+
if (normalized === 'true')
|
|
4492
|
+
return trueLabel;
|
|
4493
|
+
if (normalized === 'false')
|
|
4494
|
+
return falseLabel;
|
|
4495
|
+
}
|
|
4496
|
+
return value ? trueLabel : falseLabel;
|
|
4497
|
+
}
|
|
4498
|
+
function resolveBooleanLabels(locale) {
|
|
4499
|
+
const normalized = String(locale || '').trim().toLowerCase();
|
|
4500
|
+
if (normalized.startsWith('pt')) {
|
|
4501
|
+
return ['Sim', 'Nao'];
|
|
4502
|
+
}
|
|
4503
|
+
if (normalized.startsWith('es')) {
|
|
4504
|
+
return ['Si', 'No'];
|
|
4505
|
+
}
|
|
4506
|
+
if (normalized.startsWith('fr')) {
|
|
4507
|
+
return ['Oui', 'Non'];
|
|
4508
|
+
}
|
|
4509
|
+
if (normalized.startsWith('de')) {
|
|
4510
|
+
return ['Ja', 'Nein'];
|
|
4511
|
+
}
|
|
4512
|
+
return ['Yes', 'No'];
|
|
4513
|
+
}
|
|
4514
|
+
function formatDatePresentation(value, presentation) {
|
|
4515
|
+
const dt = presentation.type === 'date'
|
|
4516
|
+
? coerceDateOnlyCalendarValue(value)
|
|
4517
|
+
: coerceDateValue(value, presentation.type);
|
|
4518
|
+
if (Number.isNaN(dt.getTime())) {
|
|
4519
|
+
return String(value);
|
|
4520
|
+
}
|
|
4521
|
+
try {
|
|
4522
|
+
return formatDate(dt, presentation.format || 'shortDate', presentation.locale);
|
|
4523
|
+
}
|
|
4524
|
+
catch {
|
|
4525
|
+
return new Intl.DateTimeFormat(presentation.locale || undefined).format(dt);
|
|
4526
|
+
}
|
|
4527
|
+
}
|
|
4528
|
+
function formatNumberPresentation(value, presentation, kind) {
|
|
4529
|
+
const numericValue = typeof value === 'number'
|
|
4530
|
+
? value
|
|
4531
|
+
: value instanceof Date
|
|
4532
|
+
? value.getTime()
|
|
4533
|
+
: Number(value);
|
|
4534
|
+
if (!Number.isFinite(numericValue)) {
|
|
4535
|
+
return String(value);
|
|
4536
|
+
}
|
|
4537
|
+
const digits = parseDigitsFormat(presentation.format);
|
|
4538
|
+
const options = {
|
|
4539
|
+
style: kind.style,
|
|
4540
|
+
};
|
|
4541
|
+
if (digits) {
|
|
4542
|
+
options.minimumIntegerDigits = digits.minimumIntegerDigits;
|
|
4543
|
+
options.minimumFractionDigits = digits.minimumFractionDigits;
|
|
4544
|
+
options.maximumFractionDigits = digits.maximumFractionDigits;
|
|
4545
|
+
}
|
|
4546
|
+
if (kind.style === 'currency') {
|
|
4547
|
+
options.currency = kind.currency || 'USD';
|
|
4548
|
+
const parts = (presentation.format || '').split('|').filter(Boolean);
|
|
4549
|
+
if ((parts[1] || '').trim() === 'code') {
|
|
4550
|
+
options.currencyDisplay = 'code';
|
|
4551
|
+
}
|
|
4552
|
+
}
|
|
4553
|
+
const formatter = new Intl.NumberFormat(presentation.locale || undefined, options);
|
|
4554
|
+
const formatted = formatter.format(numericValue);
|
|
4555
|
+
if (kind.style !== 'currency' || !kind.currencyPosition) {
|
|
4556
|
+
return formatted;
|
|
4557
|
+
}
|
|
4558
|
+
return applyCurrencyPosition(formatter, numericValue, formatted, kind.currencyPosition);
|
|
4559
|
+
}
|
|
4560
|
+
function applyCurrencyPosition(formatter, value, formatted, position) {
|
|
4561
|
+
const parts = formatter.formatToParts(value);
|
|
4562
|
+
const currency = parts
|
|
4563
|
+
.filter((part) => part.type === 'currency')
|
|
4564
|
+
.map((part) => part.value)
|
|
4565
|
+
.join('');
|
|
4566
|
+
if (!currency)
|
|
4567
|
+
return formatted;
|
|
4568
|
+
const withoutCurrency = parts
|
|
4569
|
+
.filter((part) => part.type !== 'currency')
|
|
4570
|
+
.map((part) => part.value)
|
|
4571
|
+
.join('')
|
|
4572
|
+
.trim();
|
|
4573
|
+
if (!withoutCurrency)
|
|
4574
|
+
return formatted;
|
|
4575
|
+
return position === 'after'
|
|
4576
|
+
? `${withoutCurrency} ${currency}`
|
|
4577
|
+
: `${currency} ${withoutCurrency}`;
|
|
4578
|
+
}
|
|
4579
|
+
function parseDigitsFormat(format) {
|
|
4580
|
+
if (!format)
|
|
4581
|
+
return null;
|
|
4582
|
+
const match = /^(\d+)\.(\d+)-(\d+)$/.exec(format.trim());
|
|
4583
|
+
if (!match)
|
|
4584
|
+
return null;
|
|
4585
|
+
return {
|
|
4586
|
+
minimumIntegerDigits: Number(match[1]),
|
|
4587
|
+
minimumFractionDigits: Number(match[2]),
|
|
4588
|
+
maximumFractionDigits: Number(match[3]),
|
|
4589
|
+
};
|
|
4590
|
+
}
|
|
4591
|
+
function formatHeuristicDate(value, options) {
|
|
4592
|
+
try {
|
|
4593
|
+
return formatDate(coerceDateValue(value, 'date'), 'shortDate', options?.surfaceLocale || options?.appLocale || 'en-US');
|
|
4594
|
+
}
|
|
4595
|
+
catch {
|
|
4596
|
+
return value;
|
|
4597
|
+
}
|
|
4598
|
+
}
|
|
4599
|
+
function formatHeuristicDateTime(value, options) {
|
|
4600
|
+
try {
|
|
4601
|
+
const source = coerceDateValue(value, 'datetime');
|
|
4602
|
+
return formatDate(source, 'short', options?.surfaceLocale || options?.appLocale || 'en-US');
|
|
4603
|
+
}
|
|
4604
|
+
catch {
|
|
4605
|
+
return value instanceof Date ? String(value) : value.replace('T', ' ');
|
|
4606
|
+
}
|
|
4607
|
+
}
|
|
4608
|
+
function toFiniteNumber(value) {
|
|
4609
|
+
if (typeof value !== 'number' || Number.isNaN(value)) {
|
|
4610
|
+
return undefined;
|
|
4611
|
+
}
|
|
4612
|
+
return Math.floor(value);
|
|
4613
|
+
}
|
|
4614
|
+
function normalizeString(value) {
|
|
4615
|
+
if (typeof value !== 'string')
|
|
4616
|
+
return undefined;
|
|
4617
|
+
const trimmed = value.trim();
|
|
4618
|
+
return trimmed ? trimmed : undefined;
|
|
4619
|
+
}
|
|
4620
|
+
function coerceDateValue(value, type) {
|
|
4621
|
+
if (value instanceof Date) {
|
|
4622
|
+
return value;
|
|
4623
|
+
}
|
|
4624
|
+
if (typeof value === 'string') {
|
|
4625
|
+
const trimmed = value.trim();
|
|
4626
|
+
if (type === 'date' && isISODate(trimmed)) {
|
|
4627
|
+
const [year, month, day] = trimmed.split('-').map(Number);
|
|
4628
|
+
return new Date(year, month - 1, day);
|
|
4629
|
+
}
|
|
4630
|
+
if (type === 'datetime' && isISODateTimeLocal(trimmed)) {
|
|
4631
|
+
return new Date(trimmed);
|
|
4632
|
+
}
|
|
4633
|
+
}
|
|
4634
|
+
return new Date(value);
|
|
4635
|
+
}
|
|
4636
|
+
function coerceDateOnlyCalendarValue(value) {
|
|
4637
|
+
if (value instanceof Date) {
|
|
4638
|
+
if (Number.isNaN(value.getTime())) {
|
|
4639
|
+
return value;
|
|
4640
|
+
}
|
|
4641
|
+
const localMidnight = value.getHours() === 0 &&
|
|
4642
|
+
value.getMinutes() === 0 &&
|
|
4643
|
+
value.getSeconds() === 0 &&
|
|
4644
|
+
value.getMilliseconds() === 0;
|
|
4645
|
+
if (localMidnight) {
|
|
4646
|
+
return new Date(value.getFullYear(), value.getMonth(), value.getDate());
|
|
4647
|
+
}
|
|
4648
|
+
const utcMidnight = value.getUTCHours() === 0 &&
|
|
4649
|
+
value.getUTCMinutes() === 0 &&
|
|
4650
|
+
value.getUTCSeconds() === 0 &&
|
|
4651
|
+
value.getUTCMilliseconds() === 0;
|
|
4652
|
+
if (utcMidnight) {
|
|
4653
|
+
return new Date(value.getUTCFullYear(), value.getUTCMonth(), value.getUTCDate());
|
|
4654
|
+
}
|
|
4655
|
+
}
|
|
4656
|
+
return coerceDateValue(value, 'date');
|
|
4657
|
+
}
|
|
4256
4658
|
|
|
4257
4659
|
/**
|
|
4258
4660
|
* Internal wrapper used by {@link DynamicFieldLoaderDirective}.
|
|
@@ -4262,6 +4664,7 @@ function formatDisplayHtml(field, value) {
|
|
|
4262
4664
|
* project additional chrome around the field.
|
|
4263
4665
|
*/
|
|
4264
4666
|
class FieldShellComponent {
|
|
4667
|
+
hostLocale = inject(LOCALE_ID, { optional: true }) ?? 'en-US';
|
|
4265
4668
|
/** Metadata for the dynamic field being rendered. */
|
|
4266
4669
|
field;
|
|
4267
4670
|
/** Index position of the field within the directive's list. */
|
|
@@ -4375,11 +4778,21 @@ class FieldShellComponent {
|
|
|
4375
4778
|
const raw = this.control?.value;
|
|
4376
4779
|
try {
|
|
4377
4780
|
const fn = this.field?.transformDisplayValue;
|
|
4378
|
-
const formatted = typeof fn === 'function'
|
|
4781
|
+
const formatted = typeof fn === 'function'
|
|
4782
|
+
? fn(raw)
|
|
4783
|
+
: formatDisplayValue(this.field, raw, {
|
|
4784
|
+
appLocale: this.hostLocale,
|
|
4785
|
+
surfaceLocale: this.field?.localization?.locale ?? this.field?.locale ?? undefined,
|
|
4786
|
+
localization: this.field?.localization ?? undefined,
|
|
4787
|
+
});
|
|
4379
4788
|
return formatted == null ? '' : String(formatted);
|
|
4380
4789
|
}
|
|
4381
4790
|
catch {
|
|
4382
|
-
return formatDisplayValue(this.field, raw
|
|
4791
|
+
return formatDisplayValue(this.field, raw, {
|
|
4792
|
+
appLocale: this.hostLocale,
|
|
4793
|
+
surfaceLocale: this.field?.localization?.locale ?? this.field?.locale ?? undefined,
|
|
4794
|
+
localization: this.field?.localization ?? undefined,
|
|
4795
|
+
});
|
|
4383
4796
|
}
|
|
4384
4797
|
}
|
|
4385
4798
|
getPresentationHtml() {
|
|
@@ -4388,10 +4801,18 @@ class FieldShellComponent {
|
|
|
4388
4801
|
const fn = this.field?.transformDisplayValue;
|
|
4389
4802
|
const formatted = typeof fn === 'function' ? fn(raw) : null;
|
|
4390
4803
|
const val = formatted == null ? raw : formatted;
|
|
4391
|
-
return formatDisplayHtml(this.field, val
|
|
4804
|
+
return formatDisplayHtml(this.field, val, {
|
|
4805
|
+
appLocale: this.hostLocale,
|
|
4806
|
+
surfaceLocale: this.field?.localization?.locale ?? this.field?.locale ?? undefined,
|
|
4807
|
+
localization: this.field?.localization ?? undefined,
|
|
4808
|
+
});
|
|
4392
4809
|
}
|
|
4393
4810
|
catch {
|
|
4394
|
-
return formatDisplayHtml(this.field, raw
|
|
4811
|
+
return formatDisplayHtml(this.field, raw, {
|
|
4812
|
+
appLocale: this.hostLocale,
|
|
4813
|
+
surfaceLocale: this.field?.localization?.locale ?? this.field?.locale ?? undefined,
|
|
4814
|
+
localization: this.field?.localization ?? undefined,
|
|
4815
|
+
});
|
|
4395
4816
|
}
|
|
4396
4817
|
}
|
|
4397
4818
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: FieldShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -5004,9 +5425,12 @@ class DynamicFieldLoaderDirective {
|
|
|
5004
5425
|
});
|
|
5005
5426
|
this.renderFields();
|
|
5006
5427
|
}
|
|
5007
|
-
if (changes['
|
|
5428
|
+
if (changes['presentationMode']) {
|
|
5429
|
+
this.dbg('[DFL] ngOnChanges: presentationMode changed -> re-rendering fields');
|
|
5430
|
+
this.renderFields();
|
|
5431
|
+
}
|
|
5432
|
+
else if (changes['readonlyMode'] ||
|
|
5008
5433
|
changes['disabledMode'] ||
|
|
5009
|
-
changes['presentationMode'] ||
|
|
5010
5434
|
changes['visible']) {
|
|
5011
5435
|
this.applyGlobalStates();
|
|
5012
5436
|
}
|
|
@@ -5497,6 +5921,15 @@ class DynamicFieldLoaderDirective {
|
|
|
5497
5921
|
}));
|
|
5498
5922
|
}
|
|
5499
5923
|
this.shellSubscriptions.set(field.name, subscriptions);
|
|
5924
|
+
const shouldSkipComponentCreation = shellRef.instance.effectivePresentationMode &&
|
|
5925
|
+
!shellRef.instance.renderContentInPresentation();
|
|
5926
|
+
if (shouldSkipComponentCreation) {
|
|
5927
|
+
this.dbg('[DFL] step: skip field component creation in presentation mode', {
|
|
5928
|
+
name: field.name,
|
|
5929
|
+
});
|
|
5930
|
+
this.shellRefs.set(field.name, shellRef);
|
|
5931
|
+
return null;
|
|
5932
|
+
}
|
|
5500
5933
|
// Criar o componente dentro do shell
|
|
5501
5934
|
this.dbg('[DFL] step: create field component start', { name: field.name });
|
|
5502
5935
|
const componentRef = shellRef.instance.vc.createComponent(componentType);
|
|
@@ -9022,15 +9455,15 @@ class MaterialDatepickerComponent extends SimpleBaseInputComponent {
|
|
|
9022
9455
|
presentationMode = false;
|
|
9023
9456
|
minDate = computed(() => {
|
|
9024
9457
|
const md = this.metadata()?.minDate;
|
|
9025
|
-
return typeof md === 'string' ?
|
|
9458
|
+
return typeof md === 'string' ? this.parseDateOnlyString(md) : md;
|
|
9026
9459
|
}, ...(ngDevMode ? [{ debugName: "minDate" }] : []));
|
|
9027
9460
|
maxDate = computed(() => {
|
|
9028
9461
|
const md = this.metadata()?.maxDate;
|
|
9029
|
-
return typeof md === 'string' ?
|
|
9462
|
+
return typeof md === 'string' ? this.parseDateOnlyString(md) : md;
|
|
9030
9463
|
}, ...(ngDevMode ? [{ debugName: "maxDate" }] : []));
|
|
9031
9464
|
startAt = computed(() => {
|
|
9032
9465
|
const sa = this.metadata()?.startAt;
|
|
9033
|
-
return typeof sa === 'string' ?
|
|
9466
|
+
return typeof sa === 'string' ? this.parseDateOnlyString(sa) : (sa ?? null);
|
|
9034
9467
|
}, ...(ngDevMode ? [{ debugName: "startAt" }] : []));
|
|
9035
9468
|
onDateChange(event) {
|
|
9036
9469
|
this.setValue(event.value ?? null);
|
|
@@ -9101,6 +9534,14 @@ class MaterialDatepickerComponent extends SimpleBaseInputComponent {
|
|
|
9101
9534
|
}
|
|
9102
9535
|
return metadata;
|
|
9103
9536
|
}
|
|
9537
|
+
parseDateOnlyString(value) {
|
|
9538
|
+
const trimmed = value.trim();
|
|
9539
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) {
|
|
9540
|
+
const [year, month, day] = trimmed.split('-').map(Number);
|
|
9541
|
+
return new Date(year, month - 1, day);
|
|
9542
|
+
}
|
|
9543
|
+
return new Date(trimmed);
|
|
9544
|
+
}
|
|
9104
9545
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.17", ngImport: i0, type: MaterialDatepickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
9105
9546
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.17", type: MaterialDatepickerComponent, isStandalone: true, selector: "pdx-material-datepicker", inputs: { readonlyMode: "readonlyMode", disabledMode: "disabledMode", visible: "visible", presentationMode: "presentationMode" }, outputs: { validationChange: "validationChange" }, host: { properties: { "class": "componentCssClasses()", "class.praxis-disabled": "disabledMode", "style.display": "visible ? null : \"none\"", "attr.aria-hidden": "visible ? null : \"true\"", "attr.data-field-type": "\"date\"", "attr.data-field-name": "metadata()?.name", "attr.data-component-id": "componentId()" } }, providers: [
|
|
9106
9547
|
{
|
|
@@ -48061,6 +48502,14 @@ class DateUtilsService {
|
|
|
48061
48502
|
const date = new Date(y, m - 1, d, h, min, s, ms);
|
|
48062
48503
|
return isNaN(date.getTime()) ? null : date;
|
|
48063
48504
|
}
|
|
48505
|
+
if (typeof value === 'string') {
|
|
48506
|
+
const trimmed = value.trim();
|
|
48507
|
+
if (/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) {
|
|
48508
|
+
const [year, month, day] = trimmed.split('-').map(Number);
|
|
48509
|
+
const date = new Date(year, month - 1, day);
|
|
48510
|
+
return isNaN(date.getTime()) ? null : date;
|
|
48511
|
+
}
|
|
48512
|
+
}
|
|
48064
48513
|
try {
|
|
48065
48514
|
const parsed = new Date(value);
|
|
48066
48515
|
return isNaN(parsed.getTime()) ? null : parsed;
|
|
@@ -48323,11 +48772,11 @@ const OVERVIEW_SLUG = 'dynamic-fields-overview';
|
|
|
48323
48772
|
const SELECTION_GUIDE_SLUG = 'dynamic-fields-field-selection-guide';
|
|
48324
48773
|
const INLINE_SELECTION_GUIDE_SLUG = 'dynamic-fields-inline-filter-selection-guide';
|
|
48325
48774
|
const DEFAULT_A11Y_NOTES = [
|
|
48326
|
-
'Use labels
|
|
48327
|
-
'
|
|
48775
|
+
'Use clear labels and do not rely on placeholders alone.',
|
|
48776
|
+
'Ensure visible focus, AA contrast, and textual error messages.',
|
|
48328
48777
|
];
|
|
48329
48778
|
const DEFAULT_THEMING_NOTES = [
|
|
48330
|
-
'
|
|
48779
|
+
'The preview must respect host tokens and avoid introducing a landing-only skin.',
|
|
48331
48780
|
];
|
|
48332
48781
|
function detailFragment(controlType) {
|
|
48333
48782
|
return controlType.toLowerCase().replace(/[^a-z0-9-]+/g, '-');
|
|
@@ -48335,6 +48784,95 @@ function detailFragment(controlType) {
|
|
|
48335
48784
|
function jsonApiPath(relativePath) {
|
|
48336
48785
|
return `projects/praxis-dynamic-fields/src/lib/components/${relativePath}`;
|
|
48337
48786
|
}
|
|
48787
|
+
function defaultIconSemantic(input) {
|
|
48788
|
+
const controlType = input.controlType.toLowerCase();
|
|
48789
|
+
let key;
|
|
48790
|
+
let tone;
|
|
48791
|
+
if (controlType.includes('button')) {
|
|
48792
|
+
key = 'action';
|
|
48793
|
+
tone = 'amber';
|
|
48794
|
+
}
|
|
48795
|
+
else if (controlType.includes('cron')) {
|
|
48796
|
+
key = 'automation';
|
|
48797
|
+
tone = 'violet';
|
|
48798
|
+
}
|
|
48799
|
+
else if (controlType.includes('upload') ||
|
|
48800
|
+
controlType.includes('avatar') ||
|
|
48801
|
+
controlType.includes('color')) {
|
|
48802
|
+
key = 'visual';
|
|
48803
|
+
tone = 'teal';
|
|
48804
|
+
}
|
|
48805
|
+
else {
|
|
48806
|
+
switch (input.family) {
|
|
48807
|
+
case 'text':
|
|
48808
|
+
key = 'text';
|
|
48809
|
+
tone = 'blue';
|
|
48810
|
+
break;
|
|
48811
|
+
case 'numbers-range':
|
|
48812
|
+
key = 'numeric';
|
|
48813
|
+
tone = 'amber';
|
|
48814
|
+
break;
|
|
48815
|
+
case 'date-time':
|
|
48816
|
+
key = 'date-time';
|
|
48817
|
+
tone = 'violet';
|
|
48818
|
+
break;
|
|
48819
|
+
case 'selection':
|
|
48820
|
+
key = 'selection';
|
|
48821
|
+
tone = 'green';
|
|
48822
|
+
break;
|
|
48823
|
+
case 'trees-lists':
|
|
48824
|
+
key = 'tree-list';
|
|
48825
|
+
tone = 'slate';
|
|
48826
|
+
break;
|
|
48827
|
+
case 'toggle-choice':
|
|
48828
|
+
key = 'toggle';
|
|
48829
|
+
tone = 'rose';
|
|
48830
|
+
break;
|
|
48831
|
+
case 'upload-color-visual':
|
|
48832
|
+
key = 'visual';
|
|
48833
|
+
tone = 'teal';
|
|
48834
|
+
break;
|
|
48835
|
+
default:
|
|
48836
|
+
key = 'text';
|
|
48837
|
+
tone = 'blue';
|
|
48838
|
+
break;
|
|
48839
|
+
}
|
|
48840
|
+
}
|
|
48841
|
+
return { key, tone };
|
|
48842
|
+
}
|
|
48843
|
+
function defaultInteractionPattern(input) {
|
|
48844
|
+
const controlType = input.controlType.toLowerCase();
|
|
48845
|
+
if (controlType.includes('textarea'))
|
|
48846
|
+
return 'multi-line';
|
|
48847
|
+
if (controlType.includes('button') || controlType.includes('cron'))
|
|
48848
|
+
return 'trigger';
|
|
48849
|
+
if (controlType.includes('toggle') || controlType.includes('checkbox') || controlType.includes('radio'))
|
|
48850
|
+
return 'toggle';
|
|
48851
|
+
if (controlType.includes('autocomplete') ||
|
|
48852
|
+
controlType.includes('searchable') ||
|
|
48853
|
+
controlType.includes('async') ||
|
|
48854
|
+
controlType.includes('entity-lookup')) {
|
|
48855
|
+
return 'lookup';
|
|
48856
|
+
}
|
|
48857
|
+
if (controlType.includes('multi') || controlType.includes('chips') || controlType.includes('transfer')) {
|
|
48858
|
+
return 'multi-choice';
|
|
48859
|
+
}
|
|
48860
|
+
if (controlType.includes('range') || controlType.includes('period') || controlType.includes('distance')) {
|
|
48861
|
+
return 'range';
|
|
48862
|
+
}
|
|
48863
|
+
if (controlType.includes('avatar') ||
|
|
48864
|
+
controlType.includes('color') ||
|
|
48865
|
+
controlType.includes('rating') ||
|
|
48866
|
+
controlType.includes('pipeline') ||
|
|
48867
|
+
controlType.includes('sentiment') ||
|
|
48868
|
+
controlType.includes('score')) {
|
|
48869
|
+
return 'visual';
|
|
48870
|
+
}
|
|
48871
|
+
if (input.family === 'selection' || input.family === 'trees-lists') {
|
|
48872
|
+
return 'single-choice';
|
|
48873
|
+
}
|
|
48874
|
+
return 'single-value';
|
|
48875
|
+
}
|
|
48338
48876
|
function createEntry(input) {
|
|
48339
48877
|
const states = input.states ?? ['default', 'filled', 'disabled', 'readonly', 'presentation', 'error'];
|
|
48340
48878
|
return {
|
|
@@ -48375,6 +48913,8 @@ function createEntry(input) {
|
|
|
48375
48913
|
`{ "name": "${input.id}", "label": "${input.friendlyName}", "controlType": "${input.controlType}" }`,
|
|
48376
48914
|
note: input.snippetNote,
|
|
48377
48915
|
},
|
|
48916
|
+
icon: input.icon ?? defaultIconSemantic({ controlType: input.controlType, family: input.family }),
|
|
48917
|
+
interactionPattern: input.interactionPattern ?? defaultInteractionPattern({ controlType: input.controlType, family: input.family }),
|
|
48378
48918
|
a11yNotes: input.a11yNotes ?? DEFAULT_A11Y_NOTES,
|
|
48379
48919
|
themingNotes: input.themingNotes ?? DEFAULT_THEMING_NOTES,
|
|
48380
48920
|
};
|
|
@@ -48395,11 +48935,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48395
48935
|
track: 'primary-form',
|
|
48396
48936
|
family: 'text',
|
|
48397
48937
|
friendlyName: 'Text input',
|
|
48398
|
-
description: '
|
|
48938
|
+
description: 'Short canonical text input for metadata-driven forms.',
|
|
48399
48939
|
tags: ['text', 'input', 'form'],
|
|
48400
48940
|
valueShape: 'string',
|
|
48401
|
-
recommendedWhen: ['
|
|
48402
|
-
avoidWhen: ['
|
|
48941
|
+
recommendedWhen: ['short free text', 'name', 'short description'],
|
|
48942
|
+
avoidWhen: ['governed option list', 'long multi-line text'],
|
|
48403
48943
|
dataSourceKind: 'local',
|
|
48404
48944
|
apiPath: jsonApiPath('text-input/pdx-text-input.json-api.md'),
|
|
48405
48945
|
metadata: { placeholder: 'Type here' },
|
|
@@ -48413,11 +48953,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48413
48953
|
track: 'primary-form',
|
|
48414
48954
|
family: 'text',
|
|
48415
48955
|
friendlyName: 'Email input',
|
|
48416
|
-
description: '
|
|
48956
|
+
description: 'Specialized text field for email addresses.',
|
|
48417
48957
|
tags: ['text', 'email', 'validation'],
|
|
48418
48958
|
valueShape: 'string',
|
|
48419
|
-
recommendedWhen: ['email
|
|
48420
|
-
avoidWhen: ['
|
|
48959
|
+
recommendedWhen: ['validated email', 'institutional contact'],
|
|
48960
|
+
avoidWhen: ['generic free text'],
|
|
48421
48961
|
dataSourceKind: 'local',
|
|
48422
48962
|
apiPath: jsonApiPath('email-input/pdx-email-input.json-api.md'),
|
|
48423
48963
|
metadata: { placeholder: 'name@company.com' },
|
|
@@ -48428,11 +48968,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48428
48968
|
track: 'primary-form',
|
|
48429
48969
|
family: 'text',
|
|
48430
48970
|
friendlyName: 'Password input',
|
|
48431
|
-
description: '
|
|
48971
|
+
description: 'Secret field with masking and appropriate interaction behavior.',
|
|
48432
48972
|
tags: ['text', 'password', 'security'],
|
|
48433
48973
|
valueShape: 'string',
|
|
48434
|
-
recommendedWhen: ['
|
|
48435
|
-
avoidWhen: ['
|
|
48974
|
+
recommendedWhen: ['secrets', 'credentials'],
|
|
48975
|
+
avoidWhen: ['value that must remain visible on screen'],
|
|
48436
48976
|
dataSourceKind: 'local',
|
|
48437
48977
|
apiPath: jsonApiPath('password-input/pdx-password-input.json-api.md'),
|
|
48438
48978
|
}),
|
|
@@ -48442,11 +48982,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48442
48982
|
track: 'primary-form',
|
|
48443
48983
|
family: 'text',
|
|
48444
48984
|
friendlyName: 'Textarea',
|
|
48445
|
-
description: '
|
|
48985
|
+
description: 'Multi-line field for notes and longer text content.',
|
|
48446
48986
|
tags: ['text', 'textarea', 'multiline'],
|
|
48447
48987
|
valueShape: 'string',
|
|
48448
|
-
recommendedWhen: ['
|
|
48449
|
-
avoidWhen: ['
|
|
48988
|
+
recommendedWhen: ['long description', 'notes', 'justification'],
|
|
48989
|
+
avoidWhen: ['short single-line text'],
|
|
48450
48990
|
dataSourceKind: 'local',
|
|
48451
48991
|
apiPath: jsonApiPath('material-textarea/pdx-material-textarea.json-api.md'),
|
|
48452
48992
|
metadata: { rows: 4, placeholder: 'Describe the situation' },
|
|
@@ -48457,11 +48997,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48457
48997
|
track: 'primary-form',
|
|
48458
48998
|
family: 'text',
|
|
48459
48999
|
friendlyName: 'Search input',
|
|
48460
|
-
description: '
|
|
49000
|
+
description: 'Text input dedicated to search.',
|
|
48461
49001
|
tags: ['text', 'search', 'query'],
|
|
48462
49002
|
valueShape: 'string',
|
|
48463
|
-
recommendedWhen: ['
|
|
48464
|
-
avoidWhen: ['
|
|
49003
|
+
recommendedWhen: ['text search', 'short query'],
|
|
49004
|
+
avoidWhen: ['common business field without search semantics'],
|
|
48465
49005
|
dataSourceKind: 'local',
|
|
48466
49006
|
apiPath: jsonApiPath('search-input/pdx-search-input.json-api.md'),
|
|
48467
49007
|
metadata: { placeholder: 'Search records' },
|
|
@@ -48472,11 +49012,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48472
49012
|
track: 'primary-form',
|
|
48473
49013
|
family: 'text',
|
|
48474
49014
|
friendlyName: 'Phone input',
|
|
48475
|
-
description: '
|
|
49015
|
+
description: 'Specialized phone field.',
|
|
48476
49016
|
tags: ['text', 'phone', 'formatted'],
|
|
48477
49017
|
valueShape: 'string',
|
|
48478
|
-
recommendedWhen: ['
|
|
48479
|
-
avoidWhen: ['
|
|
49018
|
+
recommendedWhen: ['phone', 'contact'],
|
|
49019
|
+
avoidWhen: ['domain without phone data'],
|
|
48480
49020
|
dataSourceKind: 'local',
|
|
48481
49021
|
status: 'partial-docs',
|
|
48482
49022
|
apiPath: jsonApiPath('phone-input/pdx-phone-input.json-api.md'),
|
|
@@ -48487,11 +49027,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48487
49027
|
track: 'primary-form',
|
|
48488
49028
|
family: 'text',
|
|
48489
49029
|
friendlyName: 'URL input',
|
|
48490
|
-
description: '
|
|
49030
|
+
description: 'Field for links and URLs.',
|
|
48491
49031
|
tags: ['text', 'url', 'link'],
|
|
48492
49032
|
valueShape: 'string',
|
|
48493
|
-
recommendedWhen: ['website', 'link
|
|
48494
|
-
avoidWhen: ['
|
|
49033
|
+
recommendedWhen: ['website', 'institutional link'],
|
|
49034
|
+
avoidWhen: ['generic text'],
|
|
48495
49035
|
dataSourceKind: 'local',
|
|
48496
49036
|
status: 'partial-docs',
|
|
48497
49037
|
apiPath: jsonApiPath('url-input/pdx-url-input.json-api.md'),
|
|
@@ -48502,11 +49042,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48502
49042
|
track: 'primary-form',
|
|
48503
49043
|
family: 'text',
|
|
48504
49044
|
friendlyName: 'CPF/CNPJ input',
|
|
48505
|
-
description: '
|
|
49045
|
+
description: 'Regionalized field for Brazilian documents.',
|
|
48506
49046
|
tags: ['text', 'brazil', 'document'],
|
|
48507
49047
|
valueShape: 'string',
|
|
48508
|
-
recommendedWhen: ['CPF', 'CNPJ', '
|
|
48509
|
-
avoidWhen: ['
|
|
49048
|
+
recommendedWhen: ['CPF', 'CNPJ', 'Brazilian document'],
|
|
49049
|
+
avoidWhen: ['international domain or domain without a national document'],
|
|
48510
49050
|
dataSourceKind: 'local',
|
|
48511
49051
|
status: 'partial-docs',
|
|
48512
49052
|
apiPath: jsonApiPath('material-cpf-cnpj-input/pdx-material-cpf-cnpj-input.json-api.md'),
|
|
@@ -48517,11 +49057,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48517
49057
|
track: 'primary-form',
|
|
48518
49058
|
family: 'numbers-range',
|
|
48519
49059
|
friendlyName: 'Number input',
|
|
48520
|
-
description: '
|
|
49060
|
+
description: 'Canonical numeric field for single values.',
|
|
48521
49061
|
tags: ['number', 'numeric', 'form'],
|
|
48522
49062
|
valueShape: 'number',
|
|
48523
|
-
recommendedWhen: ['
|
|
48524
|
-
avoidWhen: ['range', '
|
|
49063
|
+
recommendedWhen: ['age', 'quantity', 'single score'],
|
|
49064
|
+
avoidWhen: ['range', 'currency'],
|
|
48525
49065
|
dataSourceKind: 'local',
|
|
48526
49066
|
status: 'partial-docs',
|
|
48527
49067
|
apiPath: jsonApiPath('number-input/pdx-number-input.json-api.md'),
|
|
@@ -48532,12 +49072,13 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48532
49072
|
track: 'primary-form',
|
|
48533
49073
|
family: 'numbers-range',
|
|
48534
49074
|
friendlyName: 'Currency input',
|
|
48535
|
-
description: '
|
|
49075
|
+
description: 'Currency field for a single monetary value.',
|
|
48536
49076
|
tags: ['number', 'currency', 'money'],
|
|
48537
49077
|
valueShape: 'number',
|
|
48538
|
-
recommendedWhen: ['
|
|
48539
|
-
avoidWhen: ['
|
|
49078
|
+
recommendedWhen: ['budget', 'average ticket', 'single monetary value'],
|
|
49079
|
+
avoidWhen: ['currency range'],
|
|
48540
49080
|
dataSourceKind: 'local',
|
|
49081
|
+
interactionPattern: 'single-value',
|
|
48541
49082
|
apiPath: jsonApiPath('material-currency/pdx-material-currency.json-api.md'),
|
|
48542
49083
|
metadata: { currency: 'BRL', locale: 'pt-BR' },
|
|
48543
49084
|
stateRecipes: [
|
|
@@ -48550,11 +49091,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48550
49091
|
track: 'primary-form',
|
|
48551
49092
|
family: 'numbers-range',
|
|
48552
49093
|
friendlyName: 'Slider',
|
|
48553
|
-
description: '
|
|
49094
|
+
description: 'Continuous range control for a single value.',
|
|
48554
49095
|
tags: ['number', 'slider', 'range'],
|
|
48555
49096
|
valueShape: 'number',
|
|
48556
|
-
recommendedWhen: ['
|
|
48557
|
-
avoidWhen: ['
|
|
49097
|
+
recommendedWhen: ['rating', 'level', 'continuous scale'],
|
|
49098
|
+
avoidWhen: ['complex financial value', 'dual range'],
|
|
48558
49099
|
dataSourceKind: 'local',
|
|
48559
49100
|
apiPath: jsonApiPath('material-slider/pdx-material-slider.json-api.md'),
|
|
48560
49101
|
metadata: { min: 0, max: 10 },
|
|
@@ -48565,11 +49106,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48565
49106
|
track: 'primary-form',
|
|
48566
49107
|
family: 'numbers-range',
|
|
48567
49108
|
friendlyName: 'Range slider',
|
|
48568
|
-
description: '
|
|
49109
|
+
description: 'Field for a numeric range with one or two bounds.',
|
|
48569
49110
|
tags: ['number', 'range', 'slider'],
|
|
48570
49111
|
valueShape: 'number | { start, end }',
|
|
48571
|
-
recommendedWhen: ['
|
|
48572
|
-
avoidWhen: ['
|
|
49112
|
+
recommendedWhen: ['numeric range', 'minimum and maximum bound'],
|
|
49113
|
+
avoidWhen: ['dates or times'],
|
|
48573
49114
|
dataSourceKind: 'local',
|
|
48574
49115
|
status: 'partial-docs',
|
|
48575
49116
|
apiPath: jsonApiPath('material-range-slider/pdx-material-range-slider.json-api.md'),
|
|
@@ -48580,12 +49121,13 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48580
49121
|
track: 'primary-form',
|
|
48581
49122
|
family: 'numbers-range',
|
|
48582
49123
|
friendlyName: 'Price range',
|
|
48583
|
-
description: '
|
|
49124
|
+
description: 'Currency range with dedicated semantics.',
|
|
48584
49125
|
tags: ['number', 'currency', 'range'],
|
|
48585
49126
|
valueShape: '{ min, max }',
|
|
48586
|
-
recommendedWhen: ['
|
|
48587
|
-
avoidWhen: ['
|
|
49127
|
+
recommendedWhen: ['price range', 'salary band', 'minimum and maximum budget'],
|
|
49128
|
+
avoidWhen: ['single monetary value'],
|
|
48588
49129
|
dataSourceKind: 'local',
|
|
49130
|
+
interactionPattern: 'range',
|
|
48589
49131
|
status: 'partial-docs',
|
|
48590
49132
|
apiPath: jsonApiPath('material-price-range/pdx-material-price-range.json-api.md'),
|
|
48591
49133
|
metadata: { currency: 'BRL', locale: 'pt-BR' },
|
|
@@ -48596,12 +49138,14 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48596
49138
|
track: 'primary-form',
|
|
48597
49139
|
family: 'numbers-range',
|
|
48598
49140
|
friendlyName: 'Rating',
|
|
48599
|
-
description: '
|
|
49141
|
+
description: 'Visual rating control.',
|
|
48600
49142
|
tags: ['number', 'rating', 'visual'],
|
|
48601
49143
|
valueShape: 'number',
|
|
48602
|
-
recommendedWhen: ['
|
|
48603
|
-
avoidWhen: ['
|
|
49144
|
+
recommendedWhen: ['visual rating', 'satisfaction', 'readable score'],
|
|
49145
|
+
avoidWhen: ['when a raw number is enough'],
|
|
48604
49146
|
dataSourceKind: 'local',
|
|
49147
|
+
icon: { key: 'visual', tone: 'amber' },
|
|
49148
|
+
interactionPattern: 'visual',
|
|
48605
49149
|
apiPath: jsonApiPath('material-rating/pdx-material-rating.json-api.md'),
|
|
48606
49150
|
metadata: { max: 5 },
|
|
48607
49151
|
}),
|
|
@@ -48611,11 +49155,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48611
49155
|
track: 'primary-form',
|
|
48612
49156
|
family: 'date-time',
|
|
48613
49157
|
friendlyName: 'Date input',
|
|
48614
|
-
description: '
|
|
49158
|
+
description: 'Native date input.',
|
|
48615
49159
|
tags: ['date', 'native', 'time'],
|
|
48616
49160
|
valueShape: 'string | Date',
|
|
48617
|
-
recommendedWhen: ['
|
|
48618
|
-
avoidWhen: ['
|
|
49161
|
+
recommendedWhen: ['simple integration with a native input'],
|
|
49162
|
+
avoidWhen: ['when standardized Material UX is required'],
|
|
48619
49163
|
dataSourceKind: 'local',
|
|
48620
49164
|
status: 'partial-docs',
|
|
48621
49165
|
apiPath: jsonApiPath('date-input/pdx-date-input.json-api.md'),
|
|
@@ -48626,11 +49170,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48626
49170
|
track: 'primary-form',
|
|
48627
49171
|
family: 'date-time',
|
|
48628
49172
|
friendlyName: 'Date picker',
|
|
48629
|
-
description: '
|
|
49173
|
+
description: 'Canonical Material datepicker.',
|
|
48630
49174
|
tags: ['date', 'picker', 'material'],
|
|
48631
49175
|
valueShape: 'Date | string',
|
|
48632
|
-
recommendedWhen: ['
|
|
48633
|
-
avoidWhen: ['range
|
|
49176
|
+
recommendedWhen: ['single date', 'design system consistency'],
|
|
49177
|
+
avoidWhen: ['time range'],
|
|
48634
49178
|
dataSourceKind: 'local',
|
|
48635
49179
|
apiPath: jsonApiPath('material-datepicker/pdx-material-datepicker.json-api.md'),
|
|
48636
49180
|
}),
|
|
@@ -48640,11 +49184,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48640
49184
|
track: 'primary-form',
|
|
48641
49185
|
family: 'date-time',
|
|
48642
49186
|
friendlyName: 'Date range',
|
|
48643
|
-
description: '
|
|
49187
|
+
description: 'Date interval.',
|
|
48644
49188
|
tags: ['date', 'range', 'time'],
|
|
48645
49189
|
valueShape: '{ startDate, endDate }',
|
|
48646
|
-
recommendedWhen: ['
|
|
48647
|
-
avoidWhen: ['
|
|
49190
|
+
recommendedWhen: ['period', 'time window'],
|
|
49191
|
+
avoidWhen: ['single date'],
|
|
48648
49192
|
dataSourceKind: 'local',
|
|
48649
49193
|
apiPath: jsonApiPath('material-date-range/pdx-material-date-range.json-api.md'),
|
|
48650
49194
|
stateRecipes: [
|
|
@@ -48657,11 +49201,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48657
49201
|
track: 'primary-form',
|
|
48658
49202
|
family: 'date-time',
|
|
48659
49203
|
friendlyName: 'Datetime local',
|
|
48660
|
-
description: '
|
|
49204
|
+
description: 'Unified field for local date and time.',
|
|
48661
49205
|
tags: ['date', 'time', 'datetime'],
|
|
48662
49206
|
valueShape: 'string',
|
|
48663
|
-
recommendedWhen: ['
|
|
48664
|
-
avoidWhen: ['
|
|
49207
|
+
recommendedWhen: ['local scheduling', 'date and time in the same field'],
|
|
49208
|
+
avoidWhen: ['when date and time need separate UX'],
|
|
48665
49209
|
dataSourceKind: 'local',
|
|
48666
49210
|
status: 'partial-docs',
|
|
48667
49211
|
apiPath: jsonApiPath('datetime-local-input/pdx-datetime-local-input.json-api.md'),
|
|
@@ -48672,11 +49216,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48672
49216
|
track: 'primary-form',
|
|
48673
49217
|
family: 'date-time',
|
|
48674
49218
|
friendlyName: 'Month input',
|
|
48675
|
-
description: '
|
|
49219
|
+
description: 'Specialized month and year field.',
|
|
48676
49220
|
tags: ['date', 'month', 'competence'],
|
|
48677
49221
|
valueShape: 'string',
|
|
48678
|
-
recommendedWhen: ['
|
|
48679
|
-
avoidWhen: ['
|
|
49222
|
+
recommendedWhen: ['accounting period', 'month/year'],
|
|
49223
|
+
avoidWhen: ['full date'],
|
|
48680
49224
|
dataSourceKind: 'local',
|
|
48681
49225
|
status: 'partial-docs',
|
|
48682
49226
|
apiPath: jsonApiPath('month-input/pdx-month-input.json-api.md'),
|
|
@@ -48687,11 +49231,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48687
49231
|
track: 'primary-form',
|
|
48688
49232
|
family: 'date-time',
|
|
48689
49233
|
friendlyName: 'Time input',
|
|
48690
|
-
description: '
|
|
49234
|
+
description: 'Simple time field.',
|
|
48691
49235
|
tags: ['time', 'input', 'hour'],
|
|
48692
49236
|
valueShape: 'string',
|
|
48693
|
-
recommendedWhen: ['
|
|
48694
|
-
avoidWhen: ['range
|
|
49237
|
+
recommendedWhen: ['single time', 'time slot'],
|
|
49238
|
+
avoidWhen: ['time range'],
|
|
48695
49239
|
dataSourceKind: 'local',
|
|
48696
49240
|
apiPath: jsonApiPath('time-input/pdx-time-input.json-api.md'),
|
|
48697
49241
|
}),
|
|
@@ -48701,11 +49245,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48701
49245
|
track: 'primary-form',
|
|
48702
49246
|
family: 'date-time',
|
|
48703
49247
|
friendlyName: 'Time picker',
|
|
48704
|
-
description: '
|
|
49248
|
+
description: 'Material time picker.',
|
|
48705
49249
|
tags: ['time', 'picker', 'hour'],
|
|
48706
49250
|
valueShape: 'string',
|
|
48707
|
-
recommendedWhen: ['
|
|
48708
|
-
avoidWhen: ['
|
|
49251
|
+
recommendedWhen: ['guided time selection'],
|
|
49252
|
+
avoidWhen: ['simple text or mask is enough'],
|
|
48709
49253
|
dataSourceKind: 'local',
|
|
48710
49254
|
apiPath: jsonApiPath('material-timepicker/pdx-material-timepicker.json-api.md'),
|
|
48711
49255
|
}),
|
|
@@ -48715,11 +49259,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48715
49259
|
track: 'primary-form',
|
|
48716
49260
|
family: 'date-time',
|
|
48717
49261
|
friendlyName: 'Time range',
|
|
48718
|
-
description: '
|
|
49262
|
+
description: 'Time interval.',
|
|
48719
49263
|
tags: ['time', 'range', 'hour'],
|
|
48720
49264
|
valueShape: '{ start, end }',
|
|
48721
|
-
recommendedWhen: ['
|
|
48722
|
-
avoidWhen: ['
|
|
49265
|
+
recommendedWhen: ['service window', 'shift'],
|
|
49266
|
+
avoidWhen: ['single time'],
|
|
48723
49267
|
dataSourceKind: 'local',
|
|
48724
49268
|
status: 'partial-docs',
|
|
48725
49269
|
apiPath: jsonApiPath('pdx-material-time-range/pdx-material-time-range.json-api.md'),
|
|
@@ -48730,11 +49274,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48730
49274
|
track: 'primary-form',
|
|
48731
49275
|
family: 'date-time',
|
|
48732
49276
|
friendlyName: 'Week input',
|
|
48733
|
-
description: '
|
|
49277
|
+
description: 'ISO week field.',
|
|
48734
49278
|
tags: ['date', 'week', 'iso'],
|
|
48735
49279
|
valueShape: 'string',
|
|
48736
|
-
recommendedWhen: ['
|
|
48737
|
-
avoidWhen: ['
|
|
49280
|
+
recommendedWhen: ['reference week'],
|
|
49281
|
+
avoidWhen: ['domain centered on conventional calendar dates'],
|
|
48738
49282
|
dataSourceKind: 'local',
|
|
48739
49283
|
status: 'partial-docs',
|
|
48740
49284
|
apiPath: jsonApiPath('week-input/pdx-week-input.json-api.md'),
|
|
@@ -48745,11 +49289,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48745
49289
|
track: 'primary-form',
|
|
48746
49290
|
family: 'date-time',
|
|
48747
49291
|
friendlyName: 'Year input',
|
|
48748
|
-
description: '
|
|
49292
|
+
description: 'Field for a standalone year.',
|
|
48749
49293
|
tags: ['date', 'year', 'fiscal'],
|
|
48750
49294
|
valueShape: 'number | string',
|
|
48751
|
-
recommendedWhen: ['
|
|
48752
|
-
avoidWhen: ['
|
|
49295
|
+
recommendedWhen: ['fiscal year', 'standalone calendar year'],
|
|
49296
|
+
avoidWhen: ['month/year or full date'],
|
|
48753
49297
|
dataSourceKind: 'local',
|
|
48754
49298
|
status: 'partial-docs',
|
|
48755
49299
|
apiPath: jsonApiPath('pdx-year-input/pdx-year-input.json-api.md'),
|
|
@@ -48760,11 +49304,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48760
49304
|
track: 'primary-form',
|
|
48761
49305
|
family: 'selection',
|
|
48762
49306
|
friendlyName: 'Select',
|
|
48763
|
-
description: '
|
|
49307
|
+
description: 'Simple closed list for a single selection.',
|
|
48764
49308
|
tags: ['selection', 'select', 'options'],
|
|
48765
49309
|
valueShape: 'string | number | object',
|
|
48766
|
-
recommendedWhen: ['
|
|
48767
|
-
avoidWhen: ['
|
|
49310
|
+
recommendedWhen: ['small stable list', 'single selection'],
|
|
49311
|
+
avoidWhen: ['large or remote list'],
|
|
48768
49312
|
dataSourceKind: 'mixed',
|
|
48769
49313
|
apiPath: jsonApiPath('material-select/pdx-material-select.json-api.md'),
|
|
48770
49314
|
metadata: {
|
|
@@ -48783,14 +49327,28 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48783
49327
|
track: 'primary-form',
|
|
48784
49328
|
family: 'selection',
|
|
48785
49329
|
friendlyName: 'Searchable select',
|
|
48786
|
-
description: 'Select
|
|
49330
|
+
description: 'Select with local search for medium or large lists.',
|
|
48787
49331
|
tags: ['selection', 'select', 'search'],
|
|
48788
49332
|
valueShape: 'string | number | object',
|
|
48789
|
-
recommendedWhen: ['
|
|
48790
|
-
avoidWhen: ['
|
|
49333
|
+
recommendedWhen: ['larger list with search', 'option discovery'],
|
|
49334
|
+
avoidWhen: ['remote on-demand list'],
|
|
48791
49335
|
dataSourceKind: 'mixed',
|
|
49336
|
+
interactionPattern: 'lookup',
|
|
48792
49337
|
status: 'partial-docs',
|
|
48793
49338
|
apiPath: jsonApiPath('material-searchable-select/pdx-material-searchable-select.json-api.md'),
|
|
49339
|
+
metadata: {
|
|
49340
|
+
options: [
|
|
49341
|
+
{ label: 'Finance', value: 'FINANCE' },
|
|
49342
|
+
{ label: 'Operations', value: 'OPERATIONS' },
|
|
49343
|
+
{ label: 'People', value: 'PEOPLE' },
|
|
49344
|
+
{ label: 'Risk', value: 'RISK' },
|
|
49345
|
+
],
|
|
49346
|
+
searchable: true,
|
|
49347
|
+
placeholder: 'Search and select',
|
|
49348
|
+
},
|
|
49349
|
+
stateRecipes: [
|
|
49350
|
+
createDefaultSeedRecipe('OPERATIONS', 'Seeded default preview to reveal local search and selected-label rendering.'),
|
|
49351
|
+
],
|
|
48794
49352
|
}),
|
|
48795
49353
|
createEntry({
|
|
48796
49354
|
id: 'async-select',
|
|
@@ -48798,12 +49356,13 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48798
49356
|
track: 'primary-form',
|
|
48799
49357
|
family: 'selection',
|
|
48800
49358
|
friendlyName: 'Async select',
|
|
48801
|
-
description: '
|
|
49359
|
+
description: 'Remote select for on-demand options.',
|
|
48802
49360
|
tags: ['selection', 'remote', 'async'],
|
|
48803
49361
|
valueShape: 'string | number | object',
|
|
48804
|
-
recommendedWhen: ['lookup
|
|
48805
|
-
avoidWhen: ['
|
|
49362
|
+
recommendedWhen: ['remote lookup', 'paginated list', 'large catalog'],
|
|
49363
|
+
avoidWhen: ['small local options'],
|
|
48806
49364
|
dataSourceKind: 'remote',
|
|
49365
|
+
interactionPattern: 'lookup',
|
|
48807
49366
|
status: 'partial-docs',
|
|
48808
49367
|
apiPath: jsonApiPath('material-async-select/pdx-material-async-select.json-api.md'),
|
|
48809
49368
|
metadata: { resourcePath: 'cities', optionLabelKey: 'name', optionValueKey: 'id' },
|
|
@@ -48814,13 +49373,25 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48814
49373
|
track: 'primary-form',
|
|
48815
49374
|
family: 'selection',
|
|
48816
49375
|
friendlyName: 'Autocomplete',
|
|
48817
|
-
description: '
|
|
49376
|
+
description: 'Incremental search with suggestions.',
|
|
48818
49377
|
tags: ['selection', 'autocomplete', 'search'],
|
|
48819
49378
|
valueShape: 'string | number | object',
|
|
48820
|
-
recommendedWhen: ['
|
|
48821
|
-
avoidWhen: ['
|
|
49379
|
+
recommendedWhen: ['incremental suggestions', 'textual discovery'],
|
|
49380
|
+
avoidWhen: ['small closed list'],
|
|
48822
49381
|
dataSourceKind: 'mixed',
|
|
49382
|
+
interactionPattern: 'lookup',
|
|
48823
49383
|
apiPath: jsonApiPath('material-autocomplete/pdx-material-autocomplete.json-api.md'),
|
|
49384
|
+
metadata: {
|
|
49385
|
+
options: [
|
|
49386
|
+
{ label: 'Analyst', value: 'ANALYST' },
|
|
49387
|
+
{ label: 'Architect', value: 'ARCHITECT' },
|
|
49388
|
+
{ label: 'Manager', value: 'MANAGER' },
|
|
49389
|
+
],
|
|
49390
|
+
placeholder: 'Start typing a role',
|
|
49391
|
+
},
|
|
49392
|
+
stateRecipes: [
|
|
49393
|
+
createDefaultSeedRecipe('ARCHITECT', 'Seeded default preview to show suggestion-driven discovery instead of an empty shell.'),
|
|
49394
|
+
],
|
|
48824
49395
|
}),
|
|
48825
49396
|
createEntry({
|
|
48826
49397
|
id: 'multi-select',
|
|
@@ -48828,11 +49399,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48828
49399
|
track: 'primary-form',
|
|
48829
49400
|
family: 'selection',
|
|
48830
49401
|
friendlyName: 'Multi select',
|
|
48831
|
-
description: '
|
|
49402
|
+
description: 'Multi-select options.',
|
|
48832
49403
|
tags: ['selection', 'multiple', 'options'],
|
|
48833
49404
|
valueShape: 'unknown[]',
|
|
48834
|
-
recommendedWhen: ['
|
|
48835
|
-
avoidWhen: ['
|
|
49405
|
+
recommendedWhen: ['multiple discrete choices'],
|
|
49406
|
+
avoidWhen: ['single selection'],
|
|
48836
49407
|
dataSourceKind: 'mixed',
|
|
48837
49408
|
status: 'partial-docs',
|
|
48838
49409
|
apiPath: jsonApiPath('material-multi-select/pdx-material-multi-select.json-api.md'),
|
|
@@ -48843,12 +49414,14 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48843
49414
|
track: 'primary-form',
|
|
48844
49415
|
family: 'trees-lists',
|
|
48845
49416
|
friendlyName: 'Multi select tree',
|
|
48846
|
-
description: '
|
|
49417
|
+
description: 'Hierarchical tree with multi-selection.',
|
|
48847
49418
|
tags: ['tree', 'selection', 'hierarchy'],
|
|
48848
49419
|
valueShape: 'unknown[]',
|
|
48849
|
-
recommendedWhen: ['
|
|
48850
|
-
avoidWhen: ['
|
|
49420
|
+
recommendedWhen: ['hierarchical taxonomy with multiple selections'],
|
|
49421
|
+
avoidWhen: ['small flat list'],
|
|
48851
49422
|
dataSourceKind: 'mixed',
|
|
49423
|
+
icon: { key: 'tree-list', tone: 'slate' },
|
|
49424
|
+
interactionPattern: 'multi-choice',
|
|
48852
49425
|
status: 'partial-docs',
|
|
48853
49426
|
apiPath: jsonApiPath('material-multi-select-tree/pdx-material-multi-select-tree.json-api.md'),
|
|
48854
49427
|
}),
|
|
@@ -48858,12 +49431,14 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48858
49431
|
track: 'primary-form',
|
|
48859
49432
|
family: 'trees-lists',
|
|
48860
49433
|
friendlyName: 'Tree select',
|
|
48861
|
-
description: '
|
|
49434
|
+
description: 'Hierarchical tree with single selection.',
|
|
48862
49435
|
tags: ['tree', 'selection', 'hierarchy'],
|
|
48863
49436
|
valueShape: 'string | number | object',
|
|
48864
|
-
recommendedWhen: ['
|
|
48865
|
-
avoidWhen: ['
|
|
49437
|
+
recommendedWhen: ['hierarchical structure with a single selection'],
|
|
49438
|
+
avoidWhen: ['multiple selections'],
|
|
48866
49439
|
dataSourceKind: 'mixed',
|
|
49440
|
+
icon: { key: 'tree-list', tone: 'slate' },
|
|
49441
|
+
interactionPattern: 'single-choice',
|
|
48867
49442
|
status: 'partial-docs',
|
|
48868
49443
|
apiPath: jsonApiPath('material-tree-select/pdx-material-tree-select.json-api.md'),
|
|
48869
49444
|
}),
|
|
@@ -48873,11 +49448,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48873
49448
|
track: 'primary-form',
|
|
48874
49449
|
family: 'trees-lists',
|
|
48875
49450
|
friendlyName: 'Selection list',
|
|
48876
|
-
description: '
|
|
49451
|
+
description: 'Explicit list of selectable options.',
|
|
48877
49452
|
tags: ['list', 'selection', 'explicit'],
|
|
48878
49453
|
valueShape: 'unknown[]',
|
|
48879
|
-
recommendedWhen: ['
|
|
48880
|
-
avoidWhen: ['dropdown
|
|
49454
|
+
recommendedWhen: ['visible list of options', 'strong list affordance'],
|
|
49455
|
+
avoidWhen: ['a compact dropdown is a better fit'],
|
|
48881
49456
|
dataSourceKind: 'mixed',
|
|
48882
49457
|
status: 'partial-docs',
|
|
48883
49458
|
apiPath: jsonApiPath('material-selection-list/pdx-material-selection-list.json-api.md'),
|
|
@@ -48888,12 +49463,14 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48888
49463
|
track: 'primary-form',
|
|
48889
49464
|
family: 'trees-lists',
|
|
48890
49465
|
friendlyName: 'Transfer list',
|
|
48891
|
-
description: '
|
|
49466
|
+
description: 'Moves items between available and selected lists.',
|
|
48892
49467
|
tags: ['list', 'transfer', 'selection'],
|
|
48893
49468
|
valueShape: 'unknown[]',
|
|
48894
|
-
recommendedWhen: ['
|
|
48895
|
-
avoidWhen: ['
|
|
49469
|
+
recommendedWhen: ['allocation between available and selected items'],
|
|
49470
|
+
avoidWhen: ['simple or small selection'],
|
|
48896
49471
|
dataSourceKind: 'mixed',
|
|
49472
|
+
icon: { key: 'tree-list', tone: 'slate' },
|
|
49473
|
+
interactionPattern: 'multi-choice',
|
|
48897
49474
|
status: 'partial-docs',
|
|
48898
49475
|
apiPath: jsonApiPath('material-transfer-list/pdx-material-transfer-list.json-api.md'),
|
|
48899
49476
|
}),
|
|
@@ -48903,11 +49480,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48903
49480
|
track: 'primary-form',
|
|
48904
49481
|
family: 'trees-lists',
|
|
48905
49482
|
friendlyName: 'Chip input',
|
|
48906
|
-
description: '
|
|
49483
|
+
description: 'Text item input in chip format.',
|
|
48907
49484
|
tags: ['chips', 'list', 'text'],
|
|
48908
49485
|
valueShape: 'string[]',
|
|
48909
|
-
recommendedWhen: ['
|
|
48910
|
-
avoidWhen: ['
|
|
49486
|
+
recommendedWhen: ['email addresses', 'editable labels', 'text list'],
|
|
49487
|
+
avoidWhen: ['single value'],
|
|
48911
49488
|
dataSourceKind: 'local',
|
|
48912
49489
|
status: 'partial-docs',
|
|
48913
49490
|
apiPath: jsonApiPath('material-chips/pdx-material-chips.json-api.md'),
|
|
@@ -48918,11 +49495,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48918
49495
|
track: 'primary-form',
|
|
48919
49496
|
family: 'trees-lists',
|
|
48920
49497
|
friendlyName: 'Chip list',
|
|
48921
|
-
description: '
|
|
49498
|
+
description: 'Text list in chips.',
|
|
48922
49499
|
tags: ['chips', 'list', 'display'],
|
|
48923
49500
|
valueShape: 'string[]',
|
|
48924
|
-
recommendedWhen: ['
|
|
48925
|
-
avoidWhen: ['
|
|
49501
|
+
recommendedWhen: ['short list in chips', 'light editing'],
|
|
49502
|
+
avoidWhen: ['single value'],
|
|
48926
49503
|
dataSourceKind: 'local',
|
|
48927
49504
|
status: 'partial-docs',
|
|
48928
49505
|
apiPath: jsonApiPath('material-chips/pdx-material-chips.json-api.md'),
|
|
@@ -48933,13 +49510,23 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48933
49510
|
track: 'primary-form',
|
|
48934
49511
|
family: 'toggle-choice',
|
|
48935
49512
|
friendlyName: 'Checkbox group',
|
|
48936
|
-
description: '
|
|
49513
|
+
description: 'Discrete boolean or multiple choices.',
|
|
48937
49514
|
tags: ['choice', 'checkbox', 'boolean'],
|
|
48938
49515
|
valueShape: 'boolean | unknown[]',
|
|
48939
|
-
recommendedWhen: ['
|
|
48940
|
-
avoidWhen: ['
|
|
49516
|
+
recommendedWhen: ['multiple discrete choices', 'boolean with the appropriate selectionMode'],
|
|
49517
|
+
avoidWhen: ['single selection'],
|
|
48941
49518
|
dataSourceKind: 'mixed',
|
|
48942
49519
|
apiPath: jsonApiPath('material-checkbox-group/pdx-material-checkbox-group.json-api.md'),
|
|
49520
|
+
metadata: {
|
|
49521
|
+
selectionMode: 'boolean',
|
|
49522
|
+
description: 'Enable publishing notifications for this record.',
|
|
49523
|
+
links: [{ label: 'Privacy terms', href: '/privacy' }],
|
|
49524
|
+
},
|
|
49525
|
+
snippet: `{ "name": "privacyConsent", "controlType": "checkbox", "selectionMode": "boolean", "description": "Enable publishing notifications for this record." }`,
|
|
49526
|
+
snippetNote: 'Checkbox is only didactic when selectionMode is explicit. Use `boolean` for a single consent/flag or `multiple` for option groups.',
|
|
49527
|
+
stateRecipes: [
|
|
49528
|
+
createDefaultSeedRecipe(true, 'Seeded default preview to make the boolean contract visible immediately.'),
|
|
49529
|
+
],
|
|
48943
49530
|
}),
|
|
48944
49531
|
createEntry({
|
|
48945
49532
|
id: 'radio-group',
|
|
@@ -48947,13 +49534,25 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48947
49534
|
track: 'primary-form',
|
|
48948
49535
|
family: 'toggle-choice',
|
|
48949
49536
|
friendlyName: 'Radio group',
|
|
48950
|
-
description: '
|
|
49537
|
+
description: 'Explicit single choice.',
|
|
48951
49538
|
tags: ['choice', 'radio', 'single'],
|
|
48952
49539
|
valueShape: 'string | number | boolean',
|
|
48953
|
-
recommendedWhen: ['
|
|
48954
|
-
avoidWhen: ['
|
|
49540
|
+
recommendedWhen: ['single choice with few options and high readability'],
|
|
49541
|
+
avoidWhen: ['many options'],
|
|
48955
49542
|
dataSourceKind: 'mixed',
|
|
48956
49543
|
apiPath: jsonApiPath('material-radio-group/pdx-material-radio-group.json-api.md'),
|
|
49544
|
+
metadata: {
|
|
49545
|
+
selectionMode: 'single',
|
|
49546
|
+
options: [
|
|
49547
|
+
{ label: 'Low', value: 'LOW' },
|
|
49548
|
+
{ label: 'Medium', value: 'MEDIUM' },
|
|
49549
|
+
{ label: 'High', value: 'HIGH' },
|
|
49550
|
+
],
|
|
49551
|
+
},
|
|
49552
|
+
snippet: `{ "name": "priority", "controlType": "radio", "selectionMode": "single", "options": [{ "label": "Low", "value": "LOW" }, { "label": "Medium", "value": "MEDIUM" }, { "label": "High", "value": "HIGH" }] }`,
|
|
49553
|
+
stateRecipes: [
|
|
49554
|
+
createDefaultSeedRecipe('MEDIUM', 'Seeded default preview to expose the explicit single-choice contract.'),
|
|
49555
|
+
],
|
|
48957
49556
|
}),
|
|
48958
49557
|
createEntry({
|
|
48959
49558
|
id: 'toggle',
|
|
@@ -48961,11 +49560,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48961
49560
|
track: 'primary-form',
|
|
48962
49561
|
family: 'toggle-choice',
|
|
48963
49562
|
friendlyName: 'Toggle',
|
|
48964
|
-
description: '
|
|
49563
|
+
description: 'Binary on/off boolean.',
|
|
48965
49564
|
tags: ['choice', 'toggle', 'boolean'],
|
|
48966
49565
|
valueShape: 'boolean',
|
|
48967
|
-
recommendedWhen: ['
|
|
48968
|
-
avoidWhen: ['
|
|
49566
|
+
recommendedWhen: ['simple boolean'],
|
|
49567
|
+
avoidWhen: ['more than two states'],
|
|
48969
49568
|
dataSourceKind: 'local',
|
|
48970
49569
|
apiPath: jsonApiPath('material-slide-toggle/pdx-material-slide-toggle.json-api.md'),
|
|
48971
49570
|
stateRecipes: [
|
|
@@ -48978,11 +49577,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48978
49577
|
track: 'primary-form',
|
|
48979
49578
|
family: 'toggle-choice',
|
|
48980
49579
|
friendlyName: 'Button toggle',
|
|
48981
|
-
description: '
|
|
49580
|
+
description: 'Segmented group for a small number of options.',
|
|
48982
49581
|
tags: ['choice', 'toggle', 'segmented'],
|
|
48983
49582
|
valueShape: 'string | number',
|
|
48984
|
-
recommendedWhen: ['
|
|
48985
|
-
avoidWhen: ['
|
|
49583
|
+
recommendedWhen: ['few short options', 'visible segmentation'],
|
|
49584
|
+
avoidWhen: ['long list'],
|
|
48986
49585
|
dataSourceKind: 'local',
|
|
48987
49586
|
status: 'partial-docs',
|
|
48988
49587
|
apiPath: jsonApiPath('material-button-toggle/pdx-material-button-toggle.json-api.md'),
|
|
@@ -48993,13 +49592,21 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
48993
49592
|
track: 'primary-form',
|
|
48994
49593
|
family: 'upload-color-visual',
|
|
48995
49594
|
friendlyName: 'File upload',
|
|
48996
|
-
description: '
|
|
49595
|
+
description: 'Field for attachments and documents.',
|
|
48997
49596
|
tags: ['upload', 'files', 'attachments'],
|
|
48998
49597
|
valueShape: 'File | File[] | metadata',
|
|
48999
|
-
recommendedWhen: ['
|
|
49000
|
-
avoidWhen: ['
|
|
49598
|
+
recommendedWhen: ['documents', 'attachments', 'supporting documents'],
|
|
49599
|
+
avoidWhen: ['flow without files'],
|
|
49001
49600
|
dataSourceKind: 'specialized',
|
|
49601
|
+
icon: { key: 'visual', tone: 'teal' },
|
|
49602
|
+
interactionPattern: 'trigger',
|
|
49002
49603
|
apiPath: jsonApiPath('material-file-upload/pdx-material-file-upload.json-api.md'),
|
|
49604
|
+
metadata: {
|
|
49605
|
+
accept: '.pdf,.png,.jpg',
|
|
49606
|
+
hint: 'Current runtime is a lightweight placeholder based on native file input.',
|
|
49607
|
+
},
|
|
49608
|
+
snippet: `{ "name": "attachment", "controlType": "upload", "accept": ".pdf,.png,.jpg", "hint": "Current runtime is a lightweight placeholder based on native file input." }`,
|
|
49609
|
+
snippetNote: 'This preview intentionally demonstrates the current placeholder runtime, not a full asset-management experience.',
|
|
49003
49610
|
}),
|
|
49004
49611
|
createEntry({
|
|
49005
49612
|
id: 'color-input',
|
|
@@ -49007,11 +49614,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49007
49614
|
track: 'primary-form',
|
|
49008
49615
|
family: 'upload-color-visual',
|
|
49009
49616
|
friendlyName: 'Color input',
|
|
49010
|
-
description: '
|
|
49617
|
+
description: 'Simple color input.',
|
|
49011
49618
|
tags: ['color', 'input', 'visual'],
|
|
49012
49619
|
valueShape: 'string',
|
|
49013
|
-
recommendedWhen: ['
|
|
49014
|
-
avoidWhen: ['
|
|
49620
|
+
recommendedWhen: ['color by simple value'],
|
|
49621
|
+
avoidWhen: ['rich palette or presets'],
|
|
49015
49622
|
dataSourceKind: 'local',
|
|
49016
49623
|
apiPath: jsonApiPath('color-input/pdx-color-input.json-api.md'),
|
|
49017
49624
|
}),
|
|
@@ -49021,11 +49628,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49021
49628
|
track: 'primary-form',
|
|
49022
49629
|
family: 'upload-color-visual',
|
|
49023
49630
|
friendlyName: 'Color picker',
|
|
49024
|
-
description: '
|
|
49631
|
+
description: 'Advanced color picker with palette.',
|
|
49025
49632
|
tags: ['color', 'picker', 'visual'],
|
|
49026
49633
|
valueShape: 'string',
|
|
49027
|
-
recommendedWhen: ['
|
|
49028
|
-
avoidWhen: ['
|
|
49634
|
+
recommendedWhen: ['rich palette', 'visual preset', 'theme'],
|
|
49635
|
+
avoidWhen: ['a simple textual value is enough'],
|
|
49029
49636
|
dataSourceKind: 'local',
|
|
49030
49637
|
apiPath: jsonApiPath('color-picker/pdx-color-picker.json-api.md'),
|
|
49031
49638
|
}),
|
|
@@ -49035,13 +49642,26 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49035
49642
|
track: 'primary-form',
|
|
49036
49643
|
family: 'upload-color-visual',
|
|
49037
49644
|
friendlyName: 'Avatar',
|
|
49038
|
-
description: '
|
|
49645
|
+
description: 'Visual representation of an entity or user.',
|
|
49039
49646
|
tags: ['visual', 'avatar', 'display'],
|
|
49040
49647
|
valueShape: 'string | object',
|
|
49041
|
-
recommendedWhen: ['
|
|
49042
|
-
avoidWhen: ['
|
|
49648
|
+
recommendedWhen: ['visual representation of a user or entity'],
|
|
49649
|
+
avoidWhen: ['text data capture'],
|
|
49043
49650
|
dataSourceKind: 'specialized',
|
|
49651
|
+
icon: { key: 'visual', tone: 'teal' },
|
|
49652
|
+
interactionPattern: 'visual',
|
|
49044
49653
|
apiPath: jsonApiPath('material-avatar/pdx-material-avatar.json-api.md'),
|
|
49654
|
+
metadata: {
|
|
49655
|
+
imageSrc: 'https://cdn.corp.example/avatar/u123.png',
|
|
49656
|
+
extra: {
|
|
49657
|
+
initials: 'AS',
|
|
49658
|
+
name: 'Ana Souza',
|
|
49659
|
+
ariaLabel: 'Avatar do responsavel',
|
|
49660
|
+
},
|
|
49661
|
+
},
|
|
49662
|
+
stateRecipes: [
|
|
49663
|
+
createDefaultSeedRecipe({ imageSrc: 'https://cdn.corp.example/avatar/u123.png', name: 'Ana Souza', initials: 'AS' }, 'Seeded default preview to show the visual contract instead of an empty shell.'),
|
|
49664
|
+
],
|
|
49045
49665
|
}),
|
|
49046
49666
|
createEntry({
|
|
49047
49667
|
id: 'button',
|
|
@@ -49049,14 +49669,23 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49049
49669
|
track: 'primary-form',
|
|
49050
49670
|
family: 'upload-color-visual',
|
|
49051
49671
|
friendlyName: 'Button',
|
|
49052
|
-
description: '
|
|
49672
|
+
description: 'Auxiliary action embedded in the form layout.',
|
|
49053
49673
|
tags: ['action', 'button', 'visual'],
|
|
49054
49674
|
valueShape: 'n/a',
|
|
49055
|
-
recommendedWhen: ['
|
|
49056
|
-
avoidWhen: ['submit
|
|
49675
|
+
recommendedWhen: ['auxiliary action in the layout'],
|
|
49676
|
+
avoidWhen: ['default form submit or cancel action'],
|
|
49057
49677
|
dataSourceKind: 'specialized',
|
|
49678
|
+
icon: { key: 'action', tone: 'amber' },
|
|
49679
|
+
interactionPattern: 'trigger',
|
|
49058
49680
|
apiPath: jsonApiPath('material-button/pdx-material-button.json-api.md'),
|
|
49059
49681
|
states: ['default', 'disabled', 'readonly'],
|
|
49682
|
+
metadata: {
|
|
49683
|
+
label: 'Validate data',
|
|
49684
|
+
action: 'validateForm',
|
|
49685
|
+
variant: 'stroked',
|
|
49686
|
+
},
|
|
49687
|
+
snippet: `{ "name": "validateBtn", "controlType": "button", "label": "Validate data", "action": "validateForm", "variant": "stroked" }`,
|
|
49688
|
+
snippetNote: 'Button previews are only meaningful when the action contract is explicit. Treat this as an embedded auxiliary action, not the form submit surface.',
|
|
49060
49689
|
}),
|
|
49061
49690
|
createEntry({
|
|
49062
49691
|
id: 'cron-builder',
|
|
@@ -49064,13 +49693,22 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49064
49693
|
track: 'primary-form',
|
|
49065
49694
|
family: 'upload-color-visual',
|
|
49066
49695
|
friendlyName: 'Cron builder',
|
|
49067
|
-
description: '
|
|
49696
|
+
description: 'Specialized control for CRON expressions.',
|
|
49068
49697
|
tags: ['cron', 'schedule', 'specialized'],
|
|
49069
49698
|
valueShape: 'string',
|
|
49070
|
-
recommendedWhen: ['
|
|
49071
|
-
avoidWhen: ['
|
|
49699
|
+
recommendedWhen: ['cron schedule', 'recurring frequency'],
|
|
49700
|
+
avoidWhen: ['dates or simple ranges'],
|
|
49072
49701
|
dataSourceKind: 'specialized',
|
|
49702
|
+
icon: { key: 'automation', tone: 'violet' },
|
|
49703
|
+
interactionPattern: 'trigger',
|
|
49073
49704
|
status: 'partial-docs',
|
|
49705
|
+
metadata: {
|
|
49706
|
+
placeholder: '0 9 * * 1-5',
|
|
49707
|
+
hint: 'Use when the business contract is truly cron-based, not just date or time range based.',
|
|
49708
|
+
},
|
|
49709
|
+
stateRecipes: [
|
|
49710
|
+
createDefaultSeedRecipe('0 9 * * 1-5', 'Seeded default preview to expose the recurring-expression contract immediately.'),
|
|
49711
|
+
],
|
|
49074
49712
|
snippetNote: 'A documentacao detalhada continua vivendo na lib especializada @praxisui/cron-builder.',
|
|
49075
49713
|
}),
|
|
49076
49714
|
createEntry({
|
|
@@ -49079,11 +49717,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49079
49717
|
track: 'inline-filter',
|
|
49080
49718
|
family: 'text',
|
|
49081
49719
|
friendlyName: 'Inline input',
|
|
49082
|
-
description: '
|
|
49720
|
+
description: 'Compact text filter for the toolbar.',
|
|
49083
49721
|
tags: ['inline', 'filter', 'text'],
|
|
49084
49722
|
valueShape: 'string',
|
|
49085
|
-
recommendedWhen: ['
|
|
49086
|
-
avoidWhen: ['
|
|
49723
|
+
recommendedWhen: ['short search in the toolbar', 'identifier', 'name'],
|
|
49724
|
+
avoidWhen: ['long text', 'complex validation'],
|
|
49087
49725
|
dataSourceKind: 'local',
|
|
49088
49726
|
apiPath: jsonApiPath('inline-input/pdx-inline-input.json-api.md'),
|
|
49089
49727
|
stateRecipes: [
|
|
@@ -49096,11 +49734,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49096
49734
|
track: 'inline-filter',
|
|
49097
49735
|
family: 'selection',
|
|
49098
49736
|
friendlyName: 'Inline select',
|
|
49099
|
-
description: '
|
|
49737
|
+
description: 'Compact pill selection for filters.',
|
|
49100
49738
|
tags: ['inline', 'filter', 'selection'],
|
|
49101
49739
|
valueShape: 'simple value',
|
|
49102
|
-
recommendedWhen: ['
|
|
49103
|
-
avoidWhen: ['
|
|
49740
|
+
recommendedWhen: ['small or medium list in the toolbar'],
|
|
49741
|
+
avoidWhen: ['large remote lookup'],
|
|
49104
49742
|
dataSourceKind: 'mixed',
|
|
49105
49743
|
apiPath: jsonApiPath('inline-select/pdx-inline-select.json-api.md'),
|
|
49106
49744
|
stateRecipes: [
|
|
@@ -49113,11 +49751,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49113
49751
|
track: 'inline-filter',
|
|
49114
49752
|
family: 'selection',
|
|
49115
49753
|
friendlyName: 'Inline searchable select',
|
|
49116
|
-
description: '
|
|
49754
|
+
description: 'Compact selection with search.',
|
|
49117
49755
|
tags: ['inline', 'filter', 'selection', 'search'],
|
|
49118
49756
|
valueShape: 'simple value | option object',
|
|
49119
|
-
recommendedWhen: ['
|
|
49120
|
-
avoidWhen: ['select
|
|
49757
|
+
recommendedWhen: ['medium or large list with search in the toolbar'],
|
|
49758
|
+
avoidWhen: ['a simple select is enough'],
|
|
49121
49759
|
dataSourceKind: 'mixed',
|
|
49122
49760
|
apiPath: jsonApiPath('inline-searchable-select/pdx-inline-searchable-select.json-api.md'),
|
|
49123
49761
|
}),
|
|
@@ -49127,11 +49765,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49127
49765
|
track: 'inline-filter',
|
|
49128
49766
|
family: 'selection',
|
|
49129
49767
|
friendlyName: 'Inline async select',
|
|
49130
|
-
description: '
|
|
49768
|
+
description: 'Compact remote selection for the toolbar.',
|
|
49131
49769
|
tags: ['inline', 'filter', 'selection', 'remote'],
|
|
49132
49770
|
valueShape: 'simple value | option object',
|
|
49133
|
-
recommendedWhen: ['lookup
|
|
49134
|
-
avoidWhen: ['
|
|
49771
|
+
recommendedWhen: ['remote lookup in the toolbar', 'on-demand list'],
|
|
49772
|
+
avoidWhen: ['small local list'],
|
|
49135
49773
|
dataSourceKind: 'remote',
|
|
49136
49774
|
apiPath: jsonApiPath('inline-async-select/pdx-inline-async-select.json-api.md'),
|
|
49137
49775
|
}),
|
|
@@ -49141,11 +49779,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49141
49779
|
track: 'inline-filter',
|
|
49142
49780
|
family: 'selection',
|
|
49143
49781
|
friendlyName: 'Inline entity lookup',
|
|
49144
|
-
description: '
|
|
49782
|
+
description: 'Compact entity lookup with enterprise semantics.',
|
|
49145
49783
|
tags: ['inline', 'filter', 'lookup', 'remote'],
|
|
49146
49784
|
valueShape: 'object | id',
|
|
49147
|
-
recommendedWhen: ['id
|
|
49148
|
-
avoidWhen: ['
|
|
49785
|
+
recommendedWhen: ['id and description', 'entity identity'],
|
|
49786
|
+
avoidWhen: ['simple local select'],
|
|
49149
49787
|
dataSourceKind: 'remote',
|
|
49150
49788
|
apiPath: jsonApiPath('inline-entity-lookup/pdx-inline-entity-lookup.json-api.md'),
|
|
49151
49789
|
}),
|
|
@@ -49155,11 +49793,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49155
49793
|
track: 'inline-filter',
|
|
49156
49794
|
family: 'selection',
|
|
49157
49795
|
friendlyName: 'Inline autocomplete',
|
|
49158
|
-
description: '
|
|
49796
|
+
description: 'Compact autocomplete for filters.',
|
|
49159
49797
|
tags: ['inline', 'filter', 'autocomplete'],
|
|
49160
49798
|
valueShape: 'simple value | option object',
|
|
49161
|
-
recommendedWhen: ['
|
|
49162
|
-
avoidWhen: ['select
|
|
49799
|
+
recommendedWhen: ['incremental suggestion in the toolbar'],
|
|
49800
|
+
avoidWhen: ['a simple select is enough'],
|
|
49163
49801
|
dataSourceKind: 'mixed',
|
|
49164
49802
|
apiPath: jsonApiPath('inline-autocomplete/pdx-inline-autocomplete.json-api.md'),
|
|
49165
49803
|
}),
|
|
@@ -49169,11 +49807,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49169
49807
|
track: 'inline-filter',
|
|
49170
49808
|
family: 'selection',
|
|
49171
49809
|
friendlyName: 'Inline multi select',
|
|
49172
|
-
description: '
|
|
49810
|
+
description: 'Compact multi-selection with pill summary.',
|
|
49173
49811
|
tags: ['inline', 'filter', 'multiple'],
|
|
49174
49812
|
valueShape: 'unknown[]',
|
|
49175
|
-
recommendedWhen: ['
|
|
49176
|
-
avoidWhen: ['
|
|
49813
|
+
recommendedWhen: ['few simultaneous selections with a short summary'],
|
|
49814
|
+
avoidWhen: ['need to read every selected item in full'],
|
|
49177
49815
|
dataSourceKind: 'mixed',
|
|
49178
49816
|
apiPath: jsonApiPath('inline-multi-select/pdx-inline-multi-select.json-api.md'),
|
|
49179
49817
|
}),
|
|
@@ -49183,10 +49821,10 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49183
49821
|
track: 'inline-filter',
|
|
49184
49822
|
family: 'numbers-range',
|
|
49185
49823
|
friendlyName: 'Inline number',
|
|
49186
|
-
description: '
|
|
49824
|
+
description: 'Compact numeric filter.',
|
|
49187
49825
|
tags: ['inline', 'filter', 'number'],
|
|
49188
49826
|
valueShape: 'number',
|
|
49189
|
-
recommendedWhen: ['
|
|
49827
|
+
recommendedWhen: ['single numeric value in the toolbar'],
|
|
49190
49828
|
avoidWhen: ['range'],
|
|
49191
49829
|
dataSourceKind: 'local',
|
|
49192
49830
|
apiPath: jsonApiPath('inline-number/pdx-inline-number.json-api.md'),
|
|
@@ -49197,11 +49835,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49197
49835
|
track: 'inline-filter',
|
|
49198
49836
|
family: 'numbers-range',
|
|
49199
49837
|
friendlyName: 'Inline currency',
|
|
49200
|
-
description: '
|
|
49838
|
+
description: 'Compact currency filter.',
|
|
49201
49839
|
tags: ['inline', 'filter', 'currency'],
|
|
49202
49840
|
valueShape: 'number',
|
|
49203
|
-
recommendedWhen: ['
|
|
49204
|
-
avoidWhen: ['
|
|
49841
|
+
recommendedWhen: ['single monetary value in the toolbar'],
|
|
49842
|
+
avoidWhen: ['currency range'],
|
|
49205
49843
|
dataSourceKind: 'local',
|
|
49206
49844
|
apiPath: jsonApiPath('inline-currency/pdx-inline-currency.json-api.md'),
|
|
49207
49845
|
}),
|
|
@@ -49211,11 +49849,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49211
49849
|
track: 'inline-filter',
|
|
49212
49850
|
family: 'numbers-range',
|
|
49213
49851
|
friendlyName: 'Inline currency range',
|
|
49214
|
-
description: '
|
|
49852
|
+
description: 'Compact currency range for the toolbar.',
|
|
49215
49853
|
tags: ['inline', 'filter', 'currency', 'range'],
|
|
49216
49854
|
valueShape: '{ minPrice?, maxPrice?, currency? }',
|
|
49217
|
-
recommendedWhen: ['
|
|
49218
|
-
avoidWhen: ['
|
|
49855
|
+
recommendedWhen: ['currency range in the toolbar'],
|
|
49856
|
+
avoidWhen: ['single value'],
|
|
49219
49857
|
dataSourceKind: 'specialized',
|
|
49220
49858
|
apiPath: jsonApiPath('inline-currency-range/pdx-inline-currency-range.json-api.md'),
|
|
49221
49859
|
}),
|
|
@@ -49225,11 +49863,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49225
49863
|
track: 'inline-filter',
|
|
49226
49864
|
family: 'numbers-range',
|
|
49227
49865
|
friendlyName: 'Inline range',
|
|
49228
|
-
description: '
|
|
49866
|
+
description: 'Compact numeric range for the toolbar.',
|
|
49229
49867
|
tags: ['inline', 'filter', 'range', 'slider'],
|
|
49230
49868
|
valueShape: 'number | { start?, end? }',
|
|
49231
|
-
recommendedWhen: ['
|
|
49232
|
-
avoidWhen: ['
|
|
49869
|
+
recommendedWhen: ['compact numeric range'],
|
|
49870
|
+
avoidWhen: ['dates or times'],
|
|
49233
49871
|
dataSourceKind: 'specialized',
|
|
49234
49872
|
apiPath: jsonApiPath('inline-currency-range/pdx-inline-currency-range.json-api.md'),
|
|
49235
49873
|
detailFragment: 'inline-range',
|
|
@@ -49240,11 +49878,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49240
49878
|
track: 'inline-filter',
|
|
49241
49879
|
family: 'numbers-range',
|
|
49242
49880
|
friendlyName: 'Inline rating',
|
|
49243
|
-
description: '
|
|
49881
|
+
description: 'Visual rating filter for the toolbar.',
|
|
49244
49882
|
tags: ['inline', 'filter', 'rating'],
|
|
49245
49883
|
valueShape: 'number | { start?, end? }',
|
|
49246
|
-
recommendedWhen: ['score
|
|
49247
|
-
avoidWhen: ['
|
|
49884
|
+
recommendedWhen: ['visual score', 'star rating'],
|
|
49885
|
+
avoidWhen: ['when a raw number is enough'],
|
|
49248
49886
|
dataSourceKind: 'specialized',
|
|
49249
49887
|
apiPath: jsonApiPath('inline-rating/pdx-inline-rating.json-api.md'),
|
|
49250
49888
|
}),
|
|
@@ -49254,12 +49892,13 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49254
49892
|
track: 'inline-filter',
|
|
49255
49893
|
family: 'numbers-range',
|
|
49256
49894
|
friendlyName: 'Inline distance radius',
|
|
49257
|
-
description: '
|
|
49895
|
+
description: 'Semantic distance and radius filter.',
|
|
49258
49896
|
tags: ['inline', 'filter', 'distance', 'radius'],
|
|
49259
49897
|
valueShape: 'number | { start?, end? }',
|
|
49260
|
-
recommendedWhen: ['
|
|
49261
|
-
avoidWhen: ['
|
|
49898
|
+
recommendedWhen: ['search radius', 'proximity'],
|
|
49899
|
+
avoidWhen: ['generic numeric range'],
|
|
49262
49900
|
dataSourceKind: 'specialized',
|
|
49901
|
+
interactionPattern: 'range',
|
|
49263
49902
|
apiPath: jsonApiPath('inline-distance-radius/pdx-inline-distance-radius.json-api.md'),
|
|
49264
49903
|
}),
|
|
49265
49904
|
createEntry({
|
|
@@ -49268,12 +49907,14 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49268
49907
|
track: 'inline-filter',
|
|
49269
49908
|
family: 'numbers-range',
|
|
49270
49909
|
friendlyName: 'Inline score priority',
|
|
49271
|
-
description: '
|
|
49910
|
+
description: 'Semantic score or priority filter.',
|
|
49272
49911
|
tags: ['inline', 'filter', 'score', 'priority'],
|
|
49273
49912
|
valueShape: 'number | { start?, end? }',
|
|
49274
|
-
recommendedWhen: ['
|
|
49275
|
-
avoidWhen: ['
|
|
49913
|
+
recommendedWhen: ['priority', 'criticality', 'score band'],
|
|
49914
|
+
avoidWhen: ['simple number with no semantic gain'],
|
|
49276
49915
|
dataSourceKind: 'specialized',
|
|
49916
|
+
icon: { key: 'visual', tone: 'amber' },
|
|
49917
|
+
interactionPattern: 'visual',
|
|
49277
49918
|
apiPath: jsonApiPath('inline-score-priority/pdx-inline-score-priority.json-api.md'),
|
|
49278
49919
|
}),
|
|
49279
49920
|
createEntry({
|
|
@@ -49282,11 +49923,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49282
49923
|
track: 'inline-filter',
|
|
49283
49924
|
family: 'date-time',
|
|
49284
49925
|
friendlyName: 'Inline date',
|
|
49285
|
-
description: '
|
|
49926
|
+
description: 'Compact date filter.',
|
|
49286
49927
|
tags: ['inline', 'filter', 'date'],
|
|
49287
49928
|
valueShape: 'Date',
|
|
49288
|
-
recommendedWhen: ['
|
|
49289
|
-
avoidWhen: ['
|
|
49929
|
+
recommendedWhen: ['single date in the toolbar'],
|
|
49930
|
+
avoidWhen: ['full period'],
|
|
49290
49931
|
dataSourceKind: 'specialized',
|
|
49291
49932
|
apiPath: jsonApiPath('inline-date/pdx-inline-date.json-api.md'),
|
|
49292
49933
|
}),
|
|
@@ -49296,11 +49937,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49296
49937
|
track: 'inline-filter',
|
|
49297
49938
|
family: 'date-time',
|
|
49298
49939
|
friendlyName: 'Inline date range',
|
|
49299
|
-
description: '
|
|
49940
|
+
description: 'Compact date range with toolbar semantics.',
|
|
49300
49941
|
tags: ['inline', 'filter', 'date', 'range'],
|
|
49301
49942
|
valueShape: '{ startDate?, endDate? }',
|
|
49302
|
-
recommendedWhen: ['
|
|
49303
|
-
avoidWhen: ['toolbar
|
|
49943
|
+
recommendedWhen: ['time window in the toolbar'],
|
|
49944
|
+
avoidWhen: ['dense toolbar or a single date'],
|
|
49304
49945
|
dataSourceKind: 'specialized',
|
|
49305
49946
|
apiPath: jsonApiPath('inline-date-range/pdx-inline-date-range.json-api.md'),
|
|
49306
49947
|
stateRecipes: [
|
|
@@ -49313,11 +49954,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49313
49954
|
track: 'inline-filter',
|
|
49314
49955
|
family: 'date-time',
|
|
49315
49956
|
friendlyName: 'Inline time',
|
|
49316
|
-
description: '
|
|
49957
|
+
description: 'Compact time filter.',
|
|
49317
49958
|
tags: ['inline', 'filter', 'time'],
|
|
49318
49959
|
valueShape: 'string HH:mm',
|
|
49319
|
-
recommendedWhen: ['
|
|
49320
|
-
avoidWhen: ['
|
|
49960
|
+
recommendedWhen: ['single time in the toolbar'],
|
|
49961
|
+
avoidWhen: ['relative period or range'],
|
|
49321
49962
|
dataSourceKind: 'specialized',
|
|
49322
49963
|
apiPath: jsonApiPath('inline-time/pdx-inline-time.json-api.md'),
|
|
49323
49964
|
}),
|
|
@@ -49327,11 +49968,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49327
49968
|
track: 'inline-filter',
|
|
49328
49969
|
family: 'date-time',
|
|
49329
49970
|
friendlyName: 'Inline time range',
|
|
49330
|
-
description: '
|
|
49971
|
+
description: 'Compact time range for the toolbar.',
|
|
49331
49972
|
tags: ['inline', 'filter', 'time', 'range'],
|
|
49332
49973
|
valueShape: '{ start?, end? }',
|
|
49333
|
-
recommendedWhen: ['
|
|
49334
|
-
avoidWhen: ['
|
|
49974
|
+
recommendedWhen: ['shift', 'operational window'],
|
|
49975
|
+
avoidWhen: ['single time'],
|
|
49335
49976
|
dataSourceKind: 'specialized',
|
|
49336
49977
|
apiPath: jsonApiPath('inline-time-range/pdx-inline-time-range.json-api.md'),
|
|
49337
49978
|
}),
|
|
@@ -49341,11 +49982,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49341
49982
|
track: 'inline-filter',
|
|
49342
49983
|
family: 'trees-lists',
|
|
49343
49984
|
friendlyName: 'Inline tree select',
|
|
49344
|
-
description: '
|
|
49985
|
+
description: 'Compact tree filter for the toolbar.',
|
|
49345
49986
|
tags: ['inline', 'filter', 'tree', 'hierarchy'],
|
|
49346
49987
|
valueShape: 'simple node value',
|
|
49347
|
-
recommendedWhen: ['
|
|
49348
|
-
avoidWhen: ['
|
|
49988
|
+
recommendedWhen: ['taxonomy or organizational unit in the toolbar'],
|
|
49989
|
+
avoidWhen: ['tree that is too deep'],
|
|
49349
49990
|
dataSourceKind: 'mixed',
|
|
49350
49991
|
apiPath: jsonApiPath('inline-tree-select/pdx-inline-tree-select.json-api.md'),
|
|
49351
49992
|
}),
|
|
@@ -49355,12 +49996,14 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49355
49996
|
track: 'inline-filter',
|
|
49356
49997
|
family: 'selection',
|
|
49357
49998
|
friendlyName: 'Inline pipeline status',
|
|
49358
|
-
description: '
|
|
49999
|
+
description: 'Semantic pipeline status filter.',
|
|
49359
50000
|
tags: ['inline', 'filter', 'pipeline', 'status'],
|
|
49360
50001
|
valueShape: 'simple value | unknown[]',
|
|
49361
|
-
recommendedWhen: ['
|
|
49362
|
-
avoidWhen: ['status
|
|
50002
|
+
recommendedWhen: ['operational pipeline', 'sales pipeline'],
|
|
50003
|
+
avoidWhen: ['simple status with no visual gain'],
|
|
49363
50004
|
dataSourceKind: 'specialized',
|
|
50005
|
+
icon: { key: 'visual', tone: 'violet' },
|
|
50006
|
+
interactionPattern: 'visual',
|
|
49364
50007
|
apiPath: jsonApiPath('inline-pipeline-status/pdx-inline-pipeline-status.json-api.md'),
|
|
49365
50008
|
}),
|
|
49366
50009
|
createEntry({
|
|
@@ -49369,11 +50012,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49369
50012
|
track: 'inline-filter',
|
|
49370
50013
|
family: 'date-time',
|
|
49371
50014
|
friendlyName: 'Inline relative period',
|
|
49372
|
-
description: '
|
|
50015
|
+
description: 'Semantic relative period preset.',
|
|
49373
50016
|
tags: ['inline', 'filter', 'date', 'relative'],
|
|
49374
50017
|
valueShape: 'string',
|
|
49375
|
-
recommendedWhen: ['
|
|
49376
|
-
avoidWhen: ['API
|
|
50018
|
+
recommendedWhen: ['today', 'yesterday', 'last 7 days', 'this month'],
|
|
50019
|
+
avoidWhen: ['API outside the canonical track that does not normalize presets'],
|
|
49377
50020
|
dataSourceKind: 'specialized',
|
|
49378
50021
|
apiPath: jsonApiPath('inline-relative-period/pdx-inline-relative-period.json-api.md'),
|
|
49379
50022
|
}),
|
|
@@ -49383,12 +50026,14 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49383
50026
|
track: 'inline-filter',
|
|
49384
50027
|
family: 'selection',
|
|
49385
50028
|
friendlyName: 'Inline sentiment',
|
|
49386
|
-
description: '
|
|
50029
|
+
description: 'Semantic sentiment or polarity filter.',
|
|
49387
50030
|
tags: ['inline', 'filter', 'sentiment'],
|
|
49388
50031
|
valueShape: 'string',
|
|
49389
|
-
recommendedWhen: ['
|
|
49390
|
-
avoidWhen: ['enum
|
|
50032
|
+
recommendedWhen: ['sentiment', 'polarity', 'mood'],
|
|
50033
|
+
avoidWhen: ['simple enum with no visual gain'],
|
|
49391
50034
|
dataSourceKind: 'specialized',
|
|
50035
|
+
icon: { key: 'visual', tone: 'rose' },
|
|
50036
|
+
interactionPattern: 'visual',
|
|
49392
50037
|
apiPath: jsonApiPath('inline-sentiment/pdx-inline-sentiment.json-api.md'),
|
|
49393
50038
|
}),
|
|
49394
50039
|
createEntry({
|
|
@@ -49397,12 +50042,14 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49397
50042
|
track: 'inline-filter',
|
|
49398
50043
|
family: 'selection',
|
|
49399
50044
|
friendlyName: 'Inline color label',
|
|
49400
|
-
description: '
|
|
50045
|
+
description: 'Semantic colored-label filter.',
|
|
49401
50046
|
tags: ['inline', 'filter', 'color', 'labels'],
|
|
49402
50047
|
valueShape: 'simple value | unknown[]',
|
|
49403
|
-
recommendedWhen: ['tags
|
|
49404
|
-
avoidWhen: ['
|
|
50048
|
+
recommendedWhen: ['colored tags', 'visual categories'],
|
|
50049
|
+
avoidWhen: ['when color is the only channel of meaning'],
|
|
49405
50050
|
dataSourceKind: 'specialized',
|
|
50051
|
+
icon: { key: 'visual', tone: 'teal' },
|
|
50052
|
+
interactionPattern: 'visual',
|
|
49406
50053
|
apiPath: jsonApiPath('inline-color-label/pdx-inline-color-label.json-api.md'),
|
|
49407
50054
|
a11yNotes: [
|
|
49408
50055
|
'Nunca dependa apenas de cor para comunicar estado ou significado.',
|
|
@@ -49415,11 +50062,11 @@ const DYNAMIC_FIELDS_PLAYGROUND_CATALOG = [
|
|
|
49415
50062
|
track: 'inline-filter',
|
|
49416
50063
|
family: 'toggle-choice',
|
|
49417
50064
|
friendlyName: 'Inline toggle',
|
|
49418
|
-
description: '
|
|
50065
|
+
description: 'Compact boolean with neutral state for the toolbar.',
|
|
49419
50066
|
tags: ['inline', 'filter', 'toggle', 'boolean'],
|
|
49420
50067
|
valueShape: 'boolean | null',
|
|
49421
|
-
recommendedWhen: ['
|
|
49422
|
-
avoidWhen: ['false
|
|
50068
|
+
recommendedWhen: ['simple boolean in the toolbar'],
|
|
50069
|
+
avoidWhen: ['false and null are not well documented in the flow'],
|
|
49423
50070
|
dataSourceKind: 'local',
|
|
49424
50071
|
apiPath: jsonApiPath('inline-toggle/pdx-inline-toggle.json-api.md'),
|
|
49425
50072
|
stateRecipes: [
|
|
@@ -50826,6 +51473,24 @@ function getControlTypeCatalog(controlType) {
|
|
|
50826
51473
|
* Lida com campos que não possuem controlType definido,
|
|
50827
51474
|
* inferindo tipos apropriados baseado no schema JSON.
|
|
50828
51475
|
*/
|
|
51476
|
+
const VALUE_PRESENTATION_TYPES = new Set([
|
|
51477
|
+
'string',
|
|
51478
|
+
'number',
|
|
51479
|
+
'currency',
|
|
51480
|
+
'percentage',
|
|
51481
|
+
'date',
|
|
51482
|
+
'datetime',
|
|
51483
|
+
'time',
|
|
51484
|
+
'boolean',
|
|
51485
|
+
]);
|
|
51486
|
+
const VALUE_PRESENTATION_STYLES = new Set([
|
|
51487
|
+
'default',
|
|
51488
|
+
'short',
|
|
51489
|
+
'medium',
|
|
51490
|
+
'long',
|
|
51491
|
+
'full',
|
|
51492
|
+
'compact',
|
|
51493
|
+
]);
|
|
50829
51494
|
/**
|
|
50830
51495
|
* Mapeia um JSON Schema completo para array de FieldMetadata
|
|
50831
51496
|
*
|
|
@@ -50925,6 +51590,10 @@ function mapPropertyToFieldMetadata(fieldName, property, requiredFields = []) {
|
|
|
50925
51590
|
// Propriedades específicas baseadas no tipo
|
|
50926
51591
|
...extractTypeSpecificProperties(property, uiConfig),
|
|
50927
51592
|
};
|
|
51593
|
+
const valuePresentation = mapValuePresentation(uiConfig.valuePresentation);
|
|
51594
|
+
if (valuePresentation) {
|
|
51595
|
+
fieldMetadata.valuePresentation = valuePresentation;
|
|
51596
|
+
}
|
|
50928
51597
|
// Keep a lightweight trace for downstream editors/runtimes to distinguish
|
|
50929
51598
|
// explicit schema text from convenience-generated labels.
|
|
50930
51599
|
if (!uiConfig.label && !property.title) {
|
|
@@ -50942,6 +51611,41 @@ function mapPropertyToFieldMetadata(fieldName, property, requiredFields = []) {
|
|
|
50942
51611
|
}
|
|
50943
51612
|
return fieldMetadata;
|
|
50944
51613
|
}
|
|
51614
|
+
function mapValuePresentation(value) {
|
|
51615
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
51616
|
+
return undefined;
|
|
51617
|
+
}
|
|
51618
|
+
const typeToken = String(value.type ?? '').trim();
|
|
51619
|
+
if (!typeToken || !VALUE_PRESENTATION_TYPES.has(typeToken)) {
|
|
51620
|
+
if (typeToken) {
|
|
51621
|
+
logger.warn(`[JsonSchemaMapper] Ignorando x-ui.valuePresentation.type invalido: ${typeToken}`);
|
|
51622
|
+
}
|
|
51623
|
+
return undefined;
|
|
51624
|
+
}
|
|
51625
|
+
const presentation = {
|
|
51626
|
+
type: typeToken,
|
|
51627
|
+
};
|
|
51628
|
+
const styleToken = String(value.style ?? '').trim();
|
|
51629
|
+
if (styleToken) {
|
|
51630
|
+
if (VALUE_PRESENTATION_STYLES.has(styleToken)) {
|
|
51631
|
+
presentation.style = styleToken;
|
|
51632
|
+
}
|
|
51633
|
+
else {
|
|
51634
|
+
logger.warn(`[JsonSchemaMapper] Ignorando x-ui.valuePresentation.style invalido: ${styleToken}`);
|
|
51635
|
+
}
|
|
51636
|
+
}
|
|
51637
|
+
const formatToken = String(value.format ?? '').trim();
|
|
51638
|
+
if (formatToken) {
|
|
51639
|
+
presentation.format = formatToken;
|
|
51640
|
+
}
|
|
51641
|
+
if (value.currency && typeof value.currency === 'object') {
|
|
51642
|
+
presentation.currency = { ...value.currency };
|
|
51643
|
+
}
|
|
51644
|
+
if (value.number && typeof value.number === 'object') {
|
|
51645
|
+
presentation.number = { ...value.number };
|
|
51646
|
+
}
|
|
51647
|
+
return presentation;
|
|
51648
|
+
}
|
|
50945
51649
|
/**
|
|
50946
51650
|
* Infere controlType baseado no schema JSON quando x-ui não está disponível
|
|
50947
51651
|
*
|