@dbcdk/react-components 0.0.110 → 0.0.112

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.
@@ -47,6 +47,7 @@ const Input = react.forwardRef(function Input2({
47
47
  buttonDisabled = false,
48
48
  buttonLabel,
49
49
  buttonIcon,
50
+ buttonAriaLabel,
50
51
  trailingLabel,
51
52
  id,
52
53
  tooltipOpenOnFocus = true,
@@ -172,6 +173,7 @@ const Input = react.forwardRef(function Input2({
172
173
  type: "button",
173
174
  variant: trailingButtonVariant,
174
175
  size: inputSize,
176
+ "aria-label": buttonAriaLabel,
175
177
  children: [
176
178
  buttonIcon != null ? buttonIcon : null,
177
179
  buttonLabel != null ? buttonLabel : null
@@ -16,6 +16,7 @@ export type InputProps = Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size
16
16
  buttonDisabled?: boolean;
17
17
  buttonLabel?: string;
18
18
  buttonIcon?: React.ReactNode;
19
+ buttonAriaLabel?: string;
19
20
  trailingLabel?: string;
20
21
  tooltip?: React.ReactNode;
21
22
  tooltipPlacement?: 'top' | 'right' | 'bottom' | 'left';
@@ -41,6 +41,7 @@ const Input = forwardRef(function Input2({
41
41
  buttonDisabled = false,
42
42
  buttonLabel,
43
43
  buttonIcon,
44
+ buttonAriaLabel,
44
45
  trailingLabel,
45
46
  id,
46
47
  tooltipOpenOnFocus = true,
@@ -166,6 +167,7 @@ const Input = forwardRef(function Input2({
166
167
  type: "button",
167
168
  variant: trailingButtonVariant,
168
169
  size: inputSize,
170
+ "aria-label": buttonAriaLabel,
169
171
  children: [
170
172
  buttonIcon != null ? buttonIcon : null,
171
173
  buttonLabel != null ? buttonLabel : null
@@ -2,17 +2,24 @@
2
2
  'use strict';
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
+ var React = require('react');
5
6
  var styles = require('./MediaCard.module.css');
6
7
  var SkeletonLoaderItem = require('../skeleton-loader/skeleton-loader-item/SkeletonLoaderItem');
7
8
 
8
9
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
10
 
11
+ var React__default = /*#__PURE__*/_interopDefault(React);
10
12
  var styles__default = /*#__PURE__*/_interopDefault(styles);
11
13
 
14
+ function cx(...parts) {
15
+ return parts.filter(Boolean).join(" ");
16
+ }
12
17
  function MediaCard({
13
18
  src,
14
19
  alt,
15
20
  href,
21
+ component: Component,
22
+ linkElement,
16
23
  loading = false,
17
24
  aspectRatio = "1 / 1",
18
25
  objectFit = "cover",
@@ -24,12 +31,13 @@ function MediaCard({
24
31
  imageClassName,
25
32
  linkProps
26
33
  }) {
27
- const isInteractive = Boolean(href);
34
+ var _a;
35
+ const isInteractive = Boolean(href || Component || linkElement);
28
36
  const hasCaption = showCaption && (caption || meta);
29
37
  const content = /* @__PURE__ */ jsxRuntime.jsx(
30
38
  "figure",
31
39
  {
32
- className: [styles__default.default.root, isInteractive ? styles__default.default.interactive : "", className != null ? className : ""].join(" "),
40
+ className: cx(styles__default.default.root, isInteractive ? styles__default.default.interactive : void 0, className),
33
41
  style: { "--media-card-aspect-ratio": aspectRatio },
34
42
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles__default.default.media, children: [
35
43
  loading || !src ? /* @__PURE__ */ jsxRuntime.jsx(SkeletonLoaderItem.SkeletonLoaderItem, { height: "100%" }) : /* @__PURE__ */ jsxRuntime.jsx(
@@ -37,7 +45,7 @@ function MediaCard({
37
45
  {
38
46
  src,
39
47
  alt,
40
- className: [styles__default.default.image, imageClassName != null ? imageClassName : ""].join(" "),
48
+ className: cx(styles__default.default.image, imageClassName),
41
49
  style: {
42
50
  objectFit,
43
51
  objectPosition
@@ -51,10 +59,29 @@ function MediaCard({
51
59
  ] })
52
60
  }
53
61
  );
54
- if (!href) {
62
+ if (!isInteractive) {
55
63
  return content;
56
64
  }
57
- return /* @__PURE__ */ jsxRuntime.jsx("a", { href, className: styles__default.default.link, ...linkProps, children: content });
65
+ const wrapperProps = {
66
+ ...linkProps,
67
+ ...href ? { href } : {},
68
+ className: cx(styles__default.default.link, linkProps == null ? void 0 : linkProps.className),
69
+ children: content
70
+ };
71
+ if (linkElement) {
72
+ const child = linkElement;
73
+ const childProps = (_a = child.props) != null ? _a : {};
74
+ return React__default.default.cloneElement(child, {
75
+ ...childProps,
76
+ ...wrapperProps,
77
+ className: cx(childProps.className, wrapperProps.className),
78
+ href: href != null ? href : childProps.href
79
+ });
80
+ }
81
+ if (Component) {
82
+ return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...wrapperProps });
83
+ }
84
+ return /* @__PURE__ */ jsxRuntime.jsx("a", { ...wrapperProps });
58
85
  }
59
86
 
60
87
  exports.MediaCard = MediaCard;
@@ -1,9 +1,11 @@
1
- import type { AnchorHTMLAttributes, CSSProperties, ReactNode } from 'react';
1
+ import type { AnchorHTMLAttributes, CSSProperties, ElementType, ReactElement, ReactNode } from 'react';
2
2
  type AspectRatio = '1 / 1' | '4 / 3' | '3 / 4' | '16 / 9' | string;
3
3
  export type MediaCardProps = {
4
4
  src?: string;
5
5
  alt: string;
6
6
  href?: string;
7
+ component?: ElementType<any>;
8
+ linkElement?: ReactElement<any>;
7
9
  loading?: boolean;
8
10
  aspectRatio?: AspectRatio;
9
11
  objectFit?: CSSProperties['objectFit'];
@@ -15,5 +17,5 @@ export type MediaCardProps = {
15
17
  imageClassName?: string;
16
18
  linkProps?: Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href' | 'children'>;
17
19
  };
18
- export declare function MediaCard({ src, alt, href, loading, aspectRatio, objectFit, objectPosition, caption, meta, showCaption, className, imageClassName, linkProps, }: MediaCardProps): import("react/jsx-runtime").JSX.Element;
20
+ export declare function MediaCard({ src, alt, href, component: Component, linkElement, loading, aspectRatio, objectFit, objectPosition, caption, meta, showCaption, className, imageClassName, linkProps, }: MediaCardProps): import("react/jsx-runtime").JSX.Element;
19
21
  export {};
@@ -1,12 +1,18 @@
1
1
  'use client';
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import React from 'react';
3
4
  import styles from './MediaCard.module.css';
4
5
  import { SkeletonLoaderItem } from '../skeleton-loader/skeleton-loader-item/SkeletonLoaderItem';
5
6
 
7
+ function cx(...parts) {
8
+ return parts.filter(Boolean).join(" ");
9
+ }
6
10
  function MediaCard({
7
11
  src,
8
12
  alt,
9
13
  href,
14
+ component: Component,
15
+ linkElement,
10
16
  loading = false,
11
17
  aspectRatio = "1 / 1",
12
18
  objectFit = "cover",
@@ -18,12 +24,13 @@ function MediaCard({
18
24
  imageClassName,
19
25
  linkProps
20
26
  }) {
21
- const isInteractive = Boolean(href);
27
+ var _a;
28
+ const isInteractive = Boolean(href || Component || linkElement);
22
29
  const hasCaption = showCaption && (caption || meta);
23
30
  const content = /* @__PURE__ */ jsx(
24
31
  "figure",
25
32
  {
26
- className: [styles.root, isInteractive ? styles.interactive : "", className != null ? className : ""].join(" "),
33
+ className: cx(styles.root, isInteractive ? styles.interactive : void 0, className),
27
34
  style: { "--media-card-aspect-ratio": aspectRatio },
28
35
  children: /* @__PURE__ */ jsxs("div", { className: styles.media, children: [
29
36
  loading || !src ? /* @__PURE__ */ jsx(SkeletonLoaderItem, { height: "100%" }) : /* @__PURE__ */ jsx(
@@ -31,7 +38,7 @@ function MediaCard({
31
38
  {
32
39
  src,
33
40
  alt,
34
- className: [styles.image, imageClassName != null ? imageClassName : ""].join(" "),
41
+ className: cx(styles.image, imageClassName),
35
42
  style: {
36
43
  objectFit,
37
44
  objectPosition
@@ -45,10 +52,29 @@ function MediaCard({
45
52
  ] })
46
53
  }
47
54
  );
48
- if (!href) {
55
+ if (!isInteractive) {
49
56
  return content;
50
57
  }
51
- return /* @__PURE__ */ jsx("a", { href, className: styles.link, ...linkProps, children: content });
58
+ const wrapperProps = {
59
+ ...linkProps,
60
+ ...href ? { href } : {},
61
+ className: cx(styles.link, linkProps == null ? void 0 : linkProps.className),
62
+ children: content
63
+ };
64
+ if (linkElement) {
65
+ const child = linkElement;
66
+ const childProps = (_a = child.props) != null ? _a : {};
67
+ return React.cloneElement(child, {
68
+ ...childProps,
69
+ ...wrapperProps,
70
+ className: cx(childProps.className, wrapperProps.className),
71
+ href: href != null ? href : childProps.href
72
+ });
73
+ }
74
+ if (Component) {
75
+ return /* @__PURE__ */ jsx(Component, { ...wrapperProps });
76
+ }
77
+ return /* @__PURE__ */ jsx("a", { ...wrapperProps });
52
78
  }
53
79
 
54
80
  export { MediaCard };
@@ -62,8 +62,7 @@
62
62
  background: var(--overlay-scrim);
63
63
  backdrop-filter: blur(var(--backdrop-blur));
64
64
 
65
- font-size: var(--font-size-md);
66
- font-weight: var(--font-weight-bold);
65
+ font-size: var(--font-size-sm);
67
66
  line-height: var(--line-height-tight);
68
67
  letter-spacing: var(--letter-spacing-wide);
69
68
  }
@@ -34,6 +34,7 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
34
34
  onButtonClick,
35
35
  buttonLabel,
36
36
  buttonIcon,
37
+ buttonAriaLabel,
37
38
  fullWidth = false,
38
39
  value,
39
40
  onChange,
@@ -120,6 +121,7 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
120
121
  }, [result]);
121
122
  const showInputIcon = !onButtonClick || !!buttonLabel || !!buttonIcon;
122
123
  const trailingButtonIcon = onButtonClick && !buttonLabel && !buttonIcon ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, {}) : buttonIcon;
124
+ const trailingButtonAriaLabel = buttonAriaLabel != null ? buttonAriaLabel : onButtonClick && !buttonLabel ? "S\xF8g" : void 0;
123
125
  const activeOptionId = activeIndex !== null && (result == null ? void 0 : result.length) ? `${listboxId}-option-${activeIndex}` : void 0;
124
126
  const inputProps = {
125
127
  ...rest,
@@ -147,6 +149,7 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
147
149
  onButtonClick,
148
150
  buttonLabel,
149
151
  buttonIcon: trailingButtonIcon,
152
+ buttonAriaLabel: trailingButtonAriaLabel,
150
153
  ...inputProps,
151
154
  placeholder: (_a = rest.placeholder) != null ? _a : "Indtast s\xF8geord"
152
155
  }
@@ -228,6 +231,7 @@ const SearchBox = react.forwardRef(function SearchBoxInner({
228
231
  onButtonClick,
229
232
  buttonLabel,
230
233
  buttonIcon: trailingButtonIcon,
234
+ buttonAriaLabel: trailingButtonAriaLabel,
231
235
  ...inputProps,
232
236
  onKeyDown: (e) => {
233
237
  var _a3;
@@ -23,6 +23,7 @@ type SearchBoxProps<T extends Record<string, unknown>> = {
23
23
  onButtonClick?: () => void;
24
24
  buttonLabel?: string;
25
25
  buttonIcon?: React.ReactNode;
26
+ buttonAriaLabel?: string;
26
27
  } & React.InputHTMLAttributes<HTMLInputElement>;
27
28
  type SearchBoxComponent = <T extends Record<string, unknown>>(props: SearchBoxProps<T> & React.RefAttributes<HTMLInputElement>) => React.ReactElement | null;
28
29
  export declare const SearchBox: SearchBoxComponent;
@@ -28,6 +28,7 @@ const SearchBox = forwardRef(function SearchBoxInner({
28
28
  onButtonClick,
29
29
  buttonLabel,
30
30
  buttonIcon,
31
+ buttonAriaLabel,
31
32
  fullWidth = false,
32
33
  value,
33
34
  onChange,
@@ -114,6 +115,7 @@ const SearchBox = forwardRef(function SearchBoxInner({
114
115
  }, [result]);
115
116
  const showInputIcon = !onButtonClick || !!buttonLabel || !!buttonIcon;
116
117
  const trailingButtonIcon = onButtonClick && !buttonLabel && !buttonIcon ? /* @__PURE__ */ jsx(Search, {}) : buttonIcon;
118
+ const trailingButtonAriaLabel = buttonAriaLabel != null ? buttonAriaLabel : onButtonClick && !buttonLabel ? "S\xF8g" : void 0;
117
119
  const activeOptionId = activeIndex !== null && (result == null ? void 0 : result.length) ? `${listboxId}-option-${activeIndex}` : void 0;
118
120
  const inputProps = {
119
121
  ...rest,
@@ -141,6 +143,7 @@ const SearchBox = forwardRef(function SearchBoxInner({
141
143
  onButtonClick,
142
144
  buttonLabel,
143
145
  buttonIcon: trailingButtonIcon,
146
+ buttonAriaLabel: trailingButtonAriaLabel,
144
147
  ...inputProps,
145
148
  placeholder: (_a = rest.placeholder) != null ? _a : "Indtast s\xF8geord"
146
149
  }
@@ -222,6 +225,7 @@ const SearchBox = forwardRef(function SearchBoxInner({
222
225
  onButtonClick,
223
226
  buttonLabel,
224
227
  buttonIcon: trailingButtonIcon,
228
+ buttonAriaLabel: trailingButtonAriaLabel,
225
229
  ...inputProps,
226
230
  onKeyDown: (e) => {
227
231
  var _a3;
@@ -16,10 +16,7 @@ const THEME_OPTIONS = [
16
16
  function ThemeMenuSection() {
17
17
  const { theme, switchTheme } = useTheme.useTheme();
18
18
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
19
- /* @__PURE__ */ jsxRuntime.jsxs(Menu.Menu.Header, { children: [
20
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Palette, {}),
21
- "Udseende"
22
- ] }),
19
+ /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Header, { children: "Udseende" }),
23
20
  THEME_OPTIONS.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
24
21
  Menu.Menu.RadioItem,
25
22
  {
@@ -14,10 +14,7 @@ const THEME_OPTIONS = [
14
14
  function ThemeMenuSection() {
15
15
  const { theme, switchTheme } = useTheme();
16
16
  return /* @__PURE__ */ jsxs(Fragment, { children: [
17
- /* @__PURE__ */ jsxs(Menu.Header, { children: [
18
- /* @__PURE__ */ jsx(Palette, {}),
19
- "Udseende"
20
- ] }),
17
+ /* @__PURE__ */ jsx(Menu.Header, { children: "Udseende" }),
21
18
  THEME_OPTIONS.map((option) => /* @__PURE__ */ jsx(
22
19
  Menu.RadioItem,
23
20
  {
@@ -99,6 +99,7 @@
99
99
  --ease-accelerate: cubic-bezier(0.4, 0, 1, 1);
100
100
 
101
101
  /* Elevation & Overlay */
102
+ --overlay-scrim-subtle: rgba(0, 0, 0, 0.2);
102
103
  --overlay-scrim: rgba(0, 0, 0, 0.5);
103
104
  --backdrop-blur: 8px;
104
105
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dbcdk/react-components",
3
- "version": "0.0.110",
3
+ "version": "0.0.112",
4
4
  "description": "Reusable React components for DBC projects",
5
5
  "license": "ISC",
6
6
  "author": "",