@psnext/design-system 1.5.1 → 2.0.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/DESIGN.md +639 -0
- package/README.md +39 -2
- package/SKILL.md +101 -0
- package/bin/install-agent-skill.mjs +54 -0
- package/dist/Header.cjs +25 -25
- package/dist/Header.cjs.map +1 -1
- package/dist/Header.js +25 -25
- package/dist/Header.js.map +1 -1
- package/dist/Icon.cjs +19 -19
- package/dist/Icon.cjs.map +1 -1
- package/dist/Icon.js +19 -19
- package/dist/Icon.js.map +1 -1
- package/dist/Logo.cjs +4 -14
- package/dist/Logo.cjs.map +1 -1
- package/dist/Logo.js +4 -14
- package/dist/Logo.js.map +1 -1
- package/dist/Sidebar.cjs +26 -20
- package/dist/Sidebar.cjs.map +1 -1
- package/dist/Sidebar.js +21 -21
- package/dist/Sidebar.js.map +1 -1
- package/dist/cn.cjs +14 -1
- package/dist/cn.cjs.map +1 -1
- package/dist/cn.js +14 -1
- package/dist/cn.js.map +1 -1
- package/dist/index.cjs +13 -10
- package/dist/index.d.cts +5 -5
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -4
- package/dist/index10.d.cts +7 -7
- package/dist/index10.d.cts.map +1 -1
- package/dist/index10.d.ts +7 -7
- package/dist/index11.d.cts +3 -3
- package/dist/index11.d.cts.map +1 -1
- package/dist/index11.d.ts +3 -3
- package/dist/index11.d.ts.map +1 -1
- package/dist/index12.d.cts +18 -17
- package/dist/index12.d.cts.map +1 -1
- package/dist/index12.d.ts +18 -17
- package/dist/index12.d.ts.map +1 -1
- package/dist/index13.d.cts +6 -6
- package/dist/index13.d.cts.map +1 -1
- package/dist/index13.d.ts +6 -6
- package/dist/index14.d.cts +5 -5
- package/dist/index14.d.cts.map +1 -1
- package/dist/index14.d.ts +5 -5
- package/dist/index14.d.ts.map +1 -1
- package/dist/index15.d.cts +3 -3
- package/dist/index15.d.cts.map +1 -1
- package/dist/index15.d.ts +3 -3
- package/dist/index15.d.ts.map +1 -1
- package/dist/index16.d.cts +2 -2
- package/dist/index16.d.cts.map +1 -1
- package/dist/index16.d.ts +2 -2
- package/dist/index17.d.cts +4 -4
- package/dist/index17.d.cts.map +1 -1
- package/dist/index17.d.ts +4 -4
- package/dist/index17.d.ts.map +1 -1
- package/dist/index18.d.cts +11 -11
- package/dist/index18.d.cts.map +1 -1
- package/dist/index18.d.ts +11 -11
- package/dist/index19.d.cts +10 -10
- package/dist/index19.d.cts.map +1 -1
- package/dist/index19.d.ts +10 -10
- package/dist/index19.d.ts.map +1 -1
- package/dist/index2.d.cts +8 -8
- package/dist/index2.d.cts.map +1 -1
- package/dist/index2.d.ts +8 -8
- package/dist/index2.d.ts.map +1 -1
- package/dist/index20.d.cts +16 -16
- package/dist/index20.d.cts.map +1 -1
- package/dist/index20.d.ts +16 -16
- package/dist/index20.d.ts.map +1 -1
- package/dist/index21.d.cts +4 -4
- package/dist/index21.d.cts.map +1 -1
- package/dist/index21.d.ts +4 -4
- package/dist/index22.d.cts +11 -11
- package/dist/index22.d.cts.map +1 -1
- package/dist/index22.d.ts +11 -11
- package/dist/index22.d.ts.map +1 -1
- package/dist/index23.d.cts +16 -16
- package/dist/index23.d.cts.map +1 -1
- package/dist/index23.d.ts +16 -16
- package/dist/index23.d.ts.map +1 -1
- package/dist/index24.d.cts +10 -10
- package/dist/index24.d.cts.map +1 -1
- package/dist/index24.d.ts +10 -10
- package/dist/index25.d.cts +2 -2
- package/dist/index25.d.ts +2 -2
- package/dist/index25.d.ts.map +1 -1
- package/dist/index26.d.cts +14 -14
- package/dist/index26.d.cts.map +1 -1
- package/dist/index26.d.ts +14 -14
- package/dist/index26.d.ts.map +1 -1
- package/dist/index27.d.cts +7 -7
- package/dist/index27.d.ts +7 -7
- package/dist/index27.d.ts.map +1 -1
- package/dist/index28.d.cts +6 -6
- package/dist/index28.d.ts +5 -5
- package/dist/index28.d.ts.map +1 -1
- package/dist/index29.d.cts +4 -4
- package/dist/index29.d.ts +4 -4
- package/dist/index29.d.ts.map +1 -1
- package/dist/index3.d.cts +13 -13
- package/dist/index3.d.cts.map +1 -1
- package/dist/index3.d.ts +13 -13
- package/dist/index3.d.ts.map +1 -1
- package/dist/index30.d.cts +6 -6
- package/dist/index30.d.ts +4 -4
- package/dist/index31.d.cts +4 -4
- package/dist/index31.d.cts.map +1 -1
- package/dist/index31.d.ts +4 -4
- package/dist/index31.d.ts.map +1 -1
- package/dist/index32.d.cts +8 -5
- package/dist/index32.d.cts.map +1 -1
- package/dist/index32.d.ts +9 -6
- package/dist/index32.d.ts.map +1 -1
- package/dist/index33.d.cts +14 -10
- package/dist/index33.d.cts.map +1 -1
- package/dist/index33.d.ts +15 -11
- package/dist/index33.d.ts.map +1 -1
- package/dist/index34.d.cts +5 -5
- package/dist/index34.d.ts +5 -5
- package/dist/index34.d.ts.map +1 -1
- package/dist/index35.d.cts +14 -14
- package/dist/index35.d.ts +14 -14
- package/dist/index35.d.ts.map +1 -1
- package/dist/index36.d.cts +3 -3
- package/dist/index36.d.cts.map +1 -1
- package/dist/index36.d.ts +3 -3
- package/dist/index36.d.ts.map +1 -1
- package/dist/index37.d.cts +5 -5
- package/dist/index37.d.ts +4 -4
- package/dist/index37.d.ts.map +1 -1
- package/dist/index38.d.cts +2 -2
- package/dist/index38.d.ts +2 -2
- package/dist/index39.d.cts +17 -17
- package/dist/index39.d.cts.map +1 -1
- package/dist/index39.d.ts +17 -17
- package/dist/index39.d.ts.map +1 -1
- package/dist/index4.d.cts +2 -2
- package/dist/index4.d.cts.map +1 -1
- package/dist/index4.d.ts +2 -2
- package/dist/index4.d.ts.map +1 -1
- package/dist/index40.d.cts +4 -4
- package/dist/index40.d.cts.map +1 -1
- package/dist/index40.d.ts +5 -5
- package/dist/index40.d.ts.map +1 -1
- package/dist/index41.d.cts +11 -11
- package/dist/index41.d.cts.map +1 -1
- package/dist/index41.d.ts +11 -11
- package/dist/index41.d.ts.map +1 -1
- package/dist/index42.d.cts +8 -8
- package/dist/index42.d.cts.map +1 -1
- package/dist/index42.d.ts +8 -8
- package/dist/index42.d.ts.map +1 -1
- package/dist/index43.d.cts +10 -10
- package/dist/index43.d.cts.map +1 -1
- package/dist/index43.d.ts +10 -10
- package/dist/index43.d.ts.map +1 -1
- package/dist/index44.d.cts +1 -48
- package/dist/index44.d.ts +1 -48
- package/dist/index45.d.cts +42 -22
- package/dist/index45.d.cts.map +1 -1
- package/dist/index45.d.ts +42 -22
- package/dist/index45.d.ts.map +1 -1
- package/dist/index46.d.cts +21 -34
- package/dist/index46.d.cts.map +1 -1
- package/dist/index46.d.ts +21 -34
- package/dist/index46.d.ts.map +1 -1
- package/dist/index47.d.cts +33 -17
- package/dist/index47.d.cts.map +1 -1
- package/dist/index47.d.ts +33 -17
- package/dist/index47.d.ts.map +1 -1
- package/dist/index48.d.cts +18 -14
- package/dist/index48.d.cts.map +1 -1
- package/dist/index48.d.ts +18 -14
- package/dist/index48.d.ts.map +1 -1
- package/dist/index49.d.cts +12 -60
- package/dist/index49.d.cts.map +1 -1
- package/dist/index49.d.ts +12 -60
- package/dist/index49.d.ts.map +1 -1
- package/dist/index5.d.cts +7 -7
- package/dist/index5.d.cts.map +1 -1
- package/dist/index5.d.ts +7 -7
- package/dist/index5.d.ts.map +1 -1
- package/dist/index50.d.cts +55 -49
- package/dist/index50.d.cts.map +1 -1
- package/dist/index50.d.ts +55 -49
- package/dist/index50.d.ts.map +1 -1
- package/dist/index51.d.cts +56 -24
- package/dist/index51.d.cts.map +1 -1
- package/dist/index51.d.ts +56 -24
- package/dist/index51.d.ts.map +1 -1
- package/dist/index52.d.cts +25 -203
- package/dist/index52.d.cts.map +1 -1
- package/dist/index52.d.ts +25 -203
- package/dist/index52.d.ts.map +1 -1
- package/dist/index53.d.cts +198 -15
- package/dist/index53.d.cts.map +1 -1
- package/dist/index53.d.ts +198 -15
- package/dist/index53.d.ts.map +1 -1
- package/dist/index54.d.cts +21 -23
- package/dist/index54.d.cts.map +1 -1
- package/dist/index54.d.ts +21 -23
- package/dist/index54.d.ts.map +1 -1
- package/dist/index55.d.cts +21 -18
- package/dist/index55.d.cts.map +1 -1
- package/dist/index55.d.ts +21 -18
- package/dist/index55.d.ts.map +1 -1
- package/dist/index56.d.cts +21 -8
- package/dist/index56.d.cts.map +1 -1
- package/dist/index56.d.ts +21 -8
- package/dist/index56.d.ts.map +1 -1
- package/dist/index57.d.cts +6 -44
- package/dist/index57.d.cts.map +1 -1
- package/dist/index57.d.ts +6 -44
- package/dist/index57.d.ts.map +1 -1
- package/dist/index58.d.cts +46 -47
- package/dist/index58.d.cts.map +1 -1
- package/dist/index58.d.ts +46 -47
- package/dist/index58.d.ts.map +1 -1
- package/dist/index59.d.cts +47 -59
- package/dist/index59.d.cts.map +1 -1
- package/dist/index59.d.ts +47 -59
- package/dist/index59.d.ts.map +1 -1
- package/dist/index6.d.cts +7 -7
- package/dist/index6.d.cts.map +1 -1
- package/dist/index6.d.ts +7 -7
- package/dist/index6.d.ts.map +1 -1
- package/dist/index60.d.cts +56 -38
- package/dist/index60.d.cts.map +1 -1
- package/dist/index60.d.ts +56 -38
- package/dist/index60.d.ts.map +1 -1
- package/dist/index61.d.cts +38 -14
- package/dist/index61.d.cts.map +1 -1
- package/dist/index61.d.ts +38 -14
- package/dist/index61.d.ts.map +1 -1
- package/dist/index62.d.cts +20 -41
- package/dist/index62.d.cts.map +1 -1
- package/dist/index62.d.ts +20 -41
- package/dist/index62.d.ts.map +1 -1
- package/dist/index63.d.cts +41 -19
- package/dist/index63.d.cts.map +1 -1
- package/dist/index63.d.ts +41 -19
- package/dist/index63.d.ts.map +1 -1
- package/dist/index64.d.cts +14 -39
- package/dist/index64.d.cts.map +1 -1
- package/dist/index64.d.ts +14 -39
- package/dist/index64.d.ts.map +1 -1
- package/dist/index65.d.cts +39 -16
- package/dist/index65.d.cts.map +1 -1
- package/dist/index65.d.ts +39 -16
- package/dist/index65.d.ts.map +1 -1
- package/dist/index66.d.cts +18 -12
- package/dist/index66.d.cts.map +1 -1
- package/dist/index66.d.ts +18 -12
- package/dist/index66.d.ts.map +1 -1
- package/dist/index67.d.cts +12 -30
- package/dist/index67.d.cts.map +1 -1
- package/dist/index67.d.ts +12 -30
- package/dist/index67.d.ts.map +1 -1
- package/dist/index68.d.cts +28 -27
- package/dist/index68.d.cts.map +1 -1
- package/dist/index68.d.ts +28 -27
- package/dist/index68.d.ts.map +1 -1
- package/dist/index69.d.cts +36 -69
- package/dist/index69.d.cts.map +1 -0
- package/dist/index69.d.ts +36 -69
- package/dist/index69.d.ts.map +1 -0
- package/dist/index7.d.cts +8 -8
- package/dist/index7.d.cts.map +1 -1
- package/dist/index7.d.ts +8 -8
- package/dist/index70.d.cts +76 -237
- package/dist/index70.d.cts.map +1 -1
- package/dist/index70.d.ts +76 -237
- package/dist/index70.d.ts.map +1 -1
- package/dist/index71.d.cts +242 -0
- package/dist/index71.d.cts.map +1 -0
- package/dist/index71.d.ts +242 -0
- package/dist/index71.d.ts.map +1 -0
- package/dist/index8.d.cts +4 -4
- package/dist/index8.d.cts.map +1 -1
- package/dist/index8.d.ts +4 -4
- package/dist/index8.d.ts.map +1 -1
- package/dist/index9.d.cts +2 -2
- package/dist/index9.d.ts +2 -2
- package/dist/layouts/Container/index.cjs +4 -4
- package/dist/layouts/Container/index.cjs.map +1 -1
- package/dist/layouts/Container/index.d.cts +1 -1
- package/dist/layouts/Container/index.d.ts +1 -1
- package/dist/layouts/Container/index.js +4 -4
- package/dist/layouts/Container/index.js.map +1 -1
- package/dist/layouts/PageBackground/index.cjs +2 -2
- package/dist/layouts/PageBackground/index.cjs.map +1 -1
- package/dist/layouts/PageBackground/index.d.cts +1 -1
- package/dist/layouts/PageBackground/index.d.ts +1 -1
- package/dist/layouts/PageBackground/index.js +2 -2
- package/dist/layouts/PageBackground/index.js.map +1 -1
- package/dist/layouts/Stack/index.d.cts +1 -1
- package/dist/layouts/Stack/index.d.ts +1 -1
- package/dist/layouts/TwoColumn/index.d.cts +1 -1
- package/dist/layouts/TwoColumn/index.d.ts +1 -1
- package/dist/layouts/index.d.cts +4 -4
- package/dist/layouts/index.d.ts +4 -4
- package/dist/patterns/DataTable/index.cjs +12 -7
- package/dist/patterns/DataTable/index.cjs.map +1 -1
- package/dist/patterns/DataTable/index.d.cts +3 -3
- package/dist/patterns/DataTable/index.d.cts.map +1 -1
- package/dist/patterns/DataTable/index.d.ts +3 -3
- package/dist/patterns/DataTable/index.d.ts.map +1 -1
- package/dist/patterns/DataTable/index.js +12 -7
- package/dist/patterns/DataTable/index.js.map +1 -1
- package/dist/patterns/Footer/index.cjs +5 -5
- package/dist/patterns/Footer/index.cjs.map +1 -1
- package/dist/patterns/Footer/index.d.cts +9 -9
- package/dist/patterns/Footer/index.d.cts.map +1 -1
- package/dist/patterns/Footer/index.d.ts +9 -9
- package/dist/patterns/Footer/index.d.ts.map +1 -1
- package/dist/patterns/Footer/index.js +5 -5
- package/dist/patterns/Footer/index.js.map +1 -1
- package/dist/patterns/Header/index.d.cts +1 -1
- package/dist/patterns/Header/index.d.ts +1 -1
- package/dist/patterns/MediaObject/index.cjs +1 -1
- package/dist/patterns/MediaObject/index.cjs.map +1 -1
- package/dist/patterns/MediaObject/index.d.cts +12 -12
- package/dist/patterns/MediaObject/index.d.cts.map +1 -1
- package/dist/patterns/MediaObject/index.d.ts +13 -13
- package/dist/patterns/MediaObject/index.d.ts.map +1 -1
- package/dist/patterns/MediaObject/index.js +1 -1
- package/dist/patterns/MediaObject/index.js.map +1 -1
- package/dist/patterns/NavRail/index.cjs +195 -0
- package/dist/patterns/NavRail/index.cjs.map +1 -0
- package/dist/patterns/NavRail/index.d.cts +2 -0
- package/dist/patterns/NavRail/index.d.ts +2 -0
- package/dist/patterns/NavRail/index.js +185 -0
- package/dist/patterns/NavRail/index.js.map +1 -0
- package/dist/patterns/SectionCard/index.cjs +1 -1
- package/dist/patterns/SectionCard/index.cjs.map +1 -1
- package/dist/patterns/SectionCard/index.d.cts +2 -2
- package/dist/patterns/SectionCard/index.d.ts +2 -2
- package/dist/patterns/SectionCard/index.d.ts.map +1 -1
- package/dist/patterns/SectionCard/index.js +1 -1
- package/dist/patterns/SectionCard/index.js.map +1 -1
- package/dist/patterns/SectionHeading/index.d.cts +2 -2
- package/dist/patterns/SectionHeading/index.d.cts.map +1 -1
- package/dist/patterns/SectionHeading/index.d.ts +2 -2
- package/dist/patterns/SectionHeading/index.d.ts.map +1 -1
- package/dist/patterns/index.cjs +9 -0
- package/dist/patterns/index.d.cts +3 -2
- package/dist/patterns/index.d.ts +3 -2
- package/dist/patterns/index.js +2 -1
- package/dist/primitives/Accordion/index.cjs +6 -6
- package/dist/primitives/Accordion/index.cjs.map +1 -1
- package/dist/primitives/Accordion/index.js +6 -6
- package/dist/primitives/Accordion/index.js.map +1 -1
- package/dist/primitives/Alert/index.cjs +4 -4
- package/dist/primitives/Alert/index.cjs.map +1 -1
- package/dist/primitives/Alert/index.js +4 -4
- package/dist/primitives/Alert/index.js.map +1 -1
- package/dist/primitives/AlertDialog/index.cjs +4 -4
- package/dist/primitives/AlertDialog/index.cjs.map +1 -1
- package/dist/primitives/AlertDialog/index.js +4 -4
- package/dist/primitives/AlertDialog/index.js.map +1 -1
- package/dist/primitives/Avatar/index.cjs +5 -5
- package/dist/primitives/Avatar/index.cjs.map +1 -1
- package/dist/primitives/Avatar/index.js +5 -5
- package/dist/primitives/Avatar/index.js.map +1 -1
- package/dist/primitives/Badge/index.cjs +11 -10
- package/dist/primitives/Badge/index.cjs.map +1 -1
- package/dist/primitives/Badge/index.js +11 -10
- package/dist/primitives/Badge/index.js.map +1 -1
- package/dist/primitives/Breadcrumb/index.cjs +4 -4
- package/dist/primitives/Breadcrumb/index.cjs.map +1 -1
- package/dist/primitives/Breadcrumb/index.js +4 -4
- package/dist/primitives/Breadcrumb/index.js.map +1 -1
- package/dist/primitives/Button/index.cjs +20 -13
- package/dist/primitives/Button/index.cjs.map +1 -1
- package/dist/primitives/Button/index.js +20 -13
- package/dist/primitives/Button/index.js.map +1 -1
- package/dist/primitives/ButtonGroup/index.cjs +3 -3
- package/dist/primitives/ButtonGroup/index.cjs.map +1 -1
- package/dist/primitives/ButtonGroup/index.js +3 -3
- package/dist/primitives/ButtonGroup/index.js.map +1 -1
- package/dist/primitives/Calendar/index.cjs +22 -21
- package/dist/primitives/Calendar/index.cjs.map +1 -1
- package/dist/primitives/Calendar/index.js +22 -21
- package/dist/primitives/Calendar/index.js.map +1 -1
- package/dist/primitives/Card/index.cjs +18 -16
- package/dist/primitives/Card/index.cjs.map +1 -1
- package/dist/primitives/Card/index.js +18 -16
- package/dist/primitives/Card/index.js.map +1 -1
- package/dist/primitives/Carousel/index.cjs +2 -2
- package/dist/primitives/Carousel/index.cjs.map +1 -1
- package/dist/primitives/Carousel/index.js +2 -2
- package/dist/primitives/Carousel/index.js.map +1 -1
- package/dist/primitives/Chart/index.cjs +12 -12
- package/dist/primitives/Chart/index.cjs.map +1 -1
- package/dist/primitives/Chart/index.js +12 -12
- package/dist/primitives/Chart/index.js.map +1 -1
- package/dist/primitives/Checkbox/index.cjs +6 -6
- package/dist/primitives/Checkbox/index.cjs.map +1 -1
- package/dist/primitives/Checkbox/index.js +6 -6
- package/dist/primitives/Checkbox/index.js.map +1 -1
- package/dist/primitives/CheckboxTree/index.cjs +2 -2
- package/dist/primitives/CheckboxTree/index.cjs.map +1 -1
- package/dist/primitives/CheckboxTree/index.js +2 -2
- package/dist/primitives/CheckboxTree/index.js.map +1 -1
- package/dist/primitives/Command/index.cjs +9 -9
- package/dist/primitives/Command/index.cjs.map +1 -1
- package/dist/primitives/Command/index.js +9 -9
- package/dist/primitives/Command/index.js.map +1 -1
- package/dist/primitives/ContextMenu/index.cjs +10 -10
- package/dist/primitives/ContextMenu/index.cjs.map +1 -1
- package/dist/primitives/ContextMenu/index.js +10 -10
- package/dist/primitives/ContextMenu/index.js.map +1 -1
- package/dist/primitives/Credits/index.cjs +4 -4
- package/dist/primitives/Credits/index.cjs.map +1 -1
- package/dist/primitives/Credits/index.js +4 -4
- package/dist/primitives/Credits/index.js.map +1 -1
- package/dist/primitives/Dialog/index.cjs +5 -5
- package/dist/primitives/Dialog/index.cjs.map +1 -1
- package/dist/primitives/Dialog/index.js +5 -5
- package/dist/primitives/Dialog/index.js.map +1 -1
- package/dist/primitives/Drawer/index.cjs +5 -5
- package/dist/primitives/Drawer/index.cjs.map +1 -1
- package/dist/primitives/Drawer/index.js +5 -5
- package/dist/primitives/Drawer/index.js.map +1 -1
- package/dist/primitives/DropdownMenu/index.cjs +9 -9
- package/dist/primitives/DropdownMenu/index.cjs.map +1 -1
- package/dist/primitives/DropdownMenu/index.js +9 -9
- package/dist/primitives/DropdownMenu/index.js.map +1 -1
- package/dist/primitives/Empty/index.cjs +4 -4
- package/dist/primitives/Empty/index.cjs.map +1 -1
- package/dist/primitives/Empty/index.js +4 -4
- package/dist/primitives/Empty/index.js.map +1 -1
- package/dist/primitives/Field/index.cjs +5 -5
- package/dist/primitives/Field/index.cjs.map +1 -1
- package/dist/primitives/Field/index.js +5 -5
- package/dist/primitives/Field/index.js.map +1 -1
- package/dist/primitives/Form/index.cjs +1 -1
- package/dist/primitives/Form/index.cjs.map +1 -1
- package/dist/primitives/Form/index.js +1 -1
- package/dist/primitives/Form/index.js.map +1 -1
- package/dist/primitives/Heading/index.cjs +2 -2
- package/dist/primitives/Heading/index.cjs.map +1 -1
- package/dist/primitives/Heading/index.js +2 -2
- package/dist/primitives/Heading/index.js.map +1 -1
- package/dist/primitives/HoverCard/index.cjs +1 -1
- package/dist/primitives/HoverCard/index.cjs.map +1 -1
- package/dist/primitives/HoverCard/index.js +1 -1
- package/dist/primitives/HoverCard/index.js.map +1 -1
- package/dist/primitives/InfoBanner/index.cjs +12 -12
- package/dist/primitives/InfoBanner/index.cjs.map +1 -1
- package/dist/primitives/InfoBanner/index.js +12 -12
- package/dist/primitives/InfoBanner/index.js.map +1 -1
- package/dist/primitives/Input/index.cjs +13 -7
- package/dist/primitives/Input/index.cjs.map +1 -1
- package/dist/primitives/Input/index.js +13 -7
- package/dist/primitives/Input/index.js.map +1 -1
- package/dist/primitives/InputGroup/index.cjs +7 -7
- package/dist/primitives/InputGroup/index.cjs.map +1 -1
- package/dist/primitives/InputGroup/index.js +7 -7
- package/dist/primitives/InputGroup/index.js.map +1 -1
- package/dist/primitives/InputOtp/index.cjs +3 -3
- package/dist/primitives/InputOtp/index.cjs.map +1 -1
- package/dist/primitives/InputOtp/index.js +3 -3
- package/dist/primitives/InputOtp/index.js.map +1 -1
- package/dist/primitives/Item/index.cjs +6 -6
- package/dist/primitives/Item/index.cjs.map +1 -1
- package/dist/primitives/Item/index.js +6 -6
- package/dist/primitives/Item/index.js.map +1 -1
- package/dist/primitives/Kbd/index.cjs +1 -1
- package/dist/primitives/Kbd/index.cjs.map +1 -1
- package/dist/primitives/Kbd/index.js +1 -1
- package/dist/primitives/Kbd/index.js.map +1 -1
- package/dist/primitives/Link/index.cjs +4 -4
- package/dist/primitives/Link/index.cjs.map +1 -1
- package/dist/primitives/Link/index.js +4 -4
- package/dist/primitives/Link/index.js.map +1 -1
- package/dist/primitives/Menubar/index.cjs +12 -12
- package/dist/primitives/Menubar/index.cjs.map +1 -1
- package/dist/primitives/Menubar/index.js +12 -12
- package/dist/primitives/Menubar/index.js.map +1 -1
- package/dist/primitives/NativeSelect/index.cjs +5 -5
- package/dist/primitives/NativeSelect/index.cjs.map +1 -1
- package/dist/primitives/NativeSelect/index.js +5 -5
- package/dist/primitives/NativeSelect/index.js.map +1 -1
- package/dist/primitives/NavRail/index.cjs +9 -194
- package/dist/primitives/NavRail/index.d.cts +1 -0
- package/dist/primitives/NavRail/index.d.ts +1 -0
- package/dist/primitives/NavRail/index.js +1 -184
- package/dist/primitives/NavigationMenu/index.cjs +7 -7
- package/dist/primitives/NavigationMenu/index.cjs.map +1 -1
- package/dist/primitives/NavigationMenu/index.js +7 -7
- package/dist/primitives/NavigationMenu/index.js.map +1 -1
- package/dist/primitives/Pagination/index.cjs +7 -13
- package/dist/primitives/Pagination/index.cjs.map +1 -1
- package/dist/primitives/Pagination/index.d.cts +1 -1
- package/dist/primitives/Pagination/index.d.ts +1 -1
- package/dist/primitives/Pagination/index.js +8 -14
- package/dist/primitives/Pagination/index.js.map +1 -1
- package/dist/primitives/Popover/index.cjs +4 -4
- package/dist/primitives/Popover/index.cjs.map +1 -1
- package/dist/primitives/Popover/index.js +4 -4
- package/dist/primitives/Popover/index.js.map +1 -1
- package/dist/primitives/Progress/index.cjs +16 -16
- package/dist/primitives/Progress/index.cjs.map +1 -1
- package/dist/primitives/Progress/index.d.cts +1 -1
- package/dist/primitives/Progress/index.d.ts +1 -1
- package/dist/primitives/Progress/index.js +16 -16
- package/dist/primitives/Progress/index.js.map +1 -1
- package/dist/primitives/RadioGroup/index.cjs +7 -7
- package/dist/primitives/RadioGroup/index.cjs.map +1 -1
- package/dist/primitives/RadioGroup/index.d.cts +1 -1
- package/dist/primitives/RadioGroup/index.d.ts +1 -1
- package/dist/primitives/RadioGroup/index.js +7 -7
- package/dist/primitives/RadioGroup/index.js.map +1 -1
- package/dist/primitives/Resizable/index.cjs +2 -2
- package/dist/primitives/Resizable/index.cjs.map +1 -1
- package/dist/primitives/Resizable/index.d.cts +1 -1
- package/dist/primitives/Resizable/index.d.ts +1 -1
- package/dist/primitives/Resizable/index.js +2 -2
- package/dist/primitives/Resizable/index.js.map +1 -1
- package/dist/primitives/ScrollArea/index.cjs +2 -2
- package/dist/primitives/ScrollArea/index.cjs.map +1 -1
- package/dist/primitives/ScrollArea/index.d.cts +1 -1
- package/dist/primitives/ScrollArea/index.d.ts +1 -1
- package/dist/primitives/ScrollArea/index.js +2 -2
- package/dist/primitives/ScrollArea/index.js.map +1 -1
- package/dist/primitives/Select/index.cjs +8 -8
- package/dist/primitives/Select/index.cjs.map +1 -1
- package/dist/primitives/Select/index.d.cts +1 -1
- package/dist/primitives/Select/index.d.ts +1 -1
- package/dist/primitives/Select/index.js +8 -8
- package/dist/primitives/Select/index.js.map +1 -1
- package/dist/primitives/Separator/index.cjs +1 -1
- package/dist/primitives/Separator/index.cjs.map +1 -1
- package/dist/primitives/Separator/index.js +1 -1
- package/dist/primitives/Separator/index.js.map +1 -1
- package/dist/primitives/Sheet/index.cjs +8 -8
- package/dist/primitives/Sheet/index.cjs.map +1 -1
- package/dist/primitives/Sheet/index.d.cts +1 -1
- package/dist/primitives/Sheet/index.d.ts +1 -1
- package/dist/primitives/Sheet/index.js +8 -8
- package/dist/primitives/Sheet/index.js.map +1 -1
- package/dist/primitives/Sidebar/index.d.cts +1 -1
- package/dist/primitives/Sidebar/index.d.ts +1 -1
- package/dist/primitives/Skeleton/index.cjs +2 -2
- package/dist/primitives/Skeleton/index.cjs.map +1 -1
- package/dist/primitives/Skeleton/index.d.cts +1 -1
- package/dist/primitives/Skeleton/index.d.ts +1 -1
- package/dist/primitives/Skeleton/index.js +2 -2
- package/dist/primitives/Skeleton/index.js.map +1 -1
- package/dist/primitives/Slider/index.cjs +3 -3
- package/dist/primitives/Slider/index.cjs.map +1 -1
- package/dist/primitives/Slider/index.d.cts +1 -1
- package/dist/primitives/Slider/index.d.ts +1 -1
- package/dist/primitives/Slider/index.js +3 -3
- package/dist/primitives/Slider/index.js.map +1 -1
- package/dist/primitives/Sonner/index.cjs +13 -6
- package/dist/primitives/Sonner/index.cjs.map +1 -1
- package/dist/primitives/Sonner/index.d.cts +1 -1
- package/dist/primitives/Sonner/index.d.ts +1 -1
- package/dist/primitives/Sonner/index.js +13 -6
- package/dist/primitives/Sonner/index.js.map +1 -1
- package/dist/primitives/Spinner/index.d.cts +1 -1
- package/dist/primitives/Spinner/index.d.ts +1 -1
- package/dist/primitives/Switch/index.cjs +7 -7
- package/dist/primitives/Switch/index.cjs.map +1 -1
- package/dist/primitives/Switch/index.d.cts +1 -1
- package/dist/primitives/Switch/index.d.ts +1 -1
- package/dist/primitives/Switch/index.js +7 -7
- package/dist/primitives/Switch/index.js.map +1 -1
- package/dist/primitives/Table/index.cjs +7 -7
- package/dist/primitives/Table/index.cjs.map +1 -1
- package/dist/primitives/Table/index.d.cts +1 -1
- package/dist/primitives/Table/index.d.ts +1 -1
- package/dist/primitives/Table/index.js +7 -7
- package/dist/primitives/Table/index.js.map +1 -1
- package/dist/primitives/Tabs/index.cjs +21 -21
- package/dist/primitives/Tabs/index.cjs.map +1 -1
- package/dist/primitives/Tabs/index.d.cts +1 -1
- package/dist/primitives/Tabs/index.d.ts +1 -1
- package/dist/primitives/Tabs/index.js +21 -21
- package/dist/primitives/Tabs/index.js.map +1 -1
- package/dist/primitives/Text/index.cjs +5 -5
- package/dist/primitives/Text/index.cjs.map +1 -1
- package/dist/primitives/Text/index.d.cts +1 -1
- package/dist/primitives/Text/index.d.ts +1 -1
- package/dist/primitives/Text/index.js +5 -5
- package/dist/primitives/Text/index.js.map +1 -1
- package/dist/primitives/Textarea/index.cjs +20 -8
- package/dist/primitives/Textarea/index.cjs.map +1 -1
- package/dist/primitives/Textarea/index.d.cts +1 -1
- package/dist/primitives/Textarea/index.d.ts +1 -1
- package/dist/primitives/Textarea/index.js +20 -8
- package/dist/primitives/Textarea/index.js.map +1 -1
- package/dist/primitives/ThemeProvider/index.d.cts +1 -1
- package/dist/primitives/ThemeProvider/index.d.ts +1 -1
- package/dist/primitives/Toggle/index.cjs +11 -10
- package/dist/primitives/Toggle/index.cjs.map +1 -1
- package/dist/primitives/Toggle/index.d.cts +1 -1
- package/dist/primitives/Toggle/index.d.ts +1 -1
- package/dist/primitives/Toggle/index.js +11 -10
- package/dist/primitives/Toggle/index.js.map +1 -1
- package/dist/primitives/ToggleGroup/index.cjs +2 -2
- package/dist/primitives/ToggleGroup/index.cjs.map +1 -1
- package/dist/primitives/ToggleGroup/index.d.cts +1 -1
- package/dist/primitives/ToggleGroup/index.d.ts +1 -1
- package/dist/primitives/ToggleGroup/index.js +2 -2
- package/dist/primitives/ToggleGroup/index.js.map +1 -1
- package/dist/primitives/Tooltip/index.cjs +2 -2
- package/dist/primitives/Tooltip/index.cjs.map +1 -1
- package/dist/primitives/Tooltip/index.d.cts +1 -1
- package/dist/primitives/Tooltip/index.d.ts +1 -1
- package/dist/primitives/Tooltip/index.js +2 -2
- package/dist/primitives/Tooltip/index.js.map +1 -1
- package/dist/primitives/index.cjs +10 -10
- package/dist/primitives/index.d.cts +21 -21
- package/dist/primitives/index.d.ts +21 -21
- package/dist/primitives/index.js +2 -2
- package/dist/styles/base.css +23 -4
- package/dist/styles/brand-scopes.css +49 -0
- package/dist/styles/glass.css +13 -8
- package/dist/styles/index.css +8 -9
- package/dist/styles/theme.css +141 -90
- package/dist/styles/tokens/border-radius.css +8 -8
- package/dist/styles/tokens/mode-dark.css +71 -94
- package/dist/styles/tokens/mode-light.css +71 -94
- package/dist/styles/tokens/shadows.css +4 -7
- package/dist/styles/tokens/spacing.css +17 -37
- package/dist/styles/tokens/theme-bodhi.css +6 -28
- package/dist/styles/tokens/theme-slingshot.css +7 -28
- package/dist/styles/tokens/theme-sustain.css +6 -28
- package/dist/styles/typography.css +9 -9
- package/package.json +8 -2
- package/dist/index44.d.cts.map +0 -1
- package/dist/index44.d.ts.map +0 -1
- package/dist/primitives/NavRail/index.cjs.map +0 -1
- package/dist/primitives/NavRail/index.js.map +0 -1
- package/dist/styles/semantic.css +0 -178
- package/dist/styles/tokens/alpha.css +0 -39
- package/dist/styles/tokens/chart-colors-dark.css +0 -18
- package/dist/styles/tokens/chart-colors-light.css +0 -18
- package/dist/styles/tokens/colors.css +0 -251
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["React","cn","RechartsPrimitive"],"sources":["../../../src/primitives/Chart/Chart.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as RechartsPrimitive from \"recharts\";\nimport type { TooltipValueType } from \"recharts\";\n\nimport { cn } from \"@/utils\";\n\n// Format: { THEME_NAME: CSS_SELECTOR }\nconst THEMES = { light: \"\", dark: \".dark\" } as const;\n\nconst INITIAL_DIMENSION = { width: 320, height: 200 } as const;\ntype TooltipNameType = number | string;\n\n/** Maps each data key to its display label, optional icon, and color (flat or per-theme). */\nexport type ChartConfig = Record<\n string,\n {\n /** Human-readable label rendered in tooltips and the legend. */\n label?: React.ReactNode;\n /** Optional icon component shown alongside the label. */\n icon?: React.ComponentType;\n } & (\n | { color?: string; theme?: never }\n | { color?: never; theme: Record<keyof typeof THEMES, string> }\n )\n>;\n\ntype ChartContextProps = {\n config: ChartConfig;\n};\n\nconst ChartContext = React.createContext<ChartContextProps | null>(null);\n\nfunction useChart() {\n const context = React.useContext(ChartContext);\n\n if (!context) {\n throw new Error(\"useChart must be used within a <ChartContainer />\");\n }\n\n return context;\n}\n\n/** Root chart wrapper: provides the config context, theme CSS variables, and a responsive container. */\nfunction ChartContainer({\n id,\n className,\n children,\n config,\n initialDimension = INITIAL_DIMENSION,\n ...props\n}: React.ComponentProps<\"div\"> & {\n /** Maps data keys to labels, icons, and colors used across tooltip and legend. */\n config: ChartConfig;\n /** Recharts chart element rendered inside the responsive container. */\n children: React.ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>[\"children\"];\n /** Initial width/height used before the responsive container measures its parent. */\n initialDimension?: {\n width: number;\n height: number;\n };\n}) {\n const uniqueId = React.useId();\n const chartId = `chart-${id ?? uniqueId.replace(/:/g, \"\")}`;\n\n return (\n <ChartContext.Provider value={{ config }}>\n <div\n data-slot=\"chart\"\n data-chart={chartId}\n className={cn(\n \"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden\",\n className,\n )}\n {...props}\n >\n <ChartStyle id={chartId} config={config} />\n <RechartsPrimitive.ResponsiveContainer initialDimension={initialDimension}>\n {children}\n </RechartsPrimitive.ResponsiveContainer>\n </div>\n </ChartContext.Provider>\n );\n}\n\n/** Injects per-chart CSS custom properties (`--color-*`) derived from the config, one block per theme. */\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n const colorConfig = Object.entries(config).filter(([, config]) => config.theme ?? config.color);\n\n if (!colorConfig.length) {\n return null;\n }\n\n return (\n <style\n dangerouslySetInnerHTML={{\n __html: Object.entries(THEMES)\n .map(\n ([theme, prefix]) => `\n${prefix} [data-chart=${id}] {\n${colorConfig\n .map(([key, itemConfig]) => {\n const color = itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ?? itemConfig.color;\n return color ? ` --color-${key}: ${color};` : null;\n })\n .join(\"\\n\")}\n}\n`,\n )\n .join(\"\\n\"),\n }}\n />\n );\n};\n\n/** Recharts Tooltip element; pair with `ChartTooltipContent` for the styled body. */\nconst ChartTooltip = RechartsPrimitive.Tooltip;\n\n/** Styled tooltip body that resolves labels, colors, and indicators from the chart config. */\nfunction ChartTooltipContent({\n active,\n payload,\n className,\n indicator = \"dot\",\n hideLabel = false,\n hideIndicator = false,\n label,\n labelFormatter,\n labelClassName,\n formatter,\n color,\n nameKey,\n labelKey,\n}: React.ComponentProps<typeof RechartsPrimitive.Tooltip> &\n React.ComponentProps<\"div\"> & {\n /** Hides the tooltip's leading label row. */\n hideLabel?: boolean;\n /** Hides the per-item color indicator swatch. */\n hideIndicator?: boolean;\n /** Visual style of the per-item color indicator. */\n indicator?: \"line\" | \"dot\" | \"dashed\";\n /** Config key used to resolve each item's label/color (defaults to its name). */\n nameKey?: string;\n /** Config key used to resolve the tooltip's label (defaults to the data key). */\n labelKey?: string;\n } & Omit<\n RechartsPrimitive.DefaultTooltipContentProps<TooltipValueType, TooltipNameType>,\n \"accessibilityLayer\"\n >) {\n const { config } = useChart();\n\n const tooltipLabel = React.useMemo(() => {\n if (hideLabel || !payload?.length) {\n return null;\n }\n\n const [item] = payload;\n const key = `${labelKey ?? item?.dataKey ?? item?.name ?? \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const value =\n !labelKey && typeof label === \"string\" ? (config[label]?.label ?? label) : itemConfig?.label;\n\n if (labelFormatter) {\n return (\n <div className={cn(\"font-medium\", labelClassName)}>{labelFormatter(value, payload)}</div>\n );\n }\n\n if (!value) {\n return null;\n }\n\n return <div className={cn(\"font-medium\", labelClassName)}>{value}</div>;\n }, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);\n\n if (!active || !payload?.length) {\n return null;\n }\n\n const nestLabel = payload.length === 1 && indicator !== \"dot\";\n\n return (\n <div\n className={cn(\n \"grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border bg-popover px-2.5 py-1.5 text-xs shadow-xl\",\n className,\n )}\n >\n {!nestLabel ? tooltipLabel : null}\n <div className=\"grid gap-1.5\">\n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.name ?? item.dataKey ?? \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const indicatorColor = color ?? item.payload?.fill ?? item.color;\n\n return (\n <div\n key={index}\n className={cn(\n \"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground\",\n indicator === \"dot\" && \"items-center\",\n )}\n >\n {formatter && item?.value !== undefined && item.name ? (\n formatter(item.value, item.name, item, index, item.payload)\n ) : (\n <>\n {itemConfig?.icon ? (\n <itemConfig.icon />\n ) : (\n !hideIndicator && (\n <div\n className={cn(\n \"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)\",\n {\n \"h-2.5 w-2.5\": indicator === \"dot\",\n \"w-1\": indicator === \"line\",\n \"w-0 border-[1.5px] border-dashed bg-transparent\":\n indicator === \"dashed\",\n \"my-0.5\": nestLabel && indicator === \"dashed\",\n },\n )}\n style={\n {\n \"--color-bg\": indicatorColor,\n \"--color-border\": indicatorColor,\n } as React.CSSProperties\n }\n />\n )\n )}\n <div\n className={cn(\n \"flex flex-1 justify-between leading-none\",\n nestLabel ? \"items-end\" : \"items-center\",\n )}\n >\n <div className=\"grid gap-1.5\">\n {nestLabel ? tooltipLabel : null}\n <span className=\"text-muted-foreground\">\n {itemConfig?.label ?? item.name}\n </span>\n </div>\n {item.value != null && (\n <span className=\"font-mono font-medium text-foreground tabular-nums\">\n {typeof item.value === \"number\"\n ? item.value.toLocaleString()\n : String(item.value)}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\n/** Recharts Legend element; pair with `ChartLegendContent` for the styled body. */\nconst ChartLegend = RechartsPrimitive.Legend;\n\n/** Styled legend body that resolves labels, icons, and colors from the chart config. */\nfunction ChartLegendContent({\n className,\n hideIcon = false,\n payload,\n verticalAlign = \"bottom\",\n nameKey,\n}: React.ComponentProps<\"div\"> & {\n /** Hides each item's icon, showing only the color swatch. */\n hideIcon?: boolean;\n /** Config key used to resolve each item's label/color (defaults to the data key). */\n nameKey?: string;\n} & RechartsPrimitive.DefaultLegendContentProps) {\n const { config } = useChart();\n\n if (!payload?.length) {\n return null;\n }\n\n return (\n <div\n className={cn(\n \"flex items-center justify-center gap-4\",\n verticalAlign === \"top\" ? \"pb-3\" : \"pt-3\",\n className,\n )}\n >\n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.dataKey ?? \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n\n return (\n <div\n key={index}\n className={cn(\n \"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground\",\n )}\n >\n {itemConfig?.icon && !hideIcon ? (\n <itemConfig.icon />\n ) : (\n <div\n className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n style={{\n backgroundColor: item.color,\n }}\n />\n )}\n {itemConfig?.label}\n </div>\n );\n })}\n </div>\n );\n}\n\n// Helper to extract item config from a payload.\nfunction getPayloadConfigFromPayload(config: ChartConfig, payload: unknown, key: string) {\n if (typeof payload !== \"object\" || payload === null) {\n return undefined;\n }\n\n const payloadPayload =\n \"payload\" in payload && typeof payload.payload === \"object\" && payload.payload !== null\n ? payload.payload\n : undefined;\n\n let configLabelKey: string = key;\n\n if (key in payload && typeof payload[key as keyof typeof payload] === \"string\") {\n configLabelKey = payload[key as keyof typeof payload] as string;\n } else if (\n payloadPayload &&\n key in payloadPayload &&\n typeof payloadPayload[key as keyof typeof payloadPayload] === \"string\"\n ) {\n configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string;\n }\n\n return configLabelKey in config ? config[configLabelKey] : config[key];\n}\n\nexport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n ChartLegend,\n ChartLegendContent,\n ChartStyle,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["React","cn","RechartsPrimitive"],"sources":["../../../src/primitives/Chart/Chart.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as RechartsPrimitive from \"recharts\";\nimport type { TooltipValueType } from \"recharts\";\n\nimport { cn } from \"@/utils\";\n\n// Format: { THEME_NAME: CSS_SELECTOR }\nconst THEMES = { light: \"\", dark: \".dark\" } as const;\n\nconst INITIAL_DIMENSION = { width: 320, height: 200 } as const;\ntype TooltipNameType = number | string;\n\n/** Maps each data key to its display label, optional icon, and color (flat or per-theme). */\nexport type ChartConfig = Record<\n string,\n {\n /** Human-readable label rendered in tooltips and the legend. */\n label?: React.ReactNode;\n /** Optional icon component shown alongside the label. */\n icon?: React.ComponentType;\n } & (\n | { color?: string; theme?: never }\n | { color?: never; theme: Record<keyof typeof THEMES, string> }\n )\n>;\n\ntype ChartContextProps = {\n config: ChartConfig;\n};\n\nconst ChartContext = React.createContext<ChartContextProps | null>(null);\n\nfunction useChart() {\n const context = React.useContext(ChartContext);\n\n if (!context) {\n throw new Error(\"useChart must be used within a <ChartContainer />\");\n }\n\n return context;\n}\n\n/** Root chart wrapper: provides the config context, theme CSS variables, and a responsive container. */\nfunction ChartContainer({\n id,\n className,\n children,\n config,\n initialDimension = INITIAL_DIMENSION,\n ...props\n}: React.ComponentProps<\"div\"> & {\n /** Maps data keys to labels, icons, and colors used across tooltip and legend. */\n config: ChartConfig;\n /** Recharts chart element rendered inside the responsive container. */\n children: React.ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>[\"children\"];\n /** Initial width/height used before the responsive container measures its parent. */\n initialDimension?: {\n width: number;\n height: number;\n };\n}) {\n const uniqueId = React.useId();\n const chartId = `chart-${id ?? uniqueId.replace(/:/g, \"\")}`;\n\n return (\n <ChartContext.Provider value={{ config }}>\n <div\n data-slot=\"chart\"\n data-chart={chartId}\n className={cn(\n \"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-txt [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-primary-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-primary-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-primary-border [&_.recharts-radial-bar-background-sector]:fill-muted-bg [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted-bg [&_.recharts-reference-line_[stroke='#ccc']]:stroke-primary-border [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden\",\n className,\n )}\n {...props}\n >\n <ChartStyle id={chartId} config={config} />\n <RechartsPrimitive.ResponsiveContainer initialDimension={initialDimension}>\n {children}\n </RechartsPrimitive.ResponsiveContainer>\n </div>\n </ChartContext.Provider>\n );\n}\n\n/** Injects per-chart CSS custom properties (`--color-*`) derived from the config, one block per theme. */\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n const colorConfig = Object.entries(config).filter(([, config]) => config.theme ?? config.color);\n\n if (!colorConfig.length) {\n return null;\n }\n\n return (\n <style\n dangerouslySetInnerHTML={{\n __html: Object.entries(THEMES)\n .map(\n ([theme, prefix]) => `\n${prefix} [data-chart=${id}] {\n${colorConfig\n .map(([key, itemConfig]) => {\n const color = itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ?? itemConfig.color;\n return color ? ` --color-${key}: ${color};` : null;\n })\n .join(\"\\n\")}\n}\n`,\n )\n .join(\"\\n\"),\n }}\n />\n );\n};\n\n/** Recharts Tooltip element; pair with `ChartTooltipContent` for the styled body. */\nconst ChartTooltip = RechartsPrimitive.Tooltip;\n\n/** Styled tooltip body that resolves labels, colors, and indicators from the chart config. */\nfunction ChartTooltipContent({\n active,\n payload,\n className,\n indicator = \"dot\",\n hideLabel = false,\n hideIndicator = false,\n label,\n labelFormatter,\n labelClassName,\n formatter,\n color,\n nameKey,\n labelKey,\n}: React.ComponentProps<typeof RechartsPrimitive.Tooltip> &\n React.ComponentProps<\"div\"> & {\n /** Hides the tooltip's leading label row. */\n hideLabel?: boolean;\n /** Hides the per-item color indicator swatch. */\n hideIndicator?: boolean;\n /** Visual style of the per-item color indicator. */\n indicator?: \"line\" | \"dot\" | \"dashed\";\n /** Config key used to resolve each item's label/color (defaults to its name). */\n nameKey?: string;\n /** Config key used to resolve the tooltip's label (defaults to the data key). */\n labelKey?: string;\n } & Omit<\n RechartsPrimitive.DefaultTooltipContentProps<TooltipValueType, TooltipNameType>,\n \"accessibilityLayer\"\n >) {\n const { config } = useChart();\n\n const tooltipLabel = React.useMemo(() => {\n if (hideLabel || !payload?.length) {\n return null;\n }\n\n const [item] = payload;\n const key = `${labelKey ?? item?.dataKey ?? item?.name ?? \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const value =\n !labelKey && typeof label === \"string\" ? (config[label]?.label ?? label) : itemConfig?.label;\n\n if (labelFormatter) {\n return (\n <div className={cn(\"font-semibold\", labelClassName)}>{labelFormatter(value, payload)}</div>\n );\n }\n\n if (!value) {\n return null;\n }\n\n return <div className={cn(\"font-semibold\", labelClassName)}>{value}</div>;\n }, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);\n\n if (!active || !payload?.length) {\n return null;\n }\n\n const nestLabel = payload.length === 1 && indicator !== \"dot\";\n\n return (\n <div\n className={cn(\n \"grid min-w-32 items-start rounded-8 border border-primary-border bg-glass-none-bg px-3 py-2 text-xs leading-4\",\n className,\n )}\n >\n {!nestLabel ? tooltipLabel : null}\n <div className=\"grid gap-1.5\">\n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.name ?? item.dataKey ?? \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const indicatorColor = color ?? item.payload?.fill ?? item.color;\n\n return (\n <div\n key={index}\n className={cn(\n \"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-txt\",\n indicator === \"dot\" && \"items-center\",\n )}\n >\n {formatter && item?.value !== undefined && item.name ? (\n formatter(item.value, item.name, item, index, item.payload)\n ) : (\n <>\n {itemConfig?.icon ? (\n <itemConfig.icon />\n ) : (\n !hideIndicator && (\n <div\n className={cn(\n \"shrink-0 rounded-2 border-(--color-border) bg-(--color-bg)\",\n {\n \"h-2.5 w-2.5\": indicator === \"dot\",\n \"w-0.75\": indicator === \"line\",\n \"w-0 border-2 border-dashed bg-transparent\": indicator === \"dashed\",\n \"my-0.5\": nestLabel && indicator === \"dashed\",\n },\n )}\n style={\n {\n \"--color-bg\": indicatorColor,\n \"--color-border\": indicatorColor,\n } as React.CSSProperties\n }\n />\n )\n )}\n <div\n className={cn(\n \"flex flex-1 justify-between leading-none\",\n nestLabel ? \"items-end\" : \"items-center\",\n )}\n >\n <div className=\"grid gap-1.5\">\n {nestLabel ? tooltipLabel : null}\n <span className=\"text-primary-txt\">{itemConfig?.label ?? item.name}</span>\n </div>\n {item.value != null && (\n <span className=\"font-semibold text-primary-txt tabular-nums\">\n {typeof item.value === \"number\"\n ? item.value.toLocaleString()\n : String(item.value)}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\n/** Recharts Legend element; pair with `ChartLegendContent` for the styled body. */\nconst ChartLegend = RechartsPrimitive.Legend;\n\n/** Styled legend body that resolves labels, icons, and colors from the chart config. */\nfunction ChartLegendContent({\n className,\n hideIcon = false,\n payload,\n verticalAlign = \"bottom\",\n nameKey,\n}: React.ComponentProps<\"div\"> & {\n /** Hides each item's icon, showing only the color swatch. */\n hideIcon?: boolean;\n /** Config key used to resolve each item's label/color (defaults to the data key). */\n nameKey?: string;\n} & RechartsPrimitive.DefaultLegendContentProps) {\n const { config } = useChart();\n\n if (!payload?.length) {\n return null;\n }\n\n return (\n <div\n className={cn(\n \"flex items-center justify-center gap-4\",\n verticalAlign === \"top\" ? \"pb-3\" : \"pt-3\",\n className,\n )}\n >\n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.dataKey ?? \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n\n return (\n <div\n key={index}\n className={cn(\n \"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-txt\",\n )}\n >\n {itemConfig?.icon && !hideIcon ? (\n <itemConfig.icon />\n ) : (\n <div\n className=\"h-2 w-2 shrink-0 rounded-2\"\n style={{\n backgroundColor: item.color,\n }}\n />\n )}\n {itemConfig?.label}\n </div>\n );\n })}\n </div>\n );\n}\n\n// Helper to extract item config from a payload.\nfunction getPayloadConfigFromPayload(config: ChartConfig, payload: unknown, key: string) {\n if (typeof payload !== \"object\" || payload === null) {\n return undefined;\n }\n\n const payloadPayload =\n \"payload\" in payload && typeof payload.payload === \"object\" && payload.payload !== null\n ? payload.payload\n : undefined;\n\n let configLabelKey: string = key;\n\n if (key in payload && typeof payload[key as keyof typeof payload] === \"string\") {\n configLabelKey = payload[key as keyof typeof payload] as string;\n } else if (\n payloadPayload &&\n key in payloadPayload &&\n typeof payloadPayload[key as keyof typeof payloadPayload] === \"string\"\n ) {\n configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string;\n }\n\n return configLabelKey in config ? config[configLabelKey] : config[key];\n}\n\nexport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n ChartLegend,\n ChartLegendContent,\n ChartStyle,\n};\n"],"mappings":"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"}
|
|
@@ -26,7 +26,7 @@ function ChartContainer({ id, className, children, config, initialDimension = IN
|
|
|
26
26
|
children: /* @__PURE__ */ jsxs("div", {
|
|
27
27
|
"data-slot": "chart",
|
|
28
28
|
"data-chart": chartId,
|
|
29
|
-
className: cn("flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-
|
|
29
|
+
className: cn("flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-txt [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-primary-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-primary-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-primary-border [&_.recharts-radial-bar-background-sector]:fill-muted-bg [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted-bg [&_.recharts-reference-line_[stroke='#ccc']]:stroke-primary-border [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden", className),
|
|
30
30
|
...props,
|
|
31
31
|
children: [/* @__PURE__ */ jsx(ChartStyle, {
|
|
32
32
|
id: chartId,
|
|
@@ -62,12 +62,12 @@ function ChartTooltipContent({ active, payload, className, indicator = "dot", hi
|
|
|
62
62
|
const itemConfig = getPayloadConfigFromPayload(config, item, `${labelKey ?? item?.dataKey ?? item?.name ?? "value"}`);
|
|
63
63
|
const value = !labelKey && typeof label === "string" ? config[label]?.label ?? label : itemConfig?.label;
|
|
64
64
|
if (labelFormatter) return /* @__PURE__ */ jsx("div", {
|
|
65
|
-
className: cn("font-
|
|
65
|
+
className: cn("font-semibold", labelClassName),
|
|
66
66
|
children: labelFormatter(value, payload)
|
|
67
67
|
});
|
|
68
68
|
if (!value) return null;
|
|
69
69
|
return /* @__PURE__ */ jsx("div", {
|
|
70
|
-
className: cn("font-
|
|
70
|
+
className: cn("font-semibold", labelClassName),
|
|
71
71
|
children: value
|
|
72
72
|
});
|
|
73
73
|
}, [
|
|
@@ -82,19 +82,19 @@ function ChartTooltipContent({ active, payload, className, indicator = "dot", hi
|
|
|
82
82
|
if (!active || !payload?.length) return null;
|
|
83
83
|
const nestLabel = payload.length === 1 && indicator !== "dot";
|
|
84
84
|
return /* @__PURE__ */ jsxs("div", {
|
|
85
|
-
className: cn("grid min-w-
|
|
85
|
+
className: cn("grid min-w-32 items-start rounded-8 border border-primary-border bg-glass-none-bg px-3 py-2 text-xs leading-4", className),
|
|
86
86
|
children: [!nestLabel ? tooltipLabel : null, /* @__PURE__ */ jsx("div", {
|
|
87
87
|
className: "grid gap-1.5",
|
|
88
88
|
children: payload.filter((item) => item.type !== "none").map((item, index) => {
|
|
89
89
|
const itemConfig = getPayloadConfigFromPayload(config, item, `${nameKey ?? item.name ?? item.dataKey ?? "value"}`);
|
|
90
90
|
const indicatorColor = color ?? item.payload?.fill ?? item.color;
|
|
91
91
|
return /* @__PURE__ */ jsx("div", {
|
|
92
|
-
className: cn("flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-
|
|
92
|
+
className: cn("flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-txt", indicator === "dot" && "items-center"),
|
|
93
93
|
children: formatter && item?.value !== void 0 && item.name ? formatter(item.value, item.name, item, index, item.payload) : /* @__PURE__ */ jsxs(Fragment, { children: [itemConfig?.icon ? /* @__PURE__ */ jsx(itemConfig.icon, {}) : !hideIndicator && /* @__PURE__ */ jsx("div", {
|
|
94
|
-
className: cn("shrink-0 rounded-
|
|
94
|
+
className: cn("shrink-0 rounded-2 border-(--color-border) bg-(--color-bg)", {
|
|
95
95
|
"h-2.5 w-2.5": indicator === "dot",
|
|
96
|
-
"w-
|
|
97
|
-
"w-0 border-
|
|
96
|
+
"w-0.75": indicator === "line",
|
|
97
|
+
"w-0 border-2 border-dashed bg-transparent": indicator === "dashed",
|
|
98
98
|
"my-0.5": nestLabel && indicator === "dashed"
|
|
99
99
|
}),
|
|
100
100
|
style: {
|
|
@@ -106,11 +106,11 @@ function ChartTooltipContent({ active, payload, className, indicator = "dot", hi
|
|
|
106
106
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
107
107
|
className: "grid gap-1.5",
|
|
108
108
|
children: [nestLabel ? tooltipLabel : null, /* @__PURE__ */ jsx("span", {
|
|
109
|
-
className: "text-
|
|
109
|
+
className: "text-primary-txt",
|
|
110
110
|
children: itemConfig?.label ?? item.name
|
|
111
111
|
})]
|
|
112
112
|
}), item.value != null && /* @__PURE__ */ jsx("span", {
|
|
113
|
-
className: "font-
|
|
113
|
+
className: "font-semibold text-primary-txt tabular-nums",
|
|
114
114
|
children: typeof item.value === "number" ? item.value.toLocaleString() : String(item.value)
|
|
115
115
|
})]
|
|
116
116
|
})] })
|
|
@@ -130,9 +130,9 @@ function ChartLegendContent({ className, hideIcon = false, payload, verticalAlig
|
|
|
130
130
|
children: payload.filter((item) => item.type !== "none").map((item, index) => {
|
|
131
131
|
const itemConfig = getPayloadConfigFromPayload(config, item, `${nameKey ?? item.dataKey ?? "value"}`);
|
|
132
132
|
return /* @__PURE__ */ jsxs("div", {
|
|
133
|
-
className: cn("flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-
|
|
133
|
+
className: cn("flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-txt"),
|
|
134
134
|
children: [itemConfig?.icon && !hideIcon ? /* @__PURE__ */ jsx(itemConfig.icon, {}) : /* @__PURE__ */ jsx("div", {
|
|
135
|
-
className: "h-2 w-2 shrink-0 rounded-
|
|
135
|
+
className: "h-2 w-2 shrink-0 rounded-2",
|
|
136
136
|
style: { backgroundColor: item.color }
|
|
137
137
|
}), itemConfig?.label]
|
|
138
138
|
}, index);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/primitives/Chart/Chart.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as RechartsPrimitive from \"recharts\";\nimport type { TooltipValueType } from \"recharts\";\n\nimport { cn } from \"@/utils\";\n\n// Format: { THEME_NAME: CSS_SELECTOR }\nconst THEMES = { light: \"\", dark: \".dark\" } as const;\n\nconst INITIAL_DIMENSION = { width: 320, height: 200 } as const;\ntype TooltipNameType = number | string;\n\n/** Maps each data key to its display label, optional icon, and color (flat or per-theme). */\nexport type ChartConfig = Record<\n string,\n {\n /** Human-readable label rendered in tooltips and the legend. */\n label?: React.ReactNode;\n /** Optional icon component shown alongside the label. */\n icon?: React.ComponentType;\n } & (\n | { color?: string; theme?: never }\n | { color?: never; theme: Record<keyof typeof THEMES, string> }\n )\n>;\n\ntype ChartContextProps = {\n config: ChartConfig;\n};\n\nconst ChartContext = React.createContext<ChartContextProps | null>(null);\n\nfunction useChart() {\n const context = React.useContext(ChartContext);\n\n if (!context) {\n throw new Error(\"useChart must be used within a <ChartContainer />\");\n }\n\n return context;\n}\n\n/** Root chart wrapper: provides the config context, theme CSS variables, and a responsive container. */\nfunction ChartContainer({\n id,\n className,\n children,\n config,\n initialDimension = INITIAL_DIMENSION,\n ...props\n}: React.ComponentProps<\"div\"> & {\n /** Maps data keys to labels, icons, and colors used across tooltip and legend. */\n config: ChartConfig;\n /** Recharts chart element rendered inside the responsive container. */\n children: React.ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>[\"children\"];\n /** Initial width/height used before the responsive container measures its parent. */\n initialDimension?: {\n width: number;\n height: number;\n };\n}) {\n const uniqueId = React.useId();\n const chartId = `chart-${id ?? uniqueId.replace(/:/g, \"\")}`;\n\n return (\n <ChartContext.Provider value={{ config }}>\n <div\n data-slot=\"chart\"\n data-chart={chartId}\n className={cn(\n \"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden\",\n className,\n )}\n {...props}\n >\n <ChartStyle id={chartId} config={config} />\n <RechartsPrimitive.ResponsiveContainer initialDimension={initialDimension}>\n {children}\n </RechartsPrimitive.ResponsiveContainer>\n </div>\n </ChartContext.Provider>\n );\n}\n\n/** Injects per-chart CSS custom properties (`--color-*`) derived from the config, one block per theme. */\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n const colorConfig = Object.entries(config).filter(([, config]) => config.theme ?? config.color);\n\n if (!colorConfig.length) {\n return null;\n }\n\n return (\n <style\n dangerouslySetInnerHTML={{\n __html: Object.entries(THEMES)\n .map(\n ([theme, prefix]) => `\n${prefix} [data-chart=${id}] {\n${colorConfig\n .map(([key, itemConfig]) => {\n const color = itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ?? itemConfig.color;\n return color ? ` --color-${key}: ${color};` : null;\n })\n .join(\"\\n\")}\n}\n`,\n )\n .join(\"\\n\"),\n }}\n />\n );\n};\n\n/** Recharts Tooltip element; pair with `ChartTooltipContent` for the styled body. */\nconst ChartTooltip = RechartsPrimitive.Tooltip;\n\n/** Styled tooltip body that resolves labels, colors, and indicators from the chart config. */\nfunction ChartTooltipContent({\n active,\n payload,\n className,\n indicator = \"dot\",\n hideLabel = false,\n hideIndicator = false,\n label,\n labelFormatter,\n labelClassName,\n formatter,\n color,\n nameKey,\n labelKey,\n}: React.ComponentProps<typeof RechartsPrimitive.Tooltip> &\n React.ComponentProps<\"div\"> & {\n /** Hides the tooltip's leading label row. */\n hideLabel?: boolean;\n /** Hides the per-item color indicator swatch. */\n hideIndicator?: boolean;\n /** Visual style of the per-item color indicator. */\n indicator?: \"line\" | \"dot\" | \"dashed\";\n /** Config key used to resolve each item's label/color (defaults to its name). */\n nameKey?: string;\n /** Config key used to resolve the tooltip's label (defaults to the data key). */\n labelKey?: string;\n } & Omit<\n RechartsPrimitive.DefaultTooltipContentProps<TooltipValueType, TooltipNameType>,\n \"accessibilityLayer\"\n >) {\n const { config } = useChart();\n\n const tooltipLabel = React.useMemo(() => {\n if (hideLabel || !payload?.length) {\n return null;\n }\n\n const [item] = payload;\n const key = `${labelKey ?? item?.dataKey ?? item?.name ?? \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const value =\n !labelKey && typeof label === \"string\" ? (config[label]?.label ?? label) : itemConfig?.label;\n\n if (labelFormatter) {\n return (\n <div className={cn(\"font-medium\", labelClassName)}>{labelFormatter(value, payload)}</div>\n );\n }\n\n if (!value) {\n return null;\n }\n\n return <div className={cn(\"font-medium\", labelClassName)}>{value}</div>;\n }, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);\n\n if (!active || !payload?.length) {\n return null;\n }\n\n const nestLabel = payload.length === 1 && indicator !== \"dot\";\n\n return (\n <div\n className={cn(\n \"grid min-w-[8rem] items-start gap-1.5 rounded-lg border border-border bg-popover px-2.5 py-1.5 text-xs shadow-xl\",\n className,\n )}\n >\n {!nestLabel ? tooltipLabel : null}\n <div className=\"grid gap-1.5\">\n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.name ?? item.dataKey ?? \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const indicatorColor = color ?? item.payload?.fill ?? item.color;\n\n return (\n <div\n key={index}\n className={cn(\n \"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground\",\n indicator === \"dot\" && \"items-center\",\n )}\n >\n {formatter && item?.value !== undefined && item.name ? (\n formatter(item.value, item.name, item, index, item.payload)\n ) : (\n <>\n {itemConfig?.icon ? (\n <itemConfig.icon />\n ) : (\n !hideIndicator && (\n <div\n className={cn(\n \"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)\",\n {\n \"h-2.5 w-2.5\": indicator === \"dot\",\n \"w-1\": indicator === \"line\",\n \"w-0 border-[1.5px] border-dashed bg-transparent\":\n indicator === \"dashed\",\n \"my-0.5\": nestLabel && indicator === \"dashed\",\n },\n )}\n style={\n {\n \"--color-bg\": indicatorColor,\n \"--color-border\": indicatorColor,\n } as React.CSSProperties\n }\n />\n )\n )}\n <div\n className={cn(\n \"flex flex-1 justify-between leading-none\",\n nestLabel ? \"items-end\" : \"items-center\",\n )}\n >\n <div className=\"grid gap-1.5\">\n {nestLabel ? tooltipLabel : null}\n <span className=\"text-muted-foreground\">\n {itemConfig?.label ?? item.name}\n </span>\n </div>\n {item.value != null && (\n <span className=\"font-mono font-medium text-foreground tabular-nums\">\n {typeof item.value === \"number\"\n ? item.value.toLocaleString()\n : String(item.value)}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\n/** Recharts Legend element; pair with `ChartLegendContent` for the styled body. */\nconst ChartLegend = RechartsPrimitive.Legend;\n\n/** Styled legend body that resolves labels, icons, and colors from the chart config. */\nfunction ChartLegendContent({\n className,\n hideIcon = false,\n payload,\n verticalAlign = \"bottom\",\n nameKey,\n}: React.ComponentProps<\"div\"> & {\n /** Hides each item's icon, showing only the color swatch. */\n hideIcon?: boolean;\n /** Config key used to resolve each item's label/color (defaults to the data key). */\n nameKey?: string;\n} & RechartsPrimitive.DefaultLegendContentProps) {\n const { config } = useChart();\n\n if (!payload?.length) {\n return null;\n }\n\n return (\n <div\n className={cn(\n \"flex items-center justify-center gap-4\",\n verticalAlign === \"top\" ? \"pb-3\" : \"pt-3\",\n className,\n )}\n >\n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.dataKey ?? \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n\n return (\n <div\n key={index}\n className={cn(\n \"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground\",\n )}\n >\n {itemConfig?.icon && !hideIcon ? (\n <itemConfig.icon />\n ) : (\n <div\n className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n style={{\n backgroundColor: item.color,\n }}\n />\n )}\n {itemConfig?.label}\n </div>\n );\n })}\n </div>\n );\n}\n\n// Helper to extract item config from a payload.\nfunction getPayloadConfigFromPayload(config: ChartConfig, payload: unknown, key: string) {\n if (typeof payload !== \"object\" || payload === null) {\n return undefined;\n }\n\n const payloadPayload =\n \"payload\" in payload && typeof payload.payload === \"object\" && payload.payload !== null\n ? payload.payload\n : undefined;\n\n let configLabelKey: string = key;\n\n if (key in payload && typeof payload[key as keyof typeof payload] === \"string\") {\n configLabelKey = payload[key as keyof typeof payload] as string;\n } else if (\n payloadPayload &&\n key in payloadPayload &&\n typeof payloadPayload[key as keyof typeof payloadPayload] === \"string\"\n ) {\n configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string;\n }\n\n return configLabelKey in config ? config[configLabelKey] : config[key];\n}\n\nexport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n ChartLegend,\n ChartLegendContent,\n ChartStyle,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/primitives/Chart/Chart.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport * as RechartsPrimitive from \"recharts\";\nimport type { TooltipValueType } from \"recharts\";\n\nimport { cn } from \"@/utils\";\n\n// Format: { THEME_NAME: CSS_SELECTOR }\nconst THEMES = { light: \"\", dark: \".dark\" } as const;\n\nconst INITIAL_DIMENSION = { width: 320, height: 200 } as const;\ntype TooltipNameType = number | string;\n\n/** Maps each data key to its display label, optional icon, and color (flat or per-theme). */\nexport type ChartConfig = Record<\n string,\n {\n /** Human-readable label rendered in tooltips and the legend. */\n label?: React.ReactNode;\n /** Optional icon component shown alongside the label. */\n icon?: React.ComponentType;\n } & (\n | { color?: string; theme?: never }\n | { color?: never; theme: Record<keyof typeof THEMES, string> }\n )\n>;\n\ntype ChartContextProps = {\n config: ChartConfig;\n};\n\nconst ChartContext = React.createContext<ChartContextProps | null>(null);\n\nfunction useChart() {\n const context = React.useContext(ChartContext);\n\n if (!context) {\n throw new Error(\"useChart must be used within a <ChartContainer />\");\n }\n\n return context;\n}\n\n/** Root chart wrapper: provides the config context, theme CSS variables, and a responsive container. */\nfunction ChartContainer({\n id,\n className,\n children,\n config,\n initialDimension = INITIAL_DIMENSION,\n ...props\n}: React.ComponentProps<\"div\"> & {\n /** Maps data keys to labels, icons, and colors used across tooltip and legend. */\n config: ChartConfig;\n /** Recharts chart element rendered inside the responsive container. */\n children: React.ComponentProps<typeof RechartsPrimitive.ResponsiveContainer>[\"children\"];\n /** Initial width/height used before the responsive container measures its parent. */\n initialDimension?: {\n width: number;\n height: number;\n };\n}) {\n const uniqueId = React.useId();\n const chartId = `chart-${id ?? uniqueId.replace(/:/g, \"\")}`;\n\n return (\n <ChartContext.Provider value={{ config }}>\n <div\n data-slot=\"chart\"\n data-chart={chartId}\n className={cn(\n \"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-txt [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-primary-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-primary-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-primary-border [&_.recharts-radial-bar-background-sector]:fill-muted-bg [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted-bg [&_.recharts-reference-line_[stroke='#ccc']]:stroke-primary-border [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden\",\n className,\n )}\n {...props}\n >\n <ChartStyle id={chartId} config={config} />\n <RechartsPrimitive.ResponsiveContainer initialDimension={initialDimension}>\n {children}\n </RechartsPrimitive.ResponsiveContainer>\n </div>\n </ChartContext.Provider>\n );\n}\n\n/** Injects per-chart CSS custom properties (`--color-*`) derived from the config, one block per theme. */\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n const colorConfig = Object.entries(config).filter(([, config]) => config.theme ?? config.color);\n\n if (!colorConfig.length) {\n return null;\n }\n\n return (\n <style\n dangerouslySetInnerHTML={{\n __html: Object.entries(THEMES)\n .map(\n ([theme, prefix]) => `\n${prefix} [data-chart=${id}] {\n${colorConfig\n .map(([key, itemConfig]) => {\n const color = itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ?? itemConfig.color;\n return color ? ` --color-${key}: ${color};` : null;\n })\n .join(\"\\n\")}\n}\n`,\n )\n .join(\"\\n\"),\n }}\n />\n );\n};\n\n/** Recharts Tooltip element; pair with `ChartTooltipContent` for the styled body. */\nconst ChartTooltip = RechartsPrimitive.Tooltip;\n\n/** Styled tooltip body that resolves labels, colors, and indicators from the chart config. */\nfunction ChartTooltipContent({\n active,\n payload,\n className,\n indicator = \"dot\",\n hideLabel = false,\n hideIndicator = false,\n label,\n labelFormatter,\n labelClassName,\n formatter,\n color,\n nameKey,\n labelKey,\n}: React.ComponentProps<typeof RechartsPrimitive.Tooltip> &\n React.ComponentProps<\"div\"> & {\n /** Hides the tooltip's leading label row. */\n hideLabel?: boolean;\n /** Hides the per-item color indicator swatch. */\n hideIndicator?: boolean;\n /** Visual style of the per-item color indicator. */\n indicator?: \"line\" | \"dot\" | \"dashed\";\n /** Config key used to resolve each item's label/color (defaults to its name). */\n nameKey?: string;\n /** Config key used to resolve the tooltip's label (defaults to the data key). */\n labelKey?: string;\n } & Omit<\n RechartsPrimitive.DefaultTooltipContentProps<TooltipValueType, TooltipNameType>,\n \"accessibilityLayer\"\n >) {\n const { config } = useChart();\n\n const tooltipLabel = React.useMemo(() => {\n if (hideLabel || !payload?.length) {\n return null;\n }\n\n const [item] = payload;\n const key = `${labelKey ?? item?.dataKey ?? item?.name ?? \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const value =\n !labelKey && typeof label === \"string\" ? (config[label]?.label ?? label) : itemConfig?.label;\n\n if (labelFormatter) {\n return (\n <div className={cn(\"font-semibold\", labelClassName)}>{labelFormatter(value, payload)}</div>\n );\n }\n\n if (!value) {\n return null;\n }\n\n return <div className={cn(\"font-semibold\", labelClassName)}>{value}</div>;\n }, [label, labelFormatter, payload, hideLabel, labelClassName, config, labelKey]);\n\n if (!active || !payload?.length) {\n return null;\n }\n\n const nestLabel = payload.length === 1 && indicator !== \"dot\";\n\n return (\n <div\n className={cn(\n \"grid min-w-32 items-start rounded-8 border border-primary-border bg-glass-none-bg px-3 py-2 text-xs leading-4\",\n className,\n )}\n >\n {!nestLabel ? tooltipLabel : null}\n <div className=\"grid gap-1.5\">\n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.name ?? item.dataKey ?? \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n const indicatorColor = color ?? item.payload?.fill ?? item.color;\n\n return (\n <div\n key={index}\n className={cn(\n \"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-txt\",\n indicator === \"dot\" && \"items-center\",\n )}\n >\n {formatter && item?.value !== undefined && item.name ? (\n formatter(item.value, item.name, item, index, item.payload)\n ) : (\n <>\n {itemConfig?.icon ? (\n <itemConfig.icon />\n ) : (\n !hideIndicator && (\n <div\n className={cn(\n \"shrink-0 rounded-2 border-(--color-border) bg-(--color-bg)\",\n {\n \"h-2.5 w-2.5\": indicator === \"dot\",\n \"w-0.75\": indicator === \"line\",\n \"w-0 border-2 border-dashed bg-transparent\": indicator === \"dashed\",\n \"my-0.5\": nestLabel && indicator === \"dashed\",\n },\n )}\n style={\n {\n \"--color-bg\": indicatorColor,\n \"--color-border\": indicatorColor,\n } as React.CSSProperties\n }\n />\n )\n )}\n <div\n className={cn(\n \"flex flex-1 justify-between leading-none\",\n nestLabel ? \"items-end\" : \"items-center\",\n )}\n >\n <div className=\"grid gap-1.5\">\n {nestLabel ? tooltipLabel : null}\n <span className=\"text-primary-txt\">{itemConfig?.label ?? item.name}</span>\n </div>\n {item.value != null && (\n <span className=\"font-semibold text-primary-txt tabular-nums\">\n {typeof item.value === \"number\"\n ? item.value.toLocaleString()\n : String(item.value)}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n );\n })}\n </div>\n </div>\n );\n}\n\n/** Recharts Legend element; pair with `ChartLegendContent` for the styled body. */\nconst ChartLegend = RechartsPrimitive.Legend;\n\n/** Styled legend body that resolves labels, icons, and colors from the chart config. */\nfunction ChartLegendContent({\n className,\n hideIcon = false,\n payload,\n verticalAlign = \"bottom\",\n nameKey,\n}: React.ComponentProps<\"div\"> & {\n /** Hides each item's icon, showing only the color swatch. */\n hideIcon?: boolean;\n /** Config key used to resolve each item's label/color (defaults to the data key). */\n nameKey?: string;\n} & RechartsPrimitive.DefaultLegendContentProps) {\n const { config } = useChart();\n\n if (!payload?.length) {\n return null;\n }\n\n return (\n <div\n className={cn(\n \"flex items-center justify-center gap-4\",\n verticalAlign === \"top\" ? \"pb-3\" : \"pt-3\",\n className,\n )}\n >\n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.dataKey ?? \"value\"}`;\n const itemConfig = getPayloadConfigFromPayload(config, item, key);\n\n return (\n <div\n key={index}\n className={cn(\n \"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-txt\",\n )}\n >\n {itemConfig?.icon && !hideIcon ? (\n <itemConfig.icon />\n ) : (\n <div\n className=\"h-2 w-2 shrink-0 rounded-2\"\n style={{\n backgroundColor: item.color,\n }}\n />\n )}\n {itemConfig?.label}\n </div>\n );\n })}\n </div>\n );\n}\n\n// Helper to extract item config from a payload.\nfunction getPayloadConfigFromPayload(config: ChartConfig, payload: unknown, key: string) {\n if (typeof payload !== \"object\" || payload === null) {\n return undefined;\n }\n\n const payloadPayload =\n \"payload\" in payload && typeof payload.payload === \"object\" && payload.payload !== null\n ? payload.payload\n : undefined;\n\n let configLabelKey: string = key;\n\n if (key in payload && typeof payload[key as keyof typeof payload] === \"string\") {\n configLabelKey = payload[key as keyof typeof payload] as string;\n } else if (\n payloadPayload &&\n key in payloadPayload &&\n typeof payloadPayload[key as keyof typeof payloadPayload] === \"string\"\n ) {\n configLabelKey = payloadPayload[key as keyof typeof payloadPayload] as string;\n }\n\n return configLabelKey in config ? config[configLabelKey] : config[key];\n}\n\nexport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n ChartLegend,\n ChartLegendContent,\n ChartStyle,\n};\n"],"mappings":"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"}
|
|
@@ -9,7 +9,7 @@ let react_jsx_runtime = require("react/jsx-runtime");
|
|
|
9
9
|
function Checkbox({ className, ...props }) {
|
|
10
10
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(radix_ui.Checkbox.Root, {
|
|
11
11
|
"data-slot": "checkbox",
|
|
12
|
-
className: require_cn.cn("group/checkbox peer bg-input-
|
|
12
|
+
className: require_cn.cn("group/checkbox peer bg-input-bg size-4 shrink-0 rounded-4 border border-primary-invert-border transition-shadow outline-none disabled:cursor-not-allowed disabled:opacity-50 disabled:border-secondary-border", "data-[state=checked]:bg-primary-invert-bg data-[state=checked]:text-primary-invert-txt data-[state=checked]:border-transparent", "data-[state=indeterminate]:bg-primary-invert-bg data-[state=indeterminate]:text-primary-invert-txt data-[state=indeterminate]:border-transparent", "focus-visible:ring-focus focus-visible:ring-3", "aria-invalid:border-danger-border aria-invalid:ring-focus-error", "aria-invalid:data-[state=checked]:bg-danger-txt aria-invalid:data-[state=checked]:border-transparent", className),
|
|
13
13
|
...props,
|
|
14
14
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(radix_ui.Checkbox.Indicator, {
|
|
15
15
|
"data-slot": "checkbox-indicator",
|
|
@@ -25,22 +25,22 @@ function RichCheckbox({ className, title, description, flipped = false, id, ...p
|
|
|
25
25
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
26
26
|
"data-slot": "rich-checkbox",
|
|
27
27
|
htmlFor: checkboxId,
|
|
28
|
-
className: require_cn.cn("flex cursor-pointer items-start gap-3 rounded-
|
|
28
|
+
className: require_cn.cn("flex cursor-pointer items-start gap-3 rounded-10 border border-primary-border bg-muted-bg p-3 text-primary-txt transition-colors has-[[data-state=checked]]:border-selected-border has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50", flipped ? "flex-row-reverse" : "flex-row", className),
|
|
29
29
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Checkbox, {
|
|
30
30
|
"data-slot": "rich-checkbox-control",
|
|
31
31
|
id: checkboxId,
|
|
32
|
-
className: "mt-0.
|
|
32
|
+
className: "mt-0.75",
|
|
33
33
|
...props
|
|
34
34
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
35
35
|
"data-slot": "rich-checkbox-content",
|
|
36
|
-
className: "flex flex-1 flex-col gap-1",
|
|
36
|
+
className: "flex flex-1 flex-col gap-1.5",
|
|
37
37
|
children: [title != null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
38
38
|
"data-slot": "rich-checkbox-title",
|
|
39
|
-
className: "
|
|
39
|
+
className: "text-sm leading-5",
|
|
40
40
|
children: title
|
|
41
41
|
}), description != null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
42
42
|
"data-slot": "rich-checkbox-description",
|
|
43
|
-
className: "text-
|
|
43
|
+
className: "text-xs leading-4 text-muted-txt",
|
|
44
44
|
children: description
|
|
45
45
|
})]
|
|
46
46
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["CheckboxPrimitive","cn","CheckIcon","MinusIcon"],"sources":["../../../src/primitives/Checkbox/Checkbox.tsx"],"sourcesContent":["import { CheckIcon, MinusIcon } from \"lucide-react\";\nimport { Checkbox as CheckboxPrimitive } from \"radix-ui\";\nimport { useId } from \"react\";\nimport type * as React from \"react\";\n\nimport { cn } from \"@/utils\";\n\n/** A square toggle control built on Radix Checkbox, supporting checked, unchecked, indeterminate, error, and disabled states. */\nfunction Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n \"group/checkbox peer bg-input-
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["CheckboxPrimitive","cn","CheckIcon","MinusIcon"],"sources":["../../../src/primitives/Checkbox/Checkbox.tsx"],"sourcesContent":["import { CheckIcon, MinusIcon } from \"lucide-react\";\nimport { Checkbox as CheckboxPrimitive } from \"radix-ui\";\nimport { useId } from \"react\";\nimport type * as React from \"react\";\n\nimport { cn } from \"@/utils\";\n\n/** A square toggle control built on Radix Checkbox, supporting checked, unchecked, indeterminate, error, and disabled states. */\nfunction Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n \"group/checkbox peer bg-input-bg size-4 shrink-0 rounded-4 border border-primary-invert-border transition-shadow outline-none disabled:cursor-not-allowed disabled:opacity-50 disabled:border-secondary-border\",\n // Checked + indeterminate: full-bleed inverted fill, no visible border (Figma).\n \"data-[state=checked]:bg-primary-invert-bg data-[state=checked]:text-primary-invert-txt data-[state=checked]:border-transparent\",\n \"data-[state=indeterminate]:bg-primary-invert-bg data-[state=indeterminate]:text-primary-invert-txt data-[state=indeterminate]:border-transparent\",\n \"focus-visible:ring-focus focus-visible:ring-3\",\n // Error: danger border when unchecked, danger fill when checked. Figma binds\n // the fill to content/status/danger (the 700-level danger color), so the\n // checked error fill is the -txt token used as a background on purpose.\n \"aria-invalid:border-danger-border aria-invalid:ring-focus-error\",\n \"aria-invalid:data-[state=checked]:bg-danger-txt aria-invalid:data-[state=checked]:border-transparent\",\n className,\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"flex items-center justify-center text-current transition-none\"\n >\n <CheckIcon className=\"size-3.5 group-data-[state=indeterminate]/checkbox:hidden\" />\n <MinusIcon className=\"hidden size-3.5 group-data-[state=indeterminate]/checkbox:block\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\n/** A bordered card variant of {@link Checkbox} that pairs the control with a title and optional description. */\nfunction RichCheckbox({\n className,\n title,\n description,\n flipped = false,\n id,\n ...props\n}: Omit<React.ComponentProps<typeof Checkbox>, \"children\"> & {\n /** Primary label rendered next to the checkbox. */\n title?: React.ReactNode;\n /** Secondary helper text rendered beneath the title. */\n description?: React.ReactNode;\n /** When true, places the checkbox on the right (row-reverse) instead of the left. */\n flipped?: boolean;\n}) {\n const generatedId = useId();\n const checkboxId = id ?? generatedId;\n return (\n <label\n data-slot=\"rich-checkbox\"\n htmlFor={checkboxId}\n className={cn(\n \"flex cursor-pointer items-start gap-3 rounded-10 border border-primary-border bg-muted-bg p-3 text-primary-txt transition-colors has-[[data-state=checked]]:border-selected-border has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50\",\n flipped ? \"flex-row-reverse\" : \"flex-row\",\n className,\n )}\n >\n <Checkbox data-slot=\"rich-checkbox-control\" id={checkboxId} className=\"mt-0.75\" {...props} />\n <span data-slot=\"rich-checkbox-content\" className=\"flex flex-1 flex-col gap-1.5\">\n {title != null && (\n <span data-slot=\"rich-checkbox-title\" className=\"text-sm leading-5\">\n {title}\n </span>\n )}\n {description != null && (\n <span data-slot=\"rich-checkbox-description\" className=\"text-xs leading-4 text-muted-txt\">\n {description}\n </span>\n )}\n </span>\n </label>\n );\n}\n\nexport { Checkbox, RichCheckbox };\n"],"mappings":";;;;;;;;AAQA,SAAS,SAAS,EAAE,WAAW,GAAG,SAA8D;CAC9F,OACE,iBAAA,GAAA,kBAAA,KAACA,SAAAA,SAAkB,MAAnB;EACE,aAAU;EACV,WAAWC,WAAAA,GACT,iNAEA,kIACA,oJACA,iDAIA,mEACA,wGACA,SACF;EACA,GAAI;YAEJ,iBAAA,GAAA,kBAAA,MAACD,SAAAA,SAAkB,WAAnB;GACE,aAAU;GACV,WAAU;aAFZ,CAIE,iBAAA,GAAA,kBAAA,KAACE,aAAAA,WAAD,EAAW,WAAU,4DAA6D,CAAA,GAClF,iBAAA,GAAA,kBAAA,KAACC,aAAAA,WAAD,EAAW,WAAU,kEAAmE,CAAA,CAC7D;;CACP,CAAA;AAE5B;;AAGA,SAAS,aAAa,EACpB,WACA,OACA,aACA,UAAU,OACV,IACA,GAAG,SAQF;CACD,MAAM,eAAA,GAAA,MAAA,OAAoB;CAC1B,MAAM,aAAa,MAAM;CACzB,OACE,iBAAA,GAAA,kBAAA,MAAC,SAAD;EACE,aAAU;EACV,SAAS;EACT,WAAWF,WAAAA,GACT,oPACA,UAAU,qBAAqB,YAC/B,SACF;YAPF,CASE,iBAAA,GAAA,kBAAA,KAAC,UAAD;GAAU,aAAU;GAAwB,IAAI;GAAY,WAAU;GAAU,GAAI;EAAQ,CAAA,GAC5F,iBAAA,GAAA,kBAAA,MAAC,QAAD;GAAM,aAAU;GAAwB,WAAU;aAAlD,CACG,SAAS,QACR,iBAAA,GAAA,kBAAA,KAAC,QAAD;IAAM,aAAU;IAAsB,WAAU;cAC7C;GACG,CAAA,GAEP,eAAe,QACd,iBAAA,GAAA,kBAAA,KAAC,QAAD;IAAM,aAAU;IAA4B,WAAU;cACnD;GACG,CAAA,CAEJ;IACD;;AAEX"}
|
|
@@ -8,7 +8,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
8
8
|
function Checkbox({ className, ...props }) {
|
|
9
9
|
return /* @__PURE__ */ jsx(Checkbox$1.Root, {
|
|
10
10
|
"data-slot": "checkbox",
|
|
11
|
-
className: cn("group/checkbox peer bg-input-
|
|
11
|
+
className: cn("group/checkbox peer bg-input-bg size-4 shrink-0 rounded-4 border border-primary-invert-border transition-shadow outline-none disabled:cursor-not-allowed disabled:opacity-50 disabled:border-secondary-border", "data-[state=checked]:bg-primary-invert-bg data-[state=checked]:text-primary-invert-txt data-[state=checked]:border-transparent", "data-[state=indeterminate]:bg-primary-invert-bg data-[state=indeterminate]:text-primary-invert-txt data-[state=indeterminate]:border-transparent", "focus-visible:ring-focus focus-visible:ring-3", "aria-invalid:border-danger-border aria-invalid:ring-focus-error", "aria-invalid:data-[state=checked]:bg-danger-txt aria-invalid:data-[state=checked]:border-transparent", className),
|
|
12
12
|
...props,
|
|
13
13
|
children: /* @__PURE__ */ jsxs(Checkbox$1.Indicator, {
|
|
14
14
|
"data-slot": "checkbox-indicator",
|
|
@@ -24,22 +24,22 @@ function RichCheckbox({ className, title, description, flipped = false, id, ...p
|
|
|
24
24
|
return /* @__PURE__ */ jsxs("label", {
|
|
25
25
|
"data-slot": "rich-checkbox",
|
|
26
26
|
htmlFor: checkboxId,
|
|
27
|
-
className: cn("flex cursor-pointer items-start gap-3 rounded-
|
|
27
|
+
className: cn("flex cursor-pointer items-start gap-3 rounded-10 border border-primary-border bg-muted-bg p-3 text-primary-txt transition-colors has-[[data-state=checked]]:border-selected-border has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50", flipped ? "flex-row-reverse" : "flex-row", className),
|
|
28
28
|
children: [/* @__PURE__ */ jsx(Checkbox, {
|
|
29
29
|
"data-slot": "rich-checkbox-control",
|
|
30
30
|
id: checkboxId,
|
|
31
|
-
className: "mt-0.
|
|
31
|
+
className: "mt-0.75",
|
|
32
32
|
...props
|
|
33
33
|
}), /* @__PURE__ */ jsxs("span", {
|
|
34
34
|
"data-slot": "rich-checkbox-content",
|
|
35
|
-
className: "flex flex-1 flex-col gap-1",
|
|
35
|
+
className: "flex flex-1 flex-col gap-1.5",
|
|
36
36
|
children: [title != null && /* @__PURE__ */ jsx("span", {
|
|
37
37
|
"data-slot": "rich-checkbox-title",
|
|
38
|
-
className: "
|
|
38
|
+
className: "text-sm leading-5",
|
|
39
39
|
children: title
|
|
40
40
|
}), description != null && /* @__PURE__ */ jsx("span", {
|
|
41
41
|
"data-slot": "rich-checkbox-description",
|
|
42
|
-
className: "text-
|
|
42
|
+
className: "text-xs leading-4 text-muted-txt",
|
|
43
43
|
children: description
|
|
44
44
|
})]
|
|
45
45
|
})]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["CheckboxPrimitive"],"sources":["../../../src/primitives/Checkbox/Checkbox.tsx"],"sourcesContent":["import { CheckIcon, MinusIcon } from \"lucide-react\";\nimport { Checkbox as CheckboxPrimitive } from \"radix-ui\";\nimport { useId } from \"react\";\nimport type * as React from \"react\";\n\nimport { cn } from \"@/utils\";\n\n/** A square toggle control built on Radix Checkbox, supporting checked, unchecked, indeterminate, error, and disabled states. */\nfunction Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n \"group/checkbox peer bg-input-
|
|
1
|
+
{"version":3,"file":"index.js","names":["CheckboxPrimitive"],"sources":["../../../src/primitives/Checkbox/Checkbox.tsx"],"sourcesContent":["import { CheckIcon, MinusIcon } from \"lucide-react\";\nimport { Checkbox as CheckboxPrimitive } from \"radix-ui\";\nimport { useId } from \"react\";\nimport type * as React from \"react\";\n\nimport { cn } from \"@/utils\";\n\n/** A square toggle control built on Radix Checkbox, supporting checked, unchecked, indeterminate, error, and disabled states. */\nfunction Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n \"group/checkbox peer bg-input-bg size-4 shrink-0 rounded-4 border border-primary-invert-border transition-shadow outline-none disabled:cursor-not-allowed disabled:opacity-50 disabled:border-secondary-border\",\n // Checked + indeterminate: full-bleed inverted fill, no visible border (Figma).\n \"data-[state=checked]:bg-primary-invert-bg data-[state=checked]:text-primary-invert-txt data-[state=checked]:border-transparent\",\n \"data-[state=indeterminate]:bg-primary-invert-bg data-[state=indeterminate]:text-primary-invert-txt data-[state=indeterminate]:border-transparent\",\n \"focus-visible:ring-focus focus-visible:ring-3\",\n // Error: danger border when unchecked, danger fill when checked. Figma binds\n // the fill to content/status/danger (the 700-level danger color), so the\n // checked error fill is the -txt token used as a background on purpose.\n \"aria-invalid:border-danger-border aria-invalid:ring-focus-error\",\n \"aria-invalid:data-[state=checked]:bg-danger-txt aria-invalid:data-[state=checked]:border-transparent\",\n className,\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"flex items-center justify-center text-current transition-none\"\n >\n <CheckIcon className=\"size-3.5 group-data-[state=indeterminate]/checkbox:hidden\" />\n <MinusIcon className=\"hidden size-3.5 group-data-[state=indeterminate]/checkbox:block\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n );\n}\n\n/** A bordered card variant of {@link Checkbox} that pairs the control with a title and optional description. */\nfunction RichCheckbox({\n className,\n title,\n description,\n flipped = false,\n id,\n ...props\n}: Omit<React.ComponentProps<typeof Checkbox>, \"children\"> & {\n /** Primary label rendered next to the checkbox. */\n title?: React.ReactNode;\n /** Secondary helper text rendered beneath the title. */\n description?: React.ReactNode;\n /** When true, places the checkbox on the right (row-reverse) instead of the left. */\n flipped?: boolean;\n}) {\n const generatedId = useId();\n const checkboxId = id ?? generatedId;\n return (\n <label\n data-slot=\"rich-checkbox\"\n htmlFor={checkboxId}\n className={cn(\n \"flex cursor-pointer items-start gap-3 rounded-10 border border-primary-border bg-muted-bg p-3 text-primary-txt transition-colors has-[[data-state=checked]]:border-selected-border has-[:disabled]:cursor-not-allowed has-[:disabled]:opacity-50\",\n flipped ? \"flex-row-reverse\" : \"flex-row\",\n className,\n )}\n >\n <Checkbox data-slot=\"rich-checkbox-control\" id={checkboxId} className=\"mt-0.75\" {...props} />\n <span data-slot=\"rich-checkbox-content\" className=\"flex flex-1 flex-col gap-1.5\">\n {title != null && (\n <span data-slot=\"rich-checkbox-title\" className=\"text-sm leading-5\">\n {title}\n </span>\n )}\n {description != null && (\n <span data-slot=\"rich-checkbox-description\" className=\"text-xs leading-4 text-muted-txt\">\n {description}\n </span>\n )}\n </span>\n </label>\n );\n}\n\nexport { Checkbox, RichCheckbox };\n"],"mappings":";;;;;;;AAQA,SAAS,SAAS,EAAE,WAAW,GAAG,SAA8D;CAC9F,OACE,oBAACA,WAAkB,MAAnB;EACE,aAAU;EACV,WAAW,GACT,iNAEA,kIACA,oJACA,iDAIA,mEACA,wGACA,SACF;EACA,GAAI;YAEJ,qBAACA,WAAkB,WAAnB;GACE,aAAU;GACV,WAAU;aAFZ,CAIE,oBAAC,WAAD,EAAW,WAAU,4DAA6D,CAAA,GAClF,oBAAC,WAAD,EAAW,WAAU,kEAAmE,CAAA,CAC7D;;CACP,CAAA;AAE5B;;AAGA,SAAS,aAAa,EACpB,WACA,OACA,aACA,UAAU,OACV,IACA,GAAG,SAQF;CACD,MAAM,cAAc,MAAM;CAC1B,MAAM,aAAa,MAAM;CACzB,OACE,qBAAC,SAAD;EACE,aAAU;EACV,SAAS;EACT,WAAW,GACT,oPACA,UAAU,qBAAqB,YAC/B,SACF;YAPF,CASE,oBAAC,UAAD;GAAU,aAAU;GAAwB,IAAI;GAAY,WAAU;GAAU,GAAI;EAAQ,CAAA,GAC5F,qBAAC,QAAD;GAAM,aAAU;GAAwB,WAAU;aAAlD,CACG,SAAS,QACR,oBAAC,QAAD;IAAM,aAAU;IAAsB,WAAU;cAC7C;GACG,CAAA,GAEP,eAAe,QACd,oBAAC,QAAD;IAAM,aAAU;IAA4B,WAAU;cACnD;GACG,CAAA,CAEJ;IACD;;AAEX"}
|
|
@@ -73,11 +73,11 @@ function TreeNode({ node, depth, selected, expanded, onToggleSelect, onToggleExp
|
|
|
73
73
|
type: "button",
|
|
74
74
|
onClick: () => onToggleExpand(node.id),
|
|
75
75
|
"aria-label": isExpanded ? "Collapse" : "Expand",
|
|
76
|
-
className: "flex size-5 shrink-0 items-center justify-center text-muted-
|
|
76
|
+
className: "flex size-5 shrink-0 items-center justify-center text-muted-txt hover:text-primary-txt",
|
|
77
77
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronRight, { className: require_cn.cn("size-4 transition-transform", isExpanded && "rotate-90") })
|
|
78
78
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "w-5 shrink-0" }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
79
79
|
htmlFor: checkboxId,
|
|
80
|
-
className: "flex flex-1 cursor-pointer items-center gap-2 rounded-
|
|
80
|
+
className: "flex flex-1 cursor-pointer items-center gap-2 rounded-6 px-2 py-1.5 transition-colors hover:bg-muted-bg/40",
|
|
81
81
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_primitives_Checkbox_index.Checkbox, {
|
|
82
82
|
id: checkboxId,
|
|
83
83
|
checked: state === "indeterminate" ? "indeterminate" : state === "checked",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["React","cn","ChevronRight","Checkbox"],"sources":["../../../src/primitives/CheckboxTree/CheckboxTree.tsx"],"sourcesContent":["\"use client\";\n\nimport { ChevronRight } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Checkbox } from \"@/primitives/Checkbox\";\nimport { cn } from \"@/utils\";\n\n// CheckboxTree — a hierarchical checkbox list with expand/collapse and\n// tri-state (checked / unchecked / indeterminate) propagation: toggling a branch\n// toggles all its descendants, and a branch reflects its children\n// (checked when all are, indeterminate when some are). Controlled via `value`\n// (the set of selected node ids, branches included when fully selected).\n\n/** A single node in the tree: a stable id, a label, and optional children. */\nexport interface CheckboxTreeNode {\n /** Stable unique identifier used for selection and expansion tracking. */\n id: string;\n /** Content rendered next to the checkbox. */\n label: React.ReactNode;\n /** Nested child nodes; presence makes this node a collapsible branch. */\n children?: CheckboxTreeNode[];\n}\n\ntype NodeState = \"checked\" | \"unchecked\" | \"indeterminate\";\n\n/** All ids in a node's subtree (the node itself + every descendant). */\nfunction collectIds(node: CheckboxTreeNode): string[] {\n if (!node.children?.length) return [node.id];\n return [node.id, ...node.children.flatMap(collectIds)];\n}\n\n/** A leaf is checked iff selected; a branch derives its state from its children. */\nfunction getNodeState(node: CheckboxTreeNode, selected: Set<string>): NodeState {\n if (!node.children?.length) return selected.has(node.id) ? \"checked\" : \"unchecked\";\n const states = node.children.map((child) => getNodeState(child, selected));\n if (states.every((s) => s === \"checked\")) return \"checked\";\n if (states.every((s) => s === \"unchecked\")) return \"unchecked\";\n return \"indeterminate\";\n}\n\ninterface CheckboxTreeProps extends Omit<React.ComponentProps<\"div\">, \"onChange\"> {\n /** The hierarchical node data to render. */\n nodes: CheckboxTreeNode[];\n /** Selected node ids (controlled). Includes branch ids when fully selected. */\n value: string[];\n /** Called with the next selected ids whenever a node (and its subtree) is toggled. */\n onValueChange?: (value: string[]) => void;\n /** Node ids expanded on first render. */\n defaultExpandedIds?: string[];\n}\n\n/**\n * A hierarchical checkbox list with expand/collapse and tri-state\n * (checked / unchecked / indeterminate) propagation across each subtree.\n */\nfunction CheckboxTree({\n nodes,\n value,\n onValueChange,\n defaultExpandedIds,\n className,\n ...props\n}: CheckboxTreeProps) {\n const [expanded, setExpanded] = React.useState<Set<string>>(\n () => new Set(defaultExpandedIds ?? []),\n );\n const selected = React.useMemo(() => new Set(value), [value]);\n\n const toggleExpand = (id: string) =>\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n\n const toggleSelect = (node: CheckboxTreeNode) => {\n const ids = collectIds(node);\n const allSelected = ids.every((id) => selected.has(id));\n const next = new Set(selected);\n for (const id of ids) {\n if (allSelected) next.delete(id);\n else next.add(id);\n }\n onValueChange?.([...next]);\n };\n\n return (\n <div\n role=\"tree\"\n data-slot=\"checkbox-tree\"\n className={cn(\"flex flex-col gap-1\", className)}\n {...props}\n >\n {nodes.map((node) => (\n <TreeNode\n key={node.id}\n node={node}\n depth={0}\n selected={selected}\n expanded={expanded}\n onToggleSelect={toggleSelect}\n onToggleExpand={toggleExpand}\n />\n ))}\n </div>\n );\n}\n\ninterface TreeNodeProps {\n /** The node rendered by this row. */\n node: CheckboxTreeNode;\n /** Nesting depth, used for indentation and heading emphasis. */\n depth: number;\n /** Set of currently selected node ids. */\n selected: Set<string>;\n /** Set of currently expanded node ids. */\n expanded: Set<string>;\n /** Toggles selection of the node and its subtree. */\n onToggleSelect: (node: CheckboxTreeNode) => void;\n /** Toggles the expanded/collapsed state of a branch. */\n onToggleExpand: (id: string) => void;\n}\n\n/** Renders a single tree row plus, when expanded, its child rows recursively. */\nfunction TreeNode({\n node,\n depth,\n selected,\n expanded,\n onToggleSelect,\n onToggleExpand,\n}: TreeNodeProps) {\n const hasChildren = !!node.children?.length;\n const isExpanded = expanded.has(node.id);\n const state = getNodeState(node, selected);\n const checkboxId = React.useId();\n\n return (\n <div\n role=\"treeitem\"\n aria-expanded={hasChildren ? isExpanded : undefined}\n aria-checked={state === \"indeterminate\" ? \"mixed\" : state === \"checked\"}\n >\n <div className=\"flex items-center gap-1\" style={{ paddingLeft: `${depth * 1.5}rem` }}>\n {hasChildren ? (\n <button\n type=\"button\"\n onClick={() => onToggleExpand(node.id)}\n aria-label={isExpanded ? \"Collapse\" : \"Expand\"}\n className=\"flex size-5 shrink-0 items-center justify-center text-muted-
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["React","cn","ChevronRight","Checkbox"],"sources":["../../../src/primitives/CheckboxTree/CheckboxTree.tsx"],"sourcesContent":["\"use client\";\n\nimport { ChevronRight } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Checkbox } from \"@/primitives/Checkbox\";\nimport { cn } from \"@/utils\";\n\n// CheckboxTree — a hierarchical checkbox list with expand/collapse and\n// tri-state (checked / unchecked / indeterminate) propagation: toggling a branch\n// toggles all its descendants, and a branch reflects its children\n// (checked when all are, indeterminate when some are). Controlled via `value`\n// (the set of selected node ids, branches included when fully selected).\n\n/** A single node in the tree: a stable id, a label, and optional children. */\nexport interface CheckboxTreeNode {\n /** Stable unique identifier used for selection and expansion tracking. */\n id: string;\n /** Content rendered next to the checkbox. */\n label: React.ReactNode;\n /** Nested child nodes; presence makes this node a collapsible branch. */\n children?: CheckboxTreeNode[];\n}\n\ntype NodeState = \"checked\" | \"unchecked\" | \"indeterminate\";\n\n/** All ids in a node's subtree (the node itself + every descendant). */\nfunction collectIds(node: CheckboxTreeNode): string[] {\n if (!node.children?.length) return [node.id];\n return [node.id, ...node.children.flatMap(collectIds)];\n}\n\n/** A leaf is checked iff selected; a branch derives its state from its children. */\nfunction getNodeState(node: CheckboxTreeNode, selected: Set<string>): NodeState {\n if (!node.children?.length) return selected.has(node.id) ? \"checked\" : \"unchecked\";\n const states = node.children.map((child) => getNodeState(child, selected));\n if (states.every((s) => s === \"checked\")) return \"checked\";\n if (states.every((s) => s === \"unchecked\")) return \"unchecked\";\n return \"indeterminate\";\n}\n\ninterface CheckboxTreeProps extends Omit<React.ComponentProps<\"div\">, \"onChange\"> {\n /** The hierarchical node data to render. */\n nodes: CheckboxTreeNode[];\n /** Selected node ids (controlled). Includes branch ids when fully selected. */\n value: string[];\n /** Called with the next selected ids whenever a node (and its subtree) is toggled. */\n onValueChange?: (value: string[]) => void;\n /** Node ids expanded on first render. */\n defaultExpandedIds?: string[];\n}\n\n/**\n * A hierarchical checkbox list with expand/collapse and tri-state\n * (checked / unchecked / indeterminate) propagation across each subtree.\n */\nfunction CheckboxTree({\n nodes,\n value,\n onValueChange,\n defaultExpandedIds,\n className,\n ...props\n}: CheckboxTreeProps) {\n const [expanded, setExpanded] = React.useState<Set<string>>(\n () => new Set(defaultExpandedIds ?? []),\n );\n const selected = React.useMemo(() => new Set(value), [value]);\n\n const toggleExpand = (id: string) =>\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n\n const toggleSelect = (node: CheckboxTreeNode) => {\n const ids = collectIds(node);\n const allSelected = ids.every((id) => selected.has(id));\n const next = new Set(selected);\n for (const id of ids) {\n if (allSelected) next.delete(id);\n else next.add(id);\n }\n onValueChange?.([...next]);\n };\n\n return (\n <div\n role=\"tree\"\n data-slot=\"checkbox-tree\"\n className={cn(\"flex flex-col gap-1\", className)}\n {...props}\n >\n {nodes.map((node) => (\n <TreeNode\n key={node.id}\n node={node}\n depth={0}\n selected={selected}\n expanded={expanded}\n onToggleSelect={toggleSelect}\n onToggleExpand={toggleExpand}\n />\n ))}\n </div>\n );\n}\n\ninterface TreeNodeProps {\n /** The node rendered by this row. */\n node: CheckboxTreeNode;\n /** Nesting depth, used for indentation and heading emphasis. */\n depth: number;\n /** Set of currently selected node ids. */\n selected: Set<string>;\n /** Set of currently expanded node ids. */\n expanded: Set<string>;\n /** Toggles selection of the node and its subtree. */\n onToggleSelect: (node: CheckboxTreeNode) => void;\n /** Toggles the expanded/collapsed state of a branch. */\n onToggleExpand: (id: string) => void;\n}\n\n/** Renders a single tree row plus, when expanded, its child rows recursively. */\nfunction TreeNode({\n node,\n depth,\n selected,\n expanded,\n onToggleSelect,\n onToggleExpand,\n}: TreeNodeProps) {\n const hasChildren = !!node.children?.length;\n const isExpanded = expanded.has(node.id);\n const state = getNodeState(node, selected);\n const checkboxId = React.useId();\n\n return (\n <div\n role=\"treeitem\"\n aria-expanded={hasChildren ? isExpanded : undefined}\n aria-checked={state === \"indeterminate\" ? \"mixed\" : state === \"checked\"}\n >\n <div className=\"flex items-center gap-1\" style={{ paddingLeft: `${depth * 1.5}rem` }}>\n {hasChildren ? (\n <button\n type=\"button\"\n onClick={() => onToggleExpand(node.id)}\n aria-label={isExpanded ? \"Collapse\" : \"Expand\"}\n className=\"flex size-5 shrink-0 items-center justify-center text-muted-txt hover:text-primary-txt\"\n >\n <ChevronRight\n className={cn(\"size-4 transition-transform\", isExpanded && \"rotate-90\")}\n />\n </button>\n ) : (\n <span className=\"w-5 shrink-0\" />\n )}\n <label\n htmlFor={checkboxId}\n className=\"flex flex-1 cursor-pointer items-center gap-2 rounded-6 px-2 py-1.5 transition-colors hover:bg-muted-bg/40\"\n >\n <Checkbox\n id={checkboxId}\n checked={state === \"indeterminate\" ? \"indeterminate\" : state === \"checked\"}\n onCheckedChange={() => onToggleSelect(node)}\n />\n <span className={cn(\"text-sm\", depth === 0 && \"font-medium\")}>{node.label}</span>\n </label>\n </div>\n {hasChildren && isExpanded && (\n <div role=\"group\">\n {node.children?.map((child) => (\n <TreeNode\n key={child.id}\n node={child}\n depth={depth + 1}\n selected={selected}\n expanded={expanded}\n onToggleSelect={onToggleSelect}\n onToggleExpand={onToggleExpand}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nexport { CheckboxTree };\n"],"mappings":";;;;;;;;;;AA2BA,SAAS,WAAW,MAAkC;CACpD,IAAI,CAAC,KAAK,UAAU,QAAQ,OAAO,CAAC,KAAK,EAAE;CAC3C,OAAO,CAAC,KAAK,IAAI,GAAG,KAAK,SAAS,QAAQ,UAAU,CAAC;AACvD;;AAGA,SAAS,aAAa,MAAwB,UAAkC;CAC9E,IAAI,CAAC,KAAK,UAAU,QAAQ,OAAO,SAAS,IAAI,KAAK,EAAE,IAAI,YAAY;CACvE,MAAM,SAAS,KAAK,SAAS,KAAK,UAAU,aAAa,OAAO,QAAQ,CAAC;CACzE,IAAI,OAAO,OAAO,MAAM,MAAM,SAAS,GAAG,OAAO;CACjD,IAAI,OAAO,OAAO,MAAM,MAAM,WAAW,GAAG,OAAO;CACnD,OAAO;AACT;;;;;AAiBA,SAAS,aAAa,EACpB,OACA,OACA,eACA,oBACA,WACA,GAAG,SACiB;CACpB,MAAM,CAAC,UAAU,eAAeA,MAAM,eAC9B,IAAI,IAAI,sBAAsB,CAAC,CAAC,CACxC;CACA,MAAM,WAAWA,MAAM,cAAc,IAAI,IAAI,KAAK,GAAG,CAAC,KAAK,CAAC;CAE5D,MAAM,gBAAgB,OACpB,aAAa,SAAS;EACpB,MAAM,OAAO,IAAI,IAAI,IAAI;EACzB,IAAI,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,EAAE;OAC3B,KAAK,IAAI,EAAE;EAChB,OAAO;CACT,CAAC;CAEH,MAAM,gBAAgB,SAA2B;EAC/C,MAAM,MAAM,WAAW,IAAI;EAC3B,MAAM,cAAc,IAAI,OAAO,OAAO,SAAS,IAAI,EAAE,CAAC;EACtD,MAAM,OAAO,IAAI,IAAI,QAAQ;EAC7B,KAAK,MAAM,MAAM,KACf,IAAI,aAAa,KAAK,OAAO,EAAE;OAC1B,KAAK,IAAI,EAAE;EAElB,gBAAgB,CAAC,GAAG,IAAI,CAAC;CAC3B;CAEA,OACE,iBAAA,GAAA,kBAAA,KAAC,OAAD;EACE,MAAK;EACL,aAAU;EACV,WAAWC,WAAAA,GAAG,uBAAuB,SAAS;EAC9C,GAAI;YAEH,MAAM,KAAK,SACV,iBAAA,GAAA,kBAAA,KAAC,UAAD;GAEQ;GACN,OAAO;GACG;GACA;GACV,gBAAgB;GAChB,gBAAgB;EACjB,GAPM,KAAK,EAOX,CACF;CACE,CAAA;AAET;;AAkBA,SAAS,SAAS,EAChB,MACA,OACA,UACA,UACA,gBACA,kBACgB;CAChB,MAAM,cAAc,CAAC,CAAC,KAAK,UAAU;CACrC,MAAM,aAAa,SAAS,IAAI,KAAK,EAAE;CACvC,MAAM,QAAQ,aAAa,MAAM,QAAQ;CACzC,MAAM,aAAaD,MAAM,MAAM;CAE/B,OACE,iBAAA,GAAA,kBAAA,MAAC,OAAD;EACE,MAAK;EACL,iBAAe,cAAc,aAAa,KAAA;EAC1C,gBAAc,UAAU,kBAAkB,UAAU,UAAU;YAHhE,CAKE,iBAAA,GAAA,kBAAA,MAAC,OAAD;GAAK,WAAU;GAA0B,OAAO,EAAE,aAAa,GAAG,QAAQ,IAAI,KAAK;aAAnF,CACG,cACC,iBAAA,GAAA,kBAAA,KAAC,UAAD;IACE,MAAK;IACL,eAAe,eAAe,KAAK,EAAE;IACrC,cAAY,aAAa,aAAa;IACtC,WAAU;cAEV,iBAAA,GAAA,kBAAA,KAACE,aAAAA,cAAD,EACE,WAAWD,WAAAA,GAAG,+BAA+B,cAAc,WAAW,EACvE,CAAA;GACK,CAAA,IAER,iBAAA,GAAA,kBAAA,KAAC,QAAD,EAAM,WAAU,eAAgB,CAAA,GAElC,iBAAA,GAAA,kBAAA,MAAC,SAAD;IACE,SAAS;IACT,WAAU;cAFZ,CAIE,iBAAA,GAAA,kBAAA,KAACE,kCAAAA,UAAD;KACE,IAAI;KACJ,SAAS,UAAU,kBAAkB,kBAAkB,UAAU;KACjE,uBAAuB,eAAe,IAAI;IAC3C,CAAA,GACD,iBAAA,GAAA,kBAAA,KAAC,QAAD;KAAM,WAAWF,WAAAA,GAAG,WAAW,UAAU,KAAK,aAAa;eAAI,KAAK;IAAY,CAAA,CAC3E;KACJ;MACJ,eAAe,cACd,iBAAA,GAAA,kBAAA,KAAC,OAAD;GAAK,MAAK;aACP,KAAK,UAAU,KAAK,UACnB,iBAAA,GAAA,kBAAA,KAAC,UAAD;IAEE,MAAM;IACN,OAAO,QAAQ;IACL;IACA;IACM;IACA;GACjB,GAPM,MAAM,EAOZ,CACF;EACE,CAAA,CAEJ;;AAET"}
|
|
@@ -70,11 +70,11 @@ function TreeNode({ node, depth, selected, expanded, onToggleSelect, onToggleExp
|
|
|
70
70
|
type: "button",
|
|
71
71
|
onClick: () => onToggleExpand(node.id),
|
|
72
72
|
"aria-label": isExpanded ? "Collapse" : "Expand",
|
|
73
|
-
className: "flex size-5 shrink-0 items-center justify-center text-muted-
|
|
73
|
+
className: "flex size-5 shrink-0 items-center justify-center text-muted-txt hover:text-primary-txt",
|
|
74
74
|
children: /* @__PURE__ */ jsx(ChevronRight, { className: cn("size-4 transition-transform", isExpanded && "rotate-90") })
|
|
75
75
|
}) : /* @__PURE__ */ jsx("span", { className: "w-5 shrink-0" }), /* @__PURE__ */ jsxs("label", {
|
|
76
76
|
htmlFor: checkboxId,
|
|
77
|
-
className: "flex flex-1 cursor-pointer items-center gap-2 rounded-
|
|
77
|
+
className: "flex flex-1 cursor-pointer items-center gap-2 rounded-6 px-2 py-1.5 transition-colors hover:bg-muted-bg/40",
|
|
78
78
|
children: [/* @__PURE__ */ jsx(Checkbox, {
|
|
79
79
|
id: checkboxId,
|
|
80
80
|
checked: state === "indeterminate" ? "indeterminate" : state === "checked",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/primitives/CheckboxTree/CheckboxTree.tsx"],"sourcesContent":["\"use client\";\n\nimport { ChevronRight } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Checkbox } from \"@/primitives/Checkbox\";\nimport { cn } from \"@/utils\";\n\n// CheckboxTree — a hierarchical checkbox list with expand/collapse and\n// tri-state (checked / unchecked / indeterminate) propagation: toggling a branch\n// toggles all its descendants, and a branch reflects its children\n// (checked when all are, indeterminate when some are). Controlled via `value`\n// (the set of selected node ids, branches included when fully selected).\n\n/** A single node in the tree: a stable id, a label, and optional children. */\nexport interface CheckboxTreeNode {\n /** Stable unique identifier used for selection and expansion tracking. */\n id: string;\n /** Content rendered next to the checkbox. */\n label: React.ReactNode;\n /** Nested child nodes; presence makes this node a collapsible branch. */\n children?: CheckboxTreeNode[];\n}\n\ntype NodeState = \"checked\" | \"unchecked\" | \"indeterminate\";\n\n/** All ids in a node's subtree (the node itself + every descendant). */\nfunction collectIds(node: CheckboxTreeNode): string[] {\n if (!node.children?.length) return [node.id];\n return [node.id, ...node.children.flatMap(collectIds)];\n}\n\n/** A leaf is checked iff selected; a branch derives its state from its children. */\nfunction getNodeState(node: CheckboxTreeNode, selected: Set<string>): NodeState {\n if (!node.children?.length) return selected.has(node.id) ? \"checked\" : \"unchecked\";\n const states = node.children.map((child) => getNodeState(child, selected));\n if (states.every((s) => s === \"checked\")) return \"checked\";\n if (states.every((s) => s === \"unchecked\")) return \"unchecked\";\n return \"indeterminate\";\n}\n\ninterface CheckboxTreeProps extends Omit<React.ComponentProps<\"div\">, \"onChange\"> {\n /** The hierarchical node data to render. */\n nodes: CheckboxTreeNode[];\n /** Selected node ids (controlled). Includes branch ids when fully selected. */\n value: string[];\n /** Called with the next selected ids whenever a node (and its subtree) is toggled. */\n onValueChange?: (value: string[]) => void;\n /** Node ids expanded on first render. */\n defaultExpandedIds?: string[];\n}\n\n/**\n * A hierarchical checkbox list with expand/collapse and tri-state\n * (checked / unchecked / indeterminate) propagation across each subtree.\n */\nfunction CheckboxTree({\n nodes,\n value,\n onValueChange,\n defaultExpandedIds,\n className,\n ...props\n}: CheckboxTreeProps) {\n const [expanded, setExpanded] = React.useState<Set<string>>(\n () => new Set(defaultExpandedIds ?? []),\n );\n const selected = React.useMemo(() => new Set(value), [value]);\n\n const toggleExpand = (id: string) =>\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n\n const toggleSelect = (node: CheckboxTreeNode) => {\n const ids = collectIds(node);\n const allSelected = ids.every((id) => selected.has(id));\n const next = new Set(selected);\n for (const id of ids) {\n if (allSelected) next.delete(id);\n else next.add(id);\n }\n onValueChange?.([...next]);\n };\n\n return (\n <div\n role=\"tree\"\n data-slot=\"checkbox-tree\"\n className={cn(\"flex flex-col gap-1\", className)}\n {...props}\n >\n {nodes.map((node) => (\n <TreeNode\n key={node.id}\n node={node}\n depth={0}\n selected={selected}\n expanded={expanded}\n onToggleSelect={toggleSelect}\n onToggleExpand={toggleExpand}\n />\n ))}\n </div>\n );\n}\n\ninterface TreeNodeProps {\n /** The node rendered by this row. */\n node: CheckboxTreeNode;\n /** Nesting depth, used for indentation and heading emphasis. */\n depth: number;\n /** Set of currently selected node ids. */\n selected: Set<string>;\n /** Set of currently expanded node ids. */\n expanded: Set<string>;\n /** Toggles selection of the node and its subtree. */\n onToggleSelect: (node: CheckboxTreeNode) => void;\n /** Toggles the expanded/collapsed state of a branch. */\n onToggleExpand: (id: string) => void;\n}\n\n/** Renders a single tree row plus, when expanded, its child rows recursively. */\nfunction TreeNode({\n node,\n depth,\n selected,\n expanded,\n onToggleSelect,\n onToggleExpand,\n}: TreeNodeProps) {\n const hasChildren = !!node.children?.length;\n const isExpanded = expanded.has(node.id);\n const state = getNodeState(node, selected);\n const checkboxId = React.useId();\n\n return (\n <div\n role=\"treeitem\"\n aria-expanded={hasChildren ? isExpanded : undefined}\n aria-checked={state === \"indeterminate\" ? \"mixed\" : state === \"checked\"}\n >\n <div className=\"flex items-center gap-1\" style={{ paddingLeft: `${depth * 1.5}rem` }}>\n {hasChildren ? (\n <button\n type=\"button\"\n onClick={() => onToggleExpand(node.id)}\n aria-label={isExpanded ? \"Collapse\" : \"Expand\"}\n className=\"flex size-5 shrink-0 items-center justify-center text-muted-
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/primitives/CheckboxTree/CheckboxTree.tsx"],"sourcesContent":["\"use client\";\n\nimport { ChevronRight } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Checkbox } from \"@/primitives/Checkbox\";\nimport { cn } from \"@/utils\";\n\n// CheckboxTree — a hierarchical checkbox list with expand/collapse and\n// tri-state (checked / unchecked / indeterminate) propagation: toggling a branch\n// toggles all its descendants, and a branch reflects its children\n// (checked when all are, indeterminate when some are). Controlled via `value`\n// (the set of selected node ids, branches included when fully selected).\n\n/** A single node in the tree: a stable id, a label, and optional children. */\nexport interface CheckboxTreeNode {\n /** Stable unique identifier used for selection and expansion tracking. */\n id: string;\n /** Content rendered next to the checkbox. */\n label: React.ReactNode;\n /** Nested child nodes; presence makes this node a collapsible branch. */\n children?: CheckboxTreeNode[];\n}\n\ntype NodeState = \"checked\" | \"unchecked\" | \"indeterminate\";\n\n/** All ids in a node's subtree (the node itself + every descendant). */\nfunction collectIds(node: CheckboxTreeNode): string[] {\n if (!node.children?.length) return [node.id];\n return [node.id, ...node.children.flatMap(collectIds)];\n}\n\n/** A leaf is checked iff selected; a branch derives its state from its children. */\nfunction getNodeState(node: CheckboxTreeNode, selected: Set<string>): NodeState {\n if (!node.children?.length) return selected.has(node.id) ? \"checked\" : \"unchecked\";\n const states = node.children.map((child) => getNodeState(child, selected));\n if (states.every((s) => s === \"checked\")) return \"checked\";\n if (states.every((s) => s === \"unchecked\")) return \"unchecked\";\n return \"indeterminate\";\n}\n\ninterface CheckboxTreeProps extends Omit<React.ComponentProps<\"div\">, \"onChange\"> {\n /** The hierarchical node data to render. */\n nodes: CheckboxTreeNode[];\n /** Selected node ids (controlled). Includes branch ids when fully selected. */\n value: string[];\n /** Called with the next selected ids whenever a node (and its subtree) is toggled. */\n onValueChange?: (value: string[]) => void;\n /** Node ids expanded on first render. */\n defaultExpandedIds?: string[];\n}\n\n/**\n * A hierarchical checkbox list with expand/collapse and tri-state\n * (checked / unchecked / indeterminate) propagation across each subtree.\n */\nfunction CheckboxTree({\n nodes,\n value,\n onValueChange,\n defaultExpandedIds,\n className,\n ...props\n}: CheckboxTreeProps) {\n const [expanded, setExpanded] = React.useState<Set<string>>(\n () => new Set(defaultExpandedIds ?? []),\n );\n const selected = React.useMemo(() => new Set(value), [value]);\n\n const toggleExpand = (id: string) =>\n setExpanded((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n\n const toggleSelect = (node: CheckboxTreeNode) => {\n const ids = collectIds(node);\n const allSelected = ids.every((id) => selected.has(id));\n const next = new Set(selected);\n for (const id of ids) {\n if (allSelected) next.delete(id);\n else next.add(id);\n }\n onValueChange?.([...next]);\n };\n\n return (\n <div\n role=\"tree\"\n data-slot=\"checkbox-tree\"\n className={cn(\"flex flex-col gap-1\", className)}\n {...props}\n >\n {nodes.map((node) => (\n <TreeNode\n key={node.id}\n node={node}\n depth={0}\n selected={selected}\n expanded={expanded}\n onToggleSelect={toggleSelect}\n onToggleExpand={toggleExpand}\n />\n ))}\n </div>\n );\n}\n\ninterface TreeNodeProps {\n /** The node rendered by this row. */\n node: CheckboxTreeNode;\n /** Nesting depth, used for indentation and heading emphasis. */\n depth: number;\n /** Set of currently selected node ids. */\n selected: Set<string>;\n /** Set of currently expanded node ids. */\n expanded: Set<string>;\n /** Toggles selection of the node and its subtree. */\n onToggleSelect: (node: CheckboxTreeNode) => void;\n /** Toggles the expanded/collapsed state of a branch. */\n onToggleExpand: (id: string) => void;\n}\n\n/** Renders a single tree row plus, when expanded, its child rows recursively. */\nfunction TreeNode({\n node,\n depth,\n selected,\n expanded,\n onToggleSelect,\n onToggleExpand,\n}: TreeNodeProps) {\n const hasChildren = !!node.children?.length;\n const isExpanded = expanded.has(node.id);\n const state = getNodeState(node, selected);\n const checkboxId = React.useId();\n\n return (\n <div\n role=\"treeitem\"\n aria-expanded={hasChildren ? isExpanded : undefined}\n aria-checked={state === \"indeterminate\" ? \"mixed\" : state === \"checked\"}\n >\n <div className=\"flex items-center gap-1\" style={{ paddingLeft: `${depth * 1.5}rem` }}>\n {hasChildren ? (\n <button\n type=\"button\"\n onClick={() => onToggleExpand(node.id)}\n aria-label={isExpanded ? \"Collapse\" : \"Expand\"}\n className=\"flex size-5 shrink-0 items-center justify-center text-muted-txt hover:text-primary-txt\"\n >\n <ChevronRight\n className={cn(\"size-4 transition-transform\", isExpanded && \"rotate-90\")}\n />\n </button>\n ) : (\n <span className=\"w-5 shrink-0\" />\n )}\n <label\n htmlFor={checkboxId}\n className=\"flex flex-1 cursor-pointer items-center gap-2 rounded-6 px-2 py-1.5 transition-colors hover:bg-muted-bg/40\"\n >\n <Checkbox\n id={checkboxId}\n checked={state === \"indeterminate\" ? \"indeterminate\" : state === \"checked\"}\n onCheckedChange={() => onToggleSelect(node)}\n />\n <span className={cn(\"text-sm\", depth === 0 && \"font-medium\")}>{node.label}</span>\n </label>\n </div>\n {hasChildren && isExpanded && (\n <div role=\"group\">\n {node.children?.map((child) => (\n <TreeNode\n key={child.id}\n node={child}\n depth={depth + 1}\n selected={selected}\n expanded={expanded}\n onToggleSelect={onToggleSelect}\n onToggleExpand={onToggleExpand}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nexport { CheckboxTree };\n"],"mappings":"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"}
|