@miljodirektoratet/md-css 4.1.2 → 4.2.0

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": "@miljodirektoratet/md-css",
3
- "version": "4.1.2",
3
+ "version": "4.2.0",
4
4
  "description": "CSS for Miljødirektoratet",
5
5
  "author": "Miljødirektoratet",
6
6
  "main": "./src/index.css",
package/src/colors.css CHANGED
@@ -3,6 +3,7 @@
3
3
  --mdPrimaryColor160: #003b3a;
4
4
  --mdPrimaryColor120: #005251;
5
5
  --mdPrimaryColor80: #337e7d;
6
+ --mdPrimaryColor40: #99bebe;
6
7
  --mdPrimaryColor30: #b2cece;
7
8
  --mdPrimaryColor20: #ccdfde;
8
9
  --mdPrimaryColor10: #e5eeee;
@@ -28,7 +29,7 @@
28
29
  --mdGreyColor10: #e8e8e8;
29
30
  --mdGreyColor20: #d2d2d2;
30
31
  --mdGreyColor40: #a6a6a6;
31
- --mdGreyColor60: #808080;
32
+ --mdGreyColor60: #767676;
32
33
  --mdGreyColor80: #4e4e4e;
33
34
 
34
35
  --mdGreenColor60: #b3e8c2;
@@ -0,0 +1,79 @@
1
+ # Structure
2
+
3
+ To use the `MdComboBox` css in `@miljodirektoratet/md-css` as a standalone, without the accompanying React component, please use the following HTML structure. Note that this component is built on [Ariakit combobox](https://ariakit.org/components/combobox), so implementing it outside React may be challenging due to the complex accessibility behavior it provides.
4
+
5
+ Class names in brackets [] are optional-/togglable-/decorator- or state dependant classes.
6
+
7
+ See [Storybook](https://miljodir.github.io/md-components) for examples and more info.
8
+
9
+ ```html
10
+ <div class="md-combobox md-combobox--[large|medium|small] [md-combobox--has-error]">
11
+ <!-- Label section with optional help button -->
12
+ <div class="md-combobox__label-wrapper">
13
+ <div class="md-combobox__label">
14
+ <Ariakit.ComboboxLabel>{label}</Ariakit.ComboboxLabel>
15
+ <div class="md-combobox__help-button">
16
+ <!-- Help button component -->
17
+ </div>
18
+ </div>
19
+
20
+ <div class="md-combobox__help-text [md-combobox__help-text--open]">
21
+ <!-- Help text component -->
22
+ </div>
23
+ </div>
24
+
25
+ <!-- Input wrapper with prefix icon and arrow -->
26
+ <div class="md-combobox__input-wrapper [md-combobox__input-wrapper--disabled]">
27
+ <div class="md-combobox__input--before">
28
+ <!-- Prefix icon: search icon, loading spinner, or custom icon -->
29
+ </div>
30
+
31
+ <Ariakit.Combobox
32
+ class="md-combobox__input [md-combobox__input--no-prefix-icon]"
33
+ placeholder="{placeholder}"
34
+ />
35
+
36
+ <div class="md-combobox__input--after">
37
+ <div>
38
+ <!-- Counter for multi-select: +{count} -->
39
+ </div>
40
+ <!-- Reset button - displayed when allowReset is true and there's a value or search text -->
41
+ <button class="md-combobox__reset" aria-label="Nullstill">
42
+ <!-- Close/clear icon -->
43
+ </button>
44
+ <!-- Chevron icon -->
45
+ </div>
46
+ </div>
47
+
48
+ <!-- Dropdown/popover -->
49
+ <Ariakit.ComboboxPopover class="md-combobox__popover">
50
+ <!-- For regular options -->
51
+ <Ariakit.ComboboxItem class="md-combobox__checkbox-item [md-combobox__checkbox-item--selected]">
52
+ <!-- For single select: just text -->
53
+ Option text
54
+
55
+ <!-- For multi-select: checkbox -->
56
+ <MdCheckbox label="Option text" />
57
+ </Ariakit.ComboboxItem>
58
+
59
+ <!-- No results state -->
60
+ <div class="md-combobox__checkbox-item md-combobox__checkbox-item--no-result">
61
+ No results found
62
+ </div>
63
+ </Ariakit.ComboboxPopover>
64
+
65
+ <!-- Error text -->
66
+ <div class="md-combobox__error">{errorText}</div>
67
+ </div>
68
+ ```
69
+
70
+ ## Accessibility Notes
71
+
72
+ The MdComboBox component uses Ariakit's ComboBox component which handles numerous accessibility attributes including:
73
+
74
+ - Proper ARIA roles and attributes
75
+ - Keyboard navigation
76
+ - Focus management
77
+ - Screen reader announcements
78
+
79
+ When implementing this outside of React, you'll need to handle these accessibility concerns manually. The library automatically manages attributes like `aria-activedescendant`, `aria-controls`, `aria-expanded`, etc.
@@ -0,0 +1,196 @@
1
+ .md-combobox {
2
+ font-family: 'Open sans';
3
+ width: 100%;
4
+ }
5
+
6
+ /* Label */
7
+ .md-combobox__label-wrapper {
8
+ margin-bottom: 0.5rem;
9
+ }
10
+ .md-combobox__label {
11
+ display: flex;
12
+ align-items: center;
13
+ gap: 0.5rem;
14
+ }
15
+ .md-combobox__label label {
16
+ font-weight: 600;
17
+ }
18
+
19
+ .md-combobox__input-wrapper {
20
+ position: relative;
21
+ }
22
+ .md-combobox__input {
23
+ width: 100%;
24
+ font-size: 1rem;
25
+ line-height: 150%;
26
+ border: 1px solid var(--mdPrimaryColor);
27
+ padding: 0.6875rem 6rem 0.6875rem 2.5rem;
28
+ }
29
+ .md-combobox--large .md-combobox__input {
30
+ padding: 0.9375rem 4rem 0.9375rem 2.5rem;
31
+ }
32
+ .md-combobox--small .md-combobox__input {
33
+ padding: 0.4375rem 4rem 0.4375rem 2.5rem;
34
+ }
35
+ .md-combobox__input--no-prefix-icon,
36
+ .md-combobox--large .md-combobox__input--no-prefix-icon,
37
+ .md-combobox--small .md-combobox__input--no-prefix-icon {
38
+ padding-left: 0.75rem;
39
+ }
40
+ .md-combobox__input::placeholder {
41
+ color: var(--mdGreyColor60);
42
+ font-size: 1rem;
43
+ }
44
+ .md-combobox--has-value .md-combobox__input[aria-expanded='false']::placeholder {
45
+ color: var(--mdTextColor);
46
+ }
47
+
48
+ .md-combobox__input[data-focus-visible],
49
+ .md-combobox__input[aria-expanded='true'] {
50
+ outline: 2px solid var(--mdPrimaryColor);
51
+ outline-offset: -2px;
52
+ }
53
+
54
+ .md-combobox__input[aria-expanded='true']::placeholder {
55
+ opacity: 0;
56
+ }
57
+
58
+ .md-combobox__input:disabled {
59
+ background-color: var(--mdGreyColor20);
60
+ border-color: var(--mdGreyColor60);
61
+ }
62
+ .md-combobox__input:disabled::placeholder {
63
+ color: var(--mdGreyColor60);
64
+ }
65
+ .md-combobox__input--before {
66
+ position: absolute;
67
+ display: flex;
68
+ top: 50%;
69
+ left: 0.75rem;
70
+ color: var(--mdPrimaryColor);
71
+ width: 1.5rem;
72
+ height: 1.5rem;
73
+ transform: translateY(-50%);
74
+ }
75
+ .md-combobox__input-wrapper--disabled .md-combobox__input--before {
76
+ color: var(--mdGreyColor60);
77
+ }
78
+ .md-combobox__input--after {
79
+ position: absolute;
80
+ top: 50%;
81
+ right: 0.75rem;
82
+ display: flex;
83
+ align-items: center;
84
+ gap: 0.5rem;
85
+ color: var(--mdTextColor);
86
+ transform: translateY(-50%);
87
+ z-index: 0;
88
+ }
89
+ .md-combobox__input-wrapper--disabled .md-combobox__input--after {
90
+ color: var(--mdGreyColor60);
91
+ }
92
+ .md-combobox__input--after svg {
93
+ width: 1.5rem;
94
+ height: 1.5rem;
95
+ color: var(--mdTextColor);
96
+ }
97
+ .md-combobox__input--after svg.md-combobox__input-arrow {
98
+ transition: rotate 0.2s ease-in;
99
+ }
100
+ .md-combobox__input-wrapper--disabled .md-combobox__input--after svg {
101
+ color: var(--mdGreyColor60);
102
+ }
103
+ .md-combobox__input[aria-expanded='true'] + .md-combobox__input--after svg.md-combobox__input-arrow {
104
+ rotate: -180deg;
105
+ transition: rotate 0.2s ease-in;
106
+ }
107
+ .md-combobox__reset,
108
+ .md-combobox__toggle {
109
+ padding: 0;
110
+ margin: 0;
111
+ background: transparent;
112
+ border: 0;
113
+ border-radius: 0;
114
+ margin-right: 0.3rem;
115
+ width: 1.5rem;
116
+ height: 1.5rem;
117
+ cursor: pointer;
118
+ line-height: 150%;
119
+
120
+ &:focus-visible {
121
+ outline: 2px solid var(--mdPrimaryColor);
122
+ outline-offset: -2px;
123
+ }
124
+ }
125
+
126
+ /* Popover */
127
+ .md-combobox__popover {
128
+ background-color: #fff;
129
+ max-height: min(var(--popover-available-height, 300px), 300px);
130
+ overflow: auto;
131
+ overscroll-behavior: contain;
132
+ border: 2px solid var(--mdPrimaryColor);
133
+ border-top: 0;
134
+ opacity: 0;
135
+ transition-duration: 200ms;
136
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
137
+ animation-duration: 200ms;
138
+ animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
139
+ transform: translateY(-5%);
140
+ z-index: 3;
141
+ }
142
+ .md-combobox__popover[data-enter] {
143
+ opacity: 1;
144
+ transform: translateY(0%);
145
+ }
146
+
147
+ /* Combobox item */
148
+ .md-combobox__checkbox-item {
149
+ padding: 0.75rem;
150
+ cursor: pointer;
151
+ }
152
+ .md-combobox__checkbox-item--no-result {
153
+ font-style: italic;
154
+ }
155
+ .md-combobox--large .md-combobox__checkbox-item {
156
+ padding: 1rem 0.75rem;
157
+ }
158
+ .md-combobox--small .md-combobox__checkbox-item {
159
+ padding: 0.5rem 0.75rem;
160
+ }
161
+ .md-combobox__checkbox-item[aria-selected='true'] {
162
+ background-color: var(--mdPrimaryColor20);
163
+ }
164
+ .md-combobox__checkbox-item[data-focus-visible],
165
+ .md-combobox__checkbox-item[data-active-item] {
166
+ background-color: var(--mdPrimaryColor40);
167
+
168
+ .md-checkbox__label::before {
169
+ background-color: #fff;
170
+ }
171
+ }
172
+
173
+ /* Help text */
174
+ .md-combobox__help-text {
175
+ max-height: 0;
176
+ overflow: hidden;
177
+ transition: max-height 0.15s ease-out;
178
+ }
179
+ .md-combobox__help-text--open {
180
+ padding-top: 0.5rem;
181
+ padding-bottom: 0.5rem;
182
+ max-height: 2000px;
183
+ transition: max-height 0.5s ease-in;
184
+ }
185
+
186
+ /* Error */
187
+ .md-combobox__error {
188
+ margin-top: 0.5rem;
189
+ color: var(--mdErrorColor);
190
+ font-size: 0.88em;
191
+ }
192
+ .md-combobox--has-error .md-combobox__input,
193
+ .md-combobox--has-error .md-combobox__popover {
194
+ outline-color: var(--mdErrorColor);
195
+ border-color: var(--mdErrorColor);
196
+ }
package/src/index.css CHANGED
@@ -26,6 +26,7 @@
26
26
  @import './formElements/multiselect/multiselect.css';
27
27
  @import './formElements/multiautocomplete/multiautocomplete.css';
28
28
  @import './formElements/fileupload/fileupload.css';
29
+ @import './formElements/combobox/combobox.css';
29
30
  @import './utils.css';
30
31
 
31
32
  html {