├── .npmrc
├── .docker
├── .dockerignore
├── bin
│ └── entrypoint.sh
└── Dockerfile
├── on-server.sh
├── src
├── assets
│ └── sass
│ │ ├── tokens.scss
│ │ ├── legacy-tokens
│ │ ├── utils.scss
│ │ ├── transitions.scss
│ │ ├── fontWeight.scss
│ │ ├── reset.scss
│ │ ├── shadows.scss
│ │ ├── borders.scss
│ │ ├── elevation.scss
│ │ └── typography.scss
│ │ ├── tokens
│ │ ├── index.scss
│ │ ├── _utils.scss
│ │ ├── _transitions.scss
│ │ ├── _fontWeight.scss
│ │ ├── _reset.scss
│ │ ├── _shadows.scss
│ │ ├── _borders.scss
│ │ ├── _elevation.scss
│ │ └── _typography.scss
│ │ └── legacy-tokens.scss
├── utils
│ ├── constants
│ │ ├── sizes.js
│ │ ├── keycodes.js
│ │ ├── widths.js
│ │ ├── validationStates.js
│ │ ├── inputTypes.js
│ │ └── generateKey.js
│ ├── methods
│ │ ├── hasSlot.js
│ │ ├── variantClassResolver.js
│ │ ├── hexToRgb.js
│ │ ├── rounder.js
│ │ ├── uuidv4.js
│ │ ├── hasSameItems.ts
│ │ ├── removeAccents.js
│ │ └── contrastChecker.js
│ ├── validators
│ │ ├── input.js
│ │ ├── variant.js
│ │ ├── state.js
│ │ └── time.js
│ ├── composables
│ │ ├── useHasSlots.js
│ │ ├── useHasSlot.js
│ │ ├── useIsMobile.js
│ │ ├── useDropdownPosition.js
│ │ ├── useComponentEmits.js
│ │ ├── useClickOutside.js
│ │ ├── useInputStatusClasses.js
│ │ └── useToast.js
│ ├── index.js
│ └── directives
│ │ └── cdsFloatify.js
├── tests
│ ├── __snapshots__
│ │ ├── DialogModal.spec.ts.snap
│ │ ├── WebcamModal.spec.ts.snap
│ │ ├── ActionBar.spec.ts.snap
│ │ ├── SideSheet.spec.ts.snap
│ │ ├── LoadingIndicator.spec.ts.snap
│ │ ├── Text.spec.js.snap
│ │ ├── Skeleton.spec.ts.snap
│ │ ├── SkeletonText.spec.ts.snap
│ │ ├── LoadingBar.spec.ts.snap
│ │ ├── PieChart.spec.ts.snap
│ │ ├── LineChart.spec.ts.snap
│ │ ├── Spacer.spec.ts.snap
│ │ ├── BarChart.spec.ts.snap
│ │ ├── DonutChart.spec.ts.snap
│ │ ├── Highlight.spec.ts.snap
│ │ ├── PolarAreaChart.spec.ts.snap
│ │ ├── Timeline.spec.ts.snap
│ │ ├── Button.spec.ts.snap
│ │ ├── StackedBarChart.spec.ts.snap
│ │ ├── Spinner.spec.ts.snap
│ │ ├── Scrollable.spec.ts.snap
│ │ ├── Badge.spec.ts.snap
│ │ ├── ProgressBar.spec.ts.snap
│ │ ├── CarouselController.spec.ts.snap
│ │ ├── TruncateContainer.spec.js.snap
│ │ ├── IconButton.spec.ts.snap
│ │ ├── Radio.spec.ts.snap
│ │ ├── RadialBarChart.spec.ts.snap
│ │ ├── Checkbox.spec.ts.snap
│ │ ├── Alert.spec.ts.snap
│ │ ├── CollapsibleContainer.spec.ts.snap
│ │ ├── AlertCard.spec.ts.snap
│ │ ├── Chip.spec.js.snap
│ │ ├── ProgressCircular.spec.ts.snap
│ │ ├── TopAppBar.spec.ts.snap
│ │ ├── ToastContainer.spec.js.snap
│ │ ├── Box.spec.ts.snap
│ │ ├── MobileStepperInput.spec.js.snap
│ │ ├── PasswordInput.spec.ts.snap
│ │ ├── FileViewer.spec.ts.snap
│ │ ├── FloatingActionButton.spec.ts.snap
│ │ ├── TimeInput.spec.ts.snap
│ │ ├── MobileNavbar.spec.ts.snap
│ │ ├── Textarea.spec.js.snap
│ │ ├── BaseMobileInput.spec.js.snap
│ │ ├── Breadcrumb.spec.ts.snap
│ │ ├── EmptyState.spec.ts.snap
│ │ ├── CalloutCard.spec.ts.snap
│ │ ├── BaseInput.spec.js.snap
│ │ ├── BottomSheet.spec.ts.snap
│ │ ├── TextInput.spec.js.snap
│ │ ├── NumberInput.spec.js.snap
│ │ ├── CheckboxGroup.spec.ts.snap
│ │ ├── Toast.spec.js.snap
│ │ ├── Tile.spec.ts.snap
│ │ ├── List.spec.ts.snap
│ │ ├── Card.spec.ts.snap
│ │ └── PanelCard.spec.ts.snap
│ ├── LoadingBar.spec.ts
│ ├── Scrollable.spec.ts
│ ├── TimeInput.spec.ts
│ ├── Skeleton.spec.ts
│ ├── Checkbox.spec.ts
│ ├── ProgressCircular.spec.ts
│ ├── PasswordInput.spec.ts
│ ├── SkeletonText.spec.ts
│ ├── TopAppBar.spec.ts
│ ├── WebcamModal.spec.ts
│ ├── CarouselController.spec.ts
│ ├── EmptyState.spec.ts
│ ├── BottomSheet.spec.ts
│ ├── PanelCard.spec.ts
│ ├── Alert.spec.ts
│ ├── Highlight.spec.ts
│ ├── LoadingIndicator.spec.ts
│ ├── Badge.spec.ts
│ ├── Button.spec.ts
│ ├── Radio.spec.ts
│ ├── AlertCard.spec.ts
│ ├── ColorPicker.spec.ts
│ ├── ActionBar.spec.ts
│ ├── DialogModal.spec.ts
│ ├── Card.spec.ts
│ ├── FileViewer.spec.ts
│ ├── IconButton.spec.ts
│ ├── SideSheet.spec.ts
│ ├── CalloutCard.spec.ts
│ ├── Box.spec.ts
│ ├── MobileStepperInput.spec.js
│ ├── ActionsList.spec.ts
│ ├── InnerTabs.spec.ts
│ ├── Spacer.spec.ts
│ ├── Table.spec.ts
│ ├── RadioButtonGroup.spec.ts
│ ├── FloatingActionButton.spec.ts
│ ├── List.spec.ts
│ ├── Spinner.spec.ts
│ ├── Toast.spec.js
│ ├── MultiFileInput.spec.ts
│ ├── Carousel.spec.ts
│ ├── Stepper.spec.ts
│ ├── Breadcrumb.spec.ts
│ ├── MobileNavbar.spec.ts
│ ├── CollapsibleContainer.spec.ts
│ ├── Timeline.spec.ts
│ ├── Chip.spec.js
│ ├── MobileNavigation.spec.ts
│ ├── SideBar.spec.ts
│ ├── HasSameItems.spec.ts
│ ├── Wizard.spec.ts
│ ├── CheckboxGroup.spec.ts
│ └── Tile.spec.ts
├── vite-env.d.ts
├── entities
│ └── PaginationItem.js
├── components
│ ├── RequiredIndicator.vue
│ ├── PageContainer.vue
│ ├── Truncate.vue
│ ├── Clickable.vue
│ ├── SkeletonText.vue
│ ├── ToastContainer.vue
│ └── Timeline.vue
├── docs-components
│ └── CopyToken.vue
└── style.css
├── .vscode
└── extensions.json
├── docs
├── .vitepress
│ ├── env.d.ts
│ └── theme
│ │ ├── layout.vue
│ │ └── Layout.vue
├── tsconfig.json
├── docgen
│ ├── FigmaFrame.vue
│ └── PreviewContainer.vue
├── utils
│ ├── remove-accents.md
│ ├── cds-tip.md
│ ├── rounder.md
│ ├── has-slot.md
│ ├── contrast-checker.md
│ ├── cds-floatify.md
│ └── palete-resolver.md
├── foundation
│ ├── shadow.md
│ ├── transições.md
│ ├── peso-fonte.md
│ ├── elevation.md
│ ├── bordas.md
│ ├── cores.md
│ ├── tipografia.md
│ └── iconografia.md
├── components
│ ├── containers
│ │ ├── divider.md
│ │ └── box.md
│ ├── forms
│ │ ├── pin-input.md
│ │ ├── search-input.md
│ │ ├── chevron.md
│ │ ├── file-input.md
│ │ ├── label.md
│ │ ├── time-input.md
│ │ ├── password-input.md
│ │ ├── radio.md
│ │ ├── text-area.md
│ │ ├── flat-button.md
│ │ ├── icon-button.md
│ │ └── switch.md
│ ├── utils
│ │ ├── truncate.md
│ │ └── clickable.md
│ ├── loaders
│ │ ├── loading-bar.md
│ │ ├── spinner.md
│ │ ├── skeleton-text.md
│ │ └── overlay-loader.md
│ ├── estrutural
│ │ └── page-container.md
│ ├── navegação
│ │ ├── link.md
│ │ ├── segmented-control.md
│ │ └── pagination.md
│ ├── notificação
│ │ ├── alert-card.md
│ │ └── alert.md
│ ├── display
│ │ ├── tooltip.md
│ │ ├── progress-circular.md
│ │ ├── dropdown.md
│ │ ├── progress-bar.md
│ │ ├── badge.md
│ │ ├── avatar.md
│ │ ├── timeline-item.md
│ │ └── chip.md
│ ├── tipografia
│ │ └── text.md
│ └── charts
│ │ └── polar-area-chart.md
└── pull_request_template.md
├── docker-compose.yml
├── tsconfig.node.json
├── .github
├── workflows
│ ├── label.yml
│ ├── prettier.yml
│ ├── publish.yml
│ ├── deployV2.yml
│ ├── publish-next.yml
│ ├── test.yml
│ ├── build-docs.yml
│ └── deploy.yml
├── ISSUE_TEMPLATE
│ ├── Bug.md
│ └── FEATURE_REQUEST.md
└── labeler.yml
├── vitest.config.ts
├── .gitignore
├── types
└── vitepress-env.d.ts
├── tsconfig.json
├── public
├── vite.svg
└── img
│ └── smartphone-rotation.svg
├── eslint.config.js
└── vite.config.ts
/.npmrc:
--------------------------------------------------------------------------------
1 | legacy-peer-deps=true
2 |
--------------------------------------------------------------------------------
/.docker/.dockerignore:
--------------------------------------------------------------------------------
1 | *
2 | !bin/
3 | !Dockerfile
--------------------------------------------------------------------------------
/on-server.sh:
--------------------------------------------------------------------------------
1 | docker-compose exec cuida $*
2 |
--------------------------------------------------------------------------------
/src/assets/sass/tokens.scss:
--------------------------------------------------------------------------------
1 | @use './tokens/index' as *;
2 |
--------------------------------------------------------------------------------
/src/utils/constants/sizes.js:
--------------------------------------------------------------------------------
1 | export default ["sm", "md", "lg"];
2 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["Vue.volar"]
3 | }
4 |
--------------------------------------------------------------------------------
/src/utils/constants/keycodes.js:
--------------------------------------------------------------------------------
1 | export default {
2 | ESC: 27,
3 | };
4 |
--------------------------------------------------------------------------------
/src/utils/constants/widths.js:
--------------------------------------------------------------------------------
1 | export default ["thin", "default", "wide"];
2 |
--------------------------------------------------------------------------------
/.docker/bin/entrypoint.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 | npm install
5 | npm run build
6 | npm run docs:dev
7 |
--------------------------------------------------------------------------------
/src/utils/constants/validationStates.js:
--------------------------------------------------------------------------------
1 | export default [
2 | 'valid',
3 | 'invalid',
4 | 'default',
5 | ];
6 |
--------------------------------------------------------------------------------
/docs/.vitepress/env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 | ///
3 |
--------------------------------------------------------------------------------
/src/utils/constants/inputTypes.js:
--------------------------------------------------------------------------------
1 | export default ['text', 'textarea', 'email', 'password', 'tel', 'number', 'search', 'url'];
2 |
--------------------------------------------------------------------------------
/src/utils/methods/hasSlot.js:
--------------------------------------------------------------------------------
1 | export default (slots, slotName) => {
2 | return Object.keys(slots).some((slot) => slot === slotName);
3 | };
4 |
--------------------------------------------------------------------------------
/src/utils/validators/input.js:
--------------------------------------------------------------------------------
1 | import inputTypes from '../constants/inputTypes';
2 |
3 | export default (value) => inputTypes.includes(value);
4 |
--------------------------------------------------------------------------------
/src/utils/validators/variant.js:
--------------------------------------------------------------------------------
1 | import { colorOptions } from '../constants/colors';
2 |
3 | export default (value) => colorOptions.includes(value);
4 |
--------------------------------------------------------------------------------
/src/utils/methods/variantClassResolver.js:
--------------------------------------------------------------------------------
1 | export default function variantClassResolver(baseClass, variant) {
2 | return `${baseClass}--${variant}`;
3 | }
4 |
--------------------------------------------------------------------------------
/src/utils/validators/state.js:
--------------------------------------------------------------------------------
1 | import validationStates from '../constants/validationStates';
2 |
3 | export default (value) => validationStates.includes(value);
4 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/DialogModal.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`DialogModal > renders correctly 1`] = `""`;
4 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/WebcamModal.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`WebcamModal > renders correctly 1`] = `""`;
4 |
--------------------------------------------------------------------------------
/src/assets/sass/legacy-tokens/utils.scss:
--------------------------------------------------------------------------------
1 | @mixin label {
2 | font-size: 14px;
3 | font-weight: $font-weight-semibold;
4 | color: $n-700;
5 | display: block;
6 | margin: mb(1);
7 | }
8 |
--------------------------------------------------------------------------------
/src/utils/composables/useHasSlots.js:
--------------------------------------------------------------------------------
1 | import { useSlots } from 'vue';
2 |
3 | export function useHasSlots() {
4 | const slots = useSlots();
5 | return !!Object.keys(slots).length;
6 | };
7 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/ActionBar.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`ActionBar snapshot test > renders correctly 1`] = `""`;
4 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/SideSheet.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Spacer snapshot test > renders correctly 1`] = `""`;
4 |
--------------------------------------------------------------------------------
/src/utils/composables/useHasSlot.js:
--------------------------------------------------------------------------------
1 | import { useSlots } from 'vue';
2 |
3 | export function useHasSlot (slotName) {
4 | const slots = useSlots();
5 | return Object.keys(slots).some((slot) => slot === slotName);
6 | }
7 |
--------------------------------------------------------------------------------
/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | declare module '*.vue' {
4 | import type { DefineComponent } from 'vue'
5 | const component: DefineComponent<{}, {}, any>
6 | export default component
7 | }
8 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.7'
2 |
3 | services:
4 | cuida:
5 | container_name: main
6 | image: sysvaleops/cuida:dev-1.0
7 | volumes:
8 | - .:/usr/src/app
9 | ports:
10 | - 6006:6006
11 |
--------------------------------------------------------------------------------
/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "allowSyntheticDefaultImports": true
7 | },
8 | "include": ["vite.config.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/LoadingIndicator.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`LoadingIndicator > renders correctly 1`] = `"
"`;
4 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Text.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Text Component > renders correctly 1`] = `"Texto de exemplo "`;
4 |
--------------------------------------------------------------------------------
/src/entities/PaginationItem.js:
--------------------------------------------------------------------------------
1 | export default class PaginationItem {
2 | constructor(index, value, selected, text = null) {
3 | this.index = index;
4 | this.value = value;
5 | this.selected = selected;
6 | this.text = text || value;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/src/utils/methods/hexToRgb.js:
--------------------------------------------------------------------------------
1 | export default (hex) => {
2 | var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
3 | return result ? [
4 | parseInt(result[1], 16),
5 | parseInt(result[2], 16),
6 | parseInt(result[3], 16)
7 | ] : null;
8 | }
9 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Skeleton.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Skeleton > renders correctly 1`] = `"
"`;
4 |
--------------------------------------------------------------------------------
/src/utils/index.js:
--------------------------------------------------------------------------------
1 | export { default as KeyCodes } from "./constants/keycodes";
2 | export { default as generateKey } from "./constants/generateKey";
3 | export { default as sizes } from "./constants/sizes";
4 | export { default as widths } from "./constants/widths";
5 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/SkeletonText.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`SkeletonText > renders correctly 1`] = `"
"`;
4 |
--------------------------------------------------------------------------------
/src/utils/methods/rounder.js:
--------------------------------------------------------------------------------
1 | export default function rounder(elementWidth, limiter = 24) {
2 | let rawRadii = elementWidth / 8;
3 | let radiiMod4 = rawRadii % 4;
4 | let borderRadius = rawRadii > limiter ? limiter : rawRadii - radiiMod4 + 4;
5 |
6 | return `${borderRadius}px`;
7 | }
8 |
--------------------------------------------------------------------------------
/.github/workflows/label.yml:
--------------------------------------------------------------------------------
1 | name: "Labeler 🏷️"
2 | on:
3 | - pull_request_target
4 |
5 | jobs:
6 | triage:
7 | name: Assign tag
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/labeler@main
11 | with:
12 | repo-token: "${{ secrets.GITHUB_TOKEN }}"
13 |
--------------------------------------------------------------------------------
/src/assets/sass/tokens/index.scss:
--------------------------------------------------------------------------------
1 | @forward './borders';
2 | @forward './colors.module';
3 | @forward './elevation';
4 | @forward './fontWeight';
5 | @forward './reset';
6 | @forward './shadows';
7 | @forward './spacing';
8 | @forward './transitions';
9 | @forward './typography';
10 | @forward './utils';
11 |
--------------------------------------------------------------------------------
/src/utils/composables/useIsMobile.js:
--------------------------------------------------------------------------------
1 | import { computed } from 'vue';
2 | import isDeviceType from '../methods/isDeviceType';
3 |
4 | export default function() {
5 | const isMobile = computed(() => {
6 | return isDeviceType('smartphone') || isDeviceType('tablet');
7 | });
8 |
9 | return { isMobile };
10 | }
11 |
--------------------------------------------------------------------------------
/src/utils/methods/uuidv4.js:
--------------------------------------------------------------------------------
1 | export default function generateKey() { //cria UUIDv4
2 | return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (char) {
3 | const random = Math.random() * 16 | 0;
4 | const value = char === 'x' ? random : (random & 0x3 | 0x8);
5 | return value.toString(16);
6 | });
7 | }
8 |
--------------------------------------------------------------------------------
/src/assets/sass/tokens/_utils.scss:
--------------------------------------------------------------------------------
1 | @use './fontWeight' as fontWeight;
2 | @use './colors.module.scss' as colors;
3 | @use './spacing.scss' as spacing;
4 |
5 | @mixin label {
6 | font-size: 14px;
7 | font-weight: fontWeight.$font-weight-semibold;
8 | color: colors.$n-700;
9 | display: block;
10 | margin: spacing.mb(1);
11 | }
12 |
--------------------------------------------------------------------------------
/src/assets/sass/legacy-tokens/transitions.scss:
--------------------------------------------------------------------------------
1 | $interaction: all .2s ease-in-out;
2 | $hover: all .3s ease-in-out;
3 | $opening: all .4s ease-in-out;
4 |
5 | $transition: ();
6 |
7 | $transition: map-merge(
8 | (
9 | 'interaction': $interaction,
10 | 'hover': $hover,
11 | 'opening': $opening,
12 | ),
13 | $transition
14 | );
15 |
--------------------------------------------------------------------------------
/src/assets/sass/legacy-tokens/fontWeight.scss:
--------------------------------------------------------------------------------
1 | $font-weight-regular: 430;
2 | $font-weight-semibold: 600;
3 | $font-weight-bold: 800;
4 |
5 | $fontWeight: ();
6 |
7 | $fontWeight: map-merge(
8 | (
9 | 'regular': $font-weight-regular,
10 | 'semibold': $font-weight-semibold,
11 | 'bold': $font-weight-bold,
12 | ),
13 | $fontWeight
14 | );
15 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/LoadingBar.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`LoadingBar > renders correctly 1`] = `
4 | ""
9 | `;
10 |
--------------------------------------------------------------------------------
/docs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "include": [
4 | "../types/**/*.d.ts",
5 | ".vitepress/**/*",
6 | "**/*.md",
7 | "**/*.vue"
8 | ],
9 | "exclude": [
10 | "../node_modules",
11 | ".vitepress/cache"
12 | ],
13 | "vueCompilerOptions": {
14 | "vitePressExtensions": [".md"]
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/assets/sass/tokens/_transitions.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:map';
2 |
3 | $interaction: all .2s ease-in-out;
4 | $hover: all .3s ease-in-out;
5 | $opening: all .4s ease-in-out;
6 |
7 | $transition: ();
8 |
9 | $transition: map.merge(
10 | (
11 | 'interaction': $interaction,
12 | 'hover': $hover,
13 | 'opening': $opening,
14 | ),
15 | $transition
16 | );
17 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/PieChart.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`PieChart > renders correctly 1`] = `" "`;
4 |
--------------------------------------------------------------------------------
/src/assets/sass/tokens/_fontWeight.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:map';
2 |
3 | $font-weight-regular: 430;
4 | $font-weight-semibold: 600;
5 | $font-weight-bold: 800;
6 |
7 | $fontWeight: ();
8 |
9 | $fontWeight: map.merge(
10 | (
11 | 'regular': $font-weight-regular,
12 | 'semibold': $font-weight-semibold,
13 | 'bold': $font-weight-bold,
14 | ),
15 | $fontWeight
16 | );
17 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/LineChart.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`LineChart > renders correctly 1`] = `"
"`;
4 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Spacer.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Spacer snapshot test > renders correctly 1`] = `
4 | ""
8 | `;
9 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/BarChart.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`BarChart > renders correctly 1`] = `"
"`;
4 |
--------------------------------------------------------------------------------
/src/utils/methods/hasSameItems.ts:
--------------------------------------------------------------------------------
1 | export default function hasSameItems(arr1: string[], arr2: string[]): boolean {
2 | if (arr1.length !== arr2.length) return false;
3 | if (arr1.length === 0 && arr2.length === 0) return true;
4 |
5 | const sorted1 = [...arr1].sort();
6 | const sorted2 = [...arr2].sort();
7 |
8 | return sorted1.every((item, index) => item === sorted2[index]);
9 | }
--------------------------------------------------------------------------------
/src/tests/__snapshots__/DonutChart.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`DonutChart > renders correctly 1`] = `"
"`;
4 |
--------------------------------------------------------------------------------
/.docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:16.18.1-alpine3.16
2 |
3 | COPY bin/entrypoint.sh /usr/local/bin/entrypoint.sh
4 |
5 | RUN mkdir -p /usr/src/app \
6 | && apk update \
7 | && apk add --no-cache bash==5.1.16-r2 \
8 | && rm -rf /var/cache/apk/* \
9 | && rm -rf /tmp/*
10 |
11 | WORKDIR /usr/src/app
12 |
13 | EXPOSE 6006
14 | ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
15 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Highlight.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Highlight > renders correctly 1`] = `
4 | "
5 | Texto
6 | "
7 | `;
8 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/PolarAreaChart.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`PolarAreaChart > renders correctly 1`] = `" "`;
4 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Timeline.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Timeline > renders correctly 1`] = `
4 | "
5 |
6 |
"
7 | `;
8 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Button.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Button > renders correctly 1`] = `
4 | "
5 |
6 |
7 | Botão
8 |
9 | "
10 | `;
11 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/StackedBarChart.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`StackedBarChart > renders correctly 1`] = `"
"`;
4 |
--------------------------------------------------------------------------------
/src/utils/constants/generateKey.js:
--------------------------------------------------------------------------------
1 | export default function generateKey(length = 8) {
2 | let result = '';
3 | const characters =
4 | 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
5 | const charactersLength = characters.length;
6 | for (let i = 0; i < length; i += 1) {
7 | result += characters.charAt(Math.floor(Math.random() * charactersLength));
8 | }
9 | return result;
10 | }
11 |
--------------------------------------------------------------------------------
/src/assets/sass/tokens/_reset.scss:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | *:before,
6 | *:after {
7 | box-sizing: border-box;
8 | }
9 |
10 | svg {
11 | box-sizing: content-box;
12 | }
13 |
14 | body {
15 | line-height: 1.25;
16 | }
17 |
18 | ol, ul {
19 | list-style: none;
20 | }
21 |
22 | a {
23 | text-decoration: none;
24 | color: inherit;
25 | }
26 |
27 | svg:focus {
28 | outline: none;
29 | }
--------------------------------------------------------------------------------
/src/components/RequiredIndicator.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 | *
6 |
7 |
8 |
9 |
13 |
14 |
21 |
--------------------------------------------------------------------------------
/src/tests/LoadingBar.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import LoadingBar from '../components/LoadingBar.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('LoadingBar', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(LoadingBar, {
8 | props: {},
9 | });
10 |
11 | expect(wrapper.html()).toMatchSnapshot();
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Spinner.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Spinner > renders correctly 1`] = `"
"`;
4 |
5 | exports[`Spinner > renders correctly with delay 1`] = `""`;
6 |
7 | exports[`Spinner > renders correctly with delay 2`] = `"
"`;
8 |
--------------------------------------------------------------------------------
/src/assets/sass/legacy-tokens/reset.scss:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | *:before,
6 | *:after {
7 | box-sizing: border-box;
8 | }
9 |
10 | svg {
11 | box-sizing: content-box;
12 | }
13 |
14 | body {
15 | line-height: 1.25;
16 | }
17 |
18 | ol, ul {
19 | list-style: none;
20 | }
21 |
22 | a {
23 | text-decoration: none;
24 | color: inherit;
25 | }
26 |
27 | svg:focus {
28 | outline: none;
29 | }
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Scrollable.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Scrollable > renders correctly 1`] = `
4 | ""
9 | `;
10 |
--------------------------------------------------------------------------------
/docs/docgen/FigmaFrame.vue:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
15 |
16 |
--------------------------------------------------------------------------------
/src/tests/Scrollable.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import Scrollable from '../components/Scrollable.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('Scrollable', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(Scrollable, {
8 | props: {
9 | maxHeight: '200px',
10 | },
11 | });
12 |
13 | expect(wrapper.html()).toMatchSnapshot();
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Badge.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Badge > renders correctly 1`] = `
4 | ""
13 | `;
14 |
--------------------------------------------------------------------------------
/src/tests/TimeInput.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import TimeInput from '../components/TimeInput.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('TimeInput', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(TimeInput, {
8 | props: {
9 | label: 'Test label',
10 | },
11 | });
12 |
13 | expect(wrapper.html()).toMatchSnapshot();
14 | });
15 | });
16 |
17 |
--------------------------------------------------------------------------------
/src/tests/Skeleton.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import Skeleton from '../components/Skeleton.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('Skeleton', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(Skeleton, {
8 | props: {
9 | width: '300',
10 | shape: 'circle'
11 | },
12 | });
13 |
14 | expect(wrapper.html()).toMatchSnapshot();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/ProgressBar.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`ProgressBar > renders correctly 1`] = `
4 | ""
10 | `;
11 |
--------------------------------------------------------------------------------
/src/tests/Checkbox.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import Checkbox from '../components/Checkbox.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('Checkbox', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(Checkbox, {
8 | props: {
9 | modelValue: false,
10 | label: 'checkbox test'
11 | },
12 | });
13 |
14 | expect(wrapper.html()).toMatchSnapshot();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/src/tests/ProgressCircular.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import ProgressCircular from '../components/ProgressCircular.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('ProgressCircular', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(ProgressCircular, {
8 | props: {
9 | value: 0.67,
10 | },
11 | });
12 |
13 | expect(wrapper.html()).toMatchSnapshot();
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/CarouselController.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Button > renders correctly 1`] = `
4 | "
5 |
6 |
7 | Click here
8 |
9 | "
10 | `;
11 |
--------------------------------------------------------------------------------
/src/utils/validators/time.js:
--------------------------------------------------------------------------------
1 | import { DateTime } from 'luxon';
2 |
3 | export const hourFormat = (time) => {
4 | return /[0-2][0-9]:[0-5][0-9]/.test(time);
5 | };
6 |
7 | export const isAfter = (finalTime, initialTime) => {
8 | if (!(hourFormat(finalTime) && hourFormat(initialTime))) {
9 | return false;
10 | }
11 |
12 | return (
13 | DateTime.fromFormat(finalTime, 'HH:mm').diff(
14 | DateTime.fromFormat(initialTime, 'HH:mm')
15 | ) > 0
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/src/tests/PasswordInput.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import PasswordInput from '../components/PasswordInput.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('PasswordInput', () => {
6 | test('If component renders correctly', () => {
7 | const wrapper = mount(PasswordInput, {
8 | props: {
9 | id: 'password-input',
10 | },
11 | });
12 |
13 | expect(wrapper.html()).toMatchSnapshot();
14 | });
15 | });
16 |
17 |
--------------------------------------------------------------------------------
/src/tests/SkeletonText.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import SkeletonText from '../components/SkeletonText.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('SkeletonText', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(SkeletonText, {
8 | props: {
9 | width: '300',
10 | height: '20',
11 | },
12 | });
13 |
14 | expect(wrapper.html()).toMatchSnapshot();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/src/tests/TopAppBar.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import TopAppBar from '../components/TopAppBar.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('TopAppBar', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(TopAppBar, {
8 | props: {
9 | title: 'Título massa',
10 | showMenuIcon: true,
11 | },
12 | });
13 |
14 | expect(wrapper.html()).toMatchSnapshot();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/src/tests/WebcamModal.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import WebcamModal from '../components/WebcamModal.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('WebcamModal', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(WebcamModal, {
8 | props: {
9 | modelValue: true,
10 | title: 'Olá, camera!',
11 | },
12 | });
13 |
14 | expect(wrapper.html()).toMatchSnapshot();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/src/tests/CarouselController.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import Button from '../components/Button.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('Button', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(Button, {
8 | props: {
9 | total: 12,
10 | perPage: 4,
11 | propertyName: 'Métricas',
12 | },
13 | });
14 |
15 | expect(wrapper.html()).toMatchSnapshot();
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/src/tests/EmptyState.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import EmptyState from '../components/EmptyState.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('EmptyState', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(EmptyState, {
8 | props: {
9 | title: 'EmptyState title',
10 | text: 'EmptyState text',
11 | },
12 | });
13 |
14 | expect(wrapper.html()).toMatchSnapshot();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/src/tests/BottomSheet.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import BottomSheet from '../components/BottomSheet.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('BottomSheet', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(BottomSheet, {
8 | props: {
9 | modelValue: true,
10 | title: 'Qual o segredo da vida?',
11 | },
12 | });
13 |
14 | expect(wrapper.html()).toMatchSnapshot();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/src/tests/PanelCard.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import PanelCard from '../components/PanelCard.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('PanelCard', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(PanelCard, {
8 | props: {
9 | title: 'Redes',
10 | subtitle: 'Habilite as redes da regulação',
11 | },
12 | });
13 |
14 | expect(wrapper.html()).toMatchSnapshot();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/src/assets/sass/legacy-tokens/shadows.scss:
--------------------------------------------------------------------------------
1 | $shadow-sm: 0px 4px 8px rgba(16, 24, 64, 0.04);
2 | $shadow-md: 0px 10px 15px -3px rgba(0, 0, 0, 0.1), 0px 4px 6px -2px rgba(0, 0, 0, 0.05);
3 | $shadow-lg: 0px 5.06px 4.85px rgba(10, 35, 66, 0.07), 0px 12.56px 11.65px rgba(10, 35, 66, 0.0503), 0px 22.42px 21.94px rgba(10, 35, 66, 0.0418);
4 |
5 | $shadows: ();
6 |
7 | $shadows: map-merge(
8 | (
9 | 'sm': $shadow-sm,
10 | 'md': $shadow-md,
11 | 'lg': $shadow-lg,
12 | ),
13 | $shadows
14 | );
15 |
--------------------------------------------------------------------------------
/src/tests/Alert.spec.ts:
--------------------------------------------------------------------------------
1 | // @vitest-environment jsdom
2 | import { describe, test, expect } from 'vitest';
3 | import Alert from '../components/Alert.vue';
4 | import { mount } from '@vue/test-utils';
5 |
6 | describe('Alert snapshot test', () => {
7 | test('renders correctly', () => {
8 | const wrapper = mount(Alert, {
9 | props: {
10 | variant: 'info',
11 | text: 'Texto do alerta',
12 | }
13 | });
14 |
15 | expect(wrapper.html()).toMatchSnapshot();
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/src/tests/Highlight.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import Highlight from '../components/Highlight.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('Highlight', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(Highlight, {
8 | props: {
9 | variant: 'success',
10 | },
11 | slots: {
12 | default: 'Texto',
13 | }
14 | });
15 |
16 | expect(wrapper.html()).toMatchSnapshot();
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/src/tests/LoadingIndicator.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import LoadingIndicator from '../components/LoadingIndicator.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('LoadingIndicator', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(LoadingIndicator, {
8 | props: {
9 | modelValue: true,
10 | variant: 'green',
11 | },
12 | });
13 |
14 | expect(wrapper.html()).toMatchSnapshot();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/src/tests/Badge.spec.ts:
--------------------------------------------------------------------------------
1 | // @vitest-environment jsdom
2 | import { describe, test, expect } from 'vitest';
3 | import Badge from '../components/Badge.vue';
4 | import { mount } from '@vue/test-utils';
5 |
6 | describe('Badge', () => {
7 | test('renders correctly', async () => {
8 | const wrapper = mount(Badge, {
9 | props: {
10 | variant: 'gray',
11 | },
12 | slots: {
13 | default: 'Badge'
14 | }
15 | });
16 |
17 | expect(wrapper.html()).toMatchSnapshot();
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/.github/workflows/prettier.yml:
--------------------------------------------------------------------------------
1 | name: "Prettier 🪄"
2 |
3 | on: [push]
4 |
5 | jobs:
6 | prettier:
7 | runs-on: ubuntu-latest
8 |
9 | steps:
10 | - name: Checkout
11 | uses: actions/checkout@v2
12 | with:
13 | ref: ${{ github.head_ref }}
14 |
15 | - name: Prettify code
16 | uses: creyD/prettier_action@v4.2
17 | with:
18 | commit_message: 'style: correções de estilo de código (Prettier)'
19 | prettier_options: --write **/*.{js,md}
--------------------------------------------------------------------------------
/src/assets/sass/tokens/_shadows.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:map';
2 |
3 | $shadow-sm: 0px 4px 8px rgba(16, 24, 64, 0.04);
4 | $shadow-md: 0px 10px 15px -3px rgba(0, 0, 0, 0.1), 0px 4px 6px -2px rgba(0, 0, 0, 0.05);
5 | $shadow-lg: 0px 5.06px 4.85px rgba(10, 35, 66, 0.07), 0px 12.56px 11.65px rgba(10, 35, 66, 0.0503), 0px 22.42px 21.94px rgba(10, 35, 66, 0.0418);
6 |
7 | $shadows: ();
8 |
9 | $shadows: map.merge(
10 | (
11 | 'sm': $shadow-sm,
12 | 'md': $shadow-md,
13 | 'lg': $shadow-lg,
14 | ),
15 | $shadows
16 | );
17 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/TruncateContainer.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`TruncateContainer.vue > renders correctly 1`] = `
4 | "
5 |
6 |
7 |
Some content inside the container
8 |
9 |
10 |
11 |
"
12 | `;
13 |
--------------------------------------------------------------------------------
/src/components/PageContainer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
13 |
14 |
24 |
--------------------------------------------------------------------------------
/src/tests/Button.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import Button from '../components/Button.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('Button', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(Button, {
8 | props: {
9 | variant: 'green',
10 | size: 'md',
11 | text: 'Button',
12 | },
13 | slots: {
14 | default: 'Botão'
15 | }
16 | });
17 |
18 | expect(wrapper.html()).toMatchSnapshot();
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/src/tests/Radio.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect, vi } from 'vitest';
2 | import Radio from '../components/Radio.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('Radio', () => {
6 | test('renders correctly', async () => {
7 | Math.random = vi.fn(() => 0.1);
8 |
9 | const wrapper = mount(Radio, {
10 | props: {
11 | modelValue: null,
12 | value: 'option-1',
13 | label: 'Opção 1',
14 | },
15 | });
16 |
17 | expect(wrapper.html()).toMatchSnapshot();
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/src/assets/sass/legacy-tokens.scss:
--------------------------------------------------------------------------------
1 | @use './legacy-tokens/tokens/index' as *;
2 | @import "./legacy-tokens/borders.scss";
3 | @import "./legacy-tokens/colors.module.scss";
4 | @import "./legacy-tokens/elevation.scss";
5 | @import "./legacy-tokens/fontWeight.scss";
6 | @import "./legacy-tokens/reset.scss";
7 | @import "./legacy-tokens/shadows.scss";
8 | @import "./legacy-tokens/spacing.scss";
9 | @import "./legacy-tokens/transitions.scss";
10 | @import "./legacy-tokens/typography.scss";
11 | @import "./legacy-tokens/utils.scss";
12 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/IconButton.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`IconButton > renders correctly 1`] = `" "`;
4 |
--------------------------------------------------------------------------------
/vitest.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vitest/config';
2 | import Vue from '@vitejs/plugin-vue';
3 |
4 | export default defineConfig({
5 | plugins: [Vue()],
6 | test: {
7 | globals: true,
8 | environment: 'jsdom',
9 | snapshotFormat: {
10 | maxDepth: 2
11 | },
12 | coverage: {
13 | enabled: true,
14 | provider: 'v8',
15 | reportsDirectory: './coverage',
16 | reporter: ['text', 'lcov', 'json', 'html'],
17 | exclude: ['**/tests/**', '**/__tests__/**'],
18 | }
19 | },
20 | root: '.', //Define the root
21 | });
--------------------------------------------------------------------------------
/src/tests/AlertCard.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import AlertCard from '../components/AlertCard.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('AlertCard snapshot test', () => {
6 | test('renders correctly', () => {
7 | const wrapper = mount(AlertCard, {
8 | props: {
9 | title: 'Título do AlertCard',
10 | subTitle: 'Subtítulo do AlertCard',
11 | variant: 'info',
12 | value: false,
13 | }
14 | });
15 |
16 | expect(wrapper.html()).toMatchSnapshot();
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/src/tests/ColorPicker.spec.ts:
--------------------------------------------------------------------------------
1 | // @vitest-environment jsdom
2 | import { describe, test, expect } from 'vitest';
3 | import ColorPicker from '../components/ColorPicker.vue';
4 | import { mount } from '@vue/test-utils';
5 |
6 | describe('ColorPicker', () => {
7 | test('renders correctly', async () => {
8 | const wrapper = mount(ColorPicker, {
9 | props: {
10 | modelValue: '#000000',
11 | inline: true,
12 | swatch: ['#000000', '#000000'],
13 | },
14 | });
15 |
16 | expect(wrapper.html()).toMatchSnapshot();
17 | });
18 | });
19 |
--------------------------------------------------------------------------------
/src/tests/ActionBar.spec.ts:
--------------------------------------------------------------------------------
1 | // @vitest-environment jsdom
2 | import { describe, test, expect } from 'vitest';
3 | import ActionBar from '../components/ActionBar.vue';
4 | import { mount } from '@vue/test-utils';
5 |
6 | const actions = ['Button1', 'Button2', 'Button3'];
7 |
8 | describe('ActionBar snapshot test', () => {
9 | test('renders correctly', async () => {
10 | const wrapper = mount(ActionBar, {
11 | props: {
12 | show: true,
13 | actions,
14 | }
15 | });
16 |
17 | expect(wrapper.html()).toMatchSnapshot();
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/src/tests/DialogModal.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import DialogModal from '../components/DialogModal.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('DialogModal', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(DialogModal, {
8 | props: {
9 | modelValue: true,
10 | title: 'Olá, mundo!',
11 | description: 'Esta ação afetará o sistema e os arquivos associados.',
12 | },
13 | });
14 |
15 | expect(wrapper.html()).toMatchSnapshot();
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/docs/utils/remove-accents.md:
--------------------------------------------------------------------------------
1 | # RemoveAccents()
2 |
3 | Sanitiza strings removendo acentos.
4 |
5 |
6 |
7 |
8 | ⚠️ *Método disponível apenas para desenvolvimento interno no Cuida*
9 |
10 |
11 |
12 | #### Argumentos
13 |
14 | **(String):**
15 | - String cujo valor se deseja sanitizar
16 | - Obrigatória: *Sim*
17 | - Valores válidos: qualquer string;
18 |
19 |
20 |
21 | #### Retorno
22 |
23 | **(Strgin):** String sem acentos.
24 |
25 |
26 |
27 | #### Exemplo
28 |
29 | ```js
30 | removeAccents(this.label);
31 | ```
32 |
--------------------------------------------------------------------------------
/docs/foundation/shadow.md:
--------------------------------------------------------------------------------
1 | # Sombras
2 | Os tokens de sombra são utilizados para criar hierarquia visual e impressão de profundidade.
3 |
4 |
5 |
6 |
7 | ## Recomendações
8 |
9 | - Não recomendamos a utilização de sombras em logos e em imagens.
10 |
11 | - Evite utilizar sombras como único recurso para indicar interação.
12 |
13 |
14 |
15 |
16 | ## Tokens
17 | Os tokens de sombra são variáveis scss e estão descritos abaixo.
18 |
19 |
20 |
21 |
22 |
25 |
--------------------------------------------------------------------------------
/src/tests/Card.spec.ts:
--------------------------------------------------------------------------------
1 | // @vitest-environment jsdom
2 | import { describe, test, expect } from 'vitest';
3 | import Card from '../components/Card.vue';
4 | import { mount } from '@vue/test-utils';
5 |
6 | describe('Card snapshot test', () => {
7 | test('renders correctly', () => {
8 | const wrapper = mount(Card, {
9 | props: {
10 | title: 'Card Title',
11 | content: "Some quick example text to build on the card title and make up the bulk of the card's content.",
12 | }
13 | });
14 |
15 | expect(wrapper.html()).toMatchSnapshot();
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/src/tests/FileViewer.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import FileViewer from '../components/FileViewer.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('FileViewer', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(FileViewer, {
8 | props: {
9 | label: 'Comprovante de residência',
10 | fileUrl: 'https://images.pexels.com/photos/1254140/pexels-photo-1254140.jpeg',
11 | variant: 'green',
12 | },
13 | });
14 |
15 | expect(wrapper.html()).toMatchSnapshot();
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/src/tests/IconButton.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import IconButton from '../components/IconButton.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('IconButton', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(IconButton, {
8 | global: {
9 | stubs: {
10 | 'cds-icon': true,
11 | 'cds-tooltip': true,
12 | },
13 | },
14 | props: {
15 | size: 'lg',
16 | icon: 'trash-outline'
17 | },
18 | });
19 |
20 | expect(wrapper.html()).toMatchSnapshot();
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/src/tests/SideSheet.spec.ts:
--------------------------------------------------------------------------------
1 | // @vitest-environment jsdom
2 | import { describe, test, expect } from 'vitest';
3 | import SideSheet from '../components/SideSheet.vue';
4 | import { mount } from '@vue/test-utils';
5 |
6 | describe('Spacer snapshot test', () => {
7 | test('renders correctly', () => {
8 | const wrapper = mount(SideSheet, {
9 | props: {
10 | title: 'Title',
11 | modelValue: false,
12 | },
13 | slots: {
14 | default:
15 | 'Conteúdo do SideSheet',
16 | },
17 | });
18 |
19 | expect(wrapper.html()).toMatchSnapshot();
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/src/tests/CalloutCard.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import CalloutCard from '../components/CalloutCard.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('CalloutCard', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(CalloutCard, {
8 | props: {
9 | image: 'https://cdn-icons-png.flaticon.com/512/7486/7486747.png',
10 | title: 'Título do CalloutCard',
11 | },
12 | slots: {
13 | text: 'Texto do CalloutCar',
14 | }
15 | });
16 |
17 | expect(wrapper.html()).toMatchSnapshot();
18 | });
19 | });
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
26 | .vitest
27 | .cache
28 | coverage
29 |
30 | # VitePress
31 | docs/.vitepress/cache/
32 | docs/.vitepress/dist/
33 | docs/.vitepress/*.timestamp-*.mjs
34 |
35 | # Vite/VitePress temporary timestamp files
36 | *.timestamp-*.mjs
37 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Radio.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Radio > renders correctly 1`] = `
4 | "Opção 1 "
9 | `;
10 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/RadialBarChart.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`RadialBarChart > renders correctly 1`] = `
4 | " "
8 | `;
9 |
--------------------------------------------------------------------------------
/docs/.vitepress/theme/layout.vue:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 | Cuida design system
12 |
13 |
14 | O Cuida é o design system open source da Sysvale, pensado para ajudar
15 | times de produto a trabalhar de modo consistente e performático na
16 | construção de aplicações do Cidade Saudável.
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/tests/Box.spec.ts:
--------------------------------------------------------------------------------
1 | // @vitest-environment jsdom
2 | import { describe, test, expect } from 'vitest';
3 | import Box from '../components/Box.vue';
4 | import { mount } from '@vue/test-utils';
5 |
6 | describe('Spacer snapshot test', () => {
7 | test('renders correctly', () => {
8 | const wrapper = mount(Box, {
9 | props: {
10 | elevated: false,
11 | fluid: false,
12 | padding: 4,
13 | },
14 | slots: {
15 | default:
16 | '
',
17 | },
18 | });
19 |
20 | expect(wrapper.html()).toMatchSnapshot();
21 | });
22 | });
23 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Checkbox.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Checkbox > renders correctly 1`] = `
4 | ""
7 | `;
8 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Alert.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Alert snapshot test > renders correctly 1`] = `
4 | " "
7 | `;
8 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: "Publisher 📦"
2 | on:
3 | push:
4 | branches:
5 | - main
6 | jobs:
7 | build:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - name: Checkout
11 | uses: actions/checkout@v2
12 | - name: Setup Node
13 | uses: actions/setup-node@v2
14 | with:
15 | node-version: '20.x'
16 | registry-url: 'https://registry.npmjs.org'
17 | - name: Install dependencies and build 🔧
18 | run: npm ci && npm run build
19 | - name: Publish package on NPM 📦
20 | run: npm publish
21 | env:
22 | NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
23 |
--------------------------------------------------------------------------------
/src/utils/directives/cdsFloatify.js:
--------------------------------------------------------------------------------
1 | import { createPopper } from '@popperjs/core';
2 |
3 | export default (el, biding) => {
4 | let target = '';
5 | let popoverElement = '';
6 | let modifiers = biding.modifiers;
7 | let position = biding.arg;
8 |
9 | target = document.querySelector(`[id='${biding.value}']`);
10 | popoverElement = document.querySelector(`[id='${el.id}']`);
11 |
12 | createPopper(target, popoverElement, {
13 | placement: position,
14 | modifiers: [
15 | {
16 | name: 'offset',
17 | options: {
18 | offset: [0, -4],
19 | },
20 | },
21 | {
22 | name: 'flip',
23 | enabled: !!modifiers.flip,
24 | },
25 | ],
26 | });
27 | };
28 |
--------------------------------------------------------------------------------
/src/tests/MobileStepperInput.spec.js:
--------------------------------------------------------------------------------
1 | import { describe, test, expect, vi } from 'vitest';
2 | import MobileStepperInput from '../components/MobileStepperInput.vue';
3 | import { shallowMount } from '@vue/test-utils';
4 |
5 | describe('MobileStepperInput', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = shallowMount(MobileStepperInput);
8 |
9 | expect(wrapper.html()).toMatchSnapshot();
10 | });
11 |
12 | test('state classes are applyied correctly', async () => {
13 | expect.assertions(1);
14 |
15 | const wrapper = shallowMount(MobileStepperInput);
16 |
17 | expect(wrapper.vm.stepperInputStatusClasses).toBe('mobile-stepper-input');
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/src/utils/methods/removeAccents.js:
--------------------------------------------------------------------------------
1 | export default function removeAccents(str = '') {
2 | const accents =
3 | 'ÀÁÂÃÄÅàáâãäåÒÓÔÕÕÖØòóôõöøÈÉÊËèéêëðÇçÐÌÍÎÏìíîïÙÚÛÜùúûüÑñŠšŸÿýŽž';
4 | const accentsOut =
5 | 'AAAAAAaaaaaaOOOOOOOooooooEEEEeeeeeCcDIIIIiiiiUUUUuuuuNnSsYyyZz';
6 | const strLen = str.length;
7 | let newStr = str.split('');
8 | let x;
9 |
10 | for (let i = 0; i < strLen; i += 1) {
11 | x = accents.indexOf(str[i]);
12 | if (x !== -1) {
13 | newStr[i] = accentsOut[x];
14 | }
15 | }
16 |
17 | newStr = newStr.join('');
18 | newStr = newStr.split('.').join('');
19 | newStr = newStr.split('-').join('');
20 | newStr = newStr.split('/').join('');
21 |
22 | return newStr;
23 | }
24 |
--------------------------------------------------------------------------------
/docs/components/containers/divider.md:
--------------------------------------------------------------------------------
1 | # Divider
2 |
3 | Dividers são componentes utilizados para separar ou agrupar conteúdo.
4 |
5 | ---
6 |
7 |
8 | ## Obs.:
9 | - A prop `vertical` ocualta o texto do divider.
10 |
11 |
12 |
13 | ---
14 |
15 | ## Uso
16 |
17 | ```js
18 |
19 | ```
20 |
21 | ---
22 |
23 | ## Preview
24 |
25 |
29 |
30 | ---
31 |
32 | ## Props
33 |
34 |
38 |
39 |
40 | ---
41 |
42 |
48 |
--------------------------------------------------------------------------------
/src/tests/ActionsList.spec.ts:
--------------------------------------------------------------------------------
1 | // @vitest-environment jsdom
2 | import { describe, test, expect } from 'vitest';
3 | import ActionsList from '../components/ActionsList.vue';
4 | import { mount } from '@vue/test-utils';
5 |
6 | const actions = [
7 | {
8 | 'title': 'Icon1',
9 | },
10 | {
11 | 'title': 'Icon2',
12 | },
13 | {
14 | 'title': 'Icon3',
15 | },
16 | {
17 | 'title': 'Icon4',
18 | }
19 | ];
20 |
21 | describe('ActionsList snapshot test', () => {
22 | test('renders correctly', () => {
23 | const wrapper = mount(ActionsList, {
24 | props: {
25 | actions,
26 | numberOfExpandedActions: 2,
27 | }
28 | });
29 |
30 | expect(wrapper.html()).toMatchSnapshot();
31 | });
32 | });
33 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/CollapsibleContainer.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`CollapsibleContainer > renders correctly 1`] = `
4 | "
5 | Seu universo expandido
7 |
8 |
11 |
"
12 | `;
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/Bug.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "🐞 Bug"
3 | about: Aponte um problema e ajude a evoluir o Cuida
4 | title: ""
5 | labels: "type:Bug"
6 | assignees: ""
7 | ---
8 |
9 | Encontrou um bug? Por favor, preencha as seções abaixo. 👍
10 |
11 | ### Resumo do problema
12 |
13 | Uma breve descrição do bug encontrado. Prints são muito bem-vindos.
14 |
15 | ### Passos para reproduzir
16 |
17 | 1. ...
18 | 2. ...
19 | 3. ...
20 |
21 | ### Qual o comportamento esperado?
22 |
23 | Qual deveria ser o comportamento padrão na situação mencionada?
24 |
25 | ### Detalhes técnicos
26 |
27 | - Versão do Cuida;
28 | - Versão das principais dependências envolvidas com o problema;
29 | - Navegador utilizado;
30 | - Versão do navegador;
31 |
--------------------------------------------------------------------------------
/.github/labeler.yml:
--------------------------------------------------------------------------------
1 | '🧱 Componente':
2 | - changed-files:
3 | - any-glob-to-any-file: ['src/components/index.ts']
4 |
5 | '🐛 Bug':
6 | - changed-files:
7 | - any-glob-to-any-file: ['src/components/*.vue']
8 | - all-globs-to-all-files: ['!src/stories/**']
9 |
10 | '📃 Documentação':
11 | - changed-files:
12 | - any-glob-to-any-file: ['src/stories/**/*.stories.mdx']
13 | - all-globs-to-all-files: ['!src/components/index.ts', '!src/components/*.vue']
14 |
15 | '🛠️ Build':
16 | - changed-files:
17 | - any-glob-to-any-file: ['vite.config.ts', 'src/components/index.ts', '.github/**/*']
18 |
19 | '🧩 Token':
20 | - changed-files:
21 | - any-glob-to-any-file: ['src/assets/sass/**/*', 'src/stories/tokens/*.stories.mdx']
22 |
--------------------------------------------------------------------------------
/src/assets/sass/legacy-tokens/borders.scss:
--------------------------------------------------------------------------------
1 | $border-radius-button: 4px;
2 | $border-radius-lil: 6px;
3 | $border-radius-extra-small: 8px;
4 | $border-radius-small: 12px;
5 | $border-radius-medium: 16px;
6 | $border-radius-large: 20px;
7 | $border-radius-extra-large: 24px;
8 | $border-radius-circle: 50%;
9 |
10 | $border-radius: ();
11 |
12 | $border-radius: map-merge(
13 | (
14 | 'button': $border-radius-button,
15 | 'lil': $border-radius-lil,
16 | 'extra-small': $border-radius-extra-small,
17 | 'small': $border-radius-small,
18 | 'medium': $border-radius-medium,
19 | 'large': $border-radius-large,
20 | 'extra-large': $border-radius-extra-large,
21 | 'circle': $border-radius-circle,
22 | ),
23 | $border-radius
24 | );
25 |
--------------------------------------------------------------------------------
/src/tests/InnerTabs.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import InnerTabs from '../components/InnerTabs.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | const mockedData = [
6 | { title: 'Dummy title 1', name: 'dummy-1' },
7 | { title: 'Dummy title 2', name: 'dummy-2' },
8 | { title: 'Dummy title 3', name: 'dummy-3' },
9 | { title: 'Dummy title 4', name: 'dummy-4' },
10 | ];
11 |
12 | describe('InnerTabs', () => {
13 | test('renders correctly', async () => {
14 | const wrapper = mount(InnerTabs, {
15 | props: {
16 | tabs: mockedData,
17 | activeTab: mockedData[0],
18 | headerLeft: false,
19 | },
20 | });
21 |
22 | expect(wrapper.html()).toMatchSnapshot();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/AlertCard.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`AlertCard snapshot test > renders correctly 1`] = `
4 | "Título do AlertCard Subtítulo do AlertCard
5 |
7 |
8 |
"
9 | `;
10 |
--------------------------------------------------------------------------------
/docs/utils/cds-tip.md:
--------------------------------------------------------------------------------
1 | # v-cds-tip
2 |
3 | Os v-cds-tip é uma diretiva do Cuida utilizada para implementar tooltips. O hover no componente dispara a exibição do tooptip. Para parar a exibição do tooptip basta enviar null como texto.
4 |
5 |
6 |
7 | #### Argumentos
8 |
9 | **(String):**
10 | - Especifica o texto do tooltip
11 | - Obrigatória: *Sim*
12 | - Valores válidos: qualquer string
13 |
14 |
15 |
16 | #### Retorno
17 |
18 | Nenhum
19 |
20 |
21 |
22 | #### Obs:
23 | - Utiliza o [tippy.js](https://tippyjs.bootcss.com/) como dependência. A leitura da documentação do tippy pode ajudar no uso dessa diretiva.
24 |
25 |
26 |
27 | #### Exemplo
28 |
29 | ```html
30 |
33 | ...
34 |
35 | ```
--------------------------------------------------------------------------------
/src/assets/sass/tokens/_borders.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:map';
2 |
3 | $border-radius-button: 4px;
4 | $border-radius-lil: 6px;
5 | $border-radius-extra-small: 8px;
6 | $border-radius-small: 12px;
7 | $border-radius-medium: 16px;
8 | $border-radius-large: 20px;
9 | $border-radius-extra-large: 24px;
10 | $border-radius-circle: 50%;
11 |
12 | $border-radius: ();
13 |
14 | $border-radius: map.merge(
15 | (
16 | 'button': $border-radius-button,
17 | 'lil': $border-radius-lil,
18 | 'extra-small': $border-radius-extra-small,
19 | 'small': $border-radius-small,
20 | 'medium': $border-radius-medium,
21 | 'large': $border-radius-large,
22 | 'extra-large': $border-radius-extra-large,
23 | 'circle': $border-radius-circle,
24 | ),
25 | $border-radius
26 | );
27 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Chip.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Chip > renders correctly 1`] = `
4 | "
5 |
6 |
7 |
8 |
9 |
10 |
11 | Chip
12 |
13 |
14 |
15 |
"
16 | `;
17 |
--------------------------------------------------------------------------------
/src/tests/Spacer.spec.ts:
--------------------------------------------------------------------------------
1 | // @vitest-environment jsdom
2 | import { describe, test, expect } from 'vitest';
3 | import Spacer from '../components/Spacer.vue';
4 | import { mount } from '@vue/test-utils';
5 |
6 | describe('Spacer snapshot test', () => {
7 | test('renders correctly', () => {
8 | const wrapper = mount(Spacer, {
9 | props: {
10 | paddingTop: 0,
11 | paddingRight: 0,
12 | paddingBottom: 0,
13 | paddingLeft: 0,
14 | marginTop: 0,
15 | marginRight: 0,
16 | marginBottom: 0,
17 | marginLeft: 0,
18 | },
19 | slots: {
20 | default: '
'
21 | }
22 | });
23 |
24 | expect(wrapper.html()).toMatchSnapshot();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/ProgressCircular.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`ProgressCircular > renders correctly 1`] = `
4 | "
5 |
8 | 1%
11 | "
12 | `;
13 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/TopAppBar.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`TopAppBar > renders correctly 1`] = `
4 | ""
14 | `;
15 |
--------------------------------------------------------------------------------
/src/tests/Table.spec.ts:
--------------------------------------------------------------------------------
1 |
2 | import { describe, test, expect } from 'vitest';
3 | import Table from '../components/Table.vue';
4 | import { shallowMount } from '@vue/test-utils';
5 |
6 | const fields = ['field1', 'field2', 'field3'];
7 |
8 | describe('Table', () => {
9 | test('renders correctly', async () => {
10 | const wrapper = shallowMount(Table, {
11 | props: {
12 | fields,
13 | items: [
14 | {
15 | field1: 'field 1 content',
16 | field2: 'field 2 content',
17 | field3: 'field 3 content',
18 | },
19 | {
20 | field1: 'field 1 content',
21 | field2: 'field 2 content',
22 | field3: 'field 3 content',
23 | },
24 | ],
25 | },
26 | });
27 |
28 | expect(wrapper.html()).toMatchSnapshot();
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/ToastContainer.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`ToastContainer snapshot test > renders correctly 1`] = `
4 | "
5 |
6 |
7 | "
8 | `;
9 |
--------------------------------------------------------------------------------
/docs/docgen/PreviewContainer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
20 |
21 |
31 |
--------------------------------------------------------------------------------
/.github/workflows/deployV2.yml:
--------------------------------------------------------------------------------
1 | name: "Deployer - Legacy 🚀"
2 | on:
3 | push:
4 | branches:
5 | - v2.70-legacy
6 |
7 | jobs:
8 | deploy:
9 | runs-on: ubuntu-latest
10 | concurrency: ci-${{github.ref}}
11 | steps:
12 | - name: 📚 Checkout
13 | uses: actions/checkout@v2.3.4
14 |
15 | - name: 🟢 Node
16 | uses: actions/setup-node@v2.1.4
17 | with:
18 | node-version: 14
19 | registry-url: https://registry.npmjs.org
20 |
21 | - name: 🔧 Build
22 | run: |
23 | npm ci
24 | npm run docs:build
25 |
26 | - name: 🚀 Deploy - legacy
27 | uses: JamesIves/github-pages-deploy-action@v4
28 | with:
29 | folder: docs/.vitepress/dist
30 | branch: gh-pages
31 |
--------------------------------------------------------------------------------
/src/tests/RadioButtonGroup.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import RadioButtonGroup from '../components/RadioButtonGroup.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | const options = [
6 | {
7 | text: 'Component1',
8 | value: 'value1',
9 | disabled: true,
10 | },
11 | {
12 | text: 'Component2',
13 | value: 'value2',
14 | },
15 | {
16 | text: 'Component3',
17 | value: 'value3',
18 | },
19 | ];
20 |
21 | describe('RadioButtonGroup', () => {
22 | test('renders correctly', async () => {
23 | const wrapper = mount(RadioButtonGroup, {
24 | props: {
25 | id: 'radio-button',
26 | modelValue: null,
27 | value: '',
28 | options,
29 | },
30 | });
31 |
32 | expect(wrapper.html()).toMatchSnapshot();
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Box.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Spacer snapshot test > renders correctly 1`] = `
4 | ""
19 | `;
20 |
--------------------------------------------------------------------------------
/src/components/Truncate.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
11 |
31 |
32 |
--------------------------------------------------------------------------------
/src/tests/FloatingActionButton.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import FloatingActionButton from '../components/FloatingActionButton.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | const subItems = [
6 | {
7 | icon: 'document-outline',
8 | label: 'Documentos',
9 | },
10 | {
11 | icon: 'home-outline',
12 | label: 'Início',
13 | },
14 | {
15 | icon: 'edit-outline',
16 | label: 'Editar',
17 | }
18 | ];
19 |
20 | describe('FloatingActionButton', () => {
21 | test('renders correctly', async () => {
22 | const wrapper = mount(FloatingActionButton, {
23 | props: {
24 | icon: 'plus-outline',
25 | size: 'md',
26 | variant: 'green',
27 | subItems,
28 | },
29 | });
30 |
31 | expect(wrapper.html()).toMatchSnapshot();
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/docs/components/forms/pin-input.md:
--------------------------------------------------------------------------------
1 | # PinInput
2 |
3 | PinInputs são componentes utilizados para adição de one-time passwords e códigos de 2FA
4 |
5 | ---
6 |
7 |
8 |
9 | ## Uso
10 |
11 | ```js
12 |
15 | ```
16 |
17 | ---
18 |
19 | ## Preview
20 |
21 |
26 |
27 | ---
28 |
29 | ## Props
30 |
31 |
35 |
36 |
37 | ## Eventos
38 |
39 |
43 |
44 |
54 |
--------------------------------------------------------------------------------
/docs/foundation/transições.md:
--------------------------------------------------------------------------------
1 | # Transições
2 |
3 | Os tokens de transição são utilizados para suavizar as interações com os componentes
4 | do Cuida.
5 |
6 |
7 |
8 |
9 | ## Recomendações
10 |
11 | - Os tokens de transição foram criados imaginando o seu uso em interações específicas (click, hover, aparecimento na tela).
12 | Evite utilizar os tokens em situações muito distintas daquelas pras quais foram projetados.
13 |
14 | ## Observações
15 | - Ao passar o mouse sobre a ilustração de exemplo na tabela, serão mostrados exemplos de transição usando os tokens.
16 |
17 |
18 |
19 | ## Tokens
20 | Os tokens de border-radius são variáveis scss e estão descritos abaixo.
21 |
22 |
23 |
24 |
28 |
--------------------------------------------------------------------------------
/src/tests/List.spec.ts:
--------------------------------------------------------------------------------
1 | // @vitest-environment jsdom
2 | import { describe, test, expect } from 'vitest';
3 | import List from '../components/List.vue';
4 | import { mount } from '@vue/test-utils';
5 |
6 | describe('List snapshot test', () => {
7 | test('renders correctly', () => {
8 | const wrapper = mount(List, {
9 | props: {
10 | items: [
11 | {
12 | title: 'List Title 1',
13 | content: 'Some quick example text to build on the List title and make up the bulk of the List\'s content.',
14 | },
15 | {
16 | title: 'List Title 2',
17 | content: 'Some quick example text to build on the List title and make up the bulk of the List\'s content.',
18 | },
19 | ],
20 | variant: 'green',
21 | }
22 | });
23 |
24 | expect(wrapper.html()).toMatchSnapshot();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/MobileStepperInput.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`MobileStepperInput > renders correctly 1`] = `
4 | ""
11 | `;
12 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/PasswordInput.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`PasswordInput > If component renders correctly 1`] = `
4 | ""
13 | `;
14 |
--------------------------------------------------------------------------------
/src/utils/composables/useDropdownPosition.js:
--------------------------------------------------------------------------------
1 | import { ref, computed } from 'vue';
2 |
3 | const internalHasFloatingLabel = ref(false);
4 |
5 | export function direction(elementRef, height, hasFloatingLabel) {
6 | internalHasFloatingLabel.value = hasFloatingLabel;
7 | const direction = ref('down');
8 | let boundingRect = elementRef.value.getBoundingClientRect();
9 |
10 | if ((boundingRect.top + boundingRect.height + height) < window.innerHeight) {
11 | direction.value = 'down';
12 | } else {
13 | direction.value = 'up';
14 | }
15 |
16 | return direction.value;
17 | }
18 |
19 | export const dropdownTopPosition = computed(() => {
20 | return internalHasFloatingLabel.value ? '56px' : '72px';
21 | });
22 |
23 | export const dropdownBottomPosition = computed(() => {
24 | return internalHasFloatingLabel.value ? '76px' : '68px';
25 | });
26 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: "🚀 Feature request"
3 | about: Sugira uma melhoria para o Cuida ou um novo componente / recurso
4 | title: ""
5 | labels: "type: Melhoria"
6 | assignees: ""
7 | ---
8 |
9 | ### Do que se trata o feature request?
10 |
11 | - [ ] Novo componente
12 | - [ ] Novo recurso na documentação
13 | - [ ] Novo recurso para facilitar o uso
14 |
15 | ### Visão geral
16 |
17 | Contextualize do que se trata a feature request.
18 |
19 | ### Propósito
20 |
21 | - Em que cenário esse recurso vai ser utilizado?
22 | - Como esse recurso ajuda a evoluir o Cuida?
23 | - Existem recursos no Cuida que são semelhantes, mas que não resolvem o problema?
24 |
25 | ### Exemplos
26 |
27 | Exemplos de componentes e recursos semelhantes presentes em outros Deisgn Systems de referência. Prints e gifs são sempre bem-vindos aqui.
28 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/FileViewer.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`FileViewer > renders correctly 1`] = `
4 | "
5 |
8 |
9 |
Comprovante de residência
10 |
https://images.pexels.com/photos/1254140/pexels-photo-1254140.jpeg
11 |
12 |
13 |
14 | "
15 | `;
16 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/FloatingActionButton.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`FloatingActionButton > renders correctly 1`] = `
4 | ""
12 | `;
13 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/TimeInput.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`TimeInput > renders correctly 1`] = `
4 | "
5 | Test label
6 |
7 |
8 |
9 |
14 |
15 |
"
16 | `;
17 |
--------------------------------------------------------------------------------
/docs/components/utils/truncate.md:
--------------------------------------------------------------------------------
1 | # Truncate
2 |
3 | Componente auxiliar utilizado para truncar texto adicionando a ele reticências
4 |
5 | ---
6 |
7 | ## Uso
8 |
9 | ```js
10 |
13 | Texto longo para testar o truncate
14 |
15 | ```
16 |
17 | ---
18 |
19 | ## Preview
20 |
21 |
26 | Texto longo para testar o truncate
27 |
28 |
29 | ---
30 |
31 | ## Props
32 |
33 |
37 |
38 |
39 | ## Slots
40 |
41 |
45 |
46 | ---
47 |
48 |
54 |
--------------------------------------------------------------------------------
/.github/workflows/publish-next.yml:
--------------------------------------------------------------------------------
1 | name: "Publisher Next 📦 (next branch)"
2 |
3 | on:
4 | push:
5 | branches:
6 | - next
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v2
14 | - name: Setup Node
15 | uses: actions/setup-node@v2
16 | with:
17 | node-version: '20.x'
18 | registry-url: 'https://registry.npmjs.org'
19 | - name: Install dependencies and build 🔧
20 | run: npm ci && npm run build
21 | - name: Bump version to next
22 | run: |
23 | npm version prerelease --preid=next
24 | git push origin next --follow-tags
25 | - name: Publish next version on NPM 📦
26 | run: npm publish --tag next
27 | env:
28 | NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
29 |
--------------------------------------------------------------------------------
/docs/components/loaders/loading-bar.md:
--------------------------------------------------------------------------------
1 | # LoadingBar Deprecated
2 |
3 | LoadingBars é um componente utilizado para indicar que o progresso de uma operação ainda não foi finalizado.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - For necessário impedir a visualização e navegação do conteúdo de páginas enquanto houver alguma pendência de operação.
10 |
11 |
12 |
13 | ## Quando não usar:
14 | - A visualização e navegação não puder ser interrompida.
15 |
16 | ---
17 |
18 | ## Uso
19 |
20 | ```js
21 |
22 | ```
23 |
24 | ---
25 |
26 | ## Preview
27 |
28 |
33 |
34 | ---
35 |
36 |
42 |
--------------------------------------------------------------------------------
/src/utils/composables/useComponentEmits.js:
--------------------------------------------------------------------------------
1 | export function nativeEmits(emits = null) {
2 | const emitBlur = (event) => emits('blur', event);
3 | const emitChange = (event) => emits('change', event);
4 | const emitClick = (event) => emits('click', event);
5 | const emitFocus = (event) => emits('focus', event);
6 | const emitKeydown = (event) => emits('keydown', event);
7 | const emitMouseenter = (event) => emits('mouseenter', event);
8 | const emitMouseleave = (event) => emits('mouseleave', event);
9 |
10 | return {
11 | emitBlur,
12 | emitChange,
13 | emitClick,
14 | emitFocus,
15 | emitKeydown,
16 | emitMouseenter,
17 | emitMouseleave,
18 | };
19 | }
20 |
21 | export const nativeEvents = {
22 | 'blur': null,
23 | 'change': null,
24 | 'click': null,
25 | 'focus': null,
26 | 'keydown': null,
27 | 'mouseenter': null,
28 | 'mouseleave': null,
29 | };
30 |
--------------------------------------------------------------------------------
/docs/components/forms/search-input.md:
--------------------------------------------------------------------------------
1 | # SearchInput
2 |
3 | SearchInputs permitem que os usuários realizem buscas sobre conjuntos de dados na interface
4 |
5 | ---
6 |
7 |
8 |
9 |
10 | ## Uso
11 |
12 | ```js
13 |
16 | ```
17 |
18 | ---
19 |
20 | ## Preview
21 |
22 |
27 |
28 | ---
29 |
30 | ## Props
31 |
32 |
36 |
37 |
38 |
54 |
--------------------------------------------------------------------------------
/docs/utils/rounder.md:
--------------------------------------------------------------------------------
1 | # Rounder()
2 |
3 | Método utilizado para determinar o `border-radius` de um elemento baseado na sua largura.
4 |
5 |
6 |
7 |
8 | ⚠️ *Método disponível apenas para desenvolvimento interno no Cuida*
9 |
10 |
11 |
12 | #### Argumentos
13 |
14 | **(Number):**
15 | - Largura de um elemento no DOM
16 | - Obrigatória: *Sim*
17 | - Valores válidos: qualquer número natural;
18 |
19 | **(Number):**
20 | - Limitador do border-radius. Essa prop limita o valor máximo que pode ser retornado.
21 | - Obrigatória: *Não*
22 | - Valores válidos: qualquer número natural;
23 | - Valor padrão: 24px;
24 |
25 |
26 |
27 | #### Retorno
28 |
29 | **(Number):** Valor a ser utilizado como border-radius, calculado à partir da largura de um elemento no DOM.
30 |
31 |
32 |
33 | #### Exemplo
34 |
35 | ```js
36 | rounder(this.width, 16);
37 | ```
38 |
--------------------------------------------------------------------------------
/src/tests/Spinner.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect, vi } from 'vitest';
2 | import Spinner from '../components/Spinner.vue';
3 | import { flushPromises, mount } from '@vue/test-utils';
4 |
5 | describe('Spinner', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(Spinner, {
8 | props: {
9 | size: 'sm',
10 | variant: 'blue',
11 | },
12 | });
13 |
14 | await flushPromises();
15 |
16 | expect(wrapper.html()).toMatchSnapshot();
17 | });
18 |
19 | test('renders correctly with delay', async () => {
20 | vi.useFakeTimers();
21 |
22 | const wrapper = mount(Spinner, {
23 | props: {
24 | size: 'sm',
25 | variant: 'blue',
26 | delay: 1000,
27 | },
28 | });
29 |
30 | expect(wrapper.html()).toMatchSnapshot();
31 |
32 | await vi.runAllTimers();
33 |
34 | expect(wrapper.html()).toMatchSnapshot();
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/docs/components/forms/chevron.md:
--------------------------------------------------------------------------------
1 | # Chevron
2 |
3 | Chevrons são elementos gráficos usados em interfaces para indicar possibilidade de interação.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - Parte de um elemento pode ser oculta o visível,
10 | - Indicar ações como `play`, `next` e `fastfoward`
11 |
12 |
13 |
14 |
15 | ## Quando não usar:
16 | - Como ícones.
17 | - Evite usar chevrons sem a propriedade `animate` ativa
18 |
19 | ---
20 |
21 | ## Uso
22 |
23 | ```js
24 |
25 | ```
26 |
27 | ---
28 |
29 | ## Preview
30 |
31 |
35 |
36 | ---
37 |
38 | ## Props
39 |
40 |
44 |
45 |
46 |
52 |
--------------------------------------------------------------------------------
/docs/pull_request_template.md:
--------------------------------------------------------------------------------
1 | #### Por favor, verifique se o seu pull request está de acordo com o checklist abaixo:
2 |
3 | - [x] A implementação feita possui testes (Caso haja um motivo para não haver testes/haver apenas testes de snapshot, descrever abaixo)
4 | - [x] A documentação no mdx foi feita ou atualizada, caso necessário
5 | - [x] O eslint passou localmente
6 |
7 | ### 1 - Resumo
8 |
9 | ### 2 - Tipo de pull request
10 |
11 | - [ ] 🧱 Novo componente
12 | - [ ] ✨ Nova feature ou melhoria
13 | - [ ] 🐛 Fix
14 | - [ ] 👨💻 Refatoração
15 | - [ ] 📝 Documentação
16 | - [ ] 🎨 Estilo
17 | - [ ] 🤖 Build ou CI/CD
18 |
19 |
20 | ### 3 - Esse PR fecha alguma issue? Favor referenciá-la
21 |
22 | ### 4 - Quais são os passos para avaliar o pull request?
23 |
24 | ### 5 - Imagem ou exemplo de uso:
25 |
26 | ### 6 - Esse pull request adiciona _breaking changes_?
27 | - [ ] Sim
28 | - [ ] Não
29 |
--------------------------------------------------------------------------------
/src/tests/Toast.spec.js:
--------------------------------------------------------------------------------
1 | import { describe, test, expect, vi } from 'vitest'
2 | import { mount } from '@vue/test-utils'
3 | import Toast from '../components/Toast.vue'
4 |
5 | describe('Toast', () => {
6 | test('renders correctly', () => {
7 | const wrapper = mount(Toast, {
8 | props: {
9 | modelValue: true,
10 | },
11 | })
12 |
13 | expect(wrapper.html()).toMatchSnapshot()
14 | })
15 |
16 | test('toast auto-dismisses after defined time', async () => {
17 | vi.useFakeTimers()
18 |
19 | const wrapper = mount(Toast, {
20 | props: {
21 | modelValue: true,
22 | autoDismissible: true,
23 | dismissAfter: 4000,
24 | },
25 | })
26 |
27 | expect(wrapper.vm.model).toBe(true)
28 |
29 | vi.advanceTimersByTime(4000)
30 |
31 | await wrapper.vm.$nextTick()
32 |
33 | expect(wrapper.emitted('dismiss')).toBeTruthy()
34 |
35 | vi.useRealTimers()
36 | })
37 | })
38 |
--------------------------------------------------------------------------------
/src/tests/MultiFileInput.spec.ts:
--------------------------------------------------------------------------------
1 | // @vitest-environment jsdom
2 | import { describe, test, expect } from 'vitest';
3 | import MultiFileInput from '../components/MultiFileInput.vue';
4 | import { mount } from '@vue/test-utils';
5 |
6 | describe('MultiFileInput snapshot test', () => {
7 | test('renders correctly', () => {
8 | const wrapper = mount(MultiFileInput, {
9 | props: {
10 | documents:[
11 | {
12 | name: 'Comprovante de residência',
13 | required: true,
14 | },
15 | {
16 | name: 'Guia de encaminhamento',
17 | required: false,
18 | },
19 | {
20 | name: 'RG',
21 | required: false,
22 | },
23 | {
24 | name: 'Passaporte',
25 | required: true,
26 | }
27 | ],
28 | variant: 'green',
29 | buttonSecondary: false,
30 | }
31 | });
32 |
33 | expect(wrapper.html()).toMatchSnapshot();
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/src/utils/composables/useClickOutside.js:
--------------------------------------------------------------------------------
1 | import { ref, onMounted, onUnmounted } from 'vue'
2 |
3 | export function useClickOutside(options = {}) {
4 | const clickedOutside = ref(options.initialState || false)
5 |
6 | let targetElement = null
7 |
8 | const handleClickOutside = (event) => {
9 | if (!targetElement) return
10 |
11 | clickedOutside.value = !targetElement.contains(event.target);
12 | }
13 |
14 | const setTargetElement = (element) => {
15 | targetElement = element
16 | }
17 |
18 | onMounted(() => {
19 | document.addEventListener('click', handleClickOutside)
20 | document.addEventListener('touchend', handleClickOutside)
21 | })
22 |
23 | onUnmounted(() => {
24 | document.removeEventListener('click', handleClickOutside)
25 | document.removeEventListener('touchend', handleClickOutside)
26 | })
27 |
28 | return {
29 | clickedOutside,
30 | setTargetElement
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/docs/foundation/peso-fonte.md:
--------------------------------------------------------------------------------
1 | # Peso da Fonte
2 |
3 | O peso da fonte é um token tipográfico que pode ser utilizado para alterar o valor padrão
4 | do peso da escala tipográfica e dar ênfase a determinado texto ou frase.
5 | Os pesos de fonte utilizados no Cuida são principalmente o Regular(430), o Semibold (600) e o Bold (800).
6 |
7 |
8 |
9 |
10 | ## Recomendações
11 |
12 | - Para facilitar o escaneamento e trabalhar a hierarquia de conteúdo, recomendamos a utilização pontual de textos em negrito.
13 | - Recomendamos a utilização de texto semibold(600) em títulos de seção e botões, devendo ser evitado o uso em textos
14 | no corpo das páginas.
15 | - Textos no corpo das páginas devem possuir, preferencialmente, peso de regular (430).
16 |
17 |
18 |
19 | ## Estilos Padrão
20 |
21 |
22 |
23 |
24 |
25 |
28 |
--------------------------------------------------------------------------------
/docs/utils/has-slot.md:
--------------------------------------------------------------------------------
1 | # HasSlot() Deprecated
2 |
3 | Método utilizado para checar se um slot específico está sendo usado no componente.
4 |
5 |
6 |
7 |
8 | ⚠️ **Esse Util está deprecated. Utilize o composable do Vue `useSlots()`**
9 |
10 | ⚠️ *Método disponível apenas para desenvolvimento interno no Cuida*
11 |
12 |
13 |
14 | #### Argumentos
15 |
16 | **(Objeto):**
17 | - Objeto de slots obtido com o `this.$slots`
18 | - Obrigatória: *Sim*
19 | - Valores válidos: objeto de slots do componente;
20 |
21 | **(String):**
22 | - Nome do slot que se deseja checar o uso
23 | - Obrigatória: *Sim*
24 | - Valores válidos: qualquer string contendo o nome de um dos slots do componente;
25 |
26 |
27 |
28 | #### Retorno
29 |
30 | **(Boolean):** Indica se um slot específico está em uso.
31 |
32 |
33 |
34 | #### Exemplo
35 |
36 | ```js
37 | hasSlot(this.$slots, 'image');
38 | ```
39 |
--------------------------------------------------------------------------------
/src/tests/Carousel.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import Carousel from '../components/Carousel.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | describe('Carousel', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(Carousel, {
8 | props: {
9 | items: [
10 | 'https://picsum.photos/600/800?random=1',
11 | 'https://picsum.photos/600/800?random=2',
12 | 'https://picsum.photos/600/800?random=3',
13 | 'https://picsum.photos/600/800?random=4',
14 | 'https://picsum.photos/600/800?random=5',
15 | 'https://picsum.photos/600/800?random=6',
16 | 'https://picsum.photos/600/800?random=7',
17 | ],
18 | gap: 0,
19 | snapTo: 'start',
20 | showArrows: false,
21 | darkArrows: false,
22 | },
23 | slots: {
24 | default: 'Texto',
25 | }
26 | });
27 |
28 | expect(wrapper.html()).toMatchSnapshot();
29 | });
30 | });
--------------------------------------------------------------------------------
/src/tests/__snapshots__/MobileNavbar.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`MobileNavbar > renders correctly 1`] = `
4 | "
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
"
13 | `;
14 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: "Tester ⚗️"
2 |
3 | on: [push]
4 |
5 | jobs:
6 | build:
7 | runs-on: ubuntu-latest
8 | strategy:
9 | matrix:
10 | node-version: [18, 20, 22]
11 | steps:
12 | - name: 📚 Checkout
13 | uses: actions/checkout@v2
14 | - name: 🟢 Node
15 | uses: actions/setup-node@v2.1.4
16 | with:
17 | node-version: ${{ matrix.node-version }}
18 | - name: 🔧 Build
19 | run: npm i
20 | - name: 🚀 Run tests with coverage
21 | run: npx vitest run --coverage
22 | - name: 📊 Upload coverage to Codecov
23 | if: always()
24 | uses: actions/upload-artifact@v4
25 | with:
26 | name: coverage-report-${{ matrix.node-version }}
27 | path: coverage/
28 | if-no-files-found: warn
29 | compression-level: 6
30 | overwrite: true
31 | include-hidden-files: false
--------------------------------------------------------------------------------
/docs/foundation/elevation.md:
--------------------------------------------------------------------------------
1 | # Elevação
2 |
3 | Os tokens de elevação são utilizados para indicar o posicionamento dos diversos
4 | elementos da interface no eixo Z, dividindo os componentes em camadas. Por padrão
5 | todos os componentes estão dispostos na mesma camada.
6 |
7 |
8 |
9 |
10 | ## Recomendações
11 |
12 | - Os tokens de elevação foram criados imaginando o seu uso em componentes de referência (backdrop, toolbar, modal, etc.).
13 | Evite utilizar os tokens em "classes de componente" muito distintas daquelas pras quais foram projetados.
14 |
15 | ## Observações
16 | - Ao passar o mouse sobre a ilustração de exemplo na tabela, será mostrada a comparação dos tokens e seus níveis de elevação.
17 |
18 |
19 |
20 | ## Tokens
21 | Os tokens de elevação são variáveis scss e estão descritos abaixo.
22 |
23 |
24 |
25 |
28 |
--------------------------------------------------------------------------------
/src/utils/methods/contrastChecker.js:
--------------------------------------------------------------------------------
1 | const RED = 0.2126;
2 | const GREEN = 0.7152;
3 | const BLUE = 0.0722;
4 | const GAMMA = 2.4;
5 |
6 | const PARAMETER = {
7 | POOR: 3,
8 | GOOD: 4.5,
9 | VERYGOOD: 7,
10 | SUPER: 12,
11 | }
12 |
13 | import hexToRgb from './hexToRgb.js';
14 |
15 | export default (color1, color2, parameter = 'GOOD') => {
16 | let color1RGB = hexToRgb(color1);
17 | let color2RGB = hexToRgb(color2);
18 |
19 | var lum1 = luminance(...color1RGB);
20 | var lum2 = luminance(...color2RGB);
21 | var brightest = Math.max(lum1, lum2);
22 | var darkest = Math.min(lum1, lum2);
23 |
24 | return ((brightest + 0.05) / (darkest + 0.05)) >= PARAMETER[parameter];
25 | };
26 |
27 | function luminance(r, g, b) {
28 | var a = [r, g, b].map((v) => {
29 | v /= 255;
30 | return v <= 0.03928
31 | ? v / 12.92
32 | : Math.pow((v + 0.055) / 1.055, GAMMA);
33 | });
34 |
35 | return a[0] * RED + a[1] * GREEN + a[2] * BLUE;
36 | }
37 |
--------------------------------------------------------------------------------
/src/tests/Stepper.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import Stepper from '../components/Stepper.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | const mocked_data = [
6 | {
7 | label: 'Dummy label 1',
8 | completed: true,
9 | inProcessing: false,
10 | error: false,
11 | },
12 | {
13 | label: 'Dummy label 3',
14 | completed: false,
15 | inProcessing: true,
16 | error: false,
17 | },
18 | {
19 | label: 'Dummy label 2',
20 | completed: false,
21 | inProcessing: false,
22 | error: true,
23 | },
24 | {
25 | label: 'Dummy label X',
26 | completed: false,
27 | inProcessing: false,
28 | error: false,
29 | },
30 | ];
31 |
32 | describe('Stepper', () => {
33 | test('renders correctly', async () => {
34 | const wrapper = mount(Stepper, {
35 | props: {
36 | value: 4,
37 | steps: mocked_data,
38 | },
39 | });
40 |
41 | expect(wrapper.html()).toMatchSnapshot();
42 | });
43 | });
44 |
--------------------------------------------------------------------------------
/docs/components/loaders/spinner.md:
--------------------------------------------------------------------------------
1 | # Spinner
2 |
3 | Spinners é um componente utilizado para indicar que o progresso de uma operação ainda não foi finalizado.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - For necessário impedir a visualização e navegação do conteúdo de páginas enquanto houver alguma pendência de operação.
10 |
11 |
12 |
13 | ## Quando não usar:
14 | - A visualização e navegação não puder ser interrompida.
15 |
16 | ---
17 |
18 | ## Uso
19 |
20 | ```js
21 |
25 | ```
26 |
27 | ---
28 |
29 | ## Preview
30 |
31 |
35 |
36 | ---
37 |
38 | ## Props
39 |
40 |
44 |
45 |
46 | ---
47 |
48 |
56 |
--------------------------------------------------------------------------------
/types/vitepress-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | import type { Component } from "vue";
4 | import type { DefineComponent } from "vue";
5 | import type { PreviewBuilderType } from "../docs/docgen/PreviewBuilder.vue";
6 | import type { PreviewContainerType } from "../docs/docgen/PreviewContainer.vue";
7 | import type { PlaygroundBuilderType } from "../docs/docgen/PlaygroundBuilder.vue";
8 | import type { LogBuilderType } from "../docs/docgen/LogBuilder.vue";
9 |
10 | // Aqui você declara todos os componentes globais que quer autocomplete
11 | declare module "vue" {
12 | export interface GlobalComponents {
13 | CdsButton: Component;
14 | CdsInput: Component;
15 | CdsSpinner: Component;
16 | CdsCard: Component;
17 | APITable: Component;
18 | PreviewContainer: PreviewContainerType;
19 | PlaygroundBuilder: PlaygroundBuilderType;
20 | FigmaFrame: Component;
21 | PreviewBuilder: PreviewBuilderType;
22 | LogBuilder: LogBuilderType;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/assets/sass/legacy-tokens/elevation.scss:
--------------------------------------------------------------------------------
1 | $z-index-sunk: -1000;
2 | $z-index-base: 0;
3 | $z-index-backdrop: 1000;
4 | $z-index-toolbar: 2000;
5 | $z-index-sidesheet: 2500;
6 | $z-index-modal: 3000;
7 | $z-index-tooltip: 4000;
8 | $z-index-toast: 5000;
9 |
10 | $z-index: ();
11 |
12 | $z-index: map-merge(
13 | (
14 | 'sunk': $z-index-sunk,
15 | 'base': $z-index-base,
16 | 'backdrop': $z-index-backdrop,
17 | 'toolbar': $z-index-toolbar,
18 | 'sidesheet': $z-index-sidesheet,
19 | 'modal': $z-index-modal,
20 | 'tooltip': $z-index-tooltip,
21 | 'toast': $z-index-toast,
22 | ),
23 | $z-index
24 | );
25 |
26 | .z-index-sunk { $z-index-sunk: -1000; }
27 | .z-index-base { $z-index-base: 0; }
28 | .z-index-backdrop { $z-index-backdrop: 1000; }
29 | .z-index-toolbar { $z-index-toolbar: 2000; }
30 | .z-index-sidesheet { $z-index-sidesheet: 2500; }
31 | .z-index-modal { $z-index-modal: 3000; }
32 | .z-index-tooltip { $z-index-tooltip: 4000; }
33 | .z-index-toast { $z-index-toast: 5000; }
--------------------------------------------------------------------------------
/src/tests/Breadcrumb.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import Breadcrumb from '../components/Breadcrumb.vue';
3 | import { shallowMount } from '@vue/test-utils';
4 |
5 | const items = [
6 | {
7 | label: 'Relatórios',
8 | route: {
9 | path: '/reports',
10 | name: 'reports'
11 | },
12 | },
13 | {
14 | label: 'Relatórios individualizados',
15 | route: {
16 | path: '/individualized-reports',
17 | name: 'individualized'
18 | },
19 | },
20 | {
21 | label: 'Relatório de usuários',
22 | route: {
23 | path: '/users-reports',
24 | name: 'users'
25 | },
26 | },
27 | ];
28 |
29 | describe('Breadcrumb snapshot test', () => {
30 | test('renders correctly', () => {
31 | const wrapper = shallowMount(Breadcrumb, {
32 | global: {
33 | stubs: {
34 | 'router-link': true,
35 | },
36 | },
37 | props: {
38 | items: items,
39 | },
40 | });
41 |
42 | expect(wrapper.html()).toMatchSnapshot();
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "module": "ESNext",
5 | "lib": ["ESNext", "DOM"],
6 | "allowJs": true,
7 | "rootDir": "",
8 | "outDir": "dist",
9 | "useDefineForClassFields": true,
10 | "moduleResolution": "Node",
11 | "strict": false,
12 | "jsx": "preserve",
13 | "jsxFactory": "h",
14 | "sourceMap": true,
15 | "resolveJsonModule": true,
16 | "isolatedModules": true,
17 | "esModuleInterop": true,
18 | "skipLibCheck": true,
19 | "baseUrl": "./",
20 | "types": ["vite/client", "vue"],
21 | "paths": {
22 | "@/*": ["src/*"]
23 | }
24 | },
25 | "include": [
26 | "src",
27 | "types"
28 | ],
29 | "vueCompilerOptions": {
30 | "vitePressExtensions": [".md"]
31 | },
32 | "exclude": [
33 | "node_modules",
34 | "dist",
35 | "docs",
36 | "**/*.spec.ts",
37 | "**/*.test.ts"
38 | ],
39 | "references": [{ "path": "./tsconfig.node.json" }]
40 | }
41 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Textarea.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`TextArea > renders correctly 1`] = `
4 | ""
22 | `;
23 |
--------------------------------------------------------------------------------
/.github/workflows/build-docs.yml:
--------------------------------------------------------------------------------
1 | name: 'Build docs 📚'
2 | permissions:
3 | contents: read
4 |
5 | on: [push]
6 |
7 | jobs:
8 | docs-build:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: 📚 Checkout
12 | uses: actions/checkout@v4
13 | with:
14 | fetch-depth: 0
15 |
16 | - name: 🟢 Setup Node
17 | uses: actions/setup-node@v4
18 | with:
19 | node-version: 22
20 | cache: npm
21 |
22 | - name: 📦 Install dependencies
23 | run: npm ci
24 |
25 | - name: 🔨 Build JSDocs JSON
26 | run: npm run build
27 | env:
28 | NODE_OPTIONS: "--experimental-specifier-resolution=node"
29 |
30 | - name: 📖 Build documentation with VitePress
31 | run: npm run docs:build
32 | env:
33 | NODE_OPTIONS: "--experimental-specifier-resolution=node"
34 |
35 | - name: ✅ Build completed successfully
36 | run: echo "Documentation build completed successfully!"
37 |
--------------------------------------------------------------------------------
/src/utils/composables/useInputStatusClasses.js:
--------------------------------------------------------------------------------
1 | import { computed } from 'vue';
2 |
3 | export function useInputStatusClasses(baseClass, state, disabled, hasFocus) {
4 | return computed(() => {
5 | let inputStatusClass = '';
6 |
7 | if (!hasFocus.value) {
8 | inputStatusClass = `${baseClass}`;
9 |
10 | if (!disabled) {
11 | if (state === 'valid') {
12 | inputStatusClass += ` ${baseClass}--valid`;
13 | } else if (state === 'invalid') {
14 | inputStatusClass += ` ${baseClass}--invalid`;
15 | }
16 | } else {
17 | inputStatusClass += ` ${baseClass}--disabled`;
18 | }
19 | } else if (!disabled) {
20 | if (state === 'default') {
21 | inputStatusClass += ` ${baseClass}--focused`;
22 | } else if (state === 'valid') {
23 | inputStatusClass += ` ${baseClass}--focused-valid`;
24 | } else if (state === 'invalid') {
25 | inputStatusClass += ` ${baseClass}--focused-invalid`;
26 | }
27 | }
28 |
29 | return inputStatusClass;
30 | });
31 | }
32 |
--------------------------------------------------------------------------------
/src/assets/sass/tokens/_elevation.scss:
--------------------------------------------------------------------------------
1 | @use 'sass:map';
2 |
3 | $z-index-sunk: -1000;
4 | $z-index-base: 0;
5 | $z-index-backdrop: 1000;
6 | $z-index-toolbar: 2000;
7 | $z-index-sidesheet: 2500;
8 | $z-index-modal: 3000;
9 | $z-index-tooltip: 4000;
10 | $z-index-toast: 5000;
11 |
12 | $z-index: ();
13 |
14 | $z-index: map.merge(
15 | (
16 | 'sunk': $z-index-sunk,
17 | 'base': $z-index-base,
18 | 'backdrop': $z-index-backdrop,
19 | 'toolbar': $z-index-toolbar,
20 | 'sidesheet': $z-index-sidesheet,
21 | 'modal': $z-index-modal,
22 | 'tooltip': $z-index-tooltip,
23 | 'toast': $z-index-toast,
24 | ),
25 | $z-index
26 | );
27 |
28 | .z-index-sunk { $z-index-sunk: -1000; }
29 | .z-index-base { $z-index-base: 0; }
30 | .z-index-backdrop { $z-index-backdrop: 1000; }
31 | .z-index-toolbar { $z-index-toolbar: 2000; }
32 | .z-index-sidesheet { $z-index-sidesheet: 2500; }
33 | .z-index-modal { $z-index-modal: 3000; }
34 | .z-index-tooltip { $z-index-tooltip: 4000; }
35 | .z-index-toast { $z-index-toast: 5000; }
--------------------------------------------------------------------------------
/src/tests/__snapshots__/BaseMobileInput.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`BaseMobileInput > renders correctly 1`] = `
4 | ""
14 | `;
15 |
--------------------------------------------------------------------------------
/src/utils/composables/useToast.js:
--------------------------------------------------------------------------------
1 | import generateKey from '../methods/uuidv4';
2 | import { reactive } from 'vue'
3 |
4 | export const toastState = reactive({
5 | toasts: [],
6 | });
7 |
8 | export function useToast() {
9 | function fire({
10 | title,
11 | description = null,
12 | variant = 'info',
13 | dismissible = true,
14 | dismissAfter = 4000,
15 | autoDismissible = true,
16 | light = false,
17 | }) {
18 | const id = generateKey();
19 |
20 | toastState.toasts.push({
21 | id,
22 | title,
23 | description,
24 | variant,
25 | dismissible,
26 | dismissAfter,
27 | autoDismissible,
28 | light,
29 | });
30 |
31 | if (autoDismissible) {
32 | setTimeout(() => {
33 | dismissToast(id);
34 | }, dismissAfter);
35 | }
36 | }
37 |
38 | function dismissToast(id) {
39 | const index = toastState.toasts.findIndex((toast) => toast.id === id);
40 | if (index !== -1) toastState.toasts.splice(index, 1);
41 | }
42 |
43 | return {
44 | toastState,
45 | fire,
46 | dismissToast,
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/docs/components/estrutural/page-container.md:
--------------------------------------------------------------------------------
1 | # PageContainer
2 |
3 | PageContainers são blocos básicos de estrutura no Cuida. Eles provêm padding e alinhamento de conteúdo.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - PageContainers devem ser usados sempre na construção das páginas, com o conteúdo sendo colocado como slot no componente.
10 |
11 |
12 |
13 | ## Quando não usar:
14 | - Não devem ser usados PageContainers aninhados.
15 |
16 | ---
17 |
18 | ## Uso
19 |
20 | ```vue
21 |
22 | Teste
23 |
24 | ```
25 |
26 | ---
27 |
28 | ## Preview
29 |
30 |
31 |
32 |
35 | Componente interno
36 |
37 |
38 |
39 |
40 | ---
41 |
42 | ## Slots
43 |
44 |
48 |
49 |
52 |
--------------------------------------------------------------------------------
/docs/components/containers/box.md:
--------------------------------------------------------------------------------
1 | # Box
2 |
3 | Boxes são componentes básicos de container que encapsulam conteúdo com o estilo padrão de borda, de sombra e de padding do cuida. Podem ser utilizados como componente primivo para cards, popovers, modais, etc.
4 |
5 | ---
6 |
7 | ## Uso
8 |
9 | ```js
10 |
13 | 2
14 |
15 | ```
16 |
17 | ---
18 |
19 | ## Preview
20 |
21 |
26 | 2
27 |
28 |
29 | ---
30 |
31 | ## Props
32 |
33 |
37 |
38 |
39 | ## Eventos
40 |
41 |
45 |
46 |
47 | ## Slots
48 |
49 |
53 |
54 |
55 |
65 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Breadcrumb.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Breadcrumb snapshot test > renders correctly 1`] = `
4 | "
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | "
17 | `;
18 |
--------------------------------------------------------------------------------
/src/tests/MobileNavbar.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import MobileNavbar from '../components/MobileNavbar.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | const mockedData = [
6 | { icon: 'home-outline', label: 'Início', route: { name: 'Google', path: 'www.google.com' } },
7 | { icon: 'search-outline', label: 'Busca', route: { name: 'Google', path: 'www.google.com' } },
8 | { icon: 'notification-bell-outline', label: 'Notificações', route: { name: 'Google', path: 'www.google.com' } },
9 | { icon: 'user-outline', label: 'Perfil', route: { name: 'Google', path: 'www.google.com' } },
10 | ];
11 |
12 | describe('MobileNavbar', () => {
13 | test('renders correctly', async () => {
14 | const wrapper = mount(MobileNavbar, {
15 | global: {
16 | stubs: {
17 | 'cds-icon': true,
18 | 'cds-avatar': true,
19 | 'router-link': true,
20 | },
21 | },
22 | props: {
23 | items: mockedData,
24 | variant: 'blue',
25 | },
26 | });
27 |
28 | expect(wrapper.html()).toMatchSnapshot();
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/docs/components/forms/file-input.md:
--------------------------------------------------------------------------------
1 | # FileInput
2 |
3 | FileInput é um input customizado de arquivos.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - For necessário que o usuário faça uploads do seu computador para a plataforma.
10 | - For necessário prover uma experiência de arrasta e solta para upload de arquivos.
11 |
12 |
13 |
14 | ## Quando não usar:
15 | - Se tratar de uma experiência mobile-first.
16 |
17 |
18 | ---
19 |
20 | ## Uso
21 |
22 | ```js
23 |
26 | ```
27 |
28 | ---
29 |
30 | ## Preview
31 |
32 |
37 |
38 | ---
39 |
40 | ## Props
41 |
42 |
46 |
47 |
48 | ## Eventos
49 |
50 |
54 |
55 |
56 |
66 |
--------------------------------------------------------------------------------
/src/tests/CollapsibleContainer.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import CollapsibleContainer from '../components/CollapsibleContainer.vue';
3 | import { flushPromises, mount } from '@vue/test-utils';
4 |
5 | describe('CollapsibleContainer', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(CollapsibleContainer, {
8 | props: {
9 | modelValue: true,
10 | title: 'Seu universo expandido',
11 | },
12 | });
13 |
14 | expect(wrapper.html()).toMatchSnapshot();
15 | });
16 |
17 | test('content is rendered correctly on modelValue change', async () => {
18 | expect.assertions(2);
19 |
20 | const wrapper = mount(CollapsibleContainer, {
21 | props: {
22 | modelValue: false,
23 | title: 'Seu universo expandido',
24 | },
25 | });
26 |
27 | expect(wrapper.findAll('[data-testid="collapsible-content"]').length).toBe(0);
28 |
29 | wrapper.setProps({
30 | modelValue: true,
31 | });
32 |
33 | await flushPromises();
34 |
35 | expect(wrapper.findAll('[data-testid="collapsible-content"]').length).toBe(1);
36 | })
37 | });
38 |
--------------------------------------------------------------------------------
/src/tests/Timeline.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import Timeline from '../components/Timeline.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | const history = [
6 | {
7 | date: '22/09/2022',
8 | title: 'Bloqueio nível 1',
9 | text: 'Usuário: Uncle Bob',
10 | _dotStyle: 'hollowed',
11 | },
12 | {
13 | date: '15/05/2022',
14 | title: 'Bloqueio nível 2',
15 | text: 'Usuário: Linus Torvalds',
16 | _dotStyle: 'hollowed',
17 | },
18 | {
19 | date: '18/02/2022',
20 | title: 'Bloqueio nível 1',
21 | text: 'Usuário: Don Norman',
22 | },
23 | {
24 | date: '20/12/2021',
25 | title: 'Bloqueio nível 3',
26 | text: 'Usuário: Richard Stallman',
27 | _dotStyle: 'filled',
28 | },
29 | {
30 | date: '04/11/2021',
31 | title: 'Bloqueio nível 1',
32 | text: 'Usuário: Dennis Ritchie',
33 | },
34 | ];
35 |
36 | describe('Timeline', () => {
37 | test('renders correctly', async () => {
38 | const wrapper = mount(Timeline, {
39 | props: {
40 | history,
41 | },
42 | });
43 |
44 | expect(wrapper.html()).toMatchSnapshot();
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/docs/components/loaders/skeleton-text.md:
--------------------------------------------------------------------------------
1 | # Skeleton Text Deprecated
2 |
3 | Skeleton texts permitem exibir um estado de carregamento para vários tipos de componentes
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - Informar ao usuário que as informações do componentes estão sendo carregadas.
10 | - O conteúdo a ser carregado for dinâmico.
11 |
12 |
13 |
14 | ## Quando não usar:
15 | - O conteúdo a ser carregado for estático.
16 |
17 | ## Observações
18 | - O Skeleton text deve ser ajustado de acordo com o componente a ser utilizado.
19 |
20 | ---
21 |
22 | ## Uso
23 |
24 | ```js
25 |
28 | ```
29 |
30 | ---
31 |
32 | ## Preview
33 |
34 |
38 |
39 | ---
40 |
41 | ## Props
42 |
43 |
47 |
48 |
49 | ---
50 |
51 |
59 |
--------------------------------------------------------------------------------
/docs/.vitepress/theme/Layout.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Cuida Design System
7 |
8 |
9 | O Cuida é o design system open source da Sysvale, pensado para
10 | ajudar times de produto a trabalhar de modo consistente e
11 | performático na construção de aplicações do Cidade Saudável.
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
34 |
35 |
44 |
--------------------------------------------------------------------------------
/docs/components/loaders/overlay-loader.md:
--------------------------------------------------------------------------------
1 | # OverlayLoader
2 |
3 | OverlayLoader é utilizado para indicar o carregamento de componentes internos de páginas, como cards e gráficos.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - Para indicar o carregamento de elementos de página que ainda não possuam skeleton implementado.
10 |
11 |
12 |
13 | ## Quando não usar:
14 | - Não utilize o OverlayLoader para carregamento de páginas. Nesses casos prefira o Spinner.
15 | - Não utilize o OverlayLoader para indicar carregameto de componentes que possuam skeletons implementados
16 |
17 | ---
18 |
19 | ## Uso
20 |
21 | ```js
22 |
26 | ```
27 |
28 | ---
29 |
30 | ## Preview
31 |
32 |
36 |
37 | ---
38 |
39 | ## Props
40 |
41 |
45 |
46 |
47 | ---
48 |
49 |
55 |
--------------------------------------------------------------------------------
/docs/components/utils/clickable.md:
--------------------------------------------------------------------------------
1 | # Clickable Deprecated
2 |
3 | Componente utilizado para adicionar um wrapper cliclável a componentes que não possuem interação nativa por clique.
4 |
5 | ---
6 |
7 | ## Uso
8 |
9 | ```js
10 |
14 | Texto clicável
15 |
16 | ```
17 |
18 | ---
19 |
20 | ## Preview
21 |
22 |
27 | Texto clicável
28 |
29 |
30 | ---
31 |
32 | ## Props
33 |
34 |
38 |
39 |
40 | ## Eventos
41 |
42 |
46 |
47 |
48 | ## Slots
49 |
50 |
54 |
55 | ---
56 |
57 |
67 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/EmptyState.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`EmptyState > renders correctly 1`] = `
4 | "
5 |
7 |
EmptyState title
8 |
9 | EmptyState text
11 |
12 |
17 |
18 |
19 | Finalizar
20 |
21 |
22 |
"
23 | `;
24 |
--------------------------------------------------------------------------------
/docs/components/forms/label.md:
--------------------------------------------------------------------------------
1 | # Label
2 |
3 | Permite que o usuário adicione, remova e edite múltiplos inputs em uma lista dinâmica.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - Em conjunto com componentes que não apresentam nativamente a label;
10 |
11 |
12 |
13 | ## Quando não usar:
14 | - Um componente já possui nativamente a label;
15 | ---
16 |
17 | ## Uso
18 |
19 | ```js
20 |
21 | ```
22 |
23 | ---
24 |
25 | ## Preview
26 |
27 |
32 |
33 | ---
34 |
35 | ## Props
36 |
37 |
41 |
42 |
43 | ## Eventos
44 |
45 |
49 |
50 |
51 |
70 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/CalloutCard.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`CalloutCard > renders correctly 1`] = `
4 | "Título do CalloutCard
Texto do CalloutCar
5 |
6 |
7 |
12 |
13 |
14 | Ok
15 |
16 |
17 |
18 |
19 |
"
20 | `;
21 |
--------------------------------------------------------------------------------
/docs/utils/contrast-checker.md:
--------------------------------------------------------------------------------
1 | # ContrastChecker()
2 |
3 | Os ContrastChecker() é um método utilizado para testar o contraste entre duas cores.
4 |
5 |
6 |
7 |
8 | ⚠️ *Método disponível apenas para desenvolvimento interno no Cuida*
9 |
10 |
11 |
12 | #### Argumentos
13 |
14 | **(String):**
15 | - Hexadecimal da **primeira** cor de teste
16 | - Obrigatória: *Sim*
17 | - Valores válidos: qualquer string no formato hexadecimal. ex.: '#000000';
18 |
19 | **(String):**
20 | - Hexadecimal da **segunda** cor de teste
21 | - Obrigatória: *Sim*
22 | - Valores válidos: qualquer string no formato hexadecimal. ex.: '#000000';
23 |
24 | **(String):**
25 | - Parâmetro usado como referência na avaliação do contraste entre as cores. O parâmetro recomendado para textos de até 18px é 'VERYGOOD' ou 'SUPER'.
26 | - Obrigatória: *Não*
27 | - Valores válidos: 'POOR', 'GOOD', 'VERYGOOD', 'SUPER';
28 | - Valor padrão: 'GOOD';
29 |
30 |
31 |
32 | #### Retorno
33 |
34 | **(Boolean):** Indica se o teste de contraste entre as duas cores informadas foi aprovado.
35 |
36 |
37 |
38 | #### Exemplo
39 |
40 | ```js
41 | ContrastChecker('#2AC092', '#FFFFFF', 'POOR');
42 | ```
43 |
--------------------------------------------------------------------------------
/docs/components/forms/time-input.md:
--------------------------------------------------------------------------------
1 | # TimeInput
2 |
3 | TimeInputs são componentes utilizados para inserir horários específicos no formato simples: hora e minutos.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - For necessário definir horários de eventos, agendamentos, alarmes e etc…
10 |
11 |
12 |
13 | ## Quando não usar:
14 | - For necessário mostrar opções disponíveis de horários para seleção.
15 |
16 |
17 |
18 | ---
19 |
20 | ## Uso
21 |
22 | ```js
23 |
27 | ```
28 |
29 | ---
30 |
31 | ## Preview
32 |
33 |
38 |
39 | ---
40 |
41 | ## Props
42 |
43 |
47 |
48 |
49 | ## Eventos
50 |
51 |
55 |
56 |
57 |
70 |
--------------------------------------------------------------------------------
/docs/components/navegação/link.md:
--------------------------------------------------------------------------------
1 | # Link
2 |
3 | Links são componentes usados para navegar para outra página e podem abrir uma nova guia.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - For necessário navegar para outra seção ou página.
10 | - For necessário redirecionar para um site ou documento externo.
11 |
12 |
13 |
14 | ## Quando não usar:
15 | - For necessário executar uma ação (exemplo: salvar, editar). Nesses casos é recomendado utilizar o componente Button.
16 |
17 | ---
18 |
19 | ## Uso
20 |
21 | ```js
22 |
26 | ```
27 |
28 | ---
29 |
30 | ## Preview
31 |
32 |
37 |
38 | ---
39 |
40 | ## Props
41 |
42 |
46 |
47 |
48 | ## Slots
49 |
50 |
54 |
55 |
64 |
--------------------------------------------------------------------------------
/src/tests/Chip.spec.js:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import Chip from '../components/Chip.vue';
3 | import { flushPromises, mount } from '@vue/test-utils';
4 |
5 | describe('Chip', () => {
6 | test('renders correctly', async () => {
7 | const wrapper = mount(Chip, {
8 | props: {
9 | modelValue: false,
10 | variant: 'gray',
11 | },
12 | slots: {
13 | default: 'Chip'
14 | }
15 | });
16 |
17 | expect(wrapper.html()).toMatchSnapshot();
18 | });
19 |
20 | test('emits update modelValue event based on click correctly', async () => {
21 | expect.assertions(2);
22 |
23 | const wrapper = mount(Chip, {
24 | props: {
25 | modelValue: false,
26 | variant: 'gray',
27 | },
28 | slots: {
29 | default: 'Chip'
30 | }
31 | });
32 |
33 | const container = wrapper.find('[data-testid="chip-container"]');
34 |
35 | container.trigger('click');
36 |
37 | await flushPromises();
38 |
39 | expect(wrapper.emitted()['update:modelValue'][0]).toEqual([true]);
40 |
41 | container.trigger('click');
42 |
43 | await flushPromises();
44 |
45 | expect(wrapper.emitted()['update:modelValue'][1]).toEqual([false]);
46 | });
47 | });
48 |
--------------------------------------------------------------------------------
/docs/foundation/bordas.md:
--------------------------------------------------------------------------------
1 | # Bordas
2 |
3 | Os tokens de border-radius são utilizados para arredondar as bordas dos cantos de componentes
4 | da interface, tornando-os mais sutis, amigáveis e orgânicos. No Cuida, prezamos por bordas um
5 | tanto arredondadas, que crescem de acordo com o tamanho do componente.
6 |
7 |
8 |
9 |
10 | ## Recomendações
11 |
12 | - Não recomendamos a utilização de componentes com border-radius igual a 0,
13 | uma vez que vão contra a linguagem visual que estamos construindo.
14 |
15 | - Não recomendamos utilizar bordas muito arredondadas em elementos
16 | pequenos. O objetivo é ter bordas mais orgânicas, e não elementos arredondados.
17 |
18 | - Recomendamos que os elementos possuam border-radius uniformes, por isso nossos
19 | tokens não preveem cenários nos quais um elemento possui border-radius
20 | diferentes para cada um de seus cantos. Caso percebamos essa necessidade,
21 | trabalharemos nisso no futuro.
22 |
23 |
24 |
25 |
26 | ## Tokens
27 | Os tokens de border-radius são variáveis scss e estão descritos abaixo.
28 |
29 |
30 |
31 |
34 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/BaseInput.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`BaseInput > renders correctly 1`] = `
4 | ""
23 | `;
24 |
--------------------------------------------------------------------------------
/docs/components/navegação/segmented-control.md:
--------------------------------------------------------------------------------
1 | # SegmentedControl
2 |
3 | SegmentedControls são componentes que permitem que o usuário visualize versões alternativas de uma feature ou interface
4 |
5 | ---
6 |
7 | ## Uso
8 |
9 | ```js
10 |
16 | ```
17 |
18 | ---
19 |
20 | ## Preview
21 |
22 |
27 |
28 | ---
29 |
30 | ## Props
31 |
32 |
36 |
37 |
38 | ## Eventos
39 |
40 |
44 |
45 |
46 |
59 |
--------------------------------------------------------------------------------
/docs/foundation/cores.md:
--------------------------------------------------------------------------------
1 | # Cores
2 |
3 | As cores são importantes para identificação do nosso
4 | produto, além de ajudarem a criar experiências
5 | consistentes através das nossas soluções.
6 |
7 |
8 |
9 |
10 | ## Recomendações
11 |
12 | - Para melhor diferenciar vários tipos de dados e informações,
13 | quando em mapas e tabelas, recomendamos a utilização de múltiplas cores.
14 |
15 | - Para melhor comunicar o propósito principal da interface,
16 | recomendamos a utilização da cor primária apenas uma vez por
17 | página, ou o mínimo necessário.
18 |
19 | - Para facilitar a construção de modelos mentais de uso da
20 | interface, recomendamos a utilização de cores de maneira
21 | consistente para a representação de status, mensagens de
22 | feedback e convenções
23 |
24 | Ex.: links azuis, mensagens de validação vermelhas, mensagens de sucesso azuis ou verdes.
25 |
26 | ## Observações:
27 | - Recomendamos o uso do token de gradiente como background das aplicações. Para utilizá-lo, atribua o token à propriedade background.
28 |
29 |
30 |
31 | ## Paleta de cores
32 |
33 |
34 |
35 |
36 |
37 |
40 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/BottomSheet.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`BottomSheet > renders correctly 1`] = `
4 | "
5 |
6 |
7 |
8 |
11 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
"
24 | `;
25 |
--------------------------------------------------------------------------------
/src/tests/MobileNavigation.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import MobileNavigation from '../components/MobileNavigation.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | const mockedData = [
6 | {
7 | label: 'Início',
8 | icon: 'home-outline',
9 | route: {
10 | path: '/home',
11 | name: 'home'
12 | },
13 | },
14 | {
15 | label: 'Vigilância Sanitária',
16 | icon: 'shield-outline',
17 | route: {
18 | path: '/visa',
19 | name: 'visa'
20 | }
21 | },
22 | {
23 | label: 'Central de marcação',
24 | icon: 'calendar-outline',
25 | route: {
26 | path: '/regulation',
27 | name: 'regulation'
28 | },
29 | },
30 | ];
31 |
32 | describe('MobileNavigation', () => {
33 | test('renders correctly', async () => {
34 | const wrapper = mount(MobileNavigation, {
35 | global: {
36 | stubs: {
37 | 'cds-icon': true,
38 | 'cds-avatar': true,
39 | 'router-link': true,
40 | },
41 | },
42 | props: {
43 | items: mockedData,
44 | activeItem: mockedData[1],
45 | user: {
46 | name: 'Joana Mendes',
47 | role: 'Administradora',
48 | }
49 | },
50 | });
51 |
52 | expect(wrapper.html()).toMatchSnapshot();
53 | });
54 | });
55 |
--------------------------------------------------------------------------------
/docs/components/forms/password-input.md:
--------------------------------------------------------------------------------
1 | # PasswordInput
2 |
3 | PasswordInputs permitem que os usuários insiram caracteres sensíveis na interface.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - Necessitar de um campo de texto para inserir informações sensíveis, como uma senha.
10 |
11 |
12 |
13 | ## Quando não usar:
14 | - O dado a ser utilizado no componente for um dado comum (Exemplo: nome ou idade).
15 |
16 | ---
17 |
18 | ## Uso
19 |
20 | ```js
21 |
24 | ```
25 |
26 | ---
27 |
28 | ## Preview
29 |
30 |
35 |
36 | ---
37 |
38 | ## Props
39 |
40 |
44 |
45 |
46 | ## Eventos
47 |
48 |
52 |
53 |
54 | ## Slots
55 |
56 |
60 |
61 | ---
62 |
63 |
73 |
--------------------------------------------------------------------------------
/docs/utils/cds-floatify.md:
--------------------------------------------------------------------------------
1 | # v-cds-floatify
2 |
3 | Os v-cds-floatify é uma diretiva do Cuida que permite que os elementos que a utilizam se tornem flutuantes.
4 |
5 |
6 |
7 | #### Argumentos
8 |
9 | **(String):**
10 | - Indica o posicionamento do componente em referência ao elemento alvo. É passado como argumento da diretiva, no formato `v-cds-floatify:[argument]`
11 | - Obrigatória: *Não*
12 | - Valores válidos: 'top', 'top-start', 'top-end, 'bottom', 'bottom-start, 'bottom-end, 'left', 'left-start, 'left-end, 'right', 'right-start, 'right-end;
13 |
14 | **(String):**
15 | - O id do elemento que o ContrastChecker vai usar como referência para se posicionar. É passado como valor pra diretiva, no formato `v-cds-floatify="argument"`
16 | - Obrigatória: *Sim*
17 | - Valores válidos: qualquer string que indica o id de um elemento do DOM;
18 |
19 |
20 |
21 | #### Retorno
22 |
23 | Nenhum
24 |
25 |
26 |
27 | #### Obs:
28 | - Utiliza o [popper.js](https://popper.js.org/docs/v2/) como dependência. A leitura da documentação do popper pode ajudar no uso dessa diretiva.
29 |
30 |
31 |
32 | #### Exemplo
33 |
34 | ```html
35 |
36 |
39 | ...
40 |
41 |
42 | ```
--------------------------------------------------------------------------------
/src/tests/SideBar.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import SideBar from '../components/SideBar.vue';
3 | import { shallowMount } from '@vue/test-utils';
4 |
5 | const mockedData = [
6 | {
7 | label: 'Dashboard',
8 | icon: 'dashboard-outline',
9 | route: {
10 | path: '/dashboard',
11 | name: 'dashboard'
12 | },
13 | },
14 | {
15 | label: 'Links',
16 | icon: 'link-outline',
17 | items: [
18 | {
19 | label: 'Painel (Tv)',
20 | path: '/tv-link',
21 | name: 'painel-tv'
22 | },
23 | {
24 | label: 'Totem',
25 | path: '/totem-link',
26 | name: 'totem'
27 | },
28 | ]
29 | },
30 | {
31 | label: 'Relatórios',
32 | icon: 'printer-outline',
33 | route: {
34 | path: '/reports',
35 | name: 'pagina2'
36 | },
37 | },
38 | ];
39 |
40 | describe('SideBar', () => {
41 | test('renders correctly', async () => {
42 | const wrapper = shallowMount(SideBar, {
43 | global: {
44 | stubs: {
45 | 'router-link': true,
46 | },
47 | },
48 | props: {
49 | items: mockedData,
50 | activeItem: mockedData[4],
51 | userName: 'Joana Mendes',
52 | userRole: 'Administradora',
53 | },
54 | });
55 |
56 | expect(wrapper.html()).toMatchSnapshot();
57 | });
58 | });
59 |
--------------------------------------------------------------------------------
/src/docs-components/CopyToken.vue:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/tests/HasSameItems.spec.ts:
--------------------------------------------------------------------------------
1 | import hasSameItems from '../utils/methods/hasSameItems';
2 | import { describe, it, expect } from 'vitest';
3 |
4 | describe('hasSameItems', () => {
5 | it('should return true when arrays have same items regardless of order', () => {
6 | const arr1: string[] = ['a', 'b', 'c'];
7 | const arr2: string[] = ['c', 'a', 'b'];
8 | expect(hasSameItems(arr1, arr2)).toBe(true);
9 | });
10 |
11 | it('should return false when arrays have different items', () => {
12 | const arr1: string[] = ['a', 'b', 'c'];
13 | const arr2: string[] = ['a', 'b', 'd'];
14 | expect(hasSameItems(arr1, arr2)).toBe(false);
15 | });
16 |
17 | it('should return false when arrays have different lengths', () => {
18 | const arr1: string[] = ['a', 'b', 'c'];
19 | const arr2: string[] = ['a', 'b'];
20 | expect(hasSameItems(arr1, arr2)).toBe(false);
21 | });
22 |
23 | it('should handle arrays with duplicate values', () => {
24 | const arr1: string[] = ['a', 'b', 'b', 'c'];
25 | const arr2: string[] = ['b', 'a', 'c', 'b'];
26 | expect(hasSameItems(arr1, arr2)).toBe(true);
27 | });
28 |
29 | it('should return true for empty arrays', () => {
30 | const arr1: string[] = [];
31 | const arr2: string[] = [];
32 | expect(hasSameItems(arr1, arr2)).toBe(true);
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/TextInput.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`TextInput > renders correctly 1`] = `
4 | ""
23 | `;
24 |
--------------------------------------------------------------------------------
/docs/components/notificação/alert-card.md:
--------------------------------------------------------------------------------
1 | # AlertCard
2 |
3 | AlertCards são componentes utilizados para transmitir mensagens contextuais importantes e apresentar possíveis ações a serem tomadas em cima delas.
4 |
5 | ---
6 |
7 | ### Quando usar
8 |
9 | - For necessário mostrar informações contextuais extensas.
10 | - For necessário mostrar informações contextuais que requerem ações do usuário sobre elas.
11 |
12 | ### Quando não usar
13 |
14 | - For necessário mostrar informações de maneira discreta ou que pode ser ocultada. Para esse caso, recomendamos o uso de toasts.
15 | - For necessário mostrar informações contextuais curtas.
16 |
17 | ---
18 |
19 | ## Uso
20 |
21 | ```js
22 |
28 | ```
29 |
30 | ---
31 |
32 | ## Preview
33 |
34 |
38 |
39 | ---
40 |
41 | ## Props
42 |
43 |
47 |
48 |
49 | ## Slots
50 |
51 |
55 |
56 |
62 |
--------------------------------------------------------------------------------
/docs/components/forms/radio.md:
--------------------------------------------------------------------------------
1 | # Radio
2 |
3 | O Radio permite que os usuários selecionem uma opção de um conjunto.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - As opções que o componente busca prover são mutuamente exclusivas.
10 |
11 |
12 |
13 | ## Quando não usar:
14 | - Duas ou mais opções puderem ser selecionadas ao mesmo tempo.
15 | - Houver 4 ou mais opções. Você pode usar o componente `Dropdown` nesses casos.
16 |
17 | ---
18 |
19 | ## Uso
20 |
21 | ```js
22 |
27 | ```
28 |
29 | ---
30 |
31 | ## Preview
32 |
33 |
38 |
39 | ---
40 |
41 | ## Props
42 |
43 |
47 |
48 |
49 | ## Eventos
50 |
51 |
55 |
56 |
57 | ## Slots
58 |
59 |
63 |
64 | ---
65 |
66 |
80 |
--------------------------------------------------------------------------------
/docs/components/display/tooltip.md:
--------------------------------------------------------------------------------
1 | # Tooltip
2 |
3 | Tooltip são labels flutuantes não interativas usados para explicar um elemento ou recurso da interface. Podem ser acionados com hover.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - O texto a ser exibido como label for conciso, com no máximo 4 palavras.
10 | - Para exibir informações suplementares sobre uma feature ou elemento da interface.
11 |
12 |
13 |
14 |
15 | ## Quando não usar:
16 | - Para comunicar erros e status do sistema.
17 | - Para mostrar informações críticas para a compreensão de uma feature ou elemento da interface.
18 |
19 | ---
20 |
21 | ## Uso
22 |
23 | ```js
24 |
27 | Tooltip trigger
28 |
29 | ```
30 |
31 | ---
32 |
33 | ## Preview
34 |
35 |
39 | Tooltip trigger
40 |
41 |
42 | ---
43 |
44 | ## Props
45 |
46 |
50 |
51 |
52 | ## Slots
53 |
54 |
58 |
59 | ---
60 |
61 |
69 |
--------------------------------------------------------------------------------
/src/tests/Wizard.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import Wizard from '../components/Wizard.vue';
3 | import { mount } from '@vue/test-utils';
4 |
5 | const mockedSteps = [
6 | {
7 | title: 'Dummy title 1',
8 | subtitle: 'Dummy subtitle 1',
9 | completed: true,
10 | inProcessing: false,
11 | error: false,
12 | },
13 | {
14 | title: 'Dummy title 2',
15 | subtitle: 'Dummy subtitle 2',
16 | completed: false,
17 | inProcessing: false,
18 | error: true,
19 | },
20 | {
21 | title: 'Dummy title 3',
22 | subtitle: 'Dummy subtitle 3',
23 | completed: false,
24 | inProcessing: true,
25 | error: false,
26 | },
27 | ];
28 |
29 | describe('Wizard', () => {
30 | test('renders correctly', async () => {
31 | const wrapper = mount(Wizard, {
32 | props: {
33 | steps: mockedSteps,
34 | },
35 | slots: {
36 | 'step-1-header': 'Dummy title without subtitle',
37 | 'step-1': 'Dummy content 1
',
38 | },
39 | });
40 |
41 | expect(wrapper.html()).toMatchSnapshot();
42 | });
43 |
44 | test('it accepts valid steps length', () => {
45 | const validator = Wizard.props.steps.validator;
46 | const invalidSteps = [...mockedSteps, {}];
47 | expect(validator(mockedSteps)).toBe(true);
48 | expect(validator(invalidSteps)).toBe(false);
49 | });
50 | });
51 |
--------------------------------------------------------------------------------
/docs/components/display/progress-circular.md:
--------------------------------------------------------------------------------
1 | # ProgressCircular
2 |
3 | ProgressCirculars são componentes que indicam o status/progresso de uma operação em andamento, em formato circular.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - For necessário transmitir a ideia de progresso ou percentual de uma operação em andamento.
10 | - For necessário transmitir a ideia de status de uma operação em andamento e que fração dela já foi concluída.
11 | - For necessário chamar a atenção do usuário para uma informação específica de maneira gráfica.
12 |
13 |
14 |
15 | ## Quanddo não usar:
16 | - For necessário representar fração de um processo com muitas etapas.
17 |
18 | ---
19 |
20 | ## Uso
21 |
22 | ```js
23 |
29 | ```
30 |
31 | ---
32 |
33 | ## Preview
34 |
35 |
39 |
40 | ---
41 |
42 | ## Props
43 |
44 |
48 |
49 |
50 |
59 |
--------------------------------------------------------------------------------
/docs/components/display/dropdown.md:
--------------------------------------------------------------------------------
1 | # Dropdown
2 |
3 | Dropdown são componentes utilizados para ativar popovers contendo filtros para listas e views.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - Para utilizar com filtros.
10 | - Houver popovers contendo opções de filtragem.
11 |
12 |
13 |
14 |
15 | ## Quando não usar:
16 | - Em substituição à um Multiselect ou Select.
17 |
18 | ---
19 |
20 | ## Uso
21 |
22 | ```js
23 |
28 | ```
29 |
30 | ---
31 |
32 | ## Preview
33 |
34 |
39 | Slot do dropdown do Dropdown
40 |
41 |
42 | ---
43 |
44 | ## Props
45 |
46 |
50 |
51 |
52 | ## Eventos
53 |
54 |
58 |
59 |
60 | ## Slots
61 |
62 |
66 |
67 |
80 |
--------------------------------------------------------------------------------
/src/components/Clickable.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
15 |
16 |
17 |
18 |
19 |
20 |
48 |
49 |
--------------------------------------------------------------------------------
/docs/foundation/tipografia.md:
--------------------------------------------------------------------------------
1 | # Tipografia
2 |
3 | A Tipografia padrão do Cuida é a Satoshi. Utilizamos a Satoshi variável com recursos OpenType.
4 |
5 |
6 |
7 |
8 | ## Recomendações
9 |
10 | - Para facilitar a leitura e reduzir o contraste, nunca use #000000 em fundos brancos e #FFFFFF
11 | em backgrounds escuros. Utilize as cores neutras da paleta do Cuida.
12 |
13 | - Para facilitar o processo de escaneamento da interface, recomendamos evitar a utilização de títulos, labels,
14 | botões e demais elementos da interface em caixa alta, sendo recomendado esse recurso apenas para criar diferenças
15 | na hierarquia tipográfica.
16 |
17 | - Para evitar problemas de legibilidade, não recomendamos a utilização de textos itálicos.
18 |
19 | - Para evitar problemas de legibilidade e erros de interpretação da interface, recomendamos
20 | a utilização de textos sublinhados apenas quando necessário, como recursos para realçar links.
21 |
22 | - Para facilitar o escaneamento e trabalhar a hierarquia de conteúdo,
23 | recomendamos a utilização pontual de textos em negrito.
24 |
25 |
26 |
27 | ## Tokens
28 | Os tokens de tipografia são variáveis scss cujas características estão descritos abaixo.
29 |
30 |
31 |
32 |
33 |
36 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/NumberInput.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`CdsNumberInput > renders correctly 1`] = `
4 | ""
25 | `;
26 |
--------------------------------------------------------------------------------
/docs/components/navegação/pagination.md:
--------------------------------------------------------------------------------
1 | # Pagination
2 |
3 | Pagination são indicadores de status utilizados para tornar evidentes metadados importates.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - For necessário mostrar status associados com a lógica de negócio ou ações do usuário.
10 | - O conteúdo a ser mostrado for *readonly*.
11 | - For preciso categorizar algo.
12 |
13 |
14 |
15 |
16 | ## Quando não usar:
17 | - O conteúdo que a Pagination representa puder ser setado ou removido pelo usuário.
18 | - O click no componente precisar executar uma ação ou funcionalidade.
19 |
20 | ---
21 |
22 | ## Uso
23 |
24 | ```js
25 |
31 | ```
32 |
33 | ---
34 |
35 | ## Preview
36 |
37 |
42 |
43 | ---
44 |
45 | ## Props
46 |
47 |
51 |
52 |
53 | ## Eventos
54 |
55 |
59 |
60 |
61 |
71 |
--------------------------------------------------------------------------------
/docs/components/display/progress-bar.md:
--------------------------------------------------------------------------------
1 | # ProgressBar
2 |
3 | ProgressBars são componentes utilizados para indicar o status e progresso de algo aos usuários.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - For necessário transmitir a ideia do progresso de algo.
10 | - For necessário transmitir a ideia do status de algo.
11 | - Se deseja chamar a atenção do usuário para uma informação específica de maneira gráfica.
12 |
13 |
14 |
15 | ## Quando não usar:
16 | - For necessário criar loaders.
17 | - For necessária muita precisão ao mostrar os números ou progresso.
18 | - For necessário criar steppers.
19 |
20 | ---
21 |
22 | ## Uso
23 |
24 | ```js
25 |
29 | ```
30 |
31 | ---
32 |
33 | ## Preview
34 |
35 |
39 |
40 | ---
41 |
42 | ## Props
43 |
44 |
48 |
49 |
50 | ## Slots
51 |
52 |
56 |
57 | ---
58 |
71 |
--------------------------------------------------------------------------------
/docs/components/forms/text-area.md:
--------------------------------------------------------------------------------
1 | # TextArea
2 |
3 | TextAreas permitem que os usuários insiram um texto longo em uma interface.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - Necessitar de um campo de texto para inserir informações grandes. Exemplo: Descrição de produto ou mensagens.
10 |
11 |
12 |
13 | ## Quando não usar:
14 | - For necessário informar apenas um dado específico ao campo de texto.
15 |
16 | ---
17 |
18 | ## Uso
19 |
20 | ```js
21 |
24 | ```
25 |
26 | ---
27 |
28 | ## Preview
29 |
30 |
35 |
36 | ---
37 |
38 | ## Props
39 |
40 |
44 |
45 |
46 |
73 |
--------------------------------------------------------------------------------
/docs/components/display/badge.md:
--------------------------------------------------------------------------------
1 | # Badge
2 |
3 | Badge são indicadores de status utilizados para tornar evidentes metadados importantes.
4 |
5 | ---
6 |
7 | ### Quando usar
8 |
9 | - For necessário mostrar status associados com a lógica de negócio ou ações do usuário.
10 | - O conteúdo a ser mostrado for *readonly*.
11 | - For preciso categorizar algo.
12 |
13 | ### Quando não usar
14 |
15 | - O conteúdo que a badge representa puder ser setado ou removido pelo usuário.
16 | - O click no componente precisar executar uma ação ou funcionalidade.
17 |
18 | ---
19 |
20 | ## Uso
21 |
22 | ```js
23 |
27 | Badge
28 |
29 | ```
30 |
31 | ---
32 |
33 | ## Preview
34 |
35 |
40 | Badge
41 |
42 |
43 | ---
44 |
45 | ## Props
46 |
47 |
51 |
52 |
53 |
54 | ## Eventos
55 |
56 |
60 |
61 |
62 | ## Slots
63 |
64 |
68 |
69 | ---
70 |
71 |
81 |
--------------------------------------------------------------------------------
/docs/components/display/avatar.md:
--------------------------------------------------------------------------------
1 | # Avatar
2 |
3 | Avatares são componentes utilizados para exibir representações visuais de usuários, como imagens ou nome.
4 |
5 | ---
6 |
7 | ### Quando usar
8 |
9 | - Recomenda-se o uso de avatares quando o usuário ou lista de usuários possuir imagens ou nomes definidos.
10 | - É geralmente usado em conjunto com Headers, NavBars, Tabelas, Cards e Listas.
11 |
12 | ---
13 |
14 | ## Uso
15 |
16 | ```js
17 |
20 | ```
21 |
22 | ---
23 |
24 | ## Preview
25 |
26 |
27 |
30 |
31 | Conteúdo do dropdown
32 |
33 |
34 |
35 |
36 |
37 |
38 | ---
39 |
40 | ## Props
41 |
42 |
46 |
47 |
48 | ## Slots
49 |
50 |
54 |
55 | ---
56 |
57 |
62 |
63 |
71 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/CheckboxGroup.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`CheckboxGroup > renders correctly 1`] = `
4 | "Checkbox Group Test
5 |
6 |
7 |
12 |
17 |
18 |
"
19 | `;
20 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Toast.spec.js.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Toast > renders correctly 1`] = `
4 | "
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | Título do toast Descrição do toast, exibida abaixo do título
15 |
16 |
17 |
18 |
19 |
20 |
21 |
"
22 | `;
23 |
--------------------------------------------------------------------------------
/docs/components/display/timeline-item.md:
--------------------------------------------------------------------------------
1 | # TimelineItem
2 |
3 | TimelineItems são componentes auxiliares utilizados para montar Timelines.
4 |
5 | ---
6 |
7 |
8 | ## Quando não usar:
9 | - Fora de componentes `Timeline`.
10 |
11 | ---
12 |
13 | ## Uso
14 |
15 | ```js
16 |
21 |
22 | 24/01/20202
23 |
24 |
25 | Denis Ritchie
26 |
27 |
28 | Criador da linguagem de programação C
29 |
30 |
31 | ```
32 |
33 | ---
34 |
35 | ## Preview
36 |
37 |
41 |
42 | 24/01/20202
43 |
44 |
45 | Denis Ritchie
46 |
47 |
48 | Criador da linguagem de programação C
49 |
50 |
51 |
52 | ---
53 |
54 | ## Props
55 |
56 |
60 |
61 |
62 | ## Slots
63 |
64 |
68 |
69 | ---
70 |
80 |
--------------------------------------------------------------------------------
/docs/components/notificação/alert.md:
--------------------------------------------------------------------------------
1 | # Alert
2 |
3 | Alerts são componentes utilizados para prover feedbacks contextuais e notificações em resposta a ações do usuário ou atividades do sistema.
4 |
5 | ---
6 |
7 | ## Quando usar
8 |
9 | - For necessário mostrar informações contextuais.
10 | - Para feedbacks urgentes.
11 |
12 | ## Quando não usar
13 |
14 | - Não cubra outros elementos da interface com um Alert.
15 | - For necessário mostrar informações de modo não intrusivo. Para esse caso, recomendamos o uso de b-toasts.
16 | - For necessário mostrar informações contextuais extensas. Para esse caso, recomendamos o uso de AlertCard.
17 |
18 | ---
19 |
20 | ## Uso
21 |
22 | ```js
23 |
27 | ```
28 |
29 | ---
30 |
31 | ## Preview
32 |
33 |
38 |
39 | ---
40 |
41 | ## Props
42 |
43 |
47 |
48 |
49 | ## Eventos
50 |
51 |
55 |
56 |
57 | ## Slots
58 |
59 |
63 |
64 | ---
65 |
66 |
76 |
--------------------------------------------------------------------------------
/src/components/SkeletonText.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
33 |
34 |
--------------------------------------------------------------------------------
/docs/components/forms/flat-button.md:
--------------------------------------------------------------------------------
1 | # FlatButton
2 |
3 | FlatButtons são componentes semelhantes a links, mas que funcionam como botões.
4 |
5 | ---
6 |
7 | ### Quando usar
8 |
9 | - Componente usado quando a interface necessita de botões menos proeminentes, sem comprometer a hierarquia visual da tela.
10 |
11 | ### Quando não usar
12 |
13 | - For necessário dar a opção de executar uma ação como um detalhe pequeno na interface.
14 |
15 | ---
16 |
17 | ## Uso
18 |
19 | ```js
20 |
24 | ```
25 |
26 | ---
27 |
28 | ## Preview
29 |
30 |
35 |
36 | ---
37 |
38 | ## Props
39 |
40 |
44 |
45 |
46 | ## Eventos
47 |
48 |
52 |
53 |
54 | ## Slots
55 |
56 |
60 |
61 | ---
62 |
63 |
68 |
69 |
79 |
--------------------------------------------------------------------------------
/docs/foundation/iconografia.md:
--------------------------------------------------------------------------------
1 | # Iconografia
2 |
3 | A iconografia que utilizamos no Cuida simplifica a interação do usuário com o sistema, pois possibilita que elementos sejam mais
4 | facilmente identificados. Além disso, permite que os usuários compreendam com mais facilidade os componentes do layout,
5 | reduzindo a curva de aprendizado sobre a interface.
6 |
7 |
8 |
9 |
10 | ## Recomendações
11 |
12 | - Para melhor representar ícones do sistema, recomendamos que sejam utilizados ícones com tamanho entre 20 x 20 e 24 x 24 pixels.
13 |
14 | - Para melhor compreensão por parte do usuário, utilize ícones já comumente adotados para a função desejada.
15 | Por exemplo, um sino para notificações, uma engrenagem para configurações, etc.
16 |
17 | - Para tornar o conteúdo mais claro, utilize ícones em conjunto com texto, sempre que possível.
18 |
19 |
20 |
21 | ## Ícones
22 |
23 | O Cuida implementa um wrapper em forma de componente dos ícones do CuidaIcons . Qualquer manutenção ou melhoria
24 | deve ser feita no projeto respectivo e no design kit no Figma e, caso necessário, atualizada aqui.
25 |
26 | ```html
27 |
33 | ```
34 |
35 |
36 |
37 |
38 |
39 |
42 |
--------------------------------------------------------------------------------
/docs/components/forms/icon-button.md:
--------------------------------------------------------------------------------
1 | # IconButton
2 |
3 | IconButtons são componentes que permitem que o usuário execute uma ação com um toque.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - For necessário comunicar ao usuário que ele pode executar uma ação na interface,
10 | seja em diálogos, janelas modais, formulários, cards, etc.
11 |
12 |
13 |
14 |
15 | ## Quando não usar:
16 | - For necessário dar a opção de executar uma ação como um detalhe pequeno na interface.
17 | Nesse caso, recomendamos o uso de links.
18 |
19 |
20 |
21 | ---
22 |
23 | ## Uso
24 |
25 | ```js
26 |
30 | ```
31 |
32 | ---
33 |
34 | ## Preview
35 |
36 |
41 |
42 | ---
43 |
44 | ## Props
45 |
46 |
50 |
51 |
52 | ## Eventos
53 |
54 |
58 |
59 |
60 | ---
61 |
79 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Tile.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Tile > renders correctly 1`] = `
4 | "
5 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 |
23 |
24 |
Tile content
25 |
26 |
27 |
28 |
"
29 | `;
30 |
--------------------------------------------------------------------------------
/docs/components/display/chip.md:
--------------------------------------------------------------------------------
1 | # Chip
2 |
3 | Chips ajudam as pessoas a inserir informações, fazer seleções, filtrar conteúdo ou disparar ações.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - For necessário selecionar e/ou filtrar conteúdo
10 | - O conteúdo que a chip representa puder ser setado ou removido pelo usuário.
11 |
12 |
13 |
14 | ## Quando não usar:
15 | - O conteúdo a ser mostrado for *readonly* (nesse caso, é mais indicado utlizar o componente Badge).
16 |
17 | ---
18 |
19 | ## Uso
20 |
21 | ```js
22 |
27 | Chip
28 |
29 | ```
30 |
31 | ---
32 |
33 | ## Preview
34 |
35 |
40 | Chip
41 |
42 |
43 |
44 | ---
45 |
46 | ## Props
47 |
48 |
52 |
53 |
54 |
55 | ## Slots
56 |
57 |
61 |
62 | ---
63 |
64 |
69 |
70 |
82 |
--------------------------------------------------------------------------------
/src/assets/sass/tokens/_typography.scss:
--------------------------------------------------------------------------------
1 | @mixin heading-1 {
2 | font-size: 45px;
3 | font-weight: 700;
4 | letter-spacing: 0.15px;
5 | }
6 |
7 | @mixin heading-2 {
8 | font-size: 33px;
9 | font-weight: 700;
10 | letter-spacing: 0.1px;
11 | }
12 |
13 | @mixin heading-3 {
14 | font-size: 29px;
15 | font-weight: 650;
16 | letter-spacing: 0px;
17 | }
18 |
19 | @mixin subheading-1 {
20 | font-size: 25px;
21 | font-weight: 600;
22 | letter-spacing: 0.15px;
23 | }
24 |
25 | @mixin subheading-2 {
26 | font-size: 21px;
27 | font-weight: 600;
28 | letter-spacing: 0px;
29 | }
30 |
31 | @mixin subheading-3 {
32 | font-size: 17px;
33 | font-weight: 600;
34 | letter-spacing: 0px;
35 | }
36 |
37 | @mixin body-1 {
38 | font-size: 17px;
39 | font-weight: 430;
40 | letter-spacing: 0px;
41 | }
42 |
43 | @mixin body-2 {
44 | font-size: 15px;
45 | font-weight: 430;
46 | letter-spacing: 0px;
47 | }
48 |
49 | @mixin button-1 {
50 | font-size: 16px;
51 | font-weight: 750;
52 | letter-spacing: 0.2px;
53 | }
54 |
55 | @mixin button-2 {
56 | font-size: 14px;
57 | font-weight: 700;
58 | letter-spacing: 0.15px;
59 | }
60 |
61 | @mixin button-3 {
62 | font-size: 12px;
63 | font-weight: 700;
64 | letter-spacing: 0.15px;
65 | }
66 |
67 | @mixin caption {
68 | font-size: 13.5px;
69 | font-weight: 470;
70 | letter-spacing: 0.1px;
71 | }
72 |
73 | @mixin overline {
74 | font-size: 11.5px;
75 | font-weight: 650;
76 | letter-spacing: 0.15px;
77 | }
78 |
--------------------------------------------------------------------------------
/src/assets/sass/legacy-tokens/typography.scss:
--------------------------------------------------------------------------------
1 | @mixin heading-1 {
2 | font-size: 45px;
3 | font-weight: 700;
4 | letter-spacing: 0.15px;
5 | }
6 |
7 | @mixin heading-2 {
8 | font-size: 33px;
9 | font-weight: 700;
10 | letter-spacing: 0.1px;
11 | }
12 |
13 | @mixin heading-3 {
14 | font-size: 29px;
15 | font-weight: 650;
16 | letter-spacing: 0px;
17 | }
18 |
19 | @mixin subheading-1 {
20 | font-size: 25px;
21 | font-weight: 600;
22 | letter-spacing: 0.15px;
23 | }
24 |
25 | @mixin subheading-2 {
26 | font-size: 21px;
27 | font-weight: 600;
28 | letter-spacing: 0px;
29 | }
30 |
31 | @mixin subheading-3 {
32 | font-size: 17px;
33 | font-weight: 600;
34 | letter-spacing: 0px;
35 | }
36 |
37 | @mixin body-1 {
38 | font-size: 17px;
39 | font-weight: 430;
40 | letter-spacing: 0px;
41 | }
42 |
43 | @mixin body-2 {
44 | font-size: 15px;
45 | font-weight: 430;
46 | letter-spacing: 0px;
47 | }
48 |
49 | @mixin button-1 {
50 | font-size: 16px;
51 | font-weight: 750;
52 | letter-spacing: 0.2px;
53 | }
54 |
55 | @mixin button-2 {
56 | font-size: 14px;
57 | font-weight: 700;
58 | letter-spacing: 0.15px;
59 | }
60 |
61 | @mixin button-3 {
62 | font-size: 12px;
63 | font-weight: 700;
64 | letter-spacing: 0.15px;
65 | }
66 |
67 | @mixin caption {
68 | font-size: 13.5px;
69 | font-weight: 470;
70 | letter-spacing: 0.1px;
71 | }
72 |
73 | @mixin overline {
74 | font-size: 11.5px;
75 | font-weight: 650;
76 | letter-spacing: 0.15px;
77 | }
78 |
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/List.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`List snapshot test > renders correctly 1`] = `
4 | "
5 |
6 |
7 |
List Title 1
8 |
Some quick example text to build on the List title and make up the bulk of the List's content.
9 |
10 |
15 |
16 |
17 |
18 |
19 |
List Title 2
20 |
Some quick example text to build on the List title and make up the bulk of the List's content.
21 |
22 |
27 |
"
28 | `;
29 |
--------------------------------------------------------------------------------
/docs/utils/palete-resolver.md:
--------------------------------------------------------------------------------
1 | # PaleteResolver()
2 |
3 | Mixin sass utilizado para criar classes com as cores da paleta do Design Dystem.
4 |
5 |
6 |
7 |
8 | O PaleteResolver, de modo semelhante ao VariantResolver implementa um loop por entre os tokens de cor do Cuida,
9 | mas enquanto o VariantResolver percorre a paleta retornando shades específicos, o PaleteResolver percorre as cores
10 | da paleta retornando todos os tokens shades disponíveis, disponibilizando uma única variável chamada `$color`.
11 |
12 |
13 |
14 | #### Exemplo
15 |
16 | ```scss
17 | .color-picker {
18 | &__swatch {
19 | @include paleteResolver using ($color) {
20 | background-color: $color;
21 | transition: $interaction;
22 | }
23 | }
24 | }
25 | ```
26 |
27 |
28 |
29 | O código acima sem o seria o mesmo mesmo que:
30 |
31 | ```scss
32 | .color-picker {
33 | &__swatch {
34 | &--bn-400 {
35 | background-color: $bn-400;
36 | transition: $interaction;
37 | }
38 |
39 | ...
40 |
41 | &--bn-500 {
42 | background-color: $bn-500;
43 | transition: $interaction;
44 | }
45 |
46 | ...
47 |
48 | &--bn-600 {
49 | background-color: $bn-600;
50 | transition: $interaction;
51 | }
52 |
53 | ...
54 |
55 | &--in-50 {
56 | background-color: $in-50;
57 | transition: $interaction;
58 | }
59 |
60 | ...
61 |
62 | &--in-100 {
63 | background-color: $in-100;
64 | transition: $interaction;
65 | }
66 |
67 | ...
68 | }
69 | }
70 | ```
--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js';
2 | import vue from 'eslint-plugin-vue';
3 | import vueParser from 'vue-eslint-parser';
4 | import tsParser from '@typescript-eslint/parser';
5 | import globals from 'globals';
6 |
7 | export default [
8 | js.configs.recommended,
9 | ...vue.configs['flat/recommended'],
10 | ...vue.configs['flat/strongly-recommended'],
11 | {
12 | files: ['**/*.vue'],
13 | languageOptions: {
14 | parser: vueParser,
15 | parserOptions: {
16 | parser: tsParser,
17 | ecmaVersion: 'latest',
18 | sourceType: 'module',
19 | },
20 | globals: {
21 | ...globals.node,
22 | ...globals.browser,
23 | },
24 | },
25 | },
26 | {
27 | files: ['**/*.{js,mjs,ts}'],
28 | languageOptions: {
29 | parser: tsParser,
30 | ecmaVersion: 'latest',
31 | sourceType: 'module',
32 | globals: {
33 | ...globals.node,
34 | },
35 | },
36 | },
37 | {
38 | rules: {
39 | 'vue/html-indent': [
40 | 'error',
41 | 'tab',
42 | {
43 | attribute: 1,
44 | closeBracket: 0,
45 | alignAttributesVertically: true,
46 | ignores: [],
47 | },
48 | ],
49 | 'vue/require-explicit-emits': 'off',
50 | 'no-tabs': 'off',
51 | indent: [
52 | 'error',
53 | 'tab',
54 | {
55 | SwitchCase: 1,
56 | },
57 | ],
58 | quotes: [
59 | 'error',
60 | 'single',
61 | {
62 | allowTemplateLiterals: true,
63 | },
64 | ],
65 | 'no-extra-semi': 'off',
66 | },
67 | },
68 | ];
69 |
--------------------------------------------------------------------------------
/src/tests/CheckboxGroup.spec.ts:
--------------------------------------------------------------------------------
1 | import { describe, test, expect } from 'vitest';
2 | import CheckboxGroup from '../components/CheckboxGroup.vue';
3 | import CheckboxItem from '../components/Checkbox.vue';
4 | import { mount } from '@vue/test-utils';
5 |
6 | describe('CheckboxGroup', () => {
7 | test('renders correctly', async () => {
8 | const wrapper = mount(CheckboxGroup, {
9 | props: {
10 | modelValue: ['test-1'],
11 | label: 'Checkbox Group Test',
12 | options: [
13 | {
14 | value: 'test-1',
15 | label: 'Teste 1',
16 | },
17 | {
18 | value: 'test-2',
19 | label: 'Teste 2',
20 | },
21 | ],
22 | },
23 | });
24 |
25 | expect(wrapper.html()).toMatchSnapshot();
26 | });
27 |
28 | test('checkbox options are rendered correctly', async () => {
29 | expect.assertions(2);
30 |
31 | const wrapper = await mount(CheckboxGroup, {
32 | props: {
33 | modelValue: ['test-1'],
34 | label: 'Checkbox Group Test',
35 | options: [
36 | {
37 | value: 'test-1',
38 | label: 'Teste 1',
39 | },
40 | {
41 | value: 'test-2',
42 | label: 'Teste 2',
43 | },
44 | ],
45 | },
46 | });
47 |
48 | const checkboxArray = wrapper.findAllComponents(CheckboxItem);
49 | const checkedCheckbox = checkboxArray.find((checkbox) => checkbox.vm.label === 'Teste 1');
50 |
51 | expect(checkboxArray.length).toBe(2);
52 | expect(checkedCheckbox?.vm.modelValue).toBeTruthy();
53 | });
54 | });
55 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/Card.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`Card snapshot test > renders correctly 1`] = `
4 | "
5 |
10 |
11 |
12 |
13 |
14 |
15 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
Some quick example text to build on the card title and make up the bulk of the card's content.
28 |
29 |
30 |
31 |
32 |
33 |
34 |
"
35 | `;
36 |
--------------------------------------------------------------------------------
/public/img/smartphone-rotation.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/tests/Tile.spec.ts:
--------------------------------------------------------------------------------
1 | // @vitest-environment jsdom
2 | import { describe, test, expect } from 'vitest';
3 | import Tile from '../components/Tile.vue';
4 | import Icon from '../components/Icon.vue';
5 | import Image from '../components/Image.vue';
6 | import Skeleton from '../components/Skeleton.vue';
7 | import { mount, flushPromises } from '@vue/test-utils';
8 |
9 | describe('Tile', () => {
10 | test('renders correctly', async () =>{
11 | const wrapper = mount(Tile, {
12 | props: {
13 | title: 'Tile content',
14 | icon: 'trash-outline',
15 | }
16 | });
17 |
18 | expect(wrapper.html()).toMatchSnapshot();
19 | expect(wrapper.findComponent(Icon).exists()).toBeTruthy();
20 | expect(wrapper.findComponent(Image).exists()).toBeFalsy();
21 |
22 | wrapper.setProps({
23 | icon: 'https://via.placeholder.com/150',
24 | });
25 |
26 | await flushPromises();
27 |
28 | expect(wrapper.findComponent(Icon).exists()).toBeFalsy();
29 | expect(wrapper.findComponent(Image).exists()).toBeTruthy();
30 | });
31 |
32 | test('skeleton loads correctly', async () => {
33 | const wrapper = mount(Tile, {
34 | props: {
35 | loading: true,
36 | }
37 | });
38 |
39 | expect(wrapper.findComponent(Skeleton).exists()).toBeTruthy();
40 |
41 | wrapper.setProps({
42 | title: 'Tile content',
43 | icon: 'trash-outline',
44 | loading: false,
45 | });
46 |
47 | await flushPromises();
48 |
49 | expect(wrapper.findComponent(Skeleton).exists()).toBeFalsy();
50 | });
51 | });
52 |
--------------------------------------------------------------------------------
/docs/components/forms/switch.md:
--------------------------------------------------------------------------------
1 | # Switch
2 |
3 | Switches são componentes utilizados para ativar ou desativar configurações ou opções específicas.
4 |
5 | ---
6 |
7 | ### Quando usar
8 |
9 | - A configuração controlada pelo Switch deve aplicar mudanças automaticamente.
10 | - Ao usar labels. Quando usados em conjunto, devem descrever dois estados, dependentes do estado do Switch.
11 |
12 | ### Quando não usar
13 |
14 | - Em formulários que possuem botão de submit.
15 | - Utilizar Switches para controlar ações que dependam de requisições sem indicar o tempo de espera ao usuário.
16 |
17 | ---
18 |
19 | ## Uso
20 |
21 | ```js
22 |
25 | ```
26 |
27 | ---
28 |
29 | ## Preview
30 |
31 |
36 |
37 | ---
38 |
39 | ## Props
40 |
41 |
45 |
46 |
47 | ## Eventos
48 |
49 |
53 |
54 |
55 | ## Slots
56 |
57 |
61 |
62 | ---
63 |
64 | ## Figma
65 |
66 |
69 |
70 |
79 |
--------------------------------------------------------------------------------
/src/components/ToastContainer.vue:
--------------------------------------------------------------------------------
1 |
2 |
6 |
10 |
21 |
22 |
23 |
24 |
25 |
33 |
34 |
66 |
--------------------------------------------------------------------------------
/src/tests/__snapshots__/PanelCard.spec.ts.snap:
--------------------------------------------------------------------------------
1 | // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2 |
3 | exports[`PanelCard > renders correctly 1`] = `
4 | "
5 |
10 |
11 |
12 |
13 |
14 |
15 |
21 |
25 |
26 |
27 |
28 |
29 |
30 |
"
31 | `;
32 |
--------------------------------------------------------------------------------
/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite';
2 |
3 | import vue from '@vitejs/plugin-vue';
4 | import typescript from '@rollup/plugin-typescript';
5 |
6 | import { fileURLToPath, URL } from "url";
7 | import path from 'node:path';
8 |
9 | // https://vitejs.dev/config/
10 | export default defineConfig({
11 | css: {
12 | modules: {
13 | scopeBehaviour: 'global',
14 | },
15 | },
16 | optimizeDeps: {
17 | esbuildOptions: {
18 | target: ['es2020', 'safari14', 'chrome87', 'edge88', 'firefox78'],
19 | },
20 | },
21 | build: {
22 | target: ['es2020', 'safari14', 'chrome87', 'edge88', 'firefox78'],
23 | lib: {
24 | entry: path.resolve(__dirname, './src/components/index.ts'),
25 | name: '@sysvale/cuida',
26 | // the proper extensions will be added
27 | fileName: (format) => `@sysvale/cuida.${format}.js`,
28 | },
29 | rollupOptions: {
30 | // make sure to externalize deps that shouldn't be bundled
31 | // into your library
32 | external: ['vue'],
33 | output: {
34 | // Provide global variables to use in the UMD build
35 | // for externalized deps
36 | globals: {
37 | vue: 'Vue'
38 | },
39 | },
40 | },
41 | },
42 | plugins: [
43 | {
44 | ...typescript({ tsconfig: './tsconfig.json' }),
45 | apply: 'build',
46 | declaration: true,
47 | declarationDir: 'types/',
48 | rootDir: '/'
49 | },
50 | vue(),
51 | ],
52 | resolve: {
53 | alias: {
54 | "@": fileURLToPath(new URL("./src", import.meta.url)),
55 | },
56 | },
57 | })
58 |
--------------------------------------------------------------------------------
/docs/components/tipografia/text.md:
--------------------------------------------------------------------------------
1 | # Text
2 |
3 | Text são indicadores de status utilizados para tornar evidentes metadados importantes.
4 |
5 | ---
6 |
7 | ### Quando usar
8 |
9 | - For necessário mostrar status associados com a lógica de negócio ou ações do usuário.
10 | - O conteúdo a ser mostrado for *readonly*.
11 | - For preciso categorizar algo.
12 |
13 | ### Quando não usar
14 |
15 | - O conteúdo que a text representa puder ser setado ou removido pelo usuário.
16 | - O click no componente precisar executar uma ação ou funcionalidade.
17 |
18 | ---
19 |
20 | ## Uso
21 |
22 | ```js
23 |
28 | O empenho em analisar o desenvolvimento contínuo de distintas formas de atuação obstaculiza a apreciação da importância do retorno esperado a longo prazo.
29 |
30 | ```
31 |
32 | ---
33 |
34 | ## Preview
35 |
36 |
40 | O empenho em analisar o desenvolvimento contínuo de distintas formas de atuação obstaculiza a apreciação da importância do retorno esperado a longo prazo.
41 |
42 |
43 | ---
44 |
45 | ## Props
46 |
47 |
51 |
52 |
53 |
54 | ## Slots
55 |
56 |
60 |
61 | ---
62 |
63 |
69 |
--------------------------------------------------------------------------------
/docs/components/charts/polar-area-chart.md:
--------------------------------------------------------------------------------
1 | # PolarAreaChart
2 |
3 | Um componente de gráfico reutilizável para exibir dados visualmente.
4 |
5 | ---
6 |
7 |
8 | ## Quando usar:
9 | - Exibir dados em formatos visuais;
10 | - Visualizar tendências ao longo de variáveis contínuas, como direções ou graus.
11 |
12 |
13 |
14 | ## Quando não usar:
15 | - Para informações simples que podem ser exibidas em um formato tabular ou em texto;
16 | - Quando os dados apresentarem ênfase na comparação númerica de quantidades;
17 | - Não recomendado para representar séries temporais ou dados discretos.
18 |
19 | ---
20 |
21 | ## Uso
22 |
23 | ```js
24 |
30 | ```
31 |
32 | ---
33 |
34 | ## Preview
35 |
36 |
40 |
41 | ---
42 |
43 | ## Props
44 |
45 |
49 |
50 |
51 | ---
52 |
53 |
74 |
--------------------------------------------------------------------------------
/src/components/Timeline.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
50 |
62 |
--------------------------------------------------------------------------------
/src/style.css:
--------------------------------------------------------------------------------
1 | :root {
2 | font-family: Satoshi, Inter, Avenir, Helvetica, Arial, sans-serif;
3 |
4 | color-scheme: light dark;
5 | color: rgba(255, 255, 255, 0.87);
6 | background-color: #242424;
7 |
8 | font-synthesis: none;
9 | text-rendering: optimizeLegibility;
10 | -webkit-font-smoothing: antialiased;
11 | -moz-osx-font-smoothing: grayscale;
12 | -webkit-text-size-adjust: 100%;
13 | }
14 |
15 | a {
16 | font-weight: 500;
17 | color: #646cff;
18 | text-decoration: inherit;
19 | }
20 | a:hover {
21 | color: #535bf2;
22 | }
23 |
24 | body {
25 | margin: 0;
26 | display: flex;
27 | place-items: center;
28 | min-width: 320px;
29 | min-height: 100vh;
30 | font-family: Satoshi, Inter, Avenir, Helvetica, Arial, sans-serif;
31 | }
32 |
33 | h1 {
34 | font-size: 3.2em;
35 | line-height: 1.1;
36 | }
37 |
38 | .card {
39 | padding: 2em;
40 | }
41 |
42 | #app {
43 | max-width: 1280px;
44 | margin: 0 auto;
45 | padding: 2rem;
46 | text-align: center;
47 | }
48 |
49 | @media (prefers-color-scheme: light) {
50 | :root {
51 | color: #213547;
52 | background-color: #ffffff;
53 | }
54 | a:hover {
55 | color: #747bff;
56 | }
57 | button {
58 | background-color: #f9f9f9;
59 | }
60 | }
61 |
62 | .d-flex {
63 | display: flex;
64 | }
65 |
66 | .docs-grid-cell {
67 | font-size: 18px;
68 | font-weight: 550;
69 | background-color: #E7EDF3;
70 | padding: 12px;
71 | border-radius: 12px;
72 | display: flex;
73 | align-items: center;
74 | justify-content: center;
75 | }
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: 'Deploy 🚀'
2 |
3 | on:
4 | push:
5 | branches: main
6 |
7 | workflow_dispatch:
8 |
9 | permissions:
10 | contents: read
11 | pages: write
12 | id-token: write
13 |
14 | concurrency:
15 | group: pages
16 | cancel-in-progress: false
17 |
18 | jobs:
19 | build:
20 | runs-on: ubuntu-latest
21 | steps:
22 | - name: Checkout
23 | uses: actions/checkout@v4
24 | with:
25 | fetch-depth: 0
26 | - name: Setup Node
27 | uses: actions/setup-node@v4
28 | with:
29 | node-version: 22
30 | cache: npm
31 | - name: Setup Pages
32 | uses: actions/configure-pages@v4
33 | - name: Install dependencies
34 | run: npm ci
35 | - name: Build JSDocs JSON
36 | run: npm run build
37 | env:
38 | NODE_OPTIONS: "--experimental-specifier-resolution=node"
39 | - name: Build with VitePress
40 | run: npm run docs:build
41 | env:
42 | NODE_OPTIONS: "--experimental-specifier-resolution=node"
43 | - name: Upload artifact
44 | uses: actions/upload-pages-artifact@v3
45 | with:
46 | path: docs/.vitepress/dist
47 |
48 | deploy:
49 | environment:
50 | name: github-pages
51 | url: ${{ steps.deployment.outputs.page_url }}
52 | needs: build
53 | runs-on: ubuntu-latest
54 | name: Deploy
55 | steps:
56 | - name: Deploy to GitHub Pages
57 | id: deployment
58 | uses: actions/deploy-pages@v4
59 |
--------------------------------------------------------------------------------