@canonical/react-components 3.9.1 → 3.10.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/dist/components/PrefixedInput/PrefixedInput.d.ts +13 -0
- package/dist/components/PrefixedInput/PrefixedInput.js +64 -0
- package/dist/components/PrefixedInput/PrefixedInput.scss +22 -0
- package/dist/components/PrefixedInput/PrefixedInput.stories.d.ts +11 -0
- package/dist/components/PrefixedInput/PrefixedInput.stories.js +58 -0
- package/dist/components/PrefixedInput/PrefixedInput.test.d.ts +1 -0
- package/dist/components/PrefixedInput/index.d.ts +1 -0
- package/dist/components/PrefixedInput/index.js +13 -0
- package/dist/components/PrefixedIpInput/PrefixedIpInput.d.ts +27 -0
- package/dist/components/PrefixedIpInput/PrefixedIpInput.js +65 -0
- package/dist/components/PrefixedIpInput/PrefixedIpInput.stories.d.ts +13 -0
- package/dist/components/PrefixedIpInput/PrefixedIpInput.stories.js +137 -0
- package/dist/components/PrefixedIpInput/PrefixedIpInput.test.d.ts +1 -0
- package/dist/components/PrefixedIpInput/index.d.ts +2 -0
- package/dist/components/PrefixedIpInput/index.js +56 -0
- package/dist/components/PrefixedIpInput/utils.d.ts +39 -0
- package/dist/components/PrefixedIpInput/utils.js +125 -0
- package/dist/components/PrefixedIpInput/utils.test.d.ts +1 -0
- package/dist/esm/components/PrefixedInput/PrefixedInput.d.ts +13 -0
- package/dist/esm/components/PrefixedInput/PrefixedInput.js +57 -0
- package/dist/esm/components/PrefixedInput/PrefixedInput.scss +22 -0
- package/dist/esm/components/PrefixedInput/PrefixedInput.stories.d.ts +11 -0
- package/dist/esm/components/PrefixedInput/PrefixedInput.stories.js +51 -0
- package/dist/esm/components/PrefixedInput/PrefixedInput.test.d.ts +1 -0
- package/dist/esm/components/PrefixedInput/index.d.ts +1 -0
- package/dist/esm/components/PrefixedInput/index.js +1 -0
- package/dist/esm/components/PrefixedIpInput/PrefixedIpInput.d.ts +27 -0
- package/dist/esm/components/PrefixedIpInput/PrefixedIpInput.js +58 -0
- package/dist/esm/components/PrefixedIpInput/PrefixedIpInput.stories.d.ts +13 -0
- package/dist/esm/components/PrefixedIpInput/PrefixedIpInput.stories.js +128 -0
- package/dist/esm/components/PrefixedIpInput/PrefixedIpInput.test.d.ts +1 -0
- package/dist/esm/components/PrefixedIpInput/index.d.ts +2 -0
- package/dist/esm/components/PrefixedIpInput/index.js +2 -0
- package/dist/esm/components/PrefixedIpInput/utils.d.ts +39 -0
- package/dist/esm/components/PrefixedIpInput/utils.js +112 -0
- package/dist/esm/components/PrefixedIpInput/utils.test.d.ts +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +2 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +65 -0
- package/package.json +1 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ReactElement } from "react";
|
|
2
|
+
import { type InputProps } from "../Input";
|
|
3
|
+
import "./PrefixedInput.scss";
|
|
4
|
+
import { PropsWithSpread } from "../../types";
|
|
5
|
+
export type PrefixedInputProps = PropsWithSpread<{
|
|
6
|
+
/**
|
|
7
|
+
* The immutable text that appears at the beginning of the input field.
|
|
8
|
+
* This text is not editable by the user and visually appears inside the input.
|
|
9
|
+
*/
|
|
10
|
+
immutableText: string;
|
|
11
|
+
}, Omit<InputProps, "type">>;
|
|
12
|
+
declare const PrefixedInput: ({ immutableText, ...props }: PrefixedInputProps) => ReactElement;
|
|
13
|
+
export default PrefixedInput;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _Input = _interopRequireDefault(require("../Input"));
|
|
9
|
+
var _classnames = _interopRequireDefault(require("classnames"));
|
|
10
|
+
require("./PrefixedInput.scss");
|
|
11
|
+
var _useListener = require("../../hooks/useListener");
|
|
12
|
+
const _excluded = ["immutableText"];
|
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
14
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
15
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
16
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
17
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
18
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
19
|
+
// export type PrefixedInputProps = Omit<InputProps, "type"> & {
|
|
20
|
+
// /**
|
|
21
|
+
// * The immutable text that appears at the beginning of the input field.
|
|
22
|
+
// * This text is not editable by the user and visually appears inside the input.
|
|
23
|
+
// */
|
|
24
|
+
// immutableText: string;
|
|
25
|
+
// };
|
|
26
|
+
|
|
27
|
+
const PrefixedInput = _ref => {
|
|
28
|
+
let {
|
|
29
|
+
immutableText
|
|
30
|
+
} = _ref,
|
|
31
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
32
|
+
const prefixTextRef = (0, _react.useRef)(null);
|
|
33
|
+
const inputWrapperRef = (0, _react.useRef)(null);
|
|
34
|
+
const updatePadding = (0, _react.useCallback)(() => {
|
|
35
|
+
var _inputWrapperRef$curr;
|
|
36
|
+
const prefixElement = prefixTextRef.current;
|
|
37
|
+
const inputElement = (_inputWrapperRef$curr = inputWrapperRef.current) === null || _inputWrapperRef$curr === void 0 ? void 0 : _inputWrapperRef$curr.querySelector("input");
|
|
38
|
+
if (prefixElement && inputElement) {
|
|
39
|
+
// Adjust the left padding of the input to be the same width as the immutable text.
|
|
40
|
+
// This displays the user input and the unchangeable text together as one combined string.
|
|
41
|
+
const prefixWidth = prefixElement.getBoundingClientRect().width;
|
|
42
|
+
inputElement.style.paddingLeft = "".concat(prefixWidth, "px");
|
|
43
|
+
}
|
|
44
|
+
}, []);
|
|
45
|
+
(0, _useListener.useListener)(window, updatePadding, "resize", true);
|
|
46
|
+
(0, _react.useLayoutEffect)(() => {
|
|
47
|
+
updatePadding();
|
|
48
|
+
}, [immutableText, props.label, updatePadding]);
|
|
49
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
50
|
+
className: (0, _classnames.default)("prefixed-input", {
|
|
51
|
+
"prefixed-input--with-label": !!props.label
|
|
52
|
+
})
|
|
53
|
+
}, /*#__PURE__*/_react.default.createElement("div", {
|
|
54
|
+
className: "prefixed-input__text",
|
|
55
|
+
ref: prefixTextRef
|
|
56
|
+
}, immutableText), /*#__PURE__*/_react.default.createElement("div", {
|
|
57
|
+
ref: inputWrapperRef
|
|
58
|
+
}, /*#__PURE__*/_react.default.createElement(_Input.default, _extends({}, props, {
|
|
59
|
+
className: (0, _classnames.default)("prefixed-input__input", props.className),
|
|
60
|
+
type: "text",
|
|
61
|
+
wrapperClassName: (0, _classnames.default)("prefixed-input__wrapper", props.wrapperClassName)
|
|
62
|
+
}))));
|
|
63
|
+
};
|
|
64
|
+
var _default = exports.default = PrefixedInput;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
@import "vanilla-framework";
|
|
2
|
+
|
|
3
|
+
.prefixed-input {
|
|
4
|
+
position: relative;
|
|
5
|
+
|
|
6
|
+
.prefixed-input__input {
|
|
7
|
+
padding-top: 0.25rem;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.prefixed-input__text {
|
|
11
|
+
padding-left: $spv--large;
|
|
12
|
+
padding-top: 0.3rem;
|
|
13
|
+
pointer-events: none;
|
|
14
|
+
position: absolute;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
&--with-label {
|
|
18
|
+
.prefixed-input__text {
|
|
19
|
+
top: 2.5rem;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import PrefixedInput from "./PrefixedInput";
|
|
3
|
+
declare const meta: Meta<typeof PrefixedInput>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof PrefixedInput>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const WithLabel: Story;
|
|
8
|
+
export declare const Disabled: Story;
|
|
9
|
+
export declare const WithError: Story;
|
|
10
|
+
export declare const WithHelpText: Story;
|
|
11
|
+
export declare const Required: Story;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.WithLabel = exports.WithHelpText = exports.WithError = exports.Required = exports.Disabled = exports.Default = void 0;
|
|
7
|
+
var _PrefixedInput = _interopRequireDefault(require("./PrefixedInput"));
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
|
+
const meta = {
|
|
10
|
+
component: _PrefixedInput.default,
|
|
11
|
+
tags: ["autodocs"]
|
|
12
|
+
};
|
|
13
|
+
var _default = exports.default = meta;
|
|
14
|
+
const Default = exports.Default = {
|
|
15
|
+
args: {
|
|
16
|
+
immutableText: "https://",
|
|
17
|
+
placeholder: "example.com"
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
const WithLabel = exports.WithLabel = {
|
|
21
|
+
args: {
|
|
22
|
+
immutableText: "https://",
|
|
23
|
+
label: "Website URL",
|
|
24
|
+
placeholder: "example.com"
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const Disabled = exports.Disabled = {
|
|
28
|
+
args: {
|
|
29
|
+
immutableText: "@",
|
|
30
|
+
label: "Username",
|
|
31
|
+
placeholder: "username",
|
|
32
|
+
disabled: true
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const WithError = exports.WithError = {
|
|
36
|
+
args: {
|
|
37
|
+
immutableText: "https://",
|
|
38
|
+
label: "Website URL",
|
|
39
|
+
placeholder: "example.com",
|
|
40
|
+
error: "Invalid URL format"
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
const WithHelpText = exports.WithHelpText = {
|
|
44
|
+
args: {
|
|
45
|
+
immutableText: "User ID:",
|
|
46
|
+
label: "User Identifier",
|
|
47
|
+
placeholder: " Enter user ID",
|
|
48
|
+
help: "This will be used to identify your account"
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const Required = exports.Required = {
|
|
52
|
+
args: {
|
|
53
|
+
immutableText: "https://",
|
|
54
|
+
label: "Website URL",
|
|
55
|
+
placeholder: "example.com",
|
|
56
|
+
required: true
|
|
57
|
+
}
|
|
58
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, type PrefixedInputProps } from "./PrefixedInput";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "default", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _PrefixedInput.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
var _PrefixedInput = _interopRequireDefault(require("./PrefixedInput"));
|
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ReactElement } from "react";
|
|
2
|
+
import { type PrefixedInputProps } from "../PrefixedInput";
|
|
3
|
+
import { PropsWithSpread } from "../../types";
|
|
4
|
+
export type PrefixedIpInputProps = PropsWithSpread<{
|
|
5
|
+
/**
|
|
6
|
+
* The CIDR for the subnet (e.g., "192.168.1.0/24" or "2001:db8::/32").
|
|
7
|
+
* Used to calculate the immutable prefix and available IP range.
|
|
8
|
+
*/
|
|
9
|
+
cidr: string;
|
|
10
|
+
/**
|
|
11
|
+
* The full IP address value (if available).
|
|
12
|
+
* For IPv4: e.g., "192.168.1.100"
|
|
13
|
+
* For IPv6: e.g., "2001:db8::1"
|
|
14
|
+
*/
|
|
15
|
+
ip: string;
|
|
16
|
+
/**
|
|
17
|
+
* The name attribute for the input field.
|
|
18
|
+
*/
|
|
19
|
+
name: string;
|
|
20
|
+
/**
|
|
21
|
+
* Callback function that is called when the IP address changes.
|
|
22
|
+
* Receives the full IP address as a string parameter.
|
|
23
|
+
*/
|
|
24
|
+
onIpChange: (ip: string) => void;
|
|
25
|
+
}, Omit<PrefixedInputProps, "immutableText" | "maxLength" | "placeholder" | "name">>;
|
|
26
|
+
declare const PrefixedIpInput: ({ cidr, help, onIpChange, ip, name, ...props }: PrefixedIpInputProps) => ReactElement;
|
|
27
|
+
export default PrefixedIpInput;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _PrefixedInput = _interopRequireDefault(require("../PrefixedInput"));
|
|
9
|
+
var _utils = require("./utils");
|
|
10
|
+
const _excluded = ["cidr", "help", "onIpChange", "ip", "name"];
|
|
11
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
12
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
13
|
+
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
|
|
14
|
+
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
15
|
+
const PrefixedIpInput = _ref => {
|
|
16
|
+
let {
|
|
17
|
+
cidr,
|
|
18
|
+
help,
|
|
19
|
+
onIpChange,
|
|
20
|
+
ip,
|
|
21
|
+
name
|
|
22
|
+
} = _ref,
|
|
23
|
+
props = _objectWithoutProperties(_ref, _excluded);
|
|
24
|
+
const [networkAddress] = cidr.split("/");
|
|
25
|
+
const isIPV4 = (0, _utils.isIPv4)(networkAddress);
|
|
26
|
+
const [immutable, editable] = (0, _utils.getImmutableAndEditable)(cidr);
|
|
27
|
+
const inputValue = isIPV4 ? ip.split(".").slice(immutable.split(".").length).join(".") : ip.replace(immutable, "");
|
|
28
|
+
const getIPv4MaxLength = () => {
|
|
29
|
+
const immutableOctetsLength = immutable.split(".").length;
|
|
30
|
+
const lengths = [15, 11, 7, 3]; // Corresponding to 0-3 immutable octets
|
|
31
|
+
return lengths[immutableOctetsLength];
|
|
32
|
+
};
|
|
33
|
+
const maxLength = isIPV4 ? getIPv4MaxLength() : editable.length;
|
|
34
|
+
const placeholder = props.disabled ? "" : editable;
|
|
35
|
+
const setIp = editableValue => {
|
|
36
|
+
const fullIp = editableValue ? isIPV4 ? "".concat(immutable, ".").concat(editableValue) : "".concat(immutable).concat(editableValue) : "";
|
|
37
|
+
onIpChange(fullIp);
|
|
38
|
+
};
|
|
39
|
+
const handlePaste = e => {
|
|
40
|
+
e.preventDefault();
|
|
41
|
+
const pastedText = e.clipboardData.getData("text");
|
|
42
|
+
if (isIPV4) {
|
|
43
|
+
const octets = pastedText.split(".");
|
|
44
|
+
const trimmed = octets.slice(0 - editable.split(".").length);
|
|
45
|
+
const ip = trimmed.join(".");
|
|
46
|
+
setIp(ip);
|
|
47
|
+
} else {
|
|
48
|
+
const ip = pastedText.replace(immutable, "");
|
|
49
|
+
setIp(ip);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
return /*#__PURE__*/_react.default.createElement(_PrefixedInput.default, _extends({
|
|
53
|
+
help: help ? help : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, " ", isIPV4 ? /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, " ", "The available range in this subnet is", " ", /*#__PURE__*/_react.default.createElement("code", null, immutable, ".", editable, " ")) : /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, " ", "The available IPV6 address range is", " ", /*#__PURE__*/_react.default.createElement("code", null, immutable, editable, " ")), "."),
|
|
54
|
+
immutableText: isIPV4 ? "".concat(immutable, ".") : immutable,
|
|
55
|
+
maxLength: maxLength,
|
|
56
|
+
name: name,
|
|
57
|
+
onPaste: handlePaste,
|
|
58
|
+
value: inputValue,
|
|
59
|
+
onChange: e => {
|
|
60
|
+
setIp(e.target.value);
|
|
61
|
+
},
|
|
62
|
+
placeholder: placeholder
|
|
63
|
+
}, props));
|
|
64
|
+
};
|
|
65
|
+
var _default = exports.default = PrefixedIpInput;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import PrefixedIpInput from "./PrefixedIpInput";
|
|
3
|
+
declare const meta: Meta<typeof PrefixedIpInput>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof PrefixedIpInput>;
|
|
6
|
+
export declare const IPv4Default: Story;
|
|
7
|
+
export declare const IPv4WithValue: Story;
|
|
8
|
+
export declare const IPv4WithError: Story;
|
|
9
|
+
export declare const IPv4Disabled: Story;
|
|
10
|
+
export declare const IPv6Default: Story;
|
|
11
|
+
export declare const IPv6WithValue: Story;
|
|
12
|
+
export declare const WithCustomHelp: Story;
|
|
13
|
+
export declare const Required: Story;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.WithCustomHelp = exports.Required = exports.IPv6WithValue = exports.IPv6Default = exports.IPv4WithValue = exports.IPv4WithError = exports.IPv4Disabled = exports.IPv4Default = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _PrefixedIpInput = _interopRequireDefault(require("./PrefixedIpInput"));
|
|
9
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
10
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
11
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
12
|
+
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
13
|
+
const PrefixedIpInputWrapper = args => {
|
|
14
|
+
const [ip, setIp] = (0, _react.useState)(args.ip);
|
|
15
|
+
return /*#__PURE__*/_react.default.createElement(_PrefixedIpInput.default, _extends({}, args, {
|
|
16
|
+
ip: ip,
|
|
17
|
+
onIpChange: newIp => {
|
|
18
|
+
var _args$onIpChange;
|
|
19
|
+
setIp(newIp);
|
|
20
|
+
(_args$onIpChange = args.onIpChange) === null || _args$onIpChange === void 0 || _args$onIpChange.call(args, newIp);
|
|
21
|
+
}
|
|
22
|
+
}));
|
|
23
|
+
};
|
|
24
|
+
const meta = {
|
|
25
|
+
component: _PrefixedIpInput.default,
|
|
26
|
+
tags: ["autodocs"],
|
|
27
|
+
argTypes: {
|
|
28
|
+
ip: {
|
|
29
|
+
control: "text"
|
|
30
|
+
},
|
|
31
|
+
cidr: {
|
|
32
|
+
control: "text"
|
|
33
|
+
},
|
|
34
|
+
label: {
|
|
35
|
+
control: "text"
|
|
36
|
+
},
|
|
37
|
+
name: {
|
|
38
|
+
control: "text"
|
|
39
|
+
},
|
|
40
|
+
error: {
|
|
41
|
+
control: "text"
|
|
42
|
+
},
|
|
43
|
+
help: {
|
|
44
|
+
control: "text"
|
|
45
|
+
},
|
|
46
|
+
disabled: {
|
|
47
|
+
control: "boolean"
|
|
48
|
+
},
|
|
49
|
+
required: {
|
|
50
|
+
control: "boolean"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
render: args => /*#__PURE__*/_react.default.createElement(PrefixedIpInputWrapper, args)
|
|
54
|
+
};
|
|
55
|
+
var _default = exports.default = meta;
|
|
56
|
+
const IPv4Default = exports.IPv4Default = {
|
|
57
|
+
name: "IPv4 default",
|
|
58
|
+
args: {
|
|
59
|
+
cidr: "192.168.1.0/24",
|
|
60
|
+
ip: "",
|
|
61
|
+
name: "ip-address",
|
|
62
|
+
label: "IP Address",
|
|
63
|
+
onIpChange: ip => console.log("IP changed:", ip)
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const IPv4WithValue = exports.IPv4WithValue = {
|
|
67
|
+
name: "IPv4 with value",
|
|
68
|
+
args: {
|
|
69
|
+
cidr: "192.168.1.0/24",
|
|
70
|
+
ip: "192.168.1.100",
|
|
71
|
+
name: "ip-address",
|
|
72
|
+
label: "IP Address",
|
|
73
|
+
onIpChange: ip => console.log("IP changed:", ip)
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
const IPv4WithError = exports.IPv4WithError = {
|
|
77
|
+
name: "IPv4 with error",
|
|
78
|
+
args: {
|
|
79
|
+
cidr: "192.168.1.0/24",
|
|
80
|
+
ip: "192.168.1.256",
|
|
81
|
+
name: "ip-address",
|
|
82
|
+
label: "IP Address",
|
|
83
|
+
error: "Invalid IP address",
|
|
84
|
+
onIpChange: ip => console.log("IP changed:", ip)
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const IPv4Disabled = exports.IPv4Disabled = {
|
|
88
|
+
name: "IPv4 disabled",
|
|
89
|
+
args: {
|
|
90
|
+
cidr: "192.168.1.0/24",
|
|
91
|
+
ip: "192.168.1.50",
|
|
92
|
+
name: "ip-address",
|
|
93
|
+
label: "IP Address",
|
|
94
|
+
disabled: true,
|
|
95
|
+
onIpChange: ip => console.log("IP changed:", ip)
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const IPv6Default = exports.IPv6Default = {
|
|
99
|
+
name: "IPv6 default",
|
|
100
|
+
args: {
|
|
101
|
+
cidr: "2001:db8::/32",
|
|
102
|
+
ip: "",
|
|
103
|
+
name: "ipv6-address",
|
|
104
|
+
label: "IPv6 Address",
|
|
105
|
+
onIpChange: ip => console.log("IP changed:", ip)
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const IPv6WithValue = exports.IPv6WithValue = {
|
|
109
|
+
name: "IPv6 with value",
|
|
110
|
+
args: {
|
|
111
|
+
cidr: "2001:db8::/32",
|
|
112
|
+
ip: "2001:db8::1",
|
|
113
|
+
name: "ipv6-address",
|
|
114
|
+
label: "IPv6 Address",
|
|
115
|
+
onIpChange: ip => console.log("IP changed:", ip)
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const WithCustomHelp = exports.WithCustomHelp = {
|
|
119
|
+
args: {
|
|
120
|
+
cidr: "10.0.0.0/16",
|
|
121
|
+
ip: "",
|
|
122
|
+
name: "ip-address",
|
|
123
|
+
label: "IP Address",
|
|
124
|
+
help: "Enter a custom IP address for this device",
|
|
125
|
+
onIpChange: ip => console.log("IP changed:", ip)
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
const Required = exports.Required = {
|
|
129
|
+
args: {
|
|
130
|
+
cidr: "192.168.0.0/24",
|
|
131
|
+
ip: "",
|
|
132
|
+
name: "ip-address",
|
|
133
|
+
label: "IP Address",
|
|
134
|
+
required: true,
|
|
135
|
+
onIpChange: ip => console.log("IP changed:", ip)
|
|
136
|
+
}
|
|
137
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "convertIpToUint32", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _utils.convertIpToUint32;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "default", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _PrefixedIpInput.default;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "getFirstValidIp", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _utils.getFirstValidIp;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(exports, "getImmutableAndEditable", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return _utils.getImmutableAndEditable;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(exports, "getImmutableAndEditableOctets", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function () {
|
|
33
|
+
return _utils.getImmutableAndEditableOctets;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(exports, "getIpRangeFromCidr", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
get: function () {
|
|
39
|
+
return _utils.getIpRangeFromCidr;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(exports, "isIPv4", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function () {
|
|
45
|
+
return _utils.isIPv4;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
Object.defineProperty(exports, "isIpInSubnet", {
|
|
49
|
+
enumerable: true,
|
|
50
|
+
get: function () {
|
|
51
|
+
return _utils.isIpInSubnet;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
var _PrefixedIpInput = _interopRequireDefault(require("./PrefixedIpInput"));
|
|
55
|
+
var _utils = require("./utils");
|
|
56
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if a given IP address is a valid IPv4 address.
|
|
3
|
+
* @param ip The IP address to check
|
|
4
|
+
* @returns True if the IP is a valid IPv4 address, false otherwise
|
|
5
|
+
*/
|
|
6
|
+
export declare const isIPv4: (ip: string) => boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Takes a subnet CIDR notation (IPv4) and returns the first and last IP of the subnet.
|
|
9
|
+
* The network and host addresses are excluded.
|
|
10
|
+
*
|
|
11
|
+
* @param cidr The CIDR notation of the subnet
|
|
12
|
+
* @returns The first and last valid IP addresses as two strings in a list.
|
|
13
|
+
*/
|
|
14
|
+
export declare const getIpRangeFromCidr: (cidr: string) => string[];
|
|
15
|
+
export declare const getFirstValidIp: (ip: string) => string;
|
|
16
|
+
export declare const convertIpToUint32: (ip: string) => number;
|
|
17
|
+
/**
|
|
18
|
+
* Checks if an IPv4 address is valid for the given subnet.
|
|
19
|
+
*
|
|
20
|
+
* @param ip The IPv4 address to check, as a string
|
|
21
|
+
* @param cidr The subnet's CIDR notation e.g. 192.168.0.0/24
|
|
22
|
+
* @returns True if the IP is in the subnet, false otherwise
|
|
23
|
+
*/
|
|
24
|
+
export declare const isIpInSubnet: (ip: string, cidr: string) => boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Separates the immutable and editable octets of an IPv4 subnet range.
|
|
27
|
+
*
|
|
28
|
+
* @param startIp The start IP of the subnet
|
|
29
|
+
* @param endIp The end IP of the subnet
|
|
30
|
+
* @returns The immutable and editable octects as two strings in a list
|
|
31
|
+
*/
|
|
32
|
+
export declare const getImmutableAndEditableOctets: (startIp: string, endIp: string) => string[];
|
|
33
|
+
/**
|
|
34
|
+
* Get the immutable and editable parts of an IPv4 or IPv6 subnet.
|
|
35
|
+
*
|
|
36
|
+
* @param cidr The CIDR notation of the subnet
|
|
37
|
+
* @returns The immutable and editable as two strings in a list
|
|
38
|
+
*/
|
|
39
|
+
export declare const getImmutableAndEditable: (cidr: string) => string[];
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isIpInSubnet = exports.isIPv4 = exports.getIpRangeFromCidr = exports.getImmutableAndEditableOctets = exports.getImmutableAndEditable = exports.getFirstValidIp = exports.convertIpToUint32 = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Checks if a given IP address is a valid IPv4 address.
|
|
9
|
+
* @param ip The IP address to check
|
|
10
|
+
* @returns True if the IP is a valid IPv4 address, false otherwise
|
|
11
|
+
*/
|
|
12
|
+
const isIPv4 = ip => {
|
|
13
|
+
const ipv4Regex = /^(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}$/;
|
|
14
|
+
return ipv4Regex.test(ip);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Takes a subnet CIDR notation (IPv4) and returns the first and last IP of the subnet.
|
|
19
|
+
* The network and host addresses are excluded.
|
|
20
|
+
*
|
|
21
|
+
* @param cidr The CIDR notation of the subnet
|
|
22
|
+
* @returns The first and last valid IP addresses as two strings in a list.
|
|
23
|
+
*/
|
|
24
|
+
exports.isIPv4 = isIPv4;
|
|
25
|
+
const getIpRangeFromCidr = cidr => {
|
|
26
|
+
// https://gist.github.com/binarymax/6114792
|
|
27
|
+
|
|
28
|
+
// Get start IP and number of valid addresses
|
|
29
|
+
const [startIp, mask] = cidr.split("/");
|
|
30
|
+
const numberOfAddresses = (1 << 32 - parseInt(mask)) - 1;
|
|
31
|
+
|
|
32
|
+
// IPv4 can be represented by an unsigned 32-bit integer, so we can use a Uint32Array to store the IP
|
|
33
|
+
const buffer = new ArrayBuffer(4); //4 octets
|
|
34
|
+
const int32 = new Uint32Array(buffer);
|
|
35
|
+
|
|
36
|
+
// Convert starting IP to Uint32 and add the number of addresses to get the end IP.
|
|
37
|
+
// Subtract 1 from the number of addresses to exclude the broadcast address.
|
|
38
|
+
int32[0] = convertIpToUint32(startIp) + numberOfAddresses - 1;
|
|
39
|
+
|
|
40
|
+
// Convert the buffer to a Uint8Array to get the octets, then convert it to an array
|
|
41
|
+
const arrayApplyBuffer = Array.from(new Uint8Array(buffer));
|
|
42
|
+
|
|
43
|
+
// Reverse the octets and join them with "." to get the end IP
|
|
44
|
+
const endIp = arrayApplyBuffer.reverse().join(".");
|
|
45
|
+
const firstValidIp = getFirstValidIp(startIp);
|
|
46
|
+
return [firstValidIp, endIp];
|
|
47
|
+
};
|
|
48
|
+
exports.getIpRangeFromCidr = getIpRangeFromCidr;
|
|
49
|
+
const getFirstValidIp = ip => {
|
|
50
|
+
const buffer = new ArrayBuffer(4); //4 octets
|
|
51
|
+
const int32 = new Uint32Array(buffer);
|
|
52
|
+
|
|
53
|
+
// add 1 because the first IP is the network address
|
|
54
|
+
int32[0] = convertIpToUint32(ip) + 1;
|
|
55
|
+
const arrayApplyBuffer = Array.from(new Uint8Array(buffer));
|
|
56
|
+
return arrayApplyBuffer.reverse().join(".");
|
|
57
|
+
};
|
|
58
|
+
exports.getFirstValidIp = getFirstValidIp;
|
|
59
|
+
const convertIpToUint32 = ip => {
|
|
60
|
+
const octets = ip.split(".").map(a => parseInt(a));
|
|
61
|
+
const buffer = new ArrayBuffer(4);
|
|
62
|
+
const int32 = new Uint32Array(buffer);
|
|
63
|
+
int32[0] = (octets[0] << 24) + (octets[1] << 16) + (octets[2] << 8) + octets[3];
|
|
64
|
+
return int32[0];
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Checks if an IPv4 address is valid for the given subnet.
|
|
69
|
+
*
|
|
70
|
+
* @param ip The IPv4 address to check, as a string
|
|
71
|
+
* @param cidr The subnet's CIDR notation e.g. 192.168.0.0/24
|
|
72
|
+
* @returns True if the IP is in the subnet, false otherwise
|
|
73
|
+
*/
|
|
74
|
+
exports.convertIpToUint32 = convertIpToUint32;
|
|
75
|
+
const isIpInSubnet = (ip, cidr) => {
|
|
76
|
+
const [startIP, endIP] = getIpRangeFromCidr(cidr);
|
|
77
|
+
const ipUint32 = convertIpToUint32(ip);
|
|
78
|
+
const startIPUint32 = convertIpToUint32(startIP);
|
|
79
|
+
const endIPUint32 = convertIpToUint32(endIP);
|
|
80
|
+
return ipUint32 >= startIPUint32 && ipUint32 <= endIPUint32;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Separates the immutable and editable octets of an IPv4 subnet range.
|
|
85
|
+
*
|
|
86
|
+
* @param startIp The start IP of the subnet
|
|
87
|
+
* @param endIp The end IP of the subnet
|
|
88
|
+
* @returns The immutable and editable octects as two strings in a list
|
|
89
|
+
*/
|
|
90
|
+
exports.isIpInSubnet = isIpInSubnet;
|
|
91
|
+
const getImmutableAndEditableOctets = (startIp, endIp) => {
|
|
92
|
+
const startIpOctetList = startIp.split(".");
|
|
93
|
+
const endIpOctetList = endIp.split(".");
|
|
94
|
+
const immutable = [];
|
|
95
|
+
const editable = [];
|
|
96
|
+
startIpOctetList.forEach((octet, index) => {
|
|
97
|
+
if (octet === endIpOctetList[index]) {
|
|
98
|
+
immutable.push(octet);
|
|
99
|
+
} else {
|
|
100
|
+
editable.push("[".concat(octet, "-").concat(endIpOctetList[index], "]"));
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
return [immutable.join("."), editable.join(".")];
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get the immutable and editable parts of an IPv4 or IPv6 subnet.
|
|
108
|
+
*
|
|
109
|
+
* @param cidr The CIDR notation of the subnet
|
|
110
|
+
* @returns The immutable and editable as two strings in a list
|
|
111
|
+
*/
|
|
112
|
+
exports.getImmutableAndEditableOctets = getImmutableAndEditableOctets;
|
|
113
|
+
const getImmutableAndEditable = cidr => {
|
|
114
|
+
const isIPV4 = isIPv4(cidr.split("/")[0]);
|
|
115
|
+
if (isIPV4) {
|
|
116
|
+
const [startIp, endIp] = getIpRangeFromCidr(cidr);
|
|
117
|
+
return getImmutableAndEditableOctets(startIp, endIp);
|
|
118
|
+
}
|
|
119
|
+
const [networkAddress] = cidr.split("/");
|
|
120
|
+
const immutableIPV6 = networkAddress.substring(0, networkAddress.lastIndexOf(":"));
|
|
121
|
+
const ipv6PlaceholderColons = 7 - (immutableIPV6.match(/:/g) || []).length; // 7 is the maximum number of colons in an IPv6 address
|
|
122
|
+
const editableIPV6 = "".concat("0000:".repeat(ipv6PlaceholderColons), "0000");
|
|
123
|
+
return [immutableIPV6, editableIPV6];
|
|
124
|
+
};
|
|
125
|
+
exports.getImmutableAndEditable = getImmutableAndEditable;
|