@ng-forge/dynamic-forms-ionic 0.10.0-next.1 → 0.10.0-next.3
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.
|
@@ -70,7 +70,6 @@ var ionicButton_component = /*#__PURE__*/Object.freeze({
|
|
|
70
70
|
default: IonicButtonFieldComponent
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
// Public API - component
|
|
74
73
|
|
|
75
74
|
class IonicCheckboxFieldComponent {
|
|
76
75
|
ngf = injectNgForgeField();
|
|
@@ -147,9 +146,7 @@ class IonicDatepickerFieldComponent {
|
|
|
147
146
|
}
|
|
148
147
|
onDateChange(event) {
|
|
149
148
|
const value = event.detail.value;
|
|
150
|
-
|
|
151
|
-
// to match the field tree's value type.
|
|
152
|
-
if (value && typeof value === 'string' && value.length > 0) {
|
|
149
|
+
if (value && typeof value === 'string' && value.length > 0) {
|
|
153
150
|
const date = new Date(value);
|
|
154
151
|
this.ngf.field()().value.set(date);
|
|
155
152
|
}
|
|
@@ -318,18 +315,10 @@ var ionicDatepicker_component = /*#__PURE__*/Object.freeze({
|
|
|
318
315
|
default: IonicDatepickerFieldComponent
|
|
319
316
|
});
|
|
320
317
|
|
|
321
|
-
/** Ionic adapter binding for the shared preset runner. */
|
|
322
318
|
function runIonicPresetAction(preset, ctx, collaborators) {
|
|
323
319
|
return runPresetAction(preset, ctx, collaborators, 'Ionic', 'ion-input');
|
|
324
320
|
}
|
|
325
321
|
|
|
326
|
-
/**
|
|
327
|
-
* Inline `ion-button` addon — the host element IS `<ion-button>` so Ionic's
|
|
328
|
-
* `::slotted(ion-button[slot=start|end])` shadow CSS matches and applies its
|
|
329
|
-
* native icon-only sizing. `IonButtonAddonComponent` (tag selector) stays
|
|
330
|
-
* for the universal `<df-addon-slot>` dispatcher when the addon is rendered
|
|
331
|
-
* outside an `<ion-input>` host.
|
|
332
|
-
*/
|
|
333
322
|
class IonInlineButtonAddonComponent {
|
|
334
323
|
injector = inject(Injector);
|
|
335
324
|
action = injectNgForgeAddonAction();
|
|
@@ -340,9 +329,7 @@ class IonInlineButtonAddonComponent {
|
|
|
340
329
|
color = computed(() => this.addon().color, ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
341
330
|
fill = computed(() => this.addon().fill ?? 'clear', ...(ngDevMode ? [{ debugName: "fill" }] : /* istanbul ignore next */ []));
|
|
342
331
|
iconOnly = computed(() => !!this.icon() && !this.label(), ...(ngDevMode ? [{ debugName: "iconOnly" }] : /* istanbul ignore next */ []));
|
|
343
|
-
|
|
344
|
-
// via an effect (resolveDynamicValue's toSignal can't run inside computed).
|
|
345
|
-
_ariaLabelSignal = signal(undefined, ...(ngDevMode ? [{ debugName: "_ariaLabelSignal" }] : /* istanbul ignore next */ []));
|
|
332
|
+
_ariaLabelSignal = signal(undefined, ...(ngDevMode ? [{ debugName: "_ariaLabelSignal" }] : /* istanbul ignore next */ []));
|
|
346
333
|
resolvedAriaLabel = computed(() => this._ariaLabelSignal()?.() ?? undefined, ...(ngDevMode ? [{ debugName: "resolvedAriaLabel" }] : /* istanbul ignore next */ []));
|
|
347
334
|
constructor() {
|
|
348
335
|
explicitEffect([this.ariaLabel], ([raw]) => {
|
|
@@ -379,8 +366,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
379
366
|
{{ lbl | dynamicText | async }}
|
|
380
367
|
}
|
|
381
368
|
`, host: {
|
|
382
|
-
|
|
383
|
-
'[attr.color]': 'color() ?? null',
|
|
369
|
+
'[attr.color]': 'color() ?? null',
|
|
384
370
|
'[attr.fill]': 'fill()',
|
|
385
371
|
'[attr.disabled]': 'action.disabled() || action.loading() ? "true" : null',
|
|
386
372
|
'[attr.aria-label]': 'resolvedAriaLabel() ?? null',
|
|
@@ -389,86 +375,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
389
375
|
}, changeDetection: ChangeDetectionStrategy.OnPush, styles: [".df-ion-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"] }]
|
|
390
376
|
}], ctorParameters: () => [] });
|
|
391
377
|
|
|
392
|
-
/**
|
|
393
|
-
* Injection token for Ionic form configuration.
|
|
394
|
-
* Use this to provide global configuration for Ionic form fields.
|
|
395
|
-
*
|
|
396
|
-
* @example
|
|
397
|
-
* ```typescript
|
|
398
|
-
* import { provideDynamicForm } from '@ng-forge/dynamic-forms';
|
|
399
|
-
* import { withIonicFields } from '@ng-forge/dynamic-forms-ionic';
|
|
400
|
-
*
|
|
401
|
-
* export const appConfig: ApplicationConfig = {
|
|
402
|
-
* providers: [
|
|
403
|
-
* provideDynamicForm(
|
|
404
|
-
* ...withIonicFields({
|
|
405
|
-
* fill: 'outline',
|
|
406
|
-
* labelPlacement: 'floating'
|
|
407
|
-
* })
|
|
408
|
-
* )
|
|
409
|
-
* ]
|
|
410
|
-
* };
|
|
411
|
-
* ```
|
|
412
|
-
*/
|
|
413
378
|
const IONIC_CONFIG = new InjectionToken('IONIC_CONFIG');
|
|
414
379
|
|
|
415
|
-
/**
|
|
416
|
-
* Per-field writable signal that overrides the input's `type` attribute.
|
|
417
|
-
*
|
|
418
|
-
* Provided at the `ion-input` field component level. The button addon's
|
|
419
|
-
* `'toggle-password-visibility'` preset writes to it; the field component
|
|
420
|
-
* reads it to compute its effective `type`.
|
|
421
|
-
*
|
|
422
|
-
* Optional from a button's perspective — when the button is hosted inside a
|
|
423
|
-
* field that doesn't provide this token (e.g., textarea or a future
|
|
424
|
-
* non-input field), the toggle preset is a no-op.
|
|
425
|
-
*/
|
|
426
380
|
const IONIC_INPUT_TYPE_OVERRIDE = new InjectionToken('IONIC_INPUT_TYPE_OVERRIDE');
|
|
427
381
|
|
|
428
|
-
// minlength/maxlength bindings: Signal Forms auto-syncs these on NATIVE
|
|
429
|
-
// inputs; <ion-input> is a Stencil web component so we bind directly from
|
|
430
|
-
// FieldState (`f().maxLength?.()` — the signal itself is missing when no
|
|
431
|
-
// validator is configured).
|
|
432
382
|
class IonicInputFieldComponent {
|
|
433
383
|
elementRef = inject((ElementRef));
|
|
434
384
|
ionicConfig = inject(IONIC_CONFIG, { optional: true });
|
|
435
385
|
ngf = injectNgForgeField();
|
|
436
386
|
ngfa = injectNgForgeAddons();
|
|
437
387
|
props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
* component level so `setInputIfDeclared` (which uses
|
|
441
|
-
* `reflectComponentType`) can write it.
|
|
442
|
-
*/
|
|
443
|
-
fieldInputs = input(...(ngDevMode ? [undefined, { debugName: "fieldInputs" }] : /* istanbul ignore next */ []));
|
|
444
|
-
/** Per-instance type override populated by `toggle-password-visibility` preset. */
|
|
445
|
-
typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);
|
|
388
|
+
fieldInputs = input(...(ngDevMode ? [undefined, { debugName: "fieldInputs" }] : /* istanbul ignore next */ []));
|
|
389
|
+
typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);
|
|
446
390
|
fill = computed(() => this.props()?.fill ?? this.ionicConfig?.fill ?? 'solid', ...(ngDevMode ? [{ debugName: "fill" }] : /* istanbul ignore next */ []));
|
|
447
391
|
shape = computed(() => this.props()?.shape ?? this.ionicConfig?.shape, ...(ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []));
|
|
448
|
-
|
|
449
|
-
* Bootstrap / PrimeNG. Consumers can opt into Ionic's native inline 'start'
|
|
450
|
-
* or 'fixed' via props.labelPlacement or the IONIC_CONFIG token. */
|
|
451
|
-
labelPlacement = computed(() => this.props()?.labelPlacement ?? this.ionicConfig?.labelPlacement ?? 'stacked', ...(ngDevMode ? [{ debugName: "labelPlacement" }] : /* istanbul ignore next */ []));
|
|
392
|
+
labelPlacement = computed(() => this.props()?.labelPlacement ?? this.ionicConfig?.labelPlacement ?? 'stacked', ...(ngDevMode ? [{ debugName: "labelPlacement" }] : /* istanbul ignore next */ []));
|
|
452
393
|
color = computed(() => this.props()?.color ?? this.ionicConfig?.color, ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
/** Per-kind split: ion-button addons render inline via the attribute-
|
|
456
|
-
* selector inline component (so the slotted element is a native
|
|
457
|
-
* <ion-button> Ionic can style); everything else (icon/text/template/
|
|
458
|
-
* component kinds) goes through the universal <df-addon-slot> dispatcher
|
|
459
|
-
* wrapped in <span slot="start|end"> for safe shadow-DOM projection. */
|
|
460
|
-
buttonPrefixAddons = computed(() => this.ngfa.prefixAddons().filter((a) => a.kind === 'ion-button'), ...(ngDevMode ? [{ debugName: "buttonPrefixAddons" }] : /* istanbul ignore next */ []));
|
|
394
|
+
type = computed(() => this.typeOverride() ?? this.props()?.type ?? 'text', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
395
|
+
buttonPrefixAddons = computed(() => this.ngfa.prefixAddons().filter((a) => a.kind === 'ion-button'), ...(ngDevMode ? [{ debugName: "buttonPrefixAddons" }] : /* istanbul ignore next */ []));
|
|
461
396
|
buttonSuffixAddons = computed(() => this.ngfa.suffixAddons().filter((a) => a.kind === 'ion-button'), ...(ngDevMode ? [{ debugName: "buttonSuffixAddons" }] : /* istanbul ignore next */ []));
|
|
462
397
|
decorativePrefixAddons = computed(() => this.ngfa.prefixAddons().filter((a) => a.kind !== 'ion-button'), ...(ngDevMode ? [{ debugName: "decorativePrefixAddons" }] : /* istanbul ignore next */ []));
|
|
463
398
|
decorativeSuffixAddons = computed(() => this.ngfa.suffixAddons().filter((a) => a.kind !== 'ion-button'), ...(ngDevMode ? [{ debugName: "decorativeSuffixAddons" }] : /* istanbul ignore next */ []));
|
|
464
|
-
|
|
465
|
-
destroyed = false;
|
|
399
|
+
destroyed = false;
|
|
466
400
|
constructor() {
|
|
467
401
|
inject(DestroyRef).onDestroy(() => (this.destroyed = true));
|
|
468
|
-
|
|
469
|
-
// propagate aria-describedby to it. This effect imperatively syncs the attribute
|
|
470
|
-
// after a microtask to ensure Ionic has resolved the internal element.
|
|
471
|
-
explicitEffect([this.ngf.ariaDescribedBy], ([describedBy]) => {
|
|
402
|
+
explicitEffect([this.ngf.ariaDescribedBy], ([describedBy]) => {
|
|
472
403
|
queueMicrotask(() => {
|
|
473
404
|
if (this.destroyed)
|
|
474
405
|
return;
|
|
@@ -495,18 +426,12 @@ class IonicInputFieldComponent {
|
|
|
495
426
|
useFactory: () => signal(undefined),
|
|
496
427
|
},
|
|
497
428
|
{
|
|
498
|
-
|
|
499
|
-
// reset / paste / copy / toggle-password-visibility). The directive
|
|
500
|
-
// (`NgForgeAddonAction`) delegates here when an addon configures a
|
|
501
|
-
// `preset`. Per-ion-input-instance so the `typeOverride` signal is
|
|
502
|
-
// scoped to one field.
|
|
503
|
-
provide: ADDON_PRESET_HANDLER,
|
|
429
|
+
provide: ADDON_PRESET_HANDLER,
|
|
504
430
|
useFactory: () => {
|
|
505
431
|
const typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);
|
|
506
432
|
const fsc = inject(FIELD_SIGNAL_CONTEXT, { optional: true });
|
|
507
433
|
const logger = inject(DynamicFormLogger);
|
|
508
|
-
|
|
509
|
-
const host = inject(forwardRef(() => IonicInputFieldComponent));
|
|
434
|
+
const host = inject(forwardRef(() => IonicInputFieldComponent));
|
|
510
435
|
return {
|
|
511
436
|
run: (preset, ctx) => {
|
|
512
437
|
const fieldKey = ctx.field.key;
|
|
@@ -617,18 +542,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
617
542
|
useFactory: () => signal(undefined),
|
|
618
543
|
},
|
|
619
544
|
{
|
|
620
|
-
|
|
621
|
-
// reset / paste / copy / toggle-password-visibility). The directive
|
|
622
|
-
// (`NgForgeAddonAction`) delegates here when an addon configures a
|
|
623
|
-
// `preset`. Per-ion-input-instance so the `typeOverride` signal is
|
|
624
|
-
// scoped to one field.
|
|
625
|
-
provide: ADDON_PRESET_HANDLER,
|
|
545
|
+
provide: ADDON_PRESET_HANDLER,
|
|
626
546
|
useFactory: () => {
|
|
627
547
|
const typeOverride = inject(IONIC_INPUT_TYPE_OVERRIDE);
|
|
628
548
|
const fsc = inject(FIELD_SIGNAL_CONTEXT, { optional: true });
|
|
629
549
|
const logger = inject(DynamicFormLogger);
|
|
630
|
-
|
|
631
|
-
const host = inject(forwardRef(() => IonicInputFieldComponent));
|
|
550
|
+
const host = inject(forwardRef(() => IonicInputFieldComponent));
|
|
632
551
|
return {
|
|
633
552
|
run: (preset, ctx) => {
|
|
634
553
|
const fieldKey = ctx.field.key;
|
|
@@ -659,8 +578,7 @@ class IonicMultiCheckboxFieldComponent {
|
|
|
659
578
|
const currentValues = this.ngf.field()().value();
|
|
660
579
|
return this.options().filter((option) => currentValues.includes(option.value));
|
|
661
580
|
}, { ...(ngDevMode ? { debugName: "valueViewModel" } : /* istanbul ignore next */ {}), equal: isEqual });
|
|
662
|
-
|
|
663
|
-
checkedValuesMap = computed(() => {
|
|
581
|
+
checkedValuesMap = computed(() => {
|
|
664
582
|
const map = {};
|
|
665
583
|
for (const opt of this.valueViewModel()) {
|
|
666
584
|
map[String(opt.value)] = true;
|
|
@@ -1029,10 +947,7 @@ class IonicTextareaFieldComponent {
|
|
|
1029
947
|
ngf = injectNgForgeField();
|
|
1030
948
|
props = input(...(ngDevMode ? [undefined, { debugName: "props" }] : /* istanbul ignore next */ []));
|
|
1031
949
|
constructor() {
|
|
1032
|
-
|
|
1033
|
-
// propagate aria-describedby to it. This effect imperatively syncs the attribute
|
|
1034
|
-
// after a microtask to ensure Ionic has resolved the internal element.
|
|
1035
|
-
explicitEffect([this.ngf.ariaDescribedBy], ([describedBy]) => {
|
|
950
|
+
explicitEffect([this.ngf.ariaDescribedBy], ([describedBy]) => {
|
|
1036
951
|
queueMicrotask(() => {
|
|
1037
952
|
const ionTextarea = this.elementRef.nativeElement.querySelector('ion-textarea');
|
|
1038
953
|
if (ionTextarea?.getInputElement) {
|
|
@@ -1115,58 +1030,29 @@ var ionicTextarea_component = /*#__PURE__*/Object.freeze({
|
|
|
1115
1030
|
default: IonicTextareaFieldComponent
|
|
1116
1031
|
});
|
|
1117
1032
|
|
|
1118
|
-
/**
|
|
1119
|
-
* ion-toggle wrapper implementing FormCheckboxControl. Rendered inside
|
|
1120
|
-
* `df-ion-toggle`. `NgForgeControl` on `<ion-toggle>` claims the ambient
|
|
1121
|
-
* parent NgForgeField and routes meta + aria onto that element.
|
|
1122
|
-
*/
|
|
1123
1033
|
class IonicToggleControlComponent {
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
/** Whether the field is disabled */
|
|
1132
|
-
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
1133
|
-
/** Whether the field is readonly */
|
|
1134
|
-
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
1135
|
-
/** Whether the field is invalid (from Field directive) */
|
|
1136
|
-
invalid = input(false, ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
|
|
1137
|
-
/** Whether the field is required (from Field directive) */
|
|
1138
|
-
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
1139
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
1140
|
-
// Ionic-specific props
|
|
1141
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
1142
|
-
labelPlacement = input('end', ...(ngDevMode ? [{ debugName: "labelPlacement" }] : /* istanbul ignore next */ []));
|
|
1034
|
+
checked = model(false, ...(ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []));
|
|
1035
|
+
touched = model(false, ...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
|
|
1036
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
1037
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
1038
|
+
invalid = input(false, ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
|
|
1039
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
1040
|
+
labelPlacement = input('end', ...(ngDevMode ? [{ debugName: "labelPlacement" }] : /* istanbul ignore next */ []));
|
|
1143
1041
|
justify = input(undefined, ...(ngDevMode ? [{ debugName: "justify" }] : /* istanbul ignore next */ []));
|
|
1144
1042
|
color = input('primary', ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
1145
1043
|
enableOnOffLabels = input(false, ...(ngDevMode ? [{ debugName: "enableOnOffLabels" }] : /* istanbul ignore next */ []));
|
|
1146
1044
|
tabIndex = input(undefined, ...(ngDevMode ? [{ debugName: "tabIndex" }] : /* istanbul ignore next */ []));
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
ariaReadonly = computed(() => (this.readonly() ? true : null), ...(ngDevMode ? [{ debugName: "ariaReadonly" }] : /* istanbul ignore next */ []));
|
|
1150
|
-
/** Computed checked state - ensures proper boolean conversion for ion-toggle */
|
|
1151
|
-
isChecked = computed(() => {
|
|
1045
|
+
ariaReadonly = computed(() => (this.readonly() ? true : null), ...(ngDevMode ? [{ debugName: "ariaReadonly" }] : /* istanbul ignore next */ []));
|
|
1046
|
+
isChecked = computed(() => {
|
|
1152
1047
|
return this.checked() === true;
|
|
1153
1048
|
}, ...(ngDevMode ? [{ debugName: "isChecked" }] : /* istanbul ignore next */ []));
|
|
1154
|
-
|
|
1155
|
-
* ion-toggle doesn't have a native readonly attribute.
|
|
1156
|
-
* When readonly, we disable the toggle to prevent changes while maintaining the visual state.
|
|
1157
|
-
*/
|
|
1158
|
-
isEffectivelyDisabled = computed(() => {
|
|
1049
|
+
isEffectivelyDisabled = computed(() => {
|
|
1159
1050
|
return this.disabled() || this.readonly();
|
|
1160
1051
|
}, ...(ngDevMode ? [{ debugName: "isEffectivelyDisabled" }] : /* istanbul ignore next */ []));
|
|
1161
|
-
|
|
1162
|
-
// Event Handlers
|
|
1163
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
1164
|
-
/** Handle toggle change - sync ion-toggle's checked state to our checked model */
|
|
1165
|
-
onToggleChange(event) {
|
|
1052
|
+
onToggleChange(event) {
|
|
1166
1053
|
this.checked.set(event.detail.checked);
|
|
1167
1054
|
}
|
|
1168
|
-
|
|
1169
|
-
onBlur() {
|
|
1055
|
+
onBlur() {
|
|
1170
1056
|
this.touched.set(true);
|
|
1171
1057
|
}
|
|
1172
1058
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: IonicToggleControlComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -1269,13 +1155,7 @@ var ionicToggle_component = /*#__PURE__*/Object.freeze({
|
|
|
1269
1155
|
default: IonicToggleFieldComponent
|
|
1270
1156
|
});
|
|
1271
1157
|
|
|
1272
|
-
// Public exports for ionic field fields and types
|
|
1273
|
-
// Button
|
|
1274
1158
|
|
|
1275
|
-
/**
|
|
1276
|
-
* Ionic field type constants
|
|
1277
|
-
* Based on available field components in the /fields folder
|
|
1278
|
-
*/
|
|
1279
1159
|
const IonicField = {
|
|
1280
1160
|
Input: 'input',
|
|
1281
1161
|
Select: 'select',
|
|
@@ -1298,17 +1178,6 @@ const IonicField = {
|
|
|
1298
1178
|
Toggle: 'toggle',
|
|
1299
1179
|
};
|
|
1300
1180
|
|
|
1301
|
-
/**
|
|
1302
|
-
* Generic button mapper for custom events or basic buttons.
|
|
1303
|
-
* For specific button types (submit, next, prev, add/remove array items),
|
|
1304
|
-
* use the dedicated field types and their specific mappers.
|
|
1305
|
-
*
|
|
1306
|
-
* Supports template property for array events (AppendArrayItemEvent, PrependArrayItemEvent, InsertArrayItemEvent)
|
|
1307
|
-
* which enables the $template token in eventArgs.
|
|
1308
|
-
*
|
|
1309
|
-
* @param fieldDef The button field definition
|
|
1310
|
-
* @returns Signal containing Record of input names to values for ngComponentOutlet
|
|
1311
|
-
*/
|
|
1312
1181
|
function buttonFieldMapper(fieldDef) {
|
|
1313
1182
|
const defaultProps = inject(DEFAULT_PROPS);
|
|
1314
1183
|
const arrayContext = inject(ARRAY_CONTEXT, { optional: true });
|
|
@@ -1323,19 +1192,15 @@ function buttonFieldMapper(fieldDef) {
|
|
|
1323
1192
|
if (fieldDef.hidden !== undefined) {
|
|
1324
1193
|
inputs['hidden'] = fieldDef.hidden;
|
|
1325
1194
|
}
|
|
1326
|
-
|
|
1327
|
-
if ('event' in fieldDef && fieldDef.event !== undefined) {
|
|
1195
|
+
if ('event' in fieldDef && fieldDef.event !== undefined) {
|
|
1328
1196
|
inputs['event'] = fieldDef.event;
|
|
1329
1197
|
}
|
|
1330
|
-
|
|
1331
|
-
if ('eventArgs' in fieldDef && fieldDef.eventArgs !== undefined) {
|
|
1198
|
+
if ('eventArgs' in fieldDef && fieldDef.eventArgs !== undefined) {
|
|
1332
1199
|
inputs['eventArgs'] = fieldDef.eventArgs;
|
|
1333
1200
|
}
|
|
1334
|
-
|
|
1335
|
-
const template = 'template' in fieldDef ? fieldDef.template : undefined;
|
|
1201
|
+
const template = 'template' in fieldDef ? fieldDef.template : undefined;
|
|
1336
1202
|
if (template || arrayContext) {
|
|
1337
|
-
|
|
1338
|
-
const getIndex = () => {
|
|
1203
|
+
const getIndex = () => {
|
|
1339
1204
|
if (!arrayContext)
|
|
1340
1205
|
return -1;
|
|
1341
1206
|
return isSignal(arrayContext.index) ? arrayContext.index() : arrayContext.index;
|
|
@@ -1352,12 +1217,6 @@ function buttonFieldMapper(fieldDef) {
|
|
|
1352
1217
|
});
|
|
1353
1218
|
}
|
|
1354
1219
|
|
|
1355
|
-
/**
|
|
1356
|
-
* Navigation button mappers for Ionic - re-exported from integration package.
|
|
1357
|
-
*
|
|
1358
|
-
* These mappers handle submit, next, and previous buttons with proper
|
|
1359
|
-
* disabled state resolution based on form validity and options.
|
|
1360
|
-
*/
|
|
1361
1220
|
|
|
1362
1221
|
const VALUE_FIELD_TYPES_BASE = {
|
|
1363
1222
|
renderReadyWhen: ['field'],
|
|
@@ -1366,10 +1225,6 @@ const BUTTON_FIELD_TYPES_BASE = {
|
|
|
1366
1225
|
renderReadyWhen: [],
|
|
1367
1226
|
valueHandling: 'exclude',
|
|
1368
1227
|
};
|
|
1369
|
-
/**
|
|
1370
|
-
* Ionic field type definitions
|
|
1371
|
-
* Follows the FieldTypeDefinition interface for proper registry integration
|
|
1372
|
-
*/
|
|
1373
1228
|
const IONIC_FIELD_TYPES = [
|
|
1374
1229
|
{
|
|
1375
1230
|
name: IonicField.Input,
|
|
@@ -1501,16 +1356,9 @@ const IONIC_FIELD_TYPES = [
|
|
|
1501
1356
|
},
|
|
1502
1357
|
];
|
|
1503
1358
|
|
|
1504
|
-
/**
|
|
1505
|
-
* Module augmentation for @ng-forge/dynamic-form
|
|
1506
|
-
* This file augments the FieldRegistryLeaves interface to include
|
|
1507
|
-
* all Ionic field types provided by this library.
|
|
1508
|
-
*/
|
|
1509
1359
|
|
|
1510
1360
|
function withIonicFields(config) {
|
|
1511
|
-
|
|
1512
|
-
// the canonical Ionic surface.
|
|
1513
|
-
const base = [...IONIC_FIELD_TYPES, withIonicAddons()];
|
|
1361
|
+
const base = [...IONIC_FIELD_TYPES, withIonicAddons()];
|
|
1514
1362
|
if (config) {
|
|
1515
1363
|
base.push({
|
|
1516
1364
|
ɵkind: 'ionic-config',
|
|
@@ -1534,39 +1382,15 @@ const ION_BUTTON_KIND = {
|
|
|
1534
1382
|
kind: 'ion-button',
|
|
1535
1383
|
loadComponent: () => Promise.resolve().then(function () { return ionButtonAddon_component; }).then((m) => m.IonButtonAddonComponent),
|
|
1536
1384
|
validate: (addon, fieldKey) => {
|
|
1537
|
-
|
|
1538
|
-
// (with warning) if the rule is violated.
|
|
1539
|
-
const set = [addon.preset, addon.actionRef, addon.action].filter((v) => v !== undefined);
|
|
1385
|
+
const set = [addon.preset, addon.actionRef, addon.action].filter((v) => v !== undefined);
|
|
1540
1386
|
if (set.length > 1) {
|
|
1541
1387
|
throw new DynamicFormError(`Addon kind 'ion-button' on field '${fieldKey}' has more than one of preset/actionRef/action — exactly one allowed.`);
|
|
1542
1388
|
}
|
|
1543
|
-
|
|
1544
|
-
if (addon.icon && !addon.label && !addon.ariaLabel) {
|
|
1389
|
+
if (addon.icon && !addon.label && !addon.ariaLabel) {
|
|
1545
1390
|
throw new DynamicFormError(`Addon kind 'ion-button' on field '${fieldKey}' is icon-only — provide 'ariaLabel' for accessibility.`);
|
|
1546
1391
|
}
|
|
1547
1392
|
},
|
|
1548
1393
|
};
|
|
1549
|
-
/**
|
|
1550
|
-
* Register Ionic-shipped addon kinds (`ion-icon`, `ion-button`) standalone.
|
|
1551
|
-
*
|
|
1552
|
-
* **Most users don't need this** — `withIonicFields()` auto-includes
|
|
1553
|
-
* these kinds. Call `withIonicAddons()` directly only when you want
|
|
1554
|
-
* Ionic addon kinds without the Ionic field types (e.g., a custom
|
|
1555
|
-
* field set that wants to render `ion-icon` prefixes), or when you're
|
|
1556
|
-
* stitching addons through a different DI scope.
|
|
1557
|
-
*
|
|
1558
|
-
* @example
|
|
1559
|
-
* ```typescript
|
|
1560
|
-
* // Custom field types + Ionic addon kinds.
|
|
1561
|
-
* provideDynamicForm(
|
|
1562
|
-
* ...myCustomFields(),
|
|
1563
|
-
* withIonicAddons(),
|
|
1564
|
-
* );
|
|
1565
|
-
* ```
|
|
1566
|
-
*
|
|
1567
|
-
* Adapter authors who need to override a kind with a customised renderer
|
|
1568
|
-
* should call `withCustomAddon(...)` directly instead.
|
|
1569
|
-
*/
|
|
1570
1394
|
function withIonicAddons() {
|
|
1571
1395
|
return {
|
|
1572
1396
|
ɵkind: 'addons',
|
|
@@ -1577,33 +1401,15 @@ function withIonicAddons() {
|
|
|
1577
1401
|
};
|
|
1578
1402
|
}
|
|
1579
1403
|
|
|
1580
|
-
/**
|
|
1581
|
-
* Renderer for the `ion-button` addon kind.
|
|
1582
|
-
*
|
|
1583
|
-
* Wraps Ionic's `<ion-button>`. Click dispatch (preset / actionRef /
|
|
1584
|
-
* action precedence, multi-set warning, `disabled` / `loading`
|
|
1585
|
-
* resolution) lives on `NgForgeAddonAction`; this component focuses on
|
|
1586
|
-
* the visual layer. While `action.loading()`, an `<ion-spinner>` is
|
|
1587
|
-
* rendered in place of the icon and the button is disabled.
|
|
1588
|
-
*/
|
|
1589
1404
|
class IonButtonAddonComponent {
|
|
1590
1405
|
action = injectNgForgeAddonAction();
|
|
1591
|
-
|
|
1592
|
-
addon = this.action.addon;
|
|
1406
|
+
addon = this.action.addon;
|
|
1593
1407
|
label = computed(() => this.addon().label, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1594
1408
|
ariaLabel = computed(() => this.addon().ariaLabel, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
1595
1409
|
icon = computed(() => this.addon().icon, ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
1596
|
-
|
|
1597
|
-
* (Ionic's `medium` would force low-contrast grey, which fails WCAG on dark
|
|
1598
|
-
* surfaces). Consumers can still set `color: 'primary' | 'success' | ...`
|
|
1599
|
-
* explicitly when they want adapter-styled coloring. */
|
|
1600
|
-
color = computed(() => this.addon().color, ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
1410
|
+
color = computed(() => this.addon().color, ...(ngDevMode ? [{ debugName: "color" }] : /* istanbul ignore next */ []));
|
|
1601
1411
|
fill = computed(() => this.addon().fill ?? 'clear', ...(ngDevMode ? [{ debugName: "fill" }] : /* istanbul ignore next */ []));
|
|
1602
|
-
|
|
1603
|
-
* Truthy check on `label` mirrors Material's heuristic; empty-string label
|
|
1604
|
-
* is treated as "no label" so the button doesn't render an invisible text
|
|
1605
|
-
* slot beside the icon. */
|
|
1606
|
-
iconOnly = computed(() => !!this.icon() && !this.label(), ...(ngDevMode ? [{ debugName: "iconOnly" }] : /* istanbul ignore next */ []));
|
|
1412
|
+
iconOnly = computed(() => !!this.icon() && !this.label(), ...(ngDevMode ? [{ debugName: "iconOnly" }] : /* istanbul ignore next */ []));
|
|
1607
1413
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: IonButtonAddonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1608
1414
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: IonButtonAddonComponent, isStandalone: true, selector: "df-ion-button-addon", hostDirectives: [{ directive: i1.NgForgeAddonAction }], ngImport: i0, template: `
|
|
1609
1415
|
<ion-button
|
|
@@ -1659,17 +1465,9 @@ var ionButtonAddon_component = /*#__PURE__*/Object.freeze({
|
|
|
1659
1465
|
IonButtonAddonComponent: IonButtonAddonComponent
|
|
1660
1466
|
});
|
|
1661
1467
|
|
|
1662
|
-
/**
|
|
1663
|
-
* Renderer for the `ion-icon` addon kind.
|
|
1664
|
-
*
|
|
1665
|
-
* Outputs `<ion-icon [name]="icon">`. The host is set `aria-hidden="true"`
|
|
1666
|
-
* by default; if the addon supplies an `ariaLabel`, it is applied so the
|
|
1667
|
-
* icon is announced by screen readers.
|
|
1668
|
-
*/
|
|
1669
1468
|
class IonIconAddonComponent {
|
|
1670
1469
|
addon = input.required(...(ngDevMode ? [{ debugName: "addon" }] : /* istanbul ignore next */ []));
|
|
1671
|
-
|
|
1672
|
-
fieldInputs = input(...(ngDevMode ? [undefined, { debugName: "fieldInputs" }] : /* istanbul ignore next */ []));
|
|
1470
|
+
fieldInputs = input(...(ngDevMode ? [undefined, { debugName: "fieldInputs" }] : /* istanbul ignore next */ []));
|
|
1673
1471
|
iconName = computed(() => this.addon().icon, ...(ngDevMode ? [{ debugName: "iconName" }] : /* istanbul ignore next */ []));
|
|
1674
1472
|
ariaLabel = computed(() => this.addon().ariaLabel, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
1675
1473
|
hasAriaLabel = computed(() => this.addon().ariaLabel !== undefined, ...(ngDevMode ? [{ debugName: "hasAriaLabel" }] : /* istanbul ignore next */ []));
|
|
@@ -1694,11 +1492,7 @@ var ionIconAddon_component = /*#__PURE__*/Object.freeze({
|
|
|
1694
1492
|
IonIconAddonComponent: IonIconAddonComponent
|
|
1695
1493
|
});
|
|
1696
1494
|
|
|
1697
|
-
// Field fields
|
|
1698
1495
|
|
|
1699
|
-
/**
|
|
1700
|
-
* Generated bundle index. Do not edit.
|
|
1701
|
-
*/
|
|
1702
1496
|
|
|
1703
1497
|
export { IONIC_CONFIG, IONIC_FIELD_TYPES, IONIC_INPUT_TYPE_OVERRIDE, IonButtonAddonComponent, IonIconAddonComponent, IonicButtonFieldComponent, IonicCheckboxFieldComponent, IonicDatepickerFieldComponent, IonicField, IonicInputFieldComponent, IonicMultiCheckboxFieldComponent, IonicRadioFieldComponent, IonicSelectFieldComponent, IonicSliderFieldComponent, IonicTextareaFieldComponent, IonicToggleFieldComponent, withIonicAddons, withIonicFields };
|
|
1704
1498
|
//# sourceMappingURL=ng-forge-dynamic-forms-ionic.mjs.map
|