diff --git a/docs-src/tutorials/02-usage.md b/docs-src/tutorials/02-usage.md index ffa678fd5..9842a1171 100644 --- a/docs-src/tutorials/02-usage.md +++ b/docs-src/tutorials/02-usage.md @@ -197,9 +197,11 @@ the step will execute. For example: - `label` The label to add for `aria-label` - `classes`: A string of extra classes to add to the step's content element. - `buttons`: An array of buttons to add to the step. These will be rendered in a footer below the main body text. Each button in the array is an object of the format: - - `text`: The HTML text of the button + - `label`: The label to add for `aria-label`. It can also be a function that returns a string (useful with i18n solutions). + - `disabled`: A boolean that controls the `disabled` attribute. It can also be a function that returns a boolean. - `classes`: Extra classes to apply to the `` - `secondary`: A boolean, that when true, adds a `shepherd-button-secondary` class to the button + - `text`: The HTML text of the button. It can also be a function that returns a string (useful with i18n solutions). - `action`: A function executed when the button is clicked on. It is automatically bound to the `tour` the step is associated with, so things like `this.next` will work inside the action. You can use action to skip steps or navigate to specific steps, with something like: @@ -209,7 +211,7 @@ the step will execute. For example: } ``` - `advanceOn`: An action on the page which should advance shepherd to the next step. It should be an object with a string `selector` and an `event` name. -For example: `{selector: '.some-element', event: 'click'}`. It doesn't have to be an event inside the tour, it can be any event fired on any element on the page. +For example: `{selector: '.some-element', event: 'click'}`. It doesn't have to be an event inside the tour, it can be any event fired on any element on the page. You can also always manually advance the Tour by calling `myTour.next()`. - `highlightClass`: An extra class to apply to the `attachTo` element when it is highlighted (that is, when its step is active). You can then target that selector in your CSS. - `id`: The string to use as the `id` for the step. If an id is not passed one will be generated. diff --git a/src/js/components/shepherd-button.svelte b/src/js/components/shepherd-button.svelte index 68e063b27..3caf30716 100644 --- a/src/js/components/shepherd-button.svelte +++ b/src/js/components/shepherd-button.svelte @@ -7,17 +7,17 @@ $: { action = config.action ? config.action.bind(step.tour) : null; classes = config.classes; - disabled = config.disabled ? getDisabled(config.disabled) : false; - label = config.label; + disabled = config.disabled ? getConfigOption(config.disabled) : false; + label = config.label ? getConfigOption(config.label) : null; secondary = config.secondary; - text = config.text; + text = config.text ? getConfigOption(config.text) : null; } - function getDisabled(disabled) { - if (isFunction(disabled)) { - return disabled = disabled.call(step); - } - return disabled + function getConfigOption(option) { + if (isFunction(option)) { + return option = option.call(step); + } + return option; } diff --git a/src/types/step.d.ts b/src/types/step.d.ts index 5fc5b6bb7..d44de2f17 100644 --- a/src/types/step.d.ts +++ b/src/types/step.d.ts @@ -269,7 +269,7 @@ declare namespace Step { /** * The aria-label text of the button */ - label?: string; + label?: string | (() => string); /** * A boolean, that when true, adds a `shepherd-button-secondary` class to the button. @@ -279,7 +279,7 @@ declare namespace Step { /** * The HTML text of the button */ - text?: string; + text?: string | (() => string); } interface StepOptionsButtonEvent { diff --git a/test/unit/components/shepherd-button.spec.js b/test/unit/components/shepherd-button.spec.js index 9ee44c190..df9a736b4 100644 --- a/test/unit/components/shepherd-button.spec.js +++ b/test/unit/components/shepherd-button.spec.js @@ -93,6 +93,34 @@ describe('component/ShepherdButton', () => { expect(button).toHaveAttribute('aria-label', '5'); }); + it('label - funtion', () => { + let label = 'Test'; + const labelFunction = () => label; + const config = { + label: labelFunction + }; + + const { container, rerender } = render(ShepherdButton, { + props: { + config + } + }); + + const button = container.querySelector('.shepherd-button'); + expect(button).toHaveAttribute('aria-label', 'Test'); + + label = 'Test 2'; + + rerender({ + props: { + config + } + }); + + const buttonUpdated = container.querySelector('.shepherd-button'); + expect(buttonUpdated).toHaveAttribute('aria-label', 'Test 2'); + }); + it('label - null', () => { const config = { label: null @@ -120,5 +148,48 @@ describe('component/ShepherdButton', () => { const button = container.querySelector('.shepherd-button'); expect(button).not.toHaveAttribute('aria-label'); }); + + it('text - string', () => { + const config = { + text: 'Test' + }; + + const { container } = render(ShepherdButton, { + props: { + config + } + }); + + const button = container.querySelector('.shepherd-button'); + expect(button).toHaveTextContent('Test'); + }); + + it('text - function', () => { + let text = 'Test'; + const textFunction = () => text; + const config = { + text: textFunction + }; + + const { container, rerender } = render(ShepherdButton, { + props: { + config + } + }); + + const button = container.querySelector('.shepherd-button'); + expect(button).toHaveTextContent('Test'); + + text = 'Test 2'; + + rerender({ + props: { + config + } + }); + + const buttonUpdated = container.querySelector('.shepherd-button'); + expect(buttonUpdated).toHaveTextContent('Test 2'); + }); }); });