@godxjp/ui-mcp 33.12.5 → 33.12.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1276,7 +1276,7 @@ import { Button } from "@godxjp/ui/general";
|
|
|
1276
1276
|
<Alert tone="warning">
|
|
1277
1277
|
<AlertTitle>3 \u4EF6\u306E\u6253\u523B\u6F0F\u308C\u304C\u3042\u308A\u307E\u3059</AlertTitle>
|
|
1278
1278
|
<AlertDescription>\u672C\u65E5\u4E2D\u306B\u78BA\u8A8D\u3057\u3066\u304F\u3060\u3055\u3044\u3002</AlertDescription>
|
|
1279
|
-
</Alert>`,storyPath:"feedback/alert.tsx",rules:[]},{name:"Toaster",group:"feedback",tagline:'Mount once at app root to enable toasts. Trigger them with `import { toast } from "@godxjp/ui/feedback"` \u2014 Sonner\'s API, with a close button on `toast.error` / `toast.warning` by default.',props:[{name:"position",type:'"top-right" | "top-center" | "bottom-right" | "\u2026"',defaultValue:'"bottom-right"',description:"Toast stack anchor."},{name:"richColors",type:"boolean",description:"Enable Sonner rich variant colours."},{name:"duration",type:"number",description:"Auto-dismiss time in ms for every toast. Omit it to let the `--toast-duration` token (default 4000ms) decide \u2014 read once on mount from the ThemeScope host or `<html>` (gh#1253). A per-call `toast(\u2026, { duration })` still wins."},{name:"closeButton",type:"boolean",description:'Sonner\'s switch for a close button on EVERY toast. Leave it unset for the default: `toast.error` / `toast.warning` from `@godxjp/ui/feedback` carry a close button, `toast.success` / `toast.info` stay auto-dismiss only (gh#1253). The button is named via `t("feedback.toast.close")`.'}],usage:["DO: Mount exactly ONE `<Toaster richColors />` at the app root (e.g. inside your layout or AppShell children). Multiple mounts create duplicate toast stacks \u2014 there is no provider context, only DOM portals.",'DO: Import `toast` from `"@godxjp/ui/feedback"` to fire toasts anywhere: `toast.success(\u2026)`, `toast.error(\u2026)`, `toast.warning(\u2026)`, `toast.info(\u2026)`, `toast.loading(\u2026)`, `toast.promise(\u2026)`. It is Sonner\'s own API with one house default: `toast.error` and `toast.warning` carry a close button (opt out per call with `{ closeButton: false }`), success/info stay auto-dismiss only (gh#1253).','DON\'T: Import `toast` from `"sonner"` directly \u2014 it works, but it skips the close-button default on error/warning. Also note `toast.promise` settling into an error does not gain the button; pass `closeButton` there yourself if the failure must stay dismissible.',"DO: Tune how long toasts stay with the `--toast-duration` token in the theme (default 4000ms) rather than a `duration` prop on every mount. Never truncate a toast's body \u2014 it wraps.","DO: Let the wrapper handle theming \u2014 it uses `useDocumentTheme()` to sync with the document `dark` class and `prefers-color-scheme` automatically. Never pass a hardcoded `theme` prop unless you are deliberately overriding.","DON'T: Use `Toaster` for persistent errors or blocking confirmations. Toasts auto-dismiss; they are not a substitute for `Alert` (inline persistent warnings) or `Dialog` (decisions requiring user input).","DO: Pass `position` to relocate the stack if a persistent sidebar would obscure the default `bottom-right`. The wrapper already sets a safe `mobileOffset`; don't add redundant mobile offsets unless your layout differs.","DON'T: Hand-tune `offset` to dodge a sticky action bar. The bottom offset (desktop 24px, mobile `--toast-mobile-offset`) already adds `--toast-sticky-bar-height`, which a visible `PageContainer stickyFooter` or `MobileShell` action/tab bar publishes at runtime, so the stack clears it on its own (gh#1271). For bottom chrome the library does not render (an app's own fixed bar), set `--toast-offset-bottom` once in theme.css \u2014 it is added on desktop and mobile alike."],useCases:['After a successful form save (invoice, journal entry, vendor record) \u2014 show `toast.success("\u4FDD\u5B58\u3057\u307E\u3057\u305F")` to confirm without blocking navigation.','After a background job is enqueued (e.g. bulk sync or export) \u2014 show `toast.info("\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3092\u958B\u59CB\u3057\u307E\u3057\u305F")` then later update with `toast.promise()` to track completion.',"Mutation error fallback when the error is transient and retrying is the right UX \u2014 show `toast.error(message)` instead of replacing page content; reserve `AlertMutationFeedback` for inline, persistent error display inside a form.",'Soft destructive action confirmation outcome \u2014 e.g. "\u524A\u9664\u3057\u307E\u3057\u305F" after an item is removed, paired with an undo action via `toast("\u2026", { action: { label: \'\u5143\u306B\u623B\u3059\', onClick: undo } })`.','OAuth / session expiry warnings \u2014 surface a brief `toast.warning("\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u6709\u52B9\u671F\u9650\u304C\u8FD1\u3065\u3044\u3066\u3044\u307E\u3059")` without interrupting the user\'s current form state.'],related:["Alert \u2014 use for persistent, inline feedback that must stay visible (validation summaries, page-level warnings, destructive notices). Unlike Toaster, Alert does not auto-dismiss and lives in the document flow.","AlertMutationFeedback \u2014 use when you have a TanStack `useMutation` result and want an inline error + retry UI inside a form or card. Renders nothing on success/idle; pairs naturally with a `toast.success` in `onSuccess`.","Dialog \u2014 use when the user must make a conscious decision (confirm delete, resolve conflict) before proceeding. Toaster toasts are fire-and-forget; Dialog blocks until the user responds."],example:`// app root \u2014 mount once
|
|
1279
|
+
</Alert>`,storyPath:"feedback/alert.tsx",rules:[]},{name:"Toaster",group:"feedback",tagline:'Mount once at app root to enable toasts. Trigger them with `import { toast } from "@godxjp/ui/feedback"` \u2014 Sonner\'s API, with a close button on `toast.error` / `toast.warning` by default.',props:[{name:"position",type:'"top-right" | "top-center" | "bottom-right" | "\u2026"',defaultValue:'"bottom-right"',description:"Toast stack anchor."},{name:"richColors",type:"boolean",description:"Enable Sonner rich variant colours."},{name:"expand",type:"boolean",defaultValue:"true",description:"Draw every visible toast whole, stacked with a gap. Default `true` (gh#1387): Sonner's collapsed deck (`expand={false}`) keeps earlier toasts as cards peeking behind the front one with their text hidden, which reads as an empty box. Pass `expand={false}` to opt back into the deck."},{name:"duration",type:"number",description:"Auto-dismiss time in ms for every toast. Omit it to let the `--toast-duration` token (default 4000ms) decide \u2014 read once on mount from the ThemeScope host or `<html>` (gh#1253). A per-call `toast(\u2026, { duration })` still wins."},{name:"closeButton",type:"boolean",description:'Sonner\'s switch for a close button on EVERY toast. Leave it unset for the default: `toast.error` / `toast.warning` from `@godxjp/ui/feedback` carry a close button, `toast.success` / `toast.info` stay auto-dismiss only (gh#1253). The button is named via `t("feedback.toast.close")`.'}],usage:["DO: Mount exactly ONE `<Toaster richColors />` at the app root (e.g. inside your layout or AppShell children). Multiple mounts create duplicate toast stacks \u2014 there is no provider context, only DOM portals.",'DO: Import `toast` from `"@godxjp/ui/feedback"` to fire toasts anywhere: `toast.success(\u2026)`, `toast.error(\u2026)`, `toast.warning(\u2026)`, `toast.info(\u2026)`, `toast.loading(\u2026)`, `toast.promise(\u2026)`. It is Sonner\'s own API with one house default: `toast.error` and `toast.warning` carry a close button (opt out per call with `{ closeButton: false }`), success/info stay auto-dismiss only (gh#1253).','DON\'T: Import `toast` from `"sonner"` directly \u2014 it works, but it skips the close-button default on error/warning. Also note `toast.promise` settling into an error does not gain the button; pass `closeButton` there yourself if the failure must stay dismissible.',"DO: Tune how long toasts stay with the `--toast-duration` token in the theme (default 4000ms) rather than a `duration` prop on every mount. Never truncate a toast's body \u2014 it wraps.","DO: Let the wrapper handle theming \u2014 it uses `useDocumentTheme()` to sync with the document `dark` class and `prefers-color-scheme` automatically. Never pass a hardcoded `theme` prop unless you are deliberately overriding.","DON'T: Use `Toaster` for persistent errors or blocking confirmations. Toasts auto-dismiss; they are not a substitute for `Alert` (inline persistent warnings) or `Dialog` (decisions requiring user input).","DO: Pass `position` to relocate the stack if a persistent sidebar would obscure the default `bottom-right`. The wrapper already sets a safe `mobileOffset`; don't add redundant mobile offsets unless your layout differs.","DON'T: Hand-tune `offset` to dodge a sticky action bar. The bottom offset (desktop 24px, mobile `--toast-mobile-offset`) already adds `--toast-sticky-bar-height`, which a visible `PageContainer stickyFooter` or `MobileShell` action/tab bar publishes at runtime, so the stack clears it on its own (gh#1271). For bottom chrome the library does not render (an app's own fixed bar), set `--toast-offset-bottom` once in theme.css \u2014 it is added on desktop and mobile alike."],useCases:['After a successful form save (invoice, journal entry, vendor record) \u2014 show `toast.success("\u4FDD\u5B58\u3057\u307E\u3057\u305F")` to confirm without blocking navigation.','After a background job is enqueued (e.g. bulk sync or export) \u2014 show `toast.info("\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u3092\u958B\u59CB\u3057\u307E\u3057\u305F")` then later update with `toast.promise()` to track completion.',"Mutation error fallback when the error is transient and retrying is the right UX \u2014 show `toast.error(message)` instead of replacing page content; reserve `AlertMutationFeedback` for inline, persistent error display inside a form.",'Soft destructive action confirmation outcome \u2014 e.g. "\u524A\u9664\u3057\u307E\u3057\u305F" after an item is removed, paired with an undo action via `toast("\u2026", { action: { label: \'\u5143\u306B\u623B\u3059\', onClick: undo } })`.','OAuth / session expiry warnings \u2014 surface a brief `toast.warning("\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u6709\u52B9\u671F\u9650\u304C\u8FD1\u3065\u3044\u3066\u3044\u307E\u3059")` without interrupting the user\'s current form state.'],related:["Alert \u2014 use for persistent, inline feedback that must stay visible (validation summaries, page-level warnings, destructive notices). Unlike Toaster, Alert does not auto-dismiss and lives in the document flow.","AlertMutationFeedback \u2014 use when you have a TanStack `useMutation` result and want an inline error + retry UI inside a form or card. Renders nothing on success/idle; pairs naturally with a `toast.success` in `onSuccess`.","Dialog \u2014 use when the user must make a conscious decision (confirm delete, resolve conflict) before proceeding. Toaster toasts are fire-and-forget; Dialog blocks until the user responds."],example:`// app root \u2014 mount once
|
|
1280
1280
|
import { Toaster } from "@godxjp/ui/feedback";
|
|
1281
1281
|
<>{children}<Toaster richColors /></>
|
|
1282
1282
|
|
|
@@ -1291,7 +1291,7 @@ toast.error("\u4FDD\u5B58\u306B\u5931\u6557\u3057\u307E\u3057\u305F"); // also c
|
|
|
1291
1291
|
{ value: "overview", label: "\u6982\u8981", content: "\u6982\u8981\u30B3\u30F3\u30C6\u30F3\u30C4" },
|
|
1292
1292
|
{ value: "history", label: "\u5C65\u6B74", content: "\u5C65\u6B74\u30B3\u30F3\u30C6\u30F3\u30C4" },
|
|
1293
1293
|
]}
|
|
1294
|
-
/>`,storyPath:"navigation/tabs.tsx",rules:[]},{name:"Pagination",subParts:["PaginationContent","PaginationEllipsis","PaginationItem","PaginationLink","PaginationNext","PaginationPrevious"],group:"navigation",tagline:"Offset/page-based pagination bar. Sits below a table card. Keyboard focus uses the shared inset ring in clipping surfaces; scrollports reveal partially clipped keyboard targets without changing their layout.",props:[{name:"ariaLabel",type:"string",description:"T\xEAn kh\u1EA3 truy c\u1EADp c\u1EE7a landmark ph\xE2n trang. B\u1EAFt bu\u1ED9c khi m\u1ED9t trang c\xF3 nhi\u1EC1u b\u1ED9 ph\xE2n trang."},{name:"value",type:"number",defaultValue:"1",description:"Current page (1-indexed)."},{name:"total",type:"number",description:"Total number of items."},{name:"pageSize",type:"number",defaultValue:"10",description:"Items per page."},{name:"showTotal",type:"boolean | (total, range) => ReactNode",description:"Show total count, or a custom label fn."},{name:"onValueChange",type:"(page: number, pageSize: number) => void",description:"Page / page-size change handler."},{name:"pageSizeOptions",type:"number[]",description:"Selectable page sizes shown in the size changer."},{name:"showSizeChanger",type:"boolean",description:"Show the page-size selector beside the pager."},{name:"hideOnSinglePage",type:"boolean",defaultValue:"true",description:"Hide the control when there is nothing to page through \u2014 zero items OR exactly one page. Set false to opt in to the bar on a single page (e.g. to keep showTotal visible); total=0 is always hidden."},{name:"simple",type:"boolean",description:"Compact form for narrow contexts \u2014 Prev / n\xB7N / Next, no page-number buttons. The intentional mobile transformation (desktop never wraps)."},{name:"showQuickJumper",type:"boolean | { goButton?: React.ReactNode }",description:"Ant Design `showQuickJumper` \u2014 a 'go to page' number field at the inline end of the bar. Enter (or the optional `goButton`) commits, clamped into [1, pageCount]; a non-numeric commit is ignored rather than jumping to NaN. The field is named by a real `<label htmlFor>`, not an aria-label."},{name:"size",type:'"sm" | "md"',defaultValue:'"md"',description:'Ant Design `size` (`small` \u2192 `sm`, `middle` \u2192 `md`). Implemented as ONE local `--control-height` on the bar, so the page buttons, the size-changer trigger and the quick-jumper field shrink together and cannot drift apart. `sm` reads `--control-height-sm` of the surrounding density scope (knob `--pagination-control-height-sm`, default `initial`), so a small pager in a compact DataTable matches its size="sm" toolbar controls.'},{name:"align",type:'"start" | "center" | "end"',defaultValue:'"end"',description:'Ant Design `align`, on the logical inline axis. `end` keeps the long-standing table-footer position. With `align="end"` the `showTotal` label sits BESIDE the page buttons (antd); `start` / `center` keep the total pushed to the inline start.'},{name:"responsive",type:"boolean",defaultValue:"true",description:"Ant Design `responsive`. Collapses the bar to its `simple` form below the library's single mobile breakpoint (`useIsMobile`, max-width 767px) instead of leaving a number strip wider than the phone to scroll. `simple` always wins; pass `responsive={false}` to pin the full pager at every width."},{name:"disabled",type:"boolean",description:"Disable all navigation controls."},{name:"aria-label",type:"string",description:`Override the nav landmark's accessible name (defaults to a localized "Pagination"). Required when more than one Pagination renders on the same page/view \u2014 two nav landmarks sharing one name/role fail landmark-unique.`}],usage:["DO always control Pagination externally: store `value` (page) and `pageSize` in React state (or URL params), and update both in the `onValueChange(page, pageSize)` callback. Pagination is fully controlled \u2014 it has no internal state and will not move unless `value` changes.","DO let Pagination hide itself for zero items and single pages (`hideOnSinglePage`, default true) \u2014 it is navigation between multiple result pages. Render it inside a table footer only in the DATA state: never during loading, empty, error, or an unmet prerequisite. Pass `hideOnSinglePage={false}` only when you still want the bar on one page to keep `showTotal` visible.","DO trust Pagination to stay ONE horizontal row on desktop (it never wraps). For genuinely narrow viewports use `simple` for the intentional compact transformation rather than letting controls wrap.","DO pass `total` as the raw item count (not page count). The component computes `Math.ceil(total / pageSize)` internally; passing a pre-computed page count as `total` will over-paginate.","DO use `showSizeChanger` together with `pageSizeOptions` when the user needs density control (default options are [10, 20, 50, 100]). When `showSizeChanger` is omitted the page-size Select is not rendered at all \u2014 do NOT hand-roll your own Select beside Pagination.","DO use `simple` mode for compact contexts (mobile, sidebars, sheet footers) \u2014 it renders Prev / `n / total` / Next with no page-number buttons. Use the full form for primary admin list pages.","DO use `showTotal` to surface item counts: pass `true` for the built-in i18n label, or a function `(total, [from, to]) => ReactNode` for a custom range label like '1\u201310 of 342 invoices'. Never hard-code a total string beside the component.","DON'T use Pagination for cursor- or infinite-scroll-based lists. Pagination is strictly offset/page-based (`value` is a page number). For cursor pagination inside a DataTable use `DataTable.Pagination`; for infinite scroll use `InfiniteQueryState`.","NOTE the page strip scrolls horizontally rather than wrapping, and its page buttons are normally the keyboard route to that overflow. Disable the whole bar (`disabled`) and there is no such route, so the strip takes `tabindex=0` itself to stay keyboard-scrollable (WCAG 2.1.1). Nothing to configure \u2014 just don't strip the attribute in consumer CSS/JS."],useCases:["Server-paged DataTable: do NOT place a Pagination below the card \u2014 pass `pagination={{ total, current, pageSize, onChange }}` to DataTable and it renders this component in its own footer (total + page numbers, density-sized).","Standalone offset-paginated admin list pages (e.g. invoice list, customer list, transaction history) rendered outside DataTable \u2014 place Pagination below the table card, outside the card border, with `showTotal` and optionally `showSizeChanger`.","Search results pages where the backend accepts `page` + `per_page` query parameters and returns a total count \u2014 wire `value` and `pageSize` to URL search params so the URL is shareable and browser-back works.","Reports and filtered data grids where the user needs to export 'all selected pages': `showTotal` with a custom function lets you show '1\u201350 of 1 200 rows' so the user understands the scope before exporting.","Compact modal or sheet footers with a long list (e.g. selecting from a product catalog inside a dialog) \u2014 use `simple` mode to save horizontal space while keeping navigation accessible.","DataTable instances where the server returns an offset-based total and `DataTable.Pagination` is not being used: attach a standalone Pagination below the card and pass the same `page` / `pageSize` state to both the DataTable `data` prop and the API fetch."],related:["DataTable.Pagination \u2014 use instead of standalone Pagination when the list is rendered inside a DataTable compound and uses cursor-based navigation (cursor + hasMore + onChange). DataTable.Pagination handles First/Next without page arithmetic; standalone Pagination requires a known total.","InfiniteQueryState \u2014 use for infinite-scroll / load-more lists driven by useInfiniteQuery. It auto-manages skeleton, empty, and error states; Pagination is inappropriate here because there is no discrete page number.","DataTable \u2014 when offset pagination is needed inside DataTable, prefer composing DataTable with a standalone Pagination below the card rather than DataTable.Pagination if the API is offset-based and returns a total count. DataTable itself does not paginate; you supply `data` for the current page.","SearchInput \u2014 often placed in the same toolbar as Pagination. Resetting `value` to page 1 inside the search `onSearchChange` handler is mandatory; forgetting this is the most common bug when combining search and Pagination."],example:`import { Pagination } from "@godxjp/ui/navigation";
|
|
1294
|
+
/>`,storyPath:"navigation/tabs.tsx",rules:[]},{name:"Pagination",subParts:["PaginationContent","PaginationEllipsis","PaginationItem","PaginationLink","PaginationNext","PaginationPrevious"],group:"navigation",tagline:"Offset/page-based pagination bar. Sits below a table card. Keyboard focus uses the shared inset ring in clipping surfaces; scrollports reveal partially clipped keyboard targets without changing their layout.",props:[{name:"ariaLabel",type:"string",description:"T\xEAn kh\u1EA3 truy c\u1EADp c\u1EE7a landmark ph\xE2n trang. B\u1EAFt bu\u1ED9c khi m\u1ED9t trang c\xF3 nhi\u1EC1u b\u1ED9 ph\xE2n trang."},{name:"value",type:"number",defaultValue:"1",description:"Current page (1-indexed)."},{name:"total",type:"number",description:"Total number of items."},{name:"pageSize",type:"number",defaultValue:"10",description:"Items per page."},{name:"showTotal",type:"boolean | (total, range) => ReactNode",description:"Show total count, or a custom label fn."},{name:"onValueChange",type:"(page: number, pageSize: number) => void",description:"Page / page-size change handler."},{name:"pageSizeOptions",type:"number[]",description:"Selectable page sizes shown in the size changer (default [10, 20, 50, 100]). The current `pageSize` is always listed: one missing from the options is added in ascending order (antd parity, gh#1386)."},{name:"showSizeChanger",type:"boolean",description:"Show the page-size selector beside the pager."},{name:"hideOnSinglePage",type:"boolean",defaultValue:"true",description:"Hide the control when there is nothing to page through \u2014 zero items OR exactly one page. Set false to opt in to the bar on a single page (e.g. to keep showTotal visible); total=0 is always hidden."},{name:"simple",type:"boolean",description:"Compact form for narrow contexts \u2014 Prev / n\xB7N / Next, no page-number buttons. The intentional mobile transformation (desktop never wraps)."},{name:"showQuickJumper",type:"boolean | { goButton?: React.ReactNode }",description:"Ant Design `showQuickJumper` \u2014 a 'go to page' number field at the inline end of the bar. Enter (or the optional `goButton`) commits, clamped into [1, pageCount]; a non-numeric commit is ignored rather than jumping to NaN. The field is named by a real `<label htmlFor>`, not an aria-label."},{name:"size",type:'"sm" | "md"',defaultValue:'"md"',description:'Ant Design `size` (`small` \u2192 `sm`, `middle` \u2192 `md`). Implemented as ONE local `--control-height` on the bar, so the page buttons, the size-changer trigger and the quick-jumper field shrink together and cannot drift apart. `sm` reads `--control-height-sm` of the surrounding density scope (knob `--pagination-control-height-sm`, default `initial`), so a small pager in a compact DataTable matches its size="sm" toolbar controls.'},{name:"align",type:'"start" | "center" | "end"',defaultValue:'"end"',description:'Ant Design `align`, on the logical inline axis. `end` keeps the long-standing table-footer position. With `align="end"` the `showTotal` label sits BESIDE the page buttons (antd); `start` / `center` keep the total pushed to the inline start.'},{name:"responsive",type:"boolean",defaultValue:"true",description:"Ant Design `responsive`. Collapses the bar to its `simple` form below the library's single mobile breakpoint (`useIsMobile`, max-width 767px) instead of leaving a number strip wider than the phone to scroll. `simple` always wins; pass `responsive={false}` to pin the full pager at every width."},{name:"disabled",type:"boolean",description:"Disable all navigation controls."},{name:"aria-label",type:"string",description:`Override the nav landmark's accessible name (defaults to a localized "Pagination"). Required when more than one Pagination renders on the same page/view \u2014 two nav landmarks sharing one name/role fail landmark-unique.`}],usage:["DO always control Pagination externally: store `value` (page) and `pageSize` in React state (or URL params), and update both in the `onValueChange(page, pageSize)` callback. Pagination is fully controlled \u2014 it has no internal state and will not move unless `value` changes.","DO let Pagination hide itself for zero items and single pages (`hideOnSinglePage`, default true) \u2014 it is navigation between multiple result pages. Render it inside a table footer only in the DATA state: never during loading, empty, error, or an unmet prerequisite. Pass `hideOnSinglePage={false}` only when you still want the bar on one page to keep `showTotal` visible.","DO trust Pagination to stay ONE horizontal row on desktop (it never wraps). For genuinely narrow viewports use `simple` for the intentional compact transformation rather than letting controls wrap.","DO pass `total` as the raw item count (not page count). The component computes `Math.ceil(total / pageSize)` internally; passing a pre-computed page count as `total` will over-paginate.","DO use `showSizeChanger` together with `pageSizeOptions` when the user needs density control (default options are [10, 20, 50, 100]). When `showSizeChanger` is omitted the page-size Select is not rendered at all \u2014 do NOT hand-roll your own Select beside Pagination.","DO use `simple` mode for compact contexts (mobile, sidebars, sheet footers) \u2014 it renders Prev / `n / total` / Next with no page-number buttons. Use the full form for primary admin list pages.","DO use `showTotal` to surface item counts: pass `true` for the built-in i18n label, or a function `(total, [from, to]) => ReactNode` for a custom range label like '1\u201310 of 342 invoices'. Never hard-code a total string beside the component.","DON'T use Pagination for cursor- or infinite-scroll-based lists. Pagination is strictly offset/page-based (`value` is a page number). For cursor pagination inside a DataTable use `DataTable.Pagination`; for infinite scroll use `InfiniteQueryState`.","NOTE the page strip scrolls horizontally rather than wrapping, and its page buttons are normally the keyboard route to that overflow. Disable the whole bar (`disabled`) and there is no such route, so the strip takes `tabindex=0` itself to stay keyboard-scrollable (WCAG 2.1.1). Nothing to configure \u2014 just don't strip the attribute in consumer CSS/JS."],useCases:["Server-paged DataTable: do NOT place a Pagination below the card \u2014 pass `pagination={{ total, current, pageSize, onChange }}` to DataTable and it renders this component in its own footer (total + page numbers, density-sized).","Standalone offset-paginated admin list pages (e.g. invoice list, customer list, transaction history) rendered outside DataTable \u2014 place Pagination below the table card, outside the card border, with `showTotal` and optionally `showSizeChanger`.","Search results pages where the backend accepts `page` + `per_page` query parameters and returns a total count \u2014 wire `value` and `pageSize` to URL search params so the URL is shareable and browser-back works.","Reports and filtered data grids where the user needs to export 'all selected pages': `showTotal` with a custom function lets you show '1\u201350 of 1 200 rows' so the user understands the scope before exporting.","Compact modal or sheet footers with a long list (e.g. selecting from a product catalog inside a dialog) \u2014 use `simple` mode to save horizontal space while keeping navigation accessible.","DataTable instances where the server returns an offset-based total and `DataTable.Pagination` is not being used: attach a standalone Pagination below the card and pass the same `page` / `pageSize` state to both the DataTable `data` prop and the API fetch."],related:["DataTable.Pagination \u2014 use instead of standalone Pagination when the list is rendered inside a DataTable compound and uses cursor-based navigation (cursor + hasMore + onChange). DataTable.Pagination handles First/Next without page arithmetic; standalone Pagination requires a known total.","InfiniteQueryState \u2014 use for infinite-scroll / load-more lists driven by useInfiniteQuery. It auto-manages skeleton, empty, and error states; Pagination is inappropriate here because there is no discrete page number.","DataTable \u2014 when offset pagination is needed inside DataTable, prefer composing DataTable with a standalone Pagination below the card rather than DataTable.Pagination if the API is offset-based and returns a total count. DataTable itself does not paginate; you supply `data` for the current page.","SearchInput \u2014 often placed in the same toolbar as Pagination. Resetting `value` to page 1 inside the search `onSearchChange` handler is mandatory; forgetting this is the most common bug when combining search and Pagination."],example:`import { Pagination } from "@godxjp/ui/navigation";
|
|
1295
1295
|
|
|
1296
1296
|
<Pagination value={page} total={filtered.length} pageSize={10} showTotal onValueChange={(p) => setPage(p)} />`,storyPath:"navigation/pagination.tsx",rules:[40]},{name:"DropdownMenu",subParts:["DropdownMenuCheckboxItem","DropdownMenuContent","DropdownMenuGroup","DropdownMenuItem","DropdownMenuLabel","DropdownMenuPortal","DropdownMenuRadioGroup","DropdownMenuRadioItem","DropdownMenuSeparator","DropdownMenuShortcut","DropdownMenuSub","DropdownMenuSubContent","DropdownMenuSubTrigger","DropdownMenuTrigger"],group:"navigation",tagline:"Dropdown menu (react-aria). Compose DropdownMenu/DropdownMenuTrigger/DropdownMenuContent/DropdownMenuItem/DropdownMenuSeparator. `trigger` picks the gestures \u2014 click (default), hover, or contextMenu, which is what replaced the deleted ContextMenu component.",props:[{name:"width",type:'"trigger" | "auto" | "sm" | "md" | "lg"',description:"On DropdownMenuContent: match the trigger, fit content, or use a token width. Omit to keep the default minimum."},{name:"open",type:"boolean",description:"Controlled open state (Ant Design `open`)."},{name:"trigger",type:'("click" | "hover" | "contextMenu")[]',defaultValue:'["click"]',description:'On the ROOT. Ant Design `trigger` \u2014 the gestures that open the menu, and more than one may be live at once. `contextMenu` opens AT the pointer and suppresses the browser\'s own menu; it is the replacement for the ContextMenu component deleted in v23, and antd expresses right-click menus the same way. The default is `["click"]`, not antd\'s `["hover"]`. The keyboard opener survives every mode: Enter/Space/ArrowDown for click and hover, Shift+F10 or the ContextMenu key for contextMenu \u2014 so a gesture list can never produce a pointer-only menu (WCAG 2.1.1).'},{name:"disabled",type:"boolean",description:"On the ROOT. Ant Design `disabled` \u2014 no gesture opens the menu (antd implements it by emptying the trigger list). The trigger's own `disabled` still works for the button case."},{name:"mouseEnterDelay",type:"number",defaultValue:"0.15",description:'On the ROOT, in SECONDS (antd\'s unit). Hover dwell before a `trigger={["hover"]}` menu opens.'},{name:"mouseLeaveDelay",type:"number",defaultValue:"0.1",description:"On the ROOT, in SECONDS. Grace period after the pointer leaves before a hover menu closes \u2014 it is what lets the reader cross the gap from the trigger onto the menu, so do not set it to 0."},{name:"shortcut",type:"string",description:'On the ROOT. A page-level key that OPENS the menu \u2014 `"f"` for a filter menu, `"mod+shift+v"` for a view menu (gh#1264). Same combo syntax and guard as SearchInput/CommandPalette: a bare key is ignored while focus is in an editable element or an IME is composing. Off by default; ignored while `disabled`. The trigger gets `aria-keyshortcuts` automatically (an explicit consumer value wins); show the key visibly too (e.g. `DropdownMenuShortcut`). Never fires from inside a dialog, menu or listbox that does not contain the menu (gh#1267).'},{name:"onOpenChange",type:"(open: boolean) => void",description:"Open-state change handler (Ant Design `onOpenChange`)."},{name:"placement",type:'"top" | "topStart" | "topEnd" | "bottom" | "bottomStart" | "bottomEnd"',description:"On DropdownMenuContent. Ant Design `placement`, spelled on the LOGICAL inline axis (antd's `bottomLeft` is `bottomStart` here), so an RTL app anchors on the correct edge with no second value. It is sugar over Radix's `side` + `align`, and an explicitly passed `side`/`align` still wins. antd's inline-side placements (`left*`/`right*`) are deliberately absent \u2014 Radix's `side` is physical and this library ships no DirectionProvider, so they would open on the wrong edge in RTL; pass Radix's own `side` if you knowingly want a physical one."},{name:"arrow",type:"boolean",description:"On DropdownMenuContent. Ant Design `arrow` \u2014 paints the pointer at the anchored edge (default off). Sized from --dropdown-arrow-{width,height,background} rather than Radix's built-in 10\xD75."},{name:"description",type:"React.ReactNode",description:'On DropdownMenuItem (gh#1246). A muted second line under the label \u2014 the two-line row, parity with `MegaMenuLinkProp.description`. Rendered as react-aria `<Text slot="description">` (`data-slot="dropdown-menu-item-description"`), so the row\'s accessible NAME stays the label and the description becomes its `aria-describedby`. A string label is handed to the collection as `textValue`, so typeahead still reaches the row by its label; pass `textValue` yourself when the label is not a plain string. Sized by --menu-item-description-{font-size,space-block}; rows without one keep the one-line height.'}],usage:["DO compose the full sub-part tree: DropdownMenu (root) \u2192 DropdownMenuTrigger (with asChild to delegate to your Button/icon) \u2192 DropdownMenuContent \u2192 DropdownMenuItem / DropdownMenuSeparator / DropdownMenuLabel / DropdownMenuGroup. Omitting any level (e.g. rendering DropdownMenuContent without DropdownMenu as ancestor) breaks Radix context and the menu will not open.","DO use DropdownMenuTrigger with asChild and pass a godx-ui Button or icon Button as the child \u2014 never render a raw <button> or <div> as the trigger, and never omit asChild when the child is already a button-like element (double-button nesting breaks a11y).","DO use variant='destructive' on DropdownMenuItem for irreversible actions (delete, revoke, void) \u2014 this applies the semantic destructive colour token automatically without any className override.","DO use DropdownMenuSub + DropdownMenuSubTrigger + DropdownMenuSubContent for nested sub-menus (e.g. 'Export' \u2192 'CSV', 'PDF'). The ChevronRight icon is rendered automatically by DropdownMenuSubTrigger \u2014 do not add your own.","DO use DropdownMenuCheckboxItem (with checked + onCheckedChange) or DropdownMenuRadioGroup + DropdownMenuRadioItem for toggle/selection menus such as column visibility or active view. These items manage their own checked indicator \u2014 do not layer a Checkbox or RadioGroup inside a plain DropdownMenuItem.","DON'T put anything but collection nodes directly inside DropdownMenuContent / DropdownMenuGroup / DropdownMenuRadioGroup \u2014 only DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuGroup, DropdownMenuSub, or a component that returns one. A leading icon or a bare text label goes INSIDE an item. react-aria builds the menu through a stand-in document that cannot create SVG or text nodes, so an icon placed beside the items throws during render (`createElementNS is not a function`); the library contains that throw so the page survives, but the menu comes up EMPTY and the console says why (gh#637).","DON'T use DropdownMenu for form submission \u2014 items fire onSelect callbacks, not form field values. There is no name prop for native form submission. If a menu selection must feed a form field, lift state into a controlled value and wire a hidden Input or use Select instead.",'DO use `trigger={["contextMenu"]}` for a right-click menu on a row, card or tile \u2014 there is no ContextMenu component any more (deleted in v23). Give that target something focusable and an interactive role: the menu must be reachable with Shift+F10, and react-aria warns in dev when an `asChild` trigger has neither.',"DON'T put actions ONLY behind `contextMenu`. Right-click is undiscoverable for new users and absent on touch (it falls back to long-press), so mirror anything critical in a visible click trigger.",'DO keep `mouseLeaveDelay` non-zero on `trigger={["hover"]}`: closing the instant the pointer leaves the trigger makes the menu impossible to reach, because the pointer has to cross the gap to get there.'],useCases:["Row action menu in a DataTable: a '...' icon Button opens a DropdownMenu with Edit, Duplicate, DropdownMenuSeparator, then Delete (variant='destructive') \u2014 keeps the row compact and avoids inline button clutter.","Topbar / avatar chip: a user-avatar Button triggers a DropdownMenu with Profile, Settings, DropdownMenuSeparator, Sign out \u2014 standard app-shell pattern for account actions.","Bulk-action toolbar: after selecting rows, an 'Actions' Button opens a DropdownMenu with Approve, Reject, Export \u2014 prevents the toolbar from overflowing with individual buttons.","Column visibility toggle in a report table: a 'Columns' Button opens a DropdownMenu whose items are DropdownMenuCheckboxItem entries, letting users show/hide columns without a Dialog.","Quick status change on an accounting entry: a Badge-like trigger opens a DropdownMenu with DropdownMenuRadioGroup items (Draft, Posted, Voided) so the user can transition status without navigating away.",'Right-click actions on a DataTable row or a file tile: `trigger={["click", "contextMenu"]}` puts the same menu behind the row\'s kebab AND a right-click anywhere on the row, so the accelerator and the discoverable affordance stay one menu.','Hover-opened menu on a toolbar entry (`trigger={["hover"]}`) where the pointer is already travelling \u2014 the keyboard still opens it with Enter.'],related:["Popover \u2014 use Popover when the floating panel needs arbitrary layout (filter forms, date pickers, rich content grids). Use DropdownMenu only for a list of discrete clickable actions or toggle items; DropdownMenu has no layout flexibility beyond label/separator/group.","Command \u2014 use Command (cmdk) when the list is large, needs fuzzy-search filtering, or acts as a keyboard-driven command palette. DropdownMenu has no built-in search input; once the list exceeds ~8 items or needs filtering, switch to Command (often inside a Popover).","Select \u2014 use Select when the purpose is choosing a value to submit in a form field (has a name prop for native form submission, renders a hidden select for a11y). Use DropdownMenu when the purpose is triggering actions, not picking a form value.","Sidebar \u2014 use Sidebar for persistent left-rail navigation. DropdownMenu is transient (opens on click, dismisses on select); Sidebar is always-visible structural navigation."],example:`import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator } from "@godxjp/ui/navigation";
|
|
1297
1297
|
import { Button } from "@godxjp/ui/general";
|
|
@@ -7977,7 +7977,7 @@ export default function Demo() {
|
|
|
7977
7977
|
</PageContainer>
|
|
7978
7978
|
);
|
|
7979
7979
|
}
|
|
7980
|
-
`};var p={name:"@godxjp/ui-mcp",version:"33.12.5",godxUiCompatibility:"33.12.x",description:"Model Context Protocol server for @godxjp/ui \u2014 gives Claude Code / Codex CLI / Cursor / any MCP-aware agent live access to the component catalog, prop vocabulary, design tokens, 45 cardinal rules, copy-paste-ready patterns, 12 design / taste skills synthesised from Leonxlnx/taste-skill, 20+ anti-AI-tell patterns, and a 50-check redesign audit \u2014 token-efficient (list \u2192 drill-down).",type:"module",main:"./dist/index.js",module:"./dist/index.js",types:"./dist/index.d.ts",bin:{"godx-ui-mcp":"./dist/index.js"},files:["dist","README.md"],publishConfig:{registry:"https://registry.npmjs.org/",access:"public"},repository:{type:"git",url:"git+https://github.com/godx-jp/godxjp-ui.git",directory:"mcp"},homepage:"https://github.com/godx-jp/godxjp-ui/tree/main/mcp#readme",license:"Apache-2.0",scripts:{build:"tsup",dev:"tsup --watch",start:"node dist/index.js",inspect:"npx @modelcontextprotocol/inspector node dist/index.js","type-check":"tsc --noEmit",test:"vitest run",prepublishOnly:"npm run build"},dependencies:{"@modelcontextprotocol/sdk":"^1.29.0",zod:"^4.4.3"},devDependencies:{"@types/node":"^22.10.0",tsup:"^8.5.1",typescript:"^6.0.3",vitest:"^4.1.6"},keywords:["mcp","model-context-protocol","godxjp","ui","design-system","react","claude","cursor"],author:"GoDX (https://godx.jp)",bugs:{url:"https://github.com/godx-jp/godxjp-ui/issues"}};var O=[{name:"list_skills",description:"List every design/taste skill bundled by this MCP (id + name + whenToUse + section ids). Use FIRST to discover skills; then `get_skill_section` to drill in.",inputSchema:{type:"object",properties:{}}},{name:"list_primitives",description:'List every @godxjp/ui primitive/composite/shell (group + tagline per entry). Optionally filter by group. Then `get_component` for one\'s full API. Core only by default \u2014 pass tier="lab" for the opt-in @godxjp/ui/lab components.',inputSchema:{type:"object",properties:{tier:{type:"string",enum:["core","lab","all"],description:'Default "core". "lab" lists the opt-in `@godxjp/ui/lab` components (niche, kept and tested, not in the default context); "all" lists both.'},group:{type:"string",enum:["general","layout","data-display","data-entry","feedback","navigation","composites","shell","providers"]}}}},{name:"list_utilities",description:'List every NON-component public export of @godxjp/ui \u2014 hooks, helper functions and constants (cn, formatDate, formatCurrency, toast, useDebouncedValue, buttonVariants, CHART_COLORS, SHOW_PARENT \u2026). Reach for this before hand-writing a className merger, a date/money formatter, a debounce hook or a chart palette: two products in this org each re-implemented `cn` because it could not be found. Optionally filter by kind. Then `get_component name="<name>"` for its signature, usage and example.',inputSchema:{type:"object",properties:{kind:{type:"string",enum:["hook","function","value"],description:"hook = only legal inside a component body; function = callable anywhere; value = a constant to read."}}}},{name:"list_patterns",description:"List every canonical copy-paste code pattern (signup-form, settings-page, data-table-page, async-data-state, confirm-destructive, \u2026); common aliases resolve too. Use before `get_pattern`.",inputSchema:{type:"object",properties:{}}},{name:"list_anti_ai_tells",description:"List every AI-tell pattern to AVOID (optionally by category). Use to self-audit a design before shipping; then `get_anti_ai_tell` for the fix.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["visual","layout","copy","interaction","imagery","structure"]}}}},{name:"list_redesign_checks",description:"List the redesign audit checklist (50+ checks; optionally by category). Use when auditing an existing project; then `get_redesign_check` for a symptom's fix.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["typography","color-surface","layout","interactivity","content","components","iconography","code-quality","omissions"]}}}},{name:"list_audit_rules",description:"List the LOCAL static ui-audit rules (scripts/ui-audit.mjs) to run BEFORE any visual review \u2014 each cites the standard it enforces (WCAG/WAI-ARIA/Intl/ISO/IANA/CSS-Logical) + a fix + the run command. Optionally by category.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["tokens","composition","api","a11y","i18n","rtl","copy"]}}}},{name:"list_visual_checks",description:"List the RUNTIME visual-audit checks (scripts/visual-audit.mjs \u2014 Playwright + axe-core) to run against the RUNNING app: contrast/ARIA (axe), target size, rendered-accent chroma, DOM emoji, banner layout. Needs a browser (vs list_audit_rules, static). Optionally by category.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["a11y","color","i18n","layout"]}}}},{name:"get_anti_ai_tell",description:"Fetch ONE anti-AI-tell \u2014 full body + concrete fix. Use after `list_anti_ai_tells`.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Exact tell name from list_anti_ai_tells."}},required:["name"]}},{name:"get_redesign_check",description:"Fetch redesign check(s) matching a symptom snippet. Returns full fix + UI note. Use after `list_redesign_checks`.",inputSchema:{type:"object",properties:{symptom:{type:"string",description:"Fragment of the symptom text (e.g. 'Inter everywhere' / '100vh')."}},required:["symptom"]}},{name:"get_skill_section",description:"Fetch ONE section of ONE skill \u2014 token-efficient. E.g. `skill='soft', section='double-bezel'`. Use after `list_skills` narrowed the relevant skill + section.",inputSchema:{type:"object",properties:{skill:{type:"string",description:"Skill id (e.g. 'soft', 'minimalist', 'taste')."},section:{type:"string",description:"Section id within that skill."}},required:["skill","section"]}},{name:"get_component",description:"Full guide for one @godxjp/ui component \u2014 import path, props/types/defaults, HOW to use it (DO/DON'T), WHEN to reach for it (use cases), related components (don't reinvent/confuse), a copy-paste example, story path, and cardinal rules. Use this before hand-rolling anything. Design-token knobs are listed compactly (name+default); pass `verbose:true` for what each token controls.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Component name (e.g. 'Button', 'DataTable')."},verbose:{type:"boolean",description:"Include the full design-token table with a 'what it controls' description per token. Default false (compact token+default only) to save context."}},required:["name"]}},{name:"get_pattern",description:"Full code snippet for one canonical pattern \u2014 copy-paste-ready.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Pattern slug (use list_patterns first)."}},required:["name"]}},{name:"get_rule",description:"Read one cardinal rule from CLAUDE.md (by number) OR all if no number.",inputSchema:{type:"object",properties:{number:{type:"number",description:"Rule number (1-N)."}}}},{name:"get_vocab",description:"Read shared prop-vocabulary type (`SizeProp`, `StatusProp`, `ColorProp`, `LoadingProp`, etc.) OR all if no name.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Vocab type name."}}}},{name:"get_tokens",description:"Read design tokens, optionally filtered by tier category (primitive / semantic / component).",inputSchema:{type:"object",properties:{category:{type:"string",enum:["primitive","semantic","component"]}}}},{name:"list_consumer_skills",description:"List the design skills relevant to an app-dev BUILDING WITH @godxjp/ui (audience consumer/both). Hides core library-maintenance skills. START HERE if you import @godxjp/ui and want guidance (design-to-page, compose-a-screen, taste, \u2026). Returns id + name + whenToUse + section ids.",inputSchema:{type:"object",properties:{}}},{name:"get_consumer_skill",description:"Fetch ONE section of ONE consumer-facing skill. Same as get_skill_section but refuses core-only skills (steers app-devs away from library-maintenance material). Use after list_consumer_skills / route_consumer_task.",inputSchema:{type:"object",properties:{skill:{type:"string",description:"Consumer skill id (e.g. 'design-to-page', 'compose-a-screen')."},section:{type:"string",description:"Section id within that skill."}},required:["skill"]}},{name:"route_consumer_task",description:"Natural-language task \u2192 consumer skill+section pointer. Like route_task but only points to consumer-facing skills (never core library-maintenance). Use FIRST when you're building an app with @godxjp/ui.",inputSchema:{type:"object",properties:{task:{type:"string",description:"Describe what you want to build."}},required:["task"]}},{name:"draft_bug_report",description:"When @godxjp/ui ITSELF is at fault (missing token, a primitive lacking the controlled-vocabulary prop, a real a11y/behaviour bug, a wrong catalog example) and you cannot follow a rule \u2014 DON'T fake a workaround. This drafts a detailed GitHub issue body + a copy-paste `gh issue create` command so you can report it. Prints the command only; never runs gh.",inputSchema:{type:"object",properties:{summary:{type:"string",description:"One-line title of the bug / blocked rule."},repro:{type:"string",description:"Minimal steps or code to reproduce."},expected:{type:"string",description:"What SHOULD happen (per the rule/spec)."},actual:{type:"string",description:"What actually happens."},component:{type:"string",description:"Affected component name, if any (links to get_component)."},rule:{type:"number",description:"Cardinal rule number that can't be followed, if any."},version:{type:"string",description:"Installed @godxjp/ui version (e.g. '12.1.0')."},env:{type:"string",description:"Environment (browser/OS/framework), if relevant."}},required:["summary"]}},{name:"check_compatibility",description:"Report whether the @godxjp/ui version installed in the target project matches THIS catalog (which describes one release train). A mismatched minor means the props/tokens/patterns may describe a build they never installed (#140). Pass the installed version (`npm ls @godxjp/ui`); call it at the START of a consumer session.",inputSchema:{type:"object",properties:{version:{type:"string",description:"Installed @godxjp/ui version in the target project, e.g. '16.10.0'. Omit to just read the catalog's own version + compatible range."}}}},{name:"route_task",description:"Natural-language task \u2192 skill+section pointer (e.g. 'design a premium agency hero' \u2192 soft/vibe-archetypes). Use FIRST when you don't know which skill applies.",inputSchema:{type:"object",properties:{task:{type:"string",description:"Describe what you want to build."}},required:["task"]}},{name:"suggest_primitive",description:"Use case \u2192 primitive recommendation. E.g. 'confirm a destructive delete' \u2192 DangerZone pattern + Dialog suggestion.",inputSchema:{type:"object",properties:{use_case:{type:"string"}},required:["use_case"]}},{name:"search_components",description:'Fuzzy-search primitives by name / tagline / prop. Returns ranked matches. Core only by default; pass tier="lab" or "all" to include the opt-in @godxjp/ui/lab components.',inputSchema:{type:"object",properties:{query:{type:"string"},tier:{type:"string",enum:["core","lab","all"],description:'Default "core". "lab" lists the opt-in `@godxjp/ui/lab` components (niche, kept and tested, not in the default context); "all" lists both.'}},required:["query"]}},{name:"get_frame_coverage",description:"Verified preview-contract coverage for a component (issue #163). Answers 'is this state actually PROVEN?' \u2014 returns, per contract dimension (variants, tones, sizes, shapes, density, controlled/uncontrolled ownership, disabled/read-only/loading/empty/error/success, async retry/cancel/offline, responsive viewport matrix, RTL, long/localized content, keyboard/focus, accessible name/description/error, reduced motion / coarse touch), whether an EXECUTED case proves it (covered), whether nothing proves it (UNTESTED), or whether it cannot exist (not-applicable, with a reason). UNTESTED IS NOT A PASS: never infer that a component supports a state because an example renders. Call this before telling a user a component 'supports' anything. Omit `name` for the repo-wide summary and the tracked known gaps.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Public export name (e.g. 'Button', 'DataTable', 'CardFooter'). Omit for the repo-wide coverage summary."}}}},{name:"get_design",description:"DESIGN.md \u2014 the visual spec for screens built with @godxjp/ui: real tokens (YAML front matter), colour scarcity rules, typography, layout & density, elevation, components, ADMIN SCREEN ANATOMY (list / detail / form / settings / dashboard / approval queue), do's and don'ts, responsive, iteration guide, known gaps. Read before composing a screen. Pass `section` for one section; omit it for the whole document (~12 KB).",inputSchema:{type:"object",properties:{section:{type:"string",description:"Section id or heading word, e.g. 'tokens', 'colors', 'admin-screen-anatomy', 'dos-and-donts', 'iteration-guide'. Unknown ids list the valid ones."}}}},{name:"get_exemplar",description:"A reference screen to match for an admin archetype: its anatomy notes from DESIGN.md, the full source of the showcase built from real @godxjp/ui primitives, and its live preview URL for screenshot comparison. Archetypes: "+E.map(e=>e.archetype).join(", ")+". Omit `archetype` to list them.",inputSchema:{type:"object",properties:{archetype:{type:"string",description:E.map(e=>e.archetype).join(" | ")+" (aliases: "+E.flatMap(e=>e.aliases??[]).join(", ")+")."}}}},{name:"lint_jsx",description:"Heuristic check of a JSX snippet for common violations \u2014 raw `<button>` / `<input>`, `color='error'` on Tag/Badge, missing aria-label, missing source.code override on stories with cell renderers (rule 34), etc.",inputSchema:{type:"object",properties:{jsx:{type:"string"}},required:["jsx"]}}],Ze=new Set(O.map(e=>e.name));function et(e=X()){let t=p.godxUiCompatibility??p.version,a=`@godxjp/ui-mcp ${p.version} (catalog for @godxjp/ui ${t})`;if(!e)return a;let n=e.source==="node_modules"?"read from node_modules at answer time":"from GODX_UI_VERSION at launch \u2014 node_modules/@godxjp/ui not resolved";return`${a} \u2014 installed @godxjp/ui ${e.version} (${n})`}function tt(e=X()){let t=e?V(e.version):null,a=V(p.version);return!e||!t||!a?null:dt(t,a)>0?`\u26A0\uFE0F SERVER OLDER THAN INSTALLED PACKAGE: this server is @godxjp/ui-mcp ${p.version}, the project has @godxjp/ui ${e.version} installed \u2014 this catalog is BEHIND the package and may be missing props and components that exist. Do not conclude from this answer that a prop is unavailable. Restart the session so the server relaunches on the installed version (run \`npx @godxjp/ui sync-rules\` first if the project's .mcp.json still pins an older @godxjp/ui-mcp).`:t.major===a.major?null:`\u26A0\uFE0F MAJOR MISMATCH: this server is @godxjp/ui-mcp ${p.version}, the project has @godxjp/ui ${e.version} installed \u2014 this catalog may describe components that do not exist in the installed package. Pin the MCP to @godxjp/ui-mcp@${e.version} (\`npx @godxjp/ui sync-rules\` updates the project's .mcp.json; a registration outside the project needs \`claude mcp remove <key>\`), then restart the agent.`}async function G(e,t){let a=await at(e,t);if(!Ze.has(e))return a;let n=X(),o=tt(n);return`${et(n)}
|
|
7980
|
+
`};var p={name:"@godxjp/ui-mcp",version:"33.12.6",godxUiCompatibility:"33.12.x",description:"Model Context Protocol server for @godxjp/ui \u2014 gives Claude Code / Codex CLI / Cursor / any MCP-aware agent live access to the component catalog, prop vocabulary, design tokens, 45 cardinal rules, copy-paste-ready patterns, 12 design / taste skills synthesised from Leonxlnx/taste-skill, 20+ anti-AI-tell patterns, and a 50-check redesign audit \u2014 token-efficient (list \u2192 drill-down).",type:"module",main:"./dist/index.js",module:"./dist/index.js",types:"./dist/index.d.ts",bin:{"godx-ui-mcp":"./dist/index.js"},files:["dist","README.md"],publishConfig:{registry:"https://registry.npmjs.org/",access:"public"},repository:{type:"git",url:"git+https://github.com/godx-jp/godxjp-ui.git",directory:"mcp"},homepage:"https://github.com/godx-jp/godxjp-ui/tree/main/mcp#readme",license:"Apache-2.0",scripts:{build:"tsup",dev:"tsup --watch",start:"node dist/index.js",inspect:"npx @modelcontextprotocol/inspector node dist/index.js","type-check":"tsc --noEmit",test:"vitest run",prepublishOnly:"npm run build"},dependencies:{"@modelcontextprotocol/sdk":"^1.29.0",zod:"^4.4.3"},devDependencies:{"@types/node":"^22.10.0",tsup:"^8.5.1",typescript:"^6.0.3",vitest:"^4.1.6"},keywords:["mcp","model-context-protocol","godxjp","ui","design-system","react","claude","cursor"],author:"GoDX (https://godx.jp)",bugs:{url:"https://github.com/godx-jp/godxjp-ui/issues"}};var O=[{name:"list_skills",description:"List every design/taste skill bundled by this MCP (id + name + whenToUse + section ids). Use FIRST to discover skills; then `get_skill_section` to drill in.",inputSchema:{type:"object",properties:{}}},{name:"list_primitives",description:'List every @godxjp/ui primitive/composite/shell (group + tagline per entry). Optionally filter by group. Then `get_component` for one\'s full API. Core only by default \u2014 pass tier="lab" for the opt-in @godxjp/ui/lab components.',inputSchema:{type:"object",properties:{tier:{type:"string",enum:["core","lab","all"],description:'Default "core". "lab" lists the opt-in `@godxjp/ui/lab` components (niche, kept and tested, not in the default context); "all" lists both.'},group:{type:"string",enum:["general","layout","data-display","data-entry","feedback","navigation","composites","shell","providers"]}}}},{name:"list_utilities",description:'List every NON-component public export of @godxjp/ui \u2014 hooks, helper functions and constants (cn, formatDate, formatCurrency, toast, useDebouncedValue, buttonVariants, CHART_COLORS, SHOW_PARENT \u2026). Reach for this before hand-writing a className merger, a date/money formatter, a debounce hook or a chart palette: two products in this org each re-implemented `cn` because it could not be found. Optionally filter by kind. Then `get_component name="<name>"` for its signature, usage and example.',inputSchema:{type:"object",properties:{kind:{type:"string",enum:["hook","function","value"],description:"hook = only legal inside a component body; function = callable anywhere; value = a constant to read."}}}},{name:"list_patterns",description:"List every canonical copy-paste code pattern (signup-form, settings-page, data-table-page, async-data-state, confirm-destructive, \u2026); common aliases resolve too. Use before `get_pattern`.",inputSchema:{type:"object",properties:{}}},{name:"list_anti_ai_tells",description:"List every AI-tell pattern to AVOID (optionally by category). Use to self-audit a design before shipping; then `get_anti_ai_tell` for the fix.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["visual","layout","copy","interaction","imagery","structure"]}}}},{name:"list_redesign_checks",description:"List the redesign audit checklist (50+ checks; optionally by category). Use when auditing an existing project; then `get_redesign_check` for a symptom's fix.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["typography","color-surface","layout","interactivity","content","components","iconography","code-quality","omissions"]}}}},{name:"list_audit_rules",description:"List the LOCAL static ui-audit rules (scripts/ui-audit.mjs) to run BEFORE any visual review \u2014 each cites the standard it enforces (WCAG/WAI-ARIA/Intl/ISO/IANA/CSS-Logical) + a fix + the run command. Optionally by category.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["tokens","composition","api","a11y","i18n","rtl","copy"]}}}},{name:"list_visual_checks",description:"List the RUNTIME visual-audit checks (scripts/visual-audit.mjs \u2014 Playwright + axe-core) to run against the RUNNING app: contrast/ARIA (axe), target size, rendered-accent chroma, DOM emoji, banner layout. Needs a browser (vs list_audit_rules, static). Optionally by category.",inputSchema:{type:"object",properties:{category:{type:"string",enum:["a11y","color","i18n","layout"]}}}},{name:"get_anti_ai_tell",description:"Fetch ONE anti-AI-tell \u2014 full body + concrete fix. Use after `list_anti_ai_tells`.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Exact tell name from list_anti_ai_tells."}},required:["name"]}},{name:"get_redesign_check",description:"Fetch redesign check(s) matching a symptom snippet. Returns full fix + UI note. Use after `list_redesign_checks`.",inputSchema:{type:"object",properties:{symptom:{type:"string",description:"Fragment of the symptom text (e.g. 'Inter everywhere' / '100vh')."}},required:["symptom"]}},{name:"get_skill_section",description:"Fetch ONE section of ONE skill \u2014 token-efficient. E.g. `skill='soft', section='double-bezel'`. Use after `list_skills` narrowed the relevant skill + section.",inputSchema:{type:"object",properties:{skill:{type:"string",description:"Skill id (e.g. 'soft', 'minimalist', 'taste')."},section:{type:"string",description:"Section id within that skill."}},required:["skill","section"]}},{name:"get_component",description:"Full guide for one @godxjp/ui component \u2014 import path, props/types/defaults, HOW to use it (DO/DON'T), WHEN to reach for it (use cases), related components (don't reinvent/confuse), a copy-paste example, story path, and cardinal rules. Use this before hand-rolling anything. Design-token knobs are listed compactly (name+default); pass `verbose:true` for what each token controls.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Component name (e.g. 'Button', 'DataTable')."},verbose:{type:"boolean",description:"Include the full design-token table with a 'what it controls' description per token. Default false (compact token+default only) to save context."}},required:["name"]}},{name:"get_pattern",description:"Full code snippet for one canonical pattern \u2014 copy-paste-ready.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Pattern slug (use list_patterns first)."}},required:["name"]}},{name:"get_rule",description:"Read one cardinal rule from CLAUDE.md (by number) OR all if no number.",inputSchema:{type:"object",properties:{number:{type:"number",description:"Rule number (1-N)."}}}},{name:"get_vocab",description:"Read shared prop-vocabulary type (`SizeProp`, `StatusProp`, `ColorProp`, `LoadingProp`, etc.) OR all if no name.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Vocab type name."}}}},{name:"get_tokens",description:"Read design tokens, optionally filtered by tier category (primitive / semantic / component).",inputSchema:{type:"object",properties:{category:{type:"string",enum:["primitive","semantic","component"]}}}},{name:"list_consumer_skills",description:"List the design skills relevant to an app-dev BUILDING WITH @godxjp/ui (audience consumer/both). Hides core library-maintenance skills. START HERE if you import @godxjp/ui and want guidance (design-to-page, compose-a-screen, taste, \u2026). Returns id + name + whenToUse + section ids.",inputSchema:{type:"object",properties:{}}},{name:"get_consumer_skill",description:"Fetch ONE section of ONE consumer-facing skill. Same as get_skill_section but refuses core-only skills (steers app-devs away from library-maintenance material). Use after list_consumer_skills / route_consumer_task.",inputSchema:{type:"object",properties:{skill:{type:"string",description:"Consumer skill id (e.g. 'design-to-page', 'compose-a-screen')."},section:{type:"string",description:"Section id within that skill."}},required:["skill"]}},{name:"route_consumer_task",description:"Natural-language task \u2192 consumer skill+section pointer. Like route_task but only points to consumer-facing skills (never core library-maintenance). Use FIRST when you're building an app with @godxjp/ui.",inputSchema:{type:"object",properties:{task:{type:"string",description:"Describe what you want to build."}},required:["task"]}},{name:"draft_bug_report",description:"When @godxjp/ui ITSELF is at fault (missing token, a primitive lacking the controlled-vocabulary prop, a real a11y/behaviour bug, a wrong catalog example) and you cannot follow a rule \u2014 DON'T fake a workaround. This drafts a detailed GitHub issue body + a copy-paste `gh issue create` command so you can report it. Prints the command only; never runs gh.",inputSchema:{type:"object",properties:{summary:{type:"string",description:"One-line title of the bug / blocked rule."},repro:{type:"string",description:"Minimal steps or code to reproduce."},expected:{type:"string",description:"What SHOULD happen (per the rule/spec)."},actual:{type:"string",description:"What actually happens."},component:{type:"string",description:"Affected component name, if any (links to get_component)."},rule:{type:"number",description:"Cardinal rule number that can't be followed, if any."},version:{type:"string",description:"Installed @godxjp/ui version (e.g. '12.1.0')."},env:{type:"string",description:"Environment (browser/OS/framework), if relevant."}},required:["summary"]}},{name:"check_compatibility",description:"Report whether the @godxjp/ui version installed in the target project matches THIS catalog (which describes one release train). A mismatched minor means the props/tokens/patterns may describe a build they never installed (#140). Pass the installed version (`npm ls @godxjp/ui`); call it at the START of a consumer session.",inputSchema:{type:"object",properties:{version:{type:"string",description:"Installed @godxjp/ui version in the target project, e.g. '16.10.0'. Omit to just read the catalog's own version + compatible range."}}}},{name:"route_task",description:"Natural-language task \u2192 skill+section pointer (e.g. 'design a premium agency hero' \u2192 soft/vibe-archetypes). Use FIRST when you don't know which skill applies.",inputSchema:{type:"object",properties:{task:{type:"string",description:"Describe what you want to build."}},required:["task"]}},{name:"suggest_primitive",description:"Use case \u2192 primitive recommendation. E.g. 'confirm a destructive delete' \u2192 DangerZone pattern + Dialog suggestion.",inputSchema:{type:"object",properties:{use_case:{type:"string"}},required:["use_case"]}},{name:"search_components",description:'Fuzzy-search primitives by name / tagline / prop. Returns ranked matches. Core only by default; pass tier="lab" or "all" to include the opt-in @godxjp/ui/lab components.',inputSchema:{type:"object",properties:{query:{type:"string"},tier:{type:"string",enum:["core","lab","all"],description:'Default "core". "lab" lists the opt-in `@godxjp/ui/lab` components (niche, kept and tested, not in the default context); "all" lists both.'}},required:["query"]}},{name:"get_frame_coverage",description:"Verified preview-contract coverage for a component (issue #163). Answers 'is this state actually PROVEN?' \u2014 returns, per contract dimension (variants, tones, sizes, shapes, density, controlled/uncontrolled ownership, disabled/read-only/loading/empty/error/success, async retry/cancel/offline, responsive viewport matrix, RTL, long/localized content, keyboard/focus, accessible name/description/error, reduced motion / coarse touch), whether an EXECUTED case proves it (covered), whether nothing proves it (UNTESTED), or whether it cannot exist (not-applicable, with a reason). UNTESTED IS NOT A PASS: never infer that a component supports a state because an example renders. Call this before telling a user a component 'supports' anything. Omit `name` for the repo-wide summary and the tracked known gaps.",inputSchema:{type:"object",properties:{name:{type:"string",description:"Public export name (e.g. 'Button', 'DataTable', 'CardFooter'). Omit for the repo-wide coverage summary."}}}},{name:"get_design",description:"DESIGN.md \u2014 the visual spec for screens built with @godxjp/ui: real tokens (YAML front matter), colour scarcity rules, typography, layout & density, elevation, components, ADMIN SCREEN ANATOMY (list / detail / form / settings / dashboard / approval queue), do's and don'ts, responsive, iteration guide, known gaps. Read before composing a screen. Pass `section` for one section; omit it for the whole document (~12 KB).",inputSchema:{type:"object",properties:{section:{type:"string",description:"Section id or heading word, e.g. 'tokens', 'colors', 'admin-screen-anatomy', 'dos-and-donts', 'iteration-guide'. Unknown ids list the valid ones."}}}},{name:"get_exemplar",description:"A reference screen to match for an admin archetype: its anatomy notes from DESIGN.md, the full source of the showcase built from real @godxjp/ui primitives, and its live preview URL for screenshot comparison. Archetypes: "+E.map(e=>e.archetype).join(", ")+". Omit `archetype` to list them.",inputSchema:{type:"object",properties:{archetype:{type:"string",description:E.map(e=>e.archetype).join(" | ")+" (aliases: "+E.flatMap(e=>e.aliases??[]).join(", ")+")."}}}},{name:"lint_jsx",description:"Heuristic check of a JSX snippet for common violations \u2014 raw `<button>` / `<input>`, `color='error'` on Tag/Badge, missing aria-label, missing source.code override on stories with cell renderers (rule 34), etc.",inputSchema:{type:"object",properties:{jsx:{type:"string"}},required:["jsx"]}}],Ze=new Set(O.map(e=>e.name));function et(e=X()){let t=p.godxUiCompatibility??p.version,a=`@godxjp/ui-mcp ${p.version} (catalog for @godxjp/ui ${t})`;if(!e)return a;let n=e.source==="node_modules"?"read from node_modules at answer time":"from GODX_UI_VERSION at launch \u2014 node_modules/@godxjp/ui not resolved";return`${a} \u2014 installed @godxjp/ui ${e.version} (${n})`}function tt(e=X()){let t=e?V(e.version):null,a=V(p.version);return!e||!t||!a?null:dt(t,a)>0?`\u26A0\uFE0F SERVER OLDER THAN INSTALLED PACKAGE: this server is @godxjp/ui-mcp ${p.version}, the project has @godxjp/ui ${e.version} installed \u2014 this catalog is BEHIND the package and may be missing props and components that exist. Do not conclude from this answer that a prop is unavailable. Restart the session so the server relaunches on the installed version (run \`npx @godxjp/ui sync-rules\` first if the project's .mcp.json still pins an older @godxjp/ui-mcp).`:t.major===a.major?null:`\u26A0\uFE0F MAJOR MISMATCH: this server is @godxjp/ui-mcp ${p.version}, the project has @godxjp/ui ${e.version} installed \u2014 this catalog may describe components that do not exist in the installed package. Pin the MCP to @godxjp/ui-mcp@${e.version} (\`npx @godxjp/ui sync-rules\` updates the project's .mcp.json; a registration outside the project needs \`claude mcp remove <key>\`), then restart the agent.`}async function G(e,t){let a=await at(e,t);if(!Ze.has(e))return a;let n=X(),o=tt(n);return`${et(n)}
|
|
7981
7981
|
${o?`${o}
|
|
7982
7982
|
`:""}
|
|
7983
7983
|
${a}`}async function at(e,t){switch(e){case"list_skills":return it();case"list_primitives":return Pe(t.group,t.tier);case"list_utilities":return Tt(t.kind);case"list_patterns":return ut();case"list_anti_ai_tells":return bt(t.category);case"list_redesign_checks":return vt(t.category);case"list_audit_rules":return gt(t.category);case"list_visual_checks":return mt(t.category);case"get_anti_ai_tell":return ft(String(t.name??""));case"get_redesign_check":return yt(String(t.symptom??""));case"get_skill_section":return Le(String(t.skill??""),String(t.section??""));case"get_component":return St(String(t.name??""),t.verbose===!0);case"get_pattern":return Dt(String(t.name??""));case"get_rule":return Et(typeof t.number=="number"?t.number:void 0);case"get_vocab":return Ot(t.name==null?void 0:String(t.name));case"get_tokens":return Nt(t.category);case"list_consumer_skills":return rt();case"get_consumer_skill":return st(String(t.skill??""),String(t.section??""));case"route_consumer_task":return Oe(String(t.task??""),{consumerOnly:!0});case"draft_bug_report":return lt(t);case"check_compatibility":return ze(t.version==null?void 0:String(t.version));case"route_task":return Oe(String(t.task??""));case"suggest_primitive":return Rt(String(t.use_case??""));case"search_components":return It(String(t.query??""),t.tier);case"get_frame_coverage":return At(t.name===void 0?void 0:String(t.name));case"get_design":return nt(t.section==null?void 0:String(t.section));case"get_exemplar":return ot(t.archetype==null?"":String(t.archetype));case"lint_jsx":return zt(String(t.jsx??""));default:return`Unknown tool: ${e}`}}function nt(e){if(e===void 0||e.trim()==="")return U;let t=ke(e);if(t)return t.body;let a=j().map(n=>`- \`${n.id}\` \u2014 ${n.title}`).join(`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@godxjp/ui-mcp",
|
|
3
|
-
"version": "33.12.
|
|
3
|
+
"version": "33.12.6",
|
|
4
4
|
"godxUiCompatibility": "33.12.x",
|
|
5
5
|
"description": "Model Context Protocol server for @godxjp/ui \u2014 gives Claude Code / Codex CLI / Cursor / any MCP-aware agent live access to the component catalog, prop vocabulary, design tokens, 45 cardinal rules, copy-paste-ready patterns, 12 design / taste skills synthesised from Leonxlnx/taste-skill, 20+ anti-AI-tell patterns, and a 50-check redesign audit \u2014 token-efficient (list \u2192 drill-down).",
|
|
6
6
|
"type": "module",
|