diff --git a/libs/core/src/components.d.ts b/libs/core/src/components.d.ts
index 239a7802e..ff046805b 100644
--- a/libs/core/src/components.d.ts
+++ b/libs/core/src/components.d.ts
@@ -1352,6 +1352,38 @@ export namespace Components {
* @example Opens in new tab
*/
"target"?: '_blank' | '_self' | '_parent' | '_top';
+ /**
+ * Enables or disables Turbo Drive for this link. Maps to the `data-turbo` attribute on the inner anchor element.
+ */
+ "turbo"?: string;
+ /**
+ * Controls the Turbo visit action type. Maps to the `data-turbo-action` attribute on the inner anchor element.
+ */
+ "turboAction"?: 'advance' | 'replace';
+ /**
+ * Displays a confirmation dialog before navigating. Maps to the `data-turbo-confirm` attribute on the inner anchor element.
+ */
+ "turboConfirm"?: string;
+ /**
+ * Specifies the Turbo Frame to target for navigation. Maps to the `data-turbo-frame` attribute on the inner anchor element.
+ */
+ "turboFrame"?: string;
+ /**
+ * Changes the HTTP method for the link request. Maps to the `data-turbo-method` attribute on the inner anchor element.
+ */
+ "turboMethod"?: 'get' | 'post' | 'put' | 'patch' | 'delete';
+ /**
+ * Controls link prefetching on hover. Maps to the `data-turbo-prefetch` attribute on the inner anchor element.
+ */
+ "turboPrefetch"?: string;
+ /**
+ * Eagerly preloads the link's destination into cache. Maps to the `data-turbo-preload` attribute on the inner anchor element.
+ */
+ "turboPreload"?: string;
+ /**
+ * Accepts Turbo Stream responses for GET requests. Maps to the `data-turbo-stream` attribute on the inner anchor element.
+ */
+ "turboStream"?: string;
/**
* Sets the link variant styles.
* @defaultValue inline
@@ -4472,6 +4504,38 @@ declare namespace LocalJSX {
* @example Opens in new tab
*/
"target"?: '_blank' | '_self' | '_parent' | '_top';
+ /**
+ * Enables or disables Turbo Drive for this link. Maps to the `data-turbo` attribute on the inner anchor element.
+ */
+ "turbo"?: string;
+ /**
+ * Controls the Turbo visit action type. Maps to the `data-turbo-action` attribute on the inner anchor element.
+ */
+ "turboAction"?: 'advance' | 'replace';
+ /**
+ * Displays a confirmation dialog before navigating. Maps to the `data-turbo-confirm` attribute on the inner anchor element.
+ */
+ "turboConfirm"?: string;
+ /**
+ * Specifies the Turbo Frame to target for navigation. Maps to the `data-turbo-frame` attribute on the inner anchor element.
+ */
+ "turboFrame"?: string;
+ /**
+ * Changes the HTTP method for the link request. Maps to the `data-turbo-method` attribute on the inner anchor element.
+ */
+ "turboMethod"?: 'get' | 'post' | 'put' | 'patch' | 'delete';
+ /**
+ * Controls link prefetching on hover. Maps to the `data-turbo-prefetch` attribute on the inner anchor element.
+ */
+ "turboPrefetch"?: string;
+ /**
+ * Eagerly preloads the link's destination into cache. Maps to the `data-turbo-preload` attribute on the inner anchor element.
+ */
+ "turboPreload"?: string;
+ /**
+ * Accepts Turbo Stream responses for GET requests. Maps to the `data-turbo-stream` attribute on the inner anchor element.
+ */
+ "turboStream"?: string;
/**
* Sets the link variant styles.
* @defaultValue inline
diff --git a/libs/core/src/components/pds-link/pds-link.tsx b/libs/core/src/components/pds-link/pds-link.tsx
index 6d71ada83..d805268d0 100644
--- a/libs/core/src/components/pds-link/pds-link.tsx
+++ b/libs/core/src/components/pds-link/pds-link.tsx
@@ -62,6 +62,54 @@ export class PdsLink {
*/
@Prop() href!: string;
+ /**
+ * Enables or disables Turbo Drive for this link.
+ * Maps to the `data-turbo` attribute on the inner anchor element.
+ */
+ @Prop() turbo?: string;
+
+ /**
+ * Specifies the Turbo Frame to target for navigation.
+ * Maps to the `data-turbo-frame` attribute on the inner anchor element.
+ */
+ @Prop() turboFrame?: string;
+
+ /**
+ * Controls the Turbo visit action type.
+ * Maps to the `data-turbo-action` attribute on the inner anchor element.
+ */
+ @Prop() turboAction?: 'advance' | 'replace';
+
+ /**
+ * Changes the HTTP method for the link request.
+ * Maps to the `data-turbo-method` attribute on the inner anchor element.
+ */
+ @Prop() turboMethod?: 'get' | 'post' | 'put' | 'patch' | 'delete';
+
+ /**
+ * Displays a confirmation dialog before navigating.
+ * Maps to the `data-turbo-confirm` attribute on the inner anchor element.
+ */
+ @Prop() turboConfirm?: string;
+
+ /**
+ * Accepts Turbo Stream responses for GET requests.
+ * Maps to the `data-turbo-stream` attribute on the inner anchor element.
+ */
+ @Prop() turboStream?: string;
+
+ /**
+ * Controls link prefetching on hover.
+ * Maps to the `data-turbo-prefetch` attribute on the inner anchor element.
+ */
+ @Prop() turboPrefetch?: string;
+
+ /**
+ * Eagerly preloads the link's destination into cache.
+ * Maps to the `data-turbo-preload` attribute on the inner anchor element.
+ */
+ @Prop() turboPreload?: string;
+
private classNames() {
const classNames = ['pds-link'];
@@ -105,6 +153,14 @@ export class PdsLink {
target={targetValue}
rel={relValue}
style={this.setLinkStyles()}
+ data-turbo={this.turbo || undefined}
+ data-turbo-frame={this.turboFrame || undefined}
+ data-turbo-action={this.turboAction || undefined}
+ data-turbo-method={this.turboMethod || undefined}
+ data-turbo-confirm={this.turboConfirm || undefined}
+ data-turbo-stream={this.turboStream || undefined}
+ data-turbo-prefetch={this.turboPrefetch || undefined}
+ data-turbo-preload={this.turboPreload || undefined}
>
{this.href}
{showExternalIcon &&
diff --git a/libs/core/src/components/pds-link/readme.md b/libs/core/src/components/pds-link/readme.md
index 2f6076467..cce0d8170 100644
--- a/libs/core/src/components/pds-link/readme.md
+++ b/libs/core/src/components/pds-link/readme.md
@@ -7,16 +7,24 @@ Link is mainly used as navigational element and usually appear within or directl
## Properties
-| Property | Attribute | Description | Type | Default |
-| ------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | ----------- |
-| `color` | `color` | Sets the link color. | `string` | `undefined` |
-| `componentId` | `component-id` | A unique identifier used for the underlying component `id` attribute. | `string` | `undefined` |
-| `download` | `download` | Prompts the user to save the linked URL instead of navigating to it. It can be used without a value to download with the default filename, or with a string value to suggest a specific filename for the download. | `string` | `undefined` |
-| `external` | `external` | **[DEPRECATED]** Consider using the `target` prop for more control. This prop will be maintained for backward compatibility.
Determines whether the link should open in a new tab. | `boolean` | `false` |
-| `fontSize` | `font-size` | The font size of the link's text. | `"lg" \| "md" \| "sm"` | `'lg'` |
-| `href` _(required)_ | `href` | The hyperlink's destination URL. If no text is provided in the custom slot, the href will be used. | `string` | `undefined` |
-| `target` | `target` | Specifies where to open the linked document. | `"_blank" \| "_parent" \| "_self" \| "_top"` | `undefined` |
-| `variant` | `variant` | Sets the link variant styles. | `"inline" \| "plain"` | `'inline'` |
+| Property | Attribute | Description | Type | Default |
+| ------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------- | ----------- |
+| `color` | `color` | Sets the link color. | `string` | `undefined` |
+| `componentId` | `component-id` | A unique identifier used for the underlying component `id` attribute. | `string` | `undefined` |
+| `download` | `download` | Prompts the user to save the linked URL instead of navigating to it. It can be used without a value to download with the default filename, or with a string value to suggest a specific filename for the download. | `string` | `undefined` |
+| `external` | `external` | **[DEPRECATED]** Consider using the `target` prop for more control. This prop will be maintained for backward compatibility.
Determines whether the link should open in a new tab. | `boolean` | `false` |
+| `fontSize` | `font-size` | The font size of the link's text. | `"lg" \| "md" \| "sm"` | `'lg'` |
+| `href` _(required)_ | `href` | The hyperlink's destination URL. If no text is provided in the custom slot, the href will be used. | `string` | `undefined` |
+| `target` | `target` | Specifies where to open the linked document. | `"_blank" \| "_parent" \| "_self" \| "_top"` | `undefined` |
+| `turbo` | `turbo` | Enables or disables Turbo Drive for this link. Maps to the `data-turbo` attribute on the inner anchor element. | `string` | `undefined` |
+| `turboAction` | `turbo-action` | Controls the Turbo visit action type. Maps to the `data-turbo-action` attribute on the inner anchor element. | `"advance" \| "replace"` | `undefined` |
+| `turboConfirm` | `turbo-confirm` | Displays a confirmation dialog before navigating. Maps to the `data-turbo-confirm` attribute on the inner anchor element. | `string` | `undefined` |
+| `turboFrame` | `turbo-frame` | Specifies the Turbo Frame to target for navigation. Maps to the `data-turbo-frame` attribute on the inner anchor element. | `string` | `undefined` |
+| `turboMethod` | `turbo-method` | Changes the HTTP method for the link request. Maps to the `data-turbo-method` attribute on the inner anchor element. | `"delete" \| "get" \| "patch" \| "post" \| "put"` | `undefined` |
+| `turboPrefetch` | `turbo-prefetch` | Controls link prefetching on hover. Maps to the `data-turbo-prefetch` attribute on the inner anchor element. | `string` | `undefined` |
+| `turboPreload` | `turbo-preload` | Eagerly preloads the link's destination into cache. Maps to the `data-turbo-preload` attribute on the inner anchor element. | `string` | `undefined` |
+| `turboStream` | `turbo-stream` | Accepts Turbo Stream responses for GET requests. Maps to the `data-turbo-stream` attribute on the inner anchor element. | `string` | `undefined` |
+| `variant` | `variant` | Sets the link variant styles. | `"inline" \| "plain"` | `'inline'` |
## Slots
diff --git a/libs/core/src/components/pds-link/test/pds-link.spec.tsx b/libs/core/src/components/pds-link/test/pds-link.spec.tsx
index 54ab69c75..4b27ddcc3 100644
--- a/libs/core/src/components/pds-link/test/pds-link.spec.tsx
+++ b/libs/core/src/components/pds-link/test/pds-link.spec.tsx
@@ -118,4 +118,115 @@ describe('pds-link', () => {
const anchor = root?.shadowRoot?.querySelector('a');
expect(anchor?.getAttribute('download')).toBe('my-file.pdf');
});
+
+ describe('turbo props', () => {
+ it('renders data-turbo on the inner anchor', async () => {
+ const { root } = await newSpecPage({
+ components: [PdsLink],
+ html: `Page`,
+ });
+
+ const anchor = root?.shadowRoot?.querySelector('a');
+ expect(anchor?.getAttribute('data-turbo')).toBe('true');
+ });
+
+ it('renders data-turbo-frame on the inner anchor', async () => {
+ const { root } = await newSpecPage({
+ components: [PdsLink],
+ html: `Page`,
+ });
+
+ const anchor = root?.shadowRoot?.querySelector('a');
+ expect(anchor?.getAttribute('data-turbo-frame')).toBe('admin-content');
+ });
+
+ it('renders data-turbo-action on the inner anchor', async () => {
+ const { root } = await newSpecPage({
+ components: [PdsLink],
+ html: `Page`,
+ });
+
+ const anchor = root?.shadowRoot?.querySelector('a');
+ expect(anchor?.getAttribute('data-turbo-action')).toBe('replace');
+ });
+
+ it('renders data-turbo-method on the inner anchor', async () => {
+ const { root } = await newSpecPage({
+ components: [PdsLink],
+ html: `Delete`,
+ });
+
+ const anchor = root?.shadowRoot?.querySelector('a');
+ expect(anchor?.getAttribute('data-turbo-method')).toBe('delete');
+ });
+
+ it('renders data-turbo-confirm on the inner anchor', async () => {
+ const { root } = await newSpecPage({
+ components: [PdsLink],
+ html: `Delete`,
+ });
+
+ const anchor = root?.shadowRoot?.querySelector('a');
+ expect(anchor?.getAttribute('data-turbo-confirm')).toBe('Are you sure?');
+ });
+
+ it('renders data-turbo-stream on the inner anchor', async () => {
+ const { root } = await newSpecPage({
+ components: [PdsLink],
+ html: `Page`,
+ });
+
+ const anchor = root?.shadowRoot?.querySelector('a');
+ expect(anchor?.getAttribute('data-turbo-stream')).toBe('true');
+ });
+
+ it('renders data-turbo-prefetch on the inner anchor', async () => {
+ const { root } = await newSpecPage({
+ components: [PdsLink],
+ html: `Page`,
+ });
+
+ const anchor = root?.shadowRoot?.querySelector('a');
+ expect(anchor?.getAttribute('data-turbo-prefetch')).toBe('false');
+ });
+
+ it('renders data-turbo-preload on the inner anchor', async () => {
+ const { root } = await newSpecPage({
+ components: [PdsLink],
+ html: `Page`,
+ });
+
+ const anchor = root?.shadowRoot?.querySelector('a');
+ expect(anchor?.getAttribute('data-turbo-preload')).toBe('true');
+ });
+
+ it('omits turbo data attributes when props are not set', async () => {
+ const { root } = await newSpecPage({
+ components: [PdsLink],
+ html: `Page`,
+ });
+
+ const anchor = root?.shadowRoot?.querySelector('a');
+ expect(anchor?.hasAttribute('data-turbo')).toBe(false);
+ expect(anchor?.hasAttribute('data-turbo-frame')).toBe(false);
+ expect(anchor?.hasAttribute('data-turbo-action')).toBe(false);
+ expect(anchor?.hasAttribute('data-turbo-method')).toBe(false);
+ expect(anchor?.hasAttribute('data-turbo-confirm')).toBe(false);
+ expect(anchor?.hasAttribute('data-turbo-stream')).toBe(false);
+ expect(anchor?.hasAttribute('data-turbo-prefetch')).toBe(false);
+ expect(anchor?.hasAttribute('data-turbo-preload')).toBe(false);
+ });
+
+ it('renders multiple turbo attributes together', async () => {
+ const { root } = await newSpecPage({
+ components: [PdsLink],
+ html: `Page`,
+ });
+
+ const anchor = root?.shadowRoot?.querySelector('a');
+ expect(anchor?.getAttribute('data-turbo')).toBe('true');
+ expect(anchor?.getAttribute('data-turbo-frame')).toBe('content');
+ expect(anchor?.getAttribute('data-turbo-action')).toBe('advance');
+ });
+ });
});