@novi-ui/flatlay 0.3.0 → 0.4.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/dist/combo-box/combo-box.d.mts +37 -0
- package/dist/combo-box/combo-box.d.mts.map +1 -0
- package/dist/combo-box/combo-box.mjs +129 -0
- package/dist/combo-box/combo-box.mjs.map +1 -0
- package/dist/combo-box/combo-box.styles.d.mts +88 -0
- package/dist/combo-box/combo-box.styles.d.mts.map +1 -0
- package/dist/combo-box/combo-box.styles.mjs +113 -0
- package/dist/combo-box/combo-box.styles.mjs.map +1 -0
- package/dist/combo-box/index.d.mts +3 -0
- package/dist/date-picker/date-picker.d.mts +16 -0
- package/dist/date-picker/date-picker.d.mts.map +1 -0
- package/dist/date-picker/date-picker.mjs +140 -0
- package/dist/date-picker/date-picker.mjs.map +1 -0
- package/dist/date-picker/date-picker.styles.d.mts +103 -0
- package/dist/date-picker/date-picker.styles.d.mts.map +1 -0
- package/dist/date-picker/date-picker.styles.mjs +131 -0
- package/dist/date-picker/date-picker.styles.mjs.map +1 -0
- package/dist/date-picker/index.d.mts +3 -0
- package/dist/index.d.mts +16 -1
- package/dist/index.mjs +11 -1
- package/dist/menu/menu.styles.d.mts +9 -9
- package/dist/number-field/index.d.mts +3 -0
- package/dist/number-field/number-field.d.mts +16 -0
- package/dist/number-field/number-field.d.mts.map +1 -0
- package/dist/number-field/number-field.mjs +93 -0
- package/dist/number-field/number-field.mjs.map +1 -0
- package/dist/number-field/number-field.styles.d.mts +88 -0
- package/dist/number-field/number-field.styles.d.mts.map +1 -0
- package/dist/number-field/number-field.styles.mjs +102 -0
- package/dist/number-field/number-field.styles.mjs.map +1 -0
- package/dist/pagination/index.d.mts +3 -0
- package/dist/pagination/pagination.d.mts +13 -0
- package/dist/pagination/pagination.d.mts.map +1 -0
- package/dist/pagination/pagination.mjs +98 -0
- package/dist/pagination/pagination.mjs.map +1 -0
- package/dist/pagination/pagination.styles.d.mts +67 -0
- package/dist/pagination/pagination.styles.d.mts.map +1 -0
- package/dist/pagination/pagination.styles.mjs +83 -0
- package/dist/pagination/pagination.styles.mjs.map +1 -0
- package/dist/select/select.d.mts +1 -1
- package/dist/select/select.mjs +1 -1
- package/dist/select/select.mjs.map +1 -1
- package/dist/table/index.d.mts +3 -0
- package/dist/table/table.d.mts +104 -0
- package/dist/table/table.d.mts.map +1 -0
- package/dist/table/table.mjs +167 -0
- package/dist/table/table.mjs.map +1 -0
- package/dist/table/table.styles.d.mts +58 -0
- package/dist/table/table.styles.d.mts.map +1 -0
- package/dist/table/table.styles.mjs +84 -0
- package/dist/table/table.styles.mjs.map +1 -0
- package/package.json +5 -4
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { disabledState, focusRing } from "../styles/focus-ring.mjs";
|
|
2
|
+
import { mono, monoNumeric } from "../styles/mono.mjs";
|
|
3
|
+
import { tv } from "tailwind-variants";
|
|
4
|
+
//#region src/number-field/number-field.styles.ts
|
|
5
|
+
/**
|
|
6
|
+
* 増減ボタン。**罫線で区切ったセル**に等幅の `−` `+` を置く(ADR-F7)。
|
|
7
|
+
* 面も影も持たず、押した瞬間だけ反転する(スタンプ。ADR-F3)。
|
|
8
|
+
* 記号は文字で描く。帳票の語彙は活字であって図形ではない。
|
|
9
|
+
*/
|
|
10
|
+
const stepper = [
|
|
11
|
+
"shrink-0 self-stretch inline-flex items-center justify-center",
|
|
12
|
+
"px-[var(--novi-pad-control-x-sm)]",
|
|
13
|
+
"text-[var(--novi-color-muted)]",
|
|
14
|
+
"border-l",
|
|
15
|
+
"outline-none",
|
|
16
|
+
monoNumeric,
|
|
17
|
+
"hover:text-[var(--novi-color-fg)] hover:bg-[var(--novi-color-subtle)]",
|
|
18
|
+
"data-[focus-visible]:text-[var(--novi-color-fg)]",
|
|
19
|
+
"data-[pressed]:bg-[var(--novi-color-fg)] data-[pressed]:text-[var(--novi-color-bg)]",
|
|
20
|
+
"data-[disabled]:opacity-40 data-[disabled]:cursor-default",
|
|
21
|
+
"transition-[background-color,color]",
|
|
22
|
+
"duration-[var(--novi-duration-fast)] ease-[var(--novi-ease-standard)]"
|
|
23
|
+
].join(" ");
|
|
24
|
+
const slots = {
|
|
25
|
+
root: "flex flex-col gap-1.5",
|
|
26
|
+
label: `text-[length:var(--novi-text-sm)] text-[var(--novi-color-fg)] ${mono}`,
|
|
27
|
+
/**
|
|
28
|
+
* 記入欄の枠。罫線の幅は全 variant が持ち、色だけを variant が決める(Flatlay の型)。
|
|
29
|
+
* 増減セルの縦罫線も同じ色を継ぐので、`border-color` は枠にだけ書く。
|
|
30
|
+
*/
|
|
31
|
+
inputWrapper: [
|
|
32
|
+
"flex items-center w-full overflow-hidden",
|
|
33
|
+
"text-[var(--novi-color-fg)]",
|
|
34
|
+
"border",
|
|
35
|
+
"rounded-[var(--novi-radius-sm)]",
|
|
36
|
+
"data-[invalid]:border-[var(--novi-color-danger)]",
|
|
37
|
+
"transition-[border-color,opacity]",
|
|
38
|
+
"duration-[var(--novi-duration-fast)] ease-[var(--novi-ease-standard)]",
|
|
39
|
+
focusRing,
|
|
40
|
+
disabledState
|
|
41
|
+
].join(" "),
|
|
42
|
+
input: [
|
|
43
|
+
"w-full min-w-0 bg-transparent outline-none text-right",
|
|
44
|
+
`text-[var(--novi-color-fg)] ${monoNumeric}`,
|
|
45
|
+
"placeholder:text-[var(--novi-color-muted)]"
|
|
46
|
+
].join(" "),
|
|
47
|
+
decrement: stepper,
|
|
48
|
+
increment: stepper,
|
|
49
|
+
description: `text-[length:var(--novi-text-sm)] text-[var(--novi-color-muted)] ${mono}`,
|
|
50
|
+
errorMessage: `text-[length:var(--novi-text-sm)] text-[var(--novi-color-danger)] ${mono}`
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* NumberField のスタイル定義。
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* import { numberFieldStyles } from '@novi-ui/flatlay'
|
|
57
|
+
* import { tv } from 'tailwind-variants'
|
|
58
|
+
*
|
|
59
|
+
* const myField = tv({ extend: numberFieldStyles, slots: { input: 'text-left' } })
|
|
60
|
+
*/
|
|
61
|
+
const numberFieldStyles = tv({
|
|
62
|
+
slots,
|
|
63
|
+
variants: {
|
|
64
|
+
size: {
|
|
65
|
+
sm: {
|
|
66
|
+
inputWrapper: "h-7",
|
|
67
|
+
input: "px-[var(--novi-pad-control-x-sm)] text-[length:var(--novi-text-sm)]"
|
|
68
|
+
},
|
|
69
|
+
md: {
|
|
70
|
+
inputWrapper: "h-8",
|
|
71
|
+
input: "px-[var(--novi-pad-control-x-md)] text-[length:var(--novi-text-base)]"
|
|
72
|
+
},
|
|
73
|
+
lg: {
|
|
74
|
+
inputWrapper: "h-10",
|
|
75
|
+
input: "px-[var(--novi-pad-control-x-lg)] text-[length:var(--novi-text-base)]"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
radius: {
|
|
79
|
+
none: { inputWrapper: "rounded-[var(--novi-radius-none)]" },
|
|
80
|
+
sm: { inputWrapper: "rounded-[var(--novi-radius-sm)]" },
|
|
81
|
+
md: { inputWrapper: "rounded-[var(--novi-radius-md)]" },
|
|
82
|
+
lg: { inputWrapper: "rounded-[var(--novi-radius-lg)]" },
|
|
83
|
+
full: { inputWrapper: "rounded-[var(--novi-radius-full)]" }
|
|
84
|
+
},
|
|
85
|
+
variant: {
|
|
86
|
+
solid: { inputWrapper: "bg-[var(--novi-color-surface)] border-[var(--novi-color-border-strong)]" },
|
|
87
|
+
outline: { inputWrapper: "bg-transparent border-[var(--novi-color-border-strong)]" },
|
|
88
|
+
soft: { inputWrapper: "bg-[var(--novi-color-subtle)] border-[var(--novi-color-border)]" },
|
|
89
|
+
ghost: { inputWrapper: "bg-transparent border-transparent border-b-[var(--novi-color-border-strong)]" },
|
|
90
|
+
plain: { inputWrapper: "bg-transparent border-transparent" }
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
defaultVariants: {
|
|
94
|
+
size: "md",
|
|
95
|
+
radius: "sm",
|
|
96
|
+
variant: "outline"
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
//#endregion
|
|
100
|
+
export { numberFieldStyles };
|
|
101
|
+
|
|
102
|
+
//# sourceMappingURL=number-field.styles.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"number-field.styles.mjs","names":[],"sources":["../../src/number-field/number-field.styles.ts"],"sourcesContent":["import type {\n NoviRadius,\n NoviSize,\n NoviVariant,\n numberFieldRequiredSlots,\n numberFieldSlots,\n SlotMap,\n VariantMap,\n} from '@novi-ui/core'\nimport { tv } from 'tailwind-variants'\nimport { disabledState, focusRing } from '../styles/focus-ring'\nimport { mono, monoNumeric } from '../styles/mono'\n\n/**\n * 増減ボタン。**罫線で区切ったセル**に等幅の `−` `+` を置く(ADR-F7)。\n * 面も影も持たず、押した瞬間だけ反転する(スタンプ。ADR-F3)。\n * 記号は文字で描く。帳票の語彙は活字であって図形ではない。\n */\nconst stepper = [\n 'shrink-0 self-stretch inline-flex items-center justify-center',\n 'px-[var(--novi-pad-control-x-sm)]',\n 'text-[var(--novi-color-muted)]',\n 'border-l',\n 'outline-none',\n monoNumeric,\n 'hover:text-[var(--novi-color-fg)] hover:bg-[var(--novi-color-subtle)]',\n 'data-[focus-visible]:text-[var(--novi-color-fg)]',\n 'data-[pressed]:bg-[var(--novi-color-fg)] data-[pressed]:text-[var(--novi-color-bg)]',\n 'data-[disabled]:opacity-40 data-[disabled]:cursor-default',\n 'transition-[background-color,color]',\n 'duration-[var(--novi-duration-fast)] ease-[var(--novi-ease-standard)]',\n].join(' ')\n\nconst slots = {\n root: 'flex flex-col gap-1.5',\n label: `text-[length:var(--novi-text-sm)] text-[var(--novi-color-fg)] ${mono}`,\n /**\n * 記入欄の枠。罫線の幅は全 variant が持ち、色だけを variant が決める(Flatlay の型)。\n * 増減セルの縦罫線も同じ色を継ぐので、`border-color` は枠にだけ書く。\n */\n inputWrapper: [\n 'flex items-center w-full overflow-hidden',\n 'text-[var(--novi-color-fg)]',\n 'border',\n 'rounded-[var(--novi-radius-sm)]',\n 'data-[invalid]:border-[var(--novi-color-danger)]',\n 'transition-[border-color,opacity]',\n 'duration-[var(--novi-duration-fast)] ease-[var(--novi-ease-standard)]',\n focusRing,\n disabledState,\n ].join(' '),\n // 数値は右詰めの等幅。帳票の金額欄と同じ\n input: [\n 'w-full min-w-0 bg-transparent outline-none text-right',\n `text-[var(--novi-color-fg)] ${monoNumeric}`,\n 'placeholder:text-[var(--novi-color-muted)]',\n ].join(' '),\n decrement: stepper,\n increment: stepper,\n description: `text-[length:var(--novi-text-sm)] text-[var(--novi-color-muted)] ${mono}`,\n // 色だけに頼らずテキストを必ず伴う(WCAG 1.4.1)\n errorMessage: `text-[length:var(--novi-text-sm)] text-[var(--novi-color-danger)] ${mono}`,\n} satisfies SlotMap<typeof numberFieldSlots, (typeof numberFieldRequiredSlots)[number]>\n\nconst variant: VariantMap<NoviVariant, { inputWrapper: string }> = {\n solid: {\n inputWrapper: 'bg-[var(--novi-color-surface)] border-[var(--novi-color-border-strong)]',\n },\n outline: { inputWrapper: 'bg-transparent border-[var(--novi-color-border-strong)]' },\n soft: { inputWrapper: 'bg-[var(--novi-color-subtle)] border-[var(--novi-color-border)]' },\n ghost: {\n inputWrapper: 'bg-transparent border-transparent border-b-[var(--novi-color-border-strong)]',\n },\n plain: { inputWrapper: 'bg-transparent border-transparent' },\n}\n\n/** 高さは Button / Input と揃える。28 / 32 / 40px。 */\nconst size: VariantMap<NoviSize, { inputWrapper: string; input: string }> = {\n sm: {\n inputWrapper: 'h-7',\n input: 'px-[var(--novi-pad-control-x-sm)] text-[length:var(--novi-text-sm)]',\n },\n md: {\n inputWrapper: 'h-8',\n input: 'px-[var(--novi-pad-control-x-md)] text-[length:var(--novi-text-base)]',\n },\n lg: {\n inputWrapper: 'h-10',\n input: 'px-[var(--novi-pad-control-x-lg)] text-[length:var(--novi-text-base)]',\n },\n}\n\nconst radius: VariantMap<NoviRadius, { inputWrapper: string }> = {\n none: { inputWrapper: 'rounded-[var(--novi-radius-none)]' },\n sm: { inputWrapper: 'rounded-[var(--novi-radius-sm)]' },\n md: { inputWrapper: 'rounded-[var(--novi-radius-md)]' },\n lg: { inputWrapper: 'rounded-[var(--novi-radius-lg)]' },\n full: { inputWrapper: 'rounded-[var(--novi-radius-full)]' },\n}\n\n/**\n * NumberField のスタイル定義。\n *\n * @example\n * import { numberFieldStyles } from '@novi-ui/flatlay'\n * import { tv } from 'tailwind-variants'\n *\n * const myField = tv({ extend: numberFieldStyles, slots: { input: 'text-left' } })\n */\nexport const numberFieldStyles = tv({\n slots,\n // `variant` は最後に宣言する。先に書くと size のクラスに負ける\n variants: { size, radius, variant },\n defaultVariants: { size: 'md', radius: 'sm', variant: 'outline' },\n})\n\nexport type NumberFieldStyleProps = Parameters<typeof numberFieldStyles>[0]\n"],"mappings":";;;;;;;;;AAkBA,MAAM,UAAU;CACd;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,GAAG;AAEV,MAAM,QAAQ;CACZ,MAAM;CACN,OAAO,iEAAiE;;;;;CAKxE,cAAc;EACZ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CAEV,OAAO;EACL;EACA,+BAA+B;EAC/B;CACF,CAAC,CAAC,KAAK,GAAG;CACV,WAAW;CACX,WAAW;CACX,aAAa,oEAAoE;CAEjF,cAAc,qEAAqE;AACrF;;;;;;;;;;AA+CA,MAAa,oBAAoB,GAAG;CAClC;CAEA,UAAU;EAAE;GAlCZ,IAAI;IACF,cAAc;IACd,OAAO;GACT;GACA,IAAI;IACF,cAAc;IACd,OAAO;GACT;GACA,IAAI;IACF,cAAc;IACd,OAAO;GACT;EAuBY;EAAM;GAnBlB,MAAM,EAAE,cAAc,oCAAoC;GAC1D,IAAI,EAAE,cAAc,kCAAkC;GACtD,IAAI,EAAE,cAAc,kCAAkC;GACtD,IAAI,EAAE,cAAc,kCAAkC;GACtD,MAAM,EAAE,cAAc,oCAAoC;EAexC;EAAQ;GA/C1B,OAAO,EACL,cAAc,0EAChB;GACA,SAAS,EAAE,cAAc,0DAA0D;GACnF,MAAM,EAAE,cAAc,kEAAkE;GACxF,OAAO,EACL,cAAc,+EAChB;GACA,OAAO,EAAE,cAAc,oCAAoC;EAuCjC;CAAQ;CAClC,iBAAiB;EAAE,MAAM;EAAM,QAAQ;EAAM,SAAS;CAAU;AAClE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PaginationProps } from "@novi-ui/core";
|
|
2
|
+
//#region src/pagination/pagination.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* 一覧のページを移動する。**罫線で区切った 1 本の帯**に数字を並べ、現在地は反転させる
|
|
5
|
+
* (Raster は数字だけを並べ、Tactile は面を塗る)。前後は `‹` `›` の活字。
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* <Pagination total={10} page={page} onChange={setPage} />
|
|
9
|
+
*/
|
|
10
|
+
declare function Pagination({ size, radius, total, page, defaultPage, onChange, siblingCount, boundaryCount, isDisabled, 'aria-label': ariaLabel, className, classNames, id }: PaginationProps): import("react").JSX.Element;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { Pagination };
|
|
13
|
+
//# sourceMappingURL=pagination.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.d.mts","names":[],"sources":["../../src/pagination/pagination.tsx"],"mappings":";;;;;;;;;iBAegB,aACd,MACA,QACA,OACA,MACA,aACA,UACA,cACA,eACA,0BACc,WACd,WACA,YACA,MACC,kCAAe,IAAA"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { paginationStyles } from "./pagination.styles.mjs";
|
|
3
|
+
import { Button } from "react-aria-components";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
import { paginationRange } from "@novi-ui/core/client";
|
|
7
|
+
//#region src/pagination/pagination.tsx
|
|
8
|
+
/**
|
|
9
|
+
* 一覧のページを移動する。**罫線で区切った 1 本の帯**に数字を並べ、現在地は反転させる
|
|
10
|
+
* (Raster は数字だけを並べ、Tactile は面を塗る)。前後は `‹` `›` の活字。
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* <Pagination total={10} page={page} onChange={setPage} />
|
|
14
|
+
*/
|
|
15
|
+
function Pagination({ size, radius, total, page, defaultPage = 1, onChange, siblingCount, boundaryCount, isDisabled, "aria-label": ariaLabel = "ページ送り", className, classNames, id }) {
|
|
16
|
+
const s = paginationStyles({
|
|
17
|
+
size,
|
|
18
|
+
radius
|
|
19
|
+
});
|
|
20
|
+
const [internal, setInternal] = useState(defaultPage);
|
|
21
|
+
const clamp = (n) => Math.min(Math.max(n, 1), Math.max(total, 1));
|
|
22
|
+
const current = clamp(page ?? internal);
|
|
23
|
+
const go = (n) => {
|
|
24
|
+
const next = clamp(n);
|
|
25
|
+
if (next === current) return;
|
|
26
|
+
if (page === void 0) setInternal(next);
|
|
27
|
+
onChange?.(next);
|
|
28
|
+
};
|
|
29
|
+
const slots = paginationRange(current, total, {
|
|
30
|
+
siblingCount,
|
|
31
|
+
boundaryCount
|
|
32
|
+
});
|
|
33
|
+
const entries = slots.map((slot, i) => ({
|
|
34
|
+
slot,
|
|
35
|
+
key: slot === "ellipsis" ? `ellipsis-after-${slots[i - 1]}` : `page-${slot}`
|
|
36
|
+
}));
|
|
37
|
+
return /* @__PURE__ */ jsx("nav", {
|
|
38
|
+
id,
|
|
39
|
+
"aria-label": ariaLabel,
|
|
40
|
+
"data-slot": "root",
|
|
41
|
+
className: s.root({ class: [className, classNames?.root] }),
|
|
42
|
+
children: /* @__PURE__ */ jsxs("ul", {
|
|
43
|
+
"data-slot": "list",
|
|
44
|
+
className: s.list({ class: classNames?.list }),
|
|
45
|
+
children: [
|
|
46
|
+
/* @__PURE__ */ jsx("li", {
|
|
47
|
+
className: "flex",
|
|
48
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
49
|
+
"data-slot": "prev",
|
|
50
|
+
"aria-label": "前のページ",
|
|
51
|
+
isDisabled: isDisabled || current <= 1,
|
|
52
|
+
onPress: () => go(current - 1),
|
|
53
|
+
className: s.prev({ class: classNames?.prev }),
|
|
54
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
55
|
+
"aria-hidden": "true",
|
|
56
|
+
children: "‹"
|
|
57
|
+
})
|
|
58
|
+
})
|
|
59
|
+
}),
|
|
60
|
+
entries.map(({ slot, key }) => slot === "ellipsis" ? /* @__PURE__ */ jsx("li", {
|
|
61
|
+
"data-slot": "ellipsis",
|
|
62
|
+
"aria-hidden": "true",
|
|
63
|
+
className: s.ellipsis({ class: classNames?.ellipsis }),
|
|
64
|
+
children: "…"
|
|
65
|
+
}, key) : /* @__PURE__ */ jsx("li", {
|
|
66
|
+
className: "flex",
|
|
67
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
68
|
+
"data-slot": "item",
|
|
69
|
+
"aria-label": `${slot}ページ`,
|
|
70
|
+
"aria-current": slot === current ? "page" : void 0,
|
|
71
|
+
isDisabled,
|
|
72
|
+
onPress: () => go(slot),
|
|
73
|
+
className: s.item({ class: classNames?.item }),
|
|
74
|
+
children: slot
|
|
75
|
+
})
|
|
76
|
+
}, key)),
|
|
77
|
+
/* @__PURE__ */ jsx("li", {
|
|
78
|
+
className: "flex",
|
|
79
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
80
|
+
"data-slot": "next",
|
|
81
|
+
"aria-label": "次のページ",
|
|
82
|
+
isDisabled: isDisabled || current >= total,
|
|
83
|
+
onPress: () => go(current + 1),
|
|
84
|
+
className: s.next({ class: classNames?.next }),
|
|
85
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
86
|
+
"aria-hidden": "true",
|
|
87
|
+
children: "›"
|
|
88
|
+
})
|
|
89
|
+
})
|
|
90
|
+
})
|
|
91
|
+
]
|
|
92
|
+
})
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
export { Pagination };
|
|
97
|
+
|
|
98
|
+
//# sourceMappingURL=pagination.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.mjs","names":[],"sources":["../../src/pagination/pagination.tsx"],"sourcesContent":["'use client'\n\nimport type { PaginationProps } from '@novi-ui/core'\nimport { paginationRange } from '@novi-ui/core/client'\nimport { useState } from 'react'\nimport { Button } from 'react-aria-components'\nimport { paginationStyles } from './pagination.styles'\n\n/**\n * 一覧のページを移動する。**罫線で区切った 1 本の帯**に数字を並べ、現在地は反転させる\n * (Raster は数字だけを並べ、Tactile は面を塗る)。前後は `‹` `›` の活字。\n *\n * @example\n * <Pagination total={10} page={page} onChange={setPage} />\n */\nexport function Pagination({\n size,\n radius,\n total,\n page,\n defaultPage = 1,\n onChange,\n siblingCount,\n boundaryCount,\n isDisabled,\n 'aria-label': ariaLabel = 'ページ送り',\n className,\n classNames,\n id,\n}: PaginationProps) {\n const s = paginationStyles({ size, radius })\n const [internal, setInternal] = useState(defaultPage)\n const clamp = (n: number) => Math.min(Math.max(n, 1), Math.max(total, 1))\n const current = clamp(page ?? internal)\n\n const go = (n: number) => {\n const next = clamp(n)\n if (next === current) return\n if (page === undefined) setInternal(next)\n onChange?.(next)\n }\n\n // 省略記号は最大 2 つ出る。配列の添字ではなく「どの数字の直後か」で区別する\n const slots = paginationRange(current, total, { siblingCount, boundaryCount })\n const entries = slots.map((slot, i) => ({\n slot,\n key: slot === 'ellipsis' ? `ellipsis-after-${slots[i - 1]}` : `page-${slot}`,\n }))\n\n return (\n <nav\n id={id}\n aria-label={ariaLabel}\n data-slot=\"root\"\n className={s.root({ class: [className, classNames?.root] })}\n >\n <ul data-slot=\"list\" className={s.list({ class: classNames?.list })}>\n <li className=\"flex\">\n <Button\n data-slot=\"prev\"\n aria-label=\"前のページ\"\n isDisabled={isDisabled || current <= 1}\n onPress={() => go(current - 1)}\n className={s.prev({ class: classNames?.prev })}\n >\n <span aria-hidden=\"true\">‹</span>\n </Button>\n </li>\n\n {entries.map(({ slot, key }) =>\n slot === 'ellipsis' ? (\n <li\n key={key}\n data-slot=\"ellipsis\"\n aria-hidden=\"true\"\n className={s.ellipsis({ class: classNames?.ellipsis })}\n >\n …\n </li>\n ) : (\n <li key={key} className=\"flex\">\n <Button\n data-slot=\"item\"\n aria-label={`${slot}ページ`}\n aria-current={slot === current ? 'page' : undefined}\n isDisabled={isDisabled}\n onPress={() => go(slot)}\n className={s.item({ class: classNames?.item })}\n >\n {slot}\n </Button>\n </li>\n ),\n )}\n\n <li className=\"flex\">\n <Button\n data-slot=\"next\"\n aria-label=\"次のページ\"\n isDisabled={isDisabled || current >= total}\n onPress={() => go(current + 1)}\n className={s.next({ class: classNames?.next })}\n >\n <span aria-hidden=\"true\">›</span>\n </Button>\n </li>\n </ul>\n </nav>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;AAeA,SAAgB,WAAW,EACzB,MACA,QACA,OACA,MACA,cAAc,GACd,UACA,cACA,eACA,YACA,cAAc,YAAY,SAC1B,WACA,YACA,MACkB;CAClB,MAAM,IAAI,iBAAiB;EAAE;EAAM;CAAO,CAAC;CAC3C,MAAM,CAAC,UAAU,eAAe,SAAS,WAAW;CACpD,MAAM,SAAS,MAAc,KAAK,IAAI,KAAK,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,OAAO,CAAC,CAAC;CACxE,MAAM,UAAU,MAAM,QAAQ,QAAQ;CAEtC,MAAM,MAAM,MAAc;EACxB,MAAM,OAAO,MAAM,CAAC;EACpB,IAAI,SAAS,SAAS;EACtB,IAAI,SAAS,KAAA,GAAW,YAAY,IAAI;EACxC,WAAW,IAAI;CACjB;CAGA,MAAM,QAAQ,gBAAgB,SAAS,OAAO;EAAE;EAAc;CAAc,CAAC;CAC7E,MAAM,UAAU,MAAM,KAAK,MAAM,OAAO;EACtC;EACA,KAAK,SAAS,aAAa,kBAAkB,MAAM,IAAI,OAAO,QAAQ;CACxE,EAAE;CAEF,OACE,oBAAC,OAAD;EACM;EACJ,cAAY;EACZ,aAAU;EACV,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,YAAY,IAAI,EAAE,CAAC;EAE1D,UAAA,qBAAC,MAAD;GAAI,aAAU;GAAO,WAAW,EAAE,KAAK,EAAE,OAAO,YAAY,KAAK,CAAC;GAAlE,UAAA;IACE,oBAAC,MAAD;KAAI,WAAU;KACZ,UAAA,oBAAC,QAAD;MACE,aAAU;MACV,cAAW;MACX,YAAY,cAAc,WAAW;MACrC,eAAe,GAAG,UAAU,CAAC;MAC7B,WAAW,EAAE,KAAK,EAAE,OAAO,YAAY,KAAK,CAAC;MAE7C,UAAA,oBAAC,QAAD;OAAM,eAAY;OAAO,UAAA;MAAO,CAAA;KAC1B,CAAA;IACN,CAAA;IAEH,QAAQ,KAAK,EAAE,MAAM,UACpB,SAAS,aACP,oBAAC,MAAD;KAEE,aAAU;KACV,eAAY;KACZ,WAAW,EAAE,SAAS,EAAE,OAAO,YAAY,SAAS,CAAC;KACtD,UAAA;IAEG,GANG,GAMH,IAEJ,oBAAC,MAAD;KAAc,WAAU;KACtB,UAAA,oBAAC,QAAD;MACE,aAAU;MACV,cAAY,GAAG,KAAK;MACpB,gBAAc,SAAS,UAAU,SAAS,KAAA;MAC9B;MACZ,eAAe,GAAG,IAAI;MACtB,WAAW,EAAE,KAAK,EAAE,OAAO,YAAY,KAAK,CAAC;MAE5C,UAAA;KACK,CAAA;IACN,GAXK,GAWL,CAER;IAEA,oBAAC,MAAD;KAAI,WAAU;KACZ,UAAA,oBAAC,QAAD;MACE,aAAU;MACV,cAAW;MACX,YAAY,cAAc,WAAW;MACrC,eAAe,GAAG,UAAU,CAAC;MAC7B,WAAW,EAAE,KAAK,EAAE,OAAO,YAAY,KAAK,CAAC;MAE7C,UAAA,oBAAC,QAAD;OAAM,eAAY;OAAO,UAAA;MAAO,CAAA;KAC1B,CAAA;IACN,CAAA;GACF;;CACD,CAAA;AAET"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { VariantMap } from "@novi-ui/core";
|
|
2
|
+
//#region src/pagination/pagination.styles.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Pagination のスタイル定義。
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* import { paginationStyles } from '@novi-ui/flatlay'
|
|
8
|
+
* import { tv } from 'tailwind-variants'
|
|
9
|
+
*
|
|
10
|
+
* const myPagination = tv({ extend: paginationStyles, slots: { item: 'min-w-10' } })
|
|
11
|
+
*/
|
|
12
|
+
declare const paginationStyles: import("tailwind-variants").TVReturnType<{
|
|
13
|
+
size: VariantMap<"sm" | "md" | "lg", {
|
|
14
|
+
item: string;
|
|
15
|
+
prev: string;
|
|
16
|
+
next: string;
|
|
17
|
+
ellipsis: string;
|
|
18
|
+
}>;
|
|
19
|
+
radius: VariantMap<"sm" | "md" | "lg" | "none" | "full", {
|
|
20
|
+
list: string;
|
|
21
|
+
}>;
|
|
22
|
+
}, {
|
|
23
|
+
root: string;
|
|
24
|
+
list: string;
|
|
25
|
+
item: string;
|
|
26
|
+
prev: string;
|
|
27
|
+
next: string;
|
|
28
|
+
ellipsis: string;
|
|
29
|
+
}, undefined, {
|
|
30
|
+
size: VariantMap<"sm" | "md" | "lg", {
|
|
31
|
+
item: string;
|
|
32
|
+
prev: string;
|
|
33
|
+
next: string;
|
|
34
|
+
ellipsis: string;
|
|
35
|
+
}>;
|
|
36
|
+
radius: VariantMap<"sm" | "md" | "lg" | "none" | "full", {
|
|
37
|
+
list: string;
|
|
38
|
+
}>;
|
|
39
|
+
}, {
|
|
40
|
+
root: string;
|
|
41
|
+
list: string;
|
|
42
|
+
item: string;
|
|
43
|
+
prev: string;
|
|
44
|
+
next: string;
|
|
45
|
+
ellipsis: string;
|
|
46
|
+
}, import("tailwind-variants").TVReturnTypeLike<{
|
|
47
|
+
size: VariantMap<"sm" | "md" | "lg", {
|
|
48
|
+
item: string;
|
|
49
|
+
prev: string;
|
|
50
|
+
next: string;
|
|
51
|
+
ellipsis: string;
|
|
52
|
+
}>;
|
|
53
|
+
radius: VariantMap<"sm" | "md" | "lg" | "none" | "full", {
|
|
54
|
+
list: string;
|
|
55
|
+
}>;
|
|
56
|
+
}, {
|
|
57
|
+
root: string;
|
|
58
|
+
list: string;
|
|
59
|
+
item: string;
|
|
60
|
+
prev: string;
|
|
61
|
+
next: string;
|
|
62
|
+
ellipsis: string;
|
|
63
|
+
}>>;
|
|
64
|
+
type PaginationStyleProps = Parameters<typeof paginationStyles>[0];
|
|
65
|
+
//#endregion
|
|
66
|
+
export { PaginationStyleProps, paginationStyles };
|
|
67
|
+
//# sourceMappingURL=pagination.styles.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.styles.d.mts","names":[],"sources":["../../src/pagination/pagination.styles.ts"],"mappings":";;;;;;;;;;;cAqFa,8CAAgB;;IAvCY;IAAc;IAAc;IAAkB;;;IAsB1C;;;;;;;;;;;IAtBJ;IAAc;IAAc;IAAkB;;;IAsB1C;;;;;;;;;;;IAtBJ;IAAc;IAAc;IAAkB;;;IAsB1C;;;;;;;;;;KAuBjC,uBAAuB,kBAAkB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { disabledState, focusRing } from "../styles/focus-ring.mjs";
|
|
2
|
+
import { monoNumeric } from "../styles/mono.mjs";
|
|
3
|
+
import { tv } from "tailwind-variants";
|
|
4
|
+
//#region src/pagination/pagination.styles.ts
|
|
5
|
+
/**
|
|
6
|
+
* ページ番号と前後のボタンに共通のセル。**罫線で区切った 1 本の帯**に並び、
|
|
7
|
+
* 現在地は反転(スタンプ)。押した瞬間も反転する(ADR-F3)。
|
|
8
|
+
* 数字は等幅で、帳票のページ番号と同じ字形(ADR-F7)。
|
|
9
|
+
*/
|
|
10
|
+
const cell = [
|
|
11
|
+
"inline-flex items-center justify-center",
|
|
12
|
+
`text-[var(--novi-color-fg)] ${monoNumeric}`,
|
|
13
|
+
"outline-none",
|
|
14
|
+
"hover:bg-[var(--novi-color-subtle)]",
|
|
15
|
+
"data-[pressed]:bg-[var(--novi-color-fg)] data-[pressed]:text-[var(--novi-color-bg)]",
|
|
16
|
+
"aria-[current=page]:bg-[var(--novi-color-fg)] aria-[current=page]:text-[var(--novi-color-bg)]",
|
|
17
|
+
"transition-[background-color,color]",
|
|
18
|
+
"duration-[var(--novi-duration-fast)] ease-[var(--novi-ease-standard)]",
|
|
19
|
+
focusRing,
|
|
20
|
+
disabledState
|
|
21
|
+
].join(" ");
|
|
22
|
+
const slots = {
|
|
23
|
+
root: "inline-flex",
|
|
24
|
+
list: [
|
|
25
|
+
"flex items-stretch list-none m-0 p-0",
|
|
26
|
+
"border border-[var(--novi-color-border-strong)]",
|
|
27
|
+
"divide-x divide-[var(--novi-color-border)]",
|
|
28
|
+
"overflow-hidden"
|
|
29
|
+
].join(" "),
|
|
30
|
+
item: cell,
|
|
31
|
+
prev: cell,
|
|
32
|
+
next: cell,
|
|
33
|
+
ellipsis: `inline-flex items-center justify-center text-[var(--novi-color-muted)] select-none ${monoNumeric}`
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Pagination のスタイル定義。
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* import { paginationStyles } from '@novi-ui/flatlay'
|
|
40
|
+
* import { tv } from 'tailwind-variants'
|
|
41
|
+
*
|
|
42
|
+
* const myPagination = tv({ extend: paginationStyles, slots: { item: 'min-w-10' } })
|
|
43
|
+
*/
|
|
44
|
+
const paginationStyles = tv({
|
|
45
|
+
slots,
|
|
46
|
+
variants: {
|
|
47
|
+
size: {
|
|
48
|
+
sm: {
|
|
49
|
+
item: "h-7 min-w-7 px-1.5 text-[length:var(--novi-text-sm)]",
|
|
50
|
+
prev: "h-7 min-w-7 px-1.5 text-[length:var(--novi-text-sm)]",
|
|
51
|
+
next: "h-7 min-w-7 px-1.5 text-[length:var(--novi-text-sm)]",
|
|
52
|
+
ellipsis: "h-7 min-w-7 text-[length:var(--novi-text-sm)]"
|
|
53
|
+
},
|
|
54
|
+
md: {
|
|
55
|
+
item: "h-8 min-w-8 px-1.5 text-[length:var(--novi-text-base)]",
|
|
56
|
+
prev: "h-8 min-w-8 px-1.5 text-[length:var(--novi-text-base)]",
|
|
57
|
+
next: "h-8 min-w-8 px-1.5 text-[length:var(--novi-text-base)]",
|
|
58
|
+
ellipsis: "h-8 min-w-8 text-[length:var(--novi-text-base)]"
|
|
59
|
+
},
|
|
60
|
+
lg: {
|
|
61
|
+
item: "h-10 min-w-10 px-[var(--novi-pad-control-x-sm)] text-[length:var(--novi-text-base)]",
|
|
62
|
+
prev: "h-10 min-w-10 px-[var(--novi-pad-control-x-sm)] text-[length:var(--novi-text-base)]",
|
|
63
|
+
next: "h-10 min-w-10 px-[var(--novi-pad-control-x-sm)] text-[length:var(--novi-text-base)]",
|
|
64
|
+
ellipsis: "h-10 min-w-10 text-[length:var(--novi-text-base)]"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
radius: {
|
|
68
|
+
none: { list: "rounded-[var(--novi-radius-none)]" },
|
|
69
|
+
sm: { list: "rounded-[var(--novi-radius-sm)]" },
|
|
70
|
+
md: { list: "rounded-[var(--novi-radius-md)]" },
|
|
71
|
+
lg: { list: "rounded-[var(--novi-radius-lg)]" },
|
|
72
|
+
full: { list: "rounded-[var(--novi-radius-full)]" }
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
defaultVariants: {
|
|
76
|
+
size: "md",
|
|
77
|
+
radius: "sm"
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
//#endregion
|
|
81
|
+
export { paginationStyles };
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=pagination.styles.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.styles.mjs","names":[],"sources":["../../src/pagination/pagination.styles.ts"],"sourcesContent":["import type {\n NoviRadius,\n NoviSize,\n paginationRequiredSlots,\n paginationSlots,\n SlotMap,\n VariantMap,\n} from '@novi-ui/core'\nimport { tv } from 'tailwind-variants'\nimport { disabledState, focusRing } from '../styles/focus-ring'\nimport { monoNumeric } from '../styles/mono'\n\n/**\n * ページ番号と前後のボタンに共通のセル。**罫線で区切った 1 本の帯**に並び、\n * 現在地は反転(スタンプ)。押した瞬間も反転する(ADR-F3)。\n * 数字は等幅で、帳票のページ番号と同じ字形(ADR-F7)。\n */\nconst cell = [\n 'inline-flex items-center justify-center',\n `text-[var(--novi-color-fg)] ${monoNumeric}`,\n 'outline-none',\n 'hover:bg-[var(--novi-color-subtle)]',\n 'data-[pressed]:bg-[var(--novi-color-fg)] data-[pressed]:text-[var(--novi-color-bg)]',\n 'aria-[current=page]:bg-[var(--novi-color-fg)] aria-[current=page]: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\nconst slots = {\n root: 'inline-flex',\n // 帯そのものが枠。行の切れ目は縦の罫線\n list: [\n 'flex items-stretch list-none m-0 p-0',\n 'border border-[var(--novi-color-border-strong)]',\n 'divide-x divide-[var(--novi-color-border)]',\n 'overflow-hidden',\n ].join(' '),\n item: cell,\n prev: cell,\n next: cell,\n ellipsis: `inline-flex items-center justify-center text-[var(--novi-color-muted)] select-none ${monoNumeric}`,\n} satisfies SlotMap<typeof paginationSlots, (typeof paginationRequiredSlots)[number]>\n\n/** 高さは行の階級に載せる。28 / 32 / 40px */\nconst size: VariantMap<NoviSize, { item: string; prev: string; next: string; ellipsis: string }> = {\n sm: {\n item: 'h-7 min-w-7 px-1.5 text-[length:var(--novi-text-sm)]',\n prev: 'h-7 min-w-7 px-1.5 text-[length:var(--novi-text-sm)]',\n next: 'h-7 min-w-7 px-1.5 text-[length:var(--novi-text-sm)]',\n ellipsis: 'h-7 min-w-7 text-[length:var(--novi-text-sm)]',\n },\n md: {\n item: 'h-8 min-w-8 px-1.5 text-[length:var(--novi-text-base)]',\n prev: 'h-8 min-w-8 px-1.5 text-[length:var(--novi-text-base)]',\n next: 'h-8 min-w-8 px-1.5 text-[length:var(--novi-text-base)]',\n ellipsis: 'h-8 min-w-8 text-[length:var(--novi-text-base)]',\n },\n lg: {\n item: 'h-10 min-w-10 px-[var(--novi-pad-control-x-sm)] text-[length:var(--novi-text-base)]',\n prev: 'h-10 min-w-10 px-[var(--novi-pad-control-x-sm)] text-[length:var(--novi-text-base)]',\n next: 'h-10 min-w-10 px-[var(--novi-pad-control-x-sm)] text-[length:var(--novi-text-base)]',\n ellipsis: 'h-10 min-w-10 text-[length:var(--novi-text-base)]',\n },\n}\n\n// 角丸は帯(list)だけが持つ。セルは隣と罫線で接しているので角を持たない\nconst radius: VariantMap<NoviRadius, { list: string }> = {\n none: { list: 'rounded-[var(--novi-radius-none)]' },\n sm: { list: 'rounded-[var(--novi-radius-sm)]' },\n md: { list: 'rounded-[var(--novi-radius-md)]' },\n lg: { list: 'rounded-[var(--novi-radius-lg)]' },\n full: { list: 'rounded-[var(--novi-radius-full)]' },\n}\n\n/**\n * Pagination のスタイル定義。\n *\n * @example\n * import { paginationStyles } from '@novi-ui/flatlay'\n * import { tv } from 'tailwind-variants'\n *\n * const myPagination = tv({ extend: paginationStyles, slots: { item: 'min-w-10' } })\n */\nexport const paginationStyles = tv({\n slots,\n variants: { size, radius },\n defaultVariants: { size: 'md', radius: 'sm' },\n})\n\nexport type PaginationStyleProps = Parameters<typeof paginationStyles>[0]\n"],"mappings":";;;;;;;;;AAiBA,MAAM,OAAO;CACX;CACA,+BAA+B;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC,CAAC,KAAK,GAAG;AAEV,MAAM,QAAQ;CACZ,MAAM;CAEN,MAAM;EACJ;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CACV,MAAM;CACN,MAAM;CACN,MAAM;CACN,UAAU,sFAAsF;AAClG;;;;;;;;;;AA0CA,MAAa,mBAAmB,GAAG;CACjC;CACA,UAAU;EAAE;GAxCZ,IAAI;IACF,MAAM;IACN,MAAM;IACN,MAAM;IACN,UAAU;GACZ;GACA,IAAI;IACF,MAAM;IACN,MAAM;IACN,MAAM;IACN,UAAU;GACZ;GACA,IAAI;IACF,MAAM;IACN,MAAM;IACN,MAAM;IACN,UAAU;GACZ;EAuBY;EAAM;GAlBlB,MAAM,EAAE,MAAM,oCAAoC;GAClD,IAAI,EAAE,MAAM,kCAAkC;GAC9C,IAAI,EAAE,MAAM,kCAAkC;GAC9C,IAAI,EAAE,MAAM,kCAAkC;GAC9C,MAAM,EAAE,MAAM,oCAAoC;EAchC;CAAO;CACzB,iBAAiB;EAAE,MAAM;EAAM,QAAQ;CAAK;AAC9C,CAAC"}
|
package/dist/select/select.d.mts
CHANGED
|
@@ -26,7 +26,7 @@ declare function SelectItem({ id, isDisabled, children, className }: SelectItemP
|
|
|
26
26
|
* 矢印キーで移動、Escape で閉じてトリガーへフォーカスが戻る。
|
|
27
27
|
*
|
|
28
28
|
* トリガーは `<button>` で編集可能要素ではないため IME の変換は発生しない。
|
|
29
|
-
* テキスト入力を伴う選択が必要な場合は ComboBox
|
|
29
|
+
* テキスト入力を伴う選択が必要な場合は ComboBox を使う。
|
|
30
30
|
*
|
|
31
31
|
* @example
|
|
32
32
|
* <Select label="都道府県" selectedKey={pref} onSelectionChange={setPref}>
|
package/dist/select/select.mjs
CHANGED
|
@@ -38,7 +38,7 @@ function SelectItem({ id, isDisabled, children, className }) {
|
|
|
38
38
|
* 矢印キーで移動、Escape で閉じてトリガーへフォーカスが戻る。
|
|
39
39
|
*
|
|
40
40
|
* トリガーは `<button>` で編集可能要素ではないため IME の変換は発生しない。
|
|
41
|
-
* テキスト入力を伴う選択が必要な場合は ComboBox
|
|
41
|
+
* テキスト入力を伴う選択が必要な場合は ComboBox を使う。
|
|
42
42
|
*
|
|
43
43
|
* @example
|
|
44
44
|
* <Select label="都道府県" selectedKey={pref} onSelectionChange={setPref}>
|
|
@@ -1 +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
|
|
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 を使う。\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,3 @@
|
|
|
1
|
+
import { Table, TableBody, TableBodyProps, TableCell, TableCellProps, TableColumn, TableColumnProps, TableHeader, TableHeaderProps, TableRow, TableRowProps } from "./table.mjs";
|
|
2
|
+
import { TableStyleProps, tableStyles } from "./table.styles.mjs";
|
|
3
|
+
export { Table, TableBody, type TableBodyProps, TableCell, type TableCellProps, TableColumn, type TableColumnProps, TableHeader, type TableHeaderProps, TableRow, type TableRowProps, type TableStyleProps, tableStyles };
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import { TableProps } from "@novi-ui/core";
|
|
3
|
+
//#region src/table/table.d.ts
|
|
4
|
+
interface TableHeaderProps {
|
|
5
|
+
children?: ReactNode;
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 見出し行。`TableColumn` を並べる。
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* <TableHeader>
|
|
13
|
+
* <TableColumn id="name" isRowHeader>商品名</TableColumn>
|
|
14
|
+
* </TableHeader>
|
|
15
|
+
*/
|
|
16
|
+
declare function TableHeader({ children, className }: TableHeaderProps): import("react").JSX.Element;
|
|
17
|
+
interface TableColumnProps {
|
|
18
|
+
/** 列の id。`sortDescriptor.column` に入る */
|
|
19
|
+
id: string;
|
|
20
|
+
/** この列で並べ替えられる。見出しが押せるようになり `aria-sort` が付く */
|
|
21
|
+
allowsSorting?: boolean;
|
|
22
|
+
/** 行の名前になる列。少なくとも 1 列に付ける */
|
|
23
|
+
isRowHeader?: boolean;
|
|
24
|
+
/** 金額や数量は `end`(右寄せ) */
|
|
25
|
+
align?: 'start' | 'end';
|
|
26
|
+
children?: ReactNode;
|
|
27
|
+
className?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 見出しのセル。
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* <TableColumn id="amount" allowsSorting align="end">金額</TableColumn>
|
|
34
|
+
*/
|
|
35
|
+
declare function TableColumn({ id, allowsSorting, isRowHeader, align, children, className }: TableColumnProps): import("react").JSX.Element;
|
|
36
|
+
interface TableBodyProps {
|
|
37
|
+
children?: ReactNode;
|
|
38
|
+
/** 行が 0 件のときに本体へ出す内容 */
|
|
39
|
+
renderEmptyState?: () => ReactNode;
|
|
40
|
+
className?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* 本体。`TableRow` を並べる。行が無いときは `renderEmptyState` の内容が出る。
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* <TableBody renderEmptyState={() => '該当する注文はありません'}>
|
|
47
|
+
* {rows}
|
|
48
|
+
* </TableBody>
|
|
49
|
+
*/
|
|
50
|
+
declare function TableBody({ children, renderEmptyState, className }: TableBodyProps): import("react").JSX.Element;
|
|
51
|
+
interface TableRowProps {
|
|
52
|
+
/** 行の id。選択と `onRowAction` に渡る */
|
|
53
|
+
id: string;
|
|
54
|
+
isDisabled?: boolean;
|
|
55
|
+
children?: ReactNode;
|
|
56
|
+
className?: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* 行。`TableCell` を列の数だけ並べる。
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* <TableRow id="1042">
|
|
63
|
+
* <TableCell>#1042</TableCell>
|
|
64
|
+
* </TableRow>
|
|
65
|
+
*/
|
|
66
|
+
declare function TableRow({ id, isDisabled, children, className }: TableRowProps): import("react").JSX.Element;
|
|
67
|
+
interface TableCellProps {
|
|
68
|
+
/** 金額や数量は `end`(右寄せ)。見出しと揃える */
|
|
69
|
+
align?: 'start' | 'end';
|
|
70
|
+
children?: ReactNode;
|
|
71
|
+
className?: string;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* セル。
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* <TableCell align="end">¥12,800</TableCell>
|
|
78
|
+
*/
|
|
79
|
+
declare function TableCell({ align, children, className }: TableCellProps): import("react").JSX.Element;
|
|
80
|
+
/**
|
|
81
|
+
* 一覧を行と列で見せる。**縦横の罫線で升目を切った帳票**。見出しは等幅、数字は等幅の右詰め
|
|
82
|
+
* (Raster は横罫だけ、Tactile は行が面)。
|
|
83
|
+
*
|
|
84
|
+
* 行の選択は行そのものを押す(チェックボックスは出さない)。
|
|
85
|
+
* 狭い画面では表そのものが横にスクロールする。`overflow-x-auto` の枠で包むこと。
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* <Table aria-label="注文一覧" sortDescriptor={sort} onSortChange={setSort}>
|
|
89
|
+
* <TableHeader>
|
|
90
|
+
* <TableColumn id="no" isRowHeader>注文番号</TableColumn>
|
|
91
|
+
* <TableColumn id="amount" allowsSorting align="end">金額</TableColumn>
|
|
92
|
+
* </TableHeader>
|
|
93
|
+
* <TableBody>
|
|
94
|
+
* <TableRow id="1042">
|
|
95
|
+
* <TableCell>#1042</TableCell>
|
|
96
|
+
* <TableCell align="end">¥12,800</TableCell>
|
|
97
|
+
* </TableRow>
|
|
98
|
+
* </TableBody>
|
|
99
|
+
* </Table>
|
|
100
|
+
*/
|
|
101
|
+
declare function Table({ 'aria-label': ariaLabel, size, sortDescriptor, onSortChange, selectionMode, selectedKeys, defaultSelectedKeys, onSelectionChange, disabledKeys, onRowAction, children, className, classNames }: TableProps): import("react").JSX.Element;
|
|
102
|
+
//#endregion
|
|
103
|
+
export { Table, TableBody, TableBodyProps, TableCell, TableCellProps, TableColumn, TableColumnProps, TableHeader, TableHeaderProps, TableRow, TableRowProps };
|
|
104
|
+
//# sourceMappingURL=table.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.d.mts","names":[],"sources":["../../src/table/table.tsx"],"mappings":";;;UAkCiB;EACf,WAAW;EACX;;;;;;;;;;iBAWc,cAAc,UAAU,aAAa,mCAAgB,IAAA;UAYpD;;EAEf;;EAEA;;EAEA;;EAEA;EACA,WAAW;EACX;;;;;;;;iBASc,cACd,IACA,eACA,aACA,OACA,UACA,aACC,mCAAgB,IAAA;UAwBF;EACf,WAAW;;EAEX,yBAAyB;EACzB;;;;;;;;;;iBAWc,YAAY,UAAU,kBAAkB,aAAa,iCAAc,IAAA;UAqBlE;;EAEf;EACA;EACA,WAAW;EACX;;;;;;;;;;iBAWc,WAAW,IAAI,YAAY,UAAU,aAAa,gCAAa,IAAA;UAc9D;;EAEf;EACA,WAAW;EACX;;;;;;;;iBASc,YAAY,OAAiB,UAAU,aAAa,iCAAc,IAAA;;;;;;;;;;;;;;;;;;;;;;iBAmClE,sBACA,WACd,MACA,gBACA,cACA,eACA,cACA,qBACA,mBACA,cACA,aACA,UACA,WACA,cACC,6BAAU,IAAA"}
|