@kaizen/components 1.72.0 → 1.73.1

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 (40) hide show
  1. package/bin/codemod.sh +2 -0
  2. package/codemods/README.md +46 -0
  3. package/codemods/upgradeV1Buttons/index.ts +19 -0
  4. package/codemods/upgradeV1Buttons/transformV1ButtonAttributes.spec.ts +202 -0
  5. package/codemods/upgradeV1Buttons/transformV1ButtonAttributes.ts +146 -0
  6. package/codemods/upgradeV1Buttons/upgradeV1Buttons.spec.ts +658 -0
  7. package/codemods/upgradeV1Buttons/upgradeV1Buttons.ts +93 -0
  8. package/codemods/utils/createJsxElementWithChildren.spec.ts +119 -0
  9. package/codemods/utils/createJsxElementWithChildren.ts +55 -0
  10. package/codemods/utils/createProp.spec.ts +75 -19
  11. package/codemods/utils/createProp.ts +8 -1
  12. package/codemods/utils/getKaioTagName.ts +13 -5
  13. package/codemods/utils/index.ts +1 -0
  14. package/dist/cjs/Link/Link.cjs +45 -0
  15. package/dist/cjs/Link/Link.module.css.cjs +20 -0
  16. package/dist/cjs/Link/subcomponents/LinkContent.cjs +34 -0
  17. package/dist/cjs/index.cjs +2 -0
  18. package/dist/cjs/utilitiesV3.cjs +2 -0
  19. package/dist/esm/Link/Link.mjs +40 -0
  20. package/dist/esm/Link/Link.module.css.mjs +18 -0
  21. package/dist/esm/Link/subcomponents/LinkContent.mjs +26 -0
  22. package/dist/esm/index.mjs +1 -0
  23. package/dist/esm/utilitiesV3.mjs +1 -0
  24. package/dist/styles.css +120 -0
  25. package/dist/types/Link/Link.d.ts +39 -0
  26. package/dist/types/Link/index.d.ts +1 -0
  27. package/dist/types/Link/subcomponents/LinkContent.d.ts +8 -0
  28. package/dist/types/index.d.ts +1 -0
  29. package/package.json +3 -3
  30. package/src/Link/Link.module.css +119 -0
  31. package/src/Link/Link.tsx +90 -0
  32. package/src/Link/_docs/Link--api-specification.mdx +133 -0
  33. package/src/Link/_docs/Link--api-usage-guidelines.mdx +107 -0
  34. package/src/Link/_docs/Link.doc.stories.tsx +238 -0
  35. package/src/Link/_docs/Link.stickersheet.stories.tsx +191 -0
  36. package/src/Link/index.ts +1 -0
  37. package/src/Link/subcomponents/LinkContent.tsx +31 -0
  38. package/src/LinkButton/_docs/LinkButton--api-specification.mdx +1 -57
  39. package/src/__next__/Button/_docs/Button--migration-guide.mdx +81 -0
  40. package/src/index.ts +1 -0
@@ -0,0 +1,107 @@
1
+ import { Canvas, Meta, Controls } from '@storybook/blocks'
2
+ import {
3
+ ResourceLinks,
4
+ KAIOInstallation,
5
+ LinkTo,
6
+ DosAndDonts,
7
+ DoOrDont,
8
+ } from '~storybook/components'
9
+ import * as Link from './Link.doc.stories'
10
+
11
+ <Meta title="Components/Link/Usage Guidelines" />
12
+
13
+ # Link
14
+
15
+ Updated Jan 30, 2025
16
+
17
+ <ResourceLinks
18
+ sourceCode="https://github.com/cultureamp/kaizen-design-system/tree/main/packages/components/src/Link"
19
+ figma="https://www.figma.com/design/FWIOtGjpv9z0by95j1SgP0/Link?node-id=273-4107"
20
+ apiSpecification="/?path=/docs/components-link-api-specification--docs"
21
+ />
22
+
23
+ <KAIOInstallation exportNames={'Link'} />
24
+
25
+ ## Overview
26
+
27
+ `Link` allow users to navigate to a different location. They can be presented inside a paragraph or as standalone text.
28
+
29
+ <Canvas of={Link.Playground} />
30
+
31
+ <Controls
32
+ of={Link.Playground}
33
+ include={['href', 'variant', 'size', 'isDisabled', 'icon', 'iconPosition']}
34
+ className="mb-64"
35
+ />
36
+
37
+ ## When to use
38
+
39
+ - Navigating to a different page within the application
40
+ - Navigating to an entirely different site
41
+ - Jump to an element on the same page
42
+ - Link to emails or phone numbers
43
+
44
+ ## When not to use
45
+
46
+ - Do not use links for actions that will change data or manipulate how it is displayed, change a state, or trigger an action. Instead, use buttons to guide users to specific actions.
47
+
48
+ ### Use primary links to highlight
49
+
50
+ The primary link is the default and is blue. This should be used to call attention to the link and for when the blue color won’t feel too overwhelming in the experience.
51
+
52
+ ### Use secondary links to optimise readability
53
+
54
+ The secondary link is the same color as the paragraph text. Its subdued appearance is optimal for when the primary variant is too overwhelming, such as in blocks of text with several references linked throughout.
55
+
56
+ ### Use links in body copy
57
+
58
+ Put links in regular text, not in titles. If you need something bigger or more noticeable, try using a button instead.
59
+
60
+ ### Use a relative link size
61
+
62
+ The link component has four size variants, each aligning with body text sizes.
63
+
64
+ - **Inline Links**: Use the isInline prop to inherit the font size from the parent Text component.
65
+ - **Standalone Links**: Choose a size that maintains consistency with the surrounding text within the same component or pattern.
66
+
67
+ ### Give context to inline links
68
+
69
+ For links in a sentence, write them as part of the sentence and include enough information so people know what to expect. This approach can draw a user’s focus to the linked text. If the link leads to more content, it can be helpful to write it as a descriptive noun (e.g., “survey feedback”). If the link launches a task or action, start it with a verb (e.g., “Share your feedback”).
70
+
71
+ ### Specs
72
+
73
+ #### Write standalone links like calls-to-action
74
+
75
+ Standalone links are not full sentences, and do not have punctuation at the end. Treat these like calls-to-action by writing them as short verb phrases. Where possible, do not break over multiple lines.
76
+
77
+ <DosAndDonts>
78
+ <DoOrDont story={Link.StandaloneLinkDo} />
79
+ <DoOrDont story={Link.StandaloneLinkDont} isDont />
80
+ </DosAndDonts>
81
+
82
+ #### Ensure clarity by prioritizing the most valuable links
83
+
84
+ Think about how many links you use and where you put them. Don't overload your interface with too many links as clustering links can confuse people.
85
+
86
+ <DosAndDonts>
87
+ <DoOrDont story={Link.OneLinkInSentence} />
88
+ <DoOrDont story={Link.FiveLinksInSentence} isDont />
89
+ </DosAndDonts>
90
+
91
+ #### Use icons in links sparingly and consistently
92
+
93
+ Overusing icons can create visual clutter and overwhelm users. Use them sparingly to highlight common and recognisable navigation.
94
+
95
+ <DosAndDonts>
96
+ <DoOrDont story={Link.ExternalIconLink} />
97
+ <DoOrDont story={Link.RandomIconLink} isDont />
98
+ </DosAndDonts>
99
+
100
+ #### Links should make sense in isolation
101
+
102
+ If links on a page have the same label repeated multiple times, they should have distinct, accessible names that add context for users. This ensures [better accessibility for screen reader](https://cultureamp.atlassian.net/wiki/spaces/PA/pages/3240099910/Buttons+and+link+labels+make+sense+in+isolation) users, who rely on descriptive labels to distinguish between links.
103
+
104
+ <DosAndDonts>
105
+ <DoOrDont story={Link.DistinctNamedLink} />
106
+ <DoOrDont story={Link.GenericNamedLink} isDont />
107
+ </DosAndDonts>
@@ -0,0 +1,238 @@
1
+ import React from 'react'
2
+ import { type Meta, type StoryObj } from '@storybook/react'
3
+ import { Text } from '~components/Text'
4
+ import { Icon } from '~components/__next__/Icon'
5
+ import { Link } from '../Link'
6
+
7
+ const meta = {
8
+ title: 'Components/Link',
9
+ component: Link,
10
+ args: {
11
+ children: 'Link',
12
+ href: 'https://www.google.com',
13
+ },
14
+ argTypes: {
15
+ variant: {
16
+ options: ['primary', 'secondary', 'white'],
17
+ },
18
+ size: {
19
+ options: ['intro-lede', 'body', 'small', 'extra-small'],
20
+ },
21
+ icon: {
22
+ options: ['arrow_forward', 'open_in_new'],
23
+ mapping: {
24
+ // eslint-disable-next-line camelcase
25
+ arrow_forward: <Icon isPresentational name="arrow_forward" />,
26
+ // eslint-disable-next-line camelcase
27
+ open_in_new: <Icon isPresentational name="open_in_new" />,
28
+ },
29
+ description:
30
+ 'Renders an icon at the specified `iconPosition`. For size scaling, use the `Icon` component from `"@kaizen/components/future"`. See [all available icons](https://cultureamp.design/?path=/docs/components-icon-icon-future-api-specification--docs)',
31
+ },
32
+ },
33
+ } satisfies Meta<typeof Link>
34
+
35
+ export default meta
36
+
37
+ type Story = StoryObj<typeof meta>
38
+
39
+ export const Playground: Story = {
40
+ render: (props) =>
41
+ props.variant !== 'white' ? (
42
+ <Link {...props} />
43
+ ) : (
44
+ <div className="flex p-12 bg-purple-600">
45
+ {' '}
46
+ <Link {...props} />
47
+ </div>
48
+ ),
49
+ }
50
+
51
+ export const LinkVariants: Story = {
52
+ render: (props) => (
53
+ <>
54
+ <Link {...props} variant="primary" />
55
+ <br />
56
+ <Link {...props} variant="secondary" />
57
+ </>
58
+ ),
59
+ decorators: [
60
+ (Story) => (
61
+ <div className="flex gap-8">
62
+ <Story />
63
+ </div>
64
+ ),
65
+ ],
66
+ }
67
+
68
+ export const LinkVariantWhite: Story = {
69
+ render: (props) => <Link {...props} variant="white" />,
70
+ parameters: {
71
+ reverseColors: true,
72
+ },
73
+ }
74
+
75
+ export const LinkWithIconStart: Story = {
76
+ render: (props) => (
77
+ <Link {...props} icon={<Icon name="add" isPresentational />} iconPosition="start" />
78
+ ),
79
+ }
80
+
81
+ export const LinkWithIconEnd: Story = {
82
+ render: (props) => (
83
+ <Link {...props} icon={<Icon name="add" isPresentational />} iconPosition="end" />
84
+ ),
85
+ }
86
+
87
+ export const LinkOpensInNewTab: Story = {
88
+ render: (props) => (
89
+ <Link
90
+ {...props}
91
+ target="_blank"
92
+ icon={<Icon name="open_in_new" isPresentational />}
93
+ iconPosition="end"
94
+ />
95
+ ),
96
+ }
97
+
98
+ export const WithText: Story = {
99
+ render: ({ size: _, ...otherArgs }) => (
100
+ <>
101
+ <Text variant="intro-lede">
102
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae eaque amet atque. Dolores
103
+ repellendus eligendi <span style={{ textDecoration: 'underline' }}> totam.</span>{' '}
104
+ <Link {...otherArgs} icon={<Icon name="add" isPresentational />} isInline /> Mollitia vero
105
+ asperiores assumenda, odit ratione id perspiciatis suscipit molestias quas facere, commodi
106
+ saepe! Quisquam, quidem quas a quos quae quia quidem, quod, voluptates, dolorum quibusdam.
107
+ Quisquam, quidem quas a quos quae
108
+ </Text>
109
+ <br />
110
+ <Text variant="body">
111
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae eaque amet atque. Dolores
112
+ repellendus eligendi <span style={{ textDecoration: 'underline' }}> totam.</span>{' '}
113
+ <Link
114
+ {...otherArgs}
115
+ icon={<Icon name="add" isPresentational />}
116
+ isInline
117
+ size={undefined}
118
+ />
119
+ Mollitia vero asperiores assumenda, odit ratione id perspiciatis suscipit molestias quas
120
+ facere, commodi saepe! Quisquam, quidem quas a quos quae quia quidem, quod, voluptates,
121
+ dolorum quibusdam. Quisquam, quidem quas a quos quae
122
+ </Text>
123
+ <br />
124
+ <Text variant="small">
125
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae eaque amet atque. Dolores
126
+ repellendus eligendi <span style={{ textDecoration: 'underline' }}> totam.</span>{' '}
127
+ <Link {...otherArgs} icon={<Icon name="add" isPresentational />} isInline /> Mollitia vero
128
+ asperiores assumenda, odit ratione id perspiciatis suscipit molestias quas facere, commodi
129
+ saepe! Quisquam, quidem quas a quos quae quia quidem, quod, voluptates, dolorum quibusdam.
130
+ Quisquam, quidem quas a quos quae
131
+ </Text>
132
+ <br />
133
+ <Text variant="extra-small">
134
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Quae eaque amet atque. Dolores
135
+ repellendus eligendi <span style={{ textDecoration: 'underline' }}> totam.</span>{' '}
136
+ <Link {...otherArgs} icon={<Icon name="add" isPresentational />} isInline /> Mollitia vero
137
+ asperiores assumenda, odit ratione id perspiciatis suscipit molestias quas facere, commodi
138
+ saepe! Quisquam, quidem quas a quos quae quia quidem, quod, voluptates, dolorum quibusdam.
139
+ Quisquam, quidem quas a quos quae
140
+ </Text>
141
+ </>
142
+ ),
143
+ }
144
+
145
+ // Links of every different size
146
+ export const LinkSizes: Story = {
147
+ render: ({ children: _, size: __, isInline: ___, ...otherArgs }) => (
148
+ <>
149
+ <Link size="extra-small" {...otherArgs}>
150
+ Extra Small
151
+ </Link>
152
+ <br />
153
+ <Link {...otherArgs} size="small">
154
+ Small
155
+ </Link>
156
+ <br />
157
+ <Link {...otherArgs} size="body">
158
+ Body
159
+ </Link>
160
+ <br />
161
+ <Link {...otherArgs} size="intro-lede">
162
+ Intro Lede
163
+ </Link>
164
+ </>
165
+ ),
166
+ }
167
+
168
+ export const StandaloneLinkDo: Story = {
169
+ render: (props) => <Link {...props}>Learn more about demographics</Link>,
170
+ }
171
+
172
+ export const StandaloneLinkDont: Story = {
173
+ render: ({ size: _, ...otherArgs }) => (
174
+ <Text variant="body">
175
+ Learn more about{' '}
176
+ <Link {...otherArgs} isInline>
177
+ demographics
178
+ </Link>
179
+ </Text>
180
+ ),
181
+ }
182
+
183
+ export const OneLinkInSentence: Story = {
184
+ render: (props) => (
185
+ <Text variant="body">
186
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Illo ad nobis, ut aspernatur deserunt
187
+ fuga expedita amet architecto{' '}
188
+ <Link {...props} isInline size={undefined}>
189
+ pariatur cum itaque
190
+ </Link>{' '}
191
+ dicta veritatis inventore ea esse rem dolore natus! Architecto.
192
+ </Text>
193
+ ),
194
+ }
195
+
196
+ export const FiveLinksInSentence: Story = {
197
+ render: ({ size: _, ...otherArgs }) => (
198
+ <Text variant="body">
199
+ Lorem ipsum dolor sit amet consectetur adipisicing elit. Illo{' '}
200
+ <Link {...otherArgs} isInline>
201
+ {' '}
202
+ ad nobis
203
+ </Link>
204
+ , ut aspernatur{' '}
205
+ <Link {...otherArgs} isInline>
206
+ deserunt fuga expedita amet architecto
207
+ </Link>{' '}
208
+ <Link {...otherArgs} isInline>
209
+ pariatur cum itaque
210
+ </Link>{' '}
211
+ dicta veritatis{' '}
212
+ <Link {...otherArgs} isInline>
213
+ inventore ea
214
+ </Link>{' '}
215
+ esse rem dolore{' '}
216
+ <Link {...otherArgs} isInline>
217
+ natus
218
+ </Link>
219
+ ! Architecto.
220
+ </Text>
221
+ ),
222
+ }
223
+
224
+ export const ExternalIconLink: Story = {
225
+ render: (props) => <Link {...props} icon={<Icon name="open_in_new" isPresentational />} />,
226
+ }
227
+
228
+ export const RandomIconLink: Story = {
229
+ render: (props) => <Link {...props} icon={<Icon name="flag" isPresentational />} />,
230
+ }
231
+
232
+ export const DistinctNamedLink: Story = {
233
+ render: (props) => <Link {...props}>View Q4 2024 dataset</Link>,
234
+ }
235
+
236
+ export const GenericNamedLink: Story = {
237
+ render: (props) => <Link {...props}>Learn more</Link>,
238
+ }
@@ -0,0 +1,191 @@
1
+ import React from 'react'
2
+ import { type Meta } from '@storybook/react'
3
+ import { within } from '@storybook/test'
4
+ import { Icon } from '~components/__next__/Icon'
5
+ import { StickerSheet, type StickerSheetStory } from '~storybook/components/StickerSheet'
6
+ import { Link, type LinkProps } from '../Link'
7
+
8
+ export default {
9
+ title: 'Components/Link',
10
+ component: Link,
11
+ parameters: {
12
+ chromatic: { disable: false },
13
+ controls: { disable: true },
14
+ },
15
+ } satisfies Meta
16
+
17
+ const variants = ['primary', 'secondary'] satisfies LinkProps['variant'][]
18
+ const sizes = ['extra-small', 'small', 'body', 'intro-lede'] satisfies LinkProps['size'][]
19
+ const href = 'https://www.google.com' satisfies LinkProps['href']
20
+
21
+ const StickerSheetTemplate: StickerSheetStory = {
22
+ render: ({ isReversed }) => (
23
+ <>
24
+ <StickerSheet
25
+ title="Link"
26
+ headers={[
27
+ 'isUnderlined',
28
+ 'isUnderlined + Icon Start',
29
+ 'isUnderlined + Icon End',
30
+ 'Icon start',
31
+ 'Icon end',
32
+ 'isDisabled',
33
+ ]}
34
+ isReversed={isReversed}
35
+ >
36
+ {variants.map((variant) =>
37
+ sizes.map((size) => (
38
+ <StickerSheet.Row key={size + variant} header={`${variant} (${size})`}>
39
+ <Link
40
+ variant={isReversed ? 'white' : variant}
41
+ size={size}
42
+ href={href}
43
+ isUnderlined={true}
44
+ isInline={false}
45
+ >
46
+ Link
47
+ </Link>
48
+ <Link
49
+ variant={isReversed ? 'white' : variant}
50
+ size={size}
51
+ href={href}
52
+ isUnderlined={true}
53
+ isInline={false}
54
+ icon={<Icon name="add" isPresentational />}
55
+ iconPosition="start"
56
+ >
57
+ Link
58
+ </Link>
59
+ <Link
60
+ variant={isReversed ? 'white' : variant}
61
+ size={size}
62
+ href={href}
63
+ isUnderlined={true}
64
+ isInline={false}
65
+ icon={<Icon name="add" isPresentational />}
66
+ iconPosition="end"
67
+ >
68
+ Link
69
+ </Link>
70
+ <Link
71
+ variant={isReversed ? 'white' : variant}
72
+ size={size}
73
+ href={href}
74
+ isUnderlined={false}
75
+ isInline={false}
76
+ icon={<Icon name="add" isPresentational />}
77
+ iconPosition="start"
78
+ >
79
+ Link
80
+ </Link>
81
+ <Link
82
+ variant={isReversed ? 'white' : variant}
83
+ size={size}
84
+ href={href}
85
+ isUnderlined={false}
86
+ isInline={false}
87
+ icon={<Icon name="add" isPresentational />}
88
+ iconPosition="end"
89
+ >
90
+ Link
91
+ </Link>
92
+ <Link
93
+ variant={isReversed ? 'white' : variant}
94
+ size={size}
95
+ href={href}
96
+ isUnderlined={true}
97
+ isInline={false}
98
+ isDisabled={true}
99
+ >
100
+ Link
101
+ </Link>
102
+ </StickerSheet.Row>
103
+ )),
104
+ )}
105
+ </StickerSheet>
106
+ <StickerSheet
107
+ title="Pseudo states"
108
+ headers={['isHovered', 'isFocusVisible', 'isPressed']}
109
+ isReversed={isReversed}
110
+ >
111
+ {variants.map((variant) => (
112
+ <StickerSheet.Row key={variant} isReversed={isReversed} header={variant}>
113
+ <Link
114
+ variant={isReversed ? 'white' : variant}
115
+ size="small"
116
+ href={href}
117
+ isUnderlined={true}
118
+ isInline={false}
119
+ icon={<Icon name="add" isPresentational />}
120
+ data-testid="testid__link-hover"
121
+ >
122
+ Label
123
+ </Link>
124
+ <Link
125
+ variant={isReversed ? 'white' : variant}
126
+ size="small"
127
+ href={href}
128
+ isUnderlined={true}
129
+ isInline={false}
130
+ icon={<Icon name="add" isPresentational />}
131
+ data-testid="testid__link-focus"
132
+ >
133
+ Label
134
+ </Link>
135
+ <Link
136
+ variant={isReversed ? 'white' : variant}
137
+ size="small"
138
+ href={href}
139
+ isUnderlined={true}
140
+ isInline={false}
141
+ icon={<Icon name="add" isPresentational />}
142
+ data-testid="testid__link-pressed"
143
+ >
144
+ Label
145
+ </Link>
146
+ </StickerSheet.Row>
147
+ ))}
148
+ </StickerSheet>
149
+ </>
150
+ ),
151
+ play: ({ canvasElement }) => {
152
+ const canvas = within(canvasElement)
153
+ const focusLinks = canvas.getAllByTestId('testid__link-focus')
154
+ const hoverLinks = canvas.getAllByTestId('testid__link-hover')
155
+ const pressedLinks = canvas.getAllByTestId('testid__link-pressed')
156
+
157
+ focusLinks.forEach((Link) => {
158
+ Link.setAttribute('data-focus-visible', 'true')
159
+ })
160
+ hoverLinks.forEach((Link) => {
161
+ Link.setAttribute('data-hovered', 'true')
162
+ })
163
+ pressedLinks.forEach((Link) => {
164
+ Link.setAttribute('data-pressed', 'true')
165
+ })
166
+ },
167
+ }
168
+
169
+ export const StickerSheetDefault: StickerSheetStory = {
170
+ ...StickerSheetTemplate,
171
+ name: 'Sticker Sheet (Default)',
172
+ }
173
+
174
+ export const StickerSheetRTL: StickerSheetStory = {
175
+ ...StickerSheetTemplate,
176
+ name: 'Sticker Sheet (RTL)',
177
+ parameters: {
178
+ textDirection: 'rtl',
179
+ },
180
+ }
181
+
182
+ export const StickerSheetWhite: StickerSheetStory = {
183
+ ...StickerSheetTemplate,
184
+ name: 'Sticker Sheet (White)',
185
+ parameters: {
186
+ reverseColors: true,
187
+ },
188
+ args: {
189
+ isReversed: true,
190
+ },
191
+ }
@@ -0,0 +1 @@
1
+ export * from './Link'
@@ -0,0 +1,31 @@
1
+ import React, { type ReactNode } from 'react'
2
+ import { mergeClassNames } from '~components/utils/mergeClassNames'
3
+ import styles from '../Link.module.css'
4
+
5
+ export type LinkContentProps = {
6
+ children: ReactNode
7
+ icon?: JSX.Element
8
+ iconPosition?: 'start' | 'end'
9
+ isUnderlined: boolean
10
+ }
11
+
12
+ const LinkIcon = ({ icon }: { icon: JSX.Element }): JSX.Element => (
13
+ <span className={styles.icon}>{icon}</span>
14
+ )
15
+
16
+ export const LinkContent = ({
17
+ children,
18
+ icon,
19
+ iconPosition,
20
+ isUnderlined,
21
+ }: LinkContentProps): JSX.Element => {
22
+ const iconPositionStyling = iconPosition === 'start' ? styles.iconStart : styles.iconEnd
23
+
24
+ return (
25
+ <span className={mergeClassNames(styles.linkContent, isUnderlined && styles.isUnderlined)}>
26
+ {icon && iconPosition === 'start' && <LinkIcon icon={icon} />}
27
+ <span className={mergeClassNames(icon && iconPositionStyling)}>{children}</span>
28
+ {icon && iconPosition === 'end' && <LinkIcon icon={icon} />}
29
+ </span>
30
+ )
31
+ }
@@ -163,63 +163,7 @@ For resizing on smaller screens, consider using the `className` prop to leverage
163
163
 
164
164
  ## Client side routing
165
165
 
166
- To enable client side routing with the `LinkButton`, you will need to wrap your application in a [RouterProvider](https://react-spectrum.adobe.com/react-aria/routing.html#routerprovider) from the `react-aria-components` library. The allows you to set the `navigation` method that performs the client side routing in the `LinkButton` component. Refer to the framework specific guidance below for [Next.js](#nextjs-config-example) or [React Router](#react-router-config-example).
167
-
168
- ### Next.js config example
169
-
170
- The following example demonstrates how you might use the React Aria's `RouterProvider` with `Next.js`'s Pages router. This will allow the `LinkButton` to navigate using the `router.push` method.
171
-
172
- ```tsx
173
- // ...imports
174
- import type { AppProps } from 'next/app'
175
- import { type NextRouter } from 'next/router'
176
- import { RouterProvider as RacRouterProvider } from 'react-aria-components'
177
-
178
- // This provides the correct types for `routerOptions` based on the routing solution. As the component agnostic to routing technology this must defined here
179
- declare module 'react-aria-components' {
180
- interface RouterConfig {
181
- // index 2 is the types for the pages routerOptions
182
- routerOptions: NonNullable<Parameters<NextRouter['push']>[2]>
183
- }
184
- }
185
-
186
- function App({ Component, pageProps, router }: AppProps) {
187
- return (
188
- <FrontendServices {...config}>
189
- {/* application code */}
190
- <RacRouterProvider navigate={(href, opts) => router.push(href, undefined, opts)}>
191
- <Component {...pageProps} />
192
- </RacRouterProvider>
193
- {/* application code */}
194
- </FrontendServices>
195
- )
196
- }
197
-
198
- export default App
199
- ```
200
-
201
- The implementation in your application would then look something like this:
202
-
203
- ```tsx
204
- import { useRouter } from 'next/router'
205
- import { LinkButton } from '@kaizen/components'
206
-
207
- const Component = () => {
208
- const router = useRouter()
209
-
210
- return (
211
- <>
212
- <LinkButton href="http://google.com">External link</LinkButton>
213
- <LinkButton href={`${router.pathname}/path-1`}>Internal link</LinkButton>
214
- <LinkButton href={`${router.pathname}/path-2`} routerOptions={{ scroll: false }}>
215
- Link with routerOptions
216
- </LinkButton>
217
- </>
218
- )
219
- }
220
- ```
221
-
222
- Additional config options for Next.js can be found in the React Aria's documentation on the [RouterProvider](https://react-spectrum.adobe.com/react-aria/routing.html#nextjs), including the alternative setup for the [App router](https://react-spectrum.adobe.com/react-aria/routing.html##app-router).
166
+ Please refer to the [client side routing](/docs/guides-client-side-routing--docs) for more information on how to set up client side routing with the `LinkButton`.
223
167
 
224
168
  ### React Router config example
225
169