agroptima-design-system 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -25,3 +25,6 @@ jobs:
25
25
 
26
26
  - name: Lint
27
27
  run: npm run lint
28
+
29
+ - name: Types
30
+ run: npm run types
@@ -0,0 +1,27 @@
1
+ name: Run tests
2
+
3
+ on:
4
+ pull_request:
5
+ types:
6
+ - opened
7
+ - reopened
8
+ - synchronize
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ - name: Setup Node
18
+ uses: actions/setup-node@v3
19
+ with:
20
+ node-version: 18.x
21
+ cache: 'npm'
22
+
23
+ - name: Install dependencies
24
+ run: npm install
25
+
26
+ - name: Test
27
+ run: npm run test
package/app/.gitkeep ADDED
File without changes
package/jest.config.ts ADDED
@@ -0,0 +1,17 @@
1
+ import type { Config } from 'jest'
2
+ import nextJest from 'next/jest.js'
3
+
4
+ const createJestConfig = nextJest({
5
+ dir: './',
6
+ })
7
+
8
+ const config: Config = {
9
+ testEnvironment: 'jsdom',
10
+ clearMocks: true,
11
+ moduleNameMapper: {
12
+ '^.+\\.(svg)$': '<rootDir>/tests/svg.mock.js',
13
+ },
14
+ setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
15
+ }
16
+
17
+ export default createJestConfig(config)
package/jest.setup.ts ADDED
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agroptima-design-system",
3
- "version": "0.5.0",
3
+ "version": "0.6.1",
4
4
  "scripts": {
5
5
  "dev": "npm run storybook",
6
6
  "storybook": "storybook dev -p 6006 --ci",
@@ -8,7 +8,9 @@
8
8
  "build-storybook": "storybook build",
9
9
  "lint": "eslint",
10
10
  "lint:fix": "eslint src --fix",
11
- "chromatic": "npx chromatic --exit-zero-on-changes"
11
+ "types": "tsc --noEmit",
12
+ "chromatic": "npx chromatic --exit-zero-on-changes",
13
+ "test": "jest"
12
14
  },
13
15
  "dependencies": {
14
16
  "@storybook/addon-designs": "^7.0.5",
@@ -28,6 +30,10 @@
28
30
  "@storybook/react": "^7.5.0",
29
31
  "@storybook/testing-library": "^0.2.2",
30
32
  "@svgr/webpack": "^8.1.0",
33
+ "@testing-library/jest-dom": "^6.4.2",
34
+ "@testing-library/react": "^14.2.2",
35
+ "@types/jest": "^29.5.12",
36
+ "@types/jest-axe": "^3.5.9",
31
37
  "@types/node": "^20.9.4",
32
38
  "@types/react": "^18.2.38",
33
39
  "@types/react-dom": "^18.2.17",
@@ -36,7 +42,11 @@
36
42
  "eslint-config-prettier": "^9.0.0",
37
43
  "eslint-plugin-prettier": "^5.0.1",
38
44
  "eslint-plugin-storybook": "^0.6.15",
45
+ "jest": "^29.7.0",
46
+ "jest-axe": "^8.0.0",
47
+ "jest-environment-jsdom": "^29.7.0",
39
48
  "storybook": "^7.6.6",
49
+ "ts-node": "^10.9.2",
40
50
  "typescript": "^5"
41
51
  },
42
52
  "description": "Agroptima design system",
@@ -0,0 +1,71 @@
1
+ @use '../settings/color_alias';
2
+ @use '../settings/typography';
3
+ @use '../settings/config';
4
+
5
+ .checkbox-group {
6
+ .checkbox-label-container {
7
+ display: flex;
8
+ justify-content: flex-start;
9
+ align-items: center;
10
+ gap: config.$space-1x;
11
+
12
+ .background-icon {
13
+ width: config.$icon-size-4x;
14
+ height: config.$icon-size-4x;
15
+ }
16
+
17
+ .label {
18
+ @include typography.checkbox-label;
19
+ }
20
+ }
21
+
22
+ &.primary {
23
+ input[type='checkbox'] {
24
+ display: none;
25
+ }
26
+
27
+ input[type='checkbox'] + .checkbox-label-container .background-icon {
28
+ background: url('../icons/checkbox-primary-inactive.svg') left top
29
+ no-repeat;
30
+ }
31
+
32
+ input[type='checkbox']:checked
33
+ + .checkbox-label-container
34
+ .background-icon {
35
+ background: url('../icons/checkbox-primary-active.svg') left top no-repeat;
36
+ }
37
+
38
+ // Disabled
39
+ input[type='checkbox']
40
+ + .checkbox-label-container.disabled
41
+ .background-icon {
42
+ background: url('../icons/checkbox-disabled-inactive.svg') left top
43
+ no-repeat;
44
+ }
45
+
46
+ input[type='checkbox']:checked
47
+ + .checkbox-label-container.disabled
48
+ .background-icon {
49
+ background: url('../icons/checkbox-disabled-active.svg') left top
50
+ no-repeat;
51
+ }
52
+
53
+ .checkbox-label-container {
54
+ &.disabled {
55
+ .label {
56
+ @include typography.checkbox-disabled-label;
57
+ }
58
+ }
59
+ }
60
+
61
+ // Hover
62
+ &:hover {
63
+ input[type='checkbox']:not(:checked)
64
+ + .checkbox-label-container:not(.disabled)
65
+ .background-icon {
66
+ background: url('../icons/checkbox-primary-hover-inactive.svg') left top
67
+ no-repeat;
68
+ }
69
+ }
70
+ }
71
+ }
@@ -0,0 +1,45 @@
1
+ import './Checkbox.scss'
2
+
3
+ export type Variant = 'primary'
4
+
5
+ export interface CheckboxProps extends React.ComponentPropsWithoutRef<'input'> {
6
+ label?: string
7
+ hideLabel?: boolean
8
+ variant?: Variant
9
+ id: string
10
+ accessibilityLabel: string
11
+ }
12
+
13
+ export function Checkbox({
14
+ accessibilityLabel,
15
+ label,
16
+ hideLabel,
17
+ disabled,
18
+ variant = 'primary',
19
+ id,
20
+ ...props
21
+ }: CheckboxProps) {
22
+ const disabledClass = disabled ? 'disabled' : ''
23
+ const cssClasses = ['checkbox', variant].join(' ')
24
+
25
+ return (
26
+ <div className={`checkbox-group ${variant}`}>
27
+ <input
28
+ id={id}
29
+ type="checkbox"
30
+ className={cssClasses}
31
+ disabled={disabled}
32
+ aria-label={accessibilityLabel}
33
+ {...props}
34
+ />
35
+
36
+ <label
37
+ className={`checkbox-label-container ${disabledClass}`}
38
+ htmlFor={id}
39
+ >
40
+ <span className="background-icon"></span>
41
+ {!hideLabel && <span className="label">{label}</span>}
42
+ </label>
43
+ </div>
44
+ )
45
+ }
@@ -5,7 +5,11 @@ import { Icon } from './Icon'
5
5
  export type Variant = 'primary'
6
6
  export type Option = { id: string; label: string }
7
7
 
8
- export interface SelectProps extends React.ComponentPropsWithoutRef<'input'> {
8
+ type InputPropsWithoutOnChange = Omit<
9
+ React.ComponentPropsWithoutRef<'input'>,
10
+ 'onChange'
11
+ >
12
+ export interface SelectProps extends InputPropsWithoutOnChange {
9
13
  placeholder?: string
10
14
  helpText?: string
11
15
  variant?: Variant
@@ -15,6 +19,7 @@ export interface SelectProps extends React.ComponentPropsWithoutRef<'input'> {
15
19
  accessibilityLabel?: string
16
20
  hideLabel?: boolean
17
21
  selected?: Option
22
+ onChange?: (value: string) => void
18
23
  }
19
24
 
20
25
  export function Select({
@@ -29,6 +34,7 @@ export function Select({
29
34
  accessibilityLabel,
30
35
  hideLabel = false,
31
36
  selected,
37
+ onChange,
32
38
  ...props
33
39
  }: SelectProps): React.JSX.Element {
34
40
  const [showOptionsList, setShowOptionsList] = useState(false)
@@ -55,7 +61,6 @@ export function Select({
55
61
  }
56
62
 
57
63
  function selectOption(option: Option) {
58
- const { onChange } = props
59
64
  setSelectedOption(option)
60
65
  setShowOptionsList(false)
61
66
 
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path class="border" d="M0 2a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Z" fill="#F3F3F3"/><path class="background" fill-rule="evenodd" clip-rule="evenodd" d="M18 1H2a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1ZM2 0a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Z" fill="#9B9B9B"/><path class="check" d="m7.085 13.699-3.793-3.98L2 11.063 7.085 16.4 18 4.946 16.718 3.6 7.085 13.699Z" fill="#9B9B9B"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path class="background" d="M0 2a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Z" fill="#F3F3F3"/><path class="border" fill-rule="evenodd" clip-rule="evenodd" d="M18 1H2a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1ZM2 0a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Z" fill="#9B9B9B"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path class="border" d="M0 2a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Z" fill="#A95782"/><path class="background" fill-rule="evenodd" clip-rule="evenodd" d="M18 1H2a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1ZM2 0a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Z" fill="#A95782"/><path class="check" d="m7.085 13.699-3.793-3.98L2 11.063 7.085 16.4 18 4.946 16.718 3.6 7.085 13.699Z" fill="#fff"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path class="background" d="M0 2a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Z" fill="#fff"/><path class="border" fill-rule="evenodd" clip-rule="evenodd" d="M18 1H2a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1ZM2 0a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Z" fill="#A95782"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path class="background" d="M0 2a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v16a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2Z" fill="#fff"/><path class="border" fill-rule="evenodd" clip-rule="evenodd" d="M18 1H2a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h16a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1ZM2 0a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Z" fill="#727272"/></svg>
@@ -68,6 +68,24 @@ $font-primary: $font-base-stretch $text-base-style $font-base-weight #{$text-bas
68
68
  line-height: 0.775rem;
69
69
  }
70
70
 
71
+ @mixin checkbox-label {
72
+ font-style: $text-base-style;
73
+ font-variant: $text-base-style;
74
+ font-weight: 400;
75
+ font-family: $font-base-family;
76
+ font-size: 1rem;
77
+ color: color_alias.$neutral-color-1000;
78
+ }
79
+
80
+ @mixin checkbox-disabled-label {
81
+ font-style: $text-base-style;
82
+ font-variant: $text-base-style;
83
+ font-weight: 400;
84
+ font-family: $font-base-family;
85
+ font-size: 1rem;
86
+ color: color_alias.$neutral-color-400;
87
+ }
88
+
71
89
  @mixin cards-table-list-header {
72
90
  font-style: $text-base-style;
73
91
  font-variant: $text-base-style;
@@ -3,6 +3,15 @@ import { Meta } from "@storybook/addon-docs";
3
3
  <Meta title="Changelog" />
4
4
  # Changelog
5
5
 
6
+ ## 0.6.1
7
+
8
+ - Fixed error type in onChange select props
9
+ - Added check types to CI
10
+
11
+ ## 0.6.0
12
+
13
+ Checkbox component is added to Storybook.
14
+
6
15
  ## 0.5.0
7
16
 
8
17
  - IconButton component is added to Storybook.
@@ -0,0 +1,58 @@
1
+ import { StoryObj } from '@storybook/react'
2
+ import { Checkbox } from '../atoms/Checkbox'
3
+
4
+ const meta = {
5
+ title: 'Design System/Atoms/Checkbox',
6
+ component: Checkbox,
7
+ tags: ['autodocs'],
8
+ argTypes: {
9
+ accessibilityLabel: {
10
+ description: 'Accessible name & description of the element',
11
+ },
12
+ variant: {
13
+ description: 'Variant used from a list of values',
14
+ },
15
+ disabled: {
16
+ description: 'Is the component in disabled state?',
17
+ },
18
+ label: {
19
+ description: 'Label for the component',
20
+ },
21
+ id: {
22
+ description: 'Value needed for the label relation',
23
+ },
24
+ },
25
+ }
26
+
27
+ const figmaPrimaryDesign = {
28
+ design: {
29
+ type: 'figma',
30
+ url: 'https://www.figma.com/file/DN2ova21vWqCRvPspBXgI1/Design-System?type=design&node-id=521-104&mode=dev',
31
+ },
32
+ }
33
+
34
+ export default meta
35
+ type Story = StoryObj<typeof meta>
36
+
37
+ export const Primary: Story = {
38
+ args: {
39
+ accessibilityLabel: 'Marks if the user likes videogames',
40
+ variant: 'primary',
41
+ disabled: false,
42
+ label: 'Do you like videogames?',
43
+ id: 'checkbox-videogames-preference',
44
+ },
45
+ parameters: figmaPrimaryDesign,
46
+ }
47
+
48
+ export const PrimaryWithoutLabel: Story = {
49
+ args: {
50
+ accessibilityLabel: 'Marks if the user likes videogames',
51
+ variant: 'primary',
52
+ disabled: false,
53
+ label: 'Do you like videogames?',
54
+ id: 'checkbox-videogames-preference',
55
+ hideLabel: true,
56
+ },
57
+ parameters: figmaPrimaryDesign,
58
+ }
@@ -0,0 +1,29 @@
1
+ import { composeStories } from '@storybook/react'
2
+ import { act, render } from '@testing-library/react'
3
+ import { axe, toHaveNoViolations } from 'jest-axe'
4
+
5
+ import * as components from './library'
6
+
7
+ expect.extend(toHaveNoViolations)
8
+
9
+ const stories = Object.values(components).map((component) => {
10
+ return {
11
+ title: component.default.title,
12
+ stories: composeStories(component),
13
+ }
14
+ })
15
+
16
+ stories.forEach(({ title, stories }) => {
17
+ const variations = Object.entries(stories)
18
+
19
+ variations.forEach(([variationName, story]: [string, any]) => {
20
+ it(`${title} ${variationName} should be accessible`, async () => {
21
+ const { container } = render(story())
22
+
23
+ await act(async () => {
24
+ const results = await axe(container)
25
+ expect(results).toHaveNoViolations()
26
+ })
27
+ })
28
+ })
29
+ })
@@ -0,0 +1,9 @@
1
+ export * as Button from '../src/stories/Button.stories'
2
+ export * as CardsTable from '../src/stories/CardsTable.stories'
3
+ export * as CardsTableList from '../src/stories/CardsTableList.stories'
4
+ export * as Checkbox from '../src/stories/Checkbox.stories'
5
+ export * as EmptyState from '../src/stories/EmptyState.stories'
6
+ export * as IconButton from '../src/stories/IconButton.stories'
7
+ export * as Input from '../src/stories/Input.stories'
8
+ export * as Multiselect from '../src/stories/Multiselect.stories'
9
+ export * as Select from '../src/stories/Select.stories'
@@ -0,0 +1 @@
1
+ export default function () {}