@novi-ui/flatlay 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +418 -0
- package/dist/accordion/accordion.d.mts +35 -0
- package/dist/accordion/accordion.d.mts.map +1 -0
- package/dist/accordion/accordion.mjs +74 -0
- package/dist/accordion/accordion.mjs.map +1 -0
- package/dist/accordion/accordion.styles.d.mts +61 -0
- package/dist/accordion/accordion.styles.d.mts.map +1 -0
- package/dist/accordion/accordion.styles.mjs +91 -0
- package/dist/accordion/accordion.styles.mjs.map +1 -0
- package/dist/accordion/index.d.mts +3 -0
- package/dist/avatar/avatar.d.mts +22 -0
- package/dist/avatar/avatar.d.mts.map +1 -0
- package/dist/avatar/avatar.mjs +60 -0
- package/dist/avatar/avatar.mjs.map +1 -0
- package/dist/avatar/avatar.styles.d.mts +49 -0
- package/dist/avatar/avatar.styles.d.mts.map +1 -0
- package/dist/avatar/avatar.styles.mjs +55 -0
- package/dist/avatar/avatar.styles.mjs.map +1 -0
- package/dist/avatar/index.d.mts +3 -0
- package/dist/badge/badge.d.mts +15 -0
- package/dist/badge/badge.d.mts.map +1 -0
- package/dist/badge/badge.mjs +39 -0
- package/dist/badge/badge.mjs.map +1 -0
- package/dist/badge/badge.styles.d.mts +67 -0
- package/dist/badge/badge.styles.d.mts.map +1 -0
- package/dist/badge/badge.styles.mjs +110 -0
- package/dist/badge/badge.styles.mjs.map +1 -0
- package/dist/badge/index.d.mts +3 -0
- package/dist/breadcrumbs/breadcrumbs.d.mts +36 -0
- package/dist/breadcrumbs/breadcrumbs.d.mts.map +1 -0
- package/dist/breadcrumbs/breadcrumbs.mjs +82 -0
- package/dist/breadcrumbs/breadcrumbs.mjs.map +1 -0
- package/dist/breadcrumbs/breadcrumbs.styles.d.mts +46 -0
- package/dist/breadcrumbs/breadcrumbs.styles.d.mts.map +1 -0
- package/dist/breadcrumbs/breadcrumbs.styles.mjs +45 -0
- package/dist/breadcrumbs/breadcrumbs.styles.mjs.map +1 -0
- package/dist/breadcrumbs/index.d.mts +3 -0
- package/dist/button/button.d.mts +18 -0
- package/dist/button/button.d.mts.map +1 -0
- package/dist/button/button.mjs +79 -0
- package/dist/button/button.mjs.map +1 -0
- package/dist/button/button.styles.d.mts +82 -0
- package/dist/button/button.styles.d.mts.map +1 -0
- package/dist/button/button.styles.mjs +137 -0
- package/dist/button/button.styles.mjs.map +1 -0
- package/dist/button/index.d.mts +3 -0
- package/dist/card/card.d.mts +51 -0
- package/dist/card/card.d.mts.map +1 -0
- package/dist/card/card.mjs +96 -0
- package/dist/card/card.mjs.map +1 -0
- package/dist/card/card.styles.d.mts +73 -0
- package/dist/card/card.styles.d.mts.map +1 -0
- package/dist/card/card.styles.mjs +72 -0
- package/dist/card/card.styles.mjs.map +1 -0
- package/dist/card/index.d.mts +3 -0
- package/dist/checkbox/checkbox.d.mts +27 -0
- package/dist/checkbox/checkbox.d.mts.map +1 -0
- package/dist/checkbox/checkbox.mjs +109 -0
- package/dist/checkbox/checkbox.mjs.map +1 -0
- package/dist/checkbox/checkbox.styles.d.mts +114 -0
- package/dist/checkbox/checkbox.styles.d.mts.map +1 -0
- package/dist/checkbox/checkbox.styles.mjs +105 -0
- package/dist/checkbox/checkbox.styles.mjs.map +1 -0
- package/dist/checkbox/index.d.mts +3 -0
- package/dist/color-picker/color-picker.d.mts +30 -0
- package/dist/color-picker/color-picker.d.mts.map +1 -0
- package/dist/color-picker/color-picker.mjs +100 -0
- package/dist/color-picker/color-picker.mjs.map +1 -0
- package/dist/color-picker/color-picker.styles.d.mts +91 -0
- package/dist/color-picker/color-picker.styles.d.mts.map +1 -0
- package/dist/color-picker/color-picker.styles.mjs +79 -0
- package/dist/color-picker/color-picker.styles.mjs.map +1 -0
- package/dist/color-picker/index.d.mts +3 -0
- package/dist/flatlay.css +381 -0
- package/dist/flatlay.scoped.css +381 -0
- package/dist/index.d.mts +67 -0
- package/dist/index.mjs +46 -0
- package/dist/input/index.d.mts +3 -0
- package/dist/input/input.d.mts +23 -0
- package/dist/input/input.d.mts.map +1 -0
- package/dist/input/input.mjs +89 -0
- package/dist/input/input.mjs.map +1 -0
- package/dist/input/input.styles.d.mts +97 -0
- package/dist/input/input.styles.d.mts.map +1 -0
- package/dist/input/input.styles.mjs +96 -0
- package/dist/input/input.styles.mjs.map +1 -0
- package/dist/menu/index.d.mts +3 -0
- package/dist/menu/menu.d.mts +66 -0
- package/dist/menu/menu.d.mts.map +1 -0
- package/dist/menu/menu.mjs +118 -0
- package/dist/menu/menu.mjs.map +1 -0
- package/dist/menu/menu.styles.d.mts +114 -0
- package/dist/menu/menu.styles.d.mts.map +1 -0
- package/dist/menu/menu.styles.mjs +66 -0
- package/dist/menu/menu.styles.mjs.map +1 -0
- package/dist/modal/index.d.mts +3 -0
- package/dist/modal/modal.d.mts +55 -0
- package/dist/modal/modal.d.mts.map +1 -0
- package/dist/modal/modal.mjs +120 -0
- package/dist/modal/modal.mjs.map +1 -0
- package/dist/modal/modal.styles.d.mts +70 -0
- package/dist/modal/modal.styles.d.mts.map +1 -0
- package/dist/modal/modal.styles.mjs +83 -0
- package/dist/modal/modal.styles.mjs.map +1 -0
- package/dist/popover/index.d.mts +3 -0
- package/dist/popover/popover.d.mts +33 -0
- package/dist/popover/popover.d.mts.map +1 -0
- package/dist/popover/popover.mjs +57 -0
- package/dist/popover/popover.mjs.map +1 -0
- package/dist/popover/popover.styles.d.mts +40 -0
- package/dist/popover/popover.styles.d.mts.map +1 -0
- package/dist/popover/popover.styles.mjs +47 -0
- package/dist/popover/popover.styles.mjs.map +1 -0
- package/dist/progress/index.d.mts +3 -0
- package/dist/progress/progress.d.mts +15 -0
- package/dist/progress/progress.d.mts.map +1 -0
- package/dist/progress/progress.mjs +55 -0
- package/dist/progress/progress.mjs.map +1 -0
- package/dist/progress/progress.styles.d.mts +100 -0
- package/dist/progress/progress.styles.d.mts.map +1 -0
- package/dist/progress/progress.styles.mjs +65 -0
- package/dist/progress/progress.styles.mjs.map +1 -0
- package/dist/radio/index.d.mts +3 -0
- package/dist/radio/radio.d.mts +25 -0
- package/dist/radio/radio.d.mts.map +1 -0
- package/dist/radio/radio.mjs +99 -0
- package/dist/radio/radio.mjs.map +1 -0
- package/dist/radio/radio.styles.d.mts +114 -0
- package/dist/radio/radio.styles.d.mts.map +1 -0
- package/dist/radio/radio.styles.mjs +103 -0
- package/dist/radio/radio.styles.mjs.map +1 -0
- package/dist/select/index.d.mts +3 -0
- package/dist/select/select.d.mts +40 -0
- package/dist/select/select.d.mts.map +1 -0
- package/dist/select/select.mjs +121 -0
- package/dist/select/select.mjs.map +1 -0
- package/dist/select/select.styles.d.mts +85 -0
- package/dist/select/select.styles.d.mts.map +1 -0
- package/dist/select/select.styles.mjs +111 -0
- package/dist/select/select.styles.mjs.map +1 -0
- package/dist/skeleton/index.d.mts +3 -0
- package/dist/skeleton/skeleton.d.mts +15 -0
- package/dist/skeleton/skeleton.d.mts.map +1 -0
- package/dist/skeleton/skeleton.mjs +26 -0
- package/dist/skeleton/skeleton.mjs.map +1 -0
- package/dist/skeleton/skeleton.styles.d.mts +47 -0
- package/dist/skeleton/skeleton.styles.d.mts.map +1 -0
- package/dist/skeleton/skeleton.styles.mjs +31 -0
- package/dist/skeleton/skeleton.styles.mjs.map +1 -0
- package/dist/spinner/index.d.mts +3 -0
- package/dist/spinner/spinner.d.mts +15 -0
- package/dist/spinner/spinner.d.mts.map +1 -0
- package/dist/spinner/spinner.mjs +55 -0
- package/dist/spinner/spinner.mjs.map +1 -0
- package/dist/spinner/spinner.styles.d.mts +46 -0
- package/dist/spinner/spinner.styles.d.mts.map +1 -0
- package/dist/spinner/spinner.styles.mjs +50 -0
- package/dist/spinner/spinner.styles.mjs.map +1 -0
- package/dist/styles/focus-ring.mjs +30 -0
- package/dist/styles/focus-ring.mjs.map +1 -0
- package/dist/styles/inflow.mjs +156 -0
- package/dist/styles/inflow.mjs.map +1 -0
- package/dist/styles/mono.mjs +24 -0
- package/dist/styles/mono.mjs.map +1 -0
- package/dist/switch/index.d.mts +3 -0
- package/dist/switch/switch.d.mts +18 -0
- package/dist/switch/switch.d.mts.map +1 -0
- package/dist/switch/switch.mjs +58 -0
- package/dist/switch/switch.mjs.map +1 -0
- package/dist/switch/switch.styles.d.mts +58 -0
- package/dist/switch/switch.styles.d.mts.map +1 -0
- package/dist/switch/switch.styles.mjs +86 -0
- package/dist/switch/switch.styles.mjs.map +1 -0
- package/dist/tabs/index.d.mts +3 -0
- package/dist/tabs/tabs.d.mts +64 -0
- package/dist/tabs/tabs.d.mts.map +1 -0
- package/dist/tabs/tabs.mjs +93 -0
- package/dist/tabs/tabs.mjs.map +1 -0
- package/dist/tabs/tabs.styles.d.mts +64 -0
- package/dist/tabs/tabs.styles.d.mts.map +1 -0
- package/dist/tabs/tabs.styles.mjs +118 -0
- package/dist/tabs/tabs.styles.mjs.map +1 -0
- package/dist/textarea/index.d.mts +3 -0
- package/dist/textarea/textarea.d.mts +15 -0
- package/dist/textarea/textarea.d.mts.map +1 -0
- package/dist/textarea/textarea.mjs +70 -0
- package/dist/textarea/textarea.mjs.map +1 -0
- package/dist/textarea/textarea.styles.d.mts +70 -0
- package/dist/textarea/textarea.styles.d.mts.map +1 -0
- package/dist/textarea/textarea.styles.mjs +85 -0
- package/dist/textarea/textarea.styles.mjs.map +1 -0
- package/dist/toast/index.d.mts +3 -0
- package/dist/toast/toast.d.mts +47 -0
- package/dist/toast/toast.d.mts.map +1 -0
- package/dist/toast/toast.mjs +100 -0
- package/dist/toast/toast.mjs.map +1 -0
- package/dist/toast/toast.styles.d.mts +61 -0
- package/dist/toast/toast.styles.d.mts.map +1 -0
- package/dist/toast/toast.styles.mjs +79 -0
- package/dist/toast/toast.styles.mjs.map +1 -0
- package/dist/tokens/color-set.mjs +124 -0
- package/dist/tokens/color-set.mjs.map +1 -0
- package/dist/tooltip/index.d.mts +3 -0
- package/dist/tooltip/tooltip.d.mts +20 -0
- package/dist/tooltip/tooltip.d.mts.map +1 -0
- package/dist/tooltip/tooltip.mjs +45 -0
- package/dist/tooltip/tooltip.mjs.map +1 -0
- package/dist/tooltip/tooltip.styles.d.mts +48 -0
- package/dist/tooltip/tooltip.styles.d.mts.map +1 -0
- package/dist/tooltip/tooltip.styles.mjs +39 -0
- package/dist/tooltip/tooltip.styles.mjs.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import { ToastQueue } from "@novi-ui/core/client";
|
|
3
|
+
import { NoviColor } from "@novi-ui/core";
|
|
4
|
+
//#region src/toast/toast.d.ts
|
|
5
|
+
/** 1件分の通知内容。 */
|
|
6
|
+
interface NoviToast {
|
|
7
|
+
title?: ReactNode;
|
|
8
|
+
description?: ReactNode;
|
|
9
|
+
color?: NoviColor;
|
|
10
|
+
/** 補助操作。「元に戻す」など */
|
|
11
|
+
action?: ReactNode;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* 通知のキュー。アプリで1つ作って使い回す。
|
|
15
|
+
*
|
|
16
|
+
* 上流の React Aria では Toast がまだ不安定な API のため、
|
|
17
|
+
* core が安定名で再公開したものを経由している。
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* export const toast = createToastQueue()
|
|
21
|
+
* toast.add({ title: '保存しました', color: 'success' }, { timeout: 4000 })
|
|
22
|
+
*/
|
|
23
|
+
declare function createToastQueue(): ToastQueue<NoviToast>;
|
|
24
|
+
/**
|
|
25
|
+
* 通知の帯。**アプリの先頭(ヘッダの直下あたり)に置く**。
|
|
26
|
+
*
|
|
27
|
+
* 浮かないので、置いた場所がそのまま表示位置になります。通知が出ると帯が生えて
|
|
28
|
+
* 後続が押し下がり、閉じると元に戻ります。スクロールすれば流れて見えなくなります
|
|
29
|
+
* (`sticky` も使いません。滞留も重なりだからです・ADR-F4)。
|
|
30
|
+
*
|
|
31
|
+
* そのため、**見落とすと困る確認は Toast に置かないこと**。
|
|
32
|
+
* 取り返しのつかない操作の確認は Modal(テイクオーバー)を使ってください。
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* <body>
|
|
36
|
+
* <Header />
|
|
37
|
+
* <NoviToastRegion queue={toast} />
|
|
38
|
+
* <main>…</main>
|
|
39
|
+
* </body>
|
|
40
|
+
*/
|
|
41
|
+
declare function NoviToastRegion({ queue, className }: {
|
|
42
|
+
queue: ReturnType<typeof createToastQueue>;
|
|
43
|
+
className?: string;
|
|
44
|
+
}): import("react").JSX.Element;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { NoviToast, NoviToastRegion, createToastQueue };
|
|
47
|
+
//# sourceMappingURL=toast.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast.d.mts","names":[],"sources":["../../src/toast/toast.tsx"],"mappings":";;;;;UAiBiB;EACf,QAAQ;EACR,cAAc;EACd,QAAQ;;EAER,SAAS;;;;;;;;;;;;iBAaK,oBAAgB,WAAA;;;;;;;;;;;;;;;;;;iBAwDhB,kBACd,OACA;EAEA,OAAO,kBAAkB;EACzB;oBACD,IAAA"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { closeGlyphClass, toastStyles } from "./toast.styles.mjs";
|
|
3
|
+
import { Button, Text } from "react-aria-components";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { useCallback, useState } from "react";
|
|
6
|
+
import { InflowPortalProvider, Toast, ToastContent, ToastQueue, ToastRegion } from "@novi-ui/core/client";
|
|
7
|
+
//#region src/toast/toast.tsx
|
|
8
|
+
/**
|
|
9
|
+
* 通知のキュー。アプリで1つ作って使い回す。
|
|
10
|
+
*
|
|
11
|
+
* 上流の React Aria では Toast がまだ不安定な API のため、
|
|
12
|
+
* core が安定名で再公開したものを経由している。
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* export const toast = createToastQueue()
|
|
16
|
+
* toast.add({ title: '保存しました', color: 'success' }, { timeout: 4000 })
|
|
17
|
+
*/
|
|
18
|
+
function createToastQueue() {
|
|
19
|
+
return new ToastQueue({ maxVisibleToasts: 4 });
|
|
20
|
+
}
|
|
21
|
+
/** 通知1件分の行。 */
|
|
22
|
+
function ToastRow({ toast }) {
|
|
23
|
+
const s = toastStyles({ color: toast.content.color });
|
|
24
|
+
return /* @__PURE__ */ jsxs(Toast, {
|
|
25
|
+
toast,
|
|
26
|
+
"data-slot": "root",
|
|
27
|
+
className: s.root(),
|
|
28
|
+
children: [
|
|
29
|
+
/* @__PURE__ */ jsxs(ToastContent, {
|
|
30
|
+
"data-slot": "content",
|
|
31
|
+
className: s.content(),
|
|
32
|
+
children: [toast.content.title !== void 0 && /* @__PURE__ */ jsx(Text, {
|
|
33
|
+
slot: "title",
|
|
34
|
+
"data-slot": "title",
|
|
35
|
+
className: s.title(),
|
|
36
|
+
children: toast.content.title
|
|
37
|
+
}), toast.content.description !== void 0 && /* @__PURE__ */ jsx(Text, {
|
|
38
|
+
slot: "description",
|
|
39
|
+
"data-slot": "description",
|
|
40
|
+
className: s.description(),
|
|
41
|
+
children: toast.content.description
|
|
42
|
+
})]
|
|
43
|
+
}),
|
|
44
|
+
toast.content.action !== void 0 && /* @__PURE__ */ jsx("span", {
|
|
45
|
+
"data-slot": "action",
|
|
46
|
+
className: s.action(),
|
|
47
|
+
children: toast.content.action
|
|
48
|
+
}),
|
|
49
|
+
/* @__PURE__ */ jsx(Button, {
|
|
50
|
+
slot: "close",
|
|
51
|
+
"data-slot": "closeButton",
|
|
52
|
+
className: s.closeButton(),
|
|
53
|
+
"aria-label": "閉じる",
|
|
54
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
55
|
+
"aria-hidden": "true",
|
|
56
|
+
className: closeGlyphClass,
|
|
57
|
+
children: "✕"
|
|
58
|
+
})
|
|
59
|
+
})
|
|
60
|
+
]
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 通知の帯。**アプリの先頭(ヘッダの直下あたり)に置く**。
|
|
65
|
+
*
|
|
66
|
+
* 浮かないので、置いた場所がそのまま表示位置になります。通知が出ると帯が生えて
|
|
67
|
+
* 後続が押し下がり、閉じると元に戻ります。スクロールすれば流れて見えなくなります
|
|
68
|
+
* (`sticky` も使いません。滞留も重なりだからです・ADR-F4)。
|
|
69
|
+
*
|
|
70
|
+
* そのため、**見落とすと困る確認は Toast に置かないこと**。
|
|
71
|
+
* 取り返しのつかない操作の確認は Modal(テイクオーバー)を使ってください。
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* <body>
|
|
75
|
+
* <Header />
|
|
76
|
+
* <NoviToastRegion queue={toast} />
|
|
77
|
+
* <main>…</main>
|
|
78
|
+
* </body>
|
|
79
|
+
*/
|
|
80
|
+
function NoviToastRegion({ queue, className }) {
|
|
81
|
+
const [container, setContainer] = useState(null);
|
|
82
|
+
const getContainer = useCallback(() => container, [container]);
|
|
83
|
+
return /* @__PURE__ */ jsx("div", {
|
|
84
|
+
ref: setContainer,
|
|
85
|
+
"data-novi-inflow": "",
|
|
86
|
+
children: container !== null && /* @__PURE__ */ jsx(InflowPortalProvider, {
|
|
87
|
+
getContainer,
|
|
88
|
+
children: /* @__PURE__ */ jsx(ToastRegion, {
|
|
89
|
+
queue,
|
|
90
|
+
"data-slot": "region",
|
|
91
|
+
className: toastStyles().region({ class: className }),
|
|
92
|
+
children: ({ toast }) => /* @__PURE__ */ jsx(ToastRow, { toast })
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
export { NoviToastRegion, createToastQueue };
|
|
99
|
+
|
|
100
|
+
//# sourceMappingURL=toast.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast.mjs","names":[],"sources":["../../src/toast/toast.tsx"],"sourcesContent":["'use client'\n\nimport type { NoviColor } from '@novi-ui/core'\n// UNSTABLE_ / UNSAFE_ には触れない。core が安定名で再公開したものだけを使う(ADR-07 / ADR-F5)\nimport {\n InflowPortalProvider,\n type QueuedToast,\n Toast,\n ToastContent,\n ToastQueue,\n ToastRegion,\n} from '@novi-ui/core/client'\nimport { type ReactNode, useCallback, useState } from 'react'\nimport { Button, Text } from 'react-aria-components'\nimport { closeGlyphClass, toastStyles } from './toast.styles'\n\n/** 1件分の通知内容。 */\nexport interface NoviToast {\n title?: ReactNode\n description?: ReactNode\n color?: NoviColor\n /** 補助操作。「元に戻す」など */\n action?: ReactNode\n}\n\n/**\n * 通知のキュー。アプリで1つ作って使い回す。\n *\n * 上流の React Aria では Toast がまだ不安定な API のため、\n * core が安定名で再公開したものを経由している。\n *\n * @example\n * export const toast = createToastQueue()\n * toast.add({ title: '保存しました', color: 'success' }, { timeout: 4000 })\n */\nexport function createToastQueue() {\n return new ToastQueue<NoviToast>({ maxVisibleToasts: 4 })\n}\n\n/** 通知1件分の行。 */\nfunction ToastRow({ toast }: { toast: QueuedToast<NoviToast> }) {\n const s = toastStyles({ color: toast.content.color })\n\n return (\n <Toast toast={toast} data-slot=\"root\" className={s.root()}>\n <ToastContent data-slot=\"content\" className={s.content()}>\n {toast.content.title !== undefined && (\n <Text slot=\"title\" data-slot=\"title\" className={s.title()}>\n {toast.content.title}\n </Text>\n )}\n {toast.content.description !== undefined && (\n <Text slot=\"description\" data-slot=\"description\" className={s.description()}>\n {toast.content.description}\n </Text>\n )}\n </ToastContent>\n\n {toast.content.action !== undefined && (\n <span data-slot=\"action\" className={s.action()}>\n {toast.content.action}\n </span>\n )}\n\n {/* 閉じるは記号そのもの。SVG ではなく文字なのは帳票の語彙だから(ADR-F7) */}\n <Button slot=\"close\" data-slot=\"closeButton\" className={s.closeButton()} aria-label=\"閉じる\">\n <span aria-hidden=\"true\" className={closeGlyphClass}>\n ✕\n </span>\n </Button>\n </Toast>\n )\n}\n\n/**\n * 通知の帯。**アプリの先頭(ヘッダの直下あたり)に置く**。\n *\n * 浮かないので、置いた場所がそのまま表示位置になります。通知が出ると帯が生えて\n * 後続が押し下がり、閉じると元に戻ります。スクロールすれば流れて見えなくなります\n * (`sticky` も使いません。滞留も重なりだからです・ADR-F4)。\n *\n * そのため、**見落とすと困る確認は Toast に置かないこと**。\n * 取り返しのつかない操作の確認は Modal(テイクオーバー)を使ってください。\n *\n * @example\n * <body>\n * <Header />\n * <NoviToastRegion queue={toast} />\n * <main>…</main>\n * </body>\n */\nexport function NoviToastRegion({\n queue,\n className,\n}: {\n queue: ReturnType<typeof createToastQueue>\n className?: string\n}) {\n // 上流の region は prop を持たず必ず body へポータルする。\n // ここで置き場所を差し替えて、生えるのが「この位置」になるようにする(ADR-F4)\n const [container, setContainer] = useState<HTMLElement | null>(null)\n const getContainer = useCallback(() => container, [container])\n\n return (\n <div ref={setContainer} data-novi-inflow=\"\">\n {container !== null && (\n <InflowPortalProvider getContainer={getContainer}>\n <ToastRegion\n queue={queue}\n data-slot=\"region\"\n className={toastStyles().region({ class: className })}\n >\n {({ toast }) => <ToastRow toast={toast} />}\n </ToastRegion>\n </InflowPortalProvider>\n )}\n </div>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAmCA,SAAgB,mBAAmB;CACjC,OAAO,IAAI,WAAsB,EAAE,kBAAkB,EAAE,CAAC;AAC1D;;AAGA,SAAS,SAAS,EAAE,SAA4C;CAC9D,MAAM,IAAI,YAAY,EAAE,OAAO,MAAM,QAAQ,MAAM,CAAC;CAEpD,OACE,qBAAC,OAAD;EAAc;EAAO,aAAU;EAAO,WAAW,EAAE,KAAK;EAAxD,UAAA;GACE,qBAAC,cAAD;IAAc,aAAU;IAAU,WAAW,EAAE,QAAQ;IAAvD,UAAA,CACG,MAAM,QAAQ,UAAU,KAAA,KACvB,oBAAC,MAAD;KAAM,MAAK;KAAQ,aAAU;KAAQ,WAAW,EAAE,MAAM;KACrD,UAAA,MAAM,QAAQ;IACX,CAAA,GAEP,MAAM,QAAQ,gBAAgB,KAAA,KAC7B,oBAAC,MAAD;KAAM,MAAK;KAAc,aAAU;KAAc,WAAW,EAAE,YAAY;KACvE,UAAA,MAAM,QAAQ;IACX,CAAA,CAEI;;GAEb,MAAM,QAAQ,WAAW,KAAA,KACxB,oBAAC,QAAD;IAAM,aAAU;IAAS,WAAW,EAAE,OAAO;IAC1C,UAAA,MAAM,QAAQ;GACX,CAAA;GAIR,oBAAC,QAAD;IAAQ,MAAK;IAAQ,aAAU;IAAc,WAAW,EAAE,YAAY;IAAG,cAAW;IAClF,UAAA,oBAAC,QAAD;KAAM,eAAY;KAAO,WAAW;KAAiB,UAAA;IAE/C,CAAA;GACA,CAAA;EACH;;AAEX;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,gBAAgB,EAC9B,OACA,aAIC;CAGD,MAAM,CAAC,WAAW,gBAAgB,SAA6B,IAAI;CACnE,MAAM,eAAe,kBAAkB,WAAW,CAAC,SAAS,CAAC;CAE7D,OACE,oBAAC,OAAD;EAAK,KAAK;EAAc,oBAAiB;EACtC,UAAA,cAAc,QACb,oBAAC,sBAAD;GAAoC;GAClC,UAAA,oBAAC,aAAD;IACS;IACP,aAAU;IACV,WAAW,YAAY,CAAC,CAAC,OAAO,EAAE,OAAO,UAAU,CAAC;IAElD,WAAA,EAAE,YAAY,oBAAC,UAAD,EAAiB,MAAQ,CAAA;GAC9B,CAAA;EACO,CAAA;CAErB,CAAA;AAET"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { VariantMap } from "@novi-ui/core";
|
|
2
|
+
//#region src/toast/toast.styles.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Toast のスタイル定義。
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* const myToast = tv({ extend: toastStyles, slots: { region: 'gap-3' } })
|
|
8
|
+
*/
|
|
9
|
+
declare const toastStyles: import("tailwind-variants").TVReturnType<{
|
|
10
|
+
color: VariantMap<"default" | "primary" | "secondary" | "success" | "warning" | "danger", {
|
|
11
|
+
root: string;
|
|
12
|
+
}>;
|
|
13
|
+
radius: VariantMap<"sm" | "md" | "lg" | "none" | "full", {
|
|
14
|
+
root: string;
|
|
15
|
+
}>;
|
|
16
|
+
}, {
|
|
17
|
+
region: string;
|
|
18
|
+
root: string;
|
|
19
|
+
icon: string;
|
|
20
|
+
content: string;
|
|
21
|
+
title: string;
|
|
22
|
+
description: string;
|
|
23
|
+
closeButton: string;
|
|
24
|
+
action: string;
|
|
25
|
+
}, undefined, {
|
|
26
|
+
color: VariantMap<"default" | "primary" | "secondary" | "success" | "warning" | "danger", {
|
|
27
|
+
root: string;
|
|
28
|
+
}>;
|
|
29
|
+
radius: VariantMap<"sm" | "md" | "lg" | "none" | "full", {
|
|
30
|
+
root: string;
|
|
31
|
+
}>;
|
|
32
|
+
}, {
|
|
33
|
+
region: string;
|
|
34
|
+
root: string;
|
|
35
|
+
icon: string;
|
|
36
|
+
content: string;
|
|
37
|
+
title: string;
|
|
38
|
+
description: string;
|
|
39
|
+
closeButton: string;
|
|
40
|
+
action: string;
|
|
41
|
+
}, import("tailwind-variants").TVReturnTypeLike<{
|
|
42
|
+
color: VariantMap<"default" | "primary" | "secondary" | "success" | "warning" | "danger", {
|
|
43
|
+
root: string;
|
|
44
|
+
}>;
|
|
45
|
+
radius: VariantMap<"sm" | "md" | "lg" | "none" | "full", {
|
|
46
|
+
root: string;
|
|
47
|
+
}>;
|
|
48
|
+
}, {
|
|
49
|
+
region: string;
|
|
50
|
+
root: string;
|
|
51
|
+
icon: string;
|
|
52
|
+
content: string;
|
|
53
|
+
title: string;
|
|
54
|
+
description: string;
|
|
55
|
+
closeButton: string;
|
|
56
|
+
action: string;
|
|
57
|
+
}>>;
|
|
58
|
+
type ToastStyleProps = Parameters<typeof toastStyles>[0];
|
|
59
|
+
//#endregion
|
|
60
|
+
export { ToastStyleProps, toastStyles };
|
|
61
|
+
//# sourceMappingURL=toast.styles.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast.styles.d.mts","names":[],"sources":["../../src/toast/toast.styles.ts"],"mappings":";;;;;;;;cA8Ea,yCAAW;;IAvBmB;;;IASE;;;;;;;;;;;;;IATF;;;IASE;;;;;;;;;;;;;IATF;;;IASE;;;;;;;;;;;;KAqBjC,kBAAkB,kBAAkB"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { disabledState, focusRing } from "../styles/focus-ring.mjs";
|
|
2
|
+
import { mono } from "../styles/mono.mjs";
|
|
3
|
+
import { tv } from "tailwind-variants";
|
|
4
|
+
//#region src/toast/toast.styles.ts
|
|
5
|
+
/**
|
|
6
|
+
* Flatlay の Toast は**フローに挿し込まれる帯**(ADR-F4)。
|
|
7
|
+
*
|
|
8
|
+
* 右下(Raster)にも上端中央(Tactile)にも固定しない。固定は viewport に
|
|
9
|
+
* 貼り付けること、つまり z 軸そのものだから。`sticky` も同じ理由で使わない
|
|
10
|
+
* (スクロール中にコンテンツへ重なった時点で「重なりを持つ UI」になる)。
|
|
11
|
+
*
|
|
12
|
+
* 代わりに region はアプリの先頭に置くフローの帯で、スクロールすれば
|
|
13
|
+
* 流れて見えなくなってよい。帳票の朱書きはページの先頭にあり、
|
|
14
|
+
* 読み進めるあいだ追いかけてはこない。
|
|
15
|
+
*
|
|
16
|
+
* この割り切りの代償は「長いページで気づきにくい」こと。
|
|
17
|
+
* 見落とすと困る確認は Toast ではなく Modal(テイクオーバー)を使う。
|
|
18
|
+
*/
|
|
19
|
+
const slots = {
|
|
20
|
+
region: "flex flex-col gap-1.5 w-full outline-none",
|
|
21
|
+
root: [
|
|
22
|
+
"w-full flex items-start gap-3 px-3 py-2 outline-none",
|
|
23
|
+
"text-[var(--novi-color-fg)] bg-[var(--novi-color-subtle)]",
|
|
24
|
+
"border border-[var(--novi-color-border-strong)]",
|
|
25
|
+
"border-l-2 border-l-[var(--c)]"
|
|
26
|
+
].join(" "),
|
|
27
|
+
icon: "shrink-0 text-[var(--c)]",
|
|
28
|
+
content: "flex-1 min-w-0 flex flex-col gap-0.5",
|
|
29
|
+
title: `truncate font-medium ${mono}`,
|
|
30
|
+
description: `text-[length:var(--novi-text-sm)] text-[var(--novi-color-muted)] ${mono}`,
|
|
31
|
+
closeButton: [
|
|
32
|
+
"shrink-0 grid place-items-center size-5",
|
|
33
|
+
"text-[var(--novi-color-muted)]",
|
|
34
|
+
"border border-transparent",
|
|
35
|
+
"hover:text-[var(--novi-color-fg)]",
|
|
36
|
+
"data-[pressed]:bg-[var(--novi-color-fg)] data-[pressed]:text-[var(--novi-color-bg)]",
|
|
37
|
+
"transition-[background-color,color]",
|
|
38
|
+
"duration-[var(--novi-duration-fast)] ease-[var(--novi-ease-standard)]",
|
|
39
|
+
focusRing,
|
|
40
|
+
disabledState
|
|
41
|
+
].join(" "),
|
|
42
|
+
action: "shrink-0"
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Toast のスタイル定義。
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* const myToast = tv({ extend: toastStyles, slots: { region: 'gap-3' } })
|
|
49
|
+
*/
|
|
50
|
+
const toastStyles = tv({
|
|
51
|
+
slots,
|
|
52
|
+
variants: {
|
|
53
|
+
color: {
|
|
54
|
+
default: { root: "[--c:var(--novi-color-border-strong)]" },
|
|
55
|
+
primary: { root: "[--c:var(--novi-color-primary)]" },
|
|
56
|
+
secondary: { root: "[--c:var(--novi-color-secondary)]" },
|
|
57
|
+
success: { root: "[--c:var(--novi-color-success)]" },
|
|
58
|
+
warning: { root: "[--c:var(--novi-color-warning)]" },
|
|
59
|
+
danger: { root: "[--c:var(--novi-color-danger)]" }
|
|
60
|
+
},
|
|
61
|
+
radius: {
|
|
62
|
+
none: { root: "rounded-[var(--novi-radius-none)]" },
|
|
63
|
+
sm: { root: "rounded-[var(--novi-radius-sm)]" },
|
|
64
|
+
md: { root: "rounded-[var(--novi-radius-md)]" },
|
|
65
|
+
lg: { root: "rounded-[var(--novi-radius-lg)]" },
|
|
66
|
+
full: { root: "rounded-[var(--novi-radius-full)]" }
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
defaultVariants: {
|
|
70
|
+
color: "default",
|
|
71
|
+
radius: "none"
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
/** 閉じるの ✕。等幅で出す(ADR-F7・Modal の「← 戻る」と同じ扱い)。 */
|
|
75
|
+
const closeGlyphClass = mono;
|
|
76
|
+
//#endregion
|
|
77
|
+
export { closeGlyphClass, toastStyles };
|
|
78
|
+
|
|
79
|
+
//# sourceMappingURL=toast.styles.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast.styles.mjs","names":[],"sources":["../../src/toast/toast.styles.ts"],"sourcesContent":["import type {\n NoviColor,\n NoviRadius,\n SlotMap,\n toastRequiredSlots,\n toastSlots,\n VariantMap,\n} from '@novi-ui/core'\nimport { tv } from 'tailwind-variants'\nimport { disabledState, focusRing } from '../styles/focus-ring'\nimport { mono } from '../styles/mono'\n\n/**\n * Flatlay の Toast は**フローに挿し込まれる帯**(ADR-F4)。\n *\n * 右下(Raster)にも上端中央(Tactile)にも固定しない。固定は viewport に\n * 貼り付けること、つまり z 軸そのものだから。`sticky` も同じ理由で使わない\n * (スクロール中にコンテンツへ重なった時点で「重なりを持つ UI」になる)。\n *\n * 代わりに region はアプリの先頭に置くフローの帯で、スクロールすれば\n * 流れて見えなくなってよい。帳票の朱書きはページの先頭にあり、\n * 読み進めるあいだ追いかけてはこない。\n *\n * この割り切りの代償は「長いページで気づきにくい」こと。\n * 見落とすと困る確認は Toast ではなく Modal(テイクオーバー)を使う。\n */\nconst slots = {\n // 固定しない。置いた場所がそのまま表示位置になる(アプリ先頭を推奨)\n region: 'flex flex-col gap-1.5 w-full outline-none',\n root: [\n 'w-full flex items-start gap-3 px-3 py-2 outline-none',\n 'text-[var(--novi-color-fg)] bg-[var(--novi-color-subtle)]',\n // 左端の太い罫が朱書きの線。色はここだけが受け持つ\n 'border border-[var(--novi-color-border-strong)]',\n 'border-l-2 border-l-[var(--c)]',\n ].join(' '),\n icon: 'shrink-0 text-[var(--c)]',\n content: 'flex-1 min-w-0 flex flex-col gap-0.5',\n // 見出しも注記も等幅。通知は読ませる文ではなく読み取らせる記録(ADR-F7)\n title: `truncate font-medium ${mono}`,\n description: `text-[length:var(--novi-text-sm)] text-[var(--novi-color-muted)] ${mono}`,\n closeButton: [\n 'shrink-0 grid place-items-center size-5',\n 'text-[var(--novi-color-muted)]',\n 'border border-transparent',\n 'hover:text-[var(--novi-color-fg)]',\n 'data-[pressed]:bg-[var(--novi-color-fg)] data-[pressed]:text-[var(--novi-color-bg)]',\n 'transition-[background-color,color]',\n 'duration-[var(--novi-duration-fast)] ease-[var(--novi-ease-standard)]',\n focusRing,\n disabledState,\n ].join(' '),\n action: 'shrink-0',\n} satisfies SlotMap<typeof toastSlots, (typeof toastRequiredSlots)[number]>\n\nconst color: VariantMap<NoviColor, { root: string }> = {\n default: { root: '[--c:var(--novi-color-border-strong)]' },\n primary: { root: '[--c:var(--novi-color-primary)]' },\n secondary: { root: '[--c:var(--novi-color-secondary)]' },\n success: { root: '[--c:var(--novi-color-success)]' },\n warning: { root: '[--c:var(--novi-color-warning)]' },\n danger: { root: '[--c:var(--novi-color-danger)]' },\n}\n\nconst radius: VariantMap<NoviRadius, { root: string }> = {\n none: { root: 'rounded-[var(--novi-radius-none)]' },\n sm: { root: 'rounded-[var(--novi-radius-sm)]' },\n md: { root: 'rounded-[var(--novi-radius-md)]' },\n lg: { root: 'rounded-[var(--novi-radius-lg)]' },\n full: { root: 'rounded-[var(--novi-radius-full)]' },\n}\n\n/**\n * Toast のスタイル定義。\n *\n * @example\n * const myToast = tv({ extend: toastStyles, slots: { region: 'gap-3' } })\n */\nexport const toastStyles = tv({\n slots,\n variants: { color, radius },\n // 紙の幅いっぱいに走る帯に角は要らない(両テーマの既定は lg)\n defaultVariants: { color: 'default', radius: 'none' },\n})\n\nexport type ToastStyleProps = Parameters<typeof toastStyles>[0]\n\n/** 閉じるの ✕。等幅で出す(ADR-F7・Modal の「← 戻る」と同じ扱い)。 */\nexport const closeGlyphClass = mono\n"],"mappings":";;;;;;;;;;;;;;;;;;AA0BA,MAAM,QAAQ;CAEZ,QAAQ;CACR,MAAM;EACJ;EACA;EAEA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CACV,MAAM;CACN,SAAS;CAET,OAAO,wBAAwB;CAC/B,aAAa,oEAAoE;CACjF,aAAa;EACX;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CACV,QAAQ;AACV;;;;;;;AAyBA,MAAa,cAAc,GAAG;CAC5B;CACA,UAAU;EAAE;GAxBZ,SAAS,EAAE,MAAM,wCAAwC;GACzD,SAAS,EAAE,MAAM,kCAAkC;GACnD,WAAW,EAAE,MAAM,oCAAoC;GACvD,SAAS,EAAE,MAAM,kCAAkC;GACnD,SAAS,EAAE,MAAM,kCAAkC;GACnD,QAAQ,EAAE,MAAM,iCAAiC;EAmBrC;EAAO;GAfnB,MAAM,EAAE,MAAM,oCAAoC;GAClD,IAAI,EAAE,MAAM,kCAAkC;GAC9C,IAAI,EAAE,MAAM,kCAAkC;GAC9C,IAAI,EAAE,MAAM,kCAAkC;GAC9C,MAAM,EAAE,MAAM,oCAAoC;EAW/B;CAAO;CAE1B,iBAAiB;EAAE,OAAO;EAAW,QAAQ;CAAO;AACtD,CAAC;;AAKD,MAAa,kBAAkB"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
//#region src/tokens/color-set.ts
|
|
2
|
+
/**
|
|
3
|
+
* Stationery のトーン。
|
|
4
|
+
*
|
|
5
|
+
* 三部作で L は 44 / 50 / **47**、C は light 0.090 / 0.080 / **0.070** の等差になる。
|
|
6
|
+
* L47 は掃引で決めた値で、律速は **Fieldbook を `subtle` 面に置いたとき(5.76:1)**。
|
|
7
|
+
* 実用上限は L52(4.65:1)で、L53 で 4.46:1 と基準を割る。上限ぎりぎりを採らないのは、
|
|
8
|
+
* 後から subtle の明度を動かせなくなるため(`flatlay-tokens.test.ts` の変異テストが境界を固定する)。
|
|
9
|
+
* C を両テーマより低く取るのは、机の上の事務道具は染料でも印刷インクでもなく、
|
|
10
|
+
* 「褪せた実用品の色」だから。
|
|
11
|
+
*/
|
|
12
|
+
const FLATLAY_TONE = {
|
|
13
|
+
light: {
|
|
14
|
+
l: 47,
|
|
15
|
+
c: .07
|
|
16
|
+
},
|
|
17
|
+
dark: {
|
|
18
|
+
l: 75,
|
|
19
|
+
c: .06
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* 8色。全色が**机の上の事務道具**の実名を持つ。
|
|
24
|
+
*
|
|
25
|
+
* **赤が無いのは欠落ではなく決定**(requirements Background)。校正の朱書きは
|
|
26
|
+
* エラー表示の道具なので、赤は意味色(danger)に予約する。
|
|
27
|
+
* primary が danger と紛れる事故を、規則ではなく世界観で防ぐ。
|
|
28
|
+
*/
|
|
29
|
+
const COLOR_DEFS = [
|
|
30
|
+
{
|
|
31
|
+
id: "fieldbook",
|
|
32
|
+
name: "Fieldbook",
|
|
33
|
+
hue: 172,
|
|
34
|
+
pair: "eraser",
|
|
35
|
+
description: "測量野帳の表紙の緑。既定色"
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: "blueprint",
|
|
39
|
+
name: "Blueprint",
|
|
40
|
+
hue: 215,
|
|
41
|
+
pair: "manila",
|
|
42
|
+
description: "青焼き図面の青"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "carbon",
|
|
46
|
+
name: "Carbon",
|
|
47
|
+
hue: 288,
|
|
48
|
+
pair: "legalpad",
|
|
49
|
+
description: "カーボン複写紙の紫"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "ribbon",
|
|
53
|
+
name: "Ribbon",
|
|
54
|
+
hue: 330,
|
|
55
|
+
pair: "fieldbook",
|
|
56
|
+
description: "タイプライターのインクリボン"
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "eraser",
|
|
60
|
+
name: "Eraser",
|
|
61
|
+
hue: 352,
|
|
62
|
+
pair: "pencil",
|
|
63
|
+
description: "ピンクの消しゴム"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: "manila",
|
|
67
|
+
name: "Manila",
|
|
68
|
+
hue: 58,
|
|
69
|
+
pair: "blueprint",
|
|
70
|
+
description: "マニラ封筒の黄土"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: "legalpad",
|
|
74
|
+
name: "Legalpad",
|
|
75
|
+
hue: 98,
|
|
76
|
+
pair: "carbon",
|
|
77
|
+
description: "黄色いリーガルパッド"
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: "pencil",
|
|
81
|
+
name: "Pencil",
|
|
82
|
+
hue: 240,
|
|
83
|
+
pair: "eraser",
|
|
84
|
+
description: "鉛筆の芯。無彩枠",
|
|
85
|
+
fixedC: .02,
|
|
86
|
+
fixedCDark: .017
|
|
87
|
+
}
|
|
88
|
+
];
|
|
89
|
+
/**
|
|
90
|
+
* `data-novi-color` 未指定・未知の名前のときに効く色(FR-08)。
|
|
91
|
+
*
|
|
92
|
+
* Fieldbook(緑)なのは、Ink 268・Indigo 255 に続く**3代連続の藍を避ける**ため
|
|
93
|
+
* (デザイン診断 B-2)。既定色はモデルの第一印象そのものになる。
|
|
94
|
+
*/
|
|
95
|
+
const DEFAULT_COLOR_ID = "fieldbook";
|
|
96
|
+
const oklch = (l, c, hue) => `oklch(${l}% ${c} ${hue})`;
|
|
97
|
+
/**
|
|
98
|
+
* 色面に乗る文字。押下で反転すると**この色が面になる**ため(ADR-F3)、
|
|
99
|
+
* 地の紙とほぼ同じ明度に置いて、反転しても紙の上に見えるようにする。
|
|
100
|
+
*/
|
|
101
|
+
const primaryFgFor = (hue, scheme) => scheme === "light" ? oklch(98.5, .004, hue) : oklch(18, .02, hue);
|
|
102
|
+
/**
|
|
103
|
+
* 定義とトーンから実際の CSS 値を組み立てる。
|
|
104
|
+
* テストが不正なトーンを作って検査そのものを確かめるのにも使う。
|
|
105
|
+
*/
|
|
106
|
+
function buildColorEntry(def, tone = FLATLAY_TONE) {
|
|
107
|
+
return {
|
|
108
|
+
...def,
|
|
109
|
+
light: {
|
|
110
|
+
primary: oklch(tone.light.l, def.fixedC ?? tone.light.c, def.hue),
|
|
111
|
+
primaryFg: primaryFgFor(def.hue, "light")
|
|
112
|
+
},
|
|
113
|
+
dark: {
|
|
114
|
+
primary: oklch(tone.dark.l, def.fixedCDark ?? tone.dark.c, def.hue),
|
|
115
|
+
primaryFg: primaryFgFor(def.hue, "dark")
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** Stationery の全8色(事前計算済み) */
|
|
120
|
+
const FLATLAY_COLOR_SET = COLOR_DEFS.map((def) => buildColorEntry(def));
|
|
121
|
+
//#endregion
|
|
122
|
+
export { DEFAULT_COLOR_ID, FLATLAY_COLOR_SET, FLATLAY_TONE, buildColorEntry };
|
|
123
|
+
|
|
124
|
+
//# sourceMappingURL=color-set.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color-set.mjs","names":[],"sources":["../../src/tokens/color-set.ts"],"sourcesContent":["/**\n * Flatlay のカラーセット「Stationery」とトーン。\n *\n * **specs/06-tones-and-colors と specs/07-theme-flatlay が唯一の真実**で、ここはその写し。\n * 構造は Raster / Tactile の `color-set.ts` と同じだが、値も**染まり方**も独立している。\n *\n * 三部作の中立色の扱いは3方式ある:\n * - Raster 染まらない紙(中立は完全な無彩)\n * - Tactile 染まる生地(中立まで hue に従う)\n * - Flatlay **地は染まらず、罫線だけが染まる**(FR-07)\n *\n * 第3方式なのは、Flatlay が階層を罫線でしか作れないため。\n * 唯一の階層表現に色を持たせないと、色を選んだ実感がどこにも出ない。\n */\n\nexport interface FlatlayTone {\n /** OKLCH の L(% 単位の数値。47 = 47%) */\n l: number\n /** OKLCH の C */\n c: number\n}\n\n/**\n * Stationery のトーン。\n *\n * 三部作で L は 44 / 50 / **47**、C は light 0.090 / 0.080 / **0.070** の等差になる。\n * L47 は掃引で決めた値で、律速は **Fieldbook を `subtle` 面に置いたとき(5.76:1)**。\n * 実用上限は L52(4.65:1)で、L53 で 4.46:1 と基準を割る。上限ぎりぎりを採らないのは、\n * 後から subtle の明度を動かせなくなるため(`flatlay-tokens.test.ts` の変異テストが境界を固定する)。\n * C を両テーマより低く取るのは、机の上の事務道具は染料でも印刷インクでもなく、\n * 「褪せた実用品の色」だから。\n */\nexport const FLATLAY_TONE: { light: FlatlayTone; dark: FlatlayTone } = {\n light: { l: 47, c: 0.07 },\n dark: { l: 75, c: 0.06 },\n}\n\nexport interface FlatlayColorDef {\n /** `data-novi-color` に指定する名前(kebab-case) */\n id: string\n /** 表示名 */\n name: string\n /** OKLCH の hue(度) */\n hue: number\n /** 相方(ダブルエントリー)。`--novi-color-secondary` にこの色の値が入る */\n pair: string\n /** 1行の出自。docs / llms / MCP が使う */\n description: string\n /** 無彩枠だけが持つ C の例外値(light) */\n fixedC?: number\n /** 同・dark */\n fixedCDark?: number\n}\n\n/**\n * 8色。全色が**机の上の事務道具**の実名を持つ。\n *\n * **赤が無いのは欠落ではなく決定**(requirements Background)。校正の朱書きは\n * エラー表示の道具なので、赤は意味色(danger)に予約する。\n * primary が danger と紛れる事故を、規則ではなく世界観で防ぐ。\n */\nconst COLOR_DEFS: readonly FlatlayColorDef[] = [\n {\n id: 'fieldbook',\n name: 'Fieldbook',\n hue: 172,\n pair: 'eraser',\n description: '測量野帳の表紙の緑。既定色',\n },\n {\n id: 'blueprint',\n name: 'Blueprint',\n hue: 215,\n pair: 'manila',\n description: '青焼き図面の青',\n },\n {\n id: 'carbon',\n name: 'Carbon',\n hue: 288,\n pair: 'legalpad',\n description: 'カーボン複写紙の紫',\n },\n {\n id: 'ribbon',\n name: 'Ribbon',\n hue: 330,\n pair: 'fieldbook',\n description: 'タイプライターのインクリボン',\n },\n {\n id: 'eraser',\n name: 'Eraser',\n hue: 352,\n pair: 'pencil',\n description: 'ピンクの消しゴム',\n },\n {\n id: 'manila',\n name: 'Manila',\n hue: 58,\n pair: 'blueprint',\n description: 'マニラ封筒の黄土',\n },\n {\n id: 'legalpad',\n name: 'Legalpad',\n hue: 98,\n pair: 'carbon',\n description: '黄色いリーガルパッド',\n },\n {\n id: 'pencil',\n name: 'Pencil',\n hue: 240,\n pair: 'eraser',\n description: '鉛筆の芯。無彩枠',\n fixedC: 0.02,\n fixedCDark: 0.017,\n },\n]\n\n/**\n * `data-novi-color` 未指定・未知の名前のときに効く色(FR-08)。\n *\n * Fieldbook(緑)なのは、Ink 268・Indigo 255 に続く**3代連続の藍を避ける**ため\n * (デザイン診断 B-2)。既定色はモデルの第一印象そのものになる。\n */\nexport const DEFAULT_COLOR_ID = 'fieldbook'\n\n/**\n * OKLCH → 線形 sRGB。\n * 生成器(Node 実行)からも呼ぶため、依存なしで持つ(両テーマと同じ理由)。\n */\nfunction toLinearSrgb(l: number, c: number, hue: number): [number, number, number] {\n const rad = (hue * Math.PI) / 180\n const a = c * Math.cos(rad)\n const b = c * Math.sin(rad)\n\n const lc = (l + 0.3963377774 * a + 0.2158037573 * b) ** 3\n const mc = (l - 0.1055613458 * a - 0.0638541728 * b) ** 3\n const sc = (l - 0.0894841775 * a - 1.291485548 * b) ** 3\n\n return [\n 4.0767416621 * lc - 3.3077115913 * mc + 0.2309699292 * sc,\n -1.2684380046 * lc + 2.6097574011 * mc - 0.3413193965 * sc,\n -0.0041960863 * lc - 0.7034186147 * mc + 1.707614701 * sc,\n ]\n}\n\n/** その OKLCH が sRGB で再現できるか。トーンの天井はコントラストではなくこれが決める。 */\nexport function inSrgbGamut(l: number, c: number, hue: number): boolean {\n const tolerance = 0.0005\n return toLinearSrgb(l, c, hue).every((v) => v >= -tolerance && v <= 1 + tolerance)\n}\n\n/**\n * 染まらない紙の配合。**chroma は 0 で固定**(FR-07)。\n *\n * `surface` が `bg` と同値なのは Flatlay の性格そのもの。浮く面が存在しないので、\n * 「持ち上がった面の色」という概念が要らない。面の境目は罫線だけが作る。\n * `overlay` も同じ理由で暗幕ではなく紙色になる(ADR-F2)。\n */\nconst PAPER_RECIPE = {\n light: {\n bg: 98.8,\n subtle: 95.5,\n surface: 98.8,\n overlay: 98.8,\n fg: 22,\n muted: 46,\n default: 95.5,\n 'default-fg': 22,\n },\n dark: {\n bg: 15,\n subtle: 20,\n surface: 15,\n overlay: 15,\n fg: 94,\n muted: 70,\n default: 20,\n 'default-fg': 94,\n },\n} as const\n\n/**\n * 染まる罫線の配合。**Flatlay で唯一 hue に従うトークン**。\n *\n * C は 0.02〜0.03 の帯域。これ未満だと選んだ色が見えず、超えると\n * 「線に色が塗ってある」ようになって帳票の顔から外れる。\n * `border-strong` の L は全 hue で bg に対し 3:1 を満たす値(実測 3.99〜4.20:1)。\n */\nconst RULE_RECIPE = {\n light: {\n border: { l: 88, c: 0.025 },\n 'border-strong': { l: 58, c: 0.03 },\n },\n dark: {\n border: { l: 32, c: 0.022 },\n 'border-strong': { l: 55, c: 0.03 },\n },\n} as const\n\nexport type Scheme = 'light' | 'dark'\n\nconst oklch = (l: number, c: number, hue: number) => `oklch(${l}% ${c} ${hue})`\n\n/**\n * その色を選んだときの中立色一式。\n * 地・文字は hue を渡しても無彩のまま返り、罫線 2 本だけが染まる。\n */\nexport function neutralsFor(hue: number, scheme: Scheme): Record<string, string> {\n const out: Record<string, string> = {}\n for (const [name, l] of Object.entries(PAPER_RECIPE[scheme])) {\n out[name] = oklch(l, 0, 0)\n }\n for (const [name, { l, c }] of Object.entries(RULE_RECIPE[scheme])) {\n out[name] = oklch(l, c, hue)\n }\n return out\n}\n\nexport interface FlatlayColorSchemeValues {\n primary: string\n primaryFg: string\n}\n\nexport interface FlatlayColorEntry extends FlatlayColorDef {\n light: FlatlayColorSchemeValues\n dark: FlatlayColorSchemeValues\n}\n\n/**\n * 色面に乗る文字。押下で反転すると**この色が面になる**ため(ADR-F3)、\n * 地の紙とほぼ同じ明度に置いて、反転しても紙の上に見えるようにする。\n */\nconst primaryFgFor = (hue: number, scheme: Scheme) =>\n scheme === 'light' ? oklch(98.5, 0.004, hue) : oklch(18, 0.02, hue)\n\n/**\n * 定義とトーンから実際の CSS 値を組み立てる。\n * テストが不正なトーンを作って検査そのものを確かめるのにも使う。\n */\nexport function buildColorEntry(\n def: FlatlayColorDef,\n tone: { light: FlatlayTone; dark: FlatlayTone } = FLATLAY_TONE,\n): FlatlayColorEntry {\n return {\n ...def,\n light: {\n primary: oklch(tone.light.l, def.fixedC ?? tone.light.c, def.hue),\n primaryFg: primaryFgFor(def.hue, 'light'),\n },\n dark: {\n primary: oklch(tone.dark.l, def.fixedCDark ?? tone.dark.c, def.hue),\n primaryFg: primaryFgFor(def.hue, 'dark'),\n },\n }\n}\n\n/** Stationery の全8色(事前計算済み) */\nexport const FLATLAY_COLOR_SET: readonly FlatlayColorEntry[] = COLOR_DEFS.map((def) =>\n buildColorEntry(def),\n)\n\n/** @throws セットに無い id(相方の参照ミスは実行時ではなくここで死ぬべき) */\nexport function colorById(id: string): FlatlayColorEntry {\n const entry = FLATLAY_COLOR_SET.find((c) => c.id === id)\n if (entry === undefined) throw new Error(`Stationery に無い色です: ${id}`)\n return entry\n}\n"],"mappings":";;;;;;;;;;;AAgCA,MAAa,eAA0D;CACrE,OAAO;EAAE,GAAG;EAAI,GAAG;CAAK;CACxB,MAAM;EAAE,GAAG;EAAI,GAAG;CAAK;AACzB;;;;;;;;AA0BA,MAAM,aAAyC;CAC7C;EACE,IAAI;EACJ,MAAM;EACN,KAAK;EACL,MAAM;EACN,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,KAAK;EACL,MAAM;EACN,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,KAAK;EACL,MAAM;EACN,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,KAAK;EACL,MAAM;EACN,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,KAAK;EACL,MAAM;EACN,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,KAAK;EACL,MAAM;EACN,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,KAAK;EACL,MAAM;EACN,aAAa;CACf;CACA;EACE,IAAI;EACJ,MAAM;EACN,KAAK;EACL,MAAM;EACN,aAAa;EACb,QAAQ;EACR,YAAY;CACd;AACF;;;;;;;AAQA,MAAa,mBAAmB;AA8EhC,MAAM,SAAS,GAAW,GAAW,QAAgB,SAAS,EAAE,IAAI,EAAE,GAAG,IAAI;;;;;AA+B7E,MAAM,gBAAgB,KAAa,WACjC,WAAW,UAAU,MAAM,MAAM,MAAO,GAAG,IAAI,MAAM,IAAI,KAAM,GAAG;;;;;AAMpE,SAAgB,gBACd,KACA,OAAkD,cAC/B;CACnB,OAAO;EACL,GAAG;EACH,OAAO;GACL,SAAS,MAAM,KAAK,MAAM,GAAG,IAAI,UAAU,KAAK,MAAM,GAAG,IAAI,GAAG;GAChE,WAAW,aAAa,IAAI,KAAK,OAAO;EAC1C;EACA,MAAM;GACJ,SAAS,MAAM,KAAK,KAAK,GAAG,IAAI,cAAc,KAAK,KAAK,GAAG,IAAI,GAAG;GAClE,WAAW,aAAa,IAAI,KAAK,MAAM;EACzC;CACF;AACF;;AAGA,MAAa,oBAAkD,WAAW,KAAK,QAC7E,gBAAgB,GAAG,CACrB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { TooltipProps } from "@novi-ui/core";
|
|
2
|
+
//#region src/tooltip/tooltip.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* 要素の補足説明。ホバーとフォーカスの両方で開く。
|
|
5
|
+
*
|
|
6
|
+
* Flatlay で**唯一浮くもの**なので、`placement` / `offset` は他テーマ同様に効く
|
|
7
|
+
* (Popover / Menu / Select では受け取るだけで効かない)。
|
|
8
|
+
*
|
|
9
|
+
* ツールチップだけに情報を置かないこと。触れないと読めないため、
|
|
10
|
+
* 操作に必須の情報は本文かラベルに書く。
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* <Tooltip content="コピーする">
|
|
14
|
+
* <Button>複製</Button>
|
|
15
|
+
* </Tooltip>
|
|
16
|
+
*/
|
|
17
|
+
declare function Tooltip({ content, placement, offset, delay, isOpen, defaultOpen, onOpenChange, isDisabled, children, className, classNames, id }: TooltipProps): import("react").JSX.Element;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { Tooltip };
|
|
20
|
+
//# sourceMappingURL=tooltip.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tooltip.d.mts","names":[],"sources":["../../src/tooltip/tooltip.tsx"],"mappings":";;;;;;;;;;;;;;;;iBAoBgB,UACd,SACA,WACA,QACA,OACA,QACA,aACA,cACA,YACA,UACA,WACA,YACA,MACC,+BAAY,IAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { tooltipStyles } from "./tooltip.styles.mjs";
|
|
3
|
+
import { Tooltip, TooltipTrigger } from "react-aria-components";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/tooltip/tooltip.tsx
|
|
6
|
+
/**
|
|
7
|
+
* 要素の補足説明。ホバーとフォーカスの両方で開く。
|
|
8
|
+
*
|
|
9
|
+
* Flatlay で**唯一浮くもの**なので、`placement` / `offset` は他テーマ同様に効く
|
|
10
|
+
* (Popover / Menu / Select では受け取るだけで効かない)。
|
|
11
|
+
*
|
|
12
|
+
* ツールチップだけに情報を置かないこと。触れないと読めないため、
|
|
13
|
+
* 操作に必須の情報は本文かラベルに書く。
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* <Tooltip content="コピーする">
|
|
17
|
+
* <Button>複製</Button>
|
|
18
|
+
* </Tooltip>
|
|
19
|
+
*/
|
|
20
|
+
function Tooltip$1({ content, placement = "top", offset = 6, delay = 400, isOpen, defaultOpen, onOpenChange, isDisabled, children, className, classNames, id }) {
|
|
21
|
+
const s = tooltipStyles();
|
|
22
|
+
return /* @__PURE__ */ jsxs(TooltipTrigger, {
|
|
23
|
+
isOpen,
|
|
24
|
+
defaultOpen,
|
|
25
|
+
onOpenChange,
|
|
26
|
+
isDisabled,
|
|
27
|
+
delay,
|
|
28
|
+
children: [children, /* @__PURE__ */ jsx(Tooltip, {
|
|
29
|
+
placement,
|
|
30
|
+
offset,
|
|
31
|
+
"data-slot": "root",
|
|
32
|
+
className: s.root({ class: [className, classNames?.root] }),
|
|
33
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
34
|
+
id,
|
|
35
|
+
"data-slot": "content",
|
|
36
|
+
className: s.content({ class: classNames?.content }),
|
|
37
|
+
children: content
|
|
38
|
+
})
|
|
39
|
+
})]
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { Tooltip$1 as Tooltip };
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=tooltip.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tooltip.mjs","names":["Tooltip","RACTooltip"],"sources":["../../src/tooltip/tooltip.tsx"],"sourcesContent":["'use client'\n\nimport type { TooltipProps } from '@novi-ui/core'\nimport { Tooltip as RACTooltip, TooltipTrigger } from 'react-aria-components'\nimport { tooltipStyles } from './tooltip.styles'\n\n/**\n * 要素の補足説明。ホバーとフォーカスの両方で開く。\n *\n * Flatlay で**唯一浮くもの**なので、`placement` / `offset` は他テーマ同様に効く\n * (Popover / Menu / Select では受け取るだけで効かない)。\n *\n * ツールチップだけに情報を置かないこと。触れないと読めないため、\n * 操作に必須の情報は本文かラベルに書く。\n *\n * @example\n * <Tooltip content=\"コピーする\">\n * <Button>複製</Button>\n * </Tooltip>\n */\nexport function Tooltip({\n content,\n placement = 'top',\n offset = 6,\n delay = 400,\n isOpen,\n defaultOpen,\n onOpenChange,\n isDisabled,\n children,\n className,\n classNames,\n id,\n}: TooltipProps) {\n const s = tooltipStyles()\n\n return (\n <TooltipTrigger\n isOpen={isOpen}\n defaultOpen={defaultOpen}\n onOpenChange={onOpenChange}\n isDisabled={isDisabled}\n delay={delay}\n >\n {children}\n <RACTooltip\n placement={placement}\n offset={offset}\n data-slot=\"root\"\n className={s.root({ class: [className, classNames?.root] })}\n >\n {/* RAC の Tooltip は id を受け取らないため中身に付ける */}\n <span id={id} data-slot=\"content\" className={s.content({ class: classNames?.content })}>\n {content}\n </span>\n </RACTooltip>\n </TooltipTrigger>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoBA,SAAgBA,UAAQ,EACtB,SACA,YAAY,OACZ,SAAS,GACT,QAAQ,KACR,QACA,aACA,cACA,YACA,UACA,WACA,YACA,MACe;CACf,MAAM,IAAI,cAAc;CAExB,OACE,qBAAC,gBAAD;EACU;EACK;EACC;EACF;EACL;EALT,UAAA,CAOG,UACD,oBAACC,SAAD;GACa;GACH;GACR,aAAU;GACV,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,YAAY,IAAI,EAAE,CAAC;GAG1D,UAAA,oBAAC,QAAD;IAAU;IAAI,aAAU;IAAU,WAAW,EAAE,QAAQ,EAAE,OAAO,YAAY,QAAQ,CAAC;IAClF,UAAA;GACG,CAAA;EACI,CAAA,CACE;;AAEpB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//#region src/tooltip/tooltip.styles.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Tooltip のスタイル定義。
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* const myTooltip = tv({ extend: tooltipStyles, slots: { content: 'px-3' } })
|
|
7
|
+
*/
|
|
8
|
+
declare const tooltipStyles: import("tailwind-variants").TVReturnType<{
|
|
9
|
+
[key: string]: {
|
|
10
|
+
[key: string]: import("tailwind-variants").ClassValue | {
|
|
11
|
+
root?: import("tailwind-variants").ClassValue;
|
|
12
|
+
arrow?: import("tailwind-variants").ClassValue;
|
|
13
|
+
content?: import("tailwind-variants").ClassValue;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
} | {
|
|
17
|
+
[x: string]: {
|
|
18
|
+
[x: string]: import("tailwind-variants").ClassValue | {
|
|
19
|
+
root?: import("tailwind-variants").ClassValue;
|
|
20
|
+
arrow?: import("tailwind-variants").ClassValue;
|
|
21
|
+
content?: import("tailwind-variants").ClassValue;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
} | {}, {
|
|
25
|
+
root: string;
|
|
26
|
+
arrow: string;
|
|
27
|
+
content: string;
|
|
28
|
+
}, undefined, {
|
|
29
|
+
[key: string]: {
|
|
30
|
+
[key: string]: import("tailwind-variants").ClassValue | {
|
|
31
|
+
root?: import("tailwind-variants").ClassValue;
|
|
32
|
+
arrow?: import("tailwind-variants").ClassValue;
|
|
33
|
+
content?: import("tailwind-variants").ClassValue;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
} | {}, {
|
|
37
|
+
root: string;
|
|
38
|
+
arrow: string;
|
|
39
|
+
content: string;
|
|
40
|
+
}, import("tailwind-variants").TVReturnTypeLike<unknown, {
|
|
41
|
+
root: string;
|
|
42
|
+
arrow: string;
|
|
43
|
+
content: string;
|
|
44
|
+
}>>;
|
|
45
|
+
type TooltipStyleProps = Parameters<typeof tooltipStyles>[0];
|
|
46
|
+
//#endregion
|
|
47
|
+
export { TooltipStyleProps, tooltipStyles };
|
|
48
|
+
//# sourceMappingURL=tooltip.styles.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tooltip.styles.d.mts","names":[],"sources":["../../src/tooltip/tooltip.styles.ts"],"mappings":";;;;;;;cAqCa,2CAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAEd,oBAAoB,kBAAkB"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { mono } from "../styles/mono.mjs";
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
//#region src/tooltip/tooltip.styles.ts
|
|
4
|
+
/**
|
|
5
|
+
* Tooltip は Flatlay で**唯一浮くもの**(ADR-F6・`position` の例外2号)。
|
|
6
|
+
*
|
|
7
|
+
* 他のすべては開くと場所を取るが、ポインタ追従の一時表示だけはフローに入れられない。
|
|
8
|
+
* 入れた瞬間にレイアウトが動き、ポインタがトリガーから外れて即座に閉じる
|
|
9
|
+
* (出た瞬間に消えるものは補足として成立しない)。
|
|
10
|
+
* 配置は上流(`useOverlayPosition`)がインラインで書くので、ここでは打ち消さない。
|
|
11
|
+
*
|
|
12
|
+
* 浮くことを認めた代わりに、**紙の上の面には見せない**。地と文字を反転した
|
|
13
|
+
* インクの札にして、書類の一部ではなく「一時的に当てた付箋」として読ませる。
|
|
14
|
+
* 影は使わない。浮いていることは反転色と重なりの事実が示す。
|
|
15
|
+
*
|
|
16
|
+
* 例外は Modal(テイクオーバー)とここの2つで凍結してある(NG1)。
|
|
17
|
+
* 3つ目を足すときは「z 軸を持たない」という主張そのものを見直すことになる。
|
|
18
|
+
*/
|
|
19
|
+
const slots = {
|
|
20
|
+
root: [
|
|
21
|
+
"outline-none max-w-xs",
|
|
22
|
+
"bg-[var(--novi-color-fg)] text-[var(--novi-color-bg)]",
|
|
23
|
+
"border border-transparent",
|
|
24
|
+
"rounded-[var(--novi-radius-sm)]"
|
|
25
|
+
].join(" "),
|
|
26
|
+
arrow: "hidden",
|
|
27
|
+
content: `px-2 py-1 text-[length:var(--novi-text-xs)] leading-snug ${mono}`
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Tooltip のスタイル定義。
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const myTooltip = tv({ extend: tooltipStyles, slots: { content: 'px-3' } })
|
|
34
|
+
*/
|
|
35
|
+
const tooltipStyles = tv({ slots });
|
|
36
|
+
//#endregion
|
|
37
|
+
export { tooltipStyles };
|
|
38
|
+
|
|
39
|
+
//# sourceMappingURL=tooltip.styles.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tooltip.styles.mjs","names":[],"sources":["../../src/tooltip/tooltip.styles.ts"],"sourcesContent":["import type { SlotMap, tooltipRequiredSlots, tooltipSlots } from '@novi-ui/core'\nimport { tv } from 'tailwind-variants'\nimport { mono } from '../styles/mono'\n\n/**\n * Tooltip は Flatlay で**唯一浮くもの**(ADR-F6・`position` の例外2号)。\n *\n * 他のすべては開くと場所を取るが、ポインタ追従の一時表示だけはフローに入れられない。\n * 入れた瞬間にレイアウトが動き、ポインタがトリガーから外れて即座に閉じる\n * (出た瞬間に消えるものは補足として成立しない)。\n * 配置は上流(`useOverlayPosition`)がインラインで書くので、ここでは打ち消さない。\n *\n * 浮くことを認めた代わりに、**紙の上の面には見せない**。地と文字を反転した\n * インクの札にして、書類の一部ではなく「一時的に当てた付箋」として読ませる。\n * 影は使わない。浮いていることは反転色と重なりの事実が示す。\n *\n * 例外は Modal(テイクオーバー)とここの2つで凍結してある(NG1)。\n * 3つ目を足すときは「z 軸を持たない」という主張そのものを見直すことになる。\n */\nconst slots = {\n root: [\n 'outline-none max-w-xs',\n 'bg-[var(--novi-color-fg)] text-[var(--novi-color-bg)]',\n 'border border-transparent',\n 'rounded-[var(--novi-radius-sm)]',\n ].join(' '),\n // 矢印は描かない。指す先は重なりの位置が示している\n arrow: 'hidden',\n content: `px-2 py-1 text-[length:var(--novi-text-xs)] leading-snug ${mono}`,\n} satisfies SlotMap<typeof tooltipSlots, (typeof tooltipRequiredSlots)[number]>\n\n/**\n * Tooltip のスタイル定義。\n *\n * @example\n * const myTooltip = tv({ extend: tooltipStyles, slots: { content: 'px-3' } })\n */\nexport const tooltipStyles = tv({ slots })\n\nexport type TooltipStyleProps = Parameters<typeof tooltipStyles>[0]\n"],"mappings":";;;;;;;;;;;;;;;;;;AAmBA,MAAM,QAAQ;CACZ,MAAM;EACJ;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CAEV,OAAO;CACP,SAAS,4DAA4D;AACvE;;;;;;;AAQA,MAAa,gBAAgB,GAAG,EAAE,MAAM,CAAC"}
|