@focus8/settings-registry 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -138,21 +138,18 @@ export const SETTINGS_GROUPS = [
138
138
  id: 'calendarType',
139
139
  labelKey: 'Settings.CalendarType',
140
140
  icon: 'ArrowLeftRight',
141
- keys: ['calendarView.type'],
141
+ keys: ['calendarView.type', 'calendarView.view'],
142
142
  },
143
143
  {
144
144
  id: 'calendarView',
145
145
  labelKey: 'Settings.CalendarView',
146
146
  icon: 'Eye',
147
147
  keys: [
148
- 'calendarView.view',
149
- 'calendarView.dayViewZoom',
150
- 'calendarView.weekViewZoom',
151
- 'calendarView.splitView',
152
148
  'calendarView.showCalendarNames',
149
+ 'calendarView.splitView',
153
150
  'calendarView.calendarColumns',
154
- 'calendarView.autoReturnToTodayEnabled',
155
- 'calendarView.autoReturnToTodayTimeoutSeconds',
151
+ 'calendarView.dayViewZoom',
152
+ 'calendarView.weekViewZoom',
156
153
  ],
157
154
  },
158
155
  {
@@ -197,12 +194,14 @@ export const SETTINGS_GROUPS = [
197
194
  'sound.timerAlarmTimeout',
198
195
  'timer.',
199
196
  ],
197
+ appMode: 'ENROLLED',
200
198
  },
201
199
  {
202
200
  id: 'lockScreen',
203
201
  labelKey: 'Settings.LockScreen',
204
202
  icon: 'Lock',
205
203
  keys: ['lockScreen.'],
204
+ appMode: 'ENROLLED',
206
205
  },
207
206
  {
208
207
  id: 'touch',
@@ -221,7 +220,11 @@ export const SETTINGS_GROUPS = [
221
220
  id: 'device',
222
221
  labelKey: 'SettingsDevices.Title',
223
222
  icon: 'Smartphone',
224
- keys: ['device.'],
223
+ keys: [
224
+ 'device.',
225
+ 'calendarView.autoReturnToTodayEnabled',
226
+ 'calendarView.autoReturnToTodayTimeoutSeconds',
227
+ ],
225
228
  },
226
229
  {
227
230
  id: 'language',
@@ -240,6 +243,223 @@ export const EXCLUDED_DEVICE_SETTINGS = new Set([
240
243
  'device.authWarningDismissTtlDays',
241
244
  'notification.hasBeenPrompted',
242
245
  ]);
246
+ /**
247
+ * Maps each setting key to its i18n label and optional description key.
248
+ * These keys must exist in every consumer's i18n catalog.
249
+ *
250
+ * When a key is missing from this map, consumers should fall back to
251
+ * the auto-generated label from `SettingsRegistry.getSettingLabel()`.
252
+ */
253
+ export const SETTINGS_LABELS = {
254
+ // ── Appearance ──────────────────────────────────────────────────────────
255
+ 'appearance.theme': { labelKey: 'Settings.SelectTheme' },
256
+ 'appearance.clockType': {
257
+ labelKey: 'Settings.ClockType',
258
+ descriptionKey: 'Settings.ClockTypeDescription',
259
+ },
260
+ 'appearance.enableDayColors': {
261
+ labelKey: 'Settings.EnableDayColors',
262
+ descriptionKey: 'Settings.EnableDayColorsDescription',
263
+ },
264
+ // ── Calendar type ───────────────────────────────────────────────────────
265
+ 'calendarView.type': {
266
+ labelKey: 'Settings.CalendarType',
267
+ descriptionKey: 'Settings.ModeDescription',
268
+ },
269
+ 'calendarView.view': { labelKey: 'Settings.Calendar' },
270
+ // ── Calendar view ───────────────────────────────────────────────────────
271
+ 'calendarView.showCalendarNames': { labelKey: 'Settings.ShowCalendarNames' },
272
+ 'calendarView.splitView': {
273
+ labelKey: 'Settings.SplitViewLabel',
274
+ descriptionKey: 'Settings.SplitViewDescription',
275
+ },
276
+ 'calendarView.calendarColumns': {
277
+ labelKey: 'Settings.SplitViewConfig',
278
+ descriptionKey: 'Settings.SplitViewConfigDescription',
279
+ },
280
+ 'calendarView.dayViewZoom': {
281
+ labelKey: 'Settings.CalendarDayViewIntervalTitle',
282
+ descriptionKey: 'Settings.CalendarDayViewIntervalDescription',
283
+ },
284
+ 'calendarView.weekViewZoom': {
285
+ labelKey: 'Settings.CalendarWeekViewIntervalTitle',
286
+ descriptionKey: 'Settings.CalendarWeekViewIntervalDescription',
287
+ },
288
+ // ── Auto return to today ────────────────────────────────────────────────
289
+ 'calendarView.autoReturnToTodayEnabled': {
290
+ labelKey: 'Settings.AutoReturnToTodayEnabled',
291
+ },
292
+ 'calendarView.autoReturnToTodayTimeoutSeconds': {
293
+ labelKey: 'Settings.AutoReturnToTodayTimeout',
294
+ },
295
+ // ── Weather ─────────────────────────────────────────────────────────────
296
+ 'calendarView.weatherLocation': { labelKey: 'Settings.WeatherLocation' },
297
+ 'calendarView.showWeatherOnEvents': {
298
+ labelKey: 'Settings.ShowWeatherOnEvents',
299
+ descriptionKey: 'Settings.ShowWeatherOnEventsDescription',
300
+ },
301
+ 'calendarView.showWeatherOnTimeline': {
302
+ labelKey: 'Settings.ShowWeatherOnTimeline',
303
+ descriptionKey: 'Settings.ShowWeatherOnTimelineDescription',
304
+ },
305
+ // ── Sound & alerts ──────────────────────────────────────────────────────
306
+ 'sound.reminderVolume': {
307
+ labelKey: 'Settings.ReminderVolume',
308
+ descriptionKey: 'Settings.ReminderVolumeDescription',
309
+ },
310
+ 'sound.timerVolume': {
311
+ labelKey: 'Settings.TimerVolume',
312
+ descriptionKey: 'Settings.TimerVolumeDescription',
313
+ },
314
+ 'sound.mediaVolume': {
315
+ labelKey: 'Settings.MediaVolume',
316
+ descriptionKey: 'Settings.MediaVolumeDescription',
317
+ },
318
+ 'sound.alarmSound': { labelKey: 'Settings.AlarmSound' },
319
+ 'sound.reminderAlarmSound': { labelKey: 'Settings.ReminderAlarmAsset' },
320
+ 'sound.reminderAlarmTimeout': { labelKey: 'Settings.ReminderAlarmTimeout' },
321
+ 'sound.timerAlarmSound': { labelKey: 'Settings.TimerAlarmSound' },
322
+ 'sound.timerAlarmTimeout': { labelKey: 'Settings.TimerAlarmTimeout' },
323
+ 'sound.allowCustomReminderSounds': {
324
+ labelKey: 'Settings.AllowCustomReminderSounds',
325
+ },
326
+ 'sound.ttsEnabled': {
327
+ labelKey: 'Settings.EnableSpeech',
328
+ descriptionKey: 'Settings.EnableSpeechDescription',
329
+ },
330
+ 'sound.ttsRate': { labelKey: 'Settings.TtsTitle' },
331
+ // ── Timer ───────────────────────────────────────────────────────────────
332
+ 'timer.showTimeRemaining': { labelKey: 'Settings.TimerShowTimeRemaining' },
333
+ 'timer.showEndTime': { labelKey: 'Settings.TimerShowEndTime' },
334
+ 'timer.showRestartButton': { labelKey: 'Settings.TimerShowRestartButton' },
335
+ 'timer.showPauseButton': { labelKey: 'Settings.TimerShowPauseButton' },
336
+ // ── Lock screen ─────────────────────────────────────────────────────────
337
+ 'lockScreen.pin': { labelKey: 'Settings.LockScreenTitlePin' },
338
+ 'lockScreen.clockDisplay': { labelKey: 'Settings.LockScreenClockTitle' },
339
+ 'lockScreen.showDate': { labelKey: 'Settings.LockScreenShowDate' },
340
+ 'lockScreen.showHourNumbers': {
341
+ labelKey: 'Settings.LockScreenShowHourNumbers',
342
+ },
343
+ 'lockScreen.imageMode': { labelKey: 'Settings.LockScreenImageModeTitle' },
344
+ 'lockScreen.backgroundImage': {
345
+ labelKey: 'Settings.LockScreenImageModeBackground',
346
+ },
347
+ 'lockScreen.photoFrameImages': {
348
+ labelKey: 'Settings.LockScreenImageModePhotoFrame',
349
+ },
350
+ 'lockScreen.photoFrameIntervalSeconds': {
351
+ labelKey: 'Settings.LockScreenPhotoFrameIntervalTitle',
352
+ },
353
+ 'lockScreen.inactivityLockEnabled': {
354
+ labelKey: 'SettingsInactivity.EnableLabel',
355
+ },
356
+ 'lockScreen.inactivityTimeoutMinutes': {
357
+ labelKey: 'SettingsInactivity.TimeoutLabel',
358
+ },
359
+ // ── Touch / gestures ───────────────────────────────────────────────────
360
+ 'touch.enableTapToCreate': {
361
+ labelKey: 'Settings.EnableTapToCreate',
362
+ descriptionKey: 'Settings.EnableTapToCreateDescription',
363
+ },
364
+ 'touch.enableDragDrop': {
365
+ labelKey: 'Settings.EnableDragDrop',
366
+ descriptionKey: 'Settings.EnableDragDropDescription',
367
+ },
368
+ // ── Device ──────────────────────────────────────────────────────────────
369
+ 'device.timePickerMode': { labelKey: 'Settings.DateTimeTitle' },
370
+ // ── Language ────────────────────────────────────────────────────────────
371
+ 'language.locale': { labelKey: 'Settings.SelectLanguage' },
372
+ // ── Notifications ───────────────────────────────────────────────────────
373
+ 'notification.enabled': { labelKey: 'Settings.NotificationsEnabled' },
374
+ 'notification.notifyAllCalendars': {
375
+ labelKey: 'Settings.NotifyAllCalendars',
376
+ },
377
+ 'notification.enabledCalendarIds': {
378
+ labelKey: 'Settings.NotificationsCalendars',
379
+ },
380
+ // ── Chronological header ────────────────────────────────────────────────
381
+ 'chronological.header.showNavigationArrows': {
382
+ labelKey: 'ChronologicalFeatures.NavigationArrows',
383
+ },
384
+ 'chronological.header.showClock': {
385
+ labelKey: 'ChronologicalFeatures.Clock',
386
+ },
387
+ 'chronological.header.showCurrentYearInDate': {
388
+ labelKey: 'ChronologicalFeatures.ShowCurrentYear',
389
+ },
390
+ 'chronological.header.showTimeOfDay': {
391
+ labelKey: 'ChronologicalFeatures.TimeOfDay',
392
+ },
393
+ // ── Chronological footer ────────────────────────────────────────────────
394
+ 'chronological.footer.showMenuButton': {
395
+ labelKey: 'ChronologicalFeatures.MenuButton',
396
+ },
397
+ 'chronological.footer.showViewSwitcherDay': {
398
+ labelKey: 'ChronologicalFeatures.ViewSwitcherDay',
399
+ },
400
+ 'chronological.footer.showViewSwitcherWeek': {
401
+ labelKey: 'ChronologicalFeatures.ViewSwitcherWeek',
402
+ },
403
+ 'chronological.footer.showViewSwitcherMonth': {
404
+ labelKey: 'ChronologicalFeatures.ViewSwitcherMonth',
405
+ },
406
+ 'chronological.footer.showTimerButton': {
407
+ labelKey: 'ChronologicalFeatures.TimerButton',
408
+ },
409
+ 'chronological.footer.showNewEventButton': {
410
+ labelKey: 'ChronologicalFeatures.NewEventButton',
411
+ },
412
+ 'chronological.footer.showSettingsButton': {
413
+ labelKey: 'ChronologicalFeatures.SettingsButton',
414
+ },
415
+ // ── Chronological timer ─────────────────────────────────────────────────
416
+ 'chronological.timer.showNewCountdown': {
417
+ labelKey: 'TimerFeatures.ShowNewCountdown',
418
+ },
419
+ 'chronological.timer.showFromTemplate': {
420
+ labelKey: 'TimerFeatures.ShowFromTemplate',
421
+ },
422
+ 'chronological.timer.showEditTemplate': {
423
+ labelKey: 'TimerFeatures.ShowEditTemplate',
424
+ },
425
+ 'chronological.timer.showDeleteTemplate': {
426
+ labelKey: 'TimerFeatures.ShowDeleteTemplate',
427
+ },
428
+ 'chronological.timer.showAddTemplate': {
429
+ labelKey: 'TimerFeatures.ShowAddTemplate',
430
+ },
431
+ // ── Chronological menu ──────────────────────────────────────────────────
432
+ 'chronological.menu.showSettingsButton': {
433
+ labelKey: 'ChronologicalFeatures.MenuSettingsButton',
434
+ },
435
+ 'chronological.quickSettings.showTimerVolume': {
436
+ labelKey: 'ChronologicalFeatures.QuickSettingsTimerVolume',
437
+ },
438
+ 'chronological.quickSettings.showReminderVolume': {
439
+ labelKey: 'ChronologicalFeatures.QuickSettingsReminderVolume',
440
+ },
441
+ 'chronological.quickSettings.showMediaVolume': {
442
+ labelKey: 'ChronologicalFeatures.QuickSettingsMediaVolume',
443
+ },
444
+ 'chronological.quickSettings.showBrightness': {
445
+ labelKey: 'ChronologicalFeatures.QuickSettingsBrightness',
446
+ },
447
+ 'chronological.quickSettings.showLockScreen': {
448
+ labelKey: 'ChronologicalFeatures.QuickSettingsLockScreen',
449
+ },
450
+ // ── Event form (time-based) ─────────────────────────────────────────────
451
+ 'eventForm.recurrence': { labelKey: 'Calendar.LabelRecurrence' },
452
+ 'eventForm.reminders': { labelKey: 'Calendar.LabelReminders' },
453
+ 'eventForm.emailReminders': { labelKey: 'Calendar.LabelEmailReminders' },
454
+ 'eventForm.location': { labelKey: 'Common.Location' },
455
+ 'eventForm.travelTime': { labelKey: 'TravelTime.Title' },
456
+ 'eventForm.description': { labelKey: 'Common.Description' },
457
+ 'eventForm.checklist': { labelKey: 'EventChecklist.DefaultName' },
458
+ 'eventForm.images': { labelKey: 'EventImageGallery.SectionTitle' },
459
+ 'eventForm.audioClips': { labelKey: 'EventAudioGallery.SectionTitle' },
460
+ 'eventForm.notificationReceivers': { labelKey: 'EventForm.NotificationReceivers' },
461
+ 'eventForm.visibility': { labelKey: 'EventVisibility.Title' },
462
+ };
243
463
  /**
244
464
  * Check whether a setting key matches a group's key matchers.
245
465
  */
@@ -254,9 +474,9 @@ function matchesGroup(key, group) {
254
474
  * buckets them into the standard groups, filtering by calendar type and
255
475
  * excluded keys.
256
476
  */
257
- export function groupSettingsForDevice(allSettings, calendarType) {
258
- // Filter excluded
259
- const settings = allSettings.filter((s) => !EXCLUDED_DEVICE_SETTINGS.has(s.key));
477
+ export function groupSettingsForDevice(allSettings, calendarType, appMode) {
478
+ // Filter excluded and hidden settings
479
+ const settings = allSettings.filter((s) => !EXCLUDED_DEVICE_SETTINGS.has(s.key) && s.uiType !== 'HIDDEN');
260
480
  // Calendar type filtering for event form keys
261
481
  const isChronological = calendarType === 'chronological';
262
482
  const filteredSettings = settings.filter((s) => {
@@ -275,6 +495,10 @@ export function groupSettingsForDevice(allSettings, calendarType) {
275
495
  if (group.calendarType && group.calendarType !== calendarType) {
276
496
  continue;
277
497
  }
498
+ // Skip groups not relevant for current app mode
499
+ if (group.appMode && group.appMode !== appMode) {
500
+ continue;
501
+ }
278
502
  const matched = filteredSettings.filter((s) => !claimed.has(s.key) && matchesGroup(s.key, group));
279
503
  if (matched.length === 0) {
280
504
  continue;
@@ -298,10 +522,51 @@ export const DEFAULT_REGISTRY_CONFIG = {
298
522
  defaultLocale: 'nb',
299
523
  };
300
524
  // ---------------------------------------------------------------------------
525
+ // Shared option arrays (reused across multiple settings)
526
+ // ---------------------------------------------------------------------------
527
+ const ALARM_SOUND_OPTIONS = [
528
+ { value: 'none', labelKey: 'Settings.Option.AlarmSound.None' },
529
+ { value: 'alarm1', labelKey: 'Settings.Option.AlarmSound.Alarm1' },
530
+ { value: 'alarm2', labelKey: 'Settings.Option.AlarmSound.Alarm2' },
531
+ { value: 'alarm3', labelKey: 'Settings.Option.AlarmSound.Alarm3' },
532
+ { value: 'alarm4', labelKey: 'Settings.Option.AlarmSound.Alarm4' },
533
+ { value: 'alarm5', labelKey: 'Settings.Option.AlarmSound.Alarm5' },
534
+ { value: 'alarm6', labelKey: 'Settings.Option.AlarmSound.Alarm6' },
535
+ { value: 'alarm7', labelKey: 'Settings.Option.AlarmSound.Alarm7' },
536
+ { value: 'alarm8', labelKey: 'Settings.Option.AlarmSound.Alarm8' },
537
+ { value: 'alarm9', labelKey: 'Settings.Option.AlarmSound.Alarm9' },
538
+ ];
539
+ const ALARM_TIMEOUT_OPTIONS = [
540
+ { value: 1, labelKey: 'Settings.Option.AlarmTimeout.1min' },
541
+ { value: 2, labelKey: 'Settings.Option.AlarmTimeout.2min' },
542
+ { value: 3, labelKey: 'Settings.Option.AlarmTimeout.3min' },
543
+ { value: 5, labelKey: 'Settings.Option.AlarmTimeout.5min' },
544
+ { value: 10, labelKey: 'Settings.Option.AlarmTimeout.10min' },
545
+ ];
546
+ const DAY_VIEW_ZOOM_OPTIONS = [
547
+ { value: 15, labelKey: 'Settings.Option.DayViewZoom.15min' },
548
+ { value: 30, labelKey: 'Settings.Option.DayViewZoom.30min' },
549
+ { value: 60, labelKey: 'Settings.Option.DayViewZoom.60min' },
550
+ ];
551
+ const TIME_OF_DAY_SLIDER = { min: 0, max: 23, step: 1 };
552
+ // ---------------------------------------------------------------------------
301
553
  // Helper
302
554
  // ---------------------------------------------------------------------------
303
- function def(category, type, defaultValue, sync = true) {
304
- return { category, type, default: defaultValue, sync };
555
+ function def(category, type, defaultValue, uiType, extra) {
556
+ const result = {
557
+ category,
558
+ type,
559
+ default: defaultValue,
560
+ sync: extra?.sync ?? true,
561
+ uiType,
562
+ };
563
+ if (extra?.options) {
564
+ result.options = extra.options;
565
+ }
566
+ if (extra?.sliderConfig) {
567
+ result.sliderConfig = extra.sliderConfig;
568
+ }
569
+ return result;
305
570
  }
306
571
  // ---------------------------------------------------------------------------
307
572
  // Entry builder (internal — used by SettingsRegistry class and factory)
@@ -311,159 +576,276 @@ function buildEntries(config) {
311
576
  // ═══════════════════════════════════════════════════════════════════════
312
577
  // Appearance
313
578
  // ═══════════════════════════════════════════════════════════════════════
314
- 'appearance.theme': def('appearance', 'string', config.defaultTheme),
315
- 'appearance.clockType': def('appearance', 'string', 'digital'),
316
- 'appearance.enableDayColors': def('appearance', 'boolean', false),
579
+ 'appearance.theme': def('appearance', 'string', config.defaultTheme, 'CUSTOM_THEME_PICKER', {
580
+ options: [
581
+ { value: 'light', labelKey: 'Settings.Option.Theme.Light' },
582
+ { value: 'dark', labelKey: 'Settings.Option.Theme.Dark' },
583
+ { value: 'system', labelKey: 'Settings.Option.Theme.System' },
584
+ ],
585
+ }),
586
+ 'appearance.clockType': def('appearance', 'string', 'digital', 'CUSTOM_CLOCK_TYPE', {
587
+ options: [
588
+ { value: 'digital', labelKey: 'Settings.Option.ClockType.Digital' },
589
+ { value: 'analog', labelKey: 'Settings.Option.ClockType.Analog' },
590
+ ],
591
+ }),
592
+ 'appearance.enableDayColors': def('appearance', 'boolean', false, 'TOGGLE'),
317
593
  // ═══════════════════════════════════════════════════════════════════════
318
594
  // Calendar view
319
595
  // ═══════════════════════════════════════════════════════════════════════
320
- 'calendarView.type': def('calendarView', 'string', 'time-based'),
321
- 'calendarView.view': def('calendarView', 'string', 'day'),
322
- 'calendarView.dayViewZoom': def('calendarView', 'number', 60),
323
- 'calendarView.weekViewZoom': def('calendarView', 'number', 60),
324
- 'calendarView.splitView': def('calendarView', 'boolean', false),
325
- 'calendarView.showCalendarNames': def('calendarView', 'boolean', true),
326
- 'calendarView.calendarColumns': def('calendarView', 'json', []),
327
- 'calendarView.autoReturnToTodayEnabled': def('calendarView', 'boolean', config.isEnrolled),
328
- 'calendarView.autoReturnToTodayTimeoutSeconds': def('calendarView', 'number', 300),
329
- 'calendarView.showWeatherOnEvents': def('calendarView', 'boolean', false),
330
- 'calendarView.showWeatherOnTimeline': def('calendarView', 'boolean', false),
331
- 'calendarView.weatherLocation': def('calendarView', 'json', null),
596
+ 'calendarView.type': def('calendarView', 'string', 'time-based', 'CUSTOM_CALENDAR_TYPE', {
597
+ options: [
598
+ {
599
+ value: 'chronological',
600
+ labelKey: 'Settings.Option.CalendarType.Chronological',
601
+ },
602
+ {
603
+ value: 'time-based',
604
+ labelKey: 'Settings.Option.CalendarType.TimeBased',
605
+ },
606
+ ],
607
+ }),
608
+ 'calendarView.view': def('calendarView', 'string', 'day', 'SELECT', {
609
+ options: [
610
+ { value: 'day', labelKey: 'Settings.Option.CalendarView.Day' },
611
+ {
612
+ value: '3-days',
613
+ labelKey: 'Settings.Option.CalendarView.3Days',
614
+ },
615
+ {
616
+ value: '5-days',
617
+ labelKey: 'Settings.Option.CalendarView.5Days',
618
+ },
619
+ {
620
+ value: '7-days',
621
+ labelKey: 'Settings.Option.CalendarView.7Days',
622
+ },
623
+ { value: 'week', labelKey: 'Settings.Option.CalendarView.Week' },
624
+ {
625
+ value: 'month',
626
+ labelKey: 'Settings.Option.CalendarView.Month',
627
+ },
628
+ {
629
+ value: 'overview',
630
+ labelKey: 'Settings.Option.CalendarView.Overview',
631
+ },
632
+ ],
633
+ }),
634
+ 'calendarView.dayViewZoom': def('calendarView', 'number', 60, 'SELECT', { options: DAY_VIEW_ZOOM_OPTIONS }),
635
+ 'calendarView.weekViewZoom': def('calendarView', 'number', 60, 'SELECT', { options: DAY_VIEW_ZOOM_OPTIONS }),
636
+ 'calendarView.splitView': def('calendarView', 'boolean', false, 'TOGGLE'),
637
+ 'calendarView.showCalendarNames': def('calendarView', 'boolean', true, 'TOGGLE'),
638
+ 'calendarView.calendarColumns': def('calendarView', 'json', [], 'CUSTOM_SPLIT_VIEW_CONFIG'),
639
+ 'calendarView.autoReturnToTodayEnabled': def('calendarView', 'boolean', config.isEnrolled, 'TOGGLE'),
640
+ 'calendarView.autoReturnToTodayTimeoutSeconds': def('calendarView', 'number', 300, 'SLIDER', { sliderConfig: { min: 30, max: 600, step: 30 } }),
641
+ 'calendarView.showWeatherOnEvents': def('calendarView', 'boolean', false, 'TOGGLE'),
642
+ 'calendarView.showWeatherOnTimeline': def('calendarView', 'boolean', false, 'TOGGLE'),
643
+ 'calendarView.weatherLocation': def('calendarView', 'json', null, 'CUSTOM_WEATHER_LOCATION'),
332
644
  // ═══════════════════════════════════════════════════════════════════════
333
645
  // Event form field visibility (time-based)
334
646
  // ═══════════════════════════════════════════════════════════════════════
335
- 'eventForm.recurrence': def('eventForm', 'boolean', true),
336
- 'eventForm.reminders': def('eventForm', 'boolean', true),
337
- 'eventForm.emailReminders': def('eventForm', 'boolean', false),
338
- 'eventForm.location': def('eventForm', 'boolean', true),
339
- 'eventForm.travelTime': def('eventForm', 'boolean', false),
340
- 'eventForm.description': def('eventForm', 'boolean', true),
341
- 'eventForm.checklist': def('eventForm', 'boolean', true),
342
- 'eventForm.images': def('eventForm', 'boolean', false),
343
- 'eventForm.audioClips': def('eventForm', 'boolean', false),
344
- 'eventForm.notificationReceivers': def('eventForm', 'boolean', true),
345
- 'eventForm.visibility': def('eventForm', 'boolean', false),
647
+ 'eventForm.recurrence': def('eventForm', 'boolean', true, 'TOGGLE'),
648
+ 'eventForm.reminders': def('eventForm', 'boolean', true, 'TOGGLE'),
649
+ 'eventForm.emailReminders': def('eventForm', 'boolean', false, 'TOGGLE'),
650
+ 'eventForm.location': def('eventForm', 'boolean', true, 'TOGGLE'),
651
+ 'eventForm.travelTime': def('eventForm', 'boolean', false, 'TOGGLE'),
652
+ 'eventForm.description': def('eventForm', 'boolean', true, 'TOGGLE'),
653
+ 'eventForm.checklist': def('eventForm', 'boolean', true, 'TOGGLE'),
654
+ 'eventForm.images': def('eventForm', 'boolean', false, 'TOGGLE'),
655
+ 'eventForm.audioClips': def('eventForm', 'boolean', false, 'TOGGLE'),
656
+ 'eventForm.notificationReceivers': def('eventForm', 'boolean', true, 'TOGGLE'),
657
+ 'eventForm.visibility': def('eventForm', 'boolean', false, 'TOGGLE'),
346
658
  // ═══════════════════════════════════════════════════════════════════════
347
659
  // Sound & alerts
348
660
  // ═══════════════════════════════════════════════════════════════════════
349
- 'sound.timerVolume': def('sound', 'number', 0.5),
350
- 'sound.reminderVolume': def('sound', 'number', 0.5),
351
- 'sound.mediaVolume': def('sound', 'number', 0.5),
352
- 'sound.alarmSound': def('sound', 'string', 'alarm1'),
353
- 'sound.reminderAlarmSound': def('sound', 'string', 'alarm1'),
354
- 'sound.timerAlarmSound': def('sound', 'string', 'alarm1'),
355
- 'sound.timerAlarmTimeout': def('sound', 'number', 3),
356
- 'sound.reminderAlarmTimeout': def('sound', 'number', 3),
357
- 'sound.allowCustomReminderSounds': def('sound', 'boolean', false),
358
- 'sound.ttsEnabled': def('sound', 'boolean', config.isEnrolled),
359
- 'sound.ttsRate': def('sound', 'number', 1.0),
661
+ 'sound.timerVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER'),
662
+ 'sound.reminderVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER'),
663
+ 'sound.mediaVolume': def('sound', 'number', 0.5, 'VOLUME_SLIDER'),
664
+ 'sound.alarmSound': def('sound', 'string', 'alarm1', 'SELECT', { options: ALARM_SOUND_OPTIONS }),
665
+ 'sound.reminderAlarmSound': def('sound', 'string', 'alarm1', 'SELECT', { options: ALARM_SOUND_OPTIONS }),
666
+ 'sound.timerAlarmSound': def('sound', 'string', 'alarm1', 'SELECT', { options: ALARM_SOUND_OPTIONS }),
667
+ 'sound.timerAlarmTimeout': def('sound', 'number', 3, 'SELECT', { options: ALARM_TIMEOUT_OPTIONS }),
668
+ 'sound.reminderAlarmTimeout': def('sound', 'number', 3, 'SELECT', { options: ALARM_TIMEOUT_OPTIONS }),
669
+ 'sound.allowCustomReminderSounds': def('sound', 'boolean', false, 'TOGGLE'),
670
+ 'sound.ttsEnabled': def('sound', 'boolean', config.isEnrolled, 'TOGGLE'),
671
+ 'sound.ttsRate': def('sound', 'number', 1.0, 'SLIDER', { sliderConfig: { min: 0.5, max: 2, step: 0.1 } }),
360
672
  // ═══════════════════════════════════════════════════════════════════════
361
673
  // Timer
362
674
  // ═══════════════════════════════════════════════════════════════════════
363
- 'timer.showTimeRemaining': def('timer', 'boolean', true),
364
- 'timer.showEndTime': def('timer', 'boolean', true),
365
- 'timer.showRestartButton': def('timer', 'boolean', true),
366
- 'timer.showPauseButton': def('timer', 'boolean', true),
675
+ 'timer.showTimeRemaining': def('timer', 'boolean', true, 'TOGGLE'),
676
+ 'timer.showEndTime': def('timer', 'boolean', true, 'TOGGLE'),
677
+ 'timer.showRestartButton': def('timer', 'boolean', true, 'TOGGLE'),
678
+ 'timer.showPauseButton': def('timer', 'boolean', true, 'TOGGLE'),
367
679
  // ═══════════════════════════════════════════════════════════════════════
368
680
  // Lock screen
369
681
  // ═══════════════════════════════════════════════════════════════════════
370
- 'lockScreen.pin': def('lockScreen', 'string', ''),
371
- 'lockScreen.inactivityLockEnabled': def('lockScreen', 'boolean', false),
372
- 'lockScreen.inactivityTimeoutMinutes': def('lockScreen', 'number', 5),
373
- 'lockScreen.clockDisplay': def('lockScreen', 'string', 'digital'),
374
- 'lockScreen.showDate': def('lockScreen', 'boolean', true),
375
- 'lockScreen.showHourNumbers': def('lockScreen', 'boolean', true),
376
- 'lockScreen.imageMode': def('lockScreen', 'string', 'none'),
377
- 'lockScreen.backgroundImage': def('lockScreen', 'json', null),
378
- 'lockScreen.photoFrameImages': def('lockScreen', 'json', []),
379
- 'lockScreen.photoFrameIntervalSeconds': def('lockScreen', 'number', 60),
682
+ 'lockScreen.pin': def('lockScreen', 'string', '', 'PIN_INPUT'),
683
+ 'lockScreen.inactivityLockEnabled': def('lockScreen', 'boolean', false, 'TOGGLE'),
684
+ 'lockScreen.inactivityTimeoutMinutes': def('lockScreen', 'number', 5, 'SELECT', {
685
+ options: [
686
+ { value: 1, labelKey: 'Settings.Option.InactivityTimeout.1min' },
687
+ { value: 5, labelKey: 'Settings.Option.InactivityTimeout.5min' },
688
+ { value: 10, labelKey: 'Settings.Option.InactivityTimeout.10min' },
689
+ { value: 15, labelKey: 'Settings.Option.InactivityTimeout.15min' },
690
+ { value: 30, labelKey: 'Settings.Option.InactivityTimeout.30min' },
691
+ { value: 45, labelKey: 'Settings.Option.InactivityTimeout.45min' },
692
+ ],
693
+ }),
694
+ 'lockScreen.clockDisplay': def('lockScreen', 'string', 'digital', 'SELECT', {
695
+ options: [
696
+ { value: 'none', labelKey: 'Settings.Option.ClockDisplay.None' },
697
+ {
698
+ value: 'digital',
699
+ labelKey: 'Settings.Option.ClockDisplay.Digital',
700
+ },
701
+ {
702
+ value: 'analog',
703
+ labelKey: 'Settings.Option.ClockDisplay.Analog',
704
+ },
705
+ ],
706
+ }),
707
+ 'lockScreen.showDate': def('lockScreen', 'boolean', true, 'TOGGLE'),
708
+ 'lockScreen.showHourNumbers': def('lockScreen', 'boolean', true, 'TOGGLE'),
709
+ 'lockScreen.imageMode': def('lockScreen', 'string', 'none', 'SELECT', {
710
+ options: [
711
+ { value: 'none', labelKey: 'Settings.Option.ImageMode.None' },
712
+ {
713
+ value: 'background',
714
+ labelKey: 'Settings.Option.ImageMode.Background',
715
+ },
716
+ {
717
+ value: 'photoFrame',
718
+ labelKey: 'Settings.Option.ImageMode.PhotoFrame',
719
+ },
720
+ ],
721
+ }),
722
+ 'lockScreen.backgroundImage': def('lockScreen', 'json', null, 'CUSTOM_IMAGE'),
723
+ 'lockScreen.photoFrameImages': def('lockScreen', 'json', [], 'CUSTOM_IMAGE_ARRAY'),
724
+ 'lockScreen.photoFrameIntervalSeconds': def('lockScreen', 'number', 60, 'SELECT', {
725
+ options: [
726
+ { value: 30, labelKey: 'Settings.Option.PhotoFrameInterval.30sec' },
727
+ { value: 60, labelKey: 'Settings.Option.PhotoFrameInterval.1min' },
728
+ { value: 120, labelKey: 'Settings.Option.PhotoFrameInterval.2min' },
729
+ { value: 300, labelKey: 'Settings.Option.PhotoFrameInterval.5min' },
730
+ ],
731
+ }),
380
732
  // ═══════════════════════════════════════════════════════════════════════
381
733
  // Touch / gestures
382
734
  // ═══════════════════════════════════════════════════════════════════════
383
- 'touch.enableTapToCreate': def('touch', 'boolean', false),
384
- 'touch.enableDragDrop': def('touch', 'boolean', false),
735
+ 'touch.enableTapToCreate': def('touch', 'boolean', false, 'TOGGLE'),
736
+ 'touch.enableDragDrop': def('touch', 'boolean', false, 'TOGGLE'),
385
737
  // ═══════════════════════════════════════════════════════════════════════
386
738
  // Device (not synced unless noted)
387
739
  // ═══════════════════════════════════════════════════════════════════════
388
- 'device.id': def('device', 'string', '', false),
389
- 'device.timePickerMode': def('device', 'string', 'dials'),
390
- 'device.devMenuEnabled': def('device', 'boolean', false, false),
391
- 'device.authWarningDismissTtlDays': def('device', 'number', 3, false),
740
+ 'device.id': def('device', 'string', '', 'HIDDEN', { sync: false }),
741
+ 'device.timePickerMode': def('device', 'string', 'dials', 'SELECT', {
742
+ options: [
743
+ { value: 'dials', labelKey: 'Settings.Option.TimePickerMode.Dials' },
744
+ {
745
+ value: 'keypad',
746
+ labelKey: 'Settings.Option.TimePickerMode.Keypad',
747
+ },
748
+ ],
749
+ }),
750
+ 'device.devMenuEnabled': def('device', 'boolean', false, 'HIDDEN', { sync: false }),
751
+ 'device.authWarningDismissTtlDays': def('device', 'number', 3, 'HIDDEN', { sync: false }),
392
752
  // ═══════════════════════════════════════════════════════════════════════
393
753
  // Language
394
754
  // ═══════════════════════════════════════════════════════════════════════
395
- 'language.locale': def('language', 'string', config.defaultLocale),
755
+ 'language.locale': def('language', 'string', config.defaultLocale, 'CUSTOM_LANGUAGE_PICKER', {
756
+ options: [
757
+ { value: 'nb', labelKey: 'Settings.Option.Language.Norwegian' },
758
+ { value: 'en', labelKey: 'Settings.Option.Language.English' },
759
+ ],
760
+ }),
396
761
  // ═══════════════════════════════════════════════════════════════════════
397
762
  // Notifications
398
763
  // ═══════════════════════════════════════════════════════════════════════
399
- 'notification.enabled': def('notification', 'boolean', false),
400
- 'notification.notifyAllCalendars': def('notification', 'boolean', true),
401
- 'notification.enabledCalendarIds': def('notification', 'json', []),
402
- 'notification.hasBeenPrompted': def('notification', 'boolean', false, false),
764
+ 'notification.enabled': def('notification', 'boolean', false, 'TOGGLE'),
765
+ 'notification.notifyAllCalendars': def('notification', 'boolean', true, 'TOGGLE'),
766
+ 'notification.enabledCalendarIds': def('notification', 'json', [], 'CUSTOM_CALENDAR_IDS'),
767
+ 'notification.hasBeenPrompted': def('notification', 'boolean', false, 'HIDDEN', { sync: false }),
403
768
  // ═══════════════════════════════════════════════════════════════════════
404
769
  // Chronological features (header, footer, menu, quick settings, timer)
405
770
  // ═══════════════════════════════════════════════════════════════════════
406
771
  // Header
407
- 'chronological.header.showNavigationArrows': def('chronological', 'boolean', true),
408
- 'chronological.header.showClock': def('chronological', 'boolean', true),
409
- 'chronological.header.showCurrentYearInDate': def('chronological', 'boolean', false),
410
- 'chronological.header.showTimeOfDay': def('chronological', 'boolean', false),
772
+ 'chronological.header.showNavigationArrows': def('chronological', 'boolean', true, 'TOGGLE'),
773
+ 'chronological.header.showClock': def('chronological', 'boolean', true, 'TOGGLE'),
774
+ 'chronological.header.showCurrentYearInDate': def('chronological', 'boolean', false, 'TOGGLE'),
775
+ 'chronological.header.showTimeOfDay': def('chronological', 'boolean', false, 'TOGGLE'),
411
776
  // Footer
412
- 'chronological.footer.showMenuButton': def('chronological', 'boolean', true),
413
- 'chronological.footer.showViewSwitcherDay': def('chronological', 'boolean', true),
414
- 'chronological.footer.showViewSwitcherWeek': def('chronological', 'boolean', true),
415
- 'chronological.footer.showViewSwitcherMonth': def('chronological', 'boolean', true),
416
- 'chronological.footer.showTimerButton': def('chronological', 'boolean', true),
417
- 'chronological.footer.showNewEventButton': def('chronological', 'boolean', true),
418
- 'chronological.footer.showSettingsButton': def('chronological', 'boolean', true),
777
+ 'chronological.footer.showMenuButton': def('chronological', 'boolean', true, 'TOGGLE'),
778
+ 'chronological.footer.showViewSwitcherDay': def('chronological', 'boolean', true, 'TOGGLE'),
779
+ 'chronological.footer.showViewSwitcherWeek': def('chronological', 'boolean', true, 'TOGGLE'),
780
+ 'chronological.footer.showViewSwitcherMonth': def('chronological', 'boolean', true, 'TOGGLE'),
781
+ 'chronological.footer.showTimerButton': def('chronological', 'boolean', true, 'TOGGLE'),
782
+ 'chronological.footer.showNewEventButton': def('chronological', 'boolean', true, 'TOGGLE'),
783
+ 'chronological.footer.showSettingsButton': def('chronological', 'boolean', true, 'TOGGLE'),
419
784
  // Timer features
420
- 'chronological.timer.showNewCountdown': def('chronological', 'boolean', true),
421
- 'chronological.timer.showFromTemplate': def('chronological', 'boolean', true),
422
- 'chronological.timer.showEditTemplate': def('chronological', 'boolean', true),
423
- 'chronological.timer.showDeleteTemplate': def('chronological', 'boolean', true),
424
- 'chronological.timer.showAddTemplate': def('chronological', 'boolean', true),
785
+ 'chronological.timer.showNewCountdown': def('chronological', 'boolean', true, 'TOGGLE'),
786
+ 'chronological.timer.showFromTemplate': def('chronological', 'boolean', true, 'TOGGLE'),
787
+ 'chronological.timer.showEditTemplate': def('chronological', 'boolean', true, 'TOGGLE'),
788
+ 'chronological.timer.showDeleteTemplate': def('chronological', 'boolean', true, 'TOGGLE'),
789
+ 'chronological.timer.showAddTemplate': def('chronological', 'boolean', true, 'TOGGLE'),
425
790
  // Menu
426
- 'chronological.menu.showSettingsButton': def('chronological', 'boolean', true),
791
+ 'chronological.menu.showSettingsButton': def('chronological', 'boolean', true, 'TOGGLE'),
427
792
  // Quick settings
428
- 'chronological.quickSettings.showTimerVolume': def('chronological', 'boolean', true),
429
- 'chronological.quickSettings.showReminderVolume': def('chronological', 'boolean', true),
430
- 'chronological.quickSettings.showMediaVolume': def('chronological', 'boolean', true),
431
- 'chronological.quickSettings.showBrightness': def('chronological', 'boolean', true),
432
- 'chronological.quickSettings.showLockScreen': def('chronological', 'boolean', true),
793
+ 'chronological.quickSettings.showTimerVolume': def('chronological', 'boolean', true, 'TOGGLE'),
794
+ 'chronological.quickSettings.showReminderVolume': def('chronological', 'boolean', true, 'TOGGLE'),
795
+ 'chronological.quickSettings.showMediaVolume': def('chronological', 'boolean', true, 'TOGGLE'),
796
+ 'chronological.quickSettings.showBrightness': def('chronological', 'boolean', true, 'TOGGLE'),
797
+ 'chronological.quickSettings.showLockScreen': def('chronological', 'boolean', true, 'TOGGLE'),
433
798
  // Time-of-day periods
434
- 'chronological.timeOfDay.morningStart': def('chronological', 'number', 6),
435
- 'chronological.timeOfDay.forenoonStart': def('chronological', 'number', 9),
436
- 'chronological.timeOfDay.afternoonStart': def('chronological', 'number', 12),
437
- 'chronological.timeOfDay.eveningStart': def('chronological', 'number', 18),
438
- 'chronological.timeOfDay.nightStart': def('chronological', 'number', 0),
799
+ 'chronological.timeOfDay.morningStart': def('chronological', 'number', 6, 'SLIDER', { sliderConfig: TIME_OF_DAY_SLIDER }),
800
+ 'chronological.timeOfDay.forenoonStart': def('chronological', 'number', 9, 'SLIDER', { sliderConfig: TIME_OF_DAY_SLIDER }),
801
+ 'chronological.timeOfDay.afternoonStart': def('chronological', 'number', 12, 'SLIDER', { sliderConfig: TIME_OF_DAY_SLIDER }),
802
+ 'chronological.timeOfDay.eveningStart': def('chronological', 'number', 18, 'SLIDER', { sliderConfig: TIME_OF_DAY_SLIDER }),
803
+ 'chronological.timeOfDay.nightStart': def('chronological', 'number', 0, 'SLIDER', { sliderConfig: TIME_OF_DAY_SLIDER }),
439
804
  // ═══════════════════════════════════════════════════════════════════════
440
805
  // Chronological event form
441
806
  // ═══════════════════════════════════════════════════════════════════════
442
807
  // Toggleable fields
443
- 'chronologicalEventForm.field.description': def('chronologicalEventForm', 'boolean', true),
444
- 'chronologicalEventForm.field.recurrence': def('chronologicalEventForm', 'boolean', true),
445
- 'chronologicalEventForm.field.acknowledge': def('chronologicalEventForm', 'boolean', true),
446
- 'chronologicalEventForm.field.checklist': def('chronologicalEventForm', 'boolean', true),
447
- 'chronologicalEventForm.field.extraImages': def('chronologicalEventForm', 'boolean', true),
448
- 'chronologicalEventForm.field.reminders': def('chronologicalEventForm', 'boolean', true),
449
- 'chronologicalEventForm.field.audioClips': def('chronologicalEventForm', 'boolean', true),
808
+ 'chronologicalEventForm.field.description': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
809
+ 'chronologicalEventForm.field.recurrence': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
810
+ 'chronologicalEventForm.field.acknowledge': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
811
+ 'chronologicalEventForm.field.checklist': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
812
+ 'chronologicalEventForm.field.extraImages': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
813
+ 'chronologicalEventForm.field.reminders': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
814
+ 'chronologicalEventForm.field.audioClips': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
450
815
  // Fixed fields
451
- 'chronologicalEventForm.fixedField.allDay': def('chronologicalEventForm', 'boolean', true),
452
- 'chronologicalEventForm.fixedField.endTime': def('chronologicalEventForm', 'boolean', true),
453
- 'chronologicalEventForm.fixedField.visibility': def('chronologicalEventForm', 'boolean', true),
816
+ 'chronologicalEventForm.fixedField.allDay': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
817
+ 'chronologicalEventForm.fixedField.endTime': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
818
+ 'chronologicalEventForm.fixedField.visibility': def('chronologicalEventForm', 'boolean', true, 'TOGGLE'),
454
819
  // Suggest end time
455
- 'chronologicalEventForm.suggestEndTime.enabled': def('chronologicalEventForm', 'boolean', false),
456
- 'chronologicalEventForm.suggestEndTime.value': def('chronologicalEventForm', 'number', 30),
457
- 'chronologicalEventForm.suggestEndTime.unit': def('chronologicalEventForm', 'string', 'minutes'),
820
+ 'chronologicalEventForm.suggestEndTime.enabled': def('chronologicalEventForm', 'boolean', false, 'TOGGLE'),
821
+ 'chronologicalEventForm.suggestEndTime.value': def('chronologicalEventForm', 'number', 30, 'SLIDER', { sliderConfig: { min: 5, max: 480, step: 5 } }),
822
+ 'chronologicalEventForm.suggestEndTime.unit': def('chronologicalEventForm', 'string', 'minutes', 'SELECT', {
823
+ options: [
824
+ {
825
+ value: 'minutes',
826
+ labelKey: 'Settings.Option.SuggestEndTimeUnit.Minutes',
827
+ },
828
+ {
829
+ value: 'hours',
830
+ labelKey: 'Settings.Option.SuggestEndTimeUnit.Hours',
831
+ },
832
+ ],
833
+ }),
458
834
  // Default visibility
459
- 'chronologicalEventForm.defaultVisibility': def('chronologicalEventForm', 'string', 'Private'),
835
+ 'chronologicalEventForm.defaultVisibility': def('chronologicalEventForm', 'string', 'Private', 'SELECT', {
836
+ options: [
837
+ { value: 'Public', labelKey: 'Settings.Option.Visibility.Public' },
838
+ { value: 'Private', labelKey: 'Settings.Option.Visibility.Private' },
839
+ { value: 'Custom', labelKey: 'Settings.Option.Visibility.Custom' },
840
+ ],
841
+ }),
460
842
  // Reminder presets
461
- 'chronologicalEventForm.reminderPresets.timed': def('chronologicalEventForm', 'json', [5, 15, 30, 60, 120, 1440]),
843
+ 'chronologicalEventForm.reminderPresets.timed': def('chronologicalEventForm', 'json', [5, 15, 30, 60, 120, 1440], 'CUSTOM_REMINDER_PRESETS'),
462
844
  'chronologicalEventForm.reminderPresets.allDay': def('chronologicalEventForm', 'json', [
463
845
  { daysBefore: 0, time: '09:00' },
464
846
  { daysBefore: 1, time: '18:00' },
465
847
  { daysBefore: 2, time: '09:00' },
466
- ]),
848
+ ], 'CUSTOM_REMINDER_PRESETS'),
467
849
  };
468
850
  }
469
851
  // ---------------------------------------------------------------------------
@@ -606,11 +988,20 @@ export function parseSettingsSnapshot(json, calendarType, registry = defaultRegi
606
988
  if (!groups.has(category)) {
607
989
  groups.set(category, []);
608
990
  }
991
+ const labelDef = SETTINGS_LABELS[key];
992
+ const entryDef = key in registry.entries
993
+ ? registry.entries[key]
994
+ : undefined;
609
995
  groups.get(category).push({
610
996
  key,
611
997
  name,
612
998
  label: registry.getSettingLabel(key),
999
+ labelKey: labelDef?.labelKey,
1000
+ descriptionKey: labelDef?.descriptionKey,
613
1001
  value,
1002
+ uiType: entryDef?.uiType ?? 'TEXT_INPUT',
1003
+ ...(entryDef?.options && { options: entryDef.options }),
1004
+ ...(entryDef?.sliderConfig && { sliderConfig: entryDef.sliderConfig }),
614
1005
  });
615
1006
  }
616
1007
  // Determine which categories to show