@novi-ui/tactile 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +3 -0
- package/dist/combo-box/combo-box.d.mts +34 -0
- package/dist/combo-box/combo-box.d.mts.map +1 -0
- package/dist/combo-box/combo-box.mjs +127 -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 +115 -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 +162 -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 +134 -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 +117 -0
- package/dist/number-field/number-field.mjs.map +1 -0
- package/dist/number-field/number-field.styles.d.mts +76 -0
- package/dist/number-field/number-field.styles.d.mts.map +1 -0
- package/dist/number-field/number-field.styles.mjs +96 -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 +14 -0
- package/dist/pagination/pagination.d.mts.map +1 -0
- package/dist/pagination/pagination.mjs +100 -0
- package/dist/pagination/pagination.mjs.map +1 -0
- package/dist/pagination/pagination.styles.d.mts +73 -0
- package/dist/pagination/pagination.styles.d.mts.map +1 -0
- package/dist/pagination/pagination.styles.mjs +100 -0
- package/dist/pagination/pagination.styles.mjs.map +1 -0
- package/dist/popover/popover.styles.d.mts +3 -3
- 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 +172 -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 +83 -0
- package/dist/table/table.styles.mjs.map +1 -0
- package/package.json +8 -6
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { alignEndClass, tableStyles } from "./table.styles.mjs";
|
|
3
|
+
import { Cell, Column, Row, Table, TableBody, TableHeader } from "react-aria-components";
|
|
4
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { createContext, useContext } from "react";
|
|
6
|
+
//#region src/table/table.tsx
|
|
7
|
+
/**
|
|
8
|
+
* 表の中の部品が size と classNames を受け取るための経路。
|
|
9
|
+
* 利用者向けの Provider ではなく、Table の内側だけで閉じる。
|
|
10
|
+
*/
|
|
11
|
+
const TableContext = createContext({ s: tableStyles() });
|
|
12
|
+
function SortIcon({ direction }) {
|
|
13
|
+
const d = direction === "ascending" ? "M8 4l4 5H4z" : direction === "descending" ? "M8 12L4 7h8z" : "";
|
|
14
|
+
return /* @__PURE__ */ jsx("svg", {
|
|
15
|
+
viewBox: "0 0 16 16",
|
|
16
|
+
width: "1em",
|
|
17
|
+
height: "1em",
|
|
18
|
+
fill: "currentColor",
|
|
19
|
+
"aria-hidden": "true",
|
|
20
|
+
children: d === "" ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("path", { d: "M8 3l3 3.5H5z" }), /* @__PURE__ */ jsx("path", { d: "M8 13l-3-3.5h6z" })] }) : /* @__PURE__ */ jsx("path", { d })
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 見出し行。`TableColumn` を並べる。
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* <TableHeader>
|
|
28
|
+
* <TableColumn id="name" isRowHeader>商品名</TableColumn>
|
|
29
|
+
* </TableHeader>
|
|
30
|
+
*/
|
|
31
|
+
function TableHeader$1({ children, className }) {
|
|
32
|
+
const { s, classNames } = useContext(TableContext);
|
|
33
|
+
return /* @__PURE__ */ jsx(TableHeader, {
|
|
34
|
+
"data-slot": "header",
|
|
35
|
+
className: s.header({ class: [className, classNames?.header] }),
|
|
36
|
+
children
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 見出しのセル。
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* <TableColumn id="amount" allowsSorting align="end">金額</TableColumn>
|
|
44
|
+
*/
|
|
45
|
+
function TableColumn({ id, allowsSorting, isRowHeader, align = "start", children, className }) {
|
|
46
|
+
const { s, classNames } = useContext(TableContext);
|
|
47
|
+
return /* @__PURE__ */ jsx(Column, {
|
|
48
|
+
id,
|
|
49
|
+
allowsSorting,
|
|
50
|
+
isRowHeader,
|
|
51
|
+
"data-slot": "column",
|
|
52
|
+
className: `group ${s.column({ class: [
|
|
53
|
+
align === "end" ? alignEndClass : "",
|
|
54
|
+
className,
|
|
55
|
+
classNames?.column
|
|
56
|
+
] })}`,
|
|
57
|
+
children: ({ sortDirection }) => /* @__PURE__ */ jsxs(Fragment, { children: [children, allowsSorting && /* @__PURE__ */ jsx("span", {
|
|
58
|
+
"data-slot": "sortIcon",
|
|
59
|
+
className: s.sortIcon({ class: classNames?.sortIcon }),
|
|
60
|
+
children: /* @__PURE__ */ jsx(SortIcon, { direction: sortDirection })
|
|
61
|
+
})] })
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 本体。`TableRow` を並べる。行が無いときは `renderEmptyState` の内容が出る。
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* <TableBody renderEmptyState={() => '該当する注文はありません'}>
|
|
69
|
+
* {rows}
|
|
70
|
+
* </TableBody>
|
|
71
|
+
*/
|
|
72
|
+
function TableBody$1({ children, renderEmptyState, className }) {
|
|
73
|
+
const { s, classNames } = useContext(TableContext);
|
|
74
|
+
return /* @__PURE__ */ jsx(TableBody, {
|
|
75
|
+
"data-slot": "body",
|
|
76
|
+
className: s.body({ class: [className, classNames?.body] }),
|
|
77
|
+
renderEmptyState: renderEmptyState === void 0 ? void 0 : () => /* @__PURE__ */ jsx("div", {
|
|
78
|
+
"data-slot": "empty",
|
|
79
|
+
className: s.empty({ class: classNames?.empty }),
|
|
80
|
+
children: renderEmptyState()
|
|
81
|
+
}),
|
|
82
|
+
children
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 行。`TableCell` を列の数だけ並べる。
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* <TableRow id="1042">
|
|
90
|
+
* <TableCell>#1042</TableCell>
|
|
91
|
+
* </TableRow>
|
|
92
|
+
*/
|
|
93
|
+
function TableRow({ id, isDisabled, children, className }) {
|
|
94
|
+
const { s, classNames } = useContext(TableContext);
|
|
95
|
+
return /* @__PURE__ */ jsx(Row, {
|
|
96
|
+
id,
|
|
97
|
+
isDisabled,
|
|
98
|
+
"data-slot": "row",
|
|
99
|
+
className: s.row({ class: [className, classNames?.row] }),
|
|
100
|
+
children
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* セル。
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* <TableCell align="end">¥12,800</TableCell>
|
|
108
|
+
*/
|
|
109
|
+
function TableCell({ align = "start", children, className }) {
|
|
110
|
+
const { s, classNames } = useContext(TableContext);
|
|
111
|
+
return /* @__PURE__ */ jsx(Cell, {
|
|
112
|
+
"data-slot": "cell",
|
|
113
|
+
className: s.cell({ class: [
|
|
114
|
+
align === "end" ? alignEndClass : "",
|
|
115
|
+
className,
|
|
116
|
+
classNames?.cell
|
|
117
|
+
] }),
|
|
118
|
+
children
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 一覧を行と列で見せる。**行が指で押せる面**で、40px 以上の高さを持つ
|
|
123
|
+
* (Raster は横罫だけ、Flatlay は縦横の罫線の帳票)。
|
|
124
|
+
*
|
|
125
|
+
* 行の選択は行そのものを押す(チェックボックスは出さない)。
|
|
126
|
+
* 狭い画面では表そのものが横にスクロールする。`overflow-x-auto` の枠で包むこと。
|
|
127
|
+
*
|
|
128
|
+
* @example
|
|
129
|
+
* <Table aria-label="注文一覧" sortDescriptor={sort} onSortChange={setSort}>
|
|
130
|
+
* <TableHeader>
|
|
131
|
+
* <TableColumn id="no" isRowHeader>注文番号</TableColumn>
|
|
132
|
+
* <TableColumn id="amount" allowsSorting align="end">金額</TableColumn>
|
|
133
|
+
* </TableHeader>
|
|
134
|
+
* <TableBody>
|
|
135
|
+
* <TableRow id="1042">
|
|
136
|
+
* <TableCell>#1042</TableCell>
|
|
137
|
+
* <TableCell align="end">¥12,800</TableCell>
|
|
138
|
+
* </TableRow>
|
|
139
|
+
* </TableBody>
|
|
140
|
+
* </Table>
|
|
141
|
+
*/
|
|
142
|
+
function Table$1({ "aria-label": ariaLabel, size, sortDescriptor, onSortChange, selectionMode, selectedKeys, defaultSelectedKeys, onSelectionChange, disabledKeys, onRowAction, children, className, classNames }) {
|
|
143
|
+
const s = tableStyles({ size });
|
|
144
|
+
return /* @__PURE__ */ jsx(TableContext.Provider, {
|
|
145
|
+
value: {
|
|
146
|
+
s,
|
|
147
|
+
classNames
|
|
148
|
+
},
|
|
149
|
+
children: /* @__PURE__ */ jsx(Table, {
|
|
150
|
+
"aria-label": ariaLabel,
|
|
151
|
+
sortDescriptor,
|
|
152
|
+
onSortChange: (d) => onSortChange?.({
|
|
153
|
+
column: String(d.column),
|
|
154
|
+
direction: d.direction
|
|
155
|
+
}),
|
|
156
|
+
selectionMode,
|
|
157
|
+
selectionBehavior: "replace",
|
|
158
|
+
selectedKeys,
|
|
159
|
+
defaultSelectedKeys,
|
|
160
|
+
onSelectionChange: (keys) => onSelectionChange?.(keys === "all" ? "all" : new Set([...keys].map(String))),
|
|
161
|
+
disabledKeys,
|
|
162
|
+
onRowAction: onRowAction === void 0 ? void 0 : (key) => onRowAction(String(key)),
|
|
163
|
+
"data-slot": "root",
|
|
164
|
+
className: s.root({ class: [className, classNames?.root] }),
|
|
165
|
+
children
|
|
166
|
+
})
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
//#endregion
|
|
170
|
+
export { Table$1 as Table, TableBody$1 as TableBody, TableCell, TableColumn, TableHeader$1 as TableHeader, TableRow };
|
|
171
|
+
|
|
172
|
+
//# sourceMappingURL=table.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.mjs","names":["TableHeader","RACTableHeader","TableBody","RACTableBody","Table","RACTable"],"sources":["../../src/table/table.tsx"],"sourcesContent":["'use client'\n\nimport type { TableProps, TableSortDescriptor } from '@novi-ui/core'\nimport { createContext, type ReactNode, useContext } from 'react'\nimport {\n Cell,\n Column,\n Table as RACTable,\n TableBody as RACTableBody,\n TableHeader as RACTableHeader,\n Row,\n} from 'react-aria-components'\nimport { alignEndClass, tableStyles } from './table.styles'\n\ntype Styles = ReturnType<typeof tableStyles>\ntype SlotClassNames = NonNullable<TableProps['classNames']>\n\n/**\n * 表の中の部品が size と classNames を受け取るための経路。\n * 利用者向けの Provider ではなく、Table の内側だけで閉じる。\n */\nconst TableContext = createContext<{ s: Styles; classNames?: SlotClassNames }>({\n s: tableStyles(),\n})\n\nfunction SortIcon({ direction }: { direction: 'ascending' | 'descending' | undefined }) {\n const d =\n direction === 'ascending' ? 'M8 4l4 5H4z' : direction === 'descending' ? 'M8 12L4 7h8z' : ''\n return (\n <svg viewBox=\"0 0 16 16\" width=\"1em\" height=\"1em\" fill=\"currentColor\" aria-hidden=\"true\">\n {d === '' ? (\n <>\n <path d=\"M8 3l3 3.5H5z\" />\n <path d=\"M8 13l-3-3.5h6z\" />\n </>\n ) : (\n <path d={d} />\n )}\n </svg>\n )\n}\n\nexport interface TableHeaderProps {\n children?: ReactNode\n className?: string\n}\n\n/**\n * 見出し行。`TableColumn` を並べる。\n *\n * @example\n * <TableHeader>\n * <TableColumn id=\"name\" isRowHeader>商品名</TableColumn>\n * </TableHeader>\n */\nexport function TableHeader({ children, className }: TableHeaderProps) {\n const { s, classNames } = useContext(TableContext)\n return (\n <RACTableHeader\n data-slot=\"header\"\n className={s.header({ class: [className, classNames?.header] })}\n >\n {children}\n </RACTableHeader>\n )\n}\n\nexport interface TableColumnProps {\n /** 列の id。`sortDescriptor.column` に入る */\n id: string\n /** この列で並べ替えられる。見出しが押せるようになり `aria-sort` が付く */\n allowsSorting?: boolean\n /** 行の名前になる列。少なくとも 1 列に付ける */\n isRowHeader?: boolean\n /** 金額や数量は `end`(右寄せ) */\n align?: 'start' | 'end'\n children?: ReactNode\n className?: string\n}\n\n/**\n * 見出しのセル。\n *\n * @example\n * <TableColumn id=\"amount\" allowsSorting align=\"end\">金額</TableColumn>\n */\nexport function TableColumn({\n id,\n allowsSorting,\n isRowHeader,\n align = 'start',\n children,\n className,\n}: TableColumnProps) {\n const { s, classNames } = useContext(TableContext)\n return (\n <Column\n id={id}\n allowsSorting={allowsSorting}\n isRowHeader={isRowHeader}\n data-slot=\"column\"\n className={`group ${s.column({ class: [align === 'end' ? alignEndClass : '', className, classNames?.column] })}`}\n >\n {({ sortDirection }) => (\n <>\n {children}\n {allowsSorting && (\n <span data-slot=\"sortIcon\" className={s.sortIcon({ class: classNames?.sortIcon })}>\n <SortIcon direction={sortDirection} />\n </span>\n )}\n </>\n )}\n </Column>\n )\n}\n\nexport interface TableBodyProps {\n children?: ReactNode\n /** 行が 0 件のときに本体へ出す内容 */\n renderEmptyState?: () => ReactNode\n className?: string\n}\n\n/**\n * 本体。`TableRow` を並べる。行が無いときは `renderEmptyState` の内容が出る。\n *\n * @example\n * <TableBody renderEmptyState={() => '該当する注文はありません'}>\n * {rows}\n * </TableBody>\n */\nexport function TableBody({ children, renderEmptyState, className }: TableBodyProps) {\n const { s, classNames } = useContext(TableContext)\n return (\n <RACTableBody\n data-slot=\"body\"\n className={s.body({ class: [className, classNames?.body] })}\n renderEmptyState={\n renderEmptyState === undefined\n ? undefined\n : () => (\n <div data-slot=\"empty\" className={s.empty({ class: classNames?.empty })}>\n {renderEmptyState()}\n </div>\n )\n }\n >\n {children}\n </RACTableBody>\n )\n}\n\nexport interface TableRowProps {\n /** 行の id。選択と `onRowAction` に渡る */\n id: string\n isDisabled?: boolean\n children?: ReactNode\n className?: string\n}\n\n/**\n * 行。`TableCell` を列の数だけ並べる。\n *\n * @example\n * <TableRow id=\"1042\">\n * <TableCell>#1042</TableCell>\n * </TableRow>\n */\nexport function TableRow({ id, isDisabled, children, className }: TableRowProps) {\n const { s, classNames } = useContext(TableContext)\n return (\n <Row\n id={id}\n isDisabled={isDisabled}\n data-slot=\"row\"\n className={s.row({ class: [className, classNames?.row] })}\n >\n {children}\n </Row>\n )\n}\n\nexport interface TableCellProps {\n /** 金額や数量は `end`(右寄せ)。見出しと揃える */\n align?: 'start' | 'end'\n children?: ReactNode\n className?: string\n}\n\n/**\n * セル。\n *\n * @example\n * <TableCell align=\"end\">¥12,800</TableCell>\n */\nexport function TableCell({ align = 'start', children, className }: TableCellProps) {\n const { s, classNames } = useContext(TableContext)\n return (\n <Cell\n data-slot=\"cell\"\n className={s.cell({\n class: [align === 'end' ? alignEndClass : '', className, classNames?.cell],\n })}\n >\n {children}\n </Cell>\n )\n}\n\n/**\n * 一覧を行と列で見せる。**行が指で押せる面**で、40px 以上の高さを持つ\n * (Raster は横罫だけ、Flatlay は縦横の罫線の帳票)。\n *\n * 行の選択は行そのものを押す(チェックボックスは出さない)。\n * 狭い画面では表そのものが横にスクロールする。`overflow-x-auto` の枠で包むこと。\n *\n * @example\n * <Table aria-label=\"注文一覧\" sortDescriptor={sort} onSortChange={setSort}>\n * <TableHeader>\n * <TableColumn id=\"no\" isRowHeader>注文番号</TableColumn>\n * <TableColumn id=\"amount\" allowsSorting align=\"end\">金額</TableColumn>\n * </TableHeader>\n * <TableBody>\n * <TableRow id=\"1042\">\n * <TableCell>#1042</TableCell>\n * <TableCell align=\"end\">¥12,800</TableCell>\n * </TableRow>\n * </TableBody>\n * </Table>\n */\nexport function Table({\n 'aria-label': ariaLabel,\n size,\n sortDescriptor,\n onSortChange,\n selectionMode,\n selectedKeys,\n defaultSelectedKeys,\n onSelectionChange,\n disabledKeys,\n onRowAction,\n children,\n className,\n classNames,\n}: TableProps) {\n const s = tableStyles({ size })\n\n return (\n <TableContext.Provider value={{ s, classNames }}>\n {/* RAC の Table は id を受け取らない(DOM に出す口が無い)。NoviBaseProps の id は表では効かない */}\n <RACTable\n aria-label={ariaLabel}\n sortDescriptor={sortDescriptor}\n onSortChange={(d) =>\n onSortChange?.({\n column: String(d.column),\n direction: d.direction,\n } as TableSortDescriptor)\n }\n selectionMode={selectionMode}\n // 行そのものを押して選ぶ。チェックボックスの列は出さない\n selectionBehavior=\"replace\"\n selectedKeys={selectedKeys}\n defaultSelectedKeys={defaultSelectedKeys}\n onSelectionChange={(keys) =>\n onSelectionChange?.(keys === 'all' ? 'all' : new Set([...keys].map(String)))\n }\n disabledKeys={disabledKeys}\n onRowAction={onRowAction === undefined ? undefined : (key) => onRowAction(String(key))}\n data-slot=\"root\"\n className={s.root({ class: [className, classNames?.root] })}\n >\n {children}\n </RACTable>\n </TableContext.Provider>\n )\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { VariantMap } from "@novi-ui/core";
|
|
2
|
+
//#region src/table/table.styles.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Table のスタイル定義。
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* import { tableStyles } from '@novi-ui/tactile'
|
|
8
|
+
* import { tv } from 'tailwind-variants'
|
|
9
|
+
*
|
|
10
|
+
* const myTable = tv({ extend: tableStyles, slots: { cell: 'h-16' } })
|
|
11
|
+
*/
|
|
12
|
+
declare const tableStyles: import("tailwind-variants").TVReturnType<{
|
|
13
|
+
size: VariantMap<"sm" | "md" | "lg", {
|
|
14
|
+
column: string;
|
|
15
|
+
cell: string;
|
|
16
|
+
}>;
|
|
17
|
+
}, {
|
|
18
|
+
root: string;
|
|
19
|
+
header: string;
|
|
20
|
+
column: string;
|
|
21
|
+
sortIcon: string;
|
|
22
|
+
body: string;
|
|
23
|
+
row: string;
|
|
24
|
+
cell: string;
|
|
25
|
+
empty: string;
|
|
26
|
+
}, undefined, {
|
|
27
|
+
size: VariantMap<"sm" | "md" | "lg", {
|
|
28
|
+
column: string;
|
|
29
|
+
cell: string;
|
|
30
|
+
}>;
|
|
31
|
+
}, {
|
|
32
|
+
root: string;
|
|
33
|
+
header: string;
|
|
34
|
+
column: string;
|
|
35
|
+
sortIcon: string;
|
|
36
|
+
body: string;
|
|
37
|
+
row: string;
|
|
38
|
+
cell: string;
|
|
39
|
+
empty: string;
|
|
40
|
+
}, import("tailwind-variants").TVReturnTypeLike<{
|
|
41
|
+
size: VariantMap<"sm" | "md" | "lg", {
|
|
42
|
+
column: string;
|
|
43
|
+
cell: string;
|
|
44
|
+
}>;
|
|
45
|
+
}, {
|
|
46
|
+
root: string;
|
|
47
|
+
header: string;
|
|
48
|
+
column: string;
|
|
49
|
+
sortIcon: string;
|
|
50
|
+
body: string;
|
|
51
|
+
row: string;
|
|
52
|
+
cell: string;
|
|
53
|
+
empty: string;
|
|
54
|
+
}>>;
|
|
55
|
+
type TableStyleProps = Parameters<typeof tableStyles>[0];
|
|
56
|
+
//#endregion
|
|
57
|
+
export { TableStyleProps, tableStyles };
|
|
58
|
+
//# sourceMappingURL=table.styles.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.styles.d.mts","names":[],"sources":["../../src/table/table.styles.ts"],"mappings":";;;;;;;;;;;cAiFa,yCAAW;;IAxBmB;IAAc;;;;;;;;;;;;;IAAd;IAAc;;;;;;;;;;;;;IAAd;IAAc;;;;;;;;;;;;KA8B7C,kBAAkB,kBAAkB"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { focusRing } from "../styles/focus-ring.mjs";
|
|
2
|
+
import { tv } from "tailwind-variants";
|
|
3
|
+
//#region src/table/table.styles.ts
|
|
4
|
+
/**
|
|
5
|
+
* Tactile の表は**行が面**。1 行が指で押せる高さと余白を持ち、選んだ行は面が沈む
|
|
6
|
+
* (Raster は横罫だけ、Flatlay は縦横の罫線)。罫線は行のあいだの細い線だけ。
|
|
7
|
+
*/
|
|
8
|
+
const slots = {
|
|
9
|
+
root: [
|
|
10
|
+
"w-full border-separate border-spacing-0 text-left",
|
|
11
|
+
"text-[var(--novi-color-fg)]",
|
|
12
|
+
"outline-none"
|
|
13
|
+
].join(" "),
|
|
14
|
+
header: "",
|
|
15
|
+
column: [
|
|
16
|
+
"font-medium text-[var(--novi-color-muted)] text-[length:var(--novi-text-sm)]",
|
|
17
|
+
"border-b border-[var(--novi-color-border)]",
|
|
18
|
+
"whitespace-nowrap align-middle",
|
|
19
|
+
"outline-none",
|
|
20
|
+
"data-[allows-sorting]:cursor-pointer",
|
|
21
|
+
"data-[allows-sorting]:hover:text-[var(--novi-color-fg)]",
|
|
22
|
+
"data-[focus-visible]:text-[var(--novi-color-fg)]",
|
|
23
|
+
"aria-[sort=ascending]:text-[var(--novi-color-fg)] aria-[sort=descending]:text-[var(--novi-color-fg)]",
|
|
24
|
+
focusRing
|
|
25
|
+
].join(" "),
|
|
26
|
+
sortIcon: ["ml-1.5 inline-flex align-middle text-[var(--novi-color-muted)]", "opacity-40 group-aria-[sort=ascending]:opacity-100 group-aria-[sort=descending]:opacity-100"].join(" "),
|
|
27
|
+
body: "",
|
|
28
|
+
row: [
|
|
29
|
+
"outline-none",
|
|
30
|
+
"text-[var(--novi-color-fg)]",
|
|
31
|
+
"data-[hovered]:bg-[var(--novi-color-subtle)]",
|
|
32
|
+
"data-[selected]:bg-[var(--novi-color-subtle)] data-[selected]:font-medium",
|
|
33
|
+
"data-[pressed]:bg-[var(--novi-color-border)]",
|
|
34
|
+
"data-[disabled]:opacity-40",
|
|
35
|
+
"data-[focus-visible]:outline-2 data-[focus-visible]:-outline-offset-2 data-[focus-visible]:outline-[var(--novi-color-ring)]",
|
|
36
|
+
"transition-[background-color]",
|
|
37
|
+
"duration-[var(--novi-duration-fast)] ease-[var(--novi-ease-standard)]"
|
|
38
|
+
].join(" "),
|
|
39
|
+
cell: [
|
|
40
|
+
"align-middle tabular-nums",
|
|
41
|
+
"border-b border-[var(--novi-color-border)]",
|
|
42
|
+
"outline-none",
|
|
43
|
+
"data-[focus-visible]:outline-2 data-[focus-visible]:-outline-offset-2 data-[focus-visible]:outline-[var(--novi-color-ring)]"
|
|
44
|
+
].join(" "),
|
|
45
|
+
empty: [
|
|
46
|
+
"flex items-center justify-center",
|
|
47
|
+
"py-[var(--novi-pad-surface-y)] px-[var(--novi-pad-surface-x)]",
|
|
48
|
+
"text-[var(--novi-color-muted)] text-[length:var(--novi-text-base)]"
|
|
49
|
+
].join(" ")
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Table のスタイル定義。
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* import { tableStyles } from '@novi-ui/tactile'
|
|
56
|
+
* import { tv } from 'tailwind-variants'
|
|
57
|
+
*
|
|
58
|
+
* const myTable = tv({ extend: tableStyles, slots: { cell: 'h-16' } })
|
|
59
|
+
*/
|
|
60
|
+
const tableStyles = tv({
|
|
61
|
+
slots,
|
|
62
|
+
variants: { size: {
|
|
63
|
+
sm: {
|
|
64
|
+
column: "h-10 px-[var(--novi-pad-control-x-sm)]",
|
|
65
|
+
cell: "h-10 px-[var(--novi-pad-control-x-sm)] text-[length:var(--novi-text-sm)]"
|
|
66
|
+
},
|
|
67
|
+
md: {
|
|
68
|
+
column: "h-12 px-[var(--novi-pad-control-x-md)]",
|
|
69
|
+
cell: "h-12 px-[var(--novi-pad-control-x-md)] text-[length:var(--novi-text-base)]"
|
|
70
|
+
},
|
|
71
|
+
lg: {
|
|
72
|
+
column: "h-14 px-[var(--novi-pad-control-x-lg)]",
|
|
73
|
+
cell: "h-14 px-[var(--novi-pad-control-x-lg)] text-[length:var(--novi-text-lg)]"
|
|
74
|
+
}
|
|
75
|
+
} },
|
|
76
|
+
defaultVariants: { size: "md" }
|
|
77
|
+
});
|
|
78
|
+
/** 右寄せの列(金額・数量)。見出しとセルの両方に付ける */
|
|
79
|
+
const alignEndClass = "text-right";
|
|
80
|
+
//#endregion
|
|
81
|
+
export { alignEndClass, tableStyles };
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=table.styles.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.styles.mjs","names":[],"sources":["../../src/table/table.styles.ts"],"sourcesContent":["import type { NoviSize, SlotMap, tableRequiredSlots, tableSlots, VariantMap } from '@novi-ui/core'\nimport { tv } from 'tailwind-variants'\nimport { focusRing } from '../styles/focus-ring'\n\n/**\n * Tactile の表は**行が面**。1 行が指で押せる高さと余白を持ち、選んだ行は面が沈む\n * (Raster は横罫だけ、Flatlay は縦横の罫線)。罫線は行のあいだの細い線だけ。\n */\nconst slots = {\n root: [\n 'w-full border-separate border-spacing-0 text-left',\n 'text-[var(--novi-color-fg)]',\n 'outline-none',\n ].join(' '),\n header: '',\n column: [\n 'font-medium text-[var(--novi-color-muted)] text-[length:var(--novi-text-sm)]',\n 'border-b border-[var(--novi-color-border)]',\n 'whitespace-nowrap align-middle',\n 'outline-none',\n 'data-[allows-sorting]:cursor-pointer',\n 'data-[allows-sorting]:hover:text-[var(--novi-color-fg)]',\n 'data-[focus-visible]:text-[var(--novi-color-fg)]',\n 'aria-[sort=ascending]:text-[var(--novi-color-fg)] aria-[sort=descending]:text-[var(--novi-color-fg)]',\n focusRing,\n ].join(' '),\n sortIcon: [\n 'ml-1.5 inline-flex align-middle text-[var(--novi-color-muted)]',\n 'opacity-40 group-aria-[sort=ascending]:opacity-100 group-aria-[sort=descending]:opacity-100',\n ].join(' '),\n body: '',\n row: [\n 'outline-none',\n // 面(hover / 選択)を持つので文字色も持つ。ダークで不可視にならない\n 'text-[var(--novi-color-fg)]',\n 'data-[hovered]:bg-[var(--novi-color-subtle)]',\n 'data-[selected]:bg-[var(--novi-color-subtle)] data-[selected]:font-medium',\n 'data-[pressed]:bg-[var(--novi-color-border)]',\n 'data-[disabled]:opacity-40',\n 'data-[focus-visible]:outline-2 data-[focus-visible]:-outline-offset-2 data-[focus-visible]:outline-[var(--novi-color-ring)]',\n 'transition-[background-color]',\n 'duration-[var(--novi-duration-fast)] ease-[var(--novi-ease-standard)]',\n ].join(' '),\n cell: [\n 'align-middle tabular-nums',\n 'border-b border-[var(--novi-color-border)]',\n 'outline-none',\n 'data-[focus-visible]:outline-2 data-[focus-visible]:-outline-offset-2 data-[focus-visible]:outline-[var(--novi-color-ring)]',\n ].join(' '),\n empty: [\n 'flex items-center justify-center',\n 'py-[var(--novi-pad-surface-y)] px-[var(--novi-pad-surface-x)]',\n 'text-[var(--novi-color-muted)] text-[length:var(--novi-text-base)]',\n ].join(' '),\n} satisfies SlotMap<typeof tableSlots, (typeof tableRequiredSlots)[number]>\n\n/** 行の高さは Button と揃える。40 / 48 / 56px。指で押せる行 */\nconst size: VariantMap<NoviSize, { column: string; cell: string }> = {\n sm: {\n column: 'h-10 px-[var(--novi-pad-control-x-sm)]',\n cell: 'h-10 px-[var(--novi-pad-control-x-sm)] text-[length:var(--novi-text-sm)]',\n },\n md: {\n column: 'h-12 px-[var(--novi-pad-control-x-md)]',\n cell: 'h-12 px-[var(--novi-pad-control-x-md)] text-[length:var(--novi-text-base)]',\n },\n lg: {\n column: 'h-14 px-[var(--novi-pad-control-x-lg)]',\n cell: 'h-14 px-[var(--novi-pad-control-x-lg)] text-[length:var(--novi-text-lg)]',\n },\n}\n\n/**\n * Table のスタイル定義。\n *\n * @example\n * import { tableStyles } from '@novi-ui/tactile'\n * import { tv } from 'tailwind-variants'\n *\n * const myTable = tv({ extend: tableStyles, slots: { cell: 'h-16' } })\n */\nexport const tableStyles = tv({\n slots,\n variants: { size },\n defaultVariants: { size: 'md' },\n})\n\nexport type TableStyleProps = Parameters<typeof tableStyles>[0]\n\n/** 右寄せの列(金額・数量)。見出しとセルの両方に付ける */\nexport const alignEndClass = 'text-right'\n"],"mappings":";;;;;;;AAQA,MAAM,QAAQ;CACZ,MAAM;EACJ;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CACV,QAAQ;CACR,QAAQ;EACN;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CACV,UAAU,CACR,kEACA,6FACF,CAAC,CAAC,KAAK,GAAG;CACV,MAAM;CACN,KAAK;EACH;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CACV,MAAM;EACJ;EACA;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;CACV,OAAO;EACL;EACA;EACA;CACF,CAAC,CAAC,KAAK,GAAG;AACZ;;;;;;;;;;AA2BA,MAAa,cAAc,GAAG;CAC5B;CACA,UAAU,EAAE;EAzBZ,IAAI;GACF,QAAQ;GACR,MAAM;EACR;EACA,IAAI;GACF,QAAQ;GACR,MAAM;EACR;EACA,IAAI;GACF,QAAQ;GACR,MAAM;EACR;CAcY,EAAK;CACjB,iBAAiB,EAAE,MAAM,KAAK;AAChC,CAAC;;AAKD,MAAa,gBAAgB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@novi-ui/tactile",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Novi UI theme 2 — touch-first. Bottom sheets, generous tap targets, soft elevation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -28,13 +28,16 @@
|
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"react": "^19.0.0",
|
|
31
|
-
"react-aria-components": "^1.20.0"
|
|
31
|
+
"react-aria-components": "^1.20.0",
|
|
32
|
+
"tailwindcss": "^4.0.0"
|
|
32
33
|
},
|
|
33
34
|
"dependencies": {
|
|
34
|
-
"
|
|
35
|
-
"
|
|
35
|
+
"@novi-ui/core": "0.5.0",
|
|
36
|
+
"tailwind-variants": "^3.3.1"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
39
|
+
"@internationalized/date": "^3.12.3",
|
|
40
|
+
"@novi-ui/raster": "0.7.0",
|
|
38
41
|
"@size-limit/preset-small-lib": "^13.0.3",
|
|
39
42
|
"@testing-library/dom": "^10.4.1",
|
|
40
43
|
"@testing-library/react": "^16.3.2",
|
|
@@ -51,8 +54,7 @@
|
|
|
51
54
|
"size-limit": "^13.0.3",
|
|
52
55
|
"tsdown": "0.22.14",
|
|
53
56
|
"typescript": "6.0.3",
|
|
54
|
-
"vitest": "4.1.11"
|
|
55
|
-
"@novi-ui/raster": "0.5.0"
|
|
57
|
+
"vitest": "4.1.11"
|
|
56
58
|
},
|
|
57
59
|
"scripts": {
|
|
58
60
|
"build": "tsdown && node scripts/generate-theme-css.mjs",
|