Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,17 @@ The content of the Ionic docs is written as [Markdown](https://commonmark.org/)

You can make copy edits to the site by [editing the Markdown files directly on GitHub](https://help.github.com/articles/editing-files-in-another-user-s-repository/). In your pull request, please explain what was missing from or inaccurate about the content.

### Links and Headings

Use Markdown for links and headings whenever possible. When you need JSX, such as inside a component prop or in `src/`, use the Docusaurus components instead of raw HTML:

- [`<Link>`](https://docusaurus.io/docs/docusaurus-core#link) from `@docusaurus/Link` instead of `<a>`. It handles the base URL and locale, and opens external URLs in a new tab with `rel="noopener noreferrer"`.
- [`<Heading>`](https://docusaurus.io/docs/api/misc/@docusaurus/eslint-plugin/prefer-docusaurus-heading) from `@theme/Heading` instead of `<h2>` to `<h6>`.

The build only checks links and anchors that go through Markdown or these components. A raw `<a href>` to a page that doesn't exist builds without errors, and a raw heading's `id` can't be used as a link target.

Markup inside code samples is exempt, since it's example code rather than part of the page.

### Reference Content

The Markdown in `docs/` does not only contain manually written markdown files:
Expand Down
23 changes: 11 additions & 12 deletions docs/api/item.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Parts from '@ionic-internal/component-api/v9/item/parts.mdx';
import CustomProps from '@ionic-internal/component-api/v9/item/custom-props.mdx';
import Slots from '@ionic-internal/component-api/v9/item/slots.mdx';

import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
import BestPracticeFigure from '@components/global/BestPracticeFigure';
import Tabs from '@theme/Tabs';
Expand Down Expand Up @@ -78,8 +79,8 @@ The text content type includes form control labels or other visible text. This t
text={
<>
If you find that you need a few more sentences to clarify the item's purpose, consider moving the additional
sentences to a <a href={useBaseUrl('api/note')}>Note</a> at the bottom of the list. Adding the item to its own
list makes it clear which item the text is associated with.
sentences to a <Link to="/api/note">Note</Link> at the bottom of the list. Adding the item to its own list makes
it clear which item the text is associated with.
</>
}
doText="Move long text outside of the list"
Expand Down Expand Up @@ -165,15 +166,14 @@ Developers should avoid creating [nested interactives](https://dequeuniversity.c
<BestPracticeFigure
text={
<>
Actions can be added by using the <a href={useBaseUrl('api/item-sliding')}>Item Sliding</a> component. Actions can
also be placed directly inside of the Item without the use of Item Sliding, but this should be limited to no more
than 2 actions.
Actions can be added by using the <Link to="/api/item-sliding">Item Sliding</Link> component. Actions can also be
placed directly inside of the Item without the use of Item Sliding, but this should be limited to no more than 2
actions.
</>
}
doText={
<>
Use an <a href={useBaseUrl('api/item-sliding')}>Item Sliding</a> to reveal multiple actions by swiping on the
Item.
Use an <Link to="/api/item-sliding">Item Sliding</Link> to reveal multiple actions by swiping on the Item.
</>
}
doNotText="Don't put more than 2 actions within an Item."
Expand Down Expand Up @@ -206,8 +206,8 @@ Controls are form components such as checkboxes, inputs, radios, and more. Each
<>
Metadata such as helper text or character counts should not be used on form controls in list views. If such
metadata is needed, the form control should be placed outside of a list.{' '}
<a href={useBaseUrl('api/input#filled-inputs')}>Filled Inputs</a> are a great way of visually defining the input
container outside of a list.
<Link to="/api/input#filled-inputs">Filled Inputs</Link> are a great way of visually defining the input container
outside of a list.
</>
}
doText="Place inputs with metadata outside of the list."
Expand All @@ -229,8 +229,7 @@ Controls are form components such as checkboxes, inputs, radios, and more. Each
<BestPracticeFigure
text={
<>
Alternatively, the metadata can be placed in a <a href={useBaseUrl('api/note')}>Note</a> at the bottom of the
list.
Alternatively, the metadata can be placed in a <Link to="/api/note">Note</Link> at the bottom of the list.
</>
}
doText="Place metadata for inputs at the end of a list."
Expand All @@ -253,7 +252,7 @@ Controls are form components such as checkboxes, inputs, radios, and more. Each
text={
<>
Items should typically have no more than two controls. If you need more controls, consider adding the additional
controls in a <a href={useBaseUrl('api/modal')}>Modal</a> that is accessible from the item.
controls in a <Link to="/api/modal">Modal</Link> that is accessible from the item.
</>
}
doText="Move additional controls to a submenu accessible from the item."
Expand Down
10 changes: 6 additions & 4 deletions docs/intro/vscode-extension.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
title: VS Code Extension
---

import Link from '@docusaurus/Link';

<head>
<title>VS Code Extension</title>
<meta name="description" content="Using the Ionic/Ionic-Framework VS Code Extension" />
Expand All @@ -11,12 +13,12 @@ The [WebNative Visual Studio Code extension](https://marketplace.visualstudio.co

If you have VS Code on this computer click Install below. You can also find the extension by searching for "WebNative".

<a href="vscode:extension/webnative.webnative" target="_self">
<Link to="vscode:extension/webnative.webnative" target="_self">
<button className="install-button">Install</button>
</a>
<a href="https://webnative.dev/introduction/getting-started/" target="_self">
</Link>
<Link to="https://webnative.dev/introduction/getting-started/" target="_self">
<button className="docs-button">Docs</button>
</a>
</Link>

## Additional Documentation {/* #additional-documentation */}

Expand Down
6 changes: 3 additions & 3 deletions docs/troubleshooting/native.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Running an app on an iOS device requires a provisioning profile. If a provisioni

For Cordova, open the `config.xml` file and modify the `id` attribute of the root element, `<widget>`. Refer to [the Cordova documentation](https://cordova.apache.org/docs/en/latest/config_ref/#widget) for more information.

2. **Open the project in **Xcode**.**
2. **Open the project in Xcode.**

For Capacitor, run the following to open the app in Xcode:

Expand All @@ -34,11 +34,11 @@ Running an app on an iOS device requires a provisioning profile. If a provisioni

For Cordova, open Xcode. Use **File** &raquo; **Open** and locate the app. Open the app's `platforms/ios` directory.

3. **In **Project navigator**, select the project root to open the project editor. Under the **Identity** section, verify that the Package ID that was set matches the Bundle Identifier.**
3. **In Project navigator, select the project root to open the project editor. Under the Identity section, verify that the Package ID that was set matches the Bundle Identifier.**

![Xcode showing the Identity section for an iOS app with fields for Display Name, Bundle Identifier, Version, and Build.](/img/running/ios-xcode-identity-setup.png 'Xcode Identity Section')

4. **In the same project editor, under the **Signing** section, ensure **Automatically manage signing** is enabled.** Then, select a Development Team. Given a Development Team, Xcode will attempt to automatically prepare provisioning and signing.
4. **In the same project editor, under the Signing section, ensure Automatically manage signing is enabled.** Then, select a Development Team. Given a Development Team, Xcode will attempt to automatically prepare provisioning and signing.

![Xcode showing the Signing section with 'Automatically manage signing' enabled and a Development Team selected.](/img/running/ios-xcode-signing-setup.png 'Xcode Signing Section')

Expand Down
2 changes: 1 addition & 1 deletion src/components/global/BestPracticeFigure/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import './best-practice-figure.css';

Custom HTML can also be passed to any of the text properties by using curly braces:

text={<>My text with a <a href="#">link</a></>}
text={<>My text with a <Link to="/api/note">link</Link></>}

Markdown such as backticks will not be processed when using curly braces.
The <code> tag can be used instead:
Expand Down
5 changes: 3 additions & 2 deletions src/components/global/DocDemo/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useEffect, useState, useRef, useCallback } from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';

import './demo.css';

Expand Down Expand Up @@ -57,9 +58,9 @@ const DocDemo = (props) => {
);

const sourceLink = (
<a href={props.source} className="docs-demo-source" target="_blank" title="Demo Source">
<Link to={props.source} className="docs-demo-source" title="Demo Source">
View Source
</a>
</Link>
);

const device = (
Expand Down
11 changes: 0 additions & 11 deletions src/components/global/DocsCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ interface Props extends React.HTMLAttributes<HTMLDivElement> {

function DocsCard(props: Props): ReactNode {
const isStatic = typeof props.href === 'undefined';
const isOutbound = typeof props.href !== 'undefined' ? /^http/.test(props.href) : false;
const header = props.header === 'undefined' ? null : <header className="Card-header">{props.header}</header>;
const hoverIcon = props.hoverIcon || props.icon;

Expand Down Expand Up @@ -65,16 +64,6 @@ function DocsCard(props: Props): ReactNode {
);
}

if (isOutbound) {
return (
<docs-card class={className}>
<a className={clsx(styles.card, 'docs-card')} href={props.href} target="_blank">
{content}
</a>
</docs-card>
);
}

return (
<docs-card class={className}>
<Link to={props.href} className={clsx(styles.card, 'docs-card')}>
Expand Down
9 changes: 4 additions & 5 deletions src/components/global/Playground/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import React, {
useState,
} from 'react';

import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
import './playground.css';
import { EditorOptions, openAngularEditor, openHtmlEditor, openReactEditor, openVueEditor } from './stackblitz.utils';
Expand Down Expand Up @@ -871,20 +872,18 @@ export default function Playground({
</button>
</Tooltip>
<Tooltip content="Report an issue">
<a
<Link
className="playground__icon-button"
href="https://github.com/ionic-team/ionic-docs/issues/new/choose"
to="https://github.com/ionic-team/ionic-docs/issues/new/choose"
aria-label="Report an issue"
target="_blank"
rel="noreferrer"
>
<svg aria-hidden="true" width="12" height="12" viewBox="0 0 12 12" fill="none">
<path
d="M6 0C2.68661 0 0 2.75625 0 6.15268C0 8.87143 1.71964 11.175 4.10357 11.9893C4.14107 11.9973 4.17321 12 4.20536 12C4.42768 12 4.51339 11.8366 4.51339 11.6946C4.51339 11.5473 4.50804 11.1616 4.50536 10.6473C4.28036 10.6982 4.07946 10.7196 3.9 10.7196C2.74554 10.7196 2.48304 9.82232 2.48304 9.82232C2.20982 9.1125 1.81607 8.92232 1.81607 8.92232C1.29375 8.55536 1.81339 8.54464 1.85357 8.54464H1.85625C2.45893 8.59821 2.775 9.18214 2.775 9.18214C3.075 9.70714 3.47679 9.85446 3.83571 9.85446C4.11696 9.85446 4.37143 9.76339 4.52143 9.69375C4.575 9.29732 4.73036 9.02679 4.90179 8.87143C3.57054 8.71607 2.16964 8.18839 2.16964 5.83125C2.16964 5.15893 2.40268 4.60982 2.78571 4.18125C2.72411 4.02589 2.51786 3.39911 2.84464 2.55268C2.84464 2.55268 2.8875 2.53929 2.97857 2.53929C3.19554 2.53929 3.68571 2.62232 4.49464 3.18482C4.97411 3.04821 5.48571 2.98125 5.99732 2.97857C6.50625 2.98125 7.02054 3.04821 7.5 3.18482C8.30893 2.62232 8.79911 2.53929 9.01607 2.53929C9.10714 2.53929 9.15 2.55268 9.15 2.55268C9.47679 3.39911 9.27054 4.02589 9.20893 4.18125C9.59196 4.6125 9.825 5.16161 9.825 5.83125C9.825 8.19375 8.42143 8.71339 7.08482 8.86607C7.29911 9.05625 7.49196 9.43125 7.49196 10.0045C7.49196 10.8268 7.48393 11.4911 7.48393 11.692C7.48393 11.8366 7.56696 12 7.78929 12C7.82143 12 7.85893 11.9973 7.89643 11.9893C10.283 11.175 12 8.86875 12 6.15268C12 2.75625 9.31339 0 6 0Z"
fill="#73849A"
/>
</svg>
</a>
</Link>
</Tooltip>
</div>
</div>
Expand Down
6 changes: 4 additions & 2 deletions src/components/page/api/APIList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import React, { type ComponentProps, type ReactNode } from 'react';

import Link from '@docusaurus/Link';
import Heading from '@theme/Heading';
import sidebars from '@site/sidebars';
import clsx from 'clsx';

Expand All @@ -11,14 +13,14 @@ function APIList({ sidebar, ...props }: ComponentProps<'div'> & { sidebar?: unkn

return (
<>
<h4>{section.label}</h4>
<Heading as="h4">{section.label}</Heading>
<ul>
{section.items.map((item) => {
return (
item &&
item.replace && (
<li>
<a href={item}>{item.replace('api/', '')}</a>
<Link to={`/${item}`}>{item.replace('api/', '')}</Link>
</li>
)
);
Expand Down
5 changes: 3 additions & 2 deletions src/components/page/intro/AppWizard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import React, { type ComponentProps } from 'react';

import styles from './index.module.scss';
Expand All @@ -14,9 +15,9 @@ export default function AppWizard(props: ComponentProps<'div'>) {
</p>
</div>
<div>
<a href="https://ionicframework.com/start" className="wizard-button">
<Link to="https://ionicframework.com/start" className="wizard-button">
Open Wizard
</a>
</Link>
</div>
</div>
);
Expand Down
22 changes: 9 additions & 13 deletions src/components/page/intro/next/DeveloperExperts/index.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
import React from 'react';
import Link from '@docusaurus/Link';
import Heading from '@theme/Heading';
import styles from './index.module.scss';

export default function DeveloperExperts() {
return (
<div className={styles.developerExperts}>
<header>
<h3 className={styles.developerExpertsTitle}>Featured Ionic Developer Expert Projects</h3>
<Heading as="h3" className={styles.developerExpertsTitle}>
Featured Ionic Developer Expert Projects
</Heading>
<p className={styles.developerExpertsDescription}>
Extend your knowledge of Ionic from premium educational materials made by community members.
</p>
</header>
<div className={styles.developerExpertsLinks}>
<a href="https://ionicacademy.com" target="_blank" rel="noopener noreferrer">
Ionic Academy →
</a>
<a href="https://ionicstart.com" target="_blank" rel="noopener noreferrer">
Ionic Start →
</a>
<a href="https://ionicthemes.com" target="_blank" rel="noopener noreferrer">
Ionic Themes →
</a>
<a href="https://ionicreacthub.com" target="_blank" rel="noopener noreferrer">
Ionic React Hub →
</a>
<Link to="https://ionicacademy.com">Ionic Academy →</Link>
<Link to="https://ionicstart.com">Ionic Start →</Link>
<Link to="https://ionicthemes.com">Ionic Themes →</Link>
<Link to="https://ionicreacthub.com">Ionic React Hub →</Link>
</div>
</div>
);
Expand Down
9 changes: 3 additions & 6 deletions src/components/page/native/NativeEnterpriseCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
import clsx from 'clsx';
import React, { type ComponentProps } from 'react';
Expand All @@ -6,11 +7,7 @@ import styles from './index.module.scss';

export default function NativeEnterpriseCard(props: ComponentProps<'a'>) {
return (
<a
className={clsx(props.className, styles.nativeEnterprise)}
href="https://ionic.io/enterprise-sdk"
target="_blank"
>
<Link className={clsx(props.className, styles.nativeEnterprise)} to="https://ionic.io/enterprise-sdk">
<div className="image-wrapper">
<img src={useBaseUrl('/img/native/native-enterprise@2x.png')} width="476" height="228" />
</div>
Expand All @@ -22,6 +19,6 @@ export default function NativeEnterpriseCard(props: ComponentProps<'a'>) {
enterprise-grade apps.
</p>
</div>
</a>
</Link>
);
}
7 changes: 4 additions & 3 deletions src/components/page/reference/ReleaseNotes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import Link from '@docusaurus/Link';
import Heading from '@theme/Heading';
import clsx from 'clsx';
import React from 'react';
import releases from './release-notes.json';
Expand Down Expand Up @@ -49,9 +50,9 @@ export default function ReleaseNotes(props: { [key: string]: any }) {
<div className={styles['release-info']}>
<div className={styles['release-header']}>
<Link to={`https://github.com/ionic-team/ionic-framework/releases/v${release.version}`}>
<h2>
<Heading as="h2">
<span className={styles['release-version']}>{release.version}</span>
</h2>
</Heading>
</Link>
<span className={styles['release-badge']}>{release.type}</span>
{index === 0 ? (
Expand All @@ -61,7 +62,7 @@ export default function ReleaseNotes(props: { [key: string]: any }) {
) : null}
</div>
<div className={styles['release-published']}>
<h3>{release.published_at}</h3>
<Heading as="h3">{release.published_at}</Heading>
</div>
<div
dangerouslySetInnerHTML={{
Expand Down
5 changes: 3 additions & 2 deletions src/components/page/theming/SteppedColorGenerator/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Color } from '../_utils/color';

import { generateSteppedColors } from '../_utils/index';
import clsx from 'clsx';
import Heading from '@theme/Heading';
import styles from './index.module.scss';

export default function ColorGenerator(props: ComponentProps<'div'> & { useTextAndBackgroundStepColors?: boolean }) {
Expand All @@ -29,10 +30,10 @@ export default function ColorGenerator(props: ComponentProps<'div'> & { useTextA
<div className={clsx(props.className, 'stepped-color-generator')}>
<div className={clsx(styles.inputRows)}>
<ColorDot color={backgroundColor} />
<h3>Background</h3>
<Heading as="h3">Background</Heading>
<ColorInput color={backgroundColor} setColor={setBackgroundColor} />
<ColorDot color={textColor} />
<h3>Text</h3>
<Heading as="h3">Text</Heading>
<ColorInput color={textColor} setColor={setTextColor} />
</div>
<pre className={clsx(styles.codePre)}>
Expand Down
Loading
Loading