@carbon/utilities-react 0.20.0-rc.0 → 0.21.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -0
- package/es/StepFlow/index.d.ts +2 -0
- package/es/StepFlow/index.js +3 -1
- package/es/chunk.d.ts +45 -0
- package/es/chunk.js +60 -0
- package/es/index.d.ts +5 -0
- package/es/index.js +6 -1
- package/es/useNoInteractiveChildren/index.d.ts +21 -0
- package/es/useNoInteractiveChildren/index.js +78 -3
- package/lib/StepFlow/index.js +6 -1
- package/lib/chunk.js +111 -0
- package/lib/index.js +18 -1
- package/lib/useNoInteractiveChildren/index.js +83 -3
- package/package.json +24 -13
- package/es/StepFlow/StepContext.js +0 -1
- package/es/StepFlow/StepGroup.js +0 -1
- package/es/StepFlow/types.js +0 -0
- package/lib/StepFlow/StepContext.js +0 -1
- package/lib/StepFlow/StepGroup.js +0 -1
- package/lib/StepFlow/types.js +0 -1
- package/types/StepFlow/StepContext.d.ts +0 -14
- package/types/StepFlow/StepGroup.d.ts +0 -17
- package/types/StepFlow/index.d.ts +0 -9
- package/types/StepFlow/types.d.ts +0 -25
- package/types/index.d.ts +0 -9
- package/types/useNoInteractiveChildren/index.d.ts +0 -18
package/README.md
CHANGED
|
@@ -19,6 +19,44 @@ instead:
|
|
|
19
19
|
yarn add @carbon/utilities-react
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
+
## Maintainer information
|
|
23
|
+
|
|
24
|
+
This package uses a convention-based multi-entry build. The supported public API
|
|
25
|
+
consists of two parts.
|
|
26
|
+
|
|
27
|
+
1. The root entrypoint
|
|
28
|
+
|
|
29
|
+
```js
|
|
30
|
+
import { utility } from '@carbon/utilities-react';
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
2. Any top-level module with a `src/<name>/index.*` file
|
|
34
|
+
|
|
35
|
+
```js
|
|
36
|
+
import { utility } from '@carbon/utilities-react/utility';
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Review the
|
|
40
|
+
[architecture decision record (ADR)](../../docs/decisions/0004-adopt-explicit-package-entrypoints-for-utilities.md)
|
|
41
|
+
for more detail on how and why this approach is used.
|
|
42
|
+
|
|
43
|
+
### Adding a utility
|
|
44
|
+
|
|
45
|
+
1. Create a new top-level directory under `src/`
|
|
46
|
+
2. Export the public API for that utility from `src/<name>/index.ts`,
|
|
47
|
+
`index.tsx`, `index.js`, or `index.jsx`
|
|
48
|
+
3. Re-export it from `src/index.ts` if it should also be available from the
|
|
49
|
+
package root
|
|
50
|
+
4. Build the package and verify the generated outputs under `es/<name>/index.*`
|
|
51
|
+
and `lib/<name>/index.js`
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
src/
|
|
55
|
+
someReactUtility/
|
|
56
|
+
index.tsx
|
|
57
|
+
someReactUtility.tsx
|
|
58
|
+
```
|
|
59
|
+
|
|
22
60
|
## 🙌 Contributing
|
|
23
61
|
|
|
24
62
|
We're always looking for contributors to help us fix bugs, build new features,
|
package/es/StepFlow/index.js
CHANGED
|
@@ -1 +1,3 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import { n as useStepContext, r as StepGroup, t as StepProvider } from "../chunk.js";
|
|
2
|
+
|
|
3
|
+
export { StepGroup, StepProvider, useStepContext };
|
package/es/chunk.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React, { Dispatch, ReactNode, SetStateAction } from "react";
|
|
2
|
+
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
3
|
+
|
|
4
|
+
//#region src/StepFlow/StepGroup.d.ts
|
|
5
|
+
interface StepGroupProps {
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Container for steps. The children are filtered for only truthy values (via Children.toArray)
|
|
10
|
+
* and only the current step is returned from this component based on the `currentStep` value
|
|
11
|
+
* from `useStepContext`.
|
|
12
|
+
*/
|
|
13
|
+
declare const StepGroup: ({
|
|
14
|
+
children
|
|
15
|
+
}: StepGroupProps) => string | number | bigint | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined>;
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/StepFlow/types.d.ts
|
|
18
|
+
/**
|
|
19
|
+
* This interface should be extended by the consumer to match their own unique
|
|
20
|
+
* use case given the fields within their own stepped experience.
|
|
21
|
+
*/
|
|
22
|
+
interface formStateType {
|
|
23
|
+
[key: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
interface StepContextType {
|
|
26
|
+
formState: formStateType;
|
|
27
|
+
setFormState: Dispatch<SetStateAction<formStateType>>;
|
|
28
|
+
totalSteps: number;
|
|
29
|
+
setTotalSteps: Dispatch<SetStateAction<number>>;
|
|
30
|
+
currentStep: number;
|
|
31
|
+
handleGoToStep: (step: number) => void;
|
|
32
|
+
handleNext: () => void;
|
|
33
|
+
handlePrevious: () => void;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/StepFlow/StepContext.d.ts
|
|
37
|
+
interface StepProviderProps {
|
|
38
|
+
children: ReactNode;
|
|
39
|
+
}
|
|
40
|
+
declare const StepProvider: ({
|
|
41
|
+
children
|
|
42
|
+
}: StepProviderProps) => react_jsx_runtime0.JSX.Element;
|
|
43
|
+
declare const useStepContext: () => StepContextType;
|
|
44
|
+
//#endregion
|
|
45
|
+
export { StepGroup as i, useStepContext as n, StepContextType as r, StepProvider as t };
|
package/es/chunk.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React, { createContext, useContext, useEffect, useState } from "react";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
|
|
4
|
+
//#region src/StepFlow/StepGroup.tsx
|
|
5
|
+
/**
|
|
6
|
+
* Copyright IBM Corp. 2025, 2025
|
|
7
|
+
*
|
|
8
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
9
|
+
* LICENSE file in the root directory of this source tree.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Container for steps. The children are filtered for only truthy values (via Children.toArray)
|
|
13
|
+
* and only the current step is returned from this component based on the `currentStep` value
|
|
14
|
+
* from `useStepContext`.
|
|
15
|
+
*/
|
|
16
|
+
const StepGroup = ({ children }) => {
|
|
17
|
+
const { setTotalSteps, currentStep } = useStepContext();
|
|
18
|
+
const childrenArray = React.Children.toArray(children);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
setTotalSteps(childrenArray.length);
|
|
21
|
+
}, [childrenArray.length, setTotalSteps]);
|
|
22
|
+
return childrenArray[currentStep - 1];
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/StepFlow/StepContext.tsx
|
|
27
|
+
/**
|
|
28
|
+
* Copyright IBM Corp. 2025, 2025
|
|
29
|
+
*
|
|
30
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
31
|
+
* LICENSE file in the root directory of this source tree.
|
|
32
|
+
*/
|
|
33
|
+
const StepContext = createContext(void 0);
|
|
34
|
+
const StepProvider = ({ children }) => {
|
|
35
|
+
const [totalSteps, setTotalSteps] = useState(1);
|
|
36
|
+
const [currentStep, setCurrentStep] = useState(1);
|
|
37
|
+
const [formState, setFormState] = useState({});
|
|
38
|
+
const context = {
|
|
39
|
+
formState,
|
|
40
|
+
setFormState,
|
|
41
|
+
totalSteps,
|
|
42
|
+
setTotalSteps,
|
|
43
|
+
currentStep,
|
|
44
|
+
handleGoToStep: (step) => setCurrentStep(step),
|
|
45
|
+
handleNext: () => setCurrentStep((step) => step + 1),
|
|
46
|
+
handlePrevious: () => setCurrentStep((step) => step - 1)
|
|
47
|
+
};
|
|
48
|
+
return /* @__PURE__ */ jsx(StepContext.Provider, {
|
|
49
|
+
value: context,
|
|
50
|
+
children
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
const useStepContext = () => {
|
|
54
|
+
const context = useContext(StepContext);
|
|
55
|
+
if (context === void 0) throw new Error("Context hook used outside of Step provider");
|
|
56
|
+
return context;
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
//#endregion
|
|
60
|
+
export { useStepContext as n, StepGroup as r, StepProvider as t };
|
package/es/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { getInteractiveContent, getRoleContent, useInteractiveChildrenNeedDescription, useNoInteractiveChildren } from "./useNoInteractiveChildren/index.js";
|
|
2
|
+
import { i as StepGroup, n as useStepContext, r as StepContextType, t as StepProvider } from "./chunk.js";
|
|
3
|
+
import "./StepFlow/index.js";
|
|
4
|
+
export * from "@carbon/utilities";
|
|
5
|
+
export { type StepContextType, StepGroup, StepProvider, getInteractiveContent, getRoleContent, useInteractiveChildrenNeedDescription, useNoInteractiveChildren, useStepContext };
|
package/es/index.js
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { getInteractiveContent, getRoleContent, useInteractiveChildrenNeedDescription, useNoInteractiveChildren } from "./useNoInteractiveChildren/index.js";
|
|
2
|
+
import { n as useStepContext, r as StepGroup, t as StepProvider } from "./chunk.js";
|
|
3
|
+
|
|
4
|
+
export * from "@carbon/utilities"
|
|
5
|
+
|
|
6
|
+
export { StepGroup, StepProvider, getInteractiveContent, getRoleContent, useInteractiveChildrenNeedDescription, useNoInteractiveChildren, useStepContext };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
//#region src/useNoInteractiveChildren/index.d.ts
|
|
2
|
+
declare function useNoInteractiveChildren(ref: any, message?: string): void;
|
|
3
|
+
declare function useInteractiveChildrenNeedDescription(ref: any, message?: string): void;
|
|
4
|
+
/**
|
|
5
|
+
* Determines if a given DOM node has interactive content, or is itself
|
|
6
|
+
* interactive. It returns the interactive node if one is found
|
|
7
|
+
*
|
|
8
|
+
* @param {HTMLElement} node
|
|
9
|
+
* @returns {HTMLElement}
|
|
10
|
+
*/
|
|
11
|
+
declare function getInteractiveContent(node: HTMLElement): HTMLElement;
|
|
12
|
+
/**
|
|
13
|
+
* Determines if a given DOM node has a role, or has itself a role.
|
|
14
|
+
* It returns the node with a role if one is found
|
|
15
|
+
*
|
|
16
|
+
* @param {HTMLElement} node
|
|
17
|
+
* @returns {HTMLElement}
|
|
18
|
+
*/
|
|
19
|
+
declare function getRoleContent(node: HTMLElement): HTMLElement;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { getInteractiveContent, getRoleContent, useInteractiveChildrenNeedDescription, useNoInteractiveChildren };
|
|
@@ -1,5 +1,80 @@
|
|
|
1
|
-
import{useEffect
|
|
1
|
+
import { useEffect } from "react";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
//#region src/useNoInteractiveChildren/index.jsx
|
|
4
|
+
/**
|
|
5
|
+
* Copyright IBM Corp. 2016, 2026
|
|
6
|
+
*
|
|
7
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
8
|
+
* LICENSE file in the root directory of this source tree.
|
|
9
|
+
*/
|
|
10
|
+
function useNoInteractiveChildren(ref, message = "component should have no interactive child nodes") {
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (process.env.NODE_ENV === "production") return;
|
|
13
|
+
const { current } = ref;
|
|
14
|
+
const node = current ? getInteractiveContent(current) : null;
|
|
15
|
+
if (node) {
|
|
16
|
+
const errorMessage = `Error: ${message}.\n\nInstead found: ${node.outerHTML}`;
|
|
17
|
+
console.error(errorMessage);
|
|
18
|
+
throw new Error(errorMessage);
|
|
19
|
+
}
|
|
20
|
+
}, [message, ref]);
|
|
21
|
+
}
|
|
22
|
+
function useInteractiveChildrenNeedDescription(ref, message = `interactive child node(s) should have an \`aria-describedby\` property`) {
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
if (process.env.NODE_ENV === "production") return;
|
|
25
|
+
const { current } = ref;
|
|
26
|
+
const node = current ? getInteractiveContent(current) : null;
|
|
27
|
+
if (node && !node.hasAttribute("aria-describedby")) throw new Error(`Error: ${message}.\n\nInstead found: ${node.outerHTML}`);
|
|
28
|
+
}, [message, ref]);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Determines if a given DOM node has interactive content, or is itself
|
|
32
|
+
* interactive. It returns the interactive node if one is found
|
|
33
|
+
*
|
|
34
|
+
* @param {HTMLElement} node
|
|
35
|
+
* @returns {HTMLElement}
|
|
36
|
+
*/
|
|
37
|
+
function getInteractiveContent(node) {
|
|
38
|
+
if (!node || !node.childNodes) return null;
|
|
39
|
+
if (isFocusable(node)) return node;
|
|
40
|
+
for (const childNode of node.childNodes) {
|
|
41
|
+
const interactiveNode = getInteractiveContent(childNode);
|
|
42
|
+
if (interactiveNode) return interactiveNode;
|
|
43
|
+
}
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Determines if a given DOM node has a role, or has itself a role.
|
|
48
|
+
* It returns the node with a role if one is found
|
|
49
|
+
*
|
|
50
|
+
* @param {HTMLElement} node
|
|
51
|
+
* @returns {HTMLElement}
|
|
52
|
+
*/
|
|
53
|
+
function getRoleContent(node) {
|
|
54
|
+
if (!node || !node.childNodes) return null;
|
|
55
|
+
if (node?.getAttribute?.("role") && node.getAttribute("role") !== "") return node;
|
|
56
|
+
for (const childNode of node.childNodes) {
|
|
57
|
+
const roleNode = getRoleContent(childNode);
|
|
58
|
+
if (roleNode) return roleNode;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Determines if the given element is focusable, or not
|
|
64
|
+
*
|
|
65
|
+
* @param {HTMLElement} element
|
|
66
|
+
* @returns {boolean}
|
|
67
|
+
* @see https://github.com/w3c/aria-practices/blob/0553bb51588ffa517506e2a1b2ca1422ed438c5f/examples/js/utils.js#L68
|
|
68
|
+
*/
|
|
69
|
+
function isFocusable(element) {
|
|
70
|
+
if (element.tabIndex === void 0 || element.tabIndex < 0) return false;
|
|
71
|
+
if (element.disabled) return false;
|
|
72
|
+
switch (element.nodeName) {
|
|
73
|
+
case "A": return !!element.href && element.rel !== "ignore";
|
|
74
|
+
case "INPUT": return element.type !== "hidden";
|
|
75
|
+
default: return true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
4
78
|
|
|
5
|
-
|
|
79
|
+
//#endregion
|
|
80
|
+
export { getInteractiveContent, getRoleContent, useInteractiveChildrenNeedDescription, useNoInteractiveChildren };
|
package/lib/StepFlow/index.js
CHANGED
|
@@ -1 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_StepContext = require('../chunk.js');
|
|
3
|
+
|
|
4
|
+
exports.StepGroup = require_StepContext.StepGroup;
|
|
5
|
+
exports.StepProvider = require_StepContext.StepProvider;
|
|
6
|
+
exports.useStepContext = require_StepContext.useStepContext;
|
package/lib/chunk.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
13
|
+
__defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
let react = require("react");
|
|
29
|
+
react = __toESM(react);
|
|
30
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
31
|
+
|
|
32
|
+
//#region src/StepFlow/StepGroup.tsx
|
|
33
|
+
/**
|
|
34
|
+
* Copyright IBM Corp. 2025, 2025
|
|
35
|
+
*
|
|
36
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
37
|
+
* LICENSE file in the root directory of this source tree.
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* Container for steps. The children are filtered for only truthy values (via Children.toArray)
|
|
41
|
+
* and only the current step is returned from this component based on the `currentStep` value
|
|
42
|
+
* from `useStepContext`.
|
|
43
|
+
*/
|
|
44
|
+
const StepGroup = ({ children }) => {
|
|
45
|
+
const { setTotalSteps, currentStep } = useStepContext();
|
|
46
|
+
const childrenArray = react.default.Children.toArray(children);
|
|
47
|
+
(0, react.useEffect)(() => {
|
|
48
|
+
setTotalSteps(childrenArray.length);
|
|
49
|
+
}, [childrenArray.length, setTotalSteps]);
|
|
50
|
+
return childrenArray[currentStep - 1];
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region src/StepFlow/StepContext.tsx
|
|
55
|
+
/**
|
|
56
|
+
* Copyright IBM Corp. 2025, 2025
|
|
57
|
+
*
|
|
58
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
59
|
+
* LICENSE file in the root directory of this source tree.
|
|
60
|
+
*/
|
|
61
|
+
const StepContext = (0, react.createContext)(void 0);
|
|
62
|
+
const StepProvider = ({ children }) => {
|
|
63
|
+
const [totalSteps, setTotalSteps] = (0, react.useState)(1);
|
|
64
|
+
const [currentStep, setCurrentStep] = (0, react.useState)(1);
|
|
65
|
+
const [formState, setFormState] = (0, react.useState)({});
|
|
66
|
+
const context = {
|
|
67
|
+
formState,
|
|
68
|
+
setFormState,
|
|
69
|
+
totalSteps,
|
|
70
|
+
setTotalSteps,
|
|
71
|
+
currentStep,
|
|
72
|
+
handleGoToStep: (step) => setCurrentStep(step),
|
|
73
|
+
handleNext: () => setCurrentStep((step) => step + 1),
|
|
74
|
+
handlePrevious: () => setCurrentStep((step) => step - 1)
|
|
75
|
+
};
|
|
76
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(StepContext.Provider, {
|
|
77
|
+
value: context,
|
|
78
|
+
children
|
|
79
|
+
});
|
|
80
|
+
};
|
|
81
|
+
const useStepContext = () => {
|
|
82
|
+
const context = (0, react.useContext)(StepContext);
|
|
83
|
+
if (context === void 0) throw new Error("Context hook used outside of Step provider");
|
|
84
|
+
return context;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
//#endregion
|
|
88
|
+
Object.defineProperty(exports, 'StepGroup', {
|
|
89
|
+
enumerable: true,
|
|
90
|
+
get: function () {
|
|
91
|
+
return StepGroup;
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
Object.defineProperty(exports, 'StepProvider', {
|
|
95
|
+
enumerable: true,
|
|
96
|
+
get: function () {
|
|
97
|
+
return StepProvider;
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
Object.defineProperty(exports, '__toESM', {
|
|
101
|
+
enumerable: true,
|
|
102
|
+
get: function () {
|
|
103
|
+
return __toESM;
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
Object.defineProperty(exports, 'useStepContext', {
|
|
107
|
+
enumerable: true,
|
|
108
|
+
get: function () {
|
|
109
|
+
return useStepContext;
|
|
110
|
+
}
|
|
111
|
+
});
|
package/lib/index.js
CHANGED
|
@@ -1 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_StepContext = require('./chunk.js');
|
|
3
|
+
const require_useNoInteractiveChildren_index = require('./useNoInteractiveChildren/index.js');
|
|
4
|
+
|
|
5
|
+
exports.StepGroup = require_StepContext.StepGroup;
|
|
6
|
+
exports.StepProvider = require_StepContext.StepProvider;
|
|
7
|
+
exports.getInteractiveContent = require_useNoInteractiveChildren_index.getInteractiveContent;
|
|
8
|
+
exports.getRoleContent = require_useNoInteractiveChildren_index.getRoleContent;
|
|
9
|
+
exports.useInteractiveChildrenNeedDescription = require_useNoInteractiveChildren_index.useInteractiveChildrenNeedDescription;
|
|
10
|
+
exports.useNoInteractiveChildren = require_useNoInteractiveChildren_index.useNoInteractiveChildren;
|
|
11
|
+
exports.useStepContext = require_StepContext.useStepContext;
|
|
12
|
+
var _carbon_utilities = require("@carbon/utilities");
|
|
13
|
+
Object.keys(_carbon_utilities).forEach(function (k) {
|
|
14
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return _carbon_utilities[k]; }
|
|
17
|
+
});
|
|
18
|
+
});
|
|
@@ -1,5 +1,85 @@
|
|
|
1
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_StepContext = require('../chunk.js');
|
|
3
|
+
let react = require("react");
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
//#region src/useNoInteractiveChildren/index.jsx
|
|
6
|
+
/**
|
|
7
|
+
* Copyright IBM Corp. 2016, 2026
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
10
|
+
* LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/
|
|
12
|
+
function useNoInteractiveChildren(ref, message = "component should have no interactive child nodes") {
|
|
13
|
+
(0, react.useEffect)(() => {
|
|
14
|
+
if (process.env.NODE_ENV === "production") return;
|
|
15
|
+
const { current } = ref;
|
|
16
|
+
const node = current ? getInteractiveContent(current) : null;
|
|
17
|
+
if (node) {
|
|
18
|
+
const errorMessage = `Error: ${message}.\n\nInstead found: ${node.outerHTML}`;
|
|
19
|
+
console.error(errorMessage);
|
|
20
|
+
throw new Error(errorMessage);
|
|
21
|
+
}
|
|
22
|
+
}, [message, ref]);
|
|
23
|
+
}
|
|
24
|
+
function useInteractiveChildrenNeedDescription(ref, message = `interactive child node(s) should have an \`aria-describedby\` property`) {
|
|
25
|
+
(0, react.useEffect)(() => {
|
|
26
|
+
if (process.env.NODE_ENV === "production") return;
|
|
27
|
+
const { current } = ref;
|
|
28
|
+
const node = current ? getInteractiveContent(current) : null;
|
|
29
|
+
if (node && !node.hasAttribute("aria-describedby")) throw new Error(`Error: ${message}.\n\nInstead found: ${node.outerHTML}`);
|
|
30
|
+
}, [message, ref]);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Determines if a given DOM node has interactive content, or is itself
|
|
34
|
+
* interactive. It returns the interactive node if one is found
|
|
35
|
+
*
|
|
36
|
+
* @param {HTMLElement} node
|
|
37
|
+
* @returns {HTMLElement}
|
|
38
|
+
*/
|
|
39
|
+
function getInteractiveContent(node) {
|
|
40
|
+
if (!node || !node.childNodes) return null;
|
|
41
|
+
if (isFocusable(node)) return node;
|
|
42
|
+
for (const childNode of node.childNodes) {
|
|
43
|
+
const interactiveNode = getInteractiveContent(childNode);
|
|
44
|
+
if (interactiveNode) return interactiveNode;
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Determines if a given DOM node has a role, or has itself a role.
|
|
50
|
+
* It returns the node with a role if one is found
|
|
51
|
+
*
|
|
52
|
+
* @param {HTMLElement} node
|
|
53
|
+
* @returns {HTMLElement}
|
|
54
|
+
*/
|
|
55
|
+
function getRoleContent(node) {
|
|
56
|
+
if (!node || !node.childNodes) return null;
|
|
57
|
+
if (node?.getAttribute?.("role") && node.getAttribute("role") !== "") return node;
|
|
58
|
+
for (const childNode of node.childNodes) {
|
|
59
|
+
const roleNode = getRoleContent(childNode);
|
|
60
|
+
if (roleNode) return roleNode;
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Determines if the given element is focusable, or not
|
|
66
|
+
*
|
|
67
|
+
* @param {HTMLElement} element
|
|
68
|
+
* @returns {boolean}
|
|
69
|
+
* @see https://github.com/w3c/aria-practices/blob/0553bb51588ffa517506e2a1b2ca1422ed438c5f/examples/js/utils.js#L68
|
|
70
|
+
*/
|
|
71
|
+
function isFocusable(element) {
|
|
72
|
+
if (element.tabIndex === void 0 || element.tabIndex < 0) return false;
|
|
73
|
+
if (element.disabled) return false;
|
|
74
|
+
switch (element.nodeName) {
|
|
75
|
+
case "A": return !!element.href && element.rel !== "ignore";
|
|
76
|
+
case "INPUT": return element.type !== "hidden";
|
|
77
|
+
default: return true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
4
80
|
|
|
5
|
-
|
|
81
|
+
//#endregion
|
|
82
|
+
exports.getInteractiveContent = getInteractiveContent;
|
|
83
|
+
exports.getRoleContent = getRoleContent;
|
|
84
|
+
exports.useInteractiveChildrenNeedDescription = useInteractiveChildrenNeedDescription;
|
|
85
|
+
exports.useNoInteractiveChildren = useNoInteractiveChildren;
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carbon/utilities-react",
|
|
3
3
|
"description": "Utilities and helpers to drive consistency across software products using the Carbon Design System with React",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.21.0-rc.0",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"module": "es/index.js",
|
|
8
|
-
"types": "
|
|
8
|
+
"types": "es/index.d.ts",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
11
|
"url": "https://github.com/carbon-design-system/carbon.git",
|
|
@@ -15,9 +15,24 @@
|
|
|
15
15
|
"files": [
|
|
16
16
|
"es",
|
|
17
17
|
"lib",
|
|
18
|
-
"types",
|
|
19
18
|
"telemetry.yml"
|
|
20
19
|
],
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./es/index.d.ts",
|
|
24
|
+
"import": "./es/index.js",
|
|
25
|
+
"require": "./lib/index.js",
|
|
26
|
+
"default": "./es/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./*": {
|
|
29
|
+
"types": "./es/*/index.d.ts",
|
|
30
|
+
"import": "./es/*/index.js",
|
|
31
|
+
"require": "./lib/*/index.js",
|
|
32
|
+
"default": "./es/*/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./package.json": "./package.json"
|
|
35
|
+
},
|
|
21
36
|
"keywords": [
|
|
22
37
|
"ibm",
|
|
23
38
|
"carbon",
|
|
@@ -30,26 +45,22 @@
|
|
|
30
45
|
"provenance": true
|
|
31
46
|
},
|
|
32
47
|
"scripts": {
|
|
33
|
-
"build
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"build": "yarn build:es & yarn build:cjs & yarn build:types",
|
|
37
|
-
"watch": "yarn build:es --watch & yarn build:cjs --watch",
|
|
38
|
-
"clean": "rimraf es lib",
|
|
48
|
+
"build": "yarn clean && tsdown --config tsdown.config.mts",
|
|
49
|
+
"watch": "tsdown --config tsdown.config.mts --watch",
|
|
50
|
+
"clean": "rimraf es lib types",
|
|
39
51
|
"postinstall": "ibmtelemetry --config=telemetry.yml"
|
|
40
52
|
},
|
|
41
53
|
"peerDependencies": {
|
|
42
54
|
"react": "^16.8.6 || ^17.0.1 || ^18.2.0 || ^19.0.0"
|
|
43
55
|
},
|
|
44
56
|
"devDependencies": {
|
|
45
|
-
"esbuild": "^0.25.0",
|
|
46
57
|
"rimraf": "^6.0.1",
|
|
47
|
-
"
|
|
58
|
+
"tsdown": "^0.20.3",
|
|
48
59
|
"typescript-config-carbon": "^0.9.0"
|
|
49
60
|
},
|
|
50
61
|
"dependencies": {
|
|
51
|
-
"@carbon/utilities": "^0.
|
|
62
|
+
"@carbon/utilities": "^0.18.0-rc.0",
|
|
52
63
|
"@ibm/telemetry-js": "^1.6.1"
|
|
53
64
|
},
|
|
54
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "d901529b78f5b70b49309ad45604fa5ec99a2e69"
|
|
55
66
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{jsx as x}from"react/jsx-runtime";import{useContext as a,createContext as u,useState as r}from"react";const n=u(void 0),h=({children:t})=>{const[p,d]=r(1),[s,o]=r(1),[S,c]=r({}),i={formState:S,setFormState:c,totalSteps:p,setTotalSteps:d,currentStep:s,handleGoToStep:e=>o(e),handleNext:()=>o(e=>e+1),handlePrevious:()=>o(e=>e-1)};return x(n.Provider,{value:i,children:t})},m=()=>{const t=a(n);if(t===void 0)throw new Error("Context hook used outside of Step provider");return t};export{h as StepProvider,m as useStepContext};
|
package/es/StepFlow/StepGroup.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import n,{useEffect as p}from"react";import{useStepContext as c}from".";const a=({children:r})=>{const{setTotalSteps:e,currentStep:o}=c(),t=n.Children.toArray(r);return p(()=>{e(t.length)},[t.length,e]),t[o-1]};export{a as StepGroup};
|
package/es/StepFlow/types.js
DELETED
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var s=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var v=(e,t)=>{for(var n in t)s(e,n,{get:t[n],enumerable:!0})},P=(e,t,n,d)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of C(t))!f.call(e,o)&&o!==n&&s(e,o,{get:()=>t[o],enumerable:!(d=x(t,o))||d.enumerable});return e};var l=e=>P(s({},"__esModule",{value:!0}),e);var T={};v(T,{StepProvider:()=>h,useStepContext:()=>m});module.exports=l(T);var c=require("react/jsx-runtime"),r=require("react");const S=(0,r.createContext)(void 0),h=({children:e})=>{const[t,n]=(0,r.useState)(1),[d,o]=(0,r.useState)(1),[i,a]=(0,r.useState)({}),u={formState:i,setFormState:a,totalSteps:t,setTotalSteps:n,currentStep:d,handleGoToStep:p=>o(p),handleNext:()=>o(p=>p+1),handlePrevious:()=>o(p=>p-1)};return(0,c.jsx)(S.Provider,{value:u,children:e})},m=()=>{const e=(0,r.useContext)(S);if(e===void 0)throw new Error("Context hook used outside of Step provider");return e};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var S=Object.create;var p=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var l=Object.getPrototypeOf,m=Object.prototype.hasOwnProperty;var f=(t,e)=>{for(var r in e)p(t,r,{get:e[r],enumerable:!0})},s=(t,e,r,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of i(e))!m.call(t,n)&&n!==r&&p(t,n,{get:()=>e[n],enumerable:!(o=a(e,n))||o.enumerable});return t};var h=(t,e,r)=>(r=t!=null?S(l(t)):{},s(e||!t||!t.__esModule?p(r,"default",{value:t,enumerable:!0}):r,t)),d=t=>s(p({},"__esModule",{value:!0}),t);var G={};f(G,{StepGroup:()=>C});module.exports=d(G);var c=h(require("react")),u=require(".");const C=({children:t})=>{const{setTotalSteps:e,currentStep:r}=(0,u.useStepContext)(),o=c.default.Children.toArray(t);return(0,c.useEffect)(()=>{e(o.length)},[o.length,e]),o[r-1]};
|
package/lib/StepFlow/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var n=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var i=Object.prototype.hasOwnProperty;var m=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of p(t))!i.call(e,o)&&o!==r&&n(e,o,{get:()=>t[o],enumerable:!(a=S(t,o))||a.enumerable});return e};var s=e=>m(n({},"__esModule",{value:!0}),e);var c={};module.exports=s(c);
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright IBM Corp. 2025, 2025
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
import { ReactNode } from 'react';
|
|
8
|
-
import { StepContextType } from './types';
|
|
9
|
-
interface StepProviderProps {
|
|
10
|
-
children: ReactNode;
|
|
11
|
-
}
|
|
12
|
-
export declare const StepProvider: ({ children }: StepProviderProps) => import("react/jsx-runtime").JSX.Element;
|
|
13
|
-
export declare const useStepContext: () => StepContextType;
|
|
14
|
-
export {};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright IBM Corp. 2025, 2025
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
import React from 'react';
|
|
8
|
-
interface StepGroupProps {
|
|
9
|
-
children: React.ReactNode;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Container for steps. The children are filtered for only truthy values (via Children.toArray)
|
|
13
|
-
* and only the current step is returned from this component based on the `currentStep` value
|
|
14
|
-
* from `useStepContext`.
|
|
15
|
-
*/
|
|
16
|
-
export declare const StepGroup: ({ children }: StepGroupProps) => string | number | bigint | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | React.ReactPortal | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined>;
|
|
17
|
-
export {};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright IBM Corp. 2025, 2025
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
export { StepGroup } from './StepGroup';
|
|
8
|
-
export { StepProvider, useStepContext } from './StepContext';
|
|
9
|
-
export type { StepContextType } from './types';
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright IBM Corp. 2025, 2025
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
import { Dispatch, SetStateAction } from 'react';
|
|
8
|
-
/**
|
|
9
|
-
* This interface should be extended by the consumer to match their own unique
|
|
10
|
-
* use case given the fields within their own stepped experience.
|
|
11
|
-
*/
|
|
12
|
-
interface formStateType {
|
|
13
|
-
[key: string]: unknown;
|
|
14
|
-
}
|
|
15
|
-
export interface StepContextType {
|
|
16
|
-
formState: formStateType;
|
|
17
|
-
setFormState: Dispatch<SetStateAction<formStateType>>;
|
|
18
|
-
totalSteps: number;
|
|
19
|
-
setTotalSteps: Dispatch<SetStateAction<number>>;
|
|
20
|
-
currentStep: number;
|
|
21
|
-
handleGoToStep: (step: number) => void;
|
|
22
|
-
handleNext: () => void;
|
|
23
|
-
handlePrevious: () => void;
|
|
24
|
-
}
|
|
25
|
-
export {};
|
package/types/index.d.ts
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright IBM Corp. 2024
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
export * from '@carbon/utilities';
|
|
8
|
-
export * from './useNoInteractiveChildren';
|
|
9
|
-
export * from './StepFlow';
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export function useNoInteractiveChildren(ref: any, message?: string): void;
|
|
2
|
-
export function useInteractiveChildrenNeedDescription(ref: any, message?: string): void;
|
|
3
|
-
/**
|
|
4
|
-
* Determines if a given DOM node has interactive content, or is itself
|
|
5
|
-
* interactive. It returns the interactive node if one is found
|
|
6
|
-
*
|
|
7
|
-
* @param {HTMLElement} node
|
|
8
|
-
* @returns {HTMLElement}
|
|
9
|
-
*/
|
|
10
|
-
export function getInteractiveContent(node: HTMLElement): HTMLElement;
|
|
11
|
-
/**
|
|
12
|
-
* Determines if a given DOM node has a role, or has itself a role.
|
|
13
|
-
* It returns the node with a role if one is found
|
|
14
|
-
*
|
|
15
|
-
* @param {HTMLElement} node
|
|
16
|
-
* @returns {HTMLElement}
|
|
17
|
-
*/
|
|
18
|
-
export function getRoleContent(node: HTMLElement): HTMLElement;
|