Skip to content

chore(clerk-js): Add API Keys component descriptors #6095

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 113 commits into from
Jun 18, 2025

Conversation

wobsoriano
Copy link
Member

@wobsoriano wobsoriano commented Jun 10, 2025

Description

This PR adds element descriptors to the <APIKeys /> AIO component for customization.

Coverage:

  • Top-level container
  • Header
    • Search input box
      • Search input
    • Add button
  • Table
    • Rows
    • Cells
    • Copy/reveal buttons
    • Spinner
  • Form container
    • name field
    • description field
    • expiration field
    • submit button
  • Revoke modal
    • Input
    • Submit button

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features
    • Enhanced the API Keys management interface with new element descriptors, enabling improved customization and theming of UI components related to API keys.
    • Added default descriptors for table components to improve UI consistency and customization.
  • Style
    • Added structured metadata to API Keys UI elements, supporting more granular styling and accessibility.
  • Chores
    • Minor formatting improvements for consistency.
    • Updated bundle size limit for UI common files.

Copy link

pkg-pr-new bot commented Jun 17, 2025

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@6095

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@6095

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@6095

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@6095

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@6095

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@6095

@clerk/elements

npm i https://pkg.pr.new/@clerk/elements@6095

@clerk/clerk-expo

npm i https://pkg.pr.new/@clerk/clerk-expo@6095

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@6095

@clerk/express

npm i https://pkg.pr.new/@clerk/express@6095

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@6095

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@6095

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@6095

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@6095

@clerk/clerk-react

npm i https://pkg.pr.new/@clerk/clerk-react@6095

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@6095

@clerk/remix

npm i https://pkg.pr.new/@clerk/remix@6095

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@6095

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@6095

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@6095

@clerk/themes

npm i https://pkg.pr.new/@clerk/themes@6095

@clerk/types

npm i https://pkg.pr.new/@clerk/types@6095

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@6095

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@6095

commit: 8e38cd6

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (6)
packages/clerk-js/src/ui/components/ApiKeys/CreateApiKeyForm.tsx (1)

3-3: Import list is getting long – consider multi-line formatting

The utilities import now spans many identifiers; for readability consider:

-import { Box, Button, Col, descriptors, Flex, FormLabel, localizationKeys, Text } from '@/ui/customizables';
+import {
+  Box,
+  Button,
+  Col,
+  descriptors,
+  Flex,
+  FormLabel,
+  localizationKeys,
+  Text,
+} from '@/ui/customizables';
packages/clerk-js/src/ui/customizables/elementDescriptors.ts (1)

462-482: Manual list maintenance is error-prone

The API-keys keys are appended in three places:

  1. ElementsConfig
  2. APPEARANCE_KEYS (here)
  3. Component usage

A single source of truth (e.g. generating APPEARANCE_KEYS from ElementsConfig at build-time) would prevent future omissions & cut review overhead.

packages/clerk-js/src/ui/components/ApiKeys/RevokeAPIKeyConfirmationModal.tsx (2)

84-87: Consider adding a row-specific elementId for stronger selector granularity

Card.Root gains an elementDescriptor, which is great, but without a complementary elementId the selector will match every revoke-modal in the DOM.
If multiple revoke modals can coexist (e.g. in tests or storybook), distinguishing them becomes impossible.

-  <Card.Root
-    role='alertdialog'
-    elementDescriptor={descriptors.apiKeysRevokeModal}
-  >
+  <Card.Root
+    role='alertdialog'
+    elementDescriptor={descriptors.apiKeysRevokeModal}
+    elementId={descriptors.apiKeysRevokeModal.setId(apiKeyId ?? 'revoke-modal')}
+  >

46-55: Make the confirmation check case-insensitive

Users frequently type revoke in lowercase; failing the check feels unnecessarily strict.

-const canSubmit = revokeField.value === 'Revoke';
+const canSubmit = revokeField.value.trim().toLowerCase() === 'revoke';
packages/clerk-js/src/ui/components/ApiKeys/ApiKeysTable.tsx (2)

54-56: aria-label not updated when state changes

You already added descriptor metadata to CopySecretButton; while you’re touching this block, consider toggling the aria-label after the copy operation so screen-reader users know the button’s new purpose.

-aria-label={hasCopied ? 'Copied API key to clipboard' : 'Copy API key'}
+aria-label={hasCopied ? 'Copied API key to clipboard' : 'Copy API key'}

(You may instead expose the string through localizationKeys like the rest of the UI.)


98-100: Show key label becomes stale after reveal

When revealed toggles, the button continues to say Show key. Swap the label to Hide key (and localise) for accurate accessibility.

-aria-label={'Show key'}
+aria-label={revealed ? 'Hide key' : 'Show key'}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c3fa15d and b9b994f.

📒 Files selected for processing (8)
  • .changeset/chilly-pears-film.md (1 hunks)
  • packages/clerk-js/src/ui/components/ApiKeys/ApiKeys.tsx (6 hunks)
  • packages/clerk-js/src/ui/components/ApiKeys/ApiKeysTable.tsx (8 hunks)
  • packages/clerk-js/src/ui/components/ApiKeys/CreateApiKeyForm.tsx (4 hunks)
  • packages/clerk-js/src/ui/components/ApiKeys/RevokeAPIKeyConfirmationModal.tsx (4 hunks)
  • packages/clerk-js/src/ui/components/ApiKeys/useApiKeys.ts (0 hunks)
  • packages/clerk-js/src/ui/customizables/elementDescriptors.ts (1 hunks)
  • packages/types/src/appearance.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/clerk-js/src/ui/components/ApiKeys/useApiKeys.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
packages/clerk-js/src/ui/components/ApiKeys/CreateApiKeyForm.tsx (1)
packages/clerk-js/src/ui/customizables/elementDescriptors.ts (1)
  • descriptors (545-545)
packages/clerk-js/src/ui/components/ApiKeys/ApiKeys.tsx (1)
packages/clerk-js/src/ui/customizables/elementDescriptors.ts (1)
  • descriptors (545-545)
⏰ Context from checks skipped due to timeout of 90000ms (24)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 14)
  • GitHub Check: Integration Tests (nextjs, chrome, 13)
  • GitHub Check: Integration Tests (expo-web, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (elements, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (tanstack-react-router, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Integration Tests (quickstart, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Unit Tests (22, **)
  • GitHub Check: Publish with pkg-pr-new
  • GitHub Check: Unit Tests (18, --filter=@clerk/astro --filter=@clerk/backend --filter=@clerk/express --filter=@c...
  • GitHub Check: Static analysis
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (10)
packages/types/src/appearance.ts (1)

589-609: API-keys descriptors correctly wired into ElementsConfig

The new apiKeys* entries are all declared with the proper WithOptions signature (WithOptions<string> for id-based parts, plain WithOptions for the rest) and the naming matches the keys used elsewhere (elementDescriptors.ts, components). No functional issues spotted.

packages/clerk-js/src/ui/components/ApiKeys/CreateApiKeyForm.tsx (2)

100-106: Good: FormContainer is now targettable

Supplying elementDescriptor={descriptors.apiKeysCreateForm} ensures the form container can be themed or queried in tests – nice.


196-202: ```shell
#!/bin/bash

Locate the definition of SubmitButton in Form.tsx to check supported props

rg -n --context 5 "SubmitButton" packages/clerk-js/src/ui/elements/Form.tsx


</details>
<details>
<summary>packages/clerk-js/src/ui/components/ApiKeys/ApiKeys.tsx (4)</summary>

`8-18`: **Import keeps file-local barrel pattern consistent**

Including `descriptors` in the barrel import keeps consistency with other pages. Looks good.

---

`94-108`: **Root & header containers now descriptor-enabled**

Adding `elementDescriptor` on the main `<Col>` and header `<Flex>` gives users fine-grained styling hooks – nice improvement.

---

`118-129`: **Search input and “Add” button descriptors**

These are the primary interactive controls; descriptor coverage here is valuable for e2e tests.

---

`144-148`: **Table descriptor wired through**

`ApiKeysTable` now receives `elementDescriptor={descriptors.apiKeysTable}` — make sure `ApiKeysTableProps` includes this optional prop (it was marked optional in the PR description).

</details>
<details>
<summary>.changeset/chilly-pears-film.md (1)</summary>

`1-7`: **Changeset OK**

Version bumps & summary look correct.

</details>
<details>
<summary>packages/clerk-js/src/ui/components/ApiKeys/RevokeAPIKeyConfirmationModal.tsx (1)</summary>

`99-103`: **`Form.ControlRow` lacks an `elementId`; localisation fallback still hard-coded**

1. As with the modal root, adding an `elementId` would allow tests/themes to target the exact input when several modals are open.

2. The label/placeholder text (`"Revoke"`) remains hard-coded and English-only.  
   There is already a TODO for localisation – consider wiring `localizationKeys` now so this PR is fully i18n-ready.

```diff
-  <Form.ControlRow
-    elementId={revokeField.id}
-    elementDescriptor={descriptors.apiKeysRevokeModalInput}
-  >
+  <Form.ControlRow
+    elementId={descriptors.apiKeysRevokeModalInput.setId(revokeField.id)}
+    elementDescriptor={descriptors.apiKeysRevokeModalInput}
+  >

Likely an incorrect or invalid review comment.

packages/clerk-js/src/ui/components/ApiKeys/ApiKeysTable.tsx (1)

125-127: Passing a possibly undefined elementDescriptor is fine—guard inside Table to avoid prop-bleed

If Table spreads incoming props onto a DOM element, undefined is harmless in React but can leak into data- attributes if not filtered. Ensure the Table component strips falsy descriptors internally. No action required here if that guard already exists.

Copy link
Member

@alexcarpenter alexcarpenter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good, I do think we should remove the id usage. There is also a handful of elements with internal only classNames.

@@ -93,6 +104,7 @@ export const APIKeysPage = ({ subject, perPage, revokeModalRoot }: APIKeysPagePr
alignItems: 'stretch',
},
}}
elementDescriptor={descriptors.apiKeysHeader}
>
<Box>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Box should also include a descriptor here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added, thanks!

Comment on lines 61 to 62
export const Th = makeCustomizable(makeLocalizable(sanitizeDomProps(Primitives.Th)));
export const Td = makeCustomizable(makeLocalizable(sanitizeDomProps(Primitives.Td)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also include defaultDescriptors for th and td below?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added!

@wobsoriano wobsoriano enabled auto-merge (squash) June 18, 2025 15:05
@wobsoriano wobsoriano merged commit b495279 into main Jun 18, 2025
61 of 62 checks passed
@wobsoriano wobsoriano deleted the rob/api-keys-element-descriptors branch June 18, 2025 15:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants