Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/shiny-cats-kneel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@clerk/clerk-js': patch
'@clerk/types': patch
---

Remove deprecated `hideSlug` in favor of `organizationSettings.slug.disabled` setting
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,6 @@ type CreateOrganizationFormProps = {
headerTitle?: LocalizationKey;
headerSubtitle?: LocalizationKey;
};
/**
* @deprecated
* This prop will be removed in a future version.
* Configure whether organization slug is enabled via the Clerk Dashboard under Organization Settings.
*/
hideSlug?: boolean;
};

export const CreateOrganizationForm = withCardStateProvider((props: CreateOrganizationFormProps) => {
Expand Down Expand Up @@ -70,7 +64,7 @@ export const CreateOrganizationForm = withCardStateProvider((props: CreateOrgani
const canSubmit = dataChanged;

// Environment setting takes precedence over prop
const organizationSlugEnabled = !organizationSettings.slug.disabled && !props.hideSlug;
const organizationSlugEnabled = !organizationSettings.slug.disabled;

const onSubmit = async (e: React.FormEvent) => {
e.preventDefault();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { CreateOrganizationForm } from './CreateOrganizationForm';
export const CreateOrganizationPage = withCardStateProvider(() => {
const { closeCreateOrganization } = useClerk();

const { mode, navigateAfterCreateOrganization, skipInvitationScreen, hideSlug } = useCreateOrganizationContext();
const { mode, navigateAfterCreateOrganization, skipInvitationScreen } = useCreateOrganizationContext();
const card = useCardState();
const { showDevModeNotice } = useDevMode();

Expand All @@ -33,7 +33,6 @@ export const CreateOrganizationPage = withCardStateProvider(() => {
closeCreateOrganization();
}
}}
hideSlug={hideSlug}
/>
</Card.Content>
<Card.Footer />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,40 +80,6 @@ describe('CreateOrganization', () => {
expect(getByRole('heading', { name: 'Create organization', level: 1 })).toBeInTheDocument();
});

describe('with `hideSlug` prop', () => {
it('renders component without slug field', async () => {
const { wrapper, fixtures, props } = await createFixtures(f => {
f.withOrganizations();
f.withUser({
email_addresses: ['test@clerk.com'],
});
});

fixtures.clerk.createOrganization.mockReturnValue(
Promise.resolve(
getCreatedOrg({
maxAllowedMemberships: 1,
slug: 'new-org-1722578361',
}),
),
);

props.setProps({ hideSlug: true });
const { userEvent, getByRole, queryByText, queryByLabelText, getByLabelText } = render(<CreateOrganization />, {
wrapper,
});

expect(queryByLabelText(/Slug/i)).not.toBeInTheDocument();

await userEvent.type(getByLabelText(/Name/i), 'new org');
await userEvent.click(getByRole('button', { name: /create organization/i }));

await waitFor(() => {
expect(queryByText(/Invite new members/i)).toBeInTheDocument();
});
});
});

describe('with organization slug configured on environment', () => {
it('when disabled, renders component without slug field', async () => {
const { wrapper, fixtures } = await createFixtures(f => {
Expand Down Expand Up @@ -178,72 +144,6 @@ describe('CreateOrganization', () => {
expect(queryByText(/Invite new members/i)).toBeInTheDocument();
});
});

it('when enabled and `hideSlug` prop is passed, renders component without slug field', async () => {
const { wrapper, fixtures, props } = await createFixtures(f => {
f.withOrganizations();
f.withOrganizationSlug(true);
f.withUser({
email_addresses: ['test@clerk.com'],
});
});

fixtures.clerk.createOrganization.mockReturnValue(
Promise.resolve(
getCreatedOrg({
maxAllowedMemberships: 1,
slug: 'new-org-1722578361',
}),
),
);

props.setProps({ hideSlug: true });
const { userEvent, getByRole, queryByText, queryByLabelText, getByLabelText } = render(<CreateOrganization />, {
wrapper,
});

expect(queryByLabelText(/Slug/i)).not.toBeInTheDocument();

await userEvent.type(getByLabelText(/Name/i), 'new org');
await userEvent.click(getByRole('button', { name: /create organization/i }));

await waitFor(() => {
expect(queryByText(/Invite new members/i)).toBeInTheDocument();
});
});

it('when disabled and `hideSlug` prop is passed, renders component without slug field', async () => {
const { wrapper, fixtures, props } = await createFixtures(f => {
f.withOrganizations();
f.withOrganizationSlug(false); // Environment disables slug
f.withUser({
email_addresses: ['test@clerk.com'],
});
});

fixtures.clerk.createOrganization.mockReturnValue(
Promise.resolve(
getCreatedOrg({
maxAllowedMemberships: 1,
slug: 'new-org-1722578361',
}),
),
);

props.setProps({ hideSlug: true });
const { userEvent, getByRole, queryByText, queryByLabelText, getByLabelText } = render(<CreateOrganization />, {
wrapper,
});

expect(queryByLabelText(/Slug/i)).not.toBeInTheDocument();

await userEvent.type(getByLabelText(/Name/i), 'new org');
await userEvent.click(getByRole('button', { name: /create organization/i }));

await waitFor(() => {
expect(queryByText(/Invite new members/i)).toBeInTheDocument();
});
});
});

it('skips invitation screen', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export const OrganizationListPage = withCardStateProvider(() => {

const OrganizationListFlows = ({ showListInitially }: { showListInitially: boolean }) => {
const card = useCardState();
const { navigateAfterCreateOrganization, skipInvitationScreen, hideSlug } = useOrganizationListContext();
const { navigateAfterCreateOrganization, skipInvitationScreen } = useOrganizationListContext();
const [isCreateOrganizationFlow, setCreateOrganizationFlow] = useState(!showListInitially);
return (
<>
Expand All @@ -112,7 +112,6 @@ const OrganizationListFlows = ({ showListInitially }: { showListInitially: boole
onCancel={
showListInitially && isCreateOrganizationFlow ? () => setCreateOrganizationFlow(false) : undefined
}
hideSlug={hideSlug}
/>
</Box>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,16 +277,16 @@ describe('OrganizationList', () => {
});
});

it('displays CreateOrganization without slug field', async () => {
const { wrapper, props } = await createFixtures(f => {
it("does not display slug field if it's disabled on environment", async () => {
const { wrapper } = await createFixtures(f => {
f.withOrganizations();
f.withOrganizationSlug(false);
f.withUser({
email_addresses: ['test@clerk.com'],
create_organization_enabled: true,
});
});

props.setProps({ hideSlug: true });
const { findByRole, getByRole, userEvent, queryByLabelText } = render(<OrganizationList />, { wrapper });

await waitFor(async () =>
Expand All @@ -297,6 +297,26 @@ describe('OrganizationList', () => {
expect(queryByLabelText(/Slug/i)).not.toBeInTheDocument();
});

it("display slug field if it's enabled on environment", async () => {
const { wrapper } = await createFixtures(f => {
f.withOrganizations();
f.withOrganizationSlug(true);
f.withUser({
email_addresses: ['test@clerk.com'],
create_organization_enabled: true,
});
});

const { findByRole, getByRole, userEvent, queryByLabelText } = render(<OrganizationList />, { wrapper });

await waitFor(async () =>
expect(await findByRole('menuitem', { name: 'Create organization' })).toBeInTheDocument(),
);
await userEvent.click(getByRole('menuitem', { name: 'Create organization' }));
expect(queryByLabelText(/Name/i)).toBeInTheDocument();
expect(queryByLabelText(/Slug/i)).toBeInTheDocument();
});

it('does not display CreateOrganization within OrganizationList when disabled', async () => {
const { wrapper } = await createFixtures(f => {
f.withOrganizations();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ export const OrganizationSwitcherPopover = React.forwardRef<HTMLDivElement, Orga

organizationProfileProps,
skipInvitationScreen,
hideSlug,
} = useOrganizationSwitcherContext();

const { user } = useUser();
Expand Down Expand Up @@ -86,7 +85,7 @@ export const OrganizationSwitcherPopover = React.forwardRef<HTMLDivElement, Orga
if (createOrganizationMode === 'navigation') {
return navigateCreateOrganization();
}
return openCreateOrganization({ afterCreateOrganizationUrl, skipInvitationScreen, hideSlug });
return openCreateOrganization({ afterCreateOrganizationUrl, skipInvitationScreen });
};

const handleItemClick = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,23 +253,6 @@ describe('OrganizationSwitcher', () => {
expect(fixtures.clerk.openCreateOrganization).toHaveBeenCalled();
});

it('opens create organization without slug field', async () => {
const { wrapper, fixtures, props } = await createFixtures(f => {
f.withOrganizations();
f.withUser({
email_addresses: ['test@clerk.com'],
create_organization_enabled: true,
});
});

props.setProps({ hideSlug: true });
const { getByRole, queryByLabelText, userEvent } = render(<OrganizationSwitcher />, { wrapper });
await userEvent.click(getByRole('button', { name: 'Open organization switcher' }));
await userEvent.click(getByRole('menuitem', { name: 'Create organization' }));
expect(fixtures.clerk.openCreateOrganization).toHaveBeenCalled();
expect(queryByLabelText(/Slug/i)).not.toBeInTheDocument();
});

it('does not display create organization button if permissions not present', async () => {
const { wrapper, props } = await createFixtures(f => {
f.withOrganizations();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ export const useCreateOrganizationContext = () => {
return {
...ctx,
skipInvitationScreen: ctx.skipInvitationScreen || false,
hideSlug: ctx.hideSlug || false,
navigateAfterCreateOrganization,
componentName,
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,6 @@ export const useOrganizationListContext = () => {
...ctx,
afterCreateOrganizationUrl,
skipInvitationScreen: ctx.skipInvitationScreen || false,
hideSlug: ctx.hideSlug || false,
hidePersonal: organizationSettings.forceOrganizationSelection || ctx.hidePersonal || false,
navigateAfterCreateOrganization,
navigateAfterSelectOrganization,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ export const useOrganizationSwitcherContext = () => {
organizationProfileMode: organizationProfileMode || 'modal',
createOrganizationMode: createOrganizationMode || 'modal',
skipInvitationScreen: ctx.skipInvitationScreen || false,
hideSlug: ctx.hideSlug || false,
afterCreateOrganizationUrl,
afterLeaveOrganizationUrl,
navigateOrganizationProfile,
Expand Down
18 changes: 0 additions & 18 deletions packages/types/src/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1562,12 +1562,6 @@ export type CreateOrganizationProps = RoutingOptions & {
* prop of ClerkProvider (if one is provided)
*/
appearance?: CreateOrganizationTheme;
/**
* @deprecated
* This prop will be removed in a future version.
* Configure whether organization slug is enabled via the Clerk Dashboard under Organization Settings.
*/
hideSlug?: boolean;
};

export type CreateOrganizationModalProps = WithoutRouting<CreateOrganizationProps>;
Expand Down Expand Up @@ -1723,12 +1717,6 @@ export type OrganizationSwitcherProps = CreateOrganizationMode &
* the number of max allowed members is equal to 1
*/
skipInvitationScreen?: boolean;
/**
* @deprecated
* This prop will be removed in a future version.
* Configure whether organization slug is enabled via the Clerk Dashboard under Organization Settings.
*/
hideSlug?: boolean;
/**
* Customisation options to fully match the Clerk components to your own brand.
* These options serve as overrides and will be merged with the global `appearance`
Expand Down Expand Up @@ -1784,12 +1772,6 @@ export type OrganizationListProps = {
* @default undefined`
*/
afterSelectPersonalUrl?: ((user: UserResource) => string) | LooseExtractedParams<PrimitiveKeys<UserResource>>;
/**
* @deprecated
* This prop will be removed in a future version.
* Configure whether organization slug is enabled via the Clerk Dashboard under Organization Settings.
*/
hideSlug?: boolean;
};

export type WaitlistProps = {
Expand Down