@jbpark/ui-kit 8.1.0 → 9.1.0

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.
Files changed (41) hide show
  1. package/dist/Button.d.mts +48 -12
  2. package/dist/Button.d.mts.map +1 -1
  3. package/dist/Button.mjs +62 -11
  4. package/dist/Button.mjs.map +1 -1
  5. package/dist/Tag.d.mts +8 -11
  6. package/dist/Tag.d.mts.map +1 -1
  7. package/dist/Tag.mjs +8 -7
  8. package/dist/Tag.mjs.map +1 -1
  9. package/dist/components/atoms/date-picker.mjs +1 -1
  10. package/dist/components/atoms/float-button/float-button.mjs +1 -1
  11. package/dist/components/atoms/input/search.mjs +1 -1
  12. package/dist/components/atoms/radio/group.mjs +1 -1
  13. package/dist/components/atoms/radio/radio.d.mts +1 -1
  14. package/dist/components/atoms/switch.d.mts +9 -1
  15. package/dist/components/atoms/switch.d.mts.map +1 -1
  16. package/dist/components/atoms/switch.mjs +23 -11
  17. package/dist/components/atoms/switch.mjs.map +1 -1
  18. package/dist/components/organisms/drawer.mjs +1 -1
  19. package/dist/components/organisms/modal.d.mts +4 -5
  20. package/dist/components/organisms/modal.d.mts.map +1 -1
  21. package/dist/components/organisms/modal.mjs +5 -6
  22. package/dist/components/organisms/modal.mjs.map +1 -1
  23. package/dist/components/organisms/toast.d.mts +2 -8
  24. package/dist/components/organisms/toast.d.mts.map +1 -1
  25. package/dist/components/organisms/toast.mjs +4 -5
  26. package/dist/components/organisms/toast.mjs.map +1 -1
  27. package/dist/core/badge.d.mts +25 -2
  28. package/dist/core/badge.d.mts.map +1 -0
  29. package/dist/core/badge.mjs +47 -0
  30. package/dist/core/badge.mjs.map +1 -0
  31. package/dist/core/button.d.mts +14 -2
  32. package/dist/core/button.d.mts.map +1 -0
  33. package/dist/core/dialog.mjs +1 -1
  34. package/dist/core/field.d.mts +1 -1
  35. package/dist/index.d.mts +4 -4
  36. package/dist/lib/colors.d.mts +6 -31
  37. package/dist/lib/colors.d.mts.map +1 -1
  38. package/dist/style.css +53 -34
  39. package/package.json +1 -1
  40. package/dist/lib/chassis.mjs +0 -23
  41. package/dist/lib/chassis.mjs.map +0 -1
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { cn } from "../../utils.mjs";
3
3
  import { DEFAULT_LOCALE, useConfig } from "../../providers/config/context.mjs";
4
- import Button from "../../Button.mjs";
5
4
  import { dialog_exports } from "../../core/dialog.mjs";
5
+ import Button from "../../Button.mjs";
6
6
  import { createImperativeStack, isBrowser } from "./imperative-stack.mjs";
7
7
  import { useState } from "react";
8
8
  import { Check, CircleQuestionMark, Info, OctagonAlert, OctagonX } from "lucide-react";
@@ -65,13 +65,12 @@ const STATIC_ICONS = {
65
65
  warning: /* @__PURE__ */ jsx(OctagonAlert, { className: "text-yellow-400" }),
66
66
  confirm: /* @__PURE__ */ jsx(CircleQuestionMark, {})
67
67
  };
68
- const StaticModal = ({ id, status, type, title, content, okText, cancelText, container, icon, onOk, onCancel, ...props }) => {
68
+ const StaticModal = ({ id, status, mode, title, content, okText, cancelText, container, icon, onOk, onCancel, ...props }) => {
69
69
  const { locale } = useConfig();
70
70
  const [open, setOpen] = useState(true);
71
71
  const resolvedOkText = okText ?? locale.ok ?? DEFAULT_LOCALE.ok;
72
72
  const resolvedCancelText = cancelText ?? locale.cancel ?? DEFAULT_LOCALE.cancel;
73
- const isConfirm = type === "confirm";
74
- const resolvedStatus = status ?? (isConfirm ? void 0 : type);
73
+ const isConfirm = mode === "confirm";
75
74
  const closeModal = (callback) => {
76
75
  callback?.();
77
76
  setOpen(false);
@@ -108,7 +107,7 @@ const StaticModal = ({ id, status, type, title, content, okText, cancelText, con
108
107
  },
109
108
  title: /* @__PURE__ */ jsxs("p", {
110
109
  className: cn("text-center text-lg leading-normal whitespace-pre-wrap", "flex items-center justify-center gap-x-2"),
111
- children: [icon || (isConfirm ? STATIC_ICONS.confirm : resolvedStatus && STATIC_ICONS[resolvedStatus]), title]
110
+ children: [icon || (isConfirm ? STATIC_ICONS.confirm : status && STATIC_ICONS[status]), title]
112
111
  }),
113
112
  container,
114
113
  onCancel: () => closeModal(onCancel),
@@ -146,7 +145,7 @@ Modal.warning = (props) => modalStack.render({
146
145
  ...props
147
146
  });
148
147
  Modal.confirm = (props) => modalStack.render({
149
- type: "confirm",
148
+ mode: "confirm",
150
149
  ...props
151
150
  });
152
151
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"modal.mjs","names":["dialog"],"sources":["../../../src/components/organisms/modal.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport {\n Check,\n CircleQuestionMark,\n Info,\n OctagonAlert,\n OctagonX,\n} from 'lucide-react';\n\nimport { DEFAULT_LOCALE, useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport { dialog } from '../../core';\nimport Button from '../atoms/button';\nimport {\n type ImperativeStack,\n createImperativeStack,\n isBrowser,\n} from './imperative-stack';\n\nconst {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} = dialog;\n\nexport interface Props {\n open?: boolean;\n maskClosable?: boolean;\n closable?:\n | boolean\n | {\n closeIcon?: React.ReactNode;\n disabled?: boolean;\n };\n closeIcon?: React.ReactNode;\n title?: React.ReactNode;\n content?: React.ReactNode;\n footer?: React.ReactNode;\n className?: string;\n classNames?: {\n mask?: string;\n header?: string;\n body?: string;\n footer?: string;\n };\n style?: React.CSSProperties;\n okText?: string;\n cancelText?: string;\n container?: HTMLElement;\n children?: React.ReactNode;\n onOk?: () => void;\n onCancel?: () => void;\n}\n\ntype ModalStatus = 'info' | 'success' | 'error' | 'warning';\n\ninterface StaticProps extends Props {\n status?: ModalStatus;\n /**\n * @deprecated Use `status` for the semantic state. Kept as an alias so\n * existing `type=\"info|success|error|warning\"` calls keep working. `confirm`\n * is an interaction mode, not a status — call `Modal.confirm()` instead\n * (still accepted here as `type=\"confirm\"` for back-compat).\n */\n type?: ModalStatus | 'confirm';\n id?: string;\n icon?: React.ReactNode;\n container?: HTMLElement;\n}\n\nconst Modal = ({\n open = false,\n maskClosable,\n closable = false,\n closeIcon,\n className,\n classNames,\n style,\n title,\n content,\n footer,\n container,\n children,\n okText,\n cancelText,\n onOk,\n onCancel,\n ...props\n}: Props) => {\n const { locale, defaultProps } = useConfig();\n const modalDefaults = defaultProps?.modal as\n Partial<Pick<Props, 'maskClosable'>> | undefined;\n // Explicit prop > `Config` default > built-in, matching Button/Tag.\n const resolvedMaskClosable =\n maskClosable ?? modalDefaults?.maskClosable ?? false;\n\n if (typeof window === 'undefined') {\n return null;\n }\n\n return (\n <Dialog\n open={open}\n onOpenChange={(open: boolean) => {\n if (!open) {\n onCancel?.();\n }\n }}\n {...props}\n >\n <DialogContent\n className={cn(\n 'rounded-lg p-4 max-sm:max-w-[80%]',\n 'border-none outline-none',\n className,\n )}\n classNames={{\n ...classNames,\n mask: cn('bg-black/60', classNames?.mask),\n }}\n style={style}\n closable={closable}\n closeIcon={closeIcon}\n container={container}\n onPointerDownOutside={event => {\n if (!resolvedMaskClosable) {\n event.preventDefault();\n }\n }}\n >\n {/**\n * @todo [Dialog & AlertDialog] fix: can't get id correctly in shadow dom\n * @see https://github.com/radix-ui/primitives/pull/3384\n **/}\n <DialogHeader\n className={cn(\n classNames?.header,\n !title && 'hidden',\n //\n )}\n >\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription className=\"hidden\" />\n </DialogHeader>\n <div className={cn('break-all', classNames?.body)}>\n {children ?? content}\n </div>\n {footer !== null && (\n <DialogFooter\n className={cn('flex-row justify-end gap-x-2', classNames?.footer)}\n >\n {footer || (\n <>\n <Button onClick={onOk}>\n {okText ?? locale.ok ?? DEFAULT_LOCALE.ok}\n </Button>\n <Button variant=\"outlined\" onClick={onCancel}>\n {cancelText ?? locale.cancel ?? DEFAULT_LOCALE.cancel}\n </Button>\n </>\n )}\n </DialogFooter>\n )}\n </DialogContent>\n </Dialog>\n );\n};\n\nconst STATIC_ICONS = {\n info: <Info className=\"text-blue-400\" />,\n success: <Check className=\"text-green-400\" />,\n error: <OctagonX className=\"text-red-400\" />,\n warning: <OctagonAlert className=\"text-yellow-400\" />,\n confirm: <CircleQuestionMark />,\n};\n\nconst StaticModal = ({\n id,\n status,\n type,\n title,\n content,\n okText,\n cancelText,\n container,\n icon,\n onOk,\n onCancel,\n ...props\n}: StaticProps & { id: string }): React.ReactPortal | null => {\n const { locale } = useConfig();\n const [open, setOpen] = useState(true);\n const resolvedOkText = okText ?? locale.ok ?? DEFAULT_LOCALE.ok;\n const resolvedCancelText =\n cancelText ?? locale.cancel ?? DEFAULT_LOCALE.cancel;\n // `confirm` is an interaction mode (two-button footer), not a status. The\n // semantic state comes from `status`, with `type` as its deprecated alias.\n const isConfirm = type === 'confirm';\n const resolvedStatus = status ?? (isConfirm ? undefined : type);\n\n const closeModal = (callback?: () => void) => {\n callback?.();\n setOpen(false);\n setTimeout(() => {\n modalStack.destroy(id);\n }, 200);\n };\n\n const footer = isConfirm ? (\n <div className=\"grid w-full grid-cols-5 gap-x-2\">\n <Button\n variant=\"outlined\"\n className=\"col-span-2\"\n onClick={() => closeModal(onCancel)}\n >\n {resolvedCancelText}\n </Button>\n <Button className=\"col-span-3\" onClick={() => closeModal(onOk)}>\n {resolvedOkText}\n </Button>\n </div>\n ) : (\n <Button\n className={cn(\n 'grow',\n //\n )}\n onClick={() => closeModal(onOk)}\n >\n {resolvedOkText}\n </Button>\n );\n\n if (!isBrowser) {\n return null;\n }\n\n return createPortal(\n <Modal\n open={open}\n footer={footer}\n className={cn(\n 'z-10000',\n 'box-content w-100',\n 'rounded-3xl p-4',\n 'gap-y-0',\n )}\n classNames={{\n mask: 'z-10000 bg-black/[.6]',\n body: cn(\n 'text-black-70 whitespace-pre-wrap text-center',\n content && 'mt-3',\n ),\n footer: 'mt-9',\n }}\n title={\n <p\n className={cn(\n 'text-center text-lg leading-normal whitespace-pre-wrap',\n 'flex items-center justify-center gap-x-2',\n //\n )}\n >\n {icon ||\n (isConfirm\n ? STATIC_ICONS.confirm\n : resolvedStatus && STATIC_ICONS[resolvedStatus])}\n {title}\n </p>\n }\n container={container}\n onCancel={() => closeModal(onCancel)}\n {...props}\n >\n {content}\n </Modal>,\n modalStack.getRootElement(container)!,\n );\n};\n\n// No `role`/`aria-modal` here — this element is only a mount point for the\n// imperative stack, not the dialog itself. Radix already renders its own\n// `role=\"dialog\"`/`aria-modal=\"true\"` on the actual `DialogContent` via\n// portal once a modal is open. Setting it here as well would (a) leave\n// `aria-modal=\"true\"` on the page permanently, even with zero modals open,\n// hiding the rest of the document from screen readers, and (b) duplicate\n// Radix's own dialog role once one is open.\nconst modalStack: ImperativeStack<StaticProps> =\n createImperativeStack<StaticProps>({\n createRootElement: () => {\n const el = document.createElement('div');\n el.style.zIndex = '10000';\n el.style.position = 'absolute';\n return el;\n },\n StackItem: StaticModal,\n });\n\nModal.destroy = modalStack.destroy;\n\nModal.destroyAll = () => {\n modalStack.destroy();\n};\n\nModal.info = (props: StaticProps) =>\n modalStack.render({ status: 'info', ...props });\nModal.success = (props: StaticProps) =>\n modalStack.render({ status: 'success', ...props });\nModal.error = (props: StaticProps) =>\n modalStack.render({ status: 'error', ...props });\nModal.warning = (props: StaticProps) =>\n modalStack.render({ status: 'warning', ...props });\n// `confirm` is a mode, not a status, so it rides the `type` axis (the only\n// place it lives) rather than `status`.\nModal.confirm = (props: StaticProps) =>\n modalStack.render({ type: 'confirm', ...props });\n\nexport default Modal;\n"],"mappings":"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"}
1
+ {"version":3,"file":"modal.mjs","names":["dialog"],"sources":["../../../src/components/organisms/modal.tsx"],"sourcesContent":["'use client';\n\nimport React, { useState } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport {\n Check,\n CircleQuestionMark,\n Info,\n OctagonAlert,\n OctagonX,\n} from 'lucide-react';\n\nimport { DEFAULT_LOCALE, useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport { dialog } from '../../core';\nimport Button from '../atoms/button';\nimport {\n type ImperativeStack,\n createImperativeStack,\n isBrowser,\n} from './imperative-stack';\n\nconst {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} = dialog;\n\nexport interface Props {\n open?: boolean;\n maskClosable?: boolean;\n closable?:\n | boolean\n | {\n closeIcon?: React.ReactNode;\n disabled?: boolean;\n };\n closeIcon?: React.ReactNode;\n title?: React.ReactNode;\n content?: React.ReactNode;\n footer?: React.ReactNode;\n className?: string;\n classNames?: {\n mask?: string;\n header?: string;\n body?: string;\n footer?: string;\n };\n style?: React.CSSProperties;\n okText?: string;\n cancelText?: string;\n container?: HTMLElement;\n children?: React.ReactNode;\n onOk?: () => void;\n onCancel?: () => void;\n}\n\ntype ModalStatus = 'info' | 'success' | 'error' | 'warning';\n\ninterface StaticProps extends Props {\n status?: ModalStatus;\n /**\n * Interaction mode set by `Modal.confirm()` to request the two-button\n * footer. `confirm` is a mode, not a status, so it rides its own axis rather\n * than `status` — call `Modal.confirm()` rather than setting this directly.\n */\n mode?: 'confirm';\n id?: string;\n icon?: React.ReactNode;\n container?: HTMLElement;\n}\n\nconst Modal = ({\n open = false,\n maskClosable,\n closable = false,\n closeIcon,\n className,\n classNames,\n style,\n title,\n content,\n footer,\n container,\n children,\n okText,\n cancelText,\n onOk,\n onCancel,\n ...props\n}: Props) => {\n const { locale, defaultProps } = useConfig();\n const modalDefaults = defaultProps?.modal as\n Partial<Pick<Props, 'maskClosable'>> | undefined;\n // Explicit prop > `Config` default > built-in, matching Button/Tag.\n const resolvedMaskClosable =\n maskClosable ?? modalDefaults?.maskClosable ?? false;\n\n if (typeof window === 'undefined') {\n return null;\n }\n\n return (\n <Dialog\n open={open}\n onOpenChange={(open: boolean) => {\n if (!open) {\n onCancel?.();\n }\n }}\n {...props}\n >\n <DialogContent\n className={cn(\n 'rounded-lg p-4 max-sm:max-w-[80%]',\n 'border-none outline-none',\n className,\n )}\n classNames={{\n ...classNames,\n mask: cn('bg-black/60', classNames?.mask),\n }}\n style={style}\n closable={closable}\n closeIcon={closeIcon}\n container={container}\n onPointerDownOutside={event => {\n if (!resolvedMaskClosable) {\n event.preventDefault();\n }\n }}\n >\n {/**\n * @todo [Dialog & AlertDialog] fix: can't get id correctly in shadow dom\n * @see https://github.com/radix-ui/primitives/pull/3384\n **/}\n <DialogHeader\n className={cn(\n classNames?.header,\n !title && 'hidden',\n //\n )}\n >\n <DialogTitle>{title}</DialogTitle>\n <DialogDescription className=\"hidden\" />\n </DialogHeader>\n <div className={cn('break-all', classNames?.body)}>\n {children ?? content}\n </div>\n {footer !== null && (\n <DialogFooter\n className={cn('flex-row justify-end gap-x-2', classNames?.footer)}\n >\n {footer || (\n <>\n <Button onClick={onOk}>\n {okText ?? locale.ok ?? DEFAULT_LOCALE.ok}\n </Button>\n <Button variant=\"outlined\" onClick={onCancel}>\n {cancelText ?? locale.cancel ?? DEFAULT_LOCALE.cancel}\n </Button>\n </>\n )}\n </DialogFooter>\n )}\n </DialogContent>\n </Dialog>\n );\n};\n\nconst STATIC_ICONS = {\n info: <Info className=\"text-blue-400\" />,\n success: <Check className=\"text-green-400\" />,\n error: <OctagonX className=\"text-red-400\" />,\n warning: <OctagonAlert className=\"text-yellow-400\" />,\n confirm: <CircleQuestionMark />,\n};\n\nconst StaticModal = ({\n id,\n status,\n mode,\n title,\n content,\n okText,\n cancelText,\n container,\n icon,\n onOk,\n onCancel,\n ...props\n}: StaticProps & { id: string }): React.ReactPortal | null => {\n const { locale } = useConfig();\n const [open, setOpen] = useState(true);\n const resolvedOkText = okText ?? locale.ok ?? DEFAULT_LOCALE.ok;\n const resolvedCancelText =\n cancelText ?? locale.cancel ?? DEFAULT_LOCALE.cancel;\n // `confirm` is an interaction mode (two-button footer), not a status; the\n // semantic state comes from `status`.\n const isConfirm = mode === 'confirm';\n\n const closeModal = (callback?: () => void) => {\n callback?.();\n setOpen(false);\n setTimeout(() => {\n modalStack.destroy(id);\n }, 200);\n };\n\n const footer = isConfirm ? (\n <div className=\"grid w-full grid-cols-5 gap-x-2\">\n <Button\n variant=\"outlined\"\n className=\"col-span-2\"\n onClick={() => closeModal(onCancel)}\n >\n {resolvedCancelText}\n </Button>\n <Button className=\"col-span-3\" onClick={() => closeModal(onOk)}>\n {resolvedOkText}\n </Button>\n </div>\n ) : (\n <Button\n className={cn(\n 'grow',\n //\n )}\n onClick={() => closeModal(onOk)}\n >\n {resolvedOkText}\n </Button>\n );\n\n if (!isBrowser) {\n return null;\n }\n\n return createPortal(\n <Modal\n open={open}\n footer={footer}\n className={cn(\n 'z-10000',\n 'box-content w-100',\n 'rounded-3xl p-4',\n 'gap-y-0',\n )}\n classNames={{\n mask: 'z-10000 bg-black/[.6]',\n body: cn(\n 'text-black-70 whitespace-pre-wrap text-center',\n content && 'mt-3',\n ),\n footer: 'mt-9',\n }}\n title={\n <p\n className={cn(\n 'text-center text-lg leading-normal whitespace-pre-wrap',\n 'flex items-center justify-center gap-x-2',\n //\n )}\n >\n {icon ||\n (isConfirm ? STATIC_ICONS.confirm : status && STATIC_ICONS[status])}\n {title}\n </p>\n }\n container={container}\n onCancel={() => closeModal(onCancel)}\n {...props}\n >\n {content}\n </Modal>,\n modalStack.getRootElement(container)!,\n );\n};\n\n// No `role`/`aria-modal` here — this element is only a mount point for the\n// imperative stack, not the dialog itself. Radix already renders its own\n// `role=\"dialog\"`/`aria-modal=\"true\"` on the actual `DialogContent` via\n// portal once a modal is open. Setting it here as well would (a) leave\n// `aria-modal=\"true\"` on the page permanently, even with zero modals open,\n// hiding the rest of the document from screen readers, and (b) duplicate\n// Radix's own dialog role once one is open.\nconst modalStack: ImperativeStack<StaticProps> =\n createImperativeStack<StaticProps>({\n createRootElement: () => {\n const el = document.createElement('div');\n el.style.zIndex = '10000';\n el.style.position = 'absolute';\n return el;\n },\n StackItem: StaticModal,\n });\n\nModal.destroy = modalStack.destroy;\n\nModal.destroyAll = () => {\n modalStack.destroy();\n};\n\nModal.info = (props: StaticProps) =>\n modalStack.render({ status: 'info', ...props });\nModal.success = (props: StaticProps) =>\n modalStack.render({ status: 'success', ...props });\nModal.error = (props: StaticProps) =>\n modalStack.render({ status: 'error', ...props });\nModal.warning = (props: StaticProps) =>\n modalStack.render({ status: 'warning', ...props });\n// `confirm` is a mode, not a status, so it rides its own `mode` axis rather\n// than `status`.\nModal.confirm = (props: StaticProps) =>\n modalStack.render({ mode: 'confirm', ...props });\n\nexport default Modal;\n"],"mappings":"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"}
@@ -2,12 +2,6 @@
2
2
  type ToastStatus = 'info' | 'success' | 'error' | 'warning';
3
3
  interface Props {
4
4
  status?: ToastStatus;
5
- /**
6
- * @deprecated Use `status`. Kept as an alias so existing
7
- * `type="info|success|error|warning"` usage keeps working; `status` matches
8
- * the shared semantic-state vocabulary used by `Result`.
9
- */
10
- type?: ToastStatus;
11
5
  title: React.ReactNode;
12
6
  description?: React.ReactNode;
13
7
  icon?: React.ReactNode;
@@ -22,7 +16,7 @@ interface StaticProps extends Props {
22
16
  container?: HTMLElement;
23
17
  }
24
18
  declare const Toast: {
25
- ({ status, type, title, description, icon, closable, action, className, onClose }: Props): import("react").JSX.Element;
19
+ ({ status, title, description, icon, closable, action, className, onClose }: Props): import("react").JSX.Element;
26
20
  destroy: (id?: string) => void;
27
21
  destroyAll(): void;
28
22
  info(title: React.ReactNode, props?: TriggerOptions): string | undefined;
@@ -30,7 +24,7 @@ declare const Toast: {
30
24
  error(title: React.ReactNode, props?: TriggerOptions): string | undefined;
31
25
  warning(title: React.ReactNode, props?: TriggerOptions): string | undefined;
32
26
  };
33
- type TriggerOptions = Omit<StaticProps, 'status' | 'type' | 'title'>;
27
+ type TriggerOptions = Omit<StaticProps, 'status' | 'title'>;
34
28
  //#endregion
35
29
  export { Props, type StaticProps as ToastOptions, Toast as default };
36
30
  //# sourceMappingURL=toast.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"toast.d.mts","names":[],"sources":["../../../src/components/organisms/toast.tsx"],"mappings":";KAkBK;UAEY;EACf,SAAS;;;;;;EAMT,OAAO;EACP,OAAO,MAAM;EACb,cAAc,MAAM;EACpB,OAAO,MAAM;EACb;EACA,SAAS,MAAM;EACf;EACA;;UAGQ,oBAAoB;EAC5B;EACA;EACA,YAAY;;cAUR;KAUH,QAAA,MAAA,OAAA,aAAA,MAAA,UAAA,QAAA,WAAA,WAAA,wBAAK,IAAA;;;EAsHa,KAAA,OAAA,MAAM,WAAS,QAAU;EAEtB,QAAA,OAAA,MAAM,WAAS,QAAU;EAE3B,MAAA,OAAA,MAAM,WAAS,QAAU;EAEvB,QAAA,OAAA,MAAM,WAAS,QAAU;;KAR5C,iBAAiB,KAAK"}
1
+ {"version":3,"file":"toast.d.mts","names":[],"sources":["../../../src/components/organisms/toast.tsx"],"mappings":";KAkBK;UAEY;EACf,SAAS;EACT,OAAO,MAAM;EACb,cAAc,MAAM;EACpB,OAAO,MAAM;EACb;EACA,SAAS,MAAM;EACf;EACA;;UAGQ,oBAAoB;EAC5B;EACA;EACA,YAAY;;cAUR;KASH,QAAA,OAAA,aAAA,MAAA,UAAA,QAAA,WAAA,WAAA,wBAAK,IAAA;;;EAoHa,KAAA,OAAA,MAAM,WAAS,QAAU;EAEtB,QAAA,OAAA,MAAM,WAAS,QAAU;EAE3B,MAAA,OAAA,MAAM,WAAS,QAAU;EAEvB,QAAA,OAAA,MAAM,WAAS,QAAU;;KAR5C,iBAAiB,KAAK"}
@@ -15,16 +15,15 @@ const STATUS_ICONS = {
15
15
  error: /* @__PURE__ */ jsx(OctagonX, { className: "text-red-400" }),
16
16
  warning: /* @__PURE__ */ jsx(OctagonAlert, { className: "text-yellow-400" })
17
17
  };
18
- const Toast = ({ status, type, title, description, icon, closable = true, action, className, onClose }) => {
18
+ const Toast = ({ status, title, description, icon, closable = true, action, className, onClose }) => {
19
19
  const { locale } = useConfig();
20
- const resolvedStatus = status ?? type;
21
20
  return /* @__PURE__ */ jsxs("div", {
22
- role: resolvedStatus === "error" ? "alert" : "status",
21
+ role: status === "error" ? "alert" : "status",
23
22
  className: cn("pointer-events-auto flex w-80 items-start gap-3 rounded-lg", "bg-background text-foreground border p-4 shadow-lg", className),
24
23
  children: [
25
- (icon || resolvedStatus) && /* @__PURE__ */ jsx("div", {
24
+ (icon || status) && /* @__PURE__ */ jsx("div", {
26
25
  className: "mt-0.5 shrink-0 [&_svg]:size-5",
27
- children: icon || resolvedStatus && STATUS_ICONS[resolvedStatus]
26
+ children: icon || status && STATUS_ICONS[status]
28
27
  }),
29
28
  /* @__PURE__ */ jsxs("div", {
30
29
  className: "flex-1 space-y-1",
@@ -1 +1 @@
1
- {"version":3,"file":"toast.mjs","names":[],"sources":["../../../src/components/organisms/toast.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { useTimeout } from '@jbpark/use-hooks';\nimport { Check, Info, OctagonAlert, OctagonX, X } from 'lucide-react';\n\nimport { DEFAULT_LOCALE, useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport Button from '../atoms/button';\nimport {\n type ImperativeStack,\n createImperativeStack,\n isBrowser,\n} from './imperative-stack';\n\ntype ToastStatus = 'info' | 'success' | 'error' | 'warning';\n\nexport interface Props {\n status?: ToastStatus;\n /**\n * @deprecated Use `status`. Kept as an alias so existing\n * `type=\"info|success|error|warning\"` usage keeps working; `status` matches\n * the shared semantic-state vocabulary used by `Result`.\n */\n type?: ToastStatus;\n title: React.ReactNode;\n description?: React.ReactNode;\n icon?: React.ReactNode;\n closable?: boolean;\n action?: React.ReactNode;\n className?: string;\n onClose?: () => void;\n}\n\ninterface StaticProps extends Props {\n id?: string;\n duration?: number;\n container?: HTMLElement;\n}\n\nconst STATUS_ICONS: Record<ToastStatus, React.ReactNode> = {\n info: <Info className=\"text-blue-400\" />,\n success: <Check className=\"text-green-400\" />,\n error: <OctagonX className=\"text-red-400\" />,\n warning: <OctagonAlert className=\"text-yellow-400\" />,\n};\n\nconst Toast = ({\n status,\n type,\n title,\n description,\n icon,\n closable = true,\n action,\n className,\n onClose,\n}: Props) => {\n const { locale } = useConfig();\n // `type` is the deprecated alias for `status`; prefer `status` when both set.\n const resolvedStatus = status ?? type;\n\n return (\n <div\n role={resolvedStatus === 'error' ? 'alert' : 'status'}\n className={cn(\n 'pointer-events-auto flex w-80 items-start gap-3 rounded-lg',\n 'bg-background text-foreground border p-4 shadow-lg',\n className,\n //\n )}\n >\n {(icon || resolvedStatus) && (\n <div className=\"mt-0.5 shrink-0 [&_svg]:size-5\">\n {icon || (resolvedStatus && STATUS_ICONS[resolvedStatus])}\n </div>\n )}\n <div className=\"flex-1 space-y-1\">\n <p className=\"text-sm font-medium\">{title}</p>\n {description && (\n <p className=\"text-muted-foreground text-sm\">{description}</p>\n )}\n {action && <div className=\"pt-1\">{action}</div>}\n </div>\n {closable && (\n <Button\n variant=\"text\"\n shape=\"circle\"\n size=\"small\"\n aria-label={locale.close ?? DEFAULT_LOCALE.close}\n icon={<X />}\n onClick={onClose}\n />\n )}\n </div>\n );\n};\n\nconst DEFAULT_DURATION = 4000;\n\nconst StaticToast = ({\n id,\n duration = DEFAULT_DURATION,\n container,\n onClose,\n ...props\n}: StaticProps & { id: string }): React.ReactPortal | null => {\n const [visible, setVisible] = useState(true);\n\n const close = () => {\n onClose?.();\n setVisible(false);\n setTimeout(() => {\n toastStack.destroy(id);\n }, 200);\n };\n\n const { reset, clear } = useTimeout(close, duration || null);\n\n if (!isBrowser) {\n return null;\n }\n\n return createPortal(\n <div\n className={cn(\n 'transition-all duration-200',\n visible ? 'opacity-100' : 'translate-x-2 opacity-0',\n )}\n // Without this, a toast with a closable/action button (or one the\n // user is mid-read on) could auto-dismiss itself out from under\n // them — hovering or focusing anything inside pauses the timer,\n // moving away restarts it from the full duration.\n onMouseEnter={clear}\n onMouseLeave={reset}\n onFocus={clear}\n onBlur={reset}\n >\n <Toast {...props} onClose={close} />\n </div>,\n toastStack.getRootElement(container)!,\n );\n};\n\nconst toastStack: ImperativeStack<StaticProps> =\n createImperativeStack<StaticProps>({\n createRootElement: () => {\n const el = document.createElement('div');\n el.setAttribute('role', 'region');\n // Plain DOM, created outside any React tree — no Config to read a\n // locale override from until #226 gives the imperative stack a way\n // to inherit one.\n el.setAttribute('aria-label', 'Notifications');\n el.style.zIndex = '10000';\n el.style.position = 'fixed';\n el.style.right = '0';\n el.style.bottom = '0';\n el.style.display = 'flex';\n el.style.flexDirection = 'column-reverse';\n el.style.gap = '8px';\n el.style.padding = '16px';\n el.style.pointerEvents = 'none';\n return el;\n },\n StackItem: StaticToast,\n });\n\nToast.destroy = toastStack.destroy;\n\nToast.destroyAll = () => {\n toastStack.destroy();\n};\n\ntype TriggerOptions = Omit<StaticProps, 'status' | 'type' | 'title'>;\n\nToast.info = (title: React.ReactNode, props?: TriggerOptions) =>\n toastStack.render({ status: 'info', title, ...props });\nToast.success = (title: React.ReactNode, props?: TriggerOptions) =>\n toastStack.render({ status: 'success', title, ...props });\nToast.error = (title: React.ReactNode, props?: TriggerOptions) =>\n toastStack.render({ status: 'error', title, ...props });\nToast.warning = (title: React.ReactNode, props?: TriggerOptions) =>\n toastStack.render({ status: 'warning', title, ...props });\n\nexport default Toast;\nexport type { StaticProps as ToastOptions };\n"],"mappings":"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"}
1
+ {"version":3,"file":"toast.mjs","names":[],"sources":["../../../src/components/organisms/toast.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { createPortal } from 'react-dom';\n\nimport { useTimeout } from '@jbpark/use-hooks';\nimport { Check, Info, OctagonAlert, OctagonX, X } from 'lucide-react';\n\nimport { DEFAULT_LOCALE, useConfig } from '@repo/ui/providers';\nimport { cn } from '@repo/ui/utils';\n\nimport Button from '../atoms/button';\nimport {\n type ImperativeStack,\n createImperativeStack,\n isBrowser,\n} from './imperative-stack';\n\ntype ToastStatus = 'info' | 'success' | 'error' | 'warning';\n\nexport interface Props {\n status?: ToastStatus;\n title: React.ReactNode;\n description?: React.ReactNode;\n icon?: React.ReactNode;\n closable?: boolean;\n action?: React.ReactNode;\n className?: string;\n onClose?: () => void;\n}\n\ninterface StaticProps extends Props {\n id?: string;\n duration?: number;\n container?: HTMLElement;\n}\n\nconst STATUS_ICONS: Record<ToastStatus, React.ReactNode> = {\n info: <Info className=\"text-blue-400\" />,\n success: <Check className=\"text-green-400\" />,\n error: <OctagonX className=\"text-red-400\" />,\n warning: <OctagonAlert className=\"text-yellow-400\" />,\n};\n\nconst Toast = ({\n status,\n title,\n description,\n icon,\n closable = true,\n action,\n className,\n onClose,\n}: Props) => {\n const { locale } = useConfig();\n\n return (\n <div\n role={status === 'error' ? 'alert' : 'status'}\n className={cn(\n 'pointer-events-auto flex w-80 items-start gap-3 rounded-lg',\n 'bg-background text-foreground border p-4 shadow-lg',\n className,\n //\n )}\n >\n {(icon || status) && (\n <div className=\"mt-0.5 shrink-0 [&_svg]:size-5\">\n {icon || (status && STATUS_ICONS[status])}\n </div>\n )}\n <div className=\"flex-1 space-y-1\">\n <p className=\"text-sm font-medium\">{title}</p>\n {description && (\n <p className=\"text-muted-foreground text-sm\">{description}</p>\n )}\n {action && <div className=\"pt-1\">{action}</div>}\n </div>\n {closable && (\n <Button\n variant=\"text\"\n shape=\"circle\"\n size=\"small\"\n aria-label={locale.close ?? DEFAULT_LOCALE.close}\n icon={<X />}\n onClick={onClose}\n />\n )}\n </div>\n );\n};\n\nconst DEFAULT_DURATION = 4000;\n\nconst StaticToast = ({\n id,\n duration = DEFAULT_DURATION,\n container,\n onClose,\n ...props\n}: StaticProps & { id: string }): React.ReactPortal | null => {\n const [visible, setVisible] = useState(true);\n\n const close = () => {\n onClose?.();\n setVisible(false);\n setTimeout(() => {\n toastStack.destroy(id);\n }, 200);\n };\n\n const { reset, clear } = useTimeout(close, duration || null);\n\n if (!isBrowser) {\n return null;\n }\n\n return createPortal(\n <div\n className={cn(\n 'transition-all duration-200',\n visible ? 'opacity-100' : 'translate-x-2 opacity-0',\n )}\n // Without this, a toast with a closable/action button (or one the\n // user is mid-read on) could auto-dismiss itself out from under\n // them — hovering or focusing anything inside pauses the timer,\n // moving away restarts it from the full duration.\n onMouseEnter={clear}\n onMouseLeave={reset}\n onFocus={clear}\n onBlur={reset}\n >\n <Toast {...props} onClose={close} />\n </div>,\n toastStack.getRootElement(container)!,\n );\n};\n\nconst toastStack: ImperativeStack<StaticProps> =\n createImperativeStack<StaticProps>({\n createRootElement: () => {\n const el = document.createElement('div');\n el.setAttribute('role', 'region');\n // Plain DOM, created outside any React tree — no Config to read a\n // locale override from until #226 gives the imperative stack a way\n // to inherit one.\n el.setAttribute('aria-label', 'Notifications');\n el.style.zIndex = '10000';\n el.style.position = 'fixed';\n el.style.right = '0';\n el.style.bottom = '0';\n el.style.display = 'flex';\n el.style.flexDirection = 'column-reverse';\n el.style.gap = '8px';\n el.style.padding = '16px';\n el.style.pointerEvents = 'none';\n return el;\n },\n StackItem: StaticToast,\n });\n\nToast.destroy = toastStack.destroy;\n\nToast.destroyAll = () => {\n toastStack.destroy();\n};\n\ntype TriggerOptions = Omit<StaticProps, 'status' | 'title'>;\n\nToast.info = (title: React.ReactNode, props?: TriggerOptions) =>\n toastStack.render({ status: 'info', title, ...props });\nToast.success = (title: React.ReactNode, props?: TriggerOptions) =>\n toastStack.render({ status: 'success', title, ...props });\nToast.error = (title: React.ReactNode, props?: TriggerOptions) =>\n toastStack.render({ status: 'error', title, ...props });\nToast.warning = (title: React.ReactNode, props?: TriggerOptions) =>\n toastStack.render({ status: 'warning', title, ...props });\n\nexport default Toast;\nexport type { StaticProps as ToastOptions };\n"],"mappings":";;;;;;;;;;;AAqCA,MAAM,eAAqD;CACzD,MAAM,oBAAC,MAAD,EAAM,WAAU,gBAAiB,CAAA;CACvC,SAAS,oBAAC,OAAD,EAAO,WAAU,iBAAkB,CAAA;CAC5C,OAAO,oBAAC,UAAD,EAAU,WAAU,eAAgB,CAAA;CAC3C,SAAS,oBAAC,cAAD,EAAc,WAAU,kBAAmB,CAAA;AACtD;AAEA,MAAM,SAAS,EACb,QACA,OACA,aACA,MACA,WAAW,MACX,QACA,WACA,cACW;CACX,MAAM,EAAE,WAAW,UAAU;CAE7B,OACE,qBAAC,OAAD;EACE,MAAM,WAAW,UAAU,UAAU;EACrC,WAAW,GACT,8DACA,sDACA,SAEF;EAPF,UAAA;IASI,QAAQ,WACR,oBAAC,OAAD;IAAK,WAAU;IACZ,UAAA,QAAS,UAAU,aAAa;GAC9B,CAAA;GAEP,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACE,oBAAC,KAAD;MAAG,WAAU;MAAuB,UAAA;KAAS,CAAA;KAC5C,eACC,oBAAC,KAAD;MAAG,WAAU;MAAiC,UAAA;KAAe,CAAA;KAE9D,UAAU,oBAAC,OAAD;MAAK,WAAU;MAAQ,UAAA;KAAY,CAAA;IAC3C;;GACJ,YACC,oBAAC,QAAD;IACE,SAAQ;IACR,OAAM;IACN,MAAK;IACL,cAAY,OAAO,SAAS,eAAe;IAC3C,MAAM,oBAAC,GAAD,CAAI,CAAA;IACV,SAAS;GACV,CAAA;EAEA;;AAET;AAEA,MAAM,mBAAmB;AAEzB,MAAM,eAAe,EACnB,IACA,WAAW,kBACX,WACA,SACA,GAAG,YACyD;CAC5D,MAAM,CAAC,SAAS,cAAc,SAAS,IAAI;CAE3C,MAAM,cAAc;EAClB,UAAU;EACV,WAAW,KAAK;EAChB,iBAAiB;GACf,WAAW,QAAQ,EAAE;EACvB,GAAG,GAAG;CACR;CAEA,MAAM,EAAE,OAAO,UAAU,WAAW,OAAO,YAAY,IAAI;CAE3D,IAAI,CAAC,WACH,OAAO;CAGT,OAAO,aACL,oBAAC,OAAD;EACE,WAAW,GACT,+BACA,UAAU,gBAAgB,yBAC5B;EAKA,cAAc;EACd,cAAc;EACd,SAAS;EACT,QAAQ;EAER,UAAA,oBAAC,OAAD;GAAO,GAAI;GAAO,SAAS;EAAQ,CAAA;CAChC,CAAA,GACL,WAAW,eAAe,SAAS,CACrC;AACF;AAEA,MAAM,aACJ,sBAAmC;CACjC,yBAAyB;EACvB,MAAM,KAAK,SAAS,cAAc,KAAK;EACvC,GAAG,aAAa,QAAQ,QAAQ;EAIhC,GAAG,aAAa,cAAc,eAAe;EAC7C,GAAG,MAAM,SAAS;EAClB,GAAG,MAAM,WAAW;EACpB,GAAG,MAAM,QAAQ;EACjB,GAAG,MAAM,SAAS;EAClB,GAAG,MAAM,UAAU;EACnB,GAAG,MAAM,gBAAgB;EACzB,GAAG,MAAM,MAAM;EACf,GAAG,MAAM,UAAU;EACnB,GAAG,MAAM,gBAAgB;EACzB,OAAO;CACT;CACA,WAAW;AACb,CAAC;AAEH,MAAM,UAAU,WAAW;AAE3B,MAAM,mBAAmB;CACvB,WAAW,QAAQ;AACrB;AAIA,MAAM,QAAQ,OAAwB,UACpC,WAAW,OAAO;CAAE,QAAQ;CAAQ;CAAO,GAAG;AAAM,CAAC;AACvD,MAAM,WAAW,OAAwB,UACvC,WAAW,OAAO;CAAE,QAAQ;CAAW;CAAO,GAAG;AAAM,CAAC;AAC1D,MAAM,SAAS,OAAwB,UACrC,WAAW,OAAO;CAAE,QAAQ;CAAS;CAAO,GAAG;AAAM,CAAC;AACxD,MAAM,WAAW,OAAwB,UACvC,WAAW,OAAO;CAAE,QAAQ;CAAW;CAAO,GAAG;AAAM,CAAC"}
@@ -1,2 +1,25 @@
1
- import "react";
2
- import "class-variance-authority";
1
+ import * as React$1 from "react";
2
+ import { VariantProps } from "class-variance-authority";
3
+ //#region src/core/badge.d.ts
4
+ /**
5
+ * Vendored from shadcn's `new-york-v4` badge registry entry.
6
+ *
7
+ * Two deliberate local adaptations, both of which must survive the next sync:
8
+ * - upstream imports `Slot` from the unified `radix-ui` package; this repo
9
+ * installs the individual `@radix-ui/*` packages (13 of them) and has no
10
+ * `radix-ui` dependency, so the import stays on `@radix-ui/react-slot`.
11
+ * - `cn` resolves through `@repo/ui/utils` rather than upstream's `cn` alias.
12
+ *
13
+ * Everything else is upstream verbatim, including the `rounded-full` /
14
+ * `border-transparent` base and the `ghost` / `link` variants.
15
+ */
16
+ declare const badgeVariants: (props?: ({
17
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
18
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
19
+ type Props = React$1.ComponentProps<'span'> & VariantProps<typeof badgeVariants> & {
20
+ asChild?: boolean;
21
+ };
22
+ declare function Badge({ className, variant, asChild, ...props }: Props): React$1.JSX.Element;
23
+ //#endregion
24
+ export { Badge, type Props, badgeVariants };
25
+ //# sourceMappingURL=badge.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge.d.mts","names":[],"sources":["../../src/core/badge.tsx"],"mappings":";;;;;;;;;;;;;;;cAmBM,gBAAa;;6CA0BlB;KAEI,QAAQ,QAAM,yBACjB,oBAAoB;EAClB;;iBAGK,QACP,WACA,SACA,YACG,SACF,QAAK,QAAA,IAAA"}
@@ -0,0 +1,47 @@
1
+ import { cn } from "../utils.mjs";
2
+ import "react";
3
+ import { Slot } from "@radix-ui/react-slot";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { cva } from "class-variance-authority";
6
+ //#region src/core/badge.tsx
7
+ /**
8
+ * Vendored from shadcn's `new-york-v4` badge registry entry.
9
+ *
10
+ * Two deliberate local adaptations, both of which must survive the next sync:
11
+ * - upstream imports `Slot` from the unified `radix-ui` package; this repo
12
+ * installs the individual `@radix-ui/*` packages (13 of them) and has no
13
+ * `radix-ui` dependency, so the import stays on `@radix-ui/react-slot`.
14
+ * - `cn` resolves through `@repo/ui/utils` rather than upstream's `cn` alias.
15
+ *
16
+ * Everything else is upstream verbatim, including the `rounded-full` /
17
+ * `border-transparent` base and the `ghost` / `link` variants.
18
+ */
19
+ const badgeVariants = cva(`inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden
20
+ rounded-full border border-transparent px-2 py-0.5 text-xs font-medium
21
+ whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring
22
+ focus-visible:ring-[3px] focus-visible:ring-ring/50
23
+ aria-invalid:border-destructive aria-invalid:ring-destructive/20
24
+ dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none
25
+ [&>svg]:size-3`, {
26
+ variants: { variant: {
27
+ default: "bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
28
+ secondary: "bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
29
+ destructive: "bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90",
30
+ outline: "border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
31
+ ghost: "[a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
32
+ link: "text-primary underline-offset-4 [a&]:hover:underline"
33
+ } },
34
+ defaultVariants: { variant: "default" }
35
+ });
36
+ function Badge({ className, variant = "default", asChild = false, ...props }) {
37
+ return /* @__PURE__ */ jsx(asChild ? Slot : "span", {
38
+ "data-slot": "badge",
39
+ "data-variant": variant,
40
+ className: cn(badgeVariants({ variant }), className),
41
+ ...props
42
+ });
43
+ }
44
+ //#endregion
45
+ export { Badge, badgeVariants };
46
+
47
+ //# sourceMappingURL=badge.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"badge.mjs","names":[],"sources":["../../src/core/badge.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Slot } from '@radix-ui/react-slot';\nimport { type VariantProps, cva } from 'class-variance-authority';\n\nimport { cn } from '@repo/ui/utils';\n\n/**\n * Vendored from shadcn's `new-york-v4` badge registry entry.\n *\n * Two deliberate local adaptations, both of which must survive the next sync:\n * - upstream imports `Slot` from the unified `radix-ui` package; this repo\n * installs the individual `@radix-ui/*` packages (13 of them) and has no\n * `radix-ui` dependency, so the import stays on `@radix-ui/react-slot`.\n * - `cn` resolves through `@repo/ui/utils` rather than upstream's `cn` alias.\n *\n * Everything else is upstream verbatim, including the `rounded-full` /\n * `border-transparent` base and the `ghost` / `link` variants.\n */\nconst badgeVariants = cva(\n `inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden\n rounded-full border border-transparent px-2 py-0.5 text-xs font-medium\n whitespace-nowrap transition-[color,box-shadow] focus-visible:border-ring\n focus-visible:ring-[3px] focus-visible:ring-ring/50\n aria-invalid:border-destructive aria-invalid:ring-destructive/20\n dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none\n [&>svg]:size-3`,\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground [a&]:hover:bg-primary/90',\n secondary:\n 'bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',\n destructive:\n 'bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90',\n outline:\n 'border-border text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',\n ghost: '[a&]:hover:bg-accent [a&]:hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 [a&]:hover:underline',\n },\n },\n defaultVariants: {\n variant: 'default',\n },\n },\n);\n\ntype Props = React.ComponentProps<'span'> &\n VariantProps<typeof badgeVariants> & {\n asChild?: boolean;\n };\n\nfunction Badge({\n className,\n variant = 'default',\n asChild = false,\n ...props\n}: Props) {\n const Comp = asChild ? Slot : 'span';\n\n return (\n <Comp\n data-slot=\"badge\"\n data-variant={variant}\n className={cn(badgeVariants({ variant }), className)}\n {...props}\n />\n );\n}\n\nexport { Badge, badgeVariants, type Props };\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmBA,MAAM,gBAAgB,IACpB;;;;;;mBAOA;CACE,UAAU,EACR,SAAS;EACP,SAAS;EACT,WACE;EACF,aACE;EACF,SACE;EACF,OAAO;EACP,MAAM;CACR,EACF;CACA,iBAAiB,EACf,SAAS,UACX;AACF,CACF;AAOA,SAAS,MAAM,EACb,WACA,UAAU,WACV,UAAU,OACV,GAAG,SACK;CAGR,OACE,oBAHW,UAAU,OAAO,QAG5B;EACE,aAAU;EACV,gBAAc;EACd,WAAW,GAAG,cAAc,EAAE,QAAQ,CAAC,GAAG,SAAS;EACnD,GAAI;CACL,CAAA;AAEL"}
@@ -1,2 +1,14 @@
1
- import "react";
2
- import "class-variance-authority";
1
+ import * as React$1 from "react";
2
+ import { VariantProps } from "class-variance-authority";
3
+ //#region src/core/button.d.ts
4
+ declare const buttonVariants: (props?: ({
5
+ variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
6
+ size?: "icon" | "default" | "xs" | "sm" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
7
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
+ type Props = React$1.ComponentProps<'button'> & VariantProps<typeof buttonVariants> & {
9
+ asChild?: boolean;
10
+ };
11
+ declare function Button({ className, variant, size, asChild, ...props }: Props): React$1.JSX.Element;
12
+ //#endregion
13
+ export { Button, type Props, buttonVariants };
14
+ //# sourceMappingURL=button.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.d.mts","names":[],"sources":["../../src/core/button.tsx"],"mappings":";;;cAOM,iBAAc;;;6CAgCnB;KAEI,QAAQ,QAAM,2BACjB,oBAAoB;EAClB;;iBAGK,SACP,WACA,SACA,MACA,YACG,SACF,QAAK,QAAA,IAAA"}
@@ -2,8 +2,8 @@
2
2
  import { __exportAll } from "../_virtual/_rolldown/runtime.mjs";
3
3
  import { cn } from "../utils.mjs";
4
4
  import { useConfig } from "../providers/config/context.mjs";
5
- import Button from "../Button.mjs";
6
5
  import { OVERLAY_LAYER } from "../lib/z-layers.mjs";
6
+ import Button from "../Button.mjs";
7
7
  import "react";
8
8
  import { XIcon } from "lucide-react";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,2 +1,2 @@
1
1
  import "./label.mjs";
2
- import "class-variance-authority";
2
+ import { VariantProps } from "class-variance-authority";
package/dist/index.d.mts CHANGED
@@ -25,6 +25,10 @@ import Select from "./components/atoms/select.mjs";
25
25
  import Skeleton from "./components/atoms/skeleton/index.mjs";
26
26
  import Slider from "./components/atoms/slider/slider.mjs";
27
27
  import Spin from "./components/atoms/spin.mjs";
28
+ import { ComponentSize, DefaultProps, Locale, ThemeConfig, ThemeToken } from "./providers/config/types.mjs";
29
+ import { DEFAULT_LOCALE, useConfig } from "./providers/config/context.mjs";
30
+ import Config, { Props as Props$3 } from "./providers/config/config.mjs";
31
+ import { ConfigSnapshotProvider, getRootConfigValue } from "./providers/config/registry.mjs";
28
32
  import Switch from "./components/atoms/switch.mjs";
29
33
  import "./components/atoms/index.mjs";
30
34
  import Collapse, { Props as Props$2 } from "./components/molecules/collapse.mjs";
@@ -49,8 +53,4 @@ import Result, { Props as Props$17 } from "./components/templates/result.mjs";
49
53
  import PageHeader, { Props as Props$16 } from "./components/templates/page-header.mjs";
50
54
  import Row, { Props as Props$19 } from "./components/templates/grid/row.mjs";
51
55
  import Col, { Props as Props$1 } from "./components/templates/grid/col.mjs";
52
- import { ComponentSize, DefaultProps, Locale, ThemeConfig, ThemeToken } from "./providers/config/types.mjs";
53
- import { DEFAULT_LOCALE, useConfig } from "./providers/config/context.mjs";
54
- import Config, { Props as Props$3 } from "./providers/config/config.mjs";
55
- import { ConfigSnapshotProvider, getRootConfigValue } from "./providers/config/registry.mjs";
56
56
  export { Button, Card, type Props as CardProps, Checkbox, Col, type Props$1 as ColProps, Collapse, type Props$2 as CollapseProps, ColorPicker, type ComponentSize, Config, type Props$3 as ConfigProps, ConfigSnapshotProvider, Container, type Props$4 as ContainerProps, type Props$5 as ContentProps, DEFAULT_LOCALE, DatePicker, type DefaultProps, Drawer, type Props$6 as DrawerProps, Dropdown, type Props$7 as DropdownProps, Empty, type Props$8 as EmptyProps, FloatButton, type Props$9 as FooterProps, type Props$10 as HeaderProps, Input, Layout, type Props$11 as LayoutProps, List, type Props$12 as ListProps, type Locale, Marquees, type Props$13 as MarqueesProps, Menu, type Props$14 as MenuProps, Modal, type Props$15 as ModalProps, PageHeader, type Props$16 as PageHeaderProps, Popover, Progress, Radio, Result, type Props$17 as ResultProps, Reveals, type Props$18 as RevealsProps, RichTextEditor, Row, type Props$19 as RowProps, Select, type Props$20 as SiderProps, Skeleton, Slider, Space, type Props$21 as SpaceProps, Spin, Splitter, type Props$22 as SplitterProps, Swiper, type Props$23 as SwiperProps, Switch, Tag, type ThemeConfig, type ThemeToken, Toast, type StaticProps as ToastOptions, Typography, Upload, type UploadFile, type Props$24 as UploadProps, getRootConfigValue, useConfig };
@@ -5,41 +5,16 @@
5
5
  * `data-color`), so the same word means the same hue on either component
6
6
  * (#320).
7
7
  *
8
- * The names track **Tailwind's own palette names** (#342). They always did
9
- * track Tailwind's *values* — every preset was a Tailwind hue, just spelled
10
- * with antd's vocabulary — so four of them said one thing and rendered
11
- * another: `magenta` rendered Tailwind's `fuchsia`, `geekblue` rendered
12
- * `indigo`, `gold` rendered `amber`. Aligning the spelling makes the name and
13
- * the value agree, and lets `globals.css` resolve each entry straight from the
14
- * matching `--color-*` theme variable instead of a hand-copied hex.
8
+ * The names track **Tailwind's own palette names** (#342): every preset is a
9
+ * Tailwind hue spelled the way Tailwind spells it, so the name and the value
10
+ * agree and `globals.css` can resolve each entry straight from the matching
11
+ * `--color-*` theme variable instead of a hand-copied hex. The pre-8.0 antd
12
+ * spellings were removed in 9.0.0.
15
13
  *
16
14
  * Keep this list in sync with the `[data-color='…']` rules there.
17
15
  */
18
16
  declare const PRESET_COLORS: readonly ["blue", "purple", "cyan", "green", "fuchsia", "pink", "red", "orange", "yellow", "indigo", "lime", "amber"];
19
17
  type PresetColor = (typeof PRESET_COLORS)[number];
20
- /**
21
- * Pre-8.0 spellings, still accepted and still rendering exactly what they
22
- * rendered before — they are aliases, not a behaviour change:
23
- *
24
- * | deprecated | renders | canonical spelling |
25
- * | ---------- | ----------------- | ----------------------------- |
26
- * | `magenta` | `--color-fuchsia-500` | `fuchsia` |
27
- * | `geekblue` | `--color-indigo-500` | `indigo` |
28
- * | `gold` | `--color-amber-500` | `amber` |
29
- * | `volcano` | `--color-orange-600` | *(none — see below)* |
30
- *
31
- * `volcano` is the odd one out and has no canonical successor. Every other
32
- * preset is a distinct hue at Tailwind's `500` step, but `volcano` is
33
- * `orange-600` — the same hue as `orange`, one step darker. That makes it a
34
- * lightness variant masquerading as a hue, so it doesn't belong in a list
35
- * whose axis is "one entry per hue". It keeps rendering `orange-600` until the
36
- * next major; callers who want that exact shade can set `--btn-bg`/`--tag-bg`
37
- * directly.
38
- *
39
- * All four are removed in the next major.
40
- */
41
- declare const DEPRECATED_PRESET_COLORS: readonly ["magenta", "geekblue", "gold", "volcano"];
42
- type DeprecatedPresetColor = (typeof DEPRECATED_PRESET_COLORS)[number];
43
18
  //#endregion
44
- export { DEPRECATED_PRESET_COLORS, DeprecatedPresetColor, PRESET_COLORS, PresetColor };
19
+ export { PRESET_COLORS, PresetColor };
45
20
  //# sourceMappingURL=colors.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"colors.d.mts","names":[],"sources":["../../src/lib/colors.ts"],"mappings":";;;;;;;;;;;;;;;;;cAgBa;KAeD,sBAAsB;;;;;;;;;;;;;;;;;;;;;;cAuBrB;KAOD,gCAAgC"}
1
+ {"version":3,"file":"colors.d.mts","names":[],"sources":["../../src/lib/colors.ts"],"mappings":";;;;;;;;;;;;;;;cAca;KAeD,sBAAsB"}
package/dist/style.css CHANGED
@@ -103,54 +103,42 @@
103
103
  }
104
104
  }
105
105
  @layer components {
106
- :is([data-slot="button"], [data-slot="badge"])[data-color="blue"] {
106
+ :is([data-slot="button"], [data-slot="tag"])[data-color="blue"] {
107
107
  --preset-color: var(--color-blue-500);
108
108
  }
109
- :is([data-slot="button"], [data-slot="badge"])[data-color="purple"] {
109
+ :is([data-slot="button"], [data-slot="tag"])[data-color="purple"] {
110
110
  --preset-color: var(--color-purple-500);
111
111
  }
112
- :is([data-slot="button"], [data-slot="badge"])[data-color="cyan"] {
112
+ :is([data-slot="button"], [data-slot="tag"])[data-color="cyan"] {
113
113
  --preset-color: var(--color-cyan-500);
114
114
  }
115
- :is([data-slot="button"], [data-slot="badge"])[data-color="green"] {
115
+ :is([data-slot="button"], [data-slot="tag"])[data-color="green"] {
116
116
  --preset-color: var(--color-green-500);
117
117
  }
118
- :is([data-slot="button"], [data-slot="badge"])[data-color="fuchsia"] {
118
+ :is([data-slot="button"], [data-slot="tag"])[data-color="fuchsia"] {
119
119
  --preset-color: var(--color-fuchsia-500);
120
120
  }
121
- :is([data-slot="button"], [data-slot="badge"])[data-color="pink"] {
121
+ :is([data-slot="button"], [data-slot="tag"])[data-color="pink"] {
122
122
  --preset-color: var(--color-pink-500);
123
123
  }
124
- :is([data-slot="button"], [data-slot="badge"])[data-color="red"] {
124
+ :is([data-slot="button"], [data-slot="tag"])[data-color="red"] {
125
125
  --preset-color: var(--color-red-500);
126
126
  }
127
- :is([data-slot="button"], [data-slot="badge"])[data-color="orange"] {
127
+ :is([data-slot="button"], [data-slot="tag"])[data-color="orange"] {
128
128
  --preset-color: var(--color-orange-500);
129
129
  }
130
- :is([data-slot="button"], [data-slot="badge"])[data-color="yellow"] {
130
+ :is([data-slot="button"], [data-slot="tag"])[data-color="yellow"] {
131
131
  --preset-color: var(--color-yellow-500);
132
132
  }
133
- :is([data-slot="button"], [data-slot="badge"])[data-color="indigo"] {
133
+ :is([data-slot="button"], [data-slot="tag"])[data-color="indigo"] {
134
134
  --preset-color: var(--color-indigo-500);
135
135
  }
136
- :is([data-slot="button"], [data-slot="badge"])[data-color="lime"] {
136
+ :is([data-slot="button"], [data-slot="tag"])[data-color="lime"] {
137
137
  --preset-color: var(--color-lime-500);
138
138
  }
139
- :is([data-slot="button"], [data-slot="badge"])[data-color="amber"] {
139
+ :is([data-slot="button"], [data-slot="tag"])[data-color="amber"] {
140
140
  --preset-color: var(--color-amber-500);
141
141
  }
142
- :is([data-slot="button"], [data-slot="badge"])[data-color="magenta"] {
143
- --preset-color: var(--color-fuchsia-500);
144
- }
145
- :is([data-slot="button"], [data-slot="badge"])[data-color="geekblue"] {
146
- --preset-color: var(--color-indigo-500);
147
- }
148
- :is([data-slot="button"], [data-slot="badge"])[data-color="gold"] {
149
- --preset-color: var(--color-amber-500);
150
- }
151
- :is([data-slot="button"], [data-slot="badge"])[data-color="volcano"] {
152
- --preset-color: var(--color-orange-600);
153
- }
154
142
  [data-slot="button"][data-color] {
155
143
  --btn-bg: var(--preset-color);
156
144
  --btn-fg: white;
@@ -164,7 +152,7 @@
164
152
  --btn-bg-active: color-mix(in oklch, var(--btn-bg), black 22%);
165
153
  }
166
154
  }
167
- [data-slot="button"][data-color="yellow"], [data-slot="button"][data-color="lime"], [data-slot="button"][data-color="amber"], [data-slot="button"][data-color="gold"] {
155
+ [data-slot="button"][data-color="yellow"], [data-slot="button"][data-color="lime"], [data-slot="button"][data-color="amber"] {
168
156
  --btn-fg: black;
169
157
  }
170
158
  [data-slot="button"][data-color="default"] {
@@ -178,7 +166,7 @@
178
166
  [data-slot="button"][data-color="danger"] {
179
167
  --btn-bg: var(--destructive);
180
168
  }
181
- [data-slot="badge"][data-color] {
169
+ [data-slot="tag"][data-color] {
182
170
  --tag-bg: var(--preset-color);
183
171
  --tag-fg: var(--tag-bg);
184
172
  --tag-tint: var(--tag-bg);
@@ -186,32 +174,32 @@
186
174
  --tag-tint: color-mix(in oklab, var(--tag-bg), transparent 90%);
187
175
  }
188
176
  }
189
- [data-slot="badge"][data-color="default"] {
177
+ [data-slot="tag"][data-color="default"] {
190
178
  --tag-bg: var(--border);
191
179
  --tag-tint: var(--muted);
192
180
  --tag-fg: var(--muted-foreground);
193
181
  }
194
- [data-slot="badge"][data-color="default"][data-variant="outlined"] {
182
+ [data-slot="tag"][data-color="default"][data-variant="outlined"] {
195
183
  --tag-fg: var(--foreground);
196
184
  }
197
- [data-slot="badge"][data-color="primary"] {
185
+ [data-slot="tag"][data-color="primary"] {
198
186
  --tag-bg: var(--primary);
199
187
  }
200
- [data-slot="badge"][data-color="danger"] {
188
+ [data-slot="tag"][data-color="danger"] {
201
189
  --tag-bg: var(--destructive);
202
190
  }
203
- [data-slot="badge"][data-color="success"] {
191
+ [data-slot="tag"][data-color="success"] {
204
192
  --tag-bg: var(--color-green-500);
205
193
  --tag-fg: var(--color-green-600);
206
194
  }
207
- [data-slot="badge"][data-color="warning"] {
195
+ [data-slot="tag"][data-color="warning"] {
208
196
  --tag-bg: var(--color-yellow-500);
209
197
  --tag-fg: var(--color-yellow-600);
210
198
  }
211
- :is(.dark, [data-theme="dark"]) [data-slot="badge"][data-color="success"] {
199
+ :is(.dark, [data-theme="dark"]) [data-slot="tag"][data-color="success"] {
212
200
  --tag-fg: var(--color-green-400);
213
201
  }
214
- :is(.dark, [data-theme="dark"]) [data-slot="badge"][data-color="warning"] {
202
+ :is(.dark, [data-theme="dark"]) [data-slot="tag"][data-color="warning"] {
215
203
  --tag-fg: var(--color-yellow-400);
216
204
  }
217
205
  [data-slot="col"] {
@@ -349,6 +337,9 @@
349
337
  .left-0 {
350
338
  left: 0px;
351
339
  }
340
+ .left-0\.5 {
341
+ left: calc(var(--spacing) * 0.5);
342
+ }
352
343
  .left-1\/2 {
353
344
  left: calc(1 / 2 * 100%);
354
345
  }
@@ -448,12 +439,18 @@
448
439
  .mr-2 {
449
440
  margin-right: calc(var(--spacing) * 2);
450
441
  }
442
+ .mr-2\.5 {
443
+ margin-right: calc(var(--spacing) * 2.5);
444
+ }
451
445
  .mr-6 {
452
446
  margin-right: calc(var(--spacing) * 6);
453
447
  }
454
448
  .mr-7 {
455
449
  margin-right: calc(var(--spacing) * 7);
456
450
  }
451
+ .mr-9 {
452
+ margin-right: calc(var(--spacing) * 9);
453
+ }
457
454
  .mb-2 {
458
455
  margin-bottom: calc(var(--spacing) * 2);
459
456
  }
@@ -469,6 +466,9 @@
469
466
  .ml-2 {
470
467
  margin-left: calc(var(--spacing) * 2);
471
468
  }
469
+ .ml-2\.5 {
470
+ margin-left: calc(var(--spacing) * 2.5);
471
+ }
472
472
  .ml-4 {
473
473
  margin-left: calc(var(--spacing) * 4);
474
474
  }
@@ -478,6 +478,9 @@
478
478
  .ml-7 {
479
479
  margin-left: calc(var(--spacing) * 7);
480
480
  }
481
+ .ml-9 {
482
+ margin-left: calc(var(--spacing) * 9);
483
+ }
481
484
  .box-border {
482
485
  box-sizing: border-box;
483
486
  }
@@ -553,6 +556,10 @@
553
556
  width: calc(var(--spacing) * 8);
554
557
  height: calc(var(--spacing) * 8);
555
558
  }
559
+ .size-8\! {
560
+ width: calc(var(--spacing) * 8) !important;
561
+ height: calc(var(--spacing) * 8) !important;
562
+ }
556
563
  .size-9 {
557
564
  width: calc(var(--spacing) * 9);
558
565
  height: calc(var(--spacing) * 9);
@@ -591,6 +598,9 @@
591
598
  .h-10 {
592
599
  height: calc(var(--spacing) * 10);
593
600
  }
601
+ .h-10\! {
602
+ height: calc(var(--spacing) * 10) !important;
603
+ }
594
604
  .h-12 {
595
605
  height: calc(var(--spacing) * 12);
596
606
  }
@@ -654,6 +664,9 @@
654
664
  .w-15 {
655
665
  width: calc(var(--spacing) * 15);
656
666
  }
667
+ .w-16\! {
668
+ width: calc(var(--spacing) * 16) !important;
669
+ }
657
670
  .w-20 {
658
671
  width: calc(var(--spacing) * 20);
659
672
  }
@@ -2398,6 +2411,9 @@
2398
2411
  .data-\[state\=checked\]\:left-\[calc\(100\%-26px\)\][data-state="checked"] {
2399
2412
  left: calc(100% - 26px);
2400
2413
  }
2414
+ .data-\[state\=checked\]\:left-\[calc\(100\%-34px\)\][data-state="checked"] {
2415
+ left: calc(100% - 34px);
2416
+ }
2401
2417
  .data-\[state\=checked\]\:translate-x-\[calc\(100\%-2px\)\][data-state="checked"] {
2402
2418
  --tw-translate-x: calc(100% - 2px);
2403
2419
  translate: var(--tw-translate-x) var(--tw-translate-y);
@@ -3034,6 +3050,9 @@
3034
3050
  a.\[a\&\]\:hover\:text-accent-foreground:hover {
3035
3051
  color: var(--accent-foreground);
3036
3052
  }
3053
+ a.\[a\&\]\:hover\:underline:hover {
3054
+ text-decoration-line: underline;
3055
+ }
3037
3056
  }
3038
3057
  }
3039
3058
  :root {