@kaizen/components 0.0.0-canary-introduce-next-entrypoint-20250225031042 → 0.0.0-canary-react-19-peer-20250303022312

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 (99) 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 +210 -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/Calendar/CalendarPopover/CalendarPopover.cjs +38 -25
  15. package/dist/cjs/Focusable/Focusable.module.scss.cjs +6 -0
  16. package/dist/cjs/Link/Link.cjs +45 -0
  17. package/dist/cjs/Link/Link.module.css.cjs +20 -0
  18. package/dist/cjs/Link/subcomponents/LinkContent.cjs +34 -0
  19. package/dist/cjs/future.cjs +1 -1
  20. package/dist/cjs/index.cjs +4 -0
  21. package/dist/cjs/next.cjs +1 -1
  22. package/dist/cjs/overlaysV3.cjs +0 -2
  23. package/dist/cjs/utilitiesV3.cjs +4 -0
  24. package/dist/esm/Calendar/CalendarPopover/CalendarPopover.mjs +39 -26
  25. package/dist/esm/Focusable/Focusable.module.scss.mjs +4 -0
  26. package/dist/esm/Link/Link.mjs +40 -0
  27. package/dist/esm/Link/Link.module.css.mjs +18 -0
  28. package/dist/esm/Link/subcomponents/LinkContent.mjs +26 -0
  29. package/dist/esm/future.mjs +1 -1
  30. package/dist/esm/index.mjs +2 -0
  31. package/dist/esm/next.mjs +1 -1
  32. package/dist/esm/overlaysV3.mjs +0 -1
  33. package/dist/esm/utilitiesV3.mjs +2 -0
  34. package/dist/styles.css +8905 -8782
  35. package/dist/types/Link/Link.d.ts +39 -0
  36. package/dist/types/Link/index.d.ts +1 -0
  37. package/dist/types/Link/subcomponents/LinkContent.d.ts +8 -0
  38. package/dist/types/__next__/Tooltip/index.d.ts +0 -1
  39. package/dist/types/__next__/index.d.ts +1 -0
  40. package/dist/types/index.d.ts +2 -0
  41. package/package.json +3 -3
  42. package/src/Calendar/CalendarPopover/CalendarPopover.module.scss +8 -0
  43. package/src/Calendar/CalendarPopover/CalendarPopover.tsx +13 -2
  44. package/src/Calendar/CalendarPopover/_docs/CalendarPopover.stickersheet.stories.tsx +1 -55
  45. package/src/Calendar/CalendarRange/_docs/CalendarRange.stickersheet.stories.tsx +1 -1
  46. package/src/Calendar/CalendarRange/_docs/CalendarRange.stories.tsx +1 -1
  47. package/src/Calendar/CalendarSingle/_docs/CalendarSingle.stickersheet.stories.tsx +1 -1
  48. package/src/Calendar/CalendarSingle/_docs/CalendarSingle.stories.tsx +1 -1
  49. package/src/DatePicker/_docs/DatePicker.stickersheet.stories.tsx +1 -1
  50. package/src/DatePicker/_docs/DatePicker.stories.tsx +1 -1
  51. package/src/DatePicker/_docs/getLocale.stickersheet.stories.tsx +1 -1
  52. package/src/DateRangePicker/_docs/DateRangePicker.stickersheet.stories.tsx +1 -1
  53. package/src/DateRangePicker/_docs/DateRangePicker.stories.tsx +1 -1
  54. package/src/{__next__/Tooltip/subcomponents/Focusable → Focusable}/_docs/ApiSpecification.mdx +3 -3
  55. package/src/{__next__/Tooltip/subcomponents/Focusable → Focusable}/_docs/Focusable.stories.tsx +1 -1
  56. package/src/Icon/_docs/Icon.docs.stories.tsx +1 -1
  57. package/src/Icon/_docs/Icon.mdx +1 -1
  58. package/src/Icon/_docs/Icon.stickersheet.stories.tsx +1 -1
  59. package/src/Link/Link.module.css +119 -0
  60. package/src/Link/Link.tsx +90 -0
  61. package/src/Link/_docs/Link--api-specification.mdx +133 -0
  62. package/src/Link/_docs/Link--api-usage-guidelines.mdx +107 -0
  63. package/src/Link/_docs/Link.doc.stories.tsx +238 -0
  64. package/src/Link/_docs/Link.stickersheet.stories.tsx +191 -0
  65. package/src/Link/index.ts +1 -0
  66. package/src/Link/subcomponents/LinkContent.tsx +31 -0
  67. package/src/LinkButton/_docs/LinkButton--api-specification.mdx +1 -57
  68. package/src/Modal/GenericModal/_docs/GenericModal.spec.stories.tsx +1 -1
  69. package/src/Modal/GenericModal/_docs/GenericModal.stories.tsx +1 -1
  70. package/src/Tile/subcomponents/GenericTile/GenericTile.spec.stories.tsx +1 -1
  71. package/src/Tile/subcomponents/GenericTile/_docs/GenericTile.stickersheet.stories.tsx +1 -1
  72. package/src/TitleBlockZen/TitleBlockZen.module.scss +1 -6
  73. package/src/__next__/Button/_docs/Button--migration-guide.mdx +81 -0
  74. package/src/__next__/Icon/_docs/Icon--api-specification.mdx +1 -1
  75. package/src/__next__/Icon/_docs/Icon--usage-guidelines.mdx +1 -1
  76. package/src/__next__/Menu/_docs/Menu--api-specification.mdx +1 -1
  77. package/src/__next__/Menu/_docs/Menu--usage-guidelines.mdx +1 -1
  78. package/src/__next__/Select/_docs/Select.mdx +2 -2
  79. package/src/__next__/Select/_docs/Select.stickersheet.stories.tsx +1 -1
  80. package/src/__next__/Select/_docs/Select.stories.tsx +1 -1
  81. package/src/__next__/Tabs/_docs/Tabs--api-specification.mdx +1 -1
  82. package/src/__next__/Tag/RemovableTag/_docs/RemovableTag.mdx +1 -1
  83. package/src/__next__/Tooltip/_docs/ApiSpecification.mdx +1 -1
  84. package/src/__next__/Tooltip/_docs/Tooltip.docs.stories.tsx +2 -1
  85. package/src/__next__/Tooltip/_docs/Tooltip.mdx +1 -1
  86. package/src/__next__/Tooltip/_docs/Tooltip.spec.stories.tsx +2 -1
  87. package/src/__next__/Tooltip/_docs/Tooltip.stories.tsx +2 -1
  88. package/src/__next__/Tooltip/index.ts +0 -1
  89. package/src/__next__/index.ts +4 -0
  90. package/src/index.ts +2 -0
  91. package/dist/cjs/__next__/Tooltip/subcomponents/Focusable/Focusable.module.scss.cjs +0 -6
  92. package/dist/esm/__next__/Tooltip/subcomponents/Focusable/Focusable.module.scss.mjs +0 -4
  93. /package/dist/cjs/{__next__/Tooltip/subcomponents/Focusable → Focusable}/Focusable.cjs +0 -0
  94. /package/dist/esm/{__next__/Tooltip/subcomponents/Focusable → Focusable}/Focusable.mjs +0 -0
  95. /package/dist/types/{__next__/Tooltip/subcomponents/Focusable → Focusable}/Focusable.d.ts +0 -0
  96. /package/dist/types/{__next__/Tooltip/subcomponents/Focusable → Focusable}/index.d.ts +0 -0
  97. /package/src/{__next__/Tooltip/subcomponents/Focusable → Focusable}/Focusable.module.scss +0 -0
  98. /package/src/{__next__/Tooltip/subcomponents/Focusable → Focusable}/Focusable.tsx +0 -0
  99. /package/src/{__next__/Tooltip/subcomponents/Focusable → Focusable}/index.ts +0 -0
@@ -0,0 +1,39 @@
1
+ import React from 'react';
2
+ import { type LinkProps as RACLinkProps } from 'react-aria-components';
3
+ import { type TextProps } from "../Text";
4
+ export type LinkProps = BaseLinkProps & ((UnderlinedLink | NonUnderlinedLink) & (InlineLink | NonInlineLink));
5
+ type BaseLinkProps = {
6
+ /** Controls the visual style of a link. @default 'primary' */
7
+ variant?: 'primary' | 'secondary' | 'white';
8
+ /** Controls the position of a link. @default 'end' */
9
+ iconPosition?: 'start' | 'end';
10
+ } & Omit<RACLinkProps, 'children'> & {
11
+ /** Used as the label for the Link. */
12
+ children: RACLinkProps['children'];
13
+ };
14
+ type UnderlinedLink = {
15
+ /** Toggles the underline of the icon and children @default true */
16
+ isUnderlined?: true;
17
+ /** The icon to be displayed, optional when link is underlined */
18
+ icon?: JSX.Element;
19
+ };
20
+ type NonUnderlinedLink = {
21
+ /** Toggles the underline of the icon and children */
22
+ isUnderlined?: false;
23
+ /** The icon to be displayed, required when link is not underlined */
24
+ icon: JSX.Element;
25
+ };
26
+ type InlineLink = {
27
+ /** isInline assumes the Link is wrapped in a [Text](https://cultureamp.design/?path=/docs/components-text--docs) component */
28
+ isInline: true;
29
+ /** The size of the link, not passed when isInline */
30
+ size?: never;
31
+ };
32
+ type NonInlineLink = {
33
+ /** isInline assumes the Link is wrapped in a [Text](https://cultureamp.design/?path=/docs/components-text--docs) component @default false */
34
+ isInline?: false;
35
+ /** The size of the link. Sizes correlate to body text sizes. @default 'body' */
36
+ size?: TextProps['variant'];
37
+ };
38
+ export declare const Link: React.ForwardRefExoticComponent<LinkProps & React.RefAttributes<HTMLAnchorElement>>;
39
+ export {};
@@ -0,0 +1 @@
1
+ export * from './Link';
@@ -0,0 +1,8 @@
1
+ import { type ReactNode } from 'react';
2
+ export type LinkContentProps = {
3
+ children: ReactNode;
4
+ icon?: JSX.Element;
5
+ iconPosition?: 'start' | 'end';
6
+ isUnderlined: boolean;
7
+ };
8
+ export declare const LinkContent: ({ children, icon, iconPosition, isUnderlined, }: LinkContentProps) => JSX.Element;
@@ -1,3 +1,2 @@
1
1
  export * from './Tooltip';
2
2
  export * from './TooltipTrigger';
3
- export * from './subcomponents/Focusable';
@@ -5,3 +5,4 @@ export * from './Select';
5
5
  export * from './Tag';
6
6
  export * from './Tabs';
7
7
  export * from './Tooltip';
8
+ export * from '../Focusable';
@@ -21,6 +21,7 @@ export * from './ErrorPage';
21
21
  export * from './FieldGroup';
22
22
  export * from './FieldMessage';
23
23
  export * from './Filter';
24
+ export * from './Focusable';
24
25
  export * from './GuidanceBlock';
25
26
  export * from './Heading';
26
27
  export * from './Icon';
@@ -29,6 +30,7 @@ export * from './Input';
29
30
  export * from './KaizenProvider';
30
31
  export * from './Label';
31
32
  export * from './LabelledMessage';
33
+ export * from './Link';
32
34
  export * from './LikertScaleLegacy';
33
35
  export * from './LinkButton';
34
36
  export * from './Loading';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaizen/components",
3
- "version": "0.0.0-canary-introduce-next-entrypoint-20250225031042",
3
+ "version": "0.0.0-canary-react-19-peer-20250303022312",
4
4
  "description": "Kaizen component library",
5
5
  "author": "Geoffrey Chong <geoff.chong@cultureamp.com>",
6
6
  "homepage": "https://cultureamp.design",
@@ -185,7 +185,7 @@
185
185
  "svgo": "^3.3.2",
186
186
  "tslib": "^2.8.1",
187
187
  "tsx": "^4.19.2",
188
- "@kaizen/design-tokens": "10.8.7",
188
+ "@kaizen/design-tokens": "0.0.0-canary-react-19-peer-20250303022312",
189
189
  "@kaizen/package-bundler": "2.0.4"
190
190
  },
191
191
  "devDependenciesComments": {
@@ -194,7 +194,7 @@
194
194
  },
195
195
  "peerDependencies": {
196
196
  "@cultureamp/i18n-react-intl": "^2.5.9",
197
- "react": "^18.3.1",
197
+ "react": "^18.3.1 || ^19.0.0",
198
198
  "react-dom": "^18.3.1",
199
199
  "react-intl": "^6.6.8 || ^7.0.0",
200
200
  "typescript": "5.x"
@@ -17,3 +17,11 @@
17
17
  padding: $spacing-24;
18
18
  }
19
19
  }
20
+
21
+ // Overrides for if the browser supports popovers. The inset unset is to fix a bug with RTL positioning https://github.com/floating-ui/floating-ui/issues/3221
22
+ // Margin 0 because default styling for [popover] is margin: auto to center it.
23
+ .calendarPopover[popover]:popover-open {
24
+ z-index: unset;
25
+ margin: 0;
26
+ inset: unset;
27
+ }
@@ -1,4 +1,4 @@
1
- import React, { useState, type HTMLAttributes } from 'react'
1
+ import React, { useEffect, useState, type HTMLAttributes } from 'react'
2
2
  import {
3
3
  autoPlacement,
4
4
  autoUpdate,
@@ -30,7 +30,7 @@ export const CalendarPopover = ({
30
30
  }: CalendarPopoverProps): JSX.Element => {
31
31
  const [floatingElement, setFloatingElement] = useState<HTMLDivElement | null>(null)
32
32
 
33
- const { floatingStyles } = useFloating({
33
+ const { floatingStyles, update } = useFloating({
34
34
  placement: 'bottom-start',
35
35
  elements: {
36
36
  reference: referenceElement,
@@ -57,6 +57,15 @@ export const CalendarPopover = ({
57
57
  ...floatingOptions,
58
58
  })
59
59
 
60
+ useEffect(() => {
61
+ if (floatingElement && referenceElement) {
62
+ // @ts-expect-error this can be removed when we update to react 19
63
+ referenceElement.popoverTargetElement = floatingElement
64
+ floatingElement.showPopover?.()
65
+ update()
66
+ }
67
+ }, [referenceElement, floatingElement, update])
68
+
60
69
  return (
61
70
  <div
62
71
  ref={setFloatingElement}
@@ -64,6 +73,8 @@ export const CalendarPopover = ({
64
73
  className={classnames(styles.calendarPopover, classNameOverride)}
65
74
  role="dialog"
66
75
  aria-modal="true"
76
+ // @ts-expect-error this can be removed when we update to react 19
77
+ popover="manual"
67
78
  {...restProps}
68
79
  >
69
80
  {children}
@@ -1,14 +1,13 @@
1
1
  import React from 'react'
2
2
  import { autoPlacement, offset, size } from '@floating-ui/react-dom'
3
3
  import { type Meta } from '@storybook/react'
4
- import { Text } from '~components/Text'
5
4
  import { StickerSheet, type StickerSheetStory } from '~storybook/components/StickerSheet'
6
5
  import { CalendarRange } from '../../CalendarRange'
7
6
  import { CalendarSingle } from '../../CalendarSingle'
8
7
  import { CalendarPopover, type CalendarPopoverProps } from '../index'
9
8
 
10
9
  export default {
11
- title: 'Components/Date controls/Calendars/CalendarPopover',
10
+ title: 'Components/Datepickers/Calendars (primitives)/CalendarPopover (primitive)',
12
11
  parameters: {
13
12
  chromatic: {
14
13
  disable: false,
@@ -150,56 +149,3 @@ export const StickerSheetRTL: StickerSheetStory = {
150
149
  textDirection: 'rtl',
151
150
  },
152
151
  }
153
-
154
- export const StickerSheetResponsive: StickerSheetStory = {
155
- name: 'Sticker Sheet (Responsive)',
156
- render: () => (
157
- <>
158
- <Text variant="intro-lede" classNameOverride="mb-12 ">
159
- CalendarSingle scaled to availableHeight
160
- </Text>
161
- <div className="h-[250px] p-12 bg-purple-100 overflow-hidden relative">
162
- <CalendarPopoverExample strategy="absolute">
163
- <CalendarSingle selected={new Date('2022-02-19')} />
164
- </CalendarPopoverExample>
165
- </div>
166
- <Text variant="intro-lede" classNameOverride="mb-12 ">
167
- CalendarRange scaled to availableHeight
168
- </Text>
169
- <div className="h-[250px] p-12 bg-purple-100 overflow-hidden relative">
170
- <CalendarPopoverExample strategy="absolute">
171
- <CalendarRange
172
- selected={{
173
- from: new Date('2022-02-19'),
174
- to: new Date('2022-03-04'),
175
- }}
176
- hasDivider
177
- />
178
- </CalendarPopoverExample>
179
- </div>
180
- <Text variant="intro-lede" classNameOverride="mb-12 mt-24">
181
- CalendarSingle scaled to availableWidth
182
- </Text>
183
- <div className="h-[250px] p-12 bg-purple-100 overflow-hidden relative w-[250px]">
184
- <CalendarPopoverExample strategy="absolute">
185
- <CalendarSingle selected={new Date('2022-03-19')} />
186
- </CalendarPopoverExample>
187
- </div>
188
- <Text variant="intro-lede" classNameOverride="mb-12 mt-24">
189
- CalendarRanger scaled to availableWidth
190
- </Text>
191
- <div className="h-[250px] p-12 bg-purple-100 overflow-hidden relative w-[250px]">
192
- <CalendarPopoverExample strategy="absolute">
193
- <CalendarRange
194
- data-testid="sb-final-calendar"
195
- selected={{
196
- from: new Date('2022-02-19'),
197
- to: new Date('2022-03-04'),
198
- }}
199
- hasDivider
200
- />
201
- </CalendarPopoverExample>
202
- </div>
203
- </>
204
- ),
205
- }
@@ -5,7 +5,7 @@ import { StickerSheet, type StickerSheetStory } from '~storybook/components/Stic
5
5
  import { CalendarRange, type CalendarRangeProps } from '../../index'
6
6
 
7
7
  export default {
8
- title: 'Components/Date controls/Calendars/CalendarRange',
8
+ title: 'Components/Datepickers/Calendars (primitives)/CalendarRange (primitive)',
9
9
  parameters: {
10
10
  chromatic: { disable: false },
11
11
  controls: { disable: true },
@@ -6,7 +6,7 @@ import { type DateRange } from '../../types'
6
6
  import { CalendarRange } from '../index'
7
7
 
8
8
  const meta = {
9
- title: 'Components/Date controls/Calendars/CalendarRange',
9
+ title: 'Components/Datepickers/Calendars (primitives)/CalendarRange (primitive)',
10
10
  component: CalendarRange,
11
11
  argTypes: {
12
12
  ...defaultMonthControls,
@@ -6,7 +6,7 @@ import styles from '../../baseCalendarClassNames.module.scss'
6
6
  import { CalendarSingle, type CalendarSingleProps } from '../index'
7
7
 
8
8
  export default {
9
- title: 'Components/Date controls/Calendars/CalendarSingle',
9
+ title: 'Components/Datepickers/Calendars (primitives)/CalendarSingle (primitive)',
10
10
  parameters: {
11
11
  chromatic: { disable: false },
12
12
  controls: { disable: true },
@@ -5,7 +5,7 @@ import { weekStartsOnControls } from '../../_docs/controls/weekStartsOnControls'
5
5
  import { CalendarSingle } from '../index'
6
6
 
7
7
  const meta = {
8
- title: 'Components/Date controls/Calendars/CalendarSingle',
8
+ title: 'Components/Datepickers/Calendars (primitives)/CalendarSingle (primitive)',
9
9
  component: CalendarSingle,
10
10
  argTypes: {
11
11
  ...defaultMonthControls,
@@ -7,7 +7,7 @@ import { StickerSheet, type StickerSheetStory } from '~storybook/components/Stic
7
7
  import { DatePicker } from '../index'
8
8
 
9
9
  export default {
10
- title: 'Components/Date controls/DatePicker',
10
+ title: 'Components/Datepickers/DatePicker',
11
11
  parameters: {
12
12
  chromatic: { disable: false },
13
13
  controls: { disable: true },
@@ -13,7 +13,7 @@ import { datePickerLocaleControls } from './controls/datePickerLocaleControls'
13
13
  import { disabledDayMatchersControls } from './controls/disabledDayMatchersControls'
14
14
 
15
15
  const meta = {
16
- title: 'Components/Date controls/DatePicker',
16
+ title: 'Components/Datepickers/DatePicker',
17
17
  component: DatePicker,
18
18
  argTypes: {
19
19
  ...datePickerLocaleControls,
@@ -6,7 +6,7 @@ import { StickerSheet, type StickerSheetStory } from '~storybook/components/Stic
6
6
  import { getLocale } from '../utils/getLocale'
7
7
 
8
8
  export default {
9
- title: 'Components/Date controls/DatePicker/Tests',
9
+ title: 'Components/Datepickers/DatePicker/Tests',
10
10
  parameters: {
11
11
  chromatic: { disable: false },
12
12
  controls: { disable: true },
@@ -10,7 +10,7 @@ import { StickerSheet, type StickerSheetStory } from '~storybook/components/Stic
10
10
  import { DateRangePicker, formatDateRangeValue, type DateRangePickerProps } from '../index'
11
11
 
12
12
  export default {
13
- title: 'Components/Date controls/DateRangePicker',
13
+ title: 'Components/Datepickers/DateRangePicker',
14
14
  parameters: {
15
15
  chromatic: { disable: false },
16
16
  controls: { disable: true },
@@ -5,7 +5,7 @@ import { type DateRange } from 'react-day-picker'
5
5
  import { DateRangePicker, formatDateRangeValue } from '../index'
6
6
 
7
7
  const meta = {
8
- title: 'Components/Date controls/DateRangePicker',
8
+ title: 'Components/Datepickers/DateRangePicker',
9
9
  component: DateRangePicker,
10
10
  args: {
11
11
  labelText: 'Label',
@@ -2,18 +2,18 @@ import { Canvas, Controls, Meta } from '@storybook/blocks'
2
2
  import { KAIOInstallation, ResourceLinks } from '~storybook/components'
3
3
  import * as exampleStories from './Focusable.stories'
4
4
 
5
- <Meta title="Components/Tooltip/Tooltip (next)/Focusable/API Specification" />
5
+ <Meta title="Components/Focusable/API Specification" />
6
6
 
7
7
  # Focusable API Specification
8
8
 
9
9
  Updated June 25, 2024
10
10
 
11
11
  <ResourceLinks
12
- sourceCode="https://github.com/cultureamp/kaizen-design-system/tree/main/packages/components/src/__next__/Tooltip/subcomponents/Focusable"
12
+ sourceCode="https://github.com/cultureamp/kaizen-design-system/tree/main/packages/components/src/Focusable"
13
13
  className="mt-16 !mb-8"
14
14
  />
15
15
 
16
- <KAIOInstallation exportNames={['Focusable']} isNext />
16
+ <KAIOInstallation exportNames={['Focusable']} />
17
17
 
18
18
  ## Overview
19
19
 
@@ -4,7 +4,7 @@ import { Tag } from '~components/__next__/Tag'
4
4
  import { Focusable } from '../index'
5
5
 
6
6
  const meta = {
7
- title: 'Components/Tooltip/Tooltip (next)/Focusable',
7
+ title: 'Components/Focusable',
8
8
  component: Focusable,
9
9
  parameters: {
10
10
  layout: 'centered',
@@ -7,7 +7,7 @@ import { AddIcon } from '../index'
7
7
  import styles from './icon.module.scss'
8
8
 
9
9
  const meta = {
10
- title: 'Components/Icon/*Icon Components (deprecated)',
10
+ title: 'Components/Icon/Icon components (deprecated)',
11
11
  component: AddIcon,
12
12
  args: {
13
13
  role: 'presentation',
@@ -6,7 +6,7 @@ import * as IconStories from './Icon.docs.stories'
6
6
 
7
7
  # Icon (deprecated)
8
8
 
9
- <ResourceLinks sourceCode="https://github.com/cultureamp/kaizen-design-system/tree/main/packages/components/src/Icons" />
9
+ <ResourceLinks sourceCode="https://github.com/cultureamp/kaizen-design-system/tree/main/packages/components/src/Icon" />
10
10
 
11
11
  <ReplacementNotice />
12
12
 
@@ -4,7 +4,7 @@ import * as ICONS from '~components/Icon'
4
4
  import { StickerSheet, type StickerSheetStory } from '~storybook/components/StickerSheet'
5
5
 
6
6
  export default {
7
- title: 'Components/Icon/*Icon Components (deprecated)',
7
+ title: 'Components/Icon/Icon components (deprecated)',
8
8
  parameters: {
9
9
  chromatic: { disable: false },
10
10
  controls: { disable: true },
@@ -0,0 +1,119 @@
1
+ .link {
2
+ color: var(--link-text-color, var(--color-blue-500));
3
+ font-family: var(--typography-paragraph-body-font-family);
4
+ font-size: var(--link-font-size, inherit);
5
+ line-height: var(--link-line-height, inherit);
6
+ font-weight: var(--typography-paragraph-body-font-weight);
7
+ text-decoration: none;
8
+ position: relative;
9
+ white-space: nowrap;
10
+ outline: 0;
11
+ }
12
+
13
+ .link[data-focus-visible]::after {
14
+ content: '';
15
+ position: absolute;
16
+ background: transparent;
17
+ border-color: var(--color-blue-500);
18
+ border-radius: 0;
19
+ border-width: var(--border-focus-ring-border-width);
20
+ border-style: var(--border-focus-ring-border-style);
21
+ inset: calc(-1 * (var(--border-focus-ring-border-width) * 2) - 1px);
22
+ }
23
+
24
+ .isUnderlined {
25
+ border-bottom: var(--spacing-1) solid var(--link-text-color, var(--color-blue-500));
26
+ }
27
+
28
+ .icon > * {
29
+ vertical-align: text-bottom;
30
+ font-size: var(--icon-font-size, 1em);
31
+ }
32
+
33
+ .iconStart {
34
+ margin-inline-start: var(--text-icon-gap, 0.5em);
35
+ }
36
+
37
+ .iconEnd {
38
+ margin-inline-end: var(--text-icon-gap, 0.5em);
39
+ }
40
+
41
+ .primary[data-hovered] {
42
+ --link-text-color: var(--color-blue-600);
43
+ }
44
+
45
+ .primary[data-pressed] {
46
+ --link-text-color: var(--color-blue-700);
47
+ }
48
+
49
+ .secondary {
50
+ --link-text-color: var(--color-purple-800);
51
+ }
52
+
53
+ .secondary[data-hovered] {
54
+ --link-text-color: var(--color-gray-600);
55
+ }
56
+
57
+ .secondary[data-pressed] {
58
+ --link-text-color: var(--color-black);
59
+ }
60
+
61
+ [class*='extra-small'] .link.isInline,
62
+ .extra-small {
63
+ --link-font-size: var(--typography-paragraph-extra-small-font-size);
64
+ --link-line-height: var(--typography-paragraph-extra-small-line-height);
65
+ --icon-font-size: 0.875rem;
66
+ --text-icon-gap: var(--spacing-2);
67
+ }
68
+
69
+ [class*='body'] .link.isInline,
70
+ .body {
71
+ --link-font-size: var(--typography-paragraph-body-font-size);
72
+ --link-line-height: var(--typography-paragraph-body-line-height);
73
+ --icon-font-size: 1.25rem;
74
+ --text-icon-gap: var(--spacing-6);
75
+ }
76
+
77
+ [class*='intro-lede'] .link.isInline,
78
+ .intro-lede {
79
+ --link-font-size: var(--typography-paragraph-intro-lede-font-size);
80
+ --link-line-height: var(--typography-paragraph-intro-lede-line-height);
81
+ --icon-font-size: 1.5rem;
82
+ --text-icon-gap: var(--spacing-8);
83
+ }
84
+
85
+ [class*='small']:not([class*='extra-small']) .link.isInline,
86
+ .small {
87
+ --link-font-size: var(--typography-paragraph-small-font-size);
88
+ --link-line-height: var(--typography-paragraph-small-line-height);
89
+ --icon-font-size: 1rem;
90
+ --text-icon-gap: var(--spacing-4);
91
+ }
92
+
93
+ .white {
94
+ --link-text-color: var(--color-white);
95
+ }
96
+
97
+ .white[data-focus-visible]::after {
98
+ border-color: var(--color-blue-300);
99
+ }
100
+
101
+ .white.isDisabled {
102
+ --link-text-color: rgba(var(--color-white-rgb), 0.2);
103
+ }
104
+
105
+ .reversed {
106
+ --link-text-color: var(--color-white);
107
+ }
108
+
109
+ .reversed[data-focus-visible]::after {
110
+ border-color: var(--color-blue-300);
111
+ }
112
+
113
+ .link.isDisabled {
114
+ --link-text-color: var(--color-gray-400);
115
+ }
116
+
117
+ .reversed.isDisabled {
118
+ --link-text-color: rgba(var(--color-white-rgb), 0.2);
119
+ }
@@ -0,0 +1,90 @@
1
+ import React, { forwardRef } from 'react'
2
+ import { Link as RACLink, type LinkProps as RACLinkProps } from 'react-aria-components'
3
+ import { type TextProps } from '~components/Text'
4
+ import { mergeClassNames } from '~components/utils/mergeClassNames'
5
+ import { LinkContent } from './subcomponents/LinkContent'
6
+ import styles from './Link.module.css'
7
+
8
+ export type LinkProps = BaseLinkProps &
9
+ ((UnderlinedLink | NonUnderlinedLink) & (InlineLink | NonInlineLink))
10
+
11
+ type BaseLinkProps = {
12
+ /** Controls the visual style of a link. @default 'primary' */
13
+ variant?: 'primary' | 'secondary' | 'white'
14
+ /** Controls the position of a link. @default 'end' */
15
+ iconPosition?: 'start' | 'end'
16
+ } & Omit<RACLinkProps, 'children'> & {
17
+ /** Used as the label for the Link. */
18
+ children: RACLinkProps['children']
19
+ }
20
+
21
+ type UnderlinedLink = {
22
+ /** Toggles the underline of the icon and children @default true */
23
+ isUnderlined?: true
24
+ /** The icon to be displayed, optional when link is underlined */
25
+ icon?: JSX.Element
26
+ }
27
+
28
+ type NonUnderlinedLink = {
29
+ /** Toggles the underline of the icon and children */
30
+ isUnderlined?: false
31
+ /** The icon to be displayed, required when link is not underlined */
32
+ icon: JSX.Element
33
+ }
34
+
35
+ type InlineLink = {
36
+ /** isInline assumes the Link is wrapped in a [Text](https://cultureamp.design/?path=/docs/components-text--docs) component */
37
+ isInline: true
38
+ /** The size of the link, not passed when isInline */
39
+ size?: never
40
+ }
41
+
42
+ type NonInlineLink = {
43
+ /** isInline assumes the Link is wrapped in a [Text](https://cultureamp.design/?path=/docs/components-text--docs) component @default false */
44
+ isInline?: false
45
+ /** The size of the link. Sizes correlate to body text sizes. @default 'body' */
46
+ size?: TextProps['variant']
47
+ }
48
+
49
+ export const Link = forwardRef(
50
+ (
51
+ {
52
+ children,
53
+ variant = 'primary',
54
+ size = 'body',
55
+ icon,
56
+ iconPosition = 'end',
57
+ isInline = false,
58
+ isDisabled,
59
+ className,
60
+ isUnderlined = true,
61
+ ...otherProps
62
+ }: LinkProps,
63
+ ref: React.ForwardedRef<HTMLAnchorElement>,
64
+ ) => {
65
+ const childIsFunction = typeof children === 'function'
66
+
67
+ return (
68
+ <RACLink
69
+ ref={ref}
70
+ className={mergeClassNames(
71
+ styles.link,
72
+ isDisabled && styles.isDisabled,
73
+ isInline ? styles.isInline : styles[size],
74
+ styles[variant],
75
+ className,
76
+ )}
77
+ isDisabled={isDisabled}
78
+ {...otherProps}
79
+ >
80
+ {(racStateProps) => (
81
+ <LinkContent icon={icon} iconPosition={iconPosition} isUnderlined={isUnderlined}>
82
+ {childIsFunction ? children(racStateProps) : children}
83
+ </LinkContent>
84
+ )}
85
+ </RACLink>
86
+ )
87
+ },
88
+ )
89
+
90
+ Link.displayName = 'Link'