@hyphen/hyphen-components 6.1.1 → 6.2.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/dist/components/Sidebar/Sidebar.d.ts +1 -1
- package/dist/css/utilities.css +1 -1
- package/dist/css/variables.css +2 -2
- package/dist/hyphen-components.cjs.development.js +1 -1
- package/dist/hyphen-components.cjs.development.js.map +1 -1
- package/dist/hyphen-components.cjs.production.min.js +1 -1
- package/dist/hyphen-components.cjs.production.min.js.map +1 -1
- package/dist/hyphen-components.esm.js +1 -1
- package/dist/hyphen-components.esm.js.map +1 -1
- package/dist/lib/tokens.d.ts +1 -1
- package/package.json +2 -2
- package/src/components/AspectRatio/AspectRatio.test.tsx +18 -0
- package/src/components/Collapsible/Collapsible.test.tsx +22 -0
- package/src/components/DropdownMenu/DropdownMenu.test.tsx +23 -0
- package/src/components/FormControl/FormControl.test.tsx +26 -0
- package/src/components/HelpText/HelpText.test.tsx +12 -0
- package/src/components/InputValidationMessage/InputValidationMessage.test.tsx +18 -0
- package/src/components/Sidebar/Sidebar.test.tsx +26 -0
- package/src/components/Sidebar/Sidebar.tsx +1 -1
- package/src/components/ThemeProvider/ThemeProvider.test.tsx +49 -0
- package/src/components/Toggle/Toggle.test.tsx +13 -0
- package/src/components/ToggleGroup/ToggleGroup.test.tsx +19 -0
- package/src/components/Tooltip/Tooltip.test.tsx +24 -0
package/dist/lib/tokens.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BorderRadiusSize, Breakpoint, BreakpointSizeWithBase } from '../types';
|
|
2
|
-
export declare const ICON_NAMES: ("add" | "alarm-disable" | "alarm" | "analytics" | "app-window" | "arrow-down" | "arrow-left" | "arrow-right" | "arrow-up" | "arrows-maximize" | "at" | "ban" | "block" | "blocks" | "book-open" | "c-add" | "c-check" | "c-delete" | "c-in-progress" | "c-info" | "c-question" | "c-remove" | "c-user" | "c-warning" | "calendar-create" | "calendar" | "camera" | "caret-down" | "caret-left" | "caret-right" | "caret-sm-down" | "caret-sm-left" | "caret-sm-right" | "caret-sm-up" | "caret-up-down" | "caret-up" | "chart-bar" | "chart-line" | "chat" | "check" | "checkbox-btn-checked" | "checkbox-btn-indeterminate" | "checkbox-btn" | "circle-filled" | "circle" | "clipboard" | "cloud" | "code" | "command-line" | "computer" | "contact" | "copy-document" | "dashboard" | "database" | "dock-left" | "document" | "dots" | "download" | "electricity-bolt" | "exclamation-mark" | "eye-slash" | "eye" | "filter" | "flag" | "folder" | "gear" | "grab" | "hash-mark" | "heart-o" | "heart" | "home" | "info" | "integrations" | "key" | "launch-app" | "lightbulb" | "link" | "list" | "lock" | "logo-deploy" | "logo-env" | "logo-link" | "logo-netinfo" | "logo-toggle" | "logout" | "mail" | "memory" | "menu" | "minus" | "moon" | "paperclip" | "path-intersect" | "pause" | "pc" | "pencil" | "phone" | "photo" | "play" | "qr-code" | "radio-btn-checked" | "radio-btn-unchecked" | "refresh" | "remove" | "rewind" | "search" | "send" | "settings" | "skip" | "ssd" | "stack" | "star-o" | "star" | "stopwatch" | "subtract" | "sun" | "t-warning" | "tag" | "terminal" | "time-alarm" | "time-clock" | "trash" | "unlocked" | "upload" | "user-create" | "user" | "users" | "wifi-off" | "wifi" | "zoom-in" | "zoom-out")[];
|
|
2
|
+
export declare const ICON_NAMES: ("add" | "alarm-disable" | "alarm" | "analytics" | "app-window" | "arrow-down" | "arrow-left" | "arrow-right" | "arrow-up" | "arrows-maximize" | "at" | "ban" | "block" | "blocks" | "book-open" | "c-add" | "c-check" | "c-delete" | "c-in-progress" | "c-info" | "c-question" | "c-remove" | "c-user" | "c-warning" | "calendar-create" | "calendar" | "camera" | "caret-down" | "caret-left" | "caret-right" | "caret-sm-down" | "caret-sm-left" | "caret-sm-right" | "caret-sm-up" | "caret-up-down" | "caret-up" | "chart-bar" | "chart-line" | "chat" | "check" | "checkbox-btn-checked" | "checkbox-btn-indeterminate" | "checkbox-btn" | "circle-filled" | "circle" | "clipboard" | "cloud" | "code" | "command-line" | "computer" | "contact" | "copy-document" | "cpu" | "dashboard" | "database" | "dock-left" | "document" | "dots" | "download" | "electricity-bolt" | "exclamation-mark" | "eye-slash" | "eye" | "filter" | "flag" | "folder" | "gear" | "grab" | "hash-mark" | "heart-o" | "heart" | "home" | "info" | "integrations" | "key" | "launch-app" | "lightbulb" | "link" | "list" | "lock" | "logo-deploy" | "logo-env" | "logo-github" | "logo-link" | "logo-netinfo" | "logo-toggle" | "logout" | "mail" | "memory" | "menu" | "microphone" | "minus" | "moon" | "paperclip" | "path-intersect" | "pause" | "pc" | "pencil" | "phone" | "photo" | "play" | "qr-code" | "radio-btn-checked" | "radio-btn-unchecked" | "refresh" | "remove" | "rewind" | "search" | "send" | "settings" | "skip" | "ssd" | "stack" | "star-o" | "star" | "stopwatch" | "subtract" | "sun" | "t-warning" | "tag" | "terminal" | "time-alarm" | "time-clock" | "trash" | "unlocked" | "upload" | "user-create" | "user" | "users" | "wifi-off" | "wifi" | "zoom-in" | "zoom-out")[];
|
|
3
3
|
export declare const BORDER_RADIUS_OPTIONS: BorderRadiusSize[];
|
|
4
4
|
export declare const BORDER_SIZE_OPTIONS: ("0" | "sm" | "md" | "lg")[];
|
|
5
5
|
export declare const BREAKPOINT_OPTIONS: BreakpointSizeWithBase[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyphen/hyphen-components",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "@hyphen"
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
],
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@emotion/react": "^11.14.0",
|
|
65
|
-
"@hyphen/hyphen-design-tokens": "^5.
|
|
65
|
+
"@hyphen/hyphen-design-tokens": "^5.2.0",
|
|
66
66
|
"@radix-ui/react-aspect-ratio": "^1.1.7",
|
|
67
67
|
"@radix-ui/react-collapsible": "^1.1.12",
|
|
68
68
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { render } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { AspectRatio } from './AspectRatio';
|
|
4
|
+
|
|
5
|
+
describe('AspectRatio', () => {
|
|
6
|
+
test('renders children within the aspect ratio box', () => {
|
|
7
|
+
const { container } = render(
|
|
8
|
+
<AspectRatio ratio={16 / 9}>
|
|
9
|
+
<div data-testid="child" />
|
|
10
|
+
</AspectRatio>
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
const wrapper = container.firstChild as HTMLElement;
|
|
14
|
+
expect(wrapper).toBeInTheDocument();
|
|
15
|
+
expect(wrapper.querySelector('[data-testid="child"]')).toBeInTheDocument();
|
|
16
|
+
expect(wrapper.style.position).toBe('relative');
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import {
|
|
4
|
+
Collapsible,
|
|
5
|
+
CollapsibleTrigger,
|
|
6
|
+
CollapsibleContent,
|
|
7
|
+
} from './Collapsible';
|
|
8
|
+
|
|
9
|
+
describe('Collapsible', () => {
|
|
10
|
+
test('toggles content visibility when trigger is clicked', async () => {
|
|
11
|
+
render(
|
|
12
|
+
<Collapsible>
|
|
13
|
+
<CollapsibleTrigger>Toggle</CollapsibleTrigger>
|
|
14
|
+
<CollapsibleContent>Hidden content</CollapsibleContent>
|
|
15
|
+
</Collapsible>
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
expect(screen.queryByText('Hidden content')).not.toBeInTheDocument();
|
|
19
|
+
fireEvent.click(screen.getByText('Toggle'));
|
|
20
|
+
expect(await screen.findByText('Hidden content')).toBeInTheDocument();
|
|
21
|
+
});
|
|
22
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import {
|
|
4
|
+
DropdownMenu,
|
|
5
|
+
DropdownMenuTrigger,
|
|
6
|
+
DropdownMenuContent,
|
|
7
|
+
DropdownMenuItem,
|
|
8
|
+
} from './DropdownMenu';
|
|
9
|
+
|
|
10
|
+
describe('DropdownMenu', () => {
|
|
11
|
+
test('renders item when menu is open', () => {
|
|
12
|
+
render(
|
|
13
|
+
<DropdownMenu open>
|
|
14
|
+
<DropdownMenuTrigger>Open</DropdownMenuTrigger>
|
|
15
|
+
<DropdownMenuContent>
|
|
16
|
+
<DropdownMenuItem>Item</DropdownMenuItem>
|
|
17
|
+
</DropdownMenuContent>
|
|
18
|
+
</DropdownMenu>
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
expect(screen.getByText('Item')).toBeInTheDocument();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { FormControl } from './FormControl';
|
|
4
|
+
|
|
5
|
+
describe('FormControl', () => {
|
|
6
|
+
test('renders label and error message', () => {
|
|
7
|
+
render(
|
|
8
|
+
<FormControl id="input" label="Label" error="Error">
|
|
9
|
+
<input id="input" />
|
|
10
|
+
</FormControl>
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
expect(screen.getByText('Label')).toBeInTheDocument();
|
|
14
|
+
expect(screen.getByText('Error')).toBeInTheDocument();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('hides label when hideLabel is true', () => {
|
|
18
|
+
render(
|
|
19
|
+
<FormControl id="input" label="Label" hideLabel>
|
|
20
|
+
<input id="input" />
|
|
21
|
+
</FormControl>
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
expect(screen.queryByText('Label')).not.toBeInTheDocument();
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { HelpText } from './HelpText';
|
|
4
|
+
|
|
5
|
+
describe('HelpText', () => {
|
|
6
|
+
test('renders children with correct class', () => {
|
|
7
|
+
render(<HelpText>Helpful</HelpText>);
|
|
8
|
+
const text = screen.getByText('Helpful');
|
|
9
|
+
expect(text).toBeInTheDocument();
|
|
10
|
+
expect(text).toHaveClass('help-text');
|
|
11
|
+
});
|
|
12
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { InputValidationMessage } from './InputValidationMessage';
|
|
4
|
+
|
|
5
|
+
describe('InputValidationMessage', () => {
|
|
6
|
+
test('renders message with default size', () => {
|
|
7
|
+
render(<InputValidationMessage>Oops</InputValidationMessage>);
|
|
8
|
+
const msg = screen.getByText('Oops');
|
|
9
|
+
expect(msg).toBeInTheDocument();
|
|
10
|
+
expect(msg).toHaveClass('font-size-sm');
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('supports different sizes', () => {
|
|
14
|
+
render(<InputValidationMessage size="md">Big</InputValidationMessage>);
|
|
15
|
+
const msg = screen.getByText('Big');
|
|
16
|
+
expect(msg).toHaveClass('font-size-md');
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Sidebar, SidebarProvider, SidebarTrigger } from './Sidebar';
|
|
4
|
+
|
|
5
|
+
jest.mock('../../hooks/useIsMobile/useIsMobile', () => ({
|
|
6
|
+
useIsMobile: () => false,
|
|
7
|
+
}));
|
|
8
|
+
|
|
9
|
+
describe('Sidebar', () => {
|
|
10
|
+
test('toggles open state with trigger', () => {
|
|
11
|
+
render(
|
|
12
|
+
<SidebarProvider>
|
|
13
|
+
<Sidebar data-testid="sidebar">
|
|
14
|
+
<div>Content</div>
|
|
15
|
+
</Sidebar>
|
|
16
|
+
<SidebarTrigger />
|
|
17
|
+
</SidebarProvider>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
const sidebar = document.querySelector('[data-state]') as HTMLElement;
|
|
21
|
+
expect(sidebar).toHaveAttribute('data-state', 'expanded');
|
|
22
|
+
|
|
23
|
+
fireEvent.click(screen.getByLabelText('toggle sidebar'));
|
|
24
|
+
expect(sidebar).toHaveAttribute('data-state', 'collapsed');
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { render } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { ThemeProvider, ThemeProviderContext } from './ThemeProvider';
|
|
4
|
+
|
|
5
|
+
beforeAll(() => {
|
|
6
|
+
Object.defineProperty(window, 'matchMedia', {
|
|
7
|
+
writable: true,
|
|
8
|
+
value: jest.fn().mockImplementation(() => ({
|
|
9
|
+
matches: false,
|
|
10
|
+
media: '',
|
|
11
|
+
onchange: null,
|
|
12
|
+
addListener: jest.fn(),
|
|
13
|
+
removeListener: jest.fn(),
|
|
14
|
+
addEventListener: jest.fn(),
|
|
15
|
+
removeEventListener: jest.fn(),
|
|
16
|
+
dispatchEvent: jest.fn(),
|
|
17
|
+
})),
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('ThemeProvider', () => {
|
|
22
|
+
test('applies default theme to document element', () => {
|
|
23
|
+
render(
|
|
24
|
+
<ThemeProvider defaultTheme="light">
|
|
25
|
+
<div />
|
|
26
|
+
</ThemeProvider>
|
|
27
|
+
);
|
|
28
|
+
expect(document.documentElement.classList.contains('light')).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('setTheme updates class and localStorage', () => {
|
|
32
|
+
const Consumer = () => {
|
|
33
|
+
const { setTheme } = React.useContext(ThemeProviderContext);
|
|
34
|
+
React.useEffect(() => {
|
|
35
|
+
setTheme('dark');
|
|
36
|
+
}, [setTheme]);
|
|
37
|
+
return null;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
render(
|
|
41
|
+
<ThemeProvider defaultTheme="light">
|
|
42
|
+
<Consumer />
|
|
43
|
+
</ThemeProvider>
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
expect(document.documentElement.classList.contains('dark')).toBe(true);
|
|
47
|
+
expect(localStorage.getItem('hyphen-ui-theme')).toBe('dark');
|
|
48
|
+
});
|
|
49
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Toggle } from './Toggle';
|
|
4
|
+
|
|
5
|
+
describe('Toggle', () => {
|
|
6
|
+
test('changes state when clicked', () => {
|
|
7
|
+
render(<Toggle>Bold</Toggle>);
|
|
8
|
+
const button = screen.getByRole('button');
|
|
9
|
+
expect(button).toHaveAttribute('data-state', 'off');
|
|
10
|
+
fireEvent.click(button);
|
|
11
|
+
expect(button).toHaveAttribute('data-state', 'on');
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { ToggleGroup, ToggleGroupItem } from './ToggleGroup';
|
|
4
|
+
|
|
5
|
+
describe('ToggleGroup', () => {
|
|
6
|
+
test('handles selection and displays error message', () => {
|
|
7
|
+
render(
|
|
8
|
+
<ToggleGroup type="single" variant="outline" error="Error">
|
|
9
|
+
<ToggleGroupItem value="a">A</ToggleGroupItem>
|
|
10
|
+
</ToggleGroup>
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
const item = screen.getByText('A');
|
|
14
|
+
expect(item).toHaveClass('outline');
|
|
15
|
+
fireEvent.click(item);
|
|
16
|
+
expect(item).toHaveAttribute('data-state', 'on');
|
|
17
|
+
expect(screen.getByText('Error')).toBeInTheDocument();
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { render, screen } from '@testing-library/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import {
|
|
4
|
+
Tooltip,
|
|
5
|
+
TooltipTrigger,
|
|
6
|
+
TooltipContent,
|
|
7
|
+
TooltipProvider,
|
|
8
|
+
} from './Tooltip';
|
|
9
|
+
|
|
10
|
+
describe('Tooltip', () => {
|
|
11
|
+
test('renders content when open', () => {
|
|
12
|
+
render(
|
|
13
|
+
<TooltipProvider>
|
|
14
|
+
<Tooltip open>
|
|
15
|
+
<TooltipTrigger>Hover me</TooltipTrigger>
|
|
16
|
+
<TooltipContent>Tip content</TooltipContent>
|
|
17
|
+
</Tooltip>
|
|
18
|
+
</TooltipProvider>
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
const contents = screen.getAllByText('Tip content');
|
|
22
|
+
expect(contents.length).toBeGreaterThan(0);
|
|
23
|
+
});
|
|
24
|
+
});
|