@duro-app/ui 0.22.0 → 0.23.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 (53) hide show
  1. package/dist/components/Alert/Alert.meta.d.ts.map +1 -1
  2. package/dist/components/Callout/Callout.meta.d.ts.map +1 -1
  3. package/dist/components/Card/Card.meta.d.ts.map +1 -1
  4. package/dist/components/CheckboxGroup/CheckboxGroup.d.ts +22 -0
  5. package/dist/components/CheckboxGroup/CheckboxGroup.d.ts.map +1 -0
  6. package/dist/components/CheckboxGroup/CheckboxGroup.meta.d.ts +3 -0
  7. package/dist/components/CheckboxGroup/CheckboxGroup.meta.d.ts.map +1 -0
  8. package/dist/components/CheckboxGroup/CheckboxGroup.stories.d.ts +9 -0
  9. package/dist/components/CheckboxGroup/CheckboxGroup.stories.d.ts.map +1 -0
  10. package/dist/components/CheckboxGroup/styles.css.d.ts +12 -0
  11. package/dist/components/CheckboxGroup/styles.css.d.ts.map +1 -0
  12. package/dist/components/EmptyState/EmptyState.meta.d.ts.map +1 -1
  13. package/dist/components/InputGroup/InputGroup.meta.d.ts.map +1 -1
  14. package/dist/components/RadioGroup/RadioGroup.d.ts +22 -0
  15. package/dist/components/RadioGroup/RadioGroup.d.ts.map +1 -0
  16. package/dist/components/RadioGroup/RadioGroup.meta.d.ts +3 -0
  17. package/dist/components/RadioGroup/RadioGroup.meta.d.ts.map +1 -0
  18. package/dist/components/RadioGroup/RadioGroup.stories.d.ts +9 -0
  19. package/dist/components/RadioGroup/RadioGroup.stories.d.ts.map +1 -0
  20. package/dist/components/RadioGroup/styles.css.d.ts +60 -0
  21. package/dist/components/RadioGroup/styles.css.d.ts.map +1 -0
  22. package/dist/components/StatusIcon/StatusIcon.meta.d.ts.map +1 -1
  23. package/dist/components/Table/Table.d.ts +4 -3
  24. package/dist/components/Table/Table.d.ts.map +1 -1
  25. package/dist/components/Table/styles.css.d.ts +1 -1
  26. package/dist/components/ThemeProvider/ThemeProvider.meta.d.ts.map +1 -1
  27. package/dist/index.css +1 -1
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +1252 -1034
  31. package/dist/index.js.map +1 -1
  32. package/package.json +2 -2
  33. package/src/components/Alert/Alert.meta.ts +4 -1
  34. package/src/components/Callout/Callout.meta.ts +4 -1
  35. package/src/components/Card/Card.meta.ts +4 -1
  36. package/src/components/Checkbox/styles.css.ts +1 -1
  37. package/src/components/CheckboxGroup/CheckboxGroup.meta.ts +25 -0
  38. package/src/components/CheckboxGroup/CheckboxGroup.stories.tsx +88 -0
  39. package/src/components/CheckboxGroup/CheckboxGroup.tsx +105 -0
  40. package/src/components/CheckboxGroup/styles.css.ts +13 -0
  41. package/src/components/EmptyState/EmptyState.meta.ts +1 -4
  42. package/src/components/Icon/Icon.meta.ts +5 -5
  43. package/src/components/InputGroup/InputGroup.meta.ts +4 -1
  44. package/src/components/RadioGroup/RadioGroup.meta.ts +25 -0
  45. package/src/components/RadioGroup/RadioGroup.stories.tsx +83 -0
  46. package/src/components/RadioGroup/RadioGroup.tsx +113 -0
  47. package/src/components/RadioGroup/styles.css.ts +66 -0
  48. package/src/components/StatusIcon/StatusIcon.meta.ts +1 -4
  49. package/src/components/Table/Table.stories.tsx +9 -9
  50. package/src/components/Table/Table.tsx +31 -15
  51. package/src/components/Table/styles.css.ts +2 -2
  52. package/src/components/ThemeProvider/ThemeProvider.meta.ts +1 -3
  53. package/src/index.ts +2 -0
@@ -55,7 +55,7 @@ function statusVariant(status: string) {
55
55
 
56
56
  export const Default: Story = {
57
57
  render: () => (
58
- <Table.Root columns={4}>
58
+ <Table.Root>
59
59
  <Table.Header>
60
60
  <Table.Row>
61
61
  <Table.HeaderCell>Service</Table.HeaderCell>
@@ -108,7 +108,7 @@ export const Default: Story = {
108
108
 
109
109
  export const Striped: Story = {
110
110
  render: () => (
111
- <Table.Root variant="striped" columns={4}>
111
+ <Table.Root variant="striped">
112
112
  <Table.Header>
113
113
  <Table.Row>
114
114
  <Table.HeaderCell>Service</Table.HeaderCell>
@@ -141,7 +141,7 @@ export const Striped: Story = {
141
141
 
142
142
  export const Bordered: Story = {
143
143
  render: () => (
144
- <Table.Root variant="bordered" columns={4}>
144
+ <Table.Root variant="bordered">
145
145
  <Table.Header>
146
146
  <Table.Row>
147
147
  <Table.HeaderCell>Service</Table.HeaderCell>
@@ -175,7 +175,7 @@ export const Bordered: Story = {
175
175
 
176
176
  export const Compact: Story = {
177
177
  render: () => (
178
- <Table.Root size="sm" columns={4}>
178
+ <Table.Root size="sm">
179
179
  <Table.Header>
180
180
  <Table.Row>
181
181
  <Table.HeaderCell>Service</Table.HeaderCell>
@@ -248,7 +248,7 @@ function CheckboxTableDemo() {
248
248
 
249
249
  return (
250
250
  <>
251
- <Table.Root columns={5}>
251
+ <Table.Root>
252
252
  <Table.Header>
253
253
  <Table.Row>
254
254
  <Table.HeaderCell aria-label="Select all">
@@ -316,7 +316,7 @@ export const AllVariants: Story = {
316
316
  <html.div style={storyStyles.stack}>
317
317
  <html.div>
318
318
  <html.span style={storyStyles.label}>Default</html.span>
319
- <Table.Root columns={3}>
319
+ <Table.Root>
320
320
  <Table.Header>
321
321
  <Table.Row>
322
322
  <Table.HeaderCell>Name</Table.HeaderCell>
@@ -341,7 +341,7 @@ export const AllVariants: Story = {
341
341
 
342
342
  <html.div>
343
343
  <html.span style={storyStyles.label}>Striped</html.span>
344
- <Table.Root variant="striped" columns={3}>
344
+ <Table.Root variant="striped">
345
345
  <Table.Header>
346
346
  <Table.Row>
347
347
  <Table.HeaderCell>Name</Table.HeaderCell>
@@ -371,7 +371,7 @@ export const AllVariants: Story = {
371
371
 
372
372
  <html.div>
373
373
  <html.span style={storyStyles.label}>Bordered</html.span>
374
- <Table.Root variant="bordered" columns={3}>
374
+ <Table.Root variant="bordered">
375
375
  <Table.Header>
376
376
  <Table.Row>
377
377
  <Table.HeaderCell>Name</Table.HeaderCell>
@@ -396,7 +396,7 @@ export const AllVariants: Story = {
396
396
 
397
397
  <html.div>
398
398
  <html.span style={storyStyles.label}>Compact (sm)</html.span>
399
- <Table.Root size="sm" columns={3}>
399
+ <Table.Root size="sm">
400
400
  <Table.Header>
401
401
  <Table.Row>
402
402
  <Table.HeaderCell>Name</Table.HeaderCell>
@@ -1,4 +1,4 @@
1
- import {type ReactNode, createContext, useContext, Children} from 'react'
1
+ import {type ReactNode, type MutableRefObject, createContext, useContext, useRef, Children, isValidElement} from 'react'
2
2
  import {html} from 'react-strict-dom'
3
3
  import {styles} from './styles.css'
4
4
 
@@ -12,8 +12,8 @@ export type TableSize = 'sm' | 'md'
12
12
  interface TableContextValue {
13
13
  variant: TableVariant
14
14
  size: TableSize
15
- columns: number
16
- isHeader: boolean
15
+ /** Mutable ref: header Row writes inferred template, body Rows read it */
16
+ inferredTemplateRef: MutableRefObject<string | null>
17
17
  }
18
18
 
19
19
  const TableContext = createContext<TableContextValue | null>(null)
@@ -24,7 +24,7 @@ function useTable() {
24
24
  return ctx
25
25
  }
26
26
 
27
- // --- HeaderContext (to distinguish header vs body rowgroup) ---
27
+ // --- HeaderContext ---
28
28
 
29
29
  const HeaderContext = createContext(false)
30
30
 
@@ -34,12 +34,13 @@ interface RootProps {
34
34
  children: ReactNode
35
35
  variant?: TableVariant
36
36
  size?: TableSize
37
- columns: number
38
37
  }
39
38
 
40
- function Root({children, variant = 'default', size = 'md', columns}: RootProps) {
39
+ function Root({children, variant = 'default', size = 'md'}: RootProps) {
40
+ const inferredTemplateRef = useRef<string | null>(null)
41
+
41
42
  return (
42
- <TableContext.Provider value={{variant, size, columns, isHeader: false}}>
43
+ <TableContext.Provider value={{variant, size, inferredTemplateRef}}>
43
44
  <html.div role="table" style={styles.root}>
44
45
  {children}
45
46
  </html.div>
@@ -83,24 +84,40 @@ function Body({children}: {children: ReactNode}) {
83
84
  )
84
85
  }
85
86
 
86
- // Row index context for striped variant
87
87
  const RowIndexContext = createContext<number>(-1)
88
88
 
89
89
  // --- Row ---
90
90
 
91
91
  function Row({children}: {children: ReactNode}) {
92
- const {variant, columns} = useTable()
92
+ const {variant, inferredTemplateRef} = useTable()
93
93
  const isHeader = useContext(HeaderContext)
94
94
  const rowIndex = useContext(RowIndexContext)
95
95
  const isEvenRow = rowIndex >= 0 && rowIndex % 2 === 1
96
96
  const childArray = Children.toArray(children)
97
97
 
98
+ let template: string
99
+
100
+ if (isHeader) {
101
+ // Build template from HeaderCell width props
102
+ const widths: string[] = []
103
+ Children.forEach(children, (child) => {
104
+ if (isValidElement(child)) {
105
+ const props = child.props as {width?: string}
106
+ widths.push(props.width || '1fr')
107
+ }
108
+ })
109
+ template = widths.join(' ')
110
+ inferredTemplateRef.current = template
111
+ } else {
112
+ template = inferredTemplateRef.current ?? `repeat(${childArray.length}, 1fr)`
113
+ }
114
+
98
115
  return (
99
116
  <html.div
100
117
  role="row"
101
118
  style={[
102
119
  styles.row,
103
- styles.gridColumns(columns),
120
+ styles.gridColumns(template),
104
121
  !isHeader && styles.bodyRow,
105
122
  !isHeader && variant === 'striped' && isEvenRow && styles.stripedEven,
106
123
  ]}
@@ -116,19 +133,18 @@ function Row({children}: {children: ReactNode}) {
116
133
  )
117
134
  }
118
135
 
119
- // Cell index context for bordered variant
120
- const CellIndexContext = createContext<{index: number; total: number}>({
121
- index: 0,
122
- total: 0,
123
- })
136
+ const CellIndexContext = createContext<{index: number; total: number}>({index: 0, total: 0})
124
137
 
125
138
  // --- HeaderCell ---
126
139
 
127
140
  function HeaderCell({
128
141
  children,
142
+ width: _width,
129
143
  'aria-label': ariaLabel,
130
144
  }: {
131
145
  children?: ReactNode
146
+ /** Column width: CSS value like '40px', '2fr', 'auto'. Defaults to '1fr'. */
147
+ width?: string
132
148
  'aria-label'?: string
133
149
  }) {
134
150
  const {size, variant} = useTable()
@@ -91,7 +91,7 @@ export const styles = css.create({
91
91
  },
92
92
 
93
93
  // Dynamic styles — simple identifier params only (StyleX constraint)
94
- gridColumns: (columns: number) => ({
95
- gridTemplateColumns: `repeat(${columns}, 1fr)`,
94
+ gridColumns: (template: string) => ({
95
+ gridTemplateColumns: template,
96
96
  }),
97
97
  })
@@ -7,9 +7,7 @@ export const meta: ComponentMeta = {
7
7
  'App root — required for all Duro components to render correctly',
8
8
  'Theme switching (dark/light mode toggle)',
9
9
  ],
10
- whenNotToUse: [
11
- 'Never omit — all Duro components require ThemeProvider',
12
- ],
10
+ whenNotToUse: ['Never omit — all Duro components require ThemeProvider'],
13
11
  example: `<ThemeProvider theme="dark">
14
12
  <App />
15
13
  </ThemeProvider>`,
package/src/index.ts CHANGED
@@ -11,6 +11,7 @@ export {Button, type ButtonVariant, type ButtonSize} from './components/Button/B
11
11
  export {Callout, type CalloutVariant} from './components/Callout/Callout'
12
12
  export {Card, type CardVariant, type CardSize} from './components/Card/Card'
13
13
  export {Checkbox} from './components/Checkbox/Checkbox'
14
+ export {CheckboxGroup} from './components/CheckboxGroup/CheckboxGroup'
14
15
  export {Dialog, type DialogSize} from './components/Dialog/Dialog'
15
16
  export {DetailPanel, type DetailPanelSize} from './components/DetailPanel/DetailPanel'
16
17
  export {Drawer, type DrawerAnchor, type DrawerSize} from './components/Drawer/Drawer'
@@ -29,6 +30,7 @@ export {
29
30
  } from './components/LinkButton/LinkButton'
30
31
  export {Menu} from './components/Menu/Menu'
31
32
  export {Panel} from './components/Panel/Panel'
33
+ export {RadioGroup} from './components/RadioGroup/RadioGroup'
32
34
  export {ScrollArea} from './components/ScrollArea/ScrollArea'
33
35
  export {Select} from './components/Select/Select'
34
36
  export {SideNav} from './components/SideNav/SideNav'