@atlaskit/smart-card 18.0.16 → 18.0.19

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 (182) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/client/package.json +1 -0
  3. package/dist/cjs/i18n/cs.js +43 -0
  4. package/dist/cjs/i18n/da.js +43 -0
  5. package/dist/cjs/i18n/de.js +43 -0
  6. package/dist/cjs/i18n/en.js +43 -0
  7. package/dist/cjs/i18n/en_GB.js +43 -0
  8. package/dist/cjs/i18n/en_ZZ.js +43 -0
  9. package/dist/cjs/i18n/es.js +43 -0
  10. package/dist/cjs/i18n/et.js +16 -0
  11. package/dist/cjs/i18n/fi.js +43 -0
  12. package/dist/cjs/i18n/fr.js +43 -0
  13. package/dist/cjs/i18n/hu.js +43 -0
  14. package/dist/cjs/i18n/it.js +43 -0
  15. package/dist/cjs/i18n/ja.js +43 -0
  16. package/dist/cjs/i18n/ko.js +43 -0
  17. package/dist/cjs/i18n/nb.js +43 -0
  18. package/dist/cjs/i18n/nl.js +43 -0
  19. package/dist/cjs/i18n/pl.js +43 -0
  20. package/dist/cjs/i18n/pt_BR.js +43 -0
  21. package/dist/cjs/i18n/pt_PT.js +16 -0
  22. package/dist/cjs/i18n/ru.js +43 -0
  23. package/dist/cjs/i18n/sk.js +16 -0
  24. package/dist/cjs/i18n/sv.js +43 -0
  25. package/dist/cjs/i18n/th.js +43 -0
  26. package/dist/cjs/i18n/tr.js +43 -0
  27. package/dist/cjs/i18n/uk.js +43 -0
  28. package/dist/cjs/i18n/vi.js +43 -0
  29. package/dist/cjs/i18n/zh.js +43 -0
  30. package/dist/cjs/i18n/zh_TW.js +43 -0
  31. package/dist/cjs/state/actions/index.js +1 -1
  32. package/dist/cjs/utils/token.js +1 -0
  33. package/dist/cjs/version.json +1 -1
  34. package/dist/cjs/view/FlexibleCard/components/blocks/action-group/index.js +3 -1
  35. package/dist/cjs/view/FlexibleCard/components/blocks/title-block/errored/index.js +4 -2
  36. package/dist/cjs/view/FlexibleCard/components/blocks/title-block/index.js +1 -1
  37. package/dist/cjs/view/FlexibleCard/components/blocks/title-block/resolving/index.js +11 -25
  38. package/dist/cjs/view/FlexibleCard/components/blocks/utils.js +1 -1
  39. package/dist/cjs/view/FlexibleCard/components/common/image-icon/index.js +4 -11
  40. package/dist/cjs/view/FlexibleCard/components/common/loading-skeleton/index.js +32 -0
  41. package/dist/cjs/view/FlexibleCard/components/common/loading-skeleton/types.js +5 -0
  42. package/dist/cjs/view/FlexibleCard/components/container/index.js +66 -23
  43. package/dist/cjs/view/FlexibleCard/components/container/layered-link/index.js +37 -0
  44. package/dist/cjs/view/FlexibleCard/components/container/layered-link/types.js +5 -0
  45. package/dist/cjs/view/FlexibleCard/components/elements/avatar-group/index.js +1 -0
  46. package/dist/cjs/view/FlexibleCard/components/elements/icon/index.js +1 -18
  47. package/dist/cjs/view/FlexibleCard/components/utils.js +20 -1
  48. package/dist/cjs/view/FlexibleCard/index.js +2 -2
  49. package/dist/es2019/i18n/cs.js +35 -0
  50. package/dist/es2019/i18n/da.js +35 -0
  51. package/dist/es2019/i18n/de.js +35 -0
  52. package/dist/es2019/i18n/en.js +35 -0
  53. package/dist/es2019/i18n/en_GB.js +35 -0
  54. package/dist/es2019/i18n/en_ZZ.js +35 -0
  55. package/dist/es2019/i18n/es.js +35 -0
  56. package/dist/es2019/i18n/et.js +8 -0
  57. package/dist/es2019/i18n/fi.js +35 -0
  58. package/dist/es2019/i18n/fr.js +35 -0
  59. package/dist/es2019/i18n/hu.js +35 -0
  60. package/dist/es2019/i18n/it.js +35 -0
  61. package/dist/es2019/i18n/ja.js +35 -0
  62. package/dist/es2019/i18n/ko.js +35 -0
  63. package/dist/es2019/i18n/nb.js +35 -0
  64. package/dist/es2019/i18n/nl.js +35 -0
  65. package/dist/es2019/i18n/pl.js +35 -0
  66. package/dist/es2019/i18n/pt_BR.js +35 -0
  67. package/dist/es2019/i18n/pt_PT.js +8 -0
  68. package/dist/es2019/i18n/ru.js +35 -0
  69. package/dist/es2019/i18n/sk.js +8 -0
  70. package/dist/es2019/i18n/sv.js +35 -0
  71. package/dist/es2019/i18n/th.js +35 -0
  72. package/dist/es2019/i18n/tr.js +35 -0
  73. package/dist/es2019/i18n/uk.js +35 -0
  74. package/dist/es2019/i18n/vi.js +35 -0
  75. package/dist/es2019/i18n/zh.js +35 -0
  76. package/dist/es2019/i18n/zh_TW.js +35 -0
  77. package/dist/es2019/state/actions/index.js +1 -1
  78. package/dist/es2019/utils/token.js +1 -0
  79. package/dist/es2019/version.json +1 -1
  80. package/dist/es2019/view/FlexibleCard/components/blocks/action-group/index.js +13 -0
  81. package/dist/es2019/view/FlexibleCard/components/blocks/title-block/errored/index.js +6 -1
  82. package/dist/es2019/view/FlexibleCard/components/blocks/title-block/index.js +4 -5
  83. package/dist/es2019/view/FlexibleCard/components/blocks/title-block/resolving/index.js +10 -25
  84. package/dist/es2019/view/FlexibleCard/components/blocks/utils.js +0 -1
  85. package/dist/es2019/view/FlexibleCard/components/common/image-icon/index.js +4 -31
  86. package/dist/es2019/view/FlexibleCard/components/common/loading-skeleton/index.js +39 -0
  87. package/dist/es2019/view/FlexibleCard/components/common/loading-skeleton/types.js +1 -0
  88. package/dist/es2019/view/FlexibleCard/components/container/index.js +59 -10
  89. package/dist/es2019/view/FlexibleCard/components/container/layered-link/index.js +54 -0
  90. package/dist/es2019/view/FlexibleCard/components/container/layered-link/types.js +1 -0
  91. package/dist/es2019/view/FlexibleCard/components/elements/avatar-group/index.js +1 -0
  92. package/dist/es2019/view/FlexibleCard/components/elements/icon/index.js +2 -19
  93. package/dist/es2019/view/FlexibleCard/components/utils.js +16 -0
  94. package/dist/es2019/view/FlexibleCard/index.js +2 -2
  95. package/dist/esm/i18n/cs.js +35 -0
  96. package/dist/esm/i18n/da.js +35 -0
  97. package/dist/esm/i18n/de.js +35 -0
  98. package/dist/esm/i18n/en.js +35 -0
  99. package/dist/esm/i18n/en_GB.js +35 -0
  100. package/dist/esm/i18n/en_ZZ.js +35 -0
  101. package/dist/esm/i18n/es.js +35 -0
  102. package/dist/esm/i18n/et.js +8 -0
  103. package/dist/esm/i18n/fi.js +35 -0
  104. package/dist/esm/i18n/fr.js +35 -0
  105. package/dist/esm/i18n/hu.js +35 -0
  106. package/dist/esm/i18n/it.js +35 -0
  107. package/dist/esm/i18n/ja.js +35 -0
  108. package/dist/esm/i18n/ko.js +35 -0
  109. package/dist/esm/i18n/nb.js +35 -0
  110. package/dist/esm/i18n/nl.js +35 -0
  111. package/dist/esm/i18n/pl.js +35 -0
  112. package/dist/esm/i18n/pt_BR.js +35 -0
  113. package/dist/esm/i18n/pt_PT.js +8 -0
  114. package/dist/esm/i18n/ru.js +35 -0
  115. package/dist/esm/i18n/sk.js +8 -0
  116. package/dist/esm/i18n/sv.js +35 -0
  117. package/dist/esm/i18n/th.js +35 -0
  118. package/dist/esm/i18n/tr.js +35 -0
  119. package/dist/esm/i18n/uk.js +35 -0
  120. package/dist/esm/i18n/vi.js +35 -0
  121. package/dist/esm/i18n/zh.js +35 -0
  122. package/dist/esm/i18n/zh_TW.js +35 -0
  123. package/dist/esm/state/actions/index.js +1 -1
  124. package/dist/esm/utils/token.js +1 -0
  125. package/dist/esm/version.json +1 -1
  126. package/dist/esm/view/FlexibleCard/components/blocks/action-group/index.js +2 -1
  127. package/dist/esm/view/FlexibleCard/components/blocks/title-block/errored/index.js +4 -2
  128. package/dist/esm/view/FlexibleCard/components/blocks/title-block/index.js +1 -1
  129. package/dist/esm/view/FlexibleCard/components/blocks/title-block/resolving/index.js +10 -25
  130. package/dist/esm/view/FlexibleCard/components/blocks/utils.js +1 -1
  131. package/dist/esm/view/FlexibleCard/components/common/image-icon/index.js +4 -11
  132. package/dist/esm/view/FlexibleCard/components/common/loading-skeleton/index.js +20 -0
  133. package/dist/esm/view/FlexibleCard/components/common/loading-skeleton/types.js +1 -0
  134. package/dist/esm/view/FlexibleCard/components/container/index.js +57 -23
  135. package/dist/esm/view/FlexibleCard/components/container/layered-link/index.js +26 -0
  136. package/dist/esm/view/FlexibleCard/components/container/layered-link/types.js +1 -0
  137. package/dist/esm/view/FlexibleCard/components/elements/avatar-group/index.js +1 -0
  138. package/dist/esm/view/FlexibleCard/components/elements/icon/index.js +2 -19
  139. package/dist/esm/view/FlexibleCard/components/utils.js +16 -0
  140. package/dist/esm/view/FlexibleCard/index.js +2 -2
  141. package/dist/types/i18n/cs.d.ts +35 -0
  142. package/dist/types/i18n/da.d.ts +35 -0
  143. package/dist/types/i18n/de.d.ts +35 -0
  144. package/dist/types/i18n/en.d.ts +35 -0
  145. package/dist/types/i18n/en_GB.d.ts +35 -0
  146. package/dist/types/i18n/en_ZZ.d.ts +35 -0
  147. package/dist/types/i18n/es.d.ts +35 -0
  148. package/dist/types/i18n/et.d.ts +8 -0
  149. package/dist/types/i18n/fi.d.ts +35 -0
  150. package/dist/types/i18n/fr.d.ts +35 -0
  151. package/dist/types/i18n/hu.d.ts +35 -0
  152. package/dist/types/i18n/it.d.ts +35 -0
  153. package/dist/types/i18n/ja.d.ts +35 -0
  154. package/dist/types/i18n/ko.d.ts +35 -0
  155. package/dist/types/i18n/nb.d.ts +35 -0
  156. package/dist/types/i18n/nl.d.ts +35 -0
  157. package/dist/types/i18n/pl.d.ts +35 -0
  158. package/dist/types/i18n/pt_BR.d.ts +35 -0
  159. package/dist/types/i18n/pt_PT.d.ts +8 -0
  160. package/dist/types/i18n/ru.d.ts +35 -0
  161. package/dist/types/i18n/sk.d.ts +8 -0
  162. package/dist/types/i18n/sv.d.ts +35 -0
  163. package/dist/types/i18n/th.d.ts +35 -0
  164. package/dist/types/i18n/tr.d.ts +35 -0
  165. package/dist/types/i18n/uk.d.ts +35 -0
  166. package/dist/types/i18n/vi.d.ts +35 -0
  167. package/dist/types/i18n/zh.d.ts +35 -0
  168. package/dist/types/i18n/zh_TW.d.ts +35 -0
  169. package/dist/types/utils/token.d.ts +1 -0
  170. package/dist/types/view/FlexibleCard/components/common/loading-skeleton/index.d.ts +5 -0
  171. package/dist/types/view/FlexibleCard/components/common/loading-skeleton/types.d.ts +3 -0
  172. package/dist/types/view/FlexibleCard/components/container/index.d.ts +1 -1
  173. package/dist/types/view/FlexibleCard/components/container/layered-link/index.d.ts +5 -0
  174. package/dist/types/view/FlexibleCard/components/container/layered-link/types.d.ts +6 -0
  175. package/dist/types/view/FlexibleCard/components/container/types.d.ts +1 -0
  176. package/dist/types/view/FlexibleCard/components/utils.d.ts +1 -0
  177. package/dist/types/view/FlexibleCard/types.d.ts +1 -0
  178. package/hooks/package.json +1 -0
  179. package/in-product/package.json +1 -0
  180. package/package.json +1 -1
  181. package/ssr/package.json +1 -0
  182. package/types/package.json +1 -0
@@ -0,0 +1,35 @@
1
+ /**
2
+ * NOTE:
3
+ *
4
+ * This file is automatically generated by Traduki 2.0.
5
+ * DO NOT CHANGE IT BY HAND or your changes will be lost.
6
+ */
7
+ //Ukrainian (Ukraine)
8
+ export default {
9
+ 'fabric.linking.cannot_connect': 'Не вдається підключитися, спробуйте ще раз',
10
+ 'fabric.linking.cannot_find_link': 'Не вдається знайти посилання',
11
+ 'fabric.linking.click_to_join': 'Можна приєднатися до {context}, щоб переглянути цю проблему',
12
+ 'fabric.linking.connect_link_account': 'Для перегляду потрібно підключитись',
13
+ 'fabric.linking.create_on': 'Створено {context}',
14
+ 'fabric.linking.created_by': 'Автор: {context}',
15
+ 'fabric.linking.delete': 'Видалити',
16
+ 'fabric.linking.edit': 'Редагувати',
17
+ 'fabric.linking.forbidden_access': 'У вас немає доступу',
18
+ 'fabric.linking.invalid_permissions': 'Посилання з обмеженим доступом; спробуйте інший обліковий запис',
19
+ 'fabric.linking.modified_on': 'Оновлено {context}',
20
+ 'fabric.linking.pending_request': 'Запит на надання доступу в очікуванні',
21
+ 'fabric.linking.priority_blocker': 'Блокувальний',
22
+ 'fabric.linking.priority_critical': 'Критичний',
23
+ 'fabric.linking.priority_high': 'Високий',
24
+ 'fabric.linking.priority_highest': 'Найвищий',
25
+ 'fabric.linking.priority_low': 'Низький',
26
+ 'fabric.linking.priority_lowest': 'Найнижчий',
27
+ 'fabric.linking.priority_major': 'Серйозний',
28
+ 'fabric.linking.priority_medium': 'Середній',
29
+ 'fabric.linking.priority_minor': 'Низький',
30
+ 'fabric.linking.priority_trivial': 'Звичайний',
31
+ 'fabric.linking.priority_undefined': 'Не визначено',
32
+ 'fabric.linking.request_access': 'Надішліть запит на доступ до {context}, щоб переглянути завдання',
33
+ 'fabric.linking.request_denied': 'Ваш запит на надання доступу відхилено',
34
+ 'fabric.linking.updated_by': 'Автор зміни: {context}'
35
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * NOTE:
3
+ *
4
+ * This file is automatically generated by Traduki 2.0.
5
+ * DO NOT CHANGE IT BY HAND or your changes will be lost.
6
+ */
7
+ //Vietnamese (Vietnam)
8
+ export default {
9
+ 'fabric.linking.cannot_connect': 'Không thể kết nối, hãy thử lại',
10
+ 'fabric.linking.cannot_find_link': 'Không tìm được liên kết',
11
+ 'fabric.linking.click_to_join': 'Tham gia {context} để xem vấn đề này',
12
+ 'fabric.linking.connect_link_account': 'Kết nối để xem trước',
13
+ 'fabric.linking.create_on': 'Đã tạo {context}',
14
+ 'fabric.linking.created_by': 'Được tạo bởi {context}',
15
+ 'fabric.linking.delete': 'Xóa',
16
+ 'fabric.linking.edit': 'Chỉnh sửa',
17
+ 'fabric.linking.forbidden_access': 'Quyền truy cập của bạn bị cấm',
18
+ 'fabric.linking.invalid_permissions': 'Liên kết bị hạn chế, thử một tài khoản khác',
19
+ 'fabric.linking.modified_on': 'Đã cập nhật {context}',
20
+ 'fabric.linking.pending_request': 'Đang chờ xử lý yêu cầu quyền truy cập của bạn',
21
+ 'fabric.linking.priority_blocker': 'Trở ngại',
22
+ 'fabric.linking.priority_critical': 'Rất cao',
23
+ 'fabric.linking.priority_high': 'Cao',
24
+ 'fabric.linking.priority_highest': 'Cao nhất',
25
+ 'fabric.linking.priority_low': 'Thấp',
26
+ 'fabric.linking.priority_lowest': 'Thấp nhất',
27
+ 'fabric.linking.priority_major': 'Lớn',
28
+ 'fabric.linking.priority_medium': 'Trung bình',
29
+ 'fabric.linking.priority_minor': 'Nhỏ',
30
+ 'fabric.linking.priority_trivial': 'Không đáng kể',
31
+ 'fabric.linking.priority_undefined': 'Chưa xác định',
32
+ 'fabric.linking.request_access': 'Yêu cầu quyền truy cập vào {context} để xem vấn đề này',
33
+ 'fabric.linking.request_denied': 'Yêu cầu quyền truy cập của bạn đã bị từ chối',
34
+ 'fabric.linking.updated_by': 'Được sửa đổi bởi {context}'
35
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * NOTE:
3
+ *
4
+ * This file is automatically generated by Traduki 2.0.
5
+ * DO NOT CHANGE IT BY HAND or your changes will be lost.
6
+ */
7
+ //Chinese (Simplified)
8
+ export default {
9
+ 'fabric.linking.cannot_connect': '无法连接,请重试',
10
+ 'fabric.linking.cannot_find_link': '未找到链接',
11
+ 'fabric.linking.click_to_join': '加入{context}以查看此事务',
12
+ 'fabric.linking.connect_link_account': '连接以预览',
13
+ 'fabric.linking.create_on': '{context}已创建',
14
+ 'fabric.linking.created_by': '创建者:{context}',
15
+ 'fabric.linking.delete': '删除',
16
+ 'fabric.linking.edit': '编辑',
17
+ 'fabric.linking.forbidden_access': '您的访问已被禁止',
18
+ 'fabric.linking.invalid_permissions': '受限链接,请尝试其他帐户',
19
+ 'fabric.linking.modified_on': '{context}已更新',
20
+ 'fabric.linking.pending_request': '您的访问请求正等待处理',
21
+ 'fabric.linking.priority_blocker': '阻止程序',
22
+ 'fabric.linking.priority_critical': '紧急',
23
+ 'fabric.linking.priority_high': '高',
24
+ 'fabric.linking.priority_highest': '最高',
25
+ 'fabric.linking.priority_low': '低',
26
+ 'fabric.linking.priority_lowest': '最低',
27
+ 'fabric.linking.priority_major': '重要',
28
+ 'fabric.linking.priority_medium': '中等',
29
+ 'fabric.linking.priority_minor': '次要',
30
+ 'fabric.linking.priority_trivial': '微小',
31
+ 'fabric.linking.priority_undefined': '未定义',
32
+ 'fabric.linking.request_access': '请求访问{context}以查看此事务',
33
+ 'fabric.linking.request_denied': '您的访问请求已被拒绝',
34
+ 'fabric.linking.updated_by': '修改者:{context}'
35
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * NOTE:
3
+ *
4
+ * This file is automatically generated by Traduki 2.0.
5
+ * DO NOT CHANGE IT BY HAND or your changes will be lost.
6
+ */
7
+ //Chinese (Traditional)
8
+ export default {
9
+ 'fabric.linking.cannot_connect': '無法連結,請再試一次',
10
+ 'fabric.linking.cannot_find_link': '找不到連結',
11
+ 'fabric.linking.click_to_join': '加入 {context} 以查看此議題',
12
+ 'fabric.linking.connect_link_account': '連線以預覽',
13
+ 'fabric.linking.create_on': '建立時間:{context}',
14
+ 'fabric.linking.created_by': '建立者:{context}',
15
+ 'fabric.linking.delete': '刪除',
16
+ 'fabric.linking.edit': '編輯',
17
+ 'fabric.linking.forbidden_access': '您的存取遭拒',
18
+ 'fabric.linking.invalid_permissions': '連結受到限制,請嘗試其他帳戶',
19
+ 'fabric.linking.modified_on': '更新時間:{context}',
20
+ 'fabric.linking.pending_request': '您的存取要求擱置中',
21
+ 'fabric.linking.priority_blocker': '封鎖程式',
22
+ 'fabric.linking.priority_critical': '重要',
23
+ 'fabric.linking.priority_high': '高',
24
+ 'fabric.linking.priority_highest': '最高',
25
+ 'fabric.linking.priority_low': '低',
26
+ 'fabric.linking.priority_lowest': '最低',
27
+ 'fabric.linking.priority_major': '主要',
28
+ 'fabric.linking.priority_medium': '中',
29
+ 'fabric.linking.priority_minor': '次要',
30
+ 'fabric.linking.priority_trivial': '不太重要',
31
+ 'fabric.linking.priority_undefined': '未定義',
32
+ 'fabric.linking.request_access': '要求存取 {context} 以檢視此議題',
33
+ 'fabric.linking.request_denied': '您的存取要求遭拒',
34
+ 'fabric.linking.updated_by': '修改者:{context}'
35
+ };
@@ -70,7 +70,7 @@ export const useSmartCardActions = (id, url, analytics) => {
70
70
  const nextStatus = response ? getStatus(response) : 'fatal'; // If we require authorization & do not have an authFlow available,
71
71
  // throw an error and render as a normal blue link.
72
72
 
73
- if (nextStatus === 'unauthorized' && !hasAuthFlowSupported) {
73
+ if ((nextStatus === 'unauthorized' || nextStatus === 'forbidden') && !hasAuthFlowSupported) {
74
74
  handleResolvedLinkError(resourceUrl, new APIError('fallback', hostname, ERROR_MESSAGE_OAUTH));
75
75
  return;
76
76
  } // Handle any other errors
@@ -11,6 +11,7 @@ export const tokens = {
11
11
  elevation: token('elevation.shadow.raised', '0px 1px 1px #091E4240, 0px 0px 1px #091E424F'),
12
12
  errorMessage: token('color.text.disabled', '#6B778C'),
13
13
  errorMessageHover: token('color.text.subtle', '#8993A4'),
14
+ focus: token('color.border.focused', '#388BFF'),
14
15
  snippet: token('color.text', '#172B4D'),
15
16
  text: token('color.text.subtlest', '#626F86')
16
17
  };
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "18.0.16",
3
+ "version": "18.0.19",
4
4
  "sideEffects": false
5
5
  }
@@ -9,9 +9,22 @@ import { SmartLinkSize } from '../../../../../constants';
9
9
  import Button from '@atlaskit/button/standard-button';
10
10
  import MoreIcon from '@atlaskit/icon/glyph/more';
11
11
  import { sizeToSpacing } from '../../actions/action';
12
+ import { tokens } from '../../../../../utils/token';
12
13
  const styles = css`
13
14
  display: inline-flex;
14
15
  line-height: 1rem;
16
+ > div {
17
+ align-items: center;
18
+ button:focus {
19
+ // AK button removes the default browser outline on focus and apply
20
+ // box-shadow styling to create the outline appearance.
21
+ // Due to our container elements (Container/Block/ElementGroup) has
22
+ // overflow hidden to prevent the metadata element from leaking outside
23
+ // of its container, the box-shadow doesn't show properly.
24
+ // Invert the AK box-shadow styling.
25
+ box-shadow: inset 0 0 0 2px ${tokens.focus};
26
+ }
27
+ }
15
28
  `;
16
29
  /**
17
30
  * Creates a group of Action components. Accepts an array of Actions, in addition to some styling
@@ -27,6 +27,9 @@ const getMessageStyles = (size, hasAction) => {
27
27
  ${sizeStyles}
28
28
  ${getTruncateStyles(1, getLinkLineHeight(size))}
29
29
  color: ${tokens.errorMessage};
30
+ :focus {
31
+ outline: ${tokens.focus} solid 2px;
32
+ }
30
33
  `;
31
34
  };
32
35
  /**
@@ -63,9 +66,11 @@ const TitleBlockErroredView = ({
63
66
  direction: SmartLinkDirection.Horizontal,
64
67
  align: SmartLinkAlignment.Right
65
68
  }, jsx("span", {
69
+ className: hasAction ? 'has-action' : '',
66
70
  css: getMessageStyles(size, hasAction),
67
71
  onClick: onClick,
68
- "data-testid": `${testId}-errored-view-message`
72
+ "data-testid": `${testId}-errored-view-message`,
73
+ tabIndex: hasAction ? 0 : -1
69
74
  }, jsx(FormattedMessage, _extends({}, descriptor, {
70
75
  values: values
71
76
  })))), actionGroup);
@@ -12,13 +12,12 @@ const getActionStyles = (showOnHover, isOpen) => {
12
12
  if (showOnHover && !isOpen) {
13
13
  return css`
14
14
  .actions-button-group {
15
- visibility: hidden;
15
+ opacity: 0;
16
16
  }
17
17
 
18
- &:hover {
19
- .actions-button-group {
20
- visibility: visible;
21
- }
18
+ &:hover .actions-button-group,
19
+ .actions-button-group:focus-within {
20
+ opacity: 1;
22
21
  }
23
22
  `;
24
23
  }
@@ -3,28 +3,10 @@ import _extends from "@babel/runtime/helpers/extends";
3
3
  /** @jsx jsx */
4
4
  import React from 'react';
5
5
  import { jsx } from '@emotion/core';
6
- import Spinner from '@atlaskit/spinner';
7
6
  import Block from '../../block';
8
7
  import { SmartLinkSize } from '../../../../../../constants';
9
-
10
- const getSpinnerSize = size => {
11
- // Spinner sizes should be equivalent or smaller than Icon size
12
- // to avoid the jumping.
13
- switch (size) {
14
- case SmartLinkSize.XLarge:
15
- return 28;
16
-
17
- case SmartLinkSize.Large:
18
- return 24;
19
-
20
- case SmartLinkSize.Medium:
21
- return 16;
22
-
23
- case SmartLinkSize.Small:
24
- default:
25
- return 12;
26
- }
27
- };
8
+ import LoadingSkeleton from '../../../common/loading-skeleton';
9
+ import { getIconSizeStyles, getIconWidth } from '../../../utils';
28
10
  /**
29
11
  * This represents a TitleBlock for a Smart Link that is currently waiting
30
12
  * for a request to finish.
@@ -32,7 +14,6 @@ const getSpinnerSize = size => {
32
14
  * @see TitleBlock
33
15
  */
34
16
 
35
-
36
17
  const TitleBlockResolvingView = ({
37
18
  actionGroup,
38
19
  testId,
@@ -42,12 +23,16 @@ const TitleBlockResolvingView = ({
42
23
  const {
43
24
  size = SmartLinkSize.Medium
44
25
  } = blockProps;
26
+ const iconWidth = getIconWidth(size);
27
+ const iconStyles = getIconSizeStyles(iconWidth);
45
28
  return jsx(Block, _extends({}, blockProps, {
46
29
  testId: `${testId}-resolving-view`
47
- }), jsx(Spinner, {
48
- size: getSpinnerSize(size),
49
- testId: `${testId}-resolving-spinner`
50
- }), title, actionGroup);
30
+ }), jsx("span", {
31
+ css: iconStyles,
32
+ "data-testid": `${testId}-icon`
33
+ }, jsx(LoadingSkeleton, {
34
+ testId: `${testId}-icon-loading`
35
+ })), title, actionGroup);
51
36
  };
52
37
 
53
38
  export default TitleBlockResolvingView;
@@ -68,7 +68,6 @@ export const getBaseStyles = (direction, size) => css`
68
68
  line-height: 1rem;
69
69
  min-width: 0;
70
70
  overflow: hidden;
71
- overflow-y: hidden;
72
71
  ${getDirectionStyles(direction)};
73
72
  &:empty {
74
73
  display: none;
@@ -1,34 +1,8 @@
1
1
  /** @jsx jsx */
2
2
  import React from 'react';
3
- import { css, jsx, keyframes } from '@emotion/core';
3
+ import { jsx } from '@emotion/core';
4
4
  import ImageLoader from 'react-render-image';
5
- import { token } from '@atlaskit/tokens';
6
- const placeholderShimmer = keyframes`
7
- 0% { background-position: -20px 0; }
8
- 100% { background-position: 20px 0; }
9
- `;
10
- const shimmer = css`
11
- border-radius: 2px;
12
- user-select: none;
13
- background: ${token('color.skeleton.subtle', '#f6f7f8')};
14
- // TODO: https://product-fabric.atlassian.net/browse/DSP-4236
15
- background-image: linear-gradient(
16
- to right,
17
- ${token('color.skeleton.subtle', '#f6f7f8')} 0%,
18
- ${token('color.skeleton', '#edeef1')} 20%,
19
- ${token('color.skeleton.subtle', '#f6f7f8')} 40%,
20
- ${token('color.skeleton.subtle', '#f6f7f8')}100%
21
- );
22
- background-repeat: no-repeat;
23
- background-size: 280% 100%;
24
- display: inline-block;
25
-
26
- animation-duration: 1s;
27
- animation-fill-mode: forwards;
28
- animation-iteration-count: infinite;
29
- animation-name: ${placeholderShimmer};
30
- animation-timing-function: linear;
31
- `;
5
+ import LoadingSkeleton from '../loading-skeleton';
32
6
 
33
7
  const ImageIcon = ({
34
8
  defaultIcon,
@@ -36,9 +10,8 @@ const ImageIcon = ({
36
10
  url
37
11
  }) => jsx(ImageLoader, {
38
12
  src: url,
39
- loading: jsx("span", {
40
- css: shimmer,
41
- "data-testid": `${testId}-loading`
13
+ loading: jsx(LoadingSkeleton, {
14
+ testId: `${testId}-loading`
42
15
  }),
43
16
  loaded: jsx("img", {
44
17
  src: url,
@@ -0,0 +1,39 @@
1
+ /** @jsx jsx */
2
+ import React from 'react';
3
+ import { css, jsx, keyframes } from '@emotion/core';
4
+ import { token } from '@atlaskit/tokens';
5
+ const animationNameStyles = keyframes`
6
+ 0% { background-position: -20px 0; }
7
+ 100% { background-position: 20px 0; }
8
+ `;
9
+ const styles = css`
10
+ border-radius: 2px;
11
+ user-select: none;
12
+ background: ${token('color.skeleton.subtle', '#f6f7f8')};
13
+ // TODO: https://product-fabric.atlassian.net/browse/DSP-4236
14
+ background-image: linear-gradient(
15
+ to right,
16
+ ${token('color.skeleton.subtle', '#f6f7f8')} 0%,
17
+ ${token('color.skeleton', '#edeef1')} 20%,
18
+ ${token('color.skeleton.subtle', '#f6f7f8')} 40%,
19
+ ${token('color.skeleton.subtle', '#f6f7f8')}100%
20
+ );
21
+ background-repeat: no-repeat;
22
+ background-size: 280% 100%;
23
+ display: inline-block;
24
+
25
+ animation-duration: 1s;
26
+ animation-fill-mode: forwards;
27
+ animation-iteration-count: infinite;
28
+ animation-name: ${animationNameStyles};
29
+ animation-timing-function: linear;
30
+ `;
31
+
32
+ const LoadingSkeleton = ({
33
+ testId
34
+ }) => jsx("span", {
35
+ css: styles,
36
+ "data-testid": testId
37
+ });
38
+
39
+ export default LoadingSkeleton;
@@ -1,9 +1,11 @@
1
1
  /** @jsx jsx */
2
- import React from 'react';
2
+ import React, { useContext } from 'react';
3
3
  import { css, jsx } from '@emotion/core';
4
4
  import { SmartLinkSize, SmartLinkTheme } from '../../../../constants';
5
5
  import { isFlexibleUiBlock, isFlexibleUiTitleBlock } from '../../../../utils/flexible';
6
6
  import { tokens } from '../../../../utils/token';
7
+ import { FlexibleUiContext } from '../../../../state/flexible-ui-context';
8
+ import LayeredLink from './layered-link';
7
9
  const elevationStyles = css`
8
10
  border: 1px solid transparent;
9
11
  border-radius: 1.5px;
@@ -45,15 +47,33 @@ const getPadding = size => {
45
47
  }
46
48
  };
47
49
 
48
- export const getContainerStyles = (size, hideBackground, hideElevation, hidePadding) => css`
50
+ const clickableContainerStyles = css`
51
+ // Position any interactive elements at the top of the z-index stack.
52
+ a,
53
+ button,
54
+ .has-action {
55
+ position: relative;
56
+ z-index: 1;
57
+ }
58
+ `;
59
+ export const getContainerStyles = (size, hideBackground, hideElevation, hidePadding, clickableContainer) => css`
49
60
  display: flex;
50
61
  gap: ${getGap(size)} 0;
51
62
  flex-direction: column;
52
63
  min-width: 0;
53
- overflow: hidden;
64
+ overflow-x: hidden;
65
+ position: relative;
54
66
  ${hideBackground ? '' : `background-color: ${tokens.background};`}
55
67
  ${hidePadding ? '' : `padding: ${getPadding(size)};`}
56
68
  ${hideElevation ? '' : elevationStyles}
69
+ ${clickableContainer ? clickableContainerStyles : ''}
70
+ &:hover ~ .actions-button-group {
71
+ opacity: 1;
72
+ }
73
+ a:focus,
74
+ .has-action:focus {
75
+ outline-offset: -2px;
76
+ }
57
77
  `;
58
78
 
59
79
  const renderChildren = (children, containerSize, containerTheme, status, retry, onClick) => React.Children.map(children, child => {
@@ -70,6 +90,31 @@ const renderChildren = (children, containerSize, containerTheme, status, retry,
70
90
  });
71
91
  }
72
92
  });
93
+
94
+ const getTitleBlockProps = children => {
95
+ const block = React.Children.toArray(children).find(child => isFlexibleUiTitleBlock(child));
96
+
97
+ if ( /*#__PURE__*/React.isValidElement(block)) {
98
+ return block.props;
99
+ }
100
+ };
101
+
102
+ const getLayeredLink = (testId, context, children) => {
103
+ const {
104
+ title,
105
+ url = ''
106
+ } = context || {};
107
+ const {
108
+ anchorTarget: target,
109
+ text
110
+ } = getTitleBlockProps(children) || {};
111
+ return jsx(LayeredLink, {
112
+ target: target,
113
+ testId: testId,
114
+ text: text || title,
115
+ url: url
116
+ });
117
+ };
73
118
  /**
74
119
  * This represents the container in which all Flexible UI Smart Links are rendered.
75
120
  * @see Block
@@ -78,19 +123,23 @@ const renderChildren = (children, containerSize, containerTheme, status, retry,
78
123
 
79
124
  const Container = ({
80
125
  children,
126
+ clickableContainer = false,
81
127
  hideBackground = false,
82
128
  hideElevation = false,
83
129
  hidePadding = false,
130
+ onClick,
84
131
  retry,
85
132
  size = SmartLinkSize.Medium,
86
133
  status,
87
134
  testId = 'smart-links-container',
88
- theme = SmartLinkTheme.Link,
89
- onClick
90
- }) => jsx("div", {
91
- css: getContainerStyles(size, hideBackground, hideElevation, hidePadding),
92
- "data-smart-link-container": true,
93
- "data-testid": testId
94
- }, renderChildren(children, size, theme, status, retry, onClick));
135
+ theme = SmartLinkTheme.Link
136
+ }) => {
137
+ const context = useContext(FlexibleUiContext);
138
+ return jsx("div", {
139
+ css: getContainerStyles(size, hideBackground, hideElevation, hidePadding, clickableContainer),
140
+ "data-smart-link-container": true,
141
+ "data-testid": testId
142
+ }, clickableContainer ? getLayeredLink(testId, context, children) : null, renderChildren(children, size, theme, status, retry, onClick));
143
+ };
95
144
 
96
145
  export default Container;
@@ -0,0 +1,54 @@
1
+ /** @jsx jsx */
2
+ import React from 'react';
3
+ import { jsx, css } from '@emotion/core';
4
+ const styles = css`
5
+ // Stretch the invisible link over the whole of the post.
6
+ // Hide the link’s text.
7
+ top: 0;
8
+ right: 0;
9
+ bottom: 0;
10
+ left: 0;
11
+ overflow-x: hidden;
12
+ text-indent: 100%;
13
+ white-space: nowrap;
14
+
15
+ // Needs a heightened specificity to trump other anchor.
16
+ // Stack it under all other links in the post text.
17
+ a&.layered-link {
18
+ position: absolute;
19
+ z-index: 0;
20
+ }
21
+
22
+ // When hovering over the layered link, any hidden action buttons inside
23
+ // the Container should become visible.
24
+ // As actions resides inside blocks and layered link is expected to be
25
+ // on the same level of blocks. That makes the blocks, e.g. TitleBlock,
26
+ // its sibling. Using general sibling combinator here to apply styling to
27
+ // all the siblings of layered link.
28
+ // The general sibling combinator (~) separates two selectors and matches all
29
+ // iterations of the second element, that are following the first element
30
+ // (though not necessarily immediately), and are children of the same parent
31
+ // element.
32
+ &:hover ~ * {
33
+ .actions-button-group {
34
+ opacity: 1;
35
+ }
36
+ }
37
+ `;
38
+
39
+ const LayeredLink = ({
40
+ target,
41
+ testId,
42
+ text,
43
+ url
44
+ }) => jsx("a", {
45
+ className: "layered-link",
46
+ css: styles,
47
+ "data-testid": `${testId}-layered-link`,
48
+ href: url,
49
+ target: target,
50
+ tabIndex: -1 // Hide tab index and let the title link be the link.
51
+
52
+ }, text);
53
+
54
+ export default LayeredLink;
@@ -48,6 +48,7 @@ const AvatarGroup = ({
48
48
 
49
49
  return jsx("span", {
50
50
  css: [getStyles(size), overrideCss],
51
+ "data-fit-to-content": true,
51
52
  "data-smart-element-avatar-group": true,
52
53
  "data-testid": testId
53
54
  }, jsx(AtlaskitAvatarGroup, {
@@ -5,7 +5,7 @@ import { css, jsx } from '@emotion/core';
5
5
  import { SmartLinkPosition, SmartLinkSize } from '../../../../../constants';
6
6
  import AtlaskitIcon from '../../common/atlaskit-icon';
7
7
  import ImageIcon from '../../common/image-icon';
8
- import { getIconSizeStyles, getTruncateStyles } from '../../utils';
8
+ import { getIconSizeStyles, getIconWidth, getTruncateStyles } from '../../utils';
9
9
 
10
10
  const getPositionStyles = (size, position) => {
11
11
  switch (position) {
@@ -23,23 +23,6 @@ const getPositionStyles = (size, position) => {
23
23
  }
24
24
  };
25
25
 
26
- const getWidth = size => {
27
- switch (size) {
28
- case SmartLinkSize.XLarge:
29
- return '2rem';
30
-
31
- case SmartLinkSize.Large:
32
- return '1.5rem';
33
-
34
- case SmartLinkSize.Medium:
35
- return '1rem';
36
-
37
- case SmartLinkSize.Small:
38
- default:
39
- return '.75rem';
40
- }
41
- };
42
-
43
26
  const getIconStyles = (size, position, width) => css`
44
27
  ${getPositionStyles(size, position)}
45
28
  ${getIconSizeStyles(width)}
@@ -105,7 +88,7 @@ const Icon = ({
105
88
  const defaultIcon = renderDefaultIcon(label, testId);
106
89
  return (render === null || render === void 0 ? void 0 : render()) || renderImageIcon(defaultIcon, icon, url, testId) || renderAtlaskitIcon(icon, label, testId) || defaultIcon;
107
90
  }, [icon, label, render, testId, url]);
108
- const width = getWidth(size);
91
+ const width = getIconWidth(size);
109
92
  const styles = getIconStyles(size, position, width);
110
93
  const renderStyles = render ? getCustomRenderStyles(width) : undefined;
111
94
  return jsx("div", {
@@ -39,6 +39,22 @@ export const getIconSizeStyles = width => {
39
39
  }
40
40
  `;
41
41
  };
42
+ export const getIconWidth = size => {
43
+ switch (size) {
44
+ case SmartLinkSize.XLarge:
45
+ return '2rem';
46
+
47
+ case SmartLinkSize.Large:
48
+ return '1.5rem';
49
+
50
+ case SmartLinkSize.Medium:
51
+ return '1rem';
52
+
53
+ case SmartLinkSize.Small:
54
+ default:
55
+ return '.75rem';
56
+ }
57
+ };
42
58
  export const getLinkLineHeight = size => {
43
59
  switch (size) {
44
60
  case SmartLinkSize.XLarge:
@@ -32,9 +32,9 @@ const FlexibleCard = ({
32
32
  }, /*#__PURE__*/React.createElement(Container, _extends({
33
33
  testId: testId
34
34
  }, ui, {
35
+ onClick: onClick,
35
36
  retry: retry,
36
- status: status,
37
- onClick: onClick
37
+ status: status
38
38
  }), children));
39
39
  };
40
40