@lumx/react 3.8.0 → 3.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -6,8 +6,8 @@
6
6
  "url": "https://github.com/lumapps/design-system/issues"
7
7
  },
8
8
  "dependencies": {
9
- "@lumx/core": "^3.8.0",
10
- "@lumx/icons": "^3.8.0",
9
+ "@lumx/core": "^3.8.1",
10
+ "@lumx/icons": "^3.8.1",
11
11
  "@popperjs/core": "^2.5.4",
12
12
  "body-scroll-lock": "^3.1.5",
13
13
  "classnames": "^2.3.2",
@@ -111,5 +111,5 @@
111
111
  "build:storybook": "storybook build"
112
112
  },
113
113
  "sideEffects": false,
114
- "version": "3.8.0"
114
+ "version": "3.8.1"
115
115
  }
@@ -3,7 +3,10 @@ import { commonTestsSuiteRTL } from '@lumx/react/testing/utils';
3
3
 
4
4
  import { render } from '@testing-library/react';
5
5
  import { queryByClassName } from '@lumx/react/testing/utils/queries';
6
+ import { toNestedProps } from '@lumx/react/stories/decorators/withNestedProps';
7
+
6
8
  import { ImageBlock, ImageBlockProps } from './ImageBlock';
9
+ import { FullFeatured } from './ImageBlock.stories';
7
10
 
8
11
  const CLASSNAME = ImageBlock.className as string;
9
12
 
@@ -14,6 +17,31 @@ const setup = (props: Partial<ImageBlockProps> = {}) => {
14
17
  };
15
18
 
16
19
  describe(`<${ImageBlock.displayName}>`, () => {
20
+ it('should render caption elements', () => {
21
+ const props = {
22
+ ...toNestedProps(FullFeatured.args),
23
+ titleProps: { className: 'custom-title-class' },
24
+ descriptionProps: { className: 'custom-description-class' },
25
+ };
26
+ const { imageBlock } = setup(props);
27
+ const wrapper = queryByClassName(imageBlock as HTMLElement, 'lumx-image-block__wrapper');
28
+ expect(wrapper).toBeInTheDocument();
29
+
30
+ const caption = queryByClassName(wrapper as HTMLElement, 'lumx-image-block__caption');
31
+ expect(caption).toBeInTheDocument();
32
+
33
+ const title = queryByClassName(caption as HTMLElement, 'lumx-image-block__title');
34
+ expect(title).toBeInTheDocument();
35
+ expect(title).toHaveClass(props.titleProps.className);
36
+
37
+ const description = queryByClassName(caption as HTMLElement, 'lumx-image-block__description');
38
+ expect(description).toBeInTheDocument();
39
+ expect(description).toHaveClass(props.descriptionProps.className);
40
+
41
+ const tags = queryByClassName(wrapper as HTMLElement, 'lumx-image-block__tags');
42
+ expect(tags).toBeInTheDocument();
43
+ });
44
+
17
45
  // Common tests suite.
18
46
  commonTestsSuiteRTL(setup, {
19
47
  baseClassName: CLASSNAME,
@@ -81,6 +81,7 @@ export const ImageBlock: Comp<ImageBlockProps, HTMLDivElement> = forwardRef((pro
81
81
  captionStyle,
82
82
  className,
83
83
  description,
84
+ descriptionProps,
84
85
  fillHeight,
85
86
  image,
86
87
  size,
@@ -88,6 +89,7 @@ export const ImageBlock: Comp<ImageBlockProps, HTMLDivElement> = forwardRef((pro
88
89
  theme,
89
90
  thumbnailProps,
90
91
  title,
92
+ titleProps,
91
93
  ...forwardedProps
92
94
  } = props;
93
95
  return (
@@ -118,10 +120,12 @@ export const ImageBlock: Comp<ImageBlockProps, HTMLDivElement> = forwardRef((pro
118
120
  />
119
121
  <ImageCaption
120
122
  as="figcaption"
121
- className={`${CLASSNAME}__wrapper`}
123
+ baseClassName={CLASSNAME}
122
124
  theme={theme}
123
125
  title={title}
126
+ titleProps={titleProps}
124
127
  description={description}
128
+ descriptionProps={descriptionProps}
125
129
  tags={tags}
126
130
  captionStyle={captionStyle}
127
131
  align={align}
@@ -1,15 +1,22 @@
1
1
  import React, { CSSProperties, ReactNode } from 'react';
2
2
 
3
3
  import { FlexBox, HorizontalAlignment, Text, TextProps } from '@lumx/react';
4
- import { HasClassName, HasPolymorphicAs, HasTheme } from '@lumx/react/utils/type';
4
+ import { HasPolymorphicAs, HasTheme } from '@lumx/react/utils/type';
5
+ import classNames from 'classnames';
5
6
 
6
7
  type As = 'div' | 'figcaption';
7
8
 
9
+ type ForwardedTextProps = Omit<TextProps, 'as' | 'typography' | 'color' | 'colorVariant'>;
10
+
8
11
  export type ImageCaptionMetadata = {
9
12
  /** Image title to display in the caption. */
10
13
  title?: string;
14
+ /** Props to pass to the title. */
15
+ titleProps?: ForwardedTextProps;
11
16
  /** Image description. Can be either a string, or sanitized html. */
12
17
  description?: string | { __html: string };
18
+ /** Props to pass to the title. */
19
+ descriptionProps?: ForwardedTextProps;
13
20
  /** Tag content. */
14
21
  tags?: ReactNode;
15
22
  /** Caption custom CSS style. */
@@ -17,9 +24,10 @@ export type ImageCaptionMetadata = {
17
24
  };
18
25
 
19
26
  export type ImageCaptionProps<AS extends As = 'figcaption'> = HasTheme &
20
- HasClassName &
21
27
  HasPolymorphicAs<AS> &
22
28
  ImageCaptionMetadata & {
29
+ /** Base className for sub elements */
30
+ baseClassName?: string;
23
31
  /** Alignment. */
24
32
  align?: HorizontalAlignment;
25
33
  /** Truncate text on title & description (no line wrapping). */
@@ -28,7 +36,19 @@ export type ImageCaptionProps<AS extends As = 'figcaption'> = HasTheme &
28
36
 
29
37
  /** Internal component used to render image captions */
30
38
  export const ImageCaption = <AS extends As>(props: ImageCaptionProps<AS>) => {
31
- const { className, theme, as = 'figcaption', title, description, tags, captionStyle, align, truncate } = props;
39
+ const {
40
+ baseClassName,
41
+ theme,
42
+ as = 'figcaption',
43
+ title,
44
+ titleProps,
45
+ description,
46
+ descriptionProps,
47
+ tags,
48
+ captionStyle,
49
+ align,
50
+ truncate,
51
+ } = props;
32
52
  if (!title && !description && !tags) return null;
33
53
 
34
54
  const titleColor = { color: theme === 'dark' ? 'light' : 'dark' } as const;
@@ -41,7 +61,7 @@ export const ImageCaption = <AS extends As>(props: ImageCaptionProps<AS>) => {
41
61
  return (
42
62
  <FlexBox
43
63
  as={as}
44
- className={className}
64
+ className={classNames(baseClassName && `${baseClassName}__wrapper`)}
45
65
  style={captionStyle}
46
66
  orientation="vertical"
47
67
  vAlign={align}
@@ -49,17 +69,43 @@ export const ImageCaption = <AS extends As>(props: ImageCaptionProps<AS>) => {
49
69
  gap="regular"
50
70
  >
51
71
  {(title || description) && (
52
- <Text as="p" truncate={truncate} {...baseColor}>
72
+ <Text
73
+ as="p"
74
+ className={classNames(baseClassName && `${baseClassName}__caption`)}
75
+ truncate={truncate}
76
+ {...baseColor}
77
+ >
53
78
  {title && (
54
- <Text as="span" typography="subtitle1" {...titleColor}>
79
+ <Text
80
+ {...titleProps}
81
+ as="span"
82
+ className={classNames(titleProps?.className, baseClassName && `${baseClassName}__title`)}
83
+ typography="subtitle1"
84
+ {...titleColor}
85
+ >
55
86
  {title}
56
87
  </Text>
57
88
  )}{' '}
58
- {description && <Text as="span" typography="body1" {...descriptionContent} />}
89
+ {description && (
90
+ <Text
91
+ {...descriptionProps}
92
+ as="span"
93
+ className={classNames(
94
+ descriptionProps?.className,
95
+ baseClassName && `${baseClassName}__description`,
96
+ )}
97
+ typography="body1"
98
+ {...descriptionContent}
99
+ />
100
+ )}
59
101
  </Text>
60
102
  )}
61
103
  {tags && (
62
- <FlexBox orientation="horizontal" vAlign={align}>
104
+ <FlexBox
105
+ className={classNames(baseClassName && `${baseClassName}__tags`)}
106
+ orientation="horizontal"
107
+ vAlign={align}
108
+ >
63
109
  {tags}
64
110
  </FlexBox>
65
111
  )}