Skip to content

Conversation

@hlopez94
Copy link

@hlopez94 hlopez94 commented Jan 14, 2026

This pull request adds support for custom data-* attributes to the Shepherd tour button and cancel icon components, allowing users to pass arbitrary data attributes via configuration. It introduces a new utility function to handle conversion of these attributes and includes comprehensive unit tests to ensure correct behavior across various scenarios.

Component enhancements:

  • Added support for spreading custom data-* attributes on the shepherd-button and shepherd-cancel-icon components by using a new convertDataAttributes utility. This enables passing attributes like data-test, data-step, etc., via the config. [1] [2] [3] [4] [5]

Utility function:

  • Introduced convertDataAttributes in data-attributes.ts, which converts an array of { id, value } objects into a dictionary of data-* attributes for easy spreading onto HTML elements. Handles string, number, boolean, and edge cases.

Testing:

  • Added extensive unit tests for the new utility function to cover empty, undefined, mixed types, duplicates, and special cases.
  • Added new tests for shepherd-button to verify correct application of single, multiple, numeric, boolean, and edge-case data attributes.
  • Added tests for shepherd-header to verify that the cancel icon correctly renders with custom data attributes and label combinations.

Closes #2036

Summary by CodeRabbit

  • New Features

    • Components now support custom data-* attributes for attaching arbitrary data to DOM elements.
    • Added a utility to convert structured attribute data into data-* key/value pairs for consistent usage.
  • Tests

    • Comprehensive unit tests added for data-* attribute handling across components and the new utility.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel
Copy link

vercel bot commented Jan 14, 2026

@hlopez94 is attempting to deploy a commit to the shipshapecode Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Jan 14, 2026

📝 Walkthrough

Walkthrough

Adds a utility to convert DataAttribute arrays into HTML data-* attributes, applies it to Shepherd button and cancel-icon components (spreading resulting attributes onto buttons), and introduces comprehensive unit tests covering conversion and component rendering for various dataAttribute cases.

Changes

Cohort / File(s) Summary
Data Attributes Utility
shepherd.js/src/utils/data-attributes.ts, test/unit/utils/data-attributes.spec.js
New DataAttribute interface and convertDataAttributes function that returns a Record<string,string> of data- attributes; tests cover undefined/null/empty, type conversions, special characters, duplicates, and edge cases.
Button component
shepherd.js/src/components/shepherd-button.svelte
Imports convertDataAttributes, derives dataAttrs from config, and spreads {...dataAttrs} onto the button to render data-* attributes.
Cancel icon component
shepherd.js/src/components/shepherd-cancel-icon.svelte
Imports convertDataAttributes, derives dataAttrs from cancelIcon.dataAttributes, and spreads {...dataAttrs} onto the cancel button.
Component tests & header integration
test/unit/components/shepherd-button.spec.js, test/unit/components/shepherd-cancel-icon.spec.js, test/unit/components/shepherd-header.spec.js
New/expanded tests validating application of single/multiple numeric/boolean/string/special-character data-* attributes, handling of empty/undefined/null/missing-id entries, interaction with labels/classes, click behavior, and header rendering with cancel icon.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰
I hopped in code with eager paws,
and stitched new tags without a pause.
Buttons and cancels wear data bright,
now tests applaud the morning light.
Hop, tag, and ship — a dev's delight! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main change: adding data attributes support to CancelIcon and Button components.
Linked Issues check ✅ Passed The PR fully addresses issue #2036 by implementing data attributes support for cancel icon and button components with comprehensive tests.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing data attributes support as specified in issue #2036; no out-of-scope modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

🧹 Recent nitpick comments
shepherd.js/src/utils/data-attributes.ts (1)

32-40: Consider adding a null-check for array elements for runtime safety.

If the dataAttributes array contains null or undefined elements at runtime, accessing attr.id will throw a TypeError. While TypeScript typing should prevent this at compile time, adding a defensive check would improve robustness when handling external data.

🛡️ Suggested defensive check
   return dataAttributes.reduce(
     (acc, attr) => {
-      if (attr.id) {
+      if (attr?.id) {
         acc[`data-${attr.id}`] = String(attr.value);
       }
       return acc;
     },
     {} as Record<string, string>
   );

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42e9210 and d415f49.

📒 Files selected for processing (1)
  • shepherd.js/src/utils/data-attributes.ts
🔇 Additional comments (1)
shepherd.js/src/utils/data-attributes.ts (1)

1-7: LGTM!

The interface is well-documented with clear JSDoc and appropriate type constraints for the value property.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@test/unit/components/shepherd-cancel-icon.spec.js`:
- Around line 55-73: The assertion in the test "renders close symbol (&times;)"
is wrong because textContent returns the decoded character; update the
expectation for the queried element (closeSymbol from
container.querySelector('span[aria-hidden="true"]')) to assert the actual
multiplication sign character (×) instead of the literal "&times;". If the
component is supposed to render the raw entity text rather than the decoded
symbol, change the assertion to check innerHTML (closeSymbol.innerHTML) for the
string "&times;" instead.
🧹 Nitpick comments (2)
shepherd.js/src/utils/data-attributes.ts (1)

25-37: Consider validating attribute id format.

The implementation is clean and handles edge cases well. However, there's no validation that attr.id contains valid characters for a data attribute name. HTML5 data-* attribute names must not contain uppercase letters and should follow specific naming conventions.

For example, an id with spaces like "my attr" would produce data-my attr which is invalid HTML.

💡 Optional: Add id format validation
 return dataAttributes.reduce((acc, attr) => {
-  if (attr.id) {
+  if (attr.id && /^[a-z][a-z0-9-]*$/i.test(attr.id)) {
     acc[`data-${attr.id}`] = String(attr.value);
   }
   return acc;
 }, {} as Record<string, string>);

Alternatively, you could sanitize the id by converting to lowercase and replacing invalid characters, or simply document that consumers are responsible for valid ids.

test/unit/components/shepherd-cancel-icon.spec.js (1)

416-435: Weak assertion doesn't verify transparent background.

The test name says "button has transparent background" but the assertion expect(cancelIcon.style.background || styles.background).toBeTruthy() only checks that some background value exists, not that it's transparent. This test would pass for any background value including opaque colors.

Consider either:

  1. Removing this test if styling is tested elsewhere (CSS unit tests)
  2. Making the assertion more specific if transparency verification is important
Option: Remove or improve the assertion

If you want to actually test for transparency:

       const cancelIcon = container.querySelector('.shepherd-cancel-icon');
       const styles = window.getComputedStyle(cancelIcon);
-      // Basic style checks - specific values might vary based on CSS
-      expect(cancelIcon.style.background || styles.background).toBeTruthy();
+      // Verify transparent or no background
+      expect(styles.backgroundColor).toMatch(/transparent|rgba\(0,\s*0,\s*0,\s*0\)/);

Or remove the test if CSS is validated elsewhere:

-    it('button has transparent background', () => {
-      // ... entire test ...
-    });
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 857d481 and 42e9210.

📒 Files selected for processing (7)
  • shepherd.js/src/components/shepherd-button.svelte
  • shepherd.js/src/components/shepherd-cancel-icon.svelte
  • shepherd.js/src/utils/data-attributes.ts
  • test/unit/components/shepherd-button.spec.js
  • test/unit/components/shepherd-cancel-icon.spec.js
  • test/unit/components/shepherd-header.spec.js
  • test/unit/utils/data-attributes.spec.js
🧰 Additional context used
🧬 Code graph analysis (3)
test/unit/components/shepherd-header.spec.js (1)
test/unit/test-helpers.js (1)
  • container (6-6)
test/unit/utils/data-attributes.spec.js (1)
shepherd.js/src/utils/data-attributes.ts (1)
  • convertDataAttributes (25-38)
test/unit/components/shepherd-cancel-icon.spec.js (2)
shepherd.js/src/tour.ts (1)
  • Tour (106-470)
shepherd.js/src/step.ts (1)
  • Step (305-727)
🔇 Additional comments (18)
shepherd.js/src/utils/data-attributes.ts (1)

1-7: LGTM!

The DataAttribute interface is well-defined with appropriate types for the value field supporting strings, numbers, and booleans.

shepherd.js/src/components/shepherd-button.svelte (1)

3-3: LGTM!

Clean integration of the data attributes feature. The use of $derived ensures reactivity, and spreading the attributes at the end of the button element is the correct approach.

Also applies to: 22-23, 35-35

shepherd.js/src/components/shepherd-cancel-icon.svelte (1)

2-2: LGTM!

This directly addresses issue #2036. The implementation is consistent with the button component, and correctly sources dataAttributes from the cancelIcon config object alongside the existing label property.

Also applies to: 14-14, 22-22

test/unit/utils/data-attributes.spec.js (1)

1-123: Excellent test coverage!

The test suite comprehensively covers:

  • Null/undefined/empty inputs
  • Single and multiple attributes
  • Type coercion for numbers and booleans
  • Invalid inputs (missing/empty id)
  • Edge cases (zero, empty string, special characters)
  • Duplicate handling behavior

This provides strong confidence in the utility's behavior.

test/unit/components/shepherd-button.spec.js (1)

197-341: LGTM!

Comprehensive integration tests that verify the data attributes feature works correctly at the component level. The tests smartly verify:

  • Single and multiple attributes render correctly
  • Type coercion works in the DOM
  • Empty/undefined inputs don't break the component
  • Invalid inputs are filtered out
  • Feature works alongside existing button properties

Good use of attribute filtering (lines 269-272, 309-312) to verify exact attribute counts.

test/unit/components/shepherd-header.spec.js (5)

92-114: LGTM!

Good test coverage for the new dataAttributes feature on the cancel icon. The test properly validates that multiple data attributes are correctly applied to the element.


116-140: LGTM!

Solid integration test verifying that both label and dataAttributes work correctly together, ensuring no conflicts between existing and new functionality.


142-174: LGTM!

Title rendering tests are clear and cover both positive and negative cases appropriately.


176-198: LGTM!

Good integration test ensuring title and cancel icon render correctly when both are provided.


200-217: LGTM!

Appropriate structural test verifying the header element's CSS class and semantic HTML tag.

test/unit/components/shepherd-cancel-icon.spec.js (8)

10-31: LGTM!

Good basic functionality tests covering default aria-label and button type attributes.


32-53: LGTM!

Properly tests custom aria-label override functionality.


76-125: LGTM!

Click behavior tests are well-implemented, including proper async handling and verification of preventDefault being called.


127-176: LGTM!

Excellent coverage of single and multiple data attributes with proper assertions.


178-228: LGTM!

Good tests for type coercion of numeric and boolean values to strings, which is the expected HTML data attribute behavior.


230-298: LGTM!

Comprehensive edge case coverage for empty, undefined, and null dataAttributes inputs.


300-361: LGTM!

Good test coverage for invalid entries (missing/empty id) and special characters in values.


364-394: LGTM!

Good integration test verifying label and dataAttributes work together correctly.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

How to add data attributes on cancel Icon?

1 participant