@reltio/design 0.0.0-65
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 +58 -0
- package/components/Button/Button.d.ts +9 -0
- package/components/Button/Button.js +71 -0
- package/components/Button/Button.module.css.d.ts +2 -0
- package/components/Button/Button.module.css.js +194 -0
- package/components/Button/Button.module.css.json +1 -0
- package/components/Button/Button.types.d.ts +109 -0
- package/components/Button/Button.types.js +1 -0
- package/components/Button/index.d.ts +2 -0
- package/components/Button/index.js +1 -0
- package/package.json +26 -0
- package/packages/design/index.d.ts +1 -0
- package/packages/design/index.js +1 -0
- package/utils/classNames.d.ts +12 -0
- package/utils/classNames.js +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
|
|
2
|
+
**@reltio/design** is a public JavaScript library that contains key components and utilities for developing Reltio UI applications.
|
|
3
|
+
|
|
4
|
+
- Built on ReactJS.
|
|
5
|
+
- Intended for Reltio internal teams developing applications.
|
|
6
|
+
- [Storybook with component examples is available here](https://reltio.design).
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
To install, use NPM:
|
|
11
|
+
```bash
|
|
12
|
+
npm install @reltio/design
|
|
13
|
+
```
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
Example usage of the **Button** component:
|
|
17
|
+
|
|
18
|
+
```jsx
|
|
19
|
+
import React from 'react';
|
|
20
|
+
import { Button } from '@reltio/design';
|
|
21
|
+
|
|
22
|
+
function App() {
|
|
23
|
+
return <Button>Touch me</Button>;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default App;
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Important:** React is listed as peer dependencies. Make sure it's added to your project.
|
|
30
|
+
|
|
31
|
+
## Target Audience
|
|
32
|
+
|
|
33
|
+
The library is designed for Reltio internal teams developing applications.
|
|
34
|
+
|
|
35
|
+
If you need additional components from the [Storybook](https://reltio.design), contact the **UI Center of Excellence** team at [ui.coe@reltio.com](mailto:ui.coe@reltio.com).
|
|
36
|
+
|
|
37
|
+
## Contribution
|
|
38
|
+
|
|
39
|
+
Adding or modifying components is done via the monorepo: [https://bitbucket.org/reltio-ondemand/reltio-design](https://bitbucket.org/reltio-ondemand/reltio-design).
|
|
40
|
+
|
|
41
|
+
### Development Process:
|
|
42
|
+
|
|
43
|
+
1. Ensure you have write access to the monorepo.
|
|
44
|
+
2. Create a feature branch for your changes.
|
|
45
|
+
3. Run Storybook locally with `npm run dev`
|
|
46
|
+
3. Follow the standard pull request (PR) creation and code review processes adopted across Reltio teams.
|
|
47
|
+
4. After your PR is successfully merged into the main branch, run a **custom Bitbucket pipeline** to publish the component to NPM.
|
|
48
|
+
|
|
49
|
+
### Publishing:
|
|
50
|
+
|
|
51
|
+
- If the component is published from the main branch, it will be released to NPM.
|
|
52
|
+
- If it is published from a feature branch, the component will be versioned as `0.0.0-{BUILD_ID}` and tagged with `{BRANCH_NAME}`.
|
|
53
|
+
|
|
54
|
+
For any questions about the process, contact the **UI Center of Excellence** team via [ui.coe@reltio.com](mailto:ui.coe@reltio.com).
|
|
55
|
+
|
|
56
|
+
## License
|
|
57
|
+
|
|
58
|
+
This library is distributed under Reltio’s corporate license and is intended for internal use only.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ButtonProps } from "./Button.types";
|
|
2
|
+
/**
|
|
3
|
+
* Universal Button Component
|
|
4
|
+
*
|
|
5
|
+
* A flexible, accessible button component that supports multiple variants
|
|
6
|
+
* (filled, outlined, text), color options (primary, secondary, inherited),
|
|
7
|
+
* sizes, states, and can render as either a button or anchor element.
|
|
8
|
+
*/
|
|
9
|
+
export declare const Button: ({ variant, color, size, disabled, fullWidth, children, className, onClick, href, type, "aria-label": ariaLabel, ...rest }: ButtonProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
import { classNames } from "../../utils/classNames";
|
|
4
|
+
import styles from "./Button.module.css";
|
|
5
|
+
/**
|
|
6
|
+
* Universal Button Component
|
|
7
|
+
*
|
|
8
|
+
* A flexible, accessible button component that supports multiple variants
|
|
9
|
+
* (filled, outlined, text), color options (primary, secondary, inherited),
|
|
10
|
+
* sizes, states, and can render as either a button or anchor element.
|
|
11
|
+
*/
|
|
12
|
+
export const Button = ({ variant = "filled", color = "inherited", size = "medium", disabled = false, fullWidth = false, children, className, onClick, href, type = "button", "aria-label": ariaLabel, ...rest }) => {
|
|
13
|
+
const buttonRef = useRef(null);
|
|
14
|
+
// Remove focus when button becomes disabled
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
if (disabled &&
|
|
17
|
+
buttonRef.current &&
|
|
18
|
+
document.activeElement === buttonRef.current) {
|
|
19
|
+
buttonRef.current.blur();
|
|
20
|
+
}
|
|
21
|
+
}, [disabled]);
|
|
22
|
+
// Determine if button is interactive
|
|
23
|
+
const isInteractive = !disabled;
|
|
24
|
+
// Handle click events
|
|
25
|
+
const handleClick = (event) => {
|
|
26
|
+
if (!isInteractive) {
|
|
27
|
+
event.preventDefault();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
// Prevent navigation for disabled anchors
|
|
31
|
+
if (href && disabled) {
|
|
32
|
+
event.preventDefault();
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
onClick?.(event);
|
|
36
|
+
};
|
|
37
|
+
// Handle keyboard events (Enter and Space)
|
|
38
|
+
const handleKeyDown = (event) => {
|
|
39
|
+
if (!isInteractive) {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
// Enter and Space activate button
|
|
44
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
45
|
+
if (event.key === " ") {
|
|
46
|
+
event.preventDefault(); // Prevent page scroll
|
|
47
|
+
}
|
|
48
|
+
if (href) {
|
|
49
|
+
// For anchors, trigger click
|
|
50
|
+
buttonRef.current?.click();
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// For buttons, trigger onClick
|
|
54
|
+
onClick?.(event);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
// Compose className using classNames utility
|
|
59
|
+
const composedClassName = classNames(styles.root, styles[variant], styles[color], styles[size], disabled && styles.disabled, fullWidth && styles.fullWidth, className);
|
|
60
|
+
// ARIA attributes
|
|
61
|
+
const ariaAttributes = {
|
|
62
|
+
"aria-label": ariaLabel,
|
|
63
|
+
"aria-disabled": disabled ? true : undefined,
|
|
64
|
+
};
|
|
65
|
+
// Render as anchor if href is provided
|
|
66
|
+
if (href) {
|
|
67
|
+
return (_jsx("a", { ref: buttonRef, href: disabled ? undefined : href, className: composedClassName, onClick: handleClick, onKeyDown: handleKeyDown, ...ariaAttributes, ...rest, children: children }));
|
|
68
|
+
}
|
|
69
|
+
// Render as button
|
|
70
|
+
return (_jsx("button", { ref: buttonRef, type: type, disabled: disabled, className: composedClassName, onClick: handleClick, onKeyDown: handleKeyDown, ...ariaAttributes, ...rest, children: children }));
|
|
71
|
+
};
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import styleInject from 'style-inject';
|
|
2
|
+
import json from './Button.module.css.json';
|
|
3
|
+
styleInject(`
|
|
4
|
+
/* CSS Custom Properties - All defined on .root (Principle IX) */
|
|
5
|
+
._root_1lt78_1 {
|
|
6
|
+
/* Font tokens */
|
|
7
|
+
--reltio-button-font-family: var(
|
|
8
|
+
--reltio-font-family-body,
|
|
9
|
+
"Roboto",
|
|
10
|
+
sans-serif
|
|
11
|
+
);
|
|
12
|
+
--reltio-button-font-size: var(--reltio-font-size-body, 16px);
|
|
13
|
+
--reltio-button-font-weight: var(--reltio-font-weight-body, 500);
|
|
14
|
+
--reltio-button-line-height: var(--reltio-line-height-body, 1.5);
|
|
15
|
+
--reltio-button-letter-spacing: var(--reltio-letter-spacing-body, 0.15px);
|
|
16
|
+
|
|
17
|
+
/* Color tokens */
|
|
18
|
+
--reltio-button-color-background: #f5f5fa;
|
|
19
|
+
--reltio-button-color-primary: var(--reltio-color-primary, #0000cc);
|
|
20
|
+
--reltio-button-color-primary-text: var(--reltio-color-on-primary, #ffffff);
|
|
21
|
+
--reltio-button-color-text: var(--reltio-color-text, #0e0e25);
|
|
22
|
+
|
|
23
|
+
/* Spacing tokens */
|
|
24
|
+
--reltio-button-padding-x-small: var(--reltio-spacing-sm, 16px);
|
|
25
|
+
--reltio-button-padding-y-small: var(--reltio-spacing-xs, 8px);
|
|
26
|
+
--reltio-button-padding-x-medium: var(--reltio-spacing-md, 20px);
|
|
27
|
+
--reltio-button-padding-y-medium: var(--reltio-spacing-sm, 12px);
|
|
28
|
+
--reltio-button-padding-x-large: var(--reltio-spacing-lg, 32px);
|
|
29
|
+
--reltio-button-padding-y-large: var(--reltio-spacing-md, 16px);
|
|
30
|
+
--reltio-button-gap-x: var(--reltio-spacing-xs, 8px);
|
|
31
|
+
|
|
32
|
+
/* Size tokens */
|
|
33
|
+
--reltio-button-height-small: var(--reltio-spacing-xl, 32px);
|
|
34
|
+
--reltio-button-height-medium: var(--reltio-spacing-2xl, 40px);
|
|
35
|
+
--reltio-button-height-large: var(--reltio-spacing-3xl, 48px);
|
|
36
|
+
|
|
37
|
+
/* Border and shape */
|
|
38
|
+
--reltio-button-border-radius: 9999px; /* Fully rounded corners (pill shape) - Material Design 3 */
|
|
39
|
+
--reltio-button-border-width: 0;
|
|
40
|
+
|
|
41
|
+
/* Transitions */
|
|
42
|
+
--reltio-button-transition-duration: 200ms;
|
|
43
|
+
--reltio-button-transition-timing: ease;
|
|
44
|
+
|
|
45
|
+
/* Disabled state */
|
|
46
|
+
--reltio-button-disabled-opacity: 0.38;
|
|
47
|
+
--reltio-button-disabled-cursor: not-allowed;
|
|
48
|
+
|
|
49
|
+
/* Base styles */
|
|
50
|
+
display: inline-flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
justify-content: center;
|
|
53
|
+
gap: var(--reltio-button-gap-x);
|
|
54
|
+
border: var(--reltio-button-border-width) solid transparent;
|
|
55
|
+
border-radius: var(--reltio-button-border-radius);
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
font-family: var(--reltio-button-font-family);
|
|
58
|
+
font-size: var(--reltio-button-font-size);
|
|
59
|
+
font-weight: var(--reltio-button-font-weight);
|
|
60
|
+
line-height: var(--reltio-button-line-height);
|
|
61
|
+
letter-spacing: var(--reltio-button-letter-spacing);
|
|
62
|
+
text-align: center;
|
|
63
|
+
text-decoration: none;
|
|
64
|
+
white-space: nowrap;
|
|
65
|
+
user-select: none;
|
|
66
|
+
transition: all var(--reltio-button-transition-duration)
|
|
67
|
+
var(--reltio-button-transition-timing);
|
|
68
|
+
box-sizing: border-box;
|
|
69
|
+
/* Remove default button styles */
|
|
70
|
+
background: none;
|
|
71
|
+
margin: 0;
|
|
72
|
+
padding: 0;
|
|
73
|
+
|
|
74
|
+
/* Focus visible state */
|
|
75
|
+
&:focus-visible {
|
|
76
|
+
outline: 2px solid var(--reltio-button-color-primary);
|
|
77
|
+
outline-offset: 2px;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Disabled state */
|
|
81
|
+
&:disabled,
|
|
82
|
+
&[aria-disabled="true"] {
|
|
83
|
+
opacity: var(--reltio-button-disabled-opacity);
|
|
84
|
+
cursor: var(--reltio-button-disabled-cursor);
|
|
85
|
+
pointer-events: none;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* Style: Filled - base structure */
|
|
90
|
+
._filled_1lt78_87 {
|
|
91
|
+
border: none;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* Style: Outlined - base structure */
|
|
95
|
+
._outlined_1lt78_92 {
|
|
96
|
+
background-color: transparent;
|
|
97
|
+
border: 1px solid;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Style: Text - base structure */
|
|
101
|
+
._text_1lt78_98 {
|
|
102
|
+
background-color: transparent;
|
|
103
|
+
border: none;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/* Filled + Primary */
|
|
107
|
+
._filled_1lt78_87._primary_1lt78_104 {
|
|
108
|
+
background-color: var(--reltio-button-color-primary);
|
|
109
|
+
color: #fff;
|
|
110
|
+
|
|
111
|
+
&:hover {
|
|
112
|
+
background-color: #006;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Filled + Inherited */
|
|
117
|
+
._filled_1lt78_87._inherited_1lt78_114 {
|
|
118
|
+
background-color: var(--reltio-button-color-background);
|
|
119
|
+
color: var(--reltio-button-color-text);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/* Outlined + Primary */
|
|
123
|
+
._outlined_1lt78_92._primary_1lt78_104 {
|
|
124
|
+
border-color: var(--reltio-button-color-primary);
|
|
125
|
+
color: var(--reltio-button-color-primary);
|
|
126
|
+
|
|
127
|
+
&:hover {
|
|
128
|
+
background-color: var(--reltio-button-color-background);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/* Outlined + Inherited */
|
|
133
|
+
._outlined_1lt78_92._inherited_1lt78_114 {
|
|
134
|
+
/* Border and text color inherit from parent */
|
|
135
|
+
border-color: currentColor;
|
|
136
|
+
color: inherit;
|
|
137
|
+
|
|
138
|
+
&:hover {
|
|
139
|
+
background-color: var(--reltio-button-color-background);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* Text + Primary */
|
|
144
|
+
._text_1lt78_98._primary_1lt78_104 {
|
|
145
|
+
color: var(--reltio-button-color-primary);
|
|
146
|
+
|
|
147
|
+
&:hover {
|
|
148
|
+
background-color: var(--reltio-button-color-background);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/* Text + Inherited */
|
|
153
|
+
._text_1lt78_98._inherited_1lt78_114 {
|
|
154
|
+
color: inherit;
|
|
155
|
+
|
|
156
|
+
&:hover {
|
|
157
|
+
background-color: var(--reltio-button-color-background);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* Size: Small */
|
|
162
|
+
._small_1lt78_159 {
|
|
163
|
+
min-height: var(--reltio-button-height-small);
|
|
164
|
+
padding: var(--reltio-button-padding-y-small)
|
|
165
|
+
var(--reltio-button-padding-x-small);
|
|
166
|
+
font-size: 0.875rem;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/* Size: Medium */
|
|
170
|
+
._medium_1lt78_167 {
|
|
171
|
+
min-height: var(--reltio-button-height-medium);
|
|
172
|
+
padding: var(--reltio-button-padding-y-medium)
|
|
173
|
+
var(--reltio-button-padding-x-medium);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* Size: Large */
|
|
177
|
+
._large_1lt78_174 {
|
|
178
|
+
min-height: var(--reltio-button-height-large);
|
|
179
|
+
padding: var(--reltio-button-padding-y-large)
|
|
180
|
+
var(--reltio-button-padding-x-large);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/* State: Disabled */
|
|
184
|
+
._disabled_1lt78_181 {
|
|
185
|
+
opacity: var(--reltio-button-disabled-opacity);
|
|
186
|
+
cursor: var(--reltio-button-disabled-cursor);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/* Full Width */
|
|
190
|
+
._fullWidth_1lt78_187 {
|
|
191
|
+
width: 100%;
|
|
192
|
+
}
|
|
193
|
+
`);
|
|
194
|
+
export default json;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "root": "_root_1lt78_1", "filled": "_filled_1lt78_87", "outlined": "_outlined_1lt78_92", "text": "_text_1lt78_98", "primary": "_primary_1lt78_104", "inherited": "_inherited_1lt78_114", "small": "_small_1lt78_159", "medium": "_medium_1lt78_167", "large": "_large_1lt78_174", "disabled": "_disabled_1lt78_181", "fullWidth": "_fullWidth_1lt78_187" }
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Visual variant for the button
|
|
4
|
+
*/
|
|
5
|
+
export type ButtonVariant = "filled" | "outlined" | "text";
|
|
6
|
+
/**
|
|
7
|
+
* Color variant for the button
|
|
8
|
+
*/
|
|
9
|
+
export type ButtonColor = "primary" | "inherited";
|
|
10
|
+
/**
|
|
11
|
+
* Size variant for the button
|
|
12
|
+
*/
|
|
13
|
+
export type ButtonSize = "small" | "medium" | "large";
|
|
14
|
+
/**
|
|
15
|
+
* Base button props (without element-specific attributes)
|
|
16
|
+
*/
|
|
17
|
+
type BaseButtonProps = {
|
|
18
|
+
/**
|
|
19
|
+
* Visual variant
|
|
20
|
+
* @default "filled"
|
|
21
|
+
*/
|
|
22
|
+
variant?: ButtonVariant;
|
|
23
|
+
/**
|
|
24
|
+
* Color variant
|
|
25
|
+
* @default "inherited"
|
|
26
|
+
*/
|
|
27
|
+
color?: ButtonColor;
|
|
28
|
+
/**
|
|
29
|
+
* Size variant
|
|
30
|
+
* @default "medium"
|
|
31
|
+
*/
|
|
32
|
+
size?: ButtonSize;
|
|
33
|
+
/**
|
|
34
|
+
* Whether the button is disabled
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Whether the button should take full width of container
|
|
40
|
+
* @default false
|
|
41
|
+
*/
|
|
42
|
+
fullWidth?: boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Button content (text, icons, etc.)
|
|
45
|
+
*/
|
|
46
|
+
children: React.ReactNode;
|
|
47
|
+
/**
|
|
48
|
+
* Additional CSS class names
|
|
49
|
+
*/
|
|
50
|
+
className?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Additional CSS variables
|
|
53
|
+
*/
|
|
54
|
+
style?: React.CSSProperties & {
|
|
55
|
+
"--reltio-button-color-background"?: string;
|
|
56
|
+
"--reltio-button-color-text"?: string;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Click event handler
|
|
60
|
+
*/
|
|
61
|
+
onClick?: React.MouseEventHandler<HTMLElement>;
|
|
62
|
+
/**
|
|
63
|
+
* Accessible label for screen readers
|
|
64
|
+
* Required if button has no visible text
|
|
65
|
+
*/
|
|
66
|
+
"aria-label"?: string;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Button props when rendered as button element (no href)
|
|
70
|
+
*/
|
|
71
|
+
type ButtonElementProps = BaseButtonProps & {
|
|
72
|
+
/**
|
|
73
|
+
* If href is provided, component renders as anchor element
|
|
74
|
+
* If href is not provided, component renders as button element
|
|
75
|
+
*/
|
|
76
|
+
href?: never;
|
|
77
|
+
/**
|
|
78
|
+
* Button type (only applicable when rendered as button)
|
|
79
|
+
* @default "button"
|
|
80
|
+
*/
|
|
81
|
+
type?: "button" | "submit" | "reset";
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Anchor props when rendered as anchor element (with href)
|
|
85
|
+
*/
|
|
86
|
+
type AnchorElementProps = BaseButtonProps & {
|
|
87
|
+
/**
|
|
88
|
+
* URL to navigate to (causes component to render as anchor)
|
|
89
|
+
*/
|
|
90
|
+
href: string;
|
|
91
|
+
/**
|
|
92
|
+
* Button type is not applicable for anchor elements
|
|
93
|
+
*/
|
|
94
|
+
type?: never;
|
|
95
|
+
/**
|
|
96
|
+
* Target attribute for anchor (e.g., "_blank")
|
|
97
|
+
*/
|
|
98
|
+
target?: string;
|
|
99
|
+
/**
|
|
100
|
+
* Rel attribute for anchor (e.g., "noopener noreferrer")
|
|
101
|
+
*/
|
|
102
|
+
rel?: string;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Union type for Button component props
|
|
106
|
+
* Component can be either a button or an anchor based on href prop
|
|
107
|
+
*/
|
|
108
|
+
export type ButtonProps = (ButtonElementProps | AnchorElementProps) & Omit<React.ComponentPropsWithoutRef<"button">, keyof ButtonElementProps> & Omit<React.ComponentPropsWithoutRef<"a">, keyof AnchorElementProps>;
|
|
109
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./Button";
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reltio/design",
|
|
3
|
+
"version": "0.0.0-65",
|
|
4
|
+
"main": "packages/design/index.js",
|
|
5
|
+
"description": "Reltio Design System",
|
|
6
|
+
"peerDependencies": {
|
|
7
|
+
"react": "^17.0.2",
|
|
8
|
+
"react-dom": "^17.0.2"
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"style-inject": "^0.3.0"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "node build-css.mjs && tsc && tsc-alias",
|
|
15
|
+
"postbuild": "cp package.json dist/ && cp README.md dist/"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/react": "^17.0.83",
|
|
19
|
+
"@types/react-dom": "^17.0.26",
|
|
20
|
+
"glob": "^11.0.0",
|
|
21
|
+
"postcss": "^8.4.49",
|
|
22
|
+
"postcss-modules": "^6.0.1",
|
|
23
|
+
"tsc-alias": "^1.8.10",
|
|
24
|
+
"typescript": "^5.7.2"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../components/Button";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "../../components/Button";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combines CSS class names into a single string, handling BEM-like naming conventions.
|
|
3
|
+
* Filters out falsy values and ensures unique class names.
|
|
4
|
+
* For classes with suffixes (containing '__'), automatically adds the base class.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* classNames('a__b', false, 'c__d', 'c__e') // returns 'a a__b c c__d c__e'
|
|
8
|
+
*
|
|
9
|
+
* @param cssClasses - Array of CSS class names (strings) or falsy values
|
|
10
|
+
* @returns space-separated string of unique CSS class names
|
|
11
|
+
*/
|
|
12
|
+
export declare const classNames: (...cssClasses: (string | undefined | null | false)[]) => string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Combines CSS class names into a single string, handling BEM-like naming conventions.
|
|
3
|
+
* Filters out falsy values and ensures unique class names.
|
|
4
|
+
* For classes with suffixes (containing '__'), automatically adds the base class.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* classNames('a__b', false, 'c__d', 'c__e') // returns 'a a__b c c__d c__e'
|
|
8
|
+
*
|
|
9
|
+
* @param cssClasses - Array of CSS class names (strings) or falsy values
|
|
10
|
+
* @returns space-separated string of unique CSS class names
|
|
11
|
+
*/
|
|
12
|
+
export const classNames = (...cssClasses) => {
|
|
13
|
+
const uniqueClasses = new Set();
|
|
14
|
+
cssClasses.forEach((cssClass) => {
|
|
15
|
+
if (!cssClass)
|
|
16
|
+
return;
|
|
17
|
+
// Add the class itself
|
|
18
|
+
uniqueClasses.add(cssClass);
|
|
19
|
+
// If class contains a suffix (__), add the base class
|
|
20
|
+
const baseClass = cssClass.split("__")[0];
|
|
21
|
+
if (baseClass && baseClass !== cssClass) {
|
|
22
|
+
uniqueClasses.add(baseClass);
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return Array.from(uniqueClasses).join(" ");
|
|
26
|
+
};
|