@capra/core 1.8.2 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +294 -46
- package/dist/index.d.cts +132 -20
- package/dist/index.d.mts +132 -20
- package/dist/index.mjs +295 -49
- package/dist/style.css +251 -72
- package/docs/core-alert--usage.md +2 -0
- package/docs/core-anchor--usage.md +2 -0
- package/docs/core-autocompletefield--usage.md +2 -0
- package/docs/core-badge--design.md +10 -5
- package/docs/core-badge--usage.md +5 -2
- package/docs/core-breadcrumbs--usage.md +2 -0
- package/docs/core-button--usage.md +2 -0
- package/docs/core-buttonlink--usage.md +2 -0
- package/docs/core-checkbox--usage.md +2 -0
- package/docs/core-collapse--usage.md +2 -0
- package/docs/core-datepickerfield--usage.md +2 -0
- package/docs/core-daterangepickerfield--usage.md +2 -0
- package/docs/core-divider--usage.md +2 -0
- package/docs/core-emptystate--usage.md +2 -0
- package/docs/core-helpertext--usage.md +2 -0
- package/docs/core-iconbutton--usage.md +2 -0
- package/docs/core-inputrow--usage.md +2 -0
- package/docs/core-label--usage.md +2 -0
- package/docs/core-link--usage.md +2 -0
- package/docs/core-listitem--usage.md +2 -0
- package/docs/core-menu--usage.md +2 -0
- package/docs/core-modal--usage.md +2 -0
- package/docs/core-pagination--usage.md +2 -0
- package/docs/core-pill--usage.md +2 -0
- package/docs/core-radio--usage.md +2 -0
- package/docs/core-radiogroup--usage.md +2 -0
- package/docs/core-radiotile--usage.md +2 -0
- package/docs/core-ribbon--usage.md +2 -0
- package/docs/core-skeleton--usage.md +1 -2
- package/docs/core-skeletongroup--usage.md +0 -1
- package/docs/core-spinner--usage.md +2 -0
- package/docs/core-switch--usage.md +2 -0
- package/docs/core-tabnav--usage.md +2 -0
- package/docs/core-tag--usage.md +2 -0
- package/docs/core-text--usage.md +2 -0
- package/docs/core-textarea--usage.md +2 -0
- package/docs/core-textinput--usage.md +2 -0
- package/docs/core-tooltip--usage.md +2 -0
- package/docs/core-topnav--usage.md +2 -0
- package/docs/core-tree--design.md +31 -0
- package/docs/core-tree--usage.md +102 -0
- package/docs/core-verticalnavigation--usage.md +2 -0
- package/docs/history-changelogs-capra-core--docs.md +34 -0
- package/docs/index.md +2 -0
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -252,7 +252,7 @@ const VisuallyHidden = ({ children, ...props }) => {
|
|
|
252
252
|
//#endregion
|
|
253
253
|
//#region src/components/input-helpers/Label.tsx
|
|
254
254
|
/** Label text and optional required indicator for form fields, aligned with Capra field layouts. */
|
|
255
|
-
const Label
|
|
255
|
+
const Label = react.forwardRef((props, ref) => {
|
|
256
256
|
const [mergedProps, mergedRef] = (0, react_aria_components.useContextProps)(props, ref, react_aria_components.LabelContext);
|
|
257
257
|
const { trailingSlot, children, required, FORCE__className: classNameOverride, style, ...labelProps } = mergedProps;
|
|
258
258
|
if (!children) return null;
|
|
@@ -265,7 +265,7 @@ const Label$1 = react.forwardRef((props, ref) => {
|
|
|
265
265
|
"aria-hidden": true
|
|
266
266
|
}, "*"), /* @__PURE__ */ react.createElement(VisuallyHidden, null, "This field is required"))), trailingSlot && /* @__PURE__ */ react.createElement("span", { className: Label_module_default.trailingSlot }, trailingSlot));
|
|
267
267
|
});
|
|
268
|
-
Label
|
|
268
|
+
Label.displayName = "Label";
|
|
269
269
|
//#endregion
|
|
270
270
|
//#region src/components/TextInput/TextInput.module.css
|
|
271
271
|
var TextInput_module_default = {
|
|
@@ -395,7 +395,7 @@ function AutocompleteFieldWithoutRef(props, ref) {
|
|
|
395
395
|
id,
|
|
396
396
|
shouldFocusWrap: true,
|
|
397
397
|
ref: comboboxRef
|
|
398
|
-
}, /* @__PURE__ */ react.default.createElement(Label
|
|
398
|
+
}, /* @__PURE__ */ react.default.createElement(Label, null, label), /* @__PURE__ */ react.default.createElement(TextInput, {
|
|
399
399
|
...inputProps,
|
|
400
400
|
ref,
|
|
401
401
|
trailingSlot: trailingContent
|
|
@@ -577,15 +577,15 @@ const Card = Object.assign(CardRoot, {
|
|
|
577
577
|
//#endregion
|
|
578
578
|
//#region src/components/Badge/Badge.module.css
|
|
579
579
|
var Badge_module_default = {
|
|
580
|
-
"badge": "capra-Badge-module-
|
|
581
|
-
"base": "capra-Badge-module-
|
|
580
|
+
"badge": "capra-Badge-module-_3WihW-badge",
|
|
581
|
+
"base": "capra-Badge-module-_3WihW-base"
|
|
582
582
|
};
|
|
583
583
|
//#endregion
|
|
584
584
|
//#region src/components/Badge/Badge.tsx
|
|
585
585
|
/**
|
|
586
586
|
* Badges display an indicator/counter on an associated component.
|
|
587
587
|
*/
|
|
588
|
-
function Badge({ appearance = "danger", variant, count = 0, showZero = false, overflowCount = 99, FORCE__className, ...props }) {
|
|
588
|
+
function Badge({ appearance = "danger", variant = "counter", size = "md", count = 0, showZero = false, overflowCount = 99, FORCE__className, style, ...props }) {
|
|
589
589
|
if (variant === "counter" && !showZero && !count) return null;
|
|
590
590
|
const getBadgeContent = () => {
|
|
591
591
|
if (variant === "dot") return null;
|
|
@@ -593,43 +593,55 @@ function Badge({ appearance = "danger", variant, count = 0, showZero = false, ov
|
|
|
593
593
|
return value > overflowCount ? `${overflowCount}+` : value;
|
|
594
594
|
};
|
|
595
595
|
return /* @__PURE__ */ react.createElement("span", {
|
|
596
|
-
role: "status",
|
|
597
596
|
className: clsx(Badge_module_default.badge, FORCE__className),
|
|
598
597
|
"data-appearance": appearance,
|
|
598
|
+
"data-size": size,
|
|
599
599
|
"data-variant": variant,
|
|
600
|
+
style,
|
|
600
601
|
...props
|
|
601
602
|
}, getBadgeContent());
|
|
602
603
|
}
|
|
603
604
|
/**
|
|
604
605
|
* A convenience component allowing you to easily attach a badge to another component.
|
|
605
606
|
*/
|
|
606
|
-
function BadgeLayout({ children }) {
|
|
607
|
-
return /* @__PURE__ */ react.createElement("div", {
|
|
607
|
+
function BadgeLayout({ children, offset = [0, 0] }) {
|
|
608
|
+
return /* @__PURE__ */ react.createElement("div", {
|
|
609
|
+
className: Badge_module_default.base,
|
|
610
|
+
style: {
|
|
611
|
+
"--_badge-offset-x": `${offset[0]}px`,
|
|
612
|
+
"--_badge-offset-y": `${offset[1]}px`
|
|
613
|
+
}
|
|
614
|
+
}, children);
|
|
608
615
|
}
|
|
609
616
|
//#endregion
|
|
610
617
|
//#region src/components/ListItem/ListItem.module.css
|
|
611
618
|
var ListItem_module_default = {
|
|
612
|
-
"
|
|
613
|
-
"
|
|
614
|
-
"
|
|
615
|
-
"
|
|
616
|
-
"
|
|
617
|
-
"
|
|
618
|
-
"
|
|
619
|
-
"
|
|
620
|
-
"
|
|
619
|
+
"__listItem-layout": "capra-ListItem-module-QN6vFW-__listItem-layout",
|
|
620
|
+
"content": "capra-ListItem-module-QN6vFW-content",
|
|
621
|
+
"description": "capra-ListItem-module-QN6vFW-description",
|
|
622
|
+
"label": "capra-ListItem-module-QN6vFW-label",
|
|
623
|
+
"leading": "capra-ListItem-module-QN6vFW-leading",
|
|
624
|
+
"listItem": "capra-ListItem-module-QN6vFW-listItem capra-ListItem-module-QN6vFW-__listItem-layout",
|
|
625
|
+
"slot": "capra-ListItem-module-QN6vFW-slot",
|
|
626
|
+
"slots": "capra-ListItem-module-QN6vFW-slots",
|
|
627
|
+
"suffix": "capra-ListItem-module-QN6vFW-suffix",
|
|
628
|
+
"trailing": "capra-ListItem-module-QN6vFW-trailing"
|
|
621
629
|
};
|
|
622
630
|
//#endregion
|
|
623
631
|
//#region src/components/ListItem/ListItemSlots.tsx
|
|
632
|
+
const CollapsedSlot = "__CollapsedSlot__";
|
|
624
633
|
const ListItemSlots = ({ children, trailing = false, FORCE__className }) => {
|
|
625
634
|
if (react.default.Children.count(children) === 0) return null;
|
|
626
635
|
return /* @__PURE__ */ react.default.createElement("div", {
|
|
627
636
|
className: clsx(ListItem_module_default.slots, FORCE__className),
|
|
628
637
|
"data-trailing": trailing || void 0
|
|
629
|
-
}, react.default.Children.map(children, (child, index) =>
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
638
|
+
}, react.default.Children.map(children, (child, index) => {
|
|
639
|
+
if (child === "__CollapsedSlot__") return void 0;
|
|
640
|
+
return /* @__PURE__ */ react.default.createElement("div", {
|
|
641
|
+
key: index,
|
|
642
|
+
className: ListItem_module_default.slot
|
|
643
|
+
}, child);
|
|
644
|
+
}));
|
|
633
645
|
};
|
|
634
646
|
//#endregion
|
|
635
647
|
//#region src/components/ListItem/ListItem.tsx
|
|
@@ -652,7 +664,7 @@ const Trailing = ({ children, FORCE__className }) => {
|
|
|
652
664
|
const Content = ({ children, FORCE__className }) => {
|
|
653
665
|
return /* @__PURE__ */ react.createElement("div", { className: clsx(ListItem_module_default.content, FORCE__className) }, children);
|
|
654
666
|
};
|
|
655
|
-
const Label = ({ children, id }) => {
|
|
667
|
+
const Label$1 = ({ children, id }) => {
|
|
656
668
|
return /* @__PURE__ */ react.createElement("div", {
|
|
657
669
|
id,
|
|
658
670
|
className: ListItem_module_default.label
|
|
@@ -671,7 +683,7 @@ const Spacer = () => {
|
|
|
671
683
|
});
|
|
672
684
|
};
|
|
673
685
|
ListItem.Content = Content;
|
|
674
|
-
ListItem.Label = Label;
|
|
686
|
+
ListItem.Label = Label$1;
|
|
675
687
|
ListItem.Description = Description;
|
|
676
688
|
ListItem.Suffix = Suffix;
|
|
677
689
|
ListItem.Spacer = Spacer;
|
|
@@ -1112,7 +1124,7 @@ const TextField = react.forwardRef((props, ref) => {
|
|
|
1112
1124
|
className: fieldLayout_module_default.field,
|
|
1113
1125
|
"data-capra-field-root": "",
|
|
1114
1126
|
"data-layout": layout
|
|
1115
|
-
}, /* @__PURE__ */ react.createElement(Label
|
|
1127
|
+
}, /* @__PURE__ */ react.createElement(Label, { required }, label), /* @__PURE__ */ react.createElement(TextInput, {
|
|
1116
1128
|
ref,
|
|
1117
1129
|
...inputRest,
|
|
1118
1130
|
appearance,
|
|
@@ -1216,7 +1228,7 @@ const NumberField = react.forwardRef((props, ref) => {
|
|
|
1216
1228
|
className: fieldLayout_module_default.field,
|
|
1217
1229
|
"data-capra-field-root": "",
|
|
1218
1230
|
"data-layout": layout
|
|
1219
|
-
}, /* @__PURE__ */ react.createElement(Label
|
|
1231
|
+
}, /* @__PURE__ */ react.createElement(Label, { required }, label), /* @__PURE__ */ react.createElement(react_aria_components.Group, {
|
|
1220
1232
|
"data-capra-text-input": "",
|
|
1221
1233
|
"data-size": size,
|
|
1222
1234
|
className: clsx(TextInput_module_default.wrapper, NumberField_module_default.withStepper, classNameOverride)
|
|
@@ -2232,7 +2244,7 @@ function DatePickerFieldInner(props, ref) {
|
|
|
2232
2244
|
isInvalid,
|
|
2233
2245
|
shouldForceLeadingZeros: true,
|
|
2234
2246
|
validationBehavior: "aria"
|
|
2235
|
-
}, /* @__PURE__ */ react.createElement(Label
|
|
2247
|
+
}, /* @__PURE__ */ react.createElement(Label, { required }, label), /* @__PURE__ */ react.createElement(DatePickerFieldRow, {
|
|
2236
2248
|
appearance,
|
|
2237
2249
|
size,
|
|
2238
2250
|
leadingSlot,
|
|
@@ -2474,7 +2486,7 @@ function DateRangePickerFieldInner(props, ref) {
|
|
|
2474
2486
|
isInvalid,
|
|
2475
2487
|
shouldForceLeadingZeros: true,
|
|
2476
2488
|
validationBehavior: "aria"
|
|
2477
|
-
}, /* @__PURE__ */ react.createElement(Label
|
|
2489
|
+
}, /* @__PURE__ */ react.createElement(Label, { required }, label), /* @__PURE__ */ react.createElement(DateRangePickerFieldRow, {
|
|
2478
2490
|
appearance,
|
|
2479
2491
|
size,
|
|
2480
2492
|
leadingSlot,
|
|
@@ -2703,7 +2715,7 @@ const TextArea = react.forwardRef((props, ref) => {
|
|
|
2703
2715
|
...ariaFieldProps,
|
|
2704
2716
|
className: fieldLayout_module_default.field,
|
|
2705
2717
|
"data-layout": layout
|
|
2706
|
-
}, /* @__PURE__ */ react.createElement(Label
|
|
2718
|
+
}, /* @__PURE__ */ react.createElement(Label, { required }, label), /* @__PURE__ */ react.createElement("div", {
|
|
2707
2719
|
className: clsx(TextArea_module_default.wrapper, classNameOverride),
|
|
2708
2720
|
"data-has-indicator": hasIndicator,
|
|
2709
2721
|
"data-autosize": autoSizeActive,
|
|
@@ -4380,23 +4392,23 @@ const submenuPanelClassName = Menu_module_default.menu;
|
|
|
4380
4392
|
//#endregion
|
|
4381
4393
|
//#region src/components/TabNav/TabNav.module.css
|
|
4382
4394
|
var TabNav_module_default = {
|
|
4383
|
-
"dropdownIcon": "capra-TabNav-module-
|
|
4384
|
-
"extraContent": "capra-TabNav-module-
|
|
4385
|
-
"indentSpacer": "capra-TabNav-module-
|
|
4386
|
-
"panel": "capra-TabNav-module-
|
|
4387
|
-
"root": "capra-TabNav-module-
|
|
4388
|
-
"subMenu": "capra-TabNav-module-
|
|
4389
|
-
"subMenuItem": "capra-TabNav-module-
|
|
4390
|
-
"subMenuItemActive": "capra-TabNav-module-
|
|
4391
|
-
"subTab": "capra-TabNav-module-
|
|
4392
|
-
"subTabList": "capra-TabNav-module-
|
|
4393
|
-
"subTabListItem": "capra-TabNav-module-
|
|
4394
|
-
"tab": "capra-TabNav-module-
|
|
4395
|
-
"tabBar": "capra-TabNav-module-
|
|
4396
|
-
"tabGroup": "capra-TabNav-module-
|
|
4397
|
-
"tabIcon": "capra-TabNav-module-
|
|
4398
|
-
"tabLabel": "capra-TabNav-module-
|
|
4399
|
-
"tabList": "capra-TabNav-module-
|
|
4395
|
+
"dropdownIcon": "capra-TabNav-module-pLDWhG-dropdownIcon",
|
|
4396
|
+
"extraContent": "capra-TabNav-module-pLDWhG-extraContent",
|
|
4397
|
+
"indentSpacer": "capra-TabNav-module-pLDWhG-indentSpacer",
|
|
4398
|
+
"panel": "capra-TabNav-module-pLDWhG-panel",
|
|
4399
|
+
"root": "capra-TabNav-module-pLDWhG-root",
|
|
4400
|
+
"subMenu": "capra-TabNav-module-pLDWhG-subMenu",
|
|
4401
|
+
"subMenuItem": "capra-TabNav-module-pLDWhG-subMenuItem",
|
|
4402
|
+
"subMenuItemActive": "capra-TabNav-module-pLDWhG-subMenuItemActive",
|
|
4403
|
+
"subTab": "capra-TabNav-module-pLDWhG-subTab",
|
|
4404
|
+
"subTabList": "capra-TabNav-module-pLDWhG-subTabList",
|
|
4405
|
+
"subTabListItem": "capra-TabNav-module-pLDWhG-subTabListItem",
|
|
4406
|
+
"tab": "capra-TabNav-module-pLDWhG-tab",
|
|
4407
|
+
"tabBar": "capra-TabNav-module-pLDWhG-tabBar",
|
|
4408
|
+
"tabGroup": "capra-TabNav-module-pLDWhG-tabGroup",
|
|
4409
|
+
"tabIcon": "capra-TabNav-module-pLDWhG-tabIcon",
|
|
4410
|
+
"tabLabel": "capra-TabNav-module-pLDWhG-tabLabel",
|
|
4411
|
+
"tabList": "capra-TabNav-module-pLDWhG-tabList"
|
|
4400
4412
|
};
|
|
4401
4413
|
//#endregion
|
|
4402
4414
|
//#region src/components/TabNav/TabNav.tsx
|
|
@@ -4970,6 +4982,240 @@ function ArrowSvg() {
|
|
|
4970
4982
|
}));
|
|
4971
4983
|
}
|
|
4972
4984
|
//#endregion
|
|
4985
|
+
//#region src/components/Tree/Tree.module.css
|
|
4986
|
+
var Tree_module_default = {
|
|
4987
|
+
"chevronButton": "capra-Tree-module--hXpBa-chevronButton",
|
|
4988
|
+
"chevronIcon": "capra-Tree-module--hXpBa-chevronIcon",
|
|
4989
|
+
"indentSpacer": "capra-Tree-module--hXpBa-indentSpacer",
|
|
4990
|
+
"item": "capra-Tree-module--hXpBa-item capra-ListItem-module-QN6vFW-__listItem-layout",
|
|
4991
|
+
"itemContent": "capra-Tree-module--hXpBa-itemContent capra-ListItem-module-QN6vFW-content",
|
|
4992
|
+
"itemLabel": "capra-Tree-module--hXpBa-itemLabel capra-ListItem-module-QN6vFW-label",
|
|
4993
|
+
"itemSuffix": "capra-Tree-module--hXpBa-itemSuffix capra-ListItem-module-QN6vFW-suffix",
|
|
4994
|
+
"label": "capra-Tree-module--hXpBa-label",
|
|
4995
|
+
"root": "capra-Tree-module--hXpBa-root",
|
|
4996
|
+
"selectionCheckbox": "capra-Tree-module--hXpBa-selectionCheckbox",
|
|
4997
|
+
"suffix": "capra-Tree-module--hXpBa-suffix"
|
|
4998
|
+
};
|
|
4999
|
+
//#endregion
|
|
5000
|
+
//#region src/components/Tree/Tree.tsx
|
|
5001
|
+
const TreeSelectionContext = react.createContext(null);
|
|
5002
|
+
function getTextValue(item) {
|
|
5003
|
+
return typeof item.label === "string" ? item.label : String(item.key);
|
|
5004
|
+
}
|
|
5005
|
+
function buildTreeIndex(items) {
|
|
5006
|
+
const parentByKey = /* @__PURE__ */ new Map();
|
|
5007
|
+
const descendantsByKey = /* @__PURE__ */ new Map();
|
|
5008
|
+
const selectableDescendantsByKey = /* @__PURE__ */ new Map();
|
|
5009
|
+
const disabledKeys = /* @__PURE__ */ new Set();
|
|
5010
|
+
const selectableKeys = /* @__PURE__ */ new Set();
|
|
5011
|
+
const visit = (item, parent) => {
|
|
5012
|
+
parentByKey.set(item.key, parent);
|
|
5013
|
+
if (item.isDisabled) disabledKeys.add(item.key);
|
|
5014
|
+
else selectableKeys.add(item.key);
|
|
5015
|
+
const descendants = [];
|
|
5016
|
+
const selectableDescendants = [];
|
|
5017
|
+
for (const child of item.children ?? []) {
|
|
5018
|
+
visit(child, item.key);
|
|
5019
|
+
descendants.push(child.key, ...descendantsByKey.get(child.key) ?? []);
|
|
5020
|
+
if (!child.isDisabled) selectableDescendants.push(child.key);
|
|
5021
|
+
for (const descendant of selectableDescendantsByKey.get(child.key) ?? []) selectableDescendants.push(descendant);
|
|
5022
|
+
}
|
|
5023
|
+
descendantsByKey.set(item.key, descendants);
|
|
5024
|
+
selectableDescendantsByKey.set(item.key, selectableDescendants);
|
|
5025
|
+
};
|
|
5026
|
+
for (const item of items) visit(item, null);
|
|
5027
|
+
return {
|
|
5028
|
+
parentByKey,
|
|
5029
|
+
descendantsByKey,
|
|
5030
|
+
selectableDescendantsByKey,
|
|
5031
|
+
disabledKeys,
|
|
5032
|
+
selectableKeys
|
|
5033
|
+
};
|
|
5034
|
+
}
|
|
5035
|
+
function sanitizeSelection(selection, index) {
|
|
5036
|
+
const next = /* @__PURE__ */ new Set();
|
|
5037
|
+
for (const key of selection) if (index.parentByKey.has(key) && !index.disabledKeys.has(key)) next.add(key);
|
|
5038
|
+
return next;
|
|
5039
|
+
}
|
|
5040
|
+
function reconcileParentKeys(selection, index) {
|
|
5041
|
+
const next = new Set(selection);
|
|
5042
|
+
for (const [key, selectableDescendants] of index.selectableDescendantsByKey) {
|
|
5043
|
+
if (selectableDescendants.length === 0) continue;
|
|
5044
|
+
if (!selectableDescendants.every((descendantKey) => next.has(descendantKey))) next.delete(key);
|
|
5045
|
+
}
|
|
5046
|
+
return next;
|
|
5047
|
+
}
|
|
5048
|
+
function selectionToSet(selection, index) {
|
|
5049
|
+
if (selection === "all") return new Set(index.selectableKeys);
|
|
5050
|
+
if (selection == null) return /* @__PURE__ */ new Set();
|
|
5051
|
+
return sanitizeSelection(selection, index);
|
|
5052
|
+
}
|
|
5053
|
+
function expandKeysWithAncestors(keys, index) {
|
|
5054
|
+
if (keys == null) return;
|
|
5055
|
+
const expanded = /* @__PURE__ */ new Set();
|
|
5056
|
+
for (const key of keys) {
|
|
5057
|
+
if (!index.parentByKey.has(key)) continue;
|
|
5058
|
+
let current = key;
|
|
5059
|
+
while (current != null) {
|
|
5060
|
+
expanded.add(current);
|
|
5061
|
+
current = index.parentByKey.get(current) ?? null;
|
|
5062
|
+
}
|
|
5063
|
+
}
|
|
5064
|
+
return expanded;
|
|
5065
|
+
}
|
|
5066
|
+
function getCheckboxState(key, selectedKeys, index) {
|
|
5067
|
+
const selectableDescendants = index.selectableDescendantsByKey.get(key) ?? [];
|
|
5068
|
+
if (selectableDescendants.length === 0) return {
|
|
5069
|
+
checked: selectedKeys.has(key),
|
|
5070
|
+
indeterminate: false
|
|
5071
|
+
};
|
|
5072
|
+
const selectedDescendantCount = selectableDescendants.filter((descendantKey) => selectedKeys.has(descendantKey)).length;
|
|
5073
|
+
const allSelectableDescendantsSelected = selectedDescendantCount === selectableDescendants.length;
|
|
5074
|
+
const someSelectableDescendantsSelected = selectedDescendantCount > 0;
|
|
5075
|
+
if (allSelectableDescendantsSelected || selectedKeys.has(key)) return {
|
|
5076
|
+
checked: true,
|
|
5077
|
+
indeterminate: false
|
|
5078
|
+
};
|
|
5079
|
+
return {
|
|
5080
|
+
checked: false,
|
|
5081
|
+
indeterminate: someSelectableDescendantsSelected
|
|
5082
|
+
};
|
|
5083
|
+
}
|
|
5084
|
+
function applySelectionChange(prev, next, index) {
|
|
5085
|
+
const cascadedSelection = sanitizeSelection(next, index);
|
|
5086
|
+
for (const key of next) {
|
|
5087
|
+
if (prev.has(key) || index.disabledKeys.has(key)) continue;
|
|
5088
|
+
if ((index.descendantsByKey.get(key) ?? []).length === 0) continue;
|
|
5089
|
+
cascadedSelection.add(key);
|
|
5090
|
+
for (const descendantKey of index.selectableDescendantsByKey.get(key) ?? []) cascadedSelection.add(descendantKey);
|
|
5091
|
+
}
|
|
5092
|
+
for (const key of prev) {
|
|
5093
|
+
if (next.has(key) || index.disabledKeys.has(key)) continue;
|
|
5094
|
+
if ((index.descendantsByKey.get(key) ?? []).length === 0) continue;
|
|
5095
|
+
cascadedSelection.delete(key);
|
|
5096
|
+
for (const descendantKey of index.descendantsByKey.get(key) ?? []) cascadedSelection.delete(descendantKey);
|
|
5097
|
+
}
|
|
5098
|
+
return reconcileParentKeys(cascadedSelection, index);
|
|
5099
|
+
}
|
|
5100
|
+
function TreeSelectionCheckbox({ item }) {
|
|
5101
|
+
const context = react.useContext(TreeSelectionContext);
|
|
5102
|
+
if (context?.selectionMode !== "multiple") return null;
|
|
5103
|
+
const checkboxState = getCheckboxState(item.key, context.selectedKeys, context.index);
|
|
5104
|
+
return /* @__PURE__ */ react.createElement(Checkbox, {
|
|
5105
|
+
"aria-checked": checkboxState.indeterminate ? "mixed" : checkboxState.checked ? "true" : "false",
|
|
5106
|
+
"aria-label": getTextValue(item),
|
|
5107
|
+
checked: checkboxState.checked,
|
|
5108
|
+
disabled: context.index.disabledKeys.has(item.key),
|
|
5109
|
+
indeterminate: checkboxState.indeterminate,
|
|
5110
|
+
FORCE__className: Tree_module_default.selectionCheckbox,
|
|
5111
|
+
onChange: (event) => {
|
|
5112
|
+
event.stopPropagation();
|
|
5113
|
+
context.toggleSelection(item.key);
|
|
5114
|
+
},
|
|
5115
|
+
onClick: (event) => {
|
|
5116
|
+
event.stopPropagation();
|
|
5117
|
+
},
|
|
5118
|
+
onMouseDown: (event) => {
|
|
5119
|
+
event.stopPropagation();
|
|
5120
|
+
},
|
|
5121
|
+
onKeyDown: (event) => {
|
|
5122
|
+
event.stopPropagation();
|
|
5123
|
+
},
|
|
5124
|
+
onPointerDown: (event) => {
|
|
5125
|
+
event.stopPropagation();
|
|
5126
|
+
}
|
|
5127
|
+
});
|
|
5128
|
+
}
|
|
5129
|
+
function renderTreeItem(item) {
|
|
5130
|
+
return /* @__PURE__ */ react.createElement(react_aria_components.TreeItem, {
|
|
5131
|
+
id: item.key,
|
|
5132
|
+
key: item.key,
|
|
5133
|
+
className: Tree_module_default.item,
|
|
5134
|
+
isDisabled: item.isDisabled,
|
|
5135
|
+
textValue: getTextValue(item)
|
|
5136
|
+
}, /* @__PURE__ */ react.createElement(react_aria_components.TreeItemContent, null, ({ hasChildItems, id, level, selectionMode }) => /* @__PURE__ */ react.createElement(react.Fragment, null, /* @__PURE__ */ react.createElement(ListItem.Leading, null, Array.from({ length: Math.max(level - 1, 0) }).map((_, index) => /* @__PURE__ */ react.createElement("span", {
|
|
5137
|
+
key: `${String(item.key)}-indent-${index}`,
|
|
5138
|
+
"aria-hidden": "true",
|
|
5139
|
+
className: Tree_module_default.indentSpacer
|
|
5140
|
+
})), hasChildItems ? /* @__PURE__ */ react.createElement(react_aria_components.Button, {
|
|
5141
|
+
slot: "chevron",
|
|
5142
|
+
className: Tree_module_default.chevronButton
|
|
5143
|
+
}, /* @__PURE__ */ react.createElement("span", {
|
|
5144
|
+
"aria-hidden": "true",
|
|
5145
|
+
className: Tree_module_default.chevronIcon
|
|
5146
|
+
}, /* @__PURE__ */ react.createElement(_capra_icons.CaretRight, { size: "xs" }))) : /* @__PURE__ */ react.createElement("div", null), selectionMode === "multiple" ? /* @__PURE__ */ react.createElement(TreeSelectionCheckbox, { item }) : CollapsedSlot), /* @__PURE__ */ react.createElement("div", { className: Tree_module_default.itemContent }, /* @__PURE__ */ react.createElement("div", {
|
|
5147
|
+
id: String(id),
|
|
5148
|
+
className: Tree_module_default.itemLabel
|
|
5149
|
+
}, item.label)), /* @__PURE__ */ react.createElement(ListItem.Trailing, null, item.suffix ? /* @__PURE__ */ react.createElement("div", { className: Tree_module_default.itemSuffix }, item.suffix) : CollapsedSlot, item.trailingSlot || "__CollapsedSlot__"))), /* @__PURE__ */ react.createElement(react_aria_components.Collection, { items: item.children }, renderTreeItem));
|
|
5150
|
+
}
|
|
5151
|
+
/**
|
|
5152
|
+
* A hierarchical tree with cascading multi-select and Capra ListItem row layout.
|
|
5153
|
+
*/
|
|
5154
|
+
function Tree({ FORCE__className: classNameOverride, items, selectionMode = "multiple", defaultSelectedKeys, selectedKeys, onSelectionChange, expandedKeys, defaultExpandedKeys, ...props }) {
|
|
5155
|
+
const index = react.useMemo(() => buildTreeIndex(items), [items]);
|
|
5156
|
+
const resolvedExpandedKeys = react.useMemo(() => expandKeysWithAncestors(expandedKeys, index), [expandedKeys, index]);
|
|
5157
|
+
const resolvedDefaultExpandedKeys = react.useMemo(() => expandKeysWithAncestors(defaultExpandedKeys, index), [defaultExpandedKeys, index]);
|
|
5158
|
+
const [internalSelectedKeys, setInternalSelectedKeys] = react.useState(() => applySelectionChange(/* @__PURE__ */ new Set(), selectionToSet(selectedKeys ?? defaultSelectedKeys, index), index));
|
|
5159
|
+
react.useEffect(() => {
|
|
5160
|
+
const nextSelectedKeys = selectedKeys != null ? applySelectionChange(/* @__PURE__ */ new Set(), selectionToSet(selectedKeys, index), index) : reconcileParentKeys(sanitizeSelection(internalSelectedKeys, index), index);
|
|
5161
|
+
if (nextSelectedKeys.size !== internalSelectedKeys.size || Array.from(nextSelectedKeys).some((key) => !internalSelectedKeys.has(key))) setInternalSelectedKeys(nextSelectedKeys);
|
|
5162
|
+
}, [
|
|
5163
|
+
index,
|
|
5164
|
+
internalSelectedKeys,
|
|
5165
|
+
selectedKeys
|
|
5166
|
+
]);
|
|
5167
|
+
const selectedKeysRef = react.useRef(internalSelectedKeys);
|
|
5168
|
+
selectedKeysRef.current = internalSelectedKeys;
|
|
5169
|
+
const commitSelection = react.useCallback((nextSelectedKeys) => {
|
|
5170
|
+
setInternalSelectedKeys(nextSelectedKeys);
|
|
5171
|
+
onSelectionChange?.(new Set(nextSelectedKeys));
|
|
5172
|
+
}, [onSelectionChange]);
|
|
5173
|
+
const toggleSelection = react.useCallback((key) => {
|
|
5174
|
+
if (selectionMode !== "multiple" || index.disabledKeys.has(key)) return;
|
|
5175
|
+
const nextSelectedKeys = new Set(selectedKeysRef.current);
|
|
5176
|
+
if (nextSelectedKeys.has(key)) nextSelectedKeys.delete(key);
|
|
5177
|
+
else nextSelectedKeys.add(key);
|
|
5178
|
+
commitSelection(applySelectionChange(selectedKeysRef.current, nextSelectedKeys, index));
|
|
5179
|
+
}, [
|
|
5180
|
+
commitSelection,
|
|
5181
|
+
index,
|
|
5182
|
+
selectionMode
|
|
5183
|
+
]);
|
|
5184
|
+
const handleSelectionChange = react.useCallback((nextSelection) => {
|
|
5185
|
+
if (selectionMode !== "multiple") {
|
|
5186
|
+
commitSelection(selectionToSet(nextSelection, index));
|
|
5187
|
+
return;
|
|
5188
|
+
}
|
|
5189
|
+
commitSelection(applySelectionChange(selectedKeysRef.current, selectionToSet(nextSelection, index), index));
|
|
5190
|
+
}, [
|
|
5191
|
+
commitSelection,
|
|
5192
|
+
index,
|
|
5193
|
+
selectionMode
|
|
5194
|
+
]);
|
|
5195
|
+
const selectionContext = react.useMemo(() => ({
|
|
5196
|
+
index,
|
|
5197
|
+
selectedKeys: internalSelectedKeys,
|
|
5198
|
+
selectionMode,
|
|
5199
|
+
toggleSelection
|
|
5200
|
+
}), [
|
|
5201
|
+
index,
|
|
5202
|
+
internalSelectedKeys,
|
|
5203
|
+
selectionMode,
|
|
5204
|
+
toggleSelection
|
|
5205
|
+
]);
|
|
5206
|
+
return /* @__PURE__ */ react.createElement(TreeSelectionContext.Provider, { value: selectionContext }, /* @__PURE__ */ react.createElement(react_aria_components.Tree, {
|
|
5207
|
+
...props,
|
|
5208
|
+
selectionBehavior: "toggle",
|
|
5209
|
+
className: clsx(Tree_module_default.root, classNameOverride),
|
|
5210
|
+
items,
|
|
5211
|
+
selectedKeys: internalSelectedKeys,
|
|
5212
|
+
selectionMode,
|
|
5213
|
+
onSelectionChange: handleSelectionChange,
|
|
5214
|
+
expandedKeys: resolvedExpandedKeys,
|
|
5215
|
+
defaultExpandedKeys: resolvedDefaultExpandedKeys
|
|
5216
|
+
}, /* @__PURE__ */ react.createElement(react_aria_components.Collection, { items }, renderTreeItem)));
|
|
5217
|
+
}
|
|
5218
|
+
//#endregion
|
|
4973
5219
|
exports.Alert = Alert;
|
|
4974
5220
|
exports.Anchor = Anchor;
|
|
4975
5221
|
exports.AutocompleteField = AutocompleteField;
|
|
@@ -4990,6 +5236,7 @@ exports.Drawer = Drawer;
|
|
|
4990
5236
|
exports.EmptyState = EmptyState;
|
|
4991
5237
|
exports.IconButton = IconButton;
|
|
4992
5238
|
exports.InputRow = InputRow;
|
|
5239
|
+
exports.Label = Label;
|
|
4993
5240
|
exports.Link = Link;
|
|
4994
5241
|
exports.ListItem = ListItem;
|
|
4995
5242
|
exports.Menu = Menu;
|
|
@@ -5023,6 +5270,7 @@ exports.TextField = TextField;
|
|
|
5023
5270
|
exports.Toast = Toast;
|
|
5024
5271
|
exports.Tooltip = Tooltip;
|
|
5025
5272
|
exports.TopNav = TopNav;
|
|
5273
|
+
exports.Tree = Tree;
|
|
5026
5274
|
exports.VerticalNavigation = VerticalNavigation;
|
|
5027
5275
|
exports.VisuallyHidden = VisuallyHidden;
|
|
5028
5276
|
exports.submenuPanelClassName = submenuPanelClassName;
|