@k8o/arte-odyssey 6.0.1 → 7.0.1

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 (114) hide show
  1. package/README.md +12 -3
  2. package/dist/components/buttons/button/button.d.mts +1 -0
  3. package/dist/components/buttons/button/button.mjs +36 -14
  4. package/dist/components/buttons/icon-button/icon-button.d.mts +1 -0
  5. package/dist/components/buttons/icon-button/icon-button.mjs +22 -4
  6. package/dist/components/buttons/icon-link/icon-link.mjs +3 -3
  7. package/dist/components/buttons/link-button/link-button.mjs +6 -6
  8. package/dist/components/data-display/accordion/accordion-item.mjs +1 -1
  9. package/dist/components/data-display/accordion/accordion.mjs +4 -6
  10. package/dist/components/data-display/accordion/context.mjs +2 -2
  11. package/dist/components/data-display/avatar/avatar.mjs +4 -3
  12. package/dist/components/data-display/baseline-status/baseline-status.mjs +14 -16
  13. package/dist/components/data-display/code/code.mjs +7 -7
  14. package/dist/components/data-display/table/table.mjs +38 -54
  15. package/dist/components/feedback/alert/alert.mjs +22 -24
  16. package/dist/components/feedback/progress/progress.mjs +12 -14
  17. package/dist/components/feedback/skeleton/skeleton.mjs +4 -6
  18. package/dist/components/feedback/spinner/spinner.mjs +12 -14
  19. package/dist/components/feedback/toast/context.d.mts +18 -0
  20. package/dist/components/feedback/toast/context.mjs +29 -0
  21. package/dist/components/feedback/toast/index.d.mts +2 -1
  22. package/dist/components/feedback/toast/index.mjs +2 -1
  23. package/dist/components/feedback/toast/provider.d.mts +1 -7
  24. package/dist/components/feedback/toast/provider.mjs +4 -24
  25. package/dist/components/feedback/toast/toast.mjs +2 -2
  26. package/dist/components/form/autocomplete/autocomplete.mjs +26 -17
  27. package/dist/components/form/checkbox/checkbox.mjs +6 -5
  28. package/dist/components/form/checkbox-card/checkbox-card.mjs +8 -6
  29. package/dist/components/form/checkbox-group/checkbox-group.mjs +15 -9
  30. package/dist/components/form/file-field/file-field.d.mts +1 -1
  31. package/dist/components/form/file-field/file-field.mjs +14 -9
  32. package/dist/components/form/form/form.d.mts +10 -0
  33. package/dist/components/form/form/form.mjs +12 -0
  34. package/dist/components/form/form/index.d.mts +2 -0
  35. package/dist/components/form/form/index.mjs +2 -0
  36. package/dist/components/form/form-control/form-control.mjs +13 -11
  37. package/dist/components/form/number-field/number-field.mjs +11 -8
  38. package/dist/components/form/password-input/password-input.mjs +6 -3
  39. package/dist/components/form/radio/radio.mjs +9 -7
  40. package/dist/components/form/radio-card/radio-card.mjs +9 -7
  41. package/dist/components/form/select/select.mjs +5 -2
  42. package/dist/components/form/slider/slider.mjs +6 -3
  43. package/dist/components/form/switch/switch.mjs +9 -7
  44. package/dist/components/form/text-field/text-field.mjs +5 -1
  45. package/dist/components/form/textarea/textarea.mjs +14 -7
  46. package/dist/components/icons/arte-odyssey.mjs +62 -68
  47. package/dist/components/icons/base.mjs +1 -3
  48. package/dist/components/icons/github-mark.mjs +13 -19
  49. package/dist/components/icons/logo.mjs +23 -29
  50. package/dist/components/icons/lucide.mjs +199 -379
  51. package/dist/components/icons/qiita.mjs +22 -28
  52. package/dist/components/icons/twitter.mjs +14 -20
  53. package/dist/components/index.d.mts +4 -2
  54. package/dist/components/index.mjs +5 -3
  55. package/dist/components/layout/scroll-linked/scroll-linked.mjs +1 -1
  56. package/dist/components/navigation/anchor/anchor.mjs +3 -3
  57. package/dist/components/navigation/breadcrumb/breadcrumb.d.mts +1 -1
  58. package/dist/components/navigation/breadcrumb/breadcrumb.mjs +18 -24
  59. package/dist/components/navigation/pagination/pagination.mjs +3 -5
  60. package/dist/components/navigation/tabs/tabs.mjs +14 -9
  61. package/dist/components/overlays/dialog/dialog.mjs +4 -3
  62. package/dist/components/overlays/drawer/drawer.mjs +1 -1
  63. package/dist/components/overlays/dropdown-menu/dropdown-menu.mjs +8 -9
  64. package/dist/components/overlays/dropdown-menu/hooks.d.mts +1 -1
  65. package/dist/components/overlays/list-box/hooks.d.mts +1 -1
  66. package/dist/components/overlays/list-box/hooks.mjs +1 -1
  67. package/dist/components/overlays/list-box/list-box.mjs +15 -16
  68. package/dist/components/overlays/modal/modal.mjs +20 -11
  69. package/dist/components/overlays/popover/hooks.mjs +12 -8
  70. package/dist/components/overlays/popover/popover.mjs +1 -1
  71. package/dist/components/overlays/tooltip/tooltip.mjs +7 -11
  72. package/dist/components/providers/arte-odyssey-provider.mjs +4 -6
  73. package/dist/components/providers/portal-root.mjs +6 -10
  74. package/dist/helpers/cn.mjs +1 -3
  75. package/dist/helpers/color/find-all-colors.d.mts +6 -5
  76. package/dist/helpers/color/find-all-colors.mjs +29 -29
  77. package/dist/helpers/number/between.mjs +1 -3
  78. package/dist/helpers/number/cast.mjs +3 -7
  79. package/dist/helpers/number/commalize.mjs +1 -1
  80. package/dist/helpers/uuid-v4.mjs +1 -1
  81. package/dist/hooks/click-away/index.mjs +2 -2
  82. package/dist/hooks/client/index.mjs +1 -3
  83. package/dist/hooks/debounced-transition/index.d.mts +5 -0
  84. package/dist/hooks/debounced-transition/index.mjs +49 -0
  85. package/dist/hooks/deferred-debounce/index.d.mts +4 -0
  86. package/dist/hooks/deferred-debounce/index.mjs +9 -0
  87. package/dist/hooks/disclosure/index.mjs +9 -3
  88. package/dist/hooks/hash/index.mjs +5 -4
  89. package/dist/hooks/hover/index.mjs +6 -2
  90. package/dist/hooks/index.d.mts +3 -3
  91. package/dist/hooks/index.mjs +3 -3
  92. package/dist/hooks/intersection-observer/use-intersection-observer.mjs +1 -1
  93. package/dist/hooks/interval/index.mjs +9 -6
  94. package/dist/hooks/resize/index.d.mts +0 -1
  95. package/dist/hooks/resize/index.mjs +6 -14
  96. package/dist/hooks/scroll-direction/index.mjs +12 -20
  97. package/dist/hooks/scroll-lock/index.mjs +14 -18
  98. package/dist/hooks/timeout/index.mjs +9 -6
  99. package/dist/hooks/window-resize/index.d.mts +0 -1
  100. package/dist/hooks/window-resize/index.mjs +6 -18
  101. package/dist/hooks/window-size/index.mjs +1 -3
  102. package/dist/index.d.mts +6 -4
  103. package/dist/index.mjs +7 -5
  104. package/dist/styles/index.css +9 -14
  105. package/dist/styles/tokens.d.mts +84 -0
  106. package/dist/styles/tokens.mjs +752 -0
  107. package/docs/references/components.md +18 -4
  108. package/docs/references/hooks.md +29 -27
  109. package/docs/references/interaction-design.md +5 -2
  110. package/package.json +29 -22
  111. package/dist/hooks/debounce/index.d.mts +0 -6
  112. package/dist/hooks/debounce/index.mjs +0 -35
  113. package/dist/hooks/throttle/index.d.mts +0 -6
  114. package/dist/hooks/throttle/index.mjs +0 -53
package/README.md CHANGED
@@ -58,7 +58,11 @@ import { Card } from '@k8o/arte-odyssey';
58
58
  function MyPage() {
59
59
  return (
60
60
  <Card title="Welcome to ArteOdyssey">
61
- <Button color="primary" variant="contained" onClick={() => alert('Hello!')}>
61
+ <Button
62
+ color="primary"
63
+ variant="contained"
64
+ onClick={() => alert('Hello!')}
65
+ >
62
66
  Click me
63
67
  </Button>
64
68
  </Card>
@@ -164,7 +168,9 @@ import { Button } from '@k8o/arte-odyssey';
164
168
  label="Email"
165
169
  isRequired
166
170
  errorText={error}
167
- renderInput={(props) => <TextField {...props} id="email" placeholder="Enter your email" />}
171
+ renderInput={(props) => (
172
+ <TextField {...props} id="email" placeholder="Enter your email" />
173
+ )}
168
174
  />
169
175
  <Button type="submit">Submit</Button>
170
176
  </form>;
@@ -185,7 +191,10 @@ function MyComponent() {
185
191
  <Button onClick={() => setIsOpen(true)}>Open Dialog</Button>
186
192
  {isOpen && (
187
193
  <Dialog.Root>
188
- <Dialog.Header title="Confirm Action" onClose={() => setIsOpen(false)} />
194
+ <Dialog.Header
195
+ title="Confirm Action"
196
+ onClose={() => setIsOpen(false)}
197
+ />
189
198
  <Dialog.Content>
190
199
  <p>Are you sure you want to continue?</p>
191
200
  <Button onClick={() => setIsOpen(false)}>Confirm</Button>
@@ -9,6 +9,7 @@ declare const Button: FC<{
9
9
  fullWidth?: boolean;
10
10
  startIcon?: ReactNode;
11
11
  endIcon?: ReactNode;
12
+ onAction?: () => void | Promise<void>;
12
13
  } & Omit<HTMLProps<HTMLButtonElement>, 'size' | 'type'>>;
13
14
  //#endregion
14
15
  export { Button };
@@ -1,29 +1,51 @@
1
+ "use client";
1
2
  import { cn } from "../../../helpers/cn.mjs";
2
- import { jsxs } from "react/jsx-runtime";
3
+ import { Spinner } from "../../feedback/spinner/spinner.mjs";
4
+ import { useTransition } from "react";
5
+ import { useFormStatus } from "react-dom";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
3
7
  //#region src/components/buttons/button/button.tsx
4
- const Button = ({ ref, children, type = "button", size = "md", color = "primary", variant = "contained", disabled = false, fullWidth = false, onClick, startIcon, endIcon, ...rest }) => {
8
+ const Button = ({ ref, children, type = "button", size = "md", color = "primary", variant = "contained", disabled = false, fullWidth = false, onAction, onClick, startIcon, endIcon, ...rest }) => {
9
+ const [transitionPending, startTransition] = useTransition();
10
+ const { pending: formPending } = useFormStatus();
11
+ const isPending = transitionPending || type === "submit" && formPending;
12
+ const isDisabled = disabled || isPending;
13
+ const handleClick = onClick || onAction ? (event) => {
14
+ onClick?.(event);
15
+ if (event.defaultPrevented) return;
16
+ if (onAction) startTransition(async () => {
17
+ await onAction();
18
+ });
19
+ } : void 0;
20
+ const resolvedStartIcon = isPending ? /* @__PURE__ */ jsx(Spinner, {
21
+ label: "Loading",
22
+ size: size === "lg" ? "md" : "sm"
23
+ }) : startIcon;
24
+ const hasStartIcon = resolvedStartIcon !== void 0;
25
+ const hasEndIcon = endIcon !== void 0;
5
26
  return /* @__PURE__ */ jsxs("button", {
27
+ "aria-busy": isPending || void 0,
6
28
  className: cn("cursor-pointer rounded-full border-2 text-center font-bold transition-colors", {
7
- "border-transparent bg-primary-bg text-fg hover:bg-primary-bg-emphasize/80 active:bg-primary-bg-emphasize": variant === "contained" && color === "primary",
8
- "border-transparent bg-secondary-bg text-fg hover:bg-secondary-bg-emphasize/80 active:bg-secondary-bg-emphasize": variant === "contained" && color === "secondary",
29
+ "border-transparent bg-primary-bg text-primary-fg hover:bg-primary-bg-emphasize/80 active:bg-primary-bg-emphasize": variant === "contained" && color === "primary",
30
+ "border-transparent bg-secondary-bg text-secondary-fg hover:bg-secondary-bg-emphasize/80 active:bg-secondary-bg-emphasize": variant === "contained" && color === "secondary",
9
31
  "border-transparent bg-bg-subtle text-fg-base hover:bg-bg-mute/80 active:bg-bg-mute": variant === "contained" && color === "gray",
10
- "cursor-not-allowed opacity-35 hover:bg-primary-bg active:bg-primary-bg": disabled && variant === "contained" && color === "primary",
11
- "cursor-not-allowed opacity-35 hover:bg-secondary-bg active:bg-secondary-bg": disabled && variant === "contained" && color === "secondary",
12
- "cursor-not-allowed opacity-35 hover:bg-bg-subtle active:bg-bg-subtle": disabled && variant === "contained" && color === "gray",
32
+ "cursor-not-allowed opacity-35 hover:bg-primary-bg active:bg-primary-bg": isDisabled && variant === "contained" && color === "primary",
33
+ "cursor-not-allowed opacity-35 hover:bg-secondary-bg active:bg-secondary-bg": isDisabled && variant === "contained" && color === "secondary",
34
+ "cursor-not-allowed opacity-35 hover:bg-bg-subtle active:bg-bg-subtle": isDisabled && variant === "contained" && color === "gray",
13
35
  "border-primary-border bg-bg-base text-primary-fg hover:bg-bg-subtle active:bg-bg-mute": variant === "outlined" && color === "primary",
14
36
  "border-secondary-border bg-bg-base text-secondary-fg hover:bg-bg-subtle active:bg-bg-mute": variant === "outlined" && color === "secondary",
15
37
  "border-border-base bg-bg-base text-fg-base hover:bg-bg-subtle active:bg-bg-mute": variant === "outlined" && color === "gray",
16
- "cursor-not-allowed bg-bg-base opacity-35 hover:bg-bg-base active:bg-bg-base": disabled && variant === "outlined",
38
+ "cursor-not-allowed bg-bg-base opacity-35": isDisabled && variant === "outlined",
17
39
  "border-transparent bg-transparent text-fg-mute hover:bg-bg-subtle hover:text-fg-base active:bg-bg-mute active:text-fg-base": variant === "skeleton",
18
- "cursor-not-allowed bg-transparent text-fg-mute opacity-35 hover:bg-transparent hover:text-fg-mute active:bg-transparent active:text-fg-mute": disabled && variant === "skeleton"
19
- }, "focus-visible:border-transparent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-border-info", size === "sm" && "px-3 py-1 text-sm", size === "md" && "px-4 py-2 text-md", size === "lg" && "px-6 py-3 text-lg", fullWidth && "w-full", Boolean(startIcon ?? endIcon) && "flex items-center gap-2", startIcon && endIcon ? "justify-between" : startIcon && variant !== "skeleton" ? "justify-center" : endIcon && "justify-between"),
20
- disabled,
21
- onClick,
40
+ "cursor-not-allowed bg-transparent text-fg-mute opacity-35": isDisabled && variant === "skeleton"
41
+ }, "focus-visible:border-transparent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-border-info", size === "sm" && "px-3 py-1 text-sm", size === "md" && "px-4 py-2 text-md", size === "lg" && "px-6 py-3 text-lg", fullWidth && "w-full", (hasStartIcon || hasEndIcon) && "flex items-center gap-2", hasStartIcon && hasEndIcon ? "justify-between" : hasStartIcon && variant !== "skeleton" ? "justify-center" : hasEndIcon && "justify-between"),
42
+ disabled: isDisabled,
43
+ onClick: handleClick,
22
44
  ref,
23
- type,
45
+ type: type === "submit" ? "submit" : "button",
24
46
  ...rest,
25
47
  children: [
26
- startIcon,
48
+ resolvedStartIcon,
27
49
  children,
28
50
  endIcon
29
51
  ]
@@ -5,6 +5,7 @@ type Props = {
5
5
  size?: 'sm' | 'md' | 'lg';
6
6
  bg?: 'transparent' | 'base' | 'primary' | 'secondary';
7
7
  label: string;
8
+ onAction?: () => void | Promise<void>;
8
9
  } & Omit<HTMLProps<HTMLButtonElement>, 'size' | 'type'>;
9
10
  declare const IconButton: FC<Props>;
10
11
  //#endregion
@@ -1,13 +1,31 @@
1
+ "use client";
1
2
  import { cn } from "../../../helpers/cn.mjs";
3
+ import { useTransition } from "react";
4
+ import { useFormStatus } from "react-dom";
2
5
  import { jsx, jsxs } from "react/jsx-runtime";
3
6
  //#region src/components/buttons/icon-button/icon-button.tsx
4
- const IconButton = ({ ref, size = "md", bg = "transparent", label, children, ...props }) => {
7
+ const IconButton = ({ ref, size = "md", bg = "transparent", label, children, onAction, onClick, disabled, ...props }) => {
8
+ const [transitionPending, startTransition] = useTransition();
9
+ const { pending: formPending } = useFormStatus();
10
+ const isPending = transitionPending || formPending;
11
+ const isDisabled = Boolean(disabled) || isPending;
12
+ const handleClick = onClick || onAction ? (event) => {
13
+ onClick?.(event);
14
+ if (event.defaultPrevented) return;
15
+ if (onAction) startTransition(async () => {
16
+ await onAction();
17
+ });
18
+ } : void 0;
5
19
  return /* @__PURE__ */ jsxs("button", {
6
- "aria-label": props.role ? label : void 0,
7
- className: cn("inline-flex cursor-pointer rounded-full transition-colors", "focus-visible:border-transparent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-border-info", (bg === "transparent" || bg === "base") && "hover:bg-bg-subtle active:bg-bg-mute", bg === "base" && "bg-bg-base", bg === "transparent" && "bg-transparent", bg === "primary" && "bg-primary-bg hover:bg-primary-bg-emphasize/80 active:bg-primary-bg-emphasize", bg === "secondary" && "bg-secondary-bg hover:bg-secondary-bg-emphasize/80 active:bg-secondary-bg-emphasize", size === "sm" && "p-1", size === "md" && "p-2", size === "lg" && "p-3", props.disabled && "cursor-not-allowed opacity-50 hover:bg-transparent active:bg-transparent"),
20
+ "aria-busy": isPending || void 0,
21
+ "aria-label": props.role !== void 0 && props.role !== "" ? label : void 0,
22
+ className: cn("inline-flex cursor-pointer rounded-full transition-colors", "focus-visible:border-transparent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-border-info", (bg === "transparent" || bg === "base") && "hover:bg-bg-subtle active:bg-bg-mute", bg === "base" && "bg-bg-base", bg === "transparent" && "bg-transparent", bg === "primary" && "bg-primary-bg hover:bg-primary-bg-emphasize/80 active:bg-primary-bg-emphasize", bg === "secondary" && "bg-secondary-bg hover:bg-secondary-bg-emphasize/80 active:bg-secondary-bg-emphasize", size === "sm" && "p-1", size === "md" && "p-2", size === "lg" && "p-3", isDisabled && "cursor-not-allowed opacity-50 hover:bg-transparent active:bg-transparent"),
23
+ disabled: isDisabled,
24
+ onClick: handleClick,
8
25
  ref,
26
+ type: "button",
9
27
  ...props,
10
- children: [!props.role && /* @__PURE__ */ jsx("span", {
28
+ children: [(props.role === void 0 || props.role === "") && /* @__PURE__ */ jsx("span", {
11
29
  className: "sr-only",
12
30
  children: label
13
31
  }), children]
@@ -2,9 +2,9 @@ import { cn } from "../../../helpers/cn.mjs";
2
2
  import { isInternalRoute } from "../../../helpers/is-internal-route.mjs";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/components/buttons/icon-link/icon-link.tsx
5
- const IconLink = ({ size = "md", bg = "transparent", label, href, children, openInNewTab = false, renderAnchor = ({ children, ...props }) => /* @__PURE__ */ jsx("a", {
6
- ...props,
7
- children
5
+ const IconLink = ({ size = "md", bg = "transparent", label, href, children, openInNewTab = false, renderAnchor = ({ children: anchorChildren, ...rest }) => /* @__PURE__ */ jsx("a", {
6
+ ...rest,
7
+ children: anchorChildren
8
8
  }) }) => {
9
9
  const props = (isInternalRoute(href) && !openInNewTab ? "internal" : "external") === "internal" ? {} : {
10
10
  target: "_blank",
@@ -2,9 +2,9 @@ import { cn } from "../../../helpers/cn.mjs";
2
2
  import { isInternalRoute } from "../../../helpers/is-internal-route.mjs";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
4
  //#region src/components/buttons/link-button/link-button.tsx
5
- const LinkButton = ({ children, size = "md", color = "primary", variant = "contained", href, startIcon, endIcon, active = false, openInNewTab = false, renderAnchor = ({ children, ...props }) => /* @__PURE__ */ jsx("a", {
6
- ...props,
7
- children
5
+ const LinkButton = ({ children, size = "md", color = "primary", variant = "contained", href, startIcon, endIcon, active = false, openInNewTab = false, renderAnchor = ({ children: anchorChildren, ...rest }) => /* @__PURE__ */ jsx("a", {
6
+ ...rest,
7
+ children: anchorChildren
8
8
  }) }) => {
9
9
  const props = (isInternalRoute(href) && !openInNewTab ? "internal" : "external") === "internal" ? {} : {
10
10
  target: "_blank",
@@ -13,14 +13,14 @@ const LinkButton = ({ children, size = "md", color = "primary", variant = "conta
13
13
  return renderAnchor({
14
14
  href,
15
15
  className: cn("rounded-full border-2 text-center font-bold transition-colors", {
16
- "border-transparent bg-primary-bg text-fg hover:bg-primary-bg-emphasize/80 active:bg-primary-bg-emphasize": variant === "contained" && color === "primary",
17
- "border-transparent bg-secondary-bg text-fg hover:bg-secondary-bg-emphasize/80 active:bg-secondary-bg-emphasize": variant === "contained" && color === "secondary",
16
+ "border-transparent bg-primary-bg text-primary-fg hover:bg-primary-bg-emphasize/80 active:bg-primary-bg-emphasize": variant === "contained" && color === "primary",
17
+ "border-transparent bg-secondary-bg text-secondary-fg hover:bg-secondary-bg-emphasize/80 active:bg-secondary-bg-emphasize": variant === "contained" && color === "secondary",
18
18
  "border-transparent bg-bg-subtle text-fg-base hover:bg-bg-mute/80 active:bg-bg-mute": variant === "contained" && color === "gray",
19
19
  "border-primary-border bg-bg-base text-primary-fg hover:bg-bg-subtle active:bg-bg-mute": variant === "outlined" && color === "primary",
20
20
  "border-secondary-border bg-bg-base text-secondary-fg hover:bg-bg-subtle active:bg-bg-mute": variant === "outlined" && color === "secondary",
21
21
  "border-border-base bg-bg-base text-fg-base hover:bg-bg-subtle active:bg-bg-mute": variant === "outlined" && color === "gray",
22
22
  "border-transparent bg-transparent text-fg-mute hover:bg-bg-subtle hover:text-fg-base active:bg-bg-mute active:text-fg-base": variant === "skeleton"
23
- }, "focus-visible:border-transparent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-border-info", size === "sm" && "px-3 py-1 text-sm", size === "md" && "px-4 py-2 text-md", size === "lg" && "px-6 py-3 text-lg", Boolean(startIcon ?? endIcon) && "flex items-center gap-2", Boolean(endIcon) && "justify-between", active && "text-fg-info hover:text-fg-info active:text-fg-info"),
23
+ }, "focus-visible:border-transparent focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-border-info", size === "sm" && "px-3 py-1 text-sm", size === "md" && "px-4 py-2 text-md", size === "lg" && "px-6 py-3 text-lg", Boolean(startIcon ?? endIcon) && "flex items-center gap-2", Boolean(endIcon) && "justify-between", active && "text-fg-info"),
24
24
  "aria-label": children,
25
25
  ...props,
26
26
  children: /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { AccordionItemProvider } from "./context.mjs";
3
- import { jsx } from "react/jsx-runtime";
4
3
  import { useId } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
5
  //#region src/components/data-display/accordion/accordion-item.tsx
6
6
  const AccordionItem = ({ children, defaultOpen = false }) => {
7
7
  return /* @__PURE__ */ jsx(AccordionItemProvider, {
@@ -1,10 +1,8 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  //#region src/components/data-display/accordion/accordion.tsx
3
- const Accordion = ({ children }) => {
4
- return /* @__PURE__ */ jsx("div", {
5
- className: "divide-y divide-border-mute",
6
- children
7
- });
8
- };
3
+ const Accordion = ({ children }) => /* @__PURE__ */ jsx("div", {
4
+ className: "divide-border-mute divide-y",
5
+ children
6
+ });
9
7
  //#endregion
10
8
  export { Accordion };
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { useDisclosure } from "../../../hooks/disclosure/index.mjs";
3
- import { jsx } from "react/jsx-runtime";
4
3
  import { createContext, use } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
5
  //#region src/components/data-display/accordion/context.tsx
6
6
  const OpenContext = createContext(false);
7
7
  const ToggleOpenContext = createContext(void 0);
@@ -14,7 +14,7 @@ const useToggleOpen = () => {
14
14
  };
15
15
  const useItemId = () => {
16
16
  const id = use(ItemIdContext);
17
- if (!id) throw new Error("useItemId must be used within AccordionProvider");
17
+ if (id === void 0 || id === "") throw new Error("useItemId must be used within AccordionProvider");
18
18
  return id;
19
19
  };
20
20
  const AccordionItemProvider = ({ defaultOpen = false, id, children }) => {
@@ -1,11 +1,12 @@
1
1
  "use client";
2
2
  import { cn } from "../../../helpers/cn.mjs";
3
- import { jsx } from "react/jsx-runtime";
4
3
  import { useState } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
5
  //#region src/components/data-display/avatar/avatar.tsx
6
6
  const getInitials = (name) => {
7
- if (!name) return "?";
8
- return name.trim().split(/\s+/).slice(0, 2).map((part) => part.charAt(0).toUpperCase()).join("") || "?";
7
+ if (name === void 0 || name === "") return "?";
8
+ const initials = name.trim().split(/\s+/).slice(0, 2).map((part) => part.charAt(0).toUpperCase()).join("");
9
+ return initials === "" ? "?" : initials;
9
10
  };
10
11
  const Avatar = ({ alt, fallback, name, size = "md", src }) => {
11
12
  const [failedSrc, setFailedSrc] = useState(null);
@@ -1,25 +1,23 @@
1
1
  "use client";
2
+ import { Suspense, use } from "react";
2
3
  import { jsx } from "react/jsx-runtime";
3
- import { useSyncExternalStore } from "react";
4
4
  //#region src/components/data-display/baseline-status/baseline-status.tsx
5
- let didInit = false;
6
- const BaselineStatus = ({ featureId }) => {
7
- if (!useSyncExternalStore((onStoreChange) => {
8
- if (!didInit) {
9
- didInit = true;
10
- import("baseline-status").then(() => {
11
- onStoreChange();
12
- });
13
- }
14
- return () => {};
15
- }, () => didInit, () => false)) return /* @__PURE__ */ jsx("div", {
16
- className: "max-w-full animate-pulse rounded-lg border border-border-base bg-bg-base p-4",
17
- style: { height: "120px" }
18
- });
5
+ let loadPromise = null;
6
+ const loadBaselineStatus = () => {
7
+ loadPromise ??= import("baseline-status");
8
+ return loadPromise;
9
+ };
10
+ const BaselineStatusResolved = ({ featureId }) => {
11
+ use(loadBaselineStatus());
19
12
  return /* @__PURE__ */ jsx("baseline-status", {
20
- className: "wrap-normal max-w-full rounded-lg border border-border-base bg-bg-base p-4",
13
+ className: "border-border-base bg-bg-base max-w-full rounded-lg border p-4 wrap-normal",
21
14
  featureId
22
15
  });
23
16
  };
17
+ const BaselineStatusSkeleton = () => /* @__PURE__ */ jsx("div", { className: "border-border-base bg-bg-base h-58 max-w-full animate-pulse rounded-lg border p-4 sm:h-40 md:h-30" });
18
+ const BaselineStatus = ({ featureId }) => /* @__PURE__ */ jsx(Suspense, {
19
+ fallback: /* @__PURE__ */ jsx(BaselineStatusSkeleton, {}),
20
+ children: /* @__PURE__ */ jsx(BaselineStatusResolved, { featureId })
21
+ });
24
22
  //#endregion
25
23
  export { BaselineStatus };
@@ -1,28 +1,28 @@
1
1
  import { findAllColors } from "../../../helpers/color/find-all-colors.mjs";
2
+ import { Fragment } from "react";
2
3
  import { jsx, jsxs } from "react/jsx-runtime";
3
- import { Fragment as Fragment$1 } from "react";
4
4
  //#region src/components/data-display/code/code.tsx
5
5
  const Code = ({ children }) => {
6
6
  const colors = findAllColors(children);
7
7
  if (colors.length === 0) return /* @__PURE__ */ jsx("code", {
8
- className: "m-0.5 rounded-md bg-bg-mute px-1.5 sm:py-0.5",
8
+ className: "bg-bg-mute m-0.5 rounded-md px-1.5 sm:py-0.5",
9
9
  children
10
10
  });
11
11
  const parts = [];
12
12
  let lastIndex = 0;
13
- colors.forEach((colorInfo, index) => {
13
+ for (const [index, colorInfo] of colors.entries()) {
14
14
  if (colorInfo.start > lastIndex) parts.push(children.slice(lastIndex, colorInfo.start));
15
- parts.push(/* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
15
+ parts.push(/* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
16
16
  "aria-label": `Color: ${colorInfo.color}`,
17
- className: "inline-block h-3 w-3 shrink-0 rounded-sm border border-border-base",
17
+ className: "border-border-base inline-block size-3 shrink-0 rounded-sm border",
18
18
  role: "img",
19
19
  style: { backgroundColor: colorInfo.color }
20
20
  }), children.slice(colorInfo.start, colorInfo.end)] }, `color-${String(index)}`));
21
21
  lastIndex = colorInfo.end;
22
- });
22
+ }
23
23
  if (lastIndex < children.length) parts.push(children.slice(lastIndex));
24
24
  return /* @__PURE__ */ jsx("code", {
25
- className: "m-0.5 inline-flex items-center gap-1 rounded-md bg-bg-mute px-1.5 sm:py-0.5",
25
+ className: "bg-bg-mute m-0.5 inline-flex items-center gap-1 rounded-md px-1.5 sm:py-0.5",
26
26
  children: parts
27
27
  });
28
28
  };
@@ -1,61 +1,45 @@
1
1
  import { cn } from "../../../helpers/cn.mjs";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  //#region src/components/data-display/table/table.tsx
4
- const Root = ({ children, className, containerClassName }) => {
5
- return /* @__PURE__ */ jsx("div", {
6
- className: cn("w-full overflow-x-auto rounded-lg border border-border-mute bg-bg-base", containerClassName),
7
- children: /* @__PURE__ */ jsx("table", {
8
- className: cn("min-w-full border-collapse text-left text-sm", className),
9
- children
10
- })
11
- });
12
- };
13
- const Head = ({ children, className }) => {
14
- return /* @__PURE__ */ jsx("thead", {
15
- className: cn("bg-bg-subtle", className),
16
- children
17
- });
18
- };
19
- const Body = ({ children, className }) => {
20
- return /* @__PURE__ */ jsx("tbody", {
21
- className: cn("[&_tr:last-child]:border-b-0", className),
22
- children
23
- });
24
- };
25
- const Row = ({ children, className, interactive = false }) => {
26
- return /* @__PURE__ */ jsx("tr", {
27
- className: cn("border-border-mute border-b transition-colors", interactive && "hover:bg-bg-mute", className),
28
- children
29
- });
30
- };
31
- const HeaderCell = ({ align = "left", children, className }) => {
32
- return /* @__PURE__ */ jsx("th", {
33
- className: cn("px-4 py-3 font-medium text-fg-base", align === "center" && "text-center", align === "right" && "text-right", className),
34
- scope: "col",
4
+ const Root = ({ children, className, containerClassName }) => /* @__PURE__ */ jsx("div", {
5
+ className: cn("w-full overflow-x-auto rounded-lg border border-border-mute bg-bg-base", containerClassName),
6
+ children: /* @__PURE__ */ jsx("table", {
7
+ className: cn("min-w-full border-collapse text-left text-sm", className),
35
8
  children
36
- });
37
- };
38
- const Cell = ({ align = "left", children, className, colSpan, tone = "default" }) => {
39
- return /* @__PURE__ */ jsx("td", {
40
- className: cn("px-4 py-3 align-middle", tone === "muted" ? "text-fg-mute" : "text-fg-base", align === "center" && "text-center", align === "right" && "text-right", className),
41
- colSpan,
42
- children
43
- });
44
- };
45
- const Caption = ({ children, className }) => {
46
- return /* @__PURE__ */ jsx("caption", {
47
- className: cn("caption-bottom px-4 py-3 text-fg-mute text-sm", className),
48
- children
49
- });
50
- };
51
- const EmptyState = ({ children, colSpan }) => {
52
- return /* @__PURE__ */ jsx(Row, { children: /* @__PURE__ */ jsx(Cell, {
53
- align: "center",
54
- className: "py-10 text-fg-mute",
55
- colSpan,
56
- children
57
- }) });
58
- };
9
+ })
10
+ });
11
+ const Head = ({ children, className }) => /* @__PURE__ */ jsx("thead", {
12
+ className: cn("bg-bg-subtle", className),
13
+ children
14
+ });
15
+ const Body = ({ children, className }) => /* @__PURE__ */ jsx("tbody", {
16
+ className: cn("[&_tr:last-child]:border-b-0", className),
17
+ children
18
+ });
19
+ const Row = ({ children, className, interactive = false }) => /* @__PURE__ */ jsx("tr", {
20
+ className: cn("border-border-mute border-b transition-colors", interactive && "hover:bg-bg-mute", className),
21
+ children
22
+ });
23
+ const HeaderCell = ({ align = "left", children, className }) => /* @__PURE__ */ jsx("th", {
24
+ className: cn("px-4 py-3 font-medium text-fg-base", align === "center" && "text-center", align === "right" && "text-right", className),
25
+ scope: "col",
26
+ children
27
+ });
28
+ const Cell = ({ align = "left", children, className, colSpan, tone = "default" }) => /* @__PURE__ */ jsx("td", {
29
+ className: cn("px-4 py-3 align-middle", tone === "muted" ? "text-fg-mute" : "text-fg-base", align === "center" && "text-center", align === "right" && "text-right", className),
30
+ colSpan,
31
+ children
32
+ });
33
+ const Caption = ({ children, className }) => /* @__PURE__ */ jsx("caption", {
34
+ className: cn("caption-bottom px-4 py-3 text-fg-mute text-sm", className),
35
+ children
36
+ });
37
+ const EmptyState = ({ children, colSpan }) => /* @__PURE__ */ jsx(Row, { children: /* @__PURE__ */ jsx(Cell, {
38
+ align: "center",
39
+ className: "text-fg-mute py-10",
40
+ colSpan,
41
+ children
42
+ }) });
59
43
  const Table = {
60
44
  Root,
61
45
  Head,
@@ -8,30 +8,28 @@ const STATUS_LABEL = {
8
8
  warning: "警告",
9
9
  error: "エラー"
10
10
  };
11
- const Alert = ({ status, message }) => {
12
- return /* @__PURE__ */ jsxs("div", {
13
- className: cn("flex items-center gap-3 rounded-lg p-4", status === "success" && "bg-bg-success", status === "info" && "bg-bg-info", status === "warning" && "bg-bg-warning", status === "error" && "bg-bg-error"),
14
- role: status === "error" || status === "warning" ? "alert" : "status",
15
- children: [/* @__PURE__ */ jsxs("span", {
16
- className: cn(status === "success" && "text-fg-success", status === "info" && "text-fg-info", status === "warning" && "text-fg-warning", status === "error" && "text-fg-error"),
17
- children: [/* @__PURE__ */ jsx(AlertIcon, {
18
- size: "md",
19
- status
20
- }), /* @__PURE__ */ jsx("span", {
21
- className: "sr-only",
22
- children: STATUS_LABEL[status]
23
- })]
24
- }), Array.isArray(message) ? message.length > 1 ? /* @__PURE__ */ jsx("ul", {
25
- className: "space-y-1",
26
- children: message.map((msg) => /* @__PURE__ */ jsx("li", { children: msg }, msg))
27
- }) : /* @__PURE__ */ jsx("p", {
28
- className: "font-bold",
29
- children: message[0]
30
- }) : /* @__PURE__ */ jsx("p", {
31
- className: "font-bold",
32
- children: message
11
+ const Alert = ({ status, message }) => /* @__PURE__ */ jsxs("div", {
12
+ className: cn("flex items-center gap-3 rounded-lg p-4", status === "success" && "bg-bg-success", status === "info" && "bg-bg-info", status === "warning" && "bg-bg-warning", status === "error" && "bg-bg-error"),
13
+ role: status === "error" || status === "warning" ? "alert" : "status",
14
+ children: [/* @__PURE__ */ jsxs("span", {
15
+ className: cn(status === "success" && "text-fg-success", status === "info" && "text-fg-info", status === "warning" && "text-fg-warning", status === "error" && "text-fg-error"),
16
+ children: [/* @__PURE__ */ jsx(AlertIcon, {
17
+ size: "md",
18
+ status
19
+ }), /* @__PURE__ */ jsx("span", {
20
+ className: "sr-only",
21
+ children: STATUS_LABEL[status]
33
22
  })]
34
- });
35
- };
23
+ }), Array.isArray(message) ? message.length > 1 ? /* @__PURE__ */ jsx("ul", {
24
+ className: "space-y-1",
25
+ children: message.map((msg) => /* @__PURE__ */ jsx("li", { children: msg }, msg))
26
+ }) : /* @__PURE__ */ jsx("p", {
27
+ className: "font-bold",
28
+ children: message[0]
29
+ }) : /* @__PURE__ */ jsx("p", {
30
+ className: "font-bold",
31
+ children: message
32
+ })]
33
+ });
36
34
  //#endregion
37
35
  export { Alert };
@@ -1,19 +1,17 @@
1
1
  import { toPrecision } from "../../../helpers/number/to-precision.mjs";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  //#region src/components/feedback/progress/progress.tsx
4
- const Progress = ({ progress, maxProgress, minProgress = 0, label }) => {
5
- return /* @__PURE__ */ jsx("div", {
6
- className: "w-full rounded-full bg-bg-emphasize",
7
- children: /* @__PURE__ */ jsx("div", {
8
- "aria-label": label ?? `${toPrecision(progress / maxProgress).toString()}%`,
9
- "aria-valuemax": maxProgress,
10
- "aria-valuemin": minProgress,
11
- "aria-valuenow": progress,
12
- className: "h-4 rounded-full bg-primary-bg transition-all",
13
- role: "progressbar",
14
- style: { width: `${(progress / maxProgress * 100).toString()}%` }
15
- })
16
- });
17
- };
4
+ const Progress = ({ progress, maxProgress, minProgress = 0, label }) => /* @__PURE__ */ jsx("div", {
5
+ className: "bg-bg-emphasize w-full rounded-full",
6
+ children: /* @__PURE__ */ jsx("div", {
7
+ "aria-label": label ?? `${toPrecision(progress / maxProgress).toString()}%`,
8
+ "aria-valuemax": maxProgress,
9
+ "aria-valuemin": minProgress,
10
+ "aria-valuenow": progress,
11
+ className: "bg-primary-bg h-4 rounded-full transition-all",
12
+ role: "progressbar",
13
+ style: { width: `${(progress / maxProgress * 100).toString()}%` }
14
+ })
15
+ });
18
16
  //#endregion
19
17
  export { Progress };
@@ -1,11 +1,9 @@
1
1
  import { cn } from "../../../helpers/cn.mjs";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
  //#region src/components/feedback/skeleton/skeleton.tsx
4
- const Skeleton = ({ animate = true, shape = "rect", size = "md" }) => {
5
- return /* @__PURE__ */ jsx("div", {
6
- "aria-hidden": true,
7
- className: cn("bg-bg-mute", animate && "animate-pulse", shape === "rect" && "rounded-lg", shape === "rect" && size === "sm" && "h-3 w-24", shape === "rect" && size === "md" && "h-4 w-40", shape === "rect" && size === "lg" && "h-5 w-56", shape === "circle" && "rounded-full", shape === "circle" && size === "sm" && "size-8", shape === "circle" && size === "md" && "size-12", shape === "circle" && size === "lg" && "size-16")
8
- });
9
- };
4
+ const Skeleton = ({ animate = true, shape = "rect", size = "md" }) => /* @__PURE__ */ jsx("div", {
5
+ "aria-hidden": true,
6
+ className: cn("bg-bg-mute", animate && "animate-pulse", shape === "rect" && "rounded-lg", shape === "rect" && size === "sm" && "h-3 w-24", shape === "rect" && size === "md" && "h-4 w-40", shape === "rect" && size === "lg" && "h-5 w-56", shape === "circle" && "rounded-full", shape === "circle" && size === "sm" && "size-8", shape === "circle" && size === "md" && "size-12", shape === "circle" && size === "lg" && "size-16")
7
+ });
10
8
  //#endregion
11
9
  export { Skeleton };
@@ -1,19 +1,17 @@
1
1
  import { cn } from "../../../helpers/cn.mjs";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  //#region src/components/feedback/spinner/spinner.tsx
4
- const Spinner = ({ label = "Loading", size = "md" }) => {
5
- return /* @__PURE__ */ jsxs("output", {
6
- "aria-label": label,
7
- "aria-live": "polite",
8
- className: "inline-flex items-center justify-center",
9
- children: [/* @__PURE__ */ jsx("span", {
10
- "aria-hidden": true,
11
- className: cn("inline-block animate-spin rounded-full border-4 border-border-base border-t-primary-border", size === "sm" && "size-4", size === "md" && "size-6", size === "lg" && "size-8")
12
- }), /* @__PURE__ */ jsx("span", {
13
- className: "sr-only",
14
- children: label
15
- })]
16
- });
17
- };
4
+ const Spinner = ({ label = "Loading", size = "md" }) => /* @__PURE__ */ jsxs("output", {
5
+ "aria-label": label,
6
+ "aria-live": "polite",
7
+ className: "inline-flex items-center justify-center",
8
+ children: [/* @__PURE__ */ jsx("span", {
9
+ "aria-hidden": true,
10
+ className: cn("inline-block animate-spin rounded-full border-4 border-border-base border-t-primary-border", size === "sm" && "size-4", size === "md" && "size-6", size === "lg" && "size-8")
11
+ }), /* @__PURE__ */ jsx("span", {
12
+ className: "sr-only",
13
+ children: label
14
+ })]
15
+ });
18
16
  //#endregion
19
17
  export { Spinner };
@@ -0,0 +1,18 @@
1
+ import { Status } from "../../../types/variables.mjs";
2
+ import * as _$react from "react";
3
+ import { Dispatch, SetStateAction } from "react";
4
+
5
+ //#region src/components/feedback/toast/context.d.ts
6
+ type ToastType = {
7
+ id: string;
8
+ status: Status;
9
+ message: string;
10
+ };
11
+ declare const SetToastContext: _$react.Context<Dispatch<SetStateAction<ToastType[]>> | undefined>;
12
+ declare const useToast: () => {
13
+ onOpen: (status: Status, message: string) => void;
14
+ onClose: (id: string) => void;
15
+ onCloseAll: () => void;
16
+ };
17
+ //#endregion
18
+ export { SetToastContext, ToastType, useToast };