@photonix/basic 3.9.0 → 4.1.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/index.css +25 -3
- package/dist/index.d.mts +78 -1
- package/dist/index.d.ts +78 -1
- package/dist/index.js +892 -267
- package/dist/index.mjs +902 -277
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -6768,7 +6768,7 @@ var Switch = React233.forwardRef(
|
|
|
6768
6768
|
Switch.displayName = "Switch";
|
|
6769
6769
|
|
|
6770
6770
|
// ../ultimate/src/components/text-field/TextField.tsx
|
|
6771
|
-
var
|
|
6771
|
+
var React240 = __toESM(require("react"));
|
|
6772
6772
|
var import_react_dom2 = require("react-dom");
|
|
6773
6773
|
|
|
6774
6774
|
// ../ultimate/src/components/divider/Divider.tsx
|
|
@@ -6809,11 +6809,613 @@ var Divider = React234.forwardRef(
|
|
|
6809
6809
|
);
|
|
6810
6810
|
Divider.displayName = "Divider";
|
|
6811
6811
|
|
|
6812
|
+
// ../ultimate/src/hooks/useNumberSuggestions.ts
|
|
6813
|
+
var React235 = __toESM(require("react"));
|
|
6814
|
+
|
|
6815
|
+
// ../ultimate/src/utils/format.utils.ts
|
|
6816
|
+
var formatCurrency = (value, separator = ",", allowDecimal = true, maxDecimals = 2) => {
|
|
6817
|
+
if (!value) return "";
|
|
6818
|
+
const decimalChar = separator === "," ? "." : ",";
|
|
6819
|
+
let cleaned = value.replace(new RegExp(`[^\\d\\${decimalChar}-]`, "g"), "");
|
|
6820
|
+
const isNegative = cleaned.startsWith("-");
|
|
6821
|
+
cleaned = cleaned.replace(/-/g, "");
|
|
6822
|
+
const parts = cleaned.split(decimalChar);
|
|
6823
|
+
let integerPart = parts[0] ?? "";
|
|
6824
|
+
const decimalPart = parts[1];
|
|
6825
|
+
integerPart = integerPart.replace(/^0+(?=\d)/, "");
|
|
6826
|
+
if (integerPart === "") integerPart = "0";
|
|
6827
|
+
integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
|
|
6828
|
+
let result = integerPart;
|
|
6829
|
+
if (allowDecimal && decimalPart !== void 0) {
|
|
6830
|
+
result += decimalChar + decimalPart.slice(0, maxDecimals);
|
|
6831
|
+
}
|
|
6832
|
+
if (isNegative && result !== "0") {
|
|
6833
|
+
result = "-" + result;
|
|
6834
|
+
}
|
|
6835
|
+
return result;
|
|
6836
|
+
};
|
|
6837
|
+
var VN_CALLING_CODE = "84";
|
|
6838
|
+
var E164_MAX_DIGITS = 15;
|
|
6839
|
+
var chunkDigits = (digits, sizes) => {
|
|
6840
|
+
const groups = [];
|
|
6841
|
+
let index = 0;
|
|
6842
|
+
for (const size of sizes) {
|
|
6843
|
+
if (index >= digits.length) break;
|
|
6844
|
+
groups.push(digits.slice(index, index + size));
|
|
6845
|
+
index += size;
|
|
6846
|
+
}
|
|
6847
|
+
return groups;
|
|
6848
|
+
};
|
|
6849
|
+
var genericPhoneGroups = (length) => {
|
|
6850
|
+
if (length <= 5) return [length];
|
|
6851
|
+
const threes = Math.floor(length / 3);
|
|
6852
|
+
switch (length % 3) {
|
|
6853
|
+
case 0:
|
|
6854
|
+
return Array(threes).fill(3);
|
|
6855
|
+
case 1:
|
|
6856
|
+
return [...Array(threes - 1).fill(3), 4];
|
|
6857
|
+
default:
|
|
6858
|
+
return [...Array(threes - 2).fill(3), 4, 4];
|
|
6859
|
+
}
|
|
6860
|
+
};
|
|
6861
|
+
var groupNationalNumber = (nsn, callingCode) => {
|
|
6862
|
+
if (callingCode === VN_CALLING_CODE) {
|
|
6863
|
+
if (/^[35789]/.test(nsn)) return chunkDigits(nsn.slice(0, 9), [3, 3, 3]);
|
|
6864
|
+
if (/^2[48]/.test(nsn)) return chunkDigits(nsn.slice(0, 10), [2, 4, 4]);
|
|
6865
|
+
if (nsn.startsWith("2")) return chunkDigits(nsn.slice(0, 10), [3, 3, 4]);
|
|
6866
|
+
}
|
|
6867
|
+
const capped = nsn.slice(0, E164_MAX_DIGITS - callingCode.length);
|
|
6868
|
+
return chunkDigits(capped, genericPhoneGroups(capped.length));
|
|
6869
|
+
};
|
|
6870
|
+
var parsePhone = (value, options = {}) => {
|
|
6871
|
+
const trimmed = value.trim();
|
|
6872
|
+
let digits = trimmed.replace(/\D/g, "");
|
|
6873
|
+
let hasPlus = trimmed.startsWith("+");
|
|
6874
|
+
if (!hasPlus && digits.startsWith("00")) {
|
|
6875
|
+
hasPlus = true;
|
|
6876
|
+
digits = digits.slice(2);
|
|
6877
|
+
}
|
|
6878
|
+
const fixedCode = options.countryCode?.replace(/\D/g, "");
|
|
6879
|
+
if (fixedCode) {
|
|
6880
|
+
if (hasPlus && digits.startsWith(fixedCode)) digits = digits.slice(fixedCode.length);
|
|
6881
|
+
return { kind: "national", callingCode: fixedCode, nsn: digits.replace(/^0/, "") };
|
|
6882
|
+
}
|
|
6883
|
+
if (hasPlus) {
|
|
6884
|
+
if (!digits.startsWith(VN_CALLING_CODE)) return { kind: "unknown", digits: digits.slice(0, E164_MAX_DIGITS) };
|
|
6885
|
+
return { kind: "international", callingCode: VN_CALLING_CODE, nsn: digits.slice(2).replace(/^0/, "") };
|
|
6886
|
+
}
|
|
6887
|
+
if (/^1[89]00/.test(digits)) return { kind: "service", digits: digits.slice(0, 10) };
|
|
6888
|
+
if (digits.startsWith("0")) return { kind: "trunk", callingCode: VN_CALLING_CODE, nsn: digits.slice(1) };
|
|
6889
|
+
return { kind: "national", callingCode: VN_CALLING_CODE, nsn: digits };
|
|
6890
|
+
};
|
|
6891
|
+
var formatPhone = (value, options) => {
|
|
6892
|
+
if (!value) return "";
|
|
6893
|
+
const parsed = parsePhone(value, options);
|
|
6894
|
+
switch (parsed.kind) {
|
|
6895
|
+
case "unknown":
|
|
6896
|
+
return `+${parsed.digits}`;
|
|
6897
|
+
case "service":
|
|
6898
|
+
return chunkDigits(parsed.digits, parsed.digits.length <= 8 ? [4, 4] : [4, 3, 3]).join(" ");
|
|
6899
|
+
case "international":
|
|
6900
|
+
return [`+${parsed.callingCode}`, ...groupNationalNumber(parsed.nsn, parsed.callingCode)].join(" ");
|
|
6901
|
+
case "trunk": {
|
|
6902
|
+
const groups = groupNationalNumber(parsed.nsn, parsed.callingCode);
|
|
6903
|
+
return groups.length ? `0${groups.join(" ")}` : "0";
|
|
6904
|
+
}
|
|
6905
|
+
case "national":
|
|
6906
|
+
return groupNationalNumber(parsed.nsn, parsed.callingCode).join(" ");
|
|
6907
|
+
}
|
|
6908
|
+
};
|
|
6909
|
+
var normalizePhone = (value, options) => {
|
|
6910
|
+
if (!value) return "";
|
|
6911
|
+
const parsed = parsePhone(value, options);
|
|
6912
|
+
switch (parsed.kind) {
|
|
6913
|
+
case "unknown":
|
|
6914
|
+
return parsed.digits ? `+${parsed.digits}` : "";
|
|
6915
|
+
case "service":
|
|
6916
|
+
return parsed.digits;
|
|
6917
|
+
default: {
|
|
6918
|
+
const nsn = groupNationalNumber(parsed.nsn, parsed.callingCode).join("");
|
|
6919
|
+
return nsn ? `+${parsed.callingCode}${nsn}` : "";
|
|
6920
|
+
}
|
|
6921
|
+
}
|
|
6922
|
+
};
|
|
6923
|
+
var BANK_ACCOUNT_MAX_DIGITS = 19;
|
|
6924
|
+
var formatBankAccount = (value) => {
|
|
6925
|
+
if (!value) return "";
|
|
6926
|
+
const digits = value.replace(/\D/g, "").slice(0, BANK_ACCOUNT_MAX_DIGITS);
|
|
6927
|
+
const groups = digits.match(/\d{1,4}/g) ?? [];
|
|
6928
|
+
if (groups.length > 1 && groups[groups.length - 1].length === 1) {
|
|
6929
|
+
const last = groups.pop();
|
|
6930
|
+
groups[groups.length - 1] += last;
|
|
6931
|
+
}
|
|
6932
|
+
return groups.join(" ");
|
|
6933
|
+
};
|
|
6934
|
+
var formatCardNumber = (value) => {
|
|
6935
|
+
if (!value) return "";
|
|
6936
|
+
const digits = value.replace(/[^0-9]/g, "").slice(0, 16);
|
|
6937
|
+
return digits.replace(/(\d{4})(?=\d)/g, "$1 ").trim();
|
|
6938
|
+
};
|
|
6939
|
+
var calculateCursorPosition = (prevValue, nextValue, prevCursorPos) => {
|
|
6940
|
+
if (prevCursorPos <= 0) return 0;
|
|
6941
|
+
const rawBefore = prevValue.slice(0, prevCursorPos).replace(/[^0-9]/g, "");
|
|
6942
|
+
const rawDigitCount = rawBefore.length;
|
|
6943
|
+
let digitsSeen = 0;
|
|
6944
|
+
for (let i = 0; i < nextValue.length; i++) {
|
|
6945
|
+
if (/\d/.test(nextValue[i])) {
|
|
6946
|
+
digitsSeen++;
|
|
6947
|
+
}
|
|
6948
|
+
if (digitsSeen === rawDigitCount) {
|
|
6949
|
+
return i + 1;
|
|
6950
|
+
}
|
|
6951
|
+
}
|
|
6952
|
+
return nextValue.length;
|
|
6953
|
+
};
|
|
6954
|
+
|
|
6955
|
+
// ../ultimate/src/utils/number-detect.utils.ts
|
|
6956
|
+
var NUMBER_SUGGESTION_THRESHOLD = 0.4;
|
|
6957
|
+
var CONFIDENT_SCORE = 0.7;
|
|
6958
|
+
var FALLBACK_CUTOFF = 0.5;
|
|
6959
|
+
var ACCOUNT_LABELS = [
|
|
6960
|
+
"stk",
|
|
6961
|
+
"so tk",
|
|
6962
|
+
"so tai khoan",
|
|
6963
|
+
"tai khoan",
|
|
6964
|
+
"tk",
|
|
6965
|
+
"tknh",
|
|
6966
|
+
"account",
|
|
6967
|
+
"acct",
|
|
6968
|
+
"acc",
|
|
6969
|
+
"a/c",
|
|
6970
|
+
"ck",
|
|
6971
|
+
"chuyen khoan",
|
|
6972
|
+
"chuyen tien",
|
|
6973
|
+
"chuyen vao",
|
|
6974
|
+
"nhan tien",
|
|
6975
|
+
"thu huong"
|
|
6976
|
+
];
|
|
6977
|
+
var BANK_NAMES = [
|
|
6978
|
+
"vietcombank",
|
|
6979
|
+
"vcb",
|
|
6980
|
+
"techcombank",
|
|
6981
|
+
"tcb",
|
|
6982
|
+
"mbbank",
|
|
6983
|
+
"mb bank",
|
|
6984
|
+
"mb",
|
|
6985
|
+
"bidv",
|
|
6986
|
+
"vietinbank",
|
|
6987
|
+
"vietin",
|
|
6988
|
+
"ctg",
|
|
6989
|
+
"agribank",
|
|
6990
|
+
"acb",
|
|
6991
|
+
"vpbank",
|
|
6992
|
+
"vpb",
|
|
6993
|
+
"tpbank",
|
|
6994
|
+
"tpb",
|
|
6995
|
+
"sacombank",
|
|
6996
|
+
"stb",
|
|
6997
|
+
"hdbank",
|
|
6998
|
+
"hdb",
|
|
6999
|
+
"vib",
|
|
7000
|
+
"shb",
|
|
7001
|
+
"msb",
|
|
7002
|
+
"ocb",
|
|
7003
|
+
"seabank",
|
|
7004
|
+
"eximbank",
|
|
7005
|
+
"eib",
|
|
7006
|
+
"lpbank",
|
|
7007
|
+
"lienvietpostbank",
|
|
7008
|
+
"namabank",
|
|
7009
|
+
"nam a bank",
|
|
7010
|
+
"abbank",
|
|
7011
|
+
"pvcombank",
|
|
7012
|
+
"baovietbank",
|
|
7013
|
+
"bac a bank",
|
|
7014
|
+
"bacabank",
|
|
7015
|
+
"kienlongbank",
|
|
7016
|
+
"vietbank",
|
|
7017
|
+
"vietabank",
|
|
7018
|
+
"saigonbank",
|
|
7019
|
+
"scb",
|
|
7020
|
+
"pgbank",
|
|
7021
|
+
"ncb",
|
|
7022
|
+
"gpbank",
|
|
7023
|
+
"oceanbank",
|
|
7024
|
+
"cbbank",
|
|
7025
|
+
"uob",
|
|
7026
|
+
"hsbc",
|
|
7027
|
+
"shinhan",
|
|
7028
|
+
"woori",
|
|
7029
|
+
"citibank",
|
|
7030
|
+
"cake",
|
|
7031
|
+
"timo",
|
|
7032
|
+
"ubank",
|
|
7033
|
+
"ngan hang",
|
|
7034
|
+
"bank"
|
|
7035
|
+
];
|
|
7036
|
+
var PHONE_LABELS = [
|
|
7037
|
+
"sdt",
|
|
7038
|
+
"so dt",
|
|
7039
|
+
"so dien thoai",
|
|
7040
|
+
"dien thoai",
|
|
7041
|
+
"dt",
|
|
7042
|
+
"dd",
|
|
7043
|
+
"di dong",
|
|
7044
|
+
"phone",
|
|
7045
|
+
"tel",
|
|
7046
|
+
"mobile",
|
|
7047
|
+
"hotline",
|
|
7048
|
+
"zalo",
|
|
7049
|
+
"viber",
|
|
7050
|
+
"whatsapp",
|
|
7051
|
+
"telegram",
|
|
7052
|
+
"sms",
|
|
7053
|
+
"lien he",
|
|
7054
|
+
"lh",
|
|
7055
|
+
"call",
|
|
7056
|
+
"nhan tin"
|
|
7057
|
+
];
|
|
7058
|
+
var MONEY_MARKERS = [
|
|
7059
|
+
"d",
|
|
7060
|
+
"vnd",
|
|
7061
|
+
"dong",
|
|
7062
|
+
"k",
|
|
7063
|
+
"tr",
|
|
7064
|
+
"trieu",
|
|
7065
|
+
"ty",
|
|
7066
|
+
"nghin",
|
|
7067
|
+
"ngan",
|
|
7068
|
+
"usd",
|
|
7069
|
+
"dola",
|
|
7070
|
+
"xu",
|
|
7071
|
+
"%"
|
|
7072
|
+
];
|
|
7073
|
+
var isDigit = (c) => c !== void 0 && c >= "0" && c <= "9";
|
|
7074
|
+
var isLetter = (c) => c !== void 0 && /\p{L}/u.test(c);
|
|
7075
|
+
var isAlnum = (c) => isDigit(c) || isLetter(c);
|
|
7076
|
+
var isGapChar = (c) => c === " " || c === "." || c === "-" || c === "\xA0" || c === "(" || c === ")";
|
|
7077
|
+
var foldChar = (c) => {
|
|
7078
|
+
if (c === "\u0111" || c === "\u0110" || c === "\u20AB") return "d";
|
|
7079
|
+
const base = c.normalize("NFD")[0] ?? c;
|
|
7080
|
+
return base.toLowerCase();
|
|
7081
|
+
};
|
|
7082
|
+
var fold = (text) => {
|
|
7083
|
+
let out = "";
|
|
7084
|
+
for (let i = 0; i < text.length; i++) out += foldChar(text[i]);
|
|
7085
|
+
return out;
|
|
7086
|
+
};
|
|
7087
|
+
var readRuns = (text) => {
|
|
7088
|
+
const runs = [];
|
|
7089
|
+
let i = 0;
|
|
7090
|
+
while (i < text.length) {
|
|
7091
|
+
let j = i;
|
|
7092
|
+
if (text[j] === "(") j++;
|
|
7093
|
+
const plus = text[j] === "+";
|
|
7094
|
+
if (plus) j++;
|
|
7095
|
+
if (!isDigit(text[j]) || j === i && !isDigit(text[i])) {
|
|
7096
|
+
i++;
|
|
7097
|
+
continue;
|
|
7098
|
+
}
|
|
7099
|
+
const start = i;
|
|
7100
|
+
const glued = isAlnum(text[start - 1]) || text[start - 1] === "+";
|
|
7101
|
+
const groups = [];
|
|
7102
|
+
let gap = "";
|
|
7103
|
+
let k = j;
|
|
7104
|
+
for (; ; ) {
|
|
7105
|
+
const groupStart = k;
|
|
7106
|
+
while (isDigit(text[k])) k++;
|
|
7107
|
+
groups.push({ digits: text.slice(groupStart, k), start: groupStart, end: k, gap });
|
|
7108
|
+
let g = k;
|
|
7109
|
+
while (g < text.length && g - k < 2 && isGapChar(text[g])) g++;
|
|
7110
|
+
if (g > k && isDigit(text[g])) {
|
|
7111
|
+
gap = text.slice(k, g);
|
|
7112
|
+
k = g;
|
|
7113
|
+
continue;
|
|
7114
|
+
}
|
|
7115
|
+
break;
|
|
7116
|
+
}
|
|
7117
|
+
i = k;
|
|
7118
|
+
if (glued || isLetter(text[k])) continue;
|
|
7119
|
+
runs.push({ plus, start, groups });
|
|
7120
|
+
}
|
|
7121
|
+
return runs;
|
|
7122
|
+
};
|
|
7123
|
+
var phoneShape = (digits, plus) => {
|
|
7124
|
+
let international = plus;
|
|
7125
|
+
let d = digits;
|
|
7126
|
+
if (!plus && d.startsWith("0084")) {
|
|
7127
|
+
international = true;
|
|
7128
|
+
d = d.slice(2);
|
|
7129
|
+
}
|
|
7130
|
+
if (international) {
|
|
7131
|
+
if (d.startsWith("84")) {
|
|
7132
|
+
const nsn = d.slice(2).replace(/^0/, "");
|
|
7133
|
+
return /^[35789]\d{8}$/.test(nsn) || /^2\d{9}$/.test(nsn) ? "strong" : null;
|
|
7134
|
+
}
|
|
7135
|
+
return d.length >= 8 && d.length <= 15 ? "weak" : null;
|
|
7136
|
+
}
|
|
7137
|
+
if (/^0[35789]\d{8}$/.test(d) || /^02\d{9}$/.test(d) || /^1[89]00(\d{4}|\d{6})$/.test(d)) return "strong";
|
|
7138
|
+
if (/^84[35789]\d{8}$/.test(d)) return "weak";
|
|
7139
|
+
return null;
|
|
7140
|
+
};
|
|
7141
|
+
var isCompletePhone = (digits, plus) => plus ? /^84[35789]\d{8}$/.test(digits) : /^0[35789]\d{8}$/.test(digits) || /^02\d{9}$/.test(digits);
|
|
7142
|
+
var ACCOUNT_MAX_DIGITS = 19;
|
|
7143
|
+
var E164_MAX_DIGITS2 = 15;
|
|
7144
|
+
var splitRun = (run) => {
|
|
7145
|
+
const segments = [];
|
|
7146
|
+
let current = [run.groups[0]];
|
|
7147
|
+
let plus = run.plus;
|
|
7148
|
+
let start = run.start;
|
|
7149
|
+
const close = () => {
|
|
7150
|
+
segments.push({
|
|
7151
|
+
plus,
|
|
7152
|
+
start,
|
|
7153
|
+
end: current[current.length - 1].end,
|
|
7154
|
+
groups: current,
|
|
7155
|
+
digits: current.map((g) => g.digits).join("")
|
|
7156
|
+
});
|
|
7157
|
+
};
|
|
7158
|
+
for (const group of run.groups.slice(1)) {
|
|
7159
|
+
const digits = current.map((g) => g.digits).join("");
|
|
7160
|
+
const max = plus ? E164_MAX_DIGITS2 : ACCOUNT_MAX_DIGITS;
|
|
7161
|
+
const breaks = digits.length >= 8 && group.digits.length >= 6 || isCompletePhone(digits, plus) && group.digits.startsWith("0") || digits.length + group.digits.length > max;
|
|
7162
|
+
if (breaks) {
|
|
7163
|
+
close();
|
|
7164
|
+
current = [group];
|
|
7165
|
+
plus = false;
|
|
7166
|
+
start = group.gap.endsWith("(") ? group.start - 1 : group.start;
|
|
7167
|
+
} else {
|
|
7168
|
+
current.push(group);
|
|
7169
|
+
}
|
|
7170
|
+
}
|
|
7171
|
+
close();
|
|
7172
|
+
return segments;
|
|
7173
|
+
};
|
|
7174
|
+
var looksLikeAmount = (segment) => {
|
|
7175
|
+
const [first, ...rest] = segment.groups;
|
|
7176
|
+
if (!first || rest.length === 0) return false;
|
|
7177
|
+
if (first.digits.length > 3 || first.digits.startsWith("0")) return false;
|
|
7178
|
+
return rest.every((g) => g.digits.length === 3 && g.gap === ".");
|
|
7179
|
+
};
|
|
7180
|
+
var startsWithWord = (folded, at, words) => words.some((w) => folded.startsWith(w, at) && !isAlnum(folded[at + w.length]));
|
|
7181
|
+
var isMoney = (text, folded, segment) => {
|
|
7182
|
+
if (looksLikeAmount(segment)) return true;
|
|
7183
|
+
if (segment.plus || segment.digits.startsWith("0")) return false;
|
|
7184
|
+
let before = segment.start - 1;
|
|
7185
|
+
while (before >= 0 && folded[before] === " ") before--;
|
|
7186
|
+
if (folded[before] === "$") return true;
|
|
7187
|
+
let after = segment.end;
|
|
7188
|
+
if ((folded[after] === "," || folded[after] === ".") && isDigit(folded[after + 1])) {
|
|
7189
|
+
after++;
|
|
7190
|
+
while (isDigit(folded[after])) after++;
|
|
7191
|
+
}
|
|
7192
|
+
while (after < folded.length && folded[after] === " ") after++;
|
|
7193
|
+
if (text[after] === "$") return true;
|
|
7194
|
+
return startsWithWord(folded, after, MONEY_MARKERS);
|
|
7195
|
+
};
|
|
7196
|
+
var BEFORE_WINDOW = 40;
|
|
7197
|
+
var AFTER_WINDOW = 28;
|
|
7198
|
+
var lastWordEnd = (folded, from, to, words) => {
|
|
7199
|
+
let best = -1;
|
|
7200
|
+
for (const w of words) {
|
|
7201
|
+
let at = folded.indexOf(w, from);
|
|
7202
|
+
while (at !== -1 && at + w.length <= to) {
|
|
7203
|
+
const end = at + w.length;
|
|
7204
|
+
if (!isAlnum(folded[at - 1]) && !isAlnum(folded[end]) && end > best) best = end;
|
|
7205
|
+
at = folded.indexOf(w, at + 1);
|
|
7206
|
+
}
|
|
7207
|
+
}
|
|
7208
|
+
return best;
|
|
7209
|
+
};
|
|
7210
|
+
var firstWordStart = (folded, from, to, words) => {
|
|
7211
|
+
let best = -1;
|
|
7212
|
+
for (const w of words) {
|
|
7213
|
+
const at = folded.indexOf(w, from);
|
|
7214
|
+
if (at === -1 || at + w.length > to) continue;
|
|
7215
|
+
if (!isAlnum(folded[at - 1]) && !isAlnum(folded[at + w.length]) && (best === -1 || at < best)) best = at;
|
|
7216
|
+
}
|
|
7217
|
+
return best;
|
|
7218
|
+
};
|
|
7219
|
+
var readContext = (folded, segment, prevEnd, nextStart) => {
|
|
7220
|
+
let lineStart = folded.lastIndexOf("\n", segment.start - 1) + 1;
|
|
7221
|
+
if (folded.slice(lineStart, segment.start).trim() === "" && lineStart >= 2) {
|
|
7222
|
+
lineStart = folded.lastIndexOf("\n", lineStart - 2) + 1;
|
|
7223
|
+
}
|
|
7224
|
+
const from = Math.max(lineStart, prevEnd, segment.start - BEFORE_WINDOW);
|
|
7225
|
+
const accountEnd = Math.max(
|
|
7226
|
+
lastWordEnd(folded, from, segment.start, ACCOUNT_LABELS),
|
|
7227
|
+
lastWordEnd(folded, from, segment.start, BANK_NAMES)
|
|
7228
|
+
);
|
|
7229
|
+
const phoneEnd = lastWordEnd(folded, from, segment.start, PHONE_LABELS);
|
|
7230
|
+
if (accountEnd !== -1 || phoneEnd !== -1) return accountEnd > phoneEnd ? "bankAccount" : "phone";
|
|
7231
|
+
let lineEnd = folded.indexOf("\n", segment.end);
|
|
7232
|
+
if (lineEnd === -1) lineEnd = folded.length;
|
|
7233
|
+
const to = Math.min(lineEnd, nextStart, segment.end + AFTER_WINDOW);
|
|
7234
|
+
return firstWordStart(folded, segment.end, to, BANK_NAMES) !== -1 ? "bankAccount" : null;
|
|
7235
|
+
};
|
|
7236
|
+
var scoreSegment = (segment, context) => {
|
|
7237
|
+
const { digits, plus } = segment;
|
|
7238
|
+
const shape = phoneShape(digits, plus);
|
|
7239
|
+
const scores = {};
|
|
7240
|
+
if (shape) {
|
|
7241
|
+
if (context === "phone") scores.phone = 1;
|
|
7242
|
+
else if (context === null) scores.phone = shape === "strong" ? 0.8 : 0.5;
|
|
7243
|
+
} else if (context === "phone" && digits.length >= 8 && digits.length <= E164_MAX_DIGITS2) {
|
|
7244
|
+
scores.phone = 0.6;
|
|
7245
|
+
}
|
|
7246
|
+
const international = plus || shape !== null && digits.startsWith("0084");
|
|
7247
|
+
const minAccount = context === "bankAccount" ? 6 : 8;
|
|
7248
|
+
if (!international && digits.length >= minAccount && digits.length <= ACCOUNT_MAX_DIGITS) {
|
|
7249
|
+
if (context === "bankAccount") scores.bankAccount = 1;
|
|
7250
|
+
else if (context === null) scores.bankAccount = shape ? 0.4 : 0.7;
|
|
7251
|
+
}
|
|
7252
|
+
return scores;
|
|
7253
|
+
};
|
|
7254
|
+
var detectNumbers = (input) => {
|
|
7255
|
+
if (!input) return [];
|
|
7256
|
+
const text = input.normalize("NFC");
|
|
7257
|
+
const folded = fold(text);
|
|
7258
|
+
const segments = readRuns(text).flatMap(splitRun);
|
|
7259
|
+
const result = [];
|
|
7260
|
+
segments.forEach((segment, index) => {
|
|
7261
|
+
if (isMoney(text, folded, segment)) return;
|
|
7262
|
+
const prevEnd = index > 0 ? segments[index - 1].end : 0;
|
|
7263
|
+
const nextStart = index < segments.length - 1 ? segments[index + 1].start : text.length;
|
|
7264
|
+
const scores = scoreSegment(segment, readContext(folded, segment, prevEnd, nextStart));
|
|
7265
|
+
if (scores.phone === void 0 && scores.bankAccount === void 0) return;
|
|
7266
|
+
const value = (segment.plus ? "+" : "") + segment.digits;
|
|
7267
|
+
const best = (scores.phone ?? 0) >= (scores.bankAccount ?? 0) ? "phone" : "bankAccount";
|
|
7268
|
+
result.push({
|
|
7269
|
+
value,
|
|
7270
|
+
formatted: best === "phone" ? formatPhone(value) : formatBankAccount(value),
|
|
7271
|
+
text: text.slice(segment.start, segment.end),
|
|
7272
|
+
start: segment.start,
|
|
7273
|
+
end: segment.end,
|
|
7274
|
+
scores
|
|
7275
|
+
});
|
|
7276
|
+
});
|
|
7277
|
+
return result;
|
|
7278
|
+
};
|
|
7279
|
+
var numberKey = (value, kind) => kind === "phone" ? normalizePhone(value) || value.replace(/\D/g, "") : value.replace(/\D/g, "");
|
|
7280
|
+
var suggestNumbers = (text, kind, options = {}) => {
|
|
7281
|
+
const seen = /* @__PURE__ */ new Map();
|
|
7282
|
+
for (const detected of detectNumbers(text)) {
|
|
7283
|
+
const found = { ...detected, formatted: kind === "phone" ? formatPhone(detected.value) : formatBankAccount(detected.value) };
|
|
7284
|
+
const score = found.scores[kind];
|
|
7285
|
+
if (score === void 0 || score < NUMBER_SUGGESTION_THRESHOLD) continue;
|
|
7286
|
+
const key = numberKey(found.value, kind);
|
|
7287
|
+
const known = seen.get(key);
|
|
7288
|
+
if (!known) seen.set(key, found);
|
|
7289
|
+
else if ((known.scores[kind] ?? 0) < score) seen.set(key, { ...found, start: known.start, end: known.end });
|
|
7290
|
+
}
|
|
7291
|
+
let ranked = [...seen.values()].sort(
|
|
7292
|
+
(a, b) => (b.scores[kind] ?? 0) - (a.scores[kind] ?? 0) || a.start - b.start
|
|
7293
|
+
);
|
|
7294
|
+
if ((ranked[0]?.scores[kind] ?? 0) >= CONFIDENT_SCORE) {
|
|
7295
|
+
ranked = ranked.filter((found) => (found.scores[kind] ?? 0) >= FALLBACK_CUTOFF);
|
|
7296
|
+
}
|
|
7297
|
+
return options.limit === void 0 ? ranked : ranked.slice(0, options.limit);
|
|
7298
|
+
};
|
|
7299
|
+
var isTextWithNumbers = (text) => {
|
|
7300
|
+
if (!text || !/\d/.test(text)) return false;
|
|
7301
|
+
if (/[\p{L}\n]/u.test(text)) return true;
|
|
7302
|
+
return detectNumbers(text).length > 1;
|
|
7303
|
+
};
|
|
7304
|
+
|
|
7305
|
+
// ../ultimate/src/hooks/useNumberSuggestions.ts
|
|
7306
|
+
var source = "";
|
|
7307
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
7308
|
+
var emit = () => listeners.forEach((listener) => listener());
|
|
7309
|
+
var setNumberSuggestionSource = (text) => {
|
|
7310
|
+
if (text === source) return;
|
|
7311
|
+
source = text;
|
|
7312
|
+
emit();
|
|
7313
|
+
};
|
|
7314
|
+
var copyListenerCount = 0;
|
|
7315
|
+
var handleCopy = (event) => {
|
|
7316
|
+
const target = event.target;
|
|
7317
|
+
let text = "";
|
|
7318
|
+
if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {
|
|
7319
|
+
text = target.value.slice(target.selectionStart ?? 0, target.selectionEnd ?? 0);
|
|
7320
|
+
} else {
|
|
7321
|
+
text = window.getSelection()?.toString() ?? "";
|
|
7322
|
+
}
|
|
7323
|
+
if (/\d/.test(text) && suggestNumbersAny(text)) setNumberSuggestionSource(text);
|
|
7324
|
+
};
|
|
7325
|
+
var suggestNumbersAny = (text) => suggestNumbers(text, "phone", { limit: 1 }).length > 0 || suggestNumbers(text, "bankAccount", { limit: 1 }).length > 0;
|
|
7326
|
+
var subscribe = (listener) => {
|
|
7327
|
+
listeners.add(listener);
|
|
7328
|
+
if (typeof document !== "undefined" && copyListenerCount++ === 0) {
|
|
7329
|
+
document.addEventListener("copy", handleCopy, true);
|
|
7330
|
+
}
|
|
7331
|
+
return () => {
|
|
7332
|
+
listeners.delete(listener);
|
|
7333
|
+
if (typeof document !== "undefined" && --copyListenerCount === 0) {
|
|
7334
|
+
document.removeEventListener("copy", handleCopy, true);
|
|
7335
|
+
}
|
|
7336
|
+
};
|
|
7337
|
+
};
|
|
7338
|
+
var getSnapshot = () => source;
|
|
7339
|
+
var getServerSnapshot = () => "";
|
|
7340
|
+
var clipboardAccess = async () => {
|
|
7341
|
+
if (typeof navigator === "undefined" || !navigator.clipboard?.readText) return "none";
|
|
7342
|
+
try {
|
|
7343
|
+
const status = await navigator.permissions?.query({ name: "clipboard-read" });
|
|
7344
|
+
if (status?.state === "granted") return "granted";
|
|
7345
|
+
if (status?.state === "denied") return "none";
|
|
7346
|
+
} catch {
|
|
7347
|
+
}
|
|
7348
|
+
return "ask";
|
|
7349
|
+
};
|
|
7350
|
+
var readClipboard = async () => {
|
|
7351
|
+
try {
|
|
7352
|
+
return await navigator.clipboard.readText() ?? "";
|
|
7353
|
+
} catch {
|
|
7354
|
+
return "";
|
|
7355
|
+
}
|
|
7356
|
+
};
|
|
7357
|
+
var useNumberSuggestions = ({
|
|
7358
|
+
kind,
|
|
7359
|
+
value,
|
|
7360
|
+
onSelect,
|
|
7361
|
+
enabled = true,
|
|
7362
|
+
clipboard = true,
|
|
7363
|
+
limit = 5
|
|
7364
|
+
}) => {
|
|
7365
|
+
const text = React235.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
7366
|
+
const [canPasteFromClipboard, setCanPasteFromClipboard] = React235.useState(false);
|
|
7367
|
+
const onSelectRef = React235.useRef(onSelect);
|
|
7368
|
+
onSelectRef.current = onSelect;
|
|
7369
|
+
const suggestions = React235.useMemo(() => {
|
|
7370
|
+
if (!enabled || !text || limit <= 0) return [];
|
|
7371
|
+
const current = value ? numberKey(value, kind) : "";
|
|
7372
|
+
return suggestNumbers(text, kind).filter((found) => numberKey(found.value, kind) !== current).slice(0, limit);
|
|
7373
|
+
}, [enabled, text, value, kind, limit]);
|
|
7374
|
+
const take = React235.useCallback(
|
|
7375
|
+
(incoming, fill) => {
|
|
7376
|
+
setNumberSuggestionSource(incoming);
|
|
7377
|
+
const [best] = suggestNumbers(incoming, kind, { limit: 1 });
|
|
7378
|
+
if (fill && best) onSelectRef.current(best.value);
|
|
7379
|
+
},
|
|
7380
|
+
[kind]
|
|
7381
|
+
);
|
|
7382
|
+
const onPaste = React235.useCallback(
|
|
7383
|
+
(event) => {
|
|
7384
|
+
if (!enabled) return;
|
|
7385
|
+
const pasted = event.clipboardData.getData("text");
|
|
7386
|
+
if (!isTextWithNumbers(pasted)) return;
|
|
7387
|
+
event.preventDefault();
|
|
7388
|
+
take(pasted, true);
|
|
7389
|
+
},
|
|
7390
|
+
[enabled, take]
|
|
7391
|
+
);
|
|
7392
|
+
const onFocus = React235.useCallback(() => {
|
|
7393
|
+
if (!enabled || !clipboard) return;
|
|
7394
|
+
void clipboardAccess().then(async (access) => {
|
|
7395
|
+
if (access === "granted") {
|
|
7396
|
+
const read = await readClipboard();
|
|
7397
|
+
if (read && read !== source && isTextWithNumbers(read)) take(read, false);
|
|
7398
|
+
setCanPasteFromClipboard(false);
|
|
7399
|
+
} else {
|
|
7400
|
+
setCanPasteFromClipboard(access === "ask");
|
|
7401
|
+
}
|
|
7402
|
+
});
|
|
7403
|
+
}, [enabled, clipboard, take]);
|
|
7404
|
+
const pasteFromClipboard = React235.useCallback(async () => {
|
|
7405
|
+
const read = await readClipboard();
|
|
7406
|
+
setCanPasteFromClipboard(false);
|
|
7407
|
+
if (!read) return;
|
|
7408
|
+
if (isTextWithNumbers(read)) take(read, !value);
|
|
7409
|
+
else if (/\d/.test(read)) onSelectRef.current(read.trim());
|
|
7410
|
+
}, [take, value]);
|
|
7411
|
+
return { suggestions, onPaste, onFocus, canPasteFromClipboard, pasteFromClipboard };
|
|
7412
|
+
};
|
|
7413
|
+
|
|
6812
7414
|
// ../ultimate/src/components/dropdown-list/DropdownList.tsx
|
|
6813
|
-
var
|
|
7415
|
+
var React238 = __toESM(require("react"));
|
|
6814
7416
|
|
|
6815
7417
|
// ../ultimate/src/components/search-field/SearchField.tsx
|
|
6816
|
-
var
|
|
7418
|
+
var React237 = __toESM(require("react"));
|
|
6817
7419
|
|
|
6818
7420
|
// ../ultimate/src/hooks/useComposedRefs.ts
|
|
6819
7421
|
var import_react3 = require("react");
|
|
@@ -6865,9 +7467,9 @@ function useClickOutside(ref, handler, enabled = true, ignoredRefs = []) {
|
|
|
6865
7467
|
var import_react6 = require("react");
|
|
6866
7468
|
|
|
6867
7469
|
// ../ultimate/src/internal/overlay/OverlayScope.tsx
|
|
6868
|
-
var
|
|
7470
|
+
var React236 = __toESM(require("react"));
|
|
6869
7471
|
var import_jsx_runtime232 = require("react/jsx-runtime");
|
|
6870
|
-
var OverlayDepthContext =
|
|
7472
|
+
var OverlayDepthContext = React236.createContext(0);
|
|
6871
7473
|
|
|
6872
7474
|
// ../ultimate/src/hooks/useEscapeKeydown.ts
|
|
6873
7475
|
var layersByDocument = /* @__PURE__ */ new WeakMap();
|
|
@@ -7120,7 +7722,7 @@ var SearchField_default = {};
|
|
|
7120
7722
|
|
|
7121
7723
|
// ../ultimate/src/components/search-field/SearchField.tsx
|
|
7122
7724
|
var import_jsx_runtime233 = require("react/jsx-runtime");
|
|
7123
|
-
var SearchField =
|
|
7725
|
+
var SearchField = React237.forwardRef(
|
|
7124
7726
|
({
|
|
7125
7727
|
placeholder = "Search",
|
|
7126
7728
|
variant = "default",
|
|
@@ -7140,16 +7742,19 @@ var SearchField = React236.forwardRef(
|
|
|
7140
7742
|
defaultValue,
|
|
7141
7743
|
fullWidth = true,
|
|
7142
7744
|
width,
|
|
7745
|
+
bare = false,
|
|
7746
|
+
loading = false,
|
|
7747
|
+
onKeyDown,
|
|
7143
7748
|
...props
|
|
7144
7749
|
}, ref) => {
|
|
7145
|
-
const [focused, setFocused] =
|
|
7750
|
+
const [focused, setFocused] = React237.useState(false);
|
|
7146
7751
|
const [valueState, setValueState] = useControllableState({
|
|
7147
7752
|
value,
|
|
7148
7753
|
defaultValue: defaultValue || "",
|
|
7149
7754
|
onChange
|
|
7150
7755
|
});
|
|
7151
|
-
const inputRef =
|
|
7152
|
-
|
|
7756
|
+
const inputRef = React237.useRef(null);
|
|
7757
|
+
React237.useEffect(() => {
|
|
7153
7758
|
if (!shortcutHint || disabled) return;
|
|
7154
7759
|
const handleGlobalKeyDown = (e) => {
|
|
7155
7760
|
if (!e.isComposing && !e.defaultPrevented && (e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "k") {
|
|
@@ -7160,7 +7765,7 @@ var SearchField = React236.forwardRef(
|
|
|
7160
7765
|
window.addEventListener("keydown", handleGlobalKeyDown);
|
|
7161
7766
|
return () => window.removeEventListener("keydown", handleGlobalKeyDown);
|
|
7162
7767
|
}, [shortcutHint, disabled]);
|
|
7163
|
-
|
|
7768
|
+
React237.useImperativeHandle(ref, () => inputRef.current);
|
|
7164
7769
|
const currentValue = valueState;
|
|
7165
7770
|
const handleFocus = (e) => {
|
|
7166
7771
|
setFocused(true);
|
|
@@ -7189,7 +7794,8 @@ var SearchField = React236.forwardRef(
|
|
|
7189
7794
|
inputRef.current?.focus();
|
|
7190
7795
|
};
|
|
7191
7796
|
const handleKeyDown = (e) => {
|
|
7192
|
-
|
|
7797
|
+
onKeyDown?.(e);
|
|
7798
|
+
if (e.defaultPrevented || disabled || e.nativeEvent.isComposing) return;
|
|
7193
7799
|
if (e.key === "Enter") {
|
|
7194
7800
|
e.preventDefault();
|
|
7195
7801
|
focusNextElement(e.currentTarget);
|
|
@@ -7204,6 +7810,7 @@ var SearchField = React236.forwardRef(
|
|
|
7204
7810
|
SearchField_default[size],
|
|
7205
7811
|
!fullWidth && !width && SearchField_default.widthAuto,
|
|
7206
7812
|
variant === "rounded" && SearchField_default.searchFieldRounded,
|
|
7813
|
+
bare && SearchField_default.bare,
|
|
7207
7814
|
focused && SearchField_default.searchFieldFocused,
|
|
7208
7815
|
disabled && SearchField_default.searchFieldDisabled,
|
|
7209
7816
|
className
|
|
@@ -7211,7 +7818,7 @@ var SearchField = React236.forwardRef(
|
|
|
7211
7818
|
style: { ...style, width },
|
|
7212
7819
|
onClick: () => !disabled && inputRef.current?.focus(),
|
|
7213
7820
|
children: [
|
|
7214
|
-
/* @__PURE__ */ (0, import_jsx_runtime233.jsx)("span", { className: SearchField_default.searchFieldIcon, children: /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(SearchOutline, { size: size === "large" ? 24 : 20 }) }),
|
|
7821
|
+
/* @__PURE__ */ (0, import_jsx_runtime233.jsx)("span", { className: SearchField_default.searchFieldIcon, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(Spinner2, { size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime233.jsx)(SearchOutline, { size: size === "large" ? 24 : 20 }) }),
|
|
7215
7822
|
/* @__PURE__ */ (0, import_jsx_runtime233.jsx)(
|
|
7216
7823
|
"input",
|
|
7217
7824
|
{
|
|
@@ -7227,6 +7834,7 @@ var SearchField = React236.forwardRef(
|
|
|
7227
7834
|
value: currentValue,
|
|
7228
7835
|
placeholder,
|
|
7229
7836
|
type: "search",
|
|
7837
|
+
"aria-busy": loading || void 0,
|
|
7230
7838
|
...props
|
|
7231
7839
|
}
|
|
7232
7840
|
),
|
|
@@ -7272,7 +7880,7 @@ function getItemId(collectionId, part, key) {
|
|
|
7272
7880
|
|
|
7273
7881
|
// ../ultimate/src/components/dropdown-list/DropdownList.tsx
|
|
7274
7882
|
var import_jsx_runtime234 = require("react/jsx-runtime");
|
|
7275
|
-
var DropdownList =
|
|
7883
|
+
var DropdownList = React238.forwardRef(
|
|
7276
7884
|
({
|
|
7277
7885
|
items,
|
|
7278
7886
|
role = "listbox",
|
|
@@ -7290,32 +7898,32 @@ var DropdownList = React237.forwardRef(
|
|
|
7290
7898
|
className,
|
|
7291
7899
|
style
|
|
7292
7900
|
}, ref) => {
|
|
7293
|
-
const typeaheadRef =
|
|
7294
|
-
const [searchQuery, setSearchQuery] =
|
|
7901
|
+
const typeaheadRef = React238.useRef({ text: "", time: 0 });
|
|
7902
|
+
const [searchQuery, setSearchQuery] = React238.useState("");
|
|
7295
7903
|
const showSearch = role === "listbox" && items.length >= 10;
|
|
7296
|
-
const instanceId =
|
|
7904
|
+
const instanceId = React238.useId();
|
|
7297
7905
|
const itemId = (value2) => value2 === void 0 ? void 0 : getItemId(instanceId, "item", value2);
|
|
7298
|
-
const selectedValues =
|
|
7906
|
+
const selectedValues = React238.useMemo(() => {
|
|
7299
7907
|
if (Array.isArray(value)) return value;
|
|
7300
7908
|
return value ? [value] : [];
|
|
7301
7909
|
}, [value]);
|
|
7302
|
-
const filteredItems =
|
|
7910
|
+
const filteredItems = React238.useMemo(() => {
|
|
7303
7911
|
if (!searchQuery.trim()) return items;
|
|
7304
7912
|
const query = searchQuery.toLowerCase();
|
|
7305
7913
|
return items.filter(
|
|
7306
7914
|
(item) => item.label.toLowerCase().includes(query)
|
|
7307
7915
|
);
|
|
7308
7916
|
}, [items, searchQuery]);
|
|
7309
|
-
const selectableFilteredValues =
|
|
7917
|
+
const selectableFilteredValues = React238.useMemo(() => filteredItems.filter((item) => !item.disabled).map((item) => item.value), [filteredItems]);
|
|
7310
7918
|
const showSelectAll = mode === "multi" && Boolean(selectAllLabel) && selectableFilteredValues.length > 0;
|
|
7311
7919
|
const allFilteredSelected = showSelectAll && selectableFilteredValues.every((itemValue) => selectedValues.includes(itemValue));
|
|
7312
7920
|
const someFilteredSelected = showSelectAll && !allFilteredSelected && selectableFilteredValues.some((itemValue) => selectedValues.includes(itemValue));
|
|
7313
|
-
const handleSelectAllClick =
|
|
7921
|
+
const handleSelectAllClick = React238.useCallback(() => {
|
|
7314
7922
|
if (!showSelectAll) return;
|
|
7315
7923
|
const nextValues = allFilteredSelected ? selectedValues.filter((itemValue) => !selectableFilteredValues.includes(itemValue)) : Array.from(/* @__PURE__ */ new Set([...selectedValues, ...selectableFilteredValues]));
|
|
7316
7924
|
onChange?.(nextValues);
|
|
7317
7925
|
}, [allFilteredSelected, onChange, selectableFilteredValues, selectedValues, showSelectAll]);
|
|
7318
|
-
const displayItems =
|
|
7926
|
+
const displayItems = React238.useMemo(() => {
|
|
7319
7927
|
if (!showSelectAll || !selectAllLabel) return filteredItems;
|
|
7320
7928
|
return [
|
|
7321
7929
|
{ value: "__phx_select_all__", label: selectAllLabel, __selectAll: true },
|
|
@@ -7338,10 +7946,10 @@ var DropdownList = React237.forwardRef(
|
|
|
7338
7946
|
const isSelected = (itemValue) => {
|
|
7339
7947
|
return selectedValues.includes(itemValue);
|
|
7340
7948
|
};
|
|
7341
|
-
const [showTopGradient, setShowTopGradient] =
|
|
7342
|
-
const [showBottomGradient, setShowBottomGradient] =
|
|
7343
|
-
const listRef =
|
|
7344
|
-
const handleScroll =
|
|
7949
|
+
const [showTopGradient, setShowTopGradient] = React238.useState(false);
|
|
7950
|
+
const [showBottomGradient, setShowBottomGradient] = React238.useState(false);
|
|
7951
|
+
const listRef = React238.useRef(null);
|
|
7952
|
+
const handleScroll = React238.useCallback(() => {
|
|
7345
7953
|
const el = listRef.current;
|
|
7346
7954
|
if (!el) return;
|
|
7347
7955
|
const scrollTop = el.scrollTop;
|
|
@@ -7350,7 +7958,7 @@ var DropdownList = React237.forwardRef(
|
|
|
7350
7958
|
setShowTopGradient(scrollTop > 10);
|
|
7351
7959
|
setShowBottomGradient(scrollTop + clientHeight < scrollHeight - 10);
|
|
7352
7960
|
}, []);
|
|
7353
|
-
|
|
7961
|
+
React238.useEffect(() => {
|
|
7354
7962
|
handleScroll();
|
|
7355
7963
|
}, [displayItems, handleScroll]);
|
|
7356
7964
|
const ITEM_HEIGHT = size === "sm" ? 32 : 48;
|
|
@@ -7360,9 +7968,9 @@ var DropdownList = React237.forwardRef(
|
|
|
7360
7968
|
itemHeight: ITEM_HEIGHT,
|
|
7361
7969
|
containerHeight: parsedMaxHeight
|
|
7362
7970
|
});
|
|
7363
|
-
const [focusedIndex, setFocusedIndex] =
|
|
7364
|
-
const [isKeyboardMode, setIsKeyboardMode] =
|
|
7365
|
-
|
|
7971
|
+
const [focusedIndex, setFocusedIndex] = React238.useState(-1);
|
|
7972
|
+
const [isKeyboardMode, setIsKeyboardMode] = React238.useState(false);
|
|
7973
|
+
React238.useEffect(() => {
|
|
7366
7974
|
if (displayItems.length === 0) {
|
|
7367
7975
|
setFocusedIndex(-1);
|
|
7368
7976
|
return;
|
|
@@ -7379,7 +7987,7 @@ var DropdownList = React237.forwardRef(
|
|
|
7379
7987
|
return prev;
|
|
7380
7988
|
});
|
|
7381
7989
|
}, [displayItems, value, mode]);
|
|
7382
|
-
|
|
7990
|
+
React238.useEffect(() => {
|
|
7383
7991
|
if (focusedIndex !== -1 && listRef.current) {
|
|
7384
7992
|
const itemTop = focusedIndex * ITEM_HEIGHT;
|
|
7385
7993
|
const itemBottom = itemTop + ITEM_HEIGHT;
|
|
@@ -7393,7 +8001,7 @@ var DropdownList = React237.forwardRef(
|
|
|
7393
8001
|
}
|
|
7394
8002
|
}
|
|
7395
8003
|
}, [focusedIndex, ITEM_HEIGHT]);
|
|
7396
|
-
const handleListScroll =
|
|
8004
|
+
const handleListScroll = React238.useCallback((e) => {
|
|
7397
8005
|
handleScroll();
|
|
7398
8006
|
if (isVirtual) onVirtualScroll(e);
|
|
7399
8007
|
}, [handleScroll, isVirtual, onVirtualScroll]);
|
|
@@ -7549,7 +8157,7 @@ var DropdownList = React237.forwardRef(
|
|
|
7549
8157
|
tabIndex: -1
|
|
7550
8158
|
}
|
|
7551
8159
|
),
|
|
7552
|
-
item.icon && /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("span", { className: DropdownList_default.dropdownListItemIcon, children:
|
|
8160
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("span", { className: DropdownList_default.dropdownListItemIcon, children: React238.isValidElement(item.icon) ? React238.cloneElement(item.icon, { size: size === "sm" ? 20 : 24 }) : item.icon }),
|
|
7553
8161
|
/* @__PURE__ */ (0, import_jsx_runtime234.jsx)("span", { className: DropdownList_default.dropdownListItemLabel, children: item.label }),
|
|
7554
8162
|
mode === "single" && isSelected(item.value) && /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("span", { className: DropdownList_default.dropdownListCheckmark, children: /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(CheckSmallOutline, { size: size === "sm" ? 20 : 24 }) })
|
|
7555
8163
|
]
|
|
@@ -7596,7 +8204,7 @@ var DropdownList = React237.forwardRef(
|
|
|
7596
8204
|
tabIndex: -1
|
|
7597
8205
|
}
|
|
7598
8206
|
),
|
|
7599
|
-
item.icon && /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("span", { className: DropdownList_default.dropdownListItemIcon, children:
|
|
8207
|
+
item.icon && /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("span", { className: DropdownList_default.dropdownListItemIcon, children: React238.isValidElement(item.icon) ? React238.cloneElement(item.icon, { size: size === "sm" ? 20 : 24 }) : item.icon }),
|
|
7600
8208
|
/* @__PURE__ */ (0, import_jsx_runtime234.jsx)("span", { className: DropdownList_default.dropdownListItemLabel, children: item.label }),
|
|
7601
8209
|
mode === "single" && isSelected(item.value) && /* @__PURE__ */ (0, import_jsx_runtime234.jsx)("span", { className: DropdownList_default.dropdownListCheckmark, children: /* @__PURE__ */ (0, import_jsx_runtime234.jsx)(CheckSmallOutline, { size: size === "sm" ? 20 : 24 }) })
|
|
7602
8210
|
]
|
|
@@ -7621,137 +8229,11 @@ var DropdownList = React237.forwardRef(
|
|
|
7621
8229
|
);
|
|
7622
8230
|
DropdownList.displayName = "DropdownList";
|
|
7623
8231
|
|
|
7624
|
-
// ../ultimate/src/utils/format.utils.ts
|
|
7625
|
-
var formatCurrency = (value, separator = ",", allowDecimal = true, maxDecimals = 2) => {
|
|
7626
|
-
if (!value) return "";
|
|
7627
|
-
const decimalChar = separator === "," ? "." : ",";
|
|
7628
|
-
let cleaned = value.replace(new RegExp(`[^\\d\\${decimalChar}-]`, "g"), "");
|
|
7629
|
-
const isNegative = cleaned.startsWith("-");
|
|
7630
|
-
cleaned = cleaned.replace(/-/g, "");
|
|
7631
|
-
const parts = cleaned.split(decimalChar);
|
|
7632
|
-
let integerPart = parts[0] ?? "";
|
|
7633
|
-
const decimalPart = parts[1];
|
|
7634
|
-
integerPart = integerPart.replace(/^0+(?=\d)/, "");
|
|
7635
|
-
if (integerPart === "") integerPart = "0";
|
|
7636
|
-
integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
|
|
7637
|
-
let result = integerPart;
|
|
7638
|
-
if (allowDecimal && decimalPart !== void 0) {
|
|
7639
|
-
result += decimalChar + decimalPart.slice(0, maxDecimals);
|
|
7640
|
-
}
|
|
7641
|
-
if (isNegative && result !== "0") {
|
|
7642
|
-
result = "-" + result;
|
|
7643
|
-
}
|
|
7644
|
-
return result;
|
|
7645
|
-
};
|
|
7646
|
-
var VN_CALLING_CODE = "84";
|
|
7647
|
-
var E164_MAX_DIGITS = 15;
|
|
7648
|
-
var chunkDigits = (digits, sizes) => {
|
|
7649
|
-
const groups = [];
|
|
7650
|
-
let index = 0;
|
|
7651
|
-
for (const size of sizes) {
|
|
7652
|
-
if (index >= digits.length) break;
|
|
7653
|
-
groups.push(digits.slice(index, index + size));
|
|
7654
|
-
index += size;
|
|
7655
|
-
}
|
|
7656
|
-
return groups;
|
|
7657
|
-
};
|
|
7658
|
-
var genericPhoneGroups = (length) => {
|
|
7659
|
-
if (length <= 5) return [length];
|
|
7660
|
-
const threes = Math.floor(length / 3);
|
|
7661
|
-
switch (length % 3) {
|
|
7662
|
-
case 0:
|
|
7663
|
-
return Array(threes).fill(3);
|
|
7664
|
-
case 1:
|
|
7665
|
-
return [...Array(threes - 1).fill(3), 4];
|
|
7666
|
-
default:
|
|
7667
|
-
return [...Array(threes - 2).fill(3), 4, 4];
|
|
7668
|
-
}
|
|
7669
|
-
};
|
|
7670
|
-
var groupNationalNumber = (nsn, callingCode) => {
|
|
7671
|
-
if (callingCode === VN_CALLING_CODE) {
|
|
7672
|
-
if (/^[35789]/.test(nsn)) return chunkDigits(nsn.slice(0, 9), [3, 3, 3]);
|
|
7673
|
-
if (/^2[48]/.test(nsn)) return chunkDigits(nsn.slice(0, 10), [2, 4, 4]);
|
|
7674
|
-
if (nsn.startsWith("2")) return chunkDigits(nsn.slice(0, 10), [3, 3, 4]);
|
|
7675
|
-
}
|
|
7676
|
-
const capped = nsn.slice(0, E164_MAX_DIGITS - callingCode.length);
|
|
7677
|
-
return chunkDigits(capped, genericPhoneGroups(capped.length));
|
|
7678
|
-
};
|
|
7679
|
-
var parsePhone = (value, options = {}) => {
|
|
7680
|
-
const trimmed = value.trim();
|
|
7681
|
-
let digits = trimmed.replace(/\D/g, "");
|
|
7682
|
-
let hasPlus = trimmed.startsWith("+");
|
|
7683
|
-
if (!hasPlus && digits.startsWith("00")) {
|
|
7684
|
-
hasPlus = true;
|
|
7685
|
-
digits = digits.slice(2);
|
|
7686
|
-
}
|
|
7687
|
-
const fixedCode = options.countryCode?.replace(/\D/g, "");
|
|
7688
|
-
if (fixedCode) {
|
|
7689
|
-
if (hasPlus && digits.startsWith(fixedCode)) digits = digits.slice(fixedCode.length);
|
|
7690
|
-
return { kind: "national", callingCode: fixedCode, nsn: digits.replace(/^0/, "") };
|
|
7691
|
-
}
|
|
7692
|
-
if (hasPlus) {
|
|
7693
|
-
if (!digits.startsWith(VN_CALLING_CODE)) return { kind: "unknown", digits: digits.slice(0, E164_MAX_DIGITS) };
|
|
7694
|
-
return { kind: "international", callingCode: VN_CALLING_CODE, nsn: digits.slice(2).replace(/^0/, "") };
|
|
7695
|
-
}
|
|
7696
|
-
if (/^1[89]00/.test(digits)) return { kind: "service", digits: digits.slice(0, 10) };
|
|
7697
|
-
if (digits.startsWith("0")) return { kind: "trunk", callingCode: VN_CALLING_CODE, nsn: digits.slice(1) };
|
|
7698
|
-
return { kind: "national", callingCode: VN_CALLING_CODE, nsn: digits };
|
|
7699
|
-
};
|
|
7700
|
-
var formatPhone = (value, options) => {
|
|
7701
|
-
if (!value) return "";
|
|
7702
|
-
const parsed = parsePhone(value, options);
|
|
7703
|
-
switch (parsed.kind) {
|
|
7704
|
-
case "unknown":
|
|
7705
|
-
return `+${parsed.digits}`;
|
|
7706
|
-
case "service":
|
|
7707
|
-
return chunkDigits(parsed.digits, parsed.digits.length <= 8 ? [4, 4] : [4, 3, 3]).join(" ");
|
|
7708
|
-
case "international":
|
|
7709
|
-
return [`+${parsed.callingCode}`, ...groupNationalNumber(parsed.nsn, parsed.callingCode)].join(" ");
|
|
7710
|
-
case "trunk": {
|
|
7711
|
-
const groups = groupNationalNumber(parsed.nsn, parsed.callingCode);
|
|
7712
|
-
return groups.length ? `0${groups.join(" ")}` : "0";
|
|
7713
|
-
}
|
|
7714
|
-
case "national":
|
|
7715
|
-
return groupNationalNumber(parsed.nsn, parsed.callingCode).join(" ");
|
|
7716
|
-
}
|
|
7717
|
-
};
|
|
7718
|
-
var BANK_ACCOUNT_MAX_DIGITS = 19;
|
|
7719
|
-
var formatBankAccount = (value) => {
|
|
7720
|
-
if (!value) return "";
|
|
7721
|
-
const digits = value.replace(/\D/g, "").slice(0, BANK_ACCOUNT_MAX_DIGITS);
|
|
7722
|
-
const groups = digits.match(/\d{1,4}/g) ?? [];
|
|
7723
|
-
if (groups.length > 1 && groups[groups.length - 1].length === 1) {
|
|
7724
|
-
const last = groups.pop();
|
|
7725
|
-
groups[groups.length - 1] += last;
|
|
7726
|
-
}
|
|
7727
|
-
return groups.join(" ");
|
|
7728
|
-
};
|
|
7729
|
-
var formatCardNumber = (value) => {
|
|
7730
|
-
if (!value) return "";
|
|
7731
|
-
const digits = value.replace(/[^0-9]/g, "").slice(0, 16);
|
|
7732
|
-
return digits.replace(/(\d{4})(?=\d)/g, "$1 ").trim();
|
|
7733
|
-
};
|
|
7734
|
-
var calculateCursorPosition = (prevValue, nextValue, prevCursorPos) => {
|
|
7735
|
-
if (prevCursorPos <= 0) return 0;
|
|
7736
|
-
const rawBefore = prevValue.slice(0, prevCursorPos).replace(/[^0-9]/g, "");
|
|
7737
|
-
const rawDigitCount = rawBefore.length;
|
|
7738
|
-
let digitsSeen = 0;
|
|
7739
|
-
for (let i = 0; i < nextValue.length; i++) {
|
|
7740
|
-
if (/\d/.test(nextValue[i])) {
|
|
7741
|
-
digitsSeen++;
|
|
7742
|
-
}
|
|
7743
|
-
if (digitsSeen === rawDigitCount) {
|
|
7744
|
-
return i + 1;
|
|
7745
|
-
}
|
|
7746
|
-
}
|
|
7747
|
-
return nextValue.length;
|
|
7748
|
-
};
|
|
7749
|
-
|
|
7750
8232
|
// ../ultimate/src/components/text-field/TextField.module.css
|
|
7751
8233
|
var TextField_default = {};
|
|
7752
8234
|
|
|
7753
8235
|
// ../ultimate/src/internal/form/useNativeFieldReset.ts
|
|
7754
|
-
var
|
|
8236
|
+
var React239 = __toESM(require("react"));
|
|
7755
8237
|
function useNativeFieldReset(ref, resetState, resetValue, formId) {
|
|
7756
8238
|
const reset = useCallbackRef((event) => {
|
|
7757
8239
|
queueMicrotask(() => {
|
|
@@ -7760,7 +8242,7 @@ function useNativeFieldReset(ref, resetState, resetValue, formId) {
|
|
|
7760
8242
|
ref.current.value = resetValue;
|
|
7761
8243
|
});
|
|
7762
8244
|
});
|
|
7763
|
-
|
|
8245
|
+
React239.useEffect(() => {
|
|
7764
8246
|
const form = ref.current?.form;
|
|
7765
8247
|
form?.addEventListener("reset", reset);
|
|
7766
8248
|
return () => form?.removeEventListener("reset", reset);
|
|
@@ -7769,7 +8251,7 @@ function useNativeFieldReset(ref, resetState, resetValue, formId) {
|
|
|
7769
8251
|
|
|
7770
8252
|
// ../ultimate/src/components/text-field/TextField.tsx
|
|
7771
8253
|
var import_jsx_runtime235 = require("react/jsx-runtime");
|
|
7772
|
-
var TextField =
|
|
8254
|
+
var TextField = React240.forwardRef(
|
|
7773
8255
|
({
|
|
7774
8256
|
label,
|
|
7775
8257
|
labelStyle = "outside",
|
|
@@ -7809,15 +8291,16 @@ var TextField = React239.forwardRef(
|
|
|
7809
8291
|
maxLength,
|
|
7810
8292
|
portal = true,
|
|
7811
8293
|
selectOnFocus = false,
|
|
8294
|
+
smartPaste = true,
|
|
7812
8295
|
...props
|
|
7813
8296
|
}, ref) => {
|
|
7814
|
-
const generatedId =
|
|
8297
|
+
const generatedId = React240.useId();
|
|
7815
8298
|
const inputId = props.id ?? generatedId;
|
|
7816
8299
|
const helperId = `${inputId}-help`;
|
|
7817
|
-
const [focused, setFocused] =
|
|
7818
|
-
const [isDropdownOpen, setIsDropdownOpen] =
|
|
7819
|
-
const [passwordVisible, setPasswordVisible] =
|
|
7820
|
-
const inputRef =
|
|
8300
|
+
const [focused, setFocused] = React240.useState(false);
|
|
8301
|
+
const [isDropdownOpen, setIsDropdownOpen] = React240.useState(false);
|
|
8302
|
+
const [passwordVisible, setPasswordVisible] = React240.useState(false);
|
|
8303
|
+
const inputRef = React240.useRef(null);
|
|
7821
8304
|
const [valueState, setValueState, resetValueState] = useControllableState({
|
|
7822
8305
|
value,
|
|
7823
8306
|
defaultValue: defaultValue || "",
|
|
@@ -7835,8 +8318,8 @@ var TextField = React239.forwardRef(
|
|
|
7835
8318
|
defaultValue: defaultTrailingDropdownValue || "",
|
|
7836
8319
|
onChange: onTrailingDropdownChange
|
|
7837
8320
|
});
|
|
7838
|
-
const triggerWrapperRef =
|
|
7839
|
-
const popoverRef =
|
|
8321
|
+
const triggerWrapperRef = React240.useRef(null);
|
|
8322
|
+
const popoverRef = React240.useRef(null);
|
|
7840
8323
|
const { style: popoverStyle } = usePopoverPosition(triggerWrapperRef, popoverRef, isDropdownOpen, {
|
|
7841
8324
|
margin: 8,
|
|
7842
8325
|
strategy: portal ? "fixed" : "absolute",
|
|
@@ -7849,7 +8332,7 @@ var TextField = React239.forwardRef(
|
|
|
7849
8332
|
[triggerWrapperRef]
|
|
7850
8333
|
);
|
|
7851
8334
|
useEscapeKeydown(() => setIsDropdownOpen(false), isDropdownOpen);
|
|
7852
|
-
const keepSelectionOnMouseUpRef =
|
|
8335
|
+
const keepSelectionOnMouseUpRef = React240.useRef(false);
|
|
7853
8336
|
const handleFocus = (e) => {
|
|
7854
8337
|
setFocused(true);
|
|
7855
8338
|
if (selectOnFocus) e.currentTarget.select();
|
|
@@ -7866,14 +8349,14 @@ var TextField = React239.forwardRef(
|
|
|
7866
8349
|
}
|
|
7867
8350
|
props.onMouseUp?.(e);
|
|
7868
8351
|
};
|
|
7869
|
-
const isPhoneFormat =
|
|
8352
|
+
const isPhoneFormat = React240.useMemo(() => {
|
|
7870
8353
|
if (inputFormat) return false;
|
|
7871
8354
|
if (!leadingText) return false;
|
|
7872
8355
|
return (leadingText.startsWith("+") || /^\d+$/.test(leadingText.replace(/[\s()]/g, ""))) && !leadingText.includes("://");
|
|
7873
8356
|
}, [leadingText, inputFormat]);
|
|
7874
8357
|
const activeFormat = inputFormat || (isPhoneFormat ? "phone" : void 0);
|
|
7875
8358
|
const isNumericFormat = activeFormat === "currency" || activeFormat === "phone" || activeFormat === "bankAccount" || activeFormat === "cardNumber";
|
|
7876
|
-
const phoneCountryCode =
|
|
8359
|
+
const phoneCountryCode = React240.useMemo(() => {
|
|
7877
8360
|
if (activeFormat !== "phone") return void 0;
|
|
7878
8361
|
if (formatOptions?.countryCode) return formatOptions.countryCode;
|
|
7879
8362
|
const code = leadingText?.replace(/[\s()]/g, "");
|
|
@@ -7883,7 +8366,7 @@ var TextField = React239.forwardRef(
|
|
|
7883
8366
|
const allowDecimal = formatOptions?.allowDecimal ?? true;
|
|
7884
8367
|
const maxDigits = formatOptions?.maxDigits;
|
|
7885
8368
|
const maxDecimals = formatOptions?.maxDecimals ?? 2;
|
|
7886
|
-
const applyFormat =
|
|
8369
|
+
const applyFormat = React240.useCallback((raw) => {
|
|
7887
8370
|
switch (activeFormat) {
|
|
7888
8371
|
case "currency": {
|
|
7889
8372
|
let cleaned = raw;
|
|
@@ -7909,6 +8392,15 @@ var TextField = React239.forwardRef(
|
|
|
7909
8392
|
return raw;
|
|
7910
8393
|
}
|
|
7911
8394
|
}, [activeFormat, separator, allowDecimal, maxDigits, maxDecimals, phoneCountryCode]);
|
|
8395
|
+
const suggestionKind = activeFormat === "phone" || activeFormat === "bankAccount" ? activeFormat : void 0;
|
|
8396
|
+
const numberSuggestions = useNumberSuggestions({
|
|
8397
|
+
kind: suggestionKind ?? "phone",
|
|
8398
|
+
value: String(currentValue ?? ""),
|
|
8399
|
+
enabled: Boolean(suggestionKind) && smartPaste && !disabled && !readOnly,
|
|
8400
|
+
clipboard: false,
|
|
8401
|
+
limit: 0,
|
|
8402
|
+
onSelect: (raw) => setValueState(applyFormat(raw))
|
|
8403
|
+
});
|
|
7912
8404
|
const handleBlur = (e) => {
|
|
7913
8405
|
setFocused(false);
|
|
7914
8406
|
if (activeFormat && currentValue) {
|
|
@@ -7919,7 +8411,7 @@ var TextField = React239.forwardRef(
|
|
|
7919
8411
|
}
|
|
7920
8412
|
onBlur?.(e);
|
|
7921
8413
|
};
|
|
7922
|
-
|
|
8414
|
+
React240.useEffect(() => {
|
|
7923
8415
|
if (activeFormat && currentValue) {
|
|
7924
8416
|
const formatted = applyFormat(String(currentValue));
|
|
7925
8417
|
if (currentValue !== formatted) {
|
|
@@ -8120,6 +8612,10 @@ var TextField = React239.forwardRef(
|
|
|
8120
8612
|
onMouseDown: handleMouseDown,
|
|
8121
8613
|
onMouseUp: handleMouseUp,
|
|
8122
8614
|
onChange: handleChange,
|
|
8615
|
+
onPaste: (e) => {
|
|
8616
|
+
props.onPaste?.(e);
|
|
8617
|
+
if (!e.defaultPrevented) numberSuggestions.onPaste(e);
|
|
8618
|
+
},
|
|
8123
8619
|
onKeyDown: handleKeyDown,
|
|
8124
8620
|
value: currentValue,
|
|
8125
8621
|
placeholder: shouldShowLabelInside ? "" : placeholder,
|
|
@@ -8248,14 +8744,14 @@ var TextField = React239.forwardRef(
|
|
|
8248
8744
|
TextField.displayName = "TextField";
|
|
8249
8745
|
|
|
8250
8746
|
// ../ultimate/src/components/text-area/TextArea.tsx
|
|
8251
|
-
var
|
|
8747
|
+
var React241 = __toESM(require("react"));
|
|
8252
8748
|
|
|
8253
8749
|
// ../ultimate/src/components/text-area/TextArea.module.css
|
|
8254
8750
|
var TextArea_default = {};
|
|
8255
8751
|
|
|
8256
8752
|
// ../ultimate/src/components/text-area/TextArea.tsx
|
|
8257
8753
|
var import_jsx_runtime236 = require("react/jsx-runtime");
|
|
8258
|
-
var TextArea =
|
|
8754
|
+
var TextArea = React241.forwardRef(
|
|
8259
8755
|
({
|
|
8260
8756
|
label,
|
|
8261
8757
|
labelStyle = "outside",
|
|
@@ -8281,8 +8777,8 @@ var TextArea = React240.forwardRef(
|
|
|
8281
8777
|
fullWidth = true,
|
|
8282
8778
|
...props
|
|
8283
8779
|
}, ref) => {
|
|
8284
|
-
const [focused, setFocused] =
|
|
8285
|
-
const textareaRef =
|
|
8780
|
+
const [focused, setFocused] = React241.useState(false);
|
|
8781
|
+
const textareaRef = React241.useRef(null);
|
|
8286
8782
|
const [valueState, setValueState, resetValueState] = useControllableState({
|
|
8287
8783
|
value,
|
|
8288
8784
|
defaultValue: defaultValue || "",
|
|
@@ -8312,7 +8808,7 @@ var TextArea = React240.forwardRef(
|
|
|
8312
8808
|
}
|
|
8313
8809
|
setValueState(newValue);
|
|
8314
8810
|
};
|
|
8315
|
-
const generatedId =
|
|
8811
|
+
const generatedId = React241.useId();
|
|
8316
8812
|
const shouldShowLabelOutside = label && labelStyle === "outside";
|
|
8317
8813
|
const shouldShowLabelInside = label && labelStyle === "inside";
|
|
8318
8814
|
const textareaId = id ?? generatedId;
|
|
@@ -8400,16 +8896,16 @@ var TextArea = React240.forwardRef(
|
|
|
8400
8896
|
TextArea.displayName = "TextArea";
|
|
8401
8897
|
|
|
8402
8898
|
// ../ultimate/src/components/avatar/Avatar.tsx
|
|
8403
|
-
var
|
|
8899
|
+
var React242 = __toESM(require("react"));
|
|
8404
8900
|
|
|
8405
8901
|
// ../ultimate/src/components/avatar/Avatar.module.css
|
|
8406
8902
|
var Avatar_default = {};
|
|
8407
8903
|
|
|
8408
8904
|
// ../ultimate/src/components/avatar/Avatar.tsx
|
|
8409
8905
|
var import_jsx_runtime237 = require("react/jsx-runtime");
|
|
8410
|
-
var Avatar =
|
|
8906
|
+
var Avatar = React242.forwardRef(
|
|
8411
8907
|
({ src, alt, name, icon, size = "40", status, stroke, className, onClick, ...rest }, ref) => {
|
|
8412
|
-
const [hasError, setHasError] =
|
|
8908
|
+
const [hasError, setHasError] = React242.useState(false);
|
|
8413
8909
|
const isInteractive = !!onClick;
|
|
8414
8910
|
const Component = isInteractive ? "button" : "div";
|
|
8415
8911
|
const getInitials = (userName) => {
|
|
@@ -8467,16 +8963,16 @@ var Avatar = React241.forwardRef(
|
|
|
8467
8963
|
Avatar.displayName = "Avatar";
|
|
8468
8964
|
|
|
8469
8965
|
// ../ultimate/src/components/avatar/AvatarGroup.tsx
|
|
8470
|
-
var
|
|
8966
|
+
var React243 = __toESM(require("react"));
|
|
8471
8967
|
|
|
8472
8968
|
// ../ultimate/src/components/avatar/AvatarGroup.module.css
|
|
8473
8969
|
var AvatarGroup_default = {};
|
|
8474
8970
|
|
|
8475
8971
|
// ../ultimate/src/components/avatar/AvatarGroup.tsx
|
|
8476
8972
|
var import_jsx_runtime238 = require("react/jsx-runtime");
|
|
8477
|
-
var AvatarGroup =
|
|
8973
|
+
var AvatarGroup = React243.forwardRef(
|
|
8478
8974
|
({ children, size = "40", max = 5, showStatus = false, className, ...rest }, ref) => {
|
|
8479
|
-
const childrenArray =
|
|
8975
|
+
const childrenArray = React243.Children.toArray(children);
|
|
8480
8976
|
const hasOverflow = childrenArray.length > max;
|
|
8481
8977
|
const visibleCount = hasOverflow ? max - 1 : childrenArray.length;
|
|
8482
8978
|
const visibleChildren = childrenArray.slice(0, visibleCount);
|
|
@@ -8489,8 +8985,8 @@ var AvatarGroup = React242.forwardRef(
|
|
|
8489
8985
|
].filter(Boolean).join(" ");
|
|
8490
8986
|
return /* @__PURE__ */ (0, import_jsx_runtime238.jsxs)("div", { ref, className: groupClasses, ...rest, children: [
|
|
8491
8987
|
visibleChildren.map((child, index) => {
|
|
8492
|
-
if (
|
|
8493
|
-
return
|
|
8988
|
+
if (React243.isValidElement(child)) {
|
|
8989
|
+
return React243.cloneElement(child, {
|
|
8494
8990
|
size,
|
|
8495
8991
|
stroke: true,
|
|
8496
8992
|
key: index,
|
|
@@ -8520,7 +9016,7 @@ var AvatarGroup = React242.forwardRef(
|
|
|
8520
9016
|
AvatarGroup.displayName = "AvatarGroup";
|
|
8521
9017
|
|
|
8522
9018
|
// ../ultimate/src/components/avatar/AvatarTemplate.tsx
|
|
8523
|
-
var
|
|
9019
|
+
var React244 = __toESM(require("react"));
|
|
8524
9020
|
|
|
8525
9021
|
// ../ultimate/src/img/Image=1.png
|
|
8526
9022
|
var Image_1_default = "./Image=1-LTDZFXMH.png";
|
|
@@ -8552,7 +9048,7 @@ var toImageSrc = (image) => {
|
|
|
8552
9048
|
return image.default;
|
|
8553
9049
|
};
|
|
8554
9050
|
var AVATAR_IMAGES = [Image_1_default, Image_2_default, Image_3_default, Image_4_default, Image_5_default, Image_6_default].map(toImageSrc);
|
|
8555
|
-
var AvatarTemplate =
|
|
9051
|
+
var AvatarTemplate = React244.forwardRef(
|
|
8556
9052
|
({ templateId = 1, ...rest }, ref) => {
|
|
8557
9053
|
const src = AVATAR_IMAGES[templateId - 1];
|
|
8558
9054
|
return /* @__PURE__ */ (0, import_jsx_runtime239.jsx)(Avatar, { ref, src, className: ["phx-avatar-template", rest.className].filter(Boolean).join(" "), ...rest });
|
|
@@ -8598,14 +9094,14 @@ var Image = ({
|
|
|
8598
9094
|
};
|
|
8599
9095
|
|
|
8600
9096
|
// ../ultimate/src/components/skeleton/Skeleton.tsx
|
|
8601
|
-
var
|
|
9097
|
+
var React245 = __toESM(require("react"));
|
|
8602
9098
|
|
|
8603
9099
|
// ../ultimate/src/components/skeleton/Skeleton.module.css
|
|
8604
9100
|
var Skeleton_default = {};
|
|
8605
9101
|
|
|
8606
9102
|
// ../ultimate/src/components/skeleton/Skeleton.tsx
|
|
8607
9103
|
var import_jsx_runtime241 = require("react/jsx-runtime");
|
|
8608
|
-
var Skeleton =
|
|
9104
|
+
var Skeleton = React245.forwardRef(
|
|
8609
9105
|
({ variant = "text", width, height, rounded, className, style, ...rest }, ref) => {
|
|
8610
9106
|
const skeletonClasses = [
|
|
8611
9107
|
"phx-skeleton",
|
|
@@ -8635,17 +9131,18 @@ var Skeleton = React244.forwardRef(
|
|
|
8635
9131
|
Skeleton.displayName = "Skeleton";
|
|
8636
9132
|
|
|
8637
9133
|
// ../ultimate/src/components/chip/Chip.tsx
|
|
8638
|
-
var
|
|
9134
|
+
var React246 = __toESM(require("react"));
|
|
8639
9135
|
|
|
8640
9136
|
// ../ultimate/src/components/chip/Chip.module.css
|
|
8641
9137
|
var Chip_default = {};
|
|
8642
9138
|
|
|
8643
9139
|
// ../ultimate/src/components/chip/Chip.tsx
|
|
8644
9140
|
var import_jsx_runtime242 = require("react/jsx-runtime");
|
|
8645
|
-
var Chip =
|
|
9141
|
+
var Chip = React246.forwardRef(
|
|
8646
9142
|
({
|
|
8647
9143
|
label,
|
|
8648
9144
|
icon,
|
|
9145
|
+
iconOnly,
|
|
8649
9146
|
avatar,
|
|
8650
9147
|
badge,
|
|
8651
9148
|
variant = "outline",
|
|
@@ -8666,6 +9163,8 @@ var Chip = React245.forwardRef(
|
|
|
8666
9163
|
const isClickable = !disabled;
|
|
8667
9164
|
const hasBadgeValue = badge !== void 0 && String(badge).trim() !== "";
|
|
8668
9165
|
const shouldShowBadge = !disabled && hasBadgeValue;
|
|
9166
|
+
const showsIconOnly = Boolean(iconOnly && icon && !avatar);
|
|
9167
|
+
const isIconSquare = showsIconOnly && !shouldShowBadge && !onRemove && !hasDropdown && !(actionIcon && onAction);
|
|
8669
9168
|
const chipClasses = [
|
|
8670
9169
|
"phx-chip",
|
|
8671
9170
|
Chip_default.chipRoot,
|
|
@@ -8676,6 +9175,7 @@ var Chip = React245.forwardRef(
|
|
|
8676
9175
|
isClickable && Chip_default.clickable,
|
|
8677
9176
|
avatar && Chip_default.hasAvatar,
|
|
8678
9177
|
shouldShowBadge && Chip_default.hasBadge,
|
|
9178
|
+
isIconSquare && Chip_default.iconSquare,
|
|
8679
9179
|
className
|
|
8680
9180
|
].filter(Boolean).join(" ");
|
|
8681
9181
|
const badgeColor = variant === "filled" ? "white" : "black";
|
|
@@ -8725,8 +9225,9 @@ var Chip = React245.forwardRef(
|
|
|
8725
9225
|
ref,
|
|
8726
9226
|
className: chipClasses,
|
|
8727
9227
|
onClick: isClickable ? onClick : void 0,
|
|
8728
|
-
role: isClickable ? "button" : void 0,
|
|
9228
|
+
role: isClickable ? "button" : showsIconOnly ? "img" : void 0,
|
|
8729
9229
|
tabIndex: isClickable ? 0 : void 0,
|
|
9230
|
+
"aria-label": showsIconOnly ? label : void 0,
|
|
8730
9231
|
...rest,
|
|
8731
9232
|
onKeyDown: (event) => {
|
|
8732
9233
|
rest.onKeyDown?.(event);
|
|
@@ -8736,13 +9237,13 @@ var Chip = React245.forwardRef(
|
|
|
8736
9237
|
}
|
|
8737
9238
|
},
|
|
8738
9239
|
children: /* @__PURE__ */ (0, import_jsx_runtime242.jsxs)("div", { className: Chip_default.chipContainer, children: [
|
|
8739
|
-
avatar && /* @__PURE__ */ (0, import_jsx_runtime242.jsx)("div", { className: Chip_default.chipAvatar, children:
|
|
9240
|
+
avatar && /* @__PURE__ */ (0, import_jsx_runtime242.jsx)("div", { className: Chip_default.chipAvatar, children: React246.isValidElement(avatar) ? React246.cloneElement(avatar, {
|
|
8740
9241
|
size: size === "large" ? "32" : "24",
|
|
8741
9242
|
stroke: variant === "filled" || avatar.props.stroke
|
|
8742
9243
|
}) : avatar }),
|
|
8743
9244
|
!avatar && icon && /* @__PURE__ */ (0, import_jsx_runtime242.jsx)("span", { className: Chip_default.chipIcon, children: icon }),
|
|
8744
|
-
/* @__PURE__ */ (0, import_jsx_runtime242.jsxs)("span", { className: Chip_default.chipContent, children: [
|
|
8745
|
-
/* @__PURE__ */ (0, import_jsx_runtime242.jsx)("span", { className: Chip_default.chipLabel, children: label }),
|
|
9245
|
+
(!showsIconOnly || shouldShowBadge) && /* @__PURE__ */ (0, import_jsx_runtime242.jsxs)("span", { className: Chip_default.chipContent, children: [
|
|
9246
|
+
!showsIconOnly && /* @__PURE__ */ (0, import_jsx_runtime242.jsx)("span", { className: Chip_default.chipLabel, children: label }),
|
|
8746
9247
|
shouldShowBadge && /* @__PURE__ */ (0, import_jsx_runtime242.jsx)(
|
|
8747
9248
|
Badge,
|
|
8748
9249
|
{
|
|
@@ -8763,23 +9264,23 @@ var Chip = React245.forwardRef(
|
|
|
8763
9264
|
Chip.displayName = "Chip";
|
|
8764
9265
|
|
|
8765
9266
|
// ../ultimate/src/components/chip-bar/ChipBar.tsx
|
|
8766
|
-
var
|
|
9267
|
+
var React248 = __toESM(require("react"));
|
|
8767
9268
|
|
|
8768
9269
|
// ../ultimate/src/components/sticky-stack/StickyStack.tsx
|
|
8769
|
-
var
|
|
9270
|
+
var React247 = __toESM(require("react"));
|
|
8770
9271
|
|
|
8771
9272
|
// ../ultimate/src/components/sticky-stack/StickyStack.module.css
|
|
8772
9273
|
var StickyStack_default = {};
|
|
8773
9274
|
|
|
8774
9275
|
// ../ultimate/src/components/sticky-stack/StickyStack.tsx
|
|
8775
9276
|
var import_jsx_runtime243 = require("react/jsx-runtime");
|
|
8776
|
-
var BarSurfaceContext =
|
|
8777
|
-
var StickyStackItemContext =
|
|
9277
|
+
var BarSurfaceContext = React247.createContext(void 0);
|
|
9278
|
+
var StickyStackItemContext = React247.createContext(false);
|
|
8778
9279
|
function useInStickyStackItem() {
|
|
8779
|
-
return
|
|
9280
|
+
return React247.useContext(StickyStackItemContext);
|
|
8780
9281
|
}
|
|
8781
9282
|
function useBarSurface(surface) {
|
|
8782
|
-
const inherited =
|
|
9283
|
+
const inherited = React247.useContext(BarSurfaceContext);
|
|
8783
9284
|
return surface ?? inherited;
|
|
8784
9285
|
}
|
|
8785
9286
|
function resolveStackSurfaces(entries) {
|
|
@@ -8790,26 +9291,26 @@ function resolveStackSurfaces(entries) {
|
|
|
8790
9291
|
return covered ? "merged" : "elevated";
|
|
8791
9292
|
});
|
|
8792
9293
|
}
|
|
8793
|
-
var StickyStackContext =
|
|
9294
|
+
var StickyStackContext = React247.createContext(null);
|
|
8794
9295
|
var findScrollParent = (element) => {
|
|
8795
9296
|
for (let parent = element.parentElement; parent; parent = parent.parentElement) {
|
|
8796
9297
|
if (/(auto|scroll|overlay)/.test(getComputedStyle(parent).overflowY)) return parent;
|
|
8797
9298
|
}
|
|
8798
9299
|
return null;
|
|
8799
9300
|
};
|
|
8800
|
-
var StickyStackItem =
|
|
9301
|
+
var StickyStackItem = React247.forwardRef(
|
|
8801
9302
|
({ retracted = false, paint = true, onStuckChange, className, children, ...rest }, forwardedRef) => {
|
|
8802
|
-
const id =
|
|
8803
|
-
const stack =
|
|
9303
|
+
const id = React247.useId();
|
|
9304
|
+
const stack = React247.useContext(StickyStackContext);
|
|
8804
9305
|
const report = stack?.report;
|
|
8805
9306
|
const stackSurface = stack?.surfaces.get(id);
|
|
8806
|
-
const elementRef =
|
|
9307
|
+
const elementRef = React247.useRef(null);
|
|
8807
9308
|
const ref = useComposedRefs(forwardedRef, elementRef);
|
|
8808
|
-
const [stuck, setStuck] =
|
|
8809
|
-
const checkRef =
|
|
9309
|
+
const [stuck, setStuck] = React247.useState(false);
|
|
9310
|
+
const checkRef = React247.useRef(() => {
|
|
8810
9311
|
});
|
|
8811
9312
|
const notifyStuck = useCallbackRef(onStuckChange);
|
|
8812
|
-
|
|
9313
|
+
React247.useEffect(() => {
|
|
8813
9314
|
const element = elementRef.current;
|
|
8814
9315
|
if (!element) return;
|
|
8815
9316
|
const check = () => {
|
|
@@ -8832,8 +9333,8 @@ var StickyStackItem = React246.forwardRef(
|
|
|
8832
9333
|
window.removeEventListener("resize", check);
|
|
8833
9334
|
};
|
|
8834
9335
|
}, []);
|
|
8835
|
-
|
|
8836
|
-
|
|
9336
|
+
React247.useEffect(() => checkRef.current());
|
|
9337
|
+
React247.useEffect(() => {
|
|
8837
9338
|
notifyStuck(stuck);
|
|
8838
9339
|
}, [stuck, notifyStuck]);
|
|
8839
9340
|
useIsomorphicLayoutEffect(() => {
|
|
@@ -8875,7 +9376,7 @@ var ChipBar_default = {};
|
|
|
8875
9376
|
var import_jsx_runtime244 = require("react/jsx-runtime");
|
|
8876
9377
|
var OVERFLOW_BUTTON_SIZE = 32;
|
|
8877
9378
|
var MASK_FADE_SIZE = 44;
|
|
8878
|
-
var ChipBar =
|
|
9379
|
+
var ChipBar = React248.forwardRef(
|
|
8879
9380
|
({
|
|
8880
9381
|
leading,
|
|
8881
9382
|
children,
|
|
@@ -8890,13 +9391,13 @@ var ChipBar = React247.forwardRef(
|
|
|
8890
9391
|
}, ref) => {
|
|
8891
9392
|
const surface = useBarSurface(surfaceProp);
|
|
8892
9393
|
const sticky = useInStickyStackItem() ? false : stickyProp;
|
|
8893
|
-
const [showLeftGradient, setShowLeftGradient] =
|
|
8894
|
-
const [showRightGradient, setShowRightGradient] =
|
|
8895
|
-
const [internalIsStuck, setInternalIsStuck] =
|
|
9394
|
+
const [showLeftGradient, setShowLeftGradient] = React248.useState(false);
|
|
9395
|
+
const [showRightGradient, setShowRightGradient] = React248.useState(false);
|
|
9396
|
+
const [internalIsStuck, setInternalIsStuck] = React248.useState(false);
|
|
8896
9397
|
const isStuck = stuck !== void 0 ? stuck : internalIsStuck;
|
|
8897
|
-
const listRef =
|
|
8898
|
-
const containerRef =
|
|
8899
|
-
const updateScrollGradients =
|
|
9398
|
+
const listRef = React248.useRef(null);
|
|
9399
|
+
const containerRef = React248.useRef(null);
|
|
9400
|
+
const updateScrollGradients = React248.useCallback(() => {
|
|
8900
9401
|
const el = listRef.current;
|
|
8901
9402
|
if (el) {
|
|
8902
9403
|
const { scrollLeft, scrollWidth, clientWidth } = el;
|
|
@@ -8904,7 +9405,7 @@ var ChipBar = React247.forwardRef(
|
|
|
8904
9405
|
setShowRightGradient(Math.ceil(scrollLeft + clientWidth) < scrollWidth);
|
|
8905
9406
|
}
|
|
8906
9407
|
}, []);
|
|
8907
|
-
|
|
9408
|
+
React248.useEffect(() => {
|
|
8908
9409
|
const el = listRef.current;
|
|
8909
9410
|
if (el) {
|
|
8910
9411
|
updateScrollGradients();
|
|
@@ -8931,7 +9432,7 @@ var ChipBar = React247.forwardRef(
|
|
|
8931
9432
|
});
|
|
8932
9433
|
}
|
|
8933
9434
|
};
|
|
8934
|
-
|
|
9435
|
+
React248.useEffect(() => {
|
|
8935
9436
|
if (!sticky || surface !== void 0) return;
|
|
8936
9437
|
const container = containerRef.current;
|
|
8937
9438
|
if (!container) return;
|
|
@@ -8963,7 +9464,7 @@ var ChipBar = React247.forwardRef(
|
|
|
8963
9464
|
window.removeEventListener("resize", checkStuck);
|
|
8964
9465
|
};
|
|
8965
9466
|
}, [sticky, surface]);
|
|
8966
|
-
const setRefs =
|
|
9467
|
+
const setRefs = React248.useCallback((node) => {
|
|
8967
9468
|
containerRef.current = node;
|
|
8968
9469
|
if (typeof ref === "function") {
|
|
8969
9470
|
ref(node);
|
|
@@ -8999,7 +9500,7 @@ var ChipBar = React247.forwardRef(
|
|
|
8999
9500
|
...rest,
|
|
9000
9501
|
children: [
|
|
9001
9502
|
leading && /* @__PURE__ */ (0, import_jsx_runtime244.jsxs)("div", { className: ChipBar_default.chipBarLeading, children: [
|
|
9002
|
-
|
|
9503
|
+
React248.isValidElement(leading) ? React248.cloneElement(leading, {
|
|
9003
9504
|
size: size === "large" ? "large" : "medium"
|
|
9004
9505
|
}) : leading,
|
|
9005
9506
|
showDivider && /* @__PURE__ */ (0, import_jsx_runtime244.jsx)("div", { className: ChipBar_default.chipBarDivider })
|
|
@@ -9039,9 +9540,9 @@ var ChipBar = React247.forwardRef(
|
|
|
9039
9540
|
"scrollbarHidden",
|
|
9040
9541
|
"phx-chip-bar-list"
|
|
9041
9542
|
].filter(Boolean).join(" "),
|
|
9042
|
-
children:
|
|
9043
|
-
if (
|
|
9044
|
-
return
|
|
9543
|
+
children: React248.Children.map(children, (child) => {
|
|
9544
|
+
if (React248.isValidElement(child)) {
|
|
9545
|
+
return React248.cloneElement(child, {
|
|
9045
9546
|
size: size === "large" ? "large" : "medium"
|
|
9046
9547
|
});
|
|
9047
9548
|
}
|
|
@@ -9082,9 +9583,9 @@ var ChipBar = React247.forwardRef(
|
|
|
9082
9583
|
ChipBar.displayName = "ChipBar";
|
|
9083
9584
|
|
|
9084
9585
|
// ../ultimate/src/components/visually-hidden/VisuallyHidden.tsx
|
|
9085
|
-
var
|
|
9586
|
+
var React249 = __toESM(require("react"));
|
|
9086
9587
|
var import_jsx_runtime245 = require("react/jsx-runtime");
|
|
9087
|
-
var VisuallyHidden =
|
|
9588
|
+
var VisuallyHidden = React249.forwardRef(
|
|
9088
9589
|
({ as, children, className, style, ...props }, ref) => {
|
|
9089
9590
|
const Component = as || "span";
|
|
9090
9591
|
return /* @__PURE__ */ (0, import_jsx_runtime245.jsx)(
|
|
@@ -9114,26 +9615,150 @@ var VisuallyHidden = React248.forwardRef(
|
|
|
9114
9615
|
VisuallyHidden.displayName = "VisuallyHidden";
|
|
9115
9616
|
|
|
9116
9617
|
// ../ultimate/src/components/layout-context/LayoutContext.tsx
|
|
9117
|
-
var
|
|
9618
|
+
var React251 = __toESM(require("react"));
|
|
9619
|
+
|
|
9620
|
+
// ../ultimate/src/components/layout-context/shell.ts
|
|
9621
|
+
var React250 = __toESM(require("react"));
|
|
9622
|
+
var ShellStore = class {
|
|
9623
|
+
state = {
|
|
9624
|
+
drawerFloating: false,
|
|
9625
|
+
drawerCount: 0,
|
|
9626
|
+
open: false,
|
|
9627
|
+
parentId: null,
|
|
9628
|
+
selectedRailId: null,
|
|
9629
|
+
noDrawer: /* @__PURE__ */ new Set()
|
|
9630
|
+
};
|
|
9631
|
+
listeners = /* @__PURE__ */ new Set();
|
|
9632
|
+
railClicks = /* @__PURE__ */ new Map();
|
|
9633
|
+
closeTimer;
|
|
9634
|
+
floatingDrawers = 0;
|
|
9635
|
+
/** Delay (ms) before the card closes, so the pointer can cross from the rail item to it. */
|
|
9636
|
+
closeDelay = 200;
|
|
9637
|
+
subscribe = (listener) => {
|
|
9638
|
+
this.listeners.add(listener);
|
|
9639
|
+
return () => {
|
|
9640
|
+
this.listeners.delete(listener);
|
|
9641
|
+
};
|
|
9642
|
+
};
|
|
9643
|
+
getSnapshot = () => this.state;
|
|
9644
|
+
set(patch) {
|
|
9645
|
+
this.state = { ...this.state, ...patch };
|
|
9646
|
+
this.listeners.forEach((listener) => listener());
|
|
9647
|
+
}
|
|
9648
|
+
reconcileQueued = false;
|
|
9649
|
+
/**
|
|
9650
|
+
* After a commit (rail items and drawers report in effects, in tree order), note whether the
|
|
9651
|
+
* selected item's page has a drawer.
|
|
9652
|
+
*/
|
|
9653
|
+
reconcile() {
|
|
9654
|
+
if (this.reconcileQueued) return;
|
|
9655
|
+
this.reconcileQueued = true;
|
|
9656
|
+
queueMicrotask(() => {
|
|
9657
|
+
this.reconcileQueued = false;
|
|
9658
|
+
const { selectedRailId: id, drawerCount, noDrawer } = this.state;
|
|
9659
|
+
if (!id) return;
|
|
9660
|
+
const without = drawerCount === 0;
|
|
9661
|
+
if (without === noDrawer.has(id)) return;
|
|
9662
|
+
const next = new Set(noDrawer);
|
|
9663
|
+
if (without) next.add(id);
|
|
9664
|
+
else next.delete(id);
|
|
9665
|
+
this.set({ noDrawer: next });
|
|
9666
|
+
});
|
|
9667
|
+
}
|
|
9668
|
+
/** A drawer joins (`+1`) or leaves (`-1`) the layout. */
|
|
9669
|
+
drawerMounted(delta) {
|
|
9670
|
+
this.set({ drawerCount: Math.max(0, this.state.drawerCount + delta) });
|
|
9671
|
+
this.reconcile();
|
|
9672
|
+
if (this.state.drawerCount === 0) this.close();
|
|
9673
|
+
}
|
|
9674
|
+
/** A drawer starts (`true`) or stops floating. */
|
|
9675
|
+
drawerFloats(floating) {
|
|
9676
|
+
this.floatingDrawers = Math.max(0, this.floatingDrawers + (floating ? 1 : -1));
|
|
9677
|
+
const drawerFloating = this.floatingDrawers > 0;
|
|
9678
|
+
if (drawerFloating !== this.state.drawerFloating) this.set({ drawerFloating });
|
|
9679
|
+
if (!drawerFloating) this.close();
|
|
9680
|
+
}
|
|
9681
|
+
/** A rail item reports its click handler; the selected one also marks itself. */
|
|
9682
|
+
railItem(id, selected, onClick) {
|
|
9683
|
+
if (onClick) this.railClicks.set(id, onClick);
|
|
9684
|
+
else this.railClicks.delete(id);
|
|
9685
|
+
if (selected && this.state.selectedRailId !== id) this.set({ selectedRailId: id });
|
|
9686
|
+
if (selected) this.reconcile();
|
|
9687
|
+
return () => {
|
|
9688
|
+
if (this.railClicks.get(id) === onClick) this.railClicks.delete(id);
|
|
9689
|
+
};
|
|
9690
|
+
}
|
|
9691
|
+
/**
|
|
9692
|
+
* Whether a rail item reveals the floating drawer: any item, while a drawer floats in the
|
|
9693
|
+
* shell, except one whose page turned out to have none. `hint` (NavItem `hasDrawer`) decides
|
|
9694
|
+
* outright when given.
|
|
9695
|
+
*/
|
|
9696
|
+
isParent(id, hint) {
|
|
9697
|
+
const { drawerFloating, drawerCount, noDrawer } = this.state;
|
|
9698
|
+
if (!drawerFloating || drawerCount === 0) return false;
|
|
9699
|
+
return hint ?? !noDrawer.has(id);
|
|
9700
|
+
}
|
|
9701
|
+
/** Opens at once; closing waits `closeDelay` and any open on the way cancels it. */
|
|
9702
|
+
setOpen = (open) => {
|
|
9703
|
+
clearTimeout(this.closeTimer);
|
|
9704
|
+
if (open) {
|
|
9705
|
+
if (!this.state.open) this.set({ open: true });
|
|
9706
|
+
} else {
|
|
9707
|
+
this.closeTimer = setTimeout(() => {
|
|
9708
|
+
if (this.state.open) this.set({ open: false });
|
|
9709
|
+
}, this.closeDelay);
|
|
9710
|
+
}
|
|
9711
|
+
};
|
|
9712
|
+
/** Pointer or focus entering / leaving a parent rail item. */
|
|
9713
|
+
hoverParent(id, hovering) {
|
|
9714
|
+
if (hovering && this.state.parentId !== id) this.set({ parentId: id });
|
|
9715
|
+
this.setOpen(hovering);
|
|
9716
|
+
}
|
|
9717
|
+
/** The app's own drawer toggle, while floating: show the card for the selected item, or hide it. */
|
|
9718
|
+
toggleForSelected() {
|
|
9719
|
+
if (this.state.open) {
|
|
9720
|
+
this.close();
|
|
9721
|
+
return;
|
|
9722
|
+
}
|
|
9723
|
+
clearTimeout(this.closeTimer);
|
|
9724
|
+
this.set({ open: true, parentId: this.state.selectedRailId });
|
|
9725
|
+
}
|
|
9726
|
+
close = () => {
|
|
9727
|
+
clearTimeout(this.closeTimer);
|
|
9728
|
+
if (this.state.open) this.set({ open: false });
|
|
9729
|
+
};
|
|
9730
|
+
/** An item was chosen in the floating card: go to the page it was opened from, then close. */
|
|
9731
|
+
choose() {
|
|
9732
|
+
const { parentId, selectedRailId, open } = this.state;
|
|
9733
|
+
if (!open) return;
|
|
9734
|
+
if (parentId && parentId !== selectedRailId) this.railClicks.get(parentId)?.(parentId);
|
|
9735
|
+
this.close();
|
|
9736
|
+
}
|
|
9737
|
+
};
|
|
9738
|
+
var defaultShellStore = new ShellStore();
|
|
9739
|
+
|
|
9740
|
+
// ../ultimate/src/components/layout-context/LayoutContext.tsx
|
|
9118
9741
|
var import_jsx_runtime246 = require("react/jsx-runtime");
|
|
9119
|
-
var LayoutContext =
|
|
9742
|
+
var LayoutContext = React251.createContext(null);
|
|
9120
9743
|
var LayoutProvider = ({ children }) => {
|
|
9121
|
-
const [drawerCount, setDrawerCount] =
|
|
9122
|
-
const
|
|
9123
|
-
const
|
|
9124
|
-
const
|
|
9744
|
+
const [drawerCount, setDrawerCount] = React251.useState(0);
|
|
9745
|
+
const [shell] = React251.useState(() => new ShellStore());
|
|
9746
|
+
const registerDrawer = React251.useCallback(() => setDrawerCount((count) => count + 1), []);
|
|
9747
|
+
const unregisterDrawer = React251.useCallback(() => setDrawerCount((count) => Math.max(0, count - 1)), []);
|
|
9748
|
+
const value = React251.useMemo(() => ({
|
|
9125
9749
|
hasDrawer: drawerCount > 0,
|
|
9126
9750
|
registerDrawer,
|
|
9127
|
-
unregisterDrawer
|
|
9128
|
-
|
|
9751
|
+
unregisterDrawer,
|
|
9752
|
+
shell
|
|
9753
|
+
}), [drawerCount, registerDrawer, unregisterDrawer, shell]);
|
|
9129
9754
|
return /* @__PURE__ */ (0, import_jsx_runtime246.jsx)(LayoutContext.Provider, { value, children });
|
|
9130
9755
|
};
|
|
9131
9756
|
var useLayout = () => {
|
|
9132
|
-
return
|
|
9757
|
+
return React251.useContext(LayoutContext);
|
|
9133
9758
|
};
|
|
9134
9759
|
|
|
9135
9760
|
// ../ultimate/src/components/number-field/NumberField.tsx
|
|
9136
|
-
var
|
|
9761
|
+
var React252 = __toESM(require("react"));
|
|
9137
9762
|
var import_jsx_runtime247 = require("react/jsx-runtime");
|
|
9138
9763
|
var parseNumber = (text) => {
|
|
9139
9764
|
const normalized = text.trim().replace(",", ".");
|
|
@@ -9165,8 +9790,8 @@ function NumberField({
|
|
|
9165
9790
|
defaultValue,
|
|
9166
9791
|
onChange
|
|
9167
9792
|
});
|
|
9168
|
-
const ref =
|
|
9169
|
-
const [draft, setDraft] =
|
|
9793
|
+
const ref = React252.useRef(null);
|
|
9794
|
+
const [draft, setDraft] = React252.useState(null);
|
|
9170
9795
|
const display = draft ?? (current == null ? "" : String(current));
|
|
9171
9796
|
const resetValue = String((value !== void 0 ? current : defaultValue) ?? "");
|
|
9172
9797
|
useNativeFieldReset(
|
|
@@ -9196,7 +9821,7 @@ function NumberField({
|
|
|
9196
9821
|
)
|
|
9197
9822
|
);
|
|
9198
9823
|
};
|
|
9199
|
-
const generatedId =
|
|
9824
|
+
const generatedId = React252.useId();
|
|
9200
9825
|
const inputId = props.id ?? generatedId;
|
|
9201
9826
|
const descriptionId = description ? `${inputId}-description` : void 0;
|
|
9202
9827
|
const errorId = error ? `${inputId}-error` : void 0;
|
|
@@ -9314,17 +9939,17 @@ function NumberField({
|
|
|
9314
9939
|
}
|
|
9315
9940
|
|
|
9316
9941
|
// ../ultimate/src/components/rating/Rating.tsx
|
|
9317
|
-
var
|
|
9942
|
+
var React254 = __toESM(require("react"));
|
|
9318
9943
|
|
|
9319
9944
|
// ../ultimate/src/components/star/Star.tsx
|
|
9320
|
-
var
|
|
9945
|
+
var React253 = __toESM(require("react"));
|
|
9321
9946
|
|
|
9322
9947
|
// ../ultimate/src/components/star/Star.module.css
|
|
9323
9948
|
var Star_default = {};
|
|
9324
9949
|
|
|
9325
9950
|
// ../ultimate/src/components/star/Star.tsx
|
|
9326
9951
|
var import_jsx_runtime248 = require("react/jsx-runtime");
|
|
9327
|
-
var Star =
|
|
9952
|
+
var Star = React253.forwardRef(
|
|
9328
9953
|
({
|
|
9329
9954
|
className,
|
|
9330
9955
|
checked = false,
|
|
@@ -9335,8 +9960,8 @@ var Star = React251.forwardRef(
|
|
|
9335
9960
|
onClick,
|
|
9336
9961
|
...rest
|
|
9337
9962
|
}, ref) => {
|
|
9338
|
-
const [pressed, setPressed] =
|
|
9339
|
-
const timeoutRef =
|
|
9963
|
+
const [pressed, setPressed] = React253.useState(false);
|
|
9964
|
+
const timeoutRef = React253.useRef(null);
|
|
9340
9965
|
const iconSize = size === "small" ? 20 : 24;
|
|
9341
9966
|
const handleClick = (e) => {
|
|
9342
9967
|
if (disabled) return;
|
|
@@ -9350,7 +9975,7 @@ var Star = React251.forwardRef(
|
|
|
9350
9975
|
onClick(e);
|
|
9351
9976
|
}
|
|
9352
9977
|
};
|
|
9353
|
-
|
|
9978
|
+
React253.useEffect(() => {
|
|
9354
9979
|
return () => {
|
|
9355
9980
|
if (timeoutRef.current) clearTimeout(timeoutRef.current);
|
|
9356
9981
|
};
|
|
@@ -9405,7 +10030,7 @@ function Rating({
|
|
|
9405
10030
|
defaultValue,
|
|
9406
10031
|
onChange
|
|
9407
10032
|
});
|
|
9408
|
-
const hidden =
|
|
10033
|
+
const hidden = React254.useRef(null);
|
|
9409
10034
|
const normalize = (rating) => Number.isFinite(rating) ? Math.max(0, Math.min(count, Math.round(rating))) : 0;
|
|
9410
10035
|
const selected = normalize(current);
|
|
9411
10036
|
useNativeFieldReset(
|
|
@@ -9486,7 +10111,7 @@ function Rating({
|
|
|
9486
10111
|
}
|
|
9487
10112
|
|
|
9488
10113
|
// ../ultimate/src/components/otp/OTP.tsx
|
|
9489
|
-
var
|
|
10114
|
+
var React255 = __toESM(require("react"));
|
|
9490
10115
|
var import_react_dom3 = require("react-dom");
|
|
9491
10116
|
|
|
9492
10117
|
// ../ultimate/src/components/otp/OTP.module.css
|
|
@@ -9525,27 +10150,27 @@ function OTP({
|
|
|
9525
10150
|
defaultValue: normalize(defaultValue),
|
|
9526
10151
|
onChange
|
|
9527
10152
|
});
|
|
9528
|
-
const [local, setLocal] =
|
|
9529
|
-
const pending =
|
|
10153
|
+
const [local, setLocal] = React255.useState(() => split(value ?? defaultValue));
|
|
10154
|
+
const pending = React255.useRef(null);
|
|
9530
10155
|
const digits = value === void 0 ? Array.from({ length: count }, (_, index) => local[index] ?? "") : pending.current?.code === normalize(code) ? Array.from(
|
|
9531
10156
|
{ length: count },
|
|
9532
10157
|
(_, index) => pending.current.digits[index] ?? ""
|
|
9533
10158
|
) : split(code);
|
|
9534
|
-
const currentDigits =
|
|
10159
|
+
const currentDigits = React255.useRef(digits);
|
|
9535
10160
|
currentDigits.current = digits;
|
|
9536
|
-
const composing =
|
|
9537
|
-
const picked =
|
|
9538
|
-
const inputs =
|
|
9539
|
-
const first =
|
|
9540
|
-
const previousReadOnly =
|
|
9541
|
-
|
|
10161
|
+
const composing = React255.useRef(null);
|
|
10162
|
+
const picked = React255.useRef(false);
|
|
10163
|
+
const inputs = React255.useRef([]);
|
|
10164
|
+
const first = React255.useRef(null);
|
|
10165
|
+
const previousReadOnly = React255.useRef(readOnly);
|
|
10166
|
+
React255.useEffect(() => {
|
|
9542
10167
|
if (readOnly && !previousReadOnly.current) {
|
|
9543
10168
|
const active = inputs.current.find((input) => input === document.activeElement);
|
|
9544
10169
|
active?.blur();
|
|
9545
10170
|
}
|
|
9546
10171
|
previousReadOnly.current = readOnly;
|
|
9547
10172
|
}, [readOnly]);
|
|
9548
|
-
const id =
|
|
10173
|
+
const id = React255.useId();
|
|
9549
10174
|
const supportingText = error || helperText;
|
|
9550
10175
|
const supportingId = error ? `${id}-error` : helperText ? `${id}-helper` : void 0;
|
|
9551
10176
|
const focus = (index) => inputs.current[index]?.focus({ preventScroll: true });
|
|
@@ -9582,10 +10207,10 @@ function OTP({
|
|
|
9582
10207
|
const nextIndex = sequential ? nextCell(next) : Math.min(count - 1, start + text.length);
|
|
9583
10208
|
if (text && !inputs.current[nextIndex]?.readOnly) focus(nextIndex);
|
|
9584
10209
|
};
|
|
9585
|
-
|
|
10210
|
+
React255.useEffect(() => {
|
|
9586
10211
|
if (autoFocus && !disabled && !readOnly) focus(sequential ? nextCell(currentDigits.current) : 0);
|
|
9587
10212
|
}, []);
|
|
9588
|
-
|
|
10213
|
+
React255.useEffect(() => {
|
|
9589
10214
|
const cleanups = inputs.current.slice(0, count).map((input, index) => {
|
|
9590
10215
|
if (!input) return () => {
|
|
9591
10216
|
};
|
|
@@ -9643,7 +10268,7 @@ function OTP({
|
|
|
9643
10268
|
gap: dotFields ? "md" : "4xs",
|
|
9644
10269
|
maxW: "100%",
|
|
9645
10270
|
w: `calc(${columns} * ${cellWidth}px + ${columns - 1 + separatorCount} * var(${dotFields ? "--space-md" : "--space-4xs"}) + ${separatorCount} * var(--dimensions-12))`,
|
|
9646
|
-
children: Array.from({ length: count }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime250.jsxs)(
|
|
10271
|
+
children: Array.from({ length: count }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime250.jsxs)(React255.Fragment, { children: [
|
|
9647
10272
|
separates(index % columns) && /* @__PURE__ */ (0, import_jsx_runtime250.jsx)(Text, { as: "span", "aria-hidden": "true", className: OTP_default.separator, children: "-" }),
|
|
9648
10273
|
/* @__PURE__ */ (0, import_jsx_runtime250.jsxs)(Text, { as: "span", className: `${OTP_default.cellSlot} ${OTP_default[size]} ${dotFields ? OTP_default.dotField : ""}`, variant: size === "large" ? "headline-sm" : size === "medium" ? "title-lg" : "title-md", weight: "medium", children: [
|
|
9649
10274
|
/* @__PURE__ */ (0, import_jsx_runtime250.jsx)(
|
|
@@ -9782,7 +10407,7 @@ function PIN({ length = 4, "aria-label": accessibleLabel = "PIN", autoFocus = tr
|
|
|
9782
10407
|
}
|
|
9783
10408
|
|
|
9784
10409
|
// ../ultimate/src/components/empty/Empty.tsx
|
|
9785
|
-
var
|
|
10410
|
+
var React256 = __toESM(require("react"));
|
|
9786
10411
|
var import_jsx_runtime252 = require("react/jsx-runtime");
|
|
9787
10412
|
function Empty({
|
|
9788
10413
|
title = "No results",
|
|
@@ -9790,7 +10415,7 @@ function Empty({
|
|
|
9790
10415
|
icon,
|
|
9791
10416
|
action
|
|
9792
10417
|
}) {
|
|
9793
|
-
const titleId =
|
|
10418
|
+
const titleId = React256.useId();
|
|
9794
10419
|
return /* @__PURE__ */ (0, import_jsx_runtime252.jsxs)(
|
|
9795
10420
|
VStack,
|
|
9796
10421
|
{
|
|
@@ -9813,7 +10438,7 @@ function Empty({
|
|
|
9813
10438
|
}
|
|
9814
10439
|
|
|
9815
10440
|
// ../ultimate/src/components/result/Result.tsx
|
|
9816
|
-
var
|
|
10441
|
+
var React257 = __toESM(require("react"));
|
|
9817
10442
|
var import_illustrations = require("@photonix/illustrations");
|
|
9818
10443
|
var import_jsx_runtime253 = require("react/jsx-runtime");
|
|
9819
10444
|
var STATUS_ILLUSTRATION = {
|
|
@@ -9823,7 +10448,7 @@ var STATUS_ILLUSTRATION = {
|
|
|
9823
10448
|
info: import_illustrations.Information
|
|
9824
10449
|
};
|
|
9825
10450
|
function Result({ status, title, description, action }) {
|
|
9826
|
-
const titleId =
|
|
10451
|
+
const titleId = React257.useId();
|
|
9827
10452
|
const StatusIllustration = STATUS_ILLUSTRATION[status];
|
|
9828
10453
|
return /* @__PURE__ */ (0, import_jsx_runtime253.jsxs)(
|
|
9829
10454
|
VStack,
|