@lumx/react 3.0.1 → 3.0.2

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 (66) hide show
  1. package/esm/_internal/ClickAwayProvider.js +9 -5
  2. package/esm/_internal/ClickAwayProvider.js.map +1 -1
  3. package/esm/_internal/FlexBox.js.map +1 -1
  4. package/esm/_internal/HeadingLevelProvider.js +112 -0
  5. package/esm/_internal/HeadingLevelProvider.js.map +1 -0
  6. package/esm/_internal/ProgressTrackerStepPanel.js +2 -1
  7. package/esm/_internal/ProgressTrackerStepPanel.js.map +1 -1
  8. package/esm/_internal/Slides.js +270 -79
  9. package/esm/_internal/Slides.js.map +1 -1
  10. package/esm/_internal/TabPanel.js +2 -1
  11. package/esm/_internal/TabPanel.js.map +1 -1
  12. package/esm/_internal/Text2.js +63 -0
  13. package/esm/_internal/Text2.js.map +1 -0
  14. package/esm/_internal/_rollupPluginBabelHelpers.js +17 -1
  15. package/esm/_internal/_rollupPluginBabelHelpers.js.map +1 -1
  16. package/esm/_internal/components.js +1 -0
  17. package/esm/_internal/components.js.map +1 -1
  18. package/esm/_internal/heading.js +11 -0
  19. package/esm/_internal/heading.js.map +1 -0
  20. package/esm/_internal/progress-tracker.js +2 -1
  21. package/esm/_internal/progress-tracker.js.map +1 -1
  22. package/esm/_internal/slideshow.js +2 -0
  23. package/esm/_internal/slideshow.js.map +1 -1
  24. package/esm/_internal/state.js +145 -0
  25. package/esm/_internal/state.js.map +1 -0
  26. package/esm/_internal/tabs.js +1 -0
  27. package/esm/_internal/tabs.js.map +1 -1
  28. package/esm/_internal/text.js +10 -0
  29. package/esm/_internal/text.js.map +1 -0
  30. package/esm/_internal/useRovingTabIndex.js +9 -144
  31. package/esm/_internal/useRovingTabIndex.js.map +1 -1
  32. package/esm/index.js +5 -1
  33. package/esm/index.js.map +1 -1
  34. package/package.json +4 -5
  35. package/src/components/flex-box/FlexBox.stories.tsx +60 -4
  36. package/src/components/flex-box/FlexBox.tsx +7 -4
  37. package/src/components/flex-box/__snapshots__/FlexBox.test.tsx.snap +35 -0
  38. package/src/components/heading/Heading.stories.tsx +108 -0
  39. package/src/components/heading/Heading.test.tsx +77 -0
  40. package/src/components/heading/Heading.tsx +62 -0
  41. package/src/components/heading/HeadingLevelProvider.tsx +30 -0
  42. package/src/components/heading/constants.ts +16 -0
  43. package/src/components/heading/context.tsx +13 -0
  44. package/src/components/heading/index.ts +3 -0
  45. package/src/components/heading/useHeadingLevel.tsx +8 -0
  46. package/src/components/index.ts +1 -0
  47. package/src/components/slideshow/Slides.tsx +33 -3
  48. package/src/components/slideshow/Slideshow.stories.tsx +98 -2
  49. package/src/components/slideshow/Slideshow.tsx +15 -3
  50. package/src/components/slideshow/SlideshowControls.stories.tsx +1 -1
  51. package/src/components/slideshow/SlideshowControls.tsx +49 -11
  52. package/src/components/slideshow/SlideshowItem.tsx +0 -5
  53. package/src/components/slideshow/SlideshowItemGroup.tsx +63 -0
  54. package/src/components/slideshow/__snapshots__/Slideshow.test.tsx.snap +4 -1
  55. package/src/components/slideshow/useSlideFocusManagement.tsx +92 -0
  56. package/src/components/text/Text.stories.tsx +80 -0
  57. package/src/components/text/Text.test.tsx +62 -0
  58. package/src/components/text/Text.tsx +94 -0
  59. package/src/components/text/index.ts +1 -0
  60. package/src/hooks/useRovingTabIndex.tsx +9 -0
  61. package/src/index.ts +2 -0
  62. package/src/utils/focus/constants.ts +5 -0
  63. package/src/utils/focus/getFirstAndLastFocusable.ts +4 -10
  64. package/src/utils/focus/getFocusableElements.test.ts +151 -0
  65. package/src/utils/focus/getFocusableElements.ts +7 -0
  66. package/types.d.ts +94 -7
@@ -1 +1 @@
1
- {"version":3,"file":"slideshow.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"slideshow.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,145 @@
1
+ import { e as _toConsumableArray, _ as _objectSpread2, a as _defineProperty, d as _slicedToArray } from './_rollupPluginBabelHelpers.js';
2
+ import { createContext, useContext, useMemo, useEffect, useCallback } from 'react';
3
+ import { u as uid } from '../index2.js';
4
+
5
+ var INIT_STATE = {
6
+ isLazy: true,
7
+ shouldActivateOnFocus: false,
8
+ activeTabIndex: 0,
9
+ ids: {
10
+ tab: [],
11
+ tabPanel: []
12
+ }
13
+ };
14
+ var reducer = function reducer(state, action) {
15
+ switch (action.type) {
16
+ case 'update':
17
+ return _objectSpread2({}, state, {}, action.payload);
18
+
19
+ case 'setActiveTabIndex':
20
+ {
21
+ if (state.activeTabIndex === action.payload) {
22
+ return state;
23
+ } // Change active tab index.
24
+
25
+
26
+ return _objectSpread2({}, state, {
27
+ activeTabIndex: action.payload
28
+ });
29
+ }
30
+
31
+ case 'register':
32
+ {
33
+ var _action$payload = action.payload,
34
+ type = _action$payload.type,
35
+ id = _action$payload.id; // Append tab/tabPanel id in state.
36
+
37
+ return _objectSpread2({}, state, {
38
+ ids: _objectSpread2({}, state.ids, _defineProperty({}, type, [].concat(_toConsumableArray(state.ids[type]), [id])))
39
+ });
40
+ }
41
+
42
+ case 'unregister':
43
+ {
44
+ var _action$payload2 = action.payload,
45
+ _type = _action$payload2.type,
46
+ _id = _action$payload2.id;
47
+
48
+ var index = state.ids[_type].indexOf(_id);
49
+
50
+ if (index === -1) return state; // Remove tab & tab panel at index.
51
+
52
+ var tabIds = _toConsumableArray(state.ids.tab);
53
+
54
+ tabIds.splice(index, 1);
55
+
56
+ var tabPanelIds = _toConsumableArray(state.ids.tabPanel);
57
+
58
+ tabPanelIds.splice(index, 1);
59
+ return _objectSpread2({}, state, {
60
+ ids: {
61
+ tab: tabIds,
62
+ tabPanel: tabPanelIds
63
+ }
64
+ });
65
+ }
66
+
67
+ default:
68
+ return state;
69
+ }
70
+ };
71
+ var TabProviderContext = createContext(null);
72
+
73
+ /* eslint-disable react-hooks/rules-of-hooks */
74
+ var useTabProviderContext = function useTabProviderContext(type, originalId) {
75
+ var context = useContext(TabProviderContext);
76
+
77
+ if (!context) {
78
+ return undefined;
79
+ }
80
+
81
+ var _context = _slicedToArray(context, 2),
82
+ state = _context[0],
83
+ dispatch = _context[1]; // Current tab or tab panel id.
84
+
85
+
86
+ var id = useMemo(function () {
87
+ return originalId || "".concat(type, "-").concat(uid());
88
+ }, // eslint-disable-next-line react-hooks/exhaustive-deps
89
+ []);
90
+ useEffect(function () {
91
+ // On mount: register tab or tab panel id.
92
+ dispatch({
93
+ type: 'register',
94
+ payload: {
95
+ type: type,
96
+ id: id
97
+ }
98
+ });
99
+ return function () {
100
+ // On unmount: unregister tab or tab panel id.
101
+ dispatch({
102
+ type: 'unregister',
103
+ payload: {
104
+ type: type,
105
+ id: id
106
+ }
107
+ });
108
+ };
109
+ }, // eslint-disable-next-line react-hooks/exhaustive-deps
110
+ []); // Find tab/tabPanel index using it's id.
111
+
112
+ var index = useMemo(function () {
113
+ return state.ids[type].indexOf(id);
114
+ }, [state.ids, type, id]);
115
+ var tabId = useMemo(function () {
116
+ return state.ids.tab[index] || '';
117
+ }, [state, index]);
118
+ var tabPanelId = useMemo(function () {
119
+ return state.ids.tabPanel[index] || '';
120
+ }, [state, index]);
121
+ var isActive = useMemo(function () {
122
+ return state.activeTabIndex === index;
123
+ }, [state, index]);
124
+ var changeToTab = useCallback(function () {
125
+ return dispatch({
126
+ type: 'setActiveTabIndex',
127
+ payload: index
128
+ });
129
+ }, [dispatch, index]);
130
+ return {
131
+ isLazy: state.isLazy,
132
+ shouldActivateOnFocus: state.shouldActivateOnFocus,
133
+ tabId: tabId,
134
+ tabPanelId: tabPanelId,
135
+ isActive: isActive,
136
+ changeToTab: changeToTab
137
+ };
138
+ };
139
+ var useTabProviderContextState = function useTabProviderContextState() {
140
+ var context = useContext(TabProviderContext);
141
+ return context === null || context === void 0 ? void 0 : context[0];
142
+ };
143
+
144
+ export { INIT_STATE as I, TabProviderContext as T, useTabProviderContext as a, reducer as r, useTabProviderContextState as u };
145
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sources":["../../../src/components/tabs/state.ts"],"sourcesContent":["import { Dispatch, createContext, useCallback, useContext, useEffect, useMemo } from 'react';\nimport { uid } from 'uid';\n\ntype TabType = 'tab' | 'tabPanel';\n\nexport interface State {\n isLazy: boolean;\n shouldActivateOnFocus: boolean;\n activeTabIndex: number;\n ids: Record<TabType, string[]>;\n}\n\nexport const INIT_STATE: State = {\n isLazy: true,\n shouldActivateOnFocus: false,\n activeTabIndex: 0,\n ids: { tab: [], tabPanel: [] },\n};\n\nexport type Action =\n | { type: 'update'; payload: Partial<State> }\n | { type: 'setActiveTabIndex'; payload: number }\n | { type: 'register'; payload: { type: TabType; id: string } }\n | { type: 'unregister'; payload: { type: TabType; id: string } };\n\nexport const reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case 'update':\n return { ...state, ...action.payload };\n case 'setActiveTabIndex': {\n if (state.activeTabIndex === action.payload) {\n return state;\n }\n // Change active tab index.\n return { ...state, activeTabIndex: action.payload };\n }\n case 'register': {\n const { type, id } = action.payload;\n // Append tab/tabPanel id in state.\n return { ...state, ids: { ...state.ids, [type]: [...state.ids[type], id] } };\n }\n case 'unregister': {\n const { type, id } = action.payload;\n const index = state.ids[type].indexOf(id);\n if (index === -1) return state;\n // Remove tab & tab panel at index.\n const tabIds = [...state.ids.tab];\n tabIds.splice(index, 1);\n const tabPanelIds = [...state.ids.tabPanel];\n tabPanelIds.splice(index, 1);\n return {\n ...state,\n ids: { tab: tabIds, tabPanel: tabPanelIds },\n };\n }\n default:\n return state;\n }\n};\n\nexport const TabProviderContext = createContext<[State, Dispatch<Action>] | null>(null);\n\nexport type TabState = Pick<Required<State>, 'isLazy' | 'shouldActivateOnFocus'> & {\n isActive: boolean;\n tabId: string;\n tabPanelId: string;\n changeToTab(): void;\n};\n\n/* eslint-disable react-hooks/rules-of-hooks */\nexport const useTabProviderContext = (type: TabType, originalId?: string): undefined | TabState => {\n const context = useContext(TabProviderContext);\n if (!context) {\n return undefined;\n }\n const [state, dispatch] = context;\n\n // Current tab or tab panel id.\n const id = useMemo(\n () => originalId || `${type}-${uid()}`,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n useEffect(\n () => {\n // On mount: register tab or tab panel id.\n dispatch({ type: 'register', payload: { type, id } });\n return () => {\n // On unmount: unregister tab or tab panel id.\n dispatch({ type: 'unregister', payload: { type, id } });\n };\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n // Find tab/tabPanel index using it's id.\n const index = useMemo(() => state.ids[type].indexOf(id), [state.ids, type, id]);\n const tabId = useMemo(() => state.ids.tab[index] || '', [state, index]);\n const tabPanelId = useMemo(() => state.ids.tabPanel[index] || '', [state, index]);\n const isActive = useMemo(() => state.activeTabIndex === index, [state, index]);\n const changeToTab = useCallback(() => dispatch({ type: 'setActiveTabIndex', payload: index }), [dispatch, index]);\n return {\n isLazy: state.isLazy,\n shouldActivateOnFocus: state.shouldActivateOnFocus,\n tabId,\n tabPanelId,\n isActive,\n changeToTab,\n };\n};\n\nexport const useTabProviderContextState = (): State | undefined => {\n const context = useContext(TabProviderContext);\n return context?.[0];\n};\n"],"names":["INIT_STATE","isLazy","shouldActivateOnFocus","activeTabIndex","ids","tab","tabPanel","reducer","state","action","type","payload","id","index","indexOf","tabIds","splice","tabPanelIds","TabProviderContext","createContext","useTabProviderContext","originalId","context","useContext","undefined","dispatch","useMemo","uid","useEffect","tabId","tabPanelId","isActive","changeToTab","useCallback","useTabProviderContextState"],"mappings":"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"}
@@ -9,6 +9,7 @@ import 'lodash/isEmpty';
9
9
  import 'lodash/kebabCase';
10
10
  import 'lodash/noop';
11
11
  import './mergeRefs.js';
12
+ import './state.js';
12
13
  import './useRovingTabIndex.js';
13
14
  export { c as Tab, b as TabList, a as TabListLayout, d as TabPanel, T as TabProvider } from './TabPanel.js';
14
15
  //# sourceMappingURL=tabs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tabs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
1
+ {"version":3,"file":"tabs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;"}
@@ -0,0 +1,10 @@
1
+ import './_rollupPluginBabelHelpers.js';
2
+ import './components.js';
3
+ import 'react';
4
+ import './getRootClassName.js';
5
+ import 'lodash/isBoolean';
6
+ import 'lodash/isEmpty';
7
+ import 'lodash/kebabCase';
8
+ import 'lodash/noop';
9
+ export { T as Text } from './Text2.js';
10
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -1,150 +1,11 @@
1
- import { e as _toConsumableArray, _ as _objectSpread2, a as _defineProperty, d as _slicedToArray } from './_rollupPluginBabelHelpers.js';
2
- import { createContext, useContext, useMemo, useEffect, useCallback } from 'react';
3
- import { u as uid } from '../index2.js';
4
-
5
- var INIT_STATE = {
6
- isLazy: true,
7
- shouldActivateOnFocus: false,
8
- activeTabIndex: 0,
9
- ids: {
10
- tab: [],
11
- tabPanel: []
12
- }
13
- };
14
- var reducer = function reducer(state, action) {
15
- switch (action.type) {
16
- case 'update':
17
- return _objectSpread2({}, state, {}, action.payload);
18
-
19
- case 'setActiveTabIndex':
20
- {
21
- if (state.activeTabIndex === action.payload) {
22
- return state;
23
- } // Change active tab index.
24
-
25
-
26
- return _objectSpread2({}, state, {
27
- activeTabIndex: action.payload
28
- });
29
- }
30
-
31
- case 'register':
32
- {
33
- var _action$payload = action.payload,
34
- type = _action$payload.type,
35
- id = _action$payload.id; // Append tab/tabPanel id in state.
36
-
37
- return _objectSpread2({}, state, {
38
- ids: _objectSpread2({}, state.ids, _defineProperty({}, type, [].concat(_toConsumableArray(state.ids[type]), [id])))
39
- });
40
- }
41
-
42
- case 'unregister':
43
- {
44
- var _action$payload2 = action.payload,
45
- _type = _action$payload2.type,
46
- _id = _action$payload2.id;
47
-
48
- var index = state.ids[_type].indexOf(_id);
49
-
50
- if (index === -1) return state; // Remove tab & tab panel at index.
51
-
52
- var tabIds = _toConsumableArray(state.ids.tab);
53
-
54
- tabIds.splice(index, 1);
55
-
56
- var tabPanelIds = _toConsumableArray(state.ids.tabPanel);
57
-
58
- tabPanelIds.splice(index, 1);
59
- return _objectSpread2({}, state, {
60
- ids: {
61
- tab: tabIds,
62
- tabPanel: tabPanelIds
63
- }
64
- });
65
- }
66
-
67
- default:
68
- return state;
69
- }
70
- };
71
- var TabProviderContext = createContext(null);
72
-
73
- /* eslint-disable react-hooks/rules-of-hooks */
74
- var useTabProviderContext = function useTabProviderContext(type, originalId) {
75
- var context = useContext(TabProviderContext);
76
-
77
- if (!context) {
78
- return undefined;
79
- }
80
-
81
- var _context = _slicedToArray(context, 2),
82
- state = _context[0],
83
- dispatch = _context[1]; // Current tab or tab panel id.
84
-
85
-
86
- var id = useMemo(function () {
87
- return originalId || "".concat(type, "-").concat(uid());
88
- }, // eslint-disable-next-line react-hooks/exhaustive-deps
89
- []);
90
- useEffect(function () {
91
- // On mount: register tab or tab panel id.
92
- dispatch({
93
- type: 'register',
94
- payload: {
95
- type: type,
96
- id: id
97
- }
98
- });
99
- return function () {
100
- // On unmount: unregister tab or tab panel id.
101
- dispatch({
102
- type: 'unregister',
103
- payload: {
104
- type: type,
105
- id: id
106
- }
107
- });
108
- };
109
- }, // eslint-disable-next-line react-hooks/exhaustive-deps
110
- []); // Find tab/tabPanel index using it's id.
111
-
112
- var index = useMemo(function () {
113
- return state.ids[type].indexOf(id);
114
- }, [state.ids, type, id]);
115
- var tabId = useMemo(function () {
116
- return state.ids.tab[index] || '';
117
- }, [state, index]);
118
- var tabPanelId = useMemo(function () {
119
- return state.ids.tabPanel[index] || '';
120
- }, [state, index]);
121
- var isActive = useMemo(function () {
122
- return state.activeTabIndex === index;
123
- }, [state, index]);
124
- var changeToTab = useCallback(function () {
125
- return dispatch({
126
- type: 'setActiveTabIndex',
127
- payload: index
128
- });
129
- }, [dispatch, index]);
130
- return {
131
- isLazy: state.isLazy,
132
- shouldActivateOnFocus: state.shouldActivateOnFocus,
133
- tabId: tabId,
134
- tabPanelId: tabPanelId,
135
- isActive: isActive,
136
- changeToTab: changeToTab
137
- };
138
- };
139
- var useTabProviderContextState = function useTabProviderContextState() {
140
- var context = useContext(TabProviderContext);
141
- return context === null || context === void 0 ? void 0 : context[0];
142
- };
1
+ import { e as _toConsumableArray } from './_rollupPluginBabelHelpers.js';
2
+ import { useEffect } from 'react';
143
3
 
144
4
  var useRovingTabIndex = function useRovingTabIndex(_ref) {
145
5
  var parentRef = _ref.parentRef,
146
6
  elementSelector = _ref.elementSelector,
147
7
  keepTabIndex = _ref.keepTabIndex,
8
+ onElementFocus = _ref.onElementFocus,
148
9
  _ref$extraDependencie = _ref.extraDependencies,
149
10
  extraDependencies = _ref$extraDependencie === void 0 ? [] : _ref$extraDependencie;
150
11
  useEffect(function () {
@@ -183,7 +44,11 @@ var useRovingTabIndex = function useRovingTabIndex(_ref) {
183
44
  }
184
45
 
185
46
  var newElement = elements[newTabFocus];
186
- newElement === null || newElement === void 0 ? void 0 : newElement.focus();
47
+ newElement === null || newElement === void 0 ? void 0 : newElement.focus(); // When an element is focused using roving tab index, trigger the onElementFocus callback
48
+
49
+ if (newElement && onElementFocus) {
50
+ onElementFocus(newElement);
51
+ }
187
52
 
188
53
  if (keepTabIndex) {
189
54
  evt.currentTarget.setAttribute('tabindex', '-1');
@@ -218,5 +83,5 @@ var useRovingTabIndex = function useRovingTabIndex(_ref) {
218
83
  [parentRef].concat(_toConsumableArray(extraDependencies)));
219
84
  };
220
85
 
221
- export { INIT_STATE as I, TabProviderContext as T, useTabProviderContextState as a, useTabProviderContext as b, reducer as r, useRovingTabIndex as u };
86
+ export { useRovingTabIndex as u };
222
87
  //# sourceMappingURL=useRovingTabIndex.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useRovingTabIndex.js","sources":["../../../src/components/tabs/state.ts","../../../src/hooks/useRovingTabIndex.tsx"],"sourcesContent":["import { Dispatch, createContext, useCallback, useContext, useEffect, useMemo } from 'react';\nimport { uid } from 'uid';\n\ntype TabType = 'tab' | 'tabPanel';\n\nexport interface State {\n isLazy: boolean;\n shouldActivateOnFocus: boolean;\n activeTabIndex: number;\n ids: Record<TabType, string[]>;\n}\n\nexport const INIT_STATE: State = {\n isLazy: true,\n shouldActivateOnFocus: false,\n activeTabIndex: 0,\n ids: { tab: [], tabPanel: [] },\n};\n\nexport type Action =\n | { type: 'update'; payload: Partial<State> }\n | { type: 'setActiveTabIndex'; payload: number }\n | { type: 'register'; payload: { type: TabType; id: string } }\n | { type: 'unregister'; payload: { type: TabType; id: string } };\n\nexport const reducer = (state: State, action: Action): State => {\n switch (action.type) {\n case 'update':\n return { ...state, ...action.payload };\n case 'setActiveTabIndex': {\n if (state.activeTabIndex === action.payload) {\n return state;\n }\n // Change active tab index.\n return { ...state, activeTabIndex: action.payload };\n }\n case 'register': {\n const { type, id } = action.payload;\n // Append tab/tabPanel id in state.\n return { ...state, ids: { ...state.ids, [type]: [...state.ids[type], id] } };\n }\n case 'unregister': {\n const { type, id } = action.payload;\n const index = state.ids[type].indexOf(id);\n if (index === -1) return state;\n // Remove tab & tab panel at index.\n const tabIds = [...state.ids.tab];\n tabIds.splice(index, 1);\n const tabPanelIds = [...state.ids.tabPanel];\n tabPanelIds.splice(index, 1);\n return {\n ...state,\n ids: { tab: tabIds, tabPanel: tabPanelIds },\n };\n }\n default:\n return state;\n }\n};\n\nexport const TabProviderContext = createContext<[State, Dispatch<Action>] | null>(null);\n\nexport type TabState = Pick<Required<State>, 'isLazy' | 'shouldActivateOnFocus'> & {\n isActive: boolean;\n tabId: string;\n tabPanelId: string;\n changeToTab(): void;\n};\n\n/* eslint-disable react-hooks/rules-of-hooks */\nexport const useTabProviderContext = (type: TabType, originalId?: string): undefined | TabState => {\n const context = useContext(TabProviderContext);\n if (!context) {\n return undefined;\n }\n const [state, dispatch] = context;\n\n // Current tab or tab panel id.\n const id = useMemo(\n () => originalId || `${type}-${uid()}`,\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n useEffect(\n () => {\n // On mount: register tab or tab panel id.\n dispatch({ type: 'register', payload: { type, id } });\n return () => {\n // On unmount: unregister tab or tab panel id.\n dispatch({ type: 'unregister', payload: { type, id } });\n };\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n // Find tab/tabPanel index using it's id.\n const index = useMemo(() => state.ids[type].indexOf(id), [state.ids, type, id]);\n const tabId = useMemo(() => state.ids.tab[index] || '', [state, index]);\n const tabPanelId = useMemo(() => state.ids.tabPanel[index] || '', [state, index]);\n const isActive = useMemo(() => state.activeTabIndex === index, [state, index]);\n const changeToTab = useCallback(() => dispatch({ type: 'setActiveTabIndex', payload: index }), [dispatch, index]);\n return {\n isLazy: state.isLazy,\n shouldActivateOnFocus: state.shouldActivateOnFocus,\n tabId,\n tabPanelId,\n isActive,\n changeToTab,\n };\n};\n\nexport const useTabProviderContextState = (): State | undefined => {\n const context = useContext(TabProviderContext);\n return context?.[0];\n};\n","import { RefObject, useEffect } from 'react';\n\ninterface UseRovingTabIndexOptions {\n parentRef: RefObject<HTMLElement>;\n elementSelector: string;\n keepTabIndex?: boolean;\n /** List of values to be used as extra dependencies of the useEffect */\n extraDependencies?: any[];\n}\n\nexport const useRovingTabIndex = ({\n parentRef,\n elementSelector,\n keepTabIndex,\n extraDependencies = [],\n}: UseRovingTabIndexOptions): void => {\n useEffect(\n () => {\n const parent = parentRef?.current;\n if (!parent) {\n return undefined;\n }\n\n const elements = parent.querySelectorAll(elementSelector) as NodeListOf<HTMLElement>;\n const initialFocusableElement = parent?.querySelector(`${elementSelector}[tabindex=\"0\"]`);\n\n const handleKeyDown = (index: number) => (evt: KeyboardEvent) => {\n let newTabFocus = index;\n if (!(evt.key === 'ArrowRight' || evt.key === 'ArrowLeft')) {\n return;\n }\n\n if (evt.key === 'ArrowRight') {\n // Move right\n newTabFocus += 1;\n // If we're at the end, go to the start\n if (newTabFocus >= elements.length) {\n newTabFocus = 0;\n }\n } else if (evt.key === 'ArrowLeft') {\n // Move left\n newTabFocus -= 1;\n if (newTabFocus < 0) {\n // If we're at the start, move to the end\n newTabFocus = elements.length - 1;\n }\n }\n const newElement = elements[newTabFocus];\n newElement?.focus();\n if (keepTabIndex) {\n (evt.currentTarget as HTMLElement).setAttribute('tabindex', '-1');\n newElement?.setAttribute('tabindex', '0');\n }\n };\n\n if (elements?.length > 0) {\n elements.forEach((el, key) => {\n // if no element has tabindex set to 0, set the first element as focusable\n if (!initialFocusableElement && key === 0) {\n el.setAttribute('tabindex', '0');\n // set all other to -1\n } else if (initialFocusableElement !== el) {\n el.setAttribute('tabindex', '-1');\n }\n // add event listener\n el.addEventListener('keydown', handleKeyDown(key) as EventListener);\n });\n }\n\n // Cleanup listeners\n return () => {\n if (elements?.length > 0) {\n elements.forEach((el, key) => {\n el.removeEventListener('keydown', handleKeyDown(key) as EventListener);\n });\n }\n };\n }, // eslint-disable-next-line react-hooks/exhaustive-deps\n [parentRef, ...extraDependencies],\n );\n};\n"],"names":["INIT_STATE","isLazy","shouldActivateOnFocus","activeTabIndex","ids","tab","tabPanel","reducer","state","action","type","payload","id","index","indexOf","tabIds","splice","tabPanelIds","TabProviderContext","createContext","useTabProviderContext","originalId","context","useContext","undefined","dispatch","useMemo","uid","useEffect","tabId","tabPanelId","isActive","changeToTab","useCallback","useTabProviderContextState","useRovingTabIndex","parentRef","elementSelector","keepTabIndex","extraDependencies","parent","current","elements","querySelectorAll","initialFocusableElement","querySelector","handleKeyDown","evt","newTabFocus","key","length","newElement","focus","currentTarget","setAttribute","forEach","el","addEventListener","removeEventListener"],"mappings":"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"}
1
+ {"version":3,"file":"useRovingTabIndex.js","sources":["../../../src/hooks/useRovingTabIndex.tsx"],"sourcesContent":["import { RefObject, useEffect } from 'react';\n\ninterface UseRovingTabIndexOptions {\n parentRef: RefObject<HTMLElement>;\n elementSelector: string;\n keepTabIndex?: boolean;\n /** Action to trigger when an element is focused using roving tab index */\n onElementFocus?: (element: HTMLElement) => void;\n /** List of values to be used as extra dependencies of the useEffect */\n extraDependencies?: any[];\n}\n\nexport const useRovingTabIndex = ({\n parentRef,\n elementSelector,\n keepTabIndex,\n onElementFocus,\n extraDependencies = [],\n}: UseRovingTabIndexOptions): void => {\n useEffect(\n () => {\n const parent = parentRef?.current;\n if (!parent) {\n return undefined;\n }\n\n const elements = parent.querySelectorAll(elementSelector) as NodeListOf<HTMLElement>;\n const initialFocusableElement = parent?.querySelector(`${elementSelector}[tabindex=\"0\"]`);\n\n const handleKeyDown = (index: number) => (evt: KeyboardEvent) => {\n let newTabFocus = index;\n if (!(evt.key === 'ArrowRight' || evt.key === 'ArrowLeft')) {\n return;\n }\n\n if (evt.key === 'ArrowRight') {\n // Move right\n newTabFocus += 1;\n // If we're at the end, go to the start\n if (newTabFocus >= elements.length) {\n newTabFocus = 0;\n }\n } else if (evt.key === 'ArrowLeft') {\n // Move left\n newTabFocus -= 1;\n if (newTabFocus < 0) {\n // If we're at the start, move to the end\n newTabFocus = elements.length - 1;\n }\n }\n const newElement = elements[newTabFocus];\n newElement?.focus();\n\n // When an element is focused using roving tab index, trigger the onElementFocus callback\n if (newElement && onElementFocus) {\n onElementFocus(newElement);\n }\n\n if (keepTabIndex) {\n (evt.currentTarget as HTMLElement).setAttribute('tabindex', '-1');\n newElement?.setAttribute('tabindex', '0');\n }\n };\n\n if (elements?.length > 0) {\n elements.forEach((el, key) => {\n // if no element has tabindex set to 0, set the first element as focusable\n if (!initialFocusableElement && key === 0) {\n el.setAttribute('tabindex', '0');\n // set all other to -1\n } else if (initialFocusableElement !== el) {\n el.setAttribute('tabindex', '-1');\n }\n // add event listener\n el.addEventListener('keydown', handleKeyDown(key) as EventListener);\n });\n }\n\n // Cleanup listeners\n return () => {\n if (elements?.length > 0) {\n elements.forEach((el, key) => {\n el.removeEventListener('keydown', handleKeyDown(key) as EventListener);\n });\n }\n };\n }, // eslint-disable-next-line react-hooks/exhaustive-deps\n [parentRef, ...extraDependencies],\n );\n};\n"],"names":["useRovingTabIndex","parentRef","elementSelector","keepTabIndex","onElementFocus","extraDependencies","useEffect","parent","current","undefined","elements","querySelectorAll","initialFocusableElement","querySelector","handleKeyDown","index","evt","newTabFocus","key","length","newElement","focus","currentTarget","setAttribute","forEach","el","addEventListener","removeEventListener"],"mappings":"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"}
package/esm/index.js CHANGED
@@ -53,6 +53,8 @@ export { F as Flag } from './_internal/Flag2.js';
53
53
  import 'lodash/castArray';
54
54
  export { F as FlexBox } from './_internal/FlexBox.js';
55
55
  export { G as GenericBlock } from './_internal/GenericBlock.js';
56
+ export { T as Text } from './_internal/Text2.js';
57
+ export { H as Heading, a as HeadingLevelProvider, u as useHeadingLevel } from './_internal/HeadingLevelProvider.js';
56
58
  export { G as Grid, a as GridItem } from './_internal/GridItem.js';
57
59
  import 'lodash/isObject';
58
60
  export { a as ImageBlock, I as ImageBlockCaptionPosition } from './_internal/ImageBlock.js';
@@ -68,8 +70,9 @@ export { M as Mosaic } from './_internal/Mosaic2.js';
68
70
  export { N as Notification } from './_internal/Notification2.js';
69
71
  export { P as PostBlock } from './_internal/PostBlock.js';
70
72
  export { a as Progress, P as ProgressVariant } from './_internal/Progress2.js';
71
- import './_internal/useRovingTabIndex.js';
73
+ import './_internal/state.js';
72
74
  export { a as ProgressTracker, P as ProgressTrackerProvider, b as ProgressTrackerStep, c as ProgressTrackerStepPanel } from './_internal/ProgressTrackerStepPanel.js';
75
+ import './_internal/useRovingTabIndex.js';
73
76
  export { R as RadioButton, a as RadioGroup } from './_internal/RadioGroup.js';
74
77
  export { a as Select, c as SelectMultiple, b as SelectMultipleField, S as SelectVariant } from './_internal/SelectMultiple.js';
75
78
  export { S as SideNavigation, a as SideNavigationItem } from './_internal/SideNavigationItem.js';
@@ -77,6 +80,7 @@ export { S as SkeletonCircle, b as SkeletonRectangle, a as SkeletonRectangleVari
77
80
  export { S as Slider, c as clamp } from './_internal/Slider2.js';
78
81
  export { c as Slides, S as Slideshow, b as SlideshowControls, a as SlideshowItem } from './_internal/Slides.js';
79
82
  import 'lodash/uniqueId';
83
+ import 'lodash/chunk';
80
84
  export { S as Switch } from './_internal/Switch2.js';
81
85
  export { T as Table, a as TableBody, d as TableCell, c as TableCellVariant, e as TableHeader, f as TableRow, b as ThOrder } from './_internal/TableRow.js';
82
86
  export { c as Tab, b as TabList, a as TabListLayout, d as TabPanel, T as TabProvider } from './_internal/TabPanel.js';
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
package/package.json CHANGED
@@ -7,8 +7,8 @@
7
7
  },
8
8
  "dependencies": {
9
9
  "@juggle/resize-observer": "^3.2.0",
10
- "@lumx/core": "^3.0.1",
11
- "@lumx/icons": "^3.0.1",
10
+ "@lumx/core": "^3.0.2",
11
+ "@lumx/icons": "^3.0.2",
12
12
  "@popperjs/core": "^2.5.4",
13
13
  "body-scroll-lock": "^3.1.5",
14
14
  "classnames": "^2.2.6",
@@ -61,7 +61,6 @@
61
61
  "jest-watch-master": "^1.0.0",
62
62
  "jest-watch-suspend": "^1.1.2",
63
63
  "jest-watch-typeahead": "^0.6.0",
64
- "postcss-flexbox-unboxer": "^1.0.0",
65
64
  "rollup": "2.26.10",
66
65
  "rollup-plugin-analyzer": "^3.3.0",
67
66
  "rollup-plugin-babel": "^4.4.0",
@@ -120,6 +119,6 @@
120
119
  "build:storybook": "cd storybook && ./build"
121
120
  },
122
121
  "sideEffects": false,
123
- "version": "3.0.1",
124
- "gitHead": "cd913d1c468a87d794b68b25505975ac992e940c"
122
+ "version": "3.0.2",
123
+ "gitHead": "f66d1996ea46e90a4dc135ee8f47ef012b95171c"
125
124
  }
@@ -19,8 +19,32 @@ const flexViewKnobConfigs: Array<
19
19
  ['noShrink', boolean],
20
20
  ['wrap', boolean],
21
21
  ['gap', select, [DEFAULT_PROPS.gap, Size.tiny, Size.regular, Size.medium, Size.big, Size.huge]],
22
- ['hAlign', select, [DEFAULT_PROPS.hAlign, Alignment.center, Alignment.top, Alignment.bottom]],
23
- ['vAlign', select, [DEFAULT_PROPS.vAlign, Alignment.center, Alignment.right, Alignment.left]],
22
+ [
23
+ 'hAlign',
24
+ select,
25
+ [
26
+ DEFAULT_PROPS.hAlign,
27
+ Alignment.center,
28
+ Alignment.top,
29
+ Alignment.bottom,
30
+ Alignment.spaceAround,
31
+ Alignment.spaceBetween,
32
+ Alignment.spaceEvenly,
33
+ ],
34
+ ],
35
+ [
36
+ 'vAlign',
37
+ select,
38
+ [
39
+ DEFAULT_PROPS.vAlign,
40
+ Alignment.center,
41
+ Alignment.right,
42
+ Alignment.left,
43
+ Alignment.spaceAround,
44
+ Alignment.spaceBetween,
45
+ Alignment.spaceEvenly,
46
+ ],
47
+ ],
24
48
  ['orientation', select, [undefined, Orientation.horizontal, Orientation.vertical]],
25
49
  [
26
50
  'marginAuto',
@@ -69,13 +93,27 @@ export const Flex = () => (
69
93
  const hAlign = (prefix?: string) =>
70
94
  select(
71
95
  `${prefix ? `${prefix}: ` : ''}Horizontal align`,
72
- [Alignment.center, Alignment.top, Alignment.bottom],
96
+ [
97
+ Alignment.center,
98
+ Alignment.top,
99
+ Alignment.bottom,
100
+ Alignment.spaceAround,
101
+ Alignment.spaceBetween,
102
+ Alignment.spaceEvenly,
103
+ ],
73
104
  Alignment.center,
74
105
  );
75
106
  const vAlign = (prefix?: string) =>
76
107
  select(
77
108
  `${prefix ? `${prefix}: ` : ''}Vertical align`,
78
- [Alignment.center, Alignment.left, Alignment.right],
109
+ [
110
+ Alignment.center,
111
+ Alignment.left,
112
+ Alignment.right,
113
+ Alignment.spaceAround,
114
+ Alignment.spaceBetween,
115
+ Alignment.spaceEvenly,
116
+ ],
79
117
  Alignment.center,
80
118
  );
81
119
 
@@ -179,3 +217,21 @@ export const Align = () => (
179
217
  <FlexBox style={{ height: 'fit-content' }}>Some text</FlexBox>
180
218
  </FlexBox>
181
219
  );
220
+
221
+ export const Distribution = () => (
222
+ <FlexBox
223
+ style={{
224
+ width: `${number('width (px)', 720)}px`,
225
+ height: `${number('height (px)', 300)}px`,
226
+ border: '1px solid red',
227
+ }}
228
+ orientation={orientation()}
229
+ gap={gapSize()}
230
+ vAlign={vAlign()}
231
+ hAlign={hAlign()}
232
+ >
233
+ <Button>Button 1</Button>
234
+ <Button>Button 2</Button>
235
+ <Button>Button 3</Button>
236
+ </FlexBox>
237
+ );
@@ -1,12 +1,15 @@
1
- import { Alignment, HorizontalAlignment, Orientation, VerticalAlignment } from '@lumx/react';
1
+ import { Alignment, Orientation } from '@lumx/react';
2
2
  import { Comp, GenericProps, getRootClassName, handleBasicClasses } from '@lumx/react/utils';
3
3
  import classNames from 'classnames';
4
4
  import castArray from 'lodash/castArray';
5
5
  import React, { forwardRef, ReactNode } from 'react';
6
- import { Size } from '..';
6
+ import { HorizontalAlignment, Size, VerticalAlignment } from '..';
7
7
 
8
8
  export type MarginAutoAlignment = Extract<Alignment, 'top' | 'bottom' | 'right' | 'left'>;
9
9
  export type GapSize = Extract<Size, 'tiny' | 'regular' | 'medium' | 'big' | 'huge'>;
10
+ type SpaceAlignment = Extract<Alignment, 'space-between' | 'space-evenly' | 'space-around'>;
11
+ export type FlexVerticalAlignment = VerticalAlignment | SpaceAlignment;
12
+ export type FlexHorizontalAlignment = HorizontalAlignment | SpaceAlignment;
10
13
 
11
14
  /**
12
15
  * Defines the props of the component.
@@ -19,7 +22,7 @@ export interface FlexBoxProps extends GenericProps {
19
22
  /** Gap space between flexbox items. */
20
23
  gap?: GapSize;
21
24
  /** Flex horizontal alignment. */
22
- hAlign?: VerticalAlignment;
25
+ hAlign?: FlexVerticalAlignment;
23
26
  /** Whether the "auto margin" is enabled all around or not. */
24
27
  marginAuto?: MarginAutoAlignment | MarginAutoAlignment[];
25
28
  /** Whether the "content shrink" is disabled or not. */
@@ -27,7 +30,7 @@ export interface FlexBoxProps extends GenericProps {
27
30
  /** Flex direction. */
28
31
  orientation?: Orientation;
29
32
  /** Flex vertical alignment. */
30
- vAlign?: HorizontalAlignment;
33
+ vAlign?: FlexHorizontalAlignment;
31
34
  /** Whether the "flex wrap" is enabled or not. */
32
35
  wrap?: boolean;
33
36
  }
@@ -40,6 +40,41 @@ Array [
40
40
  ]
41
41
  `;
42
42
 
43
+ exports[`<FlexBox> Snapshots and structure should render story 'Distribution' 1`] = `
44
+ <div
45
+ className="lumx-flex-box lumx-flex-box--orientation-vertical lumx-flex-box--v-align-center lumx-flex-box--h-align-center lumx-flex-box--gap-regular"
46
+ style={
47
+ Object {
48
+ "border": "1px solid red",
49
+ "height": "300px",
50
+ "width": "720px",
51
+ }
52
+ }
53
+ >
54
+ <Button
55
+ emphasis="high"
56
+ size="m"
57
+ theme="light"
58
+ >
59
+ Button 1
60
+ </Button>
61
+ <Button
62
+ emphasis="high"
63
+ size="m"
64
+ theme="light"
65
+ >
66
+ Button 2
67
+ </Button>
68
+ <Button
69
+ emphasis="high"
70
+ size="m"
71
+ theme="light"
72
+ >
73
+ Button 3
74
+ </Button>
75
+ </div>
76
+ `;
77
+
43
78
  exports[`<FlexBox> Snapshots and structure should render story 'Flex' 1`] = `
44
79
  Array [
45
80
  <div