@ndlib/component-library 0.0.7
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/dist/components/elements/Button/Button.stories.d.ts +8 -0
- package/dist/components/elements/Button/Button.stories.js +39 -0
- package/dist/components/elements/Button/Button.test.d.ts +1 -0
- package/dist/components/elements/Button/Button.test.js +20 -0
- package/dist/components/elements/Button/index.d.ts +20 -0
- package/dist/components/elements/Button/index.js +82 -0
- package/dist/components/elements/Group/index.d.ts +23 -0
- package/dist/components/elements/Group/index.js +70 -0
- package/dist/components/elements/Link/Link.stories.d.ts +6 -0
- package/dist/components/elements/Link/Link.stories.js +21 -0
- package/dist/components/elements/Link/Link.test.d.ts +1 -0
- package/dist/components/elements/Link/Link.test.js +58 -0
- package/dist/components/elements/Link/index.d.ts +14 -0
- package/dist/components/elements/Link/index.js +41 -0
- package/dist/components/elements/layout/Box.d.ts +6 -0
- package/dist/components/elements/layout/Box.js +4 -0
- package/dist/components/elements/layout/Box.stories.d.ts +6 -0
- package/dist/components/elements/layout/Box.stories.js +12 -0
- package/dist/components/elements/layout/Column.d.ts +7 -0
- package/dist/components/elements/layout/Column.js +18 -0
- package/dist/components/elements/layout/Flex.stories.d.ts +9 -0
- package/dist/components/elements/layout/Flex.stories.js +23 -0
- package/dist/components/elements/layout/Flex.test.d.ts +1 -0
- package/dist/components/elements/layout/Flex.test.js +34 -0
- package/dist/components/elements/layout/Row.d.ts +17 -0
- package/dist/components/elements/layout/Row.js +44 -0
- package/dist/components/elements/text/Heading/Heading.stories.d.ts +8 -0
- package/dist/components/elements/text/Heading/Heading.stories.js +37 -0
- package/dist/components/elements/text/Heading/Heading.test.d.ts +1 -0
- package/dist/components/elements/text/Heading/Heading.test.js +51 -0
- package/dist/components/elements/text/Heading/index.d.ts +19 -0
- package/dist/components/elements/text/Heading/index.js +59 -0
- package/dist/components/elements/text/Label/Label.stories.d.ts +6 -0
- package/dist/components/elements/text/Label/Label.stories.js +20 -0
- package/dist/components/elements/text/Label/Label.test.d.ts +1 -0
- package/dist/components/elements/text/Label/Label.test.js +56 -0
- package/dist/components/elements/text/Label/index.d.ts +20 -0
- package/dist/components/elements/text/Label/index.js +36 -0
- package/dist/components/elements/text/Paragraph/Paragraph.stories.d.ts +6 -0
- package/dist/components/elements/text/Paragraph/Paragraph.stories.js +26 -0
- package/dist/components/elements/text/Paragraph/Paragraph.test.d.ts +1 -0
- package/dist/components/elements/text/Paragraph/Paragraph.test.js +9 -0
- package/dist/components/elements/text/Paragraph/index.d.ts +13 -0
- package/dist/components/elements/text/Paragraph/index.js +29 -0
- package/dist/components/providers/componentConfig.d.ts +20 -0
- package/dist/components/providers/componentConfig.js +31 -0
- package/dist/components/providers/env.d.ts +14 -0
- package/dist/components/providers/env.js +25 -0
- package/dist/components/providers/theme.d.ts +2 -0
- package/dist/components/providers/theme.js +6 -0
- package/dist/components/providers/ui.d.ts +10 -0
- package/dist/components/providers/ui.js +7 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +13 -0
- package/dist/theme/Color.stories.d.ts +5 -0
- package/dist/theme/Color.stories.js +26 -0
- package/dist/theme/colors.d.ts +14 -0
- package/dist/theme/colors.js +23 -0
- package/dist/theme/index.d.ts +19 -0
- package/dist/theme/index.js +18 -0
- package/dist/theme/spacing.d.ts +0 -0
- package/dist/theme/spacing.js +1 -0
- package/dist/theme/typography.d.ts +52 -0
- package/dist/theme/typography.js +135 -0
- package/dist/utils/misc.d.ts +3 -0
- package/dist/utils/misc.js +1 -0
- package/dist/utils/test.d.ts +2 -0
- package/dist/utils/test.js +7 -0
- package/global.css +59 -0
- package/package.json +72 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { Button } from '.';
|
|
3
|
+
declare const meta: Meta<typeof Button>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof Button>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const CustomColor: Story;
|
|
8
|
+
export declare const TextButton: Story;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { BUTTON_SIZE, BUTTON_TYPE, Button } from '.';
|
|
3
|
+
import { GROUP_TYPE, Group } from '../Group';
|
|
4
|
+
import { HEADING_SIZE, Heading } from '../text/Heading';
|
|
5
|
+
import { Column } from '../layout/Column';
|
|
6
|
+
import { COLOR } from '../../../theme/colors';
|
|
7
|
+
const meta = {
|
|
8
|
+
title: 'Elements/Button',
|
|
9
|
+
component: Button,
|
|
10
|
+
tags: ['autodocs'],
|
|
11
|
+
};
|
|
12
|
+
export default meta;
|
|
13
|
+
const sizes = [
|
|
14
|
+
{ size: BUTTON_SIZE.LG, label: 'Large' },
|
|
15
|
+
{ size: BUTTON_SIZE.MD, label: 'Medium' },
|
|
16
|
+
{ size: BUTTON_SIZE.SM, label: 'Small' },
|
|
17
|
+
];
|
|
18
|
+
export const Default = {
|
|
19
|
+
render: (args) => (_jsx(Column, { children: sizes.map(size => (_jsxs(Group, Object.assign({ type: GROUP_TYPE.REGION }, { children: [_jsx(Heading, Object.assign({ size: HEADING_SIZE.MD }, { children: size.label })), _jsx(Button, Object.assign({}, args, { size: size.size, sx: { mt: 1 } }))] })))) })),
|
|
20
|
+
args: {
|
|
21
|
+
type: BUTTON_TYPE.DEFAULT,
|
|
22
|
+
children: "Click Me"
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
export const CustomColor = {
|
|
26
|
+
render: (args) => (_jsx(Column, { children: sizes.map(size => (_jsxs(Group, Object.assign({ type: GROUP_TYPE.REGION }, { children: [_jsx(Heading, Object.assign({ size: HEADING_SIZE.MD }, { children: size.label })), _jsx(Button, Object.assign({}, args, { size: size.size, color: COLOR.SECONDARY, sx: { mt: 1 } }))] })))) })),
|
|
27
|
+
args: {
|
|
28
|
+
type: BUTTON_TYPE.DEFAULT,
|
|
29
|
+
children: "Click Me"
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
export const TextButton = {
|
|
33
|
+
render: (args) => (_jsx(Column, { children: sizes.map(size => (_jsxs(Group, Object.assign({ type: GROUP_TYPE.REGION }, { children: [_jsx(Heading, Object.assign({ size: HEADING_SIZE.MD }, { children: size.label })), _jsx(Button, Object.assign({}, args, { size: size.size, sx: { mt: 1 } }))] })))) })),
|
|
34
|
+
args: {
|
|
35
|
+
type: BUTTON_TYPE.TEXT,
|
|
36
|
+
onClick: () => { },
|
|
37
|
+
children: "Click Me"
|
|
38
|
+
}
|
|
39
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { fireEvent } from '@testing-library/react';
|
|
3
|
+
import { vi } from 'vitest';
|
|
4
|
+
import { render } from '../../../utils/test';
|
|
5
|
+
import { Button } from ".";
|
|
6
|
+
describe('Button', () => {
|
|
7
|
+
const mockClickHandler = vi.fn();
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
vi.resetAllMocks();
|
|
10
|
+
});
|
|
11
|
+
it('renders without throwing an error', () => {
|
|
12
|
+
const { getByText } = render(_jsx(Button, { children: "Foo" }));
|
|
13
|
+
expect(getByText('Foo')).toBeInTheDocument();
|
|
14
|
+
});
|
|
15
|
+
it('responds to click handlers', () => {
|
|
16
|
+
const { getByRole } = render(_jsx(Button, { onClick: mockClickHandler }));
|
|
17
|
+
fireEvent.click(getByRole('button'));
|
|
18
|
+
expect(mockClickHandler).toHaveBeenCalledTimes(1);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** @jsxImportSource theme-ui */
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { StyledElementProps } from "../../../theme";
|
|
4
|
+
import { COLOR } from "../../../theme/colors";
|
|
5
|
+
export declare enum BUTTON_SIZE {
|
|
6
|
+
SM = "sm",
|
|
7
|
+
MD = "md",
|
|
8
|
+
LG = "lg"
|
|
9
|
+
}
|
|
10
|
+
export declare enum BUTTON_TYPE {
|
|
11
|
+
DEFAULT = "default",
|
|
12
|
+
TEXT = "text"
|
|
13
|
+
}
|
|
14
|
+
type ButtonProps = StyledElementProps<HTMLButtonElement, {
|
|
15
|
+
size?: BUTTON_SIZE;
|
|
16
|
+
type?: BUTTON_TYPE;
|
|
17
|
+
color?: COLOR;
|
|
18
|
+
}>;
|
|
19
|
+
export declare const Button: React.FC<ButtonProps>;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx } from "theme-ui/jsx-runtime";
|
|
13
|
+
import { COLOR, colors } from "../../../theme/colors";
|
|
14
|
+
import { TYPOGRAPHY_TYPE, getTypographyStyles } from "../../../theme/typography";
|
|
15
|
+
export var BUTTON_SIZE;
|
|
16
|
+
(function (BUTTON_SIZE) {
|
|
17
|
+
BUTTON_SIZE["SM"] = "sm";
|
|
18
|
+
BUTTON_SIZE["MD"] = "md";
|
|
19
|
+
BUTTON_SIZE["LG"] = "lg";
|
|
20
|
+
})(BUTTON_SIZE || (BUTTON_SIZE = {}));
|
|
21
|
+
const typographyMap = {
|
|
22
|
+
[BUTTON_SIZE.SM]: TYPOGRAPHY_TYPE.CONTROL_SMALL,
|
|
23
|
+
[BUTTON_SIZE.MD]: TYPOGRAPHY_TYPE.CONTROL_MEDIUM,
|
|
24
|
+
[BUTTON_SIZE.LG]: TYPOGRAPHY_TYPE.CONTROL_LARGE,
|
|
25
|
+
};
|
|
26
|
+
const defaultPaddingX = {
|
|
27
|
+
[BUTTON_SIZE.SM]: 2,
|
|
28
|
+
[BUTTON_SIZE.MD]: 3,
|
|
29
|
+
[BUTTON_SIZE.LG]: 3,
|
|
30
|
+
};
|
|
31
|
+
const defaultPaddingY = {
|
|
32
|
+
[BUTTON_SIZE.SM]: 1,
|
|
33
|
+
[BUTTON_SIZE.MD]: 1,
|
|
34
|
+
[BUTTON_SIZE.LG]: 2
|
|
35
|
+
};
|
|
36
|
+
export var BUTTON_TYPE;
|
|
37
|
+
(function (BUTTON_TYPE) {
|
|
38
|
+
BUTTON_TYPE["DEFAULT"] = "default";
|
|
39
|
+
BUTTON_TYPE["TEXT"] = "text";
|
|
40
|
+
// ARROW
|
|
41
|
+
})(BUTTON_TYPE || (BUTTON_TYPE = {}));
|
|
42
|
+
export const Button = (_a) => {
|
|
43
|
+
var { size: sizeParam, type: typeParam, color, sx } = _a, rest = __rest(_a, ["size", "type", "color", "sx"]);
|
|
44
|
+
let bg = COLOR.PRIMARY;
|
|
45
|
+
let highlightColor = COLOR.PRIMARY_HIGHLIGHT;
|
|
46
|
+
let textColor = COLOR.TEXT;
|
|
47
|
+
let highlightTextColor = undefined;
|
|
48
|
+
const type = typeParam || BUTTON_TYPE.DEFAULT;
|
|
49
|
+
const size = sizeParam || BUTTON_SIZE.MD;
|
|
50
|
+
if (type === BUTTON_TYPE.DEFAULT) {
|
|
51
|
+
bg = color || COLOR.PRIMARY;
|
|
52
|
+
highlightColor = bg === COLOR.PRIMARY
|
|
53
|
+
? COLOR.PRIMARY_HIGHLIGHT
|
|
54
|
+
: bg === COLOR.SECONDARY
|
|
55
|
+
? COLOR.SECONDARY_HIGHLIGHT
|
|
56
|
+
: bg;
|
|
57
|
+
textColor = bg === COLOR.PRIMARY
|
|
58
|
+
? COLOR.TEXT_ON_PRIMARY
|
|
59
|
+
: bg === COLOR.SECONDARY
|
|
60
|
+
? COLOR.TEXT_ON_SECONDARY
|
|
61
|
+
: COLOR.TEXT;
|
|
62
|
+
}
|
|
63
|
+
if (type === BUTTON_TYPE.TEXT) {
|
|
64
|
+
bg = COLOR.TRANSPARENT;
|
|
65
|
+
textColor = color || COLOR.PRIMARY;
|
|
66
|
+
highlightColor = textColor === COLOR.PRIMARY
|
|
67
|
+
? COLOR.PRIMARY
|
|
68
|
+
: textColor === COLOR.SECONDARY
|
|
69
|
+
? COLOR.SECONDARY
|
|
70
|
+
: bg;
|
|
71
|
+
highlightTextColor = COLOR.BACKGROUND;
|
|
72
|
+
}
|
|
73
|
+
const typography = typographyMap[size];
|
|
74
|
+
return (_jsx("button", Object.assign({ sx: Object.assign(Object.assign({ bg: bg || colors.primary, color: textColor, px: defaultPaddingX[size], py: defaultPaddingY[size], border: 'none', borderRadius: '4px', ":hover": {
|
|
75
|
+
bg: highlightColor,
|
|
76
|
+
color: highlightTextColor,
|
|
77
|
+
cursor: 'pointer',
|
|
78
|
+
}, ":focus": {
|
|
79
|
+
bg: highlightColor,
|
|
80
|
+
color: highlightTextColor
|
|
81
|
+
} }, getTypographyStyles(typography)), sx) }, rest)));
|
|
82
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** @jsxImportSource theme-ui */
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { StyledElementProps } from '../../../theme';
|
|
4
|
+
type GroupContextType = {
|
|
5
|
+
level: number;
|
|
6
|
+
labelId: string;
|
|
7
|
+
trackHeadingRendered: () => void;
|
|
8
|
+
labelTargetId: string;
|
|
9
|
+
type?: GROUP_TYPE;
|
|
10
|
+
};
|
|
11
|
+
export declare enum GROUP_TYPE {
|
|
12
|
+
REGION = "region",
|
|
13
|
+
GROUP = "group",
|
|
14
|
+
RAW = "raw"
|
|
15
|
+
}
|
|
16
|
+
export declare const useGroup: () => GroupContextType;
|
|
17
|
+
type GroupProps = Omit<StyledElementProps<HTMLDivElement, {
|
|
18
|
+
type?: GROUP_TYPE;
|
|
19
|
+
}>, 'children'> & {
|
|
20
|
+
children: React.ReactNode | ((context: GroupContextType) => React.ReactNode);
|
|
21
|
+
};
|
|
22
|
+
export declare const Group: React.FC<GroupProps>;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx } from "theme-ui/jsx-runtime";
|
|
13
|
+
/** @jsxImportSource theme-ui */
|
|
14
|
+
import React, { useEffect, useMemo, useRef } from 'react';
|
|
15
|
+
import { useEnvironment } from '../../providers/env';
|
|
16
|
+
export var GROUP_TYPE;
|
|
17
|
+
(function (GROUP_TYPE) {
|
|
18
|
+
GROUP_TYPE["REGION"] = "region";
|
|
19
|
+
GROUP_TYPE["GROUP"] = "group";
|
|
20
|
+
GROUP_TYPE["RAW"] = "raw";
|
|
21
|
+
})(GROUP_TYPE || (GROUP_TYPE = {}));
|
|
22
|
+
const GROUP_TYPE_ROLE_MAP = {
|
|
23
|
+
[GROUP_TYPE.REGION]: 'region',
|
|
24
|
+
[GROUP_TYPE.GROUP]: 'group',
|
|
25
|
+
[GROUP_TYPE.RAW]: 'group'
|
|
26
|
+
};
|
|
27
|
+
const GroupContext = React.createContext({
|
|
28
|
+
level: 0,
|
|
29
|
+
labelId: '',
|
|
30
|
+
labelTargetId: '',
|
|
31
|
+
trackHeadingRendered: () => { }
|
|
32
|
+
});
|
|
33
|
+
export const useGroup = () => React.useContext(GroupContext);
|
|
34
|
+
export const Group = (_a) => {
|
|
35
|
+
var { type: typeProp, children, sx } = _a, rest = __rest(_a, ["type", "children", "sx"]);
|
|
36
|
+
const { level: parentLevel } = useGroup();
|
|
37
|
+
const { flagInDevelopment } = useEnvironment();
|
|
38
|
+
const type = typeProp || GROUP_TYPE.REGION;
|
|
39
|
+
const randomSlug = useMemo(() => Math.random().toString().slice(2), []);
|
|
40
|
+
const labelId = `group-label-${randomSlug}`;
|
|
41
|
+
const labelTargetId = `labeled-${randomSlug}`;
|
|
42
|
+
const headingRenderTracker = useRef({
|
|
43
|
+
hasHeadingRendered: false
|
|
44
|
+
});
|
|
45
|
+
const trackHeadingRendered = () => {
|
|
46
|
+
headingRenderTracker.current.hasHeadingRendered = true;
|
|
47
|
+
};
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (type === GROUP_TYPE.REGION) {
|
|
50
|
+
setTimeout(() => {
|
|
51
|
+
if (!headingRenderTracker.current.hasHeadingRendered) {
|
|
52
|
+
flagInDevelopment('Every <Group> component of type "region" must render a <Heading> component within it');
|
|
53
|
+
}
|
|
54
|
+
}, 500);
|
|
55
|
+
}
|
|
56
|
+
}, [flagInDevelopment, type]);
|
|
57
|
+
const level = Math.min(parentLevel + (type === GROUP_TYPE.REGION ? 1 : 0), 5);
|
|
58
|
+
const contextValue = {
|
|
59
|
+
level,
|
|
60
|
+
type,
|
|
61
|
+
trackHeadingRendered,
|
|
62
|
+
labelId,
|
|
63
|
+
labelTargetId,
|
|
64
|
+
};
|
|
65
|
+
const Main = (_jsx(GroupContext.Provider, Object.assign({ value: contextValue }, { children: typeof children === 'function' ? children(contextValue) : children })));
|
|
66
|
+
if (type === GROUP_TYPE.RAW) {
|
|
67
|
+
return Main;
|
|
68
|
+
}
|
|
69
|
+
return (_jsx("div", Object.assign({ role: GROUP_TYPE_ROLE_MAP[type], "aria-labelledby": labelId, sx: Object.assign({ my: 2 }, sx) }, rest, { children: Main })));
|
|
70
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Link, LINK_SIZE } from '.';
|
|
3
|
+
import { Group } from '../Group';
|
|
4
|
+
import { HEADING_SIZE, Heading } from '../text/Heading';
|
|
5
|
+
import { Column } from '../layout/Column';
|
|
6
|
+
const meta = {
|
|
7
|
+
title: 'Elements/Link',
|
|
8
|
+
component: Link,
|
|
9
|
+
};
|
|
10
|
+
export default meta;
|
|
11
|
+
const sizes = [
|
|
12
|
+
{ size: LINK_SIZE.LG, label: 'Large' },
|
|
13
|
+
{ size: LINK_SIZE.MD, label: 'Medium' },
|
|
14
|
+
{ size: LINK_SIZE.SM, label: 'Small' },
|
|
15
|
+
];
|
|
16
|
+
export const Default = {
|
|
17
|
+
render: () => (_jsx(Column, { children: sizes.map(size => (_jsxs(Group, { children: [_jsx(Heading, Object.assign({ size: HEADING_SIZE.MD }, { children: size.label })), _jsx(Link, Object.assign({ size: size.size, to: "/" }, { children: "Click Me" }))] }))) })),
|
|
18
|
+
args: {
|
|
19
|
+
children: "Click Me"
|
|
20
|
+
}
|
|
21
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { render } from '../../../utils/test';
|
|
3
|
+
import { Link } from ".";
|
|
4
|
+
import { DefaultLink } from '../../providers/componentConfig';
|
|
5
|
+
const CUSTOM_INTERNAL_TEST_ID = 'internal-link-test-id';
|
|
6
|
+
const CUSTOM_EXTERNAL_TEST_ID = 'external-link-test-id';
|
|
7
|
+
const CustomInternalLink = (props) => {
|
|
8
|
+
return (_jsx(DefaultLink, Object.assign({ "data-testid": CUSTOM_INTERNAL_TEST_ID }, props)));
|
|
9
|
+
};
|
|
10
|
+
const CustomExternalLink = (props) => {
|
|
11
|
+
return (_jsx(DefaultLink, Object.assign({ "data-testid": CUSTOM_EXTERNAL_TEST_ID }, props)));
|
|
12
|
+
};
|
|
13
|
+
describe('Link', () => {
|
|
14
|
+
it('renders default external link component without throwing', () => {
|
|
15
|
+
const { getByRole } = render(_jsx(Link, Object.assign({ to: "https://google.com" }, { children: "Foo" })));
|
|
16
|
+
expect(getByRole('link')).toBeInTheDocument();
|
|
17
|
+
});
|
|
18
|
+
it('renders default internal link component without throwing', () => {
|
|
19
|
+
const { getByRole } = render(_jsx(Link, Object.assign({ to: "/test/path" }, { children: "Foo" })));
|
|
20
|
+
expect(getByRole('link')).toBeInTheDocument();
|
|
21
|
+
});
|
|
22
|
+
it('renders custom external component if passed', () => {
|
|
23
|
+
const { getByTestId } = render(_jsx(Link, Object.assign({ to: "https://google.com" }, { children: "Foo" })), {
|
|
24
|
+
components: {
|
|
25
|
+
link: {
|
|
26
|
+
externalLinkComponent: CustomExternalLink,
|
|
27
|
+
internalLinkComponent: CustomInternalLink
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
expect(getByTestId(CUSTOM_EXTERNAL_TEST_ID)).toBeDefined();
|
|
32
|
+
expect(() => getByTestId(CUSTOM_INTERNAL_TEST_ID)).toThrow();
|
|
33
|
+
});
|
|
34
|
+
it('renders custom internal component if passed', () => {
|
|
35
|
+
const { getByTestId } = render(_jsx(Link, Object.assign({ to: "/test/route" }, { children: "Foo" })), {
|
|
36
|
+
components: {
|
|
37
|
+
link: {
|
|
38
|
+
externalLinkComponent: CustomExternalLink,
|
|
39
|
+
internalLinkComponent: CustomInternalLink
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
expect(getByTestId(CUSTOM_INTERNAL_TEST_ID)).toBeDefined();
|
|
44
|
+
expect(() => getByTestId(CUSTOM_EXTERNAL_TEST_ID)).toThrow();
|
|
45
|
+
});
|
|
46
|
+
it('passes styles to custom component', () => {
|
|
47
|
+
const { getByTestId } = render((_jsxs(_Fragment, { children: [_jsx(Link, Object.assign({ to: "https://google.com", sx: { mt: 1 } }, { children: "Foo" })), _jsx(Link, Object.assign({ to: "/test/route", sx: { mt: 1 } }, { children: "Foo" }))] })), {
|
|
48
|
+
components: {
|
|
49
|
+
link: {
|
|
50
|
+
externalLinkComponent: CustomExternalLink,
|
|
51
|
+
internalLinkComponent: CustomInternalLink
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
expect(getByTestId(CUSTOM_EXTERNAL_TEST_ID)).toHaveStyle(`margin-top: 0.25rem`);
|
|
56
|
+
expect(getByTestId(CUSTOM_INTERNAL_TEST_ID)).toHaveStyle(`margin-top: 0.25rem`);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** @jsxImportSource theme-ui */
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { StyledElementProps } from "../../../theme";
|
|
4
|
+
type LinkProps = StyledElementProps<HTMLSpanElement, {
|
|
5
|
+
to: string;
|
|
6
|
+
size?: LINK_SIZE;
|
|
7
|
+
}>;
|
|
8
|
+
export declare enum LINK_SIZE {
|
|
9
|
+
SM = "sm",
|
|
10
|
+
MD = "md",
|
|
11
|
+
LG = "lg"
|
|
12
|
+
}
|
|
13
|
+
export declare const Link: React.FC<LinkProps>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx } from "theme-ui/jsx-runtime";
|
|
13
|
+
import { useComponentConfig } from "../../providers/componentConfig";
|
|
14
|
+
import { COLOR } from "../../../theme/colors";
|
|
15
|
+
import { TYPOGRAPHY_TYPE, getTypographyStyles } from "../../../theme/typography";
|
|
16
|
+
export var LINK_SIZE;
|
|
17
|
+
(function (LINK_SIZE) {
|
|
18
|
+
LINK_SIZE["SM"] = "sm";
|
|
19
|
+
LINK_SIZE["MD"] = "md";
|
|
20
|
+
LINK_SIZE["LG"] = "lg";
|
|
21
|
+
})(LINK_SIZE || (LINK_SIZE = {}));
|
|
22
|
+
const SIZE_TYPOGRAPHY_MAP = {
|
|
23
|
+
[LINK_SIZE.SM]: TYPOGRAPHY_TYPE.CONTROL_SMALL,
|
|
24
|
+
[LINK_SIZE.MD]: TYPOGRAPHY_TYPE.CONTROL_MEDIUM,
|
|
25
|
+
[LINK_SIZE.LG]: TYPOGRAPHY_TYPE.CONTROL_LARGE
|
|
26
|
+
};
|
|
27
|
+
export const Link = (_a) => {
|
|
28
|
+
var { size, to, sx } = _a, rest = __rest(_a, ["size", "to", "sx"]);
|
|
29
|
+
const { link } = useComponentConfig();
|
|
30
|
+
const typography = SIZE_TYPOGRAPHY_MAP[size || LINK_SIZE.MD];
|
|
31
|
+
const InternalLink = link.internalLinkComponent;
|
|
32
|
+
const ExternalLink = link.externalLinkComponent;
|
|
33
|
+
const isExternal = link.externalMatcher.test(to);
|
|
34
|
+
const styles = Object.assign(Object.assign({ color: COLOR.PRIMARY }, getTypographyStyles(typography)), sx);
|
|
35
|
+
if (isExternal) {
|
|
36
|
+
return _jsx(ExternalLink, Object.assign({ to: to }, rest, { sx: styles }));
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
return _jsx(InternalLink, Object.assign({ to: to }, rest, { sx: styles }));
|
|
40
|
+
}
|
|
41
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box as BoxComponent } from './Box';
|
|
3
|
+
import { COLOR } from '../../../theme/colors';
|
|
4
|
+
const meta = {
|
|
5
|
+
title: 'Elements/Layout/Box',
|
|
6
|
+
component: BoxComponent,
|
|
7
|
+
tags: ['autodocs']
|
|
8
|
+
};
|
|
9
|
+
export default meta;
|
|
10
|
+
export const Box = {
|
|
11
|
+
render: () => (_jsx(BoxComponent, Object.assign({ sx: { p: 1, bg: COLOR.PRIMARY } }, { children: _jsx(BoxComponent, { sx: { p: 1, bg: COLOR.SECONDARY } }) }))),
|
|
12
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
/** @jsxImportSource theme-ui */
|
|
3
|
+
import { StyledElementProps } from "../../../theme";
|
|
4
|
+
import { FlexHelperProps } from "./Row";
|
|
5
|
+
type ColumnProps = StyledElementProps<HTMLDivElement, FlexHelperProps>;
|
|
6
|
+
export declare const Column: React.FC<ColumnProps>;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx } from "theme-ui/jsx-runtime";
|
|
13
|
+
import { convertFlexHelperProps } from "./Row";
|
|
14
|
+
export const Column = (_a) => {
|
|
15
|
+
var { sx, children } = _a, rest = __rest(_a, ["sx", "children"]);
|
|
16
|
+
const flexStyles = convertFlexHelperProps(rest);
|
|
17
|
+
return _jsx("div", Object.assign({}, rest, { sx: Object.assign(Object.assign(Object.assign({}, flexStyles), sx), { display: 'flex', flexDirection: 'column' }) }, { children: children }));
|
|
18
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { Row } from './Row';
|
|
3
|
+
declare const meta: Meta<typeof Row>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof Row>;
|
|
6
|
+
export declare const Columns: Story;
|
|
7
|
+
export declare const Rows: Story;
|
|
8
|
+
export declare const FlexHelpers: Story;
|
|
9
|
+
export declare const Centered: Story;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Column } from './Column';
|
|
3
|
+
import { Row } from './Row';
|
|
4
|
+
import { Paragraph } from '../text/Paragraph';
|
|
5
|
+
import { COLOR } from '../../../theme/colors';
|
|
6
|
+
const meta = {
|
|
7
|
+
title: 'Elements/Layout/Flex',
|
|
8
|
+
component: Row,
|
|
9
|
+
tags: ['autodocs']
|
|
10
|
+
};
|
|
11
|
+
export default meta;
|
|
12
|
+
export const Columns = {
|
|
13
|
+
render: () => (_jsxs(Row, Object.assign({ justify: 'space-between' }, { children: [_jsx(Column, { children: _jsx(Paragraph, { children: "Column 1" }) }), _jsx(Column, { children: _jsx(Paragraph, { children: "Column 2" }) }), _jsx(Column, { children: _jsx(Paragraph, { children: "Column 3" }) })] }))),
|
|
14
|
+
};
|
|
15
|
+
export const Rows = {
|
|
16
|
+
render: () => (_jsxs(Column, { children: [_jsx(Row, { children: _jsx(Paragraph, { children: "Row 1" }) }), _jsx(Row, { children: _jsx(Paragraph, { children: "Row 2" }) }), _jsx(Row, { children: _jsx(Paragraph, { children: "Row 3" }) })] })),
|
|
17
|
+
};
|
|
18
|
+
export const FlexHelpers = {
|
|
19
|
+
render: () => (_jsxs(Row, Object.assign({ justify: "space-between" }, { children: [_jsx(Column, Object.assign({ align: "flex-end", grow: 1, sx: { bg: COLOR.PRIMARY, color: COLOR.TEXT_ON_PRIMARY } }, { children: _jsx(Row, { children: _jsx(Paragraph, { children: "Right-aligned" }) }) })), _jsx(Column, Object.assign({ grow: 1 }, { children: _jsx(Paragraph, { children: "Growing Column...................................................." }) })), _jsx(Column, Object.assign({ shrink: 1, sx: { bg: COLOR.PRIMARY, color: COLOR.TEXT_ON_PRIMARY } }, { children: _jsx(Paragraph, { children: "Shrinking Column" }) }))] }))),
|
|
20
|
+
};
|
|
21
|
+
export const Centered = {
|
|
22
|
+
render: () => (_jsx(Row, Object.assign({ centered: true, sx: { width: '100%', height: '100px', border: 'solid black 1px' } }, { children: _jsx(Paragraph, { children: "Hello World" }) }))),
|
|
23
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { render } from '../../../utils/test';
|
|
3
|
+
import { Row } from "./Row";
|
|
4
|
+
import { Column } from "./Column";
|
|
5
|
+
describe('Row', () => {
|
|
6
|
+
it('renders without throwing an error', () => {
|
|
7
|
+
const { getByText } = render(_jsx(Row, { children: "Foo" }));
|
|
8
|
+
expect(getByText('Foo')).toBeInTheDocument();
|
|
9
|
+
});
|
|
10
|
+
it('converts helper props to styles', () => {
|
|
11
|
+
const { getByText } = render(_jsx(Row, Object.assign({ grow: 1, shrink: 1, basis: "100px", align: "baseline", justify: "flex-start" }, { children: "Foo" })));
|
|
12
|
+
const rendered = getByText('Foo');
|
|
13
|
+
expect(rendered).toHaveStyle('flex-grow: 1');
|
|
14
|
+
expect(rendered).toHaveStyle('flex-shrink: 1');
|
|
15
|
+
expect(rendered).toHaveStyle('flex-basis: 100px');
|
|
16
|
+
expect(rendered).toHaveStyle('align-items: baseline');
|
|
17
|
+
expect(rendered).toHaveStyle('justify-content: flex-start');
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
describe('Column', () => {
|
|
21
|
+
it('renders without throwing an error', () => {
|
|
22
|
+
const { getByText } = render(_jsx(Column, { children: "Foo" }));
|
|
23
|
+
expect(getByText('Foo')).toBeInTheDocument();
|
|
24
|
+
});
|
|
25
|
+
it('converts helper props to styles', () => {
|
|
26
|
+
const { getByText } = render(_jsx(Column, Object.assign({ grow: 1, shrink: 1, basis: "100px", align: "baseline", justify: "flex-start" }, { children: "Foo" })));
|
|
27
|
+
const rendered = getByText('Foo');
|
|
28
|
+
expect(rendered).toHaveStyle('flex-grow: 1');
|
|
29
|
+
expect(rendered).toHaveStyle('flex-shrink: 1');
|
|
30
|
+
expect(rendered).toHaveStyle('flex-basis: 100px');
|
|
31
|
+
expect(rendered).toHaveStyle('align-items: baseline');
|
|
32
|
+
expect(rendered).toHaveStyle('justify-content: flex-start');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
/** @jsxImportSource theme-ui */
|
|
3
|
+
import { CSSProperties, ThemeUICSSProperties } from "theme-ui";
|
|
4
|
+
import { StyledElementProps } from "../../../theme";
|
|
5
|
+
export declare const convertFlexHelperProps: (props: FlexHelperProps) => ThemeUICSSProperties;
|
|
6
|
+
export type FlexHelperProps = {
|
|
7
|
+
grow?: number;
|
|
8
|
+
shrink?: number;
|
|
9
|
+
basis?: string;
|
|
10
|
+
flex?: string;
|
|
11
|
+
align?: CSSProperties['alignItems'];
|
|
12
|
+
justify?: CSSProperties['justifyContent'];
|
|
13
|
+
centered?: boolean;
|
|
14
|
+
};
|
|
15
|
+
type RowProps = StyledElementProps<HTMLDivElement, FlexHelperProps>;
|
|
16
|
+
export declare const Row: React.FC<RowProps>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx } from "theme-ui/jsx-runtime";
|
|
13
|
+
// Putting shared utils and types here so autodocs can pick them up
|
|
14
|
+
export const convertFlexHelperProps = (props) => {
|
|
15
|
+
const styleObject = {};
|
|
16
|
+
if (props.grow) {
|
|
17
|
+
styleObject.flexGrow = props.grow;
|
|
18
|
+
}
|
|
19
|
+
if (props.shrink) {
|
|
20
|
+
styleObject.flexShrink = props.shrink;
|
|
21
|
+
}
|
|
22
|
+
if (props.flex) {
|
|
23
|
+
styleObject.flex = props.flex;
|
|
24
|
+
}
|
|
25
|
+
if (props.basis) {
|
|
26
|
+
styleObject.flexBasis = props.basis;
|
|
27
|
+
}
|
|
28
|
+
if (props.centered) {
|
|
29
|
+
styleObject.alignItems = 'center';
|
|
30
|
+
styleObject.justifyContent = 'center';
|
|
31
|
+
}
|
|
32
|
+
if (props.align) {
|
|
33
|
+
styleObject.alignItems = props.align;
|
|
34
|
+
}
|
|
35
|
+
if (props.justify) {
|
|
36
|
+
styleObject.justifyContent = props.justify;
|
|
37
|
+
}
|
|
38
|
+
return styleObject;
|
|
39
|
+
};
|
|
40
|
+
export const Row = (_a) => {
|
|
41
|
+
var { sx, children } = _a, rest = __rest(_a, ["sx", "children"]);
|
|
42
|
+
const flexStyles = convertFlexHelperProps(rest);
|
|
43
|
+
return _jsx("div", Object.assign({}, rest, { sx: Object.assign(Object.assign(Object.assign({}, flexStyles), sx), { display: 'flex', flexDirection: 'row' }) }, { children: children }));
|
|
44
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { Heading } from '.';
|
|
3
|
+
declare const meta: Meta<typeof Heading>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof Heading>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Color: Story;
|
|
8
|
+
export declare const Underline: Story;
|