@dbcdk/react-components 0.0.88 → 0.0.90

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 (70) hide show
  1. package/dist/components/accordion/Accordion.d.ts +1 -0
  2. package/dist/components/accordion/components/AccordionRow.js +1 -1
  3. package/dist/components/avatar/Avatar.js +16 -10
  4. package/dist/components/avatar/Avatar.module.css +33 -12
  5. package/dist/components/button/Button.js +8 -1
  6. package/dist/components/button/Button.module.css +2 -1
  7. package/dist/components/card/Card.d.ts +1 -5
  8. package/dist/components/card/Card.js +29 -4
  9. package/dist/components/card/Card.module.css +86 -98
  10. package/dist/components/card-container/CardContainer.d.ts +2 -1
  11. package/dist/components/card-container/CardContainer.js +2 -2
  12. package/dist/components/card-container/CardContainer.module.css +10 -9
  13. package/dist/components/clear-button/ClearButton.d.ts +2 -1
  14. package/dist/components/clear-button/ClearButton.js +6 -2
  15. package/dist/components/clear-button/ClearButton.module.css +6 -0
  16. package/dist/components/divider/Divider.d.ts +5 -0
  17. package/dist/components/divider/Divider.js +12 -0
  18. package/dist/components/forms/input/Input.d.ts +2 -1
  19. package/dist/components/forms/input/Input.js +6 -2
  20. package/dist/components/forms/input/Input.module.css +32 -0
  21. package/dist/components/forms/select/Select.d.ts +2 -1
  22. package/dist/components/forms/select/Select.js +2 -2
  23. package/dist/components/forms/typeahead/Typeahead.d.ts +2 -1
  24. package/dist/components/forms/typeahead/Typeahead.js +180 -118
  25. package/dist/components/forms/typeahead/Typeahead.module.css +4 -0
  26. package/dist/components/grid/Grid.d.ts +23 -0
  27. package/dist/components/grid/Grid.js +23 -0
  28. package/dist/components/grid/Grid.module.css +35 -0
  29. package/dist/components/headline/CollapsibleHeadline.d.ts +21 -0
  30. package/dist/components/headline/CollapsibleHeadline.js +29 -0
  31. package/dist/components/headline/Headline.d.ts +7 -5
  32. package/dist/components/headline/Headline.js +7 -6
  33. package/dist/components/headline/Headline.module.css +80 -8
  34. package/dist/components/nav-bar/NavBar.module.css +6 -2
  35. package/dist/components/overlay/modal/Modal.d.ts +2 -1
  36. package/dist/components/overlay/modal/Modal.js +5 -3
  37. package/dist/components/overlay/modal/provider/ModalProvider.js +2 -0
  38. package/dist/components/overlay/side-panel/SidePanel.d.ts +2 -1
  39. package/dist/components/overlay/side-panel/SidePanel.js +2 -2
  40. package/dist/components/page/Page.d.ts +5 -1
  41. package/dist/components/page/Page.js +6 -2
  42. package/dist/components/page/Page.module.css +54 -4
  43. package/dist/components/panel/Panel.d.ts +2 -1
  44. package/dist/components/panel/Panel.js +2 -2
  45. package/dist/components/popover/Popover.js +1 -1
  46. package/dist/components/stack/Stack.d.ts +16 -0
  47. package/dist/components/stack/Stack.js +19 -0
  48. package/dist/components/state-page/StatePage.d.ts +2 -1
  49. package/dist/components/state-page/StatePage.js +2 -2
  50. package/dist/components/table/Table.d.ts +1 -1
  51. package/dist/components/table/Table.js +22 -4
  52. package/dist/components/table/Table.module.css +14 -0
  53. package/dist/components/table/Table.types.d.ts +1 -0
  54. package/dist/components/tabs/Tabs.d.ts +3 -1
  55. package/dist/components/tabs/Tabs.js +4 -2
  56. package/dist/components/tabs/Tabs.module.css +4 -0
  57. package/dist/components/theme-button/ThemeButton.d.ts +1 -0
  58. package/dist/components/theme-button/ThemeButton.js +5 -1
  59. package/dist/components/toast/Toast.d.ts +2 -1
  60. package/dist/components/toast/Toast.js +2 -2
  61. package/dist/hooks/useViewportFill.d.ts +2 -6
  62. package/dist/hooks/useViewportFill.js +29 -24
  63. package/dist/index.d.ts +5 -0
  64. package/dist/index.js +5 -0
  65. package/dist/styles/css-helper-classes/flex.css +12 -0
  66. package/dist/styles/css-helper-classes/spacing.css +5 -0
  67. package/dist/styles/styles.css +154 -66
  68. package/dist/styles/themes/dbc/colors.css +10 -0
  69. package/dist/styles.css +154 -66
  70. package/package.json +1 -1
@@ -2,6 +2,7 @@ import type { JSX, ReactNode } from 'react';
2
2
  import type { Severity } from '../../constants/severity.types';
3
3
  export interface AccordionItem {
4
4
  header: string;
5
+ subheader?: ReactNode;
5
6
  headerAddition?: ReactNode;
6
7
  headerIcon?: ReactNode;
7
8
  severity?: Severity;
@@ -49,5 +49,5 @@ export function AccordionRow({ uid, index, item, isOpen, onToggle, shouldAnimate
49
49
  const buttonId = `${uid}-acc-btn-${index}`;
50
50
  const panelId = `${uid}-acc-panel-${index}`;
51
51
  const { innerRef, height, onTransitionEnd } = useCollapsibleHeight(isOpen, shouldAnimate);
52
- return (_jsxs("section", { className: `${styles.item} ${isOpen ? styles.open : ''} ${isDisabled ? styles.disabled : ''}`, children: [_jsx("div", { children: _jsxs("button", { type: "button", id: buttonId, className: styles.trigger, "aria-expanded": isOpen, "aria-controls": panelId, onClick: () => onToggle(index), disabled: isDisabled, children: [_jsxs("span", { className: styles.title, children: [item.headerIcon ? _jsx("span", { className: styles.icon, children: item.headerIcon }) : null, _jsx(Headline, { disableMargin: true, size: 4, weight: 500, severity: item.severity, allowWrap: isOpen, children: item.header }), item.headerAddition] }), _jsx("span", { className: styles.chevron, "aria-hidden": "true", children: _jsx(ChevronDown, {}) })] }) }), _jsx("div", { id: panelId, role: "region", "aria-labelledby": buttonId, className: `${styles.panel} ${shouldAnimate ? styles.animate : styles.noAnimate}`, style: { height }, onTransitionEnd: onTransitionEnd, children: _jsx("div", { ref: innerRef, className: styles.content, children: item.children }) })] }));
52
+ return (_jsxs("section", { className: `${styles.item} ${isOpen ? styles.open : ''} ${isDisabled ? styles.disabled : ''}`, children: [_jsx("div", { children: _jsxs("button", { type: "button", id: buttonId, className: styles.trigger, "aria-expanded": isOpen, "aria-controls": panelId, onClick: () => onToggle(index), disabled: isDisabled, children: [_jsxs("span", { className: styles.title, children: [item.headerIcon ? _jsx("span", { className: styles.icon, children: item.headerIcon }) : null, _jsx(Headline, { disableMargin: true, size: 4, weight: 500, severity: item.severity, subheader: item.subheader, allowWrap: isOpen, children: item.header }), item.headerAddition] }), _jsx("span", { className: styles.chevron, "aria-hidden": "true", children: _jsx(ChevronDown, {}) })] }) }), _jsx("div", { id: panelId, role: "region", "aria-labelledby": buttonId, className: `${styles.panel} ${shouldAnimate ? styles.animate : styles.noAnimate}`, style: { height }, onTransitionEnd: onTransitionEnd, children: _jsx("div", { ref: innerRef, className: styles.content, children: item.children }) })] }));
53
53
  }
@@ -4,14 +4,16 @@ import styles from './Avatar.module.css';
4
4
  import { SeverityBgColor, SeverityTextColor } from '../../constants/severity';
5
5
  import { sizes } from '../../constants/sizes';
6
6
  export function Avatar({ image, imgSrc, imgAlt, fullName, color = 'brand', button, size = 'md', className, fullWidth = false, photographerCredit, ...rest }) {
7
- const text = fullName
8
- ? fullName
9
- .trim()
10
- .split(/\s+/)
11
- .map(name => name.charAt(0))
12
- .join('')
13
- .toUpperCase()
14
- : '';
7
+ const text = (() => {
8
+ if (!fullName)
9
+ return '';
10
+ const parts = fullName.trim().split(/\s+/);
11
+ if (parts.length === 1) {
12
+ return parts[0].charAt(0).toUpperCase();
13
+ }
14
+ // Use first letter of first and last part only
15
+ return (parts[0].charAt(0) + parts[parts.length - 1].charAt(0)).toUpperCase();
16
+ })();
15
17
  const styleVars = {
16
18
  '--bg': SeverityBgColor[color],
17
19
  '--text': SeverityTextColor[color],
@@ -31,9 +33,13 @@ export function Avatar({ image, imgSrc, imgAlt, fullName, color = 'brand', butto
31
33
  if (imgSrc) {
32
34
  return _jsx("img", { className: styles.image, src: imgSrc, alt: imgAlt });
33
35
  }
34
- return (_jsx("span", { className: styles.avatar, "aria-hidden": "true", children: text }));
36
+ const avatarSizeClass = [styles.avatar];
37
+ if (size === 'xs')
38
+ avatarSizeClass.push(styles['size-xs']);
39
+ if (size === 'sm')
40
+ avatarSizeClass.push(styles['size-sm']);
41
+ return (_jsx("span", { className: avatarSizeClass.join(' '), "aria-hidden": "true", children: text }));
35
42
  };
36
- // Keep button behavior as before (no circular credit)
37
43
  if (button) {
38
44
  return (_jsx("button", { type: "button", ...rest, className: [styles.container, styles.button, className].filter(Boolean).join(' '), style: styleVars, children: renderImage() }));
39
45
  }
@@ -4,64 +4,85 @@
4
4
  max-inline-size: var(--component-size-xl);
5
5
  aspect-ratio: 1 / 1;
6
6
  border-radius: var(--border-radius-round);
7
- background-color: var(--bg);
8
- color: var(--text);
9
7
  display: inline-flex;
10
8
  align-items: center;
11
9
  justify-content: center;
12
- font-weight: var(--font-weight-semibold);
10
+ font-weight: var(--font-weight-normal);
13
11
  overflow: hidden;
14
12
  }
15
13
 
16
14
  .container.button {
17
15
  cursor: pointer;
18
16
  border: 0;
19
- background: var(--bg);
20
- transition: opacity var(--transition-fast) var(--ease-standard);
17
+ padding: 0;
18
+ background: transparent; /* important */
19
+ transition:
20
+ background-color var(--transition-fast) var(--ease-standard),
21
+ opacity var(--transition-fast) var(--ease-standard);
22
+ }
23
+
24
+ .container.button:hover .avatar {
25
+ background-color: color-mix(in srgb, var(--bg) 25%, var(--color-bg-surface));
21
26
  }
22
27
 
23
- .container.button:hover {
28
+ .container.button:active {
24
29
  opacity: 0.8;
25
30
  }
26
31
 
27
32
  .avatar {
28
- display: flex;
33
+ inline-size: 80%;
34
+ block-size: 80%;
35
+ display: inline-flex;
29
36
  align-items: center;
30
37
  justify-content: center;
38
+ border-radius: 50%;
39
+
40
+ /* moved here */
41
+ background-color: color-mix(in srgb, var(--bg) 20%, var(--color-bg-surface));
42
+ color: var(--bg);
43
+
31
44
  font-size: var(--font-size-sm);
32
45
  line-height: 1;
33
46
  text-transform: uppercase;
34
47
  }
35
48
 
49
+ .avatar.size-xs,
50
+ .avatar.size-sm {
51
+ font-size: var(--font-size-xs);
52
+ font-weight: var(--font-weight-normal);
53
+ }
54
+
36
55
  .image {
37
56
  inline-size: 100%;
38
57
  block-size: 100%;
39
58
  object-fit: cover;
40
59
  display: block;
60
+ border-radius: 50%; /* important if image fills avatar */
41
61
  }
42
62
 
43
63
  .imageSlot {
44
64
  display: contents;
45
65
  }
46
66
 
47
- /* Wrapper for non-button avatar so we can overlay SVG */
48
67
  .wrapper {
49
68
  position: relative;
50
69
  display: inline-block;
70
+ inline-size: var(--size);
71
+ block-size: var(--size);
72
+ max-inline-size: var(--component-size-xl);
73
+ aspect-ratio: 1 / 1;
51
74
  color: var(--text);
52
75
  }
53
76
 
54
- /* Circular photographer credit text overlay */
55
77
  .creditText {
56
78
  position: absolute;
57
79
  inset: 0;
58
- width: 100%;
59
- height: 100%;
80
+ inline-size: 100%;
81
+ block-size: 100%;
60
82
  pointer-events: none;
61
83
  fill: currentColor;
62
84
  }
63
85
 
64
- /* Make sure the font is large enough and clearly visible */
65
86
  .creditText text {
66
87
  font-size: 11px;
67
88
  font-weight: 600;
@@ -67,7 +67,14 @@ export const Button = React.forwardRef(function Button({ variant = 'outlined', s
67
67
  });
68
68
  }
69
69
  else {
70
- buttonEl = (_jsx("button", { className: computedClassName, type: type, ...buttonProps, ...(tooltipEnabled ? triggerProps : {}), "aria-describedby": describedBy, children: content }));
70
+ const isDisabled = Boolean(buttonProps.disabled);
71
+ buttonEl = (_jsx("button", { className: computedClassName, type: type, ...buttonProps, ...(tooltipEnabled && !isDisabled ? triggerProps : {}), "aria-describedby": describedBy, children: content }));
72
+ if (tooltipEnabled && isDisabled) {
73
+ buttonEl = (_jsx("span", { ref: triggerProps.ref, onPointerEnter: triggerProps.onPointerEnter, onPointerLeave: triggerProps.onPointerLeave, style: {
74
+ display: fullWidth ? 'flex' : 'inline-flex',
75
+ cursor: 'not-allowed',
76
+ }, children: buttonEl }));
77
+ }
71
78
  }
72
79
  return buttonEl;
73
80
  });
@@ -2,7 +2,7 @@
2
2
  display: inline-flex;
3
3
  align-items: center;
4
4
  justify-content: center;
5
- gap: var(--spacing-xxs);
5
+ gap: var(--spacing-xs);
6
6
 
7
7
  font-family: var(--font-family);
8
8
  font-size: var(--font-size-sm);
@@ -117,6 +117,7 @@
117
117
 
118
118
  .button.lg {
119
119
  height: var(--component-size-lg);
120
+ font-size: var(--font-size-md);
120
121
  min-block-size: var(--component-size-lg);
121
122
  padding-inline: var(--spacing-lg);
122
123
  }
@@ -6,6 +6,7 @@ type CardSize = 'sm' | 'md' | 'lg';
6
6
  type CardImagePlacement = 'left' | 'right' | 'top';
7
7
  export interface CardProps {
8
8
  title?: string;
9
+ subheader?: ReactNode;
9
10
  loading?: boolean;
10
11
  variant?: CardVariant;
11
12
  size?: CardSize;
@@ -21,11 +22,6 @@ export interface CardProps {
21
22
  sectionTitle?: string;
22
23
  showSectionDivider?: boolean;
23
24
  children?: ReactNode;
24
- /**
25
- * Keep current behavior: if provided, Card becomes "linked".
26
- * NOTE: this assumes your Hyperlink component can render the passed element correctly.
27
- * If Hyperlink expects an <a>, pass <a href="...">...</a> or whatever your existing pattern is.
28
- */
29
25
  link?: ReactNode;
30
26
  width?: 25 | 33 | 50 | 66 | 75 | 100;
31
27
  headlineSize?: 1 | 2 | 3 | 4 | 5 | 6;
@@ -4,6 +4,27 @@ import { CardMeta, CardMetaRow } from './components/CardMeta';
4
4
  import { Headline } from '../headline/Headline';
5
5
  import { Hyperlink } from '../hyperlink/Hyperlink';
6
6
  import { SkeletonLoaderItem } from '../skeleton-loader/skeleton-loader-item/SkeletonLoaderItem';
7
+ /**
8
+ * Fix for flex gap issue:
9
+ * Distributes gap proportionally across cards
10
+ */
11
+ function getGapShare(width) {
12
+ switch (width) {
13
+ case 25:
14
+ return 'calc(var(--card-container-gap, var(--spacing-md)) * 3 / 4)';
15
+ case 33:
16
+ return 'calc(var(--card-container-gap, var(--spacing-md)) * 2 / 3)';
17
+ case 50:
18
+ return 'calc(var(--card-container-gap, var(--spacing-md)) / 2)';
19
+ case 66:
20
+ return 'calc(var(--card-container-gap, var(--spacing-md)) * 2 / 3)';
21
+ case 75:
22
+ return 'calc(var(--card-container-gap, var(--spacing-md)) * 3 / 4)';
23
+ case 100:
24
+ default:
25
+ return '0px';
26
+ }
27
+ }
7
28
  function getInnerPlacementClass(imgPlacement, s) {
8
29
  switch (imgPlacement) {
9
30
  case 'top':
@@ -24,8 +45,13 @@ function getVariantClass(variant, s) {
24
45
  return s.variantDefault;
25
46
  }
26
47
  }
27
- function CardImpl({ title, loading = false, variant = 'default', size = 'md', headerMarker = true, headerIcon, headerAddition, severity, image, imgPlacement = 'left', mediaWidth, actions, headerMeta, sectionTitle, showSectionDivider = false, children, link, width, headlineSize = 4, }) {
28
- const outerStyle = width ? { ['--width']: `${width}%` } : undefined;
48
+ function CardImpl({ title, subheader, loading = false, variant = 'default', size = 'md', headerMarker = true, headerIcon, headerAddition, severity, image, imgPlacement = 'left', mediaWidth, actions, headerMeta, sectionTitle, showSectionDivider = false, children, link, width, headlineSize = 4, }) {
49
+ const outerStyle = width
50
+ ? {
51
+ ['--width']: `${width}%`,
52
+ ['--gap-share']: getGapShare(width),
53
+ }
54
+ : undefined;
29
55
  const mediaStyle = mediaWidth
30
56
  ? { ['--card-media-width']: `${mediaWidth}px` }
31
57
  : undefined;
@@ -35,8 +61,7 @@ function CardImpl({ title, loading = false, variant = 'default', size = 'md', he
35
61
  const showSection = !loading && (showSectionDivider || !!sectionTitle);
36
62
  const showBody = !loading && !!children;
37
63
  const showActions = !loading && !!actions;
38
- const inner = (_jsxs("div", { className: `${styles.inner} ${innerPlacementClass}`, children: [image ? (_jsx("div", { className: styles.media, style: mediaStyle, children: image })) : null, _jsxs("div", { className: styles.content, children: [hasHeader ? (_jsxs("header", { className: styles.header, children: [title ? (_jsx(Headline, { severity: severity, marker: headerMarker, icon: headerIcon, addition: headerAddition, size: headlineSize, weight: 500, disableMargin: true, children: title })) : null, headerMeta ? _jsx("div", { className: styles.headerMeta, children: headerMeta }) : null] })) : null, loading ? (_jsx("div", { className: styles.loadingList, "aria-busy": "true", "aria-live": "polite", children: Array.from({ length: 4 }, (_, index) => (_jsxs("div", { className: styles.loadingRow, children: [_jsx(SkeletonLoaderItem, {}), _jsx(SkeletonLoaderItem, { width: "100%" })] }, index))) })) : null, showSection ? (_jsxs("div", { className: styles.section, children: [showSectionDivider ? _jsx("div", { className: styles.sectionDivider }) : null, sectionTitle ? _jsx("div", { className: styles.sectionTitle, children: sectionTitle }) : null] })) : null, showBody ? _jsx("div", { className: styles.body, children: children }) : null, showActions ? _jsx("div", { className: styles.actions, children: actions }) : null] })] }));
39
- // keep existing behavior
64
+ const inner = (_jsxs("div", { className: `${styles.inner} ${innerPlacementClass}`, children: [image ? (_jsx("div", { className: styles.media, style: mediaStyle, children: image })) : null, _jsxs("div", { className: styles.content, children: [hasHeader ? (_jsxs("header", { className: styles.header, children: [title ? (_jsx(Headline, { severity: severity, marker: headerMarker, icon: headerIcon, addition: headerAddition, subheader: subheader, size: headlineSize, weight: 500, disableMargin: true, children: title })) : null, headerMeta ? _jsx("div", { className: styles.headerMeta, children: headerMeta }) : null] })) : null, loading ? (_jsx("div", { className: styles.loadingList, "aria-busy": "true", "aria-live": "polite", children: Array.from({ length: 4 }, (_, index) => (_jsxs("div", { className: styles.loadingRow, children: [_jsx(SkeletonLoaderItem, {}), _jsx(SkeletonLoaderItem, { width: "100%" })] }, index))) })) : null, showSection ? (_jsxs("div", { className: styles.section, children: [showSectionDivider ? _jsx("div", { className: styles.sectionDivider }) : null, sectionTitle ? _jsx("div", { className: styles.sectionTitle, children: sectionTitle }) : null] })) : null, showBody ? _jsx("div", { className: styles.body, children: children }) : null, showActions ? _jsx("div", { className: styles.actions, children: actions }) : null] })] }));
40
65
  const cardContent = link ? _jsx(Hyperlink, { children: link }) : inner;
41
66
  return (_jsx("div", { className: `${styles.outerContainer} ${styles[size]}`, style: outerStyle, children: _jsx("div", { className: `${styles.container} ${variantClass}`, children: cardContent }) }));
42
67
  }
@@ -1,62 +1,53 @@
1
- /* OUTER WRAPPER (optional width control) */
2
1
  .outerContainer {
3
- inline-size: var(--width, 100%);
2
+ --width: 100%;
3
+ --gap-share: 0px;
4
+
5
+ flex: 0 1 calc(var(--width) - var(--gap-share));
6
+ min-width: 0;
7
+ box-sizing: border-box;
4
8
  }
5
9
 
6
- /* CARD CONTAINER */
10
+ /* Card surface */
7
11
  .container {
8
- inline-size: 100%;
9
- position: relative;
10
- color: var(--card-fg-default, var(--color-fg-default));
11
- background-color: var(--card-bg-default, var(--color-bg-surface));
12
- border-radius: var(--border-radius-md);
13
- border: var(--border-width-thin) solid var(--color-border-subtle);
14
- box-shadow: var(--shadow-xs);
15
- transition:
16
- color var(--transition-fast) var(--ease-standard),
17
- box-shadow var(--transition-fast) var(--ease-standard),
18
- transform var(--transition-fast) var(--ease-standard);
19
- }
12
+ height: 100%;
13
+ border-radius: var(--border-radius-sm);
14
+ box-sizing: border-box;
20
15
 
21
- .container:hover {
22
- box-shadow: var(--shadow-sm);
16
+ /* ✅ Restore border */
17
+ border: 1px solid var(--color-border-subtle);
18
+
19
+ /* Optional: ensure background sits under border */
20
+ background-clip: padding-box;
23
21
  }
24
22
 
25
- /* BACKGROUND VARIANTS */
23
+ /* Variants */
26
24
  .variantDefault {
27
- background-color: var(--card-bg-default, var(--color-bg-surface));
25
+ background-color: var(--card-bg-default, var(--color-bg-surface, var(--color-bg-surface-subtle)));
28
26
  }
29
27
 
30
28
  .variantSubtle {
31
- background-color: var(--card-bg-subtle, var(--color-bg-contextual-subtle));
29
+ background-color: var(--card-bg-subtle, var(--color-bg-surface-subtle, var(--color-bg-surface)));
32
30
  }
33
31
 
34
- /* SIZE VARIANTS (define vars once; inner uses them) */
35
- .sm {
36
- --card-pad: var(--spacing-md);
37
- --card-gap: var(--spacing-md);
32
+ /* Sizes */
33
+ .sm .container {
34
+ padding: var(--spacing-md);
38
35
  }
39
- .md {
40
- --card-pad: var(--spacing-lg);
41
- --card-gap: var(--spacing-lg);
36
+
37
+ .md .container {
38
+ padding: var(--spacing-lg);
42
39
  }
43
- .lg {
44
- --card-pad: var(--spacing-xl);
45
- --card-gap: var(--spacing-xl);
40
+
41
+ .lg .container {
42
+ padding: var(--spacing-xl);
46
43
  }
47
44
 
48
- /* INNER LAYOUT */
45
+ /* Layout */
49
46
  .inner {
50
- margin-inline: auto;
51
47
  display: flex;
52
- align-items: flex-start;
53
- padding: var(--card-pad);
54
- gap: var(--card-gap);
55
- }
56
-
57
- /* Media placement */
58
- .innerImgTop {
59
- flex-direction: column;
48
+ gap: var(--spacing-lg);
49
+ height: 100%;
50
+ min-width: 0;
60
51
  }
61
52
 
62
53
  .innerImgLeft {
@@ -67,101 +58,98 @@
67
58
  flex-direction: row-reverse;
68
59
  }
69
60
 
70
- /* MEDIA */
71
- .media {
72
- flex: 0 0 auto;
73
- display: flex;
74
- align-items: flex-start;
75
- justify-content: center;
76
- }
77
-
78
- .innerImgLeft .media,
79
- .innerImgRight .media {
80
- inline-size: var(--card-media-width, 56px);
81
- max-inline-size: 25%;
82
- }
83
-
84
- .innerImgTop .media {
85
- inline-size: 100%;
86
- max-inline-size: 100%;
61
+ .innerImgTop {
62
+ flex-direction: column;
87
63
  }
88
64
 
89
- .media img,
90
- .media picture,
91
- .media video,
92
- .media svg {
93
- display: block;
94
- inline-size: 100%;
95
- block-size: auto;
65
+ .media {
66
+ flex: 0 0 var(--card-media-width, auto);
67
+ min-width: 0;
96
68
  }
97
69
 
98
- /* CONTENT */
99
70
  .content {
100
- flex: 1 1 auto;
101
- min-inline-size: 0;
102
71
  display: flex;
72
+ flex: 1 1 auto;
103
73
  flex-direction: column;
104
74
  gap: var(--spacing-md);
75
+ min-width: 0;
105
76
  }
106
77
 
107
- /* HEADER */
78
+ /* Header */
108
79
  .header {
109
80
  display: flex;
110
81
  align-items: flex-start;
111
82
  justify-content: space-between;
112
- gap: var(--spacing-sm);
113
- }
114
-
115
- .header > :first-child {
116
- flex: 1 1 auto;
117
- min-inline-size: 0;
83
+ gap: var(--spacing-md);
84
+ min-width: 0;
118
85
  }
119
86
 
120
87
  .headerMeta {
121
- display: flex;
122
- align-items: center;
123
- gap: var(--spacing-xs);
88
+ flex: 0 0 auto;
124
89
  }
125
90
 
126
- /* LOADING */
127
- .loadingList {
128
- display: grid;
129
- gap: var(--spacing-sm);
91
+ /* Body */
92
+ .body {
93
+ min-width: 0;
94
+ flex: 1 1 auto;
130
95
  }
131
96
 
132
- .loadingRow {
133
- display: grid;
134
- grid-template-columns: auto 1fr;
97
+ /* Actions */
98
+ .actions {
99
+ display: flex;
100
+ flex-wrap: wrap;
135
101
  gap: var(--spacing-sm);
136
- align-items: center;
102
+ margin-top: auto;
137
103
  }
138
104
 
139
- /* SECTION */
105
+ /* Section */
140
106
  .section {
141
107
  display: flex;
142
108
  flex-direction: column;
143
- gap: var(--spacing-md);
109
+ gap: var(--spacing-sm);
144
110
  }
145
111
 
146
112
  .sectionDivider {
147
- inline-size: 100%;
148
- block-size: var(--border-width-thin);
149
- background: var(--color-border-subtle);
113
+ width: 100%;
114
+ height: 1px;
115
+ background-color: var(--color-border-subtle);
150
116
  }
151
117
 
152
118
  .sectionTitle {
153
- font-weight: var(--font-weight-semibold);
119
+ font-weight: 500;
154
120
  }
155
121
 
156
- /* BODY */
157
- .body {
158
- /* neutral container */
122
+ /* Loading */
123
+ .loadingList {
124
+ display: flex;
125
+ flex-direction: column;
126
+ gap: var(--spacing-md);
159
127
  }
160
128
 
161
- /* ACTIONS */
162
- .actions {
163
- margin-top: auto;
129
+ .loadingRow {
164
130
  display: flex;
165
- justify-content: flex-end;
131
+ flex-direction: column;
166
132
  gap: var(--spacing-sm);
167
133
  }
134
+
135
+ /* Responsive */
136
+ @media screen and (max-width: 767px) {
137
+ .outerContainer {
138
+ --width: 100%;
139
+ --gap-share: 0px;
140
+
141
+ flex-basis: 100%;
142
+ max-width: 100%;
143
+ }
144
+
145
+ .inner,
146
+ .innerImgLeft,
147
+ .innerImgRight,
148
+ .innerImgTop {
149
+ flex-direction: column;
150
+ }
151
+
152
+ .header {
153
+ flex-direction: column;
154
+ }
155
+ }
@@ -2,10 +2,11 @@ import type { JSX, ReactNode } from 'react';
2
2
  import { Severity } from '../../constants/severity.types';
3
3
  interface CardContainerProps {
4
4
  headline?: string;
5
+ subheader?: ReactNode;
5
6
  children?: ReactNode[];
6
7
  expand?: boolean;
7
8
  severity?: Severity;
8
9
  displayHeaderMarker?: boolean;
9
10
  }
10
- export declare function CardContainer({ children, headline, expand, severity, displayHeaderMarker, }: CardContainerProps): JSX.Element;
11
+ export declare function CardContainer({ children, headline, subheader, expand, severity, displayHeaderMarker, }: CardContainerProps): JSX.Element;
11
12
  export {};
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { Headline } from '../../components/headline/Headline';
3
3
  import styles from './CardContainer.module.css';
4
- export function CardContainer({ children, headline, expand, severity, displayHeaderMarker, }) {
5
- return (_jsxs("div", { className: styles.wrapper, children: [headline && (_jsx(Headline, { marker: displayHeaderMarker, severity: severity, disableMargin: true, children: headline })), _jsx("div", { className: styles.container, style: { ['--expand']: expand ? '1' : '0' }, children: children })] }));
4
+ export function CardContainer({ children, headline, subheader, expand, severity, displayHeaderMarker, }) {
5
+ return (_jsxs("div", { className: styles.wrapper, children: [headline && (_jsx(Headline, { marker: displayHeaderMarker, severity: severity, disableMargin: true, subheader: subheader, children: headline })), _jsx("div", { className: styles.container, style: { ['--expand']: expand ? '1' : '0' }, children: children })] }));
6
6
  }
@@ -8,8 +8,8 @@
8
8
  display: flex;
9
9
  flex-wrap: wrap;
10
10
  gap: var(--spacing-md);
11
+ --card-container-gap: var(--spacing-md);
11
12
  border-radius: var(--border-radius-sm);
12
- --width: 100%;
13
13
  }
14
14
 
15
15
  .container.default {
@@ -47,14 +47,15 @@
47
47
  padding: var(--spacing-lg);
48
48
  }
49
49
 
50
- @media screen and (min-width: 768px) {
51
- .container {
52
- --width: 33.333%;
53
- }
54
- }
55
-
56
50
  .container > * {
57
- flex-grow: var(--expand);
58
- flex-shrink: 1;
51
+ min-width: 0;
59
52
  box-sizing: border-box;
60
53
  }
54
+
55
+ /* Mobile: stack */
56
+ @media screen and (max-width: 767px) {
57
+ .container > * {
58
+ flex-basis: 100% !important;
59
+ max-width: 100%;
60
+ }
61
+ }
@@ -1,6 +1,7 @@
1
1
  import type { ReactNode } from 'react';
2
+ import * as React from 'react';
2
3
  interface ClearButtonProps {
3
- onClick: () => void;
4
+ onClick?: (event?: React.MouseEvent | React.KeyboardEvent) => void;
4
5
  absolute?: boolean;
5
6
  }
6
7
  export declare function ClearButton({ onClick, absolute }: ClearButtonProps): ReactNode;
@@ -2,8 +2,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { X } from 'lucide-react';
3
3
  import styles from './ClearButton.module.css';
4
4
  export function ClearButton({ onClick, absolute }) {
5
- return (_jsx("span", { className: `${styles.clearButton} ${absolute ? styles.absolute : ''}`, children: _jsx("span", { className: styles.button, role: "button", onClick: e => {
5
+ return (_jsx("span", { className: `${styles.clearButton} ${absolute ? styles.absolute : ''}`, children: _jsx("button", { className: styles.button, type: "button", "data-input-role": "clear", onMouseDown: e => {
6
+ e.preventDefault();
6
7
  e.stopPropagation();
7
- onClick();
8
+ }, onClick: e => {
9
+ e.preventDefault();
10
+ e.stopPropagation();
11
+ onClick === null || onClick === void 0 ? void 0 : onClick(e);
8
12
  }, children: _jsx(X, { size: 16 }) }) }));
9
13
  }
@@ -1,8 +1,14 @@
1
1
  .clearButton .button {
2
+ appearance: none;
2
3
  display: flex;
3
4
  align-items: center;
4
5
  justify-content: center;
6
+ margin: 0;
7
+ border: 0;
8
+ background: transparent;
5
9
  color: var(--color-fg-subtle);
10
+ font: inherit;
11
+ line-height: 0;
6
12
  padding: var(--spacing-xxs);
7
13
  cursor: pointer;
8
14
  border-radius: 100%;
@@ -0,0 +1,5 @@
1
+ type DividerProps = {
2
+ spacing?: 'sm' | 'md' | 'lg';
3
+ };
4
+ export declare const Divider: ({ spacing }: DividerProps) => import("react/jsx-runtime").JSX.Element;
5
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ const spacingMap = {
3
+ sm: 'var(--spacing-sm)',
4
+ md: 'var(--spacing-md)',
5
+ lg: 'var(--spacing-lg)',
6
+ };
7
+ export const Divider = ({ spacing = 'md' }) => {
8
+ return (_jsx("div", { style: {
9
+ borderTop: '1px solid var(--color-border-subtle)',
10
+ marginBlock: spacingMap[spacing],
11
+ } }));
12
+ };
@@ -10,10 +10,11 @@ export type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size
10
10
  maxWidth?: string | number;
11
11
  inputSize?: Exclude<Size, 'xl'>;
12
12
  variant?: InputVariant;
13
- onClear?: () => void;
13
+ onClear?: (event?: React.MouseEvent | React.KeyboardEvent) => void;
14
14
  onButtonClick?: () => void;
15
15
  buttonLabel?: string;
16
16
  buttonIcon?: React.ReactNode;
17
+ trailingLabel?: string;
17
18
  tooltip?: React.ReactNode;
18
19
  tooltipPlacement?: 'top' | 'right' | 'bottom' | 'left';
19
20
  tooltipOpenOnFocus?: boolean;