Skip to content

Commit

Permalink
Merge branch 'main' into feat/theme
Browse files Browse the repository at this point in the history
  • Loading branch information
ruru-m07 authored Sep 19, 2024
2 parents a724607 + bbf4024 commit d6d5330
Show file tree
Hide file tree
Showing 5 changed files with 7 additions and 16 deletions.
4 changes: 0 additions & 4 deletions apps/www/components/selectLargeData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ import {
SelectGroup,
SelectItem,
SelectLabel,
SelectScrollDownButton,
SelectScrollUpButton,
SelectSeparator,
} from "ruru-ui/components/select";

Expand All @@ -22,13 +20,11 @@ const SelectCountries = () => {
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
<SelectSeparator />
<SelectScrollUpButton />
{Array.from({ length: 50 }, (_, index) => (
<SelectItem key={index} value={String(index)}>
Ruru-UI-V{index}
</SelectItem>
))}
<SelectScrollDownButton />
</SelectGroup>
</SelectContent>
</Select>
Expand Down
10 changes: 2 additions & 8 deletions apps/www/content/docs/components/select.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -257,18 +257,16 @@ export function DefaultValueSelect() {
</Tab>
</Tabs>

### ScrollDownButton and ScrollUpButton
### Scrollable

You can add scroll buttons to the `Select` component by using the `SelectScrollDownButton` and `SelectScrollUpButton` components.
When the content in the Select component exceeds the maximum height, it becomes scrollable, adding `ScrollUpButton` and `ScrollDownButton` to help users easily navigate through the options.

<Tabs items={["Preview", "Code"]}>
<Tab className={"flex justify-center"} value="Preview">
<SelectCountries />
</Tab>
<Tab className={"-mt-8"} value="Code">
```tsx
// [!code word:SelectScrollDownButton]
// [!code word:SelectScrollUpButton]
import {
Select,
SelectContent,
Expand All @@ -277,8 +275,6 @@ import {
SelectGroup,
SelectItem,
SelectLabel,
SelectScrollDownButton,
SelectScrollUpButton,
SelectSeparator,
} from "ruru-ui/components/select";

Expand All @@ -293,13 +289,11 @@ const SelectCountries = () => {
<SelectGroup>
<SelectLabel>Fruits</SelectLabel>
<SelectSeparator />
<SelectScrollUpButton />
{Array.from({ length: 50 }, (_, index) => (
<SelectItem key={index} value={String(index)}>
Ruru-UI-V{index}
</SelectItem>
))}
<SelectScrollDownButton />
</SelectGroup>
</SelectContent>
</Select>
Expand Down
2 changes: 1 addition & 1 deletion apps/www/public/registry/components/input.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"files": [
{
"name": "input.tsx",
"content": "\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { EyeClosedIcon, EyeOpenIcon } from \"@radix-ui/react-icons\";\n\nexport interface InputProps\n extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"children\" | \"prefix\" | \"suffix\"\n > {\n \n className?: string;\n \n iclassName?: string;\n \n prefix?: React.ReactNode | string;\n \n suffix?: React.ReactNode | string;\n \n prefixStyling?: boolean;\n \n label?: string;\n \n suffixStyling?: boolean;\n \n error?: string;\n}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n (\n {\n className,\n iclassName,\n prefix,\n suffix,\n prefixStyling = true,\n suffixStyling = true,\n label,\n type,\n error,\n ...props\n },\n ref,\n ) => {\n \n const prefixRef = React.useRef<HTMLDivElement>(null);\n const suffixRef = React.useRef<HTMLDivElement>(null);\n \n const [prefixWidth, setPrefixWidth] = React.useState(0);\n const [suffixWidth, setSuffixWidth] = React.useState(0);\n \n React.useEffect(() => {\n if (prefixRef.current) {\n setPrefixWidth(prefixRef.current.offsetWidth);\n }\n if (suffixRef.current) {\n setSuffixWidth(suffixRef.current.offsetWidth);\n }\n }, [prefix, suffix]);\n\n return (\n <div className={cn(\"relative\", className)}>\n {label && (\n <label\n className={`text-sm ${error ? \"text-[#ff6166]\" : \"text-muted-foreground\"} `}\n htmlFor={props.id}\n >\n {label}\n </label>\n )}\n {prefix && (\n <div\n ref={prefixRef}\n className={cn(\n \"absolute top-0 left-0 h-full flex items-center justify-center pl-2 text-muted-foreground\",\n `${prefixStyling ? \"rounded-l-md\" : \"\"}`,\n )}\n >\n {prefix}\n {prefixStyling && <div className=\"h-[94%] w-px ml-2 bg-border \" />}\n </div>\n )}\n <input\n type={type}\n className={cn(\n \"flex w-full h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-shadow file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:border-primary/75 focus-visible:ring-primary/35 disabled:cursor-not-allowed disabled:opacity-50\",\n iclassName,\n `${error ? \"outline-none ring-2 ring-[#ffe6e6] border-[#ff6166] dark:ring-[#561a1e] focus-visible:dark:ring-primary/35 dark:hover:ring-[#832126] hover:ring-[#f8b9b9]\" : \"\"}`,\n )}\n style={{\n paddingLeft: prefix ? `${prefixWidth + 12}px` : \"0.75rem\",\n paddingRight: suffix ? `${suffixWidth + 12}px` : \"0.75rem\",\n }}\n ref={ref}\n {...props}\n />\n {suffix && (\n <div\n ref={suffixRef}\n className={cn(\n \"absolute top-0 right-0 h-full flex items-center justify-center pr-2 text-muted-foreground\",\n `${suffixStyling ? \"rounded-r-md\" : \"\"}`,\n )}\n >\n {suffixStyling && (\n <div className=\"h-[94%] w-[1px] mr-2 bg-border \" />\n )}\n {suffix}\n </div>\n )}\n {error && (\n <div\n className=\"flex items-center text-sm text-[#ff6166] mt-1\"\n role=\"alert\"\n >\n <svg\n data-testid=\"geist-icon\"\n height=\"16\"\n strokeLinejoin=\"round\"\n viewBox=\"0 0 16 16\"\n width=\"16\"\n style={{ color: \"currentcolor\" }}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M5.30761 1.5L1.5 5.30761L1.5 10.6924L5.30761 14.5H10.6924L14.5 10.6924V5.30761L10.6924 1.5H5.30761ZM5.10051 0C4.83529 0 4.58094 0.105357 4.3934 0.292893L0.292893 4.3934C0.105357 4.58094 0 4.83529 0 5.10051V10.8995C0 11.1647 0.105357 11.4191 0.292894 11.6066L4.3934 15.7071C4.58094 15.8946 4.83529 16 5.10051 16H10.8995C11.1647 16 11.4191 15.8946 11.6066 15.7071L15.7071 11.6066C15.8946 11.4191 16 11.1647 16 10.8995V5.10051C16 4.83529 15.8946 4.58093 15.7071 4.3934L11.6066 0.292893C11.4191 0.105357 11.1647 0 10.8995 0H5.10051ZM8.75 3.75V4.5V8L8.75 8.75H7.25V8V4.5V3.75H8.75ZM8 12C8.55229 12 9 11.5523 9 11C9 10.4477 8.55229 10 8 10C7.44772 10 7 10.4477 7 11C7 11.5523 7.44772 12 8 12Z\"\n fill=\"currentColor\"\n ></path>\n </svg>\n <label className=\"ml-1\" htmlFor=\"error\">\n {error}\n </label>\n </div>\n )}\n </div>\n );\n },\n);\n\nInput.displayName = \"Input\";\n\nexport interface SearchInputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"children\"> {\n \n enablePrefixStyling?: boolean;\n}\n\nconst SearchInput = React.forwardRef<HTMLInputElement, SearchInputProps>(\n ({ enablePrefixStyling = false, ...props }, ref) => {\n return (\n <Input\n type=\"search\"\n prefix={\n <svg\n width=\"15\"\n height=\"15\"\n viewBox=\"0 0 15 15\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M10 6.5C10 8.433 8.433 10 6.5 10C4.567 10 3 8.433 3 6.5C3 4.567 4.567 3 6.5 3C8.433 3 10 4.567 10 6.5ZM9.30884 10.0159C8.53901 10.6318 7.56251 11 6.5 11C4.01472 11 2 8.98528 2 6.5C2 4.01472 4.01472 2 6.5 2C8.98528 2 11 4.01472 11 6.5C11 7.56251 10.6318 8.53901 10.0159 9.30884L12.8536 12.1464C13.0488 12.3417 13.0488 12.6583 12.8536 12.8536C12.6583 13.0488 12.3417 13.0488 12.1464 12.8536L9.30884 10.0159Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n ></path>\n </svg>\n }\n prefixStyling={enablePrefixStyling}\n className={cn(\"rounded-full\", props.className)}\n ref={ref}\n {...props}\n />\n );\n },\n);\n\nSearchInput.displayName = \"SearchInput\";\n\nconst PasswordInput = React.forwardRef<\n HTMLInputElement,\n Omit<InputProps, \"label\" | \"error\">\n>(({ className, ...props }, ref) => {\n const [showPassword, setShowPassword] = React.useState(false);\n\n return (\n <div className=\"relative\">\n <Input\n type={showPassword ? \"text\" : \"password\"}\n className={cn(\"hide-password-toggle\", className)}\n ref={ref}\n {...props}\n />\n <button\n type=\"button\"\n className={\n \"absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent\"\n }\n onClick={() => setShowPassword((prev) => !prev)}\n disabled={props.disabled}\n >\n {showPassword ? (\n <EyeOpenIcon className=\"h-4 w-4\" aria-hidden=\"true\" />\n ) : (\n <EyeClosedIcon className=\"h-4 w-4\" aria-hidden=\"true\" />\n )}\n <span className=\"sr-only\">\n {showPassword ? \"Hide password\" : \"Show password\"}\n </span>\n </button>\n\n {}\n <style>{`\n\t\t\t\t\t.hide-password-toggle::-ms-reveal,\n\t\t\t\t\t.hide-password-toggle::-ms-clear {\n\t\t\t\t\t\tvisibility: hidden;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\tdisplay: none;\n\t\t\t\t\t}\n\t\t\t\t`}</style>\n </div>\n );\n});\nPasswordInput.displayName = \"PasswordInput\";\n\nexport { Input, SearchInput, PasswordInput };\n"
"content": "\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@/utils/cn\";\nimport { EyeClosedIcon, EyeOpenIcon } from \"@radix-ui/react-icons\";\n\nexport interface InputProps\n extends Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"children\" | \"prefix\" | \"suffix\"\n > {\n \n className?: string;\n \n iclassName?: string;\n \n prefix?: React.ReactNode | string;\n \n suffix?: React.ReactNode | string;\n \n prefixStyling?: boolean;\n \n label?: string;\n \n suffixStyling?: boolean;\n \n error?: string;\n}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n (\n {\n className,\n iclassName,\n prefix,\n suffix,\n prefixStyling = true,\n suffixStyling = true,\n label,\n type,\n error,\n ...props\n },\n ref,\n ) => {\n \n const prefixRef = React.useRef<HTMLDivElement>(null);\n const suffixRef = React.useRef<HTMLDivElement>(null);\n \n const [prefixWidth, setPrefixWidth] = React.useState(0);\n const [suffixWidth, setSuffixWidth] = React.useState(0);\n \n React.useEffect(() => {\n if (prefixRef.current) {\n setPrefixWidth(prefixRef.current.offsetWidth);\n }\n if (suffixRef.current) {\n setSuffixWidth(suffixRef.current.offsetWidth);\n }\n }, [prefix, suffix]);\n\n return (\n <div className={cn(\"relative\", className)}>\n {label && (\n <label\n className={`text-sm ${error ? \"text-[#ff6166]\" : \"text-muted-foreground\"} `}\n htmlFor={props.id}\n >\n {label}\n </label>\n )}\n {prefix && (\n <div\n ref={prefixRef}\n className={cn(\n \"absolute top-0 left-0 h-full flex items-center justify-center pl-2 text-muted-foreground\",\n `${prefixStyling ? \"rounded-l-md\" : \"\"}`,\n )}\n >\n {prefix}\n {prefixStyling && <div className=\"h-[94%] w-px ml-2 bg-border \" />}\n </div>\n )}\n <input\n type={type}\n className={cn(\n \"flex w-full h-9 rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-shadow file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:border-primary/75 focus-visible:ring-primary/35 disabled:cursor-not-allowed disabled:opacity-50\",\n iclassName,\n `${error ? \"outline-none ring-2 ring-[#ffe6e6] border-[#ff6166] dark:ring-[#561a1e] focus-visible:dark:ring-primary/35 dark:hover:ring-[#832126] hover:ring-[#f8b9b9]\" : \"\"}`,\n )}\n style={{\n paddingLeft: prefix ? `${prefixWidth + 12}px` : \"0.75rem\",\n paddingRight: suffix ? `${suffixWidth + 12}px` : \"0.75rem\",\n }}\n ref={ref}\n {...props}\n />\n {suffix && (\n <div\n ref={suffixRef}\n className={cn(\n \"absolute top-0 right-0 h-full flex items-center justify-center pr-2 text-muted-foreground\",\n `${suffixStyling ? \"rounded-r-md\" : \"\"}`,\n )}\n >\n {suffixStyling && (\n <div className=\"h-[94%] w-[1px] mr-2 bg-border \" />\n )}\n {suffix}\n </div>\n )}\n {error && (\n <div\n className=\"flex items-center text-sm text-[#ff6166] mt-1\"\n role=\"alert\"\n >\n <svg\n data-testid=\"geist-icon\"\n height=\"16\"\n strokeLinejoin=\"round\"\n viewBox=\"0 0 16 16\"\n width=\"16\"\n style={{ color: \"currentcolor\" }}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M5.30761 1.5L1.5 5.30761L1.5 10.6924L5.30761 14.5H10.6924L14.5 10.6924V5.30761L10.6924 1.5H5.30761ZM5.10051 0C4.83529 0 4.58094 0.105357 4.3934 0.292893L0.292893 4.3934C0.105357 4.58094 0 4.83529 0 5.10051V10.8995C0 11.1647 0.105357 11.4191 0.292894 11.6066L4.3934 15.7071C4.58094 15.8946 4.83529 16 5.10051 16H10.8995C11.1647 16 11.4191 15.8946 11.6066 15.7071L15.7071 11.6066C15.8946 11.4191 16 11.1647 16 10.8995V5.10051C16 4.83529 15.8946 4.58093 15.7071 4.3934L11.6066 0.292893C11.4191 0.105357 11.1647 0 10.8995 0H5.10051ZM8.75 3.75V4.5V8L8.75 8.75H7.25V8V4.5V3.75H8.75ZM8 12C8.55229 12 9 11.5523 9 11C9 10.4477 8.55229 10 8 10C7.44772 10 7 10.4477 7 11C7 11.5523 7.44772 12 8 12Z\"\n fill=\"currentColor\"\n ></path>\n </svg>\n <label className=\"ml-1\" htmlFor=\"error\">\n {error}\n </label>\n </div>\n )}\n </div>\n );\n },\n);\n\nInput.displayName = \"Input\";\n\nexport interface SearchInputProps\n extends Omit<React.InputHTMLAttributes<HTMLInputElement>, \"children\"> {\n \n enablePrefixStyling?: boolean;\n}\n\nconst SearchInput = React.forwardRef<HTMLInputElement, SearchInputProps>(\n ({ enablePrefixStyling = false, ...props }, ref) => {\n return (\n <Input\n type=\"search\"\n prefix={\n <svg\n width=\"15\"\n height=\"15\"\n viewBox=\"0 0 15 15\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n d=\"M10 6.5C10 8.433 8.433 10 6.5 10C4.567 10 3 8.433 3 6.5C3 4.567 4.567 3 6.5 3C8.433 3 10 4.567 10 6.5ZM9.30884 10.0159C8.53901 10.6318 7.56251 11 6.5 11C4.01472 11 2 8.98528 2 6.5C2 4.01472 4.01472 2 6.5 2C8.98528 2 11 4.01472 11 6.5C11 7.56251 10.6318 8.53901 10.0159 9.30884L12.8536 12.1464C13.0488 12.3417 13.0488 12.6583 12.8536 12.8536C12.6583 13.0488 12.3417 13.0488 12.1464 12.8536L9.30884 10.0159Z\"\n fill=\"currentColor\"\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n ></path>\n </svg>\n }\n prefixStyling={enablePrefixStyling}\n className={cn(\"rounded-full\", props.className)}\n ref={ref}\n {...props}\n />\n );\n },\n);\n\nSearchInput.displayName = \"SearchInput\";\n\nconst PasswordInput = React.forwardRef<\n HTMLInputElement,\n Omit<InputProps, \"label\" | \"error\">\n>(({ className, ...props }, ref) => {\n const [showPassword, setShowPassword] = React.useState(false);\n\n return (\n <div className=\"relative\">\n <Input\n type={showPassword ? \"text\" : \"password\"}\n iclassName=\"hide-password-toggle\"\n className={className}\n ref={ref}\n {...props}\n />\n <button\n type=\"button\"\n className={\n \"absolute right-0 top-0 h-full px-3 py-2 hover:bg-transparent\"\n }\n onClick={() => setShowPassword((prev) => !prev)}\n disabled={props.disabled}\n >\n {showPassword ? (\n <EyeOpenIcon className=\"h-4 w-4\" aria-hidden=\"true\" />\n ) : (\n <EyeClosedIcon className=\"h-4 w-4\" aria-hidden=\"true\" />\n )}\n <span className=\"sr-only\">\n {showPassword ? \"Hide password\" : \"Show password\"}\n </span>\n </button>\n\n {}\n <style>{`\n\t\t\t\t\t.hide-password-toggle::-ms-reveal,\n\t\t\t\t\t.hide-password-toggle::-ms-clear {\n\t\t\t\t\t\tvisibility: hidden;\n\t\t\t\t\t\tpointer-events: none;\n\t\t\t\t\t\tdisplay: none;\n\t\t\t\t\t}\n\t\t\t\t`}</style>\n </div>\n );\n});\nPasswordInput.displayName = \"PasswordInput\";\n\nexport { Input, SearchInput, PasswordInput };\n"
}
],
"type": "components:ui"
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/src/components/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,8 @@ const PasswordInput = React.forwardRef<
<div className="relative">
<Input
type={showPassword ? "text" : "password"}
className={cn("hide-password-toggle", className)}
iclassName="hide-password-toggle"
className={className}
ref={ref}
{...props}
/>
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/components/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ const SelectScrollUpButton = React.forwardRef<
<SelectPrimitive.ScrollUpButton
ref={ref}
className={cn(
"flex cursor-default items-center justify-center py-1",
"flex cursor-default items-center justify-center py-1 w-full absolute top-0 bg-popover z-10",
className,
)}
{...props}
Expand All @@ -138,7 +138,7 @@ const SelectScrollDownButton = React.forwardRef<
<SelectPrimitive.ScrollDownButton
ref={ref}
className={cn(
"flex cursor-default items-center justify-center py-1",
"flex cursor-default items-center justify-center py-1 w-full absolute bottom-0 bg-popover z-10",
className,
)}
{...props}
Expand Down

0 comments on commit d6d5330

Please sign in to comment.