import { OntarioButton} from '@ongov/ontario-design-system-component-library-react';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

# ontario-button

Use buttons to help the user carry out an important action such as starting a transaction or agreeing to a purchase.

## Usage guidance

Please refer to the [Ontario Design System](https://designsystem.ontario.ca/components/detail/buttons.html) for current documentation guidance.

### Disabled state

This component intentionally does not provide a `disabled` prop.

Disabling action controls can create accessibility and usability barriers, and often does not explain what the user needs to fix.

Instead:

- keep actions available
- use validation and error messaging to clearly identify missing or invalid input

When used in forms, pair button behavior with component-level error handling guidance in related form fields.

Source: https://designsystem.ontario.ca/components/detail/buttons.html#disabled-buttons

## Configuration

Once the component package has been installed (see Ontario Design System Component Library for installation instructions), the button component can be added directly into the project's code, and can be customized by updating the properties outlined [here](#properties). Please see the [examples](#examples) below for how to configure the component.

## Examples

Example of a bare-bones button component where the `label` for the button is provided. The default button type will be `secondary`, and the native HTML button type will be `button`.

```mdx-code-block
<Tabs
	defaultValue="html"
	values={[
		{label: 'HTML', value: 'html'},
		{label: 'React', value: 'react'},
		{label: 'Angular', value: 'angular'},
	]}
	groupId="framework"
	queryString="framework">
<TabItem value="html">
```

```html
<ontario-button>Element Content</ontario-button>
```

```mdx-code-block
</TabItem>
<TabItem value="react">
```

```tsx
<OntarioButton>Element Content</OntarioButton>
```

```mdx-code-block
</TabItem>
<TabItem value="angular">
```

```html
<ontario-button>Element Content</ontario-button>
```

```mdx-code-block
</TabItem>
</Tabs>
```

<OntarioButton>Element Content</OntarioButton>

Example of a button component, which includes the `label`, `elementId`, `htmlType`, `type` and `ariaLabelText` properties.

```mdx-code-block
<Tabs
	defaultValue="html"
	values={[
		{label: 'HTML', value: 'html'},
		{label: 'React', value: 'react'},
		{label: 'Angular', value: 'angular'},
	]}
	groupId="framework"
	queryString="framework">
<TabItem value="html">
```

```html
<ontario-button aria-label-text="Example aria label text" element-id="button-id" html-type="button" type="tertiary">
	Element Content
</ontario-button>
```

```mdx-code-block
</TabItem>
<TabItem value="react">
```

```tsx
<OntarioButton ariaLabelText="Example aria label text" elementId="button-id" htmlType="button" type="tertiary">
	Element Content
</OntarioButton>
```

```mdx-code-block
</TabItem>
<TabItem value="angular">
```

```html
<ontario-button
	[ariaLabelText]="'Example aria label text'"
	[elementId]="'button-id'"
	[htmlType]="'button'"
	[type]="'tertiary'"
>
	Element Content
</ontario-button>
```

```mdx-code-block
</TabItem>
</Tabs>
```

<OntarioButton aria-label-text="Example aria label text" element-id="button-id" html-type="button" type="tertiary">
	Element Content
</OntarioButton>

Example of a button component rendering as a native link when `href` is provided. Use this pattern for navigation, and keep `htmlType` for action and form-submit use cases.

```mdx-code-block
<Tabs
	defaultValue="html"
	values={[
		{label: 'HTML', value: 'html'},
		{label: 'React', value: 'react'},
		{label: 'Angular', value: 'angular'},
	]}
	groupId="framework"
	queryString="framework">
<TabItem value="html">
```

```html
<ontario-button href="/services" target="_blank" rel="noreferrer" type="primary">Browse services</ontario-button>
```

```mdx-code-block
</TabItem>
<TabItem value="react">
```

```tsx
<OntarioButton href="/services" target="_blank" rel="noreferrer" type="primary">
	Browse services
</OntarioButton>
```

```mdx-code-block
</TabItem>
<TabItem value="angular">
```

```html
<ontario-button [href]="'/services'" [target]="'_blank'" [rel]="'noreferrer'" [type]="'primary'">
	Browse services
</ontario-button>
```

```mdx-code-block
</TabItem>
</Tabs>
```

<OntarioButton href="/services" target="_blank" rel="noreferrer" type="primary">Browse services</OntarioButton>

This is another example of a button component, where the user is passing in the label through the `label` property - overriding the 'Element Content' value. The resulting label text will display as `Example`.

```mdx-code-block
<Tabs
	defaultValue="html"
	values={[
		{label: 'HTML', value: 'html'},
		{label: 'React', value: 'react'},
		{label: 'Angular', value: 'angular'},
	]}
	groupId="framework"
	queryString="framework">
<TabItem value="html">
```

```html
<ontario-button label="Example" html-type="submit" type="primary">Element Content</ontario-button>
```

```mdx-code-block
</TabItem>
<TabItem value="react">
```

```tsx
<OntarioButton label="Example" htmlType="submit" type="primary">
	Element Content
</OntarioButton>
```

```mdx-code-block
</TabItem>
<TabItem value="angular">
```

```html
<ontario-button [label]="'Example'" [htmlType]="'submit'" [type]="'primary'"> Element Content </ontario-button>
```

```mdx-code-block
</TabItem>
</Tabs>
```

<OntarioButton label="Example" html-type="submit" type="primary">Element Content</OntarioButton>

An example of how to pass in an `onclick` function to the button component.

```mdx-code-block
<Tabs
	defaultValue="html"
	values={[
		{label: 'HTML', value: 'html'},
		{label: 'React', value: 'react'},
		{label: 'Angular', value: 'angular'},
	]}
	groupId="framework"
	queryString="framework">
<TabItem value="html">
```

```html
<ontario-button onclick="exampleFunction()">Element Content</ontario-button>
```

```mdx-code-block
</TabItem>
<TabItem value="react">
```

```tsx
<OntarioButton onClick={exampleFunction}>Element Content</OntarioButton>
```

```mdx-code-block
</TabItem>
<TabItem value="angular">
```

```html
<ontario-button (click)="exampleFunction()">Element Content</ontario-button>
```

```mdx-code-block
</TabItem>
</Tabs>
```

### Forms

The `ontario-button` supports integration with native HTML `<form>` elements. This element integrates with the underlying browser form API and should work the same as adding an `<input type="submit">`.

To use the `ontario-button` as a submit button set the `htmlType` to `"submit"`. This will wire the `ontario-button` up to the `<form>` it is in and allow it to perform the submit. Internally, the `ontario-button` will fire a `submit` event on its parent `<form>` and trigger the native behaviour of the browser.

When `href` is provided, the component renders as a native link instead. In that mode, `htmlType` is ignored and should not be used for form submission.

```html
<form>
	<!-- Add other form elements, either native or design system elements -->
	<ontario-input
		id="input-1"
		caption="What is your name?"
		required
		name="input-1"
		hint-text="Enter your full name"
	></ontario-input>

	<!-- Submit the form with a submit button -->
	<ontario-button type="primary" html-type="submit">Submit</ontario-button>
</form>
```

Alternatively, adding a `click` listener with a custom handler will allow for any action to be performed with the `ontario-button`. To trigger the submit the `<form>` element can programmatically have the `submit` event dispatched to it.

```html
<form id="form-1">
	<!-- Add other form elements, either native or design system elements -->
	<ontario-input
		id="input-1"
		caption="What is your name?"
		required
		name="input-1"
		hint-text="Enter your full name"
	></ontario-input>

	<!-- Submit the form with a submit button -->
	<ontario-button type="primary">Submit</ontario-button>
</form>

<script>
	window.addEventListener('load', () => {
		// Look up the elements within the document
		const form = document.getElementById('form-1');
		const button = document.getElementById('input-1');

		// Submit the form with an event, if `submit()` is used it can't be
		// prevented using `preventDefault()`
		button.addEventListener('click', () => {
			form?.dispatchEvent(new Event('submit', { cancelable: true }));
		});

		// Perform what ever actions are needed when submitting the form,
		// for example, validation
		form.addEventListener('submit', (event) => {
			// Perform necessary logic, eg. validation

			// Sample: emit form data to the console
			const formData = new FormData(event.target);
			console.log('Form data:', formData);

			// Avoid an actual submission if submission isn't desired (optional)
			event.preventDefault();
		});
	});
</script>
```

## Accessibility

It is important to know when the proper use-case is for a button. Often, the roles of links and buttons can get confused with one another.

- Links will redirect you to a new page or another section/component on a page.
- Buttons will trigger an action, such as opening or closing a modal, or submitting a form.

It can be confusing and frustrating for users to expect a button to trigger an action, and then they are redirected to a new page.

## Technical Note: SSR (Server-Side Rendering) Considerations

The Ontario Button component supports server-side rendering, with a few considerations:

- **Preferred content source:** Pass button text through the `label` prop.
- **Slotted content caveat:** Slotted children rely on fallback `host.textContent`, which is not reliably available during SSR.
- **Framework guidance:** For deterministic SSR output, prefer `label` over slotted children.

### SSR-safe example:

```html
<ontario-button label="Click me"></ontario-button>
```

<!-- Auto Generated Below -->

## Overview

Ontario Button triggers actions and supports button or link behavior.

This component intentionally does not expose a `disabled` prop.

To support accessible and understandable form completion:

- keep actions available
- use validation and error messaging to guide corrections instead of disabling

For component guidance, see:

- https://designsystem.ontario.ca/components/detail/buttons.html
- https://designsystem.ontario.ca/developer-docs/components/ontario-button/

Disabled/read-only policy source:

- https://designsystem.ontario.ca/components/detail/buttons.html#disabled-buttons

## Properties

| Property        | Attribute         | Description                                                                                                                                                                                                                                                                          | Type                                                            | Default       |
| --------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- | ------------- |
| `ariaLabelText` | `aria-label-text` | Provides more context as to what the button interaction is doing. This should only be used for accessibility purposes, if the button interaction requires more description than what the text provides. This is optional.                                                            | `string \| undefined`                                           | `undefined`   |
| `elementId`     | `element-id`      | The unique identifier of the button. This is optional - if no ID is passed, one will be generated.                                                                                                                                                                                   | `string \| undefined`                                           | `undefined`   |
| `href`          | `href`            | When provided, the component renders as a native anchor for navigation use cases. This takes precedence over `htmlType`, so form-submission behaviour is disabled in link mode.                                                                                                      | `string \| undefined`                                           | `undefined`   |
| `htmlType`      | `html-type`       | The native HTML button type the button should use. If no `htmlType` is passed, it will default to `'button'`. This prop only affects the component when it renders as a native `<button>`. If `href` is provided, the component renders as a native `<a>` and `htmlType` is ignored. | `"button" \| "reset" \| "submit"`                               | `'button'`    |
| `label`         | `label`           | Text to be displayed within the button. This will override the text provided through the host element textContent.                                                                                                                                                                   | `string \| undefined`                                           | `undefined`   |
| `rel`           | `rel`             | Specifies the relationship of the linked document to the current document when `href` is provided. This prop has no effect unless the component is in link mode.                                                                                                                     | `string \| undefined`                                           | `undefined`   |
| `target`        | `target`          | Specifies where to open the linked document when `href` is provided. This prop has no effect unless the component is in link mode.                                                                                                                                                   | `string \| undefined`                                           | `undefined`   |
| `type`          | `type`            | The type of button to render. If no type is passed, it will default to 'secondary'.                                                                                                                                                                                                  | `"internalThemeDark" \| "primary" \| "secondary" \| "tertiary"` | `'secondary'` |

---

_Built with [StencilJS](https://stenciljs.com/)_
