@tomny-dev/uzi 0.2.11 → 0.2.12-pr.34.96.2.48c7a99
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/index39.js +3 -1
- package/dist/index39.js.map +1 -1
- package/dist/index40.cjs +3 -0
- package/dist/index40.cjs.map +1 -1
- package/dist/index40.js +4 -3
- package/dist/index40.js.map +1 -1
- package/dist/index41.cjs +4 -3
- package/dist/index41.cjs.map +1 -1
- package/dist/style.css +4 -0
- package/package.json +1 -1
package/dist/index39.js
CHANGED
|
@@ -8,6 +8,7 @@ var section = "uzi-sidebar-nav-module__section__yjtCY";
|
|
|
8
8
|
var sectionItems = "uzi-sidebar-nav-module__sectionItems__tNcph";
|
|
9
9
|
var sectionLabel = "uzi-sidebar-nav-module__sectionLabel__Wx94m";
|
|
10
10
|
var item = "uzi-sidebar-nav-module__item__uMHkJ";
|
|
11
|
+
var itemWithoutIcon = "uzi-sidebar-nav-module__itemWithoutIcon__7gzPd";
|
|
11
12
|
var itemActive = "uzi-sidebar-nav-module__itemActive__wBbiS";
|
|
12
13
|
var itemCollapsed = "uzi-sidebar-nav-module__itemCollapsed__jLJN-";
|
|
13
14
|
var itemDisabled = "uzi-sidebar-nav-module__itemDisabled__Yf8Il";
|
|
@@ -27,6 +28,7 @@ var sidebar_nav_module_default = {
|
|
|
27
28
|
sectionItems,
|
|
28
29
|
sectionLabel,
|
|
29
30
|
item,
|
|
31
|
+
itemWithoutIcon,
|
|
30
32
|
itemActive,
|
|
31
33
|
itemCollapsed,
|
|
32
34
|
itemDisabled,
|
|
@@ -38,6 +40,6 @@ var sidebar_nav_module_default = {
|
|
|
38
40
|
badge
|
|
39
41
|
};
|
|
40
42
|
//#endregion
|
|
41
|
-
export { badge, sidebar_nav_module_default as default, description, footer, header, icon, item, itemActive, itemBody, itemCollapsed, itemDisabled, label, labelRow, section, sectionItems, sectionLabel, sections, sidebarNav, sidebarNavCollapsed };
|
|
43
|
+
export { badge, sidebar_nav_module_default as default, description, footer, header, icon, item, itemActive, itemBody, itemCollapsed, itemDisabled, itemWithoutIcon, label, labelRow, section, sectionItems, sectionLabel, sections, sidebarNav, sidebarNavCollapsed };
|
|
42
44
|
|
|
43
45
|
//# sourceMappingURL=index39.js.map
|
package/dist/index39.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index39.js","names":[],"sources":["../src/components/sidebar-nav/sidebar-nav.module.css"],"sourcesContent":[".sidebarNav {\n --sidebar-nav-icon-size: 18px;\n --sidebar-nav-icon-size-mobile: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n min-height: 0;\n}\n\n.sidebarNavCollapsed {\n gap: 10px;\n}\n\n.header,\n.footer {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.footer {\n margin-top: auto;\n padding-top: 12px;\n border-top: 1px solid var(--border);\n}\n\n.sections {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: 14px;\n}\n\n.section {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sectionItems {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sectionLabel {\n padding: 0 10px;\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--muted-foreground);\n opacity: 0.75;\n}\n\n.item {\n color: var(--foreground);\n background: transparent;\n border: none;\n box-shadow: none;\n padding: 10px 12px 10px 10px;\n border-radius: 10px;\n text-decoration: none;\n font-size: 14px;\n display: grid;\n grid-template-columns: var(--sidebar-nav-icon-size) minmax(0, 1fr);\n align-items: center;\n column-gap: 10px;\n width: 100%;\n text-align: left;\n box-sizing: border-box;\n line-height: 1.2;\n transition: background 120ms ease, color 120ms ease;\n}\n\nbutton.item {\n font-family: inherit;\n cursor: pointer;\n}\n\n.item:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.item:hover {\n background: color-mix(in srgb, var(--primary) 10%, transparent);\n}\n\n.item.itemActive {\n background: color-mix(in srgb, var(--primary) 18%, transparent);\n color: var(--foreground);\n font-weight: 700;\n}\n\n.itemCollapsed {\n grid-template-columns: 1fr;\n justify-items: center;\n padding-right: 10px;\n padding-left: 10px;\n}\n\n.itemDisabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.icon {\n width: var(--sidebar-nav-icon-size);\n height: var(--sidebar-nav-icon-size);\n min-width: var(--sidebar-nav-icon-size);\n color: var(--muted-foreground);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n vertical-align: middle;\n}\n\n.icon > * {\n width: 100% !important;\n height: 100% !important;\n max-width: 100%;\n max-height: 100%;\n}\n\n.icon :where(svg) {\n width: 100%;\n height: 100%;\n display: block;\n stroke: currentColor;\n}\n\n.item.itemActive .icon {\n color: var(--primary);\n}\n\n.itemBody {\n display: flex;\n min-width: 0;\n flex: 1 1 auto;\n flex-direction: column;\n gap: 3px;\n overflow: hidden;\n}\n\n.labelRow {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 8px;\n}\n\n.label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.description {\n color: var(--muted-foreground);\n font-size: 12px;\n line-height: 1.35;\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 999px;\n border: 1px solid var(--border);\n background: color-mix(in srgb, var(--foreground) 4%, transparent);\n color: var(--muted-foreground);\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n\n@media (max-width: 960px) {\n .sidebarNav {\n gap: 10px;\n }\n\n .sections {\n gap: 12px;\n }\n\n .sectionItems {\n gap: 6px;\n }\n\n .item {\n padding: 9px 10px 9px 8px;\n border-radius: 9px;\n font-size: 14px;\n grid-template-columns: var(--sidebar-nav-icon-size-mobile) minmax(0, 1fr);\n column-gap: 8px;\n }\n\n .icon {\n width: var(--sidebar-nav-icon-size-mobile);\n height: var(--sidebar-nav-icon-size-mobile);\n min-width: var(--sidebar-nav-icon-size-mobile);\n }\n\n .icon :where(svg) {\n width: var(--sidebar-nav-icon-size-mobile);\n height: var(--sidebar-nav-icon-size-mobile);\n }\n\n .description {\n font-size: 11px;\n }\n}\n\n@media (max-width: 480px) {\n .item {\n padding: 8px 9px 8px 7px;\n font-size: 13px;\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index39.js","names":[],"sources":["../src/components/sidebar-nav/sidebar-nav.module.css"],"sourcesContent":[".sidebarNav {\n --sidebar-nav-icon-size: 18px;\n --sidebar-nav-icon-size-mobile: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n min-height: 0;\n}\n\n.sidebarNavCollapsed {\n gap: 10px;\n}\n\n.header,\n.footer {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.footer {\n margin-top: auto;\n padding-top: 12px;\n border-top: 1px solid var(--border);\n}\n\n.sections {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: 14px;\n}\n\n.section {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sectionItems {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sectionLabel {\n padding: 0 10px;\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--muted-foreground);\n opacity: 0.75;\n}\n\n.item {\n color: var(--foreground);\n background: transparent;\n border: none;\n box-shadow: none;\n padding: 10px 12px 10px 10px;\n border-radius: 10px;\n text-decoration: none;\n font-size: 14px;\n display: grid;\n grid-template-columns: var(--sidebar-nav-icon-size) minmax(0, 1fr);\n align-items: center;\n column-gap: 10px;\n width: 100%;\n text-align: left;\n box-sizing: border-box;\n line-height: 1.2;\n transition: background 120ms ease, color 120ms ease;\n}\n\n.item.itemWithoutIcon {\n grid-template-columns: minmax(0, 1fr);\n}\n\nbutton.item {\n font-family: inherit;\n cursor: pointer;\n}\n\n.item:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.item:hover {\n background: color-mix(in srgb, var(--primary) 10%, transparent);\n}\n\n.item.itemActive {\n background: color-mix(in srgb, var(--primary) 18%, transparent);\n color: var(--foreground);\n font-weight: 700;\n}\n\n.itemCollapsed {\n grid-template-columns: 1fr;\n justify-items: center;\n padding-right: 10px;\n padding-left: 10px;\n}\n\n.itemDisabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.icon {\n width: var(--sidebar-nav-icon-size);\n height: var(--sidebar-nav-icon-size);\n min-width: var(--sidebar-nav-icon-size);\n color: var(--muted-foreground);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n vertical-align: middle;\n}\n\n.icon > * {\n width: 100% !important;\n height: 100% !important;\n max-width: 100%;\n max-height: 100%;\n}\n\n.icon :where(svg) {\n width: 100%;\n height: 100%;\n display: block;\n stroke: currentColor;\n}\n\n.item.itemActive .icon {\n color: var(--primary);\n}\n\n.itemBody {\n display: flex;\n min-width: 0;\n flex: 1 1 auto;\n flex-direction: column;\n gap: 3px;\n overflow: hidden;\n}\n\n.labelRow {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 8px;\n}\n\n.label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.description {\n color: var(--muted-foreground);\n font-size: 12px;\n line-height: 1.35;\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 999px;\n border: 1px solid var(--border);\n background: color-mix(in srgb, var(--foreground) 4%, transparent);\n color: var(--muted-foreground);\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n\n@media (max-width: 960px) {\n .sidebarNav {\n gap: 10px;\n }\n\n .sections {\n gap: 12px;\n }\n\n .sectionItems {\n gap: 6px;\n }\n\n .item {\n padding: 9px 10px 9px 8px;\n border-radius: 9px;\n font-size: 14px;\n grid-template-columns: var(--sidebar-nav-icon-size-mobile) minmax(0, 1fr);\n column-gap: 8px;\n }\n\n .icon {\n width: var(--sidebar-nav-icon-size-mobile);\n height: var(--sidebar-nav-icon-size-mobile);\n min-width: var(--sidebar-nav-icon-size-mobile);\n }\n\n .icon :where(svg) {\n width: var(--sidebar-nav-icon-size-mobile);\n height: var(--sidebar-nav-icon-size-mobile);\n }\n\n .description {\n font-size: 11px;\n }\n}\n\n@media (max-width: 480px) {\n .item {\n padding: 8px 9px 8px 7px;\n font-size: 13px;\n }\n}\n"],"mappings":""}
|
package/dist/index40.cjs
CHANGED
|
@@ -8,6 +8,7 @@ var section = "uzi-sidebar-nav-module__section__yjtCY";
|
|
|
8
8
|
var sectionItems = "uzi-sidebar-nav-module__sectionItems__tNcph";
|
|
9
9
|
var sectionLabel = "uzi-sidebar-nav-module__sectionLabel__Wx94m";
|
|
10
10
|
var item = "uzi-sidebar-nav-module__item__uMHkJ";
|
|
11
|
+
var itemWithoutIcon = "uzi-sidebar-nav-module__itemWithoutIcon__7gzPd";
|
|
11
12
|
var itemActive = "uzi-sidebar-nav-module__itemActive__wBbiS";
|
|
12
13
|
var itemCollapsed = "uzi-sidebar-nav-module__itemCollapsed__jLJN-";
|
|
13
14
|
var itemDisabled = "uzi-sidebar-nav-module__itemDisabled__Yf8Il";
|
|
@@ -27,6 +28,7 @@ var sidebar_nav_module_default = {
|
|
|
27
28
|
sectionItems,
|
|
28
29
|
sectionLabel,
|
|
29
30
|
item,
|
|
31
|
+
itemWithoutIcon,
|
|
30
32
|
itemActive,
|
|
31
33
|
itemCollapsed,
|
|
32
34
|
itemDisabled,
|
|
@@ -49,6 +51,7 @@ exports.itemActive = itemActive;
|
|
|
49
51
|
exports.itemBody = itemBody;
|
|
50
52
|
exports.itemCollapsed = itemCollapsed;
|
|
51
53
|
exports.itemDisabled = itemDisabled;
|
|
54
|
+
exports.itemWithoutIcon = itemWithoutIcon;
|
|
52
55
|
exports.label = label;
|
|
53
56
|
exports.labelRow = labelRow;
|
|
54
57
|
exports.section = section;
|
package/dist/index40.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index40.cjs","names":[],"sources":["../src/components/sidebar-nav/sidebar-nav.module.css"],"sourcesContent":[".sidebarNav {\n --sidebar-nav-icon-size: 18px;\n --sidebar-nav-icon-size-mobile: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n min-height: 0;\n}\n\n.sidebarNavCollapsed {\n gap: 10px;\n}\n\n.header,\n.footer {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.footer {\n margin-top: auto;\n padding-top: 12px;\n border-top: 1px solid var(--border);\n}\n\n.sections {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: 14px;\n}\n\n.section {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sectionItems {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sectionLabel {\n padding: 0 10px;\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--muted-foreground);\n opacity: 0.75;\n}\n\n.item {\n color: var(--foreground);\n background: transparent;\n border: none;\n box-shadow: none;\n padding: 10px 12px 10px 10px;\n border-radius: 10px;\n text-decoration: none;\n font-size: 14px;\n display: grid;\n grid-template-columns: var(--sidebar-nav-icon-size) minmax(0, 1fr);\n align-items: center;\n column-gap: 10px;\n width: 100%;\n text-align: left;\n box-sizing: border-box;\n line-height: 1.2;\n transition: background 120ms ease, color 120ms ease;\n}\n\nbutton.item {\n font-family: inherit;\n cursor: pointer;\n}\n\n.item:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.item:hover {\n background: color-mix(in srgb, var(--primary) 10%, transparent);\n}\n\n.item.itemActive {\n background: color-mix(in srgb, var(--primary) 18%, transparent);\n color: var(--foreground);\n font-weight: 700;\n}\n\n.itemCollapsed {\n grid-template-columns: 1fr;\n justify-items: center;\n padding-right: 10px;\n padding-left: 10px;\n}\n\n.itemDisabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.icon {\n width: var(--sidebar-nav-icon-size);\n height: var(--sidebar-nav-icon-size);\n min-width: var(--sidebar-nav-icon-size);\n color: var(--muted-foreground);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n vertical-align: middle;\n}\n\n.icon > * {\n width: 100% !important;\n height: 100% !important;\n max-width: 100%;\n max-height: 100%;\n}\n\n.icon :where(svg) {\n width: 100%;\n height: 100%;\n display: block;\n stroke: currentColor;\n}\n\n.item.itemActive .icon {\n color: var(--primary);\n}\n\n.itemBody {\n display: flex;\n min-width: 0;\n flex: 1 1 auto;\n flex-direction: column;\n gap: 3px;\n overflow: hidden;\n}\n\n.labelRow {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 8px;\n}\n\n.label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.description {\n color: var(--muted-foreground);\n font-size: 12px;\n line-height: 1.35;\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 999px;\n border: 1px solid var(--border);\n background: color-mix(in srgb, var(--foreground) 4%, transparent);\n color: var(--muted-foreground);\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n\n@media (max-width: 960px) {\n .sidebarNav {\n gap: 10px;\n }\n\n .sections {\n gap: 12px;\n }\n\n .sectionItems {\n gap: 6px;\n }\n\n .item {\n padding: 9px 10px 9px 8px;\n border-radius: 9px;\n font-size: 14px;\n grid-template-columns: var(--sidebar-nav-icon-size-mobile) minmax(0, 1fr);\n column-gap: 8px;\n }\n\n .icon {\n width: var(--sidebar-nav-icon-size-mobile);\n height: var(--sidebar-nav-icon-size-mobile);\n min-width: var(--sidebar-nav-icon-size-mobile);\n }\n\n .icon :where(svg) {\n width: var(--sidebar-nav-icon-size-mobile);\n height: var(--sidebar-nav-icon-size-mobile);\n }\n\n .description {\n font-size: 11px;\n }\n}\n\n@media (max-width: 480px) {\n .item {\n padding: 8px 9px 8px 7px;\n font-size: 13px;\n }\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index40.cjs","names":[],"sources":["../src/components/sidebar-nav/sidebar-nav.module.css"],"sourcesContent":[".sidebarNav {\n --sidebar-nav-icon-size: 18px;\n --sidebar-nav-icon-size-mobile: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n align-items: stretch;\n min-height: 0;\n}\n\n.sidebarNavCollapsed {\n gap: 10px;\n}\n\n.header,\n.footer {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.footer {\n margin-top: auto;\n padding-top: 12px;\n border-top: 1px solid var(--border);\n}\n\n.sections {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n gap: 14px;\n}\n\n.section {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sectionItems {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n.sectionLabel {\n padding: 0 10px;\n font-size: 11px;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--muted-foreground);\n opacity: 0.75;\n}\n\n.item {\n color: var(--foreground);\n background: transparent;\n border: none;\n box-shadow: none;\n padding: 10px 12px 10px 10px;\n border-radius: 10px;\n text-decoration: none;\n font-size: 14px;\n display: grid;\n grid-template-columns: var(--sidebar-nav-icon-size) minmax(0, 1fr);\n align-items: center;\n column-gap: 10px;\n width: 100%;\n text-align: left;\n box-sizing: border-box;\n line-height: 1.2;\n transition: background 120ms ease, color 120ms ease;\n}\n\n.item.itemWithoutIcon {\n grid-template-columns: minmax(0, 1fr);\n}\n\nbutton.item {\n font-family: inherit;\n cursor: pointer;\n}\n\n.item:focus-visible {\n outline: var(--focus-ring);\n outline-offset: var(--focus-ring-offset);\n}\n\n.item:hover {\n background: color-mix(in srgb, var(--primary) 10%, transparent);\n}\n\n.item.itemActive {\n background: color-mix(in srgb, var(--primary) 18%, transparent);\n color: var(--foreground);\n font-weight: 700;\n}\n\n.itemCollapsed {\n grid-template-columns: 1fr;\n justify-items: center;\n padding-right: 10px;\n padding-left: 10px;\n}\n\n.itemDisabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.icon {\n width: var(--sidebar-nav-icon-size);\n height: var(--sidebar-nav-icon-size);\n min-width: var(--sidebar-nav-icon-size);\n color: var(--muted-foreground);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n vertical-align: middle;\n}\n\n.icon > * {\n width: 100% !important;\n height: 100% !important;\n max-width: 100%;\n max-height: 100%;\n}\n\n.icon :where(svg) {\n width: 100%;\n height: 100%;\n display: block;\n stroke: currentColor;\n}\n\n.item.itemActive .icon {\n color: var(--primary);\n}\n\n.itemBody {\n display: flex;\n min-width: 0;\n flex: 1 1 auto;\n flex-direction: column;\n gap: 3px;\n overflow: hidden;\n}\n\n.labelRow {\n display: flex;\n min-width: 0;\n align-items: center;\n gap: 8px;\n}\n\n.label {\n flex: 1;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.description {\n color: var(--muted-foreground);\n font-size: 12px;\n line-height: 1.35;\n}\n\n.badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 4px 8px;\n border-radius: 999px;\n border: 1px solid var(--border);\n background: color-mix(in srgb, var(--foreground) 4%, transparent);\n color: var(--muted-foreground);\n font-size: 11px;\n letter-spacing: 0.04em;\n text-transform: uppercase;\n}\n\n@media (max-width: 960px) {\n .sidebarNav {\n gap: 10px;\n }\n\n .sections {\n gap: 12px;\n }\n\n .sectionItems {\n gap: 6px;\n }\n\n .item {\n padding: 9px 10px 9px 8px;\n border-radius: 9px;\n font-size: 14px;\n grid-template-columns: var(--sidebar-nav-icon-size-mobile) minmax(0, 1fr);\n column-gap: 8px;\n }\n\n .icon {\n width: var(--sidebar-nav-icon-size-mobile);\n height: var(--sidebar-nav-icon-size-mobile);\n min-width: var(--sidebar-nav-icon-size-mobile);\n }\n\n .icon :where(svg) {\n width: var(--sidebar-nav-icon-size-mobile);\n height: var(--sidebar-nav-icon-size-mobile);\n }\n\n .description {\n font-size: 11px;\n }\n}\n\n@media (max-width: 480px) {\n .item {\n padding: 8px 9px 8px 7px;\n font-size: 13px;\n }\n}\n"],"mappings":""}
|
package/dist/index40.js
CHANGED
|
@@ -114,11 +114,12 @@ function SidebarNav({ items = [], sections, currentPath, getIsActive, matchStrat
|
|
|
114
114
|
function SidebarNavEntry({ item, active, collapsed, itemClassName, onItemClick }) {
|
|
115
115
|
const rel = item.rel ?? (item.target === "_blank" ? "noreferrer" : void 0);
|
|
116
116
|
const title = item.title ?? (typeof item.label === "string" ? item.label : void 0);
|
|
117
|
-
const
|
|
118
|
-
const
|
|
117
|
+
const hasIcon = Boolean(item.icon);
|
|
118
|
+
const classes = cx(sidebar_nav_module_default.item, !hasIcon && sidebar_nav_module_default.itemWithoutIcon, active && sidebar_nav_module_default.itemActive, collapsed && sidebar_nav_module_default.itemCollapsed, item.disabled && sidebar_nav_module_default.itemDisabled, itemClassName);
|
|
119
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [hasIcon ? /* @__PURE__ */ jsx("span", {
|
|
119
120
|
className: sidebar_nav_module_default.icon,
|
|
120
121
|
children: item.icon
|
|
121
|
-
}), !collapsed ? /* @__PURE__ */ jsxs("span", {
|
|
122
|
+
}) : null, !collapsed ? /* @__PURE__ */ jsxs("span", {
|
|
122
123
|
className: sidebar_nav_module_default.itemBody,
|
|
123
124
|
children: [/* @__PURE__ */ jsxs("span", {
|
|
124
125
|
className: sidebar_nav_module_default.labelRow,
|
package/dist/index40.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index40.js","names":[],"sources":["../src/components/sidebar-nav/SidebarNav.tsx"],"sourcesContent":["\"use client\";\n\nimport { type AnchorHTMLAttributes, type CSSProperties, type ReactNode, useMemo } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./sidebar-nav.module.css\";\n\nexport type SidebarNavItem = {\n label: string;\n href?: string;\n icon?: ReactNode;\n description?: ReactNode;\n badge?: ReactNode;\n active?: boolean;\n disabled?: boolean;\n /**\n * When `true`, this item uses exact matching (matches its own path and paths starting with `{href}/`)\n * instead of prefix matching. This flag takes precedence over the global `matchStrategy` prop on a\n * per-item basis — even when `matchStrategy=\"prefix\"`, an item with `exact: true` will use exact matching.\n * When `matchStrategy=\"most-specific\"`, exact-flagged items participate in the length-based tiebreaker\n * like all other candidates, provided they pass their own match check first.\n */\n exact?: boolean;\n title?: string;\n target?: AnchorHTMLAttributes<HTMLAnchorElement>[\"target\"];\n rel?: AnchorHTMLAttributes<HTMLAnchorElement>[\"rel\"];\n onClick?: () => void;\n};\n\nexport type SidebarNavSection = {\n id?: string;\n label?: ReactNode;\n items: SidebarNavItem[];\n};\n\nexport type SidebarNavProps = {\n items?: SidebarNavItem[];\n sections?: SidebarNavSection[];\n currentPath?: string;\n getIsActive?: (item: SidebarNavItem, currentPath?: string) => boolean;\n matchStrategy?: \"prefix\" | \"most-specific\";\n onItemClick?: (item: SidebarNavItem) => void;\n header?: ReactNode;\n footer?: ReactNode;\n ariaLabel?: string;\n collapsed?: boolean;\n iconSize?: number | string;\n className?: string;\n itemClassName?: string;\n sectionClassName?: string;\n};\n\nconst isActivePrefix = (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n if (!path) return false;\n if (item.href === \"/\") return path === \"/\";\n return path.startsWith(item.href);\n};\n\nconst isActiveExact = (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n if (!path) return false;\n // Root href \"/\" must match exactly — otherwise every path would match.\n if (item.href === \"/\") return path === \"/\";\n // Normalize trailing slashes for consistent matching with findMostSpecific length computation.\n const normalizedHref = item.href.endsWith(\"/\") ? item.href.slice(0, -1) : item.href;\n return normalizedHref === path || path.startsWith(`${normalizedHref}/`);\n};\n\n// Natural matching helpers that ignore manual `active` overrides — used inside findMostSpecific\n// so that manually-set active flags don't hijack the length-based tiebreaker.\nconst isNaturalPrefixMatch = (href: string, path: string) => {\n if (href === \"/\") return path === \"/\";\n return path.startsWith(href);\n};\n\nconst isNaturalExactMatch = (href: string, path: string) => {\n if (href === \"/\") return path === \"/\";\n const normalizedHref = href.endsWith(\"/\") ? href.slice(0, -1) : href;\n return normalizedHref === path;\n};\n\nconst hrefLength = (href: string) => (href.endsWith(\"/\") ? href.length - 1 : href.length);\n\nconst findMostSpecific = (items: SidebarNavItem[], currentPath?: string): Set<string> => {\n const result = new Set<string>();\n if (!currentPath) return result;\n\n // Collect all items that naturally match the path — use natural matching helpers so that\n // manually-set `active` flags don't participate in the length-based tiebreaker.\n // Exclude disabled items from matching since they are not interactive targets.\n const matchingItems = items.filter(item => {\n if (item.disabled || !item.href) return false;\n return item.exact\n ? isNaturalExactMatch(item.href, currentPath)\n : isNaturalPrefixMatch(item.href, currentPath);\n });\n\n if (matchingItems.length === 0) return result;\n\n // Find the longest href among prefix matches.\n let maxLen = 0;\n for (const item of matchingItems) {\n if (!item.href) continue;\n const len = hrefLength(item.href);\n if (len > maxLen) maxLen = len;\n }\n\n // Only the items with the longest href are active.\n for (const item of matchingItems) {\n if (!item.href) continue;\n if (hrefLength(item.href) === maxLen) result.add(item.href);\n }\n\n return result;\n};\n\nexport function SidebarNav({\n items = [],\n sections,\n currentPath,\n getIsActive,\n matchStrategy = \"prefix\",\n onItemClick,\n header,\n footer,\n ariaLabel = \"Sidebar navigation\",\n collapsed = false,\n iconSize,\n className,\n itemClassName,\n sectionClassName,\n}: SidebarNavProps) {\n const resolvedSections = useMemo(() => {\n return sections?.length ? sections : [{ id: \"default\", items }];\n }, [sections, items]);\n\n // Stable reference to all items — avoids recreating on every render when `sections` is falsy.\n const allItems = useMemo(() => resolvedSections.flatMap(section => section.items), [resolvedSections]);\n\n // Build the default isActive function based on matchStrategy.\n const defaultIsActiveFn = useMemo<(item: SidebarNavItem, path?: string) => boolean>(() => {\n if (matchStrategy === \"most-specific\") {\n const mostSpecificHrefs = findMostSpecific(allItems, currentPath);\n return (item: SidebarNavItem) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n // Exact-flagged items participate in the length-based tiebreaker like all other candidates.\n return mostSpecificHrefs.has(item.href);\n };\n } else {\n return (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (item.exact) return isActiveExact(item, path);\n return isActivePrefix(item, path);\n };\n }\n }, [matchStrategy, allItems, currentPath]);\n\n const resolvedGetIsActive = getIsActive ?? defaultIsActiveFn;\n\n const style =\n iconSize !== undefined\n ? ({\n [\"--sidebar-nav-icon-size\" as string]:\n typeof iconSize === \"number\" ? `${iconSize}px` : iconSize,\n } satisfies CSSProperties)\n : undefined;\n\n return (\n <nav\n className={cx(\n styles.sidebarNav,\n collapsed && styles.sidebarNavCollapsed,\n className,\n )}\n aria-label={ariaLabel}\n style={style}\n >\n {header ? <div className={styles.header}>{header}</div> : null}\n <div className={styles.sections}>\n {resolvedSections.map((section, sectionIndex) => (\n <div\n key={section.id ?? `section-${sectionIndex}`}\n className={cx(styles.section, sectionClassName)}\n >\n {section.label && !collapsed ? (\n <div className={styles.sectionLabel}>{section.label}</div>\n ) : null}\n <div className={styles.sectionItems}>\n {section.items.map((item, itemIndex) => (\n <SidebarNavEntry\n key={`${section.id ?? sectionIndex}-${item.href ?? item.title ?? itemIndex}`}\n item={item}\n active={resolvedGetIsActive(item, currentPath)}\n collapsed={collapsed}\n itemClassName={itemClassName}\n onItemClick={onItemClick}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n {footer ? <div className={styles.footer}>{footer}</div> : null}\n </nav>\n );\n}\n\ntype SidebarNavEntryProps = {\n item: SidebarNavItem;\n active: boolean;\n collapsed: boolean;\n itemClassName?: string;\n onItemClick?: (item: SidebarNavItem) => void;\n};\n\nfunction SidebarNavEntry({\n item,\n active,\n collapsed,\n itemClassName,\n onItemClick,\n}: SidebarNavEntryProps) {\n const rel = item.rel ?? (item.target === \"_blank\" ? \"noreferrer\" : undefined);\n const title = item.title ?? (typeof item.label === \"string\" ? item.label : undefined);\n const classes = cx(\n styles.item,\n active && styles.itemActive,\n collapsed && styles.itemCollapsed,\n item.disabled && styles.itemDisabled,\n itemClassName,\n );\n const content = (\n <>\n {item.icon && <span className={styles.icon}>{item.icon}</span>}\n {!collapsed ? (\n <span className={styles.itemBody}>\n <span className={styles.labelRow}>\n <span className={styles.label}>{item.label}</span>\n {item.badge && <span className={styles.badge}>{item.badge}</span>}\n </span>\n {item.description ? <span className={styles.description}>{item.description}</span> : null}\n </span>\n ) : null}\n </>\n );\n\n const handleClick = () => {\n if (item.disabled) return;\n item.onClick?.();\n onItemClick?.(item);\n };\n\n if (!item.href) {\n return (\n <button\n type=\"button\"\n className={classes}\n aria-current={active ? \"page\" : undefined}\n aria-disabled={item.disabled ? \"true\" : undefined}\n disabled={item.disabled}\n title={collapsed ? title : undefined}\n onClick={handleClick}\n >\n {content}\n </button>\n );\n }\n\n if (item.disabled) {\n return (\n <div\n className={classes}\n aria-current={active ? \"page\" : undefined}\n aria-disabled=\"true\"\n title={collapsed ? title : undefined}\n >\n {content}\n </div>\n );\n }\n\n return (\n <a\n className={classes}\n href={item.href}\n target={item.target}\n rel={rel}\n aria-current={active ? \"page\" : undefined}\n title={collapsed ? title : undefined}\n onClick={handleClick}\n >\n {content}\n </a>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index40.js","names":[],"sources":["../src/components/sidebar-nav/SidebarNav.tsx"],"sourcesContent":["\"use client\";\n\nimport { type AnchorHTMLAttributes, type CSSProperties, type ReactNode, useMemo } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./sidebar-nav.module.css\";\n\nexport type SidebarNavItem = {\n label: string;\n href?: string;\n icon?: ReactNode;\n description?: ReactNode;\n badge?: ReactNode;\n active?: boolean;\n disabled?: boolean;\n /**\n * When `true`, this item uses exact matching (matches its own path and paths starting with `{href}/`)\n * instead of prefix matching. This flag takes precedence over the global `matchStrategy` prop on a\n * per-item basis — even when `matchStrategy=\"prefix\"`, an item with `exact: true` will use exact matching.\n * When `matchStrategy=\"most-specific\"`, exact-flagged items participate in the length-based tiebreaker\n * like all other candidates, provided they pass their own match check first.\n */\n exact?: boolean;\n title?: string;\n target?: AnchorHTMLAttributes<HTMLAnchorElement>[\"target\"];\n rel?: AnchorHTMLAttributes<HTMLAnchorElement>[\"rel\"];\n onClick?: () => void;\n};\n\nexport type SidebarNavSection = {\n id?: string;\n label?: ReactNode;\n items: SidebarNavItem[];\n};\n\nexport type SidebarNavProps = {\n items?: SidebarNavItem[];\n sections?: SidebarNavSection[];\n currentPath?: string;\n getIsActive?: (item: SidebarNavItem, currentPath?: string) => boolean;\n matchStrategy?: \"prefix\" | \"most-specific\";\n onItemClick?: (item: SidebarNavItem) => void;\n header?: ReactNode;\n footer?: ReactNode;\n ariaLabel?: string;\n collapsed?: boolean;\n iconSize?: number | string;\n className?: string;\n itemClassName?: string;\n sectionClassName?: string;\n};\n\nconst isActivePrefix = (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n if (!path) return false;\n if (item.href === \"/\") return path === \"/\";\n return path.startsWith(item.href);\n};\n\nconst isActiveExact = (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n if (!path) return false;\n // Root href \"/\" must match exactly — otherwise every path would match.\n if (item.href === \"/\") return path === \"/\";\n // Normalize trailing slashes for consistent matching with findMostSpecific length computation.\n const normalizedHref = item.href.endsWith(\"/\") ? item.href.slice(0, -1) : item.href;\n return normalizedHref === path || path.startsWith(`${normalizedHref}/`);\n};\n\n// Natural matching helpers that ignore manual `active` overrides — used inside findMostSpecific\n// so that manually-set active flags don't hijack the length-based tiebreaker.\nconst isNaturalPrefixMatch = (href: string, path: string) => {\n if (href === \"/\") return path === \"/\";\n return path.startsWith(href);\n};\n\nconst isNaturalExactMatch = (href: string, path: string) => {\n if (href === \"/\") return path === \"/\";\n const normalizedHref = href.endsWith(\"/\") ? href.slice(0, -1) : href;\n return normalizedHref === path;\n};\n\nconst hrefLength = (href: string) => (href.endsWith(\"/\") ? href.length - 1 : href.length);\n\nconst findMostSpecific = (items: SidebarNavItem[], currentPath?: string): Set<string> => {\n const result = new Set<string>();\n if (!currentPath) return result;\n\n // Collect all items that naturally match the path — use natural matching helpers so that\n // manually-set `active` flags don't participate in the length-based tiebreaker.\n // Exclude disabled items from matching since they are not interactive targets.\n const matchingItems = items.filter(item => {\n if (item.disabled || !item.href) return false;\n return item.exact\n ? isNaturalExactMatch(item.href, currentPath)\n : isNaturalPrefixMatch(item.href, currentPath);\n });\n\n if (matchingItems.length === 0) return result;\n\n // Find the longest href among prefix matches.\n let maxLen = 0;\n for (const item of matchingItems) {\n if (!item.href) continue;\n const len = hrefLength(item.href);\n if (len > maxLen) maxLen = len;\n }\n\n // Only the items with the longest href are active.\n for (const item of matchingItems) {\n if (!item.href) continue;\n if (hrefLength(item.href) === maxLen) result.add(item.href);\n }\n\n return result;\n};\n\nexport function SidebarNav({\n items = [],\n sections,\n currentPath,\n getIsActive,\n matchStrategy = \"prefix\",\n onItemClick,\n header,\n footer,\n ariaLabel = \"Sidebar navigation\",\n collapsed = false,\n iconSize,\n className,\n itemClassName,\n sectionClassName,\n}: SidebarNavProps) {\n const resolvedSections = useMemo(() => {\n return sections?.length ? sections : [{ id: \"default\", items }];\n }, [sections, items]);\n\n // Stable reference to all items — avoids recreating on every render when `sections` is falsy.\n const allItems = useMemo(() => resolvedSections.flatMap(section => section.items), [resolvedSections]);\n\n // Build the default isActive function based on matchStrategy.\n const defaultIsActiveFn = useMemo<(item: SidebarNavItem, path?: string) => boolean>(() => {\n if (matchStrategy === \"most-specific\") {\n const mostSpecificHrefs = findMostSpecific(allItems, currentPath);\n return (item: SidebarNavItem) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n // Exact-flagged items participate in the length-based tiebreaker like all other candidates.\n return mostSpecificHrefs.has(item.href);\n };\n } else {\n return (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (item.exact) return isActiveExact(item, path);\n return isActivePrefix(item, path);\n };\n }\n }, [matchStrategy, allItems, currentPath]);\n\n const resolvedGetIsActive = getIsActive ?? defaultIsActiveFn;\n\n const style =\n iconSize !== undefined\n ? ({\n [\"--sidebar-nav-icon-size\" as string]:\n typeof iconSize === \"number\" ? `${iconSize}px` : iconSize,\n } satisfies CSSProperties)\n : undefined;\n\n return (\n <nav\n className={cx(\n styles.sidebarNav,\n collapsed && styles.sidebarNavCollapsed,\n className,\n )}\n aria-label={ariaLabel}\n style={style}\n >\n {header ? <div className={styles.header}>{header}</div> : null}\n <div className={styles.sections}>\n {resolvedSections.map((section, sectionIndex) => (\n <div\n key={section.id ?? `section-${sectionIndex}`}\n className={cx(styles.section, sectionClassName)}\n >\n {section.label && !collapsed ? (\n <div className={styles.sectionLabel}>{section.label}</div>\n ) : null}\n <div className={styles.sectionItems}>\n {section.items.map((item, itemIndex) => (\n <SidebarNavEntry\n key={`${section.id ?? sectionIndex}-${item.href ?? item.title ?? itemIndex}`}\n item={item}\n active={resolvedGetIsActive(item, currentPath)}\n collapsed={collapsed}\n itemClassName={itemClassName}\n onItemClick={onItemClick}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n {footer ? <div className={styles.footer}>{footer}</div> : null}\n </nav>\n );\n}\n\ntype SidebarNavEntryProps = {\n item: SidebarNavItem;\n active: boolean;\n collapsed: boolean;\n itemClassName?: string;\n onItemClick?: (item: SidebarNavItem) => void;\n};\n\nfunction SidebarNavEntry({\n item,\n active,\n collapsed,\n itemClassName,\n onItemClick,\n}: SidebarNavEntryProps) {\n const rel = item.rel ?? (item.target === \"_blank\" ? \"noreferrer\" : undefined);\n const title = item.title ?? (typeof item.label === \"string\" ? item.label : undefined);\n const hasIcon = Boolean(item.icon);\n const classes = cx(\n styles.item,\n !hasIcon && styles.itemWithoutIcon,\n active && styles.itemActive,\n collapsed && styles.itemCollapsed,\n item.disabled && styles.itemDisabled,\n itemClassName,\n );\n const content = (\n <>\n {hasIcon ? <span className={styles.icon}>{item.icon}</span> : null}\n {!collapsed ? (\n <span className={styles.itemBody}>\n <span className={styles.labelRow}>\n <span className={styles.label}>{item.label}</span>\n {item.badge && <span className={styles.badge}>{item.badge}</span>}\n </span>\n {item.description ? <span className={styles.description}>{item.description}</span> : null}\n </span>\n ) : null}\n </>\n );\n\n const handleClick = () => {\n if (item.disabled) return;\n item.onClick?.();\n onItemClick?.(item);\n };\n\n if (!item.href) {\n return (\n <button\n type=\"button\"\n className={classes}\n aria-current={active ? \"page\" : undefined}\n aria-disabled={item.disabled ? \"true\" : undefined}\n disabled={item.disabled}\n title={collapsed ? title : undefined}\n onClick={handleClick}\n >\n {content}\n </button>\n );\n }\n\n if (item.disabled) {\n return (\n <div\n className={classes}\n aria-current={active ? \"page\" : undefined}\n aria-disabled=\"true\"\n title={collapsed ? title : undefined}\n >\n {content}\n </div>\n );\n }\n\n return (\n <a\n className={classes}\n href={item.href}\n target={item.target}\n rel={rel}\n aria-current={active ? \"page\" : undefined}\n title={collapsed ? title : undefined}\n onClick={handleClick}\n >\n {content}\n </a>\n );\n}\n"],"mappings":"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"}
|
package/dist/index41.cjs
CHANGED
|
@@ -114,11 +114,12 @@ function SidebarNav({ items = [], sections, currentPath, getIsActive, matchStrat
|
|
|
114
114
|
function SidebarNavEntry({ item, active, collapsed, itemClassName, onItemClick }) {
|
|
115
115
|
const rel = item.rel ?? (item.target === "_blank" ? "noreferrer" : void 0);
|
|
116
116
|
const title = item.title ?? (typeof item.label === "string" ? item.label : void 0);
|
|
117
|
-
const
|
|
118
|
-
const
|
|
117
|
+
const hasIcon = Boolean(item.icon);
|
|
118
|
+
const classes = require_cx.cx(require_sidebar_nav_module.default.item, !hasIcon && require_sidebar_nav_module.default.itemWithoutIcon, active && require_sidebar_nav_module.default.itemActive, collapsed && require_sidebar_nav_module.default.itemCollapsed, item.disabled && require_sidebar_nav_module.default.itemDisabled, itemClassName);
|
|
119
|
+
const content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [hasIcon ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
119
120
|
className: require_sidebar_nav_module.default.icon,
|
|
120
121
|
children: item.icon
|
|
121
|
-
}), !collapsed ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
122
|
+
}) : null, !collapsed ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
122
123
|
className: require_sidebar_nav_module.default.itemBody,
|
|
123
124
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
124
125
|
className: require_sidebar_nav_module.default.labelRow,
|
package/dist/index41.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index41.cjs","names":[],"sources":["../src/components/sidebar-nav/SidebarNav.tsx"],"sourcesContent":["\"use client\";\n\nimport { type AnchorHTMLAttributes, type CSSProperties, type ReactNode, useMemo } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./sidebar-nav.module.css\";\n\nexport type SidebarNavItem = {\n label: string;\n href?: string;\n icon?: ReactNode;\n description?: ReactNode;\n badge?: ReactNode;\n active?: boolean;\n disabled?: boolean;\n /**\n * When `true`, this item uses exact matching (matches its own path and paths starting with `{href}/`)\n * instead of prefix matching. This flag takes precedence over the global `matchStrategy` prop on a\n * per-item basis — even when `matchStrategy=\"prefix\"`, an item with `exact: true` will use exact matching.\n * When `matchStrategy=\"most-specific\"`, exact-flagged items participate in the length-based tiebreaker\n * like all other candidates, provided they pass their own match check first.\n */\n exact?: boolean;\n title?: string;\n target?: AnchorHTMLAttributes<HTMLAnchorElement>[\"target\"];\n rel?: AnchorHTMLAttributes<HTMLAnchorElement>[\"rel\"];\n onClick?: () => void;\n};\n\nexport type SidebarNavSection = {\n id?: string;\n label?: ReactNode;\n items: SidebarNavItem[];\n};\n\nexport type SidebarNavProps = {\n items?: SidebarNavItem[];\n sections?: SidebarNavSection[];\n currentPath?: string;\n getIsActive?: (item: SidebarNavItem, currentPath?: string) => boolean;\n matchStrategy?: \"prefix\" | \"most-specific\";\n onItemClick?: (item: SidebarNavItem) => void;\n header?: ReactNode;\n footer?: ReactNode;\n ariaLabel?: string;\n collapsed?: boolean;\n iconSize?: number | string;\n className?: string;\n itemClassName?: string;\n sectionClassName?: string;\n};\n\nconst isActivePrefix = (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n if (!path) return false;\n if (item.href === \"/\") return path === \"/\";\n return path.startsWith(item.href);\n};\n\nconst isActiveExact = (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n if (!path) return false;\n // Root href \"/\" must match exactly — otherwise every path would match.\n if (item.href === \"/\") return path === \"/\";\n // Normalize trailing slashes for consistent matching with findMostSpecific length computation.\n const normalizedHref = item.href.endsWith(\"/\") ? item.href.slice(0, -1) : item.href;\n return normalizedHref === path || path.startsWith(`${normalizedHref}/`);\n};\n\n// Natural matching helpers that ignore manual `active` overrides — used inside findMostSpecific\n// so that manually-set active flags don't hijack the length-based tiebreaker.\nconst isNaturalPrefixMatch = (href: string, path: string) => {\n if (href === \"/\") return path === \"/\";\n return path.startsWith(href);\n};\n\nconst isNaturalExactMatch = (href: string, path: string) => {\n if (href === \"/\") return path === \"/\";\n const normalizedHref = href.endsWith(\"/\") ? href.slice(0, -1) : href;\n return normalizedHref === path;\n};\n\nconst hrefLength = (href: string) => (href.endsWith(\"/\") ? href.length - 1 : href.length);\n\nconst findMostSpecific = (items: SidebarNavItem[], currentPath?: string): Set<string> => {\n const result = new Set<string>();\n if (!currentPath) return result;\n\n // Collect all items that naturally match the path — use natural matching helpers so that\n // manually-set `active` flags don't participate in the length-based tiebreaker.\n // Exclude disabled items from matching since they are not interactive targets.\n const matchingItems = items.filter(item => {\n if (item.disabled || !item.href) return false;\n return item.exact\n ? isNaturalExactMatch(item.href, currentPath)\n : isNaturalPrefixMatch(item.href, currentPath);\n });\n\n if (matchingItems.length === 0) return result;\n\n // Find the longest href among prefix matches.\n let maxLen = 0;\n for (const item of matchingItems) {\n if (!item.href) continue;\n const len = hrefLength(item.href);\n if (len > maxLen) maxLen = len;\n }\n\n // Only the items with the longest href are active.\n for (const item of matchingItems) {\n if (!item.href) continue;\n if (hrefLength(item.href) === maxLen) result.add(item.href);\n }\n\n return result;\n};\n\nexport function SidebarNav({\n items = [],\n sections,\n currentPath,\n getIsActive,\n matchStrategy = \"prefix\",\n onItemClick,\n header,\n footer,\n ariaLabel = \"Sidebar navigation\",\n collapsed = false,\n iconSize,\n className,\n itemClassName,\n sectionClassName,\n}: SidebarNavProps) {\n const resolvedSections = useMemo(() => {\n return sections?.length ? sections : [{ id: \"default\", items }];\n }, [sections, items]);\n\n // Stable reference to all items — avoids recreating on every render when `sections` is falsy.\n const allItems = useMemo(() => resolvedSections.flatMap(section => section.items), [resolvedSections]);\n\n // Build the default isActive function based on matchStrategy.\n const defaultIsActiveFn = useMemo<(item: SidebarNavItem, path?: string) => boolean>(() => {\n if (matchStrategy === \"most-specific\") {\n const mostSpecificHrefs = findMostSpecific(allItems, currentPath);\n return (item: SidebarNavItem) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n // Exact-flagged items participate in the length-based tiebreaker like all other candidates.\n return mostSpecificHrefs.has(item.href);\n };\n } else {\n return (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (item.exact) return isActiveExact(item, path);\n return isActivePrefix(item, path);\n };\n }\n }, [matchStrategy, allItems, currentPath]);\n\n const resolvedGetIsActive = getIsActive ?? defaultIsActiveFn;\n\n const style =\n iconSize !== undefined\n ? ({\n [\"--sidebar-nav-icon-size\" as string]:\n typeof iconSize === \"number\" ? `${iconSize}px` : iconSize,\n } satisfies CSSProperties)\n : undefined;\n\n return (\n <nav\n className={cx(\n styles.sidebarNav,\n collapsed && styles.sidebarNavCollapsed,\n className,\n )}\n aria-label={ariaLabel}\n style={style}\n >\n {header ? <div className={styles.header}>{header}</div> : null}\n <div className={styles.sections}>\n {resolvedSections.map((section, sectionIndex) => (\n <div\n key={section.id ?? `section-${sectionIndex}`}\n className={cx(styles.section, sectionClassName)}\n >\n {section.label && !collapsed ? (\n <div className={styles.sectionLabel}>{section.label}</div>\n ) : null}\n <div className={styles.sectionItems}>\n {section.items.map((item, itemIndex) => (\n <SidebarNavEntry\n key={`${section.id ?? sectionIndex}-${item.href ?? item.title ?? itemIndex}`}\n item={item}\n active={resolvedGetIsActive(item, currentPath)}\n collapsed={collapsed}\n itemClassName={itemClassName}\n onItemClick={onItemClick}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n {footer ? <div className={styles.footer}>{footer}</div> : null}\n </nav>\n );\n}\n\ntype SidebarNavEntryProps = {\n item: SidebarNavItem;\n active: boolean;\n collapsed: boolean;\n itemClassName?: string;\n onItemClick?: (item: SidebarNavItem) => void;\n};\n\nfunction SidebarNavEntry({\n item,\n active,\n collapsed,\n itemClassName,\n onItemClick,\n}: SidebarNavEntryProps) {\n const rel = item.rel ?? (item.target === \"_blank\" ? \"noreferrer\" : undefined);\n const title = item.title ?? (typeof item.label === \"string\" ? item.label : undefined);\n const classes = cx(\n styles.item,\n active && styles.itemActive,\n collapsed && styles.itemCollapsed,\n item.disabled && styles.itemDisabled,\n itemClassName,\n );\n const content = (\n <>\n {item.icon && <span className={styles.icon}>{item.icon}</span>}\n {!collapsed ? (\n <span className={styles.itemBody}>\n <span className={styles.labelRow}>\n <span className={styles.label}>{item.label}</span>\n {item.badge && <span className={styles.badge}>{item.badge}</span>}\n </span>\n {item.description ? <span className={styles.description}>{item.description}</span> : null}\n </span>\n ) : null}\n </>\n );\n\n const handleClick = () => {\n if (item.disabled) return;\n item.onClick?.();\n onItemClick?.(item);\n };\n\n if (!item.href) {\n return (\n <button\n type=\"button\"\n className={classes}\n aria-current={active ? \"page\" : undefined}\n aria-disabled={item.disabled ? \"true\" : undefined}\n disabled={item.disabled}\n title={collapsed ? title : undefined}\n onClick={handleClick}\n >\n {content}\n </button>\n );\n }\n\n if (item.disabled) {\n return (\n <div\n className={classes}\n aria-current={active ? \"page\" : undefined}\n aria-disabled=\"true\"\n title={collapsed ? title : undefined}\n >\n {content}\n </div>\n );\n }\n\n return (\n <a\n className={classes}\n href={item.href}\n target={item.target}\n rel={rel}\n aria-current={active ? \"page\" : undefined}\n title={collapsed ? title : undefined}\n onClick={handleClick}\n >\n {content}\n </a>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index41.cjs","names":[],"sources":["../src/components/sidebar-nav/SidebarNav.tsx"],"sourcesContent":["\"use client\";\n\nimport { type AnchorHTMLAttributes, type CSSProperties, type ReactNode, useMemo } from \"react\";\nimport { cx } from \"../../utils/cx\";\nimport styles from \"./sidebar-nav.module.css\";\n\nexport type SidebarNavItem = {\n label: string;\n href?: string;\n icon?: ReactNode;\n description?: ReactNode;\n badge?: ReactNode;\n active?: boolean;\n disabled?: boolean;\n /**\n * When `true`, this item uses exact matching (matches its own path and paths starting with `{href}/`)\n * instead of prefix matching. This flag takes precedence over the global `matchStrategy` prop on a\n * per-item basis — even when `matchStrategy=\"prefix\"`, an item with `exact: true` will use exact matching.\n * When `matchStrategy=\"most-specific\"`, exact-flagged items participate in the length-based tiebreaker\n * like all other candidates, provided they pass their own match check first.\n */\n exact?: boolean;\n title?: string;\n target?: AnchorHTMLAttributes<HTMLAnchorElement>[\"target\"];\n rel?: AnchorHTMLAttributes<HTMLAnchorElement>[\"rel\"];\n onClick?: () => void;\n};\n\nexport type SidebarNavSection = {\n id?: string;\n label?: ReactNode;\n items: SidebarNavItem[];\n};\n\nexport type SidebarNavProps = {\n items?: SidebarNavItem[];\n sections?: SidebarNavSection[];\n currentPath?: string;\n getIsActive?: (item: SidebarNavItem, currentPath?: string) => boolean;\n matchStrategy?: \"prefix\" | \"most-specific\";\n onItemClick?: (item: SidebarNavItem) => void;\n header?: ReactNode;\n footer?: ReactNode;\n ariaLabel?: string;\n collapsed?: boolean;\n iconSize?: number | string;\n className?: string;\n itemClassName?: string;\n sectionClassName?: string;\n};\n\nconst isActivePrefix = (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n if (!path) return false;\n if (item.href === \"/\") return path === \"/\";\n return path.startsWith(item.href);\n};\n\nconst isActiveExact = (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n if (!path) return false;\n // Root href \"/\" must match exactly — otherwise every path would match.\n if (item.href === \"/\") return path === \"/\";\n // Normalize trailing slashes for consistent matching with findMostSpecific length computation.\n const normalizedHref = item.href.endsWith(\"/\") ? item.href.slice(0, -1) : item.href;\n return normalizedHref === path || path.startsWith(`${normalizedHref}/`);\n};\n\n// Natural matching helpers that ignore manual `active` overrides — used inside findMostSpecific\n// so that manually-set active flags don't hijack the length-based tiebreaker.\nconst isNaturalPrefixMatch = (href: string, path: string) => {\n if (href === \"/\") return path === \"/\";\n return path.startsWith(href);\n};\n\nconst isNaturalExactMatch = (href: string, path: string) => {\n if (href === \"/\") return path === \"/\";\n const normalizedHref = href.endsWith(\"/\") ? href.slice(0, -1) : href;\n return normalizedHref === path;\n};\n\nconst hrefLength = (href: string) => (href.endsWith(\"/\") ? href.length - 1 : href.length);\n\nconst findMostSpecific = (items: SidebarNavItem[], currentPath?: string): Set<string> => {\n const result = new Set<string>();\n if (!currentPath) return result;\n\n // Collect all items that naturally match the path — use natural matching helpers so that\n // manually-set `active` flags don't participate in the length-based tiebreaker.\n // Exclude disabled items from matching since they are not interactive targets.\n const matchingItems = items.filter(item => {\n if (item.disabled || !item.href) return false;\n return item.exact\n ? isNaturalExactMatch(item.href, currentPath)\n : isNaturalPrefixMatch(item.href, currentPath);\n });\n\n if (matchingItems.length === 0) return result;\n\n // Find the longest href among prefix matches.\n let maxLen = 0;\n for (const item of matchingItems) {\n if (!item.href) continue;\n const len = hrefLength(item.href);\n if (len > maxLen) maxLen = len;\n }\n\n // Only the items with the longest href are active.\n for (const item of matchingItems) {\n if (!item.href) continue;\n if (hrefLength(item.href) === maxLen) result.add(item.href);\n }\n\n return result;\n};\n\nexport function SidebarNav({\n items = [],\n sections,\n currentPath,\n getIsActive,\n matchStrategy = \"prefix\",\n onItemClick,\n header,\n footer,\n ariaLabel = \"Sidebar navigation\",\n collapsed = false,\n iconSize,\n className,\n itemClassName,\n sectionClassName,\n}: SidebarNavProps) {\n const resolvedSections = useMemo(() => {\n return sections?.length ? sections : [{ id: \"default\", items }];\n }, [sections, items]);\n\n // Stable reference to all items — avoids recreating on every render when `sections` is falsy.\n const allItems = useMemo(() => resolvedSections.flatMap(section => section.items), [resolvedSections]);\n\n // Build the default isActive function based on matchStrategy.\n const defaultIsActiveFn = useMemo<(item: SidebarNavItem, path?: string) => boolean>(() => {\n if (matchStrategy === \"most-specific\") {\n const mostSpecificHrefs = findMostSpecific(allItems, currentPath);\n return (item: SidebarNavItem) => {\n if (item.active !== undefined) return item.active;\n if (!item.href) return false;\n // Exact-flagged items participate in the length-based tiebreaker like all other candidates.\n return mostSpecificHrefs.has(item.href);\n };\n } else {\n return (item: SidebarNavItem, path?: string) => {\n if (item.active !== undefined) return item.active;\n if (item.exact) return isActiveExact(item, path);\n return isActivePrefix(item, path);\n };\n }\n }, [matchStrategy, allItems, currentPath]);\n\n const resolvedGetIsActive = getIsActive ?? defaultIsActiveFn;\n\n const style =\n iconSize !== undefined\n ? ({\n [\"--sidebar-nav-icon-size\" as string]:\n typeof iconSize === \"number\" ? `${iconSize}px` : iconSize,\n } satisfies CSSProperties)\n : undefined;\n\n return (\n <nav\n className={cx(\n styles.sidebarNav,\n collapsed && styles.sidebarNavCollapsed,\n className,\n )}\n aria-label={ariaLabel}\n style={style}\n >\n {header ? <div className={styles.header}>{header}</div> : null}\n <div className={styles.sections}>\n {resolvedSections.map((section, sectionIndex) => (\n <div\n key={section.id ?? `section-${sectionIndex}`}\n className={cx(styles.section, sectionClassName)}\n >\n {section.label && !collapsed ? (\n <div className={styles.sectionLabel}>{section.label}</div>\n ) : null}\n <div className={styles.sectionItems}>\n {section.items.map((item, itemIndex) => (\n <SidebarNavEntry\n key={`${section.id ?? sectionIndex}-${item.href ?? item.title ?? itemIndex}`}\n item={item}\n active={resolvedGetIsActive(item, currentPath)}\n collapsed={collapsed}\n itemClassName={itemClassName}\n onItemClick={onItemClick}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n {footer ? <div className={styles.footer}>{footer}</div> : null}\n </nav>\n );\n}\n\ntype SidebarNavEntryProps = {\n item: SidebarNavItem;\n active: boolean;\n collapsed: boolean;\n itemClassName?: string;\n onItemClick?: (item: SidebarNavItem) => void;\n};\n\nfunction SidebarNavEntry({\n item,\n active,\n collapsed,\n itemClassName,\n onItemClick,\n}: SidebarNavEntryProps) {\n const rel = item.rel ?? (item.target === \"_blank\" ? \"noreferrer\" : undefined);\n const title = item.title ?? (typeof item.label === \"string\" ? item.label : undefined);\n const hasIcon = Boolean(item.icon);\n const classes = cx(\n styles.item,\n !hasIcon && styles.itemWithoutIcon,\n active && styles.itemActive,\n collapsed && styles.itemCollapsed,\n item.disabled && styles.itemDisabled,\n itemClassName,\n );\n const content = (\n <>\n {hasIcon ? <span className={styles.icon}>{item.icon}</span> : null}\n {!collapsed ? (\n <span className={styles.itemBody}>\n <span className={styles.labelRow}>\n <span className={styles.label}>{item.label}</span>\n {item.badge && <span className={styles.badge}>{item.badge}</span>}\n </span>\n {item.description ? <span className={styles.description}>{item.description}</span> : null}\n </span>\n ) : null}\n </>\n );\n\n const handleClick = () => {\n if (item.disabled) return;\n item.onClick?.();\n onItemClick?.(item);\n };\n\n if (!item.href) {\n return (\n <button\n type=\"button\"\n className={classes}\n aria-current={active ? \"page\" : undefined}\n aria-disabled={item.disabled ? \"true\" : undefined}\n disabled={item.disabled}\n title={collapsed ? title : undefined}\n onClick={handleClick}\n >\n {content}\n </button>\n );\n }\n\n if (item.disabled) {\n return (\n <div\n className={classes}\n aria-current={active ? \"page\" : undefined}\n aria-disabled=\"true\"\n title={collapsed ? title : undefined}\n >\n {content}\n </div>\n );\n }\n\n return (\n <a\n className={classes}\n href={item.href}\n target={item.target}\n rel={rel}\n aria-current={active ? \"page\" : undefined}\n title={collapsed ? title : undefined}\n onClick={handleClick}\n >\n {content}\n </a>\n );\n}\n"],"mappings":"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"}
|
package/dist/style.css
CHANGED
|
@@ -1804,6 +1804,10 @@ body {
|
|
|
1804
1804
|
transition: background 120ms ease, color 120ms ease;
|
|
1805
1805
|
}
|
|
1806
1806
|
|
|
1807
|
+
.uzi-sidebar-nav-module__item__uMHkJ.uzi-sidebar-nav-module__itemWithoutIcon__7gzPd {
|
|
1808
|
+
grid-template-columns: minmax(0, 1fr);
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1807
1811
|
button.uzi-sidebar-nav-module__item__uMHkJ {
|
|
1808
1812
|
font-family: inherit;
|
|
1809
1813
|
cursor: pointer;
|