@lvce-editor/settings-view 1.18.0 → 1.20.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.
@@ -914,15 +914,14 @@ const terminate = () => {
914
914
  globalThis.close();
915
915
  };
916
916
 
917
- const isItemModified = (item, preferences) => {
918
- return item.id in preferences;
919
- };
920
- const addModifiedProperty = (items, preferences) => {
921
- return items.map(item => ({
922
- ...item,
923
- modified: isItemModified(item, preferences)
924
- }));
917
+ const filterBySearch = (items, searchValue) => {
918
+ if (!searchValue || !searchValue.trim()) {
919
+ return items;
920
+ }
921
+ const normalizedSearchValue = searchValue.toLowerCase().trim();
922
+ return items.filter(item => item.heading.toLowerCase().includes(normalizedSearchValue));
925
923
  };
924
+
926
925
  const filterByTab = (items, tabs) => {
927
926
  const selectedTab = tabs.find(tab => tab.selected);
928
927
  if (!selectedTab) {
@@ -930,17 +929,36 @@ const filterByTab = (items, tabs) => {
930
929
  }
931
930
  return items.filter(item => item.category === selectedTab.id);
932
931
  };
933
- const filterBySearch = (items, searchValue) => {
934
- if (!searchValue || !searchValue.trim()) {
935
- return items;
936
- }
937
- const normalizedSearchValue = searchValue.toLowerCase().trim();
938
- return items.filter(item => item.heading.toLowerCase().includes(normalizedSearchValue));
932
+
933
+ const isItemModified = (item, preferences) => {
934
+ return item.id in preferences;
939
935
  };
940
- const getFilteredItems = (items, tabs, searchValue = '', preferences) => {
936
+ const validateSettings = (items, modifiedSettings, preferences) => {
937
+ return items.map(item => {
938
+ const value = preferences[item.id] ?? item.value;
939
+ const errorMessage = item.validate ? item.validate(value) : '';
940
+ const hasError = errorMessage.length > 0;
941
+ const modified = isItemModified(item, modifiedSettings);
942
+ return {
943
+ id: item.id,
944
+ heading: item.heading,
945
+ description: item.description,
946
+ type: item.type,
947
+ value: item.value,
948
+ category: item.category,
949
+ options: item.options,
950
+ modified,
951
+ errorMessage,
952
+ hasError
953
+ };
954
+ });
955
+ };
956
+
957
+ const getFilteredItems = (items, tabs, searchValue, modifiedSettings, preferences) => {
941
958
  const tabFilteredItems = filterByTab(items, tabs);
942
- const itemsWithModifiedProperty = addModifiedProperty(tabFilteredItems, preferences);
943
- return filterBySearch(itemsWithModifiedProperty, searchValue);
959
+ const searchFilteredItems = filterBySearch(tabFilteredItems, searchValue);
960
+ const validated = validateSettings(searchFilteredItems, modifiedSettings, preferences);
961
+ return validated;
944
962
  };
945
963
 
946
964
  const User = 1;
@@ -952,10 +970,11 @@ const clear$1 = state => {
952
970
  const {
953
971
  items,
954
972
  tabs,
955
- modifiedSettings
973
+ modifiedSettings,
974
+ preferences
956
975
  } = state;
957
976
  const newSearchValue = '';
958
- const filteredItems = getFilteredItems(items, tabs, newSearchValue, modifiedSettings);
977
+ const filteredItems = getFilteredItems(items, tabs, newSearchValue, modifiedSettings, preferences);
959
978
  return {
960
979
  ...state,
961
980
  filteredItems,
@@ -1065,10 +1084,12 @@ const diff2 = uid => {
1065
1084
  return diffResult;
1066
1085
  };
1067
1086
 
1087
+ const Group = 'group';
1068
1088
  const Tab$1 = 'tab';
1069
1089
  const TabList = 'tablist';
1070
1090
  const AriaRoles = {
1071
1091
  __proto__: null,
1092
+ Group,
1072
1093
  Tab: Tab$1,
1073
1094
  TabList};
1074
1095
  const Viewlet$1 = 'Viewlet';
@@ -1085,7 +1106,7 @@ const KeyCode = {
1085
1106
  const mergeClassNames = (...classNames) => {
1086
1107
  return classNames.filter(Boolean).join(' ');
1087
1108
  };
1088
- const Button$1 = 1;
1109
+ const Button = 1;
1089
1110
  const Div = 4;
1090
1111
  const H1 = 5;
1091
1112
  const Input = 6;
@@ -1100,7 +1121,7 @@ const Label = 66;
1100
1121
  const VirtualDomElements = {
1101
1122
  __proto__: null,
1102
1123
  Aside,
1103
- Button: Button$1,
1124
+ Button,
1104
1125
  Div,
1105
1126
  H1,
1106
1127
  H3,
@@ -1164,10 +1185,11 @@ const handleClickTab = (state, name) => {
1164
1185
  items,
1165
1186
  tabs,
1166
1187
  searchValue,
1167
- modifiedSettings
1188
+ modifiedSettings,
1189
+ preferences
1168
1190
  } = state;
1169
1191
  const updatedTabs = getUpdatedTabs(tabs, name);
1170
- const filteredItems = getFilteredItems(items, updatedTabs, searchValue, modifiedSettings);
1192
+ const filteredItems = getFilteredItems(items, updatedTabs, searchValue, modifiedSettings, preferences);
1171
1193
  return {
1172
1194
  ...state,
1173
1195
  tabs: updatedTabs,
@@ -1241,9 +1263,10 @@ const handleInput = (state, value, inputSource = User) => {
1241
1263
  items,
1242
1264
  tabs,
1243
1265
  history,
1244
- modifiedSettings
1266
+ modifiedSettings,
1267
+ preferences
1245
1268
  } = state;
1246
- const filteredItems = getFilteredItems(items, tabs, value, modifiedSettings);
1269
+ const filteredItems = getFilteredItems(items, tabs, value, modifiedSettings, preferences);
1247
1270
  const {
1248
1271
  newHistory,
1249
1272
  newHistoryIndex
@@ -1283,11 +1306,11 @@ const handleScroll = (state, scrollTop, inputSource = User) => {
1283
1306
  };
1284
1307
  };
1285
1308
 
1286
- const getNewFilteredItems = (oldModifiedSetings, newModifiedSettings, items, tabs, searchValue, oldFilteredItems) => {
1287
- if (oldModifiedSetings === newModifiedSettings) {
1309
+ const getNewFilteredItems = (oldModifiedSetings, newModifiedSettings, items, tabs, searchValue, oldFilteredItems, oldPreferences, newPreferences) => {
1310
+ if (oldModifiedSetings === newModifiedSettings && oldPreferences === newPreferences) {
1288
1311
  return oldFilteredItems;
1289
1312
  }
1290
- return getFilteredItems(items, tabs, searchValue, newModifiedSettings);
1313
+ return getFilteredItems(items, tabs, searchValue, newModifiedSettings, newPreferences);
1291
1314
  };
1292
1315
 
1293
1316
  const getNewModifiedSettings = (modifiedSettings, name) => {
@@ -1314,7 +1337,7 @@ const handleSettingUpdate = (state, name, value, inputSource) => {
1314
1337
  ...preferences,
1315
1338
  [name]: value
1316
1339
  };
1317
- const newFilteredItems = getNewFilteredItems(modifiedSettings, newModifiedSettings, items, tabs, searchValue, filteredItems);
1340
+ const newFilteredItems = getNewFilteredItems(modifiedSettings, newModifiedSettings, items, tabs, searchValue, filteredItems, preferences, newPreferences);
1318
1341
  return {
1319
1342
  ...state,
1320
1343
  inputSource,
@@ -1327,7 +1350,24 @@ const handleSettingChecked = (state, name, value, source = User) => {
1327
1350
  return handleSettingUpdate(state, name, value, source);
1328
1351
  };
1329
1352
 
1353
+ const Enum = 1;
1354
+ const String = 2;
1355
+ const Boolean$1 = 3;
1356
+ const Number$1 = 5;
1357
+ const Color = 6;
1358
+ const Url = 7;
1359
+
1330
1360
  const handleSettingInput = (state, name, value, inputSource = User) => {
1361
+ const {
1362
+ items
1363
+ } = state;
1364
+
1365
+ // TODO maybe have separate input functions for number and string inputs
1366
+ const settingItem = items.find(item => item.id === name);
1367
+ if (settingItem && settingItem.type === Number$1) {
1368
+ const numberValue = value === '' ? '' : Number(value);
1369
+ return handleSettingUpdate(state, name, numberValue, inputSource);
1370
+ }
1331
1371
  return handleSettingUpdate(state, name, value, inputSource);
1332
1372
  };
1333
1373
 
@@ -1434,6 +1474,11 @@ const sendMessagePortToEditorWorker = async (port, rpcId) => {
1434
1474
  // @ts-ignore
1435
1475
  await invokeAndTransfer$3('SendMessagePortToExtensionHostWorker.sendMessagePortToEditorWorker', port, command, rpcId);
1436
1476
  };
1477
+ const sendMessagePortToErrorWorker = async (port, rpcId) => {
1478
+ const command = 'HandleMessagePort.handleMessagePort';
1479
+ // @ts-ignore
1480
+ await invokeAndTransfer$3('SendMessagePortToExtensionHostWorker.sendMessagePortToErrorWorker', port, command, rpcId);
1481
+ };
1437
1482
  const sendMessagePortToMarkdownWorker = async (port, rpcId) => {
1438
1483
  const command = 'Markdown.handleMessagePort';
1439
1484
  // @ts-ignore
@@ -1683,6 +1728,7 @@ const RendererWorker = {
1683
1728
  searchFileHtml,
1684
1729
  searchFileMemory,
1685
1730
  sendMessagePortToEditorWorker,
1731
+ sendMessagePortToErrorWorker,
1686
1732
  sendMessagePortToExtensionHostWorker,
1687
1733
  sendMessagePortToFileSystemWorker,
1688
1734
  sendMessagePortToMarkdownWorker,
@@ -1723,13 +1769,6 @@ const TextEditorTab = 'text-editor';
1723
1769
  const WindowTab = 'window';
1724
1770
  const WorkbenchTab = 'workbench';
1725
1771
 
1726
- const Enum = 1;
1727
- const String = 2;
1728
- const Boolean$1 = 3;
1729
- const Number$1 = 5;
1730
- const Color = 6;
1731
- const Url = 7;
1732
-
1733
1772
  const emptyObject = {};
1734
1773
  const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
1735
1774
  const i18nString = (key, placeholders = emptyObject) => {
@@ -2841,7 +2880,21 @@ const getSettingItemsEditor = () => {
2841
2880
  description: fontSizeDescription(),
2842
2881
  type: Number$1,
2843
2882
  value: 15,
2844
- category: TextEditorTab
2883
+ category: TextEditorTab,
2884
+ validate(value) {
2885
+ if (typeof value !== 'number') {
2886
+ return 'font size must be of type number';
2887
+ }
2888
+ const minFontSize = 10;
2889
+ const maxFontSize = 100;
2890
+ if (value < minFontSize) {
2891
+ return 'font size must be at least 10';
2892
+ }
2893
+ if (value > maxFontSize) {
2894
+ return 'font size must not be greater than 100';
2895
+ }
2896
+ return '';
2897
+ }
2845
2898
  }, {
2846
2899
  id: 'editor.fontFamily',
2847
2900
  heading: fontFamily(),
@@ -2925,7 +2978,21 @@ const getSettingItemsEditor = () => {
2925
2978
  description: tabSizeDescription(),
2926
2979
  type: Number$1,
2927
2980
  value: '4',
2928
- category: TextEditorTab
2981
+ category: TextEditorTab,
2982
+ validate(value) {
2983
+ if (typeof value !== 'number') {
2984
+ return 'font size must be of type number';
2985
+ }
2986
+ const minTabSize = 1;
2987
+ const maxTabSize = 8;
2988
+ if (value < minTabSize) {
2989
+ return `tab size must be at least ${minTabSize}`;
2990
+ }
2991
+ if (value > maxTabSize) {
2992
+ return `tab size must not be greater than ${maxTabSize}`;
2993
+ }
2994
+ return '';
2995
+ }
2929
2996
  }, {
2930
2997
  id: 'editor.insertSpaces',
2931
2998
  heading: insertSpaces(),
@@ -3898,7 +3965,7 @@ const loadContent = async (state, savedState) => {
3898
3965
  const items = await getSettingItems();
3899
3966
  const preferences = await getPreferences();
3900
3967
  const modifiedSettings = getModifiedSettings(preferences);
3901
- const filteredItems = getFilteredItems(items, newTabs, searchValue, modifiedSettings);
3968
+ const filteredItems = getFilteredItems(items, newTabs, searchValue, modifiedSettings, preferences);
3902
3969
  return {
3903
3970
  ...state,
3904
3971
  filteredItems,
@@ -3931,11 +3998,10 @@ const {
3931
3998
  Viewlet
3932
3999
  } = ClassNames;
3933
4000
  const Badge = 'Badge';
3934
- const Button = 'Button';
3935
4001
  const CheckBox = 'CheckBox';
3936
- const Disabled = 'Disabled';
4002
+ const ErrorMessage = 'ErrorMessage';
3937
4003
  const InputBox = 'InputBox';
3938
- const InputButton = 'InputButton';
4004
+ const InputBoxError = 'InputBoxError';
3939
4005
  const MaskIcon = 'MaskIcon';
3940
4006
  const MaskIconClearAll = 'MaskIconClearAll';
3941
4007
  const ModifiedIndicator = 'ModifiedIndicator';
@@ -3979,15 +4045,20 @@ const HandleScroll = 'handleScroll';
3979
4045
  const HandleSettingSelect = 'handleSettingSelect';
3980
4046
  const HandleInputFocus = 'handleInputFocus';
3981
4047
 
3982
- const enabledClass = mergeClassNames(Button, InputButton, SearchFieldButton);
3983
- const disabledClass = mergeClassNames(enabledClass, Disabled);
4048
+ const enabledClass = SearchFieldButton;
4049
+ const disabledClass = mergeClassNames(enabledClass, 'SearchFieldButtonDisabled');
3984
4050
  const getClearButtonClassName = hasSearchValue => {
3985
4051
  if (hasSearchValue) {
3986
- return disabledClass;
4052
+ return enabledClass;
3987
4053
  }
3988
- return enabledClass;
4054
+ return disabledClass;
3989
4055
  };
3990
4056
 
4057
+ const icon = {
4058
+ type: VirtualDomElements.Div,
4059
+ className: mergeClassNames(MaskIcon, MaskIconClearAll),
4060
+ childCount: 0
4061
+ };
3991
4062
  const getSettingsInputButtonsDom = hasSearchValue => {
3992
4063
  return [{
3993
4064
  type: VirtualDomElements.Button,
@@ -3997,18 +4068,14 @@ const getSettingsInputButtonsDom = hasSearchValue => {
3997
4068
  name: Clear$1,
3998
4069
  disabled: !hasSearchValue,
3999
4070
  onClick: HandleClickClear
4000
- }, {
4001
- type: VirtualDomElements.Div,
4002
- className: mergeClassNames(MaskIcon, MaskIconClearAll),
4003
- childCount: 0
4004
- }];
4071
+ }, icon];
4005
4072
  };
4006
4073
 
4007
4074
  const getSettingsInputDom = () => {
4008
4075
  const placeholder = searchSettings();
4009
4076
  return [{
4010
4077
  type: VirtualDomElements.Input,
4011
- className: mergeClassNames(InputBox, SettingsSearchInput),
4078
+ className: mergeClassNames(InputBox, SettingsSearchInput, 'MultilineInputBox'),
4012
4079
  placeholder,
4013
4080
  childCount: 0,
4014
4081
  name: SettingsSearch,
@@ -4017,21 +4084,31 @@ const getSettingsInputDom = () => {
4017
4084
  }];
4018
4085
  };
4019
4086
 
4020
- const getChildCount = hasSearchValue => {
4087
+ const getChildCount$1 = hasSearchValue => {
4021
4088
  return hasSearchValue ? 3 : 2;
4022
4089
  };
4023
4090
  const getSettingsHeaderDom = (filteredSettingsCount, hasSearchValue) => {
4024
- const badgeDom = getSettingsInputBadgeDom(filteredSettingsCount, hasSearchValue);
4025
- const childCount = getChildCount(hasSearchValue);
4091
+ const childCount = getChildCount$1(hasSearchValue);
4026
4092
  return [{
4027
4093
  type: VirtualDomElements.Div,
4028
4094
  className: SettingsHeader,
4029
4095
  childCount: 1
4030
4096
  }, {
4031
4097
  type: VirtualDomElements.Div,
4032
- className: SettingsInputWrapper,
4098
+ className: mergeClassNames(SettingsInputWrapper, 'SearchField'),
4033
4099
  childCount
4034
- }, ...getSettingsInputDom(), ...getSettingsInputButtonsDom(hasSearchValue), ...badgeDom];
4100
+ }, ...getSettingsInputDom(), ...getSettingsInputBadgeDom(filteredSettingsCount, hasSearchValue), ...getSettingsInputButtonsDom(hasSearchValue)];
4101
+ };
4102
+
4103
+ const getErrorMessageDom = errorMessage => {
4104
+ if (!errorMessage) {
4105
+ return [];
4106
+ }
4107
+ return [{
4108
+ type: VirtualDomElements.Div,
4109
+ className: ErrorMessage,
4110
+ childCount: 1
4111
+ }, text(errorMessage)];
4035
4112
  };
4036
4113
 
4037
4114
  const getInputId = id => {
@@ -4043,16 +4120,19 @@ const getItemCheckBoxVirtualDom = item => {
4043
4120
  heading,
4044
4121
  description,
4045
4122
  id,
4046
- modified
4123
+ modified,
4124
+ hasError,
4125
+ errorMessage
4047
4126
  } = item;
4048
- const isModified = modified || false;
4049
4127
  const domId = getInputId(id);
4128
+ const checkBoxClassName = hasError ? `${CheckBox} ${InputBoxError}` : CheckBox;
4129
+ const errorChildCount = hasError ? 1 : 0;
4050
4130
  return [{
4051
4131
  type: VirtualDomElements.Div,
4052
4132
  className: SettingsItem,
4053
- childCount: 3,
4054
- role: 'group',
4055
- 'data-modified': isModified
4133
+ childCount: 3 + errorChildCount,
4134
+ role: AriaRoles.Group,
4135
+ 'data-modified': modified
4056
4136
  }, {
4057
4137
  type: VirtualDomElements.H3,
4058
4138
  childCount: 1
@@ -4062,7 +4142,7 @@ const getItemCheckBoxVirtualDom = item => {
4062
4142
  childCount: 2
4063
4143
  }, {
4064
4144
  type: VirtualDomElements.Input,
4065
- className: CheckBox,
4145
+ className: checkBoxClassName,
4066
4146
  childCount: 0,
4067
4147
  id: domId,
4068
4148
  inputType: 'checkbox',
@@ -4072,7 +4152,7 @@ const getItemCheckBoxVirtualDom = item => {
4072
4152
  type: VirtualDomElements.Label,
4073
4153
  childCount: 1,
4074
4154
  htmlFor: domId
4075
- }, text(description)];
4155
+ }, text(description), ...getErrorMessageDom(errorMessage)];
4076
4156
  };
4077
4157
 
4078
4158
  const parent = {
@@ -4097,30 +4177,33 @@ const getItemColorVirtualDom = item => {
4097
4177
  heading,
4098
4178
  description,
4099
4179
  id,
4100
- modified
4180
+ modified,
4181
+ hasError,
4182
+ errorMessage
4101
4183
  } = item;
4102
4184
  const domId = getInputId(id);
4103
- const isModified = modified || false;
4185
+ const colorInputClassName = hasError ? mergeClassNames('ColorInput', InputBoxError) : mergeClassNames('ColorInput');
4186
+ const errorChildCount = hasError ? 1 : 0;
4104
4187
  return [{
4105
4188
  type: VirtualDomElements.Div,
4106
4189
  className: SettingsItem,
4107
- childCount: 3,
4108
- role: 'group',
4109
- 'data-modified': isModified
4190
+ childCount: 3 + errorChildCount,
4191
+ role: AriaRoles.Group,
4192
+ 'data-modified': modified
4110
4193
  }, ...getItemHeadingDom(heading), {
4111
4194
  type: VirtualDomElements.Div,
4112
4195
  className: SettingsItemCheckBox,
4113
4196
  childCount: 2
4114
4197
  }, {
4115
4198
  type: VirtualDomElements.Input,
4116
- className: mergeClassNames('ColorInput'),
4199
+ className: colorInputClassName,
4117
4200
  inputType: 'color',
4118
4201
  placeholder: colorValue(),
4119
4202
  childCount: 0,
4120
4203
  id: domId,
4121
4204
  name: id,
4122
4205
  onInput: HandleSettingInput
4123
- }, ...getItemLabelDom(domId, description)];
4206
+ }, ...getItemLabelDom(domId, description), ...getErrorMessageDom(errorMessage)];
4124
4207
  };
4125
4208
 
4126
4209
  const getSettingsModifiedIndicatorDom = isModified => {
@@ -4134,32 +4217,46 @@ const getSettingsModifiedIndicatorDom = isModified => {
4134
4217
  }];
4135
4218
  };
4136
4219
 
4220
+ const getChildCount = (modified, hasError) => {
4221
+ const modifiedChildCount = modified ? 1 : 0;
4222
+ const errorChildCount = hasError ? 1 : 0;
4223
+ const childCount = 3 + modifiedChildCount + errorChildCount;
4224
+ return childCount;
4225
+ };
4226
+ const getInputClassName = hasError => {
4227
+ if (hasError) {
4228
+ return `${InputBox} ${InputBoxError}`;
4229
+ }
4230
+ return InputBox;
4231
+ };
4137
4232
  const getItemNumberVirtualDom = item => {
4138
4233
  const {
4139
4234
  heading,
4140
4235
  description,
4141
4236
  id,
4142
- modified
4237
+ modified,
4238
+ hasError,
4239
+ errorMessage
4143
4240
  } = item;
4144
4241
  const domId = getInputId(id);
4145
- const isModified = modified || false;
4146
- const modifiedChildCount = isModified ? 1 : 0;
4242
+ const inputClassName = getInputClassName(hasError);
4243
+ const childCount = getChildCount(modified, hasError);
4147
4244
  return [{
4148
4245
  type: VirtualDomElements.Div,
4149
4246
  className: SettingsItem,
4150
- childCount: 3 + modifiedChildCount,
4151
- role: 'group',
4152
- 'data-modified': isModified
4153
- }, ...getSettingsModifiedIndicatorDom(isModified), ...getItemHeadingDom(heading), ...getItemLabelDom(domId, description), {
4247
+ childCount,
4248
+ role: AriaRoles.Group,
4249
+ 'data-modified': modified
4250
+ }, ...getSettingsModifiedIndicatorDom(modified), ...getItemHeadingDom(heading), ...getItemLabelDom(domId, description), {
4154
4251
  type: VirtualDomElements.Input,
4155
- className: InputBox,
4252
+ className: inputClassName,
4156
4253
  inputType: 'number',
4157
4254
  placeholder: numberValue(),
4158
4255
  childCount: 0,
4159
4256
  id: domId,
4160
4257
  name: id,
4161
4258
  onInput: HandleSettingInput
4162
- }];
4259
+ }, ...getErrorMessageDom(errorMessage)];
4163
4260
  };
4164
4261
 
4165
4262
  const getOptionDom = option => {
@@ -4178,36 +4275,44 @@ const getItemSelectVirtualDom = item => {
4178
4275
  const {
4179
4276
  heading,
4180
4277
  description,
4181
- id
4278
+ id,
4279
+ options,
4280
+ hasError,
4281
+ errorMessage
4182
4282
  } = item;
4183
- const options = item.options || [];
4184
4283
  const domId = getInputId(id);
4284
+ const selectClassName = hasError ? `${Select} ${InputBoxError}` : Select;
4285
+ const errorChildCount = hasError ? 1 : 0;
4185
4286
  return [{
4186
4287
  type: VirtualDomElements.Div,
4187
4288
  className: SettingsItem,
4188
- childCount: 3,
4189
- role: 'group'
4289
+ childCount: 3 + errorChildCount,
4290
+ role: AriaRoles.Group
4190
4291
  }, ...getItemHeadingDom(heading), ...getItemLabelDom(domId, description), {
4191
4292
  type: VirtualDomElements.Select,
4192
- className: Select,
4193
- childCount: options.length,
4293
+ className: selectClassName,
4294
+ childCount: options?.length || 0,
4194
4295
  id: domId,
4195
4296
  name: id,
4196
4297
  onChange: HandleSettingSelect
4197
- }, ...options.flatMap(getOptionDom)];
4298
+ }, ...(options?.flatMap(getOptionDom) || []), ...getErrorMessageDom(errorMessage)];
4198
4299
  };
4199
4300
 
4200
4301
  const getItemStringVirtualDom = item => {
4201
4302
  const {
4202
4303
  heading,
4203
4304
  description,
4204
- id
4305
+ id,
4306
+ hasError,
4307
+ errorMessage
4205
4308
  } = item;
4309
+ const inputClassName = hasError ? `${InputBox} ${InputBoxError}` : InputBox;
4310
+ const errorChildCount = hasError ? 1 : 0;
4206
4311
  return [{
4207
4312
  type: VirtualDomElements.Div,
4208
4313
  className: SettingsItem,
4209
- childCount: 3,
4210
- role: 'group'
4314
+ childCount: 3 + errorChildCount,
4315
+ role: AriaRoles.Group
4211
4316
  }, {
4212
4317
  type: VirtualDomElements.H3,
4213
4318
  childCount: 1
@@ -4216,13 +4321,13 @@ const getItemStringVirtualDom = item => {
4216
4321
  childCount: 1
4217
4322
  }, text(description), {
4218
4323
  type: VirtualDomElements.Input,
4219
- className: InputBox,
4324
+ className: inputClassName,
4220
4325
  inputType: 'text',
4221
4326
  placeholder: stringValue(),
4222
4327
  childCount: 0,
4223
4328
  name: id,
4224
4329
  onInput: HandleSettingInput
4225
- }];
4330
+ }, ...getErrorMessageDom(errorMessage)];
4226
4331
  };
4227
4332
 
4228
4333
  const getItemUnknownVirtualDom = () => {
@@ -4230,7 +4335,7 @@ const getItemUnknownVirtualDom = () => {
4230
4335
  type: VirtualDomElements.Div,
4231
4336
  className: SettingsItem,
4232
4337
  childCount: 1,
4233
- role: 'group'
4338
+ role: AriaRoles.Group
4234
4339
  }, text(unknownSettingType())];
4235
4340
  };
4236
4341
 
@@ -4239,26 +4344,29 @@ const getItemUrlVirtualDom = item => {
4239
4344
  heading,
4240
4345
  description,
4241
4346
  id,
4242
- modified
4347
+ modified,
4348
+ hasError,
4349
+ errorMessage
4243
4350
  } = item;
4244
4351
  const domId = getInputId(id);
4245
- const isModified = modified || false;
4352
+ const inputClassName = hasError ? `${InputBox} ${InputBoxError}` : InputBox;
4353
+ const errorChildCount = hasError ? 1 : 0;
4246
4354
  return [{
4247
4355
  type: VirtualDomElements.Div,
4248
4356
  className: SettingsItem,
4249
- childCount: 3,
4250
- role: 'group',
4251
- 'data-modified': isModified
4357
+ childCount: 3 + errorChildCount,
4358
+ role: AriaRoles.Group,
4359
+ 'data-modified': modified
4252
4360
  }, ...getItemHeadingDom(heading), ...getItemLabelDom(domId, description), {
4253
4361
  type: VirtualDomElements.Input,
4254
- className: InputBox,
4362
+ className: inputClassName,
4255
4363
  inputType: 'url',
4256
4364
  placeholder: numberValue(),
4257
4365
  childCount: 0,
4258
4366
  id: domId,
4259
4367
  name: id,
4260
4368
  onInput: HandleSettingInput
4261
- }];
4369
+ }, ...getErrorMessageDom(errorMessage)];
4262
4370
  };
4263
4371
 
4264
4372
  const getItemVirtualDom = item => {
@@ -4296,7 +4404,7 @@ const getSettingsNoResultsDom = searchValue => {
4296
4404
  };
4297
4405
 
4298
4406
  const getSettingsItemsDom = (items, searchValue) => {
4299
- if (items.length === 0 && searchValue.trim()) {
4407
+ if (items.length === 0 && searchValue && searchValue.trim()) {
4300
4408
  return getSettingsNoResultsDom(searchValue);
4301
4409
  }
4302
4410
  return [{
@@ -4398,13 +4506,17 @@ const enabledTypes = [Number$1, String, Color];
4398
4506
  const renderSettingValues = (oldState, newState) => {
4399
4507
  const {
4400
4508
  filteredItems,
4401
- id
4509
+ id,
4510
+ preferences
4402
4511
  } = newState;
4403
- const numericSettings = filteredItems.filter(item => enabledTypes.includes(item.type));
4404
- const inputValues = numericSettings.map(item => ({
4405
- name: item.id,
4406
- value: item.value
4407
- }));
4512
+ const enabledSettings = filteredItems.filter(item => enabledTypes.includes(item.type));
4513
+ const inputValues = enabledSettings.map(item => {
4514
+ const value = preferences[item.id] || item.value;
4515
+ return {
4516
+ name: item.id,
4517
+ value
4518
+ };
4519
+ });
4408
4520
  return ['Viewlet.setInputValues', id, inputValues];
4409
4521
  };
4410
4522
 
@@ -4516,14 +4628,15 @@ const useNextSearchValue = state => {
4516
4628
  historyIndex,
4517
4629
  items,
4518
4630
  tabs,
4519
- modifiedSettings
4631
+ modifiedSettings,
4632
+ preferences
4520
4633
  } = state;
4521
4634
  if (history.length === 0 || historyIndex >= history.length - 1) {
4522
4635
  return state;
4523
4636
  }
4524
4637
  const newHistoryIndex = historyIndex + 1;
4525
4638
  const newSearchValue = history[newHistoryIndex];
4526
- const filteredItems = getFilteredItems(items, tabs, newSearchValue, modifiedSettings);
4639
+ const filteredItems = getFilteredItems(items, tabs, newSearchValue, modifiedSettings, preferences);
4527
4640
  return {
4528
4641
  ...state,
4529
4642
  searchValue: newSearchValue,
@@ -4539,14 +4652,15 @@ const usePreviousSearchValue = state => {
4539
4652
  historyIndex,
4540
4653
  items,
4541
4654
  tabs,
4542
- modifiedSettings
4655
+ modifiedSettings,
4656
+ preferences
4543
4657
  } = state;
4544
4658
  if (history.length === 0 || historyIndex <= 0) {
4545
4659
  return state;
4546
4660
  }
4547
4661
  const newHistoryIndex = historyIndex - 1;
4548
4662
  const newSearchValue = history[newHistoryIndex];
4549
- const filteredItems = getFilteredItems(items, tabs, newSearchValue, modifiedSettings);
4663
+ const filteredItems = getFilteredItems(items, tabs, newSearchValue, modifiedSettings, preferences);
4550
4664
  return {
4551
4665
  ...state,
4552
4666
  searchValue: newSearchValue,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/settings-view",
3
- "version": "1.18.0",
3
+ "version": "1.20.0",
4
4
  "description": "Explorer Worker",
5
5
  "repository": {
6
6
  "type": "git",