@canonical/react-components 4.3.0 → 4.4.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.
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import type { ReactNode } from "react";
3
+ import { ColSize } from "../Col";
3
4
  import type { ClassName } from "../../types";
4
5
  /**
5
6
  * The props for the Field component.
@@ -33,6 +34,10 @@ export type Props = {
33
34
  * Optional class(es) to pass to the help text element.
34
35
  */
35
36
  helpClassName?: string;
37
+ /**
38
+ * Whether the help should appear after the label (by default it will appear below the field).
39
+ */
40
+ helpAfterLabel?: boolean;
36
41
  /**
37
42
  * An id to give to the help element.
38
43
  */
@@ -65,6 +70,14 @@ export type Props = {
65
70
  * Whether the form field should have a stacked appearance.
66
71
  */
67
72
  stacked?: boolean;
73
+ /**
74
+ * The number of columns the field should have when stacked.
75
+ */
76
+ stackedFieldColumns?: ColSize;
77
+ /**
78
+ * The number of columns the label should have when stacked.
79
+ */
80
+ stackedLabelColumns?: ColSize;
68
81
  /**
69
82
  * The content for success validation.
70
83
  */
@@ -74,5 +87,5 @@ export type Props = {
74
87
  */
75
88
  validationId?: string;
76
89
  };
77
- declare const Field: ({ caution, children, className, error, forId, help, helpClassName, helpId, isSelect, isTickElement, label, labelClassName, labelFirst, required, stacked, success, validationId, ...props }: Props) => React.JSX.Element;
90
+ declare const Field: ({ caution, children, className, error, forId, help, helpClassName, helpAfterLabel, helpId, isSelect, isTickElement, label, labelClassName, labelFirst, required, stacked, stackedFieldColumns, stackedLabelColumns, success, validationId, ...props }: Props) => React.JSX.Element;
78
91
  export default Field;
@@ -8,7 +8,7 @@ var _classnames = _interopRequireDefault(require("classnames"));
8
8
  var _react = _interopRequireDefault(require("react"));
9
9
  var _Label = _interopRequireDefault(require("../Label"));
10
10
  var _Col = _interopRequireDefault(require("../Col"));
11
- const _excluded = ["caution", "children", "className", "error", "forId", "help", "helpClassName", "helpId", "isSelect", "isTickElement", "label", "labelClassName", "labelFirst", "required", "stacked", "success", "validationId"];
11
+ const _excluded = ["caution", "children", "className", "error", "forId", "help", "helpClassName", "helpAfterLabel", "helpId", "isSelect", "isTickElement", "label", "labelClassName", "labelFirst", "required", "stacked", "stackedFieldColumns", "stackedLabelColumns", "success", "validationId"];
12
12
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
13
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
14
14
  function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
@@ -40,18 +40,18 @@ const generateError = (error, caution, success, validationId) => {
40
40
  id: validationId
41
41
  }, error || caution || success);
42
42
  };
43
- const generateLabel = (forId, required, label, labelClassName, stacked) => {
43
+ const generateLabel = (forId, required, label, labelClassName, stacked, stackedLabelColumns, help, helpAfterLabel) => {
44
44
  if (!label) {
45
45
  return null;
46
46
  }
47
- const labelNode = /*#__PURE__*/_react.default.createElement(_Label.default, {
47
+ const labelNode = /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_Label.default, {
48
48
  className: labelClassName,
49
49
  forId: forId,
50
50
  required: required
51
- }, label);
51
+ }, label), helpAfterLabel ? help : null);
52
52
  if (stacked) {
53
53
  return /*#__PURE__*/_react.default.createElement(_Col.default, {
54
- size: 4
54
+ size: stackedLabelColumns
55
55
  }, labelNode);
56
56
  }
57
57
  return labelNode;
@@ -63,24 +63,17 @@ const generateContent = _ref2 => {
63
63
  labelFirst,
64
64
  labelNode,
65
65
  help,
66
- helpClassName,
67
66
  error,
68
67
  caution,
69
68
  success,
70
69
  validationId,
71
- helpId,
72
- isTickElement
70
+ helpAfterLabel
73
71
  } = _ref2;
74
72
  return /*#__PURE__*/_react.default.createElement("div", {
75
73
  className: "p-form__control u-clearfix"
76
74
  }, isSelect ? /*#__PURE__*/_react.default.createElement("div", {
77
75
  className: "p-form-validation__select-wrapper"
78
- }, children) : children, !labelFirst && labelNode, generateHelpText({
79
- helpId,
80
- help,
81
- helpClassName,
82
- isTickElement
83
- }), generateError(error, caution, success, validationId));
76
+ }, children) : children, !labelFirst && labelNode, helpAfterLabel ? null : help, generateError(error, caution, success, validationId));
84
77
  };
85
78
  const Field = _ref3 => {
86
79
  let {
@@ -91,6 +84,7 @@ const Field = _ref3 => {
91
84
  forId,
92
85
  help,
93
86
  helpClassName,
87
+ helpAfterLabel,
94
88
  helpId,
95
89
  isSelect,
96
90
  isTickElement,
@@ -99,24 +93,30 @@ const Field = _ref3 => {
99
93
  labelFirst = true,
100
94
  required,
101
95
  stacked,
96
+ stackedFieldColumns = 8,
97
+ stackedLabelColumns = 4,
102
98
  success,
103
99
  validationId
104
100
  } = _ref3,
105
101
  props = _objectWithoutProperties(_ref3, _excluded);
106
- const labelNode = generateLabel(forId, required, label, labelClassName, stacked);
102
+ const helpNode = generateHelpText({
103
+ helpId,
104
+ help,
105
+ helpClassName,
106
+ isTickElement
107
+ });
108
+ const labelNode = generateLabel(forId, required, label, labelClassName, stacked, stackedLabelColumns, helpNode, helpAfterLabel);
107
109
  const content = generateContent({
108
110
  isSelect,
109
- isTickElement,
110
111
  children,
111
112
  labelFirst,
112
113
  labelNode,
113
- help,
114
- helpClassName,
114
+ help: helpNode,
115
115
  error,
116
116
  caution,
117
117
  success,
118
118
  validationId,
119
- helpId
119
+ helpAfterLabel
120
120
  });
121
121
  return /*#__PURE__*/_react.default.createElement("div", _extends({
122
122
  className: (0, _classnames.default)("p-form__group", "p-form-validation", className, {
@@ -126,7 +126,7 @@ const Field = _ref3 => {
126
126
  row: stacked
127
127
  })
128
128
  }, props), labelFirst && labelNode, stacked ? /*#__PURE__*/_react.default.createElement(_Col.default, {
129
- size: 8
129
+ size: stackedFieldColumns
130
130
  }, content) : content);
131
131
  };
132
132
  var _default = exports.default = Field;
@@ -22,5 +22,5 @@ export type Props<C extends ElementType | ComponentType = typeof Input> = {
22
22
  * makes use of Formik's context to automatically map errors, values, states
23
23
  * etc. onto the provided field.
24
24
  */
25
- declare const FormikField: <C extends ElementType | ComponentType = ({ caution, className, error, help, helpClassName, id, label, labelClassName, required, stacked, success, takeFocus, takeFocusDelay, type, wrapperClassName, ...inputProps }: import("../Input").InputProps) => React.JSX.Element>({ component: Component, displayError, name, value, label, ...props }: Props<C>) => React.JSX.Element;
25
+ declare const FormikField: <C extends ElementType | ComponentType = ({ caution, className, error, help, helpAfterLabel, helpClassName, id, label, labelClassName, required, stacked, stackedFieldColumns, stackedLabelColumns, success, takeFocus, takeFocusDelay, type, wrapperClassName, ...inputProps }: import("../Input").InputProps) => React.JSX.Element>({ component: Component, displayError, name, value, label, ...props }: Props<C>) => React.JSX.Element;
26
26
  export default FormikField;
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import type { InputHTMLAttributes, ReactNode } from "react";
3
3
  import type { ClassName, PropsWithSpread } from "../../types";
4
+ import { ColSize } from "../Col";
4
5
  /**
5
6
  * The props for the Input component.
6
7
  */
@@ -29,6 +30,10 @@ export type Props = PropsWithSpread<{
29
30
  * The id of the input.
30
31
  */
31
32
  id?: string;
33
+ /**
34
+ * Whether the help should appear after the label (by default it will appear below the field).
35
+ */
36
+ helpAfterLabel?: boolean;
32
37
  /**
33
38
  * The label for the field.
34
39
  */
@@ -45,6 +50,14 @@ export type Props = PropsWithSpread<{
45
50
  * Whether the form field should have a stacked appearance.
46
51
  */
47
52
  stacked?: boolean;
53
+ /**
54
+ * The number of columns the field should have when stacked.
55
+ */
56
+ stackedFieldColumns?: ColSize;
57
+ /**
58
+ * The number of columns the label should have when stacked.
59
+ */
60
+ stackedLabelColumns?: ColSize;
48
61
  /**
49
62
  * The content for success validation.
50
63
  */
@@ -67,5 +80,5 @@ export type Props = PropsWithSpread<{
67
80
  *
68
81
  * An input field where the user can enter data, which can vary in many ways, depending on the type attribute.
69
82
  */
70
- declare const Input: ({ caution, className, error, help, helpClassName, id, label, labelClassName, required, stacked, success, takeFocus, takeFocusDelay, type, wrapperClassName, ...inputProps }: Props) => React.JSX.Element;
83
+ declare const Input: ({ caution, className, error, help, helpAfterLabel, helpClassName, id, label, labelClassName, required, stacked, stackedFieldColumns, stackedLabelColumns, success, takeFocus, takeFocusDelay, type, wrapperClassName, ...inputProps }: Props) => React.JSX.Element;
71
84
  export default Input;
@@ -9,7 +9,7 @@ var _react = _interopRequireWildcard(require("react"));
9
9
  var _Field = _interopRequireDefault(require("../Field"));
10
10
  var _CheckboxInput = _interopRequireDefault(require("../CheckboxInput"));
11
11
  var _RadioInput = _interopRequireDefault(require("../RadioInput"));
12
- const _excluded = ["caution", "className", "error", "help", "helpClassName", "id", "label", "labelClassName", "required", "stacked", "success", "takeFocus", "takeFocusDelay", "type", "wrapperClassName"];
12
+ const _excluded = ["caution", "className", "error", "help", "helpAfterLabel", "helpClassName", "id", "label", "labelClassName", "required", "stacked", "stackedFieldColumns", "stackedLabelColumns", "success", "takeFocus", "takeFocusDelay", "type", "wrapperClassName"];
13
13
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
14
14
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
15
15
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
@@ -35,12 +35,15 @@ const Input = _ref => {
35
35
  className,
36
36
  error,
37
37
  help,
38
+ helpAfterLabel,
38
39
  helpClassName,
39
40
  id,
40
41
  label,
41
42
  labelClassName,
42
43
  required,
43
44
  stacked,
45
+ stackedFieldColumns,
46
+ stackedLabelColumns,
44
47
  success,
45
48
  takeFocus,
46
49
  takeFocusDelay,
@@ -96,6 +99,7 @@ const Input = _ref => {
96
99
  error: error,
97
100
  forId: inputId,
98
101
  help: help,
102
+ helpAfterLabel: helpAfterLabel,
99
103
  helpClassName: helpClassName,
100
104
  helpId: helpId,
101
105
  isTickElement: type === "checkbox" || type === "radio",
@@ -103,6 +107,8 @@ const Input = _ref => {
103
107
  labelClassName: labelClassName,
104
108
  required: required,
105
109
  stacked: stacked,
110
+ stackedFieldColumns: stackedFieldColumns,
111
+ stackedLabelColumns: stackedLabelColumns,
106
112
  success: success,
107
113
  validationId: validationId
108
114
  }, input);
@@ -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 available IPV6 address range is", " ", /*#__PURE__*/_react.default.createElement("code", null, immutable, editable, " ")), "."),
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 as two strings in a list
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 [startIp, mask] = cidr.split("/");
30
- const numberOfAddresses = (1 << 32 - parseInt(mask)) - 1;
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.convertIpToUint32 = convertIpToUint32;
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
- * Get the immutable and editable parts of an IPv4 or IPv6 subnet.
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 as two strings in a list
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
- 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];
155
+ return getImmutableAndEditableIPv6(cidr);
124
156
  };
125
157
  exports.getImmutableAndEditable = getImmutableAndEditable;
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import type { ChangeEventHandler, ReactNode, OptionHTMLAttributes, SelectHTMLAttributes } from "react";
3
3
  import type { ClassName, PropsWithSpread } from "../../types";
4
+ import { ColSize } from "../Col";
4
5
  type Option = OptionHTMLAttributes<HTMLOptionElement>;
5
6
  /**
6
7
  * The props for the Select component.
@@ -22,6 +23,10 @@ export type Props = PropsWithSpread<{
22
23
  * Help text to show below the field.
23
24
  */
24
25
  help?: ReactNode;
26
+ /**
27
+ * Whether the help should appear after the label (by default it will appear below the field).
28
+ */
29
+ helpAfterLabel?: boolean;
25
30
  /**
26
31
  * Optional class(es) to pass to the help text element.
27
32
  */
@@ -54,6 +59,14 @@ export type Props = PropsWithSpread<{
54
59
  * Whether the form field should have a stacked appearance.
55
60
  */
56
61
  stacked?: boolean;
62
+ /**
63
+ * The number of columns the field should have when stacked.
64
+ */
65
+ stackedFieldColumns?: ColSize;
66
+ /**
67
+ * The number of columns the label should have when stacked.
68
+ */
69
+ stackedLabelColumns?: ColSize;
57
70
  /**
58
71
  * The content for success validation.
59
72
  */
@@ -72,5 +85,5 @@ export type Props = PropsWithSpread<{
72
85
  *
73
86
  * Use the Select component to create a drop-down list.
74
87
  */
75
- declare const Select: ({ caution, className, error, help, helpClassName, id, label, labelClassName, onChange, options, required, stacked, success, takeFocus, wrapperClassName, ...selectProps }: Props) => React.JSX.Element;
88
+ declare const Select: ({ caution, className, error, help, helpAfterLabel, helpClassName, id, label, labelClassName, onChange, options, required, stacked, stackedFieldColumns, stackedLabelColumns, success, takeFocus, wrapperClassName, ...selectProps }: Props) => React.JSX.Element;
76
89
  export default Select;
@@ -8,7 +8,7 @@ var _classnames = _interopRequireDefault(require("classnames"));
8
8
  var _react = _interopRequireWildcard(require("react"));
9
9
  var _Field = _interopRequireDefault(require("../Field"));
10
10
  const _excluded = ["label", "value"],
11
- _excluded2 = ["caution", "className", "error", "help", "helpClassName", "id", "label", "labelClassName", "onChange", "options", "required", "stacked", "success", "takeFocus", "wrapperClassName"];
11
+ _excluded2 = ["caution", "className", "error", "help", "helpAfterLabel", "helpClassName", "id", "label", "labelClassName", "onChange", "options", "required", "stacked", "stackedFieldColumns", "stackedLabelColumns", "success", "takeFocus", "wrapperClassName"];
12
12
  function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
14
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
@@ -41,6 +41,7 @@ const Select = _ref2 => {
41
41
  className,
42
42
  error,
43
43
  help,
44
+ helpAfterLabel,
44
45
  helpClassName,
45
46
  id,
46
47
  label,
@@ -49,6 +50,8 @@ const Select = _ref2 => {
49
50
  options,
50
51
  required,
51
52
  stacked,
53
+ stackedFieldColumns,
54
+ stackedLabelColumns,
52
55
  success,
53
56
  takeFocus,
54
57
  wrapperClassName
@@ -71,6 +74,7 @@ const Select = _ref2 => {
71
74
  error: error,
72
75
  forId: selectId,
73
76
  help: help,
77
+ helpAfterLabel: helpAfterLabel,
74
78
  helpClassName: helpClassName,
75
79
  helpId: helpId,
76
80
  isSelect: true,
@@ -78,6 +82,8 @@ const Select = _ref2 => {
78
82
  labelClassName: labelClassName,
79
83
  required: required,
80
84
  stacked: stacked,
85
+ stackedFieldColumns: stackedFieldColumns,
86
+ stackedLabelColumns: stackedLabelColumns,
81
87
  success: success,
82
88
  validationId: validationId
83
89
  }, /*#__PURE__*/_react.default.createElement("select", _extends({
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import type { ReactNode } from "react";
3
+ import { ColSize } from "../Col";
3
4
  import type { ClassName } from "../../types";
4
5
  /**
5
6
  * The props for the Field component.
@@ -33,6 +34,10 @@ export type Props = {
33
34
  * Optional class(es) to pass to the help text element.
34
35
  */
35
36
  helpClassName?: string;
37
+ /**
38
+ * Whether the help should appear after the label (by default it will appear below the field).
39
+ */
40
+ helpAfterLabel?: boolean;
36
41
  /**
37
42
  * An id to give to the help element.
38
43
  */
@@ -65,6 +70,14 @@ export type Props = {
65
70
  * Whether the form field should have a stacked appearance.
66
71
  */
67
72
  stacked?: boolean;
73
+ /**
74
+ * The number of columns the field should have when stacked.
75
+ */
76
+ stackedFieldColumns?: ColSize;
77
+ /**
78
+ * The number of columns the label should have when stacked.
79
+ */
80
+ stackedLabelColumns?: ColSize;
68
81
  /**
69
82
  * The content for success validation.
70
83
  */
@@ -74,5 +87,5 @@ export type Props = {
74
87
  */
75
88
  validationId?: string;
76
89
  };
77
- declare const Field: ({ caution, children, className, error, forId, help, helpClassName, helpId, isSelect, isTickElement, label, labelClassName, labelFirst, required, stacked, success, validationId, ...props }: Props) => React.JSX.Element;
90
+ declare const Field: ({ caution, children, className, error, forId, help, helpClassName, helpAfterLabel, helpId, isSelect, isTickElement, label, labelClassName, labelFirst, required, stacked, stackedFieldColumns, stackedLabelColumns, success, validationId, ...props }: Props) => React.JSX.Element;
78
91
  export default Field;
@@ -1,4 +1,4 @@
1
- var _excluded = ["caution", "children", "className", "error", "forId", "help", "helpClassName", "helpId", "isSelect", "isTickElement", "label", "labelClassName", "labelFirst", "required", "stacked", "success", "validationId"];
1
+ var _excluded = ["caution", "children", "className", "error", "forId", "help", "helpClassName", "helpAfterLabel", "helpId", "isSelect", "isTickElement", "label", "labelClassName", "labelFirst", "required", "stacked", "stackedFieldColumns", "stackedLabelColumns", "success", "validationId"];
2
2
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
3
  function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
4
4
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
@@ -34,18 +34,18 @@ var generateError = (error, caution, success, validationId) => {
34
34
  id: validationId
35
35
  }, error || caution || success);
36
36
  };
37
- var generateLabel = (forId, required, label, labelClassName, stacked) => {
37
+ var generateLabel = (forId, required, label, labelClassName, stacked, stackedLabelColumns, help, helpAfterLabel) => {
38
38
  if (!label) {
39
39
  return null;
40
40
  }
41
- var labelNode = /*#__PURE__*/React.createElement(Label, {
41
+ var labelNode = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Label, {
42
42
  className: labelClassName,
43
43
  forId: forId,
44
44
  required: required
45
- }, label);
45
+ }, label), helpAfterLabel ? help : null);
46
46
  if (stacked) {
47
47
  return /*#__PURE__*/React.createElement(Col, {
48
- size: 4
48
+ size: stackedLabelColumns
49
49
  }, labelNode);
50
50
  }
51
51
  return labelNode;
@@ -57,24 +57,17 @@ var generateContent = _ref2 => {
57
57
  labelFirst,
58
58
  labelNode,
59
59
  help,
60
- helpClassName,
61
60
  error,
62
61
  caution,
63
62
  success,
64
63
  validationId,
65
- helpId,
66
- isTickElement
64
+ helpAfterLabel
67
65
  } = _ref2;
68
66
  return /*#__PURE__*/React.createElement("div", {
69
67
  className: "p-form__control u-clearfix"
70
68
  }, isSelect ? /*#__PURE__*/React.createElement("div", {
71
69
  className: "p-form-validation__select-wrapper"
72
- }, children) : children, !labelFirst && labelNode, generateHelpText({
73
- helpId,
74
- help,
75
- helpClassName,
76
- isTickElement
77
- }), generateError(error, caution, success, validationId));
70
+ }, children) : children, !labelFirst && labelNode, helpAfterLabel ? null : help, generateError(error, caution, success, validationId));
78
71
  };
79
72
  var Field = _ref3 => {
80
73
  var {
@@ -85,6 +78,7 @@ var Field = _ref3 => {
85
78
  forId,
86
79
  help,
87
80
  helpClassName,
81
+ helpAfterLabel,
88
82
  helpId,
89
83
  isSelect,
90
84
  isTickElement,
@@ -93,24 +87,30 @@ var Field = _ref3 => {
93
87
  labelFirst = true,
94
88
  required,
95
89
  stacked,
90
+ stackedFieldColumns = 8,
91
+ stackedLabelColumns = 4,
96
92
  success,
97
93
  validationId
98
94
  } = _ref3,
99
95
  props = _objectWithoutProperties(_ref3, _excluded);
100
- var labelNode = generateLabel(forId, required, label, labelClassName, stacked);
96
+ var helpNode = generateHelpText({
97
+ helpId,
98
+ help,
99
+ helpClassName,
100
+ isTickElement
101
+ });
102
+ var labelNode = generateLabel(forId, required, label, labelClassName, stacked, stackedLabelColumns, helpNode, helpAfterLabel);
101
103
  var content = generateContent({
102
104
  isSelect,
103
- isTickElement,
104
105
  children,
105
106
  labelFirst,
106
107
  labelNode,
107
- help,
108
- helpClassName,
108
+ help: helpNode,
109
109
  error,
110
110
  caution,
111
111
  success,
112
112
  validationId,
113
- helpId
113
+ helpAfterLabel
114
114
  });
115
115
  return /*#__PURE__*/React.createElement("div", _extends({
116
116
  className: classNames("p-form__group", "p-form-validation", className, {
@@ -120,7 +120,7 @@ var Field = _ref3 => {
120
120
  row: stacked
121
121
  })
122
122
  }, props), labelFirst && labelNode, stacked ? /*#__PURE__*/React.createElement(Col, {
123
- size: 8
123
+ size: stackedFieldColumns
124
124
  }, content) : content);
125
125
  };
126
126
  export default Field;
@@ -22,5 +22,5 @@ export type Props<C extends ElementType | ComponentType = typeof Input> = {
22
22
  * makes use of Formik's context to automatically map errors, values, states
23
23
  * etc. onto the provided field.
24
24
  */
25
- declare const FormikField: <C extends ElementType | ComponentType = ({ caution, className, error, help, helpClassName, id, label, labelClassName, required, stacked, success, takeFocus, takeFocusDelay, type, wrapperClassName, ...inputProps }: import("../Input").InputProps) => React.JSX.Element>({ component: Component, displayError, name, value, label, ...props }: Props<C>) => React.JSX.Element;
25
+ declare const FormikField: <C extends ElementType | ComponentType = ({ caution, className, error, help, helpAfterLabel, helpClassName, id, label, labelClassName, required, stacked, stackedFieldColumns, stackedLabelColumns, success, takeFocus, takeFocusDelay, type, wrapperClassName, ...inputProps }: import("../Input").InputProps) => React.JSX.Element>({ component: Component, displayError, name, value, label, ...props }: Props<C>) => React.JSX.Element;
26
26
  export default FormikField;
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import type { InputHTMLAttributes, ReactNode } from "react";
3
3
  import type { ClassName, PropsWithSpread } from "../../types";
4
+ import { ColSize } from "../Col";
4
5
  /**
5
6
  * The props for the Input component.
6
7
  */
@@ -29,6 +30,10 @@ export type Props = PropsWithSpread<{
29
30
  * The id of the input.
30
31
  */
31
32
  id?: string;
33
+ /**
34
+ * Whether the help should appear after the label (by default it will appear below the field).
35
+ */
36
+ helpAfterLabel?: boolean;
32
37
  /**
33
38
  * The label for the field.
34
39
  */
@@ -45,6 +50,14 @@ export type Props = PropsWithSpread<{
45
50
  * Whether the form field should have a stacked appearance.
46
51
  */
47
52
  stacked?: boolean;
53
+ /**
54
+ * The number of columns the field should have when stacked.
55
+ */
56
+ stackedFieldColumns?: ColSize;
57
+ /**
58
+ * The number of columns the label should have when stacked.
59
+ */
60
+ stackedLabelColumns?: ColSize;
48
61
  /**
49
62
  * The content for success validation.
50
63
  */
@@ -67,5 +80,5 @@ export type Props = PropsWithSpread<{
67
80
  *
68
81
  * An input field where the user can enter data, which can vary in many ways, depending on the type attribute.
69
82
  */
70
- declare const Input: ({ caution, className, error, help, helpClassName, id, label, labelClassName, required, stacked, success, takeFocus, takeFocusDelay, type, wrapperClassName, ...inputProps }: Props) => React.JSX.Element;
83
+ declare const Input: ({ caution, className, error, help, helpAfterLabel, helpClassName, id, label, labelClassName, required, stacked, stackedFieldColumns, stackedLabelColumns, success, takeFocus, takeFocusDelay, type, wrapperClassName, ...inputProps }: Props) => React.JSX.Element;
71
84
  export default Input;
@@ -1,4 +1,4 @@
1
- var _excluded = ["caution", "className", "error", "help", "helpClassName", "id", "label", "labelClassName", "required", "stacked", "success", "takeFocus", "takeFocusDelay", "type", "wrapperClassName"];
1
+ var _excluded = ["caution", "className", "error", "help", "helpAfterLabel", "helpClassName", "id", "label", "labelClassName", "required", "stacked", "stackedFieldColumns", "stackedLabelColumns", "success", "takeFocus", "takeFocusDelay", "type", "wrapperClassName"];
2
2
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
3
3
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
4
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
@@ -28,12 +28,15 @@ var Input = _ref => {
28
28
  className,
29
29
  error,
30
30
  help,
31
+ helpAfterLabel,
31
32
  helpClassName,
32
33
  id,
33
34
  label,
34
35
  labelClassName,
35
36
  required,
36
37
  stacked,
38
+ stackedFieldColumns,
39
+ stackedLabelColumns,
37
40
  success,
38
41
  takeFocus,
39
42
  takeFocusDelay,
@@ -89,6 +92,7 @@ var Input = _ref => {
89
92
  error: error,
90
93
  forId: inputId,
91
94
  help: help,
95
+ helpAfterLabel: helpAfterLabel,
92
96
  helpClassName: helpClassName,
93
97
  helpId: helpId,
94
98
  isTickElement: type === "checkbox" || type === "radio",
@@ -96,6 +100,8 @@ var Input = _ref => {
96
100
  labelClassName: labelClassName,
97
101
  required: required,
98
102
  stacked: stacked,
103
+ stackedFieldColumns: stackedFieldColumns,
104
+ stackedLabelColumns: stackedLabelColumns,
99
105
  success: success,
100
106
  validationId: validationId
101
107
  }, input);
@@ -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 available IPV6 address range is", " ", /*#__PURE__*/React.createElement("code", null, immutable, editable, " ")), "."),
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 as two strings in a list
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 [startIp, mask] = cidr.split("/");
23
- var numberOfAddresses = (1 << 32 - parseInt(mask)) - 1;
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 as two strings in a list
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
- var [networkAddress] = cidr.split("/");
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
  };
@@ -1,6 +1,7 @@
1
1
  import React from "react";
2
2
  import type { ChangeEventHandler, ReactNode, OptionHTMLAttributes, SelectHTMLAttributes } from "react";
3
3
  import type { ClassName, PropsWithSpread } from "../../types";
4
+ import { ColSize } from "../Col";
4
5
  type Option = OptionHTMLAttributes<HTMLOptionElement>;
5
6
  /**
6
7
  * The props for the Select component.
@@ -22,6 +23,10 @@ export type Props = PropsWithSpread<{
22
23
  * Help text to show below the field.
23
24
  */
24
25
  help?: ReactNode;
26
+ /**
27
+ * Whether the help should appear after the label (by default it will appear below the field).
28
+ */
29
+ helpAfterLabel?: boolean;
25
30
  /**
26
31
  * Optional class(es) to pass to the help text element.
27
32
  */
@@ -54,6 +59,14 @@ export type Props = PropsWithSpread<{
54
59
  * Whether the form field should have a stacked appearance.
55
60
  */
56
61
  stacked?: boolean;
62
+ /**
63
+ * The number of columns the field should have when stacked.
64
+ */
65
+ stackedFieldColumns?: ColSize;
66
+ /**
67
+ * The number of columns the label should have when stacked.
68
+ */
69
+ stackedLabelColumns?: ColSize;
57
70
  /**
58
71
  * The content for success validation.
59
72
  */
@@ -72,5 +85,5 @@ export type Props = PropsWithSpread<{
72
85
  *
73
86
  * Use the Select component to create a drop-down list.
74
87
  */
75
- declare const Select: ({ caution, className, error, help, helpClassName, id, label, labelClassName, onChange, options, required, stacked, success, takeFocus, wrapperClassName, ...selectProps }: Props) => React.JSX.Element;
88
+ declare const Select: ({ caution, className, error, help, helpAfterLabel, helpClassName, id, label, labelClassName, onChange, options, required, stacked, stackedFieldColumns, stackedLabelColumns, success, takeFocus, wrapperClassName, ...selectProps }: Props) => React.JSX.Element;
76
89
  export default Select;
@@ -1,5 +1,5 @@
1
1
  var _excluded = ["label", "value"],
2
- _excluded2 = ["caution", "className", "error", "help", "helpClassName", "id", "label", "labelClassName", "onChange", "options", "required", "stacked", "success", "takeFocus", "wrapperClassName"];
2
+ _excluded2 = ["caution", "className", "error", "help", "helpAfterLabel", "helpClassName", "id", "label", "labelClassName", "onChange", "options", "required", "stacked", "stackedFieldColumns", "stackedLabelColumns", "success", "takeFocus", "wrapperClassName"];
3
3
  function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
4
4
  function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
5
5
  function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
@@ -34,6 +34,7 @@ var Select = _ref2 => {
34
34
  className,
35
35
  error,
36
36
  help,
37
+ helpAfterLabel,
37
38
  helpClassName,
38
39
  id,
39
40
  label,
@@ -42,6 +43,8 @@ var Select = _ref2 => {
42
43
  options,
43
44
  required,
44
45
  stacked,
46
+ stackedFieldColumns,
47
+ stackedLabelColumns,
45
48
  success,
46
49
  takeFocus,
47
50
  wrapperClassName
@@ -64,6 +67,7 @@ var Select = _ref2 => {
64
67
  error: error,
65
68
  forId: selectId,
66
69
  help: help,
70
+ helpAfterLabel: helpAfterLabel,
67
71
  helpClassName: helpClassName,
68
72
  helpId: helpId,
69
73
  isSelect: true,
@@ -71,6 +75,8 @@ var Select = _ref2 => {
71
75
  labelClassName: labelClassName,
72
76
  required: required,
73
77
  stacked: stacked,
78
+ stackedFieldColumns: stackedFieldColumns,
79
+ stackedLabelColumns: stackedLabelColumns,
74
80
  success: success,
75
81
  validationId: validationId
76
82
  }, /*#__PURE__*/React.createElement("select", _extends({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonical/react-components",
3
- "version": "4.3.0",
3
+ "version": "4.4.0",
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.48.0",
99
+ "vanilla-framework": "4.50.0",
100
100
  "wait-on": "9.0.3",
101
101
  "webpack": "5.105.0"
102
102
  },