resources/lib/codex/mixins/link.less
// Link Styles
//
// Per ADR 04, Codex Links are implemented as a re-usable Less mixin rather
// than a Vue.js component. Users who wish to apply the Codex Link styles to
// elements on a page should call the mixin inside of the relevant selector in
// their own stylesheets. Variants (underlined links, red links) can be accessed
// by adding the appropriate modifier class (.is-underlined and .is-red-link,
// respectively).
//
// Code that needs to customize these modifier classes or otherwise customize the
// selectors used for these modifiers can use the following sub-mixins:
// - cdx-mixin-link-base(): base link styles
// - cdx-mixin-link-underlined(): underlined link (-base must also be applied)
// - cdx-mixin-link-red(): red link (-base must also be applied)
//
// Example usage:
//
// .my-link-class {
//     .cdx-mixin-link-base();
//
//     &.custom-underlined-class {
//         .cdx-mixin-link-underlined();
//     }
//
//     &.custom-red-link-class {
//         .cdx-mixin-link-red();
//     }
// }
//
// Link styles can be used inside of other Vue components, or anywhere that Less
// is available; JS is not required.

.cdx-mixin-link-base() {
	color: @color-progressive;
	border-radius: @border-radius-base;
	text-decoration: @text-decoration-none;

	&:visited {
		color: @color-visited;

		&:hover {
			color: @color-visited--hover;
		}

		&:active {
			color: @color-visited--active;
		}
	}

	&:hover {
		color: @color-progressive--hover;
		text-decoration: @text-decoration-underline;
	}

	&:active {
		color: @color-progressive--active;
		text-decoration: @text-decoration-underline;
	}

	/* stylelint-disable-next-line plugin/no-unsupported-browser-features */
	&:focus-visible {
		outline: @border-style-base @border-width-thick @outline-color-progressive--focus;
	}

	@supports not selector( :focus-visible ) {
		&:focus {
			outline: @border-style-base @border-width-thick @outline-color-progressive--focus;
		}
	}

	// Style external link icon.
	// HACK: Make sure this doesn't apply to placeholder icons in TypeaheadSearch (T372420).
	.cdx-icon:not( .cdx-thumbnail__placeholder__icon--vue ):last-child {
		// Note, `@min-size-icon-x-small` & `@size-icon-small` are an approximation in our current
		// 16/14 base font theme environment.
		// We're faking it to make it, `@min-size-icon-x-small` is `12px` in both themes,
		// `@size-icon-small` is `1em`, achieving the desired size.
		min-width: @min-size-icon-x-small;
		min-height: @min-size-icon-x-small;
		width: @size-icon-small;
		height: @size-icon-small;
		padding-left: @spacing-25;
		vertical-align: middle;
	}
}

.cdx-mixin-link-underlined() {
	text-decoration: @text-decoration-underline;
}

.cdx-mixin-link-red() {
	color: @color-link-red;

	&:visited {
		color: @color-link-red--visited;

		&:hover {
			color: @color-link-red--visited--hover;
		}

		&:active {
			color: @color-link-red--visited--active;
		}
	}

	&:hover {
		color: @color-link-red--hover;
		text-decoration: @text-decoration-underline;
	}

	&:active {
		color: @color-link-red--active;
		text-decoration: @text-decoration-underline;
	}

	&:focus {
		outline-color: @outline-color-progressive--focus;
	}
}

.cdx-mixin-link() {
	.cdx-mixin-link-base();

	// stylelint-disable-next-line selector-class-pattern
	&.is-underlined {
		.cdx-mixin-link-underlined();
	}

	// stylelint-disable-next-line selector-class-pattern
	&.is-red-link {
		.cdx-mixin-link-red();
	}
}
