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,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-330",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/button.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/dialog.json",
|
|
8
|
+
"https://loveui.dev/building-blocks/r/label.json",
|
|
9
|
+
"https://loveui.dev/building-blocks/r/radio-group.json"
|
|
10
|
+
],
|
|
11
|
+
"files": [
|
|
12
|
+
{
|
|
13
|
+
"path": "registry/default/components/comp-330.tsx",
|
|
14
|
+
"content": "import { useId } from \"react\"\nimport { CheckIcon, RefreshCcwIcon } from \"lucide-react\"\n\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/registry/building-blocks/default/ui/dialog\"\nimport { Label } from \"@/registry/building-blocks/default/ui/label\"\nimport { RadioGroup, RadioGroupItem } from \"@/registry/building-blocks/default/ui/radio-group\"\n\nexport default function Component() {\n const id = useId()\n return (\n <Dialog>\n <DialogTrigger asChild>\n <Button variant=\"outline\">Change plan</Button>\n </DialogTrigger>\n <DialogContent>\n <div className=\"mb-2 flex flex-col gap-2\">\n <div\n className=\"flex size-11 shrink-0 items-center justify-center rounded-full border\"\n aria-hidden=\"true\"\n >\n <RefreshCcwIcon className=\"opacity-80\" size={16} />\n </div>\n <DialogHeader>\n <DialogTitle className=\"text-left\">Change your plan</DialogTitle>\n <DialogDescription className=\"text-left\">\n Pick one of the following plans.\n </DialogDescription>\n </DialogHeader>\n </div>\n\n <form className=\"space-y-5\">\n <RadioGroup className=\"gap-2\" defaultValue=\"2\">\n {/* Radio card #1 */}\n <div className=\"relative flex w-full items-center gap-2 rounded-md border border-input px-4 py-3 shadow-xs outline-none has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent\">\n <RadioGroupItem\n value=\"1\"\n id={`${id}-1`}\n aria-describedby={`${id}-1-description`}\n className=\"order-1 after:absolute after:inset-0\"\n />\n <div className=\"grid grow gap-1\">\n <Label htmlFor={`${id}-1`}>Essential</Label>\n <p\n id={`${id}-1-description`}\n className=\"text-xs text-muted-foreground\"\n >\n $4 per member/month\n </p>\n </div>\n </div>\n {/* Radio card #2 */}\n <div className=\"relative flex w-full items-center gap-2 rounded-md border border-input px-4 py-3 shadow-xs outline-none has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent\">\n <RadioGroupItem\n value=\"2\"\n id={`${id}-2`}\n aria-describedby={`${id}-2-description`}\n className=\"order-1 after:absolute after:inset-0\"\n />\n <div className=\"grid grow gap-1\">\n <Label htmlFor={`${id}-2`}>Standard</Label>\n <p\n id={`${id}-2-description`}\n className=\"text-xs text-muted-foreground\"\n >\n $19 per member/month\n </p>\n </div>\n </div>\n {/* Radio card #3 */}\n <div className=\"relative flex w-full items-center gap-2 rounded-md border border-input px-4 py-3 shadow-xs outline-none has-data-[state=checked]:border-primary/50 has-data-[state=checked]:bg-accent\">\n <RadioGroupItem\n value=\"3\"\n id={`${id}-3`}\n aria-describedby={`${id}-3-description`}\n className=\"order-1 after:absolute after:inset-0\"\n />\n <div className=\"grid grow gap-1\">\n <Label htmlFor={`${id}-3`}>Enterprise</Label>\n <p\n id={`${id}-3-description`}\n className=\"text-xs text-muted-foreground\"\n >\n $32 per member/month\n </p>\n </div>\n </div>\n </RadioGroup>\n\n <div className=\"space-y-3\">\n <p>\n <strong className=\"text-sm font-medium\">Features include:</strong>\n </p>\n <ul className=\"space-y-2 text-sm text-muted-foreground\">\n <li className=\"flex gap-2\">\n <CheckIcon\n size={16}\n className=\"mt-0.5 shrink-0 text-primary\"\n aria-hidden=\"true\"\n />\n Create unlimited projects.\n </li>\n <li className=\"flex gap-2\">\n <CheckIcon\n size={16}\n className=\"mt-0.5 shrink-0 text-primary\"\n aria-hidden=\"true\"\n />\n Remove watermarks.\n </li>\n <li className=\"flex gap-2\">\n <CheckIcon\n size={16}\n className=\"mt-0.5 shrink-0 text-primary\"\n aria-hidden=\"true\"\n />\n Add unlimited users and free viewers.\n </li>\n <li className=\"flex gap-2\">\n <CheckIcon\n size={16}\n className=\"mt-0.5 shrink-0 text-primary\"\n aria-hidden=\"true\"\n />\n Upload unlimited files.\n </li>\n <li className=\"flex gap-2\">\n <CheckIcon\n size={16}\n className=\"mt-0.5 shrink-0 text-primary\"\n aria-hidden=\"true\"\n />\n 7-day money back guarantee.\n </li>\n <li className=\"flex gap-2\">\n <CheckIcon\n size={16}\n className=\"mt-0.5 shrink-0 text-primary\"\n aria-hidden=\"true\"\n />\n Advanced permissions.\n </li>\n </ul>\n </div>\n\n <div className=\"grid gap-2\">\n <Button type=\"button\" className=\"w-full\">\n Change plan\n </Button>\n <DialogClose asChild>\n <Button type=\"button\" variant=\"ghost\" className=\"w-full\">\n Cancel\n </Button>\n </DialogClose>\n </div>\n </form>\n </DialogContent>\n </Dialog>\n )\n}\n",
|
|
15
|
+
"type": "registry:component"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"meta": {
|
|
19
|
+
"tags": [
|
|
20
|
+
"dialog",
|
|
21
|
+
"modal",
|
|
22
|
+
"user",
|
|
23
|
+
"radix"
|
|
24
|
+
],
|
|
25
|
+
"style": 1
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-331",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/button.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/dialog.json",
|
|
8
|
+
"https://loveui.dev/building-blocks/r/input.json",
|
|
9
|
+
"https://loveui.dev/building-blocks/r/label.json",
|
|
10
|
+
"https://loveui.dev/building-blocks/r/textarea.json"
|
|
11
|
+
],
|
|
12
|
+
"files": [
|
|
13
|
+
{
|
|
14
|
+
"path": "registry/default/components/comp-331.tsx",
|
|
15
|
+
"content": "\"use client\"\n\n\nimport { useId, useState } from \"react\"\nimport { CheckIcon, ImagePlusIcon, XIcon } from \"lucide-react\"\n\nimport { useCharacterLimit } from \"@/registry/building-blocks/default/hooks/use-character-limit\"\nimport { useFileUpload } from \"@/registry/building-blocks/default/hooks/use-file-upload\"\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/registry/building-blocks/default/ui/dialog\"\nimport { Input } from \"@/registry/building-blocks/default/ui/input\"\nimport { Label } from \"@/registry/building-blocks/default/ui/label\"\nimport { Textarea } from \"@/registry/building-blocks/default/ui/textarea\"\n\n// Pretend we have initial image files\nconst initialBgImage = [\n {\n name: \"profile-bg.jpg\",\n size: 1528737,\n type: \"image/jpeg\",\n url: assetPath(\"/building-blocks/profile-bg.jpg\"),\n id: \"profile-bg-123456789\",\n },\n]\n\nconst initialAvatarImage = [\n {\n name: \"avatar-72-01.jpg\",\n size: 1528737,\n type: \"image/jpeg\",\n url: \"https://i.pravatar.cc/160?img=13\",\n id: \"avatar-123456789\",\n },\n]\n\nexport default function Component() {\n const id = useId()\n\n const maxLength = 180\n const {\n value,\n characterCount,\n handleChange,\n maxLength: limit,\n } = useCharacterLimit({\n maxLength,\n initialValue:\n \"Hey, I am Connor, a web developer who loves turning ideas into amazing websites!\",\n })\n\n return (\n <Dialog>\n <DialogTrigger asChild>\n <Button variant=\"outline\">Edit profile</Button>\n </DialogTrigger>\n <DialogContent className=\"flex flex-col gap-0 overflow-y-visible p-0 sm:max-w-lg [&>button:last-child]:top-3.5\">\n <DialogHeader className=\"contents space-y-0 text-left\">\n <DialogTitle className=\"border-b px-6 py-4 text-base\">\n Edit profile\n </DialogTitle>\n </DialogHeader>\n <DialogDescription className=\"sr-only\">\n Make changes to your profile here. You can change your photo and set a\n username.\n </DialogDescription>\n <div className=\"overflow-y-auto\">\n <ProfileBg />\n <Avatar />\n <div className=\"px-6 pt-4 pb-6\">\n <form className=\"space-y-4\">\n <div className=\"flex flex-col gap-4 sm:flex-row\">\n <div className=\"flex-1 space-y-2\">\n <Label htmlFor={`${id}-first-name`}>First name</Label>\n <Input\n id={`${id}-first-name`}\n placeholder=\"Connor\"\n defaultValue=\"Connor\"\n type=\"text\"\n required\n />\n </div>\n <div className=\"flex-1 space-y-2\">\n <Label htmlFor={`${id}-last-name`}>Last name</Label>\n <Input\n id={`${id}-last-name`}\n placeholder=\"Welsh\"\n defaultValue=\"Love\"\n type=\"text\"\n required\n />\n </div>\n </div>\n <div className=\"*:not-first:mt-2\">\n <Label htmlFor={`${id}-username`}>Username</Label>\n <div className=\"relative\">\n <Input\n id={`${id}-username`}\n className=\"peer pe-9\"\n placeholder=\"Username\"\n defaultValue=\"Connor-Love-69\"\n type=\"text\"\n required\n />\n <div className=\"pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-muted-foreground/80 peer-disabled:opacity-50\">\n <CheckIcon\n size={16}\n className=\"text-emerald-500\"\n aria-hidden=\"true\"\n />\n </div>\n </div>\n </div>\n <div className=\"*:not-first:mt-2\">\n <Label htmlFor={`${id}-website`}>Website</Label>\n <div className=\"flex rounded-md shadow-xs\">\n <span className=\"-z-10 inline-flex items-center rounded-s-md border border-input bg-background px-3 text-sm text-muted-foreground\">\n https://\n </span>\n <Input\n id={`${id}-website`}\n className=\"-ms-px rounded-s-none shadow-none\"\n placeholder=\"yourwebsite.com\"\n defaultValue=\"www.connorlove.com\"\n type=\"text\"\n />\n </div>\n </div>\n <div className=\"*:not-first:mt-2\">\n <Label htmlFor={`${id}-bio`}>Biography</Label>\n <Textarea\n id={`${id}-bio`}\n placeholder=\"Write a few sentences about yourself\"\n defaultValue={value}\n maxLength={maxLength}\n onChange={handleChange}\n aria-describedby={`${id}-description`}\n />\n <p\n id={`${id}-description`}\n className=\"mt-2 text-right text-xs text-muted-foreground\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <span className=\"tabular-nums\">{limit - characterCount}</span>{\" \"}\n characters left\n </p>\n </div>\n </form>\n </div>\n </div>\n <DialogFooter className=\"border-t px-6 py-4\">\n <DialogClose asChild>\n <Button type=\"button\" variant=\"outline\">\n Cancel\n </Button>\n </DialogClose>\n <DialogClose asChild>\n <Button type=\"button\">Save changes</Button>\n </DialogClose>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n )\n}\n\nfunction ProfileBg() {\n const [{ files }, { removeFile, openFileDialog, getInputProps }] =\n useFileUpload({\n accept: \"image/*\",\n initialFiles: initialBgImage,\n })\n\n const currentImage = files[0]?.preview || null\n\n return (\n <div className=\"h-32\">\n <div className=\"relative flex size-full items-center justify-center overflow-hidden bg-muted\">\n {currentImage && (\n <img\n className=\"size-full object-cover\"\n src={currentImage}\n alt={\n files[0]?.preview\n ? \"Preview of uploaded image\"\n : \"Default profile background\"\n }\n width={512}\n height={96}\n />\n )}\n <div className=\"absolute inset-0 flex items-center justify-center gap-2\">\n <button\n type=\"button\"\n className=\"z-50 flex size-10 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\"\n onClick={openFileDialog}\n aria-label={currentImage ? \"Change image\" : \"Upload image\"}\n >\n <ImagePlusIcon size={16} aria-hidden=\"true\" />\n </button>\n {currentImage && (\n <button\n type=\"button\"\n className=\"z-50 flex size-10 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\"\n onClick={() => removeFile(files[0]?.id)}\n aria-label=\"Remove image\"\n >\n <XIcon size={16} aria-hidden=\"true\" />\n </button>\n )}\n </div>\n </div>\n <input\n {...getInputProps()}\n className=\"sr-only\"\n aria-label=\"Upload image file\"\n />\n </div>\n )\n}\n\nfunction Avatar() {\n const [{ files }, { openFileDialog, getInputProps }] = useFileUpload({\n accept: \"image/*\",\n initialFiles: initialAvatarImage,\n })\n\n const currentImage = files[0]?.preview || null\n\n return (\n <div className=\"-mt-10 px-6\">\n <div className=\"relative flex size-20 items-center justify-center overflow-hidden rounded-full border-4 border-background bg-muted shadow-xs shadow-black/10\">\n {currentImage && (\n <img\n src={currentImage}\n className=\"size-full object-cover\"\n width={80}\n height={80}\n alt=\"Profile image\"\n />\n )}\n <button\n type=\"button\"\n className=\"absolute flex size-8 cursor-pointer items-center justify-center rounded-full bg-black/60 text-white transition-[color,box-shadow] outline-none hover:bg-black/80 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\"\n onClick={openFileDialog}\n aria-label=\"Change profile picture\"\n >\n <ImagePlusIcon size={16} aria-hidden=\"true\" />\n </button>\n <input\n {...getInputProps()}\n className=\"sr-only\"\n aria-label=\"Upload profile picture\"\n />\n </div>\n </div>\n )\n}\n",
|
|
16
|
+
"type": "registry:component"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"path": "registry/default/hooks/use-character-limit.ts",
|
|
20
|
+
"content": "\"use client\"\n\nimport { ChangeEvent, useState } from \"react\"\n\ntype UseCharacterLimitProps = {\n maxLength: number\n initialValue?: string\n}\n\nexport function useCharacterLimit({\n maxLength,\n initialValue = \"\",\n}: UseCharacterLimitProps) {\n const [value, setValue] = useState(initialValue)\n const [characterCount, setCharacterCount] = useState(initialValue.length)\n\n const handleChange = (\n e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>\n ) => {\n const newValue = e.target.value\n if (newValue.length <= maxLength) {\n setValue(newValue)\n setCharacterCount(newValue.length)\n }\n }\n\n return {\n value,\n characterCount,\n handleChange,\n maxLength,\n }\n}\n",
|
|
21
|
+
"type": "registry:hook"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"path": "registry/default/hooks/use-file-upload.ts",
|
|
25
|
+
"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",
|
|
26
|
+
"type": "registry:hook"
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
"meta": {
|
|
30
|
+
"tags": [
|
|
31
|
+
"dialog",
|
|
32
|
+
"modal",
|
|
33
|
+
"user",
|
|
34
|
+
"profile",
|
|
35
|
+
"image",
|
|
36
|
+
"avatar",
|
|
37
|
+
"form",
|
|
38
|
+
"radix"
|
|
39
|
+
],
|
|
40
|
+
"style": 1
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-332",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/button.json",
|
|
7
|
+
"https://loveui.dev/building-blocks/r/dialog.json"
|
|
8
|
+
],
|
|
9
|
+
"files": [
|
|
10
|
+
{
|
|
11
|
+
"path": "registry/default/components/comp-332.tsx",
|
|
12
|
+
"content": "\"use client\"\nimport { useState } from \"react\"\nimport { ArrowRightIcon } from \"lucide-react\"\n\nimport { cn } from \"@/registry/building-blocks/default/lib/utils\"\nimport { Button } from \"@/registry/building-blocks/default/ui/button\"\nimport {\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n DialogTrigger,\n} from \"@/registry/building-blocks/default/ui/dialog\"\n\nexport default function Component() {\n const [step, setStep] = useState(1)\n\n const stepContent = [\n {\n title: \"Welcome to loveui\",\n description:\n \"Discover a powerful collection of components designed to enhance your development workflow.\",\n },\n {\n title: \"Customizable Components\",\n description:\n \"Each component is fully customizable and built with modern web standards in mind.\",\n },\n {\n title: \"Ready to Start?\",\n description:\n \"Begin building amazing interfaces with our comprehensive component library.\",\n },\n {\n title: \"Get Support\",\n description:\n \"Access our extensive documentation and community resources to make the most of loveui.\",\n },\n ]\n\n const totalSteps = stepContent.length\n\n const handleContinue = () => {\n if (step < totalSteps) {\n setStep(step + 1)\n }\n }\n\n return (\n <Dialog\n onOpenChange={(open) => {\n if (open) setStep(1)\n }}\n >\n <DialogTrigger asChild>\n <Button variant=\"outline\">Onboarding</Button>\n </DialogTrigger>\n <DialogContent className=\"gap-0 p-0 [&>button:last-child]:text-white\">\n <div className=\"p-2\">\n <img\n className=\"w-full rounded-md\"\n src={assetPath(\"/building-blocks/dialog-content.png\")}\n width={382}\n height={216}\n alt=\"dialog\"\n />\n </div>\n <div className=\"space-y-6 px-6 pt-3 pb-6\">\n <DialogHeader>\n <DialogTitle>{stepContent[step - 1].title}</DialogTitle>\n <DialogDescription>\n {stepContent[step - 1].description}\n </DialogDescription>\n </DialogHeader>\n <div className=\"flex flex-col justify-between gap-4 sm:flex-row sm:items-center\">\n <div className=\"flex justify-center space-x-1.5 max-sm:order-1\">\n {[...Array(totalSteps)].map((_, index) => (\n <div\n key={index}\n className={cn(\n \"size-1.5 rounded-full bg-primary\",\n index + 1 === step ? \"bg-primary\" : \"opacity-20\"\n )}\n />\n ))}\n </div>\n <DialogFooter>\n <DialogClose asChild>\n <Button type=\"button\" variant=\"ghost\">\n Skip\n </Button>\n </DialogClose>\n {step < totalSteps ? (\n <Button\n className=\"group\"\n type=\"button\"\n onClick={handleContinue}\n >\n Next\n <ArrowRightIcon\n className=\"-me-1 opacity-60 transition-transform group-hover:translate-x-0.5\"\n size={16}\n aria-hidden=\"true\"\n />\n </Button>\n ) : (\n <DialogClose asChild>\n <Button type=\"button\">Okay</Button>\n </DialogClose>\n )}\n </DialogFooter>\n </div>\n </div>\n </DialogContent>\n </Dialog>\n )\n}\n",
|
|
13
|
+
"type": "registry:component"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"meta": {
|
|
17
|
+
"tags": [
|
|
18
|
+
"dialog",
|
|
19
|
+
"modal",
|
|
20
|
+
"onboarding",
|
|
21
|
+
"radix"
|
|
22
|
+
],
|
|
23
|
+
"style": 1
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-333",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/command.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-333.tsx",
|
|
11
|
+
"content": "\"use client\"\n\nimport * as React from \"react\"\nimport {\n ArrowUpRightIcon,\n CircleFadingPlusIcon,\n FileInputIcon,\n FolderPlusIcon,\n SearchIcon,\n} from \"lucide-react\"\n\nimport {\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n CommandSeparator,\n CommandShortcut,\n} from \"@/registry/building-blocks/default/ui/command\"\n\nexport default function Component() {\n const [open, setOpen] = React.useState(false)\n\n React.useEffect(() => {\n const down = (e: KeyboardEvent) => {\n if (e.key === \"k\" && (e.metaKey || e.ctrlKey)) {\n e.preventDefault()\n setOpen((open) => !open)\n }\n }\n\n document.addEventListener(\"keydown\", down)\n return () => document.removeEventListener(\"keydown\", down)\n }, [])\n\n return (\n <>\n <button\n className=\"inline-flex h-9 w-fit rounded-md border border-input bg-background px-3 py-2 text-sm text-foreground shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground/70 focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\"\n onClick={() => setOpen(true)}\n >\n <span className=\"flex grow items-center\">\n <SearchIcon\n className=\"-ms-1 me-3 text-muted-foreground/80\"\n size={16}\n aria-hidden=\"true\"\n />\n <span className=\"font-normal text-muted-foreground/70\">Search</span>\n </span>\n <kbd className=\"ms-12 -me-1 inline-flex h-5 max-h-full items-center rounded border bg-background px-1 font-[inherit] text-[0.625rem] font-medium text-muted-foreground/70\">\n ⌘K\n </kbd>\n </button>\n <CommandDialog open={open} onOpenChange={setOpen}>\n <CommandInput placeholder=\"Type a command or search...\" />\n <CommandList>\n <CommandEmpty>No results found.</CommandEmpty>\n <CommandGroup heading=\"Quick start\">\n <CommandItem>\n <FolderPlusIcon\n size={16}\n className=\"opacity-60\"\n aria-hidden=\"true\"\n />\n <span>New folder</span>\n <CommandShortcut className=\"justify-center\">⌘N</CommandShortcut>\n </CommandItem>\n <CommandItem>\n <FileInputIcon\n size={16}\n className=\"opacity-60\"\n aria-hidden=\"true\"\n />\n <span>Import document</span>\n <CommandShortcut className=\"justify-center\">⌘I</CommandShortcut>\n </CommandItem>\n <CommandItem>\n <CircleFadingPlusIcon\n size={16}\n className=\"opacity-60\"\n aria-hidden=\"true\"\n />\n <span>Add block</span>\n <CommandShortcut className=\"justify-center\">⌘B</CommandShortcut>\n </CommandItem>\n </CommandGroup>\n <CommandSeparator />\n <CommandGroup heading=\"Navigation\">\n <CommandItem>\n <ArrowUpRightIcon\n size={16}\n className=\"opacity-60\"\n aria-hidden=\"true\"\n />\n <span>Go to dashboard</span>\n </CommandItem>\n <CommandItem>\n <ArrowUpRightIcon\n size={16}\n className=\"opacity-60\"\n aria-hidden=\"true\"\n />\n <span>Go to apps</span>\n </CommandItem>\n <CommandItem>\n <ArrowUpRightIcon\n size={16}\n className=\"opacity-60\"\n aria-hidden=\"true\"\n />\n <span>Go to connections</span>\n </CommandItem>\n </CommandGroup>\n </CommandList>\n </CommandDialog>\n </>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"dialog",
|
|
18
|
+
"modal",
|
|
19
|
+
"command",
|
|
20
|
+
"combobox",
|
|
21
|
+
"popover",
|
|
22
|
+
"search",
|
|
23
|
+
"radix",
|
|
24
|
+
"autocomplete",
|
|
25
|
+
"radix"
|
|
26
|
+
],
|
|
27
|
+
"style": 1
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-334",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/accordion.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-334.tsx",
|
|
11
|
+
"content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/registry/building-blocks/default/ui/accordion\"\n\nconst items = [\n {\n id: \"1\",\n title: \"What makes loveui different?\",\n content:\n \"loveui focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\",\n },\n {\n id: \"2\",\n title: \"How can I customize the components?\",\n content:\n \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\",\n },\n {\n id: \"3\",\n title: \"Is loveui optimized for performance?\",\n content:\n \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\",\n },\n {\n id: \"4\",\n title: \"How accessible are the components?\",\n content:\n \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\",\n },\n]\n\nexport default function Component() {\n return (\n <div className=\"space-y-4\">\n <h2 className=\"text-xl font-bold\">W/ chevron</h2>\n <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n {items.map((item) => (\n <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n <AccordionTrigger className=\"py-2 text-[15px] leading-6 hover:no-underline\">\n {item.title}\n </AccordionTrigger>\n <AccordionContent className=\"pb-2 text-muted-foreground\">\n {item.content}\n </AccordionContent>\n </AccordionItem>\n ))}\n </Accordion>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"accordion",
|
|
18
|
+
"radix"
|
|
19
|
+
],
|
|
20
|
+
"colSpan": 2
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-335",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/accordion.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-335.tsx",
|
|
11
|
+
"content": "import { PlusIcon } from \"lucide-react\"\nimport { Accordion as AccordionPrimitive } from \"radix-ui\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n} from \"@/registry/building-blocks/default/ui/accordion\"\n\nconst items = [\n {\n id: \"1\",\n title: \"What makes loveui different?\",\n content:\n \"loveui focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\",\n },\n {\n id: \"2\",\n title: \"How can I customize the components?\",\n content:\n \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\",\n },\n {\n id: \"3\",\n title: \"Is loveui optimized for performance?\",\n content:\n \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\",\n },\n {\n id: \"4\",\n title: \"How accessible are the components?\",\n content:\n \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\",\n },\n]\n\nexport default function Component() {\n return (\n <div className=\"space-y-4\">\n <h2 className=\"text-xl font-bold\">W/ plus-minus</h2>\n <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n {items.map((item) => (\n <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger className=\"flex flex-1 items-center justify-between gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">\n {item.title}\n <PlusIcon\n size={16}\n className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n aria-hidden=\"true\"\n />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n <AccordionContent className=\"pb-2 text-muted-foreground\">\n {item.content}\n </AccordionContent>\n </AccordionItem>\n ))}\n </Accordion>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"accordion",
|
|
18
|
+
"radix"
|
|
19
|
+
],
|
|
20
|
+
"colSpan": 2
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-336",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/accordion.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-336.tsx",
|
|
11
|
+
"content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/registry/building-blocks/default/ui/accordion\"\n\nconst items = [\n {\n id: \"1\",\n title: \"What makes loveui different?\",\n content:\n \"loveui focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\",\n },\n {\n id: \"2\",\n title: \"How can I customize the components?\",\n content:\n \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\",\n },\n {\n id: \"3\",\n title: \"Is loveui optimized for performance?\",\n content:\n \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\",\n },\n {\n id: \"4\",\n title: \"How accessible are the components?\",\n content:\n \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\",\n },\n]\n\nexport default function Component() {\n return (\n <div className=\"space-y-4\">\n <h2 className=\"text-xl font-bold\">W/ left chevron</h2>\n <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n {items.map((item) => (\n <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n <AccordionTrigger className=\"justify-start gap-3 py-2 text-[15px] leading-6 hover:no-underline [&>svg]:-order-1\">\n {item.title}\n </AccordionTrigger>\n <AccordionContent className=\"ps-7 pb-2 text-muted-foreground\">\n {item.content}\n </AccordionContent>\n </AccordionItem>\n ))}\n </Accordion>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"accordion",
|
|
18
|
+
"radix"
|
|
19
|
+
],
|
|
20
|
+
"colSpan": 2
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-337",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/accordion.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-337.tsx",
|
|
11
|
+
"content": "import { PlusIcon } from \"lucide-react\"\nimport { Accordion as AccordionPrimitive } from \"radix-ui\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n} from \"@/registry/building-blocks/default/ui/accordion\"\n\nconst items = [\n {\n id: \"1\",\n title: \"What makes loveui different?\",\n content:\n \"loveui focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\",\n },\n {\n id: \"2\",\n title: \"How can I customize the components?\",\n content:\n \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\",\n },\n {\n id: \"3\",\n title: \"Is loveui optimized for performance?\",\n content:\n \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\",\n },\n {\n id: \"4\",\n title: \"How accessible are the components?\",\n content:\n \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\",\n },\n]\n\nexport default function Component() {\n return (\n <div className=\"space-y-4\">\n <h2 className=\"text-xl font-bold\">W/ left plus-minus</h2>\n <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n {items.map((item) => (\n <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger className=\"flex flex-1 items-center gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&>svg]:-order-1 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">\n {item.title}\n <PlusIcon\n size={16}\n className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n aria-hidden=\"true\"\n />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n <AccordionContent className=\"ps-7 pb-2 text-muted-foreground\">\n {item.content}\n </AccordionContent>\n </AccordionItem>\n ))}\n </Accordion>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"accordion",
|
|
18
|
+
"radix"
|
|
19
|
+
],
|
|
20
|
+
"colSpan": 2
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-338",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/accordion.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-338.tsx",
|
|
11
|
+
"content": "import { AtSignIcon, CommandIcon, EclipseIcon, ZapIcon } from \"lucide-react\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/registry/building-blocks/default/ui/accordion\"\n\nconst items = [\n {\n id: \"1\",\n icon: CommandIcon,\n title: \"What makes loveui different?\",\n content:\n \"loveui focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\",\n },\n {\n id: \"2\",\n icon: EclipseIcon,\n title: \"How can I customize the components?\",\n content:\n \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\",\n },\n {\n id: \"3\",\n icon: ZapIcon,\n title: \"Is loveui optimized for performance?\",\n content:\n \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\",\n },\n {\n id: \"4\",\n icon: AtSignIcon,\n title: \"How accessible are the components?\",\n content:\n \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\",\n },\n]\n\nexport default function Component() {\n return (\n <div className=\"space-y-4\">\n <h2 className=\"text-xl font-bold\">W/ icon and chevron</h2>\n <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n {items.map((item) => (\n <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n <AccordionTrigger className=\"py-2 text-[15px] leading-6 hover:no-underline\">\n <span className=\"flex items-center gap-3\">\n <item.icon\n size={16}\n className=\"shrink-0 opacity-60\"\n aria-hidden=\"true\"\n />\n <span>{item.title}</span>\n </span>\n </AccordionTrigger>\n <AccordionContent className=\"ps-7 pb-2 text-muted-foreground\">\n {item.content}\n </AccordionContent>\n </AccordionItem>\n ))}\n </Accordion>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"accordion",
|
|
18
|
+
"radix"
|
|
19
|
+
],
|
|
20
|
+
"colSpan": 2
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-339",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/accordion.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-339.tsx",
|
|
11
|
+
"content": "import {\n AtSignIcon,\n CommandIcon,\n EclipseIcon,\n PlusIcon,\n ZapIcon,\n} from \"lucide-react\"\nimport { Accordion as AccordionPrimitive } from \"radix-ui\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n} from \"@/registry/building-blocks/default/ui/accordion\"\n\nconst items = [\n {\n id: \"1\",\n icon: CommandIcon,\n title: \"What makes loveui different?\",\n content:\n \"loveui focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\",\n },\n {\n id: \"2\",\n icon: EclipseIcon,\n title: \"How can I customize the components?\",\n content:\n \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\",\n },\n {\n id: \"3\",\n icon: ZapIcon,\n title: \"Is loveui optimized for performance?\",\n content:\n \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\",\n },\n {\n id: \"4\",\n icon: AtSignIcon,\n title: \"How accessible are the components?\",\n content:\n \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\",\n },\n]\n\nexport default function Component() {\n return (\n <div className=\"space-y-4\">\n <h2 className=\"text-xl font-bold\">W/ icon and plus-minus</h2>\n <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n {items.map((item) => (\n <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger className=\"flex flex-1 items-center justify-between gap-4 rounded-md py-2 text-left text-sm text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">\n <span className=\"flex items-center gap-3\">\n <item.icon\n size={16}\n className=\"shrink-0 opacity-60\"\n aria-hidden=\"true\"\n />\n <span>{item.title}</span>\n </span>\n <PlusIcon\n size={16}\n className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n aria-hidden=\"true\"\n />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n <AccordionContent className=\"ps-7 pb-2 text-muted-foreground\">\n {item.content}\n </AccordionContent>\n </AccordionItem>\n ))}\n </Accordion>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"accordion",
|
|
18
|
+
"radix"
|
|
19
|
+
],
|
|
20
|
+
"colSpan": 2
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-34",
|
|
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-34.tsx",
|
|
12
|
+
"content": "\"use client\"\n\nimport { useId } from \"react\"\n\nimport { useCharacterLimit } from \"@/registry/building-blocks/default/hooks/use-character-limit\"\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 const maxLength = 50\n const {\n value,\n characterCount,\n handleChange,\n maxLength: limit,\n } = useCharacterLimit({ maxLength })\n\n return (\n <div className=\"*:not-first:mt-2\">\n <Label htmlFor={id}>Input with character limit</Label>\n <div className=\"relative\">\n <Input\n id={id}\n className=\"peer pe-14\"\n type=\"text\"\n value={value}\n maxLength={maxLength}\n onChange={handleChange}\n aria-describedby={`${id}-description`}\n />\n <div\n id={`${id}-description`}\n className=\"pointer-events-none absolute inset-y-0 end-0 flex items-center justify-center pe-3 text-xs text-muted-foreground tabular-nums peer-disabled:opacity-50\"\n aria-live=\"polite\"\n role=\"status\"\n >\n {characterCount}/{limit}\n </div>\n </div>\n </div>\n )\n}\n",
|
|
13
|
+
"type": "registry:component"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"path": "registry/default/hooks/use-character-limit.ts",
|
|
17
|
+
"content": "\"use client\"\n\nimport { ChangeEvent, useState } from \"react\"\n\ntype UseCharacterLimitProps = {\n maxLength: number\n initialValue?: string\n}\n\nexport function useCharacterLimit({\n maxLength,\n initialValue = \"\",\n}: UseCharacterLimitProps) {\n const [value, setValue] = useState(initialValue)\n const [characterCount, setCharacterCount] = useState(initialValue.length)\n\n const handleChange = (\n e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>\n ) => {\n const newValue = e.target.value\n if (newValue.length <= maxLength) {\n setValue(newValue)\n setCharacterCount(newValue.length)\n }\n }\n\n return {\n value,\n characterCount,\n handleChange,\n maxLength,\n }\n}\n",
|
|
18
|
+
"type": "registry:hook"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"meta": {
|
|
22
|
+
"tags": [
|
|
23
|
+
"input",
|
|
24
|
+
"label"
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-340",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/accordion.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-340.tsx",
|
|
11
|
+
"content": "import { ChevronDownIcon } from \"lucide-react\"\nimport { Accordion as AccordionPrimitive } from \"radix-ui\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n} from \"@/registry/building-blocks/default/ui/accordion\"\n\nconst items = [\n {\n id: \"1\",\n title: \"Connected accounts\",\n sub: \"Manage your linked social and work accounts\",\n content:\n \"Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.\",\n },\n {\n id: \"2\",\n title: \"Notifications\",\n sub: \"Customize your notification preferences\",\n content:\n \"Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.\",\n },\n {\n id: \"3\",\n title: \"2-step verification\",\n sub: \"Add an extra layer of security to your account\",\n content:\n \"Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.\",\n },\n {\n id: \"4\",\n title: \"Contact support\",\n sub: \"We're here to help 24/7\",\n content:\n \"Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.\",\n },\n]\n\nexport default function Component() {\n return (\n <div className=\"space-y-4\">\n <h2 className=\"text-xl font-bold\">W/ sub-header and chevron</h2>\n <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n {items.map((item) => (\n <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger className=\"flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [&[data-state=open]>svg]:rotate-180\">\n <span className=\"flex flex-col space-y-1\">\n <span>{item.title}</span>\n {item.sub && (\n <span className=\"text-sm font-normal\">{item.sub}</span>\n )}\n </span>\n <ChevronDownIcon\n size={16}\n className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n aria-hidden=\"true\"\n />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n <AccordionContent className=\"pb-2 text-muted-foreground\">\n {item.content}\n </AccordionContent>\n </AccordionItem>\n ))}\n </Accordion>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"accordion",
|
|
18
|
+
"radix"
|
|
19
|
+
],
|
|
20
|
+
"colSpan": 2
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-341",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/accordion.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-341.tsx",
|
|
11
|
+
"content": "import { PlusIcon } from \"lucide-react\"\nimport { Accordion as AccordionPrimitive } from \"radix-ui\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n} from \"@/registry/building-blocks/default/ui/accordion\"\n\nconst items = [\n {\n id: \"1\",\n title: \"Connected accounts\",\n sub: \"Manage your linked social and work accounts\",\n content:\n \"Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.\",\n },\n {\n id: \"2\",\n title: \"Notifications\",\n sub: \"Customize your notification preferences\",\n content:\n \"Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.\",\n },\n {\n id: \"3\",\n title: \"2-step verification\",\n sub: \"Add an extra layer of security to your account\",\n content:\n \"Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.\",\n },\n {\n id: \"4\",\n title: \"Contact support\",\n sub: \"We're here to help 24/7\",\n content:\n \"Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.\",\n },\n]\n\nexport default function Component() {\n return (\n <div className=\"space-y-4\">\n <h2 className=\"text-xl font-bold\">W/ sub-header and plus-minus</h2>\n <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n {items.map((item) => (\n <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger className=\"flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">\n <span className=\"flex flex-col space-y-1\">\n <span>{item.title}</span>\n {item.sub && (\n <span className=\"text-sm font-normal\">{item.sub}</span>\n )}\n </span>\n <PlusIcon\n size={16}\n className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n aria-hidden=\"true\"\n />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n <AccordionContent className=\"pb-2 text-muted-foreground\">\n {item.content}\n </AccordionContent>\n </AccordionItem>\n ))}\n </Accordion>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"accordion",
|
|
18
|
+
"radix"
|
|
19
|
+
],
|
|
20
|
+
"colSpan": 2
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-342",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/accordion.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-342.tsx",
|
|
11
|
+
"content": "import {\n BellIcon,\n ChevronDownIcon,\n LifeBuoyIcon,\n Link2Icon,\n ShieldCheckIcon,\n} from \"lucide-react\"\nimport { Accordion as AccordionPrimitive } from \"radix-ui\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n} from \"@/registry/building-blocks/default/ui/accordion\"\n\nconst items = [\n {\n id: \"1\",\n icon: Link2Icon,\n title: \"Connected accounts\",\n sub: \"Manage your linked social and work accounts\",\n content:\n \"Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.\",\n },\n {\n id: \"2\",\n icon: BellIcon,\n title: \"Notifications\",\n sub: \"Customize your notification preferences\",\n content:\n \"Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.\",\n },\n {\n id: \"3\",\n icon: ShieldCheckIcon,\n title: \"2-step verification\",\n sub: \"Add an extra layer of security to your account\",\n content:\n \"Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.\",\n },\n {\n id: \"4\",\n icon: LifeBuoyIcon,\n title: \"Contact support\",\n sub: \"We're here to help 24/7\",\n content:\n \"Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.\",\n },\n]\n\nexport default function Component() {\n return (\n <div className=\"space-y-4\">\n <h2 className=\"text-xl font-bold\">W/ icon, sub-header, and chevron</h2>\n <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n {items.map((item) => (\n <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger className=\"flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [&[data-state=open]>svg]:rotate-180\">\n <span className=\"flex items-center gap-3\">\n <span\n className=\"flex size-10 shrink-0 items-center justify-center rounded-full border\"\n aria-hidden=\"true\"\n >\n <item.icon size={16} className=\"opacity-60\" />\n </span>\n <span className=\"flex flex-col space-y-1\">\n <span>{item.title}</span>\n {item.sub && (\n <span className=\"text-sm font-normal\">{item.sub}</span>\n )}\n </span>\n </span>\n <ChevronDownIcon\n size={16}\n className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n aria-hidden=\"true\"\n />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n <AccordionContent className=\"ms-3 ps-10 pb-2 text-muted-foreground\">\n {item.content}\n </AccordionContent>\n </AccordionItem>\n ))}\n </Accordion>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"accordion",
|
|
18
|
+
"radix"
|
|
19
|
+
],
|
|
20
|
+
"colSpan": 2
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-343",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/accordion.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-343.tsx",
|
|
11
|
+
"content": "import {\n BellIcon,\n LifeBuoyIcon,\n Link2Icon,\n PlusIcon,\n ShieldCheckIcon,\n} from \"lucide-react\"\nimport { Accordion as AccordionPrimitive } from \"radix-ui\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n} from \"@/registry/building-blocks/default/ui/accordion\"\n\nconst items = [\n {\n id: \"1\",\n icon: Link2Icon,\n title: \"Connected accounts\",\n sub: \"Manage your linked social and work accounts\",\n content:\n \"Connect your accounts from Google, GitHub, or Microsoft to enable single sign-on and streamline your workflow. Connected accounts can be used for quick login and importing your preferences across platforms. You can revoke access to any connected account at any time.\",\n },\n {\n id: \"2\",\n icon: BellIcon,\n title: \"Notifications\",\n sub: \"Customize your notification preferences\",\n content:\n \"Choose which updates you want to receive. You can get notifications for: security alerts, billing updates, newsletter and product announcements, usage reports, and scheduled maintenance. Notifications can be delivered via email, SMS, or push notifications on your devices.\",\n },\n {\n id: \"3\",\n icon: ShieldCheckIcon,\n title: \"2-step verification\",\n sub: \"Add an extra layer of security to your account\",\n content:\n \"Protect your account with two-factor authentication. You can use authenticator apps like Google Authenticator or Authy, receive SMS codes, or use security keys like YubiKey. We recommend using an authenticator app for the most secure experience.\",\n },\n {\n id: \"4\",\n icon: LifeBuoyIcon,\n title: \"Contact support\",\n sub: \"We're here to help 24/7\",\n content:\n \"Our support team is available around the ClockIcon to assist you. For billing inquiries, technical issues, or general questions, you can reach us through live chat, email at support@example.com, or schedule a call with our technical team. Premium support is available for enterprise customers.\",\n },\n]\n\nexport default function Component() {\n return (\n <div className=\"space-y-4\">\n <h2 className=\"text-xl font-bold\">W/ icon, sub-header, and plus-minus</h2>\n <Accordion type=\"single\" collapsible className=\"w-full\" defaultValue=\"3\">\n {items.map((item) => (\n <AccordionItem value={item.id} key={item.id} className=\"py-2\">\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger className=\"flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">\n <span className=\"flex items-center gap-3\">\n <span\n className=\"flex size-10 shrink-0 items-center justify-center rounded-full border\"\n aria-hidden=\"true\"\n >\n <item.icon size={16} className=\"opacity-60\" />\n </span>\n <span className=\"flex flex-col space-y-1\">\n <span>{item.title}</span>\n {item.sub && (\n <span className=\"text-sm font-normal\">{item.sub}</span>\n )}\n </span>\n </span>\n <PlusIcon\n size={16}\n className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n aria-hidden=\"true\"\n />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n <AccordionContent className=\"ms-3 ps-10 pb-2 text-muted-foreground\">\n {item.content}\n </AccordionContent>\n </AccordionItem>\n ))}\n </Accordion>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"accordion",
|
|
18
|
+
"radix"
|
|
19
|
+
],
|
|
20
|
+
"colSpan": 2
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-344",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/accordion.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-344.tsx",
|
|
11
|
+
"content": "import {\n Accordion,\n AccordionContent,\n AccordionItem,\n AccordionTrigger,\n} from \"@/registry/building-blocks/default/ui/accordion\"\n\nconst items = [\n {\n id: \"1\",\n title: \"What makes loveui different?\",\n content:\n \"loveui focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\",\n },\n {\n id: \"2\",\n title: \"How can I customize the components?\",\n content:\n \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\",\n },\n {\n id: \"3\",\n title: \"Is loveui optimized for performance?\",\n content:\n \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\",\n },\n {\n id: \"4\",\n title: \"How accessible are the components?\",\n content:\n \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\",\n },\n]\n\nexport default function Component() {\n return (\n <div className=\"space-y-4\">\n <h2 className=\"text-xl font-bold\">Tabs w/ chevron</h2>\n <Accordion\n type=\"single\"\n collapsible\n className=\"w-full space-y-2\"\n defaultValue=\"3\"\n >\n {items.map((item) => (\n <AccordionItem\n value={item.id}\n key={item.id}\n className=\"rounded-md border bg-background px-4 py-1 outline-none last:border-b has-focus-visible:border-ring has-focus-visible:ring-[3px] has-focus-visible:ring-ring/50\"\n >\n <AccordionTrigger className=\"py-2 text-[15px] leading-6 hover:no-underline focus-visible:ring-0\">\n {item.title}\n </AccordionTrigger>\n <AccordionContent className=\"pb-2 text-muted-foreground\">\n {item.content}\n </AccordionContent>\n </AccordionItem>\n ))}\n </Accordion>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"accordion",
|
|
18
|
+
"radix"
|
|
19
|
+
],
|
|
20
|
+
"colSpan": 2
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
|
|
3
|
+
"name": "comp-345",
|
|
4
|
+
"type": "registry:component",
|
|
5
|
+
"registryDependencies": [
|
|
6
|
+
"https://loveui.dev/building-blocks/r/accordion.json"
|
|
7
|
+
],
|
|
8
|
+
"files": [
|
|
9
|
+
{
|
|
10
|
+
"path": "registry/default/components/comp-345.tsx",
|
|
11
|
+
"content": "import { PlusIcon } from \"lucide-react\"\nimport { Accordion as AccordionPrimitive } from \"radix-ui\"\n\nimport {\n Accordion,\n AccordionContent,\n AccordionItem,\n} from \"@/registry/building-blocks/default/ui/accordion\"\n\nconst items = [\n {\n id: \"1\",\n title: \"What makes loveui different?\",\n content:\n \"loveui focuses on developer experience and performance. Built with TypeScript, it offers excellent type safety, follows accessibility standards, and provides comprehensive documentation with regular updates.\",\n },\n {\n id: \"2\",\n title: \"How can I customize the components?\",\n content:\n \"Use our CSS variables for global styling, or className and style props for component-specific changes. We support CSS modules, Tailwind, and dark mode out of the box.\",\n },\n {\n id: \"3\",\n title: \"Is loveui optimized for performance?\",\n content:\n \"Yes, with tree-shaking, code splitting, and minimal runtime overhead. Most components are under 5KB gzipped.\",\n },\n {\n id: \"4\",\n title: \"How accessible are the components?\",\n content:\n \"All components follow WAI-ARIA standards, featuring proper ARIA attributes, keyboard navigation, and screen reader support. Regular testing ensures compatibility with NVDA, VoiceOver, and JAWS.\",\n },\n]\n\nexport default function Component() {\n return (\n <div className=\"space-y-4\">\n <h2 className=\"text-xl font-bold\">Tabs w/ plus-minus</h2>\n <Accordion\n type=\"single\"\n collapsible\n className=\"w-full space-y-2\"\n defaultValue=\"3\"\n >\n {items.map((item) => (\n <AccordionItem\n value={item.id}\n key={item.id}\n className=\"rounded-md border bg-background px-4 py-1 outline-none last:border-b has-focus-visible:border-ring has-focus-visible:ring-[3px] has-focus-visible:ring-ring/50\"\n >\n <AccordionPrimitive.Header className=\"flex\">\n <AccordionPrimitive.Trigger className=\"ocus-visible:ring-0 flex flex-1 items-center justify-between rounded-md py-2 text-left text-[15px] leading-6 font-semibold transition-all outline-none [&>svg>path:last-child]:origin-center [&>svg>path:last-child]:transition-all [&>svg>path:last-child]:duration-200 [&[data-state=open]>svg]:rotate-180 [&[data-state=open]>svg>path:last-child]:rotate-90 [&[data-state=open]>svg>path:last-child]:opacity-0\">\n {item.title}\n <PlusIcon\n size={16}\n className=\"pointer-events-none shrink-0 opacity-60 transition-transform duration-200\"\n aria-hidden=\"true\"\n />\n </AccordionPrimitive.Trigger>\n </AccordionPrimitive.Header>\n <AccordionContent className=\"pb-2 text-muted-foreground\">\n {item.content}\n </AccordionContent>\n </AccordionItem>\n ))}\n </Accordion>\n </div>\n )\n}\n",
|
|
12
|
+
"type": "registry:component"
|
|
13
|
+
}
|
|
14
|
+
],
|
|
15
|
+
"meta": {
|
|
16
|
+
"tags": [
|
|
17
|
+
"accordion",
|
|
18
|
+
"radix"
|
|
19
|
+
],
|
|
20
|
+
"colSpan": 2
|
|
21
|
+
}
|
|
22
|
+
}
|