chore: Cleanup collection create dialog (#11454)

This commit is contained in:
Tom Moor
2026-02-14 17:39:53 -05:00
committed by GitHub
parent 7824f6b363
commit de69a4e671
3 changed files with 147 additions and 27 deletions
+112
View File
@@ -0,0 +1,112 @@
import * as RadixCollapsible from "@radix-ui/react-collapsible";
import { ExpandedIcon } from "outline-icons";
import * as React from "react";
import styled from "styled-components";
import { s } from "@shared/styles";
interface CollapsibleProps {
/** The label displayed on the trigger button. */
label: React.ReactNode;
/** The content to show/hide inside the collapsible panel. */
children: React.ReactNode;
/** Whether the collapsible is open by default. */
defaultOpen?: boolean;
/** Controlled open state. */
open?: boolean;
/** Callback fired when the open state changes. */
onOpenChange?: (open: boolean) => void;
/** Additional class name for the root element. */
className?: string;
}
/**
* An accessible collapsible section built on Radix UI Collapsible.
* Renders a trigger button with a disclosure chevron and animated content panel.
*
* @param props - component props.
* @returns the collapsible component.
*/
export function Collapsible({
label,
children,
defaultOpen = false,
open,
onOpenChange,
className,
}: CollapsibleProps) {
return (
<RadixCollapsible.Root
defaultOpen={defaultOpen}
open={open}
onOpenChange={onOpenChange}
className={className}
>
<StyledTrigger>
<StyledExpandedIcon aria-hidden="true" />
{label}
</StyledTrigger>
<StyledContent>{children}</StyledContent>
</RadixCollapsible.Root>
);
}
const StyledExpandedIcon = styled(ExpandedIcon)`
flex-shrink: 0;
transition: transform 150ms ease-out;
margin-left: -4px;
`;
const StyledTrigger = styled(RadixCollapsible.Trigger)`
display: flex;
align-items: center;
background: none;
border: none;
padding: 0 0 8px 0;
cursor: var(--pointer);
color: ${s("textTertiary")};
font-size: 14pxte
&:hover {
color: ${s("textSecondary")};
}
&[data-state="closed"] {
${StyledExpandedIcon} {
transform: rotate(-90deg);
}
}
`;
const StyledContent = styled(RadixCollapsible.Content)`
overflow: hidden;
&[data-state="open"] {
animation: slideDown 200ms ease-out;
}
&[data-state="closed"] {
animation: slideUp 200ms ease-out;
}
@keyframes slideDown {
from {
height: 0;
opacity: 0;
}
to {
height: var(--radix-collapsible-content-height);
opacity: 1;
}
}
@keyframes slideUp {
from {
height: var(--radix-collapsible-content-height);
opacity: 1;
}
to {
height: 0;
opacity: 0;
}
}
`;
+34 -27
View File
@@ -13,6 +13,7 @@ import { colorPalette } from "@shared/utils/collections";
import { CollectionValidation } from "@shared/validations";
import type Collection from "~/models/Collection";
import Button from "~/components/Button";
import { Collapsible } from "~/components/Collapsible";
import Input from "~/components/Input";
import { InputSelectPermission } from "~/components/InputSelectPermission";
import { createLazyComponent } from "~/components/LazyLoad";
@@ -144,7 +145,7 @@ export const CollectionForm = observer(function CollectionForm_({
<HStack>
<Input
type="text"
placeholder={t("Name")}
label={t("Name")}
{...register("name", {
required: true,
maxLength: CollectionValidation.maxNameLength,
@@ -189,38 +190,44 @@ export const CollectionForm = observer(function CollectionForm_({
/>
)}
{team.sharing && (
<Controller
control={control}
name="sharing"
render={({ field }) => (
<Switch
id="sharing"
label={t("Public document sharing")}
note={t(
"Allow documents within this collection to be shared publicly on the internet."
{(team.sharing || team.getPreference(TeamPreference.Commenting)) && (
<Collapsible label={t("Advanced options")}>
{team.sharing && (
<Controller
control={control}
name="sharing"
render={({ field }) => (
<Switch
id="sharing"
label={t("Public document sharing")}
note={t(
"Allow documents within this collection to be shared publicly on the internet."
)}
checked={field.value}
onChange={field.onChange}
/>
)}
checked={field.value}
onChange={field.onChange}
/>
)}
/>
)}
{team.getPreference(TeamPreference.Commenting) && (
<Controller
control={control}
name="commenting"
render={({ field }) => (
<Switch
id="commenting"
label={t("Commenting")}
note={t("Allow commenting on documents within this collection.")}
checked={!!field.value}
onChange={field.onChange}
{team.getPreference(TeamPreference.Commenting) && (
<Controller
control={control}
name="commenting"
render={({ field }) => (
<Switch
id="commenting"
label={t("Commenting")}
note={t(
"Allow commenting on documents within this collection."
)}
checked={!!field.value}
onChange={field.onChange}
/>
)}
/>
)}
/>
</Collapsible>
)}
<HStack justify="flex-end">
@@ -197,6 +197,7 @@
"Collections are used to group documents and choose permissions": "Collections are used to group documents and choose permissions",
"Name": "Name",
"The default access for workspace members, you can share with more users or groups later.": "The default access for workspace members, you can share with more users or groups later.",
"Advanced options": "Advanced options",
"Public document sharing": "Public document sharing",
"Allow documents within this collection to be shared publicly on the internet.": "Allow documents within this collection to be shared publicly on the internet.",
"Commenting": "Commenting",