@common-origin/design-system 1.16.1 → 2.0.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/README.md +40 -1
- package/dist/components/atoms/Button/Button.d.ts +6 -0
- package/dist/components/molecules/Breadcrumbs/Breadcrumbs.d.ts +5 -0
- package/dist/components/molecules/CardSmall/CardSmall.d.ts +5 -0
- package/dist/index.esm.js +36 -37
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +36 -37
- package/dist/index.js.map +1 -1
- package/dist/styles/tokens.json +1 -1
- package/dist/tokens/index.esm.js +1 -1
- package/dist/tokens/index.js +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -1,10 +1,49 @@
|
|
|
1
1
|
# Common Origin Design System
|
|
2
2
|
|
|
3
|
-
A production-ready design system built with atomic design principles, design tokens, and WCAG 2.2 AA accessibility compliance. This package provides reusable React components and design tokens for building consistent user interfaces.
|
|
3
|
+
A production-ready, **framework-agnostic** design system built with atomic design principles, design tokens, and WCAG 2.2 AA accessibility compliance. This package provides reusable React components and design tokens for building consistent user interfaces.
|
|
4
|
+
|
|
5
|
+
## ⚠️ Version 2.0 Breaking Changes
|
|
6
|
+
|
|
7
|
+
**Version 2.0.0** removes Next.js dependencies, making the design system work in **any React application** (Next.js, Create React App, Vite, etc.).
|
|
8
|
+
|
|
9
|
+
If you're upgrading from v1.x, see **[MIGRATION-V2.md](./MIGRATION-V2.md)** for the complete migration guide.
|
|
10
|
+
|
|
11
|
+
**Quick summary:** Components like `Button`, `Breadcrumbs`, and `CardSmall` now accept an optional `linkComponent` prop. Pass your framework's Link component (e.g., Next.js Link, React Router Link) for client-side navigation, or omit it to use standard HTML links.
|
|
4
12
|
|
|
5
13
|
## 🚀 Getting Started
|
|
6
14
|
|
|
15
|
+
### Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @common-origin/design-system styled-components
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Usage
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { Button, Typography, Stack } from '@common-origin/design-system'
|
|
25
|
+
|
|
26
|
+
// For Next.js apps, pass Link component for client-side routing
|
|
27
|
+
import Link from 'next/link'
|
|
28
|
+
|
|
29
|
+
function App() {
|
|
30
|
+
return (
|
|
31
|
+
<Stack direction="column" gap="md">
|
|
32
|
+
<Typography variant="h1">Welcome</Typography>
|
|
33
|
+
<Button
|
|
34
|
+
purpose="link"
|
|
35
|
+
url="/about"
|
|
36
|
+
linkComponent={Link}
|
|
37
|
+
>
|
|
38
|
+
Learn More
|
|
39
|
+
</Button>
|
|
40
|
+
</Stack>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
7
45
|
### Development
|
|
46
|
+
|
|
8
47
|
```bash
|
|
9
48
|
# Install dependencies
|
|
10
49
|
npm install
|
|
@@ -10,6 +10,12 @@ export interface BaseButtonProps {
|
|
|
10
10
|
iconName?: IconName;
|
|
11
11
|
id?: string;
|
|
12
12
|
'data-testid'?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Custom link component (e.g., Next.js Link, React Router Link)
|
|
15
|
+
* Receives href, children, and other props
|
|
16
|
+
* @example linkComponent={NextLink} or linkComponent={ReactRouterLink}
|
|
17
|
+
*/
|
|
18
|
+
linkComponent?: React.ComponentType<any>;
|
|
13
19
|
}
|
|
14
20
|
export interface ButtonProps extends BaseButtonProps, Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof BaseButtonProps> {
|
|
15
21
|
purpose?: 'button';
|
|
@@ -6,6 +6,11 @@ interface Breadcrumb {
|
|
|
6
6
|
interface BreadcrumbsProps {
|
|
7
7
|
breadcrumbs: Breadcrumb[];
|
|
8
8
|
'data-testid'?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Custom link component (e.g., Next.js Link)
|
|
11
|
+
* @example linkComponent={NextLink}
|
|
12
|
+
*/
|
|
13
|
+
linkComponent?: React.ComponentType<any>;
|
|
9
14
|
}
|
|
10
15
|
export declare const Breadcrumbs: React.FC<BreadcrumbsProps>;
|
|
11
16
|
export {};
|
|
@@ -5,5 +5,10 @@ export type CardSmallProps = {
|
|
|
5
5
|
subtitle?: string;
|
|
6
6
|
meta?: string;
|
|
7
7
|
href?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Custom link component (e.g., Next.js Link)
|
|
10
|
+
* @example linkComponent={NextLink}
|
|
11
|
+
*/
|
|
12
|
+
linkComponent?: React.ComponentType<any>;
|
|
8
13
|
};
|
|
9
14
|
export declare const CardSmall: React.FC<CardSmallProps>;
|
package/dist/index.esm.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useState, forwardRef, useId, useRef, useEffect, useCallback } from 'react';
|
|
2
2
|
import styled, { keyframes, css } from 'styled-components';
|
|
3
|
-
import Link from 'next/link';
|
|
4
3
|
import { parseISO, format } from 'date-fns';
|
|
5
4
|
|
|
6
5
|
function _extends() {
|
|
@@ -745,7 +744,7 @@ var semantic$a = {
|
|
|
745
744
|
h1: "700 3rem/3rem 'Inter', sans-serif",
|
|
746
745
|
h2: "700 2rem/2.5rem 'Inter', sans-serif",
|
|
747
746
|
h3: "700 1.75rem/2.25rem 'Inter', sans-serif",
|
|
748
|
-
h4: "
|
|
747
|
+
h4: "700 1.5rem/2rem 'Inter', sans-serif",
|
|
749
748
|
h5: "500 1.25rem/1.75rem 'Inter', sans-serif",
|
|
750
749
|
h6: "500 1.125rem/1.5rem 'Inter', sans-serif",
|
|
751
750
|
subtitle: "500 1rem/1.5rem 'Inter', sans-serif",
|
|
@@ -804,7 +803,7 @@ var AvatarInitials = styled.span.withConfig({
|
|
|
804
803
|
},
|
|
805
804
|
displayName: "Avatar__AvatarInitials",
|
|
806
805
|
componentId: "sc-ezn4ax-2"
|
|
807
|
-
})(templateObject_3$
|
|
806
|
+
})(templateObject_3$h || (templateObject_3$h = __makeTemplateObject(["\n font-family: ", ";\n font-weight: ", ";\n font-size: ", ";\n color: ", ";\n line-height: 1;\n text-transform: uppercase;\n user-select: none;\n"], ["\n font-family: ", ";\n font-weight: ", ";\n font-size: ", ";\n color: ", ";\n line-height: 1;\n text-transform: uppercase;\n user-select: none;\n"
|
|
808
807
|
// Helper function to get initials from name
|
|
809
808
|
])), tokensData.base.fontFamily.body, tokensData.base.fontWeight[3], function (_a) {
|
|
810
809
|
var $size = _a.$size;
|
|
@@ -867,7 +866,7 @@ var Avatar = function Avatar(_a) {
|
|
|
867
866
|
"aria-hidden": "true"
|
|
868
867
|
}, initials));
|
|
869
868
|
};
|
|
870
|
-
var templateObject_1$y, templateObject_2$l, templateObject_3$
|
|
869
|
+
var templateObject_1$y, templateObject_2$l, templateObject_3$h;
|
|
871
870
|
|
|
872
871
|
React.createElement;
|
|
873
872
|
var _a$5 = tokensData.semantic,
|
|
@@ -1018,7 +1017,7 @@ var BadgeIndicator = styled.span.withConfig({
|
|
|
1018
1017
|
},
|
|
1019
1018
|
displayName: "Badge__BadgeIndicator",
|
|
1020
1019
|
componentId: "sc-tjz4pp-1"
|
|
1021
|
-
})(templateObject_3$
|
|
1020
|
+
})(templateObject_3$g || (templateObject_3$g = __makeTemplateObject(["\n position: absolute;\n top: 0;\n right: 0;\n transform: translate(50%, -50%);\n display: ", ";\n align-items: center;\n justify-content: center;\n min-width: ", ";\n height: ", ";\n padding: ", ";\n border-radius: ", ";\n line-height: 1;\n white-space: nowrap;\n box-shadow: 0 0 0 2px ", ";\n animation: ", " 0.2s ease-out;\n \n ", "\n"], ["\n position: absolute;\n top: 0;\n right: 0;\n transform: translate(50%, -50%);\n display: ", ";\n align-items: center;\n justify-content: center;\n min-width: ", ";\n height: ", ";\n padding: ", ";\n border-radius: ", ";\n line-height: 1;\n white-space: nowrap;\n box-shadow: 0 0 0 2px ", ";\n animation: ", " 0.2s ease-out;\n \n ", "\n"])), function (props) {
|
|
1022
1021
|
return props.$isVisible ? 'flex' : 'none';
|
|
1023
1022
|
}, function (props) {
|
|
1024
1023
|
return props.$isDot ? '8px' : '16px';
|
|
@@ -1074,7 +1073,7 @@ var Badge = function Badge(_a) {
|
|
|
1074
1073
|
color: "inverse"
|
|
1075
1074
|
}, displayCount), /*#__PURE__*/React.createElement(ScreenReaderOnly, null, label)));
|
|
1076
1075
|
};
|
|
1077
|
-
var templateObject_1$w, templateObject_2$k, templateObject_3$
|
|
1076
|
+
var templateObject_1$w, templateObject_2$k, templateObject_3$g, templateObject_4$e;
|
|
1078
1077
|
|
|
1079
1078
|
React.createElement;
|
|
1080
1079
|
var StyledBox = styled.div.withConfig({
|
|
@@ -1090,7 +1089,7 @@ var StyledBox = styled.div.withConfig({
|
|
|
1090
1089
|
}, function (props) {
|
|
1091
1090
|
return props.$flexDirection && css(templateObject_2$j || (templateObject_2$j = __makeTemplateObject(["flex-direction: ", ";"], ["flex-direction: ", ";"])), props.$flexDirection);
|
|
1092
1091
|
}, function (props) {
|
|
1093
|
-
return props.$justifyContent && css(templateObject_3$
|
|
1092
|
+
return props.$justifyContent && css(templateObject_3$f || (templateObject_3$f = __makeTemplateObject(["justify-content: ", ";"], ["justify-content: ", ";"])), props.$justifyContent);
|
|
1094
1093
|
}, function (props) {
|
|
1095
1094
|
return props.$alignItems && css(templateObject_4$d || (templateObject_4$d = __makeTemplateObject(["align-items: ", ";"], ["align-items: ", ";"])), props.$alignItems);
|
|
1096
1095
|
}, function (props) {
|
|
@@ -1276,7 +1275,7 @@ var BoxTransform = function BoxTransform(props) {
|
|
|
1276
1275
|
}, rest), children);
|
|
1277
1276
|
};
|
|
1278
1277
|
var Box = BoxTransform;
|
|
1279
|
-
var templateObject_1$v, templateObject_2$j, templateObject_3$
|
|
1278
|
+
var templateObject_1$v, templateObject_2$j, templateObject_3$f, templateObject_4$d, templateObject_5$a, templateObject_6$9, templateObject_7$7, templateObject_8$3, templateObject_9$2, templateObject_10$2, templateObject_11$2, templateObject_12$2, templateObject_13$2, templateObject_14$1, templateObject_15$1, templateObject_16$1, templateObject_17$1, templateObject_18$1, templateObject_19$1, templateObject_20$1, templateObject_21$1, templateObject_22$1, templateObject_23$1, templateObject_24$1, templateObject_25$1, templateObject_26$1, templateObject_27$1, templateObject_28$1, templateObject_29$1, templateObject_30$1, templateObject_31$1, templateObject_32$1, templateObject_33$1, templateObject_34$1, templateObject_35$1, templateObject_36, templateObject_37, templateObject_38, templateObject_39, templateObject_40, templateObject_41, templateObject_42, templateObject_43;
|
|
1280
1279
|
|
|
1281
1280
|
var add = {
|
|
1282
1281
|
path: "M13 11H19V13H13V19H11V13H5V11H11V5H13V11Z",
|
|
@@ -1606,16 +1605,6 @@ var StyledLink = styled.a.withConfig({
|
|
|
1606
1605
|
displayName: "Button__StyledLink",
|
|
1607
1606
|
componentId: "sc-1eiuum9-1"
|
|
1608
1607
|
})(templateObject_2$i || (templateObject_2$i = __makeTemplateObject(["\n ", "\n border-radius: ", ";\n \n ", "\n ", "\n"], ["\n ", "\n border-radius: ", ";\n \n ", "\n ", "\n"
|
|
1609
|
-
// Styled Next.js Link component (modern API without legacyBehavior)
|
|
1610
|
-
])), baseButtonStyles, button.primary.borderRadius, getVariantStyles, getSizeStyles);
|
|
1611
|
-
// Styled Next.js Link component (modern API without legacyBehavior)
|
|
1612
|
-
var StyledNextLink = styled(Link).withConfig({
|
|
1613
|
-
shouldForwardProp: function shouldForwardProp(prop) {
|
|
1614
|
-
return !prop.startsWith('$');
|
|
1615
|
-
},
|
|
1616
|
-
displayName: "Button__StyledNextLink",
|
|
1617
|
-
componentId: "sc-1eiuum9-2"
|
|
1618
|
-
})(templateObject_3$f || (templateObject_3$f = __makeTemplateObject(["\n ", "\n border-radius: ", ";\n \n ", "\n ", "\n"], ["\n ", "\n border-radius: ", ";\n \n ", "\n ", "\n"
|
|
1619
1608
|
// Helper function to get icon size based on button size
|
|
1620
1609
|
])), baseButtonStyles, button.primary.borderRadius, getVariantStyles, getSizeStyles);
|
|
1621
1610
|
// Helper function to get icon size based on button size
|
|
@@ -1652,18 +1641,21 @@ var Button = function Button(_a) {
|
|
|
1652
1641
|
children = _a.children,
|
|
1653
1642
|
target = _a.target,
|
|
1654
1643
|
iconName = _a.iconName,
|
|
1644
|
+
LinkComponent = _a.linkComponent,
|
|
1655
1645
|
dataTestId = _a["data-testid"],
|
|
1656
|
-
rest = __rest(_a, ["variant", "size", "url", "purpose", "children", "target", "iconName", 'data-testid']);
|
|
1657
|
-
// For
|
|
1658
|
-
if (purpose === 'link' && url &&
|
|
1659
|
-
return /*#__PURE__*/React.createElement(
|
|
1660
|
-
href: url
|
|
1646
|
+
rest = __rest(_a, ["variant", "size", "url", "purpose", "children", "target", "iconName", "linkComponent", 'data-testid']);
|
|
1647
|
+
// For links with custom link component (e.g., Next.js Link, React Router Link)
|
|
1648
|
+
if (purpose === 'link' && url && LinkComponent) {
|
|
1649
|
+
return /*#__PURE__*/React.createElement(LinkComponent, {
|
|
1650
|
+
href: url
|
|
1651
|
+
}, /*#__PURE__*/React.createElement(StyledLink, {
|
|
1652
|
+
as: "span",
|
|
1661
1653
|
$variant: variant,
|
|
1662
1654
|
$size: size,
|
|
1663
1655
|
"data-testid": dataTestId
|
|
1664
|
-
}, renderButtonContent(children, iconName, size));
|
|
1656
|
+
}, renderButtonContent(children, iconName, size)));
|
|
1665
1657
|
}
|
|
1666
|
-
// For
|
|
1658
|
+
// For standard links (external or without custom component)
|
|
1667
1659
|
if (purpose === 'link' && url) {
|
|
1668
1660
|
var linkProps = rest;
|
|
1669
1661
|
return /*#__PURE__*/React.createElement(StyledLink, _extends({
|
|
@@ -1704,7 +1696,7 @@ var Button = function Button(_a) {
|
|
|
1704
1696
|
"data-testid": dataTestId
|
|
1705
1697
|
}, buttonProps), renderButtonContent(children, iconName, size));
|
|
1706
1698
|
};
|
|
1707
|
-
var templateObject_1$t, templateObject_2$i
|
|
1699
|
+
var templateObject_1$t, templateObject_2$i;
|
|
1708
1700
|
|
|
1709
1701
|
var chip = tokensData.component.chip;
|
|
1710
1702
|
// Helper function to get variant styles as objects for CSS custom properties
|
|
@@ -2735,7 +2727,8 @@ var isInternalUrl = function isInternalUrl(url) {
|
|
|
2735
2727
|
return url.startsWith('/') && !url.startsWith('http');
|
|
2736
2728
|
};
|
|
2737
2729
|
var Breadcrumbs = function Breadcrumbs(_a) {
|
|
2738
|
-
var breadcrumbs = _a.breadcrumbs
|
|
2730
|
+
var breadcrumbs = _a.breadcrumbs,
|
|
2731
|
+
LinkComponent = _a.linkComponent;
|
|
2739
2732
|
return /*#__PURE__*/React.createElement(Container, null, /*#__PURE__*/React.createElement(BreadcrumbNavStyled, {
|
|
2740
2733
|
"aria-label": "breadcrumb"
|
|
2741
2734
|
}, /*#__PURE__*/React.createElement("ol", null, breadcrumbs.map(function (breadcrumb, index) {
|
|
@@ -2743,15 +2736,16 @@ var Breadcrumbs = function Breadcrumbs(_a) {
|
|
|
2743
2736
|
key: index
|
|
2744
2737
|
}, index === breadcrumbs.length - 1 ? /*#__PURE__*/React.createElement(Typography, {
|
|
2745
2738
|
variant: "caption"
|
|
2746
|
-
}, breadcrumb.label) : isInternalUrl(breadcrumb.url) ? /*#__PURE__*/React.createElement(
|
|
2739
|
+
}, breadcrumb.label) : LinkComponent && isInternalUrl(breadcrumb.url) ? /*#__PURE__*/React.createElement(LinkComponent, {
|
|
2747
2740
|
href: breadcrumb.url
|
|
2748
2741
|
}, /*#__PURE__*/React.createElement(Typography, {
|
|
2749
2742
|
variant: "caption"
|
|
2750
|
-
}, breadcrumb.label)) : /*#__PURE__*/React.createElement("a", {
|
|
2751
|
-
href: breadcrumb.url
|
|
2743
|
+
}, breadcrumb.label)) : /*#__PURE__*/React.createElement("a", _extends({
|
|
2744
|
+
href: breadcrumb.url
|
|
2745
|
+
}, !isInternalUrl(breadcrumb.url) && {
|
|
2752
2746
|
target: "_blank",
|
|
2753
2747
|
rel: "noopener noreferrer"
|
|
2754
|
-
}, /*#__PURE__*/React.createElement(Typography, {
|
|
2748
|
+
}), /*#__PURE__*/React.createElement(Typography, {
|
|
2755
2749
|
variant: "caption"
|
|
2756
2750
|
}, breadcrumb.label)));
|
|
2757
2751
|
}))));
|
|
@@ -2768,14 +2762,12 @@ var CardSmall = function CardSmall(_a) {
|
|
|
2768
2762
|
picture = _a.picture,
|
|
2769
2763
|
subtitle = _a.subtitle,
|
|
2770
2764
|
meta = _a.meta,
|
|
2771
|
-
href = _a.href
|
|
2765
|
+
href = _a.href,
|
|
2766
|
+
LinkComponent = _a.linkComponent;
|
|
2772
2767
|
if (!picture || !meta) {
|
|
2773
2768
|
return null;
|
|
2774
2769
|
}
|
|
2775
|
-
|
|
2776
|
-
href: href || '#',
|
|
2777
|
-
"aria-label": title
|
|
2778
|
-
}, /*#__PURE__*/React.createElement(Stack, {
|
|
2770
|
+
var content = /*#__PURE__*/React.createElement(Stack, {
|
|
2779
2771
|
direction: "column",
|
|
2780
2772
|
gap: "sm"
|
|
2781
2773
|
}, /*#__PURE__*/React.createElement(Picture, {
|
|
@@ -2797,7 +2789,14 @@ var CardSmall = function CardSmall(_a) {
|
|
|
2797
2789
|
}, subtitle), meta && /*#__PURE__*/React.createElement(Typography, {
|
|
2798
2790
|
variant: "label",
|
|
2799
2791
|
color: "subdued"
|
|
2800
|
-
}, meta))))
|
|
2792
|
+
}, meta))));
|
|
2793
|
+
return /*#__PURE__*/React.createElement(CardSmallStyled, null, LinkComponent && href ? /*#__PURE__*/React.createElement(LinkComponent, {
|
|
2794
|
+
href: href,
|
|
2795
|
+
"aria-label": title
|
|
2796
|
+
}, content) : /*#__PURE__*/React.createElement("a", {
|
|
2797
|
+
href: href || '#',
|
|
2798
|
+
"aria-label": title
|
|
2799
|
+
}, content));
|
|
2801
2800
|
};
|
|
2802
2801
|
var templateObject_1$h;
|
|
2803
2802
|
|