@1money/component-ui 0.0.45 β†’ 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 (57) 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/components/Tooltip/Tooltip.js +24 -19
  26. package/es/components/Tooltip/interface.d.ts +2 -0
  27. package/es/index.css +1 -1
  28. package/lib/components/Table/Table.d.ts +2 -2
  29. package/lib/components/Table/Table.js +24 -150
  30. package/lib/components/Table/VirtualTable.d.ts +2 -2
  31. package/lib/components/Table/VirtualTable.js +28 -144
  32. package/lib/components/Table/core/useTableColumns.d.ts +21 -7
  33. package/lib/components/Table/core/useTableColumns.js +65 -13
  34. package/lib/components/Table/core/useTableDataPipeline.d.ts +13 -6
  35. package/lib/components/Table/core/useTableDataPipeline.js +192 -26
  36. package/lib/components/Table/core/useTableExpand.d.ts +2 -2
  37. package/lib/components/Table/core/useTableSelection.d.ts +3 -5
  38. package/lib/components/Table/core/useTableSelection.js +1 -1
  39. package/lib/components/Table/core/useTableSetup.d.ts +42 -0
  40. package/lib/components/Table/core/useTableSetup.js +184 -0
  41. package/lib/components/Table/features/ExpandTrigger.js +2 -1
  42. package/lib/components/Table/features/FilterTrigger.d.ts +9 -0
  43. package/lib/components/Table/features/FilterTrigger.js +164 -0
  44. package/lib/components/Table/features/SelectionColumn.d.ts +3 -2
  45. package/lib/components/Table/features/SelectionColumn.js +19 -6
  46. package/lib/components/Table/interface.d.ts +102 -21
  47. package/lib/components/Table/renderers/BodyCell.d.ts +4 -4
  48. package/lib/components/Table/renderers/BodyCell.js +1 -1
  49. package/lib/components/Table/renderers/HeaderCell.d.ts +8 -4
  50. package/lib/components/Table/renderers/HeaderCell.js +13 -3
  51. package/lib/components/Table/style/Table.css +1 -1
  52. package/lib/components/Tooltip/Tooltip.js +24 -19
  53. package/lib/components/Tooltip/interface.d.ts +2 -0
  54. package/lib/index.css +1 -1
  55. package/package.json +1 -1
  56. package/scripts/mcp-server/examples.generated.json +126 -0
  57. package/scripts/mcp-server/index.generated.json +348 -14
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1money/component-ui",
3
- "version": "0.0.45",
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 />",
@@ -865,6 +907,12 @@
865
907
  "source": "stories",
866
908
  "compilable": true
867
909
  },
910
+ "5d0dff10d14f4ead2855259dace828f08c55f468c98f3d4852244078bbe6d87c": {
911
+ "title": "With Portal Container",
912
+ "code": "{\n const clippedParentStyle: CSSProperties = {\n display: 'flex',\n gap: 24,\n padding: 24,\n width: 320,\n height: 120,\n overflow: 'hidden',\n border: '1px dashed #d7dee7',\n borderRadius: 8,\n background: '#f8fafc',\n };\n const customContainerStyle: CSSProperties = {\n position: 'relative',\n padding: 24,\n width: 320,\n minHeight: 120,\n border: '1px dashed #4f8cff',\n borderRadius: 8,\n background: '#eef4ff',\n };\n\n return (\n <div style={{ display: 'flex', flexDirection: 'column', gap: 32, padding: 80 }}>\n <div>\n <p style={PREVIEW_LABEL_STYLE}>\n Default β€” portaled to <code>document.body</code>, escapes ancestor <code>overflow: hidden</code>\n </p>\n <div style={clippedParentStyle}>\n <button id=\"tooltip-portal-default\">Hover me</button>\n <Tooltip\n anchorSelect=\"#tooltip-portal-default\"\n placement=\"bottom\"\n title=\"Portaled to body\"\n body=\"By default the tooltip is rendered in document.body, so the parent overflow can't clip it.\"\n />\n </div>\n </div>\n\n <div>\n <p style={PREVIEW_LABEL_STYLE}>\n Custom container β€” <code>getPopupContainer</code> returns the blue box\n </p>\n <div id=\"tooltip-portal-custom-container\" style={customContainerStyle}>\n <button id=\"tooltip-portal-custom\">Hover me</button>\n <Tooltip\n anchorSelect=\"#tooltip-portal-custom\"\n placement=\"bottom\"\n title=\"Custom container\"\n body=\"The tooltip DOM is mounted inside the blue box via getPopupContainer.\"\n getPopupContainer={() =>\n document.getElementById('tooltip-portal-custom-container') as HTMLElement\n }\n />\n </div>\n </div>\n </div>\n );\n }",
913
+ "source": "stories",
914
+ "compilable": true
915
+ },
868
916
  "5dc10afdccbf1759489ec0ca6e8837d8edd2fdacf6965a82e879ea4b1fe9cfbc": {
869
917
  "title": "All Variants",
870
918
  "code": "<div style={{ display: 'flex', flexDirection: 'column', gap: 32 }}>\n <div>\n <h3 style={{ marginBottom: 12 }}>Default (3 items)</h3>\n <Segment items={DEFAULT_ITEMS} />\n </div>\n <div>\n <h3 style={{ marginBottom: 12 }}>5 items</h3>\n <Segment\n items={[\n { value: '1', label: 'Label' },\n { value: '2', label: 'Label' },\n { value: '3', label: 'Label' },\n { value: '4', label: 'Label' },\n { value: '5', label: 'Label' },\n ]}\n />\n </div>\n <div>\n <h3 style={{ marginBottom: 12 }}>With disabled item</h3>\n <Segment\n items={[\n { value: '1', label: 'Active' },\n { value: '2', label: 'Normal' },\n { value: '3', label: 'Disabled', disabled: true },\n ]}\n />\n </div>\n </div>",
@@ -985,6 +1033,12 @@
985
1033
  "source": "readme",
986
1034
  "compilable": true
987
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
+ },
988
1042
  "6f2b7da00479a6033fdaca36f0646a924c61cbf09cd0e07da6948a884af98a61": {
989
1043
  "title": "Dependency",
990
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>",
@@ -1201,6 +1255,12 @@
1201
1255
  "source": "readme",
1202
1256
  "compilable": true
1203
1257
  },
1258
+ "83d457fb7d2b3478dda19b79185daa8909a55b9786ff1b3cf560cec95743926d": {
1259
+ "title": "Basic Usage",
1260
+ "code": "<Table rowKey=\"id\" columns={columns} dataSource={rows} />",
1261
+ "source": "readme",
1262
+ "compilable": true
1263
+ },
1204
1264
  "842244e70f89e2aaf6941718de836ab3a6e08d642a4d4bb2e80cee160158470f": {
1205
1265
  "title": "Default",
1206
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 }",
@@ -1345,6 +1405,12 @@
1345
1405
  "source": "stories",
1346
1406
  "compilable": false
1347
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
+ },
1348
1414
  "96a4fb49627068cd32df95bce74ab746a2901c627dcd70fa9bf9c9247f21b7a3": {
1349
1415
  "title": "Canonical usage",
1350
1416
  "code": "import { Trigger } from '@1money/component-ui';\n// or\nimport { Trigger } from '@1money/component-ui/Trigger';",
@@ -1417,6 +1483,12 @@
1417
1483
  "source": "canonical",
1418
1484
  "compilable": true
1419
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
+ },
1420
1492
  "9eae41b47da6d3b07d6bfdb98fe407b6be85aa68db3fe695699cf9588b65eda8": {
1421
1493
  "title": "Placements",
1422
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 }",
@@ -1483,6 +1555,12 @@
1483
1555
  "source": "stories",
1484
1556
  "compilable": false
1485
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
+ },
1486
1564
  "a5a04f0b0f7ad14c2ae616df4f7820ea44171f7317f4ba0ab23f15985159dc24": {
1487
1565
  "title": "Group Directions",
1488
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 }",
@@ -1687,6 +1765,18 @@
1687
1765
  "source": "readme",
1688
1766
  "compilable": true
1689
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
+ },
1690
1780
  "ba061872d363c81e7be320d4e4c26b4ed1989d21480077c3a3055d45d54f1afd": {
1691
1781
  "title": "Icon Hover Demo",
1692
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>",
@@ -1753,6 +1843,12 @@
1753
1843
  "source": "stories",
1754
1844
  "compilable": true
1755
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
+ },
1756
1852
  "c2c42c200e9bad53b274260619d36029e7257a5f80b73408ffe619abdf14a9d9": {
1757
1853
  "title": "Canonical usage",
1758
1854
  "code": "import { Drawer } from '@1money/component-ui';\n// or\nimport { Drawer } from '@1money/component-ui/Drawer';",
@@ -1951,12 +2047,24 @@
1951
2047
  "source": "stories",
1952
2048
  "compilable": false
1953
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
+ },
1954
2056
  "da48319e963f8bce14fd2d0e6276dbdb8273cee567181e50abfb14f902872b76": {
1955
2057
  "title": "Colors",
1956
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>",
1957
2059
  "source": "stories",
1958
2060
  "compilable": false
1959
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
+ },
1960
2068
  "db11dae227995e92880a75b42e93f034782b06757a643753f468b4e0b598692a": {
1961
2069
  "title": "Filter Wrap Spacing",
1962
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>",
@@ -2059,6 +2167,12 @@
2059
2167
  "source": "stories",
2060
2168
  "compilable": false
2061
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
+ },
2062
2176
  "e57037f057f4da5ac90baae9ad1d85153cb48c9cfff34a65cbe2a927bf5cb713": {
2063
2177
  "title": "Usage",
2064
2178
  "code": "<Dialog\n open={open}\n title=\"Confirm transfer\"\n onCancel={() => setOpen(false)}\n onOk={handleSubmit}\n/>",
@@ -2137,6 +2251,12 @@
2137
2251
  "source": "stories",
2138
2252
  "compilable": false
2139
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
+ },
2140
2260
  "efb94a978c87bf9343e9605b358b08efa2db1f476e21029ee2bda3da4f275448": {
2141
2261
  "title": "Api Examples",
2142
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>",
@@ -2197,6 +2317,12 @@
2197
2317
  "source": "readme",
2198
2318
  "compilable": true
2199
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
+ },
2200
2326
  "f5e88271260df2b0e8df1a0b03d96a4c3004f14d0e5aaec8892007d6c41fddb4": {
2201
2327
  "title": "With Disabled",
2202
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 />",