@entur/dropdown 9.0.2-beta.0 → 9.1.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.
@@ -1,4 +1,5 @@
1
1
  import { default as React, Dispatch, SetStateAction } from 'react';
2
+ import { FeedbackAnnouncementProps } from '../../form';
2
3
  import { VariantType } from '../../utils';
3
4
  import { NormalizedDropdownItemType, PotentiallyAsyncDropdownItemType } from './types';
4
5
  /** @deprecated use variant="information" instead */
@@ -79,6 +80,80 @@ export type DropdownProps<ValueType> = {
79
80
  * @default ', valgt element, trykk for å fjerne'
80
81
  */
81
82
  ariaLabelSelectedItem?: string;
82
- };
83
- export declare const Dropdown: <ValueType extends unknown>(props: DropdownProps<ValueType> & React.RefAttributes<HTMLDivElement>) => React.ReactElement | null;
83
+ } & FeedbackAnnouncementProps;
84
+ export declare const Dropdown: <ValueType extends unknown>(props: {
85
+ /** Tilgjengelige valg i dropdown-en */
86
+ items: PotentiallyAsyncDropdownItemType<ValueType>;
87
+ /** Valgt verdi. Bruk null for ingen verdi. */
88
+ selectedItem: NormalizedDropdownItemType<ValueType> | null;
89
+ /** Callback ved valg som skal oppdatere selectedItem */
90
+ onChange?: ((selectedItem: NormalizedDropdownItemType<ValueType> | null) => void | React.Dispatch<React.SetStateAction<NormalizedDropdownItemType<ValueType> | null>>) | undefined;
91
+ /** Beskrivende tekst som forklarer feltet */
92
+ label: string;
93
+ /** Placeholder-tekst når ingenting er satt */
94
+ placeholder?: string;
95
+ /** Om man skal ha mulighet for å nullstille Dropdown-en
96
+ * @default false
97
+ */
98
+ clearable?: boolean;
99
+ /** Velg det markerte elementet når brukeren "tab-er" seg vekk fra komponenten/input-feltet */
100
+ selectOnTab?: boolean;
101
+ /** Deaktiver dropdown-en */
102
+ disabled?: boolean;
103
+ /** Setter dropdown-en i read-only modus */
104
+ readOnly?: boolean;
105
+ /** Hvilken valideringsvariant som gjelder */
106
+ variant?: VariantType | typeof error | typeof info;
107
+ /** Valideringsmelding, brukes sammen med `variant` */
108
+ feedback?: string;
109
+ /** Tekst eller ikon som kommer først i dropdown-feltet */
110
+ prepend?: React.ReactNode;
111
+ /** */
112
+ loading?: boolean;
113
+ /** En tekst som beskriver hva som skjer når man venter på items
114
+ * @default 'Laster inn …'
115
+ */
116
+ loadingText?: string;
117
+ /** Tekst som kommer opp når det ikke er noe elementer å vise
118
+ * @default "Ingen tilgjengelige valg …"
119
+ */
120
+ noMatchesText?: string;
121
+ /** Om man skal ha mulighet for å nullstille Dropdown-en
122
+ * @default "fjern valgt"
123
+ */
124
+ labelClearSelectedItem?: string;
125
+ /** En tooltip som gir ekstra info om inputfeltet */
126
+ labelTooltip?: React.ReactNode;
127
+ /** Plasserer labelen statisk på toppen av inputfeltet
128
+ * @default false
129
+ */
130
+ disableLabelAnimation?: boolean;
131
+ /** Ekstra klassenavn */
132
+ className?: string;
133
+ /** Styling som sendes ned til Dropdown-lista */
134
+ listStyle?: {
135
+ [key: string]: any;
136
+ };
137
+ /** Styling for Dropdown-en */
138
+ style?: {
139
+ [key: string]: any;
140
+ };
141
+ /** Tekst for skjemleser for knapp som lukker listen med valg
142
+ * @default "Lukk liste med valg"
143
+ */
144
+ ariaLabelCloseList?: string;
145
+ /** Tekst for skjemleser for knapp som åpner listen med valg
146
+ * @default "Åpne liste med valg"
147
+ */
148
+ ariaLabelOpenList?: string;
149
+ /** Ord for at et element er valgt i entall
150
+ * eks. 'Element 1, _valgt_'
151
+ * @default 'valgt'
152
+ */
153
+ ariaLabelChosenSingular?: string;
154
+ /** Tekst for skjermleser som beskriver statusen til et element som valgt
155
+ * @default ', valgt element, trykk for å fjerne'
156
+ */
157
+ ariaLabelSelectedItem?: string;
158
+ } & FeedbackAnnouncementProps & React.RefAttributes<HTMLDivElement>) => React.ReactElement | null;
84
159
  export {};
@@ -1,4 +1,5 @@
1
1
  import { default as React } from 'react';
2
+ import { FeedbackAnnouncementProps } from '../../form';
2
3
  import { VariantType } from '../../utils';
3
4
  import { NormalizedDropdownItemType, PotentiallyAsyncDropdownItemType } from './types';
4
5
  /** @deprecated use variant="information" instead */
@@ -50,6 +51,51 @@ export type NativeDropdownProps<ValueType> = {
50
51
  */
51
52
  disableLabelAnimation?: boolean;
52
53
  [key: string]: any;
53
- };
54
- export declare const NativeDropdown: <ValueType extends string | number>(props: NativeDropdownProps<ValueType> & React.RefAttributes<HTMLSelectElement>) => React.ReactElement | null;
54
+ } & FeedbackAnnouncementProps;
55
+ export declare const NativeDropdown: <ValueType extends string | number>(props: {
56
+ [key: string]: any;
57
+ /** Ekstra klassenavn */
58
+ className?: string;
59
+ /**
60
+ * For å deaktivere dropdow-nen
61
+ * @default false
62
+ **/
63
+ disabled?: boolean;
64
+ /** Valideringsmelding, brukes sammen med `variant` */
65
+ feedback?: string;
66
+ /** Alle valg for dropdown-en å ha */
67
+ items: PotentiallyAsyncDropdownItemType<ValueType>;
68
+ /** Beskrivende tekst som forklarer feltet */
69
+ label: string;
70
+ /** En callback for endringer av value
71
+ * Obs: merk at parameter her denne ikke er samme som i en HTML select.
72
+ * Bruk { target } hvis du trenger info om select-elementet som ble trykket på
73
+ */
74
+ onChange?: (({ value, selectedItem, target, }: {
75
+ value: string;
76
+ selectedItem: NormalizedDropdownItemType<ValueType> | null;
77
+ target: EventTarget & HTMLSelectElement;
78
+ }) => void) | undefined;
79
+ /** Tekst eller ikon som kommer før dropdown-en */
80
+ prepend?: React.ReactNode;
81
+ /**
82
+ * Setter dropdown-en i read-only modus
83
+ * @default false
84
+ **/
85
+ readOnly?: boolean;
86
+ /** Den valgte verdien som NormalizedDropdownItemType
87
+ * (Brukes når komponenten er 'controlled')
88
+ */
89
+ selectedItem?: NormalizedDropdownItemType<ValueType> | null | undefined;
90
+ /** Den valgte verdien som sting
91
+ * (Brukes når komponenten er 'controlled)
92
+ */
93
+ value?: string;
94
+ /** Hvilken valideringsvariant som gjelder*/
95
+ variant?: VariantType | typeof error | typeof info;
96
+ /** Plasserer labelen statisk på toppen av inputfeltet
97
+ * @default false
98
+ */
99
+ disableLabelAnimation?: boolean;
100
+ } & FeedbackAnnouncementProps & React.RefAttributes<HTMLSelectElement>) => React.ReactElement | null;
55
101
  export {};
@@ -23,7 +23,37 @@ export type SearchableDropdownProps<ValueType> = DropdownProps<ValueType> & {
23
23
  /** Callback når input-feltet får fokus */
24
24
  onFocus?: (event: React.FocusEvent<HTMLDivElement>) => void;
25
25
  };
26
- export declare const SearchableDropdown: <ValueType extends unknown>(props: DropdownProps<ValueType> & {
26
+ export declare const SearchableDropdown: <ValueType extends unknown>(props: {
27
+ items: import('./types').PotentiallyAsyncDropdownItemType<ValueType>;
28
+ selectedItem: NormalizedDropdownItemType<ValueType> | null;
29
+ onChange?: ((selectedItem: NormalizedDropdownItemType<ValueType> | null) => void | React.Dispatch<React.SetStateAction<NormalizedDropdownItemType<ValueType> | null>>) | undefined;
30
+ label: string;
31
+ placeholder?: string;
32
+ clearable?: boolean;
33
+ selectOnTab?: boolean;
34
+ disabled?: boolean;
35
+ readOnly?: boolean;
36
+ variant?: import('../../utils').VariantType | "error" | "info";
37
+ feedback?: string;
38
+ prepend?: React.ReactNode;
39
+ loading?: boolean;
40
+ loadingText?: string;
41
+ noMatchesText?: string;
42
+ labelClearSelectedItem?: string;
43
+ labelTooltip?: React.ReactNode;
44
+ disableLabelAnimation?: boolean;
45
+ className?: string;
46
+ listStyle?: {
47
+ [key: string]: any;
48
+ };
49
+ style?: {
50
+ [key: string]: any;
51
+ };
52
+ ariaLabelCloseList?: string;
53
+ ariaLabelOpenList?: string;
54
+ ariaLabelChosenSingular?: string;
55
+ ariaLabelSelectedItem?: string;
56
+ } & import('../../form').FeedbackAnnouncementProps & {
27
57
  /** Filtreringen som brukes når man skriver inn tekst i inputfeltet
28
58
  * @default Regex-test som sjekker om item.label inneholder input-teksten
29
59
  */
package/dist/dropdown.cjs CHANGED
@@ -387,6 +387,15 @@ const useResolvedItems = (itemsOrItemsResolver, debounceTimeout = 250) => {
387
387
  fetchItems: debouncedFetchItems
388
388
  };
389
389
  };
390
+ function useFloatingRef(setElement) {
391
+ const latestSetElement = React.useRef(setElement);
392
+ React.useLayoutEffect(() => {
393
+ latestSetElement.current = setElement;
394
+ }, [setElement]);
395
+ return React.useCallback((node) => {
396
+ if (node !== null) latestSetElement.current(node);
397
+ }, []);
398
+ }
390
399
  function createShadowEnvironment(shadowRoot) {
391
400
  return {
392
401
  addEventListener: shadowRoot.addEventListener.bind(shadowRoot),
@@ -697,6 +706,7 @@ const SearchableDropdown = React.forwardRef(
697
706
  reactDom.flip({ fallbackStrategy: "initialPlacement" })
698
707
  ]
699
708
  });
709
+ const setFloatingMenu = useFloatingRef(refs.setFloating);
700
710
  React.useLayoutEffect(() => {
701
711
  if (isOpen && refs.reference.current && refs.floating.current) {
702
712
  return reactDom.autoUpdate(
@@ -712,7 +722,7 @@ const SearchableDropdown = React.forwardRef(
712
722
  });
713
723
  const menuProps = getMenuProps({
714
724
  refKey: "innerRef",
715
- ref: refs.setFloating,
725
+ ref: setFloatingMenu,
716
726
  style: listStyle
717
727
  });
718
728
  const inputProps = getInputProps({
@@ -810,7 +820,8 @@ const SearchableDropdown = React.forwardRef(
810
820
  className: classNames("eds-dropdown__input eds-form-control", {
811
821
  "eds-dropdown__input--hidden": showSelectedItem
812
822
  }),
813
- ...inputProps
823
+ ...inputProps,
824
+ "aria-invalid": variant === "negative" || variant === "error"
814
825
  }
815
826
  ),
816
827
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -1077,6 +1088,7 @@ const MultiSelect = React.forwardRef(
1077
1088
  reactDom.flip({ fallbackStrategy: "initialPlacement" })
1078
1089
  ]
1079
1090
  });
1091
+ const setFloatingMenu = useFloatingRef(refs.setFloating);
1080
1092
  React.useLayoutEffect(() => {
1081
1093
  if (isOpen && refs.reference.current && refs.floating.current) {
1082
1094
  return reactDom.autoUpdate(
@@ -1120,7 +1132,7 @@ const MultiSelect = React.forwardRef(
1120
1132
  const menuProps = getMenuProps({
1121
1133
  "aria-multiselectable": true,
1122
1134
  refKey: "innerRef",
1123
- ref: refs.setFloating,
1135
+ ref: setFloatingMenu,
1124
1136
  style: listStyle
1125
1137
  });
1126
1138
  const toggleButtonProps = getToggleButtonProps({
@@ -1212,7 +1224,13 @@ const MultiSelect = React.forwardRef(
1212
1224
  selectedItem: summarySelectedItems
1213
1225
  }
1214
1226
  ),
1215
- /* @__PURE__ */ jsxRuntime.jsx("input", { ...inputProps })
1227
+ /* @__PURE__ */ jsxRuntime.jsx(
1228
+ "input",
1229
+ {
1230
+ ...inputProps,
1231
+ "aria-invalid": variant === "negative" || variant === "error"
1232
+ }
1233
+ )
1216
1234
  ]
1217
1235
  }
1218
1236
  ),
@@ -1238,6 +1256,7 @@ const MultiSelect = React.forwardRef(
1238
1256
  );
1239
1257
  }
1240
1258
  );
1259
+ const error$1 = "error";
1241
1260
  const Dropdown = React.forwardRef(
1242
1261
  ({
1243
1262
  ariaLabelChosenSingular,
@@ -1321,6 +1340,8 @@ const Dropdown = React.forwardRef(
1321
1340
  ]
1322
1341
  });
1323
1342
  floatingRefs = refs;
1343
+ const setFloatingMenu = useFloatingRef(refs.setFloating);
1344
+ const setFloatingReference = useFloatingRef(refs.setReference);
1324
1345
  React.useLayoutEffect(() => {
1325
1346
  if (isOpen && refs.reference.current && refs.floating.current) {
1326
1347
  return reactDom.autoUpdate(
@@ -1338,7 +1359,7 @@ const Dropdown = React.forwardRef(
1338
1359
  isFilled
1339
1360
  });
1340
1361
  const toggleButtonProps = getToggleButtonProps({
1341
- ref: utils.mergeRefs(ref, refs.setReference, toggleButtonRef),
1362
+ ref: utils.mergeRefs(ref, setFloatingReference, toggleButtonRef),
1342
1363
  "aria-disabled": disabled,
1343
1364
  "aria-label": disabled ? "Disabled dropdown" : "",
1344
1365
  disabled,
@@ -1359,7 +1380,7 @@ const Dropdown = React.forwardRef(
1359
1380
  });
1360
1381
  const menuProps = getMenuProps({
1361
1382
  refKey: "innerRef",
1362
- ref: refs.setFloating,
1383
+ ref: setFloatingMenu,
1363
1384
  style: listStyle
1364
1385
  });
1365
1386
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1376,6 +1397,7 @@ const Dropdown = React.forwardRef(
1376
1397
  style,
1377
1398
  variant,
1378
1399
  ...toggleButtonProps,
1400
+ "aria-invalid": variant === "negative" || variant === error$1,
1379
1401
  after: /* @__PURE__ */ jsxRuntime.jsx(
1380
1402
  DropdownList,
1381
1403
  {
@@ -1449,6 +1471,8 @@ const NativeDropdown = React.forwardRef(
1449
1471
  style,
1450
1472
  value,
1451
1473
  variant,
1474
+ ariaAlertOnFeedback,
1475
+ feedbackProps,
1452
1476
  ...rest
1453
1477
  }, ref) => {
1454
1478
  const { items: normalizedItems, loading } = useResolvedItems(items);
@@ -1459,6 +1483,8 @@ const NativeDropdown = React.forwardRef(
1459
1483
  disabled,
1460
1484
  readOnly,
1461
1485
  prepend,
1486
+ ariaAlertOnFeedback,
1487
+ feedbackProps,
1462
1488
  append: /* @__PURE__ */ jsxRuntime.jsx(
1463
1489
  FieldAppend,
1464
1490
  {