@duro-app/ui 0.23.0 → 0.25.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.
Files changed (100) hide show
  1. package/dist/components/ButtonGroup/ButtonGroup.d.ts +14 -0
  2. package/dist/components/ButtonGroup/ButtonGroup.d.ts.map +1 -0
  3. package/dist/components/ButtonGroup/ButtonGroup.meta.d.ts +3 -0
  4. package/dist/components/ButtonGroup/ButtonGroup.meta.d.ts.map +1 -0
  5. package/dist/components/ButtonGroup/ButtonGroup.stories.d.ts +11 -0
  6. package/dist/components/ButtonGroup/ButtonGroup.stories.d.ts.map +1 -0
  7. package/dist/components/ButtonGroup/styles.css.d.ts +45 -0
  8. package/dist/components/ButtonGroup/styles.css.d.ts.map +1 -0
  9. package/dist/components/CheckboxGroup/CheckboxGroup.d.ts.map +1 -1
  10. package/dist/components/CheckboxGroup/CheckboxGroup.meta.d.ts.map +1 -1
  11. package/dist/components/Combobox/Combobox.d.ts +44 -0
  12. package/dist/components/Combobox/Combobox.d.ts.map +1 -0
  13. package/dist/components/Combobox/Combobox.meta.d.ts +3 -0
  14. package/dist/components/Combobox/Combobox.meta.d.ts.map +1 -0
  15. package/dist/components/Combobox/Combobox.stories.d.ts +9 -0
  16. package/dist/components/Combobox/Combobox.stories.d.ts.map +1 -0
  17. package/dist/components/Combobox/ComboboxContext.d.ts +19 -0
  18. package/dist/components/Combobox/ComboboxContext.d.ts.map +1 -0
  19. package/dist/components/Combobox/styles.css.d.ts +112 -0
  20. package/dist/components/Combobox/styles.css.d.ts.map +1 -0
  21. package/dist/components/Combobox/useComboboxRoot.d.ts +15 -0
  22. package/dist/components/Combobox/useComboboxRoot.d.ts.map +1 -0
  23. package/dist/components/Field/Field.d.ts +4 -0
  24. package/dist/components/Field/Field.d.ts.map +1 -1
  25. package/dist/components/Field/Field.stories.d.ts +3 -0
  26. package/dist/components/Field/Field.stories.d.ts.map +1 -1
  27. package/dist/components/Field/FieldContext.d.ts +5 -0
  28. package/dist/components/Field/FieldContext.d.ts.map +1 -1
  29. package/dist/components/Field/styles.css.d.ts +26 -0
  30. package/dist/components/Field/styles.css.d.ts.map +1 -1
  31. package/dist/components/Form/Form.d.ts +7 -2
  32. package/dist/components/Form/Form.d.ts.map +1 -1
  33. package/dist/components/Form/Form.stories.d.ts +6 -0
  34. package/dist/components/Form/Form.stories.d.ts.map +1 -1
  35. package/dist/components/Form/FormContext.d.ts +9 -2
  36. package/dist/components/Form/FormContext.d.ts.map +1 -1
  37. package/dist/components/Input/Input.d.ts.map +1 -1
  38. package/dist/components/List/List.d.ts.map +1 -1
  39. package/dist/components/List/List.meta.d.ts.map +1 -1
  40. package/dist/components/List/List.stories.d.ts.map +1 -1
  41. package/dist/components/RadioGroup/RadioGroup.d.ts.map +1 -1
  42. package/dist/components/RadioGroup/RadioGroup.meta.d.ts.map +1 -1
  43. package/dist/components/Table/ColumnFilter.d.ts +8 -0
  44. package/dist/components/Table/ColumnFilter.d.ts.map +1 -0
  45. package/dist/components/Table/Pagination.d.ts +7 -0
  46. package/dist/components/Table/Pagination.d.ts.map +1 -0
  47. package/dist/components/Table/SortIndicator.d.ts +16 -0
  48. package/dist/components/Table/SortIndicator.d.ts.map +1 -0
  49. package/dist/components/Table/Table.d.ts +7 -1
  50. package/dist/components/Table/Table.d.ts.map +1 -1
  51. package/dist/components/Table/Table.stories.d.ts +4 -0
  52. package/dist/components/Table/Table.stories.d.ts.map +1 -1
  53. package/dist/components/Table/styles.css.d.ts +11 -3
  54. package/dist/components/Table/styles.css.d.ts.map +1 -1
  55. package/dist/components/Table/useDataTable.d.ts +32 -0
  56. package/dist/components/Table/useDataTable.d.ts.map +1 -0
  57. package/dist/components/Textarea/Textarea.d.ts.map +1 -1
  58. package/dist/index.css +1 -1
  59. package/dist/index.d.ts +3 -0
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js +2863 -2026
  62. package/dist/index.js.map +1 -1
  63. package/package.json +3 -2
  64. package/src/components/ActionBar/ActionBar.stories.tsx +3 -3
  65. package/src/components/ButtonGroup/ButtonGroup.meta.ts +32 -0
  66. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +103 -0
  67. package/src/components/ButtonGroup/ButtonGroup.tsx +59 -0
  68. package/src/components/ButtonGroup/styles.css.ts +28 -0
  69. package/src/components/CheckboxGroup/CheckboxGroup.meta.ts +4 -1
  70. package/src/components/CheckboxGroup/CheckboxGroup.tsx +2 -9
  71. package/src/components/Combobox/Combobox.meta.ts +35 -0
  72. package/src/components/Combobox/Combobox.stories.tsx +119 -0
  73. package/src/components/Combobox/Combobox.tsx +247 -0
  74. package/src/components/Combobox/ComboboxContext.ts +26 -0
  75. package/src/components/Combobox/styles.css.ts +119 -0
  76. package/src/components/Combobox/useComboboxRoot.ts +235 -0
  77. package/src/components/Field/Field.stories.tsx +60 -0
  78. package/src/components/Field/Field.tsx +97 -9
  79. package/src/components/Field/FieldContext.ts +5 -0
  80. package/src/components/Field/styles.css.ts +26 -0
  81. package/src/components/Form/Form.stories.tsx +275 -0
  82. package/src/components/Form/Form.tsx +73 -7
  83. package/src/components/Form/FormContext.ts +10 -1
  84. package/src/components/Input/Input.tsx +2 -1
  85. package/src/components/List/List.meta.ts +8 -2
  86. package/src/components/List/List.stories.tsx +35 -15
  87. package/src/components/List/List.tsx +1 -5
  88. package/src/components/RadioGroup/RadioGroup.meta.ts +4 -1
  89. package/src/components/RadioGroup/RadioGroup.tsx +1 -4
  90. package/src/components/Table/ColumnFilter.tsx +46 -0
  91. package/src/components/Table/Pagination.tsx +82 -0
  92. package/src/components/Table/SortIndicator.tsx +53 -0
  93. package/src/components/Table/Table.stories.tsx +397 -0
  94. package/src/components/Table/Table.tsx +58 -24
  95. package/src/components/Table/styles.css.ts +16 -6
  96. package/src/components/Table/useDataTable.ts +99 -0
  97. package/src/components/Textarea/Textarea.tsx +2 -1
  98. package/src/docs/helpers.tsx +2 -2
  99. package/src/index.ts +5 -0
  100. package/src/strict.css +5 -0
@@ -0,0 +1,99 @@
1
+ import {useCallback, useState} from 'react'
2
+ import {
3
+ useReactTable,
4
+ getCoreRowModel,
5
+ getPaginationRowModel,
6
+ getSortedRowModel,
7
+ getFilteredRowModel,
8
+ type ColumnDef,
9
+ type SortingState,
10
+ type ColumnFiltersState,
11
+ type PaginationState,
12
+ type RowSelectionState,
13
+ type Table,
14
+ } from '@tanstack/react-table'
15
+
16
+ export interface UseDataTableOptions<TData> {
17
+ /** Initial pagination state */
18
+ pagination?: {pageSize?: number; pageIndex?: number}
19
+ /** Enable sorting on columns that don't explicitly disable it */
20
+ enableSorting?: boolean
21
+ /** Enable column filtering */
22
+ enableFiltering?: boolean
23
+ /** Enable row selection (checkbox) */
24
+ enableRowSelection?: boolean | ((row: any) => boolean)
25
+ /** Callback when row selection changes */
26
+ onRowSelectionChange?: (selection: RowSelectionState) => void
27
+ }
28
+
29
+ /**
30
+ * Thin wrapper around TanStack's useReactTable.
31
+ * Pre-configures row models for pagination, sorting, and filtering.
32
+ * Returns the full TanStack table instance.
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * const table = useDataTable(users, columns, {
37
+ * pagination: { pageSize: 20 },
38
+ * enableSorting: true,
39
+ * enableFiltering: true,
40
+ * })
41
+ * ```
42
+ */
43
+ export function useDataTable<TData>(
44
+ data: TData[],
45
+ columns: ColumnDef<TData, any>[],
46
+ options: UseDataTableOptions<TData> = {},
47
+ ): Table<TData> {
48
+ const {
49
+ enableSorting = false,
50
+ enableFiltering = false,
51
+ enableRowSelection = false,
52
+ onRowSelectionChange: onSelectionChangeProp,
53
+ } = options
54
+
55
+ const enablePagination = options.pagination != null
56
+
57
+ const [sorting, setSorting] = useState<SortingState>([])
58
+ const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
59
+ const [pagination, setPagination] = useState<PaginationState>({
60
+ pageIndex: options.pagination?.pageIndex ?? 0,
61
+ pageSize: options.pagination?.pageSize ?? 10,
62
+ })
63
+ const [rowSelection, setRowSelection] = useState<RowSelectionState>({})
64
+
65
+ const handleRowSelectionChange = useCallback(
66
+ (updater: any) => {
67
+ setRowSelection((prev: RowSelectionState) => {
68
+ const next = typeof updater === 'function' ? updater(prev) : updater
69
+ onSelectionChangeProp?.(next)
70
+ return next
71
+ })
72
+ },
73
+ [onSelectionChangeProp],
74
+ )
75
+
76
+ // Follow TanStack's recommended pattern: always pass all row models
77
+ // unconditionally and let the library handle unused ones. Conditional
78
+ // spreads create unstable option shapes that can trigger infinite loops.
79
+ return useReactTable({
80
+ data,
81
+ columns,
82
+ state: {sorting, columnFilters, pagination, rowSelection},
83
+ getCoreRowModel: getCoreRowModel(),
84
+ getSortedRowModel: getSortedRowModel(),
85
+ getFilteredRowModel: getFilteredRowModel(),
86
+ getPaginationRowModel: getPaginationRowModel(),
87
+ onSortingChange: setSorting,
88
+ onColumnFiltersChange: setColumnFilters,
89
+ onPaginationChange: setPagination,
90
+ enableSorting,
91
+ enableRowSelection:
92
+ typeof enableRowSelection === 'function' ? enableRowSelection : !!enableRowSelection,
93
+ onRowSelectionChange: handleRowSelectionChange,
94
+ // When pagination is disabled, set a very large page size to show all rows
95
+ ...(!enablePagination && {
96
+ autoResetPageIndex: false,
97
+ }),
98
+ })
99
+ }
@@ -41,6 +41,7 @@ export function Textarea({
41
41
  const effectiveOnChange = onChange ?? fieldCtx?.onChange
42
42
  const effectiveOnBlur = onBlur ?? fieldCtx?.onBlur
43
43
  const effectiveRef = ref ?? fieldCtx?.ref
44
+ const effectiveDisabled = disabled ?? ctx?.disabled
44
45
  const effectiveVariant = ctx?.invalid ? 'error' : variant
45
46
 
46
47
  return (
@@ -52,7 +53,7 @@ export function Textarea({
52
53
  rows={rows}
53
54
  value={effectiveValue}
54
55
  defaultValue={defaultValue}
55
- disabled={disabled}
56
+ disabled={effectiveDisabled}
56
57
  aria-describedby={
57
58
  ctx ? `${ctx.descriptionId} ${ctx.invalid ? ctx.errorId : ''}`.trim() : undefined
58
59
  }
@@ -64,7 +64,7 @@ export function TypeScaleTable({rows, label}: TypeScaleTableProps) {
64
64
  return (
65
65
  <html.div>
66
66
  {label && <html.h3 style={styles.label}>{label}</html.h3>}
67
- <Table.Root columns={4} variant="striped" size="sm">
67
+ <Table.Root variant="striped" size="sm">
68
68
  <Table.Header>
69
69
  <Table.Row>
70
70
  <Table.HeaderCell>Step</Table.HeaderCell>
@@ -106,7 +106,7 @@ export function TokenTable({tokens, label}: TokenTableProps) {
106
106
  return (
107
107
  <html.div>
108
108
  {label && <html.h3 style={styles.label}>{label}</html.h3>}
109
- <Table.Root columns={3} variant="striped" size="sm">
109
+ <Table.Root variant="striped" size="sm">
110
110
  <Table.Header>
111
111
  <Table.Row>
112
112
  <Table.HeaderCell>Token</Table.HeaderCell>
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ export {Alert, type AlertVariant} from './components/Alert/Alert'
8
8
  export {Icon, type IconName} from './components/Icon'
9
9
  export {Badge, type BadgeVariant, type BadgeSize} from './components/Badge/Badge'
10
10
  export {Button, type ButtonVariant, type ButtonSize} from './components/Button/Button'
11
+ export {ButtonGroup} from './components/ButtonGroup/ButtonGroup'
11
12
  export {Callout, type CalloutVariant} from './components/Callout/Callout'
12
13
  export {Card, type CardVariant, type CardSize} from './components/Card/Card'
13
14
  export {Checkbox} from './components/Checkbox/Checkbox'
@@ -20,6 +21,7 @@ export {Heading, type HeadingVariant} from './components/Heading/Heading'
20
21
  export {List, type ListSelectionMode} from './components/List/List'
21
22
  export {Field} from './components/Field/Field'
22
23
  export {Form, type FormProps} from './components/Form/Form'
24
+ export type {LabelPosition, NecessityIndicator} from './components/Form/FormContext'
23
25
  export {Fieldset, type FieldsetGap} from './components/Fieldset/Fieldset'
24
26
  export {Input, type InputVariant} from './components/Input/Input'
25
27
  export {InputGroup} from './components/InputGroup/InputGroup'
@@ -32,6 +34,7 @@ export {Menu} from './components/Menu/Menu'
32
34
  export {Panel} from './components/Panel/Panel'
33
35
  export {RadioGroup} from './components/RadioGroup/RadioGroup'
34
36
  export {ScrollArea} from './components/ScrollArea/ScrollArea'
37
+ export {Combobox} from './components/Combobox/Combobox'
35
38
  export {Select} from './components/Select/Select'
36
39
  export {SideNav} from './components/SideNav/SideNav'
37
40
  export {Spinner, type SpinnerSize} from './components/Spinner/Spinner'
@@ -41,6 +44,8 @@ export {
41
44
  type StatusIconVariant,
42
45
  } from './components/StatusIcon/StatusIcon'
43
46
  export {Table, type TableVariant, type TableSize} from './components/Table/Table'
47
+ // TanStack Table: consumers install @tanstack/react-table directly and use
48
+ // Table.Pagination, Table.SortIndicator, Table.ColumnFilter for styled integration
44
49
  export {Tabs} from './components/Tabs/Tabs'
45
50
  export {Textarea, type TextareaVariant} from './components/Textarea/Textarea'
46
51
  export {ThemeProvider, type ThemeName} from './components/ThemeProvider/ThemeProvider'
package/src/strict.css CHANGED
@@ -1,2 +1,7 @@
1
1
  @layer reset;
2
2
  @react-strict-dom;
3
+
4
+ /* Table: reveal sort indicator on header cell hover */
5
+ [role='columnheader']:hover [data-sort-indicator] {
6
+ opacity: 1 !important;
7
+ }