@oslokommune/punkt-css 16.26.3 → 17.0.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.
Files changed (75) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/dist/css/components/accordion.css +27 -5
  3. package/dist/css/components/accordion.min.css +1 -1
  4. package/dist/css/components/alert.css +37 -3
  5. package/dist/css/components/alert.min.css +1 -1
  6. package/dist/css/components/calendar.css +4 -0
  7. package/dist/css/components/calendar.min.css +1 -1
  8. package/dist/css/components/combobox.css +82 -0
  9. package/dist/css/components/combobox.min.css +1 -1
  10. package/dist/css/components/datepicker.css +82 -3
  11. package/dist/css/components/datepicker.min.css +1 -1
  12. package/dist/css/components/footer.css +232 -108
  13. package/dist/css/components/footer.min.css +1 -1
  14. package/dist/css/components/header-global.css +287 -0
  15. package/dist/css/components/header-global.min.css +1 -0
  16. package/dist/css/components/header-menu.css +364 -123
  17. package/dist/css/components/header-menu.min.css +1 -1
  18. package/dist/css/components/header-service-mobile.css +71 -22
  19. package/dist/css/components/header-service-mobile.min.css +1 -1
  20. package/dist/css/components/header-service.css +68 -14
  21. package/dist/css/components/header-service.min.css +1 -1
  22. package/dist/css/components/header-shared.css +49 -0
  23. package/dist/css/components/header-shared.min.css +0 -0
  24. package/dist/css/components/inputwrapper.css +58 -4
  25. package/dist/css/components/inputwrapper.min.css +1 -1
  26. package/dist/css/components/modal.css +0 -5
  27. package/dist/css/components/modal.min.css +1 -1
  28. package/dist/css/components/searchinput.css +71 -2
  29. package/dist/css/components/searchinput.min.css +1 -1
  30. package/dist/css/components/textarea.css +41 -0
  31. package/dist/css/components/textarea.min.css +1 -0
  32. package/dist/css/components/textinput.css +126 -6
  33. package/dist/css/components/textinput.min.css +1 -1
  34. package/dist/css/components/timepicker.css +133 -38
  35. package/dist/css/components/timepicker.min.css +1 -1
  36. package/dist/css/elements/button.css +20 -4
  37. package/dist/css/elements/button.min.css +1 -1
  38. package/dist/css/elements/checkbox-radio.css +3 -3
  39. package/dist/css/elements/checkbox-radio.min.css +1 -1
  40. package/dist/css/elements/input.css +121 -6
  41. package/dist/css/elements/input.min.css +1 -1
  42. package/dist/css/elements/select.css +137 -9
  43. package/dist/css/elements/select.min.css +1 -1
  44. package/dist/css/pkt-base.css +434 -1
  45. package/dist/css/pkt-base.min.css +1 -1
  46. package/dist/css/pkt-components.css +1595 -342
  47. package/dist/css/pkt-components.min.css +1 -1
  48. package/dist/css/pkt-docs.css +2077 -358
  49. package/dist/css/pkt-docs.min.css +1 -1
  50. package/dist/css/pkt-elements.css +160 -16
  51. package/dist/css/pkt-elements.min.css +1 -1
  52. package/dist/css/pkt.css +2077 -358
  53. package/dist/css/pkt.min.css +1 -1
  54. package/dist/scss/abstracts/variables/_index.scss +1 -1
  55. package/dist/scss/abstracts/variables/_spacing.scss +1 -0
  56. package/dist/scss/components/_accordion.scss +7 -11
  57. package/dist/scss/components/_alert.scss +34 -4
  58. package/dist/scss/components/_calendar.scss +3 -0
  59. package/dist/scss/components/_combobox.scss +74 -0
  60. package/dist/scss/components/_datepicker.scss +75 -8
  61. package/dist/scss/components/_footer.scss +149 -123
  62. package/dist/scss/components/_header-global.scss +192 -0
  63. package/dist/scss/components/_header-menu.scss +30 -31
  64. package/dist/scss/components/_header-service-mobile.scss +4 -28
  65. package/dist/scss/components/_header-service.scss +4 -21
  66. package/dist/scss/components/_header-shared.scss +190 -0
  67. package/dist/scss/components/_index.scss +2 -0
  68. package/dist/scss/components/_inputwrapper.scss +62 -6
  69. package/dist/scss/components/_modal.scss +1 -5
  70. package/dist/scss/components/_searchinput.scss +58 -2
  71. package/dist/scss/components/_textarea.scss +48 -0
  72. package/dist/scss/components/_timepicker.scss +95 -34
  73. package/dist/scss/elements/_button.scss +12 -3
  74. package/dist/scss/elements/_input.scss +141 -7
  75. package/package.json +3 -3
@@ -43,7 +43,7 @@ pkt-input-wrapper {
43
43
  &__helptext-container {
44
44
  display: flex;
45
45
  flex-direction: column;
46
- gap: map.get(variables.$spacing, 'size-4');
46
+ gap: map.get(variables.$spacing, 'size-8');
47
47
  }
48
48
  &__helptext {
49
49
  width: min(100%, 31rem);
@@ -71,6 +71,11 @@ pkt-input-wrapper {
71
71
  }
72
72
 
73
73
  &-expandable {
74
+ display: flex;
75
+ flex-direction: column;
76
+ align-items: flex-start;
77
+ gap: map.get(variables.$spacing, 'size-4');
78
+
74
79
  &-heading {
75
80
  margin: 0;
76
81
  @include typography.get-text('pkt-txt-18-medium');
@@ -80,7 +85,6 @@ pkt-input-wrapper {
80
85
  display: block;
81
86
  border-left: 2px solid var(--pkt-color-text-body-dark);
82
87
  padding: map.get(variables.$spacing, 'size-8') map.get(variables.$spacing, 'size-16');
83
- margin-bottom: map.get(variables.$spacing, 'size-4');
84
88
  }
85
89
 
86
90
  &-closed {
@@ -135,17 +139,32 @@ pkt-input-wrapper {
135
139
  margin-right: 8px;
136
140
  }
137
141
 
138
- // Alert
139
142
  .pkt-alert {
140
143
  width: min(100%, 31rem);
141
144
  margin: 0 0 0.5rem 0;
145
+ }
146
+
147
+ // Alert — stretch to match field width (fieldset uses align-items: flex-start)
148
+ &__alert-wrapper {
149
+ align-self: stretch;
150
+ max-width: min(100%, 31rem);
142
151
 
143
- &--error {
144
- margin: 0.5rem 0 0.5rem 0;
152
+ .pkt-alert {
153
+ width: 100%;
154
+ margin: 0;
145
155
  }
146
156
  }
147
157
 
148
- // Tag
158
+ &:has(.pkt-input--fullwidth) &__alert-wrapper {
159
+ max-width: none;
160
+ }
161
+
162
+ &__fieldset > .pkt-alert {
163
+ align-self: stretch;
164
+ width: auto;
165
+ max-width: min(100%, 31rem);
166
+ }
167
+
149
168
  .pkt-tag {
150
169
  margin-left: 8px;
151
170
  }
@@ -212,6 +231,43 @@ pkt-input-wrapper {
212
231
  outline: none;
213
232
  }
214
233
  }
234
+
235
+ // medium = base styles above; only compact sizes get modifier classes
236
+ &--small,
237
+ &--xsmall {
238
+ .pkt-inputwrapper__helptext-container {
239
+ gap: map.get(variables.$spacing, 'size-4');
240
+ }
241
+
242
+ .pkt-inputwrapper__helptext,
243
+ .pkt-inputwrapper__helptext > .pkt-btn,
244
+ .pkt-inputwrapper__helptext-expandable .pkt-btn {
245
+ @include typography.get-text('pkt-txt-12-light');
246
+ }
247
+
248
+ .pkt-inputwrapper__helptext-expandable-heading {
249
+ @include typography.get-text('pkt-txt-16-medium');
250
+ }
251
+
252
+ .pkt-inputwrapper__fieldset {
253
+ gap: map.get(variables.$spacing, 'size-4');
254
+ }
255
+ }
256
+
257
+ &--small {
258
+ .pkt-inputwrapper__label,
259
+ .pkt-inputwrapper__legend {
260
+ @include typography.get-text('pkt-txt-16-medium');
261
+ }
262
+ }
263
+
264
+ // xsmall: wrapper chrome only — field scale lives on .pkt-input--xsmall / .pkt-combobox__input--xsmall
265
+ &--xsmall {
266
+ .pkt-inputwrapper__label,
267
+ .pkt-inputwrapper__legend {
268
+ @include typography.get-text('pkt-txt-14-medium');
269
+ }
270
+ }
215
271
  }
216
272
 
217
273
  [data-mode='dark'] .pkt-inputwrapper {
@@ -236,11 +236,7 @@ $pkt-modal-padding-sides: map.get(variables.$spacing, 'size-40');
236
236
  }
237
237
  }
238
238
 
239
- // Prevent scroll when modal is open
240
- body.pkt-modal--open {
241
- overflow: hidden;
242
- scrollbar-gutter: stable;
243
- }
239
+ // Scroll lock removed from here. Is now shared with other components through shared-utils
244
240
 
245
241
  // SIZES
246
242
  .pkt-modal--small {
@@ -1,4 +1,3 @@
1
- /* Common styles for all inputs */
2
1
  @use 'sass:map';
3
2
  @use '../abstracts/variables';
4
3
  @use '../abstracts/functions';
@@ -9,9 +8,49 @@
9
8
 
10
9
  @include typography.get-text('pkt-txt-18-light');
11
10
 
11
+ &--small {
12
+ @include typography.get-text('pkt-txt-16-light');
13
+
14
+ .pkt-inputwrapper__label {
15
+ @include typography.get-text('pkt-txt-16-medium');
16
+ }
17
+
18
+ .pkt-searchinput__suggestion {
19
+ padding: 0.75rem;
20
+ @include typography.get-text('pkt-txt-16-light');
21
+ }
22
+
23
+ .pkt-searchinput__suggestion-title {
24
+ @include typography.get-text('pkt-txt-16-medium');
25
+ }
26
+ }
27
+
28
+ &--xsmall {
29
+ @include typography.get-text('pkt-txt-14-light');
30
+
31
+ .pkt-inputwrapper__label {
32
+ @include typography.get-text('pkt-txt-14-medium');
33
+ }
34
+
35
+ .pkt-searchinput__suggestion {
36
+ padding: 0.5rem;
37
+ @include typography.get-text('pkt-txt-14-light');
38
+ }
39
+
40
+ .pkt-searchinput__suggestion-title {
41
+ @include typography.get-text('pkt-txt-14-medium');
42
+ }
43
+ }
44
+
12
45
  &__field {
13
46
  width: min(100%, 31rem);
14
47
  display: flex;
48
+ align-items: stretch;
49
+
50
+ .pkt-input {
51
+ flex: 1;
52
+ min-width: 0;
53
+ }
15
54
  }
16
55
 
17
56
  &--fullwidth &__field {
@@ -35,10 +74,15 @@
35
74
  gap: 0.5rem;
36
75
  }
37
76
 
38
- &--local .pkt-input {
77
+ &--local .pkt-input__container--medium .pkt-input {
39
78
  padding: 0.5rem 0 0.5rem 1rem;
40
79
  }
41
80
 
81
+ &--local .pkt-input__container--small .pkt-input,
82
+ &--local .pkt-input__container--xsmall .pkt-input {
83
+ padding-right: 0;
84
+ }
85
+
42
86
  &--local &__button {
43
87
  &:disabled {
44
88
  border-color: var(--pkt-color-input-border-disabled);
@@ -64,9 +108,21 @@
64
108
  &--global &__suggestions {
65
109
  width: min(calc(100% - 3rem), 28rem);
66
110
  }
111
+ &--global.pkt-searchinput--small &__suggestions {
112
+ width: min(calc(100% - 2.625rem), 28rem);
113
+ }
114
+ &--global.pkt-searchinput--xsmall &__suggestions {
115
+ width: min(calc(100% - 2.25rem), 28rem);
116
+ }
67
117
  &--local-with-button &__suggestions {
68
118
  width: min(calc(100% - 3.5rem), 27.5rem);
69
119
  }
120
+ &--local-with-button.pkt-searchinput--small &__suggestions {
121
+ width: min(calc(100% - 3.125rem), 27.5rem);
122
+ }
123
+ &--local-with-button.pkt-searchinput--xsmall &__suggestions {
124
+ width: min(calc(100% - 2.75rem), 27.5rem);
125
+ }
70
126
  &--fullwidth &__suggestions {
71
127
  width: 100%;
72
128
  }
@@ -0,0 +1,48 @@
1
+ /*
2
+ * Textarea component
3
+ *
4
+ * Base field styles (border, states, min-height) live in _input.scss on .pkt-input:is(textarea).
5
+ * Wrapper label/helptext scale lives in _inputwrapper.scss (--small / --xsmall).
6
+ * Counter stays in normal flow below the field for all sizes (see textarea.astro).
7
+ */
8
+ @use 'sass:map';
9
+ @use '../abstracts/variables';
10
+ @use '../abstracts/mixins/typography';
11
+
12
+ // Match textinput: cap at 31rem; field fills the wrapper.
13
+ // React: .pkt-inputwrapper is the outer box. Elements: pkt-textarea is the flex child and
14
+ // shrink-wraps unless capped here — inner .pkt-inputwrapper width: 100% then resolves correctly.
15
+ pkt-textarea:not([fullwidth]):has(textarea.pkt-input:not([cols])) {
16
+ width: min(31rem, 100%);
17
+ }
18
+
19
+ pkt-textarea[fullwidth] {
20
+ width: 100%;
21
+ }
22
+
23
+ .pkt-inputwrapper:has(textarea.pkt-input:not(.pkt-input--fullwidth):not([cols])) {
24
+ width: min(31rem, 100%);
25
+ }
26
+
27
+ .pkt-inputwrapper:has(textarea.pkt-input--fullwidth) {
28
+ width: 100%;
29
+ }
30
+
31
+ textarea.pkt-input {
32
+ &:not(.pkt-input--fullwidth):not([cols]) {
33
+ width: 100%;
34
+ }
35
+
36
+ &--small,
37
+ &--xsmall {
38
+ padding: map.get(variables.$spacing, 'size-8') map.get(variables.$spacing, 'size-16');
39
+ }
40
+
41
+ &--small {
42
+ @include typography.get-text('pkt-txt-16-light');
43
+ }
44
+
45
+ &--xsmall {
46
+ @include typography.get-text('pkt-txt-14-light');
47
+ }
48
+ }
@@ -1,13 +1,39 @@
1
1
  /* Component: pkt-timepicker */
2
2
 
3
- @use 'sass:map';
4
- @use '../abstracts/variables';
5
3
  @use '../abstracts/mixins/typography';
6
4
 
7
5
  pkt-timepicker {
8
6
  display: block;
9
7
  }
10
8
 
9
+ /// Size overrides for small / xsmall. Base .pkt-input__container styles use medium (48px).
10
+ @mixin timepicker-field-size($min-height, $text-style, $icon-size, $padding-inline: 0.5rem) {
11
+ .pkt-input__container {
12
+ min-height: $min-height;
13
+
14
+ .pkt-timepicker__input,
15
+ .pkt-timepicker__separator {
16
+ @include typography.get-text($text-style);
17
+ }
18
+
19
+ button.pkt-timepicker__button {
20
+ padding: 0 $padding-inline;
21
+
22
+ pkt-icon,
23
+ .pkt-icon,
24
+ svg {
25
+ width: $icon-size;
26
+ height: $icon-size;
27
+ }
28
+ }
29
+
30
+ .pkt-timepicker__icon {
31
+ padding: 0 $padding-inline 0 0;
32
+ height: $icon-size;
33
+ }
34
+ }
35
+ }
36
+
11
37
  .pkt-timepicker,
12
38
  pkt-timepicker {
13
39
  &__anchor {
@@ -15,35 +41,43 @@ pkt-timepicker {
15
41
  }
16
42
 
17
43
  .pkt-input__container {
44
+ min-height: 3rem;
45
+ align-items: center;
18
46
  border: 2px solid var(--pkt-color-input-border-normal);
19
47
  background-color: var(--pkt-color-input-background-normal);
20
48
  width: fit-content;
21
49
  padding: 0 0 0 1rem;
22
50
 
51
+ // Composite layout: one bordered row, segments without individual borders/heights.
52
+ .pkt-timepicker__input,
53
+ .pkt-timepicker__separator,
54
+ .pkt-input-icon,
55
+ .pkt-timepicker__button {
56
+ border: 0;
57
+ height: auto;
58
+ min-height: 0;
59
+ padding-top: 0;
60
+ padding-bottom: 0;
61
+ flex: 0 0 auto;
62
+ }
63
+
23
64
  .pkt-input,
24
65
  .pkt-input-icon,
25
66
  .pkt-input-separator {
26
67
  border: 0;
27
- min-height: auto;
28
68
  }
29
69
 
30
- &:hover {
31
- border-color: var(--pkt-color-input-border-active);
70
+ .pkt-timepicker__input,
71
+ .pkt-timepicker__separator {
72
+ @include typography.get-text('pkt-txt-18-light');
32
73
  }
33
74
 
34
- &:focus-within {
35
- border-color: var(--pkt-color-input-border-active);
36
- outline: 2px solid var(--pkt-color-input-border-active);
75
+ .pkt-timepicker__input {
76
+ padding-inline: 0;
37
77
  }
38
78
 
39
- &:has(input:disabled) {
40
- border-color: var(--pkt-color-input-border-disabled);
41
- background-color: var(--pkt-color-surface-default-gray);
42
-
43
- .pkt-timepicker__icon,
44
- .pkt-timepicker__button {
45
- --fg-color: var(--pkt-color-input-text-disabled);
46
- }
79
+ .pkt-timepicker__separator {
80
+ padding: 0;
47
81
  }
48
82
 
49
83
  button.pkt-timepicker__button {
@@ -51,7 +85,8 @@ pkt-timepicker {
51
85
  padding: 0 0.75rem;
52
86
 
53
87
  pkt-icon,
54
- .pkt-icon {
88
+ .pkt-icon,
89
+ svg {
55
90
  width: 1.5rem;
56
91
  height: 1.5rem;
57
92
  }
@@ -70,6 +105,49 @@ pkt-timepicker {
70
105
  margin-left: 0.25rem;
71
106
  }
72
107
  }
108
+
109
+ .pkt-timepicker__icon {
110
+ align-self: center;
111
+ pointer-events: none;
112
+ padding: 0 0.75rem 0 0;
113
+ height: 1.5rem;
114
+ width: -webkit-min-content;
115
+ width: -moz-min-content;
116
+ width: min-content;
117
+
118
+ > svg,
119
+ svg {
120
+ width: 100%;
121
+ height: 100%;
122
+ }
123
+ }
124
+
125
+ &:hover {
126
+ border-color: var(--pkt-color-input-border-active);
127
+ }
128
+
129
+ &:focus-within {
130
+ border-color: var(--pkt-color-input-border-active);
131
+ outline: 2px solid var(--pkt-color-input-border-active);
132
+ }
133
+
134
+ &:has(input:disabled) {
135
+ border-color: var(--pkt-color-input-border-disabled);
136
+ background-color: var(--pkt-color-surface-default-gray);
137
+
138
+ .pkt-timepicker__icon,
139
+ .pkt-timepicker__button {
140
+ --fg-color: var(--pkt-color-input-text-disabled);
141
+ }
142
+ }
143
+ }
144
+
145
+ &--small {
146
+ @include timepicker-field-size(2.625rem, 'pkt-txt-16-light', 1.25rem);
147
+ }
148
+
149
+ &--xsmall {
150
+ @include timepicker-field-size(2.25rem, 'pkt-txt-14-light', 1.125rem);
73
151
  }
74
152
 
75
153
  // Stepper variant: no left padding — the prev button takes that space
@@ -77,7 +155,6 @@ pkt-timepicker {
77
155
  padding-left: 0;
78
156
  }
79
157
 
80
- // Fullwidth modifier
81
158
  &--fullwidth {
82
159
  .pkt-timepicker__anchor,
83
160
  .pkt-input__container {
@@ -137,7 +214,6 @@ pkt-timepicker {
137
214
  &__input {
138
215
  width: 1.5rem;
139
216
  text-align: center;
140
- padding: 0.5rem 0;
141
217
 
142
218
  &::-webkit-inner-spin-button,
143
219
  &::-webkit-outer-spin-button {
@@ -150,24 +226,9 @@ pkt-timepicker {
150
226
  }
151
227
 
152
228
  &__separator {
153
- @include typography.get-text('pkt-txt-18');
154
-
155
- padding: 0.25rem 0 0.5rem;
156
229
  user-select: none;
157
230
  }
158
231
 
159
- &__icon {
160
- height: auto;
161
- padding: 0 0.75rem 0 0;
162
- pointer-events: none;
163
-
164
- pkt-icon,
165
- .pkt-icon {
166
- width: 1.5rem;
167
- height: 1.5rem;
168
- }
169
- }
170
-
171
232
  &-popup {
172
233
  position: absolute;
173
234
  top: 100%;
@@ -1,6 +1,6 @@
1
1
  /* Button element!
2
2
  *
3
- * Size: small, medium, large
3
+ * Size: xsmall, small, medium, large
4
4
  * Skin: primary, secondary, tertiary
5
5
  * State: normal, focus, hover, active, disabled
6
6
  * Variant: label-only, icon-left, icon-right, icon-only
@@ -23,14 +23,23 @@ $-sizes: (
23
23
  'height': 3rem,
24
24
  'line-height': 1.1,
25
25
  ),
26
- 'small': (
26
+ 'xsmall': (
27
27
  'text-class': 'pkt-txt-14-medium',
28
- 'padding': 0 0.5rem,
28
+ 'padding': 0 0.75rem,
29
+ 'padding-icon-only': 0 0.4375rem,
30
+ 'icon-size': 1.125rem,
31
+ 'height': 2.25rem,
32
+ 'line-height': 1.1,
33
+ ),
34
+ 'small': (
35
+ 'text-class': 'pkt-txt-16-medium',
36
+ 'padding': 0 1rem,
29
37
  'padding-icon-only': 0 0.5625rem,
30
38
  'icon-size': 1.25rem,
31
39
  'height': 2.625rem,
32
40
  'line-height': 1.1,
33
41
  ),
42
+
34
43
  'large': (
35
44
  'text-class': 'pkt-txt-24-medium',
36
45
  'padding': 0 1rem,
@@ -20,11 +20,34 @@ pkt-select {
20
20
  color: var(--pkt-color-input-text-normal);
21
21
  margin: 0;
22
22
  padding: 0.5rem 1rem;
23
+ min-height: 3rem;
23
24
 
24
25
  @include typography.get-text('pkt-txt-18-light');
25
26
 
26
- &:not(&-compact) {
27
- min-height: 3rem;
27
+ &--small:not(:is(textarea, .pkt-timepicker__input, .pkt-datepicker__input)) {
28
+ min-height: 2.625rem;
29
+ padding: map.get(variables.$spacing, 'size-6') map.get(variables.$spacing, 'size-16');
30
+ @include typography.get-text('pkt-txt-16-light');
31
+
32
+ &:not(select[multiple]) {
33
+ height: 2.625rem;
34
+ }
35
+ }
36
+
37
+ &--xsmall:not(:is(textarea, .pkt-timepicker__input, .pkt-datepicker__input)) {
38
+ min-height: 2.25rem;
39
+ padding: map.get(variables.$spacing, 'size-4') map.get(variables.$spacing, 'size-12');
40
+ @include typography.get-text('pkt-txt-14-light');
41
+
42
+ &:not(select[multiple]) {
43
+ height: 2.25rem;
44
+ }
45
+ }
46
+
47
+ // Native inputs should not use flex layout (breaks composite prefix/suffix rows)
48
+ input.pkt-input,
49
+ select.pkt-input {
50
+ display: block;
28
51
  }
29
52
 
30
53
  &-compact#{&} {
@@ -38,7 +61,11 @@ pkt-select {
38
61
  }
39
62
  }
40
63
 
41
- &:not(textarea[cols]):not(input[size]):not(&--fullwidth):not(.pkt-datepicker__input:not(.pkt-datepicker--multiple)),
64
+ // Default field width cap (31rem). Exclusions:
65
+ // - textarea: width set in _textarea.scss (needs wrapper/host, not this rule)
66
+ // - [cols]: native HTML width; browser sizes from character count — do not override
67
+ // - input[size]: same escape hatch for text inputs
68
+ &:not(:is(textarea)):not(input[size]):not(&--fullwidth):not(.pkt-datepicker__input:not(.pkt-datepicker--multiple)),
42
69
  &__container:not(:is(:has(.pkt-datepicker__input:not(.pkt-datepicker--multiple)))):not(:is(:has(textarea[cols]))):not(
43
70
  :is(:has(input[size]))
44
71
  ):not(:is(:has(&--fullwidth))):not(:is(:has(.pkt-timepicker__input))) {
@@ -60,8 +87,9 @@ pkt-select {
60
87
  width: 100%;
61
88
  }
62
89
 
63
- &:is(textarea) {
64
- min-height: map.get(variables.$spacing, 'size-128');
90
+ // Med rows-attributt styrer rows høyden alene
91
+ &:is(textarea:not([rows])) {
92
+ min-height: map.get(variables.$spacing, 'size-148');
65
93
  }
66
94
 
67
95
  &:is(select) {
@@ -78,6 +106,25 @@ pkt-select {
78
106
  background-size:
79
107
  1.5rem auto,
80
108
  100%;
109
+
110
+ // Nestet her for å vinne over @extend-utvidede baseselektorer (f.eks. .pkt-select select)
111
+ &.pkt-input--small {
112
+ background-size:
113
+ 1.25rem auto,
114
+ 100%;
115
+ background-position: right 0.5rem top 50%;
116
+ padding: map.get(variables.$spacing, 'size-6') 2.5rem map.get(variables.$spacing, 'size-6')
117
+ map.get(variables.$spacing, 'size-16');
118
+ }
119
+
120
+ &.pkt-input--xsmall {
121
+ background-size:
122
+ 1.125rem auto,
123
+ 100%;
124
+ background-position: right 0.5rem top 50%;
125
+ padding: map.get(variables.$spacing, 'size-4') 2.25rem map.get(variables.$spacing, 'size-4')
126
+ map.get(variables.$spacing, 'size-12');
127
+ }
81
128
  }
82
129
 
83
130
  option {
@@ -93,7 +140,6 @@ pkt-select {
93
140
  opacity: 1; // 1
94
141
  }
95
142
 
96
- // states
97
143
  &:hover,
98
144
  &.pkt-input--hover {
99
145
  border-color: var(--pkt-color-input-border-hover);
@@ -196,6 +242,95 @@ pkt-select {
196
242
  padding: 0.5rem 0;
197
243
  }
198
244
 
245
+ // Composite fields (prefix / suffix): size the row as one unit — do not fix height on each child
246
+ &__container--small {
247
+ align-items: stretch;
248
+
249
+ .pkt-input-prefix,
250
+ .pkt-input-suffix,
251
+ .pkt-input-icon {
252
+ height: auto;
253
+ min-height: 2.625rem;
254
+ @include typography.get-text('pkt-txt-16-light');
255
+ }
256
+
257
+ .pkt-input-prefix {
258
+ padding: map.get(variables.$spacing, 'size-6') 0 map.get(variables.$spacing, 'size-6')
259
+ map.get(variables.$spacing, 'size-16');
260
+ }
261
+
262
+ .pkt-input-suffix {
263
+ padding: map.get(variables.$spacing, 'size-6') map.get(variables.$spacing, 'size-16')
264
+ map.get(variables.$spacing, 'size-6') 0;
265
+ }
266
+
267
+ input.pkt-input,
268
+ select.pkt-input {
269
+ height: auto;
270
+ min-height: 2.625rem;
271
+ flex: 1 1 auto;
272
+ min-width: 0;
273
+ padding: map.get(variables.$spacing, 'size-6') map.get(variables.$spacing, 'size-16');
274
+ @include typography.get-text('pkt-txt-16-light');
275
+ }
276
+
277
+ .pkt-input-icon svg,
278
+ .pkt-input-suffix svg {
279
+ width: 1.25rem;
280
+ height: 1.25rem;
281
+ }
282
+
283
+ .pkt-input-suffix::before {
284
+ height: 1.25rem;
285
+ }
286
+ }
287
+
288
+ &__container--xsmall {
289
+ align-items: stretch;
290
+
291
+ .pkt-input-prefix,
292
+ .pkt-input-suffix,
293
+ .pkt-input-icon {
294
+ height: auto;
295
+ min-height: 2.25rem;
296
+ @include typography.get-text('pkt-txt-14-light');
297
+ }
298
+
299
+ .pkt-input-prefix {
300
+ padding: map.get(variables.$spacing, 'size-4') 0 map.get(variables.$spacing, 'size-4')
301
+ map.get(variables.$spacing, 'size-12');
302
+ }
303
+
304
+ .pkt-input-suffix {
305
+ padding: map.get(variables.$spacing, 'size-4') map.get(variables.$spacing, 'size-12')
306
+ map.get(variables.$spacing, 'size-4') 0;
307
+ }
308
+
309
+ input.pkt-input,
310
+ select.pkt-input {
311
+ height: auto;
312
+ min-height: 2.25rem;
313
+ flex: 1 1 auto;
314
+ min-width: 0;
315
+ padding: map.get(variables.$spacing, 'size-4') map.get(variables.$spacing, 'size-12');
316
+ @include typography.get-text('pkt-txt-14-light');
317
+ }
318
+
319
+ .pkt-input-icon {
320
+ padding: map.get(variables.$spacing, 'size-4') map.get(variables.$spacing, 'size-8');
321
+ }
322
+
323
+ .pkt-input-icon svg,
324
+ .pkt-input-suffix svg {
325
+ width: 1.125rem;
326
+ height: 1.125rem;
327
+ }
328
+
329
+ .pkt-input-suffix::before {
330
+ height: 1.125rem;
331
+ }
332
+ }
333
+
199
334
  &--counter-error,
200
335
  &--counter-error:focus {
201
336
  border-color: var(--pkt-color-input-border-error);
@@ -233,7 +368,6 @@ pkt-select {
233
368
  margin: 0;
234
369
  }
235
370
 
236
- //states
237
371
  & input:focus {
238
372
  outline: none;
239
373
  box-shadow: none;