@ticatec/uniface-element 5.0.0 → 5.0.2

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.
Files changed (282) hide show
  1. package/README.md +29 -54
  2. package/README_CN.md +37 -57
  3. package/dist/app_layout/ClassicLayout.svelte +8 -40
  4. package/dist/app_layout/ColumnsLayout.svelte +3 -3
  5. package/dist/app_layout/HeaderLayout.svelte +4 -20
  6. package/dist/app_layout/RowsLayout.svelte +3 -3
  7. package/dist/app_layout/SidebarLayout.svelte +4 -20
  8. package/dist/base-calendar/CalendarBase.svelte +29 -6
  9. package/dist/base-calendar/CalendarBase.svelte.d.ts +4 -0
  10. package/dist/base-calendar/MonthPickupPanel.svelte +19 -6
  11. package/dist/base-calendar/MonthPickupPanel.svelte.d.ts +1 -1
  12. package/dist/base-calendar/MonthlyCalendar.svelte +18 -2
  13. package/dist/base-calendar/YearPickupPanel.svelte +24 -6
  14. package/dist/base-calendar/YearPickupPanel.svelte.d.ts +1 -1
  15. package/dist/composite/pagination_panel/PaginationPanel.svelte +2 -0
  16. package/dist/composite/transfer/Transfer.svelte +12 -6
  17. package/dist/data_display/accordion/Accordion.svelte +1 -4
  18. package/dist/data_display/card/CommonCardActionBar.svelte +31 -37
  19. package/dist/data_display/concise_data_table/Column.d.ts +6 -0
  20. package/dist/data_display/concise_data_table/ConciseListTable.svelte +4 -3
  21. package/dist/data_display/concise_data_table/DataCell.svelte +3 -3
  22. package/dist/data_display/list_box/ListBox.svelte +96 -23
  23. package/dist/data_display/list_box/ListBox.svelte.d.ts +4 -0
  24. package/dist/data_display/tree_view/TreeNodeView.svelte +25 -4
  25. package/dist/data_table/DataTable.svelte +5 -5
  26. package/dist/data_table/DataTable.svelte.d.ts +36 -16
  27. package/dist/data_table/lib/ActionsColumn.d.ts +2 -2
  28. package/dist/data_table/lib/DataColumn.d.ts +7 -1
  29. package/dist/data_table/lib/RowAction.d.ts +5 -5
  30. package/dist/data_table/lib/clickOutSide.js +6 -5
  31. package/dist/data_table/parts/FixedHeaderPanel.svelte +18 -3
  32. package/dist/data_table/parts/FixedRow.svelte +10 -1
  33. package/dist/data_table/parts/HrefCell.svelte +1 -1
  34. package/dist/data_table/parts/TableHeaderPanel.svelte +18 -2
  35. package/dist/data_table/parts/TextCell.svelte +2 -2
  36. package/dist/form/attachment_files/AttachmentEditor.svelte +20 -15
  37. package/dist/form/attachment_files/FileRender.svelte +1 -1
  38. package/dist/form/attachment_files/FileUploadBar.svelte +5 -2
  39. package/dist/form/attachment_files/FileUploadPanel.svelte +11 -73
  40. package/dist/form/cascade_options_select/CascadeOptionSelect.svelte +10 -2
  41. package/dist/form/cascade_options_select/OptionsBox.svelte +48 -2
  42. package/dist/form/checkbox/CheckBox.svelte +2 -7
  43. package/dist/form/color_picker/ColorPicker.svelte +150 -35
  44. package/dist/form/color_picker/ColorPicker.svelte.d.ts +7 -25
  45. package/dist/form/color_picker/ColorPickerPanel.svelte +23 -20
  46. package/dist/form/color_picker/ColorPickerPanel.svelte.d.ts +5 -18
  47. package/dist/form/color_picker/README.md +14 -7
  48. package/dist/form/color_picker/README_CN.md +14 -7
  49. package/dist/form/common_editor/CommonEditor.svelte +18 -4
  50. package/dist/form/common_editor/CommonPicker.svelte +14 -10
  51. package/dist/form/common_editor/CommonPopupEditor.svelte +8 -1
  52. package/dist/form/common_range_editor/CommonRangeEditor.svelte +11 -2
  53. package/dist/form/date_picker/DatePicker.svelte +1 -1
  54. package/dist/form/date_picker/DateTimePicker.svelte +1 -1
  55. package/dist/form/date_picker/ScrollBar.svelte +20 -12
  56. package/dist/form/date_picker/ScrollBar.svelte.d.ts +4 -18
  57. package/dist/form/date_range/DateRangeEditor.svelte +11 -3
  58. package/dist/form/group_box/group-check-box/GroupCheckBox.svelte +6 -1
  59. package/dist/form/group_box/group-radio-box/GroupRadioBox.svelte +6 -1
  60. package/dist/form/image-files/ImageFilesField.svelte +51 -7
  61. package/dist/form/image-files/ImagePreview.svelte +23 -9
  62. package/dist/form/image-files/ImageRender.svelte +69 -11
  63. package/dist/form/input_options_select/InputOptionsSelect.svelte +10 -2
  64. package/dist/form/lookup_editor/LookupEditor.svelte +9 -2
  65. package/dist/form/memo_editor/MemoEditor.svelte +2 -2
  66. package/dist/form/number_editor/NumberEditor.svelte +2 -2
  67. package/dist/form/options_multi_select/OptionsMultiSelect.svelte +20 -12
  68. package/dist/form/options_select/OptionsSelect.svelte +15 -6
  69. package/dist/form/options_select/OptionsSelect.svelte.d.ts +39 -17
  70. package/dist/form/prompts_text_editor/PromptsTextEditor.svelte +10 -2
  71. package/dist/form/radio_button/RadioButton.svelte +2 -8
  72. package/dist/form/switch/Switch.svelte +4 -4
  73. package/dist/form/text_editor/TextEditor.svelte +2 -2
  74. package/dist/form/unit-number-editor/UnitNumberEditor.svelte +10 -2
  75. package/dist/general/button/Button.svelte +5 -0
  76. package/dist/general/button/Button.svelte.d.ts +1 -0
  77. package/dist/general/button/IconButton.svelte +3 -1
  78. package/dist/general/button/IconButton.svelte.d.ts +1 -0
  79. package/dist/general/button/TextButton.svelte +3 -0
  80. package/dist/general/button/TextButton.svelte.d.ts +1 -0
  81. package/dist/general/icon/Icon.svelte +18 -1
  82. package/dist/general/split/Split.svelte +24 -4
  83. package/dist/general/tag/Tag.svelte +9 -1
  84. package/dist/navigation/nav_menu/MenuItem.d.ts +4 -2
  85. package/dist/navigation/nav_menu/NavigatorMenu.svelte +157 -34
  86. package/dist/navigation/nav_menu/NavigatorMenu.svelte.d.ts +2 -3
  87. package/dist/navigation/nav_menu/NavigatorMenuItem.svelte +25 -13
  88. package/dist/navigation/nav_menu/NavigatorMenuItem.svelte.d.ts +3 -3
  89. package/dist/navigation/navigator/Navigator.svelte +17 -17
  90. package/dist/navigation/page-stack/PageStack.svelte +160 -0
  91. package/dist/navigation/page-stack/PageStack.svelte.d.ts +24 -0
  92. package/dist/navigation/page-stack/PageStackContext.d.ts +25 -0
  93. package/dist/navigation/page-stack/PageStackContext.js +12 -0
  94. package/dist/navigation/page-stack/PageStackFrame.svelte +24 -0
  95. package/dist/navigation/page-stack/PageStackFrame.svelte.d.ts +11 -0
  96. package/dist/navigation/page-stack/README.md +154 -0
  97. package/dist/navigation/page-stack/README_CN.md +154 -0
  98. package/dist/navigation/page-stack/index.d.ts +6 -0
  99. package/dist/navigation/page-stack/index.js +4 -0
  100. package/dist/navigation/pagination/Pagination.svelte +114 -14
  101. package/dist/navigation/progress_step_bar/ProgressStepBlock.svelte +1 -5
  102. package/dist/navigation/tabs/Tabs.svelte +42 -10
  103. package/dist/navigation/tabs/Tabs.svelte.d.ts +2 -2
  104. package/dist/overlay/common/FloatingPanel.svelte +3 -17
  105. package/dist/overlay/common/FullscreenOverlay.svelte +27 -3
  106. package/dist/overlay/common/FullscreenOverlay.svelte.d.ts +6 -27
  107. package/dist/overlay/common/ModalPopover.svelte +18 -2
  108. package/dist/overlay/common/Popover.svelte +61 -57
  109. package/dist/overlay/common/Popover.svelte.d.ts +1 -5
  110. package/dist/overlay/common/escapeClose.d.ts +28 -0
  111. package/dist/overlay/common/escapeClose.js +47 -0
  112. package/dist/overlay/common/focusTrap.d.ts +8 -0
  113. package/dist/overlay/common/focusTrap.js +83 -0
  114. package/dist/overlay/common/mountSingleton.d.ts +27 -0
  115. package/dist/overlay/common/mountSingleton.js +45 -0
  116. package/dist/overlay/common/outsideClick.d.ts +28 -0
  117. package/dist/overlay/common/outsideClick.js +20 -0
  118. package/dist/overlay/common/scrollLock.d.ts +8 -0
  119. package/dist/overlay/common/scrollLock.js +49 -0
  120. package/dist/overlay/common/uniface-utils.js +0 -1
  121. package/dist/overlay/context-menu/ContextMenu.svelte.js +2 -15
  122. package/dist/overlay/context-menu/ContextMenuPanel.svelte +27 -3
  123. package/dist/overlay/dialog/Dialog.svelte +48 -32
  124. package/dist/overlay/dialog/DialogManager.svelte.js +7 -9
  125. package/dist/overlay/dialog/DialogWrapper.svelte +5 -2
  126. package/dist/overlay/drawer/Drawer.svelte +30 -3
  127. package/dist/overlay/indicator/Indicator.svelte.js +2 -15
  128. package/dist/overlay/indicator/IndicatorPanel.svelte +4 -1
  129. package/dist/overlay/message-box/MessageBox.svelte.js +2 -15
  130. package/dist/overlay/message-box/MessageBoxPanel.svelte +19 -3
  131. package/dist/overlay/toast/Toast.svelte.js +2 -15
  132. package/dist/overlay/toast/ToastPanel.svelte +1 -1
  133. package/dist/overlay/tooltip/Tooltip.svelte +1 -1
  134. package/dist/ticatec-uniface-web.css +128 -13
  135. package/dist/types.d.ts +4 -3
  136. package/dist/utils/prefixFilter.d.ts +3 -3
  137. package/dist/utils/prefixFilter.js +3 -5
  138. package/docs/components/README.md +133 -0
  139. package/docs/components/accordion/README.md +60 -0
  140. package/docs/components/accordion/example.svelte +7 -0
  141. package/docs/components/action-bar/README.md +114 -0
  142. package/docs/components/action-bar/example.svelte +7 -0
  143. package/docs/components/app-top-bar/README.md +60 -0
  144. package/docs/components/app-top-bar/example.svelte +9 -0
  145. package/docs/components/attachment-files/README.md +332 -0
  146. package/docs/components/attachment-files/example.svelte +16 -0
  147. package/docs/components/box/README.md +63 -0
  148. package/docs/components/box/example.svelte +10 -0
  149. package/docs/components/breadcrumbs/README.md +86 -0
  150. package/docs/components/breadcrumbs/example.svelte +11 -0
  151. package/docs/components/button/README.md +103 -0
  152. package/docs/components/button/example.svelte +10 -0
  153. package/docs/components/card/README.md +113 -0
  154. package/docs/components/card/example.svelte +10 -0
  155. package/docs/components/cascade-options-select/README.md +162 -0
  156. package/docs/components/cascade-options-select/example.svelte +18 -0
  157. package/docs/components/checkbox/README.md +103 -0
  158. package/docs/components/checkbox/example.svelte +15 -0
  159. package/docs/components/classic-layout/README.md +76 -0
  160. package/docs/components/classic-layout/example.svelte +16 -0
  161. package/docs/components/color-picker/README.md +132 -0
  162. package/docs/components/color-picker/example.svelte +16 -0
  163. package/docs/components/columns-layout/README.md +70 -0
  164. package/docs/components/columns-layout/example.svelte +12 -0
  165. package/docs/components/common-dialog/README.md +109 -0
  166. package/docs/components/common-dialog/example.svelte +12 -0
  167. package/docs/components/concise-data-table/README.md +307 -0
  168. package/docs/components/concise-data-table/example.svelte +16 -0
  169. package/docs/components/context-menu/README.md +99 -0
  170. package/docs/components/context-menu/example.svelte +10 -0
  171. package/docs/components/criteria-field/README.md +69 -0
  172. package/docs/components/criteria-field/example.svelte +9 -0
  173. package/docs/components/data-table/README.md +365 -0
  174. package/docs/components/data-table/example.svelte +23 -0
  175. package/docs/components/date-picker/README.md +136 -0
  176. package/docs/components/date-picker/example.svelte +16 -0
  177. package/docs/components/date-range/README.md +122 -0
  178. package/docs/components/date-range/example.svelte +15 -0
  179. package/docs/components/date-time-picker/README.md +142 -0
  180. package/docs/components/date-time-picker/example.svelte +16 -0
  181. package/docs/components/dialog/README.md +174 -0
  182. package/docs/components/dialog/example.svelte +13 -0
  183. package/docs/components/dialog-board/README.md +41 -0
  184. package/docs/components/dialog-board/example.svelte +5 -0
  185. package/docs/components/drawer/README.md +70 -0
  186. package/docs/components/drawer/example.svelte +12 -0
  187. package/docs/components/flex-form/README.md +55 -0
  188. package/docs/components/flex-form/example.svelte +7 -0
  189. package/docs/components/flex-row-form/README.md +56 -0
  190. package/docs/components/flex-row-form/example.svelte +7 -0
  191. package/docs/components/form-field/README.md +84 -0
  192. package/docs/components/form-field/example.svelte +10 -0
  193. package/docs/components/full-screen-overlay/README.md +66 -0
  194. package/docs/components/full-screen-overlay/example.svelte +11 -0
  195. package/docs/components/grid-form/README.md +75 -0
  196. package/docs/components/grid-form/example.svelte +9 -0
  197. package/docs/components/group-check-box/README.md +147 -0
  198. package/docs/components/group-check-box/example.svelte +21 -0
  199. package/docs/components/group-radio-box/README.md +144 -0
  200. package/docs/components/group-radio-box/example.svelte +21 -0
  201. package/docs/components/header-layout/README.md +65 -0
  202. package/docs/components/header-layout/example.svelte +12 -0
  203. package/docs/components/icon/README.md +87 -0
  204. package/docs/components/icon/example.svelte +9 -0
  205. package/docs/components/icon-button/README.md +91 -0
  206. package/docs/components/icon-button/example.svelte +10 -0
  207. package/docs/components/image-files/README.md +174 -0
  208. package/docs/components/image-files/example.svelte +19 -0
  209. package/docs/components/indicator/README.md +53 -0
  210. package/docs/components/indicator/example.svelte +14 -0
  211. package/docs/components/input-options-select/README.md +163 -0
  212. package/docs/components/input-options-select/example.svelte +16 -0
  213. package/docs/components/list-box/ListItem.svelte +14 -0
  214. package/docs/components/list-box/README.md +221 -0
  215. package/docs/components/list-box/example.svelte +61 -0
  216. package/docs/components/lookup-editor/README.md +137 -0
  217. package/docs/components/lookup-editor/example.svelte +16 -0
  218. package/docs/components/memo-editor/README.md +143 -0
  219. package/docs/components/memo-editor/example.svelte +16 -0
  220. package/docs/components/message-box/README.md +68 -0
  221. package/docs/components/message-box/example.svelte +10 -0
  222. package/docs/components/navigator/README.md +75 -0
  223. package/docs/components/navigator/example.svelte +13 -0
  224. package/docs/components/navigator-menu/README.md +113 -0
  225. package/docs/components/navigator-menu/example.svelte +10 -0
  226. package/docs/components/number-editor/README.md +144 -0
  227. package/docs/components/number-editor/example.svelte +16 -0
  228. package/docs/components/number-range/README.md +116 -0
  229. package/docs/components/number-range/example.svelte +15 -0
  230. package/docs/components/options-multi-select/README.md +161 -0
  231. package/docs/components/options-multi-select/example.svelte +20 -0
  232. package/docs/components/options-select/README.md +160 -0
  233. package/docs/components/options-select/example.svelte +21 -0
  234. package/docs/components/page/README.md +77 -0
  235. package/docs/components/page/example.svelte +10 -0
  236. package/docs/components/pagination/README.md +88 -0
  237. package/docs/components/pagination/example.svelte +10 -0
  238. package/docs/components/pagination-panel/README.md +120 -0
  239. package/docs/components/pagination-panel/example.svelte +16 -0
  240. package/docs/components/popup-hint/README.md +44 -0
  241. package/docs/components/popup-hint/example.svelte +5 -0
  242. package/docs/components/progress-bar/README.md +64 -0
  243. package/docs/components/progress-bar/example.svelte +8 -0
  244. package/docs/components/progress-step-bar/README.md +93 -0
  245. package/docs/components/progress-step-bar/example.svelte +7 -0
  246. package/docs/components/prompts-text-editor/README.md +146 -0
  247. package/docs/components/prompts-text-editor/example.svelte +17 -0
  248. package/docs/components/radio-button/README.md +121 -0
  249. package/docs/components/radio-button/example.svelte +18 -0
  250. package/docs/components/rows-layout/README.md +70 -0
  251. package/docs/components/rows-layout/example.svelte +12 -0
  252. package/docs/components/search-box/README.md +136 -0
  253. package/docs/components/search-box/example.svelte +16 -0
  254. package/docs/components/separator/README.md +44 -0
  255. package/docs/components/separator/example.svelte +7 -0
  256. package/docs/components/sidebar-layout/README.md +65 -0
  257. package/docs/components/sidebar-layout/example.svelte +12 -0
  258. package/docs/components/split/README.md +48 -0
  259. package/docs/components/split/example.svelte +8 -0
  260. package/docs/components/switch/README.md +77 -0
  261. package/docs/components/switch/example.svelte +11 -0
  262. package/docs/components/tabs/README.md +127 -0
  263. package/docs/components/tabs/example.svelte +22 -0
  264. package/docs/components/tag/README.md +63 -0
  265. package/docs/components/tag/example.svelte +8 -0
  266. package/docs/components/text-button/README.md +90 -0
  267. package/docs/components/text-button/example.svelte +9 -0
  268. package/docs/components/text-editor/README.md +147 -0
  269. package/docs/components/text-editor/example.svelte +16 -0
  270. package/docs/components/time-editor/README.md +130 -0
  271. package/docs/components/time-editor/example.svelte +16 -0
  272. package/docs/components/toast/README.md +52 -0
  273. package/docs/components/toast/example.svelte +9 -0
  274. package/docs/components/tooltip/README.md +44 -0
  275. package/docs/components/tooltip/example.svelte +5 -0
  276. package/docs/components/transfer/README.md +109 -0
  277. package/docs/components/transfer/example.svelte +13 -0
  278. package/docs/components/tree-view/README.md +163 -0
  279. package/docs/components/tree-view/example.svelte +26 -0
  280. package/docs/components/unit-number-editor/README.md +192 -0
  281. package/docs/components/unit-number-editor/example.svelte +18 -0
  282. package/package.json +15 -7
@@ -2,31 +2,39 @@
2
2
  interface Props {
3
3
  value: number;
4
4
  months: Array<string>;
5
- onClick?: (event: MouseEvent) => void;
5
+ onclick?: (event: MouseEvent) => void;
6
6
  }
7
7
 
8
8
  let {
9
9
  value = $bindable<number>(),
10
10
  months,
11
- onClick
11
+ onclick
12
12
  }: Props = $props();
13
13
 
14
14
  const handleMonthClick = (m: number) => (e: MouseEvent) => {
15
15
  if (m !== value) {
16
16
  value = m;
17
- onClick?.(e);
17
+ onclick?.(e);
18
18
  } else {
19
19
  e.stopPropagation();
20
20
  e.preventDefault();
21
21
  }
22
22
  };
23
+
24
+ const handleKeyActivate = (m: number) => (e: KeyboardEvent) => {
25
+ if (e.key === 'Enter' || e.key === ' ') {
26
+ e.preventDefault();
27
+ handleMonthClick(m)(e as unknown as MouseEvent);
28
+ }
29
+ };
23
30
  </script>
24
- <div class="uniface-month-pickup-panel" onclick={onClick} aria-hidden="true">
31
+ <div class="uniface-month-pickup-panel" onclick={onclick} role="presentation">
25
32
  <div>
26
33
  <div style="display: grid; grid-template-columns: auto auto auto; overflow: hidden; width: 100%">
27
34
  {#each months as month, idx}
28
- <div class="month-block" class:selected={idx === value} aria-hidden="true"
29
- onclick={handleMonthClick(idx)}>
35
+ <div class="month-block" class:selected={idx === value}
36
+ role="button" tabindex="0" aria-current={idx === value ? 'date' : undefined}
37
+ onclick={handleMonthClick(idx)} onkeydown={handleKeyActivate(idx)}>
30
38
  <span>{month}</span>
31
39
  </div>
32
40
  {/each}
@@ -85,4 +93,9 @@
85
93
  .month-block.selected:hover {
86
94
  background-color: unset;
87
95
  }
96
+
97
+ .month-block:focus-visible {
98
+ outline: 2px solid var(--uniface-primary-border-color, #298DFF);
99
+ outline-offset: 1px;
100
+ }
88
101
  </style>
@@ -1,7 +1,7 @@
1
1
  interface Props {
2
2
  value: number;
3
3
  months: Array<string>;
4
- onClick?: (event: MouseEvent) => void;
4
+ onclick?: (event: MouseEvent) => void;
5
5
  }
6
6
  declare const MonthPickupPanel: import("svelte").Component<Props, {}, "value">;
7
7
  type MonthPickupPanel = ReturnType<typeof MonthPickupPanel>;
@@ -94,6 +94,13 @@
94
94
  onselect?.(dayjs(new Date(year, month, ad.d)));
95
95
  }
96
96
  };
97
+
98
+ const handleDayKeyDown = (ad: CalendarDay) => (e: KeyboardEvent) => {
99
+ if (e.key === 'Enter' || e.key === ' ') {
100
+ e.preventDefault();
101
+ handleDayClick(ad)();
102
+ }
103
+ };
97
104
  </script>
98
105
  <div class="monthly-calendar" class:border>
99
106
  {#each Array(7) as _, idx}
@@ -103,14 +110,18 @@
103
110
  {/each}
104
111
  {#each days as day, idx}
105
112
  <div class="cell calendar-day"
106
- aria-hidden="true"
113
+ role="button" tabindex={day.disabled ? -1 : 0}
114
+ aria-disabled={day.disabled}
115
+ aria-current={day.isToday ? 'date' : undefined}
116
+ aria-pressed={selected.year === day.y && selected.month === day.m && selected.date === day.d}
117
+ aria-label="{day.y}-{day.m + 1}-{day.d}"
107
118
  style="width: {cellWidth}px; height: {cellHeight}px;"
108
119
  class:weekend={isWeekend(idx)}
109
120
  class:today={day.isToday}
110
121
  class:selected={selected.year === day.y && selected.month === day.m && selected.date === day.d}
111
122
  class:lastRow={idx > 34}
112
123
  class:disabled={day.disabled}
113
- onclick={handleDayClick(day)}>
124
+ onclick={handleDayClick(day)} onkeydown={handleDayKeyDown(day)}>
114
125
  <span>{day.d}</span>
115
126
  {#if dailyContent}
116
127
  <div>
@@ -200,4 +211,9 @@
200
211
  .disabled > span:first-child:hover {
201
212
  background-color: unset;
202
213
  }
214
+
215
+ .calendar-day:focus-visible > span:first-child {
216
+ outline: 2px solid var(--uniface-primary-border-color, #298DFF);
217
+ outline-offset: 1px;
218
+ }
203
219
  </style>
@@ -3,14 +3,14 @@
3
3
  year: number;
4
4
  maxYear?: number | null;
5
5
  minYear?: number | null;
6
- onClick?: (event: MouseEvent) => void;
6
+ onclick?: (event: MouseEvent) => void;
7
7
  }
8
8
 
9
9
  let {
10
10
  year = $bindable<number>(),
11
11
  maxYear = null,
12
12
  minYear = null,
13
- onClick
13
+ onclick
14
14
  }: Props = $props();
15
15
 
16
16
  let offset = $state(6);
@@ -34,18 +34,28 @@
34
34
  e.stopPropagation();
35
35
  e.preventDefault();
36
36
  };
37
+
38
+ const handleKeyActivate = (handler: (e: any) => void) => (e: KeyboardEvent) => {
39
+ if (e.key === 'Enter' || e.key === ' ') {
40
+ e.preventDefault();
41
+ handler(e);
42
+ }
43
+ };
37
44
  </script>
38
- <div class="uniface-year-pickup-panel" aria-hidden="true" onclick={onClick}>
45
+ <div class="uniface-year-pickup-panel" onclick={onclick} role="presentation">
39
46
  <div>
40
47
  <div>
41
48
  <div style="text-align: center">
42
49
  <div style="display: inline-block; width: 30px; height: 10px; padding: 6px 0">
43
- <i class="icon_google_keyboard_arrow_up" aria-hidden="true" onclick={showYears(-years)}></i>
50
+ <i class="icon_google_keyboard_arrow_up" role="button" tabindex="0" aria-label="Previous years"
51
+ onclick={showYears(-years)} onkeydown={handleKeyActivate(showYears(-years))}></i>
44
52
  </div>
45
53
  </div>
46
54
  <div style="display: grid; grid-template-columns: auto auto auto auto; width: 100%; overflow: hidden">
47
55
  {#each Array(years) as _, i}
48
- <div class="year-block" onclick={handleYearClick(i)} aria-hidden="true"
56
+ <div class="year-block" onclick={handleYearClick(i)} onkeydown={handleKeyActivate(handleYearClick(i))}
57
+ role="button" tabindex="0" aria-disabled={isDisabled(year - offset + i)}
58
+ aria-current={year === year - offset + i ? 'date' : undefined}
49
59
  class:disabled={isDisabled(year - offset + i)}
50
60
  class:selected={year === year - offset + i}>
51
61
  <span>{year - offset + i}</span>
@@ -54,7 +64,8 @@
54
64
  </div>
55
65
  <div style="text-align: center">
56
66
  <div style="display: inline-block; width: 30px; height: 10px; padding: 6px 0">
57
- <i class="icon_google_keyboard_arrow_down" aria-hidden="true" onclick={showYears(years)}></i>
67
+ <i class="icon_google_keyboard_arrow_down" role="button" tabindex="0" aria-label="Next years"
68
+ onclick={showYears(years)} onkeydown={handleKeyActivate(showYears(years))}></i>
58
69
  </div>
59
70
  </div>
60
71
  </div>
@@ -122,4 +133,11 @@
122
133
  .year-block.disabled:hover {
123
134
  font-weight: unset;
124
135
  }
136
+
137
+ .year-block:focus-visible,
138
+ .icon_google_keyboard_arrow_up:focus-visible,
139
+ .icon_google_keyboard_arrow_down:focus-visible {
140
+ outline: 2px solid var(--uniface-primary-border-color, #298DFF);
141
+ outline-offset: 1px;
142
+ }
125
143
  </style>
@@ -2,7 +2,7 @@ interface Props {
2
2
  year: number;
3
3
  maxYear?: number | null;
4
4
  minYear?: number | null;
5
- onClick?: (event: MouseEvent) => void;
5
+ onclick?: (event: MouseEvent) => void;
6
6
  }
7
7
  declare const YearPickupPanel: import("svelte").Component<Props, {}, "year">;
8
8
  type YearPickupPanel = ReturnType<typeof YearPickupPanel>;
@@ -38,6 +38,8 @@
38
38
  let pagesOptions = $derived(
39
39
  (rowsSet ?? [25, 50, 100]).map(v => ({code: v, text: `${v}`}))
40
40
  );
41
+ // Rendered via {@html} below: generateInfo is a trusted, caller-supplied
42
+ // renderer (not user input) — same opt-in-HTML boundary as DataColumn#renderHTML.
41
43
  let totalText = $derived(
42
44
  generateInfo
43
45
  ? generateInfo(total, pageCount, pageNo, rowCount)
@@ -38,6 +38,15 @@
38
38
 
39
39
  let sourceSelectedList: Array<any> = $state([]);
40
40
  let targetSelectedList: Array<any> = $state([]);
41
+ let transferContainer = $state<HTMLDivElement>();
42
+
43
+ const handleFocusIn = (event: FocusEvent) => {
44
+ if (!transferContainer?.contains(event.relatedTarget as Node | null)) onfocus?.(event);
45
+ };
46
+
47
+ const handleFocusOut = (event: FocusEvent) => {
48
+ if (!transferContainer?.contains(event.relatedTarget as Node | null)) onblur?.(event);
49
+ };
41
50
 
42
51
  const moveToTarget = async () => {
43
52
  if (sourceSelectedList.length > 0 && await onchange?.(sourceSelectedList, "right")) {
@@ -56,7 +65,7 @@
56
65
  }
57
66
  </script>
58
67
 
59
- <div class="uniface-transfer-container" {onfocus} {onblur} tabindex="0">
68
+ <div bind:this={transferContainer} class="uniface-transfer-container" onfocusin={handleFocusIn} onfocusout={handleFocusOut}>
60
69
  <ListBox class="list-container" title={sourceTitle} {filter} style="{style}; grid-column: 1/2" list={sourceList} selectMode="multiple"
61
70
  bind:selectedList={sourceSelectedList} {itemRender}>
62
71
  {#snippet footer()}
@@ -96,10 +105,7 @@
96
105
  grid-auto-columns: 1fr 60px 1fr;
97
106
  column-gap: 16px;
98
107
  }
99
- .uniface-transfer-container .header-container {
100
- margin: 10px auto 10px 10px;
101
- }
102
- .uniface-transfer-container .list-container {
108
+ .uniface-transfer-container :global(.list-container) {
103
109
  height: 100%;
104
110
  flex: 1 1 auto;
105
111
  overflow: hidden;
@@ -113,4 +119,4 @@
113
119
  flex-direction: column;
114
120
  justify-content: center;
115
121
  align-items: center;
116
- }</style>
122
+ }</style>
@@ -72,7 +72,4 @@
72
72
  overflow-y: auto;
73
73
  }
74
74
 
75
- .uniface-accordion-panel.compact {
76
- /* Compact mode handled by passing prop to AccordionItemView */
77
- }
78
- </style>
75
+ </style>
@@ -26,6 +26,13 @@
26
26
  clickEnable = true;
27
27
  }
28
28
  };
29
+
30
+ const handleActionKeyDown = (action: CardAction) => (e: KeyboardEvent) => {
31
+ if (e.key === 'Enter' || e.key === ' ') {
32
+ e.preventDefault();
33
+ handleActionClick(action)(e as unknown as MouseEvent);
34
+ }
35
+ };
29
36
  </script>
30
37
 
31
38
  <div class="card-action-bar">
@@ -34,18 +41,21 @@
34
41
  <i class="action-icon {action.icon}"
35
42
  class:disabled={action.disabled}
36
43
  data-tip={action.disabled ? undefined : action.tooltip}
37
- aria-hidden="true"
44
+ role="button" tabindex={action.disabled ? -1 : 0}
45
+ aria-disabled={action.disabled}
46
+ aria-label={action.tooltip}
38
47
  onclick={handleActionClick(action)}
48
+ onkeydown={handleActionKeyDown(action)}
39
49
  ></i>
40
50
  {:else if action.img}
41
- <img class="card-action-img"
42
- class:disabled={action.disabled}
43
- alt=""
44
- src={action.img}
45
- data-tip={action.disabled ? undefined : action.tooltip}
46
- aria-hidden="true"
47
- onclick={handleActionClick(action)}
48
- />
51
+ <button type="button" class="card-action-img-btn"
52
+ class:disabled={action.disabled}
53
+ disabled={action.disabled}
54
+ data-tip={action.disabled ? undefined : action.tooltip}
55
+ aria-label={action.tooltip}
56
+ onclick={handleActionClick(action)}>
57
+ <img class="card-action-img" alt="" src={action.img}/>
58
+ </button>
49
59
  {/if}
50
60
 
51
61
  {/each}
@@ -89,46 +99,30 @@
89
99
  }
90
100
 
91
101
 
92
- .card-action-img {
93
- width: var(--action-image-size, var(--uniface-action-image-size));
94
- height: var(--action-image-size, var(--uniface-action-image-size));
102
+ .card-action-img-btn {
103
+ background: none;
104
+ border: none;
105
+ padding: 0;
95
106
  cursor: pointer;
107
+ display: inline-flex;
96
108
  }
97
109
 
98
- .card-action-img:hover {
99
- }
100
-
101
- .card-action-img:active {
110
+ .card-action-img-btn:active {
102
111
  position: relative;
103
112
  top: 1px;
104
113
  }
105
114
 
106
- .card-action-img.disabled {
115
+ .card-action-img-btn.disabled {
107
116
  cursor: not-allowed;
108
- filter: grayscale(100%);
109
117
  }
110
118
 
111
- .action-item.disabled .action-icon:hover {
112
- color: var(--disabled-button-text-color, var(--uniface-disabled-button-text-color, #B3BCCA));
113
- }
114
-
115
- .action-item.disabled .action-icon:active {
116
- position: relative;
117
- top: 0;
118
- }
119
-
120
- .action-item.disabled .card-action-img {
119
+ .card-action-img-btn.disabled .card-action-img {
121
120
  filter: grayscale(100%);
122
- cursor: default;
123
121
  }
124
122
 
125
- .action-item.disabled .card-action-img:hover {
126
- width: var(--action-image-size, var(--uniface-action-image-size, 15px));
127
- height: var(--action-image-size, var(--uniface-action-image-size, 15px));
123
+ .card-action-img {
124
+ width: var(--action-image-size, var(--uniface-action-image-size));
125
+ height: var(--action-image-size, var(--uniface-action-image-size));
128
126
  }
129
127
 
130
- .action-item.disabled .card-action-img:active {
131
- position: relative;
132
- top: 0;
133
- }
134
- </style>
128
+ </style>
@@ -5,5 +5,11 @@ export default interface Column {
5
5
  align?: "left" | "center" | "right";
6
6
  weight?: number;
7
7
  formatter?: (value: any) => string;
8
+ renderHTML?: boolean;
9
+ /**
10
+ * @deprecated Use renderHTML instead; "escapeHTML" reads as "this escapes HTML"
11
+ * when it actually means the opposite — true renders raw, trusted HTML. Still
12
+ * honored as a fallback for existing callers.
13
+ */
8
14
  escapeHTML?: boolean;
9
15
  }
@@ -215,7 +215,8 @@
215
215
  overflow: hidden;
216
216
  display: flex;
217
217
  flex-direction: column;
218
- color: var(--uniface-concise-table-bg, unset);
218
+ background-color: var(--uniface-concise-table-color-surface);
219
+ color: var(--uniface-concise-table-color);
219
220
  }
220
221
  :global .uniface-concise-datatable .table-container {
221
222
  display: flex;
@@ -237,7 +238,7 @@
237
238
  padding: 2px 4px;
238
239
  }
239
240
  :global .uniface-concise-datatable .table-header {
240
- background-color: #f5f5f5;
241
+ background-color: var(--uniface-concise-table-header-surface);
241
242
  padding: 0;
242
243
  flex-shrink: 0;
243
244
  z-index: 10;
@@ -265,7 +266,7 @@
265
266
  color: var(--uniface-concise-table-row-alter-color, #374151);
266
267
  }
267
268
  :global .uniface-concise-datatable .table-body-container .table-row:hover {
268
- background-color: #f9f9f9;
269
+ background-color: var(--uniface-concise-table-row-hover-bg);
269
270
  }
270
271
  :global .uniface-concise-datatable .table-body-container.auto-scroll {
271
272
  overflow-y: hidden;
@@ -14,9 +14,9 @@
14
14
  }: Props = $props();
15
15
 
16
16
  let text = $derived(column.formatter ? column.formatter(data[column.field]) : (data[column.field] ?? ''));
17
- // Safe by default: HTML rendering is opt-in only (escapeHTML: true), matching the
18
- // semantics of the data_table component's DataColumn#escapeHTML flag.
19
- let renderAsHtml = $derived(column.escapeHTML === true);
17
+ // Safe by default: HTML rendering is opt-in only (renderHTML: true), matching the
18
+ // semantics of the data_table component's DataColumn#renderHTML flag.
19
+ let renderAsHtml = $derived((column.renderHTML ?? column.escapeHTML) === true);
20
20
  </script>
21
21
 
22
22
  <div class="data-cell col_{idx}" role="cell">
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import {tick} from "svelte";
2
+ import {tick, onDestroy, untrack} from "svelte";
3
3
  import SearchBox from "../../form/search_box"
4
4
  import type {FunFilter} from "../../types";
5
5
  import type {ListLazyLoader} from "../../types";
@@ -22,6 +22,10 @@
22
22
  selectedList?: Array<any>;
23
23
  class?: string;
24
24
  item$props?: any;
25
+ onchange?: OnSelectChange;
26
+ /**
27
+ * @deprecated 请使用 onchange;仍受支持以兼容旧调用。
28
+ */
25
29
  onSelectChange?: OnSelectChange;
26
30
  onItemDblClick?: OnItemDblClick;
27
31
  onItemClick?: OnItemClick;
@@ -45,6 +49,7 @@
45
49
  selectedList = $bindable([]),
46
50
  class: className,
47
51
  item$props,
52
+ onchange,
48
53
  onSelectChange,
49
54
  onItemDblClick,
50
55
  onItemClick,
@@ -56,9 +61,11 @@
56
61
  loadMoreIndicator
57
62
  }: Props = $props();
58
63
 
59
- let localSelectedItem = $state(selectedItem ?? null);
64
+ // External values are synchronized by the effects below. Neutral initial values
65
+ // avoid implying that these props are intentionally captured only once.
66
+ let localSelectedItem = $state<any>(null);
60
67
  let localSelectedList = $state(selectedList ?? []);
61
- let localFilterText = $state(filterText ?? '');
68
+ let localFilterText = $state('');
62
69
 
63
70
  let hasMore = $state(false);
64
71
  let isBusy = $state(false);
@@ -66,7 +73,7 @@
66
73
  let filteredList = $state<Array<any>>([]);
67
74
 
68
75
  let scrollElement: HTMLElement;
69
- let searchBox: any;
76
+ let searchBox = $state<any>();
70
77
 
71
78
  // Sync external props to local state
72
79
  $effect(() => {
@@ -81,12 +88,19 @@
81
88
  localFilterText = filterText ?? '';
82
89
  });
83
90
 
91
+ // onchange is the canonical name; onSelectChange is kept as a deprecated
92
+ // alias and fired alongside it for backward compatibility.
93
+ const notifySelectChange = (item: any) => {
94
+ onchange?.(item);
95
+ onSelectChange?.(item);
96
+ };
97
+
84
98
  const handleItemClick = (item: any) => (e: MouseEvent) => {
85
99
  if (readonly == false) {
86
100
  if (selectMode == 'single') {
87
101
  if (localSelectedItem != item) {
88
102
  localSelectedItem = item;
89
- onSelectChange?.(item);
103
+ notifySelectChange(item);
90
104
  }
91
105
  } else {
92
106
  onItemClick?.(item);
@@ -100,6 +114,13 @@
100
114
  }
101
115
  }
102
116
 
117
+ const handleItemKeyDown = (item: any) => (e: KeyboardEvent) => {
118
+ if (e.key === 'Enter' || e.key === ' ') {
119
+ e.preventDefault();
120
+ handleItemClick(item)(e as unknown as MouseEvent);
121
+ }
122
+ }
123
+
103
124
  const doFilter = () => {
104
125
  const newList: Array<any> = [];
105
126
  list?.forEach(item => {
@@ -113,14 +134,23 @@
113
134
  filteredList = newList;
114
135
  if (selectMode == 'single') {
115
136
  localSelectedItem = null;
116
- onSelectChange?.(null);
137
+ notifySelectChange(null);
117
138
  }
118
139
  }
119
140
 
141
+ // Guards against out-of-order responses: only the most recently issued
142
+ // request is allowed to write its result into component state.
143
+ let lazyLoadSeq = 0;
144
+ let destroyed = false;
145
+
120
146
  const lazyLoad = async (clean: boolean = true) => {
147
+ const seq = ++lazyLoadSeq;
121
148
  isBusy = true;
122
149
  try {
123
150
  let result = await lazyLoader?.(localFilterText, pageNo);
151
+ if (destroyed || seq !== lazyLoadSeq) {
152
+ return;
153
+ }
124
154
  if (result) {
125
155
  if (clean) {
126
156
  list = result.list;
@@ -131,8 +161,17 @@
131
161
  filteredList = list ?? [];
132
162
  hasMore = result.hasMore;
133
163
  }
164
+ } catch (e) {
165
+ if (!clean) {
166
+ // Failed page-2+ fetch: undo the optimistic pageNo increment so a
167
+ // retry (e.g. re-triggered by scroll) re-requests the same page.
168
+ pageNo--;
169
+ }
170
+ throw e;
134
171
  } finally {
135
- isBusy = false;
172
+ if (!destroyed && seq === lazyLoadSeq) {
173
+ isBusy = false;
174
+ }
136
175
  }
137
176
  }
138
177
 
@@ -146,12 +185,26 @@
146
185
  interval = null;
147
186
  pageNo = 1;
148
187
  scrollElement.scrollTop = 0;
149
- await lazyLoad();
150
- await tick();
151
- searchBox.focus();
188
+ try {
189
+ await lazyLoad();
190
+ } catch (e) {
191
+ console.error('ListBox: failed to reload items', e);
192
+ }
193
+ if (!destroyed) {
194
+ await tick();
195
+ searchBox?.focus();
196
+ }
152
197
  }
153
198
  }
154
199
 
200
+ onDestroy(() => {
201
+ destroyed = true;
202
+ if (interval != null) {
203
+ clearInterval(interval);
204
+ interval = null;
205
+ }
206
+ });
207
+
155
208
  const handleCriteriaChange = () => {
156
209
  if (lazyLoader != null) {
157
210
  if (interval == null) {
@@ -190,15 +243,27 @@
190
243
  }
191
244
  }
192
245
 
246
+ // untrack: lazyLoad() reads pageNo/isBusy/localFilterText synchronously
247
+ // before its first await. Without untrack, those reads register as
248
+ // dependencies of *this* effect, so a later change to pageNo (e.g. from
249
+ // fetchMore) would re-run this effect and fire a second, unrelated
250
+ // "initial load" — this must only re-run when the lazyLoader prop itself
251
+ // changes.
193
252
  $effect(() => {
194
253
  if (lazyLoader != null) {
195
- lazyLoad();
254
+ untrack(() => {
255
+ lazyLoad().catch((e) => console.error('ListBox: failed to load items', e));
256
+ });
196
257
  }
197
258
  });
198
259
 
199
260
  const fetchMore = async () => {
200
261
  pageNo++;
201
- await lazyLoad(false);
262
+ try {
263
+ await lazyLoad(false);
264
+ } catch (e) {
265
+ console.error('ListBox: failed to load more items', e);
266
+ }
202
267
  }
203
268
 
204
269
  const handleScroll = () => {
@@ -230,20 +295,25 @@
230
295
  onchange={handleCriteriaChange}/>
231
296
  </div>
232
297
  {/if}
233
- <div class="listbox-content" class:selectable={selectMode==='single'} bind:this={scrollElement} onscroll={handleScroll}>
298
+ <div class="listbox-content" class:selectable={selectMode==='single'} bind:this={scrollElement} onscroll={handleScroll}
299
+ role="listbox" aria-multiselectable={selectMode === 'multiple' ? true : undefined}>
234
300
  {#if filteredList && ItemRender}
235
301
  {#each filteredList as item}
236
302
  {#if selectMode === "multiple"}
237
- <div class="listview-item" style="display: flex; flex-direction: row; align-items: center; gap: 8px">
303
+ <div class="listview-item" style="display: flex; flex-direction: row; align-items: center; gap: 8px"
304
+ role="option" aria-selected={localSelectedList.indexOf(item) > -1}>
238
305
  <CheckBox style="flex: 0 0 auto; margin-left: 8px" {readonly} value={localSelectedList.indexOf(item) > -1}
239
306
  onchange={handleSelectionChanged(item)}/>
240
- <div style="flex: 1 1 auto; cursor: pointer" aria-hidden="true" onclick={handleSelectionChanged(item)}>
307
+ <div style="flex: 1 1 auto; cursor: pointer" role="button" tabindex="0"
308
+ onclick={handleSelectionChanged(item)}
309
+ onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); handleSelectionChanged(item)(); } }}>
241
310
  <ItemRender {readonly} {item} {...item$props}/>
242
311
  </div>
243
312
  </div>
244
313
  {:else }
245
- <div class="listview-item" class:selected={item===localSelectedItem} aria-hidden="true"
246
- ondblclick={handleItemDblClick(item)} onclick={handleItemClick(item)}>
314
+ <div class="listview-item" class:selected={item===localSelectedItem}
315
+ role="option" aria-selected={item===localSelectedItem} tabindex="0"
316
+ ondblclick={handleItemDblClick(item)} onclick={handleItemClick(item)} onkeydown={handleItemKeyDown(item)}>
247
317
  <ItemRender {item} {readonly} selected={item===localSelectedItem}
248
318
  {...item$props}/>
249
319
  </div>
@@ -277,6 +347,8 @@
277
347
  box-sizing: border-box;
278
348
  user-select: none;
279
349
  border: 1px solid var(--uniface-list-box-border-color);
350
+ background-color: var(--uniface-list-box-color-surface);
351
+ color: var(--uniface-list-box-color);
280
352
  }
281
353
 
282
354
  .uniface-listbox.round {
@@ -289,7 +361,7 @@
289
361
  position: absolute;
290
362
  top: 0;
291
363
  left: 0;
292
- background-color: #FFFFFF10;
364
+ background-color: var(--uniface-color-overlay-mask-surface);
293
365
  }
294
366
 
295
367
  .box-header {
@@ -337,10 +409,6 @@
337
409
  border-bottom: 1px solid var(--uniface-listbox-separator-color);
338
410
  }
339
411
 
340
- .listbox-content .listview-item.no-border {
341
- border-bottom: unset;
342
- }
343
-
344
412
  .listbox-content.selectable .listview-item {
345
413
  cursor: pointer;
346
414
  }
@@ -352,4 +420,9 @@
352
420
  .listbox-content.selectable .listview-item.selected {
353
421
  background-color: var(--uniface-list-box-selected-surface);
354
422
  }
355
- </style>
423
+
424
+ .listbox-content .listview-item:focus-visible {
425
+ outline: 2px solid var(--uniface-primary-border-color, #298DFF);
426
+ outline-offset: -2px;
427
+ }
428
+ </style>