@dbcdk/react-components 0.0.20 → 0.0.21

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 (40) hide show
  1. package/dist/components/button/Button.module.css +13 -6
  2. package/dist/components/chip/Chip.d.ts +3 -2
  3. package/dist/components/chip/Chip.js +2 -1
  4. package/dist/components/chip/Chip.module.css +107 -67
  5. package/dist/components/filter-field/FilterField.d.ts +2 -1
  6. package/dist/components/filter-field/FilterField.js +4 -9
  7. package/dist/components/filter-field/FilterField.module.css +203 -152
  8. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.d.ts +2 -3
  9. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.js +3 -5
  10. package/dist/components/filtering/chip-multi-toggle/ChipMultiToggle.module.css +13 -13
  11. package/dist/components/forms/input/Input.d.ts +1 -1
  12. package/dist/components/forms/input/Input.js +3 -9
  13. package/dist/components/forms/input/Input.module.css +106 -17
  14. package/dist/components/hyperlink/Hyperlink.module.css +14 -3
  15. package/dist/components/interval-select/IntervalSelect.js +2 -2
  16. package/dist/components/popover/Popover.module.css +4 -1
  17. package/dist/components/segmented-progress-bar/SegmentedProgressBar.d.ts +4 -2
  18. package/dist/components/segmented-progress-bar/SegmentedProgressBar.js +17 -19
  19. package/dist/components/segmented-progress-bar/SegmentedProgressBar.module.css +128 -20
  20. package/dist/components/sidebar/Sidebar.d.ts +2 -1
  21. package/dist/components/sidebar/Sidebar.js +2 -2
  22. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.d.ts +2 -3
  23. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.js +2 -4
  24. package/dist/components/sidebar/components/sidebar-container/SidebarContainer.module.css +2 -1
  25. package/dist/components/table/Table.d.ts +2 -7
  26. package/dist/components/table/Table.js +90 -47
  27. package/dist/components/table/Table.module.css +301 -72
  28. package/dist/components/table/TanstackTable.js +3 -27
  29. package/dist/components/table/table.utils.d.ts +1 -1
  30. package/dist/components/table/table.utils.js +2 -1
  31. package/dist/components/table/tanstackTable.utils.d.ts +9 -10
  32. package/dist/components/table/tanstackTable.utils.js +50 -30
  33. package/dist/hooks/useViewportFill.d.ts +6 -5
  34. package/dist/hooks/useViewportFill.js +43 -41
  35. package/dist/src/styles/styles.css +5 -2
  36. package/dist/styles/styles.css +5 -2
  37. package/dist/styles/themes/dbc/base.css +0 -3
  38. package/dist/styles/themes/dbc/dark.css +44 -12
  39. package/dist/styles/themes/dbc/light.css +33 -7
  40. package/package.json +1 -1
@@ -2,38 +2,157 @@
2
2
  display: inline-flex;
3
3
  align-items: stretch;
4
4
  gap: 0;
5
+ position: relative;
6
+ z-index: 0;
5
7
  font-size: var(--font-size-sm);
6
8
  font-family: var(--font-family);
7
- background: var(--color-bg-surface);
8
9
  color: var(--color-fg-default);
9
-
10
- border: var(--border-width-thin) solid var(--color-border-default);
10
+ border: 1px solid transparent;
11
11
  border-radius: var(--border-radius-default);
12
-
13
- position: relative;
14
-
12
+ overflow: visible;
15
13
  transition:
14
+ background-color var(--transition-fast) var(--ease-standard),
16
15
  border-color var(--transition-fast) var(--ease-standard),
17
16
  box-shadow var(--transition-fast) var(--ease-standard),
18
- background-color var(--transition-fast) var(--ease-standard);
17
+ color var(--transition-fast) var(--ease-standard);
18
+ }
19
+
20
+ /* =========================
21
+ VARIANTS
22
+ ========================= */
23
+
24
+ .filterField.surface {
25
+ background: var(--color-bg-surface);
26
+ border-color: var(--color-border-subtle);
27
+ box-shadow: var(--shadow-xs);
28
+ --filter-operator-bg: var(--color-bg-surface);
29
+ }
30
+
31
+ .filterField.surface:hover {
32
+ border-color: var(--color-border-default);
33
+ box-shadow: var(--shadow-sm);
34
+ }
35
+
36
+ .filterField.surface.active {
37
+ border-color: var(--color-border-default);
38
+ box-shadow: var(--shadow-sm);
39
+ }
40
+
41
+ .filterField.outlined {
42
+ background: var(--color-bg-surface);
43
+ border-color: var(--color-border-subtle);
44
+ box-shadow: none;
45
+ --filter-operator-bg: var(--color-bg-surface);
46
+ }
47
+
48
+ .filterField.outlined:hover {
49
+ border-color: var(--color-border-default);
50
+ }
51
+
52
+ .filterField.outlined.active {
53
+ border-color: var(--color-border-default);
54
+ }
55
+
56
+ .filterField.subtle {
57
+ background: var(--color-bg-toolbar);
58
+ border-color: transparent;
59
+ box-shadow: inset 0 0 0 1px transparent;
60
+ --filter-operator-bg: color-mix(in srgb, var(--color-fg-default) 4%, var(--color-bg-toolbar));
61
+ }
62
+
63
+ .filterField.subtle:hover {
64
+ background: var(--color-bg-surface-strong);
65
+ --filter-operator-bg: color-mix(
66
+ in srgb,
67
+ var(--color-fg-default) 6%,
68
+ var(--color-bg-surface-strong)
69
+ );
70
+ }
71
+
72
+ .filterField.subtle.active {
73
+ background: var(--color-bg-surface-strong);
74
+ --filter-operator-bg: color-mix(
75
+ in srgb,
76
+ var(--color-fg-default) 5%,
77
+ var(--color-bg-surface-strong)
78
+ );
79
+ }
80
+
81
+ /* =========================
82
+ ACTIVE INDICATOR
83
+ ========================= */
84
+
85
+ .filterField.active::before {
86
+ content: '';
87
+ position: absolute;
88
+ inset-inline-start: 0;
89
+ top: 1px;
90
+ bottom: 1px;
91
+ width: 3px;
92
+ border-top-left-radius: inherit;
93
+ border-bottom-left-radius: inherit;
94
+ background: var(--color-border-selected);
95
+ pointer-events: none;
96
+ z-index: 2;
19
97
  }
20
98
 
21
- /* More comfortable active state:
22
- - less "blue outline" noise
23
- - slightly warmer surface hint
24
- */
25
- .filterField.active {
26
- border-color: color-mix(in srgb, var(--color-border-default) 75%, var(--color-border-selected));
27
- background: color-mix(in srgb, var(--color-bg-surface) 96%, var(--color-bg-selected));
99
+ /* =========================
100
+ FOCUS
101
+ ========================= */
102
+
103
+ .filterField:focus-within {
104
+ z-index: 1;
105
+ }
106
+
107
+ .filterField.surface:focus-within,
108
+ .filterField.outlined:focus-within,
109
+ .filterField.subtle:focus-within {
110
+ border-color: var(--color-border-selected);
111
+ }
112
+
113
+ /* subtle focus without inner outline */
114
+ .filterField.surface:focus-within {
115
+ box-shadow: var(--shadow-sm);
116
+ }
117
+
118
+ .filterField.outlined:focus-within,
119
+ .filterField.subtle:focus-within {
120
+ box-shadow: none;
28
121
  }
29
122
 
123
+ /* stronger focus when filter is active */
124
+
125
+ .filterField.surface.active:focus-within {
126
+ box-shadow:
127
+ var(--shadow-sm),
128
+ inset 0 0 0 1px var(--color-border-selected);
129
+ }
130
+
131
+ .filterField.outlined.active:focus-within,
132
+ .filterField.subtle.active:focus-within {
133
+ box-shadow: inset 0 0 0 1px var(--color-border-selected);
134
+ }
135
+
136
+ /* =========================
137
+ SIZES
138
+ ========================= */
139
+
30
140
  .filterField.sm {
31
141
  block-size: var(--component-size-sm);
32
142
  }
143
+
33
144
  .filterField.md {
34
145
  block-size: var(--component-size-md);
35
146
  }
36
147
 
148
+ .filterField.lg {
149
+ block-size: var(--component-size-lg);
150
+ }
151
+
152
+ /* =========================
153
+ LABEL
154
+ ========================= */
155
+
37
156
  .filterField .label {
38
157
  display: inline-flex;
39
158
  align-items: center;
@@ -45,196 +164,128 @@
45
164
  user-select: none;
46
165
  }
47
166
 
48
- /* Operator trigger */
167
+ /* =========================
168
+ OPERATOR
169
+ ========================= */
170
+
49
171
  .filterField .operatorTrigger {
50
172
  display: inline-flex;
51
173
  align-items: center;
52
174
  justify-content: center;
175
+ gap: var(--spacing-xxs);
53
176
  height: 100%;
54
177
  padding-block: var(--spacing-2xs);
55
178
  padding-inline: var(--spacing-sm);
56
- background: var(--opac-bg-default);
179
+
57
180
  color: var(--color-fg-default);
181
+ background: transparent;
58
182
  border: 0;
59
- border-radius: 0;
60
183
  cursor: pointer;
184
+ position: relative;
185
+ z-index: 0;
186
+ font-weight: var(--font-weight-default);
187
+
61
188
  transition:
62
189
  background-color var(--transition-fast) var(--ease-standard),
63
190
  color var(--transition-fast) var(--ease-standard);
64
191
  }
65
- .filterField .operatorTrigger:hover {
66
- background: var(--opac-bg-dark);
192
+
193
+ /* inset operator background */
194
+
195
+ .filterField .operatorTrigger::after {
196
+ content: '';
197
+ position: absolute;
198
+ inset: 1px 0;
199
+ background: var(--filter-operator-bg, transparent);
200
+ pointer-events: none;
201
+ z-index: 0;
202
+ }
203
+
204
+ .filterField .operatorTrigger > * {
205
+ position: relative;
206
+ z-index: 1;
67
207
  }
68
- .filterField .operatorTrigger:focus-visible {
69
- outline: none;
70
- box-shadow: var(--focus-ring);
208
+
209
+ /* =========================
210
+ SEPARATORS
211
+ ========================= */
212
+
213
+ .filterField .operatorTrigger::before {
214
+ content: '';
215
+ position: absolute;
216
+ inset-inline-start: 0;
217
+ top: 8px;
218
+ bottom: 8px;
219
+ width: 1px;
220
+ background: var(--color-border-subtle);
221
+ pointer-events: none;
71
222
  }
223
+
224
+ /* =========================
225
+ DISABLED
226
+ ========================= */
227
+
72
228
  .filterField .operatorTrigger:disabled,
73
229
  .filterField .operatorTrigger[aria-disabled='true'] {
74
230
  cursor: not-allowed;
75
231
  color: var(--color-disabled-fg);
76
- background: var(--color-disabled-bg);
77
- }
78
- .filterField .operatorText {
79
- white-space: nowrap;
80
232
  }
81
233
 
82
- /* When active, operator is less dominant (calmer + more "token"-like) */
83
- .filterField.active .operatorTrigger {
84
- background: transparent;
85
- color: var(--color-fg-muted);
234
+ .filterField.surface .operatorTrigger:disabled,
235
+ .filterField.outlined .operatorTrigger:disabled {
236
+ --filter-operator-bg: var(--color-disabled-bg);
86
237
  }
87
- .filterField.active .operatorTrigger:hover {
88
- background: var(--opac-bg-dark);
89
- color: var(--color-fg-default);
238
+
239
+ .filterField.subtle .operatorTrigger:disabled {
240
+ --filter-operator-bg: color-mix(
241
+ in srgb,
242
+ var(--color-fg-default) 3%,
243
+ var(--color-bg-surface-subtle)
244
+ );
90
245
  }
91
246
 
92
- /* Wrapper for the select / multiselect control */
247
+ /* =========================
248
+ VALUE WRAPPER
249
+ ========================= */
250
+
93
251
  .filterField .valueWrapper {
94
252
  display: inline-flex;
95
253
  align-items: center;
96
254
  padding: 0;
97
255
  height: 100%;
98
-
99
256
  flex: 1;
100
257
  min-width: 0;
258
+ position: relative;
101
259
  }
102
260
 
103
- /* Ensure the control inside can stretch/shrink */
104
261
  .filterField .valueWrapper > * {
105
262
  height: 100%;
106
263
  width: 100%;
107
264
  min-width: 0;
108
265
  }
109
- .filterField .valueWrapper > * > * {
110
- height: 100% !important;
111
- }
112
-
113
- /* Active: emphasize VALUE area (but keep it soft) */
114
- .filterField.active .valueWrapper {
115
- background: color-mix(in srgb, var(--color-bg-surface) 88%, var(--color-bg-selected));
116
- border-left: var(--border-width-thin) solid
117
- color-mix(in srgb, var(--color-border-default) 80%, var(--color-border-selected));
118
- border-top-right-radius: calc(var(--border-radius-default) - 1px);
119
- border-bottom-right-radius: calc(var(--border-radius-default) - 1px);
120
- }
121
-
122
- /* =========================
123
- TRIGGER BUTTON TARGETING
124
- ========================= */
125
266
 
126
- /* Select trigger button */
127
- .filterField .valueWrapper :global(button[data-forminput]) {
128
- width: 100%;
267
+ .filterField .valueWrapper > div {
268
+ display: flex;
269
+ align-items: stretch;
129
270
  height: 100%;
130
- border: 0 !important;
131
-
132
- /* slightly more breathing room than before */
133
- padding-inline: calc(var(--spacing-sm) + var(--spacing-2xs)) !important;
134
-
135
- text-align: left;
136
- justify-content: flex-start;
137
- }
138
-
139
- /* MultiSelect trigger button (Popover container is a div; trigger is its direct child button) */
140
- .filterField .valueWrapper > div > button {
141
271
  width: 100%;
142
- height: 100%;
143
- border: 0 !important;
144
- padding-inline: calc(var(--spacing-sm) + var(--spacing-2xs)) !important;
145
-
146
- text-align: left;
147
- justify-content: flex-start;
148
- }
149
-
150
- /* Slight spacing between clear (×) and chevron for Select + MultiSelect
151
- (feels less cramped / more intentional) */
152
- .filterField .valueWrapper :global(button[data-forminput]) :global(.dbc-flex),
153
- .filterField .valueWrapper > div > button {
154
- column-gap: var(--spacing-xs);
155
- }
156
-
157
- /* Make the internal Select layout behave */
158
- .filterField .valueWrapper :global(.dbc-flex) {
159
- width: 100% !important;
160
- min-width: 0;
161
- }
162
-
163
- .filterField .valueWrapper :global(.dbc-flex > span:first-child) {
164
- flex: 1;
165
- min-width: 0;
166
- overflow: hidden;
167
- text-overflow: ellipsis;
168
- white-space: nowrap;
169
- }
170
-
171
- /* Keep ClearButton + chevron from stretching */
172
- .filterField .valueWrapper :global(.dbc-flex) > *:not(span:first-child) {
173
- flex: 0 0 auto;
174
- }
175
-
176
- /* For MultiSelect: label + chip should truncate nicely */
177
- .filterField .valueWrapper > div > button > span:first-child {
178
- display: inline-flex;
179
- align-items: center;
180
- gap: var(--spacing-xxs);
181
-
182
- flex: 1;
183
272
  min-width: 0;
184
- overflow: hidden;
185
- text-overflow: ellipsis;
186
- white-space: nowrap;
187
273
  }
188
274
 
189
- /* Emphasize chosen value text in active state (but slightly less "boldy") */
190
- .filterField.active .valueWrapper input {
191
- font-weight: 550;
192
- }
193
- .filterField.active .valueWrapper :global(button[data-forminput]),
194
- .filterField.active .valueWrapper > div > button {
195
- font-weight: 550 !important;
196
- }
275
+ /* subtle highlight when active */
197
276
 
198
- /* Icons calmer by default; crisp on hover/focus */
199
- .filterField.active .valueWrapper svg {
200
- opacity: 0.72;
201
- }
202
- .filterField.active .valueWrapper:hover svg,
203
- .filterField.active .valueWrapper :global(button[data-forminput]):focus-visible svg,
204
- .filterField.active .valueWrapper > div > button:focus-visible svg {
205
- opacity: 1;
277
+ .filterField.active .valueWrapper {
278
+ box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--color-border-selected) 18%, transparent);
206
279
  }
207
280
 
208
281
  /* =========================
209
- INPUT styling
282
+ TEXT
210
283
  ========================= */
211
284
 
212
- .filterField input {
213
- appearance: none;
214
- border: 0;
215
- outline: none;
216
- background: transparent;
217
- color: var(--color-fg-default);
218
- font: inherit;
219
- inline-size: auto;
220
- min-inline-size: 10ch;
221
- block-size: 100%;
222
- border-top-left-radius: 0;
223
- border-bottom-left-radius: 0;
224
-
225
- /* a tiny bit more comfort */
226
- padding-block: var(--spacing-3xs);
227
- }
228
-
229
- .filterField button {
230
- border-radius: 0;
285
+ .filterField .operatorText {
286
+ white-space: nowrap;
231
287
  }
232
288
 
233
289
  .filterField input::placeholder {
234
- color: var(--color-fg-muted);
235
- }
236
-
237
- .filterField input:disabled {
238
- color: var(--color-disabled-fg);
239
- cursor: not-allowed;
290
+ color: var(--color-fg-subtle);
240
291
  }
@@ -6,7 +6,6 @@ interface ChipToggleOption {
6
6
  icon?: React.ReactNode;
7
7
  }
8
8
  interface ChipMultiToggleProps {
9
- /** Optional group label (e.g. "Fejlede i") */
10
9
  label?: string;
11
10
  options: ChipToggleOption[];
12
11
  selectedValues: string[];
@@ -17,11 +16,11 @@ interface ChipMultiToggleProps {
17
16
  unselectedSeverity?: 'neutral' | 'info' | 'success' | 'warning' | 'danger' | null;
18
17
  fullWidth?: boolean;
19
18
  disabled?: boolean;
20
- showSelectedIcon?: boolean;
21
19
  showAllOption?: boolean;
22
20
  allLabel?: string;
23
21
  allIcon?: React.ReactNode;
24
22
  dataCy?: string;
23
+ type?: 'default' | 'outlined' | 'subtle' | 'rounded';
25
24
  /**
26
25
  * If true, clicking "All" toggles between:
27
26
  * - All (no filtering) => []
@@ -34,5 +33,5 @@ interface ChipMultiToggleProps {
34
33
  */
35
34
  noneValue?: string;
36
35
  }
37
- export declare function ChipMultiToggle({ label, options, selectedValues, onChange, onToggle, size, selectedSeverity, unselectedSeverity, fullWidth, disabled, showAllOption, allLabel, allIcon, showSelectedIcon, allTogglesNone, noneValue, dataCy, }: ChipMultiToggleProps): JSX.Element;
36
+ export declare function ChipMultiToggle({ label, options, selectedValues, onChange, onToggle, size, fullWidth, disabled, showAllOption, allLabel, allIcon, allTogglesNone, noneValue, type, dataCy, }: ChipMultiToggleProps): JSX.Element;
38
37
  export {};
@@ -1,10 +1,9 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Check } from 'lucide-react';
4
3
  import React from 'react';
5
4
  import { Chip } from '../../../components/chip/Chip';
6
5
  import styles from './ChipMultiToggle.module.css';
7
- export function ChipMultiToggle({ label, options, selectedValues = [], onChange, onToggle, size = 'sm', selectedSeverity = 'info', unselectedSeverity = null, fullWidth = false, disabled = false, showAllOption = false, allLabel = 'Alle', allIcon, showSelectedIcon = false, allTogglesNone = false, noneValue = '__none__', dataCy, }) {
6
+ export function ChipMultiToggle({ label, options, selectedValues = [], onChange, onToggle, size = 'sm', fullWidth = false, disabled = false, showAllOption = false, allLabel = 'Alle', allIcon, allTogglesNone = false, noneValue = '__none__', type = 'subtle', dataCy, }) {
8
7
  const selectedSet = React.useMemo(() => new Set(selectedValues), [selectedValues]);
9
8
  const isNoneSelected = allTogglesNone && selectedSet.has(noneValue);
10
9
  const isAllSelected = showAllOption && !isNoneSelected && selectedSet.size === 0;
@@ -28,7 +27,6 @@ export function ChipMultiToggle({ label, options, selectedValues = [], onChange,
28
27
  if (disabled)
29
28
  return;
30
29
  if (!allTogglesNone) {
31
- // Classic "All" = clear selection
32
30
  onChange([]);
33
31
  return;
34
32
  }
@@ -46,9 +44,9 @@ export function ChipMultiToggle({ label, options, selectedValues = [], onChange,
46
44
  onChange([]);
47
45
  }
48
46
  };
49
- return (_jsxs("div", { className: `${styles.wrapper} ${fullWidth ? styles.fullWidth : ''}`, "data-cy": dataCy, children: [label && _jsx("span", { className: styles.label, children: label }), _jsxs("div", { className: styles.container, children: [showAllOption && (_jsx("button", { type: "button", className: styles.chipButton, onClick: toggleAll, "aria-pressed": isAllSelected || isNoneSelected, disabled: disabled, children: _jsx(Chip, { size: size, severity: (isAllSelected || isNoneSelected ? selectedSeverity : unselectedSeverity), customIcon: allIcon, type: unselectedSeverity === null ? 'outlined' : 'rounded', children: isNoneSelected ? `${allLabel} (ingen)` : allLabel }) }, "__all__")), options.map(opt => {
47
+ return (_jsxs("div", { className: `${styles.wrapper} ${fullWidth ? styles.fullWidth : ''}`, "data-cy": dataCy, children: [label && _jsx("span", { className: styles.label, children: label }), _jsxs("div", { className: styles.container, children: [showAllOption && (_jsx("button", { type: "button", className: styles.chipButton, onClick: toggleAll, "aria-pressed": isAllSelected || isNoneSelected, disabled: disabled, children: _jsx(Chip, { type: type, size: size, severity: null, customIcon: allIcon, selected: isAllSelected || isNoneSelected, children: isNoneSelected ? `${allLabel} (ingen)` : allLabel }) }, "__all__")), options.map(opt => {
50
48
  // If none-state is active, everything else should look unselected
51
49
  const isSelected = !isNoneSelected && selectedSet.has(opt.value);
52
- return (_jsx("button", { type: "button", className: styles.chipButton, onClick: () => toggleValue(opt.value), "aria-pressed": isSelected, disabled: disabled, children: _jsx(Chip, { size: size, severity: (isSelected ? selectedSeverity : unselectedSeverity), customIcon: showSelectedIcon ? isSelected ? _jsx(Check, {}) : null : opt.icon, type: unselectedSeverity === null ? 'outlined' : 'rounded', children: opt.label }) }, opt.value));
50
+ return (_jsx("button", { type: "button", className: styles.chipButton, onClick: () => toggleValue(opt.value), "aria-pressed": isSelected, disabled: disabled, children: _jsx(Chip, { size: size, customIcon: opt.icon, severity: null, type: type, selected: isSelected, children: opt.label }) }, opt.value));
53
51
  })] })] }));
54
52
  }
@@ -4,8 +4,6 @@
4
4
  display: flex;
5
5
  align-items: center;
6
6
  flex-wrap: wrap;
7
-
8
- /* use theme spacing tokens */
9
7
  gap: var(--spacing-xs);
10
8
  }
11
9
 
@@ -15,10 +13,7 @@
15
13
 
16
14
  .label {
17
15
  font-weight: var(--font-weight-medium);
18
-
19
- /* theme uses --color-fg-muted / --color-fg-subtle (not --color-text-muted) */
20
16
  color: var(--color-fg-muted);
21
-
22
17
  white-space: nowrap;
23
18
  line-height: var(--line-height-tight);
24
19
  font-size: var(--font-size-sm);
@@ -28,8 +23,6 @@
28
23
  display: flex;
29
24
  flex-wrap: wrap;
30
25
  align-items: center;
31
-
32
- /* use theme spacing token */
33
26
  gap: var(--spacing-xxs);
34
27
  }
35
28
 
@@ -38,23 +31,30 @@
38
31
  border: 0;
39
32
  background: transparent;
40
33
  cursor: pointer;
41
-
42
- /* avoid default button styles on some browsers */
43
34
  font: inherit;
44
35
  color: inherit;
45
36
  }
46
37
 
47
38
  .chipButton:disabled {
48
39
  cursor: not-allowed;
49
-
50
- /* align with theme disabled */
51
40
  opacity: 1;
52
41
  color: var(--color-disabled-fg);
53
42
  }
54
43
 
55
- /* Focus ring should use theme focus tokens */
56
44
  .chipButton:focus-visible {
57
45
  outline: none;
58
- box-shadow: var(--focus-ring);
46
+ box-shadow: none;
47
+ }
48
+
49
+ .chipButton:focus-visible > * {
50
+ border-color: var(--color-border-selected);
51
+ box-shadow: inset 0 0 0 1px var(--color-border-selected);
52
+ }
53
+
54
+ .chipButton:focus-visible > .rounded {
59
55
  border-radius: var(--border-radius-rounded);
60
56
  }
57
+
58
+ .chipButton:focus-visible > .default {
59
+ border-radius: var(--border-radius-default);
60
+ }
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import type { Size } from '../../../types/sizes.types';
3
3
  import type { InputContainerProps } from '../input-container/InputContainer';
4
- export type InputVariant = 'outlined' | 'filled' | 'standalone';
4
+ export type InputVariant = 'outlined' | 'surface' | 'subtle' | 'standalone' | 'embedded';
5
5
  export type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'width'> & Omit<InputContainerProps, 'children' | 'htmlFor' | 'tooltip' | 'tooltipPlacement'> & {
6
6
  icon?: React.ReactNode;
7
7
  autoFocus?: boolean;
@@ -18,13 +18,7 @@ function mergeRefs(...refs) {
18
18
  }
19
19
  };
20
20
  }
21
- export const Input = forwardRef(function Input({
22
- // InputContainer props
23
- label, error, helpText, orientation = 'vertical', labelWidth = '160px', fullWidth = false, required, tooltip, tooltipPlacement = 'right', modified,
24
- // Input-only props
25
- icon, autoFocus, minWidth, width, inputSize = 'md', variant = 'outlined', onClear, onButtonClick, buttonLabel, buttonIcon,
26
- // Native input props
27
- id, style, className, ...inputProps }, ref) {
21
+ export const Input = forwardRef(function Input({ label, error, helpText, orientation = 'vertical', labelWidth = '160px', fullWidth = false, required, tooltip, tooltipPlacement = 'right', modified, icon, autoFocus, minWidth, width, inputSize = 'md', variant = 'outlined', onClear, onButtonClick, buttonLabel, buttonIcon, id, style, className, ...inputProps }, ref) {
28
22
  const inputRef = useRef(null);
29
23
  const reactId = useId();
30
24
  const inputId = id !== null && id !== void 0 ? id : `input-${reactId}`;
@@ -39,12 +33,12 @@ id, style, className, ...inputProps }, ref) {
39
33
  ...(minWidth ? { ['--input-min-width']: minWidth } : null),
40
34
  ...(width ? { ['--input-width']: width } : null),
41
35
  };
42
- // Anchor tooltip to the stable "field" wrapper (input + icon + clear button)
43
36
  const { triggerProps } = useTooltipTrigger({
44
37
  content: tooltip,
45
38
  placement: tooltipPlacement,
46
39
  offset: 8,
47
40
  });
41
+ const trailingButtonVariant = variant === 'outlined' || variant === 'standalone' ? 'outlined' : 'default';
48
42
  return (_jsx(InputContainer, { label: label, htmlFor: inputId, fullWidth: fullWidth, error: error, helpText: helpText, orientation: orientation, labelWidth: labelWidth, required: required, modified: modified, children: _jsxs("div", { style: rootStyle, className: [
49
43
  styles.container,
50
44
  fullWidth ? styles.fullWidth : '',
@@ -60,6 +54,6 @@ id, style, className, ...inputProps }, ref) {
60
54
  styles[variant],
61
55
  ]
62
56
  .filter(Boolean)
63
- .join(' ') }), onClear && inputProps.value && _jsx(ClearButton, { onClick: onClear, absolute: true })] }), hasButton && (_jsxs(Button, { onClick: onButtonClick, className: styles.trailingButton, type: "button", children: [buttonIcon !== null && buttonIcon !== void 0 ? buttonIcon : null, buttonLabel !== null && buttonLabel !== void 0 ? buttonLabel : null] }))] }) }));
57
+ .join(' ') }), onClear && inputProps.value && _jsx(ClearButton, { onClick: onClear, absolute: true })] }), hasButton && (_jsxs(Button, { onClick: onButtonClick, className: styles.trailingButton, type: "button", variant: trailingButtonVariant, children: [buttonIcon !== null && buttonIcon !== void 0 ? buttonIcon : null, buttonLabel !== null && buttonLabel !== void 0 ? buttonLabel : null] }))] }) }));
64
58
  });
65
59
  Input.displayName = 'Input';