@keboola/design 16.1.0 → 17.1.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 (190) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/{AIKit-Cf5plya2.js → AIKit-DyysN1kS.js} +35 -45
  3. package/dist/AIKit-DyysN1kS.js.map +1 -0
  4. package/dist/{Alert-DziS8n1H.js → Alert-BQB-og_I.js} +2 -2
  5. package/dist/{Alert-DziS8n1H.js.map → Alert-BQB-og_I.js.map} +1 -1
  6. package/dist/{AlertModal-De04fFoy.js → AlertModal-BkmyEvsR.js} +2 -2
  7. package/dist/{AlertModal-De04fFoy.js.map → AlertModal-BkmyEvsR.js.map} +1 -1
  8. package/dist/{AppShell-BUa3U7-e.js → AppShell-CDbecT-t.js} +2 -2
  9. package/dist/{AppShell-BUa3U7-e.js.map → AppShell-CDbecT-t.js.map} +1 -1
  10. package/dist/{BrandEditor-hiLBX7az.js → BrandEditor-BHE6nsob.js} +6 -6
  11. package/dist/{BrandEditor-hiLBX7az.js.map → BrandEditor-BHE6nsob.js.map} +1 -1
  12. package/dist/{BrandLogo-Dn7hhp2c.js → BrandLogo-n4Qhi1tI.js} +2 -2
  13. package/dist/{BrandLogo-Dn7hhp2c.js.map → BrandLogo-n4Qhi1tI.js.map} +1 -1
  14. package/dist/{Breadcrumb-uGFEIjFF.js → Breadcrumb-BAwQTo0c.js} +3 -3
  15. package/dist/{Breadcrumb-uGFEIjFF.js.map → Breadcrumb-BAwQTo0c.js.map} +1 -1
  16. package/dist/{Button-DbvGzEDb.js → Button-BAMX1iuI.js} +2 -2
  17. package/dist/{Button-DbvGzEDb.js.map → Button-BAMX1iuI.js.map} +1 -1
  18. package/dist/{Checkbox-B2jLlyaO.js → Checkbox-CfjpwIcg.js} +2 -2
  19. package/dist/{Checkbox-B2jLlyaO.js.map → Checkbox-CfjpwIcg.js.map} +1 -1
  20. package/dist/{Clipboard-fAkDdpEu.js → Clipboard-BaU3cDi5.js} +7 -5
  21. package/dist/Clipboard-BaU3cDi5.js.map +1 -0
  22. package/dist/{ClipboardButton-71Ugbl8c.js → ClipboardButton-BWeaQEM2.js} +5 -4
  23. package/dist/ClipboardButton-BWeaQEM2.js.map +1 -0
  24. package/dist/{CodeEditor-D_b-ZCng.js → CodeEditor-BdTxkPD4.js} +4 -4
  25. package/dist/{CodeEditor-D_b-ZCng.js.map → CodeEditor-BdTxkPD4.js.map} +1 -1
  26. package/dist/{ColorInput-Cjr1jkvy.js → ColorInput-BoVdBxJ7.js} +3 -3
  27. package/dist/{ColorInput-Cjr1jkvy.js.map → ColorInput-BoVdBxJ7.js.map} +1 -1
  28. package/dist/{ColorModeSwitch-CuPYnJ2V.js → ColorModeSwitch-BDkdmHYl.js} +2 -2
  29. package/dist/{ColorModeSwitch-CuPYnJ2V.js.map → ColorModeSwitch-BDkdmHYl.js.map} +1 -1
  30. package/dist/{Combobox-DYjvYgl3.js → Combobox-RZ0i3w8u.js} +4 -4
  31. package/dist/{Combobox-DYjvYgl3.js.map → Combobox-RZ0i3w8u.js.map} +1 -1
  32. package/dist/{Command-BcTb6GsR.js → Command-D6XYzzJf.js} +2 -2
  33. package/dist/{Command-BcTb6GsR.js.map → Command-D6XYzzJf.js.map} +1 -1
  34. package/dist/{CopyField-CnwAvQz9.js → CopyField-9WBU8thS.js} +2 -2
  35. package/dist/{CopyField-CnwAvQz9.js.map → CopyField-9WBU8thS.js.map} +1 -1
  36. package/dist/{DateInput-DJNX7Vdx.js → DateInput-CCYG0AtT.js} +3 -3
  37. package/dist/{DateInput-DJNX7Vdx.js.map → DateInput-CCYG0AtT.js.map} +1 -1
  38. package/dist/{DateRangeInput-B3g8cyS0.js → DateRangeInput-CpZK1IFp.js} +3 -3
  39. package/dist/{DateRangeInput-B3g8cyS0.js.map → DateRangeInput-CpZK1IFp.js.map} +1 -1
  40. package/dist/{DateRangePicker-48yOB2qV.js → DateRangePicker-B2AUKX7u.js} +2 -2
  41. package/dist/{DateRangePicker-48yOB2qV.js.map → DateRangePicker-B2AUKX7u.js.map} +1 -1
  42. package/dist/{FieldItem-D7eCMfMB.js → FieldItem-eM7IHBt5.js} +3 -3
  43. package/dist/{FieldItem-D7eCMfMB.js.map → FieldItem-eM7IHBt5.js.map} +1 -1
  44. package/dist/{FileUpload-DskvxhAr.js → FileUpload-d-hNPfPV.js} +2 -2
  45. package/dist/{FileUpload-DskvxhAr.js.map → FileUpload-d-hNPfPV.js.map} +1 -1
  46. package/dist/{Form-BUNW7nlt.js → Form-B_9sNehB.js} +7 -7
  47. package/dist/{Form-BUNW7nlt.js.map → Form-B_9sNehB.js.map} +1 -1
  48. package/dist/{FormGroup-QJB21LKp.js → FormGroup-D7ahkK1q.js} +3 -3
  49. package/dist/{FormGroup-QJB21LKp.js.map → FormGroup-D7ahkK1q.js.map} +1 -1
  50. package/dist/{FullScreenModal-RzY5XxiG.js → FullScreenModal-CiRKNsls.js} +2 -2
  51. package/dist/{FullScreenModal-RzY5XxiG.js.map → FullScreenModal-CiRKNsls.js.map} +1 -1
  52. package/dist/{InlineEdit-CXL0ZslO.js → InlineEdit-BzOox46S.js} +4 -4
  53. package/dist/{InlineEdit-CXL0ZslO.js.map → InlineEdit-BzOox46S.js.map} +1 -1
  54. package/dist/{InputGroup-BWeanEo7.js → InputGroup-DnGP9-ZQ.js} +2 -2
  55. package/dist/{InputGroup-BWeanEo7.js.map → InputGroup-DnGP9-ZQ.js.map} +1 -1
  56. package/dist/{Kbd-BprYCICe.js → Kbd-6velz9J-.js} +2 -2
  57. package/dist/{Kbd-BprYCICe.js.map → Kbd-6velz9J-.js.map} +1 -1
  58. package/dist/{MermaidDiagram-E3azndPk.js → MermaidDiagram-l83gco3r.js} +2 -2
  59. package/dist/{MermaidDiagram-E3azndPk.js.map → MermaidDiagram-l83gco3r.js.map} +1 -1
  60. package/dist/{Modal-Cf_kPEBW.js → Modal-CLu6Eg5p.js} +2 -2
  61. package/dist/{Modal-Cf_kPEBW.js.map → Modal-CLu6Eg5p.js.map} +1 -1
  62. package/dist/{MultiActionButtonGroup-8WQwL4UQ.js → MultiActionButtonGroup-B3-wNw7w.js} +3 -3
  63. package/dist/{MultiActionButtonGroup-8WQwL4UQ.js.map → MultiActionButtonGroup-B3-wNw7w.js.map} +1 -1
  64. package/dist/{Navbar-CRjxVboE.js → Navbar-BEc-Pqo5.js} +2 -2
  65. package/dist/{Navbar-CRjxVboE.js.map → Navbar-BEc-Pqo5.js.map} +1 -1
  66. package/dist/{PageLayout-LcvJccOW.js → PageLayout-kY31oUix.js} +2 -2
  67. package/dist/{PageLayout-LcvJccOW.js.map → PageLayout-kY31oUix.js.map} +1 -1
  68. package/dist/{PageToolbar-By2HznxO.js → PageToolbar-NmiausP7.js} +2 -2
  69. package/dist/{PageToolbar-By2HznxO.js.map → PageToolbar-NmiausP7.js.map} +1 -1
  70. package/dist/{Pagination-DrXTrvfD.js → Pagination-DidOPSPB.js} +2 -2
  71. package/dist/{Pagination-DrXTrvfD.js.map → Pagination-DidOPSPB.js.map} +1 -1
  72. package/dist/{Popconfirm-BJuDOHdv.js → Popconfirm-C4ryoeGP.js} +2 -2
  73. package/dist/{Popconfirm-BJuDOHdv.js.map → Popconfirm-C4ryoeGP.js.map} +1 -1
  74. package/dist/{RadioGroup-B9oC8P15.js → RadioGroup-BIElT-nH.js} +2 -2
  75. package/dist/{RadioGroup-B9oC8P15.js.map → RadioGroup-BIElT-nH.js.map} +1 -1
  76. package/dist/{Search-OgaNjqQM.js → Search-xDWaQ2z3.js} +2 -2
  77. package/dist/{Search-OgaNjqQM.js.map → Search-xDWaQ2z3.js.map} +1 -1
  78. package/dist/{SearchInput-eLS-uvOn.js → SearchInput-BwlJ77mV.js} +3 -3
  79. package/dist/{SearchInput-eLS-uvOn.js.map → SearchInput-BwlJ77mV.js.map} +1 -1
  80. package/dist/{SectionNav-L81iJBo3.js → SectionNav-DV3Hwj-5.js} +14 -8
  81. package/dist/SectionNav-DV3Hwj-5.js.map +1 -0
  82. package/dist/{Select-DRdkdzBp.js → Select-C3Q_Xk_Z.js} +2 -2
  83. package/dist/{Select-DRdkdzBp.js.map → Select-C3Q_Xk_Z.js.map} +1 -1
  84. package/dist/{Sheet-DVb4XoJ5.js → Sheet-D7NnOyud.js} +2 -2
  85. package/dist/{Sheet-DVb4XoJ5.js.map → Sheet-D7NnOyud.js.map} +1 -1
  86. package/dist/{Sidebar-DYvodJWN.js → Sidebar-DaUDM8jm.js} +5 -5
  87. package/dist/{Sidebar-DYvodJWN.js.map → Sidebar-DaUDM8jm.js.map} +1 -1
  88. package/dist/{Slider-B9IskDxf.js → Slider-Cdl8FOvI.js} +3 -3
  89. package/dist/{Slider-B9IskDxf.js.map → Slider-Cdl8FOvI.js.map} +1 -1
  90. package/dist/{Table-BwgBm3hJ.js → Table-DtLrXt4i.js} +39 -7
  91. package/dist/Table-DtLrXt4i.js.map +1 -0
  92. package/dist/{Tabs-DmJB4l_N.js → Tabs-DUOUQKh7.js} +2 -2
  93. package/dist/{Tabs-DmJB4l_N.js.map → Tabs-DUOUQKh7.js.map} +1 -1
  94. package/dist/{TextInput--1CfZybC.js → TextInput-BAL-zOAN.js} +3 -3
  95. package/dist/{TextInput--1CfZybC.js.map → TextInput-BAL-zOAN.js.map} +1 -1
  96. package/dist/{ThemeProvider-BCHllN7d.js → ThemeProvider-MzVbTDBj.js} +2 -2
  97. package/dist/{ThemeProvider-BCHllN7d.js.map → ThemeProvider-MzVbTDBj.js.map} +1 -1
  98. package/dist/{ToggleAllTooltip-BFmA6TXf.js → ToggleAllTooltip-DQE5Lw6w.js} +2 -2
  99. package/dist/{ToggleAllTooltip-BFmA6TXf.js.map → ToggleAllTooltip-DQE5Lw6w.js.map} +1 -1
  100. package/dist/{ZoomableSvg-BRPGgaWJ.js → ZoomableSvg-CIOqAYpd.js} +4 -4
  101. package/dist/{ZoomableSvg-BRPGgaWJ.js.map → ZoomableSvg-CIOqAYpd.js.map} +1 -1
  102. package/dist/editors.js +3 -3
  103. package/dist/flint.js +1 -1
  104. package/dist/index.d.ts +409 -365
  105. package/dist/index.js +52 -50
  106. package/dist/internal/blocks/AIKit.js +1 -1
  107. package/dist/internal/blocks/AppShell.js +1 -1
  108. package/dist/internal/blocks/AuthLayout.js +1 -1
  109. package/dist/internal/blocks/BrandEditor.js +1 -1
  110. package/dist/internal/blocks/BulkActionsBar.js +55 -0
  111. package/dist/internal/blocks/BulkActionsBar.js.map +1 -0
  112. package/dist/internal/blocks/ChipEditor.js +2 -2
  113. package/dist/internal/blocks/ClipboardButton.js +1 -1
  114. package/dist/internal/blocks/ColorInput.js +1 -1
  115. package/dist/internal/blocks/ColorModeSwitch.js +1 -1
  116. package/dist/internal/blocks/Command.js +1 -1
  117. package/dist/internal/blocks/CopyField.js +1 -1
  118. package/dist/internal/blocks/DateInput.js +1 -1
  119. package/dist/internal/blocks/DateRangeInput.js +1 -1
  120. package/dist/internal/blocks/EmptyState.js +7 -2
  121. package/dist/internal/blocks/EmptyState.js.map +1 -1
  122. package/dist/internal/blocks/ExportMenu.js +2 -2
  123. package/dist/internal/blocks/Form/connectors/ComboboxField.js +2 -2
  124. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +1 -1
  125. package/dist/internal/blocks/Form.js +2 -2
  126. package/dist/internal/blocks/FormGroup.js +1 -1
  127. package/dist/internal/blocks/InlineEdit.js +1 -1
  128. package/dist/internal/blocks/MultiActionButtonGroup.js +1 -1
  129. package/dist/internal/blocks/MultiCombobox.js +3 -3
  130. package/dist/internal/blocks/NumberInput.js +1 -1
  131. package/dist/internal/blocks/PageLayout.js +1 -1
  132. package/dist/internal/blocks/PageSection.js +31 -0
  133. package/dist/internal/blocks/PageSection.js.map +1 -0
  134. package/dist/internal/blocks/PageToolbar.js +1 -1
  135. package/dist/internal/blocks/PasswordInput.js +2 -2
  136. package/dist/internal/blocks/SearchInput.js +1 -1
  137. package/dist/internal/blocks/SearchInputWithNavigation.js +3 -3
  138. package/dist/internal/blocks/SectionNav.js +1 -1
  139. package/dist/internal/blocks/SplitButton.js +1 -1
  140. package/dist/internal/blocks/TextInput.js +1 -1
  141. package/dist/internal/blocks/Textarea.js +1 -1
  142. package/dist/internal/blocks/TimeInput.js +2 -2
  143. package/dist/internal/components/Alert.js +1 -1
  144. package/dist/internal/components/AlertModal.js +1 -1
  145. package/dist/internal/components/Avatar.js +1 -1
  146. package/dist/internal/components/BrandLogo.js +1 -1
  147. package/dist/internal/components/Breadcrumb.js +1 -1
  148. package/dist/internal/components/Button.js +1 -1
  149. package/dist/internal/components/Checkbox.js +1 -1
  150. package/dist/internal/components/Clipboard.js +1 -1
  151. package/dist/internal/components/CollapsiblePanel.js +1 -1
  152. package/dist/internal/components/Combobox.js +1 -1
  153. package/dist/internal/components/DateRangePicker.js +1 -1
  154. package/dist/internal/components/FileUpload.js +1 -1
  155. package/dist/internal/components/FullScreenModal.js +1 -1
  156. package/dist/internal/components/InputGroup.js +1 -1
  157. package/dist/internal/components/Kbd.js +1 -1
  158. package/dist/internal/components/Modal.js +1 -1
  159. package/dist/internal/components/Navbar.js +1 -1
  160. package/dist/internal/components/Pagination.js +1 -1
  161. package/dist/internal/components/Popconfirm.js +1 -1
  162. package/dist/internal/components/RadioGroup.js +1 -1
  163. package/dist/internal/components/Search.js +1 -1
  164. package/dist/internal/components/Select.js +1 -1
  165. package/dist/internal/components/Sheet.js +1 -1
  166. package/dist/internal/components/Sidebar.js +1 -1
  167. package/dist/internal/components/Slider.js +1 -1
  168. package/dist/internal/components/Table.js +1 -1
  169. package/dist/internal/components/Tabs.js +1 -1
  170. package/dist/internal/components/ThemeProvider.js +1 -1
  171. package/dist/internal/components/Tooltip.js +1 -1
  172. package/dist/internal/components/Truncated.js +1 -1
  173. package/dist/internal/components/ZoomableSvg.js +1 -1
  174. package/dist/internal/utils.js +1 -1
  175. package/dist/markdown-editor.js +6 -6
  176. package/dist/mermaid.js +1 -1
  177. package/dist/rjsf.js +11 -11
  178. package/dist/rjsf.js.map +1 -1
  179. package/dist/styles.css +1 -1
  180. package/dist/testing.js +1 -1
  181. package/dist/{utils-DjFceY3H.js → utils-BxEJOnFD.js} +2 -2
  182. package/dist/{utils-DjFceY3H.js.map → utils-BxEJOnFD.js.map} +1 -1
  183. package/package.json +3 -3
  184. package/src/styles.css +50 -0
  185. package/src/theme.css +10 -8
  186. package/dist/AIKit-Cf5plya2.js.map +0 -1
  187. package/dist/Clipboard-fAkDdpEu.js.map +0 -1
  188. package/dist/ClipboardButton-71Ugbl8c.js.map +0 -1
  189. package/dist/SectionNav-L81iJBo3.js.map +0 -1
  190. package/dist/Table-BwgBm3hJ.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"Clipboard-fAkDdpEu.js","names":[],"sources":["../src/components/Clipboard/Clipboard.tsx"],"sourcesContent":["import { useState } from 'react';\nimport type { ComponentProps, MouseEventHandler } from 'react';\n\nimport { cn, copyToClipboard } from '../../utils';\nimport { type Props as TooltipProps, Tooltip } from '../Tooltip';\n\ntype Props = {\n tooltip?: TooltipProps['tooltip'];\n tooltipPlacement?: TooltipProps['placement'];\n tooltipVariant?: TooltipProps['variant'];\n asChild?: TooltipProps['triggerAsChild'];\n text?: string | (() => string);\n} & ComponentProps<'button'>;\n\nexport const Clipboard = ({\n ref,\n text: textProp,\n children,\n tooltip = 'Copy to Clipboard',\n tooltipPlacement = 'top',\n tooltipVariant: tooltipVariantProp = 'action',\n asChild = false,\n onClick,\n className,\n ...restButtonProps\n}: Props) => {\n const [isTooltipOpen, setIsTooltipOpen] = useState(false);\n const [state, setState] = useState<'ready' | 'copied' | 'error'>('ready');\n const text = typeof textProp === 'function' ? textProp() : textProp;\n\n const copy = async (text: string) => {\n try {\n // For the clipboard feature to work reliably, the window must be in focus for security reasons.\n // However, the button can be clicked without the window being focused.\n if (!document.hasFocus()) window.focus();\n\n await copyToClipboard(text);\n setState('copied');\n } catch {\n setState('error');\n }\n };\n\n const handleOnClick: MouseEventHandler<HTMLButtonElement> = (event) => {\n // Open on click rather than waiting for hover. Radix opens on pointer-enter via a\n // `delayDuration` timer (300ms here), so clicking faster than that left the outcome invisible\n // until the timer caught up — the message was already rendered, just inside a closed tooltip.\n setIsTooltipOpen(true);\n if (text && state === 'ready') void copy(text);\n onClick?.(event);\n };\n\n const handleOnOpenChange: ComponentProps<typeof Tooltip.Root>['onOpenChange'] = (open) => {\n // Reset when the tooltip closes, allowing the user to leave the copy button.\n if (!open && state !== 'ready') setState('ready');\n setIsTooltipOpen(open);\n };\n\n const tooltipContent = (() => {\n if (!text) return 'Nothing to copy';\n if (state === 'error') return 'Failed to copy';\n if (state === 'copied') return 'Copied to Clipboard';\n return tooltip;\n })();\n\n const tooltipVariant: TooltipProps['variant'] =\n state === 'ready' && !!text ? tooltipVariantProp : 'action';\n\n // `tooltip={null}` leaves nothing to say until there is an outcome. Not rendering `Content` at all\n // is what makes that work: hovering still opens the tooltip, there is simply nothing in it, and\n // the copied / failed message appears in place the moment `state` changes. It also keeps Radix\n // from pointing the trigger's `aria-describedby` at content that has no text.\n const hasTooltipContent = tooltipContent !== null && tooltipContent !== undefined;\n\n return (\n <Tooltip.Root open={isTooltipOpen} onOpenChange={handleOnOpenChange}>\n <Tooltip.Trigger\n {...restButtonProps}\n asChild={asChild}\n keepOpenOnClick\n onClick={handleOnClick}\n className={cn('tw:cursor-pointer', className)}\n ref={ref}\n >\n {children ?? text}\n </Tooltip.Trigger>\n\n {hasTooltipContent && (\n <Tooltip.Content\n keepOpenOnPointerDownOutside\n placement={tooltipPlacement}\n variant={tooltipVariant}\n >\n {tooltipContent}\n </Tooltip.Content>\n )}\n </Tooltip.Root>\n );\n};\n"],"mappings":";;;;;AAcA,MAAa,aAAa,EACxB,KACA,MAAM,UACN,UACA,UAAU,qBACV,mBAAmB,OACnB,gBAAgB,qBAAqB,UACrC,UAAU,OACV,SACA,WACA,GAAG,sBACQ;CACX,MAAM,CAAC,eAAe,oBAAoB,SAAS,KAAK;CACxD,MAAM,CAAC,OAAO,YAAY,SAAuC,OAAO;CACxE,MAAM,OAAO,OAAO,aAAa,aAAa,SAAS,IAAI;CAE3D,MAAM,OAAO,OAAO,SAAiB;EACnC,IAAI;GAGF,IAAI,CAAC,SAAS,SAAS,GAAG,OAAO,MAAM;GAEvC,MAAM,gBAAgB,IAAI;GAC1B,SAAS,QAAQ;EACnB,QAAQ;GACN,SAAS,OAAO;EAClB;CACF;CAEA,MAAM,iBAAuD,UAAU;EAIrE,iBAAiB,IAAI;EACrB,IAAI,QAAQ,UAAU,SAAS,KAAU,IAAI;EAC7C,UAAU,KAAK;CACjB;CAEA,MAAM,sBAA2E,SAAS;EAExF,IAAI,CAAC,QAAQ,UAAU,SAAS,SAAS,OAAO;EAChD,iBAAiB,IAAI;CACvB;CAEA,MAAM,wBAAwB;EAC5B,IAAI,CAAC,MAAM,OAAO;EAClB,IAAI,UAAU,SAAS,OAAO;EAC9B,IAAI,UAAU,UAAU,OAAO;EAC/B,OAAO;CACT,EAAA,CAAG;CAEH,MAAM,iBACJ,UAAU,WAAW,CAAC,CAAC,OAAO,qBAAqB;CAMrD,MAAM,oBAAoB,mBAAmB,QAAQ,mBAAmB,KAAA;CAExE,OACE,qBAAC,QAAQ,MAAT;EAAc,MAAM;EAAe,cAAc;EAAjD,UAAA,CACE,oBAAC,QAAQ,SAAT;GACE,GAAI;GACK;GACT,iBAAA;GACA,SAAS;GACT,WAAW,GAAG,qBAAqB,SAAS;GACvC;GAEJ,UAAA,YAAY;EACE,CAAA,GAEhB,qBACC,oBAAC,QAAQ,SAAT;GACE,8BAAA;GACA,WAAW;GACX,SAAS;GAER,UAAA;EACc,CAAA,CAEP;;AAElB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ClipboardButton-71Ugbl8c.js","names":[],"sources":["../src/blocks/ClipboardButton/ClipboardButton.tsx","../src/blocks/ClipboardButton/ClipboardInline.tsx"],"sourcesContent":["import type { ComponentProps, ReactNode } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { Clipboard } from '../../components/Clipboard';\nimport { Copy } from '../../icons';\n\ntype ClipboardProps = Pick<\n ComponentProps<typeof Clipboard>,\n 'text' | 'tooltip' | 'tooltipPlacement' | 'tooltipVariant'\n>;\n\ntype ButtonProps = Omit<ComponentProps<typeof Button>, 'disabled' | 'icon'>;\n\ntype Props = ClipboardProps & ButtonProps & { icon?: ReactNode };\n\nconst DEFAULT_ICON: ReactNode = <Copy />;\nconst DEFAULT_ARIA_LABEL = 'Copy';\n\nexport const ClipboardButton = ({\n // clipboard props\n text,\n tooltip,\n tooltipPlacement,\n tooltipVariant,\n\n // button props\n icon = DEFAULT_ICON,\n variant = 'outline',\n children,\n ...rest\n}: Props) => {\n // Icon-only (no text children): the `tooltip` is visual only, not an accessible\n // name, so fall back to it (when it's a string) or a sensible default. A\n // consumer-supplied `aria-label` in `rest` still wins.\n // A non-empty string tooltip names the action; an empty/absent tooltip still\n // needs a name, so fall back to the default rather than an empty aria-label.\n const defaultAriaLabel =\n typeof tooltip === 'string' && tooltip.trim() ? tooltip : DEFAULT_ARIA_LABEL;\n const ariaLabel = rest['aria-label'] ?? (children == null ? defaultAriaLabel : undefined);\n\n return (\n <Clipboard\n asChild\n tooltip={tooltip}\n tooltipPlacement={tooltipPlacement}\n tooltipVariant={tooltipVariant}\n text={text}\n >\n <Button {...rest} aria-label={ariaLabel} variant={variant} disabled={!text}>\n {icon}\n {children}\n </Button>\n </Clipboard>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { ButtonInline } from '../../components/Button';\nimport { Clipboard } from '../../components/Clipboard';\nimport { Copy } from '../../icons';\n\ntype ClipboardProps = Pick<\n ComponentProps<typeof Clipboard>,\n 'text' | 'tooltip' | 'tooltipPlacement' | 'tooltipVariant'\n>;\n\ntype ButtonProps = Omit<ComponentProps<typeof ButtonInline>, 'disabled'>;\n\ntype Props = { hideIcon?: boolean } & ClipboardProps & ButtonProps;\n\nexport const ClipboardInline = ({\n // clipboard props\n text,\n tooltip,\n tooltipPlacement,\n tooltipVariant,\n\n // button props\n children = 'Copy To Clipboard',\n hideIcon = false,\n ...rest\n}: Props) => (\n <Clipboard\n asChild\n text={text}\n tooltip={tooltip}\n tooltipPlacement={tooltipPlacement}\n tooltipVariant={tooltipVariant}\n >\n <ButtonInline {...rest} disabled={!text}>\n {!hideIcon && <Copy className=\"tw:size-4\" />}\n {children}\n </ButtonInline>\n </Clipboard>\n);\n"],"mappings":";;;;;AAeA,MAAM,eAA0B,oBAAC,MAAD,CAAO,CAAA;AACvC,MAAM,qBAAqB;AAE3B,MAAa,mBAAmB,EAE9B,MACA,SACA,kBACA,gBAGA,OAAO,cACP,UAAU,WACV,UACA,GAAG,WACQ;CAMX,MAAM,mBACJ,OAAO,YAAY,YAAY,QAAQ,KAAK,IAAI,UAAU;CAC5D,MAAM,YAAY,KAAK,kBAAkB,YAAY,OAAO,mBAAmB,KAAA;CAE/E,OACE,oBAAC,WAAD;EACE,SAAA;EACS;EACS;EACF;EACV;EAEN,UAAA,qBAAC,QAAD;GAAQ,GAAI;GAAM,cAAY;GAAoB;GAAS,UAAU,CAAC;GAAtE,UAAA,CACG,MACA,QACK;;CACC,CAAA;AAEf;;ACvCA,MAAa,mBAAmB,EAE9B,MACA,SACA,kBACA,gBAGA,WAAW,qBACX,WAAW,OACX,GAAG,WAEH,oBAAC,WAAD;CACE,SAAA;CACM;CACG;CACS;CACF;CAEhB,UAAA,qBAAC,cAAD;EAAc,GAAI;EAAM,UAAU,CAAC;EAAnC,UAAA,CACG,CAAC,YAAY,oBAAC,MAAD,EAAM,WAAU,YAAa,CAAA,GAC1C,QACW;;AACL,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"SectionNav-L81iJBo3.js","names":[],"sources":["../src/blocks/SectionNav/SectionNavItemContent.tsx","../src/blocks/SectionNav/SectionNavGroupRow.tsx","../src/blocks/SectionNav/SectionNav.tsx"],"sourcesContent":["import { Badge } from '../../components/Badge';\nimport { ChevronDown } from '../../icons';\nimport { cn } from '../../utils';\n\nimport type { SectionNavItem } from './types';\n\ntype Props = {\n item: SectionNavItem;\n active: boolean;\n showDescription?: boolean;\n /** Group rows only — renders the chevron. */\n expanded?: boolean;\n /** `false` on sub-section rows: the group's icon covers them; `icon` stays for flattened surfaces. */\n showIcon?: boolean;\n};\n\n/** One row's body, shared by the tree and the collapsed dropdown. */\nexport const SectionNavItemContent = ({\n item,\n active,\n showDescription = false,\n expanded,\n showIcon = true,\n}: Props) => {\n const Icon = item.icon;\n\n return (\n <span className=\"tw:flex tw:min-w-0 tw:flex-1 tw:flex-col tw:gap-0.5\">\n <span className=\"tw:flex tw:items-center tw:gap-2\">\n {showIcon && Icon && <Icon className=\"tw:size-4 tw:shrink-0\" />}\n <span\n className={cn(\n 'tw:flex-1 tw:truncate tw:text-sm',\n active ? 'tw:font-medium tw:text-selected-foreground' : 'tw:text-foreground',\n )}\n >\n {item.title}\n </span>\n {item.isNew && (\n <Badge\n color=\"blue-inverse\"\n className=\"tw:min-h-0 tw:text-[10px]\"\n labelClassName=\"tw:px-1.5 tw:py-0\"\n >\n New\n </Badge>\n )}\n {expanded !== undefined && (\n <ChevronDown\n className={cn(\n 'tw:size-4 tw:shrink-0 tw:text-muted-foreground tw:transition-transform tw:duration-200',\n expanded && 'tw:rotate-180',\n )}\n />\n )}\n </span>\n {/* Wraps, and breaks unbreakable tokens that would overflow the 256px column. */}\n {showDescription && item.description && (\n <span className=\"tw:text-xs tw:break-words tw:text-muted-foreground\">\n {item.description}\n </span>\n )}\n </span>\n );\n};\n","import { useState } from 'react';\nimport type { MouseEvent, ReactNode } from 'react';\n\nimport { Collapsible } from '../../components/Collapsible';\nimport { cn, noop } from '../../utils';\n\nimport { SectionNavItemContent } from './SectionNavItemContent';\nimport type { SectionNavGroup, SectionNavItemRenderProps } from './types';\n\ntype Props = {\n group: SectionNavGroup;\n activeId: string | undefined;\n renderItem: (props: SectionNavItemRenderProps) => ReactNode;\n showDescriptions: boolean;\n};\n\n/**\n * The ring is **inset**, not an outline. A row is exactly as wide as the nav column, and\n * `PageLayout.Content nav` makes that column a scroll container (`overflow-y-auto`, which forces\n * `overflow-x` to `auto` too) — so there is 0px of slack for anything painted outside the border\n * box, and the browser's default `outline-offset: 1px` ring gets clipped on both edges. Painting\n * inside the box cannot be clipped, at any column width, by any ancestor.\n */\nconst FOCUS_RING =\n 'tw:focus-visible:outline-hidden tw:focus-visible:ring-2 tw:focus-visible:ring-inset tw:focus-visible:ring-ring';\n\nconst rowClass = (active: boolean) =>\n cn(\n 'tw:flex tw:w-full tw:cursor-pointer tw:items-center tw:gap-2 tw:rounded-md tw:border-none tw:px-3 tw:py-2 tw:text-left tw:text-sm tw:no-underline tw:transition-colors',\n FOCUS_RING,\n active\n ? 'tw:bg-selected tw:font-medium tw:text-selected-foreground'\n : 'tw:bg-transparent tw:text-foreground tw:hover:bg-[var(--hover,rgb(var(--muted)))]',\n );\n\nconst childRowClass = (active: boolean) =>\n cn(\n 'tw:flex tw:w-full tw:cursor-pointer tw:rounded-md tw:border-none tw:px-3 tw:py-1.5 tw:text-left tw:no-underline tw:transition-colors',\n FOCUS_RING,\n active ? 'tw:bg-selected' : 'tw:bg-transparent tw:hover:bg-[var(--hover,rgb(var(--muted)))]',\n );\n\n/**\n * One group row and its sub-sections. The row is a single control: it opens the group **and** goes to\n * its first section, and only collapses once you are already there — so the chevron never becomes a\n * separate thing to aim at, and one click always makes progress.\n */\nexport const SectionNavGroupRow = ({ group, activeId, renderItem, showDescriptions }: Props) => {\n // Open on arrival: the nav is short enough that hiding any of it costs more than it saves.\n const [open, setOpen] = useState(true);\n\n const hasChildren = group.children.length > 0;\n const targetId = group.children[0]?.id ?? group.id;\n const isCurrent = group.id === activeId;\n const holdsCurrent = isCurrent || group.children.some((child) => child.id === activeId);\n\n const onClick = (event: MouseEvent<HTMLElement>) => {\n if (!hasChildren) return;\n\n // Already on the row's target, so navigating would be a no-op and the only thing left for the\n // click to do is toggle. `preventDefault` is what tells the caller's link not to navigate.\n if (activeId === targetId) {\n event.preventDefault();\n setOpen((isOpen) => !isOpen);\n\n return;\n }\n\n setOpen(true);\n };\n\n return (\n <Collapsible open={open} onOpenChange={setOpen} className=\"tw:flex tw:flex-col tw:gap-0.5\">\n {renderItem({\n targetId,\n isActive: isCurrent,\n children: (\n <SectionNavItemContent\n item={group}\n active={holdsCurrent}\n expanded={hasChildren ? open : undefined}\n />\n ),\n itemProps: {\n className: rowClass(holdsCurrent),\n 'aria-current': isCurrent ? 'page' : undefined,\n 'aria-expanded': hasChildren ? open : undefined,\n 'data-active': holdsCurrent && !isCurrent ? true : undefined,\n onClick,\n },\n })}\n\n {hasChildren && (\n <Collapsible.Content>\n {/* `pl-1` keeps each row's background box off the group's rule — without it an active\n row's `bg-selected` sits flush against the line. 4px is also what lines the child titles\n (20 + 1 + 4 + 12 = 37px) up with the parent's, which its icon puts at 12 + 16 + 8 = 36px. */}\n {/* `my-0 mr-0` and not `m-0`: a host app emits its own `.tw\\:m-0` from its own source, and\n its stylesheet is the later one — shorthand and longhand at equal specificity means the\n app's `m-0` would land after this `ml-5` and flatten the indent. Longhands only, so\n nothing here can be overridden by a copy of a class this block also uses. */}\n <ul className=\"tw:my-0 tw:mr-0 tw:ml-5 tw:flex tw:list-none tw:flex-col tw:gap-0.5 tw:border-l tw:border-border tw:py-0.5 tw:pl-1\">\n {group.children.map((child) => {\n const active = child.id === activeId;\n\n return (\n <li key={child.id}>\n {renderItem({\n targetId: child.id,\n isActive: active,\n children: (\n <SectionNavItemContent\n item={child}\n active={active}\n showDescription={showDescriptions}\n showIcon={false}\n />\n ),\n itemProps: {\n className: childRowClass(active),\n 'aria-current': active ? 'page' : undefined,\n 'aria-expanded': undefined,\n 'data-active': undefined,\n onClick: noop,\n },\n })}\n </li>\n );\n })}\n {group.note && (\n <li className=\"tw:py-1 tw:pl-3 tw:text-xs tw:text-muted-foreground\">{group.note}</li>\n )}\n </ul>\n </Collapsible.Content>\n )}\n </Collapsible>\n );\n};\n","import type { ReactNode } from 'react';\n\nimport { Button } from '../../components/Button';\nimport { DropdownMenu } from '../../components/DropdownMenu';\nimport { ChevronDown } from '../../icons';\nimport { cn, noop } from '../../utils';\n\nimport { SectionNavGroupRow } from './SectionNavGroupRow';\nimport { SectionNavItemContent } from './SectionNavItemContent';\nimport type { SectionNavGroup, SectionNavItemRenderProps } from './types';\n\ntype Props = {\n /** Already filtered: visibility, permissions and flags stay in the app; rendered as given. */\n groups: SectionNavGroup[];\n /** `id` of the current section: a child's, or a childless group's. */\n activeId?: string;\n /** Return a router link / `<a>` to `targetId` with `itemProps` spread on it. */\n renderItem: (props: SectionNavItemRenderProps) => ReactNode;\n /** Show each section's `description` under its title. */\n showDescriptions?: boolean;\n /** Accessible name for the tree's `<nav>`, and the collapsed label with nothing active. */\n label?: string;\n /** Applied to the tree's `<nav>`; the column geometry belongs to `PageLayout.Content nav`. */\n className?: string;\n};\n\n/**\n * One page's grouped section nav: a tree when wide, a dropdown when narrow, both rendered via `renderItem`.\n *\n * - Not `Sidebar` (the app-level rail); this lives in `PageLayout.Content` and owns no global state.\n * - The switch is a container query; standalone, put `tw:@container/section-nav` on an ancestor.\n *\n * @see RECIPES.md#section-nav\n */\nexport const SectionNav = ({\n groups,\n activeId,\n renderItem,\n showDescriptions = false,\n label = 'Sections',\n className,\n}: Props) => {\n // The collapsed trigger names a sub-section with its group: \"Developer settings / CLI agents\".\n const activeChild = groups\n .flatMap((group) => group.children.map((child) => ({ group, child })))\n .find(({ child }) => child.id === activeId);\n const activeGroup = groups.find((group) => group.id === activeId);\n const current = activeChild\n ? {\n icon: activeChild.group.icon,\n title: activeChild.child.title,\n parent: activeChild.group.title,\n }\n : { icon: activeGroup?.icon, title: activeGroup?.title ?? label, parent: undefined };\n const CurrentIcon = current.icon;\n // Tinted like the tree's row, but not `aria-current`.\n const holdsActive = (group: SectionNavGroup) =>\n group.id === activeId || group.children.some((child) => child.id === activeId);\n\n return (\n <>\n {/* - `tailwindcss-preflight` covers the caller's `<a>` rows; without it they're `content-box`\n and overflow the column.\n - `display` comes only from the two container variants: a plain `tw:flex` / `tw:hidden`\n would lose to the host app's identical, later rule. */}\n <nav\n aria-label={label}\n className={cn(\n 'tailwindcss-preflight',\n 'tw:w-full tw:flex-col tw:gap-0.5 tw:@[640px]/section-nav:flex tw:@max-[640px]/section-nav:hidden',\n className,\n )}\n >\n {groups.map((group) => (\n <SectionNavGroupRow\n key={group.id}\n group={group}\n activeId={activeId}\n renderItem={renderItem}\n showDescriptions={showDescriptions}\n />\n ))}\n </nav>\n\n <div className=\"tw:w-full tw:bg-background tw:@[640px]/section-nav:hidden tw:@max-[640px]/section-nav:block\">\n <DropdownMenu>\n <DropdownMenu.Trigger asChild>\n <Button variant=\"outline\" className=\"tw:w-full tw:justify-between\">\n <span className=\"tw:flex tw:min-w-0 tw:items-center tw:gap-2\">\n {CurrentIcon && <CurrentIcon className=\"tw:size-4 tw:shrink-0\" />}\n {current.parent && (\n <>\n <span className=\"tw:truncate tw:font-normal tw:text-muted-foreground\">\n {current.parent}\n </span>\n <span className=\"tw:text-border\">/</span>\n </>\n )}\n <span className=\"tw:truncate tw:font-medium tw:text-foreground\">\n {current.title}\n </span>\n </span>\n <ChevronDown className=\"tw:size-4 tw:shrink-0\" />\n </Button>\n </DropdownMenu.Trigger>\n\n <DropdownMenu.Content\n align=\"start\"\n className=\"tw:w-(--radix-dropdown-menu-trigger-width)\"\n >\n {groups.map((group) =>\n group.children.length > 0 ? (\n <DropdownMenu.Group key={group.id}>\n {/* A clickable item, not a label: in the tree it navigates to the first section. */}\n <DropdownMenu.Item asChild>\n {renderItem({\n targetId: group.children[0]?.id ?? group.id,\n isActive: false,\n children: <SectionNavItemContent item={group} active={holdsActive(group)} />,\n itemProps: {\n className: 'tw:no-underline',\n 'aria-current': undefined,\n 'aria-expanded': undefined,\n 'data-active': holdsActive(group) ? true : undefined,\n onClick: noop,\n },\n })}\n </DropdownMenu.Item>\n <div className=\"tw:ml-5 tw:border-l tw:border-border tw:py-0.5 tw:pl-1\">\n {group.children.map((child) => (\n <DropdownMenu.Item key={child.id} asChild>\n {renderItem({\n targetId: child.id,\n isActive: child.id === activeId,\n children: (\n <SectionNavItemContent\n item={child}\n active={child.id === activeId}\n showDescription={showDescriptions}\n showIcon={false}\n />\n ),\n itemProps: {\n className: 'tw:no-underline',\n 'aria-current': child.id === activeId ? 'page' : undefined,\n 'aria-expanded': undefined,\n 'data-active': undefined,\n onClick: noop,\n },\n })}\n </DropdownMenu.Item>\n ))}\n </div>\n </DropdownMenu.Group>\n ) : (\n <DropdownMenu.Item key={group.id} asChild>\n {renderItem({\n targetId: group.id,\n isActive: group.id === activeId,\n children: <SectionNavItemContent item={group} active={group.id === activeId} />,\n itemProps: {\n className: 'tw:no-underline',\n 'aria-current': group.id === activeId ? 'page' : undefined,\n 'aria-expanded': undefined,\n 'data-active': undefined,\n onClick: noop,\n },\n })}\n </DropdownMenu.Item>\n ),\n )}\n </DropdownMenu.Content>\n </DropdownMenu>\n </div>\n </>\n );\n};\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Table-BwgBm3hJ.js","names":[],"sources":["../src/components/Table/TableBody.tsx","../src/components/Table/TableCell.tsx","../src/components/Table/TableFooter.tsx","../src/components/Table/TableHead.tsx","../src/components/Table/TableHeader.tsx","../src/components/Table/TableRow.tsx","../src/components/Table/TableSkeletonRows.tsx","../src/components/Table/TableSortHeader.tsx","../src/components/Table/Table.tsx"],"sourcesContent":["import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nexport const TableBody = ({\n withBorderSeparator = true,\n className,\n ...props\n}: { withBorderSeparator?: boolean } & ComponentProps<'tbody'>) => {\n return (\n <tbody\n className={cn(\n {\n 'tw:[&_tr]:border-0 tw:[&_tr]:border-b-border tw:[&_tr]:border-b tw:[&_tr]:border-solid tw:[&_tr:last-child]:border-0':\n withBorderSeparator,\n },\n className,\n )}\n {...props}\n />\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nexport const TableCell = ({ className, ...props }: ComponentProps<'td'>) => {\n return <td className={cn('tw:px-3 tw:py-2', className)} {...props} />;\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nexport const TableFooter = ({ className, ...props }: ComponentProps<'tfoot'>) => {\n return (\n <tfoot\n className={cn(\n 'tw:bg-muted/50 tw:border-t tw:border-border tw:font-medium tw:[&>tr]:last:border-b-0',\n className,\n )}\n {...props}\n />\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nexport const TableHead = ({ className, ...props }: ComponentProps<'th'>) => {\n return (\n <th\n className={cn(\n 'tw:px-3 tw:py-2 tw:text-left tw:font-medium tw:whitespace-nowrap tw:[&:has([role=checkbox])]:pr-0 tw:[&>[role=checkbox]]:translate-y-[2px] tw:focus-within:ring-2 tw:focus-within:ring-ring/50',\n className,\n )}\n {...props}\n />\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nexport const TableHeader = ({\n withShadow = false,\n className,\n ...props\n}: { withShadow?: boolean } & ComponentProps<'thead'>) => {\n return (\n <thead\n className={cn(\n // - The surface sits on `thead`, so a caller's `bg-*` replaces it at rest and on hover.\n // - `[&_tr]:hover:` (0,2,1) outranks `TableRow`'s hover tint (0,2,0): a header is not hoverable.\n 'tw:sticky tw:top-0 tw:z-10 tw:bg-card tw:[&_tr]:h-11 tw:[&_tr]:hover:bg-transparent tw:[&_tr]:border-b tw:[&_tr]:border-border',\n { 'tw:shadow-table': withShadow },\n className,\n )}\n {...props}\n />\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nexport const TableRow = ({ ref, className, ...props }: ComponentProps<'tr'>) => (\n <tr\n ref={ref}\n className={cn(\n 'tw:hover:bg-[var(--hover,color-mix(in_oklab,rgb(var(--muted))_50%,transparent))] tw:aria-selected:bg-selected tw:aria-selected:hover:bg-selected tw:aria-selected:text-[var(--selected-foreground,currentColor)]',\n className,\n )}\n {...props}\n />\n);\n","import { cn } from '../../utils';\nimport { Skeleton } from '../Skeleton/Skeleton';\n\nimport { TableCell } from './TableCell';\nimport { TableRow } from './TableRow';\n\n/** A width class, or one per row so the placeholders don't line up into a block. */\ntype Width = string | string[];\n\n/**\n * What one column shows while the rows load.\n *\n * - `className` and `colSpan` match the real column's cells, so the placeholders keep their layout.\n * - `text` (default): one line of `widthClassName`.\n * - `name`: an optional icon (`gapClassName` from the lines, `tw:gap-3.5` by default), a name line\n * varied per row by default, an optional description line.\n * - `empty`: nothing, e.g. for a row's actions.\n */\nexport type TableSkeletonColumn = { className?: string; colSpan?: number } & (\n | { type?: 'text'; widthClassName?: Width }\n | {\n type: 'name';\n iconClassName?: string;\n gapClassName?: string;\n widthClassName?: Width;\n descriptionClassName?: Width;\n }\n | { type: 'empty' }\n);\n\nconst NAME_WIDTHS = ['tw:w-2/5', 'tw:w-1/3', 'tw:w-1/2', 'tw:w-1/4', 'tw:w-2/5 tw:max-w-60'];\n\nconst widthOf = (width: Width, row: number) =>\n typeof width === 'string' ? width : width[row % width.length];\n\nconst SkeletonCellContent = ({ column, row }: { column: TableSkeletonColumn; row: number }) => {\n switch (column.type) {\n case 'empty':\n return null;\n case 'name':\n return (\n <div className={cn('tw:flex tw:items-center', column.gapClassName ?? 'tw:gap-3.5')}>\n {column.iconClassName && (\n <Skeleton height=\"sm\" className={cn('tw:shrink-0', column.iconClassName)} />\n )}\n <div className=\"tw:flex tw:min-w-0 tw:flex-1 tw:flex-col tw:gap-1.5\">\n <Skeleton height=\"xs\" className={widthOf(column.widthClassName ?? NAME_WIDTHS, row)} />\n {column.descriptionClassName && (\n <Skeleton height=\"xxs\" className={widthOf(column.descriptionClassName, row)} />\n )}\n </div>\n </div>\n );\n default:\n return <Skeleton height=\"xs\" className={widthOf(column.widthClassName ?? 'tw:w-3/4', row)} />;\n }\n};\n\n/**\n * Placeholder rows in a table's own columns while its rows load.\n *\n * - Render inside `Table.Body` in place of the rows.\n * - The first row announces `Loading {noun}` to screen readers; pass the plural noun, e.g. `jobs`.\n * - The rows don't take the hover tint, as there is nothing to act on yet.\n */\nexport const TableSkeletonRows = ({\n columns,\n noun,\n rows = 5,\n}: {\n columns: TableSkeletonColumn[];\n noun: string;\n rows?: number;\n}) =>\n Array.from({ length: rows }, (_, row) => (\n // oxlint-disable-next-line react/no-array-index-key -- the rows are identical placeholders\n <TableRow key={row} className=\"tw:hover:bg-transparent\">\n {columns.map((column, index) => (\n // oxlint-disable-next-line react/no-array-index-key -- columns have no id of their own\n <TableCell key={index} className={column.className} colSpan={column.colSpan}>\n {row === 0 && index === 0 && (\n <span role=\"status\" className=\"tw:sr-only\">{`Loading ${noun}`}</span>\n )}\n <SkeletonCellContent column={column} row={row} />\n </TableCell>\n ))}\n </TableRow>\n ));\n","import type { ComponentProps, ReactNode } from 'react';\n\nimport { ChevronDown, ChevronsUpDown, ChevronUp } from '../../icons';\nimport { cn } from '../../utils';\n\nexport type TableSortDirection = 'asc' | 'desc' | false;\n\n/** Maps a sort direction to the `aria-sort` value for the enclosing `Table.Head`. */\nexport const tableAriaSort = (sorted: TableSortDirection): ComponentProps<'th'>['aria-sort'] =>\n sorted === 'asc' ? 'ascending' : sorted === 'desc' ? 'descending' : 'none';\n\ntype Props = {\n /** Current sort state for this column: `'asc'`, `'desc'`, or `false` when unsorted. */\n sorted: TableSortDirection;\n children: ReactNode;\n} & Omit<ComponentProps<'button'>, 'children' | 'type'>;\n\n/**\n * Clickable column-header label with a sort-direction chevron, for use inside `Table.Head`.\n *\n * Presentational only — it owns no sort state. Pair it with your sort model (a `useState`\n * key/direction pair, or `@tanstack/react-table`'s `getToggleSortingHandler()` / `getIsSorted()`)\n * and set `aria-sort` on the enclosing `Table.Head` via {@link tableAriaSort}.\n */\nexport const TableSortHeader = ({ sorted, children, className, ...props }: Props) => {\n const Icon = sorted === false ? ChevronsUpDown : sorted === 'asc' ? ChevronUp : ChevronDown;\n return (\n <button\n className={cn(\n 'tw:group tw:flex tw:cursor-pointer tw:items-center tw:gap-1 tw:border-0 tw:bg-transparent tw:p-0 tw:font-medium tw:text-inherit',\n className,\n )}\n {...props}\n type=\"button\"\n >\n {children}\n <Icon className=\"tw:size-3 tw:text-muted-foreground\" />\n </button>\n );\n};\n","import type { ComponentProps } from 'react';\n\nimport { cn } from '../../utils';\n\nimport { TableBody } from './TableBody';\nimport { TableCell } from './TableCell';\nimport { TableFooter } from './TableFooter';\nimport { TableHead } from './TableHead';\nimport { TableHeader } from './TableHeader';\nimport { TableRow } from './TableRow';\nimport { TableSkeletonRows } from './TableSkeletonRows';\nimport { TableSortHeader } from './TableSortHeader';\n\n/**\n * - `borderCollapsed`: collapsed borders vs separate row spacing.\n * - `bordered`: rounded bordered container with overflow scrolling.\n */\ntype Props = {\n borderCollapsed?: boolean;\n bordered?: boolean;\n containerClassName?: string;\n} & ComponentProps<'table'>;\n\n/**\n * Presentational table for rows sharing one schema; sort/filter state is the consumer's.\n *\n * - Not for rows of differing shape — use a `Card` list.\n * - Wrap in `PageLayout.Content`.\n *\n * @see RECIPES.md#list-detail\n */\nexport const Table = ({\n borderCollapsed = true,\n bordered = false,\n containerClassName,\n className,\n ...props\n}: Props) => {\n return (\n <div\n className={cn(\n 'tw:relative tw:w-full',\n bordered && 'tw:overflow-auto tw:rounded-[10px] tw:border tw:border-solid tw:border-border',\n containerClassName,\n )}\n >\n <table\n className={cn(\n // - Semantic tokens so text and fill flip under `[data-theme='dark']`.\n // - The body sits on the card surface, like `Table.Header`.\n 'tw:w-full tw:caption-bottom tw:bg-card tw:text-sm tw:text-foreground',\n borderCollapsed ? 'tw:border-collapse' : 'tw:border-separate tw:border-spacing-y-1',\n className,\n )}\n {...props}\n />\n </div>\n );\n};\n\nTable.Header = TableHeader;\nTable.Head = TableHead;\nTable.Body = TableBody;\nTable.Row = TableRow;\nTable.Cell = TableCell;\nTable.Footer = TableFooter;\nTable.SortHeader = TableSortHeader;\nTable.SkeletonRows = TableSkeletonRows;\n"],"mappings":"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"}