@hyphen/hyphen-components 6.2.2 → 6.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyphen/hyphen-components",
3
- "version": "6.2.2",
3
+ "version": "6.3.0",
4
4
  "license": "MIT",
5
5
  "author": {
6
6
  "name": "@hyphen"
@@ -245,6 +245,38 @@
245
245
  }
246
246
  }
247
247
 
248
+ &.link {
249
+ display: inline-flex;
250
+ background-color: transparent;
251
+ border: none;
252
+ color: inherit;
253
+ padding: 0;
254
+ text-decoration: none;
255
+ font-size: inherit;
256
+ height: auto;
257
+
258
+ &:not(:disabled):hover {
259
+ text-decoration: underline;
260
+ text-underline-offset: var(--size-spacing-xs);
261
+ }
262
+
263
+ &:focus {
264
+ outline: 0;
265
+ box-shadow: var(--button-box-shadow-focus);
266
+ }
267
+
268
+ // Show focus styles on keyboard focus.
269
+ &:focus-visible {
270
+ outline: 0;
271
+ box-shadow: var(--button-box-shadow-focus);
272
+ }
273
+
274
+ &:focus:not(:focus-visible) {
275
+ outline: 0;
276
+ box-shadow: none;
277
+ }
278
+ }
279
+
248
280
  &.size-sm {
249
281
  @extend %size-sm;
250
282
  }
@@ -32,13 +32,18 @@ export const AsChild = () => (
32
32
  );
33
33
 
34
34
  export const Variants = () => (
35
- <Box gap="md" style={{ backgroundColor: 'var(--background-primary)' }}>
36
- <Box gap="sm" direction="row" alignItems="flex-start">
37
- <Button variant="primary">Primary</Button>
38
- <Button variant="secondary">Secondary</Button>
39
- <Button variant="tertiary">Tertiary</Button>
40
- <Button variant="danger">Danger</Button>
41
- </Box>
35
+ <Box
36
+ gap="md"
37
+ background="primary"
38
+ direction="row"
39
+ alignItems="center"
40
+ fontSize="sm"
41
+ >
42
+ <Button variant="primary">Primary</Button>
43
+ <Button variant="secondary">Secondary</Button>
44
+ <Button variant="tertiary">Tertiary</Button>
45
+ <Button variant="danger">Danger</Button>
46
+ <Button variant="link">Link</Button>
42
47
  </Box>
43
48
  );
44
49
 
@@ -85,15 +90,16 @@ export const Icons = () => (
85
90
  );
86
91
 
87
92
  export const IconButton = () => (
88
- <>
93
+ <Box gap="lg" direction="row" alignItems="center">
89
94
  <Button variant="tertiary" iconPrefix="add" aria-label="add" />
90
95
  <Button variant="tertiary" iconPrefix="dots" aria-label="open menu" />
91
96
  <Button variant="danger" iconPrefix="trash" aria-label="remove" />
92
- </>
97
+ <Button variant="link" iconPrefix="chat" aria-label="chat" />
98
+ </Box>
93
99
  );
94
100
 
95
101
  export const Loading = () => (
96
- <Box direction="row" gap="md">
102
+ <Box direction="row" gap="md" fontSize="sm">
97
103
  <Button isLoading aria-label="primary loading">
98
104
  Primary Loading
99
105
  </Button>
@@ -103,11 +109,14 @@ export const Loading = () => (
103
109
  <Button variant="tertiary" isLoading aria-label="tertiary loading">
104
110
  Tertiary Loading
105
111
  </Button>
112
+ <Button variant="link" isLoading aria-label="link loading">
113
+ Link Loading
114
+ </Button>
106
115
  </Box>
107
116
  );
108
117
 
109
118
  export const Disabled = () => (
110
- <Box direction="row" gap="md">
119
+ <Box direction="row" gap="md" fontSize="sm">
111
120
  <Button variant="primary" isDisabled>
112
121
  Primary Disabled
113
122
  </Button>
@@ -117,6 +126,9 @@ export const Disabled = () => (
117
126
  <Button variant="tertiary" isDisabled>
118
127
  Tertiary Disabled
119
128
  </Button>
129
+ <Button variant="link" isDisabled>
130
+ Link Disabled
131
+ </Button>
120
132
  </Box>
121
133
  );
122
134
 
@@ -133,3 +145,13 @@ export const Shadow = () => (
133
145
  </Button>
134
146
  </Box>
135
147
  );
148
+
149
+ export const InlineLink = () => (
150
+ <Box display="block" as="p" fontSize="sm" color="base" width="8xl">
151
+ This is an example of a button used as an inline link.{' '}
152
+ <Button variant="link" size="md">
153
+ Inline Link Button
154
+ </Button>
155
+ . It will wrap with text.
156
+ </Box>
157
+ );
@@ -8,7 +8,12 @@ import classNames from 'classnames';
8
8
  import { generateResponsiveClasses } from '../../lib/generateResponsiveClasses';
9
9
  import styles from './Button.module.scss';
10
10
 
11
- export type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'danger';
11
+ export type ButtonVariant =
12
+ | 'primary'
13
+ | 'secondary'
14
+ | 'tertiary'
15
+ | 'danger'
16
+ | 'link';
12
17
 
13
18
  export type ButtonSize = 'sm' | 'md' | 'lg';
14
19
 
@@ -87,9 +92,12 @@ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
87
92
  ) => {
88
93
  const disabled = isLoading || isDisabled;
89
94
 
90
- const responsiveClasses = generateResponsiveClasses('size', size)
91
- .map((c) => styles[c])
92
- .filter(Boolean);
95
+ const responsiveClasses =
96
+ variant !== 'link'
97
+ ? generateResponsiveClasses('size', size)
98
+ .map((c) => styles[c])
99
+ .filter(Boolean)
100
+ : [];
93
101
 
94
102
  const buttonClasses = classNames(
95
103
  'hyphen-components__variables__form-control',
@@ -68,3 +68,21 @@ describe('Responsive hooks', () => {
68
68
  ).toEqual(1);
69
69
  });
70
70
  });
71
+
72
+ describe('Cleanup', () => {
73
+ it('clears pending resize timeout on unmount', () => {
74
+ jest.useFakeTimers();
75
+ const clearSpy = jest.spyOn(window, 'clearTimeout');
76
+ const { unmount } = render(
77
+ <ResponsiveProvider throttle={100}>
78
+ <div />
79
+ </ResponsiveProvider>
80
+ );
81
+ window.dispatchEvent(new Event('resize'));
82
+ expect(clearSpy).toHaveBeenCalledTimes(1);
83
+ unmount();
84
+ expect(clearSpy).toHaveBeenCalledTimes(2);
85
+ clearSpy.mockRestore();
86
+ jest.useRealTimers();
87
+ });
88
+ });
@@ -53,7 +53,10 @@ export const ResponsiveProvider: React.FC<ResponsiveProviderProps> = ({
53
53
 
54
54
  window.addEventListener('resize', throttledResize);
55
55
 
56
- return () => window.removeEventListener('resize', throttledResize);
56
+ return () => {
57
+ window.removeEventListener('resize', throttledResize);
58
+ clearTimeout(timeoutId);
59
+ };
57
60
  }
58
61
  }, [throttle]);
59
62