@dbcdk/react-components 0.0.95 → 0.0.96

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.
@@ -0,0 +1,13 @@
1
+ import type { JSX, ReactNode } from 'react';
2
+ import type { Severity } from '../../constants/severity.types';
3
+ export interface AlertProps {
4
+ children: ReactNode;
5
+ title?: ReactNode;
6
+ severity?: Severity;
7
+ customIcon?: ReactNode;
8
+ disableIcon?: boolean;
9
+ fullWidth?: boolean;
10
+ maxWidth?: string | number;
11
+ role?: 'status' | 'alert';
12
+ }
13
+ export declare function Alert({ children, title, severity, customIcon, disableIcon, fullWidth, maxWidth, role, }: AlertProps): JSX.Element;
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import styles from './Alert.module.css';
4
+ import { Icon } from '../icon/Icon';
5
+ export function Alert({ children, title, severity = 'neutral', customIcon, disableIcon = false, fullWidth = false, maxWidth = '72ch', role = 'status', }) {
6
+ const hasLeading = Boolean(customIcon) || !disableIcon;
7
+ return (_jsxs("div", { className: [
8
+ styles.container,
9
+ styles[severity],
10
+ fullWidth ? styles.fullWidth : '',
11
+ hasLeading ? styles.hasLeading : '',
12
+ ]
13
+ .filter(Boolean)
14
+ .join(' '), style: {
15
+ '--alert-max-width': typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth,
16
+ }, role: role, children: [hasLeading ? (_jsx("div", { className: styles.leading, children: customIcon !== null && customIcon !== void 0 ? customIcon : _jsx(Icon, { severity: severity }) })) : null, _jsxs("div", { className: styles.content, children: [title ? _jsx("div", { className: styles.title, children: title }) : null, _jsx("div", { className: styles.body, children: children })] })] }));
17
+ }
@@ -0,0 +1,98 @@
1
+ .container {
2
+ --alert-bg: var(--color-bg-toolbar);
3
+ --alert-fg: var(--color-fg-default);
4
+ --alert-border: var(--color-border-subtle);
5
+
6
+ display: flex;
7
+ align-items: flex-start;
8
+ gap: var(--spacing-sm);
9
+ inline-size: min(100%, var(--alert-max-width, 72ch));
10
+ max-inline-size: 100%;
11
+ padding: var(--spacing-sm) var(--spacing-md);
12
+ border: 1px solid var(--alert-border);
13
+ border-radius: var(--border-radius-default);
14
+ background: var(--alert-bg);
15
+ color: var(--alert-fg);
16
+ box-sizing: border-box;
17
+ }
18
+
19
+ .fullWidth {
20
+ inline-size: 100%;
21
+ }
22
+
23
+ .leading {
24
+ display: inline-flex;
25
+ align-items: center;
26
+ justify-content: center;
27
+ flex: 0 0 auto;
28
+ padding-block-start: 2px;
29
+ }
30
+
31
+ .leading svg {
32
+ inline-size: var(--icon-size-md);
33
+ block-size: var(--icon-size-md);
34
+ color: currentColor;
35
+ }
36
+
37
+ .content {
38
+ display: flex;
39
+ flex-direction: column;
40
+ gap: var(--spacing-2xs);
41
+ min-width: 0;
42
+ flex: 1 1 auto;
43
+ }
44
+
45
+ .title,
46
+ .body {
47
+ min-width: 0;
48
+ overflow-wrap: anywhere;
49
+ word-break: break-word;
50
+ white-space: normal;
51
+ }
52
+
53
+ .title {
54
+ font-size: var(--font-size-sm);
55
+ font-weight: var(--font-weight-semibold);
56
+ line-height: var(--line-height-tight);
57
+ }
58
+
59
+ .body {
60
+ font-size: var(--font-size-sm);
61
+ line-height: var(--line-height-normal);
62
+ }
63
+
64
+ .neutral {
65
+ --alert-bg: var(--color-bg-toolbar);
66
+ --alert-fg: var(--color-fg-default);
67
+ --alert-border: var(--color-border-subtle);
68
+ }
69
+
70
+ .success {
71
+ --alert-bg: var(--color-status-success-bg);
72
+ --alert-fg: var(--color-status-success-fg);
73
+ --alert-border: var(--color-status-success-border);
74
+ }
75
+
76
+ .warning {
77
+ --alert-bg: var(--color-status-warning-bg);
78
+ --alert-fg: var(--color-status-warning-fg);
79
+ --alert-border: var(--color-status-warning-border);
80
+ }
81
+
82
+ .error {
83
+ --alert-bg: var(--color-status-error-bg);
84
+ --alert-fg: var(--color-status-error-fg);
85
+ --alert-border: var(--color-status-error-border);
86
+ }
87
+
88
+ .info {
89
+ --alert-bg: var(--color-status-info-bg);
90
+ --alert-fg: var(--color-status-info-fg);
91
+ --alert-border: var(--color-status-info-border);
92
+ }
93
+
94
+ .brand {
95
+ --alert-bg: color-mix(in srgb, var(--color-brand) 10%, var(--color-bg-surface));
96
+ --alert-fg: var(--color-brand);
97
+ --alert-border: color-mix(in srgb, var(--color-brand) 35%, transparent);
98
+ }
@@ -12,7 +12,7 @@ export function CopyButton(props) {
12
12
  const { text, variant = 'outlined', size = 'sm', children, displayStyle, disableIcon = false, disableToast = false, className, style, fullWidth, disabled, ...rest } = props;
13
13
  const [copied, setCopied] = useState(false);
14
14
  const toast = useOptionalToast();
15
- const buttonLabel = children !== null && children !== void 0 ? children : 'Kopiér';
15
+ const buttonLabel = children;
16
16
  const icon = disableIcon ? null : copied ? _jsx(Check, {}) : _jsx(Copy, {});
17
17
  const handleCopySuccess = () => {
18
18
  if (!disableIcon) {
@@ -66,7 +66,7 @@ export function CopyButton(props) {
66
66
  .join(' '), style: style, disabled: disabled, children: buttonLabel }) }));
67
67
  }
68
68
  if (displayStyle === 'field') {
69
- return (_jsx(Input, { value: text, readOnly: true, disabled: disabled, fullWidth: fullWidth, className: className, style: style, inputSize: size, variant: "outlined", buttonLabel: String(buttonLabel), buttonIcon: icon, onButtonClick: () => {
69
+ return (_jsx(Input, { value: text, readOnly: true, disabled: disabled, fullWidth: fullWidth, className: className, style: style, inputSize: size, variant: "outlined", buttonLabel: typeof buttonLabel === 'string' ? buttonLabel : undefined, buttonIcon: icon, onButtonClick: () => {
70
70
  void handleCopy();
71
71
  }, "aria-label": (_b = rest['aria-label']) !== null && _b !== void 0 ? _b : 'Kopier til udklipsholder' }));
72
72
  }
@@ -16,11 +16,13 @@ export function Checkbox({ checked: controlled, onChange, variant = 'default', d
16
16
  setInternal(value);
17
17
  onChange === null || onChange === void 0 ? void 0 : onChange(value, e);
18
18
  };
19
- const content = (_jsxs("span", { className: styles.container, "data-cy": dataCy, children: [_jsx("button", { id: controlId, disabled: disabled, type: "button", role: "checkbox", "aria-checked": isChecked, "aria-disabled": disabled || undefined, "aria-invalid": Boolean(error) || undefined, onClick: toggle, className: [styles.checkbox, isChecked ? styles.checked : '', styles[variant], styles[size]]
19
+ const content = (_jsxs("span", { className: [styles.container, size === 'sm' ? styles.containerSm : '']
20
+ .filter(Boolean)
21
+ .join(' '), "data-cy": dataCy, children: [_jsx("button", { id: controlId, disabled: disabled, type: "button", role: "checkbox", "aria-checked": isChecked, "aria-disabled": disabled || undefined, "aria-invalid": Boolean(error) || undefined, onClick: toggle, className: [styles.checkbox, isChecked ? styles.checked : '', styles[variant], styles[size]]
20
22
  .filter(Boolean)
21
23
  .join(' '), children: isChecked && _jsx(Check, { className: styles.icon }) }), label &&
22
24
  (labelAs === 'label' ? (_jsx("label", { className: styles.label, htmlFor: controlId, children: label })) : (_jsx("span", { className: styles.label, children: label })))] }));
23
25
  if (noContainer)
24
26
  return content;
25
- return (_jsx(InputContainer, { modified: modified, label: containerLabel, htmlFor: controlId, error: error, helpText: helpText, orientation: orientation, labelWidth: labelWidth, fullWidth: fullWidth, required: required, children: content }));
27
+ return (_jsx(InputContainer, { modified: modified, label: containerLabel, htmlFor: controlId, error: error, helpText: helpText, orientation: orientation, size: size, labelWidth: labelWidth, fullWidth: fullWidth, required: required, children: content }));
26
28
  }
@@ -6,6 +6,10 @@
6
6
  line-height: var(--line-height-normal);
7
7
  }
8
8
 
9
+ .containerSm {
10
+ gap: var(--spacing-xs);
11
+ }
12
+
9
13
  .checkbox {
10
14
  width: var(--component-size-sm);
11
15
  height: var(--component-size-sm);
@@ -2,7 +2,7 @@ import * as React from 'react';
2
2
  import type { Size } from '../../../types/sizes.types';
3
3
  import type { InputContainerProps } from '../input-container/InputContainer';
4
4
  export type InputVariant = 'outlined' | 'surface' | 'subtle' | 'standalone' | 'embedded';
5
- export type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'width'> & Omit<InputContainerProps, 'children' | 'htmlFor' | 'tooltip' | 'tooltipPlacement'> & {
5
+ export type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size' | 'width'> & Omit<InputContainerProps, 'children' | 'htmlFor' | 'tooltip' | 'tooltipPlacement' | 'size'> & {
6
6
  icon?: React.ReactNode;
7
7
  autoFocus?: boolean;
8
8
  minWidth?: string | number;
@@ -12,6 +12,7 @@ export type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size
12
12
  variant?: InputVariant;
13
13
  onClear?: (event?: React.MouseEvent | React.KeyboardEvent) => void;
14
14
  onButtonClick?: () => void;
15
+ buttonDisabled?: boolean;
15
16
  buttonLabel?: string;
16
17
  buttonIcon?: React.ReactNode;
17
18
  trailingLabel?: string;
@@ -18,7 +18,7 @@ function mergeRefs(...refs) {
18
18
  }
19
19
  };
20
20
  }
21
- export const Input = forwardRef(function Input({ label, error, helpText, orientation = 'vertical', labelWidth = '160px', fullWidth = false, required, tooltip, tooltipPlacement = 'right', modified = false, icon, autoFocus, minWidth, width, maxWidth, inputSize = 'md', variant = 'outlined', onClear, onButtonClick, buttonLabel, buttonIcon, trailingLabel, id, tooltipOpenOnFocus = true, style, className, fieldClassName, inputClassName, startAdornment, endAdornment, ...inputProps }, ref) {
21
+ export const Input = forwardRef(function Input({ label, error, helpText, orientation = 'vertical', labelWidth = '160px', fullWidth = false, required, tooltip, tooltipPlacement = 'right', modified = false, icon, autoFocus, minWidth, width, maxWidth, inputSize = 'md', variant = 'outlined', onClear, onButtonClick, buttonDisabled = false, buttonLabel, buttonIcon, trailingLabel, id, tooltipOpenOnFocus = true, style, className, fieldClassName, inputClassName, startAdornment, endAdornment, ...inputProps }, ref) {
22
22
  const inputRef = useRef(null);
23
23
  const reactId = useId();
24
24
  const inputId = id !== null && id !== void 0 ? id : `input-${reactId}`;
@@ -49,7 +49,7 @@ export const Input = forwardRef(function Input({ label, error, helpText, orienta
49
49
  closeOnPointerDown: false,
50
50
  });
51
51
  const trailingButtonVariant = variant === 'outlined' || variant === 'standalone' ? 'outlined' : 'default';
52
- 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: [
52
+ return (_jsx(InputContainer, { label: label, labelAction: inputProps.labelAction, htmlFor: inputId, fullWidth: fullWidth, error: error, helpText: helpText, orientation: orientation, labelWidth: labelWidth, required: required, modified: modified, children: _jsxs("div", { style: rootStyle, className: [
53
53
  styles.container,
54
54
  fullWidth ? styles.fullWidth : '',
55
55
  onClear ? styles.withClear : '',
@@ -72,6 +72,6 @@ export const Input = forwardRef(function Input({ label, error, helpText, orienta
72
72
  .filter(Boolean)
73
73
  .join(' ') }), (reservesInlineClearSlot || hasEndAdornment) && (_jsxs("span", { className: styles.endAdornment, "data-input-role": "end-adornment", children: [reservesInlineClearSlot ? (_jsx("span", { className: styles.clearSlot, "aria-hidden": hasVisibleClear ? undefined : 'true', children: hasVisibleClear && onClear ? _jsx(ClearButton, { onClick: onClear }) : null })) : null, endAdornment] })), hasVisibleClear && !hasEndAdornment && onClear ? (_jsx(ClearButton, { onClick: onClear, absolute: true })) : null] }), hasTrailingLabel && (_jsx("span", { className: [styles.trailingLabel, inputSize ? styles[inputSize] : '']
74
74
  .filter(Boolean)
75
- .join(' '), children: trailingLabel })), hasButton && (_jsxs(Button, { onClick: onButtonClick, className: styles.trailingButton, type: "button", variant: trailingButtonVariant, size: inputSize, children: [buttonIcon !== null && buttonIcon !== void 0 ? buttonIcon : null, buttonLabel !== null && buttonLabel !== void 0 ? buttonLabel : null] }))] }) }));
75
+ .join(' '), children: trailingLabel })), hasButton && (_jsxs(Button, { onClick: onButtonClick, disabled: buttonDisabled, className: styles.trailingButton, type: "button", variant: trailingButtonVariant, size: inputSize, children: [buttonIcon !== null && buttonIcon !== void 0 ? buttonIcon : null, buttonLabel !== null && buttonLabel !== void 0 ? buttonLabel : null] }))] }) }));
76
76
  });
77
77
  Input.displayName = 'Input';
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  export interface InputContainerProps {
3
3
  label?: string;
4
+ labelAction?: React.ReactNode;
4
5
  htmlFor?: string;
5
6
  error?: string;
6
7
  helpText?: string;
@@ -9,8 +10,9 @@ export interface InputContainerProps {
9
10
  required?: boolean;
10
11
  children: React.ReactNode;
11
12
  orientation?: 'vertical' | 'horizontal';
13
+ size?: 'sm' | 'md' | 'lg';
12
14
  labelWidth?: string;
13
15
  labelAlignment?: 'top' | 'center';
14
16
  modified?: boolean;
15
17
  }
16
- export declare function InputContainer({ label, htmlFor, error, helpText, helpTextAddition, fullWidth, required, children, orientation, labelWidth, modified, }: InputContainerProps): React.ReactElement;
18
+ export declare function InputContainer({ label, labelAction, htmlFor, error, helpText, helpTextAddition, fullWidth, required, children, orientation, size, labelWidth, modified, }: InputContainerProps): React.ReactElement;
@@ -1,15 +1,15 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import styles from './InputContainer.module.css';
3
- export function InputContainer({ label, htmlFor, error, helpText, helpTextAddition, fullWidth = false, required = false, children, orientation = 'horizontal', labelWidth = '160px', modified = false, }) {
3
+ export function InputContainer({ label, labelAction, htmlFor, error, helpText, helpTextAddition, fullWidth = false, required = false, children, orientation = 'horizontal', size = 'md', labelWidth = '160px', modified = false, }) {
4
4
  const message = error !== null && error !== void 0 ? error : helpText;
5
5
  const messageClass = error ? styles.errorText : styles.helpText;
6
- const renderLabel = label && (_jsxs("label", { className: styles.label, htmlFor: htmlFor, children: [label, required && _jsx("span", { className: styles.required, children: " *" })] }));
6
+ const renderLabelRow = (label || labelAction) && (_jsxs("div", { className: `${styles.labelRow} dbc-flex dbc-items-center dbc-gap-md`, children: [label && (_jsxs("label", { className: styles.label, htmlFor: htmlFor, children: [label, required && _jsx("span", { className: styles.required, children: " *" })] })), labelAction && _jsx("div", { className: styles.labelAction, children: labelAction })] }));
7
7
  const renderMessageRow = (message || helpTextAddition) && (_jsxs("div", { className: `${messageClass} ${styles.messageRow}`, children: [_jsx("span", { children: message }), helpTextAddition && _jsx("span", { className: styles.helpTextAddition, children: helpTextAddition })] }));
8
8
  if (orientation === 'vertical') {
9
- return (_jsxs("div", { "data-modified": modified ? 'true' : undefined, className: `dbc-flex dbc-flex-column dbc-gap-xs ${styles.inputContainer}`, style: { width: fullWidth ? '100%' : undefined }, children: [renderLabel, children, renderMessageRow] }));
9
+ return (_jsxs("div", { "data-modified": modified ? 'true' : undefined, className: `dbc-flex dbc-flex-column dbc-gap-xs ${styles.inputContainer}`, style: { width: fullWidth ? '100%' : undefined }, children: [renderLabelRow, children, renderMessageRow] }));
10
10
  }
11
11
  return (_jsx("div", { "data-modified": modified ? 'true' : undefined, className: styles.inputContainer, style: {
12
12
  '--label-width': labelWidth,
13
13
  width: fullWidth ? '100%' : undefined,
14
- }, children: _jsxs("div", { className: `${styles.horizontal} dbc-flex dbc-flex-column dbc-gap-xs`, children: [_jsxs("div", { className: `${styles.labelContainer} dbc-flex dbc-items-center dbc-gap-xs`, children: [renderLabel, children] }), renderMessageRow] }) }));
14
+ }, children: _jsxs("div", { className: `${styles.horizontal} dbc-flex dbc-flex-column dbc-gap-xs`, "data-size": size, children: [_jsxs("div", { className: `${styles.labelContainer} dbc-flex dbc-items-center dbc-gap-xs`, children: [renderLabelRow, children] }), renderMessageRow] }) }));
15
15
  }
@@ -2,6 +2,10 @@
2
2
  --gap: var(--spacing-sm);
3
3
  }
4
4
 
5
+ .horizontal[data-size='sm'] {
6
+ --gap: var(--spacing-xs);
7
+ }
8
+
5
9
  .labelContainer {
6
10
  gap: var(--gap);
7
11
  }
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { InputContainerProps } from '../input-container/InputContainer';
3
- export type TextareaProps = Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'onChange' | 'disabled'> & Omit<InputContainerProps, 'children' | 'htmlFor' | 'tooltip' | 'tooltipPlacement'> & {
3
+ export type TextareaProps = Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'onChange' | 'disabled'> & Omit<InputContainerProps, 'children' | 'htmlFor' | 'tooltip' | 'tooltipPlacement' | 'size'> & {
4
4
  value: string;
5
5
  inputChanged: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
6
6
  disabled?: boolean;
@@ -163,3 +163,23 @@
163
163
  align-items: center;
164
164
  gap: var(--spacing-xxs);
165
165
  }
166
+
167
+ @media (max-width: 767px) {
168
+ .headlineRow {
169
+ flex-direction: column;
170
+ align-items: flex-start;
171
+ gap: var(--spacing-md);
172
+ }
173
+
174
+ .headlineContainer h1.headline {
175
+ font-size: var(--font-size-xl);
176
+ }
177
+
178
+ .headlineContainer h2.headline {
179
+ font-size: var(--font-size-lg);
180
+ }
181
+
182
+ .addition {
183
+ inline-size: 100%;
184
+ }
185
+ }
@@ -190,6 +190,15 @@
190
190
  letter-spacing: 0.04em;
191
191
  cursor: default;
192
192
  user-select: none;
193
+ display: flex;
194
+ align-items: center;
195
+ gap: var(--spacing-xs);
196
+ }
197
+
198
+ .header svg {
199
+ inline-size: var(--icon-size-sm);
200
+ block-size: var(--icon-size-sm);
201
+ color: inherit;
193
202
  }
194
203
 
195
204
  /* Gap between items */
@@ -130,6 +130,13 @@
130
130
  margin-inline-start: auto;
131
131
  }
132
132
 
133
+ .mobileAddition {
134
+ display: flex;
135
+ flex-direction: column;
136
+ align-items: stretch;
137
+ gap: var(--spacing-xs);
138
+ }
139
+
133
140
  .navItem {
134
141
  list-style: none;
135
142
  min-inline-size: 0;
@@ -198,3 +205,17 @@
198
205
  block-size: var(--icon-size-md);
199
206
  flex: 0 0 auto;
200
207
  }
208
+
209
+ @media (max-width: 767px) {
210
+ .addition,
211
+ .mobileAddition {
212
+ flex-direction: column;
213
+ align-items: stretch;
214
+ gap: var(--spacing-xs);
215
+ }
216
+
217
+ .addition > *,
218
+ .mobileAddition > * {
219
+ width: 100%;
220
+ }
221
+ }
@@ -74,3 +74,16 @@
74
74
  border: 1px solid var(--color-border-default);
75
75
  border-radius: var(--border-radius-default);
76
76
  }
77
+
78
+ @media (max-width: 767px) {
79
+ .headerContainer {
80
+ padding-block: var(--spacing-md);
81
+ }
82
+
83
+ .content:not(.disableContentBox) {
84
+ padding-block: var(--spacing-md);
85
+ padding-inline: 0;
86
+ border: 0;
87
+ border-radius: 0;
88
+ }
89
+ }
@@ -1,12 +1,20 @@
1
1
  import React, { ElementType } from 'react';
2
2
  type GapSize = 'xxs' | 'xs' | 'sm' | 'md' | 'lg';
3
+ type StackDirection = 'row' | 'column';
4
+ type StackAlign = 'start' | 'center' | 'end';
5
+ type StackJustify = 'start' | 'center' | 'end' | 'between';
3
6
  type StackOwnProps = {
4
- direction?: 'row' | 'column';
7
+ direction?: StackDirection;
5
8
  gap?: GapSize;
6
- align?: 'start' | 'center' | 'end';
7
- justify?: 'start' | 'center' | 'end' | 'between';
9
+ align?: StackAlign;
10
+ justify?: StackJustify;
8
11
  grow?: boolean;
9
12
  wrap?: boolean;
13
+ mobileDirection?: StackDirection;
14
+ mobileGap?: GapSize;
15
+ mobileAlign?: StackAlign;
16
+ mobileJustify?: StackJustify;
17
+ mobileWrap?: boolean;
10
18
  };
11
19
  export type StackProps<C extends ElementType = 'div'> = StackOwnProps & {
12
20
  as?: C;
@@ -1,7 +1,8 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { forwardRef } from 'react';
4
- export const Stack = forwardRef(function Stack({ as, direction, gap, align, justify, grow = false, wrap = false, className, ...rest }, ref) {
4
+ import styles from './Stack.module.css';
5
+ export const Stack = forwardRef(function Stack({ as, direction, gap, align, justify, grow = false, wrap = false, mobileDirection, mobileGap, mobileAlign, mobileJustify, mobileWrap = false, className, ...rest }, ref) {
5
6
  const Tag = (as !== null && as !== void 0 ? as : 'div');
6
7
  const classes = [
7
8
  'dbc-flex',
@@ -11,6 +12,19 @@ export const Stack = forwardRef(function Stack({ as, direction, gap, align, just
11
12
  justify ? `dbc-justify-${justify}` : undefined,
12
13
  grow ? 'dbc-flex-grow' : undefined,
13
14
  wrap ? 'dbc-flex-wrap' : undefined,
15
+ mobileDirection
16
+ ? styles[`mobileDirection${mobileDirection.charAt(0).toUpperCase()}${mobileDirection.slice(1)}`]
17
+ : undefined,
18
+ mobileGap
19
+ ? styles[`mobileGap${mobileGap.charAt(0).toUpperCase()}${mobileGap.slice(1)}`]
20
+ : undefined,
21
+ mobileAlign
22
+ ? styles[`mobileAlign${mobileAlign.charAt(0).toUpperCase()}${mobileAlign.slice(1)}`]
23
+ : undefined,
24
+ mobileJustify
25
+ ? styles[`mobileJustify${mobileJustify.charAt(0).toUpperCase()}${mobileJustify.slice(1)}`]
26
+ : undefined,
27
+ mobileWrap ? styles.mobileWrap : undefined,
14
28
  className,
15
29
  ]
16
30
  .filter(Boolean)
@@ -0,0 +1,61 @@
1
+ @media (max-width: 767px) {
2
+ .mobileDirectionRow {
3
+ flex-direction: row;
4
+ }
5
+
6
+ .mobileDirectionColumn {
7
+ flex-direction: column;
8
+ }
9
+
10
+ .mobileGapXxs {
11
+ gap: var(--spacing-xxs);
12
+ }
13
+
14
+ .mobileGapXs {
15
+ gap: var(--spacing-xs);
16
+ }
17
+
18
+ .mobileGapSm {
19
+ gap: var(--spacing-sm);
20
+ }
21
+
22
+ .mobileGapMd {
23
+ gap: var(--spacing-md);
24
+ }
25
+
26
+ .mobileGapLg {
27
+ gap: var(--spacing-lg);
28
+ }
29
+
30
+ .mobileAlignStart {
31
+ align-items: flex-start;
32
+ }
33
+
34
+ .mobileAlignCenter {
35
+ align-items: center;
36
+ }
37
+
38
+ .mobileAlignEnd {
39
+ align-items: flex-end;
40
+ }
41
+
42
+ .mobileJustifyStart {
43
+ justify-content: flex-start;
44
+ }
45
+
46
+ .mobileJustifyCenter {
47
+ justify-content: center;
48
+ }
49
+
50
+ .mobileJustifyEnd {
51
+ justify-content: flex-end;
52
+ }
53
+
54
+ .mobileJustifyBetween {
55
+ justify-content: space-between;
56
+ }
57
+
58
+ .mobileWrap {
59
+ flex-wrap: wrap;
60
+ }
61
+ }
@@ -202,3 +202,32 @@
202
202
  background: var(--color-bg-surface);
203
203
  padding: var(--spacing-lg);
204
204
  }
205
+
206
+ @media (max-width: 767px) {
207
+ .headerContainer {
208
+ padding-block: var(--spacing-md);
209
+ }
210
+
211
+ .tabButton {
212
+ padding-block: var(--spacing-sm);
213
+ padding-inline: var(--spacing-xs);
214
+ }
215
+
216
+ .filled .tabList {
217
+ border-start-start-radius: 0;
218
+ border-start-end-radius: 0;
219
+ inline-size: 100%;
220
+ }
221
+
222
+ .filled .tabContent,
223
+ .panelStyle.outlined .tabContent {
224
+ padding-block: var(--spacing-md);
225
+ padding-inline: 0;
226
+ border: 0;
227
+ border-radius: 0;
228
+ }
229
+
230
+ .panelStyle .tabList {
231
+ border: 0;
232
+ }
233
+ }
@@ -1,5 +1,5 @@
1
1
  'use client';
2
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { Monitor, Moon, Palette, Sun } from 'lucide-react';
4
4
  import { Button } from '../../components/button/Button';
5
5
  import { Menu } from '../../components/menu/Menu';
@@ -12,7 +12,7 @@ const THEME_OPTIONS = [
12
12
  ];
13
13
  export function ThemeMenuSection() {
14
14
  const { theme, switchTheme } = useTheme();
15
- return (_jsxs(_Fragment, { children: [_jsx(Menu.Header, { children: "Udseende" }), THEME_OPTIONS.map(option => (_jsx(Menu.RadioItem, { name: "theme", value: option.value, checked: theme === option.value, label: option.label, onValueChange: value => switchTheme(value) }, option.value)))] }));
15
+ return (_jsxs(_Fragment, { children: [_jsxs(Menu.Header, { children: [_jsx(Palette, {}), "Udseende"] }), THEME_OPTIONS.map(option => (_jsx(Menu.RadioItem, { name: "theme", value: option.value, checked: theme === option.value, label: option.label, onValueChange: value => switchTheme(value) }, option.value)))] }));
16
16
  }
17
17
  export function ThemeButton({ size, variant = 'outlined' }) {
18
18
  const { theme, switchTheme } = useTheme();
package/dist/index.d.ts CHANGED
@@ -76,3 +76,4 @@ export * from './components/theme-button/ThemeButton';
76
76
  export * from './components/copy-button/CopyButton';
77
77
  export * from './components/divider/Divider';
78
78
  export * from './components/grid/Grid';
79
+ export * from './components/alert/Alert';
package/dist/index.js CHANGED
@@ -76,3 +76,4 @@ export * from './components/theme-button/ThemeButton';
76
76
  export * from './components/copy-button/CopyButton';
77
77
  export * from './components/divider/Divider';
78
78
  export * from './components/grid/Grid';
79
+ export * from './components/alert/Alert';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dbcdk/react-components",
3
- "version": "0.0.95",
3
+ "version": "0.0.96",
4
4
  "description": "Reusable React components for DBC projects",
5
5
  "license": "ISC",
6
6
  "author": "",