@flipdish/ui-library 0.39.2 → 0.40.1
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.
- package/dist/components/atoms/RadioButton/index.cjs +3 -16
- package/dist/components/atoms/RadioButton/index.cjs.map +1 -1
- package/dist/components/atoms/RadioButton/index.d.ts.map +1 -1
- package/dist/components/atoms/RadioButton/index.js +3 -16
- package/dist/components/atoms/RadioButton/index.js.map +1 -1
- package/dist/components/organisms/CommandMenu/commandMenu.utils.cjs +54 -0
- package/dist/components/organisms/CommandMenu/commandMenu.utils.cjs.map +1 -1
- package/dist/components/organisms/CommandMenu/commandMenu.utils.d.ts +62 -0
- package/dist/components/organisms/CommandMenu/commandMenu.utils.d.ts.map +1 -1
- package/dist/components/organisms/CommandMenu/commandMenu.utils.js +53 -1
- package/dist/components/organisms/CommandMenu/commandMenu.utils.js.map +1 -1
- package/dist/components/organisms/CommandMenu/hooks/useCommandItemHotkeys.cjs +43 -0
- package/dist/components/organisms/CommandMenu/hooks/useCommandItemHotkeys.cjs.map +1 -0
- package/dist/components/organisms/CommandMenu/hooks/useCommandItemHotkeys.d.ts +19 -0
- package/dist/components/organisms/CommandMenu/hooks/useCommandItemHotkeys.d.ts.map +1 -0
- package/dist/components/organisms/CommandMenu/hooks/useCommandItemHotkeys.js +41 -0
- package/dist/components/organisms/CommandMenu/hooks/useCommandItemHotkeys.js.map +1 -0
- package/dist/components/organisms/CommandMenu/index.cjs +2 -47
- package/dist/components/organisms/CommandMenu/index.cjs.map +1 -1
- package/dist/components/organisms/CommandMenu/index.d.ts.map +1 -1
- package/dist/components/organisms/CommandMenu/index.js +4 -49
- package/dist/components/organisms/CommandMenu/index.js.map +1 -1
- package/dist/native/components/atoms/RadioButton/index.d.ts +47 -9
- package/dist/native/components/atoms/RadioButton/index.d.ts.map +1 -0
- package/dist/native/components/atoms/RadioButton/index.js +43 -0
- package/dist/native/components/atoms/RadioButton/index.js.map +1 -0
- package/package.json +1 -1
|
@@ -5,6 +5,7 @@ var cx = require('@flipdish/ui-library/utilities/cx');
|
|
|
5
5
|
var testIdUtils = require('@flipdish/ui-library/utilities/testIdUtils');
|
|
6
6
|
var React = require('react');
|
|
7
7
|
var reactAriaComponents = require('react-aria-components');
|
|
8
|
+
var selectionControl_styles = require('../../__internal__/selectionControl/selectionControl.styles.cjs');
|
|
8
9
|
|
|
9
10
|
const RadioGroupContext = React.createContext(null);
|
|
10
11
|
/** Visual-only radio circle with no input behaviour, for building custom selectable controls; `RadioButton` renders it inside a react-aria `Radio`. */
|
|
@@ -23,24 +24,10 @@ const RadioButton = ({ label, hint, className, size = 'sm', 'data-testid': dataT
|
|
|
23
24
|
size = context?.size ?? size;
|
|
24
25
|
const fallbackTestId = testIdUtils.useResolvedTestId({ testId: dataTestId, segment: 'radio-button', rootName: 'radio-button' });
|
|
25
26
|
const radioTestId = !dataTestId && context?.testIdPrefix ? testIdUtils.joinTestId(context.testIdPrefix, `option-${testIdUtils.slugifyTestId(String(ariaRadioProps.value))}`) : fallbackTestId;
|
|
26
|
-
|
|
27
|
-
sm: {
|
|
28
|
-
root: 'gap-2',
|
|
29
|
-
textWrapper: '',
|
|
30
|
-
label: 'text-sm font-medium',
|
|
31
|
-
hint: 'text-sm',
|
|
32
|
-
},
|
|
33
|
-
md: {
|
|
34
|
-
root: 'gap-3',
|
|
35
|
-
textWrapper: 'gap-0.5',
|
|
36
|
-
label: 'text-md font-medium',
|
|
37
|
-
hint: 'text-md',
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
return (jsxRuntime.jsx(reactAriaComponents.Radio, { ...ariaRadioProps, "data-testid": radioTestId, className: (state) => cx.cx('relative flex items-start', state.isDisabled && 'cursor-not-allowed', sizes[size].root, typeof className === 'function' ? className(state) : className), children: ({ isSelected, isDisabled, isFocusVisible }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(RadioButtonBase, { size: size, isSelected: isSelected, isDisabled: isDisabled, isFocusVisible: isFocusVisible, className: label || hint ? 'mt-0.5' : '' }), (label || hint) && (jsxRuntime.jsxs("div", { className: cx.cx('inline-flex flex-col', sizes[size].textWrapper), children: [label && jsxRuntime.jsx("p", { className: cx.cx('text-secondary select-none', sizes[size].label), children: label }), hint && (
|
|
27
|
+
return (jsxRuntime.jsx(reactAriaComponents.Radio, { ...ariaRadioProps, "data-testid": radioTestId, className: (state) => cx.cx('relative flex items-start', state.isDisabled && 'cursor-not-allowed', selectionControl_styles.selectionControlSizes[size].root, typeof className === 'function' ? className(state) : className), children: ({ isSelected, isDisabled, isFocusVisible }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx(RadioButtonBase, { size: size, isSelected: isSelected, isDisabled: isDisabled, isFocusVisible: isFocusVisible, className: label || hint ? 'mt-0.5' : '' }), (label || hint) && (jsxRuntime.jsxs("div", { className: cx.cx('inline-flex flex-col', selectionControl_styles.selectionControlSizes[size].textWrapper), children: [label && jsxRuntime.jsx("p", { className: cx.cx('text-secondary select-none', selectionControl_styles.selectionControlSizes[size].label), children: label }), hint && (
|
|
41
28
|
// biome-ignore lint/a11y/noStaticElementInteractions: This is a hint that is not interactive
|
|
42
29
|
// biome-ignore lint/a11y/useKeyWithClickEvents: This is a hint that is not interactive
|
|
43
|
-
jsxRuntime.jsx("span", { className: cx.cx('text-tertiary',
|
|
30
|
+
jsxRuntime.jsx("span", { className: cx.cx('text-tertiary', selectionControl_styles.selectionControlSizes[size].hint), onClick: (event) => event.stopPropagation(), children: hint }))] }))] })) }));
|
|
44
31
|
};
|
|
45
32
|
RadioButton.displayName = 'RadioButton';
|
|
46
33
|
/** Wrapper around react-aria-components' `RadioGroup` that stacks its `RadioButton` children and passes them `size` and a derived `data-testid`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../src/components/atoms/RadioButton/index.tsx"],"sourcesContent":[null],"names":["createContext","_jsx","cx","useContext","useResolvedTestId","joinTestId","slugifyTestId","AriaRadio","_jsxs","_Fragment","AriaRadioGroup"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../src/components/atoms/RadioButton/index.tsx"],"sourcesContent":[null],"names":["createContext","_jsx","cx","useContext","useResolvedTestId","joinTestId","slugifyTestId","AriaRadio","selectionControlSizes","_jsxs","_Fragment","AriaRadioGroup"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/atoms/RadioButton/index.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,GAAG,EAAc,MAAM,OAAO,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,IAAI,mBAAmB,EAC3C,KAAK,UAAU,IAAI,cAAc,EAClC,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/atoms/RadioButton/index.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAiB,KAAK,SAAS,EAAE,KAAK,GAAG,EAAc,MAAM,OAAO,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,IAAI,mBAAmB,EAC3C,KAAK,UAAU,IAAI,cAAc,EAClC,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAID,MAAM,WAAW,oBAAoB;IACnC,wDAAwD;IACxD,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,uDAAuD;IACvD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sEAAsE;IACtE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sDAAsD;IACtD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,uJAAuJ;AACvJ,eAAO,MAAM,eAAe;kEAAwE,oBAAoB;;CAkBvH,CAAC;AAGF,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,0GAA0G;IAC1G,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,oEAAoE;IACpE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,iDAAiD;IACjD,GAAG,CAAC,EAAE,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC5B,wGAAwG;IACxG,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW;qFAA2F,gBAAgB;;CA+ClI,CAAC;AAGF,UAAU,eAAgB,SAAQ,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC,EAAE,mBAAmB;IACxF,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,oJAAoJ;AACpJ,eAAO,MAAM,UAAU,GAAI,oEAA2E,eAAe,gCAUpH,CAAC"}
|
|
@@ -3,6 +3,7 @@ import { cx } from '@flipdish/ui-library/utilities/cx';
|
|
|
3
3
|
import { useResolvedTestId, joinTestId, slugifyTestId } from '@flipdish/ui-library/utilities/testIdUtils';
|
|
4
4
|
import { createContext, useContext } from 'react';
|
|
5
5
|
import { Radio, RadioGroup as RadioGroup$1 } from 'react-aria-components';
|
|
6
|
+
import { selectionControlSizes } from '../../__internal__/selectionControl/selectionControl.styles.js';
|
|
6
7
|
|
|
7
8
|
const RadioGroupContext = createContext(null);
|
|
8
9
|
/** Visual-only radio circle with no input behaviour, for building custom selectable controls; `RadioButton` renders it inside a react-aria `Radio`. */
|
|
@@ -21,24 +22,10 @@ const RadioButton = ({ label, hint, className, size = 'sm', 'data-testid': dataT
|
|
|
21
22
|
size = context?.size ?? size;
|
|
22
23
|
const fallbackTestId = useResolvedTestId({ testId: dataTestId, segment: 'radio-button', rootName: 'radio-button' });
|
|
23
24
|
const radioTestId = !dataTestId && context?.testIdPrefix ? joinTestId(context.testIdPrefix, `option-${slugifyTestId(String(ariaRadioProps.value))}`) : fallbackTestId;
|
|
24
|
-
|
|
25
|
-
sm: {
|
|
26
|
-
root: 'gap-2',
|
|
27
|
-
textWrapper: '',
|
|
28
|
-
label: 'text-sm font-medium',
|
|
29
|
-
hint: 'text-sm',
|
|
30
|
-
},
|
|
31
|
-
md: {
|
|
32
|
-
root: 'gap-3',
|
|
33
|
-
textWrapper: 'gap-0.5',
|
|
34
|
-
label: 'text-md font-medium',
|
|
35
|
-
hint: 'text-md',
|
|
36
|
-
},
|
|
37
|
-
};
|
|
38
|
-
return (jsx(Radio, { ...ariaRadioProps, "data-testid": radioTestId, className: (state) => cx('relative flex items-start', state.isDisabled && 'cursor-not-allowed', sizes[size].root, typeof className === 'function' ? className(state) : className), children: ({ isSelected, isDisabled, isFocusVisible }) => (jsxs(Fragment, { children: [jsx(RadioButtonBase, { size: size, isSelected: isSelected, isDisabled: isDisabled, isFocusVisible: isFocusVisible, className: label || hint ? 'mt-0.5' : '' }), (label || hint) && (jsxs("div", { className: cx('inline-flex flex-col', sizes[size].textWrapper), children: [label && jsx("p", { className: cx('text-secondary select-none', sizes[size].label), children: label }), hint && (
|
|
25
|
+
return (jsx(Radio, { ...ariaRadioProps, "data-testid": radioTestId, className: (state) => cx('relative flex items-start', state.isDisabled && 'cursor-not-allowed', selectionControlSizes[size].root, typeof className === 'function' ? className(state) : className), children: ({ isSelected, isDisabled, isFocusVisible }) => (jsxs(Fragment, { children: [jsx(RadioButtonBase, { size: size, isSelected: isSelected, isDisabled: isDisabled, isFocusVisible: isFocusVisible, className: label || hint ? 'mt-0.5' : '' }), (label || hint) && (jsxs("div", { className: cx('inline-flex flex-col', selectionControlSizes[size].textWrapper), children: [label && jsx("p", { className: cx('text-secondary select-none', selectionControlSizes[size].label), children: label }), hint && (
|
|
39
26
|
// biome-ignore lint/a11y/noStaticElementInteractions: This is a hint that is not interactive
|
|
40
27
|
// biome-ignore lint/a11y/useKeyWithClickEvents: This is a hint that is not interactive
|
|
41
|
-
jsx("span", { className: cx('text-tertiary',
|
|
28
|
+
jsx("span", { className: cx('text-tertiary', selectionControlSizes[size].hint), onClick: (event) => event.stopPropagation(), children: hint }))] }))] })) }));
|
|
42
29
|
};
|
|
43
30
|
RadioButton.displayName = 'RadioButton';
|
|
44
31
|
/** Wrapper around react-aria-components' `RadioGroup` that stacks its `RadioButton` children and passes them `size` and a derived `data-testid`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/atoms/RadioButton/index.tsx"],"sourcesContent":[null],"names":["_jsx","AriaRadio","_jsxs","_Fragment","AriaRadioGroup"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/atoms/RadioButton/index.tsx"],"sourcesContent":[null],"names":["_jsx","AriaRadio","_jsxs","_Fragment","AriaRadioGroup"],"mappings":"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"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var hotkeys_utils = require('../../../utilities/__internal__/hotkeysUtils/hotkeys.utils.cjs');
|
|
4
|
+
|
|
3
5
|
/**
|
|
4
6
|
* Compares two values to determine if they are deeply equal.
|
|
5
7
|
*
|
|
@@ -30,6 +32,58 @@ const isDeepEqual = (obj1, obj2) => {
|
|
|
30
32
|
}
|
|
31
33
|
return true;
|
|
32
34
|
};
|
|
35
|
+
/**
|
|
36
|
+
* Turns menu items into the hotkey registrations `CommandMenu` installs.
|
|
37
|
+
* Disabled items and disabled keys are left out, and an empty shortcut registers nothing.
|
|
38
|
+
*
|
|
39
|
+
* @param items Flat menu items, in display order.
|
|
40
|
+
* @param disabledKeys Ids the list treats as disabled, in addition to each item's `isDisabled`.
|
|
41
|
+
* @returns The hotkey strings to register for each triggerable kind, plus whether any shortcut can never fire.
|
|
42
|
+
*/
|
|
43
|
+
const planCommandItemHotkeys = (items, disabledKeys) => {
|
|
44
|
+
const disabled = new Set(disabledKeys);
|
|
45
|
+
const registered = [];
|
|
46
|
+
for (const item of items) {
|
|
47
|
+
if (item.isDisabled || disabled.has(item.id))
|
|
48
|
+
continue;
|
|
49
|
+
const steps = hotkeys_utils.toHotkeySteps(item.shortcutKeys ?? []);
|
|
50
|
+
if (steps.length === 0)
|
|
51
|
+
continue;
|
|
52
|
+
registered.push({ id: item.id, steps, kind: hotkeys_utils.getItemHotkeyKind(steps) });
|
|
53
|
+
}
|
|
54
|
+
const ofKind = (kind) => registered.filter((entry) => entry.kind === kind);
|
|
55
|
+
// Registering a hotkey twice would run the handler twice for one keypress.
|
|
56
|
+
const unique = (kind) => [...new Set(ofKind(kind).map((entry) => entry.steps[0]))];
|
|
57
|
+
return {
|
|
58
|
+
combination: unique('combination'),
|
|
59
|
+
guarded: unique('guarded'),
|
|
60
|
+
typed: ofKind('typed'),
|
|
61
|
+
matchable: registered.filter((entry) => entry.kind === 'combination' || entry.kind === 'guarded'),
|
|
62
|
+
hasUnsupported: ofKind('unsupported').length > 0,
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
// `hotkeysEvent` carries fields (e.g. `metadata`) the vendored parser never produces, so compare only the identifying ones.
|
|
66
|
+
const hotkeyMatches = (step, fired) => {
|
|
67
|
+
const parsed = hotkeys_utils.parseHotkey(step);
|
|
68
|
+
return (parsed.hotkey.trim().toLowerCase() === fired.hotkey?.trim().toLowerCase() &&
|
|
69
|
+
parsed.isSequence === fired.isSequence &&
|
|
70
|
+
parsed.alt === fired.alt &&
|
|
71
|
+
parsed.ctrl === fired.ctrl &&
|
|
72
|
+
parsed.shift === fired.shift &&
|
|
73
|
+
parsed.meta === fired.meta &&
|
|
74
|
+
parsed.mod === fired.mod &&
|
|
75
|
+
isDeepEqual(parsed.keys, fired.keys));
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* The item a fired combination or guarded hotkey selects.
|
|
79
|
+
*
|
|
80
|
+
* @param matchable Combination and guarded registrations, in source order. A typed or unsupported entry never matches.
|
|
81
|
+
* @param fired The event `react-hotkeys-hook` reports for the key that was pressed.
|
|
82
|
+
* @returns The first matching registration, or `undefined` when the key selects nothing.
|
|
83
|
+
*/
|
|
84
|
+
const findCommandItemForHotkey = (matchable, fired) => matchable.find((entry) => (entry.kind === 'combination' || entry.kind === 'guarded') && hotkeyMatches(entry.steps[0], fired));
|
|
33
85
|
|
|
86
|
+
exports.findCommandItemForHotkey = findCommandItemForHotkey;
|
|
34
87
|
exports.isDeepEqual = isDeepEqual;
|
|
88
|
+
exports.planCommandItemHotkeys = planCommandItemHotkeys;
|
|
35
89
|
//# sourceMappingURL=commandMenu.utils.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commandMenu.utils.cjs","sources":["../../../../src/components/organisms/CommandMenu/commandMenu.utils.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"commandMenu.utils.cjs","sources":["../../../../src/components/organisms/CommandMenu/commandMenu.utils.ts"],"sourcesContent":[null],"names":["toHotkeySteps","getItemHotkeyKind","parseHotkey"],"mappings":"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"}
|
|
@@ -1,3 +1,47 @@
|
|
|
1
|
+
/** How an item shortcut can be triggered. Matches `getItemHotkeyKind`. */
|
|
2
|
+
export type CommandHotkeyKind = 'combination' | 'guarded' | 'typed' | 'unsupported';
|
|
3
|
+
/** A menu item that may register a shortcut. */
|
|
4
|
+
export interface CommandHotkeyItem {
|
|
5
|
+
/** Id reported through `onSelectionChange` when the shortcut fires. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** Skips registration, the same way a disabled list key does. */
|
|
8
|
+
isDisabled?: boolean;
|
|
9
|
+
/** Shortcut entries in hook format or symbol shorthand. Empty and missing shortcuts register nothing. */
|
|
10
|
+
shortcutKeys?: string[];
|
|
11
|
+
}
|
|
12
|
+
/** One registered shortcut, in the order the item appeared. */
|
|
13
|
+
export interface CommandItemHotkey {
|
|
14
|
+
/** Id reported through `onSelectionChange` when the shortcut fires. */
|
|
15
|
+
id: string;
|
|
16
|
+
/** Hook-format steps from `toHotkeySteps`. */
|
|
17
|
+
steps: string[];
|
|
18
|
+
/** How the shortcut can be triggered. */
|
|
19
|
+
kind: CommandHotkeyKind;
|
|
20
|
+
}
|
|
21
|
+
/** The hotkey strings and items `CommandMenu` registers from its items. */
|
|
22
|
+
export interface CommandHotkeyPlan {
|
|
23
|
+
/** Combination hotkeys, each registered once. */
|
|
24
|
+
combination: string[];
|
|
25
|
+
/** Guarded hotkeys, each registered once. */
|
|
26
|
+
guarded: string[];
|
|
27
|
+
/** Typed shortcuts in source order. The sequence index selects `id`. */
|
|
28
|
+
typed: CommandItemHotkey[];
|
|
29
|
+
/** Combination and guarded shortcuts, in source order. The first match wins. */
|
|
30
|
+
matchable: CommandItemHotkey[];
|
|
31
|
+
/** Whether any shortcut is drawn but can never be triggered. */
|
|
32
|
+
hasUnsupported: boolean;
|
|
33
|
+
}
|
|
34
|
+
/** The fields of a fired hotkey that identify it. Extra event fields are ignored. */
|
|
35
|
+
interface FiredHotkey {
|
|
36
|
+
hotkey?: string;
|
|
37
|
+
isSequence?: boolean;
|
|
38
|
+
alt?: boolean;
|
|
39
|
+
ctrl?: boolean;
|
|
40
|
+
shift?: boolean;
|
|
41
|
+
meta?: boolean;
|
|
42
|
+
mod?: boolean;
|
|
43
|
+
keys?: readonly string[] | null;
|
|
44
|
+
}
|
|
1
45
|
/**
|
|
2
46
|
* Compares two values to determine if they are deeply equal.
|
|
3
47
|
*
|
|
@@ -7,4 +51,22 @@
|
|
|
7
51
|
* @returns True if the values are deeply equal, otherwise false.
|
|
8
52
|
*/
|
|
9
53
|
export declare const isDeepEqual: (obj1: any, obj2: any) => boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Turns menu items into the hotkey registrations `CommandMenu` installs.
|
|
56
|
+
* Disabled items and disabled keys are left out, and an empty shortcut registers nothing.
|
|
57
|
+
*
|
|
58
|
+
* @param items Flat menu items, in display order.
|
|
59
|
+
* @param disabledKeys Ids the list treats as disabled, in addition to each item's `isDisabled`.
|
|
60
|
+
* @returns The hotkey strings to register for each triggerable kind, plus whether any shortcut can never fire.
|
|
61
|
+
*/
|
|
62
|
+
export declare const planCommandItemHotkeys: (items: readonly CommandHotkeyItem[], disabledKeys?: Iterable<string | number>) => CommandHotkeyPlan;
|
|
63
|
+
/**
|
|
64
|
+
* The item a fired combination or guarded hotkey selects.
|
|
65
|
+
*
|
|
66
|
+
* @param matchable Combination and guarded registrations, in source order. A typed or unsupported entry never matches.
|
|
67
|
+
* @param fired The event `react-hotkeys-hook` reports for the key that was pressed.
|
|
68
|
+
* @returns The first matching registration, or `undefined` when the key selects nothing.
|
|
69
|
+
*/
|
|
70
|
+
export declare const findCommandItemForHotkey: (matchable: readonly CommandItemHotkey[], fired: FiredHotkey) => CommandItemHotkey | undefined;
|
|
71
|
+
export {};
|
|
10
72
|
//# sourceMappingURL=commandMenu.utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commandMenu.utils.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/CommandMenu/commandMenu.utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"commandMenu.utils.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/CommandMenu/commandMenu.utils.ts"],"names":[],"mappings":"AAEA,0EAA0E;AAC1E,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,CAAC;AAEpF,gDAAgD;AAChD,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,iEAAiE;IACjE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yGAAyG;IACzG,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,uEAAuE;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,8CAA8C;IAC9C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,yCAAyC;IACzC,IAAI,EAAE,iBAAiB,CAAC;CACzB;AAED,2EAA2E;AAC3E,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wEAAwE;IACxE,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,gFAAgF;IAChF,SAAS,EAAE,iBAAiB,EAAE,CAAC;IAC/B,gEAAgE;IAChE,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,qFAAqF;AACrF,UAAU,WAAW;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CACjC;AAED;;;;;;;GAOG;AAEH,eAAO,MAAM,WAAW,GAAI,MAAM,GAAG,EAAE,MAAM,GAAG,KAAG,OAsBlD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,SAAS,iBAAiB,EAAE,EAAE,eAAe,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,KAAG,iBAsBtH,CAAC;AAkBF;;;;;;GAMG;AACH,eAAO,MAAM,wBAAwB,GAAI,WAAW,SAAS,iBAAiB,EAAE,EAAE,OAAO,WAAW,KAAG,iBAAiB,GAAG,SACI,CAAC"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { toHotkeySteps, getItemHotkeyKind, parseHotkey } from '../../../utilities/__internal__/hotkeysUtils/hotkeys.utils.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Compares two values to determine if they are deeply equal.
|
|
3
5
|
*
|
|
@@ -28,6 +30,56 @@ const isDeepEqual = (obj1, obj2) => {
|
|
|
28
30
|
}
|
|
29
31
|
return true;
|
|
30
32
|
};
|
|
33
|
+
/**
|
|
34
|
+
* Turns menu items into the hotkey registrations `CommandMenu` installs.
|
|
35
|
+
* Disabled items and disabled keys are left out, and an empty shortcut registers nothing.
|
|
36
|
+
*
|
|
37
|
+
* @param items Flat menu items, in display order.
|
|
38
|
+
* @param disabledKeys Ids the list treats as disabled, in addition to each item's `isDisabled`.
|
|
39
|
+
* @returns The hotkey strings to register for each triggerable kind, plus whether any shortcut can never fire.
|
|
40
|
+
*/
|
|
41
|
+
const planCommandItemHotkeys = (items, disabledKeys) => {
|
|
42
|
+
const disabled = new Set(disabledKeys);
|
|
43
|
+
const registered = [];
|
|
44
|
+
for (const item of items) {
|
|
45
|
+
if (item.isDisabled || disabled.has(item.id))
|
|
46
|
+
continue;
|
|
47
|
+
const steps = toHotkeySteps(item.shortcutKeys ?? []);
|
|
48
|
+
if (steps.length === 0)
|
|
49
|
+
continue;
|
|
50
|
+
registered.push({ id: item.id, steps, kind: getItemHotkeyKind(steps) });
|
|
51
|
+
}
|
|
52
|
+
const ofKind = (kind) => registered.filter((entry) => entry.kind === kind);
|
|
53
|
+
// Registering a hotkey twice would run the handler twice for one keypress.
|
|
54
|
+
const unique = (kind) => [...new Set(ofKind(kind).map((entry) => entry.steps[0]))];
|
|
55
|
+
return {
|
|
56
|
+
combination: unique('combination'),
|
|
57
|
+
guarded: unique('guarded'),
|
|
58
|
+
typed: ofKind('typed'),
|
|
59
|
+
matchable: registered.filter((entry) => entry.kind === 'combination' || entry.kind === 'guarded'),
|
|
60
|
+
hasUnsupported: ofKind('unsupported').length > 0,
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
// `hotkeysEvent` carries fields (e.g. `metadata`) the vendored parser never produces, so compare only the identifying ones.
|
|
64
|
+
const hotkeyMatches = (step, fired) => {
|
|
65
|
+
const parsed = parseHotkey(step);
|
|
66
|
+
return (parsed.hotkey.trim().toLowerCase() === fired.hotkey?.trim().toLowerCase() &&
|
|
67
|
+
parsed.isSequence === fired.isSequence &&
|
|
68
|
+
parsed.alt === fired.alt &&
|
|
69
|
+
parsed.ctrl === fired.ctrl &&
|
|
70
|
+
parsed.shift === fired.shift &&
|
|
71
|
+
parsed.meta === fired.meta &&
|
|
72
|
+
parsed.mod === fired.mod &&
|
|
73
|
+
isDeepEqual(parsed.keys, fired.keys));
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* The item a fired combination or guarded hotkey selects.
|
|
77
|
+
*
|
|
78
|
+
* @param matchable Combination and guarded registrations, in source order. A typed or unsupported entry never matches.
|
|
79
|
+
* @param fired The event `react-hotkeys-hook` reports for the key that was pressed.
|
|
80
|
+
* @returns The first matching registration, or `undefined` when the key selects nothing.
|
|
81
|
+
*/
|
|
82
|
+
const findCommandItemForHotkey = (matchable, fired) => matchable.find((entry) => (entry.kind === 'combination' || entry.kind === 'guarded') && hotkeyMatches(entry.steps[0], fired));
|
|
31
83
|
|
|
32
|
-
export { isDeepEqual };
|
|
84
|
+
export { findCommandItemForHotkey, isDeepEqual, planCommandItemHotkeys };
|
|
33
85
|
//# sourceMappingURL=commandMenu.utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commandMenu.utils.js","sources":["../../../../src/components/organisms/CommandMenu/commandMenu.utils.ts"],"sourcesContent":[null],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"commandMenu.utils.js","sources":["../../../../src/components/organisms/CommandMenu/commandMenu.utils.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var reactHotkeysHook = require('react-hotkeys-hook');
|
|
5
|
+
var useKeySequences = require('../../../../hooks/__internal__/useKeySequences/useKeySequences.cjs');
|
|
6
|
+
var hotkeys_utils = require('../../../../utilities/__internal__/hotkeysUtils/hotkeys.utils.cjs');
|
|
7
|
+
var log_utils = require('../../../../utilities/__internal__/logUtils/log.utils.cjs');
|
|
8
|
+
var commandMenu_utils = require('../commandMenu.utils.cjs');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Registers each command item's `shortcutKeys` and reports the item it selects.
|
|
12
|
+
* Combinations held with ⌘/Ctrl/Alt also fire while typing; everything else is ignored in a field.
|
|
13
|
+
* A shortcut that can never be triggered warns once.
|
|
14
|
+
*
|
|
15
|
+
* @param options The flat items, any extra disabled ids, and the selection callback.
|
|
16
|
+
* @returns Nothing. Selection is reported through `onSelectionChange`.
|
|
17
|
+
*/
|
|
18
|
+
const useCommandItemHotkeys = ({ items, disabledKeys, onSelectionChange }) => {
|
|
19
|
+
const plan = commandMenu_utils.planCommandItemHotkeys(items, disabledKeys);
|
|
20
|
+
React.useEffect(() => {
|
|
21
|
+
if (!plan.hasUnsupported)
|
|
22
|
+
return;
|
|
23
|
+
log_utils.warnOnce('CommandMenu:unsupported-shortcut', "CommandMenu: an item's `shortcutKeys` is drawn but can never be triggered. A sequence cannot contain a modifier (['⌘k', 'p']) and a modifier needs a key (['⌘']).");
|
|
24
|
+
}, [plan.hasUnsupported]);
|
|
25
|
+
const selectItemForHotkey = (keyboardEvent, hotkeysEvent) => {
|
|
26
|
+
keyboardEvent.preventDefault();
|
|
27
|
+
const match = commandMenu_utils.findCommandItemForHotkey(plan.matchable, hotkeysEvent);
|
|
28
|
+
if (match)
|
|
29
|
+
onSelectionChange?.(new Set([match.id]));
|
|
30
|
+
};
|
|
31
|
+
// Combinations held with ⌘/Ctrl/Alt cannot be mistaken for typing, so they also work inside the search input.
|
|
32
|
+
reactHotkeysHook.useHotkeys(plan.combination, selectItemForHotkey, {
|
|
33
|
+
enableOnFormTags: true,
|
|
34
|
+
// react-aria re-dispatches a key typed in the search input onto the list; once handled, skip the copy.
|
|
35
|
+
ignoreEventWhen: (event) => event.defaultPrevented,
|
|
36
|
+
});
|
|
37
|
+
// Everything typing could produce (Shift+A, `?`, G then P) is ignored in fields so it never hijacks text entry.
|
|
38
|
+
reactHotkeysHook.useHotkeys(plan.guarded, selectItemForHotkey, { ignoreEventWhen: (event) => event.defaultPrevented || hotkeys_utils.isTypingInField(event) });
|
|
39
|
+
useKeySequences.useKeySequences(plan.typed.map(({ steps }) => steps.map(hotkeys_utils.hotkeyCharacter)), (index) => onSelectionChange?.(new Set([plan.typed[index].id])));
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
exports.useCommandItemHotkeys = useCommandItemHotkeys;
|
|
43
|
+
//# sourceMappingURL=useCommandItemHotkeys.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCommandItemHotkeys.cjs","sources":["../../../../../src/components/organisms/CommandMenu/hooks/useCommandItemHotkeys.ts"],"sourcesContent":[null],"names":["planCommandItemHotkeys","useEffect","warnOnce","findCommandItemForHotkey","useHotkeys","isTypingInField","useKeySequences","hotkeyCharacter"],"mappings":";;;;;;;;;AAkBA;;;;;;;AAOG;AACI,MAAM,qBAAqB,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAgC,KAAU;IACtH,MAAM,IAAI,GAAGA,wCAAsB,CAAC,KAAK,EAAE,YAAY,CAAC;IAExDC,eAAS,CAAC,MAAK;QACb,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE;AAC1B,QAAAC,kBAAQ,CACN,kCAAkC,EAClC,mKAAmK,CACpK;AACH,IAAA,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AAEzB,IAAA,MAAM,mBAAmB,GAAmB,CAAC,aAAa,EAAE,YAAY,KAAI;QAC1E,aAAa,CAAC,cAAc,EAAE;QAC9B,MAAM,KAAK,GAAGC,0CAAwB,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC;AACpE,QAAA,IAAI,KAAK;AAAE,YAAA,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AACrD,IAAA,CAAC;;AAGD,IAAAC,2BAAU,CAAC,IAAI,CAAC,WAAW,EAAE,mBAAmB,EAAE;AAChD,QAAA,gBAAgB,EAAE,IAAI;;QAEtB,eAAe,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,gBAAgB;AACnD,KAAA,CAAC;;IAEFA,2BAAU,CAAC,IAAI,CAAC,OAAO,EAAE,mBAAmB,EAAE,EAAE,eAAe,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,gBAAgB,IAAIC,6BAAe,CAAC,KAAK,CAAC,EAAE,CAAC;IAC/HC,+BAAe,CACb,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,KAAK,CAAC,GAAG,CAACC,6BAAe,CAAC,CAAC,EACzD,CAAC,KAAK,KAAK,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAChE;AACH;;"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type CommandHotkeyItem } from '../commandMenu.utils';
|
|
2
|
+
export interface UseCommandItemHotkeysOptions {
|
|
3
|
+
/** Flat menu items in display order. */
|
|
4
|
+
items: readonly CommandHotkeyItem[];
|
|
5
|
+
/** Ids the list disables in addition to each item's `isDisabled`. */
|
|
6
|
+
disabledKeys?: Iterable<string | number>;
|
|
7
|
+
/** Called with a one-id set when a registered shortcut selects an item. */
|
|
8
|
+
onSelectionChange?: (keys: Set<string>) => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Registers each command item's `shortcutKeys` and reports the item it selects.
|
|
12
|
+
* Combinations held with ⌘/Ctrl/Alt also fire while typing; everything else is ignored in a field.
|
|
13
|
+
* A shortcut that can never be triggered warns once.
|
|
14
|
+
*
|
|
15
|
+
* @param options The flat items, any extra disabled ids, and the selection callback.
|
|
16
|
+
* @returns Nothing. Selection is reported through `onSelectionChange`.
|
|
17
|
+
*/
|
|
18
|
+
export declare const useCommandItemHotkeys: ({ items, disabledKeys, onSelectionChange }: UseCommandItemHotkeysOptions) => void;
|
|
19
|
+
//# sourceMappingURL=useCommandItemHotkeys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCommandItemHotkeys.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/CommandMenu/hooks/useCommandItemHotkeys.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,iBAAiB,EAAoD,MAAM,sBAAsB,CAAC;AAEhH,MAAM,WAAW,4BAA4B;IAC3C,wCAAwC;IACxC,KAAK,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACpC,qEAAqE;IACrE,YAAY,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IACzC,2EAA2E;IAC3E,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;CACjD;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAAI,4CAA4C,4BAA4B,KAAG,IA6BhH,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
import { useHotkeys } from 'react-hotkeys-hook';
|
|
3
|
+
import { useKeySequences } from '../../../../hooks/__internal__/useKeySequences/useKeySequences.js';
|
|
4
|
+
import { isTypingInField, hotkeyCharacter } from '../../../../utilities/__internal__/hotkeysUtils/hotkeys.utils.js';
|
|
5
|
+
import { warnOnce } from '../../../../utilities/__internal__/logUtils/log.utils.js';
|
|
6
|
+
import { planCommandItemHotkeys, findCommandItemForHotkey } from '../commandMenu.utils.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Registers each command item's `shortcutKeys` and reports the item it selects.
|
|
10
|
+
* Combinations held with ⌘/Ctrl/Alt also fire while typing; everything else is ignored in a field.
|
|
11
|
+
* A shortcut that can never be triggered warns once.
|
|
12
|
+
*
|
|
13
|
+
* @param options The flat items, any extra disabled ids, and the selection callback.
|
|
14
|
+
* @returns Nothing. Selection is reported through `onSelectionChange`.
|
|
15
|
+
*/
|
|
16
|
+
const useCommandItemHotkeys = ({ items, disabledKeys, onSelectionChange }) => {
|
|
17
|
+
const plan = planCommandItemHotkeys(items, disabledKeys);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (!plan.hasUnsupported)
|
|
20
|
+
return;
|
|
21
|
+
warnOnce('CommandMenu:unsupported-shortcut', "CommandMenu: an item's `shortcutKeys` is drawn but can never be triggered. A sequence cannot contain a modifier (['⌘k', 'p']) and a modifier needs a key (['⌘']).");
|
|
22
|
+
}, [plan.hasUnsupported]);
|
|
23
|
+
const selectItemForHotkey = (keyboardEvent, hotkeysEvent) => {
|
|
24
|
+
keyboardEvent.preventDefault();
|
|
25
|
+
const match = findCommandItemForHotkey(plan.matchable, hotkeysEvent);
|
|
26
|
+
if (match)
|
|
27
|
+
onSelectionChange?.(new Set([match.id]));
|
|
28
|
+
};
|
|
29
|
+
// Combinations held with ⌘/Ctrl/Alt cannot be mistaken for typing, so they also work inside the search input.
|
|
30
|
+
useHotkeys(plan.combination, selectItemForHotkey, {
|
|
31
|
+
enableOnFormTags: true,
|
|
32
|
+
// react-aria re-dispatches a key typed in the search input onto the list; once handled, skip the copy.
|
|
33
|
+
ignoreEventWhen: (event) => event.defaultPrevented,
|
|
34
|
+
});
|
|
35
|
+
// Everything typing could produce (Shift+A, `?`, G then P) is ignored in fields so it never hijacks text entry.
|
|
36
|
+
useHotkeys(plan.guarded, selectItemForHotkey, { ignoreEventWhen: (event) => event.defaultPrevented || isTypingInField(event) });
|
|
37
|
+
useKeySequences(plan.typed.map(({ steps }) => steps.map(hotkeyCharacter)), (index) => onSelectionChange?.(new Set([plan.typed[index].id])));
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { useCommandItemHotkeys };
|
|
41
|
+
//# sourceMappingURL=useCommandItemHotkeys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCommandItemHotkeys.js","sources":["../../../../../src/components/organisms/CommandMenu/hooks/useCommandItemHotkeys.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;;;;AAkBA;;;;;;;AAOG;AACI,MAAM,qBAAqB,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAgC,KAAU;IACtH,MAAM,IAAI,GAAG,sBAAsB,CAAC,KAAK,EAAE,YAAY,CAAC;IAExD,SAAS,CAAC,MAAK;QACb,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE;AAC1B,QAAA,QAAQ,CACN,kCAAkC,EAClC,mKAAmK,CACpK;AACH,IAAA,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AAEzB,IAAA,MAAM,mBAAmB,GAAmB,CAAC,aAAa,EAAE,YAAY,KAAI;QAC1E,aAAa,CAAC,cAAc,EAAE;QAC9B,MAAM,KAAK,GAAG,wBAAwB,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC;AACpE,QAAA,IAAI,KAAK;AAAE,YAAA,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AACrD,IAAA,CAAC;;AAGD,IAAA,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,mBAAmB,EAAE;AAChD,QAAA,gBAAgB,EAAE,IAAI;;QAEtB,eAAe,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,gBAAgB;AACnD,KAAA,CAAC;;IAEF,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,mBAAmB,EAAE,EAAE,eAAe,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,gBAAgB,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;IAC/H,eAAe,CACb,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,EACzD,CAAC,KAAK,KAAK,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAChE;AACH;;"}
|
|
@@ -7,15 +7,13 @@ var React = require('react');
|
|
|
7
7
|
var reactAriaComponents = require('react-aria-components');
|
|
8
8
|
var reactHotkeysHook = require('react-hotkeys-hook');
|
|
9
9
|
var useHotkeyHint = require('../../../hooks/__internal__/useHotkeyHint/useHotkeyHint.cjs');
|
|
10
|
-
var useKeySequences = require('../../../hooks/__internal__/useKeySequences/useKeySequences.cjs');
|
|
11
10
|
var children_utils = require('../../../utilities/__internal__/childrenUtils/children.utils.cjs');
|
|
12
11
|
var hotkeys_utils = require('../../../utilities/__internal__/hotkeysUtils/hotkeys.utils.cjs');
|
|
13
|
-
var log_utils = require('../../../utilities/__internal__/logUtils/log.utils.cjs');
|
|
14
|
-
var commandMenu_utils = require('./commandMenu.utils.cjs');
|
|
15
12
|
var CommandInput = require('./components/CommandInput.cjs');
|
|
16
13
|
var CommandMenuFooter = require('./components/CommandMenuFooter.cjs');
|
|
17
14
|
var CommandMenuHeader = require('./components/CommandMenuHeader.cjs');
|
|
18
15
|
var CommandMenuItem = require('./components/CommandMenuItem.cjs');
|
|
16
|
+
var useCommandItemHotkeys = require('./hooks/useCommandItemHotkeys.cjs');
|
|
19
17
|
var CommandMenuLink_context = require('./providers/CommandMenuLink.context.cjs');
|
|
20
18
|
|
|
21
19
|
const DEFAULT_SHORTCUT = '⌘/';
|
|
@@ -44,50 +42,7 @@ const CommandMenuRoot = ({ items, children, dialogClassName, overlayClassName, f
|
|
|
44
42
|
// Flatten the items and register hotkeys for items with shortcut keys.
|
|
45
43
|
const resolvedItems = items ?? defaultItems ?? [];
|
|
46
44
|
const flatItems = resolvedItems.flatMap((group) => group.items);
|
|
47
|
-
|
|
48
|
-
const itemHotkeys = flatItems
|
|
49
|
-
.filter((item) => !item.isDisabled && !disabledKeys.has(item.id))
|
|
50
|
-
.map((item) => ({ item, steps: hotkeys_utils.toHotkeySteps(item.shortcutKeys ?? []) }))
|
|
51
|
-
.filter(({ steps }) => steps.length > 0)
|
|
52
|
-
.map(({ item, steps }) => ({ item, steps, kind: hotkeys_utils.getItemHotkeyKind(steps) }));
|
|
53
|
-
const hotkeysOfKind = (kind) => itemHotkeys.filter((itemHotkey) => itemHotkey.kind === kind);
|
|
54
|
-
// Registering a hotkey twice would run the handler twice for one keypress.
|
|
55
|
-
const uniqueHotkeys = (kind) => [...new Set(hotkeysOfKind(kind).map(({ steps }) => steps[0]))];
|
|
56
|
-
const typedHotkeys = hotkeysOfKind('typed');
|
|
57
|
-
const hasUnsupportedHotkey = hotkeysOfKind('unsupported').length > 0;
|
|
58
|
-
React.useEffect(() => {
|
|
59
|
-
if (!hasUnsupportedHotkey)
|
|
60
|
-
return;
|
|
61
|
-
log_utils.warnOnce('CommandMenu:unsupported-shortcut', "CommandMenu: an item's `shortcutKeys` is drawn but can never be triggered. A sequence cannot contain a modifier (['⌘k', 'p']) and a modifier needs a key (['⌘']).");
|
|
62
|
-
}, [hasUnsupportedHotkey]);
|
|
63
|
-
const selectItemForHotkey = (keyboardEvent, hotkeysEvent) => {
|
|
64
|
-
keyboardEvent.preventDefault();
|
|
65
|
-
const match = itemHotkeys.find(({ kind, steps }) => {
|
|
66
|
-
if (kind !== 'combination' && kind !== 'guarded')
|
|
67
|
-
return false;
|
|
68
|
-
const parsedHotkey = hotkeys_utils.parseHotkey(steps[0]);
|
|
69
|
-
// `hotkeysEvent` carries fields (e.g. `metadata`) the vendored parser never produces, so compare only the identifying ones.
|
|
70
|
-
return (parsedHotkey.hotkey.trim().toLowerCase() === hotkeysEvent.hotkey?.trim().toLowerCase() &&
|
|
71
|
-
parsedHotkey.isSequence === hotkeysEvent.isSequence &&
|
|
72
|
-
parsedHotkey.alt === hotkeysEvent.alt &&
|
|
73
|
-
parsedHotkey.ctrl === hotkeysEvent.ctrl &&
|
|
74
|
-
parsedHotkey.shift === hotkeysEvent.shift &&
|
|
75
|
-
parsedHotkey.meta === hotkeysEvent.meta &&
|
|
76
|
-
parsedHotkey.mod === hotkeysEvent.mod &&
|
|
77
|
-
commandMenu_utils.isDeepEqual(parsedHotkey.keys, hotkeysEvent.keys));
|
|
78
|
-
});
|
|
79
|
-
if (match)
|
|
80
|
-
onSelectionChange?.(new Set([match.item.id]));
|
|
81
|
-
};
|
|
82
|
-
// Combinations held with ⌘/Ctrl/Alt cannot be mistaken for typing, so they also work inside the search input.
|
|
83
|
-
reactHotkeysHook.useHotkeys(uniqueHotkeys('combination'), selectItemForHotkey, {
|
|
84
|
-
enableOnFormTags: true,
|
|
85
|
-
// react-aria re-dispatches a key typed in the search input onto the list; once handled, skip the copy.
|
|
86
|
-
ignoreEventWhen: (event) => event.defaultPrevented,
|
|
87
|
-
});
|
|
88
|
-
// Everything typing could produce (Shift+A, `?`, G then P) is ignored in fields so it never hijacks text entry.
|
|
89
|
-
reactHotkeysHook.useHotkeys(uniqueHotkeys('guarded'), selectItemForHotkey, { ignoreEventWhen: (event) => event.defaultPrevented || hotkeys_utils.isTypingInField(event) });
|
|
90
|
-
useKeySequences.useKeySequences(typedHotkeys.map(({ steps }) => steps.map(hotkeys_utils.hotkeyCharacter)), (index) => onSelectionChange?.(new Set([typedHotkeys[index].item.id])));
|
|
45
|
+
useCommandItemHotkeys.useCommandItemHotkeys({ items: flatItems, disabledKeys: otherProps.disabledKeys, onSelectionChange });
|
|
91
46
|
// The shortcut only returns focus to the search input while the menu is open; opening is the app's job.
|
|
92
47
|
reactHotkeysHook.useHotkeys(hotkey, () => inputRef.current?.focus(), {
|
|
93
48
|
enabled: Boolean(hotkey) && isOpen,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../../../src/components/organisms/CommandMenu/index.tsx"],"sourcesContent":[null],"names":["createContext","useRef","useContext","OverlayTriggerStateContext","normalizeHotkey","useHotkeyHint","useFilter","useResolvedTestId","useState","
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../../../src/components/organisms/CommandMenu/index.tsx"],"sourcesContent":[null],"names":["createContext","useRef","useContext","OverlayTriggerStateContext","normalizeHotkey","useHotkeyHint","useFilter","useResolvedTestId","useState","useCommandItemHotkeys","useHotkeys","useMemo","flattenChildren","isValidElement","CommandMenuFooter","_jsx","TestIdProvider","CommandMenuLinkContext","_jsxs","AriaAutocomplete","AriaTextField","CommandInput","AriaModalOverlay","cx","AriaModal","AriaDialog","AriaListBox","AriaListBoxSection","CommandMenuHeader","AriaCollection","Fragment","CommandDropdownMenuItem","AriaDialogTrigger"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/CommandMenu/index.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,GAAG,EAAE,YAAY,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC9I,OAAO,EAEL,UAAU,IAAI,cAAc,EAE5B,aAAa,IAAI,iBAAiB,EAQnC,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/organisms/CommandMenu/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { cx } from '@flipdish/ui-library/utilities/cx';
|
|
3
3
|
import { useResolvedTestId, TestIdProvider } from '@flipdish/ui-library/utilities/testIdUtils';
|
|
4
|
-
import { createContext, useRef, useContext, useState,
|
|
4
|
+
import { createContext, useRef, useContext, useState, useMemo, isValidElement, Fragment } from 'react';
|
|
5
5
|
import { ModalOverlay, Modal, Dialog, OverlayTriggerStateContext, useFilter, Autocomplete, TextField, ListBox, ListBoxSection, Collection, DialogTrigger } from 'react-aria-components';
|
|
6
6
|
import { useHotkeys } from 'react-hotkeys-hook';
|
|
7
7
|
import { useHotkeyHint } from '../../../hooks/__internal__/useHotkeyHint/useHotkeyHint.js';
|
|
8
|
-
import { useKeySequences } from '../../../hooks/__internal__/useKeySequences/useKeySequences.js';
|
|
9
8
|
import { flattenChildren } from '../../../utilities/__internal__/childrenUtils/children.utils.js';
|
|
10
|
-
import { normalizeHotkey
|
|
11
|
-
import { warnOnce } from '../../../utilities/__internal__/logUtils/log.utils.js';
|
|
12
|
-
import { isDeepEqual } from './commandMenu.utils.js';
|
|
9
|
+
import { normalizeHotkey } from '../../../utilities/__internal__/hotkeysUtils/hotkeys.utils.js';
|
|
13
10
|
import { CommandInput } from './components/CommandInput.js';
|
|
14
11
|
import { CommandMenuFooter } from './components/CommandMenuFooter.js';
|
|
15
12
|
import { CommandMenuHeader } from './components/CommandMenuHeader.js';
|
|
16
13
|
import { CommandDropdownMenuItem } from './components/CommandMenuItem.js';
|
|
14
|
+
import { useCommandItemHotkeys } from './hooks/useCommandItemHotkeys.js';
|
|
17
15
|
import { CommandMenuLinkContext } from './providers/CommandMenuLink.context.js';
|
|
18
16
|
|
|
19
17
|
const DEFAULT_SHORTCUT = '⌘/';
|
|
@@ -42,50 +40,7 @@ const CommandMenuRoot = ({ items, children, dialogClassName, overlayClassName, f
|
|
|
42
40
|
// Flatten the items and register hotkeys for items with shortcut keys.
|
|
43
41
|
const resolvedItems = items ?? defaultItems ?? [];
|
|
44
42
|
const flatItems = resolvedItems.flatMap((group) => group.items);
|
|
45
|
-
|
|
46
|
-
const itemHotkeys = flatItems
|
|
47
|
-
.filter((item) => !item.isDisabled && !disabledKeys.has(item.id))
|
|
48
|
-
.map((item) => ({ item, steps: toHotkeySteps(item.shortcutKeys ?? []) }))
|
|
49
|
-
.filter(({ steps }) => steps.length > 0)
|
|
50
|
-
.map(({ item, steps }) => ({ item, steps, kind: getItemHotkeyKind(steps) }));
|
|
51
|
-
const hotkeysOfKind = (kind) => itemHotkeys.filter((itemHotkey) => itemHotkey.kind === kind);
|
|
52
|
-
// Registering a hotkey twice would run the handler twice for one keypress.
|
|
53
|
-
const uniqueHotkeys = (kind) => [...new Set(hotkeysOfKind(kind).map(({ steps }) => steps[0]))];
|
|
54
|
-
const typedHotkeys = hotkeysOfKind('typed');
|
|
55
|
-
const hasUnsupportedHotkey = hotkeysOfKind('unsupported').length > 0;
|
|
56
|
-
useEffect(() => {
|
|
57
|
-
if (!hasUnsupportedHotkey)
|
|
58
|
-
return;
|
|
59
|
-
warnOnce('CommandMenu:unsupported-shortcut', "CommandMenu: an item's `shortcutKeys` is drawn but can never be triggered. A sequence cannot contain a modifier (['⌘k', 'p']) and a modifier needs a key (['⌘']).");
|
|
60
|
-
}, [hasUnsupportedHotkey]);
|
|
61
|
-
const selectItemForHotkey = (keyboardEvent, hotkeysEvent) => {
|
|
62
|
-
keyboardEvent.preventDefault();
|
|
63
|
-
const match = itemHotkeys.find(({ kind, steps }) => {
|
|
64
|
-
if (kind !== 'combination' && kind !== 'guarded')
|
|
65
|
-
return false;
|
|
66
|
-
const parsedHotkey = parseHotkey(steps[0]);
|
|
67
|
-
// `hotkeysEvent` carries fields (e.g. `metadata`) the vendored parser never produces, so compare only the identifying ones.
|
|
68
|
-
return (parsedHotkey.hotkey.trim().toLowerCase() === hotkeysEvent.hotkey?.trim().toLowerCase() &&
|
|
69
|
-
parsedHotkey.isSequence === hotkeysEvent.isSequence &&
|
|
70
|
-
parsedHotkey.alt === hotkeysEvent.alt &&
|
|
71
|
-
parsedHotkey.ctrl === hotkeysEvent.ctrl &&
|
|
72
|
-
parsedHotkey.shift === hotkeysEvent.shift &&
|
|
73
|
-
parsedHotkey.meta === hotkeysEvent.meta &&
|
|
74
|
-
parsedHotkey.mod === hotkeysEvent.mod &&
|
|
75
|
-
isDeepEqual(parsedHotkey.keys, hotkeysEvent.keys));
|
|
76
|
-
});
|
|
77
|
-
if (match)
|
|
78
|
-
onSelectionChange?.(new Set([match.item.id]));
|
|
79
|
-
};
|
|
80
|
-
// Combinations held with ⌘/Ctrl/Alt cannot be mistaken for typing, so they also work inside the search input.
|
|
81
|
-
useHotkeys(uniqueHotkeys('combination'), selectItemForHotkey, {
|
|
82
|
-
enableOnFormTags: true,
|
|
83
|
-
// react-aria re-dispatches a key typed in the search input onto the list; once handled, skip the copy.
|
|
84
|
-
ignoreEventWhen: (event) => event.defaultPrevented,
|
|
85
|
-
});
|
|
86
|
-
// Everything typing could produce (Shift+A, `?`, G then P) is ignored in fields so it never hijacks text entry.
|
|
87
|
-
useHotkeys(uniqueHotkeys('guarded'), selectItemForHotkey, { ignoreEventWhen: (event) => event.defaultPrevented || isTypingInField(event) });
|
|
88
|
-
useKeySequences(typedHotkeys.map(({ steps }) => steps.map(hotkeyCharacter)), (index) => onSelectionChange?.(new Set([typedHotkeys[index].item.id])));
|
|
43
|
+
useCommandItemHotkeys({ items: flatItems, disabledKeys: otherProps.disabledKeys, onSelectionChange });
|
|
89
44
|
// The shortcut only returns focus to the search input while the menu is open; opening is the app's job.
|
|
90
45
|
useHotkeys(hotkey, () => inputRef.current?.focus(), {
|
|
91
46
|
enabled: Boolean(hotkey) && isOpen,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../../src/components/organisms/CommandMenu/index.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs","AriaAutocomplete","AriaTextField","AriaModalOverlay","AriaModal","AriaDialog","AriaListBox","AriaListBoxSection","AriaCollection","AriaDialogTrigger"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../src/components/organisms/CommandMenu/index.tsx"],"sourcesContent":[null],"names":["_jsx","_jsxs","AriaAutocomplete","AriaTextField","AriaModalOverlay","AriaModal","AriaDialog","AriaListBox","AriaListBoxSection","AriaCollection","AriaDialogTrigger"],"mappings":"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"}
|
|
@@ -1,12 +1,50 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
export interface RadioButtonProps {
|
|
3
|
+
/** Identifies this option within its `RadioGroup`; selecting it sets the group's value to this. */
|
|
4
|
+
value: string;
|
|
5
|
+
/** Sets the circle size and the label and hint text size; a parent `RadioGroup`'s `size` overrides it. */
|
|
6
|
+
size?: 'sm' | 'md';
|
|
7
|
+
/** Text shown beside the circle; pressing it selects the option. */
|
|
8
|
+
label?: ReactNode;
|
|
9
|
+
/** Supporting text shown below the label. */
|
|
10
|
+
hint?: ReactNode;
|
|
11
|
+
/** Disables this option and shows a reduced-opacity state. */
|
|
12
|
+
isDisabled?: boolean;
|
|
13
|
+
/** Extra classes merged onto the root `Pressable`. */
|
|
14
|
+
className?: string;
|
|
15
|
+
/** Web-style accessible name, used as `accessibilityLabel` so shared call sites work on both platforms. */
|
|
16
|
+
'aria-label'?: string;
|
|
17
|
+
/** Overrides the derived `testID` (defaults to `<group>--option-<value>` or `fd-radio-button`). */
|
|
18
|
+
'data-testid'?: string;
|
|
19
|
+
}
|
|
1
20
|
/**
|
|
2
|
-
* `RadioButton`
|
|
21
|
+
* React Native `RadioButton` — the same circle, dot, label and hint as web, built from
|
|
22
|
+
* `Pressable` and `View` instead of a react-aria `Radio`. Selection lives in the parent
|
|
23
|
+
* `RadioGroup`; there is no arrow-key navigation between options on touch devices.
|
|
3
24
|
*
|
|
4
|
-
*
|
|
5
|
-
* that importing `@flipdish/ui-library/components/atoms/RadioButton` from React Native fails at
|
|
6
|
-
* compile time rather than resolving to the web build's types. There is no
|
|
7
|
-
* matching `index.js`, so Metro cannot bundle this module either.
|
|
8
|
-
*
|
|
9
|
-
* To make `RadioButton` available on React Native, add an `index.native.tsx` beside
|
|
10
|
-
* its `index.tsx` — the build picks it up automatically and this stub disappears.
|
|
25
|
+
* @summary one option in a mutually exclusive group (React Native)
|
|
11
26
|
*/
|
|
12
|
-
export declare const
|
|
27
|
+
export declare const RadioButton: ({ value, label, hint, className, size: sizeProp, isDisabled: isDisabledProp, "aria-label": ariaLabel, "data-testid": dataTestId, }: RadioButtonProps) => import("react").JSX.Element;
|
|
28
|
+
export interface RadioGroupProps {
|
|
29
|
+
/** The `RadioButton` options. */
|
|
30
|
+
children: ReactNode;
|
|
31
|
+
/** Sets the size of every option in the group. */
|
|
32
|
+
size?: 'sm' | 'md';
|
|
33
|
+
/** Controlled selected value. */
|
|
34
|
+
value?: string | null;
|
|
35
|
+
/** Initial selected value for uncontrolled usage. */
|
|
36
|
+
defaultValue?: string | null;
|
|
37
|
+
/** Called with the newly selected option's `value`. */
|
|
38
|
+
onChange?: (value: string) => void;
|
|
39
|
+
/** Disables every option in the group. */
|
|
40
|
+
isDisabled?: boolean;
|
|
41
|
+
/** Extra classes merged onto the root `View`. */
|
|
42
|
+
className?: string;
|
|
43
|
+
/** Web-style accessible name for the group; native has no `aria-labelledby`, so set this whenever the group needs a name. */
|
|
44
|
+
'aria-label'?: string;
|
|
45
|
+
/** Overrides the `testID` (defaults to `fd-radio-group`). */
|
|
46
|
+
'data-testid'?: string;
|
|
47
|
+
}
|
|
48
|
+
/** React Native `RadioGroup` that stacks its `RadioButton` children, owns which one is selected, and passes them `size` and a derived `testID`. */
|
|
49
|
+
export declare const RadioGroup: ({ children, className, size, value, defaultValue, onChange, isDisabled, "aria-label": ariaLabel, "data-testid": dataTestId, }: RadioGroupProps) => import("react").JSX.Element;
|
|
50
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/atoms/RadioButton/index.native.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAiB,KAAK,SAAS,EAAwB,MAAM,OAAO,CAAC;AAgB5E,MAAM,WAAW,gBAAgB;IAC/B,mGAAmG;IACnG,KAAK,EAAE,MAAM,CAAC;IACd,0GAA0G;IAC1G,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,oEAAoE;IACpE,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2GAA2G;IAC3G,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mGAAmG;IACnG,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,GAAI,oIASzB,gBAAgB,gCAqClB,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,iCAAiC;IACjC,QAAQ,EAAE,SAAS,CAAC;IACpB,kDAAkD;IAClD,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,uDAAuD;IACvD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,0CAA0C;IAC1C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6HAA6H;IAC7H,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,mJAAmJ;AACnJ,eAAO,MAAM,UAAU,GAAI,+HAUxB,eAAe,gCAkBjB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { cx } from '../../../utilities/cx/index.js';
|
|
3
|
+
import { useResolvedTestId, joinTestId, slugifyTestId } from '../../../utilities/testIdUtils/index.js';
|
|
4
|
+
import { createContext, useContext, useState } from 'react';
|
|
5
|
+
import { Pressable, View } from 'react-native';
|
|
6
|
+
import { SelectionControlText } from '../../__internal__/selectionControl/SelectionControlText.js';
|
|
7
|
+
import { selectionControlSizes } from '../../__internal__/selectionControl/selectionControl.styles.js';
|
|
8
|
+
import { SELECTION_CONTROL_HIT_SLOP, getAccessibleHint, getAccessibleName } from '../../__internal__/selectionControl/selectionControl.utils.js';
|
|
9
|
+
|
|
10
|
+
const RadioGroupContext = createContext(null);
|
|
11
|
+
/**
|
|
12
|
+
* React Native `RadioButton` — the same circle, dot, label and hint as web, built from
|
|
13
|
+
* `Pressable` and `View` instead of a react-aria `Radio`. Selection lives in the parent
|
|
14
|
+
* `RadioGroup`; there is no arrow-key navigation between options on touch devices.
|
|
15
|
+
*
|
|
16
|
+
* @summary one option in a mutually exclusive group (React Native)
|
|
17
|
+
*/
|
|
18
|
+
const RadioButton = ({ value, label, hint, className, size: sizeProp = 'sm', isDisabled: isDisabledProp, 'aria-label': ariaLabel, 'data-testid': dataTestId, }) => {
|
|
19
|
+
const group = useContext(RadioGroupContext);
|
|
20
|
+
const size = group?.size ?? sizeProp;
|
|
21
|
+
const isDisabled = Boolean(isDisabledProp || group?.isDisabled);
|
|
22
|
+
const isSelected = group?.selectedValue === value;
|
|
23
|
+
const fallbackTestId = useResolvedTestId({ testId: dataTestId, segment: 'radio-button', rootName: 'radio-button' });
|
|
24
|
+
const radioTestId = !dataTestId && group ? joinTestId(group.testIdPrefix, `option-${slugifyTestId(value)}`) : fallbackTestId;
|
|
25
|
+
return (jsxs(Pressable, { testID: radioTestId, disabled: isDisabled, onPress: () => group?.select(value), accessibilityRole: "radio", hitSlop: SELECTION_CONTROL_HIT_SLOP, accessibilityLabel: getAccessibleName(ariaLabel, label), accessibilityHint: getAccessibleHint(hint), accessibilityState: { checked: isSelected, disabled: isDisabled }, className: cx('relative flex flex-row items-start self-start', selectionControlSizes[size].root, className), children: [jsx(View, { className: cx('size-4 shrink-0 items-center justify-center rounded-full border border-primary bg-primary', size === 'md' && 'size-5', isSelected && 'border-brand-solid bg-brand-solid', isDisabled && 'opacity-50', isDisabled && !isSelected && 'bg-tertiary', (label || hint) && 'mt-0.5'), children: isSelected ? jsx(View, { className: cx('size-1.5 rounded-full bg-fg-white', size === 'md' && 'size-2') }) : null }), jsx(SelectionControlText, { size: size, label: label, hint: hint })] }));
|
|
26
|
+
};
|
|
27
|
+
/** React Native `RadioGroup` that stacks its `RadioButton` children, owns which one is selected, and passes them `size` and a derived `testID`. */
|
|
28
|
+
const RadioGroup = ({ children, className, size = 'sm', value, defaultValue = null, onChange, isDisabled = false, 'aria-label': ariaLabel, 'data-testid': dataTestId, }) => {
|
|
29
|
+
const rootTestId = useResolvedTestId({ testId: dataTestId, segment: 'radio-group', rootName: 'radio-group' });
|
|
30
|
+
const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
|
|
31
|
+
const selectedValue = value !== undefined ? value : uncontrolledValue;
|
|
32
|
+
const select = (next) => {
|
|
33
|
+
if (next === selectedValue)
|
|
34
|
+
return;
|
|
35
|
+
if (value === undefined)
|
|
36
|
+
setUncontrolledValue(next);
|
|
37
|
+
onChange?.(next);
|
|
38
|
+
};
|
|
39
|
+
return (jsx(RadioGroupContext.Provider, { value: { size, testIdPrefix: rootTestId, selectedValue, isDisabled, select }, children: jsx(View, { testID: rootTestId, accessibilityRole: "radiogroup", accessibilityLabel: ariaLabel, className: cx('flex flex-col gap-4', className), children: children }) }));
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export { RadioButton, RadioGroup };
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../../../../src/components/atoms/RadioButton/index.native.tsx"],"sourcesContent":[null],"names":["_jsxs","_jsx"],"mappings":"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"}
|