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,323 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "example-app-calendar",
|
|
4
|
+
"type": "registry:block",
|
|
5
|
+
"title": "Film Production Calendar",
|
|
6
|
+
"description": "A weekly production planner for shoot blocks, crew calls, and set operations.",
|
|
7
|
+
"files": [
|
|
8
|
+
{
|
|
9
|
+
"path": "registry/example-apps/default/calendar/components/calendar/calendar-controls.tsx",
|
|
10
|
+
"type": "registry:component",
|
|
11
|
+
"target": "components/example-apps/calendar/components/calendar/calendar-controls.tsx",
|
|
12
|
+
"content": "\"use client\"\n\nimport { useState } from \"react\"\nimport {\n Calendar01Icon,\n CancelCircleIcon,\n FilterIcon,\n Search01Icon,\n Settings01Icon,\n Tick02Icon,\n UserGroupIcon,\n UserRemove01Icon,\n VideoReplayIcon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { format } from \"date-fns\"\n\nimport { Button } from \"@loveui/ui/ui/button\"\nimport { Input } from \"@loveui/ui/ui/input\"\nimport { Popover, PopoverContent, PopoverTrigger } from \"@loveui/ui/ui/popover\"\nimport { Separator } from \"@loveui/ui/ui/separator\"\n\nimport { cn } from \"../../lib/utils\"\nimport { useCalendarStore } from \"../../store/calendar-store\"\nimport { Calendar } from \"../ui/calendar\"\n\nexport function CalendarControls() {\n const {\n searchQuery,\n setSearchQuery,\n goToToday,\n goToDate,\n currentWeekStart,\n eventTypeFilter,\n participantsFilter,\n setEventTypeFilter,\n setParticipantsFilter,\n } = useCalendarStore()\n const [datePickerOpen, setDatePickerOpen] = useState(false)\n const [filterOpen, setFilterOpen] = useState(false)\n const weekStart = format(currentWeekStart, \"MMM dd\")\n const weekEnd = format(\n new Date(currentWeekStart.getTime() + 6 * 24 * 60 * 60 * 1000),\n \"MMM dd yyyy\"\n )\n\n const hasActiveFilters =\n eventTypeFilter !== \"all\" || participantsFilter !== \"all\"\n\n return (\n <div className=\"border-b border-border px-3 py-4 md:px-6\">\n <div className=\"flex flex-wrap items-center gap-2 md:gap-3\">\n <div className=\"relative max-w-[280px] min-w-[200px] flex-1 shrink-0\">\n <HugeiconsIcon\n icon={Search01Icon}\n className=\"pointer-events-none absolute top-1/2 left-3 z-10 size-4 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n placeholder=\"Search in calendar...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"h-8 bg-background pr-9 pl-9\"\n />\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"absolute top-1/2 right-1 size-6 -translate-y-1/2\"\n >\n <HugeiconsIcon icon={Settings01Icon} className=\"size-3.5\" />\n </Button>\n </div>\n\n <Button\n variant=\"outline\"\n className=\"h-8 shrink-0 px-3\"\n onClick={goToToday}\n >\n Today\n </Button>\n\n <Popover open={datePickerOpen} onOpenChange={setDatePickerOpen}>\n <PopoverTrigger\n render={\n <Button\n variant=\"outline\"\n className={cn(\n \"h-8 shrink-0 justify-start gap-2 px-3 text-left font-normal\",\n \"hover:bg-accent\"\n )}\n >\n <HugeiconsIcon\n icon={Calendar01Icon}\n className=\"size-4 text-muted-foreground\"\n />\n <span className=\"text-xs text-foreground\">\n {weekStart} - {weekEnd}\n </span>\n </Button>\n }\n />\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={currentWeekStart}\n onSelect={(date) => {\n if (date) {\n goToDate(date)\n setDatePickerOpen(false)\n }\n }}\n initialFocus\n />\n </PopoverContent>\n </Popover>\n\n <div className=\"ml-auto\" />\n\n <Popover open={filterOpen} onOpenChange={setFilterOpen}>\n <PopoverTrigger\n render={\n <Button\n variant=\"outline\"\n className={cn(\n \"h-8 gap-2 px-3\",\n hasActiveFilters && \"bg-accent\"\n )}\n >\n <HugeiconsIcon icon={FilterIcon} className=\"size-4\" />\n <span className=\"hidden text-xs sm:inline\">Filter</span>\n {hasActiveFilters && (\n <span className=\"size-1.5 rounded-full bg-primary\" />\n )}\n </Button>\n }\n />\n <PopoverContent\n className=\"w-[288px]! max-w-[288px]! min-w-[288px]! p-4\"\n align=\"end\"\n >\n <div className=\"w-full space-y-4\">\n <div>\n <h4 className=\"mb-3 flex items-center gap-2 text-sm font-semibold\">\n <HugeiconsIcon\n icon={VideoReplayIcon}\n className=\"size-4 text-muted-foreground\"\n />\n Event Type\n </h4>\n <div className=\"space-y-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 w-full justify-between px-3\"\n onClick={() => setEventTypeFilter(\"all\")}\n >\n <span className=\"text-sm\">All events</span>\n {eventTypeFilter === \"all\" && (\n <HugeiconsIcon\n icon={Tick02Icon}\n className=\"size-4 text-primary\"\n />\n )}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 w-full justify-between px-3\"\n onClick={() => setEventTypeFilter(\"with-meeting\")}\n >\n <div className=\"flex items-center gap-2.5\">\n <HugeiconsIcon\n icon={VideoReplayIcon}\n className=\"size-4 text-cyan-500\"\n />\n <span className=\"text-sm\">With meeting</span>\n </div>\n {eventTypeFilter === \"with-meeting\" && (\n <HugeiconsIcon\n icon={Tick02Icon}\n className=\"size-4 text-primary\"\n />\n )}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 w-full justify-between px-3\"\n onClick={() => setEventTypeFilter(\"without-meeting\")}\n >\n <div className=\"flex items-center gap-2.5\">\n <HugeiconsIcon\n icon={CancelCircleIcon}\n className=\"size-4 text-muted-foreground\"\n />\n <span className=\"text-sm\">Without meeting</span>\n </div>\n {eventTypeFilter === \"without-meeting\" && (\n <HugeiconsIcon\n icon={Tick02Icon}\n className=\"size-4 text-primary\"\n />\n )}\n </Button>\n </div>\n </div>\n\n <Separator />\n\n <div>\n <h4 className=\"mb-3 flex items-center gap-2 text-sm font-semibold\">\n <HugeiconsIcon\n icon={UserGroupIcon}\n className=\"size-4 text-muted-foreground\"\n />\n Participants\n </h4>\n <div className=\"space-y-1\">\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 w-full justify-between px-3\"\n onClick={() => setParticipantsFilter(\"all\")}\n >\n <span className=\"text-sm\">All</span>\n {participantsFilter === \"all\" && (\n <HugeiconsIcon\n icon={Tick02Icon}\n className=\"size-4 text-primary\"\n />\n )}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 w-full justify-between px-3\"\n onClick={() => setParticipantsFilter(\"with-participants\")}\n >\n <div className=\"flex items-center gap-2.5\">\n <HugeiconsIcon\n icon={UserGroupIcon}\n className=\"size-4 text-muted-foreground\"\n />\n <span className=\"text-sm\">With participants</span>\n </div>\n {participantsFilter === \"with-participants\" && (\n <HugeiconsIcon\n icon={Tick02Icon}\n className=\"size-4 text-primary\"\n />\n )}\n </Button>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-9 w-full justify-between px-3\"\n onClick={() =>\n setParticipantsFilter(\"without-participants\")\n }\n >\n <div className=\"flex items-center gap-2.5\">\n <HugeiconsIcon\n icon={UserRemove01Icon}\n className=\"size-4 text-muted-foreground\"\n />\n <span className=\"text-sm\">Without participants</span>\n </div>\n {participantsFilter === \"without-participants\" && (\n <HugeiconsIcon\n icon={Tick02Icon}\n className=\"size-4 text-primary\"\n />\n )}\n </Button>\n </div>\n </div>\n\n {hasActiveFilters && (\n <>\n <Separator />\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-9 w-full\"\n onClick={() => {\n setEventTypeFilter(\"all\")\n setParticipantsFilter(\"all\")\n }}\n >\n Clear all filters\n </Button>\n </>\n )}\n </div>\n </PopoverContent>\n </Popover>\n </div>\n </div>\n )\n}\n"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"path": "registry/example-apps/default/calendar/components/calendar/calendar-day-column.tsx",
|
|
16
|
+
"type": "registry:component",
|
|
17
|
+
"target": "components/example-apps/calendar/components/calendar/calendar-day-column.tsx",
|
|
18
|
+
"content": "\"use client\"\n\nimport { Event } from \"../../mock-data/events\"\nimport {\n getEventHeight,\n getEventTop,\n HOUR_HEIGHT,\n HOURS_24,\n} from \"./calendar-utils\"\nimport { CurrentTimeIndicator } from \"./current-time-indicator\"\nimport { EventCard } from \"./event-card\"\n\ninterface CalendarDayColumnProps {\n day: Date\n dayIndex: number\n events: Event[]\n today: Date\n isTodayInWeek: boolean\n currentTime: Date\n onScroll: (index: number) => (e: React.UIEvent<HTMLDivElement>) => void\n scrollRef: (el: HTMLDivElement | null) => void\n onEventClick: (event: Event) => void\n}\n\nexport function CalendarDayColumn({\n day,\n dayIndex,\n events,\n today,\n isTodayInWeek,\n currentTime,\n onScroll,\n scrollRef,\n onEventClick,\n}: CalendarDayColumnProps) {\n return (\n <div\n ref={scrollRef}\n onScroll={onScroll(dayIndex)}\n className=\"relative min-w-44 flex-1 overflow-y-auto border-r border-border last:border-r-0\"\n >\n {HOURS_24.map((hour) => (\n <div\n key={hour}\n className=\"border-b border-border\"\n style={{ height: `${HOUR_HEIGHT}px` }}\n />\n ))}\n\n <CurrentTimeIndicator\n day={day}\n today={today}\n isTodayInWeek={isTodayInWeek}\n currentTime={currentTime}\n />\n\n {events.map((event) => {\n const top = getEventTop(event.startTime)\n const height = getEventHeight(event.startTime, event.endTime)\n\n return (\n <EventCard\n key={event.id}\n event={event}\n style={{\n top: `${top + 4}px`,\n height: `${height - 8}px`,\n }}\n onClick={() => onEventClick(event)}\n />\n )\n })}\n </div>\n )\n}\n"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"path": "registry/example-apps/default/calendar/components/calendar/calendar-header.tsx",
|
|
22
|
+
"type": "registry:component",
|
|
23
|
+
"target": "components/example-apps/calendar/components/calendar/calendar-header.tsx",
|
|
24
|
+
"content": "\"use client\"\n\nimport { useState } from \"react\"\nimport {\n Add01Icon,\n AlertCircleIcon,\n Calendar01Icon,\n Clock01Icon,\n Notification01Icon,\n Tick02Icon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { format } from \"date-fns\"\n\nimport { Button } from \"@loveui/ui/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from \"@loveui/ui/ui/menu\"\n\nimport { SidebarTrigger } from \"@/components/ui/sidebar\"\n\nimport { getTodayEvents } from \"../../mock-data/events\"\nimport { useCalendarStore } from \"../../store/calendar-store\"\nimport { ThemeToggle } from \"../theme-toggle\"\nimport { CreateEventDialog } from \"./create-event-dialog\"\nimport { SchedulePopover } from \"./schedule-popover\"\n\nexport function CalendarHeader() {\n const { currentWeekStart } = useCalendarStore()\n const todayEvents = getTodayEvents()\n const meetingsCount = todayEvents.filter(\n (e) =>\n e.title.toLowerCase().includes(\"call\") ||\n e.title.toLowerCase().includes(\"meeting\")\n ).length\n const eventsCount = todayEvents.length - meetingsCount\n const [createDialogOpen, setCreateDialogOpen] = useState(false)\n\n return (\n <>\n <CreateEventDialog\n open={createDialogOpen}\n onOpenChange={setCreateDialogOpen}\n />\n <div className=\"border-b border-border bg-background\">\n <div className=\"px-3 py-2.5 md:px-6 md:py-3\">\n <div className=\"flex flex-nowrap items-center justify-between gap-2 md:gap-3\">\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n <SidebarTrigger className=\"shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <h1 className=\"mb-0 truncate text-sm font-semibold text-foreground md:mb-1 md:text-base lg:text-lg\">\n {format(currentWeekStart, \"MMMM dd, yyyy\")}\n </h1>\n <p className=\"hidden text-xs text-muted-foreground md:block\">\n You have {meetingsCount} call\n {meetingsCount !== 1 ? \"s\" : \"\"} and {eventsCount} production\n block{eventsCount !== 1 ? \"s\" : \"\"} today 🎬\n </p>\n </div>\n </div>\n\n <div className=\"flex shrink-0 items-center gap-1 md:gap-1.5 lg:gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger\n render={\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"relative size-7 shrink-0 md:size-8\"\n >\n <HugeiconsIcon\n icon={Notification01Icon}\n className=\"size-4\"\n />\n <span className=\"absolute top-1 right-1 size-1 rounded-full bg-red-500\" />\n </Button>\n }\n />\n <DropdownMenuContent align=\"end\" className=\"w-80\">\n <DropdownMenuGroup>\n <DropdownMenuLabel>Notifications</DropdownMenuLabel>\n </DropdownMenuGroup>\n <DropdownMenuSeparator />\n <DropdownMenuItem className=\"flex cursor-pointer flex-col items-start gap-1 p-3\">\n <div className=\"flex w-full items-center gap-2\">\n <HugeiconsIcon\n icon={Tick02Icon}\n className=\"size-4 text-green-500\"\n />\n <span className=\"flex-1 text-sm font-medium\">\n Meeting confirmed\n </span>\n <span className=\"text-xs text-muted-foreground\">\n 2m ago\n </span>\n </div>\n <p className=\"pl-6 text-xs text-muted-foreground\">\n Unit call is confirmed for tomorrow at 6:30 AM\n </p>\n </DropdownMenuItem>\n <DropdownMenuItem className=\"flex cursor-pointer flex-col items-start gap-1 p-3\">\n <div className=\"flex w-full items-center gap-2\">\n <HugeiconsIcon\n icon={Clock01Icon}\n className=\"size-4 text-blue-500\"\n />\n <span className=\"flex-1 text-sm font-medium\">\n Reminder\n </span>\n <span className=\"text-xs text-muted-foreground\">\n 15m ago\n </span>\n </div>\n <p className=\"pl-6 text-xs text-muted-foreground\">\n Scene 40 rehearsal starts in 30 minutes\n </p>\n </DropdownMenuItem>\n <DropdownMenuItem className=\"flex cursor-pointer flex-col items-start gap-1 p-3\">\n <div className=\"flex w-full items-center gap-2\">\n <HugeiconsIcon\n icon={AlertCircleIcon}\n className=\"size-4 text-orange-500\"\n />\n <span className=\"flex-1 text-sm font-medium\">\n Event updated\n </span>\n <span className=\"text-xs text-muted-foreground\">\n 1h ago\n </span>\n </div>\n <p className=\"pl-6 text-xs text-muted-foreground\">\n Vendor status meeting moved to 11:30 AM\n </p>\n </DropdownMenuItem>\n <DropdownMenuItem className=\"flex cursor-pointer flex-col items-start gap-1 p-3\">\n <div className=\"flex w-full items-center gap-2\">\n <HugeiconsIcon\n icon={Tick02Icon}\n className=\"size-4 text-green-500\"\n />\n <span className=\"flex-1 text-sm font-medium\">\n New participant\n </span>\n <span className=\"text-xs text-muted-foreground\">\n 3h ago\n </span>\n </div>\n <p className=\"pl-6 text-xs text-muted-foreground\">\n Nora from post joined the teaser review call\n </p>\n </DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuItem className=\"cursor-pointer justify-center\">\n <span className=\"text-xs text-muted-foreground\">\n View all notifications\n </span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n\n <SchedulePopover>\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"size-7 shrink-0 md:size-8 md:w-auto md:gap-1.5 md:px-2\"\n >\n <HugeiconsIcon icon={Calendar01Icon} className=\"size-4\" />\n <span className=\"hidden lg:inline\">Call Sheet</span>\n </Button>\n </SchedulePopover>\n\n <Button\n size=\"icon\"\n className=\"size-7 shrink-0 bg-foreground text-background hover:bg-foreground/90 md:size-8 md:w-auto md:gap-1.5 md:px-2\"\n onClick={() => setCreateDialogOpen(true)}\n >\n <HugeiconsIcon icon={Add01Icon} className=\"size-4\" />\n <span className=\"hidden lg:inline\">Create Block</span>\n </Button>\n\n <ThemeToggle />\n </div>\n </div>\n </div>\n </div>\n </>\n )\n}\n"
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"path": "registry/example-apps/default/calendar/components/calendar/calendar-hours-column.tsx",
|
|
28
|
+
"type": "registry:component",
|
|
29
|
+
"target": "components/example-apps/calendar/components/calendar/calendar-hours-column.tsx",
|
|
30
|
+
"content": "\"use client\"\n\nimport { HOUR_HEIGHT, HOURS_24 } from \"./calendar-utils\"\n\ninterface CalendarHoursColumnProps {\n onScroll: (e: React.UIEvent<HTMLDivElement>) => void\n scrollRef: React.RefObject<HTMLDivElement | null>\n}\n\nexport function CalendarHoursColumn({\n onScroll,\n scrollRef,\n}: CalendarHoursColumnProps) {\n return (\n <div\n ref={scrollRef}\n onScroll={onScroll}\n className=\"relative w-[80px] shrink-0 overflow-y-auto border-r border-border md:w-[104px]\"\n >\n {HOURS_24.map((hour) => (\n <div\n key={hour}\n className=\"border-b border-border p-2 text-xs text-muted-foreground md:p-3 md:text-sm\"\n style={{ height: `${HOUR_HEIGHT}px` }}\n >\n {hour}\n </div>\n ))}\n </div>\n )\n}\n"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"path": "registry/example-apps/default/calendar/components/calendar/calendar-sidebar.tsx",
|
|
34
|
+
"type": "registry:component",
|
|
35
|
+
"target": "components/example-apps/calendar/components/calendar/calendar-sidebar.tsx",
|
|
36
|
+
"content": "\"use client\"\n\nimport { useState } from \"react\"\nimport Link from \"next/link\"\nimport {\n ArrowDown01Icon,\n ArrowUpRight01Icon,\n Calendar01Icon,\n ChartBarLineIcon,\n CrownIcon,\n Dollar01Icon,\n FileEditIcon,\n Folder01Icon,\n Home01Icon,\n Key01Icon,\n Layers01Icon,\n Location01Icon,\n MortarboardIcon,\n Search01Icon,\n Settings01Icon,\n Share01Icon,\n SparklesIcon,\n UserGroupIcon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\n\nimport { Avatar, AvatarImage } from \"@loveui/ui/ui/avatar\"\nimport { Button } from \"@loveui/ui/ui/button\"\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from \"@loveui/ui/ui/collapsible\"\nimport { Input } from \"@loveui/ui/ui/input\"\nimport { Kbd } from \"@loveui/ui/ui/kbd\"\n\nimport {\n Sidebar,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarHeader,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarSeparator,\n} from \"@/components/ui/sidebar\"\n\nimport { cn } from \"../../lib/utils\"\n\nexport function CalendarSidebar({\n ...props\n}: React.ComponentProps<typeof Sidebar>) {\n const [featuredOpen, setFeaturedOpen] = useState(true)\n\n return (\n <Sidebar className=\"lg:border-r-0!\" {...props}>\n <SidebarHeader className=\"pb-0\">\n <div className=\"px-2 py-1.5\">\n <div className=\"flex items-center gap-2\">\n <div className=\"flex size-9 shrink-0 items-center justify-center rounded-md border border-border bg-linear-to-br from-purple-500 to-pink-600 text-xs font-semibold text-white shadow\">\n FP\n </div>\n <div className=\"flex flex-col items-start\">\n <h1 className=\"text-sm font-semibold\">Film Ops Team</h1>\n <div className=\"flex items-center gap-1\">\n <HugeiconsIcon icon={Layers01Icon} className=\"size-3\" />\n <span className=\"text-xs\">6 active sets</span>\n </div>\n </div>\n </div>\n\n <Avatar className=\"size-7 border-2 border-background\">\n <AvatarImage src=\"/cl.png\" />\n </Avatar>\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-zinc-400 dark:text-muted-foreground\"\n />\n <Input\n placeholder=\"Search anything\"\n className=\"h-8 border-2 border-border bg-neutral-100 pr-8 pl-8 text-xs dark:bg-background\"\n />\n <div className=\"absolute top-1/2 right-2 flex shrink-0 -translate-y-1/2 items-center gap-0.5 rounded border border-border bg-sidebar px-1.5 py-0.5\">\n <span className=\"text-[10px] leading-none font-medium tracking-[-0.1px] text-muted-foreground\">\n ⌘\n </span>\n <Kbd className=\"h-auto min-w-0 border-0 bg-transparent px-0 py-0 text-[10px] leading-none tracking-[-0.1px]\">\n K\n </Kbd>\n </div>\n </div>\n </div>\n </SidebarHeader>\n\n <SidebarContent>\n <SidebarGroup>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={Home01Icon} className=\"size-4\" />\n <span>Production Board</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={UserGroupIcon} className=\"size-4\" />\n <span>Crew Calls</span>\n <span className=\"ml-auto text-xs\">18</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={FileEditIcon} className=\"size-4\" />\n <span>Shot List</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton\n isActive\n className=\"h-[26px] bg-neutral-100 text-xs text-zinc-950 hover:bg-neutral-100 hover:text-zinc-950 dark:bg-muted dark:text-foreground dark:hover:bg-muted dark:hover:text-foreground\"\n >\n <HugeiconsIcon icon={Calendar01Icon} className=\"size-4\" />\n <span>Calendar</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={ChartBarLineIcon} className=\"size-4\" />\n <span>Dailies</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={Location01Icon} className=\"size-4\" />\n <span>Locations</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={Folder01Icon} className=\"size-4\" />\n <span>Assets</span>\n <HugeiconsIcon\n icon={SparklesIcon}\n className=\"ml-auto size-3 text-cyan-500\"\n />\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={Share01Icon} className=\"size-4\" />\n <span>Crew Time</span>\n <HugeiconsIcon\n icon={SparklesIcon}\n className=\"ml-auto size-3 text-cyan-500\"\n />\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={Dollar01Icon} className=\"size-4\" />\n <span>Vendors</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n\n <SidebarSeparator className=\"mx-0\" />\n\n <SidebarGroup>\n <Collapsible open={featuredOpen} onOpenChange={setFeaturedOpen}>\n <CollapsibleTrigger\n nativeButton={false}\n render={\n <SidebarGroupLabel className=\"h-4 cursor-pointer pt-2 pb-4 text-xs text-muted-foreground hover:bg-transparent hover:text-foreground\">\n <span>Featured shoot day</span>\n <HugeiconsIcon\n icon={ArrowDown01Icon}\n className={cn(\n \"ml-auto size-4 transition-transform\",\n featuredOpen && \"rotate-180\"\n )}\n />\n </SidebarGroupLabel>\n }\n />\n <CollapsibleContent>\n <SidebarGroupContent>\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={FileEditIcon} className=\"size-4\" />\n <span>Downtown Rooftop Night Exterior</span>\n <HugeiconsIcon\n icon={SparklesIcon}\n className=\"ml-auto size-3 text-cyan-500\"\n />\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={FileEditIcon} className=\"size-4\" />\n <span>Train Platform Dialogue</span>\n <HugeiconsIcon\n icon={SparklesIcon}\n className=\"ml-auto size-3 text-cyan-500\"\n />\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={FileEditIcon} className=\"size-4\" />\n <span>Harbor Chase Unit B</span>\n <HugeiconsIcon\n icon={SparklesIcon}\n className=\"ml-auto size-3 text-cyan-500\"\n />\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={FileEditIcon} className=\"size-4\" />\n <span>Studio Insert Pickups</span>\n <HugeiconsIcon\n icon={SparklesIcon}\n className=\"ml-auto size-3 text-cyan-500\"\n />\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={FileEditIcon} className=\"size-4\" />\n <span>Closing Credits Pickup</span>\n <HugeiconsIcon\n icon={SparklesIcon}\n className=\"ml-auto size-3 text-cyan-500\"\n />\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </SidebarGroupContent>\n </CollapsibleContent>\n </Collapsible>\n </SidebarGroup>\n </SidebarContent>\n\n <SidebarFooter className=\"p-4\">\n <div className=\"my-4 space-y-1\">\n <SidebarMenu>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={SparklesIcon} className=\"size-4\" />\n <span>What's New</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={MortarboardIcon} className=\"size-4\" />\n <span>Crew Academy</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={Key01Icon} className=\"size-4\" />\n <span>Gear Access</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n <SidebarMenuItem>\n <SidebarMenuButton className=\"h-[26px] text-xs text-zinc-950 hover:bg-neutral-100/50 hover:text-zinc-950 dark:text-muted-foreground dark:hover:bg-muted/50 dark:hover:text-foreground\">\n <HugeiconsIcon icon={CrownIcon} className=\"size-4\" />\n <span>Run of Show</span>\n </SidebarMenuButton>\n </SidebarMenuItem>\n </SidebarMenu>\n </div>\n\n <div className=\"flex items-center gap-3\">\n <Avatar className=\"size-7 border-2 border-background\">\n <AvatarImage src=\"https://api.dicebear.com/9.x/glass/svg?seed=user\" />\n </Avatar>\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-xs font-medium text-foreground\">FP</p>\n <p className=\"truncate text-xs text-muted-foreground\">\n filmops.studio\n </p>\n </div>\n <HugeiconsIcon\n icon={Settings01Icon}\n className=\"size-4 text-muted-foreground\"\n />\n </div>\n </SidebarFooter>\n </Sidebar>\n )\n}\n"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"path": "registry/example-apps/default/calendar/components/calendar/calendar-utils.ts",
|
|
40
|
+
"type": "registry:component",
|
|
41
|
+
"target": "components/example-apps/calendar/components/calendar/calendar-utils.ts",
|
|
42
|
+
"content": "export const HOURS_24 = Array.from({ length: 24 }, (_, i) => {\n if (i === 0) return \"12 AM\"\n if (i < 12) return `${i} AM`\n if (i === 12) return \"12 PM\"\n return `${i - 12} PM`\n})\n\nexport const HOUR_HEIGHT = 120\nexport const INITIAL_SCROLL_OFFSET = 9 * HOUR_HEIGHT\n\nexport function getEventHeight(startTime: string, endTime: string): number {\n const [startHour, startMin] = startTime.split(\":\").map(Number)\n const [endHour, endMin] = endTime.split(\":\").map(Number)\n\n const startTotal = startHour * 60 + (startMin || 0)\n const endTotal = endHour * 60 + (endMin || 0)\n const duration = endTotal - startTotal\n\n if (duration < 60) {\n return Math.max(24, Math.round((duration / 60) * HOUR_HEIGHT))\n }\n\n return Math.max(40, Math.round((duration / 60) * HOUR_HEIGHT))\n}\n\nexport function getEventTop(startTime: string): number {\n const [hour, minute] = startTime.split(\":\").map(Number)\n const totalMinutes = hour * 60 + (minute || 0)\n const offset = totalMinutes * (HOUR_HEIGHT / 60)\n return Math.max(0, Math.round(offset))\n}\n\nexport function getCurrentTimePosition(date: Date = new Date()): number {\n const hour = date.getHours()\n const minute = date.getMinutes()\n const totalMinutes = hour * 60 + minute\n const offset = totalMinutes * (HOUR_HEIGHT / 60)\n return Math.max(0, Math.round(offset))\n}\n\nexport function getEventDuration(startTime: string, endTime: string): number {\n const [startHour, startMin] = startTime.split(\":\").map(Number)\n const [endHour, endMin] = endTime.split(\":\").map(Number)\n const startTotal = startHour * 60 + (startMin || 0)\n const endTotal = endHour * 60 + (endMin || 0)\n return endTotal - startTotal\n}\n"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"path": "registry/example-apps/default/calendar/components/calendar/calendar-view.tsx",
|
|
46
|
+
"type": "registry:component",
|
|
47
|
+
"target": "components/example-apps/calendar/components/calendar/calendar-view.tsx",
|
|
48
|
+
"content": "\"use client\"\n\nimport { useEffect, useRef, useState } from \"react\"\nimport { format } from \"date-fns\"\n\nimport { Event } from \"../../mock-data/events\"\nimport { useCalendarStore } from \"../../store/calendar-store\"\nimport { CalendarDayColumn } from \"./calendar-day-column\"\nimport { CalendarHoursColumn } from \"./calendar-hours-column\"\nimport { INITIAL_SCROLL_OFFSET } from \"./calendar-utils\"\nimport { CalendarWeekHeader } from \"./calendar-week-header\"\nimport { EventSheet } from \"./event-sheet\"\n\nexport function CalendarView() {\n const { goToNextWeek, goToPreviousWeek, getWeekDays, getCurrentWeekEvents } =\n useCalendarStore()\n const weekDays = getWeekDays()\n const events = getCurrentWeekEvents()\n const hoursScrollRef = useRef<HTMLDivElement>(null)\n const daysScrollRefs = useRef<(HTMLDivElement | null)[]>([])\n const hasScrolledRef = useRef(false)\n const [currentTime, setCurrentTime] = useState(new Date())\n const [selectedEvent, setSelectedEvent] = useState<Event | null>(null)\n const [sheetOpen, setSheetOpen] = useState(false)\n\n const today = new Date()\n\n useEffect(() => {\n const interval = setInterval(() => {\n setCurrentTime(new Date())\n }, 60000)\n\n return () => clearInterval(interval)\n }, [])\n\n const eventsByDay: Record<string, Event[]> = {}\n weekDays.forEach((day) => {\n const dayStr = format(day, \"yyyy-MM-dd\")\n eventsByDay[dayStr] = events.filter((e) => e.date === dayStr)\n })\n\n const isTodayInWeek = weekDays.some(\n (day) => format(day, \"yyyy-MM-dd\") === format(today, \"yyyy-MM-dd\")\n )\n\n useEffect(() => {\n const scrollToInitial = () => {\n if (!hasScrolledRef.current && hoursScrollRef.current) {\n hoursScrollRef.current.scrollTop = INITIAL_SCROLL_OFFSET\n daysScrollRefs.current.forEach((ref) => {\n if (ref) {\n ref.scrollTop = INITIAL_SCROLL_OFFSET\n }\n })\n hasScrolledRef.current = true\n }\n }\n\n scrollToInitial()\n const timeoutId = setTimeout(scrollToInitial, 100)\n return () => clearTimeout(timeoutId)\n }, [weekDays])\n\n const handleHoursScroll = (e: React.UIEvent<HTMLDivElement>) => {\n const scrollTop = e.currentTarget.scrollTop\n daysScrollRefs.current.forEach((ref) => {\n if (ref) {\n ref.scrollTop = scrollTop\n }\n })\n }\n\n const handleDayScroll =\n (index: number) => (e: React.UIEvent<HTMLDivElement>) => {\n const scrollTop = e.currentTarget.scrollTop\n if (hoursScrollRef.current) {\n hoursScrollRef.current.scrollTop = scrollTop\n }\n daysScrollRefs.current.forEach((ref, idx) => {\n if (ref && idx !== index) {\n ref.scrollTop = scrollTop\n }\n })\n }\n\n const handleEventClick = (event: Event) => {\n setSelectedEvent(event)\n setSheetOpen(true)\n }\n\n return (\n <>\n <EventSheet\n event={selectedEvent}\n open={sheetOpen}\n onOpenChange={setSheetOpen}\n />\n <div className=\"flex h-full w-full flex-col overflow-x-auto\">\n <CalendarWeekHeader\n weekDays={weekDays}\n onPreviousWeek={goToPreviousWeek}\n onNextWeek={goToNextWeek}\n />\n\n <div className=\"flex w-max min-w-full\">\n <CalendarHoursColumn\n onScroll={handleHoursScroll}\n scrollRef={hoursScrollRef}\n />\n\n {weekDays.map((day, dayIndex) => {\n const dayStr = format(day, \"yyyy-MM-dd\")\n const dayEvents = eventsByDay[dayStr] || []\n\n return (\n <CalendarDayColumn\n key={day.toISOString()}\n day={day}\n dayIndex={dayIndex}\n events={dayEvents}\n today={today}\n isTodayInWeek={isTodayInWeek}\n currentTime={currentTime}\n onScroll={handleDayScroll}\n scrollRef={(el) => {\n daysScrollRefs.current[dayIndex] = el\n }}\n onEventClick={handleEventClick}\n />\n )\n })}\n </div>\n </div>\n </>\n )\n}\n"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"path": "registry/example-apps/default/calendar/components/calendar/calendar-week-header.tsx",
|
|
52
|
+
"type": "registry:component",
|
|
53
|
+
"target": "components/example-apps/calendar/components/calendar/calendar-week-header.tsx",
|
|
54
|
+
"content": "\"use client\"\n\nimport { ArrowLeft01Icon, ArrowRight01Icon } from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { format } from \"date-fns\"\n\nimport { Button } from \"@loveui/ui/ui/button\"\n\ninterface CalendarWeekHeaderProps {\n weekDays: Date[]\n onPreviousWeek: () => void\n onNextWeek: () => void\n}\n\nexport function CalendarWeekHeader({\n weekDays,\n onPreviousWeek,\n onNextWeek,\n}: CalendarWeekHeaderProps) {\n return (\n <div className=\"sticky top-0 z-30 flex w-max min-w-full border-b border-border bg-background\">\n <div className=\"flex w-[80px] shrink-0 items-center gap-1 border-r border-border p-1.5 md:w-[104px] md:gap-2 md:p-2\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7 md:size-8\"\n onClick={onPreviousWeek}\n >\n <HugeiconsIcon icon={ArrowLeft01Icon} className=\"size-4 md:size-5\" />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-7 md:size-8\"\n onClick={onNextWeek}\n >\n <HugeiconsIcon icon={ArrowRight01Icon} className=\"size-4 md:size-5\" />\n </Button>\n </div>\n {weekDays.map((day) => (\n <div\n key={day.toISOString()}\n className=\"flex min-w-44 flex-1 items-center border-r border-border p-1.5 last:border-r-0 md:p-2\"\n >\n <div className=\"text-xs font-medium text-foreground md:text-sm\">\n {format(day, \"dd EEE\").toUpperCase()}\n </div>\n </div>\n ))}\n </div>\n )\n}\n"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"path": "registry/example-apps/default/calendar/components/calendar/create-event-dialog.tsx",
|
|
58
|
+
"type": "registry:component",
|
|
59
|
+
"target": "components/example-apps/calendar/components/calendar/create-event-dialog.tsx",
|
|
60
|
+
"content": "\"use client\"\n\nimport { useState } from \"react\"\nimport { Calendar01Icon, Clock01Icon } from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { format } from \"date-fns\"\n\nimport { Button } from \"@loveui/ui/ui/button\"\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from \"@loveui/ui/ui/dialog\"\nimport { Input } from \"@loveui/ui/ui/input\"\nimport { Label } from \"@loveui/ui/ui/label\"\nimport { Popover, PopoverContent, PopoverTrigger } from \"@loveui/ui/ui/popover\"\n\nimport { cn } from \"../../lib/utils\"\nimport { Event } from \"../../mock-data/events\"\nimport { useCalendarStore } from \"../../store/calendar-store\"\nimport { Calendar } from \"../ui/calendar\"\n\ninterface CreateEventDialogProps {\n open: boolean\n onOpenChange: (open: boolean) => void\n}\n\nexport function CreateEventDialog({\n open,\n onOpenChange,\n}: CreateEventDialogProps) {\n const { addEvent, goToDate } = useCalendarStore()\n const [title, setTitle] = useState(\"\")\n const [date, setDate] = useState<Date | undefined>(new Date())\n const [startTime, setStartTime] = useState(\"\")\n const [endTime, setEndTime] = useState(\"\")\n const [meetingLink, setMeetingLink] = useState(\"\")\n const [timezone, setTimezone] = useState(\"\")\n const [participants, setParticipants] = useState(\"\")\n const [datePickerOpen, setDatePickerOpen] = useState(false)\n\n const handleSubmit = (e: React.FormEvent) => {\n e.preventDefault()\n\n if (!title || !date || !startTime || !endTime) {\n return\n }\n\n const participantsList = participants\n .split(\",\")\n .map((p) => p.trim())\n .filter((p) => p.length > 0)\n\n const newEvent: Omit<Event, \"id\"> = {\n title,\n date: format(date, \"yyyy-MM-dd\"),\n startTime,\n endTime,\n participants: participantsList.length > 0 ? participantsList : [\"user1\"],\n meetingLink: meetingLink || undefined,\n timezone: timezone || undefined,\n }\n\n addEvent(newEvent)\n goToDate(date)\n\n setTitle(\"\")\n setDate(new Date())\n setStartTime(\"\")\n setEndTime(\"\")\n setMeetingLink(\"\")\n setTimezone(\"\")\n setParticipants(\"\")\n onOpenChange(false)\n }\n\n return (\n <Dialog open={open} onOpenChange={onOpenChange}>\n <DialogContent className=\"sm:max-w-[500px]\">\n <DialogHeader>\n <DialogTitle>Create Event</DialogTitle>\n <DialogDescription>\n Add a new event to your calendar. Fill in the details below.\n </DialogDescription>\n </DialogHeader>\n <form onSubmit={handleSubmit}>\n <div className=\"grid gap-4 py-4\">\n <div className=\"grid gap-2\">\n <Label htmlFor=\"title\">Title</Label>\n <Input\n id=\"title\"\n placeholder=\"Event title\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n required\n />\n </div>\n\n <div className=\"grid gap-2\">\n <Label>Date</Label>\n <Popover open={datePickerOpen} onOpenChange={setDatePickerOpen}>\n <PopoverTrigger\n render={\n <Button\n variant=\"outline\"\n className={cn(\n \"w-full justify-start text-left font-normal\",\n !date && \"text-muted-foreground\"\n )}\n >\n <HugeiconsIcon\n icon={Calendar01Icon}\n className=\"mr-2 size-4\"\n />\n {date ? format(date, \"PPP\") : <span>Pick a date</span>}\n </Button>\n }\n />\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={(selectedDate) => {\n setDate(selectedDate)\n setDatePickerOpen(false)\n }}\n initialFocus\n />\n </PopoverContent>\n </Popover>\n </div>\n\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <div className=\"grid gap-2\">\n <Label htmlFor=\"startTime\">Start Time</Label>\n <div className=\"relative\">\n <HugeiconsIcon\n icon={Clock01Icon}\n className=\"pointer-events-none absolute top-1/2 left-3 z-10 size-4 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n id=\"startTime\"\n type=\"time\"\n value={startTime}\n onChange={(e) => setStartTime(e.target.value)}\n className=\"pl-9\"\n required\n />\n </div>\n </div>\n\n <div className=\"grid gap-2\">\n <Label htmlFor=\"endTime\">End Time</Label>\n <div className=\"relative\">\n <HugeiconsIcon\n icon={Clock01Icon}\n className=\"pointer-events-none absolute top-1/2 left-3 z-10 size-4 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n id=\"endTime\"\n type=\"time\"\n value={endTime}\n onChange={(e) => setEndTime(e.target.value)}\n className=\"pl-9\"\n required\n />\n </div>\n </div>\n </div>\n\n <div className=\"grid gap-2\">\n <Label htmlFor=\"participants\">\n Participants (comma-separated)\n </Label>\n <Input\n id=\"participants\"\n placeholder=\"user1, user2, user3\"\n value={participants}\n onChange={(e) => setParticipants(e.target.value)}\n />\n </div>\n\n <div className=\"grid gap-2\">\n <Label htmlFor=\"meetingLink\">Meeting Link (optional)</Label>\n <Input\n id=\"meetingLink\"\n type=\"url\"\n placeholder=\"https://meet.google.com/...\"\n value={meetingLink}\n onChange={(e) => setMeetingLink(e.target.value)}\n />\n </div>\n\n <div className=\"grid gap-2\">\n <Label htmlFor=\"timezone\">Timezone (optional)</Label>\n <Input\n id=\"timezone\"\n placeholder=\"GMT+7 Pontianak\"\n value={timezone}\n onChange={(e) => setTimezone(e.target.value)}\n />\n </div>\n </div>\n <DialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => onOpenChange(false)}\n >\n Cancel\n </Button>\n <Button type=\"submit\">Create Event</Button>\n </DialogFooter>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"path": "registry/example-apps/default/calendar/components/calendar/current-time-indicator.tsx",
|
|
64
|
+
"type": "registry:component",
|
|
65
|
+
"target": "components/example-apps/calendar/components/calendar/current-time-indicator.tsx",
|
|
66
|
+
"content": "\"use client\"\n\nimport { isSameDay } from \"date-fns\"\n\nimport { getCurrentTimePosition } from \"./calendar-utils\"\n\ninterface CurrentTimeIndicatorProps {\n day: Date\n today: Date\n isTodayInWeek: boolean\n currentTime: Date\n}\n\nexport function CurrentTimeIndicator({\n day,\n today,\n isTodayInWeek,\n currentTime,\n}: CurrentTimeIndicatorProps) {\n if (!isTodayInWeek || !isSameDay(day, today)) {\n return null\n }\n\n const currentTimePosition = getCurrentTimePosition(currentTime)\n\n return (\n <div\n className=\"pointer-events-none absolute right-0 left-0 z-20 flex items-center\"\n style={{\n top: `${currentTimePosition}px`,\n transform: \"translateY(-50%)\",\n }}\n >\n <div className=\"-ml-1 size-2 shrink-0 rounded-full bg-red-500\" />\n <div className=\"h-0.5 flex-1 bg-red-500\" />\n </div>\n )\n}\n"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"path": "registry/example-apps/default/calendar/components/calendar/event-card.tsx",
|
|
70
|
+
"type": "registry:component",
|
|
71
|
+
"target": "components/example-apps/calendar/components/calendar/event-card.tsx",
|
|
72
|
+
"content": "\"use client\"\n\nimport { ArrowUpRight01Icon } from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\n\nimport { Avatar, AvatarImage } from \"@loveui/ui/ui/avatar\"\n\nimport { Event } from \"../../mock-data/events\"\nimport { getEventDuration } from \"./calendar-utils\"\n\ninterface EventCardProps {\n event: Event\n style: any\n onClick?: () => void\n}\n\nexport function EventCard({ event, style, onClick }: EventCardProps) {\n const duration = getEventDuration(event.startTime, event.endTime)\n const isVeryShortEvent = duration < 30\n const isMediumEvent = duration >= 25 && duration < 60\n const timeStr = `${event.startTime} - ${event.endTime}${\n event.timezone ? ` (${event.timezone})` : \"\"\n }`\n const hasMultipleParticipants = event.participants.length > 3\n\n if (isVeryShortEvent) {\n return (\n <div\n className=\"absolute right-2 left-2 z-10 flex cursor-pointer items-center gap-1.5 rounded-lg border border-border bg-card px-2 py-1 transition-colors hover:bg-muted\"\n style={style}\n onClick={onClick}\n >\n <div className=\"size-1.5 shrink-0 rounded-full bg-cyan-500\" />\n <h4 className=\"flex-1 truncate text-[10px] font-semibold text-foreground\">\n {event.title}\n </h4>\n <span className=\"shrink-0 text-[9px] text-muted-foreground\">\n {event.startTime}\n </span>\n </div>\n )\n }\n\n if (isMediumEvent) {\n return (\n <div\n className=\"absolute right-2 left-2 z-10 cursor-pointer rounded-lg border border-border bg-card px-2.5 py-2 transition-colors hover:bg-muted\"\n style={style}\n onClick={onClick}\n >\n <div className=\"flex h-full flex-col gap-1\">\n <div className=\"flex items-center gap-1.5\">\n <div className=\"size-1.5 shrink-0 rounded-full bg-cyan-500\" />\n <h4 className=\"flex-1 truncate text-[10px] font-semibold text-foreground\">\n {event.title}\n </h4>\n </div>\n <p className=\"text-[9px] tracking-wide text-muted-foreground uppercase\">\n {timeStr}\n </p>\n </div>\n </div>\n )\n }\n\n return (\n <div\n className=\"absolute right-2 left-2 z-10 cursor-pointer rounded-lg border border-border bg-card p-3 transition-colors hover:bg-muted\"\n style={style}\n onClick={onClick}\n >\n <div className=\"flex h-full flex-col gap-1\">\n <div className=\"min-h-0 flex-1\">\n <h4\n className={`mb-1 text-xs font-semibold text-foreground ${\n duration <= 60 ? \"truncate whitespace-nowrap\" : \"line-clamp-2\"\n }`}\n >\n {event.title}\n </h4>\n <p className=\"mb-2 text-[10px] tracking-wide text-muted-foreground uppercase\">\n {timeStr}\n </p>\n\n {event.participants.length > 0 && (\n <div className=\"mb-2 flex items-center gap-1.5\">\n <div className=\"flex -space-x-1.5\">\n {event.participants.slice(0, 3).map((participant, idx) => (\n <Avatar\n key={idx}\n className=\"size-5 border-2 border-background\"\n >\n <AvatarImage\n src={`https://api.dicebear.com/9.x/glass/svg?seed=${participant}`}\n />\n </Avatar>\n ))}\n </div>\n {hasMultipleParticipants && (\n <span className=\"text-[10px] text-muted-foreground\">\n +{event.participants.length - 3}\n </span>\n )}\n </div>\n )}\n </div>\n\n {event.meetingLink && (\n <div className=\"mt-auto flex items-center gap-1.5 text-[10px] text-cyan-500\">\n <div className=\"flex size-4 shrink-0 items-center justify-center rounded bg-cyan-500/10\">\n <svg className=\"size-2.5\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path\n d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5v-9l6 4.5-6 4.5z\"\n fill=\"currentColor\"\n />\n </svg>\n </div>\n <span className=\"flex-1 truncate\">Join on Google Meet</span>\n <HugeiconsIcon\n icon={ArrowUpRight01Icon}\n className=\"size-3 shrink-0\"\n />\n </div>\n )}\n </div>\n </div>\n )\n}\n"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"path": "registry/example-apps/default/calendar/components/calendar/event-sheet.tsx",
|
|
76
|
+
"type": "registry:component",
|
|
77
|
+
"target": "components/example-apps/calendar/components/calendar/event-sheet.tsx",
|
|
78
|
+
"content": "\"use client\"\n\nimport { useState } from \"react\"\nimport {\n ArrowUpRight01Icon,\n Calendar01Icon,\n CallIcon,\n Cancel01Icon,\n Delete01Icon,\n FileEditIcon,\n Layers01Icon,\n LinkSquare01Icon,\n NoteIcon,\n Notification01Icon,\n PencilEdit01Icon,\n Tick02Icon,\n UserGroupIcon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { format } from \"date-fns\"\n\nimport { Avatar, AvatarImage } from \"@loveui/ui/ui/avatar\"\nimport { Button } from \"@loveui/ui/ui/button\"\nimport { Kbd } from \"@loveui/ui/ui/kbd\"\nimport {\n Sheet,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetTitle,\n} from \"@loveui/ui/ui/sheet\"\n\nimport { Event } from \"../../mock-data/events\"\n\ninterface EventSheetProps {\n event: Event | null\n open: boolean\n onOpenChange: (open: boolean) => void\n}\n\nfunction formatTime(time: string): string {\n const [hour, minute] = time.split(\":\").map(Number)\n const period = hour >= 12 ? \"PM\" : \"AM\"\n const displayHour = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour\n return `${displayHour}:${minute.toString().padStart(2, \"0\")} ${period}`\n}\n\nfunction formatDate(dateStr: string): string {\n const date = new Date(dateStr + \"T00:00:00\")\n return format(date, \"EEEE, MMMM dd\")\n}\n\nfunction getMeetingCode(link?: string): string {\n if (!link) return \"\"\n const match = link.match(/\\/[a-z-]+$/)\n if (match) {\n return match[0].slice(1).replace(/-/g, \" \").toUpperCase()\n }\n return \"dra-jhgg-mvn\"\n}\n\nfunction getParticipantName(participantId: string): string {\n const names: Record<string, string> = {\n user1: \"Maya Ortiz\",\n user2: \"Liam Carter\",\n user3: \"Nora Singh\",\n user4: \"Theo Bennett\",\n user5: \"Ari Kim\",\n }\n\n return (\n names[participantId] ||\n participantId.charAt(0).toUpperCase() + participantId.slice(1)\n )\n}\n\nfunction getParticipantEmail(participantId: string): string {\n const emails: Record<string, string> = {\n user1: \"maya.ortiz@filmops.studio\",\n user2: \"liam.carter@filmops.studio\",\n user3: \"nora.singh@filmops.studio\",\n user4: \"theo.bennett@filmops.studio\",\n user5: \"ari.kim@filmops.studio\",\n }\n\n return emails[participantId] || `${participantId}@gmail.com`\n}\n\nfunction copyToClipboard(text: string) {\n navigator.clipboard.writeText(text)\n}\n\nexport function EventSheet({ event, open, onOpenChange }: EventSheetProps) {\n const [rsvpStatus, setRsvpStatus] = useState<\"yes\" | \"no\" | \"maybe\" | null>(\n null\n )\n\n if (!event) return null\n\n const dateStr = formatDate(event.date)\n const startTimeStr = formatTime(event.startTime)\n const endTimeStr = formatTime(event.endTime)\n const timezone = event.timezone || \"PST Los Angeles\"\n const meetingCode = getMeetingCode(event.meetingLink)\n\n const organizer = event.participants[0] || \"user1\"\n const organizerName = getParticipantName(organizer)\n const organizerEmail = getParticipantEmail(organizer)\n const otherParticipants = event.participants.slice(1)\n\n const mockParticipants = [\n {\n id: organizer,\n name: organizerName,\n email: organizerEmail,\n isOrganizer: true,\n rsvp: \"yes\" as const,\n },\n ...otherParticipants.slice(0, 3).map((p) => ({\n id: p,\n name: getParticipantName(p),\n email: getParticipantEmail(p),\n isOrganizer: false,\n rsvp: \"yes\" as const,\n })),\n {\n id: \"user5\",\n name: \"Ari Kim\",\n email: \"ari.kim@filmops.studio\",\n isOrganizer: false,\n rsvp: rsvpStatus || (\"yes\" as const),\n isYou: true,\n },\n ]\n\n const yesCount = mockParticipants.filter((p) => p.rsvp === \"yes\").length\n\n return (\n <Sheet open={open} onOpenChange={onOpenChange}>\n <SheetContent\n side=\"right\"\n className=\"w-full overflow-y-auto border-t border-r border-l p-0 sm:max-w-[560px] [&>button]:hidden\"\n >\n <div className=\"flex h-full flex-col\">\n <SheetHeader className=\"border-b border-border px-4 pt-4 pb-4\">\n <div className=\"mb-3 flex items-center justify-between\">\n <div className=\"flex items-center gap-3\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-8 hover:bg-muted\"\n >\n <HugeiconsIcon\n icon={PencilEdit01Icon}\n className=\"size-4 text-muted-foreground\"\n />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-8 hover:bg-muted\"\n >\n <HugeiconsIcon\n icon={FileEditIcon}\n className=\"size-4 text-muted-foreground\"\n />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-8 hover:bg-muted\"\n >\n <HugeiconsIcon\n icon={Layers01Icon}\n className=\"size-4 text-muted-foreground\"\n />\n </Button>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-8 hover:bg-muted\"\n >\n <HugeiconsIcon\n icon={Delete01Icon}\n className=\"size-4 text-muted-foreground\"\n />\n </Button>\n </div>\n <SheetClose\n render={\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-6 rounded-full bg-muted hover:bg-muted\"\n >\n <HugeiconsIcon\n icon={Cancel01Icon}\n className=\"size-4 text-muted-foreground\"\n />\n </Button>\n }\n />\n </div>\n\n <div className=\"mb-4 flex flex-col gap-1\">\n <SheetTitle className=\"text-xl leading-normal font-semibold text-foreground\">\n {event.title}\n </SheetTitle>\n <div className=\"flex items-center gap-2 text-[13px] font-medium text-muted-foreground\">\n <span>{dateStr}</span>\n <span className=\"size-1 rounded-full bg-muted-foreground\" />\n <span>\n {startTimeStr} - {endTimeStr}\n </span>\n <span className=\"size-1 rounded-full bg-muted-foreground\" />\n <span>{timezone}</span>\n </div>\n </div>\n\n <Button variant=\"outline\">\n <span>Propose new time</span>\n <HugeiconsIcon icon={ArrowUpRight01Icon} className=\"size-4\" />\n </Button>\n </SheetHeader>\n\n <div className=\"flex-1 overflow-y-auto px-4 py-4\">\n <div className=\"mx-auto flex max-w-[512px] flex-col gap-4\">\n <div className=\"flex flex-col gap-4\">\n {mockParticipants.map((participant) => (\n <div\n key={participant.id}\n className=\"relative flex items-start gap-3\"\n >\n <Avatar className=\"size-7 shrink-0 border-[1.4px] border-background\">\n <AvatarImage\n src={`https://api.dicebear.com/9.x/glass/svg?seed=${participant.id}`}\n />\n </Avatar>\n <div className=\"min-w-0 flex-1\">\n <div className=\"relative flex items-start gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"relative mb-1 flex items-center gap-1.5\">\n <p className=\"text-[13px] leading-[18px] font-medium text-foreground\">\n {participant.name}\n </p>\n {participant.isOrganizer && (\n <span className=\"rounded-full px-0.5 py-0.5 text-[10px] font-medium text-cyan-500\">\n Organizer\n </span>\n )}\n {participant.isYou && (\n <span className=\"rounded-full px-0.5 py-0.5 text-[10px] font-medium text-foreground\">\n You\n </span>\n )}\n </div>\n <p className=\"text-xs leading-none text-muted-foreground\">\n {participant.email}\n </p>\n </div>\n <HugeiconsIcon\n icon={Tick02Icon}\n className=\"absolute top-[17px] right-0 size-3 shrink-0 text-green-500\"\n />\n </div>\n {participant.isYou && (\n <div className=\"mt-3 flex gap-1.5 rounded-lg bg-muted/50 p-1.5\">\n <Button\n variant={rsvpStatus === \"yes\" ? \"default\" : \"ghost\"}\n size=\"sm\"\n className={`h-[30px] flex-1 text-xs font-medium ${\n rsvpStatus === \"yes\"\n ? \"bg-foreground text-background shadow-sm hover:bg-foreground/90\"\n : \"text-muted-foreground\"\n }`}\n onClick={() => setRsvpStatus(\"yes\")}\n >\n Yes\n </Button>\n <Button\n variant={rsvpStatus === \"no\" ? \"default\" : \"ghost\"}\n size=\"sm\"\n className={`h-[30px] flex-1 text-xs font-medium ${\n rsvpStatus === \"no\"\n ? \"bg-foreground text-background shadow-sm hover:bg-foreground/90\"\n : \"text-muted-foreground\"\n }`}\n onClick={() => setRsvpStatus(\"no\")}\n >\n No\n </Button>\n <Button\n variant={\n rsvpStatus === \"maybe\" ? \"default\" : \"ghost\"\n }\n size=\"sm\"\n className={`h-[30px] flex-1 text-xs font-medium ${\n rsvpStatus === \"maybe\"\n ? \"bg-foreground text-background shadow-sm hover:bg-foreground/90\"\n : \"text-muted-foreground\"\n }`}\n onClick={() => setRsvpStatus(\"maybe\")}\n >\n Maybe\n </Button>\n </div>\n )}\n </div>\n </div>\n ))}\n </div>\n\n {event.meetingLink && (\n <div className=\"flex flex-col gap-2 border-t border-border pt-4\">\n <div className=\"mb-2 flex items-center gap-2\">\n <div className=\"size-6 shrink-0\">\n <svg\n viewBox=\"0 0 24 24\"\n className=\"size-full\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5v-9l6 4.5-6 4.5z\"\n fill=\"#22C55E\"\n />\n </svg>\n </div>\n <p className=\"flex-1 text-xs font-medium text-muted-foreground\">\n Meeting in Google Meet\n </p>\n <p className=\"text-xs text-muted-foreground\">\n Code: {meetingCode}\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button\n className=\"h-8 flex-1 gap-2 bg-foreground text-xs font-medium text-background shadow-sm hover:bg-foreground/90\"\n onClick={() => {\n if (event.meetingLink) {\n window.open(event.meetingLink, \"_blank\")\n }\n }}\n >\n <span>Join Google Meet meeting</span>\n <div className=\"flex gap-0.5\">\n <Kbd className=\"rounded bg-white/14 px-1.5 py-1 text-[10.8px] text-white\">\n ⌘\n </Kbd>\n <Kbd className=\"w-[18px] rounded bg-white/14 px-1.5 py-1 text-[10.8px] text-white\">\n J\n </Kbd>\n </div>\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-8 gap-2 border-border text-xs\"\n onClick={() => {\n if (event.meetingLink) {\n copyToClipboard(event.meetingLink)\n }\n }}\n >\n <HugeiconsIcon\n icon={LinkSquare01Icon}\n className=\"size-4\"\n />\n <span>Copy link</span>\n </Button>\n </div>\n </div>\n )}\n\n <div className=\"flex flex-col gap-2 border-t border-border pt-4\">\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <div className=\"p-1\">\n <HugeiconsIcon\n icon={Notification01Icon}\n className=\"size-4\"\n />\n </div>\n <span>Reminder: 30min before</span>\n </div>\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <div className=\"p-1\">\n <HugeiconsIcon icon={Calendar01Icon} className=\"size-4\" />\n </div>\n <span>Organizer: {organizerEmail}</span>\n </div>\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <div className=\"p-1\">\n <HugeiconsIcon icon={CallIcon} className=\"size-4\" />\n </div>\n <span>(US) +1 904-330-1131</span>\n </div>\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <div className=\"p-1\">\n <HugeiconsIcon icon={UserGroupIcon} className=\"size-4\" />\n </div>\n <span>\n {mockParticipants.length} persons\n <span className=\"mx-1\">•</span>\n {yesCount} yes\n </span>\n </div>\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <div className=\"p-1\">\n <HugeiconsIcon icon={NoteIcon} className=\"size-4\" />\n </div>\n <span>Notes from Organizer</span>\n </div>\n </div>\n\n <div className=\"border-t border-border pt-4\">\n <p className=\"text-xs leading-[1.6] text-muted-foreground\">\n During today's daily check-in, we had an in-depth\n discussion about the MVP (Minimum Viable Product). We agreed\n on the core features that need to be included, focusing on the\n AI-conducted interviews and the memoir compilation\n functionality.\n </p>\n </div>\n </div>\n </div>\n </div>\n </SheetContent>\n </Sheet>\n )\n}\n"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"path": "registry/example-apps/default/calendar/components/calendar/schedule-popover.tsx",
|
|
82
|
+
"type": "registry:component",
|
|
83
|
+
"target": "components/example-apps/calendar/components/calendar/schedule-popover.tsx",
|
|
84
|
+
"content": "\"use client\"\n\nimport { useState } from \"react\"\nimport {\n Calendar01Icon,\n Clock01Icon,\n UserGroupIcon,\n VideoReplayIcon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { format } from \"date-fns\"\n\nimport { Button } from \"@loveui/ui/ui/button\"\nimport { Input } from \"@loveui/ui/ui/input\"\nimport { Label } from \"@loveui/ui/ui/label\"\nimport { Popover, PopoverContent, PopoverTrigger } from \"@loveui/ui/ui/popover\"\nimport { Separator } from \"@loveui/ui/ui/separator\"\n\nimport { cn } from \"../../lib/utils\"\nimport { Calendar } from \"../ui/calendar\"\n\ninterface SchedulePopoverProps {\n children: React.ReactElement<Record<string, unknown>>\n}\n\nexport function SchedulePopover({ children }: SchedulePopoverProps) {\n const [open, setOpen] = useState(false)\n const [date, setDate] = useState<Date | undefined>(new Date())\n const [startTime, setStartTime] = useState(\"\")\n const [endTime, setEndTime] = useState(\"\")\n const [datePickerOpen, setDatePickerOpen] = useState(false)\n\n const handleSchedule = () => {\n if (!date || !startTime || !endTime) {\n return\n }\n setOpen(false)\n setDate(new Date())\n setStartTime(\"\")\n setEndTime(\"\")\n }\n\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger render={children} />\n <PopoverContent className=\"w-80 p-4\" align=\"end\">\n <div className=\"space-y-4\">\n <div>\n <h4 className=\"mb-3 text-sm font-semibold\">Schedule Meeting</h4>\n <p className=\"mb-4 text-xs text-muted-foreground\">\n Quick schedule a meeting or event\n </p>\n </div>\n\n <div className=\"space-y-3\">\n <div className=\"grid gap-2\">\n <Label className=\"text-xs\">Date</Label>\n <Popover open={datePickerOpen} onOpenChange={setDatePickerOpen}>\n <PopoverTrigger\n render={\n <Button\n variant=\"outline\"\n className={cn(\n \"h-9 w-full justify-start text-left font-normal\",\n !date && \"text-muted-foreground\"\n )}\n >\n <HugeiconsIcon\n icon={Calendar01Icon}\n className=\"mr-2 size-4\"\n />\n {date ? format(date, \"PPP\") : <span>Pick a date</span>}\n </Button>\n }\n />\n <PopoverContent className=\"w-auto p-0\" align=\"start\">\n <Calendar\n mode=\"single\"\n selected={date}\n onSelect={(selectedDate) => {\n setDate(selectedDate)\n setDatePickerOpen(false)\n }}\n initialFocus\n />\n </PopoverContent>\n </Popover>\n </div>\n\n <div className=\"grid grid-cols-2 gap-3\">\n <div className=\"grid gap-2\">\n <Label className=\"text-xs\">Start</Label>\n <div className=\"relative\">\n <HugeiconsIcon\n icon={Clock01Icon}\n className=\"pointer-events-none absolute top-1/2 left-2.5 z-10 size-3.5 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n type=\"time\"\n value={startTime}\n onChange={(e) => setStartTime(e.target.value)}\n className=\"h-9 pl-8 text-xs\"\n placeholder=\"09:00\"\n />\n </div>\n </div>\n\n <div className=\"grid gap-2\">\n <Label className=\"text-xs\">End</Label>\n <div className=\"relative\">\n <HugeiconsIcon\n icon={Clock01Icon}\n className=\"pointer-events-none absolute top-1/2 left-2.5 z-10 size-3.5 -translate-y-1/2 text-muted-foreground\"\n />\n <Input\n type=\"time\"\n value={endTime}\n onChange={(e) => setEndTime(e.target.value)}\n className=\"h-9 pl-8 text-xs\"\n placeholder=\"10:00\"\n />\n </div>\n </div>\n </div>\n\n <Separator />\n\n <div className=\"flex flex-col gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-8 justify-start gap-2 text-xs\"\n >\n <HugeiconsIcon icon={UserGroupIcon} className=\"size-3.5\" />\n <span>Add participants</span>\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-8 justify-start gap-2 text-xs\"\n >\n <HugeiconsIcon icon={VideoReplayIcon} className=\"size-3.5\" />\n <span>Add video call</span>\n </Button>\n </div>\n\n <div className=\"flex gap-2 pt-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n className=\"h-8 flex-1 text-xs\"\n onClick={() => setOpen(false)}\n >\n Cancel\n </Button>\n <Button\n size=\"sm\"\n className=\"h-8 flex-1 text-xs\"\n onClick={handleSchedule}\n disabled={!date || !startTime || !endTime}\n >\n Schedule\n </Button>\n </div>\n </div>\n </div>\n </PopoverContent>\n </Popover>\n )\n}\n"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"path": "registry/example-apps/default/calendar/components/theme-provider.tsx",
|
|
88
|
+
"type": "registry:component",
|
|
89
|
+
"target": "components/example-apps/calendar/components/theme-provider.tsx",
|
|
90
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\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"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"path": "registry/example-apps/default/calendar/components/theme-toggle.tsx",
|
|
94
|
+
"type": "registry:component",
|
|
95
|
+
"target": "components/example-apps/calendar/components/theme-toggle.tsx",
|
|
96
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\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 { setTheme, theme } = 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"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
"path": "registry/example-apps/default/calendar/components/ui/alert-dialog.tsx",
|
|
100
|
+
"type": "registry:ui",
|
|
101
|
+
"target": "components/example-apps/calendar/components/ui/alert-dialog.tsx",
|
|
102
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport type { ComponentPropsWithoutRef } from \"react\"\nimport { AlertDialog as AlertDialogPrimitive } from \"@base-ui/react/alert-dialog\"\n\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"./button\"\n\nfunction AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {\n return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" {...props} />\n}\n\nfunction AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) {\n return (\n <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />\n )\n}\n\nfunction AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) {\n return (\n <AlertDialogPrimitive.Portal data-slot=\"alert-dialog-portal\" {...props} />\n )\n}\n\nfunction AlertDialogOverlay({\n className,\n ...props\n}: AlertDialogPrimitive.Backdrop.Props) {\n return (\n <AlertDialogPrimitive.Backdrop\n data-slot=\"alert-dialog-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 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDialogContent({\n className,\n size = \"default\",\n ...props\n}: AlertDialogPrimitive.Popup.Props & {\n size?: \"default\" | \"sm\"\n}) {\n return (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Popup\n data-slot=\"alert-dialog-content\"\n data-size={size}\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 group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-6 rounded-xl bg-background p-6 ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-lg\",\n className\n )}\n {...props}\n />\n </AlertDialogPortal>\n )\n}\n\nfunction AlertDialogHeader({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-header\"\n className={cn(\n \"grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDialogFooter({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-footer\"\n className={cn(\n \"flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDialogMedia({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"alert-dialog-media\"\n className={cn(\n \"mb-2 inline-flex size-16 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-8\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {\n return (\n <AlertDialogPrimitive.Title\n data-slot=\"alert-dialog-title\"\n className={cn(\n \"text-lg font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {\n return (\n <AlertDialogPrimitive.Description\n data-slot=\"alert-dialog-description\"\n className={cn(\n \"text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AlertDialogAction({\n className,\n ...props\n}: React.ComponentProps<typeof Button>) {\n return (\n <Button\n data-slot=\"alert-dialog-action\"\n className={cn(className)}\n {...props}\n />\n )\n}\n\nfunction AlertDialogCancel({\n className,\n variant = \"outline\",\n size = \"default\",\n ...props\n}: AlertDialogPrimitive.Close.Props &\n Pick<React.ComponentProps<typeof Button>, \"variant\" | \"size\">) {\n return (\n <AlertDialogPrimitive.Close\n data-slot=\"alert-dialog-cancel\"\n className={cn(className)}\n render={<Button variant={variant} size={size} />}\n {...props}\n />\n )\n}\n\nexport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogOverlay,\n AlertDialogPortal,\n AlertDialogTitle,\n AlertDialogTrigger,\n}\n"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"path": "registry/example-apps/default/calendar/components/ui/avatar.tsx",
|
|
106
|
+
"type": "registry:ui",
|
|
107
|
+
"target": "components/example-apps/calendar/components/ui/avatar.tsx",
|
|
108
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport type { ComponentPropsWithoutRef } 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({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"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 }: ComponentPropsWithoutRef<\"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}: ComponentPropsWithoutRef<\"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"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"path": "registry/example-apps/default/calendar/components/ui/badge.tsx",
|
|
112
|
+
"type": "registry:ui",
|
|
113
|
+
"target": "components/example-apps/calendar/components/ui/badge.tsx",
|
|
114
|
+
"content": "import { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst badgeVariants = cva(\n \"group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all transition-colors focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground [a]:hover:bg-primary/80\",\n secondary:\n \"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80\",\n destructive:\n \"bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20\",\n outline:\n \"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground\",\n ghost:\n \"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nfunction Badge({\n className,\n variant = \"default\",\n render,\n ...props\n}: useRender.ComponentProps<\"span\"> & VariantProps<typeof badgeVariants>) {\n return useRender({\n defaultTagName: \"span\",\n props: mergeProps<\"span\">(\n {\n className: cn(badgeVariants({ className, variant })),\n },\n props\n ),\n render,\n state: {\n slot: \"badge\",\n variant,\n },\n })\n}\n\nexport { Badge, badgeVariants }\n"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"path": "registry/example-apps/default/calendar/components/ui/button.tsx",
|
|
118
|
+
"type": "registry:ui",
|
|
119
|
+
"target": "components/example-apps/calendar/components/ui/button.tsx",
|
|
120
|
+
"content": "import * as React from \"react\"\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-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-[3px] 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\nconst Button = React.forwardRef<\n HTMLButtonElement,\n ButtonPrimitive.Props & VariantProps<typeof buttonVariants>\n>(({ className, variant = \"default\", size = \"default\", ...props }, ref) => {\n return (\n <ButtonPrimitive\n ref={ref}\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n})\nButton.displayName = \"Button\"\n\nexport { Button, buttonVariants }\n"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"path": "registry/example-apps/default/calendar/components/ui/calendar.tsx",
|
|
124
|
+
"type": "registry:ui",
|
|
125
|
+
"target": "components/example-apps/calendar/components/ui/calendar.tsx",
|
|
126
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArrowDown01Icon,\n ArrowLeft01Icon,\n ArrowRight01Icon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\nimport { DayButton, DayPicker, getDefaultClassNames } from \"react-day-picker\"\n\nimport { cn } from \"../../lib/utils\"\nimport { Button, buttonVariants } from \"./button\"\n\nfunction Calendar({\n className,\n classNames,\n showOutsideDays = true,\n captionLayout = \"label\",\n buttonVariant = \"ghost\",\n formatters,\n components,\n ...props\n}: React.ComponentProps<typeof DayPicker> & {\n buttonVariant?: React.ComponentProps<typeof Button>[\"variant\"]\n}) {\n const defaultClassNames = getDefaultClassNames()\n\n return (\n <DayPicker\n showOutsideDays={showOutsideDays}\n className={cn(\n \"group/calendar bg-background p-3 [--cell-size:--spacing(8)] [[data-slot=card-content]_&]:bg-transparent [[data-slot=popover-content]_&]:bg-transparent\",\n String.raw`rtl:**:[.rdp-button\\_next>svg]:rotate-180`,\n String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\n className\n )}\n captionLayout={captionLayout}\n formatters={{\n formatMonthDropdown: (date) =>\n date.toLocaleString(\"default\", { month: \"short\" }),\n ...formatters,\n }}\n classNames={{\n root: cn(\"w-fit\", defaultClassNames.root),\n months: cn(\n \"relative flex flex-col gap-4 md:flex-row\",\n defaultClassNames.months\n ),\n month: cn(\"flex w-full flex-col gap-4\", defaultClassNames.month),\n nav: cn(\n \"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1\",\n defaultClassNames.nav\n ),\n button_previous: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\n defaultClassNames.button_previous\n ),\n button_next: cn(\n buttonVariants({ variant: buttonVariant }),\n \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\n defaultClassNames.button_next\n ),\n month_caption: cn(\n \"flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)\",\n defaultClassNames.month_caption\n ),\n dropdowns: cn(\n \"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium\",\n defaultClassNames.dropdowns\n ),\n dropdown_root: cn(\n \"relative rounded-md border border-input shadow-xs has-focus:border-ring has-focus:ring-[3px] has-focus:ring-ring/50\",\n defaultClassNames.dropdown_root\n ),\n dropdown: cn(\n \"absolute inset-0 bg-popover opacity-0\",\n defaultClassNames.dropdown\n ),\n caption_label: cn(\n \"font-medium select-none\",\n captionLayout === \"label\"\n ? \"text-sm\"\n : \"flex h-8 items-center gap-1 rounded-md pr-1 pl-2 text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground\",\n defaultClassNames.caption_label\n ),\n table: \"w-full border-collapse\",\n weekdays: cn(\"flex\", defaultClassNames.weekdays),\n weekday: cn(\n \"flex-1 rounded-md text-[0.8rem] font-normal text-muted-foreground select-none\",\n defaultClassNames.weekday\n ),\n week: cn(\"mt-2 flex w-full\", defaultClassNames.week),\n week_number_header: cn(\n \"w-(--cell-size) select-none\",\n defaultClassNames.week_number_header\n ),\n week_number: cn(\n \"text-[0.8rem] text-muted-foreground select-none\",\n defaultClassNames.week_number\n ),\n day: cn(\n \"group/day relative aspect-square h-full w-full p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-md\",\n props.showWeekNumber\n ? \"[&:nth-child(2)[data-selected=true]_button]:rounded-l-md\"\n : \"[&:first-child[data-selected=true]_button]:rounded-l-md\",\n defaultClassNames.day\n ),\n range_start: cn(\n \"rounded-l-md bg-accent\",\n defaultClassNames.range_start\n ),\n range_middle: cn(\"rounded-none\", defaultClassNames.range_middle),\n range_end: cn(\"rounded-r-md bg-accent\", defaultClassNames.range_end),\n today: cn(\n \"rounded-md bg-accent text-accent-foreground data-[selected=true]:rounded-none\",\n defaultClassNames.today\n ),\n outside: cn(\n \"text-muted-foreground aria-selected:text-muted-foreground\",\n defaultClassNames.outside\n ),\n disabled: cn(\n \"text-muted-foreground opacity-50\",\n defaultClassNames.disabled\n ),\n hidden: cn(\"invisible\", defaultClassNames.hidden),\n ...classNames,\n }}\n components={{\n Root: ({ className, rootRef, ...props }) => {\n return (\n <div\n data-slot=\"calendar\"\n ref={rootRef as any}\n className={cn(className)}\n {...(props as any)}\n />\n )\n },\n Chevron: ({ className, orientation, ...props }) => {\n if (orientation === \"left\") {\n return (\n <HugeiconsIcon\n icon={ArrowLeft01Icon}\n className={cn(\"size-4\", className)}\n {...props}\n />\n )\n }\n\n if (orientation === \"right\") {\n return (\n <HugeiconsIcon\n icon={ArrowRight01Icon}\n className={cn(\"size-4\", className)}\n {...props}\n />\n )\n }\n\n return (\n <HugeiconsIcon\n icon={ArrowDown01Icon}\n className={cn(\"size-4\", className)}\n {...props}\n />\n )\n },\n DayButton: CalendarDayButton,\n WeekNumber: ({ children, ...props }) => {\n return (\n <td {...(props as any)}>\n <div className=\"flex size-(--cell-size) items-center justify-center text-center\">\n {children}\n </div>\n </td>\n )\n },\n ...components,\n }}\n {...props}\n />\n )\n}\n\nfunction CalendarDayButton({\n className,\n day,\n modifiers,\n ...props\n}: React.ComponentProps<typeof DayButton>) {\n const defaultClassNames = getDefaultClassNames()\n\n const ref = React.useRef<HTMLButtonElement>(null)\n React.useEffect(() => {\n if (modifiers.focused) ref.current?.focus()\n }, [modifiers.focused])\n\n return (\n <Button\n ref={ref as any}\n variant=\"ghost\"\n size=\"icon\"\n data-day={day.date.toLocaleDateString()}\n data-selected-single={\n modifiers.selected &&\n !modifiers.range_start &&\n !modifiers.range_end &&\n !modifiers.range_middle\n }\n data-range-start={modifiers.range_start}\n data-range-end={modifiers.range_end}\n data-range-middle={modifiers.range_middle}\n className={cn(\n \"flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-md data-[range-end=true]:rounded-r-md data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:rounded-md data-[range-start=true]:rounded-l-md data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-accent-foreground [&>span]:text-xs [&>span]:opacity-70\",\n defaultClassNames.day,\n className\n )}\n {...(props as any)}\n />\n )\n}\n\nexport { Calendar, CalendarDayButton }\n"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"path": "registry/example-apps/default/calendar/components/ui/card.tsx",
|
|
130
|
+
"type": "registry:ui",
|
|
131
|
+
"target": "components/example-apps/calendar/components/ui/card.tsx",
|
|
132
|
+
"content": "import * as React from \"react\"\nimport type { ComponentPropsWithoutRef } from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Card({\n className,\n size = \"default\",\n ...props\n}: ComponentPropsWithoutRef<\"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 }: ComponentPropsWithoutRef<\"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 }: ComponentPropsWithoutRef<\"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({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"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 }: ComponentPropsWithoutRef<\"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 }: ComponentPropsWithoutRef<\"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 }: ComponentPropsWithoutRef<\"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"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"path": "registry/example-apps/default/calendar/components/ui/checkbox.tsx",
|
|
136
|
+
"type": "registry:ui",
|
|
137
|
+
"target": "components/example-apps/calendar/components/ui/checkbox.tsx",
|
|
138
|
+
"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-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-[3px] 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"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"path": "registry/example-apps/default/calendar/components/ui/collapsible.tsx",
|
|
142
|
+
"type": "registry:ui",
|
|
143
|
+
"target": "components/example-apps/calendar/components/ui/collapsible.tsx",
|
|
144
|
+
"content": "\"use client\"\n\nimport { Collapsible as CollapsiblePrimitive } from \"@base-ui/react/collapsible\"\n\nfunction Collapsible({ ...props }: CollapsiblePrimitive.Root.Props) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />\n}\n\nfunction CollapsibleTrigger({ ...props }: CollapsiblePrimitive.Trigger.Props) {\n return (\n <CollapsiblePrimitive.Trigger data-slot=\"collapsible-trigger\" {...props} />\n )\n}\n\nfunction CollapsibleContent({ ...props }: CollapsiblePrimitive.Panel.Props) {\n return (\n <CollapsiblePrimitive.Panel data-slot=\"collapsible-content\" {...props} />\n )\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent }\n"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"path": "registry/example-apps/default/calendar/components/ui/combobox.tsx",
|
|
148
|
+
"type": "registry:ui",
|
|
149
|
+
"target": "components/example-apps/calendar/components/ui/combobox.tsx",
|
|
150
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Combobox as ComboboxPrimitive } from \"@base-ui/react\"\nimport {\n ArrowDown01Icon,\n Cancel01Icon,\n Tick02Icon,\n} from \"@hugeicons/core-free-icons\"\nimport { HugeiconsIcon } from \"@hugeicons/react\"\n\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"./button\"\nimport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupInput,\n} from \"./input-group\"\n\nconst Combobox = ComboboxPrimitive.Root\n\nfunction ComboboxValue({ ...props }: ComboboxPrimitive.Value.Props) {\n return <ComboboxPrimitive.Value data-slot=\"combobox-value\" {...props} />\n}\n\nfunction ComboboxTrigger({\n className,\n children,\n ...props\n}: ComboboxPrimitive.Trigger.Props) {\n return (\n <ComboboxPrimitive.Trigger\n data-slot=\"combobox-trigger\"\n className={cn(\"[&_svg:not([class*='size-'])]:size-4\", className)}\n {...props}\n >\n {children}\n <HugeiconsIcon\n icon={ArrowDown01Icon}\n strokeWidth={2}\n className=\"pointer-events-none size-4 text-muted-foreground\"\n />\n </ComboboxPrimitive.Trigger>\n )\n}\n\nfunction ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) {\n return (\n <ComboboxPrimitive.Clear\n data-slot=\"combobox-clear\"\n render={<InputGroupButton variant=\"ghost\" size=\"icon-xs\" />}\n className={cn(className)}\n {...props}\n >\n <HugeiconsIcon\n icon={Cancel01Icon}\n strokeWidth={2}\n className=\"pointer-events-none\"\n />\n </ComboboxPrimitive.Clear>\n )\n}\n\nfunction ComboboxInput({\n className,\n children,\n disabled = false,\n showTrigger = true,\n showClear = false,\n ...props\n}: ComboboxPrimitive.Input.Props & {\n showTrigger?: boolean\n showClear?: boolean\n}) {\n return (\n <InputGroup className={cn(\"w-auto\", className)}>\n <ComboboxPrimitive.Input\n render={<InputGroupInput disabled={disabled} />}\n {...props}\n />\n <InputGroupAddon align=\"inline-end\">\n {showTrigger && (\n <InputGroupButton\n size=\"icon-xs\"\n variant=\"ghost\"\n render={<ComboboxTrigger />}\n data-slot=\"input-group-button\"\n className=\"group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent\"\n disabled={disabled}\n />\n )}\n {showClear && <ComboboxClear disabled={disabled} />}\n </InputGroupAddon>\n {children}\n </InputGroup>\n )\n}\n\nfunction ComboboxContent({\n className,\n side = \"bottom\",\n sideOffset = 6,\n align = \"start\",\n alignOffset = 0,\n anchor,\n ...props\n}: ComboboxPrimitive.Popup.Props &\n Pick<\n ComboboxPrimitive.Positioner.Props,\n \"side\" | \"align\" | \"sideOffset\" | \"alignOffset\" | \"anchor\"\n >) {\n return (\n <ComboboxPrimitive.Portal>\n <ComboboxPrimitive.Positioner\n side={side}\n sideOffset={sideOffset}\n align={align}\n alignOffset={alignOffset}\n anchor={anchor}\n className=\"isolate z-50\"\n >\n <ComboboxPrimitive.Popup\n data-slot=\"combobox-content\"\n data-chips={!!anchor}\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 group/combobox-content relative max-h-(--available-height) max-h-72 w-(--anchor-width) max-w-(--available-width) min-w-36 min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[chips=true]:min-w-(--anchor-width) *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:border-input/30 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:shadow-none\",\n className\n )}\n {...props}\n />\n </ComboboxPrimitive.Positioner>\n </ComboboxPrimitive.Portal>\n )\n}\n\nfunction ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props) {\n return (\n <ComboboxPrimitive.List\n data-slot=\"combobox-list\"\n className={cn(\n \"no-scrollbar max-h-[min(calc(--spacing(72)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto overscroll-contain p-1 data-empty:p-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ComboboxItem({\n className,\n children,\n ...props\n}: ComboboxPrimitive.Item.Props) {\n return (\n <ComboboxPrimitive.Item\n data-slot=\"combobox-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 data-highlighted:bg-accent data-highlighted:text-accent-foreground not-data-[variant=destructive]:data-highlighted:**: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\",\n className\n )}\n {...props}\n >\n {children}\n <ComboboxPrimitive.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 </ComboboxPrimitive.ItemIndicator>\n </ComboboxPrimitive.Item>\n )\n}\n\nfunction ComboboxGroup({ className, ...props }: ComboboxPrimitive.Group.Props) {\n return (\n <ComboboxPrimitive.Group\n data-slot=\"combobox-group\"\n className={cn(className)}\n {...props}\n />\n )\n}\n\nfunction ComboboxLabel({\n className,\n ...props\n}: ComboboxPrimitive.GroupLabel.Props) {\n return (\n <ComboboxPrimitive.GroupLabel\n data-slot=\"combobox-label\"\n className={cn(\"px-2 py-1.5 text-xs text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nfunction ComboboxCollection({ ...props }: ComboboxPrimitive.Collection.Props) {\n return (\n <ComboboxPrimitive.Collection data-slot=\"combobox-collection\" {...props} />\n )\n}\n\nfunction ComboboxEmpty({ className, ...props }: ComboboxPrimitive.Empty.Props) {\n return (\n <ComboboxPrimitive.Empty\n data-slot=\"combobox-empty\"\n className={cn(\n \"hidden w-full justify-center py-2 text-center text-sm text-muted-foreground group-data-empty/combobox-content:flex\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ComboboxSeparator({\n className,\n ...props\n}: ComboboxPrimitive.Separator.Props) {\n return (\n <ComboboxPrimitive.Separator\n data-slot=\"combobox-separator\"\n className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction ComboboxChips({\n className,\n ...props\n}: React.ComponentPropsWithRef<typeof ComboboxPrimitive.Chips> &\n ComboboxPrimitive.Chips.Props) {\n return (\n <ComboboxPrimitive.Chips\n data-slot=\"combobox-chips\"\n className={cn(\n \"flex min-h-9 flex-wrap items-center gap-1.5 rounded-md border border-input bg-transparent bg-clip-padding px-2.5 py-1.5 text-sm shadow-xs transition-[color,box-shadow] focus-within:border-ring focus-within:ring-[3px] focus-within:ring-ring/50 has-aria-invalid:border-destructive has-aria-invalid:ring-[3px] has-aria-invalid:ring-destructive/20 has-data-[slot=combobox-chip]:px-1.5 dark:bg-input/30 dark:has-aria-invalid:border-destructive/50 dark:has-aria-invalid:ring-destructive/40\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ComboboxChip({\n className,\n children,\n showRemove = true,\n ...props\n}: ComboboxPrimitive.Chip.Props & {\n showRemove?: boolean\n}) {\n return (\n <ComboboxPrimitive.Chip\n data-slot=\"combobox-chip\"\n className={cn(\n \"flex h-[calc(--spacing(5.5))] w-fit items-center justify-center gap-1 rounded-sm bg-muted px-1.5 text-xs font-medium whitespace-nowrap text-foreground has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-data-[slot=combobox-chip-remove]:pr-0\",\n className\n )}\n {...props}\n >\n {children}\n {showRemove && (\n <ComboboxPrimitive.ChipRemove\n render={<Button variant=\"ghost\" size=\"icon-xs\" />}\n className=\"-ml-1 opacity-50 hover:opacity-100\"\n data-slot=\"combobox-chip-remove\"\n >\n <HugeiconsIcon\n icon={Cancel01Icon}\n strokeWidth={2}\n className=\"pointer-events-none\"\n />\n </ComboboxPrimitive.ChipRemove>\n )}\n </ComboboxPrimitive.Chip>\n )\n}\n\nfunction ComboboxChipsInput({\n className,\n children,\n ...props\n}: ComboboxPrimitive.Input.Props) {\n return (\n <ComboboxPrimitive.Input\n data-slot=\"combobox-chip-input\"\n className={cn(\"min-w-16 flex-1 outline-none\", className)}\n {...props}\n />\n )\n}\n\nfunction useComboboxAnchor() {\n return React.useRef<HTMLDivElement | null>(null)\n}\n\nexport {\n Combobox,\n ComboboxInput,\n ComboboxContent,\n ComboboxList,\n ComboboxItem,\n ComboboxGroup,\n ComboboxLabel,\n ComboboxCollection,\n ComboboxEmpty,\n ComboboxSeparator,\n ComboboxChips,\n ComboboxChip,\n ComboboxChipsInput,\n ComboboxTrigger,\n ComboboxValue,\n useComboboxAnchor,\n}\n"
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"path": "registry/example-apps/default/calendar/components/ui/dialog.tsx",
|
|
154
|
+
"type": "registry:ui",
|
|
155
|
+
"target": "components/example-apps/calendar/components/ui/dialog.tsx",
|
|
156
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport type { ComponentPropsWithoutRef } from \"react\"\nimport { Dialog as DialogPrimitive } from \"@base-ui/react/dialog\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Dialog({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Root>) {\n return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Trigger>) {\n return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogClose({\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Close>) {\n return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogContent({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Popup>) {\n return (\n <DialogPrimitive.Portal>\n <DialogPrimitive.Backdrop\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/80\",\n \"data-[ending-style]:opacity-0 data-[starting-style]:opacity-0\"\n )}\n />\n <div className=\"fixed inset-0 z-50 flex items-center justify-center p-4\">\n <DialogPrimitive.Popup\n data-slot=\"dialog-content\"\n className={cn(\n \"relative z-50 grid w-full max-w-lg gap-4 border bg-background p-6 shadow-lg duration-200\",\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\",\n \"data-[starting-style]:scale-95 data-[starting-style]:opacity-0\",\n \"data-[ending-style]:scale-95 data-[ending-style]:opacity-0\",\n \"sm:rounded-lg\",\n className\n )}\n {...props}\n />\n </div>\n </DialogPrimitive.Portal>\n )\n}\n\nfunction DialogHeader({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"dialog-header\"\n className={cn(\n \"flex flex-col space-y-1.5 text-center sm:text-left\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogFooter({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"dialog-footer\"\n className={cn(\n \"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogTitle({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n return (\n <DialogPrimitive.Title\n data-slot=\"dialog-title\"\n className={cn(\n \"text-lg leading-none font-semibold tracking-tight\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DialogDescription({\n className,\n ...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n return (\n <DialogPrimitive.Description\n data-slot=\"dialog-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Dialog,\n DialogTrigger,\n DialogClose,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n}\n"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"path": "registry/example-apps/default/calendar/components/ui/dropdown-menu.tsx",
|
|
160
|
+
"type": "registry:ui",
|
|
161
|
+
"target": "components/example-apps/calendar/components/ui/dropdown-menu.tsx",
|
|
162
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport type { ComponentPropsWithoutRef } 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 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-open:bg-accent data-open:text-accent-foreground data-[inset]:pl-8 [&_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 ...props\n}: MenuPrimitive.CheckboxItem.Props) {\n return (\n <MenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\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 [&_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 ...props\n}: MenuPrimitive.RadioItem.Props) {\n return (\n <MenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\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 [&_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}: ComponentPropsWithoutRef<\"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"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"path": "registry/example-apps/default/calendar/components/ui/field.tsx",
|
|
166
|
+
"type": "registry:ui",
|
|
167
|
+
"target": "components/example-apps/calendar/components/ui/field.tsx",
|
|
168
|
+
"content": "\"use client\"\n\nimport { useMemo } from \"react\"\nimport type { ComponentPropsWithoutRef } from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\nimport { Label } from \"./label\"\nimport { Separator } from \"./separator\"\n\nfunction FieldSet({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"fieldset\">) {\n return (\n <fieldset\n data-slot=\"field-set\"\n className={cn(\n \"flex flex-col gap-6 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldLegend({\n className,\n variant = \"legend\",\n ...props\n}: ComponentPropsWithoutRef<\"legend\"> & { variant?: \"legend\" | \"label\" }) {\n return (\n <legend\n data-slot=\"field-legend\"\n data-variant={variant}\n className={cn(\n \"mb-3 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldGroup({ className, ...props }: ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"field-group\"\n className={cn(\n \"group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 [&>[data-slot=field-group]]:gap-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nconst fieldVariants = cva(\n \"group/field flex w-full gap-3 data-[invalid=true]:text-destructive\",\n {\n variants: {\n orientation: {\n vertical: \"flex-col [&>*]:w-full [&>.sr-only]:w-auto\",\n horizontal:\n \"flex-row items-center has-[>[data-slot=field-content]]:items-start [&>[data-slot=field-label]]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px\",\n responsive:\n \"flex-col @md/field-group:flex-row @md/field-group:items-center @md/field-group:has-[>[data-slot=field-content]]:items-start [&>*]:w-full @md/field-group:[&>*]:w-auto [&>.sr-only]:w-auto @md/field-group:[&>[data-slot=field-label]]:flex-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px\",\n },\n },\n defaultVariants: {\n orientation: \"vertical\",\n },\n }\n)\n\nfunction Field({\n className,\n orientation = \"vertical\",\n ...props\n}: ComponentPropsWithoutRef<\"div\"> & VariantProps<typeof fieldVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"field\"\n data-orientation={orientation}\n className={cn(fieldVariants({ orientation }), className)}\n {...props}\n />\n )\n}\n\nfunction FieldContent({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"field-content\"\n className={cn(\n \"group/field-content flex flex-1 flex-col gap-1 leading-snug\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldLabel({\n className,\n ...props\n}: React.ComponentProps<typeof Label>) {\n return (\n <Label\n data-slot=\"field-label\"\n className={cn(\n \"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-data-checked:border-primary has-data-checked:bg-primary/5 has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border dark:has-data-checked:bg-primary/10 [&>*]:data-[slot=field]:p-3\",\n \"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldTitle({ className, ...props }: ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"field-label\"\n className={cn(\n \"flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldDescription({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"p\">) {\n return (\n <p\n data-slot=\"field-description\"\n className={cn(\n \"text-left text-sm leading-normal font-normal text-muted-foreground group-has-[[data-orientation=horizontal]]/field:text-balance [[data-variant=legend]+&]:-mt-1.5\",\n \"last:mt-0 nth-last-2:-mt-1\",\n \"[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction FieldSeparator({\n children,\n className,\n ...props\n}: ComponentPropsWithoutRef<\"div\"> & {\n children?: React.ReactNode\n}) {\n return (\n <div\n data-slot=\"field-separator\"\n data-content={!!children}\n className={cn(\n \"relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2\",\n className\n )}\n {...props}\n >\n <Separator className=\"absolute inset-0 top-1/2\" />\n {children && (\n <span\n className=\"relative mx-auto block w-fit bg-background px-2 text-muted-foreground\"\n data-slot=\"field-separator-content\"\n >\n {children}\n </span>\n )}\n </div>\n )\n}\n\nfunction FieldError({\n className,\n children,\n errors,\n ...props\n}: ComponentPropsWithoutRef<\"div\"> & {\n errors?: Array<{ message?: string } | undefined>\n}) {\n const content = useMemo(() => {\n if (children) {\n return children\n }\n\n if (!errors?.length) {\n return null\n }\n\n const uniqueErrors = [\n ...new Map(errors.map((error) => [error?.message, error])).values(),\n ]\n\n if (uniqueErrors?.length == 1) {\n return uniqueErrors[0]?.message\n }\n\n return (\n <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n {uniqueErrors.map(\n (error, index) =>\n error?.message && <li key={index}>{error.message}</li>\n )}\n </ul>\n )\n }, [children, errors])\n\n if (!content) {\n return null\n }\n\n return (\n <div\n role=\"alert\"\n data-slot=\"field-error\"\n className={cn(\"text-sm font-normal text-destructive\", className)}\n {...props}\n >\n {content}\n </div>\n )\n}\n\nexport {\n Field,\n FieldLabel,\n FieldDescription,\n FieldError,\n FieldGroup,\n FieldLegend,\n FieldSeparator,\n FieldSet,\n FieldContent,\n FieldTitle,\n}\n"
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"path": "registry/example-apps/default/calendar/components/ui/input-group.tsx",
|
|
172
|
+
"type": "registry:ui",
|
|
173
|
+
"target": "components/example-apps/calendar/components/ui/input-group.tsx",
|
|
174
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport type { ComponentPropsWithoutRef } from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"./button\"\nimport { Input } from \"./input\"\nimport { Textarea } from \"./textarea\"\n\nfunction InputGroup({ className, ...props }: ComponentPropsWithoutRef<\"div\">) {\n return (\n <div\n data-slot=\"input-group\"\n role=\"group\"\n className={cn(\n \"group/input-group relative flex h-9 w-full min-w-0 items-center rounded-md border border-input shadow-xs transition-[color,box-shadow] outline-none has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-[3px] has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-[3px] has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5 [[data-slot=combobox-content]_&]:focus-within:border-inherit [[data-slot=combobox-content]_&]:focus-within:ring-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nconst inputGroupAddonVariants = cva(\n \"flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n align: {\n \"inline-start\":\n \"order-first pl-2 has-[>button]:ml-[-0.25rem] has-[>kbd]:ml-[-0.15rem]\",\n \"inline-end\":\n \"order-last pr-2 has-[>button]:mr-[-0.25rem] has-[>kbd]:mr-[-0.15rem]\",\n \"block-start\":\n \"order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2\",\n \"block-end\":\n \"order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2\",\n },\n },\n defaultVariants: {\n align: \"inline-start\",\n },\n }\n)\n\nfunction InputGroupAddon({\n className,\n align = \"inline-start\",\n ...props\n}: ComponentPropsWithoutRef<\"div\"> &\n VariantProps<typeof inputGroupAddonVariants>) {\n return (\n <div\n role=\"group\"\n data-slot=\"input-group-addon\"\n data-align={align}\n className={cn(inputGroupAddonVariants({ align }), className)}\n onClick={(e) => {\n if ((e.target as HTMLElement).closest(\"button\")) {\n return\n }\n e.currentTarget.parentElement?.querySelector(\"input\")?.focus()\n }}\n {...props}\n />\n )\n}\n\nconst inputGroupButtonVariants = cva(\n \"flex items-center gap-2 text-sm shadow-none\",\n {\n variants: {\n size: {\n xs: \"h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5\",\n sm: \"\",\n \"icon-xs\":\n \"size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0\",\n \"icon-sm\": \"size-8 p-0 has-[>svg]:p-0\",\n },\n },\n defaultVariants: {\n size: \"xs\",\n },\n }\n)\n\nfunction InputGroupButton({\n className,\n type = \"button\",\n variant = \"ghost\",\n size = \"xs\",\n ...props\n}: Omit<React.ComponentProps<typeof Button>, \"size\" | \"type\"> &\n VariantProps<typeof inputGroupButtonVariants> & {\n type?: \"button\" | \"submit\" | \"reset\"\n }) {\n return (\n <Button\n type={type}\n data-size={size}\n variant={variant}\n className={cn(inputGroupButtonVariants({ size }), className)}\n {...props}\n />\n )\n}\n\nfunction InputGroupText({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"span\">) {\n return (\n <span\n className={cn(\n \"flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction InputGroupInput({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"input\">) {\n return (\n <Input\n data-slot=\"input-group-control\"\n className={cn(\n \"flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction InputGroupTextarea({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"textarea\">) {\n return (\n <Textarea\n data-slot=\"input-group-control\"\n className={cn(\n \"flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport {\n InputGroup,\n InputGroupAddon,\n InputGroupButton,\n InputGroupText,\n InputGroupInput,\n InputGroupTextarea,\n}\n"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"path": "registry/example-apps/default/calendar/components/ui/input.tsx",
|
|
178
|
+
"type": "registry:ui",
|
|
179
|
+
"target": "components/example-apps/calendar/components/ui/input.tsx",
|
|
180
|
+
"content": "import * as React from \"react\"\nimport type { ComponentPropsWithoutRef } from \"react\"\nimport { Input as InputPrimitive } from \"@base-ui/react/input\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Input({\n className,\n type,\n ...props\n}: ComponentPropsWithoutRef<\"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-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-[3px] 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"
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
"path": "registry/example-apps/default/calendar/components/ui/kbd.tsx",
|
|
184
|
+
"type": "registry:ui",
|
|
185
|
+
"target": "components/example-apps/calendar/components/ui/kbd.tsx",
|
|
186
|
+
"content": "import type { ComponentPropsWithoutRef } from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Kbd({ className, ...props }: ComponentPropsWithoutRef<\"kbd\">) {\n return (\n <kbd\n data-slot=\"kbd\"\n className={cn(\n \"pointer-events-none inline-flex h-5 w-fit min-w-5 items-center justify-center gap-1 rounded-sm bg-muted px-1 font-sans text-xs font-medium text-muted-foreground select-none\",\n \"[&_svg:not([class*='size-'])]:size-3\",\n \"[[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction KbdGroup({ className, ...props }: ComponentPropsWithoutRef<\"div\">) {\n return (\n <kbd\n data-slot=\"kbd-group\"\n className={cn(\"inline-flex items-center gap-1\", className)}\n {...props}\n />\n )\n}\n\nexport { Kbd, KbdGroup }\n"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"path": "registry/example-apps/default/calendar/components/ui/label.tsx",
|
|
190
|
+
"type": "registry:ui",
|
|
191
|
+
"target": "components/example-apps/calendar/components/ui/label.tsx",
|
|
192
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport type { ComponentPropsWithoutRef } from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Label({ className, ...props }: ComponentPropsWithoutRef<\"label\">) {\n return (\n <label\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Label }\n"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"path": "registry/example-apps/default/calendar/components/ui/popover.tsx",
|
|
196
|
+
"type": "registry:ui",
|
|
197
|
+
"target": "components/example-apps/calendar/components/ui/popover.tsx",
|
|
198
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Popover as PopoverPrimitive } from \"@base-ui/react/popover\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Popover({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Root>) {\n return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverTrigger({\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Trigger>) {\n return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n className,\n align = \"center\",\n side = \"bottom\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof PopoverPrimitive.Popup> & {\n align?: \"start\" | \"center\" | \"end\"\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n sideOffset?: number\n}) {\n return (\n <PopoverPrimitive.Portal>\n <PopoverPrimitive.Positioner\n className=\"z-50\"\n align={align}\n side={side}\n sideOffset={sideOffset}\n >\n <PopoverPrimitive.Popup\n data-slot=\"popover-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-72 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-hidden\",\n className\n )}\n {...props}\n />\n </PopoverPrimitive.Positioner>\n </PopoverPrimitive.Portal>\n )\n}\n\nexport { Popover, PopoverTrigger, PopoverContent }\n"
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"path": "registry/example-apps/default/calendar/components/ui/select.tsx",
|
|
202
|
+
"type": "registry:ui",
|
|
203
|
+
"target": "components/example-apps/calendar/components/ui/select.tsx",
|
|
204
|
+
"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({\n className,\n placeholder,\n ...props\n}: SelectPrimitive.Value.Props & { placeholder?: string }) {\n return (\n <SelectPrimitive.Value\n data-slot=\"select-value\"\n className={cn(\"flex flex-1 text-left\", className)}\n {...props}\n >\n {(value) => value ?? placeholder}\n </SelectPrimitive.Value>\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-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-[3px] 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 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 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\",\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"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"path": "registry/example-apps/default/calendar/components/ui/separator.tsx",
|
|
208
|
+
"type": "registry:ui",
|
|
209
|
+
"target": "components/example-apps/calendar/components/ui/separator.tsx",
|
|
210
|
+
"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-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:self-stretch\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Separator }\n"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"path": "registry/example-apps/default/calendar/components/ui/sheet.tsx",
|
|
214
|
+
"type": "registry:ui",
|
|
215
|
+
"target": "components/example-apps/calendar/components/ui/sheet.tsx",
|
|
216
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport type { ComponentPropsWithoutRef } 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 }: ComponentPropsWithoutRef<\"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 }: ComponentPropsWithoutRef<\"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"
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"path": "registry/example-apps/default/calendar/components/ui/sidebar.tsx",
|
|
220
|
+
"type": "registry:ui",
|
|
221
|
+
"target": "components/example-apps/calendar/components/ui/sidebar.tsx",
|
|
222
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport type { ComponentPropsWithoutRef } 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}: ComponentPropsWithoutRef<\"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}: ComponentPropsWithoutRef<\"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({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"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({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"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({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"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({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"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({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"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({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"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\"> & ComponentPropsWithoutRef<\"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\"> & ComponentPropsWithoutRef<\"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}: ComponentPropsWithoutRef<\"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 }: ComponentPropsWithoutRef<\"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({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"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 ComponentPropsWithoutRef<\"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 ComponentPropsWithoutRef<\"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}: ComponentPropsWithoutRef<\"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}: ComponentPropsWithoutRef<\"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({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"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}: ComponentPropsWithoutRef<\"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 ComponentPropsWithoutRef<\"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"
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"path": "registry/example-apps/default/calendar/components/ui/skeleton.tsx",
|
|
226
|
+
"type": "registry:ui",
|
|
227
|
+
"target": "components/example-apps/calendar/components/ui/skeleton.tsx",
|
|
228
|
+
"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"
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"path": "registry/example-apps/default/calendar/components/ui/table.tsx",
|
|
232
|
+
"type": "registry:ui",
|
|
233
|
+
"target": "components/example-apps/calendar/components/ui/table.tsx",
|
|
234
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport type { ComponentPropsWithoutRef } from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Table({ className, ...props }: ComponentPropsWithoutRef<\"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({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"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 }: ComponentPropsWithoutRef<\"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({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"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 }: ComponentPropsWithoutRef<\"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 }: ComponentPropsWithoutRef<\"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 }: ComponentPropsWithoutRef<\"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}: ComponentPropsWithoutRef<\"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"
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
"path": "registry/example-apps/default/calendar/components/ui/textarea.tsx",
|
|
238
|
+
"type": "registry:ui",
|
|
239
|
+
"target": "components/example-apps/calendar/components/ui/textarea.tsx",
|
|
240
|
+
"content": "import * as React from \"react\"\nimport type { ComponentPropsWithoutRef } from \"react\"\n\nimport { cn } from \"../../lib/utils\"\n\nfunction Textarea({\n className,\n ...props\n}: ComponentPropsWithoutRef<\"textarea\">) {\n return (\n <textarea\n data-slot=\"textarea\"\n className={cn(\n \"flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-2.5 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-[3px] 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 { Textarea }\n"
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"path": "registry/example-apps/default/calendar/components/ui/tooltip.tsx",
|
|
244
|
+
"type": "registry:ui",
|
|
245
|
+
"target": "components/example-apps/calendar/components/ui/tooltip.tsx",
|
|
246
|
+
"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 (\n <TooltipProvider>\n <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />\n </TooltipProvider>\n )\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 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=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"
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
"path": "registry/example-apps/default/calendar/hooks/use-mobile.ts",
|
|
250
|
+
"type": "registry:hook",
|
|
251
|
+
"target": "components/example-apps/calendar/hooks/use-mobile.ts",
|
|
252
|
+
"content": "import * as React from \"react\"\n\nconst MOBILE_BREAKPOINT = 768\n\nexport function useIsMobile() {\n const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)\n\n React.useEffect(() => {\n const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)\n const onChange = () => {\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n }\n mql.addEventListener(\"change\", onChange)\n setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)\n return () => mql.removeEventListener(\"change\", onChange)\n }, [])\n\n return !!isMobile\n}\n"
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"path": "registry/example-apps/default/calendar/index.tsx",
|
|
256
|
+
"type": "registry:file",
|
|
257
|
+
"target": "components/example-apps/calendar/index.tsx",
|
|
258
|
+
"content": "/**\n * Wrapper export for embedding the app in the docs app\n */\n\"use client\"\n\nimport { SidebarProvider } from \"@/components/ui/sidebar\"\n\nimport { CalendarControls } from \"./components/calendar/calendar-controls\"\nimport { CalendarHeader } from \"./components/calendar/calendar-header\"\nimport { CalendarSidebar } from \"./components/calendar/calendar-sidebar\"\nimport { CalendarView } from \"./components/calendar/calendar-view\"\n\nexport default function CalendarWrapper() {\n return (\n <SidebarProvider className=\"bg-sidebar\">\n <CalendarSidebar />\n <div className=\"h-full min-h-0 w-full overflow-hidden lg:p-2\">\n <div className=\"bg-container flex h-full min-h-0 w-full flex-col items-center justify-start overflow-hidden bg-background lg:rounded-md lg:border\">\n <div className=\"w-full\">\n <CalendarHeader />\n <CalendarControls />\n </div>\n <div className=\"w-full flex-1 overflow-hidden\">\n <CalendarView />\n </div>\n </div>\n </div>\n </SidebarProvider>\n )\n}\n"
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"path": "registry/example-apps/default/calendar/lib/utils.ts",
|
|
262
|
+
"type": "registry:lib",
|
|
263
|
+
"target": "components/example-apps/calendar/lib/utils.ts",
|
|
264
|
+
"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"
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
"path": "registry/example-apps/default/calendar/mock-data/events.ts",
|
|
268
|
+
"type": "registry:lib",
|
|
269
|
+
"target": "components/example-apps/calendar/mock-data/events.ts",
|
|
270
|
+
"content": "export interface Event {\n id: string\n title: string\n startTime: string\n endTime: string\n date: string\n participants: string[]\n meetingLink?: string\n timezone?: string\n}\n\nexport const events: Event[] = [\n {\n id: \"1\",\n title: \"Unit call and safety briefing\",\n startTime: \"06:30\",\n endTime: \"07:15\",\n date: \"2024-02-04\",\n participants: [\"user1\", \"user2\", \"user3\", \"user4\"],\n meetingLink: \"https://meet.google.com/film-prod-room\",\n },\n {\n id: \"2\",\n title: \"Sunrise drone establishing shots\",\n startTime: \"07:30\",\n endTime: \"09:00\",\n date: \"2024-02-04\",\n participants: [\"user1\", \"user3\", \"user4\"],\n },\n {\n id: \"3\",\n title: \"Wardrobe continuity check\",\n startTime: \"09:20\",\n endTime: \"10:00\",\n date: \"2024-02-04\",\n participants: [\"user2\", \"user5\"],\n },\n {\n id: \"4\",\n title: \"Scene 12 blocking rehearsal\",\n startTime: \"10:30\",\n endTime: \"12:00\",\n date: \"2024-02-04\",\n participants: [\"user1\", \"user2\", \"user3\", \"user5\"],\n meetingLink: \"https://meet.google.com/film-blocking-a\",\n },\n {\n id: \"5\",\n title: \"Crew lunch\",\n startTime: \"12:15\",\n endTime: \"13:00\",\n date: \"2024-02-04\",\n participants: [],\n },\n {\n id: \"6\",\n title: \"Client playback review call\",\n startTime: \"16:00\",\n endTime: \"16:45\",\n date: \"2024-02-04\",\n participants: [\"user1\", \"user2\", \"user5\"],\n meetingLink: \"https://meet.google.com/film-client-review\",\n timezone: \"PST\",\n },\n {\n id: \"7\",\n title: \"Night exterior lighting test\",\n startTime: \"19:30\",\n endTime: \"20:30\",\n date: \"2024-02-04\",\n participants: [\"user1\", \"user3\", \"user4\"],\n },\n {\n id: \"8\",\n title: \"Daily wrap report\",\n startTime: \"21:00\",\n endTime: \"21:30\",\n date: \"2024-02-04\",\n participants: [\"user1\", \"user2\"],\n },\n {\n id: \"9\",\n title: \"Location handoff meeting\",\n startTime: \"07:00\",\n endTime: \"07:45\",\n date: \"2024-02-05\",\n participants: [\"user1\", \"user4\", \"user5\"],\n meetingLink: \"https://meet.google.com/location-handoff\",\n },\n {\n id: \"10\",\n title: \"Truck load-out checklist\",\n startTime: \"08:00\",\n endTime: \"08:30\",\n date: \"2024-02-05\",\n participants: [\"user1\", \"user3\"],\n },\n {\n id: \"11\",\n title: \"Scene 18 principal photography\",\n startTime: \"09:00\",\n endTime: \"11:30\",\n date: \"2024-02-05\",\n participants: [\"user1\", \"user2\", \"user3\", \"user4\", \"user5\"],\n },\n {\n id: \"12\",\n title: \"Sound team coordination call\",\n startTime: \"11:45\",\n endTime: \"12:15\",\n date: \"2024-02-05\",\n participants: [\"user1\", \"user3\", \"user4\"],\n meetingLink: \"https://meet.google.com/sound-sync\",\n },\n {\n id: \"13\",\n title: \"Lunch reset\",\n startTime: \"12:30\",\n endTime: \"13:15\",\n date: \"2024-02-05\",\n participants: [],\n },\n {\n id: \"14\",\n title: \"Props continuity sweep\",\n startTime: \"13:30\",\n endTime: \"14:10\",\n date: \"2024-02-05\",\n participants: [\"user2\", \"user5\"],\n },\n {\n id: \"15\",\n title: \"VFX marker pass\",\n startTime: \"15:00\",\n endTime: \"16:00\",\n date: \"2024-02-05\",\n participants: [\"user1\", \"user3\", \"user4\"],\n },\n {\n id: \"16\",\n title: \"Executive review meeting\",\n startTime: \"17:30\",\n endTime: \"18:15\",\n date: \"2024-02-05\",\n participants: [\"user1\", \"user2\", \"user5\"],\n meetingLink: \"https://meet.google.com/executive-review\",\n timezone: \"EST\",\n },\n {\n id: \"17\",\n title: \"Second unit prep\",\n startTime: \"06:45\",\n endTime: \"07:30\",\n date: \"2024-02-06\",\n participants: [\"user1\", \"user3\", \"user4\"],\n },\n {\n id: \"18\",\n title: \"Stunt rehearsal meeting\",\n startTime: \"08:30\",\n endTime: \"09:15\",\n date: \"2024-02-06\",\n participants: [\"user1\", \"user2\", \"user3\", \"user5\"],\n meetingLink: \"https://meet.google.com/stunt-rehearsal\",\n },\n {\n id: \"19\",\n title: \"Scene 23 chase coverage\",\n startTime: \"09:30\",\n endTime: \"12:00\",\n date: \"2024-02-06\",\n participants: [\"user1\", \"user2\", \"user3\", \"user4\", \"user5\"],\n },\n {\n id: \"20\",\n title: \"Catering break\",\n startTime: \"12:00\",\n endTime: \"12:45\",\n date: \"2024-02-06\",\n participants: [],\n },\n {\n id: \"21\",\n title: \"Insurance paperwork call\",\n startTime: \"13:00\",\n endTime: \"13:30\",\n date: \"2024-02-06\",\n participants: [\"user1\", \"user5\"],\n meetingLink: \"https://meet.google.com/insurance-desk\",\n },\n {\n id: \"22\",\n title: \"Golden hour pickup shots\",\n startTime: \"16:30\",\n endTime: \"18:00\",\n date: \"2024-02-06\",\n participants: [\"user1\", \"user3\", \"user4\"],\n },\n {\n id: \"23\",\n title: \"Post pipeline sync call\",\n startTime: \"18:30\",\n endTime: \"19:00\",\n date: \"2024-02-06\",\n participants: [\"user1\", \"user2\", \"user4\"],\n meetingLink: \"https://meet.google.com/post-pipeline\",\n timezone: \"UTC\",\n },\n {\n id: \"24\",\n title: \"Call sheet release\",\n startTime: \"07:10\",\n endTime: \"07:40\",\n date: \"2024-02-07\",\n participants: [\"user1\", \"user2\"],\n },\n {\n id: \"25\",\n title: \"Scene 31 interior dialogue\",\n startTime: \"08:15\",\n endTime: \"10:45\",\n date: \"2024-02-07\",\n participants: [\"user1\", \"user2\", \"user3\", \"user5\"],\n },\n {\n id: \"26\",\n title: \"Hair and makeup check-in\",\n startTime: \"11:00\",\n endTime: \"11:30\",\n date: \"2024-02-07\",\n participants: [\"user2\", \"user5\"],\n },\n {\n id: \"27\",\n title: \"Lunch break\",\n startTime: \"12:00\",\n endTime: \"12:45\",\n date: \"2024-02-07\",\n participants: [],\n },\n {\n id: \"28\",\n title: \"Director notes meeting\",\n startTime: \"13:00\",\n endTime: \"13:45\",\n date: \"2024-02-07\",\n participants: [\"user1\", \"user2\", \"user5\"],\n meetingLink: \"https://meet.google.com/director-notes\",\n },\n {\n id: \"29\",\n title: \"Second camera inserts\",\n startTime: \"14:30\",\n endTime: \"15:30\",\n date: \"2024-02-07\",\n participants: [\"user1\", \"user3\", \"user4\"],\n },\n {\n id: \"30\",\n title: \"Wrap and media backup\",\n startTime: \"20:30\",\n endTime: \"21:15\",\n date: \"2024-02-07\",\n participants: [\"user1\", \"user3\"],\n },\n {\n id: \"31\",\n title: \"Sunrise pickup call\",\n startTime: \"06:30\",\n endTime: \"07:00\",\n date: \"2024-02-08\",\n participants: [\"user1\", \"user4\"],\n meetingLink: \"https://meet.google.com/sunrise-pickup\",\n },\n {\n id: \"32\",\n title: \"Airport talent transfer\",\n startTime: \"08:00\",\n endTime: \"09:00\",\n date: \"2024-02-08\",\n participants: [\"user1\", \"user5\"],\n },\n {\n id: \"33\",\n title: \"Scene 40 final rehearsal\",\n startTime: \"09:30\",\n endTime: \"10:30\",\n date: \"2024-02-08\",\n participants: [\"user1\", \"user2\", \"user3\", \"user5\"],\n },\n {\n id: \"34\",\n title: \"Vendor status meeting\",\n startTime: \"11:30\",\n endTime: \"12:00\",\n date: \"2024-02-08\",\n participants: [\"user1\", \"user2\", \"user5\"],\n meetingLink: \"https://meet.google.com/vendor-status\",\n },\n {\n id: \"35\",\n title: \"Studio reset\",\n startTime: \"13:00\",\n endTime: \"13:30\",\n date: \"2024-02-08\",\n participants: [\"user3\", \"user4\"],\n },\n {\n id: \"36\",\n title: \"Client progress call\",\n startTime: \"15:00\",\n endTime: \"15:30\",\n date: \"2024-02-08\",\n participants: [\"user1\", \"user2\", \"user5\"],\n meetingLink: \"https://meet.google.com/client-progress\",\n timezone: \"PST\",\n },\n {\n id: \"37\",\n title: \"Festival teaser cut review\",\n startTime: \"18:00\",\n endTime: \"19:00\",\n date: \"2024-02-08\",\n participants: [\"user1\", \"user2\", \"user4\", \"user5\"],\n meetingLink: \"https://meet.google.com/teaser-review\",\n },\n {\n id: \"38\",\n title: \"Week close-out standup\",\n startTime: \"07:30\",\n endTime: \"08:00\",\n date: \"2024-02-09\",\n participants: [\"user1\", \"user2\", \"user3\", \"user4\"],\n },\n {\n id: \"39\",\n title: \"Scene 44 rain rig setup\",\n startTime: \"09:00\",\n endTime: \"10:30\",\n date: \"2024-02-09\",\n participants: [\"user1\", \"user3\", \"user4\"],\n },\n {\n id: \"40\",\n title: \"Finance checkpoint meeting\",\n startTime: \"11:00\",\n endTime: \"11:30\",\n date: \"2024-02-09\",\n participants: [\"user1\", \"user2\", \"user5\"],\n meetingLink: \"https://meet.google.com/finance-checkpoint\",\n },\n {\n id: \"41\",\n title: \"Lunch\",\n startTime: \"12:15\",\n endTime: \"13:00\",\n date: \"2024-02-09\",\n participants: [],\n },\n {\n id: \"42\",\n title: \"Shot log and continuity lock\",\n startTime: \"14:00\",\n endTime: \"15:00\",\n date: \"2024-02-09\",\n participants: [\"user1\", \"user2\", \"user5\"],\n },\n {\n id: \"43\",\n title: \"Weekend equipment return call\",\n startTime: \"16:00\",\n endTime: \"16:30\",\n date: \"2024-02-09\",\n participants: [\"user1\", \"user3\"],\n meetingLink: \"https://meet.google.com/equipment-return\",\n },\n {\n id: \"44\",\n title: \"Weekend location scout\",\n startTime: \"08:00\",\n endTime: \"10:00\",\n date: \"2024-02-10\",\n participants: [\"user1\", \"user4\", \"user5\"],\n },\n {\n id: \"45\",\n title: \"Storyboard revision meeting\",\n startTime: \"10:30\",\n endTime: \"11:30\",\n date: \"2024-02-10\",\n participants: [\"user1\", \"user2\", \"user5\"],\n meetingLink: \"https://meet.google.com/storyboard-revision\",\n },\n {\n id: \"46\",\n title: \"Quiet prep block\",\n startTime: \"12:00\",\n endTime: \"13:00\",\n date: \"2024-02-10\",\n participants: [],\n },\n {\n id: \"47\",\n title: \"Remote producer call\",\n startTime: \"14:00\",\n endTime: \"14:30\",\n date: \"2024-02-10\",\n participants: [\"user1\", \"user2\"],\n meetingLink: \"https://meet.google.com/remote-producer\",\n timezone: \"EST\",\n },\n {\n id: \"48\",\n title: \"Weekly archive handoff\",\n startTime: \"17:00\",\n endTime: \"17:45\",\n date: \"2024-02-10\",\n participants: [\"user1\", \"user3\", \"user4\"],\n },\n]\n\nexport function getEventsForDate(date: string): Event[] {\n return events.filter((event) => event.date === date)\n}\n\nexport function getEventsForWeek(startDate: Date): Event[] {\n const endDate = new Date(startDate)\n endDate.setDate(endDate.getDate() + 6)\n\n return events.filter((event) => {\n const eventDate = new Date(event.date)\n return eventDate >= startDate && eventDate <= endDate\n })\n}\n\nexport function getTodayEvents(): Event[] {\n const today = new Date()\n const dayOfWeek = today.getDay() === 0 ? 6 : today.getDay() - 1\n\n return events.filter((event) => {\n const eventDate = new Date(event.date)\n const eventDayOfWeek = eventDate.getDay() === 0 ? 6 : eventDate.getDay() - 1\n return eventDayOfWeek === dayOfWeek\n })\n}\n\nexport function addEvent(event: Omit<Event, \"id\">): void {\n const newId = String(events.length + 1)\n events.push({\n ...event,\n id: newId,\n })\n}\n"
|
|
271
|
+
},
|
|
272
|
+
{
|
|
273
|
+
"path": "registry/example-apps/default/calendar/store/calendar-store.ts",
|
|
274
|
+
"type": "registry:lib",
|
|
275
|
+
"target": "components/example-apps/calendar/store/calendar-store.ts",
|
|
276
|
+
"content": "import {\n addDays,\n addWeeks,\n format,\n getDay,\n startOfWeek,\n subWeeks,\n} from \"date-fns\"\nimport { create } from \"zustand\"\n\nimport { addEvent as addEventToStore, Event, events } from \"../mock-data/events\"\n\ninterface CalendarState {\n currentWeekStart: Date\n searchQuery: string\n eventTypeFilter: \"all\" | \"with-meeting\" | \"without-meeting\"\n participantsFilter: \"all\" | \"with-participants\" | \"without-participants\"\n goToNextWeek: () => void\n goToPreviousWeek: () => void\n goToToday: () => void\n goToDate: (date: Date) => void\n setSearchQuery: (query: string) => void\n setEventTypeFilter: (\n filter: \"all\" | \"with-meeting\" | \"without-meeting\"\n ) => void\n setParticipantsFilter: (\n filter: \"all\" | \"with-participants\" | \"without-participants\"\n ) => void\n addEvent: (event: Omit<Event, \"id\">) => void\n getCurrentWeekEvents: () => Event[]\n getWeekDays: () => Date[]\n}\n\nconst BASE_WEEK_START = new Date(\"2024-02-04\")\n\nfunction getDayOfWeek(date: Date): number {\n const day = getDay(date)\n return day === 0 ? 6 : day - 1\n}\n\nfunction getEventsForWeek(startDate: Date): Event[] {\n const weekEvents: Event[] = []\n\n for (let i = 0; i < 7; i++) {\n const currentDay = addDays(startDate, i)\n const currentDayOfWeek = getDayOfWeek(currentDay)\n\n events.forEach((event) => {\n const eventDate = new Date(event.date)\n const eventDayOfWeek = getDayOfWeek(eventDate)\n\n if (eventDayOfWeek === currentDayOfWeek) {\n const eventDateStr = format(currentDay, \"yyyy-MM-dd\")\n weekEvents.push({\n ...event,\n id: `${event.id}-${eventDateStr}`,\n date: eventDateStr,\n })\n }\n })\n }\n\n return weekEvents\n}\n\nexport const useCalendarStore = create<CalendarState>((set, get) => ({\n currentWeekStart: startOfWeek(new Date(), { weekStartsOn: 1 }),\n searchQuery: \"\",\n eventTypeFilter: \"all\",\n participantsFilter: \"all\",\n\n goToNextWeek: () =>\n set((state) => ({\n currentWeekStart: addWeeks(state.currentWeekStart, 1),\n })),\n\n goToPreviousWeek: () =>\n set((state) => ({\n currentWeekStart: subWeeks(state.currentWeekStart, 1),\n })),\n\n goToToday: () =>\n set({\n currentWeekStart: startOfWeek(new Date(), { weekStartsOn: 1 }),\n }),\n\n goToDate: (date: Date) =>\n set({\n currentWeekStart: startOfWeek(date, { weekStartsOn: 1 }),\n }),\n\n setSearchQuery: (query: string) => set({ searchQuery: query }),\n setEventTypeFilter: (filter: \"all\" | \"with-meeting\" | \"without-meeting\") =>\n set({ eventTypeFilter: filter }),\n setParticipantsFilter: (\n filter: \"all\" | \"with-participants\" | \"without-participants\"\n ) => set({ participantsFilter: filter }),\n\n addEvent: (event: Omit<Event, \"id\">) => {\n addEventToStore(event)\n },\n\n getCurrentWeekEvents: () => {\n const state = get()\n let weekEvents = getEventsForWeek(state.currentWeekStart)\n\n if (state.searchQuery) {\n const query = state.searchQuery.toLowerCase()\n weekEvents = weekEvents.filter(\n (event) =>\n event.title.toLowerCase().includes(query) ||\n event.participants.some((p) => p.toLowerCase().includes(query))\n )\n }\n\n if (state.eventTypeFilter === \"with-meeting\") {\n weekEvents = weekEvents.filter((event) => event.meetingLink)\n } else if (state.eventTypeFilter === \"without-meeting\") {\n weekEvents = weekEvents.filter((event) => !event.meetingLink)\n }\n\n if (state.participantsFilter === \"with-participants\") {\n weekEvents = weekEvents.filter((event) => event.participants.length > 0)\n } else if (state.participantsFilter === \"without-participants\") {\n weekEvents = weekEvents.filter((event) => event.participants.length === 0)\n }\n\n return weekEvents\n },\n\n getWeekDays: () => {\n const state = get()\n const days: Date[] = []\n for (let i = 0; i < 7; i++) {\n days.push(addDays(state.currentWeekStart, i))\n }\n return days\n },\n}))\n"
|
|
277
|
+
}
|
|
278
|
+
],
|
|
279
|
+
"categories": [
|
|
280
|
+
"example-app",
|
|
281
|
+
"productivity",
|
|
282
|
+
"calendar",
|
|
283
|
+
"production",
|
|
284
|
+
"film",
|
|
285
|
+
"operations"
|
|
286
|
+
],
|
|
287
|
+
"dependencies": [
|
|
288
|
+
"@base-ui/react",
|
|
289
|
+
"@hugeicons/core-free-icons",
|
|
290
|
+
"@hugeicons/react",
|
|
291
|
+
"class-variance-authority",
|
|
292
|
+
"clsx",
|
|
293
|
+
"date-fns",
|
|
294
|
+
"next-themes",
|
|
295
|
+
"react-day-picker",
|
|
296
|
+
"tailwind-merge",
|
|
297
|
+
"zustand"
|
|
298
|
+
],
|
|
299
|
+
"registryDependencies": [
|
|
300
|
+
"https://www.loveui.dev/r/avatar.json",
|
|
301
|
+
"https://www.loveui.dev/r/button.json",
|
|
302
|
+
"https://www.loveui.dev/r/collapsible.json",
|
|
303
|
+
"https://www.loveui.dev/r/dialog.json",
|
|
304
|
+
"https://www.loveui.dev/r/input.json",
|
|
305
|
+
"https://www.loveui.dev/r/kbd.json",
|
|
306
|
+
"https://www.loveui.dev/r/label.json",
|
|
307
|
+
"https://www.loveui.dev/r/menu.json",
|
|
308
|
+
"https://www.loveui.dev/r/popover.json",
|
|
309
|
+
"https://www.loveui.dev/r/separator.json",
|
|
310
|
+
"https://www.loveui.dev/r/sheet.json"
|
|
311
|
+
],
|
|
312
|
+
"meta": {
|
|
313
|
+
"source": "example-app",
|
|
314
|
+
"appName": "calendar",
|
|
315
|
+
"routes": [
|
|
316
|
+
{
|
|
317
|
+
"path": "/",
|
|
318
|
+
"title": "Production Week",
|
|
319
|
+
"description": "Weekly production timeline and call scheduling"
|
|
320
|
+
}
|
|
321
|
+
]
|
|
322
|
+
}
|
|
323
|
+
}
|