diff --git a/example/index.html b/example/index.html index 5cb2809a6..f1f92aabd 100644 --- a/example/index.html +++ b/example/index.html @@ -39,6 +39,7 @@

Examples

  • Basic hints usage
  • Basic hints usage on an element
  • Programmatic defining hints using JSON
  • +
  • Language Import Example
  • diff --git a/example/language-import/index.html b/example/language-import/index.html new file mode 100644 index 000000000..d792139d0 --- /dev/null +++ b/example/language-import/index.html @@ -0,0 +1,295 @@ + + + + + Intro.js Language Import Example + + + + + + + + + + +
    +

    + Intro.js Language Import Example +

    + +

    This example demonstrates how to import language files directly from intro.js and use them in your tours.

    + +
    + + + + + +
    + +
    +

    Step 2: Content Area

    +

    This area contains some sample content for the tour demonstration.

    +
    + +
    +

    Step 3: Features Section

    +

    This section showcases different features and capabilities.

    +
    + +
    +

    Step 4: Final Section

    +

    This is the last step of our tour. Thank you for following along!

    +
    + +

    Code Examples

    + +

    Method 1: ES6 Module Import (Recommended)

    +
    +// Import specific language files +import introJs, { es_ES, fr_FR, de_DE, fa_IR } from 'intro.js'; + +// Use imported language +function startSpanishTour() { + introJs.tour().setOptions({ + language: es_ES, + showStepNumbers: true, + steps: [ + { element: '#step1', intro: 'Bienvenido al ejemplo' }, + { element: '#step2', intro: 'Este es el segundo paso' }, + { element: '#step3', intro: 'Aquí puedes ver más características' }, + { element: '#step4', intro: 'Este es el paso final' } + ] + }).start(); +} +
    + +

    Method 2: Dynamic Import (For Lazy Loading)

    +
    +// Dynamic import for lazy loading +async function startSpanishTour() { + const { es_ES } = await import('intro.js'); + + introJs.tour().setOptions({ + language: es_ES, + steps: [/* your steps */] + }).start(); +} +
    + +

    Method 3: CommonJS Require (Node.js)

    +
    +// CommonJS import +const introJs = require('intro.js'); +const { es_ES, fr_FR } = require('intro.js'); + +// Use the imported language +introJs.tour().setOptions({ + language: es_ES +}).start(); +
    +
    + + + + + diff --git a/src/index.ts b/src/index.ts index b315cb5c1..c9819f952 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,6 +2,14 @@ import { version } from "../package.json"; import { Hint } from "./packages/hint"; import { Tour } from "./packages/tour"; +// Export language files for direct import +export { default as en_US } from "./i18n/en_US"; +export { default as es_ES } from "./i18n/es_ES"; +export { default as fr_FR } from "./i18n/fr_FR"; +export { default as de_DE } from "./i18n/de_DE"; +export { default as fa_IR } from "./i18n/fa_IR"; +export { Translator, type Language } from "./i18n/language"; + class LegacyIntroJs extends Tour { /** * @deprecated introJs().addHints() is deprecated, please use introJs.hint().addHints() instead diff --git a/src/packages/tour/components/TourTooltip.ts b/src/packages/tour/components/TourTooltip.ts index bb16ece9e..7567febe0 100644 --- a/src/packages/tour/components/TourTooltip.ts +++ b/src/packages/tour/components/TourTooltip.ts @@ -331,13 +331,11 @@ const Buttons = ({ }; export const Header = ({ - text, title, skipLabel, renderAsHtml, onSkipClick, }: { - text: string; title: string; skipLabel: string; renderAsHtml?: boolean; @@ -468,7 +466,7 @@ export const TourTooltip = ({ const text = step.intro; const position = step.position; - children.push(Header({ text, title, skipLabel, renderAsHtml, onSkipClick })); + children.push(Header({ title, skipLabel, renderAsHtml, onSkipClick })); children.push( TooltipContent({ diff --git a/src/packages/tour/mock.ts b/src/packages/tour/mock.ts index f8efab675..c87e1a13a 100644 --- a/src/packages/tour/mock.ts +++ b/src/packages/tour/mock.ts @@ -6,6 +6,7 @@ import { dataPosition, dataStepAttribute, } from "./dataAttributes"; +import { title } from "process"; const { div, b, a, h1 } = dom.tags; @@ -23,7 +24,7 @@ export const appendMockSteps = (targetElement: HTMLElement = document.body) => { "Mock element second to last" ); mockElementThree.setAttribute(dataStepAttribute, "10"); - + mockElementThree.setAttribute(title, "this is title"); const mockElementFour = a(); mockElementFour.setAttribute(dataIntroAttribute, "Mock element last"); mockElementFour.setAttribute(dataStepAttribute, "20"); @@ -54,12 +55,14 @@ export const getMockPartialSteps = (): Partial[] => { element: "h1", }, { + title: "second title", intro: "Step Four of the tour", position: "right", scrollTo: "off", element: document.createElement("div"), }, { + title: "third title", element: ".not-found", intro: "Element not found", }, diff --git a/src/packages/tour/option.ts b/src/packages/tour/option.ts index cfa8ba978..825fc9826 100644 --- a/src/packages/tour/option.ts +++ b/src/packages/tour/option.ts @@ -125,3 +125,52 @@ export function getDefaultTourOptions(language: Language = enUS): TourOptions { language, }; } + +/** + * Update tour options with language-aware handling + * When language is changed, automatically update button labels and messages + */ +export function setTourOptions( + options: TourOptions, + partialOptions: Partial +): TourOptions { + // If language is being set, update the translated labels automatically + if (partialOptions.language) { + const translator = new Translator(partialOptions.language); + + // Only update labels if they weren't explicitly provided in partialOptions + const updatedOptions: Partial = { + ...partialOptions, + }; + + // Update button labels if not explicitly provided + if (!partialOptions.nextLabel) { + updatedOptions.nextLabel = translator.translate("buttons.next"); + } + if (!partialOptions.prevLabel) { + updatedOptions.prevLabel = translator.translate("buttons.prev"); + } + if (!partialOptions.doneLabel) { + updatedOptions.doneLabel = translator.translate("buttons.done"); + } + if (!partialOptions.stepNumbersOfLabel) { + updatedOptions.stepNumbersOfLabel = translator.translate( + "messages.stepNumbersOfLabel" + ); + } + if (!partialOptions.dontShowAgainLabel) { + updatedOptions.dontShowAgainLabel = translator.translate( + "messages.dontShowAgainLabel" + ); + } + + partialOptions = updatedOptions; + } + + // Apply all options + for (const [key, value] of Object.entries(partialOptions)) { + (options as any)[key] = value; + } + + return options; +} diff --git a/src/packages/tour/tour.ts b/src/packages/tour/tour.ts index d1b6f1d76..c6aca49da 100644 --- a/src/packages/tour/tour.ts +++ b/src/packages/tour/tour.ts @@ -10,8 +10,8 @@ import { introSkipCallback, introStartCallback, } from "./callback"; -import { getDefaultTourOptions, TourOptions } from "./option"; -import { setOptions, setOption } from "../../option"; +import { getDefaultTourOptions, TourOptions, setTourOptions } from "./option"; +import { setOption } from "../../option"; import { start } from "./start"; import exitIntro from "./exitIntro"; import isFunction from "../../util/isFunction"; @@ -62,7 +62,7 @@ export class Tour implements Package { ) { this._targetElement = getContainerElement(elementOrSelector); this._options = options - ? setOptions(this._options, options) + ? setTourOptions(getDefaultTourOptions(), options) : getDefaultTourOptions(); } @@ -293,7 +293,7 @@ export class Tour implements Package { * @param partialOptions key/value pair of options */ setOptions(partialOptions: Partial): this { - this._options = setOptions(this._options, partialOptions); + this._options = setTourOptions(this._options, partialOptions); return this; } diff --git a/src/util/clssName.test.ts b/src/util/className.test.ts similarity index 100% rename from src/util/clssName.test.ts rename to src/util/className.test.ts