love-ui 1.2.12 → 1.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +8 -7
- package/dist/mcp-server.js +1 -1
- package/package.json +3 -2
- package/packages/loveui-skills/SKILL.md +99 -0
- package/packages/loveui-skills/agents/openai.yaml +11 -0
- package/packages/loveui-skills/references/design-directions.md +60 -0
- package/packages/loveui-skills/references/mcp-catalog-workflow.md +68 -0
- package/packages/loveui-skills/references/page-blueprints.md +76 -0
- package/packages/loveui-skills/references/quality-gates.md +51 -0
- package/public/r/accordion-controlled.json +1 -1
- package/public/r/accordion-demo.json +1 -1
- package/public/r/accordion-multiple.json +1 -1
- package/public/r/accordion-single.json +1 -1
- package/public/r/alert-demo.json +1 -1
- package/public/r/alert-dialog-demo.json +1 -1
- package/public/r/alert-error.json +1 -1
- package/public/r/alert-info.json +1 -1
- package/public/r/alert-success.json +1 -1
- package/public/r/alert-warning.json +1 -1
- package/public/r/alert-with-icon-action.json +1 -1
- package/public/r/alert-with-icon.json +1 -1
- package/public/r/announcement-tagless.json +1 -1
- package/public/r/announcement-themes.json +1 -1
- package/public/r/announcement.json +1 -1
- package/public/r/autocomplete-async.json +1 -1
- package/public/r/autocomplete-autohighlight.json +1 -1
- package/public/r/autocomplete-demo.json +1 -1
- package/public/r/autocomplete-disabled.json +1 -1
- package/public/r/autocomplete-form.json +1 -1
- package/public/r/autocomplete-grouped.json +1 -1
- package/public/r/autocomplete-inline.json +1 -1
- package/public/r/autocomplete-lg.json +1 -1
- package/public/r/autocomplete-limit.json +1 -1
- package/public/r/autocomplete-sm.json +1 -1
- package/public/r/autocomplete-with-clear.json +1 -1
- package/public/r/autocomplete-with-label.json +1 -1
- package/public/r/autocomplete-with-trigger-clear.json +1 -1
- package/public/r/avatar-demo.json +1 -1
- package/public/r/avatar-fallback.json +1 -1
- package/public/r/avatar-group.json +1 -1
- package/public/r/avatar-radius.json +1 -1
- package/public/r/avatar-size.json +1 -1
- package/public/r/avatar-stack-hover.json +1 -1
- package/public/r/avatar-stack.json +1 -1
- package/public/r/badge-demo.json +1 -1
- package/public/r/badge-destructive.json +1 -1
- package/public/r/badge-error.json +1 -1
- package/public/r/badge-info.json +1 -1
- package/public/r/badge-lg.json +1 -1
- package/public/r/badge-outline.json +1 -1
- package/public/r/badge-secondary.json +1 -1
- package/public/r/badge-sm.json +1 -1
- package/public/r/badge-success.json +1 -1
- package/public/r/badge-warning.json +1 -1
- package/public/r/badge-with-icon.json +1 -1
- package/public/r/badge-with-link.json +1 -1
- package/public/r/banner-inset.json +1 -1
- package/public/r/banner-themes.json +1 -1
- package/public/r/banner.json +1 -1
- package/public/r/bookmarks.json +206 -0
- package/public/r/breadcrumb-custom-separator.json +1 -1
- package/public/r/breadcrumb-demo.json +1 -1
- package/public/r/button-demo.json +1 -1
- package/public/r/button-destructive-outline.json +1 -1
- package/public/r/button-destructive.json +1 -1
- package/public/r/button-disabled.json +1 -1
- package/public/r/button-ghost.json +1 -1
- package/public/r/button-lg.json +1 -1
- package/public/r/button-link.json +1 -1
- package/public/r/button-loading.json +1 -1
- package/public/r/button-outline.json +1 -1
- package/public/r/button-secondary.json +1 -1
- package/public/r/button-sm.json +1 -1
- package/public/r/button-with-icon.json +1 -1
- package/public/r/button-with-link.json +1 -1
- package/public/r/button-xl.json +1 -1
- package/public/r/button-xs.json +1 -1
- package/public/r/calendar-headless.json +1 -1
- package/public/r/calendar-rac.json +16 -0
- package/public/r/calendar.json +1 -1
- package/public/r/card-demo.json +1 -1
- package/public/r/chart.json +15 -0
- package/public/r/checkbox-card.json +1 -1
- package/public/r/checkbox-demo.json +1 -1
- package/public/r/checkbox-disabled.json +1 -1
- package/public/r/checkbox-form.json +1 -1
- package/public/r/checkbox-group-demo.json +1 -1
- package/public/r/checkbox-group-disabled.json +1 -1
- package/public/r/checkbox-group-form.json +1 -1
- package/public/r/checkbox-group-nested-parent.json +1 -1
- package/public/r/checkbox-group-parent.json +1 -1
- package/public/r/checkbox-tree.json +12 -0
- package/public/r/checkbox-with-description.json +1 -1
- package/public/r/choicebox-inline.json +1 -1
- package/public/r/choicebox.json +1 -1
- package/public/r/codebase.json +1 -1
- package/public/r/collaborative-canvas.json +1 -1
- package/public/r/collapsible-demo.json +1 -1
- package/public/r/combobox-autohighlight.json +1 -1
- package/public/r/combobox-controlled.json +1 -1
- package/public/r/combobox-create-new.json +1 -1
- package/public/r/combobox-demo.json +1 -1
- package/public/r/combobox-disabled.json +1 -1
- package/public/r/combobox-fixed-width.json +1 -1
- package/public/r/combobox-form.json +1 -1
- package/public/r/combobox-grouped.json +1 -1
- package/public/r/combobox-lg.json +1 -1
- package/public/r/combobox-multiple-form.json +1 -1
- package/public/r/combobox-multiple.json +1 -1
- package/public/r/combobox-sm.json +1 -1
- package/public/r/combobox-with-clear.json +1 -1
- package/public/r/combobox-with-inner-input.json +1 -1
- package/public/r/combobox-with-label.json +1 -1
- package/public/r/command.json +18 -0
- package/public/r/comp-01.json +22 -0
- package/public/r/comp-02.json +23 -0
- package/public/r/comp-03.json +23 -0
- package/public/r/comp-04.json +23 -0
- package/public/r/comp-05.json +22 -0
- package/public/r/comp-06.json +23 -0
- package/public/r/comp-07.json +22 -0
- package/public/r/comp-08.json +23 -0
- package/public/r/comp-09.json +22 -0
- package/public/r/comp-10.json +22 -0
- package/public/r/comp-100.json +23 -0
- package/public/r/comp-101.json +23 -0
- package/public/r/comp-102.json +23 -0
- package/public/r/comp-103.json +23 -0
- package/public/r/comp-104.json +23 -0
- package/public/r/comp-105.json +23 -0
- package/public/r/comp-106.json +22 -0
- package/public/r/comp-107.json +22 -0
- package/public/r/comp-108.json +23 -0
- package/public/r/comp-109.json +22 -0
- package/public/r/comp-11.json +22 -0
- package/public/r/comp-110.json +22 -0
- package/public/r/comp-111.json +21 -0
- package/public/r/comp-112.json +21 -0
- package/public/r/comp-113.json +22 -0
- package/public/r/comp-114.json +23 -0
- package/public/r/comp-115.json +22 -0
- package/public/r/comp-116.json +22 -0
- package/public/r/comp-117.json +23 -0
- package/public/r/comp-118.json +23 -0
- package/public/r/comp-119.json +27 -0
- package/public/r/comp-12.json +22 -0
- package/public/r/comp-120.json +27 -0
- package/public/r/comp-121.json +27 -0
- package/public/r/comp-122.json +27 -0
- package/public/r/comp-123.json +22 -0
- package/public/r/comp-124.json +22 -0
- package/public/r/comp-125.json +31 -0
- package/public/r/comp-126.json +31 -0
- package/public/r/comp-127.json +21 -0
- package/public/r/comp-128.json +21 -0
- package/public/r/comp-129.json +24 -0
- package/public/r/comp-13.json +22 -0
- package/public/r/comp-130.json +23 -0
- package/public/r/comp-131.json +23 -0
- package/public/r/comp-132.json +23 -0
- package/public/r/comp-133.json +23 -0
- package/public/r/comp-134.json +23 -0
- package/public/r/comp-135.json +24 -0
- package/public/r/comp-136.json +23 -0
- package/public/r/comp-137.json +23 -0
- package/public/r/comp-138.json +25 -0
- package/public/r/comp-139.json +23 -0
- package/public/r/comp-14.json +22 -0
- package/public/r/comp-140.json +23 -0
- package/public/r/comp-141.json +23 -0
- package/public/r/comp-142.json +25 -0
- package/public/r/comp-143.json +23 -0
- package/public/r/comp-144.json +24 -0
- package/public/r/comp-145.json +24 -0
- package/public/r/comp-146.json +24 -0
- package/public/r/comp-147.json +24 -0
- package/public/r/comp-148.json +25 -0
- package/public/r/comp-149.json +24 -0
- package/public/r/comp-15.json +22 -0
- package/public/r/comp-150.json +21 -0
- package/public/r/comp-151.json +23 -0
- package/public/r/comp-152.json +23 -0
- package/public/r/comp-153.json +23 -0
- package/public/r/comp-154.json +23 -0
- package/public/r/comp-155.json +23 -0
- package/public/r/comp-156.json +25 -0
- package/public/r/comp-157.json +27 -0
- package/public/r/comp-158.json +24 -0
- package/public/r/comp-159.json +24 -0
- package/public/r/comp-16.json +22 -0
- package/public/r/comp-160.json +24 -0
- package/public/r/comp-161.json +24 -0
- package/public/r/comp-162.json +24 -0
- package/public/r/comp-163.json +28 -0
- package/public/r/comp-164.json +24 -0
- package/public/r/comp-165.json +24 -0
- package/public/r/comp-166.json +25 -0
- package/public/r/comp-167.json +24 -0
- package/public/r/comp-168.json +24 -0
- package/public/r/comp-169.json +23 -0
- package/public/r/comp-17.json +25 -0
- package/public/r/comp-170.json +25 -0
- package/public/r/comp-171.json +28 -0
- package/public/r/comp-172.json +23 -0
- package/public/r/comp-173.json +23 -0
- package/public/r/comp-174.json +23 -0
- package/public/r/comp-175.json +23 -0
- package/public/r/comp-176.json +23 -0
- package/public/r/comp-177.json +23 -0
- package/public/r/comp-178.json +23 -0
- package/public/r/comp-179.json +24 -0
- package/public/r/comp-18.json +25 -0
- package/public/r/comp-180.json +23 -0
- package/public/r/comp-181.json +25 -0
- package/public/r/comp-182.json +24 -0
- package/public/r/comp-183.json +25 -0
- package/public/r/comp-184.json +25 -0
- package/public/r/comp-185.json +24 -0
- package/public/r/comp-186.json +25 -0
- package/public/r/comp-187.json +25 -0
- package/public/r/comp-188.json +25 -0
- package/public/r/comp-189.json +23 -0
- package/public/r/comp-19.json +23 -0
- package/public/r/comp-190.json +23 -0
- package/public/r/comp-191.json +24 -0
- package/public/r/comp-192.json +23 -0
- package/public/r/comp-193.json +23 -0
- package/public/r/comp-194.json +24 -0
- package/public/r/comp-195.json +23 -0
- package/public/r/comp-196.json +24 -0
- package/public/r/comp-197.json +23 -0
- package/public/r/comp-198.json +23 -0
- package/public/r/comp-199.json +23 -0
- package/public/r/comp-20.json +23 -0
- package/public/r/comp-200.json +25 -0
- package/public/r/comp-201.json +22 -0
- package/public/r/comp-202.json +22 -0
- package/public/r/comp-203.json +23 -0
- package/public/r/comp-204.json +23 -0
- package/public/r/comp-205.json +23 -0
- package/public/r/comp-206.json +24 -0
- package/public/r/comp-207.json +23 -0
- package/public/r/comp-208.json +23 -0
- package/public/r/comp-209.json +23 -0
- package/public/r/comp-21.json +23 -0
- package/public/r/comp-210.json +24 -0
- package/public/r/comp-211.json +24 -0
- package/public/r/comp-212.json +23 -0
- package/public/r/comp-213.json +23 -0
- package/public/r/comp-214.json +23 -0
- package/public/r/comp-215.json +24 -0
- package/public/r/comp-216.json +22 -0
- package/public/r/comp-217.json +22 -0
- package/public/r/comp-218.json +25 -0
- package/public/r/comp-219.json +23 -0
- package/public/r/comp-22.json +23 -0
- package/public/r/comp-220.json +24 -0
- package/public/r/comp-221.json +23 -0
- package/public/r/comp-222.json +26 -0
- package/public/r/comp-223.json +26 -0
- package/public/r/comp-224.json +23 -0
- package/public/r/comp-225.json +24 -0
- package/public/r/comp-226.json +26 -0
- package/public/r/comp-227.json +26 -0
- package/public/r/comp-228.json +26 -0
- package/public/r/comp-229.json +30 -0
- package/public/r/comp-23.json +24 -0
- package/public/r/comp-230.json +30 -0
- package/public/r/comp-231.json +32 -0
- package/public/r/comp-232.json +31 -0
- package/public/r/comp-233.json +30 -0
- package/public/r/comp-234.json +28 -0
- package/public/r/comp-235.json +28 -0
- package/public/r/comp-236.json +24 -0
- package/public/r/comp-237.json +26 -0
- package/public/r/comp-238.json +26 -0
- package/public/r/comp-239.json +26 -0
- package/public/r/comp-24.json +23 -0
- package/public/r/comp-240.json +23 -0
- package/public/r/comp-241.json +24 -0
- package/public/r/comp-242.json +23 -0
- package/public/r/comp-243.json +23 -0
- package/public/r/comp-244.json +23 -0
- package/public/r/comp-245.json +23 -0
- package/public/r/comp-246.json +23 -0
- package/public/r/comp-247.json +23 -0
- package/public/r/comp-248.json +23 -0
- package/public/r/comp-249.json +24 -0
- package/public/r/comp-25.json +24 -0
- package/public/r/comp-250.json +25 -0
- package/public/r/comp-251.json +25 -0
- package/public/r/comp-252.json +25 -0
- package/public/r/comp-253.json +25 -0
- package/public/r/comp-254.json +35 -0
- package/public/r/comp-255.json +30 -0
- package/public/r/comp-256.json +25 -0
- package/public/r/comp-257.json +25 -0
- package/public/r/comp-258.json +32 -0
- package/public/r/comp-259.json +26 -0
- package/public/r/comp-26.json +24 -0
- package/public/r/comp-260.json +26 -0
- package/public/r/comp-261.json +24 -0
- package/public/r/comp-262.json +31 -0
- package/public/r/comp-263.json +25 -0
- package/public/r/comp-264.json +33 -0
- package/public/r/comp-265.json +32 -0
- package/public/r/comp-266.json +24 -0
- package/public/r/comp-267.json +19 -0
- package/public/r/comp-268.json +19 -0
- package/public/r/comp-269.json +19 -0
- package/public/r/comp-27.json +24 -0
- package/public/r/comp-270.json +19 -0
- package/public/r/comp-271.json +19 -0
- package/public/r/comp-272.json +19 -0
- package/public/r/comp-273.json +19 -0
- package/public/r/comp-274.json +19 -0
- package/public/r/comp-275.json +19 -0
- package/public/r/comp-276.json +19 -0
- package/public/r/comp-277.json +21 -0
- package/public/r/comp-278.json +21 -0
- package/public/r/comp-279.json +23 -0
- package/public/r/comp-28.json +24 -0
- package/public/r/comp-280.json +23 -0
- package/public/r/comp-281.json +23 -0
- package/public/r/comp-282.json +23 -0
- package/public/r/comp-283.json +23 -0
- package/public/r/comp-284.json +23 -0
- package/public/r/comp-285.json +23 -0
- package/public/r/comp-286.json +23 -0
- package/public/r/comp-287.json +24 -0
- package/public/r/comp-288.json +23 -0
- package/public/r/comp-289.json +24 -0
- package/public/r/comp-29.json +24 -0
- package/public/r/comp-290.json +24 -0
- package/public/r/comp-291.json +24 -0
- package/public/r/comp-292.json +24 -0
- package/public/r/comp-293.json +26 -0
- package/public/r/comp-294.json +24 -0
- package/public/r/comp-295.json +23 -0
- package/public/r/comp-296.json +23 -0
- package/public/r/comp-297.json +30 -0
- package/public/r/comp-298.json +26 -0
- package/public/r/comp-299.json +28 -0
- package/public/r/comp-30.json +23 -0
- package/public/r/comp-300.json +29 -0
- package/public/r/comp-301.json +24 -0
- package/public/r/comp-302.json +18 -0
- package/public/r/comp-303.json +18 -0
- package/public/r/comp-304.json +18 -0
- package/public/r/comp-305.json +21 -0
- package/public/r/comp-306.json +21 -0
- package/public/r/comp-307.json +21 -0
- package/public/r/comp-308.json +21 -0
- package/public/r/comp-309.json +21 -0
- package/public/r/comp-31.json +21 -0
- package/public/r/comp-310.json +23 -0
- package/public/r/comp-311.json +20 -0
- package/public/r/comp-312.json +21 -0
- package/public/r/comp-313.json +26 -0
- package/public/r/comp-314.json +26 -0
- package/public/r/comp-315.json +24 -0
- package/public/r/comp-316.json +25 -0
- package/public/r/comp-317.json +24 -0
- package/public/r/comp-318.json +24 -0
- package/public/r/comp-319.json +24 -0
- package/public/r/comp-32.json +21 -0
- package/public/r/comp-320.json +27 -0
- package/public/r/comp-321.json +28 -0
- package/public/r/comp-322.json +27 -0
- package/public/r/comp-323.json +30 -0
- package/public/r/comp-324.json +28 -0
- package/public/r/comp-325.json +29 -0
- package/public/r/comp-326.json +30 -0
- package/public/r/comp-327.json +30 -0
- package/public/r/comp-328.json +37 -0
- package/public/r/comp-329.json +38 -0
- package/public/r/comp-33.json +18 -0
- package/public/r/comp-330.json +27 -0
- package/public/r/comp-331.json +42 -0
- package/public/r/comp-332.json +25 -0
- package/public/r/comp-333.json +29 -0
- package/public/r/comp-334.json +22 -0
- package/public/r/comp-335.json +22 -0
- package/public/r/comp-336.json +22 -0
- package/public/r/comp-337.json +22 -0
- package/public/r/comp-338.json +22 -0
- package/public/r/comp-339.json +22 -0
- package/public/r/comp-34.json +27 -0
- package/public/r/comp-340.json +22 -0
- package/public/r/comp-341.json +22 -0
- package/public/r/comp-342.json +22 -0
- package/public/r/comp-343.json +22 -0
- package/public/r/comp-344.json +22 -0
- package/public/r/comp-345.json +22 -0
- package/public/r/comp-346.json +22 -0
- package/public/r/comp-347.json +22 -0
- package/public/r/comp-348.json +22 -0
- package/public/r/comp-349.json +22 -0
- package/public/r/comp-35.json +27 -0
- package/public/r/comp-350.json +22 -0
- package/public/r/comp-351.json +22 -0
- package/public/r/comp-352.json +24 -0
- package/public/r/comp-353.json +24 -0
- package/public/r/comp-354.json +23 -0
- package/public/r/comp-355.json +23 -0
- package/public/r/comp-356.json +23 -0
- package/public/r/comp-357.json +23 -0
- package/public/r/comp-358.json +23 -0
- package/public/r/comp-359.json +24 -0
- package/public/r/comp-36.json +26 -0
- package/public/r/comp-360.json +25 -0
- package/public/r/comp-361.json +23 -0
- package/public/r/comp-362.json +24 -0
- package/public/r/comp-363.json +27 -0
- package/public/r/comp-364.json +26 -0
- package/public/r/comp-365.json +24 -0
- package/public/r/comp-366.json +23 -0
- package/public/r/comp-367.json +23 -0
- package/public/r/comp-368.json +23 -0
- package/public/r/comp-369.json +23 -0
- package/public/r/comp-37.json +23 -0
- package/public/r/comp-370.json +23 -0
- package/public/r/comp-371.json +24 -0
- package/public/r/comp-372.json +24 -0
- package/public/r/comp-373.json +25 -0
- package/public/r/comp-374.json +26 -0
- package/public/r/comp-375.json +25 -0
- package/public/r/comp-376.json +26 -0
- package/public/r/comp-377.json +27 -0
- package/public/r/comp-378.json +24 -0
- package/public/r/comp-379.json +24 -0
- package/public/r/comp-38.json +23 -0
- package/public/r/comp-380.json +24 -0
- package/public/r/comp-381.json +26 -0
- package/public/r/comp-382.json +25 -0
- package/public/r/comp-383.json +26 -0
- package/public/r/comp-384.json +24 -0
- package/public/r/comp-385.json +24 -0
- package/public/r/comp-386.json +24 -0
- package/public/r/comp-387.json +28 -0
- package/public/r/comp-388.json +26 -0
- package/public/r/comp-389.json +24 -0
- package/public/r/comp-39.json +23 -0
- package/public/r/comp-390.json +23 -0
- package/public/r/comp-391.json +23 -0
- package/public/r/comp-392.json +23 -0
- package/public/r/comp-393.json +23 -0
- package/public/r/comp-394.json +24 -0
- package/public/r/comp-395.json +24 -0
- package/public/r/comp-396.json +24 -0
- package/public/r/comp-397.json +25 -0
- package/public/r/comp-398.json +26 -0
- package/public/r/comp-399.json +26 -0
- package/public/r/comp-40.json +23 -0
- package/public/r/comp-400.json +20 -0
- package/public/r/comp-401.json +19 -0
- package/public/r/comp-402.json +19 -0
- package/public/r/comp-403.json +19 -0
- package/public/r/comp-404.json +19 -0
- package/public/r/comp-405.json +19 -0
- package/public/r/comp-406.json +19 -0
- package/public/r/comp-407.json +19 -0
- package/public/r/comp-408.json +19 -0
- package/public/r/comp-409.json +22 -0
- package/public/r/comp-41.json +29 -0
- package/public/r/comp-410.json +22 -0
- package/public/r/comp-411.json +22 -0
- package/public/r/comp-412.json +19 -0
- package/public/r/comp-413.json +22 -0
- package/public/r/comp-414.json +22 -0
- package/public/r/comp-415.json +22 -0
- package/public/r/comp-416.json +23 -0
- package/public/r/comp-417.json +22 -0
- package/public/r/comp-418.json +23 -0
- package/public/r/comp-419.json +23 -0
- package/public/r/comp-42.json +30 -0
- package/public/r/comp-420.json +23 -0
- package/public/r/comp-421.json +23 -0
- package/public/r/comp-422.json +23 -0
- package/public/r/comp-423.json +24 -0
- package/public/r/comp-424.json +22 -0
- package/public/r/comp-425.json +23 -0
- package/public/r/comp-426.json +23 -0
- package/public/r/comp-427.json +23 -0
- package/public/r/comp-428.json +23 -0
- package/public/r/comp-429.json +23 -0
- package/public/r/comp-43.json +32 -0
- package/public/r/comp-430.json +23 -0
- package/public/r/comp-431.json +23 -0
- package/public/r/comp-432.json +23 -0
- package/public/r/comp-433.json +24 -0
- package/public/r/comp-434.json +24 -0
- package/public/r/comp-435.json +24 -0
- package/public/r/comp-436.json +24 -0
- package/public/r/comp-437.json +25 -0
- package/public/r/comp-438.json +23 -0
- package/public/r/comp-439.json +24 -0
- package/public/r/comp-44.json +25 -0
- package/public/r/comp-440.json +25 -0
- package/public/r/comp-441.json +25 -0
- package/public/r/comp-442.json +24 -0
- package/public/r/comp-443.json +24 -0
- package/public/r/comp-444.json +24 -0
- package/public/r/comp-445.json +24 -0
- package/public/r/comp-446.json +24 -0
- package/public/r/comp-447.json +25 -0
- package/public/r/comp-448.json +23 -0
- package/public/r/comp-449.json +23 -0
- package/public/r/comp-45.json +25 -0
- package/public/r/comp-450.json +23 -0
- package/public/r/comp-451.json +23 -0
- package/public/r/comp-452.json +23 -0
- package/public/r/comp-453.json +25 -0
- package/public/r/comp-454.json +22 -0
- package/public/r/comp-455.json +22 -0
- package/public/r/comp-456.json +22 -0
- package/public/r/comp-457.json +21 -0
- package/public/r/comp-458.json +22 -0
- package/public/r/comp-459.json +26 -0
- package/public/r/comp-46.json +26 -0
- package/public/r/comp-460.json +26 -0
- package/public/r/comp-461.json +27 -0
- package/public/r/comp-462.json +27 -0
- package/public/r/comp-463.json +30 -0
- package/public/r/comp-464.json +29 -0
- package/public/r/comp-465.json +29 -0
- package/public/r/comp-466.json +21 -0
- package/public/r/comp-467.json +23 -0
- package/public/r/comp-468.json +21 -0
- package/public/r/comp-469.json +21 -0
- package/public/r/comp-47.json +32 -0
- package/public/r/comp-470.json +21 -0
- package/public/r/comp-471.json +21 -0
- package/public/r/comp-472.json +23 -0
- package/public/r/comp-473.json +24 -0
- package/public/r/comp-474.json +22 -0
- package/public/r/comp-475.json +22 -0
- package/public/r/comp-476.json +21 -0
- package/public/r/comp-477.json +31 -0
- package/public/r/comp-478.json +36 -0
- package/public/r/comp-479.json +28 -0
- package/public/r/comp-48.json +32 -0
- package/public/r/comp-480.json +30 -0
- package/public/r/comp-481.json +34 -0
- package/public/r/comp-482.json +33 -0
- package/public/r/comp-483.json +37 -0
- package/public/r/comp-484.json +41 -0
- package/public/r/comp-485.json +43 -0
- package/public/r/comp-486.json +23 -0
- package/public/r/comp-487.json +26 -0
- package/public/r/comp-488.json +27 -0
- package/public/r/comp-489.json +28 -0
- package/public/r/comp-49.json +32 -0
- package/public/r/comp-490.json +23 -0
- package/public/r/comp-491.json +24 -0
- package/public/r/comp-492.json +25 -0
- package/public/r/comp-493.json +23 -0
- package/public/r/comp-494.json +23 -0
- package/public/r/comp-495.json +24 -0
- package/public/r/comp-496.json +23 -0
- package/public/r/comp-497.json +24 -0
- package/public/r/comp-498.json +24 -0
- package/public/r/comp-499.json +24 -0
- package/public/r/comp-50.json +32 -0
- package/public/r/comp-500.json +25 -0
- package/public/r/comp-501.json +25 -0
- package/public/r/comp-502.json +26 -0
- package/public/r/comp-503.json +27 -0
- package/public/r/comp-504.json +28 -0
- package/public/r/comp-505.json +28 -0
- package/public/r/comp-506.json +26 -0
- package/public/r/comp-507.json +27 -0
- package/public/r/comp-508.json +25 -0
- package/public/r/comp-509.json +25 -0
- package/public/r/comp-51.json +23 -0
- package/public/r/comp-510.json +24 -0
- package/public/r/comp-511.json +27 -0
- package/public/r/comp-512.json +27 -0
- package/public/r/comp-513.json +21 -0
- package/public/r/comp-514.json +21 -0
- package/public/r/comp-515.json +21 -0
- package/public/r/comp-516.json +22 -0
- package/public/r/comp-517.json +22 -0
- package/public/r/comp-518.json +21 -0
- package/public/r/comp-519.json +21 -0
- package/public/r/comp-52.json +23 -0
- package/public/r/comp-520.json +22 -0
- package/public/r/comp-521.json +22 -0
- package/public/r/comp-522.json +21 -0
- package/public/r/comp-523.json +21 -0
- package/public/r/comp-524.json +21 -0
- package/public/r/comp-525.json +21 -0
- package/public/r/comp-526.json +22 -0
- package/public/r/comp-527.json +23 -0
- package/public/r/comp-528.json +22 -0
- package/public/r/comp-529.json +22 -0
- package/public/r/comp-53.json +24 -0
- package/public/r/comp-530.json +22 -0
- package/public/r/comp-531.json +22 -0
- package/public/r/comp-532.json +22 -0
- package/public/r/comp-533.json +22 -0
- package/public/r/comp-534.json +22 -0
- package/public/r/comp-535.json +22 -0
- package/public/r/comp-536.json +22 -0
- package/public/r/comp-537.json +22 -0
- package/public/r/comp-538.json +22 -0
- package/public/r/comp-539.json +22 -0
- package/public/r/comp-54.json +26 -0
- package/public/r/comp-540.json +21 -0
- package/public/r/comp-541.json +21 -0
- package/public/r/comp-542.json +124 -0
- package/public/r/comp-543.json +29 -0
- package/public/r/comp-544.json +26 -0
- package/public/r/comp-545.json +29 -0
- package/public/r/comp-546.json +29 -0
- package/public/r/comp-547.json +29 -0
- package/public/r/comp-548.json +29 -0
- package/public/r/comp-549.json +29 -0
- package/public/r/comp-55.json +27 -0
- package/public/r/comp-550.json +29 -0
- package/public/r/comp-551.json +30 -0
- package/public/r/comp-552.json +29 -0
- package/public/r/comp-553.json +29 -0
- package/public/r/comp-554.json +36 -0
- package/public/r/comp-555.json +23 -0
- package/public/r/comp-556.json +23 -0
- package/public/r/comp-557.json +23 -0
- package/public/r/comp-558.json +23 -0
- package/public/r/comp-559.json +23 -0
- package/public/r/comp-56.json +26 -0
- package/public/r/comp-560.json +23 -0
- package/public/r/comp-561.json +25 -0
- package/public/r/comp-562.json +23 -0
- package/public/r/comp-563.json +23 -0
- package/public/r/comp-564.json +24 -0
- package/public/r/comp-565.json +20 -0
- package/public/r/comp-566.json +20 -0
- package/public/r/comp-567.json +20 -0
- package/public/r/comp-568.json +20 -0
- package/public/r/comp-569.json +20 -0
- package/public/r/comp-57.json +26 -0
- package/public/r/comp-570.json +20 -0
- package/public/r/comp-571.json +23 -0
- package/public/r/comp-572.json +23 -0
- package/public/r/comp-573.json +20 -0
- package/public/r/comp-574.json +22 -0
- package/public/r/comp-575.json +20 -0
- package/public/r/comp-576.json +21 -0
- package/public/r/comp-577.json +23 -0
- package/public/r/comp-578.json +28 -0
- package/public/r/comp-579.json +28 -0
- package/public/r/comp-58.json +25 -0
- package/public/r/comp-580.json +29 -0
- package/public/r/comp-581.json +45 -0
- package/public/r/comp-582.json +42 -0
- package/public/r/comp-583.json +41 -0
- package/public/r/comp-584.json +41 -0
- package/public/r/comp-585.json +41 -0
- package/public/r/comp-586.json +34 -0
- package/public/r/comp-587.json +29 -0
- package/public/r/comp-588.json +33 -0
- package/public/r/comp-589.json +37 -0
- package/public/r/comp-59.json +22 -0
- package/public/r/comp-590.json +40 -0
- package/public/r/comp-591.json +29 -0
- package/public/r/comp-592.json +41 -0
- package/public/r/comp-593.json +36 -0
- package/public/r/comp-594.json +33 -0
- package/public/r/comp-595.json +22 -0
- package/public/r/comp-596.json +26 -0
- package/public/r/comp-597.json +22 -0
- package/public/r/comp-598.json +22 -0
- package/public/r/comp-599.json +22 -0
- package/public/r/comp-60.json +23 -0
- package/public/r/comp-600.json +17 -0
- package/public/r/comp-601.json +20 -0
- package/public/r/comp-602.json +17 -0
- package/public/r/comp-603.json +20 -0
- package/public/r/comp-604.json +17 -0
- package/public/r/comp-605.json +17 -0
- package/public/r/comp-606.json +20 -0
- package/public/r/comp-607.json +20 -0
- package/public/r/comp-608.json +20 -0
- package/public/r/comp-609.json +20 -0
- package/public/r/comp-61.json +23 -0
- package/public/r/comp-610.json +23 -0
- package/public/r/comp-611.json +23 -0
- package/public/r/comp-612.json +17 -0
- package/public/r/comp-613.json +20 -0
- package/public/r/comp-614.json +17 -0
- package/public/r/comp-615.json +26 -0
- package/public/r/comp-616.json +26 -0
- package/public/r/comp-617.json +26 -0
- package/public/r/comp-62.json +23 -0
- package/public/r/comp-63.json +22 -0
- package/public/r/comp-64.json +23 -0
- package/public/r/comp-65.json +22 -0
- package/public/r/comp-66.json +22 -0
- package/public/r/comp-67.json +23 -0
- package/public/r/comp-68.json +24 -0
- package/public/r/comp-69.json +24 -0
- package/public/r/comp-70.json +24 -0
- package/public/r/comp-71.json +22 -0
- package/public/r/comp-72.json +21 -0
- package/public/r/comp-73.json +18 -0
- package/public/r/comp-74.json +27 -0
- package/public/r/comp-75.json +22 -0
- package/public/r/comp-76.json +23 -0
- package/public/r/comp-77.json +22 -0
- package/public/r/comp-78.json +21 -0
- package/public/r/comp-79.json +22 -0
- package/public/r/comp-80.json +21 -0
- package/public/r/comp-81.json +21 -0
- package/public/r/comp-82.json +22 -0
- package/public/r/comp-83.json +21 -0
- package/public/r/comp-84.json +21 -0
- package/public/r/comp-85.json +22 -0
- package/public/r/comp-86.json +22 -0
- package/public/r/comp-87.json +21 -0
- package/public/r/comp-88.json +22 -0
- package/public/r/comp-89.json +21 -0
- package/public/r/comp-90.json +22 -0
- package/public/r/comp-91.json +22 -0
- package/public/r/comp-92.json +22 -0
- package/public/r/comp-93.json +22 -0
- package/public/r/comp-94.json +24 -0
- package/public/r/comp-95.json +26 -0
- package/public/r/comp-96.json +21 -0
- package/public/r/comp-97.json +21 -0
- package/public/r/comp-98.json +22 -0
- package/public/r/comp-99.json +23 -0
- package/public/r/comparison-event-handlers.json +1 -1
- package/public/r/comparison-hover.json +1 -1
- package/public/r/comparison.json +1 -1
- package/public/r/context-menu.json +16 -0
- package/public/r/contribution-graph-custom-footer.json +1 -1
- package/public/r/credit-card-apple.json +1 -1
- package/public/r/credit-card-back.json +1 -1
- package/public/r/credit-card.json +1 -1
- package/public/r/cropper.json +15 -0
- package/public/r/cursor-color.json +1 -1
- package/public/r/cursor-message.json +1 -1
- package/public/r/cursor-name-message.json +1 -1
- package/public/r/cursor-name.json +1 -1
- package/public/r/cursor.json +1 -1
- package/public/r/dashboard-1.json +263 -0
- package/public/r/dashboard-2.json +264 -0
- package/public/r/dashboard-3.json +225 -0
- package/public/r/datefield-rac.json +15 -0
- package/public/r/deck-controlled.json +1 -1
- package/public/r/deck-product-cards.json +1 -1
- package/public/r/deck.json +1 -1
- package/public/r/dialog-close-confirmation.json +1 -1
- package/public/r/dialog-demo.json +1 -1
- package/public/r/dialog-from-menu.json +1 -1
- package/public/r/dialog-nested.json +1 -1
- package/public/r/dialog-stack-controlled.json +1 -1
- package/public/r/dialog-stack-navigation.json +1 -1
- package/public/r/dialog-stack-six.json +1 -1
- package/public/r/dialog-stack.json +1 -1
- package/public/r/dropdown-menu.json +15 -0
- package/public/r/dropzone-custom-empty-state.json +1 -1
- package/public/r/dropzone-image-preview.json +1 -1
- package/public/r/editor.json +1 -1
- package/public/r/emails.json +243 -0
- package/public/r/empty-demo.json +1 -1
- package/public/r/example-app-calendar.json +323 -0
- package/public/r/field-2.json +19 -0
- package/public/r/field-autocomplete.json +1 -1
- package/public/r/field-checkbox-group.json +1 -1
- package/public/r/field-checkbox.json +1 -1
- package/public/r/field-combobox-multiple.json +1 -1
- package/public/r/field-combobox.json +1 -1
- package/public/r/field-complete-form.json +1 -1
- package/public/r/field-demo.json +1 -1
- package/public/r/field-disabled.json +1 -1
- package/public/r/field-error.json +1 -1
- package/public/r/field-number-field.json +1 -1
- package/public/r/field-radio.json +1 -1
- package/public/r/field-required.json +1 -1
- package/public/r/field-select.json +1 -1
- package/public/r/field-slider.json +1 -1
- package/public/r/field-switch.json +1 -1
- package/public/r/field-textarea.json +1 -1
- package/public/r/field-validity.json +1 -1
- package/public/r/fieldset-demo.json +1 -1
- package/public/r/files.json +195 -0
- package/public/r/form-demo.json +1 -1
- package/public/r/form-zod.json +1 -1
- package/public/r/form.json +1 -1
- package/public/r/frame-demo.json +1 -1
- package/public/r/gantt-lanes.json +1 -1
- package/public/r/gantt-no-sidebar.json +1 -1
- package/public/r/gantt-read-only.json +1 -1
- package/public/r/gantt.json +1 -1
- package/public/r/glimpse-custom.json +1 -1
- package/public/r/glimpse.json +1 -1
- package/public/r/gooey-toast-demo.json +1 -1
- package/public/r/gooey-toast-promise.json +1 -1
- package/public/r/gooey-toast-states.json +1 -1
- package/public/r/gooey-toast-with-button.json +1 -1
- package/public/r/group-demo.json +1 -1
- package/public/r/group-with-input.json +1 -1
- package/public/r/hero.json +1 -1
- package/public/r/hover-card.json +15 -0
- package/public/r/image-crop-circular.json +1 -1
- package/public/r/image-crop-custom.json +1 -1
- package/public/r/image-crop.json +1 -1
- package/public/r/image-zoom-background.json +1 -1
- package/public/r/image-zoom-margin.json +1 -1
- package/public/r/image-zoom.json +1 -1
- package/public/r/input-demo.json +1 -1
- package/public/r/input-disabled.json +1 -1
- package/public/r/input-file.json +1 -1
- package/public/r/input-group.json +20 -0
- package/public/r/input-lg.json +1 -1
- package/public/r/input-sm.json +1 -1
- package/public/r/input-with-button.json +1 -1
- package/public/r/input-with-label.json +1 -1
- package/public/r/kanban-simple.json +1 -1
- package/public/r/kanban.json +1 -1
- package/public/r/kbd.json +12 -0
- package/public/r/leads.json +271 -0
- package/public/r/list-simple.json +1 -1
- package/public/r/list.json +1 -1
- package/public/r/maps.json +188 -0
- package/public/r/menu-checkbox.json +1 -1
- package/public/r/menu-close-on-click.json +1 -1
- package/public/r/menu-demo.json +1 -1
- package/public/r/menu-group-labels.json +1 -1
- package/public/r/menu-hover.json +1 -1
- package/public/r/menu-link.json +1 -1
- package/public/r/menu-nested.json +1 -1
- package/public/r/menu-radio-group.json +1 -1
- package/public/r/meter-demo.json +1 -1
- package/public/r/meter-with-formatted-value.json +1 -1
- package/public/r/meter-with-range.json +1 -1
- package/public/r/mini-calendar-controlled.json +1 -1
- package/public/r/multiselect.json +15 -0
- package/public/r/navigation-menu.json +12 -0
- package/public/r/number-field-form.json +1 -1
- package/public/r/number-field-with-label.json +1 -1
- package/public/r/number-field-with-scrub.json +1 -1
- package/public/r/number-field-with-step.json +1 -1
- package/public/r/pill-avatar-group.json +1 -1
- package/public/r/pill-delta.json +1 -1
- package/public/r/pill-icon.json +1 -1
- package/public/r/pill-indicator.json +1 -1
- package/public/r/pill-status.json +1 -1
- package/public/r/pill.json +1 -1
- package/public/r/popover-demo.json +1 -1
- package/public/r/popover-with-close.json +1 -1
- package/public/r/preview-card-demo.json +1 -1
- package/public/r/pricing.json +1 -1
- package/public/r/progress-with-formatted-value.json +1 -1
- package/public/r/progress-with-label-value.json +1 -1
- package/public/r/radio-group-card.json +1 -1
- package/public/r/radio-group-demo.json +1 -1
- package/public/r/radio-group-disabled.json +1 -1
- package/public/r/radio-group-form.json +1 -1
- package/public/r/radio-group-with-description.json +1 -1
- package/public/r/reel-custom.json +1 -1
- package/public/r/reel-images.json +1 -1
- package/public/r/reel-minimal.json +1 -1
- package/public/r/reel.json +1 -1
- package/public/r/registry.json +18217 -0
- package/public/r/relative-time-controlled.json +1 -1
- package/public/r/relative-time-format-date.json +1 -1
- package/public/r/relative-time-format-time.json +1 -1
- package/public/r/relative-time.json +1 -1
- package/public/r/rentals.json +187 -0
- package/public/r/roadmap.json +1 -1
- package/public/r/sandbox-no-file-explorer.json +1 -1
- package/public/r/sandbox.json +1 -1
- package/public/r/scroll-area-both.json +1 -1
- package/public/r/scroll-area-demo.json +1 -1
- package/public/r/scroll-area-horizontal.json +1 -1
- package/public/r/select-demo.json +1 -1
- package/public/r/select-disabled.json +1 -1
- package/public/r/select-form.json +1 -1
- package/public/r/select-lg.json +1 -1
- package/public/r/select-native.json +12 -0
- package/public/r/select-sm.json +1 -1
- package/public/r/select-with-groups.json +1 -1
- package/public/r/select-without-alignment.json +1 -1
- package/public/r/select.json +1 -1
- package/public/r/separator-demo.json +1 -1
- package/public/r/sheet-demo.json +1 -1
- package/public/r/sheet-position.json +1 -1
- package/public/r/sidebar-nav.json +22 -0
- package/public/r/skeleton-demo.json +1 -1
- package/public/r/skeleton.json +1 -1
- package/public/r/slider-form.json +1 -1
- package/public/r/slider-with-label-value.json +1 -1
- package/public/r/sonner.json +16 -0
- package/public/r/stats-card.json +22 -0
- package/public/r/status-custom.json +1 -1
- package/public/r/stepper.json +15 -0
- package/public/r/stories-images.json +1 -1
- package/public/r/switch-card.json +1 -1
- package/public/r/switch-demo.json +1 -1
- package/public/r/switch-disabled.json +1 -1
- package/public/r/switch-form.json +1 -1
- package/public/r/switch-with-description.json +1 -1
- package/public/r/table-demo.json +1 -1
- package/public/r/table-framed.json +1 -1
- package/public/r/table-simple.json +1 -1
- package/public/r/table.json +1 -1
- package/public/r/tabs-demo.json +1 -1
- package/public/r/tabs-underline-vertical.json +1 -1
- package/public/r/tabs-underline.json +1 -1
- package/public/r/tabs-vertical.json +1 -1
- package/public/r/tags-create.json +1 -1
- package/public/r/tags-filter.json +1 -1
- package/public/r/tags.json +1 -1
- package/public/r/template-auth-eight.json +28 -0
- package/public/r/template-auth-five.json +28 -0
- package/public/r/template-auth-four.json +29 -0
- package/public/r/template-auth-nine.json +28 -0
- package/public/r/template-auth-one.json +49 -0
- package/public/r/template-auth-seven.json +29 -0
- package/public/r/template-auth-six.json +28 -0
- package/public/r/template-auth-three.json +49 -0
- package/public/r/template-auth-two.json +44 -0
- package/public/r/template-hero-eight.json +83 -0
- package/public/r/template-hero-eleven.json +29 -0
- package/public/r/template-hero-five.json +35 -0
- package/public/r/template-hero-four.json +35 -0
- package/public/r/template-hero-fourteen.json +101 -0
- package/public/r/template-hero-nine.json +74 -0
- package/public/r/template-hero-one.json +90 -0
- package/public/r/template-hero-seven.json +83 -0
- package/public/r/template-hero-six.json +83 -0
- package/public/r/template-hero-ten.json +77 -0
- package/public/r/template-hero-thirteen.json +101 -0
- package/public/r/template-hero-three.json +35 -0
- package/public/r/template-hero-twelve.json +30 -0
- package/public/r/template-hero-two.json +96 -0
- package/public/r/template-logo-cloud-five.json +68 -0
- package/public/r/template-logo-cloud-four.json +71 -0
- package/public/r/template-logo-cloud-one.json +89 -0
- package/public/r/template-logo-cloud-three.json +71 -0
- package/public/r/template-logo-cloud-two.json +74 -0
- package/public/r/textarea-demo.json +1 -1
- package/public/r/textarea-disabled.json +1 -1
- package/public/r/textarea-form.json +1 -1
- package/public/r/textarea-lg.json +1 -1
- package/public/r/textarea-sm.json +1 -1
- package/public/r/textarea-with-label.json +1 -1
- package/public/r/ticker-inline.json +1 -1
- package/public/r/timeline.json +15 -0
- package/public/r/toast-demo.json +1 -1
- package/public/r/toast-heights.json +1 -1
- package/public/r/toast-loading.json +1 -1
- package/public/r/toast-promise.json +1 -1
- package/public/r/toast-with-action.json +1 -1
- package/public/r/toast-with-status.json +1 -1
- package/public/r/toggle-demo.json +1 -1
- package/public/r/toggle-disabled.json +1 -1
- package/public/r/toggle-group-demo.json +1 -1
- package/public/r/toggle-group-disabled.json +1 -1
- package/public/r/toggle-group-lg.json +1 -1
- package/public/r/toggle-group-multiple.json +1 -1
- package/public/r/toggle-group-outline-with-separator.json +1 -1
- package/public/r/toggle-group-outline.json +1 -1
- package/public/r/toggle-group-sm.json +1 -1
- package/public/r/toggle-group-with-disabled-item.json +1 -1
- package/public/r/toggle-icon-group.json +1 -1
- package/public/r/toggle-lg.json +1 -1
- package/public/r/toggle-outline.json +1 -1
- package/public/r/toggle-sm.json +1 -1
- package/public/r/toggle-with-icon.json +1 -1
- package/public/r/toolbar-demo.json +1 -1
- package/public/r/tooltip-demo.json +1 -1
- package/public/r/tooltip-grouped.json +1 -1
- package/public/r/tree-controlled.json +1 -1
- package/public/r/tree-custom-icons.json +1 -1
- package/public/r/tree-no-lines.json +1 -1
- package/public/r/tree-simple.json +1 -1
- package/public/r/tree.json +1 -1
- package/public/r/typography.json +1 -1
- package/public/r/ui.json +5 -0
- package/public/r/use-character-limit.json +12 -0
- package/public/r/use-file-upload.json +12 -0
- package/public/r/use-pagination.json +12 -0
- package/public/r/use-slider-with-input.json +12 -0
- package/public/r/use-toast.json +12 -0
- package/public/r/utils.json +16 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "dashboard-3",
|
|
4
|
+
"type": "registry:block",
|
|
5
|
+
"title": "Modern Dashboard",
|
|
6
|
+
"description": "A modern dashboard design with clean layout and intuitive navigation",
|
|
7
|
+
"files": [
|
|
8
|
+
{
|
|
9
|
+
"path": "registry/example-apps/default/dashboard-3/components/dashboard/content.tsx",
|
|
10
|
+
"type": "registry:component",
|
|
11
|
+
"target": "components/example-apps/dashboard-3/components/dashboard/content.tsx",
|
|
12
|
+
"content": "\"use client\"\n\nimport { Add01Icon, Download01Icon } from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\n\nimport { Button } from \"@loveui/ui/ui/button\"\n\nimport { welcomeSummary } from \"../../mock-data/dashboard\"\nimport { PerformanceChart } from \"./performance-chart\"\nimport { ProjectsTable } from \"./projects-table\"\nimport { StatsCards } from \"./stats-cards\"\nimport { TodaysTasks } from \"./todays-tasks\"\n\nfunction WelcomeSection() {\n const { userName, tasksDueToday, overdueTasks, upcomingDeadlines } =\n welcomeSummary\n\n return (\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div>\n <h1 className=\"text-xl font-semibold tracking-tight sm:text-2xl\">\n Semester operations overview, {userName}\n </h1>\n <p className=\"mt-0.5 text-sm text-muted-foreground\">\n {tasksDueToday} Tasks Due Today, {overdueTasks} Overdue Tasks,{\" \"}\n {upcomingDeadlines} Upcoming Deadlines (Next 7 Days)\n </p>\n </div>\n <div className=\"flex items-center gap-2\">\n <Button variant=\"outline\" size=\"sm\" className=\"h-9 gap-1.5\">\n <HugeiconsIcon icon={Download01Icon} className=\"size-4\" />\n Export Roster\n </Button>\n <Button\n size=\"sm\"\n className=\"h-9 gap-1.5 bg-primary hover:bg-primary/90\"\n >\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n New Course Task\n </Button>\n </div>\n </div>\n )\n}\n\nexport function DashboardContent() {\n return (\n <main className=\"h-full w-full overflow-x-hidden overflow-y-auto p-4\">\n <div className=\"mx-auto w-full space-y-6\">\n <WelcomeSection />\n <StatsCards />\n <div className=\"grid grid-cols-1 gap-4 sm:gap-6 lg:grid-cols-3\">\n <div className=\"lg:col-span-2\">\n <TodaysTasks />\n </div>\n <div>\n <PerformanceChart />\n </div>\n </div>\n <ProjectsTable />\n </div>\n </main>\n )\n}\n"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"path": "registry/example-apps/default/dashboard-3/components/dashboard/header.tsx",
|
|
16
|
+
"type": "registry:component",
|
|
17
|
+
"target": "components/example-apps/dashboard-3/components/dashboard/header.tsx",
|
|
18
|
+
"content": "\"use client\"\n\nimport { Folder01Icon, Share01Icon } from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@loveui/ui/ui/avatar\"\nimport { Button } from \"@loveui/ui/ui/button\"\n\nimport { lastUpdated } from \"../../mock-data/dashboard\"\nimport { ThemeToggle } from \"../theme-toggle\"\nimport { SidebarTrigger } from \"../ui/sidebar\"\n\nexport function DashboardHeader() {\n return (\n <header className=\"sticky top-0 z-10 flex w-full shrink-0 items-center justify-between gap-4 border-b bg-card px-4 py-3 sm:px-6\">\n <div className=\"flex items-center gap-3\">\n <SidebarTrigger className=\"-ml-2\" />\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <HugeiconsIcon icon={Folder01Icon} className=\"size-4\" />\n <span className=\"text-sm font-medium\">Academic Operations</span>\n </div>\n </div>\n\n <div className=\"flex items-center gap-2 sm:gap-3\">\n <span className=\"hidden text-xs text-muted-foreground sm:inline\">\n Last Updated {lastUpdated}\n </span>\n <div className=\"flex -space-x-2\">\n <Avatar className=\"size-7 border-2 border-card\">\n <AvatarImage src=\"https://api.dicebear.com/9.x/glass/svg?seed=a\" />\n <AvatarFallback>A</AvatarFallback>\n </Avatar>\n <Avatar className=\"size-7 border-2 border-card\">\n <AvatarImage src=\"https://api.dicebear.com/9.x/glass/svg?seed=b\" />\n <AvatarFallback>B</AvatarFallback>\n </Avatar>\n <Avatar className=\"size-7 border-2 border-card\">\n <AvatarImage src=\"https://api.dicebear.com/9.x/glass/svg?seed=c\" />\n <AvatarFallback>C</AvatarFallback>\n </Avatar>\n </div>\n <Button variant=\"outline\" size=\"sm\" className=\"h-8 gap-1.5\">\n <HugeiconsIcon icon={Share01Icon} className=\"size-3.5\" />\n <span className=\"hidden sm:inline\">Share</span>\n </Button>\n <ThemeToggle />\n </div>\n </header>\n )\n}\n"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"path": "registry/example-apps/default/dashboard-3/components/dashboard/performance-chart.tsx",
|
|
22
|
+
"type": "registry:component",
|
|
23
|
+
"target": "components/example-apps/dashboard-3/components/dashboard/performance-chart.tsx",
|
|
24
|
+
"content": "\"use client\"\n\nimport { useState } from \"react\"\nimport { MoreVerticalIcon } from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport {\n Bar,\n BarChart,\n CartesianGrid,\n Cell,\n Line,\n LineChart,\n XAxis,\n YAxis,\n} from \"recharts\"\n\nimport { Button } from \"@loveui/ui/ui/button\"\nimport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n} from \"@loveui/ui/ui/chart\"\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuSub,\n DropdownMenuSubContent,\n DropdownMenuSubTrigger,\n DropdownMenuTrigger,\n} from \"@loveui/ui/ui/menu\"\n\nimport {\n performanceChange,\n performanceChartData,\n performanceScore,\n} from \"../../mock-data/dashboard\"\n\ntype ChartType = \"bar\" | \"line\"\ntype Period = \"7d\" | \"30d\"\n\nconst barColors = [\n \"var(--muted-foreground)\",\n \"var(--muted-foreground)\",\n \"var(--foreground)\",\n \"var(--muted-foreground)\",\n \"var(--muted-foreground)\",\n \"var(--muted-foreground)\",\n]\n\nconst chartConfig = {\n value: {\n label: \"Performance\",\n },\n}\n\nexport function PerformanceChart() {\n const [chartType, setChartType] = useState<ChartType>(\"bar\")\n const [period, setPeriod] = useState<Period>(\"7d\")\n const [showGrid, setShowGrid] = useState(true)\n const [smoothCurve, setSmoothCurve] = useState(true)\n\n const resetToDefault = () => {\n setChartType(\"bar\")\n setPeriod(\"7d\")\n setShowGrid(true)\n setSmoothCurve(true)\n }\n\n // Pour l'instant, on garde les mêmes données quel que soit period\n const data = performanceChartData\n\n return (\n <div className=\"overflow-hidden rounded-xl border border-border bg-card\">\n <div className=\"flex flex-col gap-3 border-b px-4 py-3 sm:flex-row sm:items-center sm:justify-between\">\n <h3 className=\"text-base font-medium\">Course Completion Score</h3>\n <DropdownMenu>\n <DropdownMenuTrigger\n render={\n <Button variant=\"ghost\" size=\"icon\" className=\"size-8\">\n <HugeiconsIcon icon={MoreVerticalIcon} className=\"size-4\" />\n </Button>\n }\n />\n <DropdownMenuContent align=\"end\" className=\"w-52\">\n <DropdownMenuSub>\n <DropdownMenuSubTrigger>Chart Type</DropdownMenuSubTrigger>\n <DropdownMenuSubContent>\n <DropdownMenuItem onClick={() => setChartType(\"bar\")}>\n Bar Chart {chartType === \"bar\" && \"✓\"}\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => setChartType(\"line\")}>\n Line Chart {chartType === \"line\" && \"✓\"}\n </DropdownMenuItem>\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n <DropdownMenuSub>\n <DropdownMenuSubTrigger>Time Period</DropdownMenuSubTrigger>\n <DropdownMenuSubContent>\n <DropdownMenuItem onClick={() => setPeriod(\"7d\")}>\n Last 7 days {period === \"7d\" && \"✓\"}\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => setPeriod(\"30d\")}>\n Last 30 days {period === \"30d\" && \"✓\"}\n </DropdownMenuItem>\n </DropdownMenuSubContent>\n </DropdownMenuSub>\n <DropdownMenuSeparator />\n <DropdownMenuCheckboxItem\n checked={showGrid}\n onCheckedChange={(value) => setShowGrid(!!value)}\n >\n Show Grid\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n checked={smoothCurve}\n onCheckedChange={(value) => setSmoothCurve(!!value)}\n disabled={chartType === \"bar\"}\n >\n Smooth Curve\n </DropdownMenuCheckboxItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={resetToDefault}>\n Reset to Default\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n <div className=\"p-4\">\n <div className=\"mb-4 flex items-baseline gap-2\">\n <span className=\"text-3xl font-semibold\">{performanceScore}%</span>\n <span className=\"text-sm text-muted-foreground\">\n +{performanceChange}% vs previous week\n </span>\n </div>\n <ChartContainer config={chartConfig} className=\"h-[175px] w-full\">\n {chartType === \"bar\" ? (\n <BarChart\n data={data}\n margin={{ top: 8, right: 8, left: 8, bottom: 0 }}\n >\n {showGrid && (\n <CartesianGrid\n strokeDasharray=\"3 3\"\n stroke=\"var(--border)\"\n vertical={false}\n />\n )}\n <XAxis\n dataKey=\"day\"\n tickLine={false}\n axisLine={false}\n tick={{ fontSize: 11 }}\n />\n <YAxis hide domain={[0, 100]} />\n <ChartTooltip content={<ChartTooltipContent />} />\n <Bar dataKey=\"value\" radius={[4, 4, 0, 0]} strokeWidth={0}>\n {data.map((entry, index) => (\n <Cell key={entry.day} fill={barColors[index]} />\n ))}\n </Bar>\n </BarChart>\n ) : (\n <LineChart\n data={data}\n margin={{ top: 8, right: 8, left: 8, bottom: 0 }}\n >\n {showGrid && (\n <CartesianGrid\n strokeDasharray=\"3 3\"\n stroke=\"var(--border)\"\n vertical={false}\n />\n )}\n <XAxis\n dataKey=\"day\"\n tickLine={false}\n axisLine={false}\n tick={{ fontSize: 11 }}\n />\n <YAxis hide domain={[0, 100]} />\n <ChartTooltip content={<ChartTooltipContent />} />\n <Line\n type={smoothCurve ? \"monotone\" : \"linear\"}\n dataKey=\"value\"\n stroke=\"var(--foreground)\"\n strokeWidth={2}\n dot={false}\n activeDot={{\n r: 6,\n fill: \"var(--foreground)\",\n stroke: \"var(--card)\",\n strokeWidth: 2,\n }}\n />\n </LineChart>\n )}\n </ChartContainer>\n </div>\n </div>\n )\n}\n"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"path": "registry/example-apps/default/dashboard-3/components/dashboard/projects-table.tsx",
|
|
28
|
+
"type": "registry:component",
|
|
29
|
+
"target": "components/example-apps/dashboard-3/components/dashboard/projects-table.tsx",
|
|
30
|
+
"content": "\"use client\"\n\nimport { useMemo, useState } from \"react\"\nimport {\n ArrowLeft01Icon,\n ArrowLeftDoubleIcon,\n ArrowRight01Icon,\n ArrowRightDoubleIcon,\n CircleIcon,\n Clock01Icon,\n Database01Icon,\n FilterIcon,\n Folder01Icon,\n Layers01Icon,\n Megaphone01Icon,\n Search01Icon,\n Tick01Icon,\n Wallet01Icon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport {\n flexRender,\n getCoreRowModel,\n getFilteredRowModel,\n getPaginationRowModel,\n useReactTable,\n} from \"@tanstack/react-table\"\nimport type { ColumnDef } from \"@tanstack/react-table\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@loveui/ui/ui/avatar\"\nimport { Button } from \"@loveui/ui/ui/button\"\nimport { Checkbox } from \"@loveui/ui/ui/checkbox\"\nimport { Input } from \"@loveui/ui/ui/input\"\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@loveui/ui/ui/menu\"\nimport { Progress } from \"@loveui/ui/ui/progress\"\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@loveui/ui/ui/select\"\nimport {\n Table,\n TableBody,\n TableCell,\n TableHead,\n TableHeader,\n TableRow,\n} from \"@loveui/ui/ui/table\"\n\nimport { cn } from \"../../lib/utils\"\nimport {\n projects,\n type Project,\n type ProjectStatus,\n} from \"../../mock-data/dashboard\"\nimport { useDashboardStore } from \"../../store/dashboard-store\"\n\nfunction StatusBadge({ status }: { status: ProjectStatus }) {\n if (status === \"in_progress\") {\n return (\n <div className=\"flex items-center gap-1.5\">\n <HugeiconsIcon\n icon={CircleIcon}\n className=\"size-3.5 fill-cyan-500 text-cyan-500\"\n />\n <span className=\"text-sm text-cyan-600 dark:text-cyan-400\">\n In Progress\n </span>\n </div>\n )\n }\n if (status === \"completed\") {\n return (\n <div className=\"flex items-center gap-1.5\">\n <HugeiconsIcon\n icon={Tick01Icon}\n className=\"size-3.5 text-emerald-500\"\n />\n <span className=\"text-sm text-emerald-600 dark:text-emerald-400\">\n Completed\n </span>\n </div>\n )\n }\n return (\n <div className=\"flex items-center gap-1.5\">\n <HugeiconsIcon icon={Clock01Icon} className=\"size-3.5 text-amber-500\" />\n <span className=\"text-sm text-amber-600 dark:text-amber-400\">\n On Hold\n </span>\n </div>\n )\n}\n\nconst projectIconMap: Record<\n string,\n { icon: typeof Folder01Icon; iconColor: string }\n> = {\n blue: { icon: Folder01Icon, iconColor: \"text-blue-500\" },\n violet: { icon: Layers01Icon, iconColor: \"text-violet-500\" },\n cyan: { icon: Database01Icon, iconColor: \"text-cyan-500\" },\n pink: { icon: Megaphone01Icon, iconColor: \"text-pink-500\" },\n amber: { icon: Wallet01Icon, iconColor: \"text-amber-500\" },\n}\n\nexport function ProjectsTable() {\n const {\n projectsSearchQuery,\n setProjectsSearchQuery,\n projectStatusFilter,\n setProjectStatusFilter,\n } = useDashboardStore()\n\n const columns = useMemo<ColumnDef<Project>[]>(\n () => [\n {\n id: \"select\",\n header: ({ table }) => (\n <Checkbox\n checked={\n table.getIsAllPageRowsSelected()\n ? true\n : table.getIsSomePageRowsSelected()\n ? true\n : false\n }\n onCheckedChange={(value) =>\n table.toggleAllPageRowsSelected(!!value)\n }\n aria-label=\"Select all\"\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(value) => row.toggleSelected(!!value)}\n aria-label=\"Select row\"\n />\n ),\n enableSorting: false,\n enableHiding: false,\n },\n {\n accessorKey: \"name\",\n header: \"Project Name\",\n cell: ({ row }) => {\n const p = row.original\n const { icon, iconColor } =\n projectIconMap[p.color] ?? projectIconMap.blue\n return (\n <div className=\"flex items-center gap-2 font-medium text-foreground\">\n <HugeiconsIcon\n icon={icon}\n className={cn(\"size-4 shrink-0\", iconColor)}\n />\n {p.name}\n </div>\n )\n },\n },\n {\n accessorKey: \"status\",\n header: \"Status\",\n cell: ({ row }) => <StatusBadge status={row.original.status} />,\n },\n {\n accessorKey: \"progress\",\n header: \"Progress\",\n cell: ({ row }) => (\n <div className=\"flex min-w-[100px] items-center gap-2\">\n <Progress value={row.original.progress} className=\"h-2 flex-1\" />\n <span className=\"w-8 text-sm tabular-nums\">\n {row.original.progress}%\n </span>\n </div>\n ),\n },\n {\n id: \"tasks\",\n header: \"Total Tasks\",\n cell: ({ row }) => {\n const p = row.original\n return (\n <span className=\"text-sm text-muted-foreground\">\n {p.completedTasks}/{p.totalTasks}\n </span>\n )\n },\n },\n {\n accessorKey: \"dueDate\",\n header: \"Due Date\",\n cell: ({ row }) => (\n <span className=\"text-sm text-muted-foreground\">\n {row.original.dueDate}\n </span>\n ),\n },\n {\n accessorKey: \"ownerName\",\n header: \"Owner\",\n cell: ({ row }) => {\n const p = row.original\n return (\n <div className=\"flex items-center gap-2\">\n <Avatar className=\"size-6\">\n <AvatarImage\n src={`https://api.dicebear.com/9.x/glass/svg?seed=${p.ownerAvatarSeed}`}\n />\n <AvatarFallback className=\"text-xs\">\n {p.ownerName.slice(0, 2)}\n </AvatarFallback>\n </Avatar>\n <span className=\"text-sm\">{p.ownerName}</span>\n </div>\n )\n },\n },\n ],\n []\n )\n\n const filteredData = useMemo(() => {\n let result = projects\n if (projectsSearchQuery.trim()) {\n const q = projectsSearchQuery.toLowerCase()\n result = result.filter(\n (p) =>\n p.name.toLowerCase().includes(q) ||\n p.ownerName.toLowerCase().includes(q)\n )\n }\n if (projectStatusFilter !== \"all\") {\n result = result.filter((p) => p.status === projectStatusFilter)\n }\n return result\n }, [projectsSearchQuery, projectStatusFilter])\n\n const [rowSelection, setRowSelection] = useState({})\n\n const table = useReactTable({\n data: filteredData,\n columns,\n getCoreRowModel: getCoreRowModel(),\n getFilteredRowModel: getFilteredRowModel(),\n getPaginationRowModel: getPaginationRowModel(),\n onRowSelectionChange: setRowSelection,\n state: { rowSelection },\n initialState: {\n pagination: { pageSize: 10 },\n },\n })\n\n const hasActiveFilters = projectStatusFilter !== \"all\"\n const pageSize = table.getState().pagination.pageSize\n const pageIndex = table.getState().pagination.pageIndex\n const totalRows = filteredData.length\n const from = pageIndex * pageSize + 1\n const to = Math.min((pageIndex + 1) * pageSize, totalRows)\n\n return (\n <div className=\"overflow-hidden rounded-xl border border-border bg-card\">\n <div className=\"flex flex-col gap-3 border-b px-4 py-3 sm:flex-row sm:items-center sm:justify-between\">\n <h3 className=\"text-base font-medium\">Course Board</h3>\n <div className=\"flex items-center gap-2\">\n <div className=\"relative\">\n <HugeiconsIcon\n icon={Search01Icon}\n className=\"pointer-events-none absolute top-1/2 left-2.5 z-10 size-4 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n placeholder=\"Search courses...\"\n value={projectsSearchQuery}\n onChange={(e) => setProjectsSearchQuery(e.target.value)}\n className=\"h-9 w-full bg-muted/50 pl-8 text-sm sm:w-[200px]\"\n />\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger\n render={\n <Button variant=\"outline\" size=\"sm\" className=\"h-9 gap-1.5\">\n <HugeiconsIcon icon={FilterIcon} className=\"size-4\" />\n Filter\n {hasActiveFilters && (\n <span className=\"size-1.5 rounded-full bg-primary\" />\n )}\n </Button>\n }\n />\n <DropdownMenuContent align=\"start\" className=\"w-44\">\n <DropdownMenuCheckboxItem\n checked={projectStatusFilter === \"all\"}\n onCheckedChange={() => setProjectStatusFilter(\"all\")}\n >\n All statuses\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n checked={projectStatusFilter === \"in_progress\"}\n onCheckedChange={() => setProjectStatusFilter(\"in_progress\")}\n >\n In Progress\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n checked={projectStatusFilter === \"completed\"}\n onCheckedChange={() => setProjectStatusFilter(\"completed\")}\n >\n Completed\n </DropdownMenuCheckboxItem>\n <DropdownMenuCheckboxItem\n checked={projectStatusFilter === \"on_hold\"}\n onCheckedChange={() => setProjectStatusFilter(\"on_hold\")}\n >\n On Hold\n </DropdownMenuCheckboxItem>\n {hasActiveFilters && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem\n onClick={() => setProjectStatusFilter(\"all\")}\n >\n Clear filter\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </div>\n <div className=\"overflow-x-auto\">\n <Table>\n <TableHeader>\n {table.getHeaderGroups().map((headerGroup) => (\n <TableRow key={headerGroup.id} className=\"hover:bg-transparent\">\n {headerGroup.headers.map((header) => (\n <TableHead key={header.id}>\n {flexRender(\n header.column.columnDef.header,\n header.getContext()\n )}\n </TableHead>\n ))}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n {table.getRowModel().rows.length === 0 ? (\n <TableRow>\n <TableCell\n colSpan={columns.length}\n className=\"py-8 text-center text-muted-foreground\"\n >\n No courses found.\n </TableCell>\n </TableRow>\n ) : (\n table.getRowModel().rows.map((row) => (\n <TableRow\n key={row.id}\n data-state={row.getIsSelected() ? \"selected\" : undefined}\n >\n {row.getVisibleCells().map((cell) => (\n <TableCell key={cell.id}>\n {flexRender(\n cell.column.columnDef.cell,\n cell.getContext()\n )}\n </TableCell>\n ))}\n </TableRow>\n ))\n )}\n </TableBody>\n </Table>\n </div>\n <div className=\"flex flex-col items-center justify-between gap-4 border-t px-4 py-3 sm:flex-row\">\n <div className=\"flex items-center gap-4 text-sm text-muted-foreground\">\n <span>\n {totalRows === 0\n ? \"0 courses\"\n : `Showing ${from} to ${to} of ${totalRows} courses`}\n </span>\n <div className=\"flex items-center gap-2\">\n <span className=\"hidden sm:inline\">Rows per page</span>\n <Select\n value={String(pageSize)}\n onValueChange={(v) => table.setPageSize(Number(v))}\n >\n <SelectTrigger className=\"h-8 w-[70px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"5\">5</SelectItem>\n <SelectItem value=\"10\">10</SelectItem>\n <SelectItem value=\"20\">20</SelectItem>\n <SelectItem value=\"50\">50</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </div>\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"size-8\"\n onClick={() => table.setPageIndex(0)}\n disabled={!table.getCanPreviousPage()}\n >\n <HugeiconsIcon icon={ArrowLeftDoubleIcon} className=\"size-4\" />\n </Button>\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"size-8\"\n onClick={() => table.previousPage()}\n disabled={!table.getCanPreviousPage()}\n >\n <HugeiconsIcon icon={ArrowLeft01Icon} className=\"size-4\" />\n </Button>\n <span className=\"px-2 text-sm tabular-nums\">\n {pageIndex + 1} / {table.getPageCount() || 1}\n </span>\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"size-8\"\n onClick={() => table.nextPage()}\n disabled={!table.getCanNextPage()}\n >\n <HugeiconsIcon icon={ArrowRight01Icon} className=\"size-4\" />\n </Button>\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"size-8\"\n onClick={() => table.setPageIndex(table.getPageCount() - 1)}\n disabled={!table.getCanNextPage()}\n >\n <HugeiconsIcon icon={ArrowRightDoubleIcon} className=\"size-4\" />\n </Button>\n </div>\n </div>\n </div>\n )\n}\n"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"path": "registry/example-apps/default/dashboard-3/components/dashboard/sidebar.tsx",
|
|
34
|
+
"type": "registry:component",
|
|
35
|
+
"target": "components/example-apps/dashboard-3/components/dashboard/sidebar.tsx",
|
|
36
|
+
"content": "\"use client\"\n\nimport Link from \"next/link\"\nimport {\n Add01Icon,\n ArrowDown01Icon,\n Calendar01Icon,\n ChartLineData01Icon,\n DashboardSquare01Icon,\n HelpCircleIcon,\n Layers01Icon,\n Mail01Icon,\n Notification01Icon,\n Search01Icon,\n Settings01Icon,\n SparklesIcon,\n Task01Icon,\n Tick01Icon,\n UserIcon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@loveui/ui/ui/avatar\"\nimport { Button } from \"@loveui/ui/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@loveui/ui/ui/menu\"\n\nimport { cn } from \"../../lib/utils\"\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n} from \"../ui/sidebar\"\n\nconst navItems = [\n {\n title: \"Search\",\n icon: Search01Icon,\n shortcut: \"/\",\n iconColor: \"text-muted-foreground\",\n },\n { title: \"Advisor AI\", icon: SparklesIcon, iconColor: \"text-violet-500\" },\n { title: \"Course Templates\", icon: Layers01Icon, iconColor: \"text-blue-500\" },\n {\n title: \"Campus Alerts\",\n icon: Notification01Icon,\n iconColor: \"text-amber-500\",\n },\n {\n title: \"Academic Hub\",\n icon: DashboardSquare01Icon,\n isActive: true,\n iconColor: \"text-primary\",\n },\n { title: \"Faculty Inbox\", icon: Mail01Icon, iconColor: \"text-cyan-500\" },\n { title: \"Assignments\", icon: Task01Icon, iconColor: \"text-emerald-500\" },\n {\n title: \"Class Calendar\",\n icon: Calendar01Icon,\n iconColor: \"text-orange-500\",\n },\n {\n title: \"Program Insights\",\n icon: ChartLineData01Icon,\n iconColor: \"text-rose-500\",\n },\n { title: \"Student Support\", icon: HelpCircleIcon, iconColor: \"text-sky-500\" },\n {\n title: \"Preferences\",\n icon: Settings01Icon,\n iconColor: \"text-muted-foreground\",\n },\n]\n\nexport function DashboardSidebar(props: React.ComponentProps<typeof Sidebar>) {\n return (\n <Sidebar collapsible=\"offExamples\" className=\"lg:border-r-0!\" {...props}>\n <SidebarHeader className=\"px-3 py-4\">\n <div className=\"flex w-full items-center justify-between\">\n <DropdownMenu>\n <DropdownMenuTrigger\n render={\n <button className=\"flex w-full items-center justify-start gap-2 outline-none\">\n <div className=\"flex size-8 shrink-0 items-center justify-center rounded-md bg-primary text-primary-foreground\">\n <span className=\"text-sm font-bold\">AU</span>\n </div>\n <span className=\"truncate font-semibold text-sidebar-foreground\">\n Aurora University\n </span>\n <HugeiconsIcon\n icon={ArrowDown01Icon}\n className=\"size-3 shrink-0 text-muted-foreground\"\n />\n </button>\n }\n />\n <DropdownMenuContent align=\"start\" className=\"w-56\">\n <DropdownMenuGroup>\n <p className=\"px-2 py-1.5 text-xs font-medium text-muted-foreground\">\n Workspaces\n </p>\n <DropdownMenuItem>\n <div className=\"mr-2 flex size-5 items-center justify-center rounded bg-primary/20 text-xs font-bold text-primary\">\n AU\n </div>\n Aurora University\n <HugeiconsIcon icon={Tick01Icon} className=\"ml-auto size-4\" />\n </DropdownMenuItem>\n <DropdownMenuItem>\n <div className=\"mr-2 flex size-5 items-center justify-center rounded bg-blue-500/20 text-xs font-bold text-blue-600 dark:text-blue-400\">\n SC\n </div>\n Science College\n </DropdownMenuItem>\n <DropdownMenuItem>\n <div className=\"mr-2 flex size-5 items-center justify-center rounded bg-emerald-500/20 text-xs font-bold text-emerald-600 dark:text-emerald-400\">\n AR\n </div>\n Arts & Research\n </DropdownMenuItem>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <HugeiconsIcon icon={Add01Icon} className=\"mr-2 size-4\" />\n Create Workspace\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem>\n <HugeiconsIcon icon={UserIcon} className=\"mr-2 size-4\" />\n Profile\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n <Avatar className=\"size-8 shrink-0 border-2 border-sidebar\">\n <AvatarImage src=\"/cl.png\" />\n <AvatarFallback>CL</AvatarFallback>\n </Avatar>\n </div>\n </SidebarHeader>\n\n <SidebarContent className=\"px-2\">\n <SidebarGroup className=\"p-0\">\n <SidebarGroupContent>\n <SidebarMenu>\n {navItems.map((item) => (\n <SidebarMenuItem key={item.title}>\n <SidebarMenuButton\n isActive={item.isActive}\n className=\"h-9\"\n render={<Link href=\"#\" />}\n >\n <HugeiconsIcon\n icon={item.icon}\n className={cn(\"size-4 shrink-0\", item.iconColor)}\n />\n <span className=\"text-sm\">{item.title}</span>\n {item.shortcut && (\n <span className=\"ml-auto flex size-5 items-center justify-center rounded bg-muted text-[10px] font-medium text-muted-foreground\">\n {item.shortcut}\n </span>\n )}\n </SidebarMenuButton>\n </SidebarMenuItem>\n ))}\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n </SidebarContent>\n </Sidebar>\n )\n}\n"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"path": "registry/example-apps/default/dashboard-3/components/dashboard/stats-cards.tsx",
|
|
40
|
+
"type": "registry:component",
|
|
41
|
+
"target": "components/example-apps/dashboard-3/components/dashboard/stats-cards.tsx",
|
|
42
|
+
"content": "\"use client\"\n\nimport {\n Folder01Icon,\n Task01Icon,\n Tick01Icon,\n ViewIcon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\n\nimport { dashboardStats } from \"../../mock-data/dashboard\"\n\nconst stats = [\n {\n title: \"Active Courses\",\n value: dashboardStats.totalProjects.value,\n change: dashboardStats.totalProjects.change,\n icon: Folder01Icon,\n },\n {\n title: \"Open Assignments\",\n value: dashboardStats.totalTasks.value,\n change: dashboardStats.totalTasks.change,\n icon: Task01Icon,\n },\n {\n title: \"Pending Grading\",\n value: dashboardStats.inReviews.value,\n change: dashboardStats.inReviews.change,\n icon: ViewIcon,\n },\n {\n title: \"Graded Items\",\n value: dashboardStats.completedTasks.value,\n change: dashboardStats.completedTasks.change,\n icon: Tick01Icon,\n },\n]\n\nexport function StatsCards() {\n return (\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n {stats.map((stat, index) => (\n <div\n key={index}\n className=\"rounded-xl border border-border bg-card p-4\"\n >\n <div className=\"flex items-start justify-between\">\n <div className=\"space-y-1\">\n <p className=\"text-sm text-muted-foreground\">{stat.title}</p>\n <p className=\"text-2xl font-medium text-foreground\">\n {stat.value}\n </p>\n <p className=\"text-xs text-muted-foreground\">\n +{stat.change} vs last month\n </p>\n </div>\n <div className=\"flex size-10 shrink-0 items-center justify-center rounded-lg border border-border bg-muted\">\n <HugeiconsIcon\n icon={stat.icon}\n className=\"size-5 text-muted-foreground\"\n />\n </div>\n </div>\n </div>\n ))}\n </div>\n )\n}\n"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"path": "registry/example-apps/default/dashboard-3/components/dashboard/todays-tasks.tsx",
|
|
46
|
+
"type": "registry:component",
|
|
47
|
+
"target": "components/example-apps/dashboard-3/components/dashboard/todays-tasks.tsx",
|
|
48
|
+
"content": "\"use client\"\n\nimport { useMemo } from \"react\"\nimport { FilterIcon, Search01Icon } from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\n\nimport { Button } from \"@loveui/ui/ui/button\"\nimport { Input } from \"@loveui/ui/ui/input\"\nimport {\n DropdownMenu,\n DropdownMenuCheckboxItem,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@loveui/ui/ui/menu\"\n\nimport { cn } from \"../../lib/utils\"\nimport { todayTasks } from \"../../mock-data/dashboard\"\nimport { useDashboardStore } from \"../../store/dashboard-store\"\n\nconst projectColorMap: Record<string, string> = {\n blue: \"rounded-lg border border-border bg-muted/50 text-foreground\",\n violet: \"rounded-lg border border-border bg-muted/50 text-foreground\",\n cyan: \"rounded-lg border border-border bg-muted/50 text-foreground\",\n pink: \"rounded-lg border border-border bg-muted/50 text-foreground\",\n amber: \"rounded-lg border border-border bg-muted/50 text-foreground\",\n}\n\nconst uniqueProjects = Array.from(\n new Map(\n todayTasks.map((t) => [\n t.projectId,\n { id: t.projectId, name: t.projectName },\n ])\n ).values()\n)\n\nexport function TodaysTasks() {\n const {\n tasksSearchQuery,\n setTasksSearchQuery,\n tasksProjectFilter,\n toggleTasksProjectFilter,\n setTasksProjectFilter,\n } = useDashboardStore()\n\n const filteredTasks = useMemo(() => {\n let result = todayTasks\n if (tasksSearchQuery.trim()) {\n const q = tasksSearchQuery.toLowerCase()\n result = result.filter(\n (t) =>\n t.name.toLowerCase().includes(q) ||\n t.projectName.toLowerCase().includes(q)\n )\n }\n if (tasksProjectFilter.length > 0) {\n result = result.filter((t) => tasksProjectFilter.includes(t.projectId))\n }\n return result\n }, [tasksSearchQuery, tasksProjectFilter])\n\n const hasTaskFilters = tasksProjectFilter.length > 0\n\n return (\n <div className=\"overflow-hidden rounded-xl border border-border bg-card\">\n <div className=\"flex flex-col gap-3 border-b px-4 py-3 sm:flex-row sm:items-center sm:justify-between\">\n <h3 className=\"text-base font-medium\">Today's Academic Tasks</h3>\n <div className=\"flex items-center gap-2\">\n <div className=\"relative\">\n <HugeiconsIcon\n icon={Search01Icon}\n className=\"pointer-events-none absolute top-1/2 left-2.5 z-10 size-4 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n placeholder=\"Search here...\"\n value={tasksSearchQuery}\n onChange={(e) => setTasksSearchQuery(e.target.value)}\n className=\"h-9 w-full bg-muted/50 pl-8 text-sm sm:w-[200px]\"\n />\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger\n render={\n <Button variant=\"outline\" size=\"sm\" className=\"h-9 gap-1.5\">\n <HugeiconsIcon icon={FilterIcon} className=\"size-4\" />\n Filter\n {hasTaskFilters && (\n <span className=\"size-1.5 rounded-full bg-primary\" />\n )}\n </Button>\n }\n />\n <DropdownMenuContent align=\"end\" className=\"w-52\">\n <DropdownMenuCheckboxItem\n checked={tasksProjectFilter.length === 0}\n onCheckedChange={() => setTasksProjectFilter([])}\n >\n All projects\n </DropdownMenuCheckboxItem>\n <DropdownMenuSeparator />\n {uniqueProjects.map((proj) => (\n <DropdownMenuCheckboxItem\n key={proj.id}\n checked={tasksProjectFilter.includes(proj.id)}\n onCheckedChange={() => toggleTasksProjectFilter(proj.id)}\n >\n {proj.name}\n </DropdownMenuCheckboxItem>\n ))}\n {hasTaskFilters && (\n <>\n <DropdownMenuSeparator />\n <DropdownMenuItem onClick={() => setTasksProjectFilter([])}>\n Clear filter\n </DropdownMenuItem>\n </>\n )}\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n </div>\n <div className=\"divide-y\">\n {filteredTasks.length === 0 ? (\n <div className=\"px-4 py-8 text-center text-sm text-muted-foreground\">\n No academic tasks match your search.\n </div>\n ) : (\n filteredTasks.map((task) => (\n <div\n key={task.id}\n className=\"flex flex-wrap items-center gap-3 px-4 py-3 transition-colors hover:bg-muted/30\"\n >\n <span className=\"text-sm font-medium\">{task.name}</span>\n <div\n className={cn(\n \"inline-flex items-center gap-1.5 px-2 py-1 text-xs font-medium\",\n projectColorMap[task.projectColor] ?? projectColorMap.blue\n )}\n >\n {task.projectName}\n </div>\n <span className=\"ml-auto text-xs text-muted-foreground\">\n Due: {task.dueDate}\n </span>\n </div>\n ))\n )}\n </div>\n </div>\n )\n}\n"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"path": "registry/example-apps/default/dashboard-3/components/theme-provider.tsx",
|
|
52
|
+
"type": "registry:component",
|
|
53
|
+
"target": "components/example-apps/dashboard-3/components/theme-provider.tsx",
|
|
54
|
+
"content": "\"use client\"\n\nimport { ThemeProvider as NextThemesProvider } from \"next-themes\"\n\nexport function ThemeProvider({\n children,\n ...props\n}: React.ComponentProps<typeof NextThemesProvider>) {\n return <NextThemesProvider {...props}>{children}</NextThemesProvider>\n}\n"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"path": "registry/example-apps/default/dashboard-3/components/theme-toggle.tsx",
|
|
58
|
+
"type": "registry:component",
|
|
59
|
+
"target": "components/example-apps/dashboard-3/components/theme-toggle.tsx",
|
|
60
|
+
"content": "\"use client\"\n\nimport { Moon01Icon, Sun01Icon } from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { useTheme } from \"next-themes\"\n\nimport { Button } from \"@loveui/ui/ui/button\"\n\nexport function ThemeToggle() {\n const { theme, setTheme } = useTheme()\n\n return (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => setTheme(theme === \"light\" ? \"dark\" : \"light\")}\n >\n <HugeiconsIcon\n icon={Sun01Icon}\n className=\"size-5 scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90\"\n />\n <HugeiconsIcon\n icon={Moon01Icon}\n className=\"absolute size-5 scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0\"\n />\n <span className=\"sr-only\">Toggle theme</span>\n </Button>\n )\n}\n"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/avatar.tsx",
|
|
64
|
+
"type": "registry:ui",
|
|
65
|
+
"target": "components/example-apps/dashboard-3/components/ui/avatar.tsx",
|
|
66
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Avatar as AvatarPrimitive } from \"@base-ui/react/avatar\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Avatar({\n className,\n size = \"default\",\n ...props\n}: AvatarPrimitive.Root.Props & {\n size?: \"default\" | \"sm\" | \"lg\"\n}) {\n return (\n <AvatarPrimitive.Root\n data-slot=\"avatar\"\n data-size={size}\n className={cn(\n \"group/avatar relative flex size-8 shrink-0 rounded-full select-none after:absolute after:inset-0 after:rounded-full after:border after:border-border after:mix-blend-darken data-[size=lg]:size-10 data-[size=sm]:size-6 dark:after:mix-blend-lighten\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AvatarImage({ className, ...props }: AvatarPrimitive.Image.Props) {\n return (\n <AvatarPrimitive.Image\n data-slot=\"avatar-image\"\n className={cn(\n \"aspect-square size-full rounded-full object-cover\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AvatarFallback({\n className,\n ...props\n}: AvatarPrimitive.Fallback.Props) {\n return (\n <AvatarPrimitive.Fallback\n data-slot=\"avatar-fallback\"\n className={cn(\n \"flex size-full items-center justify-center rounded-full bg-muted text-sm text-muted-foreground group-data-[size=sm]/avatar:text-xs\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AvatarBadge({ className, ...props }: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"avatar-badge\"\n className={cn(\n \"absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-primary text-primary-foreground bg-blend-color ring-2 ring-background select-none\",\n \"group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden\",\n \"group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2\",\n \"group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AvatarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"avatar-group\"\n className={cn(\n \"group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AvatarGroupCount({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"avatar-group-count\"\n className={cn(\n \"relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Avatar,\n AvatarImage,\n AvatarFallback,\n AvatarGroup,\n AvatarGroupCount,\n AvatarBadge,\n}\n"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/button.tsx",
|
|
70
|
+
"type": "registry:ui",
|
|
71
|
+
"target": "components/example-apps/dashboard-3/components/ui/button.tsx",
|
|
72
|
+
"content": "\"use client\"\n\nimport { Button as ButtonPrimitive } from \"@base-ui/react/button\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/80\",\n outline:\n \"border-border bg-background shadow-xs hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n ghost:\n \"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50\",\n destructive:\n \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default:\n \"h-9 gap-1.5 px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n xs: \"h-6 gap-1 rounded-[min(var(--radius-md),8px)] px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-8 gap-1 rounded-[min(var(--radius-md),10px)] px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5\",\n lg: \"h-10 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3\",\n icon: \"size-9\",\n \"icon-xs\":\n \"size-6 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\":\n \"size-8 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-md\",\n \"icon-lg\": \"size-10\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n return (\n <ButtonPrimitive\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/card.tsx",
|
|
76
|
+
"type": "registry:ui",
|
|
77
|
+
"target": "components/example-apps/dashboard-3/components/ui/card.tsx",
|
|
78
|
+
"content": "import * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Card({\n className,\n size = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & { size?: \"default\" | \"sm\" }) {\n return (\n <div\n data-slot=\"card\"\n data-size={size}\n className={cn(\n \"group/card flex flex-col gap-6 overflow-hidden rounded-xl bg-card py-6 text-sm text-card-foreground shadow-xs ring-1 ring-foreground/10 has-[>img:first-child]:pt-0 data-[size=sm]:gap-4 data-[size=sm]:py-4 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-header\"\n className={cn(\n \"group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-6 group-data-[size=sm]/card:px-4 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-6 group-data-[size=sm]/card:[.border-b]:pb-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-title\"\n className={cn(\n \"text-base leading-normal font-medium group-data-[size=sm]/card:text-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-action\"\n className={cn(\n \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-content\"\n className={cn(\"px-6 group-data-[size=sm]/card:px-4\", className)}\n {...props}\n />\n )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"card-footer\"\n className={cn(\n \"flex items-center rounded-b-xl px-6 group-data-[size=sm]/card:px-4 [.border-t]:pt-6 group-data-[size=sm]/card:[.border-t]:pt-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n Card,\n CardHeader,\n CardFooter,\n CardTitle,\n CardAction,\n CardDescription,\n CardContent,\n}\n"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/chart.tsx",
|
|
82
|
+
"type": "registry:ui",
|
|
83
|
+
"target": "components/example-apps/dashboard-3/components/ui/chart.tsx",
|
|
84
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport * as RechartsPrimitive from \"recharts\"\n\nimport { cn } from \"../../lib/utils\"\n\n// Format: { THEME_NAME: CSS_SELECTOR }\nconst THEMES = { light: \"\", dark: \".dark\" } as const\n\nexport type ChartConfig = {\n [k in string]: {\n label?: React.ReactNode\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\nfunction ChartContainer({\n id,\n className,\n children,\n config,\n ...props\n}: React.ComponentProps<\"div\"> & {\n config: ChartConfig\n children: React.ComponentProps<\n typeof RechartsPrimitive.ResponsiveContainer\n >[\"children\"]\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>\n {children}\n </RechartsPrimitive.ResponsiveContainer>\n </div>\n </ChartContext.Provider>\n )\n}\n\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n const colorConfig = Object.entries(config).filter(\n ([, config]) => config.theme || config.color\n )\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 =\n itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ||\n itemConfig.color\n return color ? ` --color-${key}: ${color};` : null\n })\n .join(\"\\n\")}\n}\n`\n )\n .join(\"\\n\"),\n }}\n />\n )\n}\n\nconst ChartTooltip = RechartsPrimitive.Tooltip\n\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 hideLabel?: boolean\n hideIndicator?: boolean\n indicator?: \"line\" | \"dot\" | \"dashed\"\n nameKey?: string\n labelKey?: string\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\"\n ? config[label as keyof typeof config]?.label || label\n : itemConfig?.label\n\n if (labelFormatter) {\n return (\n <div className={cn(\"font-medium\", labelClassName)}>\n {labelFormatter(value, payload)}\n </div>\n )\n }\n\n if (!value) {\n return null\n }\n\n return <div className={cn(\"font-medium\", labelClassName)}>{value}</div>\n }, [\n label,\n labelFormatter,\n payload,\n hideLabel,\n labelClassName,\n config,\n labelKey,\n ])\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 gap-1.5 rounded-lg border border-border/50 bg-background 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={item.dataKey}\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 any\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 && (\n <span className=\"font-mono font-medium text-foreground tabular-nums\">\n {item.value.toLocaleString()}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n )\n })}\n </div>\n </div>\n )\n}\n\nconst ChartLegend = RechartsPrimitive.Legend\n\nfunction ChartLegendContent({\n className,\n hideIcon = false,\n payload,\n verticalAlign = \"bottom\",\n nameKey,\n}: React.ComponentProps<\"div\"> &\n Pick<RechartsPrimitive.LegendProps, \"payload\" | \"verticalAlign\"> & {\n hideIcon?: boolean\n nameKey?: string\n }) {\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) => {\n const key = `${nameKey || item.dataKey || \"value\"}`\n const itemConfig = getPayloadConfigFromPayload(config, item, key)\n\n return (\n <div\n key={item.value}\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\nfunction getPayloadConfigFromPayload(\n config: ChartConfig,\n payload: unknown,\n key: string\n) {\n if (typeof payload !== \"object\" || payload === null) {\n return undefined\n }\n\n const payloadPayload =\n \"payload\" in payload &&\n typeof payload.payload === \"object\" &&\n payload.payload !== null\n ? payload.payload\n : undefined\n\n let configLabelKey: string = key\n\n if (\n key in payload &&\n typeof payload[key as keyof typeof payload] === \"string\"\n ) {\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[\n key as keyof typeof payloadPayload\n ] as string\n }\n\n return configLabelKey in config\n ? config[configLabelKey]\n : config[key as keyof typeof config]\n}\n\nexport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n ChartLegend,\n ChartLegendContent,\n ChartStyle,\n}\n"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/checkbox.tsx",
|
|
88
|
+
"type": "registry:ui",
|
|
89
|
+
"target": "components/example-apps/dashboard-3/components/ui/checkbox.tsx",
|
|
90
|
+
"content": "\"use client\"\n\nimport { Checkbox as CheckboxPrimitive } from \"@base-ui/react/checkbox\"\nimport { Tick02Icon } from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) {\n return (\n <CheckboxPrimitive.Root\n data-slot=\"checkbox\"\n className={cn(\n \"peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input shadow-xs transition-shadow outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 dark:data-checked:bg-primary\",\n className\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator\n data-slot=\"checkbox-indicator\"\n className=\"grid place-content-center text-current transition-none [&>svg]:size-3.5\"\n >\n <HugeiconsIcon icon={Tick02Icon} strokeWidth={2} />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n )\n}\n\nexport { Checkbox }\n"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/dropdown-menu.tsx",
|
|
94
|
+
"type": "registry:ui",
|
|
95
|
+
"target": "components/example-apps/dashboard-3/components/ui/dropdown-menu.tsx",
|
|
96
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Menu as MenuPrimitive } from \"@base-ui/react/menu\"\nimport { ArrowRight01Icon, Tick02Icon } from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {\n return <MenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {\n return <MenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n}\n\nfunction DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {\n return <MenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />\n}\n\nfunction DropdownMenuContent({\n align = \"start\",\n alignOffset = 0,\n side = \"bottom\",\n sideOffset = 4,\n className,\n ...props\n}: MenuPrimitive.Popup.Props &\n Pick<\n MenuPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n <MenuPrimitive.Portal>\n <MenuPrimitive.Positioner\n className=\"isolate z-50 outline-none\"\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n >\n <MenuPrimitive.Popup\n data-slot=\"dropdown-menu-content\"\n className={cn(\n \"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-closed:overflow-hidden\",\n className\n )}\n {...props}\n />\n </MenuPrimitive.Positioner>\n </MenuPrimitive.Portal>\n )\n}\n\nfunction DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {\n return <MenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: MenuPrimitive.GroupLabel.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.GroupLabel\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-2 py-1.5 text-xs font-medium text-muted-foreground data-inset:pl-8\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: MenuPrimitive.Item.Props & {\n inset?: boolean\n variant?: \"default\" | \"destructive\"\n}) {\n return (\n <MenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"group/dropdown-menu-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {\n return <MenuPrimitive.SubmenuRoot data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: MenuPrimitive.SubmenuTrigger.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.SubmenuTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-open:bg-accent data-open:text-accent-foreground data-popup-open:bg-accent data-popup-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <HugeiconsIcon\n icon={ArrowRight01Icon}\n strokeWidth={2}\n className=\"ml-auto\"\n />\n </MenuPrimitive.SubmenuTrigger>\n )\n}\n\nfunction DropdownMenuSubContent({\n align = \"start\",\n alignOffset = -3,\n side = \"right\",\n sideOffset = 0,\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuContent>) {\n return (\n <DropdownMenuContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\n \"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 w-auto min-w-[96px] rounded-md bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100\",\n className\n )}\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n inset,\n ...props\n}: MenuPrimitive.CheckboxItem.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n data-inset={inset}\n className={cn(\n \"relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span\n className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\n data-slot=\"dropdown-menu-checkbox-item-indicator\"\n >\n <MenuPrimitive.CheckboxItemIndicator>\n <HugeiconsIcon icon={Tick02Icon} strokeWidth={2} />\n </MenuPrimitive.CheckboxItemIndicator>\n </span>\n {children}\n </MenuPrimitive.CheckboxItem>\n )\n}\n\nfunction DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {\n return (\n <MenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n inset,\n ...props\n}: MenuPrimitive.RadioItem.Props & {\n inset?: boolean\n}) {\n return (\n <MenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n data-inset={inset}\n className={cn(\n \"relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 data-inset:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span\n className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\n data-slot=\"dropdown-menu-radio-item-indicator\"\n >\n <MenuPrimitive.RadioItemIndicator>\n <HugeiconsIcon icon={Tick02Icon} strokeWidth={2} />\n </MenuPrimitive.RadioItemIndicator>\n </span>\n {children}\n </MenuPrimitive.RadioItem>\n )\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: MenuPrimitive.Separator.Props) {\n return (\n <MenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n}\n"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/input.tsx",
|
|
100
|
+
"type": "registry:ui",
|
|
101
|
+
"target": "components/example-apps/dashboard-3/components/ui/input.tsx",
|
|
102
|
+
"content": "import * as React from \"react\"\nimport { Input as InputPrimitive } from \"@base-ui/react/input\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n return (\n <InputPrimitive\n type={type}\n data-slot=\"input\"\n className={cn(\n \"h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-2.5 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Input }\n"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/progress.tsx",
|
|
106
|
+
"type": "registry:ui",
|
|
107
|
+
"target": "components/example-apps/dashboard-3/components/ui/progress.tsx",
|
|
108
|
+
"content": "\"use client\"\n\nimport { Progress as ProgressPrimitive } from \"@base-ui/react/progress\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Progress({\n className,\n children,\n value,\n ...props\n}: ProgressPrimitive.Root.Props) {\n return (\n <ProgressPrimitive.Root\n value={value}\n data-slot=\"progress\"\n className={cn(\"flex flex-wrap gap-3\", className)}\n {...props}\n >\n {children}\n <ProgressTrack>\n <ProgressIndicator />\n </ProgressTrack>\n </ProgressPrimitive.Root>\n )\n}\n\nfunction ProgressTrack({ className, ...props }: ProgressPrimitive.Track.Props) {\n return (\n <ProgressPrimitive.Track\n className={cn(\n \"relative flex h-1.5 w-full items-center overflow-x-hidden rounded-full bg-muted\",\n className\n )}\n data-slot=\"progress-track\"\n {...props}\n />\n )\n}\n\nfunction ProgressIndicator({\n className,\n ...props\n}: ProgressPrimitive.Indicator.Props) {\n return (\n <ProgressPrimitive.Indicator\n data-slot=\"progress-indicator\"\n className={cn(\"h-full bg-primary transition-all\", className)}\n {...props}\n />\n )\n}\n\nfunction ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props) {\n return (\n <ProgressPrimitive.Label\n className={cn(\"text-sm font-medium\", className)}\n data-slot=\"progress-label\"\n {...props}\n />\n )\n}\n\nfunction ProgressValue({ className, ...props }: ProgressPrimitive.Value.Props) {\n return (\n <ProgressPrimitive.Value\n className={cn(\n \"ml-auto text-sm text-muted-foreground tabular-nums\",\n className\n )}\n data-slot=\"progress-value\"\n {...props}\n />\n )\n}\n\nexport {\n Progress,\n ProgressTrack,\n ProgressIndicator,\n ProgressLabel,\n ProgressValue,\n}\n"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/select.tsx",
|
|
112
|
+
"type": "registry:ui",
|
|
113
|
+
"target": "components/example-apps/dashboard-3/components/ui/select.tsx",
|
|
114
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Select as SelectPrimitive } from \"@base-ui/react/select\"\nimport {\n ArrowDown01Icon,\n ArrowUp01Icon,\n Tick02Icon,\n UnfoldMoreIcon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst Select = SelectPrimitive.Root\n\nfunction SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {\n return (\n <SelectPrimitive.Group\n data-slot=\"select-group\"\n className={cn(\"scroll-my-1 p-1\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {\n return (\n <SelectPrimitive.Value\n data-slot=\"select-value\"\n className={cn(\"flex flex-1 text-left\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: SelectPrimitive.Trigger.Props & {\n size?: \"sm\" | \"default\"\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"flex w-fit items-center justify-between gap-1.5 rounded-md border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon\n render={\n <HugeiconsIcon\n icon={UnfoldMoreIcon}\n strokeWidth={2}\n className=\"pointer-events-none size-4 text-muted-foreground\"\n />\n }\n />\n </SelectPrimitive.Trigger>\n )\n}\n\nfunction SelectContent({\n className,\n children,\n side = \"bottom\",\n sideOffset = 4,\n align = \"center\",\n alignOffset = 0,\n alignItemWithTrigger = true,\n ...props\n}: SelectPrimitive.Popup.Props &\n Pick<\n SelectPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\" | \"alignItemWithTrigger\"\n >) {\n return (\n <SelectPrimitive.Portal>\n <SelectPrimitive.Positioner\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n alignItemWithTrigger={alignItemWithTrigger}\n className=\"isolate z-50\"\n >\n <SelectPrimitive.Popup\n data-slot=\"select-content\"\n data-align-trigger={alignItemWithTrigger}\n className={cn(\n \"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none\",\n className\n )}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.List>{children}</SelectPrimitive.List>\n <SelectScrollDownButton />\n </SelectPrimitive.Popup>\n </SelectPrimitive.Positioner>\n </SelectPrimitive.Portal>\n )\n}\n\nfunction SelectLabel({\n className,\n ...props\n}: SelectPrimitive.GroupLabel.Props) {\n return (\n <SelectPrimitive.GroupLabel\n data-slot=\"select-label\"\n className={cn(\"px-2 py-1.5 text-xs text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: SelectPrimitive.Item.Props) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className\n )}\n {...props}\n >\n <SelectPrimitive.ItemText className=\"flex flex-1 shrink-0 gap-2 whitespace-nowrap\">\n {children}\n </SelectPrimitive.ItemText>\n <SelectPrimitive.ItemIndicator\n render={\n <span className=\"pointer-events-none absolute right-2 flex size-4 items-center justify-center\" />\n }\n >\n <HugeiconsIcon\n icon={Tick02Icon}\n strokeWidth={2}\n className=\"pointer-events-none\"\n />\n </SelectPrimitive.ItemIndicator>\n </SelectPrimitive.Item>\n )\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: SelectPrimitive.Separator.Props) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>) {\n return (\n <SelectPrimitive.ScrollUpArrow\n data-slot=\"select-scroll-up-button\"\n className={cn(\n \"top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <HugeiconsIcon icon={ArrowUp01Icon} strokeWidth={2} />\n </SelectPrimitive.ScrollUpArrow>\n )\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>) {\n return (\n <SelectPrimitive.ScrollDownArrow\n data-slot=\"select-scroll-down-button\"\n className={cn(\n \"bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <HugeiconsIcon icon={ArrowDown01Icon} strokeWidth={2} />\n </SelectPrimitive.ScrollDownArrow>\n )\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n}\n"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/separator.tsx",
|
|
118
|
+
"type": "registry:ui",
|
|
119
|
+
"target": "components/example-apps/dashboard-3/components/ui/separator.tsx",
|
|
120
|
+
"content": "\"use client\"\n\nimport { Separator as SeparatorPrimitive } from \"@base-ui/react/separator\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Separator({\n className,\n orientation = \"horizontal\",\n ...props\n}: SeparatorPrimitive.Props) {\n return (\n <SeparatorPrimitive\n data-slot=\"separator\"\n orientation={orientation}\n className={cn(\n \"shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Separator }\n"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/sheet.tsx",
|
|
124
|
+
"type": "registry:ui",
|
|
125
|
+
"target": "components/example-apps/dashboard-3/components/ui/sheet.tsx",
|
|
126
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Dialog as SheetPrimitive } from \"@base-ui/react/dialog\"\nimport { Cancel01Icon } from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\n\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"./button\"\n\nfunction Sheet({ ...props }: SheetPrimitive.Root.Props) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />\n}\n\nfunction SheetTrigger({ ...props }: SheetPrimitive.Trigger.Props) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\nfunction SheetClose({ ...props }: SheetPrimitive.Close.Props) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />\n}\n\nfunction SheetPortal({ ...props }: SheetPrimitive.Portal.Props) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />\n}\n\nfunction SheetOverlay({ className, ...props }: SheetPrimitive.Backdrop.Props) {\n return (\n <SheetPrimitive.Backdrop\n data-slot=\"sheet-overlay\"\n className={cn(\n \"data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 fixed inset-0 z-50 bg-black/10 duration-100 data-ending-style:opacity-0 data-starting-style:opacity-0 supports-backdrop-filter:backdrop-blur-xs\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n showCloseButton = true,\n ...props\n}: SheetPrimitive.Popup.Props & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n showCloseButton?: boolean\n}) {\n return (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Popup\n data-slot=\"sheet-content\"\n data-side={side}\n className={cn(\n \"data-open:animate-in data-closed:animate-out data-[side=right]:data-closed:slide-out-to-right-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=top]:data-closed:slide-out-to-top-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:fade-out-0 data-open:fade-in-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=bottom]:data-open:slide-in-from-bottom-10 fixed z-50 flex flex-col gap-4 bg-background bg-clip-padding text-sm shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <SheetPrimitive.Close\n data-slot=\"sheet-close\"\n render={\n <Button\n variant=\"ghost\"\n className=\"absolute top-4 right-4\"\n size=\"icon-sm\"\n />\n }\n >\n <HugeiconsIcon icon={Cancel01Icon} strokeWidth={2} />\n <span className=\"sr-only\">Close</span>\n </SheetPrimitive.Close>\n )}\n </SheetPrimitive.Popup>\n </SheetPortal>\n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\"flex flex-col gap-1.5 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\"font-medium text-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: SheetPrimitive.Description.Props) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/sidebar.tsx",
|
|
130
|
+
"type": "registry:ui",
|
|
131
|
+
"target": "components/example-apps/dashboard-3/components/ui/sidebar.tsx",
|
|
132
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { SidebarLeftIcon } from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { useIsMobile } from \"../../hooks/use-mobile\"\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"./button\"\nimport { Input } from \"./input\"\nimport { Separator } from \"./separator\"\nimport {\n Sheet,\n SheetContent,\n SheetDescription,\n SheetHeader,\n SheetTitle,\n} from \"./sheet\"\nimport { Skeleton } from \"./skeleton\"\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"./tooltip\"\n\nconst SIDEBAR_COOKIE_NAME = \"sidebar_state\"\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7\nconst SIDEBAR_WIDTH = \"16rem\"\nconst SIDEBAR_WIDTH_MOBILE = \"18rem\"\nconst SIDEBAR_WIDTH_ICON = \"3rem\"\nconst SIDEBAR_KEYBOARD_SHORTCUT = \"b\"\n\ntype SidebarContextProps = {\n state: \"expanded\" | \"collapsed\"\n open: boolean\n setOpen: (open: boolean) => void\n openMobile: boolean\n setOpenMobile: (open: boolean) => void\n isMobile: boolean\n toggleSidebar: () => void\n}\n\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null)\n\nfunction useSidebar() {\n const context = React.useContext(SidebarContext)\n if (!context) {\n throw new Error(\"useSidebar must be used within a SidebarProvider.\")\n }\n\n return context\n}\n\nfunction SidebarProvider({\n defaultOpen = true,\n open: openProp,\n onOpenChange: setOpenProp,\n className,\n style,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n defaultOpen?: boolean\n open?: boolean\n onOpenChange?: (open: boolean) => void\n}) {\n const isMobile = useIsMobile()\n const [openMobile, setOpenMobile] = React.useState(false)\n\n // This is the internal state of the sidebar.\n // We use openProp and setOpenProp for control from outside the component.\n const [_open, _setOpen] = React.useState(defaultOpen)\n const open = openProp ?? _open\n const setOpen = React.useCallback(\n (value: boolean | ((value: boolean) => boolean)) => {\n const openState = typeof value === \"function\" ? value(open) : value\n if (setOpenProp) {\n setOpenProp(openState)\n } else {\n _setOpen(openState)\n }\n\n // This sets the cookie to keep the sidebar state.\n document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`\n },\n [setOpenProp, open]\n )\n\n // Helper to toggle the sidebar.\n const toggleSidebar = React.useCallback(() => {\n return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)\n }, [isMobile, setOpen, setOpenMobile])\n\n // Adds a keyboard shortcut to toggle the sidebar.\n React.useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (\n event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\n (event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault()\n toggleSidebar()\n }\n }\n\n window.addEventListener(\"keydown\", handleKeyDown)\n return () => window.removeEventListener(\"keydown\", handleKeyDown)\n }, [toggleSidebar])\n\n // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\n // This makes it easier to style the sidebar with Tailwind classes.\n const state = open ? \"expanded\" : \"collapsed\"\n\n const contextValue = React.useMemo<SidebarContextProps>(\n () => ({\n state,\n open,\n setOpen,\n isMobile,\n openMobile,\n setOpenMobile,\n toggleSidebar,\n }),\n [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]\n )\n\n return (\n <SidebarContext.Provider value={contextValue}>\n <div\n data-slot=\"sidebar-wrapper\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH,\n \"--sidebar-width-icon\": SIDEBAR_WIDTH_ICON,\n ...style,\n } as any\n }\n className={cn(\n \"group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n </SidebarContext.Provider>\n )\n}\n\nfunction Sidebar({\n side = \"left\",\n variant = \"sidebar\",\n collapsible = \"offExamples\",\n className,\n children,\n ...props\n}: React.ComponentProps<\"div\"> & {\n side?: \"left\" | \"right\"\n variant?: \"sidebar\" | \"floating\" | \"inset\"\n collapsible?: \"offExamples\" | \"icon\" | \"none\"\n}) {\n const { isMobile, state, openMobile, setOpenMobile } = useSidebar()\n\n if (collapsible === \"none\") {\n return (\n <div\n data-slot=\"sidebar\"\n className={cn(\n \"flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground\",\n className\n )}\n {...props}\n >\n {children}\n </div>\n )\n }\n\n if (isMobile) {\n return (\n <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\n <SheetContent\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar\"\n data-mobile=\"true\"\n className=\"top-[var(--sidebar-top-offset,0px)] h-[calc(100svh-var(--sidebar-top-offset,0px))] w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\n style={\n {\n \"--sidebar-width\": SIDEBAR_WIDTH_MOBILE,\n } as any\n }\n side={side}\n >\n <SheetHeader className=\"sr-only\">\n <SheetTitle>Sidebar</SheetTitle>\n <SheetDescription>Displays the mobile sidebar.</SheetDescription>\n </SheetHeader>\n <div className=\"flex h-full w-full flex-col\">{children}</div>\n </SheetContent>\n </Sheet>\n )\n }\n\n return (\n <div\n className=\"group peer hidden text-sidebar-foreground md:block\"\n data-state={state}\n data-collapsible={state === \"collapsed\" ? collapsible : \"\"}\n data-variant={variant}\n data-side={side}\n data-slot=\"sidebar\"\n >\n {/* This is what handles the sidebar gap on desktop */}\n <div\n data-slot=\"sidebar-gap\"\n className={cn(\n \"relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear\",\n \"group-data-[collapsible=offExamples]:w-0\",\n \"group-data-[side=right]:rotate-180\",\n variant === \"floating\" || variant === \"inset\"\n ? \"group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon)\"\n )}\n />\n <div\n data-slot=\"sidebar-container\"\n className={cn(\n \"fixed top-[var(--sidebar-top-offset,0px)] bottom-0 z-10 hidden h-[calc(100svh-var(--sidebar-top-offset,0px))] w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex\",\n side === \"left\"\n ? \"left-0 group-data-[collapsible=offExamples]:left-[calc(var(--sidebar-width)*-1)]\"\n : \"right-0 group-data-[collapsible=offExamples]:right-[calc(var(--sidebar-width)*-1)]\",\n // Adjust the padding for floating and inset variants.\n variant === \"floating\" || variant === \"inset\"\n ? \"p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]\"\n : \"group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l\",\n className\n )}\n {...props}\n >\n <div\n data-sidebar=\"sidebar\"\n data-slot=\"sidebar-inner\"\n className=\"flex size-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 group-data-[variant=floating]:ring-sidebar-border\"\n >\n {children}\n </div>\n </div>\n </div>\n )\n}\n\nfunction SidebarTrigger({\n className,\n onClick,\n ...props\n}: React.ComponentProps<typeof Button>) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <Button\n data-sidebar=\"trigger\"\n data-slot=\"sidebar-trigger\"\n variant=\"ghost\"\n size=\"icon-sm\"\n className={cn(className)}\n onClick={(event) => {\n onClick?.(event)\n toggleSidebar()\n }}\n {...props}\n >\n <HugeiconsIcon icon={SidebarLeftIcon} strokeWidth={2} />\n <span className=\"sr-only\">Toggle Sidebar</span>\n </Button>\n )\n}\n\nfunction SidebarRail({ className, ...props }: React.ComponentProps<\"button\">) {\n const { toggleSidebar } = useSidebar()\n\n return (\n <button\n data-sidebar=\"rail\"\n data-slot=\"sidebar-rail\"\n aria-label=\"Toggle Sidebar\"\n tabIndex={-1}\n onClick={toggleSidebar}\n title=\"Toggle Sidebar\"\n className={cn(\n \"absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border sm:flex\",\n \"in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize\",\n \"[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize\",\n \"group-data-[collapsible=offExamples]:translate-x-0 group-data-[collapsible=offExamples]:after:left-full hover:group-data-[collapsible=offExamples]:bg-sidebar\",\n \"[[data-side=left][data-collapsible=offExamples]_&]:-right-2\",\n \"[[data-side=right][data-collapsible=offExamples]_&]:-left-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInset({ className, ...props }: React.ComponentProps<\"main\">) {\n return (\n <main\n data-slot=\"sidebar-inset\"\n className={cn(\n \"relative flex w-full flex-1 flex-col bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarInput({\n className,\n ...props\n}: React.ComponentProps<typeof Input>) {\n return (\n <Input\n data-slot=\"sidebar-input\"\n data-sidebar=\"input\"\n className={cn(\"h-8 w-full bg-background shadow-none\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-header\"\n data-sidebar=\"header\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-footer\"\n data-sidebar=\"footer\"\n className={cn(\"flex flex-col gap-2 p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof Separator>) {\n return (\n <Separator\n data-slot=\"sidebar-separator\"\n data-sidebar=\"separator\"\n className={cn(\"mx-2 w-auto bg-sidebar-border\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-content\"\n data-sidebar=\"content\"\n className={cn(\n \"no-scrollbar flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group\"\n data-sidebar=\"group\"\n className={cn(\"relative flex w-full min-w-0 flex-col p-2\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarGroupLabel({\n className,\n render,\n ...props\n}: useRender.ComponentProps<\"div\"> & React.ComponentProps<\"div\">) {\n return useRender({\n defaultTagName: \"div\",\n props: mergeProps<\"div\">(\n {\n className: cn(\n \"flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 ring-sidebar-ring outline-hidden transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"sidebar-group-label\",\n sidebar: \"group-label\",\n },\n })\n}\n\nfunction SidebarGroupAction({\n className,\n render,\n ...props\n}: useRender.ComponentProps<\"button\"> & React.ComponentProps<\"button\">) {\n return useRender({\n defaultTagName: \"button\",\n props: mergeProps<\"button\">(\n {\n className: cn(\n \"absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"sidebar-group-action\",\n sidebar: \"group-action\",\n },\n })\n}\n\nfunction SidebarGroupContent({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-group-content\"\n data-sidebar=\"group-content\"\n className={cn(\"w-full text-sm\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu\"\n data-sidebar=\"menu\"\n className={cn(\"flex w-full min-w-0 flex-col gap-1\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-item\"\n data-sidebar=\"menu-item\"\n className={cn(\"group/menu-item relative\", className)}\n {...props}\n />\n )\n}\n\nconst sidebarMenuButtonVariants = cva(\n \"peer/menu-button group/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm ring-sidebar-ring outline-hidden transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-active:bg-sidebar-accent data-active:font-medium data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate\",\n {\n variants: {\n variant: {\n default: \"hover:bg-sidebar-accent hover:text-sidebar-accent-foreground\",\n outline:\n \"bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]\",\n },\n size: {\n default: \"h-8 text-sm\",\n sm: \"h-7 text-xs\",\n lg: \"h-12 text-sm group-data-[collapsible=icon]:p-0!\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction SidebarMenuButton({\n render,\n isActive = false,\n variant = \"default\",\n size = \"default\",\n tooltip,\n className,\n ...props\n}: useRender.ComponentProps<\"button\"> &\n React.ComponentProps<\"button\"> & {\n isActive?: boolean\n tooltip?: string | React.ComponentProps<typeof TooltipContent>\n } & VariantProps<typeof sidebarMenuButtonVariants>) {\n const { isMobile, state } = useSidebar()\n const comp = useRender({\n defaultTagName: \"button\",\n props: mergeProps<\"button\">(\n {\n className: cn(sidebarMenuButtonVariants({ variant, size }), className),\n },\n props\n ),\n render: !tooltip ? render : TooltipTrigger,\n state: {\n slot: \"sidebar-menu-button\",\n sidebar: \"menu-button\",\n size,\n active: isActive,\n },\n })\n\n if (!tooltip) {\n return comp\n }\n\n if (typeof tooltip === \"string\") {\n tooltip = {\n children: tooltip,\n }\n }\n\n return (\n <Tooltip>\n {comp}\n <TooltipContent\n side=\"right\"\n align=\"center\"\n hidden={state !== \"collapsed\" || isMobile}\n {...tooltip}\n />\n </Tooltip>\n )\n}\n\nfunction SidebarMenuAction({\n className,\n render,\n showOnHover = false,\n ...props\n}: useRender.ComponentProps<\"button\"> &\n React.ComponentProps<\"button\"> & {\n showOnHover?: boolean\n }) {\n return useRender({\n defaultTagName: \"button\",\n props: mergeProps<\"button\">(\n {\n className: cn(\n \"absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground ring-sidebar-ring outline-hidden transition-transform group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 after:absolute after:-inset-2 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 md:after:hidden [&>svg]:size-4 [&>svg]:shrink-0\",\n showOnHover &&\n \"group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-active/menu-button:text-sidebar-accent-foreground data-open:opacity-100 md:opacity-0\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"sidebar-menu-action\",\n sidebar: \"menu-action\",\n },\n })\n}\n\nfunction SidebarMenuBadge({\n className,\n ...props\n}: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sidebar-menu-badge\"\n data-sidebar=\"menu-badge\"\n className={cn(\n \"pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium text-sidebar-foreground tabular-nums select-none group-data-[collapsible=icon]:hidden peer-hover/menu-button:text-sidebar-accent-foreground peer-data-active/menu-button:text-sidebar-accent-foreground peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSkeleton({\n className,\n showIcon = false,\n ...props\n}: React.ComponentProps<\"div\"> & {\n showIcon?: boolean\n}) {\n // Random width between 50 to 90%.\n const [width] = React.useState(() => {\n return `${Math.floor(Math.random() * 40) + 50}%`\n })\n\n return (\n <div\n data-slot=\"sidebar-menu-skeleton\"\n data-sidebar=\"menu-skeleton\"\n className={cn(\"flex h-8 items-center gap-2 rounded-md px-2\", className)}\n {...props}\n >\n {showIcon && (\n <Skeleton\n className=\"size-4 rounded-md\"\n data-sidebar=\"menu-skeleton-icon\"\n />\n )}\n <Skeleton\n className=\"h-4 max-w-(--skeleton-width) flex-1\"\n data-sidebar=\"menu-skeleton-text\"\n style={\n {\n \"--skeleton-width\": width,\n } as any\n }\n />\n </div>\n )\n}\n\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<\"ul\">) {\n return (\n <ul\n data-slot=\"sidebar-menu-sub\"\n data-sidebar=\"menu-sub\"\n className={cn(\n \"mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5 group-data-[collapsible=icon]:hidden\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubItem({\n className,\n ...props\n}: React.ComponentProps<\"li\">) {\n return (\n <li\n data-slot=\"sidebar-menu-sub-item\"\n data-sidebar=\"menu-sub-item\"\n className={cn(\"group/menu-sub-item relative\", className)}\n {...props}\n />\n )\n}\n\nfunction SidebarMenuSubButton({\n render,\n size = \"md\",\n isActive = false,\n className,\n ...props\n}: useRender.ComponentProps<\"a\"> &\n React.ComponentProps<\"a\"> & {\n size?: \"sm\" | \"md\"\n isActive?: boolean\n }) {\n return useRender({\n defaultTagName: \"a\",\n props: mergeProps<\"a\">(\n {\n className: cn(\n \"flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground ring-sidebar-ring outline-hidden group-data-[collapsible=icon]:hidden hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground data-[size=md]:text-sm data-[size=sm]:text-xs [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground\",\n className\n ),\n },\n props\n ),\n render,\n state: {\n slot: \"sidebar-menu-sub-button\",\n sidebar: \"menu-sub-button\",\n size,\n active: isActive,\n },\n })\n}\n\nexport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarInput,\n SidebarInset,\n SidebarMenu,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n SidebarProvider,\n SidebarRail,\n SidebarSeparator,\n SidebarTrigger,\n useSidebar,\n}\n"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/skeleton.tsx",
|
|
136
|
+
"type": "registry:ui",
|
|
137
|
+
"target": "components/example-apps/dashboard-3/components/ui/skeleton.tsx",
|
|
138
|
+
"content": "import type { ComponentPropsWithoutRef } from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Skeleton({ className, ...props }: ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"skeleton\"\n className={cn(\"animate-pulse rounded-md bg-muted\", className)}\n {...props}\n />\n )\n}\n\nexport { Skeleton }\n"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/table.tsx",
|
|
142
|
+
"type": "registry:ui",
|
|
143
|
+
"target": "components/example-apps/dashboard-3/components/ui/table.tsx",
|
|
144
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Table({ className, ...props }: React.ComponentProps<\"table\">) {\n return (\n <div\n data-slot=\"table-container\"\n className=\"relative w-full overflow-x-auto\"\n >\n <table\n data-slot=\"table\"\n className={cn(\"w-full caption-bottom text-sm\", className)}\n {...props}\n />\n </div>\n )\n}\n\nfunction TableHeader({ className, ...props }: React.ComponentProps<\"thead\">) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn(\"[&_tr]:border-b\", className)}\n {...props}\n />\n )\n}\n\nfunction TableBody({ className, ...props }: React.ComponentProps<\"tbody\">) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn(\"[&_tr:last-child]:border-0\", className)}\n {...props}\n />\n )\n}\n\nfunction TableFooter({ className, ...props }: React.ComponentProps<\"tfoot\">) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn(\n \"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableRow({ className, ...props }: React.ComponentProps<\"tr\">) {\n return (\n <tr\n data-slot=\"table-row\"\n className={cn(\n \"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableHead({ className, ...props }: React.ComponentProps<\"th\">) {\n return (\n <th\n data-slot=\"table-head\"\n className={cn(\n \"h-10 px-2 text-left align-middle font-medium whitespace-nowrap text-foreground [&:has([role=checkbox])]:pr-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCell({ className, ...props }: React.ComponentProps<\"td\">) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n \"p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction TableCaption({\n className,\n ...props\n}: React.ComponentProps<\"caption\">) {\n return (\n <caption\n data-slot=\"table-caption\"\n className={cn(\"mt-4 text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Table,\n TableHeader,\n TableBody,\n TableFooter,\n TableHead,\n TableRow,\n TableCell,\n TableCaption,\n}\n"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"path": "registry/example-apps/default/dashboard-3/components/ui/tooltip.tsx",
|
|
148
|
+
"type": "registry:ui",
|
|
149
|
+
"target": "components/example-apps/dashboard-3/components/ui/tooltip.tsx",
|
|
150
|
+
"content": "\"use client\"\n\nimport { Tooltip as TooltipPrimitive } from \"@base-ui/react/tooltip\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction TooltipProvider({\n delay = 0,\n ...props\n}: TooltipPrimitive.Provider.Props) {\n return (\n <TooltipPrimitive.Provider\n data-slot=\"tooltip-provider\"\n delay={delay}\n {...props}\n />\n )\n}\n\nfunction Tooltip({ ...props }: TooltipPrimitive.Root.Props) {\n return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n}\n\nfunction TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {\n return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />\n}\n\nfunction TooltipContent({\n className,\n side = \"top\",\n sideOffset = 4,\n align = \"center\",\n alignOffset = 0,\n children,\n ...props\n}: TooltipPrimitive.Popup.Props &\n Pick<\n TooltipPrimitive.Positioner.Props,\n \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n >) {\n return (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Positioner\n align={align}\n alignOffset={alignOffset}\n side={side}\n sideOffset={sideOffset}\n className=\"isolate z-50\"\n >\n <TooltipPrimitive.Popup\n data-slot=\"tooltip-content\"\n className={cn(\n \"data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 z-50 w-fit max-w-xs origin-(--transform-origin) rounded-md bg-foreground px-3 py-1.5 text-xs text-background\",\n className\n )}\n {...props}\n >\n {children}\n <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5\" />\n </TooltipPrimitive.Popup>\n </TooltipPrimitive.Positioner>\n </TooltipPrimitive.Portal>\n )\n}\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"path": "registry/example-apps/default/dashboard-3/hooks/use-mobile.ts",
|
|
154
|
+
"type": "registry:hook",
|
|
155
|
+
"target": "components/example-apps/dashboard-3/hooks/use-mobile.ts",
|
|
156
|
+
"content": "import { useMediaQuery } from \"usehooks-ts\"\n\nconst MOBILE_BREAKPOINT = 768\n\nexport function useIsMobile() {\n return useMediaQuery(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)\n}\n"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"path": "registry/example-apps/default/dashboard-3/index.tsx",
|
|
160
|
+
"type": "registry:file",
|
|
161
|
+
"target": "components/example-apps/dashboard-3/index.tsx",
|
|
162
|
+
"content": "/**\n * Wrapper export for embedding the dashboard in the docs app\n */\n\"use client\"\n\nimport { DashboardContent } from \"./components/dashboard/content\"\nimport { DashboardHeader } from \"./components/dashboard/header\"\nimport { DashboardSidebar } from \"./components/dashboard/sidebar\"\nimport { SidebarProvider } from \"./components/ui/sidebar\"\n\nexport default function Dashboard3Wrapper() {\n return (\n <SidebarProvider className=\"bg-sidebar\">\n <DashboardSidebar />\n <div className=\"h-full min-h-0 w-full overflow-hidden lg:px-2 lg:pb-2\">\n <div className=\"flex h-full min-h-0 w-full flex-col overflow-hidden bg-background lg:rounded-md lg:border\">\n <DashboardHeader />\n <main className=\"w-full flex-1 overflow-auto\">\n <DashboardContent />\n </main>\n </div>\n </div>\n </SidebarProvider>\n )\n}\n"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"path": "registry/example-apps/default/dashboard-3/lib/utils.ts",
|
|
166
|
+
"type": "registry:lib",
|
|
167
|
+
"target": "components/example-apps/dashboard-3/lib/utils.ts",
|
|
168
|
+
"content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"path": "registry/example-apps/default/dashboard-3/mock-data/dashboard.ts",
|
|
172
|
+
"type": "registry:lib",
|
|
173
|
+
"target": "components/example-apps/dashboard-3/mock-data/dashboard.ts",
|
|
174
|
+
"content": "export const dashboardStats = {\n totalProjects: { value: 24, change: 6 },\n totalTasks: { value: 186, change: 24 },\n inReviews: { value: 14, change: 4 },\n completedTasks: { value: 128, change: 19 },\n}\n\nexport const performanceScore = 92\nexport const performanceChange = 8\n\nexport const performanceChartData = [\n { day: \"Mon\", value: 74 },\n { day: \"Tue\", value: 81 },\n { day: \"Wed\", value: 89 },\n { day: \"Thu\", value: 93 },\n { day: \"Fri\", value: 90 },\n { day: \"Sat\", value: 86 },\n].map((d, i, arr) => {\n const isMax = d.value === Math.max(...arr.map((x) => x.value))\n return { ...d, isHighlight: isMax }\n})\n\nexport type ProjectStatus = \"in_progress\" | \"completed\" | \"on_hold\"\n\nexport interface TodayTask {\n id: string\n name: string\n projectId: string\n projectName: string\n projectColor: string\n dueDate: string\n}\n\nexport interface Project {\n id: string\n name: string\n color: string\n status: ProjectStatus\n progress: number\n totalTasks: number\n completedTasks: number\n dueDate: string\n ownerName: string\n ownerAvatarSeed: string\n}\n\nexport const todayTasks: TodayTask[] = [\n {\n id: \"1\",\n name: \"Publish revised syllabus notes\",\n projectId: \"p1\",\n projectName: \"Computer Science 201\",\n projectColor: \"blue\",\n dueDate: \"20 Feb 2026\",\n },\n {\n id: \"2\",\n name: \"Approve teaching assistant schedule\",\n projectId: \"p2\",\n projectName: \"TA Coordination\",\n projectColor: \"violet\",\n dueDate: \"21 Feb 2026\",\n },\n {\n id: \"3\",\n name: \"Upload week-5 lab rubric\",\n projectId: \"p3\",\n projectName: \"Lab Program\",\n projectColor: \"cyan\",\n dueDate: \"21 Feb 2026\",\n },\n {\n id: \"4\",\n name: \"Finalize advisor office hours\",\n projectId: \"p4\",\n projectName: \"Student Support\",\n projectColor: \"pink\",\n dueDate: \"22 Feb 2026\",\n },\n {\n id: \"5\",\n name: \"Lock exam room assignments\",\n projectId: \"p5\",\n projectName: \"Midterm Planning\",\n projectColor: \"amber\",\n dueDate: \"22 Feb 2026\",\n },\n]\n\nconst projectSeeds: Omit<Project, \"id\">[] = [\n {\n name: \"Computer Science 201\",\n color: \"blue\",\n status: \"in_progress\",\n progress: 78,\n totalTasks: 32,\n completedTasks: 25,\n dueDate: \"24 Feb 2026\",\n ownerName: \"Prof. Miles\",\n ownerAvatarSeed: \"miles\",\n },\n {\n name: \"TA Coordination\",\n color: \"violet\",\n status: \"in_progress\",\n progress: 66,\n totalTasks: 18,\n completedTasks: 12,\n dueDate: \"25 Feb 2026\",\n ownerName: \"Dr. Nina\",\n ownerAvatarSeed: \"nina\",\n },\n {\n name: \"Lab Program\",\n color: \"cyan\",\n status: \"in_progress\",\n progress: 71,\n totalTasks: 21,\n completedTasks: 15,\n dueDate: \"27 Feb 2026\",\n ownerName: \"Prof. Owen\",\n ownerAvatarSeed: \"owen\",\n },\n {\n name: \"Student Support\",\n color: \"pink\",\n status: \"in_progress\",\n progress: 58,\n totalTasks: 17,\n completedTasks: 10,\n dueDate: \"01 Mar 2026\",\n ownerName: \"Dean Harper\",\n ownerAvatarSeed: \"harper\",\n },\n {\n name: \"Midterm Planning\",\n color: \"amber\",\n status: \"on_hold\",\n progress: 31,\n totalTasks: 15,\n completedTasks: 4,\n dueDate: \"03 Mar 2026\",\n ownerName: \"Dr. Sato\",\n ownerAvatarSeed: \"sato\",\n },\n {\n name: \"Admissions Outreach\",\n color: \"blue\",\n status: \"in_progress\",\n progress: 64,\n totalTasks: 24,\n completedTasks: 16,\n dueDate: \"06 Mar 2026\",\n ownerName: \"R. Collins\",\n ownerAvatarSeed: \"collins\",\n },\n {\n name: \"Accreditation Audit\",\n color: \"violet\",\n status: \"completed\",\n progress: 100,\n totalTasks: 12,\n completedTasks: 12,\n dueDate: \"18 Feb 2026\",\n ownerName: \"L. Grant\",\n ownerAvatarSeed: \"grant\",\n },\n {\n name: \"Career Fair Prep\",\n color: \"cyan\",\n status: \"in_progress\",\n progress: 60,\n totalTasks: 20,\n completedTasks: 12,\n dueDate: \"02 Mar 2026\",\n ownerName: \"M. Price\",\n ownerAvatarSeed: \"price\",\n },\n {\n name: \"Library Digitization\",\n color: \"pink\",\n status: \"on_hold\",\n progress: 26,\n totalTasks: 19,\n completedTasks: 5,\n dueDate: \"10 Mar 2026\",\n ownerName: \"A. Rivera\",\n ownerAvatarSeed: \"rivera\",\n },\n {\n name: \"Course Catalog Refresh\",\n color: \"amber\",\n status: \"completed\",\n progress: 100,\n totalTasks: 11,\n completedTasks: 11,\n dueDate: \"17 Feb 2026\",\n ownerName: \"J. Kim\",\n ownerAvatarSeed: \"kim\",\n },\n {\n name: \"Faculty Onboarding\",\n color: \"blue\",\n status: \"in_progress\",\n progress: 75,\n totalTasks: 14,\n completedTasks: 11,\n dueDate: \"01 Mar 2026\",\n ownerName: \"P. Noor\",\n ownerAvatarSeed: \"noor\",\n },\n {\n name: \"Peer Tutoring\",\n color: \"violet\",\n status: \"in_progress\",\n progress: 63,\n totalTasks: 16,\n completedTasks: 10,\n dueDate: \"04 Mar 2026\",\n ownerName: \"E. Brooks\",\n ownerAvatarSeed: \"brooks\",\n },\n {\n name: \"Exam Proctoring\",\n color: \"cyan\",\n status: \"completed\",\n progress: 100,\n totalTasks: 9,\n completedTasks: 9,\n dueDate: \"16 Feb 2026\",\n ownerName: \"C. Walsh\",\n ownerAvatarSeed: \"walsh\",\n },\n {\n name: \"Scholarship Review\",\n color: \"pink\",\n status: \"in_progress\",\n progress: 55,\n totalTasks: 22,\n completedTasks: 12,\n dueDate: \"08 Mar 2026\",\n ownerName: \"T. Ali\",\n ownerAvatarSeed: \"ali\",\n },\n {\n name: \"Alumni Mentorship\",\n color: \"amber\",\n status: \"on_hold\",\n progress: 24,\n totalTasks: 13,\n completedTasks: 3,\n dueDate: \"12 Mar 2026\",\n ownerName: \"D. West\",\n ownerAvatarSeed: \"west\",\n },\n]\n\nexport const projects: Project[] = projectSeeds.map((p, i) => ({\n ...p,\n id: `p${i + 1}`,\n}))\n\nexport const welcomeSummary = {\n userName: \"Connor\",\n tasksDueToday: 8,\n overdueTasks: 2,\n upcomingDeadlines: 13,\n}\n\nexport const lastUpdated = \"18 Feb 2026\"\n"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"path": "registry/example-apps/default/dashboard-3/store/dashboard-store.ts",
|
|
178
|
+
"type": "registry:lib",
|
|
179
|
+
"target": "components/example-apps/dashboard-3/store/dashboard-store.ts",
|
|
180
|
+
"content": "import { create } from \"zustand\"\n\nimport type { ProjectStatus } from \"../mock-data/dashboard\"\n\ninterface DashboardStore {\n tasksSearchQuery: string\n tasksProjectFilter: string[]\n projectsSearchQuery: string\n projectStatusFilter: ProjectStatus | \"all\"\n setTasksSearchQuery: (query: string) => void\n setTasksProjectFilter: (projectIds: string[]) => void\n toggleTasksProjectFilter: (projectId: string) => void\n setProjectsSearchQuery: (query: string) => void\n setProjectStatusFilter: (filter: ProjectStatus | \"all\") => void\n clearFilters: () => void\n}\n\nexport const useDashboardStore = create<DashboardStore>((set) => ({\n tasksSearchQuery: \"\",\n tasksProjectFilter: [],\n projectsSearchQuery: \"\",\n projectStatusFilter: \"all\",\n setTasksSearchQuery: (query) => set({ tasksSearchQuery: query }),\n setTasksProjectFilter: (projectIds) =>\n set({ tasksProjectFilter: projectIds }),\n toggleTasksProjectFilter: (projectId) =>\n set((state) => ({\n tasksProjectFilter: state.tasksProjectFilter.includes(projectId)\n ? state.tasksProjectFilter.filter((id) => id !== projectId)\n : [...state.tasksProjectFilter, projectId],\n })),\n setProjectsSearchQuery: (query) => set({ projectsSearchQuery: query }),\n setProjectStatusFilter: (filter) => set({ projectStatusFilter: filter }),\n clearFilters: () =>\n set({\n tasksSearchQuery: \"\",\n tasksProjectFilter: [],\n projectsSearchQuery: \"\",\n projectStatusFilter: \"all\",\n }),\n}))\n"
|
|
181
|
+
}
|
|
182
|
+
],
|
|
183
|
+
"categories": [
|
|
184
|
+
"example-app",
|
|
185
|
+
"dashboards",
|
|
186
|
+
"modern",
|
|
187
|
+
"clean",
|
|
188
|
+
"minimalist"
|
|
189
|
+
],
|
|
190
|
+
"dependencies": [
|
|
191
|
+
"@base-ui/react",
|
|
192
|
+
"@hugeicons/core-free-icons",
|
|
193
|
+
"@hugeicons/react",
|
|
194
|
+
"@tanstack/react-table",
|
|
195
|
+
"class-variance-authority",
|
|
196
|
+
"clsx",
|
|
197
|
+
"next-themes",
|
|
198
|
+
"recharts",
|
|
199
|
+
"tailwind-merge",
|
|
200
|
+
"usehooks-ts",
|
|
201
|
+
"zustand"
|
|
202
|
+
],
|
|
203
|
+
"registryDependencies": [
|
|
204
|
+
"https://www.loveui.dev/r/avatar.json",
|
|
205
|
+
"https://www.loveui.dev/r/button.json",
|
|
206
|
+
"https://www.loveui.dev/r/chart.json",
|
|
207
|
+
"https://www.loveui.dev/r/checkbox.json",
|
|
208
|
+
"https://www.loveui.dev/r/input.json",
|
|
209
|
+
"https://www.loveui.dev/r/menu.json",
|
|
210
|
+
"https://www.loveui.dev/r/progress.json",
|
|
211
|
+
"https://www.loveui.dev/r/select.json",
|
|
212
|
+
"https://www.loveui.dev/r/table.json"
|
|
213
|
+
],
|
|
214
|
+
"meta": {
|
|
215
|
+
"source": "example-app",
|
|
216
|
+
"appName": "dashboard-3",
|
|
217
|
+
"routes": [
|
|
218
|
+
{
|
|
219
|
+
"path": "/",
|
|
220
|
+
"title": "Dashboard",
|
|
221
|
+
"description": "Modern dashboard interface"
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "datefield-rac",
|
|
4
|
+
"type": "registry:ui",
|
|
5
|
+
"dependencies": [
|
|
6
|
+
"react-aria-components"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/ui/datefield-rac.tsx",
|
|
11
|
+
"content": "\"use client\"\n\nimport {\n composeRenderProps,\n DateFieldProps,\n DateField as DateFieldRac,\n DateInputProps as DateInputPropsRac,\n DateInput as DateInputRac,\n DateSegmentProps,\n DateSegment as DateSegmentRac,\n DateValue as DateValueRac,\n TimeFieldProps,\n TimeField as TimeFieldRac,\n TimeValue as TimeValueRac,\n} from \"react-aria-components\"\n\nimport { cn } from \"@/registry/default/lib/utils\"\n\nfunction DateField<T extends DateValueRac>({\n className,\n children,\n ...props\n}: DateFieldProps<T>) {\n return (\n <DateFieldRac\n className={composeRenderProps(className, (className) => cn(className))}\n {...props}\n >\n {children}\n </DateFieldRac>\n )\n}\n\nfunction TimeField<T extends TimeValueRac>({\n className,\n children,\n ...props\n}: TimeFieldProps<T>) {\n return (\n <TimeFieldRac\n className={composeRenderProps(className, (className) => cn(className))}\n {...props}\n >\n {children}\n </TimeFieldRac>\n )\n}\n\nfunction DateSegment({ className, ...props }: DateSegmentProps) {\n return (\n <DateSegmentRac\n className={composeRenderProps(className, (className) =>\n cn(\n \"inline rounded p-0.5 text-foreground caret-transparent outline-hidden data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focused:bg-accent data-focused:text-foreground data-invalid:text-destructive data-invalid:data-focused:bg-destructive data-invalid:data-focused:text-white data-placeholder:text-muted-foreground/70 data-focused:data-placeholder:text-foreground data-invalid:data-placeholder:text-destructive data-invalid:data-focused:data-placeholder:text-white data-[type=literal]:px-0 data-[type=literal]:text-muted-foreground/70\",\n className\n )\n )}\n {...props}\n data-invalid\n />\n )\n}\n\nconst dateInputStyle =\n \"relative inline-flex h-9 w-full items-center overflow-hidden whitespace-nowrap rounded-md border border-input bg-background px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none data-focus-within:border-ring data-focus-within:ring-ring/50 data-focus-within:ring-[3px] data-focus-within:has-aria-invalid:ring-destructive/20 dark:data-focus-within:has-aria-invalid:ring-destructive/40 data-focus-within:has-aria-invalid:border-destructive\"\n\ninterface DateInputProps extends DateInputPropsRac {\n className?: string\n unstyled?: boolean\n}\n\nfunction DateInput({\n className,\n unstyled = false,\n ...props\n}: Omit<DateInputProps, \"children\">) {\n return (\n <DateInputRac\n className={composeRenderProps(className, (className) =>\n cn(!unstyled && dateInputStyle, className)\n )}\n {...props}\n >\n {(segment) => <DateSegment segment={segment} />}\n </DateInputRac>\n )\n}\n\nexport { DateField, DateInput, DateSegment, TimeField, dateInputStyle }\nexport type { DateInputProps }\n",
|
|
12
|
+
"type": "registry:ui"
|
|
13
|
+
}
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
{
|
|
11
11
|
"path": "registry/default/examples/deck-controlled.tsx",
|
|
12
|
-
"content": "\"use client\"\n\nimport { useState } from \"react\"\n\nimport {\n Deck,\n DeckCards,\n DeckEmpty,\n DeckItem,\n} from \"../../../../../packages/deck\"\nimport { Button } from \"../../../../../packages/ui/src/ui/button\"\n\nconst cards = [\n { id: 1, title: \"Card 1\", color: \"bg-red-500\" },\n { id: 2, title: \"Card 2\", color: \"bg-blue-500\" },\n { id: 3, title: \"Card 3\", color: \"bg-green-500\" },\n { id: 4, title: \"Card 4\", color: \"bg-yellow-500\" },\n { id: 5, title: \"Card 5\", color: \"bg-purple-500\" },\n]\n\nconst Example = () => {\n const [currentIndex, setCurrentIndex] = useState(0)\n const [animationDirection, setAnimationDirection] = useState<\n \"left\" | \"right\"\n >(\"left\")\n\n const nextCardLeft = () => {\n if (currentIndex < cards.length) {\n setAnimationDirection(\"left\")\n // Small delay to ensure direction is set before index changes\n setTimeout(() => {\n setCurrentIndex((prev) => prev + 1)\n }, 0)\n }\n }\n\n const nextCardRight = () => {\n if (currentIndex < cards.length) {\n setAnimationDirection(\"right\")\n // Small delay to ensure direction is set before index changes\n setTimeout(() => {\n setCurrentIndex((prev) => prev + 1)\n }, 0)\n }\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"text-center\">\n <p className=\"mb-2 text-sm text-muted-foreground\">\n Current Index: {currentIndex} | Next Direction: {animationDirection}\n </p>\n <div className=\"flex justify-center gap-2\">\n <Button\n disabled={currentIndex >= cards.length}\n onClick={nextCardLeft}\n size=\"sm\"\n variant=\"outline\"\n >\n Next (Left Animation)\n </Button>\n <Button\n disabled={currentIndex >= cards.length}\n onClick={nextCardRight}\n size=\"sm\"\n variant=\"outline\"\n >\n Next (Right Animation)\n </Button>\n </div>\n </div>\n\n <Deck className=\"mx-auto aspect-square w-40\">\n <DeckCards\n animateOnIndexChange={true}\n className=\"aspect-[2/3]\"\n currentIndex={currentIndex}\n indexChangeDirection={animationDirection}\n onCurrentIndexChange={setCurrentIndex}\n onSwipe={(_index, _direction) => {\n // Handle swipe action\n }}\n >\n {cards.map((card) => (\n <DeckItem\n className={`${card.color} flex-col text-center text-white`}\n key={card.id}\n >\n <h3 className=\"text-2xl font-bold\">{card.title}</h3>\n <p className=\"text-sm opacity-90\">Swipe or use buttons</p>\n </DeckItem>\n ))}\n </DeckCards>\n <DeckEmpty />\n </Deck>\n </div>\n )\n}\n\nexport default Example\n",
|
|
12
|
+
"content": "\"use client\"\n\nimport { useState } from \"react\"\n\nimport {\n Deck,\n DeckCards,\n DeckEmpty,\n DeckItem,\n} from \"../../../../../packages/deck\"\nimport { Button } from \"../../../../../packages/ui/src/ui/button\"\n\nconst cards = [\n { id: 1, title: \"Updated Card 1\", color: \"bg-red-500\" },\n { id: 2, title: \"Updated Card 2\", color: \"bg-blue-500\" },\n { id: 3, title: \"Updated Card 3\", color: \"bg-green-500\" },\n { id: 4, title: \"Updated Card 4\", color: \"bg-yellow-500\" },\n { id: 5, title: \"Updated Card 5\", color: \"bg-purple-500\" },\n]\n\nconst Example = () => {\n const [currentIndex, setCurrentIndex] = useState(0)\n const [animationDirection, setAnimationDirection] = useState<\n \"left\" | \"right\"\n >(\"left\")\n\n const nextCardLeft = () => {\n if (currentIndex < cards.length) {\n setAnimationDirection(\"left\")\n // Small delay to ensure direction is set before index changes\n setTimeout(() => {\n setCurrentIndex((prev) => prev + 1)\n }, 0)\n }\n }\n\n const nextCardRight = () => {\n if (currentIndex < cards.length) {\n setAnimationDirection(\"right\")\n // Small delay to ensure direction is set before index changes\n setTimeout(() => {\n setCurrentIndex((prev) => prev + 1)\n }, 0)\n }\n }\n\n return (\n <div className=\"space-y-4\">\n <div className=\"text-center\">\n <p className=\"mb-2 text-sm text-muted-foreground\">\n Updated Current Index: {currentIndex} Updated | Next Direction:{\" \"}\n {animationDirection}\n </p>\n <div className=\"flex justify-center gap-2\">\n <Button\n disabled={currentIndex >= cards.length}\n onClick={nextCardLeft}\n size=\"sm\"\n variant=\"outline\"\n >\n Updated Next (Left Animation)\n </Button>\n <Button\n disabled={currentIndex >= cards.length}\n onClick={nextCardRight}\n size=\"sm\"\n variant=\"outline\"\n >\n Updated Next (Right Animation)\n </Button>\n </div>\n </div>\n\n <Deck className=\"mx-auto aspect-square w-40\">\n <DeckCards\n animateOnIndexChange={true}\n className=\"aspect-[2/3]\"\n currentIndex={currentIndex}\n indexChangeDirection={animationDirection}\n onCurrentIndexChange={setCurrentIndex}\n onSwipe={(_index, _direction) => {\n // Handle swipe action\n }}\n >\n {cards.map((card) => (\n <DeckItem\n className={`${card.color} flex-col text-center text-white`}\n key={card.id}\n >\n <h3 className=\"text-2xl font-bold\">{card.title}</h3>\n <p className=\"text-sm opacity-90\">Updated Swipe or use buttons</p>\n </DeckItem>\n ))}\n </DeckCards>\n <DeckEmpty />\n </Deck>\n </div>\n )\n}\n\nexport default Example\n",
|
|
13
13
|
"type": "registry:example"
|
|
14
14
|
}
|
|
15
15
|
],
|