@chassis-ui/react 0.1.2 → 0.2.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.
- package/dist/accordion.d.ts +2 -0
- package/dist/accordion.js +1 -0
- package/dist/autocomplete.d.ts +2 -0
- package/dist/autocomplete.js +1 -0
- package/dist/avatar.d.ts +2 -0
- package/dist/avatar.js +1 -0
- package/dist/badge.d.ts +2 -0
- package/dist/badge.js +1 -0
- package/dist/breadcrumb.d.ts +2 -0
- package/dist/breadcrumb.js +1 -0
- package/dist/button-group.d.ts +2 -0
- package/dist/button-group.js +1 -0
- package/dist/button.d.ts +3 -0
- package/dist/button.js +1 -0
- package/dist/calendar.d.ts +3 -0
- package/dist/calendar.js +1 -0
- package/dist/card.d.ts +2 -0
- package/dist/card.js +1 -0
- package/dist/carousel.d.ts +2 -0
- package/dist/carousel.js +1 -0
- package/dist/checkbox.d.ts +3 -0
- package/dist/checkbox.js +1 -0
- package/dist/chip-input.d.ts +2 -0
- package/dist/chip-input.js +1 -0
- package/dist/chip.d.ts +2 -0
- package/dist/chip.js +1 -0
- package/dist/chunks/Button-Cptd4Yk7.d.ts +65 -0
- package/dist/chunks/Button-I0aUy5h-.js +1 -0
- package/dist/chunks/Chip-D0Cw0mAr.js +1 -0
- package/dist/chunks/CloseButton-DJM7FRKh.js +1 -0
- package/dist/chunks/ComboboxItem-C9TpoJOI.d.ts +54 -0
- package/dist/chunks/ComboboxListBox-BhO8uRNg.js +1 -0
- package/dist/chunks/FormHelp-Be2PQL0y.js +1 -0
- package/dist/chunks/FormLabel-CYcQiFUI.js +1 -0
- package/dist/chunks/Icon-BIwkD-kx.js +1 -0
- package/dist/chunks/Icon-CioraWLF.d.ts +36 -0
- package/dist/chunks/Link-B0Y1xgYi.d.ts +69 -0
- package/dist/chunks/Link-Cq7FNWpm.js +1 -0
- package/dist/chunks/MenuItemDef-D0VDtYIQ.d.ts +82 -0
- package/dist/chunks/RangeCalendar-COnSfurr.js +1 -0
- package/dist/chunks/accordion-okRicuG5.js +1 -0
- package/dist/chunks/autocomplete-B0xTc6kg.js +1 -0
- package/dist/chunks/avatar-Bjm0DlPO.js +1 -0
- package/dist/chunks/badge-Bj8mf8lu.js +1 -0
- package/dist/chunks/breadcrumb-DDxnx_iS.js +1 -0
- package/dist/chunks/breakpoints-SLMTNHF9.d.ts +5 -0
- package/dist/chunks/breakpoints-o_2Ev7ir.js +1 -0
- package/dist/chunks/button-group-CPZYA6aZ.js +1 -0
- package/dist/chunks/card-DfF2K_5p.js +1 -0
- package/dist/chunks/carousel-DEvwcA7H.js +1 -0
- package/dist/chunks/checkbox-BFPS0pD6.js +1 -0
- package/dist/chunks/chip-input-CB1lE6vP.js +1 -0
- package/dist/chunks/collapse-WifcChO8.js +1 -0
- package/dist/chunks/color-input-CyRaLR_G.js +1 -0
- package/dist/chunks/combobox-DWEj-Sv7.js +1 -0
- package/dist/chunks/datagrid-nbnNThsT.js +2 -0
- package/dist/chunks/dateRangePresets-R1FtA1zp.d.ts +41 -0
- package/dist/chunks/datepicker-CslLKMm1.js +1 -0
- package/dist/chunks/dialogTransition-i9vw0i2Z.js +1 -0
- package/dist/chunks/direction-CPhdeL3A.js +1 -0
- package/dist/chunks/drawer-zReFjoJG.js +1 -0
- package/dist/chunks/file-input-RRqZSzjH.js +1 -0
- package/dist/chunks/flex-BTvpgaRv.js +1 -0
- package/dist/chunks/floating-input-CIC9Lm2a.js +1 -0
- package/dist/chunks/focus-ring-SR_LwaN7.js +1 -0
- package/dist/chunks/focusRedirect-BrvK3U_o.js +1 -0
- package/dist/chunks/form-GpdAyWWi.js +1 -0
- package/dist/chunks/form-field-BjQ9SIjx.js +1 -0
- package/dist/chunks/grid-CuFw89yV.js +1 -0
- package/dist/chunks/icon-mxYpL5nL.js +1 -0
- package/dist/chunks/iconConfig-Bu6Pt9o3.d.ts +69 -0
- package/dist/chunks/iconSlot-BmWxJh27.js +1 -0
- package/dist/chunks/index--0_IpTDT.d.ts +17 -0
- package/dist/chunks/index-6uob77s9.d.ts +80 -0
- package/dist/chunks/index-8PhBSbNQ.d.ts +93 -0
- package/dist/chunks/index-B0-8n-Gs.d.ts +105 -0
- package/dist/chunks/index-B8uaSJA9.d.ts +95 -0
- package/dist/chunks/index-BA-raEMm.d.ts +28 -0
- package/dist/chunks/index-BDfh8YBc.d.ts +39 -0
- package/dist/chunks/index-BKMW0rkw.d.ts +80 -0
- package/dist/chunks/index-BO9jLOIb.d.ts +58 -0
- package/dist/chunks/index-BO_1MN66.d.ts +87 -0
- package/dist/chunks/index-BTDgfLxK.d.ts +94 -0
- package/dist/chunks/index-BTTeKpiE.d.ts +363 -0
- package/dist/chunks/index-BVGGIaPX.d.ts +110 -0
- package/dist/chunks/index-Bi8FFadV.d.ts +98 -0
- package/dist/chunks/index-Bkj17NEQ.d.ts +50 -0
- package/dist/chunks/index-BlgkO3dn.d.ts +280 -0
- package/dist/chunks/index-BxTlIaZu.d.ts +301 -0
- package/dist/chunks/index-C61tPIJ-.d.ts +50 -0
- package/dist/chunks/index-CCXJXToc.d.ts +52 -0
- package/dist/chunks/index-CJzKu7QI.d.ts +40 -0
- package/dist/chunks/index-COsIPd8L.d.ts +62 -0
- package/dist/chunks/index-COsYSDrz.d.ts +109 -0
- package/dist/chunks/index-CRfm7W6C.d.ts +230 -0
- package/dist/chunks/index-CVUMS0x7.d.ts +73 -0
- package/dist/chunks/index-CaQ1JY5D.d.ts +49 -0
- package/dist/chunks/index-Cf2n0l0U.d.ts +138 -0
- package/dist/chunks/index-CftERHnE.d.ts +24 -0
- package/dist/chunks/index-ClT3E_hv.d.ts +302 -0
- package/dist/chunks/index-CsMIgBsd.d.ts +39 -0
- package/dist/chunks/index-Ctuk1xBU.d.ts +99 -0
- package/dist/chunks/index-D2VVO8rx.d.ts +49 -0
- package/dist/chunks/index-D949AidR.d.ts +40 -0
- package/dist/chunks/index-D9PZHY_I.d.ts +135 -0
- package/dist/chunks/index-DAoPg59I.d.ts +80 -0
- package/dist/chunks/index-DB_ToPdz.d.ts +202 -0
- package/dist/chunks/index-DEb9zXlC.d.ts +210 -0
- package/dist/chunks/index-DHGgezXU.d.ts +58 -0
- package/dist/chunks/index-DJJocp_q.d.ts +132 -0
- package/dist/chunks/index-DKma0jQw.d.ts +104 -0
- package/dist/chunks/index-DPV62IdF.d.ts +118 -0
- package/dist/chunks/index-DR8sYtvd.d.ts +296 -0
- package/dist/chunks/index-Dcc_W6Kv.d.ts +146 -0
- package/dist/chunks/index-Dfg4Ftb8.d.ts +68 -0
- package/dist/chunks/index-Dfy1YW5j.d.ts +73 -0
- package/dist/chunks/index-Dh5CaHTP.d.ts +44 -0
- package/dist/chunks/index-DtbUXxjz.d.ts +53 -0
- package/dist/chunks/index-Dum6Y9XR.d.ts +187 -0
- package/dist/chunks/index-HrKN6s8z.d.ts +66 -0
- package/dist/chunks/index-JllMXhVx.d.ts +176 -0
- package/dist/chunks/index-XjLvaH4G.d.ts +67 -0
- package/dist/chunks/index-dh3TKanY.d.ts +235 -0
- package/dist/chunks/index-nklPDKlC.d.ts +137 -0
- package/dist/chunks/index-qgZ5VGmc.d.ts +177 -0
- package/dist/chunks/index-tOodmT36.d.ts +129 -0
- package/dist/chunks/index-t_x6jj7l.d.ts +96 -0
- package/dist/chunks/input-adorn-C_EHML68.js +1 -0
- package/dist/chunks/input-group-iI7azfvE.js +1 -0
- package/dist/chunks/list-CMr-wB9d.js +1 -0
- package/dist/chunks/menu-CXUc-Gva.js +1 -0
- package/dist/chunks/modal-ByIj71Mq.js +1 -0
- package/dist/chunks/nav-BldxFo_B.js +1 -0
- package/dist/chunks/navbar-BwcsQuBk.js +1 -0
- package/dist/chunks/notification-DdqigVB1.js +1 -0
- package/dist/chunks/otp-input-CXe_wkII.js +1 -0
- package/dist/chunks/overlayPlacement-B7843a-Q.d.ts +6 -0
- package/dist/chunks/overlayPlacement-BtS90IVf.js +1 -0
- package/dist/chunks/pagination-BOpEAYW2.js +1 -0
- package/dist/chunks/password-strength-BfLiYiGj.js +1 -0
- package/dist/chunks/placeholder-pg95KELl.js +1 -0
- package/dist/chunks/polymorphic-CACPOv1_.js +1 -0
- package/dist/chunks/polymorphic-CVHbTHSN.d.ts +40 -0
- package/dist/chunks/popover-BpSfnZzk.js +1 -0
- package/dist/chunks/progress-DlrZ71aV.js +1 -0
- package/dist/chunks/radio-BV7Sq6D1.js +1 -0
- package/dist/chunks/range-input-BN3430j-.js +1 -0
- package/dist/chunks/renderFormCheck-BXBs6_ov.js +1 -0
- package/dist/chunks/renderFormCheck-CYWG-Rbt.d.ts +23 -0
- package/dist/chunks/renderFormField-fBEny6JV.d.ts +14 -0
- package/dist/chunks/renderFormField-wiaxvvLG.js +1 -0
- package/dist/chunks/renderMenuItemContent-CmqT3YUQ.js +1 -0
- package/dist/chunks/select-CclIIux8.js +1 -0
- package/dist/chunks/skeleton-CKq76sE_.js +1 -0
- package/dist/chunks/spacingClassName-DVhk8m3P.js +1 -0
- package/dist/chunks/spinner-BEq4PAlu.js +1 -0
- package/dist/chunks/stack-D3retZ-W.js +1 -0
- package/dist/chunks/static-table-D0M4oc_t.js +1 -0
- package/dist/chunks/stepper-CTa6e8uv.js +1 -0
- package/dist/chunks/switch-BmHpq4tL.js +1 -0
- package/dist/chunks/table-Fme9GbAR.js +1 -0
- package/dist/chunks/tableClassName-CZA2Bse8.js +1 -0
- package/dist/chunks/tabs-BnbMJM_b.js +1 -0
- package/dist/chunks/text-input-DD3d08Yf.js +1 -0
- package/dist/chunks/textarea-C0qQdCcu.js +1 -0
- package/dist/chunks/toast-BQhZ2pv5.js +1 -0
- package/dist/chunks/tooltip-DHtVAYUo.js +1 -0
- package/dist/chunks/triggerElement-BIqA4KqZ.js +1 -0
- package/dist/chunks/types-CS_40Txv.d.ts +34 -0
- package/dist/chunks/useButtonSemantics-CILM_lhi.js +1 -0
- package/dist/chunks/useDialogElement-BRIU60cT.js +1 -0
- package/dist/chunks/useDisabledAnchorGuard-Cz58UCXy.js +1 -0
- package/dist/chunks/useFloatingOverlay-CcmDZKMK.js +1 -0
- package/dist/chunks/useForkedRef-DVEfT-KI.js +1 -0
- package/dist/chunks/useFormField-BOqmBTC4.js +1 -0
- package/dist/chunks/useIsomorphicLayoutEffect-BbqRwuqn.js +1 -0
- package/dist/chunks/useToastRegionQueue-BH6bWZ73.js +1 -0
- package/dist/chunks/validationClassName-gRGs4KBm.js +1 -0
- package/dist/close-button.d.ts +2 -0
- package/dist/close-button.js +1 -0
- package/dist/collapse.d.ts +2 -0
- package/dist/collapse.js +1 -0
- package/dist/color-input.d.ts +2 -0
- package/dist/color-input.js +1 -0
- package/dist/combobox.d.ts +3 -0
- package/dist/combobox.js +1 -0
- package/dist/datagrid.d.ts +2 -0
- package/dist/datagrid.js +1 -0
- package/dist/datepicker.d.ts +2 -0
- package/dist/datepicker.js +1 -0
- package/dist/drawer.d.ts +2 -0
- package/dist/drawer.js +1 -0
- package/dist/file-input.d.ts +2 -0
- package/dist/file-input.js +1 -0
- package/dist/flex.d.ts +2 -0
- package/dist/flex.js +1 -0
- package/dist/floating-input.d.ts +2 -0
- package/dist/floating-input.js +1 -0
- package/dist/form-field.d.ts +2 -0
- package/dist/form-field.js +1 -0
- package/dist/form.d.ts +2 -0
- package/dist/form.js +1 -0
- package/dist/grid.d.ts +2 -0
- package/dist/grid.js +1 -0
- package/dist/icon.d.ts +4 -0
- package/dist/icon.js +1 -0
- package/dist/index.d.ts +72 -6354
- package/dist/index.js +1 -2
- package/dist/input-adorn.d.ts +2 -0
- package/dist/input-adorn.js +1 -0
- package/dist/input-group.d.ts +2 -0
- package/dist/input-group.js +1 -0
- package/dist/link.d.ts +3 -0
- package/dist/link.js +1 -0
- package/dist/list.d.ts +2 -0
- package/dist/list.js +1 -0
- package/dist/menu.d.ts +3 -0
- package/dist/menu.js +1 -0
- package/dist/modal.d.ts +2 -0
- package/dist/modal.js +1 -0
- package/dist/nav.d.ts +2 -0
- package/dist/nav.js +1 -0
- package/dist/navbar.d.ts +2 -0
- package/dist/navbar.js +1 -0
- package/dist/notification.d.ts +2 -0
- package/dist/notification.js +1 -0
- package/dist/otp-input.d.ts +2 -0
- package/dist/otp-input.js +1 -0
- package/dist/pagination.d.ts +2 -0
- package/dist/pagination.js +1 -0
- package/dist/password-strength.d.ts +2 -0
- package/dist/password-strength.js +1 -0
- package/dist/placeholder.d.ts +2 -0
- package/dist/placeholder.js +1 -0
- package/dist/popover.d.ts +2 -0
- package/dist/popover.js +1 -0
- package/dist/progress.d.ts +2 -0
- package/dist/progress.js +1 -0
- package/dist/radio.d.ts +2 -0
- package/dist/radio.js +1 -0
- package/dist/range-input.d.ts +2 -0
- package/dist/range-input.js +1 -0
- package/dist/select.d.ts +2 -0
- package/dist/select.js +1 -0
- package/dist/skeleton.d.ts +2 -0
- package/dist/skeleton.js +1 -0
- package/dist/spinner.d.ts +2 -0
- package/dist/spinner.js +1 -0
- package/dist/stack.d.ts +2 -0
- package/dist/stack.js +1 -0
- package/dist/static-table.d.ts +2 -0
- package/dist/static-table.js +1 -0
- package/dist/stepper.d.ts +2 -0
- package/dist/stepper.js +1 -0
- package/dist/style.css +1 -1
- package/dist/switch.d.ts +2 -0
- package/dist/switch.js +1 -0
- package/dist/table.d.ts +2 -0
- package/dist/table.js +1 -0
- package/dist/tabs.d.ts +2 -0
- package/dist/tabs.js +1 -0
- package/dist/text-input.d.ts +2 -0
- package/dist/text-input.js +1 -0
- package/dist/textarea.d.ts +2 -0
- package/dist/textarea.js +1 -0
- package/dist/toast.d.ts +2 -0
- package/dist/toast.js +1 -0
- package/dist/tooltip.d.ts +2 -0
- package/dist/tooltip.js +1 -0
- package/package.json +62 -4
- package/src/components/accordion/index.ts +4 -0
- package/src/components/autocomplete/index.ts +4 -0
- package/src/components/avatar/index.ts +4 -0
- package/src/components/badge/index.ts +4 -0
- package/src/components/breadcrumb/index.ts +4 -0
- package/src/components/button/index.ts +4 -0
- package/src/components/button-group/index.ts +4 -0
- package/src/components/calendar/index.ts +4 -0
- package/src/components/card/index.ts +4 -0
- package/src/components/carousel/CarouselControlButton.tsx +11 -4
- package/src/components/carousel/CarouselControlNext.tsx +6 -0
- package/src/components/carousel/CarouselControlPrev.tsx +6 -0
- package/src/components/carousel/CarouselPlayPause.tsx +27 -4
- package/src/components/carousel/index.ts +4 -0
- package/src/components/checkbox/Checkbox.tsx +19 -4
- package/src/components/checkbox/index.ts +4 -0
- package/src/components/chip/index.ts +4 -0
- package/src/components/chip-input/index.ts +4 -0
- package/src/components/close-button/index.ts +4 -0
- package/src/components/collapse/index.ts +4 -0
- package/src/components/color-input/index.ts +4 -0
- package/src/components/combobox/ComboboxListBox.tsx +2 -2
- package/src/components/combobox/index.ts +4 -0
- package/src/components/datagrid/index.ts +4 -0
- package/src/components/datepicker/index.ts +4 -0
- package/src/components/drawer/index.ts +8 -0
- package/src/components/file-input/index.ts +4 -0
- package/src/components/flex/index.ts +4 -0
- package/src/components/floating-input/index.ts +4 -0
- package/src/components/form/index.ts +4 -0
- package/src/components/form-field/index.ts +4 -0
- package/src/components/grid/index.ts +4 -0
- package/src/components/icon/Icon.tsx +69 -38
- package/src/components/icon/IconProvider.tsx +40 -0
- package/src/components/icon/index.ts +7 -0
- package/src/components/input-adorn/index.ts +4 -0
- package/src/components/input-group/index.ts +4 -0
- package/src/components/link/index.ts +4 -0
- package/src/components/list/index.ts +4 -0
- package/src/components/menu/index.ts +4 -0
- package/src/components/modal/index.ts +8 -0
- package/src/components/nav/index.ts +4 -0
- package/src/components/navbar/NavbarToggler.tsx +9 -3
- package/src/components/navbar/index.ts +4 -0
- package/src/components/notification/Notification.tsx +6 -5
- package/src/components/notification/index.ts +8 -0
- package/src/components/otp-input/index.ts +4 -0
- package/src/components/pagination/Pagination.tsx +16 -3
- package/src/components/pagination/index.ts +8 -0
- package/src/components/password-strength/index.ts +4 -0
- package/src/components/placeholder/index.ts +4 -0
- package/src/components/popover/index.ts +4 -0
- package/src/components/progress/index.ts +4 -0
- package/src/components/radio/Radio.tsx +13 -3
- package/src/components/radio/index.ts +4 -0
- package/src/components/range-input/index.ts +4 -0
- package/src/components/select/index.ts +4 -0
- package/src/components/skeleton/SkeletonLoader.tsx +13 -6
- package/src/components/skeleton/index.ts +4 -0
- package/src/components/spinner/index.ts +4 -0
- package/src/components/stack/index.ts +4 -0
- package/src/components/static-table/StaticTable.tsx +78 -0
- package/src/components/static-table/index.ts +8 -0
- package/src/components/stepper/index.ts +4 -0
- package/src/components/switch/Switch.tsx +16 -3
- package/src/components/switch/index.ts +4 -0
- package/src/components/table/Table.tsx +14 -22
- package/src/components/table/index.ts +4 -0
- package/src/components/tabs/index.ts +4 -0
- package/src/components/text-input/index.ts +4 -0
- package/src/components/textarea/index.ts +4 -0
- package/src/components/toast/Toast.tsx +2 -1
- package/src/components/toast/ToastHeader.tsx +4 -3
- package/src/components/toast/index.ts +8 -0
- package/src/components/tooltip/index.ts +4 -0
- package/src/hooks/useIconConfig.ts +6 -0
- package/src/index.ts +24 -4
- package/src/utils/iconConfig.ts +88 -0
- package/src/utils/iconSlot.tsx +41 -0
- package/src/utils/polymorphic.ts +49 -2
- package/src/utils/renderMenuItemContent.tsx +4 -9
- package/src/utils/slot.tsx +78 -0
- package/src/utils/tableClassName.ts +93 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import React, { forwardRef, ReactNode, TableHTMLAttributes } from 'react'
|
|
2
|
+
|
|
3
|
+
import { TableStyleProps, tableClassName, tableWrapperClassName } from '../../utils/tableClassName'
|
|
4
|
+
|
|
5
|
+
export interface StaticTableProps
|
|
6
|
+
extends TableStyleProps, Omit<TableHTMLAttributes<HTMLTableElement>, 'align' | 'color'> {
|
|
7
|
+
/**
|
|
8
|
+
* Content shown above the table, functioning as a heading for it.
|
|
9
|
+
*/
|
|
10
|
+
caption?: ReactNode
|
|
11
|
+
/**
|
|
12
|
+
* The table's own markup — plain `<thead>`/`<tbody>`/`<tfoot>`/`<tr>`/`<th>`/`<td>` elements,
|
|
13
|
+
* rendered as-is.
|
|
14
|
+
*/
|
|
15
|
+
children?: ReactNode
|
|
16
|
+
/**
|
|
17
|
+
* Convert rows into stacked label/value blocks below a container width, for tables with too
|
|
18
|
+
* many columns to read comfortably even with horizontal scrolling. `true` always stacks; a
|
|
19
|
+
* breakpoint name stacks only below it. Implies `responsive` when `responsive` isn't set
|
|
20
|
+
* separately. Unlike `Table`, which derives each cell's label from its column header, a static
|
|
21
|
+
* table has no collection to read labels from — give each `<td>` a `data-cell` attribute with
|
|
22
|
+
* the label to show before its value.
|
|
23
|
+
*/
|
|
24
|
+
stacked?: TableStyleProps['stacked']
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// A plain, server-renderable `<table>` with `Table`'s styling props and none of its behavior — no
|
|
28
|
+
// sorting, selection, or keyboard grid navigation, and no hooks, so it needs no client JavaScript
|
|
29
|
+
// at all. Imported from `@chassis-ui/react/static-table`, whose entry deliberately has no
|
|
30
|
+
// `'use client'` directive (see `RSC.md`). `forwardRef` is fine here: React Server Components
|
|
31
|
+
// render forwardRef components like any other function component (a ref just can't be passed
|
|
32
|
+
// from the server side).
|
|
33
|
+
export const StaticTable = forwardRef<HTMLTableElement, StaticTableProps>(
|
|
34
|
+
(
|
|
35
|
+
{
|
|
36
|
+
align,
|
|
37
|
+
bordered,
|
|
38
|
+
borderless,
|
|
39
|
+
caption,
|
|
40
|
+
children,
|
|
41
|
+
className,
|
|
42
|
+
color,
|
|
43
|
+
hover,
|
|
44
|
+
responsive,
|
|
45
|
+
sm,
|
|
46
|
+
stacked,
|
|
47
|
+
striped,
|
|
48
|
+
...rest
|
|
49
|
+
},
|
|
50
|
+
ref
|
|
51
|
+
) => {
|
|
52
|
+
const table = (
|
|
53
|
+
<table
|
|
54
|
+
{...rest}
|
|
55
|
+
className={tableClassName({
|
|
56
|
+
align,
|
|
57
|
+
bordered,
|
|
58
|
+
borderless,
|
|
59
|
+
className,
|
|
60
|
+
color,
|
|
61
|
+
hover,
|
|
62
|
+
sm,
|
|
63
|
+
stacked,
|
|
64
|
+
striped
|
|
65
|
+
})}
|
|
66
|
+
ref={ref}
|
|
67
|
+
>
|
|
68
|
+
{caption && <caption>{caption}</caption>}
|
|
69
|
+
{children}
|
|
70
|
+
</table>
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
const wrapperClassName = tableWrapperClassName({ responsive, stacked })
|
|
74
|
+
return wrapperClassName ? <div className={wrapperClassName}>{table}</div> : table
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
StaticTable.displayName = 'StaticTable'
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Deliberately no 'use client' directive — unlike every other component folder's barrel, this one
|
|
2
|
+
// is the server-safe entry point, `@chassis-ui/react/static-table`, and must stay importable from
|
|
3
|
+
// a React Server Component without creating a client boundary (see RSC.md). Nothing reachable from
|
|
4
|
+
// here may use hooks, context, or browser APIs; `scripts/check-rsc-directive.ts` fails the build if
|
|
5
|
+
// the built entry ever gains a directive. For the same reason it skips the
|
|
6
|
+
// `suppressFocusRingGlobally` import the other barrels carry — there's no client module to run it.
|
|
7
|
+
export { StaticTable } from './StaticTable'
|
|
8
|
+
export type { StaticTableProps } from './StaticTable'
|
|
@@ -39,6 +39,11 @@ export interface SwitchProps extends Omit<
|
|
|
39
39
|
isSelected?: boolean
|
|
40
40
|
/**
|
|
41
41
|
* The element represents a caption for a component.
|
|
42
|
+
*
|
|
43
|
+
* Children are accepted as an alias for this prop — `label` wins when both are given.
|
|
44
|
+
* react-aria, which backs this component, calls the same thing `children`; this package renames
|
|
45
|
+
* it to `label`, and honouring both means the shape React developers reach for first still
|
|
46
|
+
* names the control instead of silently producing an unlabelled one.
|
|
42
47
|
*/
|
|
43
48
|
label?: ReactNode
|
|
44
49
|
/**
|
|
@@ -135,6 +140,7 @@ const SwitchCheckbox = forwardRef<HTMLInputElement, SwitchVariantProps>(
|
|
|
135
140
|
(
|
|
136
141
|
{
|
|
137
142
|
className,
|
|
143
|
+
children,
|
|
138
144
|
color,
|
|
139
145
|
defaultSelected,
|
|
140
146
|
disabled,
|
|
@@ -151,6 +157,9 @@ const SwitchCheckbox = forwardRef<HTMLInputElement, SwitchVariantProps>(
|
|
|
151
157
|
) => {
|
|
152
158
|
const inputRef = useRef<HTMLInputElement>(null)
|
|
153
159
|
const forkedRef = useForkedRef(ref, inputRef)
|
|
160
|
+
// `label` is this package's name for what react-aria calls `children`. Accept either, so the
|
|
161
|
+
// shape React developers reach for first names the control instead of vanishing.
|
|
162
|
+
const resolvedLabel = label ?? children
|
|
154
163
|
|
|
155
164
|
const toggleState = useToggleState({
|
|
156
165
|
defaultSelected,
|
|
@@ -162,7 +171,7 @@ const SwitchCheckbox = forwardRef<HTMLInputElement, SwitchVariantProps>(
|
|
|
162
171
|
const { inputProps: switchProps } = useSwitch(
|
|
163
172
|
{
|
|
164
173
|
...rest,
|
|
165
|
-
children:
|
|
174
|
+
children: resolvedLabel,
|
|
166
175
|
isDisabled: disabled,
|
|
167
176
|
isInvalid: invalid,
|
|
168
177
|
value: rest.value as string | undefined
|
|
@@ -178,7 +187,7 @@ const SwitchCheckbox = forwardRef<HTMLInputElement, SwitchVariantProps>(
|
|
|
178
187
|
id,
|
|
179
188
|
inputProps: switchProps,
|
|
180
189
|
invalid,
|
|
181
|
-
label,
|
|
190
|
+
label: resolvedLabel,
|
|
182
191
|
size,
|
|
183
192
|
valid
|
|
184
193
|
})
|
|
@@ -192,6 +201,7 @@ SwitchCheckbox.displayName = 'SwitchCheckbox'
|
|
|
192
201
|
const SwitchRadio = forwardRef<HTMLInputElement, SwitchVariantProps>(
|
|
193
202
|
(
|
|
194
203
|
{
|
|
204
|
+
children,
|
|
195
205
|
className,
|
|
196
206
|
color,
|
|
197
207
|
defaultSelected,
|
|
@@ -209,6 +219,9 @@ const SwitchRadio = forwardRef<HTMLInputElement, SwitchVariantProps>(
|
|
|
209
219
|
) => {
|
|
210
220
|
const inputRef = useRef<HTMLInputElement>(null)
|
|
211
221
|
const forkedRef = useForkedRef(ref, inputRef)
|
|
222
|
+
// `label` is this package's name for what react-aria calls `children`. Accept either, so the
|
|
223
|
+
// shape React developers reach for first names the control instead of vanishing.
|
|
224
|
+
const resolvedLabel = label ?? children
|
|
212
225
|
|
|
213
226
|
const radioProps = {
|
|
214
227
|
...rest,
|
|
@@ -230,7 +243,7 @@ const SwitchRadio = forwardRef<HTMLInputElement, SwitchVariantProps>(
|
|
|
230
243
|
id,
|
|
231
244
|
inputProps: radioProps,
|
|
232
245
|
invalid,
|
|
233
|
-
label,
|
|
246
|
+
label: resolvedLabel,
|
|
234
247
|
size,
|
|
235
248
|
valid
|
|
236
249
|
})
|
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
|
|
26
26
|
import { useForkedRef } from '../../hooks/useForkedRef'
|
|
27
27
|
import { ContextColor } from '../../types'
|
|
28
|
+
import { tableClassName, tableWrapperClassName } from '../../utils/tableClassName'
|
|
28
29
|
import './Table.css'
|
|
29
30
|
|
|
30
31
|
// `GridNode<T>` (from `@react-types/shared`) isn't re-exported by either package's public
|
|
@@ -179,24 +180,20 @@ const TableInner = <T extends object>(
|
|
|
179
180
|
internalRef
|
|
180
181
|
)
|
|
181
182
|
|
|
182
|
-
const _className =
|
|
183
|
-
|
|
183
|
+
const _className = tableClassName({
|
|
184
|
+
align,
|
|
185
|
+
bordered,
|
|
186
|
+
borderless,
|
|
187
|
+
className,
|
|
184
188
|
color,
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
sm,
|
|
191
|
-
stacked: stacked === true,
|
|
192
|
-
striped
|
|
193
|
-
},
|
|
194
|
-
typeof stacked === 'string' ? `max-${stacked}:stacked` : undefined,
|
|
195
|
-
className
|
|
196
|
-
)
|
|
189
|
+
hover,
|
|
190
|
+
sm,
|
|
191
|
+
stacked,
|
|
192
|
+
striped
|
|
193
|
+
})
|
|
197
194
|
|
|
198
195
|
const tableEl = (
|
|
199
|
-
<table {...gridProps} className={_className
|
|
196
|
+
<table {...gridProps} className={_className} ref={ref}>
|
|
200
197
|
{caption && <caption>{caption}</caption>}
|
|
201
198
|
<TableRowGroup className={children[0].props.className} type="thead">
|
|
202
199
|
{state.collection.headerRows.map((headerRow) => (
|
|
@@ -228,13 +225,8 @@ const TableInner = <T extends object>(
|
|
|
228
225
|
</table>
|
|
229
226
|
)
|
|
230
227
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
const wrapperClassName = responsive
|
|
234
|
-
? typeof responsive === 'boolean'
|
|
235
|
-
? 'table-responsive'
|
|
236
|
-
: `max-${responsive}:table-responsive`
|
|
237
|
-
: 'table-responsive'
|
|
228
|
+
const wrapperClassName = tableWrapperClassName({ responsive, stacked })
|
|
229
|
+
if (!wrapperClassName) return tableEl
|
|
238
230
|
|
|
239
231
|
return <div className={wrapperClassName}>{tableEl}</div>
|
|
240
232
|
}
|
|
@@ -51,7 +51,8 @@ export interface ToastProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'
|
|
|
51
51
|
*/
|
|
52
52
|
footer?: ReactNode | ((close: () => void) => ReactNode)
|
|
53
53
|
/**
|
|
54
|
-
* Leading icon for the header. A string is
|
|
54
|
+
* Leading icon for the header. A string is an icon name, rendered like
|
|
55
|
+
* `<ToastIcon name={icon} />` (or by `IconProvider`'s `component`); pass
|
|
55
56
|
* any other node for a fully custom icon (typically a logo or avatar). Shorthand for
|
|
56
57
|
* `ToastHeader`'s `icon` prop; hidden from assistive technology by default, since it
|
|
57
58
|
* duplicates `title` visually.
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
PolymorphicComponentProps,
|
|
9
9
|
PolymorphicRef
|
|
10
10
|
} from '../../utils/polymorphic'
|
|
11
|
-
import {
|
|
11
|
+
import { ResolvedIcon } from '../../utils/iconSlot'
|
|
12
12
|
|
|
13
13
|
type ToastHeaderOwnProps<C extends ElementType> = {
|
|
14
14
|
/**
|
|
@@ -33,7 +33,8 @@ type ToastHeaderOwnProps<C extends ElementType> = {
|
|
|
33
33
|
*/
|
|
34
34
|
component?: C
|
|
35
35
|
/**
|
|
36
|
-
* Leading icon. A string is rendered
|
|
36
|
+
* Leading icon. A string is an icon name, rendered like `<ToastIcon name={icon} />` (or by
|
|
37
|
+
* `IconProvider`'s `component`) and hidden from
|
|
37
38
|
* assistive technology by default, since it duplicates the heading visually. Pass any other
|
|
38
39
|
* node for a fully custom icon (typically a logo or avatar) — a custom node is left as-is,
|
|
39
40
|
* since it may carry its own meaningful accessible name (e.g. an avatar's `alt` text).
|
|
@@ -82,7 +83,7 @@ function ToastHeaderRender<C extends ElementType = 'div'>(
|
|
|
82
83
|
{icon != null &&
|
|
83
84
|
(typeof icon === 'string' ? (
|
|
84
85
|
<span aria-hidden="true" className="me-sm">
|
|
85
|
-
<
|
|
86
|
+
<ResolvedIcon value={icon} className="toast-icon" />
|
|
86
87
|
</span>
|
|
87
88
|
) : (
|
|
88
89
|
<span className="me-sm">{icon}</span>
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import '../../utils/suppressFocusRingGlobally'
|
|
4
|
+
|
|
1
5
|
export { Toast } from './Toast'
|
|
2
6
|
export type { ToastProps } from './Toast'
|
|
3
7
|
export { ToastBody } from './ToastBody'
|
|
@@ -16,3 +20,7 @@ export { Toaster } from './Toaster'
|
|
|
16
20
|
export type { ToasterProps } from './Toaster'
|
|
17
21
|
export { addToast, closeToast, toastQueue } from './toastQueue'
|
|
18
22
|
export type { ToastContent } from './toastQueue'
|
|
23
|
+
// Also exported from the package root; repeated here so this folder's subpath entry
|
|
24
|
+
// (`@chassis-ui/react/<folder>`) covers the whole family without reaching back to the root.
|
|
25
|
+
export { useToast } from '../../hooks/useToast'
|
|
26
|
+
export type { UseToastResult } from '../../hooks/useToast'
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { useContext } from 'react'
|
|
2
|
+
|
|
3
|
+
import { IconConfig, IconContext } from '../utils/iconConfig'
|
|
4
|
+
|
|
5
|
+
// The nearest `IconProvider`'s settings, merged with every provider above it; empty outside one.
|
|
6
|
+
export const useIconConfig = (): IconConfig => useContext(IconContext)
|
package/src/index.ts
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
// Side-effect only: installs the single document-level pointerdown listener that works around the
|
|
4
4
|
// browser's `:focus-visible` first-click heuristic misfire — see the module's own comment. Needs to
|
|
5
|
-
// run once wherever this package is used, not per-component, so it's imported
|
|
6
|
-
//
|
|
5
|
+
// run once wherever this package is used, not per-component, so it's imported by entry points
|
|
6
|
+
// (here, and every component folder's `index.ts` barrel, each of which is also a subpath entry)
|
|
7
|
+
// rather than from any individual component.
|
|
7
8
|
import './utils/suppressFocusRingGlobally'
|
|
8
9
|
|
|
9
10
|
import { Accordion, AccordionBody, AccordionHeader, AccordionItem } from './components/accordion'
|
|
@@ -91,7 +92,7 @@ import { Select } from './components/select'
|
|
|
91
92
|
import { Switch } from './components/switch'
|
|
92
93
|
import { TextInput } from './components/text-input'
|
|
93
94
|
import { Textarea } from './components/textarea'
|
|
94
|
-
import { Icon } from './components/icon'
|
|
95
|
+
import { Icon, IconProvider } from './components/icon'
|
|
95
96
|
import { Placeholder } from './components/placeholder'
|
|
96
97
|
import { Link } from './components/link'
|
|
97
98
|
import { List, ListItem } from './components/list'
|
|
@@ -104,6 +105,7 @@ import { Progress, ProgressBar } from './components/progress'
|
|
|
104
105
|
import { Drawer, DrawerBody, DrawerFooter, DrawerHeader, DrawerTitle } from './components/drawer'
|
|
105
106
|
import { Skeleton, SkeletonLoader } from './components/skeleton'
|
|
106
107
|
import { Spinner } from './components/spinner'
|
|
108
|
+
import { StaticTable } from './components/static-table'
|
|
107
109
|
import { Stepper, StepperItem } from './components/stepper'
|
|
108
110
|
import { Table, TableBody, TableCell, TableColumn, TableHeader, TableRow } from './components/table'
|
|
109
111
|
import { Tabs, Tab, TabList, TabPanel } from './components/tabs'
|
|
@@ -224,6 +226,7 @@ export {
|
|
|
224
226
|
FormHelp,
|
|
225
227
|
FormLabel,
|
|
226
228
|
Icon,
|
|
229
|
+
IconProvider,
|
|
227
230
|
Placeholder,
|
|
228
231
|
InputGroup,
|
|
229
232
|
InputGroupAddon,
|
|
@@ -265,6 +268,7 @@ export {
|
|
|
265
268
|
Skeleton,
|
|
266
269
|
SkeletonLoader,
|
|
267
270
|
Spinner,
|
|
271
|
+
StaticTable,
|
|
268
272
|
Stepper,
|
|
269
273
|
StepperItem,
|
|
270
274
|
Switch,
|
|
@@ -367,6 +371,15 @@ export type { CloseButtonProps } from './components/close-button'
|
|
|
367
371
|
export type { CollapseProps } from './components/collapse'
|
|
368
372
|
export type { ColorInputProps } from './components/color-input'
|
|
369
373
|
export type { ComboboxGroupProps, ComboboxItemProps, ComboboxProps } from './components/combobox'
|
|
374
|
+
export type {
|
|
375
|
+
DataGridBodyProps,
|
|
376
|
+
DataGridCellProps,
|
|
377
|
+
DataGridColumnProps,
|
|
378
|
+
DataGridHeaderProps,
|
|
379
|
+
DataGridProps,
|
|
380
|
+
DataGridRowProps,
|
|
381
|
+
DataGridSelectionCellProps
|
|
382
|
+
} from './components/datagrid'
|
|
370
383
|
export type {
|
|
371
384
|
DatePickerMultipleProps,
|
|
372
385
|
DatePickerProps,
|
|
@@ -393,7 +406,13 @@ export type {
|
|
|
393
406
|
GridProps,
|
|
394
407
|
RowProps
|
|
395
408
|
} from './components/grid'
|
|
396
|
-
export type {
|
|
409
|
+
export type {
|
|
410
|
+
IconComponentProps,
|
|
411
|
+
IconKey,
|
|
412
|
+
IconProps,
|
|
413
|
+
IconProviderProps,
|
|
414
|
+
IconValue
|
|
415
|
+
} from './components/icon'
|
|
397
416
|
export type { InputAdornProps } from './components/input-adorn'
|
|
398
417
|
export type { InputGroupAddonProps, InputGroupProps } from './components/input-group'
|
|
399
418
|
export type { LinkProps } from './components/link'
|
|
@@ -449,6 +468,7 @@ export type { RangeInputProps } from './components/range-input'
|
|
|
449
468
|
export type { SelectOptionDef, SelectProps } from './components/select'
|
|
450
469
|
export type { SkeletonLoaderProps, SkeletonProps } from './components/skeleton'
|
|
451
470
|
export type { SpinnerProps } from './components/spinner'
|
|
471
|
+
export type { StaticTableProps } from './components/static-table'
|
|
452
472
|
export type { StackProps } from './components/stack'
|
|
453
473
|
export type { StepperItemDef, StepperItemProps, StepperProps } from './components/stepper'
|
|
454
474
|
export type { SwitchProps } from './components/switch'
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { ComponentType, createContext, ReactElement } from 'react'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The icons this library's own components draw, by purpose rather than by icon name — so a
|
|
5
|
+
* consumer can map each one onto any icon set (see `IconProvider`'s `icons`).
|
|
6
|
+
*/
|
|
7
|
+
export type IconKey = 'check' | 'previous' | 'next' | 'menu' | 'play' | 'pause'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* An icon given to `IconProvider`'s `icons` or to a component's icon prop: a string is an icon
|
|
11
|
+
* name, rendered by `IconProvider`'s `component` (or the built-in `Icon`); an element is rendered
|
|
12
|
+
* as-is, with the component's own class names merged onto it.
|
|
13
|
+
*/
|
|
14
|
+
export type IconValue = string | ReactElement
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Props `IconProvider`'s `component` receives for every icon name it's asked to render.
|
|
18
|
+
*/
|
|
19
|
+
export interface IconComponentProps {
|
|
20
|
+
/**
|
|
21
|
+
* The icon name — an `IconValue` string, or `IconProvider`'s default for that icon.
|
|
22
|
+
*/
|
|
23
|
+
name: string
|
|
24
|
+
/**
|
|
25
|
+
* The class names the rendering component needs on the icon (e.g. `menu-item-check`,
|
|
26
|
+
* `directional-icon`) for chassis-css to position and flip it.
|
|
27
|
+
*/
|
|
28
|
+
className?: string
|
|
29
|
+
[prop: string]: unknown
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface IconConfig {
|
|
33
|
+
/**
|
|
34
|
+
* Class names added to every `Icon`, alongside its own `icon` class.
|
|
35
|
+
*/
|
|
36
|
+
className?: string
|
|
37
|
+
/**
|
|
38
|
+
* Replaces the built-in `Icon` for every icon this library's components render by name — the
|
|
39
|
+
* strings in `icons` and their defaults, and a string `icon` on `Toast`/`Notification`. A
|
|
40
|
+
* component reference can't be passed from a React Server Component, so set this in a
|
|
41
|
+
* `'use client'` module.
|
|
42
|
+
*/
|
|
43
|
+
component?: ComponentType<IconComponentProps>
|
|
44
|
+
/**
|
|
45
|
+
* Render `Icon` as an icon-font glyph instead of an SVG sprite reference, unless an `Icon` sets
|
|
46
|
+
* `font` itself. Needs the icon font's stylesheet loaded.
|
|
47
|
+
*/
|
|
48
|
+
font?: boolean
|
|
49
|
+
/**
|
|
50
|
+
* Class-name prefix of the icon font's glyphs: an icon named `check-solid` renders as
|
|
51
|
+
* `{fontPrefix}check-solid`.
|
|
52
|
+
*
|
|
53
|
+
* @default 'cx-'
|
|
54
|
+
*/
|
|
55
|
+
fontPrefix?: string
|
|
56
|
+
/**
|
|
57
|
+
* The icon to render for each of the library's own icons, by purpose. Unset ones keep their
|
|
58
|
+
* defaults (`check-solid`, `chevron-left-outline`, `chevron-right-outline`, `bars-outline`,
|
|
59
|
+
* `play-solid`, `pause-solid`).
|
|
60
|
+
*/
|
|
61
|
+
icons?: Partial<Record<IconKey, IconValue>>
|
|
62
|
+
/**
|
|
63
|
+
* URL of the SVG sprite `Icon` references, e.g. `/static/icons/chassis-icons.svg`. Leave empty
|
|
64
|
+
* (the default) when the sprite is embedded in the page, so icons render as `href="#name"`.
|
|
65
|
+
* Browsers don't load an external sprite from another origin.
|
|
66
|
+
*
|
|
67
|
+
* @default ''
|
|
68
|
+
*/
|
|
69
|
+
sprite?: string
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// The chassis-icons names this library used before its icons became configurable. Both
|
|
73
|
+
// previous/next consumers (Pagination, Carousel) now share the outline chevrons — Pagination used
|
|
74
|
+
// the solid ones.
|
|
75
|
+
export const DEFAULT_ICONS: Record<IconKey, string> = {
|
|
76
|
+
check: 'check-solid',
|
|
77
|
+
previous: 'chevron-left-outline',
|
|
78
|
+
next: 'chevron-right-outline',
|
|
79
|
+
menu: 'bars-outline',
|
|
80
|
+
play: 'play-solid',
|
|
81
|
+
pause: 'pause-solid'
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const DEFAULT_FONT_PREFIX = 'cx-'
|
|
85
|
+
|
|
86
|
+
// Lives in `utils/` rather than `components/icon/` because it's read outside that folder too —
|
|
87
|
+
// by `IconSlot` (`./iconSlot.tsx`), which every icon-drawing component renders through.
|
|
88
|
+
export const IconContext = createContext<IconConfig>({})
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, { cloneElement, ReactElement } from 'react'
|
|
2
|
+
import { mergeProps } from 'react-aria'
|
|
3
|
+
|
|
4
|
+
import { Icon } from '../components/icon/Icon'
|
|
5
|
+
import { useIconConfig } from '../hooks/useIconConfig'
|
|
6
|
+
import { DEFAULT_ICONS, IconKey, IconValue } from './iconConfig'
|
|
7
|
+
|
|
8
|
+
// Every icon this library's own components draw goes through here, never through `<Icon>`
|
|
9
|
+
// directly, so a consumer can swap in their own icons (`IconProvider`'s `icons`/`component`, or a
|
|
10
|
+
// component's own icon prop). The rendering component passes the class names chassis-css hooks
|
|
11
|
+
// onto (`menu-item-check` positions the check, `navbar-toggler-icon` sizes and colors it,
|
|
12
|
+
// `carousel-icon-play`/`-pause` are toggled by state, `directional-icon` flips in RTL); those are
|
|
13
|
+
// merged onto whatever icon ends up rendered, so a custom icon lands in the same place a built-in
|
|
14
|
+
// one would. `aria-hidden` defaults on: each of these icons sits beside its own visible or
|
|
15
|
+
// visually-hidden label.
|
|
16
|
+
//
|
|
17
|
+
// A custom *element* deliberately doesn't get the `icon` class itself: chassis-css's `.icon` sets
|
|
18
|
+
// `fill`, which would paint over an outline icon set's `fill="none"` (Lucide, Heroicons outline,
|
|
19
|
+
// ...). It keeps its own size and color — `currentColor` icons still follow the control's text.
|
|
20
|
+
type IconRenderProps = { className?: string } & Record<string, unknown>
|
|
21
|
+
|
|
22
|
+
export function ResolvedIcon({ value, ...props }: IconRenderProps & { value: IconValue }) {
|
|
23
|
+
const { component: Component } = useIconConfig()
|
|
24
|
+
const iconProps = { 'aria-hidden': true, ...props }
|
|
25
|
+
|
|
26
|
+
if (typeof value !== 'string') {
|
|
27
|
+
const element = value as ReactElement<Record<string, unknown>>
|
|
28
|
+
return cloneElement(element, mergeProps(iconProps, element.props))
|
|
29
|
+
}
|
|
30
|
+
if (Component) return <Component name={value} {...iconProps} />
|
|
31
|
+
return <Icon name={value} {...iconProps} />
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function IconSlot({
|
|
35
|
+
icon,
|
|
36
|
+
override,
|
|
37
|
+
...props
|
|
38
|
+
}: IconRenderProps & { icon: IconKey; override?: IconValue }) {
|
|
39
|
+
const { icons } = useIconConfig()
|
|
40
|
+
return <ResolvedIcon value={override ?? icons?.[icon] ?? DEFAULT_ICONS[icon]} {...props} />
|
|
41
|
+
}
|
package/src/utils/polymorphic.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ComponentPropsWithoutRef,
|
|
3
3
|
ComponentPropsWithRef,
|
|
4
|
+
createElement,
|
|
4
5
|
ElementType,
|
|
5
6
|
ForwardRefRenderFunction,
|
|
6
7
|
forwardRef,
|
|
7
8
|
Ref
|
|
8
9
|
} from 'react'
|
|
9
10
|
|
|
11
|
+
import { devWarning } from './devWarning'
|
|
12
|
+
import { getSlotChild, Slot, SlotProvider } from './slot'
|
|
13
|
+
|
|
10
14
|
// Ref type inferred from a polymorphic component's currently-selected `component` element type.
|
|
11
15
|
export type PolymorphicRef<C extends ElementType> = ComponentPropsWithRef<C>['ref']
|
|
12
16
|
|
|
@@ -26,6 +30,21 @@ export type PolymorphicRef<C extends ElementType> = ComponentPropsWithRef<C>['re
|
|
|
26
30
|
export type PolymorphicRefWithFallback<C extends ElementType, Fallback extends HTMLElement> =
|
|
27
31
|
PolymorphicRef<C> | Ref<Fallback>
|
|
28
32
|
|
|
33
|
+
/**
|
|
34
|
+
* The `asChild` prop every polymorphic component accepts alongside `component` — see
|
|
35
|
+
* `createPolymorphicComponent` below for how it's implemented once for all of them.
|
|
36
|
+
*/
|
|
37
|
+
export interface AsChildProps {
|
|
38
|
+
/**
|
|
39
|
+
* Render the single child element in place of this component's own element, with this
|
|
40
|
+
* component's classes, props and ref merged onto it: `<Button asChild><Link href="/login">Log
|
|
41
|
+
* in</Link></Button>`. The alternative to `component` for React Server Components — an element
|
|
42
|
+
* can be passed from the server to this package's client components, a component reference
|
|
43
|
+
* (`component={Link}`) can't.
|
|
44
|
+
*/
|
|
45
|
+
asChild?: boolean
|
|
46
|
+
}
|
|
47
|
+
|
|
29
48
|
/**
|
|
30
49
|
* Props for a polymorphic component: `OwnProps` (which must declare `component?: C`) plus
|
|
31
50
|
* whatever props `C` itself accepts, minus any name already claimed by `OwnProps` so the two
|
|
@@ -33,7 +52,8 @@ export type PolymorphicRefWithFallback<C extends ElementType, Fallback extends H
|
|
|
33
52
|
* type-checking/autocomplete for that component's own props at the call site.
|
|
34
53
|
*/
|
|
35
54
|
export type PolymorphicComponentProps<C extends ElementType, OwnProps extends object> = OwnProps &
|
|
36
|
-
|
|
55
|
+
AsChildProps &
|
|
56
|
+
Omit<ComponentPropsWithoutRef<C>, keyof OwnProps | keyof AsChildProps>
|
|
37
57
|
|
|
38
58
|
/**
|
|
39
59
|
* Wraps a polymorphic component's render function in `forwardRef` and stamps `displayName` — the
|
|
@@ -41,13 +61,40 @@ export type PolymorphicComponentProps<C extends ElementType, OwnProps extends ob
|
|
|
41
61
|
* fully generic component type (e.g. `ButtonComponent`) that `forwardRef`'s own return type can't
|
|
42
62
|
* express, since `forwardRef` only accepts a non-generic render function — the caller still casts
|
|
43
63
|
* the render function to a concrete `Element`-typed instance before passing it in here.
|
|
64
|
+
*
|
|
65
|
+
* Also implements `asChild` for every polymorphic component at once (#23): the render function
|
|
66
|
+
* gets `component={Slot}` and the child element's own children, so it computes its classes,
|
|
67
|
+
* props and ref exactly as it would for any component reference (`component={Link}`) — `Slot`
|
|
68
|
+
* then clones the caller's child element with all of that merged on (see `./slot`). No render
|
|
69
|
+
* function needs to know `asChild` exists.
|
|
44
70
|
*/
|
|
45
71
|
export function createPolymorphicComponent<T>(
|
|
46
72
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
47
73
|
render: ForwardRefRenderFunction<Element, any>,
|
|
48
74
|
displayName: string
|
|
49
75
|
): T {
|
|
50
|
-
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
77
|
+
const Component = forwardRef<Element, any>(({ asChild, ...props }, ref) => {
|
|
78
|
+
const child = asChild ? getSlotChild(props.children, displayName) : null
|
|
79
|
+
if (!child) return render(props, ref)
|
|
80
|
+
|
|
81
|
+
devWarning(
|
|
82
|
+
props.component !== undefined,
|
|
83
|
+
`${displayName}: both \`asChild\` and \`component\` were passed; \`asChild\` wins and ` +
|
|
84
|
+
`\`component\` is ignored.`
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
return createElement(
|
|
88
|
+
SlotProvider,
|
|
89
|
+
{ value: child },
|
|
90
|
+
render(
|
|
91
|
+
{ ...props, component: Slot, children: (child.props as PropsWithChildren).children },
|
|
92
|
+
ref
|
|
93
|
+
)
|
|
94
|
+
)
|
|
95
|
+
}) as unknown as T & { displayName?: string }
|
|
51
96
|
Component.displayName = displayName
|
|
52
97
|
return Component
|
|
53
98
|
}
|
|
99
|
+
|
|
100
|
+
type PropsWithChildren = { children?: unknown }
|