@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,40 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import { SelectProps } from "@novi-ui/core";
|
|
3
|
+
//#region src/select/select.d.ts
|
|
4
|
+
interface SelectItemProps {
|
|
5
|
+
/** 選択値。`onSelectionChange` に渡る */
|
|
6
|
+
id: string;
|
|
7
|
+
isDisabled?: boolean;
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Select の選択肢。`Select` の子として置く。
|
|
13
|
+
*
|
|
14
|
+
* 選択済みの印は行頭の `▸`(両テーマはチェックマーク)。押下の反転と衝突しないよう、
|
|
15
|
+
* 状態は記号で、押した瞬間は面の反転で示すという役割分担にしている。
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* <SelectItem id="tokyo">東京都</SelectItem>
|
|
19
|
+
*/
|
|
20
|
+
declare function SelectItem({ id, isDisabled, children, className }: SelectItemProps): import("react").JSX.Element;
|
|
21
|
+
/**
|
|
22
|
+
* 一覧から1つ選ぶ。**選択肢はトリガーの直後、フローの中に展開される**
|
|
23
|
+
* (Raster は隣に浮き、Tactile は画面下端のシート)。
|
|
24
|
+
*
|
|
25
|
+
* 開くと後続が押し下げられるので、何かが隠れることが無い。
|
|
26
|
+
* 矢印キーで移動、Escape で閉じてトリガーへフォーカスが戻る。
|
|
27
|
+
*
|
|
28
|
+
* トリガーは `<button>` で編集可能要素ではないため IME の変換は発生しない。
|
|
29
|
+
* テキスト入力を伴う選択が必要な場合は ComboBox を使う(MVP の対象外)。
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* <Select label="都道府県" selectedKey={pref} onSelectionChange={setPref}>
|
|
33
|
+
* <SelectItem id="tokyo">東京都</SelectItem>
|
|
34
|
+
* <SelectItem id="osaka">大阪府</SelectItem>
|
|
35
|
+
* </Select>
|
|
36
|
+
*/
|
|
37
|
+
declare function Select({ variant, size, radius, label, placeholder, description, errorMessage, name, selectedKey, defaultSelectedKey, onSelectionChange, isOpen, defaultOpen, onOpenChange, isDisabled, isRequired, isInvalid, children, className, classNames, id }: SelectProps): import("react").JSX.Element;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { Select, SelectItem, SelectItemProps };
|
|
40
|
+
//# sourceMappingURL=select.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.d.mts","names":[],"sources":["../../src/select/select.tsx"],"mappings":";;;UAiBiB;;EAEf;EACA;EACA,WAAW;EACX;;;;;;;;;;;iBAYc,aAAa,IAAI,YAAY,UAAU,aAAa,kCAAe,IAAA;;;;;;;;;;;;;;;;;iBAqCnE,SACd,SACA,MACA,QACA,OACA,aACA,aACA,cACA,MACA,aACA,oBACA,mBACA,QACA,aACA,cACA,YACA,YACA,WACA,UACA,WACA,YACA,MACC,8BAAW,IAAA"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { InflowPopover } from "../styles/inflow.mjs";
|
|
3
|
+
import { optionMarkerClass, selectStyles } from "./select.styles.mjs";
|
|
4
|
+
import { Button, FieldError, Label, ListBox, ListBoxItem, Select, SelectValue, Text } from "react-aria-components";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
//#region src/select/select.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Select の選択肢。`Select` の子として置く。
|
|
9
|
+
*
|
|
10
|
+
* 選択済みの印は行頭の `▸`(両テーマはチェックマーク)。押下の反転と衝突しないよう、
|
|
11
|
+
* 状態は記号で、押した瞬間は面の反転で示すという役割分担にしている。
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* <SelectItem id="tokyo">東京都</SelectItem>
|
|
15
|
+
*/
|
|
16
|
+
function SelectItem({ id, isDisabled, children, className }) {
|
|
17
|
+
return /* @__PURE__ */ jsx(ListBoxItem, {
|
|
18
|
+
id,
|
|
19
|
+
isDisabled,
|
|
20
|
+
textValue: typeof children === "string" ? children : void 0,
|
|
21
|
+
"data-slot": "option",
|
|
22
|
+
className: className ?? selectStyles().option(),
|
|
23
|
+
children: ({ isSelected }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
|
|
24
|
+
"aria-hidden": "true",
|
|
25
|
+
className: optionMarkerClass,
|
|
26
|
+
children: isSelected ? "▸" : ""
|
|
27
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
28
|
+
className: "truncate",
|
|
29
|
+
children
|
|
30
|
+
})] })
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 一覧から1つ選ぶ。**選択肢はトリガーの直後、フローの中に展開される**
|
|
35
|
+
* (Raster は隣に浮き、Tactile は画面下端のシート)。
|
|
36
|
+
*
|
|
37
|
+
* 開くと後続が押し下げられるので、何かが隠れることが無い。
|
|
38
|
+
* 矢印キーで移動、Escape で閉じてトリガーへフォーカスが戻る。
|
|
39
|
+
*
|
|
40
|
+
* トリガーは `<button>` で編集可能要素ではないため IME の変換は発生しない。
|
|
41
|
+
* テキスト入力を伴う選択が必要な場合は ComboBox を使う(MVP の対象外)。
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* <Select label="都道府県" selectedKey={pref} onSelectionChange={setPref}>
|
|
45
|
+
* <SelectItem id="tokyo">東京都</SelectItem>
|
|
46
|
+
* <SelectItem id="osaka">大阪府</SelectItem>
|
|
47
|
+
* </Select>
|
|
48
|
+
*/
|
|
49
|
+
function Select$1({ variant, size, radius, label, placeholder = "選択してください", description, errorMessage, name, selectedKey, defaultSelectedKey, onSelectionChange, isOpen, defaultOpen, onOpenChange, isDisabled, isRequired, isInvalid, children, className, classNames, id }) {
|
|
50
|
+
const s = selectStyles({
|
|
51
|
+
variant,
|
|
52
|
+
size,
|
|
53
|
+
radius
|
|
54
|
+
});
|
|
55
|
+
return /* @__PURE__ */ jsxs(Select, {
|
|
56
|
+
id,
|
|
57
|
+
name,
|
|
58
|
+
selectedKey,
|
|
59
|
+
defaultSelectedKey,
|
|
60
|
+
onSelectionChange: (key) => onSelectionChange?.(key === null ? null : String(key)),
|
|
61
|
+
isOpen,
|
|
62
|
+
defaultOpen,
|
|
63
|
+
onOpenChange,
|
|
64
|
+
isDisabled,
|
|
65
|
+
isRequired,
|
|
66
|
+
isInvalid,
|
|
67
|
+
placeholder,
|
|
68
|
+
"data-slot": "root",
|
|
69
|
+
className: `group ${s.root({ class: [className, classNames?.root] })}`,
|
|
70
|
+
children: [
|
|
71
|
+
label !== void 0 && /* @__PURE__ */ jsx(Label, {
|
|
72
|
+
"data-slot": "label",
|
|
73
|
+
className: s.label({ class: classNames?.label }),
|
|
74
|
+
children: label
|
|
75
|
+
}),
|
|
76
|
+
/* @__PURE__ */ jsxs(Button, {
|
|
77
|
+
"data-slot": "trigger",
|
|
78
|
+
className: s.trigger({ class: classNames?.trigger }),
|
|
79
|
+
children: [/* @__PURE__ */ jsx(SelectValue, {
|
|
80
|
+
"data-slot": "value",
|
|
81
|
+
className: s.value({ class: classNames?.value })
|
|
82
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
83
|
+
"aria-hidden": "true",
|
|
84
|
+
"data-slot": "icon",
|
|
85
|
+
className: s.icon({ class: classNames?.icon }),
|
|
86
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
87
|
+
className: "group-data-[open]:hidden",
|
|
88
|
+
children: "▾"
|
|
89
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
90
|
+
className: "hidden group-data-[open]:inline",
|
|
91
|
+
children: "▴"
|
|
92
|
+
})]
|
|
93
|
+
})]
|
|
94
|
+
}),
|
|
95
|
+
/* @__PURE__ */ jsx(InflowPopover, {
|
|
96
|
+
dataSlot: "popover",
|
|
97
|
+
className: s.popover({ class: classNames?.popover }),
|
|
98
|
+
children: /* @__PURE__ */ jsx(ListBox, {
|
|
99
|
+
"data-slot": "listbox",
|
|
100
|
+
className: s.listbox({ class: classNames?.listbox }),
|
|
101
|
+
children
|
|
102
|
+
})
|
|
103
|
+
}),
|
|
104
|
+
description !== void 0 && /* @__PURE__ */ jsx(Text, {
|
|
105
|
+
slot: "description",
|
|
106
|
+
"data-slot": "description",
|
|
107
|
+
className: s.description({ class: classNames?.description }),
|
|
108
|
+
children: description
|
|
109
|
+
}),
|
|
110
|
+
/* @__PURE__ */ jsx(FieldError, {
|
|
111
|
+
"data-slot": "errorMessage",
|
|
112
|
+
className: s.errorMessage({ class: classNames?.errorMessage }),
|
|
113
|
+
children: errorMessage
|
|
114
|
+
})
|
|
115
|
+
]
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
export { Select$1 as Select, SelectItem };
|
|
120
|
+
|
|
121
|
+
//# sourceMappingURL=select.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.mjs","names":["Select","RACSelect"],"sources":["../../src/select/select.tsx"],"sourcesContent":["'use client'\n\nimport type { SelectProps } from '@novi-ui/core'\nimport type { ReactNode } from 'react'\nimport {\n Button,\n FieldError,\n Label,\n ListBox,\n ListBoxItem,\n Select as RACSelect,\n SelectValue,\n Text,\n} from 'react-aria-components'\nimport { InflowPopover } from '../styles/inflow'\nimport { optionMarkerClass, selectStyles } from './select.styles'\n\nexport interface SelectItemProps {\n /** 選択値。`onSelectionChange` に渡る */\n id: string\n isDisabled?: boolean\n children?: ReactNode\n className?: string\n}\n\n/**\n * Select の選択肢。`Select` の子として置く。\n *\n * 選択済みの印は行頭の `▸`(両テーマはチェックマーク)。押下の反転と衝突しないよう、\n * 状態は記号で、押した瞬間は面の反転で示すという役割分担にしている。\n *\n * @example\n * <SelectItem id=\"tokyo\">東京都</SelectItem>\n */\nexport function SelectItem({ id, isDisabled, children, className }: SelectItemProps) {\n return (\n <ListBoxItem\n id={id}\n isDisabled={isDisabled}\n textValue={typeof children === 'string' ? children : undefined}\n data-slot=\"option\"\n className={className ?? selectStyles().option()}\n >\n {({ isSelected }) => (\n <>\n <span aria-hidden=\"true\" className={optionMarkerClass}>\n {isSelected ? '▸' : ''}\n </span>\n <span className=\"truncate\">{children}</span>\n </>\n )}\n </ListBoxItem>\n )\n}\n\n/**\n * 一覧から1つ選ぶ。**選択肢はトリガーの直後、フローの中に展開される**\n * (Raster は隣に浮き、Tactile は画面下端のシート)。\n *\n * 開くと後続が押し下げられるので、何かが隠れることが無い。\n * 矢印キーで移動、Escape で閉じてトリガーへフォーカスが戻る。\n *\n * トリガーは `<button>` で編集可能要素ではないため IME の変換は発生しない。\n * テキスト入力を伴う選択が必要な場合は ComboBox を使う(MVP の対象外)。\n *\n * @example\n * <Select label=\"都道府県\" selectedKey={pref} onSelectionChange={setPref}>\n * <SelectItem id=\"tokyo\">東京都</SelectItem>\n * <SelectItem id=\"osaka\">大阪府</SelectItem>\n * </Select>\n */\nexport function Select({\n variant,\n size,\n radius,\n label,\n placeholder = '選択してください',\n description,\n errorMessage,\n name,\n selectedKey,\n defaultSelectedKey,\n onSelectionChange,\n isOpen,\n defaultOpen,\n onOpenChange,\n isDisabled,\n isRequired,\n isInvalid,\n children,\n className,\n classNames,\n id,\n}: SelectProps) {\n const s = selectStyles({ variant, size, radius })\n\n return (\n <RACSelect\n id={id}\n name={name}\n selectedKey={selectedKey}\n defaultSelectedKey={defaultSelectedKey}\n onSelectionChange={(key) => onSelectionChange?.(key === null ? null : String(key))}\n isOpen={isOpen}\n defaultOpen={defaultOpen}\n onOpenChange={onOpenChange}\n isDisabled={isDisabled}\n isRequired={isRequired}\n isInvalid={isInvalid}\n placeholder={placeholder}\n data-slot=\"root\"\n // trigger 側から invalid / open を参照するために group を付ける\n className={`group ${s.root({ class: [className, classNames?.root] })}`}\n >\n {label !== undefined && (\n <Label data-slot=\"label\" className={s.label({ class: classNames?.label })}>\n {label}\n </Label>\n )}\n\n <Button data-slot=\"trigger\" className={s.trigger({ class: classNames?.trigger })}>\n <SelectValue data-slot=\"value\" className={s.value({ class: classNames?.value })} />\n <span aria-hidden=\"true\" data-slot=\"icon\" className={s.icon({ class: classNames?.icon })}>\n {/* 回さずに差し替える。開いている間だけ字が反転する */}\n <span className=\"group-data-[open]:hidden\">▾</span>\n <span className=\"hidden group-data-[open]:inline\">▴</span>\n </span>\n </Button>\n\n {/* 展開部はトリガーの直後。ここに面が生えることで、description 以降が押し下がる */}\n <InflowPopover dataSlot=\"popover\" className={s.popover({ class: classNames?.popover })}>\n <ListBox data-slot=\"listbox\" className={s.listbox({ class: classNames?.listbox })}>\n {children}\n </ListBox>\n </InflowPopover>\n\n {description !== undefined && (\n <Text\n slot=\"description\"\n data-slot=\"description\"\n className={s.description({ class: classNames?.description })}\n >\n {description}\n </Text>\n )}\n\n <FieldError\n data-slot=\"errorMessage\"\n className={s.errorMessage({ class: classNames?.errorMessage })}\n >\n {errorMessage}\n </FieldError>\n </RACSelect>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;AAkCA,SAAgB,WAAW,EAAE,IAAI,YAAY,UAAU,aAA8B;CACnF,OACE,oBAAC,aAAD;EACM;EACQ;EACZ,WAAW,OAAO,aAAa,WAAW,WAAW,KAAA;EACrD,aAAU;EACV,WAAW,aAAa,aAAa,CAAC,CAAC,OAAO;EAE5C,WAAA,EAAE,iBACF,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,QAAD;GAAM,eAAY;GAAO,WAAW;GACjC,UAAA,aAAa,MAAM;EAChB,CAAA,GACN,oBAAC,QAAD;GAAM,WAAU;GAAY;EAAe,CAAA,CAC3C,EAAA,CAAA;CAEO,CAAA;AAEjB;;;;;;;;;;;;;;;;;AAkBA,SAAgBA,SAAO,EACrB,SACA,MACA,QACA,OACA,cAAc,YACd,aACA,cACA,MACA,aACA,oBACA,mBACA,QACA,aACA,cACA,YACA,YACA,WACA,UACA,WACA,YACA,MACc;CACd,MAAM,IAAI,aAAa;EAAE;EAAS;EAAM;CAAO,CAAC;CAEhD,OACE,qBAACC,QAAD;EACM;EACE;EACO;EACO;EACpB,oBAAoB,QAAQ,oBAAoB,QAAQ,OAAO,OAAO,OAAO,GAAG,CAAC;EACzE;EACK;EACC;EACF;EACA;EACD;EACE;EACb,aAAU;EAEV,WAAW,SAAS,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,YAAY,IAAI,EAAE,CAAC;EAfrE,UAAA;GAiBG,UAAU,KAAA,KACT,oBAAC,OAAD;IAAO,aAAU;IAAQ,WAAW,EAAE,MAAM,EAAE,OAAO,YAAY,MAAM,CAAC;IACrE,UAAA;GACI,CAAA;GAGT,qBAAC,QAAD;IAAQ,aAAU;IAAU,WAAW,EAAE,QAAQ,EAAE,OAAO,YAAY,QAAQ,CAAC;IAA/E,UAAA,CACE,oBAAC,aAAD;KAAa,aAAU;KAAQ,WAAW,EAAE,MAAM,EAAE,OAAO,YAAY,MAAM,CAAC;IAAI,CAAA,GAClF,qBAAC,QAAD;KAAM,eAAY;KAAO,aAAU;KAAO,WAAW,EAAE,KAAK,EAAE,OAAO,YAAY,KAAK,CAAC;KAAvF,UAAA,CAEE,oBAAC,QAAD;MAAM,WAAU;MAA2B,UAAA;KAAO,CAAA,GAClD,oBAAC,QAAD;MAAM,WAAU;MAAkC,UAAA;KAAO,CAAA,CACrD;IACA,CAAA,CAAA;;GAGR,oBAAC,eAAD;IAAe,UAAS;IAAU,WAAW,EAAE,QAAQ,EAAE,OAAO,YAAY,QAAQ,CAAC;IACnF,UAAA,oBAAC,SAAD;KAAS,aAAU;KAAU,WAAW,EAAE,QAAQ,EAAE,OAAO,YAAY,QAAQ,CAAC;KAC7E;IACM,CAAA;GACI,CAAA;GAEd,gBAAgB,KAAA,KACf,oBAAC,MAAD;IACE,MAAK;IACL,aAAU;IACV,WAAW,EAAE,YAAY,EAAE,OAAO,YAAY,YAAY,CAAC;IAE1D,UAAA;GACG,CAAA;GAGR,oBAAC,YAAD;IACE,aAAU;IACV,WAAW,EAAE,aAAa,EAAE,OAAO,YAAY,aAAa,CAAC;IAE5D,UAAA;GACS,CAAA;EACH;;AAEf"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { VariantMap } from "@novi-ui/core";
|
|
2
|
+
//#region src/select/select.styles.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Select のスタイル定義。
|
|
5
|
+
*
|
|
6
|
+
* 展開部の位置は `InflowPopover` が `!` 付きのリセットで固定するので、
|
|
7
|
+
* ここで `position` 系を書いても効かない(書く必要も無い)。
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* import { selectStyles } from '@novi-ui/flatlay'
|
|
11
|
+
* import { tv } from 'tailwind-variants'
|
|
12
|
+
*
|
|
13
|
+
* const mySelect = tv({ extend: selectStyles, slots: { option: 'px-4' } })
|
|
14
|
+
*/
|
|
15
|
+
declare const selectStyles: import("tailwind-variants").TVReturnType<{
|
|
16
|
+
size: VariantMap<"sm" | "md" | "lg", {
|
|
17
|
+
trigger: string;
|
|
18
|
+
option: string;
|
|
19
|
+
}>;
|
|
20
|
+
radius: VariantMap<"sm" | "md" | "lg" | "none" | "full", {
|
|
21
|
+
trigger: string;
|
|
22
|
+
}>;
|
|
23
|
+
variant: VariantMap<"solid" | "outline" | "soft" | "ghost" | "plain", {
|
|
24
|
+
trigger: string;
|
|
25
|
+
}>;
|
|
26
|
+
}, {
|
|
27
|
+
root: string;
|
|
28
|
+
label: string;
|
|
29
|
+
trigger: string;
|
|
30
|
+
value: string;
|
|
31
|
+
icon: string;
|
|
32
|
+
popover: string;
|
|
33
|
+
listbox: string;
|
|
34
|
+
option: string;
|
|
35
|
+
description: string;
|
|
36
|
+
errorMessage: string;
|
|
37
|
+
}, undefined, {
|
|
38
|
+
size: VariantMap<"sm" | "md" | "lg", {
|
|
39
|
+
trigger: string;
|
|
40
|
+
option: string;
|
|
41
|
+
}>;
|
|
42
|
+
radius: VariantMap<"sm" | "md" | "lg" | "none" | "full", {
|
|
43
|
+
trigger: string;
|
|
44
|
+
}>;
|
|
45
|
+
variant: VariantMap<"solid" | "outline" | "soft" | "ghost" | "plain", {
|
|
46
|
+
trigger: string;
|
|
47
|
+
}>;
|
|
48
|
+
}, {
|
|
49
|
+
root: string;
|
|
50
|
+
label: string;
|
|
51
|
+
trigger: string;
|
|
52
|
+
value: string;
|
|
53
|
+
icon: string;
|
|
54
|
+
popover: string;
|
|
55
|
+
listbox: string;
|
|
56
|
+
option: string;
|
|
57
|
+
description: string;
|
|
58
|
+
errorMessage: string;
|
|
59
|
+
}, import("tailwind-variants").TVReturnTypeLike<{
|
|
60
|
+
size: VariantMap<"sm" | "md" | "lg", {
|
|
61
|
+
trigger: string;
|
|
62
|
+
option: string;
|
|
63
|
+
}>;
|
|
64
|
+
radius: VariantMap<"sm" | "md" | "lg" | "none" | "full", {
|
|
65
|
+
trigger: string;
|
|
66
|
+
}>;
|
|
67
|
+
variant: VariantMap<"solid" | "outline" | "soft" | "ghost" | "plain", {
|
|
68
|
+
trigger: string;
|
|
69
|
+
}>;
|
|
70
|
+
}, {
|
|
71
|
+
root: string;
|
|
72
|
+
label: string;
|
|
73
|
+
trigger: string;
|
|
74
|
+
value: string;
|
|
75
|
+
icon: string;
|
|
76
|
+
popover: string;
|
|
77
|
+
listbox: string;
|
|
78
|
+
option: string;
|
|
79
|
+
description: string;
|
|
80
|
+
errorMessage: string;
|
|
81
|
+
}>>;
|
|
82
|
+
type SelectStyleProps = Parameters<typeof selectStyles>[0];
|
|
83
|
+
//#endregion
|
|
84
|
+
export { SelectStyleProps, selectStyles };
|
|
85
|
+
//# sourceMappingURL=select.styles.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.styles.d.mts","names":[],"sources":["../../src/select/select.styles.ts"],"mappings":";;;;;;;;;;;;;;cA+Ha,0CAAY;;IAnDmB;IAAgB;;;IAeZ;;;IAYE;;;;;;;;;;;;;;;IA3BN;IAAgB;;;IAeZ;;;IAYE;;;;;;;;;;;;;;;IA3BN;IAAgB;;;IAeZ;;;IAYE;;;;;;;;;;;;;;KA+BtC,mBAAmB,kBAAkB"}
|
|
@@ -0,0 +1,111 @@
|
|
|
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/select/select.styles.ts
|
|
5
|
+
/**
|
|
6
|
+
* Flatlay の Select は **インフロー押し下げ**(design.md 着手条件2)。
|
|
7
|
+
*
|
|
8
|
+
* Raster はトリガーの隣に浮き、Tactile は画面下端のシートで出る。Flatlay には
|
|
9
|
+
* 浮かせる先が無いので、**展開部はフローの中に生えて後続を押し下げる**。
|
|
10
|
+
* 配置そのものは `styles/inflow.tsx` が担い、ここは面の見た目だけを決める。
|
|
11
|
+
*
|
|
12
|
+
* 影が使えない以上、展開面が「面である」ことを示せるのは罫線だけ。
|
|
13
|
+
* 全 slot が幅のある線を持ち、行の切れ目も線で示す。
|
|
14
|
+
*/
|
|
15
|
+
const slots = {
|
|
16
|
+
root: ["flex flex-col gap-1.5", "[&>[data-novi-inflow]:empty]:hidden"].join(" "),
|
|
17
|
+
label: "text-[length:var(--novi-text-sm)] font-medium text-[var(--novi-color-fg)]",
|
|
18
|
+
trigger: [
|
|
19
|
+
"flex items-center justify-between gap-2 w-full text-left",
|
|
20
|
+
"text-[var(--novi-color-fg)]",
|
|
21
|
+
"border",
|
|
22
|
+
"rounded-[var(--novi-radius-sm)]",
|
|
23
|
+
"data-[pressed]:bg-[var(--novi-color-fg)] data-[pressed]:text-[var(--novi-color-bg)]",
|
|
24
|
+
"group-data-[invalid]:border-[var(--novi-color-danger)]",
|
|
25
|
+
"transition-[background-color,border-color,color]",
|
|
26
|
+
"duration-[var(--novi-duration-fast)] ease-[var(--novi-ease-standard)]",
|
|
27
|
+
focusRing,
|
|
28
|
+
disabledState
|
|
29
|
+
].join(" "),
|
|
30
|
+
value: "truncate data-[placeholder]:text-[var(--novi-color-muted)]",
|
|
31
|
+
icon: `shrink-0 leading-none text-[var(--novi-color-muted)] ${mono}`,
|
|
32
|
+
popover: [
|
|
33
|
+
"border border-[var(--novi-color-border-strong)]",
|
|
34
|
+
"bg-[var(--novi-color-bg)] text-[var(--novi-color-fg)]",
|
|
35
|
+
"rounded-[var(--novi-radius-sm)]",
|
|
36
|
+
"overflow-hidden"
|
|
37
|
+
].join(" "),
|
|
38
|
+
listbox: "outline-none flex flex-col divide-y divide-[var(--novi-color-border)]",
|
|
39
|
+
option: [
|
|
40
|
+
"flex items-center gap-2 px-2 cursor-pointer outline-none",
|
|
41
|
+
"text-[var(--novi-color-fg)]",
|
|
42
|
+
"data-[focused]:bg-[var(--novi-color-subtle)]",
|
|
43
|
+
"data-[selected]:font-medium",
|
|
44
|
+
"transition-[background-color,color]",
|
|
45
|
+
"duration-[var(--novi-duration-fast)] ease-[var(--novi-ease-standard)]",
|
|
46
|
+
disabledState
|
|
47
|
+
].join(" "),
|
|
48
|
+
description: "text-[length:var(--novi-text-sm)] text-[var(--novi-color-muted)]",
|
|
49
|
+
errorMessage: "text-[length:var(--novi-text-sm)] text-[var(--novi-color-danger)]"
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Select のスタイル定義。
|
|
53
|
+
*
|
|
54
|
+
* 展開部の位置は `InflowPopover` が `!` 付きのリセットで固定するので、
|
|
55
|
+
* ここで `position` 系を書いても効かない(書く必要も無い)。
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* import { selectStyles } from '@novi-ui/flatlay'
|
|
59
|
+
* import { tv } from 'tailwind-variants'
|
|
60
|
+
*
|
|
61
|
+
* const mySelect = tv({ extend: selectStyles, slots: { option: 'px-4' } })
|
|
62
|
+
*/
|
|
63
|
+
const selectStyles = tv({
|
|
64
|
+
slots,
|
|
65
|
+
variants: {
|
|
66
|
+
size: {
|
|
67
|
+
sm: {
|
|
68
|
+
trigger: "h-7 px-2.5 text-[length:var(--novi-text-sm)]",
|
|
69
|
+
option: "h-6 text-[length:var(--novi-text-sm)]"
|
|
70
|
+
},
|
|
71
|
+
md: {
|
|
72
|
+
trigger: "h-8 px-3 text-[length:var(--novi-text-base)]",
|
|
73
|
+
option: "h-7 text-[length:var(--novi-text-base)]"
|
|
74
|
+
},
|
|
75
|
+
lg: {
|
|
76
|
+
trigger: "h-10 px-4 text-[length:var(--novi-text-base)]",
|
|
77
|
+
option: "h-8 text-[length:var(--novi-text-base)]"
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
radius: {
|
|
81
|
+
none: { trigger: "rounded-[var(--novi-radius-none)]" },
|
|
82
|
+
sm: { trigger: "rounded-[var(--novi-radius-sm)]" },
|
|
83
|
+
md: { trigger: "rounded-[var(--novi-radius-md)]" },
|
|
84
|
+
lg: { trigger: "rounded-[var(--novi-radius-lg)]" },
|
|
85
|
+
full: { trigger: "rounded-[var(--novi-radius-full)]" }
|
|
86
|
+
},
|
|
87
|
+
variant: {
|
|
88
|
+
solid: { trigger: "bg-[var(--novi-color-surface)] border-[var(--novi-color-border-strong)]" },
|
|
89
|
+
outline: { trigger: "bg-transparent border-[var(--novi-color-border-strong)]" },
|
|
90
|
+
soft: { trigger: "bg-[var(--novi-color-subtle)] border-[var(--novi-color-border)]" },
|
|
91
|
+
ghost: { trigger: "bg-transparent border-transparent hover:bg-[var(--novi-color-subtle)]" },
|
|
92
|
+
plain: { trigger: "bg-transparent border-transparent px-0 underline underline-offset-4" }
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
defaultVariants: {
|
|
96
|
+
size: "md",
|
|
97
|
+
radius: "sm",
|
|
98
|
+
variant: "solid"
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
/**
|
|
102
|
+
* 選択済みの印が立つ場所。**幅を常に確保する**ので、選ぶ前後で行がずれない。
|
|
103
|
+
*
|
|
104
|
+
* チェックマーク(両テーマ)ではなく帳票のインデックス記号にしているのは、
|
|
105
|
+
* 記号そのものが等幅の列として読めるから。`1ch` は mono の 1 文字ぶん。
|
|
106
|
+
*/
|
|
107
|
+
const optionMarkerClass = `w-[1ch] shrink-0 text-[var(--novi-color-primary)] ${mono}`;
|
|
108
|
+
//#endregion
|
|
109
|
+
export { optionMarkerClass, selectStyles };
|
|
110
|
+
|
|
111
|
+
//# sourceMappingURL=select.styles.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select.styles.mjs","names":[],"sources":["../../src/select/select.styles.ts"],"sourcesContent":["import type {\n NoviRadius,\n NoviSize,\n NoviVariant,\n SlotMap,\n selectRequiredSlots,\n selectSlots,\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 の Select は **インフロー押し下げ**(design.md 着手条件2)。\n *\n * Raster はトリガーの隣に浮き、Tactile は画面下端のシートで出る。Flatlay には\n * 浮かせる先が無いので、**展開部はフローの中に生えて後続を押し下げる**。\n * 配置そのものは `styles/inflow.tsx` が担い、ここは面の見た目だけを決める。\n *\n * 影が使えない以上、展開面が「面である」ことを示せるのは罫線だけ。\n * 全 slot が幅のある線を持ち、行の切れ目も線で示す。\n */\nconst slots = {\n root: [\n 'flex flex-col gap-1.5',\n // 展開部の置き場所(`data-novi-inflow`)は閉じている間も残る。flex の gap は\n // 空の子にも掛かるので、畳まないと閉じたまま余白が 1 つ増える\n '[&>[data-novi-inflow]:empty]:hidden',\n ].join(' '),\n label: 'text-[length:var(--novi-text-sm)] font-medium text-[var(--novi-color-fg)]',\n trigger: [\n 'flex items-center justify-between gap-2 w-full text-left',\n 'text-[var(--novi-color-fg)]',\n // 罫線の幅は全 variant が持つ。色は variant が決める(Button と同じ型)\n 'border',\n 'rounded-[var(--novi-radius-sm)]',\n // 押下は反転。開閉という状態は矢印が持ち、押した瞬間だけを面が返す(ADR-F3)\n 'data-[pressed]:bg-[var(--novi-color-fg)] data-[pressed]:text-[var(--novi-color-bg)]',\n 'group-data-[invalid]:border-[var(--novi-color-danger)]',\n 'transition-[background-color,border-color,color]',\n 'duration-[var(--novi-duration-fast)] ease-[var(--novi-ease-standard)]',\n focusRing,\n disabledState,\n ].join(' '),\n value: 'truncate data-[placeholder]:text-[var(--novi-color-muted)]',\n // 開閉の向きは記号で示す。回すのは z 軸の語彙なので、字を差し替える(FR-11)\n icon: `shrink-0 leading-none text-[var(--novi-color-muted)] ${mono}`,\n popover: [\n // ここが構造差そのもの。浮かないので、面の存在は罫線が引き受ける\n 'border border-[var(--novi-color-border-strong)]',\n 'bg-[var(--novi-color-bg)] text-[var(--novi-color-fg)]',\n 'rounded-[var(--novi-radius-sm)]',\n 'overflow-hidden',\n ].join(' '),\n // 行の切れ目も線。押し下げた面の中で、どこまでが 1 行かを示せるのはこれだけ\n listbox: 'outline-none flex flex-col divide-y divide-[var(--novi-color-border)]',\n option: [\n 'flex items-center gap-2 px-2 cursor-pointer outline-none',\n 'text-[var(--novi-color-fg)]',\n 'data-[focused]:bg-[var(--novi-color-subtle)]',\n 'data-[selected]:font-medium',\n 'transition-[background-color,color]',\n 'duration-[var(--novi-duration-fast)] ease-[var(--novi-ease-standard)]',\n disabledState,\n ].join(' '),\n description: 'text-[length:var(--novi-text-sm)] text-[var(--novi-color-muted)]',\n errorMessage: 'text-[length:var(--novi-text-sm)] text-[var(--novi-color-danger)]',\n} satisfies SlotMap<typeof selectSlots, (typeof selectRequiredSlots)[number]>\n\n/**\n * `size` はトリガーの寸法と行の密度。**どちらも帳票の行**(Tactile は指の下限 48px)。\n *\n * 展開しても 1 行が 28px 前後に収まるので、押し下げ量が読める範囲に留まる。\n * 行を大きくすると、開いた瞬間にページが視界の外まで伸びる。\n */\nconst size: VariantMap<NoviSize, { trigger: string; option: string }> = {\n sm: {\n trigger: 'h-7 px-2.5 text-[length:var(--novi-text-sm)]',\n option: 'h-6 text-[length:var(--novi-text-sm)]',\n },\n md: {\n trigger: 'h-8 px-3 text-[length:var(--novi-text-base)]',\n option: 'h-7 text-[length:var(--novi-text-base)]',\n },\n lg: {\n trigger: 'h-10 px-4 text-[length:var(--novi-text-base)]',\n option: 'h-8 text-[length:var(--novi-text-base)]',\n },\n}\n\nconst radius: VariantMap<NoviRadius, { trigger: string }> = {\n none: { trigger: 'rounded-[var(--novi-radius-none)]' },\n sm: { trigger: 'rounded-[var(--novi-radius-sm)]' },\n md: { trigger: 'rounded-[var(--novi-radius-md)]' },\n lg: { trigger: 'rounded-[var(--novi-radius-lg)]' },\n full: { trigger: 'rounded-[var(--novi-radius-full)]' },\n}\n\n/**\n * トリガーの面の持ち方。Select は `color` を受け取らないので、\n * Button のようなローカル変数は要らず、中立トークンだけで書ける。\n */\nconst variant: VariantMap<NoviVariant, { trigger: string }> = {\n solid: { trigger: 'bg-[var(--novi-color-surface)] border-[var(--novi-color-border-strong)]' },\n outline: { trigger: 'bg-transparent border-[var(--novi-color-border-strong)]' },\n soft: { trigger: 'bg-[var(--novi-color-subtle)] border-[var(--novi-color-border)]' },\n ghost: {\n trigger: 'bg-transparent border-transparent hover:bg-[var(--novi-color-subtle)]',\n },\n plain: {\n trigger: 'bg-transparent border-transparent px-0 underline underline-offset-4',\n },\n}\n\n/**\n * Select のスタイル定義。\n *\n * 展開部の位置は `InflowPopover` が `!` 付きのリセットで固定するので、\n * ここで `position` 系を書いても効かない(書く必要も無い)。\n *\n * @example\n * import { selectStyles } from '@novi-ui/flatlay'\n * import { tv } from 'tailwind-variants'\n *\n * const mySelect = tv({ extend: selectStyles, slots: { option: 'px-4' } })\n */\nexport const selectStyles = tv({\n slots,\n // `variant` は最後に宣言する。先に書くと size のクラスに負ける(申し送り6)\n variants: { size, radius, variant },\n defaultVariants: { size: 'md', radius: 'sm', variant: 'solid' },\n})\n\nexport type SelectStyleProps = Parameters<typeof selectStyles>[0]\n\n/**\n * 選択済みの印が立つ場所。**幅を常に確保する**ので、選ぶ前後で行がずれない。\n *\n * チェックマーク(両テーマ)ではなく帳票のインデックス記号にしているのは、\n * 記号そのものが等幅の列として読めるから。`1ch` は mono の 1 文字ぶん。\n */\nexport const optionMarkerClass = `w-[1ch] shrink-0 text-[var(--novi-color-primary)] ${mono}`\n"],"mappings":";;;;;;;;;;;;;;AAuBA,MAAM,QAAQ;CACZ,MAAM,CACJ,yBAGA,qCACF,CAAC,CAAC,KAAK,GAAG;CACV,OAAO;CACP,SAAS;EACP;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CACV,OAAO;CAEP,MAAM,wDAAwD;CAC9D,SAAS;EAEP;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CAEV,SAAS;CACT,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CACV,aAAa;CACb,cAAc;AAChB;;;;;;;;;;;;;AA2DA,MAAa,eAAe,GAAG;CAC7B;CAEA,UAAU;EAAE;GArDZ,IAAI;IACF,SAAS;IACT,QAAQ;GACV;GACA,IAAI;IACF,SAAS;IACT,QAAQ;GACV;GACA,IAAI;IACF,SAAS;IACT,QAAQ;GACV;EA0CY;EAAM;GAtClB,MAAM,EAAE,SAAS,oCAAoC;GACrD,IAAI,EAAE,SAAS,kCAAkC;GACjD,IAAI,EAAE,SAAS,kCAAkC;GACjD,IAAI,EAAE,SAAS,kCAAkC;GACjD,MAAM,EAAE,SAAS,oCAAoC;EAkCnC;EAAQ;GA1B1B,OAAO,EAAE,SAAS,0EAA0E;GAC5F,SAAS,EAAE,SAAS,0DAA0D;GAC9E,MAAM,EAAE,SAAS,kEAAkE;GACnF,OAAO,EACL,SAAS,wEACX;GACA,OAAO,EACL,SAAS,sEACX;EAkB0B;CAAQ;CAClC,iBAAiB;EAAE,MAAM;EAAM,QAAQ;EAAM,SAAS;CAAQ;AAChE,CAAC;;;;;;;AAUD,MAAa,oBAAoB,qDAAqD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SkeletonProps } from "@novi-ui/core";
|
|
2
|
+
//#region src/skeleton/skeleton.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* 読み込み中の場所取り。
|
|
5
|
+
*
|
|
6
|
+
* 支援技術には読ませない。読み込み状態は Spinner か live region で伝えること。
|
|
7
|
+
* 大きさは `className` で指定する。
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* <Skeleton className="h-4 w-40" />
|
|
11
|
+
*/
|
|
12
|
+
declare function Skeleton({ radius, className, classNames, id }: SkeletonProps): import("react").JSX.Element;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { Skeleton };
|
|
15
|
+
//# sourceMappingURL=skeleton.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skeleton.d.mts","names":[],"sources":["../../src/skeleton/skeleton.tsx"],"mappings":";;;;;;;;;;;iBAcgB,WAAW,QAAQ,WAAW,YAAY,MAAM,gCAAa,IAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { skeletonStyles } from "./skeleton.styles.mjs";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/skeleton/skeleton.tsx
|
|
5
|
+
/**
|
|
6
|
+
* 読み込み中の場所取り。
|
|
7
|
+
*
|
|
8
|
+
* 支援技術には読ませない。読み込み状態は Spinner か live region で伝えること。
|
|
9
|
+
* 大きさは `className` で指定する。
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* <Skeleton className="h-4 w-40" />
|
|
13
|
+
*/
|
|
14
|
+
function Skeleton({ radius, className, classNames, id }) {
|
|
15
|
+
const s = skeletonStyles({ radius });
|
|
16
|
+
return /* @__PURE__ */ jsx("span", {
|
|
17
|
+
id,
|
|
18
|
+
"aria-hidden": "true",
|
|
19
|
+
"data-slot": "root",
|
|
20
|
+
className: s.root({ class: [className, classNames?.root] })
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { Skeleton };
|
|
25
|
+
|
|
26
|
+
//# sourceMappingURL=skeleton.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skeleton.mjs","names":[],"sources":["../../src/skeleton/skeleton.tsx"],"sourcesContent":["'use client'\n\nimport type { SkeletonProps } from '@novi-ui/core'\nimport { skeletonStyles } from './skeleton.styles'\n\n/**\n * 読み込み中の場所取り。\n *\n * 支援技術には読ませない。読み込み状態は Spinner か live region で伝えること。\n * 大きさは `className` で指定する。\n *\n * @example\n * <Skeleton className=\"h-4 w-40\" />\n */\nexport function Skeleton({ radius, className, classNames, id }: SkeletonProps) {\n const s = skeletonStyles({ radius })\n\n return (\n <span\n id={id}\n aria-hidden=\"true\"\n data-slot=\"root\"\n className={s.root({ class: [className, classNames?.root] })}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAgB,SAAS,EAAE,QAAQ,WAAW,YAAY,MAAqB;CAC7E,MAAM,IAAI,eAAe,EAAE,OAAO,CAAC;CAEnC,OACE,oBAAC,QAAD;EACM;EACJ,eAAY;EACZ,aAAU;EACV,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,YAAY,IAAI,EAAE,CAAC;CAC3D,CAAA;AAEL"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { VariantMap } from "@novi-ui/core";
|
|
2
|
+
//#region src/skeleton/skeleton.styles.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Skeleton のスタイル定義。
|
|
5
|
+
*
|
|
6
|
+
* 既定は `none`。場所取りは記入前の空欄そのもので、両テーマのように
|
|
7
|
+
* 中身の角丸を先取りしない(Flatlay の `sm` は 2px なので差は僅かだが、
|
|
8
|
+
* 空欄が角を持たないことは書類の見た目として意味がある)。
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const mySkeleton = tv({ extend: skeletonStyles, slots: { root: 'opacity-50' } })
|
|
12
|
+
*/
|
|
13
|
+
declare const skeletonStyles: import("tailwind-variants").TVReturnType<{
|
|
14
|
+
radius: VariantMap<"sm" | "md" | "lg" | "none" | "full", {
|
|
15
|
+
root: string;
|
|
16
|
+
}>;
|
|
17
|
+
}, {
|
|
18
|
+
/**
|
|
19
|
+
* 濃さのパルスだけ。シマー(グラデーションを translate させる光沢)は
|
|
20
|
+
* 光源を前提にした表現で、影を持たない Flatlay では成立しない(FR-11)。
|
|
21
|
+
*/
|
|
22
|
+
root: string;
|
|
23
|
+
}, undefined, {
|
|
24
|
+
radius: VariantMap<"sm" | "md" | "lg" | "none" | "full", {
|
|
25
|
+
root: string;
|
|
26
|
+
}>;
|
|
27
|
+
}, {
|
|
28
|
+
/**
|
|
29
|
+
* 濃さのパルスだけ。シマー(グラデーションを translate させる光沢)は
|
|
30
|
+
* 光源を前提にした表現で、影を持たない Flatlay では成立しない(FR-11)。
|
|
31
|
+
*/
|
|
32
|
+
root: string;
|
|
33
|
+
}, import("tailwind-variants").TVReturnTypeLike<{
|
|
34
|
+
radius: VariantMap<"sm" | "md" | "lg" | "none" | "full", {
|
|
35
|
+
root: string;
|
|
36
|
+
}>;
|
|
37
|
+
}, {
|
|
38
|
+
/**
|
|
39
|
+
* 濃さのパルスだけ。シマー(グラデーションを translate させる光沢)は
|
|
40
|
+
* 光源を前提にした表現で、影を持たない Flatlay では成立しない(FR-11)。
|
|
41
|
+
*/
|
|
42
|
+
root: string;
|
|
43
|
+
}>>;
|
|
44
|
+
type SkeletonStyleProps = Parameters<typeof skeletonStyles>[0];
|
|
45
|
+
//#endregion
|
|
46
|
+
export { SkeletonStyleProps, skeletonStyles };
|
|
47
|
+
//# sourceMappingURL=skeleton.styles.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skeleton.styles.d.mts","names":[],"sources":["../../src/skeleton/skeleton.styles.ts"],"mappings":";;;;;;;;;;;;cAmCa,4CAAc;;IAlBkB;;;;;;;;;;IAAA;;;;;;;;;;IAAA;;;;;;;;;KAwBjC,qBAAqB,kBAAkB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { tv } from "tailwind-variants";
|
|
2
|
+
/**
|
|
3
|
+
* Skeleton のスタイル定義。
|
|
4
|
+
*
|
|
5
|
+
* 既定は `none`。場所取りは記入前の空欄そのもので、両テーマのように
|
|
6
|
+
* 中身の角丸を先取りしない(Flatlay の `sm` は 2px なので差は僅かだが、
|
|
7
|
+
* 空欄が角を持たないことは書類の見た目として意味がある)。
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const mySkeleton = tv({ extend: skeletonStyles, slots: { root: 'opacity-50' } })
|
|
11
|
+
*/
|
|
12
|
+
const skeletonStyles = tv({
|
|
13
|
+
slots: {
|
|
14
|
+
/**
|
|
15
|
+
* 濃さのパルスだけ。シマー(グラデーションを translate させる光沢)は
|
|
16
|
+
* 光源を前提にした表現で、影を持たない Flatlay では成立しない(FR-11)。
|
|
17
|
+
*/
|
|
18
|
+
root: "block bg-[var(--novi-color-subtle)] motion-safe:animate-pulse" },
|
|
19
|
+
variants: { radius: {
|
|
20
|
+
none: { root: "rounded-[var(--novi-radius-none)]" },
|
|
21
|
+
sm: { root: "rounded-[var(--novi-radius-sm)]" },
|
|
22
|
+
md: { root: "rounded-[var(--novi-radius-md)]" },
|
|
23
|
+
lg: { root: "rounded-[var(--novi-radius-lg)]" },
|
|
24
|
+
full: { root: "rounded-[var(--novi-radius-full)]" }
|
|
25
|
+
} },
|
|
26
|
+
defaultVariants: { radius: "none" }
|
|
27
|
+
});
|
|
28
|
+
//#endregion
|
|
29
|
+
export { skeletonStyles };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=skeleton.styles.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skeleton.styles.mjs","names":[],"sources":["../../src/skeleton/skeleton.styles.ts"],"sourcesContent":["import type {\n NoviRadius,\n SlotMap,\n skeletonRequiredSlots,\n skeletonSlots,\n VariantMap,\n} from '@novi-ui/core'\nimport { tv } from 'tailwind-variants'\n\nconst slots = {\n /**\n * 濃さのパルスだけ。シマー(グラデーションを translate させる光沢)は\n * 光源を前提にした表現で、影を持たない Flatlay では成立しない(FR-11)。\n */\n root: 'block bg-[var(--novi-color-subtle)] motion-safe:animate-pulse',\n} satisfies SlotMap<typeof skeletonSlots, (typeof skeletonRequiredSlots)[number]>\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 * Skeleton のスタイル定義。\n *\n * 既定は `none`。場所取りは記入前の空欄そのもので、両テーマのように\n * 中身の角丸を先取りしない(Flatlay の `sm` は 2px なので差は僅かだが、\n * 空欄が角を持たないことは書類の見た目として意味がある)。\n *\n * @example\n * const mySkeleton = tv({ extend: skeletonStyles, slots: { root: 'opacity-50' } })\n */\nexport const skeletonStyles = tv({\n slots,\n variants: { radius },\n defaultVariants: { radius: 'none' },\n})\n\nexport type SkeletonStyleProps = Parameters<typeof skeletonStyles>[0]\n"],"mappings":";;;;;;;;;;;AAmCA,MAAa,iBAAiB,GAAG;CAC/B;;;;;AAtBA,MAAM,gEAsBN;CACA,UAAU,EAAE;EAnBZ,MAAM,EAAE,MAAM,oCAAoC;EAClD,IAAI,EAAE,MAAM,kCAAkC;EAC9C,IAAI,EAAE,MAAM,kCAAkC;EAC9C,IAAI,EAAE,MAAM,kCAAkC;EAC9C,MAAM,EAAE,MAAM,oCAAoC;CAetC,EAAO;CACnB,iBAAiB,EAAE,QAAQ,OAAO;AACpC,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SpinnerProps } from "@novi-ui/core";
|
|
2
|
+
//#region src/spinner/spinner.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* 処理中であることを示す回転表示。
|
|
5
|
+
*
|
|
6
|
+
* `label` を渡すと画面にも表示される。渡さない場合も支援技術には
|
|
7
|
+
* 「読み込み中」と伝わるようにしてある。
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* <Spinner label="読み込み中" />
|
|
11
|
+
*/
|
|
12
|
+
declare function Spinner({ size, color, label, className, classNames, id }: SpinnerProps): import("react").JSX.Element;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { Spinner };
|
|
15
|
+
//# sourceMappingURL=spinner.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.d.mts","names":[],"sources":["../../src/spinner/spinner.tsx"],"mappings":";;;;;;;;;;;iBAcgB,UAAU,MAAM,OAAO,OAAO,WAAW,YAAY,MAAM,+BAAY,IAAA"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { spinnerStyles } from "./spinner.styles.mjs";
|
|
3
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
4
|
+
//#region src/spinner/spinner.tsx
|
|
5
|
+
/**
|
|
6
|
+
* 処理中であることを示す回転表示。
|
|
7
|
+
*
|
|
8
|
+
* `label` を渡すと画面にも表示される。渡さない場合も支援技術には
|
|
9
|
+
* 「読み込み中」と伝わるようにしてある。
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* <Spinner label="読み込み中" />
|
|
13
|
+
*/
|
|
14
|
+
function Spinner({ size, color, label, className, classNames, id }) {
|
|
15
|
+
const s = spinnerStyles({
|
|
16
|
+
size,
|
|
17
|
+
color
|
|
18
|
+
});
|
|
19
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
20
|
+
id,
|
|
21
|
+
role: "status",
|
|
22
|
+
"data-slot": "root",
|
|
23
|
+
className: s.root({ class: [className, classNames?.root] }),
|
|
24
|
+
children: [/* @__PURE__ */ jsxs("svg", {
|
|
25
|
+
"data-slot": "circle",
|
|
26
|
+
className: s.circle({ class: classNames?.circle }),
|
|
27
|
+
viewBox: "0 0 24 24",
|
|
28
|
+
fill: "none",
|
|
29
|
+
"aria-hidden": "true",
|
|
30
|
+
children: [/* @__PURE__ */ jsx("circle", {
|
|
31
|
+
cx: "12",
|
|
32
|
+
cy: "12",
|
|
33
|
+
r: "9",
|
|
34
|
+
stroke: "currentColor",
|
|
35
|
+
strokeWidth: "2",
|
|
36
|
+
opacity: "0.2"
|
|
37
|
+
}), /* @__PURE__ */ jsx("path", {
|
|
38
|
+
d: "M21 12a9 9 0 0 0-9-9",
|
|
39
|
+
stroke: "currentColor",
|
|
40
|
+
strokeWidth: "2"
|
|
41
|
+
})]
|
|
42
|
+
}), label !== void 0 ? /* @__PURE__ */ jsx("span", {
|
|
43
|
+
"data-slot": "label",
|
|
44
|
+
className: s.label({ class: classNames?.label }),
|
|
45
|
+
children: label
|
|
46
|
+
}) : /* @__PURE__ */ jsx("span", {
|
|
47
|
+
className: "sr-only",
|
|
48
|
+
children: "読み込み中"
|
|
49
|
+
})]
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { Spinner };
|
|
54
|
+
|
|
55
|
+
//# sourceMappingURL=spinner.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.mjs","names":[],"sources":["../../src/spinner/spinner.tsx"],"sourcesContent":["'use client'\n\nimport type { SpinnerProps } from '@novi-ui/core'\nimport { spinnerStyles } from './spinner.styles'\n\n/**\n * 処理中であることを示す回転表示。\n *\n * `label` を渡すと画面にも表示される。渡さない場合も支援技術には\n * 「読み込み中」と伝わるようにしてある。\n *\n * @example\n * <Spinner label=\"読み込み中\" />\n */\nexport function Spinner({ size, color, label, className, classNames, id }: SpinnerProps) {\n const s = spinnerStyles({ size, color })\n\n return (\n <span\n id={id}\n role=\"status\"\n data-slot=\"root\"\n className={s.root({ class: [className, classNames?.root] })}\n >\n {/* 線端は切り落とし(既定の butt)。丸めると製図の線ではなくなる */}\n <svg\n data-slot=\"circle\"\n className={s.circle({ class: classNames?.circle })}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" strokeWidth=\"2\" opacity=\"0.2\" />\n <path d=\"M21 12a9 9 0 0 0-9-9\" stroke=\"currentColor\" strokeWidth=\"2\" />\n </svg>\n\n {label !== undefined ? (\n <span data-slot=\"label\" className={s.label({ class: classNames?.label })}>\n {label}\n </span>\n ) : (\n <span className=\"sr-only\">読み込み中</span>\n )}\n </span>\n )\n}\n"],"mappings":";;;;;;;;;;;;;AAcA,SAAgB,QAAQ,EAAE,MAAM,OAAO,OAAO,WAAW,YAAY,MAAoB;CACvF,MAAM,IAAI,cAAc;EAAE;EAAM;CAAM,CAAC;CAEvC,OACE,qBAAC,QAAD;EACM;EACJ,MAAK;EACL,aAAU;EACV,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,YAAY,IAAI,EAAE,CAAC;EAJ5D,UAAA,CAOE,qBAAC,OAAD;GACE,aAAU;GACV,WAAW,EAAE,OAAO,EAAE,OAAO,YAAY,OAAO,CAAC;GACjD,SAAQ;GACR,MAAK;GACL,eAAY;GALd,UAAA,CAOE,oBAAC,UAAD;IAAQ,IAAG;IAAK,IAAG;IAAK,GAAE;IAAI,QAAO;IAAe,aAAY;IAAI,SAAQ;GAAO,CAAA,GACnF,oBAAC,QAAD;IAAM,GAAE;IAAuB,QAAO;IAAe,aAAY;GAAK,CAAA,CACnE;EAEJ,CAAA,GAAA,UAAU,KAAA,IACT,oBAAC,QAAD;GAAM,aAAU;GAAQ,WAAW,EAAE,MAAM,EAAE,OAAO,YAAY,MAAM,CAAC;GACpE,UAAA;EACG,CAAA,IAEN,oBAAC,QAAD;GAAM,WAAU;GAAU,UAAA;EAAW,CAAA,CAEnC;;AAEV"}
|