@sapudex/web-components 0.192.4 → 0.199.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/bundle.esm.js +2 -0
  2. package/dist/Button.d.ts +2 -1
  3. package/dist/Button.js +2 -1
  4. package/dist/Button.js.map +1 -1
  5. package/dist/ControlButton.d.ts +11 -6
  6. package/dist/ControlButton.js +19 -7
  7. package/dist/ControlButton.js.map +1 -1
  8. package/dist/CountrySelector.js +1 -1
  9. package/dist/CountrySelector.js.map +1 -1
  10. package/dist/Footer.d.ts +1 -6
  11. package/dist/Footer.js +2 -9
  12. package/dist/Footer.js.map +1 -1
  13. package/dist/Link.d.ts +5 -0
  14. package/dist/Link.js +6 -0
  15. package/dist/Link.js.map +1 -1
  16. package/dist/List.d.ts +3 -2
  17. package/dist/List.js +10 -5
  18. package/dist/List.js.map +1 -1
  19. package/dist/ListGroupHeader.d.ts +1 -1
  20. package/dist/ListGroupHeader.js +2 -1
  21. package/dist/ListGroupHeader.js.map +1 -1
  22. package/dist/ListGroupHeaderBase.js +3 -3
  23. package/dist/ListGroupHeaderBase.js.map +1 -1
  24. package/dist/ListItem.d.ts +1 -1
  25. package/dist/ListItem.js +8 -7
  26. package/dist/ListItem.js.map +1 -1
  27. package/dist/ListItemBase.d.ts +1 -1
  28. package/dist/ListItemBase.js +1 -1
  29. package/dist/ListItemBase.js.map +1 -1
  30. package/dist/ListSelectAll.js +4 -5
  31. package/dist/ListSelectAll.js.map +1 -1
  32. package/dist/MastheadItem.d.ts +1 -6
  33. package/dist/MastheadItem.js +3 -9
  34. package/dist/MastheadItem.js.map +1 -1
  35. package/dist/MastheadMenuItem.d.ts +8 -5
  36. package/dist/MastheadMenuItem.js +9 -7
  37. package/dist/MastheadMenuItem.js.map +1 -1
  38. package/dist/MastheadShell.js +2 -2
  39. package/dist/MastheadShell.js.map +1 -1
  40. package/dist/MediaPlayer.js +3 -2
  41. package/dist/MediaPlayer.js.map +1 -1
  42. package/dist/MessageStrip.d.ts +9 -38
  43. package/dist/MessageStrip.js +30 -56
  44. package/dist/MessageStrip.js.map +1 -1
  45. package/dist/PhoneNumberField.js +7 -2
  46. package/dist/PhoneNumberField.js.map +1 -1
  47. package/dist/SecondaryNavigation.d.ts +0 -1
  48. package/dist/SecondaryNavigation.js +3 -3
  49. package/dist/SecondaryNavigation.js.map +1 -1
  50. package/dist/SecondaryNavigationItemBase.d.ts +1 -6
  51. package/dist/SecondaryNavigationItemBase.js +3 -9
  52. package/dist/SecondaryNavigationItemBase.js.map +1 -1
  53. package/dist/SegmentedButton.d.ts +2 -2
  54. package/dist/SegmentedButton.js +3 -2
  55. package/dist/SegmentedButton.js.map +1 -1
  56. package/dist/SegmentedButtonItem.d.ts +2 -6
  57. package/dist/SegmentedButtonItem.js +2 -7
  58. package/dist/SegmentedButtonItem.js.map +1 -1
  59. package/dist/SelectBox.d.ts +9 -1
  60. package/dist/SelectBox.js +14 -1
  61. package/dist/SelectBox.js.map +1 -1
  62. package/dist/Tab.d.ts +1 -6
  63. package/dist/Tab.js +1 -7
  64. package/dist/Tab.js.map +1 -1
  65. package/dist/Upload.d.ts +110 -0
  66. package/dist/Upload.js +198 -0
  67. package/dist/Upload.js.map +1 -0
  68. package/dist/UploadItem.d.ts +101 -0
  69. package/dist/UploadItem.js +151 -0
  70. package/dist/UploadItem.js.map +1 -0
  71. package/dist/assets/{bundle-c5e3cbf2.css → bundle-7a4a3e16.css} +1 -1
  72. package/dist/assets/{bundle.esm-aa637b3f.js → bundle.esm-44fd7c69.js} +208 -191
  73. package/dist/assets/messagebundle_en-59e0affd.js +1 -0
  74. package/dist/css/themes/Avatar.css +1 -1
  75. package/dist/css/themes/Button.css +1 -1
  76. package/dist/css/themes/CountrySelector.css +1 -1
  77. package/dist/css/themes/Link.css +1 -1
  78. package/dist/css/themes/Pagination.css +1 -1
  79. package/dist/css/themes/RatingIndicator.css +1 -1
  80. package/dist/css/themes/Slider.css +1 -1
  81. package/dist/css/themes/StatusBadge.css +1 -1
  82. package/dist/css/themes/TagGroup.css +1 -1
  83. package/dist/css/themes/TextField.css +1 -1
  84. package/dist/css/themes/Upload.css +1 -0
  85. package/dist/css/themes/UploadItem.css +1 -0
  86. package/dist/custom-elements-internal.json +470 -26
  87. package/dist/custom-elements.json +431 -21
  88. package/dist/features/SearchSuggestionsPopover.js +1 -1
  89. package/dist/features/SearchSuggestionsPopover.js.map +1 -1
  90. package/dist/generated/assets/i18n/messagebundle_en.json +1 -1
  91. package/dist/generated/i18n/i18n-defaults.d.ts +6 -1
  92. package/dist/generated/i18n/i18n-defaults.js +10 -5
  93. package/dist/generated/i18n/i18n-defaults.js.map +1 -1
  94. package/dist/generated/templates/ListItemTemplate.lit.js +4 -4
  95. package/dist/generated/templates/ListItemTemplate.lit.js.map +1 -1
  96. package/dist/generated/templates/ListTemplate.lit.js +2 -2
  97. package/dist/generated/templates/ListTemplate.lit.js.map +1 -1
  98. package/dist/generated/templates/MastheadMenuItemTemplate.lit.js +1 -1
  99. package/dist/generated/templates/MastheadMenuItemTemplate.lit.js.map +1 -1
  100. package/dist/generated/templates/MastheadMobileMenuTemplate.lit.js +1 -1
  101. package/dist/generated/templates/MastheadMobileMenuTemplate.lit.js.map +1 -1
  102. package/dist/generated/templates/MessageStripTemplate.lit.js +1 -1
  103. package/dist/generated/templates/MessageStripTemplate.lit.js.map +1 -1
  104. package/dist/generated/templates/PhoneNumberFieldTemplate.lit.js +1 -1
  105. package/dist/generated/templates/PhoneNumberFieldTemplate.lit.js.map +1 -1
  106. package/dist/generated/templates/SelectBoxTemplate.lit.js +2 -2
  107. package/dist/generated/templates/SelectBoxTemplate.lit.js.map +1 -1
  108. package/dist/generated/templates/TagGroupTemplate.lit.js +2 -2
  109. package/dist/generated/templates/TagGroupTemplate.lit.js.map +1 -1
  110. package/dist/generated/templates/TileTemplate.lit.js +2 -2
  111. package/dist/generated/templates/TileTemplate.lit.js.map +1 -1
  112. package/dist/generated/templates/UploadItemTemplate.lit.d.ts +4 -0
  113. package/dist/generated/templates/UploadItemTemplate.lit.js +10 -0
  114. package/dist/generated/templates/UploadItemTemplate.lit.js.map +1 -0
  115. package/dist/generated/templates/UploadTemplate.lit.d.ts +4 -0
  116. package/dist/generated/templates/UploadTemplate.lit.js +8 -0
  117. package/dist/generated/templates/UploadTemplate.lit.js.map +1 -0
  118. package/dist/generated/themes/Avatar.css.js +1 -1
  119. package/dist/generated/themes/Avatar.css.js.map +1 -1
  120. package/dist/generated/themes/Button.css.js +1 -1
  121. package/dist/generated/themes/Button.css.js.map +1 -1
  122. package/dist/generated/themes/CountrySelector.css.js +1 -1
  123. package/dist/generated/themes/CountrySelector.css.js.map +1 -1
  124. package/dist/generated/themes/Link.css.js +1 -1
  125. package/dist/generated/themes/Link.css.js.map +1 -1
  126. package/dist/generated/themes/Pagination.css.js +1 -1
  127. package/dist/generated/themes/Pagination.css.js.map +1 -1
  128. package/dist/generated/themes/RatingIndicator.css.js +1 -1
  129. package/dist/generated/themes/RatingIndicator.css.js.map +1 -1
  130. package/dist/generated/themes/Slider.css.js +1 -1
  131. package/dist/generated/themes/Slider.css.js.map +1 -1
  132. package/dist/generated/themes/StatusBadge.css.js +1 -1
  133. package/dist/generated/themes/StatusBadge.css.js.map +1 -1
  134. package/dist/generated/themes/TagGroup.css.js +1 -1
  135. package/dist/generated/themes/TagGroup.css.js.map +1 -1
  136. package/dist/generated/themes/TextField.css.js +1 -1
  137. package/dist/generated/themes/TextField.css.js.map +1 -1
  138. package/dist/generated/themes/Upload.css.d.ts +3 -0
  139. package/dist/generated/themes/Upload.css.js +9 -0
  140. package/dist/generated/themes/Upload.css.js.map +1 -0
  141. package/dist/generated/themes/UploadItem.css.d.ts +3 -0
  142. package/dist/generated/themes/UploadItem.css.js +9 -0
  143. package/dist/generated/themes/UploadItem.css.js.map +1 -0
  144. package/dist/i18n/messagebundle.properties +13 -4
  145. package/dist/i18n/messagebundle_en.properties +9 -4
  146. package/dist/types/ButtonSize.d.ts +6 -0
  147. package/dist/types/ButtonSize.js +8 -0
  148. package/dist/types/ButtonSize.js.map +1 -0
  149. package/dist/types/FileData.d.ts +5 -0
  150. package/dist/types/FileData.js +2 -0
  151. package/dist/types/FileData.js.map +1 -0
  152. package/dist/types/FileUploadState.d.ts +6 -0
  153. package/dist/types/FileUploadState.js +8 -0
  154. package/dist/types/FileUploadState.js.map +1 -0
  155. package/dist/types/MessageStrip.d.ts +12 -0
  156. package/dist/types/MessageStrip.js +15 -0
  157. package/dist/types/MessageStrip.js.map +1 -0
  158. package/dist/types/common.d.ts +6 -0
  159. package/dist/types/common.js +7 -0
  160. package/dist/types/common.js.map +1 -1
  161. package/dist/utils/Breakpoints.d.ts +33 -0
  162. package/dist/utils/Breakpoints.js +33 -0
  163. package/dist/utils/Breakpoints.js.map +1 -0
  164. package/dist/utils/convertBytesToMegabytes.d.ts +2 -0
  165. package/dist/utils/convertBytesToMegabytes.js +3 -0
  166. package/dist/utils/convertBytesToMegabytes.js.map +1 -0
  167. package/dist/vscode.html-custom-data.json +83 -1
  168. package/dist/web-types.json +191 -4
  169. package/package.json +2 -2
  170. package/src/Button.ts +5 -2
  171. package/src/ControlButton.ts +29 -8
  172. package/src/CountrySelector.ts +1 -1
  173. package/src/Footer.ts +3 -9
  174. package/src/Link.ts +12 -0
  175. package/src/List.hbs +4 -2
  176. package/src/List.ts +14 -8
  177. package/src/ListGroupHeader.ts +4 -2
  178. package/src/ListGroupHeaderBase.ts +12 -11
  179. package/src/ListItem.hbs +3 -1
  180. package/src/ListItem.ts +19 -15
  181. package/src/ListItemBase.ts +10 -10
  182. package/src/ListSelectAll.ts +5 -5
  183. package/src/MastheadItem.ts +3 -11
  184. package/src/MastheadMenuItem.hbs +1 -1
  185. package/src/MastheadMenuItem.ts +14 -7
  186. package/src/MastheadMobileMenu.hbs +1 -0
  187. package/src/MastheadShell.ts +2 -2
  188. package/src/MediaPlayer.ts +3 -3
  189. package/src/MessageStrip.hbs +1 -1
  190. package/src/MessageStrip.ts +38 -68
  191. package/src/PhoneNumberField.hbs +2 -2
  192. package/src/PhoneNumberField.ts +9 -4
  193. package/src/SecondaryNavigation.ts +3 -3
  194. package/src/SecondaryNavigationItemBase.ts +3 -9
  195. package/src/SegmentedButton.ts +4 -3
  196. package/src/SegmentedButtonItem.ts +3 -8
  197. package/src/SelectBox.hbs +19 -23
  198. package/src/SelectBox.ts +23 -1
  199. package/src/Tab.ts +1 -8
  200. package/src/TagGroup.hbs +20 -20
  201. package/src/Tile.hbs +3 -2
  202. package/src/Upload.hbs +21 -0
  203. package/src/Upload.ts +273 -0
  204. package/src/UploadItem.hbs +32 -0
  205. package/src/UploadItem.ts +218 -0
  206. package/src/features/SearchSuggestionsPopover.ts +1 -1
  207. package/src/generated/i18n/i18n-defaults.ts +2 -2
  208. package/src/generated/templates/ListItemTemplate.lit.ts +4 -4
  209. package/src/generated/templates/ListTemplate.lit.ts +2 -2
  210. package/src/generated/templates/MastheadMenuItemTemplate.lit.ts +1 -1
  211. package/src/generated/templates/MastheadMobileMenuTemplate.lit.ts +1 -1
  212. package/src/generated/templates/MessageStripTemplate.lit.ts +1 -1
  213. package/src/generated/templates/PhoneNumberFieldTemplate.lit.ts +1 -1
  214. package/src/generated/templates/SelectBoxTemplate.lit.ts +2 -2
  215. package/src/generated/templates/TagGroupTemplate.lit.ts +2 -2
  216. package/src/generated/templates/TileTemplate.lit.ts +2 -2
  217. package/src/generated/templates/UploadItemTemplate.lit.ts +15 -0
  218. package/src/generated/templates/UploadTemplate.lit.ts +13 -0
  219. package/src/generated/themes/Avatar.css.ts +1 -1
  220. package/src/generated/themes/Button.css.ts +1 -1
  221. package/src/generated/themes/CountrySelector.css.ts +1 -1
  222. package/src/generated/themes/Link.css.ts +1 -1
  223. package/src/generated/themes/Pagination.css.ts +1 -1
  224. package/src/generated/themes/RatingIndicator.css.ts +1 -1
  225. package/src/generated/themes/Slider.css.ts +1 -1
  226. package/src/generated/themes/StatusBadge.css.ts +1 -1
  227. package/src/generated/themes/TagGroup.css.ts +1 -1
  228. package/src/generated/themes/TextField.css.ts +1 -1
  229. package/src/generated/themes/Upload.css.ts +13 -0
  230. package/src/generated/themes/UploadItem.css.ts +13 -0
  231. package/src/i18n/messagebundle.properties +13 -4
  232. package/src/i18n/messagebundle_en.properties +9 -4
  233. package/src/themes/Avatar.css +36 -45
  234. package/src/themes/Button.css +3 -3
  235. package/src/themes/CountrySelector.css +1 -0
  236. package/src/themes/Link.css +17 -4
  237. package/src/themes/Pagination.css +1 -1
  238. package/src/themes/StatusBadge.css +9 -9
  239. package/src/themes/TagGroup.css +0 -4
  240. package/src/themes/TextField.css +2 -1
  241. package/src/themes/Upload.css +65 -0
  242. package/src/themes/UploadItem.css +131 -0
  243. package/src/types/ButtonSize.ts +7 -0
  244. package/src/types/FileData.ts +6 -0
  245. package/src/types/FileUploadState.ts +7 -0
  246. package/src/types/MessageStrip.ts +13 -0
  247. package/src/types/common.ts +7 -0
  248. package/src/utils/Breakpoints.ts +41 -0
  249. package/src/utils/convertBytesToMegabytes.ts +3 -0
  250. package/dist/assets/messagebundle_en-06c0dadc.js +0 -1
package/src/SelectBox.ts CHANGED
@@ -48,6 +48,12 @@ import UDExStatusMessage from "./StatusMessage.js";
48
48
  import UDExControlButton from "./ControlButton.js";
49
49
  import UDExTagGroup from "./TagGroup.js";
50
50
 
51
+ export type SelectBoxAccessibilityAttributes = {
52
+ controls?: string,
53
+ expanded?: "true" | "false" | boolean,
54
+ hasPopup?: string,
55
+ ariaLabel?: string,
56
+ }
51
57
  /**
52
58
  * @class
53
59
  *
@@ -704,10 +710,26 @@ class UDExSelectBox extends UDExSearchableListBase {
704
710
  return {
705
711
  "ariaLabel": this.accessibleName || this.label || undefined,
706
712
  "ariaLabelledBy": this.accessibleNameRef || undefined,
707
- "ariaControls": this.shadowRoot?.querySelector("[udex-list]")?.getAttribute("id"),
708
713
  };
709
714
  }
710
715
 
716
+ get accessibilityAttributes(): SelectBoxAccessibilityAttributes {
717
+ return {
718
+ expanded: this._open,
719
+ controls: this.popoverId,
720
+ hasPopup: this.listboxRole,
721
+ ariaLabel: this.iconAccessibleNameText,
722
+ };
723
+ }
724
+
725
+ get popoverId(): string {
726
+ return `${this._id}_udex-select-box__dropdown`;
727
+ }
728
+
729
+ get listboxRole(): string {
730
+ return "listbox";
731
+ }
732
+
711
733
  static get searchableListBaseTemplate() {
712
734
  return SearchableListBaseTemplate;
713
735
  }
package/src/Tab.ts CHANGED
@@ -7,7 +7,7 @@ import executeTemplate from "@ui5/webcomponents-base/dist/renderer/executeTempla
7
7
  import I18nBundle, { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
8
8
  import TabNavigation from "./TabNavigation.js";
9
9
  import UDExBadge from "./Badge.js";
10
-
10
+ import { Target } from "./types/common.js";
11
11
  import TabTemplate from "./generated/templates/TabTemplate.lit.js";
12
12
  import TabHeaderTemplate from "./generated/templates/TabHeaderTemplate.lit.js";
13
13
  import TabInOverflowTemplate from "./generated/templates/TabInOverflowTemplate.lit.js";
@@ -16,13 +16,6 @@ import { ATTENTION_BADGE } from "./generated/i18n/i18n-defaults.js";
16
16
  // Styles
17
17
  import TabInOverflowCss from "./generated/themes/TabInOverflow.css.js";
18
18
 
19
- export enum Target {
20
- _blank = "_blank",
21
- _parent = "_parent",
22
- _self = "_self",
23
- _top = "_top",
24
- }
25
-
26
19
  interface ITab extends UI5Element {
27
20
  getTabInHeaderDomRef: () => ITab | null;
28
21
  disabled?: boolean;
package/src/TagGroup.hbs CHANGED
@@ -25,24 +25,24 @@
25
25
 
26
26
  {{#*inline "TAG"}}
27
27
  <udex-tag
28
- role="{{../tagRole}}"
29
- accessible-role="option"
30
- class="udex-tag-group__tag"
31
- data-id="{{this.id}}"
32
- part="token-{{@index}}"
33
- ?read-only="{{../isReadOrDisplayOnly}}"
34
- tabindex="{{../tagTabIndex}}"
35
- id="{{_id}}-tag-group-tag"
36
- text="{{this.text}}"
37
- icon="{{this.icon}}"
38
- href="{{this.href}}"
39
- design="{{this.design}}"
40
- size="{{this.size}}"
41
- icon-placement="{{this.iconPlacement}}"
42
- accessible-name="{{this.accessibleName}}"
43
- ?non-selectable="{{this.nonSelectable}}"
44
- ?data-overflows="{{this.overflows}}"
45
- @keydown="{{../handleTagKeyDown}}"
46
- @ui5-iconClick="{{../tagIconClickHandler}}">
47
- ></udex-tag>
28
+ role="{{../tagRole}}"
29
+ accessible-role="option"
30
+ class="udex-tag-group__tag"
31
+ data-id="{{this.id}}"
32
+ part="token-{{@index}}"
33
+ ?read-only="{{../isReadOrDisplayOnly}}"
34
+ tabindex="{{../tagTabIndex}}"
35
+ id="{{_id}}-tag-group-tag"
36
+ text="{{this.text}}"
37
+ icon="{{this.icon}}"
38
+ href="{{this.href}}"
39
+ design="{{this.design}}"
40
+ size="{{this.size}}"
41
+ icon-placement="{{this.iconPlacement}}"
42
+ accessible-name="{{this.accessibleName}}"
43
+ ?non-selectable="{{this.nonSelectable}}"
44
+ ?data-overflows="{{this.overflows}}"
45
+ @keydown="{{../handleTagKeyDown}}"
46
+ @ui5-iconClick="{{../tagIconClickHandler}}">
47
+ </udex-tag>
48
48
  {{/inline}}
package/src/Tile.hbs CHANGED
@@ -1,17 +1,18 @@
1
1
  {{#if interactive}}
2
2
  <a
3
3
  class="udex-tile"
4
+ part="tile"
4
5
  href="{{href}}"
5
6
  target="{{target}}"
6
7
  aria-label="{{accessibleName}}"
7
8
  @keydown={{_onkeydown}}
8
- @click={{_onclick}}
9
- >
9
+ @click={{_onclick}}>
10
10
  <slot></slot>
11
11
  </a>
12
12
  {{else}}
13
13
  <div
14
14
  class="udex-tile"
15
+ part="tile"
15
16
  @click={{_onclick}}>
16
17
  <slot></slot>
17
18
  </div>
package/src/Upload.hbs ADDED
@@ -0,0 +1,21 @@
1
+ <div @ui5-request-delete="{{handleRemoveFile}}" class="udex-upload__wrapper">
2
+ {{#if uploadTitle}}
3
+ <h1 class="udex-upload__title">{{uploadTitle}}</h1>
4
+ {{/if}}
5
+ {{#if additionalText}}
6
+ <p class="udex-upload__additional-text">{{additionalText}}</p>
7
+ {{/if}}
8
+ <div class="udex-upload__upload-button-container">
9
+ <ui5-file-uploader id="fileUploader" hide-input accept="{{accept}}" ?multiple="{{multiple}}" @change="{{handleUploadFile}}" @click="{{handleUploadClick}}">
10
+ <udex-button design="Secondary" aria-label="{{uploadButtonAriaLabel}}" size="{{_buttonSize}}">{{uploadButtonText}}</udex-button>
11
+ </ui5-file-uploader>
12
+ {{#if _filesFull}}
13
+ <p class="udex-upload__error">{{errorText}}</p>
14
+ {{/if}}
15
+ </div>
16
+ <div class="udex-upload__files-wrapper">
17
+ <udex-list aria-busy="{{listBusy}}" mode="MultiSelect" @ui5-selection-change="{{handleSelectionChange}}">
18
+ <slot></slot>
19
+ </udex-list>
20
+ </div>
21
+ </div>
package/src/Upload.ts ADDED
@@ -0,0 +1,273 @@
1
+ import UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
2
+
3
+ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
4
+ import property from "@ui5/webcomponents-base/dist/decorators/property.js";
5
+ import { event, slot } from "@ui5/webcomponents-base/dist/decorators.js";
6
+ import ResizeHandler, { ResizeObserverCallback } from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
7
+ import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
8
+
9
+ import Integer from "@ui5/webcomponents-base/dist/types/Integer.js";
10
+ import FileUploader from "@ui5/webcomponents/dist/FileUploader.js";
11
+ import I18nBundle, { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
12
+ import { UPLOAD_BUTTON_LABEL } from "./generated/i18n/i18n-defaults.js";
13
+ import UDExButton from "./Button.js";
14
+ import UDExButtonSize from "./types/ButtonSize.js";
15
+ import UDExList from "./List.js";
16
+ import UDExUploadItem from "./UploadItem.js";
17
+ import UploadTemplate from "./generated/templates/UploadTemplate.lit.js";
18
+ import FileData from "./types/FileData.js";
19
+
20
+ // Styles
21
+ import UploadCss from "./generated/themes/Upload.css.js";
22
+
23
+ const convertBytesToMegabytes = (bytes: number) => (bytes / 1024) / 1024;
24
+ const BreakpointSizeS: number = 979;
25
+
26
+ /**
27
+ * @class
28
+ *
29
+ * <h3 class="comment-api-title">Overview</h3>
30
+ *
31
+ *
32
+ * <h3>Usage</h3>
33
+ *
34
+ * For the <code>udex-upload</code>
35
+ * <h3>ES6 Module Import</h3>
36
+ *
37
+ * <code>import "@udex/web-components/dist/Upload.js";</code>
38
+ *
39
+ * @constructor
40
+ * @extends UI5Element
41
+ * @public
42
+ */
43
+ @customElement({
44
+ tag: "udex-upload",
45
+ renderer: litRender,
46
+ styles: UploadCss,
47
+ template: UploadTemplate,
48
+ dependencies: [FileUploader, UDExList, UDExButton, UDExUploadItem],
49
+ })
50
+
51
+ /**
52
+ * Triggered when the uploaded file exceeds the maximum allowed size.
53
+ *
54
+ * @public
55
+ */
56
+ @event("file-size-exceed", {
57
+ detail:
58
+ {
59
+ files:
60
+ { type: Array },
61
+ },
62
+ })
63
+
64
+ /**
65
+ * Triggered when the user deletes the uploaded item.
66
+ *
67
+ * @public
68
+ */
69
+ @event("file-delete", {
70
+ detail:
71
+ {
72
+ file:
73
+ { type: UDExUploadItem },
74
+ },
75
+ })
76
+
77
+ /**
78
+ * Triggered when the user uploads the item.
79
+ *
80
+ * @public
81
+ */
82
+ @event("file-change", {
83
+ detail:
84
+ {
85
+ files:
86
+ { type: Array },
87
+ },
88
+ })
89
+
90
+ class UDExUpload extends UI5Element {
91
+ /**
92
+ * Defines the title of the upload.
93
+ *
94
+ * @public
95
+ */
96
+ @property({ type: String })
97
+ uploadTitle!: string;
98
+
99
+ /**
100
+ * Defines the error message shown when more than one file is uploaded with multiple set to false.
101
+ *
102
+ * @public
103
+ */
104
+ @property({ type: String })
105
+ errorText!: string;
106
+
107
+ /**
108
+ * Defines if uploader is required.
109
+ *
110
+ * @public
111
+ */
112
+ @property({ type: Boolean })
113
+ required!: boolean;
114
+
115
+ /**
116
+ * Defines if uploading multiple files is allowed.
117
+ *
118
+ * @public
119
+ */
120
+ @property({ type: Boolean })
121
+ multiple!: boolean;
122
+
123
+ /**
124
+ * Defines the acceptable file formats for uploading.
125
+ *
126
+ * @public
127
+ */
128
+ @property({ type: String })
129
+ accept!: string;
130
+
131
+ /**
132
+ * Defines the maximum allowed size of the file for uploading.
133
+ *
134
+ * @default undefined
135
+ * @public
136
+ */
137
+ @property({ type: Number, validator: Integer })
138
+ maxFileSize!: number;
139
+
140
+ /**
141
+ * Defines the additional text below the title of the upload.
142
+ *
143
+ * @public
144
+ */
145
+ @property({ type: String })
146
+ additionalText!: string;
147
+
148
+ /**
149
+ * Defines the text in the upload button.
150
+ *
151
+ * @public
152
+ */
153
+ @property({ type: String })
154
+ uploadButtonText!: string;
155
+
156
+ /**
157
+ * Defines if a file is already uploaded when multiple is false.
158
+ *
159
+ * @private
160
+ */
161
+ @property({ type: Boolean })
162
+ _filesFull: boolean = false;
163
+
164
+ /**
165
+ * Defines the uploaded files.
166
+ *
167
+ * @public
168
+ */
169
+ @slot({ type: HTMLElement, "default": true })
170
+ items!: Array<UDExUploadItem>;
171
+
172
+ /**
173
+ * Defines the percentage of the upload.
174
+ *
175
+ * @default "Large"
176
+ * @private
177
+ */
178
+ @property({ type: String, defaultValue: UDExButtonSize.Large })
179
+ _buttonSize!: `${UDExButtonSize}`;
180
+
181
+ static i18nBundle: I18nBundle;
182
+ _handleResizeBound: ResizeObserverCallback;
183
+
184
+ static async onDefine() {
185
+ UDExUpload.i18nBundle = await getI18nBundle("@udex/web-components");
186
+ }
187
+
188
+ constructor() {
189
+ super();
190
+ this._handleResizeBound = this._handleResize.bind(this);
191
+ }
192
+
193
+ onEnterDOM(): void {
194
+ ResizeHandler.register(this, this._handleResizeBound);
195
+ }
196
+
197
+ onExitDOM(): void {
198
+ ResizeHandler.deregister(this, this._handleResizeBound);
199
+ }
200
+
201
+ onAfterRendering(): void {
202
+ if (this._filesFull) {
203
+ this._filesFull = this.fileNumberExceeded;
204
+ }
205
+ }
206
+
207
+ handleUploadClick(e: Event) {
208
+ this._filesFull = this.fileNumberExceeded;
209
+ if (this.fileNumberExceeded) {
210
+ e.preventDefault();
211
+ }
212
+ }
213
+
214
+ handleUploadFile(e: Event) {
215
+ const newFiles = (e.target as HTMLInputElement).files;
216
+
217
+ if (!newFiles?.length || this.fileNumberExceeded) {
218
+ e.stopPropagation();
219
+ }
220
+
221
+ const exceededFilesData = this.maxFileSize ? this._getExceededFiles(newFiles!) : [];
222
+ if (exceededFilesData.length) {
223
+ e.stopPropagation();
224
+ this.fireEvent("file-size-exceed", {
225
+ files: exceededFilesData,
226
+ });
227
+ }
228
+ }
229
+
230
+ handleSelectionChange(e: CustomEvent) {
231
+ this.fireEvent("file-change", { files: e.detail.listItems as UDExUploadItem[] });
232
+ }
233
+
234
+ _handleResize() {
235
+ this._buttonSize = window.innerWidth <= BreakpointSizeS ? UDExButtonSize.Medium : UDExButtonSize.Large;
236
+ }
237
+
238
+ handleRemoveFile(e: CustomEvent) {
239
+ this.fireEvent("file-delete", { file: e.target as UDExUploadItem });
240
+ }
241
+
242
+ _getExceededFiles(files: FileList): Array<FileData> {
243
+ const filesArray = Array.from(files);
244
+ const exceededFiles: Array<FileData> = [];
245
+
246
+ for (let i = 0; i < filesArray.length; i++) {
247
+ const fileSize = convertBytesToMegabytes(filesArray[i].size);
248
+ if (fileSize > this.maxFileSize) {
249
+ exceededFiles.push({
250
+ fileName: filesArray[i].name,
251
+ fileSize,
252
+ });
253
+ }
254
+ }
255
+ return exceededFiles;
256
+ }
257
+
258
+ get uploadButtonAriaLabel(): string {
259
+ return UDExUpload.i18nBundle.getText(UPLOAD_BUTTON_LABEL);
260
+ }
261
+
262
+ get listBusy(): boolean {
263
+ return !this.items.length;
264
+ }
265
+
266
+ get fileNumberExceeded(): boolean {
267
+ return !this.multiple && this.items.length >= 1;
268
+ }
269
+ }
270
+
271
+ UDExUpload.define();
272
+
273
+ export default UDExUpload;
@@ -0,0 +1,32 @@
1
+ <div class="udex-upload-item__wrapper">
2
+ <div class="udex-upload-item__info {{uploadItemClasses}}">
3
+ <div>
4
+ {{#if fileInteractive}}
5
+ <udex-link href="{{fileLink}}">{{fileName}}</udex-link>
6
+ {{else}}
7
+ <p class="udex-upload-item__name">{{fileName}}</p>
8
+ {{/if}}
9
+ <div class="{{additionalInfoClasses}}">
10
+ <slot></slot>
11
+ </div>
12
+ </div>
13
+ {{#if _breakpointM}}
14
+ {{> deleteButton}}
15
+ {{/if}}
16
+ </div>
17
+ <div class="udex-upload-item__progress-info-wrapper">
18
+ {{#if showUploadProgress}}
19
+ <div class="udex-upload-item__progress-info">
20
+ <udex-progress-bar role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="{{uploadPercentage}}" value="{{uploadPercentage}}" value-state="{{uploadProgressState}}" hide-value></udex-progress-bar>
21
+ <p class="udex-upload-item__progress-status">{{uploadStatus}}</p>
22
+ </div>
23
+ {{/if}}
24
+ {{#if _breakpointL}}
25
+ {{> deleteButton}}
26
+ {{/if}}
27
+ </div>
28
+ </div>
29
+
30
+ {{#*inline deleteButton}}
31
+ <udex-button accessible-name="{{removeButtonAccessibleName}}" @keydown="{{handleButtonKeydown}}" @click="{{handleButtonClick}}" size="{{_buttonSize}}" icon="decline" design="Tertiary"></udex-button>
32
+ {{/inline}}
@@ -0,0 +1,218 @@
1
+ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
2
+ import property from "@ui5/webcomponents-base/dist/decorators/property.js";
3
+ import { slot } from "@ui5/webcomponents-base/dist/decorators.js";
4
+ import ResizeHandler, { ResizeObserverCallback } from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
5
+ import litRender from "@ui5/webcomponents-base/dist/renderer/LitRenderer.js";
6
+
7
+ import Integer from "@ui5/webcomponents-base/dist/types/Integer.js";
8
+ import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js";
9
+ import I18nBundle, { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
10
+ import { isEnter, isSpace } from "@ui5/webcomponents-base/dist/Keys.js";
11
+ import {
12
+ REMOVE_FILE_TEXT,
13
+ TERMINATED_FILE_STATUS_TEXT, UPLOADING_FILE_STATUS_TEXT,
14
+ } from "./generated/i18n/i18n-defaults.js";
15
+ import UDExListItem from "./ListItem.js";
16
+ import UDExProgressBar from "./ProgressBar.js";
17
+ import UDExLink from "./Link.js";
18
+ import UDExButton from "./Button.js";
19
+ import UDExButtonSize from "./types/ButtonSize.js";
20
+ import UploadItemTemplate from "./generated/templates/UploadItemTemplate.lit.js";
21
+
22
+ // Styles
23
+ import UploadItemCss from "./generated/themes/UploadItem.css.js";
24
+ import FileUploadState from "./types/FileUploadState.js";
25
+
26
+ const BreakpointSizeS: number = 979;
27
+ const BreakpointSizeM: number = 1279;
28
+
29
+ /**
30
+ * @class
31
+ *
32
+ * <h3 class="comment-api-title">Overview</h3>
33
+ *
34
+ *
35
+ * <h3>Usage</h3>
36
+ *
37
+ * For the <code>udex-upload-item</code>
38
+ * <h3>ES6 Module Import</h3>
39
+ *
40
+ * <code>import "@udex/web-components/dist/UploadItem.js";</code>
41
+ *
42
+ * @constructor
43
+ * @extends UDExListItemBase
44
+ * @public
45
+ */
46
+ @customElement({
47
+ tag: "udex-upload-item",
48
+ renderer: litRender,
49
+ styles: UploadItemCss,
50
+ template: UploadItemTemplate,
51
+ dependencies: [UDExLink, UDExListItem, UDExProgressBar, UDExButton],
52
+ })
53
+
54
+ class UDExUploadItem extends UDExListItem {
55
+ /**
56
+ * Defines the name of the uploaded file.
57
+ *
58
+ * @default ""
59
+ * @public
60
+ */
61
+ @property({ type: String })
62
+ fileName!: string;
63
+
64
+ /**
65
+ * Defines the link of the uploaded file.
66
+ *
67
+ * @default undefined
68
+ * @public
69
+ */
70
+ @property({ type: String })
71
+ fileLink?: string;
72
+
73
+ /**
74
+ * Defines the percentage of the upload.
75
+ *
76
+ * @default 0
77
+ * @public
78
+ */
79
+ @property({ type: Number, validator: Integer })
80
+ uploadPercentage!: number;
81
+
82
+ /**
83
+ * Defines the percentage of the upload.
84
+ *
85
+ * @default 0
86
+ * @public
87
+ */
88
+ @property({ type: FileUploadState, defaultValue: FileUploadState.Uploaded })
89
+ uploadState!: `${FileUploadState}`;
90
+
91
+ /**
92
+ * Slot for information about the uploaded file.
93
+ *
94
+ * @slot
95
+ * @public
96
+ */
97
+ @slot({ type: HTMLElement, "default": true }) uploadInfo!: Array<HTMLElement>;
98
+
99
+ /**
100
+ * Defines the percentage of the upload.
101
+ *
102
+ * @default "Large"
103
+ * @private
104
+ */
105
+ @property({ type: UDExButtonSize })
106
+ _buttonSize!: `${UDExButtonSize}`;
107
+
108
+ /**
109
+ * Defines if the screen is at the M breakpoint.
110
+ *
111
+ * @default false
112
+ * @private
113
+ */
114
+ @property({ type: Boolean })
115
+ _breakpointM!: boolean;
116
+
117
+ /**
118
+ * Defines if the screen is at the L breakpoint.
119
+ *
120
+ * @default false
121
+ * @private
122
+ */
123
+ @property({ type: Boolean })
124
+ _breakpointL!: boolean;
125
+
126
+ static i18nBundle: I18nBundle;
127
+ _handleResizeBound: ResizeObserverCallback;
128
+
129
+ static async onDefine() {
130
+ UDExUploadItem.i18nBundle = await getI18nBundle("@udex/web-components");
131
+ }
132
+
133
+ constructor() {
134
+ super();
135
+ this._handleResizeBound = this._handleResize.bind(this);
136
+ }
137
+
138
+ onEnterDOM(): void {
139
+ ResizeHandler.register(this, this._handleResizeBound);
140
+ this.fireEvent("item-press", {
141
+ selected: false,
142
+ item: this,
143
+ });
144
+ }
145
+
146
+ onExitDOM(): void {
147
+ ResizeHandler.deregister(this, this._handleResizeBound);
148
+ }
149
+
150
+ onAfterRendering(): void {
151
+ const fileLink = this.fileLinkComponent;
152
+ if (fileLink) {
153
+ fileLink._setCustomAttributes([{ attribute: "download", value: "true" }]);
154
+ }
155
+ }
156
+
157
+ handleButtonClick(e: Event) {
158
+ e.stopImmediatePropagation();
159
+ this.fireEvent("request-delete");
160
+ }
161
+
162
+ handleButtonKeydown(e: KeyboardEvent) {
163
+ if (isEnter(e) || isSpace(e)) {
164
+ e.stopImmediatePropagation();
165
+ this.fireEvent("request-delete");
166
+ }
167
+ }
168
+
169
+ _handleResize() {
170
+ this._buttonSize = window.innerWidth <= BreakpointSizeS ? UDExButtonSize.Medium : UDExButtonSize.Large;
171
+ this._breakpointL = window.innerWidth > BreakpointSizeM;
172
+ this._breakpointM = !this._breakpointL ? true : !this._breakpointL && this.uploadState === FileUploadState.Uploaded;
173
+ }
174
+
175
+ get fileLinkComponent(): UDExLink {
176
+ return this.shadowRoot!.querySelector<UDExLink>("[udex-link]")!;
177
+ }
178
+
179
+ get removeButtonAccessibleName(): string {
180
+ return UDExUploadItem.i18nBundle.getText(REMOVE_FILE_TEXT);
181
+ }
182
+
183
+ get showUploadProgress(): boolean {
184
+ return this.uploadState === FileUploadState.Error || this.uploadState === FileUploadState.Uploading;
185
+ }
186
+
187
+ get uploadProgressState(): ValueState {
188
+ if (this.uploadState === FileUploadState.Uploading) {
189
+ return ValueState.Information;
190
+ }
191
+
192
+ return ValueState.Error;
193
+ }
194
+
195
+ get uploadStatus(): string {
196
+ if (this.uploadState === FileUploadState.Uploading) {
197
+ return `${UDExUploadItem.i18nBundle.getText(UPLOADING_FILE_STATUS_TEXT)} ${this.uploadPercentage}%`;
198
+ }
199
+
200
+ return `${UDExUploadItem.i18nBundle.getText(TERMINATED_FILE_STATUS_TEXT)} ${this.uploadPercentage}%`;
201
+ }
202
+
203
+ get fileInteractive(): boolean {
204
+ return this.uploadState === FileUploadState.Uploaded;
205
+ }
206
+
207
+ get additionalInfoClasses(): string {
208
+ return `udex-upload-item__info ${this.uploadState === FileUploadState.Error ? "udex-upload-item__error" : ""}`;
209
+ }
210
+
211
+ get uploadItemClasses(): string {
212
+ return this.uploadState === "Uploaded" ? "udex-upload-item__info-uploaded" : "";
213
+ }
214
+ }
215
+
216
+ UDExUploadItem.define();
217
+
218
+ export default UDExUploadItem;
@@ -161,7 +161,7 @@ class Suggestion {
161
161
  }
162
162
  if (this.focusabledList && this.selectedItemIndex >= 0) {
163
163
  const focusabledItems = this.getFocusableItems();
164
- const button = focusabledItems[this.selectedItemIndex].querySelector("[ui5-button]") as UI5Element;
164
+ const button = focusabledItems[this.selectedItemIndex] as UI5Element;
165
165
 
166
166
  button.focus();
167
167
  return true;