UNPKG

@kopexa/sight

Version:

Kopexa Sight Design System — React component library for GRC applications

1,555 lines (1,534 loc) 62.3 kB
"use client"; "use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/components/index.ts var components_exports = {}; __export(components_exports, { ALPHA2_TO_ALPHA3: () => ALPHA2_TO_ALPHA3, ALPHA3_TO_ALPHA2: () => ALPHA3_TO_ALPHA2, Accordion: () => namespace_exports, AccordionContent: () => AccordionContent, AccordionItem: () => AccordionItem, AccordionRoot: () => AccordionRoot, AccordionTrigger: () => AccordionTrigger, AvatarUpload: () => AvatarUpload, Blankstate: () => Blankstate, COUNTRY_ALPHA2: () => COUNTRY_ALPHA2, Code: () => Code, CountryPicker: () => CountryPicker, Dialog: () => Dialog, DialogBody: () => DialogBody, DialogClose: () => DialogClose, DialogCloseTrigger: () => DialogCloseTrigger, DialogContent: () => DialogContent, DialogDescription: () => DialogDescription, DialogFooter: () => DialogFooter, DialogHeader: () => DialogHeader, DialogOverlay: () => DialogOverlay, DialogPortal: () => DialogPortal, DialogRoot: () => DialogRoot, DialogTitle: () => DialogTitle, DialogTrigger: () => DialogTrigger, FlagIcon: () => FlagIcon, RadioCardItem: () => RadioCardItem, RadioCardItemBase: () => RadioCardItemBase, RadioCardItemContent: () => RadioCardItemContent, RadioCardItemControl: () => RadioCardItemControl, RadioCardItemDescription: () => RadioCardItemDescription, RadioCardItemHiddenInput: () => RadioCardItemHiddenInput, RadioCardItemIndicator: () => RadioCardItemIndicator, RadioCardItemText: () => RadioCardItemText, RadioCardLabel: () => RadioCardLabel, RadioCardRoot: () => RadioCardRoot, Radiomark: () => Radiomark, Skeleton: () => Skeleton, SkeletonAvatar: () => SkeletonAvatar, Stat: () => Stat, StatDownIndicator: () => StatDownIndicator, StatGroup: () => StatGroup, StatHelpText: () => StatHelpText, StatLabel: () => StatLabel, StatRoot: () => StatRoot, StatUpIndicator: () => StatUpIndicator, StatValueText: () => StatValueText, StatValueUnit: () => StatValueUnit, Textarea: () => Textarea, getCountries: () => getCountries, getCountryName: () => getCountryName, toAlpha2: () => toAlpha2, toAlpha3: () => toAlpha3, toFormat: () => toFormat, useDialogContext: () => useDialogContext }); module.exports = __toCommonJS(components_exports); // src/components/accordion/accordion.tsx var import_icons = require("@kopexa/icons"); var import_react_utils = require("@kopexa/react-utils"); var import_shared_utils = require("@kopexa/shared-utils"); var import_theme = require("@kopexa/theme"); var import_react = require("react"); var import_react_aria_components = require("react-aria-components"); var import_jsx_runtime = require("react/jsx-runtime"); var [Provider, useProvider] = (0, import_react_utils.createContext)(); function toKeySet(value) { if (value === void 0) return void 0; if (Array.isArray(value)) return new Set(value); return new Set(value ? [value] : []); } function AccordionRoot({ type = "single", value, defaultValue, onValueChange, // `collapsible` is accepted for compatibility but not forwarded — react-aria's // single mode is already collapsible. collapsible: _collapsible, disabled, className, color, radius, spacing, border, triggerSpacing, children, id }) { const styles = (0, import_theme.accordion)({ color, radius, spacing, border, triggerSpacing }); const isMultiple = type === "multiple"; return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Provider, { value: { styles }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_react_aria_components.DisclosureGroup, { id, "data-slot": "accordion", allowsMultipleExpanded: isMultiple, expandedKeys: value !== void 0 ? toKeySet(value) : void 0, defaultExpandedKeys: defaultValue !== void 0 ? toKeySet(defaultValue) : void 0, onExpandedChange: onValueChange ? (keys) => { var _a; const list = [...keys]; onValueChange( isMultiple ? list : (_a = list[0]) != null ? _a : "" ); } : void 0, isDisabled: disabled, className: styles.root({ className }), children } ) }); } function AccordionItem({ value, disabled, className, children }) { const { styles } = useProvider(); return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_react_aria_components.Disclosure, { id: value, isDisabled: disabled, "data-slot": "accordion-item", className: styles.item({ className }), children } ); } function AccordionTrigger({ className, children, action, id, disabled }) { const { styles } = useProvider(); const state = (0, import_react.useContext)(import_react_aria_components.DisclosureStateContext); const dataState = (state == null ? void 0 : state.isExpanded) ? "open" : "closed"; return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_aria_components.Heading, { className: "flex items-center", children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)( import_react_aria_components.Button, { slot: "trigger", id, isDisabled: disabled, "data-slot": "accordion-trigger", "data-state": dataState, className: styles.trigger({ className: action ? (0, import_shared_utils.cn)(className, "pr-0") : className }), children: [ children, !action && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.ChevronDownIcon, { className: styles.triggerIcon() }) ] } ), action && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [ /* @__PURE__ */ (0, import_jsx_runtime.jsx)( "div", { "data-slot": "accordion-action", className: "flex shrink-0 items-center gap-1.5 px-2", children: action } ), /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_react_aria_components.Button, { "aria-label": "Toggle", excludeFromTabOrder: true, onPress: () => state == null ? void 0 : state.setExpanded(!state.isExpanded), "data-slot": "accordion-chevron", "data-state": dataState, className: styles.trigger({ className: "w-auto flex-none pl-0" }), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.ChevronDownIcon, { className: styles.triggerIcon() }) } ) ] }) ] }); } function AccordionContent({ className, children }) { const { styles } = useProvider(); const state = (0, import_react.useContext)(import_react_aria_components.DisclosureStateContext); const expanded = state == null ? void 0 : state.isExpanded; return /* @__PURE__ */ (0, import_jsx_runtime.jsx)( import_react_aria_components.DisclosurePanel, { "data-slot": "accordion-content", "data-state": expanded ? "open" : "closed", className: styles.contentContainer({ state: expanded ? "open" : "closed" }), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "min-h-0 overflow-hidden", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: styles.content({ className }), children }) }) } ); } // src/components/accordion/namespace.ts var namespace_exports = {}; __export(namespace_exports, { Content: () => AccordionContent, Item: () => AccordionItem, Root: () => AccordionRoot, Trigger: () => AccordionTrigger }); // src/components/blankstate/blankstate.tsx var import_shared_utils2 = require("@kopexa/shared-utils"); var import_theme2 = require("@kopexa/theme"); var import_jsx_runtime2 = require("react/jsx-runtime"); var Blankstate = (props) => { const { className, children, classNames, icon, title, description, size, bordered, narrow, ...rest } = props; const styles = (0, import_theme2.blankstate)({ size, bordered, narrow }); return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( "div", { className: styles.root({ className: (0, import_shared_utils2.cn)(classNames == null ? void 0 : classNames.root, className) }), ...rest, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: styles.container({ className: classNames == null ? void 0 : classNames.container }), children: [ icon && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: styles.icon({ className: classNames == null ? void 0 : classNames.icon }), children: icon }), title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h2", { className: styles.title({ className: classNames == null ? void 0 : classNames.title }), children: title }), description && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( "div", { className: styles.description({ className: classNames == null ? void 0 : classNames.description }), children: description } ), children && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: styles.actions({ className: classNames == null ? void 0 : classNames.actions }), children }) ] }) } ); }; // src/components/code/code.tsx var import_shared_utils3 = require("@kopexa/shared-utils"); var import_theme3 = require("@kopexa/theme"); var import_react2 = require("react"); var import_jsx_runtime3 = require("react/jsx-runtime"); var Code = (originalProps) => { const [props, variantProps] = (0, import_shared_utils3.mapPropsVariants)( originalProps, import_theme3.code.variantKeys ); const { children, className, ...otherProps } = props; const styles = (0, import_react2.useMemo)( () => (0, import_theme3.code)({ ...variantProps, className }), [(0, import_shared_utils3.objectToDeps)(variantProps), className] ); return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("code", { className: styles, ...otherProps, children }); }; // src/components/country-picker/countries.ts var ALPHA2_TO_ALPHA3 = { AD: "AND", AE: "ARE", AF: "AFG", AG: "ATG", AI: "AIA", AL: "ALB", AM: "ARM", AO: "AGO", AQ: "ATA", AR: "ARG", AS: "ASM", AT: "AUT", AU: "AUS", AW: "ABW", AX: "ALA", AZ: "AZE", BA: "BIH", BB: "BRB", BD: "BGD", BE: "BEL", BF: "BFA", BG: "BGR", BH: "BHR", BI: "BDI", BJ: "BEN", BL: "BLM", BM: "BMU", BN: "BRN", BO: "BOL", BQ: "BES", BR: "BRA", BS: "BHS", BT: "BTN", BV: "BVT", BW: "BWA", BY: "BLR", BZ: "BLZ", CA: "CAN", CC: "CCK", CD: "COD", CF: "CAF", CG: "COG", CH: "CHE", CI: "CIV", CK: "COK", CL: "CHL", CM: "CMR", CN: "CHN", CO: "COL", CR: "CRI", CU: "CUB", CV: "CPV", CW: "CUW", CX: "CXR", CY: "CYP", CZ: "CZE", DE: "DEU", DJ: "DJI", DK: "DNK", DM: "DMA", DO: "DOM", DZ: "DZA", EC: "ECU", EE: "EST", EG: "EGY", EH: "ESH", ER: "ERI", ES: "ESP", ET: "ETH", FI: "FIN", FJ: "FJI", FK: "FLK", FM: "FSM", FO: "FRO", FR: "FRA", GA: "GAB", GB: "GBR", GD: "GRD", GE: "GEO", GF: "GUF", GG: "GGY", GH: "GHA", GI: "GIB", GL: "GRL", GM: "GMB", GN: "GIN", GP: "GLP", GQ: "GNQ", GR: "GRC", GS: "SGS", GT: "GTM", GU: "GUM", GW: "GNB", GY: "GUY", HK: "HKG", HM: "HMD", HN: "HND", HR: "HRV", HT: "HTI", HU: "HUN", ID: "IDN", IE: "IRL", IL: "ISR", IM: "IMN", IN: "IND", IO: "IOT", IQ: "IRQ", IR: "IRN", IS: "ISL", IT: "ITA", JE: "JEY", JM: "JAM", JO: "JOR", JP: "JPN", KE: "KEN", KG: "KGZ", KH: "KHM", KI: "KIR", KM: "COM", KN: "KNA", KP: "PRK", KR: "KOR", KW: "KWT", KY: "CYM", KZ: "KAZ", LA: "LAO", LB: "LBN", LC: "LCA", LI: "LIE", LK: "LKA", LR: "LBR", LS: "LSO", LT: "LTU", LU: "LUX", LV: "LVA", LY: "LBY", MA: "MAR", MC: "MCO", MD: "MDA", ME: "MNE", MF: "MAF", MG: "MDG", MH: "MHL", MK: "MKD", ML: "MLI", MM: "MMR", MN: "MNG", MO: "MAC", MP: "MNP", MQ: "MTQ", MR: "MRT", MS: "MSR", MT: "MLT", MU: "MUS", MV: "MDV", MW: "MWI", MX: "MEX", MY: "MYS", MZ: "MOZ", NA: "NAM", NC: "NCL", NE: "NER", NF: "NFK", NG: "NGA", NI: "NIC", NL: "NLD", NO: "NOR", NP: "NPL", NR: "NRU", NU: "NIU", NZ: "NZL", OM: "OMN", PA: "PAN", PE: "PER", PF: "PYF", PG: "PNG", PH: "PHL", PK: "PAK", PL: "POL", PM: "SPM", PN: "PCN", PR: "PRI", PS: "PSE", PT: "PRT", PW: "PLW", PY: "PRY", QA: "QAT", RE: "REU", RO: "ROU", RS: "SRB", RU: "RUS", RW: "RWA", SA: "SAU", SB: "SLB", SC: "SYC", SD: "SDN", SE: "SWE", SG: "SGP", SH: "SHN", SI: "SVN", SJ: "SJM", SK: "SVK", SL: "SLE", SM: "SMR", SN: "SEN", SO: "SOM", SR: "SUR", SS: "SSD", ST: "STP", SV: "SLV", SX: "SXM", SY: "SYR", SZ: "SWZ", TC: "TCA", TD: "TCD", TF: "ATF", TG: "TGO", TH: "THA", TJ: "TJK", TK: "TKL", TL: "TLS", TM: "TKM", TN: "TUN", TO: "TON", TR: "TUR", TT: "TTO", TV: "TUV", TW: "TWN", TZ: "TZA", UA: "UKR", UG: "UGA", UM: "UMI", US: "USA", UY: "URY", UZ: "UZB", VA: "VAT", VC: "VCT", VE: "VEN", VG: "VGB", VI: "VIR", VN: "VNM", VU: "VUT", WF: "WLF", WS: "WSM", YE: "YEM", YT: "MYT", ZA: "ZAF", ZM: "ZMB", ZW: "ZWE" }; var ALPHA3_TO_ALPHA2 = Object.fromEntries( Object.entries(ALPHA2_TO_ALPHA3).map(([a2, a3]) => [a3, a2]) ); var COUNTRY_ALPHA2 = Object.keys(ALPHA2_TO_ALPHA3).sort(); function toAlpha2(code2) { if (!code2) return void 0; const c = code2.trim().toUpperCase(); if (c.length === 2) return ALPHA2_TO_ALPHA3[c] ? c : void 0; if (c.length === 3) return ALPHA3_TO_ALPHA2[c]; return void 0; } function toAlpha3(code2) { const a2 = toAlpha2(code2); return a2 ? ALPHA2_TO_ALPHA3[a2] : void 0; } function toFormat(code2, format) { return format === "alpha3" ? toAlpha3(code2) : toAlpha2(code2); } var nameFormatters = /* @__PURE__ */ new Map(); function getCountryName(code2, locale = "en") { var _a; const a2 = toAlpha2(code2); if (!a2) return void 0; let fmt = nameFormatters.get(locale); if (!fmt) { fmt = new Intl.DisplayNames([locale], { type: "region" }); nameFormatters.set(locale, fmt); } try { return (_a = fmt.of(a2)) != null ? _a : a2; } catch { return a2; } } function getCountries(locale = "en") { const collator = new Intl.Collator(locale); return COUNTRY_ALPHA2.map((alpha2) => { var _a; return { alpha2, alpha3: ALPHA2_TO_ALPHA3[alpha2], name: (_a = getCountryName(alpha2, locale)) != null ? _a : alpha2 }; }).sort((a, b) => collator.compare(a.name, b.name)); } // src/components/country-picker/country-picker.tsx var import_button = require("@kopexa/button"); var import_combobox = require("@kopexa/combobox"); var import_i18n2 = require("@kopexa/i18n"); var import_shared_utils5 = require("@kopexa/shared-utils"); var import_theme5 = require("@kopexa/theme"); var import_react3 = require("react"); // src/components/country-picker/flag-icon.tsx var import_i18n = require("@kopexa/i18n"); var import_shared_utils4 = require("@kopexa/shared-utils"); var import_theme4 = require("@kopexa/theme"); var import_tooltip = require("@kopexa/tooltip"); var FlagComponents = __toESM(require("country-flag-icons/react/3x2")); var import_jsx_runtime4 = require("react/jsx-runtime"); var flags = FlagComponents; function FlagIcon({ code: code2, size, tooltip, locale, className, "aria-label": ariaLabel, "aria-hidden": ariaHidden }) { var _a; const intl = (0, import_i18n.useSafeIntl)(); const resolvedLocale = locale != null ? locale : intl.locale; const a2 = toAlpha2(code2); const name = getCountryName(code2, resolvedLocale); const label = (_a = ariaLabel != null ? ariaLabel : name) != null ? _a : code2; const Flag = a2 ? flags[a2] : void 0; const classes = (0, import_shared_utils4.cn)((0, import_theme4.flagIcon)({ size }), className); if (ariaHidden) { return Flag ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Flag, { className: classes, "aria-hidden": true }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: classes, "aria-hidden": true }); } const flag = Flag ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Flag, { className: classes, role: "img", "aria-label": label }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: classes, role: "img", "aria-label": label }); if (!tooltip || !name) return flag; return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_tooltip.Tooltip, { content: name, children: flag }); } // src/components/country-picker/country-picker.tsx var import_jsx_runtime5 = require("react/jsx-runtime"); function norm(s) { return s.normalize("NFD").replace(/\p{Diacritic}/gu, "").toLowerCase().trim(); } function CountryPicker({ value, defaultValue, onChange, valueFormat = "alpha2", locale, placeholder = "Select country", searchPlaceholder = "Search countries\u2026", emptyMessage = "No countries found.", showCode = true, disabled, className, id }) { var _a, _b, _c, _d; const intl = (0, import_i18n2.useSafeIntl)(); const resolvedLocale = locale != null ? locale : intl.locale; const s = (0, import_theme5.countryPicker)(); const items = (0, import_react3.useMemo)(() => getCountries(resolvedLocale), [resolvedLocale]); const byA2 = (0, import_react3.useMemo)(() => { const m = /* @__PURE__ */ new Map(); for (const c of items) m.set(c.alpha2, c); return m; }, [items]); const selected = value != null ? (_b = byA2.get((_a = toAlpha2(value)) != null ? _a : "")) != null ? _b : null : void 0; const defaultSelected = defaultValue != null ? (_d = byA2.get((_c = toAlpha2(defaultValue)) != null ? _c : "")) != null ? _d : null : void 0; const filter = (item, query) => { const country = item; const q = norm(query); if (!q) return true; return norm(country.name).includes(q) || country.alpha2.toLowerCase().startsWith(q) || country.alpha3.toLowerCase().startsWith(q); }; return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)( import_combobox.Combobox, { items, value: selected, defaultValue: defaultSelected, onValueChange: (value2) => { var _a2; const country = value2; onChange == null ? void 0 : onChange( country ? (_a2 = toFormat(country.alpha2, valueFormat)) != null ? _a2 : null : null ); }, itemToStringLabel: (value2) => { var _a2; return (_a2 = value2 == null ? void 0 : value2.name) != null ? _a2 : ""; }, isItemEqualToValue: (a, b) => (a == null ? void 0 : a.alpha2) === (b == null ? void 0 : b.alpha2), filter, disabled, variant: "inside", children: [ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)( import_combobox.Combobox.Trigger, { id, className: (0, import_shared_utils5.cn)("w-full border-input bg-background px-3", className), render: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_button.Button, { variant: "outline", mode: "input" }), children: [ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_combobox.Combobox.Value, { children: (country) => country ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: s.value(), children: [ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FlagIcon, { code: country.alpha2, "aria-hidden": true }), /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: s.valueName(), children: country.name }) ] }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: s.valuePlaceholder(), children: placeholder }) }), /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_combobox.Combobox.Icon, {}) ] } ), /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_combobox.Combobox.Content, { className: "pt-0", children: [ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "p-2", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_combobox.Combobox.Input, { placeholder: searchPlaceholder }) }), /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_combobox.Combobox.Empty, { children: emptyMessage }), /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_combobox.Combobox.List, { maxHeight: 320, children: (country) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_combobox.Combobox.Item, { value: country, children: [ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: s.item(), children: [ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(FlagIcon, { code: country.alpha2, "aria-hidden": true }), /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: s.itemName(), children: country.name }), showCode && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: s.itemCode(), children: toFormat(country.alpha2, valueFormat) }) ] }), /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_combobox.Combobox.ItemIndicator, {}) ] }, country.alpha2) }) ] }) ] } ); } // src/components/dialog/dialog.tsx var import_dialog = require("@base-ui/react/dialog"); var import_icons2 = require("@kopexa/icons"); var import_react_utils2 = require("@kopexa/react-utils"); var import_shared_utils6 = require("@kopexa/shared-utils"); var import_theme6 = require("@kopexa/theme"); var import_use_controllable_state = require("@kopexa/use-controllable-state"); var import_jsx_runtime6 = require("react/jsx-runtime"); var [DialogProvider, useDialogContext] = (0, import_react_utils2.createContext)(); var DialogRoot = (props) => { const { open: openProp, onOpenChange, size, radius, placement, scrollBehavior, ...restProps } = props; const [open, setOpen] = (0, import_use_controllable_state.useControllableState)({ value: openProp, onChange: onOpenChange, defaultValue: false }); const styles = (0, import_theme6.dialog)({ size, radius, placement, scrollBehavior }); return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogProvider, { value: { styles, open, placement, size, radius }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( import_dialog.Dialog.Root, { "data-slot": "dialog", open, onOpenChange: (open2) => setOpen(open2), ...restProps } ) }); }; function DialogTrigger({ ...props }) { return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dialog.Dialog.Trigger, { "data-slot": "dialog-trigger", ...props }); } function DialogPortal({ ...props }) { return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dialog.Dialog.Portal, { "data-slot": "dialog-portal", ...props }); } function DialogClose({ ...props }) { return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dialog.Dialog.Close, { "data-slot": "dialog-close", ...props }); } function DialogOverlay({ className, ...props }) { const { styles } = useDialogContext(); return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( import_dialog.Dialog.Backdrop, { "data-slot": "dialog-overlay", className: (0, import_shared_utils6.cn)(styles.overlay(), className), ...props } ); } function DialogContent({ className, children, showCloseButton = true, ...props }) { const { styles } = useDialogContext(); return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(DialogPortal, { "data-slot": "dialog-portal", children: [ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DialogOverlay, {}), /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)( import_dialog.Dialog.Popup, { "data-slot": "dialog-content", className: (0, import_shared_utils6.cn)(styles.content(), className), ...props, children: [ children, showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)( import_dialog.Dialog.Close, { "data-slot": "dialog-close", className: styles.close(), children: [ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons2.CloseIcon, {}), /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "sr-only", children: "Close" }) ] } ) ] } ) ] }); } function DialogHeader({ className, ...props }) { const { styles } = useDialogContext(); return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( "div", { "data-slot": "dialog-header", className: styles.header({ className }), ...props } ); } function DialogFooter({ className, ...props }) { const { styles } = useDialogContext(); return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( "div", { "data-slot": "dialog-footer", className: styles.footer({ className }), ...props } ); } function DialogBody({ className, ...props }) { const { styles } = useDialogContext(); return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( "div", { "data-slot": "dialog-body", className: styles.body({ className }), ...props } ); } function DialogTitle({ className, ...props }) { const { styles } = useDialogContext(); return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( import_dialog.Dialog.Title, { "data-slot": "dialog-title", className: (0, import_shared_utils6.cn)(styles.title(), className), ...props } ); } function DialogDescription({ className, ...props }) { const { styles } = useDialogContext(); return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( import_dialog.Dialog.Description, { "data-slot": "dialog-description", className: (0, import_shared_utils6.cn)(styles.description(), className), ...props } ); } function DialogCloseTrigger({ className, ...props }) { const { styles } = useDialogContext(); return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)( import_dialog.Dialog.Close, { "data-slot": "dialog-close-trigger", className: (0, import_shared_utils6.cn)(styles.closeTrigger(), className), ...props } ); } // src/components/dialog/index.ts var Dialog = Object.assign(DialogRoot, { Root: DialogRoot, Body: DialogBody, CloseTrigger: DialogCloseTrigger, Content: DialogContent, Description: DialogDescription, Footer: DialogFooter, Header: DialogHeader, Overlay: DialogOverlay, Portal: DialogPortal, Title: DialogTitle, Trigger: DialogTrigger }); // src/components/file-upload/avatar-upload.tsx var import_button2 = require("@kopexa/button"); var import_callout = require("@kopexa/callout"); var import_i18n6 = require("@kopexa/i18n"); var import_icons3 = require("@kopexa/icons"); var import_image_crop = require("@kopexa/image-crop"); var import_shared_utils8 = require("@kopexa/shared-utils"); var import_theme7 = require("@kopexa/theme"); var import_react5 = require("react"); // src/hooks/use-file-upload/index.ts var import_i18n4 = require("@kopexa/i18n"); var import_shared_utils7 = require("@kopexa/shared-utils"); var import_react4 = require("react"); // src/hooks/use-file-upload/messages.ts var import_i18n3 = require("@kopexa/i18n"); var messages = (0, import_i18n3.defineMessages)({ file_exceeds_max: { id: "use_file_upload.file_exceeds_max", defaultMessage: `File "{name}" exceeds the maximum size of {max}.`, description: "Shown when a single file is larger than allowed" }, file_not_accepted: { id: "use_file_upload.file_not_accepted", defaultMessage: `File "{name}" is not an accepted file type.`, description: "Shown when file type/extension doesn't match accept" }, too_many_files: { id: "file_upload.too_many_files", defaultMessage: "You can only upload a maximum of {max} files.", description: "Shown when maxFiles would be exceeded" } }); // src/hooks/use-file-upload/index.ts var useFileUpload = (options = {}) => { const { maxFiles = Number.POSITIVE_INFINITY, maxSize = Number.POSITIVE_INFINITY, accept = "*", multiple = false, initialFiles = [], onFilesChange, onFilesAdded, onError } = options; const t = (0, import_i18n4.useSafeIntl)(); const [state, setState] = (0, import_react4.useState)({ files: initialFiles.map((file) => ({ file, id: file.id, preview: file.url })), isDragging: false, errors: [] }); const inputRef = (0, import_react4.useRef)(null); const validateFile = (0, import_react4.useCallback)( (file) => { if (file instanceof File) { if (file.size > maxSize) { return t.formatMessage(messages.file_exceeds_max, { name: file.name, max: (0, import_shared_utils7.formatBytes)(maxSize) }); } } else { if (file.size > maxSize) { return t.formatMessage(messages.file_exceeds_max, { name: file.name, max: (0, import_shared_utils7.formatBytes)(maxSize) }); } } if (accept !== "*") { const acceptedTypes = accept.split(",").map((type) => type.trim()); const fileType = file instanceof File ? file.type || "" : file.type; const fileExtension = `.${file instanceof File ? file.name.split(".").pop() : file.name.split(".").pop()}`; const isAccepted = acceptedTypes.some((type) => { if (type.startsWith(".")) { return fileExtension.toLowerCase() === type.toLowerCase(); } if (type.endsWith("/*")) { const baseType = type.split("/")[0]; return fileType.startsWith(`${baseType}/`); } return fileType === type; }); if (!isAccepted) { return t.formatMessage(messages.file_not_accepted, { name: file instanceof File ? file.name : file.name }); } } return null; }, [accept, maxSize, t.formatMessage] ); const createPreview = (0, import_react4.useCallback)( (file) => { if (file instanceof File) { return URL.createObjectURL(file); } return file.url; }, [] ); const generateUniqueId = (0, import_react4.useCallback)((file) => { if (file instanceof File) { return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`; } return file.id; }, []); const clearFiles = (0, import_react4.useCallback)(() => { setState((prev) => { for (const file of prev.files) { if (file.preview && file.file instanceof File && file.file.type.startsWith("image/")) { URL.revokeObjectURL(file.preview); } } if (inputRef.current) { inputRef.current.value = ""; } const newState = { ...prev, files: [], errors: [] }; onFilesChange == null ? void 0 : onFilesChange(newState.files); return newState; }); }, [onFilesChange]); const addFiles = (0, import_react4.useCallback)( (newFiles) => { if (!newFiles || newFiles.length === 0) return; const newFilesArray = Array.from(newFiles); const errors = []; setState((prev) => ({ ...prev, errors: [] })); if (!multiple) { clearFiles(); } if (multiple && maxFiles !== Number.POSITIVE_INFINITY && state.files.length + newFilesArray.length > maxFiles) { errors.push( t.formatMessage(messages.too_many_files, { max: maxFiles }) ); onError == null ? void 0 : onError(errors); setState((prev) => ({ ...prev, errors })); return; } const validFiles = []; for (const file of newFilesArray) { if (multiple) { const isDuplicate = state.files.some( (existingFile) => existingFile.file.name === file.name && existingFile.file.size === file.size ); if (isDuplicate) { return; } } if (file.size > maxSize) { errors.push( multiple ? `Some files exceed the maximum size of ${(0, import_shared_utils7.formatBytes)(maxSize)}.` : `File exceeds the maximum size of ${(0, import_shared_utils7.formatBytes)(maxSize)}.` ); continue; } const error = validateFile(file); if (error) { errors.push(error); } else { validFiles.push({ file, id: generateUniqueId(file), preview: createPreview(file) }); } } if (validFiles.length > 0) { onFilesAdded == null ? void 0 : onFilesAdded(validFiles); setState((prev) => { const newFiles2 = !multiple ? validFiles : [...prev.files, ...validFiles]; onFilesChange == null ? void 0 : onFilesChange(newFiles2); return { ...prev, files: newFiles2, errors }; }); } else if (errors.length > 0) { onError == null ? void 0 : onError(errors); setState((prev) => ({ ...prev, errors })); } if (inputRef.current) { inputRef.current.value = ""; } }, [ onError, state.files, maxFiles, multiple, maxSize, validateFile, createPreview, generateUniqueId, clearFiles, onFilesChange, onFilesAdded, t.formatMessage ] ); const removeFile = (0, import_react4.useCallback)( (id) => { setState((prev) => { const fileToRemove = prev.files.find((file) => file.id === id); if ((fileToRemove == null ? void 0 : fileToRemove.preview) && fileToRemove.file instanceof File && fileToRemove.file.type.startsWith("image/")) { URL.revokeObjectURL(fileToRemove.preview); } const newFiles = prev.files.filter((file) => file.id !== id); onFilesChange == null ? void 0 : onFilesChange(newFiles); return { ...prev, files: newFiles, errors: [] }; }); }, [onFilesChange] ); const clearErrors = (0, import_react4.useCallback)(() => { setState((prev) => ({ ...prev, errors: [] })); }, []); const handleDragEnter = (0, import_react4.useCallback)((e) => { e.preventDefault(); e.stopPropagation(); setState((prev) => ({ ...prev, isDragging: true })); }, []); const handleDragLeave = (0, import_react4.useCallback)((e) => { e.preventDefault(); e.stopPropagation(); if (e.currentTarget.contains(e.relatedTarget)) { return; } setState((prev) => ({ ...prev, isDragging: false })); }, []); const handleDragOver = (0, import_react4.useCallback)((e) => { e.preventDefault(); e.stopPropagation(); }, []); const handleDrop = (0, import_react4.useCallback)( (e) => { var _a; e.preventDefault(); e.stopPropagation(); setState((prev) => ({ ...prev, isDragging: false })); if ((_a = inputRef.current) == null ? void 0 : _a.disabled) { return; } if (e.dataTransfer.files && e.dataTransfer.files.length > 0) { if (!multiple) { const file = e.dataTransfer.files[0]; addFiles([file]); } else { addFiles(e.dataTransfer.files); } } }, [addFiles, multiple] ); const handleFileChange = (0, import_react4.useCallback)( (e) => { if (e.target.files && e.target.files.length > 0) { addFiles(e.target.files); } }, [addFiles] ); const openFileDialog = (0, import_react4.useCallback)(() => { if (inputRef.current) { inputRef.current.click(); } }, []); const getInputProps = (0, import_react4.useCallback)( (props = {}) => { return { ...props, type: "file", onChange: handleFileChange, accept: props.accept || accept, multiple: props.multiple !== void 0 ? props.multiple : multiple, ref: inputRef }; }, [accept, multiple, handleFileChange] ); return [ state, { addFiles, removeFile, clearFiles, clearErrors, handleDragEnter, handleDragLeave, handleDragOver, handleDrop, handleFileChange, openFileDialog, getInputProps } ]; }; // src/components/file-upload/messages.ts var import_i18n5 = require("@kopexa/i18n"); var messages2 = (0, import_i18n5.defineMessages)({ change_avatar: { id: "file_upload.change_avatar", defaultMessage: "Change Avatar", description: "Label for changing the avatar image" }, upload_avatar: { id: "file_upload.upload_avatar", defaultMessage: "Upload Avatar", description: "Label for uploading a new avatar image" }, remove_avatar: { id: "file_upload.remove_avatar", defaultMessage: "Remove Avatar", description: "Label for removing the current avatar image" }, avatar_uploaded: { id: "file_upload.avatar_uploaded", defaultMessage: "Avatar uploaded", description: "Message displayed when the avatar is uploaded successfully" }, accepted_file_types: { id: "file_upload.accepted_file_types", defaultMessage: "{types}{size, select, none {} other { up to {size}}}", description: "Message indicating the accepted file types for upload" }, cancel: { id: "file_upload.cancel", defaultMessage: "Cancel", description: "Label for canceling the file upload" }, apply_crop: { id: "file_upload.apply_crop", defaultMessage: "Apply", description: "Label for applying the crop to the image" } }); // src/components/file-upload/utils/data-url-to-file.ts async function dataUrlToFile(dataUrl, fileName, typeHint) { const res = await fetch(dataUrl); const blob = await res.blob(); const type = typeHint || blob.type || "image/png"; const ext = type.includes("jpeg") ? "jpg" : type.split("/")[1] || "png"; const safeName = fileName.replace(/\.[^.]+$/, ""); return new File([blob], `${safeName}-cropped.${ext}`, { type }); } // src/components/file-upload/utils/format-accept-types.ts var WILDCARD_GROUPS = { "image/*": "common image formats", "audio/*": "common audio formats", "video/*": "common video formats", "application/*": "common document formats" }; var MIME_TO_LABEL = { "image/png": "PNG", "image/jpeg": "JPG", "image/jpg": "JPG", "application/pdf": "PDF", "text/csv": "CSV", "text/plain": "TXT" }; var EXT_TO_LABEL = { ".png": "PNG", ".jpg": "JPG", ".jpeg": "JPG", ".pdf": "PDF", ".csv": "CSV", ".txt": "TXT" }; function normalizeToken(token) { return token.trim().toLowerCase(); } function formatAcceptedTypes(accept) { var _a, _b; if (!accept || typeof accept !== "string") return ""; const tokens = accept.split(",").map(normalizeToken).filter(Boolean); const labels = []; for (const token of tokens) { if (WILDCARD_GROUPS[token]) { labels.push(WILDCARD_GROUPS[token]); continue; } if (token.startsWith(".")) { labels.push( (_a = EXT_TO_LABEL[token]) != null ? _a : token.replace(/^\./, "").toUpperCase() ); continue; } if (token.includes("/")) { labels.push((_b = MIME_TO_LABEL[token]) != null ? _b : token.split("/")[1].toUpperCase()); } } const seen = /* @__PURE__ */ new Set(); return labels.filter((x) => { if (seen.has(x)) return false; seen.add(x); return true; }).join(", "); } // src/components/file-upload/utils/is-image-like.ts function isImageLike(file) { var _a, _b; if ((_a = file.type) == null ? void 0 : _a.startsWith("image/")) return true; const name = ((_b = file.name) == null ? void 0 : _b.toLowerCase()) || ""; return name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".webp"); } // src/components/file-upload/avatar-upload.tsx var import_jsx_runtime7 = require("react/jsx-runtime"); var defaultMaxSize = 2 * 1024 * 1024; var AvatarUpload = (props) => { const { maxSize = defaultMaxSize, className, onFileChange, defaultAvatar, orientation, size, shape, accept = ".png,.jpg", cropperEnabled = true, cropAspect = 1, cropMaxImageSize = defaultMaxSize, onCroppedFile, ...rest } = props; const t = (0, import_i18n6.useSafeIntl)(); const [cropOpen, setCropOpen] = (0, import_react5.useState)(false); const [cropSourceFile, setCropSourceFile] = (0, import_react5.useState)(null); const pendingOriginalId = (0, import_react5.useRef)(null); const [ { files, isDragging, errors }, { removeFile, handleDragEnter, handleDragLeave, handleDragOver, handleDrop, openFileDialog, getInputProps, clearErrors, addFiles } ] = useFileUpload({ maxFiles: 1, maxSize, accept, multiple: false, onFilesChange: (files2) => { onFileChange == null ? void 0 : onFileChange(files2[0] || null); }, onFilesAdded: (added) => { var _a; if (!cropperEnabled) return; const raw = (_a = added[0]) == null ? void 0 : _a.file; if (raw instanceof File && isImageLike(raw)) { pendingOriginalId.current = added[0].id; setCropSourceFile(raw); setCropOpen(true); } } }); const currentFile = files[0]; const previewUrl = (currentFile == null ? void 0 : currentFile.preview) || defaultAvatar; const handleRemove = () => { if (currentFile) { removeFile(currentFile.id); clearErrors(); } }; const styles = (0, import_theme7.avatarUpload)({ size, shape, orientation }); const typesLabel = formatAcceptedTypes(accept); const handleCropCancel = (0, import_react5.useCallback)(() => { setCropOpen(false); setCropSourceFile(null); pendingOriginalId.current = null; }, []); const handleCropApply = (0, import_react5.useCallback)( async (croppedDataUrl) => { if (!croppedDataUrl || !cropSourceFile) { handleCropCancel(); return; } const newFile = await dataUrlToFile( croppedDataUrl, cropSourceFile.name, cropSourceFile.type ); if (pendingOriginalId.current) { removeFile(pendingOriginalId.current); pendingOriginalId.current = null; } addFiles([newFile]); onCroppedFile == null ? void 0 : onCroppedFile(newFile); setCropOpen(false); setCropSourceFile(null); }, [cropSourceFile, addFiles, removeFile, onCroppedFile, handleCropCancel] ); return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)( "div", { "data-slot": "avatar-upload", className: styles.root({ className }), ...rest, children: [ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: styles.previewAndText(), children: [ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: styles.previewContainer(), children: [ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)( "button", { type: "button", "aria-label": previewUrl ? t.formatMessage(messages2.change_avatar) : t.formatMessage(messages2.upload_avatar), "data-dragging": (0, import_shared_utils8.dataAttr)(isDragging), "data-hasimage": (0, import_shared_utils8.dataAttr)(!!previewUrl), className: styles.preview(), onDragEnter: handleDragEnter, onDragLeave: handleDragLeave, onDragOver: handleDragOver, onDrop: handleDrop, onClick: openFileDialog, children: [ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("input", { ...getInputProps(), className: "sr-only" }), previewUrl ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( "img", { src: previewUrl, alt: "Avatar", className: styles.previewImg() } ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: styles.placeholderWrapper(), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_icons3.UserCircleIcon, { className: styles.placeholder() }) }) ] } ), currentFile && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( import_button2.IconButton, { variant: "outline", color: "default", onClick: handleRemove, size: "sm", className: styles.removeButton(), "aria-label": t.formatMessage(messages2.remove_avatar), children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_icons3.CloseIcon, {}) } ) ] }), /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: styles.instructionsContainer(), children: [ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: styles.instructions(), children: currentFile ? t.formatMessage(messages2.avatar_uploaded) : t.formatMessage(messages2.upload_avatar) }), /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: styles.acceptedFiles(), children: t.formatMessage(messages2.accepted_file_types, { types: typesLabel || "-", size: maxSize ? (0, import_shared_utils8.formatBytes)(maxSize) : "none" }) }) ] }) ] }), errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_callout.Callout, { variant: "destructive", children: errors.map((error, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: styles.errorItem(), children: error }, index.toString())) }) ] } ), cropperEnabled && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( Dialog.Root, { open: cropOpen, onOpenChange: (v) => !v ? handleCropCancel() : null, size: "2xl", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Dialog.Content, { children: [ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Dialog.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Dialog.Title, { children: t.formatMessage(messages2.change_avatar) }) }), cropSourceFile && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)( import_image_crop.ImageCrop, { aspect: cropAspect, file: cropSourceFile, maxImageSize: cropMaxImageSize, onCrop: handleCropApply, children: [ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_image_crop.ImageCropContent, { className: "max-w-md" }) }), /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Dialog.Footer, { children: [ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( Dialog.CloseTrigger, { render: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( import_button2.Button, { variant: "ghost", color: "default", startContent: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_icons3.CloseIcon, {}), children: t.formatMessage(messages2.cancel) } ) } ), /* @__PURE__ */ (0, import_jsx_runtime7.jsx)( import_image_crop.ImageCropApply, { color: "primary", variant: "solid", render: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_button2.Button, { startContent: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_icons3.CropIcon, {}), children: t.formatMessage(messages2.apply_crop) }) } ) ] }) ] } ) ] }) } ) ] }); }; // src/components/radio-card/radio-card.tsx var import_factory2 = require("@ark-ui/react/facto