@navikt/ds-react 4.6.0 → 4.7.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 (133) hide show
  1. package/_docs.json +1711 -169
  2. package/cjs/chips/Chips.js +1 -2
  3. package/cjs/date/DateInput.js +1 -0
  4. package/cjs/form/Select.js +1 -0
  5. package/cjs/form/TextField.js +1 -0
  6. package/cjs/form/Textarea.js +1 -0
  7. package/cjs/form/checkbox/Checkbox.js +1 -1
  8. package/cjs/form/combobox/ClearButton.js +27 -0
  9. package/cjs/form/combobox/Combobox.js +78 -0
  10. package/cjs/form/combobox/ComboboxProvider.js +99 -0
  11. package/cjs/form/combobox/ComboboxWrapper.js +51 -0
  12. package/cjs/form/combobox/FilteredOptions/CheckIcon.js +11 -0
  13. package/cjs/form/combobox/FilteredOptions/FilteredOptions.js +46 -0
  14. package/cjs/form/combobox/FilteredOptions/filteredOptionsContext.js +208 -0
  15. package/cjs/form/combobox/Input/Input.js +143 -0
  16. package/cjs/form/combobox/Input/inputContext.js +86 -0
  17. package/cjs/form/combobox/SelectedOptions/SelectedOptions.js +27 -0
  18. package/cjs/form/combobox/SelectedOptions/selectedOptionsContext.js +107 -0
  19. package/cjs/form/combobox/ToggleListButton.js +36 -0
  20. package/cjs/form/combobox/customOptionsContext.js +56 -0
  21. package/cjs/form/combobox/index.js +8 -0
  22. package/cjs/form/combobox/package.json +6 -0
  23. package/cjs/form/combobox/types.js +2 -0
  24. package/cjs/form/index.js +3 -1
  25. package/cjs/timeline/AxisLabels.js +12 -12
  26. package/cjs/timeline/Timeline.js +2 -2
  27. package/cjs/util/usePrevious.js +18 -0
  28. package/esm/chips/Chips.js +1 -2
  29. package/esm/chips/Chips.js.map +1 -1
  30. package/esm/date/DateInput.js +1 -0
  31. package/esm/date/DateInput.js.map +1 -1
  32. package/esm/date/datepicker/TableHead.d.ts +1 -0
  33. package/esm/form/Fieldset/useFieldset.d.ts +1 -1
  34. package/esm/form/Select.js +1 -0
  35. package/esm/form/Select.js.map +1 -1
  36. package/esm/form/TextField.js +1 -0
  37. package/esm/form/TextField.js.map +1 -1
  38. package/esm/form/Textarea.js +1 -0
  39. package/esm/form/Textarea.js.map +1 -1
  40. package/esm/form/checkbox/Checkbox.js +1 -1
  41. package/esm/form/checkbox/Checkbox.js.map +1 -1
  42. package/esm/form/checkbox/useCheckbox.d.ts +4 -4
  43. package/esm/form/combobox/ClearButton.d.ts +7 -0
  44. package/esm/form/combobox/ClearButton.js +21 -0
  45. package/esm/form/combobox/ClearButton.js.map +1 -0
  46. package/esm/form/combobox/Combobox.d.ts +4 -0
  47. package/esm/form/combobox/Combobox.js +50 -0
  48. package/esm/form/combobox/Combobox.js.map +1 -0
  49. package/esm/form/combobox/ComboboxProvider.d.ts +26 -0
  50. package/esm/form/combobox/ComboboxProvider.js +72 -0
  51. package/esm/form/combobox/ComboboxProvider.js.map +1 -0
  52. package/esm/form/combobox/ComboboxWrapper.d.ts +14 -0
  53. package/esm/form/combobox/ComboboxWrapper.js +24 -0
  54. package/esm/form/combobox/ComboboxWrapper.js.map +1 -0
  55. package/esm/form/combobox/FilteredOptions/CheckIcon.d.ts +3 -0
  56. package/esm/form/combobox/FilteredOptions/CheckIcon.js +7 -0
  57. package/esm/form/combobox/FilteredOptions/CheckIcon.js.map +1 -0
  58. package/esm/form/combobox/FilteredOptions/FilteredOptions.d.ts +3 -0
  59. package/esm/form/combobox/FilteredOptions/FilteredOptions.js +42 -0
  60. package/esm/form/combobox/FilteredOptions/FilteredOptions.js.map +1 -0
  61. package/esm/form/combobox/FilteredOptions/filteredOptionsContext.d.ts +27 -0
  62. package/esm/form/combobox/FilteredOptions/filteredOptionsContext.js +178 -0
  63. package/esm/form/combobox/FilteredOptions/filteredOptionsContext.js.map +1 -0
  64. package/esm/form/combobox/Input/Input.d.ts +10 -0
  65. package/esm/form/combobox/Input/Input.js +116 -0
  66. package/esm/form/combobox/Input/Input.js.map +1 -0
  67. package/esm/form/combobox/Input/inputContext.d.ts +19 -0
  68. package/esm/form/combobox/Input/inputContext.js +59 -0
  69. package/esm/form/combobox/Input/inputContext.js.map +1 -0
  70. package/esm/form/combobox/SelectedOptions/SelectedOptions.d.ts +8 -0
  71. package/esm/form/combobox/SelectedOptions/SelectedOptions.js +23 -0
  72. package/esm/form/combobox/SelectedOptions/SelectedOptions.js.map +1 -0
  73. package/esm/form/combobox/SelectedOptions/selectedOptionsContext.d.ts +17 -0
  74. package/esm/form/combobox/SelectedOptions/selectedOptionsContext.js +77 -0
  75. package/esm/form/combobox/SelectedOptions/selectedOptionsContext.js.map +1 -0
  76. package/esm/form/combobox/ToggleListButton.d.ts +6 -0
  77. package/esm/form/combobox/ToggleListButton.js +11 -0
  78. package/esm/form/combobox/ToggleListButton.js.map +1 -0
  79. package/esm/form/combobox/customOptionsContext.d.ts +11 -0
  80. package/esm/form/combobox/customOptionsContext.js +29 -0
  81. package/esm/form/combobox/customOptionsContext.js.map +1 -0
  82. package/esm/form/combobox/index.d.ts +2 -0
  83. package/esm/form/combobox/index.js +2 -0
  84. package/esm/form/combobox/index.js.map +1 -0
  85. package/esm/form/combobox/types.d.ts +119 -0
  86. package/esm/form/combobox/types.js +2 -0
  87. package/esm/form/combobox/types.js.map +1 -0
  88. package/esm/form/index.d.ts +1 -0
  89. package/esm/form/index.js +1 -0
  90. package/esm/form/index.js.map +1 -1
  91. package/esm/form/radio/useRadio.d.ts +4 -4
  92. package/esm/form/useFormField.d.ts +11 -10
  93. package/esm/form/useFormField.js.map +1 -1
  94. package/esm/timeline/AxisLabels.d.ts +7 -5
  95. package/esm/timeline/AxisLabels.js +12 -12
  96. package/esm/timeline/AxisLabels.js.map +1 -1
  97. package/esm/timeline/Timeline.d.ts +6 -0
  98. package/esm/timeline/Timeline.js +2 -2
  99. package/esm/timeline/Timeline.js.map +1 -1
  100. package/esm/timeline/utils/types.external.d.ts +5 -0
  101. package/esm/util/usePrevious.d.ts +2 -0
  102. package/esm/util/usePrevious.js +17 -0
  103. package/esm/util/usePrevious.js.map +1 -0
  104. package/package.json +2 -2
  105. package/src/chips/Chips.tsx +1 -1
  106. package/src/date/DateInput.tsx +1 -0
  107. package/src/form/Select.tsx +1 -0
  108. package/src/form/TextField.tsx +2 -0
  109. package/src/form/Textarea.tsx +1 -0
  110. package/src/form/checkbox/Checkbox.tsx +5 -1
  111. package/src/form/combobox/ClearButton.tsx +29 -0
  112. package/src/form/combobox/Combobox.tsx +136 -0
  113. package/src/form/combobox/ComboboxProvider.tsx +99 -0
  114. package/src/form/combobox/ComboboxWrapper.tsx +63 -0
  115. package/src/form/combobox/FilteredOptions/CheckIcon.tsx +23 -0
  116. package/src/form/combobox/FilteredOptions/FilteredOptions.tsx +106 -0
  117. package/src/form/combobox/FilteredOptions/filteredOptionsContext.tsx +266 -0
  118. package/src/form/combobox/Input/Input.tsx +170 -0
  119. package/src/form/combobox/Input/inputContext.tsx +127 -0
  120. package/src/form/combobox/SelectedOptions/SelectedOptions.tsx +45 -0
  121. package/src/form/combobox/SelectedOptions/selectedOptionsContext.tsx +147 -0
  122. package/src/form/combobox/ToggleListButton.tsx +37 -0
  123. package/src/form/combobox/combobox.stories.tsx +413 -0
  124. package/src/form/combobox/combobox.test.tsx +123 -0
  125. package/src/form/combobox/customOptionsContext.tsx +57 -0
  126. package/src/form/combobox/index.ts +2 -0
  127. package/src/form/combobox/types.ts +122 -0
  128. package/src/form/index.ts +1 -0
  129. package/src/form/useFormField.ts +19 -1
  130. package/src/timeline/AxisLabels.tsx +23 -13
  131. package/src/timeline/Timeline.tsx +18 -2
  132. package/src/timeline/utils/types.external.ts +6 -0
  133. package/src/util/usePrevious.ts +19 -0
package/src/form/index.ts CHANGED
@@ -17,6 +17,7 @@ export {
17
17
  type RadioProps,
18
18
  } from "./radio";
19
19
  export { Search, type SearchClearEvent, type SearchProps } from "./search";
20
+ export { Combobox as UNSAFE_Combobox, type ComboboxProps } from "./combobox";
20
21
  export { default as Select, type SelectProps } from "./Select";
21
22
  export { default as Switch, type SwitchProps } from "./Switch";
22
23
  export { Counter, default as Textarea, type TextareaProps } from "./Textarea";
@@ -35,10 +35,28 @@ export interface FormFieldProps {
35
35
  readOnly?: boolean;
36
36
  }
37
37
 
38
+ export interface FormFieldType {
39
+ showErrorMsg: boolean;
40
+ hasError: boolean;
41
+ errorId: string;
42
+ inputDescriptionId: string;
43
+ size: "small" | "medium";
44
+ inputProps: {
45
+ id: string;
46
+ "aria-invalid"?: boolean;
47
+ "aria-describedby"?: string;
48
+ disabled?: boolean;
49
+ };
50
+ readOnly?: boolean;
51
+ }
52
+
38
53
  /**
39
54
  * Handles props and their state for various form-fields in context with Fieldset
40
55
  */
41
- export const useFormField = (props: FormFieldProps, prefix: string) => {
56
+ export const useFormField = (
57
+ props: FormFieldProps,
58
+ prefix: string
59
+ ): FormFieldType => {
42
60
  const { size, error, errorId: propErrorId } = props;
43
61
 
44
62
  const fieldset = useContext(FieldsetContext);
@@ -19,13 +19,14 @@ import React from "react";
19
19
  import { useTimelineContext } from "./hooks/useTimelineContext";
20
20
  import { isVisible } from "./utils";
21
21
  import { horizontalPositionAndWidth } from "./utils/calc";
22
- import { AxisLabel } from "./utils/types.external";
22
+ import { AxisLabel, AxisLabelTemplates } from "./utils/types.external";
23
23
 
24
24
  export const dayLabels = (
25
25
  start: Date,
26
26
  end: Date,
27
27
  totalDays: number,
28
- direction: "left" | "right"
28
+ direction: "left" | "right",
29
+ template: string = "dd.MM"
29
30
  ): AxisLabel[] => {
30
31
  const increment = Math.ceil(totalDays / 10);
31
32
  const lastDay = startOfDay(end);
@@ -43,7 +44,7 @@ export const dayLabels = (
43
44
  return {
44
45
  direction: direction,
45
46
  horizontalPosition: horizontalPosition,
46
- label: format(day, "dd.MM", { locale: nbLocale }),
47
+ label: format(day, template, { locale: nbLocale }),
47
48
  date: day,
48
49
  width: width,
49
50
  };
@@ -54,7 +55,8 @@ export const dayLabels = (
54
55
  export const monthLabels = (
55
56
  start: Date,
56
57
  end: Date,
57
- direction: "left" | "right"
58
+ direction: "left" | "right",
59
+ template: string = "MMM yy"
58
60
  ): AxisLabel[] => {
59
61
  const startMonth = startOfMonth(start);
60
62
  const endMonth = endOfMonth(end);
@@ -70,7 +72,7 @@ export const monthLabels = (
70
72
  return {
71
73
  direction: direction,
72
74
  horizontalPosition: horizontalPosition,
73
- label: format(month, "MMM yy", { locale: nbLocale }),
75
+ label: format(month, template, { locale: nbLocale }),
74
76
  date: month,
75
77
  width: width,
76
78
  };
@@ -80,7 +82,8 @@ export const monthLabels = (
80
82
  export const yearLabels = (
81
83
  start: Date,
82
84
  end: Date,
83
- direction: "left" | "right"
85
+ direction: "left" | "right",
86
+ template: string = "yyyy"
84
87
  ): AxisLabel[] => {
85
88
  const firstYear = startOfYear(start);
86
89
  const lastYear = endOfYear(end);
@@ -96,7 +99,7 @@ export const yearLabels = (
96
99
  return {
97
100
  direction: direction,
98
101
  horizontalPosition: horizontalPosition,
99
- label: year.getFullYear().toString(),
102
+ label: format(year, template, { locale: nbLocale }),
100
103
  date: year,
101
104
  width: width,
102
105
  };
@@ -106,21 +109,28 @@ export const yearLabels = (
106
109
  const axisLabels = (
107
110
  start: Date,
108
111
  end: Date,
109
- direction: "left" | "right"
112
+ direction: "left" | "right",
113
+ templates?: AxisLabelTemplates
110
114
  ): AxisLabel[] => {
111
115
  const totalDays = differenceInDays(end, start);
112
116
  if (totalDays < 40) {
113
- return dayLabels(start, end, totalDays, direction);
117
+ return dayLabels(start, end, totalDays, direction, templates?.day);
114
118
  } else if (totalDays < 370) {
115
- return monthLabels(start, end, direction);
119
+ return monthLabels(start, end, direction, templates?.month);
116
120
  } else {
117
- return yearLabels(start, end, direction);
121
+ return yearLabels(start, end, direction, templates?.year);
118
122
  }
119
123
  };
120
124
 
121
- export const AxisLabels = () => {
125
+ export const AxisLabels = ({
126
+ templates,
127
+ }: {
128
+ templates?: AxisLabelTemplates;
129
+ }) => {
122
130
  const { endDate, startDate, direction } = useTimelineContext();
123
- const labels = axisLabels(startDate, endDate, direction).filter(isVisible);
131
+ const labels = axisLabels(startDate, endDate, direction, templates).filter(
132
+ isVisible
133
+ );
124
134
 
125
135
  return (
126
136
  <div className="navds-timeline__axislabels" aria-hidden="true">
@@ -13,6 +13,7 @@ import Pin, { PinType } from "./Pin";
13
13
  import TimelineRow, { TimelineRowType } from "./TimelineRow";
14
14
  import { parseRows } from "./utils/timeline";
15
15
  import Zoom, { ZoomType } from "./zoom";
16
+ import { AxisLabelTemplates } from "./utils/types.external";
16
17
 
17
18
  export interface TimelineProps extends React.HTMLAttributes<HTMLDivElement> {
18
19
  children: React.ReactNode;
@@ -33,6 +34,11 @@ export interface TimelineProps extends React.HTMLAttributes<HTMLDivElement> {
33
34
  * @default "left"
34
35
  */
35
36
  direction?: "left" | "right";
37
+ /**
38
+ * Templates for label texts. The templates are passed to the date-fns `format` function.
39
+ * Defaults to { day: "dd.MM", month: "MMM yy", year: "yyyy" }.
40
+ */
41
+ axisLabelTemplates?: AxisLabelTemplates;
36
42
  }
37
43
 
38
44
  interface TimelineComponent
@@ -74,7 +80,17 @@ interface TimelineComponent
74
80
  * ```
75
81
  */
76
82
  export const Timeline = forwardRef<HTMLDivElement, TimelineProps>(
77
- ({ children, startDate, endDate, direction = "left", ...rest }, ref) => {
83
+ (
84
+ {
85
+ children,
86
+ startDate,
87
+ endDate,
88
+ direction = "left",
89
+ axisLabelTemplates,
90
+ ...rest
91
+ },
92
+ ref
93
+ ) => {
78
94
  const isMultipleRows = Array.isArray(children);
79
95
 
80
96
  const firstFocusabled = useRef<
@@ -194,7 +210,7 @@ export const Timeline = forwardRef<HTMLDivElement, TimelineProps>(
194
210
  >
195
211
  <div {...rest} ref={ref}>
196
212
  <div className="navds-timeline">
197
- <AxisLabels />
213
+ <AxisLabels templates={axisLabelTemplates} />
198
214
 
199
215
  {pins.map((pin) => {
200
216
  return pin;
@@ -65,3 +65,9 @@ export interface SimplePeriod {
65
65
  */
66
66
  end: Date;
67
67
  }
68
+
69
+ export type AxisLabelTemplates = {
70
+ day?: string;
71
+ month?: string;
72
+ year?: string;
73
+ };
@@ -0,0 +1,19 @@
1
+ import { useEffect, useRef } from "react";
2
+
3
+ /*
4
+ * usePrevious hook
5
+ * The ref object's "current" property is mutable and when changed wont re-render the component
6
+ * meaning it can be used to stay "one render behind" the current state
7
+ * https://usehooks.com/usePrevious/
8
+ * https://blog.logrocket.com/accessing-previous-props-state-react-hooks/
9
+ */
10
+
11
+ const usePrevious = <T>(value: T): T | undefined => {
12
+ const ref = useRef<T>(value);
13
+ useEffect(() => {
14
+ ref.current = value;
15
+ }, [value]);
16
+ return ref.current;
17
+ };
18
+
19
+ export default usePrevious;