@digdir/designsystemet-css 0.0.0-next-20240724125515

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/popover.css ADDED
@@ -0,0 +1,84 @@
1
+ .ds-popover {
2
+ --dsc-popover-border: 1px solid;
3
+ --dsc-popover-background: var(--ds-color-neutral-background-default);
4
+ --dsc-popover-color: var(--ds-color-neutral-text-default);
5
+ --dsc-popover-border-color: var(--ds-color-neutral-border-default);
6
+ --dsc-popover-padding: var(--ds-spacing-3);
7
+ --dsc-popover-max-width: 300px;
8
+ --dsc-popover-border-radius: min(1rem, var(--ds-border-radius-md));
9
+
10
+ z-index: 1500;
11
+ background: var(--dsc-popover-background);
12
+ color: var(--dsc-popover-color);
13
+ padding: var(--dsc-popover-padding);
14
+ border: var(--dsc-popover-border);
15
+ border-radius: var(--dsc-popover-border-radius);
16
+ border-color: var(--dsc-popover-border-color);
17
+ max-width: var(--dsc-popover-max-width);
18
+ }
19
+
20
+ .ds-popover--sm {
21
+ --dsc-popover-padding: var(--ds-spacing-2) var(--ds-spacing-3);
22
+ }
23
+
24
+ .ds-popover--md {
25
+ --dsc-popover-padding: var(--ds-spacing-3) var(--ds-spacing-4);
26
+ }
27
+
28
+ .ds-popover--lg {
29
+ --dsc-popover-padding: var(--ds-spacing-3) var(--ds-spacing-5);
30
+ }
31
+
32
+ .ds-popover--default {
33
+ --dsc-popover-background: var(--ds-color-neutral-background-default);
34
+ --dsc-popover-border-color: var(--ds-color-neutral-border-default);
35
+ --dsc-popover-color: var(--ds-color-neutral-text-default);
36
+ }
37
+
38
+ .ds-popover--info {
39
+ --dsc-popover-background: var(--ds-color-info-surface-default);
40
+ --dsc-popover-border-color: var(--ds-color-info-border-default);
41
+ --dsc-popover-color: var(--ds-color-info-text-default);
42
+ }
43
+
44
+ .ds-popover--warning {
45
+ --dsc-popover-background: var(--ds-color-warning-surface-default);
46
+ --dsc-popover-border-color: var(--ds-color-warning-border-default);
47
+ --dsc-popover-color: var(--ds-color-warning-text-default);
48
+ }
49
+
50
+ .ds-popover--danger {
51
+ --dsc-popover-background: var(--ds-color-danger-surface-default);
52
+ --dsc-popover-border-color: var(--ds-color-danger-border-default);
53
+ --dsc-popover-color: var(--ds-color-danger-text-default);
54
+ }
55
+
56
+ .ds-popover__arrow {
57
+ position: absolute;
58
+ background: var(--dsc-popover-background);
59
+ transform: rotate(45deg);
60
+ }
61
+
62
+ .ds-popover__arrow.ds-popover__arrow--top {
63
+ border-top: var(--dsc-popover-border);
64
+ border-left: var(--dsc-popover-border);
65
+ border-color: inherit;
66
+ }
67
+
68
+ .ds-popover__arrow.ds-popover__arrow--bottom {
69
+ border-bottom: var(--dsc-popover-border);
70
+ border-right: var(--dsc-popover-border);
71
+ border-color: inherit;
72
+ }
73
+
74
+ .ds-popover__arrow.ds-popover__arrow--right {
75
+ border-top: var(--dsc-popover-border);
76
+ border-right: var(--dsc-popover-border);
77
+ border-color: inherit;
78
+ }
79
+
80
+ .ds-popover__arrow.ds-popover__arrow--left {
81
+ border-bottom: var(--dsc-popover-border);
82
+ border-left: var(--dsc-popover-border);
83
+ border-color: inherit;
84
+ }
package/radio.css ADDED
@@ -0,0 +1,182 @@
1
+ .ds-radio {
2
+ --dsc-radio-size: var(--ds-spacing-5);
3
+ --dsc-radio-focus-border-width: 3px;
4
+ --dsc-radio-background: radial-gradient(circle, var(--ds-color-neutral-background-default) 60%, transparent 60%);
5
+ --dsc-radio-border-color: var(--ds-color-neutral-border-default);
6
+ --dsc-radio-border__hover--size: calc(var(--ds-spacing-3) / 2);
7
+ --dsc-radio-border__hover: 0 0 0 var(--dsc-radio-border__hover--size) var(--ds-color-accent-surface-hover);
8
+ --dsc-radio-box_shadow-size: 7px;
9
+
10
+ display: grid;
11
+ }
12
+
13
+ .ds-radio:has(.ds-radio__label) {
14
+ grid-template-columns: var(--dsc-radio-size) auto;
15
+ gap: var(--ds-spacing-2);
16
+ }
17
+
18
+ /* Radio */
19
+ .ds-radio__input {
20
+ position: relative;
21
+ width: var(--dsc-radio-size);
22
+ height: var(--dsc-radio-size);
23
+ z-index: 1;
24
+ appearance: none;
25
+ outline: none;
26
+ cursor: pointer;
27
+ margin: 0;
28
+ align-self: center;
29
+ box-shadow: inset 0 0 0 2px var(--dsc-radio-border-color);
30
+ background: var(--dsc-radio-background);
31
+ border-radius: 50%;
32
+ }
33
+
34
+ .ds-radio__input::before {
35
+ position: absolute;
36
+ content: '';
37
+ display: block;
38
+ width: 2.75rem;
39
+ height: 2.75rem;
40
+ transform: translate(-50%, -50%);
41
+ top: 50%;
42
+ left: 50%;
43
+ cursor: pointer;
44
+ border-radius: var(--ds-border-radius-md);
45
+ }
46
+
47
+ .ds-radio__label {
48
+ /* min-height: var(--ds-sizing-10); */
49
+ min-width: min-content;
50
+ display: inline-flex;
51
+ flex-direction: row;
52
+ gap: var(--ds-spacing-1);
53
+ align-items: center;
54
+ cursor: pointer;
55
+ }
56
+
57
+ .ds-radio__description {
58
+ margin-top: calc(var(--ds-spacing-2) * -1);
59
+ color: var(--ds-color-neutral-text-subtle);
60
+ grid-column: 2;
61
+ }
62
+
63
+ .ds-radio--readonly > .ds-radio__input,
64
+ .ds-radio--readonly > .ds-radio__label,
65
+ .ds-radio--readonly > .ds-radio__input::before {
66
+ cursor: default;
67
+ }
68
+
69
+ .ds-radio:has(.ds-radio__input:disabled) > .ds-radio__description {
70
+ opacity: var(--ds-disabled-opacity);
71
+ }
72
+
73
+ .ds-radio__input:disabled,
74
+ .ds-radio__input:disabled::before,
75
+ .ds-radio:has(.ds-radio__input:disabled) > .ds-radio__label {
76
+ cursor: not-allowed;
77
+ opacity: var(--ds-disabled-opacity);
78
+ }
79
+
80
+ .ds-radio:has(.ds-radio__input:focus-visible) {
81
+ --dsc-focus-border-width: 3px;
82
+
83
+ outline: var(--dsc-focus-border-width) solid var(--ds-color-focus-outer);
84
+ outline-offset: var(--dsc-focus-border-width);
85
+ box-shadow: 0 0 0 var(--dsc-focus-border-width) var(--ds-color-focus-inner);
86
+ border-radius: var(--ds-border-radius-md);
87
+ }
88
+
89
+ .ds-radio__input:checked {
90
+ --dsc-radio-border-color: var(--ds-color-accent-base-default);
91
+ --dsc-radio-background: radial-gradient(circle, var(--ds-color-accent-contrast-1) 60%, transparent 60%);
92
+
93
+ /* We use a gradient to avoid bleeding pixels */
94
+ background: var(--dsc-radio-background);
95
+ }
96
+
97
+ .ds-radio--readonly > .ds-radio__input {
98
+ --dsc-radio-border-color: var(--ds-color-neutral-border-subtle);
99
+ --dsc-radio-background: var(--ds-color-neutral-background-subtle);
100
+ }
101
+
102
+ .ds-radio__input:focus-visible:not(:checked) {
103
+ --dsc-radio-border-color: var(--ds-color-accent-border-strong);
104
+
105
+ box-shadow: inset 0 0 0 2px var(--dsc-radio-border-color);
106
+ }
107
+
108
+ .ds-radio--readonly > .ds-radio__input:checked {
109
+ background: var(--ds-color-neutral-border-strong);
110
+ }
111
+
112
+ .ds-radio--error > .ds-radio__input:not(:disabled, :focus-visible) {
113
+ --dsc-radio-border-color: var(--ds-color-danger-border-default);
114
+ }
115
+
116
+ .ds-radio__input:focus-visible:checked {
117
+ box-shadow: inset 0 0 0 var(--dsc-radio-box_shadow-size) var(--dsc-radio-border-color);
118
+ }
119
+
120
+ .ds-radio__input:checked:not(:focus-visible) {
121
+ box-shadow: inset 0 0 0 var(--dsc-radio-box_shadow-size) var(--dsc-radio-border-color);
122
+ }
123
+
124
+ /* Only use hover for non-touch devices to prevent sticky-hovering
125
+ "input:not(:read-only)" does not work so using ".container:not(.readonly) >" instead */
126
+ @media (hover: hover) and (pointer: fine) {
127
+ .ds-radio:not(.ds-radio--readonly) > .ds-radio__label:hover:not(:disabled),
128
+ .ds-radio:not(.ds-radio--readonly) > .ds-radio__input:hover:not(:disabled) + .ds-radio__label {
129
+ color: var(--ds-color-accent-text-subtle);
130
+ }
131
+
132
+ .ds-radio:not(.ds-radio--readonly) > .ds-radio__input:hover:not(:checked, :disabled, :focus-visible) {
133
+ --dsc-radio-border-color: var(--ds-color-accent-border-strong);
134
+
135
+ box-shadow:
136
+ var(--dsc-radio-border__hover),
137
+ inset 0 0 0 2px var(--dsc-radio-border-color);
138
+ }
139
+
140
+ .ds-radio:not(.ds-radio--readonly) > .ds-radio__input:hover:checked:not(:disabled, :focus-visible) {
141
+ box-shadow:
142
+ var(--dsc-radio-border__hover),
143
+ inset 0 0 0 var(--dsc-radio-box_shadow-size) var(--dsc-radio-border-color);
144
+ }
145
+ }
146
+
147
+ /** Sizing */
148
+
149
+ .ds-radio--sm {
150
+ --dsc-radio-size: var(--ds-sizing-5);
151
+ --dsc-radio-box_shadow-size: 6px;
152
+
153
+ /* min-height: var(--ds-sizing-10); */
154
+ }
155
+
156
+ .ds-radio--md {
157
+ --dsc-radio-size: var(--ds-sizing-6);
158
+ --dsc-radio-border__hover--size: var(--ds-spacing-1);
159
+ --dsc-radio-box_shadow-size: 7px;
160
+
161
+ /* min-height: var(--ds-sizing-11); */
162
+ }
163
+
164
+ .ds-radio--lg {
165
+ --dsc-radio-size: var(--ds-sizing-7);
166
+ --dsc-radio-box_shadow-size: 8px;
167
+
168
+ /* min-height: var(--ds-sizing-12); */
169
+ }
170
+
171
+ .ds-radio-group {
172
+ display: flex;
173
+ flex-direction: column;
174
+ gap: var(--ds-spacing-3);
175
+ width: fit-content;
176
+ }
177
+
178
+ .ds-radio-group--horizontal {
179
+ display: flex;
180
+ flex-direction: row;
181
+ gap: var(--ds-spacing-6);
182
+ }
package/search.css ADDED
@@ -0,0 +1,170 @@
1
+ .ds-search {
2
+ --dsc-search-clear-button-size: var(--ds-sizing-6);
3
+ --dsc-search-input-background: var(--ds-color-neutral-background-default);
4
+ --dsc-search-input-border-color: var(--ds-color-neutral-border-default);
5
+ --dsc-search-input-border: 1px solid var(--dsc-search-input-border-color);
6
+ --dsc-search-input-color: var(--ds-color-neutral-text-default);
7
+
8
+ display: inline-grid;
9
+ width: 100%;
10
+ gap: var(--ds-spacing-2);
11
+ }
12
+
13
+ .ds-search--sm {
14
+ --dsc-search-clear-button-size: var(--ds-sizing-5);
15
+ }
16
+
17
+ .ds-search--md {
18
+ --dsc-search-clear-button-size: var(--ds-sizing-6);
19
+ }
20
+
21
+ .ds-search--lg {
22
+ --dsc-search-clear-button-size: var(--ds-sizing-8);
23
+ }
24
+
25
+ .ds-search__label {
26
+ min-width: min-content;
27
+ display: inline-flex;
28
+ flex-direction: row;
29
+ gap: var(--ds-spacing-1);
30
+ align-items: center;
31
+ }
32
+
33
+ .ds-search__field {
34
+ display: flex;
35
+ width: 100%;
36
+ align-items: stretch;
37
+ border-radius: var(--ds-border-radius-md);
38
+ position: relative;
39
+ }
40
+
41
+ .ds-search__icon {
42
+ position: absolute;
43
+ height: 100%;
44
+ z-index: 2;
45
+ left: var(--ds-spacing-4);
46
+ transform: scale(1.5);
47
+ pointer-events: none;
48
+ }
49
+
50
+ [type='search']::-webkit-search-decoration,
51
+ [type='search']::-webkit-search-cancel-button {
52
+ appearance: none;
53
+ }
54
+
55
+ .ds-search__input {
56
+ background: var(---dsc-search-input-background);
57
+ color: var(--dsc-search-input-color);
58
+ border: var(--dsc-search-input-border);
59
+ border-radius: var(--ds-border-radius-md);
60
+ font-family: inherit;
61
+ position: relative;
62
+ box-sizing: border-box;
63
+ flex: 0 1 auto;
64
+ height: var(--ds-sizing-10);
65
+ width: 100%;
66
+ appearance: none;
67
+ padding: 0 var(--ds-spacing-3);
68
+ }
69
+
70
+ .ds-search__input.ds-search__input--with-search-button {
71
+ border-top-right-radius: 0;
72
+ border-bottom-right-radius: 0;
73
+ }
74
+
75
+ .ds-search__input:disabled {
76
+ cursor: not-allowed;
77
+ }
78
+
79
+ .ds-search__input[type='search']:focus-visible {
80
+ z-index: 1;
81
+ }
82
+
83
+ .ds-search:has(.ds-search__input:disabled) {
84
+ opacity: var(--ds-disabled-opacity);
85
+ }
86
+
87
+ .ds-search__search-button {
88
+ border-top-left-radius: 0;
89
+ border-bottom-left-radius: 0;
90
+ }
91
+
92
+ .ds-search__search-button:not(:focus-visible) {
93
+ border-left: 0;
94
+ }
95
+
96
+ .ds-search__search-button:focus-visible {
97
+ z-index: 1;
98
+ }
99
+
100
+ .ds-search__clear-button {
101
+ color: var(--ds-color-neutral-text-default);
102
+ display: inline-flex;
103
+ align-items: center;
104
+ justify-content: center;
105
+ position: absolute;
106
+ background: none;
107
+ border: none;
108
+ right: 0.6em;
109
+ top: 50%;
110
+ transform: translateY(-50%);
111
+ cursor: pointer;
112
+ height: var(--dsc-search-clear-button-size);
113
+ width: var(--dsc-search-clear-button-size);
114
+ border-radius: var(--ds-border-radius-md);
115
+ font-size: 1.25rem;
116
+ padding: 0;
117
+ z-index: 2;
118
+ }
119
+
120
+ .ds-search--sm .ds-search__input {
121
+ --dsc-search-clear-button-size: var(--ds-sizing-4);
122
+
123
+ height: var(--ds-sizing-10);
124
+ padding: 0 var(--ds-spacing-3);
125
+ padding-right: 2.5em;
126
+ }
127
+
128
+ .ds-search--sm .ds-search__icon {
129
+ left: var(--ds-spacing-3);
130
+ }
131
+
132
+ .ds-search--md .ds-search__input {
133
+ --dsc-search-clear-button-size: var(--ds-sizing-6);
134
+
135
+ height: var(--ds-sizing-12);
136
+ padding: 0 var(--ds-spacing-4);
137
+ padding-right: 2.2em;
138
+ }
139
+
140
+ .ds-search--md .ds-search__icon {
141
+ left: var(--ds-spacing-4);
142
+ }
143
+
144
+ .ds-search--lg .ds-search__input {
145
+ --dsc-search-clear-button-size: var(--ds-sizing-12);
146
+
147
+ height: var(--ds-sizing-14);
148
+ padding: 0 var(--ds-spacing-5);
149
+ padding-right: 2em;
150
+ }
151
+
152
+ .ds-search--lg .ds-search__icon {
153
+ left: var(--ds-spacing-5);
154
+ }
155
+
156
+ .ds-search__input.ds-search__input--simple {
157
+ padding-left: 2.4em;
158
+ }
159
+
160
+ @media (hover: hover) and (pointer: fine) {
161
+ .ds-search__input:not(:focus-visible, :disabled, [aria-disabled]):hover {
162
+ --dsc-search-input-border-color: var(--ds-color-accent-border-strong);
163
+
164
+ box-shadow: inset 0 0 0 1px var(--ds-color-accent-border-strong);
165
+ }
166
+
167
+ .ds-search__clear-button:not(:focus-visible, :disabled, [aria-disabled]):hover {
168
+ background: var(--ds-color-accent-surface-hover);
169
+ }
170
+ }
package/skeleton.css ADDED
@@ -0,0 +1,59 @@
1
+ .ds-skeleton {
2
+ --dsc-skeleton-animation-duration: 0.8s;
3
+ --dsc-skeleton-background: var(--ds-color-neutral-surface-default);
4
+
5
+ height: 1.3em;
6
+ pointer-events: none;
7
+ user-select: none;
8
+ background-color: var(--dsc-skeleton-background);
9
+ animation: ds-skeleton-opacity-fade var(--dsc-skeleton-animation-duration) linear infinite alternate;
10
+ }
11
+
12
+ .ds-skeleton--circle {
13
+ width: 1.3em;
14
+ border-radius: var(--ds-border-radius-full);
15
+ aspect-ratio: 1 / 1;
16
+ }
17
+
18
+ .ds-skeleton--rectangle {
19
+ width: 100%;
20
+ border-radius: min(1rem, var(--ds-border-radius-lg));
21
+ }
22
+
23
+ .ds-skeleton--text {
24
+ width: 100%;
25
+ height: auto;
26
+ transform-origin: 0 55%;
27
+ transform: scale(1, 0.6);
28
+ border-radius: var(--ds-border-radius-full);
29
+ }
30
+
31
+ .ds-skeleton--text:empty::before {
32
+ content: '\00a0';
33
+ }
34
+
35
+ .ds-skeleton--has-children {
36
+ width: fit-content;
37
+ height: fit-content;
38
+ color: transparent !important;
39
+ }
40
+
41
+ .ds-skeleton--has-children > * {
42
+ visibility: hidden;
43
+ }
44
+
45
+ @media (prefers-reduced-motion: reduce) {
46
+ .ds-skeleton {
47
+ --dsc-skeleton-animation-duration: 1.6s;
48
+ }
49
+ }
50
+
51
+ @keyframes ds-skeleton-opacity-fade {
52
+ 0% {
53
+ opacity: 1;
54
+ }
55
+
56
+ 100% {
57
+ opacity: 0.4;
58
+ }
59
+ }
package/skiplink.css ADDED
@@ -0,0 +1,44 @@
1
+ .ds-skiplink:focus {
2
+ display: grid;
3
+ place-items: center;
4
+ outline: 0;
5
+ position: static;
6
+ width: auto;
7
+ height: auto;
8
+ margin: inherit;
9
+ overflow: visible;
10
+ clip: auto;
11
+ clip-path: none;
12
+ white-space: inherit;
13
+ text-decoration: none;
14
+ padding: var(--ds-spacing-3) var(--ds-spacing-4) var(--ds-spacing-3) var(--ds-spacing-6);
15
+ color: var(--ds-color-neutral-text-default);
16
+ background: var(--ds-color-accent-surface-default);
17
+ }
18
+
19
+ .ds-skiplink__content {
20
+ --dsc-skiplink-padding: var(--ds-spacing-2) var(--ds-spacing-4);
21
+ --dsc-skiplink-border-width: 3px;
22
+
23
+ display: flex;
24
+ align-items: center;
25
+ border: var(--ds-border-width-default) solid transparent;
26
+ background-color: transparent;
27
+ color: var(--ds-color-accent-text-subtle);
28
+ border-color: var(--ds-color-accent-border-strong);
29
+ width: fit-content;
30
+ padding: var(--dsc-skiplink-padding);
31
+ margin: var(--ds-spacing-1);
32
+ box-sizing: border-box;
33
+ cursor: pointer;
34
+ font-family: inherit;
35
+ justify-content: center;
36
+ text-align: center;
37
+ text-decoration: none;
38
+ position: relative;
39
+ border-radius: var(--ds-border-radius-md);
40
+ min-height: var(--ds-sizing-10);
41
+ outline: var(--dsc-skiplink-border-width) solid var(--ds-color-focus-outer);
42
+ outline-offset: var(--dsc-skiplink-border-width);
43
+ box-shadow: 0 0 0 var(--dsc-skiplink-border-width) var(--ds-color-focus-inner);
44
+ }
package/spinner.css ADDED
@@ -0,0 +1,69 @@
1
+ .ds-spinner {
2
+ --dsc-spinner-background: var(--ds-color-neutral-surface-default);
3
+ --dsc-spinner-stroke: var(--ds-color-accent-base-default);
4
+
5
+ animation: ds-spinner-rotate-animation linear infinite;
6
+ animation-duration: 2s;
7
+ }
8
+
9
+ .ds-spinner__circle {
10
+ stroke: var(--dsc-spinner-stroke);
11
+ stroke-dasharray: 1px, 200px;
12
+ transform-origin: center;
13
+ animation: ds-spinner-stroke-animation ease-in-out infinite;
14
+ animation-duration: 2s;
15
+ }
16
+
17
+ /* Prefers reduced motion needs longer animation,
18
+ but don't remove it since it is not decorative.
19
+ */
20
+ @media (prefers-reduced-motion: reduce) {
21
+ .ds-spinner {
22
+ animation-duration: 6s;
23
+ }
24
+
25
+ .ds-spinner__circle {
26
+ animation-duration: 6s;
27
+ }
28
+ }
29
+
30
+ .ds-spinner--neutral {
31
+ --dsc-spinner-stroke: var(--ds-color-neutral-border-default);
32
+ }
33
+
34
+ .ds-spinner--accent {
35
+ --dsc-spinner-stroke: var(--ds-color-accent-base-default);
36
+ }
37
+
38
+ .ds-spinner__background {
39
+ stroke: var(--dsc-spinner-background);
40
+ }
41
+
42
+ @keyframes ds-spinner-rotate-animation {
43
+ 0% {
44
+ transform: rotate(0deg);
45
+ }
46
+
47
+ 100% {
48
+ transform: rotate(360deg);
49
+ }
50
+ }
51
+
52
+ @keyframes ds-spinner-stroke-animation {
53
+ 0% {
54
+ stroke-dasharray: 1px, 200px;
55
+ stroke-dashoffset: 0;
56
+ }
57
+
58
+ 50% {
59
+ stroke-dasharray: 100px, 200px;
60
+ stroke-dashoffset: -15px;
61
+ transform: rotate(0deg);
62
+ }
63
+
64
+ 100% {
65
+ stroke-dasharray: 1px, 200px;
66
+ stroke-dashoffset: -120px;
67
+ transform: rotate(15deg);
68
+ }
69
+ }