@1money/component-ui 0.0.46 β†’ 0.0.47

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.
Files changed (53) hide show
  1. package/es/components/Table/Table.d.ts +2 -2
  2. package/es/components/Table/Table.js +25 -148
  3. package/es/components/Table/VirtualTable.d.ts +2 -2
  4. package/es/components/Table/VirtualTable.js +30 -143
  5. package/es/components/Table/core/useTableColumns.d.ts +21 -7
  6. package/es/components/Table/core/useTableColumns.js +65 -13
  7. package/es/components/Table/core/useTableDataPipeline.d.ts +13 -6
  8. package/es/components/Table/core/useTableDataPipeline.js +193 -27
  9. package/es/components/Table/core/useTableExpand.d.ts +2 -2
  10. package/es/components/Table/core/useTableSelection.d.ts +3 -5
  11. package/es/components/Table/core/useTableSelection.js +1 -1
  12. package/es/components/Table/core/useTableSetup.d.ts +42 -0
  13. package/es/components/Table/core/useTableSetup.js +175 -0
  14. package/es/components/Table/features/ExpandTrigger.js +2 -1
  15. package/es/components/Table/features/FilterTrigger.d.ts +9 -0
  16. package/es/components/Table/features/FilterTrigger.js +157 -0
  17. package/es/components/Table/features/SelectionColumn.d.ts +3 -2
  18. package/es/components/Table/features/SelectionColumn.js +19 -6
  19. package/es/components/Table/interface.d.ts +102 -21
  20. package/es/components/Table/renderers/BodyCell.d.ts +4 -4
  21. package/es/components/Table/renderers/BodyCell.js +1 -1
  22. package/es/components/Table/renderers/HeaderCell.d.ts +8 -4
  23. package/es/components/Table/renderers/HeaderCell.js +13 -3
  24. package/es/components/Table/style/Table.css +1 -1
  25. package/es/index.css +1 -1
  26. package/lib/components/Table/Table.d.ts +2 -2
  27. package/lib/components/Table/Table.js +24 -150
  28. package/lib/components/Table/VirtualTable.d.ts +2 -2
  29. package/lib/components/Table/VirtualTable.js +28 -144
  30. package/lib/components/Table/core/useTableColumns.d.ts +21 -7
  31. package/lib/components/Table/core/useTableColumns.js +65 -13
  32. package/lib/components/Table/core/useTableDataPipeline.d.ts +13 -6
  33. package/lib/components/Table/core/useTableDataPipeline.js +192 -26
  34. package/lib/components/Table/core/useTableExpand.d.ts +2 -2
  35. package/lib/components/Table/core/useTableSelection.d.ts +3 -5
  36. package/lib/components/Table/core/useTableSelection.js +1 -1
  37. package/lib/components/Table/core/useTableSetup.d.ts +42 -0
  38. package/lib/components/Table/core/useTableSetup.js +184 -0
  39. package/lib/components/Table/features/ExpandTrigger.js +2 -1
  40. package/lib/components/Table/features/FilterTrigger.d.ts +9 -0
  41. package/lib/components/Table/features/FilterTrigger.js +164 -0
  42. package/lib/components/Table/features/SelectionColumn.d.ts +3 -2
  43. package/lib/components/Table/features/SelectionColumn.js +19 -6
  44. package/lib/components/Table/interface.d.ts +102 -21
  45. package/lib/components/Table/renderers/BodyCell.d.ts +4 -4
  46. package/lib/components/Table/renderers/BodyCell.js +1 -1
  47. package/lib/components/Table/renderers/HeaderCell.d.ts +8 -4
  48. package/lib/components/Table/renderers/HeaderCell.js +13 -3
  49. package/lib/components/Table/style/Table.css +1 -1
  50. package/lib/index.css +1 -1
  51. package/package.json +1 -1
  52. package/scripts/mcp-server/examples.generated.json +120 -0
  53. package/scripts/mcp-server/index.generated.json +336 -14
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1money/component-ui",
3
- "version": "0.0.46",
3
+ "version": "0.0.47",
4
4
  "description": "React Components based on primereact for 1money front-end projects",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -115,6 +115,12 @@
115
115
  "source": "readme",
116
116
  "compilable": true
117
117
  },
118
+ "082ec26c8081a863c586ce7bb5d2c1fc35a0e901d02e7fe1a7e0d66fe526848e": {
119
+ "title": "Variants",
120
+ "code": "<div style={stackStyle}>\n <div>\n <TypographyTitle size=\"sm\" strong style={sectionTitleStyle}>\n Stroke\n </TypographyTitle>\n <Table {...(args as TableProps<Record<string, any>>)} dataSource={portfolioRows.slice(0, 4)} variant=\"stroke\" />\n </div>\n <div>\n <TypographyTitle size=\"sm\" strong style={sectionTitleStyle}>\n Fill\n </TypographyTitle>\n <Table {...(args as TableProps<Record<string, any>>)} dataSource={portfolioRows.slice(0, 4)} variant=\"fill\" />\n </div>\n </div>",
121
+ "source": "stories",
122
+ "compilable": false
123
+ },
118
124
  "08616eb7b07c701d8cd3872fb1e802eac207a2cf2a3a802b28360fc7112d1ca8": {
119
125
  "title": "Import",
120
126
  "code": "import { Calendar } from '@1money/component-ui';\n// or\nimport { Calendar } from '@1money/component-ui/Calendar';",
@@ -139,6 +145,12 @@
139
145
  "source": "readme",
140
146
  "compilable": true
141
147
  },
148
+ "0b1bd0a0c931658fda5287f712844f21f5f69c50228164f8c97deeb385ed9187": {
149
+ "title": "Filters",
150
+ "code": "<div>\n <TypographyBody size=\"sm\" color=\"default-tertiary\" style={hintStyle}>\n Click the funnel icon in a column header to filter. Multi-select is the\n default; selections apply on <em>OK</em>.\n </TypographyBody>\n <Table<PortfolioRow>\n rowKey=\"id\"\n size=\"large\"\n variant=\"stroke\"\n pagination={false}\n dataSource={portfolioRows}\n columns={[\n portfolioColumns[0],\n {\n ...portfolioColumns[1],\n filters: NETWORK_FILTER_ITEMS,\n onFilter: (value, record) => record.network === value,\n },\n {\n ...portfolioColumns[2],\n filters: STATUS_FILTER_ITEMS,\n onFilter: (value, record) => record.status === value,\n },\n portfolioColumns[3],\n portfolioColumns[4],\n ]}\n />\n </div>",
151
+ "source": "stories",
152
+ "compilable": true
153
+ },
142
154
  "0c7c04366337519cd94b38f5358dfa8f9eec80c8f289ba172def5f00e1a89ba3": {
143
155
  "title": "Date Picker Story",
144
156
  "code": "<ProForm\n {...args}\n initialValues={{ birthday: null, startDate: null }}\n onFinish={(values) => alert(JSON.stringify(values, null, 2))}\n >\n <ProFormDatePicker\n name=\"birthday\"\n label=\"Birthday\"\n fieldProps={{ dateFormat: 'yy-mm-dd', showIcon: true }}\n />\n <ProFormDatePicker\n name=\"startDate\"\n label=\"Start Date\"\n fieldProps={{ dateFormat: 'mm/dd/yy', showButtonBar: true }}\n />\n </ProForm>",
@@ -169,6 +181,12 @@
169
181
  "source": "readme",
170
182
  "compilable": true
171
183
  },
184
+ "0e53815284d097cccdcb6cdff3952b42734dda8b58b4cdeac1948e5f1d2b3587": {
185
+ "title": "Expandable List",
186
+ "code": "<WalletRegistryStory\n dataSource={expandableListRows}\n defaultExpandedKeys={['wallet-big-tom', 'wallet-global-treasury']}\n />",
187
+ "source": "stories",
188
+ "compilable": true
189
+ },
172
190
  "10c3dc4b995524ead942626d1a9e7ef96f11e52235700d42ddbf138090b3a9ad": {
173
191
  "title": "Canonical usage",
174
192
  "code": "import { Slider } from '@1money/component-ui';\n// or\nimport { Slider } from '@1money/component-ui/Slider';",
@@ -205,6 +223,12 @@
205
223
  "source": "stories",
206
224
  "compilable": false
207
225
  },
226
+ "1622196bc98fc696224e0af42f3858aefbb46ae0237ebd7ed753d40c2e0f87d6": {
227
+ "title": "Single Select Filter",
228
+ "code": "<Table<PortfolioRow>\n rowKey=\"id\"\n pagination={false}\n dataSource={portfolioRows}\n columns={[\n portfolioColumns[0],\n {\n ...portfolioColumns[1],\n filters: NETWORK_FILTER_ITEMS,\n filterMultiple: false,\n onFilter: (value, record) => record.network === value,\n },\n portfolioColumns[2],\n portfolioColumns[3],\n ]}\n />",
229
+ "source": "stories",
230
+ "compilable": true
231
+ },
208
232
  "1673418288f034d6e46db906f3b2fb8a2079625c30f15ed4c7c35c0e4568f940": {
209
233
  "title": "Basic Usage",
210
234
  "code": "import { Grid } from '@1money/component-ui';\nimport { GRID_ALIGN, GRID_JUSTIFY } from '@1money/component-ui/Grid';\n\nconst GRID_GUTTER: [number, number] = [16, 8];\nconst SPAN_HALF = 6;\n\n<Grid gutter={GRID_GUTTER} justify={GRID_JUSTIFY.spaceBetween} align={GRID_ALIGN.middle}>\n <Grid.Col span={SPAN_HALF}>Left</Grid.Col>\n <Grid.Col span={SPAN_HALF}>Right</Grid.Col>\n</Grid>",
@@ -253,6 +277,12 @@
253
277
  "source": "canonical",
254
278
  "compilable": true
255
279
  },
280
+ "1c879c8d080ccdc8a79261e997d29861634e6ae8f74d950f7305a1167ddb1fb5": {
281
+ "title": "Figma Auto Conversion Table",
282
+ "code": "{\n const [expandedKeys, setExpandedKeys] = useState<React.Key[]>(['activity-row-2']);\n\n const handleToggle = (rowId: string) => {\n setExpandedKeys((currentKeys) => (\n currentKeys.includes(rowId)\n ? currentKeys.filter((key) => key !== rowId)\n : [...currentKeys, rowId]\n ));\n };\n\n return (\n <div style={figmaFrameStyle}>\n <Table<ActivityLedgerRow>\n rowKey=\"id\"\n size=\"small\"\n variant=\"stroke\"\n pagination={false}\n columns={createActivityLedgerColumns({\n expandedKeys,\n onToggle: handleToggle,\n })}\n dataSource={activityLedgerRows}\n expandable={{\n showExpandColumn: false,\n expandedRowKeys: expandedKeys,\n rowExpandable: (record) => Boolean(record.details?.length),\n expandedRowRender: (record) => (\n record.details\n ? <ActivityLedgerDetailsPanel details={record.details} />\n : null\n ),\n }}\n />\n </div>\n );\n }",
283
+ "source": "stories",
284
+ "compilable": true
285
+ },
256
286
  "1cc244bf13712c43e79b378e25198234696ed488d0a147473327f0eb16c461bc": {
257
287
  "title": "Searchable Sizes",
258
288
  "code": "{\n const [largeValue, setLargeValue] = useState<string | number | undefined>('usdt');\n const [smallValue, setSmallValue] = useState<string | number | undefined>('usdt');\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 24, width: 320 }}>\n <Select\n {...args}\n size=\"large\"\n label=\"Large\"\n value={largeValue}\n onChange={(nextValue, option) => {\n setLargeValue(nextValue as string | number | undefined);\n args.onChange?.(nextValue, option);\n }}\n />\n <Select\n {...args}\n size=\"small\"\n label=\"Small\"\n filterInputAutoFocus={false}\n value={smallValue}\n onChange={(nextValue, option) => {\n setSmallValue(nextValue as string | number | undefined);\n args.onChange?.(nextValue, option);\n }}\n />\n </div>\n );\n }",
@@ -469,6 +499,12 @@
469
499
  "source": "stories",
470
500
  "compilable": true
471
501
  },
502
+ "2bfe01695a2d2aa890db17bef359b1c81761ad66301c5c548fe2e23750a8e5c8": {
503
+ "title": "Figma-aligned Expandable Example",
504
+ "code": "import { useState } from 'react';\n\ninterface WalletRow {\n id: string;\n walletName: string;\n walletSummary: string;\n}\n\nconst rows: WalletRow[] = [\n {\n id: 'wallet-ops',\n walletName: 'Operations wallet',\n walletSummary: '0x1234...abcd',\n },\n];\n\nfunction WalletDetails({ record }: { record: WalletRow }) {\n return <div>{record.walletSummary}</div>;\n}\n\nfunction WalletRegistryTable() {\n const [expandedRowKeys, setExpandedRowKeys] = useState<React.Key[]>(['wallet-ops']);\n\n return (\n <Table\n rowKey=\"id\"\n size=\"small\"\n variant=\"stroke\"\n pagination={false}\n columns={[\n {\n key: 'walletName',\n title: 'Wallet name',\n render: (_value, record) => (\n <button\n type=\"button\"\n onClick={() => {\n setExpandedRowKeys((current) => (\n current.includes(record.id)\n ? current.filter((key) => key !== record.id)\n : [...current, record.id]\n ));\n }}\n >\n {record.walletName}\n </button>\n ),\n },\n {\n key: 'walletSummary',\n dataIndex: 'walletSummary',\n title: 'Wallet address',\n },\n {\n key: 'actions',\n title: 'Actions',\n align: 'right',\n render: () => '...',\n },\n ]}\n dataSource={rows}\n expandable={{\n showExpandColumn: false,\n expandedRowKeys,\n expandedRowRender: (record) => <WalletDetails record={record} />,\n }}\n />\n );\n}",
505
+ "source": "readme",
506
+ "compilable": true
507
+ },
472
508
  "2cca976a647db275dfb45ce8bb53bc85d304e49c3d91f76e5987d11e95b604c1": {
473
509
  "title": "Import",
474
510
  "code": "import { Cell } from '@1money/component-ui';\n// or\nimport { Cell } from '@1money/component-ui/Cell';",
@@ -847,6 +883,12 @@
847
883
  "source": "stories",
848
884
  "compilable": false
849
885
  },
886
+ "5b6e430e96dfe718f6bd3291f933d68b2a94eed3e1bd87766079d71544d56592": {
887
+ "title": "Selection And Sort",
888
+ "code": "{\n const [selectedKeys, setSelectedKeys] = useState<React.Key[]>(['2']);\n\n return (\n <div>\n <TypographyBody size=\"sm\" color=\"default-tertiary\" style={hintStyle}>\n Selected rows: {selectedKeys.join(', ')}\n </TypographyBody>\n <Table\n {...(args as TableProps<Record<string, any>>)}\n rowSelection={{\n type: 'checkbox',\n selectedRowKeys: selectedKeys,\n onChange: (keys) => setSelectedKeys(keys),\n }}\n />\n </div>\n );\n }",
889
+ "source": "stories",
890
+ "compilable": false
891
+ },
850
892
  "5bbda57b2d06dfefaed853ba5ad655bb306fd8ecfbc92a6a96dee1deffc1af2f": {
851
893
  "title": "With Content",
852
894
  "code": "<Tabs\n defaultActiveKey=\"tab1\"\n items={[\n { key: 'tab1', label: 'Overview', children: <div>Overview content goes here</div> },\n { key: 'tab2', label: 'Transactions', children: <div>Transactions content goes here</div> },\n { key: 'tab3', label: 'Analytics', children: <div>Analytics content goes here</div> },\n ]}\n />",
@@ -991,6 +1033,12 @@
991
1033
  "source": "readme",
992
1034
  "compilable": true
993
1035
  },
1036
+ "6f1ac382a21af48aded6d900902e14d386aec026b6a51b8efa0fbac1f515290a": {
1037
+ "title": "Fixed And Sticky",
1038
+ "code": "<Table<PortfolioRow>\n rowKey=\"id\"\n pagination={false}\n sticky\n scroll={{ x: 1120, y: 280 }}\n dataSource={portfolioRows}\n columns={[\n {\n ...portfolioColumns[0],\n fixed: 'left',\n },\n portfolioColumns[1],\n portfolioColumns[2],\n {\n key: 'owner',\n dataIndex: 'owner',\n title: 'Owner',\n width: 220,\n },\n {\n key: 'balance',\n dataIndex: 'balance',\n title: 'Balance',\n width: 160,\n align: 'right',\n render: (value) => formatBalance(value as number),\n },\n {\n ...portfolioColumns[4],\n fixed: 'right',\n },\n ]}\n />",
1039
+ "source": "stories",
1040
+ "compilable": true
1041
+ },
994
1042
  "6f2b7da00479a6033fdaca36f0646a924c61cbf09cd0e07da6948a884af98a61": {
995
1043
  "title": "Dependency",
996
1044
  "code": "<ProForm\n {...args}\n initialValues={{ hasAccount: false, accountType: '' }}\n >\n <ProFormSwitch name=\"hasAccount\" label=\"Has Account\" />\n <ProFormDependency name={['hasAccount']}>\n {({ hasAccount }) =>\n hasAccount ? (\n <>\n <ProFormText\n name=\"accountId\"\n label=\"Account ID\"\n rules={[{ required: true }]}\n />\n <ProFormText name=\"accountName\" label=\"Account Name\" />\n </>\n ) : null\n }\n </ProFormDependency>\n </ProForm>",
@@ -1207,6 +1255,12 @@
1207
1255
  "source": "readme",
1208
1256
  "compilable": true
1209
1257
  },
1258
+ "83d457fb7d2b3478dda19b79185daa8909a55b9786ff1b3cf560cec95743926d": {
1259
+ "title": "Basic Usage",
1260
+ "code": "<Table rowKey=\"id\" columns={columns} dataSource={rows} />",
1261
+ "source": "readme",
1262
+ "compilable": true
1263
+ },
1210
1264
  "842244e70f89e2aaf6941718de836ab3a6e08d642a4d4bb2e80cee160158470f": {
1211
1265
  "title": "Default",
1212
1266
  "code": "{\n const sizes = ['large', 'small'] as const;\n const statuses = ['default', 'error'] as const;\n const valueTypes = ['Placeholder', 'Filled'] as const;\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 40 }}>\n {sizes.map((size) => (\n <div key={size}>\n <h3 style={{ margin: '0 0 16px', textTransform: 'capitalize' }}>{size}</h3>\n <div style={{ display: 'flex', gap: 24, flexWrap: 'wrap' }}>\n {statuses.map((status) =>\n valueTypes.map((vt) => (\n <div key={`${status}-${vt}`} style={{ width: 310 }}>\n <p style={{ margin: '0 0 4px', fontSize: 12, color: '#999' }}>\n {status} / {vt}\n </p>\n <Input\n size={size}\n status={status}\n label=\"Label\"\n feedback=\"Feedback\"\n feedbackIcon={status === 'error' ? <Icons name=\"error\" size={16} /> : <Icons name=\"info\" size={16} />}\n placeholder=\"Value\"\n allowClear\n defaultValue={vt === 'Filled' ? 'Input value' : undefined}\n />\n </div>\n )),\n )}\n {/* Read-Only */}\n {valueTypes.map((vt) => (\n <div key={`readonly-${vt}`} style={{ width: 310 }}>\n <p style={{ margin: '0 0 4px', fontSize: 12, color: '#999' }}>\n read-only / {vt}\n </p>\n <Input\n size={size}\n readOnly\n label=\"Label\"\n feedback=\"Feedback\"\n feedbackIcon={<Icons name=\"info\" size={16} />}\n placeholder=\"Value\"\n defaultValue={vt === 'Filled' ? 'Read-only value' : undefined}\n />\n </div>\n ))}\n {/* Disabled */}\n {valueTypes.map((vt) => (\n <div key={`disabled-${vt}`} style={{ width: 310 }}>\n <p style={{ margin: '0 0 4px', fontSize: 12, color: '#999' }}>\n disabled / {vt}\n </p>\n <Input\n size={size}\n disabled\n label=\"Label\"\n feedback=\"Feedback\"\n feedbackIcon={<Icons name=\"info\" size={16} />}\n placeholder=\"Value\"\n defaultValue={vt === 'Filled' ? 'Disabled value' : undefined}\n />\n </div>\n ))}\n </div>\n </div>\n ))}\n\n {/* ── With Prefix / Suffix ── */}\n <div>\n <h3 style={{ margin: '0 0 16px' }}>With Prefix / Suffix</h3>\n <div style={{ display: 'flex', gap: 24, flexWrap: 'wrap' }}>\n <div style={{ width: 310 }}>\n <p style={{ margin: '0 0 4px', fontSize: 12, color: '#999' }}>Prefix + Suffix</p>\n <Input\n label=\"Label\"\n defaultValue=\"100\"\n prefix={<span>USD</span>}\n suffix={<span>Max</span>}\n allowClear\n />\n </div>\n <div style={{ width: 310 }}>\n <p style={{ margin: '0 0 4px', fontSize: 12, color: '#999' }}>Prefix only</p>\n <Input\n label=\"Label\"\n placeholder=\"Enter amount\"\n prefix={<span>$</span>}\n allowClear\n />\n </div>\n <div style={{ width: 310 }}>\n <p style={{ margin: '0 0 4px', fontSize: 12, color: '#999' }}>Suffix only</p>\n <Input\n label=\"Label\"\n placeholder=\"Enter email\"\n suffix={<span>@gmail.com</span>}\n />\n </div>\n </div>\n </div>\n\n {/* ── Required / Info ── */}\n <div>\n <h3 style={{ margin: '0 0 16px' }}>Required / Info</h3>\n <div style={{ display: 'flex', gap: 24, flexWrap: 'wrap' }}>\n <div style={{ width: 310 }}>\n <p style={{ margin: '0 0 4px', fontSize: 12, color: '#999' }}>Required</p>\n <Input\n label=\"Label\"\n required\n placeholder=\"Required field\"\n />\n </div>\n <div style={{ width: 310 }}>\n <p style={{ margin: '0 0 4px', fontSize: 12, color: '#999' }}>Optional (required=false)</p>\n <Input\n label=\"Label\"\n required={false}\n placeholder=\"Optional field\"\n />\n </div>\n <div style={{ width: 310 }}>\n <p style={{ margin: '0 0 4px', fontSize: 12, color: '#999' }}>With Info</p>\n <Input\n label=\"Label\"\n info=\"Optional hint\"\n placeholder=\"Value\"\n />\n </div>\n <div style={{ width: 310 }}>\n <p style={{ margin: '0 0 4px', fontSize: 12, color: '#999' }}>With Tip</p>\n <Input\n label=\"Label\"\n tip=\"This is a helpful tooltip\"\n placeholder=\"Value\"\n />\n </div>\n <div style={{ width: 310 }}>\n <p style={{ margin: '0 0 4px', fontSize: 12, color: '#999' }}>Optional + Info + Tip</p>\n <Input\n label=\"Label\"\n required={false}\n info=\"Optional hint\"\n tip=\"This is a helpful tooltip\"\n placeholder=\"Value\"\n />\n </div>\n </div>\n </div>\n </div>\n );\n }",
@@ -1351,6 +1405,12 @@
1351
1405
  "source": "stories",
1352
1406
  "compilable": false
1353
1407
  },
1408
+ "96217a515862bd694993e67890c003764d3d7dae09ba8304339664ed91eb84ac": {
1409
+ "title": "Filters With Sort And Pagination",
1410
+ "code": "{\n const [lastAction, setLastAction] = useState<string>('β€”');\n const [lastCount, setLastCount] = useState<number>(portfolioRows.length);\n\n return (\n <div>\n <TypographyBody size=\"sm\" color=\"default-tertiary\" style={hintStyle}>\n Filter on Network / Status, sort on Balance, paginate (size 3).{' '}\n Last <code>onChange</code> action: <strong>{lastAction}</strong>{' '}\n (rows on page: {lastCount}).\n </TypographyBody>\n <Table<PortfolioRow>\n rowKey=\"id\"\n dataSource={portfolioRows}\n pagination={{ pageSize: 3 }}\n onChange={(meta) => {\n setLastAction(meta.action);\n setLastCount(meta.currentDataSource.length);\n }}\n columns={[\n portfolioColumns[0],\n {\n ...portfolioColumns[1],\n filters: NETWORK_FILTER_ITEMS,\n onFilter: (value, record) => record.network === value,\n },\n {\n ...portfolioColumns[2],\n filters: STATUS_FILTER_ITEMS,\n onFilter: (value, record) => record.status === value,\n },\n portfolioColumns[3],\n portfolioColumns[4],\n ]}\n />\n </div>\n );\n }",
1411
+ "source": "stories",
1412
+ "compilable": true
1413
+ },
1354
1414
  "96a4fb49627068cd32df95bce74ab746a2901c627dcd70fa9bf9c9247f21b7a3": {
1355
1415
  "title": "Canonical usage",
1356
1416
  "code": "import { Trigger } from '@1money/component-ui';\n// or\nimport { Trigger } from '@1money/component-ui/Trigger';",
@@ -1423,6 +1483,12 @@
1423
1483
  "source": "canonical",
1424
1484
  "compilable": true
1425
1485
  },
1486
+ "9c1283e9fdf9b6890dff56e79eee2e25f49c665934a1a11e56ef9e636b23642d": {
1487
+ "title": "Figma Wallet Registry",
1488
+ "code": "<WalletRegistryStory\n dataSource={walletRegistryRows}\n defaultExpandedKeys={['wallet-ops']}\n />",
1489
+ "source": "stories",
1490
+ "compilable": true
1491
+ },
1426
1492
  "9eae41b47da6d3b07d6bfdb98fe407b6be85aa68db3fe695699cf9588b65eda8": {
1427
1493
  "title": "Placements",
1428
1494
  "code": "{\n const placements: Placement[] = [\n 'top',\n 'top-start',\n 'top-end',\n 'bottom',\n 'bottom-start',\n 'bottom-end',\n 'left',\n 'left-start',\n 'left-end',\n 'right',\n 'right-start',\n 'right-end',\n ];\n\n return (\n <div\n style={{\n display: 'flex',\n flexWrap: 'wrap',\n gap: 12,\n padding: 120,\n justifyContent: 'center',\n }}\n >\n {placements.map((placement) => (\n <Dropdown\n {...args}\n key={placement}\n placement={placement}\n content={\n <div style={{ padding: 8, fontSize: 13, whiteSpace: 'nowrap' }}>\n {placement}\n </div>\n }\n >\n <Button size=\"small\">{placement}</Button>\n </Dropdown>\n ))}\n </div>\n );\n }",
@@ -1489,6 +1555,12 @@
1489
1555
  "source": "stories",
1490
1556
  "compilable": false
1491
1557
  },
1558
+ "a5a0117d707475ad307fab2299eec3c085bafe1954ddc3724c5fdd67f326f19d": {
1559
+ "title": "Wallet List Panel",
1560
+ "code": "<div style={figmaFrameStyle}>\n <Table<WalletListRow>\n rowKey=\"id\"\n size=\"large\"\n variant=\"stroke\"\n pagination={false}\n columns={walletListPanelColumns}\n dataSource={walletListPanelRows}\n />\n </div>",
1561
+ "source": "stories",
1562
+ "compilable": true
1563
+ },
1492
1564
  "a5a04f0b0f7ad14c2ae616df4f7820ea44171f7317f4ba0ab23f15985159dc24": {
1493
1565
  "title": "Group Directions",
1494
1566
  "code": "{\n const [verticalValue, setVerticalValue] = React.useState<string | number>('a');\n const [horizontalValue, setHorizontalValue] = React.useState<string | number>('a');\n\n const handleVerticalChange = (event: RadioChangeEvent) => {\n if (event.target.value !== undefined) {\n setVerticalValue(event.target.value);\n }\n };\n\n const handleHorizontalChange = (event: RadioChangeEvent) => {\n if (event.target.value !== undefined) {\n setHorizontalValue(event.target.value);\n }\n };\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 24 }}>\n <div>\n <h3 style={{ marginBottom: 12 }}>Direction Vertical</h3>\n <RadioGroup value={verticalValue} onChange={handleVerticalChange} direction=\"vertical\">\n <Radio value=\"a\" label=\"Option A\" />\n <Radio value=\"b\" label=\"Option B\" />\n <Radio value=\"c\" label=\"Option C\" />\n </RadioGroup>\n </div>\n <div>\n <h3 style={{ marginBottom: 12 }}>Direction Horizontal</h3>\n <RadioGroup value={horizontalValue} onChange={handleHorizontalChange} direction=\"horizontal\">\n <Radio value=\"a\" label=\"Option A\" />\n <Radio value=\"b\" label=\"Option B\" />\n <Radio value=\"c\" label=\"Option C\" />\n </RadioGroup>\n </div>\n </div>\n );\n }",
@@ -1693,6 +1765,18 @@
1693
1765
  "source": "readme",
1694
1766
  "compilable": true
1695
1767
  },
1768
+ "b8db243638e9c756f8cc0fc389226284ba74cf2edceef451b608cb3ab9bfc07e": {
1769
+ "title": "Controlled Filters",
1770
+ "code": "{\n const [networkFilter, setNetworkFilter] = useState<TableFilterValue>(['Ethereum']);\n\n return (\n <div>\n <div style={controlBarStyle}>\n <TypographyBody size=\"sm\" color=\"default-tertiary\">\n Programmatically force network filter:\n </TypographyBody>\n <Button size=\"small\" color=\"grey\" onClick={() => setNetworkFilter(['Ethereum'])}>\n Ethereum\n </Button>\n <Button size=\"small\" color=\"grey\" onClick={() => setNetworkFilter(['Solana'])}>\n Solana\n </Button>\n <Button\n size=\"small\"\n color=\"grey\"\n onClick={() => setNetworkFilter(['Ethereum', 'Solana'])}\n >\n ETH + SOL\n </Button>\n <Button size=\"small\" variant=\"text\" onClick={() => setNetworkFilter([])}>\n Reset\n </Button>\n </div>\n <Table<PortfolioRow>\n rowKey=\"id\"\n pagination={false}\n dataSource={portfolioRows}\n // In controlled mode, the built-in filter dropdown's OK / Reset cannot\n // mutate the parent's state directly β€” listen to `onChange` and mirror\n // the new selection back into local state so the round-trip works.\n onChange={(meta) => {\n if (meta.action === 'filter') {\n setNetworkFilter(meta.filters?.network ?? []);\n }\n }}\n columns={[\n portfolioColumns[0],\n {\n ...portfolioColumns[1],\n filters: NETWORK_FILTER_ITEMS,\n filteredValue: networkFilter,\n onFilter: (value, record) => record.network === value,\n },\n portfolioColumns[2],\n portfolioColumns[3],\n ]}\n />\n </div>\n );\n }",
1771
+ "source": "stories",
1772
+ "compilable": true
1773
+ },
1774
+ "b9cc21db46c34c1f749ec2f5cc996c0eb92608376b07b2eb61f2bc427f045927": {
1775
+ "title": "Virtual Scrolling",
1776
+ "code": "{\n const largeData: PortfolioRow[] = Array.from({ length: 5000 }, (_, index) => ({\n id: `virtual-${index + 1}`,\n wallet: `Wallet ${index + 1}`,\n owner: `Desk ${index % 12}`,\n network: ['Ethereum', 'Solana', 'Polygon', 'Arbitrum'][index % 4],\n status: (['active', 'hold', 'review'] as const)[index % 3],\n balance: 200000 + (index * 1375),\n actionLabel: 'Open',\n countryFlag: index % 2 === 0 ? 'πŸ‡ΊπŸ‡Έ' : 'πŸ‡ͺπŸ‡Ί',\n }));\n\n return (\n <div>\n <TypographyBody size=\"sm\" color=\"default-tertiary\" style={hintStyle}>\n 5,000 rows rendered with the virtualized table kernel.\n </TypographyBody>\n <VirtualTable<PortfolioRow>\n rowKey=\"id\"\n columns={virtualColumns}\n dataSource={largeData}\n scroll={{ x: 740, y: 360 }}\n pagination={false}\n />\n </div>\n );\n }",
1777
+ "source": "stories",
1778
+ "compilable": true
1779
+ },
1696
1780
  "ba061872d363c81e7be320d4e4c26b4ed1989d21480077c3a3055d45d54f1afd": {
1697
1781
  "title": "Icon Hover Demo",
1698
1782
  "code": "<div style={{ display: 'flex', gap: 24, flexWrap: 'wrap', alignItems: 'center' }}>\n <IconHover>\n <Icons {...args} name='deposit' />\n </IconHover>\n <IconHover>\n <Icons {...args} name='withdrawal' />\n </IconHover>\n <IconHover>\n <Icons {...args} name='conversion' />\n </IconHover>\n <IconHover>\n <Icons {...args} name='settings' />\n </IconHover>\n <IconHover>\n <Icons {...args} name='notifications' />\n </IconHover>\n <IconHover>\n <Icons {...args} name='cross' />\n </IconHover>\n <IconHover disabled>\n <Icons {...args} name='cross' />\n </IconHover>\n </div>",
@@ -1759,6 +1843,12 @@
1759
1843
  "source": "stories",
1760
1844
  "compilable": true
1761
1845
  },
1846
+ "c23b54aeab8234b5665b9182a68e75b1d9b5ea969d997e08e1d4a41b85679209": {
1847
+ "title": "Sizes",
1848
+ "code": "<div style={stackStyle}>\n <div>\n <TypographyTitle size=\"sm\" strong style={sectionTitleStyle}>\n Large\n </TypographyTitle>\n <Table {...(args as TableProps<Record<string, any>>)} dataSource={portfolioRows.slice(0, 3)} size=\"large\" />\n </div>\n <div>\n <TypographyTitle size=\"sm\" strong style={sectionTitleStyle}>\n Small\n </TypographyTitle>\n <Table {...(args as TableProps<Record<string, any>>)} dataSource={portfolioRows.slice(0, 3)} size=\"small\" />\n </div>\n </div>",
1849
+ "source": "stories",
1850
+ "compilable": false
1851
+ },
1762
1852
  "c2c42c200e9bad53b274260619d36029e7257a5f80b73408ffe619abdf14a9d9": {
1763
1853
  "title": "Canonical usage",
1764
1854
  "code": "import { Drawer } from '@1money/component-ui';\n// or\nimport { Drawer } from '@1money/component-ui/Drawer';",
@@ -1957,12 +2047,24 @@
1957
2047
  "source": "stories",
1958
2048
  "compilable": false
1959
2049
  },
2050
+ "da280e337376d16711ea44dd2d411fa903a7b572376669f415c392652b3c6142": {
2051
+ "title": "Custom Filter Dropdown",
2052
+ "code": "<div>\n <TypographyBody size=\"sm\" color=\"default-tertiary\" style={hintStyle}>\n A consumer-provided dropdown β€” substring match against the wallet name.\n </TypographyBody>\n <Table<PortfolioRow>\n rowKey=\"id\"\n pagination={false}\n dataSource={portfolioRows}\n columns={[\n {\n ...portfolioColumns[0],\n filterDropdown: ({ setSelectedKeys, selectedKeys, confirm, clearFilters }) => (\n <div style={filterDropdownStyle}>\n <input\n autoFocus\n placeholder=\"Search wallet name\"\n value={String(selectedKeys[0] ?? '')}\n onChange={(e) =>\n setSelectedKeys(e.target.value ? [e.target.value] : [])\n }\n style={filterDropdownInputStyle}\n />\n <div style={filterDropdownFooterStyle}>\n <Button size=\"small\" variant=\"text\" onClick={clearFilters}>\n Clear\n </Button>\n <Button size=\"small\" color=\"primary\" onClick={confirm}>\n Search\n </Button>\n </div>\n </div>\n ),\n onFilter: (value, record) =>\n record.wallet.toLowerCase().includes(String(value).toLowerCase()),\n },\n portfolioColumns[1],\n portfolioColumns[2],\n portfolioColumns[3],\n ]}\n />\n </div>",
2053
+ "source": "stories",
2054
+ "compilable": true
2055
+ },
1960
2056
  "da48319e963f8bce14fd2d0e6276dbdb8273cee567181e50abfb14f902872b76": {
1961
2057
  "title": "Colors",
1962
2058
  "code": "<div style={{ display: 'flex', flexWrap: 'wrap', gap: 12, alignItems: 'center' }}>\n {TAG_COLORS.map((color) => (\n <Tag {...args} key={color} color={color} label={color} />\n ))}\n </div>",
1963
2059
  "source": "stories",
1964
2060
  "compilable": false
1965
2061
  },
2062
+ "da7b2e8d26561713d8946001e3c1ba6ea8c38e7fe99e4982b9eadd4fec64215d": {
2063
+ "title": "Nested Data Index",
2064
+ "code": "<div>\n <TypographyBody size=\"sm\" color=\"default-tertiary\" style={hintStyle}>\n Columns read from <code>user.profile.name</code>,{' '}\n <code>user.profile.email</code>, and <code>balance.fiat</code> via\n array-form <code>dataIndex</code>.\n </TypographyBody>\n <Table<NestedWalletRow>\n rowKey=\"id\"\n pagination={false}\n dataSource={nestedRows}\n columns={[\n {\n key: 'name',\n dataIndex: ['user', 'profile', 'name'],\n title: 'Name',\n width: 220,\n },\n {\n key: 'email',\n dataIndex: ['user', 'profile', 'email'],\n title: 'Email',\n width: 260,\n },\n {\n key: 'asset',\n dataIndex: ['balance', 'asset'],\n title: 'Asset',\n width: 120,\n },\n {\n key: 'fiat',\n dataIndex: ['balance', 'fiat'],\n title: 'Balance',\n width: 160,\n align: 'right',\n sorter: (a, b) => a.balance.fiat - b.balance.fiat,\n render: (value) => formatBalance(value as number),\n },\n ]}\n />\n </div>",
2065
+ "source": "stories",
2066
+ "compilable": true
2067
+ },
1966
2068
  "db11dae227995e92880a75b42e93f034782b06757a643753f468b4e0b598692a": {
1967
2069
  "title": "Filter Wrap Spacing",
1968
2070
  "code": "<div style={DEMO_PAGE_STYLE}>\n <Space size={[8, 12]} wrap style={{ maxWidth: 640 }}>\n <div style={DEMO_CHIP_ITEM_STYLE}>All</div>\n <div style={DEMO_CHIP_ITEM_STYLE}>High Risk</div>\n <div style={DEMO_CHIP_ITEM_STYLE}>KYC Pending</div>\n <div style={DEMO_CHIP_ITEM_STYLE}>Manual Review</div>\n <div style={DEMO_CHIP_ITEM_STYLE}>Today</div>\n <div style={DEMO_CHIP_ITEM_STYLE}>This Week</div>\n <div style={DEMO_CHIP_ITEM_STYLE}>Large Amount</div>\n <div style={DEMO_CHIP_ITEM_STYLE}>USDT</div>\n <div style={DEMO_CHIP_ITEM_STYLE}>USD</div>\n </Space>\n </div>",
@@ -2065,6 +2167,12 @@
2065
2167
  "source": "stories",
2066
2168
  "compilable": false
2067
2169
  },
2170
+ "e507eed4788971490bf4cdd4a72e99bbbbb78635073b89a32022fdb2055c6a3b": {
2171
+ "title": "Virtual Usage",
2172
+ "code": "<VirtualTable\n rowKey=\"id\"\n columns={columns}\n dataSource={rows}\n scroll={{ x: 1200, y: 360 }}\n/>",
2173
+ "source": "readme",
2174
+ "compilable": true
2175
+ },
2068
2176
  "e57037f057f4da5ac90baae9ad1d85153cb48c9cfff34a65cbe2a927bf5cb713": {
2069
2177
  "title": "Usage",
2070
2178
  "code": "<Dialog\n open={open}\n title=\"Confirm transfer\"\n onCancel={() => setOpen(false)}\n onOk={handleSubmit}\n/>",
@@ -2143,6 +2251,12 @@
2143
2251
  "source": "stories",
2144
2252
  "compilable": false
2145
2253
  },
2254
+ "ef4904f8e094b98c456651c4a86b1a206b470678f945596a762b38b9855c76ae": {
2255
+ "title": "Rich Checkbox Props",
2256
+ "code": "<div>\n <TypographyBody size=\"sm\" color=\"default-tertiary\" style={hintStyle}>\n Rows in <code>hold</code> state are disabled and carry a per-row{' '}\n <code>title</code> / <code>aria-label</code> for accessibility.\n </TypographyBody>\n <Table<PortfolioRow>\n rowKey=\"id\"\n pagination={false}\n dataSource={portfolioRows.slice(0, 5)}\n columns={portfolioColumns}\n rowSelection={{\n type: 'checkbox',\n getCheckboxProps: (record) => ({\n disabled: record.status === 'hold',\n title:\n record.status === 'hold'\n ? `Locked β€” ${record.wallet} is on hold`\n : `Select ${record.wallet}`,\n 'aria-label': `Toggle selection for ${record.wallet}`,\n }),\n }}\n />\n </div>",
2257
+ "source": "stories",
2258
+ "compilable": true
2259
+ },
2146
2260
  "efb94a978c87bf9343e9605b358b08efa2db1f476e21029ee2bda3da4f275448": {
2147
2261
  "title": "Api Examples",
2148
2262
  "code": "<div style={DEMO_SECTION_STYLE}>\n <Flex\n gap={GAP_MIDDLE}\n align={FLEX_ALIGN.center}\n justify={FLEX_JUSTIFY.spaceBetween}\n wrap={WRAP_DISABLED}\n prefixCls={FLEX_PREFIX}\n >\n <div style={DEMO_BOX_STYLE}>Align</div>\n <div style={DEMO_BOX_STYLE}>Justify</div>\n </Flex>\n\n <Flex vertical gap={GAP_LARGE} wrap={WRAP_ENABLED} prefixCls={FLEX_PREFIX}>\n <div style={DEMO_BOX_STYLE}>Vertical</div>\n <div style={DEMO_BOX_STYLE}>Wrap</div>\n </Flex>\n </div>",
@@ -2203,6 +2317,12 @@
2203
2317
  "source": "readme",
2204
2318
  "compilable": true
2205
2319
  },
2320
+ "f59241468963f180aad8e4bfdf87c64b8defd166186019821c0a5462fcd36f72": {
2321
+ "title": "Import",
2322
+ "code": "import { Table, VirtualTable } from '@1money/component-ui';\n// or\nimport { Table, VirtualTable } from '@1money/component-ui/Table';",
2323
+ "source": "readme",
2324
+ "compilable": true
2325
+ },
2206
2326
  "f5e88271260df2b0e8df1a0b03d96a4c3004f14d0e5aaec8892007d6c41fddb4": {
2207
2327
  "title": "With Disabled",
2208
2328
  "code": "<Tabs\n items={[\n { key: 'tab1', label: 'Overview' },\n { key: 'tab2', label: 'Transactions' },\n { key: 'tab3', label: 'Analytics', disabled: true },\n { key: 'tab4', label: 'Settings' },\n ]}\n />",