diff --git a/source/content-scripts/setup.ts b/source/content-scripts/setup.ts index 1bcf879..984cf7a 100644 --- a/source/content-scripts/setup.ts +++ b/source/content-scripts/setup.ts @@ -131,7 +131,7 @@ function startTour(data: TourData, runMainAgainAfterComplete: boolean): void { // For every step we have, add it to the tour and subsequently add all the // event handlers to that step. - for (const [stepNumber, stepOptions] of data.steps.entries()) { + for (const [stepNumber, stepOptions] of data.steps().entries()) { // If the final step doesn't have buttons defined, set the "Continue" button // text to "Finish". if ( diff --git a/source/tours/interface/account-settings.tsx b/source/tours/interface/account-settings.tsx index 4408e6a..7e70747 100644 --- a/source/tours/interface/account-settings.tsx +++ b/source/tours/interface/account-settings.tsx @@ -1,18 +1,22 @@ import {type TourData, TourId} from "../types.js"; import {renderInContainer} from "../utilities.js"; -const step01 = renderInContainer( - <> -

Your Account Settings

- , -); +function renderSteps(): ReturnType { + const step01 = renderInContainer( + <> +

Your Account Settings

+ , + ); -const steps: TourData["steps"] = [ - { - id: "account-settings-01", - text: step01, - }, -]; + return [ + { + id: "account-settings-01", + text: step01, + }, + ]; +} + +const steps: TourData["steps"] = renderSteps; const eventHandlers: TourData["eventHandlers"] = []; diff --git a/source/tours/interface/homepage.tsx b/source/tours/interface/homepage.tsx index 12a30b9..6b6c13d 100644 --- a/source/tours/interface/homepage.tsx +++ b/source/tours/interface/homepage.tsx @@ -7,431 +7,442 @@ import { renderInContainer, } from "../utilities.js"; -const step01 = renderInContainer( - <> - +function renderSteps(): ReturnType { + const step01 = renderInContainer( + <> + -

The Homepage

+

The Homepage

-

- If you plan on staying a while, this is likely the place you'll see the - most. So let's work our way top to bottom, left to right. -

+

+ If you plan on staying a while, this is likely the place you'll see the + most. So let's work our way top to bottom, left to right. +

-

Starting with...

- , -); - -const step02 = renderInContainer( - <> -

The Main Header

- -

- On the left there is the Tildes logo and title, which you can click to get - back to the homepage, or refresh it if you're already there. If you are in - a group, the group name will also be shown next to it. -

- -

- On the right is the notifications section and your username. When you have - unread messages and/or are mentioned, they will show up next to the left - of it. If you don't have any notifications right now, you can{" "} - - click here - {" "} - to toggle a preview of what they look like. -

- -

- At the moment mentions only work in comments, so if you get mentioned in a - topic's text body and don't get a notification,{" "} - - that's why - - . -

- , -); - -// Toggle mock notifications, based on the code in the following link. -// If the logic for this needs to be updated, also update the permalink to the -// actual Tildes HTML code. -// https://gitlab.com/tildes/tildes/-/blob/0dbb031562cd9297968fec0049af4b833ef77301/tildes/tildes/templates/macros/user.jinja2#L9-20 -function toggleMockNotifications(event: Event): void { - // Prevent the click from going through so the anchor isn't removed. - event.preventDefault(); - - const root = document.querySelector("#site-header .logged-in-user-info"); - - /* Generic function to toggle a mock notification. */ - function toggle(existingSelector: string, href: string, text: string): void { - const existing = - root?.querySelector(existingSelector) ?? undefined; - if (existing === undefined) { - // If no notification exists, render our mock. - const messageNotification = document.createElement("a"); - const count = 1 + Math.ceil(Math.random() * 10); - messageNotification.classList.add("logged-in-user-alert"); - messageNotification.dataset.tildesShepherdMock = "true"; - messageNotification.href = href; - messageNotification.textContent = `${count} ${text}`; - root?.insertAdjacentElement("beforeend", messageNotification); - } else if (existing.dataset.tildesShepherdMock === "true") { - // If a notification exists and it has our mock attribute, remove it. - existing.remove(); - } else { - // A real notification already exists, so we do nothing. - } - } - - toggle('[href="/messages/unread"]', "/messages/unread", "new messages"); - toggle( - '[href="/notifications/unread"]', - "/notifications/unread", - "new comments", +

Starting with...

+ , ); -} -const step03 = renderInContainer( - <> -

The Listing Options

+ const step02 = renderInContainer( + <> +

The Main Header

-

- Right below the main header are the topic listing options. These determine - how the topics in the listing are sorted and from what period topics - should be shown. -

+

+ On the left there is the Tildes logo and title, which you can click to + get back to the homepage, or refresh it if you're already there. If you + are in a group, the group name will also be shown next to it. +

-

- The non-activity sorts are the easiest to explain, so let's start with - them: -

+

+ On the right is the notifications section and your username. When you + have unread messages and/or are mentioned, they will show up next to the + left of it. If you don't have any notifications right now, you can{" "} + + click here + {" "} + to toggle a preview of what they look like. +

-
    -
  • - Votes sorts topics with the most votes first. -
  • -
  • - Comments sorts them with the most comments first. -
  • -
  • - And New sorts them by their date, so the newest topics come - first. -
  • -
- -

- Then the first Activity sort will sort topics by bumping topics up - as they receive comments, however this sort makes use of comment labels. -

- - {/* TODO: When the comment labels tour is made, change the prose. */} -

- If you don't know what comment labels are yet, don't worry, there will be - a tour that explains them. But in short they are a community tool to - emphasize and de-emphasize comments, similar to votes but with more - specific intention. If you'd like to read more, check out{" "} - - the documentation - - . -

- -

- And finally All activity sorts topics the same as Activity, but - without taking into account any comment labels. -

- -

- If you only want to see topics from a certain period, click on the "from" - dropdown and select the period you want. Aside from a set of predefined - options, you can also set a custom one by clicking the "other period" - option, after which you'll be prompted to input it. -

- , -); - -const step04 = renderInContainer( - <> -

The Topic Listing

- -

- Next up, just below the listing options is the topic listing itself. We've - only highlighted the first topic here, but you can probably see it - continues all the way down the page. -

- -

Here, we've marked the main elements of a topic:

- -
    -
  1. - The topic title, when the topic is a "text topic" it links to the same - place as the comments link does. Otherwise when it's a "link topic", it - will link to an external site. -
  2. - -
  3. - The topic metadata, which by default includes the group it's in. If a - topic has specific notable tags and you have the "show tags" setting - enabled in your user settings, they will be shown after the group name. - A "topic type" may also be shown to indicate whether the topic is a text - topic, a video, an "ask" topic for recommendations or a survey, etc. -
  4. - -
  5. - The amount of comments the topic has received. If any new comments have - been posted since you last viewed the topic, in orange a "(X new)" will - be added. -
  6. - -
  7. - The topic source. For text topics this is always the poster of the - topic, but for link topics in certain groups it will be the domain name - together with that website's icon. For topics automatically posted by - Tildes itself, it will say "Scheduled topic". -
  8. -
- -

The list continues on the next page.

- , -); - -const step05 = renderInContainer( - <> -

The Topic Listing continued

- -
    -
  1. - The date when the topic was posted. For dates that are pretty recent it - will show something like "X days ago" while for longer dates it will be - the exact date, like "April 26th, 2021". -
  2. - -
  3. - The voting button, clicking it will add your vote to the topic. On - Tildes, once the topic is older than 30 days you can no longer vote on - it and the individual voting data for is removed, with only the total - count kept. You can read more about it in{" "} - - this announcement topic +

    + At the moment mentions only work in comments, so if you get mentioned in + a topic's text body and don't get a notification,{" "} + + that's why . -

  4. +

    + , + ); -
  5. - And finally the topic actions. Clicking on the "Actions" button will - show a dropdown including "Bookmark", "Ignore this topic" and if you - have been granted the permission for it, "Edit title". Ignoring the - topic will remove it from the topic listing and prevent any future - notifications from happening. Both your bookmarked and ignored topics - can be found in their respective sections on your profile. -
  6. -
- , -); + // Toggle mock notifications, based on the code in the following link. + // If the logic for this needs to be updated, also update the permalink to the + // actual Tildes HTML code. + // https://gitlab.com/tildes/tildes/-/blob/0dbb031562cd9297968fec0049af4b833ef77301/tildes/tildes/templates/macros/user.jinja2#L9-20 + function toggleMockNotifications(event: Event): void { + // Prevent the click from going through so the anchor isn't removed. + event.preventDefault(); -const step06 = renderInContainer( - <> -

The Sidebar

+ const root = document.querySelector("#site-header .logged-in-user-info"); -

- Let's take a look at the sidebar, where the first thing we're greeted with - is the search bar. -

+ /* Generic function to toggle a mock notification. */ + function toggle( + existingSelector: string, + href: string, + text: string, + ): void { + const existing = + root?.querySelector(existingSelector) ?? undefined; + if (existing === undefined) { + // If no notification exists, render our mock. + const messageNotification = document.createElement("a"); + const count = 1 + Math.ceil(Math.random() * 10); + messageNotification.classList.add("logged-in-user-alert"); + messageNotification.dataset.tildesShepherdMock = "true"; + messageNotification.href = href; + messageNotification.textContent = `${count} ${text}`; + root?.insertAdjacentElement("beforeend", messageNotification); + } else if (existing.dataset.tildesShepherdMock === "true") { + // If a notification exists and it has our mock attribute, remove it. + existing.remove(); + } else { + // A real notification already exists, so we do nothing. + } + } -

- A quick note for mobile devices, the sidebar is opened via a "Sidebar" - button that appears in the very top-right of the page. -

+ toggle('[href="/messages/unread"]', "/messages/unread", "new messages"); + toggle( + '[href="/notifications/unread"]', + "/notifications/unread", + "new comments", + ); + } -

- When searching from the homepage, topics will be included from any group. - However, searching when inside a group will only include topics from that - group and any of its sub-groups. -

+ const step03 = renderInContainer( + <> +

The Listing Options

- {/* TODO: Update the prose once the groups tour is created. */} -

- Below the search bar you will also find the title of the page, or name of - the group, and a small description. The sidebar has more elements when in - you're in a group page, but those will be touched upon in the groups tour. -

- , -); +

+ Right below the main header are the topic listing options. These + determine how the topics in the listing are sorted and from what period + topics should be shown. +

-const step07 = renderInContainer( - <> -

The Sidebar: Subscriptions

+

+ The non-activity sorts are the easiest to explain, so let's start with + them: +

-

- Moving on, you'll find the list of groups you are subscribed to and a - button below it to go to the groups listing, where you can find all the - that are available. -

+
    +
  • + Votes sorts topics with the most votes first. +
  • +
  • + Comments sorts them with the most comments first. +
  • +
  • + And New sorts them by their date, so the newest topics come + first. +
  • +
-

- To post a topic, subscribe or unsubscribe from any group, go to the group - page in question and in its sidebar there will be buttons to do all those - things. -

- , -); +

+ Then the first Activity sort will sort topics by bumping topics + up as they receive comments, however this sort makes use of comment + labels. +

-const step08 = renderInContainer( - <> -

The Sidebar: User Settings

+ {/* TODO: When the comment labels tour is made, change the prose. */} +

+ If you don't know what comment labels are yet, don't worry, there will + be a tour that explains them. But in short they are a community tool to + emphasize and de-emphasize comments, similar to votes but with more + specific intention. If you'd like to read more, check out{" "} + + the documentation + + . +

-

- At the bottom of the sidebar you will find some user settings. - Specifically the filtered topics tags you have set and a link to the - settings page. -

+

+ And finally All activity sorts topics the same as Activity, but + without taking into account any comment labels. +

-

- When you have filtered topics tags set, topics with any of the tags - present will be removed from your listing. You can read more about it by - going to the dedicated page for it by clicking the{" "} - - "Edit filtered tags" - {" "} - button. -

- , -); +

+ If you only want to see topics from a certain period, click on the + "from" dropdown and select the period you want. Aside from a set of + predefined options, you can also set a custom one by clicking the "other + period" option, after which you'll be prompted to input it. +

+ , + ); -const step09 = renderInContainer( - <> -

The Footer

+ const step04 = renderInContainer( + <> +

The Topic Listing

-

- And finally, the very last part of the homepage is the footer. Here you - will find a theme selector (more on that in a moment) and various links to - places, such as the Tildes Documentation, Contact page, the source code, - etc. We highly recommend reading through the documentation as it explains - a lot of the how and why Tildes does certain things. -

+

+ Next up, just below the listing options is the topic listing itself. + We've only highlighted the first topic here, but you can probably see it + continues all the way down the page. +

-

- As for the theme selector, you can change your theme with a number of - options. When you change it here, it will only change for the current - device, if you'd like to set an account default for all devices, head to{" "} - - your account settings - - . -

- , -); +

Here, we've marked the main elements of a topic:

-const step10 = renderInContainer( - <> -

This is the end, beautiful friend

+
    +
  1. + The topic title, when the topic is a "text topic" it links to the same + place as the comments link does. Otherwise when it's a "link topic", + it will link to an external site. +
  2. -

    And that's the end of the Homepage tour!

    +
  3. + The topic metadata, which by default includes the group it's in. If a + topic has specific notable tags and you have the "show tags" setting + enabled in your user settings, they will be shown after the group + name. A "topic type" may also be shown to indicate whether the topic + is a text topic, a video, an "ask" topic for recommendations or a + survey, etc. +
  4. -

    - As always, if you find any bugs, have feature requests or simply want to - ask a question. Please send us a message at{" "} - - @Community - - . -

    +
  5. + The amount of comments the topic has received. If any new comments + have been posted since you last viewed the topic, in orange a "(X + new)" will be added. +
  6. -

    Happy Tildying!~

    - , -); +
  7. + The topic source. For text topics this is always the poster of the + topic, but for link topics in certain groups it will be the domain + name together with that website's icon. For topics automatically + posted by Tildes itself, it will say "Scheduled topic". +
  8. +
-const steps: TourData["steps"] = [ - { - id: "homepage-01", - text: step01, - }, - { - attachTo: { - element: "#site-header", - on: "bottom", +

The list continues on the next page.

+ , + ); + + const step05 = renderInContainer( + <> +

The Topic Listing continued

+ +
    +
  1. + The date when the topic was posted. For dates that are pretty recent + it will show something like "X days ago" while for longer dates it + will be the exact date, like "April 26th, 2021". +
  2. + +
  3. + The voting button, clicking it will add your vote to the topic. On + Tildes, once the topic is older than 30 days you can no longer vote on + it and the individual voting data for is removed, with only the total + count kept. You can read more about it in{" "} + + this announcement topic + + . +
  4. + +
  5. + And finally the topic actions. Clicking on the "Actions" button will + show a dropdown including "Bookmark", "Ignore this topic" and if you + have been granted the permission for it, "Edit title". Ignoring the + topic will remove it from the topic listing and prevent any future + notifications from happening. Both your bookmarked and ignored topics + can be found in their respective sections on your profile. +
  6. +
+ , + ); + + const step06 = renderInContainer( + <> +

The Sidebar

+ +

+ Let's take a look at the sidebar, where the first thing we're greeted + with is the search bar. +

+ +

+ A quick note for mobile devices, the sidebar is opened via a "Sidebar" + button that appears in the very top-right of the page. +

+ +

+ When searching from the homepage, topics will be included from any + group. However, searching when inside a group will only include topics + from that group and any of its sub-groups. +

+ + {/* TODO: Update the prose once the groups tour is created. */} +

+ Below the search bar you will also find the title of the page, or name + of the group, and a small description. The sidebar has more elements + when in you're in a group page, but those will be touched upon in the + groups tour. +

+ , + ); + + const step07 = renderInContainer( + <> +

The Sidebar: Subscriptions

+ +

+ Moving on, you'll find the list of groups you are subscribed to and a + button below it to go to the groups listing, where you can find all the + that are available. +

+ +

+ To post a topic, subscribe or unsubscribe from any group, go to the + group page in question and in its sidebar there will be buttons to do + all those things. +

+ , + ); + + const step08 = renderInContainer( + <> +

The Sidebar: User Settings

+ +

+ At the bottom of the sidebar you will find some user settings. + Specifically the filtered topics tags you have set and a link to the + settings page. +

+ +

+ When you have filtered topics tags set, topics with any of the tags + present will be removed from your listing. You can read more about it by + going to the dedicated page for it by clicking the{" "} + + "Edit filtered tags" + {" "} + button. +

+ , + ); + + const step09 = renderInContainer( + <> +

The Footer

+ +

+ And finally, the very last part of the homepage is the footer. Here you + will find a theme selector (more on that in a moment) and various links + to places, such as the Tildes Documentation, Contact page, the source + code, etc. We highly recommend reading through the documentation as it + explains a lot of the how and why Tildes does certain things. +

+ +

+ As for the theme selector, you can change your theme with a number of + options. When you change it here, it will only change for the current + device, if you'd like to set an account default for all devices, head to{" "} + + your account settings + + . +

+ , + ); + + const step10 = renderInContainer( + <> +

This is the end, beautiful friend

+ +

And that's the end of the Homepage tour!

+ +

+ As always, if you find any bugs, have feature requests or simply want to + ask a question. Please send us a message at{" "} + + @Community + + . +

+ +

Happy Tildying!~

+ , + ); + + return [ + { + id: "homepage-01", + text: step01, }, - canClickTarget: false, - id: "homepage-02", - scrollTo: true, - text: step02, - }, - { - attachTo: { - element: "main > .listing-options", - on: "bottom", + { + attachTo: { + element: "#site-header", + on: "bottom", + }, + canClickTarget: false, + id: "homepage-02", + scrollTo: true, + text: step02, }, - canClickTarget: false, - id: "homepage-03", - text: step03, - }, - { - attachTo: { - element: ".topic-listing > li:first-child", - on: "bottom", + { + attachTo: { + element: "main > .listing-options", + on: "bottom", + }, + canClickTarget: false, + id: "homepage-03", + text: step03, }, - canClickTarget: false, - id: "homepage-04", - text: step04, - }, - { - attachTo: { - element: ".topic-listing > li:first-child", - on: "bottom", + { + attachTo: { + element: ".topic-listing > li:first-child", + on: "bottom", + }, + canClickTarget: false, + id: "homepage-04", + text: step04, }, - canClickTarget: false, - id: "homepage-05", - text: step05, - }, - { - attachTo: { - element: '#sidebar [data-tildes-shepherd-encapsulated="homepage-06"]', - on: "left-start", + { + attachTo: { + element: ".topic-listing > li:first-child", + on: "bottom", + }, + canClickTarget: false, + id: "homepage-05", + text: step05, }, - canClickTarget: false, - id: "homepage-06", - text: step06, - }, - { - attachTo: { - element: '#sidebar [data-tildes-shepherd-encapsulated="homepage-07"]', - on: "left-start", + { + attachTo: { + element: '#sidebar [data-tildes-shepherd-encapsulated="homepage-06"]', + on: "left-start", + }, + canClickTarget: false, + id: "homepage-06", + text: step06, }, - canClickTarget: false, - id: "homepage-07", - scrollTo: true, - text: step07, - }, - { - attachTo: { - element: "#sidebar .divider + .nav", - on: "left-start", + { + attachTo: { + element: '#sidebar [data-tildes-shepherd-encapsulated="homepage-07"]', + on: "left-start", + }, + canClickTarget: false, + id: "homepage-07", + scrollTo: true, + text: step07, }, - canClickTarget: false, - id: "homepage-08", - scrollTo: true, - text: step08, - }, - { - attachTo: { - element: "#site-footer", - on: "top", + { + attachTo: { + element: "#sidebar .divider + .nav", + on: "left-start", + }, + canClickTarget: false, + id: "homepage-08", + scrollTo: true, + text: step08, }, - canClickTarget: false, - id: "homepage-09", - scrollTo: true, - text: step09, - }, - { - canClickTarget: false, - id: "homepage-10", - text: step10, - }, -]; + { + attachTo: { + element: "#site-footer", + on: "top", + }, + canClickTarget: false, + id: "homepage-09", + scrollTo: true, + text: step09, + }, + { + canClickTarget: false, + id: "homepage-10", + text: step10, + }, + ]; +} + +const steps: TourData["steps"] = renderSteps; const eventHandlers: TourData["eventHandlers"] = [ { diff --git a/source/tours/introduction.tsx b/source/tours/introduction.tsx index 047f5d0..75f327e 100644 --- a/source/tours/introduction.tsx +++ b/source/tours/introduction.tsx @@ -2,128 +2,133 @@ import {fromStorage, StorageKey} from "../storage/common.js"; import {TourId, type TourData} from "./types.js"; import {openOptionsPageFromBackground, renderInContainer} from "./utilities.js"; -const step01 = renderInContainer( - <> -

Thank you for installing Tildes Shepherd!

+function renderSteps(): ReturnType { + const step01 = renderInContainer( + <> +

Thank you for installing Tildes Shepherd!

-

- Tildes Shepherd is a set of interactive guided tours for Tildes to show - you around and introduce you to the concepts that make this website great. -

+

+ Tildes Shepherd is a set of interactive guided tours for Tildes to show + you around and introduce you to the concepts that make this website + great. +

-

- To see and start the tours that are available, click on the extension icon - to go to the options page or{" "} - - click here now - - . -

+

+ To see and start the tours that are available, click on the extension + icon to go to the options page or{" "} + + click here now + + . +

-

- Each tour will start with a pop-up like this one and have "Continue", - "Back" and "Exit" buttons at the bottom. They will progress the tour - forward, backward or exit it. -

- , -); +

+ Each tour will start with a pop-up like this one and have "Continue", + "Back" and "Exit" buttons at the bottom. They will progress the tour + forward, backward or exit it. +

+ , + ); -const step02 = renderInContainer( - <> -

Tour Mechanics

+ const step02 = renderInContainer( + <> +

Tour Mechanics

-

- During the tours at various points we will want to highlight specific - areas. When that happens you won't be able to click anything inside them, - mainly to prevent you from accidentally going to a different page and - interrupting the tour. But also to prevent you from taking actions you - maybe don't want to take, like voting on something you don't necessarily - want to vote on. -

+

+ During the tours at various points we will want to highlight specific + areas. When that happens you won't be able to click anything inside + them, mainly to prevent you from accidentally going to a different page + and interrupting the tour. But also to prevent you from taking actions + you maybe don't want to take, like voting on something you don't + necessarily want to vote on. +

-

- Depending on your selected theme, the highlighted areas will have a yellow - or orange border and some extra added whitespace. As you can see in this - example where the main site header has been highlighted. -

- , -); +

+ Depending on your selected theme, the highlighted areas will have a + yellow or orange border and some extra added whitespace. As you can see + in this example where the main site header has been highlighted. +

+ , + ); -const step03 = renderInContainer( - <> -

- If you find any bugs, have feature requests or simply want to ask a - question. Please send us a message at{" "} - - @Community - - . -

+ const step03 = renderInContainer( + <> +

+ If you find any bugs, have feature requests or simply want to ask a + question. Please send us a message at{" "} + + @Community + + . +

-

- Also, big shoutout to the people at{" "} - - Ship Shape - {" "} - for making{" "} - - Shepherd.js - - , the software library making this entire project so much easier to - create. And the namesake of it, too. -

+

+ Also, big shoutout to the people at{" "} + + Ship Shape + {" "} + for making{" "} + + Shepherd.js + + , the software library making this entire project so much easier to + create. And the namesake of it, too. +

-

- Once you click the "I understand" button below, this tour won't pop up - again, so remember the extension icon is how you get to the tours. -

+

+ Once you click the "I understand" button below, this tour won't pop up + again, so remember the extension icon is how you get to the tours. +

-

Happy Tildying!~

- , -); +

Happy Tildying!~

+ , + ); -const steps: TourData["steps"] = [ - { - canClickTarget: false, - id: "introduction-01", - text: step01, - }, - { - attachTo: { - element: "#site-header", - on: "bottom", + return [ + { + canClickTarget: false, + id: "introduction-01", + text: step01, }, - canClickTarget: false, - id: "introduction-02", - text: step02, - }, - { - buttons: [ - { - classes: "btn", - text: "I understand", - async action() { - const introductionUnderstood = await fromStorage( - StorageKey.IntroductionUnderstood, - ); - introductionUnderstood.value = true; - await introductionUnderstood.save(); - this.complete(); - }, + { + attachTo: { + element: "#site-header", + on: "bottom", }, - { - classes: "btn", - text: "Back", - action() { - this.back(); + canClickTarget: false, + id: "introduction-02", + text: step02, + }, + { + buttons: [ + { + classes: "btn", + text: "I understand", + async action() { + const introductionUnderstood = await fromStorage( + StorageKey.IntroductionUnderstood, + ); + introductionUnderstood.value = true; + await introductionUnderstood.save(); + this.complete(); + }, }, - }, - ], - canClickTarget: false, - id: "introduction-03", - text: step03, - }, -]; + { + classes: "btn", + text: "Back", + action() { + this.back(); + }, + }, + ], + canClickTarget: false, + id: "introduction-03", + text: step03, + }, + ]; +} + +const steps: TourData["steps"] = renderSteps; const eventHandlers: TourData["eventHandlers"] = []; diff --git a/source/tours/types.ts b/source/tours/types.ts index b6e6ff5..99d92ad 100644 --- a/source/tours/types.ts +++ b/source/tours/types.ts @@ -50,8 +50,8 @@ export type TourData = { /** The requirements this tour must match before starting it. */ requirements: TourRequirement; - /** All the steps this tour will take. */ - steps: Shepherd.Step.StepOptions[]; + /** A function that returns all the steps this tour will take. */ + steps: () => Shepherd.Step.StepOptions[]; /** The title of the tour for use in the options page. */ title: string;