@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.
- package/README.md +12 -3
- package/dist/components/buttons/button/button.mjs +8 -6
- package/dist/components/buttons/icon-button/icon-button.mjs +3 -2
- package/dist/components/buttons/icon-link/icon-link.mjs +3 -3
- package/dist/components/buttons/link-button/link-button.mjs +6 -6
- package/dist/components/data-display/accordion/accordion.mjs +4 -6
- package/dist/components/data-display/accordion/context.mjs +1 -1
- package/dist/components/data-display/avatar/avatar.mjs +3 -2
- package/dist/components/data-display/baseline-status/baseline-status.mjs +2 -2
- package/dist/components/data-display/code/code.mjs +5 -5
- package/dist/components/data-display/table/table.mjs +38 -54
- package/dist/components/feedback/alert/alert.mjs +22 -24
- package/dist/components/feedback/progress/progress.mjs +12 -14
- package/dist/components/feedback/skeleton/skeleton.mjs +4 -6
- package/dist/components/feedback/spinner/spinner.mjs +12 -14
- package/dist/components/feedback/toast/context.d.mts +18 -0
- package/dist/components/feedback/toast/context.mjs +29 -0
- package/dist/components/feedback/toast/index.d.mts +2 -1
- package/dist/components/feedback/toast/index.mjs +2 -1
- package/dist/components/feedback/toast/provider.d.mts +1 -7
- package/dist/components/feedback/toast/provider.mjs +3 -26
- package/dist/components/feedback/toast/toast.mjs +1 -1
- package/dist/components/form/autocomplete/autocomplete.mjs +12 -13
- package/dist/components/form/checkbox/checkbox.mjs +3 -4
- package/dist/components/form/checkbox-card/checkbox-card.mjs +7 -5
- package/dist/components/form/checkbox-group/checkbox-group.mjs +15 -9
- package/dist/components/form/file-field/file-field.mjs +7 -5
- package/dist/components/form/form/form.mjs +6 -8
- package/dist/components/form/form-control/form-control.mjs +12 -10
- package/dist/components/form/number-field/number-field.mjs +5 -5
- package/dist/components/form/password-input/password-input.mjs +1 -1
- package/dist/components/form/radio/radio.mjs +1 -2
- package/dist/components/form/radio-card/radio-card.mjs +8 -6
- package/dist/components/form/select/select.mjs +1 -1
- package/dist/components/form/slider/slider.mjs +1 -1
- package/dist/components/form/switch/switch.mjs +1 -2
- package/dist/components/form/text-field/text-field.mjs +1 -1
- package/dist/components/form/textarea/textarea.mjs +1 -1
- package/dist/components/icons/arte-odyssey.mjs +62 -68
- package/dist/components/icons/base.mjs +1 -3
- package/dist/components/icons/github-mark.mjs +13 -19
- package/dist/components/icons/logo.mjs +23 -29
- package/dist/components/icons/lucide.mjs +199 -379
- package/dist/components/icons/qiita.mjs +22 -28
- package/dist/components/icons/twitter.mjs +14 -20
- package/dist/components/index.d.mts +2 -1
- package/dist/components/index.mjs +2 -1
- package/dist/components/layout/scroll-linked/scroll-linked.mjs +1 -1
- package/dist/components/navigation/anchor/anchor.mjs +3 -3
- package/dist/components/navigation/breadcrumb/breadcrumb.mjs +18 -24
- package/dist/components/navigation/pagination/pagination.mjs +1 -1
- package/dist/components/navigation/tabs/tabs.mjs +14 -9
- package/dist/components/overlays/dialog/dialog.mjs +4 -3
- package/dist/components/overlays/dropdown-menu/dropdown-menu.mjs +7 -8
- package/dist/components/overlays/dropdown-menu/hooks.d.mts +1 -1
- package/dist/components/overlays/list-box/hooks.d.mts +1 -1
- package/dist/components/overlays/list-box/hooks.mjs +1 -1
- package/dist/components/overlays/list-box/list-box.mjs +14 -15
- package/dist/components/overlays/modal/modal.mjs +1 -1
- package/dist/components/overlays/popover/hooks.mjs +12 -8
- package/dist/components/overlays/tooltip/tooltip.mjs +7 -11
- package/dist/components/providers/arte-odyssey-provider.mjs +4 -6
- package/dist/components/providers/portal-root.mjs +5 -9
- package/dist/helpers/cn.mjs +1 -3
- package/dist/helpers/color/find-all-colors.d.mts +6 -5
- package/dist/helpers/color/find-all-colors.mjs +29 -29
- package/dist/helpers/number/between.mjs +1 -3
- package/dist/helpers/number/cast.mjs +3 -7
- package/dist/helpers/number/commalize.mjs +1 -1
- package/dist/helpers/uuid-v4.mjs +1 -1
- package/dist/hooks/click-away/index.mjs +2 -2
- package/dist/hooks/client/index.mjs +1 -3
- package/dist/hooks/debounced-transition/index.d.mts +1 -1
- package/dist/hooks/debounced-transition/index.mjs +5 -6
- package/dist/hooks/disclosure/index.mjs +9 -3
- package/dist/hooks/hash/index.mjs +5 -4
- package/dist/hooks/hover/index.mjs +6 -2
- package/dist/hooks/intersection-observer/use-intersection-observer.mjs +1 -1
- package/dist/hooks/resize/index.mjs +2 -2
- package/dist/hooks/scroll-direction/index.mjs +12 -20
- package/dist/hooks/scroll-lock/index.mjs +14 -18
- package/dist/hooks/window-resize/index.mjs +1 -1
- package/dist/hooks/window-size/index.mjs +1 -3
- package/dist/index.d.mts +2 -1
- package/dist/index.mjs +2 -1
- package/docs/references/components.md +18 -4
- package/docs/references/interaction-design.md +5 -2
- 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
|
|
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) =>
|
|
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
|
|
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
|
|
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
|
|
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",
|
|
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: [
|
|
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, ...
|
|
6
|
-
...
|
|
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, ...
|
|
6
|
-
...
|
|
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
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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 (
|
|
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 (
|
|
8
|
-
|
|
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: "
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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,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
|
|
9
|
+
export { ToastProvider };
|
|
@@ -1,36 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { cn } from "../../../helpers/cn.mjs";
|
|
3
|
-
import {
|
|
3
|
+
import { SetToastContext } from "./context.mjs";
|
|
4
4
|
import { Toast } from "./toast.mjs";
|
|
5
|
-
import {
|
|
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
|
|
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
|