@navikt/ds-react 6.1.0 → 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.
Files changed (191) hide show
  1. package/cjs/accordion/Accordion.d.ts +4 -4
  2. package/cjs/alert/Alert.d.ts +12 -10
  3. package/cjs/alert/Alert.js.map +1 -1
  4. package/cjs/button/Button.d.ts +9 -8
  5. package/cjs/button/Button.js.map +1 -1
  6. package/cjs/chat/Chat.d.ts +6 -6
  7. package/cjs/chips/Chips.d.ts +2 -2
  8. package/cjs/copybutton/CopyButton.d.ts +14 -12
  9. package/cjs/copybutton/CopyButton.js.map +1 -1
  10. package/cjs/date/datepicker/types.d.ts +7 -6
  11. package/cjs/date/hooks/useDatepicker.d.ts +4 -3
  12. package/cjs/date/hooks/useDatepicker.js.map +1 -1
  13. package/cjs/date/hooks/useMonthPicker.d.ts +4 -3
  14. package/cjs/date/hooks/useMonthPicker.js.map +1 -1
  15. package/cjs/date/monthpicker/types.d.ts +2 -1
  16. package/cjs/date/parts/DateInput.d.ts +1 -1
  17. package/cjs/expansion-card/ExpansionCardTitle.d.ts +1 -1
  18. package/cjs/form/checkbox/CheckboxGroup.d.ts +3 -3
  19. package/cjs/form/checkbox/types.d.ts +4 -4
  20. package/cjs/form/combobox/types.d.ts +15 -15
  21. package/cjs/form/error-summary/ErrorSummary.d.ts +5 -5
  22. package/cjs/form/radio/RadioGroup.d.ts +1 -1
  23. package/cjs/form/search/Search.d.ts +3 -2
  24. package/cjs/form/search/Search.js.map +1 -1
  25. package/cjs/form/select/Select.d.ts +9 -9
  26. package/cjs/form/switch/Switch.d.ts +5 -5
  27. package/cjs/form/textarea/Textarea.d.ts +5 -4
  28. package/cjs/form/textarea/Textarea.js.map +1 -1
  29. package/cjs/form/useFormField.d.ts +10 -8
  30. package/cjs/form/useFormField.js.map +1 -1
  31. package/cjs/layout/bleed/Bleed.d.ts +9 -1
  32. package/cjs/layout/bleed/Bleed.js.map +1 -1
  33. package/cjs/layout/box/Box.d.ts +5 -5
  34. package/cjs/layout/grid/HGrid.d.ts +1 -3
  35. package/cjs/layout/grid/HGrid.js.map +1 -1
  36. package/cjs/layout/page/Page.d.ts +2 -2
  37. package/cjs/layout/responsive/Responsive.d.ts +2 -4
  38. package/cjs/layout/responsive/Responsive.js.map +1 -1
  39. package/cjs/layout/stack/Stack.d.ts +18 -4
  40. package/cjs/layout/stack/Stack.js.map +1 -1
  41. package/cjs/list/types.d.ts +1 -1
  42. package/cjs/loader/Loader.d.ts +1 -0
  43. package/cjs/loader/Loader.js.map +1 -1
  44. package/cjs/modal/Modal.js +28 -10
  45. package/cjs/modal/Modal.js.map +1 -1
  46. package/cjs/modal/ModalHeader.js +1 -1
  47. package/cjs/modal/ModalHeader.js.map +1 -1
  48. package/cjs/modal/ModalUtils.d.ts +5 -0
  49. package/cjs/modal/ModalUtils.js +9 -1
  50. package/cjs/modal/ModalUtils.js.map +1 -1
  51. package/cjs/modal/types.d.ts +8 -8
  52. package/cjs/pagination/Pagination.d.ts +3 -2
  53. package/cjs/pagination/Pagination.js.map +1 -1
  54. package/cjs/pagination/PaginationItem.d.ts +1 -1
  55. package/cjs/popover/Popover.d.ts +2 -1
  56. package/cjs/popover/Popover.js.map +1 -1
  57. package/cjs/read-more/ReadMore.d.ts +7 -7
  58. package/cjs/stepper/Step.d.ts +4 -4
  59. package/cjs/stepper/Stepper.d.ts +7 -5
  60. package/cjs/stepper/Stepper.js.map +1 -1
  61. package/cjs/table/AnimateHeight.d.ts +1 -1
  62. package/cjs/tabs/TabList.d.ts +1 -1
  63. package/cjs/tabs/Tabs.d.ts +7 -7
  64. package/cjs/timeline/Timeline.d.ts +6 -3
  65. package/cjs/timeline/Timeline.js +2 -1
  66. package/cjs/timeline/Timeline.js.map +1 -1
  67. package/cjs/timeline/period/index.d.ts +3 -2
  68. package/cjs/timeline/period/index.js.map +1 -1
  69. package/cjs/tooltip/Tooltip.d.ts +19 -12
  70. package/cjs/tooltip/Tooltip.js.map +1 -1
  71. package/esm/accordion/Accordion.d.ts +4 -4
  72. package/esm/alert/Alert.d.ts +12 -10
  73. package/esm/alert/Alert.js.map +1 -1
  74. package/esm/button/Button.d.ts +9 -8
  75. package/esm/button/Button.js.map +1 -1
  76. package/esm/chat/Chat.d.ts +6 -6
  77. package/esm/chips/Chips.d.ts +2 -2
  78. package/esm/copybutton/CopyButton.d.ts +14 -12
  79. package/esm/copybutton/CopyButton.js.map +1 -1
  80. package/esm/date/datepicker/types.d.ts +7 -6
  81. package/esm/date/hooks/useDatepicker.d.ts +4 -3
  82. package/esm/date/hooks/useDatepicker.js.map +1 -1
  83. package/esm/date/hooks/useMonthPicker.d.ts +4 -3
  84. package/esm/date/hooks/useMonthPicker.js.map +1 -1
  85. package/esm/date/monthpicker/types.d.ts +2 -1
  86. package/esm/date/parts/DateInput.d.ts +1 -1
  87. package/esm/expansion-card/ExpansionCardTitle.d.ts +1 -1
  88. package/esm/form/checkbox/CheckboxGroup.d.ts +3 -3
  89. package/esm/form/checkbox/types.d.ts +4 -4
  90. package/esm/form/combobox/types.d.ts +15 -15
  91. package/esm/form/error-summary/ErrorSummary.d.ts +5 -5
  92. package/esm/form/radio/RadioGroup.d.ts +1 -1
  93. package/esm/form/search/Search.d.ts +3 -2
  94. package/esm/form/search/Search.js.map +1 -1
  95. package/esm/form/select/Select.d.ts +9 -9
  96. package/esm/form/switch/Switch.d.ts +5 -5
  97. package/esm/form/textarea/Textarea.d.ts +5 -4
  98. package/esm/form/textarea/Textarea.js.map +1 -1
  99. package/esm/form/useFormField.d.ts +10 -8
  100. package/esm/form/useFormField.js.map +1 -1
  101. package/esm/layout/bleed/Bleed.d.ts +9 -1
  102. package/esm/layout/bleed/Bleed.js.map +1 -1
  103. package/esm/layout/box/Box.d.ts +5 -5
  104. package/esm/layout/grid/HGrid.d.ts +1 -3
  105. package/esm/layout/grid/HGrid.js.map +1 -1
  106. package/esm/layout/page/Page.d.ts +2 -2
  107. package/esm/layout/responsive/Responsive.d.ts +2 -4
  108. package/esm/layout/responsive/Responsive.js.map +1 -1
  109. package/esm/layout/stack/Stack.d.ts +18 -4
  110. package/esm/layout/stack/Stack.js.map +1 -1
  111. package/esm/list/types.d.ts +1 -1
  112. package/esm/loader/Loader.d.ts +1 -0
  113. package/esm/loader/Loader.js.map +1 -1
  114. package/esm/modal/Modal.js +29 -11
  115. package/esm/modal/Modal.js.map +1 -1
  116. package/esm/modal/ModalHeader.js +1 -1
  117. package/esm/modal/ModalHeader.js.map +1 -1
  118. package/esm/modal/ModalUtils.d.ts +5 -0
  119. package/esm/modal/ModalUtils.js +7 -0
  120. package/esm/modal/ModalUtils.js.map +1 -1
  121. package/esm/modal/types.d.ts +8 -8
  122. package/esm/pagination/Pagination.d.ts +3 -2
  123. package/esm/pagination/Pagination.js.map +1 -1
  124. package/esm/pagination/PaginationItem.d.ts +1 -1
  125. package/esm/popover/Popover.d.ts +2 -1
  126. package/esm/popover/Popover.js.map +1 -1
  127. package/esm/read-more/ReadMore.d.ts +7 -7
  128. package/esm/stepper/Step.d.ts +4 -4
  129. package/esm/stepper/Stepper.d.ts +7 -5
  130. package/esm/stepper/Stepper.js.map +1 -1
  131. package/esm/table/AnimateHeight.d.ts +1 -1
  132. package/esm/tabs/TabList.d.ts +1 -1
  133. package/esm/tabs/Tabs.d.ts +7 -7
  134. package/esm/timeline/Timeline.d.ts +6 -3
  135. package/esm/timeline/Timeline.js +2 -1
  136. package/esm/timeline/Timeline.js.map +1 -1
  137. package/esm/timeline/period/index.d.ts +3 -2
  138. package/esm/timeline/period/index.js.map +1 -1
  139. package/esm/tooltip/Tooltip.d.ts +19 -12
  140. package/esm/tooltip/Tooltip.js.map +1 -1
  141. package/package.json +3 -4
  142. package/src/accordion/Accordion.tsx +4 -4
  143. package/src/accordion/accordion.stories.tsx +0 -2
  144. package/src/alert/Alert.tsx +12 -10
  145. package/src/button/Button.tsx +9 -8
  146. package/src/chat/Chat.tsx +6 -6
  147. package/src/chips/Chips.tsx +2 -2
  148. package/src/copybutton/CopyButton.tsx +14 -12
  149. package/src/date/datepicker/datepicker.stories.tsx +0 -1
  150. package/src/date/datepicker/types.ts +7 -6
  151. package/src/date/hooks/useDatepicker.tsx +4 -3
  152. package/src/date/hooks/useMonthPicker.tsx +4 -3
  153. package/src/date/monthpicker/types.ts +2 -1
  154. package/src/date/parts/DateInput.tsx +1 -1
  155. package/src/expansion-card/ExpansionCardTitle.tsx +1 -1
  156. package/src/form/checkbox/CheckboxGroup.tsx +3 -3
  157. package/src/form/checkbox/types.ts +4 -4
  158. package/src/form/combobox/types.ts +15 -15
  159. package/src/form/error-summary/ErrorSummary.tsx +5 -5
  160. package/src/form/radio/RadioGroup.tsx +1 -1
  161. package/src/form/search/Search.tsx +3 -2
  162. package/src/form/select/Select.tsx +9 -9
  163. package/src/form/select/select.stories.tsx +32 -37
  164. package/src/form/switch/Switch.tsx +5 -5
  165. package/src/form/textarea/Textarea.tsx +5 -4
  166. package/src/form/useFormField.ts +10 -8
  167. package/src/layout/bleed/Bleed.tsx +9 -1
  168. package/src/layout/box/Box.tsx +5 -5
  169. package/src/layout/grid/HGrid.tsx +1 -3
  170. package/src/layout/page/Page.tsx +2 -2
  171. package/src/layout/responsive/Responsive.tsx +2 -4
  172. package/src/layout/stack/Stack.tsx +18 -4
  173. package/src/link/stories/link.stories.tsx +187 -96
  174. package/src/list/types.ts +1 -1
  175. package/src/loader/Loader.tsx +1 -0
  176. package/src/modal/Modal.tsx +49 -10
  177. package/src/modal/ModalHeader.tsx +1 -1
  178. package/src/modal/ModalUtils.ts +14 -0
  179. package/src/modal/types.ts +8 -8
  180. package/src/pagination/Pagination.tsx +3 -2
  181. package/src/pagination/PaginationItem.tsx +1 -1
  182. package/src/popover/Popover.tsx +2 -1
  183. package/src/read-more/ReadMore.tsx +7 -7
  184. package/src/stepper/Step.tsx +4 -4
  185. package/src/stepper/Stepper.tsx +7 -5
  186. package/src/table/AnimateHeight.tsx +1 -1
  187. package/src/tabs/TabList.tsx +1 -1
  188. package/src/tabs/Tabs.tsx +7 -7
  189. package/src/timeline/Timeline.tsx +6 -3
  190. package/src/timeline/period/index.tsx +3 -2
  191. package/src/tooltip/Tooltip.tsx +19 -12
@@ -13,11 +13,11 @@ import {
13
13
  } from "../utilities/types";
14
14
 
15
15
  export interface BoxProps extends React.HTMLAttributes<HTMLDivElement> {
16
- /** Background color. Accepts a color token. */
16
+ /** CSS `background-color` property. Accepts a color token. */
17
17
  background?: BackgroundToken;
18
- /** Border color. Accepts a color token. */
18
+ /** CSS `border-color` property. Accepts a color token. */
19
19
  borderColor?: BorderColorToken;
20
- /** Border radius. Accepts a radius token, or an object of radius tokens for different breakpoints.
20
+ /** CSS `border-radius` property. Accepts a radius token, or an object of radius tokens for different breakpoints.
21
21
  * @example
22
22
  * borderRadius='full'
23
23
  * borderRadius='0 full large small'
@@ -25,13 +25,13 @@ export interface BoxProps extends React.HTMLAttributes<HTMLDivElement> {
25
25
  */
26
26
  borderRadius?: ResponsiveProp<SpaceDelimitedAttribute<BorderRadiiToken>>;
27
27
  /**
28
- * Border-width. If this is not set there will be no border.
28
+ * CSS `border-width` property. If this is not set there will be no border.
29
29
  * @example
30
30
  * borderWidth='2'
31
31
  * borderWidth='1 2 3 4'
32
32
  */
33
33
  borderWidth?: SpaceDelimitedAttribute<"0" | "1" | "2" | "3" | "4" | "5">;
34
- /** Spacing around children. Accepts a spacing token or an object of spacing tokens for different breakpoints.
34
+ /** Padding around children. Accepts a spacing token or an object of spacing tokens for different breakpoints.
35
35
  * @example
36
36
  * padding='4'
37
37
  * padding={{xs: '2', sm: '3', md: '4', lg: '5', xl: '6'}}
@@ -6,13 +6,11 @@ import { ResponsiveProp, SpacingScale } from "../utilities/types";
6
6
  export interface HGridProps extends HTMLAttributes<HTMLDivElement> {
7
7
  children: React.ReactNode;
8
8
  /**
9
- * Number of columns to display. Can be a number, a string with a unit or tokens for spesific breakpoints.
9
+ * Number of columns to display. Can be a number, a string with a unit, or tokens for specific breakpoints.
10
10
  * Sets `grid-template-columns`, so `fr`, `minmax` etc. works.
11
11
  * @example
12
12
  * columns={{ sm: 1, md: 1, lg: "1fr auto", xl: "1fr auto"}}
13
- * @example
14
13
  * columns={3}
15
- * @example
16
14
  * columns="repeat(3, minmax(0, 1fr))"
17
15
  */
18
16
  columns?: ResponsiveProp<number | string>;
@@ -12,7 +12,7 @@ export interface PageProps extends React.HTMLAttributes<HTMLElement> {
12
12
  as?: "div" | "body";
13
13
  /**
14
14
  * Background color. Accepts a color token.
15
- * @default bg-default
15
+ * @default "bg-default"
16
16
  */
17
17
  background?: keyof typeof bgColors.a | "surface-subtle";
18
18
  /**
@@ -25,7 +25,7 @@ export interface PageProps extends React.HTMLAttributes<HTMLElement> {
25
25
  footerPosition?: "belowFold";
26
26
  /**
27
27
  * Adds a standardised padding of 4rem between content and footer
28
- * @default block-end
28
+ * @default "end"
29
29
  */
30
30
  contentBlockPadding?: "end" | "none";
31
31
  }
@@ -6,13 +6,11 @@ import { BreakpointsAlias } from "../utilities/types";
6
6
  export interface ResponsiveProps extends HTMLAttributes<HTMLDivElement> {
7
7
  children: React.ReactNode;
8
8
  /**
9
- * @example
10
- * above='md'
9
+ * Will show/hide element above breakpoint (inclusive)
11
10
  */
12
11
  above?: Exclude<BreakpointsAlias, "xs">;
13
12
  /**
14
- * @example
15
- * below='md'
13
+ * Will show/hide element below breakpoint (inclusive)
16
14
  */
17
15
  below?: Exclude<BreakpointsAlias, "xs">;
18
16
  /**
@@ -7,7 +7,11 @@ import { ResponsiveProp, SpacingScale } from "../utilities/types";
7
7
  export interface StackProps extends HTMLAttributes<HTMLDivElement> {
8
8
  children: React.ReactNode;
9
9
  /**
10
- * Justify-content
10
+ * CSS `justify-content` property.
11
+ *
12
+ * @example
13
+ * justify='center'
14
+ * justify={{xs: 'start', sm: 'center', md: 'end', lg: 'space-around', xl: 'space-between'}}
11
15
  */
12
16
  justify?: ResponsiveProp<
13
17
  | "start"
@@ -18,22 +22,32 @@ export interface StackProps extends HTMLAttributes<HTMLDivElement> {
18
22
  | "space-evenly"
19
23
  >;
20
24
  /**
21
- * Align-items
25
+ * CSS `align-items` property.
26
+ *
27
+ * @example
28
+ * align='center'
29
+ * align={{xs: 'start', sm: 'center', md: 'end', lg: 'baseline', xl: 'stretch'}}
22
30
  */
23
31
  align?: ResponsiveProp<"start" | "center" | "end" | "baseline" | "stretch">;
24
32
  /**
25
- * flex-wrap
33
+ * Sets the CSS `flex-wrap` property.
26
34
  */
27
35
  wrap?: boolean;
28
36
  /**
37
+ * CSS `gap` property.
38
+ *
29
39
  * @example
30
40
  * gap='4'
31
41
  * gap={{xs: '2', sm: '3', md: '4', lg: '5', xl: '6'}}
32
42
  */
33
43
  gap?: ResponsiveProp<SpacingScale>;
34
44
  /**
35
- * flex-direction
45
+ * CSS `flex-direction` property.
36
46
  * @default "row"
47
+ *
48
+ * @example
49
+ * direction='row'
50
+ * direction={{xs: 'row', sm: 'column'}}
37
51
  */
38
52
  direction?: ResponsiveProp<"row" | "column">;
39
53
  }
@@ -1,15 +1,22 @@
1
+ import { Meta } from "@storybook/react";
1
2
  import React from "react";
2
3
  import { PlusCircleFillIcon } from "@navikt/aksel-icons";
3
4
  import { Alert } from "../../alert";
4
5
  import { ConfirmationPanel } from "../../form/confirmation-panel";
6
+ import { Box } from "../../layout/box";
7
+ import { VStack } from "../../layout/stack";
5
8
  import { BodyLong } from "../../typography";
6
9
  import Link from "../Link";
7
10
  import { RandomIcon } from "./RandomIcon";
8
11
 
9
- export default {
12
+ const meta: Meta<typeof Link> = {
10
13
  title: "ds-react/Link",
11
14
  component: Link,
15
+ parameters: {
16
+ chromatic: { disable: true },
17
+ },
12
18
  };
19
+ export default meta;
13
20
 
14
21
  const LinkWrapper = ({
15
22
  children = "Ex aliqua incididunt",
@@ -27,53 +34,38 @@ const LinkWrapper = ({
27
34
  variant={variant as "action" | "neutral" | "subtle"}
28
35
  inlineText={inlineText}
29
36
  >
30
- {iconLeft && (
31
- <>
32
- <RandomIcon />{" "}
33
- </>
34
- )}
37
+ {iconLeft && <RandomIcon />}
35
38
  {children}
36
- {iconRight && (
37
- <>
38
- {" "}
39
- <RandomIcon />
40
- </>
41
- )}
39
+ {iconRight && <RandomIcon />}
42
40
  </Link>{" "}
43
41
  </>
44
42
  );
45
43
 
46
44
  export const Default = {
47
- render: ({ icon, inline }) => {
45
+ render: ({ icon, inline, underline }) => {
48
46
  const LinkD = () => (
49
- <>
50
- {" "}
51
- <Link href="#" underline={!inline} inlineText={inline}>
52
- {icon && <PlusCircleFillIcon />}Ex aliqua incididunt
53
- {icon && <PlusCircleFillIcon />}
54
- </Link>{" "}
55
- </>
47
+ <Link href="#" underline={underline} inlineText={inline}>
48
+ {icon && <PlusCircleFillIcon />}Ex aliqua incididunt
49
+ {icon && <PlusCircleFillIcon />}
50
+ </Link>
56
51
  );
57
52
 
58
53
  if (inline) {
59
54
  return (
60
- <div
61
- className="colgap"
62
- style={{
63
- width: "800px",
64
- border: "1px solid black",
65
- borderRadius: "8px",
66
- }}
55
+ <Box
56
+ borderWidth="1"
57
+ borderRadius="large"
58
+ padding="4"
59
+ style={{ maxWidth: "800px" }}
67
60
  >
68
61
  <BodyLong>
69
- Incididunt laborum nisi nisi Lorem
70
- <LinkD />
71
- in. Laborum aute fugiat officia adipisicing non veniam dolor nulla
72
- non ex consectetur fugiat eiusmod aute. Culpa sit aute est duis
73
- minim in in voluptate velit fugiat. Laboris est id deserunt ut ea
74
- Lorem eu. Esse elit laboris aute commodo sint laborum fugiat aliqua.
62
+ Incididunt laborum nisi nisi Lorem <LinkD /> in. Laborum aute fugiat
63
+ officia adipisicing non veniam dolor nulla non ex consectetur fugiat
64
+ eiusmod aute. Culpa sit aute est duis minim in in voluptate velit
65
+ fugiat. Laboris est id deserunt ut ea Lorem eu. Esse elit laboris
66
+ aute commodo sint laborum fugiat aliqua.
75
67
  </BodyLong>
76
- </div>
68
+ </Box>
77
69
  );
78
70
  }
79
71
  return <LinkD />;
@@ -82,22 +74,21 @@ export const Default = {
82
74
  args: {
83
75
  icon: false,
84
76
  inline: false,
77
+ underline: true,
85
78
  },
86
79
  };
87
80
 
88
81
  export const InlineInsideBodyLong = {
89
82
  render: ({ iconLeft, iconRight }) => {
90
83
  return (
91
- <div
92
- className="colgap"
93
- style={{
94
- width: "800px",
95
- border: "1px solid black",
96
- borderRadius: "8px",
97
- }}
84
+ <Box
85
+ borderWidth="1"
86
+ borderRadius="large"
87
+ padding="4"
88
+ style={{ width: "800px" }}
98
89
  >
99
90
  <style>{`.storybook-custom-spacing { white-space: pre;}`}</style>
100
- <BodyLong>
91
+ <BodyLong spacing>
101
92
  <LinkWrapper underline iconLeft={iconLeft} iconRight={iconRight} />
102
93
  Eiusmod aute.
103
94
  <LinkWrapper underline iconLeft={iconLeft} iconRight={iconRight} />
@@ -119,7 +110,7 @@ export const InlineInsideBodyLong = {
119
110
  </LinkWrapper>
120
111
  {" "}spacing.
121
112
  </BodyLong>
122
- </div>
113
+ </Box>
123
114
  );
124
115
  },
125
116
  args: {
@@ -128,86 +119,186 @@ export const InlineInsideBodyLong = {
128
119
  },
129
120
  };
130
121
 
131
- const DemoLink = () => (
122
+ export const Varianter = {
123
+ render: ({ iconLeft, iconRight }) => {
124
+ return (
125
+ <VStack gap="3">
126
+ {["action", "neutral", "subtle"].map((variant) => (
127
+ <div key={variant}>
128
+ <LinkWrapper
129
+ iconLeft={iconLeft}
130
+ iconRight={iconRight}
131
+ variant={variant}
132
+ />
133
+ </div>
134
+ ))}
135
+ </VStack>
136
+ );
137
+ },
138
+ args: {
139
+ iconLeft: false,
140
+ iconRight: false,
141
+ },
142
+ };
143
+
144
+ const LinkWithIcon = () => (
132
145
  <Link href="#">
133
- <PlusCircleFillIcon aria-hidden /> Ex aliqua incididunt{" "}
146
+ <PlusCircleFillIcon aria-hidden />
147
+ Ex aliqua incididunt
134
148
  <PlusCircleFillIcon aria-hidden />
135
149
  </Link>
136
150
  );
137
151
 
138
- export const Icon = () => <DemoLink />;
152
+ export const Icon = () => <LinkWithIcon />;
153
+
154
+ const Variants = () => (
155
+ <VStack gap="3">
156
+ {["action", "neutral", "subtle"].map((variant) => (
157
+ <div key={variant}>
158
+ <LinkWrapper variant={variant} />
159
+ </div>
160
+ ))}
161
+ </VStack>
162
+ );
139
163
 
140
- export const InAlert = () => {
141
- return (
164
+ export const Chromatic = () => (
165
+ <>
166
+ <h2>Default</h2>
167
+ <Link href="#">Ex aliqua incididunt</Link>
168
+
169
+ <h2>With icon</h2>
170
+ <LinkWithIcon />
171
+
172
+ <h2>Variants (no underline)</h2>
173
+ <Variants />
174
+
175
+ <h2>Inline</h2>
176
+ <BodyLong style={{ width: 500 }}>
177
+ Culpa sit aute est duis minim in in voluptate{" "}
178
+ <Link href="#" inlineText>
179
+ dette er en veldig lang lenke som brekker over flere linjer
180
+ <PlusCircleFillIcon aria-hidden />
181
+ </Link>{" "}
182
+ Culpa sit aute est duis minim in in voluptate velit Incididunt laborum
183
+ nisi nisi{" "}
184
+ <Link href="#" inlineText>
185
+ dette er en veldig lang lenke som brekker over flere linjer
186
+ </Link>{" "}
187
+ Lorem officia adipisicing non veniam occaecat commodo id ad aliquip.
188
+ </BodyLong>
189
+
190
+ <h2>In Alert</h2>
142
191
  <div className="colgap">
143
192
  <Alert variant="info">
144
- <DemoLink />
193
+ <LinkWithIcon />
145
194
  </Alert>
146
195
  <Alert variant="success">
147
- <DemoLink />
196
+ <LinkWithIcon />
148
197
  </Alert>
149
198
  <Alert variant="warning">
150
- <DemoLink />
199
+ <LinkWithIcon />
151
200
  </Alert>
152
201
  <Alert variant="error">
153
- <DemoLink />
202
+ <LinkWithIcon />
154
203
  </Alert>
155
204
  </div>
156
- );
157
- };
158
205
 
159
- export const InConfirmationPanel = () => {
160
- return (
206
+ <h2>In ConfirmationPanel</h2>
161
207
  <div className="colgap">
162
208
  <ConfirmationPanel label="demo">
163
- <DemoLink />
209
+ <LinkWithIcon />
164
210
  </ConfirmationPanel>
165
211
  <ConfirmationPanel checked label="demo">
166
- <DemoLink />
212
+ <LinkWithIcon />
167
213
  </ConfirmationPanel>
168
214
  <ConfirmationPanel error="demo" label="demo">
169
- <DemoLink />
215
+ <LinkWithIcon />
216
+ </ConfirmationPanel>
217
+ </div>
218
+ </>
219
+ );
220
+ Chromatic.parameters = { chromatic: { disable: false } };
221
+
222
+ export const ChromaticHover = () => (
223
+ <>
224
+ <h2>With icon</h2>
225
+ <LinkWithIcon />
226
+
227
+ <h2>Variants (no underline)</h2>
228
+ <Variants />
229
+
230
+ <h2>In Alert</h2>
231
+ <div className="colgap">
232
+ <Alert variant="info">
233
+ <LinkWithIcon />
234
+ </Alert>
235
+ </div>
236
+
237
+ <h2>In ConfirmationPanel</h2>
238
+ <div className="colgap">
239
+ <ConfirmationPanel checked label="demo">
240
+ <LinkWithIcon />
170
241
  </ConfirmationPanel>
171
242
  </div>
172
- );
243
+ </>
244
+ );
245
+ ChromaticHover.parameters = {
246
+ chromatic: { disable: false },
247
+ pseudo: { hover: true },
173
248
  };
174
249
 
175
- export const Variants = {
176
- render: ({ iconLeft, iconRight }) => {
177
- return (
178
- <div className="colgap">
179
- {["action", "neutral", "subtle"].map((variant) => (
180
- <>
181
- <div>
182
- <LinkWrapper
183
- iconLeft={iconLeft}
184
- iconRight={iconRight}
185
- variant={variant}
186
- />
187
- </div>
188
- </>
189
- ))}
190
- </div>
191
- );
192
- },
193
- args: {
194
- iconLeft: false,
195
- iconRight: false,
196
- },
250
+ export const ChromaticFocusVisible = () => (
251
+ <>
252
+ <h2>With icon</h2>
253
+ <LinkWithIcon />
254
+
255
+ <h2>Variants (no underline)</h2>
256
+ <Variants />
257
+
258
+ <h2>In Alert</h2>
259
+ <div className="colgap">
260
+ <Alert variant="info">
261
+ <LinkWithIcon />
262
+ </Alert>
263
+ </div>
264
+
265
+ <h2>In ConfirmationPanel</h2>
266
+ <div className="colgap">
267
+ <ConfirmationPanel checked label="demo">
268
+ <LinkWithIcon />
269
+ </ConfirmationPanel>
270
+ </div>
271
+ </>
272
+ );
273
+ ChromaticFocusVisible.parameters = {
274
+ chromatic: { disable: false },
275
+ pseudo: { focusVisible: true },
197
276
  };
198
277
 
199
- export const InlineLink = {
200
- render: () => (
201
- <BodyLong>
202
- Officia incididunt Culpa sit aute est duis minim in in voluptate velit
203
- Incididunt laborum nisi nisi Lorem officia adipisicing non veniam{" "}
204
- <Link href="#" inlineText={true}>
205
- lenke til ny side
206
- <PlusCircleFillIcon aria-hidden />
207
- </Link>{" "}
208
- Culpa sit aute est duis minim in in voluptate velit Incididunt laborum
209
- nisi nisi Lorem officia adipisicing non veniam occaecat commodo id ad
210
- aliquip.
211
- </BodyLong>
212
- ),
278
+ export const ChromaticActive = () => (
279
+ <>
280
+ <h2>With icon</h2>
281
+ <LinkWithIcon />
282
+
283
+ <h2>Variants (no underline)</h2>
284
+ <Variants />
285
+
286
+ <h2>In Alert</h2>
287
+ <div className="colgap">
288
+ <Alert variant="info">
289
+ <LinkWithIcon />
290
+ </Alert>
291
+ </div>
292
+
293
+ <h2>In ConfirmationPanel</h2>
294
+ <div className="colgap">
295
+ <ConfirmationPanel checked label="demo">
296
+ <LinkWithIcon />
297
+ </ConfirmationPanel>
298
+ </div>
299
+ </>
300
+ );
301
+ ChromaticActive.parameters = {
302
+ chromatic: { disable: false },
303
+ pseudo: { active: true },
213
304
  };
package/src/list/types.ts CHANGED
@@ -20,7 +20,7 @@ export interface ListProps extends React.HTMLAttributes<HTMLDivElement> {
20
20
  headingTag?: React.ElementType<any>;
21
21
  /**
22
22
  * Changes padding, height and font-size
23
- * @default medium
23
+ * @default "medium"
24
24
  */
25
25
  size?: "medium" | "small";
26
26
  }
@@ -35,6 +35,7 @@ export interface LoaderProps extends Omit<SVGProps<SVGSVGElement>, "ref"> {
35
35
  /**
36
36
  * Allows getting a ref to the component instance.
37
37
  * Once the component unmounts, React will set `ref.current` to `null` (or call the ref with `null` if you passed a callback ref).
38
+ *
38
39
  * @see https://react.dev/learn/referencing-values-with-refs#refs-and-the-dom
39
40
  */
40
41
  ref?: React.Ref<SVGSVGElement>;
@@ -12,7 +12,12 @@ import { ModalContextProvider, useModalContext } from "./Modal.context";
12
12
  import ModalBody from "./ModalBody";
13
13
  import ModalFooter from "./ModalFooter";
14
14
  import ModalHeader from "./ModalHeader";
15
- import { getCloseHandler, useBodyScrollLock } from "./ModalUtils";
15
+ import {
16
+ MouseCoordinates,
17
+ coordsAreInside,
18
+ getCloseHandler,
19
+ useBodyScrollLock,
20
+ } from "./ModalUtils";
16
21
  import dialogPolyfill, { needPolyfill } from "./dialog-polyfill";
17
22
  import { ModalProps } from "./types";
18
23
 
@@ -86,6 +91,7 @@ export const Modal = forwardRef<HTMLDialogElement, ModalProps>(
86
91
  "aria-labelledby": ariaLabelledby,
87
92
  style,
88
93
  onClick,
94
+ onMouseDown,
89
95
  ...rest
90
96
  }: ModalProps,
91
97
  ref,
@@ -146,22 +152,46 @@ export const Modal = forwardRef<HTMLDialogElement, ModalProps>(
146
152
  ...(!isWidthPreset ? { width } : {}),
147
153
  };
148
154
 
155
+ const mouseClickStart = useRef<MouseCoordinates>({
156
+ clientX: 0,
157
+ clientY: 0,
158
+ });
159
+ const handleModalMouseDown: React.MouseEventHandler<HTMLDialogElement> = (
160
+ event,
161
+ ) => {
162
+ mouseClickStart.current = event;
163
+ };
164
+
165
+ const shouldHandleModalClick = closeOnBackdropClick && !needPolyfill;
166
+
149
167
  /**
150
- * @note `closeOnBackdropClick` has issues on polyfill when nesting modals (DatePicker)
168
+ * `closeOnBackdropClick` has issues on polyfill when nesting modals (DatePicker)
151
169
  */
152
- const handleModalClick = (event: React.MouseEvent<HTMLDialogElement>) => {
170
+ const handleModalClick = (
171
+ endEvent: React.MouseEvent<HTMLDialogElement>,
172
+ ) => {
173
+ if (endEvent.target !== modalRef.current) {
174
+ return;
175
+ }
176
+
177
+ const modalRect = modalRef.current.getBoundingClientRect();
178
+
153
179
  if (
154
- closeOnBackdropClick &&
155
- !needPolyfill &&
156
- event.target === modalRef.current &&
157
- (!onBeforeClose || onBeforeClose() !== false)
180
+ coordsAreInside(mouseClickStart.current, modalRect) ||
181
+ coordsAreInside(endEvent, modalRect)
158
182
  ) {
159
- modalRef.current.close();
183
+ return;
184
+ }
185
+
186
+ if (onBeforeClose !== undefined && onBeforeClose() === false) {
187
+ return;
160
188
  }
189
+
190
+ modalRef.current.close();
161
191
  };
162
192
 
163
193
  /**
164
- * @note onCancel fires when you press `Esc`
194
+ * onCancel fires when you press `Esc`
165
195
  */
166
196
  const handleModalCancel = (
167
197
  event: React.SyntheticEvent<HTMLDialogElement, Event>,
@@ -182,7 +212,16 @@ export const Modal = forwardRef<HTMLDialogElement, ModalProps>(
182
212
  className={mergedClassName}
183
213
  style={mergedStyle}
184
214
  onCancel={composeEventHandlers(onCancel, handleModalCancel)}
185
- onClick={composeEventHandlers(onClick, handleModalClick)}
215
+ onClick={
216
+ shouldHandleModalClick
217
+ ? composeEventHandlers(onClick, handleModalClick)
218
+ : onClick
219
+ }
220
+ onMouseDown={
221
+ shouldHandleModalClick
222
+ ? composeEventHandlers(onMouseDown, handleModalMouseDown)
223
+ : onMouseDown
224
+ }
186
225
  aria-labelledby={mergedAriaLabelledBy}
187
226
  >
188
227
  <ModalContextProvider
@@ -26,7 +26,7 @@ const ModalHeader = forwardRef<HTMLDivElement, ModalHeaderProps>(
26
26
  size="small"
27
27
  variant="tertiary-neutral"
28
28
  onClick={context.closeHandler}
29
- icon={<XMarkIcon title="Lukk modalvindu" />}
29
+ icon={<XMarkIcon title="Lukk" />}
30
30
  />
31
31
  )}
32
32
  {children}
@@ -1,6 +1,20 @@
1
1
  import React from "react";
2
2
  import type { ModalProps } from "./types";
3
3
 
4
+ export interface MouseCoordinates {
5
+ clientX: number;
6
+ clientY: number;
7
+ }
8
+
9
+ export const coordsAreInside = (
10
+ { clientX, clientY }: MouseCoordinates,
11
+ { left, top, right, bottom }: DOMRect,
12
+ ) => {
13
+ if (clientX < left || clientY < top) return false;
14
+ if (clientX > right || clientY > bottom) return false;
15
+ return true;
16
+ };
17
+
4
18
  export function getCloseHandler(
5
19
  modalRef: React.RefObject<HTMLDialogElement>,
6
20
  header: ModalProps["header"],