Skip to content

Add Storybook test runner with a11y (axe) and CI workflow#36

Open
mrabbani wants to merge 4 commits into
mainfrom
chore/storybook-test-runner
Open

Add Storybook test runner with a11y (axe) and CI workflow#36
mrabbani wants to merge 4 commits into
mainfrom
chore/storybook-test-runner

Conversation

@mrabbani

@mrabbani mrabbani commented Feb 7, 2026

Copy link
Copy Markdown
Member
  • Add test-storybook and test-storybook:ci scripts
  • Add @storybook/test-runner and axe-playwright
  • Add .storybook/test-runner.ts for a11y checks (with a11y.disable opt-out)
  • Add GitHub Actions workflow to run UI tests on push (Playwright image)

Summary by CodeRabbit

Release Notes

  • New Features

    • Added automated Storybook UI testing in CI with accessibility checks powered by axe.
  • Documentation

    • Refreshed README and added/expanded the Storybook authoring guide for creating and testing stories.
  • Chores

    • Added test-storybook and test-storybook:ci npm scripts.
    • Reworked Storybook/CI setup and standardized formatting across the project (including workflow and config file updates).
    • Updated .gitignore to better support local development files.

mrabbani and others added 3 commits February 7, 2026 22:51
- Add test-storybook and test-storybook:ci scripts
- Add @storybook/test-runner and axe-playwright
- Add .storybook/test-runner.ts for a11y checks (with a11y.disable opt-out)
- Add GitHub Actions workflow to run UI tests on push (Playwright image)

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@arifulhoque7
arifulhoque7 force-pushed the chore/storybook-test-runner branch from bf5889b to 9998f68 Compare May 18, 2026 10:24
@coderabbitai

coderabbitai Bot commented May 18, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds Storybook accessibility testing and CI execution, updates Storybook and webpack build configuration, removes two provider re-exports, and normalizes formatting across components, stories, themes, configuration, and documentation. Most code changes preserve existing runtime behavior.

Changes

Storybook testing and build infrastructure

Layer / File(s) Summary
Accessibility testing and CI
.storybook/test-runner.ts, .github/workflows/test-ui.yml, package.json
Adds axe-playwright Storybook checks, a Playwright-based push workflow, and local/CI Storybook test scripts.
Build and project configuration
.storybook/main.ts, webpack.config.js, .storybook/preview.js, postcss.config.js, tsconfig.json, .gitignore, babel.config.cjs, components.json
Adds typed Storybook configuration and explicit webpack processing while preserving existing preview, PostCSS, TypeScript, Babel, and component configuration; updates ignored files.
Storybook deployment
.github/workflows/deploy-storybook.yml
Reformats the existing GitHub Pages deployment workflow without functional changes.

Storybook stories

Layer / File(s) Summary
UI story suite
src/components/ui/*.stories.tsx
Reformats Storybook stories across the UI component set while preserving metadata, exports, rendered structures, props, and assertions.

UI components and public exports

Layer / File(s) Summary
Component modules
src/components/ui/*.tsx
Reformats component implementations and adds modal comments/JSDoc while preserving component behavior, props, styling, and exports.
Theme and export surfaces
src/providers/*, src/themes/index.ts, src/index.ts, src/components/ui/index.ts, src/lib/utils.ts, src/styles.css, src/tweakcn.css
Reformats theme, utility, stylesheet, and barrel-export code; src/providers/index.ts no longer re-exports defaultCssVariables or ThemeContextValue.

Documentation

Layer / File(s) Summary
Project and component documentation
README.md, docs/*.md
Regenerates documentation and examples with equivalent coverage and formatting; the breadcrumb dropdown example adds an onClick toggle handler.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

  • getdokan/plugin-ui#96: Updates the theme-provider export surface by removing defaultCssVariables and ThemeContextValue.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 7.69% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a Storybook test runner with axe a11y checks and a CI workflow.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/storybook-test-runner
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch chore/storybook-test-runner

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (2)
src/components/ui/slider.tsx (1)

27-41: 💤 Low value

Consider removing commented-out code.

The commented trackClass function spans 15 lines. If this code is no longer needed, removing it would improve readability. If it might be needed in the future, consider documenting why it's preserved in a TODO comment.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ui/slider.tsx` around lines 27 - 41, Remove the large
commented-out block for the trackClass helper in src/components/ui/slider.tsx
(the commented function named trackClass); either delete it entirely to improve
readability or, if you want to keep it, replace the block with a one-line TODO
comment explaining why it’s preserved and where an equivalent implementation
lives, referencing trackClass so reviewers can locate the intent quickly.
.github/workflows/test-ui.yml (1)

19-20: ⚡ Quick win

Use npm ci for reproducible CI installs.

Line 20 should use lockfile-based install to avoid dependency drift between runs.

Proposed change
-      - name: Install dependencies
-        run: npm install
+      - name: Install dependencies
+        run: npm ci
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test-ui.yml around lines 19 - 20, The CI workflow step
named "Install dependencies" currently runs npm install which can produce
non-reproducible installs; change that step to run npm ci to perform a
lockfile-based, deterministic install (and optionally ensure package-lock.json
or npm-shrinkwrap.json is committed). Update the step that executes the install
command (the "Install dependencies" job/step) to use npm ci instead of npm
install, and add a brief check or comment to fail early if no lockfile is
present.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/STORYBOOK.md`:
- Line 271: The doc references the preview config with two different filenames
causing confusion; open STORYBOOK.md and standardize all mentions to the actual
preview filename used in the repo (replace `.storybook/preview.js` occurrences
with `.storybook/preview.tsx` if the project uses TypeScript, or vice versa if
the real file is `.storybook/preview.js`), ensuring the references at the
currently mismatched spots (the lines referencing `.storybook/preview.tsx` and
the later `.storybook/preview.js`) are updated so every mention uses the single
correct filename.

In `@package.json`:
- Line 51: The package.json script "test-storybook:ci" uses CLI tools that
aren't declared as devDependencies; add the missing devDependencies for
"concurrently", "wait-on", and "http-server" (as devDependencies) so CI installs
them on fresh installs and the "test-storybook:ci" script can run; update
package.json's devDependencies section accordingly and run npm/yarn install to
verify.

In `@src/components/ui/index.ts`:
- Around line 64-69: Update the inconsistent quote and semicolon style in the UI
barrel exports: change the single quotes to double quotes and add trailing
semicolons for the exports that use single quotes currently — specifically the
export lines that include Toggle, ToggleGroup, ToggleGroupItem, Tabs, TabsList,
TabsTrigger, TabsContent, tabsListVariants, SelectionType, SelectionItem, and
selectionItemVariants — so all export statements match the double-quote +
semicolon style used elsewhere in this file.

In `@src/providers/theme-provider.tsx`:
- Around line 470-473: Replace the template-string class concatenation for the
component's root element with the shared cn() utility: when setting className
use cn(...) to merge "pui-root", the conditional dark class (based on
resolvedMode === "dark"), and the incoming className prop; update the line that
currently constructs className with `` `pui-root ${resolvedMode === "dark" ?
"dark" : ""} ${className}`.trim()`` to call cn("pui-root", resolvedMode ===
"dark" && "dark", className) so class merging follows the project's
cn/clsx+tw-merge convention.

In `@src/themes/index.ts`:
- Around line 6-125: The theme tokens in this file (e.g., defaultTheme,
defaultDarkTheme, dokanTheme, dokanDarkTheme, blueTheme, blueDarkTheme,
greenTheme, greenDarkTheme, amberTheme, amberDarkTheme, slateTheme,
slateDarkTheme) use "oklch(...)" strings but must be converted to the HSL
raw-value contract (plain "H S% L%" channel strings without the hsl() wrapper).
Update every color token (primary, primaryForeground, ring, background,
foreground, card, cardForeground, secondary, secondaryForeground, muted,
mutedForeground, border, input, etc.) to their equivalent HSL raw channel
strings (leave radius values untouched), ensuring all dark theme spreads
(...defaultDarkTheme) also receive converted HSL values.

In `@webpack.config.js`:
- Around line 19-28: The externals block currently replaces
defaultConfig.externals, removing `@wordpress/scripts` defaults; change it to
merge with defaults by using the existing defaultConfig.externals and spreading
it (e.g., create externals = { ...defaultConfig.externals, react: 'react',
'react-dom': 'react-dom', '`@wordpress/element`': '`@wordpress/element`',
'`@wordpress/components`': '`@wordpress/components`', '`@wordpress/block-editor`':
'`@wordpress/block-editor`', '`@wordpress/hooks`': '`@wordpress/hooks`',
'`@wordpress/i18n`': '`@wordpress/i18n`', quill: 'quill' }) so you preserve defaults
while adding your custom entries; update the webpack config where externals is
set (referencing defaultConfig and the externals property) to apply this merged
object.

---

Nitpick comments:
In @.github/workflows/test-ui.yml:
- Around line 19-20: The CI workflow step named "Install dependencies" currently
runs npm install which can produce non-reproducible installs; change that step
to run npm ci to perform a lockfile-based, deterministic install (and optionally
ensure package-lock.json or npm-shrinkwrap.json is committed). Update the step
that executes the install command (the "Install dependencies" job/step) to use
npm ci instead of npm install, and add a brief check or comment to fail early if
no lockfile is present.

In `@src/components/ui/slider.tsx`:
- Around line 27-41: Remove the large commented-out block for the trackClass
helper in src/components/ui/slider.tsx (the commented function named
trackClass); either delete it entirely to improve readability or, if you want to
keep it, replace the block with a one-line TODO comment explaining why it’s
preserved and where an equivalent implementation lives, referencing trackClass
so reviewers can locate the intent quickly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 934228da-a3b7-4987-9176-35e967e76725

📥 Commits

Reviewing files that changed from the base of the PR and between 03e7989 and 48ac44e.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (51)
  • .github/workflows/deploy-storybook.yml
  • .github/workflows/test-ui.yml
  • .gitignore
  • .storybook/main.ts
  • .storybook/preview.js
  • .storybook/test-runner.ts
  • README.md
  • docs/STORYBOOK.md
  • package.json
  • postcss.config.js
  • src/components/ui/Alert.stories.tsx
  • src/components/ui/Avatar.stories.tsx
  • src/components/ui/Combobox.stories.tsx
  • src/components/ui/DropdownMenu.stories.tsx
  • src/components/ui/Input.stories.tsx
  • src/components/ui/InputGroup.stories.tsx
  • src/components/ui/InputOTP.stories.tsx
  • src/components/ui/Progress.stories.tsx
  • src/components/ui/SelectionType.stories.tsx
  • src/components/ui/Slider.stories.tsx
  • src/components/ui/Switch.stories.tsx
  • src/components/ui/Textarea.stories.tsx
  • src/components/ui/ToggleGroup.stories.tsx
  • src/components/ui/Tooltip.stories.tsx
  • src/components/ui/alert-dialog.tsx
  • src/components/ui/alert.tsx
  • src/components/ui/badge.tsx
  • src/components/ui/button.tsx
  • src/components/ui/card.tsx
  • src/components/ui/combobox.tsx
  • src/components/ui/dropdown-menu.tsx
  • src/components/ui/index.ts
  • src/components/ui/input-group.tsx
  • src/components/ui/input.tsx
  • src/components/ui/modal.tsx
  • src/components/ui/notice.tsx
  • src/components/ui/progress.tsx
  • src/components/ui/select.tsx
  • src/components/ui/selection-type.tsx
  • src/components/ui/slider.tsx
  • src/components/ui/switch.tsx
  • src/components/ui/textarea.tsx
  • src/components/ui/toggle-group.tsx
  • src/components/ui/tooltip.tsx
  • src/index.ts
  • src/lib/utils.ts
  • src/providers/theme-provider.tsx
  • src/styles.css
  • src/themes/index.ts
  • tsconfig.json
  • webpack.config.js

Comment thread docs/STORYBOOK.md
## 5. Decorators (global theme / layout)
All stories run inside the preview decorators (see `.storybook/preview.tsx`), which:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix inconsistent preview config filename references.

Line 271/383 point to .storybook/preview.tsx, but this doc later references .storybook/preview.js (Line 369). Please standardize these references to the actual file to avoid broken guidance.

Also applies to: 383-383

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/STORYBOOK.md` at line 271, The doc references the preview config with
two different filenames causing confusion; open STORYBOOK.md and standardize all
mentions to the actual preview filename used in the repo (replace
`.storybook/preview.js` occurrences with `.storybook/preview.tsx` if the project
uses TypeScript, or vice versa if the real file is `.storybook/preview.js`),
ensuring the references at the currently mismatched spots (the lines referencing
`.storybook/preview.tsx` and the later `.storybook/preview.js`) are updated so
every mention uses the single correct filename.

Comment thread package.json
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"test-storybook": "test-storybook",
"test-storybook:ci": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"npm run build-storybook && npx http-server storybook-static --port 6006 --silent\" \"wait-on tcp:6006 && test-storybook\"",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether required CLI deps for test-storybook:ci are declared.
rg -n '"test-storybook:ci"' package.json
rg -n '"(concurrently|wait-on|http-server)"' package.json

Repository: getdokan/plugin-ui

Length of output: 282


🏁 Script executed:

cat -n package.json

Repository: getdokan/plugin-ui

Length of output: 4526


test-storybook:ci script depends on CLIs not declared in devDependencies.

Line 51's test-storybook:ci script invokes concurrently, wait-on, and http-server, but none of these packages are present in devDependencies. This will cause CI to fail on fresh installs.

Add the missing dependencies:

Proposed change
   "devDependencies": {
+    "concurrently": "^9.0.1",
+    "wait-on": "^8.0.1",
+    "http-server": "^14.1.1",
     "`@babel/preset-react`": "^7.26.0",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"test-storybook:ci": "concurrently -k -s first -n \"SB,TEST\" -c \"magenta,blue\" \"npm run build-storybook && npx http-server storybook-static --port 6006 --silent\" \"wait-on tcp:6006 && test-storybook\"",
"devDependencies": {
"concurrently": "^9.0.1",
"wait-on": "^8.0.1",
"http-server": "^14.1.1",
"`@babel/preset-react`": "^7.26.0",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@package.json` at line 51, The package.json script "test-storybook:ci" uses
CLI tools that aren't declared as devDependencies; add the missing
devDependencies for "concurrently", "wait-on", and "http-server" (as
devDependencies) so CI installs them on fresh installs and the
"test-storybook:ci" script can run; update package.json's devDependencies
section accordingly and run npm/yarn install to verify.

Comment on lines +64 to +69
export { Toggle } from './toggle'
export { ToggleGroup, ToggleGroupItem } from './toggle-group'
export { Progress, ProgressTrack, ProgressIndicator, ProgressLabel, ProgressValue, CircularProgress, type ProgressProps, type CircularProgressProps } from "./progress";
export { Slider, type SliderProps } from "./slider";
export { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants } from './tabs'
export { SelectionType, SelectionItem, selectionItemVariants } from './selection-type'

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Run ESLint on the index.ts file to check for quote-style violations

npm run lint -- src/components/ui/index.ts

Repository: getdokan/plugin-ui

Length of output: 195


🏁 Script executed:

# Check for ESLint configuration and the actual file content
find . -maxdepth 2 -type f \( -name ".eslintrc*" -o -name "eslint.config.*" \) | head -20

Repository: getdokan/plugin-ui

Length of output: 44


🏁 Script executed:

# Check the actual content of the file to verify quote styles
cat -n src/components/ui/index.ts | tail -20

Repository: getdokan/plugin-ui

Length of output: 1157


🏁 Script executed:

# Check package.json to understand npm scripts and dependencies
cat package.json | grep -A 10 '"lint"'

Repository: getdokan/plugin-ui

Length of output: 395


🏁 Script executed:

# Search more thoroughly for ESLint config
find . -type f -name ".eslintrc*" -o -name "eslint.config.*" 2>/dev/null | head -20

Repository: getdokan/plugin-ui

Length of output: 44


🏁 Script executed:

# Check if there's an eslint config in package.json itself
cat package.json | grep -A 20 '"eslintConfig"'

Repository: getdokan/plugin-ui

Length of output: 44


🏁 Script executed:

# Try to find all config files in root
ls -la | grep -E '^\.'

Repository: getdokan/plugin-ui

Length of output: 44


🏁 Script executed:

# List all files in repository root
ls -la | head -30

Repository: getdokan/plugin-ui

Length of output: 1078


🏁 Script executed:

# Search for any file containing eslint configuration
find . -maxdepth 3 -type f \( -name "*config*" -o -name "*.json" \) | grep -v node_modules | head -20

Repository: getdokan/plugin-ui

Length of output: 204


🏁 Script executed:

# Check if eslint is in package.json dependencies
cat package.json | grep -i eslint

Repository: getdokan/plugin-ui

Length of output: 108


🏁 Script executed:

# Check for .eslintignore and other hidden eslint files
ls -la | grep eslint

Repository: getdokan/plugin-ui

Length of output: 44


🏁 Script executed:

# Search for any eslint references in the codebase
rg "eslint" --type json --type javascript --type typescript | head -20

Repository: getdokan/plugin-ui

Length of output: 97


🏁 Script executed:

# Check .github directory for CI/CD config that might have eslint setup
find .github -type f -name "*.yml" -o -name "*.yaml" | xargs cat 2>/dev/null

Repository: getdokan/plugin-ui

Length of output: 2018


Fix quote style inconsistency.

Lines 64-65 and 68-69 use single quotes while the rest of the file uses double quotes. This inconsistency also appears with semicolons (missing on those same lines). Update to use consistent double quotes and semicolons throughout, matching the rest of the file.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/components/ui/index.ts` around lines 64 - 69, Update the inconsistent
quote and semicolon style in the UI barrel exports: change the single quotes to
double quotes and add trailing semicolons for the exports that use single quotes
currently — specifically the export lines that include Toggle, ToggleGroup,
ToggleGroupItem, Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants,
SelectionType, SelectionItem, and selectionItemVariants — so all export
statements match the double-quote + semicolon style used elsewhere in this file.

Comment on lines +470 to +473
className={`pui-root ${
resolvedMode === "dark" ? "dark" : ""
} ${className}`.trim()}
style={{ ...cssVariables, ...style }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Use cn() for class merging instead of template-string concatenation.

Line 470–Line 473 should use the shared merge utility for consistency and safer class composition.

Proposed change
 import React, {
   createContext,
   useCallback,
   useContext,
   useEffect,
   useMemo,
   useState,
   type ReactNode,
 } from "react";
+import { cn } from "`@/lib/utils`";
@@
         data-pui-plugin={pluginId}
         data-pui-mode={resolvedMode}
-        className={`pui-root ${
-          resolvedMode === "dark" ? "dark" : ""
-        } ${className}`.trim()}
+        className={cn("pui-root", resolvedMode === "dark" && "dark", className)}
         style={{ ...cssVariables, ...style }}
       >

As per coding guidelines, "Use the cn() utility function to merge Tailwind CSS classes (combines clsx + tailwind-merge)".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
className={`pui-root ${
resolvedMode === "dark" ? "dark" : ""
} ${className}`.trim()}
style={{ ...cssVariables, ...style }}
className={cn("pui-root", resolvedMode === "dark" && "dark", className)}
style={{ ...cssVariables, ...style }}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/providers/theme-provider.tsx` around lines 470 - 473, Replace the
template-string class concatenation for the component's root element with the
shared cn() utility: when setting className use cn(...) to merge "pui-root", the
conditional dark class (based on resolvedMode === "dark"), and the incoming
className prop; update the line that currently constructs className with ``
`pui-root ${resolvedMode === "dark" ? "dark" : ""} ${className}`.trim()`` to
call cn("pui-root", resolvedMode === "dark" && "dark", className) so class
merging follows the project's cn/clsx+tw-merge convention.

Comment thread src/themes/index.ts
Comment on lines +6 to +125
export const defaultTheme: ThemeTokens = {
primary: "oklch(0.5410 0.2120 265.7540)",
primaryForeground: "oklch(1.0000 0 0)",
ring: "oklch(0.5410 0.2120 265.7540)",
radius: "0.5rem",
};
/**
* Default dark theme tokens
*/
export const defaultDarkTheme: ThemeTokens = {
background: "oklch(0.1450 0.0140 285.7500)",
foreground: "oklch(0.9850 0.0030 264.5000)",
card: "oklch(0.1450 0.0140 285.7500)",
cardForeground: "oklch(0.9850 0.0030 264.5000)",
primary: "oklch(0.6230 0.2000 265.7540)",
primaryForeground: "oklch(0.1450 0.0140 285.7500)",
secondary: "oklch(0.2690 0.0150 264.5419)",
secondaryForeground: "oklch(0.9850 0.0030 264.5000)",
muted: "oklch(0.2690 0.0150 264.5419)",
mutedForeground: "oklch(0.7110 0.0200 264.3637)",
border: "oklch(0.3690 0.0150 264.5313)",
input: "oklch(0.3690 0.0150 264.5313)",
ring: "oklch(0.6230 0.2000 265.7540)",
};
/**
* Dokan theme - Purple brand
*/
export const dokanTheme: ThemeTokens = {
primary: "oklch(0.5410 0.2120 265.7540)", // #7047EB
primaryForeground: "oklch(1.0000 0 0)",
ring: "oklch(0.5410 0.2120 265.7540)",
radius: "0.375rem",
};
/**
* Dokan dark theme
*/
export const dokanDarkTheme: ThemeTokens = {
...defaultDarkTheme,
primary: "oklch(0.6230 0.2000 265.7540)",
ring: "oklch(0.6230 0.2000 265.7540)",
};
/**
* Blue theme - For plugins like WeMail
*/
export const blueTheme: ThemeTokens = {
primary: "oklch(0.6230 0.2140 255.0900)", // Blue
primaryForeground: "oklch(1.0000 0 0)",
ring: "oklch(0.6230 0.2140 255.0900)",
radius: "0.5rem",
};
/**
* Blue dark theme
*/
export const blueDarkTheme: ThemeTokens = {
...defaultDarkTheme,
primary: "oklch(0.7000 0.1800 255.0900)",
ring: "oklch(0.7000 0.1800 255.0900)",
};
/**
* Green theme - For plugins with nature/growth branding
*/
export const greenTheme: ThemeTokens = {
primary: "oklch(0.6470 0.1780 145.0000)", // Green
primaryForeground: "oklch(1.0000 0 0)",
ring: "oklch(0.6470 0.1780 145.0000)",
radius: "0.5rem",
};
/**
* Green dark theme
*/
export const greenDarkTheme: ThemeTokens = {
...defaultDarkTheme,
primary: "oklch(0.7200 0.1600 145.0000)",
ring: "oklch(0.7200 0.1600 145.0000)",
};
/**
* Orange/Amber theme - For warm branding
*/
export const amberTheme: ThemeTokens = {
primary: "oklch(0.7690 0.1880 70.0800)", // Amber/Orange
primaryForeground: "oklch(0.2100 0.0340 32.0000)",
ring: "oklch(0.7690 0.1880 70.0800)",
radius: "0.5rem",
};
/**
* Amber dark theme
*/
export const amberDarkTheme: ThemeTokens = {
...defaultDarkTheme,
primary: "oklch(0.8200 0.1600 70.0800)",
ring: "oklch(0.8200 0.1600 70.0800)",
};
/**
* Slate/Neutral theme - For minimal, professional look
*/
export const slateTheme: ThemeTokens = {
primary: "oklch(0.3050 0.0170 264.5419)", // Slate
primaryForeground: "oklch(1.0000 0 0)",
ring: "oklch(0.3050 0.0170 264.5419)",
radius: "0.375rem",
};
/**
* Slate dark theme
*/
export const slateDarkTheme: ThemeTokens = {
...defaultDarkTheme,
primary: "oklch(0.7110 0.0200 264.3637)",
ring: "oklch(0.7110 0.0200 264.3637)",
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

Theme token format is inconsistent with the required HSL raw-value contract.

Line 6 onward defines ThemeTokens with oklch(...) values; this should be migrated to raw HSL channel strings (without hsl() wrapper) to match the theme-system contract.

As per coding guidelines, "Theme system should use HSL values without the hsl() wrapper (e.g., '220 90% 56%') for all ThemeTokens".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/themes/index.ts` around lines 6 - 125, The theme tokens in this file
(e.g., defaultTheme, defaultDarkTheme, dokanTheme, dokanDarkTheme, blueTheme,
blueDarkTheme, greenTheme, greenDarkTheme, amberTheme, amberDarkTheme,
slateTheme, slateDarkTheme) use "oklch(...)" strings but must be converted to
the HSL raw-value contract (plain "H S% L%" channel strings without the hsl()
wrapper). Update every color token (primary, primaryForeground, ring,
background, foreground, card, cardForeground, secondary, secondaryForeground,
muted, mutedForeground, border, input, etc.) to their equivalent HSL raw channel
strings (leave radius values untouched), ensuring all dark theme spreads
(...defaultDarkTheme) also receive converted HSL values.

Comment thread webpack.config.js
Comment on lines +19 to +28
externals: {
react: 'react',
'react-dom': 'react-dom',
'@wordpress/element': '@wordpress/element',
'@wordpress/components': '@wordpress/components',
'@wordpress/block-editor': '@wordpress/block-editor',
'@wordpress/hooks': '@wordpress/hooks',
'@wordpress/i18n': '@wordpress/i18n',
quill: 'quill',
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify current config overrides externals instead of merging defaults.
rg -n "externals\\s*:" webpack.config.js -n -A12 -B2
rg -n "defaultConfig\\.externals" webpack.config.js

Repository: getdokan/plugin-ui

Length of output: 586


🏁 Script executed:

rg -n "defaultConfig" webpack.config.js -B5 -A5

Repository: getdokan/plugin-ui

Length of output: 1714


🏁 Script executed:

rg -n "from.*`@wordpress/scripts`\|import.*defaultConfig" .

Repository: getdokan/plugin-ui

Length of output: 44


🏁 Script executed:

fd webpack.config.js -x cat -n {} \; | head -40

Repository: getdokan/plugin-ui

Length of output: 1640


🌐 Web query:

@wordpress/scripts webpack config externals defaults

💡 Result:

The @wordpress/scripts package provides a default Webpack configuration that automatically handles the externalization of WordPress core packages (e.g., @wordpress/components, @wordpress/element) [1][2]. This is primarily managed by the @wordpress/dependency-extraction-webpack-plugin, which is included in the default configuration [1]. Key points regarding externals and customization: 1. Default Behavior: The default configuration automatically maps WordPress package imports to their corresponding global variables (e.g., @wordpress/blob becomes wp.blob) [1]. This allows you to use import statements in your code without bundling the entire WordPress core library, ensuring your scripts rely on the versions already loaded by WordPress [1][3]. 2. Customizing Externals: If you need to modify or extend the default externals, you can create a webpack.config.js file in your project root [4][5]. You can import the default configuration and merge your changes [4][5]. 3. Conflicts with DependencyExtractionWebpackPlugin: The default plugin overlaps with standard Webpack externals [1]. If you add custom externals that conflict with the plugin's automatic extraction, you may need to remove the default instance of the DependencyExtractionWebpackPlugin from the plugins array and re-add it with custom options, or use the externals option directly if you do not need the automatic dependency list generation [1]. 4. Disabling Externals: If you are building a standalone application that does not run within the WordPress environment, you can invoke the build or start scripts with the --webpack-no-externals flag to prevent the automatic externalization of WordPress packages [6]. To extend the configuration, use the following pattern in your webpack.config.js: const defaultConfig = require( '@wordpress/scripts/config/webpack.config'); module.exports = {...defaultConfig, // Add your custom externals or overrides here externals: {...defaultConfig.externals, 'my-custom-library': 'MyGlobalVar', }, }; Always ensure you are pinning your @wordpress/scripts version, as major updates may restructure the internal configuration [4].

Citations:


Do not replace defaultConfig.externals; merge it instead.

Line 19 replaces the entire externals map, which removes defaults from @wordpress/scripts. The correct pattern is to spread the defaults and add custom externals:

-    externals: {
+    externals: {
+        ...defaultConfig.externals,
         react: 'react',
         'react-dom': 'react-dom',
         '`@wordpress/element`': '`@wordpress/element`',

This aligns with the pattern used for other config properties (output, module, plugins, resolve) and matches the official @wordpress/scripts documentation for extending configurations.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
externals: {
react: 'react',
'react-dom': 'react-dom',
'@wordpress/element': '@wordpress/element',
'@wordpress/components': '@wordpress/components',
'@wordpress/block-editor': '@wordpress/block-editor',
'@wordpress/hooks': '@wordpress/hooks',
'@wordpress/i18n': '@wordpress/i18n',
quill: 'quill',
},
externals: {
...defaultConfig.externals,
react: 'react',
'react-dom': 'react-dom',
'`@wordpress/element`': '`@wordpress/element`',
'`@wordpress/components`': '`@wordpress/components`',
'`@wordpress/block-editor`': '`@wordpress/block-editor`',
'`@wordpress/hooks`': '`@wordpress/hooks`',
'`@wordpress/i18n`': '`@wordpress/i18n`',
quill: 'quill',
},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@webpack.config.js` around lines 19 - 28, The externals block currently
replaces defaultConfig.externals, removing `@wordpress/scripts` defaults; change
it to merge with defaults by using the existing defaultConfig.externals and
spreading it (e.g., create externals = { ...defaultConfig.externals, react:
'react', 'react-dom': 'react-dom', '`@wordpress/element`': '`@wordpress/element`',
'`@wordpress/components`': '`@wordpress/components`', '`@wordpress/block-editor`':
'`@wordpress/block-editor`', '`@wordpress/hooks`': '`@wordpress/hooks`',
'`@wordpress/i18n`': '`@wordpress/i18n`', quill: 'quill' }) so you preserve defaults
while adding your custom entries; update the webpack config where externals is
set (referencing defaultConfig and the externals property) to apply this merged
object.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (1)
src/tweakcn.css (1)

34-36: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Wrap font family names in quotes.

Proper noun and multi-word font families should be enclosed in quotes to prevent parsing issues and to resolve stylelint warnings across your theme variables.

  • src/tweakcn.css#L34-L36: add quotes around "Inter", "Source Serif 4", and "JetBrains Mono" in the :root block.
  • src/tweakcn.css#L89-L91: add quotes around "Inter", "Source Serif 4", and "JetBrains Mono" in the .dark block.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tweakcn.css` around lines 34 - 36, Wrap the font family names in quotes
in the :root variables at src/tweakcn.css lines 34-36 and the corresponding
.dark variables at lines 89-91: quote Inter, Source Serif 4, and JetBrains Mono
while preserving their existing fallback families.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/ALERT.md`:
- Around line 131-147: Make the documented close controls functional: in
docs/ALERT.md lines 131-147, connect the AlertAction button to alert state or an
onDismiss callback; in docs/NOTICE.md lines 84-98, replace the empty click
handler with state-based dismissal or a close callback.

In `@docs/breadcrumb-component.md`:
- Around line 313-327: Update the dropdown example around BreadcrumbEllipsis to
use an accessible interactive trigger instead of attaching onClick directly to
the presentation component: wrap it in a labeled, focusable button and expose
the menu’s expanded state while preserving the existing setShowMenu toggle
behavior.

In `@docs/input-component.md`:
- Around line 23-30: Update every Label/Input example in
docs/input-component.md, including the “With Label” example and the additional
referenced examples, to use matching htmlFor on each Label and id on its
intended Input. Ensure each label-control pair has a unique, consistent
identifier while preserving the surrounding examples.

In `@docs/MODAL.md`:
- Around line 80-81: Update the modal example’s Cancel and Delete controls to
use the library Button component instead of native button elements, and import
Button from the package entry point. Preserve the existing variant props and
click handlers.
- Around line 42-43: Update the Modal examples in MODAL.md to import Modal,
ModalHeader, ModalTitle, ModalDescription, and Button from `@wedevs/plugin-ui` at
each referenced import location, and replace the native footer button elements
with the library Button component while preserving their existing variant props
and behavior.

In `@docs/textarea-component.md`:
- Around line 134-146: Update the Textarea usage in the autoResize example so
the ref reaches the underlying DOM textarea: either forward refs through the
Textarea component implementation or replace it with a native textarea element.
Preserve the existing textareaRef and autoResize behavior.

In `@docs/VARIABLES-MAPPING.md`:
- Around line 176-186: Label the fenced code block containing the ThemeTokens
flow diagram as text by adding the appropriate fence language marker, while
leaving the diagram content unchanged.

---

Nitpick comments:
In `@src/tweakcn.css`:
- Around line 34-36: Wrap the font family names in quotes in the :root variables
at src/tweakcn.css lines 34-36 and the corresponding .dark variables at lines
89-91: quote Inter, Source Serif 4, and JetBrains Mono while preserving their
existing fallback families.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 96610037-4940-4b8d-a0c5-6ead563df7e5

📥 Commits

Reviewing files that changed from the base of the PR and between 48ac44e and 2ee0edf.

📒 Files selected for processing (47)
  • .gitignore
  • babel.config.cjs
  • components.json
  • docs/ALERT.md
  • docs/AVATAR_AND_THUMBNAIL.md
  • docs/MODAL.md
  • docs/NOTICE.md
  • docs/THEME-PRESETS.md
  • docs/VARIABLES-MAPPING.md
  • docs/breadcrumb-component.md
  • docs/button-component.md
  • docs/input-component.md
  • docs/input-otp-component.md
  • docs/progress.md
  • docs/selection-type-component.md
  • docs/tabs-component.md
  • docs/textarea-component.md
  • postcss.config.js
  • src/components/ui/AlertDialog.stories.tsx
  • src/components/ui/Badge.stories.tsx
  • src/components/ui/Breadcrumb.stories.tsx
  • src/components/ui/Button.stories.tsx
  • src/components/ui/Card.stories.tsx
  • src/components/ui/CurrencyInput.stories.tsx
  • src/components/ui/Label.stories.tsx
  • src/components/ui/Modal.stories.tsx
  • src/components/ui/Notice.stories.tsx
  • src/components/ui/Select.stories.tsx
  • src/components/ui/Separator.stories.tsx
  • src/components/ui/Spinner.stories.tsx
  • src/components/ui/Tabs.stories.tsx
  • src/components/ui/Thumbnail.stories.tsx
  • src/components/ui/Toggle.stories.tsx
  • src/components/ui/avatar.tsx
  • src/components/ui/breadcrumb.tsx
  • src/components/ui/currency-input.tsx
  • src/components/ui/design-system-section.tsx
  • src/components/ui/direction.tsx
  • src/components/ui/input-otp.tsx
  • src/components/ui/label.tsx
  • src/components/ui/separator.tsx
  • src/components/ui/spinner.tsx
  • src/components/ui/tabs.tsx
  • src/components/ui/thumbnail.tsx
  • src/components/ui/toggle.tsx
  • src/providers/index.ts
  • src/tweakcn.css
🚧 Files skipped from review as they are similar to previous changes (2)
  • .gitignore
  • postcss.config.js

Comment thread docs/ALERT.md
Comment on lines +131 to +147
### With Close Button (AlertAction)
```tsx
import { X } from "lucide-react"
<Alert variant="info">
<AlertTitle>Update Available</AlertTitle>
<AlertDescription>A new version of the app is now available.</AlertDescription>
<AlertAction>
<Button
size="icon"
variant="ghost"
className="h-8 w-8 p-0"
>
<X className="h-4 w-4" />
</Button>
</AlertAction>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make documented close buttons functional.

Both examples show dismiss controls that do not actually dismiss their component.

  • docs/ALERT.md#L131-L147: connect the AlertAction button to alert state or an onDismiss callback.
  • docs/NOTICE.md#L84-L98: replace the empty click handler with state or a close callback.
📍 Affects 2 files
  • docs/ALERT.md#L131-L147 (this comment)
  • docs/NOTICE.md#L84-L98
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/ALERT.md` around lines 131 - 147, Make the documented close controls
functional: in docs/ALERT.md lines 131-147, connect the AlertAction button to
alert state or an onDismiss callback; in docs/NOTICE.md lines 84-98, replace the
empty click handler with state-based dismissal or a close callback.

Comment on lines +313 to +327
## With Dropdown Menu
For complex hierarchies, you can integrate dropdown menus:
```tsx
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="#">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbEllipsis onClick={() => setShowMenu(!showMenu)} />
{/* Dropdown menu implementation */}
</BreadcrumbItem>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use an accessible interactive trigger for the dropdown.

BreadcrumbEllipsis renders an aria-hidden presentation span, so adding only onClick creates a pointer-only control that is unavailable to screen readers and keyboard users. Wrap it in a labeled <button> or update the component usage with keyboard semantics, focusability, and expanded-state attributes.

Suggested documentation fix
-      <BreadcrumbEllipsis onClick={() => setShowMenu(!showMenu)} />
+      <button
+        type="button"
+        aria-label="Show more breadcrumb items"
+        aria-expanded={showMenu}
+        onClick={() => setShowMenu((open) => !open)}
+      >
+        <BreadcrumbEllipsis />
+      </button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## With Dropdown Menu
For complex hierarchies, you can integrate dropdown menus:
```tsx
<Breadcrumb>
<BreadcrumbList>
<BreadcrumbItem>
<BreadcrumbLink href="#">Home</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbSeparator />
<BreadcrumbItem>
<BreadcrumbEllipsis onClick={() => setShowMenu(!showMenu)} />
{/* Dropdown menu implementation */}
</BreadcrumbItem>
## With Dropdown Menu
For complex hierarchies, you can integrate dropdown menus:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/breadcrumb-component.md` around lines 313 - 327, Update the dropdown
example around BreadcrumbEllipsis to use an accessible interactive trigger
instead of attaching onClick directly to the presentation component: wrap it in
a labeled, focusable button and expose the menu’s expanded state while
preserving the existing setShowMenu toggle behavior.

Comment thread docs/input-component.md
Comment on lines +23 to +30
## With Label
```tsx
<div className="space-y-2">
<Label>Username</Label>
<Input placeholder="Enter your username" />
</div>
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Associate each documented label with its input.

The examples render Label and Input as siblings without matching htmlFor/id values. Add explicit associations in these examples so screen readers and label clicks target the intended control.

Suggested fix
-  <Label>Username</Label>
-  <Input placeholder="Enter your username" />
+  <Label htmlFor="username">Username</Label>
+  <Input id="username" placeholder="Enter your username" />

Also applies to: 223-229, 231-239, 242-253, 256-264, 267-276

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/input-component.md` around lines 23 - 30, Update every Label/Input
example in docs/input-component.md, including the “With Label” example and the
additional referenced examples, to use matching htmlFor on each Label and id on
its intended Input. Ensure each label-control pair has a unique, consistent
identifier while preserving the surrounding examples.

Comment thread docs/MODAL.md
Comment on lines +42 to +43
import { Modal, ModalHeader, ModalTitle, ModalDescription } from "@plugin-ui/ui";
import { useState } from "react";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

rg -n '`@plugin-ui/ui`|`@wedevs/plugin-ui`' docs package.json tsconfig.json

Repository: getdokan/plugin-ui

Length of output: 1954


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- package.json ---\n'
cat -n package.json | sed -n '1,120p'

printf '\n--- docs/MODAL.md (lines 1-220) ---\n'
cat -n docs/MODAL.md | sed -n '1,220p'

printf '\n--- search for exports / aliases ---\n'
rg -n 'exports|`@plugin-ui/ui`|`@wedevs/plugin-ui`|plugin-ui/ui' package.json docs src . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**'

Repository: getdokan/plugin-ui

Length of output: 247


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- package.json ---'
cat -n package.json | sed -n '1,160p'

echo
echo '--- docs/MODAL.md (lines 1-220) ---'
cat -n docs/MODAL.md | sed -n '1,220p'

echo
echo '--- export/alias search ---'
rg -n 'exports|`@plugin-ui/ui`|`@wedevs/plugin-ui`|plugin-ui/ui' package.json docs src . -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**'

Repository: getdokan/plugin-ui

Length of output: 16488


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- docs/button-component.md (lines 1-120) ---'
cat -n docs/button-component.md | sed -n '1,120p'

echo
echo '--- Button exports/usages ---'
rg -n 'export .*Button|from "`@wedevs/plugin-ui`"|<Button|variant=' src docs README.md package.json -g '!**/node_modules/**' -g '!**/dist/**' -g '!**/build/**'

Repository: getdokan/plugin-ui

Length of output: 22186


Use @wedevs/plugin-ui and the library Button in the Modal examples.

  • @plugin-ui/ui isn’t exported here; update the Modal imports at docs/MODAL.md:42, 69, 150 to @wedevs/plugin-ui.
  • The footer examples at docs/MODAL.md:80-81, 122 use native <button> elements with variant; switch those to the library Button component so the variants apply.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/MODAL.md` around lines 42 - 43, Update the Modal examples in MODAL.md to
import Modal, ModalHeader, ModalTitle, ModalDescription, and Button from
`@wedevs/plugin-ui` at each referenced import location, and replace the native
footer button elements with the library Button component while preserving their
existing variant props and behavior.

Source: Coding guidelines

Comment thread docs/MODAL.md
Comment on lines +80 to +81
<button variant="outline" onClick={() => setOpen(false)}>Cancel</button>
<button variant="destructive" onClick={handleDelete}>Delete</button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== docs/MODAL.md excerpt ==\n'
wc -l docs/MODAL.md
sed -n '1,140p' docs/MODAL.md | cat -n

printf '\n== Button references ==\n'
rg -n --hidden --glob '!node_modules' --glob '!dist' --glob '!build' --glob '!coverage' '\bButton\b|variant="outline"|variant="destructive"' .

printf '\n== probable entry points ==\n'
git ls-files | rg '(^|/)(index|main)\.(ts|tsx|js|jsx)$|Button\.(ts|tsx|js|jsx)$|button\.(ts|tsx|js|jsx)$'

Repository: getdokan/plugin-ui

Length of output: 19123


Use Button here instead of native <button>
variant="outline" and variant="destructive" only apply to the library Button component, so these examples should import and use Button from the package entry point.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/MODAL.md` around lines 80 - 81, Update the modal example’s Cancel and
Delete controls to use the library Button component instead of native button
elements, and import Button from the package entry point. Preserve the existing
variant props and click handlers.

Comment on lines +134 to +146
const textareaRef = useRef(null);
const autoResize = () => {
const textarea = textareaRef.current;
if (textarea) {
textarea.style.height = 'auto';
textarea.style.height = textarea.scrollHeight + 'px';
}
};
<Textarea
ref={textareaRef}
onChange={(e) => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

rg -n 'forwardRef|HTMLTextAreaElement|Textarea' src/components/ui/textarea.tsx

Repository: getdokan/plugin-ui

Length of output: 262


Forward the Textarea ref or switch to a native <textarea>. src/components/ui/textarea.tsx is a plain function component, so ref={textareaRef} won’t reach the underlying element unless it uses forwardRef.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/textarea-component.md` around lines 134 - 146, Update the Textarea usage
in the autoResize example so the ref reaches the underlying DOM textarea: either
forward refs through the Textarea component implementation or replace it with a
native textarea element. Preserve the existing textareaRef and autoResize
behavior.

Comment thread docs/VARIABLES-MAPPING.md
Comment on lines +176 to +186
```
ThemeTokens (JS) → tokensToCssVariables() → inline styles on .pui-root
Base CSS variables (--primary, etc.)
@theme inline in styles.css
Tailwind theme (--color-primary, etc.)
Utilities: bg-primary, text-foreground, rounded-md, …
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Specify the diagram’s code-fence language.

The ASCII flow diagram uses an unlabeled fenced block, which triggers MD040 and may reduce syntax/rendering consistency.

Suggested fix
-```
+```text
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
```
ThemeTokens (JS) → tokensToCssVariables() → inline styles on .pui-root
Base CSS variables (--primary, etc.)
@theme inline in styles.css
Tailwind theme (--color-primary, etc.)
Utilities: bg-primary, text-foreground, rounded-md, …
```
🧰 Tools
🪛 markdownlint-cli2 (0.23.0)

[warning] 176-176: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/VARIABLES-MAPPING.md` around lines 176 - 186, Label the fenced code
block containing the ThemeTokens flow diagram as text by adding the appropriate
fence language marker, while leaving the diagram content unchanged.

Source: Linters/SAST tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants