@canonical/react-components 4.2.0 → 4.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/OutputField/OutputField.d.ts +30 -0
- package/dist/components/OutputField/OutputField.js +44 -0
- package/dist/components/OutputField/OutputField.scss +11 -0
- package/dist/components/OutputField/OutputField.stories.d.ts +8 -0
- package/dist/components/OutputField/OutputField.stories.js +62 -0
- package/dist/components/OutputField/OutputField.test.d.ts +1 -0
- package/dist/components/OutputField/index.d.ts +2 -0
- package/dist/components/OutputField/index.js +13 -0
- package/dist/components/PrefixedIpInput/PrefixedIpInput.js +1 -1
- package/dist/components/PrefixedIpInput/utils.d.ts +10 -1
- package/dist/components/PrefixedIpInput/utils.js +43 -11
- package/dist/esm/components/OutputField/OutputField.d.ts +30 -0
- package/dist/esm/components/OutputField/OutputField.js +36 -0
- package/dist/esm/components/OutputField/OutputField.scss +11 -0
- package/dist/esm/components/OutputField/OutputField.stories.d.ts +8 -0
- package/dist/esm/components/OutputField/OutputField.stories.js +55 -0
- package/dist/esm/components/OutputField/OutputField.test.d.ts +1 -0
- package/dist/esm/components/OutputField/index.d.ts +2 -0
- package/dist/esm/components/OutputField/index.js +1 -0
- package/dist/esm/components/PrefixedIpInput/PrefixedIpInput.js +1 -1
- package/dist/esm/components/PrefixedIpInput/utils.d.ts +10 -1
- package/dist/esm/components/PrefixedIpInput/utils.js +38 -8
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +8 -0
- package/package.json +2 -2
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { FC, ReactNode } from "react";
|
|
2
|
+
import "./OutputField.scss";
|
|
3
|
+
export type Props = {
|
|
4
|
+
/**
|
|
5
|
+
* The id of the output element. This is used to associate the label with the output element for form or accessibility purposes.
|
|
6
|
+
*/
|
|
7
|
+
id: string;
|
|
8
|
+
/**
|
|
9
|
+
* The label for the output field.
|
|
10
|
+
*/
|
|
11
|
+
label: string;
|
|
12
|
+
/**
|
|
13
|
+
* The value to be displayed in the output field.
|
|
14
|
+
*/
|
|
15
|
+
value: string;
|
|
16
|
+
/**
|
|
17
|
+
* Optional help text to provide additional information about the output field.
|
|
18
|
+
*/
|
|
19
|
+
help?: ReactNode;
|
|
20
|
+
/**
|
|
21
|
+
* Whether the output field is required.
|
|
22
|
+
*/
|
|
23
|
+
required?: boolean;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* Use output fields to display read-only information with a label and optional help text. Output fields are ideal for displaying calculated values or results of user input in a consistent format.
|
|
28
|
+
*/
|
|
29
|
+
export declare const OutputField: FC<Props>;
|
|
30
|
+
export default OutputField;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.OutputField = void 0;
|
|
7
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
8
|
+
var _react = _interopRequireDefault(require("react"));
|
|
9
|
+
var _Field = _interopRequireDefault(require("../Field"));
|
|
10
|
+
require("./OutputField.scss");
|
|
11
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* Use output fields to display read-only information with a label and optional help text. Output fields are ideal for displaying calculated values or results of user input in a consistent format.
|
|
15
|
+
*/
|
|
16
|
+
const OutputField = _ref => {
|
|
17
|
+
let {
|
|
18
|
+
id,
|
|
19
|
+
label,
|
|
20
|
+
value,
|
|
21
|
+
help,
|
|
22
|
+
required
|
|
23
|
+
} = _ref;
|
|
24
|
+
return /*#__PURE__*/_react.default.createElement(_Field.default, {
|
|
25
|
+
forId: id,
|
|
26
|
+
label: label,
|
|
27
|
+
help: help,
|
|
28
|
+
labelClassName: "u-no-margin--bottom",
|
|
29
|
+
className: "output-field",
|
|
30
|
+
required: required
|
|
31
|
+
}, /*#__PURE__*/_react.default.createElement("output", {
|
|
32
|
+
id: id,
|
|
33
|
+
className: "mono-font u-sv2"
|
|
34
|
+
}, /*#__PURE__*/_react.default.createElement("b", null, value)));
|
|
35
|
+
};
|
|
36
|
+
exports.OutputField = OutputField;
|
|
37
|
+
OutputField.propTypes = {
|
|
38
|
+
id: _propTypes.default.string.isRequired,
|
|
39
|
+
label: _propTypes.default.string.isRequired,
|
|
40
|
+
value: _propTypes.default.string.isRequired,
|
|
41
|
+
help: _propTypes.default.node,
|
|
42
|
+
required: _propTypes.default.bool
|
|
43
|
+
};
|
|
44
|
+
var _default = exports.default = OutputField;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import OutputField from "./OutputField";
|
|
3
|
+
declare const meta: Meta<typeof OutputField>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof OutputField>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const HelpText: Story;
|
|
8
|
+
export declare const Required: Story;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.Required = exports.HelpText = exports.Default = void 0;
|
|
7
|
+
var _OutputField = _interopRequireDefault(require("./OutputField"));
|
|
8
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
const meta = {
|
|
10
|
+
component: _OutputField.default,
|
|
11
|
+
tags: ["autodocs"],
|
|
12
|
+
argTypes: {
|
|
13
|
+
label: {
|
|
14
|
+
control: {
|
|
15
|
+
type: "text"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
id: {
|
|
19
|
+
control: {
|
|
20
|
+
type: "text"
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
value: {
|
|
24
|
+
control: {
|
|
25
|
+
type: "text"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
help: {
|
|
29
|
+
control: {
|
|
30
|
+
type: "text"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
required: {
|
|
34
|
+
control: {
|
|
35
|
+
type: "boolean"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
args: {
|
|
40
|
+
label: "Label",
|
|
41
|
+
id: "output-field",
|
|
42
|
+
value: "Output value",
|
|
43
|
+
help: "",
|
|
44
|
+
required: false
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
var _default = exports.default = meta;
|
|
48
|
+
const Default = exports.Default = {
|
|
49
|
+
name: "Default"
|
|
50
|
+
};
|
|
51
|
+
const HelpText = exports.HelpText = {
|
|
52
|
+
name: "Help Text",
|
|
53
|
+
args: {
|
|
54
|
+
help: "This is an output field with text"
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const Required = exports.Required = {
|
|
58
|
+
name: "Required",
|
|
59
|
+
args: {
|
|
60
|
+
required: true
|
|
61
|
+
}
|
|
62
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -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 _OutputField.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
var _OutputField = _interopRequireDefault(require("./OutputField"));
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -50,7 +50,7 @@ const PrefixedIpInput = _ref => {
|
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
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
|
|
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 subnet CIDR is ", /*#__PURE__*/_react.default.createElement("code", null, cidr)), "."),
|
|
54
54
|
immutableText: isIPV4 ? "".concat(immutable, ".") : immutable,
|
|
55
55
|
maxLength: maxLength,
|
|
56
56
|
name: name,
|
|
@@ -14,6 +14,7 @@ export declare const isIPv4: (ip: string) => boolean;
|
|
|
14
14
|
export declare const getIpRangeFromCidr: (cidr: string) => string[];
|
|
15
15
|
export declare const getFirstValidIp: (ip: string) => string;
|
|
16
16
|
export declare const convertIpToUint32: (ip: string) => number;
|
|
17
|
+
export declare const convertUint32ToIp: (ipAsUint32: number) => string;
|
|
17
18
|
/**
|
|
18
19
|
* Checks if an IPv4 address is valid for the given subnet.
|
|
19
20
|
*
|
|
@@ -30,10 +31,18 @@ export declare const isIpInSubnet: (ip: string, cidr: string) => boolean;
|
|
|
30
31
|
* @returns The immutable and editable octects as two strings in a list
|
|
31
32
|
*/
|
|
32
33
|
export declare const getImmutableAndEditableOctets: (startIp: string, endIp: string) => string[];
|
|
34
|
+
/**
|
|
35
|
+
* Separates the immutable and editable parts of an IPv6 subnet range.
|
|
36
|
+
* For simplcity, if the prefix is not on a group boundary, the entire last group is considered editable.
|
|
37
|
+
*
|
|
38
|
+
* @param cidr The CIDR notation of the subnet
|
|
39
|
+
* @returns The immutable and editable parts as two strings in a list
|
|
40
|
+
*/
|
|
41
|
+
export declare const getImmutableAndEditableIPv6: (cidr: string) => string[];
|
|
33
42
|
/**
|
|
34
43
|
* Get the immutable and editable parts of an IPv4 or IPv6 subnet.
|
|
35
44
|
*
|
|
36
45
|
* @param cidr The CIDR notation of the subnet
|
|
37
|
-
* @returns The immutable and editable
|
|
46
|
+
* @returns The immutable and editable as two strings in a list
|
|
38
47
|
*/
|
|
39
48
|
export declare const getImmutableAndEditable: (cidr: string) => string[];
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.isIpInSubnet = exports.isIPv4 = exports.getIpRangeFromCidr = exports.getImmutableAndEditableOctets = exports.getImmutableAndEditable = exports.getFirstValidIp = exports.convertIpToUint32 = void 0;
|
|
6
|
+
exports.isIpInSubnet = exports.isIPv4 = exports.getIpRangeFromCidr = exports.getImmutableAndEditableOctets = exports.getImmutableAndEditableIPv6 = exports.getImmutableAndEditable = exports.getFirstValidIp = exports.convertUint32ToIp = exports.convertIpToUint32 = void 0;
|
|
7
7
|
/**
|
|
8
8
|
* Checks if a given IP address is a valid IPv4 address.
|
|
9
9
|
* @param ip The IP address to check
|
|
@@ -26,8 +26,11 @@ const getIpRangeFromCidr = cidr => {
|
|
|
26
26
|
// https://gist.github.com/binarymax/6114792
|
|
27
27
|
|
|
28
28
|
// Get start IP and number of valid addresses
|
|
29
|
-
const [
|
|
30
|
-
const
|
|
29
|
+
const [unmaskedStartIp, mask] = cidr.split("/");
|
|
30
|
+
const maskBits = parseInt(mask, 10);
|
|
31
|
+
const subnetMask = maskBits === 0 ? 0 : 0xffffffff << 32 - maskBits >>> 0;
|
|
32
|
+
const startIp = convertUint32ToIp(convertIpToUint32(unmaskedStartIp) & subnetMask);
|
|
33
|
+
const numberOfAddresses = (1 << 32 - maskBits) - 1;
|
|
31
34
|
|
|
32
35
|
// IPv4 can be represented by an unsigned 32-bit integer, so we can use a Uint32Array to store the IP
|
|
33
36
|
const buffer = new ArrayBuffer(4); //4 octets
|
|
@@ -63,6 +66,14 @@ const convertIpToUint32 = ip => {
|
|
|
63
66
|
int32[0] = (octets[0] << 24) + (octets[1] << 16) + (octets[2] << 8) + octets[3];
|
|
64
67
|
return int32[0];
|
|
65
68
|
};
|
|
69
|
+
exports.convertIpToUint32 = convertIpToUint32;
|
|
70
|
+
const convertUint32ToIp = ipAsUint32 => {
|
|
71
|
+
const buffer = new ArrayBuffer(4); //4 octets
|
|
72
|
+
const int32 = new Uint32Array(buffer);
|
|
73
|
+
int32[0] = ipAsUint32;
|
|
74
|
+
const octets = Array.from(new Uint8Array(buffer));
|
|
75
|
+
return octets.reverse().join(".");
|
|
76
|
+
};
|
|
66
77
|
|
|
67
78
|
/**
|
|
68
79
|
* Checks if an IPv4 address is valid for the given subnet.
|
|
@@ -71,7 +82,7 @@ const convertIpToUint32 = ip => {
|
|
|
71
82
|
* @param cidr The subnet's CIDR notation e.g. 192.168.0.0/24
|
|
72
83
|
* @returns True if the IP is in the subnet, false otherwise
|
|
73
84
|
*/
|
|
74
|
-
exports.
|
|
85
|
+
exports.convertUint32ToIp = convertUint32ToIp;
|
|
75
86
|
const isIpInSubnet = (ip, cidr) => {
|
|
76
87
|
const [startIP, endIP] = getIpRangeFromCidr(cidr);
|
|
77
88
|
const ipUint32 = convertIpToUint32(ip);
|
|
@@ -104,22 +115,43 @@ const getImmutableAndEditableOctets = (startIp, endIp) => {
|
|
|
104
115
|
};
|
|
105
116
|
|
|
106
117
|
/**
|
|
107
|
-
*
|
|
118
|
+
* Separates the immutable and editable parts of an IPv6 subnet range.
|
|
119
|
+
* For simplcity, if the prefix is not on a group boundary, the entire last group is considered editable.
|
|
108
120
|
*
|
|
109
121
|
* @param cidr The CIDR notation of the subnet
|
|
110
|
-
* @returns The immutable and editable
|
|
122
|
+
* @returns The immutable and editable parts as two strings in a list
|
|
111
123
|
*/
|
|
112
124
|
exports.getImmutableAndEditableOctets = getImmutableAndEditableOctets;
|
|
125
|
+
const getImmutableAndEditableIPv6 = cidr => {
|
|
126
|
+
const [address, prefix] = cidr.split("/");
|
|
127
|
+
const prefixLength = parseInt(prefix, 10);
|
|
128
|
+
const [left = "", right = ""] = address.split("::");
|
|
129
|
+
const leftGroups = left ? left.split(":").filter(Boolean) : [];
|
|
130
|
+
const rightGroups = right ? right.split(":").filter(Boolean) : [];
|
|
131
|
+
const missingGroups = Math.max(0, 8 - (leftGroups.length + rightGroups.length));
|
|
132
|
+
const expandedGroups = [...leftGroups, ...Array(missingGroups).fill("0"), ...Array(rightGroups.length).fill("0")];
|
|
133
|
+
const immutableGroupCount = Math.floor(prefixLength / 16);
|
|
134
|
+
let immutableIPV6 = immutableGroupCount > 0 ? "".concat(expandedGroups.slice(0, immutableGroupCount).join(":")) : "";
|
|
135
|
+
if (immutableGroupCount < 8) {
|
|
136
|
+
immutableIPV6 += immutableIPV6 ? ":" : "";
|
|
137
|
+
}
|
|
138
|
+
const editableIPV6 = "".concat(expandedGroups.slice(immutableGroupCount).join(":"));
|
|
139
|
+
return [immutableIPV6, editableIPV6];
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get the immutable and editable parts of an IPv4 or IPv6 subnet.
|
|
144
|
+
*
|
|
145
|
+
* @param cidr The CIDR notation of the subnet
|
|
146
|
+
* @returns The immutable and editable as two strings in a list
|
|
147
|
+
*/
|
|
148
|
+
exports.getImmutableAndEditableIPv6 = getImmutableAndEditableIPv6;
|
|
113
149
|
const getImmutableAndEditable = cidr => {
|
|
114
150
|
const isIPV4 = isIPv4(cidr.split("/")[0]);
|
|
115
151
|
if (isIPV4) {
|
|
116
152
|
const [startIp, endIp] = getIpRangeFromCidr(cidr);
|
|
117
153
|
return getImmutableAndEditableOctets(startIp, endIp);
|
|
118
154
|
}
|
|
119
|
-
|
|
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];
|
|
155
|
+
return getImmutableAndEditableIPv6(cidr);
|
|
124
156
|
};
|
|
125
157
|
exports.getImmutableAndEditable = getImmutableAndEditable;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { FC, ReactNode } from "react";
|
|
2
|
+
import "./OutputField.scss";
|
|
3
|
+
export type Props = {
|
|
4
|
+
/**
|
|
5
|
+
* The id of the output element. This is used to associate the label with the output element for form or accessibility purposes.
|
|
6
|
+
*/
|
|
7
|
+
id: string;
|
|
8
|
+
/**
|
|
9
|
+
* The label for the output field.
|
|
10
|
+
*/
|
|
11
|
+
label: string;
|
|
12
|
+
/**
|
|
13
|
+
* The value to be displayed in the output field.
|
|
14
|
+
*/
|
|
15
|
+
value: string;
|
|
16
|
+
/**
|
|
17
|
+
* Optional help text to provide additional information about the output field.
|
|
18
|
+
*/
|
|
19
|
+
help?: ReactNode;
|
|
20
|
+
/**
|
|
21
|
+
* Whether the output field is required.
|
|
22
|
+
*/
|
|
23
|
+
required?: boolean;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* Use output fields to display read-only information with a label and optional help text. Output fields are ideal for displaying calculated values or results of user input in a consistent format.
|
|
28
|
+
*/
|
|
29
|
+
export declare const OutputField: FC<Props>;
|
|
30
|
+
export default OutputField;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import _pt from "prop-types";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import Field from "../Field";
|
|
4
|
+
import "./OutputField.scss";
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* Use output fields to display read-only information with a label and optional help text. Output fields are ideal for displaying calculated values or results of user input in a consistent format.
|
|
8
|
+
*/
|
|
9
|
+
export var OutputField = _ref => {
|
|
10
|
+
var {
|
|
11
|
+
id,
|
|
12
|
+
label,
|
|
13
|
+
value,
|
|
14
|
+
help,
|
|
15
|
+
required
|
|
16
|
+
} = _ref;
|
|
17
|
+
return /*#__PURE__*/React.createElement(Field, {
|
|
18
|
+
forId: id,
|
|
19
|
+
label: label,
|
|
20
|
+
help: help,
|
|
21
|
+
labelClassName: "u-no-margin--bottom",
|
|
22
|
+
className: "output-field",
|
|
23
|
+
required: required
|
|
24
|
+
}, /*#__PURE__*/React.createElement("output", {
|
|
25
|
+
id: id,
|
|
26
|
+
className: "mono-font u-sv2"
|
|
27
|
+
}, /*#__PURE__*/React.createElement("b", null, value)));
|
|
28
|
+
};
|
|
29
|
+
OutputField.propTypes = {
|
|
30
|
+
id: _pt.string.isRequired,
|
|
31
|
+
label: _pt.string.isRequired,
|
|
32
|
+
value: _pt.string.isRequired,
|
|
33
|
+
help: _pt.node,
|
|
34
|
+
required: _pt.bool
|
|
35
|
+
};
|
|
36
|
+
export default OutputField;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import OutputField from "./OutputField";
|
|
3
|
+
declare const meta: Meta<typeof OutputField>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof OutputField>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const HelpText: Story;
|
|
8
|
+
export declare const Required: Story;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import OutputField from "./OutputField";
|
|
2
|
+
var meta = {
|
|
3
|
+
component: OutputField,
|
|
4
|
+
tags: ["autodocs"],
|
|
5
|
+
argTypes: {
|
|
6
|
+
label: {
|
|
7
|
+
control: {
|
|
8
|
+
type: "text"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
id: {
|
|
12
|
+
control: {
|
|
13
|
+
type: "text"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
value: {
|
|
17
|
+
control: {
|
|
18
|
+
type: "text"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
help: {
|
|
22
|
+
control: {
|
|
23
|
+
type: "text"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
required: {
|
|
27
|
+
control: {
|
|
28
|
+
type: "boolean"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
args: {
|
|
33
|
+
label: "Label",
|
|
34
|
+
id: "output-field",
|
|
35
|
+
value: "Output value",
|
|
36
|
+
help: "",
|
|
37
|
+
required: false
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
export default meta;
|
|
41
|
+
export var Default = {
|
|
42
|
+
name: "Default"
|
|
43
|
+
};
|
|
44
|
+
export var HelpText = {
|
|
45
|
+
name: "Help Text",
|
|
46
|
+
args: {
|
|
47
|
+
help: "This is an output field with text"
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
export var Required = {
|
|
51
|
+
name: "Required",
|
|
52
|
+
args: {
|
|
53
|
+
required: true
|
|
54
|
+
}
|
|
55
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./OutputField";
|
|
@@ -43,7 +43,7 @@ var PrefixedIpInput = _ref => {
|
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
45
|
return /*#__PURE__*/React.createElement(PrefixedInput, _extends({
|
|
46
|
-
help: help ? help : /*#__PURE__*/React.createElement(React.Fragment, null, " ", isIPV4 ? /*#__PURE__*/React.createElement(React.Fragment, null, " ", "The available range in this subnet is", " ", /*#__PURE__*/React.createElement("code", null, immutable, ".", editable, " ")) : /*#__PURE__*/React.createElement(React.Fragment, null, " ", "The
|
|
46
|
+
help: help ? help : /*#__PURE__*/React.createElement(React.Fragment, null, " ", isIPV4 ? /*#__PURE__*/React.createElement(React.Fragment, null, " ", "The available range in this subnet is", " ", /*#__PURE__*/React.createElement("code", null, immutable, ".", editable, " ")) : /*#__PURE__*/React.createElement(React.Fragment, null, " ", "The subnet CIDR is ", /*#__PURE__*/React.createElement("code", null, cidr)), "."),
|
|
47
47
|
immutableText: isIPV4 ? "".concat(immutable, ".") : immutable,
|
|
48
48
|
maxLength: maxLength,
|
|
49
49
|
name: name,
|
|
@@ -14,6 +14,7 @@ export declare const isIPv4: (ip: string) => boolean;
|
|
|
14
14
|
export declare const getIpRangeFromCidr: (cidr: string) => string[];
|
|
15
15
|
export declare const getFirstValidIp: (ip: string) => string;
|
|
16
16
|
export declare const convertIpToUint32: (ip: string) => number;
|
|
17
|
+
export declare const convertUint32ToIp: (ipAsUint32: number) => string;
|
|
17
18
|
/**
|
|
18
19
|
* Checks if an IPv4 address is valid for the given subnet.
|
|
19
20
|
*
|
|
@@ -30,10 +31,18 @@ export declare const isIpInSubnet: (ip: string, cidr: string) => boolean;
|
|
|
30
31
|
* @returns The immutable and editable octects as two strings in a list
|
|
31
32
|
*/
|
|
32
33
|
export declare const getImmutableAndEditableOctets: (startIp: string, endIp: string) => string[];
|
|
34
|
+
/**
|
|
35
|
+
* Separates the immutable and editable parts of an IPv6 subnet range.
|
|
36
|
+
* For simplcity, if the prefix is not on a group boundary, the entire last group is considered editable.
|
|
37
|
+
*
|
|
38
|
+
* @param cidr The CIDR notation of the subnet
|
|
39
|
+
* @returns The immutable and editable parts as two strings in a list
|
|
40
|
+
*/
|
|
41
|
+
export declare const getImmutableAndEditableIPv6: (cidr: string) => string[];
|
|
33
42
|
/**
|
|
34
43
|
* Get the immutable and editable parts of an IPv4 or IPv6 subnet.
|
|
35
44
|
*
|
|
36
45
|
* @param cidr The CIDR notation of the subnet
|
|
37
|
-
* @returns The immutable and editable
|
|
46
|
+
* @returns The immutable and editable as two strings in a list
|
|
38
47
|
*/
|
|
39
48
|
export declare const getImmutableAndEditable: (cidr: string) => string[];
|
|
@@ -19,8 +19,11 @@ export var getIpRangeFromCidr = cidr => {
|
|
|
19
19
|
// https://gist.github.com/binarymax/6114792
|
|
20
20
|
|
|
21
21
|
// Get start IP and number of valid addresses
|
|
22
|
-
var [
|
|
23
|
-
var
|
|
22
|
+
var [unmaskedStartIp, mask] = cidr.split("/");
|
|
23
|
+
var maskBits = parseInt(mask, 10);
|
|
24
|
+
var subnetMask = maskBits === 0 ? 0 : 0xffffffff << 32 - maskBits >>> 0;
|
|
25
|
+
var startIp = convertUint32ToIp(convertIpToUint32(unmaskedStartIp) & subnetMask);
|
|
26
|
+
var numberOfAddresses = (1 << 32 - maskBits) - 1;
|
|
24
27
|
|
|
25
28
|
// IPv4 can be represented by an unsigned 32-bit integer, so we can use a Uint32Array to store the IP
|
|
26
29
|
var buffer = new ArrayBuffer(4); //4 octets
|
|
@@ -54,6 +57,13 @@ export var convertIpToUint32 = ip => {
|
|
|
54
57
|
int32[0] = (octets[0] << 24) + (octets[1] << 16) + (octets[2] << 8) + octets[3];
|
|
55
58
|
return int32[0];
|
|
56
59
|
};
|
|
60
|
+
export var convertUint32ToIp = ipAsUint32 => {
|
|
61
|
+
var buffer = new ArrayBuffer(4); //4 octets
|
|
62
|
+
var int32 = new Uint32Array(buffer);
|
|
63
|
+
int32[0] = ipAsUint32;
|
|
64
|
+
var octets = Array.from(new Uint8Array(buffer));
|
|
65
|
+
return octets.reverse().join(".");
|
|
66
|
+
};
|
|
57
67
|
|
|
58
68
|
/**
|
|
59
69
|
* Checks if an IPv4 address is valid for the given subnet.
|
|
@@ -92,11 +102,35 @@ export var getImmutableAndEditableOctets = (startIp, endIp) => {
|
|
|
92
102
|
return [immutable.join("."), editable.join(".")];
|
|
93
103
|
};
|
|
94
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Separates the immutable and editable parts of an IPv6 subnet range.
|
|
107
|
+
* For simplcity, if the prefix is not on a group boundary, the entire last group is considered editable.
|
|
108
|
+
*
|
|
109
|
+
* @param cidr The CIDR notation of the subnet
|
|
110
|
+
* @returns The immutable and editable parts as two strings in a list
|
|
111
|
+
*/
|
|
112
|
+
export var getImmutableAndEditableIPv6 = cidr => {
|
|
113
|
+
var [address, prefix] = cidr.split("/");
|
|
114
|
+
var prefixLength = parseInt(prefix, 10);
|
|
115
|
+
var [left = "", right = ""] = address.split("::");
|
|
116
|
+
var leftGroups = left ? left.split(":").filter(Boolean) : [];
|
|
117
|
+
var rightGroups = right ? right.split(":").filter(Boolean) : [];
|
|
118
|
+
var missingGroups = Math.max(0, 8 - (leftGroups.length + rightGroups.length));
|
|
119
|
+
var expandedGroups = [...leftGroups, ...Array(missingGroups).fill("0"), ...Array(rightGroups.length).fill("0")];
|
|
120
|
+
var immutableGroupCount = Math.floor(prefixLength / 16);
|
|
121
|
+
var immutableIPV6 = immutableGroupCount > 0 ? "".concat(expandedGroups.slice(0, immutableGroupCount).join(":")) : "";
|
|
122
|
+
if (immutableGroupCount < 8) {
|
|
123
|
+
immutableIPV6 += immutableIPV6 ? ":" : "";
|
|
124
|
+
}
|
|
125
|
+
var editableIPV6 = "".concat(expandedGroups.slice(immutableGroupCount).join(":"));
|
|
126
|
+
return [immutableIPV6, editableIPV6];
|
|
127
|
+
};
|
|
128
|
+
|
|
95
129
|
/**
|
|
96
130
|
* Get the immutable and editable parts of an IPv4 or IPv6 subnet.
|
|
97
131
|
*
|
|
98
132
|
* @param cidr The CIDR notation of the subnet
|
|
99
|
-
* @returns The immutable and editable
|
|
133
|
+
* @returns The immutable and editable as two strings in a list
|
|
100
134
|
*/
|
|
101
135
|
export var getImmutableAndEditable = cidr => {
|
|
102
136
|
var isIPV4 = isIPv4(cidr.split("/")[0]);
|
|
@@ -104,9 +138,5 @@ export var getImmutableAndEditable = cidr => {
|
|
|
104
138
|
var [startIp, endIp] = getIpRangeFromCidr(cidr);
|
|
105
139
|
return getImmutableAndEditableOctets(startIp, endIp);
|
|
106
140
|
}
|
|
107
|
-
|
|
108
|
-
var immutableIPV6 = networkAddress.substring(0, networkAddress.lastIndexOf(":"));
|
|
109
|
-
var ipv6PlaceholderColons = 7 - (immutableIPV6.match(/:/g) || []).length; // 7 is the maximum number of colons in an IPv6 address
|
|
110
|
-
var editableIPV6 = "".concat("0000:".repeat(ipv6PlaceholderColons), "0000");
|
|
111
|
-
return [immutableIPV6, editableIPV6];
|
|
141
|
+
return getImmutableAndEditableIPv6(cidr);
|
|
112
142
|
};
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ export * from "./components/MultiSelect";
|
|
|
40
40
|
export { default as Notification, NotificationSeverity, } from "./components/Notifications";
|
|
41
41
|
export { NotificationConsumer, NotificationProvider, useNotify, info, success, failure, queue, } from "./components/NotificationProvider";
|
|
42
42
|
export { default as LoginPageLayout } from "./components/LoginPageLayout";
|
|
43
|
+
export { default as OutputField } from "./components/OutputField";
|
|
43
44
|
export { default as Pagination } from "./components/Pagination";
|
|
44
45
|
export { default as Panel } from "./components/Panel";
|
|
45
46
|
export { default as PasswordToggle } from "./components/PasswordToggle";
|
|
@@ -118,6 +119,7 @@ export type { GenerateLink, LogoProps, NavigationProps, NavItem, NavLink, NavLin
|
|
|
118
119
|
export type { NotificationProps } from "./components/Notifications";
|
|
119
120
|
export type { NotificationAction, NotificationType, QueuedNotification, NotificationHelper, } from "./components/NotificationProvider";
|
|
120
121
|
export type { LoginPageLayoutProps } from "./components/LoginPageLayout";
|
|
122
|
+
export type { OutputFieldProps } from "./components/OutputField";
|
|
121
123
|
export type { PaginationProps } from "./components/Pagination";
|
|
122
124
|
export type { PanelProps } from "./components/Panel";
|
|
123
125
|
export type { PrefixedInputProps } from "./components/PrefixedInput";
|
package/dist/esm/index.js
CHANGED
|
@@ -40,6 +40,7 @@ export * from "./components/MultiSelect";
|
|
|
40
40
|
export { default as Notification, NotificationSeverity } from "./components/Notifications";
|
|
41
41
|
export { NotificationConsumer, NotificationProvider, useNotify, info, success, failure, queue } from "./components/NotificationProvider";
|
|
42
42
|
export { default as LoginPageLayout } from "./components/LoginPageLayout";
|
|
43
|
+
export { default as OutputField } from "./components/OutputField";
|
|
43
44
|
export { default as Pagination } from "./components/Pagination";
|
|
44
45
|
export { default as Panel } from "./components/Panel";
|
|
45
46
|
export { default as PasswordToggle } from "./components/PasswordToggle";
|
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ export * from "./components/MultiSelect";
|
|
|
40
40
|
export { default as Notification, NotificationSeverity, } from "./components/Notifications";
|
|
41
41
|
export { NotificationConsumer, NotificationProvider, useNotify, info, success, failure, queue, } from "./components/NotificationProvider";
|
|
42
42
|
export { default as LoginPageLayout } from "./components/LoginPageLayout";
|
|
43
|
+
export { default as OutputField } from "./components/OutputField";
|
|
43
44
|
export { default as Pagination } from "./components/Pagination";
|
|
44
45
|
export { default as Panel } from "./components/Panel";
|
|
45
46
|
export { default as PasswordToggle } from "./components/PasswordToggle";
|
|
@@ -118,6 +119,7 @@ export type { GenerateLink, LogoProps, NavigationProps, NavItem, NavLink, NavLin
|
|
|
118
119
|
export type { NotificationProps } from "./components/Notifications";
|
|
119
120
|
export type { NotificationAction, NotificationType, QueuedNotification, NotificationHelper, } from "./components/NotificationProvider";
|
|
120
121
|
export type { LoginPageLayoutProps } from "./components/LoginPageLayout";
|
|
122
|
+
export type { OutputFieldProps } from "./components/OutputField";
|
|
121
123
|
export type { PaginationProps } from "./components/Pagination";
|
|
122
124
|
export type { PanelProps } from "./components/Panel";
|
|
123
125
|
export type { PrefixedInputProps } from "./components/PrefixedInput";
|
package/dist/index.js
CHANGED
|
@@ -61,6 +61,7 @@ var _exportNames = {
|
|
|
61
61
|
failure: true,
|
|
62
62
|
queue: true,
|
|
63
63
|
LoginPageLayout: true,
|
|
64
|
+
OutputField: true,
|
|
64
65
|
Pagination: true,
|
|
65
66
|
Panel: true,
|
|
66
67
|
PasswordToggle: true,
|
|
@@ -410,6 +411,12 @@ Object.defineProperty(exports, "NotificationSeverity", {
|
|
|
410
411
|
return _Notifications.NotificationSeverity;
|
|
411
412
|
}
|
|
412
413
|
});
|
|
414
|
+
Object.defineProperty(exports, "OutputField", {
|
|
415
|
+
enumerable: true,
|
|
416
|
+
get: function () {
|
|
417
|
+
return _OutputField.default;
|
|
418
|
+
}
|
|
419
|
+
});
|
|
413
420
|
Object.defineProperty(exports, "Pagination", {
|
|
414
421
|
enumerable: true,
|
|
415
422
|
get: function () {
|
|
@@ -919,6 +926,7 @@ Object.keys(_MultiSelect).forEach(function (key) {
|
|
|
919
926
|
var _Notifications = _interopRequireWildcard(require("./components/Notifications"));
|
|
920
927
|
var _NotificationProvider = require("./components/NotificationProvider");
|
|
921
928
|
var _LoginPageLayout = _interopRequireDefault(require("./components/LoginPageLayout"));
|
|
929
|
+
var _OutputField = _interopRequireDefault(require("./components/OutputField"));
|
|
922
930
|
var _Pagination = _interopRequireDefault(require("./components/Pagination"));
|
|
923
931
|
var _Panel = _interopRequireDefault(require("./components/Panel"));
|
|
924
932
|
var _PasswordToggle = _interopRequireDefault(require("./components/PasswordToggle"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canonical/react-components",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"author": {
|
|
@@ -96,7 +96,7 @@
|
|
|
96
96
|
"tsc-alias": "1.8.10",
|
|
97
97
|
"typescript": "5.7.3",
|
|
98
98
|
"typescript-eslint": "8.24.1",
|
|
99
|
-
"vanilla-framework": "4.
|
|
99
|
+
"vanilla-framework": "4.48.0",
|
|
100
100
|
"wait-on": "9.0.3",
|
|
101
101
|
"webpack": "5.105.0"
|
|
102
102
|
},
|