@atlaskit/ads-mcp 1.10.1 → 1.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/cjs/tools/migration-guides/migrations/onboarding-jira-spotlight.js +1 -1
- package/dist/cjs/tools/migration-guides/migrations/onboarding-multi-step.js +1 -1
- package/dist/cjs/tools/migration-guides/migrations/onboarding-single-step.js +1 -1
- package/dist/cjs/tools/migration-guides/migrations/onboarding-with-motion.js +1 -1
- package/dist/cjs/tools/suggest-a11y-fixes/fixes.js +2 -2
- package/dist/es2019/tools/migration-guides/migrations/onboarding-jira-spotlight.js +12 -14
- package/dist/es2019/tools/migration-guides/migrations/onboarding-multi-step.js +14 -16
- package/dist/es2019/tools/migration-guides/migrations/onboarding-single-step.js +12 -14
- package/dist/es2019/tools/migration-guides/migrations/onboarding-with-motion.js +12 -14
- package/dist/es2019/tools/suggest-a11y-fixes/fixes.js +4 -4
- package/dist/esm/tools/migration-guides/migrations/onboarding-jira-spotlight.js +1 -1
- package/dist/esm/tools/migration-guides/migrations/onboarding-multi-step.js +1 -1
- package/dist/esm/tools/migration-guides/migrations/onboarding-single-step.js +1 -1
- package/dist/esm/tools/migration-guides/migrations/onboarding-with-motion.js +1 -1
- package/dist/esm/tools/suggest-a11y-fixes/fixes.js +2 -2
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @atlaskit/ads-mcp
|
|
2
2
|
|
|
3
|
+
## 1.10.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`d5f3414d7e9ca`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d5f3414d7e9ca) -
|
|
8
|
+
Use the canonical Button entrypoint in accessibility fix suggestions.
|
|
9
|
+
|
|
3
10
|
## 1.10.1
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
|
@@ -21,7 +21,7 @@ var onboardingJiraSpotlight = exports.onboardingJiraSpotlight = {
|
|
|
21
21
|
title: 'Complex <JiraSpotlight /> migration',
|
|
22
22
|
description: 'Complex migrations are necessary for JiraSpotlight usages that make heavy use of the `children` prop to achieve customisation instead of relying on the `heading`, `body`, `image`, and/or `actions` props.',
|
|
23
23
|
before: "\n// file1.tsx\nimport { JiraSpotlight } from '@atlassian/jira-spotlight/src/ui/jira-spotlight.tsx';\n\nexport const OnboardingSpotlightWrapper = () => {\n\tconst spotlightId = 'some-unique-identifier'\n\tconst { dark, light } = spotlightImageUrls[spotlightId];\n\tconst imageUrl = colorMode === 'dark' ? dark : light;\n\n\treturn (\n\t\t<JiraSpotlight\n\t\t\ttarget={spotlightId}\n\t\t\ttargetRadius={3}\n\t\t\tdialogPlacement=''\n\t\t\ttargetBgColor={token('elevation.surface')}\n\t\t\tmessageId={spotlightId}\n\t\t\tmessageType=\"transactional\"\n\t\t\tdialogWidth={275}\n\t\t>\n\t\t\t<CustomSpotlightInner>\n\t\t\t\t{imageUrl}\n\t\t\t\t{formatMessage(heading)}\n\t\t\t\t{formatMessage(body)}\n\t\t\t\t<CustomSpotlightAction>\n\t\t\t\t\t{formatMessage(dismiss)}\n\t\t\t\t</CustomSpotlightAction>\n\t\t\t</CustomSpotlightInner>\n\t\t</JiraSpotlight>\n\t);\n}\n\n// file2.tsx\nimport { SpotlightTarget } from '@atlaskit/onboarding';\n\nconst spotlightId = 'some-unique-identifier'\n\nexport const SomeFeature = () => {\n\treturn (\n\t\t<SpotlightTarget name={spotlightId}>\n\t\t\t// Target code\n\t\t</SpotlightTarget>\n\t);\n}\n",
|
|
24
|
-
after: "\n// file2.tsx - Spotlight code has been co-located to the targeted element\nimport { Text } from '@atlaskit/primitives/compiled';\nimport {
|
|
24
|
+
after: "\n// file2.tsx - Spotlight code has been co-located to the targeted element\nimport { Text } from '@atlaskit/primitives/compiled';\nimport { PopoverContent } from '@atlaskit/spotlight/popover-content';\nimport { PopoverProvider } from '@atlaskit/spotlight/popover-provider';\nimport { PopoverTarget } from '@atlaskit/spotlight/popover-target';\nimport { SpotlightActions } from '@atlaskit/spotlight/actions';\nimport { SpotlightBody } from '@atlaskit/spotlight/body';\nimport { SpotlightCard } from '@atlaskit/spotlight/card';\nimport { SpotlightControls } from '@atlaskit/spotlight/controls';\nimport { SpotlightDismissControl } from '@atlaskit/spotlight/dismiss-control';\nimport { SpotlightFooter } from '@atlaskit/spotlight/footer';\nimport { SpotlightHeader } from '@atlaskit/spotlight/header';\nimport { SpotlightHeadline } from '@atlaskit/spotlight/headline';\nimport { SpotlightPrimaryAction } from '@atlaskit/spotlight/primary-action';\nimport Image from '@atlaskit/image';\nimport { ChoreographedComponent } from '@atlassian/jira-spotlight/src/ui/ChoreographedComponent.tsx';\n\nexport const SomeFeature = () => {\n\tconst { dark, light } = spotlightImageUrls[spotlightId];\n\n\tconst [isSpotlightVisible, actions] = useListViewOnboarding({\n\t\tprojectId: String(projectData.id),\n\t\tid: spotlightId,\n\t});\n\n\treturn (\n\t\t<PopoverProvider>\n\t\t\t<PopoverTarget>{renderTrigger(isSpotlightVisible)}</PopoverTarget>\n\t\t\t<ChoreographedComponent messageId={spotlightId} messageType=\"transactional\">\n\t\t\t\t<PopoverContent isVisible={isSpotlightVisible} placement=\"bottom-start\" dismiss={onClick}>\n\t\t\t\t\t<SpotlightCard>\n\t\t\t\t\t\t<SpotlightHeader>\n\t\t\t\t\t\t\t<SpotlightHeadline>{formatMessage(heading)}</SpotlightHeadline>\n\t\t\t\t\t\t\t<SpotlightControls>\n\t\t\t\t\t\t\t\t<SpotlightDismissControl />\n\t\t\t\t\t\t\t</SpotlightControls>\n\t\t\t\t\t\t</SpotlightHeader>\n\t\t\t\t\t\t<SpotlightMedia>\n\t\t\t\t\t\t\t<Image src={light} srcDark={dark} alt=\"\" />\n\t\t\t\t\t\t</SpotlightMedia>\n\t\t\t\t\t\t<SpotlightBody>\n\t\t\t\t\t\t\t<Text>{formatMessage(body)}</Text>\n\t\t\t\t\t\t</SpotlightBody>\n\t\t\t\t\t\t<SpotlightFooter>\n\t\t\t\t\t\t\t<SpotlightActions>\n\t\t\t\t\t\t\t\t<SpotlightPrimaryAction onClick={onClick}>\n\t\t\t\t\t\t\t\t\t{formatMessage(dismiss)}\n\t\t\t\t\t\t\t\t</SpotlightPrimaryAction>\n\t\t\t\t\t\t\t</SpotlightActions>\n\t\t\t\t\t\t</SpotlightFooter>\n\t\t\t\t\t</SpotlightCard>\n\t\t\t\t</PopoverContent>\n\t\t\t</ChoreographedComponent>\n\t\t</PopoverProvider>\n\t);\n};",
|
|
25
25
|
explanation: "Key changes when migrating a single step spotlight:\n- Replace JiraSpotlight with ChoreographedComponent from '@atlassian/jira-spotlight'.\n- PopoverProvider maintains internal Spotlight state.\n- Replace SpotlightTarget with PopoverTarget - wraps the element to highlight\n- Replace Spotlight with PopoverContent containing SpotlightCard - controls visibility and positioning\n- 'heading' becomes SpotlightHeadline inside SpotlightHeader\n- 'actions' becomes SpotlightActions with SpotlightPrimaryAction (and optionally SpotlightSecondaryAction)\n- 'body' content moves into SpotlightBody wrapped with Text component\n- Add SpotlightDismissControl inside SpotlightControls for the close button\n- The 'target' and/or 'targetName' prop is replaced with PopoverTarget directly wrapping the target element\n- 'dialogPlacement' prop becomes 'placement' on PopoverContent. Mapping: \"top right\" \u2192 \"top-start\", \"top center\" \u2192 \"top\", \"top left\" \u2192 \"top-end\", \"right bottom\" \u2192 \"right-start\", \"right middle\" \u2192 \"right-start | right-end\", \"right top\" \u2192 \"right-end\", \"bottom left\" \u2192 \"bottom-end\", \"bottom center\" \u2192 \"bottom\", \"bottom right\" \u2192 \"bottom-start\", \"left top\" \u2192 \"left-end\", \"left middle\" \u2192 \"left-start | left-end\", \"left bottom\" \u2192 \"left-start\"'"
|
|
26
26
|
}],
|
|
27
27
|
bestPractices: [],
|
|
@@ -15,7 +15,7 @@ var onboardingMultiStep = exports.onboardingMultiStep = {
|
|
|
15
15
|
title: 'Migrate multi step spotlight tour',
|
|
16
16
|
description: 'Replace the single SpotlightManager pattern with multiple PopoverProvider instances, one for each target in the tour',
|
|
17
17
|
before: "import React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport IconButton from '@atlaskit/button/icon/button';\nimport CommentAddIcon from '@atlaskit/icon/core/comment-add';\nimport CopyIcon from '@atlaskit/icon/core/copy';\nimport {\n Spotlight,\n SpotlightManager,\n SpotlightTarget,\n SpotlightTransition,\n} from '@atlaskit/onboarding';\n\nconst OnboardingTour = () => {\n const [activeSpotlight, setActiveSpotlight] = useState<null | number>(null);\n const start = () => setActiveSpotlight(0);\n const next = () => setActiveSpotlight((activeSpotlight || 0) + 1);\n const back = () => setActiveSpotlight((activeSpotlight || 1) - 1);\n const end = () => setActiveSpotlight(null);\n\n const renderActiveSpotlight = () => {\n const spotlights = [\n <Spotlight\n actions={[\n { onClick: () => next(), text: 'Next' },\n { onClick: () => end(), text: 'Dismiss', appearance: 'subtle' },\n ]}\n heading=\"Add a comment\"\n target=\"comment\"\n key=\"comment\"\n >\n Quickly add a comment to the work item.\n </Spotlight>,\n <Spotlight\n actions={[\n { onClick: () => end(), text: 'Done' },\n { onClick: () => back(), text: 'Back', appearance: 'subtle' },\n ]}\n heading=\"Copy code\"\n target=\"copy\"\n key=\"copy\"\n >\n Click to copy the example code to your clipboard.\n </Spotlight>,\n ];\n\n if (activeSpotlight === null) {\n return null;\n }\n return spotlights[activeSpotlight];\n };\n\n return (\n <SpotlightManager>\n <SpotlightTarget name=\"comment\">\n <IconButton icon={CommentAddIcon} label=\"comment\" />\n </SpotlightTarget>\n <SpotlightTarget name=\"copy\">\n <IconButton icon={CopyIcon} label=\"Copy\" />\n </SpotlightTarget>\n <Button appearance=\"primary\" onClick={start}>\n Start tour\n </Button>\n <SpotlightTransition>{renderActiveSpotlight()}</SpotlightTransition>\n </SpotlightManager>\n );\n};",
|
|
18
|
-
after: "import React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport IconButton from '@atlaskit/button/icon/button';\nimport CommentAddIcon from '@atlaskit/icon/core/comment-add';\nimport CopyIcon from '@atlaskit/icon/core/copy';\nimport { Text } from '@atlaskit/primitives/compiled';\nimport {
|
|
18
|
+
after: "import React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport IconButton from '@atlaskit/button/icon/button';\nimport CommentAddIcon from '@atlaskit/icon/core/comment-add';\nimport CopyIcon from '@atlaskit/icon/core/copy';\nimport { Text } from '@atlaskit/primitives/compiled';\nimport { PopoverContent } from '@atlaskit/spotlight/popover-content';\nimport { PopoverProvider } from '@atlaskit/spotlight/popover-provider';\nimport { PopoverTarget } from '@atlaskit/spotlight/popover-target';\nimport { SpotlightActions } from '@atlaskit/spotlight/actions';\nimport { SpotlightBody } from '@atlaskit/spotlight/body';\nimport { SpotlightCard } from '@atlaskit/spotlight/card';\nimport { SpotlightControls } from '@atlaskit/spotlight/controls';\nimport { SpotlightDismissControl } from '@atlaskit/spotlight/dismiss-control';\nimport { SpotlightFooter } from '@atlaskit/spotlight/footer';\nimport { SpotlightHeader } from '@atlaskit/spotlight/header';\nimport { SpotlightHeadline } from '@atlaskit/spotlight/headline';\nimport { SpotlightPrimaryAction } from '@atlaskit/spotlight/primary-action';\nimport { SpotlightSecondaryAction } from '@atlaskit/spotlight/secondary-action';\nimport { SpotlightStepCount } from '@atlaskit/spotlight/step-count';\n\nconst SpotlightTour = () => {\n const [currentStep, setCurrentStep] = useState<number>(0);\n\n const dismiss = () => setCurrentStep(0);\n const back = () => setCurrentStep(Math.max(currentStep - 1, 1));\n const next = () => setCurrentStep(Math.min(currentStep + 1, 2));\n const done = () => setCurrentStep(0);\n\n return (\n <>\n <PopoverProvider>\n <PopoverTarget>\n <IconButton icon={CommentAddIcon} label=\"comment\" />\n </PopoverTarget>\n <PopoverContent dismiss={dismiss} placement=\"bottom-start\" isVisible={currentStep === 1}>\n <SpotlightCard>\n <SpotlightHeader>\n <SpotlightHeadline>Add a comment</SpotlightHeadline>\n <SpotlightControls>\n <SpotlightDismissControl onClick={dismiss} />\n </SpotlightControls>\n </SpotlightHeader>\n <SpotlightBody>\n <Text>Quickly add a comment to the work item.</Text>\n </SpotlightBody>\n <SpotlightFooter>\n <SpotlightStepCount>1 of 2</SpotlightStepCount>\n <SpotlightActions>\n <SpotlightPrimaryAction onClick={next}>Next</SpotlightPrimaryAction>\n </SpotlightActions>\n </SpotlightFooter>\n </SpotlightCard>\n </PopoverContent>\n </PopoverProvider>\n\n <PopoverProvider>\n <PopoverTarget>\n <IconButton icon={CopyIcon} label=\"Copy\" />\n </PopoverTarget>\n <PopoverContent dismiss={dismiss} placement=\"bottom-start\" isVisible={currentStep === 2}>\n <SpotlightCard>\n <SpotlightHeader>\n <SpotlightHeadline>Copy code</SpotlightHeadline>\n <SpotlightControls>\n <SpotlightDismissControl onClick={dismiss} />\n </SpotlightControls>\n </SpotlightHeader>\n <SpotlightBody>\n <Text>Click to copy the example code to your clipboard.</Text>\n </SpotlightBody>\n <SpotlightFooter>\n <SpotlightStepCount>2 of 2</SpotlightStepCount>\n <SpotlightActions>\n <SpotlightSecondaryAction onClick={back}>Back</SpotlightSecondaryAction>\n <SpotlightPrimaryAction onClick={done}>Done</SpotlightPrimaryAction>\n </SpotlightActions>\n </SpotlightFooter>\n </SpotlightCard>\n </PopoverContent>\n </PopoverProvider>\n\n <Button appearance=\"primary\" onClick={() => setCurrentStep(1)}>\n Start tour\n </Button>\n </>\n );\n};",
|
|
19
19
|
explanation: "Key changes when migrating a multi-step spotlight tour:\n- SpotlightManager coordinated multiple spotlights in a tour. PopoverProvider manages internal state for a single spotlight.\n- Each target gets its own PopoverProvider > PopoverTarget > PopoverContent structure\n- The spotlight array pattern is replaced with individual SpotlightCard components per target\n- Control visibility with isVisible={currentStep === n} on each PopoverContent\n- Add SpotlightStepCount component in SpotlightFooter to show progress (e.g., \"1 of 3\")\n- Use SpotlightSecondaryAction for \"Back\" buttons instead of appearance: 'subtle' in the actions array\n- Use SpotlightPrimaryAction for \"Next\" and \"Done\" buttons\n- The renderActiveSpotlight pattern is no longer needed - visibility is controlled declaratively\n- Navigation functions use Math.max/Math.min to bound the step range safely\n- All other migration changes from single step spotlight migration guide apply."
|
|
20
20
|
}],
|
|
21
21
|
bestPractices: ['Use a numeric currentStep state where 0 = hidden, 1+ = active step number', 'Always include SpotlightStepCount in multi-step tours for user orientation', 'First step should only have "Next" action, middle steps have "Back" and "Next", last step has "Back" and "Done"', 'Use SpotlightSecondaryAction for back/dismiss actions and SpotlightPrimaryAction for next/done', 'Include SpotlightDismissControl with onClick={dismiss} so users can exit the tour at any point', 'Bound navigation functions with Math.max/Math.min to prevent invalid step values', 'Preference duplicating Spotlight code instead of trying to have a single `@atlaskit/spotlight` instance that conditionally renders content based on step.'],
|
|
@@ -15,7 +15,7 @@ var onboardingSingleStep = exports.onboardingSingleStep = {
|
|
|
15
15
|
title: 'Migrate single step spotlight',
|
|
16
16
|
description: 'Replace SpotlightTarget, and Spotlight with the new compositional @atlaskit/spotlight components',
|
|
17
17
|
before: "\n// file1.tsx\nimport React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport { Spotlight } from '@atlaskit/onboarding';\n\nconst OnboardingSpotlight = () => {\n const [isSpotlightActive, setIsSpotlightActive] = useState(true);\n const start = () => setIsSpotlightActive(true);\n const end = () => setIsSpotlightActive(false);\n\n return (\n\t\t{isSpotlightActive && (\n\t\t\t<Spotlight\n\t\t\t\tdialogPlacement='bottom right'\n\t\t\t\tactions={[\n\t\t\t\t\t{\n\t\t\t\t\t\tonClick: end,\n\t\t\t\t\t\ttext: 'Got it',\n\t\t\t\t\t},\n\t\t\t\t]}\n\t\t\t\theading=\"Feature Heading\"\n\t\t\t\ttarget=\"my-target\"\n\t\t\t>\n\t\t\t\tThis is the spotlight body content describing the feature.\n\t\t\t</Spotlight>\n\t\t)}\n );\n};\n\n// file2.tsx\nimport React from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport { Spotlight } from '@atlaskit/onboarding';\n\nconst SomeFeature = () => {\n\n return (\n\t\t<SpotlightTarget name=\"my-target\">\n\t\t\t<Button>Target Element</Button>\n\t\t</SpotlightTarget>\n );\n};\n",
|
|
18
|
-
after: "\n// file2.tsx -- the Spotlight has been co-located to the targeted element.\nimport React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport { Text } from '@atlaskit/primitives/compiled';\nimport {
|
|
18
|
+
after: "\n// file2.tsx -- the Spotlight has been co-located to the targeted element.\nimport React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport { Text } from '@atlaskit/primitives/compiled';\nimport { PopoverContent } from '@atlaskit/spotlight/popover-content';\nimport { PopoverProvider } from '@atlaskit/spotlight/popover-provider';\nimport { PopoverTarget } from '@atlaskit/spotlight/popover-target';\nimport { SpotlightActions } from '@atlaskit/spotlight/actions';\nimport { SpotlightBody } from '@atlaskit/spotlight/body';\nimport { SpotlightCard } from '@atlaskit/spotlight/card';\nimport { SpotlightControls } from '@atlaskit/spotlight/controls';\nimport { SpotlightDismissControl } from '@atlaskit/spotlight/dismiss-control';\nimport { SpotlightFooter } from '@atlaskit/spotlight/footer';\nimport { SpotlightHeader } from '@atlaskit/spotlight/header';\nimport { SpotlightHeadline } from '@atlaskit/spotlight/headline';\nimport { SpotlightPrimaryAction } from '@atlaskit/spotlight/primary-action';\n\nconst Spotlight = () => {\n const [isVisible, setIsVisible] = useState(false);\n const dismiss = () => setIsVisible(false);\n const done = () => setIsVisible(false);\n\n return (\n <PopoverProvider>\n <PopoverTarget>\n <Button onClick={() => setIsVisible(true)}>Target Element</Button>\n </PopoverTarget>\n <PopoverContent dismiss={dismiss} placement=\"bottom-start\" isVisible={isVisible}>\n <SpotlightCard>\n <SpotlightHeader>\n <SpotlightHeadline>Feature Heading</SpotlightHeadline>\n <SpotlightControls>\n <SpotlightDismissControl />\n </SpotlightControls>\n </SpotlightHeader>\n <SpotlightBody>\n <Text>This is the spotlight body content describing the feature.</Text>\n </SpotlightBody>\n <SpotlightFooter>\n <SpotlightActions>\n <SpotlightPrimaryAction onClick={done}>Got it</SpotlightPrimaryAction>\n </SpotlightActions>\n </SpotlightFooter>\n </SpotlightCard>\n </PopoverContent>\n </PopoverProvider>\n );\n};",
|
|
19
19
|
explanation: "Key changes when migrating a single step spotlight:\n- Do not use this migration guide for JiraSpotlight. Use 'jira-spotlight' instead.\n- PopoverProvider maintains internal Spotlight state. SpotlightManager coordinated multiple @atlaskit/onboarding usages and is no longer needed.\n- Replace SpotlightTarget with PopoverTarget - wraps the element to highlight\n- Replace Spotlight with PopoverContent containing SpotlightCard - controls visibility and positioning\n- The 'heading' prop becomes SpotlightHeadline inside SpotlightHeader\n- The 'actions' array becomes SpotlightActions with SpotlightPrimaryAction (and optionally SpotlightSecondaryAction)\n- The children content moves into SpotlightBody wrapped with Text component\n- Add SpotlightDismissControl inside SpotlightControls for the close button\n- The 'target' and/or 'targetName' prop is replaced with PopoverTarget directly wrapping the target element\n- The 'dialogPlacement' prop becomes 'placement' on PopoverContent. Mapping: \"top right\" \u2192 \"top-start\", \"top center\" \u2192 \"top\", \"top left\" \u2192 \"top-end\", \"right bottom\" \u2192 \"right-start\", \"right middle\" \u2192 \"right-start | right-end\", \"right top\" \u2192 \"right-end\", \"bottom left\" \u2192 \"bottom-end\", \"bottom center\" \u2192 \"bottom\", \"bottom right\" \u2192 \"bottom-start\", \"left top\" \u2192 \"left-end\", \"left middle\" \u2192 \"left-start | left-end\", \"left bottom\" \u2192 \"left-start\"'"
|
|
20
20
|
}],
|
|
21
21
|
bestPractices: ['PopoverTarget should wrap exactly one child element that will be highlighted', 'Always include SpotlightDismissControl for accessibility - allows users to dismiss via close button', 'SpotlightPrimaryAction is required and wraps the main CTA button', 'Wrap body text content in the Text component from @atlaskit/primitives/compiled'],
|
|
@@ -15,7 +15,7 @@ var onboardingWithMotion = exports.onboardingWithMotion = {
|
|
|
15
15
|
title: 'Migrate spotlight with transition animation',
|
|
16
16
|
description: 'Replace SpotlightTransition with FadeIn from @atlaskit/motion wrapped around the SpotlightCard',
|
|
17
17
|
before: "import React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport {\n Spotlight,\n SpotlightManager,\n SpotlightTarget,\n SpotlightTransition,\n} from '@atlaskit/onboarding';\n\nconst OnboardingSpotlightWithTransition = () => {\n const [isSpotlightActive, setIsSpotlightActive] = useState(false);\n const start = () => setIsSpotlightActive(true);\n const end = () => setIsSpotlightActive(false);\n\n return (\n <SpotlightManager>\n <SpotlightTarget name=\"my-target\">\n <Button>Target Element</Button>\n </SpotlightTarget>\n <div>\n <Button appearance=\"primary\" onClick={start}>\n Show spotlight\n </Button>\n </div>\n <SpotlightTransition>\n {isSpotlightActive && (\n <Spotlight\n actions={[\n {\n onClick: end,\n text: 'Got it',\n },\n ]}\n heading=\"Feature Heading\"\n target=\"my-target\"\n key=\"my-target\"\n >\n This is the spotlight body content describing the feature.\n </Spotlight>\n )}\n </SpotlightTransition>\n </SpotlightManager>\n );\n};",
|
|
18
|
-
after: "import React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport { FadeIn } from '@atlaskit/motion';\nimport { Text } from '@atlaskit/primitives/compiled';\nimport {
|
|
18
|
+
after: "import React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport { FadeIn } from '@atlaskit/motion';\nimport { Text } from '@atlaskit/primitives/compiled';\nimport { PopoverContent } from '@atlaskit/spotlight/popover-content';\nimport { PopoverProvider } from '@atlaskit/spotlight/popover-provider';\nimport { PopoverTarget } from '@atlaskit/spotlight/popover-target';\nimport { SpotlightActions } from '@atlaskit/spotlight/actions';\nimport { SpotlightBody } from '@atlaskit/spotlight/body';\nimport { SpotlightCard } from '@atlaskit/spotlight/card';\nimport { SpotlightControls } from '@atlaskit/spotlight/controls';\nimport { SpotlightDismissControl } from '@atlaskit/spotlight/dismiss-control';\nimport { SpotlightFooter } from '@atlaskit/spotlight/footer';\nimport { SpotlightHeader } from '@atlaskit/spotlight/header';\nimport { SpotlightHeadline } from '@atlaskit/spotlight/headline';\nimport { SpotlightPrimaryAction } from '@atlaskit/spotlight/primary-action';\n\nconst SpotlightWithMotion = () => {\n const [isVisible, setIsVisible] = useState(false);\n const dismiss = () => setIsVisible(false);\n const done = () => setIsVisible(false);\n\n return (\n <PopoverProvider>\n <PopoverTarget>\n <Button onClick={() => setIsVisible(true)}>Target Element</Button>\n </PopoverTarget>\n <PopoverContent done={done} dismiss={dismiss} placement=\"bottom-start\" isVisible={isVisible}>\n <FadeIn entranceDirection=\"left\">\n {(props) => (\n <div {...props}>\n <SpotlightCard>\n <SpotlightHeader>\n <SpotlightHeadline>Feature Heading</SpotlightHeadline>\n <SpotlightControls>\n <SpotlightDismissControl />\n </SpotlightControls>\n </SpotlightHeader>\n <SpotlightBody>\n <Text>This is the spotlight body content describing the feature.</Text>\n </SpotlightBody>\n <SpotlightFooter>\n <SpotlightActions>\n <SpotlightPrimaryAction onClick={done}>Got it</SpotlightPrimaryAction>\n </SpotlightActions>\n </SpotlightFooter>\n </SpotlightCard>\n </div>\n )}\n </FadeIn>\n </PopoverContent>\n </PopoverProvider>\n );\n};",
|
|
19
19
|
explanation: "Key changes when migrating a spotlight with transition animation:\n- Replace SpotlightTransition with FadeIn from @atlaskit/motion\n- Import FadeIn from '@atlaskit/motion' instead of SpotlightTransition from '@atlaskit/onboarding'\n- FadeIn uses a render props pattern - wrap content in {(props) => <div {...props}>...</div>}\n- The entranceDirection prop controls animation direction: 'left', 'right', 'top', or 'bottom'\n- All other migration changes from single step spotlight apply (PopoverProvider, compositional components, etc.)"
|
|
20
20
|
}],
|
|
21
21
|
bestPractices: ['Choose entranceDirection based on spotlight placement (e.g., "left" for right-placed spotlights)', 'Motion is optional - only add if the original onboarding spotlight used SpotlightTransition for entrance effects'],
|
|
@@ -13,7 +13,7 @@ var accessibilityFixes = exports.accessibilityFixes = {
|
|
|
13
13
|
title: 'Use aria-label prop',
|
|
14
14
|
description: 'Add aria-label for icon-only buttons',
|
|
15
15
|
before: "<button onClick={handleClose}>\n <CloseIcon />\n</button>",
|
|
16
|
-
after: "import
|
|
16
|
+
after: "import Button from '@atlaskit/button/default/button';\n\n<Button aria-label=\"Close dialog\" onClick={handleClose}>\n <CloseIcon />\n</Button>",
|
|
17
17
|
explanation: 'The aria-label provides a text description for screen readers while keeping the visual design clean.'
|
|
18
18
|
}, {
|
|
19
19
|
title: 'Use VisuallyHidden component',
|
|
@@ -307,7 +307,7 @@ var accessibilityFixes = exports.accessibilityFixes = {
|
|
|
307
307
|
title: 'Add adequate spacing',
|
|
308
308
|
description: 'Ensure sufficient space between interactive elements',
|
|
309
309
|
before: "<div>\n <Button>Save</Button><Button>Cancel</Button>\n</div>",
|
|
310
|
-
after: "import {
|
|
310
|
+
after: "import { Inline } from '@atlaskit/primitives/compiled/inline';\n\n<Inline space=\"space.100\">\n <Button>Save</Button>\n <Button>Cancel</Button>\n</Inline>",
|
|
311
311
|
explanation: 'Adequate spacing prevents accidental activation of adjacent controls.'
|
|
312
312
|
}],
|
|
313
313
|
bestPractices: ['Minimum 24x24 CSS pixels for touch targets', 'Provide adequate spacing between targets', 'Use ADS components that meet size requirements', 'Test on actual devices']
|
|
@@ -157,20 +157,18 @@ export const SomeFeature = () => {
|
|
|
157
157
|
after: `
|
|
158
158
|
// file2.tsx - Spotlight code has been co-located to the targeted element
|
|
159
159
|
import { Text } from '@atlaskit/primitives/compiled';
|
|
160
|
-
import {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
SpotlightPrimaryAction,
|
|
173
|
-
} from '@atlaskit/spotlight';
|
|
160
|
+
import { PopoverContent } from '@atlaskit/spotlight/popover-content';
|
|
161
|
+
import { PopoverProvider } from '@atlaskit/spotlight/popover-provider';
|
|
162
|
+
import { PopoverTarget } from '@atlaskit/spotlight/popover-target';
|
|
163
|
+
import { SpotlightActions } from '@atlaskit/spotlight/actions';
|
|
164
|
+
import { SpotlightBody } from '@atlaskit/spotlight/body';
|
|
165
|
+
import { SpotlightCard } from '@atlaskit/spotlight/card';
|
|
166
|
+
import { SpotlightControls } from '@atlaskit/spotlight/controls';
|
|
167
|
+
import { SpotlightDismissControl } from '@atlaskit/spotlight/dismiss-control';
|
|
168
|
+
import { SpotlightFooter } from '@atlaskit/spotlight/footer';
|
|
169
|
+
import { SpotlightHeader } from '@atlaskit/spotlight/header';
|
|
170
|
+
import { SpotlightHeadline } from '@atlaskit/spotlight/headline';
|
|
171
|
+
import { SpotlightPrimaryAction } from '@atlaskit/spotlight/primary-action';
|
|
174
172
|
import Image from '@atlaskit/image';
|
|
175
173
|
import { ChoreographedComponent } from '@atlassian/jira-spotlight/src/ui/ChoreographedComponent.tsx';
|
|
176
174
|
|
|
@@ -80,22 +80,20 @@ import IconButton from '@atlaskit/button/icon/button';
|
|
|
80
80
|
import CommentAddIcon from '@atlaskit/icon/core/comment-add';
|
|
81
81
|
import CopyIcon from '@atlaskit/icon/core/copy';
|
|
82
82
|
import { Text } from '@atlaskit/primitives/compiled';
|
|
83
|
-
import {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
SpotlightStepCount,
|
|
98
|
-
} from '@atlaskit/spotlight';
|
|
83
|
+
import { PopoverContent } from '@atlaskit/spotlight/popover-content';
|
|
84
|
+
import { PopoverProvider } from '@atlaskit/spotlight/popover-provider';
|
|
85
|
+
import { PopoverTarget } from '@atlaskit/spotlight/popover-target';
|
|
86
|
+
import { SpotlightActions } from '@atlaskit/spotlight/actions';
|
|
87
|
+
import { SpotlightBody } from '@atlaskit/spotlight/body';
|
|
88
|
+
import { SpotlightCard } from '@atlaskit/spotlight/card';
|
|
89
|
+
import { SpotlightControls } from '@atlaskit/spotlight/controls';
|
|
90
|
+
import { SpotlightDismissControl } from '@atlaskit/spotlight/dismiss-control';
|
|
91
|
+
import { SpotlightFooter } from '@atlaskit/spotlight/footer';
|
|
92
|
+
import { SpotlightHeader } from '@atlaskit/spotlight/header';
|
|
93
|
+
import { SpotlightHeadline } from '@atlaskit/spotlight/headline';
|
|
94
|
+
import { SpotlightPrimaryAction } from '@atlaskit/spotlight/primary-action';
|
|
95
|
+
import { SpotlightSecondaryAction } from '@atlaskit/spotlight/secondary-action';
|
|
96
|
+
import { SpotlightStepCount } from '@atlaskit/spotlight/step-count';
|
|
99
97
|
|
|
100
98
|
const SpotlightTour = () => {
|
|
101
99
|
const [currentStep, setCurrentStep] = useState<number>(0);
|
|
@@ -57,20 +57,18 @@ const SomeFeature = () => {
|
|
|
57
57
|
import React, { useState } from 'react';
|
|
58
58
|
import Button from '@atlaskit/button/default/button';
|
|
59
59
|
import { Text } from '@atlaskit/primitives/compiled';
|
|
60
|
-
import {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
SpotlightPrimaryAction,
|
|
73
|
-
} from '@atlaskit/spotlight';
|
|
60
|
+
import { PopoverContent } from '@atlaskit/spotlight/popover-content';
|
|
61
|
+
import { PopoverProvider } from '@atlaskit/spotlight/popover-provider';
|
|
62
|
+
import { PopoverTarget } from '@atlaskit/spotlight/popover-target';
|
|
63
|
+
import { SpotlightActions } from '@atlaskit/spotlight/actions';
|
|
64
|
+
import { SpotlightBody } from '@atlaskit/spotlight/body';
|
|
65
|
+
import { SpotlightCard } from '@atlaskit/spotlight/card';
|
|
66
|
+
import { SpotlightControls } from '@atlaskit/spotlight/controls';
|
|
67
|
+
import { SpotlightDismissControl } from '@atlaskit/spotlight/dismiss-control';
|
|
68
|
+
import { SpotlightFooter } from '@atlaskit/spotlight/footer';
|
|
69
|
+
import { SpotlightHeader } from '@atlaskit/spotlight/header';
|
|
70
|
+
import { SpotlightHeadline } from '@atlaskit/spotlight/headline';
|
|
71
|
+
import { SpotlightPrimaryAction } from '@atlaskit/spotlight/primary-action';
|
|
74
72
|
|
|
75
73
|
const Spotlight = () => {
|
|
76
74
|
const [isVisible, setIsVisible] = useState(false);
|
|
@@ -56,20 +56,18 @@ const OnboardingSpotlightWithTransition = () => {
|
|
|
56
56
|
import Button from '@atlaskit/button/default/button';
|
|
57
57
|
import { FadeIn } from '@atlaskit/motion';
|
|
58
58
|
import { Text } from '@atlaskit/primitives/compiled';
|
|
59
|
-
import {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
SpotlightPrimaryAction,
|
|
72
|
-
} from '@atlaskit/spotlight';
|
|
59
|
+
import { PopoverContent } from '@atlaskit/spotlight/popover-content';
|
|
60
|
+
import { PopoverProvider } from '@atlaskit/spotlight/popover-provider';
|
|
61
|
+
import { PopoverTarget } from '@atlaskit/spotlight/popover-target';
|
|
62
|
+
import { SpotlightActions } from '@atlaskit/spotlight/actions';
|
|
63
|
+
import { SpotlightBody } from '@atlaskit/spotlight/body';
|
|
64
|
+
import { SpotlightCard } from '@atlaskit/spotlight/card';
|
|
65
|
+
import { SpotlightControls } from '@atlaskit/spotlight/controls';
|
|
66
|
+
import { SpotlightDismissControl } from '@atlaskit/spotlight/dismiss-control';
|
|
67
|
+
import { SpotlightFooter } from '@atlaskit/spotlight/footer';
|
|
68
|
+
import { SpotlightHeader } from '@atlaskit/spotlight/header';
|
|
69
|
+
import { SpotlightHeadline } from '@atlaskit/spotlight/headline';
|
|
70
|
+
import { SpotlightPrimaryAction } from '@atlaskit/spotlight/primary-action';
|
|
73
71
|
|
|
74
72
|
const SpotlightWithMotion = () => {
|
|
75
73
|
const [isVisible, setIsVisible] = useState(false);
|
|
@@ -9,7 +9,7 @@ export const accessibilityFixes = {
|
|
|
9
9
|
before: `<button onClick={handleClose}>
|
|
10
10
|
<CloseIcon />
|
|
11
11
|
</button>`,
|
|
12
|
-
after: `import
|
|
12
|
+
after: `import Button from '@atlaskit/button/default/button';
|
|
13
13
|
|
|
14
14
|
<Button aria-label="Close dialog" onClick={handleClose}>
|
|
15
15
|
<CloseIcon />
|
|
@@ -544,12 +544,12 @@ return (
|
|
|
544
544
|
before: `<div>
|
|
545
545
|
<Button>Save</Button><Button>Cancel</Button>
|
|
546
546
|
</div>`,
|
|
547
|
-
after: `import {
|
|
547
|
+
after: `import { Inline } from '@atlaskit/primitives/compiled/inline';
|
|
548
548
|
|
|
549
|
-
<
|
|
549
|
+
<Inline space="space.100">
|
|
550
550
|
<Button>Save</Button>
|
|
551
551
|
<Button>Cancel</Button>
|
|
552
|
-
</
|
|
552
|
+
</Inline>`,
|
|
553
553
|
explanation: 'Adequate spacing prevents accidental activation of adjacent controls.'
|
|
554
554
|
}],
|
|
555
555
|
bestPractices: ['Minimum 24x24 CSS pixels for touch targets', 'Provide adequate spacing between targets', 'Use ADS components that meet size requirements', 'Test on actual devices']
|
|
@@ -15,7 +15,7 @@ export var onboardingJiraSpotlight = {
|
|
|
15
15
|
title: 'Complex <JiraSpotlight /> migration',
|
|
16
16
|
description: 'Complex migrations are necessary for JiraSpotlight usages that make heavy use of the `children` prop to achieve customisation instead of relying on the `heading`, `body`, `image`, and/or `actions` props.',
|
|
17
17
|
before: "\n// file1.tsx\nimport { JiraSpotlight } from '@atlassian/jira-spotlight/src/ui/jira-spotlight.tsx';\n\nexport const OnboardingSpotlightWrapper = () => {\n\tconst spotlightId = 'some-unique-identifier'\n\tconst { dark, light } = spotlightImageUrls[spotlightId];\n\tconst imageUrl = colorMode === 'dark' ? dark : light;\n\n\treturn (\n\t\t<JiraSpotlight\n\t\t\ttarget={spotlightId}\n\t\t\ttargetRadius={3}\n\t\t\tdialogPlacement=''\n\t\t\ttargetBgColor={token('elevation.surface')}\n\t\t\tmessageId={spotlightId}\n\t\t\tmessageType=\"transactional\"\n\t\t\tdialogWidth={275}\n\t\t>\n\t\t\t<CustomSpotlightInner>\n\t\t\t\t{imageUrl}\n\t\t\t\t{formatMessage(heading)}\n\t\t\t\t{formatMessage(body)}\n\t\t\t\t<CustomSpotlightAction>\n\t\t\t\t\t{formatMessage(dismiss)}\n\t\t\t\t</CustomSpotlightAction>\n\t\t\t</CustomSpotlightInner>\n\t\t</JiraSpotlight>\n\t);\n}\n\n// file2.tsx\nimport { SpotlightTarget } from '@atlaskit/onboarding';\n\nconst spotlightId = 'some-unique-identifier'\n\nexport const SomeFeature = () => {\n\treturn (\n\t\t<SpotlightTarget name={spotlightId}>\n\t\t\t// Target code\n\t\t</SpotlightTarget>\n\t);\n}\n",
|
|
18
|
-
after: "\n// file2.tsx - Spotlight code has been co-located to the targeted element\nimport { Text } from '@atlaskit/primitives/compiled';\nimport {
|
|
18
|
+
after: "\n// file2.tsx - Spotlight code has been co-located to the targeted element\nimport { Text } from '@atlaskit/primitives/compiled';\nimport { PopoverContent } from '@atlaskit/spotlight/popover-content';\nimport { PopoverProvider } from '@atlaskit/spotlight/popover-provider';\nimport { PopoverTarget } from '@atlaskit/spotlight/popover-target';\nimport { SpotlightActions } from '@atlaskit/spotlight/actions';\nimport { SpotlightBody } from '@atlaskit/spotlight/body';\nimport { SpotlightCard } from '@atlaskit/spotlight/card';\nimport { SpotlightControls } from '@atlaskit/spotlight/controls';\nimport { SpotlightDismissControl } from '@atlaskit/spotlight/dismiss-control';\nimport { SpotlightFooter } from '@atlaskit/spotlight/footer';\nimport { SpotlightHeader } from '@atlaskit/spotlight/header';\nimport { SpotlightHeadline } from '@atlaskit/spotlight/headline';\nimport { SpotlightPrimaryAction } from '@atlaskit/spotlight/primary-action';\nimport Image from '@atlaskit/image';\nimport { ChoreographedComponent } from '@atlassian/jira-spotlight/src/ui/ChoreographedComponent.tsx';\n\nexport const SomeFeature = () => {\n\tconst { dark, light } = spotlightImageUrls[spotlightId];\n\n\tconst [isSpotlightVisible, actions] = useListViewOnboarding({\n\t\tprojectId: String(projectData.id),\n\t\tid: spotlightId,\n\t});\n\n\treturn (\n\t\t<PopoverProvider>\n\t\t\t<PopoverTarget>{renderTrigger(isSpotlightVisible)}</PopoverTarget>\n\t\t\t<ChoreographedComponent messageId={spotlightId} messageType=\"transactional\">\n\t\t\t\t<PopoverContent isVisible={isSpotlightVisible} placement=\"bottom-start\" dismiss={onClick}>\n\t\t\t\t\t<SpotlightCard>\n\t\t\t\t\t\t<SpotlightHeader>\n\t\t\t\t\t\t\t<SpotlightHeadline>{formatMessage(heading)}</SpotlightHeadline>\n\t\t\t\t\t\t\t<SpotlightControls>\n\t\t\t\t\t\t\t\t<SpotlightDismissControl />\n\t\t\t\t\t\t\t</SpotlightControls>\n\t\t\t\t\t\t</SpotlightHeader>\n\t\t\t\t\t\t<SpotlightMedia>\n\t\t\t\t\t\t\t<Image src={light} srcDark={dark} alt=\"\" />\n\t\t\t\t\t\t</SpotlightMedia>\n\t\t\t\t\t\t<SpotlightBody>\n\t\t\t\t\t\t\t<Text>{formatMessage(body)}</Text>\n\t\t\t\t\t\t</SpotlightBody>\n\t\t\t\t\t\t<SpotlightFooter>\n\t\t\t\t\t\t\t<SpotlightActions>\n\t\t\t\t\t\t\t\t<SpotlightPrimaryAction onClick={onClick}>\n\t\t\t\t\t\t\t\t\t{formatMessage(dismiss)}\n\t\t\t\t\t\t\t\t</SpotlightPrimaryAction>\n\t\t\t\t\t\t\t</SpotlightActions>\n\t\t\t\t\t\t</SpotlightFooter>\n\t\t\t\t\t</SpotlightCard>\n\t\t\t\t</PopoverContent>\n\t\t\t</ChoreographedComponent>\n\t\t</PopoverProvider>\n\t);\n};",
|
|
19
19
|
explanation: "Key changes when migrating a single step spotlight:\n- Replace JiraSpotlight with ChoreographedComponent from '@atlassian/jira-spotlight'.\n- PopoverProvider maintains internal Spotlight state.\n- Replace SpotlightTarget with PopoverTarget - wraps the element to highlight\n- Replace Spotlight with PopoverContent containing SpotlightCard - controls visibility and positioning\n- 'heading' becomes SpotlightHeadline inside SpotlightHeader\n- 'actions' becomes SpotlightActions with SpotlightPrimaryAction (and optionally SpotlightSecondaryAction)\n- 'body' content moves into SpotlightBody wrapped with Text component\n- Add SpotlightDismissControl inside SpotlightControls for the close button\n- The 'target' and/or 'targetName' prop is replaced with PopoverTarget directly wrapping the target element\n- 'dialogPlacement' prop becomes 'placement' on PopoverContent. Mapping: \"top right\" \u2192 \"top-start\", \"top center\" \u2192 \"top\", \"top left\" \u2192 \"top-end\", \"right bottom\" \u2192 \"right-start\", \"right middle\" \u2192 \"right-start | right-end\", \"right top\" \u2192 \"right-end\", \"bottom left\" \u2192 \"bottom-end\", \"bottom center\" \u2192 \"bottom\", \"bottom right\" \u2192 \"bottom-start\", \"left top\" \u2192 \"left-end\", \"left middle\" \u2192 \"left-start | left-end\", \"left bottom\" \u2192 \"left-start\"'"
|
|
20
20
|
}],
|
|
21
21
|
bestPractices: [],
|
|
@@ -9,7 +9,7 @@ export var onboardingMultiStep = {
|
|
|
9
9
|
title: 'Migrate multi step spotlight tour',
|
|
10
10
|
description: 'Replace the single SpotlightManager pattern with multiple PopoverProvider instances, one for each target in the tour',
|
|
11
11
|
before: "import React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport IconButton from '@atlaskit/button/icon/button';\nimport CommentAddIcon from '@atlaskit/icon/core/comment-add';\nimport CopyIcon from '@atlaskit/icon/core/copy';\nimport {\n Spotlight,\n SpotlightManager,\n SpotlightTarget,\n SpotlightTransition,\n} from '@atlaskit/onboarding';\n\nconst OnboardingTour = () => {\n const [activeSpotlight, setActiveSpotlight] = useState<null | number>(null);\n const start = () => setActiveSpotlight(0);\n const next = () => setActiveSpotlight((activeSpotlight || 0) + 1);\n const back = () => setActiveSpotlight((activeSpotlight || 1) - 1);\n const end = () => setActiveSpotlight(null);\n\n const renderActiveSpotlight = () => {\n const spotlights = [\n <Spotlight\n actions={[\n { onClick: () => next(), text: 'Next' },\n { onClick: () => end(), text: 'Dismiss', appearance: 'subtle' },\n ]}\n heading=\"Add a comment\"\n target=\"comment\"\n key=\"comment\"\n >\n Quickly add a comment to the work item.\n </Spotlight>,\n <Spotlight\n actions={[\n { onClick: () => end(), text: 'Done' },\n { onClick: () => back(), text: 'Back', appearance: 'subtle' },\n ]}\n heading=\"Copy code\"\n target=\"copy\"\n key=\"copy\"\n >\n Click to copy the example code to your clipboard.\n </Spotlight>,\n ];\n\n if (activeSpotlight === null) {\n return null;\n }\n return spotlights[activeSpotlight];\n };\n\n return (\n <SpotlightManager>\n <SpotlightTarget name=\"comment\">\n <IconButton icon={CommentAddIcon} label=\"comment\" />\n </SpotlightTarget>\n <SpotlightTarget name=\"copy\">\n <IconButton icon={CopyIcon} label=\"Copy\" />\n </SpotlightTarget>\n <Button appearance=\"primary\" onClick={start}>\n Start tour\n </Button>\n <SpotlightTransition>{renderActiveSpotlight()}</SpotlightTransition>\n </SpotlightManager>\n );\n};",
|
|
12
|
-
after: "import React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport IconButton from '@atlaskit/button/icon/button';\nimport CommentAddIcon from '@atlaskit/icon/core/comment-add';\nimport CopyIcon from '@atlaskit/icon/core/copy';\nimport { Text } from '@atlaskit/primitives/compiled';\nimport {
|
|
12
|
+
after: "import React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport IconButton from '@atlaskit/button/icon/button';\nimport CommentAddIcon from '@atlaskit/icon/core/comment-add';\nimport CopyIcon from '@atlaskit/icon/core/copy';\nimport { Text } from '@atlaskit/primitives/compiled';\nimport { PopoverContent } from '@atlaskit/spotlight/popover-content';\nimport { PopoverProvider } from '@atlaskit/spotlight/popover-provider';\nimport { PopoverTarget } from '@atlaskit/spotlight/popover-target';\nimport { SpotlightActions } from '@atlaskit/spotlight/actions';\nimport { SpotlightBody } from '@atlaskit/spotlight/body';\nimport { SpotlightCard } from '@atlaskit/spotlight/card';\nimport { SpotlightControls } from '@atlaskit/spotlight/controls';\nimport { SpotlightDismissControl } from '@atlaskit/spotlight/dismiss-control';\nimport { SpotlightFooter } from '@atlaskit/spotlight/footer';\nimport { SpotlightHeader } from '@atlaskit/spotlight/header';\nimport { SpotlightHeadline } from '@atlaskit/spotlight/headline';\nimport { SpotlightPrimaryAction } from '@atlaskit/spotlight/primary-action';\nimport { SpotlightSecondaryAction } from '@atlaskit/spotlight/secondary-action';\nimport { SpotlightStepCount } from '@atlaskit/spotlight/step-count';\n\nconst SpotlightTour = () => {\n const [currentStep, setCurrentStep] = useState<number>(0);\n\n const dismiss = () => setCurrentStep(0);\n const back = () => setCurrentStep(Math.max(currentStep - 1, 1));\n const next = () => setCurrentStep(Math.min(currentStep + 1, 2));\n const done = () => setCurrentStep(0);\n\n return (\n <>\n <PopoverProvider>\n <PopoverTarget>\n <IconButton icon={CommentAddIcon} label=\"comment\" />\n </PopoverTarget>\n <PopoverContent dismiss={dismiss} placement=\"bottom-start\" isVisible={currentStep === 1}>\n <SpotlightCard>\n <SpotlightHeader>\n <SpotlightHeadline>Add a comment</SpotlightHeadline>\n <SpotlightControls>\n <SpotlightDismissControl onClick={dismiss} />\n </SpotlightControls>\n </SpotlightHeader>\n <SpotlightBody>\n <Text>Quickly add a comment to the work item.</Text>\n </SpotlightBody>\n <SpotlightFooter>\n <SpotlightStepCount>1 of 2</SpotlightStepCount>\n <SpotlightActions>\n <SpotlightPrimaryAction onClick={next}>Next</SpotlightPrimaryAction>\n </SpotlightActions>\n </SpotlightFooter>\n </SpotlightCard>\n </PopoverContent>\n </PopoverProvider>\n\n <PopoverProvider>\n <PopoverTarget>\n <IconButton icon={CopyIcon} label=\"Copy\" />\n </PopoverTarget>\n <PopoverContent dismiss={dismiss} placement=\"bottom-start\" isVisible={currentStep === 2}>\n <SpotlightCard>\n <SpotlightHeader>\n <SpotlightHeadline>Copy code</SpotlightHeadline>\n <SpotlightControls>\n <SpotlightDismissControl onClick={dismiss} />\n </SpotlightControls>\n </SpotlightHeader>\n <SpotlightBody>\n <Text>Click to copy the example code to your clipboard.</Text>\n </SpotlightBody>\n <SpotlightFooter>\n <SpotlightStepCount>2 of 2</SpotlightStepCount>\n <SpotlightActions>\n <SpotlightSecondaryAction onClick={back}>Back</SpotlightSecondaryAction>\n <SpotlightPrimaryAction onClick={done}>Done</SpotlightPrimaryAction>\n </SpotlightActions>\n </SpotlightFooter>\n </SpotlightCard>\n </PopoverContent>\n </PopoverProvider>\n\n <Button appearance=\"primary\" onClick={() => setCurrentStep(1)}>\n Start tour\n </Button>\n </>\n );\n};",
|
|
13
13
|
explanation: "Key changes when migrating a multi-step spotlight tour:\n- SpotlightManager coordinated multiple spotlights in a tour. PopoverProvider manages internal state for a single spotlight.\n- Each target gets its own PopoverProvider > PopoverTarget > PopoverContent structure\n- The spotlight array pattern is replaced with individual SpotlightCard components per target\n- Control visibility with isVisible={currentStep === n} on each PopoverContent\n- Add SpotlightStepCount component in SpotlightFooter to show progress (e.g., \"1 of 3\")\n- Use SpotlightSecondaryAction for \"Back\" buttons instead of appearance: 'subtle' in the actions array\n- Use SpotlightPrimaryAction for \"Next\" and \"Done\" buttons\n- The renderActiveSpotlight pattern is no longer needed - visibility is controlled declaratively\n- Navigation functions use Math.max/Math.min to bound the step range safely\n- All other migration changes from single step spotlight migration guide apply."
|
|
14
14
|
}],
|
|
15
15
|
bestPractices: ['Use a numeric currentStep state where 0 = hidden, 1+ = active step number', 'Always include SpotlightStepCount in multi-step tours for user orientation', 'First step should only have "Next" action, middle steps have "Back" and "Next", last step has "Back" and "Done"', 'Use SpotlightSecondaryAction for back/dismiss actions and SpotlightPrimaryAction for next/done', 'Include SpotlightDismissControl with onClick={dismiss} so users can exit the tour at any point', 'Bound navigation functions with Math.max/Math.min to prevent invalid step values', 'Preference duplicating Spotlight code instead of trying to have a single `@atlaskit/spotlight` instance that conditionally renders content based on step.'],
|
|
@@ -9,7 +9,7 @@ export var onboardingSingleStep = {
|
|
|
9
9
|
title: 'Migrate single step spotlight',
|
|
10
10
|
description: 'Replace SpotlightTarget, and Spotlight with the new compositional @atlaskit/spotlight components',
|
|
11
11
|
before: "\n// file1.tsx\nimport React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport { Spotlight } from '@atlaskit/onboarding';\n\nconst OnboardingSpotlight = () => {\n const [isSpotlightActive, setIsSpotlightActive] = useState(true);\n const start = () => setIsSpotlightActive(true);\n const end = () => setIsSpotlightActive(false);\n\n return (\n\t\t{isSpotlightActive && (\n\t\t\t<Spotlight\n\t\t\t\tdialogPlacement='bottom right'\n\t\t\t\tactions={[\n\t\t\t\t\t{\n\t\t\t\t\t\tonClick: end,\n\t\t\t\t\t\ttext: 'Got it',\n\t\t\t\t\t},\n\t\t\t\t]}\n\t\t\t\theading=\"Feature Heading\"\n\t\t\t\ttarget=\"my-target\"\n\t\t\t>\n\t\t\t\tThis is the spotlight body content describing the feature.\n\t\t\t</Spotlight>\n\t\t)}\n );\n};\n\n// file2.tsx\nimport React from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport { Spotlight } from '@atlaskit/onboarding';\n\nconst SomeFeature = () => {\n\n return (\n\t\t<SpotlightTarget name=\"my-target\">\n\t\t\t<Button>Target Element</Button>\n\t\t</SpotlightTarget>\n );\n};\n",
|
|
12
|
-
after: "\n// file2.tsx -- the Spotlight has been co-located to the targeted element.\nimport React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport { Text } from '@atlaskit/primitives/compiled';\nimport {
|
|
12
|
+
after: "\n// file2.tsx -- the Spotlight has been co-located to the targeted element.\nimport React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport { Text } from '@atlaskit/primitives/compiled';\nimport { PopoverContent } from '@atlaskit/spotlight/popover-content';\nimport { PopoverProvider } from '@atlaskit/spotlight/popover-provider';\nimport { PopoverTarget } from '@atlaskit/spotlight/popover-target';\nimport { SpotlightActions } from '@atlaskit/spotlight/actions';\nimport { SpotlightBody } from '@atlaskit/spotlight/body';\nimport { SpotlightCard } from '@atlaskit/spotlight/card';\nimport { SpotlightControls } from '@atlaskit/spotlight/controls';\nimport { SpotlightDismissControl } from '@atlaskit/spotlight/dismiss-control';\nimport { SpotlightFooter } from '@atlaskit/spotlight/footer';\nimport { SpotlightHeader } from '@atlaskit/spotlight/header';\nimport { SpotlightHeadline } from '@atlaskit/spotlight/headline';\nimport { SpotlightPrimaryAction } from '@atlaskit/spotlight/primary-action';\n\nconst Spotlight = () => {\n const [isVisible, setIsVisible] = useState(false);\n const dismiss = () => setIsVisible(false);\n const done = () => setIsVisible(false);\n\n return (\n <PopoverProvider>\n <PopoverTarget>\n <Button onClick={() => setIsVisible(true)}>Target Element</Button>\n </PopoverTarget>\n <PopoverContent dismiss={dismiss} placement=\"bottom-start\" isVisible={isVisible}>\n <SpotlightCard>\n <SpotlightHeader>\n <SpotlightHeadline>Feature Heading</SpotlightHeadline>\n <SpotlightControls>\n <SpotlightDismissControl />\n </SpotlightControls>\n </SpotlightHeader>\n <SpotlightBody>\n <Text>This is the spotlight body content describing the feature.</Text>\n </SpotlightBody>\n <SpotlightFooter>\n <SpotlightActions>\n <SpotlightPrimaryAction onClick={done}>Got it</SpotlightPrimaryAction>\n </SpotlightActions>\n </SpotlightFooter>\n </SpotlightCard>\n </PopoverContent>\n </PopoverProvider>\n );\n};",
|
|
13
13
|
explanation: "Key changes when migrating a single step spotlight:\n- Do not use this migration guide for JiraSpotlight. Use 'jira-spotlight' instead.\n- PopoverProvider maintains internal Spotlight state. SpotlightManager coordinated multiple @atlaskit/onboarding usages and is no longer needed.\n- Replace SpotlightTarget with PopoverTarget - wraps the element to highlight\n- Replace Spotlight with PopoverContent containing SpotlightCard - controls visibility and positioning\n- The 'heading' prop becomes SpotlightHeadline inside SpotlightHeader\n- The 'actions' array becomes SpotlightActions with SpotlightPrimaryAction (and optionally SpotlightSecondaryAction)\n- The children content moves into SpotlightBody wrapped with Text component\n- Add SpotlightDismissControl inside SpotlightControls for the close button\n- The 'target' and/or 'targetName' prop is replaced with PopoverTarget directly wrapping the target element\n- The 'dialogPlacement' prop becomes 'placement' on PopoverContent. Mapping: \"top right\" \u2192 \"top-start\", \"top center\" \u2192 \"top\", \"top left\" \u2192 \"top-end\", \"right bottom\" \u2192 \"right-start\", \"right middle\" \u2192 \"right-start | right-end\", \"right top\" \u2192 \"right-end\", \"bottom left\" \u2192 \"bottom-end\", \"bottom center\" \u2192 \"bottom\", \"bottom right\" \u2192 \"bottom-start\", \"left top\" \u2192 \"left-end\", \"left middle\" \u2192 \"left-start | left-end\", \"left bottom\" \u2192 \"left-start\"'"
|
|
14
14
|
}],
|
|
15
15
|
bestPractices: ['PopoverTarget should wrap exactly one child element that will be highlighted', 'Always include SpotlightDismissControl for accessibility - allows users to dismiss via close button', 'SpotlightPrimaryAction is required and wraps the main CTA button', 'Wrap body text content in the Text component from @atlaskit/primitives/compiled'],
|
|
@@ -9,7 +9,7 @@ export var onboardingWithMotion = {
|
|
|
9
9
|
title: 'Migrate spotlight with transition animation',
|
|
10
10
|
description: 'Replace SpotlightTransition with FadeIn from @atlaskit/motion wrapped around the SpotlightCard',
|
|
11
11
|
before: "import React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport {\n Spotlight,\n SpotlightManager,\n SpotlightTarget,\n SpotlightTransition,\n} from '@atlaskit/onboarding';\n\nconst OnboardingSpotlightWithTransition = () => {\n const [isSpotlightActive, setIsSpotlightActive] = useState(false);\n const start = () => setIsSpotlightActive(true);\n const end = () => setIsSpotlightActive(false);\n\n return (\n <SpotlightManager>\n <SpotlightTarget name=\"my-target\">\n <Button>Target Element</Button>\n </SpotlightTarget>\n <div>\n <Button appearance=\"primary\" onClick={start}>\n Show spotlight\n </Button>\n </div>\n <SpotlightTransition>\n {isSpotlightActive && (\n <Spotlight\n actions={[\n {\n onClick: end,\n text: 'Got it',\n },\n ]}\n heading=\"Feature Heading\"\n target=\"my-target\"\n key=\"my-target\"\n >\n This is the spotlight body content describing the feature.\n </Spotlight>\n )}\n </SpotlightTransition>\n </SpotlightManager>\n );\n};",
|
|
12
|
-
after: "import React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport { FadeIn } from '@atlaskit/motion';\nimport { Text } from '@atlaskit/primitives/compiled';\nimport {
|
|
12
|
+
after: "import React, { useState } from 'react';\nimport Button from '@atlaskit/button/default/button';\nimport { FadeIn } from '@atlaskit/motion';\nimport { Text } from '@atlaskit/primitives/compiled';\nimport { PopoverContent } from '@atlaskit/spotlight/popover-content';\nimport { PopoverProvider } from '@atlaskit/spotlight/popover-provider';\nimport { PopoverTarget } from '@atlaskit/spotlight/popover-target';\nimport { SpotlightActions } from '@atlaskit/spotlight/actions';\nimport { SpotlightBody } from '@atlaskit/spotlight/body';\nimport { SpotlightCard } from '@atlaskit/spotlight/card';\nimport { SpotlightControls } from '@atlaskit/spotlight/controls';\nimport { SpotlightDismissControl } from '@atlaskit/spotlight/dismiss-control';\nimport { SpotlightFooter } from '@atlaskit/spotlight/footer';\nimport { SpotlightHeader } from '@atlaskit/spotlight/header';\nimport { SpotlightHeadline } from '@atlaskit/spotlight/headline';\nimport { SpotlightPrimaryAction } from '@atlaskit/spotlight/primary-action';\n\nconst SpotlightWithMotion = () => {\n const [isVisible, setIsVisible] = useState(false);\n const dismiss = () => setIsVisible(false);\n const done = () => setIsVisible(false);\n\n return (\n <PopoverProvider>\n <PopoverTarget>\n <Button onClick={() => setIsVisible(true)}>Target Element</Button>\n </PopoverTarget>\n <PopoverContent done={done} dismiss={dismiss} placement=\"bottom-start\" isVisible={isVisible}>\n <FadeIn entranceDirection=\"left\">\n {(props) => (\n <div {...props}>\n <SpotlightCard>\n <SpotlightHeader>\n <SpotlightHeadline>Feature Heading</SpotlightHeadline>\n <SpotlightControls>\n <SpotlightDismissControl />\n </SpotlightControls>\n </SpotlightHeader>\n <SpotlightBody>\n <Text>This is the spotlight body content describing the feature.</Text>\n </SpotlightBody>\n <SpotlightFooter>\n <SpotlightActions>\n <SpotlightPrimaryAction onClick={done}>Got it</SpotlightPrimaryAction>\n </SpotlightActions>\n </SpotlightFooter>\n </SpotlightCard>\n </div>\n )}\n </FadeIn>\n </PopoverContent>\n </PopoverProvider>\n );\n};",
|
|
13
13
|
explanation: "Key changes when migrating a spotlight with transition animation:\n- Replace SpotlightTransition with FadeIn from @atlaskit/motion\n- Import FadeIn from '@atlaskit/motion' instead of SpotlightTransition from '@atlaskit/onboarding'\n- FadeIn uses a render props pattern - wrap content in {(props) => <div {...props}>...</div>}\n- The entranceDirection prop controls animation direction: 'left', 'right', 'top', or 'bottom'\n- All other migration changes from single step spotlight apply (PopoverProvider, compositional components, etc.)"
|
|
14
14
|
}],
|
|
15
15
|
bestPractices: ['Choose entranceDirection based on spotlight placement (e.g., "left" for right-placed spotlights)', 'Motion is optional - only add if the original onboarding spotlight used SpotlightTransition for entrance effects'],
|
|
@@ -7,7 +7,7 @@ export var accessibilityFixes = {
|
|
|
7
7
|
title: 'Use aria-label prop',
|
|
8
8
|
description: 'Add aria-label for icon-only buttons',
|
|
9
9
|
before: "<button onClick={handleClose}>\n <CloseIcon />\n</button>",
|
|
10
|
-
after: "import
|
|
10
|
+
after: "import Button from '@atlaskit/button/default/button';\n\n<Button aria-label=\"Close dialog\" onClick={handleClose}>\n <CloseIcon />\n</Button>",
|
|
11
11
|
explanation: 'The aria-label provides a text description for screen readers while keeping the visual design clean.'
|
|
12
12
|
}, {
|
|
13
13
|
title: 'Use VisuallyHidden component',
|
|
@@ -301,7 +301,7 @@ export var accessibilityFixes = {
|
|
|
301
301
|
title: 'Add adequate spacing',
|
|
302
302
|
description: 'Ensure sufficient space between interactive elements',
|
|
303
303
|
before: "<div>\n <Button>Save</Button><Button>Cancel</Button>\n</div>",
|
|
304
|
-
after: "import {
|
|
304
|
+
after: "import { Inline } from '@atlaskit/primitives/compiled/inline';\n\n<Inline space=\"space.100\">\n <Button>Save</Button>\n <Button>Cancel</Button>\n</Inline>",
|
|
305
305
|
explanation: 'Adequate spacing prevents accidental activation of adjacent controls.'
|
|
306
306
|
}],
|
|
307
307
|
bestPractices: ['Minimum 24x24 CSS pixels for touch targets', 'Provide adequate spacing between targets', 'Use ADS components that meet size requirements', 'Test on actual devices']
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/ads-mcp",
|
|
3
|
-
"version": "1.10.
|
|
3
|
+
"version": "1.10.2",
|
|
4
4
|
"description": "The official Atlassian Design System MCP server to develop apps and user interfaces matching the Atlassian style.",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"types": "dist/types/index.d.ts",
|
|
22
22
|
"atlaskit:src": "src/index.tsx",
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@atlaskit/icon": "^37.
|
|
25
|
-
"@atlaskit/icon-lab": "^7.
|
|
26
|
-
"@atlaskit/platform-feature-flags": "^2.
|
|
27
|
-
"@atlaskit/tokens": "^16.
|
|
24
|
+
"@atlaskit/icon": "^37.6.0",
|
|
25
|
+
"@atlaskit/icon-lab": "^7.8.0",
|
|
26
|
+
"@atlaskit/platform-feature-flags": "^2.2.0",
|
|
27
|
+
"@atlaskit/tokens": "^16.11.0",
|
|
28
28
|
"@axe-core/playwright": "^4.11.1",
|
|
29
29
|
"@axe-core/puppeteer": "^4.11.1",
|
|
30
30
|
"@babel/runtime": "^7.0.0",
|
|
@@ -42,6 +42,6 @@
|
|
|
42
42
|
"@atlassiansox/analytics-node-client": "^4.0.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@atlassian/feature-flags-test-utils": "^1.
|
|
45
|
+
"@atlassian/feature-flags-test-utils": "^1.3.0"
|
|
46
46
|
}
|
|
47
47
|
}
|