sparkle-design 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +5 -0
- package/README.en.md +275 -0
- package/README.md +328 -0
- package/dist/components/ui/badge/index.d.ts +67 -0
- package/dist/components/ui/badge/index.figma.d.ts +1 -0
- package/dist/components/ui/badge/index.figma.js +28 -0
- package/dist/components/ui/badge/index.js +129 -0
- package/dist/components/ui/breadcrumb/index.d.ts +70 -0
- package/dist/components/ui/breadcrumb/index.figma.d.ts +1 -0
- package/dist/components/ui/breadcrumb/index.figma.js +28 -0
- package/dist/components/ui/breadcrumb/index.js +96 -0
- package/dist/components/ui/button/index.d.ts +145 -0
- package/dist/components/ui/button/index.figma.d.ts +1 -0
- package/dist/components/ui/button/index.figma.js +59 -0
- package/dist/components/ui/button/index.js +375 -0
- package/dist/components/ui/card/index.d.ts +193 -0
- package/dist/components/ui/card/index.figma.d.ts +1 -0
- package/dist/components/ui/card/index.figma.js +28 -0
- package/dist/components/ui/card/index.js +219 -0
- package/dist/components/ui/checkbox/index.d.ts +62 -0
- package/dist/components/ui/checkbox/index.figma.d.ts +1 -0
- package/dist/components/ui/checkbox/index.figma.js +34 -0
- package/dist/components/ui/checkbox/index.js +192 -0
- package/dist/components/ui/dialog/index.d.ts +106 -0
- package/dist/components/ui/dialog/index.figma.d.ts +1 -0
- package/dist/components/ui/dialog/index.figma.js +21 -0
- package/dist/components/ui/dialog/index.js +157 -0
- package/dist/components/ui/divider/index.d.ts +44 -0
- package/dist/components/ui/divider/index.figma.d.ts +1 -0
- package/dist/components/ui/divider/index.figma.js +39 -0
- package/dist/components/ui/divider/index.js +81 -0
- package/dist/components/ui/form/index.d.ts +171 -0
- package/dist/components/ui/form/index.figma.d.ts +1 -0
- package/dist/components/ui/form/index.figma.js +129 -0
- package/dist/components/ui/form/index.js +214 -0
- package/dist/components/ui/form/label.d.ts +4 -0
- package/dist/components/ui/form/label.js +20 -0
- package/dist/components/ui/icon/index.d.ts +71 -0
- package/dist/components/ui/icon/index.figma.d.ts +1 -0
- package/dist/components/ui/icon/index.figma.js +1858 -0
- package/dist/components/ui/icon/index.js +57 -0
- package/dist/components/ui/icon-button/index.d.ts +77 -0
- package/dist/components/ui/icon-button/index.figma.d.ts +1 -0
- package/dist/components/ui/icon-button/index.figma.js +43 -0
- package/dist/components/ui/icon-button/index.js +341 -0
- package/dist/components/ui/inline-message/index.d.ts +83 -0
- package/dist/components/ui/inline-message/index.figma.d.ts +1 -0
- package/dist/components/ui/inline-message/index.figma.js +26 -0
- package/dist/components/ui/inline-message/index.js +154 -0
- package/dist/components/ui/input/index.d.ts +118 -0
- package/dist/components/ui/input/index.figma.d.ts +1 -0
- package/dist/components/ui/input/index.figma.js +36 -0
- package/dist/components/ui/input/index.js +256 -0
- package/dist/components/ui/input-password/index.d.ts +27 -0
- package/dist/components/ui/input-password/index.figma.d.ts +1 -0
- package/dist/components/ui/input-password/index.figma.js +36 -0
- package/dist/components/ui/input-password/index.js +35 -0
- package/dist/components/ui/link/index.d.ts +68 -0
- package/dist/components/ui/link/index.figma.d.ts +1 -0
- package/dist/components/ui/link/index.figma.js +22 -0
- package/dist/components/ui/link/index.js +92 -0
- package/dist/components/ui/modal/index.d.ts +83 -0
- package/dist/components/ui/modal/index.figma.d.ts +1 -0
- package/dist/components/ui/modal/index.figma.js +61 -0
- package/dist/components/ui/modal/index.js +143 -0
- package/dist/components/ui/overlay/index.d.ts +19 -0
- package/dist/components/ui/overlay/index.figma.d.ts +1 -0
- package/dist/components/ui/overlay/index.figma.js +14 -0
- package/dist/components/ui/overlay/index.js +39 -0
- package/dist/components/ui/radio/index.d.ts +94 -0
- package/dist/components/ui/radio/index.figma.d.ts +1 -0
- package/dist/components/ui/radio/index.figma.js +63 -0
- package/dist/components/ui/radio/index.js +204 -0
- package/dist/components/ui/select/index.d.ts +175 -0
- package/dist/components/ui/select/index.figma.d.ts +1 -0
- package/dist/components/ui/select/index.figma.js +30 -0
- package/dist/components/ui/select/index.js +281 -0
- package/dist/components/ui/skeleton/index.d.ts +21 -0
- package/dist/components/ui/skeleton/index.figma.d.ts +1 -0
- package/dist/components/ui/skeleton/index.figma.js +14 -0
- package/dist/components/ui/skeleton/index.js +32 -0
- package/dist/components/ui/slider/index.d.ts +75 -0
- package/dist/components/ui/slider/index.figma.d.ts +1 -0
- package/dist/components/ui/slider/index.figma.js +28 -0
- package/dist/components/ui/slider/index.js +113 -0
- package/dist/components/ui/slider/utils.d.ts +16 -0
- package/dist/components/ui/slider/utils.js +56 -0
- package/dist/components/ui/spinner/index.d.ts +42 -0
- package/dist/components/ui/spinner/index.figma.d.ts +1 -0
- package/dist/components/ui/spinner/index.figma.js +16 -0
- package/dist/components/ui/spinner/index.js +51 -0
- package/dist/components/ui/switch/index.d.ts +46 -0
- package/dist/components/ui/switch/index.figma.d.ts +1 -0
- package/dist/components/ui/switch/index.figma.js +27 -0
- package/dist/components/ui/switch/index.js +75 -0
- package/dist/components/ui/tabs/index.d.ts +53 -0
- package/dist/components/ui/tabs/index.figma.d.ts +1 -0
- package/dist/components/ui/tabs/index.figma.js +55 -0
- package/dist/components/ui/tabs/index.js +164 -0
- package/dist/components/ui/tag/index.d.ts +50 -0
- package/dist/components/ui/tag/index.figma.d.ts +1 -0
- package/dist/components/ui/tag/index.figma.js +32 -0
- package/dist/components/ui/tag/index.js +177 -0
- package/dist/components/ui/textarea/index.d.ts +49 -0
- package/dist/components/ui/textarea/index.figma.d.ts +1 -0
- package/dist/components/ui/textarea/index.figma.js +27 -0
- package/dist/components/ui/textarea/index.js +94 -0
- package/dist/components/ui/toast/index.d.ts +60 -0
- package/dist/components/ui/toast/index.figma.d.ts +1 -0
- package/dist/components/ui/toast/index.figma.js +26 -0
- package/dist/components/ui/toast/index.js +57 -0
- package/dist/components/ui/tooltip/index.d.ts +52 -0
- package/dist/components/ui/tooltip/index.figma.d.ts +1 -0
- package/dist/components/ui/tooltip/index.figma.js +23 -0
- package/dist/components/ui/tooltip/index.js +65 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +27 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +5 -0
- package/dist/test/helpers.d.ts +56 -0
- package/dist/test/helpers.js +182 -0
- package/dist/test/setup.d.ts +1 -0
- package/dist/test/setup.js +38 -0
- package/package.json +253 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
/**
|
|
14
|
+
* Copyright 2026 Goodpatch Inc.
|
|
15
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
16
|
+
*/
|
|
17
|
+
import * as React from "react";
|
|
18
|
+
import { cva } from "class-variance-authority";
|
|
19
|
+
import { cn } from "../../../lib/utils.js";
|
|
20
|
+
// タグのスタイル定義
|
|
21
|
+
const tagVariants = cva("inline-flex items-center justify-center rounded-notice h-fit min-w-0", {
|
|
22
|
+
variants: {
|
|
23
|
+
variant: {
|
|
24
|
+
solid: "",
|
|
25
|
+
outline: "border",
|
|
26
|
+
subtle: "",
|
|
27
|
+
},
|
|
28
|
+
size: {
|
|
29
|
+
sm: "py-0 px-2 min-w-10 character-1-bold-pro",
|
|
30
|
+
md: "py-0.5 px-2 min-w-12 character-1-bold-pro",
|
|
31
|
+
lg: "py-1 px-2 min-w-14 character-2-bold-pro",
|
|
32
|
+
},
|
|
33
|
+
status: {
|
|
34
|
+
neutral: "",
|
|
35
|
+
info: "",
|
|
36
|
+
success: "",
|
|
37
|
+
warning: "",
|
|
38
|
+
negative: "",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
compoundVariants: [
|
|
42
|
+
// === SOLID バリアント ===
|
|
43
|
+
// neutral + solid
|
|
44
|
+
{
|
|
45
|
+
variant: "solid",
|
|
46
|
+
status: "neutral",
|
|
47
|
+
className: "bg-neutral-500 text-white",
|
|
48
|
+
},
|
|
49
|
+
// info + solid
|
|
50
|
+
{
|
|
51
|
+
variant: "solid",
|
|
52
|
+
status: "info",
|
|
53
|
+
className: "bg-primary-500 text-white",
|
|
54
|
+
},
|
|
55
|
+
// success + solid
|
|
56
|
+
{
|
|
57
|
+
variant: "solid",
|
|
58
|
+
status: "success",
|
|
59
|
+
className: "bg-success-500 text-white",
|
|
60
|
+
},
|
|
61
|
+
// warning + solid
|
|
62
|
+
{
|
|
63
|
+
variant: "solid",
|
|
64
|
+
status: "warning",
|
|
65
|
+
className: "bg-warning-500 text-white",
|
|
66
|
+
},
|
|
67
|
+
// negative + solid
|
|
68
|
+
{
|
|
69
|
+
variant: "solid",
|
|
70
|
+
status: "negative",
|
|
71
|
+
className: "bg-negative-500 text-white",
|
|
72
|
+
},
|
|
73
|
+
// === OUTLINE バリアント ===
|
|
74
|
+
// neutral + outline
|
|
75
|
+
{
|
|
76
|
+
variant: "outline",
|
|
77
|
+
status: "neutral",
|
|
78
|
+
className: "border-neutral-500 text-neutral-500 bg-white",
|
|
79
|
+
},
|
|
80
|
+
// info + outline
|
|
81
|
+
{
|
|
82
|
+
variant: "outline",
|
|
83
|
+
status: "info",
|
|
84
|
+
className: "border-primary-500 text-primary-500 bg-white",
|
|
85
|
+
},
|
|
86
|
+
// success + outline
|
|
87
|
+
{
|
|
88
|
+
variant: "outline",
|
|
89
|
+
status: "success",
|
|
90
|
+
className: "border-success-500 text-success-500 bg-white",
|
|
91
|
+
},
|
|
92
|
+
// warning + outline
|
|
93
|
+
{
|
|
94
|
+
variant: "outline",
|
|
95
|
+
status: "warning",
|
|
96
|
+
className: "border-warning-500 text-warning-500 bg-white",
|
|
97
|
+
},
|
|
98
|
+
// negative + outline
|
|
99
|
+
{
|
|
100
|
+
variant: "outline",
|
|
101
|
+
status: "negative",
|
|
102
|
+
className: "border-negative-500 text-negative-500 bg-white",
|
|
103
|
+
},
|
|
104
|
+
// === SUBTLE バリアント ===
|
|
105
|
+
// neutral + subtle
|
|
106
|
+
{
|
|
107
|
+
variant: "subtle",
|
|
108
|
+
status: "neutral",
|
|
109
|
+
className: "bg-neutral-100 text-neutral-600",
|
|
110
|
+
},
|
|
111
|
+
// info + subtle
|
|
112
|
+
{
|
|
113
|
+
variant: "subtle",
|
|
114
|
+
status: "info",
|
|
115
|
+
className: "bg-primary-100 text-primary-600",
|
|
116
|
+
},
|
|
117
|
+
// success + subtle
|
|
118
|
+
{
|
|
119
|
+
variant: "subtle",
|
|
120
|
+
status: "success",
|
|
121
|
+
className: "bg-success-100 text-success-600",
|
|
122
|
+
},
|
|
123
|
+
// warning + subtle
|
|
124
|
+
{
|
|
125
|
+
variant: "subtle",
|
|
126
|
+
status: "warning",
|
|
127
|
+
className: "bg-warning-100 text-warning-600",
|
|
128
|
+
},
|
|
129
|
+
// negative + subtle
|
|
130
|
+
{
|
|
131
|
+
variant: "subtle",
|
|
132
|
+
status: "negative",
|
|
133
|
+
className: "bg-negative-100 text-negative-600",
|
|
134
|
+
},
|
|
135
|
+
],
|
|
136
|
+
defaultVariants: {
|
|
137
|
+
variant: "solid",
|
|
138
|
+
size: "md",
|
|
139
|
+
status: "neutral",
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
/**
|
|
143
|
+
* **概要 / Overview**
|
|
144
|
+
*
|
|
145
|
+
* - タグは特定の要素にラベリングをすることで情報を分類・整理したり、情報にステータスを付与するために使用するコンポーネントです。
|
|
146
|
+
* - en: The Tag component is used to categorize and organize information by labeling specific elements, or to assign status to information.
|
|
147
|
+
*
|
|
148
|
+
* **アンチパターン / Anti-patterns**
|
|
149
|
+
*
|
|
150
|
+
* - 通知数や件数などの数値情報には `Tag` を使わず、`Badge` を使ってください。
|
|
151
|
+
* en: Do not use `Tag` for numeric information such as notification counts. Use `Badge` instead.
|
|
152
|
+
*
|
|
153
|
+
* ```tsx
|
|
154
|
+
* // ✅ Correct
|
|
155
|
+
* <>
|
|
156
|
+
* <Tag status="success">完了</Tag>
|
|
157
|
+
* <Badge>3</Badge>
|
|
158
|
+
* </>
|
|
159
|
+
*
|
|
160
|
+
* // ❌ Wrong - 件数表示に Tag を使わない
|
|
161
|
+
* <Tag status="info">3件</Tag>
|
|
162
|
+
* ```
|
|
163
|
+
|
|
164
|
+
* **使用例 / Usage Example**
|
|
165
|
+
*
|
|
166
|
+
* ```tsx
|
|
167
|
+
* <Tag variant="solid" size="md" status="info">情報</Tag>
|
|
168
|
+
* ```
|
|
169
|
+
*
|
|
170
|
+
* @param {TagProps} props
|
|
171
|
+
*/
|
|
172
|
+
const Tag = React.forwardRef((_a, ref) => {
|
|
173
|
+
var { className, variant, size, status, children } = _a, props = __rest(_a, ["className", "variant", "size", "status", "children"]);
|
|
174
|
+
return (_jsx("div", Object.assign({ ref: ref, className: cn(tagVariants({ variant, size, status, className })) }, props, { children: _jsx("span", { className: "min-w-0 truncate", children: children }) })));
|
|
175
|
+
});
|
|
176
|
+
Tag.displayName = "Tag";
|
|
177
|
+
export { Tag, tagVariants };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 Goodpatch Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { type VariantProps } from "class-variance-authority";
|
|
7
|
+
/**
|
|
8
|
+
* **概要 / Overview**
|
|
9
|
+
*
|
|
10
|
+
* - テキストエリアは複数行のテキストフィールドの形式でユーザーからの入力を取得するために使用するコンポーネントです。
|
|
11
|
+
* - en: The Textarea component is used to capture user input in the form of multi-line text fields.
|
|
12
|
+
*/
|
|
13
|
+
declare const textareaVariants: (props?: ({
|
|
14
|
+
size?: "sm" | "md" | "lg" | null | undefined;
|
|
15
|
+
isInvalid?: boolean | null | undefined;
|
|
16
|
+
isDisabled?: boolean | null | undefined;
|
|
17
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
18
|
+
/**
|
|
19
|
+
* テキストエリアコンポーネントのプロパティ定義
|
|
20
|
+
* 標準のTextarea属性に加えてバリアントプロパティを拡張
|
|
21
|
+
*/
|
|
22
|
+
export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement>, VariantProps<typeof textareaVariants> {
|
|
23
|
+
/**
|
|
24
|
+
* エラー状態かどうか
|
|
25
|
+
* en: Whether the textarea is in an error state
|
|
26
|
+
*/
|
|
27
|
+
isInvalid?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* 無効状態かどうか
|
|
30
|
+
* en: Whether the textarea is disabled
|
|
31
|
+
*/
|
|
32
|
+
isDisabled?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* **概要 / Overview**
|
|
36
|
+
*
|
|
37
|
+
* - テキストエリアは複数行のテキストフィールドの形式でユーザーからの入力を取得するために使用するコンポーネントです。
|
|
38
|
+
* - en: The Textarea component is used to capture user input in the form of multi-line text fields.
|
|
39
|
+
*
|
|
40
|
+
* **使用例 / Usage Example**
|
|
41
|
+
*
|
|
42
|
+
* ```tsx
|
|
43
|
+
* <Textarea size="md" placeholder="複数行のテキストを入力してください" />
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @param {TextareaProps} props
|
|
47
|
+
*/
|
|
48
|
+
declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
|
|
49
|
+
export { Textarea, textareaVariants };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import figma from "@figma/code-connect";
|
|
3
|
+
import { Textarea } from "./index.js";
|
|
4
|
+
/**
|
|
5
|
+
* -- This file was auto-generated by Code Connect --
|
|
6
|
+
* `props` includes a mapping from your code props to Figma properties.
|
|
7
|
+
* You should check this is correct, and update the `example` function
|
|
8
|
+
* to return the code example you'd like to see in Figma
|
|
9
|
+
*/
|
|
10
|
+
figma.connect(Textarea, "https://www.figma.com/design/7alBZXZf65YgcII41TWT0r/Sparkle-Design?node-id=2876-24038", {
|
|
11
|
+
props: {
|
|
12
|
+
size: figma.enum("size", { sm: "sm", md: "md", lg: "lg" }),
|
|
13
|
+
isInvalid: figma.boolean("isInvalid"),
|
|
14
|
+
isDisabled: figma.enum("state", {
|
|
15
|
+
disabled: true,
|
|
16
|
+
}),
|
|
17
|
+
defaultValue: figma.boolean("isEmpty", {
|
|
18
|
+
true: undefined,
|
|
19
|
+
false: figma.string("value"),
|
|
20
|
+
}),
|
|
21
|
+
placeholder: figma.boolean("isEmpty", {
|
|
22
|
+
true: figma.string("value"),
|
|
23
|
+
false: undefined,
|
|
24
|
+
}),
|
|
25
|
+
},
|
|
26
|
+
example: props => (_jsx(Textarea, { size: props.size, isInvalid: props.isInvalid, isDisabled: props.isDisabled, placeholder: props.placeholder, defaultValue: props.defaultValue })),
|
|
27
|
+
});
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
|
+
var t = {};
|
|
3
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
4
|
+
t[p] = s[p];
|
|
5
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
6
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
7
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
8
|
+
t[p[i]] = s[p[i]];
|
|
9
|
+
}
|
|
10
|
+
return t;
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
/**
|
|
14
|
+
* Copyright 2026 Goodpatch Inc.
|
|
15
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
16
|
+
*/
|
|
17
|
+
import * as React from "react";
|
|
18
|
+
import { cva } from "class-variance-authority";
|
|
19
|
+
import { cn } from "../../../lib/utils.js";
|
|
20
|
+
/**
|
|
21
|
+
* **概要 / Overview**
|
|
22
|
+
*
|
|
23
|
+
* - テキストエリアは複数行のテキストフィールドの形式でユーザーからの入力を取得するために使用するコンポーネントです。
|
|
24
|
+
* - en: The Textarea component is used to capture user input in the form of multi-line text fields.
|
|
25
|
+
*/
|
|
26
|
+
const textareaVariants = cva(
|
|
27
|
+
// ベーススタイル
|
|
28
|
+
"flex w-full rounded-action border bg-white px-3 py-1 ring-offset-background placeholder:text-base-400 focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-[var(--color-ring-normal)] focus-visible:ring-offset-2 resize", {
|
|
29
|
+
variants: {
|
|
30
|
+
// サイズバリアント(sm, md, lg)
|
|
31
|
+
size: {
|
|
32
|
+
sm: "min-h-[56px] character-2-regular-pro",
|
|
33
|
+
md: "min-h-[56px] character-3-regular-pro",
|
|
34
|
+
lg: "min-h-[64px] character-4-regular-pro",
|
|
35
|
+
},
|
|
36
|
+
// エラー状態のバリアント
|
|
37
|
+
isInvalid: {
|
|
38
|
+
true: "border-negative-500 hover:border-negative-600 focus-visible:border-negative-600",
|
|
39
|
+
false: "border-neutral-500 hover:border-neutral-600 focus-visible:border-neutral-600",
|
|
40
|
+
},
|
|
41
|
+
// 無効状態のバリアント
|
|
42
|
+
isDisabled: {
|
|
43
|
+
false: "",
|
|
44
|
+
true: "cursor-not-allowed text-base-300 placeholder:text-base-300 focus-visible:ring-0",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
// 複合バリアント(複数の状態の組み合わせ)
|
|
48
|
+
compoundVariants: [
|
|
49
|
+
// 無効状態かつエラー状態の場合
|
|
50
|
+
{
|
|
51
|
+
isInvalid: true,
|
|
52
|
+
isDisabled: true,
|
|
53
|
+
className: "bg-neutral-50 border-negative-200 hover:border-negative-200",
|
|
54
|
+
},
|
|
55
|
+
// 無効状態かつ通常状態の場合
|
|
56
|
+
{
|
|
57
|
+
isInvalid: false,
|
|
58
|
+
isDisabled: true,
|
|
59
|
+
className: "bg-neutral-50 border-neutral-200 hover:border-neutral-200",
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
// デフォルト値
|
|
63
|
+
defaultVariants: {
|
|
64
|
+
size: "md",
|
|
65
|
+
isInvalid: false,
|
|
66
|
+
isDisabled: false,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
/**
|
|
70
|
+
* **概要 / Overview**
|
|
71
|
+
*
|
|
72
|
+
* - テキストエリアは複数行のテキストフィールドの形式でユーザーからの入力を取得するために使用するコンポーネントです。
|
|
73
|
+
* - en: The Textarea component is used to capture user input in the form of multi-line text fields.
|
|
74
|
+
*
|
|
75
|
+
* **使用例 / Usage Example**
|
|
76
|
+
*
|
|
77
|
+
* ```tsx
|
|
78
|
+
* <Textarea size="md" placeholder="複数行のテキストを入力してください" />
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @param {TextareaProps} props
|
|
82
|
+
*/
|
|
83
|
+
const Textarea = React.forwardRef((_a, ref) => {
|
|
84
|
+
var { className, isInvalid, size, isDisabled, disabled } = _a, props = __rest(_a, ["className", "isInvalid", "size", "isDisabled", "disabled"]);
|
|
85
|
+
// 後方互換性のため、isDisabledが優先、次にdisabledを使用
|
|
86
|
+
const isTextareaDisabled = isDisabled !== null && isDisabled !== void 0 ? isDisabled : disabled;
|
|
87
|
+
return (_jsx("textarea", Object.assign({ "aria-invalid": isInvalid || undefined, className: cn(textareaVariants({
|
|
88
|
+
size,
|
|
89
|
+
isInvalid,
|
|
90
|
+
isDisabled: isTextareaDisabled,
|
|
91
|
+
}), className), disabled: isTextareaDisabled, ref: ref }, props)));
|
|
92
|
+
});
|
|
93
|
+
Textarea.displayName = "Textarea";
|
|
94
|
+
export { Textarea, textareaVariants };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Toaster } from "sonner";
|
|
3
|
+
export type { ExternalToast, ToastClassnames, ToastT } from "sonner";
|
|
4
|
+
type ReactToastProps = React.ComponentProps<typeof Toaster>;
|
|
5
|
+
export interface ToastProps extends Omit<ReactToastProps, "id"> {
|
|
6
|
+
/**
|
|
7
|
+
* トーストの識別子
|
|
8
|
+
* en: Identifier of the toast
|
|
9
|
+
*/
|
|
10
|
+
id?: string | number;
|
|
11
|
+
/**
|
|
12
|
+
* トーストのタイトル
|
|
13
|
+
* en: Title of the toast
|
|
14
|
+
*/
|
|
15
|
+
title?: string;
|
|
16
|
+
/**
|
|
17
|
+
* トーストの説明
|
|
18
|
+
* en: Description of the toast
|
|
19
|
+
*/
|
|
20
|
+
description: string;
|
|
21
|
+
/**
|
|
22
|
+
* 閉じるボタンを表示するかどうか
|
|
23
|
+
* en: Whether to show the close button
|
|
24
|
+
*/
|
|
25
|
+
isCloseTrigger?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* トーストの表示時間(ミリ秒)
|
|
28
|
+
* en: Duration of the toast (in milliseconds)
|
|
29
|
+
*/
|
|
30
|
+
duration?: ReactToastProps["duration"];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* **概要 / Overview**
|
|
34
|
+
*
|
|
35
|
+
* - トーストはアクションの発生時にユーザーへフィードバックを行うために使用するコンポーネントです。
|
|
36
|
+
* - en: Toasts are used to provide feedback to users when actions occur.
|
|
37
|
+
*
|
|
38
|
+
* **使用例 / Usage Example**
|
|
39
|
+
*
|
|
40
|
+
* ```tsx
|
|
41
|
+
* <>
|
|
42
|
+
* <Toaster />
|
|
43
|
+
* <Button onClick={() => toast({
|
|
44
|
+
* title: "保存しました",
|
|
45
|
+
* description: "1件の変更が反映されました",
|
|
46
|
+
* })}>
|
|
47
|
+
* トーストを表示
|
|
48
|
+
* </Button>
|
|
49
|
+
* </>
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @param {ToastProps} props
|
|
53
|
+
*/
|
|
54
|
+
export declare function Toast({ className, title, description, isCloseTrigger, id, }: ToastProps): import("react/jsx-runtime").JSX.Element;
|
|
55
|
+
/**
|
|
56
|
+
* - トーストはアクションの発生時にユーザーへフィードバックを行うために使用するコンポーネントです。
|
|
57
|
+
* - en: Toasts are used to provide feedback to users when actions occur.
|
|
58
|
+
*/
|
|
59
|
+
export declare function toast(props: Omit<ToastProps, "id" | "position">): string | number;
|
|
60
|
+
export { Toaster };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import figma from "@figma/code-connect";
|
|
3
|
+
import { Toast } from "./index.js";
|
|
4
|
+
/**
|
|
5
|
+
* -- This file was auto-generated by Code Connect --
|
|
6
|
+
* `props` includes a mapping from your code props to Figma properties.
|
|
7
|
+
* You should check this is correct, and update the `example` function
|
|
8
|
+
* to return the code example you'd like to see in Figma
|
|
9
|
+
*/
|
|
10
|
+
figma.connect(Toast, "https://www.figma.com/design/7alBZXZf65YgcII41TWT0r/Sparkle-Design?node-id=1266%3A13444", {
|
|
11
|
+
props: {
|
|
12
|
+
// These props were automatically mapped based on your linked code:
|
|
13
|
+
title: figma.boolean("isTitle", {
|
|
14
|
+
true: figma.string("title"),
|
|
15
|
+
false: undefined,
|
|
16
|
+
}),
|
|
17
|
+
description: figma.string("description"),
|
|
18
|
+
isCloseTrigger: figma.boolean("isCloseTrigger"),
|
|
19
|
+
// No matching props could be found for these Figma properties:
|
|
20
|
+
// "isCloseTrigger": figma.boolean('isCloseTrigger'),
|
|
21
|
+
// "isTitle": figma.boolean('isTitle'),
|
|
22
|
+
// "title": figma.string('title'),
|
|
23
|
+
// "description": figma.string('description')
|
|
24
|
+
},
|
|
25
|
+
example: props => (_jsx(Toast, { title: props.title, description: props.description, isCloseTrigger: props.isCloseTrigger })),
|
|
26
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 Goodpatch Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
"use client";
|
|
6
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
7
|
+
var t = {};
|
|
8
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
9
|
+
t[p] = s[p];
|
|
10
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
11
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
12
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
13
|
+
t[p[i]] = s[p[i]];
|
|
14
|
+
}
|
|
15
|
+
return t;
|
|
16
|
+
};
|
|
17
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
// eslint-disable-next-line import/no-unresolved -- SonnerはESMのエクスポート構造によりLintの解決が失敗するため。 en: Sonner's ESM export map confuses the lint resolver.
|
|
19
|
+
import { Toaster, toast as sonnerToast } from "sonner";
|
|
20
|
+
import { cn } from "../../../lib/utils.js";
|
|
21
|
+
import { IconButton } from "../../../components/ui/icon-button/index.js";
|
|
22
|
+
/**
|
|
23
|
+
* **概要 / Overview**
|
|
24
|
+
*
|
|
25
|
+
* - トーストはアクションの発生時にユーザーへフィードバックを行うために使用するコンポーネントです。
|
|
26
|
+
* - en: Toasts are used to provide feedback to users when actions occur.
|
|
27
|
+
*
|
|
28
|
+
* **使用例 / Usage Example**
|
|
29
|
+
*
|
|
30
|
+
* ```tsx
|
|
31
|
+
* <>
|
|
32
|
+
* <Toaster />
|
|
33
|
+
* <Button onClick={() => toast({
|
|
34
|
+
* title: "保存しました",
|
|
35
|
+
* description: "1件の変更が反映されました",
|
|
36
|
+
* })}>
|
|
37
|
+
* トーストを表示
|
|
38
|
+
* </Button>
|
|
39
|
+
* </>
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* @param {ToastProps} props
|
|
43
|
+
*/
|
|
44
|
+
export function Toast({ className, title, description, isCloseTrigger = true, id, }) {
|
|
45
|
+
return (_jsxs("div", { role: "status", className: cn("shadow-float px-3 py-2 text-text-high flex w-[320px] rounded-notice gap-2 bg-neutral-50 border border-divider-middle", className), children: [_jsxs("div", { className: "h-full flex flex-col justify-center gap-0 px-1 grow", children: [title && (_jsx("p", { className: "character-3-bold-pro min-h-8 flex items-center", children: title })), _jsx("p", { className: "character-3-regular-pro min-h-8 flex items-center", children: description })] }), isCloseTrigger && (_jsx(IconButton, { icon: "close", size: "sm", variant: "ghost", theme: "neutral", "aria-label": "\u9589\u3058\u308B", onClick: () => {
|
|
46
|
+
sonnerToast.dismiss(id);
|
|
47
|
+
} }))] }));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* - トーストはアクションの発生時にユーザーへフィードバックを行うために使用するコンポーネントです。
|
|
51
|
+
* - en: Toasts are used to provide feedback to users when actions occur.
|
|
52
|
+
*/
|
|
53
|
+
export function toast(props) {
|
|
54
|
+
const { title, description, isCloseTrigger } = props, rest = __rest(props, ["title", "description", "isCloseTrigger"]);
|
|
55
|
+
return sonnerToast.custom(id => (_jsx(Toast, { title: title, description: description, isCloseTrigger: isCloseTrigger, id: id })), Object.assign(Object.assign({}, rest), { position: "top-center" }));
|
|
56
|
+
}
|
|
57
|
+
export { Toaster };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { Tooltip as TooltipPrimitive } from "radix-ui";
|
|
3
|
+
/**
|
|
4
|
+
* TooltipContentコンポーネントのプロパティ型
|
|
5
|
+
* en: Props type for TooltipContent component
|
|
6
|
+
*/
|
|
7
|
+
interface TooltipContentProps extends React.ComponentProps<typeof TooltipPrimitive.Content> {
|
|
8
|
+
/**
|
|
9
|
+
* ツールチップの表示位置を指定します。
|
|
10
|
+
* en: Specifies the position of the tooltip (top, right, bottom, left).
|
|
11
|
+
*/
|
|
12
|
+
side?: "top" | "right" | "bottom" | "left";
|
|
13
|
+
/**
|
|
14
|
+
* トリガー要素とツールチップの間の距離を指定します。
|
|
15
|
+
* en: Specifies the distance between the trigger element and the tooltip.
|
|
16
|
+
*/
|
|
17
|
+
sideOffset?: number;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* TooltipProvider コンポーネント
|
|
21
|
+
* en: TooltipProvider component
|
|
22
|
+
*/
|
|
23
|
+
declare function TooltipProvider({ delayDuration, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
/**
|
|
25
|
+
* **概要 / Overview**
|
|
26
|
+
*
|
|
27
|
+
* - ツールチップは情報を一時的に補足するために使用するコンポーネントです。
|
|
28
|
+
* - en: The Tooltip component is used to provide additional information temporarily.
|
|
29
|
+
*
|
|
30
|
+
* **使用例 / Usage Example**
|
|
31
|
+
*
|
|
32
|
+
* ```tsx
|
|
33
|
+
* <Tooltip>
|
|
34
|
+
* <TooltipTrigger>Tooltip Trigger</TooltipTrigger>
|
|
35
|
+
* <TooltipContent>Tooltip Content</TooltipContent>
|
|
36
|
+
* </Tooltip>
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @param {React.ComponentProps<typeof TooltipPrimitive.Root>} props
|
|
40
|
+
*/
|
|
41
|
+
declare function Tooltip({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>): import("react/jsx-runtime").JSX.Element;
|
|
42
|
+
/**
|
|
43
|
+
* TooltipTrigger コンポーネント
|
|
44
|
+
* en: TooltipTrigger component
|
|
45
|
+
*/
|
|
46
|
+
declare function TooltipTrigger({ ...props }: React.ComponentProps<typeof TooltipPrimitive.Trigger>): import("react/jsx-runtime").JSX.Element;
|
|
47
|
+
/**
|
|
48
|
+
* TooltipContent コンポーネント
|
|
49
|
+
* en: TooltipContent component
|
|
50
|
+
*/
|
|
51
|
+
declare function TooltipContent({ className, side, sideOffset, children, ...props }: TooltipContentProps): import("react/jsx-runtime").JSX.Element;
|
|
52
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, type TooltipContentProps, };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import figma from "@figma/code-connect";
|
|
3
|
+
import { Tooltip, TooltipContent, TooltipTrigger } from "./index.js";
|
|
4
|
+
/**
|
|
5
|
+
* -- This file was auto-generated by Code Connect --
|
|
6
|
+
* `props` includes a mapping from your code props to Figma properties.
|
|
7
|
+
* You should check this is correct, and update the `example` function
|
|
8
|
+
* to return the code example you'd like to see in Figma
|
|
9
|
+
*/
|
|
10
|
+
figma.connect(TooltipContent, "https://www.figma.com/design/7alBZXZf65YgcII41TWT0r/Sparkle-Design?node-id=973%3A684", {
|
|
11
|
+
props: {
|
|
12
|
+
// These props were automatically mapped based on your linked code:
|
|
13
|
+
side: figma.enum("side", {
|
|
14
|
+
top: "top",
|
|
15
|
+
right: "right",
|
|
16
|
+
bottom: "bottom",
|
|
17
|
+
left: "left",
|
|
18
|
+
}),
|
|
19
|
+
// No matching props could be found for these Figma properties:
|
|
20
|
+
label: figma.string("label"),
|
|
21
|
+
},
|
|
22
|
+
example: props => (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { children: "Tooltip Trigger" }), _jsx(TooltipContent, { side: props.side, children: props.label })] })),
|
|
23
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 Goodpatch Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
+
*/
|
|
5
|
+
"use client";
|
|
6
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
7
|
+
var t = {};
|
|
8
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
9
|
+
t[p] = s[p];
|
|
10
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
11
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
12
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
13
|
+
t[p[i]] = s[p[i]];
|
|
14
|
+
}
|
|
15
|
+
return t;
|
|
16
|
+
};
|
|
17
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
18
|
+
import { Tooltip as TooltipPrimitive } from "radix-ui";
|
|
19
|
+
import { cn } from "../../../lib/utils.js";
|
|
20
|
+
/**
|
|
21
|
+
* TooltipProvider コンポーネント
|
|
22
|
+
* en: TooltipProvider component
|
|
23
|
+
*/
|
|
24
|
+
function TooltipProvider(_a) {
|
|
25
|
+
var { delayDuration = 0 } = _a, props = __rest(_a, ["delayDuration"]);
|
|
26
|
+
return (_jsx(TooltipPrimitive.Provider, Object.assign({ "data-slot": "tooltip-provider", delayDuration: delayDuration }, props)));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* **概要 / Overview**
|
|
30
|
+
*
|
|
31
|
+
* - ツールチップは情報を一時的に補足するために使用するコンポーネントです。
|
|
32
|
+
* - en: The Tooltip component is used to provide additional information temporarily.
|
|
33
|
+
*
|
|
34
|
+
* **使用例 / Usage Example**
|
|
35
|
+
*
|
|
36
|
+
* ```tsx
|
|
37
|
+
* <Tooltip>
|
|
38
|
+
* <TooltipTrigger>Tooltip Trigger</TooltipTrigger>
|
|
39
|
+
* <TooltipContent>Tooltip Content</TooltipContent>
|
|
40
|
+
* </Tooltip>
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* @param {React.ComponentProps<typeof TooltipPrimitive.Root>} props
|
|
44
|
+
*/
|
|
45
|
+
function Tooltip(_a) {
|
|
46
|
+
var props = __rest(_a, []);
|
|
47
|
+
return (_jsx(TooltipProvider, { children: _jsx(TooltipPrimitive.Root, Object.assign({ "data-slot": "tooltip" }, props)) }));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* TooltipTrigger コンポーネント
|
|
51
|
+
* en: TooltipTrigger component
|
|
52
|
+
*/
|
|
53
|
+
function TooltipTrigger(_a) {
|
|
54
|
+
var props = __rest(_a, []);
|
|
55
|
+
return _jsx(TooltipPrimitive.Trigger, Object.assign({ "data-slot": "tooltip-trigger" }, props));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* TooltipContent コンポーネント
|
|
59
|
+
* en: TooltipContent component
|
|
60
|
+
*/
|
|
61
|
+
function TooltipContent(_a) {
|
|
62
|
+
var { className, side = "top", sideOffset = 0, children } = _a, props = __rest(_a, ["className", "side", "sideOffset", "children"]);
|
|
63
|
+
return (_jsx(TooltipPrimitive.Portal, { children: _jsxs(TooltipPrimitive.Content, Object.assign({ "data-slot": "tooltip-content", side: side, sideOffset: sideOffset, className: cn("bg-neutral-900 shadow-float animate-in fade-in-0 zoom-in-95", "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95", "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2", "data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", "z-50 w-fit origin-[--radix-tooltip-content-transform-origin] rounded-notice", "px-2 py-1 character-2-regular-pro text-white", className) }, props, { children: [children, _jsx(TooltipPrimitive.Arrow, { className: "bg-neutral-900 fill-neutral-900 shadow-float z-50 size-3 translate-y-[calc(-50%_-_1px)] rotate-45 rounded-xs" })] })) }));
|
|
64
|
+
}
|
|
65
|
+
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider, };
|