@k8o/arte-odyssey 7.0.0 → 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 (88) hide show
  1. package/README.md +12 -3
  2. package/dist/components/buttons/button/button.mjs +8 -6
  3. package/dist/components/buttons/icon-button/icon-button.mjs +3 -2
  4. package/dist/components/buttons/icon-link/icon-link.mjs +3 -3
  5. package/dist/components/buttons/link-button/link-button.mjs +6 -6
  6. package/dist/components/data-display/accordion/accordion.mjs +4 -6
  7. package/dist/components/data-display/accordion/context.mjs +1 -1
  8. package/dist/components/data-display/avatar/avatar.mjs +3 -2
  9. package/dist/components/data-display/baseline-status/baseline-status.mjs +2 -2
  10. package/dist/components/data-display/code/code.mjs +5 -5
  11. package/dist/components/data-display/table/table.mjs +38 -54
  12. package/dist/components/feedback/alert/alert.mjs +22 -24
  13. package/dist/components/feedback/progress/progress.mjs +12 -14
  14. package/dist/components/feedback/skeleton/skeleton.mjs +4 -6
  15. package/dist/components/feedback/spinner/spinner.mjs +12 -14
  16. package/dist/components/feedback/toast/context.d.mts +18 -0
  17. package/dist/components/feedback/toast/context.mjs +29 -0
  18. package/dist/components/feedback/toast/index.d.mts +2 -1
  19. package/dist/components/feedback/toast/index.mjs +2 -1
  20. package/dist/components/feedback/toast/provider.d.mts +1 -7
  21. package/dist/components/feedback/toast/provider.mjs +3 -26
  22. package/dist/components/feedback/toast/toast.mjs +1 -1
  23. package/dist/components/form/autocomplete/autocomplete.mjs +12 -13
  24. package/dist/components/form/checkbox/checkbox.mjs +3 -4
  25. package/dist/components/form/checkbox-card/checkbox-card.mjs +7 -5
  26. package/dist/components/form/checkbox-group/checkbox-group.mjs +15 -9
  27. package/dist/components/form/file-field/file-field.mjs +7 -5
  28. package/dist/components/form/form/form.mjs +6 -8
  29. package/dist/components/form/form-control/form-control.mjs +12 -10
  30. package/dist/components/form/number-field/number-field.mjs +5 -5
  31. package/dist/components/form/password-input/password-input.mjs +1 -1
  32. package/dist/components/form/radio/radio.mjs +1 -2
  33. package/dist/components/form/radio-card/radio-card.mjs +8 -6
  34. package/dist/components/form/select/select.mjs +1 -1
  35. package/dist/components/form/slider/slider.mjs +1 -1
  36. package/dist/components/form/switch/switch.mjs +1 -2
  37. package/dist/components/form/text-field/text-field.mjs +1 -1
  38. package/dist/components/form/textarea/textarea.mjs +1 -1
  39. package/dist/components/icons/arte-odyssey.mjs +62 -68
  40. package/dist/components/icons/base.mjs +1 -3
  41. package/dist/components/icons/github-mark.mjs +13 -19
  42. package/dist/components/icons/logo.mjs +23 -29
  43. package/dist/components/icons/lucide.mjs +199 -379
  44. package/dist/components/icons/qiita.mjs +22 -28
  45. package/dist/components/icons/twitter.mjs +14 -20
  46. package/dist/components/index.d.mts +2 -1
  47. package/dist/components/index.mjs +2 -1
  48. package/dist/components/layout/scroll-linked/scroll-linked.mjs +1 -1
  49. package/dist/components/navigation/anchor/anchor.mjs +3 -3
  50. package/dist/components/navigation/breadcrumb/breadcrumb.mjs +18 -24
  51. package/dist/components/navigation/pagination/pagination.mjs +1 -1
  52. package/dist/components/navigation/tabs/tabs.mjs +14 -9
  53. package/dist/components/overlays/dialog/dialog.mjs +4 -3
  54. package/dist/components/overlays/dropdown-menu/dropdown-menu.mjs +7 -8
  55. package/dist/components/overlays/dropdown-menu/hooks.d.mts +1 -1
  56. package/dist/components/overlays/list-box/hooks.d.mts +1 -1
  57. package/dist/components/overlays/list-box/hooks.mjs +1 -1
  58. package/dist/components/overlays/list-box/list-box.mjs +14 -15
  59. package/dist/components/overlays/modal/modal.mjs +1 -1
  60. package/dist/components/overlays/popover/hooks.mjs +12 -8
  61. package/dist/components/overlays/tooltip/tooltip.mjs +7 -11
  62. package/dist/components/providers/arte-odyssey-provider.mjs +4 -6
  63. package/dist/components/providers/portal-root.mjs +5 -9
  64. package/dist/helpers/cn.mjs +1 -3
  65. package/dist/helpers/color/find-all-colors.d.mts +6 -5
  66. package/dist/helpers/color/find-all-colors.mjs +29 -29
  67. package/dist/helpers/number/between.mjs +1 -3
  68. package/dist/helpers/number/cast.mjs +3 -7
  69. package/dist/helpers/number/commalize.mjs +1 -1
  70. package/dist/helpers/uuid-v4.mjs +1 -1
  71. package/dist/hooks/click-away/index.mjs +2 -2
  72. package/dist/hooks/client/index.mjs +1 -3
  73. package/dist/hooks/debounced-transition/index.d.mts +1 -1
  74. package/dist/hooks/debounced-transition/index.mjs +5 -6
  75. package/dist/hooks/disclosure/index.mjs +9 -3
  76. package/dist/hooks/hash/index.mjs +5 -4
  77. package/dist/hooks/hover/index.mjs +6 -2
  78. package/dist/hooks/intersection-observer/use-intersection-observer.mjs +1 -1
  79. package/dist/hooks/resize/index.mjs +2 -2
  80. package/dist/hooks/scroll-direction/index.mjs +12 -20
  81. package/dist/hooks/scroll-lock/index.mjs +14 -18
  82. package/dist/hooks/window-resize/index.mjs +1 -1
  83. package/dist/hooks/window-size/index.mjs +1 -3
  84. package/dist/index.d.mts +2 -1
  85. package/dist/index.mjs +2 -1
  86. package/docs/references/components.md +18 -4
  87. package/docs/references/interaction-design.md +5 -2
  88. package/package.json +10 -10
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>
@@ -21,11 +21,13 @@ const Button = ({ ref, children, type = "button", size = "md", color = "primary"
21
21
  label: "Loading",
22
22
  size: size === "lg" ? "md" : "sm"
23
23
  }) : startIcon;
24
+ const hasStartIcon = resolvedStartIcon !== void 0;
25
+ const hasEndIcon = endIcon !== void 0;
24
26
  return /* @__PURE__ */ jsxs("button", {
25
27
  "aria-busy": isPending || void 0,
26
28
  className: cn("cursor-pointer rounded-full border-2 text-center font-bold transition-colors", {
27
- "border-transparent bg-primary-bg text-fg hover:bg-primary-bg-emphasize/80 active:bg-primary-bg-emphasize": variant === "contained" && color === "primary",
28
- "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",
29
31
  "border-transparent bg-bg-subtle text-fg-base hover:bg-bg-mute/80 active:bg-bg-mute": variant === "contained" && color === "gray",
30
32
  "cursor-not-allowed opacity-35 hover:bg-primary-bg active:bg-primary-bg": isDisabled && variant === "contained" && color === "primary",
31
33
  "cursor-not-allowed opacity-35 hover:bg-secondary-bg active:bg-secondary-bg": isDisabled && variant === "contained" && color === "secondary",
@@ -33,14 +35,14 @@ const Button = ({ ref, children, type = "button", size = "md", color = "primary"
33
35
  "border-primary-border bg-bg-base text-primary-fg hover:bg-bg-subtle active:bg-bg-mute": variant === "outlined" && color === "primary",
34
36
  "border-secondary-border bg-bg-base text-secondary-fg hover:bg-bg-subtle active:bg-bg-mute": variant === "outlined" && color === "secondary",
35
37
  "border-border-base bg-bg-base text-fg-base hover:bg-bg-subtle active:bg-bg-mute": variant === "outlined" && color === "gray",
36
- "cursor-not-allowed bg-bg-base opacity-35 hover:bg-bg-base active:bg-bg-base": isDisabled && variant === "outlined",
38
+ "cursor-not-allowed bg-bg-base opacity-35": isDisabled && variant === "outlined",
37
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",
38
- "cursor-not-allowed bg-transparent text-fg-mute opacity-35 hover:bg-transparent hover:text-fg-mute active:bg-transparent active:text-fg-mute": isDisabled && variant === "skeleton"
39
- }, "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(resolvedStartIcon ?? endIcon) && "flex items-center gap-2", resolvedStartIcon && endIcon ? "justify-between" : resolvedStartIcon && variant !== "skeleton" ? "justify-center" : endIcon && "justify-between"),
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"),
40
42
  disabled: isDisabled,
41
43
  onClick: handleClick,
42
44
  ref,
43
- type,
45
+ type: type === "submit" ? "submit" : "button",
44
46
  ...rest,
45
47
  children: [
46
48
  resolvedStartIcon,
@@ -18,13 +18,14 @@ const IconButton = ({ ref, size = "md", bg = "transparent", label, children, onA
18
18
  } : void 0;
19
19
  return /* @__PURE__ */ jsxs("button", {
20
20
  "aria-busy": isPending || void 0,
21
- "aria-label": props.role ? label : void 0,
21
+ "aria-label": props.role !== void 0 && props.role !== "" ? label : void 0,
22
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
23
  disabled: isDisabled,
24
24
  onClick: handleClick,
25
25
  ref,
26
+ type: "button",
26
27
  ...props,
27
- children: [!props.role && /* @__PURE__ */ jsx("span", {
28
+ children: [(props.role === void 0 || props.role === "") && /* @__PURE__ */ jsx("span", {
28
29
  className: "sr-only",
29
30
  children: label
30
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,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 };
@@ -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 }) => {
@@ -4,8 +4,9 @@ import { useState } from "react";
4
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);
@@ -10,11 +10,11 @@ const loadBaselineStatus = () => {
10
10
  const BaselineStatusResolved = ({ featureId }) => {
11
11
  use(loadBaselineStatus());
12
12
  return /* @__PURE__ */ jsx("baseline-status", {
13
- 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",
14
14
  featureId
15
15
  });
16
16
  };
17
- const BaselineStatusSkeleton = () => /* @__PURE__ */ jsx("div", { className: "h-58 max-w-full animate-pulse rounded-lg border border-border-base bg-bg-base p-4 sm:h-40 md:h-30" });
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
18
  const BaselineStatus = ({ featureId }) => /* @__PURE__ */ jsx(Suspense, {
19
19
  fallback: /* @__PURE__ */ jsx(BaselineStatusSkeleton, {}),
20
20
  children: /* @__PURE__ */ jsx(BaselineStatusResolved, { featureId })
@@ -5,24 +5,24 @@ import { jsx, jsxs } from "react/jsx-runtime";
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
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 };
@@ -0,0 +1,29 @@
1
+ "use client";
2
+ import { uuidV4 } from "../../../helpers/uuid-v4.mjs";
3
+ import { createContext, use, useCallback } from "react";
4
+ //#region src/components/feedback/toast/context.ts
5
+ const MAX_TOAST_COUNT = 5;
6
+ const SetToastContext = createContext(void 0);
7
+ const useToast = () => {
8
+ const setToasts = use(SetToastContext);
9
+ if (!setToasts) throw new Error("useToast must be used within a ToastProvider");
10
+ return {
11
+ onOpen: useCallback((status, message) => {
12
+ setToasts((prev) => {
13
+ return [...prev, {
14
+ id: uuidV4(),
15
+ status,
16
+ message
17
+ }].slice(-MAX_TOAST_COUNT);
18
+ });
19
+ }, [setToasts]),
20
+ onClose: useCallback((id) => {
21
+ setToasts((prev) => prev.filter((toast) => toast.id !== id));
22
+ }, [setToasts]),
23
+ onCloseAll: useCallback(() => {
24
+ setToasts([]);
25
+ }, [setToasts])
26
+ };
27
+ };
28
+ //#endregion
29
+ export { SetToastContext, useToast };
@@ -1,2 +1,3 @@
1
- import { ToastProvider, useToast } from "./provider.mjs";
1
+ import { useToast } from "./context.mjs";
2
+ import { ToastProvider } from "./provider.mjs";
2
3
  export { ToastProvider, useToast };
@@ -1,2 +1,3 @@
1
- import { ToastProvider, useToast } from "./provider.mjs";
1
+ import { useToast } from "./context.mjs";
2
+ import { ToastProvider } from "./provider.mjs";
2
3
  export { ToastProvider, useToast };
@@ -1,15 +1,9 @@
1
- import { Status } from "../../../types/variables.mjs";
2
1
  import { FC, PropsWithChildren, RefObject } from "react";
3
2
 
4
3
  //#region src/components/feedback/toast/provider.d.ts
5
- declare const useToast: () => {
6
- onOpen: (status: Status, message: string) => void;
7
- onClose: (id: string) => void;
8
- onCloseAll: () => void;
9
- };
10
4
  declare const ToastProvider: FC<PropsWithChildren<{
11
5
  portalRef?: RefObject<HTMLElement | null>;
12
6
  position?: 'fixed' | 'absolute';
13
7
  }>>;
14
8
  //#endregion
15
- export { ToastProvider, useToast };
9
+ export { ToastProvider };
@@ -1,36 +1,13 @@
1
1
  "use client";
2
2
  import { cn } from "../../../helpers/cn.mjs";
3
- import { uuidV4 } from "../../../helpers/uuid-v4.mjs";
3
+ import { SetToastContext } from "./context.mjs";
4
4
  import { Toast } from "./toast.mjs";
5
- import { createContext, use, useCallback, useEffect, useRef, useState } from "react";
5
+ import { useEffect, useRef, useState } from "react";
6
6
  import { createPortal } from "react-dom";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
  import { AnimatePresence } from "motion/react";
9
9
  import * as motion$1 from "motion/react-client";
10
10
  //#region src/components/feedback/toast/provider.tsx
11
- const MAX_TOAST_COUNT = 5;
12
- const SetToastContext = createContext(void 0);
13
- const useToast = () => {
14
- const setToasts = use(SetToastContext);
15
- if (!setToasts) throw new Error("useToast must be used within a ToastProvider");
16
- return {
17
- onOpen: useCallback((status, message) => {
18
- setToasts((prev) => {
19
- return [...prev, {
20
- id: uuidV4(),
21
- status,
22
- message
23
- }].slice(-MAX_TOAST_COUNT);
24
- });
25
- }, [setToasts]),
26
- onClose: useCallback((id) => {
27
- setToasts((prev) => prev.filter((toast) => toast.id !== id));
28
- }, [setToasts]),
29
- onCloseAll: useCallback(() => {
30
- setToasts([]);
31
- }, [setToasts])
32
- };
33
- };
34
11
  const toastMotionVariants = {
35
12
  initial: {
36
13
  opacity: 0,
@@ -99,4 +76,4 @@ const ToastProvider = ({ children, portalRef = null, position = "fixed" }) => {
99
76
  });
100
77
  };
101
78
  //#endregion
102
- export { ToastProvider, useToast };
79
+ export { ToastProvider };
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Alert } from "../alert/alert.mjs";
3
+ import { useToast } from "./context.mjs";
3
4
  import { useTimeout } from "../../../hooks/timeout/index.mjs";
4
- import { useToast } from "./provider.mjs";
5
5
  import { useCallback } from "react";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  //#region src/components/feedback/toast/toast.tsx