@atlaskit/smart-card 45.6.7 → 45.6.9

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 (30) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/messages.js +45 -0
  3. package/dist/cjs/utils/analytics/analytics.js +1 -1
  4. package/dist/cjs/view/EmbedCard/components/carousel/CarouselSlide.compiled.css +52 -0
  5. package/dist/cjs/view/EmbedCard/components/carousel/CarouselSlide.js +124 -0
  6. package/dist/cjs/view/EmbedCard/components/carousel/index.compiled.css +12 -0
  7. package/dist/cjs/view/EmbedCard/components/carousel/index.js +122 -0
  8. package/dist/cjs/view/EmbedCard/components/carousel/types.js +5 -0
  9. package/dist/cjs/view/LinkUrl/index.js +1 -1
  10. package/dist/es2019/messages.js +45 -0
  11. package/dist/es2019/utils/analytics/analytics.js +1 -1
  12. package/dist/es2019/view/EmbedCard/components/carousel/CarouselSlide.compiled.css +52 -0
  13. package/dist/es2019/view/EmbedCard/components/carousel/CarouselSlide.js +114 -0
  14. package/dist/es2019/view/EmbedCard/components/carousel/index.compiled.css +12 -0
  15. package/dist/es2019/view/EmbedCard/components/carousel/index.js +101 -0
  16. package/dist/es2019/view/EmbedCard/components/carousel/types.js +1 -0
  17. package/dist/es2019/view/LinkUrl/index.js +1 -1
  18. package/dist/esm/messages.js +45 -0
  19. package/dist/esm/utils/analytics/analytics.js +1 -1
  20. package/dist/esm/view/EmbedCard/components/carousel/CarouselSlide.compiled.css +52 -0
  21. package/dist/esm/view/EmbedCard/components/carousel/CarouselSlide.js +117 -0
  22. package/dist/esm/view/EmbedCard/components/carousel/index.compiled.css +12 -0
  23. package/dist/esm/view/EmbedCard/components/carousel/index.js +113 -0
  24. package/dist/esm/view/EmbedCard/components/carousel/types.js +1 -0
  25. package/dist/esm/view/LinkUrl/index.js +1 -1
  26. package/dist/types/messages.d.ts +1 -1
  27. package/dist/types/view/EmbedCard/components/carousel/CarouselSlide.d.ts +39 -0
  28. package/dist/types/view/EmbedCard/components/carousel/index.d.ts +22 -0
  29. package/dist/types/view/EmbedCard/components/carousel/types.d.ts +26 -0
  30. package/package.json +4 -4
@@ -0,0 +1,101 @@
1
+ /* index.tsx generated by @compiled/babel-plugin v0.39.1 */
2
+ import "./index.compiled.css";
3
+ import { ax, ix } from "@compiled/react/runtime";
4
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
5
+ import { Box } from '@atlaskit/primitives/compiled';
6
+ import CarouselSlide from './CarouselSlide';
7
+ const styles = {
8
+ carousel: "_1reo15vq _18m915vq _1e0c1txw _1bsb1osq _4t3i1osq _kqswh2mm"
9
+ };
10
+
11
+ // Slide enters from the right: translates from 40px right + fades in
12
+ const slideInFromRight = null;
13
+ const slideWrapperMap = {
14
+ static: "_1bsb1osq _4t3i1osq",
15
+ animated: "_1bsb1osq _4t3i1osq _j7hql61g _5sagjx92 _1pglafbj _1o511hrf _bl8aglyw _2hwzhgkh"
16
+ };
17
+ /**
18
+ * Derives layout size bucket from pixel dimensions.
19
+ * Used instead of CSS @container queries (which are blocked by the linter)
20
+ * to control which elements are shown at different card sizes.
21
+ */
22
+ const getSize = (width, height) => {
23
+ if (width < 200 || height < 100) {
24
+ return 'minimal';
25
+ }
26
+ if (width < 400 || height < 140) {
27
+ return 'compact';
28
+ }
29
+ return 'full';
30
+ };
31
+ const Carousel = ({
32
+ icon,
33
+ iconLabel,
34
+ items,
35
+ onPrimaryButtonClick,
36
+ primaryButtonLabel,
37
+ testId = 'embed-card-teaser-carousel'
38
+ }) => {
39
+ const [activeIndex, setActiveIndex] = useState(0);
40
+ const [size, setSize] = useState('full');
41
+
42
+ // Tracks whether the user has navigated at least once.
43
+ // The first slide is rendered statically (no animation) to avoid any
44
+ // CSS animation running during SSR or on the initial paint.
45
+ const hasNavigated = useRef(false);
46
+ const containerRef = useRef(null);
47
+
48
+ // Observe the carousel container's size and update the layout bucket.
49
+ useEffect(() => {
50
+ const el = containerRef.current;
51
+ if (!el) {
52
+ return;
53
+ }
54
+ const observer = new ResizeObserver(([entry]) => {
55
+ const {
56
+ width,
57
+ height
58
+ } = entry.contentRect;
59
+ setSize(getSize(width, height));
60
+ });
61
+ observer.observe(el);
62
+ return () => observer.disconnect();
63
+ }, []);
64
+ const goNext = useCallback(() => {
65
+ hasNavigated.current = true;
66
+ setActiveIndex(current => (current + 1) % items.length);
67
+ }, [items.length]);
68
+ const goTo = useCallback(index => {
69
+ if (index === activeIndex) {
70
+ return;
71
+ }
72
+ hasNavigated.current = true;
73
+ setActiveIndex(index);
74
+ }, [activeIndex]);
75
+ const currentSlide = items[activeIndex];
76
+ const isLastSlide = activeIndex === items.length - 1;
77
+ return /*#__PURE__*/React.createElement(Box, {
78
+ ref: containerRef,
79
+ xcss: styles.carousel,
80
+ testId: testId
81
+ }, /*#__PURE__*/React.createElement(Box, {
82
+ key: activeIndex,
83
+ xcss: slideWrapperMap[hasNavigated.current ? 'animated' : 'static'],
84
+ "aria-live": "polite"
85
+ }, /*#__PURE__*/React.createElement(CarouselSlide, {
86
+ primaryButtonLabel: primaryButtonLabel,
87
+ description: currentSlide.description,
88
+ icon: icon,
89
+ iconLabel: iconLabel,
90
+ image: currentSlide.image,
91
+ title: currentSlide.title,
92
+ onPrimaryButtonClick: onPrimaryButtonClick,
93
+ onDotClick: goTo,
94
+ onNextClick: !isLastSlide ? goNext : undefined,
95
+ size: size,
96
+ slideIndex: activeIndex,
97
+ testId: `${testId}-slide`,
98
+ totalSlides: items.length
99
+ })));
100
+ };
101
+ export default Carousel;
@@ -9,7 +9,7 @@ import LinkWarningModal from './LinkWarningModal';
9
9
  import { useLinkWarningModal } from './LinkWarningModal/hooks/use-link-warning-modal';
10
10
  const PACKAGE_DATA = {
11
11
  packageName: "@atlaskit/smart-card",
12
- packageVersion: "45.6.6",
12
+ packageVersion: "45.6.8",
13
13
  componentName: 'linkUrl'
14
14
  };
15
15
  const LinkUrl = ({
@@ -160,6 +160,51 @@ export var messages = defineMessages({
160
160
  defaultMessage: 'To show a preview of this link, connect your {context} account.',
161
161
  description: 'Shown when a user does not have access to a link, but can connect their external account to view the link on card view. Displayed in byline.'
162
162
  },
163
+ connect_link_account_embed_teaser_dot_label: {
164
+ id: 'fabric.linking.connect_link_account_embed_teaser_dot_label.non-final',
165
+ defaultMessage: 'Go to slide {index} of {total}',
166
+ description: 'Accessible label for a dot indicator button in the teaser carousel, describing which slide it navigates to'
167
+ },
168
+ connect_link_account_embed_teaser_dot_row_label: {
169
+ id: 'fabric.linking.connect_link_account_embed_teaser_dot_row_label.non-final',
170
+ defaultMessage: 'Slides',
171
+ description: 'Accessible label for the group of dot indicator buttons in the teaser carousel'
172
+ },
173
+ connect_link_account_embed_teaser_button_next: {
174
+ id: 'fabric.linking.connect_link_account_embed_teaser_button_next.non-final',
175
+ defaultMessage: 'Next',
176
+ description: 'A button to view next teaser on benefit of connecting account on Smart Link embed'
177
+ },
178
+ connect_link_account_embed_teaser_slide_1_description: {
179
+ id: 'fabric.linking.connect_link_account_embed_teaser_slide_1_description.non-final',
180
+ defaultMessage: 'Connect your account to preview {context} files and documents directly inside Atlassian. No more context switching.',
181
+ description: 'A description on a teaser slide 1 on benefit of connecting account on Smart Link embed'
182
+ },
183
+ connect_link_account_embed_teaser_slide_1_title: {
184
+ id: 'fabric.linking.connect_link_account_embed_teaser_slide_1_title.non-final',
185
+ defaultMessage: 'See your {context} work without leaving Atlassian',
186
+ description: 'A title on a teaser slide 1 on benefit of connecting account on Smart Link embed'
187
+ },
188
+ connect_link_account_embed_teaser_slide_2_title: {
189
+ id: 'fabric.linking.connect_link_account_embed_teaser_slide_2_title.non-final',
190
+ defaultMessage: 'Search once, find it everywhere',
191
+ description: 'A title on a teaser slide 2 on benefit of connecting account on Smart Link embed'
192
+ },
193
+ connect_link_account_embed_teaser_slide_2_description: {
194
+ id: 'fabric.linking.connect_link_account_embed_teaser_slide_2_description.non-final',
195
+ defaultMessage: 'Search relevant {context} files alongside your Confluence pages and Jira issues, always respecting your {context} permissions.',
196
+ description: 'A description on a teaser slide 2 on benefit of connecting account on Smart Link embed'
197
+ },
198
+ connect_link_account_embed_teaser_slide_3_title: {
199
+ id: 'fabric.linking.connect_link_account_embed_teaser_slide_3_title.non-final',
200
+ defaultMessage: 'Get help from Rovo',
201
+ description: 'A title on a teaser slide 3 on benefit of connecting account on Smart Link embed'
202
+ },
203
+ connect_link_account_embed_teaser_slide_3_description: {
204
+ id: 'fabric.linking.connect_link_account_embed_teaser_slide_3_description.non-final',
205
+ defaultMessage: "Rovo uses your {context} content to answer questions, summarise docs, and draft updates using the work you've already done.",
206
+ description: 'A description on a teaser slide 3 on benefit of connecting account on Smart Link embed'
207
+ },
163
208
  connect_link_account_success_flag_description: {
164
209
  id: 'fabric.linking.connect_link_account_success_flag_description',
165
210
  defaultMessage: 'Shared links now display rich previews.',
@@ -4,7 +4,7 @@ export var ANALYTICS_CHANNEL = 'media';
4
4
  export var context = {
5
5
  componentName: 'smart-cards',
6
6
  packageName: "@atlaskit/smart-card" || '',
7
- packageVersion: "45.6.6" || ''
7
+ packageVersion: "45.6.8" || ''
8
8
  };
9
9
  export var TrackQuickActionType = /*#__PURE__*/function (TrackQuickActionType) {
10
10
  TrackQuickActionType["StatusUpdate"] = "StatusUpdate";
@@ -0,0 +1,52 @@
1
+
2
+ ._2rko1rr0{border-radius:var(--ds-radius-full,9999px)}
3
+ ._zulp1ejb{gap:var(--ds-space-300,24px)}
4
+ ._zulpu2gc{gap:var(--ds-space-100,8px)}
5
+ ._zulpze3t{gap:var(--ds-space-0,0)}._16jlkb7n{flex-grow:1}
6
+ ._18m91wug{overflow-y:auto}
7
+ ._19bv1jfw{padding-left:var(--ds-space-500,40px)}
8
+ ._19bvpxbi{padding-left:var(--ds-space-200,1pc)}
9
+ ._19bvze3t{padding-left:var(--ds-space-0,0)}
10
+ ._1bah1h6o{justify-content:center}
11
+ ._1bsb1osq{width:100%}
12
+ ._1bsb1tcg{width:24px}
13
+ ._1bsb7vkz{width:1pc}
14
+ ._1bsbi2wt{width:6px}
15
+ ._1e0c1txw{display:flex}
16
+ ._1e0c1ule{display:block}
17
+ ._1n261g80{flex-wrap:wrap}
18
+ ._1o9zidpf{flex-shrink:0}
19
+ ._1o9zkb7n{flex-shrink:1}
20
+ ._1oecfnf5{transition-duration:.2s}
21
+ ._1reo1wug{overflow-x:auto}
22
+ ._2lx21bp4{flex-direction:column}
23
+ ._2lx2vrvc{flex-direction:row}
24
+ ._4cvr1fhb{align-items:stretch}
25
+ ._4cvr1h6o{align-items:center}
26
+ ._4cvr1y6m{align-items:flex-start}
27
+ ._4t3i1osq{height:100%}
28
+ ._4t3i1tcg{height:24px}
29
+ ._4t3i7vkz{height:1pc}
30
+ ._4t3ii2wt{height:6px}
31
+ ._5ral1f51{object-fit:contain}
32
+ ._6fl45ucs{transition-timing-function:ease}
33
+ ._bfhk1dy8{background-color:var(--ds-background-accent-blue-subtler,#cfe1fd)}
34
+ ._bfhki8nm{background-color:var(--ds-background-neutral,#0515240f)}
35
+ ._bfhkjmqp{background-color:var(--ds-background-selected-bold,#1868db)}
36
+ ._bfhksm61{background-color:var(--ds-background-neutral-subtle,#00000000)}
37
+ ._c71l1wdt{max-height:220px}
38
+ ._ca0q1jfw{padding-top:var(--ds-space-500,40px)}
39
+ ._ca0qpxbi{padding-top:var(--ds-space-200,1pc)}
40
+ ._ca0qze3t{padding-top:var(--ds-space-0,0)}
41
+ ._i0dlghg7{flex-basis:240px}
42
+ ._i0dluuw1{flex-basis:200px}
43
+ ._k8m01k61{transition-property:background-color}
44
+ ._lcxvglyw{pointer-events:none}
45
+ ._n3td1jfw{padding-bottom:var(--ds-space-500,40px)}
46
+ ._n3tdpxbi{padding-bottom:var(--ds-space-200,1pc)}
47
+ ._n3tdze3t{padding-bottom:var(--ds-space-0,0)}
48
+ ._rsufaqso{object-position:center center}
49
+ ._u5f31jfw{padding-right:var(--ds-space-500,40px)}
50
+ ._u5f3pxbi{padding-right:var(--ds-space-200,1pc)}
51
+ ._u5f3ze3t{padding-right:var(--ds-space-0,0)}
52
+ ._vchhusvi{box-sizing:border-box}
@@ -0,0 +1,117 @@
1
+ /* CarouselSlide.tsx generated by @compiled/babel-plugin v0.39.1 */
2
+ import "./CarouselSlide.compiled.css";
3
+ import { ax, ix } from "@compiled/react/runtime";
4
+ import React from 'react';
5
+ import { useIntl } from 'react-intl';
6
+ import Button from '@atlaskit/button/new';
7
+ import { cx } from '@atlaskit/css';
8
+ import Heading from '@atlaskit/heading';
9
+ import Image from '@atlaskit/image';
10
+ import { Box, Pressable, Text } from '@atlaskit/primitives/compiled';
11
+ import { messages } from '../../../../messages';
12
+ var styles = {
13
+ columnImage: "_16jlkb7n _1o9zkb7n _i0dlghg7 _1e0c1txw _4cvr1h6o _1bah1h6o _ca0qpxbi _u5f3pxbi _n3tdpxbi _19bvpxbi _bfhk1dy8",
14
+ columnContent: "_zulp1ejb _16jlkb7n _1o9zkb7n _i0dluuw1 _1e0c1txw _2lx21bp4 _ca0q1jfw _u5f31jfw _n3td1jfw _19bv1jfw _4cvr1y6m _1bah1h6o",
15
+ columnContentCompact: "_ca0qpxbi _u5f3pxbi _n3tdpxbi _19bvpxbi",
16
+ dot: "_2rko1rr0 _1bsbi2wt _4t3ii2wt _bfhki8nm _1oecfnf5 _k8m01k61 _6fl45ucs _lcxvglyw",
17
+ dotActive: "_bfhkjmqp",
18
+ dotPassable: "_2rko1rr0 _1e0c1txw _4cvr1h6o _1bah1h6o _1bsb7vkz _4t3i7vkz _bfhksm61 _ca0qze3t _u5f3ze3t _n3tdze3t _19bvze3t",
19
+ icon: "_1o9zidpf _1bsb1tcg _4t3i1tcg _1e0c1txw _4cvr1h6o _1bah1h6o",
20
+ iconImage: "_1bsb1osq _4t3i1osq _5ral1f51",
21
+ image: "_1bsb1osq _c71l1wdt _5ral1f51 _rsufaqso _1e0c1ule",
22
+ rowButton: "_zulpu2gc _1e0c1txw _2lx2vrvc _1n261g80 _4cvr1h6o",
23
+ rowButtonCompact: "_1bsb1osq",
24
+ rowDot: "_zulpze3t _1e0c1txw _2lx2vrvc _4cvr1h6o",
25
+ rowIcon: "_zulpu2gc _1e0c1txw _4cvr1h6o",
26
+ slide: "_1reo1wug _18m91wug _1e0c1txw _1n261g80 _1bsb1osq _4t3i1osq _4cvr1fhb _vchhusvi"
27
+ };
28
+ var CarouselSlide = function CarouselSlide(_ref) {
29
+ var icon = _ref.icon,
30
+ iconLabel = _ref.iconLabel,
31
+ title = _ref.title,
32
+ description = _ref.description,
33
+ image = _ref.image,
34
+ primaryButtonLabel = _ref.primaryButtonLabel,
35
+ onPrimaryButtonClick = _ref.onPrimaryButtonClick,
36
+ onDotClick = _ref.onDotClick,
37
+ onNextClick = _ref.onNextClick,
38
+ slideIndex = _ref.slideIndex,
39
+ totalSlides = _ref.totalSlides,
40
+ size = _ref.size,
41
+ _ref$testId = _ref.testId,
42
+ testId = _ref$testId === void 0 ? 'embed-card-teaser-slide' : _ref$testId;
43
+ var _useIntl = useIntl(),
44
+ formatMessage = _useIntl.formatMessage;
45
+ var isCompact = size !== 'full';
46
+ var showNavigation = totalSlides > 1;
47
+ var renderedIcon = icon == null ? null : typeof icon === 'string' ? /*#__PURE__*/React.createElement(Box, {
48
+ xcss: styles.icon
49
+ }, /*#__PURE__*/React.createElement(Image, {
50
+ src: icon,
51
+ alt: iconLabel,
52
+ className: ax([styles.iconImage])
53
+ })) : /*#__PURE__*/React.createElement(Box, {
54
+ xcss: styles.icon
55
+ }, icon);
56
+ var renderedImage = image == null ? null : typeof image === 'string' ? /*#__PURE__*/React.createElement(Image, {
57
+ src: image,
58
+ alt: title,
59
+ className: ax([styles.image])
60
+ }) : image;
61
+ return /*#__PURE__*/React.createElement(Box, {
62
+ xcss: styles.slide,
63
+ testId: testId
64
+ }, /*#__PURE__*/React.createElement(Box, {
65
+ xcss: cx(styles.columnContent, isCompact && styles.columnContentCompact)
66
+ }, isCompact && /*#__PURE__*/React.createElement(Box, {
67
+ xcss: cx(styles.rowButton, styles.rowButtonCompact)
68
+ }, /*#__PURE__*/React.createElement(Button, {
69
+ appearance: "primary",
70
+ onClick: onPrimaryButtonClick,
71
+ shouldFitContainer: true,
72
+ testId: "".concat(testId, "-connect-compact")
73
+ }, primaryButtonLabel)), renderedIcon && /*#__PURE__*/React.createElement(Box, {
74
+ xcss: styles.rowIcon
75
+ }, renderedIcon), /*#__PURE__*/React.createElement(Box, null, /*#__PURE__*/React.createElement(Heading, {
76
+ size: "medium",
77
+ testId: "".concat(testId, "-title")
78
+ }, title)), /*#__PURE__*/React.createElement(Box, null, /*#__PURE__*/React.createElement(Text, {
79
+ testId: "".concat(testId, "-description")
80
+ }, description)), /*#__PURE__*/React.createElement(Box, {
81
+ xcss: styles.rowButton
82
+ }, !isCompact && /*#__PURE__*/React.createElement(Button, {
83
+ appearance: "primary",
84
+ onClick: onPrimaryButtonClick,
85
+ testId: "".concat(testId, "-connect")
86
+ }, primaryButtonLabel), showNavigation && onNextClick && /*#__PURE__*/React.createElement(Button, {
87
+ appearance: "subtle",
88
+ onClick: onNextClick,
89
+ testId: "".concat(testId, "-next")
90
+ }, formatMessage(messages.connect_link_account_embed_teaser_button_next)), showNavigation && /*#__PURE__*/React.createElement(Box, {
91
+ xcss: styles.rowDot,
92
+ role: "group",
93
+ "aria-label": formatMessage(messages.connect_link_account_embed_teaser_dot_row_label)
94
+ }, Array.from({
95
+ length: totalSlides
96
+ }, function (_, i) {
97
+ return /*#__PURE__*/React.createElement(Pressable, {
98
+ key: i,
99
+ xcss: styles.dotPassable,
100
+ onClick: function onClick() {
101
+ return onDotClick === null || onDotClick === void 0 ? void 0 : onDotClick(i);
102
+ },
103
+ "aria-label": formatMessage(messages.connect_link_account_embed_teaser_dot_label, {
104
+ index: i + 1,
105
+ total: totalSlides
106
+ }),
107
+ "aria-current": i === slideIndex ? 'true' : undefined,
108
+ testId: "".concat(testId, "-dot-").concat(i)
109
+ }, /*#__PURE__*/React.createElement(Box, {
110
+ xcss: cx(styles.dot, i === slideIndex && styles.dotActive)
111
+ }));
112
+ })))), !isCompact && /*#__PURE__*/React.createElement(Box, {
113
+ xcss: styles.columnImage,
114
+ testId: "".concat(testId, "-image-panel")
115
+ }, renderedImage));
116
+ };
117
+ export default CarouselSlide;
@@ -0,0 +1,12 @@
1
+ ._18m915vq{overflow-y:hidden}
2
+ ._1bsb1osq{width:100%}
3
+ ._1e0c1txw{display:flex}
4
+ ._1o511hrf{animation-fill-mode:both}
5
+ ._1pglafbj{animation-timing-function:cubic-bezier(.25,.46,.45,.94)}
6
+ ._1reo15vq{overflow-x:hidden}
7
+ ._4t3i1osq{height:100%}
8
+ ._5sagjx92{animation-duration:.28s}
9
+ ._j7hql61g{animation-name:kjqoltm}
10
+ ._kqswh2mm{position:relative}
11
+ @keyframes kjqoltm{0%{opacity:0;transform:translateX(40px)}to{opacity:1;transform:translateX(0)}}
12
+ @media (prefers-reduced-motion:reduce){._bl8aglyw{animation-name:none}._2hwzhgkh{animation-duration:.01ms}}
@@ -0,0 +1,113 @@
1
+ /* index.tsx generated by @compiled/babel-plugin v0.39.1 */
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ import "./index.compiled.css";
4
+ import { ax, ix } from "@compiled/react/runtime";
5
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
6
+ import { Box } from '@atlaskit/primitives/compiled';
7
+ import CarouselSlide from './CarouselSlide';
8
+ var styles = {
9
+ carousel: "_1reo15vq _18m915vq _1e0c1txw _1bsb1osq _4t3i1osq _kqswh2mm"
10
+ };
11
+
12
+ // Slide enters from the right: translates from 40px right + fades in
13
+ var slideInFromRight = null;
14
+ var slideWrapperMap = {
15
+ static: "_1bsb1osq _4t3i1osq",
16
+ animated: "_1bsb1osq _4t3i1osq _j7hql61g _5sagjx92 _1pglafbj _1o511hrf _bl8aglyw _2hwzhgkh"
17
+ };
18
+ /**
19
+ * Derives layout size bucket from pixel dimensions.
20
+ * Used instead of CSS @container queries (which are blocked by the linter)
21
+ * to control which elements are shown at different card sizes.
22
+ */
23
+ var getSize = function getSize(width, height) {
24
+ if (width < 200 || height < 100) {
25
+ return 'minimal';
26
+ }
27
+ if (width < 400 || height < 140) {
28
+ return 'compact';
29
+ }
30
+ return 'full';
31
+ };
32
+ var Carousel = function Carousel(_ref) {
33
+ var icon = _ref.icon,
34
+ iconLabel = _ref.iconLabel,
35
+ items = _ref.items,
36
+ onPrimaryButtonClick = _ref.onPrimaryButtonClick,
37
+ primaryButtonLabel = _ref.primaryButtonLabel,
38
+ _ref$testId = _ref.testId,
39
+ testId = _ref$testId === void 0 ? 'embed-card-teaser-carousel' : _ref$testId;
40
+ var _useState = useState(0),
41
+ _useState2 = _slicedToArray(_useState, 2),
42
+ activeIndex = _useState2[0],
43
+ setActiveIndex = _useState2[1];
44
+ var _useState3 = useState('full'),
45
+ _useState4 = _slicedToArray(_useState3, 2),
46
+ size = _useState4[0],
47
+ setSize = _useState4[1];
48
+
49
+ // Tracks whether the user has navigated at least once.
50
+ // The first slide is rendered statically (no animation) to avoid any
51
+ // CSS animation running during SSR or on the initial paint.
52
+ var hasNavigated = useRef(false);
53
+ var containerRef = useRef(null);
54
+
55
+ // Observe the carousel container's size and update the layout bucket.
56
+ useEffect(function () {
57
+ var el = containerRef.current;
58
+ if (!el) {
59
+ return;
60
+ }
61
+ var observer = new ResizeObserver(function (_ref2) {
62
+ var _ref3 = _slicedToArray(_ref2, 1),
63
+ entry = _ref3[0];
64
+ var _entry$contentRect = entry.contentRect,
65
+ width = _entry$contentRect.width,
66
+ height = _entry$contentRect.height;
67
+ setSize(getSize(width, height));
68
+ });
69
+ observer.observe(el);
70
+ return function () {
71
+ return observer.disconnect();
72
+ };
73
+ }, []);
74
+ var goNext = useCallback(function () {
75
+ hasNavigated.current = true;
76
+ setActiveIndex(function (current) {
77
+ return (current + 1) % items.length;
78
+ });
79
+ }, [items.length]);
80
+ var goTo = useCallback(function (index) {
81
+ if (index === activeIndex) {
82
+ return;
83
+ }
84
+ hasNavigated.current = true;
85
+ setActiveIndex(index);
86
+ }, [activeIndex]);
87
+ var currentSlide = items[activeIndex];
88
+ var isLastSlide = activeIndex === items.length - 1;
89
+ return /*#__PURE__*/React.createElement(Box, {
90
+ ref: containerRef,
91
+ xcss: styles.carousel,
92
+ testId: testId
93
+ }, /*#__PURE__*/React.createElement(Box, {
94
+ key: activeIndex,
95
+ xcss: slideWrapperMap[hasNavigated.current ? 'animated' : 'static'],
96
+ "aria-live": "polite"
97
+ }, /*#__PURE__*/React.createElement(CarouselSlide, {
98
+ primaryButtonLabel: primaryButtonLabel,
99
+ description: currentSlide.description,
100
+ icon: icon,
101
+ iconLabel: iconLabel,
102
+ image: currentSlide.image,
103
+ title: currentSlide.title,
104
+ onPrimaryButtonClick: onPrimaryButtonClick,
105
+ onDotClick: goTo,
106
+ onNextClick: !isLastSlide ? goNext : undefined,
107
+ size: size,
108
+ slideIndex: activeIndex,
109
+ testId: "".concat(testId, "-slide"),
110
+ totalSlides: items.length
111
+ })));
112
+ };
113
+ export default Carousel;
@@ -12,7 +12,7 @@ import LinkWarningModal from './LinkWarningModal';
12
12
  import { useLinkWarningModal } from './LinkWarningModal/hooks/use-link-warning-modal';
13
13
  var PACKAGE_DATA = {
14
14
  packageName: "@atlaskit/smart-card",
15
- packageVersion: "45.6.6",
15
+ packageVersion: "45.6.8",
16
16
  componentName: 'linkUrl'
17
17
  };
18
18
  var LinkUrl = function LinkUrl(_ref) {
@@ -1,7 +1,7 @@
1
1
  import { type MessageDescriptor } from 'react-intl';
2
2
  export type RequestAccessMessageKey = 'click_to_join' | 'click_to_join_description' | 'forbidden_description' | 'request_access' | 'request_access_description' | 'request_access_pending' | 'request_access_pending_title' | 'request_access_pending_description' | 'request_denied_description' | 'default_no_access_title' | 'direct_access_title' | 'direct_access_description' | 'direct_access' | 'access_exists_description' | 'not_found_description' | 'not_found_title';
3
3
  export type RovoChatActionMessageKey = 'rovo_prompt_context_generic' | 'rovo_prompt_context_generic_plural' | 'rovo_prompt_context_confluence_page' | 'rovo_prompt_context_confluence_page_short' | 'rovo_prompt_context_jira_work_item' | 'rovo_prompt_context_jira_work_item_short' | 'rovo_prompt_button_recommend_other_sources' | 'rovo_prompt_message_recommend_other_sources' | 'rovo_prompt_button_show_other_mentions' | 'rovo_prompt_message_show_other_mentions' | 'rovo_prompt_button_suggest_improvement' | 'rovo_prompt_message_suggest_improvement' | 'rovo_prompt_message_summarize' | 'rovo_prompt_button_ask_rovo_anything' | 'rovo_prompt_message_ask_rovo_anything' | 'rovo_prompt_button_highlight_relevant_content' | 'rovo_prompt_message_highlight_relevant_content' | 'rovo_prompt_button_identify_key_trends' | 'rovo_prompt_message_identify_key_trends' | 'rovo_prompt_button_identify_key_points' | 'rovo_prompt_message_identify_key_points' | 'rovo_prompt_button_find_open_questions' | 'rovo_prompt_message_find_open_questions' | 'rovo_prompt_button_key_highlights' | 'rovo_prompt_message_key_highlights' | 'rovo_prompt_message_summarize_document' | 'rovo_prompt_message_summarize_presentation' | 'rovo_prompt_button_explain_code' | 'rovo_prompt_message_explain_code' | 'rovo_prompt_button_catch_up' | 'rovo_prompt_message_catch_up' | 'rovo_prompt_button_salesforce_prep' | 'rovo_prompt_message_salesforce_prep';
4
- export type MessageKey = 'assigned_to' | 'ai_summarize' | 'change_status' | 'ai_summarized_abbreviation' | 'ai_summarized_info' | 'ai_summarized_info_short' | 'ai_summary_error_generic_rebrand' | 'ai_summary_error_acceptable_use_violation' | 'ai_summary_error_hipaa_content_detected' | 'ai_summary_error_exceeding_context_length_error' | 'ai_summary_action_rebrand' | 'ai_summary_action_description' | 'ai_summary_action_description_rebrand' | 'automation_action_title' | 'automation_action_tooltip' | 'automation_action_icon_label' | 'automation_action_confluence_page_modal_title' | 'automation_action_confluence_page_modal_description' | 'copy_summary_action' | 'copy_summary_action_description' | 'copied_summary_action_description' | 'beta' | 'cannot_find_link' | 'compass_applied_components_count' | 'connect_link_account_card' | 'connect_link_account_card_name' | 'connect_link_account_card_description' | 'connect_link_account_success_flag_description' | 'connect_link_account_success_flag_title' | 'connect_link_account_success_flag_title_default' | 'connect_unauthorised_account_action' | 'connect_inline_social_proof' | 'social_proof_inline_cta_tag_high_with_context' | 'social_proof_inline_cta_tag_high_no_context' | 'social_proof_inline_cta_tag_low_with_context' | 'social_proof_inline_cta_tag_low_no_context' | 'connect_unauthorised_account_description' | 'connect_unauthorised_account_description_no_provider' | 'continue' | 'copy_url_to_clipboard' | 'copied_url_to_clipboard' | 'could_not_load_link' | 'download' | 'download_description' | 'download_file' | 'follow' | 'follow_project_description' | 'follow_project_descriptionGalaxia' | 'follow_project' | 'follow_goal' | 'follow_goal_description' | 'follow_project_error' | 'follow_project_errorGalaxia' | 'follow_goal_error' | 'go_back' | 'invalid_permissions' | 'invalid_permissions_description' | 'join_to_view' | 'connect_link_account' | 'created_by' | 'created_on_relative' | 'created_on_absolute' | 'check_this_link' | 'delete' | 'edit' | 'learn_more_about_smart_links' | 'learn_more_about_connecting_account' | 'loading' | 'link_safety_warning_message' | 'modified_by' | 'modified_on_relative' | 'modified_on_absolute' | 'more_actions' | 'not_found_title' | 'not_found_description' | 'open_issue_in_jira' | 'open_link_in_a_new_tab' | 'owned_by' | 'owned_by_override' | 'preview_description' | 'preview_improved' | 'preview_modal' | 'preview_panel' | 'preview_close' | 'preview_max_size' | 'preview_min_size' | 'priority_blocker' | 'priority_critical' | 'priority_high' | 'priority_highest' | 'priority_low' | 'priority_lowest' | 'priority_major' | 'priority_medium' | 'priority_minor' | 'priority_trivial' | 'priority_undefined' | 'forbidden_access' | 'pending_request' | 'read_time' | 'restricted_link' | 'request_access_to_view' | 'request_denied' | 'sent_on_relative' | 'sent_on_absolute' | 'status_change_load_error' | 'status_change_permission_error' | 'status_change_update_error' | 'try_again' | 'try_another_account' | 'unauthorised_account_description' | 'unauthorised_account_description_no_provider' | 'unauthorised_account_name' | 'unauthorised_account_name_no_provider' | 'rovo_actions_explore' | 'unassigned' | 'unfollow' | 'unfollow_project_description' | 'unfollow_project_descriptionGalaxia' | 'unfollow_project' | 'unfollow_project_error' | 'unfollow_project_errorGalaxia' | 'unfollow_goal' | 'unfollow_goal_description' | 'unfollow_goal_error' | 'user_attributes' | 'view' | 'viewIn' | 'viewInProvider' | 'viewOriginal' | 'actions' | 'add_account' | 'cancel' | 'close' | 'connect_to' | 'connect_account_description' | 'retry' | 'save' | 'unlink_account' | RequestAccessMessageKey | 'related' | 'generic_error_message' | 'related_links_modal_error_title' | 'related_links_modal_error_description' | 'related_links_modal_unavailable_title' | 'related_links_modal_unavailable_description' | 'related_links_modal_title' | 'related_links_view_related_urls' | 'related_links_view_related_links' | 'related_links_found_in' | 'related_links_includes_links_to' | 'related_links_not_found' | 'join_to_viewIssueTermRefresh' | 'open_issue_in_jiraIssueTermRefresh' | 'request_access_to_viewIssueTermRefresh' | 'team_members_count' | 'status_change_permission_errorIssueTermRefresh' | 'connect_unauthorised_account_description_appify' | 'connect_unauthorised_account_description_no_provider_appify' | 'learn_more_about_connecting_account_experiment_shorter' | 'learn_more_about_connecting_account_appify' | 'rovo_summary_loading' | 'ai_disclaimer' | 'rovo_unauthorised_title' | 'rovo_unauthorised_title_no_provider' | 'rovo_unauthorised_feature_clear_link_names' | 'rovo_unauthorised_feature_understand_linked_docs' | 'rovo_unauthorised_feature_go_deeper_smart_suggestions' | 'rovo_unauthorised_connect_account' | 'rovo_unauthorised_not_now' | 'rovo_chat_action_section_header' | 'rovo_prompt_button_summarize_this' | 'rovo_prompt_button_ask_a_specific_question' | 'rovo_prompt_button_show_me_whats_relevant' | RovoChatActionMessageKey | 'pre_auth_block_social_proof_not_low' | 'pre_auth_block_social_proof_low';
4
+ export type MessageKey = 'assigned_to' | 'ai_summarize' | 'change_status' | 'ai_summarized_abbreviation' | 'ai_summarized_info' | 'ai_summarized_info_short' | 'ai_summary_error_generic_rebrand' | 'ai_summary_error_acceptable_use_violation' | 'ai_summary_error_hipaa_content_detected' | 'ai_summary_error_exceeding_context_length_error' | 'ai_summary_action_rebrand' | 'ai_summary_action_description' | 'ai_summary_action_description_rebrand' | 'automation_action_title' | 'automation_action_tooltip' | 'automation_action_icon_label' | 'automation_action_confluence_page_modal_title' | 'automation_action_confluence_page_modal_description' | 'copy_summary_action' | 'copy_summary_action_description' | 'copied_summary_action_description' | 'beta' | 'cannot_find_link' | 'compass_applied_components_count' | 'connect_link_account_card' | 'connect_link_account_card_name' | 'connect_link_account_card_description' | 'connect_link_account_embed_teaser_button_next' | 'connect_link_account_embed_teaser_dot_label' | 'connect_link_account_embed_teaser_dot_row_label' | 'connect_link_account_embed_teaser_slide_1_description' | 'connect_link_account_embed_teaser_slide_1_title' | 'connect_link_account_embed_teaser_slide_2_description' | 'connect_link_account_embed_teaser_slide_2_title' | 'connect_link_account_embed_teaser_slide_3_description' | 'connect_link_account_embed_teaser_slide_3_title' | 'connect_link_account_success_flag_description' | 'connect_link_account_success_flag_title' | 'connect_link_account_success_flag_title_default' | 'connect_unauthorised_account_action' | 'connect_inline_social_proof' | 'social_proof_inline_cta_tag_high_with_context' | 'social_proof_inline_cta_tag_high_no_context' | 'social_proof_inline_cta_tag_low_with_context' | 'social_proof_inline_cta_tag_low_no_context' | 'connect_unauthorised_account_description' | 'connect_unauthorised_account_description_no_provider' | 'continue' | 'copy_url_to_clipboard' | 'copied_url_to_clipboard' | 'could_not_load_link' | 'download' | 'download_description' | 'download_file' | 'follow' | 'follow_project_description' | 'follow_project_descriptionGalaxia' | 'follow_project' | 'follow_goal' | 'follow_goal_description' | 'follow_project_error' | 'follow_project_errorGalaxia' | 'follow_goal_error' | 'go_back' | 'invalid_permissions' | 'invalid_permissions_description' | 'join_to_view' | 'connect_link_account' | 'created_by' | 'created_on_relative' | 'created_on_absolute' | 'check_this_link' | 'delete' | 'edit' | 'learn_more_about_smart_links' | 'learn_more_about_connecting_account' | 'loading' | 'link_safety_warning_message' | 'modified_by' | 'modified_on_relative' | 'modified_on_absolute' | 'more_actions' | 'not_found_title' | 'not_found_description' | 'open_issue_in_jira' | 'open_link_in_a_new_tab' | 'owned_by' | 'owned_by_override' | 'preview_description' | 'preview_improved' | 'preview_modal' | 'preview_panel' | 'preview_close' | 'preview_max_size' | 'preview_min_size' | 'priority_blocker' | 'priority_critical' | 'priority_high' | 'priority_highest' | 'priority_low' | 'priority_lowest' | 'priority_major' | 'priority_medium' | 'priority_minor' | 'priority_trivial' | 'priority_undefined' | 'forbidden_access' | 'pending_request' | 'read_time' | 'restricted_link' | 'request_access_to_view' | 'request_denied' | 'sent_on_relative' | 'sent_on_absolute' | 'status_change_load_error' | 'status_change_permission_error' | 'status_change_update_error' | 'try_again' | 'try_another_account' | 'unauthorised_account_description' | 'unauthorised_account_description_no_provider' | 'unauthorised_account_name' | 'unauthorised_account_name_no_provider' | 'rovo_actions_explore' | 'unassigned' | 'unfollow' | 'unfollow_project_description' | 'unfollow_project_descriptionGalaxia' | 'unfollow_project' | 'unfollow_project_error' | 'unfollow_project_errorGalaxia' | 'unfollow_goal' | 'unfollow_goal_description' | 'unfollow_goal_error' | 'user_attributes' | 'view' | 'viewIn' | 'viewInProvider' | 'viewOriginal' | 'actions' | 'add_account' | 'cancel' | 'close' | 'connect_to' | 'connect_account_description' | 'retry' | 'save' | 'unlink_account' | RequestAccessMessageKey | 'related' | 'generic_error_message' | 'related_links_modal_error_title' | 'related_links_modal_error_description' | 'related_links_modal_unavailable_title' | 'related_links_modal_unavailable_description' | 'related_links_modal_title' | 'related_links_view_related_urls' | 'related_links_view_related_links' | 'related_links_found_in' | 'related_links_includes_links_to' | 'related_links_not_found' | 'join_to_viewIssueTermRefresh' | 'open_issue_in_jiraIssueTermRefresh' | 'request_access_to_viewIssueTermRefresh' | 'team_members_count' | 'status_change_permission_errorIssueTermRefresh' | 'connect_unauthorised_account_description_appify' | 'connect_unauthorised_account_description_no_provider_appify' | 'learn_more_about_connecting_account_experiment_shorter' | 'learn_more_about_connecting_account_appify' | 'rovo_summary_loading' | 'ai_disclaimer' | 'rovo_unauthorised_title' | 'rovo_unauthorised_title_no_provider' | 'rovo_unauthorised_feature_clear_link_names' | 'rovo_unauthorised_feature_understand_linked_docs' | 'rovo_unauthorised_feature_go_deeper_smart_suggestions' | 'rovo_unauthorised_connect_account' | 'rovo_unauthorised_not_now' | 'rovo_chat_action_section_header' | 'rovo_prompt_button_summarize_this' | 'rovo_prompt_button_ask_a_specific_question' | 'rovo_prompt_button_show_me_whats_relevant' | RovoChatActionMessageKey | 'pre_auth_block_social_proof_not_low' | 'pre_auth_block_social_proof_low';
5
5
  type Messages = {
6
6
  [K in MessageKey]: MessageDescriptor;
7
7
  };
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ */
5
+ import React from 'react';
6
+ import type { CarouselSize } from './types';
7
+ type CarouselSlideProps = {
8
+ /** Resolved description string (already injected with provider name) */
9
+ description: string;
10
+ /** Provider icon — a React element or an image URL */
11
+ icon?: React.ReactNode | string;
12
+ /** Alt for the icon, e.g. "Figma" */
13
+ iconLabel?: string;
14
+ /** Large hero image — a React element (e.g. SVG/img) or a URL string */
15
+ image: React.ReactNode | string;
16
+ /** Called when the user clicks a dot indicator to jump to that slide index */
17
+ onDotClick?: (index: number) => void;
18
+ /** Called when the user clicks the secondary "See next" button; omit on last slide */
19
+ onNextClick?: () => void;
20
+ /** Called when the user clicks the primary connect button */
21
+ onPrimaryButtonClick?: () => void;
22
+ /** Text label for the connect button (e.g. "Connect to Figma") */
23
+ primaryButtonLabel: string;
24
+ /**
25
+ * Layout size bucket derived from the carousel container's measured dimensions.
26
+ * Controls which elements are shown at different card sizes.
27
+ */
28
+ size: CarouselSize;
29
+ /** 0-based index of this slide */
30
+ slideIndex: number;
31
+ /** testId prefix */
32
+ testId?: string;
33
+ /** Resolved title string (already injected with provider name) */
34
+ title: string;
35
+ /** Total number of slides (for the dot indicators) */
36
+ totalSlides: number;
37
+ };
38
+ declare const CarouselSlide: ({ icon, iconLabel, title, description, image, primaryButtonLabel, onPrimaryButtonClick, onDotClick, onNextClick, slideIndex, totalSlides, size, testId, }: CarouselSlideProps) => React.JSX.Element;
39
+ export default CarouselSlide;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ */
5
+ import React from 'react';
6
+ import type { CarouselItem } from './types';
7
+ type CarouselProps = {
8
+ /** Provider icon element or URL — passed through to each slide */
9
+ icon?: React.ReactNode | string;
10
+ /** Alt for the icon, e.g. "Figma" */
11
+ iconLabel?: string;
12
+ /** Ordered list of teaser slides */
13
+ items: CarouselItem[];
14
+ /** Called when the user clicks the primary button */
15
+ onPrimaryButtonClick?: () => void;
16
+ /** Text for the auth button, e.g. "Connect to Figma" */
17
+ primaryButtonLabel: string;
18
+ /** testId prefix */
19
+ testId?: string;
20
+ };
21
+ declare const Carousel: ({ icon, iconLabel, items, onPrimaryButtonClick, primaryButtonLabel, testId, }: CarouselProps) => React.JSX.Element;
22
+ export default Carousel;
@@ -0,0 +1,26 @@
1
+ import type { ReactNode } from 'react';
2
+ /**
3
+ * Layout size bucket derived from the carousel container's pixel dimensions
4
+ * via ResizeObserver (replaces CSS @container queries which are lint-blocked).
5
+ *
6
+ * full — wide (> 400px) AND tall (> 140px): two-column layout with image panel
7
+ * compact — medium width/height: image hidden, button moves above title
8
+ * minimal — very small: description + dots hidden, button only
9
+ */
10
+ export type CarouselSize = 'full' | 'compact' | 'minimal';
11
+ export type CarouselItem = {
12
+ /**
13
+ * Body text describing the benefit.
14
+ * Pass a plain string for static copy, or a function that receives the
15
+ * provider name (e.g. "Google Drive") and returns the final string.
16
+ */
17
+ description: string;
18
+ /** Large hero image — either a React element (e.g. SVG) or an image URL */
19
+ image: ReactNode | string;
20
+ /**
21
+ * Title of the teaser slide.
22
+ * Pass a plain string for static copy, or a function that receives the
23
+ * provider name (e.g. "Google Drive") and returns the final string.
24
+ */
25
+ title: string;
26
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/smart-card",
3
- "version": "45.6.7",
3
+ "version": "45.6.9",
4
4
  "description": "Smart card component",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -35,7 +35,7 @@
35
35
  "ak-postbuild": "ls -d dist/* | xargs -n 1 copyfiles -u 1 -V src/**/*.{svg,png}"
36
36
  },
37
37
  "dependencies": {
38
- "@atlaskit/adf-utils": "^20.1.0",
38
+ "@atlaskit/adf-utils": "^20.2.0",
39
39
  "@atlaskit/afm-i18n-platform-linking-platform-smart-card": "2.6.0",
40
40
  "@atlaskit/analytics-cross-product": "^2.0.0",
41
41
  "@atlaskit/analytics-gas-types": "^6.0.0",
@@ -79,7 +79,7 @@
79
79
  "@atlaskit/primitives": "^20.3.0",
80
80
  "@atlaskit/react-compiler-gating": "^0.2.0",
81
81
  "@atlaskit/react-ufo": "^7.3.0",
82
- "@atlaskit/rovo-triggers": "^9.6.0",
82
+ "@atlaskit/rovo-triggers": "^9.7.0",
83
83
  "@atlaskit/section-message": "^9.2.0",
84
84
  "@atlaskit/select": "^22.3.0",
85
85
  "@atlaskit/spinner": "^20.1.0",
@@ -88,7 +88,7 @@
88
88
  "@atlaskit/textfield": "^9.1.0",
89
89
  "@atlaskit/theme": "^26.1.0",
90
90
  "@atlaskit/tile": "^2.1.0",
91
- "@atlaskit/tmp-editor-statsig": "^119.0.0",
91
+ "@atlaskit/tmp-editor-statsig": "^120.0.0",
92
92
  "@atlaskit/tokens": "^15.3.0",
93
93
  "@atlaskit/tooltip": "^23.1.0",
94
94
  "@atlaskit/ufo": "^1.0.0",