@lvce-editor/settings-view 1.19.0 → 1.21.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.
@@ -477,7 +477,8 @@ const splitLines = lines => {
477
477
  return lines.split(NewLine);
478
478
  };
479
479
  const getCurrentStack = () => {
480
- const currentStack = joinLines(splitLines(new Error().stack || '').slice(2));
480
+ const stackLinesToSkip = 3;
481
+ const currentStack = joinLines(splitLines(new Error().stack || '').slice(stackLinesToSkip));
481
482
  return currentStack;
482
483
  };
483
484
  const getNewLineIndex = (string, startIndex = undefined) => {
@@ -748,6 +749,12 @@ const invokeAndTransfer = (ipc, method, ...params) => {
748
749
  return invokeHelper(ipc, method, params, true);
749
750
  };
750
751
 
752
+ class CommandNotFoundError extends Error {
753
+ constructor(command) {
754
+ super(`Command not found ${command}`);
755
+ this.name = 'CommandNotFoundError';
756
+ }
757
+ }
751
758
  const commands = Object.create(null);
752
759
  const register = commandMap => {
753
760
  Object.assign(commands, commandMap);
@@ -758,7 +765,7 @@ const getCommand = key => {
758
765
  const execute = (command, ...args) => {
759
766
  const fn = getCommand(command);
760
767
  if (!fn) {
761
- throw new Error(`command not found ${command}`);
768
+ throw new CommandNotFoundError(command);
762
769
  }
763
770
  return fn(...args);
764
771
  };
@@ -914,15 +921,14 @@ const terminate = () => {
914
921
  globalThis.close();
915
922
  };
916
923
 
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
- }));
924
+ const filterBySearch = (items, searchValue) => {
925
+ if (!searchValue || !searchValue.trim()) {
926
+ return items;
927
+ }
928
+ const normalizedSearchValue = searchValue.toLowerCase().trim();
929
+ return items.filter(item => item.heading.toLowerCase().includes(normalizedSearchValue));
925
930
  };
931
+
926
932
  const filterByTab = (items, tabs) => {
927
933
  const selectedTab = tabs.find(tab => tab.selected);
928
934
  if (!selectedTab) {
@@ -930,17 +936,37 @@ const filterByTab = (items, tabs) => {
930
936
  }
931
937
  return items.filter(item => item.category === selectedTab.id);
932
938
  };
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));
939
+
940
+ const isItemModified = (item, preferences) => {
941
+ return item.id in preferences;
939
942
  };
940
- const getFilteredItems = (items, tabs, searchValue = '', preferences) => {
943
+
944
+ const validateSettings = (items, modifiedSettings, preferences) => {
945
+ return items.map(item => {
946
+ const value = preferences[item.id] ?? item.value;
947
+ const errorMessage = item.validate ? item.validate(value) : '';
948
+ const hasError = errorMessage.length > 0;
949
+ const modified = isItemModified(item, modifiedSettings);
950
+ return {
951
+ id: item.id,
952
+ heading: item.heading,
953
+ description: item.description,
954
+ type: item.type,
955
+ value: item.value,
956
+ category: item.category,
957
+ options: item.options,
958
+ modified,
959
+ errorMessage,
960
+ hasError
961
+ };
962
+ });
963
+ };
964
+
965
+ const getFilteredItems = (items, tabs, searchValue, modifiedSettings, preferences) => {
941
966
  const tabFilteredItems = filterByTab(items, tabs);
942
- const itemsWithModifiedProperty = addModifiedProperty(tabFilteredItems, preferences);
943
- return filterBySearch(itemsWithModifiedProperty, searchValue);
967
+ const searchFilteredItems = filterBySearch(tabFilteredItems, searchValue);
968
+ const validated = validateSettings(searchFilteredItems, modifiedSettings, preferences);
969
+ return validated;
944
970
  };
945
971
 
946
972
  const User = 1;
@@ -952,10 +978,11 @@ const clear$1 = state => {
952
978
  const {
953
979
  items,
954
980
  tabs,
955
- modifiedSettings
981
+ modifiedSettings,
982
+ preferences
956
983
  } = state;
957
984
  const newSearchValue = '';
958
- const filteredItems = getFilteredItems(items, tabs, newSearchValue, modifiedSettings);
985
+ const filteredItems = getFilteredItems(items, tabs, newSearchValue, modifiedSettings, preferences);
959
986
  return {
960
987
  ...state,
961
988
  filteredItems,
@@ -994,6 +1021,8 @@ const create$1 = (id, uri, x, y, width, height) => {
994
1021
  y,
995
1022
  width,
996
1023
  height,
1024
+ deltaY: 0,
1025
+ itemHeight: 100,
997
1026
  tabs: [],
998
1027
  items: [],
999
1028
  searchValue: '',
@@ -1001,11 +1030,18 @@ const create$1 = (id, uri, x, y, width, height) => {
1001
1030
  preferences: {},
1002
1031
  inputSource: 0,
1003
1032
  scrollOffset: 0,
1033
+ minLineY: 0,
1034
+ maxLineY: 0,
1035
+ visibleItems: [],
1004
1036
  filteredItemsCount: 0,
1005
1037
  history: [],
1006
1038
  historyIndex: -1,
1007
1039
  modifiedSettings: {},
1008
- focusSource: 0
1040
+ focusSource: 0,
1041
+ scrollBarMinHeight: 0,
1042
+ scrollBarThumbHeight: 0,
1043
+ scrollBarThumbTop: 0,
1044
+ highlightsEnabled: false
1009
1045
  };
1010
1046
  set$1(id, state, state);
1011
1047
  };
@@ -1015,7 +1051,7 @@ const isEqual$4 = (oldState, newState) => {
1015
1051
  };
1016
1052
 
1017
1053
  const isEqual$3 = (oldState, newState) => {
1018
- return oldState.filteredItems === newState.filteredItems;
1054
+ return oldState.filteredItems === newState.filteredItems && oldState.deltaY === newState.deltaY;
1019
1055
  };
1020
1056
 
1021
1057
  const isEqual$2 = (oldState, newState) => {
@@ -1065,10 +1101,12 @@ const diff2 = uid => {
1065
1101
  return diffResult;
1066
1102
  };
1067
1103
 
1104
+ const Group = 'group';
1068
1105
  const Tab$1 = 'tab';
1069
1106
  const TabList = 'tablist';
1070
1107
  const AriaRoles = {
1071
1108
  __proto__: null,
1109
+ Group,
1072
1110
  Tab: Tab$1,
1073
1111
  TabList};
1074
1112
  const Viewlet$1 = 'Viewlet';
@@ -1096,7 +1134,7 @@ const P = 50;
1096
1134
  const Ul = 60;
1097
1135
  const Select$1 = 63;
1098
1136
  const Option = 64;
1099
- const Label = 66;
1137
+ const Label$1 = 66;
1100
1138
  const VirtualDomElements = {
1101
1139
  __proto__: null,
1102
1140
  Aside,
@@ -1105,7 +1143,7 @@ const VirtualDomElements = {
1105
1143
  H1,
1106
1144
  H3,
1107
1145
  Input,
1108
- Label,
1146
+ Label: Label$1,
1109
1147
  Option,
1110
1148
  P,
1111
1149
  Select: Select$1,
@@ -1164,10 +1202,11 @@ const handleClickTab = (state, name) => {
1164
1202
  items,
1165
1203
  tabs,
1166
1204
  searchValue,
1167
- modifiedSettings
1205
+ modifiedSettings,
1206
+ preferences
1168
1207
  } = state;
1169
1208
  const updatedTabs = getUpdatedTabs(tabs, name);
1170
- const filteredItems = getFilteredItems(items, updatedTabs, searchValue, modifiedSettings);
1209
+ const filteredItems = getFilteredItems(items, updatedTabs, searchValue, modifiedSettings, preferences);
1171
1210
  return {
1172
1211
  ...state,
1173
1212
  tabs: updatedTabs,
@@ -1241,9 +1280,10 @@ const handleInput = (state, value, inputSource = User) => {
1241
1280
  items,
1242
1281
  tabs,
1243
1282
  history,
1244
- modifiedSettings
1283
+ modifiedSettings,
1284
+ preferences
1245
1285
  } = state;
1246
- const filteredItems = getFilteredItems(items, tabs, value, modifiedSettings);
1286
+ const filteredItems = getFilteredItems(items, tabs, value, modifiedSettings, preferences);
1247
1287
  const {
1248
1288
  newHistory,
1249
1289
  newHistoryIndex
@@ -1283,11 +1323,11 @@ const handleScroll = (state, scrollTop, inputSource = User) => {
1283
1323
  };
1284
1324
  };
1285
1325
 
1286
- const getNewFilteredItems = (oldModifiedSetings, newModifiedSettings, items, tabs, searchValue, oldFilteredItems) => {
1287
- if (oldModifiedSetings === newModifiedSettings) {
1326
+ const getNewFilteredItems = (oldModifiedSetings, newModifiedSettings, items, tabs, searchValue, oldFilteredItems, oldPreferences, newPreferences) => {
1327
+ if (oldModifiedSetings === newModifiedSettings && oldPreferences === newPreferences) {
1288
1328
  return oldFilteredItems;
1289
1329
  }
1290
- return getFilteredItems(items, tabs, searchValue, newModifiedSettings);
1330
+ return getFilteredItems(items, tabs, searchValue, newModifiedSettings, newPreferences);
1291
1331
  };
1292
1332
 
1293
1333
  const getNewModifiedSettings = (modifiedSettings, name) => {
@@ -1314,7 +1354,7 @@ const handleSettingUpdate = (state, name, value, inputSource) => {
1314
1354
  ...preferences,
1315
1355
  [name]: value
1316
1356
  };
1317
- const newFilteredItems = getNewFilteredItems(modifiedSettings, newModifiedSettings, items, tabs, searchValue, filteredItems);
1357
+ const newFilteredItems = getNewFilteredItems(modifiedSettings, newModifiedSettings, items, tabs, searchValue, filteredItems, preferences, newPreferences);
1318
1358
  return {
1319
1359
  ...state,
1320
1360
  inputSource,
@@ -1352,6 +1392,88 @@ const handleSettingSelect = (state, name, value, source = User) => {
1352
1392
  return handleSettingUpdate(state, name, value, source);
1353
1393
  };
1354
1394
 
1395
+ const clamp = (value, min, max) => {
1396
+ if (Number.isNaN(value)) {
1397
+ return min;
1398
+ }
1399
+ if (max < min) {
1400
+ return min;
1401
+ }
1402
+ if (value < min) {
1403
+ return min;
1404
+ }
1405
+ if (value > max) {
1406
+ return max;
1407
+ }
1408
+ return value;
1409
+ };
1410
+
1411
+ const computeScrollBar = (height, totalItemCount, itemHeight, scrollOffset, scrollBarMinHeight) => {
1412
+ const totalHeight = totalItemCount * itemHeight;
1413
+ const scrollable = Math.max(0, totalHeight - height);
1414
+ const thumbTrack = Math.max(0, height);
1415
+ const thumbHeight = totalHeight > 0 ? Math.max(scrollBarMinHeight, Math.floor(height / Math.max(totalHeight, 1) * height)) : height;
1416
+ const thumbMaxTop = Math.max(0, thumbTrack - thumbHeight);
1417
+ const thumbTop = scrollable > 0 ? Math.min(thumbMaxTop, Math.floor(scrollOffset / scrollable * thumbMaxTop)) : 0;
1418
+ return {
1419
+ thumbHeight,
1420
+ thumbTop
1421
+ };
1422
+ };
1423
+
1424
+ const computeVisibleItems = (items, height, scrollOffset, itemHeight) => {
1425
+ const safeItemHeight = itemHeight <= 0 ? 1 : itemHeight;
1426
+ const totalItems = items.length;
1427
+ const minLineY = Math.max(0, Math.floor(scrollOffset / safeItemHeight));
1428
+ const itemsPerViewport = Math.max(1, Math.ceil(height / safeItemHeight));
1429
+ const maxLineY = Math.min(totalItems, minLineY + itemsPerViewport);
1430
+ const visibleItems = items.slice(minLineY, maxLineY);
1431
+ return {
1432
+ visibleItems,
1433
+ minLineY,
1434
+ maxLineY
1435
+ };
1436
+ };
1437
+
1438
+ const handleWheel = (state, eventDeltaY, inputSource = User) => {
1439
+ const {
1440
+ deltaY: deltaY,
1441
+ filteredItems,
1442
+ height,
1443
+ itemHeight = 1
1444
+ } = state;
1445
+ const itemCount = filteredItems.length;
1446
+ const stepLimit = itemCount === 0 ? 10 : Number.POSITIVE_INFINITY;
1447
+ const limitedEventDelta = Math.max(-stepLimit, Math.min(stepLimit, eventDeltaY));
1448
+ const total = deltaY + limitedEventDelta;
1449
+ const max = itemCount === 0 ? Number.POSITIVE_INFINITY : Math.max(0, itemCount * itemHeight);
1450
+ const clampedDeltaY = clamp(total, 0, max);
1451
+ const scrollOffset = clampedDeltaY;
1452
+ const {
1453
+ visibleItems,
1454
+ minLineY,
1455
+ maxLineY
1456
+ } = computeVisibleItems(filteredItems, height, scrollOffset, itemHeight);
1457
+ const {
1458
+ scrollBarMinHeight
1459
+ } = state;
1460
+ const {
1461
+ thumbHeight,
1462
+ thumbTop
1463
+ } = computeScrollBar(height, filteredItems.length, itemHeight, scrollOffset, scrollBarMinHeight);
1464
+ return {
1465
+ ...state,
1466
+ deltaY: clampedDeltaY,
1467
+ scrollOffset,
1468
+ visibleItems,
1469
+ minLineY,
1470
+ maxLineY,
1471
+ inputSource,
1472
+ scrollBarThumbHeight: thumbHeight,
1473
+ scrollBarThumbTop: thumbTop
1474
+ };
1475
+ };
1476
+
1355
1477
  const initialize = async () => {
1356
1478
  // TODO
1357
1479
  };
@@ -1451,6 +1573,11 @@ const sendMessagePortToEditorWorker = async (port, rpcId) => {
1451
1573
  // @ts-ignore
1452
1574
  await invokeAndTransfer$3('SendMessagePortToExtensionHostWorker.sendMessagePortToEditorWorker', port, command, rpcId);
1453
1575
  };
1576
+ const sendMessagePortToErrorWorker = async (port, rpcId) => {
1577
+ const command = 'Errors.handleMessagePort';
1578
+ // @ts-ignore
1579
+ await invokeAndTransfer$3('SendMessagePortToExtensionHostWorker.sendMessagePortToErrorWorker', port, command, rpcId);
1580
+ };
1454
1581
  const sendMessagePortToMarkdownWorker = async (port, rpcId) => {
1455
1582
  const command = 'Markdown.handleMessagePort';
1456
1583
  // @ts-ignore
@@ -1646,6 +1773,14 @@ const getAllPreferences = async () => {
1646
1773
  // @ts-ignore
1647
1774
  return invoke$3('Preferences.getAll');
1648
1775
  };
1776
+ const showSaveFilePicker = async () => {
1777
+ // @ts-ignore
1778
+ return invoke$3('FilePicker.showSaveFilePicker');
1779
+ };
1780
+ const getLogsDir = async () => {
1781
+ // @ts-ignore
1782
+ return invoke$3('PlatformPaths.getLogsDir');
1783
+ };
1649
1784
  const RendererWorker = {
1650
1785
  __proto__: null,
1651
1786
  activateByEvent,
@@ -1671,6 +1806,7 @@ const RendererWorker = {
1671
1806
  getFolderSize,
1672
1807
  getIcons,
1673
1808
  getKeyBindings,
1809
+ getLogsDir,
1674
1810
  getMarkdownDom,
1675
1811
  getNodeVersion,
1676
1812
  getPreference,
@@ -1700,6 +1836,7 @@ const RendererWorker = {
1700
1836
  searchFileHtml,
1701
1837
  searchFileMemory,
1702
1838
  sendMessagePortToEditorWorker,
1839
+ sendMessagePortToErrorWorker,
1703
1840
  sendMessagePortToExtensionHostWorker,
1704
1841
  sendMessagePortToFileSystemWorker,
1705
1842
  sendMessagePortToMarkdownWorker,
@@ -1716,6 +1853,7 @@ const RendererWorker = {
1716
1853
  showContextMenu,
1717
1854
  showErrorDialog,
1718
1855
  showMessageBox,
1856
+ showSaveFilePicker,
1719
1857
  uninstallExtension,
1720
1858
  unregisterWebViewInterceptor,
1721
1859
  writeClipBoardImage,
@@ -2851,7 +2989,21 @@ const getSettingItemsEditor = () => {
2851
2989
  description: fontSizeDescription(),
2852
2990
  type: Number$1,
2853
2991
  value: 15,
2854
- category: TextEditorTab
2992
+ category: TextEditorTab,
2993
+ validate(value) {
2994
+ if (typeof value !== 'number') {
2995
+ return 'font size must be of type number';
2996
+ }
2997
+ const minFontSize = 10;
2998
+ const maxFontSize = 100;
2999
+ if (value < minFontSize) {
3000
+ return 'font size must be at least 10';
3001
+ }
3002
+ if (value > maxFontSize) {
3003
+ return 'font size must not be greater than 100';
3004
+ }
3005
+ return '';
3006
+ }
2855
3007
  }, {
2856
3008
  id: 'editor.fontFamily',
2857
3009
  heading: fontFamily(),
@@ -2935,7 +3087,21 @@ const getSettingItemsEditor = () => {
2935
3087
  description: tabSizeDescription(),
2936
3088
  type: Number$1,
2937
3089
  value: '4',
2938
- category: TextEditorTab
3090
+ category: TextEditorTab,
3091
+ validate(value) {
3092
+ if (typeof value !== 'number') {
3093
+ return 'font size must be of type number';
3094
+ }
3095
+ const minTabSize = 1;
3096
+ const maxTabSize = 8;
3097
+ if (value < minTabSize) {
3098
+ return `tab size must be at least ${minTabSize}`;
3099
+ }
3100
+ if (value > maxTabSize) {
3101
+ return `tab size must not be greater than ${maxTabSize}`;
3102
+ }
3103
+ return '';
3104
+ }
2939
3105
  }, {
2940
3106
  id: 'editor.insertSpaces',
2941
3107
  heading: insertSpaces(),
@@ -3908,10 +4074,29 @@ const loadContent = async (state, savedState) => {
3908
4074
  const items = await getSettingItems();
3909
4075
  const preferences = await getPreferences();
3910
4076
  const modifiedSettings = getModifiedSettings(preferences);
3911
- const filteredItems = getFilteredItems(items, newTabs, searchValue, modifiedSettings);
4077
+ const filteredItems = getFilteredItems(items, newTabs, searchValue, modifiedSettings, preferences);
4078
+ const {
4079
+ height,
4080
+ itemHeight
4081
+ } = state;
4082
+ const {
4083
+ visibleItems,
4084
+ minLineY,
4085
+ maxLineY
4086
+ } = computeVisibleItems(filteredItems, height, scrollOffset, itemHeight);
4087
+ const {
4088
+ scrollBarMinHeight
4089
+ } = state;
4090
+ const {
4091
+ thumbHeight,
4092
+ thumbTop
4093
+ } = computeScrollBar(height, filteredItems.length, itemHeight, scrollOffset, scrollBarMinHeight);
3912
4094
  return {
3913
4095
  ...state,
3914
4096
  filteredItems,
4097
+ visibleItems,
4098
+ minLineY,
4099
+ maxLineY,
3915
4100
  inputSource: Script,
3916
4101
  items,
3917
4102
  modifiedSettings,
@@ -3920,7 +4105,9 @@ const loadContent = async (state, savedState) => {
3920
4105
  searchValue,
3921
4106
  tabs: newTabs,
3922
4107
  history,
3923
- historyIndex
4108
+ historyIndex,
4109
+ scrollBarThumbHeight: thumbHeight,
4110
+ scrollBarThumbTop: thumbTop
3924
4111
  };
3925
4112
  };
3926
4113
 
@@ -3942,7 +4129,10 @@ const {
3942
4129
  } = ClassNames;
3943
4130
  const Badge = 'Badge';
3944
4131
  const CheckBox = 'CheckBox';
4132
+ const ErrorMessage = 'ErrorMessage';
3945
4133
  const InputBox = 'InputBox';
4134
+ const InputBoxError = 'InputBoxError';
4135
+ const Label = 'Label';
3946
4136
  const MaskIcon = 'MaskIcon';
3947
4137
  const MaskIconClearAll = 'MaskIconClearAll';
3948
4138
  const ModifiedIndicator = 'ModifiedIndicator';
@@ -3955,6 +4145,7 @@ const SettingsHeader = 'SettingsHeader';
3955
4145
  const SettingsInputWrapper = 'SettingsInputWrapper';
3956
4146
  const SettingsItem = 'SettingsItem';
3957
4147
  const SettingsItemCheckBox = 'SettingsItemCheckBox';
4148
+ const SettingsItemHeading = 'SettingsItemHeading';
3958
4149
  const SettingsItems = 'SettingsItems';
3959
4150
  const SettingsMain = 'SettingsMain';
3960
4151
  const SettingsNoResults = 'SettingsNoResults';
@@ -3983,6 +4174,7 @@ const HandleInput = 'handleInput';
3983
4174
  const HandleSettingInput = 'handleSettingInput';
3984
4175
  const HandleSettingChecked = 'handleSettingChecked';
3985
4176
  const HandleScroll = 'handleScroll';
4177
+ const HandleWheel = 'handleWheel';
3986
4178
  const HandleSettingSelect = 'handleSettingSelect';
3987
4179
  const HandleInputFocus = 'handleInputFocus';
3988
4180
 
@@ -4018,6 +4210,10 @@ const getSettingsInputDom = () => {
4018
4210
  type: VirtualDomElements.Input,
4019
4211
  className: mergeClassNames(InputBox, SettingsSearchInput, 'MultilineInputBox'),
4020
4212
  placeholder,
4213
+ autocomplete: 'off',
4214
+ autocorrect: 'off',
4215
+ autocapitalize: 'off',
4216
+ spellcheck: false,
4021
4217
  childCount: 0,
4022
4218
  name: SettingsSearch,
4023
4219
  onInput: HandleInput,
@@ -4025,11 +4221,11 @@ const getSettingsInputDom = () => {
4025
4221
  }];
4026
4222
  };
4027
4223
 
4028
- const getChildCount = hasSearchValue => {
4224
+ const getChildCount$1 = hasSearchValue => {
4029
4225
  return hasSearchValue ? 3 : 2;
4030
4226
  };
4031
4227
  const getSettingsHeaderDom = (filteredSettingsCount, hasSearchValue) => {
4032
- const childCount = getChildCount(hasSearchValue);
4228
+ const childCount = getChildCount$1(hasSearchValue);
4033
4229
  return [{
4034
4230
  type: VirtualDomElements.Div,
4035
4231
  className: SettingsHeader,
@@ -4041,62 +4237,70 @@ const getSettingsHeaderDom = (filteredSettingsCount, hasSearchValue) => {
4041
4237
  }, ...getSettingsInputDom(), ...getSettingsInputBadgeDom(filteredSettingsCount, hasSearchValue), ...getSettingsInputButtonsDom(hasSearchValue)];
4042
4238
  };
4043
4239
 
4240
+ const getErrorMessageDom = errorMessage => {
4241
+ if (!errorMessage) {
4242
+ return [];
4243
+ }
4244
+ return [{
4245
+ type: VirtualDomElements.Div,
4246
+ className: ErrorMessage,
4247
+ childCount: 1
4248
+ }, text(errorMessage)];
4249
+ };
4250
+
4044
4251
  const getInputId = id => {
4045
4252
  return id.replaceAll('.', '\\.');
4046
4253
  };
4047
4254
 
4255
+ const parent = {
4256
+ type: VirtualDomElements.H3,
4257
+ className: SettingsItemHeading,
4258
+ childCount: 1
4259
+ };
4260
+ const getItemHeadingDom = heading => {
4261
+ return [parent, text(heading)];
4262
+ };
4263
+
4264
+ const getItemLabelDom = (domId, label) => {
4265
+ return [{
4266
+ type: VirtualDomElements.Label,
4267
+ htmlFor: domId,
4268
+ childCount: 1,
4269
+ className: Label
4270
+ }, text(label)];
4271
+ };
4272
+
4048
4273
  const getItemCheckBoxVirtualDom = item => {
4049
4274
  const {
4050
4275
  heading,
4051
4276
  description,
4052
4277
  id,
4053
- modified
4278
+ modified,
4279
+ hasError,
4280
+ errorMessage
4054
4281
  } = item;
4055
- const isModified = modified || false;
4056
4282
  const domId = getInputId(id);
4283
+ const checkBoxClassName = hasError ? `${CheckBox} ${InputBoxError}` : CheckBox;
4284
+ const errorChildCount = hasError ? 1 : 0;
4057
4285
  return [{
4058
4286
  type: VirtualDomElements.Div,
4059
4287
  className: SettingsItem,
4060
- childCount: 3,
4061
- role: 'group',
4062
- 'data-modified': isModified
4063
- }, {
4064
- type: VirtualDomElements.H3,
4065
- childCount: 1
4066
- }, text(heading), {
4288
+ childCount: 2 + errorChildCount,
4289
+ role: AriaRoles.Group,
4290
+ 'data-modified': modified
4291
+ }, ...getItemHeadingDom(heading), {
4067
4292
  type: VirtualDomElements.Div,
4068
4293
  className: SettingsItemCheckBox,
4069
4294
  childCount: 2
4070
4295
  }, {
4071
4296
  type: VirtualDomElements.Input,
4072
- className: CheckBox,
4297
+ className: checkBoxClassName,
4073
4298
  childCount: 0,
4074
4299
  id: domId,
4075
4300
  inputType: 'checkbox',
4076
4301
  name: id,
4077
4302
  onChange: HandleSettingChecked
4078
- }, {
4079
- type: VirtualDomElements.Label,
4080
- childCount: 1,
4081
- htmlFor: domId
4082
- }, text(description)];
4083
- };
4084
-
4085
- const parent = {
4086
- type: VirtualDomElements.H3,
4087
- childCount: 1
4088
- };
4089
- const getItemHeadingDom = heading => {
4090
- return [parent, text(heading)];
4091
- };
4092
-
4093
- const getItemLabelDom = (domId, label) => {
4094
- return [{
4095
- type: VirtualDomElements.Label,
4096
- htmlFor: domId,
4097
- childCount: 1,
4098
- className: 'Label'
4099
- }, text(label)];
4303
+ }, ...getItemLabelDom(domId, description), ...getErrorMessageDom(errorMessage)];
4100
4304
  };
4101
4305
 
4102
4306
  const getItemColorVirtualDom = item => {
@@ -4104,30 +4308,33 @@ const getItemColorVirtualDom = item => {
4104
4308
  heading,
4105
4309
  description,
4106
4310
  id,
4107
- modified
4311
+ modified,
4312
+ hasError,
4313
+ errorMessage
4108
4314
  } = item;
4109
4315
  const domId = getInputId(id);
4110
- const isModified = modified || false;
4316
+ const colorInputClassName = hasError ? mergeClassNames('ColorInput', InputBoxError) : mergeClassNames('ColorInput');
4317
+ const errorChildCount = hasError ? 1 : 0;
4111
4318
  return [{
4112
4319
  type: VirtualDomElements.Div,
4113
4320
  className: SettingsItem,
4114
- childCount: 3,
4115
- role: 'group',
4116
- 'data-modified': isModified
4321
+ childCount: 3 + errorChildCount,
4322
+ role: AriaRoles.Group,
4323
+ 'data-modified': modified
4117
4324
  }, ...getItemHeadingDom(heading), {
4118
4325
  type: VirtualDomElements.Div,
4119
4326
  className: SettingsItemCheckBox,
4120
4327
  childCount: 2
4121
4328
  }, {
4122
4329
  type: VirtualDomElements.Input,
4123
- className: mergeClassNames('ColorInput'),
4330
+ className: colorInputClassName,
4124
4331
  inputType: 'color',
4125
4332
  placeholder: colorValue(),
4126
4333
  childCount: 0,
4127
4334
  id: domId,
4128
4335
  name: id,
4129
4336
  onInput: HandleSettingInput
4130
- }, ...getItemLabelDom(domId, description)];
4337
+ }, ...getItemLabelDom(domId, description), ...getErrorMessageDom(errorMessage)];
4131
4338
  };
4132
4339
 
4133
4340
  const getSettingsModifiedIndicatorDom = isModified => {
@@ -4141,32 +4348,46 @@ const getSettingsModifiedIndicatorDom = isModified => {
4141
4348
  }];
4142
4349
  };
4143
4350
 
4351
+ const getChildCount = (modified, hasError) => {
4352
+ const modifiedChildCount = modified ? 1 : 0;
4353
+ const errorChildCount = hasError ? 1 : 0;
4354
+ const childCount = 3 + modifiedChildCount + errorChildCount;
4355
+ return childCount;
4356
+ };
4357
+ const getInputClassName = hasError => {
4358
+ if (hasError) {
4359
+ return `${InputBox} ${InputBoxError}`;
4360
+ }
4361
+ return InputBox;
4362
+ };
4144
4363
  const getItemNumberVirtualDom = item => {
4145
4364
  const {
4146
4365
  heading,
4147
4366
  description,
4148
4367
  id,
4149
- modified
4368
+ modified,
4369
+ hasError,
4370
+ errorMessage
4150
4371
  } = item;
4151
4372
  const domId = getInputId(id);
4152
- const isModified = modified || false;
4153
- const modifiedChildCount = isModified ? 1 : 0;
4373
+ const inputClassName = getInputClassName(hasError);
4374
+ const childCount = getChildCount(modified, hasError);
4154
4375
  return [{
4155
4376
  type: VirtualDomElements.Div,
4156
4377
  className: SettingsItem,
4157
- childCount: 3 + modifiedChildCount,
4158
- role: 'group',
4159
- 'data-modified': isModified
4160
- }, ...getSettingsModifiedIndicatorDom(isModified), ...getItemHeadingDom(heading), ...getItemLabelDom(domId, description), {
4378
+ childCount,
4379
+ role: AriaRoles.Group,
4380
+ 'data-modified': modified
4381
+ }, ...getSettingsModifiedIndicatorDom(modified), ...getItemHeadingDom(heading), ...getItemLabelDom(domId, description), {
4161
4382
  type: VirtualDomElements.Input,
4162
- className: InputBox,
4383
+ className: inputClassName,
4163
4384
  inputType: 'number',
4164
4385
  placeholder: numberValue(),
4165
4386
  childCount: 0,
4166
4387
  id: domId,
4167
4388
  name: id,
4168
4389
  onInput: HandleSettingInput
4169
- }];
4390
+ }, ...getErrorMessageDom(errorMessage)];
4170
4391
  };
4171
4392
 
4172
4393
  const getOptionDom = option => {
@@ -4185,51 +4406,55 @@ const getItemSelectVirtualDom = item => {
4185
4406
  const {
4186
4407
  heading,
4187
4408
  description,
4188
- id
4409
+ id,
4410
+ options,
4411
+ hasError,
4412
+ errorMessage
4189
4413
  } = item;
4190
- const options = item.options || [];
4191
4414
  const domId = getInputId(id);
4415
+ const selectClassName = hasError ? `${Select} ${InputBoxError}` : Select;
4416
+ const errorChildCount = hasError ? 1 : 0;
4192
4417
  return [{
4193
4418
  type: VirtualDomElements.Div,
4194
4419
  className: SettingsItem,
4195
- childCount: 3,
4196
- role: 'group'
4420
+ childCount: 3 + errorChildCount,
4421
+ role: AriaRoles.Group
4197
4422
  }, ...getItemHeadingDom(heading), ...getItemLabelDom(domId, description), {
4198
4423
  type: VirtualDomElements.Select,
4199
- className: Select,
4200
- childCount: options.length,
4424
+ className: selectClassName,
4425
+ childCount: options?.length || 0,
4201
4426
  id: domId,
4202
4427
  name: id,
4203
4428
  onChange: HandleSettingSelect
4204
- }, ...options.flatMap(getOptionDom)];
4429
+ }, ...(options?.flatMap(getOptionDom) || []), ...getErrorMessageDom(errorMessage)];
4205
4430
  };
4206
4431
 
4207
4432
  const getItemStringVirtualDom = item => {
4208
4433
  const {
4209
4434
  heading,
4210
4435
  description,
4211
- id
4436
+ id,
4437
+ hasError,
4438
+ errorMessage
4212
4439
  } = item;
4440
+ const domId = getInputId(id);
4441
+ const inputClassName = hasError ? `${InputBox} ${InputBoxError}` : InputBox;
4442
+ const errorChildCount = hasError ? 1 : 0;
4213
4443
  return [{
4214
4444
  type: VirtualDomElements.Div,
4215
4445
  className: SettingsItem,
4216
- childCount: 3,
4217
- role: 'group'
4218
- }, {
4219
- type: VirtualDomElements.H3,
4220
- childCount: 1
4221
- }, text(heading), {
4222
- type: VirtualDomElements.P,
4223
- childCount: 1
4224
- }, text(description), {
4446
+ childCount: 3 + errorChildCount,
4447
+ role: AriaRoles.Group
4448
+ }, ...getItemHeadingDom(heading), ...getItemLabelDom(domId, description), {
4225
4449
  type: VirtualDomElements.Input,
4226
- className: InputBox,
4450
+ className: inputClassName,
4227
4451
  inputType: 'text',
4228
4452
  placeholder: stringValue(),
4229
4453
  childCount: 0,
4454
+ id: domId,
4230
4455
  name: id,
4231
4456
  onInput: HandleSettingInput
4232
- }];
4457
+ }, ...getErrorMessageDom(errorMessage)];
4233
4458
  };
4234
4459
 
4235
4460
  const getItemUnknownVirtualDom = () => {
@@ -4237,7 +4462,7 @@ const getItemUnknownVirtualDom = () => {
4237
4462
  type: VirtualDomElements.Div,
4238
4463
  className: SettingsItem,
4239
4464
  childCount: 1,
4240
- role: 'group'
4465
+ role: AriaRoles.Group
4241
4466
  }, text(unknownSettingType())];
4242
4467
  };
4243
4468
 
@@ -4246,48 +4471,53 @@ const getItemUrlVirtualDom = item => {
4246
4471
  heading,
4247
4472
  description,
4248
4473
  id,
4249
- modified
4474
+ modified,
4475
+ hasError,
4476
+ errorMessage
4250
4477
  } = item;
4251
4478
  const domId = getInputId(id);
4252
- const isModified = modified || false;
4479
+ const inputClassName = hasError ? `${InputBox} ${InputBoxError}` : InputBox;
4480
+ const errorChildCount = hasError ? 1 : 0;
4253
4481
  return [{
4254
4482
  type: VirtualDomElements.Div,
4255
4483
  className: SettingsItem,
4256
- childCount: 3,
4257
- role: 'group',
4258
- 'data-modified': isModified
4484
+ childCount: 3 + errorChildCount,
4485
+ role: AriaRoles.Group,
4486
+ 'data-modified': modified
4259
4487
  }, ...getItemHeadingDom(heading), ...getItemLabelDom(domId, description), {
4260
4488
  type: VirtualDomElements.Input,
4261
- className: InputBox,
4489
+ className: inputClassName,
4262
4490
  inputType: 'url',
4263
4491
  placeholder: numberValue(),
4264
4492
  childCount: 0,
4265
4493
  id: domId,
4266
4494
  name: id,
4267
4495
  onInput: HandleSettingInput
4268
- }];
4496
+ }, ...getErrorMessageDom(errorMessage)];
4497
+ };
4498
+
4499
+ const getItemRender = type => {
4500
+ switch (type) {
4501
+ case Number$1:
4502
+ return getItemNumberVirtualDom;
4503
+ case Boolean$1:
4504
+ return getItemCheckBoxVirtualDom;
4505
+ case String:
4506
+ return getItemStringVirtualDom;
4507
+ case Enum:
4508
+ return getItemSelectVirtualDom;
4509
+ case Color:
4510
+ return getItemColorVirtualDom;
4511
+ case Url:
4512
+ return getItemUrlVirtualDom;
4513
+ default:
4514
+ return getItemUnknownVirtualDom;
4515
+ }
4269
4516
  };
4270
4517
 
4271
4518
  const getItemVirtualDom = item => {
4272
- if (item.type === Number$1) {
4273
- return getItemNumberVirtualDom(item);
4274
- }
4275
- if (item.type === Boolean$1) {
4276
- return getItemCheckBoxVirtualDom(item);
4277
- }
4278
- if (item.type === String) {
4279
- return getItemStringVirtualDom(item);
4280
- }
4281
- if (item.type === Enum) {
4282
- return getItemSelectVirtualDom(item);
4283
- }
4284
- if (item.type === Color) {
4285
- return getItemColorVirtualDom(item);
4286
- }
4287
- if (item.type === Url) {
4288
- return getItemUrlVirtualDom(item);
4289
- }
4290
- return getItemUnknownVirtualDom();
4519
+ const fn = getItemRender(item.type);
4520
+ return fn(item);
4291
4521
  };
4292
4522
 
4293
4523
  const getSettingsNoResultsDom = searchValue => {
@@ -4303,7 +4533,7 @@ const getSettingsNoResultsDom = searchValue => {
4303
4533
  };
4304
4534
 
4305
4535
  const getSettingsItemsDom = (items, searchValue) => {
4306
- if (items.length === 0 && searchValue.trim()) {
4536
+ if (items.length === 0 && searchValue && searchValue.trim()) {
4307
4537
  return getSettingsNoResultsDom(searchValue);
4308
4538
  }
4309
4539
  return [{
@@ -4489,6 +4719,10 @@ const renderEventListeners = () => {
4489
4719
  name: HandleScroll,
4490
4720
  params: ['handleScroll', 'event.target.scrollTop'],
4491
4721
  passive: true
4722
+ }, {
4723
+ name: HandleWheel,
4724
+ params: ['handleWheel', 'event.deltaY'],
4725
+ passive: true
4492
4726
  }, {
4493
4727
  name: HandleSettingSelect,
4494
4728
  params: ['handleSettingSelect', 'event.target.name', 'event.target.value']
@@ -4527,14 +4761,15 @@ const useNextSearchValue = state => {
4527
4761
  historyIndex,
4528
4762
  items,
4529
4763
  tabs,
4530
- modifiedSettings
4764
+ modifiedSettings,
4765
+ preferences
4531
4766
  } = state;
4532
4767
  if (history.length === 0 || historyIndex >= history.length - 1) {
4533
4768
  return state;
4534
4769
  }
4535
4770
  const newHistoryIndex = historyIndex + 1;
4536
4771
  const newSearchValue = history[newHistoryIndex];
4537
- const filteredItems = getFilteredItems(items, tabs, newSearchValue, modifiedSettings);
4772
+ const filteredItems = getFilteredItems(items, tabs, newSearchValue, modifiedSettings, preferences);
4538
4773
  return {
4539
4774
  ...state,
4540
4775
  searchValue: newSearchValue,
@@ -4550,14 +4785,15 @@ const usePreviousSearchValue = state => {
4550
4785
  historyIndex,
4551
4786
  items,
4552
4787
  tabs,
4553
- modifiedSettings
4788
+ modifiedSettings,
4789
+ preferences
4554
4790
  } = state;
4555
4791
  if (history.length === 0 || historyIndex <= 0) {
4556
4792
  return state;
4557
4793
  }
4558
4794
  const newHistoryIndex = historyIndex - 1;
4559
4795
  const newSearchValue = history[newHistoryIndex];
4560
- const filteredItems = getFilteredItems(items, tabs, newSearchValue, modifiedSettings);
4796
+ const filteredItems = getFilteredItems(items, tabs, newSearchValue, modifiedSettings, preferences);
4561
4797
  return {
4562
4798
  ...state,
4563
4799
  searchValue: newSearchValue,
@@ -4579,6 +4815,7 @@ const commandMap = {
4579
4815
  'Settings.handleInputBlur': wrapCommand(handleInputBlur),
4580
4816
  'Settings.handleInput': wrapCommand(handleInput),
4581
4817
  'Settings.handleScroll': wrapCommand(handleScroll),
4818
+ 'Settings.handleWheel': wrapCommand(handleWheel),
4582
4819
  'Settings.handleSettingChecked': wrapCommand(handleSettingChecked),
4583
4820
  'Settings.handleSettingInput': wrapCommand(handleSettingInput),
4584
4821
  'Settings.handleInputFocus': wrapCommand(handleInputFocus),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lvce-editor/settings-view",
3
- "version": "1.19.0",
3
+ "version": "1.21.0",
4
4
  "description": "Explorer Worker",
5
5
  "repository": {
6
6
  "type": "git",