agroptima-design-system 0.22.0 → 0.22.2-beta.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agroptima-design-system",
3
- "version": "0.22.0",
3
+ "version": "0.22.2-beta.1",
4
4
  "scripts": {
5
5
  "dev": "npm run storybook",
6
6
  "storybook": "storybook dev -p 6006 --ci",
@@ -7,8 +7,8 @@
7
7
  display: flex;
8
8
  justify-content: space-between;
9
9
  padding: config.$space-2x config.$space-3x;
10
- align-items: center;
11
10
  gap: config.$space-2x;
11
+ align-items: flex-start;
12
12
  border-radius: config.$corner-radius-xxs;
13
13
  pointer-events: none;
14
14
 
@@ -19,7 +19,7 @@
19
19
  .information-container {
20
20
  display: flex;
21
21
  justify-content: flex-start;
22
- align-items: center;
22
+ align-items: flex-start;
23
23
  gap: config.$space-2x;
24
24
  }
25
25
 
@@ -28,8 +28,10 @@
28
28
  }
29
29
 
30
30
  .icon {
31
+ margin-top: 2px;
31
32
  width: config.$icon-size-5x;
32
33
  height: config.$icon-size-5x;
34
+ min-width: config.$icon-size-5x;
33
35
  > svg {
34
36
  width: 100%;
35
37
  height: 100%;
@@ -38,9 +40,10 @@
38
40
 
39
41
  .icon-button {
40
42
  pointer-events: auto;
43
+ margin-top: 5px;
41
44
  .icon {
42
- width: config.$icon-size-2x;
43
- height: config.$icon-size-2x;
45
+ width: config.$icon-size-3x;
46
+ height: config.$icon-size-3x;
44
47
 
45
48
  > svg {
46
49
  fill: color_alias.$neutral-color-400;
@@ -39,7 +39,32 @@
39
39
  }
40
40
  }
41
41
  }
42
+ }
43
+
44
+ &.secondary {
45
+ > .icon {
46
+ > svg {
47
+ fill: color_alias.$neutral-white;
48
+ path {
49
+ fill: color_alias.$neutral-white;
50
+ }
51
+ }
52
+ }
53
+
54
+ &:hover {
55
+ > .icon {
56
+ > svg {
57
+ fill: color_alias.$neutral-color-1000;
58
+ path {
59
+ fill: color_alias.$neutral-color-1000;
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
42
65
 
66
+ &.primary,
67
+ &.secondary {
43
68
  &:disabled {
44
69
  > .icon {
45
70
  > svg {
@@ -3,7 +3,7 @@ import { Icon, IconType } from '../Icon'
3
3
  import { classNames } from '../../utils/classNames'
4
4
  import { BaseButtonProps, BaseButton } from './BaseButton'
5
5
 
6
- export type Variant = 'primary'
6
+ export type Variant = 'primary' | 'secondary'
7
7
 
8
8
  interface CustomProps {
9
9
  icon: IconType
@@ -3,22 +3,107 @@
3
3
  @use '../settings/config';
4
4
 
5
5
  .input-group {
6
+ @include typography.input-text;
6
7
  display: flex;
7
8
  flex-direction: column;
8
9
  gap: config.$space-2x;
9
10
 
10
- .input {
11
- padding-left: 12px;
11
+ .input-help-text {
12
+ @include typography.form-help-text;
12
13
  }
13
14
 
14
- &:has(.input.invalid) {
15
- & .input-help-text {
16
- @include typography.form-help-text-error;
15
+ .input-label {
16
+ @include typography.form-label;
17
+ }
18
+
19
+ &.invalid .input-help-text {
20
+ @include typography.form-help-text-error;
21
+ }
22
+
23
+ .input-container {
24
+ position: relative;
25
+ gap: config.$space-2x;
26
+ display: flex;
27
+ align-items: center;
28
+ flex-direction: row;
29
+ width: 100%;
30
+ padding: config.$space-2x config.$space-3x config.$space-2x;
31
+ input[type='date'] {
32
+ min-width: -webkit-fill-available;
33
+ }
34
+ input[type='number'] {
35
+ text-align: right;
36
+ }
37
+ input::placeholder,
38
+ textarea::placeholder {
39
+ @include typography.input-placeholder-text;
40
+ }
41
+ input,
42
+ input:hover,
43
+ input:focus,
44
+ input:active,
45
+ input:focus-visible,
46
+ input:focus-within,
47
+ input:visited,
48
+ textarea,
49
+ textarea:hover,
50
+ textarea:focus,
51
+ textarea:active,
52
+ textarea:focus-visible,
53
+ textarea:focus-within,
54
+ textarea:visited {
55
+ @include typography.input-text;
56
+ width: 100%;
57
+ padding: 0;
58
+ background: none;
59
+ border: none;
60
+ border-radius: 0;
61
+ outline: none;
62
+ -webkit-appearance: none;
63
+ -moz-appearance: none;
64
+ appearance: none;
65
+ }
66
+ .input-suffix {
67
+ color: color_alias.$neutral-color-600;
68
+ }
69
+ .icon {
70
+ min-width: config.$icon-size-5x;
71
+ width: config.$icon-size-5x;
72
+ height: config.$icon-size-5x;
73
+ }
74
+
75
+ .left-icon {
76
+ top: 0.9rem;
77
+ left: 0.7rem;
17
78
  }
18
79
  }
19
80
 
20
81
  &.primary {
82
+ &.invalid .input-container {
83
+ border: 1px solid color_alias.$error-color-1000;
84
+ }
21
85
  .input-container {
86
+ border-radius: config.$corner-radius-m;
87
+ border: 1px solid color_alias.$neutral-color-600;
88
+ background: color_alias.$neutral-white;
89
+
90
+ &:has(input:focus),
91
+ &:has(textarea:focus) {
92
+ outline: color_alias.$primary-color-600;
93
+ border: 1px solid color_alias.$primary-color-600;
94
+ }
95
+
96
+ &:has(input:disabled),
97
+ &:has(textarea:disabled) {
98
+ border: 1px solid color_alias.$neutral-color-400;
99
+ background: color_alias.$neutral-color-50;
100
+ color: color_alias.$neutral-color-400;
101
+
102
+ input::placeholder,
103
+ textarea::placeholder {
104
+ color: color_alias.$neutral-color-400;
105
+ }
106
+ }
22
107
  .icon {
23
108
  > svg {
24
109
  fill: color_alias.$neutral-color-400;
@@ -37,82 +122,5 @@
37
122
  }
38
123
  }
39
124
  }
40
-
41
- .input {
42
- border-radius: config.$corner-radius-m;
43
- border: 1px solid color_alias.$neutral-color-400;
44
- background: color_alias.$neutral-white;
45
-
46
- @include typography.input-text;
47
-
48
- &::placeholder {
49
- @include typography.input-placeholder-text;
50
- }
51
-
52
- &:focus {
53
- outline: color_alias.$primary-color-600;
54
- border: 1px solid color_alias.$primary-color-600;
55
- }
56
-
57
- &.invalid {
58
- border: 1px solid color_alias.$error-color-1000;
59
- }
60
-
61
- &:disabled {
62
- border: 1px solid color_alias.$neutral-color-400;
63
- background: color_alias.$neutral-color-50;
64
- color: color_alias.$neutral-color-400;
65
-
66
- &::placeholder {
67
- color: color_alias.$neutral-color-400;
68
- }
69
- }
70
- }
71
-
72
- .input-help-text {
73
- @include typography.form-help-text;
74
- }
75
-
76
- .input-label {
77
- @include typography.form-label;
78
- }
79
- }
80
-
81
- .input-container {
82
- position: relative;
83
- display: flex;
84
- flex-direction: row;
85
-
86
- .icon {
87
- position: absolute;
88
- width: config.$icon-size-3x;
89
- height: config.$icon-size-3x;
90
- > svg {
91
- width: 100%;
92
- height: 100%;
93
- }
94
- }
95
-
96
- .left-icon {
97
- top: 0.9rem;
98
- left: 0.7rem;
99
- }
100
-
101
- .password-icon {
102
- top: 0.9rem;
103
- right: 0.7rem;
104
- }
105
- }
106
-
107
- .input {
108
- width: 100%;
109
- padding: config.$space-2x config.$space-3x config.$space-2x;
110
- &[type='date'] {
111
- min-width: -webkit-fill-available;
112
- }
113
- }
114
-
115
- .with-icon {
116
- padding-left: 28px;
117
125
  }
118
126
  }
@@ -14,6 +14,7 @@ export interface InputProps extends React.ComponentPropsWithoutRef<'input'> {
14
14
  helpText?: string
15
15
  variant?: InputVariant
16
16
  id?: string
17
+ suffix?: string
17
18
  errors?: string[]
18
19
  }
19
20
 
@@ -27,6 +28,7 @@ export function Input({
27
28
  variant = 'primary',
28
29
  disabled,
29
30
  type = 'text',
31
+ suffix,
30
32
  name,
31
33
  id,
32
34
  errors,
@@ -34,10 +36,6 @@ export function Input({
34
36
  }: InputProps): React.JSX.Element {
35
37
  const identifier = id || name
36
38
  const [showPassword, setShowPassword] = useState(false)
37
- const cssClasses = classNames('input', {
38
- 'with-icon': icon,
39
- invalid: errors?.length,
40
- })
41
39
  const helpTexts = buildHelpText(helpText, errors)
42
40
 
43
41
  function handlePasswordIcon() {
@@ -55,7 +53,11 @@ export function Input({
55
53
  }
56
54
 
57
55
  return (
58
- <div className={classNames('input-group', variant, className)}>
56
+ <div
57
+ className={classNames('input-group', variant, className, {
58
+ invalid: errors?.length,
59
+ })}
60
+ >
59
61
  {!hideLabel && (
60
62
  <label className="input-label" htmlFor={identifier}>
61
63
  {label}
@@ -65,13 +67,13 @@ export function Input({
65
67
  {icon && <Icon className="left-icon" name={icon} />}
66
68
  <input
67
69
  id={identifier}
68
- className={cssClasses}
69
70
  disabled={disabled}
70
71
  type={handleInputType()}
71
72
  name={name}
72
73
  aria-label={accessibilityLabel || label}
73
74
  {...props}
74
75
  />
76
+ {suffix && <span className="input-suffix">{suffix}</span>}
75
77
  {type === 'password' && (
76
78
  <Icon
77
79
  className="password-icon"
@@ -7,6 +7,7 @@
7
7
  position: fixed;
8
8
  inset: 0;
9
9
  z-index: depth.$z-modal;
10
+ margin: config.$space-4x;
10
11
 
11
12
  .backdrop {
12
13
  position: fixed;
@@ -37,9 +38,11 @@
37
38
  .header {
38
39
  display: flex;
39
40
  gap: config.$space-2x;
40
- align-items: center;
41
+ align-items: flex-start;
41
42
 
42
43
  .icon {
44
+ margin-top: 4px;
45
+ min-width: config.$icon-size-5x;
43
46
  width: config.$icon-size-5x;
44
47
  height: config.$icon-size-5x;
45
48
  > svg {
@@ -20,6 +20,11 @@
20
20
  &.primary {
21
21
  .quantity-selector {
22
22
  .input-container {
23
+ border-radius: 0;
24
+ border-right: 0;
25
+ border-left: 0;
26
+ background: color_alias.$neutral-white;
27
+ text-align: center;
23
28
  // Remove default arrows
24
29
  /* Chrome, Safari, Edge, Opera */
25
30
  input::-webkit-outer-spin-button,
@@ -27,38 +32,9 @@
27
32
  -webkit-appearance: none;
28
33
  margin: 0;
29
34
  }
30
-
31
- /* Firefox */
32
35
  input[type='number'] {
33
36
  -moz-appearance: textfield;
34
- }
35
- .input {
36
- border-radius: 0;
37
- border-right: 0;
38
- border-left: 0;
39
- background: color_alias.$neutral-white;
40
37
  text-align: center;
41
-
42
- @include form-typography.input-text;
43
-
44
- &::placeholder {
45
- @include form-typography.input-placeholder-text;
46
- }
47
-
48
- &:focus {
49
- outline: color_alias.$primary-color-600;
50
- border: 1px solid color_alias.$primary-color-600;
51
- }
52
-
53
- &:disabled {
54
- border: 1px solid color_alias.$neutral-color-400;
55
- background: color_alias.$neutral-color-50;
56
- color: color_alias.$neutral-color-400;
57
-
58
- &::placeholder {
59
- color: color_alias.$neutral-color-400;
60
- }
61
- }
62
38
  }
63
39
  }
64
40
  .button {
@@ -1,8 +1,8 @@
1
1
  import React from 'react'
2
2
  import { classNames } from '../utils/classNames'
3
- import './QuantitySelector.scss'
4
3
  import { Input, InputProps } from './Input'
5
- import { Button, ButtonProps } from './Button'
4
+ import { Button } from './Button'
5
+ import './QuantitySelector.scss'
6
6
 
7
7
  export type Variant = 'primary'
8
8
 
@@ -21,7 +21,7 @@
21
21
 
22
22
  .selected-option {
23
23
  border-radius: config.$corner-radius-m;
24
- border: 1px solid color_alias.$neutral-color-400;
24
+ border: 1px solid color_alias.$neutral-color-600;
25
25
  background: color_alias.$neutral-white;
26
26
  @include typography.select-text;
27
27
 
@@ -65,7 +65,7 @@
65
65
 
66
66
  .select-options {
67
67
  max-height: 256px;
68
- overflow-y: scroll;
68
+ overflow-y: auto;
69
69
  overflow-anchor: none;
70
70
  z-index: depth.$z-dropdown-options;
71
71
  border-radius: config.$corner-radius-xxs;
@@ -29,10 +29,13 @@ export function TextArea({
29
29
  ...props
30
30
  }: TextAreaProps) {
31
31
  const identifier = id || name
32
- const cssClasses = classNames('input', className, { invalid: errors?.length })
33
32
  const helpTexts = buildHelpText(helpText, errors)
34
33
  return (
35
- <div className={`input-group ${variant}`}>
34
+ <div
35
+ className={classNames('input-group', variant, className, {
36
+ invalid: errors?.length,
37
+ })}
38
+ >
36
39
  {!hideLabel && (
37
40
  <label className="input-label" htmlFor={identifier}>
38
41
  {label}
@@ -41,7 +44,6 @@ export function TextArea({
41
44
  <div className="input-container">
42
45
  <textarea
43
46
  id={identifier}
44
- className={cssClasses}
45
47
  disabled={disabled}
46
48
  name={name}
47
49
  aria-label={accessibilityLabel || label}
@@ -4,13 +4,25 @@ import { Meta } from "@storybook/blocks";
4
4
 
5
5
  # Changelog
6
6
 
7
+ # 0.22.2
8
+
9
+ * Add IconButton secondary variant
10
+
11
+ ## 0.22.1
12
+
13
+ * Add suffix to Input component
14
+ * Update styles for Input, TextArea and QuantitySelector components
15
+ * Update styles for action button in Alert components
16
+
7
17
  ## 0.22.0
8
18
 
9
- * Added FloatingButton component to Storybook
19
+ * Add a max height to Select component
20
+ * Center on top icon in Modal and Alert componets
10
21
 
11
22
  BREAKING CHANGES
12
23
 
13
- * Replece selected prop by defaultValue in Select component
24
+ * Replace selected prop by defaultValue in Select component
25
+ * Change the way to put the classname in Input component
14
26
 
15
27
  ## 0.21.5
16
28
  * Update open state in Collapsible component
@@ -22,8 +34,8 @@ BREAKING CHANGES
22
34
 
23
35
  ## 0.21.4
24
36
 
25
- * Add boder top to CardMenuOption component for first element.
26
- * Add margin top to second element row in CardsTable component.
37
+ * Add border top to CardMenuOption component for first element
38
+ * Add margin top to second element row in CardsTable component
27
39
  * CardsTable needs to specify a withTitle property to add title to first column
28
40
 
29
41
  ## 0.21.3
@@ -96,61 +96,66 @@ export const Primary = {
96
96
 
97
97
  export const PrimaryOpened = {
98
98
  render: () => (
99
- <Collapsible title="My personal data" name="personal-data" open>
100
- <div
101
- style={{
102
- display: 'flex',
103
- flexDirection: 'column',
104
- width: '100%',
105
- gap: '1rem',
106
- }}
107
- >
108
- <Input
109
- accessibilityLabel="Fill the form name"
110
- helpText="This text can help you"
111
- id="name_input"
112
- label="Name"
113
- name="name"
114
- placeholder="name..."
115
- type="name"
116
- variant="primary"
117
- />
118
- <Input
119
- accessibilityLabel="Fill the form email"
120
- helpText="This text can help you"
121
- id="email_input"
122
- label="Email"
123
- name="email"
124
- placeholder="Email..."
125
- type="email"
126
- variant="primary"
127
- />
128
- <Select
129
- accessibilityLabel="Select your favourite gaming system options"
130
- helpText="This text can help you"
131
- id="select-videogames"
132
- label="Videogames"
133
- name="example"
134
- onChange={() => {}}
135
- options={[
136
- {
137
- id: '1',
138
- label: 'Nintendo Switch',
139
- },
140
- {
141
- id: '2',
142
- label: 'PlayStation 5',
143
- },
144
- {
145
- id: '3',
146
- label: 'Xbox Series S/X',
147
- },
148
- ]}
149
- placeholder="Select your favourite gaming system..."
150
- variant="primary"
151
- />
152
- </div>
153
- </Collapsible>
99
+ <>
100
+ <Collapsible title="My personal data" name="personal-data" open>
101
+ <div
102
+ style={{
103
+ display: 'flex',
104
+ flexDirection: 'column',
105
+ width: '100%',
106
+ gap: '1rem',
107
+ }}
108
+ >
109
+ <Input
110
+ accessibilityLabel="Fill the form name"
111
+ helpText="This text can help you"
112
+ id="name_input"
113
+ label="Name"
114
+ name="name"
115
+ placeholder="name..."
116
+ type="name"
117
+ variant="primary"
118
+ />
119
+ <Input
120
+ accessibilityLabel="Fill the form email"
121
+ helpText="This text can help you"
122
+ id="email_input"
123
+ label="Email"
124
+ name="email"
125
+ placeholder="Email..."
126
+ type="email"
127
+ variant="primary"
128
+ />
129
+ <Select
130
+ accessibilityLabel="Select your favourite gaming system options"
131
+ helpText="This text can help you"
132
+ id="select-videogames"
133
+ label="Videogames"
134
+ name="example"
135
+ onChange={() => {}}
136
+ options={[
137
+ {
138
+ id: '1',
139
+ label: 'Nintendo Switch',
140
+ },
141
+ {
142
+ id: '2',
143
+ label: 'PlayStation 5',
144
+ },
145
+ {
146
+ id: '3',
147
+ label: 'Xbox Series S/X',
148
+ },
149
+ ]}
150
+ placeholder="Select your favourite gaming system..."
151
+ variant="primary"
152
+ />
153
+ </div>
154
+ </Collapsible>
155
+ <Collapsible title="Another data" name="another-data">
156
+ <Input label="Another data" name="anotherData" placeholder="..." />
157
+ </Collapsible>
158
+ </>
154
159
  ),
155
160
  }
156
161
 
@@ -56,3 +56,13 @@ export const Primary: Story = {
56
56
  },
57
57
  parameters: figmaPrimaryDesign,
58
58
  }
59
+
60
+ export const Secondary: Story = {
61
+ args: {
62
+ icon: 'Delete',
63
+ variant: 'secondary',
64
+ accessibilityLabel: 'Delete game',
65
+ disabled: false,
66
+ },
67
+ parameters: figmaPrimaryDesign,
68
+ }
@@ -37,6 +37,9 @@ const meta = {
37
37
  id: {
38
38
  description: 'Value needed for the label relation',
39
39
  },
40
+ suffix: {
41
+ description: 'Input suffix',
42
+ },
40
43
  errors: {
41
44
  description:
42
45
  'Optional array of errors. If passed, the errors are listed and invalid style is applied.',
@@ -98,3 +101,14 @@ export const WithErrors: Story = {
98
101
  },
99
102
  parameters: figmaPrimaryDesign,
100
103
  }
104
+
105
+ export const WithSuffix: Story = {
106
+ args: {
107
+ label: 'Input with suffix',
108
+ helpText: 'This text can help you',
109
+ name: 'price',
110
+ type: 'number',
111
+ suffix: '€/Bottle',
112
+ },
113
+ parameters: figmaPrimaryDesign,
114
+ }
@@ -72,7 +72,7 @@ export const WithErrors: Story = {
72
72
  helpText: 'This text can help you',
73
73
  name: 'textarea',
74
74
  id: 'textarea',
75
- errors: ['error1', 'error2'],
75
+ errors: ['Che che che', 'Another error'],
76
76
  },
77
77
  parameters: figmaPrimaryDesign,
78
78
  }