@crewlethq/ui 0.2.0 → 0.3.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/README.md +1714 -14
- package/dist/Accordion/Accordion.d.ts +54 -0
- package/dist/Accordion/index.d.ts +4 -0
- package/dist/Accordion/index.js +6 -0
- package/dist/Accordion-ZI2WLD5C.css +87 -0
- package/dist/AddPill/AddPill.d.ts +114 -0
- package/dist/AddPill/index.d.ts +3 -0
- package/dist/AddPill/index.js +3 -0
- package/dist/AddPill-DFWXYLIQ.css +434 -0
- package/dist/Announcer/Announcer.d.ts +15 -0
- package/dist/Announcer/index.d.ts +2 -0
- package/dist/Announcer/index.js +3 -0
- package/dist/AppShell/AppShell.d.ts +193 -0
- package/dist/AppShell/index.d.ts +3 -0
- package/dist/AppShell/index.js +6 -0
- package/dist/AppShell-NVE6LHNI.css +395 -0
- package/dist/Avatar/Avatar.d.ts +104 -0
- package/dist/Avatar/index.d.ts +3 -0
- package/dist/Avatar/index.js +2 -0
- package/dist/Avatar-P2KRQM2B.css +156 -0
- package/dist/BrandLockup/BrandLockup.d.ts +41 -0
- package/dist/BrandLockup/index.d.ts +3 -0
- package/dist/BrandLockup/index.js +2 -0
- package/dist/BrandLockup-6ISDEHPJ.css +108 -0
- package/dist/Button/Button.d.ts +88 -0
- package/dist/Button/index.d.ts +3 -0
- package/dist/Button/index.js +3 -0
- package/dist/Button-D4J6B4MA.css +302 -0
- package/dist/CalendarGrid/CalendarGrid.d.ts +87 -0
- package/dist/CalendarGrid/index.d.ts +3 -0
- package/dist/CalendarGrid/index.js +2 -0
- package/dist/CalendarGrid-V6TQ5QKS.css +128 -0
- package/dist/Callout/Callout.d.ts +47 -0
- package/dist/Callout/index.d.ts +3 -0
- package/dist/Callout/index.js +2 -0
- package/dist/Callout-S7QDWHDL.css +111 -0
- package/dist/Canvas/Canvas.d.ts +234 -0
- package/dist/Canvas/geometry.d.ts +249 -0
- package/dist/Canvas/index.d.ts +5 -0
- package/dist/Canvas/index.js +8 -0
- package/dist/Canvas/layerNode.d.ts +20 -0
- package/dist/Canvas-Q6JETCWR.css +315 -0
- package/dist/Card/Card.d.ts +142 -0
- package/dist/Card/headerSlot.d.ts +65 -0
- package/dist/Card/index.d.ts +5 -0
- package/dist/Card/index.js +6 -0
- package/dist/Card-AHX3Q2JD.css +428 -0
- package/dist/Charts/ActivityStrip.d.ts +45 -0
- package/dist/Charts/BarList.d.ts +51 -0
- package/dist/Charts/Legend.d.ts +32 -0
- package/dist/Charts/StackedBar.d.ts +38 -0
- package/dist/Charts/TimeSeries.d.ts +92 -0
- package/dist/Charts/dataColor.d.ts +20 -0
- package/dist/Charts/index.d.ts +12 -0
- package/dist/Charts/index.js +3 -0
- package/dist/Charts-D7G2BSXH.css +277 -0
- package/dist/Checkbox/Checkbox.d.ts +45 -0
- package/dist/Checkbox/index.d.ts +3 -0
- package/dist/Checkbox/index.js +2 -0
- package/dist/Checkbox-VGW26YLQ.css +111 -0
- package/dist/CodeBlock/CodeBlock.d.ts +60 -0
- package/dist/CodeBlock/index.d.ts +3 -0
- package/dist/CodeBlock/index.js +7 -0
- package/dist/CodeBlock-U2W6NNVC.css +153 -0
- package/dist/Combobox/Combobox.d.ts +89 -0
- package/dist/Combobox/index.d.ts +3 -0
- package/dist/Combobox/index.js +8 -0
- package/dist/Combobox-4FUVYIE7.css +80 -0
- package/dist/CommandPalette/CommandPalette.d.ts +77 -0
- package/dist/CommandPalette/index.d.ts +3 -0
- package/dist/CommandPalette/index.js +11 -0
- package/dist/CommandPalette-CSJDUCQA.css +115 -0
- package/dist/Container/Container.d.ts +17 -0
- package/dist/Container/index.d.ts +3 -0
- package/dist/Container/index.js +2 -0
- package/dist/Container-3TSKMGNI.css +52 -0
- package/dist/Copyable/CopyButton.d.ts +54 -0
- package/dist/Copyable/Copyable.d.ts +34 -0
- package/dist/Copyable/index.d.ts +5 -0
- package/dist/Copyable/index.js +6 -0
- package/dist/Copyable-5PNRFOLS.css +125 -0
- package/dist/Count/Count.d.ts +24 -0
- package/dist/Count/index.d.ts +3 -0
- package/dist/Count/index.js +3 -0
- package/dist/Count-ZVCJ6VPD.css +20 -0
- package/dist/DataTable/CopyableCell.d.ts +12 -0
- package/dist/DataTable/DataTable.d.ts +615 -0
- package/dist/DataTable/RowActionsMenu.d.ts +7 -0
- package/dist/DataTable/index.d.ts +7 -0
- package/dist/DataTable/index.js +14 -0
- package/dist/DataTable-ITNACQ2X.css +2020 -0
- package/dist/DataView/DataView.d.ts +109 -0
- package/dist/DataView/DataViewToolbar.d.ts +87 -0
- package/dist/DataView/FilterAxisBar.d.ts +103 -0
- package/dist/DataView/columns.d.ts +35 -0
- package/dist/DataView/filters.d.ts +184 -0
- package/dist/DataView/index.d.ts +11 -0
- package/dist/DataView/index.js +25 -0
- package/dist/DataView-256YF32J.css +441 -0
- package/dist/DateTimePicker/DateTimePicker.d.ts +91 -0
- package/dist/DateTimePicker/index.d.ts +3 -0
- package/dist/DateTimePicker/index.js +9 -0
- package/dist/DateTimePicker-22VNXRWC.css +199 -0
- package/dist/DescriptionList/DescriptionList.d.ts +36 -0
- package/dist/DescriptionList/index.d.ts +3 -0
- package/dist/DescriptionList/index.js +2 -0
- package/dist/DescriptionList-YYY3V3O6.css +59 -0
- package/dist/DiffList/DiffList.d.ts +47 -0
- package/dist/DiffList/index.d.ts +3 -0
- package/dist/DiffList/index.js +3 -0
- package/dist/DiffList-3EX64AAE.css +94 -0
- package/dist/Disclosure/Disclosure.d.ts +56 -0
- package/dist/Disclosure/anatomy.d.ts +43 -0
- package/dist/Disclosure/index.d.ts +5 -0
- package/dist/Disclosure/index.js +6 -0
- package/dist/Disclosure-VKBJJIZ7.css +176 -0
- package/dist/EmptyState/EmptyState.d.ts +39 -0
- package/dist/EmptyState/index.d.ts +3 -0
- package/dist/EmptyState/index.js +3 -0
- package/dist/EmptyState-C6HRBGT7.css +73 -0
- package/dist/EmptyValue/EmptyValue.d.ts +31 -0
- package/dist/EmptyValue/index.d.ts +3 -0
- package/dist/EmptyValue/index.js +3 -0
- package/dist/EmptyValue-4B6ODXHT.css +12 -0
- package/dist/EntityChip/EntityChip.d.ts +40 -0
- package/dist/EntityChip/index.d.ts +3 -0
- package/dist/EntityChip/index.js +3 -0
- package/dist/EntityChip-LUCPZBBG.css +64 -0
- package/dist/ErrorBoundary/ErrorBoundary.d.ts +58 -0
- package/dist/ErrorBoundary/index.d.ts +3 -0
- package/dist/ErrorBoundary/index.js +4 -0
- package/dist/ErrorBoundary-ME36CQTA.css +59 -0
- package/dist/Eyebrow/Eyebrow.d.ts +18 -0
- package/dist/Eyebrow/index.d.ts +3 -0
- package/dist/Eyebrow/index.js +2 -0
- package/dist/Eyebrow-5NREGHQH.css +46 -0
- package/dist/FilterChip/FilterChip.d.ts +68 -0
- package/dist/FilterChip/index.d.ts +3 -0
- package/dist/FilterChip/index.js +3 -0
- package/dist/FilterChip-GTGLLOXE.css +107 -0
- package/dist/Fullscreen/index.d.ts +2 -0
- package/dist/Fullscreen/index.js +1 -0
- package/dist/Fullscreen/useFullscreen.d.ts +32 -0
- package/dist/IconButton/IconButton.d.ts +45 -0
- package/dist/IconButton/index.d.ts +3 -0
- package/dist/IconButton/index.js +3 -0
- package/dist/IconButton-VQGNMJDI.css +158 -0
- package/dist/ImageUpload/ImageUpload.d.ts +37 -0
- package/dist/ImageUpload/index.d.ts +3 -0
- package/dist/ImageUpload/index.js +3 -0
- package/dist/ImageUpload-HKFIZR6D.css +193 -0
- package/dist/InlineCode/InlineCode.d.ts +37 -0
- package/dist/InlineCode/index.d.ts +3 -0
- package/dist/InlineCode/index.js +2 -0
- package/dist/InlineCode-6WSR5COL.css +65 -0
- package/dist/Input/FormField.d.ts +61 -0
- package/dist/Input/FormRow.d.ts +6 -0
- package/dist/Input/FormSection.d.ts +28 -0
- package/dist/Input/Input.d.ts +98 -0
- package/dist/Input/Label.d.ts +31 -0
- package/dist/Input/ReadOnlyField.d.ts +30 -0
- package/dist/Input/Textarea.d.ts +16 -0
- package/dist/Input/index.d.ts +15 -0
- package/dist/Input/index.js +5 -0
- package/dist/Input-2PU5CPKK.css +616 -0
- package/dist/Kbd/Kbd.d.ts +40 -0
- package/dist/Kbd/index.d.ts +3 -0
- package/dist/Kbd/index.js +3 -0
- package/dist/Kbd-W66MXQI5.css +61 -0
- package/dist/Layer/LayerHost.d.ts +23 -0
- package/dist/Layer/index.d.ts +7 -0
- package/dist/Layer/index.js +3 -0
- package/dist/Layer/place.d.ts +63 -0
- package/dist/Layer/stack.d.ts +159 -0
- package/dist/Layer-NAFSGCFA.css +23 -0
- package/dist/Layout/Layout.d.ts +104 -0
- package/dist/Layout/index.d.ts +3 -0
- package/dist/Layout/index.js +2 -0
- package/dist/Layout-2ZCV3IGF.css +171 -0
- package/dist/Link/Link.d.ts +45 -0
- package/dist/Link/index.d.ts +3 -0
- package/dist/Link/index.js +3 -0
- package/dist/Link-6BEFNMN2.css +80 -0
- package/dist/List/List.d.ts +73 -0
- package/dist/List/index.d.ts +3 -0
- package/dist/List/index.js +3 -0
- package/dist/List-XTHESXLR.css +161 -0
- package/dist/ListInput/ListInput.d.ts +68 -0
- package/dist/ListInput/index.d.ts +3 -0
- package/dist/ListInput/index.js +10 -0
- package/dist/ListInput-O7LJKOIG.css +147 -0
- package/dist/Listbox/index.d.ts +5 -0
- package/dist/Listbox/index.js +2 -0
- package/dist/Listbox/useListbox.d.ts +97 -0
- package/dist/Listbox/useOptionKeys.d.ts +64 -0
- package/dist/Listbox-X2DOTSQA.css +110 -0
- package/dist/Menu/Menu.d.ts +118 -0
- package/dist/Menu/index.d.ts +3 -0
- package/dist/Menu/index.js +7 -0
- package/dist/Menu-6DE7I66I.css +222 -0
- package/dist/Meter/Meter.d.ts +49 -0
- package/dist/Meter/index.d.ts +3 -0
- package/dist/Meter/index.js +3 -0
- package/dist/Meter-SKOOXQBC.css +87 -0
- package/dist/Modal/ConfirmModal.d.ts +74 -0
- package/dist/Modal/Modal.d.ts +154 -0
- package/dist/Modal/index.d.ts +5 -0
- package/dist/Modal/index.js +8 -0
- package/dist/Modal-XYQJ4BL6.css +484 -0
- package/dist/NewItemsNotice/NewItemsNotice.d.ts +28 -0
- package/dist/NewItemsNotice/index.d.ts +3 -0
- package/dist/NewItemsNotice/index.js +4 -0
- package/dist/NewItemsNotice-T4DSSPVV.css +60 -0
- package/dist/OrgLabel/OrgLabel.d.ts +117 -0
- package/dist/OrgLabel/index.d.ts +3 -0
- package/dist/OrgLabel/index.js +2 -0
- package/dist/OrgLabel-D7U6QJZD.css +293 -0
- package/dist/OrgNode/OrgNode.d.ts +103 -0
- package/dist/OrgNode/index.d.ts +3 -0
- package/dist/OrgNode/index.js +3 -0
- package/dist/OrgNode-BT7T2Q2X.css +214 -0
- package/dist/OrgTable/OrgTable.d.ts +113 -0
- package/dist/OrgTable/index.d.ts +3 -0
- package/dist/OrgTable/index.js +11 -0
- package/dist/OrgTable-VWMFC3TB.css +360 -0
- package/dist/PageHeader/PageHeader.d.ts +35 -0
- package/dist/PageHeader/index.d.ts +3 -0
- package/dist/PageHeader/index.js +3 -0
- package/dist/PageHeader-6EYWQXRE.css +88 -0
- package/dist/Popover/Popover.d.ts +91 -0
- package/dist/Popover/index.d.ts +3 -0
- package/dist/Popover/index.js +4 -0
- package/dist/Popover-WJGCF3ZQ.css +185 -0
- package/dist/PricingCard/PricingCard.d.ts +56 -0
- package/dist/PricingCard/index.d.ts +3 -0
- package/dist/PricingCard/index.js +4 -0
- package/dist/PricingCard-JFI7RYXP.css +278 -0
- package/dist/Prose/Prose.d.ts +33 -0
- package/dist/Prose/index.d.ts +3 -0
- package/dist/Prose/index.js +2 -0
- package/dist/Prose-BTXNFT2Q.css +99 -0
- package/dist/RelativeTime/RelativeTime.d.ts +31 -0
- package/dist/RelativeTime/clock.d.ts +9 -0
- package/dist/RelativeTime/format.d.ts +38 -0
- package/dist/RelativeTime/index.d.ts +6 -0
- package/dist/RelativeTime/index.js +4 -0
- package/dist/RelativeTime-EBAQPGO2.css +10 -0
- package/dist/SearchTrigger/SearchTrigger.d.ts +29 -0
- package/dist/SearchTrigger/index.d.ts +3 -0
- package/dist/SearchTrigger/index.js +2 -0
- package/dist/SearchTrigger-QXOYAUUY.css +79 -0
- package/dist/Section/Section.d.ts +41 -0
- package/dist/Section/index.d.ts +3 -0
- package/dist/Section/index.js +3 -0
- package/dist/Section-QRUPRIQ2.css +127 -0
- package/dist/SegmentedControl/SegmentedControl.d.ts +68 -0
- package/dist/SegmentedControl/index.d.ts +4 -0
- package/dist/SegmentedControl/index.js +5 -0
- package/dist/SegmentedControl-X3BI3XU4.css +68 -0
- package/dist/Select/Select.d.ts +138 -0
- package/dist/Select/index.d.ts +3 -0
- package/dist/Select/index.js +5 -0
- package/dist/Select-2X77FSWR.css +350 -0
- package/dist/Shortcut/index.d.ts +2 -0
- package/dist/Shortcut/index.js +4 -0
- package/dist/Shortcut/useShortcut.d.ts +68 -0
- package/dist/SidebarNav/SidebarNav.d.ts +117 -0
- package/dist/SidebarNav/index.d.ts +3 -0
- package/dist/SidebarNav/index.js +3 -0
- package/dist/SidebarNav-QGSFKZYA.css +319 -0
- package/dist/Skeleton/Skeleton.d.ts +50 -0
- package/dist/Skeleton/index.d.ts +3 -0
- package/dist/Skeleton/index.js +3 -0
- package/dist/Skeleton-V735HRGM.css +421 -0
- package/dist/StatCard/StatCard.d.ts +56 -0
- package/dist/StatCard/index.d.ts +3 -0
- package/dist/StatCard/index.js +3 -0
- package/dist/StatCard-KYPKZUWX.css +111 -0
- package/dist/StatGroup/StatGroup.d.ts +20 -0
- package/dist/StatGroup/index.d.ts +3 -0
- package/dist/StatGroup/index.js +2 -0
- package/dist/StatGroup-TGB6AEKM.css +80 -0
- package/dist/StatusDot/StatusDot.d.ts +25 -0
- package/dist/StatusDot/index.d.ts +3 -0
- package/dist/StatusDot/index.js +2 -0
- package/dist/StatusDot-HA2L2FSX.css +84 -0
- package/dist/Switch/Switch.d.ts +38 -0
- package/dist/Switch/index.d.ts +3 -0
- package/dist/Switch/index.js +2 -0
- package/dist/Switch-U4OWK4CL.css +169 -0
- package/dist/Table/Table.d.ts +51 -0
- package/dist/Table/index.d.ts +3 -0
- package/dist/Table/index.js +3 -0
- package/dist/Table-MDOLVUAW.css +159 -0
- package/dist/Tabs/Tabs.d.ts +97 -0
- package/dist/Tabs/index.d.ts +3 -0
- package/dist/Tabs/index.js +4 -0
- package/dist/Tabs/roving.d.ts +36 -0
- package/dist/Tabs-VLICJFVB.css +275 -0
- package/dist/Tag/Tag.d.ts +107 -0
- package/dist/Tag/index.d.ts +3 -0
- package/dist/Tag/index.js +3 -0
- package/dist/Tag-VNZEYLB6.css +406 -0
- package/dist/TagGroup/TagGroup.d.ts +41 -0
- package/dist/TagGroup/index.d.ts +3 -0
- package/dist/TagGroup/index.js +4 -0
- package/dist/TagGroup-APC2EFH4.css +75 -0
- package/dist/TagsInput/TagsInput.d.ts +112 -0
- package/dist/TagsInput/index.d.ts +3 -0
- package/dist/TagsInput/index.js +10 -0
- package/dist/TagsInput-W4P36PRJ.css +168 -0
- package/dist/Text/Text.d.ts +67 -0
- package/dist/Text/index.d.ts +3 -0
- package/dist/Text/index.js +2 -0
- package/dist/Text-XIPYYZX2.css +154 -0
- package/dist/ThemeSwitcher/ThemeSwitcher.d.ts +47 -0
- package/dist/ThemeSwitcher/index.d.ts +4 -0
- package/dist/ThemeSwitcher/index.js +6 -0
- package/dist/ThemeSwitcher/preferences.d.ts +51 -0
- package/dist/TimeWindowPicker/TimeWindowPicker.d.ts +231 -0
- package/dist/TimeWindowPicker/index.d.ts +3 -0
- package/dist/TimeWindowPicker/index.js +13 -0
- package/dist/TimeWindowPicker/mask.d.ts +82 -0
- package/dist/TimeWindowPicker-7I7KWCMU.css +403 -0
- package/dist/Timeline/Timeline.d.ts +51 -0
- package/dist/Timeline/index.d.ts +3 -0
- package/dist/Timeline/index.js +3 -0
- package/dist/Timeline-27SYKOFX.css +144 -0
- package/dist/Toaster/Toaster.d.ts +108 -0
- package/dist/Toaster/index.d.ts +3 -0
- package/dist/Toaster/index.js +5 -0
- package/dist/Toaster-NVDCEIP5.css +306 -0
- package/dist/Toolbar/Toolbar.d.ts +62 -0
- package/dist/Toolbar/index.d.ts +3 -0
- package/dist/Toolbar/index.js +4 -0
- package/dist/Toolbar-IP6LXN45.css +48 -0
- package/dist/Tooltip/Tooltip.d.ts +51 -0
- package/dist/Tooltip/index.d.ts +3 -0
- package/dist/Tooltip/index.js +4 -0
- package/dist/Tooltip-LKQF7CE4.css +71 -0
- package/dist/Tree/index.d.ts +8 -0
- package/dist/Tree/index.js +1 -0
- package/dist/Tree/layout.d.ts +160 -0
- package/dist/Tree/model.d.ts +110 -0
- package/dist/Tree/useMeasuredSizes.d.ts +61 -0
- package/dist/Tree/useTreeState.d.ts +89 -0
- package/dist/TreeCanvas/TreeCanvas.d.ts +384 -0
- package/dist/TreeCanvas/index.d.ts +3 -0
- package/dist/TreeCanvas/index.js +10 -0
- package/dist/TreeCanvas/motion.d.ts +59 -0
- package/dist/TreeCanvas-WBNQPHC7.css +1098 -0
- package/dist/TreeGrid/TreeGrid.d.ts +142 -0
- package/dist/TreeGrid/index.d.ts +3 -0
- package/dist/TreeGrid/index.js +8 -0
- package/dist/TreeGrid-NSW7VMOX.css +132 -0
- package/dist/VisuallyHidden/VisuallyHidden.d.ts +23 -0
- package/dist/VisuallyHidden/index.d.ts +3 -0
- package/dist/VisuallyHidden/index.js +2 -0
- package/dist/VisuallyHidden-L552H7OA.css +21 -0
- package/dist/chunk-22O7LAW2.js +41 -0
- package/dist/chunk-23DHIMJA.js +38 -0
- package/dist/chunk-2EOKFKHX.js +263 -0
- package/dist/chunk-2PRH365R.js +74 -0
- package/dist/chunk-2ZQMA2WB.js +57 -0
- package/dist/chunk-3CZ7XAVY.js +139 -0
- package/dist/chunk-3EYF6HKB.js +135 -0
- package/dist/chunk-3ZP55QZE.js +40 -0
- package/dist/chunk-53DVJCVW.js +14 -0
- package/dist/chunk-5C5YMZQU.js +51 -0
- package/dist/chunk-5EKIWVOR.js +132 -0
- package/dist/chunk-5IMACPJS.js +495 -0
- package/dist/chunk-5KPQ6D7N.js +54 -0
- package/dist/chunk-5SDBMKUO.js +297 -0
- package/dist/chunk-5WS6L6FA.js +114 -0
- package/dist/chunk-7EM5T4ME.js +39 -0
- package/dist/chunk-7FZ53WDJ.js +163 -0
- package/dist/chunk-7HPRF5XN.js +525 -0
- package/dist/chunk-7RPGY3JE.js +43 -0
- package/dist/chunk-A2UXBCLO.js +48 -0
- package/dist/chunk-ARMRX2YV.js +96 -0
- package/dist/chunk-AV2DXAEL.js +27 -0
- package/dist/chunk-BHHIIK3M.js +17 -0
- package/dist/chunk-BZFWDIV6.js +9 -0
- package/dist/chunk-BZYDZBAN.js +123 -0
- package/dist/chunk-CMEE37QJ.js +628 -0
- package/dist/chunk-D3OADIM6.js +112 -0
- package/dist/chunk-DD5BBGBE.js +162 -0
- package/dist/chunk-EHMQQHYR.js +1652 -0
- package/dist/chunk-EN6K2IFA.js +256 -0
- package/dist/chunk-EPOOQZYA.js +118 -0
- package/dist/chunk-ESCO4XYW.js +144 -0
- package/dist/chunk-EUCC37WY.js +14 -0
- package/dist/chunk-EV6IMYJ6.js +62 -0
- package/dist/chunk-F27EPQ7D.js +68 -0
- package/dist/chunk-F4PJZ4ED.js +245 -0
- package/dist/chunk-F6OE5FH3.js +49 -0
- package/dist/chunk-FBZAKNSX.js +263 -0
- package/dist/chunk-FEFTGVMF.js +46 -0
- package/dist/chunk-G2QFRTJ2.js +823 -0
- package/dist/chunk-GHYY2WPF.js +907 -0
- package/dist/chunk-GTOUGQQK.js +147 -0
- package/dist/chunk-GUIF6Q6N.js +143 -0
- package/dist/chunk-GXQ3B46I.js +216 -0
- package/dist/chunk-H4FBTAYS.js +130 -0
- package/dist/chunk-HOXGBLEY.js +37 -0
- package/dist/chunk-HQNHV7D6.js +54 -0
- package/dist/chunk-HTDFCRJZ.js +92 -0
- package/dist/chunk-HZ5XZNPS.js +98 -0
- package/dist/chunk-IAJLHVUA.js +28 -0
- package/dist/chunk-IJ7QXNIJ.js +1 -0
- package/dist/chunk-ITHXJHBB.js +280 -0
- package/dist/chunk-JCSA3XVH.js +32 -0
- package/dist/chunk-KLJCCMF3.js +97 -0
- package/dist/chunk-LGCPQIOZ.js +49 -0
- package/dist/chunk-LWKJQTOM.js +77 -0
- package/dist/chunk-MNAXYY3R.js +215 -0
- package/dist/chunk-NN62JQLR.js +29 -0
- package/dist/chunk-NPZY6YYL.js +251 -0
- package/dist/chunk-NTRZGNEX.js +529 -0
- package/dist/chunk-O6232G37.js +273 -0
- package/dist/chunk-O67VF5MS.js +58 -0
- package/dist/chunk-ODEQTPFM.js +6 -0
- package/dist/chunk-PNFASD6F.js +98 -0
- package/dist/chunk-PQADV6P6.js +19 -0
- package/dist/chunk-PZSWF74H.js +15 -0
- package/dist/chunk-Q4ZPPART.js +26 -0
- package/dist/chunk-QNCVHRZL.js +17 -0
- package/dist/chunk-QVE4GJAT.js +15 -0
- package/dist/chunk-QYOFACSP.js +36 -0
- package/dist/chunk-RA2ULG6H.js +29 -0
- package/dist/chunk-RDGD7Z7I.js +350 -0
- package/dist/chunk-RK4XPHVG.js +16 -0
- package/dist/chunk-RSAQOKH3.js +38 -0
- package/dist/chunk-S2XHHEW4.js +84 -0
- package/dist/chunk-S4GZWSKR.js +137 -0
- package/dist/chunk-SFZOKW2G.js +52 -0
- package/dist/chunk-T7FKOJKW.js +221 -0
- package/dist/chunk-UG46QBLT.js +325 -0
- package/dist/chunk-UOGSZKLT.js +134 -0
- package/dist/chunk-V2XMNLMS.js +52 -0
- package/dist/chunk-V663QU4R.js +51 -0
- package/dist/chunk-W4ENKCXJ.js +40 -0
- package/dist/chunk-W5J7R5EB.js +107 -0
- package/dist/chunk-WNI2WSJF.js +27 -0
- package/dist/chunk-XDTYBF2F.js +36 -0
- package/dist/chunk-XN4JBAN3.js +32 -0
- package/dist/chunk-XV6WRMBC.js +211 -0
- package/dist/chunk-YLYOWZ4V.js +33 -0
- package/dist/chunk-YMWONFSI.js +170 -0
- package/dist/chunk-ZCR6YGQ4.js +1 -0
- package/dist/generated/index.d.ts +83 -0
- package/dist/generated/index.js +91 -0
- package/dist/index.d.ts +1 -1217
- package/dist/index.js +91 -4518
- package/dist/styles.css +14841 -4274
- package/dist/utils/cx.d.ts +10 -0
- package/dist/utils/headingLevel.d.ts +16 -0
- package/dist/utils/index.d.ts +6 -0
- package/dist/utils/index.js +4 -0
- package/dist/utils/tone.d.ts +25 -0
- package/dist/utils/useClipboard.d.ts +30 -0
- package/package.json +18 -10
- package/scripts/bundle-css.mjs +25 -0
- package/scripts/check-css-literals.mjs +166 -0
- package/scripts/check-css-variables.mjs +184 -0
- package/scripts/check-css.mjs +27 -0
- package/scripts/css-source.mjs +67 -0
- package/scripts/write-barrel.mjs +60 -0
- package/dist/Accordion-NIMJQIOI.css +0 -88
- package/dist/AppShell-ZW3NSFBP.css +0 -51
- package/dist/Avatar-V6NG6Q45.css +0 -67
- package/dist/Button-XGCTXXYP.css +0 -174
- package/dist/Callout-LEGDIMAM.css +0 -52
- package/dist/Card-BOZGBML7.css +0 -86
- package/dist/Checkbox-OCUICIIZ.css +0 -58
- package/dist/CodeBlock-IEMBNIQC.css +0 -90
- package/dist/Container-LTKBA2FW.css +0 -21
- package/dist/Copyable-IB57OTHZ.css +0 -123
- package/dist/DataTable-3GALZUW2.css +0 -1593
- package/dist/DateTimePicker-NMSSGVPK.css +0 -312
- package/dist/Eyebrow-AVBORAS2.css +0 -30
- package/dist/IconButton-GB4PJDG2.css +0 -82
- package/dist/ImageUpload-3HQDF2KC.css +0 -158
- package/dist/Input-ZHUTN7CU.css +0 -210
- package/dist/Kbd-Q77CDZY7.css +0 -23
- package/dist/Modal-FJVG66S4.css +0 -138
- package/dist/Popover-FUFULUE2.css +0 -123
- package/dist/PricingCard-NKYV3JHA.css +0 -238
- package/dist/Section-665ZIPG6.css +0 -20
- package/dist/Select-GPRF7PRB.css +0 -294
- package/dist/Skeleton-3WEFLRDN.css +0 -378
- package/dist/StatCard-RTJIVTRB.css +0 -50
- package/dist/Table-AR3TRY2E.css +0 -89
- package/dist/Tabs-XZ4JIH3E.css +0 -153
- package/dist/Tag-R5QDJLYJ.css +0 -163
- package/dist/TimeWindowPicker-L3G5Q7UT.css +0 -629
- package/dist/Toaster-2O65VOR4.css +0 -264
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type ButtonHTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* How a row of chips behaves: several on at once, or exactly one.
|
|
4
|
+
*
|
|
5
|
+
* The two are different CONTROLS, not two looks. A toggle group is a set of
|
|
6
|
+
* independent switches, each a button with a pressed state that Tab reaches;
|
|
7
|
+
* a radio group is one choice, where the arrows move inside it and Tab steps
|
|
8
|
+
* past the whole thing. A screen reader is told which of the two it is looking
|
|
9
|
+
* at, so this is a prop rather than a styling flag.
|
|
10
|
+
*/
|
|
11
|
+
export type FilterChipSemantics = 'toggle' | 'radio';
|
|
12
|
+
/** The attribute the group finds its own chips by, without a registry to keep. */
|
|
13
|
+
export declare const FILTER_CHIP_ATTRIBUTE = "data-crewlet-filter-chip";
|
|
14
|
+
export interface FilterChipProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'type' | 'value' | 'onChange'> {
|
|
15
|
+
/** Whether this filter is on. Inside a radio group it comes from the group. */
|
|
16
|
+
pressed?: boolean | undefined;
|
|
17
|
+
/** Called with what the state would become. */
|
|
18
|
+
onPressedChange?: ((pressed: boolean) => void) | undefined;
|
|
19
|
+
/** How many rows this filter leaves. Drawn after the label, in the chip's ink. */
|
|
20
|
+
count?: number | string | undefined;
|
|
21
|
+
/** What this chip stands for inside a radio group. */
|
|
22
|
+
value?: string | undefined;
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A filter that is off, or on.
|
|
27
|
+
*
|
|
28
|
+
* NEUTRAL UNTIL IT IS ON, and then it takes the accent. The accent is the one
|
|
29
|
+
* colour that means "where the reader is", and the thing currently narrowing
|
|
30
|
+
* the list is exactly that: the reader's own position in the data. A row of
|
|
31
|
+
* chips accented at rest would spend the colour on controls none of which is
|
|
32
|
+
* doing anything.
|
|
33
|
+
*
|
|
34
|
+
* It is a real `<button type="button">`. The chip this replaces declared no
|
|
35
|
+
* type, so every one of them inside a form submitted it.
|
|
36
|
+
*/
|
|
37
|
+
export declare function FilterChip({ pressed, onPressedChange, count, value, className, onClick, children, ...rest }: FilterChipProps): import("react/jsx-runtime").JSX.Element;
|
|
38
|
+
export interface FilterChipGroupProps {
|
|
39
|
+
/**
|
|
40
|
+
* What the row filters, read before the chips themselves: "Event kind",
|
|
41
|
+
* "Seat". REQUIRED, because a row of chips with no name is a row of words a
|
|
42
|
+
* screen reader reads with nothing to hang them on.
|
|
43
|
+
*/
|
|
44
|
+
label: string;
|
|
45
|
+
semantics?: FilterChipSemantics | undefined;
|
|
46
|
+
/** The chosen value in radio mode. `null` is a deliberate none. */
|
|
47
|
+
value?: string | null | undefined;
|
|
48
|
+
onValueChange?: ((value: string | null) => void) | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Whether a second press on the chosen chip clears it. Off by default: a
|
|
51
|
+
* choice that can empty itself leaves a reader in a state with no answer,
|
|
52
|
+
* and most rows carry an explicit "All" chip instead.
|
|
53
|
+
*/
|
|
54
|
+
allowNone?: boolean | undefined;
|
|
55
|
+
/** Hide the label visually. It stays in the accessibility tree. */
|
|
56
|
+
hideLabel?: boolean | undefined;
|
|
57
|
+
className?: string | undefined;
|
|
58
|
+
children?: ReactNode;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A named row of filters.
|
|
62
|
+
*
|
|
63
|
+
* In radio mode the arrows move AND choose, which is what the platform's own
|
|
64
|
+
* radio group does: a reader arrowing through a set of choices is choosing,
|
|
65
|
+
* and a group where focus and selection come apart makes them press Space
|
|
66
|
+
* after every move for a reason they could not name.
|
|
67
|
+
*/
|
|
68
|
+
export declare function FilterChipGroup({ label, semantics, value, onValueChange, allowNone, hideLabel, className, children, }: FilterChipGroupProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The filter chip: neutral until it is on, and then the accent.
|
|
3
|
+
*
|
|
4
|
+
* WHY THE ACCENT HERE AND NOWHERE ELSE IN A ROW OF CONTROLS. The accent means
|
|
5
|
+
* "where the reader is". The filter currently narrowing a list is exactly
|
|
6
|
+
* that, so it is the one control in a toolbar entitled to the colour; a chip
|
|
7
|
+
* that carried it at rest would spend it on a row where nothing is happening.
|
|
8
|
+
*
|
|
9
|
+
* The pressed ground is the accent SOFT tint under the accent INK, the same
|
|
10
|
+
* measured pair a Tag uses, never the accent fill with a label on it: the fill
|
|
11
|
+
* step is measured as a mark at 3:1 and would put its own label under 4.5:1.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
.crewlet-filter-chip-group {
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
flex-wrap: wrap;
|
|
18
|
+
gap: var(--spacing-2);
|
|
19
|
+
min-width: 0;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* The micro register: the same label step a Text `label` and a stat draw. */
|
|
23
|
+
.crewlet-filter-chip-group__label {
|
|
24
|
+
font-size: var(--font-size-2xs);
|
|
25
|
+
font-weight: var(--font-weight-medium);
|
|
26
|
+
letter-spacing: var(--font-letter-spacing-wide);
|
|
27
|
+
text-transform: uppercase;
|
|
28
|
+
color: var(--color-text-tertiary);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.crewlet-filter-chip {
|
|
32
|
+
display: inline-flex;
|
|
33
|
+
align-items: center;
|
|
34
|
+
gap: var(--spacing-1);
|
|
35
|
+
height: var(--size-control-sm);
|
|
36
|
+
/* The engine's own padding, and a full step tighter than 0.2.0 drew: a
|
|
37
|
+
Filter menu puts six of these in one row under a list, and the extra 4px
|
|
38
|
+
on each side was what pushed the sixth onto a second line. */
|
|
39
|
+
padding: 0 var(--spacing-2);
|
|
40
|
+
border: 1px solid var(--color-border-default);
|
|
41
|
+
border-radius: var(--radius-pill);
|
|
42
|
+
background: transparent;
|
|
43
|
+
/*
|
|
44
|
+
* The QUIET step at rest. A chip that is off is an option a reader has not
|
|
45
|
+
* taken and the row of them is scanned rather than read; the one that is on
|
|
46
|
+
* is the only thing in the row entitled to say so, and it says it in the
|
|
47
|
+
* accent.
|
|
48
|
+
*/
|
|
49
|
+
color: var(--color-text-tertiary);
|
|
50
|
+
font-family: var(--font-family-sans);
|
|
51
|
+
font-size: var(--font-size-xs);
|
|
52
|
+
/* Regular, which is what the engine's chip inherits from the document. The
|
|
53
|
+
row is a set of equal options and a medium weight on every one of them
|
|
54
|
+
made a toolbar of six read as six headings. */
|
|
55
|
+
font-weight: var(--font-weight-regular);
|
|
56
|
+
line-height: 1;
|
|
57
|
+
white-space: nowrap;
|
|
58
|
+
cursor: pointer;
|
|
59
|
+
box-sizing: border-box;
|
|
60
|
+
transition:
|
|
61
|
+
background var(--motion-duration-fast) var(--motion-easing-default),
|
|
62
|
+
border-color var(--motion-duration-fast) var(--motion-easing-default),
|
|
63
|
+
color var(--motion-duration-fast) var(--motion-easing-default);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.crewlet-filter-chip:hover {
|
|
67
|
+
border-color: var(--color-border-hover);
|
|
68
|
+
color: var(--color-text-primary);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.crewlet-filter-chip:focus-visible {
|
|
72
|
+
outline: 2px solid var(--color-focus);
|
|
73
|
+
outline-offset: 2px;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.crewlet-filter-chip:disabled {
|
|
77
|
+
opacity: 0.5;
|
|
78
|
+
cursor: not-allowed;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.crewlet-filter-chip[aria-pressed='true'],
|
|
82
|
+
.crewlet-filter-chip[aria-checked='true'] {
|
|
83
|
+
background: var(--color-brand-accent-soft);
|
|
84
|
+
border-color: var(--color-brand-accent-soft-strong);
|
|
85
|
+
color: var(--color-brand-accent-ink);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/*
|
|
89
|
+
* The count takes the chip's own ink, in both states.
|
|
90
|
+
*
|
|
91
|
+
* The engine draws it in the DECORATION step, which measures 2.25:1 at its
|
|
92
|
+
* worst and is the one step this package refuses to put a word on: a number
|
|
93
|
+
* that says how far a filter narrows a list is a fact a reader acts on, not a
|
|
94
|
+
* hairline. It was already one step quieter than the label here, and the label
|
|
95
|
+
* has since come down to meet it, so inheriting is what the engine's two-tone
|
|
96
|
+
* pill now looks like anyway, one measured step higher.
|
|
97
|
+
*/
|
|
98
|
+
.crewlet-filter-chip__count {
|
|
99
|
+
font-variant-numeric: tabular-nums;
|
|
100
|
+
color: inherit;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@media (prefers-reduced-motion: reduce) {
|
|
104
|
+
.crewlet-filter-chip {
|
|
105
|
+
transition: none;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { useFullscreen } from '../chunk-XDTYBF2F.js';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The browser's fullscreen, for one element.
|
|
3
|
+
*
|
|
4
|
+
* WHAT IT IS FOR. A canvas, a chart or a diagram is the one thing on a screen
|
|
5
|
+
* that genuinely wants the whole window, and it is drawn from ONE element's
|
|
6
|
+
* subtree: a fullscreen element renders only what is inside it, so the surface
|
|
7
|
+
* that goes fullscreen has to be the one holding its own toolbar, its dialogs
|
|
8
|
+
* and its overlays. That is also why an overlay portals into the nearest
|
|
9
|
+
* `LayerHost` rather than into the body (see the Layer module): portalled to
|
|
10
|
+
* the body it would be outside the fullscreen element and simply not painted.
|
|
11
|
+
*
|
|
12
|
+
* NOT DRAWN WHERE THE API IS MISSING. iPhone Safari offers no element
|
|
13
|
+
* fullscreen at all, and a control that is drawn and then fails is worse than
|
|
14
|
+
* one that was never there, so `supported` is what a caller renders on.
|
|
15
|
+
*
|
|
16
|
+
* `supported` ASKS THE DOCUMENT, NOT THE ELEMENT. The engine's version read
|
|
17
|
+
* the element's own `requestFullscreen` in an effect, which answers false for
|
|
18
|
+
* as long as the ref is empty: a control inside a panel that mounts later was
|
|
19
|
+
* never drawn at all, on browsers that support it perfectly well.
|
|
20
|
+
*/
|
|
21
|
+
import { type RefObject } from 'react';
|
|
22
|
+
export interface Fullscreen {
|
|
23
|
+
/** Whether this browser offers element fullscreen. A control that draws on it. */
|
|
24
|
+
supported: boolean;
|
|
25
|
+
/** Whether THIS element is the one the document is showing fullscreen. */
|
|
26
|
+
active: boolean;
|
|
27
|
+
enter: () => void;
|
|
28
|
+
exit: () => void;
|
|
29
|
+
toggle: () => void;
|
|
30
|
+
}
|
|
31
|
+
/** Drives fullscreen for `ref`, and reports whether it is the element showing. */
|
|
32
|
+
export declare function useFullscreen(ref: RefObject<HTMLElement | null>): Fullscreen;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type ButtonHTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
export type IconButtonSize = 'sm' | 'md' | 'lg';
|
|
3
|
+
export type IconButtonVariant =
|
|
4
|
+
/** The bordered square: a secondary Button with no room for a label. */
|
|
5
|
+
'secondary'
|
|
6
|
+
/** Transparent, neutral ink, a surface tint on hover. */
|
|
7
|
+
| 'ghost'
|
|
8
|
+
/** Transparent, the accent on hover. */
|
|
9
|
+
| 'ghost-brand'
|
|
10
|
+
/** Transparent, the critical hue on hover. */
|
|
11
|
+
| 'ghost-danger'
|
|
12
|
+
/** A soft accent square with a matching boundary: the add beside a label. */
|
|
13
|
+
| 'soft-brand';
|
|
14
|
+
export interface IconButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'aria-label'> {
|
|
15
|
+
/**
|
|
16
|
+
* What the button does, in words. REQUIRED, and not a convenience: an
|
|
17
|
+
* icon-only control has no text, so without this it is announced as
|
|
18
|
+
* "button" and a reader has to press it to find out what it was.
|
|
19
|
+
*/
|
|
20
|
+
label: string;
|
|
21
|
+
/** The glyph. A component from @crewlethq/icons/glyphs, not a name. */
|
|
22
|
+
icon?: ReactNode;
|
|
23
|
+
size?: IconButtonSize | undefined;
|
|
24
|
+
variant?: IconButtonVariant | undefined;
|
|
25
|
+
/** Sets `aria-pressed`: a toggle that is on. */
|
|
26
|
+
pressed?: boolean | undefined;
|
|
27
|
+
/** Unavailable, and why. See Button's own prop for why it is not `disabled`. */
|
|
28
|
+
disabledReason?: string | undefined;
|
|
29
|
+
/** Render the single child element with these classes instead of a button. */
|
|
30
|
+
asChild?: boolean | undefined;
|
|
31
|
+
children?: ReactNode;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* A square icon-only control: a row action, a copy, a drag handle, the close
|
|
35
|
+
* in a dialog's corner.
|
|
36
|
+
*
|
|
37
|
+
* ITS SMALLEST STEP IS 24px, not the 22 it was. A pointer target under 24px
|
|
38
|
+
* fails WCAG 2.2, and at compact density a 22px square was 18: this size, like
|
|
39
|
+
* every control step, is `--size-control-*`, which floors at 24 for that
|
|
40
|
+
* reason.
|
|
41
|
+
*
|
|
42
|
+
* Distinct from Button, which has a label slot and a text size. Anything with
|
|
43
|
+
* a word beside the glyph is a Button.
|
|
44
|
+
*/
|
|
45
|
+
export declare const IconButton: import("react").ForwardRefExoticComponent<IconButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* IconButton: a square icon-only control.
|
|
3
|
+
*
|
|
4
|
+
* Three square steps, each a --size-control-* token, so an icon button sits
|
|
5
|
+
* exactly as tall as the button, select or input beside it at every density,
|
|
6
|
+
* and the smallest cannot fall under the 24px a pointer target needs.
|
|
7
|
+
*
|
|
8
|
+
* THE CORNER IS THE BUTTON'S. An icon-only control is the square case of the
|
|
9
|
+
* same control, so it takes --radius-md: a toolbar of six-pixel squares
|
|
10
|
+
* beside an eight-pixel button reads as two families of control.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
.crewlet-icon-btn {
|
|
14
|
+
display: inline-flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
padding: 0;
|
|
18
|
+
background: transparent;
|
|
19
|
+
border: 1px solid transparent;
|
|
20
|
+
border-radius: var(--radius-md);
|
|
21
|
+
cursor: pointer;
|
|
22
|
+
line-height: 1;
|
|
23
|
+
flex-shrink: 0;
|
|
24
|
+
transition:
|
|
25
|
+
background var(--motion-duration-fast) var(--motion-easing-default),
|
|
26
|
+
border-color var(--motion-duration-fast) var(--motion-easing-default),
|
|
27
|
+
color var(--motion-duration-fast) var(--motion-easing-default);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/* An outline, never a shadow alone: forced-colors mode keeps one and drops
|
|
31
|
+
the other. */
|
|
32
|
+
.crewlet-icon-btn:focus-visible {
|
|
33
|
+
outline: 2px solid var(--color-focus);
|
|
34
|
+
outline-offset: 2px;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.crewlet-icon-btn:disabled,
|
|
38
|
+
.crewlet-icon-btn[aria-disabled='true'] {
|
|
39
|
+
opacity: 0.5;
|
|
40
|
+
cursor: not-allowed;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.crewlet-icon-btn:disabled {
|
|
44
|
+
pointer-events: none;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.crewlet-icon-btn--sm {
|
|
48
|
+
width: var(--size-control-sm);
|
|
49
|
+
height: var(--size-control-sm);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.crewlet-icon-btn--md {
|
|
53
|
+
width: var(--size-control-md);
|
|
54
|
+
height: var(--size-control-md);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.crewlet-icon-btn--lg {
|
|
58
|
+
width: var(--size-control-lg);
|
|
59
|
+
height: var(--size-control-lg);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/*
|
|
63
|
+
* The glyph inside follows the button's step, at the ratio a label sets: a
|
|
64
|
+
* medium button draws its leading glyph at its own 13px text, so a square one
|
|
65
|
+
* drawing a 16px glyph put a heavier mark in the same toolbar row.
|
|
66
|
+
*/
|
|
67
|
+
.crewlet-icon-btn--sm .crewlet-glyph {
|
|
68
|
+
width: var(--font-size-xs);
|
|
69
|
+
height: var(--font-size-xs);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.crewlet-icon-btn--md .crewlet-glyph {
|
|
73
|
+
width: var(--font-size-sm);
|
|
74
|
+
height: var(--font-size-sm);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.crewlet-icon-btn--lg .crewlet-glyph {
|
|
78
|
+
width: var(--font-size-xl);
|
|
79
|
+
height: var(--font-size-xl);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/*
|
|
83
|
+
* secondary: the bordered square. The same surface, boundary and states as a
|
|
84
|
+
* secondary Button, for an icon-only control that has to read as a control
|
|
85
|
+
* with nothing around it to say so: a step in a toolbar, a month's back and
|
|
86
|
+
* forward, an add beside a field. Without it a call site drew a Button with
|
|
87
|
+
* no label and squared it off with a stylesheet of its own.
|
|
88
|
+
*/
|
|
89
|
+
.crewlet-icon-btn--secondary {
|
|
90
|
+
background: var(--color-surface-subtle);
|
|
91
|
+
border-color: var(--color-border-default);
|
|
92
|
+
color: var(--color-text-primary);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.crewlet-icon-btn--secondary:hover:not(:disabled):not([aria-disabled='true']) {
|
|
96
|
+
background: var(--color-surface-elevated);
|
|
97
|
+
border-color: var(--color-border-hover);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.crewlet-icon-btn--secondary:active:not(:disabled):not([aria-disabled='true']) {
|
|
101
|
+
background: var(--color-surface-pressed);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* ghost: transparent, neutral ink, a mild tint on hover. */
|
|
105
|
+
.crewlet-icon-btn--ghost {
|
|
106
|
+
color: var(--color-text-secondary);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.crewlet-icon-btn--ghost:hover:not(:disabled):not([aria-disabled='true']) {
|
|
110
|
+
background: var(--color-surface-hover);
|
|
111
|
+
color: var(--color-text-primary);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* ghost-brand: transparent, the accent on hover. */
|
|
115
|
+
.crewlet-icon-btn--ghost-brand {
|
|
116
|
+
color: var(--color-text-tertiary);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.crewlet-icon-btn--ghost-brand:hover:not(:disabled):not([aria-disabled='true']) {
|
|
120
|
+
background: var(--color-brand-accent-soft);
|
|
121
|
+
border-color: var(--color-brand-accent-soft-strong);
|
|
122
|
+
color: var(--color-brand-accent-ink);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/* ghost-danger: transparent, the critical hue on hover, from the token rather
|
|
126
|
+
than the rose literal it used to carry. */
|
|
127
|
+
.crewlet-icon-btn--ghost-danger {
|
|
128
|
+
color: var(--color-text-tertiary);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.crewlet-icon-btn--ghost-danger:hover:not(:disabled):not([aria-disabled='true']) {
|
|
132
|
+
background: var(--color-feedback-danger-soft);
|
|
133
|
+
color: var(--color-feedback-danger-ink);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* soft-brand: a tinted square with a matching boundary. */
|
|
137
|
+
.crewlet-icon-btn--soft-brand {
|
|
138
|
+
background: var(--color-brand-accent-soft);
|
|
139
|
+
border-color: var(--color-brand-accent-soft-strong);
|
|
140
|
+
color: var(--color-brand-accent-ink);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.crewlet-icon-btn--soft-brand:hover:not(:disabled):not([aria-disabled='true']) {
|
|
144
|
+
background: var(--color-brand-accent-soft-strong);
|
|
145
|
+
border-color: var(--color-brand-accent);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/* A toggle that is on, drawn from the state a screen reader is already told. */
|
|
149
|
+
.crewlet-icon-btn[aria-pressed='true'] {
|
|
150
|
+
background: var(--color-brand-accent-soft);
|
|
151
|
+
color: var(--color-brand-accent-ink);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@media (prefers-reduced-motion: reduce) {
|
|
155
|
+
.crewlet-icon-btn {
|
|
156
|
+
transition: none;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type HTMLAttributes } from 'react';
|
|
2
|
+
import { type AvatarShape } from '../Avatar/index.js';
|
|
3
|
+
export interface ImageUploadProps extends Omit<HTMLAttributes<HTMLDivElement>, 'onSelect'> {
|
|
4
|
+
/** Current image source. When set, the control shows the image and the overlay label reads "Change". */
|
|
5
|
+
src?: string | undefined;
|
|
6
|
+
/** Display name used for the initials fallback when no image is set. */
|
|
7
|
+
name?: string | undefined;
|
|
8
|
+
/** Rendered width and height in pixels. */
|
|
9
|
+
size?: number | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Outline shape passed through to the preview and fallback. Defaults to
|
|
12
|
+
* "square", as Avatar does: what this control takes is normally a company
|
|
13
|
+
* logo, and a wide mark cropped into a circle loses its ends.
|
|
14
|
+
*/
|
|
15
|
+
shape?: AvatarShape | undefined;
|
|
16
|
+
/** When true, the control is display only: no overlay, no remove button, no file picker. */
|
|
17
|
+
readOnly?: boolean | undefined;
|
|
18
|
+
/** When true, the control shows a spinner and ignores interaction while an upload is in flight. */
|
|
19
|
+
uploading?: boolean | undefined;
|
|
20
|
+
/** Accepted file types for the hidden file input. Defaults to "image/*". */
|
|
21
|
+
accept?: string | undefined;
|
|
22
|
+
/** Called with the raw selected File. The upload happens over the network, so no client-side encoding is performed. */
|
|
23
|
+
onSelect: (file: File) => void;
|
|
24
|
+
/** Called when the remove button is pressed. The button only renders when an image is set and the control is editable. */
|
|
25
|
+
onRemove?: (() => void) | undefined;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* ImageUpload, a click-to-upload affordance built on top of Avatar. Shows the
|
|
29
|
+
* current image (or an initials fallback), an overlay with a camera icon and
|
|
30
|
+
* an "Upload" or "Change" label (shown on hover, or always while no image is
|
|
31
|
+
* set), a hidden file input, a remove button, and an uploading state. One
|
|
32
|
+
* primitive covers both square logos and round profile pictures.
|
|
33
|
+
*
|
|
34
|
+
* The selection callback hands back the raw File rather than a data URL because
|
|
35
|
+
* the upload now happens over the network.
|
|
36
|
+
*/
|
|
37
|
+
export declare const ImageUpload: ({ src, name, size, shape, readOnly, uploading, accept, onSelect, onRemove, className, style, ...rest }: ImageUploadProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* ImageUpload, the click-to-upload affordance built on Avatar.
|
|
3
|
+
*
|
|
4
|
+
* WHITE ON THE SCRIM, from tokens, in both palettes. The overlay used to spell
|
|
5
|
+
* its own rgba(0, 0, 0, 0.5) and three shades of white; the scrim and the
|
|
6
|
+
* on-accent step are the two values the palette already measures for exactly
|
|
7
|
+
* this, which is a label drawn on something dark whatever is behind it.
|
|
8
|
+
*
|
|
9
|
+
* NO LITERAL FALLBACKS INSIDE var(). A fallback is what renders whenever the
|
|
10
|
+
* token name is misspelt, so it hides the very failure it looks like
|
|
11
|
+
* insurance against, and the dark value it held rendered on a light page.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
.crewlet-image-upload {
|
|
15
|
+
/* The default box, which the component overrides per instance from its
|
|
16
|
+
`size` prop. Declared here rather than carried as a var() fallback at each
|
|
17
|
+
of the six places that read it: a fallback repeated six times is six
|
|
18
|
+
places for the default to drift apart. */
|
|
19
|
+
--crewlet-image-upload-size: 64px;
|
|
20
|
+
/* The corner that box takes, set per instance beside the size. Declared here
|
|
21
|
+
for the same reason the size is: a default repeated as a var() fallback at
|
|
22
|
+
each place that reads it is several places for one default to drift. */
|
|
23
|
+
--crewlet-image-upload-corner: var(--radius-lg);
|
|
24
|
+
position: relative;
|
|
25
|
+
display: inline-flex;
|
|
26
|
+
flex-shrink: 0;
|
|
27
|
+
width: var(--crewlet-image-upload-size);
|
|
28
|
+
height: var(--crewlet-image-upload-size);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.crewlet-image-upload__trigger {
|
|
32
|
+
position: relative;
|
|
33
|
+
display: inline-flex;
|
|
34
|
+
width: 100%;
|
|
35
|
+
height: 100%;
|
|
36
|
+
padding: 0;
|
|
37
|
+
margin: 0;
|
|
38
|
+
border: none;
|
|
39
|
+
background: transparent;
|
|
40
|
+
cursor: pointer;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/* Shape modifiers keep the trigger, the overlay and the Avatar corners in step. */
|
|
44
|
+
.crewlet-image-upload--circle .crewlet-image-upload__trigger,
|
|
45
|
+
.crewlet-image-upload--circle .crewlet-image-upload__overlay {
|
|
46
|
+
border-radius: var(--radius-circle);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/* THE SAME CORNER THE PICTURE INSIDE TAKES, which is why it is a variable
|
|
50
|
+
rather than a step: Avatar moves a square badge's radius with its box, so a
|
|
51
|
+
trigger pinned to one step is rounder or squarer than the badge under it at
|
|
52
|
+
every size but one, and the badge's corners show through the overlay. */
|
|
53
|
+
.crewlet-image-upload--square .crewlet-image-upload__trigger,
|
|
54
|
+
.crewlet-image-upload--square .crewlet-image-upload__overlay {
|
|
55
|
+
border-radius: var(--crewlet-image-upload-corner);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.crewlet-image-upload__trigger:disabled {
|
|
59
|
+
cursor: default;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.crewlet-image-upload.is-uploading .crewlet-image-upload__trigger {
|
|
63
|
+
cursor: progress;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.crewlet-image-upload__trigger:focus-visible {
|
|
67
|
+
outline: 2px solid var(--color-focus);
|
|
68
|
+
outline-offset: 2px;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.crewlet-image-upload__overlay {
|
|
72
|
+
position: absolute;
|
|
73
|
+
inset: 0;
|
|
74
|
+
display: flex;
|
|
75
|
+
flex-direction: column;
|
|
76
|
+
align-items: center;
|
|
77
|
+
justify-content: center;
|
|
78
|
+
gap: 2px;
|
|
79
|
+
background: var(--color-surface-scrim);
|
|
80
|
+
color: var(--color-text-on-accent);
|
|
81
|
+
opacity: 0;
|
|
82
|
+
transition: opacity var(--motion-duration-base) var(--motion-easing-default);
|
|
83
|
+
pointer-events: none;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/*
|
|
87
|
+
* With nothing uploaded yet the overlay IS the whole affordance, so it stays
|
|
88
|
+
* up rather than waiting for a hover: an initials tile on its own does not say
|
|
89
|
+
* "put your logo here".
|
|
90
|
+
*
|
|
91
|
+
* AT FULL STRENGTH, and that is a fix rather than a preference. `opacity`
|
|
92
|
+
* fades the element, so 0.85 fades the scrim AND the word on it together: the
|
|
93
|
+
* composite measured 3.47:1 on a light page, where the label on the full scrim
|
|
94
|
+
* measures 5.74:1. What the fade bought was a hover that still answered, and
|
|
95
|
+
* the hover has nothing left to answer with here, because the affordance is
|
|
96
|
+
* already up: the pointer and the focus ring carry it instead.
|
|
97
|
+
*/
|
|
98
|
+
.crewlet-image-upload.is-uploading .crewlet-image-upload__overlay,
|
|
99
|
+
.crewlet-image-upload.is-empty .crewlet-image-upload__overlay {
|
|
100
|
+
opacity: 1;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.crewlet-image-upload__trigger:hover .crewlet-image-upload__overlay,
|
|
104
|
+
.crewlet-image-upload__trigger:focus-visible .crewlet-image-upload__overlay {
|
|
105
|
+
opacity: 1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/* The overlay's glyph is sized against the avatar rather than by a step,
|
|
109
|
+
because it sits inside the picture. */
|
|
110
|
+
.crewlet-image-upload__overlay .crewlet-glyph {
|
|
111
|
+
width: calc(var(--crewlet-image-upload-size) * 0.28);
|
|
112
|
+
height: calc(var(--crewlet-image-upload-size) * 0.28);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.crewlet-image-upload__overlay-text {
|
|
116
|
+
font-size: var(--font-size-2xs);
|
|
117
|
+
font-weight: var(--font-weight-medium);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.crewlet-image-upload__spinner {
|
|
121
|
+
width: calc(var(--crewlet-image-upload-size) * 0.3);
|
|
122
|
+
height: calc(var(--crewlet-image-upload-size) * 0.3);
|
|
123
|
+
border-radius: var(--radius-circle);
|
|
124
|
+
border: 2px solid var(--color-surface-scrim);
|
|
125
|
+
border-top-color: var(--color-text-on-accent);
|
|
126
|
+
animation: crewlet-image-upload-spin calc(var(--motion-duration-slow) * 2.5) linear infinite;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@keyframes crewlet-image-upload-spin {
|
|
130
|
+
to {
|
|
131
|
+
transform: rotate(360deg);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/*
|
|
136
|
+
* 24px square, which is the smallest target WCAG 2.2 accepts. It was 20, on a
|
|
137
|
+
* control that is also the only way to take a logo off.
|
|
138
|
+
*
|
|
139
|
+
* It needs no z-index of its own: it is positioned and it comes after the
|
|
140
|
+
* trigger in the markup, so it already paints above it.
|
|
141
|
+
*/
|
|
142
|
+
.crewlet-image-upload__remove {
|
|
143
|
+
position: absolute;
|
|
144
|
+
top: -6px;
|
|
145
|
+
right: -6px;
|
|
146
|
+
width: 24px;
|
|
147
|
+
height: 24px;
|
|
148
|
+
padding: 0;
|
|
149
|
+
display: flex;
|
|
150
|
+
align-items: center;
|
|
151
|
+
justify-content: center;
|
|
152
|
+
border-radius: var(--radius-circle);
|
|
153
|
+
background: var(--color-feedback-danger);
|
|
154
|
+
border: 2px solid var(--color-surface-background);
|
|
155
|
+
color: var(--color-text-on-accent);
|
|
156
|
+
cursor: pointer;
|
|
157
|
+
opacity: 0;
|
|
158
|
+
transition: opacity var(--motion-duration-fast) var(--motion-easing-default);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.crewlet-image-upload:hover .crewlet-image-upload__remove,
|
|
162
|
+
.crewlet-image-upload__remove:focus-visible {
|
|
163
|
+
opacity: 1;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.crewlet-image-upload__remove:disabled {
|
|
167
|
+
cursor: default;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
.crewlet-image-upload__remove:focus-visible {
|
|
171
|
+
outline: 2px solid var(--color-focus);
|
|
172
|
+
outline-offset: 2px;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.crewlet-image-upload__input {
|
|
176
|
+
display: none;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/*
|
|
180
|
+
* The ring holds still. The trigger already carries aria-busy, and the control
|
|
181
|
+
* is disabled while the upload is out, so nothing about the state is carried
|
|
182
|
+
* by the motion alone.
|
|
183
|
+
*/
|
|
184
|
+
@media (prefers-reduced-motion: reduce) {
|
|
185
|
+
.crewlet-image-upload__overlay,
|
|
186
|
+
.crewlet-image-upload__remove {
|
|
187
|
+
transition: none;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.crewlet-image-upload__spinner {
|
|
191
|
+
animation: none;
|
|
192
|
+
}
|
|
193
|
+
}
|