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,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-12",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/input.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/label.json"
|
|
8
|
+
],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "registry/default/components/comp-12.tsx",
|
|
12
|
+
"content": "import { useId } from \"react\"\n\nimport { Input } from \"@/registry/building-blocks/default/ui/input\"\nimport { Label } from \"@/registry/building-blocks/default/ui/label\"\n\nexport default function Component() {\n const id = useId()\n return (\n <div className=\"*:not-first:mt-2\">\n <Label htmlFor={id}>Input with end inline add-on</Label>\n <div className=\"relative\">\n <Input\n id={id}\n className=\"peer pe-12\"\n placeholder=\"google\"\n type=\"text\"\n />\n <span className=\"pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-sm text-muted-foreground peer-disabled:opacity-50\">\n .com\n </span>\n </div>\n </div>\n )\n}\n",
|
|
13
|
+
"type": "registry:component"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"meta": {
|
|
17
|
+
"tags": [
|
|
18
|
+
"input",
|
|
19
|
+
"label"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-120",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"dependencies": [
|
|
6
|
+
"@remixicon/react"
|
|
7
|
+
],
|
|
8
|
+
"registryDependencies": [
|
|
9
|
+
"https://loveui.dev/building-blocks/r/button.json"
|
|
10
|
+
],
|
|
11
|
+
"files": [
|
|
12
|
+
{
|
|
13
|
+
"path": "registry/default/components/comp-120.tsx",
|
|
14
|
+
"content": "import {\n RiFacebookFill,\n RiGithubFill,\n RiGoogleFill,\n RiTwitterXFill,\n} from \"@remixicon/react\"\n\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\n\nexport default function Component() {\n return (\n <div className=\"flex flex-wrap gap-2\">\n <Button\n className=\"flex-1\"\n variant=\"outline\"\n aria-label=\"Login with Google\"\n size=\"icon\"\n >\n <RiGoogleFill\n className=\"text-[#DB4437] dark:text-primary\"\n size={16}\n aria-hidden=\"true\"\n />\n </Button>\n <Button\n className=\"flex-1\"\n variant=\"outline\"\n aria-label=\"Login with Facebook\"\n size=\"icon\"\n >\n <RiFacebookFill\n className=\"text-[#1877f2] dark:text-primary\"\n size={16}\n aria-hidden=\"true\"\n />\n </Button>\n <Button\n className=\"flex-1\"\n variant=\"outline\"\n aria-label=\"Login with X\"\n size=\"icon\"\n >\n <RiTwitterXFill\n className=\"text-[#14171a] dark:text-primary\"\n size={16}\n aria-hidden=\"true\"\n />\n </Button>\n <Button\n className=\"flex-1\"\n variant=\"outline\"\n aria-label=\"Login with GitHub\"\n size=\"icon\"\n >\n <RiGithubFill\n className=\"text-black dark:text-primary\"\n size={16}\n aria-hidden=\"true\"\n />\n </Button>\n </div>\n )\n}\n",
|
|
15
|
+
"type": "registry:component"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"meta": {
|
|
19
|
+
"tags": [
|
|
20
|
+
"button",
|
|
21
|
+
"social",
|
|
22
|
+
"login",
|
|
23
|
+
"authentication"
|
|
24
|
+
],
|
|
25
|
+
"style": 2
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-121",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"dependencies": [
|
|
6
|
+
"@remixicon/react"
|
|
7
|
+
],
|
|
8
|
+
"registryDependencies": [
|
|
9
|
+
"https://loveui.dev/building-blocks/r/button.json"
|
|
10
|
+
],
|
|
11
|
+
"files": [
|
|
12
|
+
{
|
|
13
|
+
"path": "registry/default/components/comp-121.tsx",
|
|
14
|
+
"content": "import {\n RiFacebookFill,\n RiGithubFill,\n RiGoogleFill,\n RiTwitterXFill,\n} from \"@remixicon/react\"\n\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\n\nexport default function Component() {\n return (\n <div className=\"flex flex-col gap-2\">\n <Button variant=\"outline\">\n <RiGoogleFill\n className=\"me-1 text-[#DB4437] dark:text-white/60\"\n size={16}\n aria-hidden=\"true\"\n />\n Login with Google\n </Button>\n <Button variant=\"outline\">\n <RiTwitterXFill\n className=\"me-1 text-[#14171a] dark:text-white/60\"\n size={16}\n aria-hidden=\"true\"\n />\n Login with X\n </Button>\n <Button variant=\"outline\">\n <RiFacebookFill\n className=\"me-1 text-[#1877f2] dark:text-white/60\"\n size={16}\n aria-hidden=\"true\"\n />\n Login with Facebook\n </Button>\n <Button variant=\"outline\">\n <RiGithubFill\n className=\"me-1 text-[#333333] dark:text-white/60\"\n size={16}\n aria-hidden=\"true\"\n />\n Login with GitHub\n </Button>\n </div>\n )\n}\n",
|
|
15
|
+
"type": "registry:component"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"meta": {
|
|
19
|
+
"tags": [
|
|
20
|
+
"button",
|
|
21
|
+
"social",
|
|
22
|
+
"login",
|
|
23
|
+
"authentication"
|
|
24
|
+
],
|
|
25
|
+
"style": 2
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-122",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"dependencies": [
|
|
6
|
+
"@remixicon/react"
|
|
7
|
+
],
|
|
8
|
+
"registryDependencies": [
|
|
9
|
+
"https://loveui.dev/building-blocks/r/button.json"
|
|
10
|
+
],
|
|
11
|
+
"files": [
|
|
12
|
+
{
|
|
13
|
+
"path": "registry/default/components/comp-122.tsx",
|
|
14
|
+
"content": "import {\n RiFacebookFill,\n RiGithubFill,\n RiGoogleFill,\n RiTwitterXFill,\n} from \"@remixicon/react\"\n\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\n\nexport default function Component() {\n return (\n <div className=\"flex flex-col gap-2\">\n <Button className=\"bg-[#DB4437] text-white after:flex-1 hover:bg-[#DB4437]/90\">\n <span className=\"pointer-events-none me-2 flex-1\">\n <RiGoogleFill className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n </span>\n Login with Google\n </Button>\n <Button className=\"bg-[#14171a] text-white after:flex-1 hover:bg-[#14171a]/90\">\n <span className=\"pointer-events-none me-2 flex-1\">\n <RiTwitterXFill className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n </span>\n Login with X\n </Button>\n <Button className=\"bg-[#1877f2] text-white after:flex-1 hover:bg-[#1877f2]/90\">\n <span className=\"pointer-events-none me-2 flex-1\">\n <RiFacebookFill className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n </span>\n Login with Facebook\n </Button>\n <Button className=\"bg-[#333333] text-white after:flex-1 hover:bg-[#333333]/90\">\n <span className=\"pointer-events-none me-2 flex-1\">\n <RiGithubFill className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n </span>\n Login with GitHub\n </Button>\n </div>\n )\n}\n",
|
|
15
|
+
"type": "registry:component"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"meta": {
|
|
19
|
+
"tags": [
|
|
20
|
+
"button",
|
|
21
|
+
"social",
|
|
22
|
+
"login",
|
|
23
|
+
"authentication"
|
|
24
|
+
],
|
|
25
|
+
"style": 2
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-123",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/button.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-123.tsx",
|
|
11
|
+
"content": "\"use client\"\n\nimport { useState } from \"react\"\nimport { ChevronDownIcon, ChevronUpIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\n\nexport default function Component() {\n const [isExpanded, setIsExpanded] = useState<boolean>(false)\n\n const toggleExpand = () => {\n setIsExpanded((prevState) => !prevState)\n }\n\n return (\n <Button\n className=\"gap-1\"\n variant=\"ghost\"\n onClick={toggleExpand}\n aria-expanded={isExpanded}\n aria-controls=\"expandable-content\" // Use this ID on the element that this button controls\n >\n {isExpanded ? \"Show less\" : \"Show more\"}\n {isExpanded ? (\n <ChevronUpIcon className=\"-me-1\" size={16} aria-hidden=\"true\" />\n ) : (\n <ChevronDownIcon className=\"-me-1\" size={16} aria-hidden=\"true\" />\n )}\n </Button>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"button",
|
|
18
|
+
"collapsible"
|
|
19
|
+
],
|
|
20
|
+
"style": 2
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-124",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/button.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-124.tsx",
|
|
11
|
+
"content": "import { ChevronLeftIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\n\nexport default function Component() {\n return (\n <Button variant=\"link\" className=\"gap-1\">\n <ChevronLeftIcon className=\"opacity-60\" size={16} aria-hidden=\"true\" />\n Go back\n </Button>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"button",
|
|
18
|
+
"back"
|
|
19
|
+
],
|
|
20
|
+
"style": 2
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-125",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/button.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-125.tsx",
|
|
11
|
+
"content": "\"use client\"\n\nimport { CircleUserRoundIcon } from \"lucide-react\"\n\nimport { useFileUpload } from \"@/registry/building-blocks/default/hooks/use-file-upload\"\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\n\nexport default function Component() {\n const [{ files }, { removeFile, openFileDialog, getInputProps }] =\n useFileUpload({\n accept: \"image/*\",\n })\n\n const previewUrl = files[0]?.preview || null\n const fileName = files[0]?.file.name || null\n\n return (\n <div className=\"flex flex-col items-center gap-2\">\n <div className=\"inline-flex items-center gap-2 align-top\">\n <div\n className=\"relative flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-md border border-input\"\n aria-label={\n previewUrl ? \"Preview of uploaded image\" : \"Default user avatar\"\n }\n >\n {previewUrl ? (\n <img\n className=\"size-full object-cover\"\n src={previewUrl}\n alt=\"Preview of uploaded image\"\n width={32}\n height={32}\n />\n ) : (\n <div aria-hidden=\"true\">\n <CircleUserRoundIcon className=\"opacity-60\" size={16} />\n </div>\n )}\n </div>\n <div className=\"relative inline-block\">\n <Button onClick={openFileDialog} aria-haspopup=\"dialog\">\n {fileName ? \"Change image\" : \"Upload image\"}\n </Button>\n <input\n {...getInputProps()}\n className=\"sr-only\"\n aria-label=\"Upload image file\"\n tabIndex={-1}\n />\n </div>\n </div>\n {fileName && (\n <div className=\"inline-flex gap-2 text-xs\">\n <p className=\"truncate text-muted-foreground\" aria-live=\"polite\">\n {fileName}\n </p>{\" \"}\n <button\n onClick={() => removeFile(files[0]?.id)}\n className=\"font-medium text-destructive hover:underline\"\n aria-label={`Remove ${fileName}`}\n >\n Remove\n </button>\n </div>\n )}\n <p\n aria-live=\"polite\"\n role=\"region\"\n className=\"mt-2 text-xs text-muted-foreground\"\n >\n Basic image uploader ∙{\" \"}\n <a\n href=\"https://github.com/loveui/blob/main/apps/origin/docs/use-file-upload.md\"\n className=\"underline hover:text-foreground\"\n >\n Docs\n </a>\n </p>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"path": "registry/default/hooks/use-file-upload.ts",
|
|
16
|
+
"content": "\"use client\"\n\nimport type React from \"react\"\nimport {\n useCallback,\n useRef,\n useState,\n type ChangeEvent,\n type DragEvent,\n type InputHTMLAttributes,\n} from \"react\"\n\nexport type FileMetadata = {\n name: string\n size: number\n type: string\n url: string\n id: string\n}\n\nexport type FileWithPreview = {\n file: File | FileMetadata\n id: string\n preview?: string\n}\n\nexport type FileUploadOptions = {\n maxFiles?: number // Only used when multiple is true, defaults to Infinity\n maxSize?: number // in bytes\n accept?: string\n multiple?: boolean // Defaults to false\n initialFiles?: FileMetadata[]\n onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n files: FileWithPreview[]\n isDragging: boolean\n errors: string[]\n}\n\nexport type FileUploadActions = {\n addFiles: (files: FileList | File[]) => void\n removeFile: (id: string) => void\n clearFiles: () => void\n clearErrors: () => void\n handleDragEnter: (e: DragEvent<HTMLElement>) => void\n handleDragLeave: (e: DragEvent<HTMLElement>) => void\n handleDragOver: (e: DragEvent<HTMLElement>) => void\n handleDrop: (e: DragEvent<HTMLElement>) => void\n handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n openFileDialog: () => void\n getInputProps: (\n props?: InputHTMLAttributes<HTMLInputElement>\n ) => InputHTMLAttributes<HTMLInputElement> & {\n // Use `any` here to avoid cross-React ref type conflicts across packages\n ref: any\n }\n}\n\nexport const useFileUpload = (\n options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n const {\n maxFiles = Infinity,\n maxSize = Infinity,\n accept = \"*\",\n multiple = false,\n initialFiles = [],\n onFilesChange,\n onFilesAdded,\n } = options\n\n const [state, setState] = useState<FileUploadState>({\n files: initialFiles.map((file) => ({\n file,\n id: file.id,\n preview: file.url,\n })),\n isDragging: false,\n errors: [],\n })\n\n const inputRef = useRef<HTMLInputElement>(null)\n\n const validateFile = useCallback(\n (file: File | FileMetadata): string | null => {\n if (file instanceof File) {\n if (file.size > maxSize) {\n return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n }\n } else {\n if (file.size > maxSize) {\n return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n }\n }\n\n if (accept !== \"*\") {\n const acceptedTypes = accept.split(\",\").map((type) => type.trim())\n const fileType = file instanceof File ? file.type || \"\" : file.type\n const fileExtension = `.${file instanceof File ? file.name.split(\".\").pop() : file.name.split(\".\").pop()}`\n\n const isAccepted = acceptedTypes.some((type) => {\n if (type.startsWith(\".\")) {\n return fileExtension.toLowerCase() === type.toLowerCase()\n }\n if (type.endsWith(\"/*\")) {\n const baseType = type.split(\"/\")[0]\n return fileType.startsWith(`${baseType}/`)\n }\n return fileType === type\n })\n\n if (!isAccepted) {\n return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n }\n }\n\n return null\n },\n [accept, maxSize]\n )\n\n const createPreview = useCallback(\n (file: File | FileMetadata): string | undefined => {\n if (file instanceof File) {\n return URL.createObjectURL(file)\n }\n return file.url\n },\n []\n )\n\n const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n if (file instanceof File) {\n return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n }\n return file.id\n }, [])\n\n const clearFiles = useCallback(() => {\n setState((prev) => {\n // Clean up object URLs\n prev.files.forEach((file) => {\n if (\n file.preview &&\n file.file instanceof File &&\n file.file.type.startsWith(\"image/\")\n ) {\n URL.revokeObjectURL(file.preview)\n }\n })\n\n if (inputRef.current) {\n inputRef.current.value = \"\"\n }\n\n const newState = {\n ...prev,\n files: [],\n errors: [],\n }\n\n onFilesChange?.(newState.files)\n return newState\n })\n }, [onFilesChange])\n\n const addFiles = useCallback(\n (newFiles: FileList | File[]) => {\n if (!newFiles || newFiles.length === 0) return\n\n const newFilesArray = Array.from(newFiles)\n const errors: string[] = []\n\n // Clear existing errors when new files are uploaded\n setState((prev) => ({ ...prev, errors: [] }))\n\n // In single file mode, clear existing files first\n if (!multiple) {\n clearFiles()\n }\n\n // Check if adding these files would exceed maxFiles (only in multiple mode)\n if (\n multiple &&\n maxFiles !== Infinity &&\n state.files.length + newFilesArray.length > maxFiles\n ) {\n errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n setState((prev) => ({ ...prev, errors }))\n return\n }\n\n const validFiles: FileWithPreview[] = []\n\n newFilesArray.forEach((file) => {\n // Only check for duplicates if multiple files are allowed\n if (multiple) {\n const isDuplicate = state.files.some(\n (existingFile) =>\n existingFile.file.name === file.name &&\n existingFile.file.size === file.size\n )\n\n // Skip duplicate files silently\n if (isDuplicate) {\n return\n }\n }\n\n // Check file size\n if (file.size > maxSize) {\n errors.push(\n multiple\n ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n )\n return\n }\n\n const error = validateFile(file)\n if (error) {\n errors.push(error)\n } else {\n validFiles.push({\n file,\n id: generateUniqueId(file),\n preview: createPreview(file),\n })\n }\n })\n\n // Only update state if we have valid files to add\n if (validFiles.length > 0) {\n // Call the onFilesAdded callback with the newly added valid files\n onFilesAdded?.(validFiles)\n\n setState((prev) => {\n const newFiles = !multiple\n ? validFiles\n : [...prev.files, ...validFiles]\n onFilesChange?.(newFiles)\n return {\n ...prev,\n files: newFiles,\n errors,\n }\n })\n } else if (errors.length > 0) {\n setState((prev) => ({\n ...prev,\n errors,\n }))\n }\n\n // Reset input value after handling files\n if (inputRef.current) {\n inputRef.current.value = \"\"\n }\n },\n [\n state.files,\n maxFiles,\n multiple,\n maxSize,\n validateFile,\n createPreview,\n generateUniqueId,\n clearFiles,\n onFilesChange,\n onFilesAdded,\n ]\n )\n\n const removeFile = useCallback(\n (id: string) => {\n setState((prev) => {\n const fileToRemove = prev.files.find((file) => file.id === id)\n if (\n fileToRemove &&\n fileToRemove.preview &&\n fileToRemove.file instanceof File &&\n fileToRemove.file.type.startsWith(\"image/\")\n ) {\n URL.revokeObjectURL(fileToRemove.preview)\n }\n\n const newFiles = prev.files.filter((file) => file.id !== id)\n onFilesChange?.(newFiles)\n\n return {\n ...prev,\n files: newFiles,\n errors: [],\n }\n })\n },\n [onFilesChange]\n )\n\n const clearErrors = useCallback(() => {\n setState((prev) => ({\n ...prev,\n errors: [],\n }))\n }, [])\n\n const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setState((prev) => ({ ...prev, isDragging: true }))\n }, [])\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault()\n e.stopPropagation()\n\n if (e.currentTarget.contains(e.relatedTarget as Node)) {\n return\n }\n\n setState((prev) => ({ ...prev, isDragging: false }))\n }, [])\n\n const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault()\n e.stopPropagation()\n }, [])\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setState((prev) => ({ ...prev, isDragging: false }))\n\n // Don't process files if the input is disabled\n if (inputRef.current?.disabled) {\n return\n }\n\n if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n // In single file mode, only use the first file\n if (!multiple) {\n const file = e.dataTransfer.files[0]\n addFiles([file])\n } else {\n addFiles(e.dataTransfer.files)\n }\n }\n },\n [addFiles, multiple]\n )\n\n const handleFileChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n if (e.target.files && e.target.files.length > 0) {\n addFiles(e.target.files)\n }\n },\n [addFiles]\n )\n\n const openFileDialog = useCallback(() => {\n if (inputRef.current) {\n inputRef.current.click()\n }\n }, [])\n\n const getInputProps = useCallback(\n (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n return {\n ...props,\n type: \"file\" as const,\n onChange: handleFileChange,\n accept: props.accept || accept,\n multiple: props.multiple !== undefined ? props.multiple : multiple,\n // Cast to `any` to prevent mismatched React ref type errors across workspaces\n ref: inputRef as any,\n }\n },\n [accept, multiple, handleFileChange]\n )\n\n return [\n state,\n {\n addFiles,\n removeFile,\n clearFiles,\n clearErrors,\n handleDragEnter,\n handleDragLeave,\n handleDragOver,\n handleDrop,\n handleFileChange,\n openFileDialog,\n getInputProps,\n },\n ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n if (bytes === 0) return \"0 Bytes\"\n\n const k = 1024\n const dm = decimals < 0 ? 0 : decimals\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n",
|
|
17
|
+
"type": "registry:hook"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"meta": {
|
|
21
|
+
"tags": [
|
|
22
|
+
"button",
|
|
23
|
+
"upload",
|
|
24
|
+
"user",
|
|
25
|
+
"avatar",
|
|
26
|
+
"profile",
|
|
27
|
+
"image"
|
|
28
|
+
],
|
|
29
|
+
"style": 2
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-126",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/button.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-126.tsx",
|
|
11
|
+
"content": "\"use client\"\n\nimport { CircleUserRoundIcon, XIcon } from \"lucide-react\"\n\nimport { useFileUpload } from \"@/registry/building-blocks/default/hooks/use-file-upload\"\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\n\nexport default function Component() {\n const [{ files }, { removeFile, openFileDialog, getInputProps }] =\n useFileUpload({\n accept: \"image/*\",\n })\n\n const previewUrl = files[0]?.preview || null\n const fileName = files[0]?.file.name || null\n\n return (\n <div className=\"flex flex-col items-center gap-2\">\n <div className=\"relative inline-flex\">\n <Button\n variant=\"outline\"\n className=\"relative size-16 overflow-hidden p-0 shadow-none\"\n onClick={openFileDialog}\n aria-label={previewUrl ? \"Change image\" : \"Upload image\"}\n >\n {previewUrl ? (\n <img\n className=\"size-full object-cover\"\n src={previewUrl}\n alt=\"Preview of uploaded image\"\n width={64}\n height={64}\n style={{ objectFit: \"cover\" }}\n />\n ) : (\n <div aria-hidden=\"true\">\n <CircleUserRoundIcon className=\"size-4 opacity-60\" />\n </div>\n )}\n </Button>\n {previewUrl && (\n <Button\n onClick={() => removeFile(files[0]?.id)}\n size=\"icon\"\n className=\"absolute -top-2 -right-2 size-6 rounded-full border-2 border-background shadow-none focus-visible:border-background\"\n aria-label=\"Remove image\"\n >\n <XIcon className=\"size-3.5\" />\n </Button>\n )}\n <input\n {...getInputProps()}\n className=\"sr-only\"\n aria-label=\"Upload image file\"\n tabIndex={-1}\n />\n </div>\n {fileName && <p className=\"text-xs text-muted-foreground\">{fileName}</p>}\n <p\n aria-live=\"polite\"\n role=\"region\"\n className=\"mt-2 text-xs text-muted-foreground\"\n >\n Avatar upload button\n </p>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"path": "registry/default/hooks/use-file-upload.ts",
|
|
16
|
+
"content": "\"use client\"\n\nimport type React from \"react\"\nimport {\n useCallback,\n useRef,\n useState,\n type ChangeEvent,\n type DragEvent,\n type InputHTMLAttributes,\n} from \"react\"\n\nexport type FileMetadata = {\n name: string\n size: number\n type: string\n url: string\n id: string\n}\n\nexport type FileWithPreview = {\n file: File | FileMetadata\n id: string\n preview?: string\n}\n\nexport type FileUploadOptions = {\n maxFiles?: number // Only used when multiple is true, defaults to Infinity\n maxSize?: number // in bytes\n accept?: string\n multiple?: boolean // Defaults to false\n initialFiles?: FileMetadata[]\n onFilesChange?: (files: FileWithPreview[]) => void // Callback when files change\n onFilesAdded?: (addedFiles: FileWithPreview[]) => void // Callback when new files are added\n}\n\nexport type FileUploadState = {\n files: FileWithPreview[]\n isDragging: boolean\n errors: string[]\n}\n\nexport type FileUploadActions = {\n addFiles: (files: FileList | File[]) => void\n removeFile: (id: string) => void\n clearFiles: () => void\n clearErrors: () => void\n handleDragEnter: (e: DragEvent<HTMLElement>) => void\n handleDragLeave: (e: DragEvent<HTMLElement>) => void\n handleDragOver: (e: DragEvent<HTMLElement>) => void\n handleDrop: (e: DragEvent<HTMLElement>) => void\n handleFileChange: (e: ChangeEvent<HTMLInputElement>) => void\n openFileDialog: () => void\n getInputProps: (\n props?: InputHTMLAttributes<HTMLInputElement>\n ) => InputHTMLAttributes<HTMLInputElement> & {\n // Use `any` here to avoid cross-React ref type conflicts across packages\n ref: any\n }\n}\n\nexport const useFileUpload = (\n options: FileUploadOptions = {}\n): [FileUploadState, FileUploadActions] => {\n const {\n maxFiles = Infinity,\n maxSize = Infinity,\n accept = \"*\",\n multiple = false,\n initialFiles = [],\n onFilesChange,\n onFilesAdded,\n } = options\n\n const [state, setState] = useState<FileUploadState>({\n files: initialFiles.map((file) => ({\n file,\n id: file.id,\n preview: file.url,\n })),\n isDragging: false,\n errors: [],\n })\n\n const inputRef = useRef<HTMLInputElement>(null)\n\n const validateFile = useCallback(\n (file: File | FileMetadata): string | null => {\n if (file instanceof File) {\n if (file.size > maxSize) {\n return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n }\n } else {\n if (file.size > maxSize) {\n return `File \"${file.name}\" exceeds the maximum size of ${formatBytes(maxSize)}.`\n }\n }\n\n if (accept !== \"*\") {\n const acceptedTypes = accept.split(\",\").map((type) => type.trim())\n const fileType = file instanceof File ? file.type || \"\" : file.type\n const fileExtension = `.${file instanceof File ? file.name.split(\".\").pop() : file.name.split(\".\").pop()}`\n\n const isAccepted = acceptedTypes.some((type) => {\n if (type.startsWith(\".\")) {\n return fileExtension.toLowerCase() === type.toLowerCase()\n }\n if (type.endsWith(\"/*\")) {\n const baseType = type.split(\"/\")[0]\n return fileType.startsWith(`${baseType}/`)\n }\n return fileType === type\n })\n\n if (!isAccepted) {\n return `File \"${file instanceof File ? file.name : file.name}\" is not an accepted file type.`\n }\n }\n\n return null\n },\n [accept, maxSize]\n )\n\n const createPreview = useCallback(\n (file: File | FileMetadata): string | undefined => {\n if (file instanceof File) {\n return URL.createObjectURL(file)\n }\n return file.url\n },\n []\n )\n\n const generateUniqueId = useCallback((file: File | FileMetadata): string => {\n if (file instanceof File) {\n return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`\n }\n return file.id\n }, [])\n\n const clearFiles = useCallback(() => {\n setState((prev) => {\n // Clean up object URLs\n prev.files.forEach((file) => {\n if (\n file.preview &&\n file.file instanceof File &&\n file.file.type.startsWith(\"image/\")\n ) {\n URL.revokeObjectURL(file.preview)\n }\n })\n\n if (inputRef.current) {\n inputRef.current.value = \"\"\n }\n\n const newState = {\n ...prev,\n files: [],\n errors: [],\n }\n\n onFilesChange?.(newState.files)\n return newState\n })\n }, [onFilesChange])\n\n const addFiles = useCallback(\n (newFiles: FileList | File[]) => {\n if (!newFiles || newFiles.length === 0) return\n\n const newFilesArray = Array.from(newFiles)\n const errors: string[] = []\n\n // Clear existing errors when new files are uploaded\n setState((prev) => ({ ...prev, errors: [] }))\n\n // In single file mode, clear existing files first\n if (!multiple) {\n clearFiles()\n }\n\n // Check if adding these files would exceed maxFiles (only in multiple mode)\n if (\n multiple &&\n maxFiles !== Infinity &&\n state.files.length + newFilesArray.length > maxFiles\n ) {\n errors.push(`You can only upload a maximum of ${maxFiles} files.`)\n setState((prev) => ({ ...prev, errors }))\n return\n }\n\n const validFiles: FileWithPreview[] = []\n\n newFilesArray.forEach((file) => {\n // Only check for duplicates if multiple files are allowed\n if (multiple) {\n const isDuplicate = state.files.some(\n (existingFile) =>\n existingFile.file.name === file.name &&\n existingFile.file.size === file.size\n )\n\n // Skip duplicate files silently\n if (isDuplicate) {\n return\n }\n }\n\n // Check file size\n if (file.size > maxSize) {\n errors.push(\n multiple\n ? `Some files exceed the maximum size of ${formatBytes(maxSize)}.`\n : `File exceeds the maximum size of ${formatBytes(maxSize)}.`\n )\n return\n }\n\n const error = validateFile(file)\n if (error) {\n errors.push(error)\n } else {\n validFiles.push({\n file,\n id: generateUniqueId(file),\n preview: createPreview(file),\n })\n }\n })\n\n // Only update state if we have valid files to add\n if (validFiles.length > 0) {\n // Call the onFilesAdded callback with the newly added valid files\n onFilesAdded?.(validFiles)\n\n setState((prev) => {\n const newFiles = !multiple\n ? validFiles\n : [...prev.files, ...validFiles]\n onFilesChange?.(newFiles)\n return {\n ...prev,\n files: newFiles,\n errors,\n }\n })\n } else if (errors.length > 0) {\n setState((prev) => ({\n ...prev,\n errors,\n }))\n }\n\n // Reset input value after handling files\n if (inputRef.current) {\n inputRef.current.value = \"\"\n }\n },\n [\n state.files,\n maxFiles,\n multiple,\n maxSize,\n validateFile,\n createPreview,\n generateUniqueId,\n clearFiles,\n onFilesChange,\n onFilesAdded,\n ]\n )\n\n const removeFile = useCallback(\n (id: string) => {\n setState((prev) => {\n const fileToRemove = prev.files.find((file) => file.id === id)\n if (\n fileToRemove &&\n fileToRemove.preview &&\n fileToRemove.file instanceof File &&\n fileToRemove.file.type.startsWith(\"image/\")\n ) {\n URL.revokeObjectURL(fileToRemove.preview)\n }\n\n const newFiles = prev.files.filter((file) => file.id !== id)\n onFilesChange?.(newFiles)\n\n return {\n ...prev,\n files: newFiles,\n errors: [],\n }\n })\n },\n [onFilesChange]\n )\n\n const clearErrors = useCallback(() => {\n setState((prev) => ({\n ...prev,\n errors: [],\n }))\n }, [])\n\n const handleDragEnter = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setState((prev) => ({ ...prev, isDragging: true }))\n }, [])\n\n const handleDragLeave = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault()\n e.stopPropagation()\n\n if (e.currentTarget.contains(e.relatedTarget as Node)) {\n return\n }\n\n setState((prev) => ({ ...prev, isDragging: false }))\n }, [])\n\n const handleDragOver = useCallback((e: DragEvent<HTMLElement>) => {\n e.preventDefault()\n e.stopPropagation()\n }, [])\n\n const handleDrop = useCallback(\n (e: DragEvent<HTMLElement>) => {\n e.preventDefault()\n e.stopPropagation()\n setState((prev) => ({ ...prev, isDragging: false }))\n\n // Don't process files if the input is disabled\n if (inputRef.current?.disabled) {\n return\n }\n\n if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {\n // In single file mode, only use the first file\n if (!multiple) {\n const file = e.dataTransfer.files[0]\n addFiles([file])\n } else {\n addFiles(e.dataTransfer.files)\n }\n }\n },\n [addFiles, multiple]\n )\n\n const handleFileChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n if (e.target.files && e.target.files.length > 0) {\n addFiles(e.target.files)\n }\n },\n [addFiles]\n )\n\n const openFileDialog = useCallback(() => {\n if (inputRef.current) {\n inputRef.current.click()\n }\n }, [])\n\n const getInputProps = useCallback(\n (props: InputHTMLAttributes<HTMLInputElement> = {}) => {\n return {\n ...props,\n type: \"file\" as const,\n onChange: handleFileChange,\n accept: props.accept || accept,\n multiple: props.multiple !== undefined ? props.multiple : multiple,\n // Cast to `any` to prevent mismatched React ref type errors across workspaces\n ref: inputRef as any,\n }\n },\n [accept, multiple, handleFileChange]\n )\n\n return [\n state,\n {\n addFiles,\n removeFile,\n clearFiles,\n clearErrors,\n handleDragEnter,\n handleDragLeave,\n handleDragOver,\n handleDrop,\n handleFileChange,\n openFileDialog,\n getInputProps,\n },\n ]\n}\n\n// Helper function to format bytes to human-readable format\nexport const formatBytes = (bytes: number, decimals = 2): string => {\n if (bytes === 0) return \"0 Bytes\"\n\n const k = 1024\n const dm = decimals < 0 ? 0 : decimals\n const sizes = [\"Bytes\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\"]\n\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n\n return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + sizes[i]\n}\n",
|
|
17
|
+
"type": "registry:hook"
|
|
18
|
+
}
|
|
19
|
+
],
|
|
20
|
+
"meta": {
|
|
21
|
+
"tags": [
|
|
22
|
+
"button",
|
|
23
|
+
"upload",
|
|
24
|
+
"user",
|
|
25
|
+
"avatar",
|
|
26
|
+
"profile",
|
|
27
|
+
"image"
|
|
28
|
+
],
|
|
29
|
+
"style": 2
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-127",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/button.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-127.tsx",
|
|
11
|
+
"content": "import {\n ChevronDownIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n ChevronUpIcon,\n CircleIcon,\n} from \"lucide-react\"\n\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\n\nexport default function Component() {\n return (\n <div className=\"inline-grid w-fit grid-cols-3 gap-1\">\n <Button\n className=\"col-start-2\"\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Pan camera up\"\n >\n <ChevronUpIcon size={16} aria-hidden=\"true\" />\n </Button>\n <Button\n className=\"col-start-1\"\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Pan camera left\"\n >\n <ChevronLeftIcon size={16} aria-hidden=\"true\" />\n </Button>\n <div className=\"flex items-center justify-center\" aria-hidden=\"true\">\n <CircleIcon className=\"opacity-60\" size={16} />\n </div>\n <Button variant=\"outline\" size=\"icon\" aria-label=\"Pan camera right\">\n <ChevronRightIcon size={16} aria-hidden=\"true\" />\n </Button>\n <Button\n className=\"col-start-2\"\n variant=\"outline\"\n size=\"icon\"\n aria-label=\"Pan camera down\"\n >\n <ChevronDownIcon size={16} aria-hidden=\"true\" />\n </Button>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"button"
|
|
18
|
+
],
|
|
19
|
+
"style": 2
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-128",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/button.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-128.tsx",
|
|
11
|
+
"content": "import { ChevronRightIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\n\nexport default function Component() {\n return (\n <Button className=\"group h-auto gap-4 py-3 text-left\" variant=\"outline\">\n <div className=\"space-y-1\">\n <h3>Talent Agency</h3>\n <p className=\"font-normal whitespace-break-spaces text-muted-foreground\">\n Matches for your roster\n </p>\n </div>\n <ChevronRightIcon\n className=\"opacity-60 transition-transform group-hover:translate-x-0.5\"\n size={16}\n aria-hidden=\"true\"\n />\n </Button>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"button"
|
|
18
|
+
],
|
|
19
|
+
"style": 2
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-129",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/badge.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/button.json"
|
|
8
|
+
],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "registry/default/components/comp-129.tsx",
|
|
12
|
+
"content": "\"use client\"\n\nimport { useState } from \"react\"\nimport { BellIcon } from \"lucide-react\"\n\nimport { Badge } from \"@/registry/building-blocks/default/ui/badge\"\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\n\nexport default function Component() {\n const [count, setCount] = useState(3)\n\n const handleClick = () => {\n setCount(0)\n }\n\n return (\n <Button\n variant=\"outline\"\n size=\"icon\"\n className=\"relative\"\n onClick={handleClick}\n aria-label=\"Notifications\"\n >\n <BellIcon size={16} aria-hidden=\"true\" />\n {count > 0 && (\n <Badge className=\"absolute -top-2 left-full min-w-5 -translate-x-1/2 px-1\">\n {count > 99 ? \"99+\" : count}\n </Badge>\n )}\n </Button>\n )\n}\n",
|
|
13
|
+
"type": "registry:component"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"meta": {
|
|
17
|
+
"tags": [
|
|
18
|
+
"button",
|
|
19
|
+
"dropdown",
|
|
20
|
+
"notification"
|
|
21
|
+
],
|
|
22
|
+
"style": 2
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-13",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/input.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/label.json"
|
|
8
|
+
],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "registry/default/components/comp-13.tsx",
|
|
12
|
+
"content": "import { useId } from \"react\"\n\nimport { Input } from \"@/registry/building-blocks/default/ui/input\"\nimport { Label } from \"@/registry/building-blocks/default/ui/label\"\n\nexport default function Component() {\n const id = useId()\n return (\n <div className=\"*:not-first:mt-2\">\n <Label htmlFor={id}>Input with inline add-ons</Label>\n <div className=\"relative\">\n <Input\n id={id}\n className=\"peer ps-6 pe-12\"\n placeholder=\"0.00\"\n type=\"text\"\n />\n <span className=\"pointer-events-none absolute inset-y-0 start-0 flex items-center justify-center ps-3 text-sm text-muted-foreground peer-disabled:opacity-50\">\n €\n </span>\n <span className=\"pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-sm text-muted-foreground peer-disabled:opacity-50\">\n EUR\n </span>\n </div>\n </div>\n )\n}\n",
|
|
13
|
+
"type": "registry:component"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"meta": {
|
|
17
|
+
"tags": [
|
|
18
|
+
"input",
|
|
19
|
+
"label"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-130",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/toggle.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-130.tsx",
|
|
11
|
+
"content": "\"use client\"\n\nimport { useState } from \"react\"\nimport { MoonIcon, SunIcon } from \"lucide-react\"\n\nimport { Toggle } from \"@/registry/building-blocks/default/ui/toggle\"\n\nexport default function Component() {\n const [theme, setTheme] = useState<string>(\"light\")\n\n return (\n <div>\n <Toggle\n variant=\"outline\"\n className=\"group size-9 data-[state=on]:bg-transparent data-[state=on]:hover:bg-muted\"\n pressed={theme === \"dark\"}\n onPressedChange={() =>\n setTheme((prev) => (prev === \"dark\" ? \"light\" : \"dark\"))\n }\n aria-label={`Switch to ${theme === \"dark\" ? \"light\" : \"dark\"} mode`}\n >\n {/* Note: After dark mode implementation, rely on dark: prefix rather than group-data-[state=on]: */}\n <MoonIcon\n size={16}\n className=\"shrink-0 scale-0 opacity-0 transition-all group-data-[state=on]:scale-100 group-data-[state=on]:opacity-100\"\n aria-hidden=\"true\"\n />\n <SunIcon\n size={16}\n className=\"absolute shrink-0 scale-100 opacity-100 transition-all group-data-[state=on]:scale-0 group-data-[state=on]:opacity-0\"\n aria-hidden=\"true\"\n />\n </Toggle>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"button",
|
|
18
|
+
"toggle",
|
|
19
|
+
"darkmode"
|
|
20
|
+
],
|
|
21
|
+
"style": 2
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-131",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/button.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/dropdown-menu.json"
|
|
8
|
+
],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "registry/default/components/comp-131.tsx",
|
|
12
|
+
"content": "\"use client\"\n\nimport { useState } from \"react\"\nimport { ChevronDownIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuTrigger,\n} from \"@/registry/building-blocks/default/ui/dropdown-menu\"\n\nconst options = [\n {\n label: \"Merge pull request\",\n description:\n \"All commits from this branch will be added to the base branch via a commit version.\",\n },\n {\n label: \"Squash and merge\",\n description:\n \"The 6 commits from this branch will be combined into one commit in the base branch.\",\n },\n {\n label: \"Rebase and merge\",\n description:\n \"The 6 commits from this branch will be rebased and added to the base branch.\",\n },\n]\n\nexport default function Component() {\n const [selectedIndex, setSelectedIndex] = useState(\"0\")\n\n return (\n <div className=\"inline-flex divide-x divide-primary-foreground/30 rounded-md shadow-xs rtl:space-x-reverse\">\n <Button className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\">\n {options[Number(selectedIndex)].label}\n </Button>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button\n className=\"rounded-none shadow-none first:rounded-s-md last:rounded-e-md focus-visible:z-10\"\n size=\"icon\"\n aria-label=\"Options\"\n >\n <ChevronDownIcon size={16} aria-hidden=\"true\" />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent\n className=\"max-w-64 md:max-w-xs\"\n side=\"bottom\"\n sideOffset={4}\n align=\"end\"\n >\n <DropdownMenuRadioGroup\n value={selectedIndex}\n onValueChange={setSelectedIndex}\n >\n {options.map((option, index) => (\n <DropdownMenuRadioItem\n key={option.label}\n value={String(index)}\n className=\"items-start [&>span]:pt-1.5\"\n >\n <div className=\"flex flex-col gap-1\">\n <span className=\"text-sm font-medium\">{option.label}</span>\n <span className=\"text-xs text-muted-foreground\">\n {option.description}\n </span>\n </div>\n </DropdownMenuRadioItem>\n ))}\n </DropdownMenuRadioGroup>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n )\n}\n",
|
|
13
|
+
"type": "registry:component"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"meta": {
|
|
17
|
+
"tags": [
|
|
18
|
+
"button",
|
|
19
|
+
"dropdown"
|
|
20
|
+
],
|
|
21
|
+
"style": 2
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-132",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/checkbox.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/label.json"
|
|
8
|
+
],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "registry/default/components/comp-132.tsx",
|
|
12
|
+
"content": "import { useId } from \"react\"\n\nimport { Checkbox } from \"@/registry/building-blocks/default/ui/checkbox\"\nimport { Label } from \"@/registry/building-blocks/default/ui/label\"\n\nexport default function Component() {\n const id = useId()\n return (\n <div className=\"flex items-center gap-2\">\n <Checkbox id={id} />\n <Label htmlFor={id}>Simple checkbox</Label>\n </div>\n )\n}\n",
|
|
13
|
+
"type": "registry:component"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"meta": {
|
|
17
|
+
"tags": [
|
|
18
|
+
"checkbox",
|
|
19
|
+
"label",
|
|
20
|
+
"radix"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-133",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/checkbox.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/label.json"
|
|
8
|
+
],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "registry/default/components/comp-133.tsx",
|
|
12
|
+
"content": "\"use client\"\n\nimport { useId, useState } from \"react\"\n\nimport { Checkbox } from \"@/registry/building-blocks/default/ui/checkbox\"\nimport { Label } from \"@/registry/building-blocks/default/ui/label\"\n\nexport default function Component() {\n const id = useId()\n const [checked, setChecked] = useState<boolean | \"indeterminate\">(\n \"indeterminate\"\n )\n\n return (\n <div className=\"flex items-center gap-2\">\n <Checkbox id={id} checked={checked} onCheckedChange={setChecked} />\n <Label htmlFor={id}>Indeterminate checkbox</Label>\n </div>\n )\n}\n",
|
|
13
|
+
"type": "registry:component"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"meta": {
|
|
17
|
+
"tags": [
|
|
18
|
+
"checkbox",
|
|
19
|
+
"label",
|
|
20
|
+
"radix"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-134",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/checkbox.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/label.json"
|
|
8
|
+
],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "registry/default/components/comp-134.tsx",
|
|
12
|
+
"content": "import { useId } from \"react\"\n\nimport { Checkbox } from \"@/registry/building-blocks/default/ui/checkbox\"\nimport { Label } from \"@/registry/building-blocks/default/ui/label\"\n\nexport default function Component() {\n const id = useId()\n return (\n <div className=\"flex items-center gap-2 [--primary:var(--color-indigo-500)] [--ring:var(--color-indigo-300)] in-[.dark]:[--primary:var(--color-indigo-500)] in-[.dark]:[--ring:var(--color-indigo-900)]\">\n <Checkbox id={id} defaultChecked />\n <Label htmlFor={id}>Colored checkbox</Label>\n </div>\n )\n}\n",
|
|
13
|
+
"type": "registry:component"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"meta": {
|
|
17
|
+
"tags": [
|
|
18
|
+
"checkbox",
|
|
19
|
+
"label",
|
|
20
|
+
"radix"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-135",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/checkbox.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/label.json"
|
|
8
|
+
],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "registry/default/components/comp-135.tsx",
|
|
12
|
+
"content": "import { useId } from \"react\"\n\nimport { Checkbox } from \"@/registry/building-blocks/default/ui/checkbox\"\nimport { Label } from \"@/registry/building-blocks/default/ui/label\"\n\nexport default function Component() {\n const id = useId()\n return (\n <div className=\"flex items-center gap-2\">\n <Checkbox id={id} disabled />\n <Label htmlFor={id}>Disabled checkbox</Label>\n </div>\n )\n}\n",
|
|
13
|
+
"type": "registry:component"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"meta": {
|
|
17
|
+
"tags": [
|
|
18
|
+
"checkbox",
|
|
19
|
+
"label",
|
|
20
|
+
"disabled",
|
|
21
|
+
"radix"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-136",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/checkbox.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/label.json"
|
|
8
|
+
],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "registry/default/components/comp-136.tsx",
|
|
12
|
+
"content": "import { useId } from \"react\"\n\nimport { Checkbox } from \"@/registry/building-blocks/default/ui/checkbox\"\nimport { Label } from \"@/registry/building-blocks/default/ui/label\"\n\nexport default function Component() {\n const id = useId()\n return (\n <div className=\"flex items-center gap-2\">\n <Checkbox id={id} defaultChecked />\n <Label htmlFor={id} className=\"peer-data-[state=checked]:line-through\">\n Simple todo item\n </Label>\n </div>\n )\n}\n",
|
|
13
|
+
"type": "registry:component"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"meta": {
|
|
17
|
+
"tags": [
|
|
18
|
+
"checkbox",
|
|
19
|
+
"label",
|
|
20
|
+
"radix"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-137",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/checkbox.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/label.json"
|
|
8
|
+
],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "registry/default/components/comp-137.tsx",
|
|
12
|
+
"content": "import { useId } from \"react\"\n\nimport { Checkbox } from \"@/registry/building-blocks/default/ui/checkbox\"\nimport { Label } from \"@/registry/building-blocks/default/ui/label\"\n\nexport default function Component() {\n const id = useId()\n return (\n <div className=\"flex items-center gap-2\">\n <Checkbox\n style={\n {\n \"--primary\": \"var(--color-emerald-500)\",\n } as React.CSSProperties\n }\n id={id}\n className=\"rounded-full\"\n defaultChecked\n />\n <Label\n htmlFor={id}\n className=\"peer-data-[state=checked]:line-throgh relative peer-data-[state=checked]:text-muted-foreground after:absolute after:top-1/2 after:left-0 after:h-px after:w-full after:origin-bottom after:-translate-y-1/2 after:scale-x-0 after:bg-muted-foreground after:transition-transform after:ease-in-out peer-data-[state=checked]:after:origin-bottom peer-data-[state=checked]:after:scale-x-100\"\n >\n Fancy todo item\n </Label>\n </div>\n )\n}\n",
|
|
13
|
+
"type": "registry:component"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"meta": {
|
|
17
|
+
"tags": [
|
|
18
|
+
"checkbox",
|
|
19
|
+
"label",
|
|
20
|
+
"radix"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-138",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/checkbox.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/label.json"
|
|
8
|
+
],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "registry/default/components/comp-138.tsx",
|
|
12
|
+
"content": "import { useId } from \"react\"\n\nimport { Checkbox } from \"@/registry/building-blocks/default/ui/checkbox\"\nimport { Label } from \"@/registry/building-blocks/default/ui/label\"\n\nexport default function Component() {\n const id = useId()\n return (\n <div className=\"flex items-center gap-2\">\n <Checkbox id={id} />\n <Label htmlFor={id}>\n I agree to the{\" \"}\n <a className=\"underline\" href=\"https://loveui.dev/building-blocks\" target=\"_blank\">\n terms of service\n </a>\n </Label>\n </div>\n )\n}\n",
|
|
13
|
+
"type": "registry:component"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"meta": {
|
|
17
|
+
"tags": [
|
|
18
|
+
"checkbox",
|
|
19
|
+
"label",
|
|
20
|
+
"login",
|
|
21
|
+
"authentication",
|
|
22
|
+
"radix"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
}
|