@tollerud/ui 1.1.5 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +36 -13
- package/CHANGELOG.md +411 -0
- package/COMPONENTS.md +951 -0
- package/GETTING_STARTED.md +159 -0
- package/README.md +51 -43
- package/SKILL.md +59 -24
- package/components.json +18 -0
- package/dist/accordion.d.ts +20 -0
- package/dist/accordion.js +5 -0
- package/dist/accordion.js.map +1 -0
- package/dist/action-diff.d.ts +26 -0
- package/dist/action-diff.js +5 -0
- package/dist/action-diff.js.map +1 -0
- package/dist/action-row.d.ts +36 -0
- package/dist/action-row.js +6 -0
- package/dist/action-row.js.map +1 -0
- package/dist/alert-inbox.d.ts +23 -0
- package/dist/alert-inbox.js +6 -0
- package/dist/alert-inbox.js.map +1 -0
- package/dist/alert.d.ts +33 -0
- package/dist/alert.js +5 -0
- package/dist/alert.js.map +1 -0
- package/dist/approval-card.d.ts +27 -0
- package/dist/approval-card.js +5 -0
- package/dist/approval-card.js.map +1 -0
- package/dist/area-chart.d.ts +10 -0
- package/dist/area-chart.js +5 -0
- package/dist/area-chart.js.map +1 -0
- package/dist/avatar.d.ts +28 -0
- package/dist/avatar.js +5 -0
- package/dist/avatar.js.map +1 -0
- package/dist/backup-status-panel.d.ts +25 -0
- package/dist/backup-status-panel.js +6 -0
- package/dist/backup-status-panel.js.map +1 -0
- package/dist/badge.d.ts +17 -0
- package/dist/badge.js +5 -0
- package/dist/badge.js.map +1 -0
- package/dist/bar-chart.d.ts +15 -0
- package/dist/bar-chart.js +5 -0
- package/dist/bar-chart.js.map +1 -0
- package/dist/bento-dashboard.d.ts +30 -0
- package/dist/bento-dashboard.js +10 -0
- package/dist/bento-dashboard.js.map +1 -0
- package/dist/breadcrumb.d.ts +16 -0
- package/dist/breadcrumb.js +5 -0
- package/dist/breadcrumb.js.map +1 -0
- package/dist/button.d.ts +29 -0
- package/dist/button.js +5 -0
- package/dist/button.js.map +1 -0
- package/dist/card.d.ts +10 -0
- package/dist/card.js +5 -0
- package/dist/card.js.map +1 -0
- package/dist/checkbox.d.ts +9 -0
- package/dist/checkbox.js +5 -0
- package/dist/checkbox.js.map +1 -0
- package/dist/chunk-2QWKOCWF.js +79 -0
- package/dist/chunk-2QWKOCWF.js.map +1 -0
- package/dist/chunk-3LTW224O.js +53 -0
- package/dist/chunk-3LTW224O.js.map +1 -0
- package/dist/chunk-3XTZPDNV.js +94 -0
- package/dist/chunk-3XTZPDNV.js.map +1 -0
- package/dist/chunk-435JHF7G.js +65 -0
- package/dist/chunk-435JHF7G.js.map +1 -0
- package/dist/chunk-4PA2ACNF.js +52 -0
- package/dist/chunk-4PA2ACNF.js.map +1 -0
- package/dist/chunk-5GWHUJ5D.js +29 -0
- package/dist/chunk-5GWHUJ5D.js.map +1 -0
- package/dist/chunk-6FUKJD3W.js +123 -0
- package/dist/chunk-6FUKJD3W.js.map +1 -0
- package/dist/chunk-6IS2AYYG.js +106 -0
- package/dist/chunk-6IS2AYYG.js.map +1 -0
- package/dist/chunk-6PZKU6ZL.js +78 -0
- package/dist/chunk-6PZKU6ZL.js.map +1 -0
- package/dist/chunk-6SKTH45H.js +75 -0
- package/dist/chunk-6SKTH45H.js.map +1 -0
- package/dist/chunk-6UXW5YUC.js +77 -0
- package/dist/chunk-6UXW5YUC.js.map +1 -0
- package/dist/chunk-7EP2T3OW.js +52 -0
- package/dist/chunk-7EP2T3OW.js.map +1 -0
- package/dist/chunk-7J5QXUQN.js +38 -0
- package/dist/chunk-7J5QXUQN.js.map +1 -0
- package/dist/chunk-A6L5C3IJ.js +47 -0
- package/dist/chunk-A6L5C3IJ.js.map +1 -0
- package/dist/chunk-ADE22JSR.js +54 -0
- package/dist/chunk-ADE22JSR.js.map +1 -0
- package/dist/chunk-ANW6J6PV.js +42 -0
- package/dist/chunk-ANW6J6PV.js.map +1 -0
- package/dist/chunk-APFFKNPS.js +80 -0
- package/dist/chunk-APFFKNPS.js.map +1 -0
- package/dist/chunk-AQT3FZRQ.js +23 -0
- package/dist/chunk-AQT3FZRQ.js.map +1 -0
- package/dist/chunk-AZADSX4Z.js +85 -0
- package/dist/chunk-AZADSX4Z.js.map +1 -0
- package/dist/chunk-BPCH5LJ3.js +36 -0
- package/dist/chunk-BPCH5LJ3.js.map +1 -0
- package/dist/chunk-CDI7353B.js +40 -0
- package/dist/chunk-CDI7353B.js.map +1 -0
- package/dist/chunk-CKNWXYMA.js +53 -0
- package/dist/chunk-CKNWXYMA.js.map +1 -0
- package/dist/chunk-DNJI65VQ.js +22 -0
- package/dist/chunk-DNJI65VQ.js.map +1 -0
- package/dist/chunk-DOUDJU4P.js +63 -0
- package/dist/chunk-DOUDJU4P.js.map +1 -0
- package/dist/chunk-DRCMGIQ6.js +64 -0
- package/dist/chunk-DRCMGIQ6.js.map +1 -0
- package/dist/chunk-DZOBXK2S.js +28 -0
- package/dist/chunk-DZOBXK2S.js.map +1 -0
- package/dist/chunk-EN4OJCEF.js +54 -0
- package/dist/chunk-EN4OJCEF.js.map +1 -0
- package/dist/chunk-EVHZFYWX.js +33 -0
- package/dist/chunk-EVHZFYWX.js.map +1 -0
- package/dist/chunk-G2VKWNZA.js +53 -0
- package/dist/chunk-G2VKWNZA.js.map +1 -0
- package/dist/chunk-GTM2DE4C.js +156 -0
- package/dist/chunk-GTM2DE4C.js.map +1 -0
- package/dist/chunk-H3ZVGTJM.js +165 -0
- package/dist/chunk-H3ZVGTJM.js.map +1 -0
- package/dist/chunk-HWAWUEHC.js +28 -0
- package/dist/chunk-HWAWUEHC.js.map +1 -0
- package/dist/chunk-HWJVRTWO.js +36 -0
- package/dist/chunk-HWJVRTWO.js.map +1 -0
- package/dist/chunk-ILADNTUB.js +77 -0
- package/dist/chunk-ILADNTUB.js.map +1 -0
- package/dist/chunk-IUPVQWO5.js +31 -0
- package/dist/chunk-IUPVQWO5.js.map +1 -0
- package/dist/chunk-JFOW2DI5.js +43 -0
- package/dist/chunk-JFOW2DI5.js.map +1 -0
- package/dist/chunk-JRFSUVSO.js +66 -0
- package/dist/chunk-JRFSUVSO.js.map +1 -0
- package/dist/chunk-KI6OTVID.js +91 -0
- package/dist/chunk-KI6OTVID.js.map +1 -0
- package/dist/chunk-LUM2YJBH.js +73 -0
- package/dist/chunk-LUM2YJBH.js.map +1 -0
- package/dist/chunk-NHPISZWS.js +71 -0
- package/dist/chunk-NHPISZWS.js.map +1 -0
- package/dist/chunk-NOLWJJHT.js +52 -0
- package/dist/chunk-NOLWJJHT.js.map +1 -0
- package/dist/chunk-NPVINX3Q.js +20 -0
- package/dist/chunk-NPVINX3Q.js.map +1 -0
- package/dist/chunk-NSMU66ZX.js +47 -0
- package/dist/chunk-NSMU66ZX.js.map +1 -0
- package/dist/chunk-O5SWPHUQ.js +79 -0
- package/dist/chunk-O5SWPHUQ.js.map +1 -0
- package/dist/chunk-OGVSZ7NV.js +53 -0
- package/dist/chunk-OGVSZ7NV.js.map +1 -0
- package/dist/chunk-OLHMMFQ7.js +43 -0
- package/dist/chunk-OLHMMFQ7.js.map +1 -0
- package/dist/chunk-ONMTHBZ4.js +54 -0
- package/dist/chunk-ONMTHBZ4.js.map +1 -0
- package/dist/chunk-OVSIOZHJ.js +56 -0
- package/dist/chunk-OVSIOZHJ.js.map +1 -0
- package/dist/chunk-Q54CVE3W.js +154 -0
- package/dist/chunk-Q54CVE3W.js.map +1 -0
- package/dist/chunk-QEHTPQHL.js +35 -0
- package/dist/chunk-QEHTPQHL.js.map +1 -0
- package/dist/chunk-QEIEWGHA.js +62 -0
- package/dist/chunk-QEIEWGHA.js.map +1 -0
- package/dist/chunk-QQHBEACI.js +88 -0
- package/dist/chunk-QQHBEACI.js.map +1 -0
- package/dist/chunk-RJTDQOT2.js +73 -0
- package/dist/chunk-RJTDQOT2.js.map +1 -0
- package/dist/chunk-RQ3RXKAZ.js +203 -0
- package/dist/chunk-RQ3RXKAZ.js.map +1 -0
- package/dist/chunk-RZK2S2OO.js +126 -0
- package/dist/chunk-RZK2S2OO.js.map +1 -0
- package/dist/chunk-SAP7JSSO.js +106 -0
- package/dist/chunk-SAP7JSSO.js.map +1 -0
- package/dist/chunk-T3TQPOVM.js +79 -0
- package/dist/chunk-T3TQPOVM.js.map +1 -0
- package/dist/chunk-T3UQ7G4T.js +58 -0
- package/dist/chunk-T3UQ7G4T.js.map +1 -0
- package/dist/chunk-T56TTOI6.js +53 -0
- package/dist/chunk-T56TTOI6.js.map +1 -0
- package/dist/chunk-T7EFDE2L.js +36 -0
- package/dist/chunk-T7EFDE2L.js.map +1 -0
- package/dist/chunk-VFS3V3VY.js +91 -0
- package/dist/chunk-VFS3V3VY.js.map +1 -0
- package/dist/chunk-VOARBYVQ.js +44 -0
- package/dist/chunk-VOARBYVQ.js.map +1 -0
- package/dist/chunk-WDANALHD.js +95 -0
- package/dist/chunk-WDANALHD.js.map +1 -0
- package/dist/chunk-WSQNPRGN.js +12 -0
- package/dist/chunk-WSQNPRGN.js.map +1 -0
- package/dist/chunk-YPP7QHYT.js +393 -0
- package/dist/chunk-YPP7QHYT.js.map +1 -0
- package/dist/chunk-YTU7BRDW.js +72 -0
- package/dist/chunk-YTU7BRDW.js.map +1 -0
- package/dist/chunk-YYWODLER.js +111 -0
- package/dist/chunk-YYWODLER.js.map +1 -0
- package/dist/chunk-ZOXO3G3I.js +50 -0
- package/dist/chunk-ZOXO3G3I.js.map +1 -0
- package/dist/chunk-ZTFOR3AN.js +79 -0
- package/dist/chunk-ZTFOR3AN.js.map +1 -0
- package/dist/code-block.d.ts +14 -0
- package/dist/code-block.js +5 -0
- package/dist/code-block.js.map +1 -0
- package/dist/combobox.d.ts +26 -0
- package/dist/combobox.js +5 -0
- package/dist/combobox.js.map +1 -0
- package/dist/command-menu.d.ts +52 -0
- package/dist/command-menu.js +7 -0
- package/dist/command-menu.js.map +1 -0
- package/dist/container.d.ts +9 -0
- package/dist/container.js +5 -0
- package/dist/container.js.map +1 -0
- package/dist/cta-band.d.ts +12 -0
- package/dist/cta-band.js +5 -0
- package/dist/cta-band.js.map +1 -0
- package/dist/data-table.d.ts +58 -0
- package/dist/data-table.js +12 -0
- package/dist/data-table.js.map +1 -0
- package/dist/date-picker.d.ts +20 -0
- package/dist/date-picker.js +5 -0
- package/dist/date-picker.js.map +1 -0
- package/dist/dialog.d.ts +21 -0
- package/dist/dialog.js +5 -0
- package/dist/dialog.js.map +1 -0
- package/dist/divider.d.ts +12 -0
- package/dist/divider.js +5 -0
- package/dist/divider.js.map +1 -0
- package/dist/docker-stack-card.d.ts +21 -0
- package/dist/docker-stack-card.js +6 -0
- package/dist/docker-stack-card.js.map +1 -0
- package/dist/donut.d.ts +15 -0
- package/dist/donut.js +5 -0
- package/dist/donut.js.map +1 -0
- package/dist/dropdown-menu.d.ts +15 -0
- package/dist/dropdown-menu.js +5 -0
- package/dist/dropdown-menu.js.map +1 -0
- package/dist/empty.d.ts +12 -0
- package/dist/empty.js +5 -0
- package/dist/empty.js.map +1 -0
- package/dist/feature-card.d.ts +11 -0
- package/dist/feature-card.js +6 -0
- package/dist/feature-card.js.map +1 -0
- package/dist/file-upload.d.ts +20 -0
- package/dist/file-upload.js +5 -0
- package/dist/file-upload.js.map +1 -0
- package/dist/footer.d.ts +35 -0
- package/dist/footer.js +6 -0
- package/dist/footer.js.map +1 -0
- package/dist/form-row.d.ts +19 -0
- package/dist/form-row.js +5 -0
- package/dist/form-row.js.map +1 -0
- package/dist/glow-card.d.ts +14 -0
- package/dist/glow-card.js +5 -0
- package/dist/glow-card.js.map +1 -0
- package/dist/hero-block.d.ts +16 -0
- package/dist/hero-block.js +7 -0
- package/dist/hero-block.js.map +1 -0
- package/dist/host-card.d.ts +27 -0
- package/dist/host-card.js +6 -0
- package/dist/host-card.js.map +1 -0
- package/dist/incident-card.d.ts +23 -0
- package/dist/incident-card.js +5 -0
- package/dist/incident-card.js.map +1 -0
- package/dist/index.d.ts +77 -960
- package/dist/index.js +69 -3812
- package/dist/index.js.map +1 -1
- package/dist/input.d.ts +10 -0
- package/dist/input.js +5 -0
- package/dist/input.js.map +1 -0
- package/dist/kbd.d.ts +24 -0
- package/dist/kbd.js +5 -0
- package/dist/kbd.js.map +1 -0
- package/dist/log-viewer.d.ts +35 -0
- package/dist/log-viewer.js +5 -0
- package/dist/log-viewer.js.map +1 -0
- package/dist/meter.d.ts +23 -0
- package/dist/meter.js +5 -0
- package/dist/meter.js.map +1 -0
- package/dist/monogram.d.ts +20 -0
- package/dist/monogram.js +5 -0
- package/dist/monogram.js.map +1 -0
- package/dist/noir-glow-background.d.ts +56 -0
- package/dist/noir-glow-background.js +4 -0
- package/dist/noir-glow-background.js.map +1 -0
- package/dist/pagination.d.ts +16 -0
- package/dist/pagination.js +5 -0
- package/dist/pagination.js.map +1 -0
- package/dist/panel.d.ts +12 -0
- package/dist/panel.js +5 -0
- package/dist/panel.js.map +1 -0
- package/dist/password-input.d.ts +10 -0
- package/dist/password-input.js +5 -0
- package/dist/password-input.js.map +1 -0
- package/dist/pill.d.ts +17 -0
- package/dist/pill.js +5 -0
- package/dist/pill.js.map +1 -0
- package/dist/pricing-card.d.ts +20 -0
- package/dist/pricing-card.js +6 -0
- package/dist/pricing-card.js.map +1 -0
- package/dist/progress.d.ts +6 -0
- package/dist/progress.js +5 -0
- package/dist/progress.js.map +1 -0
- package/dist/radio-group.d.ts +18 -0
- package/dist/radio-group.js +5 -0
- package/dist/radio-group.js.map +1 -0
- package/dist/rollback-plan.d.ts +23 -0
- package/dist/rollback-plan.js +5 -0
- package/dist/rollback-plan.js.map +1 -0
- package/dist/segmented.d.ts +17 -0
- package/dist/segmented.js +5 -0
- package/dist/segmented.js.map +1 -0
- package/dist/select.d.ts +18 -0
- package/dist/select.js +5 -0
- package/dist/select.js.map +1 -0
- package/dist/service-health-card.d.ts +21 -0
- package/dist/service-health-card.js +6 -0
- package/dist/service-health-card.js.map +1 -0
- package/dist/sheet.d.ts +25 -0
- package/dist/sheet.js +5 -0
- package/dist/sheet.js.map +1 -0
- package/dist/skeleton.d.ts +13 -0
- package/dist/skeleton.js +5 -0
- package/dist/skeleton.js.map +1 -0
- package/dist/slider.d.ts +12 -0
- package/dist/slider.js +5 -0
- package/dist/slider.js.map +1 -0
- package/dist/sparkline.d.ts +16 -0
- package/dist/sparkline.js +5 -0
- package/dist/sparkline.js.map +1 -0
- package/dist/stat-card.d.ts +15 -0
- package/dist/stat-card.js +5 -0
- package/dist/stat-card.js.map +1 -0
- package/dist/status-dot.d.ts +13 -0
- package/dist/status-dot.js +5 -0
- package/dist/status-dot.js.map +1 -0
- package/dist/stepper.d.ts +16 -0
- package/dist/stepper.js +5 -0
- package/dist/stepper.js.map +1 -0
- package/dist/switch.d.ts +9 -0
- package/dist/switch.js +5 -0
- package/dist/switch.js.map +1 -0
- package/dist/tabs.d.ts +9 -0
- package/dist/tabs.js +5 -0
- package/dist/tabs.js.map +1 -0
- package/dist/tag-input.d.ts +20 -0
- package/dist/tag-input.js +5 -0
- package/dist/tag-input.js.map +1 -0
- package/dist/textarea.d.ts +10 -0
- package/dist/textarea.js +5 -0
- package/dist/textarea.js.map +1 -0
- package/dist/timeline.d.ts +30 -0
- package/dist/timeline.js +5 -0
- package/dist/timeline.js.map +1 -0
- package/dist/toaster.d.ts +10 -0
- package/dist/toaster.js +4 -0
- package/dist/toaster.js.map +1 -0
- package/dist/tooltip.d.ts +12 -0
- package/dist/tooltip.js +5 -0
- package/dist/tooltip.js.map +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.js +4 -0
- package/dist/utils.js.map +1 -0
- package/globals-layers.css +1019 -0
- package/globals-v3.css +17 -0
- package/globals-v4.css +2 -0
- package/globals.css +12 -939
- package/package.json +85 -17
- package/registry.json +936 -0
- package/tailwind.css +9 -0
- package/tokens.css +20 -0
- package/tollerud-avatar-full.png +0 -0
- package/dist/index.cjs +0 -3938
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -960
- /package/{tia-full-figure.svg → tollerud-avatar-full.svg} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/Donut.tsx"],"names":[],"mappings":";;;;AAcA,IAAM,KAAA,GAAQ,UAAA;AAAA,EACZ,CAAC,EAAE,SAAA,EAAW,QAAA,EAAU,OAAO,GAAA,EAAK,GAAG,KAAA,EAAM,EAAG,GAAA,KAAQ;AACtD,IAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA,EAAG,MAAM,CAAA,GAAI,CAAA,CAAE,KAAA,EAAO,CAAC,CAAA,IAAK,CAAA;AAC3D,IAAA,MAAM,CAAA,GAAI,OAAO,CAAA,GAAI,EAAA;AACrB,IAAA,MAAM,CAAA,GAAI,CAAA,GAAI,IAAA,CAAK,EAAA,GAAK,CAAA;AACxB,IAAA,IAAI,MAAA,GAAS,CAAA;AAEb,IAAA,uBACE,IAAA,CAAC,SAAI,GAAA,EAAU,SAAA,EAAW,GAAG,yBAAA,EAA2B,SAAS,CAAA,EAAI,GAAG,KAAA,EACtE,QAAA,EAAA;AAAA,sBAAA,IAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,IAAA;AAAA,UACP,MAAA,EAAQ,IAAA;AAAA,UACR,OAAA,EAAS,CAAA,IAAA,EAAO,IAAI,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA;AAAA,UAC5B,SAAA,EAAU,YAAA;AAAA,UACV,IAAA,EAAK,KAAA;AAAA,UACL,aAAA,EAAY,MAAA;AAAA,UAEZ,QAAA,EAAA;AAAA,4BAAA,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBACC,IAAI,IAAA,GAAO,CAAA;AAAA,gBACX,IAAI,IAAA,GAAO,CAAA;AAAA,gBACX,CAAA;AAAA,gBACA,IAAA,EAAK,MAAA;AAAA,gBACL,MAAA,EAAO,cAAA;AAAA,gBACP,WAAA,EAAY;AAAA;AAAA,aACd;AAAA,YACC,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,KAAM;AACtB,cAAA,MAAM,GAAA,GAAO,CAAA,CAAE,KAAA,GAAQ,KAAA,GAAS,CAAA;AAChC,cAAA,MAAM,GAAA,GAAM,GAAA,GAAM,EAAA,GAAK,CAAA,GAAI,CAAA;AAC3B,cAAA,MAAM,EAAA,mBACJ,GAAA;AAAA,gBAAC,QAAA;AAAA,gBAAA;AAAA,kBAEC,IAAI,IAAA,GAAO,CAAA;AAAA,kBACX,IAAI,IAAA,GAAO,CAAA;AAAA,kBACX,CAAA;AAAA,kBACA,IAAA,EAAK,MAAA;AAAA,kBACL,QAAQ,CAAA,CAAE,KAAA;AAAA,kBACV,WAAA,EAAY,IAAA;AAAA,kBACZ,eAAA,EAAiB,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,GAAA,EAAK,GAAA,GAAM,GAAG,CAAC,CAAA,CAAA,EAAI,CAAA,IAAK,GAAA,GAAM,GAAA,CAAI,CAAA,CAAA;AAAA,kBAC/D,kBAAkB,CAAC,MAAA;AAAA,kBACnB,aAAA,EAAc;AAAA,iBAAA;AAAA,gBATT;AAAA,eAUP;AAEF,cAAA,MAAA,IAAU,GAAA;AACV,cAAA,OAAO,EAAA;AAAA,YACT,CAAC;AAAA;AAAA;AAAA,OACH;AAAA,sBACA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,qBAAA,EACZ,QAAA,EAAA,QAAA,CAAS,GAAA,CAAI,CAAC,CAAA,EAAG,CAAA,qBAChB,IAAA,CAAC,KAAA,EAAA,EAAY,SAAA,EAAU,qCAAA,EACrB,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,MAAA;AAAA,UAAA;AAAA,YACC,SAAA,EAAU,oCAAA;AAAA,YACV,KAAA,EAAO,EAAE,UAAA,EAAY,CAAA,CAAE,KAAA;AAAM;AAAA,SAC/B;AAAA,wBACA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,yCAAA,EAA2C,YAAE,KAAA,EAAM,CAAA;AAAA,wBACnE,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,oCAAA,EACb,QAAA,EAAA;AAAA,UAAA,IAAA,CAAK,KAAA,CAAO,CAAA,CAAE,KAAA,GAAQ,KAAA,GAAS,GAAG,CAAA;AAAA,UAAE;AAAA,SAAA,EACvC;AAAA,OAAA,EAAA,EARQ,CASV,CACD,CAAA,EACH;AAAA,KAAA,EACF,CAAA;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-O5SWPHUQ.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface DonutSegment {\n label: string\n value: number\n color: string\n}\n\nexport interface DonutProps extends HTMLAttributes<HTMLDivElement> {\n segments: DonutSegment[]\n size?: number\n}\n\nconst Donut = forwardRef<HTMLDivElement, DonutProps>(\n ({ className, segments, size = 160, ...props }, ref) => {\n const total = segments.reduce((a, s) => a + s.value, 0) || 1\n const r = size / 2 - 14\n const c = 2 * Math.PI * r\n let offset = 0\n\n return (\n <div ref={ref} className={cn('flex items-center gap-6', className)} {...props}>\n <svg\n width={size}\n height={size}\n viewBox={`0 0 ${size} ${size}`}\n className=\"-rotate-90\"\n role=\"img\"\n aria-hidden=\"true\"\n >\n <circle\n cx={size / 2}\n cy={size / 2}\n r={r}\n fill=\"none\"\n stroke=\"var(--muted)\"\n strokeWidth=\"14\"\n />\n {segments.map((s, i) => {\n const len = (s.value / total) * c\n const gap = len > 10 ? 4 : 0\n const el = (\n <circle\n key={i}\n cx={size / 2}\n cy={size / 2}\n r={r}\n fill=\"none\"\n stroke={s.color}\n strokeWidth=\"14\"\n strokeDasharray={`${Math.max(0.1, len - gap)} ${c - (len - gap)}`}\n strokeDashoffset={-offset}\n strokeLinecap=\"butt\"\n />\n )\n offset += len\n return el\n })}\n </svg>\n <div className=\"flex flex-col gap-2\">\n {segments.map((s, i) => (\n <div key={i} className=\"flex items-center gap-2 text-[13px]\">\n <span\n className=\"h-2.5 w-2.5 shrink-0 rounded-[3px]\"\n style={{ background: s.color }}\n />\n <span className=\"min-w-[70px] text-tollerud-text-primary\">{s.label}</span>\n <span className=\"font-mono text-tollerud-text-muted\">\n {Math.round((s.value / total) * 100)}%\n </span>\n </div>\n ))}\n </div>\n </div>\n )\n }\n)\nDonut.displayName = 'Donut'\n\nexport { Donut }\n"]}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { Kbd } from './chunk-HWAWUEHC.js';
|
|
3
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
4
|
+
import { forwardRef } from 'react';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
var ActionRow = forwardRef(
|
|
8
|
+
({
|
|
9
|
+
action,
|
|
10
|
+
highlighted = false,
|
|
11
|
+
showShortcut = true,
|
|
12
|
+
className,
|
|
13
|
+
disabled,
|
|
14
|
+
onClick,
|
|
15
|
+
...props
|
|
16
|
+
}, ref) => {
|
|
17
|
+
return /* @__PURE__ */ jsxs(
|
|
18
|
+
"button",
|
|
19
|
+
{
|
|
20
|
+
ref,
|
|
21
|
+
type: "button",
|
|
22
|
+
disabled: disabled ?? action.disabled,
|
|
23
|
+
onClick: (e) => {
|
|
24
|
+
onClick?.(e);
|
|
25
|
+
action.onSelect?.();
|
|
26
|
+
},
|
|
27
|
+
className: cn(
|
|
28
|
+
"tollerud-action-row",
|
|
29
|
+
highlighted && "tollerud-action-row--highlighted",
|
|
30
|
+
(disabled ?? action.disabled) && "tollerud-action-row--disabled",
|
|
31
|
+
className
|
|
32
|
+
),
|
|
33
|
+
role: "option",
|
|
34
|
+
"aria-selected": highlighted,
|
|
35
|
+
"aria-disabled": disabled ?? action.disabled,
|
|
36
|
+
...props,
|
|
37
|
+
children: [
|
|
38
|
+
action.icon && /* @__PURE__ */ jsx("span", { className: "tollerud-action-row__icon", children: action.icon }),
|
|
39
|
+
/* @__PURE__ */ jsxs("span", { className: "tollerud-action-row__content", children: [
|
|
40
|
+
/* @__PURE__ */ jsx("span", { className: "tollerud-action-row__label", children: action.label }),
|
|
41
|
+
action.description && /* @__PURE__ */ jsx("span", { className: "tollerud-action-row__description", children: action.description })
|
|
42
|
+
] }),
|
|
43
|
+
showShortcut && action.shortcut && /* @__PURE__ */ jsx("span", { className: "tollerud-action-row__shortcut", children: /* @__PURE__ */ jsx(Kbd, { keys: action.shortcut, size: "sm" }) })
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
ActionRow.displayName = "ActionRow";
|
|
50
|
+
|
|
51
|
+
export { ActionRow };
|
|
52
|
+
//# sourceMappingURL=chunk-OGVSZ7NV.js.map
|
|
53
|
+
//# sourceMappingURL=chunk-OGVSZ7NV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/ActionRow.tsx"],"names":[],"mappings":";;;;;AAuCA,IAAM,SAAA,GAAY,UAAA;AAAA,EAChB,CACE;AAAA,IACE,MAAA;AAAA,IACA,WAAA,GAAc,KAAA;AAAA,IACd,YAAA,GAAe,IAAA;AAAA,IACf,SAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,uBACE,IAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,QAAA,EAAU,YAAY,MAAA,CAAO,QAAA;AAAA,QAC7B,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,UAAA,OAAA,GAAU,CAAC,CAAA;AACX,UAAA,MAAA,CAAO,QAAA,IAAW;AAAA,QACpB,CAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,qBAAA;AAAA,UACA,WAAA,IAAe,kCAAA;AAAA,UAAA,CACd,QAAA,IAAY,OAAO,QAAA,KAAa,+BAAA;AAAA,UACjC;AAAA,SACF;AAAA,QACA,IAAA,EAAK,QAAA;AAAA,QACL,eAAA,EAAe,WAAA;AAAA,QACf,eAAA,EAAe,YAAY,MAAA,CAAO,QAAA;AAAA,QACjC,GAAG,KAAA;AAAA,QAEH,QAAA,EAAA;AAAA,UAAA,MAAA,CAAO,wBACN,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,2BAAA,EAA6B,iBAAO,IAAA,EAAK,CAAA;AAAA,0BAG3D,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EACd,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,4BAAA,EAA8B,QAAA,EAAA,MAAA,CAAO,KAAA,EAAM,CAAA;AAAA,YAC1D,OAAO,WAAA,oBACN,GAAA,CAAC,UAAK,SAAA,EAAU,kCAAA,EACb,iBAAO,WAAA,EACV;AAAA,WAAA,EAEJ,CAAA;AAAA,UAEC,YAAA,IAAgB,MAAA,CAAO,QAAA,oBACtB,GAAA,CAAC,UAAK,SAAA,EAAU,+BAAA,EACd,QAAA,kBAAA,GAAA,CAAC,GAAA,EAAA,EAAI,IAAA,EAAM,MAAA,CAAO,QAAA,EAAU,IAAA,EAAK,MAAK,CAAA,EACxC;AAAA;AAAA;AAAA,KAEJ;AAAA,EAEJ;AACF;AACA,SAAA,CAAU,WAAA,GAAc,WAAA","file":"chunk-OGVSZ7NV.js","sourcesContent":["\"use client\"\n\nimport { type ButtonHTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\nimport { Kbd } from './Kbd'\n\nexport interface ActionItem {\n /** Unique ID */\n id: string\n /** Label text */\n label: string\n /** Subtitle / description */\n description?: string\n /** Optional icon element */\n icon?: React.ReactNode\n /** Keyboard shortcut */\n shortcut?: string | string[]\n /** Group this item belongs to */\n group?: string\n /** When true, item is disabled */\n disabled?: boolean\n /** Selection callback */\n onSelect?: () => void\n}\n\nexport interface ActionRowProps\n extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'onSelect'> {\n /** Action data */\n action: ActionItem\n /** Whether this row is currently highlighted (keyboard navigation) */\n highlighted?: boolean\n /** Whether to show the shortcut */\n showShortcut?: boolean\n}\n\n/**\n * Action row — a single command/action item in a list or command menu.\n * Inspired by Raycast's compact action layout.\n */\nconst ActionRow = forwardRef<HTMLButtonElement, ActionRowProps>(\n (\n {\n action,\n highlighted = false,\n showShortcut = true,\n className,\n disabled,\n onClick,\n ...props\n },\n ref\n ) => {\n return (\n <button\n ref={ref}\n type=\"button\"\n disabled={disabled ?? action.disabled}\n onClick={(e) => {\n onClick?.(e)\n action.onSelect?.()\n }}\n className={cn(\n 'tollerud-action-row',\n highlighted && 'tollerud-action-row--highlighted',\n (disabled ?? action.disabled) && 'tollerud-action-row--disabled',\n className\n )}\n role=\"option\"\n aria-selected={highlighted}\n aria-disabled={disabled ?? action.disabled}\n {...props}\n >\n {action.icon && (\n <span className=\"tollerud-action-row__icon\">{action.icon}</span>\n )}\n\n <span className=\"tollerud-action-row__content\">\n <span className=\"tollerud-action-row__label\">{action.label}</span>\n {action.description && (\n <span className=\"tollerud-action-row__description\">\n {action.description}\n </span>\n )}\n </span>\n\n {showShortcut && action.shortcut && (\n <span className=\"tollerud-action-row__shortcut\">\n <Kbd keys={action.shortcut} size=\"sm\" />\n </span>\n )}\n </button>\n )\n }\n)\nActionRow.displayName = 'ActionRow'\n\nexport { ActionRow }"]}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
3
|
+
import { forwardRef, useId } from 'react';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var Slider = forwardRef(
|
|
7
|
+
({ className, label, showValue, id: idProp, value, defaultValue, min = 0, max = 100, onChange, ...props }, ref) => {
|
|
8
|
+
const autoId = useId();
|
|
9
|
+
const id = idProp ?? autoId;
|
|
10
|
+
const current = value ?? defaultValue ?? min;
|
|
11
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
12
|
+
(label || showValue) && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between text-xs", children: [
|
|
13
|
+
label && /* @__PURE__ */ jsx("label", { htmlFor: id, className: "font-medium text-tollerud-text-muted", children: label }),
|
|
14
|
+
showValue && /* @__PURE__ */ jsx("span", { className: "text-tollerud-text-secondary tabular-nums", children: current })
|
|
15
|
+
] }),
|
|
16
|
+
/* @__PURE__ */ jsx(
|
|
17
|
+
"input",
|
|
18
|
+
{
|
|
19
|
+
ref,
|
|
20
|
+
id,
|
|
21
|
+
type: "range",
|
|
22
|
+
min,
|
|
23
|
+
max,
|
|
24
|
+
value,
|
|
25
|
+
defaultValue,
|
|
26
|
+
onChange: (e) => onChange?.(Number(e.target.value)),
|
|
27
|
+
className: cn(
|
|
28
|
+
"tollerud-slider cursor-pointer accent-tollerud-yellow",
|
|
29
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-tollerud-yellow/50",
|
|
30
|
+
"disabled:opacity-40 disabled:pointer-events-none",
|
|
31
|
+
className
|
|
32
|
+
),
|
|
33
|
+
...props
|
|
34
|
+
}
|
|
35
|
+
)
|
|
36
|
+
] });
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
Slider.displayName = "Slider";
|
|
40
|
+
|
|
41
|
+
export { Slider };
|
|
42
|
+
//# sourceMappingURL=chunk-OLHMMFQ7.js.map
|
|
43
|
+
//# sourceMappingURL=chunk-OLHMMFQ7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/Slider.tsx"],"names":[],"mappings":";;;;AAYA,IAAM,MAAA,GAAS,UAAA;AAAA,EACb,CAAC,EAAE,SAAA,EAAW,KAAA,EAAO,SAAA,EAAW,IAAI,MAAA,EAAQ,KAAA,EAAO,YAAA,EAAc,GAAA,GAAM,GAAG,GAAA,GAAM,GAAA,EAAK,UAAU,GAAG,KAAA,IAAS,GAAA,KAAQ;AACjH,IAAA,MAAM,SAAS,KAAA,EAAM;AACrB,IAAA,MAAM,KAAK,MAAA,IAAU,MAAA;AACrB,IAAA,MAAM,OAAA,GAAU,SAAS,YAAA,IAAgB,GAAA;AAEzC,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,uBAAA,EACX,QAAA,EAAA;AAAA,MAAA,CAAA,KAAA,IAAS,SAAA,qBACT,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2CAAA,EACZ,QAAA,EAAA;AAAA,QAAA,KAAA,wBACE,OAAA,EAAA,EAAM,OAAA,EAAS,EAAA,EAAI,SAAA,EAAU,wCAC3B,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,QAED,SAAA,oBAAa,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,6CAA6C,QAAA,EAAA,OAAA,EAAQ;AAAA,OAAA,EACrF,CAAA;AAAA,sBAEF,GAAA;AAAA,QAAC,OAAA;AAAA,QAAA;AAAA,UACC,GAAA;AAAA,UACA,EAAA;AAAA,UACA,IAAA,EAAK,OAAA;AAAA,UACL,GAAA;AAAA,UACA,GAAA;AAAA,UACA,KAAA;AAAA,UACA,YAAA;AAAA,UACA,QAAA,EAAU,CAAC,CAAA,KAAM,QAAA,GAAW,OAAO,CAAA,CAAE,MAAA,CAAO,KAAK,CAAC,CAAA;AAAA,UAClD,SAAA,EAAW,EAAA;AAAA,YACT,uDAAA;AAAA,YACA,uFAAA;AAAA,YACA,kDAAA;AAAA,YACA;AAAA,WACF;AAAA,UACC,GAAG;AAAA;AAAA;AACN,KAAA,EACF,CAAA;AAAA,EAEJ;AACF;AACA,MAAA,CAAO,WAAA,GAAc,QAAA","file":"chunk-OLHMMFQ7.js","sourcesContent":["'use client'\n\nimport { type InputHTMLAttributes, forwardRef, useId } from 'react'\nimport { cn } from '@/lib/utils'\n\nexport interface SliderProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type' | 'onChange'> {\n label?: string\n /** Show the current numeric value next to the label */\n showValue?: boolean\n onChange?: (value: number) => void\n}\n\nconst Slider = forwardRef<HTMLInputElement, SliderProps>(\n ({ className, label, showValue, id: idProp, value, defaultValue, min = 0, max = 100, onChange, ...props }, ref) => {\n const autoId = useId()\n const id = idProp ?? autoId\n const current = value ?? defaultValue ?? min\n\n return (\n <div className=\"flex flex-col gap-1.5\">\n {(label || showValue) && (\n <div className=\"flex items-center justify-between text-xs\">\n {label && (\n <label htmlFor={id} className=\"font-medium text-tollerud-text-muted\">\n {label}\n </label>\n )}\n {showValue && <span className=\"text-tollerud-text-secondary tabular-nums\">{current}</span>}\n </div>\n )}\n <input\n ref={ref}\n id={id}\n type=\"range\"\n min={min}\n max={max}\n value={value}\n defaultValue={defaultValue}\n onChange={(e) => onChange?.(Number(e.target.value))}\n className={cn(\n 'tollerud-slider cursor-pointer accent-tollerud-yellow',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-tollerud-yellow/50',\n 'disabled:opacity-40 disabled:pointer-events-none',\n className\n )}\n {...props}\n />\n </div>\n )\n }\n)\nSlider.displayName = 'Slider'\n\nexport { Slider }\n"]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { StatCard } from './chunk-LUM2YJBH.js';
|
|
3
|
+
import { ServiceHealthCard } from './chunk-7EP2T3OW.js';
|
|
4
|
+
import { HostCard } from './chunk-DOUDJU4P.js';
|
|
5
|
+
import { IncidentCard } from './chunk-EN4OJCEF.js';
|
|
6
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
7
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
function BentoDashboard({
|
|
10
|
+
title,
|
|
11
|
+
hosts = [],
|
|
12
|
+
metrics = [],
|
|
13
|
+
services = [],
|
|
14
|
+
incidents = [],
|
|
15
|
+
className
|
|
16
|
+
}) {
|
|
17
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), children: [
|
|
18
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxs("div", { children: [
|
|
19
|
+
/* @__PURE__ */ jsx("h2", { className: "text-lg font-semibold text-tollerud-text-primary", children: title }),
|
|
20
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs text-tollerud-text-muted", children: [
|
|
21
|
+
hosts.length,
|
|
22
|
+
" hosts \xB7 ",
|
|
23
|
+
services.length,
|
|
24
|
+
" services",
|
|
25
|
+
incidents.length > 0 && ` \xB7 ${incidents.length} active incident${incidents.length > 1 ? "s" : ""}`
|
|
26
|
+
] })
|
|
27
|
+
] }) }),
|
|
28
|
+
hosts.length > 0 && /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-3", children: [
|
|
29
|
+
/* @__PURE__ */ jsx("div", { className: "md:col-span-2 lg:col-span-1", children: /* @__PURE__ */ jsx(HostCard, { ...hosts[0] }) }),
|
|
30
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-3 md:col-span-2 lg:col-span-1", children: hosts.slice(1).map((h, i) => /* @__PURE__ */ jsx(HostCard, { ...h }, h.hostname ?? i)) })
|
|
31
|
+
] }),
|
|
32
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-3", children: [
|
|
33
|
+
metrics.length > 0 && /* @__PURE__ */ jsxs("div", { className: "lg:col-span-2", children: [
|
|
34
|
+
/* @__PURE__ */ jsx(SectionLabel, { children: "Metrics" }),
|
|
35
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 sm:grid-cols-4 gap-2", children: metrics.map((m, i) => /* @__PURE__ */ jsx(StatCard, { ...m }, m.label ?? i)) })
|
|
36
|
+
] }),
|
|
37
|
+
services.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
38
|
+
/* @__PURE__ */ jsx(SectionLabel, { children: "Services" }),
|
|
39
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-2", children: services.slice(0, 4).map((s, i) => /* @__PURE__ */ jsx(ServiceHealthCard, { ...s }, s.service ?? i)) })
|
|
40
|
+
] })
|
|
41
|
+
] }),
|
|
42
|
+
incidents.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
43
|
+
/* @__PURE__ */ jsx(SectionLabel, { children: "Recent Incidents" }),
|
|
44
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: incidents.slice(0, 4).map((inc, i) => /* @__PURE__ */ jsx(IncidentCard, { ...inc }, inc.title + i)) })
|
|
45
|
+
] })
|
|
46
|
+
] });
|
|
47
|
+
}
|
|
48
|
+
function SectionLabel({ children }) {
|
|
49
|
+
return /* @__PURE__ */ jsx("p", { className: "text-xs font-semibold text-tollerud-text-muted uppercase tracking-wider mb-2", children });
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { BentoDashboard };
|
|
53
|
+
//# sourceMappingURL=chunk-ONMTHBZ4.js.map
|
|
54
|
+
//# sourceMappingURL=chunk-ONMTHBZ4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/BentoDashboard.tsx"],"names":[],"mappings":"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","file":"chunk-ONMTHBZ4.js","sourcesContent":["'use client'\n\nimport { type ReactNode } from 'react'\nimport { cn } from '@/lib/utils'\nimport { HostCard, type HostCardProps } from './HostCard'\nimport { StatCard, type StatCardProps } from './StatCard'\nimport { ServiceHealthCard, type ServiceHealthCardProps } from './ServiceHealthCard'\nimport { IncidentCard } from './IncidentCard'\nimport type { IncidentSeverity } from './IncidentCard'\nimport type { BackupJob } from './BackupStatusPanel'\n\n/* ──────────────────── Bento Grid Dashboard Template ──────────────────── */\n\nexport interface BentoDashboardProps {\n title: string\n hosts?: HostCardProps[]\n metrics?: StatCardProps[]\n services?: ServiceHealthCardProps[]\n incidents?: { title: string; severity: IncidentSeverity; timestamp: string; service: string; description?: string; acknowledged?: boolean }[]\n backupJobs?: BackupJob[]\n className?: string\n /** Render the incident list footer */\n renderIncidentFooter?: () => ReactNode\n}\n\nexport function BentoDashboard({\n title,\n hosts = [],\n metrics = [],\n services = [],\n incidents = [],\n className,\n}: BentoDashboardProps) {\n return (\n <div className={cn('space-y-4', className)}>\n {/* Title bar */}\n <div className=\"flex items-center justify-between\">\n <div>\n <h2 className=\"text-lg font-semibold text-tollerud-text-primary\">{title}</h2>\n <p className=\"text-xs text-tollerud-text-muted\">\n {hosts.length} hosts · {services.length} services\n {incidents.length > 0 && ` · ${incidents.length} active incident${incidents.length > 1 ? 's' : ''}`}\n </p>\n </div>\n </div>\n\n {/* Row 1: Host cards — bento asymmetric */}\n {hosts.length > 0 && (\n <div className=\"grid grid-cols-1 md:grid-cols-2 gap-3\">\n <div className=\"md:col-span-2 lg:col-span-1\">\n <HostCard {...hosts[0]} />\n </div>\n <div className=\"grid grid-cols-1 gap-3 md:col-span-2 lg:col-span-1\">\n {hosts.slice(1).map((h, i) => (\n <HostCard key={h.hostname ?? i} {...h} />\n ))}\n </div>\n </div>\n )}\n\n {/* Row 2: Metrics + Services — side by side */}\n <div className=\"grid grid-cols-1 lg:grid-cols-3 gap-3\">\n {metrics.length > 0 && (\n <div className=\"lg:col-span-2\">\n <SectionLabel>Metrics</SectionLabel>\n <div className=\"grid grid-cols-2 sm:grid-cols-4 gap-2\">\n {metrics.map((m, i) => (\n <StatCard key={m.label ?? i} {...m} />\n ))}\n </div>\n </div>\n )}\n\n {services.length > 0 && (\n <div>\n <SectionLabel>Services</SectionLabel>\n <div className=\"space-y-2\">\n {services.slice(0, 4).map((s, i) => (\n <ServiceHealthCard key={s.service ?? i} {...s} />\n ))}\n </div>\n </div>\n )}\n </div>\n\n {/* Row 3: Incidents — full width */}\n {incidents.length > 0 && (\n <div>\n <SectionLabel>Recent Incidents</SectionLabel>\n <div className=\"space-y-1.5\">\n {incidents.slice(0, 4).map((inc, i) => (\n <IncidentCard key={inc.title + i} {...inc} />\n ))}\n </div>\n </div>\n )}\n </div>\n )\n}\n\nfunction SectionLabel({ children }: { children: ReactNode }) {\n return (\n <p className=\"text-xs font-semibold text-tollerud-text-muted uppercase tracking-wider mb-2\">{children}</p>\n )\n}\n\nexport default BentoDashboard\n"]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { Button } from './chunk-ADE22JSR.js';
|
|
3
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
4
|
+
import { forwardRef } from 'react';
|
|
5
|
+
import { Check } from 'lucide-react';
|
|
6
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
var PricingCard = forwardRef(
|
|
9
|
+
({
|
|
10
|
+
className,
|
|
11
|
+
name,
|
|
12
|
+
price,
|
|
13
|
+
period,
|
|
14
|
+
description,
|
|
15
|
+
features = [],
|
|
16
|
+
ctaLabel = "Get started",
|
|
17
|
+
onCtaClick,
|
|
18
|
+
featured,
|
|
19
|
+
badge,
|
|
20
|
+
...props
|
|
21
|
+
}, ref) => {
|
|
22
|
+
return /* @__PURE__ */ jsxs(
|
|
23
|
+
"div",
|
|
24
|
+
{
|
|
25
|
+
ref,
|
|
26
|
+
className: cn(
|
|
27
|
+
"flex flex-col gap-5 rounded-xl border p-6",
|
|
28
|
+
featured ? "border-tollerud-yellow bg-tollerud-yellow/[0.04] shadow-[0_0_0_1px_rgba(255,255,0,0.15)]" : "border-tollerud-border bg-tollerud-surface",
|
|
29
|
+
className
|
|
30
|
+
),
|
|
31
|
+
...props,
|
|
32
|
+
children: [
|
|
33
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
34
|
+
badge && /* @__PURE__ */ jsx("span", { className: "inline-flex w-fit items-center rounded-full bg-tollerud-yellow/15 px-2.5 py-0.5 text-xs font-medium text-tollerud-yellow", children: badge }),
|
|
35
|
+
/* @__PURE__ */ jsx("h3", { className: "text-base font-medium text-tollerud-text-primary", children: name }),
|
|
36
|
+
description && /* @__PURE__ */ jsx("p", { className: "text-sm text-tollerud-text-muted", children: description })
|
|
37
|
+
] }),
|
|
38
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline gap-1", children: [
|
|
39
|
+
/* @__PURE__ */ jsx("span", { className: "text-3xl font-semibold tracking-tight text-tollerud-text-primary", children: price }),
|
|
40
|
+
period && /* @__PURE__ */ jsx("span", { className: "text-sm text-tollerud-text-muted", children: period })
|
|
41
|
+
] }),
|
|
42
|
+
features.length > 0 && /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-2.5", children: features.map((feature, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2.5 text-sm text-tollerud-text-secondary", children: [
|
|
43
|
+
/* @__PURE__ */ jsx(Check, { size: 16, className: "mt-0.5 shrink-0 text-tollerud-yellow" }),
|
|
44
|
+
/* @__PURE__ */ jsx("span", { children: feature })
|
|
45
|
+
] }, i)) }),
|
|
46
|
+
/* @__PURE__ */ jsx(Button, { variant: featured ? "primary" : "secondary", onClick: onCtaClick, className: "mt-auto w-full", children: ctaLabel })
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
PricingCard.displayName = "PricingCard";
|
|
53
|
+
|
|
54
|
+
export { PricingCard };
|
|
55
|
+
//# sourceMappingURL=chunk-OVSIOZHJ.js.map
|
|
56
|
+
//# sourceMappingURL=chunk-OVSIOZHJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/PricingCard.tsx"],"names":[],"mappings":";;;;;;AAoBA,IAAM,WAAA,GAAc,UAAA;AAAA,EAClB,CACE;AAAA,IACE,SAAA;AAAA,IACA,IAAA;AAAA,IACA,KAAA;AAAA,IACA,MAAA;AAAA,IACA,WAAA;AAAA,IACA,WAAW,EAAC;AAAA,IACZ,QAAA,GAAW,aAAA;AAAA,IACX,UAAA;AAAA,IACA,QAAA;AAAA,IACA,KAAA;AAAA,IACA,GAAG;AAAA,KAEL,GAAA,KACG;AACH,IAAA,uBACE,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,2CAAA;AAAA,UACA,WACI,0FAAA,GACA,4CAAA;AAAA,UACJ;AAAA,SACF;AAAA,QACC,GAAG,KAAA;AAAA,QAEJ,QAAA,EAAA;AAAA,0BAAA,IAAA,CAAC,KAAA,EAAA,EAAI,WAAU,qBAAA,EACZ,QAAA,EAAA;AAAA,YAAA,KAAA,oBACC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,0HAAA,EACb,QAAA,EAAA,KAAA,EACH,CAAA;AAAA,4BAEF,GAAA,CAAC,IAAA,EAAA,EAAG,SAAA,EAAU,kDAAA,EAAoD,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,YACtE,WAAA,oBAAe,GAAA,CAAC,GAAA,EAAA,EAAE,SAAA,EAAU,oCAAoC,QAAA,EAAA,WAAA,EAAY;AAAA,WAAA,EAC/E,CAAA;AAAA,0BAEA,IAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,2BAAA,EACb,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,kEAAA,EAAoE,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,YACzF,MAAA,oBAAU,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,oCAAoC,QAAA,EAAA,MAAA,EAAO;AAAA,WAAA,EACxE,CAAA;AAAA,UAEC,QAAA,CAAS,MAAA,GAAS,CAAA,oBACjB,GAAA,CAAC,QAAG,SAAA,EAAU,uBAAA,EACX,QAAA,EAAA,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,EAAS,CAAA,qBACtB,IAAA,CAAC,IAAA,EAAA,EAAW,WAAU,+DAAA,EACpB,QAAA,EAAA;AAAA,4BAAA,GAAA,CAAC,KAAA,EAAA,EAAM,IAAA,EAAM,EAAA,EAAI,SAAA,EAAU,sCAAA,EAAuC,CAAA;AAAA,4BAClE,GAAA,CAAC,UAAM,QAAA,EAAA,OAAA,EAAQ;AAAA,WAAA,EAAA,EAFR,CAGT,CACD,CAAA,EACH,CAAA;AAAA,0BAGF,GAAA,CAAC,MAAA,EAAA,EAAO,OAAA,EAAS,QAAA,GAAW,SAAA,GAAY,aAAa,OAAA,EAAS,UAAA,EAAY,SAAA,EAAU,gBAAA,EACjF,QAAA,EAAA,QAAA,EACH;AAAA;AAAA;AAAA,KACF;AAAA,EAEJ;AACF;AACA,WAAA,CAAY,WAAA,GAAc,aAAA","file":"chunk-OVSIOZHJ.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { Check } from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Button } from './Button'\n\nexport interface PricingCardProps extends HTMLAttributes<HTMLDivElement> {\n name: React.ReactNode\n price: React.ReactNode\n /** Rendered after the price, e.g. \"/month\" */\n period?: React.ReactNode\n description?: React.ReactNode\n features?: React.ReactNode[]\n ctaLabel?: React.ReactNode\n onCtaClick?: () => void\n /** Visually highlights this plan as the recommended/featured option */\n featured?: boolean\n /** Small label shown above the price when featured, e.g. \"Most popular\" */\n badge?: React.ReactNode\n}\n\nconst PricingCard = forwardRef<HTMLDivElement, PricingCardProps>(\n (\n {\n className,\n name,\n price,\n period,\n description,\n features = [],\n ctaLabel = 'Get started',\n onCtaClick,\n featured,\n badge,\n ...props\n },\n ref\n ) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'flex flex-col gap-5 rounded-xl border p-6',\n featured\n ? 'border-tollerud-yellow bg-tollerud-yellow/[0.04] shadow-[0_0_0_1px_rgba(255,255,0,0.15)]'\n : 'border-tollerud-border bg-tollerud-surface',\n className\n )}\n {...props}\n >\n <div className=\"flex flex-col gap-1\">\n {badge && (\n <span className=\"inline-flex w-fit items-center rounded-full bg-tollerud-yellow/15 px-2.5 py-0.5 text-xs font-medium text-tollerud-yellow\">\n {badge}\n </span>\n )}\n <h3 className=\"text-base font-medium text-tollerud-text-primary\">{name}</h3>\n {description && <p className=\"text-sm text-tollerud-text-muted\">{description}</p>}\n </div>\n\n <div className=\"flex items-baseline gap-1\">\n <span className=\"text-3xl font-semibold tracking-tight text-tollerud-text-primary\">{price}</span>\n {period && <span className=\"text-sm text-tollerud-text-muted\">{period}</span>}\n </div>\n\n {features.length > 0 && (\n <ul className=\"flex flex-col gap-2.5\">\n {features.map((feature, i) => (\n <li key={i} className=\"flex items-start gap-2.5 text-sm text-tollerud-text-secondary\">\n <Check size={16} className=\"mt-0.5 shrink-0 text-tollerud-yellow\" />\n <span>{feature}</span>\n </li>\n ))}\n </ul>\n )}\n\n <Button variant={featured ? 'primary' : 'secondary'} onClick={onCtaClick} className=\"mt-auto w-full\">\n {ctaLabel}\n </Button>\n </div>\n )\n }\n)\nPricingCard.displayName = 'PricingCard'\n\nexport { PricingCard }\n"]}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
3
|
+
import { useId, useRef, useState, useMemo, useEffect } from 'react';
|
|
4
|
+
import { Calendar, ChevronLeft, ChevronRight } from 'lucide-react';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
var defaultFormat = (date) => date.toLocaleDateString(void 0, { year: "numeric", month: "short", day: "numeric" });
|
|
8
|
+
function isSameDay(a, b) {
|
|
9
|
+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
10
|
+
}
|
|
11
|
+
function startOfMonth(date) {
|
|
12
|
+
return new Date(date.getFullYear(), date.getMonth(), 1);
|
|
13
|
+
}
|
|
14
|
+
function buildCalendarGrid(monthDate) {
|
|
15
|
+
const first = startOfMonth(monthDate);
|
|
16
|
+
const startWeekday = first.getDay();
|
|
17
|
+
const daysInMonth = new Date(monthDate.getFullYear(), monthDate.getMonth() + 1, 0).getDate();
|
|
18
|
+
const cells = [];
|
|
19
|
+
for (let i = 0; i < startWeekday; i++) cells.push(null);
|
|
20
|
+
for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(monthDate.getFullYear(), monthDate.getMonth(), d));
|
|
21
|
+
return cells;
|
|
22
|
+
}
|
|
23
|
+
var WEEKDAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
|
24
|
+
function DatePicker({
|
|
25
|
+
value: valueProp,
|
|
26
|
+
defaultValue = null,
|
|
27
|
+
onChange,
|
|
28
|
+
label,
|
|
29
|
+
error,
|
|
30
|
+
placeholder = "Select a date",
|
|
31
|
+
formatDate = defaultFormat,
|
|
32
|
+
className,
|
|
33
|
+
disabled
|
|
34
|
+
}) {
|
|
35
|
+
const id = useId();
|
|
36
|
+
const rootRef = useRef(null);
|
|
37
|
+
const isControlled = valueProp !== void 0;
|
|
38
|
+
const [internalValue, setInternalValue] = useState(defaultValue);
|
|
39
|
+
const value = isControlled ? valueProp ?? null : internalValue;
|
|
40
|
+
const [open, setOpen] = useState(false);
|
|
41
|
+
const [viewMonth, setViewMonth] = useState(() => startOfMonth(value ?? /* @__PURE__ */ new Date()));
|
|
42
|
+
const cells = useMemo(() => buildCalendarGrid(viewMonth), [viewMonth]);
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (!open) return;
|
|
45
|
+
function onClickOutside(e) {
|
|
46
|
+
if (rootRef.current && !rootRef.current.contains(e.target)) setOpen(false);
|
|
47
|
+
}
|
|
48
|
+
function onResize() {
|
|
49
|
+
setOpen(false);
|
|
50
|
+
}
|
|
51
|
+
document.addEventListener("mousedown", onClickOutside);
|
|
52
|
+
window.addEventListener("resize", onResize);
|
|
53
|
+
return () => {
|
|
54
|
+
document.removeEventListener("mousedown", onClickOutside);
|
|
55
|
+
window.removeEventListener("resize", onResize);
|
|
56
|
+
};
|
|
57
|
+
}, [open]);
|
|
58
|
+
const select = (date) => {
|
|
59
|
+
if (!isControlled) setInternalValue(date);
|
|
60
|
+
onChange?.(date);
|
|
61
|
+
setOpen(false);
|
|
62
|
+
};
|
|
63
|
+
return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: cn("relative flex flex-col gap-1", className), children: [
|
|
64
|
+
label && /* @__PURE__ */ jsx("label", { htmlFor: id, className: "text-xs font-medium text-tollerud-text-muted", children: label }),
|
|
65
|
+
/* @__PURE__ */ jsxs(
|
|
66
|
+
"button",
|
|
67
|
+
{
|
|
68
|
+
id,
|
|
69
|
+
type: "button",
|
|
70
|
+
disabled,
|
|
71
|
+
onClick: () => {
|
|
72
|
+
setViewMonth(startOfMonth(value ?? /* @__PURE__ */ new Date()));
|
|
73
|
+
setOpen((o) => !o);
|
|
74
|
+
},
|
|
75
|
+
"aria-haspopup": "dialog",
|
|
76
|
+
"aria-expanded": open,
|
|
77
|
+
className: cn(
|
|
78
|
+
"flex w-full items-center justify-between gap-2 rounded px-3 py-2 text-left text-base",
|
|
79
|
+
"bg-tollerud-surface-raised border",
|
|
80
|
+
"transition-[border-color] duration-[150ms]",
|
|
81
|
+
"focus:outline-none focus:border-tollerud-yellow focus:shadow-[0_0_0_1px_#E8D500]",
|
|
82
|
+
error ? "border-tollerud-error" : "border-tollerud-border",
|
|
83
|
+
value ? "text-tollerud-text-primary" : "text-tollerud-text-muted",
|
|
84
|
+
disabled && "opacity-50 pointer-events-none"
|
|
85
|
+
),
|
|
86
|
+
children: [
|
|
87
|
+
/* @__PURE__ */ jsx("span", { children: value ? formatDate(value) : placeholder }),
|
|
88
|
+
/* @__PURE__ */ jsx(Calendar, { size: 15, className: "text-tollerud-text-muted" })
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
open && /* @__PURE__ */ jsxs(
|
|
93
|
+
"div",
|
|
94
|
+
{
|
|
95
|
+
role: "dialog",
|
|
96
|
+
"aria-label": "Choose date",
|
|
97
|
+
className: "absolute top-full z-50 mt-1 w-72 rounded-lg border border-tollerud-border bg-tollerud-surface-overlay p-3 shadow-lg",
|
|
98
|
+
children: [
|
|
99
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center justify-between", children: [
|
|
100
|
+
/* @__PURE__ */ jsx(
|
|
101
|
+
"button",
|
|
102
|
+
{
|
|
103
|
+
type: "button",
|
|
104
|
+
"aria-label": "Previous month",
|
|
105
|
+
onClick: () => setViewMonth((m) => new Date(m.getFullYear(), m.getMonth() - 1, 1)),
|
|
106
|
+
className: "rounded p-1 text-tollerud-text-secondary hover:bg-tollerud-surface-hover",
|
|
107
|
+
children: /* @__PURE__ */ jsx(ChevronLeft, { size: 16 })
|
|
108
|
+
}
|
|
109
|
+
),
|
|
110
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium text-tollerud-text-primary", children: viewMonth.toLocaleDateString(void 0, { month: "long", year: "numeric" }) }),
|
|
111
|
+
/* @__PURE__ */ jsx(
|
|
112
|
+
"button",
|
|
113
|
+
{
|
|
114
|
+
type: "button",
|
|
115
|
+
"aria-label": "Next month",
|
|
116
|
+
onClick: () => setViewMonth((m) => new Date(m.getFullYear(), m.getMonth() + 1, 1)),
|
|
117
|
+
className: "rounded p-1 text-tollerud-text-secondary hover:bg-tollerud-surface-hover",
|
|
118
|
+
children: /* @__PURE__ */ jsx(ChevronRight, { size: 16 })
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
] }),
|
|
122
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-7 gap-1 text-center", children: [
|
|
123
|
+
WEEKDAYS.map((d) => /* @__PURE__ */ jsx("span", { className: "text-[11px] font-medium text-tollerud-text-muted py-1", children: d }, d)),
|
|
124
|
+
cells.map((date, i) => {
|
|
125
|
+
if (!date) return /* @__PURE__ */ jsx("span", {}, i);
|
|
126
|
+
const selected = value ? isSameDay(date, value) : false;
|
|
127
|
+
const today = isSameDay(date, /* @__PURE__ */ new Date());
|
|
128
|
+
return /* @__PURE__ */ jsx(
|
|
129
|
+
"button",
|
|
130
|
+
{
|
|
131
|
+
type: "button",
|
|
132
|
+
onClick: () => select(date),
|
|
133
|
+
className: cn(
|
|
134
|
+
"h-8 w-8 rounded-full text-sm transition-colors duration-[150ms]",
|
|
135
|
+
selected ? "bg-tollerud-yellow text-tollerud-noir-black font-medium" : "text-tollerud-text-secondary hover:bg-tollerud-surface-hover",
|
|
136
|
+
!selected && today && "ring-1 ring-tollerud-yellow/40"
|
|
137
|
+
),
|
|
138
|
+
children: date.getDate()
|
|
139
|
+
},
|
|
140
|
+
i
|
|
141
|
+
);
|
|
142
|
+
})
|
|
143
|
+
] })
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
),
|
|
147
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-xs text-tollerud-error mt-0.5", children: error })
|
|
148
|
+
] });
|
|
149
|
+
}
|
|
150
|
+
DatePicker.displayName = "DatePicker";
|
|
151
|
+
|
|
152
|
+
export { DatePicker };
|
|
153
|
+
//# sourceMappingURL=chunk-Q54CVE3W.js.map
|
|
154
|
+
//# sourceMappingURL=chunk-Q54CVE3W.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/DatePicker.tsx"],"names":["CalendarIcon"],"mappings":"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","file":"chunk-Q54CVE3W.js","sourcesContent":["'use client'\n\nimport { useEffect, useId, useMemo, useRef, useState } from 'react'\nimport { ChevronLeft, ChevronRight, Calendar as CalendarIcon } from 'lucide-react'\nimport { cn } from '@/lib/utils'\n\nexport interface DatePickerProps {\n value?: Date | null\n defaultValue?: Date | null\n onChange?: (date: Date | null) => void\n label?: string\n error?: string\n placeholder?: string\n /** Format a date for display in the input (defaults to locale short date) */\n formatDate?: (date: Date) => string\n className?: string\n disabled?: boolean\n}\n\nconst defaultFormat = (date: Date) =>\n date.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })\n\nfunction isSameDay(a: Date, b: Date) {\n return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate()\n}\n\nfunction startOfMonth(date: Date) {\n return new Date(date.getFullYear(), date.getMonth(), 1)\n}\n\nfunction buildCalendarGrid(monthDate: Date): (Date | null)[] {\n const first = startOfMonth(monthDate)\n const startWeekday = first.getDay()\n const daysInMonth = new Date(monthDate.getFullYear(), monthDate.getMonth() + 1, 0).getDate()\n\n const cells: (Date | null)[] = []\n for (let i = 0; i < startWeekday; i++) cells.push(null)\n for (let d = 1; d <= daysInMonth; d++) cells.push(new Date(monthDate.getFullYear(), monthDate.getMonth(), d))\n return cells\n}\n\nconst WEEKDAYS = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']\n\nfunction DatePicker({\n value: valueProp,\n defaultValue = null,\n onChange,\n label,\n error,\n placeholder = 'Select a date',\n formatDate = defaultFormat,\n className,\n disabled,\n}: DatePickerProps) {\n const id = useId()\n const rootRef = useRef<HTMLDivElement>(null)\n const isControlled = valueProp !== undefined\n const [internalValue, setInternalValue] = useState<Date | null>(defaultValue)\n const value = isControlled ? valueProp ?? null : internalValue\n\n const [open, setOpen] = useState(false)\n const [viewMonth, setViewMonth] = useState(() => startOfMonth(value ?? new Date()))\n\n const cells = useMemo(() => buildCalendarGrid(viewMonth), [viewMonth])\n\n useEffect(() => {\n if (!open) return\n function onClickOutside(e: MouseEvent) {\n if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false)\n }\n function onResize() { setOpen(false) }\n document.addEventListener('mousedown', onClickOutside)\n window.addEventListener('resize', onResize)\n return () => {\n document.removeEventListener('mousedown', onClickOutside)\n window.removeEventListener('resize', onResize)\n }\n }, [open])\n\n const select = (date: Date) => {\n if (!isControlled) setInternalValue(date)\n onChange?.(date)\n setOpen(false)\n }\n\n return (\n <div ref={rootRef} className={cn('relative flex flex-col gap-1', className)}>\n {label && (\n <label htmlFor={id} className=\"text-xs font-medium text-tollerud-text-muted\">\n {label}\n </label>\n )}\n <button\n id={id}\n type=\"button\"\n disabled={disabled}\n onClick={() => {\n setViewMonth(startOfMonth(value ?? new Date()))\n setOpen((o) => !o)\n }}\n aria-haspopup=\"dialog\"\n aria-expanded={open}\n className={cn(\n 'flex w-full items-center justify-between gap-2 rounded px-3 py-2 text-left text-base',\n 'bg-tollerud-surface-raised border',\n 'transition-[border-color] duration-[150ms]',\n 'focus:outline-none focus:border-tollerud-yellow focus:shadow-[0_0_0_1px_#E8D500]',\n error ? 'border-tollerud-error' : 'border-tollerud-border',\n value ? 'text-tollerud-text-primary' : 'text-tollerud-text-muted',\n disabled && 'opacity-50 pointer-events-none'\n )}\n >\n <span>{value ? formatDate(value) : placeholder}</span>\n <CalendarIcon size={15} className=\"text-tollerud-text-muted\" />\n </button>\n\n {open && (\n <div\n role=\"dialog\"\n aria-label=\"Choose date\"\n className=\"absolute top-full z-50 mt-1 w-72 rounded-lg border border-tollerud-border bg-tollerud-surface-overlay p-3 shadow-lg\"\n >\n <div className=\"mb-2 flex items-center justify-between\">\n <button\n type=\"button\"\n aria-label=\"Previous month\"\n onClick={() => setViewMonth((m) => new Date(m.getFullYear(), m.getMonth() - 1, 1))}\n className=\"rounded p-1 text-tollerud-text-secondary hover:bg-tollerud-surface-hover\"\n >\n <ChevronLeft size={16} />\n </button>\n <span className=\"text-sm font-medium text-tollerud-text-primary\">\n {viewMonth.toLocaleDateString(undefined, { month: 'long', year: 'numeric' })}\n </span>\n <button\n type=\"button\"\n aria-label=\"Next month\"\n onClick={() => setViewMonth((m) => new Date(m.getFullYear(), m.getMonth() + 1, 1))}\n className=\"rounded p-1 text-tollerud-text-secondary hover:bg-tollerud-surface-hover\"\n >\n <ChevronRight size={16} />\n </button>\n </div>\n\n <div className=\"grid grid-cols-7 gap-1 text-center\">\n {WEEKDAYS.map((d) => (\n <span key={d} className=\"text-[11px] font-medium text-tollerud-text-muted py-1\">\n {d}\n </span>\n ))}\n {cells.map((date, i) => {\n if (!date) return <span key={i} />\n const selected = value ? isSameDay(date, value) : false\n const today = isSameDay(date, new Date())\n return (\n <button\n key={i}\n type=\"button\"\n onClick={() => select(date)}\n className={cn(\n 'h-8 w-8 rounded-full text-sm transition-colors duration-[150ms]',\n selected\n ? 'bg-tollerud-yellow text-tollerud-noir-black font-medium'\n : 'text-tollerud-text-secondary hover:bg-tollerud-surface-hover',\n !selected && today && 'ring-1 ring-tollerud-yellow/40'\n )}\n >\n {date.getDate()}\n </button>\n )\n })}\n </div>\n </div>\n )}\n\n {error && <p className=\"text-xs text-tollerud-error mt-0.5\">{error}</p>}\n </div>\n )\n}\nDatePicker.displayName = 'DatePicker'\n\nexport { DatePicker }\n"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
3
|
+
import { forwardRef } from 'react';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var badgeVariants = {
|
|
7
|
+
default: "bg-tollerud-noir-700 text-tollerud-text-secondary",
|
|
8
|
+
accent: "bg-tollerud-yellow/15 text-tollerud-yellow",
|
|
9
|
+
success: "bg-tollerud-success/15 text-tollerud-success",
|
|
10
|
+
error: "bg-tollerud-error/15 text-tollerud-error",
|
|
11
|
+
info: "bg-tollerud-info/15 text-tollerud-info",
|
|
12
|
+
warning: "bg-tollerud-yellow/15 text-tollerud-warning"
|
|
13
|
+
};
|
|
14
|
+
var Badge = forwardRef(
|
|
15
|
+
({ className, variant = "default", ...props }, ref) => {
|
|
16
|
+
return /* @__PURE__ */ jsx(
|
|
17
|
+
"span",
|
|
18
|
+
{
|
|
19
|
+
ref,
|
|
20
|
+
className: cn(
|
|
21
|
+
"inline-flex items-center px-2 py-0.5 text-xs font-medium rounded",
|
|
22
|
+
"tracking-wide",
|
|
23
|
+
badgeVariants[variant],
|
|
24
|
+
className
|
|
25
|
+
),
|
|
26
|
+
...props
|
|
27
|
+
}
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
Badge.displayName = "Badge";
|
|
32
|
+
|
|
33
|
+
export { Badge };
|
|
34
|
+
//# sourceMappingURL=chunk-QEHTPQHL.js.map
|
|
35
|
+
//# sourceMappingURL=chunk-QEHTPQHL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/Badge.tsx"],"names":[],"mappings":";;;;AAGA,IAAM,aAAA,GAAgB;AAAA,EACpB,OAAA,EAAS,mDAAA;AAAA,EACT,MAAA,EAAQ,4CAAA;AAAA,EACR,OAAA,EAAS,8CAAA;AAAA,EACT,KAAA,EAAO,0CAAA;AAAA,EACP,IAAA,EAAM,wCAAA;AAAA,EACN,OAAA,EAAS;AACX,CAAA;AAMA,IAAM,KAAA,GAAQ,UAAA;AAAA,EACZ,CAAC,EAAE,SAAA,EAAW,OAAA,GAAU,WAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AACrD,IAAA,uBACE,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,SAAA,EAAW,EAAA;AAAA,UACT,kEAAA;AAAA,UACA,eAAA;AAAA,UACA,cAAc,OAAO,CAAA;AAAA,UACrB;AAAA,SACF;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AACA,KAAA,CAAM,WAAA,GAAc,OAAA","file":"chunk-QEHTPQHL.js","sourcesContent":["import { type HTMLAttributes, forwardRef } from 'react'\nimport { cn } from '@/lib/utils'\n\nconst badgeVariants = {\n default: 'bg-tollerud-noir-700 text-tollerud-text-secondary',\n accent: 'bg-tollerud-yellow/15 text-tollerud-yellow',\n success: 'bg-tollerud-success/15 text-tollerud-success',\n error: 'bg-tollerud-error/15 text-tollerud-error',\n info: 'bg-tollerud-info/15 text-tollerud-info',\n warning: 'bg-tollerud-yellow/15 text-tollerud-warning',\n} as const\n\nexport interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {\n variant?: keyof typeof badgeVariants\n}\n\nconst Badge = forwardRef<HTMLSpanElement, BadgeProps>(\n ({ className, variant = 'default', ...props }, ref) => {\n return (\n <span\n ref={ref}\n className={cn(\n 'inline-flex items-center px-2 py-0.5 text-xs font-medium rounded',\n 'tracking-wide',\n badgeVariants[variant],\n className\n )}\n {...props}\n />\n )\n }\n)\nBadge.displayName = 'Badge'\n\nexport { Badge }\n"]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { Monogram } from './chunk-VOARBYVQ.js';
|
|
3
|
+
import { cn } from './chunk-WSQNPRGN.js';
|
|
4
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
var defaultLabels = {
|
|
7
|
+
tollerudProject: "A Tollerud Project",
|
|
8
|
+
allRightsReserved: "All rights reserved."
|
|
9
|
+
};
|
|
10
|
+
function Footer({
|
|
11
|
+
labels,
|
|
12
|
+
layout = "responsive",
|
|
13
|
+
className,
|
|
14
|
+
style,
|
|
15
|
+
unstyled = false,
|
|
16
|
+
accent = false,
|
|
17
|
+
classNameInner,
|
|
18
|
+
classNameLogo,
|
|
19
|
+
classNameText,
|
|
20
|
+
classNameLink
|
|
21
|
+
}) {
|
|
22
|
+
const t = { ...defaultLabels, ...labels };
|
|
23
|
+
const attribution = t.attribution?.trim();
|
|
24
|
+
const footerSurface = unstyled ? "" : accent ? "border-t border-tollerud-yellow/20 bg-tollerud-yellow/5" : "border-t border-tollerud-border bg-tollerud-noir-900/80";
|
|
25
|
+
const innerLayoutClasses = layout === "row" ? "max-w-7xl mx-auto px-8 flex flex-row items-center justify-between gap-4" : "max-w-7xl mx-auto px-8 flex flex-col md:flex-row items-center justify-center md:justify-between gap-4 md:gap-0";
|
|
26
|
+
const textWrapperClasses = layout === "row" ? "flex-1 text-right ml-4" : "flex-1 text-center md:text-right md:ml-4";
|
|
27
|
+
const textLayoutClasses = layout === "row" ? "text-sm text-tollerud-text-secondary inline-flex flex-row items-center justify-end text-right gap-0" : "text-sm text-tollerud-text-secondary flex flex-col md:flex-row md:inline gap-0";
|
|
28
|
+
return /* @__PURE__ */ jsx("footer", { className: cn("w-full pt-4 pb-4", footerSurface, className), style, children: /* @__PURE__ */ jsxs("div", { className: cn(innerLayoutClasses, classNameInner), children: [
|
|
29
|
+
/* @__PURE__ */ jsx("div", { className: "flex-shrink-0 md:flex-shrink-0", children: /* @__PURE__ */ jsx(Monogram, { color: "yellow", className: cn("h-5 w-auto", classNameLogo) }) }),
|
|
30
|
+
/* @__PURE__ */ jsx("div", { className: textWrapperClasses, children: /* @__PURE__ */ jsxs("p", { className: cn(textLayoutClasses, classNameText), children: [
|
|
31
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
32
|
+
/* @__PURE__ */ jsx(
|
|
33
|
+
"a",
|
|
34
|
+
{
|
|
35
|
+
href: "https://tollerud.no",
|
|
36
|
+
target: "_blank",
|
|
37
|
+
rel: "noopener noreferrer",
|
|
38
|
+
className: cn(
|
|
39
|
+
"underline decoration-tollerud-yellow decoration-[3px] underline-offset-[4px] hover:opacity-80 transition-opacity",
|
|
40
|
+
classNameLink
|
|
41
|
+
),
|
|
42
|
+
style: {
|
|
43
|
+
textDecorationThickness: "3px",
|
|
44
|
+
textUnderlineOffset: "4px"
|
|
45
|
+
},
|
|
46
|
+
children: t.tollerudProject
|
|
47
|
+
}
|
|
48
|
+
),
|
|
49
|
+
attribution ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
50
|
+
" ",
|
|
51
|
+
/* @__PURE__ */ jsx("span", { children: attribution })
|
|
52
|
+
] }) : null,
|
|
53
|
+
" "
|
|
54
|
+
] }),
|
|
55
|
+
/* @__PURE__ */ jsx("span", { className: layout === "row" ? "ml-1" : "md:ml-1", children: t.allRightsReserved })
|
|
56
|
+
] }) })
|
|
57
|
+
] }) });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export { Footer };
|
|
61
|
+
//# sourceMappingURL=chunk-QEIEWGHA.js.map
|
|
62
|
+
//# sourceMappingURL=chunk-QEIEWGHA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../components/Footer.tsx"],"names":[],"mappings":";;;;AAiBA,IAAM,aAAA,GAA8B;AAAA,EAClC,eAAA,EAAiB,oBAAA;AAAA,EACjB,iBAAA,EAAmB;AACrB,CAAA;AAuBO,SAAS,MAAA,CAAO;AAAA,EACrB,MAAA;AAAA,EACA,MAAA,GAAS,YAAA;AAAA,EACT,SAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA,GAAW,KAAA;AAAA,EACX,MAAA,GAAS,KAAA;AAAA,EACT,cAAA;AAAA,EACA,aAAA;AAAA,EACA,aAAA;AAAA,EACA;AACF,CAAA,EAA8B;AAC5B,EAAA,MAAM,CAAA,GAAI,EAAE,GAAG,aAAA,EAAe,GAAG,MAAA,EAAO;AACxC,EAAA,MAAM,WAAA,GAAc,CAAA,CAAE,WAAA,EAAa,IAAA,EAAK;AAExC,EAAA,MAAM,aAAA,GAAgB,QAAA,GAClB,EAAA,GACA,MAAA,GACE,yDAAA,GACA,yDAAA;AAEN,EAAA,MAAM,kBAAA,GACJ,MAAA,KAAW,KAAA,GACP,yEAAA,GACA,gHAAA;AAEN,EAAA,MAAM,kBAAA,GACJ,MAAA,KAAW,KAAA,GAAQ,wBAAA,GAA2B,0CAAA;AAEhD,EAAA,MAAM,iBAAA,GACJ,MAAA,KAAW,KAAA,GACP,qGAAA,GACA,gFAAA;AAEN,EAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EAAO,SAAA,EAAW,EAAA,CAAG,oBAAoB,aAAA,EAAe,SAAS,CAAA,EAAG,KAAA,EACnE,+BAAC,KAAA,EAAA,EAAI,SAAA,EAAW,EAAA,CAAG,kBAAA,EAAoB,cAAc,CAAA,EACnD,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,gCAAA,EACb,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,KAAA,EAAM,QAAA,EAAS,SAAA,EAAW,EAAA,CAAG,YAAA,EAAc,aAAa,CAAA,EAAG,CAAA,EACvE,CAAA;AAAA,oBAEA,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,kBAAA,EACd,QAAA,kBAAA,IAAA,CAAC,OAAE,SAAA,EAAW,EAAA,CAAG,iBAAA,EAAmB,aAAa,CAAA,EAC/C,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,MAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,GAAA;AAAA,UAAA;AAAA,YACC,IAAA,EAAK,qBAAA;AAAA,YACL,MAAA,EAAO,QAAA;AAAA,YACP,GAAA,EAAI,qBAAA;AAAA,YACJ,SAAA,EAAW,EAAA;AAAA,cACT,kHAAA;AAAA,cACA;AAAA,aACF;AAAA,YACA,KAAA,EAAO;AAAA,cACL,uBAAA,EAAyB,KAAA;AAAA,cACzB,mBAAA,EAAqB;AAAA,aACvB;AAAA,YAEC,QAAA,EAAA,CAAA,CAAE;AAAA;AAAA,SACL;AAAA,QACC,8BACC,IAAA,CAAA,QAAA,EAAA,EACG,QAAA,EAAA;AAAA,UAAA,GAAA;AAAA,0BACD,GAAA,CAAC,UAAM,QAAA,EAAA,WAAA,EAAY;AAAA,SAAA,EACrB,CAAA,GACE,IAAA;AAAA,QAAM;AAAA,OAAA,EACZ,CAAA;AAAA,sBACA,GAAA,CAAC,UAAK,SAAA,EAAW,MAAA,KAAW,QAAQ,MAAA,GAAS,SAAA,EAAY,YAAE,iBAAA,EAAkB;AAAA,KAAA,EAC/E,CAAA,EACF;AAAA,GAAA,EACF,CAAA,EACF,CAAA;AAEJ","file":"chunk-QEIEWGHA.js","sourcesContent":["'use client'\n\nimport type { CSSProperties, ReactElement } from 'react'\nimport { cn } from '@/lib/utils'\nimport { Monogram } from './Monogram'\n\nexport type FooterLabels = {\n /** Text for the tollerud.no link (e.g. \"A Tollerud Project\"). */\n tollerudProject: string\n /**\n * Optional middle segment after the link, before the rights line.\n * Example for Advania: `\"for Advania Norge AS.\"`\n */\n attribution?: string\n allRightsReserved: string\n}\n\nconst defaultLabels: FooterLabels = {\n tollerudProject: 'A Tollerud Project',\n allRightsReserved: 'All rights reserved.',\n}\n\nexport type FooterProps = {\n labels?: Partial<FooterLabels>\n /** Layout behavior: responsive keeps mobile-first stacking, row forces horizontal layout. */\n layout?: 'responsive' | 'row'\n /** Merged onto <footer>. Use for extra layout, padding, etc. */\n className?: string\n /** Merged onto <footer> (wins over conflicting backgroundColor from classes when needed). */\n style?: CSSProperties\n /**\n * When true, skips all default surface styling so className/style fully control the bar\n * (avoids fighting default background/border).\n */\n unstyled?: boolean\n /** When true, uses accent (yellow) surface instead of neutral dark. */\n accent?: boolean\n classNameInner?: string\n classNameLogo?: string\n classNameText?: string\n classNameLink?: string\n}\n\nexport function Footer({\n labels,\n layout = 'responsive',\n className,\n style,\n unstyled = false,\n accent = false,\n classNameInner,\n classNameLogo,\n classNameText,\n classNameLink,\n}: FooterProps): ReactElement {\n const t = { ...defaultLabels, ...labels }\n const attribution = t.attribution?.trim()\n\n const footerSurface = unstyled\n ? ''\n : accent\n ? 'border-t border-tollerud-yellow/20 bg-tollerud-yellow/5'\n : 'border-t border-tollerud-border bg-tollerud-noir-900/80'\n\n const innerLayoutClasses =\n layout === 'row'\n ? 'max-w-7xl mx-auto px-8 flex flex-row items-center justify-between gap-4'\n : 'max-w-7xl mx-auto px-8 flex flex-col md:flex-row items-center justify-center md:justify-between gap-4 md:gap-0'\n\n const textWrapperClasses =\n layout === 'row' ? 'flex-1 text-right ml-4' : 'flex-1 text-center md:text-right md:ml-4'\n\n const textLayoutClasses =\n layout === 'row'\n ? 'text-sm text-tollerud-text-secondary inline-flex flex-row items-center justify-end text-right gap-0'\n : 'text-sm text-tollerud-text-secondary flex flex-col md:flex-row md:inline gap-0'\n\n return (\n <footer className={cn('w-full pt-4 pb-4', footerSurface, className)} style={style}>\n <div className={cn(innerLayoutClasses, classNameInner)}>\n <div className=\"flex-shrink-0 md:flex-shrink-0\">\n <Monogram color=\"yellow\" className={cn('h-5 w-auto', classNameLogo)} />\n </div>\n\n <div className={textWrapperClasses}>\n <p className={cn(textLayoutClasses, classNameText)}>\n <span>\n <a\n href=\"https://tollerud.no\"\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cn(\n 'underline decoration-tollerud-yellow decoration-[3px] underline-offset-[4px] hover:opacity-80 transition-opacity',\n classNameLink,\n )}\n style={{\n textDecorationThickness: '3px',\n textUnderlineOffset: '4px',\n }}\n >\n {t.tollerudProject}\n </a>\n {attribution ? (\n <>\n {' '}\n <span>{attribution}</span>\n </>\n ) : null}{' '}\n </span>\n <span className={layout === 'row' ? 'ml-1' : 'md:ml-1'}>{t.allRightsReserved}</span>\n </p>\n </div>\n </div>\n </footer>\n )\n}"]}
|