• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

alma-oss / spirit-design-system / 29926312974

22 Jul 2026 01:57PM UTC coverage: 85.422% (-1.0%) from 86.381%
29926312974

Pull #2814

github

pavelklibani
test(e2e): update web-react demo homepage snapshot #DS-2304
Pull Request #2814: 🚧 [WIP] feat(web-react): introduce `UNSTABLE_Combobox` component #DS-2304

2868 of 3885 branches covered (73.82%)

Branch coverage included in aggregate %.

401 of 512 new or added lines in 16 files covered. (78.32%)

7738 of 8531 relevant lines covered (90.7%)

226.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.0
/packages/web-react/src/components/UNSTABLE_Combobox/useComboboxOptionLabels.ts
1
'use client';
2

3
import { type ReactNode, type RefObject, useCallback, useEffect, useMemo, useRef } from 'react';
174✔
4
import {
5
  collectComboboxOptionLabels,
6
  getOptionRowEl as getOptionRowElFromListbox,
7
  getOptionValueFromRow,
8
  getRowLabel,
9
} from './utils';
174✔
10

11
export interface ComboboxSelectedItem {
12
  label: string;
13
  value: string;
14
}
15

16
export interface UseComboboxOptionLabelsProps {
17
  children?: ReactNode;
18
  listboxRef: RefObject<HTMLElement | null>;
19
  selectedKeys: string[];
20
}
21

22
export interface UseComboboxOptionLabelsReturn {
23
  getOptionLabel: (key: string) => string;
24
  getOptionRowEl: (optionId: string) => HTMLElement | null;
25
  selectedItems: ComboboxSelectedItem[];
26
}
27

28
/**
29
 * Resolve option labels from children / DOM with a cache for selected tags.
30
 *
31
 * @param props Hook configuration
32
 * @param props.children Combobox option children
33
 * @param props.listboxRef Listbox grid element
34
 * @param props.selectedKeys Selected option ids
35
 * @returns {{ getOptionLabel: (key: string) => string, getOptionRowEl: (optionId: string) => HTMLElement | null, selectedItems: ComboboxSelectedItem[] }}
36
 */
37
export const useComboboxOptionLabels = ({
174✔
38
  children,
39
  listboxRef,
40
  selectedKeys,
41
}: UseComboboxOptionLabelsProps): UseComboboxOptionLabelsReturn => {
42
  const labelCacheRef = useRef<Map<string, string>>(new Map());
51✔
43

44
  const getOptionRowEl = useCallback(
51✔
45
    (optionId: string): HTMLElement | null => getOptionRowElFromListbox(listboxRef.current, optionId),
3✔
46
    [listboxRef],
47
  );
48

49
  const optionLabelsFromChildren = useMemo(() => collectComboboxOptionLabels(children), [children]);
51✔
50

51
  useEffect(() => {
51✔
52
    Object.entries(optionLabelsFromChildren).forEach(([key, optionLabel]) => {
40✔
53
      if (optionLabel) {
77!
54
        labelCacheRef.current.set(key, optionLabel);
77✔
55
      }
56
    });
57
  }, [optionLabelsFromChildren]);
58

59
  const syncLabelCacheFromDom = useCallback(() => {
51✔
60
    const listbox = listboxRef.current;
41✔
61

62
    if (!listbox) {
41✔
63
      return;
1✔
64
    }
65

66
    listbox.querySelectorAll<HTMLElement>('[role="row"]').forEach((row) => {
40✔
67
      const optionValue = getOptionValueFromRow(row);
79✔
68

69
      if (optionValue) {
79!
70
        labelCacheRef.current.set(optionValue, getRowLabel(row));
79✔
71
      }
72
    });
73
  }, [listboxRef]);
74

75
  useEffect(() => {
51✔
76
    syncLabelCacheFromDom();
41✔
77
  }, [children, selectedKeys, syncLabelCacheFromDom]);
78

79
  const getOptionLabel = useCallback(
51✔
80
    (key: string) => {
81
      const fromChildren = optionLabelsFromChildren[key];
8✔
82

83
      if (fromChildren) {
8!
84
        labelCacheRef.current.set(key, fromChildren);
8✔
85

86
        return fromChildren;
8✔
87
      }
88

NEW
89
      const cached = labelCacheRef.current.get(key);
×
90

NEW
91
      if (cached) {
×
NEW
92
        return cached;
×
93
      }
94

NEW
95
      const rowEl = getOptionRowEl(key);
×
96

NEW
97
      if (rowEl) {
×
NEW
98
        const labelText = getRowLabel(rowEl);
×
99

NEW
100
        labelCacheRef.current.set(key, labelText);
×
101

NEW
102
        return labelText;
×
103
      }
104

NEW
105
      return key;
×
106
    },
107
    [getOptionRowEl, optionLabelsFromChildren],
108
  );
109

110
  const selectedItems = useMemo(
51✔
111
    () => selectedKeys.map((key) => ({ value: key, label: getOptionLabel(key) })),
41✔
112
    [getOptionLabel, selectedKeys],
113
  );
114

115
  return {
51✔
116
    getOptionLabel,
117
    getOptionRowEl,
118
    selectedItems,
119
  };
120
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc