diff --git a/core/src/css/link.ionic.scss b/core/src/css/link.ionic.scss new file mode 100644 index 0000000000..9fc1f2828a --- /dev/null +++ b/core/src/css/link.ionic.scss @@ -0,0 +1,120 @@ +@use "../foundations/ionic.vars" as tokens; + +// Link: Shared Styles (Standalone & Underline) +// ------------------------------------------------------------------------------- +@mixin link-shared { + display: inline-flex; + + align-items: center; + + gap: 4px; + + transition: color 0.2s ease-in-out; + + font-weight: 400; + + text-decoration-color: inherit; + + text-underline-offset: 2px; + + cursor: pointer; + + // Link: Visited + // ------------------------------------------------------------------------------- + + &:visited { + color: tokens.$ionic-color-info-500; + } +} + +// Link: Standalone +// ------------------------------------------------------------------------------- + +@mixin ionic-link { + @include link-shared; + + // Link: Standalone - Hover + // ------------------------------------------------------------------------------- + + @media (any-hover: hover) { + &:hover { + text-decoration: underline; + } + } + + color: tokens.$ionic-color-info-400; + + text-decoration: none; + + // Link: Standalone - Focus + // ------------------------------------------------------------------------------- + + &:focus, + &.ion-focused { + outline: 2px solid tokens.$ionic-color-primary-100; + outline-offset: 2px; + + text-decoration: underline; + } + + // Link: Standalone - Active + // ------------------------------------------------------------------------------- + + &:active, + &.ion-activated { + color: tokens.$ionic-color-info-500; + + text-decoration: underline; + } +} + +a.ionic-link, +:not(a).ionic-link a { + @include ionic-link; +} + +// Link: Underline +// ------------------------------------------------------------------------------- + +@mixin ionic-link-underline { + @include link-shared; + + // Link: Underline - Hover + // ------------------------------------------------------------------------------- + + @media (any-hover: hover) { + &:hover { + color: tokens.$ionic-color-info-400; + } + } + + color: currentColor; + + text-decoration: underline; + + // Link: Underline - Focus + // ------------------------------------------------------------------------------- + + &:focus, + &.ion-focused { + outline: 2px solid tokens.$ionic-color-primary-100; + outline-offset: 2px; + + color: currentColor; + + text-decoration: none; + } + + // Link: Underline - Active + // ------------------------------------------------------------------------------- + + &:active, + &.ion-activated { + color: tokens.$ionic-color-info-500; + } +} + +a.ionic-link-underline, +:not(a).ionic-link-underline a { + @include ionic-link-underline; +} diff --git a/core/src/css/test/link/basic/index.html b/core/src/css/test/link/basic/index.html new file mode 100644 index 0000000000..2b921855bd --- /dev/null +++ b/core/src/css/test/link/basic/index.html @@ -0,0 +1,77 @@ + + + + + Link - Basic + + + + + + + + + + + + + + + Link - Basic + + + + +

Standalone (.ionic-link)

+ + +

Underline (.ionic-link-underline)

+ + +

Links in Content

+ + +

Parent Element

+ +
+
+ + diff --git a/core/src/css/test/link/basic/link.e2e.ts b/core/src/css/test/link/basic/link.e2e.ts new file mode 100644 index 0000000000..8ce38c17fd --- /dev/null +++ b/core/src/css/test/link/basic/link.e2e.ts @@ -0,0 +1,41 @@ +import { expect } from '@playwright/test'; +import { configs, test } from '@utils/test/playwright'; + +/** + * Link global classes are only available in the Ionic theme. + */ +configs({ modes: ['ionic-md'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => { + test.describe(title('link global classes'), () => { + test.beforeEach(async ({ page }) => { + await page.goto('/src/css/test/link/basic/index.html', config); + }); + + test.describe('.ion-link class', () => { + test('should apply to anchor elements', async ({ page }) => { + const standalone = page.locator('#standalone'); + + await expect(standalone).toHaveScreenshot(screenshot('link-standalone')); + }); + + test('should apply to child anchor elements', async ({ page }) => { + const standalone = page.locator('#standalone-nested'); + + await expect(standalone).toHaveScreenshot(screenshot('link-standalone-nested')); + }); + }); + + test.describe('.ion-link-underline class', () => { + test('should apply to anchor elements', async ({ page }) => { + const standalone = page.locator('#underline'); + + await expect(standalone).toHaveScreenshot(screenshot('link-underline')); + }); + + test('should apply to child anchor elements', async ({ page }) => { + const standalone = page.locator('#underline-nested'); + + await expect(standalone).toHaveScreenshot(screenshot('link-underline-nested')); + }); + }); + }); +}); diff --git a/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-ionic-md-ltr-light-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..3172b764c9 Binary files /dev/null and b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-ionic-md-ltr-light-Mobile-Chrome-linux.png differ diff --git a/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-ionic-md-ltr-light-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..c61fbc8373 Binary files /dev/null and b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-ionic-md-ltr-light-Mobile-Firefox-linux.png differ diff --git a/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-ionic-md-ltr-light-Mobile-Safari-linux.png new file mode 100644 index 0000000000..6f2ca049f8 Binary files /dev/null and b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-ionic-md-ltr-light-Mobile-Safari-linux.png differ diff --git a/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-nested-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-nested-ionic-md-ltr-light-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..d081eb283e Binary files /dev/null and b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-nested-ionic-md-ltr-light-Mobile-Chrome-linux.png differ diff --git a/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-nested-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-nested-ionic-md-ltr-light-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..29ab1c63f7 Binary files /dev/null and b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-nested-ionic-md-ltr-light-Mobile-Firefox-linux.png differ diff --git a/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-nested-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-nested-ionic-md-ltr-light-Mobile-Safari-linux.png new file mode 100644 index 0000000000..aee0736982 Binary files /dev/null and b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-standalone-nested-ionic-md-ltr-light-Mobile-Safari-linux.png differ diff --git a/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-ionic-md-ltr-light-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..f17d493beb Binary files /dev/null and b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-ionic-md-ltr-light-Mobile-Chrome-linux.png differ diff --git a/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-ionic-md-ltr-light-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..90f6e48f99 Binary files /dev/null and b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-ionic-md-ltr-light-Mobile-Firefox-linux.png differ diff --git a/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-ionic-md-ltr-light-Mobile-Safari-linux.png new file mode 100644 index 0000000000..e850c45ca3 Binary files /dev/null and b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-ionic-md-ltr-light-Mobile-Safari-linux.png differ diff --git a/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-nested-ionic-md-ltr-light-Mobile-Chrome-linux.png b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-nested-ionic-md-ltr-light-Mobile-Chrome-linux.png new file mode 100644 index 0000000000..827e7eaf26 Binary files /dev/null and b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-nested-ionic-md-ltr-light-Mobile-Chrome-linux.png differ diff --git a/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-nested-ionic-md-ltr-light-Mobile-Firefox-linux.png b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-nested-ionic-md-ltr-light-Mobile-Firefox-linux.png new file mode 100644 index 0000000000..59b0fcdc43 Binary files /dev/null and b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-nested-ionic-md-ltr-light-Mobile-Firefox-linux.png differ diff --git a/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-nested-ionic-md-ltr-light-Mobile-Safari-linux.png b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-nested-ionic-md-ltr-light-Mobile-Safari-linux.png new file mode 100644 index 0000000000..356af6906e Binary files /dev/null and b/core/src/css/test/link/basic/link.e2e.ts-snapshots/link-underline-nested-ionic-md-ltr-light-Mobile-Safari-linux.png differ