diff --git a/src/components/NcButton/NcButton.vue b/src/components/NcButton/NcButton.vue
index fb59dc5543..2b98b50849 100644
--- a/src/components/NcButton/NcButton.vue
+++ b/src/components/NcButton/NcButton.vue
@@ -37,44 +37,44 @@ It can be used with one or multiple actions.
aria-label="Example text"
:disabled="disabled"
:size="size"
+ :text="text"
type="tertiary-no-background">
- Example text
- Example text
+ :size="size"
+ :text="text">
- Example text
- Example text
@@ -83,13 +83,13 @@ It can be used with one or multiple actions.
- Example text
@@ -102,32 +102,32 @@ It can be used with one or multiple actions.
- Example text
- Example text
- Example text
-
@@ -148,7 +148,14 @@ export default {
size: 'normal',
style: 'icontext',
}
- }
+ },
+ computed: {
+ text() {
+ if (this.style.includes('text')) {
+ return 'Example text'
+ }
+ },
+ },
}
@@ -189,45 +196,39 @@ Sometimes it is required to change the icon alignment on the button, like for sw
```vue
-
+
- center (default)
-
+
- center-reverse
-
+
- start
-
+
- start-reverse
-
+
- end
-
+
- end-reverse
@@ -263,12 +264,11 @@ Do not change `text` or `aria-label` of the pressed/unpressed button. See: https
-
+
- Favorite
@@ -305,6 +305,21 @@ export default {
```
+### Usage example: Custom content
+Sometimes custom content, meaning more than text and icon, is required.
+For this the `default`-slot can be used.
+
+**Important**: Never include interactive elements inside the button,
+this results in invalid HTML and is not accessible!
+
+```vue
+
+
+ Some formatted content
+
+
+```
+
### Usage example: Sorting table columns
The standard way to implement sortable table column headers should be like this:
@@ -415,558 +430,37 @@ td.row-size {
}
```
-
-
-
-
diff --git a/src/components/NcButton/NcButtonImplementation.vue b/src/components/NcButton/NcButtonImplementation.vue
new file mode 100644
index 0000000000..5a96e0335d
--- /dev/null
+++ b/src/components/NcButton/NcButtonImplementation.vue
@@ -0,0 +1,404 @@
+
+
+
+
+
+
+
+
+
+ {{ text }}
+
+
+
+
+
+
+
+
diff --git a/src/components/NcButton/NcButtonWrapper.vue b/src/components/NcButton/NcButtonWrapper.vue
new file mode 100644
index 0000000000..4c1111d7b5
--- /dev/null
+++ b/src/components/NcButton/NcButtonWrapper.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
+
diff --git a/src/components/NcButton/types.ts b/src/components/NcButton/types.ts
index 551a35c221..60ec5f9619 100644
--- a/src/components/NcButton/types.ts
+++ b/src/components/NcButton/types.ts
@@ -3,6 +3,8 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
+import type { PropType } from 'vue'
+
export enum ButtonAlignment {
Start = 'start',
StartReverse = 'start-reverse',
@@ -31,3 +33,165 @@ export enum ButtonType {
Warning = 'warning',
Success = 'success',
}
+
+export interface NcButtonEmits {
+ (e: 'click', event: MouseEvent): void
+ /**
+ * Update the current pressed state of the button (if the `pressed` property was configured)
+ */
+ (e: 'update:pressed', pressed: boolean): void
+}
+
+export const NcButtonProps = {
+ /**
+ * Set the text and icon alignment
+ *
+ * @default 'center'
+ * @type {'start' | 'start-reverse' | 'center' | 'center-reverse' | 'end' | 'end-reverse'}
+ */
+ alignment: {
+ type: String as PropType,
+ default: ButtonAlignment.Center,
+ validator(value: string) {
+ return Object.values(ButtonAlignment).includes(value as ButtonAlignment)
+ },
+ },
+
+ /**
+ * By default the icon is set to `aria-hidden="true"` to hide it from the accessibility tree.
+ * But sometimes this is not desired, e.g. for a loading icon with an accessible name,
+ * setting this prop will make the icon appear in the accessible tree.
+ * @default false
+ * @since 9.0.0
+ */
+ noIconAriaHidden: {
+ type: Boolean,
+ default: false,
+ },
+
+ /**
+ * Toggles the disabled state of the button on and off.
+ */
+ disabled: {
+ type: Boolean,
+ default: false,
+ },
+
+ /**
+ * Specify the button size
+ * Accepted values: `'small'`, `'normal'` (default), `'large'`
+ */
+ size: {
+ type: String,
+ default: 'normal',
+ validator(value: string) {
+ return ['small', 'normal', 'large'].includes(value)
+ },
+ },
+
+ /**
+ * The main button text.
+ * This can be overwritten by using the *default* slot.
+ * @since 9.0.0
+ */
+ text: {
+ type: String,
+ default: '',
+ },
+
+ /**
+ * Specifies the button type
+ * If left empty, the default button style will be applied.
+ *
+ * @default 'secondary'
+ * @type {'primary' | 'secondary' | 'tertiary' | 'tertiary-no-background' | 'tertiary-on-primary' | 'error' | 'warning' | 'success'}
+ */
+ type: {
+ type: String as PropType,
+ default: ButtonType.Secondary,
+ validator(value: string) {
+ return Object.values(ButtonType).includes(value as ButtonType)
+ },
+ },
+
+ /**
+ * Specifies the button native type
+ * If left empty, the default "button" type will be used.
+ *
+ * @default 'button'
+ * @type {'submit' | 'reset' | 'button'}
+ */
+ nativeType: {
+ type: String as PropType,
+ default: ButtonNativeType.Button,
+ validator(value: string) {
+ return Object.values(ButtonNativeType).includes(value as ButtonNativeType)
+ },
+ },
+
+ /**
+ * Specifies whether the button should span all the available width.
+ * By default, buttons span the whole width of the container.
+ */
+ wide: {
+ type: Boolean,
+ default: false,
+ },
+
+ /**
+ * Always try to provide an aria-label to your button. Make it more
+ * specific than the button's name by provide some more context. E.g. if
+ * the name of the button is "send" in the Mail app, the aria label could
+ * be "Send email".
+ */
+ ariaLabel: {
+ type: String,
+ default: null,
+ },
+
+ /**
+ * Providing the href attribute turns the button component into an `a`
+ * element.
+ */
+ href: {
+ type: String,
+ default: null,
+ },
+
+ /**
+ * Target for the `a` element if `href` is set.
+ * @default '_self'
+ */
+ target: {
+ type: String,
+ default: '_self',
+ },
+
+ /**
+ * Providing the download attribute with href downloads file when clicking.
+ */
+ download: {
+ type: String,
+ default: null,
+ },
+
+ /**
+ * The pressed state of the button if it has a checked state
+ * This will add the `aria-pressed` attribute and for the button to have the primary style in checked state.
+ *
+ * Pressed state is not supported for links
+ */
+ pressed: {
+ type: Boolean,
+ default: null,
+ },
+
+ /**
+ * Providing the to attribute turns the button component into a `router-link`
+ * element. Takes precedence over the href attribute.
+ */
+ to: {
+ type: [String, Object],
+ default: null,
+ },
+}
diff --git a/styleguide.config.cjs b/styleguide.config.cjs
index 0ad025ba93..8b19b2fedd 100644
--- a/styleguide.config.cjs
+++ b/styleguide.config.cjs
@@ -160,6 +160,7 @@ module.exports = async () => {
'src/components/NcAppSettings*/*.vue',
'src/components/NcAppSidebar*/*.vue',
'src/components/NcBreadcrumb*/*.vue',
+ 'src/components/NcButton/!(NcButton).vue',
'src/components/NcCheckboxRadioSwitch/NcCheckboxContent.vue',
'src/components/NcCollectionList/!(NcCollectionList).vue',
'src/components/NcContent/*.vue',