@lumx/react 3.18.2-alpha.4 → 3.19.1-alpha.0
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/index.d.ts +201 -117
- package/index.js +470 -480
- package/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/alert-dialog/AlertDialog.tsx +1 -1
- package/src/components/autocomplete/Autocomplete.tsx +1 -1
- package/src/components/autocomplete/AutocompleteMultiple.tsx +1 -1
- package/src/components/avatar/Avatar.tsx +1 -1
- package/src/components/badge/Badge.tsx +1 -1
- package/src/components/badge/BadgeWrapper.tsx +1 -1
- package/src/components/button/Button.test.tsx +5 -5
- package/src/components/button/Button.tsx +1 -1
- package/src/components/button/ButtonGroup.tsx +1 -1
- package/src/components/button/ButtonRoot.tsx +7 -37
- package/src/components/button/IconButton.tsx +1 -1
- package/src/components/checkbox/Checkbox.tsx +1 -1
- package/src/components/chip/Chip.tsx +2 -2
- package/src/components/chip/ChipGroup.tsx +2 -2
- package/src/components/comment-block/CommentBlock.tsx +1 -1
- package/src/components/date-picker/DatePickerControlled.tsx +1 -1
- package/src/components/date-picker/constants.ts +1 -1
- package/src/components/dialog/Dialog.tsx +1 -1
- package/src/components/divider/Divider.tsx +1 -1
- package/src/components/drag-handle/DragHandle.tsx +1 -1
- package/src/components/dropdown/Dropdown.tsx +1 -1
- package/src/components/expansion-panel/ExpansionPanel.tsx +1 -1
- package/src/components/flag/Flag.tsx +1 -1
- package/src/components/flex-box/FlexBox.tsx +2 -3
- package/src/components/generic-block/GenericBlock.tsx +1 -1
- package/src/components/grid/Grid.tsx +1 -1
- package/src/components/grid/GridItem.tsx +1 -1
- package/src/components/grid-column/GridColumn.tsx +1 -1
- package/src/components/heading/Heading.tsx +1 -1
- package/src/components/heading/constants.ts +1 -1
- package/src/components/icon/Icon.tsx +1 -1
- package/src/components/image-block/ImageBlock.tsx +1 -1
- package/src/components/image-lightbox/constants.ts +1 -1
- package/src/components/inline-list/InlineList.tsx +1 -1
- package/src/components/input-helper/InputHelper.tsx +1 -1
- package/src/components/input-label/InputLabel.test.tsx +1 -1
- package/src/components/input-label/InputLabel.tsx +1 -1
- package/src/components/lightbox/Lightbox.tsx +1 -1
- package/src/components/link/Link.test.tsx +8 -6
- package/src/components/link/Link.tsx +10 -21
- package/src/components/link-preview/LinkPreview.stories.tsx +1 -1
- package/src/components/link-preview/LinkPreview.test.tsx +1 -1
- package/src/components/link-preview/LinkPreview.tsx +1 -1
- package/src/components/list/List.tsx +1 -1
- package/src/components/list/ListDivider.tsx +1 -1
- package/src/components/list/ListItem.test.tsx +1 -3
- package/src/components/list/ListItem.tsx +20 -33
- package/src/components/list/ListSubheader.tsx +1 -1
- package/src/components/message/Message.tsx +1 -1
- package/src/components/mosaic/Mosaic.tsx +1 -1
- package/src/components/navigation/Navigation.test.tsx +1 -1
- package/src/components/navigation/Navigation.tsx +1 -1
- package/src/components/navigation/NavigationItem.tsx +8 -12
- package/src/components/navigation/NavigationSection.test.tsx +2 -1
- package/src/components/navigation/NavigationSection.tsx +5 -4
- package/src/components/navigation/context.tsx +2 -1
- package/src/components/notification/Notification.tsx +1 -1
- package/src/components/popover/Popover.tsx +1 -1
- package/src/components/popover-dialog/PopoverDialog.tsx +1 -1
- package/src/components/post-block/PostBlock.tsx +1 -1
- package/src/components/progress/Progress.tsx +1 -1
- package/src/components/progress/ProgressCircular.tsx +1 -1
- package/src/components/progress/ProgressLinear.tsx +1 -1
- package/src/components/progress-tracker/ProgressTracker.tsx +1 -1
- package/src/components/progress-tracker/ProgressTrackerStep.tsx +1 -1
- package/src/components/progress-tracker/ProgressTrackerStepPanel.tsx +1 -1
- package/src/components/radio-button/RadioButton.tsx +1 -1
- package/src/components/radio-button/RadioGroup.tsx +1 -1
- package/src/components/select/Select.test.tsx +1 -1
- package/src/components/select/Select.tsx +2 -2
- package/src/components/select/SelectMultiple.test.tsx +1 -1
- package/src/components/select/SelectMultiple.tsx +2 -2
- package/src/components/select/WithSelectContext.tsx +2 -2
- package/src/components/side-navigation/SideNavigation.tsx +1 -1
- package/src/components/side-navigation/SideNavigationItem.tsx +23 -28
- package/src/components/skeleton/SkeletonCircle.tsx +1 -1
- package/src/components/skeleton/SkeletonRectangle.tsx +1 -1
- package/src/components/skeleton/SkeletonTypography.tsx +1 -1
- package/src/components/slider/Slider.tsx +1 -1
- package/src/components/slideshow/Slides.tsx +1 -1
- package/src/components/slideshow/SlideshowControls.tsx +1 -1
- package/src/components/slideshow/SlideshowItem.tsx +1 -1
- package/src/components/slideshow/SlideshowItemGroup.tsx +1 -1
- package/src/components/switch/Switch.tsx +1 -1
- package/src/components/table/Table.tsx +1 -1
- package/src/components/table/TableBody.tsx +1 -1
- package/src/components/table/TableCell.tsx +1 -1
- package/src/components/table/TableHeader.tsx +1 -1
- package/src/components/table/TableRow.tsx +1 -1
- package/src/components/tabs/Tab.tsx +1 -1
- package/src/components/tabs/TabList.tsx +1 -1
- package/src/components/tabs/TabPanel.tsx +1 -1
- package/src/components/text/Text.stories.tsx +23 -1
- package/src/components/text/Text.tsx +2 -2
- package/src/components/text-field/TextField.test.tsx +1 -1
- package/src/components/text-field/TextField.tsx +1 -1
- package/src/components/thumbnail/Thumbnail.tsx +7 -12
- package/src/components/thumbnail/useFocusPointStyle.tsx +1 -1
- package/src/components/toolbar/Toolbar.tsx +1 -1
- package/src/components/tooltip/Tooltip.tsx +1 -1
- package/src/components/uploader/Uploader.tsx +1 -1
- package/src/components/user-block/UserBlock.tsx +1 -1
- package/src/hooks/useCallbackOnEscape.ts +1 -1
- package/src/hooks/useOverflowTooltipLabel.tsx +21 -18
- package/src/index.ts +3 -1
- package/src/utils/partitionMulti.ts +2 -1
- package/src/utils/react/RawClickable.test.tsx +153 -0
- package/src/utils/react/RawClickable.tsx +65 -0
- package/src/utils/type/HasRequiredLinkHref.ts +1 -0
- package/src/utils/type/index.ts +3 -13
- package/src/components/index.ts +0 -160
- package/src/utils/browser/event.ts +0 -1
- package/src/utils/className/fontColorClass.test.ts +0 -15
- package/src/utils/className/fontColorClass.ts +0 -12
- package/src/utils/className/getBasicClass.test.ts +0 -20
- package/src/utils/className/getRootClassName.test.ts +0 -11
- package/src/utils/className/getRootClassName.ts +0 -24
- package/src/utils/className/getTypographyClassName.test.ts +0 -7
- package/src/utils/className/getTypographyClassName.ts +0 -9
- package/src/utils/className/handleBasicClasses.test.ts +0 -28
- package/src/utils/className/index.ts +0 -5
- package/src/utils/className/resolveColorWithVariants.test.ts +0 -33
- package/src/utils/className/resolveColorWithVariants.ts +0 -11
- package/src/utils/react/renderButtonOrLink.tsx +0 -16
- package/src/utils/react/renderLink.tsx +0 -17
- package/src/utils/type/Callback.ts +0 -4
- package/src/utils/type/Falsy.ts +0 -5
- package/src/utils/type/GenericProps.ts +0 -11
- package/src/utils/type/HasAriaLabelOrLabelledBy.ts +0 -19
- package/src/utils/type/HasClassName.ts +0 -6
- package/src/utils/type/HasCloseMode.ts +0 -7
- package/src/utils/type/HasTheme.ts +0 -8
- package/src/utils/type/HeadingElement.ts +0 -2
- package/src/utils/type/Point.ts +0 -4
- package/src/utils/type/Predicate.ts +0 -2
- package/src/utils/type/RectSize.ts +0 -4
- package/src/utils/type/TextElement.ts +0 -4
- package/src/utils/type/ValueOf.ts +0 -2
- package/src/utils/type/color/index.ts +0 -43
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import userEvent from '@testing-library/user-event';
|
|
4
|
+
import { RawClickable, RawClickableProps } from './RawClickable';
|
|
5
|
+
import { CustomLink } from '../../stories/utils/CustomLink';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Mounts the component and returns common DOM elements / data needed in multiple tests.
|
|
9
|
+
*/
|
|
10
|
+
const setup = (props: RawClickableProps<any>) => {
|
|
11
|
+
render(<RawClickable {...props} data-testid="raw-element" />);
|
|
12
|
+
const element = screen.getByTestId('raw-element');
|
|
13
|
+
return { props, element };
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
describe(`<RawClickable>`, () => {
|
|
17
|
+
describe('as a button', () => {
|
|
18
|
+
it('should render a button by default', () => {
|
|
19
|
+
const { element } = setup({ as: 'button', children: 'Click me' });
|
|
20
|
+
expect(element.tagName).toBe('BUTTON');
|
|
21
|
+
expect(element).toHaveAttribute('type', 'button');
|
|
22
|
+
expect(screen.getByRole('button', { name: 'Click me' })).toBe(element);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it('should trigger onClick', async () => {
|
|
26
|
+
const onClick = jest.fn();
|
|
27
|
+
const { element } = setup({ as: 'button', children: 'Click me', onClick });
|
|
28
|
+
await userEvent.click(element);
|
|
29
|
+
expect(onClick).toHaveBeenCalledTimes(1);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should be disabled with `disabled` prop', async () => {
|
|
33
|
+
const onClick = jest.fn();
|
|
34
|
+
const { element } = setup({ as: 'button', children: 'Click me', onClick, disabled: true });
|
|
35
|
+
expect(element).toBeDisabled();
|
|
36
|
+
await userEvent.click(element);
|
|
37
|
+
expect(onClick).not.toHaveBeenCalled();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should be disabled with `isDisabled` prop', async () => {
|
|
41
|
+
const onClick = jest.fn();
|
|
42
|
+
const { element } = setup({ as: 'button', children: 'Click me', onClick, isDisabled: true });
|
|
43
|
+
expect(element).toBeDisabled();
|
|
44
|
+
await userEvent.click(element);
|
|
45
|
+
expect(onClick).not.toHaveBeenCalled();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should be aria-disabled with `aria-disabled` prop', async () => {
|
|
49
|
+
const onClick = jest.fn();
|
|
50
|
+
const { element } = setup({ as: 'button', children: 'Click me', onClick, 'aria-disabled': true });
|
|
51
|
+
expect(element).not.toBeDisabled();
|
|
52
|
+
expect(element).toHaveAttribute('aria-disabled', 'true');
|
|
53
|
+
await userEvent.click(element);
|
|
54
|
+
expect(onClick).not.toHaveBeenCalled();
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
describe('as a link', () => {
|
|
59
|
+
const href = 'https://example.com';
|
|
60
|
+
|
|
61
|
+
it('should render a link with `href` prop', () => {
|
|
62
|
+
const { element } = setup({ as: 'a', children: 'Click me', href });
|
|
63
|
+
expect(element.tagName).toBe('A');
|
|
64
|
+
expect(element).toHaveAttribute('href', href);
|
|
65
|
+
expect(screen.getByRole('link', { name: 'Click me' })).toBe(element);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('should trigger onClick', async () => {
|
|
69
|
+
const onClick = jest.fn((evt) => evt.preventDefault());
|
|
70
|
+
const { element } = setup({ as: 'a', children: 'Click me', href, onClick });
|
|
71
|
+
await userEvent.click(element);
|
|
72
|
+
expect(onClick).toHaveBeenCalledTimes(1);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should be disabled with `disabled` prop', async () => {
|
|
76
|
+
const onClick = jest.fn();
|
|
77
|
+
const { element } = setup({ as: 'a', children: 'Click me', href, onClick, disabled: true });
|
|
78
|
+
expect(element).toHaveAttribute('aria-disabled', 'true');
|
|
79
|
+
expect(element).toHaveAttribute('tabindex', '-1');
|
|
80
|
+
await userEvent.click(element);
|
|
81
|
+
expect(onClick).not.toHaveBeenCalled();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should be disabled with `isDisabled` prop', async () => {
|
|
85
|
+
const onClick = jest.fn();
|
|
86
|
+
const { element } = setup({ as: 'a', children: 'Click me', href, onClick, isDisabled: true });
|
|
87
|
+
expect(element).toHaveAttribute('aria-disabled', 'true');
|
|
88
|
+
expect(element).toHaveAttribute('tabindex', '-1');
|
|
89
|
+
await userEvent.click(element);
|
|
90
|
+
expect(onClick).not.toHaveBeenCalled();
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should be aria-disabled with `aria-disabled` prop', async () => {
|
|
94
|
+
const onClick = jest.fn();
|
|
95
|
+
const { element } = setup({ as: 'a', children: 'Click me', href, onClick, 'aria-disabled': true });
|
|
96
|
+
expect(element).toHaveAttribute('aria-disabled', 'true');
|
|
97
|
+
await userEvent.click(element);
|
|
98
|
+
expect(onClick).not.toHaveBeenCalled();
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
describe('as a custom component', () => {
|
|
103
|
+
it('should render a custom component with `linkAs` prop', () => {
|
|
104
|
+
const { element } = setup({ as: CustomLink, children: 'Click me' });
|
|
105
|
+
expect(element).toHaveAttribute('data-custom-link');
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should trigger onClick', async () => {
|
|
109
|
+
const onClick = jest.fn();
|
|
110
|
+
const { element } = setup({ as: CustomLink, children: 'Click me', onClick });
|
|
111
|
+
expect(element).toHaveAttribute('data-custom-link');
|
|
112
|
+
await userEvent.click(element);
|
|
113
|
+
expect(onClick).toHaveBeenCalledTimes(1);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should be disabled with `disabled` prop', async () => {
|
|
117
|
+
const onClick = jest.fn();
|
|
118
|
+
const { element } = setup({ as: CustomLink, children: 'Click me', onClick, disabled: true });
|
|
119
|
+
expect(element).toHaveAttribute('data-custom-link');
|
|
120
|
+
expect(element).toHaveAttribute('aria-disabled', 'true');
|
|
121
|
+
expect(element).toHaveAttribute('tabindex', '-1');
|
|
122
|
+
await userEvent.click(element);
|
|
123
|
+
expect(onClick).not.toHaveBeenCalled();
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
describe('prop forwarding', () => {
|
|
128
|
+
it('should forward className', () => {
|
|
129
|
+
const { element } = setup({ as:'button', className: 'foo bar' });
|
|
130
|
+
expect(element).toHaveClass('foo bar');
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it('should forward ref and override type in button', () => {
|
|
134
|
+
const ref = React.createRef<HTMLButtonElement>();
|
|
135
|
+
const { element } = setup({ as: 'button', ref, type: 'submit' });
|
|
136
|
+
expect(element).toHaveAttribute('type', 'submit');
|
|
137
|
+
expect(ref.current).toBeInstanceOf(HTMLButtonElement);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it('should forward ref and override tabindex in link', () => {
|
|
141
|
+
const ref = React.createRef<HTMLAnchorElement>();
|
|
142
|
+
const { element } = setup({ as: 'a', ref, href: '#', tabIndex: -1 });
|
|
143
|
+
expect(ref.current).toBeInstanceOf(HTMLAnchorElement);
|
|
144
|
+
expect(element).toHaveAttribute('tabindex', '-1');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should forward ref to custom component', () => {
|
|
148
|
+
const ref = React.createRef<HTMLAnchorElement>();
|
|
149
|
+
setup({ as: CustomLink, ref });
|
|
150
|
+
expect(ref.current).toBeInstanceOf(HTMLAnchorElement);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import React, { AriaAttributes, ElementType } from 'react';
|
|
2
|
+
import { forwardRefPolymorphic } from '@lumx/react/utils/react/forwardRefPolymorphic';
|
|
3
|
+
import { ComponentRef, HasPolymorphicAs } from '@lumx/react/utils/type';
|
|
4
|
+
import { HasRequiredLinkHref } from '@lumx/react/utils/type/HasRequiredLinkHref';
|
|
5
|
+
|
|
6
|
+
type ClickableElement = 'a' | 'button' | ElementType;
|
|
7
|
+
|
|
8
|
+
type BaseClickableProps<E extends ClickableElement> = {
|
|
9
|
+
children?: React.ReactNode;
|
|
10
|
+
isDisabled?: boolean;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
'aria-disabled'?: AriaAttributes['aria-disabled'];
|
|
13
|
+
onClick?: React.MouseEventHandler<E>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type RawClickableProps<E extends ClickableElement> = HasPolymorphicAs<E> &
|
|
17
|
+
HasRequiredLinkHref<E> &
|
|
18
|
+
BaseClickableProps<E>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Render clickable element (link, button or custom element)
|
|
22
|
+
* (also does some basic disabled state handling)
|
|
23
|
+
*/
|
|
24
|
+
export const RawClickable = forwardRefPolymorphic(
|
|
25
|
+
<E extends ClickableElement>(props: RawClickableProps<E>, ref: ComponentRef<E>) => {
|
|
26
|
+
const {
|
|
27
|
+
children,
|
|
28
|
+
onClick,
|
|
29
|
+
disabled,
|
|
30
|
+
isDisabled = disabled,
|
|
31
|
+
'aria-disabled': ariaDisabled,
|
|
32
|
+
as,
|
|
33
|
+
...forwardedProps
|
|
34
|
+
} = props;
|
|
35
|
+
|
|
36
|
+
const isAnyDisabled = isDisabled || ariaDisabled === 'true' || ariaDisabled === true;
|
|
37
|
+
|
|
38
|
+
const Component = as as any;
|
|
39
|
+
let clickableProps;
|
|
40
|
+
if (Component === 'button') {
|
|
41
|
+
clickableProps = { type: forwardedProps.type || 'button', disabled: isDisabled };
|
|
42
|
+
} else {
|
|
43
|
+
clickableProps = { tabIndex: isDisabled ? '-1' : forwardedProps.tabIndex };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<Component
|
|
48
|
+
ref={ref}
|
|
49
|
+
aria-disabled={isAnyDisabled}
|
|
50
|
+
{...forwardedProps}
|
|
51
|
+
{...clickableProps}
|
|
52
|
+
onClick={(event: any) => {
|
|
53
|
+
if (isAnyDisabled) {
|
|
54
|
+
event.stopPropagation();
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
onClick?.(event);
|
|
59
|
+
}}
|
|
60
|
+
>
|
|
61
|
+
{children}
|
|
62
|
+
</Component>
|
|
63
|
+
);
|
|
64
|
+
},
|
|
65
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type HasRequiredLinkHref<E> = E extends 'a' ? { href: string } : Record<string, unknown>;
|
package/src/utils/type/index.ts
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type * from '@lumx/core/js/types';
|
|
2
|
+
|
|
2
3
|
export type { Comp } from './Comp';
|
|
3
4
|
export type { ComponentRef } from './ComponentRef';
|
|
4
|
-
export type { Falsy } from './Falsy';
|
|
5
|
-
export type { GenericProps } from './GenericProps';
|
|
6
|
-
export type { HasAriaLabelOrLabelledBy } from './HasAriaLabelOrLabelledBy';
|
|
7
|
-
export type { HasClassName } from './HasClassName';
|
|
8
|
-
export type { HasCloseMode } from './HasCloseMode';
|
|
9
5
|
export type { HasPolymorphicAs } from './HasPolymorphicAs';
|
|
10
|
-
export type { HasTheme } from './HasTheme';
|
|
11
|
-
export type { HeadingElement } from './HeadingElement';
|
|
12
6
|
export { isComponent } from './isComponent';
|
|
13
7
|
export { isComponentType } from './isComponentType';
|
|
14
8
|
export type { MaybeElementOrRef } from './MaybeElementOrRef';
|
|
15
|
-
export type {
|
|
16
|
-
export type { Predicate } from './Predicate';
|
|
17
|
-
export type { RectSize } from './RectSize';
|
|
18
|
-
export type { TextElement } from './TextElement';
|
|
19
|
-
export type { ValueOf } from './ValueOf';
|
|
9
|
+
export type { HasRequiredLinkHref } from './HasRequiredLinkHref';
|
package/src/components/index.ts
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
import { ValueOf } from '@lumx/react/utils/type';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Alignments.
|
|
5
|
-
*/
|
|
6
|
-
export const Alignment = {
|
|
7
|
-
bottom: 'bottom',
|
|
8
|
-
center: 'center',
|
|
9
|
-
end: 'end',
|
|
10
|
-
left: 'left',
|
|
11
|
-
right: 'right',
|
|
12
|
-
spaceAround: 'space-around',
|
|
13
|
-
spaceBetween: 'space-between',
|
|
14
|
-
spaceEvenly: 'space-evenly',
|
|
15
|
-
start: 'start',
|
|
16
|
-
top: 'top',
|
|
17
|
-
} as const;
|
|
18
|
-
export type Alignment = ValueOf<typeof Alignment>;
|
|
19
|
-
export type VerticalAlignment = Extract<Alignment, 'top' | 'center' | 'bottom'>;
|
|
20
|
-
export type HorizontalAlignment = Extract<Alignment, 'right' | 'center' | 'left'>;
|
|
21
|
-
|
|
22
|
-
export const Theme = {
|
|
23
|
-
light: 'light',
|
|
24
|
-
dark: 'dark',
|
|
25
|
-
} as const;
|
|
26
|
-
export type Theme = ValueOf<typeof Theme>;
|
|
27
|
-
|
|
28
|
-
export const Size = {
|
|
29
|
-
xxs: 'xxs',
|
|
30
|
-
xs: 'xs',
|
|
31
|
-
s: 's',
|
|
32
|
-
m: 'm',
|
|
33
|
-
l: 'l',
|
|
34
|
-
xl: 'xl',
|
|
35
|
-
xxl: 'xxl',
|
|
36
|
-
tiny: 'tiny',
|
|
37
|
-
regular: 'regular',
|
|
38
|
-
medium: 'medium',
|
|
39
|
-
big: 'big',
|
|
40
|
-
huge: 'huge',
|
|
41
|
-
} as const;
|
|
42
|
-
export type Size = ValueOf<typeof Size>;
|
|
43
|
-
export type GlobalSize = Extract<Size, 'xxs' | 'xs' | 's' | 'm' | 'l' | 'xl' | 'xxl'>;
|
|
44
|
-
|
|
45
|
-
export const Orientation = {
|
|
46
|
-
horizontal: 'horizontal',
|
|
47
|
-
vertical: 'vertical',
|
|
48
|
-
} as const;
|
|
49
|
-
export type Orientation = ValueOf<typeof Orientation>;
|
|
50
|
-
|
|
51
|
-
export const Emphasis = {
|
|
52
|
-
low: 'low',
|
|
53
|
-
medium: 'medium',
|
|
54
|
-
high: 'high',
|
|
55
|
-
} as const;
|
|
56
|
-
export type Emphasis = ValueOf<typeof Emphasis>;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* List of typographies that can't be customized.
|
|
60
|
-
*/
|
|
61
|
-
export const TypographyInterface = {
|
|
62
|
-
overline: 'overline',
|
|
63
|
-
caption: 'caption',
|
|
64
|
-
body1: 'body1',
|
|
65
|
-
body2: 'body2',
|
|
66
|
-
subtitle1: 'subtitle1',
|
|
67
|
-
subtitle2: 'subtitle2',
|
|
68
|
-
title: 'title',
|
|
69
|
-
headline: 'headline',
|
|
70
|
-
display1: 'display1',
|
|
71
|
-
} as const;
|
|
72
|
-
export type TypographyInterface = ValueOf<typeof TypographyInterface>;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* List of title typographies that can be customized (via CSS variables).
|
|
76
|
-
*/
|
|
77
|
-
export const TypographyTitleCustom = {
|
|
78
|
-
title1: 'custom-title1',
|
|
79
|
-
title2: 'custom-title2',
|
|
80
|
-
title3: 'custom-title3',
|
|
81
|
-
title4: 'custom-title4',
|
|
82
|
-
title5: 'custom-title5',
|
|
83
|
-
title6: 'custom-title6',
|
|
84
|
-
} as const;
|
|
85
|
-
export type TypographyTitleCustom = ValueOf<typeof TypographyTitleCustom>;
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* List of typographies that can be customized (via CSS variables).
|
|
89
|
-
*/
|
|
90
|
-
export const TypographyCustom = {
|
|
91
|
-
...TypographyTitleCustom,
|
|
92
|
-
intro: 'custom-intro',
|
|
93
|
-
'body-large': 'custom-body-large',
|
|
94
|
-
body: 'custom-body',
|
|
95
|
-
quote: 'custom-quote',
|
|
96
|
-
'publish-info': 'custom-publish-info',
|
|
97
|
-
button: 'custom-button',
|
|
98
|
-
} as const;
|
|
99
|
-
export type TypographyCustom = ValueOf<typeof TypographyCustom>;
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* List of all typographies.
|
|
103
|
-
*/
|
|
104
|
-
export const Typography = {
|
|
105
|
-
...TypographyInterface,
|
|
106
|
-
custom: TypographyCustom,
|
|
107
|
-
} as const;
|
|
108
|
-
export type Typography = TypographyInterface | TypographyCustom;
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* All available aspect ratios.
|
|
112
|
-
*/
|
|
113
|
-
export const AspectRatio = {
|
|
114
|
-
/** Intrinsic content ratio. */
|
|
115
|
-
original: 'original',
|
|
116
|
-
/** Ratio 3:1 */
|
|
117
|
-
panoramic: 'panoramic',
|
|
118
|
-
/** Ratio 16:9 */
|
|
119
|
-
wide: 'wide',
|
|
120
|
-
/** Ratio 3:2 */
|
|
121
|
-
horizontal: 'horizontal',
|
|
122
|
-
/** Ratio 3:2 */
|
|
123
|
-
vertical: 'vertical',
|
|
124
|
-
/** Ratio 1:1 */
|
|
125
|
-
square: 'square',
|
|
126
|
-
/** Ratio constrained by the parent. */
|
|
127
|
-
free: 'free',
|
|
128
|
-
} as const;
|
|
129
|
-
export type AspectRatio = ValueOf<typeof AspectRatio>;
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Semantic info about the purpose of the component
|
|
133
|
-
*/
|
|
134
|
-
export const Kind = {
|
|
135
|
-
info: 'info',
|
|
136
|
-
success: 'success',
|
|
137
|
-
warning: 'warning',
|
|
138
|
-
error: 'error',
|
|
139
|
-
} as const;
|
|
140
|
-
export type Kind = ValueOf<typeof Kind>;
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* All available white-space values
|
|
144
|
-
* */
|
|
145
|
-
export const WhiteSpace = {
|
|
146
|
-
normal: 'normal',
|
|
147
|
-
nowrap: 'nowrap',
|
|
148
|
-
pre: 'pre',
|
|
149
|
-
'pre-wrap': 'pre-wrap',
|
|
150
|
-
'pre-line': 'pre-line',
|
|
151
|
-
'break-spaces': 'break-spaces',
|
|
152
|
-
};
|
|
153
|
-
export type WhiteSpace = ValueOf<typeof WhiteSpace>;
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Re-exporting some utils types.
|
|
157
|
-
*/
|
|
158
|
-
export type { HeadingElement, TextElement, GenericProps, Callback } from '../utils/type';
|
|
159
|
-
|
|
160
|
-
export * from '../utils/type/color';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { onEnterPressed, onButtonPressed, onEscapePressed } from '@lumx/core/js/utils';
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { fontColorClass } from '@lumx/react/utils/className/fontColorClass';
|
|
2
|
-
|
|
3
|
-
describe(fontColorClass, () => {
|
|
4
|
-
it('should get lumx class for font color', () => {
|
|
5
|
-
expect(fontColorClass('dark')).toBe('lumx-color-font-dark-N');
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
it('should get lumx class for font color with variant', () => {
|
|
9
|
-
expect(fontColorClass('red', 'L2')).toBe('lumx-color-font-red-L2');
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
it('should get lumx class for font color with variant with override', () => {
|
|
13
|
-
expect(fontColorClass('red-N', 'L2')).toBe('lumx-color-font-red-L2');
|
|
14
|
-
});
|
|
15
|
-
});
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { ColorVariant, ColorWithVariants } from '@lumx/react';
|
|
2
|
-
import { resolveColorWithVariants } from '@lumx/react/utils/className';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Returns the classname associated to the given color and variant.
|
|
6
|
-
* For example, for 'dark' and 'L2' it returns `lumx-color-font-dark-L2`
|
|
7
|
-
*/
|
|
8
|
-
export function fontColorClass(propColor?: ColorWithVariants, propColorVariant?: ColorVariant) {
|
|
9
|
-
if (!propColor) return undefined;
|
|
10
|
-
const [color, colorVariant = ColorVariant.N] = resolveColorWithVariants(propColor, propColorVariant);
|
|
11
|
-
return `lumx-color-font-${color}-${colorVariant}`;
|
|
12
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { getBasicClass } from '@lumx/core/js/utils';
|
|
2
|
-
|
|
3
|
-
describe(getBasicClass, () => {
|
|
4
|
-
it('should return correct basic CSS class for different types and values', () => {
|
|
5
|
-
// Test cases with different inputs
|
|
6
|
-
expect(getBasicClass({ prefix: 'test', type: 'color', value: 'primary' })).toBe('test--color-primary');
|
|
7
|
-
expect(getBasicClass({ prefix: 'test', type: 'variant', value: 'button' })).toBe('test--variant-button');
|
|
8
|
-
expect(getBasicClass({ prefix: 'test', type: 'isDark', value: true })).toBe('test--is-dark');
|
|
9
|
-
expect(getBasicClass({ prefix: 'test', type: 'dark', value: true })).toBe('test--is-dark');
|
|
10
|
-
expect(getBasicClass({ prefix: 'test', type: 'hasDark', value: true })).toBe('test--has-dark');
|
|
11
|
-
expect(getBasicClass({ prefix: 'test', type: 'isActive', value: false })).toBe('');
|
|
12
|
-
|
|
13
|
-
// Additional tests for boolean types
|
|
14
|
-
expect(getBasicClass({ prefix: 'test', type: 'hasBorder', value: true })).toBe('test--has-border');
|
|
15
|
-
expect(getBasicClass({ prefix: 'test', type: 'isVisible', value: false })).toBe('');
|
|
16
|
-
|
|
17
|
-
// Tests for undefined
|
|
18
|
-
expect(getBasicClass({ prefix: 'test', type: 'variant', value: undefined })).toBe('test--variant-undefined');
|
|
19
|
-
});
|
|
20
|
-
});
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { getRootClassName } from '@lumx/react/utils/className/getRootClassName';
|
|
2
|
-
|
|
3
|
-
describe(getRootClassName, () => {
|
|
4
|
-
it('should transform the component name into a lumx class', () => {
|
|
5
|
-
expect(getRootClassName('Table')).toBe('lumx-table');
|
|
6
|
-
});
|
|
7
|
-
|
|
8
|
-
it('should transform the sub component name into a lumx class', () => {
|
|
9
|
-
expect(getRootClassName('TableBody', true)).toBe('lumx-table__body');
|
|
10
|
-
});
|
|
11
|
-
});
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { CSS_PREFIX } from '@lumx/core/js/constants';
|
|
2
|
-
import kebabCase from 'lodash/kebabCase';
|
|
3
|
-
|
|
4
|
-
// See https://regex101.com/r/YjS1uI/3
|
|
5
|
-
const LAST_PART_CLASSNAME = /^(.*)-(.+)$/gi;
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Get the name of the root CSS class of a component based on its name.
|
|
9
|
-
*
|
|
10
|
-
* @param componentName The name of the component. This name should contains the component prefix and be
|
|
11
|
-
* written in PascalCase.
|
|
12
|
-
* @param subComponent Whether the current component is a sub component, if true, define the class according
|
|
13
|
-
* to BEM standards.
|
|
14
|
-
* @return The name of the root CSS class. This classname include the CSS classname prefix and is written in
|
|
15
|
-
* lower-snake-case.
|
|
16
|
-
*/
|
|
17
|
-
export function getRootClassName(componentName: string, subComponent?: boolean): string {
|
|
18
|
-
const formattedClassName = `${CSS_PREFIX}-${kebabCase(componentName)}`;
|
|
19
|
-
|
|
20
|
-
if (subComponent) {
|
|
21
|
-
return formattedClassName.replace(LAST_PART_CLASSNAME, '$1__$2');
|
|
22
|
-
}
|
|
23
|
-
return formattedClassName;
|
|
24
|
-
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { getTypographyClassName } from '@lumx/react/utils/className/getTypographyClassName';
|
|
2
|
-
|
|
3
|
-
describe(getTypographyClassName, () => {
|
|
4
|
-
it('should generate lumx typography class', () => {
|
|
5
|
-
expect(getTypographyClassName('title')).toBe('lumx-typography-title');
|
|
6
|
-
});
|
|
7
|
-
});
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { Typography } from '@lumx/react';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Returns the classname associated to the given typography.
|
|
5
|
-
* For example, for `Typography.title` it returns `lumx-typography-title`
|
|
6
|
-
*/
|
|
7
|
-
export const getTypographyClassName = (typography: Typography) => {
|
|
8
|
-
return `lumx-typography-${typography}`;
|
|
9
|
-
};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { handleBasicClasses } from '@lumx/core/js/utils';
|
|
2
|
-
|
|
3
|
-
describe(handleBasicClasses, () => {
|
|
4
|
-
it('should return correct combined CSS classes based on props', () => {
|
|
5
|
-
const className = handleBasicClasses({
|
|
6
|
-
prefix: 'test',
|
|
7
|
-
// Undefined
|
|
8
|
-
undefined,
|
|
9
|
-
// Null
|
|
10
|
-
null: null,
|
|
11
|
-
// Empty string
|
|
12
|
-
emptyString: '',
|
|
13
|
-
// Empty array
|
|
14
|
-
emptyArray: [],
|
|
15
|
-
// Empty object
|
|
16
|
-
emptyObject: {},
|
|
17
|
-
// String
|
|
18
|
-
color: 'red',
|
|
19
|
-
// False property
|
|
20
|
-
isDisabled: false,
|
|
21
|
-
// Boolean without a prefix (is or has)
|
|
22
|
-
visible: true,
|
|
23
|
-
// Has prefix
|
|
24
|
-
hasButton: true,
|
|
25
|
-
});
|
|
26
|
-
expect(className).toBe('test test--color-red test--is-visible test--has-button');
|
|
27
|
-
});
|
|
28
|
-
});
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export { getBasicClass, handleBasicClasses } from '@lumx/core/js/utils';
|
|
2
|
-
export { getRootClassName } from './getRootClassName';
|
|
3
|
-
export { getTypographyClassName } from './getTypographyClassName';
|
|
4
|
-
export { fontColorClass } from './fontColorClass';
|
|
5
|
-
export { resolveColorWithVariants } from './resolveColorWithVariants';
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { resolveColorWithVariants } from './resolveColorWithVariants';
|
|
2
|
-
|
|
3
|
-
describe(resolveColorWithVariants, () => {
|
|
4
|
-
it('should handle undefined color', () => {
|
|
5
|
-
const result = resolveColorWithVariants(undefined);
|
|
6
|
-
expect(result).toEqual([undefined, undefined]);
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
it('should handle undefined color with variant', () => {
|
|
10
|
-
const result = resolveColorWithVariants(undefined, 'L2');
|
|
11
|
-
expect(result).toEqual([undefined, 'L2']);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('should handle color with undefined variant', () => {
|
|
15
|
-
const result = resolveColorWithVariants('primary');
|
|
16
|
-
expect(result).toEqual(['primary', undefined]);
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
it('should handle color & variant separated', () => {
|
|
20
|
-
const result = resolveColorWithVariants('primary', 'L2');
|
|
21
|
-
expect(result).toEqual(['primary', 'L2']);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('should handle color with variant all in one', () => {
|
|
25
|
-
const result = resolveColorWithVariants('primary-L2');
|
|
26
|
-
expect(result).toEqual(['primary', 'L2']);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('should override color variant with the given color variant', () => {
|
|
30
|
-
const result = resolveColorWithVariants('primary-L2', 'D2');
|
|
31
|
-
expect(result).toEqual(['primary', 'D2']);
|
|
32
|
-
});
|
|
33
|
-
});
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { ColorPalette, ColorVariant, ColorWithVariants } from '@lumx/react';
|
|
2
|
-
|
|
3
|
-
/** Resolve color & color variant from a `ColorWithVariants` and optionally a `ColorVariant`. */
|
|
4
|
-
export function resolveColorWithVariants(
|
|
5
|
-
colorWithVariants?: ColorWithVariants,
|
|
6
|
-
colorVariant?: ColorVariant,
|
|
7
|
-
): [color?: ColorPalette, colorVariant?: ColorVariant] {
|
|
8
|
-
if (!colorWithVariants) return [undefined, colorVariant];
|
|
9
|
-
const [color, baseColorVariant] = colorWithVariants.split('-');
|
|
10
|
-
return [color as ColorPalette, (colorVariant || baseColorVariant) as ColorVariant];
|
|
11
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import React, { ReactElement, ReactNode } from 'react';
|
|
2
|
-
import { renderLink } from './renderLink';
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
5
|
-
linkAs?: any;
|
|
6
|
-
href?: any;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Render <button> HTML component, fallbacks to `<a>` when a `href` is provided or a custom component with `linkAs`.
|
|
11
|
-
*/
|
|
12
|
-
export const renderButtonOrLink = <P extends Props>(props: P, ...children: ReactNode[]): ReactElement => {
|
|
13
|
-
const { linkAs, href, ...forwardedProps } = props;
|
|
14
|
-
if (linkAs || href) return renderLink(props, ...children);
|
|
15
|
-
return React.createElement('button', { type: 'button', ...forwardedProps }, ...children);
|
|
16
|
-
};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import React, { ReactElement, ReactNode } from 'react';
|
|
2
|
-
|
|
3
|
-
interface Props {
|
|
4
|
-
linkAs?: any;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Render link with default <a> HTML component or a custom one provided by `linkAs`.
|
|
9
|
-
*
|
|
10
|
-
* Can be used to inject the `Link` component from `react-router` and provide better a11y on LumX components.
|
|
11
|
-
*
|
|
12
|
-
* @param linkAs Custom link component.
|
|
13
|
-
* @param children Link children.
|
|
14
|
-
* @return A link.
|
|
15
|
-
*/
|
|
16
|
-
export const renderLink = <P extends Props>({ linkAs, ...forwardedProps }: P, ...children: ReactNode[]): ReactElement =>
|
|
17
|
-
React.createElement(linkAs || 'a', forwardedProps, ...children);
|
package/src/utils/type/Falsy.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { HasClassName } from './HasClassName';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Define a generic props types.
|
|
5
|
-
*/
|
|
6
|
-
export interface GenericProps extends HasClassName {
|
|
7
|
-
/**
|
|
8
|
-
* Any prop (particularly any supported prop for a HTML element).
|
|
9
|
-
*/
|
|
10
|
-
[propName: string]: any;
|
|
11
|
-
}
|