@instructure/ui-link 11.6.0 → 11.6.1-snapshot-129

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.
Files changed (56) hide show
  1. package/CHANGELOG.md +40 -288
  2. package/es/Link/{index.js → v1/index.js} +2 -2
  3. package/es/Link/v2/index.js +253 -0
  4. package/es/Link/v2/props.js +26 -0
  5. package/es/Link/v2/styles.js +242 -0
  6. package/es/{index.js → exports/a.js} +1 -1
  7. package/{src/index.ts → es/exports/b.js} +1 -3
  8. package/lib/Link/{index.js → v1/index.js} +3 -3
  9. package/lib/Link/v2/index.js +262 -0
  10. package/lib/Link/v2/props.js +31 -0
  11. package/lib/Link/v2/styles.js +248 -0
  12. package/lib/{index.js → exports/a.js} +2 -2
  13. package/lib/exports/b.js +12 -0
  14. package/package.json +43 -21
  15. package/src/Link/{index.tsx → v1/index.tsx} +3 -3
  16. package/src/Link/{props.ts → v1/props.ts} +1 -1
  17. package/src/Link/v2/README.md +261 -0
  18. package/src/Link/v2/index.tsx +321 -0
  19. package/src/Link/v2/props.ts +184 -0
  20. package/src/Link/v2/styles.ts +267 -0
  21. package/src/exports/a.ts +26 -0
  22. package/src/exports/b.ts +26 -0
  23. package/tsconfig.build.tsbuildinfo +1 -1
  24. package/types/Link/{index.d.ts → v1/index.d.ts} +1 -1
  25. package/types/Link/v1/index.d.ts.map +1 -0
  26. package/types/Link/{props.d.ts → v1/props.d.ts} +1 -1
  27. package/types/Link/v1/props.d.ts.map +1 -0
  28. package/types/Link/v1/styles.d.ts.map +1 -0
  29. package/types/Link/v1/theme.d.ts.map +1 -0
  30. package/types/Link/v2/index.d.ts +66 -0
  31. package/types/Link/v2/index.d.ts.map +1 -0
  32. package/types/Link/v2/props.d.ts +105 -0
  33. package/types/Link/v2/props.d.ts.map +1 -0
  34. package/types/Link/v2/styles.d.ts +19 -0
  35. package/types/Link/v2/styles.d.ts.map +1 -0
  36. package/types/exports/a.d.ts +3 -0
  37. package/types/exports/a.d.ts.map +1 -0
  38. package/types/exports/b.d.ts +3 -0
  39. package/types/exports/b.d.ts.map +1 -0
  40. package/types/Link/index.d.ts.map +0 -1
  41. package/types/Link/props.d.ts.map +0 -1
  42. package/types/Link/styles.d.ts.map +0 -1
  43. package/types/Link/theme.d.ts.map +0 -1
  44. package/types/index.d.ts +0 -3
  45. package/types/index.d.ts.map +0 -1
  46. /package/es/Link/{props.js → v1/props.js} +0 -0
  47. /package/es/Link/{styles.js → v1/styles.js} +0 -0
  48. /package/es/Link/{theme.js → v1/theme.js} +0 -0
  49. /package/lib/Link/{props.js → v1/props.js} +0 -0
  50. /package/lib/Link/{styles.js → v1/styles.js} +0 -0
  51. /package/lib/Link/{theme.js → v1/theme.js} +0 -0
  52. /package/src/Link/{README.md → v1/README.md} +0 -0
  53. /package/src/Link/{styles.ts → v1/styles.ts} +0 -0
  54. /package/src/Link/{theme.ts → v1/theme.ts} +0 -0
  55. /package/types/Link/{styles.d.ts → v1/styles.d.ts} +0 -0
  56. /package/types/Link/{theme.d.ts → v1/theme.d.ts} +0 -0
@@ -24,7 +24,7 @@
24
24
 
25
25
  import { Children, Component } from 'react'
26
26
 
27
- import { View } from '@instructure/ui-view'
27
+ import { View } from '@instructure/ui-view/v11_6'
28
28
  import { hasVisibleChildren } from '@instructure/ui-a11y-utils'
29
29
  import { isActiveElement, findFocusable } from '@instructure/ui-dom-utils'
30
30
  import {
@@ -37,14 +37,14 @@ import {
37
37
  import { combineDataCid } from '@instructure/ui-utils'
38
38
  import { logWarn as warn } from '@instructure/console'
39
39
 
40
- import { withStyle } from '@instructure/emotion'
40
+ import { withStyleLegacy as withStyle } from '@instructure/emotion'
41
41
  import generateStyle from './styles'
42
42
  import generateComponentTheme from './theme'
43
43
 
44
44
  import { allowedProps } from './props'
45
45
  import type { LinkProps, LinkState, LinkStyleProps } from './props'
46
46
 
47
- import type { ViewOwnProps } from '@instructure/ui-view'
47
+ import type { ViewOwnProps } from '@instructure/ui-view/v11_6'
48
48
 
49
49
  /**
50
50
  ---
@@ -34,7 +34,7 @@ import type {
34
34
  WithStyleProps,
35
35
  ComponentStyle
36
36
  } from '@instructure/emotion'
37
- import type { ViewOwnProps } from '@instructure/ui-view'
37
+ import type { ViewOwnProps } from '@instructure/ui-view/v11_6'
38
38
  import { Renderable } from '@instructure/shared-types'
39
39
 
40
40
  type LinkOwnProps = {
@@ -0,0 +1,261 @@
1
+ ---
2
+ describes: Link
3
+ ---
4
+
5
+ ### Where to use Link
6
+
7
+ `Link` is intended for presenting actions **inline with other content**, such as within headings or sentences. Typically those actions navigate the user to a different view.
8
+
9
+ ```js
10
+ ---
11
+ type: example
12
+ ---
13
+ <Link href="https://instructure.github.io/instructure-ui/" target="_blank">
14
+ Link text
15
+ </Link>
16
+ ```
17
+
18
+ ### Controlled navigation
19
+
20
+ Sometimes a simple `Link (<a>)` with an `href` is not enough for navigation and an `onClick` handler is needed. In this case, the recommended approach is the following
21
+
22
+ ```js
23
+ ---
24
+ type: example
25
+ ---
26
+ <Link
27
+ variant="standalone"
28
+ onClick = {(e)=>{
29
+ e.preventDefault()
30
+ console.log("do navigation")
31
+ }}
32
+ forceButtonRole={false}
33
+ href="#">Go to places
34
+ </Link>
35
+ ```
36
+
37
+ If neither `href` nor `onClick` is provided, the Link will render as plain text (a `<span>` element) without interactive styling:
38
+
39
+ ```js
40
+ ---
41
+ type: example
42
+ ---
43
+ <div>
44
+ <Text>This is a Link with no href or onClick: <Link>I look like plain text</Link></Text>
45
+ </div>
46
+ ```
47
+
48
+ ### Size
49
+
50
+ The `size` prop controls the font size, line height, and icon size, icon gap. Available sizes are `small`, `medium`, and `large`.
51
+
52
+ ```js
53
+ ---
54
+ type: example
55
+ ---
56
+ <div>
57
+ <div>
58
+ <Link renderIcon={<DiamondInstUIIcon />} variant="standalone" href="https://instructure.github.io/instructure-ui/" size="small">
59
+ Link small
60
+ </Link>
61
+ </div>
62
+ <br />
63
+ <div>
64
+ <Link renderIcon={<DiamondInstUIIcon />} variant="standalone" href="https://instructure.github.io/instructure-ui/" size="medium">
65
+ Link medium
66
+ </Link>
67
+ </div>
68
+ <br />
69
+ <div>
70
+ <Link renderIcon={<DiamondInstUIIcon />} variant="standalone" href="https://instructure.github.io/instructure-ui/" size="large">
71
+ Link large
72
+ </Link>
73
+ </div>
74
+ <br />
75
+ </div>
76
+ ```
77
+
78
+ ### Variant
79
+
80
+ The `variant` prop controls the text decoration and intended use case. Available variants are `inline` (underlined, for use within text) and `standalone` (no underline, for standalone links).
81
+
82
+ Use the `variant` prop in combination with the `size` prop to control both the appearance and size of the link.
83
+
84
+ ```js
85
+ ---
86
+ type: example
87
+ ---
88
+ <div>
89
+ <div>
90
+ In a line of text you should use the <Link variant="inline" size="medium" renderIcon={<DiamondInstUIIcon />} href="https://instructure.github.io/instructure-ui/">inline</Link> link variant.
91
+ </div>
92
+ <br />
93
+ <div>
94
+ If the link is standalone (not in a text), use the <code>standalone</code> variant:
95
+ <Link variant="standalone" size="medium" renderIcon={<DiamondInstUIIcon />} href="https://instructure.github.io/instructure-ui/">standalone</Link>
96
+ </div>
97
+ </div>
98
+ ```
99
+
100
+ #### Deprecated variant values
101
+
102
+ **The following variant values are deprecated and will be removed in a future version:**
103
+
104
+ - `inline-small`
105
+ - `standalone-small`
106
+
107
+ These deprecated values are still supported for backward compatibility but will trigger console warnings. Please update your code to use the new `variant` + `size` prop combination.
108
+
109
+ ```js
110
+ ---
111
+ type: code
112
+ ---
113
+ // Deprecated (still works but triggers warning)
114
+ <Link variant="inline-small" href="#">Link</Link>
115
+ <Link variant="standalone-small" href="#">Link</Link>
116
+
117
+ // Recommended
118
+ <Link variant="inline" size="small" href="#">Link</Link>
119
+ <Link variant="standalone" size="small" href="#">Link</Link>
120
+ ```
121
+
122
+ ### Adding margin
123
+
124
+ Use the `margin` prop to add space to the left or right of the Link. Because
125
+ Link displays `inline`, **top and bottom margin will not work**. If you need
126
+ to add margin to the top or bottom of Link, wrap it inside a `<View />`.
127
+
128
+ ```js
129
+ ---
130
+ type: example
131
+ ---
132
+ <Text>The quick brown fox <Link href="https://instructure.github.io/instructure-ui/" margin="0 small">jumps</Link> over the lazy dog.</Text>
133
+ ```
134
+
135
+ ### Truncating text
136
+
137
+ Use [TruncateText](TruncateText) to truncate text within Link. Note this will cause Link to display `inline-flex`,
138
+ unless an alternate `display` prop is provided.
139
+
140
+ ```js
141
+ ---
142
+ type: example
143
+ ---
144
+ <Link
145
+ onClick={() => console.log('clicked')}
146
+ renderIcon={<DiamondInstUIIcon />}
147
+ >
148
+ <TruncateText>{lorem.paragraph()}</TruncateText>
149
+ </Link>
150
+ ```
151
+
152
+ ### Using icons
153
+
154
+ Use the `renderIcon` property to put an [icon](icons) inside a Link. To position the
155
+ icon _after_ the link text, change the `iconPlacement` property to `end`. You can also
156
+ render a Link with just an icon. Don't forget to add text for screen readers, though.
157
+
158
+ ```js
159
+ ---
160
+ type: example
161
+ ---
162
+ <div>
163
+ <View as="div" margin="0 0 small">
164
+ <Link href="https://instructure.design" renderIcon={<DiamondInstUIIcon />}>Icon before text</Link> with the quick brown fox
165
+ </View>
166
+ <View as="div" margin="0 0 small">
167
+ This Link has an icon and displays inline with text. <Link
168
+ href="https://instructure.design"
169
+ renderIcon={<DiamondInstUIIcon />}
170
+ iconPlacement="end"
171
+ >
172
+ Icon appears after Link text
173
+ </Link>. This is more text after the link.
174
+ </View>
175
+ <View as="div">
176
+ This Link consists of only an icon&nbsp;
177
+ <Link onClick={() => console.log('clicked!')} renderIcon={<DiamondInstUIIcon />}>
178
+ <ScreenReaderContent>Descriptive text</ScreenReaderContent>
179
+ </Link>.
180
+ </View>
181
+ </div>
182
+ ```
183
+
184
+ ### Theme overrides
185
+
186
+ Examples showing how [theme overrides](using-theme-overrides) work for Link:
187
+
188
+ ```js
189
+ ---
190
+ type: example
191
+ ---
192
+ <div>
193
+ <InstUISettingsProvider
194
+ theme={{
195
+ newTheme: {
196
+ sharedTokens: {
197
+ focusOutline: {
198
+ infoColor: 'pink',
199
+ width: '0.5rem',
200
+ }
201
+ }
202
+ }
203
+ }}
204
+ >
205
+ <Text>The quick brown fox <Link
206
+ href="https://instructure.github.io/instructure-ui/"
207
+ themeOverride={{
208
+ textColor: 'red',
209
+ textHoverColor: 'green',
210
+ fontWeight: 700
211
+ }}>jumps</Link> over the lazy dog.
212
+ </Text>
213
+ </InstUISettingsProvider>
214
+ </div>
215
+ ```
216
+
217
+ ```js
218
+ ---
219
+ type: example
220
+ ---
221
+ <View background="primary-inverse" as="div">
222
+ <Text color="primary-inverse">The quick brown fox <Link
223
+ href="https://instructure.github.io/instructure-ui/"
224
+ color="link"
225
+ themeOverride={{
226
+ textColor: 'red',
227
+ textHoverColor: 'magenta',
228
+ onColorTextColor: 'orange',
229
+ onColorTextHoverColor: 'lime',
230
+ fontWeight: 700
231
+ }}
232
+ >jumps</Link> over the lazy dog.</Text>
233
+ <br />
234
+ <Text color="primary-inverse">The quick brown fox <Link
235
+ href="https://instructure.github.io/instructure-ui/"
236
+ renderIcon={<LogOutInstUIIcon />}
237
+ color="link-inverse"
238
+ themeOverride={{
239
+ textColor: 'red',
240
+ textHoverColor: 'magenta',
241
+ onColorTextColor: 'orange',
242
+ onColorTextHoverColor: 'lime',
243
+ fontWeight: 700
244
+ }}
245
+ >jumps</Link> over the lazy dog.</Text>
246
+ </View>
247
+ ```
248
+
249
+ ### Guidelines
250
+
251
+ ```js
252
+ ---
253
+ type: embed
254
+ ---
255
+ <Guidelines>
256
+ <Figure recommendation="a11y" title="Accessibility">
257
+ <Figure.Item>Use <code>color="link-inverse"</code> when a Link appears on a dark background to ensure adequate contrast</Figure.Item>
258
+ <Figure.Item>Links must have a non-empty href attribute to be considered true links and to be accessible to keyboard users</Figure.Item>
259
+ </Figure>
260
+ </Guidelines>
261
+ ```
@@ -0,0 +1,321 @@
1
+ /*
2
+ * The MIT License (MIT)
3
+ *
4
+ * Copyright (c) 2015 - present Instructure, Inc.
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in all
14
+ * copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ * SOFTWARE.
23
+ */
24
+
25
+ import { Children, Component } from 'react'
26
+
27
+ import { View } from '@instructure/ui-view/latest'
28
+ import { hasVisibleChildren } from '@instructure/ui-a11y-utils'
29
+ import { isActiveElement, findFocusable } from '@instructure/ui-dom-utils'
30
+ import {
31
+ getElementType,
32
+ getInteraction,
33
+ matchComponentTypes,
34
+ passthroughProps
35
+ } from '@instructure/ui-react-utils'
36
+ import { combineDataCid } from '@instructure/ui-utils'
37
+ import { logWarn as warn } from '@instructure/console'
38
+ import { renderIconWithProps } from '@instructure/ui-icons'
39
+
40
+ import { withStyle } from '@instructure/emotion'
41
+ import generateStyle from './styles'
42
+
43
+ import { allowedProps } from './props'
44
+ import type { LinkProps, LinkState, LinkStyleProps } from './props'
45
+
46
+ import type { ViewOwnProps } from '@instructure/ui-view/latest'
47
+
48
+ /**
49
+ ---
50
+ category: components
51
+ ---
52
+ **/
53
+ @withStyle(generateStyle)
54
+ class Link extends Component<LinkProps, LinkState> {
55
+ static readonly componentId = 'Link'
56
+
57
+ static allowedProps = allowedProps
58
+ static defaultProps = {
59
+ // Leave interaction default undefined so that `disabled` can also be supplied
60
+ interaction: undefined,
61
+ color: 'link',
62
+ iconPlacement: 'start',
63
+ forceButtonRole: true
64
+ } as const
65
+
66
+ state = { hasFocus: false }
67
+
68
+ get _link() {
69
+ console.warn(
70
+ '_link property is deprecated and will be removed in v9, please use ref instead'
71
+ )
72
+
73
+ return this.ref
74
+ }
75
+ ref: Element | null = null
76
+
77
+ componentDidMount() {
78
+ this.props.makeStyles?.(this.makeStyleProps())
79
+ }
80
+
81
+ componentDidUpdate() {
82
+ this.props.makeStyles?.(this.makeStyleProps())
83
+ }
84
+
85
+ makeStyleProps = (): LinkStyleProps & {
86
+ variant?: LinkProps['variant']
87
+ size?: LinkProps['size']
88
+ } => {
89
+ const { variant: variantProp, size: sizeProp } = this.props
90
+
91
+ // Handle deprecated variant values by mapping them to new variant + size props
92
+ let variant: 'inline' | 'standalone' | undefined = variantProp as any
93
+ let size = sizeProp
94
+
95
+ if (variantProp === 'inline-small' || variantProp === 'standalone-small') {
96
+ warn(
97
+ false,
98
+ `[Link] The variant value "${variantProp}" is deprecated. Use variant="${variantProp.replace(
99
+ '-small',
100
+ ''
101
+ )}" with size="small" instead.`
102
+ )
103
+ variant = variantProp.replace('-small', '') as 'inline' | 'standalone'
104
+ // Only set size from deprecated variant if size prop is not explicitly provided
105
+ if (!sizeProp) {
106
+ size = 'small'
107
+ }
108
+ } else if (
109
+ (variantProp === 'inline' || variantProp === 'standalone') &&
110
+ !sizeProp
111
+ ) {
112
+ // When using new variant values without explicit size, default to medium
113
+ // This maintains the old behavior where 'inline' and 'standalone' were medium-sized
114
+ size = 'medium'
115
+ }
116
+
117
+ return {
118
+ containsTruncateText: this.containsTruncateText,
119
+ hasVisibleChildren: this.hasVisibleChildren,
120
+ variant,
121
+ size
122
+ }
123
+ }
124
+
125
+ handleElementRef = (el: Element | null) => {
126
+ const { elementRef } = this.props
127
+
128
+ this.ref = el
129
+
130
+ if (typeof elementRef === 'function') {
131
+ elementRef(el)
132
+ }
133
+ }
134
+
135
+ handleClick: React.MouseEventHandler<ViewOwnProps> = (event) => {
136
+ const { onClick } = this.props
137
+ const { interaction } = this
138
+
139
+ if (interaction === 'disabled') {
140
+ event.preventDefault()
141
+ event.stopPropagation()
142
+ } else if (typeof onClick === 'function') {
143
+ onClick(event)
144
+ }
145
+ }
146
+
147
+ handleFocus: React.FocusEventHandler<ViewOwnProps> = (event) => {
148
+ this.setState({ hasFocus: true })
149
+ if (typeof this.props.onFocus === 'function') {
150
+ this.props.onFocus(event)
151
+ }
152
+ }
153
+
154
+ handleBlur: React.FocusEventHandler<ViewOwnProps> = (event) => {
155
+ this.setState({ hasFocus: false })
156
+ if (typeof this.props.onBlur === 'function') {
157
+ this.props.onBlur(event)
158
+ }
159
+ }
160
+
161
+ get containsTruncateText() {
162
+ let truncateText = false
163
+
164
+ Children.forEach(this.props.children, (child) => {
165
+ if (child && matchComponentTypes(child, ['TruncateText'])) {
166
+ truncateText = true
167
+ }
168
+ })
169
+
170
+ warn(
171
+ // if display prop is used, warn about icon or TruncateText
172
+ !truncateText || this.props.display === undefined,
173
+ '[Link] Using the display property with TruncateText may cause layout issues.'
174
+ )
175
+
176
+ return truncateText
177
+ }
178
+
179
+ get display() {
180
+ if (this.props.display) {
181
+ return this.props.display // user-entered display property
182
+ }
183
+
184
+ const { containsTruncateText } = this
185
+
186
+ if (this.props.renderIcon) {
187
+ return containsTruncateText ? 'inline-flex' : 'inline-block'
188
+ } else {
189
+ return containsTruncateText ? 'block' : 'auto'
190
+ }
191
+ }
192
+
193
+ get interaction() {
194
+ return getInteraction({ props: this.props, interactionTypes: ['disabled'] })
195
+ }
196
+
197
+ get element() {
198
+ return getElementType(Link, this.props)
199
+ }
200
+
201
+ get focused() {
202
+ return isActiveElement(this.ref)
203
+ }
204
+
205
+ get focusable() {
206
+ return findFocusable(this.ref)
207
+ }
208
+
209
+ get hasVisibleChildren() {
210
+ return hasVisibleChildren(this.props.children)
211
+ }
212
+
213
+ get role() {
214
+ const { role, forceButtonRole, onClick } = this.props
215
+
216
+ if (forceButtonRole) {
217
+ return onClick && this.element !== 'button' ? 'button' : role
218
+ }
219
+
220
+ return role
221
+ }
222
+
223
+ focus() {
224
+ this.ref && (this.ref as HTMLElement).focus()
225
+ }
226
+
227
+ renderIcon() {
228
+ const {
229
+ display,
230
+ renderIcon,
231
+ variant: variantProp,
232
+ size: sizeProp
233
+ } = this.props
234
+
235
+ warn(
236
+ // if display prop is used, warn about icon or TruncateText
237
+ display === undefined,
238
+ '[Link] Using the display property with an icon may cause layout issues.'
239
+ )
240
+
241
+ // Determine the actual size being used (considering deprecated variants)
242
+ let size = sizeProp
243
+ if (variantProp === 'inline-small' || variantProp === 'standalone-small') {
244
+ size = sizeProp || 'small'
245
+ } else if (
246
+ (variantProp === 'inline' || variantProp === 'standalone') &&
247
+ !sizeProp
248
+ ) {
249
+ size = 'medium'
250
+ }
251
+
252
+ // Map Link sizes to icon sizes
253
+ const linkSizeToIconSize = {
254
+ small: 'xs',
255
+ medium: 'sm',
256
+ large: 'lg'
257
+ } as const
258
+
259
+ const iconSize =
260
+ linkSizeToIconSize[(size || 'medium') as keyof typeof linkSizeToIconSize]
261
+
262
+ return (
263
+ <span css={this.props.styles?.icon}>
264
+ {renderIconWithProps(renderIcon, iconSize, undefined)}
265
+ </span>
266
+ )
267
+ }
268
+
269
+ render() {
270
+ const {
271
+ children,
272
+ onClick,
273
+ onMouseEnter,
274
+ color,
275
+ href,
276
+ margin,
277
+ renderIcon,
278
+ iconPlacement,
279
+ ...props
280
+ } = this.props
281
+
282
+ const { interaction } = this
283
+
284
+ const isDisabled = interaction === 'disabled'
285
+
286
+ const type =
287
+ this.element === 'button' || this.element === 'input'
288
+ ? 'button'
289
+ : undefined
290
+
291
+ const tabIndex = this.role === 'button' && !isDisabled ? 0 : undefined
292
+
293
+ return (
294
+ <View
295
+ {...passthroughProps(props)}
296
+ elementRef={this.handleElementRef}
297
+ as={this.element}
298
+ display={this.display}
299
+ margin={margin}
300
+ href={href}
301
+ onMouseEnter={onMouseEnter}
302
+ onClick={this.handleClick}
303
+ onFocus={this.handleFocus}
304
+ onBlur={this.handleBlur}
305
+ aria-disabled={isDisabled ? 'true' : undefined}
306
+ role={this.role}
307
+ type={type}
308
+ tabIndex={tabIndex}
309
+ css={this.props.styles?.link}
310
+ data-cid={combineDataCid('Link', this.props)}
311
+ >
312
+ {renderIcon && iconPlacement === 'start' ? this.renderIcon() : null}
313
+ {children}
314
+ {renderIcon && iconPlacement === 'end' ? this.renderIcon() : null}
315
+ </View>
316
+ )
317
+ }
318
+ }
319
+
320
+ export default Link
321
+ export { Link }