diff --git a/.prettierignore b/.prettierignore index e8425b82..85937cca 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,6 +1,9 @@ # Files *.md +*.mdx # Folders .husky/* .vscode/* + +*.yml diff --git a/.storybook/preview.ts b/.storybook/preview.ts index 6d572576..57d0b68d 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -18,6 +18,7 @@ const preview: Preview = { schema, brand, }, + tags: ['autodocs'], }; export default preview; diff --git a/.vscode/extensions.json b/.vscode/extensions.json index b5d6632f..68cb125f 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,8 +1,9 @@ { "recommendations": [ - "Vue.volar", + "Vue.volar", "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", - "EditorConfig.EditorConfig" - ] + "EditorConfig.EditorConfig", + "Tobermory.es6-string-html" + ] } diff --git a/eslint.config.js b/eslint.config.js index aa3cce8c..87246819 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,9 +1,9 @@ import eslint from '@eslint/js'; -import tseslint from 'typescript-eslint'; import vitest from '@vitest/eslint-plugin'; import prettierSkipFormattingConfig from '@vue/eslint-config-prettier/skip-formatting'; import pluginVue from 'eslint-plugin-vue'; import globals from 'globals'; +import tseslint from 'typescript-eslint'; const globalFiles = ['**/*.{vue,js,mjs,cjs,ts}']; @@ -108,10 +108,11 @@ export default [ memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'], }, ], + '@typescript-eslint/no-empty-object-type': 'off', // Permite interfaces com uso de extends apenas }, }, { - files: ['**/*.spec.ts'], + files: ['**/*.{test,spec}.ts'], plugins: { vitest, }, @@ -123,6 +124,7 @@ export default [ 'vitest/valid-title': 'off', '@typescript-eslint/no-explicit-any': 'off', '@typescript-eslint/naming-convention': 'off', + '@typescript-eslint/no-explicit-any': 'off', }, }, ...pluginVue.configs['flat/recommended'], @@ -160,7 +162,7 @@ export default [ order: ['script', 'template', 'style'], }, ], - 'vue/multi-word-component-names': 'warn', + 'vue/multi-word-component-names': 'off', // Desabilitada devido ao padrão do DS em que os componentes ao serem usados em outros projetos podem conter um nome composto 'vue/block-tag-newline': 'error', 'vue/component-api-style': ['error', ['script-setup']], 'vue/no-setup-props-reactivity-loss': 'error', @@ -170,4 +172,11 @@ export default [ 'vue/padding-line-between-blocks': ['error', 'always'], }, }, + { + files: ['**/*.stories.ts'], + name: 'ds/docs', + rules: { + '@typescript-eslint/no-explicit-any': 'off', + }, + }, ]; diff --git a/package-lock.json b/package-lock.json index a9469978..d9cf57d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -86,7 +86,7 @@ "node": ">=20.10.0" }, "peerDependencies": { - "typescript": ">= 5.5.0", + "typescript": ">= 5.5.0 < 5.7.0", "vue": ">= 3.4.29" } }, diff --git a/package.json b/package.json index 64d63153..8d08af9b 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "postinstall": "npm run build" }, "peerDependencies": { - "typescript": ">= 5.5.0", + "typescript": ">= 5.5.0 < 5.7.0", "vue": ">= 3.4.29" }, "dependencies": { diff --git a/src/App.vue b/src/App.vue index ad82da3f..2e91587d 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,6 +1,5 @@ + diff --git a/src/components/admin/table/TableRow.vue b/src/components/admin/table/TableRow.vue index b7e90970..24583a1b 100644 --- a/src/components/admin/table/TableRow.vue +++ b/src/components/admin/table/TableRow.vue @@ -9,7 +9,7 @@ const getComponent = () => { diff --git a/src/components/ui/feedback-message/FeedbackMessage.mdx b/src/components/ui/feedback-message/FeedbackMessage.mdx new file mode 100644 index 00000000..f5056fe0 --- /dev/null +++ b/src/components/ui/feedback-message/FeedbackMessage.mdx @@ -0,0 +1,15 @@ +import { Controls, Canvas, Meta } from '@storybook/blocks'; + +import * as FeedbackMessageStories from './FeedbackMessage.stories'; + + + +# FeedbackMessage + +O **FeedbackMessage** é um componente utilizado para exibir mensagens de feedback para o usuário. Ele é composto por um ícone, um texto e um botão de ação. É opcional exibir o botão de ação e o ícone. + +A sua finalidade é a de fornecer um bloco visual e textual padronizado, que ajude a guiar o usuário sobre o que está acontecendo (por exemplo, não há dados disponíveis ou ocorreu um problema que precisa ser resolvido) e quais próximos passos podem ser tomados. Assim garantimos que o usuário tenha uma experiência familiar e coerente, independentemente de qual produto ou seção esteja utilizando. + + + + diff --git a/src/components/ui/feedback-message/FeedbackMessage.scss b/src/components/ui/feedback-message/FeedbackMessage.scss new file mode 100644 index 00000000..c6ff7cbe --- /dev/null +++ b/src/components/ui/feedback-message/FeedbackMessage.scss @@ -0,0 +1,36 @@ +.ui-feedback-message { + display: grid; + text-align: center; + justify-content: center; + height: 100%; + gap: var(--s-spacing-small); + transition: all var(--s-motion-ease-linear) var(--s-motion-duration-fast); + + &-content { + display: grid; + gap: var(--s-spacing-quark); + } + + &-icon { + color: var(--s-color-content-default); + } + + &-title { + font: var(--s-typography-heading-medium); + color: var(--s-color-content-default); + font-weight: var(--s-font-weight-semibold); + margin-bottom: 0px; + } + + &-text { + font: var(--s-typography-paragraph-regular); + color: var(--s-color-content-light); + margin-bottom: 0px; + } + + &-action { + width: fit-content; + justify-self: center; + align-self: center; + } +} diff --git a/src/components/ui/feedback-message/FeedbackMessage.stories.ts b/src/components/ui/feedback-message/FeedbackMessage.stories.ts new file mode 100644 index 00000000..bf7f96be --- /dev/null +++ b/src/components/ui/feedback-message/FeedbackMessage.stories.ts @@ -0,0 +1,40 @@ +import type { Meta, StoryObj } from '@storybook/vue3'; +import FeeedbackMessage from './FeedbackMessage.vue'; +import { fn } from '@storybook/test'; + +const meta: Meta = { + title: 'ui/FeeedbackMessage', + component: FeeedbackMessage, + render: (args) => ({ + components: { FeeedbackMessage }, + setup() { + return { args }; + }, + template: '', + }), + argTypes: {}, + parameters: { + controls: { expanded: true }, + docs: { + controls: { exclude: '^on.*' }, + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const minimum: Story = { + args: { + title: 'Nenhum resultado encontrado', + subtitle: + 'Não encontramos nenhum item que corresponda à sua pesquisa.
Verifique o termo digitado ou tente um filtro diferente.', + button: { + label: 'Limpar filtros', + variant: 'primary', + }, + showIcon: true, + showButton: true, + onAction: fn(), + }, +}; diff --git a/src/components/ui/feedback-message/FeedbackMessage.vue b/src/components/ui/feedback-message/FeedbackMessage.vue new file mode 100644 index 00000000..c1464bff --- /dev/null +++ b/src/components/ui/feedback-message/FeedbackMessage.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/src/components/ui/feedback-message/index.ts b/src/components/ui/feedback-message/index.ts new file mode 100644 index 00000000..e9744988 --- /dev/null +++ b/src/components/ui/feedback-message/index.ts @@ -0,0 +1,2 @@ +export { default as FeedbackMessage } from './FeedbackMessage.vue'; +export * from './types'; diff --git a/src/components/ui/feedback-message/types.ts b/src/components/ui/feedback-message/types.ts new file mode 100644 index 00000000..27162215 --- /dev/null +++ b/src/components/ui/feedback-message/types.ts @@ -0,0 +1,21 @@ +import type { ButtonProps } from '../button'; +import type { IconProps } from '../icon'; + +export interface FeedbackMessageEmits { + (event: 'action'): void; +} + +export interface FeedbackMessageProps { + /** Define o texto principal do componente */ + title?: string; + /** Define o texto secundário do componente */ + subtitle?: string; + /** Configura o ícone do topo a ser exibido, disponibilizando todas as props do componetne Icon */ + icon?: IconProps; + /** Configura o botão de ação do componente, disponibilizando todas as props do componente Button */ + button?: ButtonProps; + /** Define se o ícone será exibido */ + showIcon: boolean; + /** Define se o botão de ação será exibido */ + showButton: boolean; +} diff --git a/src/components/ui/form-checkbox/FormCheckbox.scss b/src/components/ui/form-checkbox/FormCheckbox.scss index c258f5fd..a5895429 100644 --- a/src/components/ui/form-checkbox/FormCheckbox.scss +++ b/src/components/ui/form-checkbox/FormCheckbox.scss @@ -21,7 +21,8 @@ margin-top: var(--s-spacing-nano); } - &:hover { + &:hover, + &:focus { .ui-form-checkbox-checkmark { border-color: var(--s-color-border-highlight); } diff --git a/src/components/ui/form-checkbox/FormCheckbox.vue b/src/components/ui/form-checkbox/FormCheckbox.vue index f4557526..0651f48b 100644 --- a/src/components/ui/form-checkbox/FormCheckbox.vue +++ b/src/components/ui/form-checkbox/FormCheckbox.vue @@ -28,7 +28,7 @@ const update = (val: unknown) => {