diff --git a/packages/ui/src/components/va-button/VaButton.stories.ts b/packages/ui/src/components/va-button/VaButton.stories.ts index 2149eea298..b06e0fd273 100644 --- a/packages/ui/src/components/va-button/VaButton.stories.ts +++ b/packages/ui/src/components/va-button/VaButton.stories.ts @@ -1,15 +1,469 @@ -import { defineComponent } from 'vue' -import VaButton from './VaButton.vue' -import VaButtonDemo from './VaButton.demo.vue' +import { VaButton } from './' +import { userEvent } from '../../../.storybook/interaction-utils/userEvent' +import { within } from '@storybook/testing-library' +import { expect } from '@storybook/jest' export default { title: 'VaButton', component: VaButton, + tags: ['autodocs'], } -export const Default = () => defineComponent({ - components: { VaButton: VaButtonDemo }, - template: '', +export const Default = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const Color = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const Gradient = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const BackgroundOpacity = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const TextColor = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const TextOpacity = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const BorderColor = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const Disabled = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const Plain = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const Round = () => ({ + components: { VaButton }, + template: ` + + Button + +   + + `, +}) + +export const Block = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const Icon = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const IconRight = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) +export const IconOnly = () => ({ + components: { VaButton }, + template: ` + + `, +}) + +export const IconColor = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const Loading = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const Size = () => ({ + components: { VaButton }, + template: ` + [small] +
+ + Button +   +   + + Button + +
+ [medium] +
+ + Button +   +   + + Button + +
+ [large] +
+ + Button +   +   + + Button + +
+ `, +}) + +export const MultilineText = () => ({ + components: { VaButton }, + template: ` +

[default]

+ + Default Button with long text + +

[small]

+ + Small Button with long text + +

[medium]

+ + Medium Button with long text + +

[large]

+ + Large Button with long text + + `, +}) + +export const Preset = () => ({ + components: { VaButton }, + template: ` +

[default]

+ + Button + +

[primary]

+ + Button + +

[secondary]

+ + Button + +

[plain]

+ + Button + +

[plainOpacity]

+ + Button + + `, +}) + +export const HoverBehavior = () => ({ + components: { VaButton }, + template: ` +

[mask]

+ + Button + + +

[opacity]

+ + Button + + `, +}) + +export const HoverMaskColor = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const HoverOpacity = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const PressedBehavior = () => ({ + components: { VaButton }, + template: ` +

[mask]

+ + Button + +

[opacity]

+ + Button + + `, +}) + +export const PressedMaskColor = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const PressedOpacity = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const Href = () => ({ + components: { VaButton }, + template: ` + + Button + + `, +}) + +export const SizesConfig = () => ({ + components: { VaButton }, + data: () => ({ + sizesConfig: { defaultSize: 24, sizes: { small: 16, medium: 24, large: 32 } }, + }), + template: ` +

[default: 24px]

+ + Button + +

[small: 16px]

+ + Button + +

[medium: 24px]

+ + Button + +

[large: 32px]

+ + Button + + `, +}) + +export const FontSizesConfig = () => ({ + components: { VaButton }, + data: () => ({ + fontSizeConfig: { defaultSize: 0.75, sizes: { small: 0.5, medium: 0.75, large: 1 } }, + }), + template: ` +

[default: 0.75rem]

+ + Button + +

[small: 0.5rem]

+ + Button + +

[medium: 0.75rem]

+ + Button + +

[large: 1rem]

+ + Button + + `, +}) + +export const ClickEvent = () => ({ + components: { VaButton }, + data: () => ({ clicked: false }), + template: ` + + Button + +

Clicked: {{ clicked }}

+ `, +}) + +ClickEvent.play = async ({ canvasElement, step }) => { + const canvas = within(canvasElement) + const clickState = canvas.getByTestId('clicked') + + await step('True on click', async () => { + const button = document.querySelector('[type="button"]') as HTMLElement + + expect(clickState.innerText).toEqual('false') + await userEvent.click(button) + expect(clickState.innerText).toEqual('true') + }) +} + +export const FocusAndBlurMethods = () => ({ + components: { VaButton }, + template: ` + + Main Button +   + + Focus Button +   + + Blur Button + + `, +}) + +export const AppendSlot = () => ({ + components: { VaButton }, + template: ` + + Button + + + `, +}) + +export const PrependSlot = () => ({ + components: { VaButton }, + template: ` + + + Button + + `, +}) + +export const LoadingSlot = () => ({ + components: { VaButton }, + template: ` + + + button + + `, }) // See: https://github.com/epicmaxco/vuestic-ui/issues/2704 @@ -17,7 +471,7 @@ export const RightShift = () => ({ components: { VaButton }, template: `
- Text + Text  Text2
`, diff --git a/packages/ui/src/components/va-button/VaButton.vue b/packages/ui/src/components/va-button/VaButton.vue index 70f3d97e77..5b25591806 100644 --- a/packages/ui/src/components/va-button/VaButton.vue +++ b/packages/ui/src/components/va-button/VaButton.vue @@ -32,20 +32,23 @@ /> - + @@ -114,7 +117,7 @@ export default defineComponent({ const colorComputed = computed(() => getColor(props.color)) // loader size - const { sizeComputed } = useSize(props) + const { sizeComputed, fontSizeComputed } = useSize(props, 'VaButton') const loaderSizeComputed = computed(() => { const size = /([0-9]*)(px)/.exec(sizeComputed.value) as null | [string, string, string] return size ? `${+size[1] / 2}${size[2]}` : sizeComputed.value @@ -178,6 +181,8 @@ export default defineComponent({ return { button, tagComputed, + fontSizeComputed, + sizeComputed, computedClass, computedStyle, textColorComputed, @@ -214,11 +219,14 @@ export default defineComponent({ box-shadow: var(--va-button-box-shadow); font-family: var(--va-font-family); font-weight: var(--va-button-font-weight); + font-size: v-bind(fontSizeComputed); text-decoration: none; text-transform: initial; transition: var(--va-button-transition); box-sizing: border-box; cursor: var(--va-button-cursor); + min-width: v-bind(sizeComputed); + min-height: v-bind(sizeComputed); z-index: 0; vertical-align: top; @@ -226,8 +234,8 @@ export default defineComponent({ &::before { content: ''; position: absolute; - width: 100%; height: 100%; + width: 100%; border-radius: inherit; left: 0; top: 0; @@ -259,11 +267,8 @@ export default defineComponent({ line-height: var(--va-button-sm-line-height); border-radius: var(--va-button-sm-border-radius); letter-spacing: var(--va-button-sm-letter-spacing); - min-height: var(--va-button-sm-size); - min-width: var(--va-button-sm-size); .va-button__content { - font-size: var(--va-button-sm-font-size); padding: var(--va-button-sm-content-py) var(--va-button-sm-content-px); } @@ -307,13 +312,9 @@ export default defineComponent({ line-height: var(--va-button-line-height); border-radius: var(--va-button-border-radius); letter-spacing: var(--va-button-letter-spacing); - min-height: var(--va-button-size); - min-width: var(--va-button-size); .va-button__content { - font-size: var(--va-button-font-size); padding: var(--va-button-content-py) var(--va-button-content-px); - line-height: var(--va-button-line-height); } // set icons the same size as text @@ -356,11 +357,8 @@ export default defineComponent({ line-height: var(--va-button-lg-line-height); border-radius: var(--va-button-lg-border-radius); letter-spacing: var(--va-button-lg-letter-spacing); - min-height: var(--va-button-lg-size); - min-width: var(--va-button-lg-size); .va-button__content { - font-size: var(--va-button-lg-font-size); padding: var(--va-button-lg-content-py) var(--va-button-lg-content-px); } diff --git a/packages/ui/src/components/va-button/hooks/useButtonTextColor.ts b/packages/ui/src/components/va-button/hooks/useButtonTextColor.ts index d3cd2f2608..5bc1391add 100644 --- a/packages/ui/src/components/va-button/hooks/useButtonTextColor.ts +++ b/packages/ui/src/components/va-button/hooks/useButtonTextColor.ts @@ -96,7 +96,7 @@ export const useButtonTextColor: UseButtonTextColor = ( return computed(() => { const defaultColorStyles = { - color: textColorComputed.value, + color: textColorComputed.value === 'currentColor' ? 'currentColor' : colorToRgba(textColorComputed.value, getOpacity(props.textOpacity)), background: 'transparent', } diff --git a/packages/ui/src/components/va-checkbox/VaCheckbox.stories.ts b/packages/ui/src/components/va-checkbox/VaCheckbox.stories.ts index a4b6860bd8..9675c5914f 100644 --- a/packages/ui/src/components/va-checkbox/VaCheckbox.stories.ts +++ b/packages/ui/src/components/va-checkbox/VaCheckbox.stories.ts @@ -4,7 +4,7 @@ import { VaButton } from '../va-button' export default { title: 'VaCheckbox', component: VaCheckbox, - tags:['autodocs'], + tags: ['autodocs'], } export const Default = () => ({ @@ -202,7 +202,7 @@ export const Success = () => ({ export const ArrayValue = () => ({ components: { VaCheckbox }, - data: () => ({ value: [ 'One', 'Two' ] }), + data: () => ({ value: ['One', 'Two'] }), template: ` ({ export const TrueValue = () => ({ components: { VaCheckbox }, - data: () => ({ value: "One" }), + data: () => ({ value: 'One' }), template: ` ({ export const FalseValue = () => ({ components: { VaCheckbox }, - data: () => ({ value: "One" }), + data: () => ({ value: 'One' }), template: ` ({ export const IndeterminateValue = () => ({ components: { VaCheckbox }, - data: () => ({ value: "One" }), + data: () => ({ value: 'One' }), template: ` ({ /> {{ value }} `, -}) \ No newline at end of file +}) diff --git a/packages/ui/src/composables/useSize.ts b/packages/ui/src/composables/useSize.ts index ac2d9eb8b8..8f5c908a42 100644 --- a/packages/ui/src/composables/useSize.ts +++ b/packages/ui/src/composables/useSize.ts @@ -1,23 +1,43 @@ import { computed, getCurrentInstance, PropType } from 'vue' -import { useGlobalConfig, SizeConfig } from '../services/global-config/global-config' +import { useGlobalConfig, SizeConfig, SizesConfig } from '../services/global-config/global-config' import type { VuesticComponentName } from '../services/vue-plugin/types/components' -export const sizesConfig: SizeConfig = { - defaultSize: 48, - sizes: { - small: 32, - medium: 48, - large: 64, +export const sizesConfig: SizesConfig = { + default: { + defaultSize: 48, + sizes: { + small: 32, + medium: 48, + large: 64, + }, + }, + VaButton: { + defaultSize: 36, + sizes: { + small: 24, + medium: 36, + large: 48, + }, }, } -export const fontSizesConfig: SizeConfig = { - defaultSize: 1, - sizes: { - small: 0.75, - medium: 1, - large: 1.25, +export const fontSizesConfig: SizesConfig = { + default: { + defaultSize: 1, + sizes: { + small: 0.75, + medium: 1, + large: 1.25, + }, + }, + VaButton: { + defaultSize: 1, + sizes: { + small: 0.8125, + medium: 1, + large: 1.05, + }, }, } @@ -44,12 +64,12 @@ export const useSizeProps = { sizesConfig: { type: Object as PropType>, - default: () => sizesConfig, + default: () => sizesConfig[getCurrentInstance()?.type.name!] ?? sizesConfig['default'], }, fontSizesConfig: { type: Object as PropType>, - default: () => fontSizesConfig, + default: () => fontSizesConfig[getCurrentInstance()?.type.name!] ?? fontSizesConfig['default'], }, } diff --git a/packages/ui/src/services/global-config/types.ts b/packages/ui/src/services/global-config/types.ts index ed6e974be8..a11d932b5b 100644 --- a/packages/ui/src/services/global-config/types.ts +++ b/packages/ui/src/services/global-config/types.ts @@ -28,6 +28,8 @@ export type SizeConfig = { sizes?: { [sizeName: string]: number | string }, } +export type SizesConfig = { [key: string]: SizeConfig } + export type GlobalConfigUpdater = (config: T) => T; export type { ColorConfig,